技术标签: 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]]
在开发中,不免要定义 struct 中的某些元素为 trait object,从而带来一些 rust 语言中的生命周期问题。接下来,定义一个 struct 包含两个 Base trait 的 trait object ,然后实现一个函数是 say 函数输出的字符串的拼接结果。编译器给出的提示很明确,要在 trait object 上添加生命周期参数,确保 struct 和他的 trait object 元素在同一生命周期,避免悬垂指针。很遗憾,以上代码是不能编译通过的,编译时报如下错误。_rust struct
一.win10开启/关闭开机密码1.右键点击windows;2.点击运行; 3.输入netplwiz,点击确定; 4.当需要开启开机密码时,勾选下图选项,反之不勾选。 二.如何设置开机启动项1.在下栏任意空白位置点击鼠标右键,打开任务管理器; 2.点击菜单栏中的启动,然后在状态栏下方点击鼠标右键,即可启动/禁用项目。(启动...
前言本篇博文是关于。如果对于搭建等其它方面有需要了解的,读者可以阅读前几篇比较优质的文章:推荐阅读:【Win10】搭建个人博客 Hexo框架 (自制)推荐阅读:【Win10】搭建个人博客 Hexo框架(部署到 github 上并 导入美化样式 )推荐阅读:【Win10】Hexo 搭建个人主页 (一)解决所有文章,缺失模块问题推荐阅读:【Win10】Hexo 搭建个人主页 (二)配置图..._hexo liveforcode主题设置背景音乐
InputStream字节输入流(抽象类)字节输入类的父类AudioInputStream(高级流):音频数据的字节流ByteArrayInputStream:从字节数组中按字节读取数据FileInputStream:从文件中按字节读取数据FilterInputStream:BufferedInputStream(高级流):当获取到低级字节输入流可以转换为高级数..._java 日曜日转换
局部性原理:OS虽然IO操作只读取一部分数据,但是OS每次IO操作取值都是以页为单位,一页=4kb。1.InnoDB数据页结构页是InnoDB管理存储空间的基本单位:1页=16kb = 16384查看数据库页的大小SQL:show global status like ‘Innodb_page_size’;一个InnoDB数据页的存储结构:名称占用空间大小简单描述..._索引存的是页还是id
HF已经尽了她最大的努力,笔试过了,面试也过了,但还是在审核的时候被拒了,非常非常地可惜,但现实就是如此残酷,没办法。一个很好的机会就这样失去了,无话可说,已经尽了一切能尽的最大努力。现在想回来,其实应该去省教育厅问一下,提前将教师资格证要下来,或者直接给个电话,让管事的人去处理,但这一步没走,因为当时没有想到。HF为此回清远拿了证明,而且在4号下午已经上车的情况下又下车了,搞到晚上还_hf您的开始请求被拒绝
SSL证书详解和CFSSL工具使用1.公钥基础设施PKI基础概念CA(Certification Authority)证书,指的是权威机构给我们颁发的证书。密钥就是用来加解密用的文件或者字符串。密钥在非对称加密的领域里,指的是私钥和公钥,他们总是成对出现,其主要作用是加密和解密。常用的加密强度是2048bit。RSA即非对称加密算法。非对称加密有两个不一样的密码,一个叫私钥,另一个叫公钥,用其中一个加密的数据只能用另一个密码解开,用自己的都解不了,也就是说用公钥加密的数据只能由私钥解开。证书的编码_cfssl
目录0x0 题目涉及知识点0x1 查壳脱壳0x2 反汇编分析0x3写脚本0x0 题目涉及知识点简单脱壳指针运算位移量字符串查询0x1 查壳脱壳使用 UPX 工具脱壳0x2 反汇编分析初步了解程序执行流程,sub_401000(&v6) 为加密过程,&v4中存放了flag。 char v4; // [esp+4h] [ebp-804h] char v5; // [esp+5h] [ebp-803h] char v6; // [esp+404h] [ebp_windows_reverse1
背景:在进行索引在线表空间迁移的时候报出的错误,具体命令alter index index_name rebuild online tablespace tablespace_name;问题分析:9i之后每个index key最大可以为block size的80%。所以理论上来说,是可以创建最大长度为block size=8096*80%约为6400左右长度的index。但_oracle主键maximum key length6394
一、引言近年来,美国卡内基·梅隆大学周以真教授对计算思维的系统阐述,引起了国内计算机学者的关注,在计算机基础课中进行计算思维培养的教学改革也迅速开展起来。计算机网络是高校的一门重要课程,也是计算机应用和信息技术类专业必修的基础课程。在这门课程的教学过程中加强计算思维的培养非常重要,它对于提升计算机网络课程教学水平、提高学生的学习能力乃至推动网络技术的发展都具有重要意义。二、计算思维的概念1996 ...
启用max脚本数据类型基本使用基本数学操作建模操作语法函数导入导出应用实例总结 MAXscript是3ds Max内置脚本语言,Max2.0及以后加入的功能。也能使用在与3ds Max相关的产品中如Autodesk VIZ,character studio,Plasma和GMax;脚本可使用于建模,动画,材质,渲染等等。它是专门为3D Studio Max设计的。 – 摘_maxscript
问题:我现在需要把一个文件夹里的几十个文件改名为对应的文件名,对应关系已经有了。 比如说 原来的文件名 需要改为的文件名 北京.txt 01.txt 天津.txt 02.txt 河北.txt 03.txt 我想写一个bat文件一次执行所有的修改,请问这个批处理文件该怎么写?原来dos时代的东西学的不好。谢谢各位了 解决方法: