請求書から漫画まで!OCR+LLMで進化する文書データ構造化技術
はじめに
こんにちは、株式会社松尾研究所シニアデータサイエンティストの大西です。本記事は、松尾研究所 Advent Calendar 2024の記事です。
松尾研究所では、多くの企業と協力し、AIの社会実装に向けた研究開発を行っています。本稿では、OCRとLLM技術を活用した文書データの構造化手法についてご紹介します。
企業が保有するデータの多くは紙や非構造データとして保管されており、これを構造化するのは困難です。また、LLMを用いたRAG(Retrieval-Augmented Generation)システムを構築する際、元データが適切に構造化されていないと、正確な検索や参照が難しくなります。
今回、最適な文章データ構造化を実現する方法を調査するため、複数のOCR, LLM手法を実験して性能を比較してみました。
従来技術の課題と提案手法
OCRは、文字を認識しテキスト情報を抽出する技術です。文字情報を抽出することには優れていますが、データを構造化することが難しいという課題があります。一方で、LLMのみを用いた情報抽出では、PDFデータを画像に変換して情報を抽出します。プロンプトを工夫することでデータの構造化は可能ですが、ハルシネーションが発生したり、文字認識精度が十分でないといった欠点があります。
今回、OCRとLLMを組み合わせることで、それぞれの技術の弱点を補完できるかを検証しました。具体的には、OCRを用いて文書データから正確にテキスト情報を抽出し、LLMにテキスト情報と画像情報を入力することで構造化を行います。それぞれの手法について、請求書データや漫画のタイトル画像を用いて検証を行いました。
LLMについては2024年12月6日時点での性能を比較するために"gpt-4o-2024-08-06", "gpt-4o-2024-11-20"をそれぞれ使用しました。
参考:https://platform.openai.com/docs/models/gpt-4o#gpt-4o
OCR手法の選定
今回、実験前に5つのOCR手法を検討し主観評価により比較調査を行いました。
詳細については割愛しますが、評価の結果、Azure Document Intelligence (ADI)を利用することにしました。以後、OCR部分についてはADIと記載しています。
手法 | 主観評価 | コメント |
---|---|---|
Azure Document Intelligence | ◎ | 構造的で詳細な文字抽出が可能 |
LlamaParse | ○ | 構造化可能だが単語単位の精度が低い |
pypdfium2 | △ | 出力構造が不安定 |
Unstructured | × | 単語が重複して出力される |
PyPDF | × | 日本語対応していない |
Azure Document Intelligence(ADI)の概要と使い方
Azure Document Intelligence(ADI)は、ドキュメントやフォームからキー情報、関連値、テーブルを抽出し、構造化データとして出力するサービスです。
参考:https://learn.microsoft.com/ja-jp/training/modules/work-form-recognizer/2-what-form-recognizer
以下のプログラムを実行することで、PDFファイルから文字抽出が利用可能です。
# ライブラリのインストール
!pip install azure-ai-documentintelligence
!pip install azure-ai-formrecognizer azure-core
from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.ai.documentintelligence.models import AnalyzeResult, AnalyzeDocumentRequest
# エンドポイントとキー、OCR対象のPDFを指定
endpoint = userdata.get("ADI_ENDPOINT")
key = userdata.get("ADI_KEY")
pdf_path = "Invoice.pdf"
def get_text_from_ADI(pdf_path):
document_intelligence_client = DocumentIntelligenceClient(endpoint=endpoint, credential=AzureKeyCredential(key))
with open(pdf_path, "rb") as f:
poller = document_intelligence_client.begin_analyze_document(
"prebuilt-layout", analyze_request=f, content_type="application/octet-stream"
)
result: AnalyzeResult = poller.result()
text = ""
for page in result.pages:
for line in page.lines:
text += line.content + "\n"
return text
# PDFからテキストを抽出
text = get_text_from_ADI(pdf_path)
print(f"{text}")
オープンデータを用いた各手法の結果比較
ADI単体、LLM単体、ADI+LLMの結果を比較しました。LLMは"gpt-4o-2024-08-06", "gpt-4o-2024-11-20"をそれぞれ使用しました。
使用したデータセット
今回、請求書と漫画を例として各アルゴリズムの検証を行いました。
1. 請求書
実務でよく見られるフォーマットに近い形式での構造化精度を検証するため、文字情報や数値データ、レイアウトが含まれる典型的なビジネス文書の例として、Azureが提供するデータセットから請求書(Invoice-6.pdf)を用いました。
2. 漫画
画像と文脈性を併せ持つ資料に対するLLMの理解力を評価するため、Manga109データを用いました。プロンプトには話ごとの要約や登場人物の把握を指定しました。
Manga109-sデータセットのうち、密リターンズ(著者: 八神 健)の表紙画像を使用して検証を実施しました。
(参考)Manga109-s http://www.manga109.org/ja/download_s.html
LLMに入力するプロンプト
1. 請求書
画像とその画像から読み取ったテキストデータが入力されます。それを照らし合わせながら、以下のjson形式で出力してください。複数個のコンテンツを出力してください。コンテンツとは文章各々の塊を示します。不明な部分は「null」と出力しましょう。
---
[{
"要約": "画像全体で伝えていることを要約してください",
"日時毎の記述": "画像から抽出された日時毎の記述を指定してください",
"日時毎の価格": "日時毎の価格を指定してください",
"日時毎の割引": "日時毎の割引を指定してください",
"日時毎の各行の合計": "日時毎の各行の合計を指定してください",
"コンテンツ名": "コンテンツ名があれば指定してください",
"コンテンツ文": "コンテンツの詳細文章を指定してください",
}]
2. 漫画
画像とその画像から読み取ったテキストデータが入力されます。それを照らし合わせながら、以下のjson形式で出力してください。複数個のコンテンツを出力してください。コンテンツとは文章各々の塊を示します。不明な部分は「null」と出力しましょう。
---
[{
"#タイトル": "#毎のタイトルを指定してください",
"#要約": "#毎に画像全体で伝えていることを要約してください",
"#登場人物": "#毎の登場人物全員を指定してください",
"#著者": "#毎の著者を指定してください",,
"#セリフ": "#毎のセリフをページの順序に従って文章のまま出力してください",
}]
構造化結果
1. 請求書
まず、請求書を対象に各アルゴリズムを比較します。
ADI単体
Contoso, Ltd.
Project Statement
Date: 9/10/2020
Receipt # No .: 9876
Sold To Wingtip Toys
554 Magnolia Way
Walnut, WY, 98432
ID#: 5554443
...
$10,375
Sales Tax
3%
Total
$10,686.25
Thank you for your business!
LLM単体
model="gpt-4o-2024-08-06"
[
{
"要約": "Contoso, Ltd. は Wingtip Toys にトレーニングサービスを提供し、請求書を発行しています。",
"日時毎の記述": {
"12/5/2020": "Manager Training",
"12/10/2020": "Manager Training",
"12/11/2020": "Leadership Training"
},
"日時毎の価格": {
"12/5/2020": "$3,500",
"12/10/2020": "$3,500",
"12/11/2020": "$4,500"
},
"日時毎の割引": {
"12/5/2020": null,
"12/10/2020": null,
"12/11/2020": "25%"
},
"日時毎の各行の合計": {
"12/5/2020": "$3,500",
"12/10/2020": "$3,500",
"12/11/2020": "$3,375"
},
"コンテンツ名": "Project Statement",
"コンテンツ文": "Thank you for your business!"
}
]
model="gpt-4o-2024-11-20"
[
{
"要約": "このプロジェクト声明書では、Wingtip Toysに対して提供されたトレーニングサービスに関する請求情報を示しています。",
"日時毎の記述": {
"12/5/2020": "Manager Training",
"12/10/2020": "Manager Training",
"12/11/2020": "Leadership Training"
},
"日時毎の価格": {
"12/5/2020": "$3,500",
"12/10/2020": "$3,500",
"12/11/2020": "$4,500"
},
"日時毎の割引": {
"12/5/2020": "None",
"12/10/2020": "None",
"12/11/2020": "25%"
},
"日時毎の各行の合計": {
"12/5/2020": "$3,500",
"12/10/2020": "$3,500",
"12/11/2020": "$3,375"
},
"コンテンツ名": "Contoso, Ltd. Project Statement",
"コンテンツ文": "Sold To: Wingtip Toys, 554 Magnolia Way, Walnut, WY, 98432, ID: 5554443. Date: 9/10/2020, Receipt #: 9876. The document describes training services (Manager Training and Leadership Training) delivered on specified dates. Subtotal: $10,375, Sales Tax: 3%, Total: $10,686.25."
}
]
ADI+LLM
model="gpt-4o-2024-11-20"
[
{
"要約": "Wingtip Toysへのトレーニングサービス提供に関する請求書で、トレーニングの種類、日時、価格、割引、小計、税金、および合計金額が記載されています。",
"日時毎の記述": {
"2020-12-05": "Manager Training",
"2020-12-10": "Manager Training",
"2020-12-11": "Leadership Training"
},
"日時毎の価格": {
"2020-12-05": "$3,500",
"2020-12-10": "$3,500",
"2020-12-11": "$4,500"
},
"日時毎の割引": {
"2020-12-05": "None",
"2020-12-10": "None",
"2020-12-11": "25%"
},
"日時毎の各行の合計": {
"2020-12-05": "$3,500",
"2020-12-10": "$3,500",
"2020-12-11": "$3,375"
},
"コンテンツ名": "Contoso, Ltd. Project Statement",
"コンテンツ文": "請求日は2020年9月10日で、請求書番号9876に基づくプロジェクト明細書です。Wingtip Toysに対し、2回のManager Trainingと1回のLeadership Trainingが提供されました。Leadership Trainingには25%の割引が適用されています。小計は$10,375、税3%、最終合計は$10,686.25です。"
}
]
ADI単体では、文字情報は正しく抽出できているものの、構造化ができていません。
LLM単体では、model="gpt-4o-2024-08-06"においては、数値の誤りはないものの、日付情報や合計金額が取得できていません。model="gpt-4o-2024-11-20"では、日付や送り先等、詳細な情報が取得できています。
一方、ADI+LLMでは、網羅的に必要な情報が取得できており、より詳細に構造化されていることがわかります。
漫画
続いて、漫画についても検証してみます。
ADI単体
JUMP COMICS
ひそか
HISOKA RETURNS!
VOL.1 さらば端島密!
八神 健
JUMP COMICS
ひそか
HISOKA RETURNS!
VOL.1 さらに端島密!
八神 健
LLM単体
model="gpt-4o-2024-08-06"
[
{
"#タイトル": "密リターンズ!",
"#要約": "主人公たちが未知の冒険に挑むストーリーを描いた作品。",
"#登場人物": "男女の若いキャラクター達",
"#著者": "八神健",
"#セリフ": "null"
}
]
model="gpt-4o-2024-11-20"
[
{
"#タイトル": "密リターンズ! HISOKA RETURNS! VOL.1 さらば端島密",
"#要約": "本作は主人公・端島密が様々な事件や謎に立ち向かうストーリー漫画。巻頭から主人公とヒロインが登場し、何か重要な展開を予感させる舞台が描かれている。",
"#登場人物": "端島密、ヒロイン、他キャラクター",
"#著者": "八神健",
"#セリフ": "null"
}
]
ADI+LLM
model="gpt-4o-2024-11-20"
[
{
"#タイトル": "ひそか HISOKA RETURNS! VOL.1 さらば端島密!",
"#要約": "若い主人公たちが活躍する冒険マンガで、探偵や考古学要素が含まれたストーリーが展開される。",
"#登場人物": "少年、少女、恐竜の化石展示場で物語に関与するキャラクター",
"#著者": "八神健",
"#セリフ": "null"
},
]
LLM単体では、model="gpt-4o-2024-08-06"においてはサブタイトルを取得することができていませんでした。ADI+LLMでは、ADI自体のOCR性能が足りず、"密リターンズ、さらに端島密"と要約しており、むしろLLM単体(model="gpt-4o-2024-11-20")の方が性能が良くなっています。
上記の結果から、性能としては gpt-4o-2024-11-20 >= ADI+LLM > gpt-4o-2024-08-06 という評価となりました。OCRに使用したADIは、請求書のような定型的な文字データの抽出には優れている一方で、漫画のような手描き文字や背景と重なった文字の認識には課題があることが明らかになりました。
まとめ
OCRとLLM技術の組み合わせにより、文書データの構造化が効果的に行えることが確認されました。このアプローチは、特に請求書のような定型データにおいて高い精度で構造化を実現し、従来の手法では困難だった作業を大幅に効率化する可能性を示しています。また、GPT-4oの最新アップデートにより、OCR性能そのものが向上したことで、特定の用途ではLLM単体でも十分な構造化が可能であることがわかりました。
さらに、漫画のような非定型データや手描き文字を含む複雑な画像では、OCRの精度が課題となる一方、LLMの文脈理解力が大きな補完となることが示されました。今後は、利用ケースに応じた技術の使い分けや、より多様なデータ形式や業務要件に対応できる技術開発を進めていきたいと考えています。
興味持っていただけた方は松尾研究所について下記リンクからさらに知っていただけると幸いです。
Discussion
ADI+LLMについてはどのような方法で渡しているのでしょうか。ADIでOCRした結果+各ページの画像をLLMに渡すなどでしょうか?
大変参考になりました。自分でも色々比較してみたいです。
結果はresult.contentで取ればスッキリすると思います。
プロンプトは4oを使うなら構造化出力を使うと精度が上がるかもしれません