使用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分解法等。
因為是協同過濾的方法,所以也存在着冷啟動的問題,比如一個新物品,未和任何用戶產生交互,則它永遠不會被推薦,而新注冊的用戶也因為沒有歷史行為而無法對其推薦。其次,還有稀疏性問題,當系統中 用戶與物品的交互過少時,推薦結果往往不會太准確。