

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
<a name="textract-to-comprehend"></a>

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](https://aws.amazon.com/sdk-for-python/) questo tutorial. Puoi anche vedere il [GitHub repository degli esempi di AWS Documentation SDK per altri tutorial](https://github.com/awsdocs/aws-doc-sdk-examples) su Python. 

## Prerequisiti
<a name="tutorial-prerequisites"></a>

Prima di iniziare questo tutorial, dovrai installare Python e completare i passaggi necessari per [configurare Python](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/quickstart.html) SDK. AWS Oltre a ciò, assicurati di:
+ [Aver creato un account AWS e un ruolo IAM](https://docs.aws.amazon.com/rekognition/latest/dg/setting-up.html)
+ [Hai configurato correttamente le tue credenziali di accesso AWS](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html)
+ [Creato un bucket Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html)
+ [Amazon Textract è stato configurato per l'elaborazione asincrona](https://docs.aws.amazon.com/en_us/textract/latest/dg/api-async-roles.html), 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](https://docs.aws.amazon.com/comprehend/latest/dg/security-iam.html#security_iam_access-manage) 
+ 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
<a name="tutorial-step-1"></a>

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.

1. Inizia scrivendo il codice per creare un argomento Amazon SNS e una coda Amazon SQS.

   Il seguente esempio di codice crea una `DocumentProcessor` classe 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)
   ```

1. Scrivi il codice per chiamare l'`StartDocumentTextDetection`operazione e ottenere i risultati dell'operazione.

   La `DocumentProcessor` classe avrà anche bisogno di metodi per: 
   + Chiama l'`StartDocumentTextDetection`operazione
   + 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 `GetResults` metodi `ProcessDocument` and che chiamano `StartDocumentTextDetection` e 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
   ```

1. 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
<a name="tutorial-step-2"></a>

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'`BatchDetectSentiment`operazione di Amazon Comprehend per eseguire l'analisi del sentiment.

1. 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_score
   ```

   Potresti 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.

1. 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
   ```

1.  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_phrases
   ```

   Devi creare una funzione che richiami tutto il codice che hai creato finora. La funzione utilizzerà la `DocumentProcessor` classe creata nel `DetectAnalyzeFileAsync.py` file, 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.

1. 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
   ```

1. 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 `roleArn` con l'ARN del ruolo che hai configurato per l'uso con Amazon Textract. Sostituisci il valore di `region_name` con la regione in cui opera il tuo account. Infine, sostituisci il valore `bucket_name` con 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()
   ```

1. 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.