通过余弦相似度实现少量新闻标题聚类效果

通过余弦相似度实现少量新闻标题聚类效果

最近有个任务需要统计社交网络上综合热度比较高的事件,需要进行少量新闻文本的聚类。

比如将 “上海买菜难不难” 和 “上海买菜非常难” 这两则新闻聚成一类。

因为没怎么学过机器学习,不想耽误太长时间,所以想直接用余弦相似度来判断,简单省事。

直接实现后发现准确率较低,因此重新审视了需求,觉得词性为名词的那些词如果相同的话,有极大的可能是同一类的,毕竟各个平台的热点标题都挺短的,就直接用jieba判断了一下各个词的词性,为名词的话就加个权重,拿50个标题简单验证了下,居然准确率一下子升高到90%以上,自己日常用是没问题了。

代码如下,连找资料带实现,从0开始只用了1个小时,虽然很是简陋,胜在快速实现需求。

import jieba
import jieba.posseg as posseg
import math

# s1 = '上海买菜难不难'
# s2 = '上海买菜非常难'

def similarity(s1,s2):
    all_flag = {}
    s1_cut = []
    for word in jieba.cut(s1, cut_all=True):
        for a, b in posseg.cut(word):
            all_flag[a] = b
        s1_cut.append(word)
    s2_cut = []
    for word in jieba.cut(s2, cut_all=True):
        for a, b in posseg.cut(word):
            all_flag[a] = b
        s2_cut.append(word)

    word_set = set(s1_cut).union(set(s2_cut))  # 求两个列表的并集,就是找出两个句子所有的切分词
    # 遍历基本词组
    frq_s1 = []  # 第一个句子的词频向量
    frq_s2 = []  # 第二个句子的词频向量
    for jichuci in word_set:  # 由于是遍历基础词,所以两个句子的切分词的词频顺序是保持一致的,不用考虑其顺序问题。
        n = 5   # 权重因子
        if jichuci in all_flag and all_flag[jichuci] in ['nr', 'ng', 'ns', 'nt', 'nz', 'n']:    # 如果是名词,则乘上权重因子
            frq = s1_cut.count(jichuci) * n
            frq_s1.append(frq)
            frq = s2_cut.count(jichuci) * n
            frq_s2.append(frq)
        else:
            frq = s1_cut.count(jichuci)
            frq_s1.append(frq)
            frq = s2_cut.count(jichuci)
            frq_s2.append(frq)

    # 计算余弦相似度,套用公式进行余弦相似度计算
    sum = 0
    sq1 = 0
    sq2 = 0
    for i in range(len(frq_s1)):
        sum += frq_s1[i] * frq_s2[i]
        sq1 += pow(frq_s1[i], 2)
        sq2 += pow(frq_s2[i], 2)

    try:
        result = round(float(sum) / (math.sqrt(sq1) * math.sqrt(sq2)), 2)
    except ZeroDivisionError:
        result = 0.0
    return result

count = 0
sum = 0
history = set()
with open("数据集.txt", "r", encoding='utf-8') as f:
    for line1 in f.readlines():
        print('*******************************')
        sum += 1
        line1 = line1.strip('\n')
        history.add(line1)
        tag = 0
        with open("数据集.txt", "r", encoding='utf-8') as f2:
            for line2 in f2.readlines() :
                line2 = line2.strip('\n')
                if line2 not in history:
                    like = similarity(line1,line2)
                    if 1.0 > like > 0.17:
                        tag = 1
                        print(like)
                        print(line1 + '-------' + line2)
                        count += 1
                        history.add(line2)
                    if tag:
                        history.add(line1)

print(count)
print(sum)

测试数据是直接复制的微博、头条、腾讯新闻上的热搜数据,每个新闻一行

你可能感兴趣的:(python,python,大数据,推荐算法)