我们在Azure上运行了一些机器学习模型,基于Azure ML Studio平台(最初的拖放系统)。一年多来一切顺利,但为了更好地扩展,我们需要进行升级。因此,我正在使用scikit-learn重写这些模型,并在Jupyter笔记本中进行测试。
好消息/坏消息是,我们用于训练的数据量相当小(数据库中有几百条记录)。这些数据非常不完善,导致回归预测也非常不完善,因此出现误差是可以预料的。这也没关系。对于这个问题来说,这很好。因为问题在于,当我测试这些模型时,预测结果过于完美。我不明白自己哪里做错了,但我显然是做错了某些事情。
在我看来,最明显的嫌疑是,要么我在测试数据上进行训练,要么是通过相关性发现了明显/完美的因果关系。我使用train_test_split
表明我并没有在测试数据上进行训练,我保证第二种情况是错误的,因为这个领域非常混乱(我们大约15年前开始对这些数据进行手动线性回归,并且仍然维护Excel电子表格,以便在必要时手动进行,尽管这比我们的Azure ML Studio模型明显不够准确)。
让我们看看代码。这是我的Jupyter笔记本中相关部分(如果有更好的格式方式,请原谅):
X = myDatay = myData.ValueToPredictX_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)) # 我认为这可能有错,但不是我问题的根源for name, error in y_test_rmse.items(): print(name + " RMSE: " + str(error))
Extra Trees RMSE: 0.3843540838630157
Decision Tree RMSE: 0.32838969545222946
Random Forest RMSE: 0.4304701784728594
Linear regression RMSE: 7.971345895791494e-15
Ridge 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))
Extra Trees Score: 0.9990166492769291
Decision Tree Score: 0.999282165241745
Random Forest Score: 0.998766521504593
Linear regression Score: 1.0
Ridge Score: 0.9999999998713534
我以为可能是我的误差度量方法有问题,所以我只是简单地查看了一些分数(这就是为什么我同时包括了这两者)。然而,这两者都显示这些预测结果好得令人难以置信。请记住,输入数据的数量很小(总共约400项?)。而且这些数据基本上是根据天气模式预测商品消耗,这本身就是一个混乱的领域,因此应该存在很多误差。
我在这里哪里做错了?
(另外,如果我能以更好的方式提出这个问题或提供更多有用的信息,我将不胜感激!)
这是数据的热图。我标出了我们要预测的值。
我还绘制了一些更重要的输入与我们要预测的值的对比图(通过另一个维度进行颜色编码):
解决方案!
正如@***所指出的,我没有从我的X
变量中提取我的ValueToPredict
列。解决方案是添加一行代码来删除该列:
X = myDatay = myData.ValueToPredictX = X.drop("ValueToPredict", 1) # <--- 一行修复!X_train, X_test, y_train, y_test = train_test_split( X, y, train_size = 0.75, test_size = 0.25)
有了这个,我的误差和分数更接近我预期的水平:
Extra Trees RMSE: 1.6170428819849574
Decision Tree RMSE: 1.990459810552763
Random Forest RMSE: 1.699801032532343
Linear regression RMSE: 2.5265108241534397
Ridge RMSE: 2.528721533965162
Extra Trees Score: 0.9825944193611161
Decision Tree Score: 0.9736274412836977
Random Forest Score: 0.9807672396970707
Linear regression Score: 0.9575098985510281
Ridge Score: 0.9574355079097321
回答:
你是对的;我强烈怀疑你的X数据中有一个或多个特征与Y数据几乎完美相关。通常这是不好的,因为这些变量并不能解释Y,而是由Y解释或与Y共同决定。为了解决这个问题,考虑对Y进行基于X的线性回归,然后使用简单的p值或AIC/BIC来确定哪些X变量最不相关。删除这些变量并重复此过程,直到你的R^2开始显著下降(虽然每次都会稍微下降)。剩下的变量将是预测中最相关的,并且希望你能从这个子集中识别出哪些变量与Y如此紧密相关。