:こんにちは、エンジニアの平山です。昨今のAIブームのなか、引きの強そうなタイトルで思い切って記事を書いてみます。長くなるのでざっくりですすめますよ。最初にそこだけはっきりさせましょう。「部屋全体を写している写真なのか、そうでないのか」という判定はRoomClipでは少し重要な気がします。ときに「部屋全体が写っている写真に絞り込みたい」と思うこともあります。Learning旺盛の昨今たくさーんありそうですが、本気でこれを組もうとするとなかなか厄介です。できるだけ簡便に、出来合いのものだけで、ちゃちゃちゃっと作ってみましょう。「...合致する画像か、そうでないか、を判断...」とあるので、これはいわゆる「2値分類」とか言われる領域とわかります。要は「TRUE」か「FALSE」か、仕分けるだけ。Learningで十分できそうです。残る問題は、「ある条件に合致する画像」という部分。画像に対して「条件」を作用させなくてはならない。画像側が同じ「条件」で表現されていなくてはならない。これは少し困りました。画像を入力としてある程度正規化された表現を得なくてはいけない。過去多くの場合はここで止まっていたと思います。現代は画像解析アプリケーションはゴマンとあるわけです。rekognition。これを使えば非常に簡単にAPIをつかって画像解析ができます。僕の部屋の画像を使うと、、、こんな風に「この画像に何が写っているのか」を簡易に解析してくれます。限られたLabelと、そのLabelが指し示すものが写っているかどうかの確信度、この程度しか現時点では得られません。(※随時年齢判定とか追加されたみたいです)例えば、「Foodが80%の確率で写っていて、さらにDogが90%の確率で写ってる」とかそういうレベルです。それでも工夫と根性で予測モデルを作ることはできます。これは一見難しそうに見えてとてもシンプルな方法です。(説明変数×係数)の和という式に最終的になるのです。ロジスティック回帰の場合、この目的変数がざっくり「確率」になります。「Rekognitionによってつけられたラベルごとの確信度」を説明変数とします。画像が「部屋全体であるか、否か」を判定できそうです。具体的な話をすると、ある画像をRekognitionにかけたとき、「90の確信度でRoom」「80の確信度でDinning」と仮に判定したとします。0.65なので、65%で部屋全体の画像であることが言えました!こういうことができれば、見事に目的を達成できます。「RoomとDinningとか、どのラベルで判定すればいいの?」という2つです。Learningがなんとかしてくれます。Learningがうまく連鎖してくれそうですね。最初は根性フェーズです。事前に正解のデータを作っておく必要があります。試しに、3500件ほどの画像について人力で判定してみましょう。(えここでは3500件のうち、1800件が「部屋全体の写真」で、1200件が「そうではない写真」だったとします。続いて、3500件の画像すべてをRekognitionに放り投げ、labelを取得しておきます。仮にそのlabelの種類が全部で1000個ほどあったとします。(Dog,Food,Room,Chair...などなど)これは少し多い気がするので、そのうち「部屋全体」と判定された写真のなかで多く出現するlabelを50個。逆に「部屋全体ではない」と判定された写真の中で多く出現するlabelを50個もってきましょう。これで合計100個のラベルが手に入りました。この時点で、1つの画像ごとに下記のようなデータが手に入っているはずです。部屋全体の写真なのかどうかの判定結果これが3500件あるわけです。0」なら部屋全体ではない、というふうに数値で表現するとしましょう。すると、画像ごとに合計101個の要素をもったベクトルが手に入ります。これをカンマ区切りで、3500行のCSVにしてみましょう。これこそが「教師データ」となります。Learningに放り込みます。放り込むときは「2値判定をする」「目的変数をjudgeとする」「説明変数を残り100個のラベルの値とする」というような設定をすれば、もう完了です。本当にこれだけで完了です。具体的な画面遷移はこんな感じ。S3にあげた教師データを選択する。CSVの1行目がラベルであることを教える。目的変数がjudgeであることを教える。Learningになげつければ、「部屋全体」の写真なのかどうかをjudgeしてくれるわけです。本番環境で使えるような具体的な仕組みにしてみましょう。LeaningのEndpointに投げて「部屋全体判定」びっくりすることに、EC2いらず、いわゆるサーバレスと言うやつです。「ある条件に合致する画像かそうでないか、を判断できる機械を作る」ということがなんとか達成できました。なんとなくブラックボックスが多いですが、出来合いのものだけでもソコソコのシステムが作れるよ、というお話でした。Learningの知識周りの整理を。ここからさきは興味ある人だけどうぞ。作成した予想モデルの精度評価はAUCという数値で表現されます。これはROC曲線の積分値になるのですが、その辺周りの概説をします。2値判定の予想の場合、その予想結果のリスクは大きく2つに別れます。僕は勝手にそれを「誤解リスク」と「見逃しリスク」と呼んでます。病気の人を健康と言ってしまう見逃しリスクまず自分がやろうとしている予想が、どちらのリスクを「最低限にしなければならないか」を決めないといけません。「外の写真」だったものを「部屋全体」としてしまう誤解リスクのほうを最低限にしなければいけません。「部屋全体」の写真しか見たくないのですから。本当に0である要素のうち、どれくらいの割合1と予想してしまったのかという誤解割合が重要になります。いい、Positiveと予想したが間違えた、という表現となります。いい、Negativeと予想して、たしかに的中した、という表現です。誤診が少ない」と言えそうです。実はこれものすごーく簡単に下げることができます。シンプルに沈黙すればいいのです。ビビり倒していれば少なくとも誤診することはありません。それではなんの意味もありません。よって今度は、予想結果のリスクではなく効能について考えてみます。予想結果の効能は、1のものを1といえる力、つまり再現率が高いことです。1と予想して本当に1だった数が、実際に1だった人の数と近ければよいのです。これを先程のルールで表現すると、TP/(TP+FN)となります。Rateといえなくもないですが、一般にこれをRecall(再現率)と呼びます。見るとこれも問題のある指標です。皆を1と判定しまくれば、たしかに実際に1だった人を全員1と判定することができます。「何でもかんでも1という」の綱引きが始まるわけですね。ここで、リスクの話を思い出します。再現率は努力目標としたいところです。Rateを「どこまで妥協できるか」という覚悟を決めなくてはいけません。仮にこのレートを5%まで、と決めたとしましょう。Rateをいじることができます。Evaluationsの右下にある、このバーです。Rateを0まで下げます。するとRecall(再現率)の値も下がるはずです。これでは効能が得られない。よって、ゆっくりゆっくりFPRを上昇させていきます。するとRecallの値も上がっていきます。FPRが我慢の限界、今回は0.05ですが、この値まで上がってきたところでストップしましょう。その時のRecallの値がこのモデルの性能と呼べます。ところで、このFPRを調整しているとき一体何を調整していたのでしょうか。thresholdです。このしきい値を超えたscoreが出力されれば1と予想し、そうでなければ0と予想するという風にモデルを調整できるわけです。極端な話、このしきい値を1としてしまえば、このモデルはすべて0と予想します。いわゆる「沈黙」です。逆にしきい値を0としてしまえば、何でもかんでも1と予想します。前に戻って、FPRをゆっくりあげていったとき、きっとこう思ったはずです。FPRが0.01増えるだけでRecallが0.8くらいまであがってくれれば願ったり叶ったりですね。乱暴に言うと、この度合いを示しているのが最初のAUCという値になります。AUCが1に近ければ、この勢いが激しいと言えるケースが多くなります。(厳密にはFPRとRecallのプロットの積分値。プロットの曲線が上に凸な増加関数であればAUCは高くなる)よってこのAUCの値がざっくり「このモデルの全体的な性能」を評価していることになるので、まずもってこの値が重要になるんですね。thresholdは実際にそのモデルを使うシーンの覚悟によって異なるわけです。Learningでの2値問題処理をする時の重要な指標の説明となります。弊社で色々試行錯誤を重ねた結果、300程度の説明変数、6000くらいの教師データ数で、そこそこの誤診率・再現率を叩き出しております。複雑なことが必要な機械学習であればもう実装したほうが良いと思います。MLをうまく使いこなせると良いと思っています。非常に長くなりましたが、今日はこのへんで。この記事を書いた人:平山知宏ルームクリップ株式会社のCTO。インフラからサーバサイド全般担当。インダストリアル系の家に住みたいと思うけど、子供もできちゃったし危ないから工具とかほっぽっとくのやめようと思っている1985年生まれ。