推荐系统实践(七)CB

2023-11-21 06:10
文章标签 系统 实践 推荐 cb

本文主要是介绍推荐系统实践(七)CB,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

数据集:
temp_user_scores_mat.csv 用户–节目评分矩阵
temp_users_movies_01mat.csv 节目及其所属标签类型的01矩阵
temp_movies_01mat.csv 用户收视了的节目–标签01矩阵

整体流程:
根据用户的评分矩阵,可以得到用户对不同类别电影的偏爱程度;再根据类别和其他的电影构成的类别矩阵,得到用户的推荐列表。

第一步 求每个用户的平均评分
在这里插入图片描述
求和/(不为0的位置的个数)

第二步 求每个用户对每个类别的平均评分
在这里插入图片描述
比如对于用户1,每个位置的评分-用户的平均评分,再对每个Lable求平均

第三步: 求每个用户没看过的电影与第二步所求的每个类别平均评分的余弦相似度,作为最后的评测指标在这里插入图片描述

一、创建节目画像:
createItemsProfiles(参数:df,all_labels,所有电影) : 每个item对应的类别,构成一个矩阵(就是取每一行)
得到items_users_saw_profiles :{电影名字:{类型1:属于不属于类型1(0 or 1)}}

二、创建用户画像
createUsersProfiles(df,人,电影,类别,items_users_saw_profiles(节目画像) ):
1.遍历user-items矩阵:得到每个人的平均值 (评分总和/有评分的电影数)
2.for 每个人:
for 每个lable:
for 每个电影:
if 每个电影的属于某个label(为1,或者大于0):
则电影的属于某个Label的值-均值
再求平均值

计算user-label的评分
用户user1对于类型label1的隐性评分: user1_score_to_label1
用户user1对于其看过的含有类型label1的节目item i 的评分: score_to_item i
用户user1对其所看过的所有节目的平均评分: user1_average_score
用户user1看过的节目总数: items_count
公式: user1_score_to_label1 = Sigma(score_to_item i - user1_average_score)/items_count

items_users_saw 保存 {人名:[电影名]}
items_users_saw_scores 保存{人名:[[电影:分数],[]]}
users_average_scores_list: 保存{人名:平均评分}
users_profiles: 保存 {人名:{label:分数}} (分数的计算)

三、推荐节目集建立节目画像
createItemsProfiles(df,类别,电影名(所有))

四、对每个用户推荐电影
contentBased()
如果在用户看过的电影里则pass,如果不在计算相似度。最后对相似度排序。最后输出前5个值。
相似度计算:cos(user, item) = sigma_ui/sqrt(sigma_u * sigma_i) calCosDistance()计算余弦相似度

import math
import pandas as pd
import numpy as np
import os# 创建节目画像
# 参数说明:
# items_profiles = {item1:{'label1':1, 'label2': 0, 'label3': 0, ...}, item2:{...}...}
def createItemsProfiles(data_array, labels_names, items_names):items_profiles = {}for i in range(len(items_names)):items_profiles[items_names[i]] = {}for j in range(len(labels_names)):items_profiles[items_names[i]][labels_names[j]] = data_array[i][j]return items_profiles# 创建用户画像
# 参数说明:
# data_array: 所有用户对于其所看过的节目的评分矩阵 data_array = [[2, 0, 0, 1.1, ...], [0, 0, 1.1, ...], ...]
# users_profiles = {user1:{'label1':1.1, 'label2': 0.5, 'label3': 0.0, ...}, user2:{...}...}
def createUsersProfiles(data_array, users_names, items_names, labels_names, items_profiles):users_profiles = {}# 计算每个用户对所看过的所有节目的平均隐性评分# users_average_scores_list = [1.2, 2.2, 4.3,...]users_average_scores_list = []# 统计每个用户所看过的节目(不加入隐性评分信息)# items_users_saw = {user1:[item1, item3, item5], user2:[...],...}items_users_saw = {}# 统计每个用户所看过的节目及评分# items_users_saw_scores = {user1:[[item1, 1.1], [item2, 4.1]], user2:...}items_users_saw_scores = {}for i in range(len(users_names)):items_users_saw_scores[users_names[i]] = []items_users_saw[users_names[i]] = []count = 0sum = 0.0for j in range(len(items_names)):# 用户对该节目隐性评分为正,表示真正看过该节目if data_array[i][j] > 0:items_users_saw[users_names[i]].append(items_names[j])items_users_saw_scores[users_names[i]].append([items_names[j], data_array[i][j]])count += 1sum += data_array[i][j]if count == 0:users_average_scores_list.append(0)else:users_average_scores_list.append(sum / count)for i in range(len(users_names)):users_profiles[users_names[i]] = {}for j in range(len(labels_names)):count = 0score = 0.0for item in items_users_saw_scores[users_names[i]]:# 参数:# 用户user1对于类型label1的隐性评分: user1_score_to_label1# 用户user1对于其看过的含有类型label1的节目item i 的评分: score_to_item i# 用户user1对其所看过的所有节目的平均评分: user1_average_score# 用户user1看过的节目总数: items_count# 公式: user1_score_to_label1 = Sigma(score_to_item i - user1_average_score)/items_count# 该节目含有特定标签labels_names[j]if items_profiles[item[0]][labels_names[j]] > 0:score += (item[1] - users_average_scores_list[i])count += 1# 如果求出的值太小,直接置0if abs(score) < 1e-6:score = 0.0if count == 0:result = 0.0else:result = score / countusers_profiles[users_names[i]][labels_names[j]] = resultreturn (users_profiles, items_users_saw)# 创建节目画像
# 参数说明:
# items_profiles = {item1:{'label1':1, 'label2': 0, 'label3': 0, ...}, item2:{...}...}
def createItemsProfiles(data_array, labels_names, items_names):items_profiles = {}for i in range(len(items_names)):items_profiles[items_names[i]] = {}for j in range(len(labels_names)):items_profiles[items_names[i]][labels_names[j]] = data_array[i][j]return items_profiles# 计算用户画像向量与节目画像向量的距离(相似度)
# 向量相似度计算公式:
# cos(user, item) = sigma_ui/sqrt(sigma_u * sigma_i)# 参数说明:
# user_profile: 某一用户user的画像 user = {'label1':1.1, 'label2': 0.5, 'label3': 0.0, ...}
# item: 某一节目item的画像 item = {'label1':1, 'label2': 0, 'label3': 0, ...}
# labels_names: 所有类型名
def calCosDistance(user, item, labels_names):sigma_ui = 0.0sigma_u = 0.0sigma_i = 0.0for label in labels_names:sigma_ui += user[label] * item[label]sigma_u += (user[label] * user[label])sigma_i += (item[label] * item[label])if sigma_u == 0.0 or sigma_i == 0.0:  # 若分母为0,相似度为0return 0return sigma_ui / math.sqrt(sigma_u * sigma_i)# 基于内容的推荐算法:
# 借助特定某个用户user的画像user_profile和备选推荐节目集的画像items_profiles,通过计算向量之间的相似度得出推荐节目集# 参数说明:
# user_profile: 某一用户user的画像 user_profile = {'label1':1.1, 'label2': 0.5, 'label3': 0.0, ...}
# items_profiles: 备选推荐节目集的节目画像: items_profiles = {item1:{'label1':1, 'label2': 0, 'label3': 0}, item2:{...}...}
# items_names: 备选推荐节目集中的所有节目名
# labels_names: 所有类型名
# items_user_saw: 用户user看过的节目def contentBased(user_profile, items_profiles, items_names, labels_names, items_user_saw):# 对于用户user的推荐节目集为 recommend_items = [[节目名, 该节目画像与该用户画像的相似度], ...]recommend_items = []for i in range(len(items_names)):# 从备选推荐节目集中的选择用户user没有看过的节目if items_names[i] not in items_user_saw:recommend_items.append([items_names[i], calCosDistance(user_profile, items_profiles[items_names[i]], labels_names)])# 将推荐节目集按相似度降序排列recommend_items.sort(key=lambda item: item[1], reverse=True)return recommend_items# 输出推荐给该用户的节目列表
# max_num:最多输出的推荐节目数
def printRecommendedItems(recommend_items_sorted, max_num):count = 0for item, degree in recommend_items_sorted:print("节目名:%s, 推荐指数:%f" % (item, degree))count += 1if count == max_num:break# 主程序
if __name__ == '__main__':all_users_names = ['3', '13', '23']# 按指定顺序排列所有的标签all_labels = ['剧情', '西部', '家庭', '惊悚', '动画','爱情', '情色', '运动', '音乐', '灾难','悬疑', '儿童', '短片', '历史', '动作','科幻', '传记', '同性', '冒险', '歌舞','脱口秀', '真人秀', '新闻', '恐怖', '奇幻','犯罪', '喜剧', '纪录片', '战争', '古装','武侠', '综艺', '电视剧', '邵氏', '电影']labels_num = len(all_labels)# 读取用户--节目评分矩阵df1 = pd.read_csv('../data/dianshi-data/temp_user_scores_mat.csv', sep=',', encoding='gbk',header='infer', error_bad_lines=False)# print(df1)(m1, n1) = df1.shape# print(m1,n1)# 所有用户对其看过的节目的评分矩阵data_array1 = np.array(df1.iloc[:m1 + 1, 1:])#print(data_array1)   #得到矩阵# 按照"所有用户对其看过的节目的评分矩阵"的列序排列的所有用户观看过的节目名称items_users_saw_names1 = df1.columns[1:].tolist()#print(items_users_saw_names1) #'剧场', '王牌对王牌', '最强大脑', '金牌调解',# 读取用户观看过的节目及其所属类型的01矩阵df2 = pd.read_csv('../data/dianshi-data/temp_users_movies_01mat.csv', sep=',', encoding='gbk',header='infer', error_bad_lines=False)(m2, n2) = df2.shapedata_array2 = np.array(df2.iloc[:m2 + 1, 1:])#print(data_array2)# 按照"所有用户看过的节目及所属类型的01矩阵"的列序排列的所有用户观看过的节目名称# items_users_saw_names2 = np.array(df2.iloc[:m2 + 1, 0]).tolist()   #此句语句得不到节目名称items_users_saw_names2 = np.array(df2.iloc[:m2 + 1, 0]).tolist()#print(items_users_saw_names2)  #节目名# 为用户看过的节目建立节目画像items_users_saw_profiles = createItemsProfiles(data_array2, all_labels, items_users_saw_names2)#print(items_users_saw_profiles) #每一行的值# 建立用户画像users_profiles和用户看过的节目集items_users_saw(users_profiles, items_users_saw) = createUsersProfiles(data_array1, all_users_names, items_users_saw_names1,all_labels, items_users_saw_profiles)# print(users_profiles)# 读取备选节目及其所属类型的01矩阵df3 = pd.read_csv('../data/dianshi-data/temp_movies_01mat.csv', sep=',', encoding='gbk',header='infer', error_bad_lines=False)(m3, n3) = df3.shapedata_array3 = np.array(df3.iloc[:m3 + 1, 1:])# 按照"备选推荐节目集及所属类型01矩阵"的列序排列的所有用户观看过的节目名称items_to_be_recommended_names = np.array(df3.iloc[:m3 + 1, 0]).tolist()# 为备选推荐节目集建立节目画像items_to_be_recommended_profiles = createItemsProfiles(data_array3, all_labels, items_to_be_recommended_names)# 开始推荐for user in all_users_names:print("给用户id为 %s 的推荐节目如下:" % user)recommend_items = contentBased(users_profiles[user], items_to_be_recommended_profiles,items_to_be_recommended_names, all_labels, items_users_saw[user])printRecommendedItems(recommend_items, 5)print('该用户推荐任务完成。')

得到推荐结果:
在这里插入图片描述

参考:
https://blog.csdn.net/qq_38281438/article/details/83615810
数据下载https://download.csdn.net/download/qq_38281438/10757266

这篇关于推荐系统实践(七)CB的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/400358

相关文章

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

tomcat多实例部署的项目实践

《tomcat多实例部署的项目实践》Tomcat多实例是指在一台设备上运行多个Tomcat服务,这些Tomcat相互独立,本文主要介绍了tomcat多实例部署的项目实践,具有一定的参考价值,感兴趣的可... 目录1.创建项目目录,测试文China编程件2js.创建实例的安装目录3.准备实例的配置文件4.编辑实例的

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

springboot集成Deepseek4j的项目实践

《springboot集成Deepseek4j的项目实践》本文主要介绍了springboot集成Deepseek4j的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录Deepseek4j快速开始Maven 依js赖基础配置基础使用示例1. 流式返回示例2. 进阶

Linux系统之主机网络配置方式

《Linux系统之主机网络配置方式》:本文主要介绍Linux系统之主机网络配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、查看主机的网络参数1、查看主机名2、查看IP地址3、查看网关4、查看DNS二、配置网卡1、修改网卡配置文件2、nmcli工具【通用

Linux系统之dns域名解析全过程

《Linux系统之dns域名解析全过程》:本文主要介绍Linux系统之dns域名解析全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、dns域名解析介绍1、DNS核心概念1.1 区域 zone1.2 记录 record二、DNS服务的配置1、正向解析的配置