「自分で賢くなるAI」は必要なん？

<img src="https://qiita-image-store.s3.amazonaws.com/0/160512/1183e62b-3913-fe95-6cb7-21d23585cc38.png", width=40%>


「**AIが自分で学習して賢くなっていく！！**」という内容の謳い文句、よく聞きませんか？
自分も機械学習の仕事に少しずつ携わるようになって、この手の話が他人事ではなくなってきました。

周りから聞いたエピソードも踏まえ、自分なりに「自分で賢くなるAI」のビジネスについて考えてみたりするポエムです。
※決して否定したい記事ではありまへん！！！

# そもそも、それってそんな簡単にできるもんなの？

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160512/d379890d-abfa-d6b2-d880-07f12fa9a1d2.png", width=30%>

## *DeepLearningの分野では*...
DeepLearningでは**転移学習**と呼ばれる手法があります。
(Fine Tuningもおおよそ同じ手法を指しています）
これは、他でデータを学習した学習済みモデルを持ってきて、そこに自分たちで集めたデータを学習させる学習方法です。
少ないデータで高い精度を出すための手法で、画像系では特によく使われているイメージです。

この転移学習を使い、自分自身のモデルを繰り返し転移学習していくことでいわゆる
「**追加学習**」を実現することはできそうです。

## scikit-learnだとどうなの？...
> 転移学習を使い
> 「追加学習」を実現することはできそうです。

とは言ったものの私はDeepLearningなんてわからないんですけどね！！！！

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160512/fc6798f6-8736-e517-29b4-2c2b0d5bf493.png", width=30%>

できれば、手軽に使える`scikit-learn`のライブラリ内でいい感じにできないでしょうか？
と調べていましたが、**一筋縄ではいかないようです...**

# なぜscikit-learnだと難しいのか
機械学習の学習方法として大きく2種類、**バッチ学習**と**オンライン学習**があります。
（ミニバッチ学習等、他にも種類はあるようですが、今回はざっくり2種類とします）

scikit-learnで使える識別器は、主にバッチ学習を採用しているようなのですが
**バッチ学習では基本的に追加学習はできません...**

##　バッチ学習とオンライン学習とは
### バッチ学習
学習データ全てを使って学習し、最も最適なパラメータを導き出す方法。
常に**学習データ全てが揃っていることが前提**なので、追加学習は基本的にできない。

もし追加学習的なことをするとしたら、今までの全データをローカルに保存しておいて追加学習をしたいタイミングで貯めた全データで再学習すれば、内容的には追加学習になる。
ただしこの場合、学習時間・学習データサイズが際限無く増えることになるので現実的ではないかも...

### オンライン学習とは
こちらはバッチ学習とは逆で、データが入ってくる度に学習しパラメータ更新をしていく方法。
この学習方法であれば、上で書いているような追加学習にも対応できそうです！！！！

ちなみに「**じゃあオンライン学習だけでいいやんけ！！**」と思ってしまいそうなのですが、オンライン学習にも弱みがあります。
オンライン学習はデータが入ってくるたびにモデルのパラメータを更新する性質上、
新しいデータがノイズだった場合モデルをそのノイズに合わせにいってしまうようです。
そのため一般的にノイズに弱く、またデータの順番によっても結果が左右されてしまう、というのが弱みです。

scikit-learnの場合「`partical-fit`」という関数を持っている識別器はこの追加学習に対応しています。

## なーんだ、追加学習できそうやん！！！

でも、本当にそれって簡単にシステムに入れていいのしょうか...？
注意すべきことはないのかな？ということについてもう少し考えてみたいと思います。

# 「自分で賢くなるAI」のリスク

## ①データが消失した時に復旧できない可能性がある
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160512/04f1adf4-b844-571c-4582-b42884c933d3.png", width=30%>
もし、なんらかの理由でモデルデータがおかしくなったり消失してしまった場合。
追加学習をしていなければ、納めたものをもう一度提供すればとりあえず復旧する手段はありそうですが、追加学習されていた場合はそうはいきません。

納めたモデルと、データが飛ぶ直前のモデルは、追加学習している時点で「**別物**」になっているはずなので
モデルを納めた側が直前の状態に戻すことは不可能になります。
そういった障害に備えて、モデルのバックアップを日々取っておくことは必須に感じます。

勿論、データが消えること自体は作った側の責任では無いはずですが、
「**消えたら戻せないから、自己責任でバックアップ取るなりしてね**」ということを
認識合わせしておく必要はあるんじゃないかなあと思います。


## ②追加学習して精度が下がる可能性もある
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160512/cb99a350-7eb1-bd64-b5d0-47eb8c87f85b.png", width=30%>
そもそも追加学習をして必ず精度が上がるとは限りませんよね...？
データ量が増えること自体は喜ばしいことですが、例えばどこかでデータの性質や傾向が変わってしまった場合、
そのまま同じ処理で学習を重ねていると、全く期待はずれのモデルができあがっているかもしれません。

 「データを足せば精度は上がるもの」と考えている人は結構多いと思うので、この可能性についても説明しておく必要があるんじゃないでしょうか。

## ③予期しない形式のデータが入ってくる可能性がある
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160512/da07175e-200e-f6ec-6364-8894a43808d1.png", width=30%>
想定していないデータが入ってきた時、学習処理がこけないようテストをするのは勿論なのですが
どういうオペレーションにするかも、ある程度合意を取っておいた方がいいのかな。どうなんでしょう。

例えば、学習データのカラムが20個あるうちの1つだけNullのデータが入ってきたとします。
それは学習データとして使うべきなんでしょうか...？
ユーザーからしたら「**いや1カラムぐらいなら平均値かなんかで埋めてデータにしてよ！**」と言いたくなるかもしれませんが、
じゃあ2カラムがNullだったらどうするの？3カラムだったら？という線引きは、結構センシティブな問題だと感じます。

# その「自分で賢くなるAI」機能は必要なの？

今回追加学習について調べてみて、追加学習（転移学習）というのは「エンジニアの作業コストを減らすための手法」であって、
「自走して精度を上げていくこと」をサポートするものではないんだろうな、というのがなんとなくわかりました。

あとなんとなくですが、周りの話を聞いているとこの「自分で賢くなる」機能は
**おまけ**的な感じでつけていることが多いように思います。
「無くてはならない必須項目」として、追加学習が提供されるケースってあまり無い気がするのですが。

「**本当にそれって要るの？**」というのは、今一度エンジニアも考えないといけないことですよねえ。うんうん。