0Pricing
AI Engineering Academy · レッスン

不完全なデータと欠損データへの対処

Optionalフィールドと信頼度スコアを含むスキーマを設計し、曖昧なドキュメント向けのフォールバック抽出戦略を実装して、信頼度の低い抽出結果を人手によるレビュー用に記録します。

「不完全なデータと欠損データへの対処」はCoddyKit上の無料AI Engineering Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Engineering Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Engineering Academyコースには全4レッスンが含まれています。

不完全なドキュメントの実態

現実のドキュメントに、スキーマが期待するすべてのフィールドが含まれていることはほとんどありません。請求書には発注番号がない場合があり、履歴書には日付が記載されていない場合があり、ニュース記事には場所が登場しない場合があります。部分データや欠損データを適切に扱えるよう抽出スキーマを設計することは、存在する情報を抽出することと同じくらい重要です。

Pydanticでのオプションフィールド

すべてのドキュメントに現れるとは限らないフィールドにはOptional[type]を指定し、デフォルト値としてNoneを設定します。Pydantic v2では、これらのフィールドはNULL許容として扱われ、情報がない場合に値を幻覚しないようモデルに指示されます。欠損データには空文字列ではなく、必ずNoneを優先してください。後続処理でフィルタリングしやすくなります。

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')

信頼度スコアの追加

抽出した各フィールドについて、値とともに信頼度スコアを追加し、モデル自身に信頼度を評価させます。両方を汎用のFieldExtractヘルパーでラップしてください。信頼度の低い抽出結果は、下流システムへ直接渡すのではなく人間のレビュアーに回すことで、気付かれない不正確なデータのリスクを減らせます。

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

センチネル値とNoneの比較

データが存在しないこと自体に意味がある場合もあります。PythonのOptionalとLiteral列挙型を組み合わせて、言及されていない、明示的になしと記載されている、不明を区別してください。この3通りの区別により、下流のコードが明示的な不在と単なる言及の欠落を同じように扱うことを防ぎ、微妙なビジネスロジックのバグを回避できます。

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

フォールバック抽出戦略

最初の抽出リクエストでNoneのフィールドが多すぎる場合は、欠損情報に特化した追跡プロンプトを試してください。関連する段落だけを部分抽出済みモデルとともに送り、空のフィールドだけを埋めるようモデルに依頼します。この2段階のアプローチにより、曖昧なドキュメントでの再現率が大幅に向上します。

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)

デフォルト値とファクトリの利用

欠損時に妥当なデフォルト値があるフィールドには、Pydanticのdefaultまたはdefault_factoryを使用します。たとえば、タグのリストはNoneではなく空のリストをデフォルトにすると、下流のコードで常に反復処理できます。欠損を明示的に示して処理する必要があるフィールドにのみ、Noneを使用してください。

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

信頼度の低い抽出結果の振り分け

信頼度がしきい値を下回る抽出結果のためにレビュ―キューを構築します。信頼度の低い結果をneeds_reviewフラグ付きで別のデータベーステーブルに保存し、社内レビューUIに表示して、人間のアノテーターが修正できるようにします。修正内容はfew-shot例としてフィードバックし、以後の抽出を改善します。

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)

曖昧なテキストスパンの処理

同じテキストから、複数の有効な方法で抽出できるフィールドがあります。たとえば、「来週の月曜日」という日付は、基準日がなければ曖昧です。モデルが使用した正確なテキストをraw_spanフィールドに保存し、正規化された値と併記してください。これにより元の根拠が保持され、抽出のデバッグがはるかに容易になります。

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

欠損フィールドのパターンのログ記録

ドキュメントのコーパス全体で、どのフィールドが最も頻繁にNoneになるかを追跡します。必須フィールドの欠損率が高い場合、そのフィールドが実際に多くのドキュメントで欠けているか、スキーマの説明がモデルを混乱させている可能性があります。ドキュメントの種類ごとに欠損パターンをログに記録すると、データ品質への効果が最も大きいスキーマ改善から優先的に対処できます。

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}%)')

複数パスにまたがる抽出結果の統合

年次報告書や長大な契約書などの複雑なドキュメントでは、マルチパス抽出戦略が最も効果的です。最初のパスでは、常に存在する信頼度の高いフィールドを抽出します。後続のパスでは、特定のセクションや段落に焦点を当て、抽出が難しいフィールドを処理します。すべてのパスの結果を1つの最終レコードに統合し、後のパスで先の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
    )

スキーマ設計のベストプラクティス

適切に設計されたスキーマは、欠損データを自然に減らします。モデルが探すべきものを正確に理解できるよう、限定的で具体的なフィールド説明を使用してください。1つのフィールドに2つの概念を組み合わせるのは避けます。抽出の指針として、Fieldの説明にexamplesを追加してください。モデルが作業しやすいスキーマは、曖昧なラベルに頼るスキーマよりも欠損フィールドがはるかに少なくなります。

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')

理解度チェック

抽出パイプラインで部分データや欠損データを扱う方法についての理解度を確認しましょう。

レッスンのまとめ

このレッスンでは、Noneをデフォルト値とするオプションフィールドによって欠損データの幻覚を防げること、信頼度スコアとレビューキューによって不確かな抽出結果へのセーフティネットを構築できること、そしてマルチパス抽出によって各パスを特定のセクションに集中させ、複雑なドキュメントでの再現率を向上できることを学びました。次は、非同期処理とキューを使って抽出をスケールさせます。

よくある質問

「不完全なデータと欠損データへの対処」レッスンは無料ですか?

はい。「不完全なデータと欠損データへの対処」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Engineering Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Engineering Academyコースには全4レッスンが含まれています。

「不完全なデータと欠損データへの対処」で何を学びますか?

Optionalフィールドと信頼度スコアを含むスキーマを設計し、曖昧なドキュメント向けのフォールバック抽出戦略を実装して、信頼度の低い抽出結果を人手によるレビュー用に記録します。 ブラウザで直接実行するハンズオンコードでAI Engineering Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

AI Engineering Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのAI Engineering Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「不完全なデータと欠損データへの対処」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このAI Engineering Academyレッスンでコードを書いて実行できますか?

はい。すべてのAI Engineering Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Instructor:Pydanticによる型付き抽出
  2. 不完全なデータと欠損データへの対処
  3. 非同期処理とキューによるバッチ処理
  4. スキーマの進化と後方互換性
← AI Engineering Academyに戻る