[[ノート/テキストマイニング]]~
訪問者数 &counter();      最終更新 &lastmod();~

[[参照>ノート/ハックメモ2014前半]] 2014-03-12の項
-2014-03-12 あと、[[教師なしLDAでTwitterのスパム判別をしてみる(予備実験編):http://yamitzky.hatenablog.com/entry/2014/02/17/000201]]  関連では [[単語の頻度からLDAまでの流れの簡単なイメージのメモ:http://sucrose.hatenablog.com/entry/20120322/p1]]、 [[LDAでトピック分析:http://yuralike.blog.fc2.com/blog-entry-554.html]]、 [[LDA等のトピックモデル:http://www.slideshare.net/mathieu_bertin/lda-15615867]]、 [[latent Dirichlet allocation (LDA) :http://ibisforest.org/index.php?cmd=read&page=latent%20Dirichlet%20allocation]]、 [[LDA入門:http://www.slideshare.net/tsubosaka/tokyotextmining]]、 [[LDAを用いた著者推定:http://db-event.jpn.org/deim2011/proceedings/pdf/f4-3.pdf]]、[[LSIやLDAを手軽に試せるGensimを使った自然言語処理入門:http://yuku-tech.hatenablog.com/entry/20110623/1308810518]]

これの、最後の項: [[LSIやLDAを手軽に試せるGensimを使った自然言語処理入門:http://yuku-tech.hatenablog.com/entry/20110623/1308810518]] を参照しながらやってみる。


*2014-07-11 gensimの導入 [#s0af6dd1]

対象はmint

pythonは既に入っているので、numpy, scipy等を導入したい。そのためにはBLAS等が必要。

参考=[[Centos6.0上のインストール例:http://deeplearning.net/software/theano/install_centos6.html#install-centos6]]
-Python 2.4以上
 yum install python-devel
-OpenSSL-develがないため、pythonでHTTPSが見えないというエラー
 yum install opensll-devel
-BLAS, LAPACK, ATLAS
 yum install blas-devel lapack-devel atlas-devel
-setuptools
 wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | python
-pip  [[pipのサブコマンドはここ:https://pypi.python.org/pypi/pip]]
 easy_install pip
-NumPy
 pip install numpy (numpy==1.6.1)
-SciPy
 pip install scipy (scipy==0.10.1)
-nose
 pip install nose
-Sphynx
 pip install sphinx
-Git インストール済み
-pydot
 pip install pydot

なお、CUDAはデバイスが無いので、無し。

これで、gensimが入れられるので、gensimのHPの[[インストールマニュアル:http://radimrehurek.com/gensim/install.html]] に従ってインストール
 pip install --upgrade gensim

word2vecを試してみたい([[models.word2vec – Deep learning with word2vec:http://radimrehurek.com/gensim/models/word2vec.html#id4]]、 [[Word2vec Tutorial:http://radimrehurek.com/2014/02/word2vec-tutorial/]] のだが、入力コーパスデータをどうするか。

[[models.word2vec – Deep learning with word2vec:http://radimrehurek.com/gensim/models/word2vec.html#id4]] にある説明だとBrownCorpus (NLTKからパクれる)、Text8Corpus(C版のWord2Vecの時にダウンロード済み)があるが、text8で試すと、有名な
 model.most_similar(positive=['woman', 'king'], negative=['man'], topn=1)
 [('queen', 0.50882536)]
が出てこない。

もう少し挑戦を要する。別途日本語データを試してみたい。たとえば [[ニューラルネットによる単語のベクトル表現の学習 〜 Twitterのデータでword2vecしてみた:http://yamitzky.hatenablog.com/entry/2014/03/11/222223]] の辺を再現してみたい。

あとは、[[ニューラルネットによる単語のベクトル表現の学習 〜 Twitterのデータでword2vecしてみた:http://yamitzky.hatenablog.com/entry/2014/03/11/222223]] のように、しこしこやるか。
 
追記: 日本語対象ではないが、[[Gensimを使ったトピック単語抽出 LSAを使ったトピック語抽出まで:http://kensuke-mi.hatenablog.com/entry/20131021/1382384297]] にやはりgensimを援用した例がある。ペルシャ語だそうな。

*ここから、[[LSIやLDAを手軽に試せるGensimを使った自然言語処理入門:http://yuku-tech.hatenablog.com/entry/20110623/1308810518]] に従う [#beb3fc84]

***Wikipediaからコーパスを作成する [#d056270f]
まずjawikiの内容を持ってくる。大分前(ファイル日付は2013-05-08になっている)にダウンロードしたものがあるので、それを使う。

このページ[[LSIやLDAを手軽に試せるGensimを使った自然言語処理入門:http://yuku-tech.hatenablog.com/entry/20110623/1308810518]]にあるjawikicorpus.pyは、
 python jawikicorpus.py jawiki-latest-pages-articles.xml.bz2 jawiki
ではエラーが出てうまく動かなかった。⇒

このエラーの原因は、gensimのバージョンが現時点最新が0.10.0であり、
 pip install gensim
でインストールするとこれが入る。ところが、jawikicorpus.pyは0.7.2見当をベースにしてオーバーライドしているので、そもそも中身のメソッド名が変わっているし、引数も変わっている。そこで、
 pip install "gensim<0.7.4"
ぐらいのことをして、gensimの古いバージョンを再インストールすると、動いた。 

出来た3つのファイルを、
-[[gensimを使ったwikipediaのコーパス作成:http://hivecolor.com/id/56]]
-[[gensim0.8.6のチュートリアルをやってみた【コーパスとベクトル空間】:http://hivecolor.com/id/58]]
-[[gensim0.8.6のチュートリアルをやってみた【Topics and Transformations】:http://hivecolor.com/id/59]]
-[[gensim0.8.6のチュートリアルをやってみた【Similarity Queries】:http://hivecolor.com/id/60]]
に沿って試してみたい。



*wp2txtを使う方法 [#mdd9f21f]
wp2txtでウィキペディアダンプファイル(XML形式)からXMLタグやその他の不要部分を取り除いて、テキストのみにすることができる。rubyで動く。(最新バージョン環境では動かず、動くまで結構面倒だったが、ruby 2.0.0のバージョンで動いた。)


まずrubyをインストールする。以下の方法だと個人ユーザごとにインストールする。
-[[rbenv を使って ruby をインストールする(CentOS編):http://qiita.com/inouet/items/478f4228dbbcd442bfe8]]
-[[rbenv を利用した Ruby 環境の構築:http://dev.classmethod.jp/server-side/language/build-ruby-environment-by-rbenv/]]

ではなくて、システムワイドにrubyをインストールするには、
-[[rbenv+ruby-buildをインストールする手順 (CentOS/RedHat):http://weblabo.oscasierra.net/install-rbenv-rubybuild-to-redhat/]]
-続き [[Rubyをrbenv+ruby-buildを利用してインストールする手順 (CentOS/RedHat):http://weblabo.oscasierra.net/rbenv-install-ruby-to-redhat-1/]]
 以下rootで
 cd /usr/local   /usr/localへインストールする
 git clone git://github.com/sstephenson/rbenv.git
 echo 'export RBENV_ROOT="/usr/local/rbenv"' >> /etc/profile  パスを通す
 echo 'export PATH="${RBENV_ROOT}/bin:${PATH}"' >> /etc/profile
 echo 'eval "$(rbenv init -)"' >> /etc/profile
 source /etc/profile 一応やっておく
 
 mkdir /usr/local/rbenv/plugins
 cd /usr/local/rbenv/plugins
 git clone git://github.com/sstephenson/ruby-build.git
 
 rbenv install -l  パッケージ確認
 ### rbenv install 2.1.2  2.1以降ではbzip2-ruby-r20がコンパイルエラーなので
 rbenv install 2.0.0-p481  2.0をインストールする
 rbenv global 2.0.0-p481  デフォルトを2.0.0-p481にする
 ruby -v   インストール確認

これで、wp2txtのインストールができるようになった


-(本家)[[Rubyのインストール:https://www.ruby-lang.org/ja/installation/#rbenv]]
gemの使い方
-[[RubyGems (gem) の使い方・インストール方法:http://allabout.co.jp/gm/gc/439246/2/]]

wp2txtのありかは[[githubのここ:https://github.com/yohasebe/wp2txt/blob/master/bin/wp2txt]] だが、知らなくても済む。

wp2txtのインストールは、
-前提は[[ここ:https://rubygems.org/gems/wp2txt]]に書いてあるとおり、
bzip2-ruby-rb20、nokogiri、sanitize、trollopが必要。
 gem install bzip2-ruby-rb20 nokogiri sanitize trollop
などとしてインストールできる。

-次に、wp2txtのインストール。 ちなみに中身は[[wp2txt:https://github.com/yohasebe/wp2txt]]にある
 gem install wp2txt

追加で、
 gem install bundler
が必要になる。

ここでようやく、プログラムwp2txtが使えるのだが、その前に、自ユーザの環境で、実際に使う作業ディレクトリ下で、bundleの設定(ruby使用時の最初)
 bundle init
ファイル (作業ディレクトリ)/Bundleを、テキストエディタで編集し、使うgemを登録。書き方はこんな感じ (参考 [[Ruby書くならBundler使え:http://shokai.org/blog/archives/7262]])
 source 'https://rubygems.org'
 gem 'bzip2-ruby-rb20'
 gem 'nokogiri'
 gem 'sanitize'
 gem 'trollop'
 
 #gem 'json', '~> 1.7'     バージョンを指定したい時
 #gem 'tw', :git => 'git@github.com:shokai/tw.git'  取ってくる元を指定したいとき

こうしておいて、後はwp2txtを起動して処理すればよい。-oは出力ディレクトリ指定
 wp2txt --input-file jawiki-latest-pages-articles.xml.bz2 -o ./

出力のイメージは、以下のようなファイルができて、
 jawiki-latest-pages-articles.xml-001.txt
 jawiki-latest-pages-articles.xml-002.txt
 ...
 jawiki-latest-pages-articles.xml-379.txt
 jawiki-latest-pages-articles.xml-380.txt

その内容は、たとえば&ref(wp2txt_output_sample.txt);のような形になっている。

更にここから、
-[tpl]...[/tpl]を取り除く。
-行単位で見て、"#"で始まる行を取り除く。


***追加 [#ea4d0c9b]
2014-08-14付けの(少し新しい)記事  [[wp2txtでwikipediaのコーパスを作るまでの道のり:http://qiita.com/wwacky/items/8a9eb543171afea90c0a]]


***追加 [#jd5d85c3]
英文用だが、NLTK向けのウィキペディアコーパスのパッケージとして、[[pavlobaron/wpcorpus:https://github.com/pavlobaron/wpcorpus]] がある。

----
***別にページを立てて、日本語Wiki Corpusをさらに追求する(2015-01-08) [#lb3e7fb0]
 >> [[ノート/テキストマイニング/gensim-word2vecでベクトル空間を試す]]
 >> [[ノート/テキストマイニング/gensim-word2vecでベクトル空間を試す]]~
 >> [[ノート/テキストマイニング/gensim-word2vecでベクトル空間を試す2]]

----
*自前でtwitterからコーパスファイルを作ってみる [#t8c9b2f7]
参考にしたのは、[[自然言語処理の最新手法"word2vec"で艦これ加賀さんから乳を引いてみる:http://antibayesian.hateblo.jp/entry/2014/03/10/001532]]

やり方は、
-twitterの本文(テキスト)を形態素解析して、単語列(分かち書き)を作る。
-それを入力としてコーパス(モデル)を作る。
-足し算や引き算をして遊ぶ。

まず、twitterデータをファイルに落としておく。
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 import sys
 import codecs
 import time
 import MySQLdb
 import string
 import time
 import datetime
 from dbinit import dbinit
 sys.stdout = codecs.getwriter('utf_8')(sys.stdout)
 
 def generatefile(year, month, day):
   df = datetime.datetime(year, month, day)
   filename = 'data/' + u'tw' + df.strftime("%y%m%d")  # file per day
   outf = open(filename, 'w')
 
   for hour in range(0, 24):
     d = datetime.datetime(year, month, day, hour)  # DB table per hour
     tablename = u'tw' + d.strftime("%y%m%d%H")
 
     con = dbinit()
     cur = con.cursor()
     s = ("SELECT text FROM " + tablename ).encode('utf_8')
     cur.execute(s)
 
     r = cur.fetchone()
     while r != None:
         outf.write((r[0].replace('\n',''))+'\n')  #内部の\nは抜く、最後に\nを付ける
         r = cur.fetchone()
     cur.close()
     con.close()
 
   outf.close()
 
 year = 2014;  month = 6; day = 1
 argvs = sys.argv
 if len(argvs) < 2:
     print 'Usage: python %s day' % argvs[0]
     quit()
 lastday = int(argvs[1])
 for day in range(1,lastday+1):
   generatefile(year, month, day)
結果はたとえば
 午前零時丁度です!
 今日お父さんとお兄の子供が誕生日だおめでとう
みたいな感じのファイルになる。

次に、いま仮に、形態素解析で問題になりそうな(余分な名詞等を生成する)文字を先に取り除いてしまう。これがいいかどうかはよくわからない。その後、MeCabで単語に分ける。分かち書き指定でもよいが、どうせあとで「名詞だけ」とかやりたくなるので、丁寧に通しておく。
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 import os
 import sys
 import re
 import codecs
 import MeCab
 import string
 import datetime
 sys.stdout = codecs.getwriter('utf_8')(sys.stdout)
 argvs = sys.argv
 if len(argvs) < 2:
     print 'Usage: python %s directory' % argvs[0]
     quit()
 
 mt = MeCab.Tagger()
 r = re.compile(u'[a-zA-Z0-9a-zA-Z0-9_@:/\?#\(\)\*\^\.ヾ∀´▽←→⇒●○◎ ■□◇∧+∩><\/ 『  』「」@?♪人`≧≦☆★ωД【】! ノ・゚]|(笑)|(笑)')
 
 for infname in  os.listdir(argvs[1]):
     inf = open(argvs[1]+'/'+infname, "r")
     outfname = infname + '.out'
     outf = open(outfname, "w")
     for ll in inf.readlines():
         l = ll.decode('utf-8')
         lout = r.sub('', l, re.U)
         lout = r.sub('', lout, re.U)
         lout = r.sub('', lout, re.U)
         lout = r.sub('', lout, re.U)
 
         outstr = ''
         m = mt.parseToNode(lout.encode('utf_8'))
         while m:
              #print "m.surface\t", m.surface, "\t", m.feature
              mm = m.feature.split(',')
              hinshi = mm[0]; hinshi2 = mm[1]; hinshi3 = mm[2]
              #print "surface", m.surface, "hinshi", hinshi, "hinshi2", hinshi2
              #if hinshi2==u'固有名詞' and hinshi3==u'人名':
                  #print hinshi2, hinshi3, m.surface, m.feature
              tango = (m.surface).decode('utf-8')
              outstr = outstr + ' ' + tango 
 
              m = m.next
         outf.write((outstr+'\n').encode('utf-8'))
 
     inf.close(); outf.close()
結果は、
  午前 零 時 丁度 です
  今日 お父さん と お 兄 の 子供 が 誕生 日 だ おめでとう
みたいな感じのファイルになる。

本当は、もっと丁寧にスクリーンすべきだろう。いまは英数字の小文字はすべて消しているが、残すものはないか? 1文字の単語は除いたほうがいいのか?(そういう記述もどこかで見たような気がする) 形態素解析後の除外単語リストを用意したほうがいいのではないか? など。

次に、これを入力として、コーパスを作り学習させる。
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 import codecs, sys
 import gensim, logging
 import glob
 
 sys.stdout = codecs.getwriter('utf_8')(sys.stdout)
 logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
 
 #sentences = [['first', 'sentence'], ['second', 'sentence']]
 sentences = []
 argvs = sys.argv
 if len(argvs) < 2:
     print 'Usage: python %s directory' % argvs[0]
     quit()
 if glob.glob(argvs[1]+'tw*.out') == []:
     print 'No file found'
     quit()
 for infname in  glob.glob(argvs[1]+'/tw*.out'):
     inf = open(infname, "r")
 
     lines = inf.readlines()
     print len(lines)
     for l in lines:
         ll = l.decode('utf-8')
         u = ll.split()
         sentences.append(u)
 # train word2vec on the two sentences
 #model = gensim.models.word2vec.Word2Vec(sentences, size=5, min_count=1)
 model = gensim.models.word2vec.Word2Vec(sentences, size=200)
 
 def s(posi, nega=[], n=5):
     cnt = 1
     result = model.most_similar(positive = posi, negative = nega, topn = n)
     print u'順位', u'語', u'類似度'
     for r in result:
         print cnt, r[0], r[1]
         cnt += 1
これを、python -i <このファイル> ./ で実行し、最後にプログラムを終了させずにインタラクティブモードにする(-i指定)

それで、pythonのプロンプトが返ってきたら、sを呼び出して、similarityを試す。
 s([u'単語'])
 s([u'単語1'], [u'単語2'])  単語1はプラスする側、単語2はマイナスする側らしい
など。
 >>> s([u'俺'])
 順位 語 類似度
 1 お前 0.744944870472
 2 オレ 0.688959181309
 3 あたし 0.664245307446
 4 私 0.636135101318
 5 あいつ 0.625858306885
 
 >>> s([u'終電',u'飲み'])
 順位 語 類似度
 1 カフェオレ 0.514149785042
 2 ノンストップ 0.487345725298
 3 夜勤 0.482436865568
 4 休憩 0.477039635181
 5 自習 0.466827243567
 
 >>> s([u'新幹線',u'東京'],[u'帰り'])
 順位 語 類似度
 1 台東 0.608730196953
 2 墨田 0.606704652309
 3 大田 0.605434894562
 4 世田谷 0.600871801376
 5 港南 0.589032173157

 >>> s([u'ビール'])
 2014-07-22 14:00:36,899 : INFO : precomputing L2-norms of word weight vectors 
 順位 語 類似度
 1 酒 0.69725757187
 2 コーヒー 0.57643532753
 3 飲ん 0.553569257259
 4 ワイン 0.549029290676
 5 焼酎 0.547343611717
 
 >>> s([u'ビール',u'甘味'],[u'苦味'])
 順位 語 類似度
 1 酒 0.539837956429
 2 リキュール 0.483482539654
 3 ワイン 0.463366270065
 4 小さじ 0.455082446337
 5 ビア・スプリッツァービール 0.441155195236
 
 >>> s([u'ビール',u'食後'],[u'最初'])
 順位 語 類似度
 1 コーヒー 0.564417600632
 2 糖分 0.545417428017
 3 酒 0.540220439434
 4 豚肉 0.524781763554
 5 カフェイン 0.517480552197
 
 >>> s([u'アルタ',u'大阪'],[u'東京'])
 順位 語 類似度
 1 難波 0.510343253613
 2 郡山 0.509273350239
 3 ペデストリアンデッキ 0.508496820927
 4 豊中 0.501317083836
 5 バスターミナル 0.488690584898
 
 >>> s([u'ヒルズ',u'大阪'],[u'東京'])
 順位 語 類似度
 1 泉佐野 0.57211792469
 2 豊中 0.554686248302
 3 フェスティバルホール 0.53991407156
 4 大館 0.535022377968
 5 西部 0.526072919369
 
 >>> s([u'丸の内',u'大阪'],[u'東京'])
 順位 語 類似度
 1 心斎橋 0.697996973991
 2 和食 0.614294946194
 3 六本木 0.583541929722
 4 つぶやい 0.58198171854
 5 焼き鳥 0.570201039314
 
 >>> s([u'豊洲',u'大阪'],[u'東京'])
 順位 語 類似度
 1 東大阪 0.599119186401
 2 下京 0.593882799149
 3 京都 0.592132568359
 4 泉佐野 0.586484372616
 5 豊中 0.580929577351
上手く行かない例
 >>> s([u'表参道',u'大阪'],[u'東京'])
 順位 語 類似度
 1 東急 0.565302491188
 2 プラザ 0.563798010349
 3 吉祥寺 0.520717322826
 4 元町 0.512206435204
 5 原宿 0.473855346441
 
 >>> s([u'銀座',u'大阪'],[u'東京'])
 順位 語 類似度
 1 吉祥寺 0.539390444756
 2 京都 0.495363503695
 3 都島 0.49504378438
 4 新橋 0.489007294178
 5 梅田 0.488498836756
 

***自前でコーパスファイルを作るには [#r6d2469b]
-[[Gensimを使ったトピック単語抽出 LSAを使ったトピック語抽出まで:http://kensuke-mi.hatenablog.com/entry/20131021/1382384297]]

*おまけ MeCabの辞書に単語を登録する方法 [#q8e63676]

-[[mecabの辞書に新しい単語を登録する方法:http://hivecolor.com/id/50]]

-[[テキストからWikipedia見出し語を抽出 (⇒ Wikipedia見出し語をMeCabユーザ辞書に登録):http://aidiary.hatenablog.com/entry/20101230/1293691668]]

*おまけ NLP参照ページ [#gada3775]
[[NLP論文:http://wiki.ruka-f.net/index.php?NLP%E8%AB%96%E6%96%87]]

*おまけ twitter解析のまとめ論文 [#x32726a2]
-by 奥村学先生 [[マイクロブログマイニングの現在:http://lr-www.pi.titech.ac.jp/Twitter3.pdf]]
-[[ソーシャルセンサとしてのTwitter : ソーシャルセンサは物理センサを凌駕するか?(<特集>Twitterとソーシャルメディア):http://ci.nii.ac.jp/naid/110008898264]]

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