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

Python 线性回归:训练数据的结果很好,测试数据的结果很糟糕,python,scikit-learn,linear-regression,Python,Scikit Learn,Linear Regression,我使用的数据集约为400.000 x 250。 在训练集上测试时,该模型的R^2分数非常高,但在测试集上使用时,该模型的R^2分数非常低,我对此有一个问题。起初,这听起来像是过度装修。但是数据被随机分为训练/测试集,数据集非常大,所以我觉得必须有其他东西。 有什么建议吗 将数据集拆分为训练集和测试集 Sklearn线性回归估计量 度量计算 在训练集上测试时的R^2分数:0,64 在测试集上测试时的R^2分数:-10^23(近似值)虽然我同意Mihai的观点,即你的问题看起来确实过于拟合,但我不一

我使用的数据集约为400.000 x 250。 在训练集上测试时,该模型的R^2分数非常高,但在测试集上使用时,该模型的R^2分数非常低,我对此有一个问题。起初,这听起来像是过度装修。但是数据被随机分为训练/测试集,数据集非常大,所以我觉得必须有其他东西。 有什么建议吗

将数据集拆分为训练集和测试集 Sklearn线性回归估计量 度量计算 在训练集上测试时的R^2分数:0,64


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

虽然我同意Mihai的观点,即你的问题看起来确实过于拟合,但我不一定同意他的回答,即神经网络可以解决你的问题;至少,不是现成的。就其本身而言,神经网络比线性模型拟合得更多,而不是更少。你需要以某种方式来管理你的数据,几乎没有任何模型能为你做到这一点。你可以考虑的几个选项(道歉,我不看数据集就不能更精确):

  • 最简单的事情,使用正则化。400k行是一个很大的数目,但是有了250个尺寸,你几乎可以超出你喜欢的任何尺寸。所以试着用脊线或套索(或弹性网或其他东西)代替线性回归。请参见(套索的优点是可以为您放弃特征,请参见下一点)
  • 特别是如果你想跳出线性模型(你可能应该这样做),最好先降低问题的维度,正如我所说的250是很多。在此处尝试使用一些特征选择技术:
  • 也许最重要的是,你应该考虑调整你的输入数据。我要尝试的第一件事是,假设您真的试图预测代码所暗示的价格,用对数或log(1+x)替换它。否则,线性回归将非常努力地拟合以100万美元售出的单个对象,忽略1k美元以下的所有内容。同样重要的是,检查是否有任何非数字(分类)列,并仅在需要时保留这些列,以防将它们缩减为宏类别:一个包含1000个可能值的分类列将使问题维度增加1000,从而确保过度拟合。每一个输入(如买方名称)都有唯一分类数据的单列将直接引导您实现完美的过度拟合
  • 在所有这些之后(清理数据,通过上述任何一种方法或套索回归减少维度,直到你得到肯定小于dim 100,可能小于20-记住,这包括任何分类数据!),你应该考虑非线性方法来进一步改进你的结果——但是直到你的线性模型为测试数据提供了至少一些积极的R^ 2值时,这是无用的。sklearn提供了很多功能:它是最容易开箱即用的功能(也可以进行正则化),但在您的情况下使用它可能太慢(您应该首先在数据的子集上尝试此功能,以及以下任何功能,例如,在仅选择10或20个功能后,选择1000行,然后看看速度有多慢)。有很多不同的口味,但我认为除了线性的以外,其他的都太慢了。坚持线性的东西,可能是最快的,也是我在这么多样本上训练线性模型的方法。要真正脱离线性,最简单的技术可能包括某种树,要么直接(但这几乎肯定是过度拟合),要么更好,使用某种集成技术(随机森林是典型的go-to算法,梯度增强有时效果更好)。最后,最先进的结果通常是通过神经网络获得的,例如,参见。但是对于这些方法,sklearn通常不是正确的答案,您应该查看专用环境(TensorFlow、Caffe、PyTorch等)。。。然而,如果你不熟悉这些,那当然不值得麻烦
虽然我同意米海的观点,你的问题看起来绝对是过度拟合,但我不一定同意他的回答,即神经网络可以解决你的问题;至少,不是从盒子里出来的。就其本身而言,神经网络比线性模型拟合得更多,而不是更少。你需要以某种方式来管理你的数据,几乎没有任何模型能为你做到这一点。你可以考虑的几个选项(道歉,我不看数据集就不能更精确):

  • 最简单的事情,使用正则化。400k行是一个很大的数目,但是有了250个尺寸,你几乎可以超出你喜欢的任何尺寸。所以试着用脊线或套索(或弹性网或其他东西)代替线性回归。请参见(套索的优点是可以为您放弃特征,请参见下一点)
  • 特别是如果你想跳出线性模型(你可能应该这样做),最好先降低问题的维度,正如我所说的250是很多。在此处尝试使用一些特征选择技术:
  • 也许最重要的是,你应该考虑调整你的输入数据。我要尝试的第一件事是,假设您真的试图预测代码所暗示的价格,用对数或log(1+x)替换它。否则,线性回归将非常努力地拟合以100万美元售出的单个对象,忽略1k美元以下的所有内容。同样重要的是,检查是否有任何非数字(分类)列,并仅在需要时保留这些列,以防将它们缩减为宏类别:一个包含1000个可能值的分类列将使问题维度增加1000,从而确保过度拟合。每一个输入(如买方名称)都有唯一分类数据的单列将直接引导您实现完美的过度拟合
  • 在所有这些之后(清理数据,通过上述任何一种方法或套索回归减少维度,直到你得到肯定小于dim 100,po
    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)
    
    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)