[转载]随机梯度下降求解矩阵分解的sample(M=UV类型分解)
2013-06-03 19:30
309 查看
原文地址:随机梯度下降求解矩阵分解的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:%fn",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 Un");
for(int i=0;i<5;++i)
{
for(int j=0;j<2;++j)
{
printf("%ft",u_matrix[0][i][j]);
}
printf("n");
}
printf("nmatrix Vn");
for(int i=0;i<2;++i)
{
for(int j=0;j<5;++j)
{
printf("%ft",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("%ft",u_matrix[0][i][0]*i_matrix[0][0][j]+u_matrix[0][i][1]*i_matrix[0][1][j]);
}
printf("n");
}
printf("Original matrixn");
for(int i=0;i<5;++i)
{
for(int j=0;j<5;++j)
{
printf("%ft",rate_matrix[0][i][j]);
}
printf("n");
}
return 0;
}
----来源: http://blog.csdn.net/pennyliang/article/details/6859729
以下是代码,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:%fn",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 Un");
for(int i=0;i<5;++i)
{
for(int j=0;j<2;++j)
{
printf("%ft",u_matrix[0][i][j]);
}
printf("n");
}
printf("nmatrix Vn");
for(int i=0;i<2;++i)
{
for(int j=0;j<5;++j)
{
printf("%ft",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("%ft",u_matrix[0][i][0]*i_matrix[0][0][j]+u_matrix[0][i][1]*i_matrix[0][1][j]);
}
printf("n");
}
printf("Original matrixn");
for(int i=0;i<5;++i)
{
for(int j=0;j<5;++j)
{
printf("%ft",rate_matrix[0][i][j]);
}
printf("n");
}
return 0;
}
----来源: http://blog.csdn.net/pennyliang/article/details/6859729
相关文章推荐
- 随机梯度下降求解矩阵分解的sample(M=UV类型分解)
- 随机梯度下降求解矩阵分解的sample(M=UV类型分解)
- 奇异值、奇异矩阵、SVD分解、正交矩阵(转载)
- LUP分解求解线性方程组及求逆矩阵 java
- 矩阵特征分解介绍及雅克比(Jacobi)方法实现特征值和特征向量的求解(C++/OpenCV/Eigen)
- Netflix-协同过滤矩阵分解之随机梯度下降(SGD)
- 基于矩阵分解的推荐算法-梯度下降算法-非并行计算[转载]
- 基于随机梯度下降的矩阵分解推荐算法(python)
- 基于随机梯度下降的矩阵分解推荐算法
- 转载:Intel MKL 稀疏矩阵求解PARDISO 函数
- 【计算方法笔记】矩阵分解求解线性方程组
- 基于 MATRIX 类的矩阵分解和方程组求解
- Matlab求解中性类型的时滞微分方程组-中性类型的时滞微分方程
- lightoj1052 String Growth (矩阵求解Fibonacci)
- DeviceDriver Windows NT 驱动程序类型 (转载)
- C#中的类型转换(转载)
- 对极几何约束、基本矩阵求解、求极线
- [转载]矩阵求导,矩阵计算
- 矩阵三角分解,QR分解,奇异值分解
- oracle的基本数据类型(转载)