一、前言
在之前学习的"
开源模型应用落地-工具使用篇"系列文章中,我们已经学会了如何使用向量数据库。然而,还有一个问题一直未解决,那就是如何处理文本向量。在本文中,我们将继续深入学习关于向量的知识,特别是如何处理文本向量。
二、术语
2.1、文本向量
是将文本表示为数值向量的一种方法。文本向量可以捕捉到文本的语义和语法信息,使得我们可以在向量空间中对文本进行比较、计算相似度或应用机器学习等算法进行文本分类、情感分析、机器翻译等自然语言处理任务。
常见的文本向量表示方法包括:
- One-Hot向量:将每个单词表示为一个高维向量,其中只有一个维度为1,其余维度为0。每个单词都有一个独特的向量表示。
- 词袋模型(Bag-of-Words):将文本表示为单词的计数向量。每个维度表示一个单词,向量中的值表示该单词在文本中出现的次数。
- TF-IDF向量:根据词频-逆文档频率(TF-IDF)计算每个单词在文本中的重要性,并将文本表示为TF-IDF值的向量。
- 词嵌入向量:通过将单词映射到一个低维连续向量空间中,捕捉单词之间的语义关系。常见的词嵌入模型包括Word2Vec、GloVe和FastText。
- 句子向量:将整个句子或文本表示为一个向量。这可以通过对文本中所有词嵌入向量取平均值或使用更复杂的模型(如循环神经网络或Transformer)来实现。
2.2、获取文本向量的方法
- 基于预训练模型的词嵌入:使用预训练的词嵌入模型(例如Word2Vec、GloVe或FastText)可以将每个单词映射到一个向量空间中的固定维度向量。为了获取整个文本的向量表示,可以简单地对文本中所有单词的向量取平均值或加权平均值。
- 基于深度学习的模型:使用深度学习模型(如循环神经网络(RNN)或卷积神经网络(CNN))可以学习文本的表示。这些模型可以将整个文本作为输入,并输出一个固定维度的向量表示。例如,在自然语言处理任务(如情感分析或文本分类)中,可以使用RNN或CNN模型对文本进行建模,并使用模型中最后一个隐藏层的输出作为文本的向量表示。
- 基于Transformer的模型:Transformer模型,如BERT(Bidirectional Encoder Representations from Transformers),可以学习上下文相关的词嵌入表示。BERT模型可以将整个文本作为输入,并为每个单词生成一个向量表示。为了获取整个文本的向量表示,可以使用BERT模型中的特定层的输出,例如CLS(分类)标记的输出。
- 使用已训练的向量表示:有一些已经训练好的文本向量表示可供使用,如Universal Sentence Encoder(USE)或InferSent。这些模型已经在大规模文本语料库上进行了训练,并可以将整个文本映射到一个固定维度的向量空间中。
三、技术实现
3.1、通过开源模型实现
# 下载模型文件,例如qwen模型
def loadTokenizer(model_path):tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)return tokenizerdef getVector(model_path, content):tokenizer = loadTokenizer(model_path)inputs = tokenizer(content, return_tensors='pt')# 设置打印选项,禁用科学计数法torch.set_printoptions(sci_mode=False)return inputs["input_ids"].float().numpy()[0]if __name__ == '__main__':model_path = 'E:\\model\\qwen-7b-chat'input = "今天天气晴朗,心态正好"vector = getVector(model_path,input)print(vector)
输出:
#换成baichuan的模型
if __name__ == '__main__':model_path = 'E:\\model\\baichuan2-7B-chat'input = "今天天气晴朗,心态正好"vector = getVector(model_path,input)print(vector)
输出:
3.2、通过GPT实现
# 若未安装openai包,请先执行pip install openai
# 安装其他依赖包,pip install numpy
def normalize_l2(x):x = np.array(x)if x.ndim == 1:norm = np.linalg.norm(x)if norm == 0:return xreturn x / normelse:norm = np.linalg.norm(x, 2, axis=1, keepdims=True)return np.where(norm == 0, x, x / norm)def getVector(dim,input):client = OpenAI(api_key=API_KEY)response = client.embeddings.create(model="text-embedding-3-small", input=input, encoding_format="float")cut_dim = response.data[0].embedding[:dim]norm_dim = normalize_l2(cut_dim)return norm_dimif __name__ == '__main__':dim = 128input = "今天天气晴朗,心态正好"vector = getVector(dim,input)print(type(vector))print(vector)
输出:
四、附带说明
4.1、from openai import OpenAI报错
报错原因是:openai包的版本太低,当前openai版本为0.27.0
解决方案:升级openai包
pip install openai --upgrade
4.2、生成的文本向量需要根据实际情况进行裁剪或补位,例如计算需要256维向量,生成的文本向量不足256维的情况下,需要在尾部添加占位符(通常为0)
4.3、生成的文本向量需要进行预处理(如归一化)后,才进行计算
4.4、使用GPT,则可以根据需要选择不同的模型(https://platform.openai.com/docs/guides/embeddings/embedding-models)