langchain 入门指南 - 文本分片及向量化

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站

前面的内容中关于数据或者上下文的传递我们都是通过 Prompt 来完成的,而这样我们会面临以下挑战:

  1. Prompt 的内容大小限制:成本,处理耗时
  2. 使用大量数据的成本
  3. 并非所有数据都会用于解决当前问题

解决大量数据/文本的设想 - 分治

分割成数据块 -> 选取相关数据块(多次) -> 发送至大模型

如何根据用户的问题选择相关的数据块?

有一种办法就是:使用语义检索。(不同于关键词检索,关键词检索是要严格匹配上关键词才能检索,但语义检索可以检索到相关的文本)

语义检索是一种基于文本内容和意义的信息检索方法,它试图理解查询和文档的语义,
以便更准确地找到与查询相关地文档。

向量化(embedding) 是将文本数据转换为数值向量的过程。向量化后的文本可以用于计算文本之间的相似性,
如余弦相似度、欧几里得距离等度量。这使得语义检索能够根据查询和文档之间的语义相似性来对文档进行排序和检索,从而提高检索的准确性和效率。

embedding 示例 - 计算相似性

下面的例子中,我们会看到 np.dot(embedding1, embedding3) 的值是最大的,这说明 sentence1sentence3 的相似性最高。

from langchain_openai import OpenAIEmbeddings

import os
os.environ['OPENAI_API_KEY'] = "your key"
os.environ['OPENAI_BASE_URL'] = "https://api.openai-hk.com/v1"


embedding = OpenAIEmbeddings()
sentence1 = "我是一名软件工程师"
sentence2 = "小张从事法律工作"
sentence3 = "我是一名程序员"

embedding1 = embedding.embed_query(sentence1)
embedding2 = embedding.embed_query(sentence2)
embedding3 = embedding.embed_query(sentence3)

import numpy as np
print(np.dot(embedding1, embedding2))
print(np.dot(embedding1, embedding3))
print(np.dot(embedding2, embedding3))

输出:

0.7987314936103257
0.9586440032651322
0.7990728512968016

numpy.dot 方法用于在机器学习中衡量两个向量的相似度。点积越大,两个向量越相似。

处理大文本

我们可以使用如下函数对我们的文本进行切割:

def split_file_into_chunks(file_path, chunk_size):
    chunks = []
    with open(file_path, 'r', encoding='utf-8') as file:
        while True:
            chunk = file.read(chunk_size)
            if not chunk:
                break
            chunks.append(chunk)
    return chunks

print(split_file_into_chunks('service_design.txt', 100))

向量化

然后,我们可以对每个文本块进行向量化:

from langchain_openai import OpenAIEmbeddings
def embed(chunks):
    embedding = OpenAIEmbeddings()
    return [embedding.embed_query(chunk) for chunk in chunks]

embeddings = embed(split_file_into_chunks('service_design.txt', 100))

向量检索

最后,我们可以使用向量检索来找到与查询最相关的文本块:

def find_k_largest_indices(input_list, k):
    """
    input_list: 点积列表
    k: 返回前 k 个最大值的索引
    """
    sorted_indices = sorted(range(len(input_list)), key=lambda i: input_list[i], reverse=True)
    print(input_list)
    print(sorted_indices)
    return sorted_indices[:k]

def search(chunks, embeddings, top_k, txt):
    import numpy as np
    embedding = OpenAIEmbeddings(chunk_size=1)
    embedded_text = embedding.embed_query(txt)
    # 计算输入文本与每个分块的相似度
    distances = [np.dot(embedded_text, emb) for emb in embeddings]
    # 返回前 k 个最相似的分块的索引
    ret_idx = find_k_largest_indices(distances, top_k)
    return [chunks[i] for i in ret_idx]

print(search(split_file_into_chunks('service_design.txt', 100), embeddings, 3, "字段长度"))

使用向量检索到的块来作为 prompt

上面通过向量检索拿到相关的文本块之后,我们可以将这一小部分文本块作为上下文传递给大模型。
然后就可以大模型就可以根据这些文本块来回答用户的问题。

这个时候,你就可以针对你的文档内容提问题了。

from openai import OpenAI

client = OpenAI(
  api_key="your key",
  base_url="https://api.openai-hk.com/v1"
)

def answer_question_with_doc(question, chunks, embeddeds):
    relevent_chunks = search(chunks, embeddeds, 2, question)
    prompt = """
    仅通过总结以下的文字片段回答用户问题,注意保持回答的语义通顺(字数在 30 字以内)
    ---
    """
    for chunks in relevent_chunks:
        prompt = prompt + "\n'" + chunks + "'"

    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system", "content": prompt},
            {"role": "user", "content": question}
        ],
        temperature=0.9,
        max_tokens=200
    )
    return response.choices[0].message.content

print(answer_question_with_doc("如何做字段取舍", split_chunks, embeddings))

输出:

尽可能减少字段暴露,考虑敏感信息如客户地址、手机号等,斟酌是否必要暴露,若必需则考虑脱敏和加解密。

总结

在本文中,我们讨论了如何通过对文本进行切割,然后对这些文本块进行向量化处理,
最后,再对这些文本块做向量化搜索,以找到与查询最相关的文本块。
在搜索到相关的文本块之后,我们可以将这些文本块作为上下文传递给大模型,以回答用户的问题。

优点:

  1. 不用传递大量的文本作为上下文给大模型。节省成本的同时也减少了大模型的处理时间。
  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
天池大赛是国内知名的数据科学竞赛平台,零基础入门NLP - 新闻文本分类是其中的一项比赛任务。这个任务的目标是利用机器学习和自然语言处理的方法,对给定的新闻文本进行分类,即根据新闻内容判断其所属的类别。这个任务对于初学者来说是一个很好的入门项目。 在解决这个问题的过程中,我们需要首先对提供的训练数据进行探索性数据分析,了解数据的分布,词频以及类别的平衡情况。然后,我们可以进行文本预处理,包括分词、去除停用词、词干化等。接下来,可以构建特征表示,可以使用TF-IDF、Word2Vec或者其他词嵌入模型来提取文本的向量表示。在构建特征表示后,可以选择合适的机器学习算法,如朴素贝叶斯、支持向量机、深度学习等,来训练分类模型。 在进行模型训练之前,可以将数据集分为训练集和验证集,用于模型的评估和调优。我们可以使用交叉验证,调整模型的超参数,选择表现最好的模型。在模型训练完成后,可以使用测试集对模型进行评估,计算准确率、召回率和F1值等指标。最后,我们可以利用模型对给定的未知新闻文本进行分类预测。 在解决这个问题的过程中,还可以进行一些方法的优化和改进。比如,可以使用集成学习的方法,如随机森林、XGBoost或者LightGBM等,结合多个分类器的结果来提高整体的分类准确率。此外,可以尝试使用预训练的模型,如BERT等,来获得更好的特征表示。此外,还可以尝试使用深度学习网络,如卷积神经网络或者循环神经网络,来提取文本的高级语义特征。 总之,零基础入门NLP - 新闻文本分类是一个很好的机会,可以学习和应用自然语言处理的知识和技术。通过解决这个问题,我们可以深入了解文本分类的基本概念和方法,提升自己在数据科学领域的能力和竞争力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白如意i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值