推荐系统(唐宇迪)含具体代码

一、推荐系统介绍

在这里插入图片描述


在这里插入图片描述

用户冷启动
在这里插入图片描述

1.1 经典流程

在这里插入图片描述

1.2 涉及的技术点

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、协同过滤与矩阵分解

在这里插入图片描述

2.1 基于物品流行度(排行榜榜单)的推荐算法

class popularity_recommender_py():
    def __init__(self):
        self.train_data = None
        self.user_id = None
        self.item_id = None
        self.popularity_recommendations = None

    # create方法
    # 基于给定的训练数据、用户ID和歌曲ID来 创建推荐系统模型。
    def create(self, train_data, user_id, item_id):
        self.train_data = train_data
        self.user_id = user_id
        self.item_id = item_id

        # 计算每首歌被多少用户听过
        # 使用groupby方法按物品ID对数据进行分组
        # agg方法用于聚合数据,这里使用count函数来计算每个组的用户数量之和
        # 对每个组中的 self.user_id 列使用 count 函数,以计算不同歌曲被播放的次数
        train_data_grouped = train_data.groupby([self.item_id]).agg({self.user_id: 'count'}).reset_index()
        # 将user_id列 重命名为`score`,表示流行度得分。
        train_data_grouped.rename(columns = {user_id: 'score'},inplace=True)
    
        # 根据歌曲的被播放总次数 排序(降序)
        # 如果被播放次数相同,按用户id(升序)。
        train_data_sort = train_data_grouped.sort_values(['score', self.item_id], ascending = [0,1])
    
        # 基于得分产生一个推荐排名(降序)
        train_data_sort['Rank'] = train_data_sort['score'].rank(ascending=0, method='first')
        
        #选择推荐排名中的前十首歌曲作为推荐结果,存入self.popularity_recommendations属性中
        # popularity_recommendations为df数据类型
        self.popularity_recommendations = train_data_sort.head(10)

    # Recommend方法 推荐操作
    def recommend(self, user_id):
        # 获取传入的用户id 对应的popularity_recommendations属性值
        user_recommendations = self.popularity_recommendations
        
        # 给popularity_recommendations添加一个新的列,列名为user_id,赋值为 传入的用户id
        user_recommendations['user_id'] = user_id
    
        # 调整列的顺序,将user_id列移至最前面
        # 将 user_recommendations DataFrame 的列名作为元素存入列表
        cols = user_recommendations.columns.tolist()
        # cols[-1:]取出列表的最后一个元素,cols[:-1]取出列表除最后一个元素的所有元素,拼接操作。
        cols = cols[-1:] + cols[:-1]
        # 此df数据user_recommendations 的列名顺序为cols列表中的列名顺序
        user_recommendations = user_recommendations[cols]

        # 返回推荐信息
        return user_recommendations
    

2.2 基于物品相似度的协同过滤算法

# 基于物品的协同过滤推荐系统
class item_similarity_recommender_py():
    def __init__(self):
        self.train_data = None
        self.user_id = None
        self.item_id = None
        self.cooccurence_matrix = None
        self.songs_dict = None
        self.rev_songs_dict = None
        self.item_similarity_recommendations = None
        
    #Get unique items (songs) corresponding to a given user
    # 得到给定用户的听过的所有歌(重复的歌曲不计入)
    def get_user_items(self, user):
        # 拿到当前用户听过的所有歌(一首歌可能出现很多次)
        # self.train_data[...] 使用布尔条件 过滤 train_data
        # 得到一个只包含指定用户的听歌信息
        user_data = self.train_data[self.train_data[self.user_id] == user]
        # 提取歌曲ID列名去重+变成列表
        user_items = list(user_data[self.item_id].unique())

        return user_items
        
    #Get unique users for a given item (song)
    # 得到给定的歌曲被哪些人听过
    def get_item_users(self, item):
        item_data = self.train_data[self.train_data[self.item_id] == item]
        item_users = set(item_data[self.user_id].unique())
            
        return item_users
        
    #Get unique items (songs) in the training data
    # 得到去重的歌曲列表
    def get_all_items_train_data(self):
        all_items = list(self.train_data[self.item_id].unique())
            
        return all_items


    #构建共现矩阵
    # 目标:遍历得出 66*4879矩阵中每首歌之间(用户听过的与歌曲库之间的歌)的相似度
    def construct_cooccurence_matrix(self, user_songs, all_songs):

        user_songs_users = []
        # 拿到用户听过的歌
        for i in range(0, len(user_songs)):
            # 找出这些歌还被哪些用户听过
            # 将这些新找到的用户存入 "与推荐用户听过同一首歌的用户" 的列表中
            user_songs_users.append(self.get_item_users(user_songs[i]))

        #初始化矩阵 len(user_songs) X len(songs) ——> 66*4879
        cooccurence_matrix = np.matrix(np.zeros(shape=(len(user_songs), len(all_songs))), float)

        # 接下来的目标:找出此用户听过的每一首歌 与 歌曲库的每一首歌 之间的关系
        # 如何确定关系?
        # 假设此用户听过 歌曲i,从歌曲库中选中 歌曲j;
        # i被8000人听过,j被7000人听过
        # 如果听过这首歌的这两个群体 大部分是同一个人,那么歌曲i与j的相似度很高
        # 公式化表示:( User_i 交 User_j )/( User_i 并 User_j )
        # 值越大,歌曲i与j受众越相似,说明i与j相似度越高

        # 遍历歌曲库的所有歌4879首
        for i in range(0,len(all_songs)):
            # 找到歌库中每首歌的所有信息
            songs_i_data = self.train_data[self.train_data[self.item_id] == all_songs[i]]
            # 找到 听过"遍历到的这首歌的"所有user
            users_i = set(songs_i_data[self.user_id].unique())

            # 遍历"推荐用户"听过的歌曲
            for j in range(0,len(user_songs)):
                # 将已经得到的"与推荐用户听过同一首歌的用户" 传入users_j列表中
                users_j = user_songs_users[j]
                # 计算两类人的交集
                users_intersection = users_i.intersection(users_j)
                
                #Calculate cooccurence_matrix[i,j] as Jaccard Index
                # 术语:计算共现矩阵中位置 [i,j] 的值作为Jaccard指数。
                # 如果用户的交集不等于0
                if len(users_intersection) != 0:
                    #计算两类人的并集
                    users_union = users_i.union(users_j)
                    # 矩阵中每个元素的值为 :交集/并集
                    # 得出的计算结果就是两首歌的相似度
                    cooccurence_matrix[j,i] = float(len(users_intersection))/float(len(users_union))
                else:
                    cooccurence_matrix[j,i] = 0

        return cooccurence_matrix

    #Use the cooccurence matrix to make top recommendations
    def generate_top_recommendations(self, user, cooccurence_matrix, all_songs, user_songs):
        print("矩阵中非0值的数量:%d" % np.count_nonzero(cooccurence_matrix))

        # 计算歌曲库中的每首歌(与用户听过的所有歌)的平均相似度!注意是取平均值
        # 假设 r1=j1*i1, 则歌曲j1的平均值:(j1*i1 + j1*i2 +...+ j1*i66)/66 = j1(i1+i2+...+i66)/66
        # 在所有歌曲jn中,j几的平均得分最高,也就是歌曲库中哪首歌的相似度最高,则推荐哪个

        # 如果 cooccurence_matrix 的形状是 (m, n)
        # 那么 cooccurence_matrix.sum(axis=0) 的结果将是一个长度为 n 的一维数组
        # 这个数组的每个元素都是 cooccurence_matrix 中对应 "列的总和"
        # 在上面代码中,cooccurence_matrix.sum(axis=0)的结果是:长度为4879的一维数组
        # float(cooccurence_matrix.shape[0])=66
        user_sim_scores = cooccurence_matrix.sum(axis=0)/float(cooccurence_matrix.shape[0])
 
        #将这些得分排序(降序)
        sort_index = sorted(( (i,e)for i,e in enumerate( list(user_sim_scores) ) ), reverse=True)
    
        #Create a dataframe from the following
        columns = ['user_id', 'song', 'score', 'rank']
        #将数组中的值作为列名赋值给df
        df = pandas.DataFrame(columns=columns)
         
        #Fill the dataframe with top 10 item based recommendations
        # 用基于歌曲相似度推荐得到的前10个结果 填到df中
        rank = 1 # 排名计数变量
        for i in range(0,len(sort_index)):
            # 每首歌曲满足以下条件 可执行:
            #
            # 得分不是 NaN
            # 该歌曲不在用户已听过的歌曲列表中
            # 尚未达到 10 个推荐的上限
            if ~np.isnan(sort_index[i][0]) and all_songs[sort_index[i][1]] not in user_songs and rank <= 10:
                # 如果满足上述条件,则在 DataFrame df 中添加一行,包含用户ID、歌曲名称、得分和排名
                df.loc[len(df)]=[user,all_songs[sort_index[i][1]],sort_index[i][0],rank]
                # 添加一条信息,更新一次排名
                rank = rank+1
        
        #如果df的行数为0,则表示没有推荐的歌曲
        if df.shape[0] == 0:
            print("The current user has no songs for training the item similarity based recommendation model.")
            return -1
        else:
            return df
 
    #Create the item similarity based recommender system model
    def create(self, train_data, user_id, item_id):
        self.train_data = train_data
        self.user_id = user_id
        self.item_id = item_id

    #Use the item similarity based recommender system model to
    # 为特定用户生成推荐
    def recommend(self, user):

        #A. Get all unique songs for this user
        user_songs = self.get_user_items(user)    
            
        print("No. of unique songs for the user: %d" % len(user_songs))

        #B. Get all unique items (songs) in the training data
        all_songs = self.get_all_items_train_data()
        
        print("no. of unique songs in the training set: %d" % len(all_songs))

        #C. Construct item cooccurence matrix of size 
        #len(user_songs) X len(songs)
        cooccurence_matrix = self.construct_cooccurence_matrix(user_songs, all_songs)

        #D. Use the cooccurence matrix to make recommendations
        df_recommendations = self.generate_top_recommendations(user, cooccurence_matrix, all_songs, user_songs)
                
        return df_recommendations
    
    #Get similar items to given items
    # 为给定的歌曲列表生成相似的歌曲
    def get_similar_items(self, item_list):
        
        user_songs = item_list

        #B. Get all unique items (songs) in the training data
        all_songs = self.get_all_items_train_data()
        
        print("no. of unique songs in the training set: %d" % len(all_songs))

        #C. Construct item cooccurence matrix of size 
        #len(user_songs) X len(songs)
        cooccurence_matrix = self.construct_cooccurence_matrix(user_songs, all_songs)

        #D. Use the cooccurence matrix to make recommendations
        user = ""
        df_recommendations = self.generate_top_recommendations(user, cooccurence_matrix, all_songs, user_songs)
         
        return df_recommendations

2.3 基于SVD矩阵分解的协同过滤算法

2.3.1 理论部分

为什么使用矩阵分解:因为矩阵太大

在这里插入图片描述

假设A矩阵很大,我们将A矩阵转换为非常小的矩阵

对矩阵进行SVD分解,得到SUV矩阵

在这里插入图片描述
特征向量为列向量,每个列都代表一个特征的值

根据S矩阵每一列对应U矩阵的每个特征,值越大,表示特征越重要
如果S矩阵的前两个值占总值的绝大部分比例 则取这前几个特征即可

取S矩阵中的前两个值,代表 :取矩阵的前两个特征

在这里插入图片描述

SVD本质:将较大的矩阵进行压缩,同时保留其最重要的信息,也就是取近似操作

重新计算USV矩阵相乘的结果得到A2,比较A2和A的差异,可见差异不大,因此可以用来做近似

在这里插入图片描述

2.3.2 代码

用户听不同歌的次数占总听歌次数的比率作为评分

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

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

相关文章

Java每日一题(三道同一类型的题)

前言 本文一共有三道题:1.两数之和 2.三数之和 3. 四数之和 为什么把这三道题放一起呢&#xff0c;因为三数之和是可以根据两数之和进行推导&#xff0c;四数之和可以根据三数之和进行推导。 两数之和 思路分析: 我的思路: 1.排序 2.使用左右指针 3.处理细节问题 先让数组…

人工智能——深度学习

4. 深度学习 4.1. 概念 深度学习是一种机器学习的分支&#xff0c;旨在通过构建和训练多层神经网络模型来实现数据的高级特征表达和复杂模式识别。与传统机器学习算法相比&#xff0c;深度学习具有以下特点&#xff1a; 多层表示学习&#xff1a;深度学习使用深层神经网络&a…

Java后端常见场景业务问题

目录 单点登录如何实现权限认证如何实现上传数据的安全性如何保证订单表每天新增500W数据,分库分表的方案应该如何设计?订单表每天新增500W数据,分库分表的方案应该如何设计?*********************项目日志如何采集已经上线的bug如何排查如何快速定位系统瓶颈单点登录如何实…

Golang使用PGO优化程序性能

文章目录 参考文章PGO是什么使用PGO的好处PGO做了什么热函数内联什么是内联内联的好处Go默认的内联策略PGO的热函数内联 去虚拟化调用指令高速缓存 PGO有什么缺点可执行程序变大构建时间变长 PGO怎么使用典型的工作流程收集CPU配置文件生产环境启动PGO代码改动重新生成CPU配置文…

基于Whisper语音识别的实时视频字幕生成 (一): 流式显示视频帧和音频帧

Whishow Whistream&#xff08;微流&#xff09;是基于Whisper语音识别的的在线字幕生成工具&#xff0c;支持rtsp/rtmp/mp4等视频流在线语音识别 1. whishow介绍 whishow&#xff08;微秀&#xff09;是在线音视频流播放python实现&#xff0c;支持rtsp/rtmp/mp4等输入&…

人工智能——大语言模型

5. 大语言模型 5.1. 语言模型历史 20世纪90年代以前的语言模型都是基于语法分析这种方法&#xff0c;效果一直不佳。到了20世纪90年代&#xff0c;采用统计学方法分析语言&#xff0c;取得了重大进展。但是在庞大而复杂的语言信息上&#xff0c;基于传统统计的因为计算量巨大…

【Docker】Docker概述及引擎

一、docker概述 DevOps DevOps是一种执行标准&#xff08;思想&#xff09;&#xff0c;主要用于促进开发、测试与运维的整合 容器与虚拟机的区别 最大的区别是&#xff0c;虚拟机中存在独立的硬件系统与操作系统&#xff0c;容器中全部是共享的宿主机中的操作系统与硬件系…

[dvwa] sql injection(Blind)

blind 0x01 low 1’ and length(version()) 6 # syntax: substr(string , from<start from 1>, cut length) 1’ and substr(version(),1,1) ‘5’ # 1’ and substr(version(),2,1) ‘.’ # 1’ and substr(version(),3,1) ‘7’ # 1’ and substr(version(),4,…

酷写写靠谱不 #知识分享#媒体

酷写写是一个值得推荐的论文写作工具&#xff0c;它不仅靠谱而且非常好用。在如今这个信息爆炸的时代&#xff0c;学术界对于论文的要求越来越严格&#xff0c;论文必须具有独创性和高质量才能获得认可。而酷写写的出现&#xff0c;为广大学生和学者提供了一个便捷、高效的写作…

SuperMap三维复杂模型建模之3D极坐标建模——原理篇

作者&#xff1a;超图研究院技术支持中心-于丁 随着SuperMap iDesktop 10i(2021) V10.2.1的上线发布&#xff0c;为进一步拓展全空间数据模型及其分析计算能力&#xff0c;一个新功能“3D极坐标建模”也随着该版本悄然上线。 3D极坐标建模功能实现根据UV参数和数学表达式&…

【Python系列】Jupyter Notebook 中执行 Shell 脚本的方法

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【随笔】Git 高级篇 -- 项目里程碑 git tag(二十)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

绝地求生:杜卡迪系列活动集合 各种活动送不停

今天更新已结束&#xff0c;速度上好开冲&#xff01; 春季签到活动&#xff08;第1轮&#xff09; 活动时间 4月9日 - 4月22日 12&#xff1a;00 任务要求 每日登录游戏&#xff08;每日上午10点刷新&#xff09; 活动期间全勤可获得奖励如下 杜卡迪物资箱 (x1) 杜卡迪活…

【C++杂货铺】详解 stack 和 queue

&#x1f308;前言&#x1f308; 欢迎收看本期【C杂货铺】&#xff0c;本期内容将讲解CSTL中stack和queue的内容&#xff0c;其中包含了stack &#xff0c; queue&#xff0c;priority_queue是什么&#xff0c;怎么使用以及模拟实现这些容器。 此外&#xff0c;还将将讲解设计模…

【迅为iMX6Q】开发板 Linux version 6.6.3 SD卡 启动

开发环境 win10 64位 VMware Workstation Pro 16 ubuntu 20.04 【迅为imx6q】开发板&#xff0c; 2G DDR RAM linux-imx 下载 使用 NXP 官方提供的 linux-imx&#xff0c;代码地址为&#xff1a; https://github.com/nxp-imx/linux-imx 使用 git 下载 linux-imx&#xff…

STM32学习和实践笔记(6):自己进行时钟配置的思路

在《STM32学习和实践笔记&#xff08;4&#xff09;: 分析和理解GPIO_InitTypeDef GPIO_InitStructure (d)-CSDN博客》 中&#xff0c;我了解到&#xff0c;在程序执行我们写的main函数之前&#xff0c;实际上先执行了一个汇编语言所写的启动文件&#xff0c;以完成相应的初始…

python爬虫-----爬虫解析—xpath(第十八天)

&#x1f388;&#x1f388;作者主页&#xff1a; 喔的嘛呀&#x1f388;&#x1f388; &#x1f388;&#x1f388;所属专栏&#xff1a;python爬虫学习&#x1f388;&#x1f388; ✨✨谢谢大家捧场&#xff0c;祝屏幕前的小伙伴们每天都有好运相伴左右&#xff0c;一定要天天…

Day:004(4) | Python爬虫:高效数据抓取的编程技术(数据解析)

XPath工具 浏览器-元素-CtrlF 浏览器-控制台- $x(表达式) Xpath helper (安装包需要科学上网) 问题 使用离线安装包 出现 程序包无效 解决方案 使用修改安装包的后缀名为 rar&#xff0c;解压文件到一个文件夹&#xff0c;再用 加载文件夹的方式安装即可 安装 python若使用…

功能测试_验证qq账号的合法性

案例&#xff1a;验证qq账号的合法性&#xff08;要求&#xff1a;6-10位的自然数&#xff09; 使用等价类设计用例案例&#xff1a; 步骤&#xff1a; 1:明确需求&#xff1a;qq账号的合法性 2:划分等价类&#xff1a;有效等价类、有效取值、无效等价类、无效取值 3&…