如何解决Python Sklearn中随机森林的过度拟合问题?

2,509 阅读5分钟

在这篇文章中,我们将看到如何用Python解决Sklearn中随机森林的过拟合问题。

什么是过拟合?

过度拟合 是一个常见的现象,你在训练一个 机器学习模型。过度拟合发生在模型学习模式以及模型所训练的数据的噪声。具体来说,模型会捕捉到训练数据中观察到的特定模式,但并不能推广到其他观察中。因此,模型能够对它所训练的数据做出很好的预测,但却不能对它在训练期间没有看到的数据做出很好的预测。

为什么过拟合是个问题?

过度拟合是一个问题,因为机器学习模型的训练目的是为了对未见过的数据进行预测。过度拟合其训练数据集的模型无法对训练期间没有看到的新数据做出良好的预测,所以它们无法对未见过的数据做出预测。

如何检查你的模型是否对训练数据过度拟合?

为了检查你的模型是否对训练数据过度拟合,你应该确保将你的数据集分成一个训练数据集,用来训练你的模型,和一个测试数据集,在模型训练期间完全不接触。这样你就会有一个模型在训练期间完全没有看到的数据集可用,你可以用它来评估你的模型是否过度拟合。

一般来说,你应该把大约70%的数据分配给训练数据集,30%的数据分配给测试数据集。只有当你在训练数据集上训练你的模型,并优化和你计划优化的超参数之后,你才应该使用你的测试数据集。这时,你可以用你的模型对测试数据和训练数据进行预测,然后比较测试数据和训练数据的性能。 度量然后比较在测试和训练数据上的表现。

如果你的模型对训练数据过度拟合,你会发现训练数据上的性能指标要比测试数据上的性能指标好得多。

如何防止python sklearn的随机森林过拟合?

超参数 对于任何这样的问题,如果我们想在不改变现有数据集的情况下提升模型的性能,调谐就是答案。但在探索哪些超参数可以帮助我们之前,让我们先了解一下 随机森林模型工作原理。

随机森林模型是多个决策树的堆叠,通过结合每个决策树的结果,准确率急剧上升。基于这个对随机森林模型的简单解释,我们可以在加载随机森林模型的实例时调整多个超参数,以帮助我们调整过度拟合。

  1. max_depth。 这控制了我们的决策树有多深或有多少层。
  2. n_estimators。 这控制了每一层中的决策树的数量。这个参数和前面的参数在很大程度上解决了过度拟合的问题。
  3. 准则。 在训练随机森林时,数据被分割成若干部分,这个参数控制这些分割的方式。
  4. min_samples_leaf。 这决定了叶子结点的最小数量。
  5. min_samples_split。 这决定了分割代码所需的最小样本数。
  6. max_leaf_nodes: 这决定了叶子节点的最大数量。

还有更多的参数,我们可以通过调整来调整过拟合问题,但上面提到的参数在大多数情况下更有效地达到了目的。

注意:-

一个随机森林模型可以在不考虑这些超参数的情况下加载,因为一些默认值总是分配给这些参数,我们可以明确地控制它们来达到我们的目的。

现在让我们用数据集来探索一下这些超参数。

导入库

Python库在很大程度上简化了数据处理和操作相关的任务。

Python3

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn import metrics

我们将从sklearn加载分类任务的假数据集。

Python3

X, y = datasets.make_classification()
X_train, X_val, Y_train, Y_val = train_test_split(X,
                                                  y,
                                                  test_size = 0.2,
                                                  random_state=2022)
print(X_train.shape, X_val.shape)

输出。

(80, 20) (20, 20)

让我们在这个数据集上训练一个RandomForestClassifer,不要使用任何超参数。

Python3

model = RandomForestClassifier()
model.fit(X_train, Y_train)
print('Training Accuracy : ',
      metrics.accuracy_score(Y_train,
                             model.predict(X_train))*100)
print('Validation Accuracy : ',
      metrics.accuracy_score(Y_val,
                             model.predict(X_val))*100)

输出。

Training Accuracy :  100.0
Validation Accuracy :  75.0

在这里我们可以看到,训练准确率是100%,但验证准确率只有75%,与训练准确率相比,这意味着模型对训练数据过度拟合。为了解决这个问题,首先让我们使用参数max_depth

Python3

model = RandomForestClassifier(max_depth=2,
                               random_state=22)
model.fit(X_train, Y_train)
print('Training Accuracy : ',
      metrics.accuracy_score(Y_train,
                             model.predict(X_train))*100)
print('Validation Accuracy : ',
      metrics.accuracy_score(Y_val,
                             model.predict(X_val))*100)

输出。

Training Accuracy :  95.0
Validation Accuracy :  75.0

从25%的差异,我们仅仅通过调整一个超参数的值,就实现了20%的差异。同样地,让我们使用n_estimators。

Python3

model = RandomForestClassifier(n_estimators=30,
                               random_state=22)
model.fit(X_train, Y_train)
print('Training Accuracy : ',
      metrics.accuracy_score(Y_train,
                             model.predict(X_train))*100)
print('Validation Accuracy : ',
      metrics.accuracy_score(Y_val,
                             model.predict(X_val))*100)

输出。

Training Accuracy :  100.0
Validation Accuracy :  85.0

再次通过修剪另一个超参数,我们能更多地解决过度拟合的问题。

Python3

model = RandomForestClassifier(
    max_depth=2, n_estimators=30,
    min_samples_split=3, max_leaf_nodes=5,
    random_state=22)
 
model.fit(X_train, Y_train)
print('Training Accuracy : ',
      metrics.accuracy_score(
          Y_train, model.predict(X_train))*100)
 
print('Validation Accuracy : ', metrics.accuracy_score(
    Y_val, model.predict(X_val))*100)

输出。

Training Accuracy :  95.0
Validation Accuracy :  80.0

如上所示,我们也可以使用多个参数来轻松修剪过拟合。

总结

超参数调整是为了在相同的数据量下获得更好的性能。在这篇文章中,我们看到了如何提高RandomForestClassifier的性能,同时解决过拟合的问题。