Section 1
なぜ「23区の保育データ」を比較できないのか
「入りやすさが制度変更でどう動いたか」のような問いに答えるには、区をまたいだ同じ粒度・同じスキーマのデータが必要です。ですが現状は次の3重苦があります。
粒度がバラバラ
施設単位(定員・空き数・所在地)で出す区もあれば、区全体の待機児童数だけを集計値として出す区もあります。同じ「保育データ」でも比較可能なレベルが違います。
フォーマットがバラバラ
CSV・Excel・PDF・JSON/XML・素のHTMLが混在。文字コードもUTF-8とShift-JISが混在し、同じ列名(例:定員)でも区によって意味や単位が違うことがあります。
生成AIとの相性
この「フォーマット・粒度のバラつき」こそ、生成AIによる抽出・正規化が最も効きやすい領域です。PDFの表やHTMLの箇条書きであっても、目標スキーマを与えて読み取らせれば、人手でのデータ入力なしに構造化できます。以下は、その実践結果です。
Section 2
データの探し方 — 実は3層構造になっている
東京都・区の保育オープンデータは、1つのカタログに集約されていません。実際に23区を調査した結果、次の3つの層を順番に当たるのが最も効率的でした。
| 層 | 実体 | 注意点 |
|---|---|---|
① 東京都オープンデータカタログcatalog.data.metro.tokyo.lg.jp |
都・一部区が組織単位でCSV/GeoJSONを登録するCKANカタログ。区が直接ここにデータセットを持つケースもある(例:一部区の「子育て」データセットバンドル)。 | HTML直アクセスはAWS WAFのJSチャレンジでブロックされることがある。search.ckan.jp(横断検索ミラー)経由や、カタログのJSON API経由だと取得できることが多い。 |
② オープンデータAPIカタログspec.api.metro.tokyo.lg.jp |
①とは別建ての、区市町村のデータをJSON/XMLラッパーとして提供するカタログ。区名+「保育」等で検索すると、多くの区の一次データに辿り着ける。 | 転送形式(JSON/XML)を統一しているだけで、列名やスキーマは統一されていない。区ごとに列構成が異なる前提で読む必要がある。 |
| ③ 各区独自のオープンデータポータル/区サイト | ①②に登録がない区でも、区独自のオープンデータ推進ページや、通常の子育て支援課ページにPDF/Excelで公開されていることが多い。 | 「オープンデータ」と銘打っていないPDF/HTMLpageも実質的に唯一の一次情報であるケースが多い(例:現況の空き状況は区サイトのPDFのみ、というパターン)。 |
Section 3
どうやったか — 正規化パイプライン
23区すべてを手作業で1つずつ処理するのは非現実的なので、並列化と「捏造しない」ルールの徹底で対応しました。実際に踏んだ手順です。
23区を並列グループに分割
23区を8グループ(1グループ2〜3区)に分け、各グループを独立したLLMエージェントが並行して担当。前工程のカタログ調査で得ていた「区ごとの当たり」(データセット名・URL)を事前情報として渡し、無駄な再探索を減らしました。
3層探索 → 実データの取得
各エージェントが Section 2 の3層(都カタログ/APIカタログ/区独自ポータル)を順に当たり、見つけたCSV・Excel・PDF・HTMLを実際にダウンロード。説明文だけで済ませず、必ずファイル本体を取得させています。
スキーマへの抽出・正規化
CSV/JSONはそのままパース(Shift-JIS→UTF-8変換込み)。PDFやHTMLの表は目視で読み取り、Section 4 のスキーマに沿って手入力で構造化。列の対応関係が曖昧な場合(結合セル、複数バージョンの様式混在など)は、推測で埋めずnullのままnotesに理由を記録させました。
突き合わせ検証
可能な場合はソース側に印字された合計値(例:PDFの「合計◯◯件」という注記)と、抽出したレコードの件数を突き合わせて一致を確認。実際、江戸川区のPDFはこの方法で抽出件数とソースの印字合計が完全一致しました。一致しない・確認できないケースは正直にnotesへ記載。
マージ・集計
23区分の正規化済みJSONを1本の combined.json にマージし、区ごとのレコード件数・フォーマット内訳・欠損率を機械的に集計するスクリプトを実行。Section 5・6 の表とグラフは、すべてこのスクリプトの出力からそのまま生成しています(手作業の転記ミスが入りません)。
Section 4
統一スキーマ
23区のデータを2種類のレコード型に正規化しました。施設単位の情報と、区全体の集計・時系列情報は性質が異なるため、意図的に分けています。
① childcare_facility — 施設単位レコード
{
"ward": "港区", "ward_romaji": "Minato",
"facility_id": "区独自IDまたは生成スラッグ",
"facility_name": "string",
"facility_type": "認可保育所 | 認証保育所A型/B型 | 認可外保育施設 |
認定こども園 | 地域型保育事業 | 事業所内保育所 |
学童クラブ | 一時保育 | 病児保育 | other",
"address": "string | null", "lat": "number | null", "lon": "number | null",
"capacity_total": "number | null", "capacity_by_age": "{ \"0\":n, \"1\":n, ... } | null",
"enrolled_total": "number | null", "vacancy_count": "number | null",
"as_of_date": "YYYY-MM-DD | null", "granularity": "per_facility",
"source_format": "csv | xlsx | pdf | json | xml | html",
"source_url": "string", "source_dataset_title": "string",
"notes": "string | null — 欠損・推定・不確実性は必ずここに明記"
}
② childcare_ward_stat — 区集計・時系列レコード
{
"ward": "港区", "ward_romaji": "Minato",
"period": "YYYY-MM または YYYY年度",
"metric": "capacity_total | enrolled_total | waitlist_count | applicants | facility_count",
"value": "number", "unit": "string | null", "granularity": "ward_aggregate",
"source_format": "csv | xlsx | pdf | json | xml | html",
"source_url": "string", "source_dataset_title": "string", "notes": "string | null"
}
nullにしてnotesに理由を書く(欠損は正直な結果であり、失敗ではない)。
③PDFの表が曖昧で列の対応関係を推測しないと埋まらない場合は、無理に埋めず空欄のままにする。
Section 5
集計 — 23区の実態
23区すべてで実データを取得・正規化した結果の集計です。全体サマリーののち、23区全件の内訳表を掲載します(グラフでの可視化は次のSection 6)。
全体サマリー
4,535件
施設単位レコード(23区合計)
1,258件
区集計・時系列レコード(23区合計)
47% / 35%
定員判明率 / 緯度経度判明率(施設レコード中)
フォーマット内訳(全5,793レコード中)
構造化データ(CSV/JSON)よりPDF/HTML/Excelの方が多く、「オープンデータ」を謳っていても実際は目視転記が前提のデータが主流であることが分かります。
気になった特記事項
「待機児童ゼロ」の公式記録
千代田区(2025年度11ヶ月連続)、練馬区(2021〜2025年度5年連続)、足立区(2023年度)、葛飾区(2022〜2024年度)で、区の公式統計上ゼロという記録が見つかりました。これ自体がSection 1の「制度変更で入りやすさがどう動いたか」という問いへの重要な材料になります。
「オープンデータ」が消える/古びる
杉並区は公式オープンデータCSVページが404で消失(API経由のデータで代替)、新宿区の都カタログ登録は2017年度で更新停止、葛飾区の学童クラブCSVは2020年時点で止まっていました。オープンデータは「登録した後」のメンテナンスが弱いという構造的な傾向が見えます。
区ごとの内訳(23区全件)
| 区 | 施設件数 | 区集計件数 | 主なフォーマット | 定員判明率 | 緯度経度判明率 | 特記事項 |
|---|---|---|---|---|---|---|
| 中野区 | 441 | 8 | JSON, HTML, PDF | 54% | 53% | 23区最多の施設件数(複数データセットを合成) |
| 杉並区 | 377 | 109 | JSON, PDF | 1% | 24% | 区公式オープンデータCSVページが404で消失、API経由データで代替 |
| 江東区 | 320 | 84 | CSV, PDF | 10% | 33% | |
| 世田谷区 | 296 | 27 | HTML | 0% | 0% | 統計資料は充実もPDF中心、地区別内訳の多くは未公開 |
| 板橋区 | 295 | 148 | CSV | 0% | 53% | |
| 足立区 | 286 | 13 | CSV, Excel | 43% | 0% | 待機児童ゼロ(2023年度時点、公式アクションプラン) |
| 葛飾区 | 243 | 156 | CSV, PDF | 0% | 30% | 待機児童ゼロ(2022〜2024年度)/学童データは2020年時点で更新停止 |
| 港区 | 236 | 10 | CSV | 78% | 54% | 唯一、月次更新のCSV+GeoJSONを施設単位で公開 |
| 北区 | 221 | 7 | HTML | 100% | 0% | |
| 練馬区 | 220 | 306 | CSV, Excel | 94% | 0% | 待機児童ゼロ(2021〜2025年度、5年連続) |
| 江戸川区 | 207 | 35 | CSV, PDF | 94% | 94% | |
| 大田区 | 192 | 21 | 100% | 0% | ||
| 品川区 | 188 | 16 | 100% | 0% | ||
| 豊島区 | 149 | 100 | Excel, PDF | 93% | 93% | |
| 文京区 | 124 | 0 | CSV | 100% | 100% | 施設データはきれいなCSVだが区集計(時系列)データは未発見 |
| 目黒区 | 120 | 52 | CSV | 0% | 100% | |
| 墨田区 | 119 | 84 | HTML, PDF | 67% | 0% | |
| 中央区 | 103 | 3 | CSV | 89% | 100% | |
| 新宿区 | 98 | 9 | 0% | 0% | 公式カタログ登録は2017年度で更新停止、現況はPDFのみ | |
| 台東区 | 87 | 20 | CSV | 80% | 83% | |
| 渋谷区 | 84 | 39 | HTML, PDF | 8% | 0% | |
| 荒川区 | 83 | 0 | CSV, HTML | 0% | 84% | 当初サーベイでは見落とされていたCKANデータセットを追加調査で発見・訂正 |
| 千代田区 | 46 | 11 | 100% | 0% | 待機児童ゼロ(2025年度11ヶ月連続、公式統計) |
出典URL・欠損理由はデータセット内の source_url / notes フィールドに区・レコード単位で記録されています。
Section 6
可視化(グラフ)
上の表と同じデータを、2本のグラフで見せます。棒の実際の値はホバー(フォーマット内訳)または右側の数値ラベルで確認できます。色の意味が分かりにくい場合は、上のSection 5の表を参照してください。
区ごとの施設件数 × フォーマット構成(施設件数の多い順)
棒の長さ=施設件数(中野区441件を100%とした相対値)。色の内訳=その区のソースフォーマット構成。セグメントにカーソルを合わせると件数が表示されます。
区ごとの定員判明率(データの充実度、高い順)
「空き数だけ公開・定員は非公開」という区が多いことが分かります。単一系列のため色は1色(判明率)で統一しています。
Section 7
データを使う
この正規化データセットとスキーマ定義をそのまま公開します。同じ探索・抽出をゼロからやり直す必要はありません。
正規化済みデータセット(23区統合)
4,535施設レコード + 1,258区集計レコード。JSON、UTF-8。
スキーマ定義書
上記データセットの元になった正規化ルール(Markdown)。
source_urlが実際の一次情報源であり、区ごとにライセンス条件(多くはCC BY 4.0だが、区によって個別規約が優先される場合あり)が異なります。再配布・成果物への組み込みの際は、レコードごとのsource_urlを辿って一次情報源のライセンス表記ルールに従ってください。本サイトはあくまで「取得・正規化の手間を省く」ための中間成果物です。
本ページは1参加者(門戸良介)が個人の立場で作成した非公式コンテンツです。東京都・GovTech東京・ハッカソン事務局の公式資料ではありません。掲載データは2026年7月時点で各区の公開情報から取得したものであり、最新の値・URL・ライセンス条件は必ず各データ提供元の一次情報でご確認ください。抽出過程で読み取れなかった項目は正直にnullとしており、憶測で埋めた値はありません。