通常的矩阵分解会把一个大的矩阵分解为多个小的矩阵,但是这些矩阵的元素有正有负。而在现实世界中,比如图
像,文本等形成的矩阵中负数的存在是没有意义的,所以如果能把一个矩阵分解成全是非负元素是很有意义的。在
NMF中要求原始的矩阵的所有元素的均是非负的,那么矩阵可以分解为两个更小的非负矩阵的乘积,这个矩阵
有且仅有一个这样的分解,即满足存在性和唯一性。
Contents
1. NMF问题描述
2. NMF实现原理
3. NMF的应用
4. NMF的R实现
5. NMF的Julia实现
6. 结束语
1. NMF问题描述
传统的NMF问题可以描述如下
给定矩阵,寻找非负矩阵和非负矩阵,使得。
分解前后可理解为:原始矩阵的列向量是对左矩阵中所有列向量的加权和,而权重系数就是右矩阵对应列
向量的元素,故称为基矩阵,为系数矩阵。一般情况下的选择要比小,即满足,
这时用系数矩阵代替原始矩阵,就可以实现对原始矩阵进行降维,得到数据特征的降维矩阵,从而减少存储空
间,减少计算机资源。
2. NMF实现原理
NMF求解问题实际上是一个最优化问题,利用乘性迭代的方法求解和,非负矩阵分解是一个NP问题。NMF
问题的目标函数有很多种,应用最广泛的就是欧几里得距离和KL散度。
在NMF的分解问题中,假设噪声矩阵为,那么有
现在要找出合适的和使得最小。假设噪声服从不同的概率分布,通过最大似然函数会得到不同类型
的目标函数。接下来会分别以噪声服从高斯分布和泊松分布来说明。
(1)噪声服从高斯分布
假设噪声服从高斯分布,那么得到最大似然函数为
取对数后,得到对数似然函数为
假设各数据点噪声的方差一样,那么接下来要使得对数似然函数取值最大,只需要下面目标函数值最小。
该损失函数为2范数损失函数,它是基于欧几里得距离的度量。又因为
那么得到
同理有
接下来就可以使用梯度下降法进行迭代了。如下
如果选取
那么最终得到迭代式为
可看出这是乘性迭代规则,每一步都保证了结果为正数,一直迭代下去就会收敛,当然收敛性的证明省略。
(2)噪声服从泊松分布
若噪声为泊松噪声,那么得到损失函数为
同样经过推到得到
3. NMF的应用
NMF能用于发现数据库中图像的特征,便于快速识别应用,比如实现录入恐怖分子的照片,然后在安检口对可疑
人员进行盘查。在文档方面,NMF能够发现文档的语义相关度,用于信息的自动索引和提取。在生物学中,在
DNA阵列分析中识别基因等。在语音识别系统中NMF也能发挥重要作用。
4. NMF的R实现
先说NMF的R使用,R语言中已经有NMF包可用于NMF。非负矩阵分解已经有了很多算法,例如Multiplicative
Update,Projected Gradient Method,Gradient Descent。交替最小二乘法比较符合上面的解释,具
有更好的统计意义,而且收敛性质很好,计算速度快。已有的交替最小二乘法都使用冷冰冰的二次规划算法求解
非负回归,在bignmf中使用的最小角回归的思路解非负回归,更有统计的感觉,而且速度更快。安装包如下
bignmf:https://github.com/panlanfeng/bignmf
bignmf的部分源码如下
从上面代码可以看出,当矩阵V中元素是非double时,会强制转化为double类型。而W和H矩阵是服从高斯分布
的随机矩阵,随后传入参数调用whupdate,如果迭代次数太少会打印警告Iteration doesn't converge!
所以用bignmf分解非负矩阵调用如下函数就行了
代码:
以上是NMF分解的R语言实现,bignmf借助伟大的Rcpp和RcppEigen包,算法内层用C++ 代码实现接下来会接
着讲NMF在Julia中的实现。
5. NMF的Julia实现
在Julia语言中,有一个NMF包专门用来进行NMF分解的,现在就来详细了解它。首先来安装NMF,在Julia交互
式环境下使用如下命令
在Julia中,关于NMF的计算有很多方法,详见:https://github.com/JuliaStats/NMF.jl
NMF分解的一个例子如下
6. 结束语
关于NMF的解的收敛性和唯一性以后再证明,除了NMF分解以外,还有一种非负分解也用的比较多,而且很有
效,叫做非负张量分解法。可以参考如下论文
论文链接:http://www.doc88.com/p-8942237517189.html