¿Cuál es la forma correcta de calcular la estimación de densidad del núcleo a partir de coordenadas geográficas?

11

Tengo que calcular la estimación de densidad de kernel 2d (kde) a partir de una lista de coordenadas de latitud y longitud. Pero un grado en latitud no es la misma distancia que un grado en longitud, esto significa que los núcleos individuales serían ovales, especialmente cuanto más lejos esté el punto del ecuador.

En mi caso, los puntos están lo suficientemente cerca uno del otro que transformarlos en tierra plana no debería causar muchos problemas. Sin embargo, todavía tengo curiosidad sobre cómo se debe manejar esto en caso de que esto no sea cierto.

Aaron de Windt
fuente
Como primera suposición, asumiría que simplemente sustituiría una métrica de distancia esférica apropiada en un enfoque de núcleo estándar.
Sycorax dice Reinstate Monica
¿Quién puede decir que tener núcleos ovales es incorrecto?
gung - Restablecer Monica
1
@gung Solo imagina lo que sucedería si colocas un punto lo suficientemente cerca de un poste. Sería exprimido a lo largo del eje longitudinal. ¿Y cómo manejarías un núcleo que realmente cubre uno de los polos?
Aaron de Windt
Tendría un bulto sobre el poste que es igualmente alto en todas las longitudes. ¿Por qué es eso incorrecto?
gung - Restablecer Monica
@gung Porque si, por ejemplo, elijo un diámetro de grano de 1 grado, no estaría sobre todas las longitudes. Sería más de 1 grado longitudinal, que puede ser de unos pocos metros si el punto está lo suficientemente cerca del poste, en comparación con los ~ 110 km que es 1 grado latitudinal.
Aaron de Windt

Respuestas:

7

Puede considerar usar un núcleo especialmente adecuado para la esfera, como una densidad de von Mises-Fisher

f(x;κ,μ)exp(κμx)

donde y son ubicaciones en la esfera de la unidad expresadas en coordenadas cartesianas 3D.μx

El análogo del ancho de banda es el parámetro . La contribución a una ubicación desde un punto de entrada en la ubicación en la esfera, que tiene un peso , por lo tanto esκxμω(μ)

ω(μ)f(x;κ,μ).

Para cada , sume estas contribuciones en todos los puntos de entrada .xμi

Para ilustrar, aquí hay un Rcódigo para calcular la densidad de von Mises-Fisher, generar algunas ubicaciones aleatorias y pesos (12 de ellas en el código), y mostrar un mapa de la densidad del núcleo resultante para un determinado valor de (igual a en el código).μiω(μi)κ6

[Figura]

Los puntos se muestran como puntos negros dimensionados para tener áreas proporcionales a sus pesos . La contribución del punto grande cercano es evidente en todas las latitudes del norte. El parche amarillo-blanco brillante a su alrededor sería aproximadamente circular cuando se muestra en una proyección adecuada, como una Ortográfica (tierra desde el espacio).μiω(μi)(100,60)

#
# von Mises-Fisher density.
# mu is the location and x the point of evaluation, *each in lon-lat* coordinates.
# Optionally, x is a two-column array.
#
dvonMises <- function(x, mu, kappa, inDegrees=TRUE) {
  lambda <- ifelse(inDegrees, pi/180, 1)
  SphereToCartesian <- function(x) {
    x <- matrix(x, ncol=2)
    t(apply(x, 1, function(y) c(cos(y[2])*c(cos(y[1]), sin(y[1])), sin(y[2]))))
  }
  x <- SphereToCartesian(x * lambda)
  mu <- matrix(SphereToCartesian(mu * lambda), ncol=1)

  c.kappa <- kappa / (2*pi*(exp(kappa) - exp(-kappa)))
  c.kappa * exp(kappa * x %*% mu)
}
#
# Define a grid on which to compute the kernel density estimate.
#
x.coord <- seq(-180, 180, by=2)
y.coord <- seq(-90, 90, by=1)
x <- as.matrix(expand.grid(lon=x.coord, lat=y.coord))
#
# Give the locations.
#
n <- 12
set.seed(17)
mu <- cbind(runif(n, -180, 180), asin(runif(n, -1, 1))*180/pi)
#
# Weight them.
#
weights <- rexp(n)
#
# Compute the kernel density.
#
kappa <- 6
z <- numeric(nrow(x))
for (i in 1:nrow(mu)) {
  z <- z + weights[i] * dvonMises(x, mu[i, ], kappa)
}
z <- matrix(z, nrow=length(x.coord))
#
# Plot the result.
#
image(x.coord, y.coord, z, xlab="Longitude", ylab="Latitude")
points(mu[, 1], mu[, 2], pch=16, cex=sqrt(weights))
whuber
fuente