Einführung
In diesem Lab wird ein Beispiel für eine auf Nachbarn basierende Abfrage (insbesondere eine Kernel-Dichteschätzung) auf geographischen Daten demonstriert, wobei ein Ball Tree auf der Grundlage der Haversine-Distanzmetrik erstellt wird – d.h. Distanzen zwischen Punkten in Längen- und Breitengrad. Der Datensatz wird von Phillips et. al. (2006) zur Verfügung gestellt. Das Beispiel verwendet die Basemap-Bibliothek, um die Küstenlinien und die nationalen Grenzen Südamerikas zu zeichnen.
Tipps für die virtuelle Maschine
Nachdem der Start der virtuellen Maschine abgeschlossen ist, klicken Sie in der linken oberen Ecke, um zur Registerkarte Notebook zu wechseln und Jupyter Notebook für die Übung zu nutzen.
Manchmal müssen Sie einige Sekunden warten, bis Jupyter Notebook vollständig geladen ist. Die Validierung von Vorgängen kann aufgrund der Einschränkungen von Jupyter Notebook nicht automatisiert werden.
Wenn Sie bei der Lernphase Probleme haben, können Sie Labby gerne fragen. Geben Sie nach der Sitzung Feedback, und wir werden das Problem für Sie prompt beheben.
Importieren der erforderlichen Bibliotheken
Der erste Schritt besteht darin, die erforderlichen Bibliotheken für dieses Lab zu importieren. In diesem Lab werden wir die Bibliotheken numpy, matplotlib, fetch_species_distributions und KernelDensity verwenden.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_species_distributions
from sklearn.neighbors import KernelDensity
Daten laden
Als nächster Schritt laden wir die von Phillips et. al. (2006) bereitgestellten Daten. Der Datensatz enthält zwei Arten, die wir verwenden werden, um die Kernel-Dichteschätzung zu demonstrieren.
data = fetch_species_distributions()
species_names = ["Bradypus Variegatus", "Microryzomys Minutus"]
Daten vorbereiten
Wir bereiten nun die Daten für die Kernel-Dichteschätzung vor. Wir extrahieren die Längen- und Breitengradinformationen aus dem Datensatz und konvertieren sie in Radiant.
Xtrain = np.vstack([data["train"]["dd lat"], data["train"]["dd long"]]).T
ytrain = np.array(
[d.decode("ascii").startswith("micro") for d in data["train"]["species"]],
dtype="int",
)
Xtrain *= np.pi / 180.0 ## Convert lat/long to radians
Gitter erstellen
Wir werden nun das Kartengitter aus dem Batch-Objekt erstellen. Dazu verwenden wir die Funktion construct_grids.
def construct_grids(batch):
"""Construct the map grid from the batch object
Parameters
----------
batch : Batch object
Das von :func:`fetch_species_distributions` zurückgegebene Objekt
Returns
-------
(xgrid, ygrid) : 1-D arrays
Das Gitter, das den Werten in batch.coverages entspricht
"""
## x,y-Koordinaten für die Eckzellen
xmin = batch.x_left_lower_corner + batch.grid_size
xmax = xmin + (batch.Nx * batch.grid_size)
ymin = batch.y_left_lower_corner + batch.grid_size
ymax = ymin + (batch.Ny * batch.grid_size)
## x-Koordinaten der Gitterzellen
xgrid = np.arange(xmin, xmax, batch.grid_size)
## y-Koordinaten der Gitterzellen
ygrid = np.arange(ymin, ymax, batch.grid_size)
return (xgrid, ygrid)
## Rufen Sie die Funktion auf und speichern Sie die Ergebnisse in xgrid und ygrid
xgrid, ygrid = construct_grids(data)
Das Datennetz vorbereiten
Wir werden das Datennetz für das Konturndiagramm einrichten. Dazu verwenden wir die Funktion construct_grids.
X, Y = np.meshgrid(xgrid[::5], ygrid[::5][::-1])
land_reference = data.coverages[6][::5, ::5]
land_mask = (land_reference > -9999).ravel()
xy = np.vstack([Y.ravel(), X.ravel()]).T
xy = xy[land_mask]
xy *= np.pi / 180.0
Karte von Südamerika zeichnen
Wir werden nun die Karte von Südamerika mit den Verbreitungen jeder Art zeichnen.
fig = plt.figure()
fig.subplots_adjust(left=0.05, right=0.95, wspace=0.05)
for i in range(2):
plt.subplot(1, 2, i + 1)
print(" - computing KDE in spherical coordinates")
kde = KernelDensity(
bandwidth=0.04, metric="haversine", kernel="gaussian", algorithm="ball_tree"
)
kde.fit(Xtrain[ytrain == i])
Z = np.full(land_mask.shape[0], -9999, dtype="int")
Z[land_mask] = np.exp(kde.score_samples(xy))
Z = Z.reshape(X.shape)
levels = np.linspace(0, Z.max(), 25)
plt.contourf(X, Y, Z, levels=levels, cmap=plt.cm.Reds)
if basemap:
print(" - plot coastlines using basemap")
m = Basemap(
projection="cyl",
llcrnrlat=Y.min(),
urcrnrlat=Y.max(),
llcrnrlon=X.min(),
urcrnrlon=X.max(),
resolution="c",
)
m.drawcoastlines()
m.drawcountries()
else:
print(" - plot coastlines from coverage")
plt.contour(
X, Y, land_reference, levels=[-9998], colors="k", linestyles="solid"
)
plt.xticks([])
plt.yticks([])
plt.title(species_names[i])
plt.show()
Zusammenfassung
In diesem Lab haben wir gelernt, wie man die Kernel-Dichteschätzung auf geographische Daten anwendet. Wir haben das Dataset von Phillips et. al. (2006) verwendet, um diese Technik zu demonstrieren. Wir haben auch gelernt, wie man die Karte von Südamerika mit den Verbreitungen jeder Art mit der basemap-Bibliothek zeichnet.