Analisi della prossimità per trovare il bar più vicino utilizzando Python

Analisi di prossimità con Python per trovare il bar più vicino

Alcune parole sul trattamento dei dati spaziali

Immagine di anteprima (dell'autore)

Disclaimer: in questo articolo dimostreremo tutti gli approcci utilizzando la libreria open-source estaty. Questa libreria è nata dalla volontà di formalizzare gli algoritmi che utilizziamo nel nostro lavoro in un’utensile disponibile per altri sviluppatori. In altre parole, questo articolo è scritto dal responsabile della libreria.

Oggi vorremmo continuare a discutere dell’argomento del trattamento dei dati spaziali utilizzando una libreria Python open-source. Abbiamo già parlato di come combinare Open Street Map e dati aperti di Landsat per verificare le aree delle zone verdi vicino agli oggetti immobiliari.

Ora consideriamo un altro tipo di analisi: l’analisi di prossimità o la disponibilità (o accessibilità) di alcuni oggetti utili, come parchi, ospedali, asili, ecc. (Figura 1).

Figura 1. Schema che illustra l'approccio all'analisi di prossimità (immaginiamo che qui si tratti ad esempio dei saloni di parrucchieri) (immagine di autore)

Un po’ sull’analisi di prossimità

Proponiamo di iniziare il racconto con una breve panoramica della letteratura. Mi piace l’articolo “Location Analytics Use-Cases che ogni data scientist dovrebbe conoscere” (attenzione: si tratta di una storia solo per membri) che introduce abbastanza facilmente il lettore a ciò che è l’analisi delle informazioni geografiche.

Gli articoli “Creazione di una superficie di distanza dei costi per misurare l’accesso ai parchi” e “Lo stato di crescita dello Utah: un’analisi di prossimità dei residenti dello Utah alle strutture sanitarie” mostrano anche abbastanza chiaramente quali caratteristiche nelle città gli ingegneri possono calcolare per effettuare tali analisi. L’argomento è abbastanza popolare e sono stati sviluppati molti articoli scientifici e applicazioni pratiche: uniamoci anche noi.

Libreria (che utilizziamo)

Ora passiamo a una conversazione più concreta: gli strumenti che possono essere utilizzati per questa analisi di prossimità (oltre ai sistemi di informazioni geografiche come QGIS o ArcGIS e ai servizi proprietari come utenti finali del prodotto).

Noi, come sviluppatori, vorremmo analizzare non dati aggregati ma valori grezzi con l’aiuto di librerie o servizi convenienti (preferibilmente open-source, naturalmente). Non abbiamo trovato strumenti adatti a noi, quindi abbiamo sviluppato e utilizzato la nostra libreria open-source scritta in Python. Si chiama estaty e se vuoi, puoi vedere la pagina di documentazione dopo aver letto l’articolo:

Basandoci su questa libreria, componiamo casi d’uso. Basandoci su questi esempi, abbiamo sviluppato microservizi che aiutano i gestori immobiliari a eseguire l’analisi. Oltre ai servizi pronti all’uso, tuttavia, questi script sono organizzati come casi d’uso e sono disponibili a chiunque voglia utilizzare la libreria.

estaty può utilizzare diverse fonti di dati per effettuare i calcoli, ma gli esempi aperti (per mantenere la loro vera apertura) si basano sui dati di OpenStreetMap. In questo articolo vogliamo mostrare come possiamo fare una stima colaterale piuttosto rapida e comunque adattare l’approccio a nuove fonti di dati se necessario.

Analisi (che possiamo fare)

Prima di tutto, installa la libreria usando il comando

pip install estaty==0.1.0

o, se stai usando poetry:

poetry add estaty==0.1.0

Siamo ora pronti per utilizzare la versione 0.1.0

Iniziamo l’implementazione. Forniremo un’analisi di prossimità per l’indirizzo seguente: “Berlin, Neustädtische Kirchstraße 4–7” — coordinate {latitudine: 52.5171411, longitudine: 13.3857187}. Analizzeremo il quartiere di questo oggetto entro un raggio di 2 km.

Per scoprire quanto ci vorrà per arrivare al bar più vicino (secondo OSM — vale la pena menzionarlo qui), scriviamo ed eseguiamo il seguente codice:

Qui avviene quanto segue — costruiamo una pipeline di elaborazione per analizzare una proprietà. La pipeline avrà la forma di un grafo composto da trasformazioni sequenziali sui dati:

Figura 2. Pipeline di elaborazione dei dati spaziali per il calcolo delle distanze dei percorsi verso i bar utilizzando i dati di OpenStreetMap (immagine dell'autore)

Diamo un’occhiata più da vicino a cosa succede “sotto il cofano”. Iniziamo con il fatto che l’architettura di estaty è basata su 5 livelli astratti (nel caso della Pipeline sopra, vengono utilizzati solo tre tipi di nodi):

  • DataSource — carica i dati dalla fonte richiesta, porta i dati a uno standard comune (vettore e raster). Non importa quale sia la fonte, l’output da questo nodo sarà solo in due possibili varianti, il che consente di unificare ulteriormente il loro trattamento;
  • Preprocessor — pre-elaborazione dei dati vettoriali o raster, ad esempio assegnazione di un nuovo sistema di coordinate di riferimento (CRS);
  • Merger — combinazione dei dati nel modo richiesto. Possibili combinazioni: dati vettoriali con dati vettoriali, raster con raster e dati vettoriali con dati raster;
  • Analizzatore — il nucleo della libreria — utilizza trasformazioni atomiche semplici su raster e oggetti vettoriali per eseguire un’analisi, come ad esempio il confronto di aree o la ricerca di percorsi;
  • Report — modulo di analisi finale opzionale, che consente di generare un report in un formato user-friendly.

Combinando questi nodi in determinati modi è possibile comporre diverse pipeline per l’analisi dei dati senza modificare i modi di elaborazione dei dati originali — sostituendo unicamente le origini originali o i metodi di analisi (vedi Animazione 1).

Animazione 1. Flessibilità della libreria nella preparazione di una pipeline per l'analisi (animazione dell'autore)

Quindi, la Figura 2 mostra che nell’analisi vengono utilizzati solo tre nodi — si tratta di una pipeline piuttosto semplice. Come risultato del suo lavoro otterremo un GeoDataFrame di geopandas (una tabella con geometrie di oggetti) con oggetti lineari — percorsi verso gli oggetti di nostro interesse. In questo caso — verso i bar. La visualizzazione del risultato, tra l’altro, sarà la seguente:

Figura 3. Percorsi verso i bar con distanze calcolate dall'algoritmo (immagine dell'autore)

Abbiamo il diritto di fare ciò che vogliamo con l’insieme di oggetti lineari ottenuti — ad esempio, trovare la distanza al bar più vicino, o richiedere il valore medio del campione (come viene fatto nel codice):

  • Lunghezza minima: 308,93 m
  • Lunghezza media: 2306,49 m

Come vero esperto nella localizzazione dei bar nei centri delle grandi città, posso dire che i bar nell’area di analisi possono essere molto di più nella realtà. Ma abbiamo concordato all’inizio che avremmo analizzato i dati basati su OSM, quindi…

Il Pipeline stesso è indipendente dalla fonte dei dati su cui viene eseguita l’analisi. Questo è garantito dalla debole interconnessione dei moduli di libreria. Iniziamo con il nodo DataSource, che ha un meccanismo integrato di conversione dei dati in un tipo (ad esempio, i dati vettoriali qui saranno nel formato geopandas GeoDataFrame e saranno sempre solo tre tipi, indipendentemente dalla fonte utilizzata, saranno convertiti in punti, linee o poligoni). A seguire, un pre-processore che determinerà automaticamente la proiezione metrica appropriata per i nostri dati. L’unica cosa che conta per il pre-processore è che i dati devono provenire dal nodo DataSource, il resto dovrebbe essere gestito dal nodo precedente. Il nostro semplice pipeline viene completato da un blocco di analisi, che funzionerà su qualsiasi oggetto geometrico, indipendentemente che siano aree, linee o punti.

In questo modo, possiamo fare esattamente gli stessi calcoli per altre categorie di dati che estrapoleremo da OSM (ovviamente, l’elenco non è limitato solo a OSM), ad esempio, analisi di prossimità per scuole, parchi, oggetti d’acqua, bagni pubblici, bidoni per lo smaltimento dei rifiuti, stazioni di polizia e così via, qualsiasi cosa (per i tipi di oggetti che possono essere definiti dalle etichette, consultare la pagina wiki Map features o nella documentazione estaty sulle fonti di dati):

Figura 5. Analisi di prossimità per scuole, parchi, oggetti d'acqua, bidoni per lo smaltimento dei rifiuti, stazioni di polizia (immagine dell'autore)

Come può essere ampliato l’approccio

Abbiamo menzionato che i dati spaziali di qualsiasi natura possono essere analizzati: dati sociali, oggetti naturali o costruzioni artificiali. Guardiamo ancora più in profondità nel codice sorgente. Dalle figure possiamo vedere che il calcolo della distanza viene eseguito su percorsi costruiti in base alle strade, il che è ragionevole, perché di solito non voliamo ai bar con l’elicottero, ma camminiamo. Pertanto, l’analisi ‘distanza’ comprende la ricerca di percorsi sul grafo stradale, utilizzando quello di OSM. Cioè, l’algoritmo cerca un percorso sulle seguenti astrazioni (ci siamo basati sull’articolo seguente, altamente consigliato — OSMnx: Python per reti stradali):

Figura 6. Grafo delle strade percorribili a piedi, utilizzato per la ricerca di percorsi ottimali (immagine dell'autore)

Un grafo qui è un insieme di nodi e archi con attributi geograficamente riferiti (hanno attributi di latitudine e longitudine). Per trovare il percorso più breve da un oggetto A a un oggetto B, dobbiamo seguire tre passaggi:

  1. Trovare il nodo più vicino nel grafo all’oggetto A (chiamiamolo nodo 1)
  2. Trovare il nodo più vicino nel grafo all’oggetto B (chiamiamolo nodo 2)
  3. Utilizzando l’algoritmo di attraversamento del grafo, trovare il percorso ottimale da nodo 1 a nodo 2

Se vogliamo ottenere la distanza, è necessario sommare la lunghezza del percorso da nodo 1 a nodo 2 alle distanze da oggetto A a nodo 1 e da oggetto B a nodo 2. Gli ultimi due componenti possono essere calcolati in linea retta perché la rete con i nodi è abbastanza densa. Ma qui c’è una difficoltà: se oggetto A e B sono punti, è relativamente facile trovare i nodi più vicini ad essi (calcolare le distanze tra i punti). Se la geometria dell’oggetto A è, ad esempio, un’area, allora dobbiamo cercare il nodo “più vicino” al poligono. Cosa fare nel caso di un oggetto lineare era anche un problema da risolvere

Quindi rispondiamo alla domanda: “Come calcolare le distanze dai nodi del grafico agli oggetti vettoriali di diversi tipi: linee, punti e poligoni in modo unificato”? A questo scopo, la libreria converte gli oggetti in tipo punto (è molto facile trovare la distanza tra i punti) prima di iniziare il calcolo dei percorsi. Chiamiamo tali trasformazioni rappresentazioni (Figura 7).

Figura 7. Alcuni modi per rappresentare oggetti vettoriali (immagine dell'autore)

Cioè, invece di scrivere e mantenere tre algoritmi, ne scriviamo uno solo (cerchiamo percorsi per punti) e quindi riduciamo tutti i tipi di dati iniziali a uno solo. Come ridurli a un solo tipo è una domanda ambigua. Potremmo farlo semplicemente calcolando i centroidi. Tuttavia, nel caso di calcoli in aree urbane e soprattutto per oggetti di grandi dimensioni (come i parchi), trovare percorsi per i centroidi potrebbe non essere necessario – consideriamo di aver raggiunto il parco non quando siamo nel suo centro, ma quando facciamo il primo passo dal percorso asfaltato nell’incantevole oscurità del parco di terra piacevole.

Quindi, abbiamo deciso di utilizzare un approccio in cui troviamo il punto più vicino di un oggetto poligonale o lineare all’oggetto di analisi (da cui vengono costruiti i percorsi). Quindi questo punto viene considerato come nodo di destinazione finale, a questo nodo verrà costruito il percorso successivo attraverso il grafo.

Analisi più avanzate

Non puoi impressionare nessuno solo con percorsi verso i bar. Quindi compliciamo il compito. Supponiamo di voler fare un’analisi più complessa combinando dati da diverse fonti. Ad esempio, vogliamo calcolare quanto dobbiamo camminare in media per raggiungere i parchi con alberi di quercia (ci piace camminare dopo i bar e ammirare il parco con gli alberi). Per fare ciò, combineremo i dati da due fonti:

  • Scarichiamo dati vettoriali da GBIF | Global Biodiversity Information Facility (controlla https://www.gbif.org/, pertinente per il 20 ottobre 2023)
  • OpenStreetMap – integrazione nativa per il download dei dati nella libreria

I dati GBIF sono uno strato vettoriale con geometrie puntuali che mostrano le posizioni in cui sono state trovate determinate specie di piante e animali (e altro ancora). In questo caso ci interesserà la Quercia (o Quercus robur in latino). Ecco come appariranno i nostri dati quando sovrapponiamo uno strato di punti con le querce sopra i poligoni dei parchi:

Figura 8. Combinazione dei dati dei parchi OSM e dei dati GBIF per calcolare i percorsi verso i parchi con boschi di querce (immagine dell'autore)

Il codice per l’analisi assomiglia a questo:

Una cosa importante da notare è che i punti non devono cadere esattamente all’interno del poligono del parco. Combiamo dati da diverse fonti e possono differire leggermente. Pertanto, impostiamo un buffer di 10 metri e guardiamo il risultato (Figura 9) – considereremo che nel parco ci sia un albero di quercia se il poligono del parco ha un’intersezione con il poligono del buffer secondo i dati GBIF:

Figura 9. Percorsi verso i parchi in cui si trovano alberi di quercia, con distanze calcolate (immagine dell'autore)

Un po’ di più sulla rilevanza

L’argomento dell’analisi è richiesto e ovvio. Di conseguenza, ad esempio, la funzionalità di routing è disponibile in molte soluzioni di codice sorgente (mentre preparavo questo articolo ho trovato un interessante notebook “Esplorazione degli strumenti di routing per calcolare percorsi per un insieme di coppie di origine-destinazione“), così come nei servizi utente popolari come Google Maps e servizi correlati alle mappe implicitamente. Se parliamo di analisi di prossimità, anche qui ci sono molte soluzioni implementate. Ad esempio, possiamo menzionare uno strumento come pandana.

Tutti questi strumenti sono certamente utili, ma utilizzarli negli esempi di applicazione richiede la scrittura di un po’ di codice ausiliario. Stiamo cercando di creare uno strumento comodo per il nostro team e vogliamo condividere le nostre scoperte con la comunità. Nell’approccio presentato in questo articolo possiamo menzionare l’approccio indipendente dalla fonte dei dati e un modo flessibile di combinare i dati. Saremo felici di ricevere commenti e suggerimenti.

Link utili:

Set di dati utilizzati in questo post (& licenze):

  1. Dati mappati forniti dai contributori di OpenStreetMap e disponibili su https://www.openstreetmap.org Licenza — Open Data Commons Open Database LicenseI link sono aggiornati al 25 ottobre 2023
  2. GBIF.org (20 ottobre 2023) GBIF Occurrence Download https://doi.org/10.15468/dl.f487j5 Licenza — Attribution-NonCommercial 4.0 InternationalI link sono aggiornati al 25 ottobre 2023

La storia sull’analisi di prossimità utilizzando i dati di OpenStreetMap e altro è stata presentata da Mikhail Sarafanov e dal team Wiredhut