Document AI ile Form Ayrıştırma (Python)

1. Giriş

Bu codelab'de, Python ile el yazısıyla doldurulmuş bir formu ayrıştırmak için Document AI Form Ayrıştırıcı'yı kullanmayı öğreneceksiniz.

Örnek olarak basit bir tıbbi kayıt formu kullanacağız ancak bu prosedür, DocAI tarafından desteklenen tüm genel formlarla çalışır.

Ön koşullar

Bu codelab, diğer Document AI codelab'lerinde sunulan içeriklere dayanmaktadır.

Devam etmeden önce aşağıdaki Codelab'leri tamamlamanız önerilir.

Neler öğreneceksiniz?

  • Document AI Form Parser'ı kullanarak taranmış bir formdaki verileri ayrıştırma ve ayıklama

Gerekenler

  • Google Cloud projesi
  • Chrome veya Firefox gibi bir tarayıcı
  • Python 3 bilgisi

Anket

Bu eğitimi nasıl kullanacaksınız?

Yalnızca okuyun Okuyun ve alıştırmaları tamamlayın

Python ile ilgili deneyiminizi nasıl değerlendirirsiniz?

Yeni başlayan Orta düzey Uzman

Google Cloud hizmetlerini kullanma deneyiminizi nasıl değerlendirirsiniz?

Başlangıç Orta İleri

2. Kurulum ve Gereksinimler

Bu codelab'de, Document AI OCR Codelab'de listelenen Document AI kurulum adımlarını tamamladığınız varsayılır.

Lütfen devam etmeden önce aşağıdaki adımları tamamlayın:

Python için bir Açık Kaynak Veri Analizi kitaplığı olan Pandas'ı da yüklemeniz gerekir.

pip3 install --upgrade pandas

3. Form ayrıştırıcı işlemcisi oluşturma

Bu eğitimde Document AI Platform'da kullanmak üzere öncelikle bir Form Ayrıştırıcı işlemci örneği oluşturmanız gerekir.

  1. Konsolda Document AI Platform'a Genel Bakış sayfasına gidin.
  2. İşlemci Oluştur'u tıklayın ve Form Ayrıştırıcı'yı seçin.İşlemciler
  3. Bir işlemci adı belirtin ve listeden bölgenizi seçin.
  4. İşleyicinizi oluşturmak için Oluştur'u tıklayın.
  5. İşlemci kimliğinizi kopyalayın. Bunu daha sonra kodunuzda kullanmanız gerekir.

İşlemciyi Cloud Console'da test etme

Bir belge yükleyerek işlemcinizi konsolda test edebilirsiniz. Doküman Yükle'yi tıklayın ve ayrıştırılacak bir form seçin. Kullanabileceğiniz bir form yoksa bu örnek formu indirip kullanabilirsiniz.

Sağlık Formu

Çıkışınız şu şekilde görünmelidir: Ayrıştırılmış Form

4. Örnek Formu İndirme

Basit bir tıbbi anamnez formu içeren örnek bir dokümanımız var.

PDF'yi aşağıdaki bağlantıyı kullanarak indirebilirsiniz. Ardından Cloud Shell örneğine yükleyin.

Alternatif olarak, gsutil kullanarak herkese açık Google Cloud Storage paketimizden de indirebilirsiniz.

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

Aşağıdaki komutu kullanarak dosyanın Cloud Shell'e indirildiğini onaylayın:

ls -ltr intake-form.pdf

5. Form Anahtarı/Değer Çiftlerini Ayıklama

Bu adımda, daha önce oluşturduğunuz form ayrıştırıcı işlemcisini çağırmak için online işleme API'sini kullanacaksınız. Ardından, belgedeki anahtar/değer çiftlerini ayıklarsınız.

Online işleme, tek bir belge göndermek ve yanıtı beklemek için kullanılır. Birden fazla dosya göndermek istiyorsanız veya dosya boyutu çevrimiçi işleme için maksimum sayfa sayısını aşıyorsa toplu işlemeyi de kullanabilirsiniz. Bunu nasıl yapacağınızı OCR Codelab'den öğrenebilirsiniz.

İşlem isteği oluşturma kodu, İşlemci Kimliği dışında her işlemci türü için aynıdır.

Document yanıt nesnesi, giriş dokümanındaki sayfaların listesini içerir.

Her page nesnesi, form alanlarının ve metindeki konumlarının listesini içerir.

Aşağıdaki kod, her sayfayı yineler ve her anahtarı, değeri ve güven puanını çıkarır. Bu, veritabanlarında daha kolay depolanabilen veya diğer uygulamalarda kullanılabilen yapılandırılmış verilerdir.

form_parser.py adlı bir dosya oluşturun ve aşağıdaki kodu kullanın.

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)

Kodunuzu şimdi çalıştırın. Metnin çıkarılıp konsolunuza yazdırıldığını görmelisiniz.

Örnek dokümanımızı kullanıyorsanız aşağıdaki çıkışı görürsünüz:

$ 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. Tabloları Ayrıştırma

Form Ayrıştırıcı, dokümanlardaki tablolardan da veri ayıklayabilir. Bu adımda yeni bir örnek doküman indirecek ve tablodaki verileri çıkaracağız. Verileri Pandas'a yüklediğimiz için bu veriler tek bir yöntem çağrısıyla CSV dosyasına ve diğer birçok biçime aktarılabilir.

Tabloları içeren örnek formu indirin

Örnek form ve tablo içeren bir örnek dokümanımız var.

PDF'yi aşağıdaki bağlantıyı kullanarak indirebilirsiniz. Ardından Cloud Shell örneğine yükleyin.

Alternatif olarak, gsutil kullanarak herkese açık Google Cloud Storage paketimizden de indirebilirsiniz.

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

Aşağıdaki komutu kullanarak dosyanın Cloud Shell'e indirildiğini onaylayın:

ls -ltr form_with_tables.pdf

Tablo Verilerini Ayıklama

Tablo verileri için işleme isteği, anahtar/değer çiftlerini çıkarma isteğiyle tamamen aynıdır. Aradaki fark, yanıttaki verileri hangi alanlardan çıkardığımızdır. Tablo verileri pages[].tables[] alanında saklanır.

Bu örnekte, her tablo ve sayfa için tablo başlığı satırlarından ve gövde satırlarından bilgiler ayıklanır, ardından tablo yazdırılır ve CSV dosyası olarak kaydedilir.

table_parsing.py adlı bir dosya oluşturun ve aşağıdaki kodu kullanın.

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)

Kodunuzu şimdi çalıştırın. Metnin çıkarılıp konsolunuza yazdırıldığını görmelisiniz.

Örnek dokümanımızı kullanıyorsanız aşağıdaki çıkışı görürsünüz:

$ 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

Ayrıca, kodu çalıştırdığınız dizinde iki yeni CSV dosyası da olmalıdır.

$ ls
form_with_tables_pg1_tb0.csv form_with_tables_pg1_tb1.csv table_parsing.py

7. Tebrikler

Tebrikler, el yazısıyla doldurulmuş bir formdan veri ayıklamak için Document AI API'yi başarıyla kullandınız. Diğer form belgeleriyle denemeler yapmanızı öneririz.

Temizleme

Bu eğiticide kullanılan kaynaklar için Google Cloud hesabınızın ücretlendirilmesini istemiyorsanız:

  • Cloud Console'da Kaynakları yönetin sayfasına gidin.
  • Proje listesinde projenizi seçin ve Sil'i tıklayın.
  • İletişim kutusunda proje kimliğini yazın ve projeyi silmek için Kapat'ı tıklayın.

Daha Fazla Bilgi

Aşağıdaki takip Codelab'leriyle Document AI hakkında bilgi edinmeye devam edin.

Kaynaklar

Lisans

Bu çalışma, Creative Commons Attribution 2.0 Genel Amaçlı Lisans ile lisans altına alınmıştır.