نحوه قرار دادن داده های کوچک جدولی هنگام کار با LLM.
نوشته ادواردو روخاس اویدو با ازکیل لانزا
فرض کنید شما یک تحلیلگر مالی هستید که در یک شرکت سرمایه گذاری کار می کنید. شغل شما شامل جلوتر بودن از روندهای بازار و شناسایی فرصت های سرمایه گذاری بالقوه برای مشتریان خود است که اغلب در مورد ثروتمندترین افراد جهان و منابع ثروت آنها کنجکاو هستند. میتوانید از یک سیستم بازیابی نسل افزوده (RAG) برای شناسایی آسان و سریع روندهای بازار، فرصتهای سرمایهگذاری و ریسکهای اقتصادی و همچنین پاسخ به سؤالاتی مانند:کدام صنعت بیشترین تعداد میلیاردر را دارد؟“یا”چگونه توزیع جنسیتی میلیاردرها در مناطق مختلف مقایسه می شود؟“
اولین قدم شما این است که برای دریافت آن اطلاعات به منبع مراجعه کنید. با این حال، همانطور که بازرسی اولیه خود را انجام می دهید، یک مشکل بالقوه را کشف می کنید. سند نه تنها شامل متن، بلکه جداول نیز می باشد!
در این پست نحوه استفاده از مدل Large Language Model (LLM) برای مصرف داده های جدولی در فرمت های مختلف را نشان خواهیم داد.
LLM ها و چالش داده های ساخت یافته
برای ما انسان ها، اتصال نقطه ها بین متن و جدول آسان است. اما برای دارندگان LLM، مانند تلاش برای حل یک پازل بدون تمام قطعات است.
LLM ها برای پردازش متن به صورت سریالی طراحی شده اند، به این معنی که آنها اطلاعات را یک کلمه یا جمله در یک زمان می خوانند و درک می کنند. این پردازش متوالی نحوه آموزش آنها بر روی حجم عظیمی از داده های متنی است. با این حال، جداول اطلاعات را در قالب متفاوتی ارائه می دهند. آنها داده ها را در ردیف ها و ستون ها سازماندهی می کنند و یک ساختار چند بعدی ایجاد می کنند.
درک این ساختار نیازمند رویکردی متفاوت به یک LLM نسبت به یک متن متوالی است. دانشجویان LLM باید الگوهای بین سطرها و ستون ها را تشخیص دهند، روابط بین نقاط داده مختلف را درک کنند و معنای هدرها و مقادیر سلول را تفسیر کنند. از آنجایی که دانشجویان LLM عمدتاً در متن متوالی آموزش می بینند، ممکن است تفسیر و دستکاری داده های جدولی برای آنها دشوار باشد. مثل این است که از کسی که عادت به خواندن رمان دارد بخواهیم ناگهان نمودارها یا نمودارها را بفهمد و تفسیر کند. ممکن است برای آنها دشوار باشد زیرا خارج از روش معمول آنها برای پردازش اطلاعات است.
نمونه های رایج داده های جدولی
ما می توانیم داده های جدولی را بیشتر از آنچه فکر می کنیم پیدا کنیم. در اینجا سه سناریو از کوچک، متوسط تا بزرگ وجود دارد:
- کم اهمیت: هر روز، کاربران پلتفرم RAG ما باید درخواست های خود را با اسنادی که حاوی داده های جدولی جاسازی شده کوچک هستند، پشتیبانی کنند، همانطور که در مثال نشان داده شده در تصویر 1 نشان داده شده است. سند عمدتاً حاوی متن و برخی جداول است. گزارش صنعت در مورد فروش جهانی نمونه خوبی دیگر از داده های جدولی کوچک است زیرا دارای تجزیه و تحلیل متن همراه با جداول جزئیات فروش است که اغلب بر اساس منطقه و سازنده تقسیم می شوند. ما نمیتوانیم این ویژگیها را حذف کنیم تا مدل خود را راحتتر مصرف کنیم، زیرا آنها زمینه مهمی را فراهم میکنند.
- پادرمیانی: در برخی شرایط، ممکن است لازم باشد مقدار بیشتری از دادههای جدولی، مانند صفحات گسترده، فایلهای CSV (مقادیر جداشده با کاما) یا دادههایی که از قبل با ابزارهای گزارشدهی مورد علاقه ما، مانند Power BI، قالببندی شدهاند، تجزیه و تحلیل کنید. به عنوان مثال، فرض کنید که شما روی یک تیم بازاریابی در یک شرکت خردهفروشی کار میکنید که دادههای فروش سه ماهه گذشته را برای شناسایی روندها و فرصتهای رشد تجزیه و تحلیل میکند. این دادهها احتمالاً بهصورت فایلهای پایگاه داده چندگانه حاوی اطلاعاتی درباره فروش محصول، جمعیتشناسی مشتری و عملکرد فروش منطقهای هستند.
- بزرگ: سناریوی سومی که در آن کاربران ممکن است بخواهند تجزیه و تحلیل داده ها را انجام دهند شامل پایگاه های داده تراکنشی و مجموعه داده های چند بعدی مانند مکعب های OLAP است، زیرا آنها مزایایی نسبت به صفحات گسترده برای تجزیه و تحلیل مقادیر زیادی از داده های پیچیده دارند. OLAP عملکرد سریع پرس و جو، پشتیبانی از محاسبات پیچیده، و توانایی برش و تقسیم داده ها در ابعاد مختلف را ارائه می دهد. مکعبهای OLAP برای مدیریت پیچیدگی و حجم دادههایی که معمولاً در پایگاههای داده تراکنش یا سایر مجموعههای داده بزرگ یافت میشوند، مناسبتر هستند، که نیاز به درک حوزه اطلاعاتی دادهها دارند. به عنوان مثال، اگر در یک زنجیره خرده فروشی کار می کنید و داده ها را برای بهبود عملکرد فروش تجزیه و تحلیل می کنید، به SQL برای پرس و جو و مکعب های OLAP برای تجزیه و تحلیل برای به دست آوردن بینش از روند فروش و تقسیم بندی مشتری برای راهنمایی مدیریت موجودی و استراتژی های بازاریابی نیاز دارید. این جداول می توانند برای تحلیل و درک عالی باشند.
در این مقاله، سناریویی را بررسی خواهیم کرد که در آن داده های جدولی در اطلاعات متنی تعبیه شده است. ما با جداول کوچک حاوی ده ها سطر و چند ستون کار خواهیم کرد که همگی در ظرفیت پنجره زمینه فرم هستند.
بیایید آن را در عمل ببینیم
مثال ما از شکل 1 که فهرستی از میلیاردرهای جهان را نشان می دهد، استفاده می کند تا به چارچوب RAG آینده وارد شود و به سؤالات مربوط به لیست میلیاردرها پاسخ دهد. تنها در چهار مرحله، میتوانیم استفاده از دادههای جدولی را به عنوان زمینه سؤالات کاربران خود نشان دهیم و حتی بررسی کنیم که آیا مدل میتواند با خطا مواجه شود یا خیر.
آماده سازی کتابخانه های محیطی ما
import os
import sys
import pandas as pd
from typing import List
برای تسهیل نمایش جدولی نتایج، از کتابخانه “BeautifulTable” استفاده می کنیم که فرمت بصری جذابی را در ترمینال ارائه می دهد (اسناد زیبا).
!pip install beautifultable
from beautifultable import BeautifulTable
از آنجایی که ما فقط با جداول کار خواهیم کرد، بیایید قابلیت های Camlot-Py، یک کتابخانه مفید دیگر برای پایتون را بررسی کنیم. ما می توانیم دستورالعمل های نصب Camlot را در نصب وابستگی ها و وابستگی Ghostscript از دانلودهای Ghostscript دنبال کنیم.
!pip install opencv-python
!pip install camelot-py
!pip install ghostscript
import camelot
در حال آماده سازی داده های ما
ما لیست (میلیاردرهای جهان) را در قالب PDF ذخیره می کنیم تا کاوش خود را تسهیل کنیم.
file_path="./World_Billionaires_Wikipedia.pdf"
کد زیر به ما این امکان را می دهد که به روشی اساسی، داده ها را پس از استخراج به عنوان یک قاب داده پاندا، پاکسازی کنیم. این روال صفحه به صفحه از یک لیست از پیش تعریف شده پردازش می کند و به ما امکان می دهد به ساختاری برسیم که کار با آن آسان تر است.
توجه: کد زیر توسط نویسنده اصلاح شده است بازیابی بازگشتی + موتور پرس و جو نمایشگر
# use camelot to parse tables
def get_tables(path: str, pages: List(int)):
for page in pages:
table_list = camelot.read_pdf(path, pages=str(page))
if table_list.n>0:
for tab in range(table_list.n):
# Conversion of the the tables into the dataframes.
table_df = table_list(tab).df
table_df = (
table_df.rename(columns=table_df.iloc(0))
.drop(table_df.index(0))
.reset_index(drop=True)
)
table_df = table_df.apply(lambda x: x.str.replace('\n',''))
# Change column names to be valid as XML tags
table_df.columns = (col.replace('\n', ' ').replace(' ', '') for col in table_df.columns)
table_df.columns = (col.replace('(', '').replace(')', '') for col in table_df.columns)
return table_df
# extract data table from page number
df = get_tables(file_path, pages=(3))
حالا بیایید داده های جدولی خود را از قاب داده به چندین فرمت تبدیل کنیم، مانند: Json، CSV، Markdown و غیره.
# prepare test set
eval_df = pd.DataFrame(columns=("Data Format", "Data raw")) # , "Question", "Answer"
# Save the data in JSON format
data_json = df.to_json(orient='records')
eval_df.loc(len(eval_df)) = ("JSON", data_json)
# Save the data as a list of dictionaries
data_list_dict = df.to_dict(orient='records')
eval_df.loc(len(eval_df)) = ("DICT", data_list_dict)
# Save the data in CSV format
csv_data = df.to_csv(index=False)
eval_df.loc(len(eval_df)) = ("CSV", csv_data)
# Save the data in tab-separated format
tsv_data = df.to_csv(index=False, sep='\t')
eval_df.loc(len(eval_df)) = ("TSV (tab-separated)", tsv_data)
# Save the data in HTML format
html_data = df.to_html(index=False)
eval_df.loc(len(eval_df)) = ("HTML", html_data)
# Save the data in LaTeX format
latex_data = df.to_latex(index=False)
eval_df.loc(len(eval_df)) = ("LaTeX", latex_data)
# Save the data in Markdown format
markdown_data = df.to_markdown(index=False)
eval_df.loc(len(eval_df)) = ("Markdown", markdown_data)
# Save the data as a string
string_data = df.to_string(index=False)
eval_df.loc(len(eval_df)) = ("STRING", string_data)
# Save the data as a NumPy array
numpy_data = df.to_numpy()
eval_df.loc(len(eval_df)) = ("NumPy", numpy_data)
# Save the data in XML format
xml_data = df.to_xml(index=False)
eval_df.loc(len(eval_df)) = ("XML", xml_data)
وقت آن است که داده های آزمایشی خود را بررسی کنیم. ما یک مجموعه داده ایجاد کردهایم که در آن هر ردیف یک قالب خروجی از قاب داده را نشان میدهد و دادههای موجود در دادههای خام با دادههای جدولی که در مدل تولیدی استفاده خواهیم کرد، مطابقت دارد.
from pandas import option_context
with option_context('display.max_colwidth', 150):
display(eval_df.head(10))
تولید:
فرم ما را برای اعتبار سنجی تنظیم کنید
بیایید یک اعلان اولیه تنظیم کنیم که به ما امکان می دهد با داده های زمینه تعامل داشته باشیم.
MESSAGE_SYSTEM_CONTENT = """You are a customer service agent that helps a customer with answering questions.
Please answer the question based on the provided context below.
Make sure not to make any changes to the context, if possible, when preparing answers to provide accurate responses.
If the answer cannot be found in context, just politely say that you do not know, do not try to make up an answer."""
قبل از اجرای آزمایشات خود با مجموعه داده جدولی، باید تنظیمات اتصال را برای مدل خود تنظیم کنیم (در این مثال از AzureOpenAI استفاده خواهیم کرد). شما باید مدارک خود را ارائه دهید.
from openai import AzureOpenAI
client = AzureOpenAI(
api_key=OAI_API_Key,
api_version=OAI_API_Version,
azure_endpoint=OAI_API_Base)
def response_test(question:str, context:str, model:str = "gpt-4"):
response = client.chat.completions.create(
model=model,
messages=(
{
"role": "system",
"content": MESSAGE_SYSTEM_CONTENT,
},
{"role": "user", "content": question},
{"role": "assistant", "content": context},
),
)
return response.choices(0).message.content
از آنجایی که ما با یک مجموعه داده کار می کنیم، جایی که هر سطر نشان دهنده یک واحد مجزا از اطلاعات زمینه است، روال تکرار زیر را پیاده سازی کرده ایم که به ما امکان می دهد یک ردیف را در یک زمان پردازش کنیم و تفسیر مدل از هر ردیف را ذخیره کنیم.
def run_question_test(query: str, eval_df:str):
questions = ()
answers = ()
for index, row in eval_df.iterrows():
questions.append(query)
response = response_test(query, str(row('Data raw')))
answers.append(response)
eval_df('Question') = questions
eval_df('Answer') = answers
return eval_df
def BeautifulTableformat(query:str, results:pd.DataFrame, MaxWidth:int = 250):
table = BeautifulTable(maxwidth=MaxWidth, default_alignment=BeautifulTable.ALIGN_LEFT)
table.columns.header = ("Data Format", "Query", "Answer")
for index, row in results.iterrows():
table.rows.append((row('Data Format'), query, row('Answer')))
return table
بیا خوش بگذرانیم!
اکنون، نقطهها را به هم وصل میکنیم، مجموعه دادهها را پردازش میکنیم، که از آن با استفاده از هر قالب دادههای جدولی به عنوان اطلاعات متنی، پاسخی دریافت میکنیم، و سپس نتایج را به صورت جدولی نمایش میدهیم.
query = "What's the Elon Musk's net worth?"
result_df1 = run_question_test(query, eval_df.copy())
table = BeautifulTableformat(query, result_df1, 150)
print(table)
تولید:
ما می توانیم ببینیم که چگونه سوال، “دارایی خالص ایلان ماسک چقدر است؟“به طور مداوم برای هر قالب داده جدولی به دست آمده هنگام تبدیل یک قاب داده پاندا پاسخ داده می شود. همانطور که می دانیم، از آنجایی که از جزئیات معنایی تشکیل شده است، تفاوت بین پاسخ ها چالشی است که ما باید هنگام ایجاد معیارهای اعتبار سنجی نهایی آن را در نظر بگیریم.
همچنین اگر متغیر “MESSAGE_SYSTEM_CONTENT” را اصلاح کنیم، میتوانیم پاسخهای مختصر یا دقیقتری دریافت کنیم.
بیایید تمرین را دوباره تکرار کنیم، این بار با یک سوال که نیاز به تفکر تحلیلی بیشتری برای مدل ما دارد.
query = "What's the sixth richest billionaire in 2023 net worth?"
result_df2 = run_question_test(query, eval_df.copy())
table = BeautifulTableformat(query, result_df2, 150)
print(table)
تولید:
As with the previous example, we have used each of the Pandas data frame export formats as a query’s information context.context for the quer
مانند مثال قبلی، ما از تمام قالبهای صادراتی قاب داده پاندا به عنوان زمینه برای پرس و جو استفاده کردیم.
در این نمونه سوال "ششمین میلیاردر ثروتمند در سال 2023 کیست؟" ثابت می کند که مدل می تواند به چیزی انتزاعی تر پاسخ دهد، به عنوان مثال "ششمین میلیاردر ثروتمند" که شامل تفکر تحلیلی بیشتر و محاسبه داده های جدولی است. هر دو چالش با ثبات عالی حل شدند
ارتباط و پراکندگی
بیایید با مدل بازی کنیم و بررسی کنیم که روتر و زمینه داده ما همانطور که انتظار داریم کار می کند.
query = "What's the Michael Jordan net worth?"
result_df3 = run_question_test(query, eval_df.copy())
table = BeautifulTableformat(query, result_df3, 150)
print(table)
تولید:
در این آزمون سوالی را مطرح کرده ایم که در چارچوب اطلاعات ارائه شده پاسخ صحیحی ندارد. هدف ما این است که اطمینان حاصل کنیم که مدل ما با توهم یا با مثبت کاذب پاسخ نمی دهد (پاسخ کاذبی که درست به نظر می رسد).
پاسخ به سوال ما “دارایی خالص مایکل جردن چقدر است؟” همانطور که انتظار داشتیم برای هر قالب داده به طور مداوم حل شد (هیچ پاسخی برای سوال وجود نداشت).
بیایید مثال دیگری بیاوریم، که ممکن است یک کاربر غیرمنتظره را با استفاده از نامی که شباهت زیادی به نام موجود در داده های جدولی دارد، گمراه کند.
query = "What's Michael Musk's net worth?"
result_df4 = run_question_test(query, eval_df.copy())
table = BeautifulTableformat(query, result_df4, 180)
print(table)
با این سوال که ” دارایی خالص مایکل ماسک چقدر است؟” در حالی که ماسک ممکن است ما را وادار کند که این سوال را اشتباه تفسیر کنیم، این مدل چالش را به طور رضایت بخشی حل کرد.
نتیجه
با دریافت دادههای جدولی کوچک از اسناد متنی، دیدیم که چگونه LLM میتواند زمینه جدول را حتی زمانی که با پرسیدن سؤالاتی حاوی اطلاعات اشتباه فریب میدهد، درک کند. بدیهی است که حفظ یکپارچگی ساختاری در حین استخراج جداول تعبیه شده در زمینه مهم است. این جداول اغلب حاوی اطلاعات زمینه ای مهمی هستند که درک متن اطراف را برای ارائه نتایج دقیق تر افزایش می دهند.
با تمرکز بر جداول کوچکتر موجود، مهم است که اهمیت آنها را در ارائه سرنخ های متنی برای چارچوب RAG خود تشخیص دهید. استفاده از کتابخانه هایی مانند Camelot برای استخراج جدول تضمین می کند که این ساختارها حفظ می شوند. با این حال، همانطور که در آزمایش مدل نشان داده شد، حفظ ارتباط بدون حواسپرتی چالشهایی را ایجاد میکند. در انجام این کار، ما زمینه ضروری را برای مدلهایی مانند GPT فراهم میکنیم، که ما را قادر میسازد پاسخهای دقیق و مرتبط با متن را در زمینههای متنی گستردهتر ایجاد کنیم.
فراخوانی برای اقدام
اگر میخواهید بیشتر کاوش کنید، مجموعهای از کتابخانههای جایگزین وجود دارند که استخراج دادههای جدولی را آسانتر میکنند، مانند Tabula، pdfplumber، pdftables و pdf-table-extract. در «مقایسه با سایر کتابخانهها و ابزارهای استخراج جدول PDF»، Vinayak Mehta یک ارزیابی عملکرد مقایسهای از کتابخانههای فهرست شده ایجاد کرده است که ممکن است برای شما مفید باشد.
درباره نویسندگان
ادواردو روجاس اویدو، مهندس پلتفرم، اینتل
Eduardo Rojas Oviedo یک توسعه دهنده اختصاصی RAG در تیم پویا و نوآور اینتل است. او در ابزارهای پیشرفته توسعه هوش مصنوعی، یادگیری ماشینی و پردازش زبان طبیعی تخصص دارد و علاقه زیادی به استفاده از فناوری برای ایجاد راه حل های تاثیرگذار دارد. تخصص ادواردو در ساخت برنامههای قدرتمند و نوآورانه نهفته است که مرزهای آنچه در دنیای هوش مصنوعی ممکن است را جابجا میکند. تعهد او به اشتراک دانش و توسعه فناوری، انگیزه ای است که در پس تعالی مستمر او در این زمینه وجود دارد.
Ezequiel Lanza، مبشر هوش مصنوعی منبع باز، اینتل
Ezequiel Lanza مبشر AI منبع باز در تیم Open Ecosystem اینتل است و علاقه زیادی به کمک به مردم برای کشف دنیای هیجان انگیز هوش مصنوعی دارد. او همچنین یک ارائه کننده مکرر در کنفرانس های هوش مصنوعی و ایجاد کننده موارد استفاده، آموزش ها و راهنماها برای کمک به توسعه دهندگان برای استفاده از ابزارهای AI منبع باز است. او دارای مدرک کارشناسی ارشد در رشته علوم داده است. آن را در X در پیدا کنید @eze_lanza و لینکدین در /eze_lanza
ما را دنبال کنید!
متوسط، پادکست، Open.intel، ایکس لینکدین
دادههای جدولی، RAGها و LLMها: بهبود نتایج با درخواست صفحهگسترده ابتدا در Intel Tech on Medium منتشر شد، جایی که افراد با برجسته کردن و پاسخ دادن به این داستان به گفتگو ادامه میدهند.