Amazon Comprehend で、(キーフレーズ抽出)(エンティティ認識)(構文解析)を試してみる
前投稿で、(言語検出)(感情分析)をやってみたので、今回はその続きで、(キーフレーズ抽出)(エンティティ認識)(構文解析)です。
まず、APIリファレンスです。
APIリファレンス
Comprehend detect_key_phrasesメソッド (キーフレーズ抽出)
機能 テキスト内に見つかった「重要な言い回し」を検出します。
構文
{
"LanguageCode": "string",
"Text": "string"
}
戻り値
{
"KeyPhrases": [
{
"BeginOffset": number,
"EndOffset": number,
"Score": number,
"Text": "string"
}
]
}
構文説明
リクエストは以下のデータを JSON 形式で受け入れます。
[LanguageCode]
入力ドキュメントの言語。Amazon Comprehend でサポートされる主要言語のいずれかを指定できます。
すべてのドキュメントは同じ言語である必要があります。
タイプ: 文字列
有効な値: en | es | fr | de | it | pt | ar | hi | ja | ko | zh | zh-TW 日本語ja OK!
指定は必須
[Text]
UTF-8 テキスト文字列。各文字列には、UTF-8 エンコード文字で 5,000 バイト未満です。
タイプ: 文字列
長さの制約: 最小長= 1
指定は必須
戻り値説明
アクションが成功すると、サービスは HTTP 200 レスポンスを返します。
サービスから以下のデータが JSON 形式で返されます。
[KeyPhrases]
AmazonComprehendが入力テキストで識別したキーフレーズのコレクション。
キーフレーズごとに、応答はキーフレーズのテキスト、キーフレーズの開始位置と終了位置、
およびAmazonComprehendの検出精度である信頼度を提供します。
タイプ:KeyPhraseオブジェクトの配列
エラー内容
[InternalServerException]
内部サーバーエラーが発生しました。リクエストを再実行します。
HTTP ステータスコード: 500
[InvalidRequestException]
要求は無効です。
HTTP ステータスコード: 400
[TextSizeLimitExceedException]
入力テキストのサイズが制限を超えています。小さなドキュメントを使用する。
HTTP ステータスコード: 400
[UnsupportedLanguageException]
Amazon Comprehend は入力テキストの言語を処理できません。
ユーザー定義エンティティ認識 API の場合、英語、スペイン語、フランス語、イタリア語、ドイツ語、またはポルトガル語のみが
受け入れられます。
HTTP ステータスコード: 400
Comprehend detect_entitiesメソッド (エンティティ認識)
機能 文章から、人名、地名、社名といった固有名詞や日付などの情報を抽出します。
構文
{
"EndpointArn": "string",
"LanguageCode": "string",
"Text": "string"
}
戻り値
{
"Entities": [
{
"BeginOffset": number,
"EndOffset": number,
"Score": number,
"Text": "string",
"Type": "string"
}
]
}
構文説明
リクエストは以下のデータを JSON 形式で受け入れます。
[EndpointArn]
カスタムエンティティ認識モデルに関連付けられているエンドポイントの Amazonリソースネーム。
Amazon Comprehend で使用されるデフォルトモデルではなく、独自のカスタムモデルを使用してエンティティを検出する場合は、
エンドポイントを指定します。
エンドポイントを指定すると、Amazon Comprehend はカスタムモデルの言語を使用し、リクエストで指定した言語コードは無視されます。
タイプ: 文字列
長さの制約: 最大長=256
パターン: arn:aws(-[^:]+)?:comprehend:[a-zA-Z0-9-]*:[0-9]{12}:entity-recognizer-endpoint/[a-zA-Z0-9](-*[a-zA-Z0-9])*
指定は必須ではない
[LanguageCode]
入力ドキュメントの言語。Amazon Comprehend でサポートされる主要言語のいずれかを指定できます。
すべてのドキュメントは同じ言語である必要があります。
リクエストにカスタムエンティティ認識モデルのエンドポイントが含まれている場合、
Amazon Comprehend はカスタムモデルの言語を使用し、ここで指定した言語コードは無視されます。
タイプ:文字列
有効な値: en | es | fr | de | it | pt | ar | hi | ja | ko | zh | zh-TW 日本語ja OK!
指定は必須ではない
[Text]
UTF-8 テキスト文字列。各文字列には、UTF-8エンコード文字で 5,000バイト未満です。
タイプ: 文字列
長さの制約: 最小長= 1
指定は必須
戻り値説明
アクションが成功すると、サービスは HTTP 200 レスポンスを返します。
サービスから以下のデータが JSON 形式で返されます。
[Entities]
入力テキストで識別されたエンティティのコレクション。
応答は、エンティティごとに、エンティティテキスト、エンティティタイプ、エンティティテキストの開始位置と終了位置、
およびAmazonComprehendが検出した信頼度を提供します。
リクエストでカスタムエンティティ認識モデルが使用されている場合、
Amazon Comprehendは、モデルが認識するようにトレーニングされているエンティティを検出します。
それ以外の場合は、デフォルトのエンティティタイプを検出します。
タイプ:エンティティオブジェクトの配列
エラー内容
[InternalServerException]
内部サーバーエラーが発生しました。リクエストを再実行します。
HTTP ステータスコード: 500
[InvalidRequestException]
要求は無効です。
HTTP ステータスコード: 400
[ResourceUnavailableException]
指定されたリソースは使用できません。リソースを確認して、リクエストを再度試みてください。
HTTP ステータスコード: 400
[TextSizeLimitExceedException]
入力テキストのサイズが制限を超えています。小さなドキュメントを使用する。
HTTP ステータスコード: 400
[UnsupportedLanguageException]
Amazon Comprehend は入力テキストの言語を処理できません。ユーザー定義エンティティ認識 API の場合、
英語、スペイン語、フランス語、イタリア語、ドイツ語、またはポルトガル語のみが受け入れられます。
HTTP ステータスコード: 400
Comprehend detect_syntaxメソッド (構文分析)
機能 文書内のテキストの構文と単語の品詞を調べます。
構文
{
"LanguageCode": "string",
"Text": "string"
}
戻り値
{
"SyntaxTokens": [
{
"BeginOffset": number,
"EndOffset": number,
"PartOfSpeech": {
"Score": number,
"Tag": "string"
},
"Text": "string",
"TokenId": number
}
]
}
構文説明
リクエストは以下のデータを JSON 形式で受け入れます。
[LanguageCode]
入力ドキュメントの言語コード。Amazon Comprehend でサポートされる言語のいずれかを指定できます。
ドイツ語 (「de」)、英語 (「en」)、スペイン語 (「es」)、フランス語 (「fr」)、イタリア語 (「it」)、ポルトガル語 (「pt」)。
タイプ: 文字列
有効な値: en | es | fr | de | it | pt 日本語ja NG!(2021.7.9)
指定は必須
[Text]
A UTF-8 文字列。各文字列には、UTF エンコード文字で 5,000 バイト未満です。
タイプ: 文字列
長さの制約: 最小長=1
指定は必須
戻り値説明
アクションが成功すると、サービスは HTTP 200 レスポンスを返します。
サービスから以下のデータが JSON 形式で返されます。
[SyntaxTokens]
テキストを説明する構文トークンのコレクション。
応答は、トークンごとに、テキスト、テキストの開始位置と終了位置、およびAmazon Comprehend が信頼度を提供します。
タイプ:SyntaxTokenオブジェクトの配列
エラー内容
[InternalServerException]
内部サーバーエラーが発生しました。リクエストを再実行します。
HTTP ステータスコード: 500
[InvalidRequestException]
要求は無効です。
HTTP ステータスコード: 400
[TextSizeLimitExceedException]
入力テキストのサイズが制限を超えています。小さなドキュメントを使用してください。
HTTP ステータスコード: 400
[UnsupportedLanguageException]
Amazon Comprehend は入力テキストの言語を処理できません。
ユーザー定義エンティティ認識 API の場合、英語、スペイン語、フランス語、イタリア語、ドイツ語、ポルトガル語のみが受け入れられます。
HTTP ステータスコード: 400
③文書内のエンティティを認識するプログラム detect_key_phrase1.py
import boto3
import json
comprehend = boto3.client('comprehend', 'ap-northeast-1')
text = "炭治郎は自分を鼓舞した。\
「頑張れ炭治郎頑張れ!! 俺は今までよくやってきた!! 俺はできる奴だ!! そして今日も!! これからも!! 折れていても!! \
俺が挫けることは絶対に無い!!」\
でも、戦いが終われば、敵である鬼に対しても、慈悲の気持ちを表した。\
「殺された人たちの無念を晴らすため、これ以上被害者を出さないため…\
勿論俺は容赦無く鬼の頸に刃を振るいます。だけど鬼であることに苦しみ、\
自らの行いを悔いている者を踏みつけにはしない。鬼は人間だったんだから。\
足をどけてください。醜い化け物なんかじゃない。鬼は虚しい生き物だ。悲しい生き物だ。」"
result = comprehend.detect_key_phrases(Text=text, LanguageCode='ja')
print(json.dumps(result, indent=4))
report = {}
for phrase in result['KeyPhrases']:
txt, score = phrase['Text'], phrase['Score']
report[txt] = '{:<018} {}'.format(score, txt)
for line in sorted(report.values(), reverse=True):
print(line)
PS C:\Users\mikol\comprehend> python detect_key_phrase1.py
{
"KeyPhrases": [
{
"Score": 0.9998185634613037,
"Text": "\u70ad\u6cbb\u90ce", 炭治郎
"BeginOffset": 0,
"EndOffset": 3
},
{
"Score": 0.9988521337509155,
"Text": "\u81ea\u5206", (自分)
"BeginOffset": 4,
"EndOffset": 6
},
{
"Score": 0.9895590543746948,
"Text": "\u70ad\u6cbb\u90ce", (炭治郎)
"BeginOffset": 16,
"EndOffset": 19
},
{
"Score": 0.9987995624542236,
"Text": "\u4ffa", 俺
"BeginOffset": 25,
"EndOffset": 26
},
{
"Score": 0.9984912872314453,
"Text": "\u4ffa", 俺
"BeginOffset": 40,
"EndOffset": 41
},
{
"Score": 0.9945422410964966,
"Text": "\u5974", (奴)
"BeginOffset": 45,
"EndOffset": 46
},
{
"Score": 0.9536038637161255,
"Text": "\u4eca\u65e5", (今日)
"BeginOffset": 53,
"EndOffset": 55
},
{
"Score": 0.9983626008033752,
"Text": "\u4ffa", 俺
"BeginOffset": 76,
"EndOffset": 77
},
{
"Score": 0.9997751116752625,
"Text": "\u6226\u3044", (戦い)
"BeginOffset": 95,
"EndOffset": 97
},
{
"Score": 0.9943884015083313,
"Text": "\u6575", (敵)
"BeginOffset": 103,
"EndOffset": 104
},
{
"Score": 0.9493768215179443,
"Text": "\u9b3c", 鬼
"BeginOffset": 107,
"EndOffset": 108
},
{
"Score": 0.996557891368866,
"Text": "\u6148\u60b2\u306e\u6c17\u6301\u3061", (慈悲の気持ち)
"BeginOffset": 114,
"EndOffset": 120
},
{
"Score": 0.9971917867660522,
"Text": "\u4eba\u305f\u3061\u306e\u7121\u5ff5", (人たちの無念)
"BeginOffset": 130,
"EndOffset": 136
},
{
"Score": 0.9944612979888916,
"Text": "\u3053\u308c", (これ)
"BeginOffset": 143,
"EndOffset": 145
},
{
"Score": 0.9927535057067871,
"Text": "\u88ab\u5bb3\u8005", (被害者)
"BeginOffset": 147,
"EndOffset": 150
},
{
"Score": 0.9969915151596069,
"Text": "\u4ffa", (俺)
"BeginOffset": 160,
"EndOffset": 161
},
{
"Score": 0.9978446960449219,
"Text": "\u9b3c\u306e\u9838", (鬼の頸)
"BeginOffset": 166,
"EndOffset": 169
},
{
"Score": 0.9972043633460999,
"Text": "\u5203", (刃)
"BeginOffset": 170,
"EndOffset": 171
},
{
"Score": 0.9984999895095825,
"Text": "\u9b3c", 鬼
"BeginOffset": 181,
"EndOffset": 182
},
{
"Score": 0.9989050626754761,
"Text": "\u81ea\u3089\u306e\u884c\u3044", (自らの行い)
"BeginOffset": 192,
"EndOffset": 197
},
{
"Score": 0.9989950060844421,
"Text": "\u8005", (者)
"BeginOffset": 203,
"EndOffset": 204
},
{
"Score": 0.9999489784240723,
"Text": "\u9b3c", 鬼
"BeginOffset": 215,
"EndOffset": 216
},
{
"Score": 0.9876834750175476,
"Text": "\u4eba\u9593", (人間)
"BeginOffset": 217,
"EndOffset": 219
},
{
"Score": 0.9998825788497925,
"Text": "\u8db3", (足)
"BeginOffset": 227,
"EndOffset": 228
},
{
"Score": 0.9775259494781494,
"Text": "\u5316\u3051\u7269\u306a\u3093\u304b", (化け物なんか)
"BeginOffset": 239,
"EndOffset": 245
},
{
"Score": 0.9998785257339478,
"Text": "\u9b3c", 鬼
"BeginOffset": 250,
"EndOffset": 251
},
{
"Score": 0.998601496219635,
"Text": "\u751f\u304d\u7269", 生き物
"BeginOffset": 255,
"EndOffset": 258
},
{
"Score": 0.9991565942764282,
"Text": "\u751f\u304d\u7269", (生き物)
"BeginOffset": 263,
"EndOffset": 266
}
],
"ResponseMetadata": {
"RequestId": "11676764-31a7-464b-a957-4f9943f08f71",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "11676764-31a7-464b-a957-4f9943f08f71",
"content-type": "application/x-amz-json-1.1",
"content-length": "2228",
"date": "Thu, 08 Jul 2021 10:39:25 GMT"
},
"RetryAttempts": 0
}
}
0.9998825788497925 足
0.9998785257339478 鬼
0.9997751116752625 戦い
0.9991565942764282 生き物
0.9989950060844421 者
0.9989050626754761 自らの行い
0.9988521337509155 自分
0.9978446960449219 鬼の頸
0.9972043633460999 刃
0.9971917867660522 人たちの無念
0.9969915151596069 俺
0.9965578913688660 慈悲の気持ち
0.9945422410964966 奴
0.9944612979888916 これ
0.9943884015083313 敵
0.9927535057067871 被害者
0.9895590543746948 炭治郎
0.9876834750175476 人間
0.9775259494781494 化け物なんか
0.9536038637161255 今日
結果の順位一覧を見てもよくわからない。もういっちょ!
text = "彼こそが真の長距離打者だと感じます。また、大谷選手は素晴らしいピッチャーです。\
大リーグの常識を変えた唯一無二の存在です。\
今後もファンの方々や少年たちの夢を背負い、シーズンを乗り切って欲しいと思います。"
テキストだけ変えた!
PS C:\Users\mikol\comprehend> python detect_key_phrase2.py
{
"KeyPhrases": [
{
"Score": 0.9991952776908875,
"Text": "\u5f7c", (彼)
"BeginOffset": 0,
"EndOffset": 1
},
{
"Score": 0.9917044043540955,
"Text": "\u771f\u306e\u9577\u8ddd\u96e2\u6253\u8005", (真の長距離打者)
"BeginOffset": 4,
"EndOffset": 11
},
{
"Score": 0.5408477187156677,
"Text": "\u3001",
"BeginOffset": 20,
"EndOffset": 21
},
{
"Score": 0.7279067635536194,
"Text": "\u5927\u8c37\u9078\u624b\u306f\u7d20\u6674\u3089\u3057\u3044", 大谷選手は素晴らしい
"BeginOffset": 21,
"EndOffset": 31
},
{
"Score": 0.5462606549263,
"Text": "\u30d4\u30c3\u30c1\u30e3\u30fc", ピッチャー
"BeginOffset": 31,
"EndOffset": 36
},
{
"Score": 0.9978181719779968,
"Text": "\u5927\u30ea\u30fc\u30b0\u306e\u5e38\u8b58", (大リーグの常識)
"BeginOffset": 39,
"EndOffset": 46
},
{
"Score": 0.8959624171257019,
"Text": "\u552f\u4e00\u7121\u4e8c\u306e\u5b58\u5728", ( 唯一無二の存在)
"BeginOffset": 50,
"EndOffset": 57
},
{
"Score": 0.9995926022529602,
"Text": "\u4eca\u5f8c", (今後)
"BeginOffset": 60,
"EndOffset": 62
},
{
"Score": 0.9985405802726746,
"Text": "\u30d5\u30a1\u30f3\u306e\u65b9\u3005\u3084\u5c11\u5e74\u305f\u3061\u306e\u5922", (ファンの方々や少年たちの夢)
"BeginOffset": 63,
"EndOffset": 76
},
{
"Score": 0.9997205138206482,
"Text": "\u30b7\u30fc\u30ba\u30f3", (シーズン)
"BeginOffset": 81,
"EndOffset": 85
}
],
"ResponseMetadata": {
"RequestId": "8d98cc94-2e3a-4686-936d-47527a9bc94f",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "8d98cc94-2e3a-4686-936d-47527a9bc94f",
"content-type": "application/x-amz-json-1.1",
"content-length": "891",
"date": "Thu, 08 Jul 2021 10:39:52 GMT"
},
"RetryAttempts": 0
}
}
0.9997205138206482 シーズン
0.9995926022529602 今後
0.9991952776908875 彼
0.9985405802726746 ファンの方々や少年たちの夢
0.9978181719779968 大リーグの常識
0.9917044043540955 真の長距離打者
0.8959624171257019 唯一無二の存在
0.7279067635536194 大谷選手は素晴らしい
0.5462606549263000 ピッチャー
0.5408477187156677 、
やっぱり、良くわからない?
④文章のエンティティを認識するプログラム detect_entity.py
import boto3
comprehend = boto3.client('comprehend', 'us-east-2')
text = "Today the Tokyo Metropolitan Government confirmed 714 new coronavirus infections. The average in the last seven days exceeded 500 people, and it was 508."
result = comprehend.detect_entities(Text=text, LanguageCode='en')
for entity in result['Entities']:
print('{:20} {:20} {:<018}'.format(
entity['Text'], entity['Type'], entity['Score']))
PS C:\Users\mikol\comprehend> python detect_entity.py
Today DATE 0.9924750924110413 (DATE:日付、時刻)
Tokyo Metropolitan Government ORGANIZATION 0.9967338442802429 (ORGANIZATION:組織)
714 new coronavirus infections QUANTITY 0.8721827268600464 (QUANTITY:数値(金額、パーセンテージ」、数値、バイト数など)
seven DATE 0.43877923488616943
days QUANTITY 0.7388077974319458
500 people QUANTITY 0.9913239479064941
508 QUANTITY 0.9958401918411255
ちなみに、日本語でもOK!!
⑤文章の構文を解析するプログラム
import boto3
comprehend = boto3.client('comprehend', 'us-east-2')
text = "Today the Tokyo Metropolitan Government confirmed 714 new coronavirus infections. The average in the last seven days exceeded 500 people, and it was 508."
result = comprehend.detect_syntax(Text=text, LanguageCode='en')
for token in result['SyntaxTokens']:
print('{:20} {:20} {:<018}'.format(
token['Text'],
token['PartOfSpeech']['Tag'],
token['PartOfSpeech']['Score']))
PS C:\Users\mikol\comprehend> python detect_entity.py
Today NOUN 0.9799969196319580
the DET 0.9999412298202515
Tokyo PROPN 0.9996253252029419
Metropolitan PROPN 0.9992173910140991
Government PROPN 0.9905853867530823
confirmed VERB 0.9994437098503113
714 NUM 0.9998207688331604
new ADJ 0.9994088411331177
coronavirus NOUN 0.9429358243942261
infections NOUN 0.9999315738677979
. PUNCT 0.9999971389770508
The DET 0.9999741315841675
average NOUN 0.8812488913536072
in ADP 0.9999345541000366
the DET 0.9999885559082031
last ADJ 0.9994642138481140
seven NUM 0.9991330504417419
days NOUN 0.9999151229858398
exceeded VERB 0.9943482279777527
500 NUM 0.9997524619102478
people NOUN 0.9999828338623047
, PUNCT 0.9999984502792358
and CONJ 0.9999988079071045
it PRON 0.9999908208847046
was VERB 0.9971580505371094
508 NUM 0.9998282194137573
. PUNCT 0.9999864101409912
ちなみに、日本語はNG!!(2021.7.9)
補足 品詞一覧
Token | 品詞 |
ADJ | 形容詞 |
ADP | アドポジション |
ADV | 副詞 通常、動詞を修正する単語。また、形容詞やその他の副詞を変更することもできます。 |
AUX | 補助 動詞句の動詞に付随する関数単語。 |
CCONJ | コーディネート |
DET | 限定子 |
INTJ | インタージェクション 感嘆符または感嘆符の一部として使用される単語。 |
NOUN | 名詞 人、場所、物、動物、またはアイデアを指定する単語。 |
NUM | Numeral 数を表す単語(通常は限定詞、形容詞、代名詞)。 |
O | その他 |
PART | 粒子 別の単語や語句に関連付けられた単語を機能させ、意味を与えます。 |
PRON | 代名詞 |
PROPN | 固有名詞 特定の個人、場所、または対象の名前である名詞。 |
PUNCT | 句読点 |
SCONJ | 従属組み込み 文章の一部をリンクする結合は、それらのいずれかを他方の部分にすること。 |
SYM | 記号 ドル記号 ($) や数学記号などの単語に似たエンティティ。 |
VERB | 動詞 イベントや行動を示す言葉。 |