scikit-learn 回归预测结果太好了。我搞砸了什么?
scikit-learn regression prediction results are too good. What did I mess up?
我们在 Azure 中的 Azure ML Studio 平台(初始拖放系统)之上有一些 ML 模型 运行。一年多来一切都很好,但我们需要继续前进,这样我们才能更好地扩展。所以我正在使用 scikit-learn 在 Python 中重写这些,并在 Jupyter notebook 中测试它们。
好消息是 news/bad 我们要训练的数据相当小(数据库中有几百条记录)。这是非常不完美的数据做出非常不完美的回归预测,所以错误是可以预料的。这很好。对于这个问题,这很好。因为问题是,当我测试这些模型时,预测太完美了。我不明白我做错了什么,但我显然做错了某事。
(在我看来)明显值得怀疑的事情是,要么我正在训练测试数据,要么通过相关性发现 obvious/perfect 因果关系。我对 train_test_split
的使用告诉我我没有在我的测试数据上训练,我保证第二个是错误的,因为这个 space 是多么混乱(我们开始对这个数据进行手动线性回归大约 15几年前,并且仍然维护 Excel 电子表格以便能够在紧要关头手动完成它,即使它的准确性明显低于我们的 Azure ML Studio 模型)。
让我们看一下代码。这是我的 Jupyter notebook 的相关部分(抱歉,如果有更好的格式化方式):
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))
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 项?)。 运行 提供的数据本质上是根据天气模式对商品消费进行预测,开始时有点混乱 space,因此应该存在很多错误。
我做错了什么?
(另外,如果我能以更好的方式提出这个问题或提供更多有用的信息,我将不胜感激!)
这是数据的热图。我指出了我们预测的值。
我还绘制了一些更重要的输入与我们预测的值(按另一个维度进行颜色编码):
这是评论中提到的第 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)
有了这个,我的错误和分数比我预期的要多:
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 共同确定。要解决此问题,请考虑对 X 执行 Y 的线性回归,然后使用简单的 p 值或 AIC/BIC以确定哪些 X 变量最不相关。放下这些并重复该过程,直到您的 R^2 开始严重下降(尽管每次都会下降一点)。其余变量将与预测最相关,希望您能够从该子集中识别出哪些变量与 Y 密切相关。
我们在 Azure 中的 Azure ML Studio 平台(初始拖放系统)之上有一些 ML 模型 运行。一年多来一切都很好,但我们需要继续前进,这样我们才能更好地扩展。所以我正在使用 scikit-learn 在 Python 中重写这些,并在 Jupyter notebook 中测试它们。
好消息是 news/bad 我们要训练的数据相当小(数据库中有几百条记录)。这是非常不完美的数据做出非常不完美的回归预测,所以错误是可以预料的。这很好。对于这个问题,这很好。因为问题是,当我测试这些模型时,预测太完美了。我不明白我做错了什么,但我显然做错了某事。
(在我看来)明显值得怀疑的事情是,要么我正在训练测试数据,要么通过相关性发现 obvious/perfect 因果关系。我对 train_test_split
的使用告诉我我没有在我的测试数据上训练,我保证第二个是错误的,因为这个 space 是多么混乱(我们开始对这个数据进行手动线性回归大约 15几年前,并且仍然维护 Excel 电子表格以便能够在紧要关头手动完成它,即使它的准确性明显低于我们的 Azure ML Studio 模型)。
让我们看一下代码。这是我的 Jupyter notebook 的相关部分(抱歉,如果有更好的格式化方式):
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))
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 项?)。 运行 提供的数据本质上是根据天气模式对商品消费进行预测,开始时有点混乱 space,因此应该存在很多错误。
我做错了什么?
(另外,如果我能以更好的方式提出这个问题或提供更多有用的信息,我将不胜感激!)
这是数据的热图。我指出了我们预测的值。
我还绘制了一些更重要的输入与我们预测的值(按另一个维度进行颜色编码):
这是评论中提到的第 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)
有了这个,我的错误和分数比我预期的要多:
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 共同确定。要解决此问题,请考虑对 X 执行 Y 的线性回归,然后使用简单的 p 值或 AIC/BIC以确定哪些 X 变量最不相关。放下这些并重复该过程,直到您的 R^2 开始严重下降(尽管每次都会下降一点)。其余变量将与预测最相关,希望您能够从该子集中识别出哪些变量与 Y 密切相关。