[[ノート>ノート/ノート]]

[[gensim-word2vecでベクトル空間を試す>ノート/テキストマイニング/gensim-word2vecでベクトル空間を試す]]~
[[gensim-word2vecでベクトル空間を試す(2)>ノート/テキストマイニング/gensim-word2vecでベクトル空間を試す(2)]]~
[[gensim-word2vecでベクトル空間を試す(3)>ノート/テキストマイニング/gensim-word2vecでベクトル空間を試す(3)]]


*gensim-word2vecでベクトル空間を試す(4) 2015-02-23 [#v3cf786b]
(続きです)

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

分かち書きの出現頻度を数えてみた。
-全ての分かち書きの個数  22951
-5回以上出現した分かち書きの個数  4883
但し、頻度順での先頭周辺の約55ぐらいのエントリーは、助詞や記号などの、意味が採りづらい語であった。

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

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

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

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

&ref(wp500_small.png);

次に、詳細を見る。

&ref(wp500_large.png,,10%);

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

**ちょっとまじめにクラスタ化してみた [#gd6daf4d]
(2015-07-19)

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

***全ボキャブラリをk-meansでクラスタ化してみる。 [#fbabe055]
scikit-learnsパッケージにあるk-means (元はsci.pyを呼び出しているらしいが)を使った
xmeansというパッケージがあったので、使ってみる。

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

>[[クラスター数を自動決定するk-meansアルゴリズムの拡張について:http://www.rd.dnc.ac.jp/~tunenori/doc/xmeans_euc.pdf]]

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

-wp500words.out  コーパス上出現回数が40以上の語のみ、590語
-wpallwords.out  コーパス上のすべての語 5176語

プログラム:
 #!/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語と同様に、クラスタ数が非常に少ない。分散した結果になっている
と思われる。


トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS