SciKit-Learn:使用线性回归的天文误差

时间:2017-06-26 21:19:11

标签: python machine-learning scikit-learn

我正在尝试从标题长度+文章的文本内容预测文章的页面浏览量。我使用TFIDF如下:

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
corpus = result_df['_text'].tolist()
count_vect = CountVectorizer(min_df=1, stop_words='english')
dtm = count_vect.fit_transform(corpus)
word_counts = dtm.toarray()
tfidf_transformer = TfidfTransformer()
tfidf = tfidf_transformer.fit_transform(word_counts)
words_df = pd.DataFrame(tfidf.todense(), columns=count_vect.get_feature_names())

我正在使用这样的标准缩放:

from sklearn import preprocessing
scaler = preprocessing.StandardScaler()
result_df['_title'] = scaler.fit_transform(result_df['_title'])

所以我得到我的X如下:

_title  00  000 0002    0003    000667  000709  000725  001 0013    ... última  últimamente último  única   únicamente  único   únicos  útiles  네일_박은경  유니스텔라
0   62  0.000000    0.000000    0.0 0.0 0.0 0.0 0.0 0.000000    0.0 ... 0.000000    0.0 0.0 0.0 0.0 0.000000    0.0 0.0 0.0 0.0
1   41  0.000000    0.000000    0.0 0.0 0.0 0.0 0.0 0.000000    0.0 ... 0.000000    0.0 0.0 0.0 0.0 0.000000    0.0 0.0 0.0 0.0
2   53  0.000000    0.020781    0.0 0.0 0.0 0.0 0.0 0.000000    0.0 ... 0.000000    

我的Y(目标值)如下所示:

0        166.0
1         24.0
2         22.0

现在,我尝试运行一个基本的线性回归,得到一个绝对天文的均方根误差(RMSE):

from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X.as_matrix(), Y, test_size=0.2)

from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
import numpy as np
lin_reg = LinearRegression()
lin_reg.fit(X_train, Y_train)
views_predictions = lin_reg.predict(X_test)
lin_mse = mean_squared_error(Y_test, views_predictions)
lin_rmse = np.sqrt(lin_mse) //value is 770956447401244.75

我的平均Y值是1,487,它的标准差是~8,000,所以这个数字不可能是正确的。即使每次都猜相同的数字也会大大超过这个数字。

有趣的是,当我使用DecisionTreeRegressor时,我看到一个看似合理的RMSE为15053.957646453207(仍然高,但远不及线性回归)。

知道这里发生了什么吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

如此高的错误结果很可能过度拟合

过度拟合的根本原因是你有许多功能(可能有数万个不同的单词),可能没有那么多的例子。通过线性回归,任何单个特征都可能导致灾难性的错误。

想象一下,例如,在您的火车数据中,“aardvark"仅在一篇文章中出现过一次,并且有一篇文章看到1000篇观点比同行更受欢迎。因此,您的线性模型为特征" aardvark"分配了1000的系数。在测试数据中,你有一篇关于aardvarks的文章,其中这个词出现了1000次。你的模特得分为1000000!但一些土豚爱好者只看了3次。所以你有一个999997的erorr。

你怎么能避免这种可怕的过度拟合?

  1. 使用较少的功能。您可以使用CountVectorizer(min_df=10)计算单词,以仅使用至少10个不同文档中出现的单词。这样可以减少过度拟合稀有词语的几率。
  2. 规范您的模型。如果您使用RidgeLasso代替LinearRegression,则可能会获得更好的效果。根据我自己的经验,对tf-idf矩阵的岭回归与GBM和nearal网络一样好。
  3. 最后一条建议。您的目标(文章视图)可能具有非常不对称的分布:很少有非常受欢迎的文章和许多不重要的文章。有了这样的目标,该模型可能会被少数顶级文章所主导。为了避免这种情况,您可以对目标进行标准化,例如,通过预测其对数或其他凹变换。它可以从排名的角度改善您的模型性能(例如,增加事实和预测之间的相关性)。