Python Kneighbors分类器的欧氏值与linalg.norm和scipy.spatial.distance.euclidean不同

Python Kneighbors分类器的欧氏值与linalg.norm和scipy.spatial.distance.euclidean不同,python,machine-learning,scikit-learn,scipy,knn,Python,Machine Learning,Scikit Learn,Scipy,Knn,我正在尝试在上实现knearest邻居分类器。 我试图通过与Scipy进行比较来检查我的结果 为了验证,我使用训练集中的前6个样本,并查找训练集中第一个样本的6个最近邻。 我计算的距离与KNeighborsClassifier库给出的距离不匹配。 我不明白为什么我的价值观不同 我已经提到了获得欧几里得距离的方法 我的代码: from mlxtend.data import loadlocal_mnist import numpy as np from scipy.spatial import d

我正在尝试在上实现knearest邻居分类器。
我试图通过与Scipy进行比较来检查我的结果

为了验证,我使用训练集中的前6个样本,并查找训练集中第一个样本的6个最近邻。
我计算的距离与KNeighborsClassifier库给出的距离不匹配。
我不明白为什么我的价值观不同

我已经提到了获得欧几里得距离的方法

我的代码:

from mlxtend.data import loadlocal_mnist
import numpy as np
from scipy.spatial import distance

train, train_label = loadlocal_mnist(
        images_path='train-images.idx3-ubyte', 
        labels_path='train-labels.idx1-ubyte')
train_label = train_label.reshape(-1, 1)

train = train[:6, :]
train_label = train_label[:6, :]
# print(train_label)

test = train.copy()
test_label = train_label.copy()

test = test[:1, :]
test_label = test_label[:1, :]

for test_idx, test_row in enumerate(test):
    for train_idx, train_row in enumerate(train):
        d1 = np.linalg.norm(train_row - test_row)
        d2 = distance.euclidean(train_row, test_row)
        d3 = (((train_row - test_row)**2).sum())**0.5
        d4 = np.dot(train_row - test_row, train_row - test_row)**0.5
        print(train_idx, d1, d2, d3, d4)
测试集仅为列车组的第一排

以上各项的输出为:

0 0.0 0.0 0.0 0.0
1 2618.6771469579826 2618.6771469579826 140.3923074815711 15.937377450509228
2 2372.0210791643485 2372.0210791643485 134.29817571359635 10.770329614269007
3 2139.966354875702 2139.966354875702 122.37646832622684 11.313708498984761
4 2485.1432554281455 2485.1432554281455 135.5322839769182 13.892443989449804
5 2582.292392429641 2582.292392429641 144.69968901141425 14.212670403551895
这是我比较的Kneighbors分类器代码:

neigh = KNeighborsClassifier(n_neighbors=6)
neigh.fit(train, train_label)
closest = neigh.kneighbors(test[0].reshape(1, -1))
print(closest)
输出:

(array([[   0.        , 2387.11164381, 2554.81975881, 2582.29239243,
        2672.46721215, 2773.14911247]]), array([[0, 1, 3, 5, 4, 2]], dtype=int64))
我试图计算数据点之间的欧几里德距离,以找到最近的邻居
d1、d2、d3、d4是我从上面链接的问题中发现的4种不同方法,输出是它们的具体值。
但是我从Kneighbors分类器得到的距离值不同于所有这些分类器,它们也使用文档中给出的欧几里德距离。为什么会发生这种情况?

好的,这里有一个提示(目前没有时间进一步查看,可能会有所帮助):

第一种计算距离的方法(可能是切片初始数据的方法)肯定有很大的错误;要了解这一点,让我们将循环修改为:

for test_idx, test_row in enumerate(test):
    for train_idx, train_row in enumerate(train):
        d1 = np.linalg.norm(train_row - test_row)
        d2 = np.linalg.norm(test_row - train_row)
        d3 = distance.euclidean(train_row, test_row)
        d4 = distance.euclidean(test_row, train_row)
        print(train_idx, d1, d2, d3, d4)
在这里,显然我们应该有
d1=d2=d3=d4
;但结果是:

0 0.0 0.0 0.0 0.0
1 2618.6771469579826 2213.268623552053 2618.6771469579826 2213.268623552053
2 2372.0210791643485 2547.0901044132693 2372.0210791643485 2547.0901044132693
3 2139.966354875702 2374.7201940439213 2139.966354875702 2374.7201940439213
4 2485.1432554281455 2467.6727903026367 2485.1432554281455 2467.6727903026367
5 2582.292392429641 2449.1912951013032 2582.292392429641 2449.1912951013032
i、 e.它是
d1=d3
d2=d4
,但这两个量之间不同;这当然不应该发生,因为距离是一个对称函数,参数的顺序不应该起作用:

a = np.array((1, 2, 3))
b = np.array((4, 5, 6))
distance.euclidean(a, b)
# 5.196152422706632
distance.euclidean(b, a)
# 5.196152422706632
np.linalg.norm(a-b)
# 5.196152422706632
np.linalg.norm(b-a)
# 5.196152422706632

发人深省-希望它能有所帮助…

我不确定是什么导致了这种情况,但将数据从np.array转换为列表,然后再转换回np.array显然解决了这个问题

train = np.array(train.tolist())
test = np.array(test.tolist())

感谢@desertnaut提出问题可能存在于数据切片中的想法,但我仍然无法确定问题的原因。

请让您的问题具有可复制性(对于MNIST来说应该没有那么难);什么是
列车
测试
,它们是如何建造的?@desertnaut为列车和测试添加了代码。谢谢。
d3
d4
与这个问题有什么关系?它们似乎无关紧要……@沙漠怪人补充了更多细节,解释说是的,这是有道理的,但仍然无法找到这个bug的来源