【入門】Random Forest と Isolation Forest とは

Random Forest (ランダムフォレスト)Random Forest (ランダムフォレスト) とは、値を回帰(予測)、分類するアルゴリズムです。
Isolation Forest (分離フォレスト)Isolation Forest (分離フォレスト) とは、異常検出をするアルゴリズムです。
フォレスト (木 = 学習器の集まり)
Isolation Forest の学習器を作成
スポンサーリンク

初めに

本記事は Random Forest と Isolation Forest について記載しています。

機械学習に関連する他の記事は以下をご覧ください。

■機械学習のアルゴリズム

■ディープラーニング

スポンサーリンク

ランダムフォレストとは

Random Forest (ランダムフォレスト)Random Forest (ランダムフォレスト) とは、値を回帰(予測)、分類するアルゴリズムです。

ランダムフォレストとは、以下の2つのアルゴリズムを利用して、回帰(予測)、分類を行います。

決定木 (decision tree) とは

決定木 (decision tree)決定木 (decision tree) とは、データを分割した木構造のグラフです。(学習器として利用)
ゴルフを「する」・「しない」の2クラス (グループ) に分けた決定木

データを分割する基準は、特定のクラス (グループ)  を多く含むように分割します。

クラスは S サイズクラスと M サイズクラスの2つ

上記の場合、データを分割する基準は、「身長 > 165」の方がいいです。

これは、分割後のノードに1つのクラスが多く含まれているからです。

アンサンブル学習の種類

アンサンブル学習アンサンブル学習とは、複数の学習器 (決定木など) で予測精度を上げる学習方法です。

アンサンブル学習は、異なるデータから学習した学習器の方が予測精度が高くなります。
(同じ知識を持つ人だけで多数決をとると、同じ意見しか出ないので多数決の意味ない)

アンサンブル学習では、主に次の4つの手法があります。

バギング/ブートストラップ・アグリゲーティング

バギング/ブートストラップ・アグリゲーティングバギング/ブートストラップ・アグリゲーティングとは、データセットからランダムに n 個のデータをサンプリングして複数の学習器を作成する学習方法です。予測結果は分類であれば多数決、回帰であれば平均を採用します。

スタッキング

スタッキングスタッキングとは、学習器ごとに重みをつける方法です。

スタッキングは、バギングにおける出来の悪い学習器の結果も同じ重みで評価してしまう問題を解決するものです。

重要度の決め方は自由

バンピング

バンピングバンピングとは、複数の学習器から一番予測精度のいいものを選ぶ学習方法です。

バンピングは、外れ値で学習してしまった学習器を捨てることができます。

質の良いデータをサンプリングできた場合、良い学習器が作れる

ブースティング

ブースティングブースティングとは、以下の手順の学習方法です。
  1. データセットから学習器を作成
  2. 学習器で予測をし、間違えた予測に高い重みをつけ、1に戻る
予測結果は最後に作成した予測器を採用します。

ランダムフォレストのまとめ

Random Forest (ランダムフォレスト)Random Forest (ランダムフォレスト) とは、学習方法に「バギング」、学習器に「決定木」を使って、値を回帰(予測)、分類するアルゴリズムです。
サンプリングしたデータの全特徴量のうち、一部の特徴量だけを使って学習器を作ります
これは、異なるデータで学習した学習器を作るためです。(同じような学習器で予測しても同じ予測しか出力されないので多数決の意味がない)

ランダムフォレストの分類を Python + sklearn で実装

ランダムフォレストの分類を Python の sklearn ライブラリで実装してみます。

利用するデータセットは以下です。

sklearn.datasets.make_classification
Examples using sklearn.datasets.make_classification: Release Highlights for scikit-learn 1.3 Release Highlights for scikit-learn 0.24 Release Highlights for sci...

ソースコード

from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

# データセットを取得
X, y = make_classification(n_samples=1000, n_features=2, 
                        n_informative=2, n_redundant=0,
                        random_state=0, shuffle=False)

# データセットの特徴量Xと正解ラベルyを訓練データとテストデータに分ける
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=0) 
        
# ランダムフォレストで学習
clf = RandomForestClassifier(n_estimators=100, random_state=0).fit(X_train, y_train) 

print("予測精度=", clf.score(X_test, y_test)) #テスト用のデータを使って学習器の精度を測る
print("予測結果の詳細\n", clf.predict(X_test)==y_test) #予測結果の正誤を確認
予測精度= 0.956
予測結果の詳細
[ True  True  True  True  True  True  True  True  True  True  True  True
(中略)
  True  True  True  True  True  True  True  True  True  True]

予測精度が 95.6% の学習器が作れました。

学習結果を可視化

学習結果をよりわかりやすくするために、可視化してみます。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

# 予測の境界線をプロットし可視化
def plot_decision_boundary(model, X, y, margin=0.3): 
        _x1 = np.linspace(X[:, 0].min()-margin, X[:, 0].max()+margin, 100) # 0次元目の最小、最大の100分割
        _x2 = np.linspace(X[:, 1].min()-margin, X[:, 1].max()+margin, 100) # 1次元目の最小、最大の100分割
        x1, x2 = np.meshgrid(_x1, _x2)
        X_new = np.c_[x1.ravel(), x2.ravel()]
        y_pred = model.predict(X_new).reshape(x1.shape) # 予測結果
        custom_cmap = ListedColormap(['mediumblue', 'orangered']) # 色の指定
        plt.contourf(x1, x2, y_pred, alpha=0.3, cmap=custom_cmap) # 等高線で境界線を引く

# データセットを取得
X, y = make_classification(n_samples=1000, n_features=2, 
                        n_informative=2, n_redundant=0,
                        random_state=0, shuffle=False)

# データセットの特徴量Xと正解ラベルyを訓練データとテストデータに分ける
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=0) 
        
# ランダムフォレストで学習
clf = RandomForestClassifier(n_estimators=100, random_state=0).fit(X_train, y_train) 

plot_decision_boundary(clf, X, y) # 学習結果を可視化
plt.plot(X[:, 0][y==0], X[:, 1][y==0], 'bo', ms=10) # クラス0 のデータを可視化
plt.plot(X[:, 0][y==1], X[:, 1][y==1], "r^", ms=10) # クラス1 のデータを可視化

おおよそ分類できていることがわかります。

スポンサーリンク

Isolation Forest とは

Isolation Forest (分離フォレスト)Isolation Forest (分離フォレスト) とは、異常検出をするアルゴリズムです。

Isolation Forest では、以下の2つのアルゴリズムを利用して異常検出を行います。

Isolation Tree のアルゴリズム

Isolation Tree のアルゴリズムは以下のとおりです。

1. 分離するデータポイントを選択

2. ランダムに次元を選択 (今回は x 軸を選択)

3. 選択した次元の最小値〜最大値の範囲をランダムに選択

今回の場合は x 軸の 9 ~ 21 の間の値をランダムに選択

4. 分離するデータポイントが存在する領域を対象に、データポイントが1つ分離するまで手順2と3を繰り返す

(分離するデータポイントが存在しない領域は無視)

この領域を分割を、木構造で表したものが Isolation Tree です。

一番上のノードから、分離するデータポイントを持つノードの深さが浅いほど異常 (外れ値) であると判断します。

Isolation Tree を通常値に適用した例 (深さが深くなる)

例として、以下の異常 (外れ値) でないはなさそうデータポイントを対象に Isolation Tree を作成し、木が深くなることを確認します。

データポイントは以下のように分割できます。

つまり、Isolation Tree の深さは6となるので、先ほど示した深さ3の例と比較して、深さが深い (つまり正常値であると判断できます)。

Isolation Forest のまとめ

Isolation Forest (分離フォレスト)Isolation Forest (分離フォレスト) とは、学習方法に「バギング」、学習器に「Isolation Tree」を使って異常検出をするアルゴリズムです。

Isolation Forest を Python + sklearn で実装

Isolation Forest を Python の sklearn ライブラリで実装します。

利用するデータセットは以下です。

sklearn.datasets.make_moons
Examples using sklearn.datasets.make_moons: Classifier comparison Comparing different clustering algorithms on toy datasets Comparing different hierarchical lin...
from sklearn.ensemble import IsolationForest
from sklearn.datasets import make_moons

moons = make_moons(n_samples=200, noise=0.05, random_state=0) #学習データ
X_test = np.array([[1, -0.5],[2,1]]) # テスト用データ

# Isolation Forest で学習
clf = IsolationForest(n_estimators=100, random_state=0).fit(moons[0]) 

print("予測結果\n", clf.predict(X_test)) #1なら正常値、−1なら異常値
plt.plot(moons[0][:, 0], moons[0][:, 1],'o') # 学習用のデータを可視化
plt.plot(X_test[:,0], X_test[:,1], '*', ms=15) # テスト用データの可視化
予測結果
 [ 1 -1]

下側の☆が正常値 (1)、右上の☆が異常値 (-1) と判断できていることがわかります。

ランダムカットフォレスト (Random Cut Forest/RFC)

ランダムカットフォレストは Isolation Forest を適用したアルゴリズムです。

次元を選択する際に分散の大きい次元を選択します。(ランダムフォレストはランダムに次元を選択)

The Random Cut Forest (RCF, 2016) method [2] adapted Isolation Forest to work on data streams with bounded memory and lightweight compute.

p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 10.0px Helvetica}
https://opensearch.org/blog/odfe-updates/2019/11/real-time-anomaly-detection-in-open-distro-for-elasticsearch/

RRCF gives more weight to dimension with higher variance (according to SageMaker doc), while I think isolation forest samples at random,.....

https://stackoverflow.com/questions/63115867/isolation-forest-vs-robust-random-cut-forest-in-outlier-detection

もっと詳しく知りたい方は以下をどうぞ

https://proceedings.mlr.press/v48/guha16.pdf

機械学習の関連記事

■機械学習のアルゴリズム

■ディープラーニング


参考資料

Isolation Forest
Isolation forest is an unsupervised learning algorithm for anomaly detection.
sklearn.ensemble.RandomForestClassifier
Examples using sklearn.ensemble.RandomForestClassifier: Release Highlights for scikit-learn 1.4 Release Highlights for scikit-learn 0.24 Release Highlights for ...
sklearn.ensemble.IsolationForest
Examples using sklearn.ensemble.IsolationForest: IsolationForest example Comparing anomaly detection algorithms for outlier detection on toy datasets Evaluation...