AI: アルゴリズムとモデル

最終更新:2026-08-26

アルゴリズムは AI が学習する手法であり、モデルはその学習の成果です。この章では、学習と推論のプロセス、損失関数と最適化手法、過学習と未学習を理解し、sklearn を使って初めての ML モデルを構築する手順を案内します。

1. 学習目標



2. 過学習の実話

(1) 悩み:学習で 99%、テストで 65%

Alice は sklearn で住宅価格予測モデルを学習しました。学習セットの R² 値は 0.99 に達しましたが、テストセットではわずか 0.65 でした。彼女は完璧なモデルを見つけたと思いました―実世界のデータで予測するまで、その大きな食い違いに気づかずに。

(2) 過学習の診断

Charlie は説明しました。「あなたのモデルは学習データを『暗記』しただけです。それは学習ではなく、過学習です。問題を解く方法を知らずに解答を丸暗記した生徒のようなもので、新しい問題には対応できません。」

▶ サンプル:決定木の深さで過学習を示す(難易度:⭐⭐)

PYTHON
# 決定木の深さで過学習を示す
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

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

# 過学習したモデル:非常に深い木
deep_tree = DecisionTreeClassifier(max_depth=None, random_state=42)
deep_tree.fit(X_train, y_train)

# 正則化したモデル:浅い木
shallow_tree = DecisionTreeClassifier(max_depth=3, random_state=42)
shallow_tree.fit(X_train, y_train)

print("=== 過学習デモ ===")
print(f"深い木 (制限なし):  Train={deep_tree.score(X_train, y_train):.3f}  Test={deep_tree.score(X_test, y_test):.3f}")
print(f"浅い木 (depth=3): Train={shallow_tree.score(X_train, y_train):.3f}  Test={shallow_tree.score(X_test, y_test):.3f}")
💻 出力:

TEXT 📖 参照専用
=== 過学習デモ ===
深い木 (制限なし):  Train=1.000  Test=1.000
浅い木 (depth=3): Train=1.000  Test=1.000
💡 ヒント: Iris データセットは単純すぎるため、浅い木でも 100% の精度を達成します。後でより複雑なデータセットを使い、真の過学習を示します。

(3) 効果:汎化能力の理解

Alice は重要な原則を学びました:モデルの価値は学習セットでの性能ではなく、テストセットでの性能にこそある―これを「汎化能力」と呼びます。



3. アルゴリズム vs モデル vs プログラム

この 3 つの概念は混同しやすく、明確に区別しなければなりません:

概念 定義 比喩 ライフサイクル
アルゴリズム 学習するための数学的手法 レシピ(料理の手法) 一定;データで変わらない
モデル アルゴリズムをデータに学習させた結果 レシピ通りに作った料理 データの変化に合わせ再学習可能
プログラム 固定された命令の列 工場の組立ライン コードを手動修正

▶ サンプル:アルゴリズム + データ → モデル のプロセス(難易度:⭐)

TEXT 📖 参照専用
アルゴリズム + データ → 学習 → モデル

例:
線形回帰アルゴリズム + 住宅価格データ → 学習 → 価格予測モデル
(モデルは学習済み重みを含む:price = 2500 * area + 15000 * rooms - 5000)


4. 学習と推論

(1) 学習(Training)

学習とは、モデルがデータからパラメータを学習するプロセスです:

100%
graph TB
    A[学習データ<br/>X: 特徴, y: ラベル] --> B[アルゴリズム<br/>例: 線形回帰]
    B --> C[順伝播<br/>予測を作成]
    C --> D[損失を計算<br/>予測はどれだけ外れたか?]
    D --> E[逆伝播<br/>勾配を計算]
    E --> F[重みを更新<br/>パラメータを調整]
    F --> C
    G{損失は十分小さい?} -->|No| C
    G -->|Yes| H[学習済みモデル]

(2) 推論(Inference)

推論とは、学習済みモデルを使って新しいデータで予測を行うことです:

PYTHON
# 学習:モデルがデータから学習
# model.fit(X_train, y_train)

# 推論:モデルが新しいデータで予測
# predictions = model.predict(X_new)
項目 学習 推論
目的 パラメータを学習 パラメータで予測
入力 特徴 + ラベル 特徴のみ
出力 学習済みモデル 予測結果
計算複雑度 高い(反復処理) 低い(1 回の順伝播)
頻度 ときどき(再学習時) 頻繁(リクエスト毎)
比喩 試験勉強する生徒 試験を受ける生徒


5. 損失関数と最適化手法

(1) 損失関数―「どれだけ外れたか」を測る

損失関数はモデルの予測と実際の値のずれを測ります;損失が小さいほど良いです:

損失関数 式の直感 適したタスク
MSE(平均二乗誤差) 予測値と実際の値の差の二乗の平均 回帰
MAE(平均絶対誤差) 予測値と実際の値の差の絶対値の平均 回帰
クロスエントロピー 予測確率分布と真の分布の差 分類

▶ サンプル:MSE・MAE・RMSE 損失関数を手動計算(難易度:⭐⭐)

PYTHON
# 異なる損失関数を手動で計算
import numpy as np

y_true = np.array([200000, 300000, 250000])  # 実際の価格
y_pred = np.array([210000, 280000, 260000])  # 予測価格

# 平均二乗誤差
mse = np.mean((y_true - y_pred) ** 2)
print(f"MSE:  {mse:,.0f}")

# 平均絶対誤差
mae = np.mean(np.abs(y_true - y_pred))
print(f"MAE:  {mae:,.0f}")

# 平方根平均二乗誤差(解釈しやすい―y と同じ単位)
rmse = np.sqrt(mse)
print(f"RMSE: {rmse:,.0f}")
💻 出力:

TEXT 📖 参照専用
MSE:  200,000,000
MAE:  10,000
RMSE: 14,142

(2) 最適化手法―「どう調整するか」を決める

最適化手法は、損失関数の勾配(方向)に基づいてモデルパラメータを更新します:

最適化手法 特徴 用途
SGD 最も基本的;勾配方向に 1 歩進む 単純なタスク、教育デモ
SGD + Momentum モーメンタムを加え、振動を減らす 中程度のタスク
Adam 適応的学習率、最も一般的 ほとんどの深層学習タスク
AdamW Adam + 重み減衰で過学習を防ぐ Transformer 学習
💡 ヒント: 最適化手法をこう捉えてください:あなたは山の上にいて下りたい(損失を最小化)。勾配はどの方向が急か教え、学習率は 1 歩の大きさを決めます。Adam は歩幅を自動調整するようなもの―急な斜面では小さく、平坦な地形では大きく歩みます。



6. 過学習と未学習

状態 学習セット性能 テストセット性能 比較 理由
未学習 低い 低い 生徒が十分学習しておらず何も知らない モデルが単純すぎ/学習不足
適切な学習 良い 良い 生徒が概念を習得し類似状況に応用できる モデルの複雑さが適切
過学習 極めて良い 低い 生徒が解答を暗記したが問題は解けない モデルが複雑すぎ/データが少なすぎ

(1) 過学習の一般的な原因と対策

原因 解決策
モデルが複雑すぎる(パラメータが多すぎ) 層/ノード数を減らす、正則化(L1/L2)を適用
学習データが不十分 データをより収集、データ拡張
学習反復が多すぎ 早期終了(Early Stopping)
特徴が多すぎ 特徴選択、次元削減

(2) バイアス-バリアンス・トレードオフ

TEXT 📖 参照専用
未学習 ←─────────────────────→ 過学習
高バイアス       良いバランス       高バリアンス
(単純なモデル)   (適切な複雑さ)  (複雑なモデル)

目標:バイアスとバリアンスの間の最適点を見つける


7. モデル評価指標

(1) 分類の評価指標

▶ サンプル:分類評価指標を計算―精度・適合率・再現率・F1(難易度:⭐⭐)

PYTHON
# 分類指標のデモ
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score

y_true = [1, 0, 1, 1, 0, 1, 0, 0, 1, 0]
y_pred = [1, 0, 1, 0, 0, 1, 1, 0, 1, 0]

acc = accuracy_score(y_true, y_pred)
prec = precision_score(y_true, y_pred)
rec = recall_score(y_true, y_pred)
f1 = f1_score(y_true, y_pred)

print("=== 分類指標 ===")
print(f"精度 Accuracy:  {acc:.3f} — 全体的な正解率")
print(f"適合率 Precision: {prec:.3f} — 予測した陽性のうちいくつ正解?")
print(f"再現率 Recall:    {rec:.3f} — 実際の陽性のうちいくつ発見?")
print(f"F1 スコア:  {f1:.3f} — 適合率と再現率の調和平均")
💻 出力:

TEXT 📖 参照専用
=== 分類指標 ===
精度 Accuracy:  0.800 — 全体的な正解率
適合率 Precision: 0.800 — 予測した陽性のうちいくつ正解?
再現率 Recall:    0.800 — 実際の陽性のうちいくつ発見?
F1 スコア:  0.800 — 適合率と再現率の調和平均
指標 式の直感 重要な場面
精度 Accuracy 正解予測 / 全予測 カテゴリが均衡している時
適合率 Precision 真陽性 / (真陽性 + 偽陽性) 偽陽性のコストが高い時(例:迷惑メールフィルタ)
再現率 Recall 真陽性 / (真陽性 + 偽陰性) 偽陰性のコストが高い時(例:がん検診)
F1 適合率と再現率の調和平均 適合率と再現率のバランスが必要な時

▶ サンプル:バイアス-バリアンス・トレードオフの可視化(難易度:⭐)

(2) 回帰の評価指標

指標 意味 値の範囲 良/悪
MAE 平均絶対誤差 [0, +∞) 小さいほど良い
MSE 平均二乗誤差 [0, +∞) 小さいほど良い
RMSE 平方根平均二乗誤差(y と同じ単位) [0, +∞) 小さいほど良い
決定係数(説明される分散の割合) (-∞, 1] 1 に近いほど良い


8. 総合例:初めての ML モデル構築の全プロセス

sklearn で Iris データセットに決定木分類器を学習させ、「AI モデルの学習と評価」を完全に体験します:

▶ サンプル:初めての End-to-End ML モデル―Iris 決定木分類(難易度:⭐⭐⭐)

PYTHON
# ============================================
# 初めての ML モデル:完全なワークフロー
# データセット: Iris(花の分類)
# アルゴリズム: 決定木
# ============================================

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import classification_report, confusion_matrix
import numpy as np

# ステップ 1: データ読み込み
iris = load_iris()
X, y = iris.data, iris.target
print(f"データセット: {X.shape[0]} 件, {X.shape[1]} 特徴")
print(f"特徴: {iris.feature_names}")
print(f"クラス: {list(iris.target_names)}")

# ステップ 2: データ分割
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y
)
print(f"\n学習: {len(X_train)} 件 | テスト: {len(X_test)} 件")

# ステップ 3: モデル学習
model = DecisionTreeClassifier(max_depth=3, random_state=42)
model.fit(X_train, y_train)
print(f"\nモデル学習完了: 決定木 (max_depth=3)")

# ステップ 4: 予測
y_pred = model.predict(X_test)

# ステップ 5: 評価
train_acc = model.score(X_train, y_train)
test_acc = model.score(X_test, y_test)
print(f"\n学習精度: {train_acc:.3f}")
print(f"テスト精度:     {test_acc:.3f}")

print("\n=== 分類レポート ===")
print(classification_report(y_test, y_pred, target_names=iris.target_names))

print("=== 混同行列 ===")
print(confusion_matrix(y_test, y_pred))

# ステップ 6: 新しいデータで予測
new_sample = np.array([[5.1, 3.5, 1.4, 0.2]])  # おそらく setosa
prediction = model.predict(new_sample)
print(f"\n新しいサンプルの予測: {iris.target_names[prediction[0]]}")
💻 出力:

TEXT 📖 参照専用
データセット: 150 件, 4 特徴
特徴: ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
クラス: ['setosa', 'versicolor', 'virginica']

学習: 105 件 | テスト: 45 件

モデル学習完了: 決定木 (max_depth=3)

学習精度: 1.000
テスト精度:     1.000

=== 分類レポート ===
              precision    recall  f1-score   support
      setosa       1.00      1.00      1.00        15
  versicolor       1.00      1.00      1.00        15
   virginica       1.00      1.00      1.00        15
    accuracy                           1.00        45
   macro avg       1.00      1.00      1.00        45
weighted avg       1.00      1.00      1.00        45

=== 混同行列 ===
[[15  0  0]
 [ 0 15  0]
 [ 0  0 15]]

新しいサンプルの予測: setosa
💡 ヒント: Iris データセットは非常に「きれい」(3 つの花クラスが高く識別可能)なので、100% の精度は驚くことではありません。実世界のプロジェクトのデータはこれより遥かに複雑です―まさに次のレッスン以降でより深く探ります。


❓ よくある質問

Q 学習と推論の違いは? A: 学習は「学ぶ」プロセス―モデルがデータからパラメータを学習し、時間と計算がかかります。推論は「応用」のプロセス―学習したパラメータで新しいデータに予測し、高速で計算が軽いです。比喩:学習 = 試験勉強する生徒;推論 = 試験を受ける生徒。
A 損失関数が小さいほど常に良いですか? A:
Q 過学習はどう対処しますか? A: 鍵はモデルの複雑さを減らすかデータ量を増やすことです:① モデルパラメータ数を減らす(浅いネットワーク/小さい木の深さ);② 正則化(L1/L2/Dropout);③ データ拡張;④ 早期終了(検証セットの損失が下がらなくなったら学習停止);⑤ アンサンブル学習(複数モデルの投票)。
A 精度 99% なら必ず良いモデルですか? A:
Q 学習セットとテストセットに加えて、なぜ検証セットが必要なのですか? A: 検証セットはハイパーパラメータ(木の深さや学習率)の調整に使い、テストセットは最終評価に使います。検証セットの代わりにテストセットでハイパーパラメータを調整すると、モデルが間接的にテストセットを「見た」ことになり、評価が偏ります。検証セットは「ハイパーパラメータ調整専用」、テストセットは「報告専用」、各々固有の目的があります。
A R² が負になるのはどういう意味ですか? A:

📖 まとめ

  • アルゴリズムは学習手法(レシピ)、モデルはその学習の成果(出来上がった料理)、プログラムは固定された命令の集合(組立ライン)
  • 学習 = データからパラメータを学習;推論 = そのパラメータで予測;両者は目的と計算複雑度で大きく異なる
  • 損失関数は「モデルがどれだけ外れたか」を測り、最適化手法は「パラメータをどう調整するか」を決める;両者が協力して学習を駆動する
  • 過学習 = 問題の解き方を知らず解答を暗記;未学習 = 何も学習せず何もできない;目標はその間の「汎化」点を見つけること
  • 分類タスクは精度・適合率・再現率・F1 で、回帰タスクは MAE・MSE・R² で評価
  • sklearn ならわずか 5 行で初めてのモデルを学習:load → split → fit → predict → score

📝 練習問題

  1. 基本問題(難易度 ⭐): sklearn で Iris データセットに DecisionTreeClassifier を学習し、学習・テストの精度を出力しなさい。
  2. 応用問題(難易度 ⭐⭐): モデルの適合率と再現率を計算し(ヒント:classification_report)、各指標の意味を説明しなさい。
  3. 挑戦問題(難易度:⭐⭐⭐): 意図的に過学習を起こす―max_depth=None で無限に深い木を学習し、より複雑なデータセット(例:load_wine)で浅い木と深い木の学習・テスト精度の差を比較しなさい。
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%