Necesito calcular la muestra de la distancia de Mahalanobis en R entre cada par de observaciones en una matriz de covariables . Necesito una solución que sea eficiente, es decir, solo se calculan distancias, y preferiblemente se implementa en C / RCpp / Fortran, etc. Asumo que , la matriz de covarianza de la población, es desconocida y uso la muestra matriz de covarianza en su lugar.
Estoy particularmente interesado en esta pregunta, ya que parece no haber un método de "consenso" para calcular las distancias de Mahalanobis por pares en R, es decir, no se implementa en la dist
función ni en la cluster::daisy
función. La mahalanobis
función no calcula distancias por pares sin trabajo adicional del programador.
Esto ya fue preguntado aquí Pairwise Mahalanobis distancia en R , pero las soluciones allí parecen incorrectas.
Aquí hay un método correcto pero terriblemente ineficiente (ya que se calculan distancias):
set.seed(0)
x0 <- MASS::mvrnorm(33,1:10,diag(c(seq(1,1/2,l=10)),10))
dM = as.dist(apply(x0, 1, function(i) mahalanobis(x0, i, cov = cov(x0))))
Es bastante fácil codificarme en C, pero creo que algo tan básico debería tener una solución preexistente. ¿Hay uno?
Hay otras soluciones que se quedan cortas: HDMD::pairwise.mahalanobis()
calcula distancias, cuando solo se requieren distancias únicas. Parece prometedor, pero no quiero que mi función provenga de un paquete que depende , lo que limita severamente la capacidad de otros para ejecutar mi código. A menos que esta implementación sea perfecta, prefiero escribir la mía. ¿Alguien tiene experiencia con esta función?compositions::MahalanobisDist()
rgl
fuente
Respuestas:
A partir de la solución "succint" de ahfoss, he usado la descomposición de Cholesky en lugar de la SVD.
Debería ser más rápido, porque la resolución hacia adelante de un sistema triangular es más rápido que la multiplicación de matriz densa con la covarianza inversa ( ver aquí ). Estos son los puntos de referencia con las soluciones de ahfoss y whuber en varios entornos:
Entonces Cholesky parece ser uniformemente más rápido.
fuente
La fórmula estándar para la distancia al cuadrado de Mahalanobis entre dos puntos de datos es
donde es un vector correspondiente a la observación . Típicamente, la matriz de covarianza se estima a partir de los datos observados. Sin contar la inversión matricial, esta operación requiere multiplicaciones y adiciones, cada una repetida veces. p × 1 i p 2 + p p 2 + 2 p n ( n - 1 ) / 2xi p×1 i p2+p p2+2p n(n−1)/2
Considere la siguiente derivación:
donde . Tenga en cuenta que . Esto se basa en el hecho de que es simétrico, lo que se debe al hecho de que para cualquier matriz diagonalizable simétrica ,xTiΣ-1qyo= Σ- 12Xyo Σ-1XTyoΣ- 12= ( Σ- 12Xyo)T= qTyo A=PEPTΣ- 12 A = PmiPAGT
Si dejamos que , y tengamos en cuenta que es simétrica, vemos que también debe ser simétrica. Si es la matriz de observaciones y es la matriz manera que la fila de es , entonces puede expresarse sucintamente como . Este y los resultados anteriores implican que Σ - 1 Σ - 1A = Σ- 1 Σ- 1 Xn×pQn×pithQqiQXΣ-1Σ- 12 X n × p Q n × p yot h Q qyo Q XΣ- 12
n ( n - 1 ) / 2 p 2 p p 2 + p p 2 + 2 p O
fuente
pair.diff()
hace y también dar un ejemplo numérico con impresiones de cada paso de su función? Gracias.Probemos lo obvio. Desde
se sigue podemos calcular el vector
en tiempo y la matrizO ( p2)
en el tiempo , lo más probable es que use operaciones de matriz rápidas (paralelizables) incorporadas y luego forme la soluciónO ( p n2+ p2n )
donde es el producto externo con respecto a :+ ( a ⊕ b ) i j = a i + b j .⊕ + ( a ⊕ b )yo j= ayo+ bj.
UnaΣ = Var ( X) h
R
implementación es paralela sucintamente a la formulación matemática (y supone, con ella, que realidad es invertible con la inversa escrita aquí):hTenga en cuenta, para la compatibilidad con las otras soluciones, que solo se devuelven los elementos únicos fuera de la diagonal, en lugar de toda la matriz de distancia al cuadrado (simétrica, cero en la diagonal). Los diagramas de dispersión muestran que sus resultados concuerdan con los de
fastPwMahal
.En C o C ++, RAM se puede volver a utilizarse y calculan sobre la marcha, obviando cualquier necesidad de almacenamiento intermedio de .u ⊕ Uu ⊕ u u ⊕ u
Los estudios tiempos con van de a y van de a indican que esta implementación es a veces más rápida que dentro de ese rango. La mejora mejora a medida que y aumento. En consecuencia, podemos esperar ser superiores para . El punto de equilibrio ocurre alrededor de para33 5000 p 10 100 1,5 5 p n p p = 7 n ≥ 100norte 33 5000 pag 10 100 1,5 5 5 pag norte pag p = 7 n ≥ 100 . Si las mismas ventajas computacionales de esta solución directa pertenecen a otras implementaciones puede ser una cuestión de qué tan bien aprovechan las operaciones de matriz vectorizadas.
fastPwMahal
fastPwMahal
fuente
apply
youter
... a excepción de estallarRcpp
.R
que parece que no hay nada que ganar con eso.Si desea calcular la muestra de la distancia de Mahalanobis, existen algunos trucos algebraicos que puede explotar. Todos conducen a calcular distancias euclidianas por pares, así que supongamos que podemos usarX n × p pag O ( n p )
dist()
para eso. Supongamos que denota la matriz de datos , que suponemos que está centrada para que sus columnas tengan una media de 0 y tengan un rango para que la matriz de covarianza de la muestra no sea singular. (El centrado requiere operaciones .) Entonces la matriz de covarianza de la muestra esn × p p O ( n p ) S = X T X / n .La muestra de de Mahalanobis en pares es igual a las distancias Euclidianas en parejas de para cualquier matriz satisfaga , por ejemplo, la raíz cuadrada o el factor Cholesky. Esto se desprende de algunos álgebra lineal y conduce a un algoritmo que requiere el cálculo de , , y una descomposición de Cholesky. La peor complejidad del caso es .X L L L L T = S - 1 S S - 1 O ( n p 2 + p 3 )X
Más profundamente, estas distancias se refieren a las distancias entre los componentes principales de la muestra de . Deje que denota la SVD de . Entonces yEntonces y la muestra de las distancias de Mahalanobis son solo las distancias euclidianas en de escaladas por un factor de , porque la distancia euclidiana es invariante a la rotación . Esto lleva a un algoritmo que requiere el cálculo de la SVD de que tiene la peor complejidad cuando .X X= UD VT X
Aquí hay una implementación R del segundo método que no puedo probar en el iPad que estoy usando para escribir esta respuesta.
fuente
Esta es una solución mucho más sucinta. Todavía se basa en la derivación que involucra la matriz de covarianza de raíz cuadrada inversa (vea mi otra respuesta a esta pregunta), pero solo usa la base R y el paquete de estadísticas. Parece ser un poco más rápido (aproximadamente un 10% más rápido en algunos puntos de referencia que he ejecutado). Tenga en cuenta que devuelve la distancia de Mahalanobis, en oposición a la distancia al cuadrado de Maha.
Esta función requiere una matriz de covarianza inversa, y no devuelve un objeto de distancia, pero sospecho que esta versión reducida de la función será más útil en general para los usuarios de Exchange.
fuente
SQRT
con la descomposición de Choleskychol(invCovMat)
.Tuve un problema similar resuelto escribiendo una subrutina Fortran95. Mientras lo hace, no quería calcular los duplicados entre las distancias. Fortran95 compilado es casi tan conveniente con cálculos de matriz básicos como R o Matlab, pero mucho más rápido con bucles. Las rutinas para las descomposiciones de Cholesky y las sustituciones de triángulos se pueden usar desde LAPACK.norte2
Si solo usa las funciones de Fortran77 en la interfaz, su subrutina sigue siendo lo suficientemente portátil para otros.
fuente
Hay una manera muy fácil de hacerlo usando el paquete R "biotools". En este caso, obtendrá una Matriz de Mahalanobis de Distancia Cuadrada.
fuente
Este es el código expandido que mi vieja respuesta movió aquí desde otro hilo .
He estado haciendo durante mucho tiempo el cálculo de una matriz simétrica cuadrada de distancias de Mahalanobis por pares en SPSS a través de un enfoque de matriz de sombrero utilizando la resolución de un sistema de ecuaciones lineales (porque es más rápido que invertir la matriz de covarianza).
No soy usuario de R, así que intenté reproducir esta receta de @ahfoss aquí en SPSS junto con "mi" receta, en un dato de 1000 casos por 400 variables, y encontré mi camino considerablemente más rápido.
Una forma más rápida para calcular la matriz completa de los pares distancias de Mahalanobis es a través del sombrero matriz . Quiero decir, si está utilizando un lenguaje de alto nivel (como R) con funciones de inversión y multiplicación matricial bastante rápidas incorporadas, no necesitará ningún bucle, y será más rápido que hacer bucles de mayúsculas y minúsculas.H
Definición . La matriz de doble centrado de las distancias al cuadrado de Mahalanobis en pares es igual a , donde la matriz del sombrero es , calculada a partir de la columna centrada los datos .H (n-1) X ( X′X )- 1X′ X
Entonces, centre las columnas de la matriz de datos, calcule la matriz del sombrero, multiplique por (n-1) y realice la operación opuesta al doble centrado. Obtienes la matriz de distancias cuadradas de Mahalanobis.
"Doble centrado" es la conversión geométricamente correcta de distancias cuadradas (como Euclidiana y Mahalanobis) en productos escalares definidos a partir del centroide geométrico de la nube de datos. Esta operación se basa implícitamente en el teorema del coseno . Imagine que tiene una matriz de distancias euclidianas cuadradas entre sus puntos de datos multivariados. Encuentra el centroide (media multivariada) de la nube y reemplaza cada distancia por pares por el producto escalar correspondiente (producto de puntos), se basa en las distancias s al centroide y el ángulo entre esos vectores, como se muestra en el enlace. Los s se encuentran en la diagonal de esa matriz de productos escalares yh h2 h1h2cos son las entradas fuera de diagonal. Luego, usando directamente la fórmula del teorema del coseno, puede convertir fácilmente la matriz de "doble centrado" en la matriz de distancia al cuadrado.
En nuestra configuración, la matriz de "doble centrado" es específicamente la matriz del sombrero (multiplicada por n-1), no los productos escalares euclidianos, y la matriz de distancia al cuadrado resultante es, por lo tanto, la matriz de distancia al cuadrado de Mahalanobis, no la matriz de distancia al cuadrado euclidiana.
En notación matricial: Sea la diagonal de , un vector de columna. Propagar la columna en la matriz cuadrada: ; entonces .H H (n-1) re2m a h a l= H+ H′- 2 H ( n - 1 )
H= {H,H,...}
El código en SPSS y la sonda de velocidad está debajo.
Este primer código corresponde a la función @ahfoss
fastPwMahal
de la respuesta citada . Es equivalente a esto matemáticamente. Pero estoy calculando la matriz simétrica completa de distancias (a través de operaciones matriciales) mientras que @ahfoss calculó un triángulo de la matriz simétrica (elemento por elemento).La siguiente es mi modificación para hacerlo más rápido:
Finalmente, el "enfoque de matriz de sombrero". Para la velocidad, estoy calculando la matriz del sombrero (los datos deben estar centrados primero) través de inversa generalizada obtenido en solucionador de sistemas lineales . ( X ′ X ) - 1 X ′X ( X′X )- 1X′ ( X′X )- 1X′
solve(X'X,X')
fuente
La fórmula que ha publicado no es calcular lo que cree que está calculando (una estadística U).
En el código que publiqué, lo uso
cov(x1)
como matriz de escala (esta es la varianza de las diferencias por pares de los datos). Está utilizandocov(x0)
(esta es la matriz de covarianza de sus datos originales). Creo que esto es un error de tu parte. El punto de usar las diferencias por pares es que lo libera de la suposición de que la distribución multivariada de sus datos es simétrica alrededor de un centro de simetría (o tener que estimar ese centro de simetría para ese asunto, ya quecrossprod(x1)
es proporcional acov(x1)
). Obviamente, al usarlocov(x0)
, pierdes eso.Esto se explica bien en el documento al que me vinculé en mi respuesta original.
fuente
Matteo Fasiolo
y (supongo)whuber
en este hilo. El tuyo es diferente. Me interesaría entender lo que está calculando, pero es claramente diferente de la distancia de Mahalanobis como se define típicamente.cov(x0)
se usa típicamente en este contexto, y parece ser consistente con Croux et al. El uso de al. El documento no menciona las estadísticas U , al menos no explícitamente. Hacen mencionar -, -, -, y -estimators, tal vez usted se refiere a uno de estos? G S τ L Q D