MATLAB 非负矩阵分解

 这个算法是Lee和Seung在1999年发表在nature杂志上的。具体论文看这里:http://www.seas.upenn.edu/~ddlee/Papers/nmf.pdf。

  看不懂英文没关系,可以看这个中文的介绍:http://wenku.baidu.com/view/94c8af0bf78a6529647d5331.html。

  原理上面两篇文章已经很清楚了,我在按自己的理解介绍一下吧。

  通常矩阵分解如svd或其他什么的分解都会把矩阵分解为有正有负的矩阵,而他的这种分解方法就把矩阵完全分解成只有正数的矩阵,因为现实世界中如图像,负数是没什么意义的,所以这种只分解为正数矩阵的分解方法就很有意义了,要不也不会发在nature这样牛B的杂志上。

  这里是分解的公式:

  这里r是分解矩阵的秩,V是原矩阵的一个近似,W与H就是分解而成的两个矩阵。

  下面是W和H的求法,是一个迭代算法,初始的W与H是随机的就行了:

  

  关于代码,我借鉴了这个博客的:http://fxy1211.blog.163.com/blog/static/68255322007826111015905/,真是太感谢这位博主了。

  下面是代码:

 1 clear all;
 2 close all;
 3 clc;
 4 
 5 V=double(imread('lena.jpg'));
 6 imshow(mat2gray(V));
 7 
 8 [i u]=size(V);                                    %计算V的规格
 9 r=100;                                  %设置分解矩阵的秩
10 W=rand(i,r);                            %初始化WH,为非负数
11 H=rand(r,u);
12 maviter=100;                                    %最大迭代次数
13 for iter=1:maviter
14     W=W.*((V./(W*H))*H');           %注意这里的三个公式和文中的是对应的
15     W=W./(ones(i,1)*sum(W));    
16     H=H.*(W'*(V./(W*H)));
17 end
18 
19 img_V=W*H;
20 figure;
21 imshow(mat2gray(img_V));

下面是原图和重构后的效果,如果秩和迭代次数越大,那么重构后的图越接近原图:

原图

重构图

因为这个是看自己相关方向论文偶然在一篇论文的引用中看到了这个算法,所以就稍微了解了一下,肯定有不妥的地方,就这样吧。

原文地址:https://www.cnblogs.com/ybqjymy/p/13646081.html