在对文本进行搜索时,通常会先将文本和关键词转换为向量,然后通过余弦公式对向量进行内积,通过比对得到最合适的内容。
本篇文章分为四部分:
(1)搜索的文本向量化
(2)搜索的关键词向量化
(3)使用Tf-idf算法计算每个词的词频
(4)余弦公式计算向量
一、定义数据,使用jieba对数据进行分词,再将数据向量化处理。
(1)、先对data数据进行遍历使用jieba放入集合中,得到词表
(2)、将词表转换成字典以便后续进行向量化
# -*- coding: utf-8 -*-
import math
import faiss
import jieba
import numpy as np
# 构造数据集
data = [
"团体保险一投保信息 团体业务需要的客户基本信息 投保单上所需要的基本信息(投保人名称、业务 性质等) 客户的员工人数、年龄分布、性别、职级、工种 工作地点、有无社保 既往的方案、赔付信息 团体业务需要的保险计划信息 投保的计划 计划对应的人员类型及人数、险种、保障、 保费 生效时间、保险期间、保费付费方式、其他 相关约定",
"我们的利益收关方 渠道 客户EVENT事件管理 市场 合规 客户 风控 TPA 审计 集团 运营 保单生命周期管理 财务 监管 产品 IT 精算",]
# 数据预处理
processed_data = set() # set是一个可变、无序且不重复的集合类型。它是内置的集合数据类型之一,用于存储多个唯一的元素。
for doc in data: #遍历data中每一行
doc = doc.lower().split(' ')
for word in doc:#遍历每一行的word
processed_word = jieba.lcut(word,cut_all=False) #用jieba对当前单词进行分词处理
for x in processed_word:
processed_data.add(x) # 将处理结果存入集合
# print(processed_data)
#使用dict(zip(key,value))方法将分词结果存入字典
dictionary = dict(zip(processed_data,range(len(processed_data))))
#也可以用循环放入字典
# for word in processed_data:
# if word not in dictionary:
# dictionary[word] = len(dictionary)
# print(dictionary)
#定义词表向量
vectors = []
for doc in data:
vector = [0] * len(dictionary)#定义向量长度
# print(vector)
for word in dictionary:
if word in doc:
vector[dictionary[word]] += 1
vectors.append(vector)#记录data中每一行词频所在位置
# print(vectors)
vectors = np.array(vectors, dtype=np.float32)
dictionary运行结果为:
vectors运行结果为(每一行的长度都为词表的长度,1代表该位置的word在词表中存在):
二、定义查找内容,对其向量化(要注意查询向量的长度要与词表长度一直,否内无法计算向量距离)
# # 定义查询向量
query = "投保信息"
# 预处理查询向量
processed_query = query.lower()
# 将查询向量转换为向量表示
query_vector = [0] * len(dictionary) #定义搜索向量长度
# print(query_vector)
for word in dictionary:
if word in processed_query:
query_vector[dictionary[word]] += 1 #遍历搜索向量
# print(query_vector)
query_vector = np.array([query_vector], dtype=np.float32)
查找向量的运行结果:
(3)、使用Tf-idf算法中idf计算词频大小
idf_word=[] #定义一个空列表
for word in dictionary:
cnt=0
for doc in data:
if word in doc:
cnt += 1
idf_word.append(math.log(len(data)/(cnt+1))) #使用Tf-idf方法计算每个词频大小放入列表中
# print(idf_word)
Tf-idf算法公式:
(4)、使用余弦距离公式,求解最优距离
#创建data字典,用于关键词搜索
doc2vec = dict(zip(data,vectors))
# print(doc2vec)
max_op7=float("-inf") #定义一个负无穷大
ans_v=[0] * len(dictionary)
for search in vectors:
search *= np.array(idf_word) #tf-idf计算词频后与词表向量内积
query_vector *= np.array(idf_word) #Tf-idf计算词频后与搜索向量内容
#余弦公式计算向量之间距离
op7 = np.dot(search, query_vector.reshape(-1,1)) / (np.linalg.norm(search) * (np.linalg.norm(query_vector.reshape(-1,1))))
print(op7)
if op7>max_op7:
max_op7,ans_v=op7,search #比较各个向量之间的距离
ans = ''
# print(ans_v)
for x in doc2vec:#遍历字典doc2vec中的value
# print(x)
if (doc2vec[x]==np.array(ans_v)).all():#如果对比后的ans_v向量的key与doc2vec的向量想等就存放他的value
ans = x
print("搜索查询:", query)
print("最近邻文档:")
print(ans)
最终结果: