python - KFold 交叉验证不能修复过度拟合
问题描述
我将特征分开X
,y
然后在用 k 折交叉验证拆分后对我的训练测试数据进行预处理。之后,我将训练数据拟合到我的随机森林回归模型并计算置信度得分。为什么拆分后要进行预处理?因为人们告诉我这样做更正确,而且为了我的模型性能,我一直保持这个原则。
这是我第一次使用 KFold 交叉验证,因为我的模型得分过分,我认为我可以通过交叉验证来修复它。我仍然对如何使用它感到困惑,我已经阅读了文档和一些文章,但我并没有真正理解我如何真正将它暗示给我的模型,但我还是尝试了,但我的模型仍然过拟合。使用训练测试拆分或交叉验证导致我的模型得分仍然是 0.999,我不知道我的错误是什么,因为我是使用这种方法的新手,但我想也许我做错了,所以它不能解决过度拟合。请告诉我我的代码有什么问题以及如何解决这个问题
import pandas as pd
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
from sklearn.impute import SimpleImputer
from sklearn.model_selection import train_test_split
from sklearn.model_selection import KFold
from sklearn.preprocessing import LabelEncoder
from sklearn.ensemble import RandomForestRegressor
import scipy.stats as ss
avo_sales = pd.read_csv('avocados.csv')
avo_sales.rename(columns = {'4046':'small PLU sold',
'4225':'large PLU sold',
'4770':'xlarge PLU sold'},
inplace= True)
avo_sales.columns = avo_sales.columns.str.replace(' ','')
x = np.array(avo_sales.drop(['TotalBags','Unnamed:0','year','region','Date'],1))
y = np.array(avo_sales.TotalBags)
# X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
kf = KFold(n_splits=10)
for train_index, test_index in kf.split(x):
X_train, X_test, y_train, y_test = x[train_index], x[test_index], y[train_index], y[test_index]
impC = SimpleImputer(strategy='most_frequent')
X_train[:,8] = impC.fit_transform(X_train[:,8].reshape(-1,1)).ravel()
X_test[:,8] = impC.transform(X_test[:,8].reshape(-1,1)).ravel()
imp = SimpleImputer(strategy='median')
X_train[:,1:8] = imp.fit_transform(X_train[:,1:8])
X_test[:,1:8] = imp.transform(X_test[:,1:8])
le = LabelEncoder()
X_train[:,8] = le.fit_transform(X_train[:,8])
X_test[:,8] = le.transform(X_test[:,8])
rfr = RandomForestRegressor()
rfr.fit(X_train, y_train)
confidence = rfr.score(X_test, y_test)
print(confidence)
解决方案
您过度拟合的原因是因为非正则化的基于树的模型将根据数据进行调整,直到所有训练样本都被正确分类。例如,请参见此图像:
如您所见,这并不能很好地概括。如果您不指定规范化树的参数,该模型将无法很好地拟合测试数据,因为它基本上只会学习训练数据中的噪声。有很多方法可以对树进行正则化,您可以在此处sklearn
找到它们。例如:
- 最大特征
- min_samples_leaf
- 最大深度
通过适当的正则化,您可以获得一个很好地概括测试数据的模型。例如,看一个正则化模型:
要规范您的模型,请像这样实例化RandomForestRegressor()
模块:
rfr = RandomForestRegressor(max_features=0.5, min_samples_leaf=4, max_depth=6)
这些参数值是任意的,由您决定最适合您的数据的值。您可以使用特定领域的知识来选择这些值,或者使用超参数调整搜索,如GridSearchCV
或RandomizedSearchCV
。
除此之外,估算平均值和中位数可能会给您的数据带来很多噪音。除非您别无选择,否则我建议您不要这样做。
推荐阅读
- mongodb - 密码标志无法登录 mongo
- c# - 通过 LINQ 嵌套组到嵌套对象
- reactjs - ReactJS 无法在未安装的组件上调用 setState(或 forceUpdate)
- java - 填充Jcombobox模型
- ios - 如何按索引访问特定行
- php - 在linux终端中批量替换字符串
- java - IntellliJ 2018 + Exploded War + Tomcat:过滤 index.html 的问题
- openshift - Open-shift-Running 处理程序 [openshift_master : 验证 API 服务器] 失败 - 重试验证 API 服务器
- mule - 在 Mulesoft Web 服务使用者中启用 WS-Addressing
- c# - 以 MVVM 方式添加控件,但不直接声明控件类型