Я знаю, что в пакете 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
Результаты функции pairwise.mahalanobi
s кажутся мне совершенно абсурдными. Для начинающих он назначает расстояние 1 для data[2]
& data[3]
и data[2]
& 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, поэтому я не мог позволить себе прийти к такому выводу. Было бы здорово, если бы кто-то более опытный, чем я, мог подтвердить мою логику.