ランダムフォレストを実装してみよう!わかりやすく解説
【スマホからでも実行可能】ランダムフォレストの実装方法をPythonコード付きで丁寧に解説。機械学習のアンサンブル学習を実際に動かして理解を深めましょう。初心者にもわかりやすい実践ガイドです。
はじめに
ランダムフォレストは、機械学習の分野で非常に人気があり、強力なアルゴリズムの一つです。「森」という名前が示すように、たくさんの「木(決定木)」を使って、より精度の高い予測を目指します。分類問題(例えば、スパムメールかそうでないかを判断する)や回帰問題(例えば、家の価格を予測する)など、さまざまなタスクで優れた性能を発揮します。
この記事では、ランダムフォレストの基本的な考え方から、Pythonを使った具体的な実装方法まで、ステップバイステップで丁寧に解説していきます。専門的な知識がない方でも理解できるように、できるだけ専門用語を避け、やさしい言葉で説明することを心がけます。
記事の最後に、環境構築なしでスマホからでも即実行可能なGoogle Colabノートブックをご用意しています。 ぜひ、実際に手を動かしながら学んでみてください。
ランダムフォレストとは? もう少し詳しく
ランダムフォレストを理解する鍵は、「決定木」と「アンサンブル学習」という二つの考え方です。
決定木:判断のルールを木構造で表す
まず、「決定木」について考えてみましょう。決定木は、物事を判断するためのルールを、木の枝が分かれていくような形(木構造)で表現するものです。
例えば、「明日はピクニックに行くべきか?」を判断する決定木を考えてみます。
- 最初の質問:「天気は晴れですか?」
- はい → 次の質問へ
- いいえ → 「ピクニックには行かない」
- 次の質問(天気が晴れの場合):「最高気温は20度以上ですか?」
- はい → 「ピクニックに行く!」
- いいえ → 「ピクニックには行かない(少し寒いかも)」
このように、一連の質問とそれに対する答えをたどっていくことで、最終的な結論を導き出すのが決定木です。機械学習では、データから自動的にこのような判断ルール(木)を学習します。
しかし、決定木一本だけだと、その木が学習したデータに特化しすぎてしまい、新しいデータに対してうまく判断できないことがあります。これを「過学習(か学習)」と呼びます。一本の木の意見だけを鵜呑みにするようなイメージです。
アンサンブル学習:みんなの意見で賢く判断
そこで登場するのが「アンサンブル学習」という考え方です。これは、複数の学習モデル(この場合は複数の決定木)を組み合わせて、より強力なモデルを作る手法です。ランダムフォレストは、このアンサンブル学習の一種です。
ランダムフォレストでは、たくさんの決定木(森を構成する木々)をそれぞれ独立して作ります。そして、新しいデータについて予測を行う際には、森の中のそれぞれの木に「あなたならどう判断しますか?」と尋ね、その答えを集計して最終的な結論を出します。
例えば、分類問題であれば多数決、回帰問題であれば平均値を取ることが一般的です。多くの「専門家(決定木)」の意見を聞くことで、一人の専門家の偏った意見に左右されにくくなり、より安定して精度の高い判断ができるようになるのです。
ランダムフォレストの「ランダム」とは?
ランダムフォレストの「ランダム」という言葉には、主に二つの意味があります。
-
データのランダム性(ブートストラップサンプリング): 森を作る際、それぞれの決定木は、元の学習データ全体からランダムに一部のデータを選んで学習します。このとき、同じデータが複数回選ばれることも許容されます(復元抽出)。これにより、各決定木は少しずつ異なるデータセットで学習することになり、多様性が生まれます。
-
特徴量のランダム性: 決定木が枝分かれする際(つまり、新しい質問を考える際)、全ての利用可能な特徴量(データの項目、例えば「天気」「気温」「湿度」など)の中から、さらにランダムに選ばれた一部の特徴量だけを使って、最適な質問(分割のルール)を探します。これにより、特定の強い特徴量だけに依存しない、より多様な決定木が作られやすくなります。
これらの「ランダム性」が、個々の決定木の個性を際立たせ、森全体としての予測能力を高める秘訣です。
ランダムフォレストの仕組み:森はどうやって作られ、どうやって判断するの?
ランダムフォレストがどのようにして予測を行うのか、そのステップをもう少し具体的に見ていきましょう。
ステップ1:たくさんの木(決定木)を作る
-
データの準備: まず、学習に使用するデータセットを用意します。このデータには、予測したい結果(例えば、病気か否か、株価が上がるか下がるか)と、その結果を予測するための情報(例えば、検査結果の数値、過去の株価の動きなど)が含まれています。
-
木を育てるためのデータを選ぶ(ブートストラップサンプリング): 用意した学習データ全体から、ランダムにデータを選び出して、一本の決定木を育てるための小さなデータセットを作ります。このとき、元のデータセットと同じ数のデータを選びますが、一度選んだデータを元に戻してから次のデータを選ぶ(復元抽出)ため、同じデータが複数回選ばれたり、逆に一度も選ばれないデータが出てきたりします。これを、森に植える木の数だけ繰り返します。つまり、100本の木を作るなら、100個の小さな(でもちょっとずつ違う)データセットを作るイメージです。
-
それぞれの木を育てる(決定木の学習): ステップ2で作ったそれぞれの小さなデータセットを使って、一本一本の決定木を学習させます。木が枝分かれする(新しい判断ルールを作る)際には、さらに工夫があります。全ての判断材料(特徴量)を一度に考慮するのではなく、その中からランダムにいくつかを選び出し、その選ばれた材料の中だけで最適な判断ルールを見つけます。これにより、それぞれの木が異なる視点からデータを分析するようになり、多様性が生まれます。
このプロセスを繰り返して、たくさんの個性豊かな決定木(森)を作り上げます。
ステップ2:みんなで多数決(または平均)で予測する
新しいデータ(未知のデータ)が来たときに、ランダムフォレストがどのように予測するかを見てみましょう。
-
森の木々に意見を聞く: 新しいデータを、森の中の全ての決定木に入力します。それぞれの木は、自分が学習したルールに基づいて、その新しいデータに対する予測結果を出力します。
-
意見を集約する:
- 分類問題の場合(例:リンゴかオレンジか): 各木が出した予測(「これはリンゴだ」「いや、オレンジだ」)を集め、最も多くの木が予測したクラス(リンゴかオレンジか)を最終的な予測結果とします。これが「多数決」です。
- 回帰問題の場合(例:住宅価格の予測): 各木が出した予測値(「1000万円」「1050万円」「980万円」など)を集め、それらの平均値を最終的な予測結果とします。
このように、多くの木の意見を総合することで、一つの木の誤った判断や偏りを打ち消し、より信頼性の高い予測を得ることができます。
Pythonでランダムフォレストを実装してみよう
それでは、実際にPythonを使ってランダムフォレストを実装してみましょう。機械学習ライブラリであるscikit-learn(サイキットラーン)を使うと、比較的簡単にランダムフォレストを試すことができます。
ここでは、アヤメ(iris)の品種を分類する有名なデータセットを使って、ランダムフォレストの分類器を学習させ、その性能を評価する基本的な流れを紹介します。
必要なライブラリの準備
まず、scikit-learnと、数値計算のためのNumPy、データを扱うためのpandasをインストール(通常はAnacondaなどの環境に含まれています)し、インポートします。
# 必要なライブラリをインポート
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score
import pandas as pd
1. データの準備
scikit-learnに用意されているアヤメのデータセットを読み込みます。このデータセットには、アヤメのがく片の長さ・幅、花びらの長さ・幅という4つの特徴量と、アヤメの品種(Setosa, Versicolour, Virginicaの3種類)が含まれています。
# アヤメのデータセットを読み込む
iris = load_iris()
X = iris.data # 特徴量 (がく片の長さ・幅, 花びらの長さ・幅)
y = iris.target # 目的変数 (アヤメの品種)
# わかりやすいように特徴量の名前と品種名も確認しておきましょう
print("特徴量の名前:", iris.feature_names)
print("品種の名前:", iris.target_names)
# データをDataFrameに変換して少し見てみる (任意)
df = pd.DataFrame(data=X, columns=iris.feature_names)
df['species'] = y
print("\nデータの最初の5行:")
print(df.head())
2. 訓練データとテストデータに分割
モデルの性能を正しく評価するために、データを訓練用とテスト用に分割します。訓練用データでモデルを学習させ、テスト用データで未知のデータに対する予測能力を評価します。
train_test_split
関数を使います。test_size=0.3
は、全体の30%をテストデータとして使用することを意味します。random_state
は、分割の再現性を保つために指定するものです(同じ数値を使えば、何度実行しても同じように分割されます)。
# 訓練データとテストデータに分割 (訓練用70%, テスト用30%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42, stratify=y)
print("\n訓練データの特徴量の形状:", X_train.shape)
print("テストデータの特徴量の形状:", X_test.shape)
stratify=y
を指定することで、訓練データとテストデータのそれぞれで、元のデータにおける目的変数のクラスの比率が維持されるように分割されます。これは分類問題では特に重要です。
3. ランダムフォレストモデルの作成と学習
いよいよランダムフォレストモデルを作成し、訓練データで学習させます。
RandomForestClassifier
クラスのインスタンスを作成します。
主なパラメータには以下のようなものがあります。
n_estimators
: 森の中の決定木の数。多いほど性能が向上する傾向がありますが、計算時間も増えます。デフォルトは100です。max_features
: 個々の決定木が分割を行う際に考慮する特徴量の最大数。'sqrt'
(特徴量の総数の平方根)、'log2'
(特徴量の総数のlog2)、整数で指定、浮動小数点数で割合を指定、などがあります。None
の場合は全ての特徴量を使用します。デフォルトは'sqrt'
です。random_state
: モデルの再現性のために指定します。n_jobs
: 計算に使うCPUコアの数。-1
を指定すると、利用可能な全てのコアを使用します。データが大きい場合や木の本数が多い場合に効果的です。
# ランダムフォレスト分類器のインスタンスを作成
# n_estimators: 森を作る木の数
# random_state: 結果を再現可能にするためのシード値
# n_jobs: 並列処理に使用するプロセッサの数 (-1は全てのプロセッサを使用)
rf_classifier = RandomForestClassifier(n_estimators=100, random_state=42, n_jobs=-1)
# モデルを訓練データで学習させる
rf_classifier.fit(X_train, y_train)
print("\nランダムフォレストモデルの学習が完了しました。")
4. テストデータで予測
学習済みのモデルを使って、テストデータの品種を予測します。
# テストデータを使って予測を行う
y_pred = rf_classifier.predict(X_test)
print("\nテストデータに対する予測結果 (最初の10件):", y_pred[:10])
print("実際のテストデータの正解 (最初の10件):", y_test[:10])
5. モデルの評価
予測結果がどれくらい正しかったかを評価します。ここでは、正解率(Accuracy)を計算します。正解率は、全データのうち正しく分類できたデータの割合です。
# モデルの正解率を計算
accuracy = accuracy_score(y_test, y_pred)
print(f"\nモデルの正解率 (Accuracy): {accuracy:.4f}") # 小数点以下4桁まで表示
これで、ランダムフォレストの実装と評価の一連の流れが完了です。n_estimators
や max_depth
(木の深さの上限)などのパラメータを調整することで、さらに性能が変化することもあります。
おまけ:特徴量の重要度を見る
ランダムフォレストは、どの特徴量が予測にどれだけ貢献したか(特徴量の重要度)を知ることもできます。これは、モデルが何に着目して判断しているのかを理解する手がかりになります。
# 特徴量の重要度を取得
importances = rf_classifier.feature_importances_
# 特徴量の名前と重要度を合わせて表示
feature_importance_df = pd.DataFrame({'feature': iris.feature_names, 'importance': importances})
feature_importance_df = feature_importance_df.sort_values(by='importance', ascending=False)
print("\n特徴量の重要度:")
print(feature_importance_df)
この結果から、アヤメの品種分類にはどの特徴量(がく片の長さ、花びらの幅など)がより重要だったのかが分かります。
ランダムフォレストのメリット・デメリット
ランダムフォレストは強力な手法ですが、万能ではありません。主なメリットとデメリットを整理しておきましょう。
メリット
-
高い予測精度: 一般的に、単独の決定木や他の多くのアルゴリズムよりも高い予測精度を出すことが多いです。アンサンブル学習の効果により、安定した性能を発揮します。
-
過学習しにくい(ロバスト性が高い): 複数の決定木の結果を平均化(または多数決)するため、個々の木が訓練データに過剰に適合してしまう「過学習」という現象を抑える効果があります。これにより、未知のデータに対しても安定した性能を期待できます。
-
特徴量の重要度がわかる: どの特徴量が予測にどれだけ貢献しているかを評価する機能があります。これにより、モデルの解釈や、どのデータ項目が重要なのかを理解するのに役立ちます。
-
大規模なデータにも対応可能: 個々の決定木の学習は比較的独立して行えるため、並列処理との相性が良く、大規模なデータセットに対しても効率的に学習させることができます。
-
欠損値やスケールの異なる特徴量にも比較的強い: 決定木ベースの手法であるため、データのスケール(単位の違いなど)を事前に統一する前処理(標準化や正規化)が必須ではありません(ただし、行った方が性能が向上する場合もあります)。また、一部の欠損値に対しても比較的頑健に動作します。
-
パラメータ調整が比較的容易: いくつかの重要なパラメータ(木の数など)がありますが、デフォルトの設定でもある程度良好な性能を発揮することが多く、極端に複雑なパラメータチューニングを必要としない場合があります。
デメリット
-
計算コストが高い(学習に時間がかかることがある): 多数の決定木を生成し学習させるため、特に木の数が多い場合やデータセットが大きい場合には、学習に時間がかかったり、多くのメモリを消費したりすることがあります。
-
モデルの解釈が難しい(ブラックボックスになりやすい): 単独の決定木であれば、その判断ルールを人間が理解することは比較的容易です。しかし、ランダムフォレストは何百もの木の集合体であるため、最終的な予測が「なぜそうなったのか」を直感的に理解することは困難です。特徴量の重要度は分かりますが、具体的な判断プロセスは複雑です。
-
訓練データが非常に小さい場合には過学習のリスクも: 基本的には過学習しにくいアルゴリズムですが、訓練データが極端に小さい場合や、ノイズが非常に多い場合には、性能が十分に発揮されないことや、過学習の傾向を示すこともあり得ます。
-
回帰問題において、訓練データの範囲外の予測はできない: 回帰問題(数値を予測する問題)でランダムフォレストを使用する場合、予測値は訓練データ中の目的変数の値の平均や組み合わせで表現されるため、訓練データに含まれる目的変数の最大値を超える値や最小値を下回る値を予測することは原理的にできません。
これらのメリット・デメリットを理解した上で、問題の性質やデータの特性に合わせてランダムフォレストを活用することが重要です。
まとめ
今回は、ランダムフォレストという機械学習アルゴリズムについて、その基本的な考え方からPythonを用いた実践的な実装方法までを解説しました。
ランダムフォレストは、たくさんの「決定木」を集めて「森」を作り、それぞれの木の意見を総合することで、より賢く、より正確な判断を目指すアンサンブル学習の手法です。その「ランダム性」が、多様な木々を育て、過学習を防ぎ、高い汎化性能を実現する鍵となっています。
scikit-learnライブラリを使えば、比較的簡単にこの強力なアルゴリズムを試すことができます。データ分析や予測モデル構築の世界において、ランダムフォレストは非常に頼りになるツールの一つと言えるでしょう。
もちろん、ランダムフォレストが常に最良の選択肢とは限りません。データの特性や解決したい課題に応じて、他のアルゴリズムと比較検討することも重要です。しかし、その高い性能と使いやすさから、まず試してみる価値のある手法であることは間違いありません。
この記事が、皆さんのランダムフォレストへの理解を深め、実際に活用してみるきっかけとなれば幸いです。
ゲームで学ぶ探索アルゴリズム実践入門~木探索とメタヒューリスティクス
探索技術とそれを支えるアルゴリズムにフォーカスを当て、ゲームAIを題材にその重要性と魅力を楽しく学ぶための入門書です。
▶ Amazonで見る環境構築なしで
実行できるファイルはこちら!
このボタンからGoogle Colabを開き、すぐにコードをお試しいただけます。
関連する記事
エクストラツリー(ExtraTrees)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】この記事では、機械学習のアルゴリズムであるエクストラツリー(ExtraTrees)について、その仕組みからPythonによる実装方法までを丁寧に解説します。ランダムフォレストとの違いも理解しながら、実践的なスキルを身につけましょう。
勾配ブースティング木(Gradient Boosted Trees)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】勾配ブースティング木は、機械学習の分野で非常に強力な予測モデルの一つです。この記事では、その仕組みとPythonによる具体的な実装方法を、初心者にも分かりやすく解説します。実際にコードを動かしながら、この強力なアルゴリズムを体験してみましょう。
決定木(Decision Tree)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】決定木の実装方法をPythonコード付きでステップバイステップ解説。データの準備からモデル構築、可視化、評価、チューニングまで、実践的なスキルが身につきます。機械学習の基本である決定木をマスターしましょう。
粒子群最適化(PSO)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】粒子群最適化(PSO)のアルゴリズムをPythonで実装し、その仕組みを初心者にもわかりやすく解説します。最適化問題や機械学習に興味がある方におすすめです。パラメータ設定のコツや応用例も紹介し、実践的な理解を深めます。
サポートベクターマシン(SVM)を実装してみよう!わかりやすく解説
【スマホからでも実行可能】サポートベクターマシン(SVM)の実装方法を初心者にもわかりやすく解説。Pythonコード付きで、実際に手を動かしながらSVMの仕組みと使い方を学べます。機械学習の基礎を固めたい方、SVMを実践で使ってみたい方におすすめです。