Amazon Comprehend PlatoBlockchain Data Intelligence を使用して、レビューからより良い洞察を得ます。 垂直検索。 あい。

Amazon Comprehend を使用してレビューからより良い洞察を得る

「購入者の 85% は、個人的なおすすめと同じくらいオンライン レビューを信頼しています」 – ガートナー

消費者は、デジタル サーフェスや複数のタッチポイントを通じて企業との関わりを深めています。 統計によると、買い物客の大部分はレビューを使用して、購入する製品と使用するサービスを決定しています。 通り シュピーゲル研究センターの場合、レビューが 270 件ある商品の購入可能性は、レビューがない商品の購入可能性よりも XNUMX% 高くなります。 レビューには、消費者の意思決定に影響を与え、ブランド価値を高める力があります。

この投稿では、 Amazon Comprehend 製品レビューから意味のある情報を抽出し、それを分析して、さまざまな人口統計のユーザーが製品にどのように反応しているかを理解し、製品に対するユーザーの親和性に関する集約された情報を発見します。 Amazon Comprehend は、ドキュメントまたはテキストのコンテンツに関する洞察を抽出できる、フルマネージドで継続的にトレーニングされた自然言語処理 (NLP) サービスです。

ソリューションの概要

現在、星による評価、自由なテキストや自然言語、ソーシャル メディアの共有など、さまざまな方法で顧客がレビューを提供できます。 フリーテキストまたは自然言語によるレビューは、消費者からの独立した意見であるため、信頼の構築に役立ちます。 製品チームがレビュー チャネルを通じて顧客と対話するためによく使用されます。 顧客が自分の意見を聞いてくれると、ブランドに対する印象が向上することは証明されています。 星の評価やソーシャル メディアのシェアを分析するのは比較的簡単ですが、自然言語やフリー テキストのレビューでは、キーワードやフレーズ、トピックやコンセプト、センチメントやエンティティ レベルのセンチメントの特定など、複数の課題が生じます。 課題は主に、書かれたテキストの長さのばらつきと、信号とノイズの両方のもっともらしい存在によるものです。 さらに、情報は非常に明確で明示的 (キーワードやキー フレーズなど) の場合もあれば、不明確で暗示的 (抽象的なトピックや概念) の場合もあります。 さらに難しいのは、さまざまな種類の感情を理解し、それらを適切な製品やサービスに関連付けることです。 それでも、摩擦のないカスタマー エクスペリエンスを提供するには、この情報とテキスト シグナルを理解することが非常に重要です。

この投稿では、公開されている NLP – fast.ai 顧客から提供された製品レビューを分析するためのデータセット。 まず、トピック モデリングと呼ばれる教師なし機械学習 (ML) 手法を使用します。 これは、テキスト レビュー コレクションで発生する可能性のある抽象的なトピックを検出する、一般的な教師なし手法です。 トピック モデリングは、教師なしのクラスタリング問題です。つまり、モデルは可能なターゲット変数 (レビューのトピックなど) に関する知識を持っていません。 トピックはクラスターとして表されます。 多くの場合、ドキュメントのコーパス内のクラスターの数は、ドメインの専門家の助けを借りて、または何らかの標準的な統計分析を使用して決定されます。 モデルの出力には通常、番号付きクラスター (トピック 0、トピック 1 など)、各クラスターに関連付けられたキーワード、各ドキュメント (この場合はレビュー) の代表的なクラスターの XNUMX つのコンポーネントがあります。 固有の性質により、トピック モデルはクラスターまたはトピックに対して人間が判読できるラベルを生成しません。これはよくある誤解です。 一般に、トピック モデリングについて注意すべき点は、それが混合メンバーシップ モデルであることです。モデル内のすべてのドキュメントは、すべてのトピックに類似している可能性があります。 トピック モデルは、反復ベイジアン プロセスで学習して、各ドキュメントが特定のテーマまたはトピックに関連付けられている確率を判断します。 モデルの出力は、トピックの数を最適に選択することに依存します。 トピックの数が少ないと、トピックが広すぎる可能性があり、トピックの数が多いと、重複したトピックや類似したトピックになる可能性があります。 トピック モデルを評価するには、いくつかの方法があります。

  • 人間の判断 – 観察ベース、解釈ベース
  • 定量的指標 – パープレキシティ、コヒーレンス計算
  • 混合アプローチ – 判断ベースのアプローチと定量的アプローチの組み合わせ

Perplexity は、データセットをトレーニング セットとテスト セットの XNUMX つの部分に分割することによって計算されます。 通常、尤度は対数として計算されるため、このメトリックはホールドアウト対数尤度と呼ばれることがあります。 困惑は予測指標です。 トレーニング セットでトレーニングされた後、テスト セットを予測するトピック モデルの能力を評価します。 perplexity の欠点の XNUMX つは、文脈を捉えられないことです。つまり、トピック内の単語やドキュメント内のトピック間の関係を捉えられません。 しかし、人間の理解にとって意味文脈の考え方は重要です。 トピック内の単語の同時発生の条件付き可能性などの尺度が役立ちます。 これらのアプローチはまとめてコヒーレンスと呼ばれます。 この投稿では、人間の判断 (観察に基づく) アプローチ、つまりトピックの上位 n 単語を観察することに焦点を当てます。

このソリューションは、次の高レベルの手順で構成されています。

  1. セットアップ アマゾンセージメーカー ノートブック インスタンス。
  2. ノートブックを作成します。
  3. 探索的データ分析を実行します。
  4. Amazon Comprehend トピック モデリング ジョブを実行します。
  5. トピックを生成し、センチメントを理解します。
  6.   アマゾンクイックサイト データを視覚化し、レポートを生成します。

このソリューションは任意の AWS リージョンで使用できますが、Amazon Comprehend API と SageMaker が同じリージョンにあることを確認する必要があります。 この投稿では、リージョン 米国東部 (バージニア北部) を使用します。

SageMaker ノートブック インスタンスをセットアップする

経由で Amazon Comprehend と対話できます。 AWSマネジメントコンソール, AWSコマンドラインインターフェイス(AWS CLI)、または Amazon Comprehend API。 詳細については、次を参照してください。 Amazon Comprehend の使用開始. この記事では、SageMaker ノートブックと Python (Boto3) コードを使用して、Amazon Comprehend API を操作します。

  1. Amazon SageMaker コンソールのナビゲーションペインの [ノートブック] で、[選択]
    ノートブック インスタンス。
  2. [ノートブック インスタンスの作成] を選択します。ノートブックインスタンス
  3. ノートブック インスタンス名を指定し、インスタンス タイプを ml.r5.2xlarge に設定します。
  4. 残りのデフォルト設定はそのままにします。
  5. 作る AWS Identity and Access Management(IAM) との役割 AmazonSageMakerFullAccess 必要なものへのアクセス Amazon Simple Storage Service(Amazon S3) バケットと Amazon Comprehend API。
  6. [ノートブック インスタンスの作成] を選択します。
    数分後、ノートブック インスタンスの準備が整います。
  7. ノートブック インスタンスから Amazon Comprehend にアクセスするには、 ComprehendFullAccess ポリシーを IAM ロールに追加します。

Amazon Comprehend のセキュリティの概要については、次を参照してください。 Amazon Comprehendのセキュリティ.

プロビジョニングしたノートブック インスタンスを開いた後、Jupyter コンソールで、[新規]、[Python 3 (データ サイエンス)] の順に選択します。 または、次のサンプル コード ファイルにアクセスできます。 GitHubレポ. ファイルをノートブック インスタンスにアップロードして、直接実行するか、クローンを作成できます。

GitHub リポジトリには、次の XNUMX つのノートブックが含まれています。

  • 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 個のドキュメントを提供することをお勧めします。各ドキュメントは少なくとも 8 文の長さです。 ドキュメントは UTF-8 形式のテキスト ファイルである必要があります。 次のステップでは、データが推奨される UTF-5,000 形式であり、各入力のサイズが XNUMX バイト以下であることを確認します。

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)

次に、データを Amazon 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 を使用してトピック モデリング ジョブを実行します。 この段階で、XNUMX 番目のノートブック (model_training.ipynb) または Amazon Comprehend コンソールを使用して、トピック モデリング ジョブを実行します。 コンソールの使用方法については、次を参照してください。 コンソールを使用した分析ジョブの実行. ノートブックを使用している場合は、次の例に示すように、Boto3 を使用して Amazon Comprehend クライアントを作成することから始めることができます。

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

トピック モデリングのためにドキュメントを送信するには、ファイルごとに XNUMX つのドキュメント、または XNUMX 行に XNUMX つのドキュメントの XNUMX つの方法があります。

5 つのトピック (k 番号) から始めて、XNUMX 行に XNUMX つのドキュメントを使用します。 k またはトピックの数を選択するための標準的な方法として、最適な方法は XNUMX つではありません。 さまざまな 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 手術。 ジョブのステータスは、次のいずれかになります。

  • SUBMITTED – ジョブが受信され、処理のためにキューに入れられています
  • IN_PROGRESS – Amazon Comprehend がジョブを処理しています
  • COMPLETED – ジョブは正常に完了し、出力が利用可能です
  • FAILED – ジョブは完了しませんでした
# 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 の XNUMX つのファイルを含む圧縮アーカイブが返されます。 最初の出力ファイル、 topic-terms.csv、コレクション内のトピックのリストです。 トピックごとに、リストにはデフォルトで、重みに応じてトピックごとに上位の用語が含まれます。 XNUMX番目のファイル、 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()

トピックの数はドキュメント コレクションに関連付けられている語彙よりもはるかに少ないため、トピック空間の表現は次元削減プロセスと見なすこともできます。 ドキュメントのこのトピック空間表現を使用して、クラスタリングを実行できます。 一方、各クラスター内の単語の頻度を分析して、各クラスターに関連付けられているトピックを特定できます。 この投稿では、クラスタリングなどの他の手法は実行しません。

XNUMX 番目のノートブック (topic_mapping_sentiment_generation.ipynb) さまざまな人口統計のユーザーが製品にどのように反応しているかを調べ、特定の製品に対するユーザーの親和性に関する集計情報も分析します。

前のノートブックからの出力を組み合わせて、各トピックのトピックと関連用語を取得できます。 ただし、トピックには番号が付けられており、説明が不十分な場合があります。 したがって、関連する用語を調べてトピックに名前を付けるには、十分なドメイン知識と主題の専門知識を備えた人間参加型を使用することをお勧めします。 このプロセスは、トピック番号からトピック名へのマッピングと見なすことができます。 ただし、トピックの用語の個々のリストは相互に包括的であり、複数のマッピングが作成される可能性があることに注意してください。 ヒューマン イン ザ ループは、ユース ケースのコンテキストに基づいてマッピングを形式化する必要があります。 そうしないと、ダウンストリームのパフォーマンスが影響を受ける可能性があります。

変数を宣言することから始めます。 各レビューには、複数のトピックが含まれる場合があります。 それらの頻度を数えて、最も頻度の高いトピックを最大 XNUMX つ選択します。 これらのトピックは、レビューの代表的なトピックとして報告されます。 まず、変数を定義します 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',
}

次に、Amazon Comprehend によって生成された topic-terms.csv ファイルを使用して、各トピックに関連付けられた固有の用語を関連付けます。 次に、このトピックと用語の関連付けにマッピング辞書を適用することにより、一意の用語をトピック名に関連付けます。

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

次の DataFrame でわかるように、このマッピングにより、Amazon Comprehend によって生成されたトピックの読みやすさと説明のしやすさが向上します。

さらに、次の手順に示すように、トピック番号、用語、および名前を初期入力データに結合します。

これにより、各レビューに対応するトピック用語と名前が返されます。 トピック番号と用語は各レビューに結合され、さらに最初のノートブックに保存した元の 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. テキストを検査し、一般的な感情 (POSITIVE、NEUTRAL、MIXED、または NEGATIVE) の推論を返します。

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 に表示される値を検討できます。 最初の製品については、そのすべてのレビューの中で、全体的に顧客は製品の返品、サイズ、および快適さについて肯定的な経験をしました. XNUMX 番目の製品の場合、顧客はほとんどの場合、製品の返品に関してポジティブな経験と、製品のサイズに関してポジティブな経験の混合から肯定的な経験をしました。

# 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 最初のノートブックで Amazon 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 コンソールからシャットダウンする必要があります。

まとめ

この投稿では、Amazon Comprehend を使用して製品レビューを分析し、トピック モデリングを手法として使用して上位のトピックを見つける方法を示しました。 トピック モデリングを使用すると、複数のトピックに目を通し、大規模に整理、理解、要約することができます。 データ全体に存在する隠れたパターンをすばやく簡単に発見し、その洞察を使用してデータ主導の意思決定を行うことができます。 トピック モデリングを使用すると、カスタマー サポート チケットの自動タグ付け、トピックに基づく適切なチームへの会話のルーティング、サポート チケットの緊急性の検出、会話からのより良い洞察の取得、データ主導の計画の作成、問題の作成など、多くのビジネス上の問題を解決できます。 -焦点を絞ったコンテンツ、販売戦略の改善、顧客の問題と摩擦の特定。

これらはほんの一例ですが、組織で日常的に直面するビジネス上の問題は他にもたくさんあり、トピック モデリングと他の ML 手法を使用してそれらを解決する方法を考えることができます。


著者について

ガープリートチーマGurpreet カナダを拠点とする AWS プロフェッショナル サービスのデータ サイエンティストです。 彼女は、顧客が機械学習と人工知能技術を使用して革新し、データからビジネス価値と洞察を引き出すのを支援することに情熱を注いでいます。 余暇には、屋外でのハイキングや読書を楽しんでいます.i

ルシュディ・シャムスルシュディ・シャムス は、カナダの AWS プロフェッショナル サービスのデータ サイエンティストです。 AWS のお客様向けに機械学習製品を構築しています。 彼はサイエンス フィクションを読んだり書いたりするのが大好きです。

ウリック・タルクダーウリック・タルクダー Amazon Comprehend Service チームのシニア アーキテクトです。 彼は AWS のお客様と協力して、大規模な機械学習の導入を支援しています。 仕事以外では、読書と写真を楽しんでいます。

タイムスタンプ:

より多くの AWS機械学習