首页 > 解决方案 > scikit-learn 回归预测结果太好了。我搞砸了什么?

问题描述

我们在 Azure ML Studio 平台(最初的拖放系统)之上的 Azure 中运行了一些 ML 模型。一年多来一切都很好,但我们需要继续前进,这样我们才能更好地扩展。因此,我正在使用 scikit-learn 在 Python 中重写这些,并在 Jupyter 笔记本中对其进行测试。

好消息/坏消息是我们要训练的数据相当小(数据库中有数百条记录)。这是非常不完美的数据,做出了非常不完美的回归预测,所以错误是可以预料的。这很好。对于这个问题,很好。因为问题是,当我测试这些模型时,预测太完美了。我不明白我做错了什么,但我显然做错了什么

显而易见的事情(在我看来)是我正在对测试数据进行训练,或者通过相关性发现了明显/完美的因果关系。我的使用train_test_split告诉我我没有对我的测试数据进行训练,我保证第二个是错误的,因为这个空间是多么的混乱(我们大约 15 年前开始对这些数据进行手动线性回归,并且仍然维护 Excel 电子表格能够在紧要关头手动完成,即使它比我们的 Azure ML Studio 模型准确得多)。

让我们看一下代码。这是我的 Jupyter 笔记本的相关部分(抱歉,如果有更好的格式化方法):

X = myData
y = myData.ValueToPredict
X_train, X_test, y_train, y_test = train_test_split(
    X, 
    y, 
    train_size = 0.75,
    test_size = 0.25)
print("X_train: ", X_train.shape)
print("y_train: ", y_train.shape)
print("X_test:  ", X_test.shape)
print("y_test:  ", y_test.shape)

X_train: (300, 17)

y_train: (300,)

X_test: (101, 17)

y_test: (101,)

ESTIMATORS = {
    "Extra Trees": ExtraTreesRegressor(criterion = "mse",
                                       n_estimators=10,
                                       max_features=16,
                                       random_state=42),
    "Decision Tree": DecisionTreeRegressor(criterion = "mse",
                                  splitter = "best",
                                       random_state=42),
    "Random Forest": RandomForestRegressor(criterion = "mse",
                                       random_state=42),
    "Linear regression": LinearRegression(),
    "Ridge": RidgeCV(),
}

y_test_predict = dict()
y_test_rmse = dict()
for name, estimator in ESTIMATORS.items():
    estimator.fit(X_train, y_train)
    y_test_predict[name] = estimator.predict(X_test)
    y_test_rmse[name] = np.sqrt(np.mean((y_test - y_test_predict[name]) ** 2)) # I think this might be wrong but isn't the source of my problem
for name, error in y_test_rmse.items():
    print(name + " RMSE: " + str(error))

额外树 RMSE:0.3843540838630157

决策树 RMSE:0.32838969545222946

随机森林 RMSE:0.4304701784728594

线性回归 RMSE:7.971345895791494e-15

岭 RMSE:0.0001390197344951183

y_test_score = dict()
for name, estimator in ESTIMATORS.items():
    estimator.fit(X_train, y_train)
    y_test_predict[name] = estimator.predict(X_test)
    y_test_score[name] = estimator.score(X_test, y_test)
for name, error in y_test_score.items():
    print(name + " Score: " + str(error))

额外树分数:0.9990166492769291

决策树得分:0.999282165241745

随机森林分数:0.998766521504593

线性回归分数:1.0

岭分数:0.9999999998713534

我想也许我做错了错误指标,所以我只看了简单的分数(这就是我把两者都包括在内的原因)。然而,两者都表明这些预测好得令人难以置信。请记住,输入量很小(总共约 400 项?)。运行的数据本质上是根据天气模式对商品消费进行预测,这从一开始就是一个混乱的空间,因此应该存在很多错误。

我在这里做错了什么?

(另外,如果我能以更好的方式提出这个问题或提供更多有用的信息,我将不胜感激!)


这是数据的热图。我指出了我们预测的值。

数据的 Seaborn 热图

我还绘制了一些更重要的输入与我们预测的值(由另一个维度进行颜色编码):

我们预测的值图

这是第 2 列,如评论中所述 另一个情节


解决方案!

正如@jwil 所指出的,我并没有将我的ValueToPredict列从我的X变量中拉出来。解决方案是添加一个单行以删除该列:

X = myData
y = myData.ValueToPredict
X = X.drop("ValueToPredict", 1) # <--- ONE-LINE FIX!
X_train, X_test, y_train, y_test = train_test_split(
    X, 
    y, 
    train_size = 0.75,
    test_size = 0.25)

有了这个,我的错误和分数就比我期望的要高得多:

额外树 RMSE:1.6170428819849574

决策树 RMSE:1.990459810552763

随机森林 RMSE:1.699801032532343

线性回归 RMSE:2.5265108241534397

岭 RMSE:2.528721533965162

额外树分数:0.9825944193611161

决策树得分:0.9736274412836977

随机森林得分:0.9807672396970707

线性回归分数:0.9575098985510281

岭分数:0.9574355079097321

标签: pythonmachine-learningscikit-learnazure-machine-learning-studio

解决方案


你是对的; 我强烈怀疑您的 X 数据中有一个或多个与 Y 数据几乎完全相关的特征。通常这很糟糕,因为这些变量不能解释 Y,而是由 Y 解释或与 Y 共同确定。要解决此问题,请考虑对 X 执行 Y 的线性回归,然后使用简单的 p 值或 AIC/BIC 来确定哪些 X 变量是最不相关的。放下这些并重复这个过程,直到你的 R^2 开始严重下降(尽管每次都会下降一点)。其余变量将与预测最相关,希望您能够从该子集中确定哪些变量与 Y 密切相关。


推荐阅读