技术标签: AlgoAndDataStructure 机器学习 ALS 算法分析 MachineLearning 大数据 Python 推荐算法
数据(矩阵 A m n A_{mn} Amn)
user/item | 商品1 | 商品2 | 商品3 | 商品4 |
---|---|---|---|---|
用户1 | 9 | - | 6 | 8 |
用户2 | 3 | 9 | - | 4 |
用户3 | - | - | 6 | 8 |
用户4 | 9 | 8 | 5 | 9 |
用户5 | 8 | 7 | 6 | - |
算法目标:挖掘出用户对未购买过的商品的喜好程度,也就是说要分析出原始稀疏矩阵 A m , n A_{m,n} Am,n中的缺失值。
利用ALS算法,将稀疏矩阵 A m , n A_{m,n} Am,n拆解为两个矩阵 U m , k U_{m,k} Um,k 、 V k , n V_{k,n} Vk,n,即 A m , n = U m , k ∗ V k , n A_{m,n} = U_{m,k} * V_{k,n} Am,n=Um,k∗Vk,n
按照ALS算法的流程,需要先固定矩阵 U m , k U_{m,k} Um,k
user/k | k1 | k2 | k3 |
---|---|---|---|
用户1 | 3 | 5 | 6 |
用户2 | 4 | 3 | 3 |
用户3 | 2 | 5 | 3 |
用户4 | 6 | 2 | 2 |
用户5 | 5 | 3 | 4 |
此时,已知矩阵 A 5 , 4 A_{5,4} A5,4部分值(稀疏)、矩阵 U 5 , 3 U_{5,3} U5,3所有值,需要求解矩阵 V 3 , 4 V_{3,4} V3,4
k/item | 商品1 | 商品2 | 商品3 | 商品4 |
---|---|---|---|---|
k1 | w11 | w12 | w13 | w14 |
k2 | w21 | w22 | w23 | w24 |
k3 | w31 | w32 | w33 | w34 |
那么该如何求解呢?不急,我们先看看矩阵乘法计算公式, U 5 , 3 ∗ V 3 , 4 = A 5 , 4 U_{5,3} * V_{3,4} = A_{5,4} U5,3∗V3,4=A5,4的示例如下
从每个商品与所有用户的计算公式中,不难发现一个商品的所有w值与其他商品的w值无关!因此,不同商品的w值计算,我们可以分开来做。
回想一下,机器学习中的线性回归!同理,我们可以将求一个商品的多个w值看作多元线性回归:
因此,我们可以利用线性回归(ALS中是最小二乘法)求出所有商品的w值,即得到矩阵 V 3 , 4 V_{3,4} V3,4
接着,固定矩阵 V 3 , 4 V_{3,4} V3,4,反过来求解矩阵 U 5 , 3 U_{5,3} U5,3
如此反复的进行多次求值
直到 U 5 , 3 ∗ V 3 , 4 U_{5,3} * V_{3,4} U5,3∗V3,4得到得矩阵与矩阵 A 5 , 4 A_{5,4} A5,4的损失小于某个阈值(或是达到一定次数),既可完成求解
最终,推荐算法使用时,利用求得的矩阵 U 5 , 3 ∗ V 3 , 4 U_{5,3} * V_{3,4} U5,3∗V3,4,可以预测出用户对未购买过的商品的喜好程度,从而进行推荐!
Spark ALS模型使用示例:《Spark高级数据分析》——音乐推荐(ALS算法)
import numpy as np
import pandas as pd
# 定义User-Item稀疏矩阵
# 0代表矩阵的缺失值
R = np.array(
[[8, 9, 2, 2,0, 1],
[3, 2, 5, 6, 0, 0],
[8, 8, 0, 3, 7, 2],
[3, 3, 0, 8, 8, 1],
[7, 0, 3, 2, 5, 9],
[0, 2, 2, 6, 7, 1],
[8, 0, 3, 0, 4, 0],
[3, 9, 0, 8, 6, 8],
[3, 2, 5, 0, 8, 0],
[6, 2, 3, 8, 0, 7]]
)
def lfm_gradient_descent(R, k=3, steps=1000, alpha=0.001, lam=0.0001):
"""
LFM梯度下降算法
:param R: 原始稀疏矩阵 User-Item
:param k: User与Item之间的隐含特征个数
:param steps: 最大迭代次数
:param alpha: 学习曲率
:param lam: 正则化系数
"""
m = len(R)
n = len(R[0])
# 随机初始化矩阵U,V
P = np.random.rand(m, k)
Q = np.random.rand(k, n)
# 最大迭代steps次
for step in range(steps):
# 修正矩阵P、Q
for user in range(m):
for item in range(n):
# 跳过稀疏矩阵A的缺失值部分
if R[user][item] > 0:
# 误差
error = np.dot(P[user,:], Q[:, item]) - R[user][item]
# 利用误差error更新矩阵P、Q
for i in range(k):
P[user][i] -= alpha * (2 * error * Q[i][item] + 2 * lam * P[user][i])
Q[i][item] -= alpha * (2 * error * P[user][i] + 2 * lam * Q[i][item])
# 计算新矩阵与原始稀疏矩阵的损失
# newR = np.dot(P, Q)
cost = 0
for user in range(m):
for item in range(n):
if R[user][item] > 0:
# 损失
cost += (np.dot(P[user,:], Q[:,item]) - R[user][item]) ** 2
# 正则化
cost += lam * sum(P[user,:]**2) + lam * sum(Q[:,item]**2)
# 达到阈值,跳出迭代
if cost < 0.5:
break;
return P,Q
P,Q = lfm_gradient_descent(R, 4, 10000, 0.005, 0.0005)
print("--------- 矩阵P ---------")
print(P)
print("--------- 矩阵Q ---------")
print(Q)
print("--------- 新矩阵P*Q ---------")
print(np.dot(P, Q))
print("--------- 原始稀疏矩阵R ---------")
print(R)
--------- 矩阵P ---------
[[ 2.47101945 -0.09314859 1.38122566 0.23276072]
[-0.4175392 0.88409428 0.62463847 2.39820982]
[ 2.10106116 0.1731982 1.56076663 0.37699979]
[ 0.98266167 2.10821349 0.74604873 0.13698655]
[ 0.46591391 -0.45260323 1.54408459 1.95285085]
[ 0.62855731 1.56571349 1.05862982 0.00706062]
[ 0.95726687 -1.11403965 1.48064885 2.10244858]
[ 1.97143103 1.32056111 -0.72112522 2.56245347]
[ 0.07027225 2.03254073 0.78322988 1.50645914]
[-0.04846877 1.64219853 2.02188288 1.15083635]]
--------- 矩阵Q ---------
[[ 1.58242819 3.19303543 0.95667258 0.48655993 1.21054208 -0.6060828 ]
[-0.35870851 -0.34836087 1.15881715 3.27881658 2.32052529 0.09664613]
[ 2.78744452 0.53842092 -0.49708206 0.58858015 2.40623536 1.15769018]
[ 0.92791198 1.38316166 1.951467 1.22337834 0.88932108 3.86373607]]
--------- 新矩阵P*Q ---------
[[ 8.00969538 8.98812847 2.02365673 1.99459832 6.30567239 0.99171252]
[ 2.98861476 2.01222899 4.99458605 5.99719289 5.1819201 10.32769524]
[ 7.96302376 8.0102283 2.17060619 2.97002692 7.03617947 2.0068338 ]
[ 3.0054383 2.99441722 3.2795967 7.99726497 7.99870986 1.00114949]
[ 7.01575177 5.17782475 2.96462993 2.04058504 4.96587355 9.00674711]
[ 3.39043557 2.04132685 1.90325185 6.07124444 6.94776448 1.02320811]
[ 7.99253533 7.14991343 2.99167776 0.2566066 4.00619612 9.14958844]
[ 3.01358624 8.99083579 8.77530468 7.99950709 5.99454255 7.99858102]
[ 2.96318244 2.02170798 4.97304635 9.00248294 8.02599098 6.88114446]
[ 6.03799225 1.95357653 3.09741652 7.9588332 9.64067885 6.97533011]]
--------- 原始稀疏矩阵R ---------
[[8 9 2 2 0 1]
[3 2 5 6 0 0]
[8 8 0 3 7 2]
[3 3 0 8 8 1]
[7 0 3 2 5 9]
[0 2 2 6 7 1]
[8 0 3 0 4 0]
[3 9 0 8 6 8]
[3 2 5 0 8 0]
[6 2 3 8 0 7]]
文章浏览阅读342次,点赞4次,收藏6次。该函数还允许使用 kmeans 聚类聚合行。如果行数太大,以至于 R 无法再处理其分层聚类,大约超过 1000 行,则建议这样做。与其单独显示所有行,不如提前对行进行聚类,并仅显示聚类中心。可以通过参数kmeans_k调整集群的数量。来源:https://www.rdocumentation.org/packages/pheatmap/versions/1.0.12/topics/pheatmap。一个绘制聚类热图的函数,可以更好地控制一些图形参数,如单元大小等。Examples 例子。_pheatmap基于kmeans绘制热图
文章浏览阅读369次。<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml..._div四周阴影效果
文章浏览阅读1.7k次。Java 通过反射获取实体类对应的注释 _java获取实体类属性注解
文章浏览阅读2.3k次,点赞5次,收藏10次。在使用MyBatis进行多表联查时,想要获取关联外键的表的数据信息,使用association进行联查,但当外键表的字段名和主表相同时,外键表的数据就会被覆盖。_mybatis association绑定相同对象
文章浏览阅读2.7k次。体验1: 军神太强啦,1小时屯6题,瞬间AK,接下来的90分钟一直在跟榜体验2: A题原题,循环写得好就不麻烦,不然要写很多行,情况要想全并不难。 B题原题,有了上一场的提示之后,这题就不难了。 C题很简单(小声)。 D题卡掉了O(T*N*K*log(N))的方法,卡掉我5发logN ,不过还是可做。 E题水dp(组合数学)。 F题原题,记忆化搜索。体验3: 被DC两题卡到..._在湘大xx奶茶店夏天推出了新的饮料价格为5元。 很多学生都要买饮料,每个学生
文章浏览阅读2.8k次。需求: 点击预览图标查看该pdf报告问题: 1、最早是直接将请求倒的url放入到<web-view src="{{realUrl}}"></web-view>中展示,ios可以,安卓显示无法查看。 2、通过微信自身的API实现:wx.downloadFile({})、wx.saveFile({})、wx.openDocument({}) 3、对于文件较大的,下载较慢,需要点击过的进行缓存,再次点击无需下载,直接打开。 将点击过的下载的url添加给list的tem_微信浏览器请求pdf文件会缓存吗
文章浏览阅读680次。服务部署之配置网络策略服务(NPS)(基于Windows Server 2022)_windows server 部署网络策略服务
文章浏览阅读4.8k次,点赞6次,收藏29次。基于距离、概率、重构的视频异常检测概述_视频异常检测综述
文章浏览阅读107次。洛谷P3388#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef unsigned long long ull;const int N=2e4+5;const int mod=1e9+7;vector<int> g[N];set<int> v;int dfn[N],low[N],fa[N];int n,m,tot;void tarjan(int x){
文章浏览阅读1k次。导语:小编相信,经常会使用到电脑的朋友们,对于启用硬件加速这个词一定都是不陌生的吧!可是呢,对于一些电脑小白们来说,往往会搞不清楚,这个启用硬件加速到底是个什么意思呢?启用之后,我们的电脑又会发生什么变化呢?也有一些人,在启用之后,却不知道应该如何关闭这个硬件加速,接下来,小编就来为大家介绍一下启用硬件加速是什么意思,以及它应该如何关闭。启用硬件加速是什么意思?简而言之,硬件加速就是利用硬件模块来..._linux 禁用硬件加速合成、图层和素材面板
文章浏览阅读8.1k次,点赞13次,收藏191次。1. 写在前面很多高级的机器学习模型(xgboost, lgb, cat)和神经网络模型, 它们相对于普通线性模型在进行预测时往往有更好的精度,但是同时也失去了线性模型的可解释性, 所以这些模型也往往看作是黑箱模型, 在2017年,Lundberg和Lee的论文提出了SHAP值这一广泛适用的方法用来解释各种模型(分类以及回归), 使得前面的黑箱模型变得可解释了,这篇文章主要整理一下SHAP的使用, 这个在特征选择的时候特别好用。这次整理, 主要是在xgboost和lgb等树模型上的使用方式, 并且用一个_python对shap的计算只能针对大数值吗
文章浏览阅读625次。这篇文章深入探讨了操作系统的各个方面,以及相关的计算机科学概念。文章的结构包括对操作系统的定义和功能的讨论,涵盖了硬件管理、操作系统特征、启动过程、运行环境等多个方面。作者使用思维导图和具体版本(如哈工大版本、王道版本)作为辅助,系统性地介绍了操作系统的运行机制,包括中断与异常、系统调用等内容。文章还回顾了操作系统的历史发展,按照不同线索(如哈工大版本)进行叙述,涵盖了操作系统的发展与分类、体系结构等方面。最后,文章提到了一些考研真题,强调了对计算机科学相关概念的深入理解。_2021