3. Pythonによる自然言語処理 5-1. 感情分析の考え方[AFINN-111]
- ある文書を一括りにして性格づけする手法があります。文書を構成している単語に付与された属性をもとに、好き・嫌い、肯定的・否定的などの判定をするものです。
- それには元となる辞書が必要になりますが、英単語の感情値辞書 AFINN-111 には収録数 2,477語のそれぞれに感情値として-4から4までの整数がふられています。
⑴ AFINN-111 の取得
-
AFINN-111を読み込んでデータフレーム
afn
とします。
import pandas as pd
afn = pd.read_csv(r'https://raw.githubusercontent.com/fnielsen/afinn/master/afinn/data/AFINN-111.txt',
names=['word_score'])
afn
とします。import pandas as pd
afn = pd.read_csv(r'https://raw.githubusercontent.com/fnielsen/afinn/master/afinn/data/AFINN-111.txt',
names=['word_score'])
⑵ AFINN-111 を辞書型に変換
- 「\t」を区切り文字として単語
word
と感情値 score
の列に分けます。
afn["split"] = afn["word_score"].str.split("\t")
afn["word"] = afn["split"].str.get(0)
afn["score"] = afn["split"].str.get(1)
word
と感情値 score
の列に分けます。afn["split"] = afn["word_score"].str.split("\t")
afn["word"] = afn["split"].str.get(0)
afn["score"] = afn["split"].str.get(1)
-
score
の値は文字列なので数値型 (INTEGER) に変換した列score_int
を生成します。
import numpy as np
afn_int = afn.assign(score_int = afn['score'].astype(np.int64))
- データフレームから対象となる2カラム
word
とscore_int
を抽出し、set_index()
にキーをword
と指定してto_dict()
で辞書に変換します。
afn_int = afn_int[["word", "score_int"]]
sentiment_dict = afn_int.set_index('word')['score_int'].to_dict()
⑶ AFINN-111 による感情値の計算
- 以下は、宮沢賢治『セロ弾きのゴーシュ』の冒頭3行です。
ゴーシュは町の活動写真館でセロを弾く係りでした。けれどもあんまり上手でないという評判でした。上手でないどころではなく実は仲間の楽手のなかではいちばん下手でしたから、いつでも楽長にいじめられるのでした。
- 英語に訳して入力データ
string
とします。- Gauche was in charge of playing the cello at the town's activity photo studio.
- He had a reputation for not being a very good player.
- Not only was he not a good player, but he was actually the worst player among his fellow musicians, so he was always bullied by the head musician.
string = "Gauche was in charge of playing the cello at the town's activity photo studio. He had a reputation for not being a very good player. Not only was he not a good player, but he was actually the worst player among his fellow musicians, so he was always bullied by the head musician."
- Pythonの自然言語処理パッケージ NLTK とそのサブモジュール nltk.tokenize 一式をインポートし、トークナイザ punkt をダウンロードします。
-
string
からsent_tokenize()
で文章ごとに取り出して、以下の処理をくり返します。lower()
ですべて小文字にしてword_tokenize()
で単語に分割し、単語単位でsentiment_dict
から感情値を取得した合計をscore
とします。
import nltk
from nltk.tokenize import *
nltk.download('punkt')
for s in sent_tokenize(string):
words = word_tokenize(s.lower())
score = sum(sentiment_dict.get(word, 0) for word in words)
print(score)
-
得点が正の数なら肯定的、逆に負の数なら否定的な性格をもつ文章であることを表します。
- 「ゴーシュは町の活動写真館でセロを弾く係りでした」は 0 点で客観的事実です。
- 「けれどもあんまり上手でないという評判でした」は 3 点ですが、否定的な意味を遠回しに言っている感じです。
- 「上手でないどころではなく実は仲間の楽手のなかではいちばん下手でしたから、いつでも楽長にいじめられるのでした」は -2 点で、こちらは明らかに否定的な意味内容になっています。
- そこで、正の感情値の合計と、負の感情値の合計を別々に算出してみます。
for s in sent_tokenize(string):
words = word_tokenize(s.lower())
positive = 0
negative = 0
for word in words:
score = sentiment_dict.get(word, 0)
if score > 0:
positive += score
if score < 0:
negative += score
print(s)
print("positive:", positive)
print("negative:", negative)
- 2番目の文章の「あんまり上手でない」を「下手だ」と言い換えたらどうなるでしょうか。
string_2 = "Gauche was in charge of playing the cello at the town's activity photo studio. But he had a reputation for being terrible at it. Not only was he not a good player, but he was actually the worst player among his fellow musicians, so he was always bullied by the head musician."
for s in sent_tokenize(string_2):
words = word_tokenize(s.lower())
positive = 0
negative = 0
for word in words:
score = sentiment_dict.get(word, 0)
if score > 0:
positive += score
if score < 0:
negative += score
print(s)
print("positive:", positive)
print("negative:", negative)
- 日本語と英語の違いはありますが、言い回しによって結果はかなり違ったものになることがわかります。
⑷ 問題点と注意点
- 以上が感情分析の原理になりますが、次のようなさまざまな問題点が挙げられます。
- 辞書にない単語はカウントされない。
- 先の「not being a very good player」のように否定修飾する語がある場合でも正の値としてカウントされる。
- 同じく「not being a very good player」のように増幅修飾する語がある場合でも「good」しかカウントされない。
- 文章が長いほど感情値の和は大きくなる。
- 文章の前半と後半で感情が異なる場合もあり、一括りに性格づけすることに無理がある。
- ちなみに、日本語の「可愛い」に対応する英語はいくつかありますが、AFINN-111では「pretty : 1」「cute : 2」「lovely : 3」などとなっています。つまり感情値は順序尺度に相当すると考えられますが、連続値(-4, -3, -2, -1, 0, 1, 2, 3, 4 )すなわち比例尺度として扱っていることに注意が必要です。
- 辞書にない単語はカウントされない。
- 先の「not being a very good player」のように否定修飾する語がある場合でも正の値としてカウントされる。
- 同じく「not being a very good player」のように増幅修飾する語がある場合でも「good」しかカウントされない。
- 文章が長いほど感情値の和は大きくなる。
- 文章の前半と後半で感情が異なる場合もあり、一括りに性格づけすることに無理がある。
Author And Source
この問題について(3. Pythonによる自然言語処理 5-1. 感情分析の考え方[AFINN-111]), 我々は、より多くの情報をここで見つけました https://qiita.com/y_itoh/items/1075bb25018bd25debd3著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .