首页 > 解决方案 > 如何在 knn 算法中使用加权标签?

问题描述

我正在自己实现加权 knn 算法。

为了简化逻辑,让我们将其表示为 predict 方法,它接受三个参数:

索引 - 对象 i 的训练样本中最近 j 个邻居的矩阵(i=1...n,总共 n 个对象)。[i, j] - 训练样本中对象的索引。例如,对于 4 个对象和 3 个邻居:

indices = np.asarray([[0, 3, 1],
                      [0, 3, 1],
                      [1, 2, 0],
                      [5, 4, 3]])

距离 - 从训练样本到对象 i 的 j 个最近邻的距离矩阵。(i=1...n,总共 n 个对象)。例如,对于 4 个对象和 3 个邻居:

distances = np.asarray([[   4.12310563,    7.07106781,    7.54983444],
                       [   4.89897949,    6.70820393,    8.24621125],
                       [   0.,            1.73205081,    3.46410162],
                       [1094.09368886, 1102.55022561, 1109.62245832]])

标签 - 具有训练样本的每个对象 j 的类的真实标签的向量。例如:

labels = np.asarray([0, 0, 0, 1, 1, 2])

因此,函数签名是:

 def predict(indices, distances, labels):
      ....
      # return [np.bincount(x).argmax() for x in labels[indices]]
      return predict

在评论中,您可以看到返回“非加权”knn 方法的预测的代码,该方法不使用距离。您能否展示一下,如何使用距离矩阵计算预测?我找到了算法,但现在我完全被难住了,因为我不知道如何用 numpy 实现它。

谢谢!

标签: pythonnumpyknn

解决方案


这应该有效:

# compute inverses of distances
# suppress division by 0 warning, 
# replace np.inf with a very large number
with np.errstate(divide='ignore'):
    dinv = np.nan_to_num(1 / distances)
    
# an array with distinct class labels
distinct_labels = np.array(list(set(labels)))
# an array with labels of neighbors
neigh_labels = labels[indices]
# compute the weighted score for each potential label
weighted_scores = ((neigh_labels[:, :, np.newaxis] == distinct_labels) * dinv[:, :, np.newaxis]).sum(axis=1)
# choose the label with the highest score
predictions = distinct_labels[weighted_scores.argmax(axis=1)]

推荐阅读