前のページまでで利用した辞書は見出し語の重複を無視していました.このため,「ホーム」「ホームラン」「大和撫子」のような単語については感情極性値が得られなかったり,誤った感情極性値を取得したりという問題がありました.ここでは,このような問題を解決するために見出し語の重複を考慮した辞書を作成し,その辞書から目的の値が取得できるようにコーディングを進めます.
まず,ファイルをデータフレームに読み込み,そのデータフレームを表示して内容を確認します.
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
見出し語「ホーム」についてどのような値が格納されているかもここで確認しておきます.
df_pn[df_pn.lemma == "ホーム"]
データフレームから辞書を作成しますが,見出し語ごとに「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