# Python推荐系统学习笔记(3)

您所在的位置:网站首页 常用的协同过滤算法 # Python推荐系统学习笔记(3)

# Python推荐系统学习笔记(3)

2024-07-11 20:11| 来源: 网络整理| 查看: 265

Python推荐系统学习笔记(3)------基于协同过滤的个性化推荐算法实战—隐语义模型 一、概念性理解

传统的推荐方法 UserCF,首先需要找到和他们看了同样书的其他用户,然后给他们推荐那些用户喜欢的其他书。 ItemCF,需要给他们推荐和他们已经看的书相似的书。 基于隐语义模型 通过矩阵分解建立用户和隐类之间的关系,物品和隐类之间的关系,最终得到用户对物品的偏好关系。 隐语义模型(LFM):通过矩阵分解建立用户和隐类之间的关系,物品和隐类之间的关系,最终得到用户对物品的偏好关系。 隐含语义分析技术的分类来自对用户行为的统计,代表了用户对物品分类的看法,是基于用户的共同兴趣计算出来的,允许我们指定最终有多少个分类,会计算出物品属于每个类的权重,因此每个物品都不是硬性地被分到某一个类中。 隐含语义分析技术从诞生到今天产生了很多著名的模型和方法,其中和该技术相关且耳熟能详的名词有pLSA、LDA、隐含类别模型(latent class model)、隐含主题模型(latent topic model)、 矩阵分解(matrix factorization)。这些技术和方法在本质上是相通的,其中很多方法都可以用于个性化推荐系统。 假设我们想要发现 F个隐类,我们的任务就是找到两个矩阵 U 和 V,使这两个矩阵的乘积近似等于R,即将用户物品评分矩阵 R 分解成为两个低维矩阵相乘,然后定义损失函数,利用随机梯度下降法处理损失函数,求出U和V。

二、矩阵分解的基本思想

矩阵分解的基本思想简单来说就是每一个用户和每一个物品都会有自己的一些特性,特性即可作为隐语义模型的隐含因子,用矩阵分解可以从评分矩阵中分解出用户–特性矩阵,物品–特性矩阵,这样一是得到了用户的偏好和每件物品的特性,二是知道了矩阵的维度。 矩阵分解就是把原来的大矩阵,近似的分解成小矩阵的乘积,在实际推荐计算时不再使用大矩阵,而是使用分解得到的两个小矩阵。 具体来说就是,假设用户物品的评分矩阵Y是m乘n维,即一共有m个用户,n个物品.通过一套算法转化为两个矩阵U和V,矩阵U的维度是m乘k,矩阵V的维度是n乘k。 在这里插入图片描述 类似这样的计算过程就是矩阵分解,还有一个更常见的名字SVD,但是SVD和矩阵分解不能划等号,因为除了SVD还有一些别的矩阵分解方法。

三、算法的深层次理解

**基础的SVD算法:**矩阵分解,就是把用户和物品都映射到一个K维空间上,这个k维空间不是直接看到的,通常称为隐因子。 每一个物品都得到一个向量,每一个用户也得到一个向量。对于物品,与它对应的向量中的元素,有正有负,代表着这个物品背后暗藏的一些用户关注的因素,对于用户,与它对应的向量中的元素,也有正有负,代表这个用户在若干因素上的偏好。物品被关注的因素和用户偏好的因素,它们的数量和意义是一致的,就是我们在矩阵分解之处人为指定的。 如何得到每一个用户,每一个物品的维向量,这是一个机器学习的问题。按照机器学习思想,一般考虑两个要素:1)、损失函数 2)、优化算法。 整个SVD的学习过程就是: 1)准备好用户物品的评分矩阵,每一条评分数据看作是一条训练样本; 2)给分解后的U矩阵和V矩阵随机初始化元素值; 3)用U和V计算预测后的分数; 4) 计算预测的分数和实际的分数误差; 5)按照梯度下降的方向更行U和V中的元素值; 6)重复步骤3到5,直到达到停止条件。 得到分解后的矩阵之后,实质上就是得到每个用户和每个物品的隐因子向量,拿着这个向量再做推荐计算更加简单,简单来说就是拿着物品和用户两个向量,计算的点积就是推荐分数。

四、以用户与电影间的关系进行举例说明

每个用户看电影的时候都有偏好,这些偏好可以直观理解成:恐怖片,喜剧片,武侠片,爱情片等,称作电影特性。用户–特性矩阵表示的就是用户对这些因素(偏好)的喜欢程度。 在这里插入图片描述 同样,每一部电影也可以用这些因素描述,因此物品–特性矩阵表示的就是每一部电影这些因素的含量,也就是电影的类型。这样子两个矩阵相乘就会得到用户对这个电影的喜欢程度。 在这里插入图片描述 因为传统的矩阵分解技术不能完成矩阵的分解,即使能分解,那样计算复杂度太高,不现实。因此通常的方法是使用已存在评分计算出预测误差(或代价函数),然后使用梯度下降算法调整参数使得误差(代价函数)最小。 戴帽子的rui表示预测u对i的打分,qi表示i物品每个特性的归属度向量,表示用户u对每个特性的喜欢程度的向量。因此,物品的预测得分为: 在这里插入图片描述 下面就根据已有的数据计算误差并修正q和p使得误差最小,(SVD损失函数)误差的表示方式如下: 在这里插入图片描述 根据上面的参数可以得到电影推荐系统的误差实际计算公式如下: 在这里插入图片描述 J(X,O) 即代表该方法的代价函数(误差);r是用户对电影的评分记录表(矩阵),在其中,具有评分的记录用1表示,没有则用0表示,故 r(i,j) 代表了一种过滤条件,即 i用户对 j 电影具有评分;oi 代表i用户的喜好向量(对不同类型电影的喜欢程度值),xj代表了j电影的内容(即一个电影的各个特征类型如喜剧片恐怖片等所占数值,如(0.2,0.2,0.4,0.1)的转置,y(i,j) 是i用户对j电影的实际评分。后面两项是正则化项,是特征数量即电影特性(喜剧片,爱情片等)的数量,m是电影总数, u是用户总数。oiTxj即为 i 用户对电影的评分预测值。

五、实现隐语义模型,对隐式数据进行推荐

代码和解析见隐语义模型分析关键代码.py。

# -*- coding: utf-8 -*- ''' 实现隐语义模型,对隐式数据进行推荐 1.对正样本生成负样本 -负样本数量相当于正样本 -物品越热门,越有可能成为负样本 2.使用随机梯度下降法,更新参数 ''' import numpy as np#numpy库可以用来存储和处理大型矩阵 import pandas as pd#pandas提供了大量能使我们快速便捷地处理(分析)数据的函数和方法 from math import exp#exp() 方法返回x的指数,e^x import time import math from sklearn import model_selection#sklearn是python的机器学习库,其中封装了大量的机器学习算法,内置了大量的公开数据集. #train_test_split返回切分的数据集train/test;cross_validate返回train/test数据集上的每折得分 import random import operator#操作符函数接口 class LFM: ''' 初始化隐语义模型 参数:*data 训练数据,要求为pandas的dataframe *F 隐特征的个数 *N 迭代次数 *alpha 随机梯度下降的学习速率 *lamda 正则化参数 *ratio 负样本/正样本比例 *topk 推荐的前k个物品 ''' def __init__(self, data, ratio, F=5, N=2, alpha=0.02, lamda=0.01, topk=10): self.data = data # 样本集 self.ratio = ratio # 正负样例比率,对性能最大影响 self.F = F # 隐类数量,对性能有影响 self.N = N # 迭代次数,收敛的最佳迭代次数未知 self.alpha = alpha # 梯度下降步长 self.lamda = lamda # 正则化参数 self.topk = topk # 推荐top k项 ''' 初始化物品池,物品池中物品出现的次数与其流行度成正比 {item1:次数;item2:次数,...} ''' def InitItemPool(self): itemPool = dict()#定义物品池里面的物品和流行度为字典模型 groups = self.data.groupby([1])#groupby分组聚合数据 for item, group in groups: itemPool.setdefault(item, 0)#Python字典setdefault()函数和get()方法类似, 如果键不存在于字典中,将会添加键并将值设为默认值。


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3