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

はじめに

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

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

目次

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

データセット

全体を通じて使うデータセットを生成する関数を用意しておきます。一つ目の
データは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

参考情報

前処理大全[データ分析のための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章のコードを使ってアップリフトモデリングを実践してみます。コードは丸パクリですが、謹んで掲載させていただきます。

    こちらの図はアップリフト値の階級値ごとのCVRです。最上位のアップリフト値はCVRの差が大きいですが、上位40~50%程度のアップリフト値のときにCVRの差が最も大きいようです。

    アップリフト値の順位とCVRの図です。順位が低くても処置群のほうがCVRがわずかに高いようです。

    アップリフトのスコアとCVRの関係です。2未満であればCVRは処置群が上回っていますが、一様な傾向はなさそうです。

    コンバージョンレートの差に対象群の人数を掛けることでliftを算出したものです。アップリフトスコアが1~2点であれば儲かるようです。

    tools4upliftと出している指標が違うので比較ができないのが難点に思いました。tools4upliftはオートマチックな感じで便利なのですが、『仕事ではじめる機械学習』の9章を正義として進めたいので、どうにか揃えれるようにしていきたいと思います。

    おわりに

    tools4upliftというマーケターにとって銀の弾丸になりそうなパッケージの存在を知ることができ、実際に非常に便利そうな関数が用意されているのがわかりました。ただ、開発されたばかりのパッケージなのでそこまで結果を信じていません。『仕事ではじめる機械学習』本の結果と揃えたいなと思いました。その点がはっきりすれば業務で使ってみるのも良いですし、任意のマーケターに安心して共有できると思います。

    参考文献

    [1] 有賀康顕・中山心太・西林孝 (2018) 『仕事ではじめる機械学習』 オライリージャパン
    [2] Mouloud Belbahri, Alejandro Murua, Olivier Gandouet, Vahid Partovi Nia (2019). “Uplift Regression: The R Package tools4uplift”, arXiv:1901.10867 [stat.AP]
    [3] ohke (2019) 「Uplift modelingで施策が効く人を見極める」 け日記
    [4] usaito (2018) 「Uplift Modelingで介入効果を最適化する」 Qiita

    ABEJA SIX 2019の1日目に行ってきましたレポート

    今日は午後から有給をいただいて、ABEJA SIXの1日目に行ってきました。印象的だなと感じたものに関して、つらつらと雑記を載せておきたいと思います。


    こちらは品川グランドプリンスホテルの庭園です。


    こちらは会場の雰囲気です。


    ブースの様子1です。


    ブースの様子2です。

    ABEJA SIX 2019

    「食事画像認識モデル開発プロジェクトでの10個5個の教訓」 株式会社FiNC Technologies 南野 充則 氏

    • FiNCは450万ダウンロードされているヘルスケア系のアプリを開発している会社。
    • ユーザーの継続率を高めるための施策として、機械学習を用いている。
    • 今回の紹介事例ではユーザーの食事に関する情報を入力する手間を機械学習で短縮させ、短縮させることで継続率を高めることを狙っている。
    • 食事の画像は1日に数万枚がアプリに投稿される。
    • 食事の画像から栄養価などを計算することを目指している。
    • 食事レシピ認識モデルでは、画像からレシピを識別し、メニューの量(グラム数)なども推定し、カテゴリ単位で決まっている栄養価から推定している。レシピ本の情報を入力したり、レシピサイトをクローリングし、レシピを一人あたりの栄養価になるように標準化などもしている。きれいな画像と栄養価(材料何グラムか)の伴ったクリーンなデータセットを用意するために自社のキッチンに料理人を呼び2000レシピ分の料理を作ったとのこと。
    • 食材認識モデルでは食材一つ一つ(トマト一つとか、キャベツ一枚とか)を識別して、栄養価を素材単位で計算している。
    • 学習の結果、管理栄養士よりも3%程度の誤差でメニューの栄養価を推定可能になった。
    • 開発期間は6ヶ月間。
    • 東大の松尾研にアドバイスをもらっているらしい。

    5つの教訓

    • 1.DL/ML人材をソフトウェアエンジニアから輩出すべき
      インフラ、サーバー、DB、パフォーマンスなどに明るいソフトウェアエンジニアが機械学習や深層学習を学ぶと、分析も実装もできる頼もしいメンバーになるので、ソフトウェアエンジニアのデータサイエンティスト化に注力しているらしい。目指すは論文のリプリケーションができるレベルとのこと。
    • 2.データ取得から学習までのPDCAを最速にする
      ユーザーが画像を出したあとのフローをしっかりしていなかった。予期せぬデータが入ってくるので、そこへの対応も必要。アノテーションした項目を再学習するような仕組みを作り、そばの画像が苦手であれば、そばの画像を集中的に集めて学習させる。
    • 3.オペレーションは自社で構築せよ
      泥臭い仕事と思い、丸投げしてはいけない。データセットの質が最も大事。データセットの質を担保するには評価手法を理解し細かいオペレーションを作る必要がある。アルバイトも自社で雇用、マネジャーもエンジニアとすることで当事者意識も芽生えやすい。
    • 4.評価方法の決定からプロジェクトを始めよう
      AIを使えば、想像を超える何かが出てくると期待していまうフシがある。評価の仕方を決めたほうが、メンバーのゴールが見えるし。やりやすい。10%以内の誤差の難易度がどの程度なのかわからなかったりするし、解釈の多様性が生まれてしまうこともある。
    • 5.プロジェクトはアジャイルで進めるべき
      作ったことのないモデルを作る際にスケジューリングを引くことは難しい。SOTAくらいいけますよと言ってしまい、自らを苦しめることになりかねない。

    「機械学習におけるクラウド活用のポイント」 アマゾン ウェブ サービス ジャパン株式会社 針原 佳貴 氏 & 宇都宮 聖子 氏

    • SageMakerいいぞというお話。
    • ビジネスにおいて、機械学習を進めるに際して重要なポイントは、
      「ビジネス価値に落とし込む」
      「データの流れを理解する」
      「自分の力で頑張らない」
      の3点が挙げられていた。
    • 必要ではあるが、付加価値にはつながりにくい作業のことをUndifferentiated heavy liftingと呼ぶらしい。
    • 機械学習プロジェクトを回す際に重要なこととして、
      データ取得

      データ前処理

      モデルの開発・学習

      モデルの評価

      モデルの変換(エッジデバイスに送るにはデータを小さくする必要がある。)

      本番環境のデプロイ

      監視・評価データ変換
      のループを繰り返すことが挙げられている。
    • S3(Simple Storage Service)に蓄積しているデータがあったとして、そのデータに対して、SageMakerで前処理やら機械学習を行い、学習済みの結果をS3にためれば、それを用いてエンドポイントの推論としてカジュアルに活用することができる。S3→SageMaker→S3のコンボが良いとのこと。
    • ここ1年間で200個くらいAWSのサービスやら機能が増えているので、それを知るだけでも大変そう。でもうまく使えば、Undifferentiated heavy liftingを避けることができる。
    • わからないことがあれば、ソリューションアーキテクトに質問したり、SageMakerのSlackで聞いたりすると良いらしい。
    • SageMakerでの学習の進め方としては3種類ある。1つ目は、TensorFlowなどでゴリゴリとアルゴリズムを書く。2つ目はAWS Marketplaceで販売されているアルゴリズムを時間単位で課金して使う。3つ目はAWSのビルトインのアルゴリズム(Object Detection、Semantic Segmentation、Factorization Machineなど)を使う。

    「少数データからの学習法の展開とABEJAの取り組み」 株式会社ABEJA 藤本 敬介氏

    • データの質がモデルの結果を左右するが、きれいなデータを大量に集めるためにアノテーションをやるのは大変。少ないデータでも性能を出したい。
    • アプローチとしては、Data Augmentation、Transfer Learning、Meta learningの3つがある。

    Data Augmentation(データ拡張)

    Transfer Learning(転移学習)

    • 異なるデータセットで学習したものを再利用する。
    • Fine-tuning:別のデータで学習済みのモデルに対して、タスクに対してのデータに適用する。
    • Domain Adaptation:学習済みのモデルやデータの知識を再利用する。
    • Fine-tuningは有効な手段。

    Meta learning

    • タスクの学習のしかたを学習する
    • 少数のデータでのうまい学習方法を訓練しておいて、それを使い回す。

    ABEJAの取り組み

    • データが少ない場合はFine-tuningで高精度を出しやすい。
    • External Network:中間層の情報を利用して、例外的な処理(ネットワークにバイパスみたいなものを通す)をすることで、Fine-tuningした際に精度が落ちないようにしている。不均衡データやクラス追加に対して強い手法とされている。データ数に応じてExternal Networkのサイズを調整でき、クラス1に大量のデータがある場合、1だけネットワークを深くして、2やら3はネットワークを浅くするなどの柔軟な対応が可能。これでもって不均衡データに対応できるとのこと。また、クラス追加に関しては、追加したクラスの分だけ学習すればいいようにネットワークの学習ができるらしい。ただし、学習に時間がかかるとのこと。
    • (よくわからないが)Model-Agnostic Meta-Learning(MAML(マムル))を応用したら精度が高まるらしい。

    うーん、DNNは全然追いかけれていないので断片的にしかわからなかった。悔しいものです。

    「Deep Learningの都市伝説と現実」 株式会社ABEJA 白川 達也氏

    • リサーチャーをする上で大事なこととしては、
      1.先に見つけること
      2.シンプルに解くこと
      3.先に失敗する(大きな失敗は会社としてしないために)
      の3つがある。
    • クリーンなデータで学習したほうが精度が高くなりやすく、過学習しにくい。ラベルの精度が高ければ、高いほどよい。Big Clean Data + DLで勝つる?
    • アノテーションは簡単ではない。アノテーターごとにわかりやすい情報がバラバラで、ブレるのが本質的。どこまでやるのか、どこが基準なのかというフレーミングとアンカーリングが重要。人間とかタスクを理解してすすめるのが良い。
    • 半教師あり学習(アノテーションされていないデータを使って精度向上させる取り組み)も魅力的だが、教師データを増やしたほうが効率的。アノテーションできるならば、アノテーションしてしまおう。事前学習も意味があるので行う。
    • 次にどんな技術がくるのか? Graph Convolution、Annotation、Poincare Embeddings、ML in Hyperbolic Space
    • Taskonomyという研究が今後熱くなるかも。見たこともないタスクも解けるという柔軟性を持つモデルが構築できる?

    感想

    機械学習で精度を出すためにそこまで頑張るのか!という事例を聞けたり、知識として不足していたAWS系のサービスの話を聞けたり、自分の足りていない知識を補えた良いイベントだと思いました。