ノート

gensim-word2vecでベクトル空間を試す
gensim-word2vecでベクトル空間を試す(2)
gensim-word2vecでベクトル空間を試す(3)

gensim-word2vecでベクトル空間を試す(4) 2015-02-23

(続きです)

さて、この辺でword2vecの学習元データ(日本語Wikipediaソースを分かち書きにしたもの)の中身を確かめてみたくなった。
何で今まで放っておいたのか、というツッコミは頭を掻くとして…

分かち書きの出現頻度を数えてみた。

〜〜〜〜 〜〜〜〜 〜〜〜〜

次に、出現頻度順の上位の約590語(出現頻度が40回までのもの)を対象にして、これらがランダムな分野から取られていると仮定して、単語間距離による多次元尺度法による分析を試みる。

2通りの作図をする。1つは全体を概観する、もう1つは詳細を見る、というものである。

全体を概観すると、下図のようになる。全体は縦軸が非常に薄い扁平な分布であり、縦軸の値はおよそ1e-06から-5e07程度であるのに対して、横軸は10から-10程度である。

wp500_small.png

次に、詳細を見る。

wp500_large.png

ブラウザでこの図をクリックし、拡大表示することで、ある程度図の内容が確認できると思う。

ちょっとまじめにクラスタ化してみた

(2015-07-19)

上の図がよく分からないので、全ボキャブラリを、k-meansでクラスタ化してみる

全ボキャブラリをk-meansでクラスタ化してみる。

scikit-learnsパッケージにあるk-means (元はsci.pyを呼び出しているらしいが)を使った xmeansというパッケージがあったので、使ってみる。

xmeansのポイントは、k-meansでのクラスタ数kをいろいろと試して、いいものを見つける、という部分。詳細は

クラスター数を自動決定するk-meansアルゴリズムの拡張について

それで、既にボキャブラリの中の語のベクトルを書き出したcsv形式のファイルが作ってあるので、 それを読み込んでk-meansに食わせることになる。

プログラム:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
昔作った出現回数トップ500語のリストをファイルwp500words.outからCSVとして読み込む。
 このファイルはCSV形式で各行が、第1欄に"語", 第2欄以降200欄にnumpyベクトル
 となっている。
 読んだ結果は、連想配列words{語, numpyベクトル}に入れる。
 次に、これをxclusterで、クラスタ化し、matplotlibで表示する。
'''

import sys, string, codecs
import csv
import numpy as np
import xmeans

sys.stdout = codecs.getwriter('utf_8')(sys.stdout)
argvs = sys.argv;  argc = len(argvs)

# ベクトルをファイルから読み込む
if (argc==2):
  infname = argvs[1]
else:
  infname = "wp500words.out"
print infname

with open(infname, "rb") as f:
  dat = []
  reader = csv.reader(f)
  for row in reader:
    dat.append(row[1:])
ndat = np.array(dat, dtype=float)
print ndat.shape

x_means = xmeans.XMeans(random_state = 1).fit(ndat) 
print(x_means.labels_)
print(x_means.cluster_centers_)
print(x_means.cluster_log_likelihoods_)
print(x_means.cluster_sizes_)

また、中で呼んでいるxmeans.pyは

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
以下の論文で提案された改良x-means法の実装
クラスター数を自動決定するk-meansアルゴリズムの拡張について
http://www.rd.dnc.ac.jp/~tunenori/doc/xmeans_euc.pdf
"""

import numpy as np
from scipy import stats
from sklearn.cluster import KMeans

class XMeans:
   """
   x-means法を行うクラス
   """

   def __init__(self, k_init = 2, **k_means_args):
       """
       k_init : The initial number of clusters applied to KMeans()
       """
       self.k_init = k_init
       self.k_means_args = k_means_args

   def fit(self, X):
       """
       x-means法を使ってデータXをクラスタリングする
       X : array-like or sparse matrix, shape=(n_samples, n_features)
       """
       self.__clusters = [] 

       clusters = self.Cluster.build(X, KMeans(self.k_init, **self.k_means_args).fit(X))
       self.__recursively_split(clusters)

       self.labels_ = np.empty(X.shape[0], dtype = np.intp)
       for i, c in enumerate(self.__clusters):
           self.labels_[c.index] = i

       self.cluster_centers_ = np.array([c.center for c in self.__clusters])
       self.cluster_log_likelihoods_ = np.array([c.log_likelihood() for c in self.__clusters])
       self.cluster_sizes_ = np.array([c.size for c in self.__clusters])

       return self

   def __recursively_split(self, clusters):
       """
       引数のclustersを再帰的に分割する
       clusters : list-like object, which contains instances of 'XMeans.Cluster'
       """
       for cluster in clusters:
           if cluster.size <= 3:
               self.__clusters.append(cluster)
               continue

           k_means = KMeans(2, **self.k_means_args).fit(cluster.data)
           c1, c2 = self.Cluster.build(cluster.data, k_means, cluster.index)
          
           beta = np.linalg.norm(c1.center - c2.center) / np.sqrt(np.linalg.det(c1.cov) + np.linalg.det(c2.cov))
           alpha = 0.5 / stats.norm.cdf(beta)
           bic = -2 * (cluster.size * np.log(alpha) + c1.log_likelihood() + c2.log_likelihood()) + 2 * cluster.df * np.log(cluster.size)

           if bic < cluster.bic():
               self.__recursively_split([c1, c2])
           else:
               self.__clusters.append(cluster)

   class Cluster:
       """
       k-means法によって生成されたクラスタに関する情報を持ち、尤度やBICの計算を行うクラス
       """

       @classmethod
       def build(cls, X, k_means, index = None):
           if index == None:
               index = np.array(range(0, X.shape[0]))
           labels = range(0, k_means.get_params()["n_clusters"])

           return tuple(cls(X, index, k_means, label) for label in labels)

       # index: Xの各行におけるサンプルが元データの何行目のものかを示すベクトル
       def __init__(self, X, index, k_means, label):
           self.data = X[k_means.labels_ == label]
           self.index = index[k_means.labels_ == label]
           self.size = self.data.shape[0]
           self.df = self.data.shape[1] * (self.data.shape[1] + 3) / 2
           self.center = k_means.cluster_centers_[label]
           self.cov = np.cov(self.data.T)

       def log_likelihood(self):
           return sum(stats.multivariate_normal.logpdf(x, self.center, self.cov) for x in self.data)

       def bic(self):
           return -2 * self.log_likelihood() + self.df * np.log(self.size)

if __name__ == "__main__":
   import matplotlib.pyplot as plt

   # データの準備
   x = np.array([np.random.normal(loc, 0.1, 20) for loc in np.repeat([1,2], 2)]).flatten()
   y = np.array([np.random.normal(loc, 0.1, 20) for loc in np.tile([1,2], 2)]).flatten()

   # クラスタリングの実行
   x_means = XMeans(random_state = 1).fit(np.c_[x,y]) 
   print(x_means.labels_)
   print(x_means.cluster_centers_)
   print(x_means.cluster_log_likelihoods_)
   print(x_means.cluster_sizes_)

   # 結果をプロット
   #plt.rcParams["font.family"] = "Hiragino Kaku Gothic Pro"VL Gothic
   plt.rcParams["font.family"] = "VL Gothic"
   plt.scatter(x, y, c = x_means.labels_, s = 30)
   plt.scatter(x_means.cluster_centers_[:,0], x_means.cluster_centers_[:,1], c = "r", marker = "+", s = 100)
   plt.xlim(0, 3)
   plt.ylim(0, 3)
   plt.title(u"改良x-means法の実行結果  参考: 石岡(2000)")
   plt.show()
   # plt.savefig("clustering.png", dpi = 200)

結果は、

上位ボキャブラリ wp500words.out の場合

(590, 100)
[1 1 0 0 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 0 0 1 1 0 0 1 0 0 1 0 1 0 1 1 0
 1 1 1 0 1 1 1 1 1 0 0 1 0 0 1 1 1 0 1 1 0 1 0 1 0 1 1 1 1 0 0 1 0 1 1 1 0
 1 1 1 1 0 1 1 1 1 0 1 1 1 0 1 0 0 0 0 1 1 1 1 1 0 1 1 0 1 1 0 0 1 1 0 0 1
 0 1 1 1 0 0 1 0 0 1 0 0 0 1 0 1 1 1 0 0 1 0 1 0 0 0 0 1 1 1 1 0 1 1 0 0 1
 0 1 1 0 0 1 1 1 1 1 1 1 1 1 0 1 1 0 1 0 1 0 1 0 0 1 0 0 1 1 0 1 0 0 0 0 0
 1 0 1 1 0 0 1 0 0 0 0 1 0 0 1 1 1 0 1 1 1 0 0 0 1 1 0 1 0 1 0 0 1 1 1 0 0
 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 1 0 1 0
 0 1 0 1 1 0 0 1 0 1 1 1 0 1 0 0 1 1 0 1 0 0 1 1 0 0 1 0 0 1 0 0 0 0 1 0 0
 0 0 0 1 0 0 0 1 0 1 1 0 0 0 1 0 0 0 0 0 0 1 1 1 0 1 1 0 0 0 1 1 1 1 0 0 1
 1 1 0 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0
 1 0 0 1 0 0 0 1 0 0 0 1 1 1 1 0 0 0 0 1 1 0 1 0 0 0 1 0 0 0 0 1 1 0 1 1 0
 1 1 0 1 0 1 1 0 1 0 1 1 0 0 1 0 1 1 0 0 1 1 0 1 0 1 1 0 0 0 0 0 0 1 0 1 0
 1 1 0 1 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 0 0 0 1 1 1 0 0 1 1 1 0 0 1 1 0 0 0
 1 0 0 0 0 0 1 0 0 0 0 1 0 1 1 0 0 1 0 0 0 1 0 0 0 1 0 1 0 0 1 0 0 1 0 0 0
 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 1 0 1 0 1 0 0 0 1 0 1 1 1 1 0
 1 0 0 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 1 0]
[[ -1.20686099e-01   3.85187179e-02   1.38309300e-01   1.10604316e-01
  -4.75689712e-02   3.10646304e-02   9.41132463e-02  -5.70251271e-02
  -8.26290200e-02   1.69705502e-01  -5.27724118e-03   3.47696863e-02
   7.51235630e-02  -3.38987530e-02  -2.77249460e-01   1.00363509e-01
  -7.61209042e-02  -1.08001802e-01   2.00861811e-01  -4.92251180e-02
  -2.04249165e-02  -6.98459397e-02  -7.74254784e-03   1.65775033e-01
   2.03269792e-02  -1.14642509e-01  -1.43948051e-02   2.36037434e-01
   1.24181231e-01   1.23971916e-01   3.40378137e-02  -1.15228243e-01
  -5.64316890e-02   3.92804168e-03   5.02002672e-02   1.71132601e-01
   5.68151706e-03   1.73304358e-01   9.76300130e-02   1.59595452e-01
  -7.55954265e-02   3.01412379e-03   5.26031980e-02   9.21203577e-02
  -9.96372887e-02   1.58033987e-01   7.82006470e-02  -4.98887212e-02
  -1.39622893e-01  -1.14794670e-01  -4.94301317e-02  -3.65500695e-02
  -9.27763663e-02   1.42568130e-01  -1.49269712e-01   1.11659365e-02
  -2.93288459e-02   5.18730953e-04  -5.80049784e-02  -1.40768767e-01
   2.38481340e-01  -3.24637766e-02  -1.22973551e-01   1.26524352e-01
   1.76933846e-01  -2.21941069e-02  -8.08499012e-03   1.28241439e-02
  -2.09521374e-02   1.58220951e-01  -7.32549001e-02  -1.67406742e-01
   1.06393727e-01  -3.26073499e-02   5.64578209e-02   4.93067892e-02
  -7.39306547e-02  -3.08722195e-02  -1.44130732e-01  -9.19578088e-02
   8.68038241e-02  -4.44418239e-02  -2.07526746e-01   5.08312192e-02
  -2.48574692e-02  -8.06796804e-02  -1.59373350e-01   5.75102444e-02
   2.98243344e-02  -2.03769129e-01  -4.87509188e-02  -9.31687239e-02
  -7.31808008e-02   8.51248470e-02  -2.93075279e-02   1.88361095e-01
  -1.66319117e-01  -3.41247258e-02   5.20694389e-02   3.65269337e-02]
[  1.31880479e-02  -2.54030544e-02  -9.85077906e-03   1.33283218e-01
  -8.82072404e-02   1.29692509e-01  -5.42415829e-02   1.18031027e-01
   9.78549139e-02   1.12305881e-01   9.13690381e-02  -1.31832874e-01
   8.37297763e-02   2.41835173e-02  -8.54147521e-02  -1.39736877e-01
  -1.85013070e-02  -4.06359359e-02   1.84170983e-01  -7.40005078e-02
   5.69715734e-03  -2.68203533e-01   7.33174624e-02  -5.22390048e-02
  -1.90901346e-01  -8.09358819e-02   5.72223504e-02   2.23685524e-01
   9.29161701e-02   1.19009357e-01  -1.02789471e-02  -1.25032568e-01
   6.85472149e-02  -1.26003613e-02   7.71010544e-02   2.23108091e-01
  -2.62769098e-02   8.61013968e-02   9.17636307e-02   8.78758788e-02
  -7.91155440e-02  -5.66718362e-02   1.04390166e-01   1.73663330e-01
   5.72330463e-02   2.19457060e-01  -1.67473094e-01   1.31863359e-01
  -1.11859081e-01  -1.11725822e-01   1.78922039e-01   1.44327744e-02
  -7.59846351e-02  -1.46366834e-02   1.44038041e-03  -7.34339256e-02
  -5.20506598e-02   2.01296802e-02  -1.05705819e-01   3.48269317e-02
   1.55090163e-01   5.37089877e-03  -5.55236702e-02   5.55721898e-02
   3.36478897e-02   8.93140895e-02   3.65625906e-02   7.35926388e-02
   1.09131269e-04   6.64482816e-02  -8.57760260e-02  -6.93624111e-02
   7.34368843e-04  -8.45565492e-02   1.94706984e-01  -1.40949526e-01
  -2.20409663e-02  -9.78588215e-02  -4.52674513e-02  -1.08962615e-01
   3.48923050e-02  -1.28841058e-01  -1.87955668e-01   1.02655352e-02
  -8.59925034e-02   7.16263888e-02  -3.71724417e-02  -6.65355592e-02
  -2.43770339e-01  -5.06753503e-03  -6.83220400e-02   4.93701893e-02
  -1.31725846e-01   1.24237397e-01   8.62606164e-02   1.87323804e-02
  -9.43093694e-04   1.34606443e-01  -4.25687426e-02   6.45941934e-02]]
[ 16208.85417643  10888.41537073]
[322 268]

ということで、2クラスタ(それぞれが322語, 268語)にしかならかなった。 おそらくは非常に分散していて、クラスタとして認識できなかったと思われる。

全ボキャブラリ wpallwords.out の場合

(5176, 100)

[1 1 1 ..., 1 0 1]
[[-0.13191395 -0.0248849   0.1430598   0.12306257 -0.07450798  0.00646811
  0.09359275 -0.07826383 -0.04159682  0.19700889  0.03652305  0.06700165
  0.10931797 -0.03293728 -0.25659822  0.09524981 -0.05388804 -0.13426066
  0.26013381 -0.06362121 -0.04405031 -0.10492961 -0.00140841  0.20102812
  0.00657807 -0.08544728  0.08140551  0.25900133  0.07079124  0.08577857
  0.03910614 -0.10753588 -0.05729731  0.01935761  0.11222613  0.1467138
 -0.00473657  0.06138889  0.07425032  0.16794309 -0.06690123 -0.03610357
  0.05897139  0.01083048 -0.04415719  0.1494636   0.06852383  0.05837666
 -0.09962659 -0.10883703 -0.06343212  0.00797467 -0.05952508  0.15421827
 -0.17280034  0.04149284 -0.02401073 -0.02972178 -0.08935874 -0.17432829
  0.19173001  0.04249168 -0.06739018  0.07295972  0.18923592 -0.05475225
  0.01638102  0.06062523 -0.05627156  0.11068116 -0.07386442 -0.17519372
  0.09368976 -0.06474553  0.03360312  0.03506369 -0.05209505 -0.03938096
 -0.1331233  -0.05373295  0.04537114 -0.05383895 -0.19732957  0.05895715
 -0.03302607 -0.06516841 -0.14248325  0.08375861  0.04440468 -0.21176673
 -0.01356284 -0.12578804 -0.02089717  0.05496296 -0.03791425  0.23603258
 -0.11518421 -0.00337393  0.04839361  0.02624207]
[-0.02066534 -0.01158693  0.03691795  0.09540584 -0.05042948  0.12406175
 -0.04131038  0.0781226   0.07254279  0.05508153  0.03313755 -0.13510344
  0.04733497  0.01709512 -0.08509257 -0.12919603 -0.05339178 -0.00826791
  0.04803555 -0.08020149 -0.01233557 -0.21500708  0.04565839 -0.01903055
 -0.13970072 -0.10251378  0.01163783  0.13408184  0.10450967  0.12126194
  0.00817289 -0.04455414  0.08958532 -0.0274446   0.06401944  0.14714249
  0.02249278  0.04116854  0.05052156  0.07348924 -0.0211888  -0.08057152
 -0.00375203  0.1371551   0.05578472  0.10381077 -0.1196903   0.12013696
 -0.0610813  -0.06193025  0.11480575  0.01288549 -0.04077632 -0.00266693
  0.01593739 -0.04324223  0.04660021 -0.09035241 -0.09708149  0.02909314
  0.08207993  0.01998113 -0.01133956  0.03398011  0.0310528   0.04943719
 -0.00622721  0.07239436  0.02638805 -0.0364055  -0.13151013 -0.0766993
 -0.03492899 -0.07233917  0.13025182 -0.0292393  -0.04808092 -0.0524468
 -0.04153711 -0.06361494 -0.01272261 -0.01143723 -0.13510149  0.01049757
 -0.06178603  0.07670733  0.00937329 -0.03125577 -0.1496305   0.03684528
 -0.12286579  0.03122464 -0.07037145  0.07408756  0.04710795  0.01280504
  0.01431312  0.05152565 -0.01090218 -0.0506355 ]
[-0.11184239 -0.28264037  0.32677876  0.14855827 -0.21353295  0.263305
 -0.18366362  0.37962839 -0.01381245  0.0355929  -0.27796656 -0.12545008
 -0.13272248  0.11515194 -0.17814173 -0.53011036  0.18568002  0.32117757
 -0.0150351  -0.20357954 -0.04223859  0.16294926 -0.2658966   0.38009089
  0.21100864 -0.37237772 -0.29567207  0.21866073  0.28875229 -0.04777135
  0.13560663 -0.03867145 -0.22243745 -0.20730813 -0.06147448  0.08736833
  0.02659063  0.06632055 -0.09043126  0.0277067   0.32708776 -0.12565948
  0.22277999  0.1079998   0.0331694   0.05499604  0.13138529 -0.05932007
  0.04301388  0.07686359 -0.02671375 -0.01229028  0.00598564 -0.48022952
 -0.21276585  0.0013294  -0.01768171  0.22690265  0.20604533  0.11481116
 -0.08836293  0.15036193 -0.06484719 -0.21860142 -0.05953721  0.14216542
  0.13847516  0.07291732  0.01729672 -0.27492737  0.28349704 -0.22654794
 -0.05379034  0.09650781  0.0385203   0.2528412  -0.06989203 -0.13764652
  0.24784211 -0.18245202 -0.09886073 -0.12844509 -0.10419787 -0.08720143
  0.30057128 -0.11195836  0.22308901  0.08907373 -0.11001518 -0.04157664
  0.08767545  0.00814359 -0.22805293 -0.29677902 -0.11712225  0.03854134
  0.0756648  -0.21597487 -0.01663512 -0.08178534]]
[ 73649.74187201  33936.68768974   8591.77371155]
[2406 2411  359]

ということで、3クラスタ(それぞれが2406語, 2411語, 359語)になった。 この場合も、上位500語と同様に、クラスタ数が非常に少ない。分散した結果になっている と思われる。


添付ファイル: filewp500_large.png 322件 [詳細] filewp500_small.png 202件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2015-07-22 (水) 11:12:00 (820d)