SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

Ruby-Pythonブリッジライブラリ「PyCall」を使ってRubyでデータ分析をしよう!

  • X ポスト
  • このエントリーをはてなブックマークに追加

3 PyCallを使ってみる(2)

3.4 PyCallによるデータ分析の実例

 PyCall経由でpandasを使う例として、タイタニック号の乗客データをデータフレームとして読み込み、簡単な前処理として分布を調べ、欠損値処理をしてみます。以下のコードは、pryを使って実行していくことを想定しています。

 まずは、利用するライブラリをロードしておきます。

require 'pycall/import'
include PyCall::Import

require 'matplotlib/pyplot'
pyimport :pandas, as: :pd
pyimport :seaborn, as: :sns

 データはseabornライブラリのload_dataset関数を使いpandasのデータフレーム形式で取得します。

df = sns.load_dataset.('titanic'); nil  # この nil は df の中身が全て表示されてしまうのを防ぐため

 変数dfが参照するオブジェクトがpandasのデータフレームです。

df.type  #=> pytype(DataFrame)

 データの大きさを調べましょう。

df.shape #=> (891, 15)

 このデータは、15カラムで構成されるデータが890個あります(残りの1行はヘッダ)。15個のカラムのうち、以下のように内容が重複しているものがあります。

  • survivedaliveno → 0、yes → 1と変換して生成したもの
  • embarkedembark_townの頭文字を取ったもの
  • pclassclassを数値にしたもの
  • sexwhomalemanfemalewomanという対応関係にある

 このように内容が重複するカラムが存在すると、情報量が変わらないのに処理量が増えてしまうため、これらは削除しましょう。

df = df.drop.(%w[alive embark_town class who], axis: 1); nil

 次に欠損値の処理をします。このデータはどのくらい欠損値を含んでいるでしょうか? 調べてみましょう。

df.isnull.().sum.()
# => survived        0
# pclass          0
# sex             0
# age           177
# sibsp           0
# parch           0
# fare            0
# embarked        2
# adult_male      0
# deck          688
# alone           0
# dtype: int64

 これより、ageカラムに177個、deckカラムに688個、embarkedカラムに2個の欠損値が存在することが分かりました。

 全体で890行なので、半分以上が欠損しているdeckカラムは分析では使えません。捨てることにします。

df = df.drop.('deck', axis: 1); nil

 次にageカラムの分布を見てみましょう。分布の可視化のため、seabornのkdeplotrugplotを使います。

sampled_age = df.age.dropna.().sample.(100)
sns.kdeplot.(sampled_age, shade: true, cut: 0)
sns.rugplot.(sampled_age)
Matplotlib::Pyplot.show()
ageカラムの分布
ageカラムの分布

 ageの平均値も見てみましょう。データフレームのdescribeメソッドを使うと要約統計量を全て確認できます。

df.describe.()
# =>          survived      pclass         age       sibsp       parch        fare
# count  891.000000  891.000000  714.000000  891.000000  891.000000  891.000000
# mean     0.383838    2.308642   29.699118    0.523008    0.381594   32.204208
# std      0.486592    0.836071   14.526497    1.102743    0.806057   49.693429
# min      0.000000    1.000000    0.420000    0.000000    0.000000    0.000000
# 25%      0.000000    2.000000   20.125000    0.000000    0.000000    7.910400
# 50%      0.000000    3.000000   28.000000    0.000000    0.000000   14.454200
# 75%      1.000000    3.000000   38.000000    1.000000    0.000000   31.000000
# max      1.000000    3.000000   80.000000    8.000000    6.000000  512.329200

 これより、ageの平均は約29.7、中央値は28であることが分かります。

 可視化した分布の最頻値もだいたいその辺りの値なので、ここでは欠損値を中央値で埋めることにします。

df.age.fillna.(df.age.median.(), inplace: true)

 もう一度、ageカラムの欠損値の個数を調べてみましょう。

df.age.isnull.().sum.() #=> 0

 全ての欠損値が埋まっています。

 ここまでと同じ内容を含み、さらにカテゴリ変数のダミー変数化、分類モデルの構築をしているIRubyノートブックをpycallリポジトリのexampleディレクトリに入れてあります。以下のURLから閲覧できるのでぜひご覧ください。

3.5 その他の使用例

 PyCallのリポジトリには、本稿で紹介していない例も用意しています。

 この中のnotebooksディレクトリには、IRubyとPyCall、およびmatplotlibを利用した例をノートブック形式で用意しています。

4 PyCallの今後の開発予定

 本稿執筆時点では、PyCallの既存実装の見直しと改善、及びnumpyのC-APIを利用したラッパーの開発を進めています。

 RubyKaigi 2017までに安定版をリリースします。安定版では、本稿執筆時点のPyCallよりも、よりRubyらしい書き方を許せる仕組みを導入する予定です。また、ActiveRecordやRedArrowとpandasとの間でのデータの連携など、RubyのライブラリとPythonのライブラリの間の相互運用性を高めます。

 2017年中にはKerasとChainerを完全にサポートし、RubyでもGPUを用いた本格的な深層学習モデルを利用できるようにする予定です。

 2018年以降は、R、Julia、Stan、Scala(Spark)などPython以外のプログラミング言語やシステムとの間のブリッジを開発し、それらを同時に利用した際の相互運用性の向上を目指していきます。

5 まとめ

 本稿では、Rubyをデータサイエンスで使えるプログラミング言語にするためのRuby-PythonブリッジライブラリであるPyCallについて紹介し、PyCallを介してPythonのライブラリを利用したデータ分析工程の例を示しました。さらに、PyCallの現在の開発状況と今後の開発計画についても説明しました。

 Rubyをデータサイエンスで使えるプログラミング言語にするために言語間ブリッジを整備していくアプローチは多数の課題を抱えています。本稿執筆時点でPyCallの開発者は私一人です。上述の通り、多言語間ブリッジについて他にもやりたいことはいくつもあるので、この方向性に賛同し開発をサポートしてくださる方を募集しています。ライブラリを自力で実装できる方、ドキュメンテーションが得意な方、ウェブサイトを作るのが得意な方を探しています。われこそはと思った方は今すぐ筆者までご連絡ください。

 PyCallの開発をはじめ、Rubyでのデータサイエンス環境を整備していくにあたり、実世界での利用例や困りごとの実例をたくさん知りたいと思っています。「Railsで作ったシステムがあって、データ分析を導入したいが良いやり方が分からない」とか、「PyCallをこういう用途で使おうと思っている」といった相談や報告をいただけるとうれしいです。ご連絡をお待ちしております。

参考文献

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

村田 賢太(株式会社Speee)(ムラタ ケンタ)

 Kondara MNU/Linuxの開発をはじめ、いくつかのオープンソースソフトウェアの開発への参画を経て、2010年よりCRubyのコミッターとして、主にbigdecimalライブラリのメンテナンスを担当する。クックパッド株式会社(2011〜2016)。株式会社リクルートホールディングス(201...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10251 2017/07/14 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング