python - 在带有随机数据的sklearn.cross_validation中使用train_test_split和cross_val_score之间的不同结果

标签 python scikit-learn cross-validation

我正在代码中使用sklearn进行初步测试。

我正在测试:

1)sklearn.cross_validation.cross_val_score

2)sklearn.cross_validation.train_test_split

就像在这个question中一样。

代码如下:

#X is my data and Y the corresponding binary labels                                                  

#My classifier                                                                     
clf = svm.SVC(class_weight='auto', kernel=kernel, gamma=gamma,                   
    degree=degree, cache_size=cache_size,probability=probability)                   


#1st method: ShuffleSplit and cross validation                                      
cv = cross_validation.ShuffleSplit(X.shape[0], n_iter=5,                            
    test_size=0.4, random_state=0)                                                  
#Scoring                                                                            
scores = cross_validation.cross_val_score(clf, X, Y,                     
    cv=cv, n_jobs=3, scoring="roc_auc")                                             

#2nd method: train_test_split                                                       
X_train, X_test, y_train, y_test = cross_validation.train_test_split(               
    X, Y, test_size=0.4, random_state=42)                                           

clf.fit(X_train, y_train)                                                          
pred_test = clf.predict(X_test)                                                     
#Scoring                                                                            
score = roc_auc_score(y_test, pred_test)


与另一个问题的区别在于,在情况1)和情况2)中我的数据都是随机的。

但是我对于情况1)得到以下分数:

[ 0.9453893   0.94878745  0.95197478  0.95150763  0.94971746]


对于案例2):

0.867637


实际上,我完全不理解这种不同分数的原因,无法理解我在这里所缺少的。

分数不应该相似吗?

感谢您的时间。

最佳答案

我知道我来晚了,但是我遇到了类似的问题,偶然发现了这篇文章。使用train_test_split和cross_val_score比较答案时,使用roc_auc_score指标时,我遇到了完全相同的问题。

我认为问题出在将分类器的预测二进制输出放入roc_auc_score比较中。这意味着该度量标准只有两个二进制输出数组可作为得分依据。如果尝试改用“ predict_proba”,则将为您提供一个包含两列(假设您在此处存在两类问题)的数组,该数组包含不同样本点的类的概率。

在我的数据集上,我将其第二列与真实值一起输入roc_auc_score,此返回的答案与cross_val_score的输出更加一致。

更新:

在学到更多知识(并阅读文档!)之后,这不是最好的方法,因为它需要为SVC设置probability=True,这在计算上要昂贵得多。不要使用predictpredict_proba,而是使用decision_function,然后将这些值输入到roc_auc_score中作为预测值。

更新:

为了回应对此过程的评论,我还附上了一些数字以解释该过程。我还将提供一些背景信息,这些信息对我有帮助。

当决策边界的阈值从严格变为更宽松时,通过查看真假肯定相对假假相对数量的变化来绘制接收器工作特性曲线。但是,这种解释似乎有些难以理解,因此在此提供了一个数字。这显示了线性支持向量机在某些生成的具有2个特征(“蓝色”类和“红色”类)的数据上的决策边界。实线表示通过训练SVM找到的二进制决策的阈值。所有这些点都代表用于训练模型的数据。任何新数据都可以添加到绘图中。如果它们显示在左下方,则将被标记为“红色”,而在右上方将被标记为“蓝色”。我们可以将“红色”视为“正”类,因此预测的输出为二进制{0,1}输出(红色= 1,蓝色= 0)。

Linear SVM output for binary prediction

需要注意的一件事是数据点不是完全线性可分离的,模型中决策边界附近存在一个红色和蓝色点大量重叠的区域。因此,此处的线性模型永远无法获得理想的性能。

虚线表示SVM的边距。 SVM的训练旨在最大程度地增加此边距的宽度,并且非常依赖于所提供的超参数C值。实际上,较高的C值将迫使模型更好地适合训练数据,而较低的C值将允许此处分类错误,目的是为了更好地针对新数据和看不见的数据进行推广。完整的描述可以在scikit-learn文档中找到:http://scikit-learn.org/stable/auto_examples/svm/plot_svm_margin.html#sphx-glr-auto-examples-svm-plot-svm-margin-py。请注意,所有错误分类的点或出现在此边距区域中的所有点。其他方面,我们对正确表示超级有信心。

因此,重点是如何计算AUC。我在此图中添加了两条额外的线,红色和蓝色边界线。可以将这些视为主要决策线从高度选择区域(该区域仅将最自信的红点实际上被分类为红色)到非常宽松的边界(该点将每个点都分类为红色)的转变。请记住,此移动阈值右下角的任何点都将归为红色。

最初,没有数据点符合要分类为红色的条件,但是随着线沿箭头方向移动,它将开始铲起这些点。在早期阶段,所有这些点都是正确的,因为所有数据点都是红色的,但是当我们朝着边距区域前进时,我们很快就会开始捡到假阳性(蓝点),同时获得更多的红色。以不同速率收集真假阳性的这种模式会影响ROC曲线。证明这一点的最佳方法是使用另一个图:

ROC Curve

想象一下,我们开始从左下角开始绘制曲线,并且每当我们更改阈值位置时都进行小幅度移动。当我们收集真实的,红色的,正的时,我们在y轴方向上绘制线,但是当我们收集蓝色的时,我们在x轴方向上绘制线。目的是将直线发送到尽可能靠近左上角的位置,最后,我们将采用曲线下面积(AUC)作为指标。请注意,最后,线总是到达右上角(最终,所有数据点都将被归类为红色),在这种情况下,它仅沿图的顶部行进。这是因为在此数据集中,随着阈值越来越接近蓝线,我们只会得到假阳性。

现在想象两种截然不同的情况:如果数据是完全线性可分离的,那么没有一个训练数据点位于边界的“错误”侧,那么ROC线将始终直接沿y轴行进,直到到达y轴为止。左上角,并且沿着图顶部的头部到右上角,AUC为1。但是,如果数据点只是一团杂乱的噪声,并且混合在中心,则在与真实正值的比率相同,您的线会朝对角线的方向前进,并且AUC为0.5。因此,为什么该值代表性能的完全机会水平。

我不是scikit-learn的贡献者,并且这里没有检查源代码,但是我可以想象roc_auc_score使用decision_functionpredict_proba中的值来表示模型的置信度该点是肯定的(在我们的例子中是红色)。因此,放宽边界并查看真假率变化率的逻辑仍然成立。如果这不正确,请纠正我。

关于python - 在带有随机数据的sklearn.cross_validation中使用train_test_split和cross_val_score之间的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32268592/

相关文章:

scikit-learn - 获取每个交叉验证折叠的混淆矩阵

python - Python 中的套接字问题

python - Heroku 中推送 Flask 应用程序时出错 : sqlite3 missing

python - 具体排序由点分隔的数字列表

python - 记分器函数: difference between make_scorer/score_func and

python - 如何使用 scikit-learn 加载之前保存的模型并使用新的训练数据扩展模型

python - 使用 multiprocessing -Pool- 和 -sklearn-,代码运行但核心不显示任何工作

python - 带有自定义折叠的嵌套交叉验证

python - sklearn RandomizedSearchCV提取不同折叠的混淆矩阵

python - 在 matplotlib 的工具栏中添加一个项目