【问题标题】:Where should I define sklearn model in a kfold validation setup?我应该在 kfold 验证设置中在哪里定义 sklearn 模型?
【发布时间】:2021-05-29 10:08:57
【问题描述】:

我是机器学习的新手,我对 K-fold 交叉验证感到困惑。当我写一个 fold for 循环时,我应该在哪里定义 sklearn 模型(而不是 PyTorch 模型)。我看过一些教程,他们在 fold for 循环中定义模型并使用相同的模型预测 X_validation。但随后我们将在 for 循环中定义 k 不同模型,最终模型将是仅在最后一个折叠上训练的模型,它与之前的任何折叠都没有任何链接。

  • 在我看来,我们应该在 Kfold 交叉验证之外定义一个 Scikitlearn 模型,如果我的想法正确,或者是否存在与此方法相关的任何数据泄漏问题,请向我解释一下?

以下是我在项目中使用的实现,这里我在 kfold for loop 中定义了 sklearn-model。

import pandas as pd
from sklearn import linear_model
from sklearn import metrics

import config 
from lr_pipeline import lr_pipe

def run_training(fold):
    # load a single fold here
    df = pd.read_csv(config.TRAIN_FOLDS)
    df_train = df[df.kfold != fold].reset_index(drop=True)
    df_val = df[df.kfold == fold].reset_index(drop=True)

    # get X_train, X_val, y_train and y_val
    X_train = df_train.drop(['id','target_class','kfold'],axis=1)
    y_train = df_train['target_class']

    X_val = df_val.drop(['id','target_class','kfold'],axis=1)
    y_val = df_val['target_class']

    # preprocessing pipeline here
    X_train = lr_pipe.fit_transform(X_train)
    X_val = lr_pipe.transform(X_val)

    # train clf
    clf = linear_model.LogisticRegression()
    clf.fit(X_train,y_train)

    # metric
    pred = clf.predict_proba(X_val)[:,1]
    auc = metrics.roc_auc_score(y_val,pred)
    print(f"fold={fold}, auc={auc}")

    df_val.loc[:,"lr_pred"] = pred
    return df_val[["id","kfold","target_class","lr_pred"]]

if __name__ == '__main__':
    dfs = []
    for i in range(5):
        temp_df = run_training(i)
        dfs.append(temp_df)
    fin_valid_df = pd.concat(dfs)


    print(fin_valid_df.shape)
    fin_valid_df.to_csv(config.LR_MODEL_PRED,index=False)

【问题讨论】:

    标签: python scikit-learn k-fold


    【解决方案1】:

    让我从一个简短的背景开始。大多数机器学习模型都有两组参数:

    首先,所谓的超参数,例如对于线性回归 - 正则化系数alpha,对于决策树 - 树的depth,对于 K 个最近邻(KNN) - number of neighbors

    其次,有模型的参数,例如对于线性回归 - 权重(X w + b 中的 w 和 b),对于决策树 - 每个树级别的特定拆分,KNN 是没有任何参数的模型的罕见情况。

    模型参数是通过学习算法估计的(当你输入model.fit(X, y)时会发生这种情况),但是超参数不是。超参数由用户定义。问题是,如何选择它们,答案是交叉验证。它可以是 k 折交叉验证,也可以是任何其他验证技术,例如 train-test-splitting 或 random-shuffle 或其他。

    所以,关于你原来的问题。虽然在不同折叠上训练的两个模型的超参数可能相同,但参数会不同,因为参数是通过学习导出的训练数据中的算法。因此,无论您是在 for 循环内部还是外部创建模型并不重要,在不同折叠上训练的模型将是独立且不同的。但交叉验证的目标不是训练模型,而是定义一组最佳超参数。

    但是,我越来越多地看到人们如何平均在不同折叠上训练的模型而不在整个训练集上重新训练模型,从而减少预测的方差,在这种情况下,在 for 中定义模型可能很有用循环并保存实例以供以后使用,如下所示:

    def run_training(fold):
        ...
        clf = linear_model.LogisticRegression()
        clf.fit(X_train,y_train)
        pred = clf.predict_proba(X_val)[:,1]
        return clf
    

    我建议您坚持这种方法,并执行以下操作:

    clfs = []
    aucs_train = []
    aucs_val = []
    for train, val in kf.split(X, y):
        clf = run_training(train)
        clfs.append(clf)
        y_pred_train = clf.predict(X[train])[:, 1]
        y_pred_val = clf.predict(X[val])[:, 1]
        aucs_train.append(auc(y[train], y_pred_train))
        aucs_val.append(auc(y[val], y_pred_val))
    

    在这种情况下,clfs 将包含在不同折叠上训练的分类器,您可以将它们用于验证和预测保留/测试集。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-17
      • 1970-01-01
      • 1970-01-01
      • 2020-09-13
      • 1970-01-01
      • 2011-07-12
      • 2023-03-21
      • 2011-05-03
      相关资源
      最近更新 更多