算法思路

首先看个简单的例子:

句子 A: 我喜欢看电视,不喜欢看电影
句子 B: 我不喜欢看电影,也不喜欢看电视

基本思路

如果两句话的用词越相似,它们的内容越相似。因此,可以从词频入手,计算它们的相似度。

我们可以把它们想象成空间中的两条线段,都是从原点([0, 0, ...])出发,指向不同的方向。两条线段之间形成一个夹角,如果夹角为 0 度,意味着方向相同、线段重合;如果夹角为 90 度,意味着形成直角,方向完全不相似;如果夹角为 180 度,意味着方向正好相反。
因此,我们可以通过夹角的大小,来判断向量的相似程度。夹角越小,就代表越相似。

夹角.png

假定 a 向量是 [x1, y1],b 向量是 [x2, y2],那么可以将余弦定理改写成下面的形式:

余弦定理.png

余弦的这种计算方法对 n 维向量也成立。假定 A 和 B 是两个 n 维向量,A 是 [A1, A2, ..., An] ,B 是 [B1, B2, ..., Bn] ,则 A 与 B 的夹角θ的余弦等于:

n维向量.png

使用这个公式,我们就可以得到,句子 A 与句子 B 的夹角的余弦。

image.png

实践

计算国务院政府工作和地方政府工作报告相似度

思路:

(1) 使用 python 中的结巴分词对国务院报告、省级、县级政府报告进行分词,去掉停用词,并统计词频。
(2) 抽取出国务院政府报告与其他省、县级政府报告的关键词合成一个集合。
(3) 出现频率最高的前 1000 个词,生成国务院报告所对应的特征向量。
(4) 出现频率最高的前 1000 个词,生成各级报告所对应的特征向量。
(5) 计算国务院报告的特征向量与各级政府报告特征向量的余弦相似度,值越大越相似。 看各地方的遵从程度。

以安徽省 2014-2018 年政府工作报告和 2014-2018 年国务院政府工作报告为例:

代码介绍:

def jieba_result(content):
    '''
    获取jieba分词结果,并去掉中文符号
    :param content: 为read_file返回的文章内容
    :return:
    '''
    res = jieba.lcut(content)
    for i in remove_list():
        while i in res:
            res.remove(i)
    # print(res)
    return res

根据 python 第三方库 jieba,获取分词结果。
举个例子:

import jieba

s ="我想要有一个女朋友,伤心。"
res = jieba.lcut(s)
print(res)

----
['我', '想要', '有', '一个', '女朋友', ',', '伤心', '。']

由于分词时,会将一些中文标点符号也分出来,所以定义了一个 remove_list,将在里面的符号都删掉

同时也必须得承认,这样子简单粗略的分词,对于一整篇报告来说,准确性还是有待提高的

def remove_list():
    '''
    将下列列表的中午符号过滤
    如果有缺失,可自行添加
    :return:
    '''
    remove_list = [',', ':', '。', '《', '》', '\n', '—', '“', '”', '、', ' ']
    return remove_list

最终计算 2014-2018 年每年,安徽省工作报告和国务院工作报告相似度如下:
相似度.png

相似度惊人的高,哈哈哈哈哈。。。。

最后社会主义核心价值观镇楼
image.png


↙↙↙阅读原文可查看相关链接,并与作者交流