分类问题无处不在。从识别垃圾信息到为我们推荐下一个视频,我们不断依赖那些对数据进行分类的系统来简化我们的生活,而且往往是在不经意间。
传统机器学习在这方面表现出色。用足够多的示例数据训练一个模型,它就会学会有效地进行分类。
然而,有一系列现实问题中,虽然拥有一个分类模型会是理想的选择,但训练一个模型却并不实际。无论是缺乏足够的数据,还是觉得问题的复杂性不值得付出努力,训练一个定制模型并不总是有意义。
这时,像GPT、Claude等这样的大型语言模型(LLM)就派上了用场。这些强大且通用的模型可以通过提示来适应各种任务,而无需重新训练。在构建传统分类模型不切实际的情况下,LLM是理想的选择,原因如下:
LLM作为分类器
如何让LLM对你的数据进行分类?通过提示。提示大致应该像这样:
# Instruction
Hey LLM, you are a classifier.
Choose the most appropriate class and output only your classification.
There are these classes:
{classes}
# Solve
This is the input to be classified:
{input}
基于这样的提示,LLM将作为分类模型运行。这被称为零样本提示。结果会根据你的用例而有所不同,用例通常分为两类:
在训练分布内(类别1):
超出训练分布(类别2):
如果你的用例属于类别1,那么你可能会看到最先进的LLM在零样本提示下表现出色。
如果你的用例属于类别2,那么坏消息是,即使是最先进的LLM在零样本提示下也难以准确分类你的输入。好消息是,我们可以改进结果。
通过检索实现更好的分类
为了解决性能问题,特别是当任务超出LLM的训练分布时,我们可以通过向提示中添加检索来改进分类。这种方法被称为检索增强分类(RAC),它是一种将检索与分类相结合以提高LLM决策能力的方法。
在你的分类流程中加入检索,可以将LLM从一个简单的零样本分类器转变为一个更具上下文感知能力的分类器。这是通过从预先索引的数据集中检索相关信息并将其输入到提示中来实现的。这些额外的数据可以缩小问题的范围,使LLM更容易正确分类输入。
RAC如何改进分类
通过相似示例增强上下文:
从你的数据集中检索相似的示例,可以为LLM提供更多关于特定输入的上下文。这种上下文信息至关重要,尤其是在分类涉及细微差别或特定领域区分时。
例如,如果你正在将交易分类为“需求”、“愿望”和“旅行”等类别,检索以前被类似标记的交易可以通过展示过去如何对类似数据点进行分类来引导LLM走向正确的分类。
用检索到的数据修改提示:
在检索增强的设置中,提示包括相关的检索示例,这些示例有助于LLM更好地理解类别之间的决策边界。一个检索增强的提示可能看起来像这样:
# Instruction
Hey LLM, you are a classifier.
Consider the previously labeled examples when making your classification.
Choose the most appropriate class and output only your classification.
There are these classes:
{classes}
Here are some examples of previously labeled data:
{retrieved_examples}
# Solve
This is the input to be classified:
{input}
核心思想是,当LLM有相似的例子来指导其决策时,分类会变得更容易、更准确。
如何实现检索
要实现RAC,你需要建立一个检索系统。检索的实现方式可以根据你的用例最适合的方式而有所不同。一些选项包括:
虽然有多种选择,但向量搜索可能是将检索集成到你的流程中最简单的方法,特别是像Pinecone这样的全托管服务会为你处理基础设施。使用Pinecone,这个过程就像进行几次API调用一样简单。
无论采用哪种检索策略,检索系统都必须能够完成两件事:
为了将所有这些整合在一起,一个完整的RAC流程如下所示:
就这么简单。一旦检索到位,你的LLM就不再是盲目的,它现在有了相关的上下文信息,这意味着更好的结果。
案例研究:个人交易分类
交易数据概述
我使用了一组我自己的个人交易数据,这些数据被归类为以下标签:
- Assets:Discover:Main:Needs:Monthly
- Assets:Discover:Main:Needs:Groceries
- Assets:Discover:Main:Needs:Gas
- Assets:Discover:Main:Needs:Other
- Assets:Discover:Main:Wants:Monthly
- Assets:Discover:Main:Wants:Other
- Assets:Discover:Furniture
- Assets:Discover:FutureWants
- Assets:Discover:Travel
这个任务属于训练分布之外的类别。这些类别是我个人的预算类别,这意味着这些数据可能与LLM(大型语言模型)在训练中看到的任何数据都不同。
每笔交易都代表了一笔我想为了预算目的而自动分类到这些类别中的真实世界支出。标记的示例是由4个字段组成的JSON对象,例如:
{
"vendor": "AMAZON PRIME",
"day": "04",
"amount": "16.04",
"from_account": "Assets:Discover:Main:Needs:Monthly"
}
未标记的示例(也称为测试数据)缺少from_account字段,例如:
{
"vendor": "SPOTIFY",
"day": "09",
"amount": "11.76",
}
我有130个标记的交易和57个未标记的交易。
为了评估不同方法在这个分类任务上的效果,我使用了零样本提示、向量检索K-最近邻(KNN)和检索增强分类(RAC)进行了几项实验,以评估在57个未标记交易上from_account的分类准确性。
对于我的检索系统,我使用OpenAI嵌入和余弦相似度作为嵌入距离的度量,将130个标记的交易上传到Pinecone的无服务器向量数据库中。
评估:零样本
我首先测试了两个模型(GPT 4o-mini和GPT 4o)的零样本能力。
这些结果突出了零样本提示在领域特定分类任务中的局限性。虽然GPT 4o能够相当好地处理通用类别,但个性化类别显著阻碍了其性能。
评估:向量检索与KNN
在这个实验中,我使用检索系统从向量数据库中找到K个最相似的交易,并根据这些相似交易中from_account的众数来对未标记交易进行分类。换句话说,就是检索到的相似交易中哪个from_account最常见?这种方法完全依赖于检索系统,没有使用任何LLM调用。
这种方法对于更频繁出现的类别很有效,因为这些类别的相似历史交易提供了强大的分类指导。然而,对于更个性化的类别或数据较少的类别,这种方法表现不佳,因为最近邻往往不够独特,无法捕捉正确的分类。
评估:RAC
接下来,我实现了RAC,将向量检索与LLM分类相结合。在这个设置中,我使用向量嵌入来检索相似的历史交易,然后将这些检索到的上下文输入到LLM中,以协助做出更明智的分类决策。
RAC展示了其优势,特别是在零样本LLM难以准确分类的情况下。向量检索提供的额外上下文有助于消除那些仅根据交易描述难以归类的交易的歧义。
RAC为低数据和高度个性化的分类任务提供了一个实用的解决方案,为传统的自定义模型训练提供了一种灵活且有效的替代方案。
结论
如前所述,LLM是在无法训练自己的分类模型时的一个可行解决方案。RAC在零样本LLM表现不佳的情况下增强了LLM的分类能力。通过将LLM的广泛知识和语言理解与检索到的示例的特异性相结合,RAC填补了通用模型与领域特定任务之间的鸿沟。
在这个案例研究中,RAC显著提高了分类准确性,特别是对于零样本LLM难以处理的个性化类别。检索提供的额外上下文使LLM能够做出更明智的决策,有效地解决了训练分布外数据的问题。
使用像Pinecone这样的工具实施RAC的简便性以及LLM API调用的经济性使得它即使对于较小的项目也是可行的。虽然没有系统是完美的,但RAC在自动化和准确性之间提供了务实的平衡。