stMind

about Tech, Computer vision and Machine learning

imdb_reviews datasetのレビューに含まれるunique wordの上位N件の分布

レビューのテキストに含まれる語には、どういったものがあるか。特に、上位に含まれる語について、分布を見てみます。

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を除いたものです。

f:id:satojkovic:20200704171438p:plain

上位の語のリストで見ると、結構似ています。goodやbadのような感情分析に有効であると思われる語だけでなく、movieやfilmのようなニュートラルな語も含まれています。positiveなテキストにおいて、goodはbadより多く含まれていますが、negativeなテキストではbadはgoodより多いものの、同じくらい多く含まれていることも分かりました。