一个只关心自己的人只能做出很小的成就。
— 本杰明·富兰克林
你好,我是码财使者。
今天继续聊聊 AI 相关的话题。
问题
在之前的 【AIGC·真相】游戏人初摸AI配音:whisper语音识别 一文中,我们尝试用语音识别出对应的文本。实际测试下来,还是有一些文本识别的没有那么准确。
好在我们有所有音频的原始文本,只是和音频没有一一对应上。那现在的问题也比较清楚了: 就是找出音频对应的原始文本。
于是,我又开始研究,发现要实现我的功能,需要一种叫做文本相似度识别的技术。
对文本相似度的调研
解决方案是什么?
那么,应该如何计算两段文本的相似度呢?第一反应,人们一般很难想到比较合适的方法。利用字符串比较?似乎太简单了点。
咱们先暂时抛开上面这个问题,看看AI人工智能在解决问题时是采用什么样的思路:
上图总结起来就是:
- 世界上有很多问题,只有一小部分是数学问题
- 在数学问题里,只有一小部分是有解的
- 在有解的问题中,只有一部分是理想状态的图灵机可以解决的
- 在后一部分(图灵机可解决的部分),又只有一部分是今天的计算机可以解决的
- 而 AI 可以解决的问题,又只是计算机可以解决问题的一部分。
因此,我们首先需要将现实中的问题转化为一个数学问题,然后再对数学问题求解:
文本相似度的问题,恰好属于AI可以解决的问题,因此也类似的需要先转化为数学问题。
具体来说,我们解决这个问题需要经过如下的步骤:
- 首先通过文本表示方法,将原始文本转化为计算机可以理解的数学表示,也就是文本表示模型;
- 在文本表示模型的基础上,再根据相似度度量的算法,计算出相似度;
当然,文本在转化成数学上可以表示的事物前,还需要对其做下分词处理:因为文本是一种非结构化的数据,要先将其转化为结构化的数据,之后再转化为数学问题。
分词
分词是 [自然语言理解 – NLP] 的重要步骤。
所谓分词,就是将句子、段落、文章这种长文本,分解为以词语为单位的数据结构,方便后续的处理分析工作。
以下是一个中文分词的实际例子:
原始文本: “我喜欢玩星际争霸这款游戏”
分词结果: “我 / 喜欢 / 玩 / 星际 / 争霸 / 这款 / 游戏”
分出来的每个词基本都能表示一个有意义的最基本单元。
如果词语太短,如 “游戏” 分成了 “游” 和 “戏”, “戏” 就容易引起歧义,是 “游戏” 的 “戏” 还是 “唱戏” 的 “戏” ?
如果分的太长,比如整个句子作为一个单位来比较,句子的意思就过于复杂,基本不会有相似的情况,相似度匹配就会失败。
因此通过分词算法将文本先划分成合适的词汇单元,是一个优先要做的步骤。
文本表示模型
文本表示模型用于将文本转换为计算机可以理解和处理的形式(数学问题模型)。不同的文本表示模型捕捉了不同层次的语义信息和结构特征。
以下是一些常见的文本表示模型:
模型1:词袋模型(Bag-of-Words,BoW)
词袋模型中的这个袋子就是词语(分词后的基本单元)的集合。很容易想象,袋子里就是一堆词汇,每段文本分词后的词语就被丢进这个袋子中。
实际使用时,袋子中的所有词语排成一列,每个词语一个坑。于是一段文本就可以用这一列坑来表示:如果袋子中的词语不在这段文本中,对应坑的位置就是0,否则就是该词语在袋子中出现的次数。例如:
文本1: “这个苹果很好吃,非常甜。”
文本2: “那个橘子很新鲜,非常酸。”
首先,我们需要将这两个文本进行分词,将每个文本划分成词语的序列:
文本1分词结果: “这个 / 苹果 / 很 / 好吃 / 非常 / 甜”
文本2分词结果: “那个 / 橘子 / 很 / 新鲜 / 非常 / 酸”
袋子: [“这个”, “苹果”, “很”, “好吃”, “非常”, “甜”, “那个”, “橘子”, “新鲜”, “酸”]
然后,对于每个文本,我们统计每个词语在该文本中的出现次数,并将其转化为向量形式。
以文本1为例,它可以表示为以下向量:[1, 1, 1, 1, 1, 1, 0, 0, 0, 0],因为组成文本1的6个词语在袋子中都分别出现了1次,对应的值就是1,而袋子中剩余的词汇都没出现在文本1中,因此是0。
同样地,文本2可以表示为以下向量:文本2向量表示: [0, 0, 1, 0, 1, 0, 1, 1, 1, 1]。
模型2:TF-IDF向量
TF-IDF(Term Frequency-Inverse Document Frequency)是一种用于衡量词语在文本集合中重要性/关键性的方法。
前面我们说过,分词可以将一个文本分成多个词语,每个词语对于文本来说,重要性/关键性肯定不一样。
比如,”这个 / 苹果 / 很 / 好吃 / 非常 / 甜” 这几个词语中,”苹果”、”好吃”、”甜” 就是关键词,最能代表这段文本的意思。
如果两段文本的关键词/重要词语基本相同,是不是也基本类似?
TF-IDF 通过结合词频(TF)和逆文档频率(IDF)来衡量一个词语在文本集合中的重要性。
TF表示某个词在文本中出现的频率。如果一个词在某个文本中出现得越多,那么它对该文本的重要性就越高(重要人士就是要经常露脸 :))。
IDF表示某个词是不是在所有文本中都出现了。如果一个词出现的文档数越少,那么它对每个文档的重要性就越高(想一想独家代理、独占的重要性 :))。
TF-IDF的计算方式是将词语的TF值和IDF值相乘,得到表示该词的重要程度即 TF-IDF 权重值。TF-IDF的基本思想是通过综合考虑词语在文本中的频率(刷存在感、露脸)和在整个文本集合中的罕见程度(独家代表),来衡量词语的重要性。
通过这种计算方式,我们可以将每个词语转换成一个数值,文本中包含的词语对应的 TF-IDF 数值组合成一个向量,就是这个文本对应的向量。
假如,”这个 / 苹果 / 很 / 好吃 / 非常 / 甜” 这几个词的 TF-IDF 值分别是 0.1,0.3,0.1,0.2,0.1,0.2,那文本 “这个苹果很好吃,非常甜。” 对应的向量就是 [0.1,0.3,0.1,0.2,0.1,0.2]
模型3:词嵌入模型(Word Embedding)
词嵌入也叫词向量,是将词语映射为连续的向量空间中的向量,捕捉了词语的语义信息。
词嵌入向量的相似性考虑了语义,意义相近的词语在向量空间上也更接近:
具体的原理,会比前面两个模型更复杂,我这里就不再具体解释了。
目前流行的词嵌入模型有 word2vec、glove、Deeplearning4j,OpenAI 也提供了自己的词嵌入模型 text-embedding-ada-002,可以直接通过 API 来调用(当然,要收费 O.o)
OpenAI 提供的调用返回的例子如下:
更多模型:句子向量、预训练语言模型和其他高级模型
对这些高级模型,我没有继续研究,这里摘抄一些基本的定义放到这里:
句子向量将整个句子或短语表示为向量,可以通过平均词向量或使用循环神经网络(RNN)和卷积神经网络(CNN)等模型来获取句子的表示。
预训练语言模型(Pre-trained Language Model):预训练语言模型通过在大规模文本上进行无监督预训练,学习到了丰富的语言表示。常见的预训练语言模型包括BERT、GPT和XLNet等。
相似度度量
前面我们说了,可以将分词后的结果转化为数学形式的文本表示模型,其形式就是向量。
其实,也有直接对分词后的结果直接进行比较的方法,我称之为直接度量方法。
直接度量方法
编辑距离
编辑距离衡量的是通过插入、删除和替换字符,将一个字符串转换为另一个字符串所需的最小操作次数。
这么说可能比较抽象,来看一个具体的例子:
文本1: “我 / 喜欢 / 打 / 篮球”
文本2: “我 / 爱 / 踢 / 足球”
下面是一种可能的转换序列:
- 将”喜欢”替换为”爱”(1次操作):我爱打篮球
- 将”打”替换为”踢”(1次操作):我爱踢篮球
- 将”篮球”替换为”足球”(1次操作):我爱踢足球
总共需要3次操作,编辑距离为 3。
编辑距离越小,表示两个文本越相似,因为它们之间的转换操作越少。
词语集合差异(Jaccard 相似度系数)
Jaccard 相似度系数又称为交并比(Intersection over Union),是用于比较样本集的相似性与多样性的统计量。
现在有两个词语集合(两个文本分词后的),通过计算他们的相同集合及合并集合,可以评价他们二者的相似度。
相同/交叉集合为:
合并集合为:
Jaccard相似系数 = 交集大小 / 并集大小,数值越大(接近1)越相似。
我们来看一个具体的例子。
两个词语集合,文本1的词语集合:{“我”, “喜欢”, “打篮球”} ,文本2的词语集合:{“我”, “爱”, “踢足球”}
交集:{“我”}
并集:{“我”, “喜欢”, “打篮球”, “爱”, “踢足球”}
Jaccard相似系数 = 交集大小 / 并集大小 = 1 / 5 = 0.2
数学向量度量
通过前面介绍的文本表示模型,我们可以将文本转化为数学形式的向量。现在度量相似度,就转化为度量向量之间的相似度了。
欧氏距离
欧氏距离比较直观,就是坐标轴上的连线距离:
余弦相似度
余弦相似度是一种常用的度量两个向量之间相似度的方法。它通过计算两个向量的夹角的余弦值来度量它们的相似程度。余弦相似度的取值范围在 -1 到 1 之间,值越接近 1 表示两个向量越相似(夹角越小),值越接近 -1 表示两个向量越不相似。
应用:找出相似文本
现在,了解了这么多知识之后,我们就可以选择一种方法来解决我遇到的问题了。
最终我选择了 TF-IDF 文本表示模型,相似度度量并没有采用常用的余弦相似度来计算,就简单加总了一下所有词语的 TF-IDF 值,选择了加总值最大的那个文本作为匹配的原始文本。
具体的方法可以看这里的代码:简易相似度计算
希望本文能为你提供一点参考,方便的话点个免费的赞,感谢!感谢!
参考文档