元のページ

ステージ3-2: タームを素性とする特徴ベクトル生成の例(日本語編), 文分割 + トークン化 + ステミング + ストップワード除去 (情報工学実験 3 : データマイニング班)

目次

想定環境

文書集合からターム素性集合(コードブック)を作る

docs = []
docs.append(u"会場には車で行きます。行きます。")
docs.append(u"会場には自動車で行きます。")
docs.append(u"会場には自転車で行きます。")
docs.append(u"お店には自転車で行きます。")

# doc -> sentences分割処理の例。
import nltk
from prettyprint import pp
jp_sent_tokenizer = nltk.RegexpTokenizer(u'[^ 「」!?。]*[!?。]')
sents = jp_sent_tokenizer.tokenize( docs[0] )
pp(sents)

# sentence -> words 分割処理の例。トークン化。
#  (注意) MeCabに渡すテキストは UTF-8 でエンコード必須。
#  最初から全てを UTF-8 化しておくと良さそうだが、
#  一方、NLTKの一部は UTF-8 では正しく処理できないこともあるため、
#  ここでは docs に文書を保存する際には unicode 指定している。
#  もし文書 dcos を utf-8 保存するなら、NLTKへは unicode 変換して渡そう。
import MeCab
mecab = MeCab.Tagger('-Ochasen')
node = mecab.parseToNode(docs[0].encode('utf-8'))
while node:
    print "surface=",
    print node.surface,
    print "feature=",
    print node.feature
    node = node.next

# token を基本形に修正する例。ステミング。
node = mecab.parseToNode(docs[0].encode('utf-8'))
while node:
    fs = node.feature.split(",")
    print "surface=%s -> fs[6]=%s" % (node.surface, fs[6])
    node = node.next

def collect_words_jp(docs):
    u'''日本語文書集合 docs からの単語コードブック作成例。
    シンプルに文書集合を予め決めうちした方式で処理する。
    必要に応じて指定できるようにしていた方が使い易いかも。

    <使用しているライブラリの説明>
    nltk.RegexpTokenizer: 文章(doc)をパターンマッチングで文(sentence)に分割する。
    mecab.parseToNode: 形態素解析結果を双方向連結リストとして出力。node.next <-> node.prev
    '''
    import nltk
    jp_sent_tokenizer = nltk.RegexpTokenizer(u'[^ 「」!?。]*[!?。]')
    import MeCab
    mecab = MeCab.Tagger('-Ochasen')
    
    codebook = []
    pos = ['形容詞', '形容動詞','感動詞','副詞','連体詞','名詞','動詞']
    jp_sent_tokenizer = nltk.RegexpTokenizer(u'[^ 「」!?。]*[!?。]')
    stopwords = ["", "*", "これ", "あれ", "は", "が", "の", "を", "です", "、", "。"]
    for doc in docs:
        for sent in jp_sent_tokenizer.tokenize(doc):
            node = mecab.parseToNode(sent.encode('utf-8'))
            while node:
                fs = node.feature.split(",")
                if fs[0] in pos:
                    this_word = fs[6]
                    if this_word not in codebook and this_word not in stopwords:
                        codebook.append(this_word)
                node = node.next
    return codebook

codebook = collect_words_jp(docs)
codebook.sort()
pp(codebook)




コードブックを素性とする文書ベクトルを作る (直接ベクトル生成)

def make_vectors_jp(docs, codebook):
    u'''コードブックを素性とする文書ベクトルを作る(直接ベクトル生成)
    n-gramモデルの例と流れは一緒。
    「doc=1文とは限らない」ケースにも対応するよう拡張。
    '''
    vectors = []
    jp_sent_tokenizer = nltk.RegexpTokenizer(u'[^ 「」!?。]*[!?。]')
    for doc in docs:
        this_vector = []
        fdist = nltk.FreqDist()
        for sent in jp_sent_tokenizer.tokenize(doc):
            node = mecab.parseToNode(sent.encode('utf-8'))
            while node:
                fs = node.feature.split(",")
                this_word = fs[6]
                fdist.inc(this_word)
                node = node.next
        for word in codebook:
            this_vector.append(fdist[word])
        vectors.append(this_vector)
    return vectors

data = make_vectors_jp(docs, codebook)
data





参考サイト一覧