【问题标题】:Performing K-fold Cross-Validation: Using Same Training Set vs. Separate Validation Set执行 K 折交叉验证:使用相同的训练集与单独的验证集
【发布时间】:2016-02-25 14:42:12
【问题描述】:

我正在使用 Python scikit-learn 框架来构建决策树。我目前正在将我的训练数据分成两组,一组用于训练,另一组用于验证(通过 K 折交叉验证实现)。

要交叉验证我的模型,我应该将我的数据分成上面所述的两组还是简单地使用完整的训练集?我的主要目标是防止过度拟合。我在网上看到了关于这两种方法的使用和功效的相互矛盾的答案。

我知道当没有足够的数据用于单独的验证集时,通常使用 K 折交叉验证。我没有这个限制。直观地说,我相信将 K-fold 交叉验证与单独的数据集结合使用将进一步减少过度拟合。

我的假设正确吗?有没有更好的方法可以用来验证我的模型?

拆分数据集方法:

x_train, x_test, y_train, y_test = train_test_split(df[features], df["SeriousDlqin2yrs"], test_size=0.2, random_state=13)

dt = DecisionTreeClassifier(min_samples_split=20, random_state=99)
dt.fit(x_train, y_train)

scores = cross_val_score(dt, x_test, y_test, cv=10)

训练数据集方法:

x_train=df[features]
y_train=df["SeriousDlqin2yrs"]

dt = DecisionTreeClassifier(min_samples_split=20, random_state=99)
dt.fit(x_train, y_train)

scores = cross_val_score(dt, x_train, y_train, cv=10)

【问题讨论】:

    标签: validation machine-learning statistics scikit-learn cross-validation


    【解决方案1】:

    好吧,您似乎对验证以及 cross_val_score 所做的事情感到非常困惑。首先,您不应该执行上述任何方法。如果您不是在搜索某些超参数,而只是想回答问题“在我的数据上使用 min_samples_split=20 的 DT 有多好”,那么您应该这样做:

    dt = DecisionTreeClassifier(min_samples_split=20, random_state=99)
    scores = cross_val_score(dt, X, y, cv=10)
    

    没有任何拆分。为什么?因为cross_val_score 进行了拆分。它的作用是将Xy 分成10 个部分,并在trianing 上执行10 次拟合,然后对剩余部分进行测试。换句话说,如果你做类似的事情

    x_train=df[features]
    y_train=df["SeriousDlqin2yrs"]
    
    dt = DecisionTreeClassifier(min_samples_split=20, random_state=99)
    dt.fit(x_train, y_train) # this line does nothing!
    
    scores = cross_val_score(dt, x_train, y_train, cv=10)
    

    然后fit 命令没用,因为 cross_val_score 会再次调用 fit 10 次。此外,您根本不使用test 设置!同样,在您的第二个代码中 - 您既适合并在测试集上进行测试,也是不正确的。

    但是,如果你想拟合一些超参数,假设这个 min_samples_split,那么你应该(假设你的测试集大到可以表示):

    X_train, y_train = X[train], y[train]
    X_test, y_test = X[test], y[test]
    
    scores = []
    for param in [10, 20, 40]:
       dt = DecisionTreeClassifier(min_samples_split=param, random_state=99)
       scores.append((cross_val_score(dt, X_train, y_train, cv=10), param))
    
    best_param = max(scores)[1]
    dt = DecisionTreeClassifier(min_samples_split=best_param, random_state=99)
    print np.mean(dt.predict(X_test)==y_test) # checking accuracy on testing set
    

    【讨论】:

    • 你说得对。谢谢,这是一个非常有启发性的答案。还是个初学者,还有很多工作要做。
    猜你喜欢
    • 2018-05-03
    • 2016-05-12
    • 2013-12-31
    • 2019-10-09
    • 2019-12-23
    • 2016-01-29
    • 2011-12-16
    • 1970-01-01
    • 2018-04-03
    相关资源
    最近更新 更多