为啥 Weka RandomForest 给我的结果与 Scikit RandomForestClassifier 不同?

Posted

技术标签:

【中文标题】为啥 Weka RandomForest 给我的结果与 Scikit RandomForestClassifier 不同?【英文标题】:Why does Weka RandomForest gives me a different result than Scikit RandomForestClassifier?为什么 Weka RandomForest 给我的结果与 Scikit RandomForestClassifier 不同? 【发布时间】:2013-02-02 20:54:32 【问题描述】:

在使用相同的 RandomForest 技术和相同的数据集时,我发现 WEKA 和 scikit 之间的结果存在特殊差异。使用 scikit,我的 AUC 约为 0.62(一直以来,因为我进行了广泛的测试)。但是,使用 WEKA,我得到的结果接近 0.79。差别很大!

我测试算法的数据集是 KC1.arff,我将其副本放在我的公共保管箱文件夹 https://dl.dropbox.com/u/30688032/KC1.arff 中。对于 WEKA,我只是从 http://www.cs.waikato.ac.nz/ml/weka/downloading.html 下载了 .jar 文件。在WEKA中,我将交叉验证参数设置为10倍,数据集设置为KC1.arff,算法设置为“RandomForest -l 19 -K 0 -S 1”。然后运行代码!在 WEKA 中生成结果后,应将其保存为文件、.csv 或 .arff。阅读该文件并检查“Area_under_ROC”列,它应该有点接近 0.79。

下面是 scikit 的 RandomForest 的代码

import numpy as np
from pandas import *
from sklearn.ensemble import RandomForestClassifier

def read_arff(f):
    from scipy.io import arff
    data, meta = arff.loadarff(f) 
    return DataFrame(data)

def kfold(clr,X,y,folds=10):
    from sklearn.cross_validation import StratifiedKFold
    from sklearn import metrics
    auc_sum=0
    kf = StratifiedKFold(y, folds)
    for train_index, test_index in kf:
        X_train, X_test = X[train_index], X[test_index]
        y_train, y_test = y[train_index], y[test_index]
        clr.fit(X_train, y_train)
        pred_test = clr.predict(X_test)
        print metrics.auc_score(y_test,pred_test)
        auc_sum+=metrics.auc_score(y_test,pred_test)

    print 'AUC: ',  auc_sum/folds
    print  "----------------------------" 



#read the dataset
X=read_arff('KC1.arff')
y=X['Defective']

#changes N, and Y to 0, and 1 respectively
s = np.unique(y)
mapping = Series([x[0] for x in enumerate(s)], index = s)  
y=y.map(mapping) 
del X['Defective']

#initialize random forests (by defualt it is set to 10 trees)
rf=RandomForestClassifier()

#run algorithm
kfold(rf,np.array(X),y)

#You will get an average AUC around 0.62 as opposed to 0.79 in WEKA

请记住,真实的 auc 值,如相关论文的实验结果所示,在 0.79 左右,所以问题出在我使用 scikit 随机森林的实现上。

我们将非常感谢您的帮助!!

非常感谢!

【问题讨论】:

首先,您应该确保在 scikit 中使用相同的 RF 实现参数。其次,顾名思义,结果存在一些随机性——您提到您进行了广泛的测试,但可能还不够广泛。第三,你数据的分区也会影响结果。特别是,您应该确保生成的折叠是分层的。 我确实做了非常广泛的测试!使用 scikit,该值从未超过 0.64,而我得到的 auc 值始终接近 0.57。使用 WEKA,我也做了很多测试,我总是得到接近 0.79 的值,所以我不认为随机性是这里的因素。对于这两种算法,我使用了 10 倍,这也给了我与使用 70% 训练和 30% 测试拆分相同的结果,因此,我认为我的验证方法也不是一个因素。但是,您可能在参数上是正确的,我尽力将它们设置为相同,这就是为什么我问您是否可以找到缺陷:) :)!谢谢! 我的猜测是你在 scikit 中的折叠没有分层。 @LarsKotthoff,你能告诉我褶皱在哪里没有分层吗?我正在使用 scikit 中解释的相同方法。谢谢 你调整了随机森林的哪些参数?您应该检查估计器的数量、每次分割的采样特征数量和最大深度是否相同(至少)。 【参考方案1】:

在 scikit-learn 问题跟踪器上发布问题后,我收到反馈说问题出在我使用的“预测”功能中。它应该是“pred_test = clr.predict_proba(X_test)[:, 1]”而不是“pred_test = clr.predict(X_test)”,因为分类问题是二元的:0 或 1。

实施更改后,结果证明 WEKA 和 scikit 的随机森林的结果是一样的 :)

【讨论】:

以上是关于为啥 Weka RandomForest 给我的结果与 Scikit RandomForestClassifier 不同?的主要内容,如果未能解决你的问题,请参考以下文章

随机森林分类 weka

使用 R 对 randomForest 执行交叉验证

Weka RF 没有给出任何混淆矩阵或预期结果

为啥 weka 在 WEKA 上计算 stringToWordVector 的错误数函数?

WEKA:从classifyInstance中获取类,为啥错了

Weka 3.7.11 中的随机树对数值属性使用啥分割标准?