trieとlouds??
TRANSCRIPT
TrieとLOUDS??
はしもとまさひこ2015/6/13 東海道らぐ浜松オフ
(オフ翌日の後日談つき)
今日は自己紹介から。
● 東海道らぐ元名古屋案内人です– 愛知県大府市に住んでました。(今は神奈川県民)
● ちびぎーこ保護者会(別名:日本openSUSEユーザ会)の中の人– 夏コミ、また出るそうです(笑) ←NEW
● 最近はおーぷん万葉を始めてます– Cannaをフォークして新しいかな漢字変換システムを
開発しています。…のはずが。。。
3
さてここからはおーぷん万葉の話
● 目的「自由な日本語入力環境を手に入れよう!」– 現在: かな漢字変換ソフト「Izumo」を開発中。
● 現状の問題点:– ビックデータと叫ばれる時代に、開発がアクティブで
自由にコミットメントできる日本語入力システムがない?● 例: mozc, Anthy... (但し、SKKを除く!)
→ iBusMozcが開発停止!?(openSUSEはどうする!??)
→ そんな現状を打破したい!てのが目的です。
GW中のLILO合同オフでのお話。
CannaからフォークしてIzumo開発中
→ K&Rとかソースコードが・・・
→ げっ、グローバル変数多すぎ!?
→ あかん!! これ限界や〜(←西宮のオフだけに関西風)
結論: Cannaのフォークをやめましょう(ぉぃ)
急な決定だったため…
OSC名古屋での展示はやっつけに…(^^;
↑ OSC浜名湖の再放送みたいな感じ(まぁそうなるわな・・・)
次のターゲットはOSC京都!
● OSC京都は8月。それまで2ヶ月ちょっとある!!● ならばフルスクラッチで、最低限のかな漢字変換が
できるくらいまではいけるんじゃね?– 正直、コスト計算とかは後回しでいいよね?
…という感じで急ピッチ作成中。。。
さて、今時のかな漢字変換。。。
● なにやらいろいろな技術が出てきているらしい– Trie木 (辞書データ検索)
– ダブル配列 (辞書データ保管)– LOUDS (辞書データ保管)
– ビタビアルゴリズム (最短路検索)
当然Izumoにもこういったものが実装されるわけで…
今日の話題はこれ。
● なにやらいろいろな技術が出てきているらしい– Trie木 (辞書データ検索)
– ダブル配列 (辞書データ保管)– LOUDS (辞書データ保管)
– ビタビアルゴリズム (最短路検索)
当然Izumoにもこういったものが実装されるわけで…
Trie木とは?
● 通常の木構造に対し、枝にラベルがついたもの– メリット:共通接頭辞検索が可能になる
0
12 3
4
5 6
7
8
か
み
た
すび
わ
た
し
これがいわゆるラベルこれがついてるとTrieと呼ぶらしい
ラベルをたどることで辞書検索が可能になります→データ圧縮にもつながる
Trieの実装方法
● ダブル配列– base, check という2つの同じ大きさの配列に値を格納
– LOUDSに比べて高速だが、メモリを多く使用する
– 形態素解析器Mecabで使用(Darts)
● LOUDS– Trieをビット配列のみで表したもの
– ダブル配列に比べ遅くなるが、省メモリ– Google日本語入力/Mozcで使用(Rx)
オープンソースライブラリも結構ある!
● Darts / Darts-clone– ダブル配列の実装。Mecabで採用。
● Tx / Ux– LOUDSの実装。Ux は Tx の進化版?
● Rx– LOUDSの実装。Mozcで採用。
● marisa-trie– LOUDSの実装。とにかく高速らしい。
Izumoもこれを使えばいいんじゃね?
● いろいろ諸事情があった…– Darts / Darts-clone : ダブル配列は不採用
– Tx / Ux / Rx / marisa-trie :
→上記すべて「C++」、且つ「new-bsdライセンス」
Izumoは「C」、「MITライセンス」じゃ〜!!
できれば混ぜたくないですし。。。
ところでLOUDSってなに?
● 「らうず」と発音するらしい。(たぶん)● 私が説明するより、ぐぐったほうがきっと正解^^;
こんなビット配列です。。。
10 1110 10 110 10 0 0 0 10 0
これで先程のツリー構造を表現しています
比べてみましょう10 1110 10 110 10 0 0 0 10 0
0
12 3
4
5 6
7
8
か
み
た
すび
わ
た
し
仮想ノード「0」から3つに分岐
「1」は分岐なし
「2」から2つに分岐
「3」は分岐なし
「4」「5」「6」は末端ノード
「7」は分岐なし
「8」は末端ノード
…とか書いてますがこれを実装しようとするとどうなるか?何か気づくことがありませんか???
LOUDS実装上の最大(?)の欠点
● LOUDSは「動的ノード追加」ができません(^^;– できるかもしれないけどえらく大変!!(とのこと)– つまりは先にTrie木を構築してね!という話
10 1110 10 110 10 0 0 0 10 0
仮想ノード「0」から3つに分岐
「1」は分岐なし
「2」から2つに分岐
「3」は分岐なし
「4」「5」「6」は末端ノード
「7」は分岐なし
「8」は末端ノード
いきなりこのビット配列を作ったり後でノードを追加したりが大変となorz
というわけでTrieを実装してみよう
こんな感じのものを作ればいいんじゃないかな?
③ノードIndex(ID)
①親ノード
②変換するかな文字(Key)
これをつなぎ合わせればTrieになるよね?(敢えて果物っぽく描いてみた)
…が、しかし、、、
まだ作成途中だった…orz(動くには動いた)
こんな具合に実装中
● 32bitの値でノードを表現してそれを比較しながらTrieを構築する方法
– Key = 「ひらがな」なので行けそう。(Value=仮名文字の方は後で考える…)
● 1〜2バイト目: ノードID● 2バイト目: 制御bit● 3〜4バイト目: ひらがな(key)のコード
1〜2
ノードID
3〜4
ひらがなコード
制御コードを入れようと思ったけどこれを判定対象にするといろいろめんどいかも
2バイトでは足りないのでは?
64bitにすべきでは?
さ〜て、うまくいくかな〜?
…てことで、ご清聴、ありがとうございましたm(_ _)m