設計図 — どう作り、何を確かめたか
1. 何を測ったら作れると判断したか
実装仕様書は、漁港の位置を「海しる API」から、漁業統計を「e-Stat API」から取る前提だった。 どちらも認証キーが要る。キー無しで実際に叩いたところ、海しるは 404、e-Stat は 「認証に失敗しました」を返した。そこで仕様書の前提を実測で置き換えている。
- 漁港の位置と区域 — 国土数値情報「漁港データ」(C09)が、 点 2,931 件と区域線 3,292 本を鍵なしで配っている。海しるの代わりになる
- 漁港マスタ — 水産庁「漁港一覧」の都道府県別 PDF 40 本。 港名・読み・種別・所在地・管理者・漁協・指定年月日まで載っている
- 漁業統計 — 代わりが無い。V1.0 では出さず、欄を「未取得」で残す
2. PDF をどう読んだか
明細 PDF は横罫の無い表である。表抽出にかけると、列ごとに全行を改行で連結した 「1 行の表」が返り、疎な列(分区・海岸保全区域)は空セルが落ちて行と対応しなくなる。 そこで表抽出は使わず、罫線の座標から列境界を取り、文字を 1 字ずつ列へ割り当てた。
語単位ではうまくいかない。隣り合う列のあいだに空白が無いので、1110050斜内 のように列をまたいだ 1 語ができる (秋田県の PDF で漁港番号が 1 件も取れなかった)。文字単位なら、各文字の x で列が一意に決まる。
行高も一定ではなかった。北海道の「内路」は漁協が 2 つ(香深・船泊)で 2 行になり、 漁港番号はその 2 行のあいだに置かれている。等間隔でバンドを切ると 番号が 2 つ入る行ができる。隣り合う番号行の中点を境界にして解決した。
3. 何を正解として突き合わせたか
明細から作った表を、明細を数えた値で検査しても何も分からない。明細とは別の 2 枚の文書を正解に使っている。
- 総括表(sub81-256.pdf) — 種別ごとの全国計と、 特定第3種 13 港の港名
- 都道府県別集計(sub81-257.pdf) — 都道府県 × 種別 × 管理者区分
照合したのは 4 系統で、すべて一致した。
- 総数 2,768 港
- 種別内訳(第1種 2,031 ほか)
- 都道府県 40 件それぞれの港数・種別内訳・管理者内訳
- 特定第3種の港名の集合
3 番目は、明細の「漁港管理者」欄の文字列から 「都道府県が管理者か市町村か」を導いて突き合わせている。導出規則そのものを 外部の数が検算している形になる。
4. 通説がひとつ壊れた
都道府県別集計の「第3種」列は 114 で、総括表の第3種 101 と合わない。 実測すると 101 + 特定第3種 13 = 114 で、都道府県別表の第3種は特定第3種を含んでいる。 実装仕様書の種別表にはこの注意が無い。照合を書くときに気づいた。
5. 座標をどこまで信じるか
マスタは令和8年、座標は平成18年である。番号が一致しても、20 年のあいだに 統廃合・改称で別の港に振り替わっていることがある。実測すると、番号が一致した 2,676 港のうち 68 港は港名が違った。そこで突合を段階に分け、 港ごとにどの段階で座標が付いたかを残している(詳細画面の「座標」欄)。
国土数値情報の側も内側で整合していない。漁港番号が重複する 30 コードがあり、 重複行では港名・管理者・指定年月日が別の港のものに置き換わっている (1410690「宇島」が福岡県豊前市と宮城県石巻市の 2 点を持つ)。 重複コードは、市区町村コードの上 2 桁が都道府県と一致する候補が ちょうど 1 つのときだけ採っている。
区域線から重心を取る最後の段階には、同じ県の既知座標の外接矩形という ガードを置いた。飾りではない —— 石川県「中島」(2410125)の区域線が 35.611N/134.467E(石川県の外ではるか西)を指しており、このガードが実際に落とした。
結果、座標が付いたのは 2,721 港 (98.30%)である。残りは座標なしと明示して一覧から辿れるようにした。 うち 20 港は滋賀県で、国土数値情報の平成18年度版は滋賀県の漁港を 1 件も含まない。
6. 欠損を 0 で埋めない
値が無い欄は null にし、なぜ無いかをobserved / estimated / suppressed /not_available / not_applicable /missing_source の語彙で区別している。 画面では「データなし」「対象外」「未取得」と出し分ける。 0 と書けば、読み手はそこに 0 があったと受け取る。
7. その後に足したもの
- 海の温度 —— 気象庁の沿岸海域 107 の海面水温を 1982 年から通しで測った。 港と海域の対応は、海域名から引く規則が偽の一致を出したので付けていない
- AI —— 「公式の種別は、交付税の算定に使う施設延長で読めるのか」を、 実測の前に決めた合格ラインと予想で測った。ニューラルネットは、 同じ交差検証で最良の非ニューラルネットに勝ったときだけ出す。 読めなかった結果も、外れた予想も、そのまま出している。 最初の版は国土数値情報のメタデータを読まずに施設延長を「施設の規模」と呼び、 欠測の印である 0(八戸にも付いている)を値として学習していた。0 の港を外して学習し直すと、 合格ラインを動かさないまま答えが「読めない」(差 0.128)から「読める」(差 0.233)に変わった
- 似た港とクラスタ —— 施設延長と属性が近い 10 港を、特徴に入れていない公式の種別の一致で確かめた (無作為より 0.156 高い)。ただし施設延長だけで選ぶと上位 10 港は平均 7.6% しか重ならないので、 使った特徴と一緒に出している。クラスタは実測前に決めた条件を k=3 で満たしたが、中身を読むと 有人国境離島と海岸保全区域◎の二つの印で切れていた(ARI 0.980)ので、港の「型」とは呼んでいない
- 津波浸水想定 —— 実装仕様書は「漁港の点が浸水想定の区域の中にあるか」を 出すと書いていた。福井県で測ると、44 港のうち区域の中にあるのは 2 港だけで、残り 42 港は 区域の外(区域まで中央値 47 m)だった。港の代表点は水際にあり、陸を覆う区域の外に落ちる。 そのまま出せば偽の「区域外」になるので、内外は出さず、半径 100 / 200 / 500 m の円に 掛かる区域の最大浸水深区分を並べて出している。半径を一つに決めないのは、 福井県で半径 100 m から 200 m に広げると 17 港の区分が変わったから —— 選んだ半径が答えを決めてしまう
実装仕様書が想定した AI(魚種構成や水揚げ時系列の Autoencoder・予測)は、 港別の水揚げ・魚種が公開されていないので作っていない。