从0开始学习机器学习--Day32--推荐系统作业

题目:给用户推荐电影

代码:

import numpy as np
import matplotlib.pyplot as plt
import scipy.io as sio
from scipy.optimize import minimize
def serialize(X, theta):# 序列化,因为后续优化方法对参数的要求为一维return np.append(X.flatten(), theta.flatten())def deserialize(paramers, nm, nu, nf):X = paramers[:nm*nf].reshape(nm, nf)#reshape() 里写nm是因为X代表的是电影数据theta = paramers[nm*nf:].reshape(nu, nf)#reshape() 里写nu是因为theta代表的是用户数据return X, thetadef cost_function(paramers, Y, R, nm, nu, nf, lamda):#代价函数X, theta = deserialize(paramers, nm, nu, nf)error = 0.5*np.square((X@theta.T-Y)*R).sum()# 乘以R是因为公式里要求是对电影进行评分了的用户reg_1 = 0.5*lamda*np.square(X).sum()reg_2 = 0.5*lamda*np.square(theta).sum()return error + reg_1 + reg_2def cost_gradient(paramers, Y, R, nm, nu, nf, lamda):# 梯度下降X, theta = deserialize(paramers, nm, nu, nf)X_gradient = ((X@theta.T-Y)*R)@theta + lamda*Xtheta_gradient = ((X@theta.T-Y)*R).T@X + lamda*theta #这里用转置是遵守矩阵乘法法则return serialize(X_gradient, theta_gradient)def normalize_ratings(Y, R):#均值归一化Y_mean = (Y.sum(axis=1)/R.sum(axis=1)).reshape(-1, 1)# R的作用依然是为了定位做了评分的用户,这里reshape成二维矩阵是为了后续方便计算Y_norm = (Y-Y_mean)*Rreturn Y_norm, Y_meanmat = sio.loadmat('./data/ex8_movies.mat')
print(mat.keys())
Y, R = mat['Y'], mat['R']#Y存放的是用户对电影的评分,R存放的是判断用户是否做了评分
print(Y.shape, R.shape)paramer_mat = sio.loadmat('./data/ex8_movieParams.mat')
print(paramer_mat.keys())
X = paramer_mat['X']
theta = paramer_mat['Theta']
nu, nm, nf = paramer_mat['num_users'], paramer_mat['num_movies'], paramer_mat['num_features']
print(X.shape, theta.shape)
print(nu, nm, nf)
nu = int(nu)#将矩阵转换为整数,方便后续计算
nm = int(nm)
nf = int(nf)
print(nu, nm, nf)users = 4
movies = 5
features = 3
X_sub = X[:movies, :features]#取子集进行测试
theta_sub = theta[:users, :features]
Y_sub = Y[:movies, :users]
R_sub = R[:movies, :users]
cost1 = cost_function(serialize(X_sub, theta_sub), Y_sub, R_sub, movies, users, features, lamda=0)
print(cost1)
cost2 = cost_function(serialize(X_sub, theta_sub), Y_sub, R_sub, movies, users, features, lamda=0.5)
print(cost2)#添加个体用户,修改部分数据测试一下算法
new_ratings = np.zeros((nm, 1))
new_ratings[9] = 5
new_ratings[66] = 5
new_ratings[96] = 5
new_ratings[121] = 4
new_ratings[148] = 4
new_ratings[285] = 3
new_ratings[490] = 4
new_ratings[599] = 4
new_ratings[643] = 4
new_ratings[958] = 5
new_ratings[1117] = 3y = np.c_[Y, new_ratings]
r = np.c_[R, new_ratings!=0]#!=0是根据判断是否不为0返回True或False,因为这里只需要作是否评分的判断
print(y.shape)Y_norm, Y_mean = normalize_ratings(Y, R)#参数初始化
X = np.random.random((nm, nf))
theta =np.random.random((nu, nf))
paramers = serialize(X, theta)
lamda = 5#模型训练
res = minimize(fun=cost_function,x0=paramers,args=(Y_norm, R, nm, nu, nf, lamda),method='TNC',jac=cost_gradient,options={'maxiter':100})paramers_fit = res.x#训练好的参数
fit_X, fit_theta = deserialize(paramers_fit, nm, nu, nf)#预测
y_pred =fit_X@fit_theta.T
y_pred = y_pred[:, -1] - Y_mean.flatten()
index = np.argsort(y_pred)#按照从小到大顺序排列
print(index[:10])#输出排名靠前的,看看模型训练后认为预测样本会喜欢什么样的电影movie = []
with open('./data/movie_ids.txt', 'r', encoding='latin 1') as f:for line in f:tokens = line.strip().split(' ')#用空格来区分要分开的元素movie.append(' '.join(tokens[1:]))#不要第一个序号print(len(movie))for i in range(10):print(index[i], movie[index[i]], y_pred[index[i]])

输出:

dict_keys(['__header__', '__version__', '__globals__', 'Y', 'R'])
(1682, 943) (1682, 943)
dict_keys(['__header__', '__version__', '__globals__', 'X', 'Theta', 'num_users', 'num_movies', 'num_features'])
(1682, 10) (943, 10)
[[943]] [[1682]] [[10]]
943 1682 10
22.224603725685675
25.264421231881858
(1682, 944)
[407 123 646  58 693 960 284 653 515  19]
1682
407 Close Shave, A (1995) -5.662341746658825
123 Lone Star (1996) -5.584866704894469
646 Ran (1985) -5.439118447769447
58 Three Colors: Red (1994) -5.3926736164854745
693 Persuasion (1995) -5.327031454117134
960 Orlando (1993) -5.273157229690771
284 Secrets & Lies (1996) -5.272872567424451
653 Chinatown (1974) -5.272511152020712
515 Local Hero (1983) -5.261092245742169
19 Angels and Insects (1995) -5.2378273984105785

小结:均值归一化的必要性:预测用户的评分在结果出来前是不知道的,不作归一化会使某些数据过大是结果偏移;在做最终预测前可以人造一个小数据用于检测算法可用性,避免每次都要运行整哥算法,方便进行优化。

作业订正:https://blog.csdn.net/weixin_43490087/article/details/139842732

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

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

相关文章

Elasticsearch是如何实现Master选举的?

大家好,我是锋哥。今天分享关于【Elasticsearch是如何实现Master选举的?】面试题。希望对大家有帮助; Elasticsearch是如何实现Master选举的? Elasticsearch 使用 Zen Discovery 插件(在较新的版本中是基于 Zen2&…

WEB-通用漏洞SQL注入CTF二次堆叠DNS带外

知识点: 1、数据库堆叠注入 根据数据库类型决定是否支持多条语句执行 数据库支持多条语句执行就是堆叠,如: 2、数据库二次注入 应用功能逻辑涉及上导致的先写入后组合的注入 3、数据库Dnslog注入 解决不回显(反向连接&#…

上生产时连接mysql数据库总是被拒绝

背景: 本地项目连接数据正常 测试环境也正常 到生产上就一直报错 且生产上使用mysql连接工具可以正常连接 报错信息:Connections refused: connect 调查: 数据库版本: 本地 mysql5.7.24 测试 8.3 生产5.7.36 连接驱动&#xf…

20241121买深圳保障房还是租保租房小思考?

1. 我的买深圳保障房或租保租房的出发点? 我的需求:主要是小孩读书 如果买深圳保障房例如人才房和安居房,会有购房合同,则读书积分等同有红本积分,相当于可以选择一些不错的公办学校 如果租保租房,由于查…

鸿蒙生态崛起

1.鸿蒙生态:开发者的新蓝海 从开发者角度看,鸿蒙生态带来了巨大机遇。其分布式能力实现了不同设备间的无缝体验,如多屏协同,让应用能跨手机、平板、智能穿戴和车载设备流畅运行。开发工具也有显著提升,方舟编译器等极大…

使用Python3实现Gitee码云自动化发布

仓库信息 https://gitee.com/liumou_site/ip 实现代码 import osimport requests from loguru import loggerdef gitee(ver, message, prerelease: bool False):"""在 Gitee 上创建发布版本:param ver: 版本号:param message: 发布信息:param prerelease: 是…

第75期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区,集成了生成预训练Transformer(GPT)、人工智能生成内容(AIGC)以及大语言模型(LLM)等安全领域应用的知识。在这里,您可以找…

常见网络厂商设备默认用户名/密码大全

常见网络厂商的默认用户名/密码 01 思科 (Cisco) 设备类型:路由器、交换机、防火墙、无线控制器 默认用户名:cisco 默认密码:cisco 设备类型:网管型交换机 默认用户名:admin 默认密码:admin 02 华…

DICOM图像解析:深入解析DICOM格式文件的高效读取与处理

引言 在医学影像领域,DICOM(Digital Imaging and Communications in Medicine)标准已成为信息交换和存储的核心规范。掌握DICOM文件的读取与解析,对于开发医学影像处理软件至关重要。本文将系统地解析DICOM文件的结构、关键概念,并提供高效的读取与显示方法,旨在为开发者…

例题10-4 冒泡排序 字符串排序

void SortString(char str[][MAX_LEN], int n) {int i,j;char temp[MAX_LEN];for(i0;i<n-1;i){for(ji1;j<n;j){if(strcmp(str[i],str[j])<0) {strcpy(temp,str[i]);strcpy(str[i],str[j]);strcpy(str[j],temp);}}} } //升序排列 和 降序排列可能不只是 判断条件…

嵌入式硬件电子电路设计(六)LDO低压差线性稳压器全面详解

引言&#xff1a; LDO&#xff08;Low Dropout Regulator&#xff0c;低压差线性稳压器&#xff09;是一种常用的电源管理组件&#xff0c;用于提供稳定的输出电压&#xff0c;同时允许较小的输入电压与输出电压之间的差值。LDO广泛应用于各种电子设备中&#xff0c;特别是在对…

STM32H7开发笔记(2)——H7外设之多路定时器中断

STM32H7开发笔记&#xff08;2&#xff09;——H7外设之多路定时器中断 文章目录 STM32H7开发笔记&#xff08;2&#xff09;——H7外设之多路定时器中断0.引言1.CubeMX配置2.软件编写 0.引言 本文PC端采用Win11STM32CubeMX4.1.0.0Keil5.24.2的配置&#xff0c;硬件使用STM32H…

OpenCV从入门到精通实战(九)——基于dlib的疲劳监测 ear计算

本文实现Python库d和OpenCV来实现眼部闭合检测&#xff0c;主要用于评估用户是否眨眼。 步骤一&#xff1a;导入必要的库和设置参数 首先&#xff0c;代码导入了必要的Python库&#xff0c;如dlib、OpenCV和scipy。通过argparse设置了输入视频和面部标记预测器的参数。 from…

后端开发详细学习框架与路线

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;后端开发 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 为帮助你合理安排时间&#xff0c;以下是结合上述学习内容的阶段划分与时间分配建议。时间安排灵活&a…

如何在 Ubuntu 上安装 Mosquitto MQTT 代理

如何在 Ubuntu 上安装 Mosquitto MQTT 代理 Mosquitto 是一个开源的消息代理&#xff0c;实现了消息队列遥测传输 (MQTT) 协议。在 Ubuntu 22.04 上安装 MQTT 代理&#xff0c;您可以利用 MQTT 轻量级的 TCP/IP 消息平台&#xff0c;该平台专为资源有限的物联网 (IoT) 设备设计…

Webserver回顾

线程池如何工作&#xff1f; 从请求队列中取出request请求&#xff0c;然后process处理 process是处理业务代码&#xff0c;用于解析http请求的 如何为线程上锁 由于线程共享同一块资源&#xff0c;为了避免线程重复读写资源的数据安全问题 发什么信号 定义信号 信号量如…

实验室资源调度系统:基于Spring Boot的创新

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

STM32与CS创世SD NAND(贴片SD卡)结合完成FATFS文件系统移植与测试是一个涉及硬件与软件综合应用的复杂过程

一、前言 在STM32项目开发中&#xff0c;经常会用到存储芯片存储数据。 比如&#xff1a;关机时保存机器运行过程中的状态数据&#xff0c;上电再从存储芯片里读取数据恢复&#xff1b;在存储芯片里也会存放很多资源文件。比如&#xff0c;开机音乐&#xff0c;界面上的菜单图…

【在Linux世界中追寻伟大的One Piece】手写序列化与反序列化

目录 1 -> 序列化与反序列化概念 2 -> 序列化与反序列化作用和应用场景 3 -> 手写序列化与反序列化 1 -> 序列化与反序列化概念 序列化是指将对象的状态信息转换为可以存储或传输的形式的过程&#xff0c;通常涉及将数据结构或对象转换成字节流或字符串格式。反…

uniapp自动注册机制:easycom

传统 Vue 项目中&#xff0c;我们需要注册、导入组件之后才能使用组件。 uniapp 框架提供了一种组件自动注册机制&#xff0c;只要你在 components 文件夹下新建的组件满足 /components/组件名/组件名.vue 的命名规范&#xff0c;就能直接使用。 注意&#xff1a;组件的文件夹…