Natural Language API は、構文を解析してエンティティを抽出し、テキストの感情を把握することができる、事前学習済みの機械学習モデルです。 Google ドキュメントから呼び出して、実行することができます。
このコードラボでは、Natural Language API を呼び出して Google ドキュメント内で選択したテキストの感情を認識し、その感情に応じてテキストをハイライトする方法について学びます。
このコードラボで学んだことを生かすと、次の図のように、メニューからドキュメント内の選択されたテキストの感情にマークを付けられるようになります。
ネガティブな感情のテキストは赤色で、ポジティブな感情のテキストは緑色で、ニュートラルな感情のテキストは黄色でハイライトされます。
このコードラボでは、Google ドキュメントから Natural Language API を呼び出す方法に焦点を当てます。関連のない概念やコード ブロックには詳しくは触れずに、コピー & ペーストすればよい形で用意しています。
全てのパソコンは Codelab のみの使用となります!
ログイン後https://kiosk.gcplab.me/next17-tokへアクセスしてください。
退出なさる時はログアウトを忘れずにお願いいたします。
講師は、セットアップ済みの既存のプロジェクトで一時アカウントをあなたと共有するので、課金の有効化や本コードラボの実行に伴うコストについては心配いりません。それらのアカウントはすべて、コードラボ終了直後に無効化されます。
ログインに使用する一時ユーザー名/パスワードを講師から受け取った後、Google Cloud Console にログインします。https://console.cloud.google.com/.
割り当てられたプロジェクト ID をメモしてください (上のスクリーンショットでは「next17-t
ok-xxxx」)。以降、本コードラボでは PROJECT_ID と呼びます。
Natural Language API を呼び出す前に、メニューを作成し、そのメニューをテキストにマークをつける関数にリンクさせ、そしてユーザーが選択した箇所からテキストを抽出するための Apps Script プログラムが、Natural Language API を呼び出す前に必要となります。
/**
* @OnlyCurrentDoc
*
* The above comment directs Apps Script to limit the scope of file
* access for this add-on. It specifies that this add-on will only
* attempt to read or modify the files in which the add-on is used,
* and not all of the user's files. The authorization request message
* presented to users will reflect this limited scope.
*/
/**
* Creates a menu entry in the Google Docs UI when the document is
* opened.
*
*/
function onOpen() {
var ui = DocumentApp.getUi();
ui.createMenu('Natural Language Tools')
.addItem('Mark Sentiment', 'markSentiment')
.addToUi();
}
/**
* Gets the user-selected text and highlights it based on sentiment
* with green for positive sentiment, red for negative, and yellow
* for neutral.
*
*/
function markSentiment() {
var POSITIVE_COLOR = '#00ff00'; // Colors for sentiments
var NEGATIVE_COLOR = '#ff0000';
var NEUTRAL_COLOR = '#ffff00';
var NEGATIVE_CUTOFF = -0.2; // Thresholds for sentiments
var POSITIVE_CUTOFF = 0.2;
var selection = DocumentApp.getActiveDocument().getSelection();
if (selection) {
var string = getSelectedText();
var sentiment = retrieveSentiment(string);
// Select the appropriate color
var color = NEUTRAL_COLOR;
if (sentiment <= NEGATIVE_CUTOFF) {
color = NEGATIVE_COLOR;
}
if (sentiment >= POSITIVE_CUTOFF) {
color = POSITIVE_COLOR;
}
// Highlight the text
var elements = selection.getSelectedElements();
for (var i = 0; i < elements.length; i++) {
if (elements[i].isPartial()) {
var element = elements[i].getElement().editAsText();
var startIndex = elements[i].getStartOffset();
var endIndex = elements[i].getEndOffsetInclusive();
element.setBackgroundColor(startIndex, endIndex, color);
} else {
var element = elements[i].getElement().editAsText();
foundText = elements[i].getElement().editAsText();
foundText.setBackgroundColor(color);
}
}
}
}
/**
* Returns a string with the contents of the selected text.
* If no text is selected, returns an empty string.
*/
function getSelectedText() {
var selection = DocumentApp.getActiveDocument().getSelection();
var string = "";
if (selection) {
var elements = selection.getSelectedElements();
for (var i = 0; i < elements.length; i++) {
if (elements[i].isPartial()) {
var element = elements[i].getElement().asText();
var startIndex = elements[i].getStartOffset();
var endIndex = elements[i].getEndOffsetInclusive() + 1;
var text = element.getText().substring(startIndex, endIndex);
string = string + text;
} else {
var element = elements[i].getElement();
// Only translate elements that can be edited as text; skip
// images and other non-text elements.
if (element.editAsText) {
string = string + element.asText().getText();
}
}
}
}
return string;
}
/** Given a string, will call the Natural Language API and retrieve
* the sentiment of the string. The sentiment will be a real
* number in the range -1 to 1, where -1 is highly negative
* sentiment and 1 is highly positive.
*/
function retrieveSentiment (line) {
// TODO: Call the Natural Language API with the line given
// and return the sentiment value.
return 0.0;
}
ご自分のプログラムがテキストを抽出してハイライトできるようになったら、Natural Language API を呼び出しましょう。 この操作はすべて、retrieveSentiment 関数の本文で行います。
Google ドキュメントでもう一度 [ツール] → [スクリプト エディタ] を開きます。
retrieveSentiment 関数で
var apiKey = "your key here";
var apiEndpoint =
'https://language.googleapis.com/v1/documents:analyzeSentiment?key='
+ apiKey;
var docDetails = {
language: 'en-us',
type: 'PLAIN_TEXT',
content: line
};
var nlData = {
document: docDetails,
encodingType: 'UTF8'
};
var nlOptions = {
method : 'post',
contentType: 'application/json',
payload : JSON.stringify(nlData)
};
var response = UrlFetchApp.fetch(apiEndpoint, nlOptions);
var data = JSON.parse(response);
var sentiment = 0.0;
// Ensure all pieces were in the returned value
if (data && data.documentSentiment
&& data.documentSentiment.score){
sentiment = data.documentSentiment.score;
}
return sentiment;
感情を読み出す完全なコードは以下のとおりです。
function retrieveSentiment (line) {
var apiKey = "your key here";
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: 'en-us',
type: 'PLAIN_TEXT',
content: line
};
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);
var data = JSON.parse(response);
var sentiment = 0.0;
// Ensure all pieces were in the returned value
if (data && data.documentSentiment
&& data.documentSentiment.score){
sentiment = data.documentSentiment.score;
}
return sentiment;
}
ご自分のスクリプトを保存し、ドキュメントを再読み込みしてから、完全なプログラムを試してみましょう。 新しい機能を有効にするために、ご自分の認証情報で再許可しなければならない場合があります。 ドキュメントのさまざまな部分を選択して、部分ごとに感情がどのように変わるのか確認してみてください。
このコードラボでは Google ドキュメントを作成し、Natural Language API を呼び出してそのドキュメン内で選択した部分の感情を分析してみました。
このサンプルを問題なく操作できたら、Google Cloud Console の [認証情報] セクションに戻り、他で使用されないように API キーを削除しておきましょう。