Jev で問い合わせを振り分け、自信のないものだけ人に回せるか
分類を自動化しようとすると、たいてい全部任せるか全部やめるかの二択になる。9割当たるなら9割は任せたい。でも外れる1割がどれか分からないので、結局すべて目視する。
確率が返るモデルなら、ここを分けられるはずだった。確信しているものは通し、迷っているものだけ人に回す。このやり方は、外れやすいところに人手を集中できるので、全件見るより安い。
同じ文面に4つ聞く
架空のネット銀行に届いた問い合わせを10件作って、それぞれに4つの質問を投げた。使ったのは Jev で、質問の型が3つある。
department(choice):口座管理、振込、投資商品、アプリ不具合、本人確認、その他から一つ選ばせるneeds_same_day(noul):当日中に担当者が対応する必要があるか。確率で返るis_offensive(noul):担当者への暴言が含まれるかfrustration(score):穏やか、苛立ちあり、強い怒りの3段階のどこか
判断が割れるものを混ぜてある。「身に覚えのない出金が3件あります。確認をお願いします」は、文面が穏やかなのに当日対応が要る。「いい加減にしてください。3回問い合わせても誰も答えません。責任者を出してください」は、強い苦情ではあるが暴言ではない。
結果は型で綺麗に分かれた。
| 質問 | 型 | 一致 |
|---|---|---|
| department | choice | 10/10 |
| needs_same_day | noul | 10/10 |
| is_offensive | noul | 10/10 |
| frustration | score | 8/10 |
文面が穏やかで緊急、という組み合わせも、強い苦情と暴言の区別も、外さなかった。落ちたのは3段階のスコアだけだった。
線を引く場所がない
では自信のないものを人に回そう、と confidence を見にいったところで詰まった。
confidence は「その答えがどれくらい確からしいか」を表す数値で、選択肢の確率が片方に寄っているほど高くなる。ところが、返ってくる質問と返ってこない質問がある。
"needs_same_day": { "type": "noul", "noul": 0.82 },
"department": { "type": "choice", "choice": "security",
"probabilities": { "security": 0.98, "account": 0.02 },
"confidence": 0.96 },
"frustration": { "type": "score", "score": 0.65,
"probabilities": { "0": 0.36, "1": 0.63, "2": 0.01 },
"confidence": 0.43 }
confidence が返るのは choice と score だけだった。noul は確率そのものしか返さない。
考えてみれば当然で、二値の確率は 0.82 と言った時点で確信の度合いも同時に言っている。0.5 からの距離がそのまま確信になる。選択肢が3つ以上あると、同じ「一番高いのは0.4」でも残りが 0.35 と 0.25 に割れているのか 0.3 と 0.3 なのかで意味が違うので、別の数字が要る。
つまり noul に線を引くなら、confidence ではなく 0.5 からの距離を使うことになる。0.3 から 0.7 のあいだを人に回す、ということになる。
引いてみたが、何も買えなかった
needs_same_day でその帯に入ったのは2件だった。「昨日の15時に振込手続きをしましたが、相手先にまだ着金していないようです」が 0.41、「振込の画面でエラーコードが出て先に進めません」が 0.44。
どちらも正解だった。
noul は10件とも当たっていたのだから、当然そうなる。2件を人に回す運用は、2割を人件費に変えて、何も買っていない。
外れるものがない範囲に線を引いても意味がない。当たり前の話だが、裏返すと、精度が出ているうちは線引きの設計そのものが要らない。線が効くのは、外れるほうの質問のほうだ。
score は高いところで切らないと止まらない
落ちた frustration の2件を confidence と並べる。
| ケース | Jevの答え | confidence | 正解 |
|---|---|---|---|
| 身に覚えのない出金 | 苛立ちあり | 0.33 | 穏やか |
| 着金していない | 穏やか | 0.60 | 苛立ちあり |
低い。confidence が 0.90 以上だった6件はすべて正解だった。ここまでは期待どおりだった。
ところが質問文を英語に書き換えて同じ10件を回すと、confidence 0.80 で外すケースが出た。2回の実行を合わせると、0.90 以上の12件は全部正解で、誤りは 0.33 と 0.60 と 0.80 に散っている。
0.7 で切ると 0.80 の誤りが素通りする。0.9 で切れば全部止められるが、そのとき10件のうち4件から5件が人の手に回る。半分近くを見るなら、最初から全部見るのとどれだけ違うのか。
正解のほうを疑う
もっとも、外した2件は正解ラベルのほうが怪しい。
正解ラベルというのは、ケースを作るときにこちらで付けた「本当はこうであるべき」という答えのことだ。一致率は、モデルの出力とこのラベルがどれだけ合ったかを測っている。ラベルが間違っていれば、正しい答えが不正解として数えられる。
「昨日の15時に振込手続きをしましたが、相手先にまだ着金していないようです」に苛立ちありを付けたのはこちらの判断で、文面そのものは丁寧だ。Jevは日本語版で 0.27、英語版で 0.13 と、二度とも穏やか側に置いた。どちらが正しいかは、この文だけでは決まらない。
3段階のラベルは人間どうしでも揃わない。揃わないものを正解にして測っているので、8割という数字はモデルの精度ではない。こちらが付けたラベルとどれだけ合ったか、というだけの数字だ。
確率のぶれ
線引きの話をする前に、確率そのものが実行ごとにどれだけ動くのかを見ておいた。同じ入力でも毎回まったく同じ値が返るとは限らないので、閾値の近くにいる判定は実行ごとに変わりうる。
40のケースと質問の組を5回ずつ回して、判定が反転したものは0件、確率の幅は最大 0.08 だった。
動き方に癖がある。0.00 や 2.00 や 0.06 のように端に振れているものは、5回とも小数第2位まで同じ値を返す。幅が出るのは 0.41 から 0.44、0.52 から 0.58 のような、真ん中にいるケースだけだった。
閾値の近くにいるものほどぶれる。運用としては嫌な性質だ。ただ、ぶれること自体が「ここは割れる」という情報でもある。
結局どう組むか
二値に落とせる質問は落としたほうがいい。noul は10件とも当たったうえ、確率そのものが確信の度合いを兼ねているので、読む数字が一つで済む。
3段階以上を使うなら、confidence 0.9 で切って半分近くを人に回す前提で見積もる。そして、そこまでして測っているものが本当に3段階要るのかを先に疑ったほうがいい。「苛立ちあり」と「強い怒り」を分ける必要があったのかは、今回のケースを作った側として自信がない。
線を引ける場所と、引く意味のある場所は別だった。