轉載自博客園,請直接鏈接原文查看(更詳細更完整):
http://www.cnblogs.com/kobedeshow/p/3651833.html?utm_source=tuicool&utm_medium=referral
本文將要討論基於矩陣分解的推薦算法,這一類型的算法通常會有很高的預測精度,也活躍於各大推薦系統競賽上面,前段時間的百度電影推薦最終結果的前10名貌似都是把矩陣分解作爲一個單模型,最後各種ensemble.
假設
對於
對於如何衡量,我們分解的好壞呢,式子3,給出了衡量標準,也就是損失函數,平方項損失,最後的目標,就是每一個元素(非缺失值)的e(i,j)的總和 最小
目前現在評分矩陣有了,損失函數也有了,該優化算法登場了,下面式子4是,基於梯度下降的優化算法,p,q裏面的每個元素的更新方式
然而,機器學習算法都喜歡加一個正則項(控制過擬合),這裏面對式子3稍作修改,得到如下式子5,beita (Mahout中的lambda)是正則參數
相應的p,q矩 陣各個元素的更新也換成了如下方式
//C++算法:(對原文代碼格式進行了調整,僅保留核心算法部分,完整的代碼要查看原文,能直接運行出結果來)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
using namespace std;
void matrix_factorization(double *R,double *P,double *Q,int N,int M,int K,int steps=5000,float alpha=0.0002,float beta=0.02)
{
for(int step =0;step<steps;++step){
for(int i=0;i<N;++i) {
for(int j=0;j<M;++j) {
if(R[i*M+j]>0) {
double error = R[i*M+j];
for(int k=0;k<K;++k)
error -= P[i*K+k]*Q[k*M+j];
for(int k=0;k<K;++k) {
P[i*K+k] += alpha * (2 * error * Q[k*M+j] - beta * P[i*K+k]);
Q[k*M+j] += alpha * (2 * error * P[i*K+k] - beta * Q[k*M+j]);
}
} //end if
} //end M
} //end N
double loss=0;
for(int i=0;i<N;++i) {
for(int j=0;j<M;++j) {
if(R[i*M+j]>0){
double error = 0;
for(int k=0;k<K;++k)
error += P[i*K+k]*Q[k*M+j];
loss += pow(R[i*M+j]-error,2);
for(int k=0;k<K;++k)
loss += (beta/2) * (pow(P[i*K+k],2) + pow(Q[k*M+j],2));
}//end for R
}//end for M
}//end for N
if(loss<0.001) break; //停止條件
}//end step
}//end function
R矩陣
5,3,0,1,
4,0,0,1,
1,1,0,5,
1,0,0,4,
0,1,5,4,
重構出來的R矩陣
4.9,2.9,5.8,1.0,
3.5,2.2,5.5,2.2,
0.9,0.9,5.8,5.2,
1.2,0.9,4.3,3.3,
1.3,1.0,4.9,3.9,
這樣原來沒有值的地方就全部有預測值了,是不是很神奇呢?!