Geokodierung für Datenwissenschaftler – KDnuggets

Geokodierung für Datenwissenschaftler – KDnuggets

Quellknoten: 2713218

Wenn Datenwissenschaftler alles über das „Wo“ ihrer Daten wissen müssen, greifen sie häufig auf geografische Informationssysteme (GIS) zurück. Bei GIS handelt es sich um eine komplizierte Reihe von Technologien und Programmen, die einer Vielzahl von Zwecken dienen. Die University of Washington bietet jedoch eine ziemlich umfassende Definition: „Ein geografisches Informationssystem ist eine komplexe Anordnung verbundener oder verbundener Dinge oder Objekte, deren Zweck darin besteht, Folgendes zu tun.“ Wissen über Merkmale auf der Erdoberfläche vermitteln“ (Lawler et al.). GIS umfasst eine breite Palette von Techniken zur Verarbeitung räumlicher Daten von der Erfassung bis zur Visualisierung, von denen viele wertvolle Werkzeuge sind, selbst wenn Sie kein GIS-Spezialist sind. Dieser Artikel bietet einen umfassenden Überblick über die Geokodierung mit Demonstrationen in Python verschiedener praktischer Anwendungen. Konkret ermitteln Sie anhand der Adresse den genauen Standort einer Pizzeria in New York City, New York, und verknüpfen ihn mit Daten über nahegelegene Parks. Während die Demonstrationen Python-Code verwenden, können die Kernkonzepte auf viele Programmierumgebungen angewendet werden, um Geokodierung in Ihren Arbeitsablauf zu integrieren. Diese Tools bilden die Grundlage für die Umwandlung von Daten in räumliche Daten und öffnen die Tür für komplexere geografische Analysen. 

 

XXXXX

Geokodierung wird am häufigsten als die Umwandlung von Adressdaten in Kartierungskoordinaten definiert. Normalerweise geht es darum, einen Straßennamen in einer Adresse zu erkennen, diese Straße mit den Grenzen ihres realen Gegenstücks in einer Datenbank abzugleichen und dann anhand der Straßennummer abzuschätzen, wo auf der Straße die Adresse platziert werden soll. Lassen Sie uns als Beispiel den Prozess einer einfachen manuellen Geokodierung für die Adresse einer Pizzeria in New York am Broadway durchgehen: 2709 Broadway, New York, NY 10025. Die erste Aufgabe besteht darin, geeignete Shapefiles für das Straßennetz des Standorts zu finden Ihrer Adresse. Beachten Sie, dass in diesem Fall die Stadt und das Bundesland der Adresse „New York, NY“ lauten. Glücklicherweise veröffentlicht die Stadt New York detaillierte Straßeninformationen Offene Daten von NYC Seite (CSCL PUB). Zweitens untersuchen Sie den Straßennamen „Broadway“. Sie wissen jetzt, dass die Adresse in jeder Straße namens „Broadway“ in New York City liegen kann, sodass Sie den folgenden Python-Code ausführen können, um die NYC Open Data SODA API für alle Straßen mit dem Namen „Broadway“ abzufragen.

import geopandas as gpd
import requests
from io import BytesIO # Request the data from the SODA API
req = requests.get( "https://data.cityofnewyork.us/resource/gdww-crzy.geojson?stname_lab=BROADWAY"
)
# Convert to a stream of bytes
reqstrm = BytesIO(req.content)
# Read the stream as a GeoDataFrame
ny_streets = gpd.read_file(reqstrm)

 

Es gibt über 700 Ergebnisse dieser Abfrage, aber das bedeutet nicht, dass Sie 700 Straßen durchsuchen müssen, um Ihre Pizza zu finden. Wenn Sie die Daten visualisieren, können Sie erkennen, dass es drei Hauptstraßen am Broadway und einige kleinere Straßen gibt.

 

XXXXX
 

Der Grund dafür ist, dass jede Straße in Abschnitte unterteilt ist, die ungefähr einem Block entsprechen, was eine detailliertere Betrachtung der Daten ermöglicht. Der nächste Schritt des Prozesses besteht darin, mithilfe der Postleitzahl und der Hausnummer genau zu bestimmen, in welchem ​​dieser Abschnitte sich die Adresse befindet. Jedes Straßensegment im Datensatz enthält Adressbereiche für die Adressen von Gebäuden auf der linken und rechten Straßenseite. Ebenso enthält jedes Segment die Postleitzahl sowohl für die linke als auch für die rechte Straßenseite. Um das richtige Segment zu finden, wendet der folgende Code Filter an, um das Straßensegment zu finden, dessen Postleitzahl mit der Postleitzahl der Adresse übereinstimmt und dessen Adressbereich die Straßennummer der Adresse enthält.

# Address to be geocoded
address = "2709 Broadway, New York, NY 10025"
zipcode = address.split(" ")[-1]
street_num = address.split(" ")[0] # Find street segments whose left side address ranges contain the street number
potentials = ny_streets.loc[ny_streets["l_low_hn"] street_num]
potentials = potentials.loc[potentials["l_high_hn"] > street_num]
# Find street segments whose zipcode matches the address'
potentials = potentials.loc[potentials["l_zip"] == zipcode]

 

Dadurch wird die Liste auf den unten gezeigten Straßenabschnitt eingegrenzt.

 

XXXXX
 

Die letzte Aufgabe besteht darin, festzustellen, wo die Adresse in dieser Zeile liegt. Dies geschieht, indem die Straßennummer innerhalb des Adressbereichs für das Segment platziert wird, eine Normalisierung durchgeführt wird, um zu bestimmen, wie weit entlang der Linie die Adresse liegen soll, und diese Konstante auf die Koordinaten der Endpunkte der Linie angewendet wird, um die Koordinaten der Adresse zu erhalten. Der folgende Code beschreibt diesen Prozess.

import numpy as np
from shapely.geometry import Point # Calculate how far along the street to place the point
denom = ( potentials["l_high_hn"].astype(float) - potentials["l_low_hn"].astype(float)
).values[0]
normalized_street_num = ( float(street_num) - potentials["l_low_hn"].astype(float).values[0]
) / denom # Define a point that far along the street
# Move the line to start at (0,0)
pizza = np.array(potentials["geometry"].values[0].coords[1]) - np.array( potentials["geometry"].values[0].coords[0]
)
# Multiply by normalized street number to get coordinates on line
pizza = pizza * normalized_street_num
# Add starting segment to place line back on the map
pizza = pizza + np.array(potentials["geometry"].values[0].coords[0])
# Convert to geometry array for geopandas
pizza = gpd.GeoDataFrame( {"address": , "geometry": [Point(pizza[0], pizza[1])]}, crs=ny_streets.crs, geometry="geometry",
)

 

Nachdem die Geokodierung der Adresse abgeschlossen ist, ist es nun möglich, den Standort dieser Pizzeria auf einer Karte einzutragen, um ihren Standort zu verstehen. Da der obige Code Informationen berücksichtigt, die sich auf die linke Seite eines Straßenabschnitts beziehen, liegt der tatsächliche Standort etwas links vom gezeichneten Punkt in einem Gebäude auf der linken Straßenseite. Endlich wissen Sie, wo Sie Pizza bekommen können.

 

XXXXX
 

Dieser Prozess deckt das ab, was am häufigsten als Geokodierung bezeichnet wird, es ist jedoch nicht die einzige Verwendungsart des Begriffs. Möglicherweise bezieht sich Geokodierung auch auf den Prozess der Übertragung von Orientierungspunktnamen in Koordinaten, Postleitzahlen in Koordinaten oder Koordinaten in GIS-Vektoren. Möglicherweise hören Sie sogar, dass die umgekehrte Geokodierung (auf die später noch eingegangen wird) als Geokodierung bezeichnet wird. Eine mildere Definition für Geokodierung, die diese umfasst, wäre „die Übertragung zwischen ungefähren, natürlichsprachlichen Beschreibungen von Orten und geografischen Koordinaten“. Wenn Sie also zwischen diesen beiden Datenarten wechseln müssen, sollten Sie die Geokodierung als Lösung in Betracht ziehen.

Als Alternative zur Wiederholung dieses Vorgangs, wann immer Sie Adressen geokodieren müssen, können Sie eine Vielzahl von API-Endpunkten verwenden, z Geocoder des US Census Bureau und für Google Geocoding-API, bieten kostenlos einen genauen Geokodierungsdienst an. Einige kostenpflichtige Optionen, wie z ArcGIS von Esri, Geocode und Smarty bieten sogar Dachgenauigkeit für ausgewählte Adressen, was bedeutet, dass die zurückgegebenen Koordinaten genau auf dem Dach des Gebäudes landen und nicht auf einer nahegelegenen Straße. In den folgenden Abschnitten wird am Beispiel des US Census Bureau Geocoder beschrieben, wie Sie diese Dienste nutzen können, um die Geokodierung in Ihre Datenpipeline zu integrieren.

Um bei der Geokodierung die größtmögliche Genauigkeit zu erzielen, sollten Sie zunächst immer sicherstellen, dass Ihre Adressen so formatiert sind, dass sie den Standards des von Ihnen gewählten Dienstes entsprechen. Dies unterscheidet sich leicht zwischen den einzelnen Diensten, aber ein gängiges Format ist das USPS-Format „PRIMARY# STREET, CITY, STATE, PLZ“, wobei STATE ein Abkürzungscode ist, PRIMARY# die Straßennummer ist und alle Erwähnungen von Suite-Nummern und Gebäuden erfolgen Telefonnummern und Postfächer werden entfernt. 

Sobald Ihre Adresse formatiert ist, müssen Sie sie zur Geokodierung an die API übermitteln. Im Fall des Geocoder des US Census Bureau können Sie die Adresse entweder manuell über die Registerkarte „One Line Address Processing“ übermitteln oder das verwenden bereitgestellte REST-API um die Adresse programmgesteuert zu übermitteln. Mit dem Geocoder des US Census Bureau können Sie auch ganze Dateien mit dem Batch-Geocoder geokodieren und die Datenquelle mithilfe des Benchmark-Parameters angeben. Um die Pizzeria von früher zu geokodieren, diesen Link kann verwendet werden, um die Adresse an die REST-API zu übergeben, was in Python mit dem folgenden Code erfolgen kann.

# Submit the address to the U.S. Census Bureau Geocoder REST API for processing
response = requests.get( "https://geocoding.geo.census.gov/geocoder/locations/onelineaddress?address=2709+Broadway%2C+New+York%2C+NY+10025&benchmark=Public_AR_Current&format=json"
).json()

 

Bei den zurückgegebenen Daten handelt es sich um eine JSON-Datei, die einfach in ein Python-Wörterbuch dekodiert werden kann. Es enthält ein „tigerLineId“-Feld, das verwendet werden kann, um das Shapefile für die nächstgelegene Straße abzugleichen, ein „side“-Feld, das verwendet werden kann, um zu bestimmen, auf welcher Seite dieser Straße sich die Adresse befindet, sowie die Felder „fromAddress“ und „toAddress“. die den Adressbereich für den Straßenabschnitt enthalten. Am wichtigsten ist, dass es ein „Koordinaten“-Feld enthält, mit dem die Adresse auf einer Karte lokalisiert werden kann. Der folgende Code extrahiert die Koordinaten aus der JSON-Datei und verarbeitet sie in einen GeoDataFrame, um ihn für die räumliche Analyse vorzubereiten.

# Extract coordinates from the JSON file
coords = response["result"]["addressMatches"][0]["coordinates"]
# Convert coordinates to a Shapely Point
coords = Point(coords["x"], coords["y"])
# Extract matched address
matched_address = response["result"]["addressMatches"][0]["matchedAddress"]
# Create a GeoDataFrame containing the results
pizza_point = gpd.GeoDataFrame( {"address": [matched_address], "geometry": coords}, crs=ny_streets.crs, geometry="geometry",
)

 

Die Visualisierung dieses Punkts zeigt, dass er etwas abseits der Straße links vom Punkt liegt, der manuell geokodiert wurde.

 

XXXXX

Bei der umgekehrten Geokodierung werden geografische Koordinaten erfasst und mit Beschreibungen einer geografischen Region in natürlicher Sprache abgeglichen. Bei richtiger Anwendung ist es eine der leistungsstärksten Techniken zum Anhängen externer Daten im Data Science-Toolkit. Der erste Schritt der umgekehrten Geokodierung besteht darin, Ihre Zielregionen zu bestimmen. Dies ist die Region, die Ihre Koordinatendaten enthalten wird. Einige gängige Beispiele sind Volkszählungsbezirke, Postleitzahlen und Städte. Der zweite Schritt besteht darin, zu bestimmen, in welcher dieser Regionen sich der Punkt befindet. Bei der Verwendung gemeinsamer Regionen wird die Geocoder für US-Volkszählung kann verwendet werden, um die Geokodierung umzukehren, indem kleine Änderungen an der REST-API-Anfrage vorgenommen werden. Eine Anfrage zur Bestimmung, in welchen Volkszählungsregionen sich die Pizzeria von früher befindet, ist verlinkt hier. Das Ergebnis dieser Abfrage kann mit den gleichen Methoden wie zuvor verarbeitet werden. Die kreative Definition der Region entsprechend einem Analysebedarf und die manuelle Umkehrung der Geokodierung eröffnen jedoch viele Möglichkeiten. 

Um die Geokodierung manuell umzukehren, müssen Sie die Position und Form einer Region bestimmen und dann feststellen, ob sich der Punkt im Inneren dieser Region befindet. Zu bestimmen, ob sich ein Punkt innerhalb eines Polygons befindet, ist eigentlich ein ziemlich schwieriges Problem, aber das Ray-Casting-Algorithmus, bei dem ein Strahl, der an dem Punkt beginnt und sich unendlich in eine Richtung ausbreitet, die Grenze der Region ungerade oft schneidet, wenn er sich innerhalb der Region befindet, und ansonsten gerade oft (Shimrat), kann in den meisten Fällen zur Lösung verwendet werden Fälle. Für Mathematiker ist dies tatsächlich eine direkte Anwendung des Satz von Jordan-Kurven (Hosch). Hinweis: Wenn Sie Daten aus der ganzen Welt verwenden, kann der Ray-Casting-Algorithmus tatsächlich fehlschlagen, da ein Strahl schließlich die Erdoberfläche umschließt und zu einem Kreis wird. In diesem Fall müssen Sie stattdessen die Windungszahl (Weisstein) für die Region und den Punkt ermitteln. Der Punkt liegt innerhalb der Region, wenn die Windungszahl nicht Null ist. Glücklicherweise bietet die Geopandas-Bibliothek von Python die erforderliche Funktionalität, um sowohl das Innere einer polygonalen Region zu definieren als auch zu testen, ob sich ein Punkt darin befindet, ohne dass die gesamte komplexe Mathematik erforderlich ist.

Während die manuelle Geokodierung für viele Anwendungen zu komplex sein kann, kann die manuelle umgekehrte Geokodierung eine praktische Ergänzung Ihrer Fähigkeiten sein, da Sie Ihre Punkte problemlos stark benutzerdefinierten Regionen zuordnen können. Angenommen, Sie möchten Ihr Stück Pizza in einen Park mitnehmen und dort ein Picknick machen. Vielleicht möchten Sie wissen, ob sich die Pizzeria in der Nähe eines Parks befindet. New York City stellt im Rahmen des Projekts Shapefiles für seine Parks bereit Datensatz „Parks Properties“. (NYC Parks Open Data Team), und sie können auch über ihre SODA-API mit dem folgenden Code aufgerufen werden.

# Pull NYC park shapefiles
parks = gpd.read_file( BytesIO( requests.get( "https://data.cityofnewyork.us/resource/enfh-gkve.geojson?$limit=5000" ).content )
)
# Limit to parks with green area for a picnic
parks = parks.loc[ parks["typecategory"].isin( [ "Garden", "Nature Area", "Community Park", "Neighborhood Park", "Flagship Park", ] )
]

 

Diese Parks können zur Visualisierung hinzugefügt werden, um zu sehen, welche Parks sich in der Nähe der Pizzeria befinden.

 

XXXXX
 

Es gibt eindeutig einige Möglichkeiten in der Nähe, aber die Entfernung mithilfe der Shapefiles und des Punktes zu ermitteln, kann schwierig und rechenintensiv sein. Stattdessen kann eine umgekehrte Geokodierung angewendet werden. Der erste Schritt besteht, wie oben erwähnt, darin, die Region zu bestimmen, an die Sie den Punkt anhängen möchten. In diesem Fall ist die Region „eine halbe Meile von einem Park in New York City entfernt“. Der zweite Schritt ist die Berechnung, ob der Punkt innerhalb einer Region liegt. Dies kann mathematisch mit den zuvor genannten Methoden oder durch Anwendung der Funktion „enthält“ in Geopandas erfolgen. Der folgende Code wird verwendet, um vor dem Testen einen 1/2-Meilen-Puffer zu den Grenzen der Parks hinzuzufügen, um zu sehen, welche gepufferten Regionen der Parks jetzt den Punkt enthalten.

# Project the coordinates from latitude and longitude into meters for distance calculations
buffered_parks = parks.to_crs(epsg=2263)
pizza_point = pizza_point.to_crs(epsg=2263)
# Add a buffer to the regions extending the border by 1/2 mile = 2640 feet
buffered_parks = buffered_parks.buffer(2640)
# Find all parks whose buffered region contains the pizza parlor
pizza_parks = parks.loc[buffered_parks.contains(pizza_point["geometry"].values[0])]

 

Dieser Puffer zeigt die nahegelegenen Parks, die im Bild unten blau hervorgehoben sind

 

XXXXX
 

Nach erfolgreicher umgekehrter Geokodierung haben Sie erfahren, dass es im Umkreis von einer halben Meile um die Pizzeria 8 Parks gibt, in denen Sie Ihr Picknick machen können. Genießen Sie dieses Stück.
 

XXXXX
Pizzastück von j4p4n

Quellen

  1. Lawler, Josh und Schiess, Peter. ESRM 250: Einführung in geografische Informationssysteme in Waldressourcen. Definitionen von GIS, 12. Februar 2009, University of Washington, Seattle. Klassenvortrag. https://courses.washington.edu/gis250/lessons/introduction_gis/definitions.html
  2. CSCL PUB. New York OpenData. https://data.cityofnewyork.us/City-Government/road/svwp-sbcd
  3. Geocoder-Dokumentation des US Census Bureau. August 2022. https://geocoding.geo.census.gov/geocoder/Geocoding_Services_API.pdf 
  4. Shimrat, M., „Algorithmus 112: Position des Punktes relativ zum Polygon“ 1962, Mitteilungen der ACM Band 5, Ausgabe 8, August 1962. https://dl.acm.org/doi/10.1145/368637.368653 
  5. Hosch, William L. „Jordan-Kurvensatz“. Enzyklopädie Britannica, 13. April 2018, https://www.britannica.com/science/Jordan-curve-theorem
  6. Weisstein, Eric W. „Konturwicklungsnummer.“ Aus MathWorld–Eine Wolfram-Webressource. https://mathworld.wolfram.com/ContourWindingNumber.html
  7. NYC Parks Open Data Team. Parks-Eigenschaften. 14. April 2023. https://nycopendata.socrata.com/Recreation/Parks-Properties/enfh-gkve
  8. j4p4n, „Pizzastück.“ Aus OpenClipArt. https://openclipart.org/detail/331718/pizza-slice

 
 
Eva Miller ist Data Science Fellow bei Tech Impact, wo er Daten nutzt, um gemeinnützige Organisationen und Regierungsbehörden bei der Mission des sozialen Wohls zu unterstützen. Zuvor nutzte Evan maschinelles Lernen, um autonome Fahrzeuge an der Central Michigan University zu trainieren.
 

Zeitstempel:

Mehr von KDnuggets