我试图在虹膜数据集上从头开始在R中实现KNN分类器,作为其中的一部分,我编写了一个函数来计算欧几里德距离。这是我的代码。
known_data <- iris[1:15,c("Sepal.Length", "Petal.Length", "Class")]
unknown_data <- iris[16,c("Sepal.Length", "Petal.Length")]
# euclidean distance
euclidean_dist <- function(k,unk) {
distance <- 0
for(i in 1:nrow(k))
distance[i] <- sqrt((k[,1][i] - unk[,1][i])^2 + (k[,2][i] - unk[,2][i])^2)
return(distance)
}
euclidean_dist(known_data, unknown_data)
然而,当我调用该函数时,它正确地返回第一个值并作为NA返回。 任何人都可以显示我可能出错的代码吗? 提前谢谢。
答案 0 :(得分:3)
目的是计算known_data的第i行和单个unknown_data点之间的距离。
如何修复代码
当你计算distance[i]
时,你试图访问未退出的未知数据点的第i行,因此NA
。我相信如果您进行以下编辑,您的代码应运行正常:
known_data <- iris[1:15,c("Sepal.Length", "Petal.Length", "Class")]
unknown_data <- iris[16,c("Sepal.Length", "Petal.Length")]
# euclidean distance
euclidean_dist <- function(k,unk) {
# Make distance a vector [although not technically required]
distance <- rep(0, nrow(k))
for(i in 1:nrow(k))
# Change unk[,1][i] to unk[1,1] and similarly for unk[,2][i]
distance[i] <- sqrt((k[,1][i] - unk[1,1])^2 + (k[,2][i] - unk[1,2])^2)
return(distance)
}
euclidean_dist(known_data, unknown_data)
最后一点 - 在我正在使用的R版本中,已知数据集使用Species
而不是Class
列
另一种方法
正如@RomanLuštrik所建议的那样,通过简单的单线程可以实现获得欧氏距离的整个目标:
sqrt((known_data[, 1] - unknown_data[, 1])^2 + (known_data[, 2] - unknown_data[, 2])^2)
这与你编写的函数非常相似,但它是以矢量化形式,而不是通过循环,这通常是在R中做事的一种更好的方式。
答案 1 :(得分:0)
最好和最快的方法是使用h2o包:
#load library
library(h2o)
#initialize the node
h2o.init()
#transform the df to h2o type
known_data<-as.h2o(known_data)
unknown_data<-as.h2o(unknown_data)
#create a matrix in which the distances are going to be record
matrix1<-h2o.createFrame(rows=nrow(known_data),cols=unknown_data)
#do a loop to calculate the distance between all the rows of both df
for(i in 1:nrow(unknown_data)){
matrix[,i]<-as.data.frame(h2o.distance(known_data, unknown_data[i,],"l2"))
}