Tokyo.R #82 応用セッションでの発表スライド(公開用)です。
週次KPIレポートをconfluenceへUpするためにやったことTokyo.R #82前田和寛(kazutan)2019-10-26
View Slide
はじめに2 / 40
はじめに自己紹介名前/アカウント前田和寛(Maeda Kazuhiro)@kazutanTwitterGitHubQiita, etc...所属LINE Fukuoka株式会社開発センターDataLabs DataAnalysisチームマネージャー3 / 40
はじめに業務LINEグループにあるデータを活用して様々な課題にアプローチサービス関連サービスの成長につながる分析施策の効果検証などオペレーション関連オペレーションの可視化オペレーションの効率化につながる分析などデータ分析環境関連分析環境の準備・構築ライブラリ・パッケージ開発など4 / 40
はじめに今日のお話私が担当したサービス関連の分析業務で、実際に構築した事例を紹介具体的なデータおよびコードは社内情報のため伏せてます量が多いので、かいつまんで説明します詳細の実装については個人的に質問してください5 / 40
1.今回の課題6 / 40
1.今回の課題背景(かんたんに)弊社のとあるサービスにて過去8週分のweeklyでの各KPI指標を毎週算出してレポートしていたUU、訪問数、その他...以下のようなリクエストがもっと長期的な流れを見たい異常値かどうか判断したい将来予測も出してほしい7 / 40
1.今回の課題課題(かんたんに)大枠の処理は以下の通りweelky KPIsを算出算出したKPIスコアを用いてモデリングfitting予測値と実測値から異常値を検出forecastレポート作成各KPI指標をplot関係者が閲覧できる適切な場所へレポート作成8 / 40
1.今回の課題要件整理KPI算出データはすべて分析用DBにあるでもデータがかなり大きいKPI指標によって参照テーブルや集計ロジックが異なる単一のクエリだけですべて算出するのは厳しい各KPI指標ごとにSQLでデータを切り出して、Rでいい感じにまとめるいい感じにまとめたら、中間テーブルへ書き出す9 / 40
1.今回の課題モデリングKPIテーブルからデータを読み込み、Rでモデリングprophetを利用レポートに必要なスコアをまとめ、中間テーブルへ書き出すレポート作成の際はこのテーブルだけを読み込めばいいようにするレポート作成plot作成ggplot2を採用予測範囲を外れている実測値には予めフラグ処理レポート作成R Markdown で雛形を作成レポート設置confluence上に設置conflrを活用10 / 40
1.今回の課題アプローチ11 / 40
2.前処理とKPI算出12 / 40
2.前処理とKPI算出対象処理KPI算出データはすべて分析用DBにあるでもデータがかなり大きいKPI指標によって参照テーブルや集計ロジックが異なる単一のクエリだけですべて算出するのは厳しい各KPI指標ごとにSQLでデータを切り出して、Rでいい感じにまとめるいい感じにまとめたら、中間テーブルへ書き出す13 / 40
2.前処理とKPI算出ここでのアプローチ14 / 40
2.前処理とKPI算出glueとpurrrを使ったクエリ実行(1)glueパッケージhttps://glue.tidyverse.org/一部パラメータ化された文字列(雛形)に対して、後から文字列を挿入同一のKPIを算出する場合、ロジックは同一これを出したい期間ごとにクエリを作成すればいい15 / 40
2.前処理とKPI算出SQLファイルの例:select (略) from (略)where date between {start_date} and {end_date}Rでの実行例:# 上述 kpi1_sql_base 格納kpi1_sql glue(kpi1_sql_base,start_date = "20191001",end_date = "20191007")でも、これだと各期間でひとつずつやっていくのが面倒16 / 40
2.前処理とKPI算出glueとpurrrを使ったクエリ実行(2)purrrも活用先程のRスクリプトを以下のように変更:# 開始日 終了日 準備start_date c("20191001", "20191008", "20191015")end_date c("20191007", "20191014", "20191022")# 関数 定義f_create_sql_kpi function(sql, start_date, end_date) {glue(sql, start_date = start_date, end_date = end_date)}# 作成kpi1_sql map2(start_date, end_date,f_create_sql_kpi, sql = kpi1_sql_base )17 / 40
2.前処理とKPI算出glueとpurrrを使ったクエリ実行(3)どうせならクエリ実行もやってしまえばいい# 関数 変更f_create_kpi function(sql, start_date, end_date) {sql glue(sql, start_date = start_date, end_date = end_date)df ( sql 実行 df 出 処理 書 )return(df)}# 一気kpi1_df map2_dfr(start_date, end_date,f_create_kpi, sql = kpi1_sql_base)18 / 40
2.前処理とKPI算出算出した指標をまとめ、KPIテーブルに書き込む詳細は省略KPIごとにdfが存在するので、あとはRでハンドリングすればOKハンドリングが終われば、RからDBへ書き込み処理なお弊社には社内ライブラリでDBにかんたんに接続してread/writeできる関数が準備してあります19 / 40
3.モデリング20 / 40
3.モデリング対象処理モデリングKPIテーブルからデータを読み込み、Rでモデリングprophetを利用レポートに必要なスコアをまとめ、中間テーブルへ書き出すレポート作成の際はこのテーブルだけを読み込めばいいようにする21 / 40
3.モデリングここでのアプローチ22 / 40
3.モデリングprophetとpurrrによるfitting(1)KPIテーブル(tbl_kpis)は以下のような感じ:start_date end_date var_name value20191001 20191007 UU 1361246720191008 20191014 UU 1146634220191015 20191022 UU 1624507220191001 20191007 visits 4008338220191008 20191014 visits 3070466623 / 40
3.モデリングprophetとpurrrによるfitting(1)tidyなデータにしているので、var_nameでnestしてprophetしたいまずはfittingしてreportingに必要な指標を取得する関数を準備# prophet 関数 準備fit_by_prophet function(df,(prophet 引数 準備)) {fit prophet(df = df,(prophet 引数 引 渡 ))future make_future_dataframe(fit, (各種設定))pred predict(fit, future)res pred %>%select(ds, starts_with("yhat")) %>%left_join(fit$history, by = c("ds" = "ds")) %>%select( c(floor, t, y_scaled))return(res)}24 / 40
3.モデリングprophetとpurrrによるfitting(2)あとは以下のような感じでnestしてpurrrのmapしていけばOKfits_weekly_kpi kpi_table %>%group_by(var_name) %>%nest() %>%mutate(pred = map(data,fit_by_prophet,(各種 設定 ))) %>%select(var_name, pred) %>%unnest() %>%mutate(start_date = ymd(ds)) %>%select(start_date, var_name, y, yhat, yhat_lower, yhat_upper)25 / 40
3.モデリング結果をKPIテーブルに書き込む詳細は省略上記のコードでdfができるので、それをまるっと書き込むなお弊社には社内ライブラリでDBにかんたんに接続してread/writeできる関数が準備してあります26 / 40
4.レポート作成27 / 40
4.レポート作成対象処理レポート作成plot作成ggplot2を採用予測範囲を外れている実測値には予めフラグ処理レポート作成R Markdown で雛形を作成レポート設置confluence上に設置conflrを活用28 / 40
4.レポート作成ここでのアプローチ29 / 40
4.レポート作成ggplot2によるKPI可視化(1)今回のplotに利用する変数は以下の通り:var_name: KPI指標の名称start_date: 週の開始日y: 実測の集計値yhat: fitさせた予測値yhat_upper, yhat_lower: 予測のCI上限, 下限今回は加え、yがyhat_upper, yhat_lowerの区間から外ているかどうかのフラグ変数(outlier)を作成これらを一気にやる関数を準備30 / 40
4.レポート作成ggplot2によるKPI可視化(2)準備した関数はこんな感じ:plot_kpi function(df, target_var, plot_title, decimal = FALSE) {# 変数名 使 filter & 変数追加df_for_plot filter(df, var_name target_var) %>%mutate(outliers = case_when(y > yhat_upper ~ "upper",y < yhat_lower ~ "lower",is.na(y) ~ NA_character_,TRUE ~ "middle"))subtitle_text paste("対象 :",min(filter(df_for_plot, !is.na(y))$start_dat"-",max(filter(df_for_plot, !is.na(y))$start_dat31 / 40
4.レポート作成(続き)#ggplotp ggplot(df_for_plot) +# geomsgeom_ribbon(aes(x = start_date, ymin = yhat_lower, ymax = yhat_upper),fill = "#0000ff33") +geom_line(aes(x = start_date, y = yhat), color = "#0000ffaa") +geom_point(aes(x = start_date, y = y, color = outliers),show.legend = FALSE, na.rm = TRUE) +# scalesscale_x_date(date_breaks = "1 month", date_labels = "%Y/%m") +scale_y_continuous(labels = if (!decimal) scales comma else waiver()) +scale_color_manual(values = c("red", "black", "blue", "gray")) +# labels and themestheme_bw() +labs(title = plot_title, subtitle = subtitle_text,caption = "点 実測値 実線 帯 予測値 \n将来8週間 予測 \n日x = "", y = "")# outputp}32 / 40
4.レポート作成ggplot2によるKPI可視化(3)仕上がりはこんな感じになる:33 / 40
4.レポート作成レポート用Rmd作成内容自体はシンプルなので詳細は省略setupチャンクで予測値を含むKPI指標テーブルを読み込む上述の関数に上記テーブルデータと必要な引数をセットするchunkを準備これを各KPIごとに準備してあげればOK34 / 40
4.レポート作成レポートの設置場所はどうする?とりまく状況弊社ではConfluence Wikiが最も利用されているすでに多くの社員が利用していて、社内共通のプラットフォームで利用できるでも、コピペでWiki編集するのはつらすぎる解決策conflrパッケージhttps://github.com/line/conflrLINEが公開しているパッケージRmdから直接conflrへUpload可能RStudioのAddinから実行すればOK!!!!!!!35 / 40
まとめ36 / 40
まとめ課題の確認weelky KPIsを算出算出したKPIスコアを用いてモデリングfitting予測値と実測値から異常値を検出forecastレポート作成各KPI指標をplot関係者が閲覧できる適切な場所へレポート作成37 / 40
まとめ達成するためのアプローチ38 / 40
まとめ今回の限界および課題ホントは細かい部分でもっと色々やってる発表の尺や公表できない部分があり省略してます実際はこの3ステップをRScriptにそれぞれまとめているそしてそれをオーガナイズするRScriptを準備して実行してるこの仕組みで、conflrでの作業がどうしても手作業が残った構築した当時、conflrはAddinからしかUpできなかった現在ではAddin経由しなくてもRのコマンドで実行可能Jenkinsやdroneなどと組み合わせて完全自動化できる!!39 / 40
Enjoy!40 / 40