読者です 読者をやめる 読者になる 読者になる

RをPandasに置き換える(ヒストグラム)

ビジネス活用事例で学ぶ データサイエンス入門

ビジネス活用事例で学ぶ データサイエンス入門

タイトルのとおり、ビジネス事例(アプリ開発会社の事例)を元にしてデータ分析を学ぶスタイルになっています。馴染みのある事例なのでデータ活用のイメージがしやすい内容になっています。

本書はRを使っていますが、どちらかというとPython Pandasの方が好きなので、RからPandasに置き換えてみました。

(0)R・データの準備

Rインストール

R for Mac OS X

R-3.2.3.pkgをインストールしました。

データダウンロード

ビジネス活用事例で学ぶ データサイエンス入門

上記からダウンロードしました。

(1)CSVファイル読み込み

  • DAU(1日1回以上アクセスしたユーザのデータ
  • DPU(1日1円以上課金したユーザのデータ
  • Install(ユーザごとにいつゲームを利用開始したかのデータ)

R

> dau <- read.csv("section3-dau.csv", header = T, stringsAsFactors = F)
> head(dau)
    log_date app_name user_id
1 2013-06-01  game-01     116
2 2013-06-01  game-01   13491
3 2013-06-01  game-01    7006

> dpu <- read.csv("section3-dpu.csv", header = T, stringsAsFactors = F)
> head(dpu)
    log_date app_name user_id payment
1 2013-06-01  game-01     351    1333
2 2013-06-01  game-01   12796      81
3 2013-06-01  game-01     364     571

> install <- read.csv("section3-install.csv", header = T, stringsAsFactors= F)
> head(install)
  install_date app_name user_id
1   2013-04-15  game-01       1
2   2013-04-15  game-01       2
3   2013-04-15  game-01       3

Pandas

>>> import pandas as pd
>>> dau = pd.read_csv("section3-dau.csv")
>>> dau
          log_date app_name  user_id
0       2013-06-01  game-01      116
1       2013-06-01  game-01    13491
2       2013-06-01  game-01     7006

>>> dpu = pd.read_csv("section3-dpu.csv")
>>> dpu
       log_date app_name  user_id  payment
0    2013-06-01  game-01      351     1333
1    2013-06-01  game-01    12796       81
2    2013-06-01  game-01      364      571

>>> install = pd.read_csv("section3-install.csv")
>>> install
      install_date app_name  user_id
0       2013-04-15  game-01        1
1       2013-04-15  game-01        2
2       2013-04-15  game-01        3

(2)DAUのデータにInstallデータをくっつける

R

> dau.install <- merge(dau, install, by = c("user_id", "app_name"))
> head(dau.install)
  user_id app_name   log_date install_date
1       1  game-01 2013-06-03   2013-04-15
2       1  game-01 2013-06-14   2013-04-15
3       1  game-01 2013-07-09   2013-04-15

Pandas

>>> dauinstall = pd.merge(dau, install, how='left', on=['user_id', 'app_name'])
>>> dauinstall
          log_date app_name  user_id install_date
0       2013-06-01  game-01      116   2013-04-17
1       2013-06-01  game-01    13491   2013-06-01
2       2013-06-01  game-01     7006   2013-05-03

(3)dau.installに、さらにDPUデータをくっつける

R

> dau.install.payment <- merge(dau.install, dpu, by = c("log_date", "app_name", "user_id"), all.x = T)
> head(dau.install.payment)
    log_date app_name user_id install_date payment
1 2013-06-01  game-01       1   2013-04-15      NA
2 2013-06-01  game-01       3   2013-04-15      NA
3 2013-06-01  game-01       6   2013-04-15      NA

Pandas

>>> dauinstallpayment = pd.merge(dauinstall, dpu, how = 'left', on = ['log_date', 'app_name', 'user_id'])
>>> dauinstallpayment
          log_date app_nam  user_id install_date  payment
0       2013-06-01  game-01      116   2013-04-17      NaN
1       2013-06-01  game-01    13491   2013-06-01      NaN
2       2013-06-01  game-01     7006   2013-05-03      NaN

(4)payment=NAのデータを除外する

R

> head(na.omit(dau.install.payment))
      log_date app_name user_id install_date payment
7   2013-06-01  game-01      19   2013-04-15     162
81  2013-06-01  game-01     351   2013-04-18    1333
84  2013-06-01  game-01     364   2013-04-18     571

Pandas

>>> dauinstallpayment.dropna(subset=['payment'])
          log_date app_name  user_id install_date  payment
12      2013-06-01  game-01       19   2013-04-15      162
84      2013-06-01  game-01      351   2013-04-18     1333
87      2013-06-01  game-01      364   2013-04-18      571

(5)payment=NAのデータに課金額0を設定する

R

> dau.install.payment$payment[is.na(dau.install.payment$payment)] <- 0
> head(dau.install.payment)
    log_date app_name user_id install_date payment
1 2013-06-01  game-01       1   2013-04-15       0
2 2013-06-01  game-01       3   2013-04-15       0
3 2013-06-01  game-01       6   2013-04-15       0

Pandas

>>> dauinstallpayment.fillna(0)
          log_date app_name  user_id install_date  payment
0       2013-06-01  game-01      116   2013-04-17        0
1       2013-06-01  game-01    13491   2013-06-01        0
2       2013-06-01  game-01     7006   2013-05-03        0

>>> dauinstallpayment.fillna(0, inplace=True)
>>> dauinstallpayment
          log_date app_name  user_id install_date  payment
0       2013-06-01  game-01      116   2013-04-17        0
1       2013-06-01  game-01    13491   2013-06-01        0
2       2013-06-01  game-01     7006   2013-05-03        0

(6)月次で集計する

R

> dau.install.payment$log_month <- substr(dau.install.payment$log_date, 1, 7)
> dau.install.payment$install_month <- substr(dau.install.payment$install_date, 1, 7)
> library("plyr")
> mau.payment <- ddply(dau.install.payment, .(log_month, user_id, install_month), summarize, payment = sum(payment))
> head(mau.payment)
  log_month user_id install_month payment
1   2013-06       1       2013-04       0
2   2013-06       2       2013-04       0
3   2013-06       3       2013-04   14994

Pandas

dauinstallpayment['log_month'] = dauinstallpayment['log_date'].str[0:7]
dauinstallpayment['install_month'] = dauinstallpayment['install_date'].str[0:7]

>>> maupayment = dauinstallpayment.groupby(['user_id','log_month', 'install_month'])['payment'].sum() 
>>> maupayment
user_id  log_month  install_month
1        2013-06    2013-04              0
         2013-07    2013-04              0
2        2013-06    2013-04              0
3        2013-06    2013-04          14994

(7)新規ユーザか既存ユーザかの区分を追加する

R

> mau.payment$user.type <-ifelse(mau.payment$install_month == mau.payment$log_month, "install", "existing")
> mau.payment.summary <- ddply(mau.payment, .(log_month, user.type), summarise, total.payment = sum(payment))
> head(mau.payment)
  log_month user_id install_month payment user.type
1   2013-06       1       2013-04       0  existing
2   2013-06       2       2013-04       0  existing
3   2013-06       3       2013-04   14994  existing
4   2013-06       4       2013-04       0  existing
5   2013-06       6       2013-04       0  existing
6   2013-06       7       2013-04       0  existing
> head(mau.payment.summary)
  log_month user.type total.payment
1   2013-06  existing        177886
2   2013-06   install         49837
3   2013-07  existing        177886
4   2013-07   install         29199

Pandas

>>> dauinstallpayment['user_type'] = np.where(dauinstallpayment['log_month'] == dauinstallpayment['install_month'], 'install', 'existing')
>>> dauinstallpayment
          log_date app_name  user_id install_date  payment log_month install_month user_type
0       2013-06-01  game-01      116   2013-04-17        0   2013-06       2013-04  existing
1       2013-06-01  game-01    13491   2013-06-01        0   2013-06       2013-06   install
2       2013-06-01  game-01     7006   2013-05-03        0   2013-06       2013-05  existing

(8)グラフによりデータを可視化する(新規、既存比較)

R

ggplot(mau.payment.summary, aes(x = log_month, y = total.payment, fill = user.type)) + geom_bar(stat="identity") + scale_y_continuous(label = comma)

スクリーンショット 2016-02-27 15.09.32.png

Pandas

TODO..

(9)グラフによりデータを可視化する(金額別売上比較)

R

ggplot(mau.payment[mau.payment$payment > 0 & mau.payment$user.type == "install", ], aes(x = payment, fill = log_month)) + geom_histogram(position = "dodge", binwidth = 2000)

スクリーンショット 2016-02-27 15.10.30.png

Pandas

TODO..

補足 Pandasを0.17にした

Equivalent of R/ifelse in Python/Pandas? Compare string columns?

conda update anaconda
conda update conda
conda update pandas

numpy:  1.9.2-py34_0      --> 1.10.4-py34_0     
pandas: 0.16.2-np19py34_0 --> 0.17.1-np110py34_0
pytz:   2015.4-py34_0     --> 2015.7-py34_0     
six:    1.9.0-py34_0      --> 1.10.0-py34_0 

まとめ

Rの良いところの感想は以下です。しばらくRとPandasを併用してみてPro/Conを考えてみます。いずれにしても両方知っておくと、情報量を増やすことができるので良いと思いました。

  • Rのインストールが簡単
  • グラフがmatplotlibより(少し)オシャレ

参考

ビジネス活用事例で学ぶ データサイエンス入門

RjpWiki

R for Mac OS X

Merge, join, and concatenate

Python pandas 図でみる データ連結 / 結合処理

Equivalent of transform in R/ddply in Python/pandas?

pandasでよく使う文法まとめ

Python pandas strアクセサによる文字列処理

pandasメモ

Equivalent of R/ifelse in Python/Pandas? Compare string columns?

TipMe

TipMe with IndieSquare