python - Scikit learn 中的交叉验证与网格搜索

标签 python scikit-learn cross-validation grid-search

我正在使用sklearn.model_selection.GridSearchCVsklearn.model_selection.cross_val_score ,在这样做的过程中,我遇到了意想不到的结果。

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

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)

接下来,我定义管道“生成器”:

def my_pipeline(C=None):
    if C is None:
        return Pipeline(
            [
                ('step1', StandardScaler()),
                ('clf', LinearSVC(random_state=42))
            ])
    else:
        return Pipeline(
            [
                ('step1', StandardScaler()),
                ('clf', LinearSVC(C=C, random_state=42))
            ])        

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

Cs = [0.01, 0.1, 1, 2, 5, 10, 50, 100]

最后,我想检查一下最大的recall_score是多少。可以得到的。有一次,我使用cross_val_score来做到这一点一旦直接使用 GridSearchCV .

np.max(
    [
        np.mean(
            cross_val_score(my_pipeline(C=c), X, y,
                            cv=3, 
                            scoring=make_scorer(recall_score)
    )) for c in Cs])

和:

GridSearchCV(
    my_pipeline(),
    {
        'clf__C': Cs
    },
    scoring=make_scorer(recall_score),
    cv=3
).fit(X, y).best_score_)

在我的示例中,前者生成 0.85997883750571147,后者生成 0.85999999999999999。我期望值是相同的。我错过了什么?

我把它全部放在 gist 中也是如此。

编辑:修复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 中的分数是四舍五入的)。

关于python - Scikit learn 中的交叉验证与网格搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45277086/

相关文章:

python - 用 pandas 在 excel 中给单元格着色

python - App Engine 多个电子邮件地址返回 404

python - 如何将火车模型投入生产?

python - 在sklearn中将文本列转换为数字

python - XGBoost - xgb.cv 和 cross_val_score 之间的巨大差异

python - 显示每个条形堆栈的所有数据标签的总和

python - 如何使用本地服务器的 nginx 将 http 转换为 https(自签名证书)

python : Failing to install scikit-learn (error code 1) on widows

python - 具有显示标准偏差的 n 重交叉验证的精确召回曲线

python-3.x - 非随机地将数据拆分为训练和测试