美文网首页互联网科技
文章相似度计算

文章相似度计算

作者: 迈阿密小白 | 来源:发表于2018-10-16 12:52 被阅读62次

    算法思路

    首先看个简单的例子:

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

    基本思路

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

    • 第一步分词


      分词.png
    • 合并所有词


      合并.png
    • 计算词频


      词频.png
    • 得出词频向量


      词频向量.png

    我们可以把它们想象成空间中的两条线段,都是从原点([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
    
    
    • 获得前1000的向量
    def top_n(res,res_all,n):
        '''
        获得分词的Top n 词频,得出词频向量
        :param res: jieba_res  安徽  jieba_res 国务院
        :param res_all: 合并后的报告
        :param n:
        :return:
        '''
        dic={}
        for i in res_all:
            if i not in res:
                dic[i]=0
            else:
                dic[i]=res.count(i)
    
        sort_res= sorted(dic.items(), key=lambda x: x[1], reverse=True) #排序
    
        top_n = sort_res[:n]  #获取Top n
        # print(top_n)
        top_n_res=[]
        for i in top_n:
            top_n_res.append(i[1])
        # print(top_n_res)
        return top_n_res
    

    统计省工作报告,前1000热词的向量和国务院前1000热词的向量

    • 计算相似度
    def CalculateCos(gwyList, subList):
        '''
        根据两个词频向量,算出cos值
        :param gwyList:
        :param subList:
        :return:
        '''
        gwyLen = 0
        for gwynum in gwyList:
            gwyLen = gwyLen + gwynum ** 2
        gwyLen = gwyLen ** 0.5
        subLen = 0
        for sub in subList:
            subLen = subLen + sub ** 2
        subLen = subLen ** 0.5
        # return subLen
        totalLen = len(gwyList)
        fenmu = 0
        for i in range(0,totalLen):
            fenmu = fenmu + subList[i] * gwyList[i]
        print(fenmu / (subLen * gwyLen))
        return fenmu / (subLen * gwyLen)
    

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


    相似度.png

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

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


    image.png

    相关文章

      网友评论

      本文标题:文章相似度计算

      本文链接:https://www.haomeiwen.com/subject/xrxhzftx.html