毎日テキストマイニング

180日間、毎日テキストマイニングをするブログ

2018/7/11【19日目】Pythonではじめてのネガポジ判定

今日からネガポジ判定を勉強していきたいと思います。 簡単に説明しておきますと、ある単語がネガティブな言葉なのかポジティブな言葉なのかを判定し、得点化することをいうそうです。Weblioの辞書によると次のように定義されています。

ネガポジ判定とは、主に人の発言や発想などが、前向き(ポジティブ)か後ろ向き(ネガティブ)かを判定することである。

それで、ネガポジ判定を行う方法ですが、ポジティブかネガティブかを判定する辞書を作る必要があるそうです。すでに単語ごとにネガティブかポジティブかを割り当てた辞書が存在するらしいので、今回はこれを使用させてもらいます。(研究目的の利用に限り公開します、と書かれていますが一応これも研究ということで。。。)。

単語感情極性対応表

http://www.lr.pi.titech.ac.jp/~takamura/pndic_ja.html

中のデータはこんな感じです。1に近いほどポジティブで、-1に近いほどネガティブと判定されます。

優れる:すぐれる:動詞:1
良い:よい:形容詞:0.999995
喜ぶ:よろこぶ:動詞:0.999979
褒める:ほめる:動詞:0.999979
(中略)
酷い:ひどい:形容詞:-0.999997
病気:びょうき:名詞:-0.999998
死ぬ:しぬ:動詞:-0.999999
悪い:わるい:形容詞:-1

55125行もあります。Atom上でcsv形式に置換しようと思いましたが、膨大すぎてAtomがクラッシュします笑。ひとまずこの膨大なデータを[np_jp.dic]として保存し、csv形式への置換はPythonでやることにします。

単語を判定する

csv形式に置換するというよりは、:で区切れば良いそうで、これはPandasでできるみたいです。Pandasをimportして、pandasのread_csvメソッドに引数でsepオプションを付ければ任意の文字で分けることができるようです。ここでは:で分けるようにしたいと思います。

import pandas as pd
npjp = pd.read_csv('./akb_dic/np_jp.dic', sep=‘:’)

読み込めたようなので、printしてみます。

print(npjp)

実行結果

         優れる    すぐれる   動詞         1
0         良い      よい  形容詞  0.999995
1         喜ぶ    よろこぶ   動詞  0.999979
2        褒める     ほめる   動詞  0.999979
3       めでたい    めでたい  形容詞  0.999645
4         賢い    かしこい  形容詞  0.999486
(省略)

無事に分けれましたが、0番目が”良い”になってしまっていますね。Pandasだと読み込んだファイルの0行目をヘッダーとして扱うみたいです。読み込み時にnameを引数として渡すと、ヘッダーを指定できるそうです。ここでは左から'Tango','Yomi','Hinshi', 'Score’としたいと思います。

npjp = pd.read_csv('./akb_dic/np_jp.dic',
                   sep=':', 
                   encoding='utf-8',
                   names=('Tango','Yomi','Hinshi', 'Score'))

改めてprint。

       Tango    Yomi Hinshi     Score
0        優れる    すぐれる     動詞  1.000000
1         良い      よい    形容詞  0.999995
2         喜ぶ    よろこぶ     動詞  0.999979
3        褒める     ほめる     動詞  0.999979
4       めでたい    めでたい    形容詞  0.999645

綺麗にできました。 しかしこのままではあまりにも膨大なので、{“Tango”;Score}という風に辞書型に変換したいと思います。 列と列をまとめて辞書型に変換するのは15日目前半で行ったdic = dict(zip(terms, X_train_tf[i].toarray()[0]))で行いたいとおもいます。

pandasで列を指定するのは変数[“列名”]でいけるみたいです。こんな感じです。

tango_retu = npjp['Tango']
score_retu = npjp['Score']
npjp_dic   = dict(zip(tango_retu, score_retu))
print(npjp_dic["テレビ"])

実行結果

-0.719902

なんでテレビがこんなにもネガティブなスコアをつけられているのか謎ですが、とりあえずスコアを表示できました。

呟きをネガティブかポジティブか判定する

続いて呟きの内容をスコア付けして、呟きの内容がネガティブなのかポジティブなのかを判定したいと思います。

ひとまず、今日の呟きで一番上にあったものを判定したいと思います。

tweet = "SHOWROOM配信最後までありがとうございました❣️??さけるチーズを食べまして。147本にさきました。

見た印象としましては、だいぶポジティブだと思いますが、いったいどう判定されるのでしょうか? ひとまずいつも通りにMeCabで単語ごとに分けます。改行がいらないのでだいぶシンプルですね。

import MeCab

tagger = MeCab.Tagger ("")

kaisekiyou = tweet.split('¥n')
string = ' '.join(kaisekiyou)
mecab = tagger.parse(string)

kaigyou = mecab.splitlines()
print(kaigyou)

実行結果

['SHOWROOM\t名詞,固有名詞,組織,*,*,*,*', '配信\t名詞,サ変接続,*,*,*,*,配信,ハイシン,ハイシン', '最後\t名詞,一般,*,*,*,*,最後,サイゴ,サイゴ', 'まで\t助詞,副助詞,*,*,*,*,まで,マデ,マデ', 'ありがとう\t感動詞,*,*,*,*,*,ありがとう,アリガトウ,アリガトー', 'ござい\t助動詞,*,*,*,五段・ラ行特殊,連用形,ござる,ゴザイ,ゴザイ', 'まし\t助動詞,*,*,*,特殊・マス,連用形,ます,マシ,マシ', (中略)’。\t記号,句点,*,*,*,*,。,。,。', '147\t名詞,数,*,*,*,*,*', '本\t名詞,接尾,助数詞,*,*,*,本,ホン,ホン', 'に\t助詞,格助詞,一般,*,*,*,に,ニ,ニ', 'さき\t動詞,自立,*,*,五段・カ行イ音便,連用形,さく,サキ,サキ', 'まし\t助動詞,*,*,*,特殊・マス,連用形,ます,マシ,マシ', 'た\t助動詞,*,*,*,特殊・タ,基本形,た,タ,タ', '。\t記号,句点,*,*,*,*,。,。,。', 'EOS']

それで、これを単語ごとに辞書型のTangoと対応させればよさそうです。 ひとまずリスト毎に区切っていきたいので、split(‘\t’)を使います。

for tango_list in kaigyou:
    tab = tango_list.split('\t')
    print(tab)

実行結果。

['SHOWROOM', '名詞,固有名詞,組織,*,*,*,*']
['配信', '名詞,サ変接続,*,*,*,*,配信,ハイシン,ハイシン']
['最後', '名詞,一般,*,*,*,*,最後,サイゴ,サイゴ']
['まで', '助詞,副助詞,*,*,*,*,まで,マデ,マデ']
['ありがとう', '感動詞,*,*,*,*,*,ありがとう,アリガトウ,アリガトー']
['ござい', '助動詞,*,*,*,五段・ラ行特殊,連用形,ござる,ゴザイ,ゴザイ']
['まし', '助動詞,*,*,*,特殊・マス,連用形,ます,マシ,マシ']
['た', '助動詞,*,*,*,特殊・タ,基本形,た,タ,タ']
['❣', '名詞,サ変接続,*,*,*,*,*']
['️', '記号,一般,*,*,*,*,*']
['??', '名詞,サ変接続,*,*,*,*,*']
['さける', '動詞,自立,*,*,一段,基本形,さける,サケル,サケル']
['チーズ', '名詞,一般,*,*,*,*,チーズ,チーズ,チーズ']
['を', '助詞,格助詞,一般,*,*,*,を,ヲ,ヲ']
['食べ', '動詞,自立,*,*,一段,連用形,食べる,タベ,タベ']
['まし', '助動詞,*,*,*,特殊・マス,連用形,ます,マシ,マシ']
['て', '助詞,接続助詞,*,*,*,*,て,テ,テ']
['。', '記号,句点,*,*,*,*,。,。,。']
['147', '名詞,数,*,*,*,*,*']
['本', '名詞,接尾,助数詞,*,*,*,本,ホン,ホン']
['に', '助詞,格助詞,一般,*,*,*,に,ニ,ニ']
['さき', '動詞,自立,*,*,五段・カ行イ音便,連用形,さく,サキ,サキ']
['まし', '助動詞,*,*,*,特殊・マス,連用形,ます,マシ,マシ']
['た', '助動詞,*,*,*,特殊・タ,基本形,た,タ,タ']
['。', '記号,句点,*,*,*,*,。,。,。']
['EOS']

このリストの[0]番目をnpjp_dicと比較させます。npjp_dicの中に[tab0]の単語があれば、スコアを返します。

for tango_list in kaigyou:
    tab = tango_list.split('\t')
    if tab[0] in npjp_dic:
        pn_score = npjp_dic[tab[0]]
    else:
        pn_score = '辞書に単語がないです'
    print(pn_score)

実行結果。

辞書に単語がないです
-0.249507
-0.658284
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
-0.468381
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
-0.902223
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです

あれ、思ったよりも辞書にある単語が少ないですね。。。拾った単語は下記の通りです。

配信:-0.249507
最後:-0.658284
チーズ:-0.468381
本:-0.902223

拾った単語だけを見ると「配信後の最後のチーズ1本」みたいな感じでめちゃくちゃネガティブですね。 調整が必要そうなので、明日はもう少しいじってみたいと思います。

今日の結果

AKBのメンバーによる呟きは44件でした。 一番ポジティブな呟きは下記でした。

"誕生日当日にお祝いしてくれました。
本当にありがとう。
大好き❤︎そしてみんな可愛い❤︎
みんなずっとお友達でいてね❤︎ https://t.co/X8C9tewahN"

スコアはこんな感じです笑。相変わらず、登録されている単語が少ないですね。

0.396127
-0.903573
-0.438766
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
0.992982
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
-0.496938
辞書に単語がないです
0.960503
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです
辞書に単語がないです

今日勉強したこと

  • ネガポジ判定
  • Pandasのread_csvのやり方
  • 置換の仕方
  • ヘッダーの付け方