如何处理高基数类别数据进行查询分析

50 阅读3分钟

引言

在大型数据集的查询分析中,处理具有高基数(大量可能值)的类别变量常常是一个挑战。我们希望对类别列进行过滤,但通常需要指定确切的类别值。当类别值数量较少时,可以通过提示进行简单处理,但当有效值数量较多时,这些值可能无法全部装入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---