はじめに
この実験では、Isolation Forest を使った異常検出のプロセスを学びます。まず、2 つのクラスタといくつかのアウトライアが含まれるデータセットを生成し、次に Isolation Forest モデルを学習してアウトライアを識別します。最後に、モデルの決定境界を可視化して、内包点とアウトライアをどのように分離するかを確認します。
VM のヒント
VM の起動が完了したら、左上隅をクリックしてNotebookタブに切り替え、Jupyter Notebook を使って練習しましょう。
Jupyter Notebook の読み込みには数秒かかる場合があります。Jupyter Notebook の制限により、操作の検証は自動化できません。
学習中に問題がある場合は、Labby にお問い合わせください。セッション後にフィードバックを提供してください。すぐに問題を解決いたします。
データ生成
2 つのクラスタといくつかのアウトライアが含まれるデータセットを生成します。クラスタは標準正規分布からの乱数サンプリングによって生成されます。そのうちの 1 つは球形で、もう 1 つはやや歪んだ形状になります。アウトライアは一様分布からの乱数サンプリングによって生成されます。
import numpy as np
from sklearn.model_selection import train_test_split
n_samples, n_outliers = 120, 40
rng = np.random.RandomState(0)
covariance = np.array([[0.5, -0.1], [0.7, 0.4]])
cluster_1 = 0.4 * rng.randn(n_samples, 2) @ covariance + np.array([2, 2]) ## 一般的な形状
cluster_2 = 0.3 * rng.randn(n_samples, 2) + np.array([-2, -2]) ## 球形
outliers = rng.uniform(low=-4, high=4, size=(n_outliers, 2))
X = np.concatenate([cluster_1, cluster_2, outliers])
y = np.concatenate(
[np.ones((2 * n_samples), dtype=int), -np.ones((n_outliers), dtype=int)]
)
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=42)
データセットの可視化
生成されたクラスタを可視化して、データセットがどのようなものかを確認します。
import matplotlib.pyplot as plt
scatter = plt.scatter(X[:, 0], X[:, 1], c=y, s=20, edgecolor="k")
handles, labels = scatter.legend_elements()
plt.axis("square")
plt.legend(handles=handles, labels=["outliers", "inliers"], title="true class")
plt.title("Gaussian inliers with \nuniformly distributed outliers")
plt.show()
モデルの学習
学習データを使って Isolation Forest モデルを学習します。
from sklearn.ensemble import IsolationForest
clf = IsolationForest(max_samples=100, random_state=0)
clf.fit(X_train)
離散的な決定境界を描画する
離散的な決定境界を可視化するために、DecisionBoundaryDisplayクラスを使用します。背景色は、その特定の領域内のサンプルがアウトライアと予測されるかどうかを表します。散布図は真のラベルを表示します。
import matplotlib.pyplot as plt
from sklearn.inspection import DecisionBoundaryDisplay
disp = DecisionBoundaryDisplay.from_estimator(
clf,
X,
response_method="predict",
alpha=0.5,
)
disp.ax_.scatter(X[:, 0], X[:, 1], c=y, s=20, edgecolor="k")
disp.ax_.set_title("Binary decision boundary \nof IsolationForest")
plt.axis("square")
plt.legend(handles=handles, labels=["outliers", "inliers"], title="true class")
plt.show()
パス長決定境界を描画する
response_method="decision_function" を設定することで、DecisionBoundaryDisplay の背景は、観測値の正規性の尺度を表します。このようなスコアは、ランダムな木の森全体で平均化されたパス長によって与えられ、それ自体は、特定のサンプルを分離するために必要な葉の深さ(または同じことである分割数)によって与えられます。
disp = DecisionBoundaryDisplay.from_estimator(
clf,
X,
response_method="decision_function",
alpha=0.5,
)
disp.ax_.scatter(X[:, 0], X[:, 1], c=y, s=20, edgecolor="k")
disp.ax_.set_title("Path length decision boundary \nof IsolationForest")
plt.axis("square")
plt.legend(handles=handles, labels=["outliers", "inliers"], title="true class")
plt.colorbar(disp.ax_.collections[1])
plt.show()
まとめ
この実験では、アノマリ検出に Isolation Forest をどのように使用するかを学びました。2 つのクラスタといくつかのアウトライアを含むデータセットを生成し、アウトライアを識別するために Isolation Forest モデルを学習し、モデルの決定境界を可視化して、それがインライアとアウトライアをどのように分離するかを確認しました。