協同過濾算法之基於物品的推薦算法
目前有關個性化推薦算法主要分為三大類:1.基於協同過濾的推薦;2.基於內容過濾的推薦和3.社會化推薦。
本文主要討論基於協同過濾的推薦,而該算法也可以划分為兩類:
1.基於用戶的協同過濾算法(UserCF)
該算法利用用戶之間的相似性來推薦用戶感興趣的信息,個人通過合作的機制給予信息相當程度的回應(如評分)並記錄下來以達到過濾的目的進而幫助別人篩選信息,回應不一定局限於特別感興趣的,特別不感興趣信息的紀錄也相當重要。但有很難解決的兩個問題,一個是稀疏性,即在系統使用初期由於系統資源還未獲得足夠多的評價,很難利用這些評價來發現相似的用戶。另一個是可擴展性,隨着系統用戶和資源的增多,系統的性能會越來越差。
2.基於物品的協同過濾算法(ItemCF)
內容過濾根據信息資源與用戶興趣的相似性來推薦商品,通過計算用戶興趣模型和商品特征向量之間的向量相似性,主動將相似度高的商品發送給該模型的客戶。由於每個客戶都獨立操作,擁有獨立的特征向量,不需要考慮別的用戶的興趣,不存在評價級別多少的問題,能推薦新的項目或者是冷門的項目。這些優點使得基於內容過濾的推薦系統不受冷啟動和稀疏問題的影響
數據描述
#用戶,興趣度,物品
uid_score_bid = ['A,1,a', 'A,1,b', 'A,1,d', 'B,1,b', 'B,1,c', 'B,1,e', 'C,1,c', 'C,1,d', 'D,1,b', 'D,1,c', 'D,1,d',
'E,1,a', 'E,1,d']
1.構建用戶-->物品的倒排
def loadData(files):
data ={};
for line in files:
user,score,item=line.split(",");
data.setdefault(user,{});
data[user][item]=score;
print "----1.用戶:物品的倒排----"
print data
return data
#2.計算
# 2.1 構造物品-->物品的共現矩陣
# 2.2 計算物品與物品的相似矩陣
def similarity(data):
# 2.1 構造物品:物品的共現矩陣
N={};#喜歡物品i的總人數
C={};#喜歡物品i也喜歡物品j的人數
for user,item in data.items():
for i,score in item.items():
N.setdefault(i,0);
N[i]+=1;
C.setdefault(i,{});
for j,scores in item.items():
if j not in i:
C[i].setdefault(j,0);
C[i][j]+=1;
print "---2.構造的共現矩陣---"
print ('N:',N);
print ('C',C);
#2.2 計算物品與物品的相似矩陣
W={};
for i,item in C.items():
W.setdefault(i,{});
for j,item2 in item.items():
W[i].setdefault(j,0);
W[i][j]=C[i][j]/sqrt(N[i]*N[j]);
print "---3.構造的相似矩陣---"
print W
return W
#3.根據用戶的歷史記錄,給用戶推薦物品
def recommandList(data,W,user,k=3,N=10):
rank={};
for i,score in data[user].items():#獲得用戶user歷史記錄,如A用戶的歷史記錄為{'a': '1', 'b': '1', 'd': '1'}
for j,w in sorted(W[i].items(),key=operator.itemgetter(1),reverse=True)[0:k]:#獲得與物品i相似的k個物品
if j not in data[user].keys():#該相似的物品不在用戶user的記錄里
rank.setdefault(j,0);
rank[j]+=float(score) * w;
print "---4.推薦----"
print sorted(rank.items(),key=operator.itemgetter(1),reverse=True)[0:N];
return sorted(rank.items(),key=operator.itemgetter(1),reverse=True)[0:N];
if __name__=='__main__':
#用戶,興趣度,物品
uid_score_bid = ['A,1,a', 'A,1,b', 'A,1,d', 'B,1,b', 'B,1,c', 'B,1,e', 'C,1,c', 'C,1,d', 'D,1,b', 'D,1,c', 'D,1,d',
'E,1,a', 'E,1,d'];
data=loadData(uid_score_bid);#獲得數據
W=similarity(data);#計算物品相似矩陣
recommandList(data,W,'A',3,10);#推薦