前回、ラベルつきのデータを使ってランダムフォレストで分類器を作った。
今回は同じデータを使うがラベルは無視してベクトルデータだけを使い、教師なし学習のk-means法でのクラスタリングを行う。コードは以下に置いたので、前回との差分だけ書いていく。
環境
- OSX 10.10.5
- Conda 3.19.0
- Python 2.7.11
- MeCab 0.996
準備
k-means法の計算にscikit-learnを使う。
scikit-learnで使える距離はデフォルトではEuclid距離に限られるようなので問題に応じて工夫が必要かも。
あとベクトルの規格化にnumpyを使うことにした。
import numpy as np
from sklearn.cluster import KMeans
今回はmecab-ipadic-neologdを使うほうが精度が目に見えて上がった気がする。
m = MeCab.Tagger(' -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
次元圧縮
文書をベクトルにするところは前回と一緒で、LSIに渡す次元をチューニングできるようにする。トピック数よりも少し多めにするのがよい気がする。
print '# LSI Model'
dimension = num_topics+3
lsi_model = gensim.models.LsiModel(bow_docs.values(), num_topics=dimension)
lsi_docs = {}
for i, docname in enumerate(files):
vec = bow_docs[docname]
lsi_docs[i] = lsi_model[vec]
def vec2dense(vec, num_terms):
return list(gensim.matutils.corpus2dense([vec], num_terms=num_terms).T[0])
クラスタリング
- 次元による分布の違いの影響が小さくなるようにする
- ここでは全てのベクトルを規格化して単位10次元球面上のクラスタリングになるようにした。
- 次元ごとに分散をもとに正規化するほうが一般的か?
- 処理したベクトルとクラスタ数をKMeansに渡してクラスタリングする。
print '# Clustering'
data_all = [vec2dense(lsi_docs[i],dimension) for i, docname in enumerate(files)]
normalized = [vec/np.linalg.norm(vec) for vec in data_all]
result = KMeans(n_clusters=num_topics).fit_predict(normalized)
for i,docname in enumerate(files):
print docname,'cluster',result[i]
実行結果
# MORPHOLOGICAL ANALYSIS
number of features 1561
# BAG OF WORDS
# LSI Model
# Clustering
birth-1 cluster 3
birth-2 cluster 3
birth-3 cluster 3
birth-4 cluster 3
birth-5 cluster 3
birth-6 cluster 3
birth-7 cluster 3
birth-8 cluster 3
design-1 cluster 2
design-2 cluster 2
design-3 cluster 2
design-4 cluster 2
design-5 cluster 2
design-6 cluster 2
design-7 cluster 2
design-8 cluster 2
ekiden-1 cluster 6
ekiden-2 cluster 6
ekiden-3 cluster 6
ekiden-4 cluster 6
ekiden-5 cluster 6
ekiden-6 cluster 6
ekiden-7 cluster 6
ekiden-8 cluster 6
fe-1 cluster 5
fe-2 cluster 5
fe-3 cluster 5
fe-4 cluster 5
fe-5 cluster 5
fe-6 cluster 5
fe-7 cluster 5
fe-8 cluster 5
ikukyu-1 cluster 9
ikukyu-2 cluster 9
ikukyu-3 cluster 9
ikukyu-4 cluster 9
ikukyu-5 cluster 9
ikukyu-6 cluster 9
ikukyu-7 cluster 9
ikukyu-8 cluster 9
riken-1 cluster 4
riken-2 cluster 4
riken-3 cluster 4
riken-4 cluster 4
riken-5 cluster 4
riken-6 cluster 4
riken-7 cluster 4
riken-8 cluster 4
starwars-1 cluster 1
starwars-2 cluster 1
starwars-3 cluster 1
starwars-4 cluster 1
starwars-5 cluster 1
starwars-6 cluster 1
starwars-7 cluster 1
starwars-8 cluster 1
takahama-1 cluster 7
takahama-2 cluster 7
takahama-3 cluster 7
takahama-4 cluster 7
takahama-5 cluster 7
takahama-6 cluster 7
takahama-7 cluster 7
takahama-8 cluster 7
thief-1 cluster 8
thief-2 cluster 8
thief-3 cluster 8
thief-4 cluster 8
thief-5 cluster 8
thief-6 cluster 8
thief-7 cluster 8
thief-8 cluster 8
tunnel-1 cluster 0
tunnel-2 cluster 0
tunnel-3 cluster 0
tunnel-4 cluster 0
tunnel-5 cluster 0
tunnel-6 cluster 0
tunnel-7 cluster 0
tunnel-8 cluster 0
文書群のとり方にもよるが、この場合は綺麗にクラスタリングできている。