NGワードの正規表現を、意味で判断する Jev に置き換えられるか
投資商品の紹介文を公開する前のチェックを10件用意して、NGワードの正規表現と、意味で判断するモデルの両方に通した。正規表現が4件、モデルが9件だった。
ただし置き換えられたのは取りこぼしのほうだけで、知識が要る判定は外している。その1件も、事実を一行足したら解けた。
言い過ぎを機械で拾う
金融商品を扱うサービスでは、紹介文やお知らせを公開する前に、言い過ぎていないかを確認する工程を置くことが多い。値上がりを断定していないか、元本が減らないように読めないか、といったところを見る。最終的には人が判断するが、件数が多いので、まず機械で一次チェックを挟む。
その一次チェックは、だいたい正規表現の配列から始まる。
const NG = [/絶対/, /必ず(儲|もう)か/, /元本保証/, /損はしません/, /リスクなし/];
自然な選び方だと思う。差し戻される表現はある程度決まっているし、正規表現なら速いうえ、なぜ引っかかったかが一目で分かる。新しい言い回しが出るたびにパターンを一つ足す。リストは伸び続けるが、伸ばせばいずれ追いつくものだと思っていた。
増やしても追いつかず、増やすと誤検知が出る
個人向けのネット銀行と証券をひとつのアプリで出している架空のサービスを想定して、投資信託の紹介文を10件作った。差し戻すべき文が5件、問題ない文が5件。ケースと実行スクリプトはリポジトリに置いてある。
上の正規表現に通すと、正しく判定できたのは4件だった。
見逃したのはこういう文だった。
- 過去5年で一度もマイナスになっていません。今後も同様の推移が期待できます。
- 預金と同じ感覚でお使いいただけます。
- 値下がりの心配はまずないと考えてよいでしょう。
- 年利8%を安定して出し続けているファンドです。
登録済みのどのパターンとも語彙が重なっていない。「元本保証」とも「絶対」とも書かずに、元本が減らないことを読ませている。
厄介なのは誤検知のほうだった。
- 本商品に元本保証はありません。
- 絶対収益型のファンドとして運用しています。
前者は、むしろ書いておくべき注意文である。後者の「絶対収益型」は、相場が下がる局面でも利益を狙う運用方針を指す商品分類の名前で、これも問題ない。それでも 元本保証 と 絶対 に当たる。正規表現は、直後の打ち消しを見ないし、語がどこで切れるかも見ない。
見逃しを潰そうとパターンを増やせば、この種の誤検知が増える。片方を締めると、もう片方が緩む。
意味で判断させる
同じ10件を Jev に投げた。判断の材料になる文章と、聞きたいことの定義を渡すと、確率が返ってくるモデルである。質問は真偽を聞く noul ひとつだけ。
{
is_violation: {
type: 'noul',
instructions: 'この文章に、社内のコンプライアンスチェックで差し戻される表現が含まれるか',
criteria: {
true: '利益や値上がりを断定する、元本割れしないと誤認させる、リスクがないかのように読ませる表現がある',
false: '事実の記述、リスクの説明、注意喚起にとどまっている',
},
},
}
criteria には、パターンではなく判断の方針を書く。何にマッチさせるかではなく、何をもって差し戻すかを説明する形になる。
正規表現が4件、Jevが9件。見逃されていた4件は 0.58 から 0.88 で拾い、「元本保証はありません」は 0.09 で問題なしと答えた。打ち消しを読んでいる。
外したのは1件だけで、それが「絶対収益型のファンドとして運用しています」だった。確率は 0.59。正規表現が誤検知したのと同じ文で、Jev も差し戻す側に倒している。
真ん中に来た確率は2つあって、もう一つは「預金と同じ感覚でお使いいただけます」の 0.58 だった。こちらは当たっている。残る8件は 0.05 から 0.97 まで、どれも端に寄っていた。
0.5 のあたりに来たことは、間違えている印ではない。人間でも割れる文だという印でしかなく、どちらに倒れたかは別の話だった。
文字列の距離では解けない名寄せ
固定ルールにはもう一つの形がある。
同じ組織が「株式会社〇〇」と「〇〇」のように違う書き方で登録されることがあって、これを同じものとして扱う作業を名寄せと呼ぶ。一番素直なやり方は、登録名をキーにして完全一致で引くことだ。速いし、当たれば確実である。ただし1文字でも違うと当たらない。
名寄せを機械でやるとき、次に思いつくのが文字列の近さで測る方法になる。何文字書き換えれば同じ文字列になるかを数える編集距離が代表的で、近ければ同じ組織とみなす。
実在の金融機関名で10組を作って、同じ組織かどうかを聞いた。この「文字列が近ければ同じ」という前提が崩れるペアを、両方向に入れてある。
確率は実行ごとに 0.02 ほど動く。以下の話に効く差ではないが、手元で再現したときに小数第2位が合わないのはそのためだ。
| 名称A | 名称B | 正解 | Jev |
|---|---|---|---|
| みずほ銀行 | みずほ信託銀行 | 別 | 0.15 |
| 三井住友銀行 | 三井住友信託銀行 | 別 | 0.08 |
| 楽天銀行 | 楽天証券 | 別 | 0.06 |
| 野村證券 | 野村証券 | 同一 | 0.97 |
| 新生銀行 | SBI新生銀行 | 同一 | 0.54 |
| ジャパンネット銀行 | PayPay銀行 | 同一 | 0.16 |
上の3組が、字面は近いのに別の会社という向き。「みずほ銀行」と「みずほ信託銀行」は2文字の追加でしかないが、別の法人である。編集距離で閾値を引けば、まず同一に倒れる。Jevは 0.15 と 0.08 で、はっきり別だと答えた。
下の3組は逆で、字面が離れているのに同じ会社だ。「證」と「証」の違いは解けた。改称も「SBI」が前に付くだけなら 0.54 でかろうじて解けた。
解けなかったのが「ジャパンネット銀行」と「PayPay銀行」で、0.16、つまり別の会社だと答えている。この2つは同じ銀行で、2021年に名前が変わった。重なっている文字は「銀行」だけなので、文字列を見るかぎり手掛かりがない。
知らないだけだった
改称の事実を、判断の材料になる文章のほうに一行足して、もう一度聞いた。
名称A: ジャパンネット銀行
名称B: PayPay銀行
参考: ジャパンネット銀行は2021年にPayPay銀行へ商号変更した。
0.96 になった。0.54 で危なかった「新生銀行 / SBI新生銀行」も、同じように事実を足すと 0.96 まで上がる。別の会社の組はいずれも確率が下がり、判定が緩くなったわけでもなかった。
推論ができなかったのではなく、知らなかっただけだった。
そして、知らないことを教える場所があった。正規表現に「この会社は改称した」と伝える書き方はない。パターンを足すか、前段に表記の対応表を持つか、どちらにしても判定の外側に別の仕組みを建てることになる。
置き換えられるのは、意味を読めば分かるほうだ。知識が要ることは置き換えられないが、判断の材料に混ぜておけば解ける。固定ルールとの差は、精度よりもまず、載せる先があるかどうかにあった。