随机森林过拟合?

机器算法验证 分类 随机森林 scikit-学习
2022-01-16 21:15:59

我正在用 scikit-learn 试验随机森林,我的训练集得到了很好的结果,但我的测试集的结果相对较差......

这是我试图解决的问题(灵感来自扑克):给定玩家 A 的底牌、玩家 B 的底牌和翻牌(3 张牌),哪个玩家的手牌最好?从数学上讲,这是 14 个输入(7 张牌——一个等级和一个花色)和一个输出(0 或 1)。

以下是我到目前为止的一些结果:

Training set size: 600k, test set size: 120k, number of trees: 25
Success rate in training set: 99.975%
Success rate in testing set: 90.05%

Training set size: 400k, test set size: 80k, number of trees: 100
Success rate in training set: 100%
Success rate in testing set: 89.7%

Training set size: 600k, test set size: 120k, number of trees: 5
Success rate in training set: 98.685%
Success rate in testing set: 85.69%

以下是使用的相关代码:

from sklearn.ensemble import RandomForestClassifier
Forest = RandomForestClassifier(n_estimators = 25) #n_estimator varies
Forest = Forest.fit(inputs[:trainingSetSize],outputs[:trainingSetSize])
trainingOutputs = Forest.predict(inputs[:trainingSetSize])
testOutputs = Forest.predict(inputs[trainingSetSize:])

似乎无论使用多少树,训练集的性能都比测试集好得多,尽管训练集相对较大且特征数量相当少......

2个回答

这是使用 RF 模型时常见的新手错误(我会举手作为以前的肇事者)。当整体考虑时,您使用训练集构建的森林在许多情况下将几乎完美地拟合训练数据(如您所发现的)。然而,当算法构建森林时,它会记住袋外 (OOB) 预测误差,这是它对泛化误差的最佳猜测。

如果您将训练数据发送回预测方法(正如您所做的那样),您将得到这个几乎完美的预测(非常乐观),而不是正确的 OOB 错误。不要这样做。相反,经过训练的 Forest 对象应该在其中记住 OOB 错误。我不熟悉 scikit-learn 的实现,但是看这里的文档看起来你需要oob_score=True在调用 fit 方法时指定,然后泛化错误将存储为oob_score_在返回的对象中。在 R 包“randomForest”中,在返回的对象上调用不带参数的 predict 方法将返回训练集上的 OOB 预测。这使您可以使用其他度量来定义错误。将训练集发送回预测方法会给你一个不同的结果,因为这将使用所有的树。我不知道scikit-learn实施是否会这样做。

将训练数据发送回预测方法以测试准确性是错误的。不过,这是一个非常常见的错误,所以不要担心。

我认为答案是 max_features 参数:int、string 或 None,可选(默认 =“auto”)参数。基本上对于这个问题,您应该将其设置为 None ,以便每棵树都使用所有输入构建,因为显然您无法仅使用一小部分卡片构建正确的分类器(默认“自动”选择 sqrt(nfeatures)每棵树的输入)