一、矩阵分解回想

在博文推荐算法——基于矩阵分解的推荐算法中,提到了将用户-商品矩阵进行分解。从而实现对未打分项进行打分。

矩阵分解是指将一个矩阵分解成两个或者多个矩阵的乘积。对于上述的用户-商品矩阵(评分矩阵),记为Vm×n。能够将其分解成两个或者多个矩阵的乘积,如果分解成两个矩阵Wm×k和Hk×n。我们要使得矩阵Wm×k和Hk×n的乘积能够还原原始的矩阵Vm×n:

Vm×n≈Wm×k×Hk×n=V^m×n

当中,矩阵Wm×k表示的是m个用户与k个主题之间的关系,而矩阵Hk×n表示的是k个主题与n个商品之间的关系。

通常在用户对商品进行打分的过程中。打分是非负的,这就要求:

Wm×k⩾0

Hk×n⩾0

这便是非负矩阵分解(Non-negtive Matrix Factorization, NMF)的来源。

二、非负矩阵分解

2.1、非负矩阵分解的形式化定义

上面简介了非负矩阵分解的基本含义。简单来讲,非负矩阵分解是在矩阵分解的基础上对分解完毕的矩阵加上非负的限制条件。即对于用户-商品矩阵Vm×n,找到两个矩阵Wm×k和Hk×n,使得:

Vm×n≈Wm×k×Hk×n=V^m×n

同一时候要求:

Wm×k⩾0

Hk×n⩾0

2.2、损失函数

为了能够定量的比較矩阵Vm×n和矩阵V^m×n的近似程度。在參考文献1中作者提出了两种损失函数的定义方式:

  • 平方距离

∥A−B∥2=∑i,j(Ai,j−Bi,j)2

  • KL散度

D(A∥B)=∑i,j(Ai,jlogAi,jBi,j−Ai,j+Bi,j)

在KL散度的定义中,D(A∥B)⩾0。当且仅当A=B时取得等号。

当定义好损失函数后,须要求解的问题就变成了例如以下的形式,相应于不同的损失函数:

求解例如以下的最小化问题:

  • minimize∥V−WH∥2s.t.W⩾0,H⩾0

  • minimizeD(V∥WH)s.t.W⩾0,H⩾0

2.3、优化问题的求解

在參考文献1中,作者提出了乘法更新规则(multiplicative update rules),详细的操作例如以下:

对于平方距离的损失函数:

Wi,k=Wi,k(VHT)i,k(WHHT)i,k

Hk,j=Hk,j(WTV)k,j(WTWH)k,j

对于KL散度的损失函数:

Wi,k=Wi,k∑uHk,uVi,u/(WH)i,u∑vHk,v

Hk,j=Hk,j∑uWu,kVu,j/(WH)u,j)∑vWv,k

上述的乘法规则主要是为了在计算的过程中保证非负,而基于梯度下降的方法中,加减运算无法保证非负。事实上上述的乘法更新规则与基于梯度下降的算法是等价的。以下以平方距离为损失函数说明上述过程的等价性:

平方损失函数能够写成:

l=∑i=1m∑j=1n[Vi,j−(∑k=1rWi,k⋅Hk,j)]2

使用损失函数对Hk,j求偏导数:

∂l∂Hk,j=∑i=1m∑j=1n[2(Vi,j−(∑k=1rWi,k⋅Hk,j))⋅(−Wi,k)]=−2[(WTV)k,j−(WTWH)k,j]

则依照梯度下降法的思路:

Hk,j=Hk,j−ηk,j∂l∂Hk,j

即为:

Hk,j=Hk,j+ηk,j[(WTV)k,j−(WTWH)k,j]

令ηk,j=Hk,j(WTWH)k,j,即能够得到上述的乘法更新规则的形式。

2.4、非负矩阵分解的实现

对于例如以下的矩阵:

通过非负矩阵分解。得到例如以下的两个矩阵:

对原始矩阵的还原为:

实现的代码

#!/bin/python

from numpy import * 

def load_data(file_path):
f = open(file_path)
V = []
for line in f.readlines():
lines = line.strip().split("\t")
data = []
for x in lines:
data.append(float(x))
V.append(data)
return mat(V) def train(V, r, k, e):
m, n = shape(V)
W = mat(random.random((m, r)))
H = mat(random.random((r, n))) for x in xrange(k):
#error
V_pre = W * H
E = V - V_pre
#print E
err = 0.0
for i in xrange(m):
for j in xrange(n):
err += E[i,j] * E[i,j]
print err if err < e:
break a = W.T * V
b = W.T * W * H
#c = V * H.T
#d = W * H * H.T
for i_1 in xrange(r):
for j_1 in xrange(n):
if b[i_1,j_1] != 0:
H[i_1,j_1] = H[i_1,j_1] * a[i_1,j_1] / b[i_1,j_1] c = V * H.T
d = W * H * H.T
for i_2 in xrange(m):
for j_2 in xrange(r):
if d[i_2, j_2] != 0:
W[i_2,j_2] = W[i_2,j_2] * c[i_2,j_2] / d[i_2, j_2] return W,H if __name__ == "__main__":
#file_path = "./data_nmf"
file_path = "./data1" V = load_data(file_path)
W, H = train(V, 2, 100, 1e-5 ) print V
print W
print H
print W * H

收敛曲线例如以下图所看到的:

'''
Date:20160411
@author: zhaozhiyong
''' from pylab import *
from numpy import * data = [] f = open("result_nmf")
for line in f.readlines():
lines = line.strip()
data.append(lines) n = len(data)
x = range(n)
plot(x, data, color='r',linewidth=3)
plt.title('Convergence curve')
plt.xlabel('generation')
plt.ylabel('loss')
show()

參考文献

推荐算法——非负矩阵分解(NMF)的更多相关文章

  1. 文本主题模型之非负矩阵分解(NMF)

    在文本主题模型之潜在语义索引(LSI)中,我们讲到LSI主题模型使用了奇异值分解,面临着高维度计算量太大的问题.这里我们就介绍另一种基于矩阵分解的主题模型:非负矩阵分解(NMF),它同样使用了矩阵分解 ...

  2. 非负矩阵分解NMF

    http://blog.csdn.net/pipisorry/article/details/52098864 非负矩阵分解(NMF,Non-negative matrix factorization ...

  3. 【代码更新】单细胞分析实录(21): 非负矩阵分解(NMF)的R代码实现,只需两步,啥图都有

    1. 起因 之前的代码(单细胞分析实录(17): 非负矩阵分解(NMF)代码演示)没有涉及到python语法,只有4个python命令行,就跟Linux下面的ls grep一样的.然鹅,有几个小伙伴不 ...

  4. 浅谈隐语义模型和非负矩阵分解NMF

    本文从基础介绍隐语义模型和NMF. 隐语义模型 ”隐语义模型“常常在推荐系统和文本分类中遇到,最初来源于IR领域的LSA(Latent Semantic Analysis),举两个case加快理解. ...

  5. 单细胞分析实录(17): 非负矩阵分解(NMF)代码演示

    本次演示使用的数据来自2017年发表于Cell的头颈鳞癌单细胞文章:Single-Cell Transcriptomic Analysis of Primary and Metastatic Tumo ...

  6. 数据降维-NMF非负矩阵分解

    1.什么是非负矩阵分解? NMF的基本思想可以简单描述为:对于任意给定的一个非负矩阵V,NMF算法能够寻找到一个非负矩阵W和一个非负矩阵H,使得满足 ,从而将一个非负的矩阵分解为左右两个非负矩阵的乘积 ...

  7. 降维、特征提取与流形学习--非负矩阵分解(NMF)

    非负矩阵分解(NMF)是一种无监督学习算法,目的在于提取有用的特征(可以识别出组合成数据的原始分量),也可以用于降维,通常不用于对数据进行重建或者编码. NMF将每个数据点写成一些分量的加权求和(与P ...

  8. 推荐算法之用矩阵分解做协调过滤——LFM模型

    隐语义模型(Latent factor model,以下简称LFM),是推荐系统领域上广泛使用的算法.它将矩阵分解应用于推荐算法推到了新的高度,在推荐算法历史上留下了光辉灿烂的一笔.本文将对 LFM ...

  9. 机器学习--K折交叉验证和非负矩阵分解

    1.交叉验证 交叉验证(Cross validation),交叉验证用于防止模型过于复杂而引起的过拟合.有时亦称循环估计, 是一种统计学上将数据样本切割成较小子集的实用方法. 于是可以先在一个子集上做 ...

随机推荐

  1. Codeforces Beta Round #6 (Div. 2 Only) D. Lizards and Basements 2 dfs

    D. Lizards and Basements 2 题目连接: http://codeforces.com/contest/6/problem/D Description This is simpl ...

  2. LM27313 (ACTIVE) 具有 30V 内部 FET 开关(采用 SOT-23 封装)的 1.6 MHz 升压转换器

    The LM27313 switching regulator is a current-mode boost converter with a fixed operating frequency o ...

  3. Java:volatile 关键字的一点理解

    背景 学了六年C#,一直没有使用过 volatile,对多线程编程也是偶尔才会使用,这次学习 Java 又遇到了 volatile,准备稍微深入的了解一下. volatile 的作用? 几乎所有支持这 ...

  4. monkey源代码分析之事件注入方法变化

    在上一篇文章<Monkey源代码分析之事件注入>中.我们看到了monkey在注入事件的时候用到了<Monkey源代码分析番外篇之Android注入事件的三种方法比較>中的第一种 ...

  5. maven编译错误,警告: BASE64Decoder是内部专用 API, 可能会在未来发行版中删除

    修改红色部分版本号为2.3.2              <plugin>                 <groupId>org.apache.maven.plugins& ...

  6. OpenCV学习(9) 分水岭算法(3)

    本教程我学习一下opencv中分水岭算法的具体实现方式. 原始图像和Mark图像,它们的大小都是32*32,分水岭算法的结果是得到两个连通域的轮廓图. 原始图像:(原始图像必须是3通道图像) Mark ...

  7. [Todo] Java并发编程学习

    有两个系列的博文,交替着可以看看: 1. Java并发编程与技术内幕 http://blog.csdn.net/Evankaka/article/details/51866242 2. [Java并发 ...

  8. qt study 元对象,属性和反射编程

    所谓反射,就是指对象成员的自我检查,使用反射编程(reflective programming),就可以编写出通用的操作,可以对具有不同结构的类进行操作. QMetaObject 元对象模式,描述一个 ...

  9. java学习笔记1--开发环境平台总结

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note1.html,转载请注明源地址. 1.Java程序设计语言 Java程序设计语言是一种高 ...

  10. 北京SAP-AGS CoE support consultant intern 面试总结

    7月4号去大连SAP面试.通过的话直接去北京SAP參加实习(有幸已通过). SAP一直是我理想的公司,大二的时候曾试图參加SAP大连vt项目,当时下了非常大决心,假设通过了就先留在大连,可惜英语群面就 ...