[python]比较文章相似度

import jieba.posseg as pseg
import jieba
import jieba.analyse
import codecs
import math


设置待比较的几篇文章

files=[
    './sample/a1.txt',
    './sample/a2.txt',
    './sample/b1.txt',
    './sample/a3.txt',
]
texts=[codecs.open(file,'r','utf8').read() for file in files]

词频统计

from collections import Counter
def analyse_count(text,n=20):
    words=jieba.cut(text)
    words=[each.strip() for each in words]
    counter=Counter(words)
    for a in counter.most_common(n):
        print('%-10s\t%d' % (a[0],a[1]))
    print('\n')
for i in range(len(texts)):
    print("%s 词频统计\n======================"%files[i])
    analyse_count(texts[i])
./sample/a1.txt 词频统计
======================
,           74
的           62
            48
、           32
。           27
和           20
学习          17
在           11
理论          11
上           10
共产党员        10
"           8
要           7
是           7
入党          6
积极分子        6
自己          6
了           6
马克思主义       6
重要          6


./sample/a2.txt 词频统计
======================
,           107
的           74
            53
。           38
学习          26
、           23
在           21
和           14
;           13
要           12
自己          12
向           12
人民          11
服务          11
为           11
我           10
上           10
同学          10
大学生         9
党组织         9


./sample/b1.txt 词频统计
======================
,           401
。           275
的           238
            176
他           166
了           140
“           106
”           106
—           96
在           59
…           56
他们          53
我           51
德思礼         49
是           49
说           49
?           38
多           38
布利          38
没有          37


./sample/a3.txt 词频统计
======================
,           71
的           58
            25
我           21
。           19
在           14
工作          11
自己          10
、           10
上           10
学习          9
思想          8
党员          8
入党          7
了           6
理论          5
都           5
政治          5
是           5
党组织         5

关键词提取

jieba.analyse.set_stop_words('stop_words.txt')
def print_topic(text):
    tags = jieba.analyse.extract_tags(text, topK=20, withWeight=True)
    print("%10s\t%s"%('关键词','权重'))
    for v, n in tags:
        print("%-10s\t%d"%(v,n*10000))
    print('')
for i in range(len(texts)):
    print("%s 关键词提取\n======================"%files[i])
    print_topic(texts[i])
./sample/a1.txt 关键词提取
======================
       关键词  权重
学习          2625
共产党员        2233
积极分子        1664
理论          1546
入党          1484
业务知识        1338
马克思主义       1204
本职工作        1183
人生观         1062
邓小平理论       1038
本领          1032
大学生         1002
范文          985
思想汇报        971
先进性         856
党员          832
联系实际        827
政治          823
自觉性         813
三个代表        795

./sample/a2.txt 关键词提取
======================
       关键词  权重
学习          3028
党组织         1572
入党          1492
同学          1452
大学生         1360
全心全意        1352
人格          1336
服务          1184
健全          915
思想          901
靠拢          862
理论          848
认真学习        790
实际行动        759
模范作用        701
学生          697
工作          677
动机          631
党员          627
积极分子        627

./sample/b1.txt 关键词提取
======================
       关键词  权重
德思礼         3283
布利          2414
麦格          1608
哈利          1364
波特          1156
地说          871
教授          865
海格          841
猫头鹰         802
太太          765
斗篷          727
夫妇          533
女贞          491
达力          469
一只          464
麻瓜们         402
神秘          385
雪糕          344
钻机          335
街角          328

./sample/a3.txt 关键词提取
======================
       关键词  权重
入党          2103
党员          2022
学习          1688
工作          1500
思想          1451
党组织         1406
积极分子        1347
严格要求        1287
2018        1164
牢记          906
服务          867
理论          853
政治          833
范文          798
思想汇报        786
理论知识        731
汇报          719
认真负责        718
在思想上        647
一名          607

相似度判断

jieba.analyse.set_stop_words('stop_words.txt')
def cut_word(article):
    # 这里使用了TF-IDF算法,所以分词结果会有些不同->https://github.com/fxsjy/jieba#3-关键词提取
    res = jieba.analyse.extract_tags(
        sentence=article, topK=100, withWeight=True)
    return res


def tf_idf(res1=None, res2=None):
    # 向量,可以使用list表示
    vector_1 = []
    vector_2 = []
    # 词频,可以使用dict表示
    tf_1 = {i[0]: i[1] for i in res1}
    tf_2 = {i[0]: i[1] for i in res2}
    res = set(list(tf_1.keys()) + list(tf_2.keys()))

    # 填充词频向量
    for word in res:
        if word in tf_1:
            vector_1.append(tf_1[word])
        else:
            vector_1.append(0)
            if word in tf_2:
                vector_2.append(tf_2[word])
            else:
                vector_2.append(0)

    return vector_1, vector_2


def numerator(vector1, vector2):
    #分子
    return sum(a * b for a, b in zip(vector1, vector2))


def denominator(vector):
    #分母
    return math.sqrt(sum(a * b for a,b in zip(vector, vector)))


def run(vector1, vector2):
    return numerator(vector1,vector2) / (denominator(vector1) * denominator(vector2))

def get_similarity(text1,text2):
    vectors =  tf_idf(res1=cut_word(article=text1), res2=cut_word(article=text2))
    # 相似度
    similarity = run(vector1=vectors[0], vector2=vectors[1])
    # 使用arccos计算弧度
    # rad = math.acos(similarity)
    return similarity

两两比较

for i,j in [(0,1),(0,2),(1,2),(0,3),(2,3)]:
    print(' %s 和 %s 的相似度: %.2f'%(files[i],files[j],get_similarity(texts[i],texts[j])))
 ./sample/a1.txt 和 ./sample/a2.txt 的相似度: 0.33
 ./sample/a1.txt 和 ./sample/b1.txt 的相似度: 0.19
 ./sample/a2.txt 和 ./sample/b1.txt 的相似度: 0.27
 ./sample/a1.txt 和 ./sample/a3.txt 的相似度: 0.35
 ./sample/b1.txt 和 ./sample/a3.txt 的相似度: 0.25

结果分析

a1.txt a2.txt a3.txt 是政治思想报告主题的,而b1.txt 是哈利波特的小说

可以明显看出 a1,a2,a3 互相之间的相似度高于30%

而a1,a2,a3 与b1之间的相似度低于30%

算法是有效的

发布了36 篇原创文章 · 获赞 23 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/still_night/article/details/78998659