从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, theta

def 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_2

def 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*X
    theta_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)*R
    return Y_norm, Y_mean

mat = 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] = 3

y = 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

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

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

相关文章

项目实战(webshop)

一、搭建靶场webshop(www.example1.com) 二、信息收集 1、获取IP winR→cmd→ping www.example1.com→显示出ip(192.168.51.128) 注:TTL为IP包的生存时间,拿到TTL我们可以大概的判断一下目标机器的操作系统,但不是很准确,因为…

初识算法 · 分治(3)

目录 前言: 归并排序 题目解析 算法原理 算法编写 求逆序对总数 题目解析 算法原理 算法编写 前言: ​本文的主题是分治,通过两道题目讲解,一道是归并排序,一道是求逆序对。 链接分别为: 912. 排…

MyBatis——#{} 和 ${} 的区别和动态 SQL

1. #{} 和 ${} 的区别 为了方便,接下来使用注解方式来演示: #{} 的 SQL 语句中的参数是用过 ? 来起到类似于占位符的作用,而 ${} 是直接进行参数替换,这种直接替换的即时 SQL 就可能会出现一个问题 当传入一个字符串时&#xff…

学习threejs,导入FBX格式骨骼绑定模型

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.FBXLoader fbx 模型加…

【腾讯云产品最佳实践】腾讯云CVM入门技术与实践:通过腾讯云快速构建云上应用

目录 前言 什么是腾讯云CVM? 腾讯云CVM的技术优势 基于最佳技术实践,使用腾讯云CVM搭建应用 1. 开通CVM实例 2. 连接CVM实例 3. 配置Web环境 4. 部署PHP应用 腾讯云CVM行业应用案例:电商平台的双十一攻略 1. 弹性伸缩解决高并发问题…

mongodb多表查询,五个表查询

需求是这样的,而数据是从mysql导入进来的,由于mysql不支持数组类型的数据,所以有很多关联表。药剂里找药物,需要药剂与药物的关联表,然后再找药物表。从药物表里再找药物与成分关联表,最后再找成分表。 这里…

STL中vector实现——简单易懂版

本章内容 模拟实现 vector 的部分重要功能 1.迭代器的引入1.1 之前写法1.2 STL库中的写法 2.默认成员函数2.1构造与拷贝构造2.2拷贝赋值2.3析构函数 3.增删查改功能3.1插入3.2删除 4.为什么STL中vector没有find函数?5.🔥🔥迭代器失效场景&am…

Springboot + vue 健身房管理系统项目部署

1、前言 ​ 许多人在拿到 Spring Boot 项目的源码后,不知道如何运行。我以 Spring Boot Vue 健身房管理系统的部署为例,详细介绍一下部署流程。大多数 Spring Boot 项目都可以通过这种方式部署,希望能帮助到大家。 ​ 2、项目查看 ​ 首…

NuGet如何支持HTTP源

今天是2024年11月21号,最近更新了VisualStudio后发现HTTP的包源已经默认禁止使用了,生成时会直接报错。如下图: 官方也明确指出了要想使用HTTP包源的解决办法,这里就简单总结一下。 一、全局配置 1、全局NuGet包的配置文件路径在…

SpringBoot学习记录(四)之分页查询

SpringBoot学习记录(四)之分页查询 一、业务需求1、基本信息2、请求参数3、相应数据 二、传统方式分页三、使用PageHelper分页插件 一、业务需求 根据条件进行员工数据的条件分页查询 1、基本信息 请求路径: /emps 请求方式: …

JavaParser如何获取方法的返回类型

使用JavaParser 如何获取一个Java类中的某个方法的返回类型呢? 假如有一个如下的简单的Java 类: /*** Copyright (C) Oscar Chen(XM):* * Date: 2024-11-21* Author: XM*/ package com.osxm.ai.sdlc.codeparse.codesample;public class MyClass {public…

2024亚太杯国际赛C题宠物预测1234问完整解题思路代码+成品参考文章

中国宠物业发展趋势及预测模型 一、问题背景与研究目标 近年来,中国宠物业经历了快速发展,特别是在城市化进程加快、人口结构变化和消费水平提升的背景下,宠物作为家庭成员的角色变得愈发重要。根据相关数据,中国宠物数量&#…

Java实现离线身份证号码OCR识别

最近公司要求做离线身份证OCR功能,找了一圈总算是找到了,在这里对文档做个整理,方便后来者,感谢码龄23年博主的分享 系统:Windows11,红旗Linux Asianux8.1 文档中Linux全root用户操作;需先安装…

Gradle核心概念总结

这部分内容主要根据 Gradle 官方文档整理,做了对应的删减,主要保留比较重要的部分,不涉及实战,主要是一些重要概念的介绍。 Gradle 这部分内容属于可选内容,可以根据自身需求决定是否学习,目前国内还是使用…

鸿蒙网络编程系列50-仓颉版TCP回声服务器示例

1. TCP服务端简介 TCP服务端是基于TCP协议构建的一种网络服务模式,它为HTTP(超文本传输协议)、SMTP(简单邮件传输协议)等高层协议的应用程序提供了可靠的底层支持。在TCP服务端中,服务器启动后会监听一个或…

第5-1节:SpringBoot对SpringMVC的自动配置

我的后端学习大纲 SpringBoot学习大纲 1、SpringBoot对SpringMVC自动配置概览

Emacs进阶之插入时间信息(一百六十三)

简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列【…

嵌入式实验报告:家用计时器

实验目的和要求 1、实验目的 掌握STM32串口通信原理。学习编程实现STM32的UART通信掌握STM32中断程序设计流程。熟悉STM32固件库的基本使用。熟悉STM32定时器中断设计流程。2、实验要求 设计一个家用计时器,其功能如下: 利用串口设置计时时间,格式:XX:XX:X 例如01:59:…

【WRF理论第十二期】Registry.EM 文件详解

【WRF理论第十二期】Registry.EM 文件详解 Registry.EM 文件的作用Registry.EM 文件的结构Registry.EM 文件内容理解如何修改 Registry.EM 文件以输出特定变量WRF-Urban 修改 Registry.EM 文件以输出 UCM 相关变量1. 修改 Registry.EM 文件2. 重新编译 WRF 注意事项参考 在 WRF…

Midjourney 图生图,真人二次元保持一致性,场景多元可选择

Midjourney 拥有强大的图生图的功能,下面我们就来看一下,如何在我们的AceDataCloud网站上实现将照片切换成任意的二次元场景,同时保持人物的一致性。 我们可以按照如下的步骤去实现人物一致性。 下面我们来看看效果吧,原图如下。…