K-NN:用K=1不等于0训练MSE
K-NN: training MSE with K=1 not equal to 0
理论上,k = 1 的训练 MSE 应该为零。但是,以下脚本显示的情况并非如此。我首先生成一些玩具数据:x 代表睡眠时间,y 代表快乐。然后我训练数据并预测结果。最后,我通过两种方法计算训练数据的 MSE。谁能告诉我哪里出了问题?
from sklearn.neighbors import KNeighborsRegressor
model = KNeighborsRegressor(n_neighbors=1)
import numpy as np
x = np.array([7,8,6,7,5.7,6.8,8.6,6.5,7.8,5.7,9.8,7.7,8.8,6.2,7.1,5.7]).reshape(16,1)
y = np.array([5,7,4,5,6,9,7,6.8,8,7.6,9.3,8.2,7,6.2,3.8,6]).reshape(16,1)
model = model.fit(x,y)
for hours_slept in range(1,11):
happiness = model.predict([[hours_slept]])
print("if you sleep %.0f hours, you will be %.1f happy!" %(hours_slept, happiness))
# calculate MSE
# fast method
def model_mse(model,x,y):
predictions = model.predict(x)
return np.mean(np.power(y-predictions,2))
print(model_mse(model,x,y))
输出:
if you sleep 1 hours, you will be 6.0 happy!
if you sleep 2 hours, you will be 6.0 happy!
if you sleep 3 hours, you will be 6.0 happy!
if you sleep 4 hours, you will be 6.0 happy!
if you sleep 5 hours, you will be 6.0 happy!
if you sleep 6 hours, you will be 4.0 happy!
if you sleep 7 hours, you will be 5.0 happy!
if you sleep 8 hours, you will be 7.0 happy!
if you sleep 9 hours, you will be 7.0 happy!
if you sleep 10 hours, you will be 9.3 happy!
0.15999999999999992 #strictly larger than 0!
在您的数据中,x
在 y
、6
和 7.6
中有多个 5.7
的标签。训练后,算法为变量5.7
分配标签6
,在评估时,当它第二次遇到5.7
时,它returns6
但是不是 7.6
。因此,这对的平方误差是 (7.6 - 6)**2 = 2.56
,考虑到其他误差是 0
,均方误差是 1/16 * 2.56 = 0.16
- 正是你的结果。
In theory, the training MSE for k = 1 should be zero
这里隐含的假设是没有重复个样本x
,或者更准确地说,相同的特征x
具有相同的值y
。这里是这样吗?让我们看看
pred = model.predict(x)
np.where(pred!=y)[0]
# array([9])
所以,只有一个值 y
和 pred
确实不同:
y[9]
# array([7.6])
pred[9]
# array([6.])
哪里
x[9]
# array([5.7])
有多少样本 x
的值为 5.7
,相应的 y
是多少?
ind = np.where(x==5.7)[0]
ind
# array([ 4, 9, 15])
y[ind]
# result:
array([[6. ],
[7.6],
[6. ]])
pred[ind]
# result
array([[6.],
[6.],
[6.]])
因此,这里实际发生的情况是,对于 x=5.7
,算法不出所料地无法明确地确定哪个确切样本是单个最近邻 - 具有 y=6
的样本或具有 [=24] 的样本=];在这里它选择了与真实 y
不一致的那个,导致非零 MSE。
我想深入研究 knn 源代码可以准确证明内部处理此类情况的方式,但我将其作为练习。
理论上,k = 1 的训练 MSE 应该为零。但是,以下脚本显示的情况并非如此。我首先生成一些玩具数据:x 代表睡眠时间,y 代表快乐。然后我训练数据并预测结果。最后,我通过两种方法计算训练数据的 MSE。谁能告诉我哪里出了问题?
from sklearn.neighbors import KNeighborsRegressor
model = KNeighborsRegressor(n_neighbors=1)
import numpy as np
x = np.array([7,8,6,7,5.7,6.8,8.6,6.5,7.8,5.7,9.8,7.7,8.8,6.2,7.1,5.7]).reshape(16,1)
y = np.array([5,7,4,5,6,9,7,6.8,8,7.6,9.3,8.2,7,6.2,3.8,6]).reshape(16,1)
model = model.fit(x,y)
for hours_slept in range(1,11):
happiness = model.predict([[hours_slept]])
print("if you sleep %.0f hours, you will be %.1f happy!" %(hours_slept, happiness))
# calculate MSE
# fast method
def model_mse(model,x,y):
predictions = model.predict(x)
return np.mean(np.power(y-predictions,2))
print(model_mse(model,x,y))
输出:
if you sleep 1 hours, you will be 6.0 happy!
if you sleep 2 hours, you will be 6.0 happy!
if you sleep 3 hours, you will be 6.0 happy!
if you sleep 4 hours, you will be 6.0 happy!
if you sleep 5 hours, you will be 6.0 happy!
if you sleep 6 hours, you will be 4.0 happy!
if you sleep 7 hours, you will be 5.0 happy!
if you sleep 8 hours, you will be 7.0 happy!
if you sleep 9 hours, you will be 7.0 happy!
if you sleep 10 hours, you will be 9.3 happy!
0.15999999999999992 #strictly larger than 0!
在您的数据中,x
在 y
、6
和 7.6
中有多个 5.7
的标签。训练后,算法为变量5.7
分配标签6
,在评估时,当它第二次遇到5.7
时,它returns6
但是不是 7.6
。因此,这对的平方误差是 (7.6 - 6)**2 = 2.56
,考虑到其他误差是 0
,均方误差是 1/16 * 2.56 = 0.16
- 正是你的结果。
In theory, the training MSE for k = 1 should be zero
这里隐含的假设是没有重复个样本x
,或者更准确地说,相同的特征x
具有相同的值y
。这里是这样吗?让我们看看
pred = model.predict(x)
np.where(pred!=y)[0]
# array([9])
所以,只有一个值 y
和 pred
确实不同:
y[9]
# array([7.6])
pred[9]
# array([6.])
哪里
x[9]
# array([5.7])
有多少样本 x
的值为 5.7
,相应的 y
是多少?
ind = np.where(x==5.7)[0]
ind
# array([ 4, 9, 15])
y[ind]
# result:
array([[6. ],
[7.6],
[6. ]])
pred[ind]
# result
array([[6.],
[6.],
[6.]])
因此,这里实际发生的情况是,对于 x=5.7
,算法不出所料地无法明确地确定哪个确切样本是单个最近邻 - 具有 y=6
的样本或具有 [=24] 的样本=];在这里它选择了与真实 y
不一致的那个,导致非零 MSE。
我想深入研究 knn 源代码可以准确证明内部处理此类情况的方式,但我将其作为练习。