警察庁オープンデータの前処理と死亡事故発生予測のための機械学習について

はじめに

先日、近所の幹線道路の信号付き横断歩道を横断しようとした際に、2メートルほど先で回避不能な速度で車が赤信号を無視して横断歩道を突っ切きるという非常に恐ろしいイベントに遭遇しました。
そこで、私は「このイベント、何回かあったら死亡事故が起きるぞ」と思いました。警察署に近隣道路の不満について電話をしてみたのですが、「警察もちゃんと考えて取り締まっていたり対策してますので」と言われ、何の成果も獲れない電話となりました。
そのようなモヤモヤの中、私は民間でできることは「客観的なデータでもって、エリア、曜日、天候、時間帯ごとの、死亡事故のリスクを見積もり、それを公開して注意喚起していくこと」なのではないかと思うに至りました。
よって、警察庁が公開している交通事故のオープンデータについて、その前処理と機械学習によるエリアの死亡事故の発生予測などについて記していきます。

前処理のためのデータやコードはこちらのGitHubにあります。
https://github.com/KamonohashiPerry/traffic_accident_analysis
スターを10個以上いただけて、データ作って良かったなと思いました。

目次

・データについて
・先行研究について
・前処理について
・EDAからわかること
・機械学習
・さいごに

データについて

2019年と2020年の交通事故に関するデータが警察庁よりオープンデータとして公開されています。
オープンデータ 2020年(令和2年)
オープンデータ 2019年(平成31年/令和元年)

どのようなデータかというと、
それぞれ2019年と2020年の間に発生した全国の事故について、発生した状況(時、場所、天候)やその結果に関するデータからなり、項目の数としては58個とオープンデータとしてはかなり豊富な情報量となっています。

データは本票、補充票、高速票の3つからなるのですが、今回は本票だけを用います。
高速道路の精緻な分析をしようと思うと、高速票を繋ぐ必要がありますが、私の目的は一般道にあるので、繋がないものとします。

先行研究について

事故の予測に関する先行研究

交通事故の分析に関する研究は以下のものがあり、参考にしました。
死亡事故を予測するという問題設定として、その特徴量としては場所、時間帯、曜日、場所かつ時間、場所かつ曜日かつ時間、天候、季節、風速・風向き、車線の数、歩道の有無、制限速度などを用いていることがわかりました。
そして、データをクラスタリングするためにDBSCANを用いたり、不均衡データであることから、アンダーサンプリングを行ったりしているようです。
最後に、アルゴリズムはSVMやロジスティック回帰、深層学習と色々と使われているようです。

・Live Prediction of Traffic Accident Risks Using Machine Learning and Google Maps

・Data-Driven Urban TrafficAccidentAnalysis and Prediction Using
Logit and Machine Learning-Based Pattern Recognition Models

・A Deep Learning Approach for Detecting Traffic
Accidents from Social Media Data

・A BASIC STUDY ON TRAFFIC ACCIDENT DATA ANALYSIS USING
SUPPORT VECTOR MACHINE

・Predicting Crash Injury Severity with Machine Learning Algorithm Synergized with Clustering Technique: A Promising Protocol

・Comparison Analysis of Tree Based and Ensembled Regression Algorithms for Traffic
Accident Severity Prediction

その他

・Taxi Demand Prediction System

・2019年04月号トピックス 警察庁のオープンデータを活用した独自AIによる犯罪発生予測

前処理について

ソースコードに関しては、GitHubに上げておりますので、
.pyなら
https://github.com/KamonohashiPerry/traffic_accident_analysis/blob/main/src/preprocess.py
https://github.com/KamonohashiPerry/traffic_accident_analysis/blob/main/src/preprocess_second.py

.ipynbなら
https://github.com/KamonohashiPerry/traffic_accident_analysis/blob/main/Traffic_Accident_Analysis.ipynb
を参照ください。

基本方針

・天候、時間帯、曜日、平日、道路の形状、スピード制限など、事故の結果(死亡の有無)を明らかに予測できそうなもの以外を特徴量にします。
・メッシュ単位での過去の事故に関する情報に関する特徴量の作成(学習を行う時点よりも過去の時点のデータのみ利用)

詳細

・事故の発生日時のdatetime化(列で年・月・日・時・分が分かれているため)
・マスタ情報(PDF)をもとにマスタのIDを名前に変換
・緯度経度のデータについて、度分秒から度への変換を行い、3次メッシュ(1km四方)のデータを作成
・メッシュ単位での特徴量として、過去の事故発生件数、死亡数などを集計
・メッシュ単位での特徴量として、過去に発生した事故に関するもろもろのデータの集計(そのメッシュで事故を起こした平均年齢や事故が発生してきた時間帯など)
・もろもろの変数のダミー変数化

EDAからわかること

EDAに関しては.ipynbのみで行っております。
https://github.com/KamonohashiPerry/traffic_accident_analysis/blob/main/Traffic_Accident_Analysis.ipynb

私がよく分析で使うのは、データの該当件数とカテゴリごとの率の可視化なのですが、以下の図の見方としては、青の棒グラフが各カテゴリの件数、赤の折れ線グラフが死亡率となっています。

都道府県


福井県、鳥取県、秋田県、島根県、岩手県などは死亡率が高そうです。

道路種別


農道(815件)や林道(88件)で起きる事故非常に死亡率が高くなるようです。

時間帯


夜間や明け方は死亡率が高くなるようです。

天候


霧の天候(294件)では死亡率が高くなるようです。

人口密集地かどうか


市街地ではないところでは死亡率が高くなるようです。

道路の形状


踏切-第一種(254件)はかなり死亡率が高くなるようです。カーブも死亡率が高くなります。そういえば実家の近くにも魔のカーブと呼ばれるところはありますし、事故も起きていました。

信号機のタイプ


点滅-3灯式(2566件)や点灯-押ボタン式(7703件)は死亡率が高いようです。

道路の幅


大きな交差点では死亡率が高い傾向にあります。単路に関しては一様な傾向ではないですが、小さい方が死亡率が高そうです。

道路の区切り


道路の区切りがペイントだけのケースは、中央分離帯がある場合よりも死亡率が高い傾向にあります。あと、中央線がポストコーン(チンアナゴみたいなやつ)だと死亡率が上がるようです。

歩道との区別


道路について歩道との区分がない場合に死亡率が高くなるようです。

速度制限


速度域が高くなるにつれ、死亡率が高くなるようです。あと、速度規制がされていないところも高くなっています。

曜日


土日の死亡率が高い。

祝日・その前日


祝日とその前日の死亡率は高い傾向にある。

以上のことから、得られた考察としては、
・土日や祝前日の道路はいつもより危ない
・夜間や明け方の道路は危ない
・制限速度の高い道路は危ない
・大きな交差点は危ない
・点滅信号は危ない
・カーブは危ない
・霧は危ない
でした。普段、出歩く際に意識しておくといいと思います。

機械学習

教師データを事故発生からの死亡有無(1or0)、特徴量を先行研究を参考にオープンデータから作れるものとして、
基本的には、LightGBMでの学習、ハイパーパラメータ探索、モデルの訓練(メッシュ番号でグループ化したクロスバリデーション)、テストデータ(学習は2020年11月まで、テストは2020年12月以降としている)での予測、日本地図への可視化を行っています。

ソースコードはGitHubに上げてあるので、ここでは記しません。

.pyなら(学習のみ)
https://github.com/KamonohashiPerry/traffic_accident_analysis/blob/main/src/train_model.py

.ipynbなら(学習だけでなく、予測と日本地図への可視化もしている)
https://github.com/KamonohashiPerry/traffic_accident_analysis/blob/main/Traffic_Accident_Analysis.ipynb

10-foldのCVをメッシュ番号でグループ化して学習させた際のAUCです。高い部類に入りますが、今回は不均衡データなので、抜群に当たっている感じではないです。


事故の死亡率は、0.9%なので、この予測の場合、2.2%が死亡すると当てれているということになります。また、予測から、全体の72%の死亡事故を当てているという結果です。
この性能に関しては今後、もっと高めていく余地はいくらでもあると思います。

こちらは、テストデータでの予測スコアの階級値(青い棒グラフ)と実際の死亡率(赤い線グラフ)を示したものです。スコアが高いものは信じてもいいかなぁと思いました。

特徴量重要度の上位10件は以下の通りです。

時間帯とか、防護策とか、信号機のタイプとか、市街地かどうかなどが予測に役立っているようです。

死亡事故発生を予測した確率を日本地図の関東エリアにプロットしたものが以下の図になります。

市街地のほうが死亡事故が起きやすいように見えますね。

東京都だけに絞ってみましたが、危険なエリアは都心に点在はしていますが、郊外のほうが死亡率が高そうです。

さいごに

交通事故にあいかけて、その怒りの感情を警察庁のデータにぶつけてみましたが、死亡事故が起きやすい条件などがある程度見えてきたと思いました。もちろん、なんとなく思っていた傾向もあったのですが、数字でハッキリと出せるのは良いですね。今後、旅行などをする際に、確率の高いエリアを警戒して行動するようにしたいです。
そして、地図への可視化は普段の仕事でほとんど行わないのですが、こうしてデータに触れて可視化の練習ができたのも有意義に思いました。
この警察庁のデータは分析するまでに工数がかかるデータとも言えるので、この記事をとっかかりとして、オープンデータの分析に挑戦して安全な生活を送る上での知見をシェアしていけると良いな、というか民間としてはこれくらいしかできないなと思っています。

参考情報

・[第3版]Python機械学習プログラミング 達人データサイエンティストによる理論と実践 (impress top gear)
・Pythonでプロットした地図を出力する
・Pythonで度と度分秒を相互に変換する

Recommender Systems: The Textbookの要点まとめ(随時更新)

はじめに

レコメンド関連の書籍を探していた際に、
Recommender Systems: The Textbook (English Edition)の無料公開されているPDFを見つけたので、それについて読んでは追記するスタイルでメモを残していこうと思います。(すごく長くなる予感)

これまで読んできたレコメンド関連の本の中では、説明が丁寧だったり事例が豊富に思います。数式はあまり出てこないですが、言葉でちゃんと説明しようとしているのが感じられます。『AIアルゴリズムマーケティング 自動化のための機械学習/経済モデル、ベストプラクティス、アーキテクチャ (impress top gear)』のレコメンドの章もわかりやすく幅広いトピックが扱われていますが、それに匹敵する本にも思います。

第1章(An Introduction to Recommender Systems)

Goals of Recommender Systems

  • 1.ユーザーとアイテムの組み合わせの評価値の予測問題
    過去のユーザーのプリファレンスデータを使って学習する。未知のアイテムに関しては行列補完問題とも見なせる。
  • 2.上位k個の推薦問題
    あるアイテムに対して、あるユーザーの上位k個のアイテムを推薦する。

推薦システムの第一の目的はプロダクトの売上向上。

  • 推薦システムの運営上ないし技術的な目的
    1.関連性(Relevance)
    2.新規性(Novelty)
    3.意外性(Serendipity)
    4.推薦の多様性(Diversity)
  • 推薦システムの例
    1.GroupLensの推薦
    2.Amazon.comの推薦
    3.Netflixの映画推薦
    4.Googleニュース推薦
    5.Facebookの友達推薦

Basic Models of Recommender Systems

  • 協調フィルタリング(Collaborative Filtering)
    1.メモリーベース
    ・ユーザーベース協調フィルタリング
    ・アイテムベース協調フィルタリング
    2.モデルベース
  • コンテンツベース(Content-Based)
  • ナレッジベース(Knowledge-Based)
    滅多に買われないようなアイテム(自動車、不動産)の際に考える。評価は使わない。その代わり、ユーザーの要望とアイテムの近さや、ユーザーの制約などを用いる。
    1.制約ベースの推薦システム
    2.条件ベースの推薦システム
  • デモグラフィック(Demographic)
  • ハイブリッド、アンサンブルベース(Hybrid and Ensemble-Based)
  • 評価の種類
  • 明示的な評価と暗黙的な評価
  • 欠損値分析との関係性

Domain-Specific Challenges in Recommender System

  • コンテキストベース(Context-Based)
    時間や場所、ソーシャルデータを使う。季節性を考慮したりする。
  • 時間依存(Time-Sensitive)
    1.時間と共に評価は変わる。流行りすたりがある。
    2.特定の時期だけ、特定のアイテムの評価があがることはある。(レインコート、ダウン)
  • 位置情報(Location-Based)
  • ソーシャル(Social Recommender System)
    ネットワーク構造やソーシャルでの繋がり、タグ、組み合わせに基づいている。

Advanced Topics and Applications

  • コールドスタート問題(Cold-Start Problem)
  • 攻撃耐性(Attack-Resistant)
    アルゴリズムをハックされると情報推薦の効率性が阻害される。本来、上がってくるべきものが上がらないので。
  • 集団への影響(Group)
    推薦アルゴリズムは個々人よりも集団のプリファレンスに影響を与える。
  • 複数の基準(Multi-Criteria)
    ユーザーは単一の基準でアイテムを評価はしない。
  • アクティブラーニング(Active Learning)
    ユーザーが評価をしやすいようにするための取り組み、たくさん過去に評価したユーザーがいた場合は、新しい映画に関して評価をしやすいように予測するとか色々。
  • プライバシー(Privacy)
  • 様々な適用領域
    小売、音楽、コンテンツ、web検索、クエリ、デジタル広告

第2章

TBD

第3章

TBD

第4章

TBD

第5章(Knowledge-Based Recommender Systems)

  • コンテンツベースは新しいアイテムの推薦には良いが、新しいユーザーには推薦できない。協調フィルタリングやコンテンツベースは過去の履歴といったデータをベースに扱うが、ナレッジベースはユーザーが何を求めているのかに基づいている。
  • 不動産や自動車、旅行商品などは滅多に購入しないため、評価のデータは十分に得ることができない。
  • 映画はレコメンドされた際に、その理由が明示されなくとも受け入れるが、不動産や自動車は詳細な情報抜きには、そのレコメンドを受け入れることは難しい。
  • ナレッジベースのレコメンドが有効なケース
    1.ユーザーの要望が明確なケース。協調フィルタリングやコンテンツベースでは満たせない。
    2.選択肢が幅広く商品の複雑さが大きい商品のケース。詳細な評価を得にくい。
    3.商品の評価が時間と共に大きく変わるケース。パソコンとか車はすぐ新しいものが出てきたりして評価が変わってしまう。
  • ナレッジベースのレコメンドにおけるユーザーとのコミュニケーション
    1.対話システム
    対話でのフィードバックループのコンテキストからユーザーのプリファレンスを把握する。
    2.検索ベースシステム
    質問に答えることでプリファレンスを把握していく。
    3.ナビゲーションベース
    ユーザーがアイテムに対して反応をしてしていき、その結果に応じて望んでいるアイテムに到達できる。

Constraint-Based Recommender Systems

  • アイテムの属性に関する強い要望や制約を識別する。
  • 制約ベースのレコメンドシステムにおける3つのインプット
    1.ユーザー固有の情報(デモグラ、リスク嗜好)、必須要件(バストイレ別とか)
    2.ナレッジベースの属性情報。アイテムに応じた属性を顧客の属性にマッピングする。
    直接:都心か郊外か→郊外→近隣のものを推薦
    間接:家族の人数→5人以上→寝室が2つ以上のものを推薦
    3.アイテムに関するデータを全部使う
  • 関連した結果を返す際の3つのアプローチ
    1.ユーザーの回答をもとに条件を類推し、ユーザーの要望に加える。(例えば、家族の人数が5以上と回答された場合に、寝室の数は3以上必要だろうとして要望に加える。)
    2.要望をもとにデータベースのクエリを生成
    3.ユーザーの要望に関連したカタログを抽出する
  • 対話のアプローチ
    1.インターフェースを通してユーザーのプリファレンスの初期値を得る。
    2.マッチさせたアイテムを並べてユーザーに示す。なぜそれを表示したのかの理由も付ける。
    3.条件緩和や追加の要望を受け付ける。レコメンドの件数が多すぎたら要件を増やして、少なすぎたら要件を減らす。
  • マッチしたアイテムの並べ方
    効用関数を使ったりする。
    $$ U( \overline V ) = \sum_{j=1}^{d}w_j \cdot f_j(v_j) $$
    \( w_j \)は評価のウェイト、\( v_j \)はマッチした属性の値。
  • 受け入れられない結果や空集合への対応
  • 制約の追加

Case-Based Recommenders

  • 制約ベースのレコメンドとは違い、強い制約がない。良いレコメンド結果になるまでユーザーの要望を繰り返し修正していくアプローチとなる。
  • ケースベースのレコメンドの場合の重要な要素
    1.類似度の指標

    $$f(\overline{T}, \overline{X}) = \frac{\sum_{i \in S}w_i \cdot Sim(t_i, x_i)}{\sum_{i \in S} w_i} $$

    Sは属性の集合で、属性ごとに重みが違う。tはターゲット。xはあるアイテム。

    ・対称
    $$ Sim(t_i, x_i) = 1 – \frac{|t_i – x_i|}{max_i – min_i} $$
    ・非対称

    $$ Sim(t_i, x_i) = 1 – \frac{|t_i – x_i|}{max_i – min_i} + \alpha_i \cdot I( x_i > t_i ) \cdot \frac{|t_i – x_i|}{max_i – min_i} $$

    ・多様性
    1から類似度を差し引いたものが多様性の尺度となる。
    $$D(\overline{X}, \overline{Y}) = 1 – f(\overline{X}, \overline{Y})$$
    2.批評
    ・推薦結果がユーザーに示されてから、批評を通じてフィードバックを受ける。
    ・単純な批評:特徴の一つを変更してもらう
    ・複合的な批評:複数の特徴量を変更してもらう
    ・動的な批評:データマイニングからフィードバックを掴み取る(アソシエーション分析とか)

Persistent Personalization in Knowledge-Based Systems

  • ナレッジベースのレコメンドでの過去ログの蓄積があれば、効用関数や類似度関数、制約の提案、動的な批評に関してパーソナライズすることが可能。

第6章

TBD

第7章

評価の目標に正確度がよく使われるが、ユーザー体験において重要な指標は目新しさや信頼度やカバー範囲やセレンディピティなど、それ以外の指標によるところが多い。正確度は大事な指標ではあるが、それだけでは良いレコメンドシステムを作ることは難しい。

Evaluation Paradigms

レコメンドシステムの評価方法にはユーザースタディ、オンライン評価、オフライン評価の3つがある。

  • ユーザースタディ
    特定のタスクを行い、レコメンドシステムを触ってもらい質問をするなどして、ユーザーからのフィードバックをもらう。ただし大規模に行うとコストもかかるし、参加する時点でユーザーの性質が違う可能性もあり、バイアスが含まれる可能性がある。
  • オンライン評価
    レコメンドシステムを実装したサイトなどで、ユーザーのグループをAとBに分け、アルゴリズムAとアルゴリズムBをそれぞれ用いて、その結果としてコンバージョンレートなどを比較する。バンディットアルゴリズムを使うのも良い。ただ、オンライン評価は実装含めコストがかかる。
  • オフライン評価
    レコメンドアルゴリズムにおいて最もポピュラーな評価方法で、過去のデータにおける評価を行う。当然、オンライン評価のほうが望ましいが、統計的にロバストであろうと観点で非常によく使われる。ただし、セレンディピティや目新しさを評価することは難しい。

General Goals of Evaluation Design

  • Accuracy
    モデルの訓練にも、評価にも使われる。レコメンドシステムにおいても、機械学習の分類や回帰タスクと同様に、ホールドアウトや交差検証などを行って評価する。
    あるユーザーのあるアイテムに対する評価の誤差を以下の式で表す。
    \(e_{uj} = \hat r_{uj} – r_{}uj \)
    なお、Eは評価対象の集合とする。その際、正確度の評価は以下のようになる。

    $$ MSE = \frac{\sum_{(u, j) \in E} e_{uj}^2 }{|E|} $$

    $$ RMSE = \sqrt{ \frac{\sum_{(u, j) \in E} e_{uj}^2 }{|E|} }$$

    なお、他にもランキングベースの評価方法もある。
    ただ、精度が高くても、ユーザーが絶対に買うであろうアイテムしかレコメンドできない場合は、レコメンドシステムの意味合いとしては薄れる。

  • Coverage
    レコメンドシステムが精度が高すぎる場合、一部のアイテムは一部のユーザーに全く推薦されなくなる。
    k点以上の評価を付けるであろうと予測したユーザーの割合は、ユーザー空間でのカバレッジと呼ばれる。
    一般的に、近傍ベースの手法を考えた際に、近傍を広げた場合、精度は落ちてしまうが、カバレッジは高くなる。ようは、精度とカバレッジはトレードオフの関係にある。
  • Confidence and Trust
    予測した評価の範囲として信頼区間が与えられる。予測した値の誤差が信頼区間にマッチしているかどうかで測る。同じアルゴリズムにおいて、信頼区間が狭いものほど良いと判断する。ただし、予測が正確だとしても、評価をユーザーに信じてもらえないと役に立たない。推薦理由がロジカルかどうかが重要となる。
  • Novelty
    ユーザーがこれまで気づかなかったような推薦ができているかどうかを表す指標。オンライン評価として画面上でユーザーに回答してもらうという方法で測るケースが多いが、いつでもその評価を実行することはできない。
    一方、オフラインであれば、それが可能となる。現時点よりも将来に選びそうなアイテムを推薦できるようになれば、それがノベルティに繋がる。
    過去に評価されているアイテムを、正しく推薦されてしまうとノベルティに関するペナルティが与えられるとする。将来時点で評価されるアイテムを正しく推薦できたらノベルティに関してリワードが与えられると考える。ようは将来と過去の予測の正確度の差分でもってノベルティを測ることとなる。
  • Serendipity
    セレンディピティは幸運な発見を意味する。レコメンドの成功における驚きのレベルを測る。セレンディピティはノベルティよりも強い条件で、セレンディピティがある場合、そのアイテムは目新しいが、逆は真ではない。
    オンライン評価の場合、ユーザーからのフィードバックで意外性があったかどうかを測ればいい。
    オフライン評価の場合、コンテンツベースで選んだものではないアイテムがユーザーに選ばれた場合に、セレンディピティがあると見なすことができる。コンテンツベースのレコメンドとそうでないレコメンドの結果の二つを用意する必要がある。
  • Diversity
    推薦リストの中でのアイテムの多様性を測る。多様性が高まれば、ユーザーのニーズを捉える可能性が高まると考えられる。
    多様性はコンテンツを元にしたアイテム間の類似度で測る。全てのアイテムのペアに対しての平均的な類似度が多様性を表す。
  • Robustness and Stability
    偽の評価や時間とともに急激にデータが変化した際に、レコメンドシステムが影響をあまり受けない場合、そのレコメンドシステムはロバストで安定していると見なすことができる。レコメンドシステムの利用者の中には、ランキングを不正に高めることが自身の利益に繋がることがある。
  • Scalability
    近年、暗黙フィードバックも考慮すれば、レコメンドシステムを構築するためのデータは比較的簡単に入手できるようになった。そこで、データの大きさがもたらす問題に関して注意を払う必要がある。
    1.機械学習モデルの訓練時間
    2.予測(推論)時間
    3.計算の際に要求するメモリの量

Design Issues in Offline Recommender Evaluation

  • レコメンドシステムを開発するに際して、データは3つのパーツに分割される。
    1.訓練データ(モデルの構築)
    2.検証データ(モデル選択・パラメータチューニング)
    3.テストデータ(二度漬け禁止)
  • ※豆知識:Netflix Prizeのデータは学習データとテストデータがかなり違っていたらしい。学習データに古いレーティングが入っていて、テストデータに新しいレーティングがあるという状態だったとのこと。
  • Segmenting the Rating for Training and Testing
    ・Hold-Out
    ・Cross-Validation
  • Comparison with Classification Design
    回帰や分類タスクと同様にサンプルセレクションバイアスの問題がはらんでいる。

Accuracy Metrics in Offline Evaluation

  • レコメンドシステムの評価方法としてはランキング系のものが良いが、わかりやすさを重視するならばRMSEが良い。
  • Measuring the Accuracy of Ratings Prediction
    ・MSE
    ・RMSE
    ・MAE
    ・NRMSE
    ・NMAE
  • RMSE versus MAE
    RMSEは異常の影響を受けやすい。一方でMAEは影響を受けにくい。
  • Impacr of the Long Tail
    主要なアイテムによって評価は影響を受けるが、売り上げの大半はロングテールなアイテムであり、主要なアイテムがロングテールなアイテムに悪影響を与えることがありうる。
  • Evaluating Ranking via Correlation
    レコメンドシステムはユーザーに対しアイテムのランキングを提供し、上位k個のアイテムが推薦されることとなる。
    ランキングのための評価指標について。
    1.スピアマン順位相関係数
    2.ケンドール順位相関係数
  • Evaluating Ranking via Utility
    効用関数ベースのランキング評価指標。
    $$ F(u, j) = \frac{max\{ r_{uj} – C_{u} , 0 \}}{2^{\frac{v_j – 1}{\alpha}}} $$
    ここで、\( C_{u} \)はユーザーの平均的な評価とされる。

    $$ R-score(u) = \sum_{j \in I_{u} F(u, j) } $$

    ・DCG(discounted cumulatiove gain)
    $$ DCG = \frac{1}{m} \sum_{u=1}^{m} \sum_{j \in I_u, v_j \leq L } \frac{g_{uj}}{log_2 (v_j + 1)} $$
    \( v_j \)はアイテムjの順位を表す。
    $$ g_{uj} = 2^{rel_{uj} – 1 } $$
    ここで\( rel_{uj} \)は実際の評価が使われることが多いとのこと。

    ・NDCG(normalized discounted cumulatiove gain)
    $$ NDCG = \frac{DCG}{IDCG} $$

Limitations of Evaluation Measures

第8章

TBD

第9章

TBD

第10章

TBD

第11章

TBD

第12章

TBD

第13章

TBD

[Python]データ分析業務で使いそうなコードまとめ(随時更新)

はじめに

仕事で使いそうなPythonのコードを残しておくドキュメントが欲しいなと思ったので、よく使うものをこちらに貯めていこうと思います。まだ19個しかないですが、30個を目標に追記していきます。

フォーマットとしては、
1.やりたい処理
2.コード
3.参考情報のリンク
の3つを1セットにしています。
まずは、自分自身や周りで仕事をしている人が楽をできるドキュメントになればいいなと思って作っていきます。

目次

・重複削除
・階級のデータを作りたい
・再起的にリストをコピーしたい
・ピボットテーブルでアクセスログから特徴量用のデータを作りたい
・データフレームのある列に対して特定の文字列で分割し、その任意のN番目のものを抽出したい
・データフレームの行単位で割り算を行いたい
・列単位で行を足し合わせて文字列を作りたい
・グループのレコードごとにidを割り当てたい
・正規表現で任意の合致した文字列で挟まれた文字列を抽出したい
・複数列の集計値同士で除した値が欲しい
・等間隔の実数の数列を作成したい
・スペース区切りの文字列において、ある単語の前後N個の語を抽出したい
・グループごとに文字列を結合したい
・文字列の置換をdict形式のデータで行いたい
・テキストを形態素解析してBoW形式のデータにして特徴量にしたい
・訓練データとテストデータで特徴量の数が足りない時に不足した変数を追加したい
・アクセスログのユーザーごとのレコードごとの累積和を計算したい
・選択したカラムで一気にダミー変数にしたい
・グループ化して平均値を計算し、プロットし、2軸でそれぞれのデータ数も載せたい
・参考情報

データセット

全体を通じて使うデータセットを生成する関数を用意しておきます。一つ目の
データはkaggleのBoston Housingのデータセットです。

二つ目はアクセスログのデータが欲しかったので、Google Analytics APIを使ってデータを抽出したものとなります。ここではソースコードを載せますが、皆さんは当然見れません。一応、GitHubにデータを上げておきます。

三つ目はテキストデータです。

前処理

重複削除

  • やりたいこと
    重複したデータを除外したい。最初に現れたレコードだけを残したい。
  • コード
  • 参考情報
    https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.duplicated.html

階級のデータを作りたい

  • やりたいこと
    任意の範囲に応じたラベルをつけた階級値を作りたい。
  • コード
  • 参考情報
    https://pandas.pydata.org/docs/reference/api/pandas.cut.html

再起的にリストをコピーしたい

  • やりたいこと
    リストをコピーした際に、コピーしたものを変更した際に、もとのものも変更されてしまうので、それを防ぎたい。
  • コード
  • 参考情報
    https://docs.python.org/3/library/copy.html

ピボットテーブルでアクセスログから特徴量用のデータを作りたい

  • やりたいこと
    集計されていないアクセスログをもとに、セッションidごとの触れたページを集計し、Bag of Words形式のデータフレームにしたい。これは機械学習の特徴量に使えるので便利。
  • コード
  • 参考情報
    https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.pivot_table.html

データフレームのある列に対して特定の文字列で分割し、その任意のN番目のものを抽出したい

  • やりたいこと
    pandasのデータフレームである文字列の列に対して特定のキーワードで分割し、そのN番目のものをデータフレームの列として持たせる。今回はURLのパラメータの後ろについている文字列を抽出している。
  • コード
  • 参考情報

データフレームの行単位で割り算を行いたい

  • やりたいこと
    各行の合計で、各行を割ることでレコード単位で重み付けを行いたい時や確率を計算したいときに良く使います。データはアクセスログをBag of Word形式したものを使います。
  • コード
  • 参考情報
    https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.div.html

列単位で行を足し合わせて文字列を作りたい

  • やりたいこと
    データフレームの列の要素をつなぎ合わせて文字列を作成したい。複合キーを作らないとデータを繋げない時などによく使います。
  • コード
  • 参考情報
    https://www.kato-eng.info/entry/pandas-concat-pk

グループのレコードごとにidを割り当てたい

  • やりたいこと
    アクセスログなどで、任意のユーザーの初回に触れたページや、N番目に触れたページなどを抽出しやすいように、ユーザーごとのログにidを付与したい。
  • コード
  • 参考情報
    https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.factorize.html

正規表現で任意の合致した文字列で挟まれた文字列を抽出したい

  • やりたいこと
    正規表現を用いて、文字列に対して「指定した文字列と文字列の間にある表現」を抽出するための処理です。URLのデータや規則性のあるテキストデータに対して特徴量を作りたい時に使えます。
  • コード
  • 参考情報
    https://docs.python.org/ja/3/library/re.html

複数列の集計値同士で除した値が欲しい

  • やりたいこと
    複数の列で集計した値同士を用いて、さらにそこから比率のデータを作りたい。ターゲットエンコーディングを行いたい場合に使える。
  • コード
  • 参考情報
    https://stackoverflow.com/questions/45075626/summarize-using-multiple-columns-in-python-pandas-dataframe

等間隔の実数の数列を作成したい

  • やりたいこと
    パラメータチューニングをする際に、各パラメータについて等間隔の実数列を作りたいときがあるので、その時に使うコード。
  • コード
  • 参考情報
    https://www.pythoncentral.io/pythons-range-function-explained/

スペース区切りの文字列において、ある単語の前後N個の単語を抽出したい

  • やりたいこと
    テキストマイニングをする際に、関心のある単語の前後N文字を抽出したい時がある。もちろん、関心のある単語の周辺の単語というものを特徴量にすることも良いと思われる。ここではMeCabによる形態素解析により分かち書きにする関数と共に紹介する。
  • コード
  • 参考情報
    https://stackoverflow.com/questions/17645701/extract-words-surrounding-a-search-word

グループごとに文字列を結合したい

  • やりたいこと
    テキストマイニングなどで、任意のグループごとのテキストデータをスペース区切りで繋ぎたいときがあります。任意のグループごとのテキストを一気に連結できて便利です。これを形態素解析して特徴量にするのも良いと思います。
  • コード
  • 参考情報
    https://stackoverflow.com/questions/17841149/pandas-groupby-how-to-get-a-union-of-strings

文字列の置換をdict形式のデータで行いたい

  • やりたいこと
    事前に用意した置換のリストを使って、文字列の置換を一気に行いたい。
  • コード
  • 参考情報
    http://omoplatta.blogspot.com/2010/10/python_30.html

テキストを形態素解析してBoW形式のデータにして特徴量にしたい

  • やりたいこと
    任意の日本語のテキストとラベルの組み合わせがあるとして、テキストを形態素解析してTF-IDFを計算し、それを特徴量としてラベルを予測するということをやりたい。ここでは以前集めて、GitHubに載せてあるデザイナーズマンションのデータを使い、MeCabで形態素解析をしたあとに、TF-IDFを計算し、それを特徴量にしてsklearnで簡単に予測をし、リフト曲線を描いている。
  • コード
  • 参考情報
    https://scikit-plot.readthedocs.io/en/stable/metrics.html

訓練データとテストデータで特徴量の数が足りない時に不足した変数を追加したい

  • やりたいこと
    訓練データとテストデータの変数の数が違う時に、そのままではモデルを使えないので、補うために使う。
  • コード
  • 参考情報
    なし

アクセスログのユーザーごとのレコードごとの累積和を計算したい

  • やりたいこと
    アクセスログや購買データなどで、レコードごとの累積の値を計算したいときに使う。時系列に従いどんどん足されていく。
  • コード
  • 参考情報
    https://ohke.hateblo.jp/entry/2018/05/05/230000

選択したカラムで一気にダミー変数にしたい

  • やりたいこと
    ダミー変数を一気に生成したい。名前も一気に付けたい。
  • コード
  • 参考情報
    なし

グループ化して平均値を計算し、プロットし、2軸でそれぞれのデータ数も載せたい

  • やりたいこと
    EDAの時に、グループ化して平均値などを計算するだけでなく、該当するデータ数も2軸でプロットしたい。
  • コード
  • 参考情報
    なし

参考情報

前処理大全[データ分析のためのSQL/R/Python実践テクニック]
はじめてのアナリティクス API: サービス アカウント向け Python クイックスタート
カモノハシペリー
ペリー|フィニアスとファーブ|ディズニーキッズ公式

Uncertainty in Gradient Boosting via Ensembles[A4一枚まで備忘録]

A4用紙1枚にまとめるイメージでメモを残そうという取り組み。

今回は機械学習でとりわけ、回帰の問題を扱うことが仕事であった際に参照できるメモの一つとして残したい。
先日、Catboostのドキュメントに参考文献としてUncertainty in Gradient Boosting via Ensemblesの存在を知った。業務において、価格の予測とか、期間の予測とかマーケティングのデータでも良く扱うものなので、分類だけでなく回帰についてもバランス良く知見を貯めたいところ。

目次

Abstract
Introduction
Background and related work
Generating ensembles of GDBT models
Experiments on Synthetic Data
Experiments on classfication and regression datasets
Conclusion
Broader Impact

Abstract

機械学習のモデルは予測において点推定しかしないが、実務上は不確実性を定量化したいニーズがある。この研究では、予測の不確実性推定値を導出するためのアンサンブルベースの枠組みが紹介されている。予測における不確実性は「データに起因する複雑さとノイズの不確実性」「特徴空間において、情報がないことに起因する不確実性」に分解される。
手法としては確率的勾配ブースティングと確率的勾配ランジュバンブースティング(SGLB)が扱われている。SGLBは一つの勾配ブースティングモデルからのアンサンブルを可能にし、モデルの複雑さを減らすことができる。また、予測性能の向上について様々なデータセットを使って示されている。

Introduction

一般的な勾配ブースティングについて、回帰の際に点推定しか返さないことを挙げている。NGBoostについても言及している。NGBoostなら、勾配ブースト決定木(GBDT)を訓練して平均値を返せるとのこと。ただし、データの不確実性に起因する不確実性しか捕捉できないという問題がある。モデルに関する知識の欠落によって生じる不確実性に関して扱うことはできない。近年ではニューラルネットワークを用いて知識を起因とする不確実性の研究がなされているらしい。今回扱う、アンサンブルアプローチは全体の不確実性を「データの不確実性」と「知識の不確実性」に分解する。扱うモデルは確率的勾配ブースティングと、確率的勾配ランジュバンブースティング(SGLB)となっており、SGLBの利点として、漸近的に真のベイジアン事後分布からサンプリングされることが挙げられている。また、SGLBによって1つの勾配ブースティングのみをモデルを使ってアンサンブルをすることができるとされている。これにより計算の複雑さを減らすことができる。結果として、予測性能が高まり、誤りやドメインの外側のデータの入力の検知ができるようになったとされている。

Background and related work

  • ベイジアンのアプローチ
    ベイズ統計学を使っている。予測の多様性について考察することで、知識の不確実性の推定を行うことができるとしている。さらに、確率モデルのアンサンブルを行なっている。アンサンブルモデルの不一致さ、広がりの程度が知識の不確実性につながるとしている。事後分布の近似のための研究が色々となされ、ニューラルネットワークのモデルなども使われた。モデルの事後分布をもとに、予測の事後分布を手に入れる。予測の事後分布のエントロピーが、予測の不確実性を推定する。知識の不確実性は、全ての不確実性からデータの不確実性の期待値を差し引いた相互情報量で表される。確率的な回帰モデルのアンサンブルを考える時、予測事後分布のエントロピーと相互情報量を推定することができない。代わりに総変動の法則に従ってなら推定することができるが、1~2次のモーメントに基づいているだけなので、高次元での不確実性に関する見落としが起きうる。
  • 勾配ブースティング
    弱学習器は浅い決定木によって形成される。ただ、勾配ブースティングの回帰モデルは点での予測しかしない。予測の不確実性に関する研究はほとんどされていない。近年、NGBoost (Natural Gradient Boosting)が登場し、予測の不確かさを推定することができるようになった。NGBoostは入力変数xが与えられたもとでの、出力変数の条件付き事後分布の推定を行ってくれる。

Generating ensembles of GDBT models

NGBoostはデータの不確実性を捉えることができるものの、知識の不確実性については捉えることができない。
知識の不確実性を捉えるための方法としては、事後分布からサンプリングされた予測モデル(GBDT)のアンサンブルが挙げられる。
そもそもGBDT自身が木のアンサンブルであるが、そのGBDTのアンサンブルを考える。

アンサンブルをする方法としては、確率的勾配ブースティングのアプローチで生成された独立なモデルを扱うことがあげられている。
もとのモデルにノイズを注入して、出力をぶれさせることで予測の分布を得ようとしている。ただ、これは事後分布の推定を保証しないらしい。

ただし、確率的勾配ランジュバンブースティング(SGLB)アルゴリズムを用いることで真の事後分布からGBDTモデルをサンプリングすることができるらしい。
非凸の損失関数においての最適化の収束のために、確率的勾配ランジュバン力学が用いられているとのこと。ランジュバン力学ってなんだろうか。

確率的勾配ブースティングとの違いは2つある。

  • 1.ガウシアンノイズが勾配に明示的に加えられている。
    • 正規分布の平均は0で分散に逆拡散温度というものがある。ノイズをコントロールするものであることに間違いはない。確かに物理っぽい。STANのリープフロッグとかを思い出した。このノイズが最適値を見つけるのに役立つらしい。
  • 2.ブースティングモデルの更新式に正則化パラメータを設けている。
    • 定常分布に弱く収束していくマルコフ連鎖にパラメータが従うらしい。

対数尤度に正則化項が残るものの、比例するらしく、真の事後分布に従うと見なせるらしい。

確率的勾配ブースティングや確率的勾配ランジュバンブースティングは計算する上で重大なオーバーヘッドが生じるらしくイタレーションを減らすなど質を下げたり複雑さを増したりする必要があるとのこと。それを避けるために、仮想SGLBアンサンブルというものが提案されている。

SGLBアルゴリズムのイタレーションごとのパラメータは弱く定常に収束するマルコフ連鎖に従うことから、それらをモデルのアンサンブルと見なす。
しかしながらモデル同士が強く相関してしまうので、アンサンブルの質が下がる。ただし、各々のパラメータのK番目の集合のみを使うことで克服できるとある。
K番目のパラメータ集合のみのモデルで構築したアンサンブルを仮想アンサンブルと呼んでいる。

Experiments on Synthetic Data

ここではGBDTモデルのアンサンブルアルゴリズムを合成データを用いて実験している。
合成データとしては、以下の2つの1次元データセットが扱われている。

  • 合成データセット
    • 分散が増加していく絶対値x
    • 分散が減少していく絶対値x
  • 比較するモデル
    • SGLB
    • SGB
    • vSGLB(仮想SGLB):SGLBから生成
  • 結果
    • 分散が減少していく絶対値xのケースだと、データの不確実性に関して、SGBではサンプルの領域外で過剰に不確実性が増してしまう。
    • 分散が増加していく絶対値xのケースだと、知識の不確実性に関して、SGBではサンプルの領域外で不確実性が増してしまう。

サンプルの領域外のほうが、領域内よりも不確実性が大きいはずだが、実験データではそうではないらしい。

Experiments on classfication and regression datasets

GBDTモデルのアンサンブルアルゴリズムを色々なデータのいろいろなタスク(回帰、分類)で予測性能をみている。

  • タスク
    • 回帰タスク
    • 分類タスク
  • データセット
    • 18種類くらいある。(Wineとか、解約のデータとかAmazonのデータとかいろいろ)
  • 比較するモデル
    • SGB:このアンサンブルは10個の独立したモデルで、それぞれ1K本の木を持つ。
    • SGLB:このアンサンブルは10個の独立したモデルで、それぞれ1K本の木を持つ。
    • vSGLB(仮想SGLB):[500, 1000]の区間から50番目のモデルをアンサンブルに追加していっている。
  • どう実装しているか
    • CatBoostライブラリをベース
    • 分類では二値分類のクラスの確率分布を生成
    • 回帰では正規分布の平均と分散を生成
    • 負の対数尤度を最適化している
    • ハイパーパラメータはランダムサーチ
  • 何の指標を見ているか
    • 負の対数尤度
    • 誤分類率
    • RMSE
    • 不確実性の合計、知識の不確実性:Prediction-Rejection Ratio(PPR)というもので測る。どれくらい不確実性が誤差と順番と相関するかを測るらしい。100が最大で、ランダムだと0になる。
    • AUC:領域外のデータに関する評価に用いる。領域外データは合成して生成した。
    • 分類:負の対数尤度(NLL)
      • アンサンブル手法に軍配が上がるが、違いは軽微である。
      • 仮想アンサンブルが勝るときがある。
    • 分類:誤分類率
      • アンサンブル手法に軍配が上がるが、違いは軽微である。
    • 回帰:RMSE
      • アンサンブル手法に軍配が上がるが、違いは軽微である。
    • SGBやSGLBはパフォーマンスが良い。
      • vSGLBはわずかにパフォーマンスが悪い。自己相関があるなかでアンサンブルしているためパフォーマンス悪化が生じていると考えられる。
        • ただ単一モデルのものよりかは良い。
        • コストをかけずに精度を上げたいという観点ではvSGLBはよい選択肢となる。

    Conclusion

    この論文では、GBDTを用いたアンサンブルベースの不確実性推定モデルが扱われた。SGB、SGLB、仮想SGLBについて合成データや、分類や回帰のタスクにおいて比較した結果、アンサンブル手法が精度面で秀でているわけではないことが示された。
    しかし、知識の不確実性(モデルで十分に想定できていない不確実性)を扱う際にアンサンブル手法が役立つことがわかった。
    知識の不確実性を扱う場合に、計算コストの少ない手法として仮想のSGLBが提案され、精度において十分ではないが、低コストで知識の不確実性を扱う観点において有用であることが示された。

    Broader Impact

    • 不確実性の推定は、機械学習モデルをより安全に、より信頼できるものにするという観点で重要。
    • GBDT系の手法はニューラルネットワーク系の手法よりも計算コストが低くて良い。
    • 不確実性の推定が貧弱なものとならないように引き続き研究が求められる。

    追記

    不確実性について扱われた、ソースコードの載っている記事を集める。

    BLSTMを用いた文書分類でデザイナーズマンション予測に再挑戦

    はじめに

    仕事で深層学習を使うことはないのですが、扱える技術の幅を広げていきたいなと思い、BLSTMを用いた文書分類についてkerasでの簡単なサンプルコードをやってみようと思います。データは以前集めた、某不動産紹介サイトの賃貸マンションの設備に関する文書とそれがデザイナーズマンションかどうかのラベルを使います。そして文書内の単語からその文書がデザイナーズマンションかどうかを予測します。前回はAUCで83%だったので、それを超えれると良いですね。

    目次

    単純なRNNとは

    • モチベーション
      • フィードフォワード型のニューラルネットワークではうまく扱うことができない時系列データをうまく扱えるようにすること。
    •  特徴
      • 入力が互いに関係している(多層パーセプトロンの際は置かれていない仮定)
        • 直訳すると循環するニューラルネットワークとなる。
      • 最初の文の単語が2つ目、3つ目の単語に影響を与える可能性を考慮。
      具体的な関数の形としては、 $$ h_t = \tanh (W h_{t-1} + U x_t) \\\ y_t = softmax(V h_t) $$ で与えられる。
      \( h_t \)は隠れ層の状態を、\( x_t \)は入力変数を、\( y_t \)は出力ベクトルを表している。(他のアルファベットは重み行列)

    LSTMとは

    • モチベーション
      • 単純なRNNの勾配消失問題を解決するために提案された手法。
    • 特徴
      • 単純なRNNに置き換えることで性能が大幅に向上することも珍しくない。
        • 時系列データ、長い文章、録音データからなる長期的なパターンを取り出すことを得意としている手法。
      • 勾配消失問題に強い
      • Long Short-Term Memory:長短期記憶
        • 長期依存性を学習できるRNNの亜種。
        • 入力ゲート、忘却ゲート、出力ゲート、内部隠れ層という4つの層が相互に関わり合う。重要な入力を認識し、それを長期状態に格納すること、必要な限りで記憶を保持すること、必要なときに記憶を取り出すことを学習する。
          • 入力ゲート:内部隠れ層のどの部分を長期状態に加えるかを決める。
          • 忘却ゲート:長期状態のどの部分を消去するか決める。
          • 出力ゲート:各タイムステップで、長期状態のどの部分を読み出し、出力するかを決める。
    $$
    i = \sigma (W_i h_{t-1} + U_i x_t) \\
    f = \sigma (W_f h_{t-1} + U_f x_t) \\
    o = \sigma (W_o h_{t-1} + U_ox_t ) \\
    g = \tanh (W_g h_{t-1} + U_g x_t) \\
    c_t = (c_{t-1} \otimes f ) \otimes ( g \otimes i) \\
    h_t = \tanh (c_t) \otimes o
    $$ i:入力ゲート(input)
    f:忘却ゲート(forget)
    o:出力ゲート(output)
    \( \sigma \):シグモイド関数
    g:内部隠れ層状態
    \(c_t \):時刻tにおけるセル状態
    \(h_t \):時刻tにおける隠れ状態

    Bidirectional LSTMとは

    • モチベーション
      •  従来のRNNの制約を緩和するために導入。
    • 特徴
      • ある特定の時点で過去と将来の利用可能な入力情報を用いて訓練するネットワーク
        • 従来のRNNのニューロンをフォワード(未来)なものとバックワード(過去)なものとの2つに分ける。
          • 2つのLSTMを訓練している。
        • 全体のコンテキストを利用して推定することができるのが良いらしい。
          • 文章で言うと、文章の前(過去)と後(未来)を考慮して分類などを行うイメージ。
        • 人間もコンテキストを先読みしながら解釈することもある。
      • BLSTMは全てのシークエンスの予測問題において有効ではないが、適切に扱えるドメインで良い結果を残す。
      • 1997年とかなり歴史があるものらしい
    出典:Deep Dive into Bidirectional LSTM

    Bidirectional LSTMで文書分類

    今回は、BLSTMを使って、マンションの設備に関するテキスト情報から、そのマンションがデザイナーズマンションかどうかを予測します。全体のソースコードはGoogle Colabを御覧ください。

    データ

    データを確認してみると、
     
    今回のデータがテキストとラベルからなっていることがわかる。なお、データ数は1864件あり、そのうち16%がデザイナーズマンションです。

    前処理

    Google Colab上で形態素解析を行うために、MeCabをインストールする。
     
    これでMaCab NeologdをGoogle ColabのPythonで実行できます。
    テキストデータの前処理を行うために名詞だけを抽出してリスト形式で返す関数を定義します。
     
    ここで、語彙に関するデータを作成します。
     
    続いて、単語とそのインデックスからなるdict形式のデータを作成します。
     
    最後に、これまでに作成した語彙とそのインデックスのデータを用いて、実際に学習に使う入力データと出力データを作成します。
     

    実行

    先程作成したデータを訓練データとテストデータに分けます。
    ここで、AUCを計算するための関数を定義します。(まるまる拝借しました)
    続いて、kerasを用いて、ネットワークを構築し、コンパイルを行います。
      テストデータでの予測精度を確認します。
    実際のラベルとテキストデータを見比べてみます。
    LSTMの場合は、BLSTMに関する記述(1行)をネットワークから除外すれば良いので簡単に試すことができます。 せっかくなので比較してみたところ、AUCは0.841でした。BLSTMは0.844だったので、若干上回る程度のようです。 以前扱った記事ではデザイナーズマンション分類はAUCが0.83程度だったので、LSTMを使ったほうが精度が少しだけ高いようです。

    追記

    TensorBoardの検証のloglossを見てみます。 エポックに対してloglossが非常に荒れています。学習曲線としてはセオリー的にアウトなようです。一方で、検証のAUCはエポックに従って高まるようです。 AUCは良くなっているけどloglossが増え続けている。loglossが下がらないと過学習している可能性が高いので、これは過学習しているだけなのだろう。

    参考文献

     

    2019年に読んだデータ分析系の本の振り返り(21+1冊)

    はじめに

    2020年、あけましておめでとうございます。年末に自分自身を振り返ろうと思ったのですが、結局データ分析と勉強しかしていないわけで、書籍を振り返ろうと思うに至りました。私の知り合いのデータサイエンティストはだいたい全冊持っているであろうと思われますが、良い本だと思うので思い出していただければ幸いです。

    1.『ベイズモデリングの世界』(岩波書店)

    基本的に階層ベイズモデルを使って、個体ごとの異質性を考慮した分析手法が提案されています。前半はオムニバス形式で様々な先生がモデルの適用について執筆されており、後半では伊庭先生による階層ベイズモデルの講義になっています。途中でスタイン統計量による縮小推定の話があげられ、柔軟なモデリングのためには「階層化した方が少なくとも望ましい推定量が得られる」という数学的証明を捨てることもやむを得ないと書かれています。

    2.『トピックモデルによる統計的潜在意味解析 (自然言語処理シリーズ) 』(コロナ社)

    この本はトピックモデルの教科書というよりも、ベイズ推定の教科書という側面が強い印象があります。途中で出てくる数式は流し読みするのは難しく、最低2冊以上のノートが別途必要になると思います。一度でもLDAのパラメータを導出してみたいという方には良い教科書だと思います。疑似コードが提供されているので、それをもとにRやPythonでコーディングしていけば、一番シンプルなLDAが非常に短い行で実行できてしまうことに驚かれるかもしれません。人間が手を動かして推定アルゴリズムを導出しているからこそ、短いコードで済むということを実感できるはずです。

    3.『構造的因果モデルの基礎』(共立出版)

    グラフィカルなアプローチで因果推論を扱っている書籍です。Judea Pearl流の因果推論アプローチについて記すことを目的に書かれています。基礎と書かれていますが決して簡単ではありません。ただ、扱われる数学のレベルとしては確率と線形代数がわかれば大丈夫だと思われます。余談ではありますが、1章の相関関係と因果関係の事例紹介で「おむつとビールの話」が都市伝説ではなくきちんと記事としてWall Street Journalという雑誌に掲載されていたことが明らかにされています。

    4.『現場で使える!PyTorch開発入門 深層学習モデルの作成とアプリケーションへの実装 (AI & TECHNOLOGY)』(翔泳社)

    PyTorchを触ったことがないが、深層学習の手法について知っている層を対象とした本です。6章まではGoogleのColabで動かせるのでGoogleに課金することなく深層学習による回帰、CNN、GAN、RNN、Encoder-Decoderモデル、ニューラル行列因子分解をPyTorchで試すことができます。写経したものはこちら。転移学習や高解像度化や画像生成、文章のクラス分類、文書生成、機械翻訳などもできるので、PyTorchでこれくらいの量をコーディングしたらこれくらいのことができるのかという学びや、他の人の書いたPyTorchコードを読みやすくなるなどの便益は十分にあると思いました。

    5.『作ってわかる! アンサンブル学習アルゴリズム入門』(シーアンドアール研究所)

    会社で行っているPythonもくもく会用に買った本で、scikit-learnを使わずに機械学習のアルゴリズム(アンサンブル系)をコーディングするための本です。pythonのコードについて逐次、細かい解説が行われているわけではないので、1行1行自分でコメントを加えながら写経をしていけば力が付くという本かなと思われます。sklearnはそれはそれで素晴らしいですが、こういう本でフルスクラッチで修行できるのはいいですね。

    6.『数理統計学―基礎から学ぶデータ解析』(内田老鶴圃)

    統計検定1級を合格された方のブログで紹介されていた教科書です。理系の大学生レベルの数学知識があれば、数理統計学の基礎を学べると思います。中心極限定理の証明や、様々な分布の期待値や分散、様々な分布の性質について数式を用いてしっかり理解することができます。数式もほどよく端折られているので、無論ですがノートが数冊必要になります。各章毎にある練習問題も解くことで力が付くと思います。日本の大学の授業の教科書がこれだったらジェノサイド(再履修者の大量発生)が起きるんだろうなと思ってしまった。

    7.『44の例題で学ぶ統計的検定と推定の解き方』(オーム社)

    統計の検定に関してだけ扱った珍しい本です。第3部までは統計学の普通の教科書ですが、それ以降であらゆる検定の例題が44件も載せられています。パラメトリックな検定から、ノンパラメトリックな検定まで幅広く扱われています。一番気にいっているのは仮説検定法の分類の表です。これさえあれば、どのデータに対してどの検定を行えばいいかが一目瞭然です。

    8.『わけがわかる機械学習 ── 現実の問題を解くために、しくみを理解する』(技術評論社)

    機械学習の原理を手早く数式を交えて学べる本です。かゆいところに手が届いていると言うか、既出の教科書では捨象されがちな、条件付き確率における2変数以上の条件づけでの表現に紙面を割いていたりしてくれるのが嬉しいです。ある程度数学の話はわかるが、だいぶ忘れているビジネスパーソンには大変にありがたいコンテンツと言えると思います。ベイズ線形回帰に関しても行列を用いた、わかりやすい導出方法が紹介されています。またコラムで紹介されている、測度論にどう向き合えばいいかの著者の見解は参考になります。

    9.『Statistical Rethinking: A Bayesian Course with Examples in R and Stan (Chapman & Hall/CRC Texts in Statistical Science)

    R言語とstanを用いてベイズ統計学を入門レベルから学べる本です。各トピックごとにそれなりの紙面が割かれています。例題も豊富にあるので、線形回帰・MCMC・情報量基準・階層ベイズモデルまで、ベイズ統計学を基礎から応用までしっかりと学べると思います。youtubeで著者の講義も配信されているので、留学気分を味わえます。

    10.『scikit-learnとTensorFlowによる実践機械学習』(オライリージャパン)

    2019年に日本で開かれたML SummitでTFの開発者がおすすめしていた教科書です。前半部分で機械学習の入門から応用までをわかりやすい説明で学ぶことができます。数式は少ないですが、図とソースコード(Python)がちりばめられており、手を動かして理解を進めることができます。後半部分はTensorFlowを用いた深層学習の基礎を同様に手を動かして学ぶことができます。ただ、TFのバージョンも変わってきているので前半の説明をアテにして読むのも良いと思います。

    11.『AIアルゴリズムマーケティング 自動化のための機械学習/経済モデル、ベストプラクティス、アーキテクチャ (impress top gear)

    マーケティングへのデータサイエンスの適用に関する珍しい書籍です。ソースコードはついていないですが、業務で使う際のアイデアが手に入ることもあります。一般的な回帰、生存時間分析、オークション、アトリビューション分析、アップリフトモデリング以外にも、情報検索やレコメンデーションやトピックモデルなどマーケティングながら学際的なトピックも扱われています。レコメンドなどで使われる、ランク学習に関して詳しく書かれた書籍をあまり知らないので、この本はその点においてもありがたい本でもあります。

    12.『入門 統計的因果推論』(朝倉書店)

    ほぼ全ての章でグラフィカルなアプローチで因果推論を扱っています。例題も豊富なので、一つ一つ丁寧にやれば理解が捗ります。おそらく、例題の多さを含め一番丁寧にd分離性、do演算子、バックドア基準、フロントドア基準に関する説明をしてくれている本なのかなと思いました。グラフでの因果推論に関して初めての人でも、確率さえ知っていれば読み進めることができるはずです。また、途中で操作変数法の紹介もされ、経済学出身者としては読みやすい。ただ、傾向スコアのくだりや、DIDなどのくだりはあまり出てきません。あと、やってないですが章末の練習問題に対するSolution Manualが提供されているようです。

    13.『実践 ベイズモデリング -解析技法と認知モデル-』(朝倉書店)

    ベイズモデリングを様々な事例に適用する方法がオムニバス形式で記された本です。ワイブル分布や異質性を考慮した二項分布、無制限複数選択形式のアンケートデータに対する手法、トピックモデル、項目反応理論などが扱われています。マーケティングの実務で使える事例が多いように感じました。こちらはサポートサイトでRコードとstanコードが提供されています。あと、appendixにあるプレート表現の見方も参考になります。

    14.『機械学習スタートアップシリーズ ベイズ推論による機械学習入門 (KS情報科学専門書)

    機械学習などで用いるベイズ推論を扱った教科書です。入門とありますが、入門者は書かれた数式をそのまま見ていても頭に入らないのではないでしょうか。手を動かしてなんぼの本だと思います。ノート2冊は絶対に必要です。たぶん、数式の展開を丁寧に記すと倍以上の厚みの本になると思います。各々のモデルに関してグラフィカルモデルが記されているのや、サンプルコードとしてGitHubにJuliaで書かれたソースコードが提供されているのも良いです。

    15.『その問題、数理モデルが解決します』(ベレ出版)

    物語形式で、様々な問題に対して数理モデリングのアプローチが紹介されています。途中でマッチング理論やゲーム理論やオークションなども登場することから、経済学出身者も喜ぶ内容かもしれません。社会人になってからナッシュ均衡という言葉が書かれた本は中々出会って来なかった。

    16.『ヤバい予測学 ― 「何を買うか」から「いつ死ぬか」まであなたの行動はすべて読まれている』(CCCメディアハウス)

    2013年と結構古い本ですが、データ分析を様々な事象に対して適用した事例紹介本です。アップリフトモデリングへの言及もあり、こういったものに関して日本は何年も遅れてブームが来るんだなという実感を与えてくれた本でもありました。appendixに分析事例が147個ほどあげられているのも参考になります。

    17.『たのしいベイズモデリング2: 事例で拓く研究のフロンティア』(北大路書房)

    主にstanを用いたベイズモデリングによる分析事例が1と2で38本もオムニバス形式で載っています。ほとんどの事例で階層ベイズモデルが扱われています。2では若干マーケティングに近い内容の題材も扱われ、データサイエンティストの人にも嬉しい内容かもしれません。もちろんデータとstanとRのコードがサポートサイトで提供されています。

    18.『カルマンフィルタ ―Rを使った時系列予測と状態空間モデル― (統計学One Point 2)』(共立出版)

    状態空間モデルで時系列予測を行うための手法が記されている本です。RのKFASパッケージが全面に渡って扱われています。トレンドを考慮したり、カレンダー効果を追加したり、共変量を追加したりなど様々なアプローチが紹介されコードも伴っているわけですから、業務でも抜群に役に立ちました。

    19.『機械学習のエッセンス -実装しながら学ぶPython,数学,アルゴリズム- (Machine Learning)』(SBクリエイティブ)

    自分のいる会社で最低限の数学がわかると思われる若いメンバーに買ってもらうように言っている本です。微積分・線形代数だけでなく、カルシュ・キューン・タッカー条件(最適化数学)に関しても扱ってくれているので、ここで出てくる数学がわかれば大体の論文に立ち向かえると思います。さらに、Pythonの基礎もこれで学ぶことができるので一石二鳥な素敵な本ですね。また、最後の方でスクラッチでアルゴリズムを書くパートがあり、こちらも勉強になります。

    20.『機械学習のための特徴量エンジニアリング ―その原理とPythonによる実践 (オライリー・ジャパン)』(オライリー・ジャパン)

    機械学習における前処理の指針を与えてくれる本です。Pythonのコードが提供されています。例えばですが、「テストデータにだけある、新しい単語は取り除いてしまえばいい」などの細かいアドバイスが何気に嬉しいです。「Effectコーディング」「特徴量ハッシング」「ビンカウンティング」「バックオフ」「leakage-proof統計量」などは読むまで知らないところだったので勉強になりました。

    21.『データサイエンスのための統計学入門 ―予測、分類、統計モデリング、統計的機械学習とRプログラミング』(オライリージャパン)

    データ分析の仕事をする上で最低限必要な知識を幅広く抑えることができる本です。数式は少なく、ところどころ出てくるコードはR言語です。参考文献などがブログだったりするため厳密さがめちゃあるわけではないですが、業務で使う分には問題ないと思います。分類問題において、AUCなどの評価指標だけでなく、予測値自体の探索的分析のすすめなどが書かれており、参考になりました。また、特徴量エンジンとしてのk-NN法の話も面白いと思いました。

    [+α]『プログラマのためのGoogle Cloud Platform入門 サービスの全体像からクラウドネイティブアプリケーション構築まで』(翔泳社)

    Google Cloud Platformを初めて触るデータ分析者にはちょうど良い本です。説明もわかりやすいので、いきなりアカウントを作ってドキュメントを解読するよりかは戸惑いは減るはずです。この本を土台に、GCS・GCEを駆使してML系のAPIを呼び出して使うなどの最低限の操作は私でもできるようになりました。GCPの画面や機能もどんどん変わっていくので書籍を買ってもアレなんですが、歴史的な背景も若干記述されているので、それはそれで勉強になります。ただ、エンジニアにこの本を買うべきか聞いた際にネガティブな意見があったのですが、たぶん現役プログラマからすると簡単過ぎるからなんだろうなと思います。

    終わりに

    2019年もぼちぼち勉強できましたが、2020年もこれまで同様にノートとペンを大事にする勉強を続けていき、コーディングも分析ももっともっと数をこなして会社や社会に求められるようなデータ分析官を目指していこうと思います。あぁ、英会話などの勉強をする時間を作るのが難しい。

    [Stan]ロジスティック回帰の階層ベイズモデルとk-foldsクロスバリデーション

    はじめに

    stanは意思決定のための分析などでのパラメータ推定に使うことが多く、機械学習のために扱うことはありませんでした。ただ、過去にリク面などでお話したデータサイエンティストの方はstanで機械学習していて、クロスバリデーションもしているとの発言をされていました。
    先日、記事を漁っていたらstanでクロスバリデーションを行うためのコードを書いている方を見つけたので、その方のコードをもとに大人のirisであるwineデータを用いて、質の高いワインかどうかを分類するために階層ベイズでのロジスティック回帰モデルを回してみたいと思います。

    データについて

    UCI Machine Learning Repositoryにある、赤ワインの評価と成分のデータです。データに関する説明はワインの味(美味しさのグレード)は予測できるか?(1)で丁寧になされていますので、ご確認ください。今回は6点以上であれば1を、そうでなければ0を取るものを教師データとしています。

    分析方針

    今回は階層ベイズモデルを扱うことから、グループごとにロジスティック回帰のパラメータが異なるという仮定を置きます。そのために、citric.acidというデータを3つのカテゴリデータに変換して、それをグループとして扱います。モデルでは、今回のデータセットの変数を全て回帰項として使います。もちろん、回帰用の式からはcitric.acidは除外します。
    全体の80%を訓練データに、20%をテストデータとして、10foldsクロスバリデーションでのstanによる予測結果の平均AUCを評価指標とします。最後に、テストデータを用いた予測のAUCを確かめます。また、階層ベイズモデルではないモデルでの10foldsクロスバリデーションでのAUCとも比較します

    分析概要

    ・データ整形
    ・訓練データとテストデータの分割
    ・クロスバリデーション用のデータの作成
    ・stanの実行
    ・クロスバリデーション結果の出力
    ・テストデータでの予測
    ・非階層モデルとの比較

    全体のコード以下のリンクにあります。
    kick_logistic_regression_allowing_k_hold_cross_validation_hierachical.R
    logistic_regression_allowing_k_fold_cross_validation_hierachical.stan

    データ整形

    階層ベイズで扱うグループをcitric.acidから作っています。

    訓練データとテストデータの分割

    ワインの質に関するバイナリーデータをこちらで作成し、80%を訓練データに、20%をテストデータに分割しています。

    クロスバリデーション用のデータの作成

    こちらのコードでは任意の数でクロスバリデーション用のデータを作成し、stanで扱う訓練用データのlistに追加しています。
    また、参考にしているブログより転用したstan_kfoldという関数を定義しています。k分割した際のstanの推定結果をリストに格納するための関数です。

    stanの実行

    こちらのstanのコードでは、M個のグループごとにパラメータが異なるというモデルを書いています。modelブロックの途中でholdoutを入れることで一部のデータを推定に使わないようにしています。

    こちらはstanをキックするためのコードです。いつもと違い、先程定義したstan_kfoldを用いています。

    クロスバリデーション結果の出力

    以下は、k個ずつ手に入ったクロスバリデーションでの推定結果から、各パラメータの平均値を計算し、ロジスティック回帰モデルで2値の予測を行い、平均AUCを計算するコードです。

    平均AUCは0.675となりました。すごくいいわけではないですが、手抜きモデルとしてはまずまずと言ったところでしょうか。

    テストデータでの予測

    以下のコードで最初に分けていたテストデータでの予測結果を返します。

    実行の結果、AUCは0.665と、クロスバリデーションでの平均AUCと比べてあまり下がりませんでした。

    非階層モデルとの比較

    非階層モデルでも同様に10foldsクロスバリデーションの平均AUCを計算しました。非階層モデルよりもAUCが1%ポイントくらいは高いようです。

    おわりに

    現時点において、stanでの柔軟なモデリングを機械学習に活かす作法について紹介されている文献はあまりなく、選手人口はどれくらいいるのか気になるところですが、発見したブログのやり方でクロスバリデーションをカジュアルに行えるので、より多くの方がstanでの機械学習にチャレンジしうるものだなと思いました。ただ、このレベルの階層ベイズだとrstanarmで簡単にできてしまうので、より深く分析してモデルをカスタムしていきたいですね。

    参考情報

    [1]Lionel Hertzog (2018), “K-fold cross-validation in Stan,datascienceplus.com”
    [2]Alex Pavlakis (2018), “Making Predictions from Stan models in R”, Medium
    [3]Richard McElreath (2016), “Statistical Rethinking: A Bayesian Course with Examples in R and Stan (Chapman & Hall/CRC Texts in Statistical Science)”, Chapman and Hall/CRC
    [4]松浦 健太郎 (2016), 『StanとRでベイズ統計モデリング (Wonderful R)』, 共立出版
    [5]馬場真哉 (2019), 『実践Data Scienceシリーズ RとStanではじめる ベイズ統計モデリングによるデータ分析入門』, 講談社

    [Python]機械学習などでテキストデータを特徴量にする際のソースコード集

    テキストデータの特徴量化について

    仕事ではテキストデータを多用するので、機械学習などで扱うためにテキストデータを特徴量にするためのアプローチを色々と整理してソースコードを残しておきたいと思います。今回はあくまでも私の知っているものだけなので、網羅性はないかもしれませんが悪しからず。
    (2019/08/18 追記)Stackingをカジュアルに行えるvecstackというモジュールを用いた予測も試してみました。下の方の追記をご覧ください。

    アプローチ

    テキストデータを特徴量にする際のアプローチとしては、以下の3つが良く使っているものとなります。
    ・単語ベース
    ・クラスタ、トピック、分散表現ベース
    ・文書間の類似度ベース

    今回扱うデータ

    ひょんなことから、昨年10月くらいに取りためたマンションの施設情報のテキストです。

    緑色が印象的な某不動産紹介サイトをクローリングしました。全部で1864件ほどの文書数となります。

    加えて、デザイナーズマンションかどうかのフラグを作成しました(17%くらいがデザイナーズマンションの割合)。これでもって、マンションの施設情報からデザイナーズマンションかどうかを分類できるかチャレンジしたいと思います。
    ここにデータを置いていますので、興味のある方はご利用ください。

    今回扱うモデル

    ランダムフォレストです。10foldsクロスバリデーションによるAUCの結果を各手法のスコアとして扱います。

    こちらは、任意の手法に関して10foldsクロスバリデーションで実行し、AUCのグラフを生成してくれるソースコードです。主にscikit-learnのサイトに載っているものです。引数のclassifierをsklearnの任意のモデルのインスタンスで渡せば動きます。

    単語ベース

    シンプルに単語をそのまま特徴量にするというものですが、文書によっては単語数が多すぎて収集がつかないと思います。そこで単語を簡単に選択できるDocumentFeatureSelectionというパッケージを利用します。

    このパッケージでは
    ・TF-IDFベースの特徴量選択
    ・PMI(Pointwise Mutual Information)ベースの特徴量選択
    ・SOA(Strength of association)ベースの特徴量選択
    ・BNS(Bi-Normal Separation)ベースの特徴量選択
    を行うことができます。

    まずは今回のベースラインとして、単語のカウントベースでの特徴量を扱いたいと思います。
    その前に、GitHubに上がっているデータに対して以下のように簡単な前処理をしておきます。

    ようやくベースラインの予測となります。以下のコードを実行すると、ROCが描かれた図がJupyter上で表示されます。

    AUC82%というのはベースラインとしてはなかなか強敵なのではないでしょうか。

    さて、本題の特徴量選択パッケージの適用をするためのソースコードを以下に記します。

    以上のソースコードを実行すれば、tf_idf_scored_df、pmi_scored_df、soa_scored_df、bns_scored_dfにスコアを付与された単語のリストが手に入ります。

    ここでは各スコアに関してアドホックに閾値を設けて、特徴量として利用することにします。

    TF-IDFベースの特徴量選択

    PMIベースの特徴量選択

    SOAベースの特徴量選択

    BNSベースの特徴量選択

    クラスタ、トピック、分散表現ベース

    続いて、k-meansやLDAやword2vecを用いて特徴量を作成する方法です。今回はk-means、ミニバッチk-means、LDA、FastTextによる分散表現を扱います。

    k-means、ミニバッチk-means

    LDA

    こちらはgensimでLDAを推定し、推定したトピックの割合をデータフレームで返すコードです。

    トピック数をとりあえず30個くらいに指定して推定したトピックの割合を特徴量として文書分類を行います。そのため、特徴量の数は30個になります。

    FastTextによる分散表現

    今回はデータ数が少ないことから、学習済みの分散表現を用います。日本語のコーパスに対して、FastTextで推定された分散表現となります。学習済み分散表現はこちらから拝借しました。

    分散表現は単語に対して計算されるので、単語に対して分散表現を足し合わせたものを特徴量として扱います。ここでは分散表現の合計値、平均値、TF-IDFで重みを付けた平均値の3つのパターンを試します。

    合計値ベース

    平均値ベース

    TF-IDFで単語を重みづけた平均値ベース

    文書間の類似度ベース

    今回は、デザイナーズマンションの定義文に似ているかどうかという観点で類似度ベースの特徴量を作ってみたいと思います。

    今回は変数が一つだけなので、機械学習はせず、デザイナーズマンション割合との関係を図示するにとどめておきます。横軸がデザイナーズマンションの定義と施設情報の類似度で、縦軸がデザイナーズマンション割合です。

    どうやら、途中でデザイナーズマンション割合がピークを迎えるようです。

    おわりに

    最先端の手法は調べれていないですが、テキストデータを特徴量に落とし込む手段を備忘録として残しておきました。今回あげた中では、SOAベースの特徴量選択のAUCが83%と一番高かったですが、ベースラインが82%と僅差でした。そして、分散表現形のものは80%に届いた程度です。余力があれば新しい特徴量の作り方が分かり次第アップデートしようと思います。

    追記

    “Automate Stacking In Python How to Boost Your Performance While Saving Time”という記事を見つけたので、紹介されているvecstackモジュールを使って今回のモデルに関して簡単にstackingしてみようと思います。
    コードに関しては、こちらのGitHubに上げています。試してみた所、AUCは88%になりました。結構上がりましたね。しかもコードはめちゃ短いので楽です。

    参考文献

    [1]Julian Avila et al(2019), 『Python機械学習ライブラリ scikit-learn活用レシピ80+』, impress top gear
    [2]Receiver Operating Characteristic (ROC) with cross validation
    [3]@Kensuke-Mitsuzawa(2016), “テキストデータで特徴量選択をする”, Qiita
    [4]JapaneseTokenizer 1.6
    [5]DocumentFeatureSelection 1.5
    [6]自然言語処理における自己相互情報量 (Pointwise Mutual Information, PMI)
    [7]【Techの道も一歩から】第3回「第11回テキストアナリティクス・シンポジウム」
    [8]文書分類タスクでよく利用されるfeature selection

    Uplift Modeling用のパッケージtools4upliftを使ってみた

    はじめに

    今回は、今後仕事で使いたいという思いもあり、RでUplift Modelingに関して便利なパッケージがないか探した結果、2019年に登場したばかりのtools4upliftの存在を知りました。アップリフトモデリングのモチベーションに関しても簡単に説明しながら、サンプルデータで実践してみようと思います。

    ・Uplift Modelingとはなにか
    ・Uplift Modelingの卑近な例え話
    ・Uplift Modelingのサンプルデータ
    ・tools4upliftについて
    ・tools4upliftでCriteoデータを試してみる
    ・『仕事ではじめる機械学習』の9章のコードをCriteoデータに試してみる
    ・おわりに
    ・参考文献

    Uplift Modelingとはなにか

    きちんとした説明は、あまりにも今更感があるので説明は端折りたいと思います。既出の文献がありますので、そちらを熟読ください。

    Uplift Modelingの卑近な例え話

    自分が吉野家のマーケティング担当だとしましょう。吉野家のアプリで割引クーポンを顧客にばらまくことができるとします。
    マーケターとして重要なのは、割引クーポンを渡したことをきっかけとして吉野家に足を運び購入する顧客を増やせるかどうかになります。

    マーケターの手元にあるのは、割引クーポンをばらまいた顧客とばらまかなかった顧客、そして吉野家で牛丼を食べたかどうかのデータです。
    以前のマーケティング担当者がランダムにクーポンをばらまいていたことが重要なポイントです。

    このデータから、顧客は以下の4分類に分かれます。

    • 無関心:割引クーポンをばらまこうが我関せず。そもそも吉野家に行く気はない。
    • 説得可能:普段、牛丼が安いすき屋にばかり行っているが、割高に感じている吉野家に負い目を感じている。割引クーポンで揺さぶられ来店する。
    • 天の邪鬼:吉野家コピペのように、割引クーポンを握りしめた家族連れに遭遇したくないので、割引クーポンをばらまかれたら来店しないような客。
    • 鉄板:毎日決まった時間に吉野家に行くことを心に決めている客。

    マーケターは割引クーポンをばらまいた顧客と割引クーポンをばらまいていない顧客にデータを二分し、それぞれ機械学習のための訓練用データとテスト用データを用意します。

    つまり、「割引クーポンをばらまいた顧客」の訓練用データとテスト用データと「割引クーポンをばらまいていない顧客」の訓練用データとテスト用データの計4つのデータセットを用意します。

    まず、牛丼の購入の有無を教師とした訓練用データでロジスティック回帰モデルなどを推定します。
    その結果、「割引クーポンをばらまいた顧客」から推定したモデルと、「割引クーポンをばらまいていない顧客」から推定したモデルが手元に残ります。

    2つのテスト用データを1つにまとめて、先程推定したモデルを用いて、牛丼の購入確率を求めます。モデルは2つあるので、予測結果がテスト用データ1つに対して2つあることになります。

    その予測結果の比(「割引クーポンをばらまいた顧客」モデルベースの予測値÷「割引クーポンをばらまいていない顧客」モデルベースの予測値)をアップリフトとみなします。

    以下の図はこれまでの説明を図にしたものです。

    アップリフトがどの程度の水準であれば、説得可能なユーザーが多いのかを探っていくことで、吉野家のアプリにおいて、どのユーザーに割引クーポンを発行するべきかがわかることになります。

    Uplift Modelingのサンプルデータ

    残念なことに吉野家のアプリのデータはありません。そこで今回は公開データを利用します。
    以前より、The MineThatData E-Mail Analytics And Data Mining ChallengeのメールのデータがUplift Modelingで非常にしばしば取り上げられるデータでしたが、Twitterで他にデータないのかとぼやいたところ、2名の方にCriteo Uplift Prediction Datasetを紹介していただきました。

    余談ですが、Criteo社と言えばディスプレイ広告のキング的な存在で、少し商品のリンクを踏んだだけであっという間に広告がレコメンドされますよね。自社で出稿用バナーを作っていましたが、CVRが高くなる良いクリエイティブを作ってきたのか、単にCriteo社のアルゴリズムが優秀なだけなのか非常に気になるところでしたね。

    Criteo社が提供してくれている今回のデータは、2500万行に及ぶユーザーのデータで、プライバシー保護の観点から特徴量は復元できないような形式で提供されています。バイナリーのラベルとしては訪問やコンバージョンなどがあり、データ全体に占める処置群の割合は84.6%となっています。要は、吉野家で言う割引クーポンをばらまいた顧客が全体の84.6%に及ぶということです。

    tools4upliftについて

    2019年1月に公開されたRのUplift Modeling用のパッケージです。

    • 特徴量における連続値をカテゴリ変数にする際に、最適な階級値を求めてくれる関数
    • アップリフトモデリングの可視化する関数
    • アップリフトモデリングにおける特徴量選択ができる関数
    • アップリフトモデリングにおけるモデルのバリデーションを行う関数

    などが提供されており、ちょいとRを触れるマーケターにとって、アップリフトモデリングにおける試行錯誤がかなりしやすくなる便利なパッケージだと思いました。
    なお、このパッケージで扱っているモデルはロジスティック回帰になります。介入データをもとに推定したモデルの条件付き確率と非介入データをもとに推定したモデルの条件付き確率の差をアップリフトとして推定しています。

    このパッケージの解説論文においては、アップリフトモデリングの評価指標としてQini曲線というものが提案されていました。Qini曲線はローレンツ曲線のようなもので、Qini曲線とランダムに割り当てた際のアップリフト量の差分の合計をQini係数と定義しています。

    tools4upliftでCriteoデータを試してみる

    こちらはアップリフト値の予測値の上位から右に並べた際のアップリフトの増大のグラフになります。20%あたりでピークになるようです。

    こちらはアップリフト量の棒グラフです。20%の階級値を超えたらガクンと下がるのがわかります。

    なお、Qini係数は0.03233551でした。

    『仕事ではじめる機械学習』の9章のコードをCriteoデータに試してみる

    tools4upliftの結果を鵜呑みにするのもあれなので、『仕事ではじめる機械学習』の9章のコードを使ってアップリフトモデリングを実践してみます。コードは丸パクリですが、謹んで掲載させていただきます。