😃
ランダムフォレストアルゴリズム
フォレストツリーとは複数の決定木をつかって多数決的に分類や回帰の精度を向上させるアンサンブル学習のこと。
前回は決定木をやったが、今回はランダムフォレストという手法をやる。
とりあえず面倒なのでchatgpt先生に聞いてみる。
ランダムフォレスト(Random Forest)は、**複数の決定木**を使って予測を行う**アンサンブル学習法**です。基本的なアイデアは、単独の決定木ではなく、多くの決定木を作り、それぞれが個別に予測を行い、その予測を組み合わせて最終的な予測を得るというものです。
### 簡単な手順
1. **データのサンプリング**:元のデータセットからブートストラップ法(重複を許してランダムにサンプルを抽出)で複数のサブデータセットを作成します。
2. **決定木の構築**:各サブデータセットに対して決定木を構築します。各ノードの分岐に使う特徴量もランダムに選ばれます(通常は全特徴量の一部)。
3. **予測**:テストデータに対して、各決定木が予測を行います。
- **分類**の場合、多数決を取って最終的なクラスを決定します。
- **回帰**の場合、各木の予測値の平均を取ります。
### メリット
- **過学習の防止**:個々の決定木が過学習していても、複数の木の結果を組み合わせることで、過学習のリスクが低くなります。
- **頑健性**:データのノイズや欠損値に対して強いです。
- **重要な特徴量の評価**:どの特徴量が予測に重要かを知ることができます。
### デメリット
- **解釈が難しい**:単一の決定木と比べて、全体のモデルがブラックボックスになりがちです。
- **計算コスト**:多くの木を作るため、学習に時間がかかることがあります。
簡単に言えば、ランダムフォレストは「たくさんの決定木に同じ問題を解かせて、みんなの答えを集めて最も正しい答えを選ぶ」方法です。
まあとにかく複数の決定木を作り、その結果を多数決して一番多かった答えを真とするでおそらく間違いない。
主にアンサンブル学習という手法、ここではブートストラップ法というものを使う。
ブートストラップ法
ランダムにデータセットを抽出する。なお、ここでは重複を許してランダムにサンプルを抽出する。
PassengerId,Survived,Pclass,Name,Sex,Age,SibSp,Parch,Ticket,Fare,Cabin,Embarked
1,0,3,"Braund, Mr. Owen Harris",male,22,1,0,A/5 21171,7.25,,S
2,1,1,"Cumings, Mrs. John Bradley (Florence Briggs Thayer)",female,38,1,0,PC 17599,71.2833,C85,C
3,1,3,"Heikkinen, Miss. Laina",female,26,0,0,STON/O2. 3101282,7.925,,S
4,1,1,"Futrelle, Mrs. Jacques Heath (Lily May Peel)",female,35,1,0,113803,53.1,C123,S
5,0,3,"Allen, Mr. William Henry",male,35,0,0,373450,8.05,,S
6,0,3,"Moran, Mr. James",male,,0,0,330877,8.4583,,Q
7,0,1,"McCarthy, Mr. Timothy J",male,54,0,0,17463,51.8625,E46,S
8,0,3,"Palsson, Master. Gosta Leonard",male,2,3,1,349909,21.075,,S
9,1,3,"Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)",female,27,0,2,347742,11.1333,,S
10,1,2,"Nasser, Mrs. Nicholas (Adele Achem)",female,14,1,0,237736,30.0708,,C
11,1,3,"Sandstrom, Miss. Marguerite Rut",female,4,1,1,PP 9549,16.7,G6,S
12,1,1,"Bonnell, Miss. Elizabeth",female,58,0,0,113783,26.55,C103,S
13,0,3,"Saundercock, Mr. William Henry",male,20,0,0,A/5. 2151,8.05,,S
14,0,3,"Andersson, Mr. Anders Johan",male,39,1,5,347082,31.275,,S
15,0,3,"Vestrom, Miss. Hulda Amanda Adolfina",female,14,0,0,350406,7.8542,,S
16,1,2,"Hewlett, Mrs. (Mary D Kingcome) ",female,55,0,0,248706,16,,S
17,0,3,"Rice, Master. Eugene",male,2,4,1,382652,29.125,,Q
18,1,2,"Williams, Mr. Charles Eugene",male,,0,0,244373,13,,S
.
.
.
.
上記のデータからランダムに抽出する。
これを並列的におこない、学習させるのだ。
つまり簡単にいうと、ランダムフォレストとはバンキング(ブートストラップ)を利用して、ニュアンスの変わった決定木を沢山作成し、データを導く。
アルゴリズム。
1.データをランダムにサンプリング
元データからランダムにデータをブートストラップでサンプリングし、Nグループ分データグループを作る。
2.Nグループごとに決定木を作製する。
グループがN個存在するので、その中で決定木をN個分作る。
ちなみにpythonで実行すると、以下一文で100個の決定木が作られる。
rf_model=RandomForestClassifir(n_estimators=100,random_state=42)
3.N個つくられた木で学習させる
多数の木それぞれ学習させ答えをださせる、決定木は多数のため答えも多様なものになる。
以下は学習のコード
rf_model.fit(X_train, y_train)
Nグループの多数決(回帰は平均)を取り、最終予測を行う。
複数の決定木の結果を平均し、その結果を導く。
精度
以下、決定木アルゴリズム及びランダムフォレストアルゴリズムを実行した結果だ。
決定木
ランダムフォレスト
上記のようにランダムフォレストだと若干精度が高い、精度として80%とは結構なものではないだろうか。
まあ大体にして生存者を100の精度で予測するのは難しいのだろう。
以下に掲載。
決定木単体
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier,export_text, plot_tree
from sklearn.metrics import accuracy_score, classification_report,confusion_matrix
import matplotlib.pyplot as plt
# データの読み込み
url = 'https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv'
data = pd.read_csv(url)
# データの先頭を表示
print(data.head())
# 不要なカラムを削除
# 名前とか。
data = data.drop(['Name', 'Ticket', 'Cabin'], axis=1)
# 欠損値の処理(年齢の平均で埋める)
data['Age'].fillna(data['Age'].mean(), inplace=True)
# 性別を数値に変換
data['Sex'] = data['Sex'].map({'male': 0, 'female': 1})
# 目的変数と特徴量を設定
# 特徴量 = 説明変数 クラス 性別 年齢
X = data[['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare']]
# 目的変数=生存者
y = data['Survived']
# データの分割
# テストデータ=20パーセント
# 訓練データ=80パーセント
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# クラスの重みを設定
class_weights = {0: 1, 1: 2} # 非生存の重みを1、生存の重みを2に設定
# モデルの作成
model = DecisionTreeClassifier(random_state=42,class_weight='balanced')
# 学習する。
model.fit(X_train, y_train)
# 予測
y_pred = model.predict(X_test)
# 精度の表示
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy}')
print(classification_report(y_test, y_pred))
# ジニ不純度を用いた決定木のモデル
model_gini = DecisionTreeClassifier(criterion='gini', random_state=42)
model_gini.fit(X_train, y_train)
# エントロピーを用いた決定木のモデル
model_entropy = DecisionTreeClassifier(criterion='entropy', random_state=42)
model_entropy.fit(X_train, y_train)
# テストデータに対する予測
y_pred_gini = model_gini.predict(X_test)
y_pred_entropy = model_entropy.predict(X_test)
# 結果の表示
print("ジニ不純度を使用したモデルの評価:")
print(confusion_matrix(y_test, y_pred_gini))
print(classification_report(y_test, y_pred_gini))
print("エントロピーを使用したモデルの評価:")
print(confusion_matrix(y_test, y_pred_entropy))
print(classification_report(y_test, y_pred_entropy))
# 決定木の可視化
plt.figure(figsize=(20, 10))
plot_tree(model, filled=True, feature_names=X.columns, class_names=['Not Survived', 'Survived'])
plt.show()
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
# データの読み込み
url = 'https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv'
data = pd.read_csv(url)
# データの先頭を表示
print(data.head())
# 不要なカラムを削除
data = data.drop(['Name', 'Ticket', 'Cabin'], axis=1)
# 欠損値の処理
data['Age'] = data['Age'].fillna(data['Age'].median())
data['Embarked'] = data['Embarked'].fillna(data['Embarked'].mode()[0])
# 性別を数値に変換
data['Sex'] = data['Sex'].map({'male': 0, 'female': 1})
# 特徴量と目的変数の設定
X = data[['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare']]
y = data['Survived']
# データの分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# ランダムフォレストのモデルの作成
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)
# モデルの訓練
rf_model.fit(X_train, y_train)
# テストデータによる予測
y_pred = rf_model.predict(X_test)
# 精度の計算
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.2f}")
Discussion