アンサンブル学習のすゝめ

# はじめに
こんにちは！
僕は研究を行いながら、長期インターンでデータサイエンティストとして働く大学院生です！

学部時代から長期インターンを始め、現在まで４社経験してきました。
この経験から、プログラミングの学習を始めたばかりの人や、長期インターンを行う勇気が出ない人に、学習サポートやデータ分析の実績作り支援などを行わせてもらっています！

僕自身、プログラミングの習得や長期インターン探しに苦労したので、その経験をお伝えすることで、より多くの人が挫折せずデータサイエンティストになるまで成長して欲しいです！

以下でサポートを行なっているのでご興味ある方はご連絡ください！学生・社会人問わず専攻も問わずサポートいたします！

### X(Twitter)

https://twitter.com/DS_school_1

今回は<font color="red">実務</font>や<font color="red">Kaggle</font>で頻繁に利用されるアンサンブル学習について解説します！

# アンサンブル学習とは
アンサンブル学習は、複数の学習アルゴリズムを組み合わせることで、単一のアルゴリズムよりも優れた予測性能を達成する手法です。このアプローチは、バイアスやバリアンスのトレードオフを改善し、より堅牢なモデルを構築することを目指しています。

アンサンブル学習にはいくつかの重要な特徴があり、これらはデータサイエンスと機械学習の分野において大きな価値を持っています。

### 高精度
アンサンブル学習は、複数の決定木を組み合わせることによって、個々の決定木よりも高い精度を達成することができます。この高精度は、複数のモデルが異なる視点からデータを分析し、その予測を組み合わせることで実現されます。例えば、ランダムフォレストは複数の決定木から成り、各木の予測の平均を取ることで、個々の決定木に比べて過学習のリスクを軽減しつつ、予測の精度を向上させます。

### 過学習を防ぐ
アンサンブル学習の一般的な利点の一つは、過学習を防ぐ能力です。個々のモデルが特定のデータセットに過度に適応すること（過学習）を防ぐために、アンサンブル学習では複数のモデルの予測を組み合わせます。このプロセスにより、各モデルの予測のバリアンス（散らばり）を平均化し、より一般化されたモデルを作成することができます。特にバギング（例：ランダムフォレスト）やブースティング（例：XGBoost）の手法は、この特性を利用しています。

### 特徴量重要度の算出
アンサンブル学習モデル、特に決定木ベースのモデル（ランダムフォレスト、XGBoostなど）では、特徴量の重要度を算出することが可能です。これらのモデルは各特徴が予測にどれだけ寄与しているかを評価し、特徴量の重要度を提供します。これにより、どの特徴量が予測に最も影響を与えているかを理解することができ、モデルの解釈性と透明性が向上します。特徴量の重要度は、モデルの決定においてどの変数が最も重要かを知るための有用な指標となります。

# バギング
バギング（Bootstrap Aggregating）は、複数のモデルの予測を組み合わせることで、全体の分散を減らす技術です。これは、データセットからランダムにサブセットを取り出し（ブートストラップ）、各サブセットに対してモデルを訓練します。

<img width="400" alt="図1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584936/77f3ce1e-ca6a-586b-7014-f9e9d4dc9bfe.png">



## ランダムフォレスト
ランダムフォレストはバギングの一例で、多数の決定木を組み合わせたものです。アルゴリズムの概要は以下の通りです。

1. **ブートストラップサンプリング**を用いて、複数の訓練データセットを生成します。
1. 各訓練セットに対して決定木を構築します。ただし、各分割で全ての特徴ではなく、ランダムに選択した一部の特徴を用いることが一般的です。
1. すべての決定木の予測を集約して、最終的な予測を行います。
1. ランダムフォレストの基本モデルは次のように表されます：

```math
Y = f(X) + \epsilon
```

### ブートストラップサンプリング
ブートストラップサンプリングは、統計学における重要な手法の一つで、元のデータセットからランダムにサンプル（データ点）を選択し、新しいサブセットを作成するプロセスです。この選択は「置き換え」を伴います。つまり、同じデータ点が一つのサブセット内で複数回選択される可能性があります。

# ブースティング
ブースティングは、複数の弱学習器を順番に訓練し、それらを組み合わせて強い学習器を作る手法です。各ステップで、前の学習器が間違えたデータ点により多くの重みを付けることで、モデルの性能を徐々に向上させます。

ブースティングの反復的な学習プロセスは次のように表されます：

```math
F_t(x) = F_{t-1}(x) + \alpha_t h_t(x)
```

<img width="400" alt="図2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3584936/e56969a4-ee45-6bee-3b12-d64dc66bf4ff.png">

## XGBoost・LightGBM
XGBoostとLightGBMは、ブースティングに基づく高性能なアルゴリズムです。これらは特に大規模なデータセットに対して効果的で、高速な計算と優れた精度を提供します。

### XGBoost (eXtreme Gradient Boosting)
#### 特徴
+ **正則化**：XGBoostはモデルの複雑さを制御するためにL1およびL2正則化を導入します。これにより、過学習を防ぎ、モデルの一般化を向上させます。
+ **勾配ブースティング**：弱学習器（通常は決定木）を逐次的に追加し、前の学習器の誤差を修正していきます。各ステップでは、目的関数の勾配（損失関数の導関数）に沿って最適化を行います。
+ **スケーラブルなアーキテクチャ**：XGBoostは並列化と分散計算を効率的に行う設計になっており、大規模データセットに対しても高速な計算が可能です。
+ **欠損値の扱い**：XGBoostはデータセット内の欠損値を自動的に処理し、最適な分岐方法を学習します。

#### 数学的背景
XGBoostは以下の目的関数を最小化します：

```math
Obj = Σl(y_i, y_i') + ΣΩ(f_i)
```
ここで、$l$ は損失関数、$Ω$は正則化項、$f_i$はブースティングにおける弱学習器です。

### LightGBM (Light Gradient Boosting Machine)
#### 特徴
+ **GOSS (Gradient-based One-Side Sampling)**：LightGBMは勾配の小さいデータ点をランダムに間引くことで、計算効率を向上させます。重要なデータ点に焦点を当てることで、精度の低下を最小限に抑えながら計算速度を向上させます。
+ **EFB (Exclusive Feature Bundling)**：特徴量が多い場合に、互いに排他的な特徴をバンドルし、次元を削減します。これにより、計算コストを削減しつつ特徴量の多様性を維持します。
+ **軽量設計**：LightGBMはメモリ使用量と計算速度の点で非常に効率的です。これにより、比較的小さなコンピューティングリソースで高速な学習が可能になります。

#### 数学的背景
LightGBMは次の目的関数を最小化します：

```math
Obj = Σl(y_i, y_i') + ΣΩ(f_i)
```
XGBoostと同様に、ここでの$l$は損失関数、$Ω$は正則化項、$f_i$は弱学習器を表しますが、アルゴリズムの実装方法や最適化手法に違いがあります。

#### 対比
+ **速度とスケーラビリティ**：LightGBMはXGBoostに比べて、大規模データセットや高次元データに対して計算速度が速く、メモリ効率が良いです。
+ **精度**：両者とも高い精度を提供しますが、特定のデータセットや問題設定によっては一方が他方より優れた結果を示すことがあります。
+ **柔軟性と使いやすさ**：XGBoostはより細かいパラメータチューニングを提供し、多くの機械学習コンテストでの成功事例があります。一方、LightGBMは高速な計算が求められる場合に好まれます。


# 実装例
この章では、決定木、ランダムフォレスト、LightGBMを用いた実装例を紹介し、それぞれの精度を比較します。Pythonのscikit-learnライブラリとLightGBMライブラリを用いて、具体的なコードを示します。

```python
# 必要なライブラリをインポート
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
import lightgbm as lgb

# 乳がんデータセットの読み込み
data = load_breast_cancer()
X = data.data
y = data.target

# 訓練セットとテストセットに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 決定木のモデル
dt_classifier = DecisionTreeClassifier()
dt_classifier.fit(X_train, y_train)
dt_predictions = dt_classifier.predict_proba(X_test)[:, 1]
dt_auc = roc_auc_score(y_test, dt_predictions)

# ランダムフォレストのモデル
rf_classifier = RandomForestClassifier()
rf_classifier.fit(X_train, y_train)
rf_predictions = rf_classifier.predict_proba(X_test)[:, 1]
rf_auc = roc_auc_score(y_test, rf_predictions)

# LightGBMのモデル
lgb_classifier = lgb.LGBMClassifier()
lgb_classifier.fit(X_train, y_train)
lgb_predictions = lgb_classifier.predict_proba(X_test)[:, 1]
lgb_auc = roc_auc_score(y_test, lgb_predictions)

# AUCによる精度の比較
print(f"Decision Tree AUC: {dt_auc}")
print(f"Random Forest AUC: {rf_auc}")
print(f"LightGBM AUC: {lgb_auc}")

# Decision Tree AUC: 0.9253193580085163
# Random Forest AUC: 0.9950867998689813
# LightGBM AUC: 0.9934490664919751 
```

やはり、アンサンブル学習の精度は決定木モデルよりも良くなった。パラメータチューニングを行えば更なる精度向上が見込める。

# さいごに
最後まで読んでいただきありがとうございました！
少しでもデータサイエンティストを目指す方の一助となればと思います。

もし僕の活動にもご興味を持っていただけたら、X(Twitter)もフォローしていただけると嬉しいです！

X(Twitter)

https://twitter.com/DS_school_1

# 参考文献
+ **アンサンブル学習を超わかりやすく解説**
https://datawokagaku.com/ensemble/
+ **アンサンブル学習完全ガイド**
https://reinforz.co.jp/bizmedia/5832/
+ **アンサンブル学習の仕組み**
https://www.codexa.net/what-is-ensemble-learning/