加权k近邻和R kknn包

use*_*868 0 r machine-learning nearest-neighbor

我想了解 R kknn 包如何计算二元分类问题的权重、距离和类概率。在下面的 R 代码中,训练样本中有 3 个观察值,保留样本中有 1 个观察值。两个预测变量是身高和体重。使用欧几里德距离,训练样本中每个观测值的距离为:

sqrt((6-8)^2 + (4-5)^2) = 2.24

sqrt((6-3)^2 + (4-7)^2) = 4.24

sqrt((6-7)^2 + (4-3)^2) = 1.41。

当 k=3 且权重相等时,我得到的保留概率为:

(1/3 * 1) + (1/3 * 0) + (1/3 * 1) = 0.67。

当 k=2 且权重相等时,我得到的保留概率为:

(1/2 * 1) + (1/2 * 1) = 1.00。

我想了解 R kknn 包如何使用“三角形”、“高斯”和“逆”权重(以及更一般的)进行相同的计算。

library(kknn)

training <- data.frame(class = c(1, 0, 1), height = c(8, 3, 7), weight = c(5, 7, 3))

holdouts <- data.frame(class = 1, height = 6, weight = 4)

triangular_kernel <- kknn(class ~., training, holdouts, distance = 2, kernel = "triangular", k = 3)

triangular_kernel[["fitted.values"]]

triangular_kernel[["W"]]

triangular_kernel[["D"]]

gaussian_kernel <- kknn(class ~., training, holdouts, distance = 2, kernel = "gaussian", k = 3)

gaussian_kernel[["fitted.values"]]

gaussian_kernel[["W"]]

gaussian_kernel[["D"]]

inverse_kernel <- kknn(class ~., training, holdouts, distance = 2, kernel = "inv", k = 3)

inverse_kernel[["fitted.values"]]

inverse_kernel[["W"]]

inverse_kernel[["D"]]
Run Code Online (Sandbox Code Playgroud)

Don*_*nen 5

调用会kknn::kknn在控制台中打印 kknn 函数的源代码。有了它,人们可以逐行浏览该函数以了解它的作用。

距离

kknn调用已编译的 C 代码dmEuclid。为了获取其源代码,我们遵循本指南,在 R 中编写以下代码:

untar(download.packages(pkgs = "kknn", destdir = ".", type = "source")[,2])
Run Code Online (Sandbox Code Playgroud)

然后打开工作目录 ( ) 中 kknn_1.3.1.tar 的 src 目录,使用任何文本编辑器getwd()查找并打开dm.C。滚动大约一半即可找到dmEuclid。要测试 的确切输出dmEuclid,您可以安装构建工具,并通过在下拉菜单中选择它来在 Rstudio 中打开 C++ 文件,然后使用不同的输入运行代码。 欧几里得

在函数输出之后,在您的情况下,结果dmtmp$dm

3.779645e-01  1.133893e+00 1.000000e+150 3.685210e-156
Run Code Online (Sandbox Code Playgroud)

根据您的规范k,选择前 3 个值作为距离D。这是由包作者手动转换的maxdist = 1e-06,因为最大距离小于您的情况。

重量

kknn函数使用以下部分根据您定义的内核分配权重方案。

 W <- D/maxdist
 W <- pmin(W, 1 - (1e-06))
 W <- pmax(W, 1e-06)
Run Code Online (Sandbox Code Playgroud)

此时您的 W 值大于 1,因此 W 被强制为大约 1。

if (kernel == "inv" 
        W <- 1/W
if (kernel == "triangular") 
        W <- 1 - W
if (kernel == "gaussian") {
        alpha = 1/(2 * (k + 1))
        qua = abs(qnorm(alpha))
        W = W * qua
        W = dnorm(W, sd = 1)
    }
Run Code Online (Sandbox Code Playgroud)

对此的解释可以在 gowerc 链接的论文中找到。然后将 W 转换为W <- matrix(W, p, k)1 行 (p=1)、3 列 (k=3) 的矩阵

拟合值

p = 1在你的情况下是 1, k=3, cl = c(1,0,1).

C <- matrix(dmtmp$cl, nrow = p, ncol = k + 1)
C <- C[, 1:k] + 1
CL <- matrix(cl[C], nrow = p, ncol = k)
W <- matrix(W, p, k)
fit <- rowSums(W * CL)/pmax(rowSums(W), 1e-06)
Run Code Online (Sandbox Code Playgroud)