קישור ל-API: ניתוח סנטימנט של משוב

רמת הקוד: בינונית
משך הזמן: 20 דקות
סוג הפרויקט: אוטומציה עם תפריט מותאם אישית

מטרות

  • להבין מה הפתרון עושה.
  • הסבר על הפעולות של שירותי Apps Script בתוך הפתרון.
  • מגדירים את הסביבה.
  • מגדירים את הסקריפט.
  • מריצים את הסקריפט.

מידע על הפתרון הזה

אתם יכולים לנתח כמויות גדולות של נתוני טקסט, כמו שאלוני משוב פתוחים. כדי לבצע ניתוח ישויות וניתוח סנטימנטים מתוך Google Sheets, הפתרון הזה משתמש ב-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 עם חשבון לחיוב שמשויך אליו. אפשר לעיין במאמר הפעלת החיוב בפרויקט.

הגדרת הסביבה

פותחים את פרויקט Cloud במסוף Google Cloud

אם הוא עדיין לא פתוח, פותחים את פרויקט Cloud שבו רוצים להשתמש לדוגמה הזו:

  1. נכנסים לדף Select a project במסוף Google Cloud.

    בחירת פרויקט ב-Cloud

  2. בוחרים את הפרויקט ב-Google Cloud שבו רוצים להשתמש. לחלופין, לוחצים על Create project (יצירת פרויקט) ופועלים לפי ההוראות במסך. אם יוצרים פרויקט ב-Google Cloud, יכול להיות שתצטרכו להפעיל את החיוב בפרויקט.

הפעלת Google Cloud Natural Language API

הפתרון הזה מתחבר ל-Google Cloud Natural Language API. לפני שמשתמשים ב-Google APIs, צריך להפעיל אותם בפרויקט ב-Google Cloud. אפשר להפעיל ממשק API אחד או יותר בפרויקט אחד ב-Google Cloud.

  • מפעילים את Google Cloud Natural Language API בפרויקט ב-Cloud.

    להפעלת ה-API

כדי להשתמש בפתרון הזה, צריך פרויקט ב-Cloud עם מסך הסכמה מוגדר. הגדרת מסך ההסכמה ל-OAuth קובעת מה Google תציג למשתמשים ומרשמת את האפליקציה שלכם כדי שתוכלו לפרסם אותה מאוחר יותר.

  1. במסוף Google Cloud, נכנסים לתפריט > APIs & Services > OAuth consent screen.

    מעבר למסך ההסכמה של OAuth

  2. בקטע User type בוחרים באפשרות Internal ולוחצים על Create.
  3. ממלאים את טופס הרישום של האפליקציה ולוחצים על שמירה והמשך.
  4. בשלב הזה, אפשר לדלג על הוספת היקפי הרשאה וללחוץ על Save and Continue (שמירה והמשך). בעתיד, כשיוצרים אפליקציה לשימוש מחוץ לארגון ב-Google Workspace, צריך לשנות את סוג המשתמש ל-חיצוני, ואז להוסיף את היקפי ההרשאה הנדרשים לאפליקציה.

  5. בודקים את סיכום רישום האפליקציה. כדי לבצע שינויים, לוחצים על עריכה. אם הרשמת האפליקציה נראית תקינה, לוחצים על Back to Dashboard.

קבלת מפתח API ל-Google Cloud Natural Language API

  1. נכנסים למסוף Google Cloud. מוודאים שהפרויקט שבו החיוב מופעל פתוח.
  2. במסוף Google Cloud, נכנסים לתפריט > APIs & Services > Credentials.

    כניסה לדף Credentials

  3. לוחצים על Create credentials (יצירת פרטי כניסה) > API key (מפתח 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. בחלק העליון של הגיליון האלקטרוני, לוחצים על Sentiment Tools (כלים למדידת רגשות) > Mark entities and sentiment (סימון ישויות ורגשות). יכול להיות שתצטרכו לרענן את הדף כדי שהתפריט המותאם אישית יופיע.
  2. כשמוצגת בקשה, מאשרים את הסקריפט. אם במסך ההסכמה ל-OAuth מוצגת האזהרה This app isn't verified, ממשיכים על ידי בחירה באפשרות Advanced > Go to {Project Name} (unsafe).

  3. לוחצים שוב על Sentiment Tools (כלים למדידת סנטימנטים) > Mark entities and sentiment (סימון ישויות וסנטימנטים).

  4. כשהסקריפט יסתיים, עוברים לגיליון Pivot Table כדי לראות את התוצאות.

בדיקת הקוד

כדי לבדוק את הקוד של Apps Script לפתרון הזה, לוחצים על הצגת קוד המקור בהמשך:

הצגת קוד המקור

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.
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.

השלבים הבאים