search
LoginSignup
3

posted at

updated at

Organization

AWS Comprehend + Lambda + NewRelicで毎日のツイートの感情分析を可視化してみた

概要

AWSのComprehendを使って自分のツイートの感情分析を行い、分析結果の数値をNewRelicに送信してダッシュボードを作ります。

完成図

こんな感じに毎日のツイートのポジティブ・ネガティブを可視化させます。

スクリーンショット 2022-12-14 20.32.52.png

用意するもの

  • NewRelicのライセンスキー
  • Twitter APIのキー
  • Lambda関数

Twitter APIキーの発行やNewRelicの使い方詳細の説明は割愛します。

Lambdaで関数作成

コードの全体像としてはこんな感じです

import tweepy
import boto3
import os
import datetime as dt
import json
import requests

# 環境変数を読みこむ
TWITTER_API_KEY = os.environ["TWITTER_API_KEY"]
TWITTER_API_SECRET = os.environ["TWITTER_API_SECRET"]
TWITTER_BEARER_TOKEN = os.environ["TWITTER_BEARER_TOKEN"]
TWITTER_ACCESS_TOKEN = os.environ["TWITTER_ACCESS_TOKEN"]
TWITTER_ACCESS_SECRET = os.environ["TWITTER_ACCESS_SECRET"]
NEWRELIC_KEY = os.environ["NEWRELIC_KEY"]
NEWRELIC_ENDPOINT = os.environ["NEWRELIC_ENDPOINT"]

# Twitter APIと連携
client = tweepy.Client(bearer_token=TWITTER_BEARER_TOKEN,
                        consumer_key=TWITTER_API_KEY,
                        consumer_secret=TWITTER_API_SECRET,
                        access_token=TWITTER_ACCESS_TOKEN,
                        access_token_secret=TWITTER_ACCESS_SECRET
                    )
                    
comprehend = boto3.client('comprehend')

def get_formatted_datetime(fmt, now):
    return dt.datetime.strftime(now, fmt)
    
def get_sentiment_score(target):
    sentiment = comprehend.detect_sentiment(Text=target, LanguageCode='ja')
    return sentiment.get('SentimentScore')
    
## NewRelicにデータを送信する関数
def post_newrelic(data):
    headers = {"X-Insert-Key": NEWRELIC_KEY}
    res = requests.post(NEWRELIC_ENDPOINT, headers=headers, json=data)
    return res
    
def lambda_handler(event,context):

    # twitterのcreated_atはUTCになってる。JSTで時刻を合わせてやる
    fmt = "%Y-%m-%dT15:00:00Z"
    JST = dt.timezone(dt.timedelta(hours=9), 'JST')
    now = dt.datetime.now(JST)
    start_today = get_formatted_datetime(fmt, now - dt.timedelta(days=1))
    now_formatted = get_formatted_datetime("%Y-%m-%dT%H:%M:%SZ",now)

    user = client.get_me()

    # ツイートを取得する
    tweets = client.get_users_tweets(id = user.data.id,
                                    exclude=("replies"),
                                    start_time=start_today,
                                    end_time=now_formatted
                                    )
    tweets_data = tweets.data

    data = []
    if tweets_data != None:
        for i, tweet in enumerate(tweets_data):
            result = get_sentiment_score(tweet.text)

            score = result['Positive'] - result['Negative']
            label = max(result, key=result.get)
            
            if label == 'Positive':
                label = 'ポジティブ'
            elif label == 'Negative':
                label = 'ネガティブ'
            else:
                label = 'その他'
                
            d = {}
            d["eventType"] = "twitter"
            d["positive_score"] = result['Positive']
            d["negative_score"] = result['Negative']
            d["label"] = label
            d["tweet"] = tweet.text
            data.append(d)
            
		
    return post_newrelic(data)

Comprehend APIで返ってくる値

取得したツイートをComprehend APIに投げると

result = get_sentiment_score(tweet.text)

以下のような値が取れます。

{
  "Text": "ツイート内容", 
  "Positive": 0.xxxxxxx, 
  "Negative": 0.xxxxxxx, 
  "Neutral": 0.xxxxxxx, 
  "Mixed": 0.xxxxxxxx
}

Positive, Negative, Neutral, Mixedの4つの感情スコアが返され、それぞれ1に近いほど大きいスコアとされています。

NewRelicに送信する値を定義

今回は以下4つをパラメータとしてNewRelicに送信します。

ポジティブ指数 (positive_score)
ネガティブ指数 (negative_score)
感情ラベル (label)
ツイート内容 (tweet)

d = {}
d["eventType"] = "twitter"
d["positive_score"] = result['Positive']
d["negative_score"] = result['Negative']
d["label"] = label
d["tweet"] = tweet.text
            

感情ラベル(label)は、
Positiveのスコアが最も高得点なツイートを 「ポジティブ」
Negativeのスコアが最も高得点なツイートを 「ネガティブ」
それ以外を 「その他」 として設定します。

label = max(result, key=result.get)
            
if label == 'Positive':
    label = 'ポジティブ'
elif label == 'Negative':
    label = 'ネガティブ'
else:
    label = 'その他'

EventBridgeの設定

作成したLambda関数を毎日呼び出すトリガーをEventBridgeで作成します。

Lambda関数のページからトリガーを追加
スクリーンショット 2022-12-14 20.59.03.png

トリガーの種類としてEventBridgeを選択
スクリーンショット 2022-12-14 20.56.15.png

今回は 「毎日21時に実行する」 ルールを設定します
スクリーンショット 2022-12-14 20.58.49.png

これでEventBridgeの設定は完了です。

NewRelicでグラフを作成

NRQLを使って分析結果をいい感じに表示させるグラフを作成します

直近1週間のツイートのポジティブ指数・ネガティブ指数

SELECT average(positive_score) as 'ポジティブ指数', average(negative_score) as 'ネガティブ指数' FROM twitter since 1 week ago

スクリーンショット 2022-12-14 20.18.49.png

1日ごとのポジティブツイート/ネガティブツイートの数

SELECT count(tweet) FROM twitter where label != 'その他' facet label since 2 week ago TIMESERIES 1 day

スクリーンショット 2022-12-14 20.33.01.png

1週間のポジティブ/ネガティブツイートの比率

SELECT count(*) FROM twitter where label != 'その他' facet label since 1 week ago

スクリーンショット 2022-12-14 20.19.32.png

ツイートごとの分析結果を表示

SELECT label, positive_score , negative_score, tweet FROM twitter since 1 day ago order by timestamp desc

スクリーンショット 2022-12-14 20.40.03.png

所感

  • ネガティブなツイートが多かったらAPI経由で自動でツイ消しのような仕組みも作りたい
    • NewRelicのAlert Condition + Workflowを使用すれば作れそう
  • 割とネガティブっぽいツイートが多いことに気づく
    • 前向きに生きよう!

参考・関連記事

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3