0Pricing
Learn AI with Python · レッスン

決定木:理論と実装

Gini 不純度、情報利得、木の深さ、過学習、sklearn DecisionTreeClassifier を扱います。

「決定木:理論と実装」はCoddyKit上の無料Learn AI with Pythonレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn AI with Python学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn AI with Pythonコースには全4レッスンが含まれています。

決定木とは

決定木は、特徴量の値に基づいてデータを分岐させ、葉ノードで予測に到達するまで、はい・いいえの質問を繰り返します。

各内部ノードは1つの特徴量を検査し、各分岐は結果を表し、各葉はクラスを割り当てます。決定の経路をたどれるため、決定木は解釈しやすいモデルです。

ジニ不純度

ジニ不純度は、ノード内でクラスがどの程度混在しているかを測定します。純粋なノード(すべて同じクラス)のジニ不純度は0です。

式は Gini = 1 - sum(p_i^2) です。ここで p_i はクラス i の割合を表します。決定木は、不純度を最も大きく減らす分割を選択します。

import numpy as np

def gini(labels):
    classes, counts = np.unique(labels, return_counts=True)
    probs = counts / counts.sum()
    return 1 - np.sum(probs ** 2)

print(gini([0, 0, 1, 1]))   # 0.5 (max mix)
print(gini([0, 0, 0, 0]))   # 0.0 (pure)

情報利得とエントロピー

別の分割基準として、エントロピーに基づく情報利得があります。エントロピーは -sum(p_i * log2(p_i)) です。

情報利得 = 親ノードのエントロピー - 子ノードの加重エントロピーです。ジニ不純度とエントロピーでは通常、似た決定木が生成されますが、ジニ不純度のほうが計算は少し高速です。

import numpy as np

def entropy(labels):
    _, counts = np.unique(labels, return_counts=True)
    p = counts / counts.sum()
    return -np.sum(p * np.log2(p))

print(entropy([0, 0, 1, 1]))   # 1.0
print(entropy([0, 0, 0, 1]))   # ~0.81

DecisionTreeClassifierの学習

Scikit-learnには DecisionTreeClassifier が用意されています。criterion パラメータ(giniまたはentropy)で分割基準を選択します。

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split

X, y = load_iris(return_X_y=True)
Xtr, Xte, ytr, yte = train_test_split(X, y, random_state=0)

clf = DecisionTreeClassifier(criterion="gini", random_state=0)
clf.fit(Xtr, ytr)
print("Accuracy:", clf.score(Xte, yte))

過学習とmax_depth

制約のない決定木は、すべての葉が純粋になるまで成長し、ノイズまで記憶してしまいます。これは過学習です。

max_depth パラメータは決定木の深さの上限を設定し、汎化を促します。深さを小さくするほど、モデルは単純になり、過学習も減少します。

from sklearn.tree import DecisionTreeClassifier

shallow = DecisionTreeClassifier(max_depth=3, random_state=0)
deep = DecisionTreeClassifier(max_depth=None, random_state=0)
# shallow generalizes better on unseen data;
# deep often overfits the training set

その他の事前枝刈りパラメータ

max_depth 以外にも、次のパラメータで成長を制御できます。

  • min_samples_split:ノードを分割するための最小サンプル数
  • min_samples_leaf:葉に含める最小サンプル数
  • max_leaf_nodes:葉の総数の上限

これらはすべて分散を減らし、過学習を防ぎます。

from sklearn.tree import DecisionTreeClassifier

clf = DecisionTreeClassifier(
    max_depth=5,
    min_samples_split=10,
    min_samples_leaf=5,
    random_state=0,
)

plot_treeで可視化する

plot_tree は決定木全体を描画するため、すべての分割、ジニ不純度、各ノードのクラス分布を確認できます。

import matplotlib.pyplot as plt
from sklearn.tree import plot_tree
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris

X, y = load_iris(return_X_y=True)
clf = DecisionTreeClassifier(max_depth=3).fit(X, y)

plt.figure(figsize=(12, 6))
plot_tree(clf, filled=True, feature_names=load_iris().feature_names)
plt.show()

特徴量の重要度

学習後の feature_importances_ から、すべての分割を通じて各特徴量が不純度をどれだけ減らしたかが分かります。値の合計は1.0です。

これは、モデルにとってどの入力が最も重要かをすばやく順位付けする方法です。

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris

data = load_iris()
clf = DecisionTreeClassifier(max_depth=3).fit(data.data, data.target)

for name, imp in zip(data.feature_names, clf.feature_importances_):
    print(f"{name}: {imp:.3f}")

コスト複雑度枝刈り(ccp_alpha)

事後枝刈りでは、決定木全体を成長させた後、弱い枝を切り取ります。ccp_alpha パラメータは枝刈りの強さを制御し、alphaが大きいほど多くのノードを削除します。

候補となるalphaを見つけるには、cost_complexity_pruning_path を使用します。

from sklearn.tree import DecisionTreeClassifier

base = DecisionTreeClassifier(random_state=0)
path = base.cost_complexity_pruning_path(Xtr, ytr)
alphas = path.ccp_alphas

pruned = DecisionTreeClassifier(ccp_alpha=0.01, random_state=0)
pruned.fit(Xtr, ytr)

最適なAlphaの選択

ccp_alpha を選ぶには、候補となるalphaごとに決定木を1つ学習させ、検証精度を比較します。最適なalphaは、精度と単純さのバランスを取ります。

from sklearn.tree import DecisionTreeClassifier

scores = []
for a in alphas:
    t = DecisionTreeClassifier(ccp_alpha=a, random_state=0)
    t.fit(Xtr, ytr)
    scores.append((a, t.score(Xte, yte)))

best = max(scores, key=lambda s: s[1])
print("Best alpha:", best[0])

長所と短所

長所:解釈しやすい、スケーリングが不要、非線形な境界を扱える、異なるデータ型を扱える。

短所:分散が大きい(データが少し変わるだけで決定木が変わる)、過学習しやすい、軸に沿った分割しかできない。これらの弱点が、ランダムフォレストのようなアンサンブル手法の動機になります。

クイックチェック

決定木の概念について理解度を確認します。

まとめ

まとめ:決定木は、ジニ不純度または情報利得を使用してデータを分割します。事前枝刈り(max_depth、min_samples_leaf)または事後枝刈り(ccp_alpha)で過学習を制御します。plot_tree と feature_importances_ でモデルを調べます。分散が大きいため、アンサンブル手法が有効です。

よくある質問

「決定木:理論と実装」レッスンは無料ですか?

はい。「決定木:理論と実装」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn AI with Pythonコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn AI with Pythonコースには全4レッスンが含まれています。

「決定木:理論と実装」で何を学びますか?

Gini 不純度、情報利得、木の深さ、過学習、sklearn DecisionTreeClassifier を扱います。 ブラウザで直接実行するハンズオンコードでLearn AI with Pythonを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Learn AI with Pythonを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLearn AI with Pythonは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「決定木:理論と実装」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLearn AI with Pythonレッスンでコードを書いて実行できますか?

はい。すべてのLearn AI with Pythonレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 決定木:理論と実装
  2. ランダムフォレストとバギング
  3. 勾配ブースティング:GBM と XGBoost
  4. LightGBM と CatBoost
← Learn AI with Pythonに戻る