Natural Language API は、構文を解析してエンティティを抽出し、テキストの感情を把握することができる、事前学習済みの機械学習モデルです。 Google ドキュメントから呼び出して、実行することができます。

このコードラボでは、Natural Language API を呼び出して Google ドキュメント内で選択したテキストの感情を認識し、その感情に応じてテキストをハイライトする方法について学びます。

目標にすること

このコードラボで学んだことを生かすと、次の図のように、メニューからドキュメント内の選択されたテキストの感情にマークを付けられるようになります。

ネガティブな感情のテキストは赤色で、ポジティブな感情のテキストは緑色で、ニュートラルな感情のテキストは黄色でハイライトされます。

学習すること

必要になるもの

このコードラボでは、Google ドキュメントから Natural Language API を呼び出す方法に焦点を当てます。関連のない概念やコード ブロックには詳しくは触れずに、コピー & ペーストすればよい形で用意しています。

自分のペースで進める環境のセットアップ

  1. まだ Google Account(Gmail または Google Apps)をお持ちでない場合は、アカウントを作成する必要があります。
  2. Google Cloud Platform Console(console.cloud.google.comにサインインして、新規プロジェクトを作成します。

  1. 次に、Google Cloud のリソース(Natural Language API など)を使用できるように、Developers Console で課金を有効にする必要があります。 毎月、Natural Language API の最初の 5,000 コールは無料で提供されていますので、このコードラボの間に Google Cloud Platform を使用しても、課金されることはありません。

Google Cloud Platform の新規ユーザーには$300 相当の無料トライアルが付与されます。

ブラウザのタブ/ウィンドウを開いて、Google Cloud Console(https://console.cloud.google.com)にログインします。

ログインすると、以下のような画面が表示されます。

Natural Language API を有効にする

ダッシュボードの一番上にある [APIを有効にする] をクリックし、[Natural Language API] を選択して Natural Language API を有効にします。

API キーを取得する

リクエスト URL 内で渡すための API キーを生成する必要があります。

API キーを作成するために、プロジェクト ダッシュボードの [API Manager] セクションに移動します。

次に、[認証情報 ] タブを選択して、[認証情報を作成] をクリックします。

ドロップダウン メニューで [API キー] を選択します。

取得した API キーをテキスト ファイルまたは Google ドキュメントにコピーします。このキーは後で使用します。 API キーを取得したら、Google ドキュメントに移動する準備の完了です。

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 キーを削除しておきましょう。