종 분포 모델링

Beginner

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

소개

이 실험에서는 머신 러닝을 사용하여 종의 지리적 분포를 모델링하는 방법을 배웁니다. 이는 보존 생물학에서 중요한 문제로, 다양한 종의 분포를 이해하고 효과적인 보존 전략을 설계하는 데 도움이 됩니다. 과거 관측치와 14 개의 환경 변수가 주어진 남미 포유류 두 종의 데이터 세트를 사용할 것입니다. scikit-learn 라이브러리의 OneClassSVM 알고리즘을 사용하여 이 두 종의 지리적 분포를 모델링할 것입니다.

VM 팁

VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 연습을 위한 Jupyter Notebook에 접근할 수 있는 Notebook 탭으로 전환합니다.

때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업의 유효성 검사는 자동화될 수 없습니다.

학습 중 문제가 발생하면 Labby 에게 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.

라이브러리 가져오기

이 단계에서는 분석에 필요한 라이브러리를 가져옵니다. 머신 러닝을 위해 scikit-learn 라이브러리, 수치 계산을 위해 numpy 라이브러리, 시각화를 위해 matplotlib 라이브러리를 가져올 것입니다.

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

데이터 로드

이 단계에서는 scikit-learn 라이브러리에서 데이터를 로드합니다. fetch_species_distributions 함수를 사용하여 과거 관측치와 14 개의 환경 변수가 주어진 남미 포유류 두 종의 데이터를 로드합니다.

## 압축된 데이터 로드
data = fetch_species_distributions()

맵 그리드 생성

이 단계에서는 데이터 객체로부터 맵 그리드를 생성합니다. construct_grids라는 함수를 만들어 데이터 객체를 입력으로 받아 xgrid 와 ygrid 를 반환합니다.

def construct_grids(batch):
    """배치 객체로부터 맵 그리드를 생성합니다.

    매개변수
    ----------
    batch : 배치 객체
        fetch_species_distributions 함수의 반환 값

    반환값
    -------
    (xgrid, ygrid) : 1 차원 배열
        batch.coverages 의 값에 해당하는 그리드
    """
    ## 모서리 셀의 x, y 좌표
    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 좌표
    xgrid = np.arange(xmin, xmax, batch.grid_size)
    ## 그리드 셀의 y 좌표
    ygrid = np.arange(ymin, ymax, batch.grid_size)

    return (xgrid, ygrid)

## 맵 그리드 생성
xgrid, ygrid = construct_grids(data)

특정 종 번들 생성

이 단계에서는 특정 생물체에 대한 정보를 담은 번들 (bunch) 을 생성합니다. create_species_bunch 함수를 만들어 종 이름, 학습 데이터, 테스트 데이터, 범위 데이터, x 축 그리드, y 축 그리드를 입력으로 받아 번들 객체를 반환합니다.

def create_species_bunch(species_name, train, test, coverages, xgrid, ygrid):
    """특정 생물체에 대한 정보를 담은 번들 생성

    test/train 레코드 배열을 사용하여 지정된 종 이름에 대한 데이터를 추출합니다.
    """
    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():
        ## 원하는 종과 관련된 점 선택
        pts = pts[pts["species"] == species_name]
        bunch["pts_%s" % label] = pts

        ## 각 학습 및 테스트 점에 대한 범위 값 결정
        ix = np.searchsorted(xgrid, pts["dd long"])
        iy = np.searchsorted(ygrid, pts["dd lat"])
        bunch["cov_%s" % label] = coverages[:, -iy, ix].T

    return bunch

## 종 번들 생성
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
)

OneClassSVM 모델 학습

이 단계에서는 OneClassSVM 모델을 학습 데이터에 맞춥니다. 특징을 표준화하고 OneClassSVM 모델을 학습 데이터에 맞춥니다.

## 특징 표준화
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

## OneClassSVM 모델 학습
clf = svm.OneClassSVM(nu=0.1, kernel="rbf", gamma=0.5)
clf.fit(train_cover_std)

종 분포 예측

이 단계에서는 OneClassSVM 모델을 사용하여 종 분포를 예측합니다. 학습 데이터를 사용하여 종 분포를 예측하고 결과를 플롯합니다.

## 학습 데이터를 사용하여 종 분포 예측
Z = np.ones((data.Ny, data.Nx), dtype=np.float64)

## 육지 지점에 대해서만 예측합니다.
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

## 예측 결과의 등고선 플롯
plt.contourf(X, Y, Z, levels=levels, cmap=plt.cm.Reds)
plt.colorbar(format="%.2f")

## 학습/테스트 지점 산점도
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")

AUC 계산

이 단계에서는 배경 지점에 대한 ROC 곡선 아래 면적 (AUC) 을 계산합니다. 테스트 데이터와 배경 지점을 사용하여 종 분포를 예측하고 AUC 를 계산합니다.

## 배경 지점에 대한 AUC 계산
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 ROC 곡선 아래 면적 : %f" % roc_auc)

종 분포 시각화

이 단계에서는 생성한 함수와 모델을 사용하여 두 종의 종 분포를 시각화합니다.

## 종 분포 시각화
plot_species_distribution()
plt.show()

요약

이 실험에서는 머신 러닝을 사용하여 종의 지리적 분포를 모델링하는 방법을 배웠습니다. scikit-learn 라이브러리의 OneClassSVM 알고리즘을 사용하여 남미 포유류 두 종의 지리적 분포를 과거 관측치와 14 개의 환경 변수를 바탕으로 모델링했습니다. 또한 종 분포를 시각화하고 ROC 곡선 아래 면적 (AUC) 을 계산하여 모델의 성능을 평가하는 방법을 배웠습니다.