AWS SDK for Python(Boto3)を使用してAmazon Comprehendを操作する

2018.03.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Amazon Comprehend を AWS SDK for Python (Boto3)で使用する主要な4つの関数と、Topic Modelingで使用する関数のサンプルコードをご紹介します。

主要な4つの関数

  • DetectDominantLanguage
  • DetectEntities
  • DetectKeyPhrases
  • DetectSentiment

これらの関数は最大25のドキュメントをバッチ処理するBatch APIsも用意されています。

Topic Modelingで使用する関数

  • StartTopicsDetectionJob
  • DescribeTopicsDetectionJob
  • ListTopicsDetectionJobs

Sample Code

まずは、主要な4つの関数を使ってみます。

import boto3
import json

# Comprehend constant
REGION = 'us-west-2'


# Function for detecting the dominant language
def detect_dominant_language(text):
    comprehend = boto3.client('comprehend', region_name=REGION)
    response = comprehend.detect_dominant_language(Text=text)
    return response


# Function for detecting named entities
def detect_entities(text, language_code):
    comprehend = boto3.client('comprehend', region_name=REGION)
    response = comprehend.detect_entities(Text=text, LanguageCode=language_code)
    return response


# Function for detecting key phrases
def detect_key_phraes(text, language_code):
    comprehend = boto3.client('comprehend', region_name=REGION)
    response = comprehend.detect_key_phrases(Text=text, LanguageCode=language_code)
    return response


# Function for detecting sentiment
def detect_sentiment(text, language_code):
    comprehend = boto3.client('comprehend', region_name=REGION)
    response = comprehend.detect_sentiment(Text=text, LanguageCode=language_code)
    return response


def main():
    # text
    text = "Amazon Comprehend is a natural language processing (NLP) service that uses machine learning to find insights and relationships in text."

    # language code
    language_code = 'en'

    # detecting the dominant language
    result = detect_dominant_language(text)
    print("Starting detecting the dominant language")
    print(json.dumps(result, sort_keys=True, indent=4))
    print("End of detecting the dominant language\n")

    # detecting named entities
    result = detect_entities(text, language_code)
    print("Starting detecting named entities")
    print(json.dumps(result, sort_keys=True, indent=4))
    print("End of detecting named entities\n")

    # detecting key phrases
    result = detect_key_phraes(text, language_code)
    print("Starting detecting key phrases")
    print(json.dumps(result, sort_keys=True, indent=4))
    print("End of detecting key phrases\n")

    # detecting sentiment
    result = detect_sentiment(text, language_code)
    print("Starting detecting sentiment")
    print(json.dumps(result, sort_keys=True, indent=4))
    print("End of detecting sentiment\n")


if __name__ == '__main__':
    main()

DetectDominantLanguage operation.

テキストに使用されている主要言語を検出します。 Amazon Comprehendは101の異なる言語を検出できます。

Execution result

{
"Languages": [
{
"LanguageCode": "en",
"Score": 0.9940536618232727
}
],
"ResponseMetadata": {
"HTTPHeaders": {
"connection": "keep-alive",
"content-length": "64",
"content-type": "application/x-amz-json-1.1",
"date": "Thu, 22 Mar 2018 04:15:20 GMT",
"x-amzn-requestid": "a29fda00-2d87-11e8-ad56-************"
},
"HTTPStatusCode": 200,
"RequestId": "a29fda00-2d87-11e8-ad56-************",
"RetryAttempts": 0
}
}

DetectEntities operation.

テキストにあるの人物や場所などのエンティティを検出することができます。

Execution result

{
"Entities": [
{
"BeginOffset": 0,
"EndOffset": 6,
"Score": 0.8670787215232849,
"Text": "Amazon",
"Type": "ORGANIZATION"
},
{
"BeginOffset": 7,
"EndOffset": 17,
"Score": 1.0,
"Text": "Comprehend",
"Type": "COMMERCIAL_ITEM"
}
],
"ResponseMetadata": {
"HTTPHeaders": {
"connection": "keep-alive",
"content-length": "201",
"content-type": "application/x-amz-json-1.1",
"date": "Thu, 22 Mar 2018 04:15:20 GMT",
"x-amzn-requestid": "a2b84450-2d87-11e8-b3f9-************"
},
"HTTPStatusCode": 200,
"RequestId": "a2b84450-2d87-11e8-b3f9-************",
"RetryAttempts": 0
}
}

DetectKeyPhrases operation.

テキストの内容を最もよく示すキーフレーズを検出します。

Execution result

{
"KeyPhrases": [
{
"BeginOffset": 0,
"EndOffset": 17,
"Score": 0.9958747029304504,
"Text": "Amazon Comprehend"
},
{
"BeginOffset": 21,
"EndOffset": 50,
"Score": 0.9654422998428345,
"Text": "a natural language processing"
},
{
"BeginOffset": 52,
"EndOffset": 55,
"Score": 0.941932201385498,
"Text": "NLP"
},
{
"BeginOffset": 57,
"EndOffset": 64,
"Score": 0.9076098203659058,
"Text": "service"
},
{
"BeginOffset": 75,
"EndOffset": 91,
"Score": 0.872683584690094,
"Text": "machine learning"
},
{
"BeginOffset": 100,
"EndOffset": 126,
"Score": 0.9918361902236938,
"Text": "insights and relationships"
},
{
"BeginOffset": 130,
"EndOffset": 134,
"Score": 0.998969554901123,
"Text": "text"
}
],
"ResponseMetadata": {
"HTTPHeaders": {
"connection": "keep-alive",
"content-length": "615",
"content-type": "application/x-amz-json-1.1",
"date": "Thu, 22 Mar 2018 04:15:21 GMT",
"x-amzn-requestid": "a2d409a7-2d87-11e8-a9a6-************"
},
"HTTPStatusCode": 200,
"RequestId": "a2d409a7-2d87-11e8-a9a6-************",
"RetryAttempts": 0
}
}

DetectSentiment operation.

テキストの内容にある感情(positive, negative, mixed, or neutral)を検出します。

Execution result

{
"ResponseMetadata": {
"HTTPHeaders": {
"connection": "keep-alive",
"content-length": "161",
"content-type": "application/x-amz-json-1.1",
"date": "Thu, 22 Mar 2018 04:15:21 GMT",
"x-amzn-requestid": "a2ebb00b-2d87-11e8-9c58-************"
},
"HTTPStatusCode": 200,
"RequestId": "a2ebb00b-2d87-11e8-9c58-************",
"RetryAttempts": 0
},
"Sentiment": "NEUTRAL",
"SentimentScore": {
"Mixed": 0.003294283989816904,
"Negative": 0.01219215989112854,
"Neutral": 0.7587229609489441,
"Positive": 0.2257905900478363
}
}

Topic Modeling

トピック検出ジョブを実行してみます。

Sample Code

import boto3
import json
import time
from bson import json_util

# Comprehend constant
REGION = 'us-west-2'

# A low-level client representing Amazon Comprehend
comprehend = boto3.client('comprehend', region_name=REGION)

# Start topics detection job setting
input_s3_url = "s3://your_input"
input_doc_format = "ONE_DOC_PER_FILE or ONE_DOC_PER_FILE"
output_s3_url = "s3://your_output"
data_access_role_arn = "arn:aws:iam::aws_account_id:role/role_name"
number_of_topics = 10
job_name = "Job_name"

input_data_config = {"S3Uri": input_s3_url, "InputFormat": input_doc_format}
output_data_config = {"S3Uri": output_s3_url}

# Starts an asynchronous topic detection job.
response = comprehend.start_topics_detection_job(NumberOfTopics=number_of_topics,
                                                 InputDataConfig=input_data_config,
                                                 OutputDataConfig=output_data_config,
                                                 DataAccessRoleArn=data_access_role_arn,
                                                 JobName=job_name)

# Gets job_id
job_id = response["JobId"]
print('job_id: ' + job_id)

# It loops until JobStatus becomes 'COMPLETED' or 'FAILED'.
while True:
    result = comprehend.describe_topics_detection_job(JobId=job_id)
    job_status = result["TopicsDetectionJobProperties"]["JobStatus"]

    if job_status in ['COMPLETED', 'FAILED']:
        print("job_status: " + job_status)
        break
    else:
        print("job_status: " + job_status)
        time.sleep(60)

# You can get a list of the topic detection jobs that you have submitted.
input_data_config = {"S3Uri": input_s3_url, "InputFormat": input_doc_format}

filter_job_name = {"JobName": job_name}

topics_detection_job_list = comprehend.list_topics_detection_jobs(Filter=filter_job_name)
print('topics_detection_job_list: ' + json.dumps(topics_detection_job_list,
                                                 sort_keys=True,
                                                 indent=4,
                                                 default=json_util.default))

StartTopicsDetectionJob

非同期でトピック検出ジョブをスタートします。 JobIdを取得して次のDescribeTopicDetectionJobでジョブの状態を確認できます。

InputFormatには2種類あります。

  • ONE_DOC_PER_FILE
  • 各ファイルに一つのドキュメントが含まれている場合
  • ONE_DOC_PER_LINE
  • 一つのファイル、ファイルの各行はドキュメントとみなされます。

DescribeTopicDetectionJob

トピック検出ジョブのステータスを取得します。 以下4つのステータスがあります。

  • JobStatus
  • SUBMITTED
  • IN_PROGRESS
  • COMPLETED
  • FAILED

サンプルコードではJobStatusがCOMPLETEDFAILEDでループを抜けるようにしました。

ListTopicsDetectionJobs

トピック検出ジョブのリストを取得します。

Execution result

job_id: 2733262c2747153ab8cb0b01********
job_status: SUBMITTED
job_status: IN_PROGRESS
[...]
job_status: COMPLETED
topics_detection_job_list: {
"ResponseMetadata": {
"HTTPHeaders": {
"connection": "keep-alive",
"content-length": "415",
"content-type": "application/x-amz-json-1.1",
"date": "Thu, 22 Mar 2018 04:27:59 GMT",
"x-amzn-requestid": "669ffb28-2d89-11e8-82a0-************"
},
"HTTPStatusCode": 200,
"RequestId": "669ffb28-2d89-11e8-82a0-************",
"RetryAttempts": 0
},
"TopicsDetectionJobPropertiesList": [
{
"EndTime": {
"$date": 1521692818930
},
"InputDataConfig": {
"InputFormat": "ONE_DOC_PER_FILE",
"S3Uri": "s3://your_input"
},
"JobId": "2733262c2747153ab8cb0b01********",
"JobName": "Job4",
"JobStatus": "COMPLETED",
"NumberOfTopics": 10,
"OutputDataConfig": {
"S3Uri": "s3://your_output/**********-2733262c2747153ab8cb0b01********-1521692274392/output/output.tar.gz"
},
"SubmitTime": {
"$date": 1521692274392
}
}
]
}

アウトプットファイルを確認

アウトプット先のs3バケットにファイルができていることを確認します。 ListTopicsDetectionJobsで確認が可能です。

  • OutputDataConfig
"OutputDataConfig": {
"S3Uri": "s3://comprehend-output/************-23e550d3b1e792cf128931339a222d85-1521571329055/output/output.tar.gz"
},
$ aws s3 cp s3://comprehend-output/************-23e550d3b1e792cf128931339a222d85-1521571329055/output/output.tar.gz .
$ tar -zxvf output.tar.gz
x topic-terms.csv
x doc-topics.csv
  • topic-terms.csv
  • コレクション内のトピックリストです。各トピックについて、デフォルトで、トピックの重み付けに従って上位の用語が含まれています。
  • doc-topics.csv
  • トピックに関連付けられたドキュメントとそのトピックに関連するドキュメントの割合を一覧表示します。

※正確な結果を得るにはそれぞれのtopic modeling jobで少なくとも1,000のドキュメントを使用する必要があります。

まとめ

Amazon Comprehendを利用するにあたりAPIを使うと思いますのでAWS SDK for Python (Boto3)を使った各関数のサンプルコードをご紹介しました。

参考URL