Python入門トップページ


単語感情極性対応表を用いた感情分析:目次

  1. MeCab で形態素解析を実行する
  2. 単語感情極性対応表を確認する
  3. 見出し語の重複を無視して作成した辞書で感情を分析する
  4. 見出し語の重複を考慮した辞書を作成する
  5. 見出し語の重複を考慮して作成した辞書で感情を分析する
  6. 読みをカタカナに変換した辞書でスコアを取得する
  7. 見出し語と読みの情報を利用して感情を分析する

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

単語感情極性対応表を用いた感情分析

見出し語の重複を考慮した辞書を作成する

前のページまでで利用した辞書は見出し語の重複を無視していました.このため,「ホーム」「ホームラン」「大和撫子」のような単語については感情極性値が得られなかったり,誤った感情極性値を取得したりという問題がありました.ここでは,このような問題を解決するために見出し語の重複を考慮した辞書を作成し,その辞書から目的の値が取得できるようにコーディングを進めます.

まず,ファイルをデータフレームに読み込み,そのデータフレームを表示して内容を確認します.


import MeCab as mc
import pandas as pd
import numpy as np
import os

# 単語感情極性対応表
path_dic = os.path.sep.join(['dic', 'pn_ja.dic'])
df_pn = pd.read_csv(path_dic, encoding="sjis", sep=":", names=["lemma", "reading", "pos", "score"])
df_pn
2024-sentiment-13

見出し語「ホーム」についてどのような値が格納されているかもここで確認しておきます.


df_pn[df_pn.lemma == "ホーム"]
2024-sentiment-14

データフレームから辞書を作成しますが,見出し語ごとに「reading」をキーとして「score」が保存された辞書が保存されるようにします(実際は「pos:品詞」も考慮すべきかもしれませんが).

データフレームを辞書に変換
dic_lemma = df_pn.groupby('lemma').apply(lambda x: dict(zip(x['reading'], x['score']))).to_dict()

辞書を表示して,どのようなデータ構造になっているのかを確認します.(ただし,非常に大きなデータが表示されるので実行には注意してください.)


print(dic_lemma)
{
    '―粉': {'みじんこ': -0.629769},
    'ああ': {'ああ': -0.31688},
    'あいこ': {'あいこ': -0.367684},
...(中略)...
    'ホーム': {'ホームラン': -0.199562, 'ホームスパン': -0.238954, 'ホーム': -0.263255, 'ホームドクター': -0.263565, 'ホームステイ': -0.267942, 'ホームドラマ': -0.289906, 'ホームシック': -0.29162, 'ホームグラウンド': -0.327826, 'ホームルーム': -0.347714, 'ホームストレッチ': -0.354835, 'ホームヘルパー': -0.408128},
...(中略)...
    '大和': {'やまとなでしこ': -0.255471, 'やまとことば': -0.256392, 'やまとうた': -0.355588, 'やまとしまね': -0.395319, 'やまとごころ': -0.400031, 'やまとごと': -0.407539, 'やまとだましい': -0.428098, 'やまとえ': -0.456326, 'やまと': -0.468667, 'やまといも': -0.469222, 'やまとべい': -0.571956},
...(中略)...
    '嬉しい': {'うれしい': 0.998871},
...(中略)...
    '最悪': {'さいあく': -0.994867},
...(中略)...
    'Z旗': {'ゼットき': -0.292753},
    'pH': {'ピーエイチ': -0.25394},
    'ppm': {'ピーピーエム': -0.356563}
}

辞書 dic_lemma からキー「ホーム」で取り出した結果をpprint を使って整形して表示してみます.


from pprint import pprint
pprint(dic_lemma['ホーム'])
{'ホーム': -0.263255,
 'ホームグラウンド': -0.327826,
 'ホームシック': -0.29162,
 'ホームステイ': -0.267942,
 'ホームストレッチ': -0.354835,
 'ホームスパン': -0.238954,
 'ホームドクター': -0.263565,
 'ホームドラマ': -0.289906,
 'ホームヘルパー': -0.408128,
 'ホームラン': -0.199562,
 'ホームルーム': -0.347714}

重複のない見出し語「嬉しい」などは次のような出力が得られます.


pprint(dic_lemma['嬉しい'])
{'うれしい': 0.998871}

しかしながら,辞書に存在しない「あいうえお」などではエラーでプログラムが止まってしまいます.


pprint(dic_lemma['あいうえお'])
--------------------------------------------
KeyError   Traceback (most recent call last)
Cell In[32], line 1
----> 1 pprint(dic_lemma['あいうえお'])

KeyError: 'あいうえお'

このようなエラーを防止するためにいくつかの工夫を施します.具体的には辞書から値を取得する次のような関数を作成します.この関数ではget() を利用することで,キーが存在しない場合にもエラーとならず,空の辞書が結果として得られるようにしています.さらに,「嬉しい」のように重複がない場合のみ感情極性値を返し,それ以外は np.nan を返すようにします.なお,4行目の next(iter(results.values())) では,results.values() で得られた結果から先頭の要素(値)だけを取得していることにも注意してください.


def get_lemma_score(dic_lemma, lemma):
    results = dic_lemma.get(lemma, {})
    if len(results) == 1:
        return next(iter(results.values()))
    return np.nan 

上で定義した関数 get_lemma_score() を呼び出して,「嬉しい」の感情極性値が取得できることを確認します.


get_lemma_score(dic_lemma, "嬉しい")
0.998871

「最悪」についても感情極性値を取得してみます.


get_lemma_score(dic_lemma, "最悪")
-0.994867

重複のある「ホーム」については現時点では np.nan となります.


get_lemma_score(dic_lemma, "ホーム")
nan

辞書に存在しない「あいうえお」でもエラーにならずに np.nan となりました.


get_lemma_score(dic_lemma, "あいうえお")
nan

目次に戻る