Analisar o sentimento do feedback usando a API Natural Language do Google Cloud

Nível de programação: intermediário
Duração: 20 minutos
Tipo de projeto: automação com um menu personalizado

Objetivos

  • Entenda o que a solução faz.
  • Entenda o que os serviços do Apps Script fazem na solução.
  • Prepare o ambiente.
  • Configure o script.
  • Execute o script.

Sobre esta solução

É possível analisar dados de texto, como feedback aberto, em escala. Para realizar análises de entidade e sentimento nas Planilhas Google, essa solução usa o serviço UrlFetch para se conectar à API Natural Language do Google Cloud.

Diagrama de como a análise de sentimento funciona

Como funciona

O script coleta texto da planilha e se conecta à API Natural Language do Google Cloud para analisar entidades e sentimentos presentes na string. Uma tabela dinâmica resume a pontuação média de sentimento para cada entidade mencionada em todas as linhas de dados de texto.

Serviços do Apps Script

Esta solução usa os seguintes serviços:

  • Serviço de planilha: envia os dados de texto para a API Cloud Natural Language do Google Cloud e marca cada linha como "Concluída" depois que o sentimento é analisado.
  • Serviço UrlFetch: se conecta à API Google Cloud Natural Language para realizar análises de entidade e sentimento no texto.

Pré-requisitos

Para usar esta amostra, você precisa atender aos seguintes pré-requisitos:

  • Uma Conta do Google (as contas do Google Workspace podem exigir a aprovação do administrador).
  • Um navegador da Web com acesso à Internet.

  • Um projeto do Google Cloud com uma conta de faturamento associada. Consulte Ativar o faturamento de um projeto.

Configurar o ambiente

Abra seu projeto do Cloud no console do Google Cloud.

Se ele ainda não estiver aberto, abra o projeto do Google Cloud que você pretende usar para esta amostra:

  1. No console do Google Cloud, acesse a página Selecionar um projeto.

    Selecione um projeto do Cloud

  2. Selecione o projeto do Google Cloud que você quer usar. Ou clique em Criar projeto e siga as instruções na tela. Se você criar um projeto do Google Cloud, talvez seja necessário ativar o faturamento dele.

Ativar a API Cloud Natural Language

Essa solução se conecta à API Cloud Natural Language do Google Cloud. Antes de usar as APIs do Google, é necessário ativá-las em um projeto do Google Cloud. É possível ativar uma ou mais APIs em um único projeto do Google Cloud.

  • No seu projeto do Cloud, ative a API Google Cloud Natural Language.

    Ativar a API

Essa solução exige um projeto do Cloud com uma tela de consentimento configurada. Ao configurar a tela de permissão OAuth, você define o que o Google mostra aos usuários e registra seu app para que ele possa ser publicado mais tarde.

  1. No console do Google Cloud, acesse Menu > Google Auth platform > Branding.

    Acessar Branding

  2. Se você já tiver configurado o Google Auth platform, poderá definir as seguintes configurações da tela de permissão do OAuth em Branding, Público-alvo e Acesso a dados. Se você receber uma mensagem informando que Google Auth platform ainda não foi configurado, clique em Começar:
    1. Em Informações do app, no campo Nome do app, insira um nome para o app.
    2. Em E-mail para suporte do usuário, escolha um endereço de e-mail de suporte para que os usuários possam entrar em contato com você se tiverem dúvidas sobre o consentimento deles.
    3. Clique em Próxima.
    4. Em Público-alvo, selecione Interno.
    5. Clique em Próxima.
    6. Em Informações de contato, insira um Endereço de e-mail para receber notificações sobre mudanças no seu projeto.
    7. Clique em Próxima.
    8. Em Concluir, leia a Política de dados do usuário dos serviços de API do Google e, se concordar, selecione Concordo com a Política de dados do usuário dos serviços de API do Google.
    9. Clique em Continuar.
    10. Clique em Criar.
  3. Por enquanto, você pode pular a adição de escopos. No futuro, quando você criar um app para uso fora da sua organização do Google Workspace, mude o Tipo de usuário para Externo. Em seguida, adicione os escopos de autorização necessários para o app. Para saber mais, consulte o guia completo Configurar a permissão OAuth.

Receber uma chave de API para a API Google Cloud Natural Language

  1. Acesse o Console do Google Cloud. Verifique se o projeto com faturamento ativado está aberto.
  2. No console do Google Cloud, acesse Menu > APIs e serviços > Credenciais.

    Ir para Credenciais

  3. Clique em Criar credenciais > Chave de API.

  4. Anote a chave de API para usar em uma etapa posterior.

Configurar o script

Criar o projeto do Apps Script

  1. Clique no botão abaixo para fazer uma cópia da planilha de exemplo Análise de sentimento para feedback. O projeto do Apps Script para essa solução está anexado à planilha.
    Fazer uma cópia
  2. Clique em Extensões > Apps Script.
  3. Atualize a seguinte variável no arquivo de script com sua chave de API:
    const myApiKey = 'YOUR_API_KEY'; // Replace with your API key.
  4. Clique em Salvar Ícone Salvar.

Adicionar dados de texto

  1. Volte para a planilha.
  2. Adicione dados de texto às colunas id e comments. Você pode usar amostras de avaliações de imóveis para férias do Kaggle ou seus próprios dados. Você pode adicionar mais colunas, se necessário, mas para ser executado com sucesso, o script precisa ter dados nas colunas id e comments.

Executar o script

  1. Na parte de cima da planilha, clique em Ferramentas de análise de sentimento > Marcar entidades e sentimento. Talvez seja necessário atualizar a página para que esse menu personalizado apareça.
  2. Quando solicitado, autorize o script. Se a tela de permissão OAuth mostrar o aviso Este app não foi verificado, selecione Avançado > Acessar {Nome do projeto} (não seguro).

  3. Clique em Ferramentas de análise de sentimentos > Marcar entidades e sentimentos novamente.

  4. Quando o script terminar, mude para a planilha Tabela dinâmica para conferir os resultados.

Revisar o código

Para revisar o código do Apps Script dessa solução, clique em Ver código-fonte abaixo:

Acessar o código-fonte

Code.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.
const 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
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const dataSheet = ss.getSheetByName("Review Data");
  const rows = dataSheet.getDataRange();
  const numRows = rows.getNumRows();
  const values = rows.getValues();
  const 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.
  const entitySheet = ss.getSheetByName("Entity Sentiment Data");
  if (entitySheet == null) {
    ss.insertSheet("Entity Sentiment Data");
    const entitySheet = ss.getSheetByName("Entity Sentiment Data");
    const esHeaderRange = entitySheet.getRange(1, 1, 1, 6);
    const 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.
  const textColumnIdx = headerRow.indexOf(COLUMN_NAME.COMMENTS);
  const entityColumnIdx = headerRow.indexOf(COLUMN_NAME.ENTITY);
  const 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) {
    const value = values[i];
    const commentEnCellVal = value[textColumnIdx];
    const entityCellVal = value[entityColumnIdx];
    const reviewId = value[idColumnIdx];

    // Calls retrieveEntitySentiment function for each row that has a comment
    // and also an empty entity_sentiment cell value.
    if (commentEnCellVal && !entityCellVal) {
      const nlData = retrieveEntitySentiment(commentEnCellVal);
      // Pastes each entity and sentiment score into Entity Sentiment Data sheet.
      const newValues = [];
      for (let entity in nlData.entities) {
        entity = nlData.entities[entity];
        const 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) {
  const apiKey = myApiKey;
  const apiEndpoint = `https://language.googleapis.com/v1/documents:analyzeEntitySentiment?key=${apiKey}`;
  // Creates a JSON request, with text string, language, type and encoding
  const 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.
  const nlOptions = {
    method: "post",
    contentType: "application/json",
    payload: JSON.stringify(nlData),
  };
  // Makes the API call.
  const response = UrlFetchApp.fetch(apiEndpoint, nlOptions);
  return JSON.parse(response);
}

Colaboradores

Esta amostra é mantida pelo Google com a ajuda dos Google Developer Experts.

Próximas etapas