コードで読む:バラバラCSVが政策の“ギャップ”を生む仕組みと直し方

IT政策の提案
コードで読む:バラバラCSVが政策の“ギャップ”を生む仕組みと直し方

どうも〜おかむーです!今日はちょっとエンジニア寄りに、政府や自治体が公開しているCSV群を見ながら「政策の数値目標と実績のギャップ」がどこで生まれるかをコード目線で追っていきますよ〜

  • 複数省庁・自治体のCSV(例: https://notice.go.jp/docs/status_notice.csv、https://www.mhlw.go.jp/content/001682075.csv、https://www.soumu.go.jp/main_content/000323625.csv)にはスキーマ不整合が多い
  • スキーマ不整合は「単位」「日付」「地理キー」のミスマッチとなり、政策評価の誤差源になる
  • エンジニア的対処は「スキーマ辞書」「自動正規化パイプライン」「機械可読な目標の公開」

結論

データそのものが“同じことを示している”とは限らないんですよね。CSVの列名や単位、日付フォーマット、行政区画コードが揃っていないだけで、政策の数値目標と実績を比較する作業はノイズだらけになる。要するに、まずは“比較できる土俵”をコードで作ることが先決です。

レポート本文

問題の現場観 — これ見てくださいよ

複数の公開CSV(例: notice.go.jp のNOTICE一覧、総務省の全国CSV、厚労省の救護施設CSV)をざっと見ると、よくある不整合が目立ちます。

  • 日付: yyyy-mm-dd、yyyy/mm/dd、和暦混在、タイムゾーン不明
  • 地理: 都道府県名の表記ゆれ(例: "茨城県" vs "茨城")、JISコード未使用
  • 単位: 数量が「人」「名」「件」で混在、単位の注記もなし
  • メタデータ不足: 更新日時、生成プロセス、責任窓口がCSVに埋め込まれていない

エンジニア的に言うと、これAPI一本で解決する話なんですよね。とは言え、現状はバラバラのCSVをスキーマオンリードでつないでいく必要があります。

技術検証: 典型的なパイプライン

ここで実際にやることをコード例で示します(Python/pandasベース)。要点は「読み取り時にメタデータを付与し、正規化ルールを適用する」ことです。

import pandas as pd

from dateutil import parser

CSVを読み込み時にエンコーディングを推定して開くのが現実的

df = pd.read_csv('https://www.mhlw.go.jp/content/001682075.csv', encoding='cp932')

カラム正規化マップ

col_map = {'施設名':'name','収容人数':'capacity','都道府県':'prefecture','更新日':'updated_at'}

df = df.rename(columns=col_map)

日付パース

df['updated_at'] = df['updated_at'].apply(lambda x: parser.parse(x))

単位の揃え(例: 人数の欠損や文字列を数値に)

df['capacity'] = pd.to_numeric(df['capacity'], errors='coerce')

地理キーをJISコードにマップする(別テーブル)

prefecture_map = { '茨城県':8, ... }

df['pref_code'] = df['prefecture'].map(prefecture_map)

要するに、こうした前処理を一箇所で定義できると後続処理での誤差が劇的に減ります。

政策評価の“ギャップ”をどう計るか

政策側の数値目標(例: 避難所収容率90%)と現場データを比較するには、

  • 目標を機械可読にする(JSONで「target:90, denom:population, geography:prefecture」みたいに)
  • データを正規化して同じ指標を算出(単位、期間、母数を合わせる)
  • 差分と不確実性(データの欠損率や最終更新差)を定量化
  • 差分算出の例(疑似コード):

    # target_json を政策サーバーから取得
    

    target = { 'pref_code':8, 'indicator':'capacity_rate', 'target_value':0.9 }

    observed = df.groupby('pref_code')['capacity'].sum() / population_by_pref

    gap = target_value - observed[target['pref_code']]

    ただし観測値の不確実性を可視化するために、欠損率や最終更新日差を一緒に伝えるべきです。

    改善提案(技術的)

    • 各CSVに小さな機械可読ヘッダを追加:JSON-LDやdatapackage.jsonでスキーマ/単位/更新日を明記
    • 都道府県はJISコードで必須化、日付はISO8601で統一
    • 政策目標もAPI化して、目標のメタデータ(期間・分母・算出方法)を公開
    • CIでCSVスキーマチェックを回す(GitHub Actions + yamale/jsonschema)
    • 簡易ライブラリ(pandasベース)を各自治体で共有して、正規化ルールを共通にする

    サンプルのメタデータスニペット(datapackage.json風):

    {
    

    "name": "mhlw-shelters",

    "resources": [{"path":"001682075.csv","schema":{ "fields":[{"name":"pref_code","type":"integer"},{"name":"capacity","type":"integer","unit":"people"}]}}]

    }

    まとめ

    • CSVの表面上の数値は“比較可能”とは限らない。列名・単位・地理キー・日付の不整合が政策評価の雑音を生む
    • エンジニア的には「機械可読メタデータ」と「正規化パイプライン」で解決可能
    • 最終的には政策目標も機械可読にして、評価までを自動化するのが理想

    おかむーから一言

    テクノロジーで社会をアップデートするってのは、データの細かい“揺れ”を丁寧に潰していく作業なんですよね。コードで土台を作れば、政策の議論がもっと実になる!

    シェアする