はじめに
この実験では、機械学習を使って種の地理的分布をモデル化する方法を学びます。これは保全生物学における重要な問題であり、異なる種の分布を理解し、効果的な保全戦略を立案するのに役立ちます。過去の観測データと 14 の環境変数を使った南米の 2 つの哺乳類のデータセットを使います。scikit-learn ライブラリの OneClassSVM アルゴリズムを使って、これら 2 つの種の地理的分布をモデル化します。
VM のヒント
VM の起動が完了したら、左上隅をクリックしてノートブックタブに切り替え、Jupyter 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 ライブラリからデータを読み込みます。過去の観測データと 14 の環境変数を持つ 2 種類の南米の哺乳類のデータを読み込むために、fetch_species_distributions 関数を使います。
## Load the compressed data
data = fetch_species_distributions()
マップグリッドの構築
このステップでは、データオブジェクトからマップグリッドを構築します。データオブジェクトを入力として受け取り、xgrid と ygrid を返す construct_grids という関数を作成します。
def construct_grids(batch):
"""Construct the map grid from the batch object
Parameters
----------
batch : Batch object
The object returned by fetch_species_distributions
Returns
-------
(xgrid, ygrid) : 1-D arrays
The grid corresponding to the values in batch.coverages
"""
## x,y coordinates for corner cells
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 coordinates of the grid cells
xgrid = np.arange(xmin, xmax, batch.grid_size)
## y coordinates of the grid cells
ygrid = np.arange(ymin, ymax, batch.grid_size)
return (xgrid, ygrid)
## Construct the map grid
xgrid, ygrid = construct_grids(data)
種のバンチを作成する
このステップでは、特定の生物に関する情報を持つバンチを作成します。種名、学習用データ、テスト用データ、カバレッジ、x グリッド、y グリッドを入力として受け取り、バンチオブジェクトを返す create_species_bunch という関数を作成します。
def create_species_bunch(species_name, train, test, coverages, xgrid, ygrid):
"""Create a bunch with information about a particular organism
This will use the test/train record arrays to extract the
data specific to the given species name.
"""
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():
## choose points associated with the desired species
pts = pts[pts["species"] == species_name]
bunch["pts_%s" % label] = pts
## determine coverage values for each of the training & testing points
ix = np.searchsorted(xgrid, pts["dd long"])
iy = np.searchsorted(ygrid, pts["dd lat"])
bunch["cov_%s" % label] = coverages[:, -iy, ix].T
return bunch
## Create species 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 モデルを学習データにフィットさせます。
## Standardize features
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
## Fit OneClassSVM
clf = svm.OneClassSVM(nu=0.1, kernel="rbf", gamma=0.5)
clf.fit(train_cover_std)
種の分布を予測する
このステップでは、OneClassSVM モデルを使って種の分布を予測します。学習データを使って種の分布を予測し、結果をプロットします。
## Predict species distribution using the training data
Z = np.ones((data.Ny, data.Nx), dtype=np.float64)
## We'll predict only for the land points.
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
## plot contours of the prediction
plt.contourf(X, Y, Z, levels=levels, cmap=plt.cm.Reds)
plt.colorbar(format="%.2f")
## scatter training/testing points
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 を計算します。
## Compute AUC with regards to background points
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 Area under the ROC curve : %f" % roc_auc)
種の分布を描画する
このステップでは、作成した関数とモデルを使って、両方の種の種の分布を描画します。
## Plot species distribution
plot_species_distribution()
plt.show()
まとめ
この実験では、機械学習を使って種の地理的分布をモデル化する方法を学びました。scikit - learn ライブラリの OneClassSVM アルゴリズムを使って、過去の観測データと 14 個の環境変数を元に、南米の 2 種の哺乳類の地理的分布をモデル化しました。また、種の分布を描画し、ROC 曲線の下の面積を計算してモデルの性能を評価する方法も学びました。