はてなブログProにすれば勝手に広告が消えると思ってたら、設定が必要だった。だいたい3ステップぐらい必要だった。広告を消したのは「広告って読み込み重いから鬱陶しいよね」という軽い気持ちから。
- 設定から、詳細設定タブを選択する。
- 広告を非表示で、はてなによる広告を表示しない、を選択する。
- 画面最下部の変更するボタンを押すことを忘れずに。
以上。※画像がドーンってデカくなったので記事を後で修正しました。
Rubyで線形代数・機械学習アルゴリズムの実装を行う場合、SciRubyのNMatrixが最適だろう。 このNMatrixで、 RやPythonのNumpyと同様に、後ろで叩いているBLAS/LAPACKを、OpenBLASやIntel MKLに変えることで、高速化することを考えた。 しかし、Macでは、BLAS/LAPACKはAccelerate Frameworkに含まれていて、OpenBLASに変えるまでもなく十分に速かった。 環境は、MacBook、Intel Core m3 1.1Ghz、メモリ8G、macOS Sierra 10.12.6 である。
まずは、素のNMatrixと、MacのBLAS/LAPACKを使う場合の実行速度を計測した。 インストールは、gemからもできるが、測定条件を一致させるため最新版をビルドする方法を採用した。
$ git clone https://github.com/SciRuby/nmatrix.git $ cd nmatrix/ $ bundle install $ bundle exec rake compile nmatrix_plugins=lapacke $ bundle exec rake spec nmatrix_plugins=lapacke $ bundle exec rake install nmatrix_plugins=lapacke
単純な行列積で、実行速度を計測する。行列積が速くなると色々と嬉しい。
require 'nmatrix' require 'benchmark' Benchmark.bm do |x| x.report do 50.times do a = NMatrix.random [1000, 1000] b = NMatrix.random [1000, 1000] c = a.dot b end end end
これを、実行すると以下の様になる。
$ ruby test_nmat.rb user system total real 53.790000 1.400000 55.190000 ( 56.935680)
さらにLAPACKプラグインの実行速度を確認するため、require ‘nmatrix'を、
require 'nmatrix/lapacke'
と変更する。これを実行すると、素のNMatrixと比較してグンと速くなった。
$ ruby test_nmat.rb user system total real 23.050000 1.090000 24.140000 ( 18.840261)
OpenBLASは、Homebrewでインストールできる。 「–build-from-source」や「–with-openmp」といったオプションも指定できるが、 何も指定しないものが、行列積では最も速かった。
brew install openblas
「ext/nmatrix_lapacke/extconf.rb」を編集して、OpenBLASを使用するようにする。
... #ldefaults = {lapack: ["/usr/local/lib"].delete_if { |d| !Dir.exists?(d) } } ldefaults = {lapack: ["/usr/local/opt/openblas/lib"] } ... #$libs += " -llapack " $libs += " -L/usr/local/opt/openblas/lib -lopenblas " ...
NMatrixを再インストールする。
$ gem uninstall namtrix nmatix-lapacke $ bundle exec rake clean $ bundle exec rake compile nmatrix_plugins=lapacke $ bundle exec rake spec nmatrix_plugins=lapacke $ bundle exec rake install nmatrix_plugins=lapacke
OpenBLASを叩くLAPACKプラグインという状態なので、
require 'nmatrix/lapacke'
とする。実行してみると、LAPACKの結果と大差ないものとなった。
$ ruby test_nmat.rb user system total real 27.400000 4.530000 31.930000 ( 17.920017)
以下の特異値分解を含むプログラムでも比較を行った。
require 'nmatrix/lapacke' require 'benchmark' Benchmark.bm do |x| x.report do 50.times do a = NMatrix.random [200, 2000] b = a.dot a.transpose # b.gesvd end end end
LAPACKを使用した場合では、
$ ruby test_nmat2.rb user system total real 6.040000 0.300000 6.340000 ( 5.908795)
となり、OpenBLASを使用した場合では、
$ ruby test_nmat2.rb user system total real 27.220000 4.920000 32.140000 ( 16.595134)
となった。OpenBLASよりもLAPACKの方が速く、 MacではAccelerate FrameworkのBLAS/LAPACKを使用した方が良いことがわかる。
ちなみに、Intel MKLでも試したが、Accelerate FrameworkのBLAS/LAPACKの方が速かった。 また、Intel MKLでは、rake spec した際にコケてしまった。
MacでNMatrixを使用する場合は、
gem install nmatrix nmatrix-lapacke
として、
require 'nmatrix/lapacke'
とすれば良い。
マーケティング寄りのデータ分析の知識を補うため、以下の本で勉強を始めた。事例ベースな内容で、とても読みやすい。 Pandasも習得したいので、Pandasに翻訳しながら読み進めている。今回は第6章を勉強した。
ちなみに、CSVファイルなどのデータは、本のサポートページ(SBクリエイティブ:ビジネス活用事例で学ぶ データサイエンス入門)で配布されている。
第6章では、重回帰分析を扱っている。作業はJupyter Notebook上で行った。回帰にはScikit-Learnを用いる。 本ではひとまず、散布図を出力して、テレビ広告・雑誌広告とアプリのインストール数との関係を見ている。
%matplotlib inline # Jupyter Notebookでmatplotlibの図が表示されないときにつけるおまじない import matplotlib.pyplot as plt import pandas as pd import numpy as np from sklearn.linear_model import LinearRegression # データを読み込む。 ad_data = pd.read_csv('ad_result.csv') ad_data.head(2)
month | tvcm | magazine | install | |
---|---|---|---|---|
0 | 2013-01 | 6358 | 5955 | 53948 |
1 | 2013-02 | 8176 | 6069 | 57300 |
# 散布図の出力にはscatterメソッドを用いる。 # x軸とy軸は、データのヘッダにある列名で指定できる。 ad_data.plot.scatter(x='tvcm', y='install') ad_data.plot.scatter(x='magazine', y='install')
散布図から何かしらの相関があることが伺える。回帰分析によりモデル化する。
# Numpy形式でデータを取り出す。 X=np.array(ad_data[['tvcm', 'magazine']]) y=np.array(ad_data['install']) # 回帰モデルを得る。 model=LinearRegression().fit(X, y) # 回帰モデルの切片と係数を確認する。 # インストール数とテレビ広告・雑誌広告には以下の関係があることがわかる。 # 「インストール数 = 188.174 + 1.361 x テレビ広告 +7.250 x 雑誌広告」 print(model.intercept_) print(model.coef_) # 188.17427483 # [ 1.3609213 7.24980915] # 決定係数を確認する。 # 1に近いので、当てはまりが良いことがわかる。 print(model.score(X,y)) # 0.937901430104
別の選択肢としては、StatsModelのOLS(Ordinary Least Squares)を用いる方法がある。 StatsModelの回帰分析は、summaryメソッドを持っており、R言語のlm関数に似た結果を得られる。
from statsmodels.regression.linear_model import OLS results=model = OLS(y, X).fit() print(results.summary()) # OLS Regression Results # ============================================================================== # Dep. Variable: y R-squared: 1.000 # Model: OLS Adj. R-squared: 0.999 # Method: Least Squares F-statistic: 8403. # Date: Sun, 16 Jul 2017 Prob (F-statistic): 5.12e-14 # Time: 16:15:12 Log-Likelihood: -84.758 # No. Observations: 10 AIC: 173.5 # Df Residuals: 8 BIC: 174.1 # Df Model: 2 # Covariance Type: nonrobust # ============================================================================== # coef std err t P>|t| [0.025 0.975] # ------------------------------------------------------------------------------ # x1 1.3540 0.405 3.347 0.010 0.421 2.287 # x2 7.2892 0.476 15.320 0.000 6.192 8.386 # ============================================================================== # Omnibus: 1.009 Durbin-Watson: 0.876 # Prob(Omnibus): 0.604 Jarque-Bera (JB): 0.804 # Skew: 0.539 Prob(JB): 0.669 # Kurtosis: 2.123 Cond. No. 14.0 # ==============================================================================
6章から、機械学習に関係する話がでてくる。PandasというよりもScikit-Learnが活躍する感じ。7章にある「本当の意味での正解データがないなかで、なんらかの(ビジネス上意味のある)示唆を出さなければならない」という記述は、「うっ」という苦しい気持ちになる。
マーケティング寄りのデータ分析の知識を補うため、以下の本で勉強を始めた。事例ベースな内容で、とても読みやすい。 Pandasも習得したいので、Pandasに翻訳しながら読み進めている。今回は第5章を勉強した。
ちなみに、CSVファイルなどのデータは、本のサポートページ(SBクリエイティブ:ビジネス活用事例で学ぶ データサイエンス入門)で配布されている。
第5章では、Web系のデータ分析では定番?のバナー広告のA/Bテストを扱っている。作業はJupyter Notebook上で行った。 カイ二乗検定が使われているが、Pandasにはカイ二乗検定はない様子なので、SciPyのstats.chi2_contingencyを使う。
%matplotlib inline # Jupyter Notebookでmatplotlibの図が表示されないときにつけるおまじない import matplotlib.pyplot as plt import pandas as pd import numpy as np from scipy.stats import chi2_contingency # データを読み込む。 ab_test_imp = pd.read_csv('section5-ab_test_imp.csv') ab_test_goal = pd.read_csv('section5-ab_test_goal.csv') # transition_idが同じものをくっつける。 ab_test_imp_goal = pd.merge(ab_test_imp, ab_test_goal, on=['transaction_id'], how='outer', suffixes=['','.g']) # user_id.gがNaNだった場合に「0」それ以外では「1」として、クリックされたかを判定するフラグとする。 ab_test_imp_goal['is_goal'] = 1 - ab_test_imp_goal['user_id.g'].apply(np.isnan).astype(int) # 集計してクリック率を計算する。 sum_goal = ab_test_imp_goal.groupby('test_case')['is_goal'].sum() sz_user = ab_test_imp.groupby('test_case')['user_id'].size() sum_goal / sz_user # ※ Jupyter Notebook上には以下の用にクリック率が表示される。 # Aが約8%で、Bが約11%となった。 # test_case # A 0.080256 # B 0.115460 # dtype: float64 # カイ二乗検定により、クリック率に統計的な差があるかを確認する。 cr = ab_test_imp_goal.pivot_table(index='test_case',columns='is_goal', values='user_id', aggfunc='count') # ※ crは以下のようなクロス集計結果となる # is_goal 0 1 # test_case # A 40592 3542 # B 38734 5056 # chi2, p, dof, expected = chi2_contingency(cr.as_matrix()) print(chi2) # 308.375052893 print(p) # 4.93413963379e-69
chi2の値が本と同様の値となり、p値も本と同様にとても小さな値となった。 p値が小さいということで 「バナーAとバナーBでは、クリックされなかった(0)とクリックされた(1)の割合に差がない」という帰無仮説が棄却され、広告をバナーAとバナーBに分けたことで、クリック率が変わったと判断できる。 本では、この後、テストケースごとのクリック率を計算したりするが、今回は省略。
Rのchisq.test関数と勝手が違ったので、手間取ってしまった。本ではカイ二乗検定の詳しい説明がないので、気になる方は別な統計本を買って勉強する必要がある。「統計的に有意な差」と「ビジネス的に意味があるか」という2つの観点が出てきたりして、ちょっと、この章は読みづらい感がある。
マーケティング寄りのデータ分析の知識を補うため、以下の本で勉強を始めた。事例ベースな内容で、とても読みやすい。 Pandasも習得したいので、Pandasに翻訳しながら読み進めている。今回は第4章を勉強した。
ちなみに、CSVファイルなどのデータは、本のサポートページ(SBクリエイティブ:ビジネス活用事例で学ぶ データサイエンス入門)で配布されている。
第4章では、クロス集計を扱っている。作業はJupyter Notebook上で行った。Pandasなコードは以下のとおり。
%matplotlib inline # Jupyter Notebookでmatplotlibの図が表示されないときにつけるおまじない import matplotlib.pyplot as plt import pandas as pd import numpy as np # データを読み込む。 dau = pd.read_csv('section4-dau.csv') user_info = pd.read_csv('section4-user_info.csv') # user_idとapp_nameが同じものをくっつける。 dau_user_info = pd.merge(dau, user_info, on=['user_id', 'app_name']) # 月次で集計するため、日付を月までにする。 dau_user_info['log_month'] = dau_user_info['log_date'].str.slice(0, 7) # 性別で集計する。 dau_user_info.pivot_table(index='log_month',columns='gender', values='user_id', aggfunc='count')
gender | F | M |
---|---|---|
log_month | ||
2013-08 | 47343 | 46842 |
2013-09 | 38027 | 38148 |
# 年代で集計する(表は省略)。 dau_user_info.pivot_table(index='log_month',columns='generation', values='user_id', aggfunc='count') # 性別と年代で集計する(表は省略)。 dau_user_info.pivot_table(index='log_month',columns=['gender', 'generation'], values='user_id', aggfunc='count') # デバイスで集計する(表は省略)。 dau_user_info.pivot_table(index='log_month',columns='device_type', values='user_id', aggfunc='count') # 集計結果を可視化する。 dau_user_info.groupby(['log_date', 'device_type'])['app_name'].count().groupby('device_type').plot(legend=True,rot=45)
デバイスでわけて、日付ごとのユーザー数を集計し、可視化したものが以下のとおり。 本と同様に、9月になってから、Androidユーザーが少なくなっている。
pivot_tableで多重なクロス集計もできるので便利。今回も手こずったのは、plotの部分で、x軸のラベルを日付だけにしたかったけど諦め。細かいことは、matplotlib使えば良いんだろうけど、勉強中なので、しばらくはPandasのplotにこだわりたい。