Machine Learning Design Patterns 聴講メモ

# 記事のステータス
編集中(2021/01/28)

# 含まれる内容
[Machine Learning Design Patterns](https://www.oreilly.com/library/view/machine-learning-design/9781098115777/)の著者3人による著書の[発売イベント](https://www.youtube.com/watch?v=rGQ3JT6KS4M)の聴講メモ。
メモ程度なので、正確性には自信がない。

以下()で囲んだ文章は自分が言葉を補った箇所

# what are Design Patterns
頻繁に起こる問題についての繰り返し使用可能な解決法
（essentially repeatable solutions to commonly occurring problems.）


# rebalancing

ほとんどのデータはバランスが良くない。
例えば多クラス分類のためのデータセットで一つのクラスは少数のデータしか存在しないなど。

bias(予測と真の値との差)は常に悪いものではない。
例えばNaturally occuring biasはデータをいくら集めても解消できないバイアスである。
Naturally occuring biasに気づくには正しい評価指標でモデルを評価しているかも重要な観点である。

![スクリーンショット 2021-01-28 16.56.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/6191eff9-f708-4086-05ea-3f3b1669133a.png)

この例では全体のaccuracyは良好だが、クラスごとのaccuracyを見てみるとminority[データ数が少ないクラス]は精度が不良である。



__このような問題の解決法__
- Downsampling
- Upsampling
- Weighted Classes

__Downsampling__

以下のようにmajority class(データ数が多いクラス)とminority class(データが少ないクラス)があった際に、例えばランダムサンプリングでデータ数が多いクラスのデータを省くというもの。


![スクリーンショット 2021-01-28 17.04.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/9ca2e703-8a31-1d79-1409-88ae795f7fa9.png)

一方で注意が必要なのは、一定期間にわたってデータを集める際に全ての時間において統一的な方法でデータを省く必要があるということ。ある時間においてはランダムにデータを省き、ある時間では前から順にデータを省くというのは問題が生じる。

Downsamplingはシンプルな方法だが、minority classにも一定のデータが必要である。100枚しかなければうまくいかない

__Upsampling__

以下のようにminority classのデータを人工データなどによって増幅させることである。

![スクリーンショット 2021-01-28 17.13.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/31bc02d2-ee41-1eb0-9d59-db41f66a5317.png)

テーブルデータだとSMOTEという手法がある。
[解説編：オーバーサンプリング手法解説 (SMOTE, ADASYN, Borderline-SMOTE, Safe-level SMOTE)](https://qiita.com/eigs/items/8ae0970afe188a1124d1)

画像データであれば、augmentationが有効である。

__Weighted Classes__

以下のようにモデルがminority classの情報も学習するように、minority classのlossを意図的に大きくするもの。

![スクリーンショット 2021-01-28 17.21.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/c502b15e-521b-0fbc-55eb-2530d10d9b39.png)

Kerasは以下のように行う。

![スクリーンショット 2021-01-28 17.24.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/0e421a6f-35ed-f834-492d-26f05e858322.png)

上記３つ紹介したが、どれか一つに絞る必要はない。全て使用しても良い。(経験上、どの取り組みがうまくいったか分からなくなるので、一つずつ加えるのが良いと思う)

その他

Reframing : タスクを再定義するというもの
例えば人間の体重を回帰で予測するモデルを作っても外れ値などの影響で、精度が悪いとする。その場合は 重 / 普通 / 軽 などの分類問題に切り替えることで回帰よりも良い問題設定になるかもしれない。


# continuous evalution

MLには以下のライフサイクルがある。

ただ、テスト環境での精度が良く、本番環境での精度も序盤はよかったモデルが急に精度を落としてしまうことがある。
例えば新型コロナウイルスの影響で行動様式が変容した場合、それ以前の行動様式で得られたデータで学習したモデルは全く使えないものになってしまう。
デプロイして終わりではなく、継続した開発が必要になる。

![スクリーンショット 2021-01-28 17.43.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/f4595450-2e39-7841-59ed-f418b619821e.png)

自然言語処理のタスクを考えてみる。
例えば記事の見出しを入力したら、メディアを言い当てるというタスクとしよう。
以下のように入力と推論結果、推論が行われた日時を保存しておくとする。
さらに人手でGround Truthを作成することによって(このあたりのコスト節約のノウハウも知りたいところ)時間の経過と共に精度がどのように変化していくか確認できる。

![スクリーンショット 2021-01-28 17.57.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/3db8bbeb-63a6-4ec1-adaf-df82341496de.png)

もし、以下のように精度が一定の閾値を下回った際には再学習が必要と考えられる。

![スクリーンショット 2021-01-28 17.58.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/681e2138-65fb-b8d4-2bb1-799f95a04688.png)

同じように複数のモデルについてその精度を算出することができる。

![スクリーンショット 2021-01-28 18.00.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/e496eb35-271b-55e6-a29a-45033f0f9fe3.png)

当然だが、精度の閾値を高くすれば再学習は頻繁に行われるし、精度の閾値が低ければ再学習は少ない回数しか行われない。このあたりはコストの観点から決定されるべきである。

![スクリーンショット 2021-01-28 19.18.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/d34414f5-ea7c-f2a1-57f7-bdd2590a90fb.png)

ただ、上記の運用はコストの観点から難しい可能性がある。
この場合以下のような運用も考えられる。
例えばデータが変容しそうな将来的な時期の目処を立てる。その頃にデータを収集し、古いデータで学習したモデルで新しいデータを推論し精度を算出する。その精度を過去の精度と比較して下がっているか否かを調べることができる。
それによって再学習の必要性も判断できるだろう。

![スクリーンショット 2021-01-28 19.50.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/54b3499d-0ca9-15b6-cb86-81aea5e66cf0.png)



# bridged schema

この章はモデルを本番環境にデプロイした後の話。
基本的にデータは時間の経過と共により詳細なことがわかるようになる。

例えばチップの支払い方法を予測するモデルを作成したとする。開発時には[現金、カード]どちらかしかデータからは分からなかったが、データが変化し[現金、クレカ、ギフトカード、デビットカード]まで詳細にわかるようになったとする。

当然だが、モデルも[現金、カード]の2クラス分類のものから[現金、クレカ、ギフトカード、デビットカード]の4クラス分類のモデルへとアップデータするべきである。
このようにschema=構造=データは変化するのでモデルも変化させる必要がある。

このように昔のschemaと新しいschemaをうまく橋渡しする必要がある。
以下では3つの対応方法をあげる。

Union Schema : 昔のデータで学習したモデルと新しいデータで学習モデルを使いわける。昔のデータで学習したモデルは新しいデータに全く適用できないので意味がない。

Cascade Schema : 昔のデータで学習したモデルの出力に新しいモデルを結合させ、両方を学習する。さらに結合したモデルには新しいデータを加えて学習をする。ただ、これはあまりにモデルが複雑すぎる。

bridgeding=橋渡しはあくまで昔のデータから新しいデータに移行するための、一時的な対応策である。なので迅速にこの橋渡しを行える仕組みが必要だ。

そこでbridged schemaを紹介する。
この方法は少ない数の新しいデータを元に古いschemaからうまく橋渡しをするというものである。少量の新しいデータと古いデータで学習し、これが昔のデータでも十分な精度があるものかを評価する。

まずあがるのは以下の二つの質問である。
1つめは新しいデータに対する推論の精度をどのように評価するか。
2つめはオーグメンテーションのためにどれぐらいの数の古いデータが必要か。

![スクリーンショット 2021-01-28 21.05.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/2a3c7627-4d79-7c1a-3515-38552e293406.png)

評価データに古いデータを用いる。x軸は評価データの数で、y軸は推論結果の標準偏差である。だいたい2500枚あれば標準偏差は一定になる。


![スクリーンショット 2021-01-28 21.05.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/b77bb538-c057-4637-2051-a9af29b834c9.png)


![スクリーンショット 2021-01-28 21.09.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1025945/767dc28b-cb18-5393-38a8-f269274e621e.png)