Scikit Learn 分层交叉验证中的差异
Posted
技术标签:
【中文标题】Scikit Learn 分层交叉验证中的差异【英文标题】:Discrepancy in Scikit Learn Stratified Cross Validation 【发布时间】:2015-12-11 21:22:15 【问题描述】:我发现使用相同数据的两种交叉验证技术之间的分类性能存在差异。我想知道是否有人可以对此有所了解。
方法一:cross_validation.train_test_split 方法 2:分层 KFold。具有相同数据集的两个示例
数据集 5500[n_samples :: Class 1 = 500 ; Class 0 = 5000 ] by 193 个特征
方法 1 [使用 train_test_split 进行随机迭代]
for i in range(0,5):
X_tr, X_te, y_tr, y_te = cross_validation.train_test_split(X_train.values, y_train, test_size=0.2, random_state=i)
clf = RandomForestClassifier(n_estimators=250, max_depth=None, min_samples_split=1, random_state=0, oob_score=True)
y_score = clf.fit(X_tr, y_tr).predict(X_te)
y_prob = clf.fit(X_tr, y_tr).predict_proba(X_te)
cm = confusion_matrix(y_te, y_score)
print cm
fpr, tpr, thresholds = roc_curve(y_te,y_prob[:,1])
roc_auc = auc(fpr, tpr);
print "ROC AUC: ", roc_auc
方法一的结果
Iteration 1 ROC AUC: 0.91
[[998 4]
[ 42 56]]
Iteration 5 ROC AUC: 0.88
[[1000 3]
[ 35 62]]
方法 2 [StratifiedKFold 交叉验证]
cv = StratifiedKFold(y_train, n_folds=5,random_state=None,shuffle=False)
clf = RandomForestClassifier(n_estimators=250, max_depth=None, min_samples_split=1, random_state=None, oob_score=True)
for train, test in cv:
y_score = clf.fit(X_train.values[train], y_train[train]).predict(X_train.values[test])
y_prob = clf.fit(X_train.values[train], y_train[train]).predict_proba(X_train.values[test])
cm = confusion_matrix(y_train[test], y_score)
print cm
fpr, tpr, thresholds = roc_curve(y_train[test],y_prob[:,1])
roc_auc = auc(fpr, tpr);
print "ROC AUC: ", roc_auc
方法2的结果
Fold 1 ROC AUC: 0.76
Fold 1 Confusion Matrix
[[995 5]
[ 92 8]]
Fold 5 ROC AUC: 0.77
Fold 5 Confusion Matrix
[[986 14]
[ 76 23]]
【问题讨论】:
【参考方案1】:train_test_split 没有分层。在当前的开发版本和即将到来的 0.17 中,您可以使用 stratify=y
使其分层,但在 0.16.2 中则不行。
此外,随机状态不是固定的,使用方式也不同,因此您不能期望完全相同的结果。
【讨论】:
您好安德烈亚斯,感谢您的回复。与 layerifiedkfold 相比,我更关心任何 cross_val.train_test_split 的一致更好的分类结果。我可以看到 train_test_split 保持了类平衡,这使得它可以与 stratifiedkfold 相媲美[我不期望完全相同的结果]。我的问题是,为什么stratifiedkfold 不能产生一个显示接近cross_validation.train_test_split 的分类结果的折叠。我从 sklearn-0.14.1 移动到 0.16.1 并注意到在相同数据和折叠上使用 stratifiedkfold 的性能下降。再次感谢。 啊。那么这意味着您的数据中存在相关性。在 StratifiedKFold 中执行 shuffle=True 以获得相同的结果。但是您应该找出为什么您的数据中有顺序。此外,train_test_split 不保留班级余额。 非常感谢。 [正数据] 前 500 [负数据] 501-5000 包含。改变 shuffle=True 就可以了。下面是 5 次折叠的结果,其中 shuffle True 和 False。 [ shuffle=True 的结果] ROC AUC: 0.951, 0.950, 0.956, 0.958, 0.955 和 [ shuffle=False 的结果] ROC AUC : 0.719, 0.915, 0.835, 0.723, 0.662 我认为标签数据的顺序不会影响折叠或分类性能。 [1] 。折叠选择是顺序发生还是随机发生? [2]。是否有可能解释为什么这会影响折叠选择。 褶皱尽可能连续(分层时)。如果没有分层,它只是第一个折叠中的前 n / k 个样本等。洗牌意味着在拆分之前对数据进行洗牌,因此折叠是随机的。以上是关于Scikit Learn 分层交叉验证中的差异的主要内容,如果未能解决你的问题,请参考以下文章