本实例为实现斯坦福大学吴恩达老师第9周16章推荐系统之协同过滤算法
吴恩达老师课件中关于协同过滤算法的总结:
假设电影供应商有5部电影和4个用户,用户评价了其中某一部分电影,现需预测用户对其余为评价电影的评分
u1 | u2 | u3 | u4 | |
m1 | 5 | 5 | 0 | 0 |
m2 | 5 | ? | ? | 0 |
m3 | ? | 4 | 0 | ? |
m4 | 0 | 0 | 5 | 4 |
m5 | 0 | 0 | 5 | ? |
根据上述算法总结,使用Matlab,可以实现上述算法。 (注:本例使用的是最基本的Gradient Descent)
完整代码如下:
%吴恩达老师视频中协同过滤算法的实现
%% input parameter
nu=4;%用户数
nm=5;%电影数量
n=3;%电影特征数
Y=[5,5,0,0;
5,-1,-1,0;
-1,4,0,-1;
0,0,5,4;
0,0,5,-1]; %Y(i,j)表示用户j对电影i的评分;-1表示对电影没有进行评分
R=ones(nm,nu);
idx=find(Y==-1);
R(idx)=0;
lambda=0.1;%正则化参数
alpha=0.01;%学习率
%% first:initialize x and theta
%这里必须采用随机初始化
x=rand(nm,n);%电影的特征向量
theta=rand(nu,n);%用户的参数向量
%% second:use Gradient Descent
J=0;%初始化代价函数为0;
x_grad=zeros(size(x));
theta_grad=zeros(size(theta));
loop=5e4;
for k=1:loop
predict=(x*theta').*R;
%代价函数
J=1/2*sum(sum((predict-Y) .^ 2))+lambda/2*sum(sum(theta .^ 2))+lambda/2*sum(sum(x .^ 2));
fprintf('J= %d\n', J);
for i=1:nm
index=find(R(i,:)==1);%找出每一行评价了的索引
thetatemp=theta(index,:);
Ytemp=Y(i,index);
x_grad(i,:)=(x(i,:)*thetatemp'-Ytemp)*thetatemp+lambda* x(i, :);
x(i,:)=x(i,:)-alpha*x_grad(i,:);
end
for i=1:nu
index=find(R(:,i)==1);%找出每一列评价了的索引
xtemp=x(index,:);
Ytemp=Y(index,i);
theta_grad(i,:)=(xtemp*theta(i,:)'-Ytemp)'*xtemp+lambda*theta(i,:);
theta(i,:)=theta(i,:)-alpha*theta_grad(i,:);
end
end
%% third: predict
Ypredict=x*theta';
%% calculate the square error
index= find(R== 1);
s_error_mat= (Ypredict- Y).^2;
s_error= sum(s_error_mat(index));