Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何计算scikit学习中的正确交叉验证分数?_Python_Python 3.x_Machine Learning_Scikit Learn - Fatal编程技术网

Python 如何计算scikit学习中的正确交叉验证分数?

Python 如何计算scikit学习中的正确交叉验证分数?,python,python-3.x,machine-learning,scikit-learn,Python,Python 3.x,Machine Learning,Scikit Learn,我正在做一项分类任务。然而,我得到的结果略有不同: #First Approach kf = KFold(n=len(y), n_folds=10, shuffle=True, random_state=False) pipe= make_pipeline(SVC()) for train_index, test_index in kf: X_train, X_test = X[train_index], X[test_index] y_train, y_test = y[tra

我正在做一项分类任务。然而,我得到的结果略有不同:

#First Approach
kf = KFold(n=len(y), n_folds=10, shuffle=True, random_state=False)
pipe= make_pipeline(SVC())
for train_index, test_index in kf:
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]

print ('Precision',np.mean(cross_val_score(pipe, X_train, y_train, scoring='precision')))



#Second Approach
clf.fit(X_train,y_train)
y_pred = clf.predict(X_test)
print ('Precision:', precision_score(y_test, y_pred,average='binary'))

#Third approach
pipe= make_pipeline(SCV())
print('Precision',np.mean(cross_val_score(pipe, X, y, cv=kf, scoring='precision')))

#Fourth approach

pipe= make_pipeline(SVC())
print('Precision',np.mean(cross_val_score(pipe, X_train, y_train, cv=kf, scoring='precision')))
输出:


对于任何分类任务,最好使用分层折叠交叉验证拆分。在分层KFold中,对于分类问题,每个类的样本数相等

这取决于你的分类问题的类型。看到准确度和回忆分数总是很好的。对于倾斜的二元分类,人们倾向于使用ROC AUC分数:

from sklearn import metrics
metrics.roc_auc_score(ytest, ypred)
让我们看看您的解决方案:

import numpy as np
from sklearn.cross_validation import cross_val_score
from sklearn.metrics import precision_score
from sklearn.cross_validation import KFold
from sklearn.pipeline import make_pipeline
from sklearn.svm import SVC

np.random.seed(1337)

X = np.random.rand(1000,5)

y = np.random.randint(0,2,1000)

kf = KFold(n=len(y), n_folds=10, shuffle=True, random_state=42)
pipe= make_pipeline(SVC(random_state=42))
for train_index, test_index in kf:
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]

print ('Precision',np.mean(cross_val_score(pipe, X_train, y_train, scoring='precision')))
# Here you are evaluating precision score on X_train.

#Second Approach
clf = SVC(random_state=42)
clf.fit(X_train,y_train)
y_pred = clf.predict(X_test)
print ('Precision:', precision_score(y_test, y_pred, average='binary'))

# here you are evaluating precision score on X_test

#Third approach
pipe= make_pipeline(SVC())
print('Precision',np.mean(cross_val_score(pipe, X, y, cv=kf, scoring='precision')))

# Here you are splitting the data again and evaluating mean on each fold

因此,结果是不同的

首先,如中所述和部分中所示,
scikit学习
交叉验证
cross_val_得分
执行以下操作:

  • 将数据集
    X
    拆分为N倍(根据参数
    cv
    )。它相应地拆分标签
    y
  • 使用估计器(参数
    估计器
    )对其进行N-1次的训练
  • 使用估计器预测最后一次折叠的标签
  • 通过比较预测值和真实值返回分数(参数<代码>分数
  • 重复步骤2。到步骤4。通过改变测试折叠。因此,您将得到一个N个分数的数组
  • 让我们看看你的每一种方法

    第一种方法:

    为什么要在交叉验证之前分割训练集,因为scikit学习功能会为您这样做?因此,您在较少的数据上训练您的模型,最后得到一个值得验证的分数

    第二种方法:

    在这里,您在数据上使用了另一个度量,而不是
    交叉验证。因此,您无法将其与其他验证分数进行比较,因为它们是两个不同的东西。一个是典型的错误百分比,而
    精度
    是用于校准二进制分类器(真或假)的度量。虽然这是一个很好的指标(您可以检查ROC曲线、精度和召回率指标),但仅比较这些指标

    第三种方法:

    这个比较自然。这个分数是很好的(我的意思是如果你想将它与其他分类器/估计器进行比较)。然而,我要警告你,不要因此而直接采用平均值。因为有两件事你可以比较:均值和方差。数组的每一个分数都不同于另一个,您可能想知道与其他估计值相比,差异有多大(您肯定希望方差尽可能小)

    第四种方法:

    Kfold
    似乎有问题,与
    cross\u val\u分数不相关

    最后:

    仅使用第二种方法或第三种方法比较估算值。但他们肯定不会估计同样的事情——精度和错误率

    clf = make_pipeline(SVC())
    # However, fot clf, you can use whatever estimator you like
    scores = cross_val_score(clf, X, y, cv = 10, scoring='precision')
    print('Mean score : ', np.mean(scores))
    print('Score variance : ', np.var(scores))
    

    通过将
    clf
    更改为另一个估计器(或将其集成到一个循环中),您将能够获得每个eastimator的分数并对其进行比较

    感谢您的帮助,关于
    交叉值分数
    ,你知道为什么我会得到不同的结果,哪种方法是正确的计算方法吗?这可能是因为随机种子。您是否尝试设置random_state参数并查看发生了什么?是的,我的random在开始之前执行了以下操作:
    np.random.seed(1337)
    与seed无关。这是因为每种方法都在做不同的事情:)但是,如果没有指定种子,那么每次交叉验证的结果都会有微小的差异,交叉验证的平均值也会有(非常)微小的差异。如果是同一粒种子,你每次进行实验时都会得到完全相同的结果——我不建议这样做,因为理由太过恰当。谢谢,两个答案都很好,尽管我都想接受,但我会接受投票率更高的答案。谢谢你的帮助,关于第三种方法,我不明白为什么我不能这样做:
    cross\u val\u score(pipe,X\u train,y\u train,cv=kf,scoring='precision')
    ,我得到了以下例外:
    索引器:索引900超出了大小900的界限,为什么会发生这种情况?kf是全套的,即len(y),而您正在使用X\u train,你在那里训练。是的,绝对:)我想你想做的是
    cv=10
    (而不是
    cv=kf
    )。文件规定,对于整数/无输入,如果y是二进制或多类,则使用分层折叠。因此,默认情况下,如果
    cv=10
    ,并且您的数据表示类,则默认情况下使用StratifiedKFold。我没有得到我想在测试步骤中评估的
    -测试步骤集成在
    交叉测试分数中
    ,但是如果您只想进行一次分割,请使用
    训练测试分割
    ,这在交叉验证中可能不是一个好的做法。您为什么要这样做?我认为,
    cross\u val\u score
    是为您所做的精心设计的,以防您想要比较估计器的性能。
    import numpy as np
    from sklearn.cross_validation import cross_val_score
    from sklearn.metrics import precision_score
    from sklearn.cross_validation import KFold
    from sklearn.pipeline import make_pipeline
    from sklearn.svm import SVC
    
    np.random.seed(1337)
    
    X = np.random.rand(1000,5)
    
    y = np.random.randint(0,2,1000)
    
    kf = KFold(n=len(y), n_folds=10, shuffle=True, random_state=42)
    pipe= make_pipeline(SVC(random_state=42))
    for train_index, test_index in kf:
        X_train, X_test = X[train_index], X[test_index]
        y_train, y_test = y[train_index], y[test_index]
    
    print ('Precision',np.mean(cross_val_score(pipe, X_train, y_train, scoring='precision')))
    # Here you are evaluating precision score on X_train.
    
    #Second Approach
    clf = SVC(random_state=42)
    clf.fit(X_train,y_train)
    y_pred = clf.predict(X_test)
    print ('Precision:', precision_score(y_test, y_pred, average='binary'))
    
    # here you are evaluating precision score on X_test
    
    #Third approach
    pipe= make_pipeline(SVC())
    print('Precision',np.mean(cross_val_score(pipe, X, y, cv=kf, scoring='precision')))
    
    # Here you are splitting the data again and evaluating mean on each fold
    
    clf = make_pipeline(SVC())
    # However, fot clf, you can use whatever estimator you like
    scores = cross_val_score(clf, X, y, cv = 10, scoring='precision')
    print('Mean score : ', np.mean(scores))
    print('Score variance : ', np.var(scores))