加权 k 最近邻和 R kknn 包
Weighted k-nearest neighbors and R kknn package
我想了解 R kknn 包如何计算二元 class 化问题的权重、距离和 class 概率。在下面的 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"]]
调用 kknn::kknn
会在控制台中打印 kknn 函数的源代码。有了它,你可以一行一行地查看函数,看看它做了什么。
距离
kknn
调用已编译的 C 代码 dmEuclid
。获取其源代码,我们按照this guide,在R中编写如下代码:
untar(download.packages(pkgs = "kknn", destdir = ".", type = "source")[,2])
然后在你的工作目录(getwd()
)中打开kknn_1.3.1.tar的src目录找到并打开dm.C 使用任何文本编辑器。滚动一半左右找到 dmEuclid。要测试 dmEuclid
的确切输出,您可以安装构建工具,并在 Rstudio 中打开一个 C++ 文件,方法是在下拉菜单中选择它,然后 运行 具有不同输入的代码。
根据函数输出,在您的情况下 dmtmp$dm
结果为
3.779645e-01 1.133893e+00 1.000000e+150 3.685210e-156
根据您的规范 k
,选择前 3 个值作为距离 D
。
这是包作者手动转换为 maxdist = 1e-06
,因为最大距离小于您的情况。
权重
kknn
函数使用以下部分根据您定义的内核分配权重方案。
W <- D/maxdist
W <- pmin(W, 1 - (1e-06))
W <- pmax(W, 1e-06)
此时您的 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)
}
可以在 gowerc 链接的论文中找到其解释。
然后将 W 转换为 1 行 (p=1)、3 列 (k=3)
的矩阵 W <- matrix(W, p, k)
拟合值
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)
我想了解 R kknn 包如何计算二元 class 化问题的权重、距离和 class 概率。在下面的 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"]]
调用 kknn::kknn
会在控制台中打印 kknn 函数的源代码。有了它,你可以一行一行地查看函数,看看它做了什么。
距离
kknn
调用已编译的 C 代码 dmEuclid
。获取其源代码,我们按照this guide,在R中编写如下代码:
untar(download.packages(pkgs = "kknn", destdir = ".", type = "source")[,2])
然后在你的工作目录(getwd()
)中打开kknn_1.3.1.tar的src目录找到并打开dm.C 使用任何文本编辑器。滚动一半左右找到 dmEuclid。要测试 dmEuclid
的确切输出,您可以安装构建工具,并在 Rstudio 中打开一个 C++ 文件,方法是在下拉菜单中选择它,然后 运行 具有不同输入的代码。
根据函数输出,在您的情况下 dmtmp$dm
结果为
3.779645e-01 1.133893e+00 1.000000e+150 3.685210e-156
根据您的规范 k
,选择前 3 个值作为距离 D
。
这是包作者手动转换为 maxdist = 1e-06
,因为最大距离小于您的情况。
权重
kknn
函数使用以下部分根据您定义的内核分配权重方案。
W <- D/maxdist
W <- pmin(W, 1 - (1e-06))
W <- pmax(W, 1e-06)
此时您的 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)
}
可以在 gowerc 链接的论文中找到其解释。 然后将 W 转换为 1 行 (p=1)、3 列 (k=3)
的矩阵W <- matrix(W, p, k)
拟合值
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)