我正在研究虹膜数据,有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)
}
如何将此代码与上述代码合并?
答案 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)))
}
如果观察结果是行而不是列,只需在函数调用之前转置矩阵即可。