この教材は原論文と同じデータを読み込み、同じ手順で計算し直しています。画面に出る数値と図は、あなたのブラウザがその場で計算した結果です。
| 原論文が使ったデータ | SSDSE-B・日本銀行・Federal Reserve Board・Yahoo! Finance・県民経済計算 分析単位:都道府県 中核手法:ニューラルネットワーク・SHAP |
|---|---|
| この教材が使うデータ |
|
| 原論文(PDF) | 景気の変動要因と景気の変動による影響の分析 審査員奨励賞/佐々木 俊輔、鈴木 櫂人(東京都立大泉高等学校) |
▶ ここに書いてある分析は、ページ下部の「🐍 ブラウザで動かす」でそのまま実行できます(インストール不要)。動かしているのは code/2022_H5_6_shorei.py(305 行)そのものです。
このページで実再現できるのは図1・図2・図3(有効求人倍率とその説明変数のうち SSDSE-B に収録されている分)です。コードの編集は不要です。(原論文の中心である回帰型NN+SHAPの数値、および景気指標 NYダウ・米FRB金利などは再現できないため、図4は原論文の報告値を可視化します。)
data/raw/ フォルダに入れます。html/figures/ に自動保存されます。SSDSE-B 収録外の指標(NYダウ・米FRB金利など)とモデル性能はスクリプト内に原論文の報告値を転記して可視化します。
著者たちは東京都立大泉高校の生徒である。研究の背景には円安の進行があり、原論文は「令和4年9月5日現在、1ドル=140.42円」と、当時の厳しい日本経済の状況を出発点にしている。
景気の良し悪しを測る代表的な指標のひとつが有効求人倍率(有効求人数を有効求職者数で割った値)である。この値が高いほど「人手を求める企業が多い=景気が良い」と読める。そこで著者は「有効求人倍率を高めるには、どの要素が効いているのか」を突き止めようとした。ただし関係は複雑に絡むと考え、単純な回帰ではなく表現力の高い予測モデル(ニューラルネットワーク)を作り、その中身を SHAP で開けるという二段構えの発想を採った。
高校生の部 SSDSE-B+日銀・FRB・Yahoo! Finance・内閣府 回帰型ニューラルネットワーク SHAP(説明可能AI) 相関分析
原論文は2005〜2019年・47都道府県のパネル(N=705)を組み、40以上の指標を説明変数に使っている。多くは人口・世帯・教育・消費といった SSDSE 由来の指標だが、景気指標(ドル円為替・日銀金利・米FRB金利・日経平均・NYダウ)は日本銀行・FRB・Yahoo! Financeから、県内総生産は内閣府「県民経済計算」から補っている。景気指標は47都道府県で同じ値を用いる全国共通の系列である。
| 役割 | データ | 出典 | 本ページでの扱い |
|---|---|---|---|
| 目的量 | 月間有効求人倍率(一般)=求人数/求職者数 | SSDSE-B-2022・SSDSE-2019B | 実再現(F3103/F3102) |
| 人口構成 | 男性割合・15歳未満/15〜64歳/65歳以上人口割合 | SSDSE-B | 実再現 |
| 行動 | 一般旅券発行件数・合計特殊出生率 | SSDSE-B | 実再現 |
| 消費 | 食料費・保健医療費ほか(二人以上の世帯) | SSDSE-B | 実再現 |
| 景気指標 | NYダウ・米FRB金利・日経平均・ドル円・日銀金利 | 日本銀行・FRB・Yahoo! Finance | 報告値の可視化(SSDSE未収録) |
| 経済規模 | 県内総生産(名目) | 内閣府 県民経済計算 | 使用しない(SSDSE-B未収録) |
| モデル性能 | 損失・決定係数 R²=0.939、SHAP貢献度 | 原論文の推定結果 | 報告値の可視化(再計算不可) |
F3103 月間有効求人数/F3102 月間有効求職者数 から計算でき、年齢構成・一般旅券発行件数・消費支出も SSDSE-B に列がある。そこで図1(有効求人倍率の推移)・図2(年齢構成との関係)・図3(各説明変数との相関)をSSDSE-B の実データで再計算する。原論文が SHAP で示した符号の主張を、単純な相関係数で追試する位置づけである。各年・各都道府県の月間有効求人倍率(一般)を目的変数に、人口・世帯・教育・消費・景気指標など多数の指標を説明変数として並べる。人数系の指標は総人口で割って規模の違いをそろえ、N=705を訓練60%・検証20%・テスト20%に分けたうえで標準化(平均0・分散1)する。
全結合層のみの回帰型ニューラルネットワークを PyTorch で組む。活性化関数は Mish(ReLUに似た滑らかな曲線)、損失は平均二乗誤差に L2正則化を足したもの。最適化は精度が最も安定した AdaGrad を選び、中間層16・ノード41・正則化係数0.002・バッチ3・学習率0.01・150エポックで学習した。
SHAP(SHapley Additive exPlanations)は、モデルの各予測に対してどの説明変数がどれだけ効いたかを定量化する説明可能AIの手法。NNには DeepExplainer を用い、各説明変数の貢献度(重要度)と、予測値との相関の向きを可視化する。
SHAP の結果から、社会・経済(米国株・金利)、生活環境(消費)、教育、人口構成の各分野で、有効求人倍率に効く要因を読み解く。
目的変数の有効求人倍率と、SSDSEに収録された説明変数(年齢構成・一般旅券発行件数・消費)について、実データで推移と相関を確かめる。SHAPの数値そのものは再現できないため、原論文の符号の主張を単純相関で追試する。
研究の主役は目的変数の有効求人倍率である。まずこの指標が景気の波をどう映すかを、SSDSE-Bで全国について実再現する。ここは都道府県データから計算できる実再現部分である。
skiprows=[1] で読み込み、F3103 月間有効求人数・F3102 月間有効求職者数・年齢別人口・一般旅券発行件数・消費支出を数値化する。そこから目的変数の有効求人倍率(F3103/F3102)と、男性割合・年齢構成・旅券発行率などの説明変数を作る。72 73 74 75 76 77 78 79 80 81 82 83 84 85 | df = pd.read_csv(DATA_B, encoding='cp932', skiprows=[1]) NUM_COLS = ['F3103', 'F3102', 'A1101', 'A110101', 'A1301', 'A1302', 'A1303', 'A4103', 'G5105', 'L322101', 'L322106'] for c in NUM_COLS: df[c] = pd.to_numeric(df[c], errors='coerce') df['年度'] = df['SSDSE-B-2026'].astype(int) # 指標づくり(SSDSE-B に実在する列だけを使用) df['有効求人倍率'] = df['F3103'] / df['F3102'] # 月間有効求人数 / 月間有効求職者数 df['男性割合'] = df['A110101'] / df['A1101'] * 100 # 総人口に占める男性の割合 df['若年割合'] = df['A1301'] / df['A1101'] * 100 # 15歳未満人口割合 df['生産年齢割合'] = df['A1302'] / df['A1101'] * 100 # 15〜64歳人口割合 df['高齢割合'] = df['A1303'] / df['A1101'] * 100 # 65歳以上人口割合 df['旅券発行率'] = df['G5105'] / df['A1101'] * 1000 # 一般旅券発行件数(人口千人あたり) |
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | nat = (df.dropna(subset=['F3103', 'F3102']) .groupby('年度') .apply(lambda g: g['F3103'].sum() / g['F3102'].sum()) .rename('全国有効求人倍率') .reset_index()) band = (df.dropna(subset=['有効求人倍率']) .groupby('年度')['有効求人倍率'] .agg(['min', 'max']).reset_index()) years = nat['年度'].values peak_year = int(nat.loc[nat['全国有効求人倍率'].idxmax(), '年度']) peak_val = nat['全国有効求人倍率'].max() val_2012 = nat['全国有効求人倍率'].iloc[0] val_2020 = float(nat.loc[nat['年度'] == 2020, '全国有効求人倍率'].values[0]) print(f"対象年度: {years.min()}〜{years.max()}({len(years)}か年)") print(f"全国の有効求人倍率: {val_2012:.3f}({years.min()}年) → ピーク {peak_val:.3f}({peak_year}年)") |
=== [1] 月間有効求人倍率(一般)の推移(全国, 実再現) === 対象年度: 2012〜2023(12か年) 全国の有効求人倍率: 0.708(2012年) → ピーク 1.517(2018年) コロナ禍の 2020年に 1.056 まで低下(景気後退を反映)
原論文の主張のうち直感に反するのが「65歳以上割合は正・15〜64歳割合は負」である。これをSSDSE-Bの実データで検証する。
scipy.stats.pearsonr で求める。原論文の「65歳以上は正・15〜64歳は負」という一見不思議な主張を実データで検証する。140 141 142 143 144 145 | d23 = df[df['SSDSE-B-2026'] == 2023].dropna(subset=['有効求人倍率']).copy() r_old, p_old = stats.pearsonr(d23['有効求人倍率'], d23['高齢割合']) r_work, p_work = stats.pearsonr(d23['有効求人倍率'], d23['生産年齢割合']) print(f"標本数 N = {len(d23)} 都道府県(2023年)") print(f"有効求人倍率 × 65歳以上人口割合 : r = {r_old:+.4f}(p = {p_old:.4f})… 原論文の報告は正 → 符号一致") print(f"有効求人倍率 × 15〜64歳人口割合 : r = {r_work:+.4f}(p = {p_work:.4f})… 原論文の報告は負 → 符号一致") |
=== [2] 有効求人倍率 × 年齢構成(2023年・47都道府県, 実再現) === 標本数 N = 47 都道府県(2023年) 有効求人倍率 × 65歳以上人口割合 : r = +0.2871(p = 0.0504)… 原論文の報告は正 → 符号一致 有効求人倍率 × 15〜64歳人口割合 : r = -0.3129(p = 0.0323)… 原論文の報告は負 → 符号一致
原論文がSHAPで示した符号の主張を、SSDSE-B収録の説明変数について単純相関で追試する。SHAPの数値そのものは再現できないため、あくまで符号の照合である。
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | CORR_VARS = [ ('65歳以上人口割合', '高齢割合', '+'), ('合計特殊出生率', 'A4103', None), ('総人口に占める男性割合', '男性割合', '+'), ('食料費(二人以上世帯)', 'L322101', '+'), ('保健医療費(二人以上世帯)', 'L322106', None), ('15歳未満人口割合', '若年割合', None), ('15〜64歳人口割合', '生産年齢割合', '-'), ('一般旅券発行件数(率)', '旅券発行率', '-'), ] rows3 = [] print(f"{'説明変数':<26}{'相関係数':>9}{'p値':>9} 原論文SHAPの符号 / 一致") for name, col, reported in CORR_VARS: dd = d23.dropna(subset=[col]) r, p = stats.pearsonr(dd['有効求人倍率'], dd[col]) if reported is None: judge = '(報告なし)' else: same = (reported == '+' and r > 0) or (reported == '-' and r < 0) judge = f'報告={reported} → ' + ('符号一致' if same else '符号不一致') print(f"{name:<26}{r:>+9.3f}{p:>9.3f} {judge}") rows3.append((name, r, p, reported)) |
=== [3] 有効求人倍率と各説明変数のピアソン相関(2023年・47都道府県, 実再現) === 説明変数 相関係数 p値 原論文SHAPの符号 / 一致 65歳以上人口割合 +0.287 0.050 報告=+ → 符号一致 合計特殊出生率 +0.298 0.042 (報告なし) 総人口に占める男性割合 +0.022 0.885 報告=+ → 符号一致 食料費(二人以上世帯) -0.222 0.133 報告=+ → 符号不一致 保健医療費(二人以上世帯) -0.310 0.034 (報告なし) 15歳未満人口割合 -0.017 0.908 (報告なし) 15〜64歳人口割合 -0.313 0.032 報告=- → 符号一致 一般旅券発行件数(率) -0.356 0.014 報告=- → 符号一致
ここからが原論文の中心である回帰型NN+SHAPの成果。これらはモデルの完全一致が必要で、景気指標はSSDSE-Bに無いため、原論文の報告値を転記して可視化する(再計算ではない)。
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | LOSS = [('train(訓練)', 0.00642), ('validation(検証)', 0.0101), ('test(テスト)', 0.0104)] R2 = 0.939 print("予測モデルの損失(報告値):") for name, v in LOSS: print(f" {name:<20}{v:.5f}") print(f"テストデータの決定係数 R² = {R2}(報告値)") # SHAP で報告された相関の「向き」(符号のみ。大きさは原論文に数値報告なし) DIRECTION = [ ('NYダウ平均株価', +1, '強い正(SSDSE未収録)'), ('米FRB金利', +1, '強い正(SSDSE未収録)'), ('総人口に占める男性割合', +1, '正・貢献度高'), ('65歳以上人口割合', +1, '正'), ('食料費(消費支出系)', +1, '正'), ('15〜64歳人口割合', -1, '負'), ('一般旅券発行件数', -1, '負'), ] print("\nSHAP で報告された相関の向き(符号のみ・大きさは数値報告なし):") for name, sign, note in DIRECTION: print(f" {name:<20}{'+' if sign > 0 else '−'} {note}") print("※NYダウ・米FRB金利・日経平均・ドル円・日銀金利・県内総生産は SSDSE-B に無く再計算不可") |
=== [4] 原論文の報告値:モデル性能とSHAPの相関の向き === 予測モデルの損失(報告値): train(訓練) 0.00642 validation(検証) 0.01010 test(テスト) 0.01040 テストデータの決定係数 R² = 0.939(報告値) SHAP で報告された相関の向き(符号のみ・大きさは数値報告なし): NYダウ平均株価 + 強い正(SSDSE未収録) 米FRB金利 + 強い正(SSDSE未収録) 総人口に占める男性割合 + 正・貢献度高 65歳以上人口割合 + 正 食料費(消費支出系) + 正 15〜64歳人口割合 − 負 一般旅券発行件数 − 負 ※NYダウ・米FRB金利・日経平均・ドル円・日銀金利・県内総生産は SSDSE-B に無く再計算不可
SHAPの結果から、著者は分野ごとに有効求人倍率に効く要因を読み解いた(原論文 5章)。要点を整理する。
全説明変数の中でもNYダウ平均株価・米FRB金利が強い正の相関を示した。著者は、米国が日本の2番目の輸出入相手国であり、日本が2019年に世界最大の対米投資国となった(図5・外務省)ことを挙げ、日米の経済的な結びつきの強さが有効求人倍率=景気に表れていると解釈する。
有効求人倍率は65歳以上割合と正・15〜64歳割合と負の関係にある。求職者数が生産年齢人口と密接なため、定義上こうした逆符号が生じると説明する(本ページ図2で符号一致を確認)。さらに総人口の男性割合の貢献度が高く正で、著者は「男性割合が高い地域ほど景気が良い=明らかな男女格差」と読み、女性の社会進出の促進が景気にも良い影響を与えると提言する。
保健医療費・住居費・被服費などの貢献度は小さい。生活に不可欠な費用は景気の良し悪しに左右されにくいためと考えられる。一方、消費支出の中では食料費の貢献度が高く正で、好景気だと外食などのサービス消費が増えるためと解釈する。教育費も景気にあまり左右されないことが示された。
一般旅券発行件数は有効求人倍率と負の相関。著者は2008年のリーマンショック直後に円高が進み、不景気なのに海外旅行者が増えた例を挙げ、同様の要因(不景気・円高で海外旅行が増える)が働いていると考察する(本ページ図3で符号一致を確認)。
本研究は、景気の指標である有効求人倍率を高める要因は何かという問いに、回帰型ニューラルネットワーク+SHAPで挑んだ。テストの決定係数 R²=0.939(報告値)という高精度モデルを作り、その中身をSHAPで開けて、NYダウ・米FRB金利の強い正の相関(米国連動)、男性割合の正(男女格差)、65歳以上は正・15〜64歳は負、一般旅券発行件数の負などを読み取った(いずれも報告値)。本ページでは、目的変数の有効求人倍率(図1)、年齢構成との関係(図2)、各説明変数との相関(図3)をSSDSE-Bで実再現し、SHAPの符号の主張の多くが実データでも成り立つことを確かめた。モデル性能と景気指標は報告値として切り分けた。高校生が「予測してから中身を説明する」現代的な分析に踏み込んだ点が見どころである。
このページの実再現の図(図1〜図3)は、以下から再現できます。
🐍 再現コード(.py) 📊 SSDSE-B-2026.csv
※ 図1(有効求人倍率の推移)・図2(年齢構成との関係)・図3(各説明変数との相関)はSSDSE-B の F3103/F3102 ほかから算出した実再現です。図4(モデル性能とSHAPの相関の向き)は、回帰型NN+SHAPの数値と景気指標(NYダウ・米FRB金利など)がモデル依存・SSDSE-B外のため、原論文の報告値を可視化したものです(新たな数値の捏造はしていません)。県内総生産(GDP)などSSDSE-Bに無い列は使用していません。
この研究を読むとき・まねするときに陥りやすい誤解を整理する。
F3103 月間有効求人数 を F3102 月間有効求職者数 で割って自分で作る。既製の指標に頼らず、実在する列から指標を組み立てるのがデータ加工の基本。クリックすると各用語の詳しい解説ページに移動できます。
この研究で使われている手法を、手を動かす順に説明する。
この研究の「有効求人倍率は米国経済や人口構成に強く関連する」という結論は、次の研究の出発点になる。
再現コードを少し変えるだけで試せる課題を、易しい順に用意した。
df[df['SSDSE-B-2026']==2023] で2023年を選んでいる。ここを2019年や2020年に変えて、有効求人倍率の高い県・低い県を並べてみよう。「高精度モデルを作り、SHAPで理由を説明する」発想は、金融・製造・医療で広く使われている。
この研究を読んで浮かびやすい疑問に答える。
この論文を理解できたか、クリックで確認しましょう。間違えても解説が出ます。
このページの分析は、この画面の中でそのまま実行できます。
Python をインストールする必要も、CSV をダウンロードする必要もありません。
下のセルの 「▶ ブラウザで実行」 を上から順に押すか、
「▶ 最初から全部実行」 で一気に流してください。
表示されるのは、本文の図表とまったく同じ計算の結果です
(動かしているのは再現スクリプト code/2022_H5_6_shorei.py そのもの)。
コードは書き換えられます。「✏️ 書き換える」で数字や変数を変えて ▶ を押すと、 結果がどう変わるかをその場で確かめられます(元に戻すボタンつき)。 ページを開いた時点で裏で実行環境の準備が始まっているので、待ち時間はほとんどありません。 初回だけ実行環境の取得にインターネット接続が必要です。