日本語・英語・中国語を混ぜて書く生活をしていると、IME の切り替えが地味に一番のストレスになる。 Ctrl+Space を押し忘れて「nいはお」と打ち、消して、切り替えて、打ち直す。 これを 1 日に何十回もやる。
それなら IME の側で、打ったキー列から言語を当ててしまえばいい。そう思って、
fcitx5 + hazkey (AzooKey のエンジン + Zenzai) に英語と中国語の自動判定を足した。
切り替えキーは押さない。kyouhaiitenkidesune も meeting も nihao も、同じ状態のまま打つ。
しばらく使っていて、妙なことに気づいた。長めに打ってから変換したほうが、明らかに直す回数が少ない。 普通の IME の使い方とは逆だ。そこで実際に測ってみた。
普通の IME は「こまめに区切る」と楽になる
日本語 IME を長く使っている人ほど、文節ごと、あるいは数文節ごとに変換して確定する癖がある。 連文節変換は昔からあるが、長い文を一度に変換して外れると、文節の区切りを直したり候補を選び直したりする手間が大きい。 こまめに確定すれば、外れたときの被害が小さくて済む。これは合理的な習慣だ。
ところが、言語を自動で判定する IME ではこの前提が崩れる。理由は 2 つある。
- 言語の判定は、短いほど外れる。
nihao(你好) もwo(我) もma(吗) も、日本語のローマ字として普通に読める。 キー列だけで言語を当てる判定器を作って長さ別に測ると、3 文字では 89%、8 文字以上なら 99% 当たった。 短い入力には、言語を決める材料がそもそも無い。 - 変換モデルが文全体を見る。 Zenzai はニューラルなかな漢字変換で、入力全体を文脈として使う。 「かれは」を「彼は」にするか「枯葉」にするかは、後ろに何が続くかを見ないと決まらない。
作ったもの
- 英語の判定: 文字 1〜5gram の対数尤度比 (英語 vs 日本語ローマ字)。英語らしければ打ったままの英字を 1 位に出す。
長い入力の中に英単語が混ざっていれば、英語の区間と日本語の区間に分ける DP を解く。
たとえば
kinouhagithubnosetteiwokaeta→ 「昨日はgithubの設定を変えた」。 - 中国語の判定: 英語の判定の後段で、拼音 vs 日本語ローマ字を同じ形の n-gram で判定する。 中国語らしければ、fcitx5 の拼音入力と同じ libime を別プロセスで呼んで変換する (1 句 2.8ms)。
- 文脈: 直前の文章にかながあれば日本語、無ければ最後に確定した言語に寄せる。 Discord のように前後の文章を IME に渡さないアプリがあるので、後者が要る。
日本語と中国語のローマ字表記は重なりが大きい。日本語の塊の 46% が、拼音としても分解できてしまう。 つまり「拼音として読めるか」は判定にほとんど効かない。効くのは長さと文脈だけだ。
測り方
Tatoeba の文を、同じキー列のまま区切り方だけ変えて打つ。
- 文節ごとに変換・確定 (前後の文章を渡さないアプリを想定し、文脈なし)
- 文節ごとに変換・確定 (確定した文字列を次の変換の文脈として渡す)
- 2 文節ずつ / 4 文節ずつ
- 文まるごと
確定は常に 1 位の候補で行い、正解との文字誤り率 (CER) と、文が丸ごと一致した率を取る。 もう 1 つ、「直しながら打つ」場合も測った。区切りごとに 1 位が正解でなく、一覧に正解があればそれを選ぶ。 このとき 1 位が外れていた回数を「直す回数」とする。学習の影響が混ざらないよう、1 文ごとにサーバーを立て直している。
データは 3 種類、各 150 文。
- 日本語だけの文
- 英単語まじりの文 (名詞 + 助詞 の名詞を
githubやmeetingに差し替えたもの) - 中国語の文 (単語の区切りは jieba)
結果
日本語だけ (平均 5.2 文節)
| 一度に変換する長さ | 誤り率 | 文が一致 | 直す回数/文 |
|---|---|---|---|
| 文節ごと・文脈なし | 11.9% | 31% | 1.21 |
| 文節ごと・文脈あり | 6.8% | 57% | 0.60 |
| 2 文節ずつ | 4.1% | 64% | 0.42 |
| 4 文節ずつ | 3.8% | 66% | 0.37 |
| 文まるごと | 3.6% | 68% | 0.32 |
言語判定がほぼ関係しない日本語だけの文でも、長いほど良い。改善は 2 段に分かれている。
- 文脈なし → 文脈ありで、直す回数が半分になる。これは左側の文脈の効果だ。
- 文節ごと → 文まるごとで、さらに半分になる。これは右側の文脈、つまり後ろに何が続くかの効果だ。
左の文脈を IME に渡しても、右の文脈は打った本人の頭の中にしか無い。 外れ方の典型は「かれは」→「枯葉」で、文節ごとに確定すると、後ろの「シャーウッドの森を」を見ずに決めることになる。
英単語まじり (平均 5.5 文節)
| 一度に変換する長さ | 誤り率 | 文が一致 | 直す回数/文 |
|---|---|---|---|
| 文節ごと・文脈なし | 11.5% | 31% | 1.17 |
| 文節ごと・文脈あり | 7.3% | 50% | 0.68 |
| 2 文節ずつ | 6.3% | 55% | 0.50 |
| 4 文節ずつ | 5.9% | 56% | 0.45 |
| 文まるごと | 5.9% | 59% | 0.41 |
傾向は同じ。4 文節あたりで頭打ちになっている。
中国語 (平均 7.2 語)
| 一度に変換する長さ | 誤り率 | 文が一致 | 直す回数/文 |
|---|---|---|---|
| 1 語ごと・文脈なし | 66% | 12% | 1.85 |
| 1 語ごと・文脈あり | 85% | 12% | 1.84 |
| 2 語ずつ | 34% | 42% | 0.86 |
| 4 語ずつ | 23% | 55% | 0.62 |
| 文まるごと | 14% | 57% | 0.43 |
ここが一番はっきり出た。1 語ずつ打つと、そもそも中国語として扱われない。
你快要走了。 → に快要走了。
你和我有一些共同点。 → にheをyouyixiegongtongdian。
ni や he は 2 文字しかなく、日本語のローマ字として読むほうが自然だ。
しかも文脈を渡すと悪化する (66% → 85%)。最初の ni が「に」になると、それが「直前は日本語」という文脈になり、
続く拼音まで日本語に引っ張られる。外れた結果が次の判定の材料になり、外れが連鎖していく。
文まるごと打てば、7 語ぶんの拼音が中国語であることはほぼ疑いようがない。
結論: 打ち方が逆転する
普通の IME では、こまめに区切るのは「外れたときの被害を小さくする」ための保険だった。 言語を自動で判定する IME では、区切ることが外れる原因そのものになる。
- 日本語だけでも、文まるごと打つと直す回数は文節ごとの約半分 (0.60 → 0.32)
- 中国語では 4 分の 1 (1.84 → 0.43)
- 文脈を渡さないアプリで文節ごとに打つのが最悪 (日本語 1.21、中国語 1.85)
長い入力は、もはや「外れたら面倒なもの」ではなく「当てるための材料」だ。 実際の体感としても、句読点までまとめて打って Space を押す使い方に自然と寄っていった。
測って初めて見つかったバグ
この測定は、記事のためというより実装の点検として役に立った。
- 途中に読点がある中国語の文が全部崩れていた。 libime は句読点を含む入力を読めず、
nihao,wojiaoqingshui.が「にはお、をじあお…」になっていた。中国語の文の 15% に途中の読点がある。 句読点で区切って別々に変換するよう直したところ、文まるごとの誤り率は 39% → 14% になった。 上の中国語の表は、直した後の数字だ。 - 長めの入力で
youtubeが「ようつべ」になる。 文節ごとなら英語として残るのに、 2 文節以上まとめると Zenzai の変換に負ける。こちらはまだ直していない。
1 文ずつ手で打って試していた間は、どちらにも気づかなかった。 読点の件は「長く打つほうが良い」という主張を直撃するバグで、測らずに記事を書いていたら、 中国語の結果を「長くても大して良くならない」と読み違えていたはずだ。
この数字の限界
- 誤り率には表記の揺れも含まれる (ご飯/ごはん、行った/いった)。区切り方によらず同じ条件で数えているので、比較には影響しない。
- 「直す回数」は理想的な利用者を想定している。 正しい候補が一覧にあれば必ず選ぶ、という前提だ。
- Tatoeba の文は短い (5 文節前後)。もっと長い段落で頭打ちになるか、逆に悪くなるかは測っていない。
- 中国語の区切りは jieba の単語単位 で、人が実際に打つ区切りとは違うかもしれない。
- 測ったのは 1 位の正しさだけ で、変換にかかる時間は含めていない。Zenzai は CPU で 1 文 200ms 前後かかるので、文まるごとの変換は打鍵中の候補表示より重い。
おわりに
「長く打ったほうが良い」は、使っていて薄々感じていたことだった。 測ってみると、日本語だけでも差がはっきりあり、中国語では打ち方を変えないと使い物にならないほどの差になった。 IME の使い心地は「区切り方」という利用者の癖とセットで決まっていて、 エンジンが変われば、最適な癖も変わる。
