Uzyskaj lepszy wgląd w recenzje, korzystając z analizy danych Amazon Comprehend PlatoBlockchain. Wyszukiwanie pionowe. AI.

Uzyskaj lepszy wgląd w recenzje za pomocą Amazon Comprehend

„85% kupujących ufa recenzjom online tak samo jak osobistej rekomendacji” – Gartner

Konsumenci coraz częściej nawiązują kontakt z firmami za pośrednictwem cyfrowych powierzchni i wielu punktów styku. Statystyki pokazują, że większość kupujących korzysta z recenzji, aby określić, jakie produkty kupić i z jakich usług skorzystać. Jak na Centrum Badawcze Spiegla, prawdopodobieństwo zakupu produktu z pięcioma opiniami jest o 270% większe niż prawdopodobieństwo zakupu produktu bez recenzji. Recenzje mają moc wpływania na decyzje konsumentów i wzmacniania wartości marki.

W tym poście używamy Amazon Comprehend aby wyodrębnić znaczące informacje z recenzji produktów, przeanalizować je, aby zrozumieć, jak użytkownicy o różnych grupach demograficznych reagują na produkty i odkryć zagregowane informacje na temat powinowactwa użytkowników do produktu. Amazon Comprehend to w pełni zarządzana i stale szkolona usługa przetwarzania języka naturalnego (NLP), która może uzyskać wgląd w treść dokumentu lub tekstu.

Omówienie rozwiązania

Obecnie opinie mogą być udostępniane przez klientów na różne sposoby, takie jak oceny w postaci gwiazdek, dowolny tekst lub język naturalny lub udostępnianie w mediach społecznościowych. Dowolne recenzje tekstowe lub w języku naturalnym pomagają budować zaufanie, ponieważ są to niezależna opinia konsumentów. Jest często używany przez zespoły produktowe do interakcji z klientami za pośrednictwem kanałów recenzji. Udowodniono, że kiedy klienci czują się wysłuchani, poprawiają się ich wyczucie marki. Podczas gdy analizowanie ocen w postaci gwiazdek lub udostępnień w mediach społecznościowych jest stosunkowo łatwiejsze, recenzje w języku naturalnym lub swobodnym tekście stanowią wiele wyzwań, takich jak identyfikacja słów kluczowych lub wyrażeń, tematów lub koncepcji oraz nastrojów lub nastrojów na poziomie podmiotu. Wyzwanie wynika głównie ze zmienności długości tekstu pisanego oraz prawdopodobnej obecności zarówno sygnałów, jak i szumu. Ponadto informacje mogą być bardzo jasne i jednoznaczne (na przykład ze słowami kluczowymi i frazami kluczowymi) lub niejasne i niejawne (abstrakcyjne tematy i koncepcje). Jeszcze większym wyzwaniem jest zrozumienie różnych typów nastrojów i powiązanie ich z odpowiednimi produktami i usługami. Niemniej jednak bardzo ważne jest, aby zrozumieć te informacje i sygnały tekstowe, aby zapewnić bezproblemową obsługę klienta.

W tym poście używamy publicznie dostępnego NLP – szybki.ai zestaw danych do analizy recenzji produktów dostarczonych przez klientów. Zaczynamy od zastosowania techniki nienadzorowanego uczenia maszynowego (ML) znanej jako modelowanie tematów. Jest to popularna nienadzorowana technika, która wykrywa abstrakcyjne tematy, które mogą wystąpić w zbiorze recenzji tekstów. Modelowanie tematyczne to problem grupowania, który nie jest nadzorowany, co oznacza, że ​​modele nie mają wiedzy na temat możliwych zmiennych docelowych (takich jak tematy w przeglądzie). Tematy są reprezentowane jako klastry. Często o liczbie klastrów w korpusie dokumentów decydują eksperci dziedzinowi lub przy użyciu standardowej analizy statystycznej. Wyniki modelu generalnie składają się z trzech komponentów: ponumerowanych klastrów (temat 0, temat 1 itd.), słów kluczowych powiązanych z każdym klastrem oraz klastrów reprezentatywnych dla każdego dokumentu (lub przeglądu w naszym przypadku). Ze względu na swoją nieodłączną naturę modele tematyczne nie generują czytelnych dla człowieka etykiet dla klastrów lub tematów, co jest powszechnym nieporozumieniem. Należy zwrócić uwagę na ogólne modelowanie tematów, że jest to mieszany model członkostwa — każdy dokument w modelu może być podobny do każdego tematu. Model tematyczny uczy się w iteracyjnym procesie bayesowskim, aby określić prawdopodobieństwo, że każdy dokument jest powiązany z danym tematem lub tematem. Wynik modelu zależy od optymalnego doboru liczby tematów. Niewielka liczba tematów może spowodować, że tematy będą zbyt obszerne, a większa ich liczba – zbędnych tematów lub tematów o podobnym charakterze. Istnieje kilka sposobów oceny modeli tematycznych:

  • Osąd ludzki – oparty na obserwacji, oparty na interpretacji
  • Mierniki ilościowe – Zakłopotanie, obliczenia koherencji
  • Podejście mieszane — połączenie podejścia opartego na osądzie i podejścia ilościowego

Zakłopotanie oblicza się, dzieląc zbiór danych na dwie części — zbiór uczący i zbiór testowy. Prawdopodobieństwo jest zwykle obliczane jako logarytm, więc ta metryka jest czasami nazywana prawdopodobieństwem logarytmowania. Zakłopotanie to metryka predykcyjna. Ocenia zdolność modelu tematycznego do przewidywania zestawu testowego po przeszkoleniu w zestawie szkoleniowym. Jedną z wad zakłopotania jest to, że nie wychwytuje kontekstu, co oznacza, że ​​nie wychwytuje relacji między słowami w temacie lub tematami w dokumencie. Jednak idea kontekstu semantycznego jest ważna dla ludzkiego zrozumienia. Pomocne mogą być miary, takie jak warunkowe prawdopodobieństwo współwystępowania słów w temacie. Podejścia te są zbiorczo określane jako koherencja. W tym poście skupiamy się na podejściu osądu ludzkiego (opartym na obserwacji), czyli obserwowaniu n najważniejszych słów w temacie.

Rozwiązanie składa się z następujących etapów wysokiego poziomu:

  1. Skonfiguruj Amazon Sage Maker instancja notatnika.
  2. Utwórz notatnik.
  3. Wykonaj eksploracyjną analizę danych.
  4. Uruchom zadanie modelowania tematów Amazon Comprehend.
  5. Generuj tematy i rozumiej sentyment.
  6. Zastosowanie Amazon QuickSight do wizualizacji danych i generowania raportów.

Możesz użyć tego rozwiązania w dowolnym regionie AWS, ale musisz upewnić się, że interfejsy API Amazon Comprehend i SageMaker znajdują się w tym samym regionie. W tym poście używamy Regionu US East (N. Virginia).

Skonfiguruj instancję notatnika SageMaker

Możesz wchodzić w interakcję z Amazon Comprehend za pośrednictwem Konsola zarządzania AWS, Interfejs wiersza poleceń AWS (AWS CLI)lub Amazon Zrozum API. Aby uzyskać więcej informacji, zobacz Rozpoczęcie pracy z Amazonem Rozumiem. W tym poście używamy notatnika SageMaker i kodu Pythona (Boto3) do interakcji z interfejsami API Amazon Comprehend.

  1. W konsoli Amazon SageMaker, w obszarze Notatnik w okienku nawigacji, wybierz
    Instancje notatek.
  2. Wybierz Utwórz instancję notatek.Instancje notesu
  3. Określ nazwę wystąpienia notatnika i ustaw typ wystąpienia jako ml.r5.2xlarge.
  4. Pozostaw resztę ustawień domyślnych.
  5. Tworzenie Zarządzanie tożsamością i dostępem AWS (IAM) rola z AmazonSageMakerFullAccess i dostęp do wszelkich niezbędnych Usługa Amazon Simple Storage (Amazon S3) zasobniki i interfejsy API Amazon Comprehend.
  6. Wybierz Utwórz instancję notatek.
    Po kilku minutach instancja notatnika jest gotowa.
  7. Aby uzyskać dostęp do Amazon Comprehend z instancji notebooka, musisz dołączyć ComprehendFullAccess polityki do Twojej roli uprawnień.

Aby zapoznać się z przeglądem bezpieczeństwa Amazon Comprehend, zobacz Bezpieczeństwo w Amazon Comprehend.

Po otwarciu udostępnionej instancji notesu w konsoli Jupyter wybierz opcję Nowy, a następnie Python 3 (nauka o danych). Alternatywnie możesz uzyskać dostęp do przykładowego pliku kodu w GitHub repo. Możesz przesłać plik do instancji notatnika, aby uruchomić go bezpośrednio lub sklonować.

Repozytorium GitHub zawiera trzy notatniki:

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

Wykonaj eksploracyjną analizę danych

Używamy pierwszego notatnika (data_processing.ipynb) w celu zbadania i przetwarzania danych. Zaczynamy od prostego załadowania danych z wiadra S3 do 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)

W poniższej sekcji wykonujemy eksploracyjną analizę danych (EDA), aby zrozumieć dane. Zaczynamy od zbadania kształtu danych i metadanych. Dla autentyczności używamy tylko zweryfikowanych recenzji.

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

Dalej badamy liczbę każdej kategorii i sprawdzamy, czy występują zduplikowane dane.

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

Kiedy jesteśmy zadowoleni z wyników, przechodzimy do kolejnego etapu wstępnego przetwarzania danych. Amazon Comprehend zaleca dostarczenie co najmniej 1,000 dokumentów w każdej pracy związanej z modelowaniem tematu, przy czym każdy dokument ma co najmniej trzy zdania. Dokumenty muszą być w plikach tekstowych w formacie UTF-8. W kolejnym kroku upewniamy się, że dane są w zalecanym formacie UTF-8, a każde dane wejściowe mają rozmiar nie większy niż 5,000 bajtów.

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)

Następnie zapisujemy dane w Amazon S3, a także przechowujemy lokalną kopię w instancji notebooka.

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

To kończy naszą fazę przetwarzania danych.

Uruchom zadanie modelowania tematów Amazon Comprehend

Następnie przechodzimy do następnej fazy, w której wykorzystujemy wstępnie przetworzone dane do uruchomienia zadania modelowania tematu przy użyciu Amazon Comprehend. Na tym etapie możesz skorzystać z drugiego notatnika (model_training.ipynb) lub użyj konsoli Amazon Comprehend, aby uruchomić zadanie modelowania tematu. Aby uzyskać instrukcje dotyczące korzystania z konsoli, zobacz Uruchamianie zadań analizy za pomocą konsoli. Jeśli korzystasz z notesu, możesz zacząć od utworzenia klienta Amazon Comprehend za pomocą Boto3, jak pokazano w poniższym przykładzie.

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

Możesz przesłać swoje dokumenty do modelowania tematów na dwa sposoby: jeden dokument na plik lub jeden dokument na wiersz.

Zaczynamy od 5 tematów (liczba k) i używamy jednego dokumentu na linię. Nie ma jednego najlepszego sposobu, jako standardowej praktyki, aby wybrać k lub liczbę tematów. Możesz wypróbować różne wartości k i wybrać tę, która ma największe prawdopodobieństwo.

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

Nasza praca związana z modelowaniem tematów Amazon Zrozum, wymaga zdania InputDataConfig obiekt słownika z S3, InputFormat, DocumentReadAction jako wymagane parametry. Podobnie musisz podać OutputDataConfig obiekt z S3 i DataAccessRoleArn jako wymagane parametry. Aby uzyskać więcej informacji, zapoznaj się z dokumentacją Boto3 dla 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,
}

Następnie można uruchomić zadanie asynchronicznego wykrywania tematów, przekazując liczbę tematów, obiekt konfiguracji danych wejściowych, obiekt konfiguracji danych wyjściowych i rolę uprawnień, jak pokazano w poniższym przykładzie.

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

Możesz śledzić aktualny status zadania, dzwoniąc pod numer DescribeTopicDetectionJob operacja. Status zadania może być jednym z następujących:

  • SUBMITTED – zadanie zostało odebrane i znajduje się w kolejce do przetworzenia
  • IN_PROGRESS – Amazon Comprehend przetwarza zadanie
  • ZAKOŃCZONE — zadanie zostało pomyślnie zakończone i dane wyjściowe są dostępne
  • FAILED – zadanie nie zostało ukończone
# 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)

Po pomyślnym zakończeniu zadania zwraca skompresowane archiwum zawierające dwa pliki: topic-terms.csv i doc-topics.csv. Pierwszy plik wyjściowy, topic-terms.csv, to lista tematów w kolekcji. W przypadku każdego tematu lista domyślnie zawiera najpopularniejsze terminy według tematu według ich wagi. Drugi plik, doc-topics.csv, zawiera listę dokumentów powiązanych z tematem oraz część dokumentu, która dotyczy tego tematu. Ponieważ określiliśmy ONE_DOC_PER_LINE wcześniej w input_doc_format zmienna, dokument jest identyfikowany przez nazwę pliku i numer wiersza z indeksem 0 w pliku. Aby uzyskać więcej informacji na temat modelowania tematów, zobacz Modelowanie tematyczne.
Dane wyjściowe Amazon Comprehend są kopiowane lokalnie dla naszych następnych kroków.

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

Ponieważ liczba tematów jest znacznie mniejsza niż słownictwo związane z kolekcją dokumentów, reprezentację przestrzeni tematów można również postrzegać jako proces redukcji wymiarowości. Możesz użyć tej reprezentacji dokumentów w przestrzeni tematu do przeprowadzenia grupowania. Z drugiej strony można przeanalizować częstotliwość słów w każdym klastrze, aby określić temat związany z każdym klastrem. W tym poście nie stosujemy żadnych innych technik, takich jak klastrowanie.

Używamy trzeciego notatnika (topic_mapping_sentiment_generation.ipynb), aby dowiedzieć się, jak użytkownicy z różnych grup demograficznych reagują na produkty, a także przeanalizować zagregowane informacje na temat przywiązania użytkowników do określonego produktu.

Możemy połączyć dane wyjściowe z poprzedniego notatnika, aby uzyskać tematy i powiązane terminy dla każdego tematu. Jednak tematy są ponumerowane i mogą być niewyjaśnione. Dlatego wolimy używać „człowieka w pętli” z wystarczającą wiedzą domenową i merytoryczną, aby nazwać tematy, patrząc na powiązane z nimi terminy. Ten proces można uznać za mapowanie z numerów tematów na nazwy tematów. Warto jednak zauważyć, że indywidualna lista terminów dla tematów może wzajemnie się obejmować, a zatem może tworzyć wiele mapowań. Human-in-the-loop powinien sformalizować mapowania w oparciu o kontekst przypadku użycia. W przeciwnym razie może to wpłynąć na wydajność na dalszych etapach.

Zaczynamy od zadeklarowania zmiennych. Każda recenzja może mieć wiele tematów. Liczymy ich częstotliwość i wybieramy maksymalnie trzy najczęstsze tematy. Te tematy są zgłaszane jako reprezentatywne tematy recenzji. Najpierw definiujemy zmienną TOP_TOPICS pomieścić maksymalną liczbę reprezentatywnych tematów. Po drugie, definiujemy i ustawiamy wartości na language_code zmienna obsługująca wymagany parametr języka Amazon Comprehend. Wreszcie tworzymy topicMaps, czyli słownik odwzorowujący numery tematów na nazwy tematów.

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

Następnie używamy pliku topic-terms.csv wygenerowanego przez Amazon Comprehend, aby połączyć unikalne terminy związane z każdym tematem. Następnie, stosując słownik mapowania do tego powiązania temat-termin, łączymy unikalne terminy z nazwami tematów.

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

To mapowanie poprawia czytelność i wyjaśnialność tematów generowanych przez Amazon Comprehend, jak widać w poniższym DataFrame.

Ponadto dołączamy numer tematu, terminy i nazwy do początkowych danych wejściowych, jak pokazano w poniższych krokach.

Zwraca to terminy i nazwy tematów odpowiadające każdej recenzji. Numery tematów i terminy są łączone z każdą recenzją, a następnie ponownie łączone z oryginalną ramką DataFrame, którą zapisaliśmy w pierwszym notatniku.

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

Generujemy sentyment do tekstu recenzji za pomocą detect_sentiment. Sprawdza tekst i zwraca wnioskowanie o dominującym nastroju (POZYTYWNY, NEUTRALNY, MIESZANY lub NEGATYWNY).

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)

Zarówno tematy, jak i odczucia są ściśle powiązane z recenzjami. Ponieważ będziemy agregować tematy i nastroje na poziomie produktu, musimy utworzyć klucz złożony, łącząc tematy i nastroje generowane przez 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']

Następnie agregujemy dane na poziomie produktu i liczymy klucze złożone dla każdego produktu.

Ten ostatni krok pomaga nam lepiej zrozumieć szczegółowość recenzji produktu i kategoryzować je według tematu w sposób zagregowany. Na przykład możemy rozważyć wartości pokazane dla topicDF DataFrame. W przypadku pierwszego produktu, ze wszystkich recenzji, klienci mieli ogólnie pozytywne wrażenia dotyczące zwrotu produktu, rozmiaru i komfortu. W przypadku drugiego produktu klienci mieli głównie mieszane lub pozytywne doświadczenia dotyczące zwrotu produktu oraz pozytywne doświadczenia dotyczące rozmiaru produktu.

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

Najważniejsze tematy na produkt

Nasza ostateczna ramka DataFrame składa się z tych informacji tematycznych i informacji o nastrojach połączonych z ostatnią ramką DataFrame o nazwie feedbackTopics które zaoszczędziliśmy na Amazon S3 w naszym pierwszym notebooku.

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

Użyj Amazon QuickSight do wizualizacji danych

Możesz użyć QuickSight do wizualizacji danych i generowania raportów. QuickSight to usługa analizy biznesowej (BI), której można używać do wykorzystywania danych z wielu różnych źródeł i tworzenia inteligentnych pulpitów nawigacyjnych. W tym przykładzie generujemy analizę QuickSight przy użyciu końcowego utworzonego zestawu danych, jak pokazano w poniższych przykładowych wizualizacjach.

Wizualizacja QuickSight

Aby dowiedzieć się więcej o Amazon QuickSight, zapoznaj się z Pierwsze kroki z Amazon Quicksight.

Oczyszczanie

Na koniec musimy zamknąć instancję notatnika, której używaliśmy w tym eksperymencie, z konsoli AWS.

Wnioski

W tym poście pokazaliśmy, jak używać Amazon Comprehend do analizowania recenzji produktów i znajdowania najważniejszych tematów za pomocą modelowania tematów jako techniki. Modelowanie tematyczne umożliwia przeglądanie wielu tematów oraz organizowanie, rozumienie i podsumowywanie ich na dużą skalę. Możesz szybko i łatwo odkryć ukryte wzorce obecne w danych, a następnie wykorzystać te informacje do podejmowania decyzji opartych na danych. Możesz użyć modelowania tematów do rozwiązania wielu problemów biznesowych, takich jak automatyczne tagowanie zgłoszeń do obsługi klienta, kierowanie rozmów do odpowiednich zespołów na podstawie tematu, wykrywanie pilności zgłoszeń do pomocy technicznej, uzyskiwanie lepszych informacji z rozmów, tworzenie planów opartych na danych, tworzenie problemów - skoncentrowane treści, ulepszanie strategii sprzedaży oraz identyfikowanie problemów i tarcia klientów.

To tylko kilka przykładów, ale możesz pomyśleć o wielu innych problemach biznesowych, z którymi codziennie borykasz się w swojej organizacji, oraz o tym, jak możesz wykorzystać modelowanie tematów z innymi technikami ML, aby je rozwiązać.


O autorach

Gurpreet CheemaGurpreet jest analitykiem danych z AWS Professional Services z siedzibą w Kanadzie. Jej pasją jest pomaganie klientom w innowacyjnych technologiach uczenia maszynowego i sztucznej inteligencji, aby wykorzystać wartość biznesową i wnioski z danych. W wolnym czasie lubi wędrować na świeżym powietrzu i czytać książki.i

Rushdiego ShamsaRushdiego Shamsa jest analitykiem danych w AWS Professional Services w Kanadzie. Buduje produkty uczenia maszynowego dla klientów AWS. Uwielbia czytać i pisać science fiction.

Wricka TalukdaraWricka Talukdara jest starszym architektem w zespole Amazon Comprehend Service. Współpracuje z klientami AWS, aby pomóc im wdrożyć uczenie maszynowe na dużą skalę. Poza pracą lubi czytać i fotografować.

Znak czasu:

Więcej z Uczenie maszynowe AWS