EnsekiTT Blog

EnsekiTTが書くブログです。

JUMAN++で遊んでる時にValueErrorが出ちゃう原因と対策の話

つまりなにしたの?

今までもJUMAN++をPyKNPから呼び出してで遊んでる時にValueErrorが出ていて、禁止文字をいっぱい増やしたらとりあえず回避できていた。
今回Word2vecで遊ぶにあたって禁止文字だらけでも困ってしまうのでその原因を調査し、対策を行った。*1

追記
invalid literal for int() with base 10: 'その他'

みたいなのが依然として出る。
引っかかったのは以下の2文

しかし、近年ではスパム(迷惑メール)などの問題により、むやみにメールアドレスを公開しない風潮が高まっていることから、このマナーは廃れつつある。

ユーザ名やパスワードを暗号化せずに転送するなどの問題の他、数多くのセキュリティ脆弱性が指摘されている。RFC2577は、以下の脆弱性を列挙している:

大きいデータ入れる時はValueErrorのキャッチを怠らないほうが良い。

f:id:ensekitt:20171019002739j:plain
*2

どんなエラーか

~/.pyenv/versions/3.6.0/envs/__/lib/python3.6/site-packages/pyknp/juman/morpheme.py in _parse_spec(self, spec)
     90             self.genkei = parts[2]
     91             self.hinsi = parts[3]
---> 92             self.hinsi_id = int(parts[4])
     93             self.bunrui = parts[5]
     94             self.bunrui_id = int(parts[6])

ValueError: invalid literal for int() with base 10: '\\'

こんなの。
原因はmorpheme.pyにあるっぽい。

parts[4]の中身がおかしい。

intにキャスト出来ないものが入っているみたいなので、この関数の引数であるspecと解析後っぽいpartsの中身を確認してみた。

>||
spec: \ a \ a \ a 未定義語 15 その他 1 * 0 * 0 "品詞推定:名詞"
parts: ['\\', 'a', '\\', 'a', '\\', 'a', '未定義語', '15', 'その他', '1', '*', '0', '*', '0', '"品詞推定:名詞"']
|

なるほどこれは4番目'\\'ですわ。ってことで、原因は半角英数前の半角スペースでした。

半角スペース+半角英数の組み合わせで一つの未定義語扱いになるようで、これをスペース区切りで分割したら、
スペースを示す\ と半角英数字まで分離されて配列長が狂う様子。

解決策

半角スペースを全角スペースに置換してから実行した。
ここは文章の性質に合わせて適切なスペースを突っ込むのが良いと思うけど、とりあえず全角スペースでも良いかなという感じ。

target_string = "ほげほげ aふがふが" #半角スペース+a
juman = Juman()
cleaned_string = target_string.replace('半角スペース', '全角スペース') #見えにくいので日本語で書いた
result = juman.analysis(cleaned_string)

こんな感じで置換してから実行したら

      特殊 1 空白 6 * 0 * 0 NIL
['\u3000', '\u3000', '\u3000', '特殊', '1', '空白', '6', '*', '0', '*', '0', 'NIL']
a a a 特殊 1 記号 5 * 0 * 0 NIL
['a', 'a', 'a', '特殊', '1', '記号', '5', '*', '0', '*', '0', 'NIL']

こんなふうになって無事にValueErrorは出なくなった。

*1:ドキュメントに書いてあるかも…

*2:出自がわからない