非负矩阵分解 matlab,【求问】Funk-SVD如何保障分解矩阵非负

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

刚接触机器学习和矩阵分解,有一个预测矩阵空白数据的需求,比较基础的是采用Funk-SVD,V=WH,但这个分解出来可能有负值。后来看了非负矩阵分解的算法,自己推了一下。模仿NMF取了一个特殊的学习率,把负项削掉了(没有完备的证明),但正常推导效果不好(猜测是步长会变大?)。然后找到一篇博文,上面加了一个对W或H的归一化,效果就好了。也不知道为啥。有哪位大佬懂么?

下附matlab程序

[n m]=size(V);

Va=V;

r=round(0.5*m*n/(m+n))+1; %设置分解矩阵的秩

W=rand(n,r); %初始化WH,为非负数

H=rand(r,m);

P=ones(n,m)-isnan(V);

for i=1:n

for j=1:m

if P(i,j)==0 %空

V(i,j)=1; %任意给一个非空初值

end

end

end

maviter=2000; %最大迭代次数

for iter=1:maviter

% W=W.*((V./(W*H))*H'); %注意这里的三个公式和文中的是对应的

% W=W./(ones(i,1)*sum(W));

% H=H.*(W'*(V./(W*H)));

% W迭代

B=W*H;

for i=1:n

for k=1:r

fz=0;fm=0;

for j=1:m

fz=fz+P(i,j)*V(i,j)*H(k,j);

fm=fm+P(i,j)*H(k,j)*B(i,j);

end

W(i,k)=W(i,k)*fz/fm;

end

end

% W=W./(ones(n,1)*sum(W));

% H迭代

for j=1:m

for k=1:r

fz=0;fm=0;

for i=1:n

fz=fz+P(i,j)*W(i,k)*V(i,j);

fm=fm+P(i,j)*B(i,j)*W(i,k);

end

H(k,j)=H(k,j)*fz/fm;

end

end

H=H./(sum(H)*ones(m,1)); %%%%%这里多了一步归一化

loss=0;

for i=1:n

for j=1:m

if P(i,j)>0 %非空

error = 0;

for k=1:r

error = error+W(i,k)*H(k,j);

end

loss=loss+(V(i,j)-error)*(V(i,j)-error);

end

end

end

if mod(iter,100)==0

iter

loss

end

end

V0=W*H;

re_V=Va;

for i=1:n

for j=1:m

if P(i,j)==0 %空

re_V(i,j)=V0(i,j);

end

end

end

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值