随机梯度下降求解矩阵分解的sample(M=UV类型分解)

以下是代码,3小时搞定,完成的一刻,非常喜悦。原始矩阵可以理解为5个用户对5件衣服的点评,其中用户1,2对第5件衣服打高分,因为第五件衣服好看。用户3,4,5对第一件衣服打高分,因为价格便宜,因此这个矩阵可以分解为5*2,2*5的两个矩阵(2表示2个因素,色彩和价格)运行过程中错误在不断减少,表明算法的有效性。 code 很hard不比拼code质量,只求算法正确性。
view plain

     #include "stdio.h"  
    static unsigned long next = 1;  
      
    int myrand(void) {  
            next = next * 1103515245 + 12345;  
            return((unsigned)(next/65536) % 32768);  
    };  
      
    void mysrand(unsigned seed = 1) {  
            next = seed;  
    };  
      
    int main(void)  
    {  
            float rate_matrix[2][5][5] = {  
                    {  
                    {1,2,3,1,5},  
                    {1,2,3,1,5},  
                    {5,1,3,1,2},  
                    {5,1,3,1,2},  
                    {5,1,3,1,2},},  
                    {  
                    {1,2,3,1,5},  
                    {1,2,3,1,5},  
                    {5,1,3,1,2},  
                    {5,1,3,1,2},  
                    {5,1,3,1,2},}  
            };  
            float u_matrix[2][5][2] = {  
                    {  
                    {0.4,0.5},  
                    {0.4,0.5},  
                    {0.4,0.33},  
                    {0.4,0.33},  
                    {0.4,0.33},},  
                    {{2,1},  
                    {1,2},  
                    {1,3},  
                    {4,1},  
                    {1,1},}  
            };  
            float i_matrix[2][2][5] = {  
                    {{0.1,0.2,0.1,0.4,0.1},  
                    {0.2,0.1,0,0.1,1}},  
                    {{1,1,1,1,1},  
                    {1,1,1,1,1}},  
            };  
      
            for( int s = 0;s<=50;++s)  
            {  
      
                    int now = s%2;  
                    int next = (s+1)%2;  
      
                    for(int i = 0;i < 5;++i)  
                    {  
                            for(int j = 0; j<5;++j)  
                            {  
                                    rate_matrix[1][i][j] = 0.0;  
                                    for(int k =0;k<2;++k)  
                                    {  
                                            rate_matrix[1][i][j] += u_matrix[now][i][k]*i_matrix[now][k][j];  
                                    }  
                                    rate_matrix[1][i][j]  = rate_matrix[1][i][j] - rate_matrix[0][i][j];  
      
                            };  
                    };  
                    double sum_err = 0.0;  
                    for(int i = 0;i < 5;++i)  
                    {  
                            for(int j = 0;j<5;++j)  
                            {  
                                    sum_err += (rate_matrix[1][i][j])*(rate_matrix[1][i][j]);  
                            }  
                    }  
                    sum_err/=25;  
                    printf("sum_err:%f\n",sum_err);  
                    for(int i =0;i<5;++i)  
                    {  
                            int k = myrand()%5;  
                            double b = i_matrix[now][0][k];  
                            double a = rate_matrix[1][i][k];  
                            u_matrix[next][i][0] = u_matrix[now][i][0] - 0.1*(a*b - 0.1*u_matrix[now][i][0]);  
      
                            b = i_matrix[now][1][k];  
                            a = rate_matrix[1][i][k];  
                            u_matrix[next][i][1] = u_matrix[now][i][1] - 0.1*(a*b - 0.1*u_matrix[now][i][1]);  
                    }  
      
                    for(int i =0;i<5;++i)  
                    {  
                            int k = myrand()%5;  
                            double b = u_matrix[now][k][0];  
                            double a = rate_matrix[1][k][i];  
                            i_matrix[next][0][i] = i_matrix[now][0][i] - 0.1*(a*b - 0.1*i_matrix[now][0][i]);  
      
                            b = u_matrix[now][k][1];  
                            a = rate_matrix[1][k][i];  
                            i_matrix[next][1][i] = i_matrix[now][1][i] - 0.1*(a*b - 0.1*i_matrix[now][1][i]);  
      
                    }  
            };  
            printf("matrix U\n");  
            for(int i=0;i<5;++i)  
            {  
                    for(int j=0;j<2;++j)  
                    {  
                            printf("%f\t",u_matrix[0][i][j]);  
                    }  
                    printf("\n");  
            }  
            printf("\nmatrix V\n");  
            for(int i=0;i<2;++i)  
            {  
                    for(int j=0;j<5;++j)  
                    {  
                            printf("%f\t",i_matrix[0][i][j]);  
                    }  
                    printf("\n");  
            }  
            printf("matrix U*V \n");  
            for(int i=0;i<5;++i)  
            {  
                    for(int j=0;j<5;++j)  
                    {  
                            printf("%f\t",u_matrix[0][i][0]*i_matrix[0][0][j]+u_matrix[0][i][1]*i_matrix[0][1][j]);  
                    }  
                    printf("\n");  
            }  
            printf("Original matrix\n");  
            for(int i=0;i<5;++i)  
            {  
                    for(int j=0;j<5;++j)  
                    {  
                            printf("%f\t",rate_matrix[0][i][j]);  
                    }  
                    printf("\n");  
            }  
            return 0;  
    }                                      



----来源: http://blog.csdn.net/pennyliang/article/details/6859729


原文地址:http://blog.sina.com.cn/s/blog_7eb42b5a0100xnog.html


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值