[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
[[ノート>ノート/ノート]]
[[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語と同様に、クラスタ数が非常に少ない。分散した結果になっている
と思われる。
終了行:
[[ノート>ノート/ノート]]
[[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語と同様に、クラスタ数が非常に少ない。分散した結果になっている
と思われる。
ページ名: