线性回归:训练数据的结果很好,测试数据很糟糕

时间:2018-06-11 07:21:44

标签: python scikit-learn linear-regression

我正在使用大约400.000 x 250的数据集。 我在训练集上测试它时,模型产生了非常好的R ^ 2分数,但在测试集上使用时效果极差。最初,这听起来像是过度拟合。但数据随机分成训练/测试集,数据集非常大,所以我觉得必须要有别的东西。 有什么建议吗?

将数据集拆分为训练集和测试集

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(df.drop(['SalePrice'], 
axis=1), df.SalePrice, test_size = 0.3)

Sklearn的线性回归估计器

from sklearn import linear_model
linReg = linear_model.LinearRegression()    # Create linear regression object
linReg.fit(X_train, y_train)                # Train the model using the training sets

# Predict from training set
y_train_linreg = linReg.predict(X_train)

# Predict from test set
y_pred_linreg = linReg.predict(X_test)

度量标准计算

from sklearn import metrics
metrics.r2_score(y_train, y_train_linreg)
metrics.r2_score(y_test, y_pred_linreg)
在训练集上进行测试时,

R ^ 2得分:0,64

在测试集上测试时得到R ^ 2得分:-10 ^ 23(近似值)

1 个答案:

答案 0 :(得分:3)

虽然我同意Mihai的说法,你的问题肯定看起来过度拟合,但我不一定同意他的答案,神经网络可以解决你的问题;至少,没有开箱即用。神经网络本身比线性模型更适合而不是更少。您需要以某种方式处理您的数据,几乎没有任何模型可以为您做到这一点。您可能会考虑一些选项(道歉,如果不查看数据集,我就不能更精确):

  • 最简单的事情,使用正规化。 400k行很多,但有250个尺寸,几乎可以随心所欲。因此,尝试用Ridge或Lasso(或Elastic Net或其他)替换LinearRegression。请参阅http://scikit-learn.org/stable/modules/linear_model.html(Lasso具有为您丢弃功能的优势,请参阅下一点)
  • 特别是如果你想要走出线性模型之外(你可能应该这样做),建议首先减少问题的维度,因为我说250很多。尝试使用一些功能选择技术:http://scikit-learn.org/stable/modules/feature_selection.html
  • 可能最重要的是,您应该考虑调整输入数据。我要尝试的第一件事是,假设你真的试图预测代码所暗示的价格,用它的对数或log(1 + x)来代替它。否则,线性回归将非常难以适应以1百万美元出售的单个对象,忽略低于1千美元的所有东西。同样重要的是,检查您是否有任何非数字(分类)列,并仅在需要时保留它们,以防将它们减少为宏类别:具有1000个可能值的分类列将使您的问题维度增加1000,这是一个有保障的装备。每个输入(例如买方名称)具有唯一分类数据的单个列将引导您直接完美过度拟合。
  • 在完成所有这些之后(清理数据,通过上述任何一种方法减少尺寸,或只是通过Lasso回归直到你得到肯定小于100,可能小于20 - 并记住这包括任何分类数据!),你应该考虑使用非线性方法来进一步改善结果 - 但是在您的线性模型为测试数据提供至少一些温和的R ^ 2值之前,这是无用的。 sklearn提供了很多:http://scikit-learn.org/stable/modules/kernel_ridge.html是最容易使用的开箱即用(也是正规化),但它可能在你的情况下使用太慢(你应该首先尝试这个,任何以下内容,对于您的数据的一个子集,一旦您只选择了10或20个特征,就会说1000行,看看它有多慢。 http://scikit-learn.org/stable/modules/svm.html#regression有许多不同的味道,但我认为除了线性之外的所有都会太慢。坚持线性事物,http://scikit-learn.org/stable/modules/sgd.html#regression可能是最快的,我将如何在这么多样本上训练线性模型。真正脱离线性,最简单的技术可能包括某种树,直接http://scikit-learn.org/stable/modules/tree.html#regression(但这几乎是一定的过度拟合),或者更好的是,使用一些整体技术(随机森林http://scikit-learn.org/stable/modules/ensemble.html#forests-of-randomized-trees是典型的定位算法,梯度增强http://scikit-learn.org/stable/modules/ensemble.html#gradient-tree-boosting有时效果更好)。最后,通常通过神经网络获得最先进的结果,参见例如。 http://scikit-learn.org/stable/modules/neural_networks_supervised.html但是对于这些方法,sklearn通常不是正确的答案,你应该看看专用环境(TensorFlow,Caffe,PyTorch等)......但如果你不熟悉它们肯定是不值得的麻烦!