一个数据帧的实例与其他数据帧的所有实例的欧几里德距离

时间:2016-06-04 11:44:54

标签: r

我正在研究虹膜数据,有5列我想要做的是计算data_test的一个实例与所有其他data_train实例的欧氏距离。像data_test的第1行一样,包含data_train的所有实例,然后是data_test的第2行,包含data_train的所有实例,依此类推, 我的data_test和data_train是我原始数据的分割

library(caret)
split=0.70
trainIndex <- createDataPartition(mydata$Species, p=split, list=FALSE)
data_train <- mydata[ trainIndex,]
data_test <- mydata[-trainIndex,]

有一个与此类似的提出解决方案的问题

apply(data_test,1,function(data_test)apply(data_train,1,function(data_train,data_test)dist(rbind(data_train,data_test)),data_test))

然而问题是我有一个分类属性的类属性,我不想在此包含,我知道一种方法是制作data_test的子集并训练和排除我的类属性,有没有办法我可以在上面的行中排除这个类吗?

另一个问题是我想从每一行(具有data_train的所有行的data_test行)欧几里德距离找到k个最小距离。到目前为止我正在整理它们

df <- df[order(df , decreasing = FALSE)]
k=2
if(k>1){
  df<- head(df,k)
}

如何将此代码与上述代码合并?

3 个答案:

答案 0 :(得分:0)

我已经弄清楚了,以防其他人想要解决方案

library(caret)
split=0.70
trainIndex <- createDataPartition(mydata$Species, p=split, list=FALSE)
data_train <- mydata[ trainIndex,]
data_test <- mydata[-trainIndex,]
data_train <- data_train[,1:4]
data_test<-data_test[,1:4]

df<-apply(data_test,1,function(data_test)apply(data_train,1,function(data_train,data_test)dist(rbind(data_train,data_test)),data_test))
df

df <- apply(df,2,sort,decreasing=F)
df

k=2
if(k>1){
  df<- head(df[,1:2],k)
}

答案 1 :(得分:0)

我假设通过&#34;类属性&#34;你的意思是数据集有一个需要从计算中排除的分类变量。这可以通过索引数据并排除相关列来实现。此外,将数据转换为矩阵对象很方便。

> data_train <- as.matrix(iris[ trainIndex, 1:4])
> data_test <- as.matrix(iris[-trainIndex, 1:4])
> dim(data_train)
[1] 105   4
> dim(data_test)
[1] 45  4

现在,对于eucludian距离,你可以做到

> distance <- sapply(1:nrow(data_test), function(i)
+     sqrt(rowSums(sweep(data_train, 2, data_test[i, ])^2)))
> dim(distance)
[1] 105  45

distance是一个105乘45的矩阵,其中第i列包含 第data_test行的第i行与data_train的105行中的每一行之间的欧几里德距离。

然后,为了找到每列的最小k距离,您可以执行以下操作

> k <- 3
> apply(distance, 2, function(x) sort(x)[1:k])
          [,1]      [,2]      [,3]      [,4]      [,5]      [,6]      [,7]
[1,] 0.1000000 0.1414214 0.3000000 0.2828427 0.4582576 0.2000000 0.1414214
[2,] 0.1414214 0.2449490 0.3464102 0.3000000 0.5099020 0.2236068 0.1414214
[3,] 0.1414214 0.2645751 0.3605551 0.3316625 0.5656854 0.2449490 0.1732051
          [,8]     [,9]     [,10]     [,11]     [,12]     [,13]     [,14]
[1,] 0.3000000 0.244949 0.1414214 0.2236068 0.2645751 0.1414214 0.2236068
[2,] 0.3316625 0.300000 0.1732051 0.3000000 0.3162278 0.2000000 0.2449490
[3,] 0.3464102 0.300000 0.2449490 0.3162278 0.3741657 0.2000000 0.2449490
         [,15]     [,16]     [,17]     [,18]     [,19]     [,20]     [,21]
[1,] 0.1414214 0.2645751 0.3872983 0.3605551 0.4898979 0.1414214 0.1414214
[2,] 0.1732051 0.3316625 0.5099020 0.4582576 0.5196152 0.2449490 0.3162278
[3,] 0.2236068 0.4582576 0.5196152 0.6708204 0.5477226 0.4242641 0.3162278
         [,22]     [,23]     [,24]     [,25]     [,26]     [,27]     [,28]
[1,] 0.3605551 0.3316625 0.3000000 0.1414214 0.1414214 0.2000000 0.2645751
[2,] 0.4242641 0.3741657 0.3872983 0.1732051 0.2645751 0.4123106 0.5744563
[3,] 0.4690416 0.4000000 0.4358899 0.3000000 0.2828427 0.4795832 0.6082763
         [,29]     [,30]     [,31]     [,32]     [,33]     [,34]     [,35]
[1,] 0.1732051 0.2645751 0.4358899 0.2236068 0.4123106 0.5477226 0.2236068
[2,] 0.1732051 0.3162278 0.5291503 0.3741657 0.8185353 0.8944272 0.3000000
[3,] 0.2236068 0.4242641 0.5477226 0.4242641 0.8602325 1.2489996 0.3000000
         [,36]     [,37]     [,38]     [,39]     [,40]     [,41]     [,42]
[1,] 0.3162278 0.2645751 0.1732051 0.2828427 0.4582576 0.3316625 0.3162278
[2,] 0.3162278 0.7000000 0.3872983 0.3605551 0.4690416 0.3605551 0.4358899
[3,] 0.3316625 0.9695360 0.4242641 0.4242641 0.5099020 0.3741657 0.4358899
         [,43]     [,44]     [,45]
[1,] 0.2449490 0.2449490 0.2449490
[2,] 0.3464102 0.3605551 0.3000000
[3,] 0.3464102 0.4690416 0.6164414

答案 2 :(得分:0)

我认为使用像这样的函数会更高效,更紧凑:

euclidian = function(
  mat1,       # Matrix with observations in COLUMNS.
  mat2=mat1   # Matrix with observations in COLUMNS.
) {
  apply(mat1, 2, function(yi) sqrt(colSums((mat2 - yi)^2)))
}

如果观察结果是行而不是列,只需在函数调用之前转置矩阵即可。