企業で扱う文書としてOfficeやPDFなど非構造化データのファイルを検索対象にする場合、全文検索に加えて文書にタグ付けをして検索時の絞り込みに使うなどの工夫が行われています。
非構造化データを構造化するためには、辞書やパターン、機械学習などの技術が使われてましたが、最近では文書の構造を理解して、事前定義なしで構造化する技術が出てきています。このような技術はRAGで基盤モデルへの入力に含めるデータの前処理として応用できます。
今回は、watsonxのテキスト抽出API(Text Extraction)を利用して、非構造化ファイルからどのような情報が抽出できるのか確認します。
環境セットアップ
- watsonx.ai Runtime Service インスタンスを作成します。 (無料プランが提供されており、インスタンスの作成方法はこちらで確認できます)
watsonx.aiのプロジェクト資産に接続を作成
今回、テキスト抽出の対象とするドキュメントは、IBM Cloud Object Storage(ICOS)に保存します。抽出されたテキストなど最終結果ファイルもICOSに保存されます。
watsonx.aiの資産に接続を作成
watsonx.aiのGUIで資産に接続を作成します。詳細はマニュアルに記載があります。

Credentialsをアクセスキーと秘密鍵にする必要があります。
テキスト抽出の作業を開始
作業はローカルPCのJupyter Notebookで行います。このノートブックではPython 3.11を使用しています
%pip install "ibm-watsonx-ai>=1.3.13" | tail -n 1
watsonx.ai の資格情報の定義
watsonxを操作するために必要な watsonx.ai 資格情報を定義します。
# IBM CloudのAPIキーを指定します
api_key = "abcDE12I-fgh3JklmnOP4qr5S6tUV_WXy78ZABCdefgh"
# locationは使用しているリージョンに置き換えてください(例: us-south、eu-gb、jp-tok)
location = "us-south"
# watsonx.aiの管理タブにあるプロジェクトIDを使用します
project_id = "a123df9f-80dd-4f37-a874-43164bc215db"
IBM CloudのAPIキーについて、詳しくは、ドキュメントを参照してください。
watsonx.ai API クライアント初期化
from ibm_watsonx_ai import Credentials
from ibm_watsonx_ai import APIClient
credentials = Credentials(
url=f"https://{location}.ml.cloud.ibm.com",
api_key=api_key,
)
client = APIClient(credentials=credentials, project_id=project_id)
環境セットアップで作成した接続資産のIDを確認します。複数表示される場合は、今回作成したNAMEのIDを使用します。
# 接続資産の一覧を表示
client.connections.list()
上記のIDを connection_asset_id 、ICOSのバケット名をbucket_nameとして指定します。
connection_asset_id = "970341a4-08ee-40a8-a82c-8c9cba524aa6"
# ICOSのバケット名を指定します
bucket_name = "watsonxx-donotdelete-pr-ythuqn61fy6tfw"
対象のファイル名と結果の保存先フォルダを指定
テキスト抽出を行う対象のファイル名を source_filename として指定します。
from ibm_watsonx_ai.helpers import DataConnection, S3Location
# ICOS上のテキスト抽出対象ファイルの名前を指定
source_filename = "PurchaseRequest.png"
document_reference = DataConnection(
connection_asset_id=connection_asset_id,
location=S3Location(bucket=bucket_name, path=source_filename)
)
# ICOS上のテキスト抽出結果の保存先フォルダの指定
results_reference = DataConnection(
connection_asset_id=connection_asset_id,
location=S3Location(bucket=bucket_name, path="text_extraction_result/") # 最後は'/'で終わる必要がある
)
ICOSに対象ファイルをアップロード
ローカルPCのフォルダにある上記で指定した対象ファイルをアップロードします。
document_reference.set_client(client)
document_reference.write(source_filename)
テキスト抽出リクエストの準備
from ibm_watsonx_ai.foundation_models.extractions import TextExtractionsV2
# テキスト抽出マネージャーを初期化
extraction = TextExtractionsV2(api_client=client, project_id=project_id)
テキスト抽出パラメータの定義
今回の例では、OCRを使用、画像の説明、キーと値のペアの抽出などを指定しています。
from ibm_watsonx_ai.metanames import TextExtractionsV2ParametersMetaNames
parameters = {
TextExtractionsV2ParametersMetaNames.MODE: "high_quality",
TextExtractionsV2ParametersMetaNames.OCR_MODE: "enabled",
TextExtractionsV2ParametersMetaNames.LANGUAGES: ["ja"],
TextExtractionsV2ParametersMetaNames.AUTO_ROTATION_CORRECTION: True,
TextExtractionsV2ParametersMetaNames.CREATE_EMBEDDED_IMAGES: "enabled_verbalization_all",
TextExtractionsV2ParametersMetaNames.OUTPUT_DPI: 72,
TextExtractionsV2ParametersMetaNames.KVP_MODE: "generic_with_semantic",
TextExtractionsV2ParametersMetaNames.SEMANTIC_CONFIG: {
"enable_generic_kvp": True,
}
}
テキスト抽出で使用可能なパラメーターについては、マニュアルを参照してください
テキスト抽出パラメータ
APIドキュメント
テキスト抽出を実行
出力形式としては、以下の5種類を指定できます。
| 出力形式 | 説明 |
|---|---|
| Markdown | タイトル, 表, 段落などをMarkdown形式で出力。画像やチャートの説明を含めることもできます。キーと値のペアのデータは含まれていません |
| JSON | すべての非構造化テキスト, テーブル, キーと値のペア, 位置情報などのデータ構造をJSON形式で出力します。 |
| HTML | タイトル, 表, 段落などのデータ構造はを、HTMLタグを使って出力。キーと値のペアのデータは含まれていません。 |
| テキスト | 構造化されていないテキストだけを出力。 結果には、テーブル, タイトル, キーと値のペアのデータは含まれません。 |
| PNG | ドキュメントの各ページを個別のPNG形式の画像で出力します。 |
今回の例では、JSON, HTML, PNG, Markdown を指定して実行してます。
from ibm_watsonx_ai.foundation_models.extractions import TextExtractionsV2ResultFormats
multiple_formats_job_details = extraction.run_job(
document_reference=document_reference,
results_reference=results_reference,
parameters=parameters,
result_formats=[
TextExtractionsV2ResultFormats.ASSEMBLY_JSON,
TextExtractionsV2ResultFormats.HTML,
TextExtractionsV2ResultFormats.PAGE_IMAGES,
TextExtractionsV2ResultFormats.MARKDOWN
]
)
multiple_formats_job_details
# ジョブIDを取得
multiple_formats_extraction_job_id = extraction.get_job_id(extraction_details=multiple_formats_job_details)
# listメソッドを使用してテキスト抽出ジョブを一覧表示できます
extraction.list_jobs()
テキスト抽出ジョブが完了するまで待つには、次のセルを実行します:
import time
while True:
time.sleep(5)
job_details = extraction.get_job_details(extraction_job_id=multiple_formats_extraction_job_id)
job_status = job_details["entity"]["results"]["status"]
if job_status != "running":
print("\n", job_status, sep="")
break
print(".", sep="", end="", flush=True)
.....
completed
抽出結果の確認
ジョブの抽出が完了したら、ICOSから結果をダウンロードします。
multiple_results_reference = extraction.get_results_reference(multiple_formats_extraction_job_id)
multiple_results_dir = "multiple_text_extraction_results"
multiple_results_reference.download_folder(local_dir=multiple_results_dir)
ダウンロードが成功すると、ファイルの内容を読み取ることができます。
今回のサンプルでは multiple_text_extraction_results フォルダが作成されて、そこに出力ファイルが保存されています。

抽出結果:JSONファイル(assembly.json)

ファイル内の表形式の内容から、キー(key)と値(value)のペアで結果を取得できています。キーはsemantic_labelとして意味的なキーもつけられています。これはフォーマットが異なる表で項目名が異なる表現でも同じキーが付けられるので、後からデータの集計や検索を行うのが容易になります。
抽出結果:Markdownファイル(assembly.md)

ファイルの構造を理解して結果を抽出できています。画像については内容の説明が行われています。グラフなどチャートがある場合は、チャートの内容の説明が出力されます。
抽出ジョブの削除
テキスト抽出ジョブを削除するには、delete_job() メソッドを使用します。
# JOB_IDを指定してジョブの削除
extraction.delete_job("fb90edfc-ec56-4bd1-8646-67c23cdd2d9a")
最後に
今回はサンプルとして画像のファイルからテキスト抽出を行いました。文書の構造や表を理解して、タイトルや作成者などをメタ情報として抽出したり、表構造の内容からはキーと値のペアで情報を抽出できることを確認しました。また画像や写真などを含む場合は、その内容の説明が行うこともできてます。
この技術は、社内に存在するOffice/PDF、グラフや写真などを含むファイルを取り込み、抽出された内容を検索やRAGの入力データとして利用することを想定しています。
テキスト抽出はAPIとして提供されているので、すでに利用しているRAGの仕組みの前処理として組み込むことも可能となっています。
参考情報
Text Extraction 製品マニュアル:
https://www.ibm.com/docs/ja/watsonx/saas?topic=generation-text-extraction
APIドキュメント:
https://cloud.ibm.com/apidocs/watsonx-ai#text-extraction
文書テキスト抽出の1ページあたりの料金:
https://www.ibm.com/docs/ja/watsonx/saas?topic=integrations-billing-details-generative-ai-assets#text-extraction


