קבל תובנה טובה יותר מסקירות באמצעות Amazon Comprehend PlatoBlockchain Data Intelligence. חיפוש אנכי. איי.

קבל תובנה טובה יותר מביקורות באמצעות Amazon Comprehend

"85% מהקונים סומכים על ביקורות מקוונות כמו המלצה אישית" - גרטנר

צרכנים מתקשרים יותר ויותר עם עסקים באמצעות משטחים דיגיטליים ונקודות מגע מרובות. נתונים סטטיסטיים מראים שרוב הקונים משתמשים בביקורות כדי לקבוע אילו מוצרים לקנות ובאילו שירותים להשתמש. לפי מרכז המחקר שפיגל, סבירות הרכישה של מוצר עם חמש ביקורות גדולה ב-270% מהסבירות לרכישה של מוצר ללא ביקורות. לביקורות יש את הכוח להשפיע על החלטות צרכנים ולחזק את ערך המותג.

בפוסט זה אנו משתמשים אמזון להתבונן לחלץ מידע משמעותי מסקירות מוצרים, לנתח אותו כדי להבין כיצד מגיבים משתמשים בקבוצות דמוגרפיה שונות למוצרים, ולגלות מידע מצטבר על זיקה של משתמשים למוצר. Amazon Comprehend הוא שירות עיבוד שפה טבעית (NLP) מנוהל במלואו ומאומן באופן רציף שיכול להוציא תובנות לגבי תוכן של מסמך או טקסט.

סקירת פתרונות

כיום, לקוחות יכולים לספק ביקורות בדרכים שונות, כגון דירוגי כוכבים, טקסט חופשי או שפה טבעית, או שיתופים ברשתות חברתיות. ביקורות טקסט חופשי או שפה טבעית עוזרות לבנות אמון, מכיוון שזו חוות דעת עצמאית של צרכנים. הוא משמש לעתים קרובות על ידי צוותי מוצר כדי ליצור אינטראקציה עם לקוחות דרך ערוצי ביקורת. עובדה מוכחת היא שכאשר לקוחות מרגישים שנשמעו, ההרגשה שלהם לגבי המותג משתפרת. בעוד שקל יחסית לנתח דירוגי כוכבים או שיתופים במדיה חברתית, שפה טבעית או ביקורות טקסט חופשיות מציבים אתגרים רבים, כמו זיהוי מילות מפתח או ביטויים, נושאים או מושגים, וסנטימנטים או רגשות ברמת הישות. האתגר נובע בעיקר משונות האורך בטקסט הכתוב ונוכחות סבירה של אותות ורעש כאחד. יתר על כן, המידע יכול להיות מאוד ברור ומפורש (לדוגמה, עם מילות מפתח וביטויי מפתח) או לא ברור ומרומז (נושאים ומושגים מופשטים). עוד יותר מאתגר הוא להבין סוגים שונים של סנטימנטים ולקשר אותם למוצרים ושירותים מתאימים. עם זאת, חשוב מאוד להבין את המידע ואת האותות הטקסטואליים כדי לספק חווית לקוח ללא חיכוכים.

בפוסט זה, אנו משתמשים בקובץ זמין לציבור NLP – fast.ai מערך נתונים לניתוח סקירות המוצרים שסופקו על ידי לקוחות. אנו מתחילים בשימוש בטכניקת למידת מכונה ללא פיקוח (ML) הידועה בשם דוגמנות נושאים. זוהי טכניקה פופולרית ללא פיקוח המגלה נושאים מופשטים שיכולים להתרחש באוסף סקירת טקסט. דוגמנות נושאים היא בעיית אשכולות שאינה מפוקחת, כלומר אין למודלים ידע על משתני יעד אפשריים (כגון נושאים בסקירה). הנושאים מיוצגים כאשכולות. לעתים קרובות, מספר האשכולות בקורפוס של מסמכים נקבע בעזרת מומחי תחום או באמצעות ניתוח סטטיסטי סטנדרטי כלשהו. פלטי המודל כוללים בדרך כלל שלושה מרכיבים: אשכולות ממוספרים (נושא 0, נושא 1 וכן הלאה), מילות מפתח המשויכות לכל אשכול ואשכולות מייצגים לכל מסמך (או סקירה במקרה שלנו). מטבעם המובנה, מודלים של נושאים אינם יוצרים תוויות קריאות לאדם עבור האשכולות או הנושאים, וזו תפיסה שגויה נפוצה. משהו שכדאי לשים לב אליו לגבי מודלים של נושאים באופן כללי הוא שזהו מודל חברות מעורב - לכל מסמך במודל עשוי להיות דמיון לכל נושא. מודל הנושא לומד בתהליך בייסיאני איטרטיבי כדי לקבוע את ההסתברות שכל מסמך משויך לנושא או לנושא נתון. פלט הדגם תלוי בבחירת מספר הנושאים בצורה מיטבית. מספר קטן של נושאים עלול לגרום לנושאים להיות רחבים מדי, ומספר גדול יותר של נושאים עלול לגרום לנושאים מיותרים או לנושאים בעלי דמיון. ישנן מספר דרכים להעריך מודלים של נושאים:

  • שיפוט אנושי – מבוסס תצפית, מבוסס פרשנות
  • מדדים כמותיים - תמיהה, חישובי קוהרנטיות
  • גישה מעורבת - שילוב של גישות מבוססות שיפוט וכמותיות

התמיהה מחושבת על ידי פיצול מערך נתונים לשני חלקים - ערכת הדרכה ומערך מבחנים. הסבירות מחושבת בדרך כלל כלוגריתם, כך שמדד זה מכונה לפעמים סבירות היומן המתוחזקת. תמיהה היא מדד חיזוי. הוא מעריך את יכולתו של מודל נושא לחזות מערך מבחנים לאחר שהוכשר על ערכת אימונים. אחד החסרונות של התמיהה הוא שהוא לא לוכד הקשר, כלומר הוא לא לוכד את הקשר בין מילים בנושא או נושאים במסמך. עם זאת, הרעיון של הקשר סמנטי חשוב להבנה האנושית. מדדים כגון הסבירות המותנית להתרחשות משותפת של מילים בנושא יכולים להיות מועילים. גישות אלו מכונות ביחד קוהרנטיות. עבור פוסט זה, אנו מתמקדים בגישת השיפוט האנושי (מבוסס תצפית), כלומר התבוננות ב-n המילים המובילות בנושא.

הפתרון מורכב מהשלבים הבאים ברמה גבוהה:

  1. הגדר אמזון SageMaker מופע מחברת.
  2. צור מחברת.
  3. בצע ניתוח נתוני חקר.
  4. הפעל את עבודת הדוגמנות שלך בנושא Amazon Comprehend.
  5. ליצור נושאים ולהבין סנטימנט.
  6. השתמש אמזון קוויקסייט כדי להמחיש נתונים ולהפיק דוחות.

אתה יכול להשתמש בפתרון הזה בכל אזור AWS, אבל אתה צריך לוודא שממשקי ה-API של Amazon Comprehend ו-SageMaker נמצאים באותו אזור. עבור פוסט זה, אנו משתמשים באזור ארה"ב מזרח (נ' וירג'יניה).

הגדר את מופע המחברת של SageMaker שלך

אתה יכול ליצור אינטראקציה עם Amazon Comprehend דרך קונסולת הניהול של AWS, ממשק שורת הפקודה AWS (AWS CLI), או Amazon Comprehend API. למידע נוסף, עיין ב תחילת העבודה עם Amazon Comprehend. אנו משתמשים במחברת SageMaker ובקוד Python (Boto3) לאורך הפוסט הזה כדי ליצור אינטראקציה עם ממשקי ה-API של Amazon Comprehend.

  1. במסוף אמזון SageMaker, תחת Notebook בחלונית הניווט, בחר
    מופעי מחברת.
  2. בחר צור מופע מחברת.מופעי מחברת
  3. ציין שם מופע של מחברת והגדר את סוג המופע כ-ml.r5.2xlarge.
  4. השאר את שאר הגדרות ברירת המחדל.
  5. צור AWS זהות וניהול גישה (IAM) תפקיד עם AmazonSageMakerFullAccess וגישה לכל צורך שירות אחסון פשוט של אמזון (Amazon S3) דליים וממשקי API של Amazon Comprehend.
  6. בחר צור מופע מחברת.
    לאחר מספר דקות, מופע המחברת שלך מוכן.
  7. כדי לגשת ל- Amazon Comprehend ממופע המחברת, עליך לצרף את ComprehendFullAccess מדיניות לתפקיד IAM שלך.

לסקירת אבטחה של Amazon Comprehend, עיין ב אבטחה ב- Amazon Comprehend.

לאחר פתיחת מופע המחברת שהקבעת, במסוף Jupyter, בחר New ולאחר מכן Python 3 (Data Science). לחלופין, תוכל לגשת לקובץ הקוד לדוגמה ב- GitHub ריפו. אתה יכול להעלות את הקובץ למופע המחברת כדי להפעיל אותו ישירות או לשכפל אותו.

המאגר של GitHub מכיל שלוש מחברות:

  • data_processing.ipynb
  • model_training.ipynb
  • topic_mapping_sentiment_generation.ipynb

ביצוע ניתוח נתונים חקרני

אנו משתמשים במחברת הראשונה (data_processing.ipynb) כדי לחקור ולעבד את הנתונים. אנו מתחילים בטעינת הנתונים מדלי S3 לתוך DataFrame.

# Bucket containing the data
BUCKET = 'clothing-shoe-jewel-tm-blog'

# Item ratings and metadata
S3_DATA_FILE = 'Clothing_Shoes_and_Jewelry.json.gz' # Zip
S3_META_FILE = 'meta_Clothing_Shoes_and_Jewelry.json.gz' # Zip

S3_DATA = 's3://' + BUCKET + '/' + S3_DATA_FILE
S3_META = 's3://' + BUCKET + '/' + S3_META_FILE

# Transformed review, input for Comprehend
LOCAL_TRANSFORMED_REVIEW = os.path.join('data', 'TransformedReviews.txt')
S3_OUT = 's3://' + BUCKET + '/out/' + 'TransformedReviews.txt'

# Final dataframe where topics and sentiments are going to be joined
S3_FEEDBACK_TOPICS = 's3://' + BUCKET + '/out/' + 'FinalDataframe.csv'

def convert_json_to_df(path):
    """Reads a subset of a json file in a given path in chunks, combines, and returns
    """
    # Creating chunks from 500k data points each of chunk size 10k
    chunks = pd.read_json(path, orient='records', 
                                lines=True, 
                                nrows=500000, 
                                chunksize=10000, 
                                compression='gzip')
    # Creating a single dataframe from all the chunks
    load_df = pd.DataFrame()
    for chunk in chunks:
        load_df = pd.concat([load_df, chunk], axis=0)
    return load_df

# Review data
original_df = convert_json_to_df(S3_DATA)

# Metadata
original_meta = convert_json_to_df(S3_META)

בסעיף הבא, אנו מבצעים ניתוח נתונים חקרני (EDA) כדי להבין את הנתונים. אנו מתחילים בחקירת צורת הנתונים והמטא נתונים. לצורך האותנטיות, אנו משתמשים בביקורות מאומתות בלבד.

# Shape of reviews and metadata
print('Shape of review data: ', original_df.shape)
print('Shape of metadata: ', original_meta.shape)

# We are interested in verified reviews only
# Also checking the amount of missing values in the review data
print('Frequency of verified/non verified review data: ', original_df['verified'].value_counts())
print('Frequency of missing values in review data: ', original_df.isna().sum())

אנו חוקרים עוד את הספירה של כל קטגוריה, ונראה אם ​​קיימים נתונים כפולים.

# Count of each categories for EDA.
print('Frequncy of different item categories in metadata: ', original_meta['category'].value_counts())

# Checking null values for metadata
print('Frequency of missing values in metadata: ', original_meta.isna().sum())

# Checking if there are duplicated data. There are indeed duplicated data in the dataframe.
print('Duplicate items in metadata: ', original_meta[original_meta['asin'].duplicated()])

כאשר אנו מרוצים מהתוצאות, אנו עוברים לשלב הבא של עיבוד מוקדם של הנתונים. Amazon Comprehend ממליצה לספק לפחות 1,000 מסמכים בכל עבודת דוגמנות בנושא, כאשר כל מסמך באורך שלושה משפטים לפחות. המסמכים חייבים להיות בקובצי טקסט בפורמט UTF-8. בשלב הבא, אנו מוודאים שהנתונים הם בפורמט UTF-8 המומלץ וכל קלט בגודל של לא יותר מ-5,000 בתים.

def clean_text(df):
    """Preprocessing review text.
    The text becomes Comprehend compatible as a result.
    This is the most important preprocessing step.
    """
    # Encode and decode reviews
    df['reviewText'] = df['reviewText'].str.encode("utf-8", "ignore")
    df['reviewText'] = df['reviewText'].str.decode('ascii')

    # Replacing characters with whitespace
    df['reviewText'] = df['reviewText'].replace(r'r+|n+|t+|u2028',' ', regex=True)

    # Replacing punctuations
    df['reviewText'] = df['reviewText'].str.replace('[^ws]','', regex=True)

    # Lowercasing reviews
    df['reviewText'] = df['reviewText'].str.lower()
    return df

def prepare_input_data(df):
    """Encoding and getting reviews in byte size.
    Review gets encoded to utf-8 format and getting the size of the reviews in bytes. 
    Comprehend requires each review input to be no more than 5000 Bytes
    """
    df['review_size'] = df['reviewText'].apply(lambda x:len(x.encode('utf-8')))
    df = df[(df['review_size'] > 0) & (df['review_size'] < 5000)]
    df = df.drop(columns=['review_size'])
    return df

# Only data points with a verified review will be selected and the review must not be missing
filter = (original_df['verified'] == True) & (~original_df['reviewText'].isna())
filtered_df = original_df[filter]

# Only a subset of fields are selected in this experiment. 
filtered_df = filtered_df[['asin', 'reviewText', 'summary', 'unixReviewTime', 'overall', 'reviewerID']]

# Just in case, once again, dropping data points with missing review text
filtered_df = filtered_df.dropna(subset=['reviewText'])
print('Shape of review data: ', filtered_df.shape)

# Dropping duplicate items from metadata
original_meta = original_meta.drop_duplicates(subset=['asin'])

# Only a subset of fields are selected in this experiment. 
original_meta = original_meta[['asin', 'category', 'title', 'description', 'brand', 'main_cat']]

# Clean reviews using text cleaning pipeline
df = clean_text(filtered_df)

# Dataframe where Comprehend outputs (topics and sentiments) will be added
df = prepare_input_data(df)

לאחר מכן אנו שומרים את הנתונים באמזון S3 וגם שומרים עותק מקומי במופע המחברת.

# Saving dataframe on S3 df.to_csv(S3_FEEDBACK_TOPICS, index=False) 

# Reviews are transformed per Comprehend guideline- one review per line
# The txt file will be used as input for Comprehend
# We first save the input file locally
with open(LOCAL_TRANSFORMED_REVIEW, "w") as outfile:
    outfile.write("n".join(df['reviewText'].tolist()))

# Transferring the transformed review (input to Comprehend) to S3
!aws s3 mv {LOCAL_TRANSFORMED_REVIEW} {S3_OUT}

זה משלים את שלב עיבוד הנתונים שלנו.

הפעל עבודת דוגמנות בנושא Amazon Comprehend

לאחר מכן אנו עוברים לשלב הבא, שבו אנו משתמשים בנתונים המעובדים מראש כדי להפעיל עבודת דוגמנות נושאים באמצעות Amazon Comprehend. בשלב זה, אתה יכול להשתמש במחברת השנייה (model_training.ipynb) או השתמש במסוף Amazon Comprehend כדי להפעיל את עבודת הדוגמנות בנושא. להוראות לשימוש במסוף, עיין ב הפעלת עבודות ניתוח באמצעות המסוף. אם אתה משתמש במחברת, אתה יכול להתחיל ביצירת לקוח Amazon Comprehend באמצעות Boto3, כפי שמוצג בדוגמה הבאה.

# Client and session information
session = boto3.Session()
s3 = boto3.resource('s3')

# Account id. Required downstream.
account_id = boto3.client('sts').get_caller_identity().get('Account')

# Initializing Comprehend client
comprehend = boto3.client(service_name='comprehend', 
                          region_name=session.region_name)

אתה יכול להגיש את המסמכים שלך לעיצוב נושא בשתי דרכים: מסמך אחד לכל קובץ, או מסמך אחד בכל שורה.

אנחנו מתחילים עם 5 נושאים (מספר k), ומשתמשים במסמך אחד בכל שורה. אין דרך אחת הטובה ביותר כתרגול סטנדרטי לבחור k או מספר הנושאים. אתה יכול לנסות ערכים שונים של k, ולבחור את הערך בעל הסבירות הגדולה ביותר.

# Number of topics set to 5 after having a human-in-the-loop
# This needs to be fully aligned with topicMaps dictionary in the third script 
NUMBER_OF_TOPICS = 5

# Input file format of one review per line
input_doc_format = "ONE_DOC_PER_LINE"

# Role arn (Hard coded, masked)
data_access_role_arn = "arn:aws:iam::XXXXXXXXXXXX:role/service-role/AmazonSageMaker-ExecutionRole-XXXXXXXXXXXXXXX"

עבודת הדוגמנות שלנו ב-Amazon Comprehend דורשת ממך לעבור InputDataConfig אובייקט מילון עם S3, InputFormat, ו DocumentReadAction לפי הפרמטרים הנדרשים. באופן דומה, אתה צריך לספק את OutputDataConfig אובייקט עם S3 ו DataAccessRoleArn לפי הפרמטרים הנדרשים. למידע נוסף, עיין בתיעוד Boto3 עבור start_topics_detection_job.

# Constants for S3 bucket and input data file
BUCKET = 'clothing-shoe-jewel-tm-blog'
input_s3_url = 's3://' + BUCKET + '/out/' + 'TransformedReviews.txt'
output_s3_url = 's3://' + BUCKET + '/out/' + 'output/'

# Final dataframe where we will join Comprehend outputs later
S3_FEEDBACK_TOPICS = 's3://' + BUCKET + '/out/' + 'FinalDataframe.csv'

# Local copy of Comprehend output
LOCAL_COMPREHEND_OUTPUT_DIR = os.path.join('comprehend_out', '')
LOCAL_COMPREHEND_OUTPUT_FILE = os.path.join(LOCAL_COMPREHEND_OUTPUT_DIR, 'output.tar.gz')

INPUT_CONFIG={
    # The S3 URI where Comprehend input is placed.
    'S3Uri':    input_s3_url,
    # Document format
    'InputFormat': input_doc_format,
}
OUTPUT_CONFIG={
    # The S3 URI where Comprehend output is placed.
    'S3Uri':    output_s3_url,
}

לאחר מכן תוכל להתחיל משימת זיהוי נושאים אסינכרוני על ידי העברת מספר הנושאים, אובייקט תצורת הקלט, אובייקט תצורת הפלט ותפקיד IAM, כפי שמוצג בדוגמה הבאה.

# Reading the Comprehend input file just to double check if number of reviews 
# and the number of lines in the input file have an exact match.
obj = s3.Object(input_s3_url)
comprehend_input = obj.get()['Body'].read().decode('utf-8')
comprehend_input_lines = len(comprehend_input.split('n'))

# Reviews where Comprehend outputs will be merged
df = pd.read_csv(S3_FEEDBACK_TOPICS)
review_df_length = df.shape[0]

# The two lengths must be equal
assert comprehend_input_lines == review_df_length

# Start Comprehend topic modelling job.
# Specifies the number of topics, input and output config and IAM role ARN 
# that grants Amazon Comprehend read access to data.
start_topics_detection_job_result = comprehend.start_topics_detection_job(
                                                    NumberOfTopics=NUMBER_OF_TOPICS,
                                                    InputDataConfig=INPUT_CONFIG,
                                                    OutputDataConfig=OUTPUT_CONFIG,
                                                    DataAccessRoleArn=data_access_role_arn)

print('start_topics_detection_job_result: ' + json.dumps(start_topics_detection_job_result))

# Job ID is required downstream for extracting the Comprehend results
job_id = start_topics_detection_job_result["JobId"]
print('job_id: ', job_id)

אתה יכול לעקוב אחר המצב הנוכחי של העבודה על ידי התקשרות ל DescribeTopicDetectionJob מבצע. סטטוס המשרה יכול להיות אחד מהבאים:

  • הוגשה - המשרה התקבלה והיא עומדת בתור לעיבוד
  • IN_PROGRESS - Amazon Comprehend מעבד את העבודה
  • הושלמה - העבודה הושלמה בהצלחה והפלט זמין
  • נכשל - העבודה לא הושלמה
# Topic detection takes a while to complete. 
# We can track the current status by calling Use the DescribeTopicDetectionJob operation.
# Keeping track if Comprehend has finished its job
description = comprehend.describe_topics_detection_job(JobId=job_id)

topic_detection_job_status = description['TopicsDetectionJobProperties']["JobStatus"]
print(topic_detection_job_status)
while topic_detection_job_status not in ["COMPLETED", "FAILED"]:
    time.sleep(120)
    topic_detection_job_status = comprehend.describe_topics_detection_job(JobId=job_id)['TopicsDetectionJobProperties']["JobStatus"]
    print(topic_detection_job_status)

topic_detection_job_status = comprehend.describe_topics_detection_job(JobId=job_id)['TopicsDetectionJobProperties']["JobStatus"]
print(topic_detection_job_status)

כאשר העבודה הושלמה בהצלחה, היא מחזירה ארכיון דחוס המכיל שני קבצים: topic-terms.csv ו-doc-topics.csv. קובץ הפלט הראשון, topic-terms.csv, היא רשימה של נושאים באוסף. עבור כל נושא, הרשימה כוללת, כברירת מחדל, את המונחים המובילים לפי נושא לפי משקלם. הקובץ השני, doc-topics.csv, מפרט את המסמכים המשויכים לנושא ואת הפרופורציה של המסמך הנוגע לנושא. כי פירטנו ONE_DOC_PER_LINE מוקדם יותר ב input_doc_format משתנה, המסמך מזוהה על ידי שם הקובץ ומספר השורה 0 באינדקס בתוך הקובץ. למידע נוסף על דוגמנות נושאים, עיין ב דוגמנות נושא.
הפלטים של Amazon Comprehend מועתקים באופן מקומי לצעדים הבאים שלנו.

# Bucket prefix where model artifacts are stored
prefix = f'{account_id}-TOPICS-{job_id}'

# Model artifact zipped file
artifact_file = 'output.tar.gz'

# Location on S3 where model artifacts are stored
target = f's3://{BUCKET}/out/output/{prefix}/{artifact_file}'

# Copy Comprehend output from S3 to local notebook instance
! aws s3 cp {target}  ./comprehend-out/

# Unzip the Comprehend output file. 
# Two files are now saved locally- 
#       (1) comprehend-out/doc-topics.csv and 
#       (2) comprehend-out/topic-terms.csv

comprehend_tars = tarfile.open(LOCAL_COMPREHEND_OUTPUT_FILE)
comprehend_tars.extractall(LOCAL_COMPREHEND_OUTPUT_DIR)
comprehend_tars.close()

מכיוון שמספר הנושאים קטן בהרבה מאוצר המילים המשויך לאוסף המסמכים, ניתן לראות את ייצוג מרחב הנושא גם כתהליך הפחתת מימד. אתה יכול להשתמש בייצוג מרחב נושא זה של מסמכים כדי לבצע אשכולות. מצד שני, אתה יכול לנתח את תדירות המילים בכל אשכול כדי לקבוע נושא המשויך לכל אשכול. עבור הפוסט הזה, אנחנו לא מבצעים שום טכניקה אחרת כמו קיבוץ.

אנו משתמשים במחברת השלישית (topic_mapping_sentiment_generation.ipynb) כדי למצוא כיצד משתמשים בדמוגרפיה שונים מגיבים למוצרים, וכן לנתח מידע מצטבר על זיקה של משתמשים למוצר מסוים.

נוכל לשלב את הפלטים מהמחברת הקודמת כדי לקבל נושאים ומונחים נלווים לכל נושא. עם זאת, הנושאים ממוספרים ועשויים להיות חסרי הסבר. לכן, אנו מעדיפים להשתמש באדם בלולאה עם מספיק ידע בתחום ומומחיות בנושא כדי לתת שם לנושאים על ידי התבוננות במונחים הקשורים אליהם. תהליך זה יכול להיחשב כמיפוי ממספרי נושאים לשמות נושאים. עם זאת, ראוי לציין שהרשימה האישית של מונחים לנושאים יכולה להיות מכילה הדדית ולכן עשויה ליצור מיפויים מרובים. האדם-in-the-loop צריך לעצב את המיפויים על סמך ההקשר של מקרה השימוש. אחרת, הביצועים במורד הזרם עלולים להיות מושפעים.

נתחיל בהכרזה על המשתנים. עבור כל סקירה, יכולים להיות מספר נושאים. אנו סופרים את התדירות שלהם ובוחרים לכל היותר שלושה נושאים שכיחים ביותר. נושאים אלו מדווחים כנושאים המייצגים של סקירה. ראשית, נגדיר משתנה TOP_TOPICS להחזיק את המספר המרבי של נושאים מייצגים. שנית, אנו מגדירים ומגדירים ערכים ל- language_code משתנה לתמיכה בפרמטר השפה הנדרש של Amazon Comprehend. לבסוף, אנחנו יוצרים topicMaps, שהוא מילון שממפה מספרי נושאים לשמות נושאים.

# boto3 session to access service
session = boto3.Session()
comprehend = boto3.client(  'comprehend',
                            region_name=session.region_name)

# S3 bucket
BUCKET = 'clothing-shoe-jewel-tm-blog'

# Local copy of doc-topic file
DOC_TOPIC_FILE = os.path.join('comprehend-out', 'doc-topics.csv')

# Final dataframe where we will join Comprehend outputs later
S3_FEEDBACK_TOPICS = 's3://' + BUCKET + '/out/' + 'FinalDataframe.csv'

# Final output
S3_FINAL_OUTPUT = 's3://' + BUCKET + '/out/' + 'reviewTopicsSentiments.csv'

# Top 3 topics per product will be aggregated
TOP_TOPICS = 3

# Working on English language only. 
language_code = 'en'

# Topic names for 5 topics created by human-in-the-loop or SME feed
topicMaps = {
    0: 'Product comfortability',
    1: 'Product Quality and Price',
    2: 'Product Size',
    3: 'Product Color',
    4: 'Product Return',
}

לאחר מכן, אנו משתמשים בקובץ topic-terms.csv שנוצר על ידי Amazon Comprehend כדי לחבר את המונחים הייחודיים הקשורים לכל נושא. לאחר מכן, על ידי יישום מילון המיפוי על שיוך נושא-מונח זה, אנו מחברים את המונחים הייחודיים לשמות הנושאים.

# Loading documents and topics assigned to each of them by Comprehend
docTopics = pd.read_csv(DOC_TOPIC_FILE)
docTopics.head()

# Creating a field with doc number. 
# This doc number is the line number of the input file to Comprehend.
docTopics['doc'] = docTopics['docname'].str.split(':').str[1]
docTopics['doc'] = docTopics['doc'].astype(int)
docTopics.head()

# Load topics and associated terms
topicTerms = pd.read_csv(DOC_TOPIC_FILE)

# Consolidate terms for each topic
aggregatedTerms = topicTerms.groupby('topic')['term'].aggregate(lambda term: term.unique().tolist()).reset_index()

# Sneak peek
aggregatedTerms.head(10)

מיפוי זה משפר את הקריאה ואת יכולת ההסבר של הנושאים שנוצרו על ידי Amazon Comprehend, כפי שאנו יכולים לראות ב-DataFrame הבא.

יתר על כן, אנו מצטרפים את מספר הנושא, המונחים והשמות לנתוני הקלט הראשוניים, כפי שמוצג בשלבים הבאים.

זה מחזיר מונחי נושא ושמות התואמים לכל ביקורת. מספרי הנושא והמונחים מצטרפים עם כל סקירה ולאחר מכן מצטרפים בחזרה ל-DataFrame המקורי ששמרנו במחברת הראשונה.

# Load final dataframe where Comprehend results will be merged to 
feedbackTopics = pd.read_csv(S3_FEEDBACK_TOPICS)

# Joining topic numbers to main data
# The index of feedbackTopics is referring to doc field of docTopics dataframe
feedbackTopics = pd.merge(feedbackTopics, 
                          docTopics, 
                          left_index=True, 
                          right_on='doc', 
                          how='left')

# Reviews will now have topic numbers, associated terms and topics names
feedbackTopics = feedbackTopics.merge(aggregatedTerms, 
                                      on='topic', 
                                      how='left')
feedbackTopics.head()

אנו מייצרים סנטימנט עבור טקסט הביקורת באמצעות detect_sentiment. הוא בודק טקסט ומחזיר הסקה של הסנטימנט הרווח (פוזיטיב, ניטרלי, מעורב או שלילי).

def detect_sentiment(text, language_code):
    """Detects sentiment for a given text and language
    """
    comprehend_json_out = comprehend.detect_sentiment(Text=text, LanguageCode=language_code)
    return comprehend_json_out

# Comprehend output for sentiment in raw json 
feedbackTopics['comprehend_sentiment_json_out'] = feedbackTopics['reviewText'].apply(lambda x: detect_sentiment(x, language_code))

# Extracting the exact sentiment from raw Comprehend Json
feedbackTopics['sentiment'] = feedbackTopics['comprehend_sentiment_json_out'].apply(lambda x: x['Sentiment'])

# Sneak peek
feedbackTopics.head(2)

שני הנושאים והרגשות קשורים בקשר הדוק עם ביקורות. מכיוון שאנו נצבור נושאים וסנטימנטים ברמת המוצר, עלינו ליצור מפתח מורכב על ידי שילוב הנושאים והרגשות שנוצרו על ידי Amazon Comprehend.

# Creating a composite key of topic name and sentiment.
# This is because we are counting frequency of this combination.
feedbackTopics['TopicSentiment'] = feedbackTopics['TopicNames'] + '_' + feedbackTopics['sentiment']

לאחר מכן, אנו מצטברים ברמת המוצר וסופרים את המפתחות המרוכבים עבור כל מוצר.

שלב אחרון זה עוזר לנו להבין טוב יותר את הפירוט של הביקורות לכל מוצר ולסווג אותם לפי נושא בצורה מצטברת. לדוגמה, אנו יכולים לשקול את הערכים המוצגים עבור topicDF DataFrame. עבור המוצר הראשון, מכל הביקורות עליו, בסך הכל, הלקוחות חוו חוויה חיובית לגבי החזרת המוצר, הגודל והנוחות. עבור המוצר השני, ללקוחות הייתה בעיקר חוויה מעורבת לחיובית בהחזרת המוצר וחוויה חיובית על גודל המוצר.

# Create product id group
asinWiseDF = feedbackTopics.groupby('asin')

# Each product now has a list of topics and sentiment combo (topics can appear multiple times)
topicDF = asinWiseDF['TopicSentiment'].apply(lambda x:list(x)).reset_index()

# Count appreances of topics-sentiment combo for product
topicDF['TopTopics'] = topicDF['TopicSentiment'].apply(Counter)

# Sorting topics-sentiment combo based on their appearance
topicDF['TopTopics'] = topicDF['TopTopics'].apply(lambda x: sorted(x, key=x.get, reverse=True))

# Select Top k topics-sentiment combo for each product/review
topicDF['TopTopics'] = topicDF['TopTopics'].apply(lambda x: x[:TOP_TOPICS])

# Sneak peek
topicDF.head()

נושאים מובילים לכל מוצר

ה-DataFrame הסופי שלנו מורכב ממידע הנושא הזה וממידע סנטימנטים שצורפו בחזרה ל-DataFrame הסופי בשם feedbackTopics ששמרנו באמזון S3 במחברת הראשונה שלנו.

# Adding the topic-sentiment combo back to product metadata
finalDF = S3_FEEDBACK_TOPICS.merge(topicDF, on='asin', how='left')

# Only selecting a subset of fields
finalDF = finalDF[['asin', 'TopTopics', 'category', 'title']]

# Saving the final output locally
finalDF.to_csv(S3_FINAL_OUTPUT, index=False)

השתמש ב- Amazon QuickSight כדי להמחיש את הנתונים

אתה יכול להשתמש ב-QuickSight כדי להמחיש את הנתונים ולהפיק דוחות. QuickSight הוא שירות בינה עסקית (BI) שבו אתה יכול להשתמש כדי לצרוך נתונים ממקורות רבים ושונים ולבנות לוחות מחוונים חכמים. בדוגמה זו, אנו יוצרים ניתוח QuickSight באמצעות מערך הנתונים הסופי שיצרנו, כפי שמוצג בהדמיות הדוגמה הבאות.

ויזואליזציה של QuickSight

למידע נוסף על Amazon QuickSight, עיין ב תחילת העבודה עם Amazon Quicksight.

ניקוי

בסופו של דבר, עלינו לכבות את מופע המחברת בו השתמשנו בניסוי זה מ-AWS Console.

סיכום

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

אלו הן רק כמה דוגמאות, אבל אתה יכול לחשוב על עוד הרבה בעיות עסקיות שאתה מתמודד איתן בארגון שלך על בסיס יומי, וכיצד אתה יכול להשתמש במודלים של נושאים עם טכניקות ML אחרות כדי לפתור אותן.


על הכותבים

Gurpreet Cheemaגורפריט הוא מדען נתונים עם שירותים מקצועיים של AWS הממוקם מקנדה. היא נלהבת לעזור ללקוחות לחדש עם טכנולוגיות למידת מכונה ובינה מלאכותית כדי להפיק ערך עסקי ותובנות מהנתונים. בזמנה הפנוי היא נהנית לטייל בחוץ ולקרוא ספרים

רושדי שמסרושדי שמס הוא מדען נתונים עם שירותים מקצועיים של AWS, קנדה. הוא בונה מוצרי למידת מכונה עבור לקוחות AWS. הוא אוהב לקרוא ולכתוב ספרי מדע בדיוני.

וריק טלוקדרוריק טלוקדר הוא אדריכל בכיר בצוות Amazon Comprehend Service. הוא עובד עם לקוחות AWS כדי לעזור להם לאמץ למידת מכונה בקנה מידה גדול. מחוץ לעבודה, הוא נהנה לקרוא ולצלם.

בול זמן:

עוד מ למידת מכונות AWS