计算机毕设 推荐系统设计与实现 协同过滤推荐算法

文章目录

  • 0 前言
        • 简介
        • 常见推荐算法
          • 协同过滤
          • 分解矩阵
          • 聚类
          • 深度学习
        • 协同过滤原理
        • 系统设计
            • 示例代码(py)
        • 系统展示
            • 系统界面
            • 推荐效果
  • 最后


0 前言

🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩 推荐系统设计与实现

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:3分
  • 工作量:3分
  • 创新点:4分
简介

推荐系统,是当今互联网背后的无名英雄。

我们在某宝首页看见的商品,某条上读到的新闻,某度上的搜索列表,甚至在各种地方看见的广告,都有赖于推荐算法和系统.

本片文章讲述有哪些常用的推荐算法, 协同过滤推荐算法的原理, 以及如何使用协同过滤算法设计一个商品推荐毕业设计系统.

常见推荐算法
协同过滤

协同过滤(Collaborative Filtering)作为推荐算法中最经典的类型,包括在线的协同和离线的过滤两部分。所谓在线协同,就是通过在线数据找到用户可能喜欢的物品,而离线过滤,则是过滤掉一些不值得推荐的数据,比比如推荐值评分低的数据,或者虽然推荐值高但是用户已经购买的数据。

协同过滤的模型一般为m个物品,m个用户的数据,只有部分用户和部分数据之间是有评分数据的,其它部分评分是空白,此时我们要用已有的部分稀疏数据来预测那些空白的物品和数据之间的评分关系,找到最高评分的物品推荐给用户。

一般来说,协同过滤推荐分为三种类型。第一种是基于用户(user-based)的协同过滤,第二种是基于项目(item-based)的协同过滤,第三种是基于模型(model based)的协同过滤。

基于用户的协同过滤的基本原理是,根据所有用户对物品或者信息的偏好,发现与当前用户口味和偏好相似的用户群,然后基于这些用户的历史偏好,为当前用户进行推荐。

在这里插入图片描述
假设用户A喜欢物品A、物品C,用户B喜欢物品B,用户C喜欢物品A、物品C和物品D。从这些用户的历史偏好中,我们可以看出用户A和用户C的偏好是类似的。同时我们可以看到用户C喜欢物品D,所以我们可以猜想用户A可能也喜欢物品D,因此可以把物品D推荐给用户A。

分解矩阵

这是一个非常优雅的推荐算法,因为当涉及到矩阵分解时,我们通常不会太多地去思考哪些项目将停留在所得到矩阵的列和行中。但是使用这个推荐引擎,我们清楚地看到,u是第i个用户的兴趣向量,v是第j个电影的参数向量。

在这里插入图片描述
所以我们可以用u和v的点积来估算x(第i个用户对第j个电影的评分)。我们用已知的分数构建这些向量,并使用它们来预测未知的得分。

例如,在矩阵分解之后,Ted的向量是(1.4; .8),商品A的向量是(1.4; .9),现在,我们可以通过计算(1.4; .8)和(1.4; .9)的点积,来还原商品A-Ted的得分。结果,我们得到2.68分。
    
在这里插入图片描述

聚类

上面两种算法都极其简单,适用于小型系统。在这两种方法中,我们把推荐问题当做一个有监督机器学习任务来解决。

现在,该开始用无监督学习来解决问题了。

假设我们正在建立一个大型推荐系统,这时协同过滤和矩阵分解花费的时间更长了。第一个浮现在脑海里的解决之道,就是聚类。

业务开展之初,缺乏之前的用户数据,聚类将是最好的方法。

不过,聚类是一种比较弱的个性化推荐,因为这种方法的本质是识别用户组,并对这个组内的用户推荐相同的内容。

当我们有足够数据时,最好使用聚类作为第一步,来缩减协同过滤算法中相关邻居的选择范围。这个方法还能挺高复杂推荐系统的性能。

每个聚类都会根据其中用户的偏好,来分配一组典型的偏好。每个聚类中的用户,都会收到为这个聚类计算出的推荐内容。

深度学习

在过去的十年中,神经网络已经取得了巨大的飞跃。如今,神经网络已经得以广泛应用,并逐渐取代传统的机器学习方法。

接下来,我要介绍一下YouTube如何使用深度学习方法来做个性化推荐。

毫无疑问,由于体量庞大、动态库和各种观察不到的外部因素,为YouTube用户提供推荐内容是一项非常具有挑战性的任务。

根据《Deep Neural Networks for YouTube Recommendations》( https://static.googleusercontent.com/media/research.google.com/ru//pubs/archive/45530.pdf ),YouTube的推荐系统算法由两个神经网络组成:一个用于候选生成,一个用于排序。如果你没时间仔细研究论文,可以看看我们下面给出的简短总结。

在这里插入图片描述
以用户的浏览历史为输入,候选生成网络可以显著减小可推荐的视频数量,从庞大的库中选出一组最相关的视频。这样生成的候选视频与用户的相关性最高,然后我们会对用户评分进行预测。

这个网络的目标,只是通过协同过滤提供更广泛的个性化。

在这里插入图片描述
进行到这一步,我们得到一组规模更小但相关性更高的内容。我们的目标是仔细分析这些候选内容,以便做出最佳的选择。

这个任务由排序网络完成。

所谓排序就是根据视频描述数据和用户行为信息,使用设计好的目标函数为每个视频打分,得分最高的视频会呈献给用户。
在这里插入图片描述
通过这两步,我们可以从非常庞大的视频库中选择视频,并面向用户进行有针对性的推荐。这个方法还能让我们把其他来源的内容也容纳进来。
在这里插入图片描述
推荐任务是一个极端的多类分类问题。这个预测问题的实质,是基于用户(U)和语境©,在给定的时间t精确地从库(V)中上百万的视频类(i)中,对特定的视频观看(Wt)情况进行分类。

协同过滤原理

使用基于物品的协同过滤,需要维护一个物品相似度矩阵;使用基于用户的协同过滤,需要维护一个用户相似度矩阵。
在这里插入图片描述
两用户之间的相似度的计算其实很简单,用户i与用户j的相似度 = (i、j都打开过的网页数)/根号(i打开过的网页数 * j打开过的网页数)。这个计算与“基于物品的协同过滤”中的物品之间相似度的计算是类似的。

在这里插入图片描述

上面是一个用户相似度计算的案例。我们试着计算A和D之间的相似度。从“用户打开过的网页”可以看出,A和D都打开过的网页只有d,也就是1个。用户A打开过的网页数=3,用户D打开过的网页数=3。所以A和D的相似度=1/根号(3*3)。其他的计算也是类似的。

有了用户之间的相似度之后,就可以计算推荐度了。假设e是刚刚发布的文章,这时候用户B、C、D都浏览到e新闻的标题,其中C、D点击了,我们就可以计算A对e的兴趣度。

A对e的兴趣度=A与B的相似度B对e的兴趣度 + A与C的相似度C对e的兴趣度 + A与D的相似度*D对e的兴趣度。 因为我们这里用的不是评分制,而是考虑是否点击,那么D点击了e,D对e的兴趣度=1。

A对e的兴趣度 = 1/根号(6)*1 + 1/根号(6)*1 + 1/根号(9)*1

所以,比如100篇新的文章出来之后,对部分用户进行了曝光,然后就可以根据用户相似度,来预计其他用户对这篇文章的兴趣度,进而挑选这100篇中预计兴趣度最高的30篇曝光给这群用户。

系统设计
示例代码(py)
from abc import ABCMeta, abstractmethod
import numpy as np
from collections import defaultdict


class CF_base(metaclass=ABCMeta):
    def __init__(self, k=3):
        self.k = k
        self.n_user = None
        self.n_item = None

    @abstractmethod
    def init_param(self, data):
        pass

    @abstractmethod
    def cal_prediction(self, *args):
        pass

    @abstractmethod
    def cal_recommendation(self, user_id, data):
        pass

    def fit(self, data):
        # 计算所有用户的推荐物品
        self.init_param(data)
        all_users = []
        for i in range(self.n_user):
            all_users.append(self.cal_recommendation(i, data))
        return all_users


class CF_knearest(CF_base):
    """
    基于物品的K近邻协同过滤推荐算法
    """

    def __init__(self, k, criterion='cosine'):
        super(CF_knearest, self).__init__(k)
        self.criterion = criterion
        self.simi_mat = None
        return

    def init_param(self, data):
        # 初始化参数
        self.n_user = data.shape[0]
        self.n_item = data.shape[1]
        self.simi_mat = self.cal_simi_mat(data)
        return

    def cal_similarity(self, i, j, data):
        # 计算物品i和物品j的相似度
        items = data[:, [i, j]]
        del_inds = np.where(items == 0)[0]
        items = np.delete(items, del_inds, axis=0)
        if items.size == 0:
            similarity = 0
        else:
            v1 = items[:, 0]
            v2 = items[:, 1]
            if self.criterion == 'cosine':
                if np.std(v1) > 1e-3:  # 方差过大,表明用户间评价尺度差别大需要进行调整
                    v1 = v1 - v1.mean()
                if np.std(v2) > 1e-3:
                    v2 = v2 - v2.mean()
                similarity = (v1 @ v2) / np.linalg.norm(v1, 2) / np.linalg.norm(v2, 2)
            elif self.criterion == 'pearson':
                similarity = np.corrcoef(v1, v2)[0, 1]
            else:
                raise ValueError('the method is not supported now')
        return similarity

    def cal_simi_mat(self, data):
        # 计算物品间的相似度矩阵
        simi_mat = np.ones((self.n_item, self.n_item))
        for i in range(self.n_item):
            for j in range(i + 1, self.n_item):
                simi_mat[i, j] = self.cal_similarity(i, j, data)
                simi_mat[j, i] = simi_mat[i, j]
        return simi_mat

    def cal_prediction(self, user_row, item_ind):
        # 计算预推荐物品i对目标活跃用户u的吸引力
        purchase_item_inds = np.where(user_row > 0)[0]
        rates = user_row[purchase_item_inds]
        simi = self.simi_mat[item_ind][purchase_item_inds]
        return np.sum(rates * simi) / np.linalg.norm(simi, 1)

    def cal_recommendation(self, user_ind, data):
        # 计算目标用户的最具吸引力的k个物品list
        item_prediction = defaultdict(float)
        user_row = data[user_ind]
        un_purchase_item_inds = np.where(user_row == 0)[0]
        for item_ind in un_purchase_item_inds:
            item_prediction[item_ind] = self.cal_prediction(user_row, item_ind)
        res = sorted(item_prediction, key=item_prediction.get, reverse=True)
        return res[:self.k]


class CF_svd(CF_base):
    """
    基于矩阵分解的协同过滤算法
    """

    def __init__(self, k=3, r=3):
        super(CF_svd, self).__init__(k)
        self.r = r  # 选取前k个奇异值
        self.uk = None  # 用户的隐因子向量
        self.vk = None  # 物品的隐因子向量
        return

    def init_param(self, data):
        # 初始化,预处理
        self.n_user = data.shape[0]
        self.n_item = data.shape[1]
        self.svd_simplify(data)
        return data

    def svd_simplify(self, data):
        # 奇异值分解以及简化
        u, s, v = np.linalg.svd(data)
        u, s, v = u[:, :self.r], s[:self.r], v[:self.r, :]  # 简化
        sk = np.diag(np.sqrt(s))  # r*r
        self.uk = u @ sk  # m*r
        self.vk = sk @ v  # r*n
        return

    def cal_prediction(self, user_ind, item_ind, user_row):
        rate_ave = np.mean(user_row)  # 用户已购物品的评价的平均值(未评价的评分为0)
        return rate_ave + self.uk[user_ind] @ self.vk[:, item_ind]  # 两个隐因子向量的内积加上平均值就是最终的预测分值

    def cal_recommendation(self, user_ind, data):
        # 计算目标用户的最具吸引力的k个物品list
        item_prediction = defaultdict(float)
        user_row = data[user_ind]
        un_purchase_item_inds = np.where(user_row == 0)[0]
        for item_ind in un_purchase_item_inds:
            item_prediction[item_ind] = self.cal_prediction(user_ind, item_ind, user_row)
        res = sorted(item_prediction, key=item_prediction.get, reverse=True)
        return res[:self.k]


if __name__ == '__main__':
    # data = np.array([[4, 3, 0, 5, 0],
    #                  [4, 0, 4, 4, 0],
    #                  [4, 0, 5, 0, 3],
    #                  [2, 3, 0, 1, 0],
    #                  [0, 4, 2, 0, 5]])
    data = np.array([[3.5, 1.0, 0.0, 0.0, 0.0, 0.0],
                     [2.5, 3.5, 3.0, 3.5, 2.5, 3.0],
                     [3.0, 3.5, 1.5, 5.0, 3.0, 3.5],
                     [2.5, 3.5, 0.0, 3.5, 4.0, 0.0],
                     [3.5, 2.0, 4.5, 0.0, 3.5, 2.0],
                     [3.0, 4.0, 2.0, 3.0, 3.0, 2.0],
                     [4.5, 1.5, 3.0, 5.0, 3.5, 0.0]])
    # cf = CF_svd(k=1, r=3)
    cf = CF_knearest(k=1)
    print(cf.fit(data))
系统展示
系统界面

在这里插入图片描述

推荐效果

在这里插入图片描述

最后

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/138509.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mybatis框架——mybatis是什么

第一,mybatis是一个持久层的框架,它支持自定义SQL,存储过程以及高级映射。 mybatis几乎代替了所有的JDBC代码以及设置参数和获取结果集的工作,可以通过简单的XML或者注解来配置和映射原始类型、接口和Java POJO(Plain…

成都爱尔林江提醒孩子注意力不集中?可能是看不清的“弱视”!

婴儿时期的孩子,注意力不集中是常态,因为总是容易被身边事物吸引,玩一会儿这个,爬一爬又玩玩那个。这个过程其实也是建立认知的过程,注意力在发展建立,产生对事物的探索也是神经系统和头脑在发育。 随着孩子…

Spring整合redis的key时出现\xac\xed\x00\x05t\前缀问题

AutowiredRedisTemplate redisTemplate;User usernew User(5,"tomhs","tttt");ValueOperations opsForValue redisTemplate.opsForValue();//存放key,opsForValue.set("user"user.getId(),user);//读取数据;System.out.println(opsForValue.get…

java DataSize存储容量单位规范化设置

之前的文章 java Duration格式规范化 自定义时间单位类型我们讲述了 Duration 这种jdk单位规范 其实我们还有一个单位 DataSize 我们这里属性类中 加入这个 DataSize的一个属性 然后设置他的 get set函数 然后 toString中加上他的输出 方便我们去看 这个类型是用来设置存储容…

预后模型+实验生信思路,新颖可重复发文空间大

今天给同学们分享一篇生信文章“Novel Implication of the Basement Membrane for Breast Cancer Outcome and Immune Infiltration”,这篇文章发表在Int J Biol Sci期刊上,影响因子为3.5。 结果解读: 建立骨髓评分的预后骨髓基因选择策略 …

Linux Mint 21.3 将搭载 Cinnamon 6.0 和实验性 Wayland 支持

导读Wayland 会话可能在 Linux Mint 23 系列中成为默认选项,预计将在 2026 年实现。 Linux Mint 项目今天在他们的每月新闻通讯中 宣布,他们已经开始着手在未来的 Linux Mint 发行版中实施 Wayland 会话,最初将在 Linux Mint 21.3 中提供。 …

C++11『基础新特性』

✨个人主页: 北 海 🎉所属专栏: C修行之路 🎃操作环境: Visual Studio 2022 版本 17.6.5 文章目录 🌇前言🏙️正文1.C11 简介1.1.起源1.2.主要更新 2.列表初始化2.1.对于内置类型2.2.对于自定义…

从替代走向引领,永洪科技迈向全球化

对于数据分析领域而言,这是一个最好的时代。 《全球数字经济白皮书(2023年)》介绍,2016年-2022年,中国数字经济年均复合增长率为14.2%,数字经济发展增速和规模兼具。随着数字基础实施持续夯实、数字应用不…

接口开放太麻烦?试试阿里云API网关吧

前言 我在多方合作时,系统间的交互是怎么做的?这篇文章中写过一些多方合作时接口的调用规则和例子,然而,接口开放所涉及的安全、权限、监控、流量控制等问题,可不是简简单单就可以解决的,这一般需要专业的…

红队系列-shellcode AV evasion免杀合集

shellcode免杀 一些概念shellcode EDR 了解国内360全家桶360核晶引擎 火绒腾讯电脑管家安全狗金山毒霸瑞星 国外Windwos DefenerKaspersky 卡巴斯基ESET Nod32NortonMcAfeeAVASTAVG科摩多火眼诺顿Symantec小红伞 AV检测方式分类静态扫描引擎特征码扫描识别文件效验和法静态免杀…

媒体软文投放的流程与媒体平台的选择

海内外媒体软文:助力信息传播与品牌建设 在当今数字化时代,企业如何在庞大的信息海洋中脱颖而出,成为品牌建设的领军者?媒体软文投放无疑是一项强大的策略,通过选择合适的平台,精准投放,可以实…

大洋钻探系列之二IODP 342航次是干什么的?(上)

本文简单介绍一下大洋钻探IODP 342航次,从中,我们一窥大洋钻探航次的风采。 IODP342的航次报告在网络上可以下载,英文名字叫《Integrated Ocean Drilling ProgramExpedition 342 Preliminary Report》,航次研究的主要内容是纽芬兰…

学习c#的第九天

C# 可空类型&#xff08;Nullable&#xff09; C# 可空类型&#xff08;Nullable&#xff09; 可空类型允许我们在值类型中包含 null 值&#xff0c;这在处理数据库查询结果或需要表示缺失值的情况时非常有用。 声明一个可空类型的语法如下&#xff1a; < data_type>…

【Python Opencv】图片与视频的操作

文章目录 前言一、opencv图片1.1 读取图像1.2 显示图像1.3 写入图像1.4 示例代码 二、Opencv视频2.1 从相机捕获视频获取摄像头一帧一帧读取显示图片VideoCapture 中的get和set函数示例代码 2.2 从文件播放视频示例代码 2.3 保存视频示例代码 总结 前言 在计算机视觉和图像处理…

蓝桥杯 选择排序

选择排序的思想 选择排序的思想和冒泡排序类似&#xff0c;是每次找出最大的然后直接放到右边对应位置&#xff0c;然后将最 右边这个确定下来&#xff08;而不是一个一个地交换过去&#xff09;。 再来确定第二大的&#xff0c;再确定第三大的… 对于数组a[]&#xff0c;具体…

50个值得关注的生成式AI初创企业【2023】

在线工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 生成式AI初创公司已成为科技界最新、最强大的参与者&#xff0c;它们利用自然语言处理、机器学习和其他形式的人工智能为各种业务用例生成…

总结MYSQL中VHARCHAR和TEXT

前几天在设计表结构时&#xff0c;针对表中的一个字段使用text还是使用varchar是受到了开发同学的挑战。本篇文章对text和varchar的区别做个总结。 VHARCHAR和TEXT对比 char(n)varchar(n)中括号中n代表字符的个数&#xff0c;并不代表字节个数&#xff0c;所以当使用了中文的…

实战 | 基于卷积神经网络的蘑菇识别微信小程序

一个不知名大学生&#xff0c;江湖人称菜狗 original author: Jacky Li Email : 3435673055qq.com Time of completion&#xff1a;2023.11.13 Last edited: 2023.11.13 导读&#xff1a;其实没啥难的&#xff0c;主要是随手搞了就发出来把&#xff0c;太久没有水过帖子了&…

LCA

定义 最近公共祖先简称 LCA&#xff08;Lowest Common Ancestor&#xff09;。两个节点的最近公共祖先&#xff0c;就是这两个点的公共祖先里面&#xff0c;离根最远的那个。 性质 如果 不为 的祖先并且 不为 的祖先&#xff0c;那么 分别处于 的两棵不同子树中&#…

Python高级语法---Python内存管理机制

文章目录 1. 内存管理基础引用计数2. 垃圾回收机制垃圾回收3. 使用weakref处理循环引用weakref模块总结Python是一种高级编程语言,其内存管理机制高效且用户友好。这篇文章将详细介绍Python的内存管理基础、垃圾回收机制,以及如何使用weakref模块处理循环引用。我们将通过简单…