为什么交叉验证RF分类比没有交叉验证更糟糕?

时间:2018-03-28 22:09:37

标签: python scikit-learn random-forest cross-validation

我很困惑为什么没有交叉验证的随机森林分类模型得到的平均准确度得分为.996,但是交叉验证的5倍,模型的平均准确度得分为.687。

共有275,956个样本。等级0 = 217891,等级1 = 6073,等级2 = 51992

我正在努力预测" TARGET"列,这是3个类[0,1,2]:

String filePath = new File("").getAbsolutePath();
    System.out.println(filePath);
    AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File(filePath+"/zene.wav").getAbsoluteFile());

从文档中,数据分为训练和测试

data.head()
bottom_temperature  bottom_humidity top_temperature top_humidity    external_temperature    external_humidity   weight  TARGET  
26.35   42.94   27.15   40.43   27.19   0.0  0.0    1   
36.39   82.40   33.39   49.08   29.06   0.0  0.0    1   
36.32   73.74   33.84   42.41   21.25   0.0  0.0    1   

进行交叉验证:

# link to docs http://scikit-learn.org/stable/modules/cross_validation.html
from sklearn.model_selection import train_test_split
from sklearn import datasets
from sklearn import svm

# Create a list of the feature column's names
features = data.columns[:7]

# View features
features
Out[]: Index([u'bottom_temperature', u'bottom_humidity', u'top_temperature',
       u'top_humidity', u'external_temperature', u'external_humidity',
       u'weight'],
      dtype='object')


#split data
X_train, X_test, y_train, y_test = train_test_split(data[features], data.TARGET, test_size=0.4, random_state=0)

#build model
clf = RandomForestClassifier(n_jobs=2, random_state=0)
clf.fit(X_train, y_train)

#predict
preds = clf.predict(X_test)

#accuracy of predictions
accuracy = accuracy_score(y_test, preds)
print('Mean accuracy score:', accuracy)

('Mean accuracy score:', 0.96607267423425713)

#verify - its the same
clf.score(X_test, y_test)
0.96607267423425713

低得多!

并验证第二种方式:

from sklearn.model_selection import cross_val_score
scores = cross_val_score(clf, data[features], data.TARGET, cv=5)
print("Accuracy: %0.2f (+/- %0.2f)" % (scores.mean(), scores.std() * 2))

Accuracy: 0.69 (+/- 0.07)

根据我的理解,交叉验证不应该通过这个数量降低预测的准确性,而是改进模型的预测,因为模型已经看到了更好的"表示所有数据。

3 个答案:

答案 0 :(得分:2)

train_test_split中,您只使用60%的数据进行培训(test_size=0.4)一次。但是在cross_val_score中,数据将被分成80%的列车(cv = 5)5次(每次4次将成为列车,剩余1次作为测试)。

现在您应该认为80%的训练数据超过60%,因此准确性不应该降低。但在这里还有一件事需要注意。

默认情况下,train_test_split不会对拆分进行分层,但会在cross_val_score中执行。分层是在每个折叠中保持类别(目标)的比例相同。所以最有可能的情况是,在train_test_split中没有保持目标比例,这会导致分类器过度拟合,从而导致分数过高。

我建议将cross_val_score作为最终得分。

答案 1 :(得分:2)

通常我会同意Vivek并告诉您相信您的交叉验证。

但是,某些级别的CV是随机森林中固有的,因为每棵树都是从自举样本中生长出来的,所以在运行交叉验证时,您不应期望看到这么大的精度降低。我怀疑您的问题是由于您的数据排序中的某种时间或位置依赖性。

当您使用train_test_split时,数据会从数据集中随机抽取,因此您的所有80个环境都可能出现在您的列车和测试数据集中。但是,当您使用CV的默认选项进行拆分时,我相信每个折叠都是按顺序绘制的,因此每个折叠中都不存在每个环境(假设您的数据按环境排序)。这会导致准确性降低,因为您使用另一个环境来预测一个环境。

简单的解决方案是设置cv=ms.StratifiedKFold(n_splits=5, shuffle=True)

在使用连锁数据集之前,我已多次遇到此问题,并且必须有数百个其他人已经并且没有意识到问题所在。默认行为的想法是维护时间序列中的顺序(从我在GitHub讨论中看到的)。

答案 2 :(得分:1)

您的数据可能具有某些固有顺序。在执行简历时,请将“随机播放”更改为true。