【NLP 30、文本匹配任务 —— 传统机器学习算法】

news2025/3/6 4:15:21

目录

一、文本匹配任务的定义

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():用于创建一个指定形状和数据类型的全零数组。

参数名类型说明
shapeint 或 tuple数组的形状,可以是一个整数或表示形状的元组。
dtypedtype, 可选数组的数据类型,默认为 float64
order{'C', 'F'}, 可选数组元素在内存中的排列顺序,'C' 表示按行排列,'F' 表示按列排列。

range():生成一个不可变的整数序列,常用于循环控制。

参数名类型说明
startint, 可选序列的起始值,默认为 0。
stopint序列的结束值(不包含)。
stepint, 可选步长,默认为 1。

len():返回对象的长度(如字符串、列表、元组等)。

参数名类型说明
objobject需要计算长度的对象。

min():返回一组数据中的最小值。

参数名类型说明
iterableiterable可迭代对象(如列表、元组等)。
*args可选多个单独的参数,用于比较。
keyfunction, 可选用于指定比较规则的函数。
defaultobject, 可选当可迭代对象为空时返回的默认值。

max():返回一组数据中的最大值。

参数名类型说明
iterableiterable可迭代对象(如列表、元组等)。
*args可选多个单独的参数,用于比较。
keyfunction, 可选用于指定比较规则的函数。
defaultobject, 可选当可迭代对象为空时返回的默认值。
#编辑距离
def editing_distance(string1, string2):
    matrix = np.zeros((len(string1) + 1, len(string2) + 1))
    for i in range(len(string1) + 1):
        matrix[i][0] = i
    for j in range(len(string2) + 1):
        matrix[0][j] = j
    for i in range(1, len(string1) + 1):
        for j in range(1, len(string2) + 1):
            if string1[i - 1] == string2[j - 1]:
                d = 0
            else:
                d = 1
            matrix[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():返回对象的长度(如字符串、列表、元组等)。

参数名类型说明
objobject需要计算长度的对象。
#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, List


class BM25:
    EPSILON = 0.25
    PARAM_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_size
        self.doc_freqs = {}  # 记录每篇文档中查询词的词频
        self.idf = {}  # 记录查询词的 IDF
        self.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 word
        for index, document in corpus.items():
            self.corpus_size += 1
            self.doc_len[index] = len(document)  # 文档的单词数
            self.wordNumsOfAllDoc += len(document)

            frequencies = {}  # 一篇文档中单词出现的频率
            for word in document:
                if word not in frequencies:
                    frequencies[word] = 0
                frequencies[word] += 1
            self.doc_freqs[index] = frequencies

            # 构建词到文档的倒排索引,将包含单词的和文档和包含关系进行反向映射
            for word in frequencies.keys():
                if word not in self.docContainedWord:
                    self.docContainedWord[word] = set()
                self.docContainedWord[word].add(index)

        # 计算 idf
        idf_sum = 0  # collect idf sum to calculate an average idf for epsilon value
        negative_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] = idf
            idf_sum += idf
            if idf < 0:
                negative_idfs.append(word)

        average_idf = float(idf_sum) / len(self.idf)
        eps = BM25.EPSILON * average_idf
        for word in negative_idfs:
            self.idf[word] = eps

Ⅳ、计算文档集合中平均每篇文档的词数

@property: Python 中的一个内置装饰器,用于将类的方法转换为属性,使得可以像访问普通属性一样访问这些方法。它主要用于封装类的属性,提供更简洁和直观的接口,同时允许在访问或修改属性时执行额外的逻辑,如数据验证或计算。

float():将字符串或数字转换为浮点数。

参数名类型描述
x字符串或数字要转换为浮点数的字符串或数字。如果未提供参数,则返回0.0。
    @property
    def 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_K1
    b = BM25.PARAM_B
    score = 0
    doc_freqs = self.doc_freqs[doc_index]
    for word in query:
        if word not in doc_freqs:
            continue
        score += 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, List


class BM25:
    EPSILON = 0.25
    PARAM_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_size
        self.doc_freqs = {}  # 记录每篇文档中查询词的词频
        self.idf = {}  # 记录查询词的 IDF
        self.doc_len = {}  # 记录每篇文档的单词数
        self.docContainedWord = {}  # 包含单词 word 的文档集合
        self._initialize(corpus)


    def _initialize(self, corpus: Dict):
        """
            根据语料库构建倒排索引
        """
        # nd = {} # word -> number of documents containing the word
        for index, document in corpus.items():
            self.corpus_size += 1
            self.doc_len[index] = len(document)  # 文档的单词数
            self.wordNumsOfAllDoc += len(document)

            frequencies = {}  # 一篇文档中单词出现的频率
            for word in document:
                if word not in frequencies:
                    frequencies[word] = 0
                frequencies[word] += 1
            self.doc_freqs[index] = frequencies

            # 构建词到文档的倒排索引,将包含单词的和文档和包含关系进行反向映射
            for word in frequencies.keys():
                if word not in self.docContainedWord:
                    self.docContainedWord[word] = set()
                self.docContainedWord[word].add(index)

        # 计算 idf
        idf_sum = 0  # collect idf sum to calculate an average idf for epsilon value
        negative_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] = idf
            idf_sum += idf
            if idf < 0:
                negative_idfs.append(word)

        average_idf = float(idf_sum) / len(self.idf)
        eps = BM25.EPSILON * average_idf
        for word in negative_idfs:
            self.idf[word] = eps

    @property
    def avgdl(self):
        return float(self.wordNumsOfAllDoc) / self.corpus_size


    def get_score(self, query: List, doc_index):
        """
        计算查询 q 和文档 d 的相关性分数
        :param query: 查询词列表
        :param doc_index: 为语料库中某篇文档对应的索引
        """
        k1 = BM25.PARAM_K1
        b = BM25.PARAM_B
        score = 0
        doc_freqs = self.doc_freqs[doc_index]
        for word in query:
            if word not in doc_freqs:
                continue
            score += 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:梨 —— 苹果 —— 华为

③ 受停用词(无效词)文本长度影响很大(也是词袋模型)

更换语种,甚至更换领域,都需要重新训练

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2310340.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

爬虫Incapsula reese84加密案例:Etihad航空

声明: 该文章为学习使用,严禁用于商业用途和非法用途,违者后果自负,由此产生的一切后果均与作者无关 一、找出需要加密的参数 1.js运行 atob(‘aHR0cHM6Ly93d3cuZXRpaGFkLmNvbS96aC1jbi8=’) 拿到网址,F12打开调试工具,随便搜索航班,切换到network搜索一个时间点可以找…

【Vue教程】使用Vite快速搭建前端工程化项目 Vue3 Vite Node.js

??大家好&#xff01;我是毛毛张! ??个人首页&#xff1a; ??今天毛毛张分享的是关于如何快速??♂搭建一个前端工程化的项目的环境搭建以及流程?? 文章目录 1.前端工程化环境搭建?? 1.1 什么是前端工程化1.2 nodejs的简介和安装 1.2.1 什么是Nodejs1.2.2 如何安装…

如何将飞书多维表格与DeepSeek R1结合使用:效率提升的完美搭档

将飞书的多维表格与DeepSeek R1结合使用&#xff0c;就像为你的数据管理和分析之旅装上一台涡轮增压器。两者的合作&#xff0c;不仅仅在速度上让人耳目一新&#xff0c;更是将智能化分析带入了日常的工作场景。以下是它们如何相辅相成并改变我们工作方式的一些分享。 --- 在…

算数操作符、赋值操作符、单目操作符、强制类型转换

一、算术操作符&#xff08;、 -、 *、 /、 %&#xff09; • - * / %操作符都是双⽬操作符,有**两个操作数**的符号就叫做双目操作符 10 4| || | 操作数1 操作数2// - % / * 以此类推•操作符也被叫做&#xff1a;运算符 1. 符号、符号 - 和 符号* •…

为AI聊天工具添加一个知识系统 之133 详细设计之74通用编程语言 之4 架构及其核心

本篇继续讨论 通用编程语言。 说明&#xff1a;本阶段的所有讨论都是围绕这一主题展开的&#xff0c;但前面的讨论分成了三个大部分&#xff08;后面列出了这一段的讨论题目的归属关系&#xff09;-区别distinguish&#xff08;各别&#xff09;&#xff1a; 文化和习俗。知识…

RNN实现精神分裂症患者诊断(pytorch)

RNN理论知识 RNN&#xff08;Recurrent Neural Network&#xff0c;循环神经网络&#xff09; 是一种 专门用于处理序列数据&#xff08;如时间序列、文本、语音、视频等&#xff09;的神经网络。与普通的前馈神经网络&#xff08;如 MLP、CNN&#xff09;不同&#xff0c;RNN…

私有云基础架构

基础配置 使用 VMWare Workstation 创建三台 2 CPU、8G内存、100 GB硬盘 的虚拟机 主机 IP 安装服务 web01 192.168.184.110 Apache、PHP database 192.168.184.111 MariaDB web02 192.168.184.112 Apache、PHP 由于 openEuler 22.09 系统已经停止维护了&#xff…

rust学习笔记11-集合349. 两个数组的交集

rust除了结构体&#xff0c;还有集合类型&#xff0c;同样也很重要&#xff0c;常见的有数组&#xff08;Array&#xff09;、向量&#xff08;Vector&#xff09;、哈希表&#xff08;HashMap&#xff09; 和 集合&#xff08;HashSet&#xff09;字符串等&#xff0c;好意外呀…

超详细:数据库的基本架构

MySQL基础架构 下面这个图是我给出的一个MySQL基础架构图&#xff0c;可以清楚的了解到SQL语句在MySQL的各个模块进行执行过程。 然后MySQL可以分为两个部分&#xff0c;一个是server层&#xff0c;另一个是存储引擎。 server层 Server层涵盖了MySQL的大多数核心服务功能&am…

AI催化新一轮创业潮与创富潮:深圳在抢跑

作者&#xff1a;尺度商业大掌柜黄利明 2025年春节伊始至今&#xff0c;从DeepSeek R1开源模型持续引发全球围观&#xff0c;到腾讯混元Turbo S模型发布秀出了"秒回"绝活&#xff0c;再到国务院发布《新一代人工智能发展规划&#xff08;2025-2030&#xff09;》重磅…

Python:类型转换和深浅拷贝,可变与不可变对象

int()&#xff1a;转换为一个整数&#xff0c;只能转换由纯数字组成的字符串 浮点型强转整型会去掉小数点及后面的数&#xff0c;只保留整数部分 #如果字符串中有数字和正负号以外的字符就会报错 float()&#xff1a;整形转换为浮点型会自动添加一位小数 .0 如果字符串中有…

NAT 代理服务 内网穿透

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; NAT 技术背景二&#xff1a;&#x1f525; NAT IP 转换过程三&#xff1a;&#x1f525; NAPT四&#xff1a;&#x1f525; 代理服务器&#x1f98b; 正向…

高级课第五次作业

首先配置交换机&#xff0c;路由器 LSW1配置 [SW1]vlan batch 10 20 30 40 [SW1]int g0/0/2 [SW1-GigabitEthernet0/0/2]port link-type access [SW1-GigabitEthernet0/0/2]port default vlan 10 [SW1]int g0/0/3 [SW1-GigabitEthernet0/0/3]port link-type access […

51单片机编程学习笔记——动态数码管显示多个数字

大纲 视觉残留原理生理基础神经传导与处理 应用与视觉暂留相关的现象 频闪融合不好的实现好的效果 延伸 在《51单片机编程学习笔记——动态数码管》一文中&#xff0c;我们看到如何使用动态数码管显示数字。但是基于动态数码管设计的特点&#xff0c;每次只能显示1个数字。这就…

金蝶ERP星空对接流程

1.金蝶ERP星空OPENAPI地址&#xff1a; 金蝶云星空开放平台 2.下载金蝶云星空的对应SDK包 金蝶云星空开放平台 3.引入SDK流程步骤 引入Kingdee.CDP.WebApi.SDK 右键项目添加引用&#xff0c;在打开的引用管理器中选择浏览页签&#xff0c;点击浏览按钮&#xff0c;找到从官…

【随手笔记】利尔达NB模组

1.名称 移芯EC6263GPP 参数 指令备注 利尔达上电输出 [2025-03-04 10:24:21.379] I_AT_WAIT:i_len2 [2025-03-04 10:24:21.724] LI_AT_WAIT:i_len16 [2025-03-04 10:24:21.724] [2025-03-04 10:24:21.733] Lierda [2025-03-04 10:24:21.733] [2025-03-04 10:24:21.745] OK移…

Vue3的核心语法【未完】

Vue3的核心语法 OptionsAPI与CompositionAPI Options API&#xff08;选项式&#xff09; 和 Composition API &#xff08;组合式&#xff09;是 Vue.js 中用于构建组件的两种不同方式。Options API Options API Options API 是 Vue 2 中的传统模式&#xff0c;并在 Vue 3…

解决redis lettuce连接池经常出现连接拒绝(Connection refused)问题

一.软件环境 windows10、11系统、springboot2.x、redis 6 7 linux&#xff08;centos&#xff09;系统没有出现这问题&#xff0c;如果你是linux系统碰到的&#xff0c;本文也有一定大参考价值。 根本思路就是&#xff1a;tcp/ip连接的保活(keepalive)。 二.问题描述 在spr…

从DNS到TCP:DNS解析流程和浏览器输入域名访问流程

1 DNS 解析流程 1.1 什么是DNS域名解析 在生活中我们会经常遇到域名&#xff0c;比如说CSDN的域名www.csdn.net&#xff0c;百度的域名www.baidu.com,我们也会碰到IP&#xff0c;现在目前有的是IPV4&#xff0c;IPV6。那这两个有什么区别呢&#xff1f;IP地址是互联网上计算机…

解锁Egg.js:从Node.js小白到Web开发高手的进阶之路

一、Egg.js 是什么 在当今的 Web 开发领域&#xff0c;Node.js 凭借其事件驱动、非阻塞 I/O 的模型&#xff0c;在构建高性能、可扩展的网络应用方面展现出独特的优势 &#xff0c;受到了广大开发者的青睐。它让 JavaScript 不仅局限于前端&#xff0c;还能在服务器端大展身手&…