LoginSignup
20

More than 5 years have passed since last update.

k-means法で文書のクラスタリング

Posted at

前回、ラベルつきのデータを使ってランダムフォレストで分類器を作った。

今回は同じデータを使うがラベルは無視してベクトルデータだけを使い、教師なし学習の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

文書群のとり方にもよるが、この場合は綺麗にクラスタリングできている。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20