言語処理100本ノック-98(pandas使用):Ward法によるクラスタリング


言語処理100本ノック 2015の98本目「Ward法によるクラスタリング」の記録です。
前回の非階層型クラスタリングと異なり、階層型クラスタリングをします。ノック結果はクラスタが階層型となる下図の形です(238ヶ国なので大きい・・・)。

参考リンク

リンク 備考
098.Ward法によるクラスタリング.ipynb 回答プログラムのGitHubリンク
素人の言語処理100本ノック:98 言語処理100本ノックで常にお世話になっています
PythonによるDendrogramの作成とlinkageの要素について PythonでのWard法とデンドログラム実装方法

環境

種類 バージョン 内容
OS Ubuntu18.04.01 LTS 仮想で動かしています
pyenv 1.2.15 複数Python環境を使うことがあるのでpyenv使っています
Python 3.6.9 pyenv上でpython3.6.9を使っています
3.7や3.8系を使っていないことに深い理由はありません
パッケージはvenvを使って管理しています

上記環境で、以下のPython追加パッケージを使っています。通常のpipでインストールするだけです。

種類 バージョン
matplotlib 3.1.1
pandas 0.25.3
scipy 1.4.1

課題

第10章: ベクトル空間法 (II)

第10章では,前章に引き続き単語ベクトルの学習に取り組む.

98. Ward法によるクラスタリング

96の単語ベクトルに対して,Ward法による階層型クラスタリングを実行せよ.さらに,クラスタリング結果をデンドログラムとして可視化せよ.

課題補足(階層的クラスタリング)

今回は階層的クラスタリングです。その詳細はリンク先が非常にわかりやすかったです。
上位階層で分けることで、クラスタ数を任意に設定できます。

回答

回答プログラム 098.Ward法によるクラスタリング.ipynb

import matplotlib.pyplot as plt
import pandas as pd
from scipy.cluster.hierarchy import dendrogram, linkage

country_vec = pd.read_pickle('./096.country_vector.zip')
print(country_vec.info())

clustered = linkage(country_vec, method='ward')

plt.figure(figsize=(20, 50), dpi=100, facecolor='c')
_ = dendrogram(clustered, labels=list(country_vec.index), leaf_font_size=8, orientation='right')
plt.show()

回答解説

全般的に記事「PythonによるDendrogramの作成とlinkageの要素について」を参考にしています。
関数linkageを使ってクラスタリングをします。パラメータmethodwardにすることでWard法でのクラスタリングになります。

clustered = linkage(country_vec, method='ward')

あとは結果を表示します。表示したデンドログラム(樹形図)は上の方に載せています。わざわざ背景色をc(シアン)に設定したのは、なぜかデフォルトの白だとラベルがimageファイルにしたときに見えなくなったからです。

plt.figure(figsize=(20, 50), dpi=100, facecolor='c')
_ = dendrogram(clustered, labels=list(country_vec.index), leaf_font_size=8, orientation='right')
plt.show()

上の方だけ見てみます。K-Meansと違って、個々の国の類似度もわかるのがいいですね。
海洋国家が並んでいるかと思えば、JapanとChinaが近い位置にある。なんでなのでしょうかね。イラクとアフガニスタン、イスラエルなんかは物理的な距離は近いですが、意味が似ているのでしょうか?