Krijg beter inzicht uit beoordelingen met Amazon Comprehend PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

Krijg beter inzicht uit beoordelingen met Amazon Comprehend

“85% van de kopers vertrouwt online reviews net zo goed als een persoonlijke aanbeveling” – Gartner

Consumenten komen steeds meer in contact met bedrijven via digitale oppervlakken en meerdere contactpunten. Statistieken tonen aan dat de meerderheid van de shoppers beoordelingen gebruikt om te bepalen welke producten ze moeten kopen en welke diensten ze moeten gebruiken. Vanaf Spiegel Onderzoekscentrum, is de aankoopkans voor een product met vijf beoordelingen 270% groter dan de aankoopkans van een product zonder beoordelingen. Recensies hebben de kracht om consumentenbeslissingen te beïnvloeden en de merkwaarde te versterken.

In dit bericht gebruiken we Amazon begrijpt het om zinvolle informatie uit productrecensies te halen, deze te analyseren om te begrijpen hoe gebruikers van verschillende demografische categorieën op producten reageren en geaggregeerde informatie te ontdekken over de affiniteit van gebruikers met een product. Amazon Comprehend is een volledig beheerde en continu getrainde NLP-service (Natural Language Processing) die inzicht kan krijgen in de inhoud van een document of tekst.

Overzicht oplossingen

Tegenwoordig kunnen recensies door klanten op verschillende manieren worden gegeven, zoals sterbeoordelingen, gratis tekst of natuurlijke taal, of delen op sociale media. Beoordelingen in vrije tekst of natuurlijke taal helpen vertrouwen op te bouwen, omdat het een onafhankelijke mening van consumenten is. Het wordt vaak gebruikt door productteams om via beoordelingskanalen met klanten te communiceren. Het is een bewezen feit dat wanneer klanten zich gehoord voelen, hun gevoel over het merk verbetert. Hoewel het relatief eenvoudiger is om sterbeoordelingen of gedeelde sociale media te analyseren, vormen natuurlijke taal of gratis tekstrecensies meerdere uitdagingen, zoals het identificeren van trefwoorden of woordgroepen, onderwerpen of concepten, en sentimenten of sentimenten op entiteitsniveau. De uitdaging is voornamelijk te wijten aan de variabiliteit van de lengte in geschreven tekst en de aannemelijke aanwezigheid van zowel signalen als ruis. Bovendien kan de informatie ofwel heel duidelijk en expliciet zijn (bijvoorbeeld met trefwoorden en sleutelzinnen) of onduidelijk en impliciet (abstracte onderwerpen en concepten). Nog uitdagender is het begrijpen van verschillende soorten sentimenten en deze te relateren aan geschikte producten en diensten. Desalniettemin is het van groot belang om deze informatie en tekstuele signalen te begrijpen om een ​​probleemloze klantervaring te bieden.

In dit bericht gebruiken we een openbaar beschikbare NLP – snel.ai dataset om de productrecensies van klanten te analyseren. We beginnen met het gebruik van een unsupervised machine learning (ML) techniek die bekend staat als topic modeling. Dit is een populaire techniek zonder toezicht die abstracte onderwerpen ontdekt die kunnen voorkomen in een verzameling tekstrecensies. Topic-modellering is een clusterprobleem dat niet wordt gecontroleerd, wat betekent dat de modellen geen kennis hebben van mogelijke doelvariabelen (zoals onderwerpen in een recensie). De onderwerpen zijn weergegeven als clusters. Vaak wordt het aantal clusters in een corpus van documenten bepaald met de hulp van domeinexperts of met behulp van een standaard statistische analyse. De modeluitvoer heeft over het algemeen drie componenten: genummerde clusters (onderwerp 0, onderwerp 1, enzovoort), trefwoorden die aan elk cluster zijn gekoppeld en representatieve clusters voor elk document (of recensie in ons geval). Door hun inherente aard genereren onderwerpmodellen geen door mensen leesbare labels voor de clusters of onderwerpen, wat een veel voorkomende misvatting is. Iets om op te merken over onderwerpmodellering in het algemeen is dat het een gemengd lidmaatschapsmodel is - elk document in het model kan op elk onderwerp lijken. Het onderwerpmodel leert in een iteratief Bayesiaans proces om de waarschijnlijkheid te bepalen dat elk document wordt geassocieerd met een bepaald thema of onderwerp. De modeloutput is afhankelijk van het optimaal selecteren van het aantal onderwerpen. Een klein aantal onderwerpen kan ertoe leiden dat de onderwerpen te breed zijn, en een groter aantal onderwerpen kan resulteren in overbodige of vergelijkbare onderwerpen. Er zijn een aantal manieren om onderwerpmodellen te evalueren:

  • Menselijk oordeel - Op waarneming gebaseerd, op interpretatie gebaseerd
  • Kwantitatieve statistieken - Perplexiteit, coherentieberekeningen
  • Gemengde benadering - Een combinatie van op oordeel gebaseerde en kwantitatieve benaderingen

Perplexiteit wordt berekend door een dataset in twee delen te splitsen: een trainingsset en een testset. Waarschijnlijkheid wordt meestal berekend als een logaritme, dus deze statistiek wordt soms de uitgehouden log-waarschijnlijkheid genoemd. Perplexiteit is een voorspellende maatstaf. Het beoordeelt het vermogen van een onderwerpmodel om een ​​testset te voorspellen nadat het is getraind op een trainingsset. Een van de tekortkomingen van verbijstering is dat het geen context vastlegt, wat inhoudt dat het de relatie tussen woorden in een onderwerp of onderwerpen in een document niet vastlegt. Het idee van een semantische context is echter belangrijk voor het menselijk begrip. Maatregelen zoals de voorwaardelijke waarschijnlijkheid van het gelijktijdig voorkomen van woorden in een onderwerp kunnen nuttig zijn. Deze benaderingen worden gezamenlijk aangeduid als coherentie. Voor deze post richten we ons op de menselijke beoordelingsbenadering (op observatie gebaseerd), namelijk het observeren van de top n woorden in een onderwerp.

De oplossing bestaat uit de volgende stappen op hoog niveau:

  1. Stel een Amazon Sage Maker notebook exemplaar.
  2. Maak een notitieboek.
  3. Uitvoeren van verkennende data-analyses.
  4. Voer uw Amazon Comprehend-taak voor onderwerpmodellering uit.
  5. Genereer onderwerpen en begrijp sentiment.
  6. Te gebruiken Amazon QuickSight om gegevens te visualiseren en rapporten te genereren.

U kunt deze oplossing in elke AWS-regio gebruiken, maar u moet ervoor zorgen dat de Amazon Comprehend-API's en SageMaker zich in dezelfde regio bevinden. Voor dit bericht gebruiken we de regio US East (N. Virginia).

Uw SageMaker-notebookinstantie instellen

U kunt communiceren met Amazon Comprehend via de AWS-beheerconsole, AWS-opdrachtregelinterface (AWS CLI), of Amazon Comprehend API. Voor meer informatie, zie: Aan de slag met Amazon Comprehend. We gebruiken een SageMaker-notebook en Python (Boto3)-code in dit bericht om te communiceren met de Amazon Comprehend-API's.

  1. Kies op de Amazon SageMaker-console onder Notebook in het navigatievenster:
    Notebook-instanties.
  2. Kies Notebook-instantie maken.Notebook-instanties
  3. Geef de naam van een notebookinstantie op en stel het instantietype in op ml.r5.2xlarge.
  4. Laat de rest van de standaardinstellingen.
  5. Maak een AWS identiteits- en toegangsbeheer (IAM) rol met AmazonSageMakerFullAccess en toegang tot alle noodzakelijke Eenvoudige opslagservice van Amazon (Amazon S3) buckets en Amazon Comprehend API's.
  6. Kies Notebook-instantie maken.
    Na een paar minuten is uw notebookexemplaar gereed.
  7. Om toegang te krijgen tot Amazon Comprehend vanuit de notebook-instantie, moet u de ComprehendFullAccess beleid toe aan uw IAM-rol.

Raadpleeg voor een beveiligingsoverzicht van Amazon Comprehend: Beveiliging in Amazon Comprehend.

Nadat u het notebook-exemplaar dat u hebt ingericht hebt geopend, kiest u op de Jupyter-console Nieuw en vervolgens Python 3 (Data Science). U kunt ook toegang krijgen tot het voorbeeldcodebestand in de GitHub repo. U kunt het bestand uploaden naar de notebook-instantie om het rechtstreeks uit te voeren of het te klonen.

De GitHub-repo bevat drie notebooks:

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

Verkennende data-analyse uitvoeren

We gebruiken het eerste notitieboekje (data_processing.ipynb) om de gegevens te verkennen en te verwerken. We beginnen door simpelweg de gegevens van een S3-bucket in een DataFrame te laden.

# 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)

In de volgende sectie voeren we verkennende gegevensanalyse (EDA) uit om de gegevens te begrijpen. We beginnen met het verkennen van de vorm van de data en metadata. Voor authenticiteit gebruiken we alleen geverifieerde beoordelingen.

# 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())

We onderzoeken het aantal van elke categorie verder en kijken of er dubbele gegevens aanwezig zijn.

# 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()])

Als we tevreden zijn met de resultaten, gaan we naar de volgende stap van het voorbewerken van de gegevens. Amazon Comprehend raadt aan ten minste 1,000 documenten in elke taak voor het modelleren van onderwerpen aan te leveren, waarbij elk document ten minste drie zinnen lang is. Documenten moeten in UTF-8-geformatteerde tekstbestanden zijn. In de volgende stap zorgen we ervoor dat de gegevens de aanbevolen UTF-8-indeling hebben en dat elke invoer niet groter is dan 5,000 bytes.

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)

We slaan de gegevens vervolgens op Amazon S3 op en bewaren ook een lokale kopie in de notebook-instantie.

# 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}

Hiermee is onze gegevensverwerkingsfase voltooid.

Een onderwerpmodelleringstaak voor Amazon Comprehend uitvoeren

Vervolgens gaan we naar de volgende fase, waar we de voorverwerkte gegevens gebruiken om een ​​onderwerpmodelleringstaak uit te voeren met Amazon Comprehend. In dit stadium kunt u ofwel het tweede notitieblok gebruiken (model_training.ipynb) of gebruik de Amazon Comprehend-console om de onderwerpmodelleringstaak uit te voeren. Voor instructies over het gebruik van de console, zie: Analysetaken uitvoeren met de console. Als u de notebook gebruikt, kunt u beginnen met het maken van een Amazon Comprehend-client met Boto3, zoals in het volgende voorbeeld wordt getoond.

# 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)

U kunt uw documenten op twee manieren indienen voor onderwerpmodellering: één document per bestand of één document per regel.

We beginnen met 5 onderwerpen (k-getal), en gebruiken één document per regel. Er is geen enkele beste manier om standaard k of het aantal onderwerpen te selecteren. U kunt verschillende waarden van k uitproberen en degene kiezen met de grootste kans.

# 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"

Voor onze taak voor het modelleren van onderwerpen in Amazon Comprehend moet je slagen voor een InputDataConfig woordenboekobject met S3, InputFormat en DocumentReadAction als vereiste parameters. Evenzo moet u de OutputDataConfig object met S3 en DataAccessRoleArn als vereiste parameters. Raadpleeg voor meer informatie de Boto3-documentatie voor: 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,
}

U kunt vervolgens een asynchrone onderwerpdetectietaak starten door het aantal onderwerpen, het invoerconfiguratieobject, het uitvoerconfiguratieobject en een IAM-rol door te geven, zoals in het volgende voorbeeld wordt weer gegeven.

# 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)

U kunt de huidige status van de taak volgen door te bellen naar de DescribeTopicDetectionJob operatie. De status van de taak kan een van de volgende zijn:

  • SUBMITTED – De opdracht is ontvangen en staat in de wachtrij voor verwerking
  • IN_PROGRESS - Amazon Comprehend is bezig met het verwerken van de taak
  • VOLTOOID – De taak is met succes voltooid en de uitvoer is beschikbaar
  • MISLUKT - De taak is niet voltooid
# 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)

Wanneer de taak met succes is voltooid, retourneert het een gecomprimeerd archief met twee bestanden: topic-terms.csv en doc-topics.csv. Het eerste uitvoerbestand, topic-terms.csv, is een lijst met onderwerpen in de collectie. Voor elk onderwerp bevat de lijst standaard de belangrijkste termen per onderwerp op basis van hun gewicht. Het tweede bestand, doc-topics.csv, geeft een overzicht van de documenten die aan een onderwerp zijn gekoppeld en het deel van het document dat met het onderwerp te maken heeft. Omdat we hebben gespecificeerd: ONE_DOC_PER_LINE eerder in de input_doc_format variabele, wordt het document geïdentificeerd door de bestandsnaam en het 0-geïndexeerde regelnummer in het bestand. Voor meer informatie over onderwerpmodellering, zie: Modellering van onderwerpen.
De outputs van Amazon Comprehend worden lokaal gekopieerd voor onze volgende stappen.

# 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()

Omdat het aantal onderwerpen veel kleiner is dan de woordenschat die bij de documentenverzameling hoort, kan de representatie van de onderwerpruimte ook worden gezien als een proces van dimensionaliteitsreductie. U kunt deze weergave van documenten in de onderwerpruimte gebruiken om clustering uit te voeren. Aan de andere kant kunt u de frequentie van woorden in elk cluster analyseren om het onderwerp te bepalen dat bij elk cluster hoort. Voor dit bericht voeren we geen andere technieken uit, zoals clustering.

We gebruiken het derde notitieboek (topic_mapping_sentiment_generation.ipynb) om te achterhalen hoe gebruikers van verschillende demografische categorieën op producten reageren, en ook om geaggregeerde informatie over gebruikersaffiniteit met een bepaald product te analyseren.

We kunnen de uitvoer van het vorige notitieblok combineren om onderwerpen en bijbehorende termen voor elk onderwerp te krijgen. De onderwerpen zijn echter genummerd en kunnen niet worden uitgelegd. Daarom gebruiken we liever een mens-in-the-loop met voldoende domeinkennis en materiedeskundigheid om de onderwerpen te benoemen door te kijken naar de bijbehorende termen. Dit proces kan worden beschouwd als een mapping van onderwerpnummers naar onderwerpnamen. Het is echter opmerkelijk dat de afzonderlijke lijst met termen voor de onderwerpen wederzijds inclusief kan zijn en daarom meerdere toewijzingen kan creëren. De mens-in-de-loop moet de mappings formaliseren op basis van de context van de use case. Anders kunnen de downstreamprestaties worden beïnvloed.

We beginnen met het declareren van de variabelen. Voor elke recensie kunnen er meerdere onderwerpen zijn. We tellen hun frequentie en selecteren maximaal drie meest voorkomende onderwerpen. Deze onderwerpen worden gerapporteerd als de representatieve onderwerpen van een review. Eerst definiëren we een variabele TOP_TOPICS om het maximale aantal representatieve onderwerpen te bevatten. Ten tweede definiëren en stellen we waarden in op de language_code variabele om de vereiste taalparameter van Amazon Comprehend te ondersteunen. Ten slotte creëren we topicMaps, een woordenboek dat onderwerpnummers toewijst aan onderwerpnamen.

# 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',
}

Vervolgens gebruiken we het bestand topic-terms.csv dat is gegenereerd door Amazon Comprehend om de unieke termen te verbinden die aan elk onderwerp zijn gekoppeld. Door vervolgens het toewijzingswoordenboek toe te passen op deze onderwerp-term-associatie, verbinden we de unieke termen met de onderwerpnamen.

# 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)

Deze mapping verbetert de leesbaarheid en uitlegbaarheid van de onderwerpen die worden gegenereerd door Amazon Comprehend, zoals we kunnen zien in het volgende DataFrame.

Verder voegen we het onderwerpnummer, termen en namen toe aan de initiële invoergegevens, zoals weergegeven in de volgende stappen.

Hiermee worden onderwerptermen en namen geretourneerd die overeenkomen met elke recensie. De onderwerpnummers en voorwaarden worden bij elke recensie samengevoegd en vervolgens weer samengevoegd tot het originele DataFrame dat we in de eerste notebook hebben opgeslagen.

# 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()

We genereren sentiment voor de recensietekst met behulp van detect_sentiment. Het inspecteert tekst en retourneert een gevolgtrekking van het heersende sentiment (POSITIEF, NEUTRAAL, GEMENGD of NEGATIEF).

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)

Zowel onderwerpen als sentimenten zijn nauw verbonden met recensies. Omdat we onderwerpen en sentimenten op productniveau gaan aggregeren, moeten we een samengestelde sleutel maken door de onderwerpen en sentimenten te combineren die door Amazon Comprehend worden gegenereerd.

# 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']

Daarna aggregeren we op productniveau en tellen de samengestelde sleutels voor elk product.

Deze laatste stap helpt ons de granulariteit van de beoordelingen per product beter te begrijpen en deze op een geaggregeerde manier per onderwerp te categoriseren. We kunnen bijvoorbeeld de waarden bekijken die worden weergegeven voor topicDF DataFrame. Voor het eerste product, van alle beoordelingen ervoor, hadden de klanten over het algemeen een positieve ervaring met productretour, maat en comfort. Voor het tweede product hadden de klanten meestal een gemengde tot positieve ervaring met productretour en een positieve ervaring met productgrootte.

# 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()

Toponderwerpen per product

Ons definitieve DataFrame bestaat uit deze onderwerpinformatie en sentimentinformatie die is samengevoegd met het uiteindelijke DataFrame genaamd feedbackTopics die we hebben opgeslagen op Amazon S3 in onze eerste notebook.

# 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)

Gebruik Amazon QuickSight om de gegevens te visualiseren

U kunt QuickSight gebruiken om de gegevens te visualiseren en rapporten te genereren. QuickSight is een business intelligence (BI)-service die u kunt gebruiken om gegevens uit veel verschillende bronnen te gebruiken en intelligente dashboards te bouwen. In dit voorbeeld genereren we een QuickSight-analyse met behulp van de uiteindelijke dataset die we hebben geproduceerd, zoals weergegeven in de volgende voorbeeldvisualisaties.

QuickSight-visualisatie

Raadpleeg voor meer informatie over Amazon QuickSight: Aan de slag met Amazon Quicksight.

Opruimen

Aan het einde moeten we de notebookinstantie die we in dit experiment hebben gebruikt, afsluiten vanuit AWS Console.

Conclusie

In dit bericht hebben we laten zien hoe je Amazon Comprehend kunt gebruiken om productrecensies te analyseren en de belangrijkste onderwerpen te vinden met behulp van onderwerpmodellering als techniek. Met onderwerpmodellering kunt u meerdere onderwerpen bekijken en deze op grote schaal ordenen, begrijpen en samenvatten. U kunt snel en eenvoudig verborgen patronen ontdekken die in de gegevens aanwezig zijn en dat inzicht vervolgens gebruiken om gegevensgestuurde beslissingen te nemen. U kunt onderwerpmodellering gebruiken om tal van zakelijke problemen op te lossen, zoals het automatisch taggen van klantenondersteuningstickets, het routeren van gesprekken naar de juiste teams op basis van onderwerp, het detecteren van de urgentie van ondersteuningstickets, het verkrijgen van betere inzichten uit gesprekken, het creëren van datagestuurde plannen, het creëren van problemen -gerichte inhoud, het verbeteren van de verkoopstrategie en het identificeren van problemen en fricties van klanten.

Dit zijn slechts enkele voorbeelden, maar u kunt nog veel meer zakelijke problemen bedenken waarmee u in uw organisatie dagelijks wordt geconfronteerd, en hoe u onderwerpmodellering met andere ML-technieken kunt gebruiken om deze op te lossen.


Over de auteurs

Gurpreet CheemaGurpreet is een datawetenschapper bij AWS Professional Services, gevestigd in Canada. Ze heeft een passie voor het helpen van klanten bij het innoveren met Machine Learning en Artificial Intelligence-technologieën om zakelijke waarde en inzichten uit data te halen. In haar vrije tijd wandelt ze graag buiten en leest ze graag boeken.i

Rushdi ShamsRushdi Shams is een datawetenschapper bij AWS Professional Services, Canada. Hij bouwt machine learning-producten voor AWS-klanten. Hij houdt van lezen en schrijven van sciencefiction.

Wrick TalukdarWrick Talukdar is een Senior Architect bij het Amazon Comprehend Service-team. Hij werkt samen met AWS-klanten om hen te helpen machine learning op grote schaal toe te passen. Naast zijn werk houdt hij van lezen en fotograferen.

Tijdstempel:

Meer van AWS-machine learning