Kern-Dichteschätzung von Artenverbreitungen

Machine LearningMachine LearningBeginner
Jetzt üben

This tutorial is from open-source community. Access the source code

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

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.