使用随机数据

时间:2015-08-28 10:13:41

标签: 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

我实际上完全不明白这个不同分数的原因,也无法得到我在这里失踪的东西。

评分是否应该相似?

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

我知道我已经迟到了,但是我遇到了类似的问题而且偶然发现了这篇文章。使用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找到的二元决策的阈值。所有点都代表用于训练模型的数据。任何新数据都可以添加到图中;如果它们出现在左下方,则会标记为“红色”,并且在右上角标记为“蓝色”'。我们可以想到“红色”'作为“积极的' class,因此预测的输出是二进制{0,1}输出(红色= 1,蓝色= 0)。

Linear SVM output for binary prediction

有一点需要注意的是,数据点不是完全线性可分的,模型中靠近决策边界的区域中红色和蓝色点重叠很多。因此,这里的线性模型无法获得完美的性能。

虚线表示SVM的边距。 SVM的训练旨在最大化该边距的宽度,并且非常依赖于提供的超参数 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。我在这张图上添加了两条额外的线,红色和蓝色边界线。这些可以被认为是主要决策线的 shift 从高选择性区域,其中只有最自信的红点实际上被归类为红色,到非常放松的边界,每个点都将是被归类为红色。请记住,此移动阈值右下角的任何点都将被归类为红色。

最初,没有数据点符合要归类为红色的标准,但随着线条沿箭头方向移动,它开始挖掘这些点。在早期阶段,所有这些都是正确的,因为所有数据点都是红色的,但是当我们朝向边缘区域时,我们很快就会开始获得误报(蓝点),同时获得更多的红色。这种以不同速率收集真假阳性的模式会影响ROC曲线。显示这个的最好方法是另一个数字:

ROC Curve

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

现在想象两种截然不同的情况:如果数据完全可线性分离,那么没有一个训练数据点出现在“错误”的情况下。在边界的一侧,ROC线总是直接向 y 轴向上,直到它到达左上方,并且沿着图形顶部的头部向右上方,给出AUC但是,如果数据点只是一团噪音,所有数据都在中心混合,那么你会得到与正数相同的误报,你的线会朝向对角线的方向前进并给出一个AUC为0.5。因此,为什么这个值代表完整的机会水平。

我不是scikit-learn的撰稿人,我还没有在这里查看源代码,但我可以想象roc_auc_score使用来自decision_function或{{1}的值作为一个积极的(在我们的例子中是红色)类中,模型的自信程度的表示。因此,放宽边界和观察真假误差的变化率的相同逻辑仍然存在。如果这不对,那么请纠正我。