kaekenのData Science探究ブログ

主にData Science、機械学習、深層学習、統計学、Python、数学、ビッグデータに関する知見をポストします。

2019.04沖縄合宿で参加した勉強会一覧

花粉症から逃れるため、

自主的に2019.04沖縄合宿を実施しておりました。

1ヶ月弱滞在し、非常に有意義な合宿でした。

クラウド、サーバレスの盛り上がりを体感し、

今後は、クラウド・サーバレス関連も重点的にウォッチしていきます。

また、AI/機械学習/Pythonの勉強会も盛んで、

沖縄でのデータサイエンス界隈の盛り上がりも実感しました。

現地のエンジニアの方々と交流でき、

非常に有意義な時間を過ごせました。

以下、沖縄で参加した勉強会一覧です!

4/16 Firebase 勉強会 in 沖縄 × 大阪 - Togetter https://togetter.com/li/1338768

4/20 GCPUG Okinawa!#7 午前「GKEハンズオン」午後「GCPと課題解決と意思決定」 - connpass https://okipug.connpass.com/event/115468/

4/21 PythonBeginners沖縄 22 初心者向け勉強会 - connpass https://python-beginners-okinawa.connpass.com/event/125925/

4/22 BeginnersLab #2 ベイズ勉強会(5.Joint probabilityから) - connpass https://python-beginners-okinawa.connpass.com/event/127905/

4/24 AliEatersOkinawa Meetup #1 - Alibaba Cloud - - connpass https://alieaters-okinawa.connpass.com/event/125747/

AliEatersOkinawa Meetup #1 - Alibaba Cloud - - Togetter https://togetter.com/li/1342269

4/26 Serverless Meetup Ryukyu #1 - connpass https://serverless.connpass.com/event/126902/

Serverless Meetup Ryukyu #1 - Togetter https://togetter.com/li/1342014

4/27 BeginnersLab #3 ベイズ勉強会(8.ベイズの定理から) - connpass https://python-beginners-okinawa.connpass.com/event/129229/

4/27 Cloud on the BEACH 2019 勉強会の部 - JAWS-UG沖縄 | Doorkeeper https://jaws-ug-okinawa.doorkeeper.jp/events/88202

JAWS-UG沖縄 Cloud on the BEACH 2019のまとめ - Togetter https://togetter.com/li/1342523

4/28 PyData.Okinawa Meetup #39 PythonOCR - connpass https://pydataokinawa.connpass.com/event/126114/

また来年花粉症の季節に来ます!

R言語でWebページの総合ランキングを作る方法

概要

Webページを評価する切り口は、さまざまな種類があります。

  • 表示回数
  • クリック数
  • 直帰率
  • 平均滞在時間
  • CV数
  • 各種ソーシャルいいね数
  • ...

もし各切り口の単位がバラバラで、ボリュームも異なり、優劣がつけられない場合、

総合的に判断することが難しくなります。

このような場合、

多数の考慮すべき情報を統合し優先順位をつけて総合ランキングを作るには、

以下の標準化を使うことで、総合的な評価指標の作成が可能になります。

標準化:単位が異なる複数の変数から総合指標を作成する方法

標準化については、以下の分かりやすい説明記事をご覧ください。

https://bellcurve.jp/statistics/course/7801.html

標準化することで、まったく異なる対象(数学と国語など)を統一的に評価できるようになります。

今回は、以下の具体的な6種類のデータを使って、Webページの総合ランキングを作成する方法をご紹介します。

実装

準備

まず、上記データのエクセルファイルを準備します。

R言語では、エクセルファイルやCSVなど、さまざまなファイルを読み書きすることが可能です。

# xls/xlsx形式を読み込むreadxlパッケージのインストール
install.packages("readxl", dependencies = TRUE)

# パッケージの利用準備
library(readxl)

# エクセルファイルの1シート目を読み込む
data = read_excel("~/Downloads/page_log.xlsx", 1)

つぎに、読み込んだデータの中身を確認します。

データの列名の意味は、以下の通りです。

  • No : データ行番号
  • TITLE : ページタイトル
  • PV : ページビュー
  • New : 新規流入
  • Average Time : 平均滞在時間
  • FB : Facebookいいね数
  • Pocket : Pocket保存数
  • Hatebu : はてブ登録数
# 読み込んだデータサンプリング
head(data)

# A tibble: 6 x 8
     No TITLE      PV    New `Average Time`    FB Pocket Hatebu
  <dbl> <chr>   <dbl>  <dbl>          <dbl> <dbl>  <dbl>  <dbl>
1     1 title1 154321  86341            184   264     60     21
2     2 title2 132840 103214            243   457     32     48
3     3 title3 186789 364212            160   190     52     26
4     4 title4  66455  30547            130   256    105     50
5     5 title5 506487 430687            311   830   1651   1198
6     6 title6 303546 153054            164    74    124     68

桁数がバラバラです。

以下、各データの統計量です。

# 要約統計量の表示
summary(data)
       No           TITLE                 PV              New        
 Min.   : 1.00   Length:12          Min.   : 43088   Min.   :  2064  
 1st Qu.: 3.75   Class :character   1st Qu.:116244   1st Qu.: 41438  
 Median : 6.50   Mode  :character   Median :174461   Median : 88342  
 Mean   : 6.50                      Mean   :192949   Mean   :122096  
 3rd Qu.: 9.25                      3rd Qu.:236802   3rd Qu.:115923  
 Max.   :12.00                      Max.   :506487   Max.   :430687  
  Average Time         FB             Pocket            Hatebu       
 Min.   : 58.0   Min.   : 15.00   Min.   :  25.00   Min.   :   4.00  
 1st Qu.:158.5   1st Qu.: 86.75   1st Qu.:  43.25   1st Qu.:   9.25  
 Median :198.0   Median :131.00   Median :  52.00   Median :  23.50  
 Mean   :206.6   Mean   :215.00   Mean   : 192.25   Mean   : 123.83  
 3rd Qu.:278.5   3rd Qu.:258.00   3rd Qu.:  84.00   3rd Qu.:  48.50  
 Max.   :311.0   Max.   :830.00   Max.   :1651.00   Max.   :1198.00


# 必要なカラムだけの要約統計量の表示
summary(data[,3:8])
       PV              New          Average Time         FB        
 Min.   : 43088   Min.   :  2064   Min.   : 58.0   Min.   : 15.00  
 1st Qu.:116244   1st Qu.: 41438   1st Qu.:158.5   1st Qu.: 86.75  
 Median :174461   Median : 88342   Median :198.0   Median :131.00  
 Mean   :192949   Mean   :122096   Mean   :206.6   Mean   :215.00  
 3rd Qu.:236802   3rd Qu.:115923   3rd Qu.:278.5   3rd Qu.:258.00  
 Max.   :506487   Max.   :430687   Max.   :311.0   Max.   :830.00  
     Pocket            Hatebu       
 Min.   :  25.00   Min.   :   4.00  
 1st Qu.:  43.25   1st Qu.:   9.25  
 Median :  52.00   Median :  23.50  
 Mean   : 192.25   Mean   : 123.83  
 3rd Qu.:  84.00   3rd Qu.:  48.50  
 Max.   :1651.00   Max.   :1198.00

Rでの行列指定方法は、以下のとおりです。

# cf. Rでの行列指定方法

# 一般形式
var[行指定, 列指定]

# 全行, 3-8列目だけ選択
var[, 3:8]

# 全行, 2列目だけ削除
var[, -2]

# 5行目, 1-2列目だけ選択
var[5, 1:2]

さらに、標準偏差など統計量を一括取得するパッケージを導入します。

# cf. psychパッケージdescribeコマンドで標準偏差など統計量を一括取得

install.packages("psych", dependencies = TRUE)
library(psych)
describe(data)

             vars  n      mean        sd   median  trimmed       mad   min
No              1 12      6.50      3.61      6.5      6.5      4.45     1
TITLE*          2 12       NaN        NA       NA      NaN        NA   Inf
PV              3 12 192949.17 130451.96 174461.0 176581.5 110918.50 43088
New             4 12 122096.00 136667.32  88341.5 103240.1  74921.71  2064
Average Time    5 12    206.58     78.37    198.0    211.0     83.77    58
FB              6 12    215.00    228.75    131.0    173.5    114.16    15
Pocket          7 12    192.25    460.32     52.0     63.1     22.98    25
Hatebu          8 12    123.83    338.92     23.5     28.4     26.69     4
                max  range  skew kurtosis       se
No               12     11  0.00    -1.50     1.04
TITLE*         -Inf   -Inf    NA       NA       NA
PV           506487 463399  0.95     0.20 37658.24
New          430687 428623  1.26     0.12 39452.46
Average Time    311    253 -0.21    -1.22    22.62
FB              830    815  1.57     1.57    66.03
Pocket         1651   1626  2.63     5.41   132.88
Hatebu         1198   1194  2.63     5.42    97.84

標準化

それでは、まず各データをscale()で標準化します。

# scaleコマンドを使う
data_st <- scale(data[,3:8])

# describe
library(psych)
head(data_st)

              PV        New Average Time         FB     Pocket     Hatebu
[1,] -0.29611028 -0.2616207   -0.2881790  0.2142092 -0.2873013 -0.3034187
[2,] -0.46077626 -0.1381603    0.4647019  1.0579310 -0.3481288 -0.2237529
[3,] -0.04722173  1.7715720   -0.5944357 -0.1092904 -0.3046806 -0.2886658
[4,] -0.96966090 -0.6698675   -0.9772565  0.1792362 -0.1895428 -0.2178517
[5,]  2.40347350  2.2579721    1.3324291  2.6885437  3.1690042  3.1694223
[6,]  0.84779740  0.2265209   -0.5433929 -0.6163978 -0.1482670 -0.1647411

describe(data_st)

             vars  n mean sd median trimmed  mad   min  max range  skew
PV              1 12    0  1  -0.14   -0.13 0.85 -1.15 2.40  3.55  0.95
New             2 12    0  1  -0.25   -0.14 0.55 -0.88 2.26  3.14  1.26
Average Time    3 12    0  1  -0.11    0.06 1.07 -1.90 1.33  3.23 -0.21
FB              4 12    0  1  -0.37   -0.18 0.50 -0.87 2.69  3.56  1.57
Pocket          5 12    0  1  -0.30   -0.28 0.05 -0.36 3.17  3.53  2.63
Hatebu          6 12    0  1  -0.30   -0.28 0.08 -0.35 3.17  3.52  2.63
             kurtosis   se
PV               0.20 0.29
New              0.12 0.29
Average Time    -1.22 0.29
FB               1.57 0.29
Pocket           5.41 0.29
Hatebu           5.42 0.29

上記を確認すると、きちんと 平均(mean):0 標準偏差(sd):1 に標準化されていることがわかります。

参考までに、行列情報の表示方法です。

# cf. 行列情報の表示

# 行列の行数だけ表示
> nrow(data_st)
[1] 12

# 行列の列数だけ表示
> ncol(data_st)
[1] 6

標準化による総合指標を作成

標準化された6つの指標を合成して総合指標にします。

まず、データフレームに変換します。

data_st_df <- data.frame(data_st)
describe(data_st_df)
             vars  n mean sd median trimmed  mad   min  max range  skew
PV              1 12    0  1  -0.14   -0.13 0.85 -1.15 2.40  3.55  0.95
New             2 12    0  1  -0.25   -0.14 0.55 -0.88 2.26  3.14  1.26
Average.Time    3 12    0  1  -0.11    0.06 1.07 -1.90 1.33  3.23 -0.21
FB              4 12    0  1  -0.37   -0.18 0.50 -0.87 2.69  3.56  1.57
Pocket          5 12    0  1  -0.30   -0.28 0.05 -0.36 3.17  3.53  2.63
Hatebu          6 12    0  1  -0.30   -0.28 0.08 -0.35 3.17  3.52  2.63
             kurtosis   se
PV               0.20 0.29
New              0.12 0.29
Average.Time    -1.22 0.29
FB               1.57 0.29
Pocket           5.41 0.29
Hatebu           5.42 0.29

そして、すべて同じ重み付けをする場合、項目の平均を掛け合わせて、scoreカラムに代入します。

data_st_df$score <- apply(data_st_df[,1:6], 1, mean)
describe(data_st_df)
             vars  n mean   sd median trimmed  mad   min  max range  skew
PV              1 12    0 1.00  -0.14   -0.13 0.85 -1.15 2.40  3.55  0.95
New             2 12    0 1.00  -0.25   -0.14 0.55 -0.88 2.26  3.14  1.26
Average.Time    3 12    0 1.00  -0.11    0.06 1.07 -1.90 1.33  3.23 -0.21
FB              4 12    0 1.00  -0.37   -0.18 0.50 -0.87 2.69  3.56  1.57
Pocket          5 12    0 1.00  -0.30   -0.28 0.05 -0.36 3.17  3.53  2.63
Hatebu          6 12    0 1.00  -0.30   -0.28 0.08 -0.35 3.17  3.52  2.63
score           7 12    0 0.84  -0.14   -0.17 0.25 -0.82 2.50  3.33  2.10
             kurtosis   se
PV               0.20 0.29
New              0.12 0.29
Average.Time    -1.22 0.29
FB               1.57 0.29
Pocket           5.41 0.29
Hatebu           5.42 0.29
score            3.78 0.24

cf. apply(x, y, z)の使い方です。

apply(x, y, z)引数
x: データセット名
y: 1 ... 列方向に各行を計算
y: 2 ... 行方向に各列を計算
z: mean平均 or sd標準偏差 or sum合計 or ...

cf. PVだけ重要視するなど、もしすべて同じ重み付けをせず、異なる重み付けをしたい場合は、各指標ごとに固定の値で割り算します。

総合指標を結合

実データと標準化したデータをcbind()で結合します。

data_score <- cbind(data, data_st_df)
str(data_score)

'data.frame':  12 obs. of  15 variables:
 $ No          : num  1 2 3 4 5 6 7 8 9 10 ...
 $ TITLE       : chr  "title1" "title2" "title3" "title4" ...
 $ PV          : num  154321 132840 186789 66455 506487 ...
 $ New         : num  86341 103214 364212 30547 430687 ...
 $ Average Time: num  184 243 160 130 311 164 277 212 303 283 ...
 $ FB          : num  264 457 190 256 830 74 114 91 15 36 ...
 $ Pocket      : num  60 32 52 105 1651 ...
 $ Hatebu      : num  21 48 26 50 1198 ...
 $ PV          : num  -0.2961 -0.4608 -0.0472 -0.9697 2.4035 ...
 $ New         : num  -0.262 -0.138 1.772 -0.67 2.258 ...
 $ Average.Time: num  -0.288 0.465 -0.594 -0.977 1.332 ...
 $ FB          : num  0.214 1.058 -0.109 0.179 2.689 ...
 $ Pocket      : num  -0.287 -0.348 -0.305 -0.19 3.169 ...
 $ Hatebu      : num  -0.303 -0.224 -0.289 -0.218 3.169 ...
 $ score       : num  -0.2037 0.0586 0.0712 -0.4742 2.5035 ...
 

head(data_score, 3)

  No  TITLE     PV    New Average Time  FB Pocket Hatebu          PV
1  1 title1 154321  86341          184 264     60     21 -0.29611028
2  2 title2 132840 103214          243 457     32     48 -0.46077626
3  3 title3 186789 364212          160 190     52     26 -0.04722173
         New Average.Time         FB     Pocket     Hatebu       score
1 -0.2616207   -0.2881790  0.2142092 -0.2873013 -0.3034187 -0.20373681
2 -0.1381603    0.4647019  1.0579310 -0.3481288 -0.2237529  0.05863578
3  1.7715720   -0.5944357 -0.1092904 -0.3046806 -0.2886658  0.07121298

少し整形して、見やすくします。

data_score <- cbind(data[,1:2], data_st_df$score)
colnames(data_score) <- c("No", "Title", "Score")
data_score

   No   Title        Score
1   1  title1 -0.203736806
2   2  title2  0.058635784
3   3  title3  0.071212976
4   4  title4 -0.474157196
5   5  title5  2.503474161
6   6  title6 -0.066413432
7   7  title7 -0.028503090
8   8  title8 -0.212493302
9   9  title9  0.009188198
10 10 title10 -0.207829963
11 11 title11 -0.627226978
12 12 title12 -0.822150352

cf. cbind() / rbind()

cbind() ... col bind 列方向のバインド
rbind() ... row bind 行方向のバインド

ランキングの作成

総合指標をランキング形式に変換します。

data_score$rank <- rank(data_score$Score)
data_score
   No   Title        Score rank
1   1  title1 -0.203736806    6
2   2  title2  0.058635784   10
3   3  title3  0.071212976   11
4   4  title4 -0.474157196    3
5   5  title5  2.503474161   12
6   6  title6 -0.066413432    7
7   7  title7 -0.028503090    8
8   8  title8 -0.212493302    4
9   9  title9  0.009188198    9
10 10 title10 -0.207829963    5
11 11 title11 -0.627226978    2
12 12 title12 -0.822150352    1


# ランクづけを大きいものほど小さくする降順に変更
data_score$rank <- rank(-data_score$Score)
data_score
   No   Title        Score rank
1   1  title1 -0.203736806    7
2   2  title2  0.058635784    3
3   3  title3  0.071212976    2
4   4  title4 -0.474157196   10
5   5  title5  2.503474161    1
6   6  title6 -0.066413432    6
7   7  title7 -0.028503090    5
8   8  title8 -0.212493302    9
9   9  title9  0.009188198    4
10 10 title10 -0.207829963    8
11 11 title11 -0.627226978   11
12 12 title12 -0.822150352   12

# ランクづけした後に、ランク昇順で表示
result <- data_score[order(data_score$rank), ]
result
   No   Title        Score rank
5   5  title5  2.503474161    1
3   3  title3  0.071212976    2
2   2  title2  0.058635784    3
9   9  title9  0.009188198    4
7   7  title7 -0.028503090    5
6   6  title6 -0.066413432    6
1   1  title1 -0.203736806    7
10 10 title10 -0.207829963    8
8   8  title8 -0.212493302    9
4   4  title4 -0.474157196   10
11 11 title11 -0.627226978   11
12 12 title12 -0.822150352   12

以上、

Web記事の総合ランキングを作る方法をご紹介しました。

発展

各項目ごとに重み付けする値を変更したり、

さまざまな項目の組み合わせで総合ランキングを作成したりできます。

JupyterNotebookで対話的インターフェイスipywidgetsを使う方法

概要

JupyterNotebookは、セル単位でプログラムを実行できるインターフェイスがあります。

ただ、変数の値を少し変更したり、

設定条件を変えたい場合は、

セルの中身のプログラムを変更する必要があります。

もう少し、マウス操作や、直感的に数値変更できるようにするためには、

対話的インターフェイスipywidgetsエクステンションを導入することで、

Webフォームのように、インタラクティブウィジェットを導入することができます。

導入

インストール(conda)

conda環境がある場合、

以下のコマンドラインipywidgetsを導入できます。

$ conda --version
conda 4.6.4

$ conda install -c conda-forge ipywidgets==6.0.0

インストール(pip)

pipの場合、jupyterコマンドでextensionを有効化します。

$ pip --version
pip 18.1

$ pip install ipywidgets
$ jupyter nbextension enable --py widgetsnbextension

使用例

引数に整数値を与えてスライダを実装

引数に整数値を与えてスライダを表示する例です。

from ipywidgets import interact

@interact(i=1)
def f(i):
  return i*1024

さまざまなインターフェイス

スライダー以外に、テキストフォームやセレクトボックスやチェックボックスの事例です

@interact(i=1, f=0.1, s='text', l=['a','b'], is_checked=True)
def f(i, f, s, l, is_checked):
  return i, f, s, l, is_checked

住宅ローンの返済シミュレータ

明示的にクラス指定することで、スライダを呼び出すこともできます。

以下の事例は、住宅ローンの返済シミュレータです。

from ipywidgets import IntSlider, FloatSlider
import numpy as np

rate_slider = FloatSlider(min=1, max=5, step=0.1, value=2, description='金利')
nper_slider = IntSlider(min=1, max=35, step=1, value=20, description='返済期間')
pv_slider = IntSlider(
  min=5000000,
  max=50000000,
  step=1000000,
  value=20000000,
  description='返済金額')

@interact(rate=rate_slider, nper=nper_slider, pv=pv_slider)
def pmt(rate, nper, pv):
  rate = rate * 0.01 / 12
  nper = nper * 12
  payment = abs(int(np.pmt(rate, nper, pv)))
  print('月々の返済額: {:,d} 円'.format(payment))
  print('返済総額: {:,d} 円'.format(payment * nper))

ボタン押下時処理(イベントハンドリング)

ボタンウィジェット操作時の動作を設定する方法です。

from ipywidgets import Button
from IPython.display import display, clear_output
from datetime import datetime

def on_button_clicked(b):
  clear_output() # すでにある出力を削除
  print('{:%H時%M分%S秒}です'.format(datetime.now()))

b = Button(description='いま何時?')
b.on_click(on_button_clicked)
display(b)

使用可能なウィジェット一覧

以下コマンドでウィジェット一覧を確認できます。

from ipywidgets import Widget
from pprint import pprint

pprint(Widget.widget_types)

以下に実例が列挙されています。

https://ipywidgets.readthedocs.io/en/stable/examples/Widget%20List.html

ウィジェットのレイアウト変更

ウィジェットのレイアウトを変えたい場合は、以下設定で変更できます。

from ipywidgets import HBox, VBox, Text, Dropdown

# HBox: 横並びに整列
# VBox: タテ並びに整列
# Accordion: アコーディオン表示
# Tabs: タブ表示

w1 = Text(value='Text')
w2 = Button(description='Button')
w3 = Dropdown(options=['1', '2'])
w4 = IntSlider()

VBox([ HBox([w1, w2]), HBox([w3, w4]) ])

可視化ツールとの連携

Matplotlibとの連携

ipywidgetsとMatplotlibなどの可視化ツールを連携する方法があり、

以下のようにドロップダウンで選択した値から棒グラフを出力する方法があります。

import os
import pandas as pd
import matplotlib.pyplot as plt

anime_genre_top10_csv = os.path.join('./anime_genre_top10.csv')
top10_df = pd.read_csv(anime_genre_top10_csv)

def plot_genre_members(b):
  clear_output()
  filter_by_type = top10_df.loc[top10_df['type'] == types.value]
  plot_data = filter_by_type.groupby('genre').sum()['members']
  ax = plot_data.plot.bar()
  ax.set_title(types.value)
  plt.show()

types = Dropdown(options=list(top10_df['type'].unique()))
submit_button = Button(description='グラフを表示')
submit_button.on_click(plot_genre_members)

HBox([types, submit_button])

Bokehとの連携

インタラクティブに操作できるBokehとも連携できます。

以下、連携したデータのプロットを表示/非表示切り替えたり、

画面上で操作できるようになります。

from bokeh.plotting import figure
from bokeh.io import output_notebook, push_notebook, show
from bokeh.palettes import d3
from IPython.display import display
from ipywidgets import ColorPicker, Checkbox, Tab

# 散布図を描画
def plot_scatter(_type):
    data = df.loc[df["type"] == _type, ["members", "rating"]]
    return p.circle(
        data["members"],
        data["rating"],
        legend=_type,
        color=colors[_type],
        line_color=None,
    )


# 図形の色を変更
def change_color(change):
    if change["new"]:
        description = change["owner"].description
        _type = description.split()[0]
        r[_type].glyph.fill_color = change["new"]
        push_notebook(handle=t)


# 図形の不透明度を変更
def change_alpha(change):
    if change["new"]:
        description = change["owner"].description
        _type = description.split()[0]
        r[_type].glyph.fill_alpha = change["new"]
        push_notebook(handle=t)


# 図形の表示 ・ 非表示の切り替え
def change_visible(change):
    description = change["owner"].description
    _type = description.split()[0]
    r[_type].visible = change["new"]
    push_notebook(handle=t)


# サンプルデータの取得
df = pd.read_csv(os.path.join("./anime_master.csv"))
types = sorted(set(df["type"]))  # ユニークなtype列
colors = dict(zip(types, d3["Category10"][6]))  # 配色
# グラフの描画
p = figure(plot_width=400, plot_height=400)
r = dict(zip(types, [plot_scatter(x) for x in types]))
p.legend.location = "bottom_right"
# カラーピッカ
color_picker = [ColorPicker(description=" ".join((x, "color:"))) for x in types]
# フロートスライダ
float_slider = [
    FloatSlider(description=" ".join((x, "alpha:")), min=0, max=1, value=1)
    for x in types
]
# チェックボックス
check_box = [Checkbox(description=" ".join((x, "visible:")), value=True) for x in types]
# イベントのハンドリング
for i, x in enumerate(types):
    color_picker[i].observe(change_color, names="value")
    float_slider[i].observe(change_alpha, names="value")
    check_box[i].observe(change_visible, names="value")
titles = dict(zip(range(len(types)), types))  # タブのタイトル
# タブに登録するウィジェット
children = [
    HBox([cp, fs, cb]) for cp, fs, cb in zip(color_picker, float_slider, check_box)
]
display(Tab(children=children, _titles=titles))
output_notebook()
t = show(p, notebook_handle=True)

以上、

JupyterNotebookで対話的インターフェイスipywidgetsを使う方法でした。

JupyterNotebookでRを使う方法

概要

データ分析など、ブラウザ上で対話的にPythonコマンドを実行できる、

Jupyter Notebookでは、R言語Rubyといった他の言語のカーネル

インストールすることで、他言語も使うことができます。

以下導入方法です。

Rカーネルの導入

パッケージインストール

R StudioなどRコンソールで

以下コマンドを実行して

Rカーネルをインストールします。

install.packages('devtools')
devtools::install_github('IRkernel/IRkernel')
IRkernel::installspec()

RのNotebook作成

Jupyter Notebookを起動します。

Notebookを新規作成するとき、

メニューにRが出てきますので、

クリックすれば、

R言語が書けるNotebookが作成されます。

記述例

以下のように、通常のRを記述すれば、実行結果が表示されます。

以上、JupyterNotebookでRを使う方法でした。

RによるRFM分析

概要

RによるRFM分析をご紹介します。

RFM分析 とは、顧客を以下の3つの側面から分析する手法です。

  • R(Recency, 最近購買しているかどうか, 購買日付)
  • F(Frequency, 頻繁に購買しているかどうか, 購買頻度)
  • M(Monetary, 高額に購買しているかどうか, 購買金額)

まず、最近、頻繁に、高額商品を購入していれば、優良顧客と言えます。

逆に、最近購入していない、または、頻繁に購入していない、または、高額に購入していない、

のいずれか、またはその組み合わせの場合は、優良顧客とは言えず、

改善していく施策を打つ必要があります。

準備

データ

まず、以下のような売上データを準備します。

# 顧客ID,売上金額,日付
custID,sales,date
1289,2599,2012/1/1
1925,110,2012/1/1
1498,75,2012/1/1

実装

まず、売上データを読み込みます。

rfmdata <- read.csv("~/Downloads/idposdata.csv", header = T)
str(rfmdata)

'data.frame':  10000 obs. of  3 variables:
 $ custID: int  1289 1925 1498 1535 1886 1773 1422 1219 1215 1500 ...
 $ sales : int  2599 110 75 99 2485 3828 191 3901 266 58 ...
 $ date  : Factor w/ 360 levels "2012/1/1","2012/1/10",..: 1 1 1 1 1 1 1 1 1 1 ...
 

summary(rfmdata)

     custID         sales                date     
 Min.   :1000   Min.   :   1.0   2012/4/16 :  42  
 1st Qu.:1251   1st Qu.:  66.0   2012/11/17:  41  
 Median :1498   Median : 197.0   2012/7/15 :  41  
 Mean   :1498   Mean   : 610.8   2012/10/17:  40  
 3rd Qu.:1749   3rd Qu.: 587.0   2012/8/12 :  40  
 Max.   :1999   Max.   :9998.0   2012/8/17 :  40  
                                 (Other)   :9756

まず、Recencyを算出するため、datediff列に新しく基準日と購買日の差分日数を格納します。

rfmdata$datediff<- round(as.numeric(difftime("2013-01-01",rfmdata$date,units="days")))
str(rfmdata)

'data.frame':  10000 obs. of  4 variables:
 $ custID  : int  1289 1925 1498 1535 1886 1773 1422 1219 1215 1500 ...
 $ sales   : int  2599 110 75 99 2485 3828 191 3901 266 58 ...
 $ date    : Factor w/ 360 levels "2012/1/1","2012/1/10",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ datediff: num  366 366 366 366 366 366 366 366 366 366 ...

cf. もし基準日を"2013-01-01"ではなく、実行日を基準にする場合は、Sys.Date() に置き換えます。

Sys.Date()
[1] "2019-02-17"

差分日数を算出したら、Recencyを計算します。

Recency <- aggregate(rfmdata$datediff,list(rfmdata$custID),min)
names(Recency) <- c("custID","Recency")
str(Recency)

'data.frame':  1000 obs. of  2 variables:
 $ custID : int  1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ...
 $ Recency: num  13 8 74 26 33 20 9 33 9 16 ...

次に、顧客IDをキーにして、購買頻度Frequencyを集計します。

Frequency <- aggregate(rfmdata$sales,list(rfmdata$custID),length)
names(Frequency) <- c("custID","Frequency")
str(Frequency)

'data.frame':  1000 obs. of  2 variables:
 $ custID   : int  1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ...
 $ Frequency: int  9 11 6 8 10 14 15 5 15 14 ...

そして、購買金額Monetaryも算出します。

Monetary <- aggregate(rfmdata$sales,list(rfmdata$custID),sum)
names(Monetary) <- c("custID","Monetary")
str(Monetary)

'data.frame':  1000 obs. of  2 variables:
 $ custID  : int  1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ...
 $ Monetary: int  1177 6364 6995 2909 11470 9235 6312 1814 4930 10560 ...

最後に、各変数を結合します。

temp <- merge(Frequency,Monetary,"custID")
customerRFM <- merge(temp,Recency,"custID")
str(customerRFM)

'data.frame':  1000 obs. of  4 variables:
 $ custID   : int  1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ...
 $ Frequency: int  9 11 6 8 10 14 15 5 15 14 ...
 $ Monetary : int  1177 6364 6995 2909 11470 9235 6312 1814 4930 10560 ...
 $ Recency  : num  13 8 74 26 33 20 9 33 9 16 ...

各RFMデータが集計されましたので、それぞれランクづけを5段階にしてみます。

customerRFM$rankR <- cut(customerRFM$Recency,quantile(customerRFM$Recency,(0:5)/5,na.rm=TRUE),label=FALSE,include.lowest=TRUE)
customerRFM$rankF <- cut(customerRFM$Frequency,quantile(customerRFM$Frequency,(0:5)/5,na.rm=TRUE),label=FALSE,include.lowest=TRUE)
customerRFM$rankM <- cut(customerRFM$Monetary,quantile(customerRFM$Monetary,(0:5)/5,na.rm=TRUE),label=FALSE,include.lowest=TRUE)

なお、Recencyだけは、小さい方が良いので、反転しておきます。

customerRFM$rankR <- 6-customerRFM$rankR

ランクづけしたデータを参照します。

str(customerRFM)
'data.frame':  1000 obs. of  7 variables:
 $ custID   : int  1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ...
 $ Frequency: int  9 11 6 8 10 14 15 5 15 14 ...
 $ Monetary : int  1177 6364 6995 2909 11470 9235 6312 1814 4930 10560 ...
 $ Recency  : num  13 8 74 26 33 20 9 33 9 16 ...
 $ rankR    : num  5 5 1 3 3 4 5 3 5 4 ...
 $ rankF    : int  2 3 1 2 3 5 5 1 5 5 ...
 $ rankM    : int  1 4 4 2 5 5 4 1 3 5 ...

ランクづけしたデータを表形式で参照します。

// 5列目rankR, 6列目rankFの組み合わせ
table(customerRFM[,5:6])

     rankF
rankR  1  2  3  4  5
    1 78 59 34 21  7
    2 47 57 41 28 25
    3 35 42 57 32 26
    4 31 55 41 38 43
    5 24 41 55 44 39

// 6列目rankF, 7列目rankMの組み合わせ
table(customerRFM[,6:7])
     rankM
rankF  1  2  3  4  5
    1 99 46 29 25 16
    2 64 66 56 42 26
    3 28 58 42 57 43
    4  8 24 44 43 44
    5  1  6 29 33 71

// 各rankMと、他のrankR/rankFとの組み合わせ
table(customerRFM[,5:7])
, , rankM = 1

     rankF
rankR  1  2  3  4  5
    1 43 11  3  0  0
    2 23 17  6  3  0
    3 17 13  8  1  0
    4 10 12  3  3  0
    5  6 11  8  1  1

, , rankM = 2

     rankF
rankR  1  2  3  4  5
    1 15 17  8  2  0
    2  9 17  6  4  2
    3  8 12 13  6  0
    4  4 13 10  3  1
    5 10  7 21  9  3

, , rankM = 3

     rankF
rankR  1  2  3  4  5
    1  8 15  7  7  2
    2  4 12  8  6  8
    3  4  7 10 11  5
    4 10 11  7  8  7
    5  3 11 10 12  7

, , rankM = 4

     rankF
rankR  1  2  3  4  5
    1  8 10  7  6  1
    2  5  6 12  8  2
    3  4  8 17  5  9
    4  5 13 13 14 11
    5  3  5  8 10 10

, , rankM = 5

     rankF
rankR  1  2  3  4  5
    1  4  6  9  6  4
    2  6  5  9  7 13
    3  2  2  9  9 12
    4  2  6  8 10 24
    5  2  7  8 12 18

最後に、高いランクだけファイルに出力する場合は以下のようにきじゅつします

subset(customerRFM, customerRFM$rankM==5 & customerRFM$rankF==5 & customerRFM$rankR==5)
RFMgoodcustomers <- subset(customerRFM, customerRFM$rankM==5 & customerRFM$rankF==5 & customerRFM$rankR==5)
write.csv(RFMgoodcustomers, "~/Downloads/RFMgoodcustomers.csv", quote=F, row.names=F)

以上、RによるRFM分析でした。

Rによるデシル分析

概要

Rによるデシル分析についてご紹介します。

デシル分析とは、売上など特定の数値で顧客データを並び替えたあとに、10等分する分析です。

上位に集中する特徴を捉えて、次の施策を考案するために活用します。

準備

データ

まず、1カスタマー1データで売上データを準備します。

customerId,sales_amount
1289,2599
1925,110
1498,75
...

実装

さっそくデシル分析をしていきます。

まず、上記で準備した売上データを読み込みます。

sales_data = read.csv("~/Downloads/decile.csv", header = T)

つぎに、str()でデータ構造を確認します。

str(sales_data)

'data.frame':  10000 obs. of  2 variables:
 $ customerId  : int  1289 1925 1498 1535 1886 1773 1422 1219 1215 1500 ...
 $ sales_amount: int  2599 110 75 99 2485 3828 191 3901 266 58 ...

また、summary()で基礎統計量も確認します。

summary(sales_data)

   customerId    sales_amount   
 Min.   :1000   Min.   :   1.0  
 1st Qu.:1251   1st Qu.:  66.0  
 Median :1498   Median : 197.0  
 Mean   :1498   Mean   : 610.8  
 3rd Qu.:1749   3rd Qu.: 587.0  
 Max.   :1999   Max.   :9998.0

そして、売上のヒストグラムを表示します。

hist(sales_data$sales)

基礎データの概略を把握した後、さっそく顧客IDごとの売上集計をして、結果を確認します。

sales_data_sum <- aggregate(sales_data$sales_amount,list(sales_data$customerId),sum)
str(sales_data_sum)
'data.frame':  1000 obs. of  2 variables:
 $ Group.1: int  1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ...
 $ x      : int  1177 6364 6995 2909 11470 9235 6312 1814 4930 10560 ...

列名を付け直して、わかりやすくします。

names(sales_data_sum) <- c("customerId","Monetary")
str(sales_data_sum)
'data.frame':  1000 obs. of  2 variables:
 $ customerId: int  1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ...
 $ Monetary  : int  1177 6364 6995 2909 11470 9235 6312 1814 4930 10560 ...

ヒストグラムで表示確認します。

hist(sales_data_sum$Monetary)

さて、つぎは、

顧客IDごとに売上集計がとれたので、顧客を10等分してランク名を付けます。

quantile()で指定分位数に分割し、cut()で量的変数を質的変数に変換します。

各顧客IDごとに、decile_rankが付与されています。

sales_data_sum$decile_rank <- cut(sales_data_sum$Monetary,quantile(sales_data_sum$Monetary,(0:10)/10,na.rm=TRUE),label=FALSE,include.lowest=TRUE)

str(sales_data_sum)
'data.frame':  1000 obs. of  3 variables:
 $ customerId : int  1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 ...
 $ Monetary   : int  1177 6364 6995 2909 11470 9235 6312 1814 4930 10560 ...
 $ decile_rank: int  1 7 7 3 9 9 7 2 5 9 ...

cf. (0:10)/10 は、0.1刻みで0から1まで生成する記法です。

res = (0:10)/10
> res
 [1] 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0

ランクづけができたら、それぞれのランクごとに集計します。

decile <- aggregate(sales_data_sum$Monetary,list(sales_data_sum$decile_rank),sum) 
names(decile) <- c("decile_rank","Monetary")
str(decile)
'data.frame':  10 obs. of  2 variables:
 $ decile_rank: int  1 2 3 4 5 6 7 8 9 10
 $ Monetary   : int  114950 211066 288829 373596 467780 566464 687162 830994 1031740 1535566

デシルランクごとに売上比率を算出します。

total <- sum(decile$Monetary)
percent <- decile$Monetary / total * 100
decile2 <- cbind(decile, percent)
decile3 <- decile2[order(-decile2$decile_rank),]
str(decile3)

'data.frame':  10 obs. of  3 variables:
 $ decile_rank: int  10 9 8 7 6 5 4 3 2 1
 $ Monetary   : int  1535566 1031740 830994 687162 566464 467780 373596 288829 211066 114950
 $ percent    : num  25.14 16.89 13.6 11.25 9.27 ...

もし、上位金額のデータだけを活用したい場合は、以下のように抽出し、CSVファイルに出力して活用できます。

subset(sales_data_sum, sales_data_sum$decile_rank==10)
decile_top_customers <- subset(sales_data_sum, sales_data_sum$decile_rank==10)
write.csv(decile_top_customers, "~/Downloads/decile_top_customers.csv", quote=F, row.names=F)

以上、Rによるデシル分析をご紹介しました。

Rによる共分散・相関係数・ファイ係数の算出

概要

Rによる共分散・相関係数・ファイ係数の算出方法をご紹介します。

関数

2つの異なるデータ群の共分散を cov() で算出できます。

ただし、単位に依存するので、例えば、身長がm単位なのかcm単位なのかで共分散の値が異なります。

cov() : 共分散

共分散: 偏差の積の平均
デメリット: 単位に依存する
> h1 <- c(1.5, 1.6, 1.7, 1.8, 1.9) # 身長(m)
> h1
[1] 1.5 1.6 1.7 1.8 1.9
> 
> h2 <- h1*100 # 身長(cm)
> h2
[1] 150 160 170 180 190
> 
> w <- c(50, 60, 70, 80, 90) # 体重(kg)
> w
[1] 50 60 70 80 90
> 
> cov(h1, w)
[1] 2.5
> 
> cov(h2, w)
[1] 250

cor() : 相関係数

x, y の共分散を、それぞれのx, y の標準偏差の積で割った値が相関係数です。

メリットとして、単位に依存しないので、任意のデータ群の相関が統一的に算出できます。

また、

100%正の相関のときは1

100%負の相関のときは-1

無相関のときは0

となります。

相関係数r : cov(x,y) / ( sd(x) * sd(y) )
メリット: 単位に依存しない
-1 <= r <= 1
> h1 <- c(1.5, 1.6, 1.7, 1.8, 1.9) # 身長(m)
> h1
[1] 1.5 1.6 1.7 1.8 1.9
> 
> h2 <- h1*100 # 身長(cm)
> h2
[1] 150 160 170 180 190
> 
> w <- c(50, 60, 70, 80, 90) # 体重(kg)
> w
[1] 50 60 70 80 90
> 
> cor(h1, w)
[1] 1
> 
> cor(h2, w)
[1] 1

> z <- c(90, 80, 70, 60, 50)
> z
[1] 90 80 70 60 50
> cor(z,w)
[1] -1

> p <- c(100, 2, 400, 8, 5)
> cor(p, w)
[1] -0.1700732

table(x, y) クロス集計表

複数のデータ群を集計したクロス集計表は、table()を使って整理します。

> x <- c("a", "b", "a", "a", "b", "a", "b", "a", "a", "a", "a", "a", "b", "a", "a", "b", "a")
> table(x)
x
 a  b 
12  5 
> 
> y <- c("b", "b", "a", "b", "a", "a", "a", "b", "a", "a", "b", "a", "b", "b", "a", "a", "a")
> table(y)
y
 a  b 
10  7 
> 
> table(x, y)
   y
x   a b
  a 7 5
  b 3 2

ファイ係数

カテゴリカルデータの相関係数を算出したい場合は、以下のようにダミー変数に変換した値の相関係数をとります。

これをファイ係数と呼びます。

ファイ係数: 1 or 0 の値からなる変数(2値変数)の相関係数

ifelse(Condition, True, False)

IF分岐させたい場合は、ifelse()を使います。

> x <- c("a", "b", "a", "a", "b", "a", "b", "a", "a", "a", "a", "a", "b", "a", "a", "b", "a")
> x
 [1] "a" "b" "a" "a" "b" "a" "b" "a" "a" "a" "a" "a" "b" "a" "a" "b"
[17] "a"
> x_bi <- ifelse(x=="a", 1, 0)
> x_bi
 [1] 1 0 1 1 0 1 0 1 1 1 1 1 0 1 1 0 1
> y <- c("b", "b", "a", "b", "a", "a", "a", "b", "a", "a", "b", "a", "b", "b", "a", "a", "a")
> y_bi <- ifelse(y=="a", 1, 0)
> y_bi
 [1] 0 0 1 0 1 1 1 0 1 1 0 1 0 0 1 1 1
> cor(x_bi, y_bi)
[1] -0.01543033
> cor(x_bi, x_bi)
[1] 1
> cor(x_bi, ifelse(x_bi==1, 0, 1))
[1] -1

以上です。

Rによる分散・標準偏差・Z得点・偏差値の算出

概要

Rによる分散・標準偏差・Z得点・偏差値の算出方法をご紹介します。

関数

var(): 不偏分散

不偏分散を算出するには、var()を使います。

x <- c(10, 13, 8, 15, 8)
x
# [1] 10 13  8 15  8

# 不偏分散
var(x)
# [1] 9.7

sd(): 標準偏差

標準偏差を算出するには、sd() を使います。 もしくは、sqrt(var(x)) で分散の平方根をとります。

x <- c(10, 13, 8, 15, 8)
x
# [1] 10 13  8 15  8

# 標準偏差(不偏分散)
> sd(x)
[1] 3.114482

# OR

> sqrt(var(x))
[1] 3.114482

varp() // 標本分散 独自関数

不偏分散ではなく、標本分散を算出したい場合は、以下のような独自関数を作成します。

自由度を n ではなく n-1 に置き換える必要があります。

# 標本分散を算出する関数
varp <- function(x) {
  ret <- var(x) * ( length(x) - 1 ) / length(x)
  ret
}

x <- c(10, 13, 8, 15, 8)
x
# [1] 10 13  8 15  8

# 標本分散
varp(x)
# [1] 7.76

# 標準偏差(標本分散)
> sqrt(varp(x))
[1] 2.785678

score(): 標準化によるZ得点

Z得点(z値、z-score、z-value)とは、

平均が0

標準偏差が1

になるように変換した得点のことを指し、

(値 - 平均) / 標準偏差 で算出できます。

また、偏差値とは、

平均が50

標準偏差が10

になるように変換した値であり、

z得点 * 10 + 50 で算出できます。

z得点 = (値 - 平均) / 標準偏差
平均(z得点) = 0
標準偏差(z得点) = 1

偏差値 = z得点 * 10 + 50
平均(偏差値) = 50
標準偏差(偏差値) = 10

scale() を使えば、標準化できます。

> num <- sample(20)
> num
 [1]  6  8 17 18 19  2 11  1 20  5 15  3 16 12  9 14  7 13  4 10
> z_score <- scale(num)
> z_score
             [,1]
 [1,] -0.76063883
 [2,] -0.42257713
 [3,]  1.09870053
 [4,]  1.26773138
 [5,]  1.43676223
 [6,] -1.43676223
 [7,]  0.08451543
 [8,] -1.60579308
 [9,]  1.60579308
[10,] -0.92966968
[11,]  0.76063883
[12,] -1.26773138
[13,]  0.92966968
[14,]  0.25354628
[15,] -0.25354628
[16,]  0.59160798
[17,] -0.59160798
[18,]  0.42257713
[19,] -1.09870053
[20,] -0.08451543
attr(,"scaled:center")
[1] 10.5
attr(,"scaled:scale")
[1] 5.91608

> mean(z_score)
[1] 0

> sd(z_score)
[1] 1

# 偏差値 = z得点 * 10 + 50
# 平均(偏差値) = 50
# 標準偏差(偏差値) = 10
> standard_score = z_score * 10 + 50
> standard_score
          [,1]
 [1,] 42.39361
 [2,] 45.77423
 [3,] 60.98701
 [4,] 62.67731
 [5,] 64.36762
 [6,] 35.63238
 [7,] 50.84515
 [8,] 33.94207
 [9,] 66.05793
[10,] 40.70330
[11,] 57.60639
[12,] 37.32269
[13,] 59.29670
[14,] 52.53546
[15,] 47.46454
[16,] 55.91608
[17,] 44.08392
[18,] 54.22577
[19,] 39.01299
[20,] 49.15485
attr(,"scaled:center")
[1] 10.5
attr(,"scaled:scale")
[1] 5.91608

> mean(standard_score)
[1] 50
> sd(standard_score)
[1] 10

以上です。

Rによるバスケット分析まとめ

概要

Rによるバスケット分析方法をまとめました。

Rのバスケット分析パッケージを使えば、

すぐに詳細なバスケット分析ができます。

書籍『リテールデータ分析入門』のデータを使って、実際に分析してみます。

準備

データの準備

まず、商品カテゴリ(例:おにぎり、お茶など)一覧を定義します。

Cate1,Cate2,Cate3,...
おにぎり,お茶,弁当,...

以後、

つぎに、実際の購買データを準備します。

レシート番号,購買商品
1,おにぎり&お茶
2,お茶&弁当
3,弁当
4,...

このままでは、Rで処理しづらいので、以下のように、 各カテゴリが

購入されていれば 1

購入されていなければ 0

とダミー変数に変換しておきます。

ReceiptNo,Cate1,Cate2,Cate3,Cate4,Cate5,Cate6,Cate7,Cate8,Cate9,Cate10
1,0,0,1,1,0,0,1,0,0,0
2,1,0,0,0,0,0,1,0,0,0
3,0,1,0,0,1,0,1,0,0,0
...

cf.ダミー変数への変換方法は、別途記事にします。

Rパッケージの準備

Rパッケージのarulesをインストールします。 https://www.rdocumentation.org/packages/arules/versions/1.6-2

install.packages("arules")

バスケット分析の実施

パッケージを読み込みます。

library("arules")

上記で準備しておいたダミー変数のcsvファイルを読み込みます。

data_set <- read.csv("~/Downloads/Receipt1000.csv", header = T, row.names = 1)
// 引数の説明:
// header 有り: header = T
// header 無し: header = F
// 1列目を行名として使う場合: row.names = 1
// 1列目を行名として使う場合: row.names削除

行列形式に変換します

data_set_matrix = as(data_set, "matrix")

バスケット分析を実行しルールを生成します

rules <- apriori(data_set_matrix, parameter = list(supp = 0.06, conf = 0.2, maxlen = 2))
// 引数の説明:
// supp: support値下限を指定
// conf: confidence値下限を指定
// maxlen: 条件部個数の最大値を指定

ルールの概要を確認します

summary(rules)
set of 36 rules

rule length distribution (lhs + rhs):sizes
 1  2 
 7 29 

   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
  1.000   2.000   2.000   1.806   2.000   2.000 

summary of quality measures:
    support          confidence          lift           count       
 Min.   :0.06300   Min.   :0.2030   Min.   :0.760   Min.   : 63.00  
 1st Qu.:0.08075   1st Qu.:0.2593   1st Qu.:1.000   1st Qu.: 80.75  
 Median :0.09900   Median :0.3676   Median :1.083   Median : 99.00  
 Mean   :0.13458   Mean   :0.3610   Mean   :1.131   Mean   :134.58  
 3rd Qu.:0.14850   3rd Qu.:0.4316   3rd Qu.:1.231   3rd Qu.:148.50  
 Max.   :0.43800   Max.   :0.6201   Max.   :1.742   Max.   :438.00  

mining info:
         data ntransactions support confidence
rules          1000    0.06        0.2

生成されたルール先頭行を表示します

// 引数の説明:
// by: ソート項目を指定(supp=support, conf=confidence, lift)

// 表の説明:
// lhs: 条件部 空の場合は、各カテゴリの購買確率
// rhs: 結論部

> inspect(head(rules, by = "supp"))
    lhs    rhs     support confidence lift count
[1] {}  => {Cate1} 0.438   0.438      1    438  
[2] {}  => {Cate2} 0.391   0.391      1    391  
[3] {}  => {Cate3} 0.263   0.263      1    263  
[4] {}  => {Cate4} 0.229   0.229      1    229  
[5] {}  => {Cate8} 0.212   0.212      1    212  
[6] {}  => {Cate7} 0.205   0.205      1    205  

> inspect(head(rules, by = "conf"))
    lhs         rhs     support confidence lift     count
[1] {Cate4}  => {Cate1} 0.142   0.6200873  1.415725 142  
[2] {Cate10} => {Cate1} 0.080   0.5925926  1.352951  80  
[3] {Cate9}  => {Cate1} 0.103   0.5786517  1.321123 103  
[4] {Cate3}  => {Cate1} 0.140   0.5323194  1.215341 140  
[5] {Cate5}  => {Cate1} 0.099   0.4876847  1.113435  99  
[6] {Cate6}  => {Cate1} 0.085   0.4696133  1.072176  85

> inspect(head(rules, by = "lift"))
    lhs         rhs     support confidence lift     count
[1] {Cate9}  => {Cate4} 0.071   0.3988764  1.741818  71  
[2] {Cate4}  => {Cate9} 0.071   0.3100437  1.741818  71  
[3] {Cate4}  => {Cate1} 0.142   0.6200873  1.415725 142  
[4] {Cate1}  => {Cate4} 0.142   0.3242009  1.415725 142  
[5] {Cate10} => {Cate1} 0.080   0.5925926  1.352951  80  
[6] {Cate9}  => {Cate1} 0.103   0.5786517  1.321123 103 

ルール全体を表示します

inspect(sort(rules, by="supp"))
// 引数の説明:
// by: ソート項目を指定(supp=support, conf=confidence, lift)
     lhs         rhs     support confidence lift      count
[1]  {}       => {Cate1} 0.438   0.4380000  1.0000000 438  
[2]  {}       => {Cate2} 0.391   0.3910000  1.0000000 391  
[3]  {}       => {Cate3} 0.263   0.2630000  1.0000000 263  
[4]  {}       => {Cate4} 0.229   0.2290000  1.0000000 229  
[5]  {}       => {Cate8} 0.212   0.2120000  1.0000000 212  
[6]  {}       => {Cate7} 0.205   0.2050000  1.0000000 205  
[7]  {}       => {Cate5} 0.203   0.2030000  1.0000000 203  
[8]  {Cate2}  => {Cate1} 0.168   0.4296675  0.9809761 168  
[9]  {Cate1}  => {Cate2} 0.168   0.3835616  0.9809761 168  
[10] {Cate4}  => {Cate1} 0.142   0.6200873  1.4157245 142  
[11] {Cate1}  => {Cate4} 0.142   0.3242009  1.4157245 142  
[12] {Cate3}  => {Cate1} 0.140   0.5323194  1.2153411 140  
[13] {Cate1}  => {Cate3} 0.140   0.3196347  1.2153411 140  
[14] {Cate3}  => {Cate2} 0.115   0.4372624  1.1183180 115  
[15] {Cate2}  => {Cate3} 0.115   0.2941176  1.1183180 115  
[16] {Cate9}  => {Cate1} 0.103   0.5786517  1.3211226 103  
[17] {Cate1}  => {Cate9} 0.103   0.2351598  1.3211226 103  
[18] {Cate5}  => {Cate1} 0.099   0.4876847  1.1134355  99  
[19] {Cate1}  => {Cate5} 0.099   0.2260274  1.1134355  99  
[20] {Cate4}  => {Cate2} 0.097   0.4235808  1.0833268  97  
[21] {Cate2}  => {Cate4} 0.097   0.2480818  1.0833268  97  
[22] {Cate7}  => {Cate1} 0.094   0.4585366  1.0468872  94  
[23] {Cate1}  => {Cate7} 0.094   0.2146119  1.0468872  94  
[24] {Cate5}  => {Cate2} 0.087   0.4285714  1.0960906  87  
[25] {Cate2}  => {Cate5} 0.087   0.2225064  1.0960906  87  
[26] {Cate6}  => {Cate1} 0.085   0.4696133  1.0721764  85  
[27] {Cate8}  => {Cate1} 0.081   0.3820755  0.8723184  81  
[28] {Cate10} => {Cate1} 0.080   0.5925926  1.3529511  80  
[29] {Cate7}  => {Cate2} 0.077   0.3756098  0.9606388  77  
[30] {Cate4}  => {Cate3} 0.077   0.3362445  1.2784964  77  
[31] {Cate3}  => {Cate4} 0.077   0.2927757  1.2784964  77  
[32] {Cate9}  => {Cate4} 0.071   0.3988764  1.7418184  71  
[33] {Cate4}  => {Cate9} 0.071   0.3100437  1.7418184  71  
[34] {Cate6}  => {Cate2} 0.068   0.3756906  0.9608455  68  
[35] {Cate9}  => {Cate2} 0.064   0.3595506  0.9195667  64  
[36] {Cate8}  => {Cate2} 0.063   0.2971698  0.7600251  63

以上でRによるバスケット分析ができました。

応用

カテゴリの粒度

カテゴリの粒度は、データによって異なります。

カテゴリを集約しすぎると、施策へ反映しづらくなり、

カテゴリを分割しすぎると、分析結果の解釈が難しくなります。

出現頻度に応じて、集約したり分割することで調整します。

カテゴリの追加

カテゴリに商品だけでなく、

時間情報・曜日など追加したり、

購入者属性を追加することで、

異なる種類のカテゴリ同士のルールを生成できます。

同時購買を生み出す消費者心理

バスケット分析の結果で、同時購買を生み出す消費者心理を推測することは可能ですが、本当に有効な打ち手かどうか検討する必要があります。

一般的に、複数の商品の組み合わせによって得られる便益は、以下のように分類できます:

  • 商品A単体の便益
  • 商品Aだけがもつ固有便益
  • 商品B単体の便益
  • 商品Bだけがもつ固有便益
  • 商品A,Bの共通便益: 重複する便益
  • 商品A,Bの併用便益: 組み合わせることで新規に生まれる便益

さらに、共通便益と併用便益の有無で、以下のように分類できます:

  • 共通便益なし & 併用便益なし (例)おむつとビール、など殆どの組み合わせ
  • 共通便益なし & 併用便益あり (例)おにぎりとお茶、カミソリ本体と刃
  • 共通便益あり & 併用便益なし (例)お茶と牛乳、アメとガム
  • 共通便益あり & 併用便益あり (例)なし

一般的に併用便益の魅力を消費者が理解できれば、同時購買が発生しやすく、

共通便益がある場合、同時購買が発生しにくいです。

バスケット分析を通して、消費者に併用便益の魅力を伝える施策を打つ必要があります。

レコメンデーションに用いられる3つの指標まとめ

概要

購買データから、同時に購入される商品の傾向を分析することを、

マーケットバスケット分析(ショッピングバスケット分析とも呼ばれる。以下バスケット分析)

と呼びます。アソシエーション分析の一種です。

バスケット分析では、

「商品Aを買うときは、商品Bを買う」といった同時購買のルールを見出すことが求められます。

以下では、

「商品Aを買う」(条件部)とき、「商品Bを買う」(結論部)

というルールを

A=>B

という記号で表現します。

「商品Aを買うときは、商品Bを買う」というパターンが発見されたら、

レコメンデーションで使うことができます。

ここでは、まず、

レコメンデーションに用いられる3つの指標をまとめたいと思います。

3つの重要な指標

3つの重要な指標について説明します。

  • Support(支持度): 同時確率
  • Confidence(信頼度): 条件付き確率
  • Lift(リフト): 改善率

Support(支持度)

A=>BのSupport(支持度) とは、

すべてのトランザクションに占める商品A,Bが同時に購入されたトランザクションの割合を指します。

A=>BのSupport(支持度) : AとBの同時購買回数 / 全トランザクション数

と定義します。

具体的には、

全購買件数が5件あり、

商品Aと商品Bを購入した回数が2回であれば、

A=>BのSupport(支持度) : 2 / 5 = 0.4

となります。

Support(支持度)の高いルールは良いルールと言えます。

なお、

A=>BのSupport(支持度)

B=>AのSupport(支持度)

は、等しくなります。

Confidence(信頼度)

A=>BのConfidence(信頼度)とは、

商品Aを買ったトランザクションに占める、

Bが同時に購入されたトランザクションの割合、

つまり条件付き確率を指します。

A=>BのConfidence(信頼度) : AとBの同時購買回数 / Aの購買回数

B=>AのConfidence(信頼度) : AとBの同時購買回数 / Bの購買回数

と定義します。

具体的には、

商品Aを購入したトランザクションが3件、

商品Bを購入したトランザクションが2件、

商品Aと商品Bを同時購入したトランザクションが2件であれば、

A=>BのConfidence(信頼度) : 2 / 3

B=>AのConfidence(信頼度) : 2 / 2

となります。

Confidence(信頼度)の高いルールは良いルールと言えます。

なお、

A=>BのConfidence(信頼度)

B=>AのConfidence(信頼度)

は、基本的に異なります。

つまり、方向性によっては、レコメンデーションの意味をなさないときがありますので、注意が必要です。

例)髭剃り本体を買った人に替え刃をレコメンドできるが、替え刃を買った人に髭剃り本体をリコメンドしても意味がない(当然もっているはず)

Lift(リフト)

A=>BのLift(リフト)とは、

A=>BのSupport(支持度)を、

AとBが独立と仮定したときの購買確率で割った値を指します。

Aの購買確率 : Aの購買回数 / 全トランザクション数

Bの購買確率 : Bの購買回数 / 全トランザクション数

A=>BのLift(リフト) : A=>BのSupport(支持度) / Aの購買確率 * Bの購買確率

別の定義で表現すれば、

A=>BのConfidence(信頼度)を、

Bの購買確率で割った値を指します。

A=>BのLift(リフト) : A=>BのConfidence(信頼度) / Bの購買確率

要するに、

Aの購入によってどれぐらい確率が持ち上げ(Lift)られているか?

という指標です。

A=>BのLift(リフト)値1 を越えているかが、有効なルールの判断基準と言えます。

具体的には、

トランザクションが5件あり、

商品Aを購入したトランザクションが3件、

商品Bを購入したトランザクションが2件であれば、

Aの購入確率 : 3 / 5

Bの購入確率 : 2 / 5

であり、

商品Aと商品Bを同時購入したトランザクションが2件であれば、

A=>BのSupport(支持度) : 2 / 5

A=>BのConfidence(信頼度) : 2 / 3

であり、

A=>BのLift(リフト) : A=>BのSupport(支持度) / Aの購買確率 * Bの購買確率 = (2 / 5) / (3 / 5) * (2 / 5) = 5 / 3 > 1

または、

A=>BのLift(リフト) : A=>BのConfidence(信頼度) / Bの購買確率 = (2 / 3) / (2 / 5) = 5 / 3 > 1

であり、

この例では、

A=>BのLift(リフト)値1 を超えているので、

同時購入されやすいと言えます。

逆に、

A=>BのLift(リフト)値1 以下ならば、

同時購入されにくいと言えます。

以上、

3つの重要な指標について説明しました。

  • Support(支持度): 同時確率
  • Confidence(信頼度): 条件付き確率
  • Lift(リフト): 改善率

『リテールデータ分析入門』書誌情報

顧客の購買行動を測定したデータをリテールデータと呼びますが、

大規模なリテールデータに特化したRによる分析ノウハウが記載されている書籍です。

書誌情報

リテールデータ分析入門

上田隆穂/編著 田島博和/編著 奥瀬喜之/編著 斉藤嘉一/編著
出版社名    中央経済社
出版年月    2014年6月
ISBNコード   978-4-502-09630-3 
(4-502-09630-X)
税込価格    3,024円
頁数・縦    236P 21cm

目次概要

第1章 リテールデータを活用するにはどう考えればよいのか
第2章 データを俯瞰する
第3章 顧客とのリレーションシップをつくる
第4章 同時に購買されやすい商品を知る
第5章 重要な顧客を特定する
第6章 消費者の立場から価格を設定する
第7章 ブランド・ロイヤルティとストア・ロイヤルティを構築する
第8章 購買数量を把握する
第9章 価格とブランド・ロイヤルティがブランド選択に及ぼす影響を把握する

目次詳細

 まえがき
第1章 リテールデータを活用するにはどう考えればよいのか
1   リテール・サイエンスの進展
2   分析にあたっての本質的な課題
3   データ分析から仮説づくりのきっかけをどう生み出すか
4   たとえばPOSデータ分析レベルはどのように整理できるか?
5   新しいデータ分析としての定性データのテキスト・マイニング化(定量化)による分析
6   リテールデータの活用の方向性
第2章 データを俯瞰する
1   ID付きPOSデータとは何か
2   データを詳細に分析する前にしておくこと
3   データの特徴を可視化する
4   数値からデータの特徴をつかむ
5   データクリーニング
第3章 顧客とのリレーションシップをつくる
1   リレーションシップ・マーケティング
2   ID付きPOSデータに基づくリレーションシップ・マーケティングの実践
3   “リレーションシップ”と消費者心理
4   まとめ
第4章 同時に購買されやすい商品を知る
1   レシートデータ
2   ショッピングバスケット分析の考え方
3   Rによるショッピングバスケット分析
4   ショッピングバスケット分析の応用
5   同時購買を引き出す仕組みづくりに向けて
第5章 重要な顧客を特定する
1   デシル分析
2   RFM分析
3   デシル分析とRFM分析の発展
第6章 消費者の立場から価格を設定する
1   価格設定における消費者心理の重要性
2   消費者の価格反応―価格弾力性
3   消費者の値ごろ感―参照価格概念
4   消費者心理を踏まえた価格設定
5   まとめ
第7章 ブランド・ロイヤルティとストア・ロイヤルティを構築する
1   ブランドとは何か
2   ブランド・ロイヤルティをどのように捉えるのか
3   ストア・ロイヤルティをどのように捉えるのか
4   真のブランド・ロイヤルティとストア・ロイヤルティの構築に向けて
第8章 購買数量を把握する
1   価格の変化による購買数量の把握
2   価格弾力性と値引きの影響
3   複数のマーケティング変数の影響を把握する
第9章 価格とブランド・ロイヤルティがブランド選択に及ぼす影響を把握する
1   ブランド選択をモデル化する
2   2項ロジットモデルとロジスティック回帰分析
3   Rによる2項ロジットモデルの推定
4   多項ロジットモデル―選択肢が3つ以上のロジットモデル
5   まとめ
 
あとがき
索引

『Rによるやさしい統計学』書誌情報

R言語による統計学入門として、『Rによるやさしい統計学』が名著です。

その書誌情報です。

概要

Rによるやさしい統計学 | Ohmsha

著者山田 剛史 杉澤 武俊 村井 潤一郎 共著
定価2,916 円(本体2,700 円+税)
A5 420頁 2008/01発行
ISBN978-4-274-06710-5

主要目次

第Ⅰ部 基礎編
第1章 R と統計学
第2章 1 つの変数の記述統計
第3章 2 つの変数の記述統計
第4章 母集団と標本
第5章 統計的仮説検定
第6章 2 つの平均値を比較する
第7章 分散分析
第Ⅱ部 応用編
第8章 ベクトル・行列の基礎
第9章 データフレーム
第10章 外れ値が相関係数に及ぼす影響
第11章 統計解析で分かること・分からないこと
第12章 二項検定
第13章 プリ・ポストデザインデータの分析
第14章 質問紙尺度データの処理
第15章 回帰分析
第16章 因子分析
第17章 共分散構造分析
第18章 人工データの発生
第19章 検定の多重性と第1 種の誤りの確率
第20章 検定力分析によるサンプルサイズの決定
付録A R の情報源
付録B 練習問題解答
付録C FAQ

詳細目次

第I部 基礎編
第1章 R と統計学
1.1 Rって何だろう
1.2 なぜR を使うのか
1.2.1 他のソフトとの比較
1.2.2 R を使ってみよう
1.3 R を導入しよう
1.3.1 R のインストール手順(Windows)
1.3.2 R のインストール手順(Mac OS X)
1.4 R をさわってみよう
1.4.1 R の画面の様子
1.4.2 基本的な操作の概要
1.5 R をもっとさわってみよう
1.5.1 R を使った統計
1.5.2 同じことをExcel でやると
1.6 R の使い方のコツ
1.6.1 複数の値をまとめて扱う
1.6.2 外部データファイルを読み込んでみよう
1.6.3 関数を作ってみよう
1.6.4 他の人の作った関数を利用する
1.6.5 パッケージをインストールしてみよう
1.6.6 Rcmdr を使ってみる
1.7 この本のこれから
第2章 1 つの変数の記述統計
2.1 1 つの変数の要約
2.2 本書で用いるデータの説明
2.3 変数の種類
2.4 データの視覚的表現
2.5 平均とは
2.6 平均以外の代表値
2.7 散布度
2.8 分散、標準偏差とは
2.9 分散、標準偏差以外の散布度
2.10 標準化
2.11 偏差値
まとめ
練習問題
第3章 2 つの変数の記述統計
3.1 2 つの変数の関係
3.2 散布図
3.3 共分散
3.4 相関係数
3.5 クロス集計表
3.6 ファイ係数
まとめ.
練習問題
第4章 母集団と標本
4.1 母集団と標本
4.2 推測統計の分類
4.3 点推定
4.3.1 点推定の手順
4.3.2 推定量と推定値
4.3.3 標本抽出に伴う誤差
4.4 推定値がどれくらいあてになるのかを調べる方法
4.4.1 標本抽出の方法――単純無作為抽出
4.4.2 確率変数
4.4.3 確率分布
4.4.4 母集団分布
4.4.5 正規分布
4.4.6 正規分布について少し詳しく
4.4.7 正規母集団から単純無作為抽出を行う
4.5 標本分布
4.5.1 標本分布から何が分かるのか
4.5.2 標本分布を「経験的」に求める
4.5.3 正規母集団の母平均の推定
4.5.4 標本分布を求める
4.5.5 不偏性
4.5.6 標準誤差
4.6 標本平均以外の標本分布
4.6.1 標本分散と不偏分散の標本分布
4.6.2 中央値の標本分布
まとめ
練習問題
第5章 統計的仮説検定
5.1 統計的仮説検定の必要性
5.2 統計的仮説検定の手順と用語
5.2.1 帰無仮説と対立仮説
5.2.2 検定統計量
5.2.3 有意水準と棄却域
5.2.4 統計的仮説検定の結果の報告
5.2.5 p 値
5.2.6 第1 種の誤りと第2 種の誤り
5.2.7 検定力
5.3 標準正規分布を用いた検定(1 つの平均値の検定・母分散σ2 が既知)
5.4 t 分布を用いた検定(1 つの平均値の検定・母分散σ2 が未知)
5.5 相関係数の検定(無相関検定)
5.6 独立性の検定(カイ二乗検定)
5.7 サンプルサイズの検定結果への影響について
まとめ
練習問題
第6章 2 つの平均値を比較する
6.1 2 つの平均値を比較するケース
6.2 独立な2 群のt 検定
6.3 t 検定の前提条件
6.3.1 分散の等質性の検定
6.3.2 Welch の検定
6.4 対応のあるt 検定
まとめ
練習問題
第7章 分散分析
7.1 一元配置分散分析(対応なし)
7.1.1 一元配置分散分析(対応なし)を実行する
7.1.2 平方和の分解
7.1.3 多重比較(Tukey の方法)
7.2 一元配置分散分析(対応あり)
7.2.1 対応がないものと見なして分散分析をしてみる
7.2.2 一元配置分散分析(対応あり)を実行する
7.2.3 対応の有無による違い
7.2.4 平方和の分解と自由度の計算
7.3 二元配置分散分析(対応なし)
7.3.1 主効果と交互作用効果
7.3.2 二元配置分散分析(対応なし)を分析する
7.3.3 一元配置と見なして分散分析をしてみる
7.4 二元配置分散分析(2 要因とも対応あり)
7.5 二元配置分散分析(1 要因のみ対応あり)
まとめ
練習問題
第II部 応用編
第8章 ベクトル・行列の基礎
8.1 スカラーとベクトル
8.2 ベクトル
8.2.1 ベクトルを作るための関数
8.2.2 ベクトルの基本演算
8.2.3 ベクトルの要素を取り出す
8.3 行列.
8.3.1 行列の基本演算
8.3.2 特別な行列
8.3.3 行列の要素を取り出す
8.3.4 行列を使ってデータを扱う(第7 章を例として)
8.3.5 行列の演算(応用)
第9章 データフレーム
9.1 外部データファイルを読み込むには
9.2 第2章の分析
9.3 第3章の分析
9.4 第5章の分析
9.5 第6章の分析
9.6 第7章の分析
9.7 データフレームについて
9.7.1 data.frame 関数により、直接データフレームを作成する場合
9.7.2 すでにあるベクトルを合成してデータフレームを作成する場合
9.7.3 すでにある行列をデータフレームに変換する場合
9.7.4 外部データファイルを読み込んでデータフレームを作る場合
9.7.5 データフレームをデータエディタウィンドウで編集する
第10章 外れ値が相関係数に及ぼす影響
10.1 問題:動物の体重と脳の重さ
10.2 R で分析してみよう
第11章 統計解析で分かること・分からないこと
11.1 問題:子どものゲーム時間と親の認識
11.2 R で分析してみよう
11.2.1 問題(1)
11.2.2 問題(2)
11.2.3 問題(3)
第12章 二項検定
12.1 二項検定とは
12.2 問題:北海道日本ハムファイターズと東北楽天ゴールデンイーグルスはどちらが強い?
12.2.1 R で分析してみよう
12.3 問題:じゃんけんの結果を予測できるか? 
12.3.1 R で分析してみよう
第13章 プリ・ポストデザインデータの分析
13.1 プリ・ポストデザイン
13.2 R で分析してみよう
13.2.1 ポストテストの値を従属変数、プリテストの値を統制変数
(共変量)とした、群の効果に関する共分散分析
13.2.2 変化量について、t 検定によって群の効果を吟味
第14章 質問紙尺度データの処理
14.1 質問紙尺度について
14.2 R で分析してみよう
14.2.1 パッケージpsy を利用する
14.2.2 逆転項目の処理
14.2.3 尺度得点の計算
14.2.4 α 係数を求める
第15章 回帰分析
15.1 回帰分析とは
15.2 R で分析してみよう
第16章 因子分析
16.1 因子分析とは
16.2 R で分析してみよう
第17章 共分散構造分析
17.1 sem パッケージ
17.2 sem パッケージを利用した共分散構造分析
17.2.1 相関係数行列の入力
17.2.2 測定方程式と構造方程式の記述
17.2.3 共分散構造分析の解
第18章 人工データの発生
18.1 人工データを使うと
18.2 どのような人工データを発生させるか.
18.3 母集団を指定する
18.3.1 1 変数の場合
18.3.2 多変量の場合
18.4 特定の統計モデルに基づいたデータの発生
18.4.1 回帰分析モデル
18.4.2 因子分析モデル
18.5 標本統計量を特定の値にする
18.5.1 データの平均と標準偏差を特定の値にする
18.5.2 データの標本相関係数を任意の値にする
18.6 再現性のある人工データを発生させる
第19章 検定の多重性と第1 種の誤りの確率
19.1 検定の多重性の問題
19.2 プログラムの全体的なイメージを考える
19.3 プログラムの作成
第20章 検定力分析によるサンプルサイズの決定
20.1 検定力
20.2 検定力を求めるシミュレーション
20.2.1 独立な2 群のt 検定の検定力
20.2.2 対立仮説のもとでの検定統計量の標本分布
20.3 検定力分析でサンプルサイズを決める
20.3.1 標準の関数を使う
20.3.2 pwr パッケージを使う
20.3.3 t 検定のサンプルサイズを決める
20.3.4 cohen.ES 関数で効果の大きさの値を求める
20.3.5 無相関検定のサンプルサイズを決める
20.3.6 独立性の検定(カイ二乗検定)のサンプルサイズを決める
20.3.7 一元配置分散分析のサンプルサイズを決める
付録 A R の情報源
書籍
サイト
その他
引用文献
付録 B 練習問題解答
第2章
第3章
第4章
第5章
第6章
第7章
付録 C FAQ
索 引

非常に分かりやすいRによる統計入門書です。 おすすめです。

1章 ニューラルネットワークの復習 / 1.1 数学とPythonの復習 |『ゼロから作るDeep Learning2自然言語処理編』

f:id:kaeken:20181001221520p:plain

1章 ニューラルネットワークの復習

まずはニューラルネットワークを復習する章なので、復習がてらコード部分を写経。

1.1 数学とPythonの復習

1.1.1 ベクトルと行列

>>> import numpy as np # numpyインポート
>>> x = np.array([1,2,3]) # np.array()メソッドで配列生成
>>> x.__class__ #クラス名表示
<class 'numpy.ndarray'> # 多次元配列用クラスndarray
>>> x.shape # 多次元配列の形状を示すインスタンス変数shape
(3,) # 要素数3 
>>> x.ndim # 次元数を示すインスタンス変数ndim
1 #次元数1

>>> W = np.array([[1,2,3], [4,5,6]])
>>> W.shape
(2, 3) #2行3列
>>> W.ndim
2 #次元数2

1.1.2 行列の要素ごとの演算

>>> W = np.array([[1,2,3], [4,5,6]])
>>> X = np.array([[0,1,2], [3,4,5]])
>>> W + X # 和
array([[ 1,  3,  5],
       [ 7,  9, 11]])
>>> W * X # 積
array([[ 0,  2,  6],
       [12, 20, 30]])

1.1.3 ブロードキャスト

形状の異なる配列同士の演算

>>> A = np.array([[1,2], [3,4]])
>>> A * 10 # 10倍
array([[10, 20],
       [30, 40]])
>>>
>>> A = np.array([[1,2], [3,4]])
>>> b = np.array([10,20])
>>> A * b # 2次元配列(2,2), 1次元配列(1,2)の演算
array([[10, 40],
       [30, 80]])

1.1.4 ベクトルの内積と行列の積

# ベクトルの内積
>>> a = np.array([1,2,3])
>>> b = np.array([4,5,6])
>>> np.dot(a,b)
32

# 行列の積
>>> A = np.array([[1,2], [3,4]])
>>> B = np.array([[5,6], [7,8]])
>>> np.dot(A,B)
array([[19, 22],
       [43, 50]])

1.1.5 行列の形状チェック

行列の積は、対応する次元の要素数を一致させる必要がある

# 3行2列と、2行4列の積は、3行4列になる
>>> C = np.array([[1,2], [3,4], [5,6]])
>>> D = np.array([[1,2,3,4], [5,6,7,8]])
>>> C.shape
(3, 2)
>>> D.shape
(2, 4)
>>> np.dot(C,D)
array([[11, 14, 17, 20],
       [23, 30, 37, 44],
       [35, 46, 57, 68]])

# 2行4列と、3行2列の積は、演算不可
>>> np.dot(D,C)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: shapes (2,4) and (3,2) not aligned: 4 (dim 1) != 3 (dim 0)

NumPyの練習は、以下が使える。

rougier/numpy-100: 100 numpy exercises (100% complete)

『ゼロから作るDeep Learning2自然言語処理編』学習開始

f:id:kaeken:20181001221520p:plain

『ゼロから作るDeep Learning自然言語処理編』学習開始。

『ゼロから作るDeep Learning』の続編で、自然言語処理・時系列データがメインテーマ。

機械学習・深層学習の分野は、2年前に『ゼロから作るDeep Learning』を学習したときから比べて、ものすごい勢いで発展してきており、すべてを追うことはかなり困難。

また、基礎ができていないと、多数の事象をそれぞれ個別に学ぶことになり、効率が悪い。

目先のビジネスは最低限にして、倦まず弛まず、基礎を淡々と積み上げていく。

以下、リソースまとめ。

GitHubリポジトリoreilly-japan/deep-learning-from-scratch-2: 『ゼロから作る Deep Learning ❷』のリポジトリ

git clone https://github.com/oreilly-japan/deep-learning-from-scratch-2.git

正誤表 errata · oreilly-japan/deep-learning-from-scratch-2 Wiki

以下『ゼロから作るDeep Learning自然言語処理編』目次。

まえがき

1章 ニューラルネットワークの復習
    1.1 数学とPythonの復習
        1.1.1 ベクトルと行列
        1.1.2 行列の要素ごとの演算
        1.1.3 ブロードキャスト
        1.1.4 ベクトルの内積と行列の積
        1.1.5 行列の形状チェック
    1.2 ニューラルネットワークの推論
        1.2.1 ニューラルネットワークの推論の全体図
        1.2.2 レイヤとしてのクラス化と順伝播の実装
    1.3 ニューラルネットワークの学習
        1.3.1 損失関数
        1.3.2 微分と勾配
        1.3.3 チェインルール
        1.3.4 計算グラフ
        1.3.5 勾配の導出と逆伝播の実装
        1.3.6 重みの更新
    1.4 ニューラルネットワークで問題を解く
        1.4.1 スパイラル・データセット
        1.4.2 ニューラルネットワークの実装
        1.4.3 学習用のソースコード
        1.4.4 Trainerクラス
    1.5 計算の高速化
        1.5.1 ビット精度
        1.5.2 GPU(CuPy)
    1.6 まとめ

2章 自然言語と単語の分散表現
    2.1 自然言語処理とは
        2.1.1 単語の意味
    2.2 シソーラス
        2.2.1 WordNet
        2.2.2 シソーラスの問題点
    2.3 カウントベースの手法
        2.3.1 Pythonによるコーパスの下準備
        2.3.2 単語の分散表現
        2.3.3 分布仮説
        2.3.4 共起行列
        2.3.5 ベクトル間の類似度
        2.3.6 類似単語のランキング表示
    2.4 カウントベースの手法の改善
        2.4.1 相互情報量
        2.4.2 次元削減
        2.4.3 SVDによる次元削減
        2.4.4 PTBデータセット
        2.4.5 PTBデータセットでの評価
    2.5 まとめ

3章 word2vec
    3.1 推論ベースの手法とニューラルネットワーク
        3.1.1 カウントベースの手法の問題点
        3.1.2 推論ベースの手法の概要
        3.1.3 ニューラルネットワークにおける単語の処理方法
    3.2 シンプルなword2vec
        3.2.1 CBOWモデルの推論処理
        3.2.2 CBOWモデルの学習
        3.2.3 word2vecの重みと分散表現
    3.3 学習データの準備
        3.3.1 コンテキストとターゲット
        3.3.2 one-hot表現への変換
    3.4 CBOWモデルの実装
        3.4.1 学習コードの実装
    3.5 word2vecに関する補足
        3.5.1 CBOWモデルと確率
        3.5.2 skip-gramモデル
        3.5.3 カウントベース v.s. 推論ベース
    3.6 まとめ

4章 word2vecの高速化
    4.1 word2vecの改良①
        4.1.1 Embeddingレイヤ
        4.1.2 Embeddingレイヤの実装
    4.2 word2vecの改良②
        4.2.1 中間層以降の計算の問題点
        4.2.2 多値分類から二値分類へ
        4.2.3 シグモイド関数と交差エントロピー誤差
        4.2.4 多値分類から二値分類へ(実装編)
        4.2.5 Negative Sampling
        4.2.6 Negative Samplingのサンプリング手法
        4.2.7 Negative Samplingの実装
    4.3 改良版word2vecの学習
        4.3.1 CBOWモデルの実装
        4.3.2 CBOWモデルの学習コード
        4.3.3 CBOWモデルの評価
    4.4 word2vecに関する残りのテーマ
        4.4.1 word2vecを使ったアプリケーションの例
        4.4.2 単語ベクトルの評価方法
    4.5 まとめ

5章 リカレントニューラルネットワーク(RNN)
    5.1 確率と言語モデル
        5.1.1 word2vecを確率の視点から眺める
        5.1.2 言語モデル
        5.1.3 CBOWモデルを言語モデルに?
    5.2 RNNとは
        5.2.1 循環するニューラルネットワーク
        5.2.2 ループの展開
        5.2.3 Backpropagation Through Time
        5.2.4 Truncated BPTT
        5.2.5 Truncated BPTTのミニバッチ学習
    5.3 RNNの実装
        5.3.1 RNNレイヤの実装
        5.3.2 Time RNNレイヤの実装
    5.4 時系列データを扱うレイヤの実装
        5.4.1 RNNLMの全体図
        5.4.2 Timeレイヤの実装
    5.5 RNNLMの学習と評価
        5.5.1 RNNLMの実装
        5.5.2 言語モデルの評価
        5.5.3 RNNLMの学習コード
        5.5.4 RNNLMのTrainerクラス
    5.6 まとめ

6章 ゲート付きRNN
    6.1 RNNの問題点
        6.1.1 RNNの復習
        6.1.2 勾配消失もしくは勾配爆発
        6.1.3 勾配消失もしくは勾配爆発の原因
        6.1.4 勾配爆発への対策
    6.2 勾配消失とLSTM
        6.2.1 LSTMのインタフェース
        6.2.2 LSTMレイヤの組み立て
        6.2.3 outputゲート
        6.2.4 forgetゲート
        6.2.5 新しい記憶セル
        6.2.6 inputゲート
        6.2.7 LSTMの勾配の流れ
    6.3 LSTMの実装
        6.3.1 TimeLSTMの実装
    6.4 LSTMを使った言語モデル
    6.5 RNNLMのさらなる改善
        6.5.1 LSTMレイヤの多層化
        6.5.2 Dropoutによる過学習の抑制
        6.5.3 重み共有
        6.5.4 より良いRNNLMの実装
        6.5.5 最先端の研究へ
    6.6 まとめ

7章 RNNによる文章生成
    7.1 言語モデルを使った文章生成
        7.1.1 RNNによる文章生成の手順
        7.1.2 文章生成の実装
        7.1.3 さらに良い文章へ
    7.2 seq2seq
        7.2.1 seq2seqの原理
        7.2.2 時系列データ変換用のトイ・プロブレム
        7.2.3 可変長の時系列データ
        7.2.4 足し算データセット
    7.3 seq2seqの実装
        7.3.1 Encoderクラス
        7.3.2 Decoderクラス
        7.3.3 Seq2seqクラス
        7.3.4 seq2seqの評価
    7.4 seq2seqの改良
        7.4.1 入力データの反転(Reverse)
        7.4.2 覗き見(Peeky)
    7.5 seq2seqを用いたアプリケーション
        7.5.1 チャットボット
        7.5.2 アルゴリズムの学習
        7.5.3 イメージキャプション
    7.6 まとめ

8章 Attention
    8.1 Attentionの仕組み
        8.1.1 seq2seqの問題点
        8.1.2 Encoderの改良
        8.1.3 Decoderの改良①
        8.1.4 Decoderの改良②
        8.1.5 Decoderの改良③
    8.2 Attention付きseq2seqの実装
        8.2.1 Encoderの実装
        8.2.2 Decoderの実装
        8.2.3 seq2seqの実装
    8.3 Attentionの評価
        8.3.1 日付フォーマットの変換問題
        8.3.2 Attention付きseq2seqの学習
        8.3.3 Attentionの可視化
    8.4 Attentionに関する残りのテーマ
        8.4.1 双方向RNN
        8.4.2 Attentionレイヤの使用方法
        8.4.3 seq2seqの深層化とskipコネクション
    8.5 Attentionの応用
        8.5.1 Google Neural Machine Translation(GNMT)
        8.5.2 Transformer
        8.5.3 Neural Turing Machine(NTM)
    8.6 まとめ

付録A sigmoid関数とtanh関数の微分
    A.1 sigmoid関数
    A.2 tanh関数
    A.3 まとめ

付録B WordNetを動かす
    B.1 NLTKのインストール
    B.2 WordNetで同義語を得る
    B.3 WordNetと単語ネットワーク
    B.4 WordNetによる意味の類似度

付録C GRU
    C.1 GRUのインタフェース
    C.2 GRUの計算グラフ

おわりに
参考文献
索引

手を動かしながら、コツコツ進める。

(2018-02-04)気になるAI/ML/DL/DSネタ:2018年度前期東大AI講座、脳内イメージ映像化、GoogleドライブOCR、など

実データで学ぶ人工知能講座(AIデータフロンティアコース)平成30年度前期募集のご案内 講座について – 2018年度前期講座 – Learn.AI

東京大学では、大阪大学とともに、国立研究開発法人新エネルギー・産業技術総合開発機構NEDO)の委託を受け、人工知能(AI)分野の人材不足に対応するための即戦力人材の育成講座(AIデータフロンティアコース)を開講します。


何を考えているのかな? 人間の脳内イメージを映像化するAI | ギズモード・ジャパン

fMRIという手法で脳内の血流動態反応を視覚化し、そこから得られた数々の反応情報をAIに学習させているそう。この反応ならこんな絵! という学習を重ねていくことで、映像を再構築できるようになったのだとか。


Google Driveで画像を開いたと思ったら文字が全て書き起こされているという事態に衝撃の人々「マジかよ!」「あ!ホントだ」 - Togetter

1:文字起こししたい画像をGoogleドライブに保存
2:Googleドライブで保存した画像を右クリック
3:Googleドキュメントを選択して開く
4:画像が文字起こしされて展開される


データ分析は「強者の武器」、駆け出しのうちはデータが貯まるまでの間に他にやるべきことがある - 六本木で働くデータサイエンティストのブログ

空前の人工知能ブームに伴ってデータサイエンティストブームが再燃するなど「ビッグデータ」や「データ活用」が改めて脚光を浴びつつある昨今ですが、そういうご時世だからこそ地に足のついたデータ活用戦略をとるべきだ、というのが個人的な意見です。


類似文字列検索ライブラリResemblaを公開しました : LINE Engineering Blog

Resemblaは、このように複雑で多岐にわたる問題に取り組むため、以下の2点に主眼を置いて開発している類似文字列検索ライブラリです。 文字列の性質に合わせた尺度の選択と組み合わせによる品質の改善 候補の絞り込みとコーパスの前処理による速度の向上