通常的矩阵分解会把一个大的矩阵分解为多个小的矩阵,但是这些矩阵的元素有正有负。而在现实世界中,比如图
像,文本等形成的矩阵中负数的存在是没有意义的,所以如果能把一个矩阵分解成全是非负元素是很有意义的。在
NMF中要求原始的矩阵
的所有元素的均是非负的,那么矩阵
可以分解为两个更小的非负矩阵的乘积,这个矩阵
有且仅有一个这样的分解,即满足存在性和唯一性。
Contents
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