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

Posted

技术标签:

【中文标题】我自己的 KNN 函数给出的结果与 scikit-learn 不同【英文标题】:My own KNN function doesn't give same result as scikit-learn 【发布时间】:2021-12-20 21:05:03 【问题描述】:

我正在尝试从头开始创建一个 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】:

从训练集中删除观察后,您正尝试使用 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

【讨论】:

以上是关于我自己的 KNN 函数给出的结果与 scikit-learn 不同的主要内容,如果未能解决你的问题,请参考以下文章

Scikit-learn 脚本给出的结果与教程大不相同,当我更改数据框时会出错

scikit-learn学习基础知识二

scikit-learn中的机器学习算法封装——kNN

[机器学习与scikit-learn-18]:算法-K近邻算法KNN的原理与代码实例

scikit-learn估计器-KNN均值聚类

在 Scikit 的谱聚类中使用预先计算的亲和矩阵时的 KNN?