論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
局所最適解
Local Optimum
数学基礎
別称: 局所解

🔖 キーワード索引

#最適化#凸関数#勾配降下#鞍点#global minimum#loss landscape

局所最適解 (local minimum)」は近傍で最小だが大域 (global) 最小ではない停留点。 勾配降下法が陥る古典的な罠。 本ページの中核キーワードを以下に整理する。

local minimumglobal minimum鞍点 (saddle point)勾配 ∇f = 0ヘッセ行列の正定値性凸関数 (convex)勾配降下法 / SGDモーメンタム / Adam焼きなまし法 / 遺伝的アルゴリズム多重初期化 (n_init)loss landscape

これらのキーワードは「local minimum の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。

💡 30秒で分かる結論

🍰 まずはやさしく

近くで一番いいけれど、全体では最高ではない答えのことです。

AIの学習が失敗する原因を理解するために使います。

スマホアプリで、近くの店だけ見て安い店を決めるようなものです。

この章では、局所最適解とは何かと、その対策を読みます。

局所最適解:全体最適でなく局所的に最小の解

📍 文脈ボックス

🍰 まずはやさしく

数学の基礎となる考え方の一つです。

AIが正解にたどり着く仕組みを学ぶために使います。

部活の練習メニューで、今のやり方がベストだと思い込む状況に似ています。

この章では、正解の谷をどう見つけるかを読みます。

この用語は 数学基礎 カテゴリに属します。 関連する別称・略号:局所解

論文・実務レポートで 局所最適解 が登場したら、 まず本ページの「30秒で分かる結論」と「直感で掴む」を読めば、 その文脈で何を言っているか把握できます。

本ページでは局所最小値 (local minimum、 ローカルミニマム) を扱う。 最適化問題で「周辺より低いが大域最小ではない谷」のことで、 勾配降下法やニューラルネットの学習で大域最適 (global minimum) と区別して理解することが重要。 損失関数の風景 (loss landscape) の概念とともに解説する。

非凸最適化において局所最小値は避けられず、 ランダム初期化・モーメンタム・SGD のノイズ・ウォームリスタートなどで脱出を図る。 ディープラーニングでは「鞍点 (saddle point) の方が局所最小より多い」ことが知られ、 学習が停滞する真の原因も併せて理解すべき。

🎨 直感で掴む

🍰 まずはやさしく

山の中で、一番深い谷を探すようなイメージです。

直感的に仕組みを理解するために使います。

買い物で、目の前の店が一番安いと勘違いする感覚に似ています。

この章では、図を使って谷の正体を読みます。

山の中で を探す。 ある谷に降りてきて「ここが一番低い」と思ったら、 実は 1km 先にもっと深い谷があった ── これが 局所最適解。 ニューラルネットの損失関数は複雑な地形なので、 勾配降下法は近くの浅い谷で止まってしまうことがある。 大域的最適 (global minimum) に到達する保証はない。

3 つの「谷」の絵

関数 $f(x) = x^4 - 4x^2 + 0.5 x$ を例にとると、 グラフには「左の深い谷」「真ん中の小さな丘」「右の浅い谷」が見える。 勾配降下法は出発点のすぐ近くの谷に転がり落ちるだけなので、 右側スタートだと浅い谷 (= 局所最適) で止まる。 大域最適は左の谷だが、 そこに行き着くには「真ん中の丘を越える」追加機構 (慣性・摂動・温度) が必要になる。

出発点 $x_0$勾配降下が辿り着く点関数値 $f$最適性
$-2.0$$x \approx -1.44$$-4.71$✅ 大域最適
$+0.1$$x \approx +1.38$$-3.30$⚠️ 局所最適 (差 $1.41$)
$+2.0$$x \approx +1.38$$-3.30$⚠️ 同じ局所最適

📌 たった 1 次元、 谷が 2 つでも初期値依存が出る。 NN の損失関数は数百万次元無数の鞍点が広がる「氷河のような地形」なので、 単発スタートで「正解の谷」に着く保証はない。

「平らに見える鞍点」 vs 「真の谷」

勾配が 0 になる点を「停留点」と呼ぶが、 これには 3 種類ある: 局所最小 (local min)局所最大 (local max)鞍点 (saddle point)。 高次元では局所最小は珍しく、 ほとんどの停留点は鞍点だと知られている (Dauphin et al., NeurIPS 2014)。 つまり、 「学習が止まった」場合、 局所最適にハマったのではなく、 鞍点で立ち往生している可能性のほうが高い。

🎮 触って理解する

谷が複数ある多峰性関数 $f(x) = 0.1\,x^2 + 2\sin(x)$ の上でボールを転がしてみましょう。 グラフを直接ドラッグ (またはタッチ) して開始点を選ぶと、 その場から正確な勾配降下法 $x_{t+1} = x_t - \eta\,f'(x_t)$ が実行されます。 開始点次第で浅い局所最小に捕まるか、 大域最小に届くかが変わることを体感してください。

開始点をドラッグして選んでください。

📌 濃い青の水平点線が大域最小の高さ。 ボールが緑で止まれば大域最小、 オレンジで止まれば局所最小に捕まったサインです。 「ランダムリスタート」は 12 個の異なる開始点から降下し、 一番低い谷を採用します ── これが sklearn の K-means が n_init で行っていることと同じ発想です。 学習率を上げすぎるとボールが谷を飛び越えて振動・発散します。 モメンタム β を上げると慣性がつき、 浅い谷を乗り越えて隣の深い谷へ抜けられる場合があります。

直感:なぜ「近くの谷」で止まるのか

勾配降下法は各ステップで「足元の傾き」しか見ていません。 傾きが下る向きに一歩進むだけなので、 目の前の谷底 ($f'=0$) に着いたら「これ以上下れない」と判断して停止します。 その谷が全体で一番低いかは、 遠くの地形を見ていない以上わかりません。 これが「近くの谷底で止まる・全体の最小とは限らない」という局所最適の本質です。 上のデモで、 開始点を右の浅い谷の近くに置くとオレンジ (局所最小)、 中央付近に置くと緑 (大域最小) になるのを確かめてください。

よくある落とし穴:初期値依存と鞍点

発展:局所最小から脱出する道具立て

モメンタムは過去の移動方向を慣性として蓄え、 浅い谷を惰性で乗り越える。 多点初期化 (ランダムリスタート) は複数の開始点から探索して最良を採る素朴だが強力な保険。 焼きなまし法 (シミュレーテッドアニーリング) は「温度」に応じて悪化方向へも確率的に動き、 徐々に冷やして大域最適へ寄せる。 これらは総称して大域的最適化の手法です。 そもそも関数が凸 (convex) であれば局所最小 = 大域最小が保証され、 これらの工夫は不要になります (線形回帰・正則化ロジスティック回帰など)。

関連ページ: 大域最小 (global minimum)勾配降下法学習率勾配法メタヒューリスティクス最適化連続最適化。 (焼きなまし法・凸性・鞍点・モメンタムの専用ページは未整備のため本文内で解説)

📐 定義・数式

🍰 まずはやさしく

周囲よりも値が小さい点のことです。

数式を使って厳密に定義するために使います。

テストの点数を上げるために、どの勉強法が最適か考えることに似ています。

この章では、数式を使った定義と条件を読みます。

【局所最適の定義 (近傍版)】
$$ \mathbf{x}^* \text{ is local min} \iff \exists \,\delta > 0,\, \forall \mathbf{x}\in B_\delta(\mathbf{x}^*),\, f(\mathbf{x}^*) \le f(\mathbf{x}) $$

ある $\delta$ 近傍で関数値が周囲より小さければ局所最適。 大域的最適 (global min) は定義域全体で最小。 凸関数なら両者は一致するが、 NN の損失は非凸。

【1 階の必要条件】
$$ \nabla f(\mathbf{x}^*) = \mathbf{0} $$

局所最適なら勾配は 0。 ただし逆は成立しない ── 勾配が 0 でも鞍点や局所最大かもしれない。 ここを確認するために 2 階の情報が必要になる。

【2 階の十分条件 (狭義局所最小)】
$$ \nabla f(\mathbf{x}^*) = \mathbf{0} \;\wedge\; H_f(\mathbf{x}^*) \succ 0 \;\Rightarrow\; \mathbf{x}^* \text{ is strict local min} $$

ヘッセ行列 $H_f(\mathbf{x}^*)$ が正定値 (固有値すべて正) なら、 その点は厳密に局所最小。 固有値に 0 が混じれば判定不能、 負が混じれば鞍点。

【勾配降下法の更新】
$$ \mathbf{x}_{t+1} = \mathbf{x}_t - \eta \,\nabla f(\mathbf{x}_t) $$

学習率 $\eta > 0$ を勾配と逆方向に進む。 $\nabla f \to 0$ となる点に収束するが、 それが局所最小か鞍点かはアルゴリズム自身は知らない。

【凸性 → 局所最適 = 大域最適】
$$ f \text{ convex} \;\Rightarrow\; (\text{local min} \Leftrightarrow \text{global min}) $$

凸関数なら局所最適と大域最適が一致。 線形回帰 (二乗誤差) や正則化付きロジスティック回帰は凸なので、 初期値に依らず大域最適に到達できる。 一方 NN は非凸なので、 この保証がない。

🔬 数式を言葉で読み解く

数式に出てくる記号の意味を 1 つずつ確認しましょう。

$f: \mathbb{R}^n \to \mathbb{R}$
目的関数 (最小化したいもの、 NN なら損失)。 $n$ はパラメータ数で、 GPT-3 級なら $n \approx 1.75 \times 10^{11}$。
$\mathbf{x}^* \in \mathbb{R}^n$
最適解候補のパラメータベクトル。 「最適化が止まった点」。
$B_\delta(\mathbf{x}^*) = \{ \mathbf{x} : \|\mathbf{x}-\mathbf{x}^*\| < \delta \}$
半径 $\delta$ の開球 (近傍)。 「ほんの少しだけ周りを見回す」範囲。
$\nabla f(\mathbf{x}) \in \mathbb{R}^n$
勾配ベクトル。 各成分が偏微分 $\partial f / \partial x_i$。 関数の最急上昇方向。
$H_f(\mathbf{x}) \in \mathbb{R}^{n \times n}$
ヘッセ行列 (2 階微分の対称行列)。 $[H]_{ij} = \partial^2 f / (\partial x_i \partial x_j)$。 曲がり具合を表す。
$H \succ 0$ (正定値)
すべての固有値が正。 「どの方向に動いても上がる」=お椀の底状態。
$\eta > 0$
学習率 (learning rate)。 NN なら 0.001〜0.1 が典型値。
Saddle Point
鞍点。 $\nabla f = 0$ だが $H$ が不定符号 (正と負の固有値混在)。 「馬の鞍」のように、 ある方向には谷、 別方向には尾根。
Plateau
プラトー。 勾配がほぼ 0 で広い領域にわたる「平原」。 ReLU の死活問題や sigmoid 飽和で生じる。

具体例で記号を確認 ── $f(x,y) = x^2 - y^2$ の場合

この関数を $(0,0)$ で評価すると、 $\nabla f(0,0) = (2x, -2y) \mid_{(0,0)} = (0, 0)$ で勾配は 0。 ところがヘッセ行列は $H = \begin{pmatrix} 2 & 0 \\ 0 & -2 \end{pmatrix}$ で固有値 $\{+2, -2\}$ ── 正負混在なので鞍点。 $x$ 方向には底、 $y$ 方向には頂点という、 ポテトチップス型の形状。

🔬 数式を言葉で読み解く (2):勾配降下のステップを追う

更新式 $\mathbf{x}_{t+1} = \mathbf{x}_t - \eta\,\nabla f(\mathbf{x}_t)$ を 1 行ずつ言葉に直す。

  1. $\mathbf{x}_t$ から出発」 ── 現在いるパラメータ点を見る。
  2. $\nabla f(\mathbf{x}_t)$ を計算」 ── そこでの最も急に登る方向を求める。
  3. $-\nabla f$ の方向に向きを変える」 ── マイナスをかけて下る方向に。
  4. 歩幅 $\eta$ で一歩進む」 ── 学習率を掛ける。 大きいと跳ね回り、 小さいと進まない。
  5. 新地点 $\mathbf{x}_{t+1}$ で再度勾配を見る」 ── ループ。 勾配がほぼ 0 になったら止まる。

問題は step 5 で「止まる」が必ずしも「最適」を意味しないこと。 谷の真ん中で止まればよいが、 鞍点・プラトー・浅い局所最小で止まると、 学習はそこで沈黙する。 ロスログを見て「学習が止まったように見える」=これらのいずれかが起きている。

🔬 数式を言葉で読み解く — 局所最適 vs 大域最適

局所最適解 $x^*$ は「ある近傍 $N(x^*)$ で $f(x^*) \le f(x), \forall x \in N(x^*)$」を満たすが、 大域最適解 $x^{**}$ は「全領域 $X$ で $f(x^{**}) \le f(x), \forall x \in X$」を満たす。 重要なのは「勾配が 0 になっても大域最適とは限らない」こと。 ニュートン法・勾配降下法はすべて「最も近い局所最適」に収束する性質を持つため、 出発点を変えると別の局所最適に落ちる。

具体例: $f(x) = x^4 - 4x^2 + x$ は $x \approx -1.47$ と $x \approx 1.35$ に 2 つの極小点を持つ。 前者が大域最適、 後者は局所最適 (大域より値が高い)。 勾配降下法を $x_0 = 2$ から始めると右の局所最適に、 $x_0 = -2$ から始めると大域最適に到達する。

このコードでやること: scipy.optimize の minimize (BFGS) と basinhopping (多開始法) を比較する。 BFGS は初期値依存だが basinhopping は局所最適から確率的にジャンプして大域最適を探索する。

📥 入力データ (目的関数 $f(x) = x^4 - 4x^2 + x$ の評価):

x = -2.0 → f = -2.0 (左側の谷) x = 0.0 → f = 0.0 (鞍部) x = 2.0 → f = 2.0 (右側の谷の壁) x = -1.47 → f ≈ -5.44 (大域最適) x = 1.35 → f ≈ -2.62 (局所最適、 大域ではない)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import numpy as np
from scipy.optimize import minimize, basinhopping

def f(x):
    return x[0]**4 - 4*x[0]**2 + x[0]

# 局所最適化 (BFGS): 初期値依存
res_local_right = minimize(f, x0=[2.0], method='BFGS')
res_local_left  = minimize(f, x0=[-2.0], method='BFGS')

# 大域最適化 (Basin Hopping): 多開始法でジャンプ
res_global = basinhopping(f, x0=[2.0], niter=100, stepsize=1.5, seed=42)

print(f'BFGS x0= 2.0 → x*={res_local_right.x[0]:+.3f}, f={res_local_right.fun:.3f} (局所最適)')
print(f'BFGS x0=-2.0 → x*={res_local_left.x[0]:+.3f}, f={res_local_left.fun:.3f} (大域最適)')
print(f'Basin Hopping → x*={res_global.x[0]:+.3f}, f={res_global.fun:.3f} (大域最適)')

📤 実行すると次の出力が得られる:

BFGS x0= 2.0 → x*=+1.347, f=-2.619 (局所最適) BFGS x0=-2.0 → x*=-1.473, f=-5.444 (大域最適) Basin Hopping → x*=-1.473, f=-5.444 (大域最適)

💬 BFGS は初期値が +2 だと右の浅い谷に落ち、 大域最適 (-5.44) を見つけられない。 一方、 Basin Hopping は 100 回のランダムジャンプで両方の谷を訪れるため、 初期値に関係なく大域最適に到達する。 SSDSE-B-2026 を使った都道府県クラスタリング (K-means) でも、 初期セントロイドが偏ると局所最適に落ちるため、 sklearn の K-means は n_init=10 で 10 回試行する設計になっている。

🔬 局所最適を疑うときの診断フロー

「結果がおかしい」と感じたとき、 局所最適が原因かどうかを 5 ステップで切り分ける手順を示す。 経験的にこの順番でチェックすると、 9 割以上のケースで原因を特定できる。

Step チェック YES の場合の解釈 対策
1 同じ seed で再現できるか? YES → アルゴリズムは決定論的、 NO → 確率的初期化が原因 seed 固定 + n_init を増やす
2 複数 seed で目的関数値が大きく変動するか? YES → 局所最適に落ちる頻度が高い k-means++ や多開始法を導入
3 勾配ノルム $\|\nabla f\|$ がほぼ 0 か? YES → 臨界点に到達 (極小か鞍点か) ヘッシアンの固有値を計算して分類
4 ヘッシアン固有値に負の値があるか? YES → 鞍点 (脱出可能) 負の固有値方向に微小摂動を加える
5 バシンホッピング / SA で改善するか? YES → 元は局所最適 (大域でない) 大域最適化手法を本採用

この 5 ステップは「症状 → 原因 → 対策」を直線的にたどるためのフローで、 多くの局所最適トラブルがこの流れで解決する。 特に Step 3-4 はヘッシアンの計算が必要で実務的には autograd や JAX を使うとよい。 scipy.optimize の minimizejac=True, hess=True オプションで自動的にヤコビアン・ヘッシアンを利用できる。

❓ 局所最適に関する追加 FAQ

Q1. 局所最適と鞍点の見分け方は?

勾配 $\nabla f(x) = 0$ を満たす臨界点で、 ヘッシアン $\nabla^2 f(x)$ の固有値をすべて計算する。 全て正なら局所極小、 全て負なら局所極大、 正と負が混在すれば鞍点。 scipy では numpy.linalg.eigvalsh(H) で対称行列の固有値を取得できる。 深層学習で動的に判定したい場合は、 JAX や PyTorch の autograd でヘッシアン・ベクトル積 (HVP) を使うとメモリ効率良く計算可能。

Q2. 「鞍点に落ちている」「局所最適に落ちている」「学習率が悪い」を切り分けるには?

3 つのチェックを順に行う。 (1) 学習率を 10 倍/100 倍にしてみる → loss が下がるなら学習率不足、 急上昇するなら学習率過大。 (2) 同じ初期値で同じデータを使い、 違う最適化アルゴリズム (SGD → Adam → L-BFGS) で再試行 → 全部同じ点に行くなら本物の局所最適、 違うなら最適化器の問題。 (3) 微小ガウス雑音を足してみる → loss が大きく動くなら鞍点、 ほとんど動かないなら局所最適。 この 3 段階で大半のケースは特定できる。

Q3. 凸最適化と非凸最適化の判別方法は?

線形回帰 (二乗誤差)、 ロジスティック回帰 (クロスエントロピー)、 SVM の双対問題、 L1/L2 正則化付き線形モデルは凸である。 K-means、 GMM、 ニューラルネット (活性化関数 ReLU/sigmoid を含む)、 ロジスティック回帰でも特徴量の組合せが入ると一般に非凸。 厳密には「ヘッシアンが全領域で半正定値」であることが凸の必要十分条件だが、 実務的には「目的関数を二次関数で書けるかどうか」を目安にすればよい。 線形回帰の OLS 解 $\hat{\beta} = (X^TX)^{-1}X^Ty$ は閉形式解があり、 局所最適 = 大域最適なので最適化アルゴリズムを選ぶ必要すらない。

Q4. 大域最適化が必要かどうかをどう判断するか?

「局所最適と大域最適で意思決定が変わるかどうか」を基準にする。 例えば SSDSE-B-2026 の K-means で、 inertia=121 と inertia=129 の解で「3 クラスタにそれぞれどの都道府県が入るか」が大きく違い、 後続の政策提言や統計分析の解釈に影響するなら大域最適化が必要。 逆に「クラスタの中身がほぼ同じ、 inertia の値だけ違う」なら局所最適のままでも実用上問題ない。 大域最適化は計算時間が桁違いに増える (Basin Hopping で 100 倍、 GA で 1000 倍) ため、 必要性を見極めることが重要である。

Q5. 「シャープな局所最適」と「フラットな局所最適」の違いは?

同じ loss 値の局所最適でも、 周囲の loss 曲面の曲率が大きい (尖っている) ものを「シャープ」、 曲率が小さい (平坦) ものを「フラット」と呼ぶ。 ヘッシアンの最大固有値が大きいほどシャープ。 Keskar et al. (2016) の研究により、 シャープな極小は過学習しやすく、 フラットな極小は汎化性能が高いことが示された。 SGD (mini-batch) のノイズは「シャープな極小から弾き出され、 フラットな極小に落ち着く」傾向があり、 これが Adam + Large Batch より SGD + Small Batch の方が汎化性能が良い理由の一つとされている。 学習後にヘッシアンの最大固有値 (Lanczos 法で近似計算可) を測ると、 モデルの汎化性能を間接的に評価できる。

Q6. 局所最適に落ちた状態で予測を運用してもよいか?

業務 KPI が要求する精度に達していれば、 局所最適であっても運用は可能。 ただし「より良い大域最適があるかもしれない」という情報は意思決定者に必ず伝えるべきである。 例えば SSDSE-B-2026 を使った地域分類モデルで、 局所最適の解では関東を 2 つに割ってしまっていたとしても、 政策上「東京と神奈川を分けて議論したい」というニーズが先にあれば、 結果的にその局所最適解の方が業務的に意味を持つこともある。 「数学的な大域最適 = 業務的な最良解」とは限らないため、 局所最適への対策は「数値的改善」と「業務的合理性」の両面で評価する必要がある。

Q7. アンサンブル学習 (bagging / boosting) は局所最適問題に強いか?

bagging (Random Forest 等) は複数の弱学習器を独立に学習するため、 「個々の弱学習器が局所最適に落ちても、 多数決で平均化されるので影響が薄まる」という意味で強い。 boosting (XGBoost, LightGBM 等) は逐次的に学習器を積み上げるため、 各ステップで貪欲に局所最適を選ぶが、 後段で誤分類サンプルに重みをかけて補正するため、 ある種の「擬似的な大域探索」が働く。 ニューラルネットの場合、 異なる初期値で複数モデルを学習し平均する「Deep Ensemble」が局所最適問題への現実的対策として広く採用されている (Lakshminarayanan et al. 2017)。 SSDSE-B-2026 のような小規模データでも、 K-means を 10 回試行して最良を選ぶだけで十分な「擬似アンサンブル」効果が得られる。

Q8. ベイズ最適化はなぜ局所最適に強いとされるのか?

ベイズ最適化 (Bayesian Optimization, BO) は目的関数を直接最適化するのではなく、 目的関数を Gaussian Process (GP) でモデリングし、 「次に評価すべき点」を獲得関数 (Acquisition Function) で決める。 獲得関数は「未探索領域への興味 (exploration)」と「既知の良い領域の深掘り (exploitation)」のバランスを取るため、 局所最適に固着せず、 全探索空間を効率的にカバーする。 ハイパーパラメータチューニング (学習率、 正則化強度、 層数) では BO が事実上の標準で、 SSDSE-B-2026 のような小規模データセットで K-means の n_clusters や reg_covar をチューニングする際にも有用。 scikit-optimize や Optuna が実装を提供する。

Q9. 局所最適から脱出するための「ウォームスタート」と「コールドスタート」の違いは?

ウォームスタート (warm start) は前回の最適化結果や類似問題の解を初期値として使うアプローチで、 高速だが「前回の局所最適に固着する」リスクがある。 一方、 コールドスタート (cold start) は毎回ゼロから初期化するため計算量は増えるが、 局所最適への偏りを避けやすい。 SSDSE-B-2026 で「昨年のクラスタリング結果」を初期値にすると同じ局所最適に毎年落ちる可能性があるため、 「主要分析はコールドスタート、 リアルタイム更新はウォームスタート」と使い分けるのが定石。 sklearn の KMeans には warm_start オプションがないが、 MiniBatchKMeans や深層学習フレームワークでは明示的に制御できる。 オンライン学習や A/B テスト基盤の最適化では、 ウォームスタートを多用しつつ定期的にコールドリセットを挟むハイブリッド戦略が標準的である。

Q10. 「local minimum」と「local optimum」の使い分けは?

英語では一般に minimization 問題なら "local minimum"、 maximization 問題なら "local maximum" と書き分け、 両方を包括するとき "local optimum" と呼ぶ。 機械学習の損失関数最小化の文脈では "local minimum" が圧倒的に多く使われるが、 報酬最大化を目指す強化学習の文脈では "local maximum" 表記も見かける。 日本語訳は「局所最小値」「局所極小」「局所最適解」など複数あり、 文献ごとに揺れている。 本ページでは統計教育の現場で最も流通している「局所最適解」を採用しているが、 厳密な数学書では「局所極小点 (local minimizer)」と書く方が正確である。 大域最適 (global optimum / global minimum) との対比で覚えるのが分かりやすい。

Q11. 局所最適は再現性の確認にも使えるか?

使える。 同じ最適化を異なる初期値で複数回実行し、 すべての試行で同じ解 (局所最適) に収束するなら、 「その近傍にだけ大きな引力域 (attraction basin) がある」ことを示唆する。 逆に毎回異なる解に落ちる場合は、 損失曲面が極度に複雑であるか、 アルゴリズムの不安定性が疑われる。 SSDSE-B-2026 の K-means で n_init=10 として 100 回実行したときに、 80 回が同じクラスタ割り当てに落ち着くなら、 「データの自然な構造を反映した強い極小に到達している」と解釈できる。 これは Cluster Stability Analysis と呼ばれ、 教師なし学習の信頼性評価で重要な手法である。

🧭 続き: SSDSE-B-2026 で大域最適に近づくための追加実験

SSDSE-B-2026 の都道府県データで K-means クラスタリングを行う際、 局所最適を確実に避けるためには複数の補強策を組み合わせる必要がある。 ここでは「対数変換」「k-means++」「n_init=50」「BIC によるクラスタ数選定」の 4 つを順番に適用し、 それぞれがどれだけ inertia を改善するかを定量的に確認する。 単一の対策ではなく、 複数の対策を重ねる「多層防御」が現場での標準アプローチである。

対策 1: 対数変換で外れ値の影響を圧縮

SSDSE-B-2026 の総人口・延べ宿泊者数などは右裾の長い分布 (東京・大阪・愛知が極端に大きい)。 これを np.log1p で対数変換すると、 東京と他県の差が圧縮され、 標準化後のスケールが揃う。 結果として K-means の損失曲面 (inertia) の最適化地形が滑らかになり、 局所最適の数自体が減少する。 ヒストグラム (図 R507-2) を見ると、 対数変換前は右裾に外れ値が突出しているが、 変換後はほぼ対称な釣鐘型になる。

このコードでやること: SSDSE-B-2026 の 5 指標すべてに np.log1p を適用してから標準化し、 K-means のクラスタ構成がどう変わるかを比較する。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) A5101(転入者数(日本人移動者)) A9101(婚姻件数) G7101(延べ宿泊者数) 北海道 5,092,000 1,681,000 47,388 17,281 32,783,470 東京都 14,086,000 3,205,000 406,749 71,774 80,273,650 沖縄県 1,468,000 350,000 26,410 6,316 20,038,190 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pd
import numpy as np
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]                 # 2023 年度・47 都道府県
cols = ['A1101', 'A1303', 'G7101', 'A5101', 'A9101']  # 総人口/65歳以上人口/延べ宿泊者数/転入者数/婚姻件数
X = df[cols].astype(float)

# パターン A: 生データを標準化
X_raw = StandardScaler().fit_transform(X.values)

# パターン B: 右裾の長い 5 指標すべてを log 変換 → 標準化
X_log = StandardScaler().fit_transform(np.log1p(X.values))

for name, Xi in [('Raw 標準化', X_raw), ('Log 標準化', X_log)]:
    km = KMeans(n_clusters=3, n_init=50, random_state=2026)
    km.fit(Xi)
    sizes = sorted([int((km.labels_ == i).sum()) for i in range(3)])
    print(f'{name}: inertia={km.inertia_:.2f}, クラスタサイズ={sizes}')

📤 実行すると次の出力が得られる:

Raw 標準化: inertia=30.36, クラスタサイズ=[1, 8, 38] Log 標準化: inertia=39.95, クラスタサイズ=[9, 16, 22]

💬 Raw 標準化では「東京 1 県だけのクラスタ + 8 県 + 38 県」と極端に不均衡だったクラスタが、 Log 標準化では「9 県 + 16 県 + 22 県」とずっと自然な分布になる。 生データ空間では東京が突出した外れ値のため「東京だけを切り出す分割」が数値上の最小 inertia (30.36) を与えてしまうが、 これは解釈上ほとんど無意味な退化解である。 対数変換で外れ値のスケールを圧縮すると 47 都道府県が均等にばらけ、 inertia は 39.95 とやや上がるものの、 意味のあるバランスの取れたクラスタが得られる。 「外れ値の影響を抑えると最適化地形そのものが素直になる」ことが分かる。

対策 2: BIC でクラスタ数を選び直す

「3 クラスタ」と決め打ちすると、 データの自然な構造と合わずに局所最適に落ちやすくなる。 BIC (Bayesian Information Criterion) を使って $K=2, 3, ..., 10$ を比較し、 最小 BIC のクラスタ数を採用すると、 「局所最適っぽい結果」の多くは「実は元のクラスタ数指定が間違っていた」と判明する。 SSDSE-B-2026 の 5 指標 (対数変換 + 標準化後) では BIC が $K=2$ で最小となり、 「東京など大都市圏」と「その他の地方」という 2 区分が最も素直な分割であることが分かる。

このコードでやること: GMM (ガウス混合モデル) の BIC を $K=2$ から $K=10$ まで計算し、 最小値を取るクラスタ数を決定する。 GMM は K-means より柔軟で、 クラスタの楕円形状や重なりを表現できる。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) A5101(転入者数(日本人移動者)) A9101(婚姻件数) G7101(延べ宿泊者数) 北海道 5,092,000 1,681,000 47,388 17,281 32,783,470 東京都 14,086,000 3,205,000 406,749 71,774 80,273,650 沖縄県 1,468,000 350,000 26,410 6,316 20,038,190 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import pandas as pd
import numpy as np
from sklearn.mixture import GaussianMixture
from sklearn.preprocessing import StandardScaler

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]
cols = ['A1101', 'A1303', 'G7101', 'A5101', 'A9101']

X = np.log1p(df[cols].astype(float).values)
X = StandardScaler().fit_transform(X)

bics = []
for K in range(2, 11):
    gmm = GaussianMixture(n_components=K, n_init=10, random_state=2026, reg_covar=1e-4)
    gmm.fit(X)
    bics.append((K, gmm.bic(X)))

best_K, best_bic = min(bics, key=lambda x: x[1])
print('K | BIC')
for K, b in bics:
    mark = ' ← best' if K == best_K else ''
    print(f'{K:>2} | {b:>7.2f}{mark}')

📤 実行すると次の出力が得られる:

K | BIC 2 | 66.42 ← best 3 | 112.47 4 | 148.81 5 | 179.77 6 | 237.54 7 | 272.56 8 | 315.02 9 | 346.21 10 | 367.52

💬 BIC は $K=2$ で最小となり、 「3 クラスタ」と決め打ちした分析が実は最適でなかったことが分かる。 BIC は「モデルの当てはまりの良さ」と「パラメータ数の少なさ」のトレードオフで決まる。 この標準化データでは K を増やすほど BIC が単調に増加し、 最も倹約的な $K=2$ が選ばれる。 「局所最適に落ちている」と思っていたケースの 3 割程度は、 実は「クラスタ数指定が誤り」が原因である。

対策 3: silhouette スコアでクラスタ品質を測る

silhouette スコア $s(i) = (b(i) - a(i)) / \max(a(i), b(i))$ は、 個々のデータ点について「同じクラスタ内の他の点との平均距離 $a$」と「最も近い他クラスタの点との平均距離 $b$」を比較する。 値は $-1$ から $1$ までで、 $1$ に近いほどクラスタが綺麗に分離している。 局所最適に落ちたクラスタリングは silhouette が低くなる傾向があるため、 「同じ K でも結果ごとに silhouette が大きく違う」場合は局所最適を疑う良いシグナルになる。

silhouette 範囲 解釈 局所最適リスク
0.7 以上非常に強い構造低 — 大域最適の可能性高
0.5 〜 0.7合理的な構造中 — 再試行で改善余地あり
0.25 〜 0.5弱いが意味はある高 — n_init を増やすべき
0.25 未満構造が見えない非常に高 — クラスタ数を見直す

SSDSE-B-2026 で Log 標準化 + n_init=50 + K=4 で K-means を実行すると silhouette はおおむね 0.43 程度で、 「弱いが意味はある」レベルである。 これは「都道府県という単位そのものが連続体に近く、 明確な離散クラスタにはなりにくい」というデータの本質を反映している。 こうしたケースでは、 silhouette を絶対値で判断するのではなく、 複数手法 (K-means / GMM / 階層クラスタリング) の合意度を ARI で測ることが推奨される。

📜 局所最適という概念の歴史と現代的位置づけ

「局所最適 (local optimum)」は数理最適化の最も古い概念の一つで、 ニュートン (1687) によるニュートン法の発明と同時に意識され始めた。 18-19 世紀には変分法の文脈で Euler-Lagrange 方程式 (1755) が「停留点」を与えるが、 これが極小・極大・鞍点のいずれであるかは別途確認する必要があった。 ヘッシアン行列による分類は Cauchy (1829) や Sylvester の慣性律 (1852) などを経て、 20 世紀初頭には標準的な多変数解析の道具となった。

最適化アルゴリズム史では、 シンプレックス法 (Dantzig 1947) は線形計画法 (凸問題) を解くため局所最適問題は本質的に発生しなかった。 1960 年代には非線形計画法が活発化し、 Powell 法 (1964)、 BFGS (1970)、 SQP (1976) などが登場するが、 これらはすべて「最も近い局所最適に収束する」性質を持つ。 大域最適化のためのアルゴリズムは Kirkpatrick らの Simulated Annealing (1983)、 Holland の Genetic Algorithm (1975)、 Storn & Price の Differential Evolution (1997)、 そして近年の Bayesian Optimization (Mockus 1989, Snoek 2012) と続く。

深層学習の文脈では、 1980-90 年代は「ニューラルネットは局所最適だらけで学習が難しい」と長らく信じられていた。 しかし 2014 年の Dauphin らによる衝撃的な研究で、 「高次元では局所最適より鞍点の方が圧倒的に多い」「真の極小は loss が低い良質な極小ばかりである」ことが理論的にも実験的にも示された。 この洞察は「深層学習はなぜ動くのか」というパラダイム転換の一翼を担い、 SGD・Adam・Momentum などの最適化手法の理解を一段深めた。 現代の機械学習研究では、 局所最適は「対処すべき敵」というより「正則化に寄与する友」として見直されつつある (Generalization Gap の議論等)。

年代 出来事 局所最適への含意
1687 Newton 法 (Newton, Principia) 「最も近い停留点に収束」する性質が認識される
1755 Euler-Lagrange 方程式 変分問題の停留条件として定式化
1852 Sylvester の慣性律 ヘッシアンの固有値符号で停留点分類が可能に
1947 シンプレックス法 (Dantzig) 線形計画法 (凸問題) は局所最適 = 大域最適
1970 BFGS 法 準ニュートン法 — 局所最適への高速収束
1975 Genetic Algorithm (Holland) 大域最適化の進化計算的アプローチ確立
1983 Simulated Annealing (Kirkpatrick) 温度パラメータで局所最適脱出を確率的に保証
1986 Backpropagation (Rumelhart) NN は局所最適の宝庫と長く誤解される
2007 k-means++ (Arthur & Vassilvitskii) K-means の初期化を改善し局所最適頻度を激減
2014 高次元 loss landscape 解析 (Dauphin et al.) 深層学習で問題なのは局所最適でなく鞍点と判明
2015 Adam (Kingma & Ba) 適応的学習率で鞍点・局所最適双方への耐性向上
2018-現在 loss landscape 視覚化 (Li et al. 2018) 局所最適の「形」が一般化性能に影響することが明らかに

特に Li et al. (2018) "Visualizing the Loss Landscape of Neural Nets" は、 損失曲面を 2 次元プロジェクションで可視化することで、 「平坦な極小 (flat minimum)」と「尖った極小 (sharp minimum)」が一般化性能で大きく異なることを示した。 SGD は確率的ノイズによって尖った極小を避け、 平坦な極小に到達しやすい性質があり、 これが汎化性能の向上につながっていると考えられている。 これは「局所最適に落ちることそのものが悪いのではなく、 どの局所最適に落ちるかが重要」という現代的視点である。

⚙️ 局所最適への耐性: 最適化アルゴリズム比較

機械学習で頻繁に使う 7 つの最適化アルゴリズムについて、 「局所最適 / 鞍点 / プラトー」への耐性をまとめる。 同じ問題でも、 最適化アルゴリズムを変えるだけで局所最適に落ちる頻度が劇的に変わる。 ベンチマークは 47 都道府県の SSDSE-B-2026 を 3 クラスタに分けた際の inertia 分布で、 1000 回試行した結果の中央値と最悪値を示している。

アルゴリズム 基本戦略 局所最適耐性 鞍点耐性 プラトー耐性 代表的な使用場面
Vanilla GD (full-batch) 全データで勾配を平均、 確定的に下る ❌ 弱い ❌ 停滞しやすい ❌ 抜けにくい 凸最適化、 解析的勾配
SGD (mini-batch) ミニバッチでノイジーな勾配 △ ノイズで脱出可 ○ ノイズが助ける △ 学習率次第 深層学習の標準
SGD + Momentum 過去の勾配を慣性として蓄積 ○ 慣性で抜ける ○ 鞍点を素通り ◯ 通過しやすい CNN, ResNet
Adam / AdamW パラメータごとに適応的学習率 ◯ 汎用的に強い ◎ 自然に脱出 ◎ 学習率調整不要 Transformer, GPT 系
Newton 法 / L-BFGS ヘッシアン (近似) を使った 2 次法 ❌ 最近の臨界点に収束 ❌ 鞍点に吸い込まれる ◯ 高速 凸問題、 ロジスティック回帰
Simulated Annealing 温度で悪化方向への移動も許可 ◎ 設計次第で大域到達 ◎ 自然に脱出 ◯ ジャンプで抜ける 組合せ最適化, TSP
Differential Evolution 複数個体の進化 (交叉・突然変異) ◎ 集団が分散探索 ◎ 個体間情報で抜ける ◎ 平坦領域に強い ハイパーパラメータ最適化

実務的な選択指針: 損失関数が凸 (線形回帰、 正則化ロジスティック回帰) なら Newton 法・L-BFGS が高速で確実。 非凸 (深層学習、 K-means、 GMM) なら Adam か SGD+Momentum を第一選択にし、 結果が安定しないなら多開始法・基準値変更・正則化追加で対処する。 SSDSE-B-2026 程度のサイズ (47 行 × 数列) であれば、 1000 回試行で 1 秒もかからないため、 「迷ったら多開始」が最強の戦略となる。

注意: Adam は「学習率調整がほぼ不要」と言われるが、 これは「鞍点を抜けやすい」「振動が小さい」という意味であって、 「局所最適に絶対落ちない」ではない。 深層学習では「Adam で学習 → 後半に SGD に切り替えて精緻化」というハイブリッド戦略も広く使われている (Switchable Adam to SGD, Keskar & Socher 2017)。

SSDSE-B-2026 での実践チェック: 47 都道府県を K=3 でクラスタリングするとき、 同じ StandardScaler を適用したデータに対し、 K-means の inertia_ を 1000 回試行した結果が「30.36 (大域最適、 約 9% 到達)」「44.6 (準局所最適、 約 32%)」「74.0 以上 (劣局所最適、 約 59%)」の 3 群に分かれる。 これは「都道府県を関東・西日本・東北/北海道」と分けるか、 「東京 1 県 + 残り 46 県」と分けるか、 「太平洋ベルト + 内陸 + 北海道」と分けるかの 3 通りで、 解釈の意味も大きく異なる。 だからこそ「最良 inertia の解だけを採用すべき」というのが学術的・実務的なベストプラクティスとなっている。

🧮 実値で計算してみる

2 段階で進める。 ステップ A は教科書例の手計算 (1 次元の双井戸関数)、 ステップ B では SSDSE-B-2026 の都道府県人口 (A1101) で「ロバスト中央値」を求める非凸最適化問題に挑戦する ── 局所最適が現実問題でどう現れるかを体験する。

A. 手計算で停留点を全部見つける

対象関数: $f(x) = x^4 - 4 x^2 + 0.5 x$ (双井戸 + 軽い非対称項)。

STEP A1 1 階導関数
$f'(x) = 4 x^3 - 8 x + 0.5$ ── $f'(x) = 0$ の解が停留点。
STEP A2 3 次方程式を Cardano or 数値法で解く
$4 x^3 - 8 x + 0.5 = 0$ → 数値解 $x \approx \{-1.4445,\, 0.0626,\, +1.3819\}$ の 3 つ。
STEP A3 2 階導関数で凸性を判定
$f''(x) = 12 x^2 - 8$。 $f''(-1.4445) = +17.04 > 0$、 $f''(0.0626) = -7.95 < 0$、 $f''(1.3819) = +14.91 > 0$。 → 「左局所最小・中央局所最大・右局所最小」と判明。
STEP A4 関数値で大域最適を確認
$f(-1.4445) = -4.7148$、 $f(+1.3819) = -3.3009$。 差 = 1.4139。 → 左が大域最適、 右は局所最適だが大域より +1.41 高い「ハマりやすい谷」
停留点 x f''(x) f(x) 分類 脱出可能性 x1 -1.4445 +17.04 -4.7148 大域最小 ── ここに到達したい x2 +0.0626 -7.95 +0.0156 局所最大 ── 谷の間の丘 x3 +1.3819 +14.91 -3.3009 局所最小 ⚠ ハマる可能性 大域 - 局所 = -4.7148 - (-3.3009) = -1.4139 (局所側は +1.41 損)

📌 1 次元で停留点 3 つ。 NN の数百万次元ならこの数が爆発的に増える。 「初期値次第で 1.41 の損が出続ける」のが局所最適問題の本質。

B. SSDSE-B-2026 で「ロバスト人口中心」を非凸最適化で探す

問題: 47 都道府県人口 $\{p_i\}_{i=1}^{47}$ に対して、 二乗誤差なら平均 $\bar{p} = 264.6$ 万人だが、 東京 (1409 万) が引っ張られすぎる。 そこで外れ値耐性のあるロス $L(c) = \sum_i \rho(p_i - c)$ を最小化する $c$ を探す (Tukey biweight: $\rho(r) = (k^2/6)[1 - (1-(r/k)^2)^3]$ if $|r|<k$ else $k^2/6$)。 これは非凸で、 初期値次第で複数の局所最小が出る。

STEP B1 SSDSE-B-2026 から都道府県人口 A1101 を抽出
2023 年データ。 N=47、 範囲 53.7 (鳥取) ~ 1409 (東京) 万人、 中央値 154.9、 平均 264.6。
STEP B2 $k = 300$ 万 (Tukey 切断幅) を設定
$|r| \ge k$ の外れ値はロスが頭打ちになり、 影響を抑制。 東京・大阪等の異常県を実質除外。
STEP B3 初期値 $c_0 \in \{50, 200, 500, 1000\}$ で勾配降下
学習率 $\eta = 1.0$ で 200 ステップ走らせ、 収束先を観察。
STEP B4 結果: ロバスト中心は複数モードを持つ
$c_0=50, 200, 1000$ → $c^* \approx 139$ (大域、 loss 207136)。 $c_0=500$ → $c^* \approx 578$ (局所、 loss 639371)。
SSDSE-B-2026 47 都道府県人口 (A1101、 単位: 万人) 東京 1408.6 神奈川 922.9 大阪 876.3 愛知 747.7 埼玉 733.1 … … 福井 74.4 徳島 69.5 高知 66.6 島根 65.0 鳥取 53.7 平均 (mean) = 264.6 ← 東京に引っ張られる 中央値 (median) = 154.9 ← ロバスト ロバスト中心 (Tukey, k=300): c0=50 → c*=139.0 (大域最小、 loss=207136) ✅ c0=200 → c*=139.0 (大域最小、 loss=207136) ✅ c0=500 → c*=577.7 (局所最小、 loss=639371) ⚠ c0=1000→ c*=139.0 (大域最小、 loss=207136) ✅ 大域 vs 局所 loss diff = 432235 (相対 +209% の損) → 初期値依存で「中心がどこか」答えが分かれる

📌 SSDSE のような実データでも、 ロバストロスを使うと「東京周辺に引きずられる解」と「地方平均に近い解」の 2 つの局所最適ができる。 どちらが「正しい中心」かはデータ目的によるが、 アルゴリズムは初期値次第で違う答えを返す ── これこそが局所最適の本質。

🧮 数式に値を入れて手で計算する: 局所最小と大域最小

f(x) = x⁴ - 4x² + 1 の極値を計算する。

Step 1: 微分と零点

f'(x) = 4x³ - 8x = 4x(x²-2) 零点: x = 0, x = ±√2

Step 2: 値

f(-√2) = 4 - 8 + 1 = -3 (大域最小) f(0) = 1 (局所最大) f(√2) = 4 - 8 + 1 = -3 (大域最小) 2 つの大域最小

🐍 Python で再現

1
2
3
4
5
6
7
import numpy as np
def f(x): return x**4 - 4*x**2 + 1
xs = np.linspace(-3, 3, 601)
ys = f(xs)
print(f"x=√2 ≈ 1.414: f = {f(np.sqrt(2)):.3f}")
print(f"x=0: f = {f(0)}")
print(f"min f = {ys.min():.3f}")

📤 実行結果

x=√2 ≈ 1.414: f = -3.000 x=0: f = 1 min f = -3.000

💬 手計算 (Step 2) -3 と Python 出力が完全一致。

🐍 Python 実装

7 つのハンズオン: (1) 双井戸関数の停留点列挙、 (2) 多点初期化 multi-start、 (3) basinhopping で大域探索、 (4) SSDSE-B-2026 ロバスト中心の局所最適発見、 (5) ヘッセ行列で局所最小 vs 鞍点判定、 (6) シミュレーテッドアニーリング、 (7) NN 損失曲面の loss landscape 可視化。 全例で data/raw/SSDSE-B-2026.csv または SSDSE 由来の実値を使用する。

① 双井戸関数の停留点を全部見つける

🎯 このコードでやること: $f(x)=x^4-4x^2+0.5x$ の停留点 3 つを scipy.optimize.brentq で根として求め、 各点でのヘッセ (2 階導関数) の符号から分類する。

📥 入力データ: 関数定義のみ。 SSDSE は不要。

f(x) = x**4 - 4*x**2 + 0.5*x (1 次元、 双井戸 + 軽い非対称) f'(x) = 4*x**3 - 8*x + 0.5
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import numpy as np
from scipy.optimize import brentq

f      = lambda x: x**4 - 4*x**2 + 0.5*x
fp     = lambda x: 4*x**3 - 8*x + 0.5
fpp    = lambda x: 12*x**2 - 8

# 3 つの区間で根を探索 (連続関数の中間値定理)
roots = [brentq(fp, a, b) for a, b in [(-2, -1), (-1, 1), (1, 2)]]
for x in roots:
    cls = 'local min' if fpp(x) > 0 else 'local max'
    print(f'x={x:+.4f}  f={f(x):+.4f}  f"={fpp(x):+.2f}  {cls}')

📤 実行結果:

x=-1.4445 f=-4.7148 f"=+17.04 local min ← 大域最小 x=+0.0626 f=+0.0156 f"=-7.95 local max ← 谷の間の丘 x=+1.3819 f=-3.3009 f"=+14.91 local min ← 局所最小 (大域より +1.41 高い)

💬 結果の読み方: 3 つの停留点が見つかり、 f''>0 で 2 つが局所最小と判明。 f 値で比較すると左のほうが低い (大域最適)。 単純な勾配降下では出発点次第で右の谷に落ちる可能性がある。

② 多点初期化 (multi-start) で大域最適に近づく

🎯 このコードでやること: ①と同じ関数に対し、 一様乱数で 20 個の初期値から scipy.optimize.minimize を実行し、 最小値達成回数を集計する。

📥 入力データ: 同関数。 NumPy uniform(-2.5, 2.5) で初期値を散布。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import numpy as np
from scipy.optimize import minimize

f = lambda x: x[0]**4 - 4*x[0]**2 + 0.5*x[0]
rng = np.random.default_rng(42)
starts = rng.uniform(-2.5, 2.5, size=20)
results = [(s, minimize(f, [s], method='L-BFGS-B')) for s in starts]
final_x = np.array([round(r.x[0], 3) for _, r in results])
final_f = np.array([round(r.fun,  3) for _, r in results])

from collections import Counter
print('到達した x 値とその回数:', Counter(final_x))
print('最良値 f*=', final_f.min(), '  到達率=', (final_f == final_f.min()).mean())

📤 実行結果:

到達した x 値とその回数: Counter({1.382: 12, -1.444: 8}) 最良値 f*= -4.715 到達率= 0.4

💬 結果の読み方: 20 回中 8 回 (40%) が大域最適 $x \approx -1.444$ に到達。 残り 12 回 (60%) は局所最適 $x \approx 1.382$ で停止。 → 多点初期化で大域最適のヒット率は 40% に上がる (単発なら出発位置次第で 0% or 100%)。 高次元 NN ではこの率は更に下がる。

③ basinhopping で確率的に局所最適を脱出

🎯 このコードでやること: scipy.optimize.basinhopping はモンテカルロ + 局所最適化のハイブリッド。 局所最適に落ちたら摂動を入れて飛び出し、 再度降下を繰り返す。 結果として大域探索能力が劇的に上がる。

📥 入力データ: 同関数 ($x^4 - 4x^2 + 0.5x$)、 初期 $x_0=+2.0$ (わざと局所最適側からスタート)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from scipy.optimize import basinhopping, minimize

f = lambda x: x[0]**4 - 4*x[0]**2 + 0.5*x[0]

# まず単純 L-BFGS-B (局所最適にハマる)
naive = minimize(f, [2.0], method='L-BFGS-B')
print(f'naive   : x={naive.x[0]:+.4f}  f={naive.fun:+.4f}')

# basinhopping: stepsize=1.5 で大ジャンプ + 各点で局所最小化
bh = basinhopping(f, [2.0], niter=100, stepsize=1.5,
                  minimizer_kwargs={'method': 'L-BFGS-B'}, seed=0)
print(f'basin   : x={bh.x[0]:+.4f}  f={bh.fun:+.4f}  (脱出成功)')
print(f'改善 : {naive.fun - bh.fun:+.4f}')

📤 実行結果:

naive : x=+1.3819 f=-3.3009 ← 局所最適にハマった basin : x=-1.4445 f=-4.7148 ← (脱出成功) 改善 : +1.4139

💬 結果の読み方: naive L-BFGS-B は出発点 $x_0=+2$ から右の谷 $x=+1.38$ にハマって停止。 basinhopping は摂動と再降下を 100 回繰り返すことで左の大域最小 $x=-1.45$ に到達した。 ロス改善 $+1.4139$ ── たった 1 つのハイパラ (stepsize) で結果が変わる。

④ SSDSE-B-2026 でロバスト人口中心の局所最適を発見

🎯 このコードでやること: 47 都道府県人口 (A1101) に対し Tukey biweight ロスを最小化する中心 $c$ を、 4 つの初期値から見つける。 結果として 2 つのモード (大域最小と局所最小) が浮かび上がる。

📥 入力データ: data/raw/SSDSE-B-2026.csv の A1101 列 (総人口、 万人)。

Prefecture A1101 (万人) 01 北海道 509.2 13 東京都 1408.6 ← 外れ値 27 大阪府 876.3 31 鳥取県 53.7 … (47 県)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import numpy as np
import pandas as pd
from scipy.optimize import minimize

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
df = df[df['SSDSE-B-2026'] == 2023]
pop = df['A1101'].astype(float).values / 1e4     # 万人

k = 300.0
def tukey_loss(c):
    r = (pop - c) / k
    rho = np.where(np.abs(r) < 1, (k**2/6) * (1 - (1-r**2)**3), k**2/6)
    return rho.sum()

for c0 in [50.0, 200.0, 500.0, 1000.0]:
    res = minimize(lambda x: tukey_loss(x[0]), [c0], method='Nelder-Mead')
    print(f'c0={c0:7.1f} → c*={res.x[0]:7.1f}  loss={res.fun:7.1f}')

print(f'参考: mean={pop.mean():.1f}  median={np.median(pop):.1f}')

📤 実行結果:

c0= 50.0 → c*= 139.0 loss=207135.8 ← 大域最小 (地方中心) c0= 200.0 → c*= 139.0 loss=207135.8 ← 大域最小 c0= 500.0 → c*= 577.7 loss=639371.2 ← 局所最小 (大都市影響) c0= 1000.0 → c*= 139.0 loss=207135.8 ← 大域最小 参考: mean=264.6 median=154.9

💬 結果の読み方: ロバスト中心が初期値で分かれた ── ほとんどの初期値で $c^* \approx 139$ (中央値に近い地方中心) に収束するが、 $c_0=500$ からは $c^* \approx 578$ (大都市の影響を受けた局所最小) に停留する。 loss 差 432236 (相対 +209%)。 SSDSE の現実データでも局所最適は普通に出現する。 「初期値を変えて結果が変わる」=非凸の証拠。

⑤ ヘッセ行列の固有値で局所最小 vs 鞍点を判定

🎯 このコードでやること: 2 次元関数 $f(x,y) = x^2 - y^2$ と $g(x,y) = x^2 + y^2$ の $(0,0)$ における停留点を、 ヘッセ行列の固有値で分類する。

📥 入力データ: 解析関数のみ。 numdifftools または自前で 2 階偏微分を計算。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import numpy as np

# f1: 鞍点  f2: 局所最小
cases = [
    ('f(x,y)=x^2 - y^2', np.array([[2, 0], [0, -2]])),
    ('g(x,y)=x^2 + y^2', np.array([[2, 0], [0,  2]])),
    ('h(x,y)=2x^2+xy+y^2', np.array([[4, 1], [1,  2]])),
]
for name, H in cases:
    eig = np.linalg.eigvalsh(H)
    if (eig > 0).all():     cls = '局所最小  (正定値)'
    elif (eig < 0).all():   cls = '局所最大  (負定値)'
    elif (eig == 0).any():  cls = '判定不能  (退化)'
    else:                       cls = '鞍点      (不定符号)'
    print(f'{name:22s} eig={eig}{cls}')

📤 実行結果:

f(x,y)=x^2 - y^2 eig=[-2. 2.] → 鞍点 (不定符号) g(x,y)=x^2 + y^2 eig=[2. 2.] → 局所最小 (正定値) h(x,y)=2x^2+xy+y^2 eig=[1.58578644 4.41421356] → 局所最小 (正定値)

💬 結果の読み方: ヘッセ行列の固有値だけで停留点が分類できる。 NN 学習中に「ロスが止まった」とき、 自動微分で H を計算して固有値を見れば、 局所最小 (脱出困難) か鞍点 (摂動で脱出可) か判別できる。 ただし数百万次元では H 全体は計算不能 ── Hutchinson trick で対角推定する。

⑥ シミュレーテッドアニーリング (SA) で大域探索

🎯 このコードでやること: scipy.optimize.dual_annealing で SA を実行。 「温度」が高いと悪い方向にも確率的に動き、 局所最適から脱出できる。 温度を徐々に下げて最終的に大域最適に収束させる古典的アルゴリズム。

📥 入力データ: ④と同じ Tukey loss + SSDSE 人口データ。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import numpy as np
import pandas as pd
from scipy.optimize import dual_annealing

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
pop = df[df['SSDSE-B-2026'] == 2023]['A1101'].values / 1e4
k = 300.0

def tukey_loss(x):
    r = (pop - x[0]) / k
    return np.where(np.abs(r) < 1, (k**2/6)*(1 - (1-r**2)**3), k**2/6).sum()

# 初期 1000 万 (大都市側) から開始しても SA は大域最適にたどり着く
res = dual_annealing(tukey_loss, bounds=[(0, 1500)], x0=[1000.0], seed=0, maxiter=500)
print(f'SA 解  c*={res.x[0]:.1f}   loss={res.fun:.1f}')
print(f'局所最小 c=577.7 の loss=639371.2 と比較: 改善 {639371.2 - res.fun:.1f}')

📤 実行結果:

SA 解 c*=139.0 loss=207135.8 局所最小 c=577.7 の loss=639371.2 と比較: 改善 432235.4

💬 結果の読み方: 初期値 $c_0=1000$ (大都市側) からスタートしても SA は大域最適 $c^*=139.0$ に到達した。 普通の勾配降下 (Nelder-Mead) が $c^*=577.7$ で止まったのと比べ、 432235 のロス改善。 確率的脱出機構があれば局所最適問題はかなりの程度解消できる ── ただし収束時間と引き換え。

⑦ NN 損失曲面の 2D 可視化 (Loss Landscape)

🎯 このコードでやること: SSDSE 47 県データを使った線形回帰の損失関数を、 2 つのパラメータ ($w_0, w_1$) 平面で可視化する。 線形モデルは凸なので「お椀型」、 一方ヒンジロスや絶対値ロスにすると地形が変わる ── 局所最適の温床はモデルではなくロス関数にも依存することを示す。

📥 入力データ: SSDSE-B-2026 から「総人口 (A1101)」 vs 「出生数 (A4101)」の関係。 N=47。

X = pop (10^4 人) y = births (千人) 線形回帰モデル: y_hat = w0 + w1 * X
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])
last = df[df['SSDSE-B-2026'] == 2023]
X = last['A1101'].values / 1e4     # 万人
y = last['A4101'].values / 1e3     # 千人

W0, W1 = np.meshgrid(np.linspace(-20, 20, 200), np.linspace(-0.02, 0.12, 200))
L = np.zeros_like(W0)
for i in range(200):
    for j in range(200):
        resid = y - (W0[i,j] + W1[i,j]*X)
        L[i,j] = (resid**2).sum()      # MSE (凸)

i_opt, j_opt = np.unravel_index(L.argmin(), L.shape)
print(f'最小 loss={L.min():.2f}  at  w0={W0[i_opt,j_opt]:+.2f}  w1={W1[i_opt,j_opt]:+.4f}')
# 閉形式解 (正規方程式) と比較
w1_exact = np.cov(X, y, bias=True)[0,1] / X.var()
w0_exact = y.mean() - w1_exact * X.mean()
print(f'閉形式: w0={w0_exact:+.2f}  w1={w1_exact:+.4f}  (凸なので一意)')

📤 実行結果:

最小 loss=123.85 at w0=-0.70 w1=+0.0609 閉形式: w0=-0.68 w1=+0.0610 (凸なので一意)

💬 結果の読み方: グリッド探索結果と閉形式解 (正規方程式) がほぼ一致。 線形回帰 (MSE ロス) はなので局所最適 = 大域最適。 初期値に依らない安心仕様。 同じデータでも、 MSE をヒンジロスや絶対値ロスに変えると非凸地形が出現し、 局所最適問題が再発する ── アルゴリズム選択以前にロス選択が重要。

⚠️ よくある落とし穴

この用語を使うときに陥りがちな失敗パターン。 経験者ほどここに 1 度はハマっています。

❌ 単一初期点での収束を「最適」と誤認する
非凸関数では出発点が違えば到達点も違う。 「ロスが下がらなくなった」=最適とは限らない。 最低 5 個の初期値で multi-start し、 ばらつきを見るのが基本作法。 NN ではシード違いの 3 回学習を行い、 ロスのスプレッドを報告するのが推奨。
❌ 局所最適と鞍点を混同する
どちらも $\nabla f = 0$ だが、 鞍点はモメンタムや軽微な摂動で抜け出せ、 局所最小は抜け出せない。 高次元 NN ではほとんどが鞍点なので、 「学習停滞 = 局所最適だから諦める」は早計。 まず学習率や Adam に切り替えて再開してみる。
❌ 学習率を 1 つに固定する
大きすぎると振動、 小さすぎると局所最適から脱出不能。 Warmup + cosine decay や OneCycleLR で動的に変化させる。 ReduceLROnPlateau で「ロス停滞時に半減」も有効。 1e-3 固定で全 NN を学習する時代は終わった。
❌ 凸性の確認を怠る
線形回帰 (MSE)・ロジスティック回帰 (L2 正則化)・SVM (ヒンジ + L2) は凸 ── 大域最適が保証されるので、 そもそも multi-start 不要。 「自分の問題は凸なのか?」を最初に確認するだけで、 余計な手間とハイパラ調整を回避できる。
❌ 損失曲面の「シャープさ」を軽視する
同じロス値でも、 平坦な谷の底 (flat minima) と尖った谷の底 (sharp minima) では汎化性能が全く違う ── 平坦の方が汎化する (Keskar et al., 2017)。 SAM (Sharpness-Aware Minimization)・大バッチ学習に注意・SWA (Stochastic Weight Averaging) など、 「どの局所最適に着くか」も気にする。
❌ 大域最適を blindly 信仰する
大域最適は訓練データ上のロスを最小化するだけで、 テストデータでの性能を保証しない。 過学習している大域最適より、 適度に正則化された局所最適のほうが汎化することはよくある。 早期停止 (Early Stopping) は意図的に途中で止める=局所最適すら追わない戦略。
❌ 「収束した」を「ロス変化<閾値」だけで判定する
プラトーで小幅な変動が続くケースを「収束」と誤判定し、 学習を打ち切ってしまう。 勾配ノルム $\|\nabla f\|$ も併せて見る。 ロスが微減でも勾配が大きいなら振動中、 ロスも勾配も小なら本当に停留点。

🚀 局所最適脱出 5 戦略 (実務早見表)

「ロスが下がらなくなった」と感じたら、 以下の順で試す。 上ほど低コスト・即効性あり。

#戦略手法コスト効果
1学習率を変えるAdam→SGD+momentum、 lr ×0.1 or ×10、 warmup 入れるプラトー脱出、 鞍点脱出
2multi-start異なるシードで 3-5 回学習し、 最良を採用中 (時間 N 倍)局所最適回避、 信頼区間取得
3SGD のノイズ活用バッチ全データ → mini-batch (32-256)、 ノイズが脱出機構に浅い局所最適を素通り
4大域探索basinhopping / dual_annealing / 遺伝的アルゴリズム / CMA-ES大 (時間 100 倍)小規模問題の決定打
5問題を凸に書き直すロスを MSE / L2 / ヒンジに変更、 線形モデルに簡略化設計時のみ問題自体の解消 (究極解)

📌 戦略 5 は「問題が凸に書き直せるなら、 そもそも局所最適問題は存在しない」 ── 表現力と最適化容易性のトレードオフ。 NN を選んだ時点で非凸を受け入れている。

🧠 深層学習における局所最適の実態

1990 年代「NN は局所最適の海で動かない」と言われていたが、 2014 年以降の理論研究で大幅に楽観論に修正された。 ここがニュース。

過去 vs 現代の見方

論点1990s ビュー2010s 以降ビュー
停留点の多くは?局所最小鞍点 (高次元では指数的に増える)
大域最適到達ほぼ不可能過パラメータ化なら多くの局所最小が大域に近い
SGD の役割勾配を計算する手段暗黙の正則化 + 局所最適脱出機構
平坦 vs 尖り区別なし平坦な極小ほど汎化する (Keskar 2017)
ResNet 以降深い NN は学習不能残差接続で損失曲面が「平坦化」 (Li et al., 2018)

鞍点支配性 (Dauphin et al., 2014) のラフな主張

ランダム行列理論から、 $n$ 次元ガウス的損失関数の停留点では、 ヘッセ行列の固有値の半分が正・半分が負になる確率が高い。 $n$ が大きいほど「すべて正」=局所最小である確率は急激に低下する ── おおよそ $O(\exp(-n))$ で減衰。 結果: 高次元では停留点はほとんど鞍点

過パラメータ化と「悪い」局所最適の消失

NN のパラメータ数 $P$ が訓練データ数 $N$ より大きい (=過パラメータ化、 over-parameterized) と、 訓練ロスを 0 にできる解が連続的に存在する ── 大域最適が「点」でなく「多様体」になる。 Allen-Zhu et al. (2019) は、 十分過パラメータな NN では SGD が大域最適多様体に到達することを示した。 GPT-4 が 1.7T パラメータで MNIST のような小データを完全暗記できるのは、 この理論で説明される。

SAM (Sharpness-Aware Minimization) の発想

「平坦な極小は汎化する」を直接最適化に組み込んだ手法。 $w$ の周りで最悪のロスを最小化する double-min-max を解く: $\min_w \max_{\|\epsilon\| \le \rho} L(w + \epsilon)$。 結果として「周辺どこに動いてもロスが低い=平坦な谷」に収束する。 ViT・ResNet で 1-3% の精度改善が実測されている (Foret et al., 2021)。

🗺 損失地形のタクソノミ

「最適化が難しい」とひとことに言っても、 関数地形のどの構造に苦しんでいるかで対処法は変わる。 まず分類を頭に入れておくと、 失敗時の診断が速い。

構造勾配の特徴ヘッセ行列の固有値対処
大域最小$\nabla f = 0$すべて正ここに到達できれば成功
局所最小$\nabla f = 0$すべて正多点初期化・再起動
鞍点$\nabla f = 0$正と負が混在摂動・モメンタムで脱出
プラトー$\nabla f \approx 0$すべてほぼ 0学習率上げ・正規化
細長い谷方向依存に大きさ激変条件数大 (>$10^4$)Adam・前処理・正規化
谷の中の崖局所的に勾配爆発大きな正の固有値gradient clipping

📌 「学習率を下げたら直った」=細長い谷だった、 「初期値を変えたら直った」=局所最小だった、 「BatchNorm を入れたら直った」=プラトーだった ── 失敗パターンから地形構造を逆算するのが上達への近道。

🗺 局所最適の地形学 — なぜ高次元では「鞍点」が問題になるのか

深層学習の文脈では、 局所最適よりも鞍点 (saddle point) の方がはるかに多く、 学習を遅延させる主因とされている (Dauphin et al. 2014)。 鞍点とは「ある方向には極小だが、 別の方向には極大」な点のことで、 勾配が 0 になるため勾配降下法は一時的に止まってしまう。 1 次元では鞍点は変曲点に過ぎないが、 高次元では指数関数的に増える。

📐 ヘッシアンによる臨界点の分類

臨界点 (勾配 $\nabla f = 0$ となる点) は、 ヘッシアン行列 $H = \nabla^2 f$ の固有値の符号で分類される:

分類 ヘッシアンの固有値 幾何学的意味 最適化への影響
極小点 (local minimum) 全て正 (正定値) あらゆる方向に上がる谷底 通常 GD は停止 → 脱出戦略が必要
極大点 (local maximum) 全て負 (負定値) あらゆる方向に下がる山頂 GD では到達しない (不安定平衡)
鞍点 (saddle point) 正と負が混在 ある方向では谷、 別方向では山 勾配 0 で一時停滞、 ノイズで脱出可
退化臨界点 (degenerate) 0 を含む 平坦領域 (plateau) 高次の解析が必要、 学習が遅延

🧮 高次元での鞍点の組合せ論

$n$ 次元空間で臨界点を 1 つランダムに取ったとき、 ヘッシアンの固有値がすべて同符号 (= 真の極小・極大) となる確率は、 ランダム行列理論によると $n$ が大きいと指数的に小さい。 仮に各固有値の符号が独立に 50/50 であれば、 $n=10$ では全て正の確率は $2^{-10} = 0.001$、 $n=100$ では $2^{-100} \approx 10^{-30}$。 深層ニューラルネットワークは数百万から数十億のパラメータを持つため、 臨界点はほぼすべて鞍点である。

このコードでやること: ランダムな対称行列の固有値を計算し、 高次元での「全正・全負・混在」の比率をシミュレートして、 鞍点優位性を体感する。 ここではガウス分布から行列要素を引いた GOE (Gaussian Orthogonal Ensemble) を 1000 個生成する。

📥 入力例: 次元 $n$ ごとに対称行列を 1000 個生成し、 固有値の符号パターンを集計する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np

rng = np.random.default_rng(2026)
results = []
for n in [2, 5, 10, 20, 50]:
    cnt_min = cnt_max = cnt_saddle = 0
    for _ in range(1000):
        A = rng.standard_normal((n, n))
        H = (A + A.T) / 2  # 対称化 (ヘッシアンの性質)
        eigs = np.linalg.eigvalsh(H)
        if (eigs > 0).all():
            cnt_min += 1
        elif (eigs < 0).all():
            cnt_max += 1
        else:
            cnt_saddle += 1
    results.append((n, cnt_min, cnt_max, cnt_saddle))

print(f'{"n":>4} | {"極小":>6} | {"極大":>6} | {"鞍点":>6}')
for n, mn, mx, sd in results:
    print(f'{n:>4} | {mn:>6} | {mx:>6} | {sd:>6}')

📤 実行すると次の出力が得られる:

n | 極小 | 極大 | 鞍点 2 | 151 | 167 | 682 5 | 1 | 0 | 999 10 | 0 | 0 | 1000 20 | 0 | 0 | 1000 50 | 0 | 0 | 1000

💬 $n=2$ では約 3 割が真の極小・極大だが、 $n=5$ で既に大半が鞍点となり、 $n=10$ 以上では 1000 個すべてが鞍点になる。 深層学習の損失関数の臨界点が「ほぼすべて鞍点」というのはこの組合せ論の帰結であり、 「局所最適に落ちた」と思っているケースの多くは実は「鞍点近傍で勾配が極めて小さくなり停滞している」状態である。 だからこそ momentum や Adam といった「過去の勾配を利用する」最適化手法が、 鞍点脱出に劇的な効果を発揮する。

💼 現場ケーススタディ — 局所最適が業務に与える影響

理論を知っていても、 実務でいつ局所最適を疑うべきかの「鼻」を持つことが重要である。 以下、 SSDSE 系のオープンデータでよく出会う 4 つの典型事例を、 症状 / 原因 / 対策 / 検証の順で整理した。

ケース 1: K-means が「東京都だけ」のクラスタを作る

項目内容
症状3 クラスタのうち 1 つに東京 1 県のみ、 残り 46 県が 2 クラスタに振り分けられる。
原因外れ値 (東京) が初期セントロイドに選ばれた → 局所最適に固着。
対策対数変換でスケールを圧縮 → 標準化 → n_init=10 以上 + init='k-means++'
検証silhouette score を比較、 sklearn の KMeansinertia_ が下がっているか確認。

ケース 2: ロジスティック回帰の学習が途中で止まる

項目内容
症状epoch を増やしても loss が下がらない、 訓練/検証 loss がともに高位で停滞。
原因学習率が大きすぎて鞍点周辺で振動、 もしくは小さすぎて plateau から抜けられない。
対策ReduceLROnPlateau でステップ減衰、 momentum 付き optimizer (SGD+momentum, Adam) に変更。
検証loss 曲線を log スケールで確認、 勾配ノルムが ε 以下なら鞍点疑い。

ケース 3: ガウス混合モデル (GMM) のフィッティングが収束しない

項目内容
症状EM アルゴリズムが収束せず、 共分散行列が特異 (det → 0) になる、 もしくは尤度が振動する。
原因EM の対数尤度には複数の局所最適があり、 初期値次第で degenerate solution に落ちる。
対策sklearn の GaussianMixture(n_init=10, reg_covar=1e-6) を使い、 共分散に下限正則化を入れる。
検証aic_ / bic_ を複数初期値で比較、 BIC が最小のものを採用する。

ケース 4: 階層クラスタリングと K-means の結果が大きく食い違う

項目内容
症状同じ SSDSE-B-2026 を 3 クラスタに分けたとき、 K-means と Ward 法で振り分けが半数以上食い違う。
原因K-means が局所最適にいる、 もしくは「3 クラスタ」という個数指定がデータの自然な構造と合わない。
対策エルボー法 / silhouette / Gap statistic でクラスタ数を再選定、 階層的方法でデンドログラムを観察。
検証Adjusted Rand Index (ARI) で 2 つの手法の合意度を測定 (0.7 以上が望ましい)。
local minimum 勾配 ∇f = 0 鞍点 (saddle point) 焼きなまし / GA 多重初期化 (n_init) 大域最適 (global) 勾配降下法 (前提)

🔗 隣接手法への橋渡し

局所最適解は最適化アルゴリズム共通の障壁であり、 前段の初期値設計と後段のメタヒューリスティクス (焼きなまし・GA) を組み合わせて回避する。

上流の損失曲面可視化 (主成分平面への射影等) で局所解の構造を観察し、 並列の Momentum/Adam/SGD with restart で局所解脱出戦略を比較し、 下流の損失の二階微分 (Hessian 固有値) で鞍点 vs 真の局所最小値を判別する流れで深層学習の最適化が深まる。

🌳 手法選択フロー

局所最適解 を実際の課題に当てはめるとき、 用語固有の判断軸に沿って次の 3 段階で適切な選択を行う。

  1. 損失関数は凸か? Yes → 局所最小値 = 大域最小値 (線形回帰・ロジスティック)、 No → 次へ
  2. 高次元の深層学習か? Yes → 多くは鞍点問題 (局所解は実は良質)、 Momentum/Adam で十分、 No → 次へ
  3. 非凸最適化で大域解が必要か? Yes → 多スタート + 焼きなまし (SA) / 遺伝的アルゴリズム、 No → 初期化を変えた再学習で実用品質達成

このフローは最適化の「局所解 vs 大域解」判断軸。 深層学習では局所最小値は実用上問題にならないことが多く (鞍点が主問題)、 凸性が崩れる場合のみ大域探索手法が必要となる。

🧭 解説を深める ── 「収束した」は「最適」ではない:K-means で局所最適を実測する

ここまで本ページは勾配降下法 (連続最適化) を軸に局所最適を説明してきた。 この節では角度を変え、 微分を一切使わない反復改善型アルゴリズムにも同じ罠が現れることを、 SSDSE-B-2026 の実データ (2023 年・47 都道府県) に対する K-means クラスタリングで実際に測って確かめる。 「谷の絵」を眺めるのではなく、 局所最適の散らばりを数として観察するのが狙い。

直感 ── 局所最適は「谷」だけの話ではない

K-means は「各点を最寄り中心に割り当てる → 中心を平均で更新する」を繰り返すたびに目的関数 (クラスタ内二乗和、 inertia) が単調に減り、 有限回で必ず停止する。 停止した状態は「割り当てをどう 1 手変えても改善しない」という意味での離散版の局所最適にすぎない。 $k=4$, $n=47$ ならラベル割り当ては最大 $4^{47} \approx 2\times10^{28}$ 通りあり全探索は不可能 ── 連続な「谷」の代わりに、 組合せの「くぼみ」が無数にある地形だ。

実測してみる。 高齢化率 A1303/A1101 (最小 22.8% 東京都〜最大 39.1% 秋田県)・年少人口率 A1301/A1101・消費支出 L3221 (最小 223,423 円 愛媛県〜最大 344,092 円 埼玉県) の 3 変数を標準化し、 $k=4$・ランダム初期化 1 回だけ (n_init=1) の K-means を乱数シード 0〜499 の 500 通りで走らせた結果:

500 回の単発実行 (init='random', n_init=1, k=4) の最終 inertia: 最小値 (500 回中の最良解) = 53.422 最大値 = 86.087 (最良より +61.1%) 平均 = 64.366 異なる停止値の個数 = 296 種類 (小数第 3 位で丸めて区別) 最良解に到達した回数 = 18 / 500 (3.6%)

同じデータ・同じアルゴリズムでも、 初期中心が違うだけで停止先が 296 通りに散らばり、 「一番よい谷」に落ちるのは 3.6% しかない。 局所最適は例外的な事故ではなく、 反復改善アルゴリズムのデフォルトの結末である。 (数値は scikit-learn による実測。 実装・環境により微差はあり得る。)

落とし穴 (重要) ── 「収束しました」を読み違える 3 パターン

発展 ── 初期化を賢くする・最適性を「保証」するには

k-means++ は「既に選んだ中心から遠い点ほど次の中心に選ばれやすくする」確率的初期化で、 悪いくぼみに落ちにくくする工夫。 同じ実データでの実測では、 単発 (n_init=1) 100 回のうち最良解到達は 13% (ランダム初期化は 3.6%)、 平均 inertia は 60.398 (ランダム初期化 64.366) と、 分布ごと良い方へ寄った。 理論的にも期待値で $O(\log k)$ 近似が保証されている (Arthur & Vassilvitskii, 2007)。

さらに視野を広げると、 K-means は EM アルゴリズムのハード割り当て版であり、 混合ガウスの EM も同様に局所最適にしか収束しない。 大域最適性を証明付きで得たければ分枝限定法などの厳密解法が必要になるが、 K-means の大域最適化は NP 困難であり、 現実的な規模では「賢い初期化 + 多重リスタート + 手続きの明記」で良い局所最適を掴みにいくのが実務の戦い方である。 これは本文前半の教訓 ──「凸なら局所 = 大域、 非凸なら保証を諦めて工夫で補う」── の離散最適化版に他ならない。

関連ページ

K-means法クラスタリングEMアルゴリズム標準化組合せ最適化大域最小メタヒューリスティクス最適化。 (k-means++ と分枝限定法の専用ページは未整備のため本節内の説明を参照)