SNSやアンケートのフリーテキストからユーザーの感情情報を解析してしてデータ分析に役立たないか?と思いGoogleのNatural Language APIを利用してみました。
思ったよりも簡単に使えたのでおぼえ書きとして残しておきます。
結論としてはコーディングがめちゃくちゃ簡単で、結果もそれなりの精度で満足でした!
こちらのサンプルの文面的には微妙ですが、1,000件のテキストデータを解析にかけてスコアリングしてみたところ、それなりの内容だったので実用に足るという認識です。
まあ最後の判定は目検というか主観になってしまいますが、少なくとも車輪の再発明はしたくないと思える内容でした。
スクリプト
ソース
GoogleのColaboratoryを使っています。
APIのサービスキー(gcp_api_key.json)をGドライブのマイドライブに置いておいてください。
#ライブラリー
import os
import re
import numpy as np
import pandas as pd
from IPython.display import display
#GDriveマウント
from google.colab import drive
drive.mount('/content/gdrive')
#APIKEYファイルを設定
os.environ['GOOGLE_APPLICATION_CREDENTIALS']='/content/gdrive/My Drive/gcp_api_key.json'
# 解析文章
text='''
@yamamoto こちらが文章です。問題がある場合はこちらのURLに連絡ください。https://aaa.com/aaa
村上さんは、いつも黙っているひと、厳格なひとでした。インドネシアは喜ばしいときには笑い、悲しいときには泣きます。
日本人は悲しいときには笑い、嬉しいときには怒ります。インドネシアは、それを理解することができません。
長い間、私もそうでした。村上さんのやさしい心を知ったのは、死なれてから十日もあと、
村上さんのお骨を入れた骨壺を、舟の檣のてっぺんに結びつけ、一人、月の光に照らされ、海豚いるかと話しながら、
アラフラ海を漂っているそのときでした。もっと早くわかれば、どんなによかったか。ソレガ悲シイ悲シイデス。
#インドネシア #日本人
'''
# テキストデータのクレンジング
# URLの削除
text=re.sub(r'(https?|ftp)(:\/\/[-_\.!~*\'()a-zA-Z0-9;\/?:\@&=\+\$,%#]+)', '',text)
# ハッシュタグの削除
text=re.sub(r'#(\w+)', '',text)
# 宛先の削除
text=re.sub(r'@(\w+)', '',text)
# 不要な改行を削除
text=re.sub(r'\n', '',text)
# NLライブラリーのインポート
from google.cloud import language_v1
from google.cloud.language_v1 import types
from google.cloud.language_v1 import enums
# クライアントの生成
client = language_v1.LanguageServiceClient()
# 感情解析の実行
document = types.Document(
content=text,
type=types.Document.Type.PLAIN_TEXT)
response = client.analyze_sentiment(document=document)
# 結果の取得
score=response.document_sentiment.score
magnitude=response.document_sentiment.magnitude
sentences=response.sentences
scores=[]
magnitudes=[]
# センテンスごとにスコアーとマグニチュードを取得して配列に格納する
for sentence in sentiment['sentences']:
scores.append(sentence.sentiment.score)
magnitudes.append(sentence.sentiment.magnitude)
scores=np.array(scores)
magnitudes=np.array(magnitudes)
#感情解析の値を格納
result={
'score':sentiment['score']
,'magnitude':sentiment['magnitude']
,'text':text
,'scores_min':scores.min()
,'scores_max':scores.max()
,'scores_mean':scores.mean()
,'magnitudes_min':magnitudes.min()
,'magnitudes_max':magnitudes.max()
,'magnitudes_mean':magnitudes.mean()
,'sentence_cnt':scores.size
}
#感情解析の結果を表示
display(result)
出力結果
こちらが感情解析の結果です。
大枠は「score」と「magnitude」と「text」を確認してください。
scoreは-1.0から+1.0の値で構成されて、値が少ない(-マイナス)ほどネガティブと評価され、大きい(+プラス)ほどポジティブな傾向にあると評価されます。
magnitudeは0.0から+inf値で表現されます。
こちらはscoreのように正規化されておらず、テキスト内に「ネガティブワード」と「ポジティブワード」が出現するたびに加算されていきます。注意するべきなのはネガポジに関係なく加算されるということです。
私的な解釈としましては、感情の熱量を図る指標という認識です。
textは感情解析にかけたテキスト文章です。この例では前処理でURL部分やハッシュタグ、アットマークをクレンジングしたため不純な情報はない状態となります。
{'score': 0.0,
'magnitude': 3.0999999046325684,
'text': ' こちらが文章です。問題がある場合はこちらのURLに連絡ください。村上さんは、いつも黙っているひと、厳格なひとでした。インドネシアは喜ばしいときには笑い、悲しいときには泣きます。日本人は悲しいときには笑い、嬉しいときには怒ります。インドネシアは、それを理解することができません。長い間、私もそうでした。村上さんのやさしい心を知ったのは、死なれてから十日もあと、村上さんのお骨を入れた骨壺を、舟の檣のてっぺんに結びつけ、一人、月の光に照らされ、海豚いるかと話しながら、アラフラ海を漂っているそのときでした。もっと早くわかれば、どんなによかったか。ソレガ悲シイ悲シイデス。 '}
'scores_min': -0.699999988079071,
'scores_max': 0.30000001192092896,
'scores_mean': -0.09999999701976776,
'magnitudes_min': 0.0,
'magnitudes_max': 0.699999988079071,
'magnitudes_mean': 0.26000000089406966,
'sentence_cnt': 10,
前述の通りmagnitudeはネガポジのワードが出現するたびに加算されるため、長文になればなるほど大きくなる傾向があります。
そのため、こちらでは文節ごとにスコアリングを行なってその平均値(mean)も出力してみました。
全体のmagnitudeを利用するか平均値を利用するかは用途や文節によるため断言はできませんが、指標としてとっておくこともありだと思います。