【推荐系统】新闻相似度计算


前言

通过结巴进行分词,通过杰卡德相似系数来计算新闻的相似程度,相似度大于0.15时计算出相似的新闻可以接受,大家有如果有其他好的思路,请留言


一、新闻相似度计算思路

1、效果展示

10分钟带你入门单反摄影
相似的有:
相似度:0.18	 10分钟手臂操,这个夏天告别“拜拜肉”!
相似度:0.20	 9个经典瑜伽动作,每天10分钟,健康又瘦身!
-----------------------------------------
10分钟手臂操,这个夏天告别“拜拜肉”!
相似的有:
相似度:0.18	 10分钟带你入门单反摄影
相似度:0.15	 7个小动作每天4分钟,缓解腱鞘炎告别鼠标手!
相似度:0.15	 7个小动作每天4分钟,缓解腱鞘炎告别鼠标手!
相似度:0.15	 9个经典瑜伽动作,每天10分钟,健康又瘦身!
-----------------------------------------
10岁女孩因推拿不当 差点就高位截瘫了!
相似的有:
相似度:0.18	 14岁女孩在江苏失联
相似度:0.18	 16岁女孩在江苏失联
相似度:0.18	 21岁女孩在江苏失联
-----------------------------------------
11岁男孩骑共享单车被撞身亡 家属索赔878万
相似的有:
相似度:0.17	 13岁男孩骑小黄车练漂移 摔倒身亡[伤心]
相似度:0.17	 两男子骑共享单车撞倒辗轧小学生[怒]
相似度:0.22	 危险!10岁男童骑共享单车 手柄扎入大腿
-----------------------------------------
12岁和8岁兄弟俩洗澡时不幸双双丧命 疑热水器漏电所致[伤心]
相似的有:
相似度:0.18	 广场景观灯漏电!3岁女孩触电身亡[伤心]
-----------------------------------------
12岁女孩拿全国街舞冠军 曾捡水瓶支撑梦想
相似的有:
相似度:0.15	 12岁男孩在江苏失联
相似度:0.15	 14岁女孩在江苏失联
相似度:0.15	 16岁女孩在江苏失联
相似度:0.15	 21岁女孩在江苏失联
-----------------------------------------
12岁女童欲徒步跨省见网友 只因一句“想见你”[吃惊]
相似的有:
相似度:0.15	 12岁男孩在江苏失联
相似度:0.19	 “我不认识这个人” 4岁被拐女童一句话 网约车司机及时报警[good]
-----------------------------------------
12岁小学生玩游戏打赏主播 花掉环卫工母亲4万元积蓄[伤心]
相似的有:
相似度:0.17	 16岁少女为减肥吸毒 母亲一夜白头[伤心]
-----------------------------------------
12岁男孩捐髓救弟:愿做弟弟的大树[心]
相似的有:
相似度:0.25	 12岁男孩在江苏失联
相似度:0.15	 13岁男孩在江苏失联
相似度:0.15	 15岁男孩在江苏失联
相似度:0.21	 1岁以内你需要为宝宝做的12件事情
相似度:0.18	 今天,你愿为它们而转吗?[心]
相似度:0.15	 无论什么年纪 愿你童心依旧[心]

2、实现思路

  1. 对标题进行分词处理,分词有很多方式,我使用的结巴分词。分词可以只对标题分词,或者标题+内容的地名、名词、动名词、动词 进行分词,可自己选择。
  2. 通过杰卡德相似系数来计算两个内容的相似度。

3、杰卡德相似系数

两个集合A和B的交集元素在A,B的并集中所占的比例,称为两个集合的杰卡德相似系数,用符号J(A,B)表示。​在这里插入图片描述
杰卡德相似系数是衡量两个集合的相似度一种指标。通过两个集合的交集和并集的比值获取相似值。
交集: 表示方法 ∩ 。
并集 : 表示方法 ∪ 。
C的面积越大,说明两个集合越相似。
在这里插入图片描述

二、代码实现

1.分词

代码如下(python示例):


import os
import xlrd
import jieba.analyse

class SelectKeyWord:
    def __init__(self,file,_type):
        self.file = file
        self._type = _type
        self.news_dict = self.loadData()
        self.key_words = self.getKeyWords()

    # 加载数据
    def loadData(self):
        news_dict = dict()
        # 使用xlrd加载xlsx格式文件,返回一个table对象
        table = xlrd.open_workbook(self.file).sheets()[0]
        # 遍历每一行
        for row in range(1,table.nrows):
            # 将每一列返回为一个数组
            line = table.row_values(row, start_colx=0, end_colx=None)
            new_id = int(line[0])
            news_dict.setdefault(new_id,{})
            news_dict[new_id]["title"] = line[1]
            news_dict[new_id]["content"] = line[2]
        return news_dict

    # 调用结巴分词获取每篇文章的关键词
    def getKeyWords(self):
        news_key_words = list()
        # 加载停用词表
        stop_words_list = [line.strip() for line in open("./../files/stop_words.txt").readlines()]
        for new_id in self.news_dict.keys():
            if self._type == 1:
                # allowPOS 提取地名、名词、动名词、动词
                keywords = jieba.analyse.extract_tags(
                    self.news_dict[new_id]["title"] +self.news_dict[new_id]["content"],
                    topK=10,
                    withWeight=False,
                    allowPOS=('ns', 'n', 'vn', 'v')
                )
                news_key_words.append(str(new_id) + '\t' + ",".join(keywords) + '\t'+self.news_dict[new_id]["title"])
            elif self._type == 2:
                # cut_all :False 表示精确模式
                keywords=jieba.cut(self.news_dict[new_id]["title"],cut_all=False)
                kws = list()
                for kw in keywords:
                    if kw not in stop_words_list and kw != " " and kw != " ":
                        kws.append(kw)
                news_key_words.append(str(new_id) + '\t' + ",".join(kws) + '\t'+self.news_dict[new_id]["title"])
        return news_key_words

    # 将关键词获取结果写入文件
    def writeToFile(self,file):
        fw = open("C:\\Users\\archermind\\Desktop\\data\\%s.txt" % file.split("-")[0],"w",encoding="utf-8")
        fw.write("\n".join(self.key_words))
        fw.close()
        print("文件 %s 的关键词写入完毕。" % file)

if __name__ == "__main__":
    # 原始数据文件路径 这里替换excel路径
    original_data_path = "C:\\Users\\archermind\\Desktop\\data\\"
    files = os.listdir(original_data_path)
    # 关键词提取方式 _type = 1:以 title+content使用jieba的extract_tags进行关键词提取
    #                _type = 2:以 title进行分词处理作为文章关键词
    _type = 2
    for file in files:
        print("开始获取文件 %s 下的关键词。" % file)
        skw = SelectKeyWord(original_data_path + file ,_type)
        skw.writeToFile(file)
    print("\n关键词获取完毕")

输出信息:中间通过大空格隔开,分别为id,分词结果,title

3	中国,第三季,倒计时	#你所不知道的中国#第三季倒计时开始!
4	关注,四川,茂县,山体,垮塌,救援,目击者,称,生命,迹象	#关注四川茂县山体垮塌救援# 目击者称仍有生命迹象
5	南京,凤台,南路,车祸,后续,转发,急寻,目击者	#南京凤台南路车祸#后续:转发,急寻目击者!
6	候鸟,城市,暑假,10,平方米,中,幸福	#小候鸟的城市暑假# :10平方米中的幸福

2.相似度计算

代码如下(python):

import os

class Correlation:
    def __init__(self, file):
        self.file = file
        self.news_tags,self.news_title = self.loadData()
        self.news_cor_list = self.getCorrelation()
    # 加载数据
    def loadData(self):
        print("开始加载文件数据:%s" % self.file)
        news_tags = dict()
        news_title=dict()
        for line in open(self.file, "r", encoding="utf-8").readlines():
            try:
                newid, newtags,title = line.strip().split("\t")
                news_tags[newid] = newtags
                news_title[newid] = title
            except:
                print("读取分词数据过程中出现错误,错误行为:{}".format(line))
                pass


        return news_tags,news_title

    # 计算相关度
    def getCorrelation(self):
        news_cor_list = list()
        for newid1 in self.news_tags.keys():
            id1_tags = set(self.news_tags[newid1].split(","))
            _x = 0
            for newid2 in self.news_tags.keys():
                id2_tags = set(self.news_tags[newid2].split(","))
                if newid1 != newid2:
                    cor = ( len(id1_tags & id2_tags) ) / len (id1_tags | id2_tags)
                    if cor > 0.15:
                        if(_x==0):
                            print("-----------------------------------------");
                            print(self.news_title[newid1])
                            print("相似的有:")
                            _x=_x+1
                        print("相似度:"+format(cor,".2f")+"\t "+self.news_title[newid2]);

        return news_cor_list
if __name__ == "__main__":
    # 原始数据文件路径
    original_data_path = "C:\\Users\\archermind\\Desktop\\data\\keywords\\"
    files = os.listdir(original_data_path)
    for file in files:
        print("开始计算文件 %s 下的新闻相关度。" % file)
        cor = Correlation(original_data_path + file)

新闻数据集下载

xia

读到这里了,如果对你有帮助就留个赞吧。

另外关注公众号java内功心法回复我要当架构即可领取java方向必备进阶资料。
在这里插入图片描述

  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叁滴水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值