Modelado de la Distribución de Especies

Beginner

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

Introducción

En este laboratorio, aprenderemos a modelar las distribuciones geográficas de las especies utilizando aprendizaje automático. Este es un problema importante en biología de la conservación, ya que nos ayuda a entender la distribución de diferentes especies y a diseñar estrategias de conservación efectivas. Utilizaremos un conjunto de datos de dos mamíferos sudamericanos dados las observaciones pasadas y 14 variables ambientales. Utilizaremos el algoritmo OneClassSVM de la biblioteca scikit-learn para modelar la distribución geográfica de estas dos especies.

Consejos sobre la VM

Una vez que se haya iniciado la VM, haga clic en la esquina superior izquierda para cambiar a la pestaña Cuaderno y acceder a Jupyter Notebook para practicar.

A veces, es posible que tenga que esperar unos segundos a que Jupyter Notebook termine de cargarse. La validación de las operaciones no se puede automatizar debido a las limitaciones de Jupyter Notebook.

Si tiene problemas durante el aprendizaje, no dude en preguntar a Labby. Deje sus comentarios después de la sesión y lo resolveremos rápidamente para usted.

Importar bibliotecas

En este paso, importaremos las bibliotecas necesarias para nuestro análisis. Importaremos la biblioteca scikit-learn para el aprendizaje automático, numpy para el cálculo numérico y matplotlib para la visualización.

from time import time

import numpy as np
import matplotlib.pyplot as plt

from sklearn.utils import Bunch
from sklearn.datasets import fetch_species_distributions
from sklearn import svm, metrics

Cargar datos

En este paso, cargaremos los datos de la biblioteca scikit-learn. Utilizaremos la función fetch_species_distributions para cargar los datos de dos mamíferos sudamericanos dados las observaciones pasadas y 14 variables ambientales.

## Cargar los datos comprimidos
data = fetch_species_distributions()

Construir la cuadrícula del mapa

En este paso, construiremos la cuadrícula del mapa a partir del objeto de datos. Crearemos una función llamada construct_grids que toma el objeto de datos como entrada y devuelve xgrid e ygrid.

def construct_grids(batch):
    """Construir la cuadrícula del mapa a partir del objeto batch

    Parámetros
    ----------
    batch : Objeto Batch
        El objeto devuelto por fetch_species_distributions

    Devuelve
    -------
    (xgrid, ygrid) : arrays unidimensionales
        La cuadrícula correspondiente a los valores en batch.coverages
    """
    ## Coordenadas x,y para las celdas de esquina
    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)

    ## Coordenadas x de las celdas de la cuadrícula
    xgrid = np.arange(xmin, xmax, batch.grid_size)
    ## Coordenadas y de las celdas de la cuadrícula
    ygrid = np.arange(ymin, ymax, batch.grid_size)

    return (xgrid, ygrid)

## Construir la cuadrícula del mapa
xgrid, ygrid = construct_grids(data)

Crear el grupo de especies

En este paso, crearemos un grupo con información sobre un organismo particular. Crearemos una función llamada create_species_bunch que toma el nombre de la especie, train, test, coverages, xgrid e ygrid como entrada y devuelve un objeto grupo.

def create_species_bunch(species_name, train, test, coverages, xgrid, ygrid):
    """Crear un grupo con información sobre un organismo particular

    Esto usará las matrices de registros de prueba/train para extraer
    los datos específicos del nombre de la especie dado.
    """
    bunch = Bunch(name=" ".join(species_name.split("_")[:2]))
    species_name = species_name.encode("ascii")
    points = dict(test=test, train=train)

    for label, pts in points.items():
        ## elegir puntos asociados con la especie deseada
        pts = pts[pts["species"] == species_name]
        bunch["pts_%s" % label] = pts

        ## determinar los valores de cobertura para cada uno de los puntos de entrenamiento y prueba
        ix = np.searchsorted(xgrid, pts["dd long"])
        iy = np.searchsorted(ygrid, pts["dd lat"])
        bunch["cov_%s" % label] = coverages[:, -iy, ix].T

    return bunch

## Crear el grupo de especies
BV_bunch = create_species_bunch(
    "bradypus_variegatus_0", data.train, data.test, data.coverages, xgrid, ygrid
)
MM_bunch = create_species_bunch(
    "microryzomys_minutus_0", data.train, data.test, data.coverages, xgrid, ygrid
)

Ajustar OneClassSVM

En este paso, ajustaremos el modelo OneClassSVM a los datos de entrenamiento. Estándarizaremos las características y ajustaremos el modelo OneClassSVM a los datos de entrenamiento.

## Estándarizar características
mean = BV_bunch.cov_train.mean(axis=0)
std = BV_bunch.cov_train.std(axis=0)
train_cover_std = (BV_bunch.cov_train - mean) / std

## Ajustar OneClassSVM
clf = svm.OneClassSVM(nu=0.1, kernel="rbf", gamma=0.5)
clf.fit(train_cover_std)

Predecir la distribución de especies

En este paso, predeciríamos la distribución de especies utilizando el modelo OneClassSVM. Predeciríamos la distribución de especies utilizando los datos de entrenamiento y graficaríamos los resultados.

## Predecir la distribución de especies utilizando los datos de entrenamiento
Z = np.ones((data.Ny, data.Nx), dtype=np.float64)

## Solo predeciríamos para los puntos de tierra.
idx = np.where(data.coverages[6] > -9999)
coverages_land = data.coverages[:, idx[0], idx[1]].T

pred = clf.decision_function((coverages_land - mean) / std)
Z *= pred.min()
Z[idx[0], idx[1]] = pred

levels = np.linspace(Z.min(), Z.max(), 25)
Z[data.coverages[6] == -9999] = -9999

## graficar los contornos de la predicción
plt.contourf(X, Y, Z, levels=levels, cmap=plt.cm.Reds)
plt.colorbar(format="%.2f")

## dispersar los puntos de entrenamiento/prueba
plt.scatter(
    BV_bunch.pts_train["dd long"],
    BV_bunch.pts_train["dd lat"],
    s=2**2,
    c="black",
    marker="^",
    label="train",
)
plt.scatter(
    BV_bunch.pts_test["dd long"],
    BV_bunch.pts_test["dd lat"],
    s=2**2,
    c="black",
    marker="x",
    label="test",
)
plt.legend()
plt.title(BV_bunch.name)
plt.axis("equal")

Calcular el AUC

En este paso, calcularemos el área bajo la curva ROC (AUC) en relación con los puntos de fondo. Predeciríamos la distribución de especies utilizando los datos de prueba y los puntos de fondo, y calcularíamos el AUC.

## Calcular el AUC en relación con los puntos de fondo
background_points = np.c_[
    np.random.randint(low=0, high=data.Ny, size=10000),
    np.random.randint(low=0, high=data.Nx, size=10000),
].T

pred_background = Z[background_points[0], background_points[1]]
pred_test = clf.decision_function((BV_bunch.cov_test - mean) / std)
scores = np.r_[pred_test, pred_background]
y = np.r_[np.ones(pred_test.shape), np.zeros(pred_background.shape)]
fpr, tpr, thresholds = metrics.roc_curve(y, scores)
roc_auc = metrics.auc(fpr, tpr)
plt.text(-35, -70, "AUC: %.3f" % roc_auc, ha="right")
print("\n Área bajo la curva ROC : %f" % roc_auc)

Graficar la distribución de especies

En este paso, graficaremos la distribución de especies para ambas especies utilizando las funciones y los modelos que hemos creado.

## Graficar la distribución de especies
plot_species_distribution()
plt.show()

Resumen

En este laboratorio, aprendimos cómo modelar las distribuciones geográficas de especies utilizando aprendizaje automático. Utilizamos el algoritmo OneClassSVM de la biblioteca scikit-learn para modelar la distribución geográfica de dos mamíferos sudamericanos dados registros pasados y 14 variables ambientales. También aprendimos cómo graficar la distribución de especies y calcular el área bajo la curva ROC para evaluar el rendimiento de nuestro modelo.