Test statistici per modelli di linee spaziali?


32

Esistono numerosi test per i modelli di punti spaziali che possono essere utilizzati per determinare se i punti sono distribuiti casualmente o no, ma esistono test stabiliti per i modelli di linee spaziali? (Sto pensando a linee rette, con solo il punto iniziale e finale e senza nodi intermedi.)

I dati che voglio analizzare sono linee di OD (origine-destinazione) del movimento umano e animale. (Simile all'esempio in Cluster di linee non indirizzate .)

Finora, un'idea era quella di trattare le linee come punti 4D e usare i test dei punti, ma non sono sicuro che sia appropriato.

Il test ideale consentirebbe di determinare se ci sono gruppi di linee o meno.

Istintivamente, direi che molte linee che iniziano alla stessa origine ma hanno tutti i tipi di destinazioni diverse, non dovrebbero essere considerate un cluster. D'altra parte, molte linee che corrono (vicine) parallele per un periodo più lungo sarebbero un cluster. inserisci qui la descrizione dell'immagine


Quale dovrebbe essere il tuo comportamento se una linea è parallela a un'altra linea ma 1) molto più corta della prima o 2) "lontana" nella direzione della prima linea
radouxju

@radouxju in quei casi, direi che non appartengono allo stesso cluster
underdark

Risposte:


17

Questa è una domanda difficile in quanto non sono state sviluppate molte, se nessuna, statistiche sui processi spaziali sviluppate per le funzionalità di linea. Senza scavare seriamente in equazioni e codice, le statistiche dei processi puntuali non sono prontamente applicabili alle caratteristiche lineari e quindi statisticamente non valide. Questo perché il null, su cui viene testato un determinato modello, si basa su eventi puntuali e non su dipendenze lineari nel campo casuale. Devo dire che non so nemmeno quale sarebbe il nulla per quanto riguarda intensità e disposizione / orientamento sarebbe ancora più difficile.

Qui sto solo sputando, ma mi chiedo se una valutazione su più scale della densità della linea unita alla distanza euclidea (o alla distanza di Hausdorff se le linee sono complesse) non indicherebbe una misura continua di raggruppamento. Questi dati potrebbero quindi essere riassunti ai vettori di linea, usando la varianza per tenere conto della disparità nelle lunghezze (Thomas 2011) e assegnando un valore di cluster usando una statistica come K-medie. So che non stai cercando cluster assegnati, ma il valore del cluster potrebbe suddividere i gradi di clustering. Ciò richiederebbe ovviamente un adattamento ottimale di k, pertanto non vengono assegnati cluster arbitrari. Sto pensando che questo sarebbe un approccio interessante nella valutazione della struttura dei bordi in modelli teorici grafici.

Ecco un esempio funzionante in R, scusate, ma è più veloce e più riproducibile rispetto a fornire un esempio QGIS, ed è più nella mia zona di comfort :)

Aggiungi librerie e usa l'oggetto psp di rame di spatstat come esempio di linea

library(spatstat)
library(raster)
library(spatialEco)

data(copper)
l <- copper$Lines
l <- rotate.psp(l, pi/2)

Calcola la densità di linea standardizzata del 1 ° e 2 ° ordine, quindi passa a oggetti di classe raster

d1st <- density(l)
  d1st <- d1st / max(d1st)
  d1st <- raster(d1st)  
d2nd <- density(l, sigma = 2)
  d2nd <- d2nd / max(d2nd)
  d2nd <- raster(d2nd)  

Standardizzare la densità del 1 ° e 2 ° ordine in una densità integrata nella scala

d <- d1st + d2nd
d <- d / cellStats(d, stat='max')  

Calcola la distanza euclidea standardizzata invertita e passa alla classe raster

euclidean <- distmap(l)
euclidean <- euclidean / max(euclidean)
euclidean <- raster.invert(raster(euclidean))

Costruisci spatstat psp su un oggetto SpatialLinesDataFrame da usare in raster :: extract

as.SpatialLines.psp <- local({
     ends2line <- function(x) Line(matrix(x, ncol=2, byrow=TRUE))
     munch <- function(z) { Lines(ends2line(as.numeric(z[1:4])), ID=z[5]) }
     convert <- function(x) {
        ends <- as.data.frame(x)[,1:4]
        ends[,5] <- row.names(ends)
        y <- apply(ends, 1, munch)
        SpatialLines(y)
     }
     convert
})
l <- as.SpatialLines.psp(l)
l <- SpatialLinesDataFrame(l, data.frame(ID=1:length(l)) )

Traccia i risultati

par(mfrow=c(2,2))
  plot(d1st, main="1st order line density")
    plot(l, add=TRUE)
  plot(d2nd, main="2nd order line density")
    plot(l, add=TRUE) 
  plot(d, main="integrated line density")
    plot(l, add=TRUE)   
  plot(euclidean, main="euclidean distance")
    plot(l, add=TRUE) 

Estrai i valori raster e calcola le statistiche di riepilogo associate a ciascuna riga

l.dist <- extract(euclidean, l)
l.den <- extract(d, l)
l.stats <- data.frame(min.dist = unlist(lapply(l.dist, min)),
                      med.dist = unlist(lapply(l.dist, median)),
                      max.dist = unlist(lapply(l.dist, max)),
                      var.dist = unlist(lapply(l.dist, var)),
                      min.den = unlist(lapply(l.den, min)),
                      med.den = unlist(lapply(l.den, median)),
                      max.den = unlist(lapply(l.den, max)),
                      var.den = unlist(lapply(l.den, var)))

Utilizzare i valori di silhouette del cluster per valutare il k ottimale (numero di cluster), con la funzione optimum.k, quindi assegnare i valori del cluster alle linee. Possiamo quindi assegnare i colori a ciascun cluster e tracciare sopra il raster di densità.

clust <- optimal.k(scale(l.stats), nk = 10, plot = TRUE)                      
  l@data <- data.frame(l@data, cluster = clust$clustering) 

kcol <- ifelse(clust$clustering == 1, "red", "blue")
plot(d)
  plot(l, col=kcol, add=TRUE)

A questo punto si potrebbe eseguire una randomizzazione delle linee per verificare se l'intensità e la distanza risultanti sono significative da casuali. È possibile utilizzare la funzione "rshift.psp" per riorientare casualmente le linee. Puoi anche semplicemente randomizzare i punti di inizio e di fine e ricreare ogni riga.

Ci si chiede anche "what if" se hai appena eseguito un'analisi del modello di punto usando una statistica di analisi univariata o incrociata sui punti di inizio e fine, invariante delle linee. In un'analisi univariata confronteresti i risultati dei punti di inizio e di fine per vedere se c'è coerenza nel raggruppamento tra i due schemi di punti. Questo potrebbe essere fatto tramite un cappello a F, un cappello a G o un cappello a K di Ripley (per processi a punti non contrassegnati). Un altro approccio sarebbe un'analisi incrociata (es., Cross-K) in cui i processi a due punti vengono testati simultaneamente contrassegnandoli come [start, stop]. Ciò indicherebbe le relazioni di distanza nel processo di raggruppamento tra i punti iniziale e finale. Tuttavia, la dipendenza spaziale (nonstaionarity) da un processo di intensità sottostante può essere un problema in questi tipi di modelli rendendoli disomogenei e richiedendo un modello diverso. Ironia della sorte, il processo disomogeneo viene modellato usando una funzione di intensità che ci riporta al cerchio completo alla densità, supportando così l'idea di utilizzare una densità integrata nella scala come misura del clustering.

Ecco un rapido esempio di se la statistica Ripleys K (Besags L) per la correlazione automatica di un processo punto non marcato usando le posizioni di inizio, fine di una classe di feature di linea. L'ultimo modello è un cross-k che utilizza entrambe le posizioni di inizio e fine come processo contrassegnato nominale.

library(spatstat)
  data(copper)
  l <- copper$Lines
  l <- rotate.psp(l, pi/2)

Lr <- function (...) {
 K <- Kest(...)
  nama <- colnames(K)
   K <- K[, !(nama %in% c("rip", "ls"))]
   L <- eval.fv(sqrt(K/pi)-bw)
  L <- rebadge.fv(L, substitute(L(r), NULL), "L")
 return(L)
}

### Ripley's K ( Besag L(r) ) for start locations
start <- endpoints.psp(l, which="first")
marks(start) <- factor("start")
W <- start$window
area <- area.owin(W)
lambda <- start$n / area
 ripley <- min(diff(W$xrange), diff(W$yrange))/4
   rlarge <- sqrt(1000/(pi * lambda))
     rmax <- min(rlarge, ripley)
( Lenv <- plot( envelope(start, fun="Lr", r=seq(0, rmax, by=1), nsim=199, nrank=5) ) )

### Ripley's K ( Besag L(r) ) for end locations
stop <- endpoints.psp(l, which="second")
  marks(stop) <- factor("stop")
W <- stop$window
area <- area.owin(W)
lambda <- stop$n / area
 ripley <- min(diff(W$xrange), diff(W$yrange))/4
   rlarge <- sqrt(1000/(pi * lambda))
     rmax <- min(rlarge, ripley)
( Lenv <- plot( envelope(start, fun="Lr", r=seq(0, rmax, by=1), nsim=199, nrank=5) ) )

### Ripley's Cross-K ( Besag L(r) ) for start/stop
sdata.ppp <- superimpose(start, stop)
( Lenv <- plot(envelope(sdata.ppp, fun="Kcross", r=bw, i="start", j="stop", nsim=199,nrank=5, 
                 transform=expression(sqrt(./pi)-bw), global=TRUE) ) )

Riferimenti

Thomas JCR (2011) Un nuovo algoritmo di clustering basato su K-medie usando un segmento di linea come prototipo. In: San Martin C., Kim SW. (a cura di) Progressi in Pattern Recognition, Image Analysis, Computer Vision e Applications. CIARP 2011. Appunti di lezione in Informatica, vol 7042. Springer, Berlino, Heidelberg


14

Potresti voler esaminare la distanza di Fréchet . Ne sono venuto a conoscenza solo di recente dopo una recente domanda alla ricerca di un'implementazione di Python.

Questa è una metrica per trovare la somiglianza spaziale dei linestring . È un'idea simile alla distanza di Hausdorff, l'equivalente per le misure di somiglianza dei poligoni, ma per le linee con una direzione.

La distanza di Fréchet è definita come la lunghezza minima di un guinzaglio che collega un cane su una traiettoria con il suo proprietario su una seconda traiettoria, entrambi senza mai spostarsi indietro

Questa metrica avrà un valore piccolo per due curve che sono vicine, quasi parallele, allineate allo stesso modo e con una lunghezza simile.

Tuttavia, ciò non risponde alla parte di identificazione del cluster.

C'è una presentazione completa qui . La tua situazione suona come alcuni dei casi d'uso menzionati nelle sezioni 46-49

Questa metrica ha molti usi non geospaziali come

  • rilevazione di sottoprocessi comuni nel sequenziamento genico
  • riconoscimento della grafia
  • rilevare periodi correlati in serie temporali come le storie dei prezzi delle azioni

così mentre molti articoli nella bibliografia trattano questo argomento, la maggior parte di essi non è geospaziale. Inoltre, la maggior parte di questi articoli rientra negli algoritmi / matematica / informatica piuttosto che geospaziale / geoscienze e sono indirizzati di conseguenza.

Tuttavia, questo documento sembrava promettente:

Buchin, K., Buchin, M. e Wang, Y. (2009). Algoritmi esatti per la corrispondenza parziale della curva tramite la distanza di Fréchet. In Atti del 20 ° Simposio ACM-SIAM sugli algoritmi discreti, pagine 645–654

Alcuni degli altri articoli sembrano più vicini a ciò che stai cercando: identificazione dei cluster e allocazione delle traiettorie ai cluster, ma sono illustrati utilizzando i dati delle serie temporali o altri esempi non geospaziali. Tuttavia potrebbero indicare in direzioni interessanti.


2
Penserei che il clustering a collegamento minimo (o DBSCAN) usando la distanza di Frechet o Hausdorff, anziché la distanza euclidea, sarebbe una buona soluzione.
dbaston,

Adoro che la distanza di Frechet esista e mi piace anche che la presentazione paragona "jellybeans" e "bellybuttons".
Fezter

5

Sto suggerendo di usare un approccio simile a quello spiegato qui .

ALGORITMO e denominazione:

a) Strato della linea di nomi NODES. Calcola i cuscinetti

b) unirsi spazialmente a se stesso (da uno a molti) usando la tolleranza della distanza. Nome livello LINK

c) rimuovere dai collegamenti LINKS a se stesso, ovvero NAME = NAME_1

d) all'interno dei LINK trovi "stesse" coppie di direzioni. Ero solito:

def theSame(aList,tol):
    maxB=max(aList);minB=min(aList)
    if abs(maxB-minB)<tol:return 1
    if abs(maxB-minB-180)<tol:return 1
    return 0
#-----------
theSame( [!BEARING!, !BEARING_1!],15)

cioè supponendo che le linee che vanno nella direzione opposta siano simili in termini di direzione

d) rimuovere coppie non simili (0) dai LINK.

e) calcolare i gruppi di LINK collegati tramite NODES e trasferire i numeri dei gruppi nella tabella NODES:

inserisci qui la descrizione dell'immagine

Sfortunatamente:

inserisci qui la descrizione dell'immagine

Tuttavia statistiche semplici sui cuscinetti all'interno del gruppo, ad esempio deviazione standard di:

abs(tan(bearing))

mostrato nessuna deviazione nel primo caso e molto grande nel secondo. Allo stesso modo, le statistiche sulle lunghezze potrebbero aiutare a "correre in parallelo per molto tempo".

Se sopra è di interesse posso aggiornare la risposta con lo script che calcola i gruppi di collegamenti collegati. Sta usando il modulo arcpy e networkx.

Non so come trattare una coppia di linee che vanno dallo stesso punto in direzioni opposte ...


Sarei interessato a vedere la sceneggiatura.
alphabetasoup,

1
@RichardLaw segui il link alla prima riga della mia soluzione e scorri verso il basso per vederlo. Ho una versione leggermente migliore, ma questo lo farà. La logica è estremamente semplice: 1. crea un grafico usando collegamenti e nodi ad esso collegati 2. Prendi il 1 ° nodo e trova gli antenati (gruppo 0) 3) rimuovi i nodi dal grafico e ripeti fino a quando non rimangono più nodi. Lo uso ripetutamente per trovare gruppi di tubi disconnessi (flussi e quant'altro) ecc. Per set di dati Council / LINZ di alta qualità
FelixIP

5

Ai miei occhi c'è un problema con la definizione delle linee, che determinerà quali approcci usare (alcuni di quelli sopra menzionati). Se si tratta di coppie OD e la geometria non gioca un ruolo, mi avvicinerei a questo in base al clustering di rete. Dici che le reti non formano una rete - così sia, ma è probabile che le origini e le destinazioni cadano in regioni significative, e quindi puoi trattarla come una rete.

Se la geometria ha qualcosa da dire (queste sono, diciamo traiettorie GPS e vuoi considerare la geometria), allora dovrai davvero lavorare in uno spazio (x, y, t) - geometria simile dell'impronta del movimento ma a diversi i tempi potrebbero non essere valutati come gli stessi - questo non è specificato nella domanda.

Alcune possibilità che puoi guardare:

  1. Più vicino alle tue necessità è Dodge, Weibel, Forootan (2009), qui http://orca.cf.ac.uk/94865/1/PhysicsMovement.pdf
  2. Se la geometria può essere semplificata, forse i parametri qui menzionati potrebbero essere utili: http://www.tandfonline.com/doi/full/10.1080/17445647.2017.1313788

Ma alla fine, rileggere ancora una volta la tua domanda iniziale, potrebbe essere più semplice: puoi calcolare a coppie (tra i segmenti) la distanza tra l'intersezione dell'estensione lineare dei segmenti e i loro punti più vicini, normalizzare in qualche modo (forse in base alla lunghezza del segmento stesso) e utilizzare un algoritmo di clustering di matrici? Ragionamento: i segmenti che si intersecano lontano sono più simili (paralleli) di quelli che si intersecano nelle vicinanze. Nei disegni, non si dice come trattare segmenti co-lineari o paralleli che si trovano in un offset (lunga distanza del tasto). Presumo che ciò darebbe problemi alla soluzione sopra. (modificato per chiarezza, dichiarando esplicitamente "estensione lineare" sopra)

Nota (gennaio 2018): di recente mi sono imbattuto in questo:

  1. Cai, Yuhan e Raymond Ng. "Indicizzazione delle traiettorie spazio-temporali con polinomi di Chebyshev." Atti della conferenza internazionale ACM SIGMOD del 2004 sulla gestione dei dati. ACM, 2004.

Ciò si riferisce alla somiglianza della traiettoria e quindi consentirebbe una certa quantificazione della somiglianza. Questo si basa sull'approssimazione polinomiale delle curve e sul calcolo della distanza di Chebyshev.


4

Puoi fornire qualche dettaglio in più sul tipo di dati con cui stai lavorando? Sono solo una serie di linee disgiunte o formano una rete? Hai usato uno degli strumenti ArcGIS per l'analisi del modello spaziale? Molti dei metodi ArcGIS (K di Ripley, indice NN, Morani I) usano solo il centroide delle linee / poligoni quando usato su dati non puntuali. Tuttavia qui potrebbe essere necessario considerare di dividere ogni linea in sezioni uguali per evitare che linee molto lunghe non vengano prese in considerazione perché il loro centroide è molto lontano.

L'altra cosa a cui pensare è, concettualmente, che cos'è un gruppo di linee? Potresti avere molte linee che si avvicinano l'una all'altra, ma i loro punti finali potrebbero essere dispersi. Allo stesso modo, potresti avere molte linee che iniziano e finiscono molto vicine l'una all'altra, ma poi diventano molto disperse tra i loro punti iniziale / finale.

Tuttavia, un approccio potrebbe essere semplicemente quello di eseguire un'analisi della densità delle linee in modo che le aree con più linee (che potrebbero essere considerate raggruppate in qualche modo) avranno valori di griglia elevati, mentre le aree con densità bassa avranno valori bassi. Quindi ottieni un po 'di output hot-spot; tuttavia questo non ti dà una sola statistica come Morans I o l'NNI. Inoltre non differenzia tra densità a causa di una linea molto irregolare (cioè una spirale stretta) rispetto a molte linee.

Mi dispiace che questa non sia una risposta completa al tuo problema, ma penso che inchiodare il concetto completo di ciò che stai cercando di ottenere possa fornire alcune soluzioni migliori.

AGGIORNARE

Sulla base dell'esempio che hai fornito, penso che il suggerimento di FelixlP di creare un attributo punto con linea da utilizzare con le misure del modello di punto sia probabilmente un buon modo di procedere. Tranne che vorrei dividere i punti in segmenti uguali e avere un punto con la linea che porta ad ogni vertice di linea. Quindi è necessario esaminare le misure che esamineranno la vicinanza di ciascun punto e la somiglianza tra i cuscinetti (in modo da rilevare le linee più vicine alla perpendicolare).

Quindi usare il GI Getis-Ord (analisi Hotspot) sarebbe un buon strumento da usare per visualizzare dove si trovano i cluster; e poi un Io di Moran globale per valutare il livello globale di clustering.

La distanza alla quale segmentate le linee, tuttavia, influirà sul grado di raggruppamento trovato. Se stai cercando cluster sulla scala di 1 km, dovrai segmentare le linee attorno a quello. Allo stesso modo se stai cercando cluster su una scala di 100m, dovrai segmentare le linee di conseguenza. Questo è così da non perdere le linee e anche da non rilevare ogni linea come un cluster.


Le linee rappresentano le origini e le destinazioni del viaggio. Non formano una rete. Finora ho usato i metodi R per i modelli di punti spaziali dei punti di origine e destinazione. Non mi piace molto l'idea di usare i centroidi di linea, ma potrebbe valere la pena provare a densificare la linea e analizzare i nodi risultanti, grazie!
underdark

L'analisi della densità della linea potrebbe essere una soluzione fallback se non trovo nulla di più adatto.
underdark

Bufferare la linea primaria a una certa distanza, quindi interrogare le linee che non sono completamente racchiuse dal buffer sarebbe una soluzione? In passato ho fatto molto per trovare la via percorsa più probabile, ma i dati consistevano in polilinee multi-nodo piuttosto che semplici segmenti di linea.
jbgramm,

@jbgramm Posso pensare a molti approcci che calcolerebbero qualcosa ma non sono uno statistico e quindi sto cercando metodi consolidati - se ne esistono
underdark

2
L'uso di un punto centrale della linea, o vertici, per rappresentare i processi di un punto non è un approccio statisticamente valido. Inoltre, stai cambiando profondamente anche la rappresentazione del processo spaziale. Pubblicherò alcuni consigli, ma onestamente, l'unico che ha fornito un approccio un po 'valido è il suggerimento di @underdark di una densità di linea. Attraverso le scale, insieme a una statistica di autocorrelazione, si indica un grado di raggruppamento nelle caratteristiche lineari.
Jeffrey Evans,

3

Grazie per gli esempi

Non ho visto alcun metodo stabilito per calcolare ciò che stai cercando, tuttavia questo sarebbe il mio approccio. È una specie di soluzione a forza bruta.

Calcola un rettangolo di delimitazione minimo, quindi espanderlo in modo arbitrario, ma uguagliando una grande quantità in ciascuno dei quattro angoli.

Trova il centro di massa del rettangolo di creazione, calcola la distribuzione azimutale e della distanza per i punti OD per ogni linea e fai lo stesso usando gli angoli del rettangolo di delimitazione, confrontando gli azimut delle linee.

Prova il parallelismo da ciascuno dei quattro angoli alla fine di ciascun raggio. Verifica il parallelismo dal centro di massa all'estremità di ciascun raggio.

In questo modo è possibile confrontare la deviazione dagli angoli alle estremità. Nell'esempio (a) avresti linee quasi parallele da due degli angoli a ciascuno dei tre gruppi di linee. Avresti anche linee quasi parallele dal centro di massa alle estremità delle estremità lontane delle linee.

Esempio (b) non avresti linee parallele vicine quando calcoli dagli angoli alle estremità di ogni linea, ma le linee non sembrano casuali, si portano l'una con l'altra con lievi deviazioni.

L'esempio (c) sembra essere casuale

L'esempio (d) non è casuale, è radiale.

Guardando questo, eseguirò i test che ho descritto sopra, oltre a creare test di soluzioni triangolari dagli angoli del rettangolo di chiusura creato alle estremità dei raggi. Angoli interni simili e aree aiuterebbero a verificare il clustering a meno che una delle linee nel cluster non sia significativamente più corta delle altre.

Quanto sopra è solo un'opinione di uno sciocco, e probabilmente mi sbaglio.


-1

Seguendo la tua descrizione istintiva, qual è il criterio per 2 linee parallele?

Fondamentalmente puoi fare un test sui loro punti iniziale o finale:
Sia Sx = (start_x_line_1 - start_x_line_2),
Sy = (start_y_line_1 - start_y_line_2)
ed Ex, Ey lo stesso ma per i loro punti finali.

Quindi se sqrt (Sx² + Sy²) E sqrt (Ex² + Ey²) è sotto una certa soglia, puoi considerare queste linee come parallele.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.