レビューのテキストに含まれる語には、どういったものがあるか。特に、上位に含まれる語について、分布を見てみます。
scikit-learnのCountVectorizerを使って実装します。
def get_top_n_words(corpus, n=20, is_stop_words=False):
vectorizer = CountVectorizer(stop_words='english') if is_stop_words else CountVectorizer()
X = vectorizer.fit_transform(corpus)
X_sum = X.sum(axis=0)
words_freq = [(word, X_sum[0, idx]) for word, idx in vectorizer.vocabulary_.items()]
words_freq = sorted(words_freq, key=lambda x: x[1], reverse=True)
return words_freq[:n]
fit_transformで、corpusに含まれるunique wordのcountを含むarrayが得られるので、sumでword毎のcountを計算しています。
公式の例から引用。
>>> from sklearn.feature_extraction.text import CountVectorizer
>>> corpus = [
... 'This is the first document.',
... 'This document is the second document.',
... 'And this is the third one.',
... 'Is this the first document?',
... ]
>>> vectorizer = CountVectorizer()
>>> X = vectorizer.fit_transform(corpus)
>>> print(vectorizer.get_feature_names())
['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
>>> print(X.toarray())
[[0 1 1 1 0 0 1 0 1]
[0 2 0 1 0 1 1 0 1]
[1 0 0 1 1 0 1 1 1]
[0 1 1 1 0 0 1 0 1]]
このsumを計算すると以下のようにword毎のカウントが得られます。
>>> X.sum(axis=0)
matrix([[1, 4, 2, 4, 1, 1, 4, 1, 4]], dtype=int64)
では、分布を見てみます。上段のグラフがStop wordsを含むもの、下段がStop wordsを除いたものです。
上位の語のリストで見ると、結構似ています。goodやbadのような感情分析に有効であると思われる語だけでなく、movieやfilmのようなニュートラルな語も含まれています。positiveなテキストにおいて、goodはbadより多く含まれていますが、negativeなテキストではbadはgoodより多いものの、同じくらい多く含まれていることも分かりました。