自然言語処理入門: N-gramモデル + 出現回数による文書ベクトル生成 (nltk.ngrams + nltk.FreqDist) (情報工学実験 4 : データマイニング班)
目次- 想定環境
- 文書集合からn-gramsモデルにより素性集合(コードブック)を作る
素性=特徴ベクトルを構成する要素。素性が10個なら、1文書を10次元の特徴ベクトルとして表現することになる。
- コードブックを素性とする文書ベクトルを作る (直接ベクトル生成)
- クラスタリング(K-means)してみる
想定環境
- OS: Mac OS X 10.9.x (10.7.x以降であれば同じ方法で問題無いはず)
- Python: 3.4.x
- numpy: 1.9.0 (numpy.version)
- scipy: 0.14.0 (scipy.version)
- NLTK: 3.0.0 (nltk.__version__)
文書集合からn-gramsモデルにより素性集合(コードブック)を作る
- nltk.util.ngrams(): 入力された文字列をn-gramsに分割。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#生文書の用意(リストの1要素=1文書)
docs = []
docs.append("会場には車で行きます。")
docs.append("会場には自動車で行きます。")
docs.append("会場には自転車で行きます。")
docs.append("お店には自転車で行きます。")
print(docs)
#NLTKで n-gram(n=2) してみる
# n=2: 2-letters を1つの素性とする。
import nltk
def collect_ngram_words(docs, n):
'''文書集合 docs から n-gram のコードブックを生成。
docs は1文書を1要素とするリストで保存しているものとする。
句読点等の処理は無し。
'''
codebook = []
for doc in docs:
this_words = nltk.ngrams(doc, n)
for word in this_words:
if word not in codebook:
codebook.append(word)
return codebook
n = 2
codebook = collect_ngram_words(docs, n)
print(codebook)
コードブックを素性とする文書ベクトルを作る (直接ベクトル生成)
- nltk.probability.FreqDist(): 素性集合の出現分布を計算。
def make_vectors(docs, codebook, n):
'''文書集合docsから、codebook(n-gram)に基づいた文書ベクトルを生成。
codebook毎に出現回数をカウントし、ベクトルの要素とする。
出力 vectors[] は、「1文書の特徴ベクトルを1リスト」として準備。
'''
vectors = []
for doc in docs:
this_words = nltk.ngrams(doc, n)
fdist = nltk.FreqDist()
for word in this_words:
fdist[word] += 1
this_vector = []
for word in codebook:
this_vector.append(fdist[word])
vectors.append(this_vector)
return vectors
data = make_vectors(docs, codebook, n)
print(data)
# len(data) = 文書数。
# len(data[0]) = ベクトルの要素数 = 全素性数。
# data[0][0] = 文書0におけるcodebook[0]の出現回数。
クラスタリング(K-means)してみる
#教師無し学習(K-means)で2クラスタに分類してみる from sklearn import cluster k_means = cluster.KMeans(n_clusters=2) k_means.fit(data) k_means.labels_