自然言語処理入門: 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_