在 sklearn.cross_validation 中使用 train_test_split 和 cross_val_score 的区别
Difference between using train_test_split and cross_val_score in sklearn.cross_validation
我有一个包含 20 列的矩阵。最后一列是 0/1 标签。
数据的link为here。
我正在尝试 运行 数据集上的随机森林,使用交叉验证。我使用两种方法来做到这一点:
- 使用
sklearn.cross_validation.cross_val_score
- 使用
sklearn.cross_validation.train_test_split
当我做我认为几乎完全相同的事情时,我得到了不同的结果。为了举例说明,我 运行 使用上述两种方法进行双重交叉验证,如下面的代码所示。
import csv
import numpy as np
import pandas as pd
from sklearn import ensemble
from sklearn.metrics import roc_auc_score
from sklearn.cross_validation import train_test_split
from sklearn.cross_validation import cross_val_score
#read in the data
data = pd.read_csv('data_so.csv', header=None)
X = data.iloc[:,0:18]
y = data.iloc[:,19]
depth = 5
maxFeat = 3
result = cross_val_score(ensemble.RandomForestClassifier(n_estimators=1000, max_depth=depth, max_features=maxFeat, oob_score=False), X, y, scoring='roc_auc', cv=2)
result
# result is now something like array([ 0.66773295, 0.58824739])
xtrain, xtest, ytrain, ytest = train_test_split(X, y, test_size=0.50)
RFModel = ensemble.RandomForestClassifier(n_estimators=1000, max_depth=depth, max_features=maxFeat, oob_score=False)
RFModel.fit(xtrain,ytrain)
prediction = RFModel.predict_proba(xtest)
auc = roc_auc_score(ytest, prediction[:,1:2])
print auc #something like 0.83
RFModel.fit(xtest,ytest)
prediction = RFModel.predict_proba(xtrain)
auc = roc_auc_score(ytrain, prediction[:,1:2])
print auc #also something like 0.83
我的问题是:
为什么我得到不同的结果,即为什么我使用 train_test_split
时 AUC(我使用的指标)更高?
注意:
当我使用更多折叠(比如 10 倍)时,我的结果中似乎存在某种模式,第一次计算总是给我最高的 AUC。
在上面例子中的双重交叉验证的情况下,第一个AUC总是高于第二个;它总是类似于 0.70 和 0.58。
感谢您的帮助!
使用 cross_val_score 时,您会经常想要使用 KFolds 或 StratifiedKFolds 迭代器:
http://scikit-learn.org/0.10/modules/cross_validation.html#computing-cross-validated-metrics
默认情况下,cross_val_score 不会随机化您的数据,如果您的数据一开始就不是随机的,这可能会产生像这样的奇怪结果。
KFolds 迭代器有一个随机状态参数:
http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.KFold.html
train_test_split也是如此,它默认随机化:
http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.train_test_split.html
像您描述的那样的模式通常是 train/test 集中缺乏随机性的结果。
@KCzar 指出的答案。只想注意我发现随机化数据(X
和 y
具有相同索引改组)的最简单方法如下:
p = np.random.permutation(len(X))
X, y = X[p], y[p]
我有一个包含 20 列的矩阵。最后一列是 0/1 标签。
数据的link为here。
我正在尝试 运行 数据集上的随机森林,使用交叉验证。我使用两种方法来做到这一点:
- 使用
sklearn.cross_validation.cross_val_score
- 使用
sklearn.cross_validation.train_test_split
当我做我认为几乎完全相同的事情时,我得到了不同的结果。为了举例说明,我 运行 使用上述两种方法进行双重交叉验证,如下面的代码所示。
import csv
import numpy as np
import pandas as pd
from sklearn import ensemble
from sklearn.metrics import roc_auc_score
from sklearn.cross_validation import train_test_split
from sklearn.cross_validation import cross_val_score
#read in the data
data = pd.read_csv('data_so.csv', header=None)
X = data.iloc[:,0:18]
y = data.iloc[:,19]
depth = 5
maxFeat = 3
result = cross_val_score(ensemble.RandomForestClassifier(n_estimators=1000, max_depth=depth, max_features=maxFeat, oob_score=False), X, y, scoring='roc_auc', cv=2)
result
# result is now something like array([ 0.66773295, 0.58824739])
xtrain, xtest, ytrain, ytest = train_test_split(X, y, test_size=0.50)
RFModel = ensemble.RandomForestClassifier(n_estimators=1000, max_depth=depth, max_features=maxFeat, oob_score=False)
RFModel.fit(xtrain,ytrain)
prediction = RFModel.predict_proba(xtest)
auc = roc_auc_score(ytest, prediction[:,1:2])
print auc #something like 0.83
RFModel.fit(xtest,ytest)
prediction = RFModel.predict_proba(xtrain)
auc = roc_auc_score(ytrain, prediction[:,1:2])
print auc #also something like 0.83
我的问题是:
为什么我得到不同的结果,即为什么我使用 train_test_split
时 AUC(我使用的指标)更高?
注意: 当我使用更多折叠(比如 10 倍)时,我的结果中似乎存在某种模式,第一次计算总是给我最高的 AUC。
在上面例子中的双重交叉验证的情况下,第一个AUC总是高于第二个;它总是类似于 0.70 和 0.58。
感谢您的帮助!
使用 cross_val_score 时,您会经常想要使用 KFolds 或 StratifiedKFolds 迭代器:
http://scikit-learn.org/0.10/modules/cross_validation.html#computing-cross-validated-metrics
默认情况下,cross_val_score 不会随机化您的数据,如果您的数据一开始就不是随机的,这可能会产生像这样的奇怪结果。
KFolds 迭代器有一个随机状态参数:
http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.KFold.html
train_test_split也是如此,它默认随机化:
http://scikit-learn.org/stable/modules/generated/sklearn.cross_validation.train_test_split.html
像您描述的那样的模式通常是 train/test 集中缺乏随机性的结果。
@KCzar 指出的答案。只想注意我发现随机化数据(X
和 y
具有相同索引改组)的最简单方法如下:
p = np.random.permutation(len(X))
X, y = X[p], y[p]