読者です 読者をやめる 読者になる 読者になる

Railway gun

Web系企業に勤めるサラリーマンが書くブログ。技術に関してだったり他の物だったりします。

仮説推論エンジン"Phillip"を動かしてみた

昨今流行りのAIの影響か、推論エンジンを動かす機会があったので、構築メモ。

(※私はネットワークレイヤの人間なので推論エンジンって何?って聞かれても、あまり詳しくはわかりません。会社から依頼されたのですが、明らかに人選ミスな気がする。)

いくつかそれっぽいものがgithubに公開されているが、今回使ってみたのは「Phillip」という物。
github.com

githubのReadmeを見る限りでは、日本の方が作られた模様。WindowsOS Xでも動くそうなのだが、Linux環境で動かすことを求められたのでLinux
環境はみんな大好きAWSAmazon Linuxインスタンスを立てて試してみた。

1.ダウンロード

githubに書かれているインストール方法に従ってとにかくやってみる。
Getting Started · kazeto/phillip Wiki · GitHub

まずはサクッとgit clone。

$ git clone https://github.com/kazeto/phillip.git

次の手順は、

Move to the directory where Phillip is installed.

と書かれているが、とりあえずホームディレクトリで動けばいいのでこのままで。

2.Makefile生成

これも公式に従って実施するだけ。pythonは2.7指定だったのでyumでインストール済み。
聞かれるのは

  1. バイナリの配置場所
  2. LP-SOLVEを使うかどうか
  3. GUROBIを使うかどうか

の3つだけ。バイナリ配置場所はデフォルトで良しとし、ライブラリは二者択一で良いようなので、LP-SOLVEを使うこととする。
(GUROBIはダウンロードにアカウント作成などが必要で面倒くさかった。。。)

$ cd ./phillip
$ python tools/configure.py
*** Configuration of Phillip ***
--> BINARY TARGET [default=bin/phil]:
--> USE-LP-SOLVE [y/n]: y
--> USE-GUROBI [y/n]: n

3.ライブラリのインストールコンパイル

あとはライブラリをダウンロードしてコンパイルするだけらしい。LP-SOLVEの5.5系なら良いらしいので↓からダウンロード。
https://sourceforge.net/projects/lpsolve/files/lpsolve/5.5.2.5/

何がなんだかわからんが、とりあえず”lp_solve_5.5.2.5_exe_ux64.tar.gz”がそれっぽいので落として展開。公式にパスを通せと書いてあるのでパスを通す。そんでmake.(exportコマンドを打っているように見えますが、実際は.bash_profileに記載してます。)

$ mkdir lp_solve 
$ mv lp_solve_5.5.2.5_exe_ux64.tar.gz ./lp_solve
$ tar xzvf ./lp_solve/lp_solve_5.5.2.5_exe_ux64.tar.gz
$ export CPLUS_INCLUDE_PATH=$HOME/phillip/lp_solve
$ make
〜省略〜
rc/././sol/ilp_solver.h:14:20: fatal error: lp_lib.h: No such file or directory
 #include <lp_lib.h>
                    ^

はい。lp_lib.hが足りないらしい。多分ソースファイルにおいてありそうなので、ダウンロードのサイトに戻って今度は"lp_solve_5.5.2.5_source.tar.gz"をダウンロードして展開。パスも通す。

$ mkdir lp_solve_src
$ mv lp_solve_5.5.2.5_source.tar.gz ./lp_solve_src
$ tar xzvf ./lp_solve_src/lp_solve_5.5.2.5_source.tar.gz
$ export CPLUS_INCLUDE_PATH=$HOME/phillip/lp_solve_src/lp_solve_5.5
$ make
〜省略〜
/usr/bin/ld: cannot find -llpsolve55
collect2: error: ld returned 1 exit status
make: *** [all] Error 1

なるほどなるほど〜。こんどはlpsolve55というライブラリが足りないらしい。ライブラリだからdevかなという適当な推測の元、今度は"lp_solve_5.5.2.5_dev_ux64.tar.gz"をダウンロードして展開。ライブラリとしてパスを通す。

$ mkdir lp_solve_dev
$ mv lp_solve_5.5.2.5_dev_ux64.tar.gz ./lp_solve_src
$ tar ./lp_solve_dev/lp_solve_5.5.2.5_dev_ux64.tar.gz
$ export LIBRARY_PATH=$LIBRARY_PATH:$HOME/phillip/lp_solve_dev
$ make

無事に終わったらしい。

4.知識ベースのコンパイル

公式に従って、LISP形式のインプットを準備する。知識ベースが何かはわかってないよ。詳しい同僚はオントロジーがどうトリプルがどうとか親切に教えてくれた。(けど、基礎知識がなさすぎてあんまりよくわからんかった。あとで調べてみよう。)

  • kb.lisb
    (B (name kb01) (=> (steal-vb e1 x y) (criminal-jj e2 x)))
    (B (name kb02) (=> (criminal-jj e1 x) (arrest-vb e2 y x)))
    ; "Tom robbed jewels. Police arrested him."
    (O (name obs01) (^ (steal-vb E1 Tom Jewel) (arrest-vb E2 Police he)))

そして、この入力をつかって知識ベースをコンパイル

$ bin/phil -m compile -c dist=basic -c tab=null -k compiled -P 8 kb.lisp
# 04/05/2017 11:02:41] Phillip starts...
# 04/05/2017 11:02:41]   version: phil.3.19
〜省略

とりあえずできたっぽいね。

4.実行

これでいよいよ実行環境が整ったっぽい。

$ bin/phil -m infer -k compiled -c lhs=depth -c ilp=weighted -c sol=gurobi -P 8 -T 120 obs.lisp
〜省略
<phillip>
<configure>
<version>phil.3.19</version>
<time_stamp compiled="Apr  5 2017 10:57:03" executed="Apr  5 2017 11:15:15"></time_stamp>
<components lhs="DepthBasedEnumerator" ilp="weighted-converter" sol="gurobi-optimizer"></components>
<knowledge_base path="compiled" size="2" max_distance="-1"></knowledge_base>
<params timeout_lhs="-1" timeout_ilp="-1" timeout_sol="-1" timeout_all="120" verbose="1" gurobi_thread_num="8" kb_thread_num="8"></params>
</configure>
</phillip>

出力結果が何なのかは後でゆっくり見るとしてとりあえず動作しました。
大層なことをやったような書き方になってしまいましたが、公式のチュートリアルそのまんま走らせただけですね。。。

5.追記

どうも出力に結果が含まれていないと思ったら、オプションで指定しているプログラム指定がLP-SOLVEになっていなかった。

$ bin/phil -m infer -k compiled -c lhs=depth -c ilp=weighted -c sol=lpsolve -P 8 -T 120 obs.lisp
<phillip>
<configure>
<version>phil.3.19</version>
<time_stamp compiled="Apr  5 2017 10:57:03" executed="Apr  6 2017 03:39:53"></time_stamp>
<components lhs="DepthBasedEnumerator" ilp="weighted-converter" sol="LP-Solve"></components>
<knowledge_base path="compiled" size="2" max_distance="-1"></knowledge_base>
<params timeout_lhs="-1" timeout_ilp="-1" timeout_sol="-1" timeout_all="120" verbose="1" gurobi_thread_num="8" kb_thread_num="8"></params>
</configure>
<proofgraph name="obs.lisp::obs01" state="optimal" objective="10">
<time lhs="0" ilp="0" sol="0.001" all="0.001"></time>
<timeout lhs="no" ilp="no" sol="no" all="no"></timeout>
<literals num="4">
<literal id="0" type="observable" depth="0" active="yes" paid-cost="yes" cost="10.000000">(steal-vb E1 Tom Jewel):0</literal>
<literal id="1" type="observable" depth="0" active="yes" paid-cost="no" cost="10.000000">(arrest-vb E2 Police he):1</literal>
<literal id="2" type="hypothesis" depth="1" active="yes" paid-cost="no" cost="12.000000">(criminal-jj _u1 he):2</literal>
<literal id="3" type="hypothesis" depth="2" active="yes" paid-cost="no" cost="14.400000">(steal-vb _u2 he _u3):3</literal>
</literals>
<explanations num="2">
<explanation id="0" tail="0:{1}" head="1:{2}" active="yes" backward="yes" axiom="kb02" gap="">(arrest-vb E2 Police he):1 => BACKWARD(axiom=1) => (criminal-jj _u1 he):2</explanation>
<explanation id="1" tail="1:{2}" head="2:{3}" active="yes" backward="yes" axiom="kb01" gap="">(criminal-jj _u1 he):2 => BACKWARD(axiom=0) => (steal-vb _u2 he _u3):3</explanation>
</explanations>
<unifications num="1">
<unification l1="0" l2="3" unifier="E1=_u2, Tom=he, Jewel=_u3" active="yes" gap="">(steal-vb E1 Tom Jewel):0 ^ (steal-vb _u2 he _u3):3 => UNIFY => (= E1 _u2):4 ^ (= Tom he):5 ^ (= Jewel _u3):6</unification>
</unifications>
</proofgraph>
</phillip>

BitbucketのSSH接続エラー

みんな大好きBitbucketは自分も愛用しているのですが、
今までpushする際にはSSHではなくHTTPS経由でpushしていました。
SSH経由に変えようとしたところ、アホみたいなミスでpushエラーが起きまくったので記載。

発生したエラー

要するに「あなたの登録した鍵ではアクセスできませんよ!」というエラー。

$ git push -u origin --all
ermission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

状況(やったこと兼手順)

Macで以下の手順を実施。途中の鍵コピー以外はCentOSなどでも同じはず。

SSHキーを作成。
$ ssh-keygen -f ~/.ssh/bitbucket -t rsa -C hoge@hoge.com
Bitbucketに鍵を登録。

鍵をコピーする。(Mac以外の方は手動でコピーすれば良いです。)

$ cat ~/.ssh/bitbucket.pub | pbcopy

で、Bitbucketのアカウントの管理>SSHキーから公開鍵を登録。

SSHのconfigを設定

エディタでSSHのコンフィグにBitbucket宛の設定を記載する。
(注:ここが間違っています。正解を見たい方は一番下をご覧ください。)

Host bitbucket
  HostName bitbucket.org
  IdentityFile ~/.ssh/bitbucket
  User git
BitbucketにSSHでアクセス。

まずはSSHコマンドでアクセス。普通に成功する。

$ ssh -T git@bitbucket
logged in as hogehoge.

You can use git or hg to connect to Bitbucket. Shell access is disabled.
リポジトリディレクトリに異動し、push先を設定。
$ cd <リポジトリのディレクトリ>
$ git remote add origin git@bitbucket.org:<ユーザ名>/<リポジトリ名>.git
Bitbucketにgitリポジトリをpush。ここで失敗する。
$ git push -u origin --all
ermission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

原因

SSHのconfig設定におけるHostがgitコマンドにあっていなかった。

誤った設定

Host bitbucket
  HostName bitbucket.org
  IdentityFile ~/.ssh/bitbucket
  User git

正解

Host bitbucket.org
  HostName bitbucket.org
  IdentityFile ~/.ssh/bitbucket
  User git

SSHのみを使う時にはHostはわかりやすく、短い物を設定しますが、
gitコマンドで設定したremote先はbitbucket.orgを参照するため、
誤った設定では「そんなホストに対応した鍵はない」となってしまいます。

そのため、SSHでは成功していてもgitコマンドでは失敗、というわけでした。
SSH関連で手間取ることはないと慢心していたら、1時間ほど費やしてしまったのでメモ。

configureのコンパイラエラー対処

おなじみconfigure => make => make installの流れでつまづいた場合の解決策。
エラーが出次第、徐々に追記していきたい。

C++、g++のコンパイラが無いと言われる。

エラー表示
configure: error: C++ compiler g++ does not work or no compiler found
対処方法

gcc,gcc-c++yumで入れてやる

$ sudo yum install gcc gcc-c++

zlib.hが参照できないと言われる

エラー表示
configure: error: zlib.h is required
対処方法

zlib,zlib-develをインストールする

$ sudo yum install zlib zlib-devel

bzlib.hが参照できないと言われる

エラー表示
configure: error: bzlib.h is required
対処方法

bzip2,bzip2-develをインストールする

$ sudo yum install bzip2 bzip2-devel

Windows7にVagrant環境を作ってRuby on Railsを動かしてみる①

Ruby on Railsを学んでみようと思い、無料で公開されているチュートリアルをやってみています。

Ruby on Rails チュートリアル:実例を使って Rails を学ぼう

今まではAWS上に建てたサーバでコーディングしていましたが、ブラウザで作ったサイトを見るのにローカルの方が楽なので、PC上にVagrantをインストールして、CentOSを動かしたうえでRailsをやってみようと思います。

Vagrant環境の準備

Vagrantを使うためには

  1. Ruby
  2. VirtualBox
  3. Vagrant

のインストールが必要になります。
どれからインストールしてもそれほど問題はありませんでした。

Rubyのインストール

私のローカルPCにはRubyすら入っていなかったので、まずはRubyを入れます。

下記のサイトにWindowsインストーラ形式のバイナリがおいてあるのでダウンロードしてきます。私は最新版の2.2.1-p85(64ビット版)を落としてインストールしてきました。
RubyInstaller for Windows

インストーラ環境変数まで設定してくれる・・。便利!コマンドプロンプトで確認してみます。(Linuxのコマンドのように書いてありますが、"C:\"などと書くのが面倒なだけで、Windowsコマンドプロンプトを使っています。ここら辺のコマンドはどっちでも一緒だし。)

$ ruby -v
ruby 2.2.1p85 (2015-02-26 revision 49769) [x64-mingw32]

無事にインストール完了。

VirtualBoxのインストール

同じく下記のサイトからダウンロードしてインストールするだけ。
Downloads – Oracle VM VirtualBox

適当にインストーラを進めて行けば無事にインストール完了。
ここで再起動を求められるかもしれません。

Vagrantのインストール

コレも簡単。下記のサイトからダウンロードしてインストール。
Vagrant

コマンドプロンプトからvagrantコマンドが使えるかを確認。

$ vagrant -v
Vagrant 1.7.2

ココも問題なく、インストール完了。これでvagrant環境を立ち上げる前の前準備は完了。

バーチャルマシンの起動

まずはVagrantにバーチャルマシンを登録する作業からです。下記に使えるイメージファイルがおいてあるため、好きな物を選択。
A list of base boxes for Vagrant - Vagrantbox.es

CentOSが使いたかったので、"CentOS 6.5 x86_64"を選択します。右に書いてあるURLをコピーして、コマンドプロンプトで下記のコマンドを打ちます。
(※ディレクトリは好きな場所に移動してください。)

vagrantはコマンド名、boxはイメージファイル全般を扱うオプション、addはboxのオプションでイメージを追加するオプション、centos_6_5はダウンロードするイメージのタグのようなもの(なんでもOK)、そして最後にダウンロードするイメージのURLです。

$ vagrant box add centos_6_5 https://github.com/2creatives/vagrant-centos/releases/download/v6.5.3/centos65-x86_64-20140116.box

自動的にダウンロードが始まるので、完了するまでしばし待ちましょう。
ダウンロードが完了したら、下記のコマンドで環境の初期化を行います。

$ vagrant init centos_6_5

"Vagrantfile"がカレントディレクトリにできたよ!というメッセージが出てくると思います。
これはVagrantを起動する際に使う設定になりますが、とりあえず動かしてみるには触らなくとも大丈夫ですので、そのまま起動してみます。

$ vagrant up

ディスク容量が圧迫されていたり、Ruby環境変数がうまく通っていないなどが無い限り、うまくいくと思います。デフォルトでは127.0.0.1の2222ポートがsshでつなげるようになっているはずです。(その旨表示が出ます。)

ログイン

TeraTermputty等のコンソールを使って127.0.0.1:2222にアクセスします。アカウント名・パスワード共に"vagrant"でログインできるはずです。
f:id:pioneer_in_ocean:20150310224711p:plain
f:id:pioneer_in_ocean:20150310224827p:plain

無事にログイン。f:id:pioneer_in_ocean:20150310224923p:plain


とりあえず、本日はここまで。

git pushで「Gtk-WARNING **: cannot open display」とエラーが出た場合

bitbucketにgit pushしようとしたら、エラーで怒られてしまった。

$ git push
(gnome-ssh-askpass:XXXXX): Gtk-WARNING **: cannot open display:

cannot open displayというエラーは
「パスワード入力窓をgnomeがオープンできないよ!」
と言われているらしい。

httpsでログインを試みる設定にしていたため、パスワードを求められているようだ。
色々な方が書かれているが、「SSH_ASKPASS」を環境変数から削除すれば良さそう。

$ unset SSH_ASKPASS
$ git push
Password:

無事、うまくpushできた。

とはいえ、ssh-keyも登録しておいたはずなので、sshによるアクセスに切り替えよう・・。

RMagickのインストールエラー

他の方が開発したrailsアプリを引っ張ってきて、
自分のCentOS環境でbundle installした際に下記のエラー発生。

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

checking for Ruby version >= 1.8.5... yes
checking for gcc... yes
checking for Magick-config... no
Can't install RMagick 2.13.2. Can't find Magick-config
・
・
・
An error occurred while installing rmagick (2.13.2), and Bundler cannot continue.
Make sure that `gem install rmagick -v '2.13.2'` succeeds before bundling.

ImageMagickが入っていないためのようだ。

$ sudo yum install ImageMagick ImageMagick-devel
$ bundle install

・
・
Installing rmagick 2.13.2
Your bundle is complete!

無事、解決。

Datanodeのエラー:Initialization failed for block pool Block pool BP-xxxxxxx

久しぶりのHadoopクラスタ構築で出てきたエラー。

DataNodeを起動しようとするとログに下記のエラーが吐かれて勝手にシャットダウンしてしまう。

FATAL org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed for block pool Block pool BP-<<ユニーク値>> (storage id DS-<<ユニーク値>>) service to <<ドメイン名>>/<<IPアドレス>>:<<ポート>>

エラーの内容はBlock poolを初期化できませんでしたよ、という内容。
Hadoopが生成する"current"ディレクトリ配下のVERSIONファイルがおかしいのかと思ってみてみるが、
特におかしい所は無い。

何が原因なのか悩んだあげく、結論としては/etc/hostsファイルにドメインが記載されていなかった。

vim /etc/hosts

でhostsファイルにドメインを記載してやったら解決。

DNSで名前解決は出来ている状態になっていたのだが、Hadoopはhostsでしっかり記載してやらないと予期せぬエラーが起きる事がある。以前も同じ原因で別のエラーが出た事があった。

もし、何か理不尽なエラーが出る事があったら/etc/hostsを確認してみるといいかもしれない。