Natural Language API でお手軽センチメント分析(感情分析)


SNSで取り上げられている発言を分析して、あるサービスや商品に対する評判を可視化したい、と言うケースに当たりました。
(=センチメント分析)。

GCPのサービスの一つ 「Natural Language API」を使ったところ、お手軽にセンチメント分析ができたので、メモがてら記述しておきます。

Natural Language API とは

Google Cloud Platform が提供する機械学習系サービスの一つ。
https://cloud.google.com/natural-language?hl=ja

テキストデータの分析を手軽に行える。

  • エンティティ分析
    • 文章中の単語や固有名詞を抽出
  • 感情分析
    • 文章内の感情を数値化
  • コンテンツ分類
    • 文章のタイプ・分類を判定する

などができる。

Natural Language API の使い方

  1. GCPのダッシュボードからプロジェクト作成
  2. APIの有効化
  3. APIキーを取得

詳しくは以下を参照。
https://cloud.google.com/natural-language?hl=ja

以下のガイドを見れば、迷う箇所はほとんどない。
https://codelabs.developers.google.com/codelabs/nlp-from-google-docs-ja/index.html?index=..%2F..next17-tok#0

Google Apps Script で Twitter のツイート分析をする

  • Twitter のツイートを、Google スプレッドシートに保存
  • Google Apps Script で スクリプト作成
    • スプレッドシートのセルからツイートを取得
    • Natural Language APIで感情分析
    • 取得した結果をシートに記入

というユースケースで実装してみました。

Google スプレッドシートの準備

最初に、分析したい文章を準備

Google Apps Script の記述

次に、テキストデータを分析するためのスクリプトを準備。
今回は

  • Natural Language APIをコールする関数
  • シートからテキストデータを取得して、APIコールする関数へ引き渡し、返り値を記入する関数

の2種類で記述しました。

Natural Language APIをコールする関数

Google Code Lab のコードをほぼそのまま流用

retrieveSentiment.gs

function retrieveSentiment (textData) {
  var apiKey = 'APIキーを記述';
  var apiEndpoint = 
'https://language.googleapis.com/v1/documents:analyzeSentiment?key=' 
+ apiKey;

  //  Create a structure with the text, its language, its type,
  //  and its encoding
  var docDetails = {
    language: 'ja-jp',
    type: 'PLAIN_TEXT',
    content: textData
  };

  var nlData = {
    document: docDetails,
    encodingType: 'UTF8'
  };

  //  Package all of the options and the data together for the call
  var nlOptions = {
    method : 'post',
    contentType: 'application/json',
    payload : JSON.stringify(nlData)
  };

  //  And make the call
  var response = UrlFetchApp.fetch(apiEndpoint, nlOptions);
  Logger.log('json is :' + response)

return response;

}

シートからテキストデータを取得して、APIコールする関数へ引き渡し、返り値を記入する関数

関数内で、先に記述した関数「retrieveSentiment」を呼び出す

getSentiment.gs

// 取得したい開始行と終了行を記述
var start = '2';
var end = '5';

// シート情報取得
var mySheet = SpreadsheetApp.openById('シートのID').getSheetByName('シート名');

function getSentiment() {
  // 開始行と終了行でループを回す
  for (i = start; i <= end; i++) {
    var tweet = mySheet.getRange(i, 1).getValue();
    var response = retrieveSentiment(tweet);
    var json = JSON.parse(response);
    var score = json['documentSentiment']['score'];
    var magnitude = json['documentSentiment']['magnitude'];

    // 取得したScore Magnitudee,Jsonをシートに記述
    mySheet.getRange(i, 2).setValue(score);
    mySheet.getRange(i, 3).setValue(magnitude);
    mySheet.getRange(i, 4).setValue(response);
  }
}

実行結果

scoreは、感情がポジティブかネガティブかを表す。0が中央値。マイナスだとネガティブ。
Magnitudeは、感情の振れ幅。この数値が大きいと、ポジティブ・ネガティブそれぞれの感情がより強い。

Score、Magnitude共に1を超えると、肯定的かつ感動度合いが大きい。画像の2行目がその例。
逆だと、否定的で感情的になっている。
と言えそうです。

センチメント分析の難しさ

Scoreは、分析したテキスト全体から割り出しているため、複雑な文章だと正確な感情の抽出が難しい。

今回の例で言うと、シートの5行目。よく読むと、AAAに対する評価が非常に高く、好意的な感情を持っていることがわかるが、Scoreは 0.1 に止まっている。これは、文章全体の感情を平均化して出しているから。

特定の語句に対する正確なセンチメント分析を行おうとすると、エンティティ抽出が必要で、結構大変。

業務として使うには、手元の調整が必須な感じでした。

それはそれとして、非常に手軽にセンチメント分析ができ、面白いことに変わりはありません。