KNeighbors Regressor .predict() 函数在使用 weights='distance' 训练时给出了令人怀疑的完美结果?

KNeighbors Regressor .predict() function giving suspiciously perfect results when trained with weights='distance'?

如果我训练 KNeighborsRegressor(通过 scikit-learn),然后想将其预测与目标变量进行比较,我可以这样做:

#Initiate model
knn = neighbors.KNeighborsRegressor(n_neighbors=8)

#Define independent and target variables
X = df[['var1', 'var2', 'var3']]
Y = df['target']

#fit the model and store the predictions
knn.fit(X, Y)
predicted = knn.predict(X).ravel()

如果我比较它们,我会发现这个模型远非完美,这是预期的:

compare = pd.DataFrame(predicted,Y).reset_index()
compare.columns=['Y', 'predicted']
compare.head(3)

Returns:

+------+-----------+
| Y    | predicted |
+------+-----------+
| 985  | 2596      |
+------+-----------+
| 801  | 2464      |
+------+-----------+
| 1349 | 1907      |
+------+-----------+

如果我做完全相同的事情,只是我根据距离对邻居进行加权,则 predict() 函数将完全返回目标变量。

#Initiate model
knn_dist = neighbors.KNeighborsRegressor(n_neighbors=8, weights='distance')

#fit the model and store the predictions
knn_dist.fit(X, Y)
predicted2 = knn_dist.predict(X).ravel()

compare = pd.DataFrame(predicted2,Y).reset_index()
compare.columns=['Y', 'predicted2']
compare.head(3)

Returns 相同的列:

+------+------------+
| Y    | predicted2 |
+------+------------+
| 985  | 985        |
+------+------------+
| 801  | 801        |
+------+------------+
| 1349 | 1349       |
+------+------------+

我知道预测器并不像这暗示的那样完美,并且可以通过交叉验证证明这一点:

score_knn = cross_val_score(knn, X, Y, cv=ShuffleSplit(test_size=0.1))
print(score_knn.mean())
>>>>0.5306705590672681

我做错了什么?


根据请求,这是我的数据框中相关列的前五行:

| ID | var1     | var2     | var3     | target |
|----|----------|----------|----------|--------|
| 1  | 0.363625 | 0.805833 | 0.160446 | 985    |
| 2  | 0.353739 | 0.696087 | 0.248539 | 801    |
| 3  | 0.189405 | 0.437273 | 0.248309 | 1349   |
| 4  | 0.212122 | 0.590435 | 0.160296 | 1562   |
| 5  | 0.22927  | 0.436957 | 0.1869   | 1600   |

首先,您在整个数据集上训练模型,然后使用相同的数据集进行预测。

knn_dist.fit(X, Y)

predicted2 = knn_dist.predict(X).ravel()

这里的完美表现是教科书般的过拟合案例。 对于 X 中的每个点,该点的权重基本上为 1


接下来,当您使用 cross validation 时,您会发现该模型并不是那么完美。 您应该始终使用交叉验证,尤其是在您尝试预测(回归)目标变量的情况下。

此外,对于回归问题 不要 使用 cross_val_score 而不指定 scoring 参数。

您也可以使用 cross_val_predict。参见 here

如果您添加一些信息(例如 X 的尺寸),我可以提供更多帮助。