我自己的 KNN 函数不会给出与 scikit-learn 相同的结果

My own KNN function doesn't give same result as scikit-learn

我正在尝试从头开始创建 KNN 函数,然后将其与 scikit-learn KNeighborsClassifier 进行比较。我正在使用 iris 数据集进行测试。

根据我学到的知识,我必须单独获取每个数据点,然后计算它与其余训练数据之间的距离。

最后一步是将它与最接近它的数据的目标值相关联。出于某种原因,当我这样做时,错误率为 4%。为什么会这样?

from sklearn import *
import numpy as np

iris = datasets.load_iris()
X = iris.data
Y = iris.target

def PPV(data, target):
    target_res = []
    true = 0
    for i in range(len(target)):
        data_copy = data
        target_copy = target
        training_data = np.delete(data_copy, i, 0)
        training_target = np.delete(target_copy, i, 0)
        target_res.append(training_target[np.argmin(metrics.pairwise.euclidean_distances([data[i]], training_data))])   
        # print(f"{i} has target prediction {training_target[np.argmin(metrics.pairwise.euclidean_distances([data[i]], training_data))]}")     
    for i in range(len(target)):
        if target[i] == target_res[i]:
            true = true + 1
    print(f"The predicted PPV target values are: {target_res}")
    print(f"PPV precision: {true*100/len(target)}%")
PPV(X, Y)

以上代码的输出是:

The predicted PPV target values are: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
PPV precision: 96.0%
KNeighbors precision: 100.0% = 1

除非我遗漏了什么,否则我应该能够得到与 K=1 的 KNeighborsClassifier 算法相同的结果,因为它们具有相同的原理。

您尝试在从训练集中删除观测值后使用 1-最近邻分类器对其进行分类。因为观测值不再在训练集中,所以不能保证每个观测值都会被正确分类。得分准确率可能低于 100%。

如果您正在做这样的事情:

from sklearn.neighbors import KNeighborsClassifier
from sklearn import datasets
from sklearn import metrics

iris = datasets.load_iris()
X = iris.data
y = iris.target

knn = KNeighborsClassifier(n_neighbors=1)
knn.fit(X, y)
knn_results = knn.predict(X)  # we are predicting our own training data here
metrics.accuracy_score(y, knn_results)  # 1.0

您将获得 100% 的准确度,因为您使用 1-NN 对训练集中的相同观察结果进行分类。 1-NN分类器每次都会找到完美匹配的点。

如果您更改 n_neighbors 参数或使用新的测试数据,则此示例中的准确度可能不再是 100%。

此外,您在代码中使用的评分指标似乎是准确度,而不是精确度。 https://en.wikipedia.org/wiki/Confusion_matrix