エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

数量を機械学習で当てる モデル作成時の工夫と性能説明手法

こんにちは。エムスリーエンジニアリンググループAI・機械学習チームの池嶋です。これは エムスリー Advent Calendar 2021 の16日目の記事です。

AIチームでは機械学習を使ったプロダクトを開発し、自社サービスの改善や医療の臨床領域における研究開発など、社内外で多くのビジネス課題解決を目指しています。 このブログでは、機械学習で数量を当てるという問題に対して、AIチームにおける「予測モデル作成時の工夫」と「モデル性能説明手法」について紹介します。

予測モデル作成時の工夫編

何かの数量を当てるというのは機械学習のテーマとしてはありふれたものなので、皆さんも少なからず経験があるかと思います。例えば「ユーザーの所有している靴の数」を予測するようなケースを考えてください。特徴量として性別・年齢といった属性データ、あるいはwebサービスのデータがあればファッションに関する視聴ログなどを使うことで、機械学習で予測できそうですね。

この節では、こうした数量を予測する機械学習の問題に対して、AIチームではどのようにモデルを作成しているかを紹介します。

回帰ではなく分類モデルを使用

こうした数量を予測するケースでは、まず初めに回帰モデルで数量を直接当てに行く方法が思いつくかと思います。しかし回帰で当てる場合、評価関数の設計が難しいという問題点があります。RMSEで回帰モデルを学習すると、値の大きな外れ値に引っ張られてしまいます。一方、平均絶対パーセント誤差(MAPE; (予測-正解)/正解で誤差を計算)のような相対的な評価関数を採用すると、今度は値の非常に小さなサンプルばかりに引っ張られることになります。どんな値のレンジを当てたいかによって、評価関数を調整する必要があります。

次に多クラス分類モデルを使う手法も考えられます。推定したい数量をいくつかのしきい値で区切り、どの値のレンジに当てはまるかを分類モデルで推定するという手法です。しかしcross entropyなどシンプルな評価関数を用いると、クラスの順序を取り扱えなくなってしまいます。例えば、正解が「2~4」という場合に、「0~1」という惜しい予測をしても「100~150」という大外れな予測と同じハズレと扱われてしまうということです。順序情報を取り扱えるようにするには、こちらも評価関数の設計に工夫が必要になります。

こうした問題を回避するため、AIチームではしばしば、2クラス分類モデルを多数組み合わせる方法を採用しています。予測対象の数量データに対して、ある閾値以上かどうかでtrue/falseの2クラスに変換した教師データを作成し、2クラス分類モデルで学習します(図1)。この操作を閾値を変更して多段階で行います(所有している靴の数量を当てる問題であれば2足以上、5足以上、10足以上、...など)。

f:id:mski_iksm:20211214235751p:plain
図1. 所有している靴の数量を複数しきい値で切り、2クラス分類の教師データに変換する

推論の際には全てのモデルを組み合わせて評価し、どのしきい値のモデルまでtrueと予測されたかを確認することで数量のレンジ(「2~4足」のような表記)を推定できるという仕組みです(図2)。

f:id:mski_iksm:20211215000240p:plain
図2. 複数モデルを組み合わせて数量のレンジを推定する

デメリットとして、1人ずつ数量をきっちり予測しにくいということがあります。出力が数量のレンジとなっており、Aさんは34足というように数量をピンポイントで当てているわけではないので、詳細な比較は難しくなります。しかし、ピンポイントの数字ではなく数量レンジが分かれば十分な場合が多かったり、しきい値の切り方を細かく設定することでレンジの大きさを細かくしたりできます。工夫によりデメリットをカバーできることから、AIチームではこの方式を複数のプロジェクトで採用しています。

複数のモデルをアンサンブル

前項では、数量を当てる問題を、複数のしきい値に対して2クラス分類を当てる問題に変換しました。この各しきい値の2クラス分類問題に対して、以下のような複数のモデルを作りアンサンブルしています。

  • GBDTモデル: LightGBMを使用しています。ハイパーパラメータはOptunaで最適化しています。
  • Neural Network (NN)モデル: pytorchを使ってFFNNを構築しています。
  • マルチタスク学習モデル: 出力ノードが複数あるNNを用意し、教師データと類似のデータをサブ教師データとして同時に学習させます。サブ教師としては、教師データがアンケートで得られたものである場合、同じアンケートの他設問(例:教師が総資産である場合には子供の人数など)を採用します。NNの出力ノードは途中までの層を共有しているため、より多い教師情報でNNを学習させられることになります。
  • fine tuningモデル:事前学習済みモデルをベースにして、教師データでfine tuningします。事前学習済みモデルは、今回の教師データより遥かに多いデータで自前で学習したNNモデル使います。今回の教師データとは異なった教師データで事前学習されていても、特徴抽出には役立つとの仮説から採用しています。

特徴抽出からモデル学習・推論までパイプライン化

ここまでの工夫により、しきい値別のモデルを作成したり、複数のモデルをアンサンブルしたりなどモデル構造が複雑になってしまいました。各モデルに合わせた特徴量を作成したり、cross validationを行ったりなど、ただでさえ煩雑な処理が多い機械学習のモデルが更に複雑になっています。その結果、モデル改善の際に「特徴量作成手法を更新したけど、どのバッチをやり直すんだっけ?」「どのモデルとどの特徴量データが結びつくんだっけ?」といったデータ管理に頭を悩ませる頻度が上がってしまっています。

AIチームではこうした問題に対処するため、gokartというPython向けパイプラインライブラリを開発し活用しています。これにより、特徴量作成からモデル学習・推論までを一気通貫に実行できるようになり、特徴量データファイルとモデルファイルの対応関係などを意識する必要がなくなっています。

github.com

gokartはエムスリーのメンバーを中心に開発が進められているパイプラインライブラリです。luigiのラッパーライブラリですが、luigiとの大きな差分として中間データをキャッシュするという点があります。同じ処理の結果を別の実験などで再利用したい場合、過去に実行した結果のキャッシュファイルを使い回すことで再度実行が不要になっています。特徴量作成など似たような処理の頻発する機械学習系タスクでは大幅な時間削減が実現しています。もちろん、元データが変わるような場面では処理が再実行され、キャッシュファイルが更新されます。

モデル性能説明手法編

機械学習モデルは、大抵なにかのビジネスに活用するために開発されているかと思います。ビジネス適用の際には、そのビジネスの担当者に作成したモデルの性能を説明する必要があります。その際、説明相手は機械学習に詳しい人ばかりとは限りません。それでも、使ってもらうには何らかの形でモデルの性能を納得してもらう必要があり、その説明手法は大事なトピックの1つと考えています。

この節では、AIチームで使用しているモデルの性能説明手法を、これまでの変遷とともに紹介します。

PR曲線やROC-AUC:直感的でない

f:id:mski_iksm:20211214233016p:plain
図3. PR曲線やROC-AUC

本記事では予測の対象として数量を取り扱っていますが、しきい値ごとの2クラス分類のモデルを学習しているため、モデルの性能評価としてPrecision-Recall曲線やROC-AUCの使用が考えられます。

しかし、precisionやrecallなどの指標はあまり一般に浸透しておらず、直感的な理解が困難です。そこで、より伝わりやすい性能評価方法が求められました。

ローレンツ曲線:ユースケースが限定される

f:id:mski_iksm:20211214233051p:plain
図4. 富の集中度合いを評価するローレンツ曲線

ローレンツ曲線はものの集中度合いを測る際に使用されるグラフで、富がどれぐらいの人口に集中しているかの評価などに使用されています。人口を資産の少ない順に並べ、横軸に累積人数、縦軸に累計資産を示しています。このグラフでは、富の少ない90%の人口でやっと全体の50%の富を所有している、逆に言うと上位10%の人口が富の50%を保有しているということを示しています。

f:id:mski_iksm:20211215000921p:plain
図5. ローレンツ曲線を使ったモデル性能説明方法

これをモデルの評価に応用することを考えます。例えば、あるユーザー集団の所有している靴の数量をモデルで推定して、所有している靴の数量が多い人から順に靴の防水スプレーのプロモーションを行いたいとします。評価では、実際に所有する靴の数量がわかっている評価用データセットのモデル推定結果に対し、まずユーザーをモデルで推定した数量が多い者から順に並び替えます。ローレンツグラフの横軸にユーザーの累積人数を、縦軸にモデルで並び替えたユーザーの実際の靴の数量の累積数をプロットします。これに対して、ランダムにユーザーを並びかえた場合、同様に何人のユーザーで何足の靴を所有しているかもプロットしていきます。この差を比較することで、ランダムに対してどれぐらいの性能で並び替えが出来たかを評価できるようになります。

図5の例では、上位25%のユーザーにプロモーションができるとすると、ランダムにユーザーを選択した場合は市場の25%程度の靴にしかアクセス出来ませんが、モデルを使って靴の所有数の多そうなユーザーにターゲットを絞り込んだ場合、75%程度の靴にアクセスできるようになる、という3倍の効率差があるということを示すことが出来ます。

しかし、ローレンツグラフはここまでの説明が長かったことからも分かるように、説明が若干複雑です。また、数量の多いユーザーにプロモーションを絞りたい場合など、一部のユースケースのみでしか説得力のある説明が出来ないという問題もあります。

パーセンタイルごとの実ラベル割合グラフ:セグメントが多いとわかりにくい

f:id:mski_iksm:20211215001320p:plain
図6. 棒グラフを使ったモデル性能説明方法

より直感的に分かるグラフとして予測結果のパーセンタイルごとの実ラベル割合を示す棒グラフも検討されています。これはモデルで推定した数量の多い順にユーザーを並び替え、右から順番に上位10%ずつのユーザー群に対し実際の数量レンジの割合を棒グラフで示しています。右側の棒グラフほどモデルが数量が多いと推定した群になります。その右側の棒グラフほど、縦軸の割合で実際に靴を5足以上所有しているユーザーの割合が多いことが分かり、モデルの性能が良いといえます。

f:id:mski_iksm:20211215001656p:plain
図7. 棒グラフを使ったモデル性能説明は、数量レンジが増えるとわかりにくくなる

この図のデメリットは、縦軸の段階数が増えるとわかりにくくなることです。図6では縦軸を5未満と5以上の2段階しか用意していませんでしたが、図7のように多段階にわかれていると、実際にはどれぐらいの靴を所有しているユーザーがどのぐらいと推定されているのかが把握しにくくなります。数量を当てる問題では数量レンジの段階は多数になるので、直感的ではない可能性が高まってしまいます。

混同行列を多クラスに拡張:直感的理解が容易というメリットで採用

f:id:mski_iksm:20211214233301p:plain
図8. 2クラスにおける混同行列

混同行列は2クラス分類の問題で評価にしばしば使われる表です。列方向に予測のtrue/falseを、行方向に正解のtrue/falseを置き、それぞれのサンプル数を表に記入します。混同行列の使用により、モデルがどれぐらいのサンプルを正しく推定でき、どのような外し方をしやすいのかが分かるようになります。

f:id:mski_iksm:20211215002009p:plain
図9. 多クラスの混同行列を使ったモデル性能説明方法
これは縦軸・横軸の段階数を多数にすることで、多クラス問題にも容易に拡張ができます。モデルの推定レンジが正しかった場合左下のセルから右上にかけての対角線上の正解セル(図9赤色セル)に、モデルの推定レンジが1つずれるなど惜しかった場合対角線に隣接するセル(図9ピンク色セル)にサンプル数が加算されます。正解セルや正解+隣接セルのサンプル数の割合を示すことで、どれぐらいのサンプルで正しく推定できているかを直感的に示す事ができます。

先日公開されたAIチームの大垣によるアドベントカレンダー11日目の記事でも使われていますね。

www.m3tech.blog

f:id:mski_iksm:20211215002222p:plain
図10. 混同行列を使ったモデル性能説明方法は、レンジごとのサンプル数に大きな偏りがあるとミスリーディングを起こしやすい

この図でのデメリットは、クラスごとのサンプル数に大きな偏りがあるとミスリーディングを起こしやすいということです。例えば上記の図ではクラス0が他クラスより圧倒的に多くなっています。実際の正解ラベルに関わらず、モデル推定ではほとんどが0となっており、あまり良く推定ができているとはいえません。しかしながら図では、左下のマス(予測=0、正解=0)にサンプルが集中しているため、対角線の正解セルに位置するサンプル割合は94.3%という非常に高い数値になっています。

こうしたミスリーディングを発生させないためには、正解率といった圧縮した評価指標に頼るのではなく、表全体を俯瞰してどの正解ラベルのサンプルがどう予測されているかに注意する必要があります。この注意点をふまえても、直感的理解が容易というメリットが大きいため、最近のAIチームではこの評価方法を使ってモデルの性能を説明することが多くなっています。

まとめ

前半の予測モデル作成手法編では、数量を当てる問題に対してあえて分類モデルを使用しているなどの工夫を紹介しました。特徴抽出からモデル学習・推論までパイプライン化することで、特徴量データファイルとモデルファイルの対応関係などを意識することなく一気通貫にモデル推定が可能になりました。

後半ではモデル性能の評価に用いる図を検討しました。モデル性能の把握は、作成した推定結果がビジネスで使えるか使えないかを判断するのに必要不可欠なので、モデルの性能説明で伝わりやすい表現をすることはモデルの性能改善と同等に重要と考えています。

AIチームでは、これらの工夫を予測システムや分析用ライブラリに組み込むことで、多数のプロジェクトで使い回しができるようにしています。数量を予測するモデルに関しては、2019年にパイロット版が作られてから2年程度システムを成長させ続けてきました。最近ようやく分析ライブラリの整備など、高速道路が整備されてきたといったところです。前回のプロジェクトでは煩雑な作業だったのに、今はライブラリの活用でコード2行で簡単に書ける点に楽しさや達成感を感じています。

We are Hiring

AIチームでは、機械学習のモデルを作るだけでなく再利用可能な予測システムやライブラリの開発も進めています。データサイエンスをやりつつシステムを成長させていくエンジニアリングをしたいMLエンジニアの方、ぜひAIチームで一緒に働きましょう!

jobs.m3.com