Skip to content

第 8 章 ソースコード一覧

書籍第 8 章「木構造とアンサンブル学習」に掲載しているソースコードの一覧です。番号は書籍の「入力」番号と対応しています。上のバッジから、この章のコードをまとめた Google Colab ノートブックを開けます。

入力 8.1: 決定木によるIrisデータの分類

import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

# Irisデータセットの読み込み
df = sns.load_dataset("iris")
X = df.drop("species", axis=1)
y = df["species"]

# 訓練データとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

# 決定木の学習
tree_clf = DecisionTreeClassifier(max_depth=3, random_state=42)
tree_clf.fit(X_train, y_train)

# 予測と精度の評価
y_pred = tree_clf.predict(X_test)
print(f"正解率: {accuracy_score(y_test, y_pred):.4f}")

入力 8.2: plot_treeによる決定木の可視化

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

fig, ax = plt.subplots(figsize=(5.8, 4.3))
plot_tree(tree_clf,
          feature_names=X.columns.tolist(),
          class_names=tree_clf.classes_.tolist(),
          filled=True,
          rounded=True,
          fontsize=9,
          ax=ax)
plt.title("決定木(Iris, max_depth=3)")
plt.tight_layout()
plt.show()

入力 8.3: max_depthを変えた精度の比較

from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

for depth in [1, 2, 3, 5, 10, None]:
    clf = DecisionTreeClassifier(max_depth=depth, random_state=42)
    clf.fit(X_train, y_train)
    train_acc = accuracy_score(y_train, clf.predict(X_train))
    test_acc  = accuracy_score(y_test, clf.predict(X_test))
    print(f"max_depth={str(depth):>4s}  "
          f"訓練精度={train_acc:.4f}  テスト精度={test_acc:.4f}")

入力 8.4: 決定木とランダムフォレストの比較

import seaborn as sns
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

# ペンギンデータセットの読み込みと前処理
df = sns.load_dataset("penguins").dropna()
X = df[["bill_length_mm", "bill_depth_mm",
        "flipper_length_mm", "body_mass_g"]]
y = df["species"]

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42
)

# 単一の決定木
dt_clf = DecisionTreeClassifier(random_state=42)
dt_clf.fit(X_train, y_train)
dt_acc = accuracy_score(y_test, dt_clf.predict(X_test))

# ランダムフォレスト
rf_clf = RandomForestClassifier(n_estimators=100, random_state=42)
rf_clf.fit(X_train, y_train)
rf_acc = accuracy_score(y_test, rf_clf.predict(X_test))

print(f"決定木(単体)の正解率:       {dt_acc:.4f}")
print(f"ランダムフォレストの正解率:    {rf_acc:.4f}")

入力 8.5: 決定木の本数と正解率の関係

import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

n_trees_list = [1, 5, 10, 20, 50, 100, 200, 500]
test_scores = []

for n_trees in n_trees_list:
    clf = RandomForestClassifier(n_estimators=n_trees, random_state=42)
    clf.fit(X_train, y_train)
    test_scores.append(accuracy_score(y_test, clf.predict(X_test)))

plt.figure(figsize=(5.8, 2.9))
plt.plot(n_trees_list, test_scores, marker="o")
plt.xlabel("決定木の本数")
plt.ylabel("テスト正解率")
plt.title("ランダムフォレスト:木の本数と正解率")
plt.xscale("log")
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

入力 8.6: 勾配ブースティングによるペンギンの分類

from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import accuracy_score

# 勾配ブースティングの学習
gb_clf = GradientBoostingClassifier(
    n_estimators=100,
    learning_rate=0.1,
    max_depth=3,
    random_state=42
)
gb_clf.fit(X_train, y_train)

y_pred = gb_clf.predict(X_test)
print(f"勾配ブースティングの正解率: {accuracy_score(y_test, y_pred):.4f}")

入力 8.7: 学習率を変えた精度の比較

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import accuracy_score

# ノイズを含むやや難しい人工データを生成
# (flip_y=0.1 で約10%のサンプルのラベルをランダムに再割当て)
X2, y2 = make_classification(
    n_samples=500, n_features=10, n_informative=5,
    n_redundant=2, flip_y=0.1, random_state=42
)
X2_train, X2_test, y2_train, y2_test = train_test_split(
    X2, y2, test_size=0.3, random_state=42
)

learning_rates = [0.01, 0.05, 0.1, 0.2, 0.5, 1.0]
for lr in learning_rates:
    clf = GradientBoostingClassifier(
        n_estimators=100, learning_rate=lr,
        max_depth=3, random_state=42
    )
    clf.fit(X2_train, y2_train)
    train_acc = accuracy_score(y2_train, clf.predict(X2_train))
    test_acc = accuracy_score(y2_test, clf.predict(X2_test))
    print(f"learning_rate={lr}: "
          f"訓練 {train_acc:.4f}, テスト {test_acc:.4f}")

入力 8.8: 3つのモデルの特徴量の重要度の可視化

import numpy as np
import matplotlib.pyplot as plt

# 各モデルの学習(前節までに学習済みのものを再利用)
models = {
    "Decision Tree":      dt_clf,
    "Random Forest":      rf_clf,
    "Gradient Boosting":  gb_clf,
}

feature_names = X.columns.tolist()

fig, axes = plt.subplots(1, 3, figsize=(5.8, 1.7))

for ax, (name, model) in zip(axes, models.items()):
    importances = model.feature_importances_
    indices = np.argsort(importances)
    ax.barh(range(len(indices)),
            importances[indices], align="center")
    ax.set_yticks(range(len(indices)))
    ax.set_yticklabels([feature_names[i] for i in indices])
    ax.set_xlabel("重要度")
    ax.set_title(name)

plt.tight_layout()
plt.show()

入力 8.9: 特徴量の重要度の数値の確認

import pandas as pd

importance_df = pd.DataFrame({
    name: model.feature_importances_
    for name, model in models.items()
}, index=feature_names)

print(importance_df.round(4))