AI Engineering Academy · Lekcja

Obsługa częściowych i brakujących danych

Projektuj schematy z polami Optional i ocenami pewności, implementuj zapasowe strategie ekstrakcji dla niejednoznacznych dokumentów oraz rejestruj ekstrakcje o niskiej pewności do weryfikacji przez człowieka.

Lekcja 2 z 413 kroki

Obsługa częściowych i brakujących danych to bezpłatna lekcja AI Engineering Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej AI Engineering Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs AI Engineering Academy zawiera 4 lekcji w sumie.

Rzeczywistość niekompletnych dokumentów

Dokumenty ze świata rzeczywistego rzadko zawierają każde pole oczekiwane przez schemat. Na fakturze może brakować numeru zamówienia zakupu, w życiorysie mogą nie być podane daty, a artykuł informacyjny może nie wspominać o lokalizacji. Zaprojektowanie schematu wydobywania danych tak, aby poprawnie obsługiwał częściowe i brakujące dane, jest równie ważne jak wydobycie informacji, które są obecne.

Pola opcjonalne w Pydantic

Pola, które mogą nie występować w każdym dokumencie, należy oznaczyć jako Optional[type] i nadać im wartość domyślną None. Pydantic v2 traktuje te pola jako dopuszczające wartość null, a model otrzymuje instrukcję, aby nie halucynować wartości, gdy brakuje informacji. W przypadku brakujących danych należy zawsze preferować None zamiast pustego ciągu — ułatwia to późniejsze filtrowanie.

from pydantic import BaseModel, Field
from typing import Optional

class JobPosting(BaseModel):
    title: str
    company: str
    salary_min: Optional[float] = Field(None, description='Minimum salary if stated')
    salary_max: Optional[float] = Field(None, description='Maximum salary if stated')
    remote: Optional[bool] = Field(None, description='True if remote, False if on-site, None if unspecified')

Dodawanie ocen pewności

Należy poprosić model o ocenę własnej pewności dla każdego wydobytego pola, dodając ocenę pewności obok wartości. Obie informacje należy opakować w pomocniczy element FieldExtract. Wyniki o niskiej pewności można kierować do weryfikacji przez człowieka, zamiast przekazywać je bezpośrednio do systemów przetwarzania, co zmniejsza ryzyko cichego wprowadzania błędnych danych.

from pydantic import BaseModel
from typing import Optional

class Confident(BaseModel):
    value: Optional[str]
    confidence: float  # 0.0 to 1.0

class ContractExtract(BaseModel):
    party_a: Confident
    party_b: Confident
    effective_date: Confident
    termination_clause: Confident

Wartości sygnalizujące brak danych a None

Czasami sam brak danych ma znaczenie. Należy użyć pythonowego Optional wraz z wyliczeniem Literal, aby rozróżnić sytuacje nie wspomniano, wyraźnie stwierdzono brak i nieznane. To trójstronne rozróżnienie zapobiega traktowaniu przez kod dalszego przetwarzania wyraźnie stwierdzonego braku tak samo jak braku wzmianki, co może prowadzić do trudnych do wykrycia błędów logiki biznesowej.

from pydantic import BaseModel
from typing import Optional, Literal

class Discount(BaseModel):
    # 'none' = explicitly no discount; None = not mentioned
    discount_type: Optional[Literal['percentage', 'fixed', 'none']] = None
    discount_value: Optional[float] = None

Strategie awaryjnego wydobywania danych

Gdy podstawowe wywołanie wydobywania danych zwraca zbyt wiele pól None, należy spróbować ukierunkowanego promptu uzupełniającego, który koncentruje się konkretnie na brakujących informacjach. Należy przesłać tylko odpowiedni akapit wraz z częściowo wydobytym modelem i poprosić model o uzupełnienie wyłącznie pustych pól. Takie podejście dwuetapowe znacząco poprawia kompletność wyników w przypadku niejednoznacznych dokumentów.

def fill_missing(partial: JobPosting, raw_text: str) -> JobPosting:
    missing = [k for k, v in partial.model_dump().items() if v is None]
    if not missing:
        return partial
    prompt = f'From this text, extract ONLY these fields: {missing}.\n\n{raw_text}'
    supplement = client.chat.completions.create(
        model='gpt-4o-mini',
        response_model=JobPosting,
        messages=[{'role': 'user', 'content': prompt}]
    )
    merged = partial.model_dump()
    for field in missing:
        if getattr(supplement, field) is not None:
            merged[field] = getattr(supplement, field)
    return JobPosting(**merged)

Używanie wartości domyślnych i fabryk

W przypadku pól, dla których brak wartości ma sensowną wartość domyślną, należy użyć Pydantic default lub default_factory. Na przykład lista tagów powinna domyślnie być pustą listą zamiast None, aby kod dalszego przetwarzania zawsze mógł ją iterować. Wartość None należy rezerwować dla pól, których brak musi zostać zasygnalizowany i jawnie obsłużony.

from pydantic import BaseModel, Field
from typing import List, Optional

class Article(BaseModel):
    title: str
    author: Optional[str] = None
    tags: List[str] = Field(default_factory=list)
    word_count: Optional[int] = None
    published_date: Optional[str] = None

Kierowanie wyników o niskiej pewności do weryfikacji

Należy utworzyć kolejkę weryfikacji dla wyników wydobywania danych, których pewność jest niższa od ustalonego progu. Wyniki o niskiej pewności należy przechowywać w osobnej tabeli bazy danych z flagą needs_review, udostępnić je w wewnętrznym interfejsie weryfikacji i umożliwić adnotatorom poprawianie ich. Poprawki należy przekazywać z powrotem jako przykłady few-shot, aby poprawić przyszłe wyniki wydobywania danych.

CONFIDENCE_THRESHOLD = 0.75

def process_extraction(result: ContractExtract, doc_id: str):
    needs_review = any(
        field.confidence < CONFIDENCE_THRESHOLD
        for field in [result.party_a, result.party_b, result.effective_date]
    )
    if needs_review:
        queue_for_human_review(doc_id, result)
    else:
        store_in_production_table(doc_id, result)

Obsługa niejednoznacznych fragmentów tekstu

Niektóre pola można poprawnie wydobyć z tego samego tekstu na kilka sposobów. Na przykład data zapisana jako „następny poniedziałek” jest niejednoznaczna bez daty odniesienia. Należy użyć pola raw_span, aby zachować dokładny tekst wykorzystany przez model, obok znormalizowanej wartości. Zachowuje to oryginalny dowód i znacznie ułatwia debugowanie wydobywania danych.

from pydantic import BaseModel
from typing import Optional

class DateField(BaseModel):
    raw_span: Optional[str] = None    # exact text from document
    iso_date: Optional[str] = None    # normalized YYYY-MM-DD
    confidence: float = 1.0

class Contract(BaseModel):
    effective_date: DateField
    expiration_date: DateField

Rejestrowanie wzorców brakujących pól

Należy śledzić, które pola najczęściej przyjmują wartość None w całym korpusie dokumentów. Wysoki odsetek braków w wymaganym polu sugeruje, że albo pole rzeczywiście nie występuje w większości dokumentów, albo opis schematu wprowadza model w błąd. Rejestrowanie wzorców braków według typu dokumentu pomaga ustalić, które ulepszenia schematu będą miały największy wpływ na jakość danych.

from collections import Counter

missing_counter = Counter()

def log_missing(result):
    for field, value in result.model_dump().items():
        if value is None:
            missing_counter[field] += 1

# After processing 1000 documents:
for field, count in missing_counter.most_common(5):
    print(f'{field}: {count} missing ({100*count//1000}%)')

Łączenie wyników wydobywania z wielu przebiegów

W przypadku złożonych dokumentów, takich jak raporty roczne lub obszerne umowy, najlepiej sprawdza się strategia wydobywania wieloetapowego. W pierwszym przebiegu należy wydobyć pola o wysokiej pewności, które są zawsze obecne. W kolejnych przebiegach należy skupić się na określonych sekcjach lub akapitach, aby wydobyć trudniejsze pola. Wszystkie przebiegi należy połączyć w jeden końcowy rekord, pozwalając późniejszym przebiegom zastępować wcześniejsze wartości None.

def multi_pass_extract(pages: list) -> Invoice:
    # Pass 1: header info from first page
    header = extract_header(pages[0])
    # Pass 2: line items from middle pages
    items = []
    for page in pages[1:-1]:
        items.extend(extract_line_items(page))
    # Pass 3: totals from last page
    totals = extract_totals(pages[-1])
    return Invoice(
        vendor=header.vendor,
        invoice_number=header.invoice_number,
        line_items=items,
        total_amount=totals.total_amount
    )

Najlepsze praktyki projektowania schematów

Dobrze zaprojektowane schematy naturalnie ograniczają ilość brakujących danych. Należy używać wąskich, konkretnych opisów pól, aby model dokładnie wiedział, czego szukać. Należy unikać łączenia dwóch pojęć w jednym polu. W opisie pola należy dodawać examples, aby ułatwić wydobywanie danych. Schemat, który ułatwia modelowi pracę, będzie zawierał znacznie mniej brakujących pól niż schemat opierający się na niejasnych etykietach.

from pydantic import BaseModel, Field

class Address(BaseModel):
    street: str = Field(description='Street number and name, e.g. 123 Main St')
    city: str = Field(description='City name only, no state')
    state: str = Field(description='Two-letter US state code, e.g. CA')
    zip_code: str = Field(description='5-digit ZIP code, e.g. 94105')
    country: str = Field(default='US', description='ISO 3166-1 alpha-2 country code')

Szybki sprawdzian

Sprawdź swoją wiedzę na temat obsługi częściowych i brakujących danych w potokach wydobywania danych.

Podsumowanie rozdziału

W tym rozdziale nauczyłeś się, że pola opcjonalne z wartościami domyślnymi None zapobiegają halucynowaniu brakujących danych, oceny pewności i kolejki weryfikacji tworzą zabezpieczenie dla niepewnych wyników wydobywania danych, a wydobywanie wieloetapowe poprawia kompletność wyników w złożonych dokumentach, koncentrując każdy przebieg na określonych sekcjach. W następnej części skalujemy wydobywanie danych za pomocą przetwarzania asynchronicznego i kolejek.

Bezpłatny start

Ucz się Python dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
30
Lekcje
120

Często zadawane pytania

Czy lekcja „Obsługa częściowych i brakujących danych” jest bezpłatna?

Tak — pełny tekst „Obsługa częściowych i brakujących danych” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu AI Engineering Academy, przejdź na CoddyKit PRO. Kurs AI Engineering Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Obsługa częściowych i brakujących danych”?

Projektuj schematy z polami Optional i ocenami pewności, implementuj zapasowe strategie ekstrakcji dla niejednoznacznych dokumentów oraz rejestruj ekstrakcje o niskiej pewności do weryfikacji przez c… Ćwiczysz AI Engineering Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć AI Engineering Academy?

Nie wymagamy żadnego doświadczenia. AI Engineering Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Obsługa częściowych i brakujących danych”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji AI Engineering Academy?

Tak. Każda lekcja AI Engineering Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Instructor: ekstrakcja typowana z Pydantic
  2. Obsługa częściowych i brakujących danych
  3. Przetwarzanie wsadowe z async i kolejkami
  4. Ewolucja schematów i zgodność wsteczna
← Powrót do AI Engineering Academy