【NLP 30、文本匹配任务 —— 传统机器学习算法】
目录
一、文本匹配任务的定义
1.狭义解释
2.广义解释
二、文本匹配的应用
1.问答对话
2.信息检索
3.文本匹配任务应用
三、智能问答
1.智能问答的基本思路
依照基础资源划分:
依照答案产出方式划分
依照NLP相关技术划分
四、智能问答的价值
1.智能客服
2.Faq知识库问答
总结
3.相关名词
① 问答对
② faq库 / 知识库
③ 标准问
④ 相似问/扩展问
⑤ 用户问
⑥ 知识加工
4.Faq知识库示例
5.运行逻辑
6.算法核心
五、文本匹配算法Ⅰ —— 编辑距离
🚀 代码实现
思路与算法
1.初始化矩阵:
2.填充矩阵:
3.计算相似度:
优缺分析
优点:
缺点:
六、文本匹配算法 Ⅱ —— Jaccard相似度
代码实现
优缺分析
优点:
缺点:
适用场景:
七、文本匹配算法 Ⅲ —— BM25算法
TF·IDF算法
BM25算法
词的重要性(IDF)
词与文档的相关性(TF)
词与查询的相关性(可选)
参数设置
优缺分析
优点:
缺点:
代码实现
Ⅰ、超参数定义
Ⅱ、初始化方法
Ⅲ、根据语料库构建倒排索引并计算每个词的IDF值
Ⅳ、计算文档集合中平均每篇文档的词数
Ⅴ、计算查询query 与 某篇文档的相关性得分
Ⅵ、计算查询与所有文档的相关性得分
Ⅶ、完整的BM25算法实现
八、文本匹配算法 Ⅳ —— word2vec
1.什么是向量
2.什么是词向量
3.词向量的特点
4.词向量是如何寻得到的
5.如何训练/训练目标
6.训练提速技巧
7.如何用于文本匹配
8.优缺分析
优点:
缺点:
后来时间平静又强大,替我揭穿和筛选
—— 25.1.29
一、文本匹配任务的定义
1.狭义解释
给定一组文本,判断其语义是否相似
相似的:今天天气不错 match 今儿个天不错呀
非相似:今天天气不错 match 你的代码有BUG
以分值形式给出相似度
今天天气不错 match 今儿个天不错呀 0.9
今天天气不错 match 这几天天气不错 0.7
今天天气不错 match 你的代码有bug 0.1
2.广义解释
给定一组文本,计算某种自定义的关联度
① Natural Language Inference 自然语言推理
两句话判断是否有关联、矛盾、中立关系
eg:明天要下雨 vs 明天大晴天
② Text Entailment 文本内容
给出一段文本,和一个假设,判断文本是否能支持或反驳这个假设
主题判断、文章标题匹配内容等
二、文本匹配的应用
1.问答对话
智能客服、车载导航、手机助手、聊天机器人、智能音箱
2.信息检索
各种 APP / 网页 的搜索功能
3.文本匹配任务应用
短文本 vs 短文本:知识库问答 ,聊天机器人等
短文本 vs 长文本:文章检索,广告推荐等
长文本 vs 长文本:新闻、文章的关联推荐等
三、智能问答
1.智能问答的基本思路
① 基础资源:包括faq库,书籍文档,网页,知识图谱等等
② 问答系统:对基础资源进行了加工处理,形成问答所需要的索引和模型等
③ 用户输入问题
④ 回答系统给出答案
依照基础资源划分:
1)基于faq(热点问题)知识库的问答【以文本匹配方式为主】
2)基于文档 / 网页 / 书籍的问答【大模型RAG的方式进行问答】
3)基于图像/视频的问答【基于多模态模型的问答】
4)基于知识图谱的问答
5)基于表格的问答
6)基于特定领域知识的问答
7)基于人工规则的问答 …
依照答案产出方式划分
1)检索式的回答
答案原文或答案的多个片段存在于基础资源中(答案是事先准备好的)
2)生成式的问答
答案文本不存在于基础资源,由问答系统来生成答案(由系统模型生成)
3)二者结合
依照NLP相关技术划分
1)单轮问答(一问一答)
2)多轮问答(关联多轮问答信息)
3)多语种问答(多种语言)
4)事实性问答(明确存在唯一正确的答案,用检索式方式回答较多)
5)开放性问答(有不同的看法,用生成式方式回答较多)
6)多模态问答(与图像、视频相结合)
7)选择型问答(在几个答案中选取一个)
8)抽取式问答
9)生成式问答
……
四、智能问答的价值
1.智能客服
人工客服的局限:① 响应慢 ② 服务时间有限 ③ 业务知识有限 ④ 流动性大,培训新人成本高 ⑤ 离职了就带走了业务回答经验 ⑥ 回复内容不一样,容易造成矛盾
智能客服的优势:① 毫秒级响应② 全年24小时在线 ③ 精通所有业务知识 ④ 只需培养管理员 ⑤ 保存所有业务回答数据 ⑥ 回复内容标准
2.Faq知识库问答
Faq = Frequently asked Questions:常见问题 / 热点问题
智能客服通常做一些 Faq 的问答
总结
Faq知识库问答:列表展示所有常见问题,用户需要自己找到对应的问题,对用户不友好
希望的改进:让用户以自然语言描述自己的问题,算法进行 Faq 库的检索,给出对应的答案
3.相关名词
① 问答对
一个(或多个相似的)问题与它对应的答案
② faq库 / 知识库
很多问答对组成的集合
③ 标准问
每组问答对中的问题有多个时,选一对为其中代表
④ 相似问/扩展问
一组问答对中,标准问之外的其他问题,对标准问的扩充
⑤ 用户问
用户真正输入的问题,而不是事先准备的
⑥ 知识加工
人工编辑 faq 库的过程
4.Faq知识库示例
5.运行逻辑
① 对用户问题进行预处理:分词、去停用词、去标点、大小写转换、全半角转换,按需处理
② 使用处理后的问题,与faq库中的问题计算相似度
③ 按照相似度分值排序
④ 返回最相似问题对应的答案
6.算法核心
语义相似度计算 是 faq 问答的核心
一般简称文本匹配 f(x,y) —> Score
相似度分值合理,才可以找到正确的对应问题
计算分值的同时,也要考虑速度
思考:可不可以不通过相似度计算,匹将用户问题配知识库中最相似的问题,再通过知识库中的问题匹配对应的答案,而是直接训练一个模型,匹配用户问题与知识库中答案之间的相似度
事实上,在实际场景中,答案的格式不是固定的,如果直接匹配,如果和知识库中的问题匹配,则问题对应的答案可以是多样、多种渠道的,如果直接用问题与答案匹配,则只需要一个计算文本相似度之间的模型即可
五、文本匹配算法Ⅰ —— 编辑距离
编辑距离:两个字符串之间,由一个转成另一个所需的最少编辑操作次数
许可的编辑操作(替换、插入、删除)包括将一个字符替换成另一个字符,插入一个字符,删除一个字符
例:
相似度计算公式:
ED:编辑距离 L:字符串长度
1 - 两个字符串之间替换、插入、删除的编辑操作次数 / 两字符串的最大长度,得到两个字符串的相似度
两个字符串完全一致:编辑距离 = 0,相似度 = 1
两个字符串完全不一致:编辑距离 = 较长者长度,相似度 = 0
🚀 代码实现
思路与算法
1.初始化矩阵:
1.matrix 是一个二维数组,大小为 (len(string1) + 1) x (len(string2) + 1)
2.第一行和第一列分别初始化为 0 到 len(string1) 和 0 到 len(string2),表示从一个空字符串转换到目标字符串所需的操作次数
2.填充矩阵:
对于每个字符 string1[i - 1] 和 string2[j - 1],如果它们相等,则 d=0,否则 d=1。
matrix[i][j] 的值通过以下公式计算:
matrix[i][j] = min(matrix[i−1][j] + 1, matrix[i][j−1] + 1,matrix[i−1][j−1] + d)
其中,
matrix[i - 1][j - 1] + d 表示 替换操作(如果字符不同,则 d=1)
matrix[i][j - 1] + 1表示插入操作
matrix[i - 1][j] + 1表示删除操作
3.计算相似度:
编辑距离为: matrix[len(string1)][len(string2)]
。
相似度为:,表示两个字符串的相似程度,值越接近 1 表示越相似
np.zeros():用于创建一个指定形状和数据类型的全零数组。
参数名 | 类型 | 说明 |
---|---|---|
shape | int 或 tuple | 数组的形状,可以是一个整数或表示形状的元组。 |
dtype | dtype, 可选 | 数组的数据类型,默认为 float64 。 |
order | {'C', 'F'}, 可选 | 数组元素在内存中的排列顺序,'C' 表示按行排列,'F' 表示按列排列。 |
range():生成一个不可变的整数序列,常用于循环控制。
参数名 | 类型 | 说明 |
---|---|---|
start | int, 可选 | 序列的起始值,默认为 0。 |
stop | int | 序列的结束值(不包含)。 |
step | int, 可选 | 步长,默认为 1。 |
len():返回对象的长度(如字符串、列表、元组等)。
参数名 | 类型 | 说明 |
---|---|---|
obj | object | 需要计算长度的对象。 |
min():返回一组数据中的最小值。
参数名 | 类型 | 说明 |
---|---|---|
iterable | iterable | 可迭代对象(如列表、元组等)。 |
*args | 可选 | 多个单独的参数,用于比较。 |
key | function, 可选 | 用于指定比较规则的函数。 |
default | object, 可选 | 当可迭代对象为空时返回的默认值。 |
max():返回一组数据中的最大值。
参数名 | 类型 | 说明 |
---|---|---|
iterable | iterable | 可迭代对象(如列表、元组等)。 |
*args | 可选 | 多个单独的参数,用于比较。 |
key | function, 可选 | 用于指定比较规则的函数。 |
default | object, 可选 | 当可迭代对象为空时返回的默认值。 |
#编辑距离
def editing_distance(string1, string2):matrix = np.zeros((len(string1) + 1, len(string2) + 1))for i in range(len(string1) + 1):matrix[i][0] = ifor j in range(len(string2) + 1):matrix[0][j] = jfor i in range(1, len(string1) + 1):for j in range(1, len(string2) + 1):if string1[i - 1] == string2[j - 1]:d = 0else:d = 1matrix[i][j] = min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, matrix[i - 1][j - 1] + d)edit_distance = matrix[len(string1)][len(string2)]return 1 - edit_distance / max(len(string1), len(string2))
优缺分析
优点:
① 可解释性强
② 跨语种(甚至对于非语言序列)有效
③ 不需要训练模型
缺点:
① 字符之间没有语义相似度 eg:str1 = “我没钱”,str2 = "俺没钱",相似度得分:0.66(1 - 1 / 3)
② 受无关词/停用词影响大 eg:str1 = “我要办卡”,str2 = “你好我需要办一张卡”,相似度得分:0.44(1 - 5 / 9)
③ 受语序影响大 eg:str1 = “今天天气不错”,str2 = “天气不错今天”,相似度得分:0.33(1 - 4 / 6)
④ 文本长度对速度影响很大(算法实现中两层for循环速度基于文本长度)
六、文本匹配算法 Ⅱ —— Jaccard相似度
通用表述:根据两个集合中,不同元素所占的比例,来衡量两个样本之间的相似度
用于文本匹配:根据两个文本中,不同的字或词所占的比例,来衡量两个文本之间的相似度
相似度计算公式:
例:str1 = “今天天气真不错”,str2 = “估计明天天气更好”,公共字:天、气
A ∩ B:2(天、气)、A ∪ B:11(今、天、气、真、不、错、估、计、明、更、好)
Jaccard相似度:2 / 11 = 0.18
如果输入字符串,则得到基于字的 jaccard相似度;
如果输入词的列表,则得到基于词的 jaccard相似度;
具体用基于词 还是 用基于字的jaccrad相似度,看场景决定:① 分词是否准确;② 是否有很多类似名词、缩略词;③ 文本长度等因素,都会影响选择
代码实现
set(): Python 中的一个内置函数,用于创建一个无序且不重复的元素集合。它可以将可迭代对象(如字符串、列表、元组等)转换为集合,并自动去除重复元素
参数 | 描述 |
---|---|
iterable | 可选参数,表示一个可迭代对象(如列表、元组、字符串等)。如果不提供此参数,则返回一个空集合。 |
len():返回对象的长度(如字符串、列表、元组等)。
参数名 | 类型 | 说明 |
---|---|---|
obj | object | 需要计算长度的对象。 |
#jaccard距离
def jaccard_distance(string1, string2):words1 = set(string1)words2 = set(string2)distance = len(words1 & words2) / len(words1 | words2)return distance
优缺分析
优点:
① 语序不影响分数(词袋模型)eg:今天天气不错 / 天气不错今天
② 实现简单,速度很快
③ 可跨语种,无需训练等
缺点:
① 语序不影响分数 eg:他打了我 / 我打了他
② 字符之间没有相似度衡量:同编辑距离
③ 受无关词影响
④ 非一致文本可能出现满分 eg:他是不知道 他不是不知道
适用场景:
文本越长,语序对于准确率的影响越低,语序越不重要,更加适合Jaccard距离算法
文本短的话,Jaccard算法缺点会被放大,优点被缩小
七、文本匹配算法 Ⅲ —— BM25算法
常用在搜索引擎框架中,用来做文档和搜索问题的匹配。同样也可以用在问答中,做文本匹配。
核心思想:假如一个词在某类文本(假设为A类)中出现次数很多,而在其他类别文本(非A类)出现很少,那么这个词是A类文本的重要词(高权重词);反之,如果一个词在出现在很多领域,则其对于任意类别的重要性都很差。
BM25算法的基础是:TF · IDF算法
TF·IDF算法
TF:词频,代表这个词在某个类别文本中出现的频率,某个词在某个类别中出现的次数 / 该类别词的总数
公式:某个词在某个类别中出现的次数 / 该类别词的总数
IDF:逆文档频率,代表这个词在其他文本中出现的频率,N代表文本总数,dfi代表包含词qi的文本的总数
公式:IDF(qi) = log[(N - df_i + 0.5) / (df_i + 0.5)]
N:文档集合中的总文档数 df_i:包含词项q_i的文档数
逆文档频率IDF高 ——> 该词很少出现在其他文档
BM25算法
BM25是对TF·IDF的一种改进,优化其表示效果
公式:
词的重要性(IDF)
公式:
其中,N 是文档总数,df_i 是包含词 q_i 的文档数,IDF 值越高,表示该词在文档集合中越稀有,重要性越大
词与文档的相关性(TF)
BM25对词频(TF)进行了优化,引入了饱和函数S(q_i, d),避免词频过高时权重过大。
公式:
TF(qi, D):词 qi 在文档 D 中的词频
K:一个与文档长度相关的参数,
公式:
L_d:文档 D 的长度,L_ave:所有文档的平均长度,k_1,b:可学习参数
对词频进行调整,考虑了文档长度对词频的影响。较长的文档会受到惩罚,以避免偏向长文档
词与查询的相关性(可选)
当查询较长时,BM25还会考虑词在查询中的频率
公式:
TF(qi, Q):词qi在查询Q中的词频,k_3:可学习参数。
参数设置
k_1:控制词频的重要性,通常取值为 1.2。
b:控制文档长度的影响,通常取值为 0.75。
k_3:控制查询中词频的影响,通常取值为 1.2。
这些参数和改动的意义在于控制文本长度对分值的影响
优缺分析
优点:
① 通过使用TF·IDF弱化了无关词的影响,强化了重要词的影响,使得效果大幅提升
② 统计模型计算快(时间消耗主要是分词),不需要多轮迭代
③ 词袋模型(双刃剑)、跨语种等
缺点:
① 依然没有考虑词与词之间的相似性(字符之间没有相似度衡量)
② 需要一定量的训练(统计)样本(faq库本身)
③ 对于新增类别,需要重新计算统计模型
④ 分值不是一个总在0,1之间的数
代码实现
Ⅰ、超参数定义
ESPION:处理逆文档频率(IDF)计算中可能出现的负值的参数,确保IDF值始终为正,从而避免算法在计算相关性得分时出现异常。
PARAM_K1:超参数K_1,默认值为1.5,控制词频饱和度的上升速度。值越大,词频对得分的影响越大
PARAM_B:超参数B,默认值为0.6,控制文档长度归一化的影响。值越大,文档长度对得分的影响越大
typing:用于类型注解的库
import json
import math
import os
import pickle
import sys
from typing import Dict, Listclass BM25:EPSILON = 0.25PARAM_K1 = 1.5 # BM25算法中超参数PARAM_B = 0.6 # BM25算法中超参数
Ⅱ、初始化方法
def __init__(self, corpus: Dict):"""初始化BM25模型:param corpus: 文档集, 文档集合应该是字典形式,key为文档的唯一标识,val对应其文本内容,文本内容需要分词成列表"""self.corpus_size = 0 # 文档数量self.wordNumsOfAllDoc = 0 # 用于计算文档集合中平均每篇文档的词数 -> wordNumsOfAllDoc / corpus_sizeself.doc_freqs = {} # 记录每篇文档中查询词的词频self.idf = {} # 记录查询词的 IDFself.doc_len = {} # 记录每篇文档的单词数self.docContainedWord = {} # 包含单词 word 的文档集合self._initialize(corpus)
Ⅲ、根据语料库构建倒排索引并计算每个词的IDF值
len():返回对象的长度或元素个数。
参数名 | 类型 | 描述 |
---|---|---|
obj | 对象 | 要计算长度的对象,如字符串、列表、元组、字典等。 |
set():创建一个无序且不重复元素的集合。
参数名 | 类型 | 描述 |
---|---|---|
iterable | 可迭代对象(如列表、元组等) | 可选参数,用于创建集合。如果未提供,则创建一个空集合。 |
集合.add():向集合中添加一个元素。如果元素已存在,则不会重复添加。
参数名 | 类型 | 描述 |
---|---|---|
element | 任意类型 | 要添加到集合中的元素。如果元素已存在,则不会重复添加。 |
float():将字符串或数字转换为浮点数。
参数名 | 类型 | 描述 |
---|---|---|
x | 字符串或数字 | 要转换为浮点数的字符串或数字。如果未提供参数,则返回0.0。 |
字典.keys():返回字典中所有键的视图对象。
math.log():计算自然对数(以e为底的对数)。可以指定第二个参数作为对数的底数。
参数名 | 类型 | 描述 |
---|---|---|
x | 数字 | 要计算对数的数值。 |
base | 数字 | 可选参数,指定对数的底数。默认为自然对数(以e为底)。 |
列表.append():在列表末尾添加一个元素。
参数名 | 类型 | 描述 |
---|---|---|
object | 任意类型 | 要添加到列表末尾的元素。 |
float():将字符串或数字转换为浮点数。
参数名 | 类型 | 描述 |
---|---|---|
x | 字符串或数字 | 要转换为浮点数的字符串或数字。如果未提供参数,则返回0.0。 |
公式: ,N是文档总数,n(q_i)是包含词q_i的文档数
def _initialize(self, corpus: Dict):"""根据语料库构建倒排索引"""# nd = {} # word -> number of documents containing the wordfor index, document in corpus.items():self.corpus_size += 1self.doc_len[index] = len(document) # 文档的单词数self.wordNumsOfAllDoc += len(document)frequencies = {} # 一篇文档中单词出现的频率for word in document:if word not in frequencies:frequencies[word] = 0frequencies[word] += 1self.doc_freqs[index] = frequencies# 构建词到文档的倒排索引,将包含单词的和文档和包含关系进行反向映射for word in frequencies.keys():if word not in self.docContainedWord:self.docContainedWord[word] = set()self.docContainedWord[word].add(index)# 计算 idfidf_sum = 0 # collect idf sum to calculate an average idf for epsilon valuenegative_idfs = []for word in self.docContainedWord.keys():doc_nums_contained_word = len(self.docContainedWord[word])idf = math.log(self.corpus_size - doc_nums_contained_word +0.5) - math.log(doc_nums_contained_word + 0.5)self.idf[word] = idfidf_sum += idfif idf < 0:negative_idfs.append(word)average_idf = float(idf_sum) / len(self.idf)eps = BM25.EPSILON * average_idffor word in negative_idfs:self.idf[word] = eps
Ⅳ、计算文档集合中平均每篇文档的词数
@property: Python 中的一个内置装饰器,用于将类的方法转换为属性,使得可以像访问普通属性一样访问这些方法。它主要用于封装类的属性,提供更简洁和直观的接口,同时允许在访问或修改属性时执行额外的逻辑,如数据验证或计算。
float():将字符串或数字转换为浮点数。
参数名 | 类型 | 描述 |
---|---|---|
x | 字符串或数字 | 要转换为浮点数的字符串或数字。如果未提供参数,则返回0.0。 |
@propertydef avgdl(self):return float(self.wordNumsOfAllDoc) / self.corpus_size
Ⅴ、计算查询query 与 某篇文档的相关性得分
公式:
其中,f(qi, D) 是词 qi 在文档D中的词频,∣D∣是文档D的长度,avgdl 是文档集合的平均长度。
self.avgdl:文档集合中平均每篇文档的词数
def get_score(self, query: List, doc_index):k1 = BM25.PARAM_K1b = BM25.PARAM_Bscore = 0doc_freqs = self.doc_freqs[doc_index]for word in query:if word not in doc_freqs:continuescore += self.idf[word] * doc_freqs[word] * (k1 + 1) / (doc_freqs[word] + k1 * (1 - b + b * self.doc_len[doc_index] / self.avgdl))return [doc_index, score]
Ⅵ、计算查询与所有文档的相关性得分
遍历返回一个包含文档索引和得分的列表
列表推导式(List Comprehension)是 Python 中一种简洁且高效的方式来创建列表。它允许你在一行代码中从现有的可迭代对象(如列表、元组、字符串等)生成新的列表。列表推导式的基本语法如下:
new_list = [expression for item in iterable if condition]
expression
是对item
的操作或表达式,用于定义新列表中的每个元素。item
是可迭代对象中的每个元素。iterable
是包含要迭代的元素的可迭代对象。condition
是一个可选的条件,用于筛选要包含在新列表中的元素。
字典.keys():返回字典中所有键的视图对象。
def get_scores(self, query):scores = [self.get_score(query, index) for index in self.doc_len.keys()]return scores
Ⅶ、完整的BM25算法实现
import json
import math
import os
import pickle
import sys
from typing import Dict, Listclass BM25:EPSILON = 0.25PARAM_K1 = 1.5 # BM25算法中超参数PARAM_B = 0.6 # BM25算法中超参数def __init__(self, corpus: Dict):"""初始化BM25模型:param corpus: 文档集, 文档集合应该是字典形式,key为文档的唯一标识,val对应其文本内容,文本内容需要分词成列表"""self.corpus_size = 0 # 文档数量self.wordNumsOfAllDoc = 0 # 用于计算文档集合中平均每篇文档的词数 -> wordNumsOfAllDoc / corpus_sizeself.doc_freqs = {} # 记录每篇文档中查询词的词频self.idf = {} # 记录查询词的 IDFself.doc_len = {} # 记录每篇文档的单词数self.docContainedWord = {} # 包含单词 word 的文档集合self._initialize(corpus)def _initialize(self, corpus: Dict):"""根据语料库构建倒排索引"""# nd = {} # word -> number of documents containing the wordfor index, document in corpus.items():self.corpus_size += 1self.doc_len[index] = len(document) # 文档的单词数self.wordNumsOfAllDoc += len(document)frequencies = {} # 一篇文档中单词出现的频率for word in document:if word not in frequencies:frequencies[word] = 0frequencies[word] += 1self.doc_freqs[index] = frequencies# 构建词到文档的倒排索引,将包含单词的和文档和包含关系进行反向映射for word in frequencies.keys():if word not in self.docContainedWord:self.docContainedWord[word] = set()self.docContainedWord[word].add(index)# 计算 idfidf_sum = 0 # collect idf sum to calculate an average idf for epsilon valuenegative_idfs = []for word in self.docContainedWord.keys():doc_nums_contained_word = len(self.docContainedWord[word])idf = math.log(self.corpus_size - doc_nums_contained_word +0.5) - math.log(doc_nums_contained_word + 0.5)self.idf[word] = idfidf_sum += idfif idf < 0:negative_idfs.append(word)average_idf = float(idf_sum) / len(self.idf)eps = BM25.EPSILON * average_idffor word in negative_idfs:self.idf[word] = eps@propertydef avgdl(self):return float(self.wordNumsOfAllDoc) / self.corpus_sizedef get_score(self, query: List, doc_index):"""计算查询 q 和文档 d 的相关性分数:param query: 查询词列表:param doc_index: 为语料库中某篇文档对应的索引"""k1 = BM25.PARAM_K1b = BM25.PARAM_Bscore = 0doc_freqs = self.doc_freqs[doc_index]for word in query:if word not in doc_freqs:continuescore += self.idf[word] * doc_freqs[word] * (k1 + 1) / (doc_freqs[word] + k1 * (1 - b + b * self.doc_len[doc_index] / self.avgdl))return [doc_index, score]def get_scores(self, query):scores = [self.get_score(query, index) for index in self.doc_len.keys()]return scores
八、文本匹配算法 Ⅳ —— word2vec
1.什么是向量
指在坐标系(空间)内具有大小和方向的量
2维向量 [0.1, 2.9] 5维向量 [3, 1, 4, 2, 5]
2.什么是词向量
将每个词或字转换成同一向量空间内的一个向量
3.词向量的特点
两个词如果语义相近,则在空间中的向量接近
4.词向量是如何寻得到的
随机初始化,之后通过文本语料进行训练调整
5.如何训练/训练目标
① 基于窗口
② 基于语言模型
③ 基于共现矩阵
6.训练提速技巧
① 层次softmax/Huffman树
② 负采样
7.如何用于文本匹配
将文本中的所有词的词向量相加取平均
文本 ——> 句向量
公式:
句向量维度 = 词向量维度,不论文本长度
文本相似度 = 向量相似度 = 向量夹角余弦值
向量夹角为0,余弦值为1
8.优缺分析
优点:
① 两个文本包含语义相似的词,会提高相似度
② 训练需要的数据简单(纯文本语料即可)
③ 计算速度快,可以对知识库内问题预先计算向量
④ 将文本转化为数字,使后续复杂模型成为可能
缺点:
① 词向量的效果决定句向量效果(语料数量、领域适配、分词结果、未登录词)
② 一词多意的情况难以处理 eg:梨 —— 苹果 —— 华为
③ 受停用词(无效词)和文本长度影响很大(也是词袋模型)
④ 更换语种,甚至更换领域,都需要重新训练
相关文章:
【NLP 30、文本匹配任务 —— 传统机器学习算法】
目录 一、文本匹配任务的定义 1.狭义解释 2.广义解释 二、文本匹配的应用 1.问答对话 2.信息检索 3.文本匹配任务应用 三、智能问答 1.智能问答的基本思路 依照基础资源划分: 依照答案产出方式划分 依照NLP相关技术划分 四、智能问答的价值 1.智能客服 2.Faq知识库问…...
修改hosts文件,修改安全属性,建立自己的DNS
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
springboot + mybatis-plus + druid
目录架构 config MyMetaObjectHandler.java package com.example.config;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component;import java.util.Date;Com…...
【零基础到精通Java合集】第十一集:List集合框架与泛型
课程标题:List集合框架与泛型(15分钟) 目标:掌握泛型在List中的应用,理解类型安全的重要性,熟练操作泛型集合 0-1分钟:泛型List的意义引入 以“分类储物箱”类比泛型List:明确容器内元素类型(如只能放书籍)。说明泛型的核心作用——编译时类型检查,避免运行时类型…...
计算机网络——子网掩码
一、子网掩码是什么?它长什么样? 子网掩码的定义 子网掩码是一个32位的二进制数字,与IP地址“配对使用”,用于标识IP地址中哪部分属于网络地址,哪部分属于主机地址。 示例:IP地址 192.168.1.10,…...
[自然语言处理]pytorch概述--什么是张量(Tensor)和基本操作
pytorch概述 PyTorch 是⼀个开源的深度学习框架,由 Facebook 的⼈⼯智能研究团队开发和维护,于2017年在GitHub上开源,在学术界和⼯业界都得到了⼴泛应⽤ pytorch能做什么 GPU加速自动求导常用网络层 pytorch基础 量的概念 标量…...
18.5 ChatGLM2-6B 开源协议深度解读:自由与约束的平衡之道
ChatGLM2-6B 开源协议深度解读:自由与约束的平衡之道 关键词:ChatGLM2 开源协议, 模型授权合规, 商业使用限制, 技术伦理条款, 国产大模型治理 1. 协议核心条款全景解析 ChatGLM2-6B 采用 分层授权模式,其核心条款可归纳为三大维度: #mermaid-svg-xgEnsN0y2TMOR0Hf {font…...
javaweb自用笔记:Vue
Vue 什么是vue vue案例 1、引入vue.js文件 2、定义vue对象 3、定义vue接管的区域el 4、定义数据模型data 5、定义视图div 6、通过标签v-model来绑定数据模型 7、{{message}}直接将数据模型message展示出来 8、由于vue的双向数据绑定,当视图层标签input里的…...
FreeRTOS 源码结构解析与 STM32 HAL 库移植实践(任务创建、删除篇)
1. FreeRTOS源码结构介绍 1.1 下载源码 点击官网地址,选择 FreeRTOS 202212.01非 LTS 版本(非长期支持版),因为这个版本有着最全的历程和更多型号处理器支持。 1.2 文件夹结构介绍 下载后主文件 FreeRTOSv202212.01 下包…...
第五节:基于Winform框架的串口助手小项目---串口收发《C#编程》
“路漫漫其修远兮,吾将上下而求索” , -----------------------WHAPPY 目标任务: 1 从本地设备列表获取串口。 RegistryKey keyCom Registry.LocalMachine.OpenSubKey("Hardware\DeviceMap\SerialComm"); RegistryKey 是.NET 框…...
CSS2.1基础学习
1.定位盒模型相关 2.浮动 3.使用定位实现三列布局(不可取,定位父级为初始包含块) 4.使用浮动实现三列布局(不可取的原因是中间主列无法优先加载) 5.圣杯布局 6.等高布局 7.双飞翼布局 8.解决IE6下fixed失效问题 9.短暂总结 10.粘连布局 11.BFC是什么 12.BFC实现两列…...
alpine linux 系统最新版安装及使用教程
1.下载镜像包 官网地址 官网下载阿里云镜像站下载华为云镜像站下载清华大学镜像站下载中科大镜像站下载 官方安装文档 2.新建虚拟机 3.编辑虚拟机并开机 4.虚拟机安装 开启虚拟机 首次启动使用root登录,没有密码 登录成功,执行 setup-alpine 命令进…...
【Hudi-SQL DDL创建表语法】
CREATE TABLE 命令功能 CREATE TABLE命令通过指定带有表属性的字段列表来创建Hudi Table。 命令格式 CREATE TABLE [ IF NOT EXISTS] [database_name.]table_name[ (columnTypeList)]USING hudi[ COMMENT table_comment ][ LOCATION location_path ][ OPTIONS (options_lis…...
[Web 安全] PHP 反序列化漏洞 —— POP 链构造思路
关注这个专栏的其他相关笔记:[Web 安全] 反序列化漏洞 - 学习笔记-CSDN博客 0x01:什么是 POP 链? POP 链(Payload On Purpose Chain)是一种利用 PHP 中的魔法方法进行多次跳转以获取敏感数据的技术。它通常出现在 CTF…...
GPU/CUDA 发展编年史:从 3D 渲染到 AI 大模型时代
目录 文章目录 目录1960s~1999:GPU 的诞生:光栅化(Rasterization)3D 渲染算法的硬件化实现之路学术界算法研究历程工业界产品研发历程光栅化技术原理光栅化技术的软件实现:OpenGL 3D 渲染管线设计1. 顶点处理ÿ…...
除了DeepSpeed,在训练和推理的时候,显存不足还有什么优化方法吗?FlashAttention 具体是怎么做的
除了DeepSpeed,训练和推理时显存不足的优化方法及FlashAttention原理详解 DeepSpeed的基础内容:ZeRO分布式训练策略 一、显存不足的优化方法 1. 混合精度训练(Mixed Precision Training) 原理 使用FP16和FP32混合精度ÿ…...
GCC RISCV 后端 -- GCC 后端框架的一些理解
GCC 已经提供了一整套的编译框架,从前端(Frontend / GENERIC-Tree)对编程语言的语法语义处理,到中端(Middle-End / GIMPLE-Tree)的目标机器无关(Target Indepndent)的优化处理&#…...
庖丁解java(一篇文章学java)
(大家不用收藏这篇文章,因为这篇文章会经常更新,也就是删除后重发) 一篇文章学java,这是我滴一个执念... 当然,真一篇文章就写完java基础,java架构,java业务实现,java业务扩展,根本不可能.所以,这篇文章,就是一个索引,索什么呢? 请看下文... 关于决定开始写博文的介绍 …...
Spring框架自带的定时任务:Spring Task详解
文章目录 一、基本使用1、配置:EnableScheduling2、触发器:Scheduled 二、拓展1、修改默认的线程池2、springboot配置 三、源码分析参考资料 一、基本使用 1、配置:EnableScheduling import org.springframework.context.annotation.Config…...
DeepSeek 助力 Vue3 开发:打造丝滑的弹性布局(Flexbox)
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...
jwt 存在的无状态的安全问题与解决方案
背景我的需求 解决方法方案1:黑名单存在的问题解决方案问题成本估算: 方案2: 双token刷新核心解决的问题存在的问题 方案3: token与session结合成本估算 方案4: 长连接(websocket) 背景 jwt是无状态的,除了自动失效之外无法手动过期 举个例子: 当我们的token泄露或者密码泄露…...
【Python爬虫】爬取公共交通路网数据
程序来自于Github,以下这篇博客作为完整的学习记录,也callback上一篇爬取公共交通站点的博文。 Bardbo/get_bus_lines_and_stations_data_from_gaode: 这个项目是基于高德开放平台和公交网获取公交线路及站点数据,并生成shp文件,…...
Deepseek API+Python测试用例一键生成与导出-V1
在实际使用场景中,可能只需要获取需求文档中的部分内容,例如特定标题的正文部分、特定段落的表格内容,或者指定图片中的内容。为了满足这一需求,可以对文档清理工具进行优化,支持按标题提取内容、按章节提取表格和图片…...
如何为JAR设置定时重启?
AI越来越火了,我们想要不被淘汰就得主动拥抱。推荐一个人工智能学习网站,通俗易懂,风趣幽默,最重要的屌图甚多,忍不住分享一下给大家。点击跳转到网站 前面我们说过了如何将jar交由Systemctl管理,下面我们…...
麒麟V10-SP2-x86_64架构系统下通过KVM创建虚拟机及配置虚机的NAT、Bridge两种网络模式全过程
文章目录 一、什么是虚拟化?虚拟化具有哪些优势 二、常见的虚拟化技术1、kvm介绍2、kvm工作原理3、kvm功能 三、安装kvm并启动第一个kvm机器1、环境准备2、安装kvm工具3、启动并设置开机自启 libvirtd 服务4、验证 KVM 模块是否加载5、上传系统镜像到指定目录6、网络…...
三方库总结
一、Glide 目标:熟练掌握各种使用方法,了解其设计,背后原理 如果我设计一个图片显示框架,我会怎么做? 1.加载图片资源-从网络上下载图片资源、从本地加载图片资源 如果是从网络上加载图片,需要用到相关的网…...
用DeepSeek-R1-Distill-data-110k蒸馏中文数据集 微调Qwen2.5-7B-Instruct!
下载模型与数据 模型下载: huggingface: Qwen/Qwen2.5-7B-Instruct HF MirrorWe’re on a journey to advance and democratize artificial intelligence through open source and open science.https://hf-mirror.com/Qwen/Qwen2.5-7B-Instruct 魔搭&a…...
知识图谱的推荐实现方案(Vue)
使用 Vue 实现知识图谱思维导图展示的完整方案,结合主流库和最佳实践: 一、技术选型 组件库特点适用场景MindElixir国产开源、中文文档完善、支持关系线教育类知识图谱GoJS功能强大、商业许可、适合复杂交互企业级应用(需付费)D3…...
Nessus安装
Nessus:https://pan.quark.cn/s/f5fb09b6d4fb 1.软件安装 点击安装,剩下的下一步即可。 直接下一步安装即可 2.Web端安装 会弹出一个web窗口 开始初始化 创建用户 开始初始化 3.Cracker 会弹一个黑窗口 运行完,回车即可。访问https://loc…...
【大模型基础_毛玉仁】0.概述
更多内容:XiaoJ的知识星球 【大模型基础_毛玉仁】 系列文章参考 系列文章 【大模型基础_毛玉仁】0.概述 【大模型基础_毛玉仁】1.1 基于统计方法的语言模型 更新中。。。。。。 参考 书籍:大模型基础_完整版.pdf Github:https://github.co…...
quillEditor 禁用复制粘贴图片,以及class转style等问题
<template><div><div class"search-term"><el-form :inline"true" :model"searchInfo" class"demo-form-inline"><el-form-item label"案例标题"><el-input v-model"searchInfo.titl…...
C语⾔数据类型和变量
C 语言的数据类型 类型分类: C 语言提供丰富的数据类型,包括字符型(char、signed char、unsigned char)、整型(short、int、long 等多种,且各有 signed 和 unsigned 修饰形式) 、浮点型&#x…...
centOS 环境 安装redis方法
一、准备centOS环境 参考文章:Hyper-V 安装CentOS7_代码草率了的博客-CSDN博客 二、redis官网 地址:Download | Redis 演示版本为?redis-5.0.14.tar.gz 三、redis源码编译 登录后创建soft目录 进入目录使用wget下载所需资源包 命令:w…...
【Mac】2025-MacOS系统下常用的开发环境配置
早期版本的一个环境搭建参考 1、brew Mac自带终端运行: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" Installation successful!成功后运行三行命令后更新环境(xxx是mac的username&a…...
深入理解动态绑定与多态
动态绑定介绍 Java中的动态绑定,是一种在程序运行时确定方法执行版本的过程。它与多态紧密联系。 在Java中,动态绑定通常发生在以下情况: 方法覆盖:当子类重写父类的一个方法时,调用该方法的行为会根据对象的实际类…...
【数据结构】二叉树总结篇
遍历 递归 递归三部曲: 1.参数和返回值 2.终止条件 3.单层逻辑(遍历顺序) var preorderTraversal function(root) { // 第一种let res[];const dfsfunction(root){if(rootnull)return ;//先序遍历所以从父节点开始res.push(root.val);//递归…...
Zookeeper 及 基于ZooKeeper实现的分布式锁
1 ZooKeeper 1.1 ZooKeeper 介绍 ZooKeeper是一个开源的分布式协调服务,它的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。 原语:操作系统或…...
内嵌踢脚线怎么做能省钱?
家里装修内嵌踢脚线应该怎么做?哪种做法更经济? 先回答内嵌踢脚线应该怎么做? 做内嵌踢脚线有两种办法,简单点来说就是前凸和后挖。 前凸是踢脚线安到原来墙面上,踢脚线是从墙面上凸出来的,想要实现内嵌的效…...
DeepSeek集成到VScode工具,让编程更高效
DeepSeek与VScode的强强联合,为编程效率树立了新标杆。 DeepSeek,一款卓越的代码搜索引擎,以其精准的索引和高速的检索能力,助力开发者在浩瀚的代码海洋中迅速定位关键信息。 集成至VScode后,开发者无需离开熟悉的编辑…...
大模型应用:多轮对话(prompt工程)
概述 在与大型语言模型(如ChatGPT)交互的过程中,我们常常体验到与智能助手进行连贯多轮对话的便利性。那么,当我们开启一个新的聊天时,系统是如何管理聊天上下文的呢? 一、初始上下文的建立 1. 创建新会…...
洛谷 P1601 A+B Problem(高精)详解c++
我们之前做题碰到的数据范围一般是10^9,多点会达到10^18级别,处理10^9用int就可以存下,10^18次方要用到long long,接着解决加减乘除的问题,但是当数据范围达到了10^10^6的时候,当数据的值特别⼤,…...
【云原生】Spring Cloud是什么?Spring Cloud版本介绍
什么是SpringCloud 上一章节介绍了总体的SpringCloud的总体学习章节,因为最近项目刚好需要用到SpringCloud来搭建微服务项目、所以就跟着大家一起来再学习巩固下SpringCloud的相关知识 SpringCloud是基于SpringBoot提供了一套微服务解决方案,包括服务注…...
最节省成本的架构方案:无服务器架构
无服务器架构(Serverless Architecture)是一种颠覆性的云计算执行模型,它允许开发者专注于编写和部署代码,而无需担心底层服务器基础设施的管理。这种架构以其按需付费、自动伸缩和简化部署等优势,在成本优化方面表现出…...
C++入门续集:
1. 缺省参数: 我们看我们的上图,我们可以看我们的函数Func,我们可以看到我们的函数里面的参数写的是int a 0;这个写法是我们没有见过的,我们之前在C语言里面只见到过说是函数里面会设置参数,但是参数是没有…...
线代[9]|线性代数主要内容及其发展简史(任广千《线性代数的几何意义》的附录1)
文章目录 向量行列式矩阵线性方程组二次型 向量 向量又称为矢量,最初应用与物理学。很多物理量如力、速度、位移以及电场强度、磁感应强度等等都是向量。大约公元前350年前,古希腊著名学者亚里士多德就知道了力可以表示成向量,两个力的组合作…...
C++ Primer 动态内存与智能指针
欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…...
AI在原型设计中的革命性应用:效率与创新的双重突破
引言 在数字化转型加速的今天,产品开发周期被压缩至前所未有的程度。原型设计作为产品开发的核心环节,其效率和质量直接影响最终产品的市场竞争力。传统原型设计流程依赖人工绘制、反复修改和用户测试,耗时且成本高昂。而人工智能࿰…...
网络学习(四)HTTPS中,SSL的单向认证与双向认证
目录 一、什么是SSL?1.1 SSL 的主要功能1.2 SSL 的工作原理1.3 SSL 的核心组件1.4 SSL 的应用场景1.5 SSL 与 TLS 的区别 二、SSL 单向认证、双向认证2.1 SSL 单向认证2.2 SSL 双向认证2.3 总结:SSL 单向认证和双向认证的区别 一、什么是SSL?…...
分类任务和回归任务的区别
分类任务和回归任务是机器学习中两种常见的监督学习任务,尽管它们都属于预测性的分析,但它们的目标和应用场景存在显著的差异。 分类任务 定义:分类任务是指将输入样本映射到一个有限且离散的类别集合中的过程。目标是对数据进行分类&#…...
android接入rocketmq
一 前言 RocketMQ 作为一个功能强大的消息队列系统,不仅支持基本的消息发布与订阅,还提供了顺序消息、延时消息、事务消息等高级功能,适应了复杂的分布式系统需求。其高可用性架构、多副本机制、完善的运维管理工具,以及安全控制…...