こんにちは!ぼりたそです!
今回は機械学習アルゴリズムの一つであるランダムフォレストについてわかりやすく説明したいと思います。
この記事は以下のポイントでまとめています。
また、学習データとしてCSVファイルを入力するだけでランダムフォレスト回帰を実行するPythonコードも紹介してますので、ご興味ある方は以下の記事を参照ください。
それでは詳細に説明していきます。
ランダムフォレストとは?
まずはランダムフォレストとは何か?ということについてご紹介します。
ランダムフォレスととは、アンサンブル学習の一つで複数の決定木を構築して、各決定木の推定値の平均値(多数決)から予測する手法となります。
下の図にランダムフォレストの概略図を示しておりますが、まずデータセットから複数のデータセットに分割します(ブートストラップデータ)。
このデータから複数の決定木を構築し、各決定木ごとに推定値を算出します。その推定値の平均値(または多数決)から予測するという流れですね。
決定木については以下の記事にまとめてありますので、ご参照いただければと思います。
ランダムフォレストのメリット、デメリット
次にランダムフォレストのメリット、デメリットについて紹介します。
以下が具体的なメリット、デメリットになります。
■メリット
- 高い予測性能
ランダムフォレストは複数の決定木を組み合わせることで、単一の決定木よりも高い予測性能を持ちます。そのため、複雑な関係やノイズが含まれるデータに対しても強力なモデルを構築できます。
- 過学習の軽減
ブートストラップサンプリングとランダムな特徴の選択により、ランダムフォレストは比較的過学習しずらいです。
- 特徴の重要度の評価
ランダムフォレストは、決定木と同様に各特徴の重要度を評価することができます。予測モデルの安定性も高いので、重要度評価の信頼性も高いです。
次にデメリットについて以下に示します。
■デメリット
- 計算コストが高い
ランダムフォレストは数百程度の決定木を構築するため、その分計算コストが高いです。
- 過学習に対しては頑健だが、適切な調整が必要
過学習には比較的強いですが、やはり適切なハイパーパラメータの調整が必要です。特に、木の深さや木の数などを適切に設定することが重要です。
以上がランダムフォレストのメリット、デメリットになります。
きちんとデメリットを把握しつつ使用しましょう!
Pythonでの実行
それでは、実際にPythonにてランダムフォレストを実行してみたいと思います。
今回はある関数の回帰による予測を実行してみました。
条件は以下の通りです。
- 関数:変数8個からなる一次関数(2つの変数は係数を0に設定してあります)
- 決定木の数:50個
- 予測値:ランダムに生成した10個のデータ
from sklearn.metrics import r2_score
def run_random_forest():
# 修正されたダミーデータの生成
np.random.seed(40)
X = 10 * np.random.rand(100, 8) # 0から10の範囲で100個生成
y = 2 * X[:, 0] + 3 * X[:, 1] + 0 * X[:, 2] + 4 * X[:, 3] + 0 * X[:, 4] + 5 * X[:, 5] + 6 * X[:, 6] + 7 * X[:, 7] + np.random.randn(100)
# ランダムフォレストモデルの作成と学習
model = RandomForestRegressor(n_estimators=50, random_state=40)
model.fit(X, y)
# 予測データの生成(0から10の範囲に含まれる10点)
new_data = 10 * np.random.rand(10, 8)
predicted_values = model.predict(new_data)
# 実際の関数で計算した値
actual_values = 2 * new_data[:, 0] + 3 * new_data[:, 1] + 0 * new_data[:, 2] + 4 * new_data[:, 3] + 0 * new_data[:, 4] + 5 * new_data[:, 5] + 6 * new_data[:, 6] + 7 * new_data[:, 7]
# プロット
plt.scatter(predicted_values, actual_values, label='estimated_y vs actual_y', marker='o')
plt.xlabel('estimated_y')
plt.ylabel('actual_y')
plt.legend()
# R2値の計算と表示
r2 = r2_score(actual_values, predicted_values)
print(f"\nR2値: {r2}")
# 変数の重要度の表示
feature_importances = model.feature_importances_
print("\n変数の重要度:")
for i, importance in enumerate(feature_importances):
print(f"変数{i + 1}: {importance}")
if __name__ == "__main__":
run_random_forest()
#R2値: 0.7803982290284632
#変数の重要度:
#変数1: 0.07263404624483068
#変数2: 0.035408124359172184
#変数3: 0.021419053740529888
#変数4: 0.07561376445758594
#変数5: 0.017654683212067982
#変数6: 0.16925642086437118
#変数7: 0.1840405662624788
#変数8: 0.42397334085896343
予測データ10個について実際に計算した数値と比較してグラフにしました。対角線のような直線になっているので、なんとなくは予測できているのではないでしょうか。R^2値についても0.78なので低くはないと思います。
また、変数の重要度についても出力しましたが、係数が重くなるにつれて変数の重要度も大きくなっていますね。3番目と5番目の変数については係数を0にしてあるので重要度はきちんと低く出力されています。
以上がPythonを用いたランダムフォレストの実装になります。
終わりに
以上がランダムフォレストについての説明になります。機械学習の手法としてはよく使用されるものになりますので、ぜひ覚えたいですね。決定木だと少し信頼性に欠けるなと思う方は使ってみてください。