Blog

最近またLinux用の日本語IMEを作っている

本件は mozc の ut がどうこうとかは関係なくて、ふと linux desktop を使おうと昨年末に思いまして、昨年末からちまちまやってます

https://github.com/tokuhirom/akaza

かな漢字変換って作るの難しいのかなぁ、と思ったので作ってみている。これはまさに Just for Fun でやっている。 わりと普通に自分で常用してる分には困らないかな、というところまできている。

以下は、思ってることの垂れ流しという感じで、まとまってないですが。

「日本語入力を支える技術」という本が 2018年に出ていて、この本の内容を読めば、だいたいエンジン部分は実装できる。Amazon のレビューではこの本よんでも実装できないって書いてあるけど、変換エンジン自体は実装できます。 UI が辛い。けど。

エンジンは、ビタビアルゴリズムで最小コスト法を実装する、とかであればプログラミングできる人なら割とまじで誰でも実装できる。

ただ、どうしてもかな漢字変換エンジンは大量の細かいオブジェクトを取り扱う必要が出てくるので、python とかで実装すると結構遅い。 2年前に一回 pure python で実装したが、おそすぎたのでコア部分を C++ で書き直したという経緯がある。 Python で書いてると、色々なアルゴリズムためす上でも、Python が遅いからだめなのか、アルゴリズムがそもそも遅くて無理なのかがよくわからなくなりがちなんだよな。

UI を Python で書いて、ロジックを C++ で実装したのだがどうもインストールまわりが煩雑になるし、Rust 触ってみたかったので rust で全面的に書き直した。 Pure Rust にしたことによって、SEGV したりして謎に死ぬことがなくなったので快適になったし、高速に動いている。所有権とかがまぁめんどくさいとかはありつつ、わりと慣れれば大丈夫になる。

基本的な方針としては、mozc に近い感じの構成になっていて、最小コスト法でビタビアルゴリズムで統計的かな漢字変換である。 個人で開発しているから Google と違って大量のウェブコーパスを利用できるわけではないから、Wikipedia と青空文庫を形態素解析してそれを学習元として利用している。 mozc は Google の大量の資源を利用できるから変換精度がいいんでしょ、と思う人が多いと思うんだけど、それはまったくもってそのとおり。ただ、書き言葉という点においては、wikipedia ぐらいの規模の言語資源があれば、それを使えば割とそこそこの変換精度は出る。逆に話し言葉はめちゃくちゃ弱いので、話し言葉とかくだけた書き方のコーパスがもっとほしい。 利用できる日本語のコーパスとしては BCCWJ がほぼ唯一に近いもので、BCCWJ を使えばもっと変換精度は向上するんだけど、、個人で利用しようとすると 25万円だかかかるので二の足を踏んでいる。

識別モデルを使う というのも試してみた。今どきだと機械学習的なアプローチがナウいかなぁと思い。。だが、どうしても個人のマシンで動かしていると時間がかかってしょうがない。金をかけられない個人の趣味開発においては、統計的かな漢字変換のほうが向いていると思う。 開発を継続的にやるには無料の環境で使えるのが大事かなと思っている。モデルデータを github actions とかで生成できるのが理想的で、github actions で生成するならチープなスペックのインスタンスで 回せるぐらいのものが良い。github actions は 6 時間しか回せない。

基本的に今は単語 Bi-gram でコスト計算している。tri-gram に拡張するとプログラムが複雑になりすぎるし、有効なケースも限定的なのでまぁ。あまり bi-gram で困ってないし、という。mozc のようにクラスNグラムにしたほうがいいのかなぁ、と思いつつ、単語Nグラムで困ってないのでまぁいいかなぁといったところ。単語Nグラムだと品詞のこととか考えなくていいのがとにかく良い。 日本語の品詞難しいよ〜。個人的には、かな漢字変換の辞書登録で品詞を入れさせられるの、だるいなと前々から思ってたし。

https://komachi.hatenablog.com/entry/20081127/p2 http://www.fenix.ne.jp/~G-HAL/soft/nosettle/anthy.html#patch13

↑このへんとかを見ても思うこと。個人的には SKK の学習の具合を気に入っている。システムで提供するモデルはもちろん大事なのだが、個人の語彙などはたかが知れているので、システムで提供するモデルは「ある程度学習が進むまで耐えられる」ぐらいの精度があればよく、細かいところは個人の学習データで補ってくれや。っていうふうにするしかないのかな、と思っている。 だって個人だと Google みたいな規模のコーパス使えないんだもの。

ユーザーの学習は、unigram と bigram をテキストファイルで ~/.local/share/ とかに落とすようになっていて、自分が変換した結果の確率が学習データにあればそっちが優先されるようになっている。ので、誤変換で確定しちゃっても、正しい変換で何回か確定すればそれが優先されるようになる。このへんの学習ロジックはめちゃくちゃシンプル。基本的にユーザーの語彙は wikipedia 全体の語彙よりも少ないから、分母が小さくなるので、ユーザーの学習結果の確率計算のほうがキツく効くっていう仕組みにしている。

ちなみに、この手のかな漢字変換エンジンって、どういうふうに考えて実装したか、みたいな日記を書いてる人が多くてそういうの読むのって面白いなぁと思う。僕はそのへんの経緯を github issues とかに書くのがいいのかなぁと思ったので github issues とか discussions とか wiki に書いている。バザール的に開発できるような感じの構成にしているつもり、ではある。 お気軽になにかアイデアとかあれば書いていただければ嬉しいし、PR 送っていただければなお嬉しい。

https://github.com/tokuhirom/akaza/discussions

今月中ぐらいに一旦スナップショットリリースを出来たらいいなぁと思っている。