元のページ

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

目次

想定環境

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

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import nltk
import MeCab

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

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

# sentence -> words 分割処理の例。トークン化。
mecab = MeCab.Tagger('-Ochasen')
mecab.parse(docs[0])
node = mecab.parseToNode(docs[0])
print('\n# sentence -> words 分割処理の例。トークン化。')
while node:
    print(node.surface, node.feature, sep='\t')
    node = node.next

# token を基本形に修正する例。ステミング。
mecab.parse(docs[0])
node = mecab.parseToNode(docs[0])
print('\n# token を基本形に修正する例。ステミング。')
while node:
    fs = node.feature.split(",")
    print("surface={0} -> fs[6]={1}".format(node.surface, fs[6]))
    node = node.next

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

    <使用しているライブラリの説明>
    nltk.RegexpTokenizer: 文章(doc)をパターンマッチングで文(sentence)に分割する。
    mecab.parseToNode: 形態素解析結果を双方向連結リストとして出力。node.next <-> node.prev
    '''
    jp_sent_tokenizer = nltk.RegexpTokenizer('[^ 「」!?。]*[!?。]')
    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):
            mecab.parse(sent)
            node = mecab.parseToNode(sent)
            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

print('\n# 日本語文書集合 docs からの単語コードブック作成例。')
codebook = collect_words_jp(docs)
codebook.sort()
print(codebook)



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

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

print('\n#コードブックを素性とする文書ベクトルを作る(直接ベクトル生成)')
data = make_vectors_jp(docs, codebook)
print(data)

print('\n# 元の文書集合')
print(docs)



クラスタリング(K-means)してみる

#教師無し学習(K-means)で2クラスタに分類してみる
from sklearn import cluster
k_means = cluster.KMeans(n_clusters=2)
k_means.fit(data)
k_means.labels_





参考サイト一覧