画像からテーブル構造の抽出を GPT4V と Instructor を使って実現する
GPT-4V を使って画像から表を抽出し、Instructor を使って表を整形するサンプルコード。Instructor 自体の docs を参照して試してます。
# ライブラリのインストール
!pip install instructor -Uqq
Instructorライブラリを使って、GPT4Vから返り値として得たいフォーマットを指定します。
from io import StringIO
from typing import Annotated, Any
from pydantic import BaseModel, BeforeValidator, PlainSerializer, InstanceOf, WithJsonSchema
import pandas as pd
def md_to_df(data: Any) -> Any:
"markdownをDataFrameに変換する"
if isinstance(data, str):
return (
pd.read_csv(
StringIO(data), # Process data
sep="|",
index_col=1,
)
.dropna(axis=1, how="all")
.iloc[1:]
.map(lambda x: x.strip())
)
return data
MarkdownDataFrame = Annotated[
InstanceOf[pd.DataFrame], # pandas DataFrame のインスタンスであることを指定
BeforeValidator(md_to_df), # 検証前に md_to_df 関数を呼び出す
PlainSerializer(lambda df: df.to_markdown()), # DataFrame をマークダウンにシリアライズする方法を定義
WithJsonSchema(
{
"type": "string", # JSON スキーマタイプを文字列として指定
"description": "The markdown representation of the table, each one should be tidy, do not try to join tables that should be seperate",
}
),
]
class Table(BaseModel):
caption: str
dataframe: MarkdownDataFrame
実行のためのclientや関数を定義。
import instructor
from openai import OpenAI
from typing import Iterable
# Apply the patch to the OpenAI client to support response_model
# Also use MD_JSON mode since the visin model does not support any special structured output mode
client = instructor.patch(OpenAI(), mode=instructor.function_calls.Mode.MD_JSON)
def extract_table(url: str) -> Iterable[Table]:
return client.chat.completions.create(
model="gpt-4-vision-preview",
response_model=Iterable[Table],
max_tokens=1800,
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": "Extract table from image."},
{"type": "image_url", "image_url": {"url": url}},
],
}
],
)
試す画像の指定
今回試す画像は以下の通り。
from IPython.display import Image
from urllib.request import urlopen
# 試す画像
url = "https://a.storyblok.com/f/47007/2400x2000/bf383abc3c/231031_uk-ireland-in-three-charts_table_v01_b.png"
Image(urlopen(url).read())
テーブルの抽出
返り値を確認します。
# テーブルの抽出
tables = extract_table(url)
for table in tables:
print(table.caption, end="\n")
print(table.dataframe)
Top 10 grossing apps in October 2023 (Ireland) for Android
App Category
Rank
1 Google One Productivity
2 Disney+ Entertainment
3 TikTok - Videos, Music & LIVE Entertainment
4 Candy Crush Saga Games
5 Tinder: Dating, Chat & Friends Social networking
6 Coin Master Games
7 Roblox Games
8 Bumble - Dating & Make Friends Dating
9 Royal Match Games
10 Spotify: Music and Podcasts Music & Audio
Top 10 grossing apps in October 2023 (Ireland) for iOS
App Category
Rank
1 Tinder: Dating, Chat & Friends Social networking
2 Disney+ Entertainment
3 YouTube: Watch, Listen, Stream Entertainment
4 Audible: Audio Entertainment Entertainment
5 Candy Crush Saga Games
6 TikTok - Videos, Music & LIVE Entertainment
7 Bumble - Dating & Make Friends Dating
8 Roblox Games
9 LinkedIn: Job Search & News Business
10 Duolingo - Language Lessons Education
無事テーブルの抽出ができました。
一回目試したときは上手く行かなかったのですが、その後は上手く行っています。
今回使ったコード
今回使ったコードになります。よかったらご活用ください。
おわりに
以上、お読みいただきありがとうございます。少しでも参考になればと思います。
もし似たようなコンテンツに興味があれば、フォローしていただけると嬉しいです:note とTwitter
関連
この記事が気に入ったらサポートをしてみませんか?