如何在数据框中找到最接近给定向量的行

时间:2019-05-12 00:43:14

标签: r machine-learning r-caret nearest-neighbor

说我有一个看起来像这样的数据框:

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作为返回,因为这些行最接近类似于向量“ 0、1、1、1”。

我尝试通过以下命令使用R中的“插入符”包:

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)

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

我想找到一个模型/命令/功能,其性能与python的sklearn中的KDtrees模型类似,但是在R中(KDtrees可以返回n个最接近的索引的列表)。另外,尽管不是必需的,但我希望模型能够与功能的分类值一起使用(例如TRUE / FALSE),这样我就不必创建虚拟变量,就像我在这里用1和0做的那样。 / p>

2 个答案:

答案 0 :(得分:1)

同意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)))

答案 1 :(得分:0)

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

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行之间,因为它们是相同的