PyCallを使ってRubyからPythonのライブラリを使い倒す

# はじめに

これまで何度か紹介してきたPyCallですが、バージョンが1.0になって大幅にライブラリが変更されたので、新しいバージョンにあわせた使い方を紹介してみます。

[mrkn/pycall.rb: Calling Python functions from the Ruby language](https://github.com/mrkn/pycall.rb/tree/master)

# インストール

以下のコマンドでインストールができます。

```text:
gem install pycall
```

ちなみに、以下のライブラリも入れておくと便利です。

```text:
gem install numpy
gem install pandas
```

## Anacondaを使っている場合

私はMacにAnaconda3-4.3.1をインストールしており、この環境では以下の環境設定をしないとエラーが出たので補足します。

```
export PYTHONPATH=/Users/xxx/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/:/Users/xxx/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/site-packages/:/Users/xxx/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/lib-dynload/
export PYTHONHOME=$PYTHONPATH
```

※「xxx」は各自のユーザー名に置き換えて下さい。

ちなみに、anacondaというブランチで修正版が公開されているので、あわせてご参照下さい。

https://github.com/mrkn/pycall.rb/tree/anaconda

# 基本

PyCallを呼び出して、RubyにPythonのライブラリを設定します。
以下は、Pythonのsysを呼び出して、パスを表示するサンプルです。

```rb:
require 'pycall'
sys = PyCall.import_module('sys')
p sys.path
```

私の環境では以下のように表示されます。

```text:
['/Users/xxx/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/pycall-1.0.2/lib/pycall/python', '/Users/xxx/.pyenv/versions/anaconda3-4.3.1/lib/python36.zip', '/Users/xxx/.pyenv/versions/anaconda3-4.3.1/lib/python3.6', '/Users/xxx/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/lib-dynload', '/Users/xxx/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/site-packages', '/Users/xxx/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/site-packages/Sphinx-1.5.1-py3.6.egg', '/Users/xxx/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/site-packages/aeosa', '/Users/xxx/.pyenv/versions/anaconda3-4.3.1/lib/python3.6/site-packages/dlib-19.6.0-py3.6-macosx-10.7-x86_64.egg']
```

基本的には、以下の使い方になるようです。

ライブラリ名 = PyCall.import_module('ライブラリ名')
ライブラリ名.メソッド

# Numpy

Numpyは専用にgemが作ってあり、もっと使いやすくなっています。

```rb:
require 'numpy'
np = Numpy
x = np.asarray([1,2,3,4,5])
p x.sum()
```

上記のコードを実行すると「15」が返ってくるはずです。

# Pandas

Pandasにも同様に専用のgemがあります。
ここでは、以下のCSVファイルを読み込む例を紹介します。

```text:sample.csv
a,b,c
0,1,2
3,4,5
6,7,8
```

以下のコードを実行します。

```rb:
require 'pandas'
pd = Pandas
x = pd.read_csv('sample.csv')
p x.shape
```

結果、「(3,　3)」と表示されまるはずです。

# Matplotlib

可視化ライブラリを使用して、とても単純なグラフを描画してみます。

```rb:
require 'pycall'
plt = PyCall.import_module('matplotlib.pyplot')

plt.plot([1,3,2,4])
plt.savefig("test.png")
```

実行すると「test.png」という画像ファイルが生成され、以下のようなグラフが描画されます。

![test.png](https://qiita-image-store.s3.amazonaws.com/0/114240/f28b96db-2ab6-bbb8-60a6-97284a283722.png)

# 機械学習

毎度のことではありますが、中国電力さんが公開されている電力使用量の過去データを学習し、電力使用量を予測する機械学習のサンプルを以下に示します。
ここでは、サンプルを単純にするため、2016年度のデータのみを使って学習しています。

まずは、以下のURLより2016年度のデータをダウンロードします。
http://www.energia.co.jp/jukyuu/download.html

次に以下のサンプルを実行して下さい。

```rb:
# ライブラリ読込
require 'pycall'
require 'pandas'
require 'time'

pd = Pandas

# ファイル読込
filename = "juyo-2016.csv"
df_kw = pd.read_csv(filename, encoding: "SHIFT-JIS", skiprows: 2)
df_kw["KW"] = df_kw.pop("実績(万kW)")

# データ加工
year = []
month = []
day = []
wday = []
hour = []

PyCall.len(df_kw).times do |i|
  
  dt = DateTime.parse(df_kw.DATE.iloc[i] + " " + df_kw.TIME.iloc[i])
  
  year << dt.year
  month << dt.month
  day << dt.day
  wday << dt.wday
  hour << dt.hour
  
end

df_kw["YEAR"] = year
df_kw["MONTH"] = month
df_kw["DAY"] = day
df_kw["WEEK"] = wday
df_kw["HOUR"] = hour

# 学習データの取得
cols = ["KW","YEAR","MONTH","WEEK","HOUR"]
df = df_kw[cols]
y = df.pop("KW").as_matrix().astype("int").flatten()
x = df.as_matrix().astype("float")

# クロスバリデーション
cv = PyCall.import_module('sklearn.model_selection')
x_train, x_test, y_train, y_test = cv.train_test_split(x, y, test_size: 0.1, random_state: 42)

# 正規化
preprocessing = PyCall.import_module('sklearn.preprocessing')
scaler = preprocessing.StandardScaler.new()
scaler.fit(x_train)
x_train = scaler.transform(x_train)
x_test = scaler.transform(x_test)

# 学習
ensemble = PyCall.import_module('sklearn.ensemble')
model = ensemble.RandomForestRegressor.new(random_state: 42)
model.fit(x_train, y_train)

puts model.score(x_test,y_test)
```

実行すると「0.77093639126251379」と表示され、約77%の精度で予測できることがわかります。

# さいごに

これからもっとサンプルができたら都度追加していきます。

# 補足

iRuby Notebookを使うともっと色々なことができます。興味のある方は以下のURLをご参照頂き、iRubyをインストールしてご利用下さい。

Mac
http://qiita.com/mix_dvd/items/88c9c935c1c0a388ee83

Windows
http://qiita.com/mix_dvd/items/3e4305d31e7a6785fbb0