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

Qt打开文件对话框选择文件之后弹出两次

项目场景: 在 Qt 中,使用 ui 自动生成的 UI 文件会为每个控件自动生成一些默认的槽函数。如果您手动创建的槽函数名称与这些自动生成的槽函数名称相同,就会导致信号被多次连接,从而引发多次弹出文件对话框的问题。 原因分析&…

4. SQL视图

MySQL中的视图(View)是一种虚拟表,本质是存储了一条SELECT语句。视图并不直接存储数据,而是动态生成结果集,帮助开发者简化查询逻辑和增强数据安全性。本文将从视图的基础概念到实际应用,逐步深入地探讨如何…

从繁琐到优雅:用 PyTorch Lightning 简化深度学习项目开发

从繁琐到优雅:用 PyTorch Lightning 简化深度学习项目开发 在深度学习开发中,尤其是使用 PyTorch 时,我们常常需要编写大量样板代码来管理训练循环、验证流程和模型保存等任务。PyTorch Lightning 作为 PyTorch 的高级封装库,帮助…

鸿蒙生态崛起

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: 是…

找不同异或

给定两个字符串 s 和 t ,它们只包含小写字母。 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。 请找出在 t 中被添加的字母。 输入:s "abcd", t "abcde" 输出:"e" 解释&#xff…

第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文件的结构、关键概念,并提供高效的读取与显示方法,旨在为开发者…

信息打点学习

信息打点 web 操作系统 中间件 脚本语言 数据库 源码名称 端口扫描 源码获取 所用框架 CMS识别(指纹识别) 查同服务器的不同web应用:旁注 查同网段下面的不同服务器IP下的web应用查询技术:查c段 www.123.com 目标 没有什…

例题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);}}} } //升序排列 和 降序排列可能不只是 判断条件…

达索系统亮相第三十一届中国汽车工程学会年会暨展览会

伴随着改革开放以及中国入世WTO&#xff0c;三十多年来&#xff0c;中国汽车产销已经成为世界最大的单一市场而独占鳌头。近十年来&#xff0c;另辟蹊径的中国汽车产业人在新能源汽车赛道上引领了一波又一波令全球惊艳的创新成就&#xff0c;成为最为靓丽的新出口三大件的头牌。…

剑指offer JZ59 滑动窗口的最大值

描述 剑指offer JZ59 滑动窗口的最大值 给定一个长度为 n 的数组 num 和滑动窗口的大小 size &#xff0c;找出所有滑动窗口里数值的最大值。 例如&#xff0c;如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3&#xff0c;那么一共存在6个滑动窗口&#xff0c;他们的最大值分…

嵌入式硬件电子电路设计(六)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…

一篇文章理解前端的设计模式

前言 作为前端开发&#xff0c;如果是想要提升自己能力和技术水平&#xff0c;不能只是简单的重复造轮子&#xff0c;必须要深刻理解体会前端的设计模式&#xff0c;有助于自身能力的提升。 什么是前端设计模式 所谓前端的设计模式就是一种可以在多处地方重复使用的代码方案…