首页 > 解决方案 > 为什么我在手动拆分测试和训练数据而不是使用 Python 拆分功能时会得到不同的结果

问题描述

如果我通过 train_test_split 函数使用数据运行一个简单的 dtree 回归模型,我会得到很好的 r2 分数和低 mse 值。

training_data = pandas.read_csv('data.csv',usecols=['y','x1','x2','x3'])
y = training_data.iloc[:,0]
x = training_data.iloc[:,1:]
X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.33)
regressor = DecisionTreeRegressor(random_state = 0)  
# fit the regressor with X and Y data 
regressor.fit(X_train, y_train)
y_pred = regressor.predict(X_test)

但是,如果我将数据文件手动拆分为两个文件 2/3 训练和 1/3 测试。有一个名为 human 的列,它给出的值是 1 到 9,它是人类,我使用人类 1-6 进行训练,使用 7-9 进行测试

我得到负 r2 分数和高 mse

training_data = pandas.read_csv("train"+".csv",usecols=['y','x1','x2','x3'])
testing_data  = pandas.read_csv("test"+".csv", usecols=['y','x1','x2','x3'])

y_train = training_data.iloc[:,training_data.columns.str.contains('y')]
X_train = training_data.iloc[:,training_data.columns.str.contains('|'.join(['x1','x2','x3']))] 
y_test = testing_data.iloc[:,testing_data.columns.str.contains('y')]
X_test = testing_data.iloc[:,testing_data.columns.str.contains('|'.join(l_vars))] 

y_train = pandas.Series(y_train['y'], index=y_train.index)
y_test = pandas.Series(y_test['y'], index=y_test.index)

regressor = DecisionTreeRegressor(random_state = 0)  
regressor.fit(X_train, y_train)
y_pred = regressor.predict(X_test)

我期待或多或少相同的结果,并且两个调用的所有数据类型似乎都相同。

我错过了什么?

标签: pythondataframemodeling

解决方案


我假设这两种方法实际上都在做你想做的事情,并且你的 X_train/test 和 y_train/tests 的形状来自这两种方法是相同的。您可以绘制数据集的底层分布,也可以将您的第二个实现与交叉验证的模型进行比较(以获得更好的严谨性)。


绘制初始训练中标签 (y) 的分布(即制作条形图/密度图) - 测试集与第二个训练集(来自手动实现)。您可以深入研究并在数据中绘制其他列,查看两个实现的结果集之间的数据分布是否有任何不同。如果分布不同,那么您的两个模型之间就会出现差异。如果您的差异很大,则可能是您的标签(或其他列)实际上是针对您的手动实施进行排序的,因此您在比较的数据集中会得到非常不同的分布。

此外,如果您想确保您的手动拆分结果是基于模型结果而不是基础数据分布的“代表性”集合(可以很好地概括),我会将其与交叉验证模型的结果进行比较,而不是一组结果。

从本质上讲,尽管概率很小并且进行了train_test_split一些改组,但您基本上可以得到一个表现良好的“训练/测试”对,只是运气不好。(为了在不进行交叉验证的情况下减少这种情况的可能性,我建议使用函数的stratify参数train_test_split。那么至少你确定第一个实现“更努力地”获得平衡的训练/测试对。)

如果您决定交叉验证(使用test_train_split),您将获得折叠的平均模型预测及其周围的置信区间,并可以检查您的第二个模型结果是否在该区间内。如果它没有再次出现,这只是意味着您的拆分实际上以某种方式“损坏”(例如,通过排序值)。


PS我还要补充一点,决策树是已知会大量过度拟合的模型[1]。也许改用随机森林?(由于引导/装袋,您应该获得更稳定的结果,这将类似于交叉验证以减少过度拟合的机会。)

1 - http://cv.znu.ac.ir/afsharhim/AI/lectures/Decision%20Trees%203.pdf


推荐阅读