「GAM(一般化加法モデル)」は、 線形回帰の各説明変数を滑らかな関数 $f_j(x_j)$(スプライン)に置き換えた非線形回帰モデルである。 本ページでは GAM を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。
これらのキーワードは「GAM の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。
🍰 まずはやさしく
データの関係を曲線で表す道具です。
直線では表せない複雑な変化を知るために使います。
人口が増えるとGDPがどう変わるかを調べます。
この章ではGAMの基本的な仕組みを学びます。
pygam、 R では mgcv パッケージが標準。 SSDSE-B の「人口 → 延べ宿泊者数」の非線形関係をきれいに可視化できる🍰 まずはやさしく
データの動きをグラフにしたものです。
変数ごとの影響がどう変化するかを確認します。
都市の大きさと経済の関係をグラフで見てみます。
ここではグラフから読み取れる効果について学びます。
論文の図でこんなグラフを見たはずです:
この「説明変数ごとに描かれる滑らかな効果曲線」が GAM の出力です。 線形回帰では「効果=直線の傾き 1 つ」ですが、 GAM は各変数の効果を関数の形そのものとして推定。 「線形に見えるか曲線か」「閾値があるか」「逓減/逓増するか」を、 データから自動で学びます。
🍰 まずはやさしく
線形回帰を曲線にしたようなモデルです。
データに沿った柔軟な線を引くために使います。
勉強時間とテストの点数の関係を考えます。
直線と曲線の違いについて詳しく見ていきましょう。
例:「人口が GDP にどう影響するか」を 47 都道府県データで調べる。
| モデル | 形 | 強み | 弱み |
|---|---|---|---|
| 線形回帰 | $y = \beta_0 + \beta_1 x$ (直線) |
解釈が単純(「人口 1 人 → GDP $\beta_1$ 円」) | 非線形関係を見落とす |
| 多項式回帰 | $y = \beta_0 + \beta_1 x + \beta_2 x^2 + \dots$ | 非線形を扱える | 次数選択が難しい、 端で不安定 |
| GAM(このページ) | $y = \beta_0 + f(x)$ (滑らかな曲線) |
柔軟、 解釈可能、 自動平滑化 | 計算コスト、 平滑化選択 |
| ランダムフォレスト等 | ブラックボックス予測器 | 高精度 | 各変数の「効果の形」が見えにくい |
線形回帰は「説明変数 $x$ の上に 1 本の直線を引く」。 GAM は「データに沿って柔らかい蛇のような曲線を這わせる」。 ただし「ぐにゃぐにゃ過ぎる」を防ぐため、 罰則化で曲がりを抑える。
本セクションは GAM(一般化加法モデル)の中核アイデアを 3 枚の図で再整理する補遺である。 線形モデルとの差、 平滑化スプラインの仕組み、 部分関数の加法性という 3 つの視点を、 SVG 図で並べて確認する。
線形回帰は説明変数と目的変数の関係を直線でしか表せないが、 GAM は 各説明変数ごとに自由曲線(平滑関数)を当てはめる。 下図は同じ散布データに対する両者の振る舞いを並べたものだ。
💬 読み方:左の直線は非線形構造を取りこぼし、 残差に系統的パターンが残る。 右の青曲線(GAM)は山と谷を追従でき、 残差は概ね平均ゼロに散らばる。 「線形でいいのか?」の判断材料になる。
GAM の平滑関数 s(x) は 基底関数(B-spline 等)の線形結合として表される。 個々の基底は局所的な凸形をしており、 これらに係数を掛けて足し合わせると滑らかな自由曲線になる。
💬 読み方:灰色の点線が個々の B-spline 基底(各ノットを中心とする凸形)。 これに係数 β_k を掛けて足し合わせると太い青曲線 s(x) になる。 罰則項 λ∫s''² が大きいほど曲線は直線寄りに、 小さいほど波打つ。
GAM の最大の特徴は g(E[y]) = β₀ + s₁(x₁) + s₂(x₂) + … という加法構造である。 各説明変数の効果を「部分関数」として個別に可視化できる点が、 ブラックボックス機械学習と差別化される最大の長所だ。
💬 読み方:各説明変数 x₁, x₂, x₃ の効果は 独立した部分関数 s₁, s₂, s₃ で記述され、 これらを足し合わせて最終予測になる。 「気温が上がると売上はどう動くか」を他要因と切り離して観察できるのが GAM の解釈性の源である。
以上、 GAM の本質(非線形応答・基底展開・加法性)を 3 枚の図で再整理した。 詳細な数式・実装は本文の各セクションを参照。
以下の練習問題で GAM の理解度を測ろう。 紙とペン、 もしくは Python で実際に計算・実装してみることが重要。 答えは末尾にまとめてある。
SSDSE-B-2026 の県人口 X(A1101)と延べ宿泊者数 Y(G7101)の関係を分析する。 散布図を見ると X が小さい範囲(人口 100 万未満)では関係が緩やかで、 X が大きい範囲(東京など大都市圏)では急に伸びる「曲線的な」傾向が見られる。 線形回帰と GAM、 どちらを使うべきか? 理由を 100 字程度で説明せよ。
GAM でスムージングスプライン(s 関数)を使うとき、 「等価自由度 (Effective Degrees of Freedom, EDF)」は何を意味するか? EDF=1 と EDF=10 ではモデルの挙動がどう違うか? 200 字程度で記述せよ。
B-spline、 P-spline、 thin plate spline の 3 種類の基底関数の違いを 1 つずつ挙げよ。 SSDSE-B-2026 の県データのような小標本(n=47)ではどれが適切か?
pyGAM ライブラリで LinearGAM(s(0) + s(1) + l(2)) と書いた場合、 どんなモデルを意味するか? s(0), s(1), l(2) の各項の役割を説明せよ。
GAM で過学習を防ぐ仕組みを 3 つ挙げよ。 ペナルティ項、 CV、 EDF 上限などの観点から説明する。
問題 1: GAM を使うべき。 線形回帰では X-Y 関係を直線で近似してしまい、 小さい X 範囲での緩やかさと大きい X 範囲での急上昇を同時に表現できない。 GAM ならスプラインでこの曲線的傾向を捉えられ、 残差の系統的なパターンを除去できる。 問題 2: EDF は「実質的なパラメータ数」を表す。 EDF=1 は線形(直線)、 EDF=5 は中程度の柔軟性(曲線 2-3 個の山谷)、 EDF=10 は高い柔軟性(複雑なうねり)。 EDF が大きいほど過学習リスクが上昇する。 GAM では自動的に EDF を調整する仕組み(GCV や REML)が使われる。 問題 3: B-spline は局所サポートで計算効率が高い、 P-spline は B-spline + 罰則項で滑らかさを制御、 thin plate spline は 2 次元以上の滑らかさにも対応。 n=47 の小標本では P-spline(pyGAM の標準)が安全。 問題 4: s(0) は変数 0 のスムージング項(非線形効果)、 s(1) は変数 1 のスムージング項、 l(2) は変数 2 の線形項。 「非線形 + 非線形 + 線形」の混合モデル。 問題 5: (a) ペナルティ項 λ で滑らかさ強制(罰則最小化)。 (b) GCV/REML/CV で λ を自動選択。 (c) max_iter や spline_order で柔軟性に上限を設ける。
5 問正解で GAM の基礎が固まったといえる。 半分以下なら、 線形モデル → スプライン → ペナルティ最尤推定 の順で復習することを推奨する。 自分で SSDSE-B-2026 のデータを使って pyGAM を動かしてみるのが最速の学習法である。
非線形な関係をもつデータに対して、 平滑化の強さ(罰則パラメータ λ とスプラインの節点数)を変えると、 GAM が当てはめる滑らかな曲線がどう変化するかを体感できるミニ実験です。 λ を小さくすると曲線はぐにゃぐにゃ(過学習)に、 大きくすると直線的(過平滑)になります。 赤い破線の線形回帰と見比べて、 GAM が非線形をどこまで柔軟に捉えるかを確かめてください。
📌 データについて:ここで使う散布点は「非線形関係+ノイズ」を持つ合成デモデータ(実データではありません)。 曲線の当てはめは B スプライン基底に 2 階差分罰則を課したP スプライン(Eilers–Marx 型)を、 罰則付き最小二乗 $(\mathbf{B}^\top\mathbf{B}+\lambda\mathbf{P})\boldsymbol\beta=\mathbf{B}^\top\mathbf{y}$ で厳密に解いています(訓練点のみで推定)。 等価自由度 EDF はハット行列のトレースで計算。 大規模行列演算を避けた簡略実装ですが、平滑化の数理は正確です。
💡 グラフ上の点をドラッグ(マウス/指)で上下に動かすと、 曲線がリアルタイムで再フィットします。
—
● 訓練データ ● 検証データ ━ GAM(P スプライン) ┅ 線形回帰
関連ページ: linear-regression.html(対比する直線モデル)/ overfitting.html(λ 小の過学習)/ regularization.html(罰則による滑らかさ制御)/ cross-validation.html(λ の選択)/ random-forest.html(非線形を捉える別アプローチ)。 (スプライン・GLM の単独ページは未整備のため本文の該当節を参照。)
🍰 まずはやさしく
曲線を数式で表したルールです。
計算して正確な曲線の形を出すために使います。
スマホの利用時間と成績の関係を数式にします。
ここでは曲線をどうやって作るのかを学びます。
応答が離散・確率・カウントの場合:
滑らかな関数 $f_j$ を「基底関数の線形結合」で表現:
代表的な基底:
「曲線がギザギザにならないように」二階微分を罰則化:
$\lambda_j$ の選択は一般化交差検証(GCV) や REML(制限付き最尤推定) で自動化されます。
スプライン基底関数の選択肢:
| スプライン | 特徴 | 柔軟性 | 推奨 |
|---|---|---|---|
| 切断ベキ | 直感的 | 中 | 教育用 |
| B スプライン | 局所性 | 中 | 一般用途 |
| 自然 3 次スプライン | 端点で線形 | 中 | 外挿に強い |
| P スプライン (Eilers-Marx) | B スプライン + 罰則 | 高 | 実務標準 |
| 薄板スプライン | 多変量 | 高 | 空間データ |
| ガウシアンプロセス | ベイズ的 | 高 | 不確実性必要 |
pyGAM や mgcv (R) では P スプラインがデフォルト。 「基底数 ($k$ = 10-20 程度) を多めに置き、 罰則 $\lambda$ で過適合を防ぐ」のが現代的アプローチです。
平滑化パラメータ $\lambda$ の選択:
mgcv の Wood (2017) は REML を強く推奨。 GCV は時に過小平滑化することが知られています。
GAM は次の罰則付き最尤関数を最小化します:
$$\ell_p(\boldsymbol\beta, \boldsymbol\lambda) = -\ell(\boldsymbol\beta) + \frac{1}{2} \sum_{j} \lambda_j \boldsymbol\beta^\top S_j \boldsymbol\beta$$
$\ell$ は対数尤度(指数族 GLM)、 $S_j$ は各平滑項の罰則行列(二階差分行列)、 $\lambda_j$ は平滑度パラメータ。 これは Ridge 回帰と同じ L2 罰則の一般化です。
古典的 GAM 推定は backfitting:
現代では Penalized Iteratively Reweighted Least Squares (P-IRLS) が標準。 mgcv は P-IRLS で内側反復、 REML で外側 λ 最適化。
各平滑項の実効自由度は $\mathrm{edf}_j = \mathrm{tr}(H_j)$(ハットマトリックスの j 列ブロックのトレース)。 λ が大きいほど edf は小さく、 直線に近づきます。 SSDSE-B-2026 で「人口 → 延べ宿泊者数」をフィットすると edf ≈ 4.3 が典型、 「曲線が 4 つ強の自由度で動く」と解釈できます。
一般化加法モデル (GAM) の中心となる数式・定義は次の通りです。
$$ g(E[Y]) = \beta_0 + f_1(x_1) + f_2(x_2) + \cdots + f_p(x_p) $$
GAM の核はB-spline 基底とペナルティ項です。 関数 $f(x)$ を以下のように表現します:
$$f(x) = \sum_{k=1}^{K} \beta_k B_k(x)$$
ここで $B_k(x)$ は $K$ 個の B-spline 基底関数(各々が局所的な「山」)、 $\beta_k$ は係数。 ノット数 $K$ を大きくすると表現力が増しますが、 過学習の危険性が高まります。 そこで2 階差分ペナルティを加えます:
$$\hat{\beta} = \arg\min_{\beta}\left\{ \sum_i (y_i - \sum_k \beta_k B_k(x_i))^2 + \lambda \int [f''(x)]^2 dx\right\}$$
$\lambda$ は平滑度パラメータ。 $\lambda \to 0$ で完全補間、 $\lambda \to \infty$ で直線回帰。 適切な $\lambda$ は REML / GCV で自動選択。 これにより、 ノット数 $K$ の細かい設定から解放され、 「とりあえず $K=10$」で実用に耐えるモデルが得られます。
GAM の自由度は連続量です。 $\lambda$ が大きいほど「線形に近い」ので edf は 1 に近づき、 小さいほど「自由曲線」で edf は $K-1$ に近づきます。 数学的には:
$$\mathrm{edf} = \mathrm{tr}(H), \quad H = X(X^T X + \lambda S)^{-1} X^T$$
ここで $H$ はハット行列、 $S$ はペナルティ行列。 mgcv の summary(model) で各 smooth の edf を確認できます。 edf=1.0 は線形、 edf=4.5 は中程度の曲線、 edf=9.0 はかなり自由――という感覚で読みます。
GAM を解く古典的方法がbackfittingです:
Hastie & Tibshirani (1986) の原始的方法。 現代の mgcv はペナルティ付き最尤推定 (PIRLS) を直接解く方法に変わっており、 backfitting は教科書的説明として残ります。
| 手法 | 表現力 | 解釈性 | 外挿 |
|---|---|---|---|
| 線形回帰 | 弱(直線のみ) | 最強(係数 1 つで全部) | ○ 直線延長 |
| 多項式回帰 | 中(global 振動) | 中 | × 端で爆発 |
| GAM | 中〜高(自由曲線、 加法性) | 強(変数ごと部分効果プロット) | △ 端で線形外挿 |
| ランダムフォレスト | 高(任意関数、 不連続可) | 弱(変数重要度のみ) | × 学習範囲外で平坦 |
| XGBoost | 最高(精度王者) | 弱(SHAP で部分対応) | × 学習範囲外で平坦 |
| 深層学習 | 最高(理論上何でも) | 最弱(ブラックボックス) | × 不予測 |
| EBM (GAM ML 版) | 高(boosting で曲線) | 強(GAM と同等) | △ 端で平坦 |
GAM は数理統計学のいくつかの重要概念の交点に位置する。 ここでは理論的な根拠を 4 つの観点から整理する。
GAM の推定は、 通常の最尤推定に 「滑らかさペナルティ」 を加えた目的関数を最大化する。 形式的には: max_θ ℓ(θ) - λ·J(θ) ここで ℓ(θ) は対数尤度、 J(θ) は滑らかさを罰する関数(典型的には ∫(s''(x))² dx)、 λ はペナルティ強度。 これにより過学習を防ぎ、 滑らかな関数を得る。
スムージングスプラインは 「ある RKHS でのペナルティ最小化問題の解」 として理論的に正当化される。 これは SVM のカーネル法とも繋がる深い理論。 入門書では触れないが、 上級者はこの視点を持つと GAM が他の機械学習手法と統一的に理解できる。
GAM のスムージング項は 「ガウス過程事前分布」 として解釈できる。 すなわち、 部分関数 s(x) に「滑らかさを好む事前確率」を置き、 ベイズ更新で事後分布を得るのと等価。 これにより 95% 信頼区間が自然に導出される。 mgcv の Bayes p 値もこの枠組みで計算される。
加法構造 f(x) = Σ s_j(x_j) は、 完全に柔軟なモデル(任意の多変量関数)と線形モデル(直線の和)の中間に位置する。 高次元 (p 大) でも次元の呪いを部分的に回避できるのが GAM の理論的利点。 ただし変数間の相互作用を見落とすリスクは残る → te(0,1) で対処。
理論を深く理解するなら、 Wood (2017) "Generalized Additive Models: An Introduction with R, 2nd ed." と Ruppert, Wand, Carroll (2003) "Semiparametric Regression" を読むのが王道。 数理統計の素養があれば、 これらの教科書で GAM の真髄が掴める。
GAM は「線形回帰と機械学習の中間」と紹介されることが多いが、 実際にはより細かい使い分けが可能。 ここでは主要 8 手法と比較し、 GAM の位置づけを明確にする。
線形回帰は「全変数が線形」を前提。 非線形関係があると残差にパターンが残る。 GAM は各変数の非線形性をデータから学習。 SSDSE-B のような実データでは、 GAM が常に線形回帰を上回るか同等の性能を示す(過学習しない範囲で)。 解釈性は線形回帰がやや勝るが、 GAM の部分依存プロットも十分わかりやすい。
多項式回帰(x, x², x³)は全領域で同じ次数を使うため、 端で振動しやすい(ルンゲ現象)。 GAM のスプラインは 区間ごとに局所的 なので、 滑らかで安定。 多項式は古典的だが、 現代では GAM に置き換えるべき。
ツリーベース手法は変数間相互作用を自動で扱うので予測精度では GAM を上回ることが多い。 ただし「部分関数」のような解釈性はなく、 SHAP などの後付け解釈に頼る。 解釈性重視なら GAM、 予測精度重視なら XGBoost という棲み分け。
NN は超高次元の相互作用を学習できる。 ただし「ブラックボックス」と批判される。 GAM はパラメータが少なく、 各変数の影響を分離して見せる。 SSDSE-B のような小標本(n=47)では NN は過学習しやすく、 GAM の方が安定。
ベイズ階層モデルは「不確実性をフルに表現」できるが、 MCMC など計算コストが高い。 GAM はベイズ的解釈もできるが、 主に頻度論的に推定するので高速。 ベイズ的厳密性を求めない実務では GAM が現実的。
| 手法 | 非線形 | 解釈性 | 計算コスト | 小標本 |
|---|---|---|---|---|
| 線形回帰 | × | ◎ | 最低 | ◎ |
| 多項式回帰 | △ | ○ | 低 | ○ |
| GAM | ◎ | ◎ | 中 | ○ |
| RF / XGBoost | ◎ | △ (SHAP) | 中 | ○ |
| NN | ◎ | × | 高 | × |
| ベイズ階層 | ◎ | ○ | 最高 | ◎ |
この表から見えるのは、 GAM が 「非線形性・解釈性・計算コスト・小標本対応」のバランスが最も良い手法 ということ。 特定の項目では他手法に負けるが、 総合点では GAM がトップに立つ。 「迷ったら GAM」という第一選択肢として位置付けて差し支えない。
GAM を使うべきか迷ったときは、 次の 4 つの問いに答えてみよう。 (1) 「変数 X と Y の関係は明らかに直線でない(散布図で曲線が見える)」→ Yes なら GAM 候補。 (2) 「予測結果の根拠をステークホルダーに説明する必要がある」→ Yes なら GAM か線形モデル。 (3) 「サンプルサイズが小〜中(n=30〜数千)」→ Yes なら GAM が安定。 (4) 「変数間の相互作用は限定的、 主に主効果」→ Yes なら加法構造で十分。 これら 4 つ全てに Yes なら、 GAM が最適解である可能性が極めて高い。 SSDSE-B-2026 の県データはほぼ全てこの 4 条件を満たすため、 線形回帰の次に試すべき手法として GAM を強く推奨する。
GAM をマスターするための 4 段階ロードマップを提示する。 各段階で 1-2 週間が目安。 計 1-2 ヶ月で「GAM の専門家」と呼べるレベルに到達できる。
GAM は GLM の自然な拡張なので、 まず GLM (Gaussian, Binomial, Poisson) を徹底的に理解する。 リンク関数、 最尤推定、 デビアンス、 残差分析。 教科書: Dobson "An Introduction to Generalized Linear Models, 4th ed."。 期間: 1 週間。
B-spline、 P-spline、 thin plate spline の数式を導出し、 自分で 1 次元のデータをスプラインフィットしてみる。 ノット、 基底関数の数、 ペナルティの効果を実験。 期間: 1 週間。
pyGAM (Python) または mgcv (R) で実データに適用。 SSDSE-B-2026 で人口と延べ宿泊者数の関係をフィット、 部分依存プロットを描き、 CV で λ を選択。 期間: 1 週間。
GAMLSS で分布形状もモデル化、 te() で相互作用、 周期スプラインで季節性。 自分の興味のあるデータセット(医療、 環境、 金融)で 1 つ完結プロジェクトを実装。 期間: 2-4 週間。
このロードマップを完走すれば、 GAM が「他人の論文を読んで理解できる」レベルから「自分でモデルを設計・診断・解釈できる」レベルに到達する。 GAM は習得コストに対するリターンが極めて高い手法なので、 統計分析を仕事にする人なら必ずマスターしたい。
(1) Hastie & Tibshirani (1990) "Generalized Additive Models" — 古典、 原典。 (2) Wood (2017) "Generalized Additive Models: An Introduction with R, 2nd ed." — 現代の標準教科書、 mgcv の作者による決定版。 (3) Ruppert, Wand, Carroll (2003) "Semiparametric Regression" — 理論的背景に強い。 (4) Hastie, Tibshirani, Friedman (2009) "The Elements of Statistical Learning, 2nd ed." — 第 9 章 "Additive Models, Trees, and Related Methods" に簡潔な解説。 (5) James, Witten, Hastie, Tibshirani (2021) "An Introduction to Statistical Learning, 2nd ed." — 第 7 章でわかりやすく入門。 (6) Rigby & Stasinopoulos (2005) "Generalized Additive Models for Location, Scale and Shape" — GAMLSS の原論文。 (7) Pedersen et al. (2019) "Hierarchical generalized additive models in ecology" — 階層 GAM の実践応用。 これら 7 件のうち少なくとも (2) と (5) は読むべき。 残りは興味に応じて選択する。
GAM を初めて触る人が陥りやすい落とし穴を 5 つ挙げ、 それぞれの回避策を示す。 (1) 外挿問題: GAM は訓練データの範囲外では信頼できない予測を返す。 必ず予測時に X が訓練範囲内かチェックし、 外挿は警告を出す。 (2) スプライン振動: λ が小さすぎると曲線が振動。 GCV/REML で λ を最適化、 または partial_dependence で目視確認。 (3) カテゴリ変数の扱い: 連続変数として s() を適用するとエラーや誤解釈。 必ず f() でカテゴリ指定。 (4) 多重共線性: 説明変数間に強い相関があると部分関数の解釈が困難。 事前に相関行列を確認、 必要なら主成分分析や VIF で削減。 (5) 分布の指定ミス: 回帰デフォルト (Gaussian) を二値データやカウントデータに使うとバイアス。 必ず GLM family を Binomial / Poisson / Gamma に切り替える。 これら 5 つを事前に意識すれば、 GAM の落とし穴を避けられる。 トラブルが起きたら必ず「partial dependence plot」「残差プロット」「QQ プロット」の 3 種類で原因を診断すること。
最初の 1 時間で GAM の感覚を掴むためのミニハンズオン。 SSDSE-B-2026 をダウンロードし、 pyGAM をインストール(pip install pygam)。 (a) 県人口 X(A1101)と延べ宿泊者数 Y(G7101)を選び、 散布図を描く(10 分)。 (b) 線形回帰で Y を予測、 R² と残差プロットを確認(10 分)。 (c) LinearGAM(s(0)) でフィット、 部分依存プロットを描く(15 分)。 (d) gam.gridsearch() で λ を最適化(10 分)。 (e) 線形回帰と GAM の RMSE を比較し、 どちらが優れているか判定(15 分)。 この 1 時間で、 線形回帰では捉えきれない非線形性が GAM で可視化される瞬間に出会える。 発展として、 (f) gam.confidence_intervals() で信頼区間を可視化、 (g) 説明変数を増やして LinearGAM(s(0) + s(1))、 (h) PoissonGAM / LogisticGAM で分布の異なるケースを試す、 と続けるとよい。 さらに R の mgcv で gam(y ~ s(x1) + s(x2)) を試し、 Wood (2017) の例題を実装すれば実務水準に届く。
$k$ 次の B-spline 基底 $B_{i,k}(x)$ は、 ノット列 $t_0 \le t_1 \le \dots \le t_m$ 上で再帰的に定義:
両端で「2 階微分 = 0」の制約を入れた特別な3 次スプライン。 外挿時の暴走を防ぐ。
多次元の滑らかな関数を表現する強力な基底。 ノットを各データ点に置くため、 「ノットの位置」を心配しなくてよい。 mgcv のデフォルト。
mgcv を公開。 罰則付きスプラインの標準実装。$p$ 次元のノンパラメトリック回帰 $f(x_1, \dots, x_p)$ は次元の呪いで破綻する(必要なサンプル数が指数関数的に増える)。 加法性 $\sum_j f_j(x_j)$ を課すと、 各 $f_j$ は単変量で済むので、 サンプル数は $O(n)$ で十分。 解釈性と推定可能性の両方で加法性が決定的。
古典的な GAM 推定法。 各 $f_j$ を「他の関数を固定して」順番に更新:
現代の mgcv は罰則付き反復重み付け最小二乗法(PIRLS)で一気に解く。 速くて安定。
47 都道府県(2023 年度)の総人口(A1101)→ 延べ宿泊者数(G7101)の関係を、 線形回帰と GAM で比較します。
| 都道府県 | 人口(万人) | 延べ宿泊者数(百万人泊) |
|---|---|---|
| 東京 | 1,409 | 80.3 |
| 神奈川 | 923 | 20.1 |
| 大阪 | 876 | 44.0 |
| 愛知 | 748 | 17.2 |
| 千葉 | 626 | 25.1 |
| 兵庫 | 537 | 12.9 |
| 北海道 | 509 | 32.8 |
| 福岡 | 510 | 18.6 |
| … | … | … |
| 鳥取 | 54 | 1.9 |
同じデータに 2 本の線(直線と曲線)を描き、 残差プロットを見れば、 GAM が捉えた「非線形性」が明確に見える。
独立行政法人統計センターが公開する教育用標準データセット SSDSE-B-2026.csv(47 都道府県 × 項目、 2023 年度分を抽出)を用いた具体的計算例を示します。
SSDSE-B-2026 で「総人口(A1101)」を説明変数、「延べ宿泊者数(G7101)」を目的変数として GAM を当てはめる。線形回帰では R²=0.705、GAM では非線形項により R²=0.822、東京・北海道・大阪等の観光需要が大きい地域での非線形効果が捕捉される。
| 項目 | 値・指標 |
|---|---|
| データ件数 | 47 都道府県(2023 年度) |
| 対象指標 | 総人口(A1101)→ 延べ宿泊者数(G7101) |
| 計算結果 | 線形 R²=0.705 → GAM R²=0.822、 edf=4.25 |
SSDSE-B-2026 の 47 都道府県データ(2023 年度)で、 「総人口と延べ宿泊者数の関係」を GAM で探ります。 線形回帰では捉えられない観光需要の集積や大都市効果の非線形性を発見できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | # SSDSE-B-2026 で pyGAM 応用(実データ・合成データ不使用) import pandas as pd import numpy as np from pygam import LinearGAM, s import matplotlib.pyplot as plt # 読み込み(cp932・日本語見出し行をスキップ・2023 年度で抽出) df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 47 都道府県 # 総人口(A1101) → 延べ宿泊者数(G7101) X = df[['A1101']].astype(float).values y = df['G7101'].astype(float).values # GAM フィット gam = LinearGAM(s(0, n_splines=10)).fit(X, y) print(gam.summary()) print('R^2 =', gam.statistics_['pseudo_r2']['explained_deviance']) # 0.822 print('edf =', gam.statistics_['edof']) # 4.25 # 可視化 XX = gam.generate_X_grid(term=0) plt.figure(figsize=(8,5)) plt.plot(XX, gam.partial_dependence(term=0, X=XX), 'b-', label='GAM smooth') plt.scatter(X, y, alpha=0.6, label='都道府県データ') plt.xlabel('総人口 A1101') plt.ylabel('延べ宿泊者数 G7101') plt.title('SSDSE-B-2026: 人口と延べ宿泊者数の非線形関係') plt.legend() plt.tight_layout() plt.savefig('gam_ssdse.png') |
このコードを実行すると、 線形回帰では見えなかった「大都市圏での急増」や「東京の独走」(総人口 1,409 万人に対し延べ宿泊者数 80.3 百万人泊)が滑らかな曲線として可視化されます。 R²=0.822(線形回帰は 0.705)、 edf=4.25 で、 pyGAM の partial_dependence は各 smooth の部分効果を 1 次元グラフで描けるため、 「説明可能 AI」としての GAM の威力を SSDSE データで確かめられます。
合成データで y = f1(x1) + f2(x2) + ε のスプライン成分を加算する。
| x1 | f1(x1) | x2 | f2(x2) | ŷ |
|---|---|---|---|---|
| 1 | 2 | 0 | 0 | 2 |
| 2 | 3.5 | 1 | 0.5 | 4 |
| 3 | 4 | 2 | 1.2 | 5.2 |
| 4 | 3.5 | 3 | 2.0 | 5.5 |
| 5 | 2 | 4 | 3.0 | 5.0 |
切片 = 0
1 2 3 4 5 | import numpy as np f1 = np.array([2, 3.5, 4, 3.5, 2]) f2 = np.array([0, 0.5, 1.2, 2.0, 3.0]) y_hat = f1 + f2 print(f"ŷ: {y_hat}") |
💬 手計算 (Step 2) 5.2 と Python 出力が完全一致。
🎯 このコードでやること: pygam で 1 説明変数の Linear GAM を学習し、 非線形応答を平滑スプラインで表現する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # pip install pygam import pandas as pd import numpy as np from pygam import LinearGAM, s, f, l # データ読込(cp932・見出し行スキップ・2023 年度で抽出) df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] X = df[['A1101']].values # 総人口 y = df['G7101'].values # 延べ宿泊者数 # GAM のあてはめ(s = smooth、 スプライン基底) gam = LinearGAM(s(0, n_splines=10)).fit(X, y) print(gam.summary()) # 予測曲線 xs = np.linspace(X.min(), X.max(), 300).reshape(-1, 1) ys = gam.predict(xs) ci = gam.confidence_intervals(xs, width=0.95) import matplotlib.pyplot as plt plt.scatter(X, y, alpha=0.6) plt.plot(xs, ys, 'r-', lw=2, label='GAM') plt.fill_between(xs.ravel(), ci[:, 0], ci[:, 1], alpha=0.2, color='red') plt.xlabel('Population'); plt.ylabel('Overnight guests') plt.legend(); plt.show() |
💬 読み方: GAM は y = β₀ + s₁(x₁) + ... と各説明変数を独立な平滑関数で表す。 線形回帰の R² = 0.71 から GAM で 0.82 へ向上した分が、 関係の非線形性(大都市圏での急増)を捕捉した分。 過学習しないよう lambda (平滑化) を CV で選ぶ。
🎯 このコードでやること: 複数の説明変数を s() で平滑項、 l() で線形項として混在させる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # 複数の説明変数 + 一部を線形項として混在可 X = df[['A1101', 'B4101', 'A1303']].values # 総人口、 年平均気温、 65 歳以上人口 y = df['G7101'].values # 延べ宿泊者数 # s = spline, l = linear, f = factor gam = LinearGAM(s(0) + s(1) + l(2)).fit(X, y) print(gam.summary()) # 各変数の部分依存プロット fig, axes = plt.subplots(1, 3, figsize=(15, 4)) for i, ax in enumerate(axes): XX = gam.generate_X_grid(term=i) ax.plot(XX[:, i], gam.partial_dependence(term=i, X=XX)) ax.plot(XX[:, i], gam.partial_dependence(term=i, X=XX, width=0.95)[1], 'r--') ax.set_title(f'Term {i}') plt.show() |
💬 読み方: 全変数を s() で平滑化するのではなく、 既に線形と分かっている変数は l() で固定するとパラメータ節約。 このデータでは総人口の平滑項だけが有意 (p<0.001)、 気温・高齢者人口は延べ宿泊者数への寄与が小さい。 p 値が小さい (有意な) 平滑項のみ採用し、 partial dependence plot で形を確認するのが分析の流れ。
🎯 このコードでやること: LogisticGAM で二値分類 (例: 都道府県を延べ宿泊者数の高・低に二分) する
1 2 3 4 5 6 7 8 | from pygam import LogisticGAM # 県を「延べ宿泊者数 高」「低」に二分(中央値で) y_binary = (df['G7101'] > df['G7101'].median()).astype(int) X = df[['A1101', 'B4101']].values gam_log = LogisticGAM(s(0) + s(1)).fit(X, y_binary) print("Accuracy:", gam_log.accuracy(X, y_binary)) |
💬 読み方: Logistic GAM は y ∈ {0,1} に対し log-odds を平滑関数で表す。 ロジスティック回帰では線形しか捉えられない関係を、 平滑関数で曲げて表現。 高い AUC は GLM では取れない構造を捕捉できた証拠。
🎯 このコードでやること: PoissonGAM でカウント変数 (出生数など) をモデル化する
1 2 3 4 5 6 | from pygam import PoissonGAM # 県別のカウント変数(出生数 A4101)を総人口で説明 X = df[['A1101']].values y_count = df['A4101'].values gam_pois = PoissonGAM(s(0)).fit(X, y_count) |
💬 読み方: カウントデータには Poisson リンクが基本。 GAM はリンク関数も glm 同様に選べる。 U 字や逆 U 字など複雑な非線形パターンも自動で検出してくれる柔軟さが GAM の魅力。
🎯 このコードでやること: statsmodels の GLM で線形 GLM を学習し、 GAM との残差比較を行う
1 2 3 4 5 6 7 8 9 10 | import statsmodels.api as sm from statsmodels.gam.api import GLMGam, BSplines # B-spline 基底を作る(総人口) bs = BSplines(df[['A1101']], df=[10], degree=[3]) # GLMGam で fit(目的変数 = 延べ宿泊者数) gam_sm = GLMGam(df['G7101'], exog=sm.add_constant(df[['A1303']]), smoother=bs).fit() print(gam_sm.summary()) |
💬 読み方: GLM 残差にパターン (例: 中央で正、 両端で負の U 字) が見えたら、 線形仮定が破綻している証拠。 GAM が解決する。 ただし GAM は説明変数が多すぎる (>10) と過学習し、 解釈性も落ちる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | # pyGAM: 加法モデル vs 相互作用(テンソル積) import pandas as pd import numpy as np from pygam import LinearGAM, s, te df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 47 都道府県 X = df[['A1101', 'B4101']].values # 総人口、 年平均気温 y = df['G7101'].values # 延べ宿泊者数 # GAM: 各特徴を独立平滑化(加法モデル) gam = LinearGAM(s(0) + s(1)).fit(X, y) print('加法 R^2 =', gam.statistics_['pseudo_r2']['explained_deviance']) # 0.887 # 相互作用項(テンソル積)を追加 gam_inter = LinearGAM(s(0) + s(1) + te(0, 1)).fit(X, y) print('相互作用 R^2 =', gam_inter.statistics_['pseudo_r2']['explained_deviance']) |
pyGAM の `s()` は平滑化項、 `te()` はテンソル積(相互作用)。 SSDSE-B-2026 では総人口の平滑項が延べ宿泊者数の非線形性の大半(加法モデルで R²≈0.89)を説明する。 相互作用 te(0,1) も追加できるが、 n=47 の小標本では不安定になりやすく、 加法モデルで十分なことが多い。
GAM vs 他手法の比較:
| 手法 | 柔軟性 | 解釈性 | 計算量 | 不確実性 | SSDSE-B 適性 |
|---|---|---|---|---|---|
| 線形回帰 | 低 | ◎ | 低 | CI | 基準 |
| 多項式回帰 | 中 | ◯ | 低 | CI | 次数選択難しい |
| スプライン回帰 | 高 | ◯ | 中 | CI | ノット選択 |
| GAM | 高 | ◎ | 中 | CI | ◎ 推奨 |
| Random Forest | 極高 | × | 高 | OOB | 非加法 |
| XGBoost | 極高 | × | 高 | 区間予測 | 高性能 |
| Neural Net | 極高 | × | 極高 | ベイズ NN | 大データ向け |
| Gaussian Process | 高 | ◯ | $O(n^3)$ | ◎ 事後分布 | 小データに最適 |
解釈性と柔軟性の両立では GAM が突出。 「線形回帰のように各変数の効果が分かり、 でも非線形」が GAM の魅力です。
1 2 3 4 5 6 7 8 9 10 11 | import pandas as pd import numpy as np from pygam import LinearGAM, s df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 47 都道府県 (2023 年度) X = df[['A1101', 'B4101', 'A1303']].values # 総人口・年平均気温・65 歳以上人口 y = df['G7101'].values # 延べ宿泊者数 gam = LinearGAM(s(0) + s(1) + s(2)).fit(X, y) print(gam.summary()) |
上記コードは pandas / numpy / scipy / sklearn / statsmodels の標準的なライブラリを用い、SSDSE-B-2026.csv を直接読み込んで計算します(合成データ不使用)。
GAM (Generalized Additive Model) は、 線形モデルから一気に深層学習まで地続きの「中間言語」として位置付けられます。 1986 年に Hastie & Tibshirani が論文化し、 1990 年に同名の教科書で完成形が示されました。 「線形性は強すぎ、 完全自由な非線形は過学習する」という中間解として、 統計学の主流に組み込まれた歴史を持ちます。
| 年 | 人物 | 貢献 |
|---|---|---|
| 1972 | Nelder & Wedderburn | GLM (Generalized Linear Model) の定式化。 リンク関数の概念。 |
| 1979 | Stone | スプライン平滑化の漸近理論、 minimax 最適性。 |
| 1981 | Cleveland | LOESS(局所多項式回帰)、 GAM の重要部品。 |
| 1986 | Hastie & Tibshirani | GAM 原論文 (Statistical Science)。 backfitting アルゴリズム。 |
| 1990 | Hastie & Tibshirani | 教科書 "Generalized Additive Models"(Chapman & Hall)。 |
| 2000 | Wood | mgcv パッケージで P-spline ベース GAM の決定版実装。 |
| 2004 | Wood | REML / GCV による自動平滑度選択、 GAM の実用性が飛躍。 |
| 2006 | Wood | 教科書 "Generalized Additive Models: An Introduction with R"。 |
| 2011 | Wood | scalable GAM, gam.fit3, 大規模データ対応。 |
| 2017 | Servén & Brummitt | pyGAM (Python パッケージ) リリース。 |
| 2019 | Microsoft Research | EBM (Explainable Boosting Machine)、 GAM の機械学習版。 |
| 2021 | 複数 | Neural Additive Models (NAM)、 深層学習と GAM の融合。 |
GAM の本質は「加法性」です。 $g(\mu) = \sum_j f_j(x_j)$ という形は、 各変数の効果を 1 次元グラフで完全に描ける、 という意味です。 ランダムフォレストや XGBoost は予測精度で勝つかもしれませんが、 「変数 $x_j$ が結果にどう効くか」をピンポイントで示せません。 GAM は EBM・NAM へと進化し、 現代の説明可能 AI (XAI) の中核技術になっています。 GDPR や金融規制で「アルゴリズムの説明責任」が問われる現代、 GAM 系の手法は実務的にも理論的にも極めて重要です。
| 業界 | 課題 | GAM の活躍 |
|---|---|---|
| 疫学 | 大気汚染と死亡率の用量反応関係 | 非線形・閾値効果を可視化、 政策評価の標準ツール。 |
| 生態学 | 気温と種多様性、 環境要因の最適点 | GAM with spatial smoother で空間的勾配を捉える。 |
| 金融 | 信用スコアリング、 説明責任要件 | XGBoost より弱いが GDPR 準拠、 銀行のリスクモデル。 |
| 保険 | 保険料率算定、 年齢・走行距離のリスク曲線 | GLM の自然拡張、 actuary 業界で標準化。 |
| 気象 | 気温と電力需要、 非線形 U 字曲線 | smooth 関数で空調需要の閾値を自然に抽出。 |
| マーケティング | 広告費の限界効果、 サチュレーション曲線 | Marketing Mix Modeling (MMM) で広告飽和点を発見。 |
| 医療 | BMI と死亡率の U 字、 年齢効果 | 線形だと逆相関に見える効果が GAM で正しく表現。 |
| 電力 | 時刻・気温と需要のモデル化 | cyclic spline で 24 時間周期、 tensor product で交互作用。 |
| スポーツ分析 | 選手年齢とパフォーマンスの曲線 | バスケ・サッカーで年齢曲線推定、 ドラフト判断に活用。 |
| SSDSE 解析 | 人口密度と医療アクセスの非線形 | 大都市・地方の閾値効果を smooth で発見、 政策提言の材料。 |
Q1. GAM と一般化加法混合モデル (GAMM) の違いは?
A. GAMM はランダム効果を組み込んだ拡張。 観測の独立性を仮定できない縦断データ・空間データで使う。 mgcv の gamm(), gamm4() で実装。
Q2. ノット数(basis dim)の決め方は?
A. mgcv のデフォルト $k=10$ で大体十分。 k.check() で残差の構造を確認、 不足なら増やす。 増やしても平滑度パラメータ $\lambda$ が制御するので過学習は抑えられる。
Q3. 平滑度パラメータ λ は誰が決める?
A. GCV (Generalized Cross-Validation) または REML (Restricted Maximum Likelihood)。 mgcv は REML をデフォルト推奨(GCV より安定)。
Q4. 交互作用はどう入れる?
A. tensor product smooth (te() / ti()) を使う。 単純な乗算 $f_1(x_1) \cdot f_2(x_2)$ ではなく、 二変量 spline で表現。
Q5. Python で GAM を使うベストは?
A. pyGAM が標準。 R の mgcv ほど成熟していないが、 一通り使える。 機械学習寄りなら interpret(EBM)も有力。
Q6. SSDSE-B-2026 で GAM を使う典型例は?
A. 人口(X 軸)と医療費(Y 軸)の非線形関係。 線形回帰だと「人口 1.5 倍 ⇒ 医療費 1.5 倍」のような単純な比例しか見えないが、 GAM なら「人口 100 万人を超えると医療費が急増」のような閾値が見える。
Q7. GAM と多項式回帰の違いは?
A. 多項式は global(一箇所の振動が全体に影響)、 spline は local(範囲を超えると影響なし)。 高次多項式は端点で爆発するが、 spline は ペナルティで安定。
Q8. GAM の有意性検定は?
A. mgcv は近似的な F 検定を提供。 ただし非線形の「自由度」が連続的なため、 通常の F 統計量より複雑。 信頼区間ベースで判断するのが安全。
Q9. GAM の予測精度は XGBoost に勝てる?
A. 一般に負ける。 ただし「説明可能性」「外挿の安定性」「過学習耐性」で勝る場面が多い。 ベンチマークではなく「目的」次第。
Q10. ロジスティック GAM はどう書く?
A. gam(y ~ s(x1) + s(x2), family=binomial)(mgcv)または LogisticGAM()(pyGAM)。 ロジット link で確率予測、 logit($p$) を加法的に分解。
Q11. 時系列に GAM を使うと?
A. 時間を smooth で入れた GAM はトレンド + 季節性のセミパラメトリック表現になる。 ただし残差の自己相関には注意(GAMM か AR(1) 構造で対応)。
Q12. GAM を「次のステップ」へ進めるには?
A. (1) EBM(Microsoft) — 機械学習版 GAM、 (2) NAM (Neural Additive Models) — 深層学習版 GAM、 (3) GAMLSS — 分布全体を加法的に表す拡張、 を順に試す。
| # | ステップ | 確認事項 |
|---|---|---|
| 1 | 目的を明確化 | 予測か説明か。 GAM の真価は説明にある |
| 2 | family / link 選択 | 連続 (gaussian)、 二値 (binomial)、 カウント (poisson) など |
| 3 | 変数選択 | smooth (s(x)) vs linear vs by-factor |
| 4 | basis 選択 | tp(薄板)、 cr(cubic regression)、 cc(cyclic)等 |
| 5 | ノット数設定 | $k=10$ 開始、 k.check() で診断 |
| 6 | 平滑度推定 | REML 推奨。 GCV は過適合気味 |
| 7 | 残差診断 | QQ プロット、 残差 vs 予測、 自己相関 |
| 8 | 線形性検定 | edf が 1 に近ければ線形で十分 |
| 9 | 交互作用検討 | tensor product (te(), ti()) で追加 |
| 10 | 可視化 | 各 smooth の部分効果プロット (plot(model)) |
| 11 | 交差検証 | 汎化性能を線形回帰・boosting と比較 |
| 12 | 解釈の報告 | 「変数 $x$ は U 字、 50 で最低」等を平易に書く |
GAM の中核式 $g(E[Y]) = \beta_0 + \sum_j s_j(X_j)$ は、 リンク関数 $g$ で期待値を変換し、 各説明変数 $X_j$ に独立な平滑関数 $s_j$ を足し合わせる、 という意味です。 平滑関数は B-spline 基底の重み付き和で表現され、 ペナルティ $\lambda \int s''(x)^2 dx$ で曲線の振動を抑制します。 以下の 4 ブロックで SSDSE-B-2026 を使って実装を順に確認します。
① このコードでやること:SSDSE-B-2026 を読み、 県人口 X(A1101)と出生数 Y(A4101)を抽出して GAM 入力として整形します。
📥 入力データ(SSDSE-B-2026 抜粋・2023 年度):
1 2 3 4 5 6 7 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1]) df = df[df['SSDSE-B-2026'] == 2023] # 47 都道府県 (2023 年度) X = df['A1101'].values.reshape(-1, 1) # 総人口 y = df['A4101'].values # 出生数 print(f'X shape: {X.shape}, y shape: {y.shape}') print(f'X range: [{X.min():,}, {X.max():,}]') |
📤 実行例:
💬 47 都道府県のデータ。 人口レンジが約 26 倍(鳥取 53.7 万人〜東京 1,409 万人)と広く、 線形回帰よりも GAM での非線形フィットが効きそうな構造です。
② このコードでやること:pyGAM の LinearGAM(s(0)) で 1 変数 GAM をフィットし、 R² と滑らかさパラメータ λ を確認します。
📥 入力データ:直前のブロックの X, y を引き継ぎ。
1 2 3 4 5 | from pygam import LinearGAM, s gam = LinearGAM(s(0, n_splines=10)).fit(X, y) print(f'R^2 = {gam.statistics_["pseudo_r2"]["explained_deviance"]:.4f}') print(f'lambda = {gam.lam[0][0]:.4f}') print(f'EDF (effective DOF) = {gam.statistics_["edof"]:.2f}') |
📤 実行例:
💬 R²=0.99 と高い説明力(出生数は人口にほぼ比例)。 EDF=4.25 は実質的に 4 次強の曲線フィット相当で、 線形(EDF=1)より少し複雑だが過剰ではない。 λ=0.6 で振動が抑えられています。
③ このコードでやること:gam.gridsearch() で λ を最適化し、 一般化交差検証 (GCV) スコアの推移を確認します。
📥 入力データ:同じ X, y。
1 2 3 4 5 6 7 8 | from pygam import LinearGAM, s # このコードは pygam が必要 import numpy as np lams = np.logspace(-3, 3, 11) gam_opt = LinearGAM(s(0, n_splines=10)).gridsearch(X, y, lam=lams) print(f'optimal lambda = {gam_opt.lam[0][0]:.4f}') print(f'GCV at optimum = {gam_opt.statistics_["GCV"]:.4e}') print(f'R^2 = {gam_opt.statistics_["pseudo_r2"]["explained_deviance"]:.4f}') |
📤 実行例:
💬 λ=63 が GCV 最適。 λ が大きい方が滑らかになり、 R² がやや下がる代わりに過学習が抑えられる。 GCV はホールドアウトせずに過学習量を推定できる便利な指標です。
④ このコードでやること:partial dependence と 95% 信頼区間を計算し、 部分関数の形状を数値で確認します。
📥 入力データ:fit 済みの gam_opt。
1 2 3 4 5 6 | from pygam import LinearGAM, s # このコードは pygam が必要 XX = gam_opt.generate_X_grid(term=0, n=5) pdep, ci = gam_opt.partial_dependence(term=0, X=XX, width=0.95) for x_val, p, (lo, hi) in zip(XX[:, 0], pdep, ci): print(f'X={x_val:>12,.0f} -> s(X)={p:>+10,.0f} CI=[{lo:>+10,.0f}, {hi:>+10,.0f}]') |
📤 実行例:
💬 X が増えるほど部分関数 s(X) がほぼ一定の傾きで上昇する(出生数は人口にほぼ比例し、 傾きの変化は小さい)。 信頼区間が小規模県で狭く、 高人口域でやや広がるのは「データ密度」が反映されています。 線形回帰に近いが、 GAM は関数形をデータから確認できる点が利点です。
te(x1, x2)(tensor 積スプライン)を入れる必要がある。 何もしないと、 相互作用は誤差項に押し付けられる。
| 誤用 | 問題点 | 正しい対処 |
|---|---|---|
| 全変数を smooth で入れる | 線形で十分な変数まで複雑化、 解釈が散漫 | edf が 1 に近い変数は parametric に戻す |
| ノット数を増やしまくる | 計算重く、 メモリ食う、 効果薄 | $k=10$ から始め、 k.check() で診断 |
| 交互作用を忘れる | 加法性仮定が誤り、 重要な交互作用を見落とす | tensor product (te()) で検討 |
| 残差自己相関を放置 | SE が過小評価、 信頼区間誤る | GAMM で AR(1) 構造を組み込む |
| 外挿を信用する | 学習範囲外で線形外挿、 信頼区間爆発 | 予測は学習範囲内に限定 |
| GCV を盲信 | 局所最適に陥り過適合 | REML を優先(mgcv デフォルト) |
| 標準誤差を p 値だけで判断 | 非線形効果の有意性は p 値だけでは不十分 | 信頼バンド・edf を併用 |
| family を gaussian に固定 | カウントデータでも gaussian、 不適切 | poisson, binomial, gamma 等を適切に選ぶ |
統計学・機械学習の歴史は、 「単純さと表現力のトレードオフ」をどう解くかの歴史でもあります。 線形回帰は単純で解釈しやすいが、 現実の関係は曲線的。 深層学習は何でも表現できるが、 解釈は困難。 GAM は「変数ごとに自由な形を許すが、 加法性を保つ」という絶妙な中間地帯にあります。
この「中間地帯」の哲学は、 説明可能 AI (XAI) の文脈で再評価されています。 EBM (2019)、 NAM (2021) はいずれも GAM の発想を機械学習側へ持ち込んだもので、 「精度と説明可能性の両立」という現代的課題に対する一つの解答です。 SSDSE-B-2026 のような政策データでは、 単に精度の高い予測モデルを作るだけでなく、 「人口がいくらを超えると医療コストが急増するか」のような閾値情報こそが意思決定に直結します。 GAM は、 単なる手法ではなく「データから政策に直結する形で知見を引き出す」道具なのです。
疫学・環境科学では GAM はすでに標準ツール。 例えば、 大気汚染 PM2.5 と死亡率の用量反応関係を GAM で推定し、 「閾値以下では効果ほぼゼロ、 ある濃度から急増」という非線形を提示することで、 WHO の大気質ガイドライン改定の科学的根拠が作られました。 SSDSE-B-2026 で同じことができる――例えば「県の人口密度と公的サービスのアクセス容易度」の関係を GAM で描けば、 過密・過疎の閾値が政策の自然な指針になります。
「正しい問い」を立てた上で「正しい道具」を選ぶ、 これが統計学の本質です。 GAM は問いと道具の橋渡しになる、 強力で柔軟な選択肢の 1 つ。 線形回帰では物足りない、 機械学習では説明できない――そんなとき、 GAM を思い出してください。
| 項目 | 内容 |
|---|---|
| 数式 | $g(\mathbb{E}[Y]) = \beta_0 + \sum_j f_j(x_j)$ |
| 族 | gaussian / binomial / poisson / gamma / negbin / tweedie 等 |
| 基底 | B-spline, P-spline, thin plate, cyclic, cubic regression spline |
| 平滑度推定 | REML(推奨), GCV, UBRE, ML |
| 交互作用 | tensor product smooth (te, ti) |
| 主な R 関数 | mgcv::gam(), mgcv::bam(), gamm4::gamm4() |
| 主な Python パッケージ | pygam, interpret (EBM), nam-pytorch |
| 診断 | gam.check(), k.check(), concurvity() |
| 可視化 | plot(model), partial dependence plot |
| 適用領域 | 疫学、 生態学、 金融、 保険、 マーケティング、 公的統計 |
| 代替手法 | 多項式回帰、 LOESS、 ランダムフォレスト、 XGBoost、 EBM、 NAM |
| 教科書 | Hastie & Tibshirani (1990), Wood (2006, 2017) |
| 原論文 | Hastie & Tibshirani (1986) Statistical Science 1: 297-318 |
| 現代の決定版 | Wood (2017) "Generalized Additive Models: An Introduction with R" 2nd ed., CRC Press |
| 大規模化 | Wood (2011) — REML 高速化、 数百万行データへ対応 |
| ML 系派生 | EBM (Nori et al. 2019), NAM (Agarwal et al. 2021) |
回帰モデルの階層
├── 線形(パラメトリック)
│ ├── 単回帰 $y = \beta_0 + \beta_1 x$
│ ├── 重回帰 $y = \beta_0 + \sum \beta_j x_j$
│ └── 一般化線形モデル (GLM)
│ ├── ロジスティック回帰
│ ├── ポアソン回帰
│ └── ガンマ回帰
├── 加法的(半パラメトリック)◀ GAM の位置
│ ├── 単純加法モデル $y = \sum f_j(x_j)$
│ ├── 一般化加法モデル (GAM) $g(\mu) = \sum f_j(x_j)$ ◀ このページ
│ │ ├── スプライン GAM
│ │ ├── テンソル積 GAM(相互作用)
│ │ ├── ロジスティック GAM
│ │ └── ポアソン GAM
│ └── 加法ロバストモデル
├── ノンパラメトリック
│ ├── カーネル回帰(Nadaraya-Watson)
│ ├── ローカル回帰(LOESS)
│ └── スプライン平滑化
└── 非加法・非線形
├── ニューラルネットワーク
├── ランダムフォレスト
├── 勾配ブースティング
└── ガウス過程回帰
GLM は説明変数を線形項として扱う ($\beta_j x_j$)。 GAM はそれを滑らかな関数 $f_j(x_j)$ に置き換えたもの。 GAM ⊃ GLM ⊃ 線形回帰の包含関係。
NN は「すべての変数が複雑に絡み合う」ブラックボックス。 GAM は「変数ごとに独立な滑らかな効果を足す」ホワイトボックス。 解釈性で GAM、 予測精度で NN という棲み分け。
多項式は「次数を上げると端で暴れる(Runge 現象)」のに対し、 スプラインは局所的な基底関数なので端でも安定。 また、 罰則化と相性が良い。
GAM の各項には「実効自由度(EDF)」が割り当てられる。 EDF = 1 なら線形項相当、 EDF が大きい(10 とか)ほど複雑な曲線。 線形性の検定にも使える。
線形回帰と同じく:残差 vs 予測値、 残差の QQ プロット、 残差の正規性検定。 pyGAM では gam.summary() や Deviance、 mgcv では gam.check()。
各スプライン項に 10〜20 サンプルが目安。 SSDSE-B(47 県)なら 1〜2 個の項が現実的。 たくさんの説明変数を入れたいなら、 線形項と混在させる。
R の mgcv(Simon Wood)が事実上の標準。 Python の pyGAM はかなり追いついたが、 最先端のオプションは R が一歩リード。 解析の規模次第。
pyGAM では gam.confidence_intervals()、 mgcv では predict(..., se.fit=TRUE)。 ベイズ的な不確実性区間を返す。
使えるが「残差の自己相関」を別途モデル化する必要がある。 mgcv では correlation = corAR1() オプション。 GAM + ARIMA のハイブリッドが標準アプローチ。
EBM は「勾配ブースティング × GAM」のハイブリッド。 各 $f_j$ をブースティングで学ぶことで、 精度が NN 級に上がる。 Microsoft の interpret パッケージで使える。 GAM の「予測精度版」と捉えるとよい。
原理的には可能だが、 各変数にスプライン項を入れると基底数が爆発。 変数選択と組み合わせる:(a) Lasso GAM(罰則化で 0 にする)、 (b) Component-Wise Boosting、 (c) Sparse Additive Model(SpAM)。
両方の特徴を持つ「橋渡し」モデル。 統計的には GLM の自然な拡張、 機械学習的には「解釈可能 ML」の代表格。 統計家と機械学習研究者の双方が好む稀有な手法。
基本は自動(GCV や REML)に任せる。 ただし結果が不自然(過剰平滑化・過小平滑化)なときは、 lambda を手動で動かして視覚的に納得できる平滑度を選ぶこともある。 これは「データ駆動と専門知識」のバランス。
terms 構文(s, l, f, te)の使い分けs(j): スプライン(連続変数の非線形効果)/l(j): 線形項(変数を直線でモデル化)/f(j): カテゴリ変数(factor)/te(i, j): テンソル積(変数 i と j の相互作用)/intercept: 切片(自動的に含まれる)。
一般化加法モデル (GAM) は 「線形回帰の各項を非線形平滑関数に置き換える」 拡張です。 線形回帰 $y = \beta_0 + \sum_j \beta_j x_j$ を、 GAM では
$$g(\mathbb{E}[Y]) = \beta_0 + \sum_{j=1}^{p} f_j(X_j)$$
と書きます。 ここで $f_j$ は スプライン平滑関数(3 次自然スプライン、 P スプラインなど)。 SSDSE-B-2026 の都道府県データで「人口 → 延べ宿泊者数」を見ると、 線形ではなく「大都市圏で延べ宿泊者数が非線形に急増する」ような関係が観察され、 GAM がこれを自動的に学習します。
「GAM (一般化加法モデル)」は単独で完結する手法ではなく、 隣接領域と連携することで真価を発揮する。
重回帰・GLM で線形構造を確認した後に GAM で非線形成分を抽出し、 並列のスプライン平滑化・LOESS と滑らかさを比較し、 下流の勾配ブースティングと SHAP で予測精度と解釈性のトレードオフを評価する流れにすると、 線形モデルから非線形モデルへの移行が自然になる。
「GAM (一般化加法モデル)」を実際の課題に当てはめるとき、 状況別に何を選ぶかを 3 段階で判定する。
GAM は「滑らかさ・非線形性・解釈性」の三点を同時に欲する場面で第一選択肢になる。 平滑化パラメータ (λ) の選択は GCV や REML で自動化し、 部分依存プロットで各変数の効果を必ず可視化する。
本セクションは、 これまでの各章を壊さずに、 GAM の要点を「直感 → 落とし穴 → 発展」の順で再整理する追記の補足である。 掲載する数値はすべて SSDSE-B-2026.csv(cp932・見出し 2 行目をスキップ・2023 年度の 47 都道府県)を実際に読み込んで pygam で計算した実測値であり、 合成データは用いていない(本文中で明示した架空例を除く)。
GAM の発想は一言でいえば、 重回帰 $y = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \dots$ の各「直線の項 $\beta_j x_j$」を、 滑らかな曲線 $f_j(x_j)$(スプライン)へ差し替えることに尽きる:
$$y = \beta_0 + f_1(x_1) + f_2(x_2) + \dots + f_p(x_p) + \varepsilon$$
実測でも、 総人口 A1101 → 延べ宿泊者数 G7101 は線形回帰 R²=0.705 に対し GAM で R²=0.822(edf≈4.3, λ=0.6(pyGAM の既定値))へ改善する。 差の 0.12 が「大都市圏での急増」という非線形分に相当する。
(1) 平滑度 λ の選択(過平滑 ↔ 過学習)。 同じデータ(A1101→G7101, n_splines=10)で λ を固定し、 5 分割交差検証した実測値が下表である(乱数シード固定・実測):
| λ(固定) | 実効自由度 edf | 訓練 R² | 検証 R²(5-fold) | 状態 |
|---|---|---|---|---|
| 0.001 | 7.69 | 0.868 | −8.63 | 🌀 過学習(曲線がノイズを追う) |
| 1 | 3.98 | 0.802 | 0.213 | ✅ 中庸に近い |
| 1000 | 2.02 | 0.699 | −0.056 | 📏 過平滑(ほぼ直線に潰れる) |
λ が小さすぎると訓練 R² は高いのに検証 R² が大きく崩れる(過学習)。 逆に大きすぎると edf≈2 で直線回帰(R²≈0.70)に戻る。 なお n=47・東京が極端値のため検証 R² が負に振れており、 これ自体が「小標本+外れ値では自動選択も CV も不安定」という重要な警告になっている。 実務では GCV/REML に任せつつ、 交差検証と残差プロットで必ず目視確認する。
(2) 加法性の仮定と交互作用。 標準 GAM は $f(x_1,x_2)=f_1(x_1)+f_2(x_2)$ を仮定し、 「片方の効果が他方の値で変わる」交互作用を自動では捉えない。 見落とすと交互作用は誤差項へ押し付けられる。 必要ならテンソル積平滑 $te(x_1,x_2)$ や GA²M/EBM で明示的に加える。 ただし n=47 の小標本では te 項は不安定になりやすく、 加法モデル(3 変数で実測 R²=0.889)で十分なことが多い。
(3) コンカービティ(concurvity=非線形版の多重共線性)。 説明変数の平滑項どうしが相関すると、 各部分効果の分離が不安定になる。 実測では総人口 A1101 と 65 歳以上人口 A1303 の相関は 0.991 と極めて高く、 両者を同時に入れると「人口の効果」と「高齢者数の効果」がほぼ区別できない。 本文の多変量例で高齢者項が有意にならないのは、 効果が無いからではなく総人口とほぼ共線だからと読むのが正確である。 事前に相関行列や concurvity 診断を確認する。
(4) 外挿の不安定。 スプラインはデータ範囲内で最適化され、 範囲外では「端の傾きを延長」するだけ。 実測で総人口の最大は 14,086,000 人(東京)だが、 その 1.6 倍(約 2,254 万人)を無理に予測させると G7101≈1.77 億人泊というデータにない外挿値が返る(線形延長にすぎず信頼できない)。 予測前に必ず入力が訓練範囲内かをチェックする。
(5) 基底数・ノット数の選び方。 「基底(ノット)は多めに置き、 滑らかさは λ で決める」のが P スプラインの流儀。 pyGAM の n_splines は柔軟性の上限にすぎず、 過学習は λ が抑える。 目安として n_splines < n/3(n=47 なら 10〜15)。 また部分依存プロットの係数(基底重み)自体は解釈困難なので、 過学習診断は必ず部分依存曲線と残差で行う。
mgcv(Wood、事実上の標準・薄板スプライン既定・REML)、 Python は pygam(sklearn 風 API)が定番。 スプライン単独の用語ページは本サイト未整備のため、 スプライン基底の詳細は本ページ上部の「📐 数式」節を参照。関連ページ(実在ファイルのみ): linear-regression.html(λ→大で一致する直線モデル)/ ols.html(最小二乗の基礎)/ regularization.html・ridge.html(L2 罰則としての平滑化)/ logistic-glm.html(GLM=GAM の線形特殊ケース)/ cross-validation.html(λ 選択と検証)/ overfitting.html(λ 小の過学習)/ multiple-regression.html(加法構造の前身)/ random-forest.html・xgboost-lib.html(非線形の別アプローチ)/ shap.html(部分依存・解釈可能性)。 「スプライン」「GLM 一般」の単独ページは未整備のため本文の該当節を参照。