光の早さでsentence2vec使ってみた。

sentence2vec 動かした - laughingのブログに触発されて、昔やったword2vecの拡張版っぽいやつのsentence2vecをやってみる。
最近メタアナリシスに忙しいので論文は全く読まずにライブラリを使ってやっちゃうダメなやつである。
コーパスはとある医療系テキストを使った。もともとは20MBくらい。
これを文字だけのテキストデータであるtest.txtにする。これは半角区切りで文章がひたすら続いていればいい。
sentence2vecは文章単位でのベクトル演算が可能になるっぽいアルゴリズムっぽいもので、1文章が1行のファイルであるsent.txtを作成する。

# Pythonで
file = "text.txt"
f = open(file, "rU")
# 特殊文字の削除
rep = ['[', ']', '#', '&', ',', ';', ':', '(', ')', '%', '<', '>', '!', '?'] + map(str, range(0, 10))

res = []
for line in f:
	tmp = line.rstrip().lower()
	for i in rep:
		tmp = tmp.replace(i, "")
	
	res += [" " + tmp]

res = unicode("".join(res), "ascii", "ignore") # ' や α などを取り除く。
w0 = open("test.txt", "w")
w0.write(res.replace(".", ""))
w0.close()

res1 = res.split(".") # . で文章単位で1行になっている、ということにする。
w0 = open("sent.txt", "w")
for i in res1:
	w0.write(i + "\n")

w0.close()

これで入力データができた。
sentence2vecのdemo.pyは、word2vecとsentence2vecのどちらも実行するようになっているので気長に待つ。
2時間弱待ってword2vec実行後のtest.txt.vecが24MB、sentence2vec実行後のsent.txt.vecが170MBくらいのものができた。時間がかかりすぎる場合はオプションのベクトル次元数をいじればいい。
 
test.txt.vecの結果はこちら。コーパス内の単語数とベクトル次元はこうなる。

# test.txt.vec
25222 100
the 0.116980 -0.177670 0.334393 -0.083892 -0.144798 -0.056806 -0.373836 -0.002931 -0.102459 0.275562 -0.090770 -0.079841 0.025352 -0.310755 -0.142552 0.160147 -0.061221 0.085489 -0.080151 -0.175332 0.040710 -0.012896 -0.085050 -0.280277 0.029606 0.042688 -0.138835 0.442679 0.167368 0.391008 0.163348 0.058577 -0.189532 -0.068764 0.196751 -0.062043 -0.263244 0.106796 0.247118 0.225896 0.124060 0.081417 0.181844 0.060523 0.269512 -0.061750 0.179639 0.071806 -0.019324 -0.072994 -0.258610 0.326965 0.010802 0.129078 0.226204 0.149128 0.157377 -0.170974 -0.165566 0.027354 0.349809 -0.072913 -0.025090 -0.035087 -0.101824 -0.050989 -0.360751 0.219851 -0.400203 -0.019248 0.150906 -0.127538 -0.025823 0.179442 -0.573239 0.181908 0.224479 -0.053886 0.022851 0.078715 0.270700 0.086844 0.193476 -0.116758 -0.097282 0.342317 -0.030158 -0.252276 0.065481 -0.009350 -0.082443 0.000299 -0.172476 0.016123 -0.176677 0.095456 0.110286 -0.145078 -0.145358 -0.115610
of -0.055226 0.030355 -0.194448 0.022834 0.343762 -0.379061 0.697046 -0.167625 0.383166 -0.021791 -0.037873 -0.169079 0.050516 -0.320152 -0.065604 0.262059 0.310838 0.101314 0.083397 -0.015304 -0.297676 0.086297 -0.053756 -0.225387 -0.049301 0.418623 0.057814 0.015822 0.024149 0.458939 -0.024714 0.234658 0.199269 0.126527 0.226257 -0.296661 -0.146221 -0.049912 -0.277486 -0.006324 0.008214 -0.226396 -0.095007 0.040760 -0.003855 0.355840 -0.231565 -0.056786 -0.074291 0.057808 -0.060201 -0.242923 -0.141219 0.042631 -0.270568 -0.382428 0.104403 -0.086382 -0.130320 0.037442 0.067218 -0.213910 -0.132597 0.054474 0.000217 -0.052158 0.124145 0.007163 0.078557 0.133388 -0.027024 -0.210486 0.145471 -0.044883 0.017042 -0.208468 -0.257370 0.412816 -0.073427 -0.155531 -0.121383 -0.272382 0.050018 -0.001605 0.238857 0.080981 0.082283 -0.023772 -0.038628 -0.398496 0.161026 -0.377211 -0.027127 0.344358 0.123647 0.210355 0.103308 -0.012144 0.247145 -0.038463

 
sent.txt.vecの結果はこちら。コーパス内の単語数とベクトル次元はこうなる。入力したsent.txtの行IDと一致するのであとで探せる。

# sent.txt.vec
181364 100
sent_0 -0.228808 -0.036884 -0.140708 -0.294131 0.062093 0.200158 -0.015975 -0.222824 -0.405780 -0.031346 -0.478011 0.020063 -0.190374 0.101430 -0.200574 -0.337594 -0.129126 0.238390 0.220285 -0.323609 -0.424170 0.207937 0.193231 0.325193 0.361575 0.271062 -0.312593 0.426731 -0.172794 0.099045 0.191219 0.249147 -0.329888 -0.140088 -0.029720 -0.642521 0.397162 0.139624 0.266282 -0.354639 0.800223 -0.154193 0.240487 0.148841 -0.398626 0.116973 0.127689 0.047644 0.220390 -0.060153 -0.067981 -0.377255 -0.045188 0.263967 -0.250186 0.312383 0.033706 -0.052752 0.315506 -0.095276 0.143078 0.117022 -0.239076 0.174319 0.148838 0.268929 0.298261 -0.052090 0.255270 -0.027655 0.858588 0.378020 -0.156231 -0.019227 -0.009059 0.237308 -0.153779 -0.180625 -0.272600 -0.332033 0.540318 -0.181632 0.019558 -0.130305 -0.268125 0.252307 0.114354 0.314812 -0.266849 -0.031428 0.429367 0.019560 0.014925 -0.460187 -0.016962 0.321848 -0.421457 -0.087517 -0.029916 0.243982
sent_1 -0.145014 0.050516 -0.018690 -0.072142 0.389861 -0.029410 -0.128896 0.050734 -0.195057 -0.094339 0.026966 -0.142618 0.245177 0.094958 -0.001161 -0.019187 0.012995 -0.136440 0.233531 0.059154 -0.422856 -0.022292 -0.206395 0.183306 0.135693 0.082426 -0.273590 -0.276868 -0.285319 -0.004387 -0.033742 0.091095 -0.150832 0.264567 0.291805 -0.053973 0.153894 0.132558 0.060756 0.153311 0.196707 -0.020911 0.250817 0.033775 0.107564 0.102860 0.078208 0.250585 0.119277 -0.019731 -0.002878 -0.170948 -0.084251 0.285322 -0.275500 0.129299 0.301445 -0.137811 0.157843 0.096887 -0.004338 -0.029380 -0.089423 0.030257 -0.135602 -0.009559 0.139020 -0.194846 0.008805 0.114778 0.165475 -0.102759 0.143076 -0.087238 -0.013653 -0.327399 0.009718 -0.112409 -0.142979 -0.058942 0.208973 -0.134463 -0.231528 0.035542 -0.131102 0.107795 0.054123 0.312880 0.029978 -0.245107 0.044272 -0.030367 -0.070682 -0.067220 0.011433 0.109598 -0.128850 -0.050654 -0.019510 0.112609

 
word2vecの結果を見てみる。ピリオドを処理し忘れたのであれだが、化学療法(chemotherapy)と言えばcyclophosphamideやcisplatinのようである。古典的な細胞障害性抗癌剤が挙がった。

# Python
import os
os.chdir("/sentence2vec-master/")
from word2vec import Word2Vec, Sent2Vec, LineSentence
model1 = Word2Vec.load_word2vec_format("test.txt.vec", binary=False)
a = model1.most_similar([u"chemotherapy"])
for x in a:
	print x[0] + "\t" + str(x[1])
chemotherapy.	0.592872321606
cyclophosphamide	0.536337733269
cisplatin	0.499094545841
carcinogenesis	0.473640620708
leflunomide	0.468907207251
reversion	0.466912925243
tamoxifen	0.456218272448
therapy.	0.449881106615
trimethoprim	0.444862633944
treatment	0.444471091032

  
sentence2vecの結果を見てみる。どんな文章を元に見ようかと思って、適当にクロールした結果

obesity increases a womanfs risk for certain cancers in particular postmenopausal breast and endometrial cancer in part because adipose tissue provides an extragonadal source of estrogen through aromatization of circulating adrenal and ovarian androgens especially the conversion of androstenedione to estrone

肥満は閉経後の乳癌および子宮内膜癌のリスクを高める。というのも、脂肪組織は性腺以外のエストロゲン分泌構造物であり、副腎や卵巣の男性ホルモンを芳香化(女性ホルモン化)する。これは特にアンドロステンジオンをエストロンに変換することを言っている。
 
乳癌や生殖器の腫瘍は性ホルモン感受性で、これらのホルモンによって増殖が促進されるということがわかっている。なのでこれらのホルモンをブロックすることが治療戦略としてある、というのが背景。
 

from word2vec import Word2Vec, Sent2Vec, LineSentence
model2 = Word2Vec.load_word2vec_format("sent.txt.vec", binary=False)
sent = [f.strip() for f in open("sent.txt", "rU")]
i = 2617 # 文章の行ID
a = model2.most_similar(["sent_" + str(i)])

for x in a:
	print sent[int(x[0][5:])] + "\t" + str(x[1])
	# print x[0] + "\t" + str(x[1])
sent_96771	0.556594848633
sent_47695	0.545332014561
sent_52011	0.542452573776
sent_51840	0.537765681744
sent_106931	0.537760913372
sent_48695	0.533379197121
sent_48603	0.533295929432
sent_47594	0.530121922493
sent_106756	0.520916998386
sent_52214	0.519094884396

で、どんな文章がひっかかったかというと

ovarian secretion of estradiol and progesterone controls the shedding of the endometrium resulting in menses and in combination with the inhibins provides feedback regulation of the hypothalamus and pituitary to control secretion of fsh and lh

性ホルモンの分泌の話や

regulation of testicular function regulation of the hypothalamic-pituitary-testis axis in adult man hypothalamic gnrh regulates the production of the pituitary gonadotropins lh and fsh fig

それに対応する男性ホルモンの話や

targeted deletion of the insulin receptor in adipose tissue protect against obesity apparently by increasing energy expenditure

脂肪組織の話が出てきたわけだが、性ホルモンや副腎皮質ホルモン、受容体などの薬理学的な話ばっかりが出てきて、ぶっちゃけ癌の話が出てきて欲しかった。
 
結論:興味のある人は論文原著を読んで教えてください。