いまさらだけどVagrantを使って，R Studio Server + Mahout の分析環境を作ってみる


こんにちは，@isseium です．
Vagrantには興味があったのですが，Macbook Air の空き容量の都合であくまで実験しかできず実用はしていませんでした．

月日は流れ，夏にMacbook Airを買い換えて容量が増えましたんで使ってみたいと思います．

## なにをするか？

私は，[CheekiTrip](http://cheekitrip.com) という過去のチェックイン情報から旅先を推薦するサービスを運営しています．まだまだ不完全なサービスなのですが，150名以上の方に登録いただいていて，そこそこデータが集まってきました．（[サービスの詳細はこちらのエントリをご覧下さい](http://isseium.hateblo.jp/entry/2014/05/11/203038) ）


![CheekiTrip](http://i.gyazo.com/2cb52d9b6718b10b48491846b342f852.png)


今回，このデータもとにを推薦アルゴリズム改善したいと思いましてローカルに分析環境が欲しくなりました．

現在のCheekiTripの推薦は，Apache Mahout を使った協調フィルタリングです．まずはこの Apache Mahout を Vagrant 上にインストールしたいです．Mahout は大規模データには強力ですが，データを見ながらインタラクティブに実験するには少し使いにくいので，Rもインストールしたいですね．

![構成図](https://www.evernote.com/shard/s31/sh/cad85001-3b54-4f21-b5ed-e5bc991af42f/fa0c96397023087b35b66698a084fdc7/deep/0/20140422_%E5%85%A8%E4%BD%93%E3%82%BC%E3%83%9F%E7%99%BA%E8%A1%A8.pptx.png)


というわけで，今回やることは

1. Vagrant のインストール（Virtual Box）
2. Vagrant マシンのセットアップ（CentOS 7.0）
3. Chef を利用して，Mahout と R をインストール

になります．

**ChefやVagrantの設定まわりはあまり自信がないのでアドバイスいただけると幸いです！**

## 0. 前提環境

今回は，こんな環境を構築します．

| ソフトウェア等 | バージョン |
|----+----|
| ホストOS | MacOS X 10.9.4 |
| ゲストOS | CentOS 7.0 |
| Vagrant | 1.6.5 |
| Virtual Box | 4.3.12 |
| Apache Mahout | 0.9 |
| R Studio | 3.1.1|

## 1. Vagrant のインストール

### 1-1. Vagrant をインストールする

[公式サイト](https://www.vagrantup.com/downloads.html) からインストールを行います．

Mac の標準的なインストール方法です．

### 1-2. Virtual Box をインストールする

こちらも[公式サイト](https://www.virtualbox.org/wiki/Downloads) からインストールを行います．

Vagrant と同じく Mac の標準的なインストール方法です．

### 1-3. インストールの確認

ターミナルを起動します．

```bash
$ vagrant --version
```

![vagrantバージョン確認](http://i.gyazo.com/953cd935afd044de3b81bcc8bc95ece7.png)


## 2. はじめての Vagrant マシン作成

### 2-1. boxの作成（イメージのダウンロード）

Vagrant にはイメージを集約しているサイトがいくつかあるみたいですが，opscode がメンテしている[bento](https://github.com/opscode/bento) を使おうと思います．

使いたいOSイメージのURLをコピーしてきます．このひな形をboxというらしいです．
**今回はVirtualBoxを利用します！間違えてVMWareのイメージをダウンロードしないでね！**


イメージは数百MB以上あるので，そこそこ時間がかかります．

```bash
$ vagrant box add centos70 http://opscode-vm-bento.s3.amazonaws.com/vagrant/virtualbox/opscode_centos-7.0_chef-provisionerless.box
（中略）

# box の確認
$ vagrant box list
centos70 (virtualbox, 0)		# vmware だと vmware_desktop と表示されます
```

### 2-2. ゲストマシンの作成

さきほど作成した box をもとに実際のゲストマシンを作成します．

```bash
$ mkdir -p ~/vagrant/cheekitrip_development
$ cd ~/vagrant/cheekitrip_development

$ vagrant init centos70
（略）

$ $ vagrant up
（略）
```

以上でCentOSが起動しました．

### 2-3. SSH で接続

起動したCentOSにログインするには

```bash
$ vagrant ssh
```

とします．直接SSHをしたりWebサーバを構築するときのために，~/.ssh/config にネットワーク設定を追加します．

```bash
# 追記内容の確認
$ vagrant ssh-config --host mahout		# mahout というホスト名にしています
Host mahout
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/issei/.vagrant.d/insecure_private_key
  IdentitiesOnly yes
  LogLevel FATAL

# ssh_config に追記
$ vagrant ssh-config --host mahout >> ~/.ssh/config

# ssh コマンド経由でログイン
$ ssh mahout
```

## 3. chef/knife で mahout と R Studio をインストール

Chef と Knife は事前に MacOS X にインストールしてある前提ではじめます．
動作している状態のものを [こちら](https://github.com/isseium/MyAnalysis) にpushしておりますのでそちらもあわせてご覧下さい．

### 3-1. 仮想マシン内の chef の設定

ゲストOSにchefをインストールするためのプラグインと設定をします．

```bash
$ vagrant plugin install vagrant-omnibus
```

``` Vagrantfile
# 90行目くらいに下記を追加
config.omnibus.chef_version = :latest
```

### 3-2. ネットワーク設定
R Studio Server を外部から8787ポートでアクセスするための設定を行います

```Vagrantfile
# 24行目くらいに下記を追加
config.vm.network "forwarded_port", guest: 8787, host: 8787
```

### 3-3. R Studio インストールの設定

```
$ knife solo init MyAnalysis
$ cd MyAnalysis
```
opscode に用意されている hadoop と，github上にあった R Studio の [cookbook](https://github.com/takemikami/chef-rstudio) を利用します

```Berksfile
source "https://supermarket.getchef.com"

cookbook 'yum', git: "git@github.com:opscode-cookbooks/yum.git"
cookbook 'rstudio', git: "git@github.com:takemikami/chef-rstudio.git"
```

### 3-4. Mahout Cookbook の作成

mahout用のcookbookが用意されていないので自作します

```bash
$ knife cookbook create mahout -o site-cookbooks/
```

```site-cookbooks/mahout/recipes/default.rb
#
# Cookbook Name:: mahout
# Recipe:: default
#
# Copyright 2014, YOUR_COMPANY_NAME
#
# All rights reserved - Do Not Redistribute
#

# TODO: 将来的に attributes に移行
install_version = "0.9"
download_filepath="/tmp/mahout.tar.gz"
install_path = "/usr/local"
install_sym_path = "/usr/local/bin/mahout"
bin_path = "#{install_path}/mahout-distribution-#{install_version}/bin/mahout"

# 必要なパッケージのインストール
%w{java-1.6.0-openjdk java-1.6.0-openjdk-src java-1.6.0-openjdk-devel}.each do |pkg|
  package pkg do
    action :install 
  end
end

# mahout ダウンロード
bash "install_mahout" do
  code <<-EOL
    wget ftp://ftp.riken.jp/net/apache/mahout/#{install_version}/mahout-distribution-#{install_version}.tar.gz -O #{download_filepath}
    tar xvzf #{download_filepath} -C #{install_path}
    rm -f #{install_sym_path}
    ln -s #{bin_path} #{install_sym_path}
    rm #{download_filepath}
  EOL
end

# bashrc の作成
template "/home/vagrant/.bashrc" do
  source "dot.bashrc.erb"
  variables :partials => {
    "mahout.bashrc.erb" => "hack the planet",
  },
  :top_level => "I'm a variable from the template resource"
end

```

```site-cookbooks/mahout/templates/default/dot.bashrc.erb
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions

# Mahout
<%= render "mahout.bashrc.erb" %>
```

``` site-cookbooks/mahout/templates/default/mahout.bashrc.erb
export JAVA_HOME=/usr/lib/jvm/java-1.6.0-openjdk.x86_64/
```

### 3-5. ゲストマシンにインストール

```bash
$ berks vendor
$ cd ..
$ vargrant reload --provision
```

## 4. 確認

### 4-1. R Studio Server

```localhost:8787``` にアクセスします．

![Rstudioserver](http://i.gyazo.com/aaa8f0a174f3a38c06e07ca3aaa733d2.png)

初期パスワードは ```ID: vagrant ```, ```Pass: vagrant```です．

![Rstudioserver2](http://i.gyazo.com/3a86e5d446ee7bb047ad28a948ff6cc7.png)


### 4-2. Mahout

```bash
$ vagrant ssh
$ mahout
hadoop binary is not in PATH,HADOOP_HOME/bin,HADOOP_PREFIX/bin, running locally
An example program must be given as the first argument.
Valid program names are:
  arff.vector: : Generate Vectors from an ARFF file or directory
  baumwelch: : Baum-Welch algorithm for unsupervised HMM training
  canopy: : Canopy clustering
  cat: : Print a file or resource as the logistic regression models would see it
  cleansvd: : Cleanup and verification of SVD output
  clusterdump: : Dump cluster output to text
  clusterpp: : Groups Clustering Output In Clusters
  cmdump: : Dump confusion matrix in HTML or text formats
  concatmatrices: : Concatenates 2 matrices of same cardinality into a single matrix
  cvb: : LDA via Collapsed Variation Bayes (0th deriv. approx)
（以下略）
``` 

せっかくなので協調フィルタリングしてみましょう．
以下のファイルを作成します．「ユーザID, アイテムID, レーティング」のCSVファイルです．
（参考: http://girlincomputerscience.blogspot.jp/2010/11/apache-mahout.html)

```mydata.dat
1,101,5.0
1,102,3.0
1,103,2.5
2,101,2.0
2,102,2.5
2,103,5.0
2,104,2.0
3,101,2.5
3,104,4.0
3,105,4.5
3,107,5.0
4,101,5.0
4,103,3.0
4,104,4.5
4,106,4.0
5,101,4.0
5,102,3.0
5,103,2.0
5,104,4.0
5,105,3.5
5,106,4.0
```



協調フィルタリングを実行します．

```bash
$ mahout recommenditembased --input mydata.dat  --numRecommendations 2 --output output/ --similarityClassname SIMILARITY_PEARSON_CORRELATION
（略）
```

結果はこちら

```bash
$ cat output/part-r-00000
1       [104:3.9258494]
3       [102:3.2698717]
4       [102:4.7433763]
```

再実行するときは，output と tempファイルを削除しましょう．

```bash
$ rm -rf output temp
```

# まとめ

Vagrant を使って CentOS 環境を用意し，その上に Chef を利用して R + Mahout の統計環境ができあがりました．これを使って統計解析していきたいですね！！！