pythonを使ったテキストマイニングの前処理メモ。名詞を抽出し、ストップワードや珍しい単語を除去する方法。
名詞を抽出し、ストップワードや珍しい単語を除去する
テキストマイニングにおける定番の前処理らしいです。pythonで試してみました。
もっと膨大な文章集合を実践的に扱う場合は、「10%以上の文章にでてきた単語を除去」とかもやるみたいです。正解があるわけではなく、扱うデータと目的に合わせて適宜変えるとよいと思います。
#coding:utf-8
import MeCab
def extractKeyword(text):
u"""textを形態素解析して、名詞のみのリストを返す"""
tagger = MeCab.Tagger()
encoded_text = text.encode('utf-8')
node = tagger.parseToNode(encoded_text).next
keywords = []
while node:
if node.feature.split(",")[0] == "名詞":
keywords.append(node.surface)
node = node.next
return keywords
def splitDocument(documents):
u"""文章集合を受け取り、名詞のみ空白区切りの文章にして返す"""
splitted_documents = []
for d in documents:
keywords = extractKeyword(d)
splitted_documents.append(' '.join(keywords))
return splitted_documents
def removeStoplist(documents, stoplist):
u"""ストップワードを取り除く"""
stoplist_removed_documents = []
for document in documents:
words = []
for word in document.lower().split():
if word not in stoplist:
words.append(word)
stoplist_removed_documents.append(words)
return stoplist_removed_documents
def getTokensOnce(all_tokens):
u"""一回しか出現しない単語を返す"""
tokens_once = set([])
for word in set(all_tokens):
if all_tokens.count(word) == 1:
tokens_once.add(word)
return tokens_once
def removeTokensOnce(documents, tokens_once):
u"""一回しか出現しない単語を取り除く"""
token_removed_documents = []
for document in documents:
words = []
for word in document:
if word not in tokens_once:
words.append(word)
token_removed_documents.append(words)
return token_removed_documents
if __name__ == "__main__":
raw_documents = [u'私はやっぱりピアノを弾きます。',
u'りんごは食べないですねー。',
u'りんごは食べないですねー。',
u'プレステのバイオハザード2懐かしいです。',
u'今日が返却期限だったからあのDVDは返却したよ。']
print 'raw_documents:'
for d in raw_documents:
print d
print ''
# 空白区切りの文字列を入れるリスト
splitted_documents = splitDocument(raw_documents)
print 'splitted_documents:'
for d in splitted_documents:
print d
print ''
stoplist = set('プレ ハザード'.split()) # 通常の文字列でよい
print 'stoplist:'
for s in stoplist:
print s,
print '\\n'
# ストップワードを除いた二重リスト
stoplist_removed_documents = removeStoplist(splitted_documents, stoplist)
print 'stoplist_removed_documents:'
for t in stoplist_removed_documents:
for w in t:
print w,
print ''
print ''
# 全ての単語を重複ありで含むリスト
all_tokens = sum(stoplist_removed_documents, [])
print 'all_tokens:'
for t in all_tokens:
print t,
print '\\n'
# 一回しかでてこない単語のみを持つセット
tokens_once = getTokensOnce(all_tokens)
print 'tokens_once:'
for t in tokens_once:
print t,
print '\\n'
# 一回しかでてこない単語を除いた最終的なテキスト
preprocessed_documents = removeTokensOnce(stoplist_removed_documents, tokens_once)
print 'preprocessed_documents:'
for d in preprocessed_documents:
for w in d:
print w,
print ''
出力結果は下記の通り。
raw_documents: 私はやっぱりピアノを弾きます。 りんごは食べないですねー。 りんごは食べないですねー。 プレステのバイオハザード2懐かしいです。 今日が返却期限だったからあのDVDは返却したよ。 splitted_documents: 私 ピアノ りんご りんご プレ ステ バイオ ハザード 2 今日 返却 期限 DVD 返却 stoplist: ハザード プレ stoplist_removed_documents: 私 ピアノ りんご りんご ステ バイオ 2 今日 返却 期限 dvd 返却 all_tokens: 私 ピアノ りんご りんご ステ バイオ 2 今日 返却 期限 dvd 返却 tokens_once: 今日 ステ 期限 dvd 2 私 ピアノ バイオ preprocessed_documents: りんご りんご 返却 返却
参考リンク
LSIやLDAを手軽に試せるGensimを使った自然言語処理入門
gensimに日本語Wikipediaを取り込むためのスクリプト
