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

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

*gensim-word2vecでベクトル空間を試す(2) 2015-01-11 [#sa400ce9]

**限定された語リストに対してベクトルを取り出し、主成分分析をしてみる [#d045d88c]

思い付き: 同じ意味カテゴリに属しそうな語をいくつか取り出して、それがベクトル空間内でどういう形になるかに興味がある。~
具体的には、平面になってほしいような気がしている。~
そこで、主成分分析をして、次元数が1つかせいぜい2つぐらいにならないか見てみる。

まずpythonでベクトルを書き出して、それをRに読ませて主成分分析(なり何なり)をする

 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 import gensim, logging
 import sys
 import string, codecs
 import numpy as np
 import math
 
 sys.stdout = codecs.getwriter('utf_8')(sys.stdout)
 argvs = sys.argv;  argc = len(argvs)
 
 logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
 
 model = gensim.models.word2vec.Word2Vec.load("jpw-wakati-model")
 # looking at the "model" to be a dictionary
 
 # 全ボキャブラリを対象に単語ベクトルを出力したいならば
 # voc = model.vocab.keys()
 
 # 対象語をファイルから読み込む
 voc = codecs.open(argvs[1], 'r', encoding='utf-8').read().split()
 outf = codecs.open(argvs[1]+'.out', 'w', encoding='utf-8')
 for x in voc:
   try:
      wvec = model[x]
   except KeyError:
      print x, u'を無視します'
   outf.write('"' + x + '"' + ', ' )
   c = 0
   for v in wvec:
      if c==0:
         outf.write(str(v))
      else:
         outf.write(', '+str(v))
      c += 1
   outf.write('\n')
 outf.close()

あらかじめ単語リストファイル list-fruit.txt を用意しておく。
 リンゴ バナナ ミカン イチゴ メロン カキ ブドウ グレープフルーツ

これを、上記プログラムで処理する。
 python readvecs.py

出力ファイル &ref(list-fruit.out); が生成される。

これを R に読み込み、主成分分析処理を行う。prcompを用いscaingをTRUEとした[[[Rのprcomp()関数で主成分分析をするときの注意点:http://statsbeginner.hatenablog.com/entry/2014/07/27/121214]]]。
 > w1 <- read.csv('list-fruit.txt.out', header=FALSE, row.names=1)
 > w2 <- prcomp(w1, scaling=TRUE)
 > summary(w2)
 Importance of components:
                           PC1    PC2    PC3    PC4     PC5     PC6     PC7
 Standard deviation     0.9070 0.7501 0.5742 0.4973 0.40887 0.37208 0.29335
 Proportion of Variance 0.3495 0.2390 0.1401 0.1051 0.07102 0.05882 0.03656
 Cumulative Proportion  0.3495 0.5885 0.7286 0.8336 0.90462 0.96344 1.00000
                              PC8
 Standard deviation     2.431e-16
 Proportion of Variance 0.000e+00
 Cumulative Proportion  1.000e+00

同様に、都市リストのデータ list-city.txt を
 東京 大阪 京都 仙台 札幌 盛岡 金沢 静岡 広島 福岡 長崎 鹿児島

とし、同じ処理
 python readvecs.py list-city.txt
を行うと、出力ファイル &ref(list-city.out); を得る。同様にRにて主成分分析すると、

 > w1 <- read.csv('list-city.out', header=FALSE, row.names=1)
 > w2 <- prcomp(w1, scaling=TRUE)
 > summary(w2)
 Importance of components:
                           PC1    PC2    PC3     PC4     PC5     PC6    PC7
 Standard deviation     1.0001 0.6822 0.5848 0.50667 0.43939 0.34185 0.3006
 Proportion of Variance 0.3685 0.1715 0.1260 0.09458 0.07113 0.04306 0.0333
 Cumulative Proportion  0.3685 0.5400 0.6660 0.76056 0.83169 0.87475 0.9080
                            PC8     PC9    PC10    PC11      PC12
 Standard deviation     0.27398 0.26865 0.24615 0.20435 2.613e-16
 Proportion of Variance 0.02766 0.02659 0.02232 0.01539 0.000e+00
 Cumulative Proportion  0.93570 0.96229 0.98461 1.00000 1.000e+00

さらに同様に、動物のリスト list-mammal.txt を
 イヌ ネコ ウシ ブタ サル ゾウ シカ ウマ カバ クマ ウサギ ネズミ トラ イタチ
とし、同じ処理
 python readvecs.py list-mammal.txt
を行うと、出力 &ref(list-mammal.out); を得る。これをRにて主成分分析すると、

 > m1 <- read.csv('list-mammal.out', header=FALSE, row.names=1)
 > m2 <- prcomp(m1, scaling=FALSE)
 > summary(m2)
 Importance of components:
                           PC1    PC2    PC3    PC4     PC5     PC6     PC7
 Standard deviation     0.6970 0.5569 0.5103 0.4810 0.40739 0.33854 0.31129
 Proportion of Variance 0.2433 0.1553 0.1304 0.1158 0.08311 0.05739 0.04853
 Cumulative Proportion  0.2433 0.3986 0.5290 0.6448 0.72795 0.78534 0.83386
                            PC8     PC9    PC10    PC11    PC12    PC13
 Standard deviation     0.29464 0.25713 0.24042 0.23252 0.19974 0.16455
 Proportion of Variance 0.04347 0.03311 0.02894 0.02707 0.01998 0.01356
 Cumulative Proportion  0.87734 0.91044 0.93939 0.96646 0.98644 1.00000
                             PC14
 Standard deviation     1.625e-16
 Proportion of Variance 0.000e+00
 Cumulative Proportion  1.000e+00

が得られた。

これらを眺め渡すのに、まずは累積寄与率 Cumulative Proportion を並べてみると、
         PC1    PC2    PC3    PC4     PC5     PC6     PC7     PC8     PC9    PC10    PC11    PC12    PC13      PC14
 果物 0.3495 0.5885 0.7286 0.8336 0.90462 0.96344 1.00000 1.000e+00
 都市 0.3685 0.5400 0.6660 0.76056 0.83169 0.87475 0.9080 0.93570 0.96229 0.98461 1.00000 1.000e+00
 動物 0.2433 0.3986 0.5290 0.6448 0.72795 0.78534 0.83386 0.87734 0.91044 0.93939 0.96646 0.98644 1.00000 1.000e+00

これをグラフに書いてみよう。上記寄与率データをファイル &ref(list-list.txt); に作っておき、Rでこんなスクリプトを作ってみた。
 x <- read.table('list-list.txt', colClasses=c("character", rep("numeric",14)))
 pchs = c(15,16,17)
 par(pch=pchs[1])
 plot(as.numeric(x[1,]),xlim=c(1,14),ylim=c(0,1),xlab='',ylab='',type='o')
 par(new=T)
 par(pch=pchs[2])
 plot(as.numeric(x[2,]),xlim=c(1,14),ylim=c(0,1),xlab='',ylab='',type='o')
 par(new=T)
 par(pch=pchs[3])
 plot(as.numeric(x[3,]),xlim=c(1,14),ylim=c(0,1),xlab='# of dims',ylab='cumulative  proportion',type='o')
 labels <- rownames(x)
 legend("topleft", legend = labels, pch = pchs)

結果として得られた図は、~
&ref(list-list.png,,400x400);

この結果だと、同じカテゴリに属する単語を選んだのだが、それが単語ベクトル空間内での平面もしくは薄い平面になるような、(線形結合による)次元圧縮はできなかった。


**異なる種類の語が、クラスタを成すか? (2015-01-15〜16) [#kd188bd5]

***2グループの場合 [#q4566bdb]
語群として
 リンゴ バナナ ミカン イチゴ メロン イヌ ネコ ウシ ブタ サル ゾウ
を取る。前半が果物、後半が動物、いずれも5語ずつとした。

これに対して、語ベクトルを取り (&ref(list-fru-mam-out.txt);) クラスタリングを試みる。

 > f1 <- read.csv('list-fru-mam.out', header=FALSE, row.names=1)
 > fd1 <- dist(f1)
 > fd1
          リンゴ   バナナ   ミカン   イチゴ   メロン     イヌ     ネコ     ウシ    ブタ     サル
 バナナ 1.970062
 ミカン 1.790549 2.511023
 イチゴ 1.438550 2.063315 1.501940
 メロン 1.773539 2.211781 2.349659 1.837267
 イヌ   2.145225 2.680048 2.105527 2.218265 2.679541
 ネコ   2.006368 2.360916 2.290100 2.193245 2.568588 1.443856
 ウシ   2.755805 3.131311 2.091293 2.481934 3.203987 2.114679 2.557964
 ブタ   1.784726 2.219938 2.177678 1.930415 2.390244 1.359422 1.236227 2.329943
 サル   1.868444 2.040648 2.201255 2.124999 2.164924 1.925178 1.626010 2.526037  1.613498
 ゾウ   2.262009 2.446191 2.215216 2.186955 2.487413 1.794068 1.571855 2.237841  1.499698 1.601881
        
 > fk <- hclust(fd1, method="ward.D2")
 > plot(fk)

&ref(fru-mam.png,,400x400);

k-means法でクラスタ数=2とすると、
 > fkm <- kmeans(fd1, centers=2)
 > fkm
 K-means clustering with 2 clusters of sizes 6, 5
 
 Cluster means:
     リンゴ   バナナ   ミカン   イチゴ   メロン     イヌ     ネコ     ウシ
 1 2.137096 2.479842 2.180178 2.189302 2.582449 1.439534 1.405985 1.961077
 2 1.394540 1.751236 1.630634 1.368214 1.634449 2.365721 2.283844 2.732866
       ブタ     サル     ゾウ
 1 1.339798 1.548767 1.450890
 2 2.100600 2.080054 2.319557
 
 Clustering vector:
 リンゴ バナナ ミカン イチゴ メロン   イヌ   ネコ   ウシ   ブタ   サル   ゾウ
      2      2      2      2      2      1      1      1      1      1      1
 
 Within cluster sum of squares by cluster:
 [1] 22.49424 18.49027
  (between_SS / total_SS =  31.1 %)
となって、動物と果物の2つのクラスタに分かれた。

***3グループの場合 [#s508c61f]

 > fc1 <- read.csv('list-fru-mam-city.out', header=FALSE, row.names=1)
 > fcd1 <- dist(fc1)
 > fcd1
          リンゴ   バナナ   ミカン   イチゴ   メロン     イヌ     ネコ     ウシ    ブタ     サル     ゾウ     東京     大阪     京都     仙台
 バナナ 1.970062
 ミカン 1.790549 2.511023
 イチゴ 1.438550 2.063315 1.501940
 メロン 1.773539 2.211781 2.349659 1.837267
 イヌ   2.145225 2.680048 2.105527 2.218265 2.679541
 ネコ   2.006368 2.360916 2.290100 2.193245 2.568588 1.443856
 ウシ   2.755805 3.131311 2.091293 2.481934 3.203987 2.114679 2.557964
 ブタ   1.784726 2.219938 2.177678 1.930415 2.390244 1.359422 1.236227 2.329943
 サル   1.868444 2.040648 2.201255 2.124999 2.164924 1.925178 1.626010 2.526037  1.613498
 ゾウ   2.262009 2.446191 2.215216 2.186955 2.487413 1.794068 1.571855 2.237841  1.499698 1.601881
 東京   3.424360 3.638329 3.806821 3.663877 3.098019 3.586443 3.376725 4.459185  3.433395 3.174265 3.480218
 大阪   3.346723 3.395097 3.701793 3.555570 3.116262 3.534008 3.324191 4.300704  3.361214 3.159386 3.468155 2.063095
 京都   3.734754 3.862700 4.068500 3.920570 3.631977 3.824423 3.736952 4.549313  3.751813 3.479855 3.846242 2.241960 2.141106
 仙台   3.299348 3.614781 3.705851 3.539363 3.350149 3.491068 3.260330 4.101234  3.365073 3.205548 3.518331 2.645173 2.112040 2.766430
 札幌   3.221615 3.495529 3.559657 3.454006 3.157557 3.431812 3.206204 4.039476  3.299149 3.103612 3.328526 2.368928 2.040717 2.834629 1.725378
         
 > fck <- hclust(fcd1, method="ward.D2")
 > plot(fck)

&ref(fru-mam-city.png,,400x400);

k-means法で、クラスタ数=3として処理すると、
 > fckm <- kmeans(fcd1, centers=3)
 > fckm
 K-means clustering with 3 clusters of sizes 5, 5, 6
 
 Cluster means:
     リンゴ   バナナ   ミカン   イチゴ   メロン     イヌ     ネコ     ウシ
 1 3.405360 3.601287 3.768524 3.626677 3.270793 3.573551 3.380880 4.289982
 2 1.394540 1.751236 1.630634 1.368214 1.634449 2.365721 2.283844 2.732866
 3 2.137096 2.479842 2.180178 2.189302 2.582449 1.439534 1.405985 1.961077
       ブタ     サル     ゾウ     東京     大阪     京都     仙台     札幌
 1 3.442129 3.224533 3.528294 1.863831 1.671392 1.996825 1.849804 1.793930
 2 2.100600 2.080054 2.319557 3.526281 3.423089 3.843700 3.501898 3.377673
 3 1.339798 1.548767 1.450890 3.585038 3.524610 3.864766 3.490264 3.401463
 
 Clustering vector:
 リンゴ バナナ ミカン イチゴ メロン   イヌ   ネコ   ウシ   ブタ   サル   ゾウ
      2      2      2      2      2      3      3      3      3      3      3
   東京   大阪   京都   仙台   札幌
      1      1      1      1      1
 
 Within cluster sum of squares by cluster:
 [1] 24.64086 19.34918 26.03245
  (between_SS / total_SS =  71.1 %)
のように、3つのクラスタに分かれた。

**「関係性」を見る必要がある (2015-01-15〜16) [#y4785065]
西尾氏の本の第5章に従うと、「国と首都」のような、語間での関係を、並べてみる必要があるらしい。つまり、同じカテゴリーのものを集めても、その間の関係はよく見えてこない(=次元圧縮できない)。むしろ、日本と東京、ロシアとモスクワ、といった語の間の関係が、語ベクトル間の差分(〜距離)ベクトルの関係(類似性)として出てくる、という議論らしい。

試してみたい。

西尾氏の本の5章の図5-2でやっているのは、語ペアの間の距離として数値(スカラ)の距離を見るだけではなく(これはもともとのword2vecの実験で多数されている)、
語ベクトル空間内での語ペアの位置関係を、主成分分析で次元圧縮しているようである。

ファイル list-capital.txt
 東京 日本 ロシア モスクワ 中国 北京 トルコ アンカラ ポーランド ワルシャワ ドイツ ベルリン フランス パリ イタリア ローマ ギリシャ アテネ スペイン マドリード ポルトガル リスボン

を用意し、それぞれの語ベクトルを readvecs で取り出す。
 python readvecs.py list-capital.txt
生成された語ベクトルのファイルは &ref(list-capital.out); に格納される。


これをRを使って主成分分析すると、
 > w1 <- read.csv('list-capital.out', header=FALSE, row.names=1)
 > w2 <- prcomp(w1, scaling=TRUE)
 > summary(w2)
 Importance of components:
                           PC1    PC2    PC3     PC4     PC5     PC6     PC7
 Standard deviation     0.8322 0.7666 0.5991 0.45433 0.43011 0.41188 0.34593
 Proportion of Variance 0.2443 0.2073 0.1266 0.07282 0.06526 0.05985 0.04222
 Cumulative Proportion  0.2443 0.4516 0.5783 0.65108 0.71634 0.77619 0.81841
                            PC8     PC9    PC10    PC11    PC12    PC13    PC14
 Standard deviation     0.29572 0.27079 0.25856 0.23029 0.21238 0.18681 0.17795
 Proportion of Variance 0.03085 0.02587 0.02358 0.01871 0.01591 0.01231 0.01117
 Cumulative Proportion  0.84926 0.87513 0.89871 0.91742 0.93333 0.94564 0.95682
                           PC15    PC16    PC17    PC18    PC19    PC20    PC21
 Standard deviation     0.17483 0.14279 0.13705 0.13309 0.12062 0.10692 0.09475
 Proportion of Variance 0.01078 0.00719 0.00663 0.00625 0.00513 0.00403 0.00317
 Cumulative Proportion  0.96760 0.97479 0.98142 0.98767 0.99280 0.99683 1.00000
                             PC22
 Standard deviation     1.646e-16
 Proportion of Variance 0.000e+00
 Cumulative Proportion  1.000e+00
 
 > plot(w2$x, type="n")
 > text(w2$x, rownames(w1))

&ref(list-capital-pc.png,,800x800);

次に、語ベクトル空間上での語間の差分ベクトルを計算し、その差分ベクトルに対して主成分分析をしてみる。差分ベクトルは同じ次元内にあるのではないか、という問である。

差分を計算するために、vecdiff.py を作成した。
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 # vecdiff.py #
 
 import sys, string, codecs
 import numpy as np
 import math
 
 sys.stdout = codecs.getwriter('utf_8')(sys.stdout)
 argvs = sys.argv;  argc = len(argvs)
 
 # ベクトルをファイルから読み込む
 #wl = codecs.open("testvec.dat", 'r', encoding='utf-8').readlines()
 #for l in wl:
 #   print l
 #   for x in l.split(','):
 #     print x
 
 infname = argvs[1]
 fname = infname.split('.')[0]
 data = np.loadtxt(infname, delimiter=',', dtype=object)
 
 outfname = fname + '.diff'
 outf = codecs.open(outfname, 'w', encoding='utf-8')
 
 maxitem = len(data[:,0])
 for x in range(0,maxitem):
   for y in range(0,x):
     if (x!=y):
       diff = data[x,1:].astype(float) - data[y,1:].astype(float)
       #print diff
       #outf.write(str(('"'+data[x,0].decode('utf-8').strip('"')+'-'+data[y,0].decode('utf-8').strip('"')+'" ')))
       outf.write(('"'+data[x,0].decode('utf-8').strip('"')[0:2]+'-'+data[y,0].decode('utf-8').strip('"')[0:2]+'" '))
       for u in range(0,len(data[0,:])-1):
         outf.write(',' + str(diff[u]) + ' ')
       outf.write(str('\n'))

これを用いて、
 python vecdiff.py list-capital.out
として、list-capital.outに含まれる語ベクトルから、(すべての組合せについて)差分ベクトルを生成する。全部の組合せについて差分ベクトルを作ったものを &ref(list-capital.diff); に置き、そこから、正しい国名−首都のペアになったエントリーだけを抜き出したものを、&ref(list-capital-paired.diff); に置く。


まず、list-capital-pairad.diff を、前と同じように主成分分析する。
 > d1 <- read.csv('list-capital-paired.diff', header=FALSE, row.names=1)
 > d2 <- prcomp(d1, scaling=TRUE)
 > summary(d2)
 Importance of components:
                           PC1    PC2    PC3    PC4     PC5     PC6     PC7
 Standard deviation     0.8910 0.7424 0.6094 0.5435 0.52773 0.41172 0.39639
 Proportion of Variance 0.2762 0.1918 0.1292 0.1028 0.09689 0.05898 0.05467
 Cumulative Proportion  0.2762 0.4680 0.5972 0.6999 0.79683 0.85581 0.91047
                            PC8     PC9   PC10      PC11
 Standard deviation     0.31055 0.31016 0.2543 2.092e-16
 Proportion of Variance 0.03355 0.03347 0.0225 0.000e+00
 Cumulative Proportion  0.94403 0.97750 1.0000 1.000e+00
 
 > plot(d2$x, type="n")
 > text(d2$x, rownames(d1))

&ref(list-capital-diff.png,,800x800);

イタリア・ローマの関係はかなり外れており、日本・東京とギリシャ・アテネが多少外れているが、その他は割と集まっている感じがする。差分ベクトル間の距離(距離行列)を、R上でdist(d1) により計算すると
 > dd1 <- dist(d1)
 > dd1
 
             日本・東京  ソ・モス  中国・北京  トル・アン  ポー・ワル  ドイ・ベル  フラ・パリ  イタ・ロー  ギリ・アテ  スペ・マド
 ソ・モス       2.351636
 中国・北京     2.921458  1.847766
 トル・アン     2.632693  1.665206    1.851017
 ポー・ワル     2.534892  1.698815    2.175155    1.977977
 ドイ・ベル     2.581418  1.473037    2.075114    1.808661    1.644332
 フラ・パリ     2.504862  1.614954    1.916339    2.010471    1.730841    1.452563
 イタ・ロー     3.169835  2.634452    3.094171    2.689891    2.887835    2.676715    2.661344
 ギリ・アテ     3.704089  2.401050    2.273844    2.834751    2.814918    2.325160    2.326286    3.573224
 スペ・マド     2.902570  1.940497    2.565212    2.351040    2.125049    2.308997    2.181794    3.141020    2.946346
 ポル・リス     2.712275  1.774076    2.118614    2.114721    1.581006    1.644635    1.947070    3.004948    2.481797    2.259865
 

差分ベクトルをクラスタ化してみる。k-means法で、上記の観察からクラスタ数=3とすると、

 > dk <- kmeans(dd1, centers=3)
 > dk
 K-means clustering with 3 clusters of sizes 2, 8, 1
 
 Cluster means:
   日本・東京  ソ・モス  中国・北京  トル・アン  ポー・ワル  ドイ・ベル
 1    1.584917  2.493044    3.007815    2.661292    2.711363    2.629066
 2    2.642725  1.501794    1.818652    1.722387    1.616647    1.550917
 3    3.704089  2.401050    2.273844    2.834751    2.814918    2.325160
   フラ・パリ  イタ・ロー  ギリ・アテ  スペ・マド  ポル・リス
 1    2.583103    1.584917    3.638657    3.021795    2.858611
 2    1.606754    2.848797    2.550519    1.966557    1.679998
 3    2.326286    3.573224    0.000000    2.946346    2.481797
 
 日本・東京    ソ・モス  中国・北京  トル・アン  ポー・ワル  ドイ・ベル
           1           2           2           2           2           2
 フラ・パリ  イタ・ロー  ギリ・アテ  スペ・マド  ポル・リス
           2           1           3           2           2

となり、3つのクラスタ~
[(日本・東京)、(イタリア・ローマ)]~
[(ソ連・モスクワ)、(中国・北京)、(トルコ・アンカラ)、(ポーランド・ワルシャワ)、(ドイツ・ベルリン)、(フランス・パリ)、(スペイン・マドリード)、(ポルトガル・リスボン)]~
[(ギリシャ・アテネ)]~
を得た。

またクラスタ数を4とすると、(図を見て4カ所に分かれるので)
 > dk4 <- kmeans(dd1, centers=4)
 > dk4
 K-means clustering with 4 clusters of sizes 1, 1, 1, 8
 
 Cluster means:
   日本・東京  ソ・モス  中国・北京  トル・アン  ポー・ワル  ドイ・ベル
 1    3.704089  2.401050    2.273844    2.834751    2.814918    2.325160
 2    0.000000  2.351636    2.921458    2.632693    2.534892    2.581418
 3    3.169835  2.634452    3.094171    2.689891    2.887835    2.676715
 4    2.642725  1.501794    1.818652    1.722387    1.616647    1.550917
   フラ・パリ  イタ・ロー  ギリ・アテ  スペ・マド  ポル・リス
 1    2.326286    3.573224    0.000000    2.946346    2.481797
 2    2.504862    3.169835    3.704089    2.902570    2.712275
 3    2.661344    0.000000    3.573224    3.141020    3.004948
 4    1.606754    2.848797    2.550519    1.966557    1.679998
 
 Clustering vector:
 日本・東京    ソ・モス  中国・北京  トル・アン  ポー・ワル  ドイ・ベル
          2           4           4           4           4           4
 フラ・パリ  イタ・ロー  ギリ・アテ  スペ・マド  ポル・リス
          4           3           1           4           4
 
 Within cluster sum of squares by cluster:
 [1]  0.00000  0.00000  0.00000 29.95733
  (between_SS / total_SS =  59.4 %)


***全部の組合せのdiffは [#abdb8534]

では、全部の要素の組合せ(国名・首都に関わらず、つまり国名−国名等も含む)で差分ベクトルを作って、その差分ベクトルを主成分分析してみる。考えていることは、いろいろな差分の中で、特定の国名−首都の組合せの差分だけが、何か別枠になっていることがないか、という点である。 表示がうっとうしいので、差分ベクトルの対称分を省略している。

まず、差分ベクトルをクラスタ化してみる。階層化クラスタリングだと、
 > a1 <- read.csv('list-capital.diff', header=FALSE, row.names=1)
 > ad <- dist(a1)
 > ah <- hclust(ad, method="ward.D2")
 > par(cex=0.7)
 > plot(ah)

&ref(list-capital-diff-hclust.png,,40%);

おもしろいのは、都市ごと・国ごとにグループ化される傾向があることである。
左から見ると、アテネと何か、マドリードと何か、という具合にグループ化されている。更に、アテネグループの中で、アテネ・国名と、アテネ・都市名が、何となく分離している。次のマドリードの場合だともっと顕著に、相手が国名か都市名かで分離している。
何かの「カテゴリー」を検出しているようだ。

では、k-mean法だとどうなるか。クラスタ数をいくつにするかという問題があるが、
階層化クラスタリングの結果を参考にすると、それぞれの都市名に対して都市名・国名のペアと、都市名・都市名のペアがあるので、11の都市名に対して22クラスタができる可能性がある。 k=22 で試す。

 > ak <- kmeans(ad, centers=22)
 > ak
 K-means clustering with 22 clusters of sizes 11, 9, 5, 3, 35, 7, 8, 9, 15, 10, 5, 7, 13, 16, 11, 9, 5, 16, 3, 3, 17, 14
 
 Clustering vector:
 日本-東京  ロシ-東京  ロシ-日本  モス-東京  モス-日本  モス-ロシ  中国-東京
         13         13         10          7          4         14         13
 中国-日本  中国-ロシ  中国-モス  北京-東京  北京-日本  北京-ロシ  北京-モス
         10         12         12          7          6          1         12
 北京-中国  トル-東京  トル-日本  トル-ロシ  トル-モス  トル-中国  トル-北京
         14         13         10          5         21          9         16
 アン-東京  アン-日本  アン-ロシ  アン-モス  アン-中国  アン-北京  アン-トル
          7          6         14          5          3          9         14 
 ポー-東京  ポー-日本  ポー-ロシ  ポー-モス  ポー-中国  ポー-北京  ポー-トル
         13         10          5         21          9         16          5
 ポー-アン  ワル-東京  ワル-日本  ワル-ロシ  ワル-モス  ワル-中国  ワル-北京
         22          7          6         14          5          3          9
 ワル-トル  ワル-アン  ワル-ポー  ドイ-東京  ドイ-日本  ドイ-ロシ  ドイ-モス
          8         18         14         13         10          5         22
 ドイ-中国  ドイ-北京  ドイ-トル  ドイ-アン  ドイ-ポー  ドイ-ワル  ベル-東京
          9         16         18         22         18         22          7
 ベル-日本  ベル-ロシ  ベル-モス  ベル-中国  ベル-北京  ベル-トル  ベル-アン
          4          8         18          3          9          8         18
 ベル-ポー  ベル-ワル  ベル-ドイ  フラ-東京  フラ-日本  フラ-ロシ  フラ-モス
          8         18          8         13         10         18         22
 フラ-中国  フラ-北京  フラ-トル  フラ-アン  フラ-ポー  フラ-ワル  フラ-ドイ
          9         16         18         22         18         22         18
 フラ-ベル  パリ-東京  パリ-日本  パリ-ロシ  パリ-モス  パリ-中国  パリ-北京
         22          7          4          8         18          3          9
 パリ-トル  パリ-アン  パリ-ポー  パリ-ワル  パリ-ドイ  パリ-ベル  パリ-フラ
          8         18          8         18          8          5         14
 イタ-東京  イタ-日本  イタ-ロシ  イタ-モス  イタ-中国  イタ-北京  イタ-トル
         13         10          5         22          9         16         18
 イタ-アン  イタ-ポー  イタ-ワル  イタ-ドイ  イタ-ベル  イタ-フラ  イタ-パリ
         22         18         22          5         21          5         21
 ロー-東京  ロー-日本  ロー-ロシ  ロー-モス  ロー-中国  ロー-北京  ロー-トル
         13          6         15         17          9         16         15
 ロー-アン  ロー-ポー  ロー-ワル  ロー-ドイ  ロー-ベル  ロー-フラ  ロー-パリ
         17         15         17         15         17         15         17
 ロー-イタ  ギリ-東京  ギリ-日本  ギリ-ロシ  ギリ-モス  ギリ-中国  ギリ-北京
         15         13         10          5         21          9         16
 ギリ-トル  ギリ-アン  ギリ-ポー  ギリ-ワル  ギリ-ドイ  ギリ-ベル  ギリ-フラ
          5         22          5         21          5         21          5
 ギリ-パリ  ギリ-イタ  ギリ-ロー  アテ-東京  アテ-日本  アテ-ロシ  アテ-モス
         21          5         12         13          6          1         11
 アテ-中国  アテ-北京  アテ-トル  アテ-アン  アテ-ポー  アテ-ワル  アテ-ドイ
          1          9          1         11          1         11          1
 アテ-ベル  アテ-フラ  アテ-パリ  アテ-イタ  アテ-ロー  アテ-ギリ  スペ-東京
         11          1         11          1          1          1         13
 スペ-日本  スペ-ロシ  スペ-モス  スペ-中国  スペ-北京  スペ-トル  スペ-アン
         10          5         21          9         16          5         22
 スペ-ポー  スペ-ワル  スペ-ドイ  スペ-ベル  スペ-フラ  スペ-パリ  スペ-イタ
          5         21          5         21          5         21          5
 スペ-ロー  スペ-ギリ  スペ-アテ  マド-東京  マド-日本  マド-ロシ  マド-モス
         12          5         20          7          6          2         15
 マド-中国  マド-北京  マド-トル  マド-アン  マド-ポー  マド-ワル  マド-ドイ
         19         19          2         15          2         15          2
 マド-ベル  マド-フラ  マド-パリ  マド-イタ  マド-ロー  マド-ギリ  マド-アテ
         15          2         15          2          2          2         19
 マド-スペ  ポル-東京  ポル-日本  ポル-ロシ  ポル-モス  ポル-中国  ポル-北京
          2         13         10          5         21          9         16
 ポル-トル  ポル-アン  ポル-ポー  ポル-ワル  ポル-ドイ  ポル-ベル  ポル-フラ
          5         22          5         21          5         21          5
 ポル-パリ  ポル-イタ  ポル-ロー  ポル-ギリ  ポル-アテ  ポル-スペ  ポル-マド
         21          5         12          5         20          5         21
 リス-東京  リス-日本  リス-ロシ  リス-モス  リス-中国  リス-北京  リス-トル
          7          6         14          5          3          9         14
 リス-アン  リス-ポー  リス-ワル  リス-ドイ  リス-ベル  リス-フラ  リス-パリ
         18         14          5         14          5         14          5
 リス-イタ  リス-ロー  リス-ギリ  リス-アテ  リス-スペ  リス-マド  リス-ポル
         14          1         14         20         14         12         14
 
 Within cluster sum of squares by cluster:
  [1] 300.610775 119.236551  59.882213   9.885346 630.596354 230.907256
  [7] 194.960225  96.064969 417.729167 153.298504  64.629177 245.088509
 [13] 339.733609 240.028695 349.731117 127.867876  51.019780 304.450561
 [19]  71.439988  64.700711 243.915489 212.425544
  (between_SS / total_SS =  83.5 %)

更に、差分ベクトルを主成分分析をしてみる。

 > a1 <- read.csv('list-capital.diff', header=FALSE, row.names=1)
 > a2 <- prcomp(a1, scaling=TRUE)
 > summary(a2)
 Importance of components:
                           PC1    PC2    PC3     PC4     PC5    PC6     PC7
 Standard deviation     1.1666 0.9428 0.8365 0.63844 0.58822 0.5556 0.48425
 Proportion of Variance 0.2605 0.1702 0.1340 0.07803 0.06624 0.0591 0.04489
 Cumulative Proportion  0.2605 0.4307 0.5647 0.64272 0.70896 0.7681 0.81295
                            PC8    PC9    PC10    PC11    PC12    PC13    PC14
 Standard deviation     0.39755 0.3838 0.34650 0.32444 0.28898 0.25229 0.24864
 Proportion of Variance 0.03026 0.0282 0.02299 0.02015 0.01599 0.01219 0.01184
 Cumulative Proportion  0.84320 0.8714 0.89439 0.91454 0.93053 0.94271 0.95455
                           PC15    PC16    PC17    PC18   PC19    PC20    PC21
 Standard deviation     0.23808 0.20175 0.19421 0.18489 0.1679 0.14828 0.13396
 Proportion of Variance 0.01085 0.00779 0.00722 0.00654 0.0054 0.00421 0.00344
 Cumulative Proportion  0.96540 0.97319 0.98041 0.98696 0.9924 0.99656 1.00000
                             PC22      PC23      PC24      PC25      PC26
 Standard deviation     5.837e-16 3.244e-16 2.721e-16 2.297e-16 2.172e-16
 Proportion of Variance 0.000e+00 0.000e+00 0.000e+00 0.000e+00 0.000e+00
 Cumulative Proportion  1.000e+00 1.000e+00 1.000e+00 1.000e+00 1.000e+00
 
 (以下省略)
 
                             PC97      PC98      PC99     PC100
 Standard deviation     5.048e-17 4.608e-17 4.156e-17 2.495e-17
 Proportion of Variance 0.000e+00 0.000e+00 0.000e+00 0.000e+00
 Cumulative Proportion  1.000e+00 1.000e+00 1.000e+00 1.000e+00
 
 > par(cex=0.5)
 > plot(a2$x, type="n")
 > text(a2$x, rownames(a1))

図に描くと

&ref(list-capital-all.png,,80%);

累積寄与率を見ると、90%に至るにはPC10まで必要である。

また図の中で傾向を探すことも難しそうだ。


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

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