日本郵便の郵便番号データ ken_all をどうにかする

f:id:Naotsugu:20200216034407p:plain


はじめに

郵便番号の入力に応じて、都道府県や市区町村を入力補完したいといったよくあるユースケースがあります。 このときに辞書データの候補となるのが、日本郵便の公開する郵便番号データ ken_all.csv です。

しかしこのデータは悪評高きことで有名で、システムで使うには泥臭い整形が多数必要になります。

ここでは、この郵便番号データをどうにかする方法について見ていきます。


郵便番号と住所の割当についての注意点

郵便番号データ自体とは関係ないのですが、郵便番号を扱う際にの注意点があります。

知らない人にとっては驚きですが、同じ郵便番号だったとしても、市区町村どころか都道府県すらもまたぐケースがあります。

例えば、498-0000 は、三重県と愛知県で同じ郵便番号が割り当てられている地域があります。

"4980000",・・,"三重県","桑名郡木曽岬町,・・
"4980000",・・,"愛知県","弥富市",・・

もちろん都道府県だけではなく、町域や市区町村は、普通にまたいで同じ郵便番号が割り当てられる場合があります。なので、郵便番号が決定しても、住所を一意に特定することはできないという点は覚えておく必要があります。

郵便番号は単に配送のための番号であり、地形や運送上の理由により地域区分局が異なる地域を配送範囲に含めていたり、市区町村の合併や、支店・集配センターの統廃合などの都合で定期的に変更されるものなのです。


郵便番号データのカラム定義

最も良く使われる、郵便番号データダウンロードの「読み仮名データの促音・拗音を小書きで表記するもの」を対象に見ていきます。

このファイルのレイアウトは以下のように定義されています。

Index 項目
0 全国地方公共団体コード
1 (旧)郵便番号(5桁)
2 郵便番号(7桁)
3 都道府県名カナ
4 市区町村名カナ
5 町域名カナ
6 都道府県名
7 市区町村名
8 町域名
9 一町域が二以上の郵便番号で表される場合の表示 (1は該当, 0は該当せず)
10 小字毎に番地が起番されている町域の表示 (1は該当, 0は該当せず)
11 丁目を有する町域の場合の表示 (1は該当, 0は該当せず)
12 一つの郵便番号で二以上の町域を表す場合の表示 (1は該当, 0は該当せず)
13 更新の表示
14 変更理由


ファイル中には以下のようなレコードが12万レコードほど格納されています。

13103,"106  ","1060045","トウキョウト","ミナトク","アザブジュウバン","東京都","港区","麻布十番",0,0,1,0,0,0


複数行に分割されるレコード

郵便番号データには、前時代的な以下のような仕様が存在します。

全角となっている町域部分の文字数が38文字を越える場合、また半角となっているフリガナ部分の文字数が76文字を越える場合は、複数レコードに分割しています。

実データとしては以下のような感じで複数行への分割が行われることになります。

・・,"0330072",・・,"青森県","上北郡六戸町","折茂(今熊「213~234、240、247、262、266、27",1,1,0,0,0,0
・・,"0330072",・・,"青森県","上北郡六戸町","5、277、280、295、1199、1206、1504を除く」、",1,1,0,0,0,0
・・,"0330072",・・,"青森県","上北郡六戸町","大原、沖山、上折茂「1-13、71-192を除く」)",1,1,0,0,0,0

郵便番号データを扱うためには、まず分割されたレコードを識別する必要があります。


分割は38文字で次レコードにいくかというとそうではなく、35 文字で分割されていたり、32 文字で分割されていたりと様々です。

レコード分割されているかどうかは、レコード末尾のフラグなどで判断できるものでもなく、唯一の手段として、 が始まり で終わるまでが分割されたレコードと判定するしかありません。

幸い (・・) がネストされるケースはなく、ネストするような場合は (・・) の中に 「・・」 で記載されている点は統一されています。

なお、(・・) がネストされるケースは存在しませんが、"名駅ミッドランドスクエア(高層棟)(1階)" のように (・・) が連続して発生するレコードは存在します。


カナについても同じ様に (...) で分割されていると判断できます。

・・,"9620211","フクシマケン","スカガワシ","タキ(アカツチ、ガンダ、キタクボ、シラスナ、シラスナヤマ、ダイシンバタ、ダイニチマエ、タキニシ、チャクノシタ、","福島県","須賀川市","滝(赤土、雁田、・・"
・・,"9620211","フクシマケン","スカガワシ","ヒナタマエ、ホンゴウ、マエタ)","福島県","須賀川市","日向前、本郷、前田)"

しかし中には、町域名が分割されていたとしても、町域名カナは以下のように "ムカデヤチョウ" とだけ記載されているケースもあるため、町域の分割がすなわち町域名カナの分割にはならないので注意が必要です。

・・,"6048214","キョウトフ","キョウトシナカギョウク","ムカデヤチョウ","京都府","京都市中京区","百足屋町(新町通蛸薬師下る、新町通錦小路上る、・・",・・
・・,"6048214","キョウトフ","キョウトシナカギョウク","ムカデヤチョウ","京都府","京都市中京区","通新町西入、錦小路通新町東入)",・・


町域名の編集

町域名のカラムには町域名自体ではなく、人間向けの補足説明が文字として掲載されているため、住所データとして使う場合には、これらの文字を削除してあげる必要があります。


"以下に掲載がない場合"

以下のような "以下に掲載がない場合" という文字が入ったレコードが 1,874 件程存在します。

・・,"9636300",・・,"福島県","石川郡玉川村","以下に掲載がない場合",・・

このようなケースでは、町域名の内容を削除すれば良いでしょう。


"・・の次に番地がくる場合"

同じように、"・・の次に番地がくる場合" という文字が入ったレコードが 17レコード件程存在します。

・・,"6492211",・・,"和歌山県","西牟婁郡白浜町","白浜町の次に番地がくる場合",・・

これも町域名を削除すれば良いでしょう。


"・・一円"

"・・一円" という文字が入ったレコードが 23 件ほど存在します。

・・,"3994511",・・,"長野県","上伊那郡南箕輪村","南箕輪村一円",・・

この場合も、町域名を削除します。

ただし、本当に 一円 という町域も存在するので、このような場合は町域名として残す必要があります。

・・,"5220317",・・,"滋賀県","犬上郡多賀町","一円",・・


カンマ区切りされた町域名

甲、乙 と、カンマ区切りの町域表記が 11 レコードあります。

・・,"7614104",・・,"香川県","小豆郡土庄町","甲、乙(吉ケ浦)",・・
・・,"7614101",・・,"香川県","小豆郡土庄町","甲、乙(その他)",・・

小豆郡土庄町 甲 と 、小豆郡土庄町 乙(吉ケ浦) として捉えればよいのでしょうか。


地割

岩手には地割という特殊な表記があり、以下のような記載パターンがあります

カンマ区切り

・・,"0295503",・・,"岩手県","和賀郡西和賀町","穴明22地割、穴明23地割",・・

区切り

・・,"0295523",・・,"岩手県","和賀郡西和賀町","越中畑64地割~越中畑66地割",・・

第XX地割のように、「第」が付くものも存在します。

・・,"0287917",・・,"岩手県","九戸郡洋野町","種市第50地割~第70地割(大沢、城内、滝沢)",・・

カッコ内に記載されているものも存在します。

・・,"0282402",・・,"岩手県","宮古市","川井(第9地割~第11地割)",・・


町域名がカッコ付きで補足されるパターン

先の例でも少し触れましたが、町域名には、(・・) で補足されるものがあり、いくつかのパターンがあります。

単語が記載されるケース

・・,"0895865",・・,"北海道","十勝郡浦幌町","厚内(全域)",・・

で範囲として記載されるケース

・・,"2080032",・・,"東京都","武蔵村山市","三ツ木(1~5丁目)",・・

で連結されるケース

・・,"1340015",```,"東京都","江戸川区","西瑞江(4丁目1~2番・10~27番、5丁目)",・・

カッコ内に 「・・」 で補足されるケース

・・,"9800065",・・,"宮城県","仙台市青葉区","土樋(1丁目「11を除く」)",・・

「・・」 が連続するケース

・・,"3842304",・・"長野県","北佐久郡立科町","茂田井(1~500「211番地を除く」「古町」、2527~2529「土遠」)",・・

以下でカッコ内に記載された不要な情報について詳細に見ていきます。


(全域),(丁目)(各町)(番地)(無番地)(その他)

以下のようなレコードが該当します。

・・,"0895865",・・,"北海道","十勝郡浦幌町","厚内(全域)",・・
・・,"5193671",・・,"三重県","尾鷲市","矢浜(丁目)",・・
・・,"6011101",・・,"京都府","京都市左京区","広河原(各町)",・・
・・,"4400066",・・,"愛知県","豊橋市","東田町(番地)",・・
・・,"4400075",・・,"愛知県","豊橋市","花田町(無番地)",・・
・・,"9130031",・・,"福井県","坂井市","三国町新保(その他)",・・

これらは、住所情報として使うにはカッコごと削除する必要があるでしょう。


(○○屋敷)

意外と見過ごされがちですが、以下のレコードが存在します。

・・"4411336",・・,"愛知県","新城市","富岡(○○屋敷)"・・

これも同様に削除する必要があるでしょう。


ビルの記載 (地階・階層不明)(X階)

ビルに関しては概ね以下のようなレコードとして掲載されています。

・・,"1076090",・・,"東京都","港区","赤坂赤坂アークヒルズ・アーク森ビル(地階・階層不明)",・・
・・,"1076001",・・,"東京都","港区","赤坂赤坂アークヒルズ・アーク森ビル(1階)",・・
・・,"1076002",・・,"東京都","港区","赤坂赤坂アークヒルズ・アーク森ビル(2階)",・・

(地階・階層不明) に関してはカッコとその中身の文字を削除すれば良いでしょう。

階層が掲載されているものについては、カッコだけを削除し、中身の階層は残してあげるのが良いでしょう。

"赤坂赤坂アークヒルズ・アーク森ビル(1階)" という場合は、"赤坂赤坂アークヒルズ・アーク森ビル1階" という要領で編集します。


(高層棟)(1階) といったカッコが連続するケースがあります。

・・,"4506201",・・,"愛知県","名古屋市中村区","名駅ミッドランドスクエア(高層棟)(1階)"・・

当該ビルの情報を調べても、(高層棟) という記載は不要に思われるため、(高層棟) という文字はそのまま削除すれば問題ないと思われます。


・・を除く)

・・を除く) 系のレコードは 36レコードほど存在します。

パターンとしては様々です。

・・,"7201264",・・,"広島県","福山市","芦田町福田(376-10を除く)",・・
・・,"5400001",・・,"大阪府","大阪市中央区","城見(次のビルを除く)",・・
・・,"4400075",・・,"愛知県","豊橋市","花田町官有地(無番地を除く)",・・


・・を含む)

・・を含む) は以下の2レコードのみです。

・・,"7920846",・・,"愛媛県","新居浜市","立川町(立川山を含む)",・・
・・,"7860301",・・,"高知県","高岡郡四万十町","大正(葛籠川、轟崎を含む)",・・


・・その他)

・・その他) は2レコードのみです。

・・,"0741272",・・,"北海道","深川市","音江町(国見その他)",・・
・・,"4400845",・・,"愛知県","豊橋市","高師町(北原、その他)",・・


・・以下)

・・以下) は1レコードのみです。

・・,"6496413",・・,"和歌山県","紀の川市","竹房(450番地以下)",・・


・・以上)

・・以上) は6レコード存在します。

・・,"6496162",・・,"和歌山県","紀の川市","竹房(451番地以上)",・・
・・,"3998251",・・,"長野県","松本市","島内(9820、9821、9823~9830、9864番地以上)",・・
・・,"6660134",・・,"兵庫県","川西市","萩原台西(3丁目283番以上)",・・


・・以内)

・・以内) は1レコードのみです。

・・,"8830104",・・,"宮崎県","日向市","東郷町山陰戊(513の1以内)",・・


・・以降)

・・以降) は以下の2レコードのみです。

・・,"8911274",・・,"鹿児島県","鹿児島市","緑ヶ丘町(35番以降)",・・
・・,"8420007",・・,"佐賀県","神埼市","神埼町鶴(3000番地以降)",・・


・・以外)

・・以外) は以下の1レコードのみです。

・・,"3812241",・・,"長野県","長野市","青木島町青木島乙(956番地以外)",・・


・・」以外

・・,"0482402",・・,"北海道","余市郡仁木町","大江(1丁目、2丁目「651、662、668番地」以外、3丁目5、1",・・


・・番地以上

・・,"9960301",・・,"山形県","最上郡大蔵村","南山(430番地以上「1770-1~2、1862-42、",・・


カッコの取り扱い

郵便番号に対する住所情報の補完という意味では、カッコ内の記載はそのまま削除しても良いでしょう。

しかしもう少し親切にすることもできます。


以下のような場合は、

・・,"0580343",・・,"北海道","幌泉郡えりも町","東洋(油駒、南東洋、132~156、158~354、366、367番地)"

以下のように整形することでより親切になるでしょう。

・・,"0580343",・・,"北海道","幌泉郡えりも町","東洋","油駒"
・・,"0580343",・・,"北海道","幌泉郡えりも町","東洋","南東洋"
・・,"0580343",・・,"北海道","幌泉郡えりも町","東洋","366番地"
・・,"0580343",・・,"北海道","幌泉郡えりも町","東洋","367番地"
・・,"0580343",・・,"北海道","幌泉郡えりも町","東洋",""


実装として以下を参考にしてください。

github.com