相似词处理

相似词处理

1. 简介

同义词挖掘一般有三种思路,借助已有知识库,上下文相关性,文本相似度。

1.1 知识库

可以借助已有知识库得到需要同义词,比如说《哈工大信息检索研究室同义词词林扩展版》和 HowNet,其中《词林》文件数据如下。

Aa01A01= 人 士 人物 人士 人氏 人选
Aa01A02= 人类 生人 全人类
Aa01A03= 人手 人员 人口 人丁 口 食指
Aa01A04= 劳力 劳动力 工作者
Aa01A05= 匹夫 个人
Aa01A06= 家伙 东西 货色 厮 崽子 兔崽子 狗崽子 小子 杂种 畜生 混蛋 王八蛋 竖子 鼠辈 小崽子
Aa01A07= 者 手 匠 客 主 子 家 夫 翁 汉 员 分子 鬼 货 棍 徒
Aa01A08= 每人 各人 每位
Aa01A09= 该人 此人

以上两个知识库是人工编辑的,毕竟数量有限,我们还可以借助众包知识库百科词条获取同义词,比如百度百科,如下图所示,在百度百科搜索“凤梨”,我们可以看到在返回页面结果中的 info box中有一个属性为“别称”,别称中就是凤梨的同义词。除此之外,在百科词条的开头描述中,有如下描述“又称”、“俗称”也是同义词,我们可以利用爬虫把这些词爬下来。

百度搜索和谷歌搜索等搜索工具一般都有重定向页,这也可以帮助我们去挖掘同义词。

使用知识库挖掘同义词的优点是简单易得,而且准确率也高,缺点就是知识库覆盖率有限,不是每个细分领域都有。对于金融、医疗、娱乐等领域都需要各自的知识库。

img

1.2 上下文相关性

利用上下文相关性挖掘同义词也比较好理解,如果两个词的上下文越相似的话,那么这两个词是同义词的概率就越大。使用词向量挖掘同义词是比较常见的做法,比如使用word2vector训练得到词向量,然后再计算余弦相似度,取最相似的top k个词,就得到了同义词。

word2vector是无监督学习,而且本质上来说它是一个语言模型,词向量只是它的副产品,并不是直接用来挖掘同义词。有篇paper发明了弱监督的同义词挖掘模型DPE,也取得了不错的效果。DPE模型流程如下图,一共分为两个阶段,第一阶段跟word2vector差不多,也是训练词向量,只不过DPE是一种graph embedding的思路,首先从语料中构建语义共现网络,然后通过对网络的边采样训练词向量。第二阶段通过弱监督训练一个打分函数,对输入的一对词判断属于同义词的概率。

img

基于上下文相关性的同义词挖掘方法的优点是能够在语料中挖掘大量的同义词,缺点是训练时间长,而且挖掘的同义词很多都不是真正意义上的同义词需要人工筛选。这种方法对于词频较高的词效果较好。

1.3 文本相似度

对于这一对同义词“阿里巴巴网络技术有限公司”和“阿里巴巴网络公司”直接去计算上下文相似度可能不太有效,那一种直观的方法是直接计算这两个词的文本相似度,比如使用编辑距离(Levenshtein distance)或者 LCS(longest common subsequence),如果两个词的文本相似度大于阈值的话我们就认为他们是同义词的关系。在这里推荐一个计算文本相似度的Java开源项目,基本上文本相似度算法应有尽有。[ 文本相似度算法 ]

img

基于文本相似度同义词挖掘方法的优点是计算简单,不同于word2vector,这种方法不需要使用很大的语料,只要这个词出现过一次就可以发现同义词关系。这种方法的缺点是有时候不太靠谱,会挖掘出很多错误的同义词,尤其是当两个词比较短的情况下,比如“周杰伦”和“周杰”,就可能会被认为是同义词。所以这种方法适用于一些较长的文本,特别是专业词汇,术语。

2. 句子相似度计算

2.1 编辑距离

编辑距离,英文叫做 Edit Distance,又称 Levenshtein 距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数,如果它们的距离越大,说明它们越是不同。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。

例如我们有两个字符串:string 和 setting,如果我们想要把 string 转化为 setting,需要这么两步:

第一步,在 s 和 t 之间加入字符 e。
第二步,把 r 替换成 t。
所以它们的编辑距离差就是 2,这就对应着二者要进行转化所要改变(添加、替换、删除)的最小步数。

安装:pip3 install distance

import distance

str1 = "公司地址是哪里"
str2 = "公司在什么位置"

def edit_distance(s1, s2):
    return distance.levenshtein(s1, s2)

print(edit_distance(str1, str2))

想要获取相似的文本的话可以直接设定一个编辑距离的阈值来实现,如设置编辑距离为 2

def edit_distance(s1, s2):
    return distance.levenshtein(s1, s2)

strings = [
    '你在干什么',
    '你在干啥子',
    '你在做什么',
    '你好啊',
    '我喜欢吃香蕉'
]

target = '你在干啥'
results = list(filter(lambda x: edit_distance(x, target) <= 2, strings))
print(results)
# ['你在干什么', '你在干啥子']

2.2 杰卡德系数计算

杰卡德系数,英文叫做 Jaccard index, 又称为 Jaccard 相似系数,用于比较有限样本集之间的相似性与差异性。Jaccard 系数值越大,样本相似度越高。

实际上它的计算方式非常简单,就是两个样本的交集除以并集得到的数值,当两个样本完全一致时,结果为 1,当两个样本完全不同时,结果为 0。

算法非常简单,就是交集除以并集,下面我们用 Python 代码来实现一下:

from sklearn.feature_extraction.text import CountVectorizer
import numpy as np

def jaccard_similarity(s1, s2):
    def add_space(s):
        return ' '.join(list(s))

    # 将字中间加入空格
    s1, s2 = add_space(s1), add_space(s2)
    # 转化为TF矩阵
    cv = CountVectorizer(tokenizer=lambda s: s.split())
    corpus = [s1, s2]
    vectors = cv.fit_transform(corpus).toarray()
    # 获取词表内容
    ret = cv.get_feature_names()
    print(ret)
    # 求交集
    numerator = np.sum(np.min(vectors, axis=0))
    # 求并集
    denominator = np.sum(np.max(vectors, axis=0))
    # 计算杰卡德系数
    return 1.0 * numerator / denominator


s1 = '你在干嘛呢'
s2 = '你在干什么呢'
print(jaccard_similarity(s1, s2))

2.3 Word2Vec计算

顾名思义,其实就是将每一个词转换为向量的过程。

Word2Vec的词向量模型是训练的维基百科的中文语库,这里模型有250维和50维,向量维度越大模型越大,计算越复杂,正常使用时,需要小的模型,发现50维的也差不多.

流程:

  1. 对句子进行拆词
  2. 去除无用的分词
  3. 计算句子平均词向量
  4. 余弦相似度

对句子进行拆词:Python提供了很对可用库,自行选择
去除无用的分词:删除没用的语气词等,为的是减少对计算句子平均词向量的影响。
计算句子平均词向量用的是AVG-W2V,计算句子平均词向量,所以02步尤为重要
余弦相似度:

余弦相似度 np.linalg.norm(求范数)(向量的第二范数为传统意义上的向量长度
dist1=float(np.dot(vec1,vec2)/(np.linalg.norm(vec1)*np.linalg.norm(vec2)))
def key_words_ask_method(sentence1, sentence2):
    '''
    因为无论是#1:AVG-W2V 2:AVG-W2V-TFIDF 都需要求得平均值,
    除数:决定整个数据的大小  被除数:影响平均值
    所以 分词的标准很重要,可通过自定义词典、停用词 和 语义分析进行适当处理
    '''
    vec1 = sentence_to_vec(sentence1)
    vec2 = sentence_to_vec(sentence2)

    # 零向量直接返回
    if (vec1 == np.zeros(WORD_VECTOR_DIM)).all() == True or (vec2 == np.zeros(WORD_VECTOR_DIM)).all() == True:
        return "不符合相似"

    # score = cos(vec1, vec2)
    # print(score)
    # if score < COSINE_CRITICAL_VALUE:
    #     return "1"
    # else:
    #     return "0"

    # 余弦相似度 np.linalg.norm(求范数)(向量的第二范数为传统意义上的向量长度
    dist1=float(np.dot(vec1,vec2)/(np.linalg.norm(vec1)*np.linalg.norm(vec2)))
    print("score:", dist1)
    if dist1 > 0.92:
        return "两个句子相似"
    else:
        return "两个句子不相似"

img

参考:

nlp自然语言处理中句子相似度计算

同义词(近义词)算法总结(附代码)

### 回答1: Python 相似扩展是一种语言处理技术,其目的是基于语义关系扩展汇表,将一个单与其相关的汇组扩展到更广泛的范围,从而提升自然语言处理系统的准确性和效率。 Python 相似扩展可以通过使用 WordNet 等汇库来实现。WordNet 是一个英文单汇分类资源库,其中包含了大量的汇及其意义和实用的汇组,如同义、反义、实例等。通过使用 WordNet,我们可以建立起汇之间的联系,进一步扩展出具有相关意义的汇组,从而得到更为准确的结果。 在 Python 中,相关的库包括了 NLTK 和 Gensim 等。其中 NLTK 是 Python 中一个著名的自然语言处理工具包,提供了众多的语言处理模块,包括性标注、句法分析、语义分析等。而 Gensim 则是一个用于生成文本向量的库,可通过分析语间的相似度得出相似汇组,从而应用于文本分类、信息检索等领域。 Python 相似扩展技术在语义理解、文本分类、信息提取及智能搜索等领域有着广泛的应用,提高了机器理解自然语言的能力,为现代人工智能提供了更好的基础条件。 ### 回答2: Python相似扩展主要是通过自然语言处理技术对给定的单进行分析,以便找到与该单在语义上相似或相关的单。这些相似可以是同义、反义、相关等,它们可以用于搜索引擎优化(SEO)、文本挖掘和信息检索等领域。 Python相似扩展可以使用多种技术来实现,比如基于语料库的方法、基于知识图谱的方法、基于嵌入的方法等。其中,基于嵌入的方法已被证明在语义相似度衡量方面具有优秀性能。一个典型的基于嵌入的方法是使用Word2Vec算法,该算法将单表示为向量,并通过将这些向量组合起来来计算语义相似度。 除了Word2Vec算法,还有许多其他的算法可以用来实现Python相似扩展,比如GloVe、FastText等。这些算法也可以用来构建文本分类、情感分析等自然语言处理应用。 综上所述,Python相似扩展是自然语言处理领域的一个重要问题,它可以帮助人们更好地理解自然语言,也为一些应用提供了便利。在使用Python相似扩展时,需要根据具体的场景选择适当的算法,以获得更好的表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值