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

我正在代码中使用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

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

分数不应该相似吗?

感谢您的时间。

python大神给出的解决方案

我知道我来晚了,但是我遇到了类似的问题,偶然发现了这篇文章。使用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)。

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

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

虚线表示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曲线。证明这一点的最佳方法是使用另一个图:

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

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

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

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

Python sqlite3数据库已锁定 - python

我在Windows上使用Python 3和sqlite3。我正在开发一个使用数据库存储联系人的小型应用程序。我注意到,如果应用程序被强制关闭(通过错误或通过任务管理器结束),则会收到sqlite3错误(sqlite3.OperationalError:数据库已锁定)。我想这是因为在应用程序关闭之前,我没有正确关闭数据库连接。我已经试过了: connectio…

用大写字母拆分字符串,但忽略AAA Python Regex - python

我的正则表达式:vendor = "MyNameIsJoe. I'mWorkerInAAAinc." ven = re.split(r'(?<=[a-z])[A-Z]|[A-Z](?=[a-z])', vendor) 以大写字母分割字符串,例如:'我的名字是乔。 I'mWorkerInAAAinc”变成…

Python-熊猫描述了抛出错误:无法散列的类型“ dict” - python

更新:我正在使用“ Socrata开源API”中的一些示例代码。我在代码中注意到以下注释:# First 2000 results, returned as JSON from API / converted to Python # list of dictionaries by sodapy. 我不熟悉JSON。我已经下载了一个数据集,并创建了一个包含大量…

子条件的python条件覆盖 - python

我试图找到一个python代码覆盖率工具,该工具可以衡量语句中是否包含子表达式:例如,我想看看下面的示例是否涵盖了condition1 / condition2 / condtion3?if condition1 or condition2 or condition3: x = true_value python大神给出的解决方案 对此的唯一合理答案是:当前…

USB设备发行 - python

我目前正在使用PyUSB。由于我不熟悉USB,所以我不知道如何执行以下操作。我已经从Python PyUSB成功连接到我的USB设备硬件。在代码中,我需要重置USB设备硬件。通过向硬件发送命令来完成。现在,在硬件重置后,我想从Python PyUSB释放当前的USB设备。然后,我想在重置后将其重新连接到USB设备硬件。请让我知道,如何释放USB设备连接和接口…