AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


表格数据、RAG和LLMs:通过数据表格提示改善结果
发布日期:2024-05-26 18:56:57 浏览次数: 1885 来源:机器AI学习 数据AI挖掘


LLMs 和结构化数据的挑战对于我们人类来说,将文本和表格之间的点连接起来是直观的。但对于大型语言模型(LLMs)而言,这就像试图解决一个没有所有碎片的谜题。

LLMs 被设计成以顺序方式处理文本,这意味着它们一次读取和理解一个词或一个句子的信息。这种顺序处理是它们在大量文本数据上训练的方式。然而,表格以不同的格式呈现信息。它们将数据组织成行和列,从而创建了一个多维结构。

理解这种结构要求 LLMs 采用与顺序文本不同的方法。LLMs 需要识别跨行和列的模式,理解不同数据点之间的关系,并解释标题和单元格值的含义。因为 LLMs 主要在顺序文本上进行训练,所以它们可能在解释和处理表格数据时遇到困难。这就像是要求一个习惯于阅读小说的人突然去理解和解释图表或图形;他们可能会觉得挑战性很大,因为这超出了他们通常处理信息的模式。


表格数据的常见示例我们可能会比想象中更频繁地遇到表格数据。以下是从小、中到大三种不同场景的示例:

小:每天,我们RAG平台的用户需要使用包含嵌入式小表格数据的文件来支持他们的查询,正如图1所示的例子中,文档主要包含文本和一些表格。一个关于全球销售的行业报告是小表格数据的另一个很好的例子,因为它在文本分析旁边用表格详细列出了销售数字,这些数字通常按地区和制造商细分。我们不能移除那些表格数据以简化模型的处理过程,因为它们提供了关键的背景信息。中:在某些情况下,你可能需要分析更多的表格数据,比如电子表格、CSV文件(逗号分隔值)或我们首选报告工具预先格式化的数据,如Power BI。例如,假设你在一个零售公司的营销团队工作,正在分析上季度的销售数据以识别趋势和增长机会。这些数据可能以多个数据库文件的形式出现,包含产品销售、客户人口统计和区域销售表现的信息。大:用户可能希望进行数据分析的第三种情景涉及交易数据库和多维数据集,如OLAP立方体,因为它们在分析大量复杂数据方面相比电子表格具有优势。OLAP提供快速查询性能、对复杂计算的支持以及能够跨多个维度切割和切块数据的能力。OLAP立方体更适合处理通常在交易数据库或其他大型数据集中发现的复杂性和数据量,这要求对数据信息领域有所了解。例如,如果你是一个零售连锁店,正在分析数据以提高销售业绩,你将需要SQL进行查询和OLAP立方体进行分析,以便从销售趋势和客户细分中获得洞察,从而指导库存管理和营销策略。这些表可能很大,难以分析和理解。在本文中,我们将探讨表格数据嵌入文本信息的情景。我们将处理包含十几行和几个列的小表格,所有这些都在模型的上下文窗口容量内。


让我们看看实际操作我们的例子将基于图1,它展示了世界亿万富翁名单,以供我们未来的RAG框架使用,并回答有关这个亿万富翁名单的问题。通过四个步骤,我们可以演示如何使用表格数据作为用户问题的上下文,甚至验证是否可能让模型产生错误。

准备我们的环境库

import os import sysimport pandas as pdfrom typing import List

为了便于表格显示结果,我们将使用“BeautifulTable”库,它在终端中提供了视觉上吸引人的格式(beautifultable的文档)。

!pip install beautifultablefrom beautifultable import BeautifulTable

既然我们只会处理表格,让我们探索一下camelot-py的功能,这是另一个有用的Python库。我们可以按照camelot安装说明进行操作,在依赖项安装和Ghostscript下载中的Ghostscript依赖项。

!pip install opencv-python!pip install camelot-py!pip install ghostscript
import camelot

预处理

我们将把名单(世界亿万富翁)保存为PDF,以便于我们的探索。

file_path="./World_Billionaires_Wikipedia.pdf"

下面的代码将允许我们以基本的方式清理数据,一旦它被提取为Pandas dataframe。这个程序逐页处理一个预选定的列表,并让我们可以访问一个易于操作的结构。

注意:以下代码是由作者根据Recursive Retriever + Query Engine Demo改编的。

# 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 numberdf = get_tables(file_path, pages=[3])

现在,让我们将表格数据从数据框转换为多种格式,例如:Json、CSV或Markdown等。

# prepare test seteval_df = pd.DataFrame(columns=["Data Format", "Data raw"]) # , "Question", "Answer"
# Save the data in JSON formatdata_json = df.to_json(orient='records')eval_df.loc[len(eval_df)] = ["JSON", data_json]
# Save the data as a list of dictionariesdata_list_dict = df.to_dict(orient='records')eval_df.loc[len(eval_df)] = ["DICT", data_list_dict]
# Save the data in CSV formatcsv_data = df.to_csv(index=False)eval_df.loc[len(eval_df)] = ["CSV", csv_data]
# Save the data in tab-separated formattsv_data = df.to_csv(index=False, sep='\t')eval_df.loc[len(eval_df)] = ["TSV (tab-separated)", tsv_data]
# Save the data in HTML formathtml_data = df.to_html(index=False)eval_df.loc[len(eval_df)] = ["HTML", html_data]
# Save the data in LaTeX formatlatex_data = df.to_latex(index=False)eval_df.loc[len(eval_df)] = ["LaTeX", latex_data]
# Save the data in Markdown formatmarkdown_data = df.to_markdown(index=False)eval_df.loc[len(eval_df)] = ["Markdown", markdown_data]
# Save the data as a stringstring_data = df.to_string(index=False)eval_df.loc[len(eval_df)] = ["STRING", string_data]
# Save the data as a NumPy arraynumpy_data = df.to_numpy()eval_df.loc[len(eval_df)] = ["NumPy", numpy_data]
# Save the data in XML formatxml_data = df.to_xml(index=False)eval_df.loc[len(eval_df)] = ["XML", xml_data]

现在是探索我们的测试数据的时候了。我们已经配置了一个数据集,其中每一行代表一个来自数据框的输出格式,而“Data raw”中的数据对应于我们将与生成模型一起使用的表格数据。

from pandas import option_contextwith 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)

输出

我们可以看到,“埃隆·马斯克的净资产是多少?”这个问题在Panda数据框转换过程中获得的每种表格数据格式中都得到了一致的回答。正如我们知道的那样,因为它由语义阐述组成,所以响应之间的变化是我们必须考虑的一个挑战,以便在生成最终验证指标时进行考虑。

如果我们修改我们的“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

与之前的例子一样,我们使用Pandas dataframe导出格式中的每一种作为查询的上下文。

在这个例子中,“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这样的模型提供了必要的上下文,使它们能够在更广泛的文本中生成准确和上下文相关的响应。



53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询