Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

レコメンドエンジン作成コンテストの勝ち方

5,128 views

Published on

PyData.Tokyo Meetup #18での講演資料です。
https://pydatatokyo.connpass.com/event/

Published in: Data & Analytics

レコメンドエンジン作成コンテストの勝ち方

  1. 1. copyright Fringe81 Co.,Ltd. レコメンドエンジン作成 コンテストの勝ち方 貫井 駿 (Shun Nukui) Fringe81株式会社 PyData.Tokyo Meetup #18 1
  2. 2. copyright Fringe81 Co.,Ltd. 2ヶ月間本気で レコメンドエンジン作成に 取り組んで初めて気がついた 困難と解決アプローチ 2
  3. 3. copyright Fringe81 Co.,Ltd. こんな人に聞いてほしい ● データ分析コンテストに参加したことある ● これから参加したいという人 ● 業務や趣味で機械学習による予測タスクをやっている人 3
  4. 4. copyright Fringe81 Co.,Ltd. ● 貫井 駿(ぬくい しゅん, @heartz2001) ● 専門:Webマイニング、機械学習 ● 略歴: ○ 2017年3月 東京工業大学情報理工学研究科 卒業 ■ 競馬研究会 元部長 ○ 2017年4月-9月 競馬予想販売を専業 ■ 機械学習の実践的なノウハウを習得 ○ 2017年10月 Fringe81株式会社 入社 ■ アドネットワークのアルゴリズム最適化 ● データ分析コンテスト歴:今回初参加 ● 趣味:競馬、将棋 自己紹介 4
  5. 5. copyright Fringe81 Co.,Ltd. アジェンダ ● コンテスト概要 ● レコメンドにおける問題設計 ● 時系列データにおける訓練・検証・テストデータの構築 ● 保守性の高い分析コードの設計 ● 特徴量の作成 ● LightGBMのチューニング 5
  6. 6. copyright Fringe81 Co.,Ltd. レコメンドエンジン作成チャレンジコンテスト ● SIGNATE(旧・DeepAnalytics) 主催 ● 株式会社オプトがデータ提供 ● ユーザの行動履歴データを元にその後それぞれのユーザが高い関心度 を示す商品を予測 ○ ユーザの行動予測 ● 推薦対象ユーザ1人に対して22件の商品を推薦 ● 人材、旅行、不動産、アパレルの4業種 ● 業種ごとに個別に予測モデル作成 ● コンテスト詳細: https://signate.jp/competitions/45 6
  7. 7. copyright Fringe81 Co.,Ltd. レコメンドエンジン作成チャレンジコンテスト 7 商品1 商品2 商品3 商品22 ・・・ ユーザ ● 過去の行動ログをもとに、1ユーザあたり22件の商品を推薦 ● 未来の行動ログにおける関連度が高い商品をより上位に推薦できると ハイスコアになる ● 関連度:閲覧=1点、広告クリック=2点、CV=3点 上位に関連度高い商品を 推薦できれば高スコア
  8. 8. copyright Fringe81 Co.,Ltd. 評価方法 ● nDCG(normalized discounted cumulative gain) ○ ランキング問題ではおなじみの評価指標 ● 関連度:閲覧=1点、広告クリック=2点、CV=3点 ● 理想的な並び順で予測できていれば nDCG=1.0で最大 ○ 推薦順のDCGを理想的な並び順のDCG(=IDCG)で割る 8
  9. 9. copyright Fringe81 Co.,Ltd. データ内容 カラム名 説明 user_id ユーザID product_id 商品ID event_type 行動ID (閲覧, 広告クリック, CV, カート) ad 広告経由か否か time_stamp タイムスタンプ ● train.tsv: 訓練用行動履歴 (2017/4/1-2017/4/30) ● test.tsv: 推薦対象ユーザID (2017/5/1-2017/5/7 に行動) カラム名 説明 user_id ユーザID (train.tsvで最低1回は行動をしている ) 9
  10. 10. copyright Fringe81 Co.,Ltd. コンテストのおおまかな流れ train.tsv test.tsv 推薦 システム 学習 推薦対象入力 推薦商品 リスト 推薦 submit!! 1日5回まで スコア ランキング 10
  11. 11. copyright Fringe81 Co.,Ltd. 簡単そうにみえるでしょ? 11
  12. 12. copyright Fringe81 Co.,Ltd. わたしも最初はそう思っていました 12
  13. 13. copyright Fringe81 Co.,Ltd. 1. レコメンドにおける問題設計 2. 時系列データにおける訓練・検証・テストデータの構築 3. 保守性の高い分析コードの設計 4. 特徴量の作成 5. LightGBMのチューニング 数々の困難 13
  14. 14. copyright Fringe81 Co.,Ltd. 1. レコメンドにおける問題設計 2. 時系列データにおける訓練・検証・テストデータの構築 3. 保守性の高い分析コードの設計 4. 特徴量の作成 5. LightGBMのチューニング 数々の困難 14
  15. 15. copyright Fringe81 Co.,Ltd. ● 多くのコンペではtrain.csvを読み込んだらそれがXに対応する ● 今回のデータは1つの(user, item)のペアについて複数のログが存 在する ● 予測モデルの入力Xの1行 ≠ 行動ログの1行 ● 暗黙的フィードバックのため、良い・悪いが明示されていない ○ ⇔ 明示的フィードバック 困難1: 予測モデルの入力Xをどう定義するか 15
  16. 16. copyright Fringe81 Co.,Ltd. レコメンド問題のよくある設定 (映画レビュー) ● (user, item) に対して良い・悪いのスコアが与えられている ○ 明示的フィードバック (explicit feedback) ● 未知の (user, item) に対してスコアを予測 ○ 協調フィルタリングなど 4 2 2 1 3 3 user1 user2 user3 item1 item2 item3 item4 item5 0.4 4 0.1 2 0.1 0.8 3.8 0.2 2 0.1 1 2.0 3 1.5 3 user1 user2 user3 item1 item2 item3 item4 item5 予測 例) 映画のレビュー評価 16
  17. 17. copyright Fringe81 Co.,Ltd. ● 暗黙的フィードバック (implicit feedback) ● (user, item)が行動履歴に現れていても良い・悪いを直接スコア 化できない 今回の行動ログにおけるレコメンド ? ? ? ? ? ? user1 user2 user3 item1 item2 item3 item4 item5 user_id item_id action_type user2 item4 閲覧 user2 item4 閲覧 user2 item4 クリック 行動ログ 17 行動⇔スコアの対応が不明 =スコアの対応規則さえ決め てしまえば良い
  18. 18. copyright Fringe81 Co.,Ltd. 1. 観測済み (user, item) について良い・悪いをスコアリング ○ 良い=未来の期間において商品に再び関心をもつ 2. 未観測の (user, item) のスコアを予測 解決: 問題を2段階に分ける user_id item_id action_type user2 item4 閲覧 user2 item4 カート user2 item4 クリック 0.4 4.1 0.1 2.3 0.1 0.8 3.8 0.2 2.7 0.1 1.2 2.0 3.5 1.5 3.1 user1 user2 user3 item1 item2 item3 item4 item5 4.1 2.3 2.7 1.2 3.5 3.1 user1 user2 user3 item1 item2 item3 item4 item5 行動→ スコア の対応 未知ペアの スコアリング 18
  19. 19. copyright Fringe81 Co.,Ltd. 段階1: 観測済みペアに対するスコアリング 19 簡単なルールベースの例: 過去の行動ログにおいて(user, item)以下の得点を合計 ● 閲覧=1点 ● クリック=2点 ● CV=1点 ● カート=4点 未来において再び興味を持つかどうかの観 点でスコアリング 過去の行動ログ 未来の行動ログ
  20. 20. copyright Fringe81 Co.,Ltd. 機械学習として解く場合: 入力 X 過去の行動ログにおける(user, item)に対する特徴量 例) ユーザが商品を閲覧した回数, 商品の合計クリック回数 出力 y 未来の行動ログにおける(user, item)に対する関連度 例) 閲覧=1, クリック=2, CV=3 ⇛シンプルな回帰予測問題に落とし込めた 段階1: 観測済みペアに対するスコアリング 20
  21. 21. copyright Fringe81 Co.,Ltd. ● 行列の欠損部分を埋める方法はいろいろ ○ Matrix Factorization ○ Label Propagation 段階2: 未観測のペアに対するスコアリング 4 2 2 1 3 3 user1 user2 user3 item1 item2 item3 item4 item5 0.4 4 0.1 2 0.1 0.8 3.8 0.2 2 0.1 1 2.0 3 1.5 3 user1 user2 item1 item2 item3 item4 item5 予測 21
  22. 22. copyright Fringe81 Co.,Ltd. 1. レコメンドにおける問題設計 2. 時系列データにおける訓練・検証・テストデータの構築 3. 保守性の高い分析コードの設計 4. 特徴量の作成 5. LightGBMのチューニング 数々の困難 22
  23. 23. copyright Fringe81 Co.,Ltd. submitした結果の評価値だけに頼ると、 ● 1日5回までしかsubmitできないので、実験サイクルを回せる回数 が限られる ● テストデータに対して過適合を起こして汎化性能が低い予測モデ ルになる ⇛ 手元でモデルの性能を評価できるようにする必要がある モデルの検証がなぜ必要か? 23
  24. 24. copyright Fringe81 Co.,Ltd. ● 訓練データ (X_train, y_train) ○ モデル学習に利用するデータ ● 検証データ (X_valid, y_valid) ○ モデル選定のための性能比較に用いるデータ ● テストデータ (X_test, y_test) ○ 最終的に選定されたモデルの性能を評価するための データ 予測モデルにおける訓練・検証・テスト 24
  25. 25. copyright Fringe81 Co.,Ltd. 困難2: 時系列データの場合の分割方法 5/75/14/244/174/10 テスト検証訓練 ● 入力Xは過去の行動ログから作られる ● 目的変数yは未来の行動ログから作られる 25 以下のような単純な分け方にはならない
  26. 26. copyright Fringe81 Co.,Ltd. 解決: 正しい訓練・検証・テストの分割方法 5/75/14/244/174/10 y_testを予測する 訓練 検証 テスト 26 X_train y_train X_valid y_valid X_test y_test
  27. 27. copyright Fringe81 Co.,Ltd. 解決: 正しい訓練・検証・テストの分割方法 5/75/14/244/174/10 訓練 検証 テスト 27 X_train y_train X_valid y_valid X_test y_test この考えに至るまでに 1週間くらいかかった… ● 実際には、Xを作成するための過去ログの長さはyの期間に合わせずに ちょうどよく決める必要があるためもっと複雑…
  28. 28. copyright Fringe81 Co.,Ltd. 1. レコメンドにおける問題設計 2. 時系列データにおける訓練・検証・テストデータの構築 3. 保守性の高い分析コードの設計 4. 特徴量の作成 5. LightGBMのチューニング 数々の困難 28
  29. 29. copyright Fringe81 Co.,Ltd. ● 分析していると、データ読み込み、基礎集計、データ整形、特徴量生 成、モデル学習、評価などすべての工程が詰まっている「神 notebook」を作りがち ● 瞬発力重視の分析なら強い ● 1~2ヶ月スパンのデータ解析コンテストでは管理しきれなくなる 困難3: 分析コード散らかる問題 29
  30. 30. copyright Fringe81 Co.,Ltd. 解決: 予測タスクの機能ごとにモジュール化 csvcsv tsv DataSet DataProcessor Feature 前処理されたデータ 特徴量の生成レシピ Recommeder 特徴量行列 user_id item_id u11111 p12345 u11111 p12378 …. 予測 結果 Evaluator submit!! 評価値 ● 各機能はモジュール(*.pyファイル)に分けて実装 30 Config
  31. 31. copyright Fringe81 Co.,Ltd. モジュール化するメリット ● 実行スクリプトには処理の流れだけを記述し簡潔さを保つ ● コアの処理コードが一元化されるので管理が楽 ● ユニットテストが書きやすい ● git のバージョン管理もしやすい ● どの予測タスクもだいたいフローは同じなので使い回しが効く 31
  32. 32. copyright Fringe81 Co.,Ltd. コンパクトな実験サイクル 32 config.py run.py 評価値 フィードバック・更新 学習・評価設定適用
  33. 33. copyright Fringe81 Co.,Ltd. 1. レコメンドにおける問題設計 2. 時系列データにおける訓練・検証・テストデータの構築 3. 保守性の高い分析コードの設計 4. 特徴量の作成 5. LightGBMのチューニング 数々の困難 33
  34. 34. copyright Fringe81 Co.,Ltd. ● 決してリッチとは言えない行動ログデータから他の競技者と差別 化を図る特徴量を作らないといけない ● 色々なアイデアを思いついたとしても、特徴量の処理を書くのは 複雑になって管理できなくなりがち 困難4: 特徴量の作成 34
  35. 35. copyright Fringe81 Co.,Ltd. 質素な行動ログ 35 カラム名 説明 user_id ユーザID product_id 商品ID event_type 行動ID (閲覧, 広告クリック, CV, カート) ad 広告経由か否か time_stamp タイムスタンプ ● ユーザのデモグラ(年齢・性別・居住地など)がない ● 商品のカテゴリや説明文もない
  36. 36. copyright Fringe81 Co.,Ltd. ● ユーザの行動した平均時間帯 ● 商品のクリックされた平均時間帯 ● 曜日ごとのユーザの行動回数 ● 曜日ごとの商品の閲覧回数 ● 最初/最後ログに現れてからの日数 … タイムスタンプの情報をフル活用 36
  37. 37. copyright Fringe81 Co.,Ltd. 時間帯の表現の工夫 cos sin 0時12時 9時 18時 ● 周期性のある数値は円周上に並べて(cos, sin)で表現 37
  38. 38. copyright Fringe81 Co.,Ltd. ● 過去ログから閲覧回数などの総和をとるときに直近の重みが強く なるように係数を掛ける 直近の行動情報を重視する工夫 38
  39. 39. copyright Fringe81 Co.,Ltd. ● 同一処理の繰り返し記述が無くせる ○ スケールが容易になる ⇛ 400個以上の特徴量を作成 ● クラス名を和名にして命名に悩まない ○ Python3系限定 解決: 1特徴量を1クラスで表現 39
  40. 40. copyright Fringe81 Co.,Ltd. 1. レコメンドにおける問題設計 2. 時系列データにおける訓練・検証・テストデータの構築 3. 保守性の高い分析コードの設計 4. 特徴量の作成 5. LightGBMのチューニング 数々の困難 40
  41. 41. copyright Fringe81 Co.,Ltd. ● Microsoftが関わるGradient Boostingの高速・高精度実装 ○ https://github.com/Microsoft/LightGBM ● Kaggleでも今はxgboostを超える人気(?) ● tree-baseなので特徴量のスケールに影響受けない ● カテゴリ特徴量をダミー化せずに扱える LightGBM 41
  42. 42. copyright Fringe81 Co.,Ltd. ● gradient boostingの特徴として訓練サンプルに過適合しやすい ● 精度と複雑さをコントロールするハイパーパラメータがたくさんがあ る 困難5: LightGBMのチューニングが大変 42
  43. 43. copyright Fringe81 Co.,Ltd. ● 過学習がしやすくハイパーパラメータの調整が重要 ● validationデータを与えるとearly_stoppingで過学習始まった時点 でストップしてくれる機能が便利 ● ただしvalidationデータ分の学習データが減ってしまう 解決: LightGBMのearly stopping train train valid LightGBM 分割 学習 early_stopping用 ⇛学習に使われない 43
  44. 44. copyright Fringe81 Co.,Ltd. 解決: LightGBM による 5-fold アンサンブル train fold3 fold2 fold1 fold5 fold4 LightGBM train valid LightGBM train valid ・・・ average 5-foldの場合、 計算時間5倍になるので注意! 44
  45. 45. copyright Fringe81 Co.,Ltd. 最終結果 45
  46. 46. copyright Fringe81 Co.,Ltd. ● めちゃくちゃ時間がかかる ● 時間をかけた分だけスコアは伸びる ● 入力データの前処理、特徴量エンジニアリング>予測モデル ● コンペで培ったノウハウはかなり部分を業務に活かせた 所感 46
  47. 47. copyright Fringe81 Co.,Ltd. ● 観測済みペアと未観測のペアのスコアリングを2段階に分ける ● 時系列の行動ログにおけるデータの分割は複雑 ● 分析の各機能はモジュール化して実行スクリプトは簡潔にする ● タイムスタンプからたくさん特徴量作れる ● Featureはクラス化して特徴量作成をスケーリング ● LightGBMはアンサンブルして過学習を抑える まとめ 47
  48. 48. copyright Fringe81 Co.,Ltd. ご清聴ありがとうございました 48
  49. 49. copyright Fringe81 Co.,Ltd. ● Python ○ pandas, numpy, scikit-learn, LightGBM ● Google Compute Engine ○ CPU 8 core, RAM 52GB ○ 無料クレジット枠で収まった 環境 49
  50. 50. copyright Fringe81 Co.,Ltd. DataProcessor DataSet Feature Feature Feature ・・・ Series Series Series DataFrame apply concat 入力特徴量 50
  51. 51. copyright Fringe81 Co.,Ltd. SIGNATE (旧・DeepAnalytics) について ● 日本で数少ないデータ分析コンテストを主催している サービス https://signate.jp/ ● 2018年4月からサービス名を「SIGNATE」に変更 野良データサイエンティスト 企業 データ・賞金 強い予測モデル データ・賞金・名誉 予測モデル 51

×