テキストのポジネガ判定 Judge Positive vs Negative of a Text

テキストのポジネガ判定 Judge Positive vs Negative of a Text


昨年、twitterに投稿される莫大な数のツイートを解析して株価を予想したという論文が発表されて話題になった。今回、その準備となる実験を行った。与えられたテキストのポジティブ、ネガティブを判定した。


Method

  1. 与えられたテキストを形態素解析した。
  2. テキストから名詞、動詞、形容詞、副詞、助動詞を抽出した(極性辞書にそれら品詞のみ収録されている)。
  3. 抽出された言葉を、単語感情極性判定辞書から探し、極性ポイントをあてはめる。
  4. 極性ポイントの平均値[-1,1]をその文章のpointとした。

Source code


import MeCab
import pandas as pd
import numpy as np

class Text_pn():
    def __init__(self):
        self.m = MeCab.Tagger()
    # set pn dictionary
        self.pndic = {}
        with open('pn_ja.dic','r') as f:
            parts = [line.split(':')[2] for line in f]
            parts = set(parts)
            for part in parts:
                self.pndic[part]=[]
        with open('pn_ja.dic', 'r') as f:
            for line in f:
                line = line.strip('\n')
                line = line.split(':')
                line[3] = float(line[3])
                self.pndic[line[2]].append({'kanji':line[0],'yomi':line[1],'point':line[3]})
                
    def mecab_list(self, s):
        '''return list of mecab analysis'''
        s = self.m.parse(s)
        return [word.split(',') for word in s.replace('\t', ',').split('\n')[:-2]]
    
    def pn(self, s):
        '''return average positive vs negative points of text'''
        points_of_s = []
        for line in self.mecab_list(s):
            try:
                word = line[11]
                word_part = line[1]
            except IndexError as e:
                #skip symbols like (, ), $, %, 
                continue
            if word_part in self.pndic.keys():
                '''if word part is noun, verb, adjective and auxiliary.'''
                for i in self.pndic[word_part]: # for each word i = dict in pndict=list
                    if word == i['kanji'] or word == i['yomi']:
                        points_of_s.append(i['point'])
                        print(word, i['point'])
                        break
                else:
                    print('{0} is not in the pn-dictionary.'.format(word))
            else:
                continue
        points_of_s = np.array(points_of_s)
        avg_point = np.mean(points_of_s)
        avg_point = round(avg_point, 2)
        print('{0}\npoint = {1}'.format(s, avg_point))
        return avg_point             
    
if __name__=='__main__':
    s = u'トンネルを抜けると雪国であった。夜の底が白くなった。'
    text_pn = Text_pn()
    text_pn.pn(s)

MeCabで使う辞書は、デフォルトのIPAではなくUnidicにした。変更方法は以前の記事参照:
MeCab-Pythonを使ったIPADICとUNIDICの比較

解析の高速化のため、Positive vs Negative 辞書を、名詞、動詞、形容詞、副詞、助動詞をキーワードとした辞書にして、Valuesをリストにした。リストの中には、単語ごとに漢字、読み、ポイントを辞書にして格納した。こうすることで、名詞は名詞だけの辞書から、動詞は動詞だけの辞書から探し出すことができる。


Result

いくつかのテキストを試した。テキストのポジネガ指数は-1を最悪、1を最高とした実数をとります。


SHARP公式twitterアカウントから


きょう 0.971487
バレンタイン is not in the pn-dictionary.
だ is not in the pn-dictionary.
ふんどし -0.414723
日 -0.903573
だ is not in the pn-dictionary.
煮干し is not in the pn-dictionary.
日 -0.903573
だ is not in the pn-dictionary.
バツ is not in the pn-dictionary.
イート is not in the pn-dictionary.
忙しい -0.993042

( ´-`).。oO(きょうはバレンタインだし、ふんどしの日だし、煮干しの日だし、ハピバツイートも忙しい)

point = -0.45

小説「雪国」の冒頭から

トンネル -0.561687
抜ける -0.977282
雪国 -0.258137
だ is not in the pn-dictionary.
ある is not in the pn-dictionary.
た is not in the pn-dictionary.
夜 -0.437052
底 -0.545065
白い -0.974579
なる -0.749541
た is not in the pn-dictionary.
トンネルを抜けると雪国であった。夜の底が白くなった。
point = -0.64

小説「伊豆の踊子」の冒頭から

道 -0.377834
つづら折り is not in the pn-dictionary.
なる -0.749541
いよいよ -0.50333
天城 is not in the pn-dictionary.
峠 -0.453942
近づく is not in the pn-dictionary.
た is not in the pn-dictionary.
思う -0.902339
ころ 0.122945
雨足 is not in the pn-dictionary.
杉 -0.193417
密林 -0.315017
白い -0.974579
染める -0.801719
すさまじい -0.736156
早い 0.939701
麓 -0.678802
追う -0.854682
来る -0.607983
た is not in the pn-dictionary.
道がつづら折りになって、いよいよ天城峠に近づいたと思うころ、雨足が杉の密林を白く染めながら、すさまじい早さで麓から私を追って来た。
point = -0.47

美輪明宏の名言から

野 -0.258563
咲く -0.958514
花 is not in the pn-dictionary.
役目 -0.824992
ある is not in the pn-dictionary.
ます is not in the pn-dictionary.
この世 is not in the pn-dictionary.
必要 -0.924249
だ is not in the pn-dictionary.
ない -0.54371
人 is not in the pn-dictionary.
いる -0.365478
ます is not in the pn-dictionary.
ぬ -0.998545
気付く -0.28839
どう -0.941861
だ is not in the pn-dictionary.
です is not in the pn-dictionary.

野に咲く花にも役目があります。

この世に必要でない人はいません。

それに気付くかどうか。

それが大事なのです。

point = -0.68

松岡修造の名言から 1

本気 0.0212263
だ is not in the pn-dictionary.
なる -0.749541
自分 is not in the pn-dictionary.
変わる is not in the pn-dictionary.
本気 0.0212263
だ is not in the pn-dictionary.
なる -0.749541
全て is not in the pn-dictionary.
変わる is not in the pn-dictionary.

本気になれば自分が変わる! 
本気になれば全てが変わる!!

point = -0.36

松岡修造の名言から 2

一 is not in the pn-dictionary.
番 -0.338417
なる -0.749541
いう is not in the pn-dictionary.
た is not in the pn-dictionary.
日本 is not in the pn-dictionary.
一 is not in the pn-dictionary.
なり is not in the pn-dictionary.
っつう is not in the pn-dictionary.
た is not in the pn-dictionary.
ぬるま湯 is not in the pn-dictionary.
つかう is not in the pn-dictionary.
てる is not in the pn-dictionary.
だ is not in the pn-dictionary.
ない -0.54371

一番になるっていったよな?
日本一なるっつったよな!

ぬるま湯なんか
つかってんじゃねぇよお前!!

point = -0.54

松岡修造の名言から 3

もっと -0.237262
熱い -0.719419
なれる 0.991114
熱い -0.719419
血 -0.526678
燃やす -0.749639
てく is not in the pn-dictionary.
人間 -0.699474
熱い -0.719419
なる -0.749541
た is not in the pn-dictionary.
とき -0.0953988
ホント is not in the pn-dictionary.
自分 is not in the pn-dictionary.
出会える is not in the pn-dictionary.
だ is not in the pn-dictionary.

もっと熱くなれよ…!!
熱い血燃やしてけよ…!!

人間熱くなったときが
ホントの自分に出会えるんだ!

point = -0.42

松岡修造の名言から 4

言い訳 is not in the pn-dictionary.
する -0.492314
てる is not in the pn-dictionary.
だ is not in the pn-dictionary.
ない -0.54371
です is not in the pn-dictionary.
できる -0.987614
ない -0.999997
こと -0.159652
無理 -0.921332
だ is not in the pn-dictionary.
諦める 0.0123167
てる is not in the pn-dictionary.
だ is not in the pn-dictionary.
ない -0.54371
です is not in the pn-dictionary.
駄目 -0.841911
だ is not in the pn-dictionary.
駄目 -0.841911
だ is not in the pn-dictionary.
あきらめる 0.0123167
だめ -0.841911
だ is not in the pn-dictionary.
できる -0.987614
できる -0.987614
絶対 -0.383341
できる -0.987614
だ is not in the pn-dictionary.

言い訳してるんじゃないですか? 
できないこと、無理だって、
諦めてるんじゃないですか?

駄目だ駄目だ!
あきらめちゃだめだ!

できる!できる!
絶対にできるんだから!

point = -0.66

Discussion 考察


二重否定を正しく解析できない

単語ごとにポジティブ、ネガティブをとるので、「ないはずがない」と言うような、二重否定ではネガティブ二個分にカウントされる。単語のニュアンスや意味は単語それ自体だけで決まるものではないので、形態素に分割してしまうと、単語の意味はとれなくなる。自動翻訳で使われるように、単語とその周辺の単語から意味を解析する必要がある。
他にも、「あきらめる」、「ない」がネガティブだとすると、「あきらめない」という言葉はポジティブだと思うが、「あきらめる + ない」と解析されるとダブルでネガティブになってしまう。

辞書に否定語が多い

参考文献
にある通り、
全単語55,125中、ポジティブワード(スコア0以上)が5,242語、ネガティブワードが49,983語
と ポジティブワードは10%ほどしかない。それゆえ解析結果もネガティブになりやすい。これは今回使わせていただいた辞書自体がもつ問題である。結果を見ての通り、

できる -0.987614
あきらめる 0.0123167

など明らかに怪しい部分もある。
単語の極性を電子のスピン方向とした平均場近似モデルで計算したとアブストラクトに書いてあった。IsingやHartree-Fockとどういった関連のあるアルゴリズムを使ったのかわからない。まるで強磁性じゃないか。論文は読んでいない。

今後

よりよい辞書を探す。
プログラムが単語の意味まで考慮して計算できるようにする。
テキストの解析から、その書いた人の気持を推察できるようにしたい。
加速度や位置情報や体温なども合わせて関連性を発見していきたい。

BIBLIOGRAPHY 参考文献

コメント

人気の投稿