ありったけの日本の住所をかき集める

# 概要
日本中の住所（都道府県～小字まで）をオープンデータから収集してみる。
与えた文字列が住所かどうかの判定にきっと使えるのではないかと。

用いるデータは[住所.jpの住所データ](http://jusyo.jp/csv/document.html)と[Geolonia 住所データ](https://geolonia.github.io/japanese-addresses/)だ。前者は[日本郵便の郵便番号データ](https://www.post.japanpost.jp/zipcode/download.html)を加工したもので、後者は[国土地理院の位置参照情報](https://nlftp.mlit.go.jp/cgi-bin/isj/dls/_choose_method.cgi)をベースにしているデータである。

本記事ではGoogle ColaboratoryでPythonを用いてデータ処理していく。

# データ処理
## 住所.jpデータ
更新日 2022-03-10 のデータをダウンロード。このデータはエンコーディングがshift-jisであるとダウンロードページに書いてあるのでnkfを使ってutf-8に変換しておく。


```python
! wget http://jusyo.jp/downloads/new/csv/csv_zenkoku.zip
! apt-get install nkf
! unzip -p csv_zenkoku.zip | nkf > csv_zenkoku.csv
```

次にファイルをpandas等で読み込み何件含まれているか数えたい。このとき、「町域補足」の列の違い等で住所全体の表記としては同じでも別の行になっていることがあるので、今回は住所を連結したときのuniqを数え上げる。さらに細かいことを言えば空値として扱われるデータがあると不便なので`fillna()`で埋めておいた方が楽だろう。

列名などは仕様を読んでいただきたい。京都通り名だけ触れておくと、これは京都市内の特殊な住所表示であり、[京都市内の通り（Wikipedia）](https://ja.wikipedia.org/wiki/%E4%BA%AC%E9%83%BD%E5%B8%82%E5%86%85%E3%81%AE%E9%80%9A%E3%82%8A)によると
> 南北の△△通に面し、東西の○○通から北に進んだところにある場所は「△△通○○上ル（あがる）」

といった具合に表記されるもので、専用の列が用意されている。

では実際にデータを読み込んで数えてみよう。

```python
import pandas as pd

jusyo_df = pd.read_csv('csv_zenkoku.csv', dtype={'京都通り名': str})
jusyo_df.fillna({'市区町村': '', '京都通り名': '', '町域': '', '字丁目': ''}, inplace=True)
jusyo_df['結合住所'] = jusyo_df['都道府県'].str.cat([jusyo_df['市区町村'], jusyo_df['京都通り名'], jusyo_df['町域'], jusyo_df['字丁目']])
jusyo_df['結合住所'].unique().size
```




    127145



約13万件とってこれた。良い感じ。

廃止された住所とかも含まれているが実際には使われてしまう場合もあるのでまあ良いだろう。

高層ビルの各階に郵便番号が振られている場合字丁目が「霞が関ビル」になったりしているが、それを除くのは簡単ではなさそう。

また郵便番号の仕様上「その他」に該当する地域の住所はとってこれない。また京都通り名も郵便番号の区別に必要最低限のものしか記載されていなさそう。仕方ない。

## Geoloniaデータ
次にGeoloniaデータをダウンロードする。githubに上がっているのでバージョンも確認しておく。



```python
! git clone https://github.com/geolonia/japanese-addresses.git
! cd japanese-addresses/ && git rev-parse --short HEAD
```

    45de9f2




そして同じようにpandasで読み込む。
```python
geolonia_df = pd.read_csv('japanese-addresses/data/latest.csv')
geolonia_df.fillna({'市区町村名': '', '大字町丁目名': '', '小字・通称名': ''}, inplace=True)
geolonia_df['結合住所'] =  geolonia_df['都道府県名'].str.cat([geolonia_df['市区町村名'], geolonia_df['大字町丁目名'], geolonia_df['小字・通称名']])
geolonia_df['結合住所'].unique().size
```




    277191



おぉ、約28万件であり、数ではGeoloniaの勝利だ。こちらは国土地理院が位置情報を測定してない住所や京都通り名は無かったりするが、郵便番号上区別されてない住所がかなりあるということだろうか。

さらにGeoloniaのAPI版のユーザーフィードバックを元にした住所データが`patches/`以下に追加されている。これも使っていこう。




```python
import glob

filepaths = glob.glob("japanese-addresses/patches/*.json")

for filepath in filepaths:
    temp_df = pd.read_json(filepath)
    temp_df.drop(columns=['参照', '更新日'], inplace=True)
    temp_df['結合住所'] =  temp_df['都道府県名'].str.cat([temp_df['市区町村名'], temp_df['大字町丁目名'], temp_df['小字・通称名']])
    geolonia_df = geolonia_df.append(temp_df, ignore_index=True)

geolonia_df['結合住所'].unique().size

```




    277364



173件増えた。

# 2つのデータの違い
廃止された住所・ビル・京都通り名の有無以外にも以下のような違いが目視で確認できた。

- 住所.jpデータには「一番町」も「１番町」も含まれている。Geoloniaは全て「一番町」のように漢数字表記に統一されている
- Geoloniaデータで「大字xxx」とされている町域名は住所.jpデータでは「xxx」のようになっている

この2つのデータを併用する場合はこうした表記の違いにも気をつけたいところ。Geoloniaデータ作成スクリプトを見に行けばより正確な情報が得られるだろう。

だがそんなのは面倒なので、郵便番号はいらないけどたくさん住所が欲しいときはGeoloniaデータだけでいいんじゃないかなあと。っていうかGeolonia住所正規化ライブラリを使えば良い気がしてきたぞ。