如何在数据框中找到与给定向量最相似的行

How to find the row in a dataframe that most closely resembles a given vector

假设我有一个如下所示的数据框:

Feature 1     Feature 2     Feature 3     Feature 4     Target
    1             1             1             1            a
    0             1             0             0            a 
    0             1             1             1            b

还有一个看起来像这样的向量:

0, 1, 1, 1

如何找到与向量最接近的匹配行的索引?例如,如果我想找到最近的 2 行,我将输入向量和数据框(可能删除了目标列),然后我将从函数中获取索引 1 和 3 作为 return,因为这些行最类似于向量“0、1、1、1”。

我尝试使用 R 中的 "caret" 包,命令为:

intrain <- createDataPartition(y = data$Target, p= 0.7, list = FALSE)
training <- data[intrain,]
testing <- data[-intrain,]

trctrl <- trainControl(method = "repeatedcv", number = 10, repeats = 3)
knn_fit <- train(Target~., data = training, method = "knn", trControl = trctrl, preProcess = c("center", "scale"), tuneLength = 10)
test_pred <- predict(knn_fit, newdata = testing)
print(test_pred)

但是,这不是 return 匹配行的索引。它只是 return 对具有与测试数据集最匹配的特征的目标的预测。

我想找到一个 model/command/function 可以在 python 中找到与 sklearn 中的 KDtrees 模型类似的性能,但在 R 中(KDtrees 可以 return n 的列表最接近的索引)。此外,虽然不是必需的,但我希望所述模型使用特征的分类值(例如 TRUE/FALSE),这样我就不必像我在这里使用 1 和 0 那样创建虚拟变量.

同意 42 的评论。使用简单的距离度量,第 1 行与向量的区别与第 2 行相同。

# your data
featureframe <- data.frame(Feature1 = c(1,0,0), Feature2 = c(1,1,1), 
                           Feature3 = c(1,0,1), Feature4 = c(1,1,1), 
                           Target = c("a","a","b"))
vec <- c(0,1,1,1)

distances <- apply(featureframe[,1:4], 1, function(x) sum((x - vec)^2))
distances
# [1] 1 1 0

根据评论进行编辑:

要明确衡量相似之处,您可以改为量化相似性度量,其中总和越接近向量的长度,两个向量就越接近:

similarity <- apply(featureframe[,1:4], 1, function(x) sum(x == vec))

如果您想对某些特征赋予更高的权重,可以将函数内的相似度向量乘以等长的权重向量。

similarity <- apply(featureframe[,1:4], 1, function(x) sum((x == vec) * c(1,2,1,1)))

要找到向量之间的最小距离,可以制作一个距离矩阵:

mat <- matrix(c(1,1,1,1
                0,1,0,0,
                0,1,1,1,
                0,1,1,1), 
              ncol = 4, byrow = T)
#the following will find the euclidean distance between each row vector
dist(mat, method = "euclidean")
         1        2        3
2 1.732051                  
3 1.000000 1.414214         
4 1.000000 1.414214 0.000000

显然,最小值在第 3 行和第 4 行之间,因为它们是相同的