具有连续和二元变量的 K 最近邻

机器算法验证 r 分类 k-最近邻
2022-01-28 09:41:20

我有一个包含列a b c(3 个属性)的数据集。a是数字和连续的,bc是分类的,每个都有两个级别。我正在使用 K-Nearest Neighbors方法ab. c因此,为了能够测量距离,我通过删除b和添加b.level1和来转换我的数据集b.level2如果观察ib类别中具有第一级,b.level1[i]=1并且b.level2[i]=0.

现在我可以在我的新数据集中测量距离:a b.level1 b.level2

从理论/数学的角度来看:您能否对二进制和连续数据执行 K 近邻 (KNN)?

FNN在 R 和函数中使用包knn()

2个回答

可以将分类变量和连续变量(特征)结合起来。

不知何故,对于诸如 k-NN 之类的方法没有太多的理论依据。启发式是,如果两个点彼此靠近(根据一定距离),那么它们在输出方面有一些共同点。也许是,也许不是。这取决于您使用的距离。

在您的示例中,您定义了两点之间的距离(a,b,c)(a,b,c)如 :

  • 取之间的平方距离aa(aa)2
  • 如果添加 +2bb是不同的,如果相等则为 +0(因为您计算每个类别的差异为 1)
  • 如果添加 +2cc不同,+0 等于(相同)

这对应于为每个特征隐式赋予权重。

请注意,如果a取较大的值(如 1000、2000...)且方差较大,则二元特征的权重与a. 只有之间的距离aa真的很重要。反过来:如果a采用像 0.001 这样的小值:只有二进制特征才会计算在内。

您可以通过重新加权来规范行为:将每个特征除以其标准偏差。这适用于连续变量和二元变量。您也可以提供自己喜欢的重量。

请注意,R 函数 kNN() 为您执行此操作:https ://www.rdocumentation.org/packages/DMwR/versions/0.4.1/topics/kNN

作为第一次尝试,只需使用基本的 norm=true (规范化)。这将避免在组合连续和分类特征时可能出现的大多数无意义的情况。

是的,您当然可以将 KNN 用于二进制数据和连续数据,但是在这样做时您应该注意一些重要的注意事项。

结果将通过相对于实值结果(对于 0-1 缩放、未加权向量)之间的离散度的二元拆分得到大量通知,如下图所示:

实值和二进制变量的分离

您可以在此示例中看到,与按比例缩放的实值变量相比,二元变量对单个观测值的最近邻居的影响更大。

此外,这扩展到多个二进制变量——如果我们将实值变量之一更改为二进制,我们可以看到,通过匹配所有涉及的二进制变量,距离将比实际值的接近程度更明智:

实值和二进制变量的分离

您只想包括关键的二元变量——实际上,您是在询问“与二元变量(如果有的话)的这种配置相匹配的所有观察值,它们具有最接近的实数值?” 这是对许多可以用 KNN 解决的问题的合理表述,而对其他问题的表述非常糟糕。

#code to reproduce plots:
library(scatterplot3d) 

scalevector <- function(x){(x-min(x))/(max(x)-min(x))}

x <- scalevector(rnorm(100))
y <- scalevector(rnorm(100))
z <- ifelse(sign(rnorm(100))==-1, 0, 1)
df <- data.frame(cbind(x,y,z))

scatterplot3d(df$x, df$z, df$y, pch=16, highlight.3d=FALSE,
              type="h", angle =235, xlab='', ylab='', zlab='')

x <- scalevector(rnorm(100))
y <- ifelse(sign(rnorm(100))==-1, 0, 1)
z <- ifelse(sign(rnorm(100))==-1, 0, 1)
df <- data.frame(cbind(x,y,z))

scatterplot3d(df$x, df$z, df$y, pch=16, highlight.3d=FALSE,
              type="h", angle =235, xlab='', ylab='', zlab='')