学习曲线

数据挖掘 机器学习 Python scikit-学习 随机森林
2022-02-18 05:25:41

我在 sklearn 的RandomForestRegressor的帮助下尝试在波士顿数据集上使用随机森林算法来预测房价medv

只是为了评估模型的性能有多好,我用下面的代码尝试了 sklearn 的学习曲线

 train_sizes = [1, 25, 50, 100, 200, 390] # 390 is 80% of shape(X)

    from sklearn.model_selection import learning_curve
    def learning_curves(estimator, X, y, train_sizes, cv):
        train_sizes, train_scores, validation_scores = learning_curve(
                                                     estimator, X, y, train_sizes = train_sizes,
                                                     cv = cv, scoring = 'neg_mean_squared_error')
        #print('Training scores:\n\n', train_scores)
        #print('\n', '-' * 70) # separator to make the output easy to read
        #print('\nValidation scores:\n\n', validation_scores)
        train_scores_mean = -train_scores.mean(axis = 1)
        print(train_scores_mean)
        validation_scores_mean = -validation_scores.mean(axis = 1)
        print(validation_scores_mean)

        plt.plot(train_sizes, train_scores_mean, label = 'Training error')
        plt.plot(train_sizes, validation_scores_mean, label = 'Validation error')

        plt.ylabel('MSE', fontsize = 14)
        plt.xlabel('Training set size', fontsize = 14)
        title = 'Learning curves for a ' + str(estimator).split('(')[0] + ' model'
        plt.title(title, fontsize = 18, y = 1.03)
        plt.legend()
        plt.ylim(0,40)

如果你注意到我已经过去了,X, y不是X_train, y_trainlearning_curve

我不明白我应该通过X, y还是只将训练子集传递X_train, y_trainlearning_curve.

更新 1

Dimensions of my Train/Test split (75%:Train and 25%:Test) X.shape: (489, 11) X_train.shape: (366, 11) X_test.shape: (123, 11) 我有几个关于工作的其他问题learning_curve

  1. 测试数据集的大小是否根据列表中提到的训练数据集的大小而变化,train_sizes或者它总是固定的(根据训练/测试拆分为 123 个样本,在我的情况下为 25%),例如

    • 什么时候train dataset size = 1测试数据大小是488还是123(X_test的大小)
    • 什么时候train dataset size = 25测试数据大小是464还是123(X_test的大小)
    • 什么时候train dataset size = 50测试数据大小是439还是123(X_test的大小)

更新 2

博客中,数据集有 9568 个观察值,博主将整个数据集传递Xlearning_curve.

train_sizes = [1, 100, 500, 2000, 5000, 7654]

在第一次迭代中,当train_size是 1 那么test_size应该是9567,但他为什么这么说

但在验证集(有 1914 个实例)上进行测试时,MSE 飙升至大约 423.4。

第一次迭代不应该test_size是 9567 而不是 1914

在第二次迭代中,当train_size为 100 时,test_size应该是9468

我的意思是如果我错了,test_size将根据纠正我的变化train_size

1个回答

[更新后1/2 ]

学习曲线显示了误差如何随着训练集大小的增加而变化。一个基本上是改变训练数据点的大小并测量所需的分数并将其与固定分数进行比较test set以查看它是如何概括的。对你来说最重要的部分是固定 test set的。如果你要改变test set,理论上你可以,你怎么能通过改变训练大小的大小来评估同一个模型的性能(因为你同时改变了两个数据集)?!

这就是为什么你X,y在 Sklearn 的学习曲线中传递整体,它返回包含train_sizes, train_scores,test_scores的元组。据我了解,它进行了嵌套验证交叉验证。它基本上需要整体X,y,并分为训练/测试(保持测试数据严格独立并固定大小),具体取决于您传递cv参数的方式,并不断增加训练大小并记录性能分数以绘制学习曲线。这确保了对最佳模型性能的适当测量。

关于您的更新 1:刚刚讨论了细节,那么您的更新 1示例场景将是错误的。我们训练一个模型(无论如何),并希望在一个保留数据集上评估它的性能。如果您更改了保留数据集,您将不知道更改训练规模是否会导致测试分数的变化或保留数据集本身的可变性!

关于您的更新 2:这正是我们迄今为止一直在讨论的内容。不管是什么,只要使用相同的方法train_sizetest_size就会保留。1914cv

示例:为了进一步澄清,让我们假设我们有以下场景:

train_sizes = [1, 50, 100, 200, 400, 600]
# X.shape: (1000, 5)
# len(train_sizes)=6

如果我们在 sklearn的learning_curve类中使用以下设置:

cv = ShuffleSplit(n_splits=10, test_size=0.2, random_state=0)
learning_curve(estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes)

由于我们有 6 个 train_size learning_curve返回 6 个点的train_sizes,train_scorestest_scores对于这些点,train_sizesandtest_size看起来像这样:

  • 第1点:train_size:1,test_size:200
  • 第2点:train_size:50,test_size:200
  • 第3点:train_size:100,test_size:200
  • 第4点:train_size:200,test_size:200
  • 第5点:train_size:400,test_size:200
  • 第6点:train_size:600,test_size:200

我认为train_sizes很清楚(取自我们提供的列表)。test_size保持不变,这是因为我们选择test_size=0.2cv回想一下,我们有 1000 个数据点,所以其中 20% 将是 -> 1000 * 0.2 = 200),这与我们的 train_sizes 无关!这是我们在此实验中保持固定的保留集希望最后一个例子能完全澄清它。;-)

我仍然会将那篇博文留在这里作为其他人的参考。