基于矩阵分解的推荐系统实例

使用MATLAB尝试了随机梯度下降的矩阵分解方法,实现了一个比较简单的推荐系统的原理。

常用推荐系统的方法有协同过滤,    基于物品内容过滤等等。

 

这次是用的矩阵分解模型属于协同过滤的一种方法,大致原理是通过一定数量的因子来描述各个用户的喜好和各个物品的属性。

通过随机梯度下降法分解后得到两个矩阵,一个是用户因子矩阵,另一个是物品因子矩阵。

这两个矩阵相乘可以得到所有用户对所有电影的预测评分。

 

以Movie-Lens数据集举例,这包含943个用户对1682部电影的十万条评分。

第一列用户编号,第二列电影编号,第三列用户对该物品的评分(1-5分);

 

Matlab代码:

function [ Grade,userCal,itemCal,deviation ] = iterator( GradeData ,iteraTime )
% 利用随机梯度下降法分解稀疏的用户评分矩阵,得到用户因子矩阵和物品因子矩阵,因子项数30;
% iteraTime : 迭代次数,建议值:30 
alpha = 0.01;
lambda = 10;
userCal = rand(943,30);
itemCal = rand(1682,30);

range = size(GradeData,1);
userCal_last = userCal;
itemCal_last = itemCal;

for limit = 1:1:iteraTime
    for i = 1:1:range
        tempUser = GradeData(i,1);
        tempItem = GradeData(i,2);
        tempGrade = GradeData(i,3);
        E = tempGrade - userCal(tempUser,:) * itemCal(tempItem,:)';
            userCal(tempUser,:) = userCal_last(tempUser,:) + alpha * ( E * itemCal_last(tempItem,:) - lambda * userCal_last(tempUser,:) );
            itemCal(tempItem,:) = itemCal_last(tempItem,:) + alpha * ( E * userCal_last(tempUser,:) - lambda * itemCal_last(tempItem,:) );
    end
    userCal_last = userCal;
    itemCal_last = itemCal;
    alpha = alpha / (1 + limit);
end
deviation= Deviation(GradeData ,lambda , userCal, itemCal);
realGrade = pack(GradeData);
Grade = userCal * itemCal' - realGrade;
end

function [ deviation ] = Deviation( GradeData , lambda ,user , item )
%计算平方误差,误差越小,拟合效果越好
range = size(GradeData(:,1));
deviation = 0;
for i = 1:1:range
    tempUser = GradeData(i,1);
    tempItem = GradeData(i,2);
    tempGrade = GradeData(i,3);
    deviation = deviation + ( tempGrade - user(tempUser,:) * item(tempItem,:)' )^2 + lambda * ( sum(user(tempUser,:).^2 ) + sum(item(tempItem,:).^2) ) ;
end
end

function [realGrade] = pack(GradeData)
%
    realGrade = [];
    range = size(GradeData,1);
    for i =1:1:range
        realGrade(GradeData(i,1),GradeData(i,2)) = GradeData(i,3);
    end
end

设置了30个因子项,这个可以根据实际情况调整。

迭代次数可以根据每一次迭代的deviation与上一次的deviation比较来判定是否收敛。

代码中直接迭代了20次,可以算出一个比较好的结果。

 

这样用户因子矩阵为943*30,物品因子矩阵为,1682*30;

 

分解后得到这两个矩阵:

 

 

 

将用户因子矩阵(943*30)与物品因子矩阵(1682*30)的转置相乘即可得到评分预测矩阵(943*1682):

 

 

根据评分预测矩阵,就可以对用户进行相关推荐了。

 

基于随机梯度下降法的推荐系统虽然是基于内容推荐,但是系统设计者无需清楚每一个物品的内容属性和每一个用户的喜好,通过矩阵分解法得出的因子矩阵可以很好的描述用户和物品的属性,当然,这来自于用户的历史行为,用户过去的行为越多,则推荐越准确。比较流行的矩阵分解法还有SVD分解法等。

 

因为是协同过滤的方法,所以也存在着冷启动的问题,比如一个新物品,未和任何用户产生交互,则它永远不会被推荐,而新注册的用户也因为没有历史行为而无法对其推荐。其次,还有稀疏性问题,当系统中 用户与物品的交互过少时,推荐结果往往不会太准确。

 

 

转载于:https://www.cnblogs.com/moranBlogs/p/3795392.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个基于GSL的线性代数实例,演示如何使用GSL库来解决线性方程组和求逆矩阵问题。 ```c #include <stdio.h> #include <gsl/gsl_linalg.h> int main() { // 定义矩阵和向量 double mdata[] = {1.0, 2.0, 3.0, 2.0, 4.0, 5.0, 3.0, 5.0, 6.0}; double vdata[] = {1.0, 2.0, 3.0}; gsl_matrix_view m = gsl_matrix_view_array(mdata, 3, 3); gsl_vector_view v = gsl_vector_view_array(vdata, 3); // 解决线性方程组 Ax = b gsl_vector *x = gsl_vector_alloc(3); gsl_permutation *p = gsl_permutation_alloc(3); int signum; gsl_linalg_LU_decomp(&m.matrix, p, &signum); gsl_linalg_LU_solve(&m.matrix, p, &v.vector, x); printf("Solution to Ax = b:\n"); gsl_vector_fprintf(stdout, x, "%g"); // 求矩阵的逆 gsl_matrix *inv = gsl_matrix_alloc(3, 3); gsl_matrix *mcopy = gsl_matrix_alloc(3, 3); gsl_matrix_memcpy(mcopy, &m.matrix); gsl_linalg_LU_decomp(mcopy, p, &signum); gsl_linalg_LU_invert(mcopy, p, inv); printf("Inverse of A:\n"); gsl_matrix_fprintf(stdout, inv, "%g"); // 释放内存 gsl_vector_free(x); gsl_permutation_free(p); gsl_matrix_free(inv); gsl_matrix_free(mcopy); return 0; } ``` 该程序首先定义了一个3x3的矩阵和一个长度为3的向量,并将它们存储在GSL的矩阵和向量视图中。然后,程序使用GSL库中的LU分解和求解线性方程组函数来解决线性方程组Ax=b,并打印解向量x的值。接下来,程序使用GSL库中的LU分解和求逆矩阵函数来求解矩阵A的逆,并打印逆矩阵的值。最后,程序释放了动态分配的内存。 需要注意的是,在编译该程序时,需要链接GSL库,例如: ``` gcc -o example example.c -lgsl -lgslcblas -lm ``` 此处,-lgsl和-lgslcblas选项用于链接GSL库和BLAS库,-lm选项用于链接数学库。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值