引言
在大型数据集的查询分析中,处理具有高基数(大量可能值)的类别变量常常是一个挑战。我们希望对类别列进行过滤,但通常需要指定确切的类别值。当类别值数量较少时,可以通过提示进行简单处理,但当有效值数量较多时,这些值可能无法全部装入LLM的上下文中,或者即使装入,也可能太多以至于LLM无法有效关注。本文将探讨如何解决这些问题。
主要内容
1. 设置开发环境
首先,我们需要安装和配置必要的开发环境和库:
# 安装必要的库包
%pip install -qU langchain langchain-community langchain-openai faker langchain-chroma
配置OpenAI的环境变量:
import getpass
import os
os.environ["OPENAI_API_KEY"] = getpass.getpass()
2. 数据准备
借助faker库,我们可以生成一组模拟的数据用于测试:
from faker import Faker
fake = Faker()
names = [fake.name() for _ in range(10000)]
3. 基线查询分析
使用LangChain设置基线查询分析:
from langchain_core.pydantic_v1 import BaseModel
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI
class Search(BaseModel):
query: str
author: str
system = """Generate a relevant search query for a library system"""
prompt = ChatPromptTemplate.from_messages(
[
("system", system),
("human", "{question}")
]
)
llm = ChatOpenAI(model="gpt-3.5-turbo-0125", temperature=0)
structured_llm = llm.with_structured_output(Search)
query_analyzer = {"question": RunnablePassthrough()} | prompt | structured_llm
# 使用API代理服务提高访问稳定性
以上设置可以在拼写准确的情况下进行正确的查询分析。
4. 处理高基数类别
4.1 将所有值加入提示
一种方法是将所有可能的值加入到提示中:
system = """Generate a relevant search query for a library system.
`author` attribute MUST be one of:
{authors}
Do NOT hallucinate author name!"""
base_prompt = ChatPromptTemplate.from_messages(
[
("system", system),
("human", "{question}")
]
)
prompt = base_prompt.partial(authors=", ".join(names))
query_analyzer_all = {"question": RunnablePassthrough()} | prompt | structured_llm
这可能会导致超出LLM的上下文长度限制。
4.2 创建索引选择相关值
创建一个索引来选择最相关的值:
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_texts(names, embeddings, collection_name="author_names")
def select_names(question):
_docs = vectorstore.similarity_search(question, k=10)
_names = [d.page_content for d in _docs]
return ", ".join(_names)
create_prompt = {
"question": RunnablePassthrough(),
"authors": select_names,
} | base_prompt
query_analyzer_select = create_prompt | structured_llm
4.3 使用Pydantic进行值替换
这种方法让LLM填入任意值,然后使用Pydantic进行有效值的替换:
from langchain_core.pydantic_v1 import validator
class Search(BaseModel):
query: str
author: str
@validator("author")
def double(cls, v: str) -> str:
return vectorstore.similarity_search(v, k=1)[0].page_content
corrective_structure_llm = llm.with_structured_output(Search)
corrective_query_analyzer = (
{"question": RunnablePassthrough()} | prompt | corrective_structure_llm
)
常见问题和解决方案
-
问题:上下文长度超出限制。
- **解决方案:**使用分段处理或创建索引来筛选相关值。
-
问题:查询返回不准确的结果。
- **解决方案:**使用索引选择最相关的类别值,确保提示的准确性。
总结和进一步学习资源
处理高基数类别变量的数据需要策略和工具的正确结合。以上方法展示了如何通过索引和数据验证来改进查询分析。为深入了解可以参考以下资源:
参考资料
- LangChain库文档
- OpenAI API指南
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---