Python Scikit学习中的交叉验证与网格搜索

Python Scikit学习中的交叉验证与网格搜索,python,scikit-learn,cross-validation,grid-search,Python,Scikit Learn,Cross Validation,Grid Search,我正在使用和,在这样做的同时,我遇到了一个意想不到的结果 在我的示例中,我使用以下导入: from sklearn.datasets import make_classification from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler from sklearn.svm import LinearSVC from sklearn.model_selection import

我正在使用和,在这样做的同时,我遇到了一个意想不到的结果

在我的示例中,我使用以下导入:

from sklearn.datasets import make_classification
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import LinearSVC
from sklearn.model_selection import cross_val_score
from sklearn.metrics import make_scorer
from sklearn.metrics import recall_score
from sklearn.model_selection import GridSearchCV
import numpy as np
首先,我创建一个随机数据集:

X, y = make_classification(n_samples=1000, n_features=20, random_state=42)
接下来,我定义管道“生成器”:

接下来,我设置了两个要测试的
C

Cs = [0.01, 0.1, 1, 2, 5, 10, 50, 100]
最后,我想检查能得到的最大值是多少。一次,我用它,一次直接用它

以及:

在我的示例中,前者产生
0.85997883750571147
,后者产生
0.85999999999999
。我希望值是相同的。我错过了什么

我也把它都放在一个盒子里


编辑:修复
cv
。我将
cv=3
替换为
StratifiedKFold(n_splits=3,random_state=42)
,结果没有改变。事实上,
cv
似乎不会影响结果。

对我来说,这似乎是一个精度问题。如果您查看完整的分数列表,则对于
交叉值(cross_val_score
),您会得到以下信息:

[0.85193468484717316,
 0.85394271697568724,
 0.85995478921674717,
 0.85995478921674717,
 0.8579467570882332,
 0.86195079720077905,
 0.81404660558401265,
 0.82201861337565829]
对于
GridSearchCV
您可以获得以下信息

[mean: 0.85200, std: 0.02736, params: {'clf__C': 0.01},
 mean: 0.85400, std: 0.02249, params: {'clf__C': 0.1},
 mean: 0.86000, std: 0.01759, params: {'clf__C': 1},
 mean: 0.86000, std: 0.01759, params: {'clf__C': 2},
 mean: 0.85800, std: 0.02020, params: {'clf__C': 5},
 mean: 0.86200, std: 0.02275, params: {'clf__C': 10},
 mean: 0.81400, std: 0.01916, params: {'clf__C': 50},
 mean: 0.82200, std: 0.02296, params: {'clf__C': 100}]

因此,每对对应的分数基本相同,精度差异很小(似乎
GridSearchCV
中的分数是四舍五入的)。

这里一个非常快速的第一个猜测是,这与随机数生成器的状态有关,即数据被拆分为折叠以进行交叉验证。如果您在
GridSearchCV
cross\u val\u score
中修复了
random\u状态
,会发生什么?猜对了,但是。。。错@安格斯维利亚姆斯查看了更新。事实上,看起来引擎盖下面有一些圆。我找不到它的记录,也找不到。
GridSearchCV(
    my_pipeline(),
    {
        'clf__C': Cs
    },
    scoring=make_scorer(recall_score),
    cv=3
).fit(X, y).best_score_)
[0.85193468484717316,
 0.85394271697568724,
 0.85995478921674717,
 0.85995478921674717,
 0.8579467570882332,
 0.86195079720077905,
 0.81404660558401265,
 0.82201861337565829]
[mean: 0.85200, std: 0.02736, params: {'clf__C': 0.01},
 mean: 0.85400, std: 0.02249, params: {'clf__C': 0.1},
 mean: 0.86000, std: 0.01759, params: {'clf__C': 1},
 mean: 0.86000, std: 0.01759, params: {'clf__C': 2},
 mean: 0.85800, std: 0.02020, params: {'clf__C': 5},
 mean: 0.86200, std: 0.02275, params: {'clf__C': 10},
 mean: 0.81400, std: 0.01916, params: {'clf__C': 50},
 mean: 0.82200, std: 0.02296, params: {'clf__C': 100}]