Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.
Estrazione e invio di testo a AWS Comprehend for Analysis
Amazon Textract ti consente di includere il rilevamento e l'analisi del testo dei documenti nelle tue applicazioni. Con Amazon Textract puoi estrarre testo da una varietà di tipi di documenti diversi utilizzando l'elaborazione sincrona e asincrona dei documenti. Il testo estratto può quindi essere salvato in un file o database o inviato a un altro servizio per un'ulteriore elaborazione. AWS
In questo tutorial eseguirai un flusso di lavoro end-to-end comune. Questo flusso di lavoro prevede:
-
Elaborazione di numerosi documenti di input con Amazon Textract
-
Fornire il testo estratto ad Amazon Comprehend per l'analisi
-
Salvataggio del testo analizzato e dei dati di analisi in un bucket Amazon Simple Storage Service (S3)
Utilizzi l'AWS SDK per Python per
Prerequisiti
Prima di iniziare questo tutorial, dovrai installare Python e completare i passaggi necessari per configurare Python
-
Hai configurato correttamente le tue credenziali di accesso AWS
-
Amazon Textract è stato configurato per l'elaborazione asincrona, copiando l'Amazon Resource Number (ARN) del ruolo IAM configurato per l'uso con Amazon Textract
-
Hai concesso l'accesso al tuo ruolo IAM ad Amazon Comprehend
-
Ha selezionato alcuni documenti da utilizzare come testo extraction/analysis e ha caricato il documento su Amazon S3. Assicurati che i file selezionati per l'analisi siano nei formati supportati da Amazon Textract.
Avvio del rilevamento asincrono del testo dei documenti
Puoi estrarre il testo dai tuoi documenti e poi analizzarlo con un servizio come Amazon Comprehend. Textract supporta l'estrazione di testo da documenti multipagina tramite operazioni asincrone, che servono per l'elaborazione di documenti di grandi dimensioni e multipagina. L'elaborazione asincrona di un file PDF consente all'applicazione di completare altre attività in attesa del completamento del processo. Questa sezione mostrerà come importare i documenti da un bucket Amazon S3 e fornirli all'operazione asincrona di rilevamento del testo di Textract.
Questo tutorial presuppone che utilizzerai Amazon S3 per archiviare i file da cui desideri estrarre il testo. Inizierai creando una classe e delle funzioni che rilevano il testo nei tuoi documenti di input. L'applicazione dovrà connettersi al client Textract, nonché ai client Amazon SQS e Amazon SNS allo scopo di monitorare lo stato di completamento del processo asincrono.
-
Inizia scrivendo il codice per creare un argomento Amazon SNS e una coda Amazon SQS.
Il seguente esempio di codice crea una
DocumentProcessorclasse che si connette ai tre servizi richiesti e quindi crea sia una coda Amazon SQS che un argomento Amazon SNS. L'argomento Amazon SNS viene utilizzato per fornire informazioni sullo stato di completamento del lavoro a una coda Amazon SQS, che verrà interrogata per ottenere lo stato di completamento di un lavoro. Esistono anche metodi per eliminare la coda Amazon SQS e l'argomento Amazon SNS una volta che il processo è stato completato e le risorse non sono più necessarie.import boto3 import json import sys import time class DocumentProcessor: jobId = '' region_name = '' roleArn = '' bucket = '' document = '' sqsQueueUrl = '' snsTopicArn = '' processType = '' def __init__(self, role, bucket, document, region): self.roleArn = role self.bucket = bucket self.document = document self.region_name = region # Instantiates necessary AWS clients session = boto3.Session(profile_name='profile-name', region_name='self.region_name') self.textract = session.client('textract', region_name=self.region_name) self.sqs = session.client('sqs', region_name=self.region_name) self.sns = session.client('sns', region_name=self.region_name) def CreateTopicandQueue(self): millis = str(int(round(time.time() * 1000))) # Create SNS topic snsTopicName = "AmazonTextractTopic" + millis topicResponse = self.sns.create_topic(Name=snsTopicName) self.snsTopicArn = topicResponse['TopicArn'] # create SQS queue sqsQueueName = "AmazonTextractQueue" + millis self.sqs.create_queue(QueueName=sqsQueueName) self.sqsQueueUrl = self.sqs.get_queue_url(QueueName=sqsQueueName)['QueueUrl'] attribs = self.sqs.get_queue_attributes(QueueUrl=self.sqsQueueUrl, AttributeNames=['QueueArn'])['Attributes'] sqsQueueArn = attribs['QueueArn'] # Subscribe SQS queue to SNS topic self.sns.subscribe( TopicArn=self.snsTopicArn, Protocol='sqs', Endpoint=sqsQueueArn) # Authorize SNS to write SQS queue policy = """{{ "Version": "2012-10-17", "Statement":[ {{ "Sid":"MyPolicy", "Effect":"Allow", "Principal" : {{"AWS" : "*"}}, "Action":"SQS:SendMessage", "Resource": "{}", "Condition":{{ "ArnEquals":{{ "aws:SourceArn": "{}" }} }} }} ] }}""".format(sqsQueueArn, self.snsTopicArn) response = self.sqs.set_queue_attributes( QueueUrl=self.sqsQueueUrl, Attributes={ 'Policy': policy }) def DeleteTopicandQueue(self): self.sqs.delete_queue(QueueUrl=self.sqsQueueUrl) self.sns.delete_topic(TopicArn=self.snsTopicArn) -
Scrivi il codice per chiamare l'
StartDocumentTextDetectionoperazione e ottenere i risultati dell'operazione.La
DocumentProcessorclasse avrà anche bisogno di metodi per:-
Chiama l'
StartDocumentTextDetectionoperazione -
Esegui un sondaggio su Amazon SQS per verificare lo stato di completamento del lavoro
-
Recupera i risultati del lavoro una volta completata l'elaborazione
Il codice seguente crea i
GetResultsmetodiProcessDocumentand che chiamanoStartDocumentTextDetectione ottengono rispettivamente il testo estratto.def ProcessDocument(self): # Checks if job found jobFound = False # Starts the text detection operation on the documents in the provided bucket # Sends status to supplied SNS topic arn response = self.textract.start_document_text_detection( DocumentLocation={'S3Object': {'Bucket': self.bucket, 'Name': self.document}}, NotificationChannel={'RoleArn': self.roleArn, 'SNSTopicArn': self.snsTopicArn}) print('Processing type: Detection') print('Start Job Id: ' + response['JobId']) dotLine = 0 while jobFound == False: sqsResponse = self.sqs.receive_message(QueueUrl=self.sqsQueueUrl, MessageAttributeNames=['ALL'], MaxNumberOfMessages=10) # Waits until messages are found in the SQS queue if sqsResponse: if 'Messages' not in sqsResponse: if dotLine < 40: print('.', end='') dotLine = dotLine + 1 else: print() dotLine = 0 sys.stdout.flush() time.sleep(5) continue # Checks for a completed job that matches the jobID in the response from # StartDocumentTextDetection for message in sqsResponse['Messages']: notification = json.loads(message['Body']) textMessage = json.loads(notification['Message']) if str(textMessage['JobId']) == response['JobId']: print('Matching Job Found:' + textMessage['JobId']) jobFound = True text_data = self.GetResults(textMessage['JobId']) self.sqs.delete_message(QueueUrl=self.sqsQueueUrl, ReceiptHandle=message['ReceiptHandle']) return text_data else: print("Job didn't match:" + str(textMessage['JobId']) + ' : ' + str(response['JobId'])) # Delete the unknown message. Consider sending to dead letter queue self.sqs.delete_message(QueueUrl=self.sqsQueueUrl, ReceiptHandle=message['ReceiptHandle']) print('Done!') # gets the results of the completed text detection job # checks for pagination tokens to determine if there are multiple pages in the input doc def GetResults(self, jobId): maxResults = 1000 paginationToken = None finished = False while finished == False: response = None if paginationToken == None: response = self.textract.get_document_text_detection(JobId=jobId, MaxResults=maxResults) else: response = self.textract.get_document_text_detection(JobId=jobId, MaxResults=maxResults, NextToken=paginationToken) blocks = response['Blocks'] # List to hold detected text detected_text = [] # Display block information and add detected text to list for block in blocks: if 'Text' in block and block['BlockType'] == "LINE": detected_text.append(block['Text']) # If response contains a next token, update pagination token if 'NextToken' in response: paginationToken = response['NextToken'] else: finished = True return detected_text -
-
Salva il codice precedente in un file chiamato
detectFileAsync.py.Utilizzerai questo file nella sezione successiva per gestire il rilevamento del testo nei documenti di input.
Elaborazione dei documenti e invio del testo a Comprehend
L'applicazione utilizzerà la classe creata nella sezione successiva per:
-
leggi documenti dal tuo bucket Amazon S3
-
estrai il testo contenuto in quei documenti
-
invia il testo ad Amazon Comprehend per l'analisi
Inizia creando alcune funzioni che utilizzano Amazon Comprehend per analizzare il testo rilevato nei documenti di input. Un tipo comune di analisi del testo è l'analisi del sentimento, che mira a catturare l'effetto di un'affermazione (positiva, negativa o neutra). È inoltre possibile eseguire il rilevamento delle entità e delle frasi chiave sui dati.
Il codice seguente inserisce il testo rilevato e richiama l'BatchDetectSentimentoperazione di Amazon Comprehend per eseguire l'analisi del sentiment.
-
Scrivi il codice per eseguire l'analisi del sentiment sul testo rilevato.
from detectFileAsync import DocumentProcessor import boto3 import pandas as pd # Detect sentiment def sentiment_analysis(detected_text, lang): comprehend = boto3.client("comprehend") detect_sent_response = comprehend.batch_detect_sentiment( TextList=detected_text, LanguageCode=lang) # Lists to hold sentiment labels and sentiment scores sentiments = [] pos_score = [] neg_score = [] neutral_score = [] mixed_score = [] # for all results add the Sentiment label and sentiment scores to lists for res in detect_sent_response['ResultList']: sentiments.append(res['Sentiment']) print(res['SentimentScore']) print(type(res['SentimentScore'])) for key, val in res['SentimentScore'].items(): if key == "Positive": pos_score.append(val) if key == "Negative": neg_score.append(val) if key == "Neutral": neutral_score.append(val) if key == "Mixed": mixed_score.append(val) return sentiments, pos_score, neg_score, neutral_score, mixed_scorePotresti anche voler eseguire altre operazioni di analisi, come il rilevamento di entità o il rilevamento di frasi chiave, sul testo rilevato. Potete scrivere le funzioni per eseguire queste operazioni di analisi sul testo, proprio come avete fatto per la successiva operazione di analisi del sentiment.
-
Scrivi il codice per eseguire il rilevamento delle entità sul testo rilevato.
# detect entities def entity_detection(detected_text, lang): comprehend = boto3.client("comprehend") # convert and handle string here # do string handling detect_ent_response = comprehend.batch_detect_entities( TextList=detected_text, LanguageCode=lang) # To fold detected entities and entity types ents = [] types = [] # Get detected entities and types from the response returned by Comprehend for i in detect_ent_response['ResultList']: if len(i['Entities']) == 0: ents.append("N/A") types.append("N/A") else: sentence_ents = [] sentence_types = [] for entities in i['Entities']: sentence_ents.append(entities['Text']) sentence_types.append(entities['Type']) ents.append(sentence_ents) types.append(sentence_types) return ents, types -
Scrivi il codice per eseguire il rilevamento delle frasi chiave sul testo rilevato.
# Detect key phrases def key_phrases_detection(detected_text, lang): comprehend = boto3.client("comprehend") key_phrases = [] detect_phrases_response = comprehend.batch_detect_key_phrases( TextList=detected_text, LanguageCode=lang) for i in detect_phrases_response['ResultList']: if len(i['KeyPhrases']) == 0: key_phrases.append("N/A") else: phrases = [] for phrase in i['KeyPhrases']: phrases.append(phrase['Text']) key_phrases.append(phrases) return key_phrasesDevi creare una funzione che richiami tutto il codice che hai creato finora. La funzione utilizzerà la
DocumentProcessorclasse creata nelDetectAnalyzeFileAsync.pyfile, quindi salverà il testo rilevato in una variabile da immettere nelle tre funzioni che utilizzano Amazon Comprehend che hai scritto in precedenza. La funzione dovrà anche creare un dataframe Pandas, in cui inserire il testo rilevato e i dati di analisi. Infine, il dataframe Pandas verrà salvato come file CSV. -
Scrivi il codice per elaborare i documenti di input con Textract e passa il testo rilevato a Comprehend.
def process_document(roleArn, bucket, document, region_name): # Create analyzer class from DocumentProcessor, create a topic and queue, use Textract to get text, # then delete topica and queue analyzer = DocumentProcessor(roleArn, bucket, document, region_name) analyzer.CreateTopicandQueue() extracted_text = analyzer.ProcessDocument() analyzer.DeleteTopicandQueue() # detect dominant language comprehend = boto3.client("comprehend") response = comprehend.detect_dominant_language(Text=str(extracted_text[:10])) print(response) print(type(response)) lang = "" for i in response['Languages']: lang = i['LanguageCode'] print(lang) # or you can enter language code below # lang = "en" print("Lines in detected text:" + str(len(extracted_text))) sliced_list = [] start = 0 end = 24 while end < len(extracted_text): sliced_list.append(extracted_text[start:end]) start += 25 end += 25 print(sliced_list) # Create lists to hold analytics data, these will be turned into columns all_sents = [] all_scores = [] all_ents = [] all_types = [] all_key_phrases = [] all_pos_ratings = [] all_neg_ratings = [] all_neutral_ratings = [] all_mixed_ratings = [] # For every slice, get sentiment analysis, entity detection and key phrases, append results to lists for slice in sliced_list: slice_labels, pos_ratings, neg_ratings, neutral_ratings, mixed_ratings = sentiment_analysis(slice, lang) all_sents.append(slice_labels) all_pos_ratings.append(pos_ratings) all_neg_ratings.append(neg_ratings) all_neutral_ratings.append(neutral_ratings) all_mixed_ratings.append(mixed_ratings) slice_ents, slice_types = entity_detection(slice, lang) all_ents.append(slice_ents) all_types.append(slice_types) key_phrases = key_phrases_detection(slice, lang) all_key_phrases.append(key_phrases) # List comprehension to flatten multiple lists into a single list extracted_text = [line for sublist in sliced_list for line in sublist] all_sents = [sent for sublist in all_sents for sent in sublist] all_scores = [score for sublist in all_scores for score in sublist] all_ents = [ents for sublist in all_ents for ents in sublist] all_types = [types for sublist in all_types for types in sublist] all_key_phrases = [kp for sublist in all_key_phrases for kp in sublist] all_mixed_ratings = [kp for sublist in all_mixed_ratings for kp in sublist] all_pos_ratings = [kp for sublist in all_pos_ratings for kp in sublist] all_neg_ratings = [kp for sublist in all_neg_ratings for kp in sublist] all_neutral_ratings = [kp for sublist in all_neutral_ratings for kp in sublist] print(len(extracted_text)) print(len(all_sents)) print(len(all_ents)) print(len(all_types)) print(len(all_key_phrases)) print("List of Recognized Entities:") # Create dataframe and save as CSV df = pd.DataFrame({'Sentences':extracted_text, 'Sentiment':all_sents, 'SentPosScore':all_pos_ratings, 'SentNegScore':all_neg_ratings, 'SentNeutralScore':all_neutral_ratings, 'SentMixedRatings':all_mixed_ratings, 'Entities':all_ents, 'EntityTypes':all_types,'KeyPhrases:':all_key_phrases}) analysis_results = str(document.replace(".","_") + "_" + "analysis" + ".csv") df.to_csv(analysis_results, index=False) print(df) print("Data written to file!") return extracted_text, analysis_results -
Scrivi il codice per elaborare i tuoi documenti e caricare i dati risultanti su S3. Nell'esempio di codice riportato di seguito, sostituisci il valore di
roleArncon l'ARN del ruolo che hai configurato per l'uso con Amazon Textract. Sostituisci il valore diregion_namecon la regione in cui opera il tuo account. Infine, sostituisci il valorebucket_namecon il nome del bucket S3 contenente i tuoi documenti.def main(): # Initialize S3 client and set RoleArn, region name, and bucket name s3 = boto3.client("s3") roleArn = '' region_name = '' bucket_name = '' # initialize global corpus full_corpus = [] # to hold all docs in bucket docs_list = [] # loop through docs in bucket, get names of all docs s3_resource = boto3.resource("s3") bucket = s3_resource.Bucket(bucket_name) for bucket_object in bucket.objects.all(): docs_list.append(bucket_object.key) print(docs_list) # For all the docs in the bucket, invoke document processing function, # add detected text to corpus of all text in batch docs, # and save CSV of comprehend analysis data and textract detected to S3 for i in docs_list: detected_text, analysis_results = process_document(roleArn, bucket_name, i, region_name) full_corpus.append(detected_text) print("Uploading file: {}".format(str(analysis_results))) name_of_file = str(analysis_results) s3.upload_file(name_of_file, bucket_name, name_of_file) # print the global corpus print(full_corpus) if __name__ == "__main__": main() -
Inserisci il codice procedente nella sezione in un file Python ed eseguilo.
Hai estratto con successo il testo con Amazon Textract, inviato il testo ad Amazon Comprehend per l'analisi e quindi salvato i risultati in un bucket Amazon S3.