我知道该HDMD
包有一个名为的函数pairwise.mahalanobis
,它应该计算成对的马氏距离。但是,我也想在这个距离上引入权重,这个函数是不可行的。因此,我开发了自己的代码。为了测试它是否运行良好,我首先保持简单,即没有权重,并将其结果与pairwise.mahalanobis
函数的结果进行比较。但是结果不匹配......以下是我使用的功能:
dist.maha <- function (X) {
diff = pair.diff(X) # pairwise difference of rows
V <- cov(X) ## empirical covariance; positive definite
L <- t(chol(V)) ## lower triangular factor
stdX <- t(forwardsolve(L, t(diff))) # solving the system of linear equations
return(stdX)
}
这是它对玩具数据的两种选择的实现:
data = as.matrix(c(100, 54, 56, 79, 12))
dist_manuel = dist.maha(data)
# This is to convert dist_manuel from a vector to a distance matrix
ind_1 = vector(length = choose(nrow(data),2))
ind_2 = vector(length = choose(nrow(data),2))
k =1
for (j in 1:(nrow(data)-1)){
for(i in (j+1):nrow(data)){
ind_1[k] = i
ind_2[k] = j
k = k + 1
}
}
dist_manuel = cbind(ind_1,ind_2,dist_manuel)
dist_mat = matrix(data = NA, nrow = nrow(data), ncol = nrow(data))
for (j in 1:(nrow(data)-1)){
for(i in (j+1):nrow(data)){
dist_mat[i,j] = dist_manuel[which(dist_manuel[,1] == i & dist_manuel[,2] == j),3]
}
}
# This is the HDMD alternative
id = c(1,2,3,4,5)
data = cbind(id,data)
HDMD = pairwise.mahalanobis(as.data.frame(data[,2]), grouping = data[,1])
dist_HDMD = HDMD$distance
# The outputs
dist_HDMD
# [,1] [,2] [,3] [,4] [,5]
#[1,] 0 1 4 9 16
#[2,] 1 0 1 4 9
#[3,] 4 1 0 1 4
#[4,] 9 4 1 0 1
#[5,] 16 9 4 1 0
dist_mat
# [,1] [,2] [,3] [,4] [,5]
#[1,] NA NA NA NA NA
#[2,] 1.4002541 NA NA NA NA
#[3,] 1.3393735 -0.06088061 NA NA NA
#[4,] 0.6392465 -0.76100768 -0.7001271 NA NA
#[5,] 2.6787470 1.27849290 1.3393735 2.039501 NA
s 函数的结果pairwise.mahalanobi
对我来说似乎完全荒谬。data[2]
对于初学者来说,它为&data[3]
和data[2]
&分配了 1 的距离,data[1]
当人们查看它们的值时这是没有意义的。另一方面,我的函数给出了一致的结果。例如,让我们比较data[1]
&data[2]
和data[1]
&之间的距离比data[3]
。
(100 - 54) / (100 - 56) = 46/44 = 1.045455
现在,这个比率也应该适用于我的函数产生的距离。
dist_mat[2,1]/dist_mat[3,1]
#[1] 1.045455
确实如此!这是否意味着我的功能在pairwise.mahalanobis
错误时运行良好?(或者我是否以某种方式错误地使用它?)我对R不是很有经验,所以我不敢自己得出这个结论。如果比我更有经验的人能证实我的逻辑,那就太好了。