2018年7月24日火曜日

gensim Phrasesで新語・複合語を探す(python、自然言語処理、機械学習)

janome Analayzerで複合語(複合名詞)を考慮して形態素解析を行う。という記事を書きましたが、janome Analyzerでは名詞+名詞=複合名詞とするため、「脱炭素」など接頭詞がついたものは名詞とみなされませんでした。

今回は、機械学習ライブラリgensimのPhrasesを使って、複数回出現した単語の組み合わせを複合語として取り出す方法をやってみます。

gensim Phrase
https://radimrehurek.com/gensim/models/phrases.html

下記ブログ記事が大変詳しく解説されていて参考になりました。

コード7区:gensim の Phrases の使い方。頻出する単語ペアを検出-python
http://ailaby.com/phrases/

・インストール
!pip install gensim

gennsimのインストールはpipでできます。

・インポート
from gensim.models.phrases import Phrases , Phraser
from janome.tokenizer import Tokenizer

gensimからPhrasesとPhraserをインポートします。

・サンプル文章(エネルギー基本計画より)
text="""原子力発電所事故の経験、反省と教訓を肝に銘じて取り組むことが原点であるという姿勢は一貫して変わらない。
原子力発電所事故は、周辺国を含む国際社会に大きな不安をもたらしている。
太陽光や風力など変動する再生可能エネルギーはディマンドコントロール、揚水、火力等を用いた調整が必要であり、それだけでの完全な脱炭素化は難しい。
再生可能エネルギー・蓄電・デジタル制御技術等を組み合わせた脱炭素化エネルギーシステムへの挑戦が、幅広い産業を巻き込んで加速しつつある。"""

上記の4文をサンプルにして、Phraserに読ませる形式に変換します。
目標は

[['原子力', '発電', '所', '事故', 'の', '経験'],['変動', 'する', '再生', '可能', 'エネルギー']]

のように、二重リストの中に分かち書きされた各文書が格納されている状態です。

・改行で分割
text_split=text.split("\n")
['原子力発電所事故の経験、反省と教訓を肝に銘じて取り組むことが原点であるという姿勢は一貫して変わらない。',
 '原子力発電所事故は、周辺国を含む国際社会に大きな不安をもたらしている。',
 '太陽光や風力など変動する再生可能エネルギーはディマンドコントロール、揚水、火力等を用いた調整が必要であり、それだけでの完全な脱炭素化は難しい。',
 '再生可能エネルギー・蓄電・デジタル制御技術等を組み合わせた脱炭素化エネルギーシステムへの挑戦が、幅広い産業を巻き込んで加速しつつある。']

・分かち書きしてリストに格納
tokenizer = Tokenizer()
corpus=[]

for text_list in text_split:

    tokens = tokenizer.tokenize(text_list)
    corpus.append([token.surface for token in tokens])
    
print(corpus)
[['原子力', '発電', '所', '事故', 'の', '経験', '、', '反省', 'と', '教訓', 'を', '肝', 'に', '銘じ', 'て', '取り組む', 'こと', 'が', '原点', 'で', 'ある', 'という', '姿勢', 'は', '一貫', 'し', 'て', '変わら', 'ない', '。'], ['原子力', '発電', '所', '事故', 'は', '、', '周辺', '国', 'を', '含む', '国際', '社会', 'に', '大きな', '不安', 'を', 'もたらし', 'て', 'いる', '。'], ['太陽光', 'や', '風力', 'など', '変動', 'する', '再生', '可能', 'エネルギー', 'は', 'ディマンドコントロール', '、', '揚水', '、', '火力', '等', 'を', '用い', 'た', '調整', 'が', '必要', 'で', 'あり', '、', 'それ', 'だけ', 'で', 'の', '完全', 'な', '脱', '炭素', '化', 'は', '難しい', '。'], ['再生', '可能', 'エネルギー', '・', '蓄電', '・', 'デジタル', '制御', '技術', '等', 'を', '組み合わせ', 'た', '脱', '炭素', '化', 'エネルギー', 'システム', 'へ', 'の', '挑戦', 'が', '、', '幅広い', '産業', 'を', '巻き込ん', 'で', '加速', 'し', 'つつ', 'ある', '。']]

janomeで分かち書きして、リスト内包表記でリストに格納しています。

janomeの使い方はこちらをご覧ください。

・準備
tokenizer = Tokenizer()
corpus_phrase=corpus
phrases=""
bigram=""
transformed_bi=[]

・Phrasesで学習、Phraserでモデルを作る
phrases = Phrases(corpus_phrase,min_count=1, threshold=1.0)
bigram = Phraser(phrases)

まず、Phrasesで文章を学習します。

パラメーターでmin_countとthresholdがでてきますが、
  • 単語と単語の組み合わせが出現した回数がmin_count以下の場合、無視されます。
  • thresholdは閾値で、単語と単語の組み合わせ出現回数、各単語の出現回数などでスコアが決まり、スコアがこの値よりも大きい場合に複合語とされます。
スコアについての詳細は下記をご覧ください。

https://radimrehurek.com/gensim/models/phrases.html#gensim.models.phrases.npmi_scorer

今回は4文章と少ないので、min_count、thresholdともに1とし、2回以上単語の組み合わせが出てきた場合は複合語とみなします。

・phraserで作ったモデルで元の文章を変換
transformed_bi=list(bigram[corpus_phrase])

for words in transformed_bi:
    print(" ".join(words))
原子力_発電 所_事故 の 経験 、 反省 と 教訓 を 肝 に 銘じ て 取り組む こと が 原点 で ある という 姿勢 は 一貫 し て 変わら ない 。
原子力_発電 所_事故 は 、 周辺 国 を 含む 国際 社会 に 大きな 不安 を もたらし て いる 。
太陽光 や 風力 など 変動 する 再生_可能 エネルギー は ディマンドコントロール 、 揚水 、 火力 等_を 用い た 調整 が 必要 で あり 、 それ だけ で の 完全 な 脱_炭素 化 は 難しい 。
再生_可能 エネルギー ・ 蓄電 ・ デジタル 制御 技術 等_を 組み合わせ た 脱_炭素 化 エネルギー システム へ の 挑戦 が 、 幅広い 産業 を 巻き込ん で 加速 し つつ ある 。

モデル(bigram)で元の文章を変換します。複合語とみなした組み合わせはアンダーバーで結ばれています。

ここでは「原子力_発電」「所_事故」「再生_可能」「脱_炭素」などが複合語となりました。2つの単語の組み合わせ(bigram)のみを考慮しているので、「原子力_発電_所」や「再生_可能_エネルギー」とはなっていません。

ここで作った文章(transformed_bi)を用いて、もう一度学習、変換することで3つ(最大4つ)の単語による複合語を見つけることができます。

・trigramを見つける
tri_phrases = Phrases(transformed_bi,min_count=1, threshold=1.0)
trigram=Phraser(tri_phrases)
transformed_tri=list(trigram[transformed_bi])

for words in transformed_tri:
    print(" ".join(words))
原子力_発電_所_事故 の 経験 、 反省 と 教訓 を 肝 に 銘じ て 取り組む こと が 原点 で ある という 姿勢 は 一貫 し て 変わら ない 。
原子力_発電_所_事故 は 、 周辺 国 を 含む 国際 社会 に 大きな 不安 を もたらし て いる 。
太陽光 や 風力 など 変動 する 再生_可能_エネルギー は ディマンドコントロール 、 揚水 、 火力 等_を 用い た 調整 が 必要 で あり 、 それ だけ で の 完全 な 脱_炭素_化 は 難しい 。
再生_可能_エネルギー ・ 蓄電 ・ デジタル 制御 技術 等_を 組み合わせ た 脱_炭素_化 エネルギー システム へ の 挑戦 が 、 幅広い 産業 を 巻き込ん で 加速 し つつ ある 。

「原子力_発電_所_事故」「再生_可能_エネルギー」などができました。

・変換後の文章から複合語を取り出す。
phraseWords=[]

for sentence in transformed_tri:
    for word in sentence:
        if word.find('_') >= 0 and word not in phraseWords:
            p_word=word
            print(p_word)
            phraseWords.append(word)
原子力_発電_所_事故
再生_可能_エネルギー
等_を
脱_炭素_化

再生可能エネルギー、脱炭素化はいいのですが、「等_を」という単語の組み合わせも入っています。これは品詞を考慮せずに特定の単語の組み合わせを複合語としているためです。また、原子力発電所事故は「原子力発電所」で1単語としたいところです。

次回以降、品詞をもとに複合語の判定をしてみます。


参考:
gensim Phrase
https://radimrehurek.com/gensim/models/phrases.html
コード7区:gensim の Phrases の使い方。頻出する単語ペアを検出-python
http://ailaby.com/phrases/

Janomeで形態素解析をやってみる。
http://eneprog.blogspot.com/2018/06/janomepython.html
janome Analayzerで複合語(複合名詞)を考慮して形態素解析を行う。
http://eneprog.blogspot.com/2018/07/janome-analayzerpython.html

0 件のコメント:

コメントを投稿

//SyntaxHighlighter CDNより https://cdnjs.com/libraries/SyntaxHighlighter // 対応言語