Sekka(石火) DESIGN MEMO Sekkaはモードレスなローマ字かな漢字変換エンジンです。SKKにインスパイアされています。 1. 特徴 1) Emacsの上で動き、次のようなインタフェースを持ちます。 日本語変換モードというものはありません。(Emacsのマイナーモードで作成) いつでも[Ctrl-J]キーで、カーソルキーの直前のローマ字が変換可能です。 例えば、Nihongo[Ctrl-J] で 「日本語」に変換します。 2) SKKの大文字小文字指定ルールが適用されます。 OkonaU => 行う に変換される。(送り仮名あり) okonaU => 行う アルファベット中に大文字が1文字でもあれば漢字かな混じりとみなされる。 okonau => おこなう (全て平仮名)に変換される。 Kanji => 漢字,幹事 など、送り仮名なしの漢字に変換される soudesu => そうです (全て平仮名)に変換される。平仮名フレーズ辞書に近いものがあれば、候補にリストアップされる。 (平仮名フレーズ辞書については後述) 3) ローマ字綴りミスはあいまい検索により、適度に救済されます。 (Jaro-Winkler文字列類似度による検索) 4) ローマ字の表記ゆれに標準で対応します。(通常ローマ字、ヘボン式などモード切替なしですべて対応可能) ------------------------------------------------------------------------ 2. 辞書ファイルの構造 (Keyがutf-8コード順にソートされるKVSを使う) 1) アルファベットをキーとしたデータ << key部 >> << value部 >> ルール [a-z]+ C で始まる。 (継続を表す) 複数の継続候補があれば、'/'で複数文字列を区切る 例 henkan Cへんかん 例 hennkan Cへんかん 例 henkann Cへんかん 例 hennkann Cへんかん 例 kani Cかに/かんい 例 kanni Cかに/かんい ルール [a-z]+[A-Z] C で始まる (継続を表す) 例 okoNau Cおこn ... 送り仮名付きの例 2) キーに対して変換候補を保持するデータ << key部 >> << value部 >> ルール 任意 変換候補リスト a/b/c/d/eのように '/'で候補を区切る。最後の '/' はあっても無視される 例 change /チェンジ ;;英語 => 日本語 例 へんかん /変換/返還 ;;ひらがな => 漢字 例 へんかんs /変換/返還 ;;ひらがな+送り仮名開始文字 => 送り仮名付き漢字かな混じり文節 例 ! /!/感嘆符 ;;記号 => 漢字や記号など 3) その他 - SKKの辞書をSekkaの辞書に変換するツールで上記データベースのimport用データ(プレインテキスト)を作る。 - Sekkaの辞書をロード時に上記の全エントリを作成する。 - 変換用DBの構築時に辞書中に重複する key が出現した場合は、value部に変換候補を足し込む。 3. ユーザー辞書の扱い master辞書とユーザー個別辞書は同一のKVSの中に混在しており、ネームスペースによって分離される。 辞書からの単語探索順序は、master辞書→ユーザー個別辞書の順となる。 ユーザー個別辞書は、master辞書との差分であり、ユーザー個別辞書を探索し、無ければmaster辞書を探索する。 1) ユーザー学習辞書の保存方法 i) マスター辞書(全ユーザー共通) [key] [value] "MASTER::henkan" "Cへんかん" "MASTER::へんかん" "/変換/返還" ii) ユーザー学習辞書(ユーザーの変換確定手順によって、マスター辞書と変換候補順が変化した場合のみエントリが出現する) (user名がuuuuの場合) [key] [value] "uuuu::へんかん" "/返還/変換" 2) ユーザー登録語彙 以下のエントリが追加される。 (user名がuuuuの場合) [key] [value] "uuuu::nihongonyuuryokumesoddo" "Cにほんごにゅうりょくめそっど" "uuuu::にほんごにゅうりょくめそっど" "/日本語入力メソッド" 3) インデックス 例えば、上記の「日本語入力メソッド」という単語エントリが追加された場合、 対応するローマ字文字列が曖昧辞書探索用インデックスにも追加される。 @trie.addKey!( "nihongonyuuryokumesoddo" ) 4. 曖昧辞書探索用インデックス distributed-tireライブラリを使って管理する。 KVSに指定するキーのprefixは以下の通り。 (user名がuuuuの場合) "IK::MASTER::" 送りあり漢字辞書 用masterインデックス "Ik::MASTER::" 送りなし漢字辞書 用masterインデックス "Ir::MASTER::" 送りなし漢字辞書(後方一致)用masterインデックス "Ih::MASTER::" 平仮名フレーズ辞書 用masterインデックス "IK::uuuu::" 送りあり漢字辞書 用ユーザ個別インデックス "Ik::uuuu::" 送りなし漢字辞書 用ユーザ個別インデックス "Ir::uuuu::" 送りなし漢字辞書(後方一致)用ユーザ個別インデックス "Ih::uuuu::" 平仮名フレーズ辞書 用ユーザ個別インデックス 5. #付き key の扱い SKKの辞書には、#で始まるキーワードが登録されていてる。 例 #じ /#0時/#1時/#2時/#0次/#3次/#1次/#3時/#0字/#3字/#1字/#2字/#2次/#3児/#1児/#0児/#2児/#3寺/#1寺/#0寺/#2寺/ #ぎょうめ /#0行目/#1行目/ SKKでは、これらのエントリは 12ji を 12時に、10gyoumeを10行目に変換できる。 つまり、 # の場所には任意の数字(10進数文字列)を記述することができる。 さらに、キーワードの中に2つ # が登場する場合もある。 例 #がつ#にち /#1月#1日/#0月#0日/#2月#2日/#2月#1日/ このエントリは以下のような方法で処理する。 1) 使用するエントリ i. SKK辞書のキーが #とアルファベットのみで構成されているエントリは使わない。 #ji /#1時/ ii. SKK辞書のキーが #と平仮名のみで構成されているエントリのみを使う。 2) SEKKA辞書フォーマットへの変換 #はそのままにして、平仮名部分を可能性のある全ローマ字表記パターンに展開する [SKK辞書エントリ例] #ぎょうめ /#0行目/#1行目/ [変換後の例] #gyoume C#ぎょうめ #gyowhume C#ぎょうめ #gypme C#ぎょうめ #ぎょうめ /#0行目/#1行目/ 3) インデックス内での # の扱い # と ローマ字の混在keyをそのまま「送りなし漢字辞書用masterインデックス」に登録する @trie.addKey!( "#gyoume" ) @trie.addKey!( "#gyowhume" ) @trie.addKey!( "#gypme" ) 4) 数字を含むローマ字を辞書から変換する方法 10進数部分を # に置換した文字列でindexから検索する ※ 数字だけで構成される入力される文字列は、単純な数字から全角文字列への変換機能を適用し、辞書引きはしない。 5) SKK辞書中の #0から #9の変換方法 ddskk-14.2と同じ以下の変換ルールとする。 #0 -> 無変換 #1 -> 全角数字へ変換 #2 -> 漢数字へ変換 (位取りなし) `5500' は`五五〇〇'と変換される。 #3 -> 漢数字へ変換 (位取りをする) `5500' は`五千五百'と変換される。 ただ、以下の3つは仕様頻度が低いためサポートしない。 #4 #5 #9 は #0(無変換) として処理する。 (以下、本家SKKの仕様) #4 -> その数字そのものをキーにして辞書を再検索 #5 -> 漢数字 (手形などで使用する文字を使用) へ変換 (位取りをする) #9 -> 将棋で使用する数字 (\"3四\" など) に変換" 6. 平仮名フレーズ辞書 SKKのオリジナル辞書には無いエントリとして、平仮名フレーズ辞書がある。 SKK辞書に以下のフォーマットで記載されたエントリがあると、平仮名フレー ズ辞書となる。 平仮名フレーズ辞書は、soudesuなどの全て小文字のクエリを綴り上最も近い フレーズに変換するための辞書で、よく使う平仮名フレーズのミスタイプを 救済することを目的にしている。 Sekkaのデフォルト辞書は、Wikipediaの日本語版コーパスから頻度の高いものと、 IPADICから平仮名フレーズを抜き出して作成している。 1) エントリ 平仮名のキーに対する変換候補無しで指定する です // なのです // した // しました // しています // していました // しているわけです // しておりました // そうです // しかし // もっと // もっとも // 2) マスター辞書の平仮名フレーズエントリの例 key の先頭にイコール(=)が付いたエントリとなる。バリュー側は変換ターゲットの平仮名文字列が入る。 [key] [value] "MASTER::=shita" "した" "MASTER::=shimashita" "しました" "MASTER::=shiteimasu" "しています" "MASTER::=motto" "もっと" 3) 曖昧辞書探索用インデックス インデックスは上述の通りのprefixで構築する 7. 後方一致辞書 後方一致で単語を検索する辞書エントリを設ける。 後方一致辞書は、送り仮名を含まない次のようなエントリに限る。 もくてき /目的/ もくひょう /目標/ 後方一致で単語を検索することによって、変換元のキーワードのタイプミスが を救済する。 例: 後方一致検索機能が無い場合 Mkuteki => みんうてき 後方一致検索機能がある場合 Mkuteki => 目的 8. コマンド 1) 辞書メンテナンスツール - sekka-jisyo convert SKK-JISYO.L を読み込み、SEKKA-JISYO.L などを生成する - sekka-jisyo load SEKKA-JISYO.L を読み込みマスター辞書とする 2) 変換エンジン - sekka-server エンジンを起動する。ネットワーク経由で変換を受け付ける。 9. ユーザー語彙登録処理のバックグラウンド処理 1) ユーザー語彙登録キュー クライアント(Emacs)からはユーザー語彙をキューに詰むインタフェースを叩く。 キューの形式は以下の通り。value側はSKK辞書の1行を1つの文字列としたS式で保持する。 キューは、TokyoCabinetではなくEventMachineのキューを使う。 (user名がuuuuの場合) i) キューの内容 第一フィールドにユーザ名を付加する。 "uuuu ぶろぐr /ブログ/", "uuuu ぶろぐt /ブログ/", "uuuu はてぶ /はてブ/はてなブックマーク/", ... ii) 登録済み語彙の保存先 [key] [value] "uuuu::(stored)" ("uuuu ブログr /ブログ/") 2) 登録キューの消化処理 Rackとは別スレッドにて、10秒に1回程度のペースでキューを1件づつ消化する。 登録処理が完了した語彙は、"ユーザID::(stored)" 側に追記する。 ※ もし、queueに入ってきた語彙で(stored)に登録済みであればその語彙は無視される。 但し、"たんご /単語/" と "たんご /単語/丹後/" のように内容が1文字でも異なっていれば上書き登録される。 [以上]