Modelagem da Distribuição de Espécies

Beginner

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

Introdução

Neste laboratório, aprenderemos a modelar as distribuições geográficas de espécies utilizando machine learning. Este é um problema importante na biologia da conservação, pois nos ajuda a compreender a distribuição de diferentes espécies e a projetar estratégias de conservação eficazes. Usaremos um conjunto de dados de dois mamíferos sul-americanos com base em observações passadas e 14 variáveis ambientais. Utilizaremos o algoritmo OneClassSVM da biblioteca scikit-learn para modelar a distribuição geográfica dessas duas espécies.

Dicas da Máquina Virtual

Após o arranque da máquina virtual, clique no canto superior esquerdo para mudar para a aba Notebook para aceder ao Jupyter Notebook para a prática.

Por vezes, pode ser necessário esperar alguns segundos para o Jupyter Notebook terminar de carregar. A validação das operações não pode ser automatizada devido a limitações no Jupyter Notebook.

Se tiver problemas durante o aprendizado, não hesite em contactar o Labby. Forneça feedback após a sessão e resolveremos o problema rapidamente para si.

Importar Bibliotecas

Neste passo, importamos as bibliotecas necessárias para a nossa análise. Importaremos a biblioteca scikit-learn para machine learning, numpy para computação numérica e matplotlib para visualização.

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

Carregar Dados

Neste passo, carregaremos os dados da biblioteca scikit-learn. Usaremos a função fetch_species_distributions para carregar os dados de dois mamíferos sul-americanos com base em observações passadas e 14 variáveis ambientais.

## Carregar os dados comprimidos
data = fetch_species_distributions()

Construir Grade do Mapa

Neste passo, construiremos a grade do mapa a partir do objeto de dados. Criaremos uma função chamada construct_grids que recebe o objeto de dados como entrada e retorna as grades xgrid e ygrid.

def construct_grids(batch):
    """Construir a grade do mapa a partir do objeto batch

    Parâmetros
    ----------
    batch : Objeto Batch
        O objeto retornado por fetch_species_distributions

    Retorna
    -------
    (xgrid, ygrid) : arrays 1-D
        A grade correspondente aos valores em batch.coverages
    """
    ## Coordenadas x,y para as células de canto
    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 das células da grade
    xgrid = np.arange(xmin, xmax, batch.grid_size)
    ## Coordenadas y das células da grade
    ygrid = np.arange(ymin, ymax, batch.grid_size)

    return (xgrid, ygrid)

## Construir a grade do mapa
xgrid, ygrid = construct_grids(data)

Criar Grupo de Espécies

Neste passo, criaremos um grupo com informações sobre um organismo específico. Criaremos uma função chamada create_species_bunch que recebe o nome da espécie, dados de treino (train), dados de teste (test), dados de cobertura (coverages), e as grades xgrid e ygrid como entrada e retorna um objeto bunch.

def create_species_bunch(species_name, train, test, coverages, xgrid, ygrid):
    """Criar um grupo com informações sobre um organismo específico

    Isto utilizará os arrays de registros de teste/treino para extrair os
    dados específicos para o nome da espécie fornecido.
    """
    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():
        ## escolher pontos associados à espécie desejada
        pts = pts[pts["species"] == species_name]
        bunch["pts_%s" % label] = pts

        ## determinar os valores de cobertura para cada um dos pontos de treino e teste
        ix = np.searchsorted(xgrid, pts["dd long"])
        iy = np.searchsorted(ygrid, pts["dd lat"])
        bunch["cov_%s" % label] = coverages[:, -iy, ix].T

    return bunch

## Criar grupos de espécies
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

Neste passo, ajustaremos o modelo OneClassSVM aos dados de treino. Padronizaremos as características e ajustaremos o modelo OneClassSVM aos dados de treino.

## Padronizar 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)

Predizer Distribuição de Espécies

Neste passo, preveremos a distribuição da espécie usando o modelo OneClassSVM. Predizeremos a distribuição da espécie usando os dados de treino e plotaremos os resultados.

## Predizer a distribuição da espécie usando os dados de treino
Z = np.ones((data.Ny, data.Nx), dtype=np.float64)

## Iremos prever apenas para os pontos terrestres.
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

## plotar contornos da previsão
plt.contourf(X, Y, Z, levels=levels, cmap=plt.cm.Reds)
plt.colorbar(format="%.2f")

## dispersão de pontos de treino/teste
plt.scatter(
    BV_bunch.pts_train["dd long"],
    BV_bunch.pts_train["dd lat"],
    s=2**2,
    c="black",
    marker="^",
    label="treino",
)
plt.scatter(
    BV_bunch.pts_test["dd long"],
    BV_bunch.pts_test["dd lat"],
    s=2**2,
    c="black",
    marker="x",
    label="teste",
)
plt.legend()
plt.title(BV_bunch.name)
plt.axis("equal")

Calcular AUC

Neste passo, calcularemos a área sob a curva ROC (AUC) em relação aos pontos de fundo. Predizeremos a distribuição da espécie usando os dados de teste e os pontos de fundo, e calcularemos a AUC.

## Calcular AUC em relação aos pontos de fundo
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 sob a curva ROC : %f" % roc_auc)

Plotar Distribuição de Espécies

Neste passo, plotaremos a distribuição das espécies para ambas as espécies utilizando as funções e modelos que criámos.

## Plotar distribuição das espécies
plot_species_distribution()
plt.show()

Sumário

Neste laboratório, aprendemos a modelar distribuições geográficas de espécies usando aprendizado de máquina. Utilizámos o algoritmo OneClassSVM da biblioteca scikit-learn para modelar a distribuição geográfica de dois mamíferos sul-americanos, com base em observações passadas e 14 variáveis ambientais. Também aprendemos a plotar a distribuição das espécies e a calcular a área sob a curva ROC para avaliar o desempenho do nosso modelo.