シドニーのレシートが「タイ・バーツ」で保存された
レシート読み取りアプリには分かりやすい仕事があります。合計金額を読むことです。そしてもうひとつ、誰も気にしない仕事があります。その金額が「どの通貨か」を判断することです。前者を間違えれば、ユーザーはすぐ気づきます。後者を間違えても、画面上はどこも壊れて見えません。表示されている数字は、紙に印字された数字とまったく同じだからです。ただ、通貨の種類だけが違う。そして家計簿が静かに狂っていきます。
2日間で、この種のバグを5件見つけました。原因はすべて同じでしたが、並べてみるまで気づきませんでした。
1. 端末番号
日本のコンビニのレシートが、カナダドルとして保存されていました。そのレシートには 小計 ¥380、税 ¥38、合計 ¥418 と、円記号が3回も印字されています。同時に、こうも印字されていました。
端末番号:1CAD
ただの端末番号です。ISOの通貨コードを探す処理が 1CAD の中の CAD を見つけ、¥ を見る前にカナダドルと判定していました。直前が「英字」なら除外する作りでしたが、「数字」は除外していなかったのです。
2. ALDIの税区分の列
オーストラリアの2枚 ― シドニー・ダブルベイのレストランと、カリンデールのALDI ― が、タイ・バーツとして保存されていました。約23倍のずれです。
シドニーの1枚には ฿ $10.00 という行があります。฿ は通貨ではありません。文字認識が英字を読み違えた結果です。本当の金額は、そのすぐ隣にドルで印字されています。
ALDIのほうが厄介でした。行はこうです。
1.39 ฿
オーストラリアのALDIのレシートでは、この列の B は「GST非課税」を意味します。その B が ฿ と読まれ、タイのレシートだと判断されました。
どちらのレシートにも TAX INVOICE と印字されています。片方にはABN(事業者番号)、もう片方にはNSW州の郵便番号。国の判定スコアはオーストラリア10対1でした。それが、形の崩れた1文字に負けたのです。
3. メニューに書かれた単語
ここから、もっと間の抜けた話になります。印字されたISOコードは強い手がかりとして扱っています。Total EUR 12.50 のような場合には妥当です。ところが、そのコードのうち7つは、ごく普通の英単語でもありました。
TRY OUR NEW MENU(新メニューをお試しください)→ トルコリラPLEASE TRY AGAIN(カード決済のエラー表示)→ トルコリラMOP AND BUCKET SET(モップとバケツ)→ マカオ・パタカAED PADS REPLACEMENT(AEDのパッド)→ UAEディルハムRM 214(部屋番号)→ マレーシア・リンギットFr. 12 Sept(ドイツ語の「金曜日」)→ スイスフラン
これらに文字認識の誤りは一切ありません。レシートがごく普通の英語を印字しているだけです。しかも AED・INR・CHF は医療の略語でもあります。薬局のレシートを読むアプリで、です。
4. 「ない」ことを根拠にしてしまった
香港のレシートは国を示す表記がなく、$ だけを印字します。そのため多くが、ユーザーの端末の通貨で保存されていました。そこで思いついた対策は、一見きれいでした。繁体字で、$ があり、台湾の表記がなければ香港だろう ― 香港のレシート10枚中9枚に当たり、他国の454枚には1枚も誤爆しませんでした。
そこへ、本物の台湾のレシートが届きました。台灣大哥大(台湾モバイル)の電信料金の領収書です。
實繳金額 $ 665
繁体字、ドル記号だけ、NT$ なし、元 なし、統一發票でもない。まさにこのルールが「香港」と判定する形でした。本物のレシート2枚で、このルールは終わりました。
5. 実際に効いたもの
台湾向けの修正は、逆の発想でした。台湾の事業者のレシートには必ず 統編(統一編號、事業者の登録番号)が印字されます。検証セットの台湾のレシート43枚すべてに存在し、他の430枚には1枚もありませんでした。これは「ある」ことを根拠にした判定です。その日のうちに反映しました。
共通していたこと
5件はすべて同じバグでした。たった1つの紛らわしい文字列が、積み上げた根拠に勝ってしまうというものです。端末番号が円記号3つに勝ち、読み違えた1文字がABNと郵便番号に勝ち、「try」という単語がすべてに勝ちました。
本物の紙に耐えるルールは、根拠があることに基づくものだけです。ないことに基づくルールは生き残りません。統編は残り、「台湾の表記がないから香港」は消えました。
なぜテストでは見つからなかったのか
どれもテストスイートからは出てきませんでした。毎リリース検証している431枚には、たまたま大文字の TRY が含まれていなかったのです。オーストラリアの2枚も、公開データセットでは「アメリカ」に分類されていたため、誰もオーストラリアのレシートとして見ていませんでした。
見つかったのは、バグを並べて「どんな形をしているか」を考えたからです。検証セットの役割はその後でした。すべての修正を431枚全部で測り、単語の修正は6つの失敗パターンを消したうえで、1枚も結果を変えませんでした。
これが正直な役割分担です。テストは「その変更が安全か」を教えてくれます。「何が間違っているか」は教えてくれません。そのためには、やはりレシートを見るしかありません。
ReceiptIQ は、毎リリース前に10か国431枚のレシートで検証しています(実物の写真391枚と、台湾の統一發票を模した合成データ40枚)。上記の修正は、見つかった週のうちに反映されました。