はじめての決定木分析 | 基礎から実践まで初心者向けに解説

機械学習の入門で必ず登場するのが 決定木(Decision Tree)です。

決定木は直感的でわかりやすく、ビジネスでもよく使われる代表的なモデルです。

この記事では、次の内容をを初心者向けに解説します。

  • 決定木とは何か
  • どんな問題に向いているのか
  • データ準備から評価・改善までの実践フロー
  • 次に学ぶべき発展手法

決定木とは?

決定木(Decision Tree)とは、条件分岐を繰り返して答えにたどり着くモデルです。

  • 年齢は30歳未満?
  • 収入は500万円以上?
  • 過去に購入経験がある?

たとえば上記のような質問を順にたどって、最終的に「購入する / しない」といった判断を行います。

決定木の特徴

なぜそうなったかが視覚的にわかる

最大の強みは、分析プロセスが樹形図として可視化されることです。複雑な数式を知らなくても、「Aという条件を満たし、かつBであれば、結果はCになる」というロジックを誰でも直感的に理解できます。

前処理の手間が少ない

他の機械学習アルゴリズム(回帰分析やニューラルネットワークなど)に比べて、データの準備が楽です。

外れ値に強い

極端な数値があっても引きずられにくい。

データの種類を問わない

数値とカテゴリー(Yes/Noなど)を混ぜてそのまま投入できます。

ビジネス現場での意思決定に強い

精度だけでなく、説明責任が求められるビジネスシーン(銀行の融資審査、マーケティングのターゲット選定、離職予測など)では、ブラックボックス化しやすいAIよりも決定木の方が好まれることが多いです。

決定木の強みと弱み

強み(メリット)弱み(デメリット)
解釈が容易、非線形な関係も捉えられる、データの正規化が不要。過学習しやすく、予測精度が他の最新手法に劣る場合がある。

どんな場面で使われる?

決定木は次のような場面で活躍します。

  • 顧客の離脱予測
  • クレジット審査
  • 商品購入の予測
  • 医療診断支援
  • 不良品検知

なぜこの判断になったのか、を説明できる点がビジネス利用で特に重宝されます。

実践ワークフロー

ここからは、架空のECサイトデータを例に、問題設定 → 学習 → 評価 → 改善までを順番に見ていきます。

Step1. 問題設定

目的

顧客が商品を購入するかどうかを予測する。

目的変数(y)説明変数(X)
購入したか(0 / 1)年齢、閲覧回数、過去購入回数、収入 など

まずは、何を当てたいのかを明確にするのが重要です。

Step2. データ準備

この工程が実務では一番時間がかかります。

主に行うこと

  • 欠損値の確認と補完
  • カテゴリ変数の変換
  • 学習用・テスト用データの分割

(例) Python

import pandas as pd
from sklearn.model_selection import train_test_split

df = pd.read_csv("customer_data.csv")

# 欠損確認
print(df.isnull().sum())

# 欠損を平均で補完(例)
df["age"] = df["age"].fillna(df["age"].mean())

X = df.drop("purchase", axis=1)
y = df["purchase"]

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)
customer_data.csv は、複数特徴量を持つ次のような構造を想定
カラム名内容
age年齢35
income年収(万円など)520
page_views商品閲覧回数12
past_purchases過去購入回数3
gender性別(M / F)M
purchase今回購入したか(目的変数)1

※実務ではカテゴリ変数処理も必須です

Step3. 決定木モデルをつくる

まずはシンプルな決定木を学習させます。

from sklearn.tree import DecisionTreeClassifier

model = DecisionTreeClassifier(
    max_depth=4,
    random_state=42
)

model.fit(X_train, y_train)

ここでmax_depth(木の深さ)を制限するのがポイントです。

深くしすぎると訓練データを丸暗記してしまいます。

Step4. 予測と評価

from sklearn.metrics import accuracy_score, classification_report

y_pred = model.predict(X_test)

print("Accuracy:", accuracy_score(y_test, y_pred))
print(classification_report(y_test, y_pred))

ここで見るポイント

🔍 精度が極端に高すぎないか

🔍 Precision / Recall のバランス

🔍 クラスごとの性能差

Step5. 木を可視化する

決定木の最大の強みは、構造を図で見られることです。

import matplotlib.pyplot as plt
from sklearn.tree import plot_tree

plt.figure(figsize=(14, 8))
plot_tree(model,
          feature_names=X.columns,
          class_names=["No", "Yes"],
          filled=True)
plt.show()

最初に分岐している特徴量がもっとも重要な変数です。

Step6. 過学習を防ぐチューニング

決定木では次のパラメータを調整します。

パラメータ意味
max_depth木の最大の深さ
min_samples_leaf葉に必要な最小サンプル
min_samples_split分割に必要な最小数

チューニングの例(GridSearch)

from sklearn.model_selection import GridSearchCV

params = {
    "max_depth": [3, 4, 5, 6],
    "min_samples_leaf": [5, 10, 20]
}

grid = GridSearchCV(
    DecisionTreeClassifier(random_state=42),
    params,
    cv=5
)

grid.fit(X_train, y_train)

print("Best params:", grid.best_params_)

Q&A

数値特徴量はどう分割される?

年齢(age)や収入(income)のような数値データは、以下のような境界値を決定木アルゴリズムが自動で選びます。

  • 30歳未満 / 以上
  • 33.5歳以下 / 超
  • 47歳以下 / 超

すべての変数が2分割?

scikit-learnの決定木(CART方式)は必ず2分岐です。

なので各ノードでは必ずこのような形になります。

age <= 33.5 ?
   ├─ Yes
   └─ No

カテゴリ変数(性別など)は?

Genderが M / F のように2種類ならと以下のような形で分かれます。

gender_M <= 0.5 ?

3種類以上ある場合も、ダミー変数化された列を使って0/1で分岐します。

人が決めるのは何?

人が決めるのは、木の深さ制限(max_depth)・葉に必要な最小データ数・使う変数の選択です。

次のステップ | アンサンブル学習

現在では、単体の決定木だけでなく、複数の決定木を組み合わせる「アンサンブル学習」という手法が主流です。

Random Forest

たくさんの決定木を作って多数決をとります。

勾配ブースティング(XGBoost / LightGBM)

決定木のミスを次の決定木が修正していきます。

Random Forestの例

from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(
    n_estimators=200,
    max_depth=6,
    random_state=42
)

rf.fit(X_train, y_train)

まとめ

✔ 決定木は質問を重ねるモデル
✔ 可視化できて説明しやすいのが特徴
✔ 深さ制限が重要
✔ 評価指標で性能を必ず確認
✔ 次はアンサンブルへ進む

おすすめ