非负矩阵分解(NMF)

通常的矩阵分解会把一个大的矩阵分解为多个小的矩阵,但是这些矩阵的元素有正有负。而在现实世界中,比如图

像,文本等形成的矩阵中负数的存在是没有意义的,所以如果能把一个矩阵分解成全是非负元素是很有意义的。在

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)噪声服从高斯分布

 

       假设噪声服从高斯分布,那么得到最大似然函数为

 

       非负矩阵分解(NMF)_第1张图片

 

       取对数后,得到对数似然函数为

 

       

 

       假设各数据点噪声的方差一样,那么接下来要使得对数似然函数取值最大,只需要下面目标函数值最小。

 

       

 

       该损失函数为2范数损失函数,它是基于欧几里得距离的度量。又因为

 

       

 

       那么得到

 

       非负矩阵分解(NMF)_第2张图片

 

       同理有

 

       

 

       接下来就可以使用梯度下降法进行迭代了。如下

 

       非负矩阵分解(NMF)_第3张图片

 

       如果选取

 

       

 

       那么最终得到迭代式为

 

       

 

       可看出这是乘性迭代规则,每一步都保证了结果为正数,一直迭代下去就会收敛,当然收敛性的证明省略。

 

 

   (2)噪声服从泊松分布

 

       若噪声为泊松噪声,那么得到损失函数为

 

       

 

       同样经过推到得到

 

       非负矩阵分解(NMF)_第4张图片

 

   

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的部分源码如下

 

   非负矩阵分解(NMF)_第5张图片

 

   从上面代码可以看出,当矩阵V中元素是非double时,会强制转化为double类型。而WH矩阵是服从高斯分布

   的随机矩阵,随后传入参数调用whupdate,如果迭代次数太少会打印警告Iteration doesn't converge!

 

   所以用bignmf分解非负矩阵调用如下函数就行了

 

   

 

   代码:

   非负矩阵分解(NMF)_第6张图片

 

   以上是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

 

你可能感兴趣的:(非负矩阵分解(NMF))