Python入門トップページ


日本語評価極性辞書(名詞編)を用いた感情分析:目次

  1. MeCab で形態素解析を実行する
  2. 日本語評価極性辞書(名詞編)を確認する
  3. 辞書形式のデータを作る
  4. 日本語評価極性辞書(名詞編)を用いて感情分析を実行する

Python で感情分析をしてみよう

日本語評価極性辞書(名詞編)を用いた感情分析

日本語評価極性辞書(名詞編)を確認する

次に東北大学自然言語処理研究グループによって公開されている日本語評価極性辞書(名詞編)をダウンロードします.このページ (https://www.cl.ecei.tohoku.ac.jp/Open_Resources-Japanese_Sentiment_Polarity_Dictionary.html) から pn.csv.m3.120408.trim というファイルをダウンロードしてください.ダウンロードしたデータは dic フォルダを作成してその中に格納することにします.なお,この日本語評価極性辞書(名詞編)の参考文献は次の通りです.

  • 東山昌彦, 乾健太郎, 松本裕治, 述語の選択選好性に着目した名詞評価極性の獲得, 言語処理学会第14回年次大会論文集, pp.584-587, 2008. / Masahiko Higashiyama, Kentaro Inui, Yuji Matsumoto. Learning Sentiment of Nouns from Selectional Preferences of Verbs and Adjectives, Proceedings of the 14th Annual Meeting of the Association for Natural Language Processing, pp.584-587, 2008.

dic フォルダに設置した pn.csv.m3.120408.trim ファイルの中身をテキストエディタなどで確認します.文字コードは utf-8 で保存されていることが確認できました.各行には見出し語 (term) と感情 (sentiment) を意味する p, e, n などと,意味カテゴリが記録されています.それぞれがタブ文字で区切られていることにも注意してください.「競争力」や「共感」に与えられている「p」はポジティブな評価極性を意味し,「供給不足」や「魑魅魍魎(ちみもうりょう)」に与えられている「n」はネガティブな評価極性を意味します.「あいさつ」「供給」「競争」などに与えられている「e」はニュートラルな評価極性を意味します.

dic/pn.csv.m3.120408.trim
"2,3日"	e	〜である・になる(状態)客観
10%	e	〜である・になる(状態)客観
100%	e	〜である・になる(状態)客観
25%	e	〜である・になる(状態)客観
80%	e	〜である・になる(状態)客観
10カ月	e	〜である・になる(状態)客観
10時間	e	〜である・になる(状態)客観
10数年	e	〜である・になる(状態)客観
10年以上	e	〜である・になる(状態)客観
10年近く	e	〜である・になる(状態)客観
...(中略)...
1バイト	e	〜である・になる(状態)客観
1位	p	〜である・になる(状態)客観
1割	e	〜である・になる(状態)客観
1時間以上	e	〜である・になる(状態)客観
1時間以内	e	〜である・になる(状態)客観
1時間半	e	〜である・になる(状態)客観
...(中略)...
AD	e	〜である・になる(状態)客観
AIDS	n	〜である・になる(状態)客観
ATフィールド	p	〜がある・高まる(存在・性質)
Amazon	e	〜である・になる(状態)客観
A型肝炎	n	〜である・になる(状態)客観
BBC	e	〜である・になる(状態)客観
...(中略)...
あいさつ	e	〜する(行為)
あいだ	e	〜である・になる(状態)客観
あいつら	e	〜である・になる(状態)客観
あいまい	n	〜である・になる(評価・感情)主観
...(中略)...
供給	e	〜する(行為)
供給不足	n	〜である・になる(状態)客観
供与	e	〜する(行為)
供養	e	〜する(行為)
侠盗	e	〜である・になる(評価・感情)主観
競り合い	e	〜がある・高まる(存在・性質)
競合	e	〜する(行為)
競作	e	〜する(行為)
競争心	e	〜がある・高まる(存在・性質)
競争相手	e	〜がある・高まる(存在・性質)
競争率	e	〜がある・高まる(存在・性質)
競争力	p	〜がある・高まる(存在・性質)
共感	p	〜する(出来事)
共存	e	〜する(出来事)
...(中略)...
魑魅魍魎	n	〜である・になる(状態)客観
鮑	e	〜である・になる(状態)客観
鹹味	e	〜である・になる(評価・感情)主観
麒麟	e	〜である・になる(状態)客観

形態素解析を行なって単語に分割した後,上の日本語評価極性辞書からその評価極性を取得することで感情分析ができそうです.実際に感情分析を行う前にこの辞書データを読み込んでその内容を確認してみます.dic フォルダに格納した pn.csv.m3.120408.trim を Python の Pandas で読み込みます.このとき,文字コードが utf-8 であること,カンマ (,) ではなくタブ文字で区切られていることに注意します.また,見出し行がないことから列名も指定します.


import pandas as pd
import os

# 日本語評価極性辞書(名詞編)
path_dic = os.path.sep.join(['dic', 'pn.csv.m3.120408.trim'])
df_pncsv = pd.read_csv(path_dic, sep="\t", names=["term", "sentiment", "semantic_category"])
df_pncsv
2024-sentiment-21

上の結果から,13,314個の見出し語 (term) が登録されていることがわかりました.また,感情 (sentiment) には p, n, e などの存在が確認できました.どのような割合で感情が登録されているかを次のコードで確認します.すると,p, n, e が大半を占めますが,それら以外にも存在することがわかりました.

どのような感情がどのような割合で登録されているか?
df_sentiment = df_pncsv.groupby('sentiment')['term'].count().reset_index()
df_sentiment = df_sentiment.sort_values(by=['term'], ascending=[False])
df_sentiment
2024-sentiment-22

まず,ポジティブ (p) の感情を持つ見出し語がどのようなものであるかを確認します.


df_pncsv[df_pncsv.sentiment=="p"]
2024-sentiment-23

感情がニュートラル (e) である見出し語を確認します.


df_pncsv[df_pncsv.sentiment=="e"]
2024-sentiment-24

次はネガティブ (n) な感情を持つ見出し語を確認します.


df_pncsv[df_pncsv.sentiment=="n"]
2024-sentiment-25

感情には「?p?n」なるものがありました.どのような見出し語に「?p?n」が割り当てられているか表示してみます.これらはポジティブであるかネガティブであるか曖昧であるが,そのどちらかであると推定できそうです.


print(df_pncsv[df_pncsv.sentiment=="?p?n"])
        term sentiment                 semantic_category
431     ぐうたら      ?p?n                           〜する(行為)
452     こだわり      ?p?n                   〜がある・高まる(存在・性質)
778     ぶらぶら      ?p?n                           〜する(行為)
971     アピール      ?p?n                           〜する(行為)
1740     ナンパ      ?p?n                           〜する(行為)
1797   ハプニング      ?p?n                   〜がある・高まる(存在・性質)
2232    リタイア      ?p?n                           〜する(行為)
2330      哀愁      ?p?n                   〜がある・高まる(存在・性質)
2778      迂回      ?p?n                           〜する(行為)
2836      永眠      ?p?n                          〜する(出来事)
3362      海賊      ?p?n                    〜である・になる(状態)客観
3664      甘さ      ?p?n                   〜がある・高まる(存在・性質)
3733     関わり      ?p?n                   〜がある・高まる(存在・性質)
3871      機嫌      ?p?n                    〜である・になる(状態)客観
3888       気      ?p?n                   〜がある・高まる(存在・性質)
4277      強気      ?p?n                 〜である・になる(評価・感情)主観
4411      均衡      ?p?n                          〜する(出来事)
4504      苦心      ?p?n                          〜する(出来事)
5270      公表      ?p?n                           〜する(行為)
5526      高値      ?p?n                    〜である・になる(状態)客観
6416      自慢      ?p?n                           〜する(行為)
6696      手術      ?p?n                           〜する(行為)
7640      深さ      ?p?n                   〜がある・高まる(存在・性質)
7986      凄さ      ?p?n                   〜がある・高まる(存在・性質)
8269      静か      ?p?n                 〜である・になる(評価・感情)主観
9314    値下がり      ?p?n                          〜する(出来事)
9318    値上がり      ?p?n                          〜する(出来事)
10062      頭      ?p?n  〜である・になる(状態)客観 & ?〜である・になる(状態)客観
10118     道草      ?p?n                           〜する(行為)
10456     濃厚      ?p?n                 〜である・になる(評価・感情)主観
11016    必要性      ?p?n                   〜がある・高まる(存在・性質)
11115     敏感      ?p?n  〜である・になる(状態)客観 & ?〜である・になる(状態)主観
11645     変貌      ?p?n                          〜する(出来事)
11685     弁償      ?p?n                           〜する(行為)
12007     満席      ?p?n                    〜である・になる(状態)客観

その他の感情が与えられた見出しををまとめて表示してみます.「?e」はニュートラルであると推定され,「?p」はポジティブであると推定され,「?p?e」はポジティブかニュートラルかが曖昧な見出し語です.さらに「a:ambiguous」は曖昧な見出し語,「o:other」はその他を意味しますが,「決壊」については全角空白で感情が割り当てられています.


df_pncsv[(df_pncsv.sentiment!="p") &
            (df_pncsv.sentiment!="e") &
            (df_pncsv.sentiment!="n") &
            (df_pncsv.sentiment!="n") &
            (df_pncsv.sentiment!="?p?n")
].sort_values('sentiment')
2024-sentiment-26

次に意味カテゴリについてもどのような情報が登録されているかグループ化して表示してみます.多くの意味カテゴリに分類されているようですが,今回はこれらの情報は利用しないことにします.


df_cat = df_pncsv.groupby('semantic_category')['term'].count().reset_index()
df_cat = df_cat.sort_values(by=['term'], ascending=[False])
print(df_cat)
                             semantic_category  term
1                              〜がある・高まる(存在・性質)  4354
33                              〜である・になる(状態)客観  2940
14                                     〜する(行為)  2369
40                           〜である・になる(評価・感情)主観  2303
8                                     〜する(出来事)   978
48                                    〜に行く(場所)   142
28                                   〜する(行為)他人    73
29                                   〜する(行為)自分    62
27                                  〜する(行為)その他    17
6                                     〜する(出来事)     8
17                      〜する(行為) & !〜する(出来事)もあり     6
20                     〜する(行為) & ?〜する(出来事)もあり?     4
50                                    存在・もの・名称     4
19                         〜する(行為) & ?〜する(出来事)     3
2                〜がある・高まる(存在・性質) & !〜する(行為)もあり     3
49                                        和語動詞     3
34        〜である・になる(状態)客観 & !〜がある・高まる(存在・性質)もあり     2
15               〜する(行為) & !〜がある・高まる(存在・性質)もあり     2
43   〜である・になる(評価・感情)主観 & !〜である・になる(評価・感情)客観もあり     2
44  〜である・になる(評価・感情)主観 & !〜である・になる(評価・感情)客観もあり?     2
39            〜である・になる(状態)客観 & ?〜である・になる(状態)客観     2
23                         〜する(行為) & ?〜する(出来事)     2
24                     〜する(行為) & ?〜する(出来事)もあり?     2
36              〜である・になる(状態)客観 & !〜をする(出来事)もあり     1
35       〜である・になる(状態)客観 & !〜がある・高まる(存在・性質)もあり?     1
47    〜である・になる(評価・感情)主観 & 〜である・になる(評価・感情)客観もあり     1
41     〜である・になる(評価・感情)主観 & !〜がある・高まる(存在・性質)もあり     1
46  〜である・になる(評価・感情)主観 & ?〜である・になる(評価・感情)客観もあり?     1
42             〜である・になる(評価・感情)主観 & !〜する(行為)もあり     1
38            〜である・になる(状態)客観 & ?〜である・になる(状態)主観     1
45            〜である・になる(評価・感情)主観 & ?〜する(行為)もあり?     1
37              〜である・になる(状態)客観 & ?〜する(出来事)もあり?     1
0                               〜である・になる(状態)客観     1
32                       〜する(行為)自分 & ?〜する(出来事)     1
31                      〜する(行為)自分 & !〜する(出来事)?     1
3         〜がある・高まる(存在・性質) & !〜である・になる(状態)主観もあり     1
4         〜がある・高まる(存在・性質) & !〜である・になる(状態)客観もあり     1
5       〜がある・高まる(存在・性質) & 〜である・になる(評価・感情)主観もあり     1
7                                      〜する(行為)     1
9               〜する(出来事) & !〜がある・高まる(存在・性質)もあり     1
10                      〜する(出来事) & !〜する(行為)もあり     1
11               〜する(出来事) & !〜である・になる(状態)客観もあり     1
12                         〜する(出来事) & ?〜する(行為)     1
13             〜する(出来事) & 〜がある・高まる(存在・性質)客観もあり     1
16                        〜する(行為) & !〜する(出来事)?     1
18                       〜する(行為) & !〜する(行為)もあり     1
21                         〜する(行為) & ?〜する(出来事)     1
22                      〜する(行為) & ?〜する(行為)もあり?     1
26              〜する(行為) & 〜である・になる(評価・感情)客観もあり     1
30             〜する(行為)自分 & !〜がある・高まる(存在・性質)もあり     1
25                          〜する(行為) & ?〜する(行為)     1

すでに13,314個の見出し語が登録されていることは確認しましたが,これらの見出し語に重複があるかどうかをここで確認しておきます.まず,データフレームから見出し語の列を抽出,さらにリスト化して,その個数を調べると同じ13,314が得られるはずです.


term = df_pncsv["term"].tolist()
print(len(term))
13314

リストから集合を作成すると重複を除くことができます.重複を除くと 13,310件に減少しました.


term_set = set(term)
print(len(term_set))
13310

(暗算で可能ですが)重複した見出し語の個数をカウントします.


print(len(term) - len(term_set))
4

4個の見出し語については重複があるようです.重複があった用語を表示します.


sorted_df = df_pncsv.groupby('term')['sentiment'].count().reset_index()
sorted_df = sorted_df.sort_values(by=['sentiment'], ascending=[False])
sorted_df[sorted_df.sentiment > 1]
2024-sentiment-27

これらの重複があった用語にはどのような感情が割り当てられているのでしょうか.そのことを確認します.「信用」と「帳消し」についてはいずれも「p」です.「規律」については「e」または「p」,「白濁」は「a」または「e」です.よって「規律」と「白濁」の取り扱いをどうするかは必要に応じて検討しましょう.今回は無視することにします.


df_pncsv[(df_pncsv.term == "帳消し") |
        (df_pncsv.term == "信用") |
        (df_pncsv.term == "規律") |
        (df_pncsv.term == "白濁")
]
2024-sentiment-28

さらに,今回利用する日本語評価極性辞書(名詞編)において,数字やアルファベットを含む見出し語はその殆どが全角文字で登録されています.一方で,前のページで確認した通り MeCab で形態素解析を実行する場合は事前に半角文字に変換(正規化)することで解析の精度が向上します.したがって,日本語評価極性辞書の見出し語をあらかじめ正規化して半角文字に変換しておきます.

まず,見出し語の列だけ取り出してリスト化します.そのうえで先頭150個を3個おきに表示します.個の結果の('25%'を除く)ほぼすべてが全角文字であることに注意してください.


term = df_pncsv['term'].tolist()
print(term[:150:3])
['2,3日', '25%', '10時間', '10年近く', '12年', '15秒', '19年', '1割', '1時間半', '1勝', '1日分', '1品', '20年近く', '2ヵ月', '2件目', '2時間半', '2勝1敗', '2年近く', '30分程度', '39歳', '3タテ', '3回連続', '3酔い', '4か月', '4日', '50年以上', '7ヶ月', '8カ月', '9ヶ月', 'AD', 'Amazon', 'BIG', 'CD', 'DV', 'ED', 'HIV', 'HTML', 'KO', 'OK', 'PMS', 'Q&A', 'RSS', 'SPAM', 'TKO', 'Web検索', 'end', 'txt', 'あいつら', 'あえぎ', 'あきらめ']

ここで説明した方法を使って正規化します.このとき内包表記を使うことでコードが短くなるとともに実行速度の向上も期待できます.半角文字に正規化できていることがわかりました.


import unicodedata
term_nfkc = [unicodedata.normalize('NFKC', t) for t in term] # 内包表記を使って半角文字に正規化する
print(term_nfkc[:150:3])
['2,3日', '25%', '10時間', '10年近く', '12年', '15秒', '19年', '1割', '1時間半', '1勝', '1日分', '1品', '20年近く', '2ヵ月', '2件目', '2時間半', '2勝1敗', '2年近く', '30分程度', '39歳', '3タテ', '3回連続', '3酔い', '4か月', '4日', '50年以上', '7ヶ月', '8カ月', '9ヶ月', 'AD', 'Amazon', 'BIG', 'CD', 'DV', 'ED', 'HIV', 'HTML', 'KO', 'OK', 'PMS', 'Q&A', 'RSS', 'SPAM', 'TKO', 'Web検索', 'end', 'txt', 'あいつら', 'あえぎ', 'あきらめ']

データフレームでの見出し語の列を正規化した内容に置き換えます.


df_pncsv['term'] = term_nfkc
df_pncsv
2024-sentiment-29

目次に戻る