Как использовать расстояние Махаланобиса, чтобы найти K ближайших соседей в R

#r #mahalanobis

Вопрос:

У меня есть набор данных временных рядов с 1970 по 2020 год в качестве моего обучающего набора данных, и у меня есть еще одно единственное наблюдение за 2021 год, что мне нужно сделать прямо сейчас, так это использовать расстояние Махаланобиса для определения 10 ближайших соседей 2021 года в обучающем наборе данных. Я попробовал несколько функций, таких как get.knn() и get.knnx() , но мне не удалось установить расстояние как расстояние Махаланобиса. Есть ли какая-либо функция, которую я могу использовать? Заранее благодарю вас!

——————редактировать———————

Итак, я попробовал функцию mahalanobis() , а затем получил список значений, являются ли эти значения расстоянием Махаланобиса? Могу ли я отсортировать их, чтобы получить 10 лучших?

Комментарии:

1. Пожалуйста, предоставьте воспроизводимые данные и покажите свой код.

2. Попробуйте biotools пакет. Он также имеет некоторые функции махаланобиса

Ответ №1:

Предыстория

Расстояние Махаланобиса измеряет, насколько далеко точка находится от среднего значения, измеренного в стандартных отклонениях, см. Википедию. Он использует повернутые координаты по собственным значениям и связан с анализом основных компонентов. Перекрестная проверка содержит несколько отличных объяснений, например, это «объяснение снизу вверх» или функция ( cholMaha см. Ниже), как оценить матрицу расстояний.

Отношение расстояния Махаланобиса к PCA

Давайте рассмотрим небольшой пример данных:

 A <- data.frame(
  x = c(-2.48, -4.03, 1.15, 0.94, 5.33, 4.72),
  y = c(-3.92, -3.4, 0.92, 0.78, 3.44, 0.5),
  z = c(-1.11, -2.18, 0.21, 0.34, 1.74, 1.12)
)
 

Затем мы можем оценить матрицу расстояний Махаланобиса с помощью D2.dist из пакета biotools или вышеупомянутой функции:

 ## Mahalanobis distance from package biotools
library("biotools")
# sqrt, because D2.dist returns squared version
sqrt(D2.dist(A, cov(A)))


## https://stats.stackexchange.com/questions/65705/pairwise-mahalanobis-distances

cholMaha <- function(X) {
  dec <- chol( cov(X) )
  tmp <- forwardsolve(t(dec), t(X) )
  dist(t(tmp))
}

cholMaha(A)
 

Теперь наступает момент. Мы также можем оценить расстояние Махаланобиса как евклидово расстояние повторно масштабированных загрузок (повернутых данных) анализа основных компонентов:

 ## derive Mahalanobis distance from principal components
pc <- prcomp(A)     # principal components
AA <- scale(pc$x)   # "upscale" all components to the same level

# Euclidean distance of rescaled PC transformed variables is identical to
# Mahalanobis distance
dist(AA)

 

Результат идентичен двум описанным выше подходам.

Применение к алгоритму классификации

Теперь это соотношение можно использовать в любом алгоритме классификации. Просто преобразуйте матрицу данных с помощью поворота PCA и установите их евклидовы расстояния.

 ## Now apply this in any classification method, e.g. hclust
par(mfrow=c(1, 2))

# Euclidean distance of original variables
plot(hclust(dist(scale(A))), main="Euclidean")

# Euclidean distance of scaled principal components
# is equivalent to Mahalanobis distance; considers covariance
plot(hclust(dist(AA)), main="Mahalanobis")
 

По сути, небольшие влияющие факторы, скрытые в переменных, масштабируются, но, к сожалению, также и случайные ошибки. Чтобы разобраться в этом подробнее, прочтите ответ «Моя бабушка готовит» на сайте Cross Validated.