H2OからMinIOにアクセスする

MinIOにCSVファイルを置いて、H2OからimportFilesをしたいとする。MinIOなので、S3としてH2Oからアクセスすれば良いと思うが、H2Oのこのドキュメントの通りにやっても上手くいかない(そのうち、改善されるのかもしれないけど、現時点ではできないと思われる…)。そもそもvalueがD〜となっているので、どっかからコピってきてとりあえず作った感じもする…。

ではどうするかだけど、PUBDEV-3321によると

-Dsys.ai.h2o.persist.s3.endPoint="play.minio.io:9000"
-Dsys.ai.h2o.persist.s3.enable.path.style=true
-Dsys.ai.h2o.persist.s3.region="us-east-1"

をjava …<ここ>… -jar h20.jar …で指定すれば良い。アクセスキーとかは普通のS3と同様に

-Daws.accessKeyId="Q3AM3UQ867SPQQA43P2F"
-Daws.secretKey="zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG"

とか、環境変数で指定すれば渡すことができる。

MinIOでhttpのままになっているなら、

-Dsys.ai.h2o.persist.s3.endPoint="http://play.minio.io:9000"

とすれば、H2Oからエラーにならないでアクセスできるようになる。

caffeのインストール

Deep LearningのフレームワークであるcaffeをUbuntu 14.04にインストールする。今回、CUDA環境は事前にセットアップ済みを想定しているが、caffeのMakefile.configでCPUを使うようにすればインストールはできるような気もする。
まず、依存するものをインストールする。

$ sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libboost-all-dev libhdf5-serial-dev
$sudo apt-get install libgflags-dev libgoogle-glog-dev liblmdb-dev protobuf-compiler

つぎに、caffeをcloneする。

$ git clone https://github.com/BVLC/caffe.git
$ cd caffe

Makefile.configを作成する。

$ cp Makefile.config.example Makefile.config

今回、pipで入れたpythonを使いたかったりもするので、以下のように変更。

$ diff -ub Makefile.config.example Makefile.config
--- Makefile.config.example	2015-07-23 16:17:54.488019582 +0900
+++ Makefile.config	2015-07-23 15:47:17.433038344 +0900
@@ -48,8 +48,10 @@
 # NOTE: this is required only if you will compile the python interface.
 # We need to be able to find Python.h and numpy/arrayobject.h.
-PYTHON_INCLUDE := /usr/include/python2.7 \
-		/usr/lib/python2.7/dist-packages/numpy/core/include
+PYTHON_INCLUDE := $(HOME)/.pyenv/versions/2.7.9/include/python2.7 \
+		$(HOME)/.pyenv/versions/2.7.9/lib/python2.7/site-packages/numpy/core/include
 # Anaconda Python distribution is quite popular. Include path:
 # Verify anaconda location, sometimes it's in root.
 # ANACONDA_HOME := $(HOME)/anaconda
@@ -58,7 +60,8 @@
 		# $(ANACONDA_HOME)/lib/python2.7/site-packages/numpy/core/include \
 # We need to be able to find libpythonX.X.so or .dylib.
-PYTHON_LIB := /usr/lib
+PYTHON_LIB := $(HOME)/.pyenv/versions/2.7.9/lib
 # PYTHON_LIB := $(ANACONDA_HOME)/lib
 # Homebrew installs numpy in a non standard path (keg only)

あとは、ビルドとテストを実行する。

$ make all
$ make test
$ make runtest

特にエラーがなければOK。そして、Pythonでcaffeを使用するための必要なものをpipで入れる。

$ for req in $(cat python/requirements.txt); do pip install $req; done

さらに、Pythonで利用したい場合は

$ make pycaffe

を実行しておく。
以上で完成。

Elasitcsearchと日本語版WikipediaでLDA

今まで、以下のあたりでいくつか書いてきました。

gensimを利用して、LDAに適用するコーパスを使う例を上げてきましたが、今までのものはbzip2されたデータからコーパスを作成しているだけな jawikicorpus.py だったので、さらに一歩進んで、データ自体もElasticsearchに入れておいて、形態素解析も含めて、Elasticsearchを使うように変えてみます。
適用するにあたっては、

  • Elasticsearchの環境を作っておくこと
  • RiverでWikipediaのデータを投入しておくこと
  • elasticsearch-extended-analyzeプラグインを入れておくこと
  • gensim等の必要なpythonモジュールを入れておくこと(pyenvとかで入れれば良いかも)

という前提で、jawikicorpus.py をダウンロードして、

$ python jawikicorpus.py localhost:9200/jawiki-pages-articles wiki_ja_output

を実行すると

$ ls wiki_ja_output_*
wiki_ja_output_bow.mm wiki_ja_output_tfidf.mm wiki_ja_output_wordids.txt.bz2
wiki_ja_output_bow.mm.index wiki_ja_output_tfidf.mm.index

という感じでコーパスが作成されます。
あとは、英語版WikipediaでLDA日本語版WikipediaでLDAにあるような感じで、LDAを適用できるかと思います。

日本語版WikipediaでLDA

英語版WikipediaでLDA」に続いて、日本語版で試してみる。
日本語の場合は形態素が必要になる。そうすると、ぐぐってみると、jawikicorpus.pyというのを用意して、コーパスを利用することになる。
でも、ぐぐってみると、古かったり、動くのかよくわからないものがいろいろと転がっている感が…。あとは、形態素解析もmecabだったりとか…。
今回、この話の流れの一番始めにElasticsearchに突っ込んでいたりとかで、Elasticsearchの形態素機能を利用できるのでそれを利用することにしたい。でも、ElasticsearchのAnalyzeAPIは名詞などの品詞情報を取得することができない。というわけで、elasticsearch-extended-analyzeをElasticsearchに入れる必要がある。

$ cd $ES_HOME
$ bin/plugin -i info.johtani/elasticsearch-extended-analyze/1.4.1

上記のプラグインを入れたら、Elasticsearchを再起動する。あと、WikipediaをElasticsearchに取り込むにあるようにja_analyzerが設定されたインデックスを用意しておく必要がある。
そして、今回利用するjawikicorpus.pyはここに置いておくので、取得して適当に変えてください。変える必要があるのはElasticsearch Infoのコメントを置いたあたりかも。このファイルでは名詞だけに絞っているので、そこを編集したりとかもありかも。
という感じで、ここまで準備ができれば、英語版と同様に実行すればよい。まずは、wikipediaの日本語ファイルをダウンロードする。

$ wget http://dumps.wikimedia.org/jawiki/latest/jawiki-latest-pages-articles.xml.bz2

次にコーパスを作る。

$ python jawikicorpus.py jawiki-latest-pages-articles.xml.bz2 wiki_ja_output

トピックモデルを作成する。

$ python wiki_lda.py --wordids wiki_ja_output_wordids.txt.bz2 --tfidf wiki_ja_output_tfidf.mm --output wiki_lda_ja.pkl

という感じでできあがり。
model.print_topics(100)とかすると、形態素解析を実行する前にwikipedia記法を取り除いて文書にした方がコーパス的には良いかなというような気も…。

英語版WikipediaでLDA

Wikipediaのデータをスクロールスキャンする」を行ったけど、まずは、Wikipediaのデータに対してLDAを適用してみることにする。日本語への適用は次回にするとして、まずは英語のWikipediaに適用してみる。
まずは、wikipediaをダウンロードする。

$ wget http://dumps.wikimedia.your.org/enwiki/latest/enwiki-latest-pages-articles.xml.bz2

結構でかいので時間がかかるだろう…。
ダウンロードできたら、今回、利用するLDAの実装はgensimを利用するので、インストールしておく。

$ pip install gensim

sklearnには、LDAの実装は存在しないので、gensimを利用しておく。
まずはコーパスを作成する。

$ python -m gensim.scripts.make_wiki enwiki-latest-pages-articles.xml.bz2 wiki_en_output

実行する環境にもよると思うけど、1日とかかかるかも。完了すると、wiki_en_output〜のファイルが複数生成される。
あとはトピックの生成をする。コマンドラインで実行してもいいけど、今回は以下のようなwiki_lda.pyを作って実行する。

# coding: utf-8
import logging, gensim
from optparse import OptionParser
import sys
def main(argv=sys.argv):
    parser = OptionParser(prog="wiki_lda.py")
    parser.add_option("--wordids", dest="wordids",
                  help="WordIDs", metavar="WORDIDS")
    parser.add_option("--tfidf", dest="tfidf",
                  help="TFIDF", metavar="TFIDF")
    parser.add_option("--output", dest="output",
                  help="Output", metavar="OUTPUT",
                  default='wiki_lda.pkl')
    (options, args) = parser.parse_args()
    logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
    id2word = gensim.corpora.Dictionary.load_from_text(options.wordids)
    mm = gensim.corpora.MmCorpus(options.tfidf)
    model = gensim.models.ldamodel.LdaModel(corpus=mm,
                                            id2word=id2word,
                                            num_topics=100,
                                            update_every=1,
                                            chunksize=10000,
                                            passes=1)
    model.save(options.output)
    return 0
if __name__ == "__main__":
    sys.exit(main())

まぁ、大したものではないけど…。num_topicsを100にしているので、適当に変えても良いだろう。
あとは、

$ python wiki_lda.py --wordids wiki_en_output_wordids.txt.bz2 --tfidf wiki_en_output_tfidf.mm --output wiki_lda_en.pkl

とすれば、トピックモデルが完成する。こっちは数時間で完了すると思う。
保存したモデルは、

$ python
>>> import gensim
>>> model = gensim.models.ldamodel.LdaModel.load("wiki_lda.pkl")
>>> for data in model.print_topics(100):
...     print data

とかすれば、利用して確認することができる。