Analyser des formulaires avec Document AI et Python

1. Introduction

Dans cet atelier de programmation, vous allez apprendre à utiliser l'analyseur de formulaires Document AI pour analyser un formulaire manuscrit avec Python.

Nous utiliserons par exemple un simple formulaire d'admission médicale, mais cette procédure fonctionnera avec n'importe quel formulaire généralisé compatible avec DocAI.

Prérequis

Cet atelier s'appuie sur le contenu présenté dans d'autres ateliers de programmation Document AI.

Nous vous recommandons d'effectuer les ateliers de programmation suivants avant de continuer.

Points abordés

  • Analyser et extraire des données d'un formulaire scanné à l'aide de l'analyseur de formulaires Document AI

Prérequis

  • Un projet Google Cloud
  • Un navigateur (Chrome ou Firefox, par exemple)
  • Connaissances sur Python 3

Enquête

Comment allez-vous utiliser ce tutoriel ?

Je vais le lire uniquement Je vais le lire et effectuer les exercices

Quel est votre niveau d'expérience avec Python ?

Débutant Intermédiaire Expert

Quel est votre niveau d'expérience avec les services Google Cloud ?

<ph type="x-smartling-placeholder"></ph> Débutant Intermédiaire Expert
.

2. Préparation

Pour cet atelier de programmation, nous partons du principe que vous avez terminé les étapes de configuration de Document AI décrites dans l'atelier de programmation OCR dans Document AI.

Veuillez effectuer les étapes suivantes avant de continuer :

Vous devez également installer Pandas, une bibliothèque d'analyse de données Open Source pour Python.

pip3 install --upgrade pandas

3. Créer un outil d'analyse des formulaires

Vous devez d'abord créer une instance de processeur d'analyseur de formulaires à utiliser dans Document AI Platform pour ce tutoriel.

  1. Dans la console, accédez à la page de présentation de la plate-forme Document AI.
  2. Cliquez sur Create Processor (Créer un processeur), puis sélectionnez Form ParserProcesseurs (Analyseur de formulaires).
  3. Spécifiez un nom de processeur, puis sélectionnez votre région dans la liste.
  4. Cliquez sur Créer pour créer le processeur.
  5. Copiez votre ID de processeur. Vous devrez l'utiliser ultérieurement dans votre code.

Tester le processeur dans la console Cloud

Vous pouvez tester votre processeur dans la console en important un document. Cliquez sur Upload Document (Importer un document), puis sélectionnez un formulaire à analyser. Vous pouvez télécharger et utiliser cet exemple de formulaire si vous n'en avez pas.

Formulaire médical

Votre résultat doit se présenter comme suit : Formulaire analysé

4. Télécharger le formulaire d'exemple

Nous disposons d'un exemple de document qui contient un simple formulaire d'admission médicale.

Vous pouvez télécharger le PDF à l'aide du lien suivant. Ensuite, importez-le dans l'instance Cloud Shell.

Vous pouvez également le télécharger depuis notre bucket public Google Cloud Storage à l'aide de gsutil.

gsutil cp gs://cloud-samples-data/documentai/codelabs/form-parser/intake-form.pdf .

Vérifiez que le fichier est téléchargé dans Cloud Shell à l'aide de la commande suivante:

ls -ltr intake-form.pdf

5. Extraire les paires clé/valeur de formulaire

Au cours de cette étape, vous allez utiliser l'API de traitement en ligne pour appeler le processeur d'analyse de formulaires que vous avez créé précédemment. Ensuite, vous extrairez les paires clé-valeur trouvées dans le document.

Le traitement en ligne consiste à envoyer un seul document et à attendre la réponse. Vous pouvez également utiliser le traitement par lot si vous souhaitez envoyer plusieurs fichiers ou si la taille du fichier dépasse le nombre maximal de pages pour le traitement en ligne. Pour savoir comment procéder, consultez l'atelier de programmation sur l'OCR.

Le code permettant d'envoyer une requête de traitement est identique pour tous les types de processeurs, à l'exception de leur ID.

L'objet de réponse Document contient une liste de pages du document d'entrée.

Chaque objet page contient une liste de champs de formulaire et leur emplacement dans le texte.

Le code suivant parcourt chaque page et extrait chaque clé, valeur et score de confiance. Il s'agit de données structurées qui peuvent plus facilement être stockées dans des bases de données ou utilisées dans d'autres applications.

Créez un fichier appelé form_parser.py et utilisez le code ci-dessous.

form_parser.py

import pandas as pd
from google.cloud import documentai_v1 as documentai


def online_process(
    project_id: str,
    location: str,
    processor_id: str,
    file_path: str,
    mime_type: str,
) -> documentai.Document:
    """
    Processes a document using the Document AI Online Processing API.
    """

    opts = {"api_endpoint": f"{location}-documentai.googleapis.com"}

    # Instantiates a client
    documentai_client = documentai.DocumentProcessorServiceClient(client_options=opts)

    # The full resource name of the processor, e.g.:
    # projects/project-id/locations/location/processor/processor-id
    # You must create new processors in the Cloud Console first
    resource_name = documentai_client.processor_path(project_id, location, processor_id)

    # Read the file into memory
    with open(file_path, "rb") as image:
        image_content = image.read()

        # Load Binary Data into Document AI RawDocument Object
        raw_document = documentai.RawDocument(
            content=image_content, mime_type=mime_type
        )

        # Configure the process request
        request = documentai.ProcessRequest(
            name=resource_name, raw_document=raw_document
        )

        # Use the Document AI client to process the sample form
        result = documentai_client.process_document(request=request)

        return result.document


def trim_text(text: str):
    """
    Remove extra space characters from text (blank, newline, tab, etc.)
    """
    return text.strip().replace("\n", " ")


PROJECT_ID = "YOUR_PROJECT_ID"
LOCATION = "YOUR_PROJECT_LOCATION"  # Format is 'us' or 'eu'
PROCESSOR_ID = "FORM_PARSER_ID"  # Create processor in Cloud Console

# The local file in your current working directory
FILE_PATH = "intake-form.pdf"
# Refer to https://cloud.google.com/document-ai/docs/processors-list
# for supported file types
MIME_TYPE = "application/pdf"

document = online_process(
    project_id=PROJECT_ID,
    location=LOCATION,
    processor_id=PROCESSOR_ID,
    file_path=FILE_PATH,
    mime_type=MIME_TYPE,
)

names = []
name_confidence = []
values = []
value_confidence = []

for page in document.pages:
    for field in page.form_fields:
        # Get the extracted field names
        names.append(trim_text(field.field_name.text_anchor.content))
        # Confidence - How "sure" the Model is that the text is correct
        name_confidence.append(field.field_name.confidence)

        values.append(trim_text(field.field_value.text_anchor.content))
        value_confidence.append(field.field_value.confidence)

# Create a Pandas Dataframe to print the values in tabular format.
df = pd.DataFrame(
    {
        "Field Name": names,
        "Field Name Confidence": name_confidence,
        "Field Value": values,
        "Field Value Confidence": value_confidence,
    }
)

print(df)

Exécutez votre code maintenant. Le texte extrait doit s'afficher dans votre console.

Si vous utilisez notre exemple de document, vous devriez obtenir le résultat suivant :

$ python3 form_parser.py
                                           Field Name  Field Name Confidence                                        Field Value  Field Value Confidence
0                                            Phone #:               0.999982                                     (906) 917-3486                0.999982
1                                  Emergency Contact:               0.999972                                         Eva Walker                0.999972
2                                     Marital Status:               0.999951                                             Single                0.999951
3                                             Gender:               0.999933                                                  F                0.999933
4                                         Occupation:               0.999914                                  Software Engineer                0.999914
5                                        Referred By:               0.999862                                               None                0.999862
6                                               Date:               0.999858                                            9/14/19                0.999858
7                                                DOB:               0.999716                                         09/04/1986                0.999716
8                                            Address:               0.999147                                     24 Barney Lane                0.999147
9                                               City:               0.997718                                             Towaco                0.997718
10                                              Name:               0.997345                                       Sally Walker                0.997345
11                                             State:               0.996944                                                 NJ                0.996944
...

6. Analyser des tables

L'analyseur de formulaires est également en mesure d'extraire des données de tables contenues dans des documents. Au cours de cette étape, nous allons télécharger un nouvel exemple de document et extraire les données du tableau. Étant donné que nous chargeons les données dans Pandas, elles peuvent être générées dans un fichier CSV et dans de nombreux autres formats avec un seul appel de méthode.

Télécharger l'exemple de formulaire avec Tables

Nous avons un exemple de document qui contient un exemple de formulaire et un tableau.

Vous pouvez télécharger le PDF à l'aide du lien suivant. Ensuite, importez-le dans l'instance Cloud Shell.

Vous pouvez également le télécharger depuis notre bucket public Google Cloud Storage à l'aide de gsutil.

gsutil cp gs://cloud-samples-data/documentai/codelabs/form-parser/form_with_tables.pdf .

Vérifiez que le fichier est téléchargé dans Cloud Shell à l'aide de la commande suivante:

ls -ltr form_with_tables.pdf

Extraire les données de la table

La requête de traitement des données de table est exactement la même que pour l'extraction des paires clé/valeur. La différence réside dans les champs à partir desquels nous extrayons les données dans la réponse. Les données de la table sont stockées dans le champ pages[].tables[].

Cet exemple extrait des informations à partir des lignes d'en-tête et des lignes de corps de chaque tableau et de chaque page, puis affiche le tableau et l'enregistre au format CSV.

Créez un fichier appelé table_parsing.py et utilisez le code ci-dessous.

table_parsing.py

# type: ignore[1]
"""
Uses Document AI online processing to call a form parser processor
Extracts the tables and data in the document.
"""
from os.path import splitext
from typing import List, Sequence

import pandas as pd
from google.cloud import documentai


def online_process(
    project_id: str,
    location: str,
    processor_id: str,
    file_path: str,
    mime_type: str,
) -> documentai.Document:
    """
    Processes a document using the Document AI Online Processing API.
    """

    opts = {"api_endpoint": f"{location}-documentai.googleapis.com"}

    # Instantiates a client
    documentai_client = documentai.DocumentProcessorServiceClient(client_options=opts)

    # The full resource name of the processor, e.g.:
    # projects/project-id/locations/location/processor/processor-id
    # You must create new processors in the Cloud Console first
    resource_name = documentai_client.processor_path(project_id, location, processor_id)

    # Read the file into memory
    with open(file_path, "rb") as image:
        image_content = image.read()

        # Load Binary Data into Document AI RawDocument Object
        raw_document = documentai.RawDocument(
            content=image_content, mime_type=mime_type
        )

        # Configure the process request
        request = documentai.ProcessRequest(
            name=resource_name, raw_document=raw_document
        )

        # Use the Document AI client to process the sample form
        result = documentai_client.process_document(request=request)

        return result.document


def get_table_data(
    rows: Sequence[documentai.Document.Page.Table.TableRow], text: str
) -> List[List[str]]:
    """
    Get Text data from table rows
    """
    all_values: List[List[str]] = []
    for row in rows:
        current_row_values: List[str] = []
        for cell in row.cells:
            current_row_values.append(
                text_anchor_to_text(cell.layout.text_anchor, text)
            )
        all_values.append(current_row_values)
    return all_values


def text_anchor_to_text(text_anchor: documentai.Document.TextAnchor, text: str) -> str:
    """
    Document AI identifies table data by their offsets in the entirety of the
    document's text. This function converts offsets to a string.
    """
    response = ""
    # If a text segment spans several lines, it will
    # be stored in different text segments.
    for segment in text_anchor.text_segments:
        start_index = int(segment.start_index)
        end_index = int(segment.end_index)
        response += text[start_index:end_index]
    return response.strip().replace("\n", " ")


PROJECT_ID = "YOUR_PROJECT_ID"
LOCATION = "YOUR_PROJECT_LOCATION"  # Format is 'us' or 'eu'
PROCESSOR_ID = "FORM_PARSER_ID"  # Create processor before running sample

# The local file in your current working directory
FILE_PATH = "form_with_tables.pdf"
# Refer to https://cloud.google.com/document-ai/docs/file-types
# for supported file types
MIME_TYPE = "application/pdf"

document = online_process(
    project_id=PROJECT_ID,
    location=LOCATION,
    processor_id=PROCESSOR_ID,
    file_path=FILE_PATH,
    mime_type=MIME_TYPE,
)

header_row_values: List[List[str]] = []
body_row_values: List[List[str]] = []

# Input Filename without extension
output_file_prefix = splitext(FILE_PATH)[0]

for page in document.pages:
    for index, table in enumerate(page.tables):
        header_row_values = get_table_data(table.header_rows, document.text)
        body_row_values = get_table_data(table.body_rows, document.text)

        # Create a Pandas Dataframe to print the values in tabular format.
        df = pd.DataFrame(
            data=body_row_values,
            columns=pd.MultiIndex.from_arrays(header_row_values),
        )

        print(f"Page {page.page_number} - Table {index}")
        print(df)

        # Save each table as a CSV file
        output_filename = f"{output_file_prefix}_pg{page.page_number}_tb{index}.csv"
        df.to_csv(output_filename, index=False)

Exécutez votre code maintenant. Le texte extrait doit s'afficher dans votre console.

Si vous utilisez notre exemple de document, vous devriez obtenir le résultat suivant :

$ python3 table_parsing.py
Page 1 - Table 0
     Item    Description
0  Item 1  Description 1
1  Item 2  Description 2
2  Item 3  Description 3
Page 1 - Table 1
  Form Number:     12345678
0   Form Date:   2020/10/01
1        Name:   First Last
2     Address:  123 Fake St

Le répertoire à partir duquel vous exécutez le code doit également contenir deux nouveaux fichiers CSV.

$ ls
form_with_tables_pg1_tb0.csv form_with_tables_pg1_tb1.csv table_parsing.py

7. Félicitations

Félicitations, vous avez bien extrait des données d'un formulaire manuscrit à l'aide de l'API Document AI. Nous vous encourageons à tester d'autres documents de formulaire.

Effectuer un nettoyage

Pour éviter que les ressources utilisées dans ce tutoriel soient facturées sur votre compte Google Cloud, procédez comme suit :

  • Dans la console Cloud, accédez à la page Gérer les ressources.
  • Dans la liste des projets, sélectionnez votre projet, puis cliquez sur "Supprimer".
  • Dans la boîte de dialogue, saisissez l'ID du projet, puis cliquez sur "Arrêter" pour supprimer le projet.

En savoir plus

Continuez à vous familiariser avec Document AI grâce aux ateliers de programmation suivants.

Ressources

Licence

Ce document est publié sous une licence Creative Commons Attribution 2.0 Generic.