我们在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项?)。运行的数据本质上是根据天气模式对商品消费进行预测,而天气模式一开始是一个杂乱的空间,因此应该存在很多错误。

我在这里做错了什么?

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



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

python - scikit-learn回归预测结果太好了。我搞砸了什么?-LMLPHP

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

python - scikit-learn回归预测结果太好了。我搞砸了什么?-LMLPHP

这是第2栏,如评论所问
python - scikit-learn回归预测结果太好了。我搞砸了什么?-LMLPHP



解!

正如@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

最佳答案

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

关于python - scikit-learn回归预测结果太好了。我搞砸了什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51622144/

10-11 07:46