Posted at

Google Natural Language API の感情分析で遊んでみる

Google Natural Language API の感情分析で遊んでみる回


なにはともあれセットアップ


  • プランをBlaze以上にアップデートする必要あり(クレジットカード情報いれることになるが、従量課金なので無料範囲で遊べるはず)

  • 公式ドキュメントにしたがってGCPのWebコンソールでAPIのクレデンシャルを設定すると、project-name-1cbc40b22079.jsonとかいうシークレットの入ったファイルが落ちてくる。クレデンシャルはGCPのプロジェクトに対応するっぽい(プロジェクト毎と思われる)

  • そのjsonのパスを環境変数 GOOGLE_APPLICATION_CREDENTIALS に設定する

  • 公式ドキュメントにしたがって使いたい言語に対応するクライアントライブラリをインストール(以下rubyで実行した例)

  • 公式にあるサンプルコードを実行(以下)

$ export GOOGLE_APPLICATION_CREDENTIALS=/Users/foo/power-of-words/project-name-1cbc40b22079.json 

$ ruby nlapi.rb
Text: Hello, world!
Score: 0.30000001192092896, 0.30000001192092896

動いたっぽい。こっから先はnode/jsでやってみる。


感情分析のアウトプットの読み方

Googleのページからのただの引用:


感情分析は、テキスト内で表現されている全体的な態度(ポジティブかネガティブか)を特定します。結果は、score と magnitude の数値によって表されます。


  1. score: -1.0(ネガティブ)~1.0(ポジティブ)のスコアで感情が表されます。これは、テキストの全体的な感情の傾向に相当します。

  2. magnitude: 指定したテキストの全体的な感情の強度(ポジティブとネガティブの両方)が 0.0~+inf の値で示されます。score と違って magnitude は正規化されていないため、テキスト内で感情(ポジティブとネガティブの両方)が表現されるたびにテキストの magnitude の値が増加します(そのため、長いテキスト ブロックで値が高くなる傾向があります)。


態度 score(ポジティブ or ネガディブ)と強度 magnitude で分析されるようだ。強度は文章内で繰り返されることで増大する。


分析の中身をみてみる

試しに文章を変えてみる。ポジティブなものからいく。例えば、I am a lucky guy. I feel really happy now.というのはどうだろうか。


// Imports the Google Cloud client library
const language = require('@google-cloud/language');

// Instantiates a client
const client = new language.LanguageServiceClient();

// The text to analyze
// const text = 'Hello, world!';
const text = "I am a lucky guy. I feel really happy now."

const document = {
content: text,
type: 'PLAIN_TEXT',
};

// Detects the sentiment of the text
client
.analyzeSentiment({document: document})
.then(results => {
const sentiment = results[0].documentSentiment;

console.log(results);
console.log(`Text: ${text}`);
console.log(`Sentiment score: ${sentiment.score}`);
console.log(`Sentiment magnitude: ${sentiment.magnitude}`);
})
.catch(err => {
console.error('ERROR:', err);
});

結果はこんな感じ。行毎にscoremagnitudeが出て、最後に文章全体のscoremagnitudeがでる。各文のscoreをみるとluckyよりhappyの方がポジティブととらえられている感じ。

[ { sentences:

[ { text: { content: 'I am a lucky guy.', beginOffset: -1 },
sentiment:
{ magnitude: 0.20000000298023224, score: 0.20000000298023224 } },
{ text: { content: 'I feel really happy now.', beginOffset: -1 },
sentiment: { magnitude: 0.8999999761581421, score: 0.8999999761581421 } } ],
documentSentiment: { magnitude: 1.100000023841858, score: 0.5 },
language: 'en' },
undefined,
undefined ]
Text: I am a lucky guy. I feel really happy now.
Sentiment score: 0.5
Sentiment magnitude: 1.100000023841858

日本語だどうだろう。同じような文章で私はラッキーな男だ。今、本当に幸福を感じる。でやってみると... お、直訳してみたつもりだが、日本語の方がスコアが高い。

[ { sentences:

[ { text: { content: '私はラッキーな男だ。', beginOffset: -1 },
sentiment: { magnitude: 0.800000011920929, score: 0.800000011920929 } },
{ text: { content: '今、本当に幸福を感じる。', beginOffset: -1 },
sentiment: { magnitude: 0.800000011920929, score: 0.800000011920929 } } ],
documentSentiment: { magnitude: 1.7000000476837158, score: 0.800000011920929 },
language: 'ja' },
undefined,
undefined ]
Text: 私はラッキーな男だ。今、本当に幸福を感じる。
Sentiment score: 0.800000011920929
Sentiment magnitude: 1.7000000476837158

うん、だいたい使い方はわかったので、今作ってるWebアプリで使っていきます。