DaruとStatsampleを使ったデータ分析を試してみた

はじめに

こんにちは、Misoca開発チームの洋食(yoshoku)です。 私は、Python十年選手な機械学習メンですが、MisocaではRuby小僧なRailsキッズしてます。 データ分析のフィールドでは、RやPythonがメジャーなプログラミング言語ですが、 SciRubyプロジェクトを中心に、 Rubyでもデータ分析やるぜ的なバイブスが上がってきています。 そんなわけで、レペゼンMisocaで、基礎的なデータ分析を試してみました。 f:id:yoshoku:20170802232449p:plain

DaruとStatsample

Daru(Data Analysis in RUby)は、その名のとおり、 Rubyでのデータの操作や可視化を実現するライブラリで、 PythonのPandasに相当するものです。 Statsample は、 統計的な分析・検定手法を提供するライブラリで、 PythonのStatsModelsに相当するものです。 どちらもgemコマンドでインストールできます。

$ gem install daru statsample

requireもライブラリ名そのままです。

require 'daru'
require 'statsample'

いろいろやってみよう

データの読み込み

Daruでは、データを、ExcelファイルやCSVファイルを読み込むことや、SQLの実行結果から得ることができます。 今回はCSVファイルから読み込むことにします。 使用するデータは、UCI Machine Learning Repositoryで公開されている、ワインの品質に関するデータを選びました。 このデータは、拡張子はCSVですが、項目はセミコロン(;)で区切られています。 Daruでは、from_csvメソッドでCSVファイルを読み込みます。 このとき、セパレータを指定できるので、カンマで区切られていなくても、読み込むことができます。

df = Daru::DataFrame.from_csv 'winequality-red.csv', {col_sep: ';'}

平均や標準偏差を見てみよう

ワインデータには、アルコール度数などのワインのパラメータと、ワインの品質が10段階で評価された値が含まれています。 いくつかのパラメータの平均や標準偏差を見てみましょう。 データから特定の項目を複数とり出したい場合は、項目名をカンマ区切りで指定します。

ds = df['fixed acidity','alcohol']

describeメソッドにより、各データ項目の平均や標準偏差を確認することができます。 Daruでは、to_sメソッドは、単なる文字列ではなく、htmlを出力するものが多いです。 これは、ReportBuilderに渡して、実行結果をhtmlで書き出すことを想定している様です (いまは Jupyter Notebook + iruby な時代ですが、せっかくなので使ってみましょう)。

rb = ReportBuilder.new
rb.add(ds.describe.to_s)
rb.save_html('result.html')

とすると、データ数・平均・標準偏差・最小値・最大値の表が作成されます。 ※表が大きくなるので小数点5桁までとしました。

alcohol fixed acidity
count 1599 1599
mean 10.42298 8.31963
std 1.06566 1.74109
min 8.4 4.6
max 14.9 15.9

相関行列を計算してみよう

相関行列も、corrメソッドにより、簡単に計算できます。

ds = df['fixed acidity','residual sugar','density','alcohol']
rb.add(ds.corr.to_s)

出力された相関行列をみると、「fixed acidity」と「density」の間に相関関係がありそうです。

fixed acidity residual sugar density alcohol
fixed acidity 0.99999 0.11477 0.66804 -0.06166
residual sugar 0.11477 1.0 0.35528 0.04207
density 0.66804 0.35528 1.0 -0.49617
alcohol -0.06166 0.04207 -0.49617 1.0

そんなわけで、Statsampleを使って散布図を見てみましょう。

rb.add(Statsample::Graph::Scatterplot.new(df['fixed acidity'], df['density']))

とすると、散布図が出力されます。

f:id:yoshoku:20170731170156p:plain:w320

※今回「fixed acidity」と「density」との間になにか相関関係があることは確認できましたが、 その意味するところは、私はワインの専門家ではないのでわかりません。 パっと思いつくのは「説明変数としてはfixed acidityかdensityのどちらか一方を削っちゃうかも」ぐらいです。 データ分析では、そのデータに対する知識も必要ですね。

重回帰分析をしてみよう

最後に、Statsampleを使って重回帰分析をしてみます。 ワインの各パラメータから、品質を表現してみましょう。 Statsample::Regression.multipleに、データと、データ中で目的変数とする項目名(ここでは品質を表すquality)を与えるだけでOKです。

model = Statsample::Regression.multiple df, 'quality'
puts model.summary

得られたモデルのsummaryメソッドで、決定係数などを確認できます。 ワインの品質には「free sulfur dioxide」「sulphates」「alcohol」あたりが重要そうな感じです。

# ここでは省略しますが説明変数のt値の一覧なども出力されます。
  R=0.600
  R^2=0.361
  R^2 Adj=0.356
  Std.Error R=0.648
  Equation=21.965 + 0.025fixed acidity + -1.084volatile acidity + -0.183citric acid +
  0.016residual sugar + -1.874chlorides + 0.004free sulfur dioxide +
  -0.003total sulfur dioxide + -17.881density + -0.414pH + 0.916sulphates + 0.276alcohol
  ...

この他、Statsampleには、t検定やカイ二乗検定といった検定も用意されているので、A/Bテストなどにも使えます。

まとめ

RやPythonと比べると、実装されていない機械学習アルゴリズムもあったりしますが、 Rubyでも、回帰分析や主成分分析など、基本的なデータ分析はできます。 ログからエビデンスを集め、お客様が必要とするサービスを、 データドリブンにデベロップしていく基盤が用意されつつあります。

採用

Misocaではサービス開発の基盤作りにLOVEなバイブスあふれたエンジニアを募集しています!