API への接続: フィードバックの感情を分析する

コーディングレベル: 中級
所要時間: 20 分
プロジェクトの種類: カスタム メニューによる自動化

目標

  • ソリューションの機能について理解する。
  • ソリューション内での Apps Script サービスの役割を理解する。
  • 環境をセットアップする。
  • スクリプトを設定します。
  • スクリプトを実行します。

このソリューションについて

自由回答式フィードバックなどのテキストデータを大規模に分析できます。このソリューションでは、Google スプレッドシート内からエンティティ分析と感情分析を実行するために、UrlFetch Service を使用して Google Cloud Natural Language API に接続します。

感情分析の仕組みを示す図

仕組み

このスクリプトは、スプレッドシートからテキストを収集し、Google Cloud Natural Language API に接続して、文字列に含まれるエンティティと感情を分析します。ピボット テーブルには、テキストデータのすべての行に記載されている各エンティティの平均感情スコアがまとめられます。

Apps Script サービス

このソリューションでは、次のサービスを使用します。

  • スプレッドシート サービス - テキストデータを Google Cloud Natural Language API に送信し、センチメントが分析されると各行を「完了」としてマークします。
  • UrlFetch サービス - Google Cloud Natural Language API に接続して、テキストのエンティティ分析と感情分析を行います。

前提条件

このサンプルを使用するには、次の前提条件を満たしている必要があります。

  • Google アカウント(Google Workspace アカウントの場合、管理者の承認が必要となる可能性があります)。
  • インターネットに接続できるウェブブラウザ。

  • 請求先アカウントが関連付けられている Google Cloud プロジェクト。プロジェクトの課金を有効にするをご覧ください。

環境の設定

Google Cloud コンソールで Cloud プロジェクトを開きます。

このサンプルに使用する Cloud プロジェクトをまだ開いていない場合は、開きます。

  1. Google Cloud コンソールで [プロジェクトを選択] ページに移動します。

    Cloud プロジェクトを選択する

  2. 使用する Google Cloud プロジェクトを選択します。または、[プロジェクトを作成] をクリックし、画面の指示に沿って操作します。Google Cloud プロジェクトを作成する場合は、プロジェクトの課金を有効にする必要がある場合があります。

Google Cloud Natural Language API を有効にする

このソリューションは Google Cloud Natural Language API に接続します。Google API を使用する前に、Google Cloud プロジェクトで API を有効にする必要があります。1 つの Google Cloud プロジェクトで 1 つ以上の API を有効にできます。

このソリューションには、同意画面が構成された Cloud プロジェクトが必要です。OAuth 同意画面を構成すると、ユーザーに表示される内容が定義され、後でアプリを公開できるようにアプリが登録されます。

  1. Google Cloud コンソールで、メニュー > [API とサービス] > [OAuth 同意画面] に移動します。

    OAuth 同意画面に移動

  2. [ユーザーの種類] で [内部] を選択し、[作成] をクリックします。
  3. アプリ登録フォームに入力し、[保存して続行] をクリックします。
  4. ここではスコープの追加をスキップして、[保存して次へ] をクリックします。今後、Google Workspace 組織の外部で使用するアプリを作成する場合は、[ユーザータイプ] を [外部] に変更し、アプリに必要な認可スコープを追加する必要があります。

  5. アプリ登録の概要を確認します。変更するには、[編集] をクリックします。アプリの登録に問題がなければ、[ダッシュボードに戻る] をクリックします。

Google Cloud Natural Language API の API キーを取得する

  1. Google Cloud コンソールに移動します。 課金が有効になっているプロジェクトが開いていることを確認します。
  2. Google Cloud コンソールで、メニュー > [API とサービス] > [認証情報] に移動します。

    [認証情報] に移動

  3. [認証情報を作成] > [API キー] をクリックします。

  4. 後で使用できるように、API キーをメモしておきます。

スクリプトを設定する

Apps Script プロジェクトを作成する

  1. 下のボタンをクリックして、フィードバックに対する感情分析のサンプル スプレッドシートのコピーを作成します。このソリューションの Apps Script プロジェクトがスプレッドシートに添付されています。
    コピーを作成
  2. [拡張機能] > [Apps Script] をクリックします。
  3. スクリプト ファイル内の次の変数を API キーに更新します。
    const myApiKey = 'YOUR_API_KEY'; // Replace with your API key.
  4. 保存アイコン[保存] をクリックします。

テキストデータを追加する

  1. スプレッドシートに戻ります。
  2. [id] 列と [comments] 列にテキストデータを追加します。Kaggle のサンプルの宿泊施設のレビューを使用するか、独自のデータを使用できます。必要に応じて列を追加できますが、スクリプトを正常に実行するには、id 列と comments 列にデータが必要です。

スクリプトを実行する

  1. スプレッドシートの上部にある [感情分析ツール] > [エンティティと感情をマーク] をクリックします。このカスタム メニューが表示されない場合は、ページを更新してください。
  2. プロンプトが表示されたら、スクリプトを承認します。OAuth 同意画面に [このアプリは確認されていません] という警告が表示された場合は、[詳細] > [{プロジェクト名} に移動(安全でない)] を選択して続行します。

  3. [感情ツール] > [エンティティと感情をマーク] をもう一度クリックします。

  4. スクリプトが完了したら、[ピボット テーブル] シートに切り替えて結果を確認します。

コードを確認する

このソリューションの Apps Script コードを確認するには、下の [ソースコードを表示] をクリックします。

ソースコードを表示

コード.gs

solutions/automations/feedback-sentiment-analysis/code.js
// To learn how to use this script, refer to the documentation:
// https://developers.google.com/apps-script/samples/automations/feedback-sentiment-analysis

/*
Copyright 2022 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Sets API key for accessing Cloud Natural Language API.
const myApiKey = 'YOUR_API_KEY'; // Replace with your API key.

// Matches column names in Review Data sheet to variables.
let COLUMN_NAME = {
  COMMENTS: 'comments',
  ENTITY: 'entity_sentiment',
  ID: 'id'
};

/**
 * Creates a Demo menu in Google Spreadsheets.
 */
function onOpen() {
  SpreadsheetApp.getUi()
    .createMenu('Sentiment Tools')
    .addItem('Mark entities and sentiment', 'markEntitySentiment')
    .addToUi();
};

/**
* Analyzes entities and sentiment for each comment in  
* Review Data sheet and copies results into the 
* Entity Sentiment Data sheet.
*/
function markEntitySentiment() {
  // Sets variables for "Review Data" sheet
  let ss = SpreadsheetApp.getActiveSpreadsheet();
  let dataSheet = ss.getSheetByName('Review Data');
  let rows = dataSheet.getDataRange();
  let numRows = rows.getNumRows();
  let values = rows.getValues();
  let headerRow = values[0];

  // Checks to see if "Entity Sentiment Data" sheet is present, and
  // if not, creates a new sheet and sets the header row.
  let entitySheet = ss.getSheetByName('Entity Sentiment Data');
  if (entitySheet == null) {
   ss.insertSheet('Entity Sentiment Data');
   let entitySheet = ss.getSheetByName('Entity Sentiment Data');
   let esHeaderRange = entitySheet.getRange(1,1,1,6);
   let esHeader = [['Review ID','Entity','Salience','Sentiment Score',
                    'Sentiment Magnitude','Number of mentions']];
   esHeaderRange.setValues(esHeader);
  };

  // Finds the column index for comments, language_detected, 
  // and comments_english columns.
  let textColumnIdx = headerRow.indexOf(COLUMN_NAME.COMMENTS);
  let entityColumnIdx = headerRow.indexOf(COLUMN_NAME.ENTITY);
  let idColumnIdx = headerRow.indexOf(COLUMN_NAME.ID);
  if (entityColumnIdx == -1) {
    Browser.msgBox("Error: Could not find the column named " + COLUMN_NAME.ENTITY + 
                   ". Please create an empty column with header \"entity_sentiment\" on the Review Data tab.");
    return; // bail
  };

  ss.toast("Analyzing entities and sentiment...");
  for (let i = 0; i < numRows; ++i) {
    let value = values[i];
    let commentEnCellVal = value[textColumnIdx];
    let entityCellVal = value[entityColumnIdx];
    let reviewId = value[idColumnIdx];

    // Calls retrieveEntitySentiment function for each row that has a comment 
    // and also an empty entity_sentiment cell value.
    if(commentEnCellVal && !entityCellVal) {
        let nlData = retrieveEntitySentiment(commentEnCellVal);
        // Pastes each entity and sentiment score into Entity Sentiment Data sheet.
        let newValues = []
        for (let entity in nlData.entities) {
          entity = nlData.entities [entity];
          let row = [reviewId, entity.name, entity.salience, entity.sentiment.score, 
                     entity.sentiment.magnitude, entity.mentions.length
                    ];
          newValues.push(row);
        }
      if(newValues.length) {
        entitySheet.getRange(entitySheet.getLastRow() + 1, 1, newValues.length, newValues[0].length).setValues(newValues);
      }
        // Pastes "complete" into entity_sentiment column to denote completion of NL API call.
        dataSheet.getRange(i+1, entityColumnIdx+1).setValue("complete");
     }
   }
};

/**
 * Calls the Cloud Natural Language API with a string of text to analyze
 * entities and sentiment present in the string.
 * @param {String} the string for entity sentiment analysis
 * @return {Object} the entities and related sentiment present in the string
 */
function retrieveEntitySentiment (line) {
  let apiKey = myApiKey;
  let apiEndpoint = 'https://language.googleapis.com/v1/documents:analyzeEntitySentiment?key=' + apiKey;
  // Creates a JSON request, with text string, language, type and encoding
  let nlData = {
    document: {
      language: 'en-us',
      type: 'PLAIN_TEXT',
      content: line
    },
    encodingType: 'UTF8'
  };
  // Packages all of the options and the data together for the API call.
  let nlOptions = {
    method : 'post',
    contentType: 'application/json',  
    payload : JSON.stringify(nlData)
  };
  // Makes the API call.
  let response = UrlFetchApp.fetch(apiEndpoint, nlOptions);
  return JSON.parse(response);
};

寄稿者

このサンプルは、Google デベロッパー エキスパートの協力を得て Google によって管理されています。

次のステップ