開発者共通の悩み?Yomi-Autocompletion の動作に関して
皆様、もう Microsoft Visual Studio International Pack ベータ1 はご覧になりましたでしょうか?
けっして、規模の大きなものではありませんが、もし、まだという方がいらしhたら是非一度ドキュメントだけでも目を通していただけると幸いです。専用フォーラム(https://forums.microsoft.com/MSDN-JA/ShowForum.aspx?ForumID=1989&SiteID=7)では、現在提供しているコンポーネントに関するフィードバックはもちろん、「こんなものが欲しい」というご意見も是非お伺いたいと思っています。
さて、今回は、その Microsoft Visual Studio International Pack より、Japanese Yomi-Autocompletion Library を簡単に紹介させていただきだいと思います。
このライブラリは、一言でいえば、読みに対応した自動補完機能をコントロールに追加するための拡張ライブラリです。読みに対応した自動補完とは、そのままですが、IMEによる入力時に、変換前の読みを入力した段階で、入力された読みに対応する候補を表示するという機能です。たとえば、都道府県名の一覧が候補になっている場合には、「お」と入力すると、「大阪」「大分」「沖縄」など「お」から始まる名前が候補として表示されます。
説明するまでもありませんが、日本語を入力する場合には直接文字を入力するかわりに、「読み」を入力した後変換することが必要になります。さらに、入力が長ければ長いほど文脈に適した変換候補を提供する日本語IMEの特性も加わり、日本語システムに関しては自動補完やインクリメンタルサーチが期待したように動作しないのが現状です。これを解決するために、「読み」への対応をご自分で実装されている方もいらっしゃると思います。より良いユーザーインターフェースの探究も皆様、開発者の方の工夫の部分ではあると思いますが、一方で、基本的な機能の作りこみに時間をとられたくないというご意見もあると思います。そこで、このライブラリでは、基本的な動作を実現するためのライブラリを提供しています。
Japanese Yomi-Autocompletion ライブラリでは、自動補完機能を持つ複数のコントロールを提供する代わりに、既存のコントロールに自動補完を追加するために必要な機能をライブラリという形で提供しています。ライブラリは、2つの中心的なクラスとデータ型や状態を表す列挙型などの周辺のクラスより構成されています。
はじめに、一番中心になるのが、YomiAutoCompletionContextManager クラスで、候補の一覧や自動補完機能の状態など、ほとんどすべての情報がこのクラスによって一括管理されています。次に、機能をコントロールに組み込む際にコンテキストマネージャとコントロールの橋渡しをするのが YomiAutoCompletionListener です。
詳細はドキュメントを見ていただく方が良いと思いますので、紹介はこれくらいにしておきましょう。
さて、実はこのライブラリを設計するにあたって、いくつかの問題がありました。特に大きな問題は、どのように読み仮名を提供するかということです。都道府県名のように読みが決まっているものや、ユーザー登録の名前のように登録時に「ふりがな」があらかじめ提供されている場合には、話は簡単です。しかし、自動補完機能を付加したい項目に必ずしも読みが与えられているとは限りませんし、読みがない項目への対応も考慮しないといけません。特定のアプリケーション向けに設計するのであれば、活用できる読みのデータがどこにあるのかが分かっていますし、「読みがなデータのある項目さえ表示されれば良い」というようにアプリケーションのシナリオに沿ってルールを決めれば解決できる場合も多くあると思います。しかし、これを汎用にするとなると、いろいろな方法や考えがあります。例えば、すべての項目は事前に読みが与えれられていることを前提にすると、割り切ってしまうのもの一つの方法だと思いますが、それだと使用できる場面がかなり限定されてしまうなど、バランスが難しい。この点を決めるまで(決意するまで?)にはずいぶんと悩みました。
結局、このライブラリでは、インターフェースが多少複雑になるのを覚悟して、以下のような、どちらかというと柔軟を重視したアプローチをとってみました。
1) 読みが分かっているものに関しては、項目の追加の際にアプリケーションが読みを提供する。
2) 読みが与えられていない項目に関しては、自動的に読みが与えられるようにする。
3) 自動の場合には、IYomiProvider インターフェースを介して、読みを取得するようにし、開発者がIYomiProvider の独自実装を提供することで、読み仮名のソースを自由に選択できるようにする。
4) IYomiProvider の一実装として、IMEの辞書から読み仮名を取得するクラスを提供する。
5) IME の辞書が対応する読みがなを複数持っている場合には、先頭の候補のみを使用する。
6) 入力補完はベストエフォートする。つまり、入力された読みが項目に与えられた読みと違う場合には、候補として表示されない。
7) ユーザーが入力した読みが項目に関連付けられた読みと一致せず、候補がでない場合を考慮し、変換後の文字列に対しては、通常の自動補完のように動作するようにする。
最後の3点は、ちょっとわかりづらいと思いますので、例をあげると、たとえば、「大和~~~」という名前の会社があったとします(現存する会社名とは一切関係ありません)。これだけでは「だいわ」と読むのか「やまと」と読むのか分かりません。この場合には、残念ながらIME から取得した読み仮名が正しいとは限りません。仮にIMEから取得した読みがなが「だいわ」の場合、ユーザーが「や」と入力してもヒットしません。したがって、ベストエフォートということになります。辛いところですが、ここは諦めるしかありませんでした。ひとつの項目に複数の読み仮名を関連づけることも検討はしましたが、5~6個の読みの候補が示されるものはざらで、もっと多くの読みをもつ単語も非常に多いうえ、それでさえ必ずしも完全に網羅しているとはいえません。結局、パフォーマンスの観点から見送りました。話は戻りますが、上の例のような場合に、読みがな自動補完だけですと、ユーザーは結局会社名をすべて入力する必要があり非常に不便です。そのため、ライブラリでは、「やまと」と入力して変換しても「大和」に変換された際には、読み仮名ではなく(7)のように項目自体の文字列にヒットするようにしました。
柔軟で拡張性に富んだものを作ろうとすると複雑で分かりづらいものになってしまうし、反対に、簡単で分かりやすいものにした場合、一歩間違えると、かゆいところに手の届かないものになってしまいます。「7割から8割の人のニーズを満たすようにして、あとは思い切って諦める。諦めるとはいいつつ、技術力のある人なら実現不可能というわけではなく、情報も提供されている。」というあたりが良いのはないかな、という漠然とした想像はできなくはないのですが、どこまでが7割の人にニーズを満たすかということは分からないというわけです。特別なことではなく、設計過程では常に悩みのたねとなる部分ですが。やはり今回も悩みに悩んでしまいました。
公式で答えの出るようなものではないですね。データ解析で線引きできれば理想ですが、十分なバイアスされていないデータを集めるというのも一朝一夕にできることではありません。結局のところ、皆様、お客様のニーズに対して、地道に、そしてもっともっと勉強する以外に答えに近づく方法はないのでしょう。
というわけで、フィードバックお待ちしております。