あれもPython,これもPython

Pythonで世界を包みたい

Pythonで自然言語処理をしてみる_トピックモデル

Python自然言語処理を行いたい場合、
選択肢は、

  • NLTK
  • Sci-kit learn
  • gensim

があります。

NLTKはフルスタックツールで、
下記の本でも丁寧に記載されています。

sklearnはtf-idfなどを扱うためのクラスを持っています。

で、最近は残りのgensimを勉強しています。

でもその前に

日本語で自然言語処理を行う場合、
単語ごとの分割が問題になってきます。
英語などは単語ごとに空白が入っているので、splitしやすいのですが、
日本語だとその分割作業があります。

Pythonだと、
Pythonmecabラッパーやjanomeなどで、
この作業が可能です。

esu-ko.hatenablog.com

で、gensim

gensimは結構色々な作業が可能です。
有名ドコロでは、word2vecがあります。

が、今回はトピックモデルについて勉強しました。

トピックモデルは文章の分類ができます。

gensimを使う

最初はcondaで入れたのですが、入れた途端condaが壊れたんで、
pipで入れなおしました。

pip install gensim

文章をjanomemecabで分割して、こんな感じの単語のリストにしておきます。

corpus=
[
    [文章Aの単語,文章Aの単語,・・・,文章Aの単語],
    [文章Bの単語,文章Bの単語,・・・,文章Bの単語],
    ・・・
    [文章Cの単語,文章Cの単語,・・・,文章Cの単語],

]

で、このリストを、gensimで扱える形に変換します。
まずは単語と単語IDの辞書にします。

from gensim import models,corpora

dictionary = corpora.Dictionary(corpus)
dictionary.save('./tweet.dict')

続いて、この辞書を使って、トピックモデル用のインプットデータを作ります。
最初の分割したデータを食べさせます。

input_data = [dictionary.doc2bow(text) for text in corpus]
    corpora.MmCorpus.serialize('./シリアライズしたなめ.mm',input_data)

最後にこれを用いてトピックモデルをつくります。
この時、使用するデータの形が特殊なので注意が必要です。
最初の行にデータの行数、その後に単語空白区切りの行データが続きます。

100000
文章Aの単語 文章Aの単語・・・文章Aの単語\n
文章Bの単語 ・・・

上記の形に変換したファイルを用意します。

input_text = ""
    input_text+= unicode(10000)+"\n"
    for line in corpus:
        input_text += " ".join(line)+"\n"
    with open("input_data.txt","wb") as f:
        input_text = input_text.encode("utf-8")
        f.write(input_text)

最後にこれをもとにモデルを使って完了です。

input_data = corpora.lowcorpus.LowCorpus("input_data.txt")
    mdl = models.ldamodel.LdaModel(
            input_data,
            num_topics = 40,
            id2word=input_data.id2word
        )

    with open("mdl.pickle","wb") as f:
        pickle.dump(mdl,f)
    print "mdl done"

結果はピックル化しておきました。
と、ここまででモデルは作れるんですが、
読み取りなどの勉強が必要そうです・・・。