kagome v2.5.0 をリリースしました

2 min read読了の目安(約2600字

TL;DR;

  • ものすごく長い未知語を処理するときにパフォーマンスが低下するバグがあった
  • 形態素解析時に文区切りするオプションを追加した
  • kagome のサブコマンドとして文区切りを追加した

ものすごく長い未知語の処理の改善

issue を頂きました。ありがとうございます!

https://github.com/ikawaha/kagome/issues/239

未知語処理するときに、未知語 w=uv に対して、前部分語 u_1, u_2, ..., u_{n-1}, u_n に対応するノードを追加して処理していました。大抵はこれで問題ないんですが、issue にあるようなものすごく長い未知語が発生すると、これが爆発してしまいます。

未知語 w に対して、w に対応するノードだけを追加すればパフォーマンスの問題は解消します。未知語の処理に正解はない(だいたいうまくいかない)ので[1]、これでもいいのですが、未知語の末尾あたりは既知の辞書が引ける語が含まれていたりして(助詞とか)差分が結構出てしまいます。

伝統の坊ちゃんGolden

解析内容が変わってしまうような変更はなるべく入れたくないものです。とはいえ気をつけていても、ちょっとした処理の変更が解析内容を変えてしまう可能性もあります。

今回、変更を加えるにあたって、 lucene の kuromoji のテストにも含まれている夏目漱石の「坊ちゃん」のデータを解析したものを golden file として、解析結果が変更される変更が入った場合に気づけるようにしてみました。

修正

未知語 w=uv に対して、前部分語 u_1, u_2, ..., u_{n-1}, u_n を追加すると爆発してしまうので、解析に影響がありそうな末尾の2パターン u_{n-1}, u_n だけを追加するようにします。

今回の修正で変更された解析内容は以下の2点でした。解析結果が変わっちゃうのは忸怩たるものがありますが、未知語周りは何やっても不満が残るものなのでここは割り切ってヨシとします。[2]

< 17:"や" (87: 29, 30) KNOWN [75284] [助詞 並立助詞 * *]
< 18:"むをえん" (90: 30, 34) UNKNOWN [21] [名詞 一般 * *]
---
> 17:"やむをえん" (87: 29, 34) KNOWN [76155] [動詞 自立 * *]
> 18:"から" (102: 34, 36) KNOWN [18772] [助詞 接続助詞 * *]
< 44:"づれ" (186: 62, 64) UNKNOWN [21] [名詞 一般 * *]
< 45:"だ" (192: 64, 65) KNOWN [41863] [助動詞 * * *]
< 46:"が" (195: 65, 66) KNOWN [19674] [助詞 接続助詞 * *]
< 47:"、" (198: 66, 67) KNOWN [97] [記号 読点 * *]
---
> 44:"づれだが" (186: 62, 66) UNKNOWN [19] [名詞 固有名詞 組織 *]
> 45:"、" (198: 66, 67) KNOWN [97] [記号 読点 * *]

パフォーマンスについては issue でもらった問題について改善を計測しました。

before: BenchmarkTooLongUnknownToken-8   	       1	14369470146 ns/op
after: BenchmarkTooLongUnknownToken-8   	     220	   5414142 ns/op

パフォーマンス的には問題ない範囲まで改善されたようです ╭( ・ㅂ・)و ̑̑ グッ 。

形態素解析の文区切りオプション

kagome をコマンドで使う時に、長すぎる文があると

$ kagome -file ./testdata/bocchan.txt
bufio.Scanner: token too long

となって解析が止まってしまっていたのですが(Go の bufio.Scanner の仕様)、解析時に文区切りをしながら解析するオプションを追加しました。

$ kagome -split -file ./testdata/bocchan.txt
坊っちゃん	名詞,一般,*,*,*,*,坊っちゃん,ボッチャン,ボッチャン
夏目	名詞,固有名詞,人名,姓,*,*,夏目,ナツメ,ナツメ
漱石	名詞,固有名詞,人名,名,*,*,漱石,ソウセキ,ソーセキ
...snip

-split オプションを付けて下さい。文区切りの仕様はリファレンスマニュアルを参照下さい。

https://zenn.dev/ikawaha/books/kagome-v2-japanese-tokenizer/viewer/filter

文区切りサブコマンド

テキストを文区切りだけしたいときもあるので(僕が!)、サブコマンドに sentence を追加しました。このサブコマンドは与えられたテキストを文区切りだけします。

$ cat ./testdata/bocchan.txt | kagome sentence |head -10|tail -4
新築の二階から首を出していたら、同級生の一人が冗談《じょうだん》に、いくら威張《いば》っても、そこから飛び降りる事は出来まい。
弱虫やーい。
と囃《はや》したからである。
小使《こづかい》に負ぶさって帰って来た時、おやじが大きな眼《め》をして二階ぐらいから飛び降りて腰を抜かす奴《やつ》があるかと云《い》ったから、この次は抜かさずに飛んで見せますと答えた。

おわりに

issue を頂けたおかげでテスト周りを整備して久しぶりにリファクタリングなども進められました。ありがとうございます!気になることがあったらいつでも issue 下さい。

Happy hacking!

脚注
  1. ほんとう? ↩︎

  2. いいのか? ↩︎