假设由n个非负样本数据组成的非负数据矩阵X,非负矩阵分解的目标是将非负数据矩阵X分解为基矩阵W和系数矩阵H的乘积,当k小于min(m,n)时,X就得到了有效压缩。
非负矩阵分解的MATLAB实现:
1.随机初始化W和H矩阵
2.设置最大迭代次数,保证分解结果收敛
3.每迭代一次,先更新W,对W的每一列做归一化处理(保证缩放不变性),再更新H。
matlab实现
function [W,H,errs,loss] = nmf_euc(V, r)
% 输入检查
% 不含负值元素
% H为系数矩阵,一列不能全为0
if min(min(V)) < 0
error('Matrix entries can not be negative');
end
if min(sum(V,2)) == 0
error('Not all entries in a row can be zero');
end
% V是一个含有n个样本的矩阵,每一列对应一个样本,每个样本为m维
[m,n] = size(V);
% 随机初始化W和H矩阵
W = rand(m,r);
H = rand(r,n);
% 设置最大迭代次数,保证分解结果是收敛的
niter = 1000;
myeps = 1e-10;
errs = zeros(niter,1);
for t = 1:niter
W = W .* ( (V*H') ./ max(W*(H*H'), myeps) );
W = normalize_W(W,1);
H = H .* ( (W'*V) ./ max((W'*W)*H, myeps) );
loss = sum((V-W*H).^2);
errs(t) = sum(sum(loss));
end