2020年8月20日木曜日

頻出熟語を自動生成してみた

夏休みの自由研究として熟語ゲームを作ってみようと思い、頻出熟語を生成するコードを書いてみました。 自然に考えれば最も効率的なのは、形態素の n-gram からの生成です。 誰得感はありますが、良さそうな熟語生成方法についてまとめました。

漢字の熟語の生成

まず作り方ですが、ノイズが多めでも語彙数を増やしたい場合は、漢字の形態素を複数個繋げて熟語を生成します。 ただしこのやり方だと、「今見た」の「今見」などを熟語にしてしまう上に、判別が難しいです。 三文字以上の熟語はともかくニ文字熟語ならたいして生成数も変わらないので、単一の形態素だけで生成するほうがお気楽に熟語を生成できます。 ただ完璧はないので、どちらにしても多少の足切りは必要です。

二文字熟語

まず本質的な注意点は、形態素と熟語は違います。 わかりやすい例が形態素の「期生」や「年生」です。 熟語では「三期生」などの使い方をしますが、「期生」単体では使うことはありません。 つまり形態素解析辞書から、熟語ではないパターンを手動で削除したり、逆に場合によっては生成しないといけません。 そしてこれが大変。

Google n-gram で複数の形態素からニ文字熟語を作る場合、体感値的には頻度 10000 で足切りしていればいい感じです。 頻度が下がってくると、苗字・会社名・地名、最終的には普段使わないような難しい熟語をどうするかといった問題が出てきます。 苗字は「田中」「山田」などの頻出パターンをリスト化してテンプレートマッチングで削除すれば一気にノイズが消えるので、考える必要はありません。 頻度が下がると意味のある熟語が出てきてしまいますが、最低でも上位2000件くらいまでは処理したほうが良さそう。 地名「東京」は何百万回も登場しており、もはや熟語と考えたほうが良いかと思います。

方針としては、会社名・苗字・氏名はすべて削除、地名は都道府県に留めて市区町村は排除、郡市区町村と令制国名は排除、海外は国名までとしました。 市区町村は頻度別に出てくるので残しておいても良かったかもなあ。 会社名は簡単な漢字を使っている有名会社を想定してみて、会社名が出ない程度に足切りすれば良さそうです。 会社名を覚える必要はそれほどないので、基本的にはすべて削除して良いと思います。 ホームセンター系の会社が、Webページ数も多いことがあって残りやすいので注意っぽい。 日本語ウェブコーパス 2010 をベースに話をすると、 閾値としては 15000 までは必修熟語という感じですが、10000 くらいでたまに難しいもの+ノイズが少し入ってきて、 5000 くらいになると人によってはまず使わないものが出てくる。 どこで切るかは利用用途によりそう。

三文字熟語 (成語)

三文字熟語の場合は単一の形態素では数が少な過ぎるので、複数の形態素で生成します。 ニ文字熟語は単一の形態素だけでも充分、つまり 1-gram で生成できます。 しかし複数の形態素の組み合わせとなると、前後の文字をよく見ないといけないので 5-gram くらい必要になります。 頑張れば結構ノイズは減るものの完璧にはノイズが取れないので、閾値 5000 くらいまで手動調整するのが良さそうです。 頻度が 5000 以下になると使えそうな熟語より、使えない文字の羅列のほうが多くなり手間が増えます。 手作業でやるにしてもこれくらいに留めておくのが良さそう。

頻度 5000 まで 4000件ほどありましたが、ある程度は機械的に削除できました。 「校舎東」とか「会社等」などの、東西南北や〜等〜的〜様などで終わる熟語はつまらないので削ります。 このあたりの処理は説明が面倒なのでコードを見て頂いたほうが早いかと思う。

ひらがな/カタカナ熟語の生成

次にひらがな/カタカナ熟語の生成について考えます。 ひらがな+カタカナ、ひらがな+漢字、カタカナ+漢字で n文字になるような熟語はあまりないです。 あっても漢字が形容詞的に使われることがほとんどと予想できるので、熟語というよりは「トマト」のような単語探しになるかと思います。

そして結論から言えば、ひらがなはなかなかうまくいきません。 「やはり」「そして」などの接続詞や形容詞が強過ぎるので、ノイズが大きいです。 反面「うどん」のようにひらがなが異常に強い熟語 (単語) もある。 熟語を探すためだけに生成して、手動削除を前提にすれば使えないこともありませんが、データを見ても使える気はしないなあ。

よってカタカナに留めるのが無難です。 熟語ではなく単語を探すと考えれば、[カナ以外][n文字のカナ][カナ以外] となる形態素を探せば良いので、簡単です。 カタカナは擬音語や名前が多い感じです。手動で削除するよりないかなあ。 頻度が下がってくると花名などが出てきて面倒なことになってくるので、これも 10000 で足切りが楽そうです。 インターネット関連用語が多い気がしますが、ひとまず良しとしました。


ここまでの内容をまとめたデータ&コードはこちら (GitHub)。

ngram-idioms

漢字は形態素版と n-gram 版の両方を用意してみましたが、形態素版のほうが良いかと思います。 二文字熟語は高頻度ならほぼ完璧な生成です。 三文字熟語はたまに「名以外」など怪しげなものがでてきますが、これ以上綺麗に削るのは難しそうで、残りは手動削除が良いかと思います。 コード自体は四文字以上の熟語も作れるようになってますが、ニ文字熟語の組み合わせで適当に作れてしまうので面白みはないため、ゲームに使うことはないかな。

この成果を活かして作ったのが以下のゲームです。 ゲームで鍛えていれば、面倒くさい意味調べを、たぶんあまりやらないで済むようになります。どぞ。

0 件のコメント: