「ビジネス活用事例で学ぶ データサイエンス入門」輪読会#7資料
TRANSCRIPT
「ビジネス活用事例で学ぶ データサイエンス入門」輪読会 #7
25 PAGES
Shintaro Nomura
R で 学 ぶ
2016.05.13 @ Akiba Code
使用テキストとソースコードの場所 2
「ビジネス活用事例で学ぶ データサイエンス入門」http://amzn.to/1Y73Y52( kindle 版あり)
使用データおよびソースコードの DLSBクリエイティブサイトhttp://www.sbcr.jp/support/11915.html
データ分析の模範フロー(復習)
現状とあるべき姿
問題発見
データ収集と加工
データ分析
アクション
3
ギャップから問題の構造を把握
データ分析を活用した機能の実装
今回の分析ストーリー
目的 チーム内で同時間帯にゲームを遊んでいる人が多くなるようにプレイヤーにチーム編成をさせたい
分析アプローチ 過去のサービス利用状況から、ユーザごとに翌日サービスを利用する時間帯の予測を行う
アクション 分析結果をもとに、同じ時間帯にアクセスするであろうユーザ同士でチームを作らせる
4安定期に入った自社開発ゲームあるある
PDCA 回したくなりがちPlan( 企画 )→Do( 実施 )→Check( 検証 )→Action( 改善 )
新企画:チーム編成のサジェスト機能
中間データ読み込み用の関数の作成 5readActionHourly <- function(app.name, date.from, date.to) {date.from <- as.Date(date.from)date.to <- as.Date(date.to)ldply(foreach(day = seq.Date(date.from, date.to, by = "day"),combine = rbind) %do%{f <- sprintf("sample-data/section10/action_hourly/%s/%s/action_hourly.tsv“, app.name, day)read.csv(f, header = T, stringsAsFactors = F, sep = "\t")})}あくまでデータの読み込みを統一的に処理するための関数を作成しているだけ。
・ readActionHourly は処理方法を指定する関数 (function) となっている・ as.Date は()内のデータ型式を日付型データに変換するコマンド・ foreachとldplyを使ってforループの記述から脱却しよう - kensuke-miの日記
sprintf 関数と「 function 」
sprintf(" まず %s, その次に %s", " 最初の文字列 ", " 次の文字列 ")[1] " まず 最初の文字列 , その次に 次の文字列 "
6
hello <- function(name){ + print(sprintf("Hello %s", name)) + } hello(“ ジャニーさん” ) # 定義した関数で出力
[1] "Hello ジャニーさん "
詳しくは・「みんなのR データ分析と統計解析の新しい教科書」第8章・ RPubs - R の文字列結合が面倒くさいので色々考えてみた
実際に実行してみた方が理解が早い
action.hourly <- readActionHourly("game-01", "2013-08-01", "2013-08-08")head(action.hourly)function により定義した readActionHourly 関数を使用し、 app.name, date.from, date.to を指定した上で、「 sample-data/section10/action_hourly/%s/%s/action_hourly.tsv 」を読み込んでみた結果
そもそもの「 sample-data/section10/action_hourly/ 」以下の構造
7
時間帯が列になるように整形
dates <- unique(action.hourly$log_date)train.list <- lapply(1:(length(dates) - 1), function(i) {day <- dates[i]x <- action.hourly[action.hourly$log_date == day, ]df <- dcast(x, user_id ~ log_hour, value.var = "count",function(x) {ifelse(sum(x) >= 7, 1, 0)})names(df) <- c("user_id", paste0("p", i, "_", 0:23))df})head(train.list[[1]])過去の下処理の集大成みたいなコードが続きますが、いくつかは #5 資料を参照くださいhttp://www.slideshare.net/ShintaroNomura/5-59987223applyファミリー | apply,sapply,lapplyの使い方とその例
length(XXX): XXX の中にある要素の個数dates[k]: 「 dates 」のk番目の要素を取り出すx <- action.hourly[action.hourly$log_date == day, ]:
8print(dates)[1] "2013-08-01" "2013-08-02" "2013-08-03" "2013-08-04" "2013-08-05" "2013-08-06" "2013-08-07" "2013-08-08"
R における for ループ
for(i in 1:10){print(i)}出力結果:
[1] 1 [1] 2 [1] 3 [1] 4 [1] 5 [1] 6 [1] 7 [1] 8 [1] 9 [1] 10
9
同じ曜日の別の日のデータと結合
# 説明(変数)用のデータを作成train.data <- train.list[[1]]for (i in 2:length(train.list)) {df <- train.list[[i]] # train.list[2] ~ train.list[7] を df に格納→新 train.data にマージtrain.data <- merge(train.data, df, by = "user_id", all.x = T)train.data[is.na(train.data)] <- 0 }names(train.data)
# 答えとなるデータを作成ans0 <- action.hourly[action.hourly$log_date == dates[length(dates)], ]# 時間帯が列になるように整形ans <- dcast(ans0, user_id ~ log_hour, value.var = "count", function(x) {ifelse(sum(x) >= 7, 1, 0)})names(ans) <- c("user_id", paste0("a_", 0:23)) # 説明用のデータとくっつけるtrain.data <- merge(train.data, ans, by = "user_id", all.x = T)train.data[is.na(train.data)] <- 0names(train.data)
10
この場合、「 2013-08-08 」になる
最終 train.datahead(train.data)・ train.data と ans がマージされた最終 train.data
※ 画像はテキスト p.244 より
11
今回の分析アプローチ(おさらい)
今回の分析ストーリー
目的チーム内で同時間帯にゲームを遊んでいる人が多くなるようにプレイヤーにチーム編成をさせたい
分析アプローチ
過去のサービス利用状況から、ユーザごとに翌日サービスを利用する時間帯の予測を行う
アクション分析結果をもとに、同じ時間帯にアクセスするであろうユーザ同士でチームを作らせる
12
予測モデル構築 → 検証 → 予測モデルを分析アルゴリズムに実装
予測モデルの構築
予測モデルの構築がそもそも可能か?
扱うデータに「規則性」「まとまり」が存在しないならば
モデル構築は厳しい
ノイズの除去
ビジネスデータにはノイズが多く、モデリングに悪影響を
及ぼす可能性も
利用ツールの選定
構築モデルにどのツールを用いるべきか予想がつかない場
合は、なるべく多くのツールで実際に検証
13
分類モデルの性能比較 ( 利用ツールの選定 )
複数のツール同士の性能を比較する方法は、
分析者が構築したいモデルへのニーズ(正
解率が高い方が良いとか、不正解を極力減
らしたいとか etc… )によって、用いる指
標が異なる
今回は指標に F1-measure (値)を使用し
ている
14
F1-measure (値)
Recall = 正解率 ( TP+TN / 全体 )Precision = 適合率 ( TP / 陽性判定全
体)
逆相関になりやすいので調和平均をとる
15
正解は「1」 正解は「0」
予測が「1」 TP (真陽性) FP (偽陽性)
予測が「0」 FN (偽陰性) TN (真陰性)
F値基準によるノイズの除去
F1値を使用して分類モデルにおけるノイ
ズの閾値を決定(直近3日間 PV≧7だと
翌日訪問/同 PV<7だと来ないモデル)
これにより、同 PV が7未満の箇所をノ
イズと決定し、そのデータを0に換える
16
決定木:分類と回帰
分類ルールを木構造で表したもの
目的変数がカテゴリデータなどの場合は「分
類木」、連続値などの量的データの場合は
「回帰木」と呼ばれる
参考:決定木 – 分類木 | トライフィールズ
⇨ひとまず R で動かして見てみましょう
ソースコード
18
ランダムフォレスト
集団(アンサンブル)学習のひとつ
ランダムに抽出した決定木を複数つくり、
その中から精度の高いモデルを1つ作成
する手法
今回のコードでは、” e1071” というパッ
ケージが必要になるかも
20
randomForest とクロスバリデーション
# 学習のカスタマイズfit.control <- trainControl(method = "LGOCV", p = 0.75, number = 30)リサンプリング方法: Leave-Group-Out クロスバリデーションp: LGO クロスバリデーションにて学習 (訓練 ) に用いるデータの割合number :指定したリサンプリング方法において学習を繰り返す回数
21
Wikipedia: クロスバリデーション
交差検証(英 : Cross-validation )とは、統計学において標本データを分割し、その一部をまず解析して、残る部分でその解析のテストを行い、解析自身の妥当性の検証・確認に当てる手法を指す。
データの解析(および導出された推定・統計的予測)がどれだけ本当に母集団に対処できるかを良い近似で検証・確認するための手法である。
最初に解析するデータを「訓練事例集合( training set )」などと呼び、他のデータを「テスト事例集合( testing set 、テストデータ)」などと呼ぶ。
randomForest による学習コード
# ランダムフォレストによる学習rf.fit.list <- lapply(0:23, function(h) {df <- train.data[, c(paste0("p", 1:7, "_", h), paste0("a_", h))]df1 <- df[df[, ncol(df)] == 1, ]df0.orig <- df[df[, ncol(df)] == 0, ]df0 <- df0.orig[sample(1:nrow(df0.orig), nrow(df1)), ]df <- rbind(df1, df0)fit <- train(x=df[, -ncol(df)], y=df[, ncol(df)],method = "rf", preProcess = c("center", "scale"),trControl = fit.control)fit})ncol(XXX) : XXX の行数(n×m次元である XXXベクトルにおけるn)nrow(XXX) : XXX の列数(n×m次元である XXXベクトルにおけるm)
train() : 予測モデルのフィッティングを行う関数( {caret} が必要) method :予測方法の指定( rf = ランダムフォレスト) trControl : training データをどうやって選ぶか( fit.control にて指定済み)
22
構築された最終モデルによる予測精度
# 作成したモデルの予測値と実際の値との比較結果の表示for (i in 0:23) {result.rf <- predict(rf.fit.list[[(i + 1)]]$finalModel, train.data)result.rf.pred <- ifelse(result.rf >= 0.5, 1, 0)print(confusionMatrix(result.rf.pred, train.data[, paste0("a_",i)]))}Confusion Matrix and Statistics ( i = 0 のとき;結果はモデル計算の都度変わる)
Accuracy : 0.815 ←( 389 + 47 ) / ( 389 + 20 + 79 + 47 ) 95% CI : (0.7794, 0.847) No Information Rate : 0.8748 P-Value [Acc > NIR] : 1 … (こうした結果が各時間帯ごとに出力される:最終的に 26×24 行出力)
23
Prediction\Reference 正解は「1」 正解は「0」
予測が「1」 389 20予測が「0」 79 47
アクション( 10.5 )
テキストでは、構築された予測モデルの精度に問
題がないとの判断から、それにより各ユーザごと
に「翌日どの時間帯にどの程度の確率でゲームを
利用するか」を出力するアルゴリズムを実装
その出力データに基づき、各ユーザが入るチーム
探しの際に、翌日そのユーザが来た際にアクティ
ブユーザー率が高くなる確率が高いチームを推薦
する機能を導入することにした
24
長期間おつかれさまでした
Q. 今後、当グループで学習したいこと (n=11; 最終回の参加希望者・回答者 )
以下の書籍をクリックすると Amazon に飛びます。
25
1 2 3
11 9 7