推荐系统毕业设计 协同过滤商品推荐系统设计与实现

news2024/11/26 12:24:29

文章目录

  • 1 简介
  • 2 常见推荐算法
    • 2.1 协同过滤
    • 2.2 分解矩阵
    • 2.3 聚类
    • 2.4 深度学习
  • 3 协同过滤原理
  • 4 系统设计
    • 4.1 示例代码(py)
  • 5 系统展示
    • 5.1 系统界面
    • 5.2 推荐效果
  • 6 最后

1 简介

🔥 Hi,大家好,这里是学长的毕设系列文章!

🔥 对毕设有任何疑问都可以问学长哦!

这两年开始,各个学校对毕设的要求越来越高,难度也越来越大… 毕业设计耗费时间,耗费精力,甚至有些题目即使是专业的老师或者硕士生也需要很长时间,所以一旦发现问题,一定要提前准备,避免到后面措手不及,草草了事。

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

🚩 协同过滤商品推荐系统设计与实现

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

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

2 常见推荐算法

2.1 协同过滤

协同过滤(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。

2.2 分解矩阵

这是一个非常优雅的推荐算法,因为当涉及到矩阵分解时,我们通常不会太多地去思考哪些项目将停留在所得到矩阵的列和行中。但是使用这个推荐引擎,我们清楚地看到,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分。
    
在这里插入图片描述

2.3 聚类

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

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

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

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

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

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

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

2.4 深度学习

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

接下来,我要介绍一下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)情况进行分类。

3 协同过滤原理

使用基于物品的协同过滤,需要维护一个物品相似度矩阵;使用基于用户的协同过滤,需要维护一个用户相似度矩阵。
在这里插入图片描述
两用户之间的相似度的计算其实很简单,用户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篇曝光给这群用户。

4 系统设计

4.1 示例代码(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))

5 系统展示

5.1 系统界面

在这里插入图片描述

5.2 推荐效果

在这里插入图片描述

6 最后

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

redis持久化方案介绍

Redis有两种持久化方案:1. RDB持久化 2. AOF持久化 1 RDB持久化 RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后&…

[附源码]Python计算机毕业设计高校实习管理平台系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等…

【自然语言处理】基于TextRank算法的文本摘要

基于TextRank算法的文本摘要文本摘要是自然语言处理(NLP)的应用之一,一定会对我们的生活产生巨大影响。随着数字媒体的发展和出版业的不断增长,谁还会有时间完整地浏览整篇文章、文档、书籍来决定它们是否有用呢? 利用…

数据结构C语言版 —— 链表增删改查实现(单链表+循环双向链表)

文章目录链表1. 链表的基本概念2. 无头非循环单链表实现1) 动态申请节点2) 打印链表元素3) 插入节点头插法尾插法在指定位置之前插入在指定位置之后插入4) 删除节点删除头部节点删除末尾节点删除指定位置之前的节点删除指定位置之后的节点删除指定位置的节点5) 查找元素6) 销毁…

【图像评价】无参考图像质量评价NIQE【含Matlab源码 681期】

⛄一、无参考图像质量评价NIQE简介 理论知识参考:通用型无参考图像质量评价算法综述 ⛄二、部分源代码 function [mu_prisparam cov_prisparam] estimatemodelparam(folderpath,… blocksizerow,blocksizecol,blockrowoverlap,blockcoloverlap,sh_th) % Input …

013 单词速记

converse adj.相反的,颠倒的 v.交谈 con(加强语气)vers(转反转)e->反转 n.conversation 谈话,对话 adv.conversely 相反的 controversy n.争端 contro(counter) 相反 vers 转 lead to ~ 导致争端 contraversial 有争议…

MySQL-内置函数

文章目录内置函数日期函数字符串函数数学函数其他函数内置函数 日期函数 current_date();current_time();current_timestamp(); 应用: 创建生日表 插入数据: 创建评论区 采用datetime 时间戳自动填充时间 查询两分钟之内发的帖子 评论时间2min…

C语言期末集训1(大一,超基础,小猫猫大课堂配套练习)——顺序结构和分支结构的题

更新不易,麻烦多多点赞,欢迎你的提问,感谢你的转发, 最后的最后,关注我,关注我,关注我,你会看到更多有趣的博客哦!!! 喵喵喵,你对我…

安科瑞配电室环境监控系统解决方案-Susie 周

1、概述 配电室综合监控系统包括智能监控系统屏、通讯管理机、UPS电源、视频监控子系统(云台球机、枪机)、环境监测子系统(温度、湿度、水浸、烟感)、控制子系统(灯光、空调、除湿机、风机、水泵)、门禁监…

Redis分布式锁 - 基础实现及优化

应用场景 互联网秒杀抢优惠卷接口幂等性校验 代码示例 案例1 - StringRedisTemplate基础实现 package com.wangcp.redisson;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org…

以流量为王的时代,如何获得不错的流量,泰山众筹如何脱颖而出?

由于互联网、疫情等因素的影响,实体业务变得越来越困难。许多实体店已经开始转向在线电子商务,但运营一个好的电子商务平台并不容易。没有稳定的流量和忠实的用户,很难达到理想的效果。那到底如何才能获得不错的“流量”呢?泰山众…

第十四届蓝桥杯集训——JavaC组第十三篇——for循环

第十四届蓝桥杯集训——JavaC组第十三篇——for循环 目录 第十四届蓝桥杯集训——JavaC组第十三篇——for循环 for循环(重点) 倒序迭代器 for循环死循环 for循环示例 暴力循环 等差数列求和公式 基础循环展开 循环控制语句 break结束 continue继续 for循环(重点) f…

【图像融合】多尺度奇异值分解图像融合【含Matlab源码 2040期】

⛄一、多尺度奇异值分解的偏振图像融合去雾算法简介 立足于提高传统算法的适应性,提高去雾图像的质量,本文设计了如图 2 所示的去雾算法流程。首先,使用基于最小二乘方法计算出更加精确的偏振信息,改善了以往偏振信息计算不准确的…

基于Qt(C++)实现(PC)学生信息管理系统【100010043】

学生信息管理系统 一、系统指南 本系统为表格式的学生信息管理系统,提供了文件新建、打开及保存功能,还可在表格中对数据进行增加、删除、修改、搜索,下面将一一介绍这些功能 1、新建文件 新建文件将会产生一个全新的空表格,…

基于java+springmvc+mybatis+vue+mysql的少儿编程管理系统

项目介绍 在国家重视教育影响下,教育部门的密确配合下,对教育进行改革、多样性、质量等等的要求,使教育系统的管理和运营比过去十年前更加理性化。依照这一现实为基础,设计一个快捷而又方便的网上少儿编程教育网站系统是一项十分…

原来这就是BFC,遇到样式问题别瞎搞了

看到一篇前端面试题,第一个问题是 什么是BFC ?,一下子唤起了我的辛酸回忆,那是在七月,在沪漂找工作的路上,预约的一个电话面试,眼看着时间就要到了,人生第一次进星巴克,提…

leetcode 337. 打家劫舍 III-[python3图解]-递归+记忆化搜索

题目 小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为root。除了root之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果 两个直接相连…

【Python百日进阶-数据分析】Day130 - plotly柱状图(条形图):go.bar()实例1

文章目录4.2 plotly.graph_objects条形图4.2.1 go的基本条形图4.2.2 分组条形图4.2.3 堆叠条形图4.2.4 带悬停文本的条形图4.2.5 带直接文本标签的条形图4.2.6 使用uniformtext控制文本大小4.2.7 旋转条形图标签4.2.8 自定义单个条颜色4.2.9 自定义单个条的宽度4.2.10 自定义单…

NetInside网络分析为企业IT工作保驾护航(二)

前言 某企业的DMS经销商在线系统,最近一段时间运维人员经常接到反馈,DMS使用出现大量访问慢的情况,针对此情况进行监测分析。 该企业已部署NetInside流量分析系统,使用流量分析系统提供实时和历史原始流量,重点针对DMS系统性能进…

MobileNetV3基于NNI剪枝操作

NNI剪枝入门可参考:nni模型剪枝_benben044的博客-CSDN博客_nni 模型剪枝 1、背景 本文的剪枝操作针对CenterNet算法的BackBone,即MobileNetV3算法。 该Backbone最后的输出格式如下: 假如out model(x),则x[-1][hm]可获得heatma…