¿Cuáles son las formas de calcular conjuntos de distancias en R para Big Data?
Problema: Necesitamos un método de big data para calcular distancias entre puntos. Planteamos a continuación lo que nos gustaría hacer con un dataframe de cinco observaciones. Sin embargo, este método en particular no es factible cuando el número de filas es grande (>1 millón). En el pasado, hemos utilizado SAS para realizar este tipo de análisis, pero preferiríamos utilizar R si es posible. (Nota: No voy a mostrar el código porque, aunque describo una forma de hacer esto con conjuntos de datos más pequeños a continuación, este método es básicamente imposible de utilizar con datos en nuestra escala.)
Comenzamos con un dataframe de tiendas, cada una con una latitud y longitud (aunque este no es un archivo espacial, ni queremos utilizar un archivo espacial).
<h1>Puedes pensar en x e y en este ejemplo como coordenadas cartesianas</h1>
tiendas <- data.frame(id = 1:5,
x = c(1, 0, 1, 2, 0),
y = c(1, 2, 0, 2, 0))
tiendas
id x y
1 1 1 1
2 2 0 2
3 3 1 0
4 4 2 2
5 5 0 0
Para cada tienda, queremos saber la cantidad de tiendas dentro de una distancia x. En un dataframe pequeño, esto es sencillo. Creamos otro dataframe con todas las coordenadas, lo fusionamos de nuevo, calculamos las distancias, creamos un indicador si la distancia es menor que x y sumamos los indicadores (restando uno para la propia tienda, que se encuentra a una distancia de 0). Esto resultaría en un conjunto de datos que se vería así:
id x y s1.dist s2.dist s3.dist s4.dist s5.dist
1: 1 1 1 0.000000 1.414214 1.000000 1.414214 1.414214
2: 2 0 2 1.414214 0.000000 2.236068 2.000000 2.000000
3: 3 1 0 1.000000 2.236068 0.000000 2.236068 1.000000
4: 4 2 2 1.414214 2.000000 2.236068 0.000000 2.828427
5: 5 0 0 1.414214 2.000000 1.000000 2.828427 0.000000
Cuando consideramos (arbitrariamente) como “cercano” aquello que está por debajo de 1.45, obtenemos indicadores que se ven así:
id x y s1.close s2.close s3.close s4.close s5.close close.total
1: 1 1 1 1 1 1 1 1 4
2: 2 0 2 1 1 0 0 0 1
3: 3 1 0 1 0 1 0 1 2
4: 4 2 2 1 0 0 1 0 1
5: 5 0 0 1 0 1 0 1 2
El producto final debería verse así:
id close.total
1: 1 4
2: 2 1
3: 3 2
4: 4 1
5: 5 2
Se agradece cualquier consejo.
Muchas gracias.
davy.ai
Un método escalable para calcular distancias entre puntos en big data es utilizar el paquete
geosphere
en R. El paquete incluye una función llamadadistm
que calcula distancias entre dos conjuntos de coordenadas utilizando varios métodos, como Haversine, Vincenty y Great Circle.Para aplicar este método al ejemplo dado, primero necesitamos crear una matriz de coordenadas utilizando la función
cbind
:Luego, podemos utilizar
distm
para calcular las distancias entre todos los pares de coordenadas:La matriz resultante
dist_matrix
tendrá distancias en metros de forma predeterminada, pero la unidad se puede cambiar utilizando el argumentodistUnit
.Para encontrar el número de tiendas dentro de una distancia x para cada tienda, podemos aplicar un umbral en
dist_matrix
y contar el número de entradas por debajo del umbral (excluyendo la diagonal). Aquí está el código para hacer eso:El vector resultante
close_stores
tendrá el número de tiendas dentro del umbral dado para cada tienda. Podemos combinarlo con la columnaid
en el dataframe original para obtener la salida final:Este método debería ser escalable para conjuntos de datos grandes con millones de filas, siempre y cuando haya suficiente memoria para almacenar la matriz de distancia entre pares. Si la memoria se convierte en un problema, existen métodos alternativos como el uso de índices espaciales o dividir el conjunto de datos en fragmentos más pequeños.