福島県の気温データをクラスタリング分析すると、天気予報の３地方に分類できるか検証してみた

## 目的
福島県の天気予報は３地方（浜通り、中通り、会津地方）に分けて提供される。  
気温データをクラスタリング分析することで、うまくこの３地方に分類できるのかを検証する。

福島県は、「県内は南北方向に延びる山脈・山地によって、地形・気候・交通・歴史などの面に違いが顕れており、3地域に分けられている。」[Wikipedia](https://ja.wikipedia.org/wiki/福島県 "Wikipedia 福島県")より引用
クラスタリング分析は、「教師なしデータ分類手法、つまり与えられたデータを外的基準なしに自動的に分類する手法。また、そのアルゴリズム。」同じく[Wikipedia](https://ja.wikipedia.org/wiki/データ・クラスタリング "Wikipedia データ・クラスタリング")より引用

## 気温データをクラスタリング分析
まず、気象庁が公開している[2022年月毎の平均気温(福島県)](https://www.data.jma.go.jp/stats/etrn/view/monthly_h1.php?prec_no=36&block_no=00&year=2022&month=&day=&view=p2 "2022年月毎の平均気温(福島県)")をコピペし、fukushima_tempreture_2022.tsv としてファイル保存する。  

このファイルを読み込んで表示すると、こんな感じ。

```python
import pandas as pd
df_tempreture = pd.read_csv('fukushima_tempreture_2022.tsv',sep='\t', index_col=0)
print(df_tempreture.head())
```

```
     梁川    福島    相馬   喜多方   猪苗代   二本松    若松    船引    浪江    只見  ...    金山  \
月                                                              ...         
1   0.6   1.1   1.8  -1.7  -3.0   0.6  -0.8  -1.4   2.1  -1.4  ...  -1.3   
2   1.6   1.6   1.8  -0.9  -2.3   1.0  -0.1  -0.7   1.8  -1.3  ...  -1.2   
3   6.3   6.8   5.9   3.5   2.8   6.3   4.6   4.8   6.3   2.3  ...   2.3   
4  12.3  13.1  11.3  10.8   9.7  12.4  11.8  10.6  12.0   6.7  ...   7.9   
5  16.9  17.6  16.1  15.9  14.2  16.6  16.5  14.6  16.1  13.9  ...  14.0   

     鷲倉    川内    飯舘    桧原    茂庭    湯本   桧枝岐    玉川    山田  
月                                                        
1  -6.9  -0.8  -1.8  -5.0  -0.7  -2.9  -4.9  -0.2   2.8  
2  -6.8  -0.5  -1.9  -4.7  -0.2  -2.6  -4.5   0.0   2.7  
3  -0.9   4.8   3.7   0.2   4.1   2.3   0.7   5.6   7.3  
4   5.8  10.3  10.1   6.2  10.6   8.6   6.1  11.5  12.7  
5  10.2  14.0  14.1  11.6  14.6  12.6  11.0  15.1  16.3  

[5 rows x 30 columns]
```
デンドログラムで可視化するとこんな感じ。

```python
import matplotlib.pyplot as plt
from scipy.cluster import hierarchy
import japanize_matplotlib
method = 'ward'
Z = hierarchy.linkage(df_tempreture.T, method=method)
hierarchy.dendrogram(Z, color_threshold=0,labels=df_tempreture.columns)
plt.ylabel('distance')
plt.title( '気温による分類')
plt.xticks(rotation=90)
plt.show()
```
なお、日本語表示ができない場合には、以下のコマンドでインストールしておく。
```
!pip install japanize_matplotlib
```

![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570565/83dba302-06ed-bbdf-2eb6-e4f767e2bc85.png)

まず、都市部（平地/盆地）と山間部で２つのクラスタに分類できるようである。
都市部（平地/盆地）は、次に３地方ではなく２つに分類される。中通り中部南部の郡山/白河は会津若松/喜多方の会津地方側に、中通り北部の福島/二本松は相馬/小名浜の浜通り側に分類される。
山間部は、次に、檜原/檜枝岐の奥まった山間部と、船引/田島など山間の町村部に分類される。
うまく３地方には分類できないようだが、細かく分割すると、実態に近い分類ができそうなので、１１個のクラスタに分類してみる。

```python
from sklearn.cluster import AgglomerativeClustering
n_clusters = 11
clustering = AgglomerativeClustering(linkage=method, n_clusters=n_clusters)
clustering.fit(df_tempreture.T)
df_clustering_result = pd.DataFrame( clustering.labels_, index=df_tempreture.columns, columns=['label'])
print(df_clustering_result.head())
```

```
     label
梁川       1
福島       1
相馬       9
喜多方      0
猪苗代      7
```
これでは分かりにくいので、地図にプロットしてみる。

## クラスタリング結果を地図にプロット

地図にプロットするため、気象庁が公開している[観測所一覧](https://www.jma.go.jp/jma/kishou/know/amedas/ame_master.pdf "観測所一覧")の位置情報をダウンロードし、福島県の観測所一覧(17p)をコピペし、ame_muster_fukushima.txt としてファイル保存する。  

読み込んで表示すると、こんな感じ。

```python
df_lonlat = pd.read_csv('ame_muster_fukushima.txt',encoding='shift_jis', sep=' ')
print(df_lonlat.head())
```

```
  都府県振興局  観測所番号 種類 観測所 名ｶﾀｶﾅ名 気象情報等に表記する名称             所在地  緯度(度)  緯度(分)  \
0     福島  36056  四  茂庭    ﾓﾆﾜ        福島市茂庭    福島市飯坂町茂庭字滑滝道     37   53.5   
1     福島  36066  四  梁川  ﾔﾅｶﾞﾜ        伊達市梁川     伊達市梁川町粟野字作田     37   51.1   
2     福島  36106  四  桧原   ﾋﾊﾞﾗ       北塩原村桧原    耶麻郡北塩原村桧原字墓下     37   43.3   
3     福島  36127  官  福島   ﾌｸｼﾏ           福島  福島市松木町　福島地方気象台     37   45.5   
4     福島  36151  四  相馬    ｿｳﾏ           相馬    相馬市成田字五郎右エ門橋     37   47.0   

   経度(度)  経度(分)  海面上の高さ(ｍ) 風速計の高さ(ｍ) 温度計の高さ(ｍ)    観測開始年月日    備考1      備考2  
0    140   26.2        200       6.5         3   平4.10.23  36950    湿度を除く  
1    140   35.3         43       9.4       1.5  #昭51.12.6      −    湿度を除く  
2    140    3.5        824       9.4         4  昭53.10.26      −    湿度を除く  
3    140   28.2         67         −         −    令3.3.18  36955  気温、雨、日照  
4    140   55.5          9       6.5       1.5  #昭51.12.7      −        −  
```
経緯度の処理や必要な列のみを抽出し、クラスタリング結果と統合する。
```python
# 経緯度の度分を度に変換する
df_lonlat['緯度'] = df_lonlat['緯度(度)'] + df_lonlat['緯度(分)']/60
df_lonlat['経度'] = df_lonlat['経度(度)'] + df_lonlat['経度(分)']/60
df_lonlat['高度'] = df_lonlat.loc[:,'海面上の高さ(ｍ)']
# 必要な列のみにする
df_lonlat = df_lonlat[['観測所','緯度','経度','高度']]
print(df_lonlat.head())
# クラスタリング結果と、観測所座標を統合
df_clustering_result = pd.merge(df_clustering_result, df_lonlat, left_index=True, right_on='観測所', how='inner')
df_clustering_result = df_clustering_result.sort_values('label')
print(df_clustering_result.head())
```
```
  観測所         緯度          経度   高度
0  茂庭  37.891667  140.436667  200
1  梁川  37.851667  140.588333   43
2  桧原  37.721667  140.058333  824
3  福島  37.758333  140.470000   67
4  相馬  37.783333  140.925000    9
    label  観測所         緯度          経度   高度
5       0  喜多方  37.658333  139.863333  212
14      0   若松  37.488333  139.910000  212
9       0  西会津  37.588333  139.656667  165
1       1   梁川  37.851667  140.588333   43
3       1   福島  37.758333  140.470000   67
```
クラスタ別に色分けして、地図上にプロットする。
```python
import folium
from folium.plugins import HeatMap
map = folium.Map(location=[37.4753244,140.2829286], zoom_start=9, tiles='OpenStreetMap')
color_list = ['red','blue','green','lightgray','black','pink','orange','lightblue','lightgreen','purple','darkred']
for i, rec in df_clustering_result.iterrows():
  folium.Marker(location=[rec.緯度,rec.経度],popup=rec.観測所,icon=folium.Icon(icon='ok', color=color_list[rec.label])).add_to(map)
map
```
![output3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570565/6a68a578-94b9-a631-dc9f-d8083250bb74.png)

３地方より細かい地域で分割できているようではある。さらに考察するために、分類されたクラスタ毎に平均気温を可視化する。

## クラスタ毎に平均気温を可視化
平均気温（度）をそのまま表示すると差が見えにくいため、県全体の平均気温との差を可視化する。
```python
df_mean = df_tempreture.mean(axis=1)  # 県全体の平均気温
fig_size_x = 8
fig_size_y = 5
fig = plt.figure(figsize=(fig_size_x, fig_size_y))
# クラスタ毎に処理
for i in range(n_clusters):
  df_work = pd.DataFrame()
  name_list = ''
  for j, rec in df_clustering_result.iterrows():
    # 対象クラスタに分類された結果のみ抽出
    if rec.label==i:
      name = rec.観測所
      name_list += name
      df_work[name] = df_tempreture[name]
  # クラスタ毎の平均と県全体の平均の差をプロット
  plt.plot(df_work.mean(axis=1)-df_mean,c=color_list[i],label=f'#{i}{name_list}')
plt.grid(axis='y')
plt.xlabel('月')
plt.xticks(range(1,13))
plt.ylabel('県全体の平均気温との差（度）')
plt.title( 'クラスタ毎の県全体の平均気温との差')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left', borderaxespad=0, fontsize=18)
plt.show()
```
![output4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570565/c85e5651-b031-fd5b-35f5-b731d4d96d34.png)

# 考察

### 各クラスタ
１月（冬場）の暖かい順に考察する。

* ピンク：浜通り南部（小名浜など）  
冬場は一番暖かいが、夏は涼しくなってくる。
* 紫：浜通り北部（相馬など）  
浜通り南部に次いで冬暖かい。年間通して、浜通り南部より１度程度低いが、８月だけは、浜通り南部と同じく暑い。
* 青：中通り北部（福島など）  
上記浜通り（南部/北部）の次に冬暖かいが、夏場になると、浜通りより暑い。（県内で一番夏が暑い。）
* 黄色：中通り中部/南部（郡山/白河など）  
中通り北部と同じ傾向だが、年間通して、中通り北部より１度ほど低い。
* 赤：会津中北部（会津若松など）  
冬は県平均だが、夏場が急激に暑くなり、中通り中部/南部を抜いて、県内で二番目に夏が暑くなる。
* 茶色：阿武隈高地（船引など）  
冬は会津中北部と同じく県平均だが、夏場は暑くならない。年間通して県平均。
* 灰色：会津南西部（只見など）  
会津地方としては会津中北部に次いで冬暖かいが、３、４月は残冬が厳しく、田島より寒い。５、６月に回復し県平均となり、阿武隈高地より暑くなる。
* 水色：猪苗代、飯館（ここだけ地域として特定できず）  
年間を通して、県平均から１～２度低い。
* 緑色：会津南部（田島など）  
年間を通して、県平均から２度ほど低い。
* 黒：会津山間部（檜枝岐など）  
年間を通して、県平均から４度ほど低い。
* 黄緑：中通り山間部（鷲倉）  
観光有料山岳道路の頂点（浄土平）で、標高高い場所にある（通常、人は住まない）。ここだけ別格で格別に寒い。秋（１０,１１月）だけは会津山間部と同じ気温となる。

### 全体

* 浜通りが冬暖かいことには納得だが、夏はそれほど涼しくないことに驚き。（浜通り南部を上回る暑さは、中通り北部と会津中北部のみ。中通り中南部と同程度の暑さ）
* 夏冬の寒暖差が最も激しいのは会津中北部であることに納得。（住むのは大変だが、美味しい米どころたる所以）
* 中通り北部と中通り中部/南部では平均気温の差がある（北部の方が暖かい/暑い）ので、北部は気温の高い浜通りへ、中部/南部は気温の低い会津へ分類された（デンドログラムにて）と推察される。クラスタリング分析では２つずつ分割していくのでそのようになったが、３つに分割する手法であれば、３地域になるのだろうか？
* 中通り中部と中通り南部は気温の傾向が似ているため、温度データだけでは分割されにくい。
* 船引などの阿武隈高地が年間を通して県平均を維持していることに驚き。（気温的には県の中心のようです。）
* 最高の避暑地となるのは、檜枝岐、檜原（裏磐梯）であり、県内有数の観光地（保養地）であることに納得。
* 会津南西部の残冬（３、４月）が厳しく、鷲倉（浄土平）の秋（１０、１１月）がそれほど寒くならないのが謎。（知見ある方いらっしゃれば教えてください。）

## まとめ
気温データだけから分類したこともあり、３地方というよりは、都市部と山間部で分割されたが、より細かい地域で分割すると、そこそこうまく分類できたと思う。降水量や日照時間なども含めると、うまく３地方で分類できたかもしれないが、、、
皆さんのお住まいの都道府県でも分析してみてはいかがでしょうか？