Python使用矩阵分解法找到类似的音乐
原文链接:http://tecdat.cn/?p=6054
这篇文章是如何使用几种不同的矩阵分解算法计算相关艺术家。代码用Python编写,以交互方式可视化结果。
加载数据
这可以使用Pandas加载到稀疏矩阵中:
# 读取数据
usecols=[0, 2, 3],
names=['user', 'artist', 'plays'])
data['user'] = data['user'].astype("category")
data['artist'] = data['artist'].astype("category")
# 建立稀疏矩阵
triplesplays = coo_matrix((data['plays'].astype(float),
(data['artist'].cat.codes,
data['user'].cat.codes)))
这里返回的矩阵有300,000名艺术家和360,000名用户,总共有大约1700万条目。每个条目都是用户播放艺术家的次数,其中的数据是从2008年的Last.fm API收集的。
矩阵分解
通常用于此问题的一种技术是将用户 - 艺术家 - 戏剧的矩阵投影到低等级近似中,然后计算该空间中的距离。
我们的想法是采用原始的播放计数矩阵,然后将其减少到两个小得多的矩阵,这些矩阵在乘以时接近原始矩阵:
Artist/User/Play CountsArtist FactorsUser Factors=×
代替将每个艺术家表示为所有360,000个可能用户的游戏计数的稀疏向量,在对矩阵进行因式分解之后,每个艺术家将由50维密集向量表示。
通过减少这样的数据的维数,我们实际上将输入矩阵压缩为两个小得多的矩阵。
潜在语义分析
出于本文的目的,我们只需要知道SVD生成输入矩阵的低秩近似。
像这样使用SVD称为潜在语义分析(LSA)。所有真正涉及的是在这个分解空间中通过余弦距离获得最相关的艺术家:
class TopRelated(object): def __init__(self, artist_factors):
# 标准化
norms = numpy.linalg.norm(artist_factors, axis=-1)
self.factors = artist_factors / norms[:, numpy.newaxis]
def get_related(self, artistid, N=10):
scores = self.factors.dot(self.factors[artistid])
best = numpy.argpartition(scores, -N)[-N:]
return sorted(zip(best, scores[best]), key=lambda x: -x[1])
潜在语义分析之所以得名,是因为在对矩阵进行分解之后,可以输入数据中潜在的隐藏结构 - 这可以被认为是揭示输入数据的语义。
LSA
类似于LSA的'Arcade Fire':
虽然LSA成功地概括了我们数据的某些方面,但这里的结果并不是那么好。
隐含的交替最小二乘法
已发现这些模型在推荐项目时效果很好,并且可以很容易地重复用于计算相关艺术家。
推荐系统中使用的许多MF模型都采用了明确的数据,用户使用类似5星级评定标准评估了他们喜欢和不喜欢的内容。
第一个挑战是有效地进行这种因式分解:通过将未知数视为负数,天真的实现将查看输入矩阵中的每个条目。由于此处的维度大约为360K乘300K - 总共有超过1000亿条目要考虑,而只有1700万非零条目。
第二个问题是我们不能确定没有听艺术家的用户实际上意味着他们不喜欢它。可能还有其他原因导致艺术家没有被收听,特别是考虑到我们在数据集中每个用户只有最多50位艺术家。
使用二元偏好的不同置信水平来学习分解矩阵表示:看不见的项目被视为负面且置信度低,其中当前项目被视为正面更高的信心。
那么目标是通过最小化平方误差损失函数的置信加权和来学习用户因子X u和艺术家因子Y i:
def alternating_least_squares(Cui, factors, regularization, iterations=20):
users, items = Cui.shape
X = np.random.rand(users, factors) * 0.01
Y = np.random.rand(items, factors) * 0.01
Ciu = Cui.T.tocsr()
for iteration in range(iterations):
least_squares(Cui, X, Y, regularization)
least_squares(Ciu, Y, X, regularization)
return X, Y
def least_squares(Cui, X, Y, regularization):
users, factors = X.shape
YtY = Y.T.dot(Y)
for u in range(users):
#
YtCuY + regularization * I in A
A = YtY + regularization * np.eye(factors)
#
b = np.zeros(factors)
for i, confidence in nonzeros(Cui, u):
factor = Y[i]
A += (confidence - 1) * np.outer(factor, factor)
b += confidence * factor
# Xu = (YtCuY + regularization * I)^-1 (YtCuPu)
X[u] = np.linalg.solve(A, b)
为了调用它,我使用与LSA中使用的置信矩阵相同的权重,然后以相同的方式计算相关的艺术家:
artist_factors ,user_factors = alternating_least_squares (bm25_weight (plays ),50 )
与仅使用LSA相比,该方法可以产生明显更好的结果。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- laravel框架中控制器的创建和使用方法分析
- php 使用expat方式解析xml文件操作示例
- laravel利用中间件做防非法登录和权限控制示例
- laravel框架中表单请求类型和CSRF防护实例分析
- Yii框架getter与setter方法功能与用法分析
- laravel框架中视图的基本使用方法分析
- laravel5 Eloquent 实现事务方式
- Laravel 微信小程序后端搭建步骤详解
- Laravel使用swoole实现websocket主动消息推送的方法介绍
- Laravel框架Eloquent ORM删除数据操作示例
- PHP常用函数之base64图片上传功能详解
- laravel-admin 实现在指定的相册下添加照片
- Laravel框架Eloquent ORM修改数据操作示例
- PHP常用函数之格式化时间操作示例
- 在phpstudy集成环境下的nginx服务器下配置url重写