基于用户行为分析的推荐算法
文章目錄
- 基于用戶行為分析的推薦算法
- 用戶行為數據簡介
- 用戶行為分析
- 用戶活躍度和物品流行度的分布
- 用戶活躍度和物品流行度的關系
- 實驗設計和算法測評
- 數據集
- 實驗設計
- 評測指標
- 基于領域的算法
- 基于用戶的協同過濾算法
- 源代碼實現
基于用戶行為分析的推薦算法
這種算法稱為協同過濾算法,協同過濾是指用戶可以齊心協力,通過不斷的和網站互動,使自己的推薦列表能夠過濾掉自己不感興趣的物品,從而越來越滿足自己的需求。
用戶行為數據簡介
用戶行為數據最簡單的存在形式是日志。很多互聯網業務會把原始日志按照用戶行為匯總成為會話日志(session log),其中每個會話代表一次用戶行為和對應的服務,如展示日志,點擊日志。
用戶行為在個性化推薦系統中一般分為顯性反饋行為(explicit feedback)和隱性反饋行為(implicit feedback)。explicit feedback包括用戶明確表示對物品的喜好的行為。implicit feedback 是指那些不能明確反應用戶喜好的行為。與explicit feedback相比,隱性反饋雖然不明確,但是數量龐大。
| 用戶興趣 | 明確 | 不明確 |
| 數量 | 很少 | 龐大 |
| 存儲 | 數據庫 | 分布式文件系統 |
| 實時讀取 | 實時 | 有延遲 |
| 正負反饋 | 都有 | 只有正反饋 |
用戶行為分析
在利用用戶行為數據設計推薦算法之前,首先需要對用戶行為數據進行分析,了解數據中蘊含的一般規律,這樣才能對算法的設計起到指導作用。以下用戶行為數據的普遍規律。
用戶活躍度和物品流行度的分布
互聯網上很多數據分布都滿足power Law也稱長尾分布。
f(x)=αxkf(x)=\alpha x^kf(x)=αxk
研究發現,用戶行為數據也滿足power law分布,fi(k)f_i (k)fi?(k)為被k個用戶產生行為的物品數,fu(k)f_u(k)fu?(k)為對k個物品產生行為的用戶數。即
fi(k)=αikiβf_i(k)=\alpha_i k^\beta_ifi?(k)=αi?kiβ?fu(k)=αukuβf_u(k)=\alpha_u k^\beta_ufu?(k)=αu?kuβ?
用戶活躍度和物品流行度的關系
根據這個規律可以發現,用戶越活躍,越傾向于冷門物品。
僅僅基于用戶行為數據設計的推薦算法一般稱為協同過濾算法。學術界對協同過濾算法提出了很多方法,如:基于領域的方法,隱語義模型、基于圖的隨機游走算法等。應用最廣泛的是:
- 基于用戶的協同過濾算法 這種算法給用戶推薦和他興趣相似的其他用戶喜歡的物品
- 基于物品的協同過濾算法 這種算法給用戶推薦和他之前喜歡的物品相似的物品
實驗設計和算法測評
數據集
采用GroupLens提供的MovieLens數據集,該數據集包含3個不同版本,選用中等大小的數據集,包含6000多用戶對4000多部電影的100萬條評分。該數據集是一個評分數據集。著重研究隱反饋數據集中的TopN推薦問題,因此忽略數據集中的評分紀錄。TopN的推薦任務是預測用戶會不會給某部電影評分,而不是預測用戶在準備對電影評分的前提下給電影評多少分。
實驗設計
首先,將用戶行為數據集均勻隨機分成M份(M=8),挑選一份作為測試集,其余的作為訓練集。在訓練集上建立用戶興趣模型,并在測試集上對用戶行為進行預測,統計相應的評測指標。為了保證評測指標并不是過擬合的結果,需要進行M次試驗,并且每次都使用不同的測試集。然后取M次試驗的評測指標的平均值作為最終的評測指標。
下面代碼為將用戶評分文件中的數據分成訓練集合測試集的過程。
這里,每次選取不同的k和相同的隨機種子seed,進行M次實驗就可以得到M個不同的訓練集和測試集,然后分別進行實驗,用M次實驗的平均值作為最后的評測指標。這樣做主要就是為了防止某次實驗結果是過擬合的結果(overf itting)。
評測指標
對用戶u推薦N個物品,記為(R(u)R(u)R(u)),令用戶在測試集上喜歡的物品集合為(T(u)T(u)T(u)),然后通過準確率/召回率評測推薦算法的精度:
recall=∑u∣R(u)andT(u)∑u∣T(u)∣recall=\frac{\sum_u |R(u) and T(u)}{\sum_u |T(u)|} recall=∑u?∣T(u)∣∑u?∣R(u)andT(u)?
precision=∑u∣R(u)andT(u)∑u∣R(u)∣precision=\frac{\sum_u |R(u) and T(u)}{\sum_u |R(u)|} precision=∑u?∣R(u)∣∑u?∣R(u)andT(u)?
召回率描述有多少比例的用戶-物品評分紀錄包含在最終的推薦列表中,而準確率描述最終的推薦列表中有多少比例是發生過的用戶-評分紀錄。
覆蓋率反映推薦算法發掘長尾的能力,覆蓋率越高,說明推薦算法越能夠將長尾中的物品推薦給用戶。
Coverage=?u∈UR(u)ICoverage=\frac{\bigcup_{u\in U}R(u) }{I}Coverage=I?u∈U?R(u)?
用推薦列表中的物品的平均流行度度量推薦結果的新穎度,如果推薦出的物品都很熱門,說明推薦的新穎度較低,否則說明推薦結果比較新穎。
基于領域的算法
基于用戶的協同過濾算法
基于用戶的協同過濾算法就是將興趣相同的人喜歡的物品推薦給你。
包括兩個步驟:
步驟1的關鍵就是計算兩個用戶的興趣相似度。這里,主要利用行為的相似度計算興趣的相似度。給定用戶uuu和vvv,令N(u)N(u)N(u)為用戶uuu曾經有過正反饋的物品集合,令N(v)N(v)N(v)為用戶vvv曾經有過正反饋的物品集合。計算方法有兩種:
- jaccard公式 :Wuv=∣N(u)?N(v)∣∣N(u)?N(v)∣W_{uv}=\frac{|N(u)\bigcap N(v)|}{|N(u)\bigcup N(v)|}Wuv?=∣N(u)?N(v)∣∣N(u)?N(v)∣?
- 通過余弦相似度計算 :Wuv=∣N(u)?N(v)∣∣N(u)∣∣N(v)∣W_{uv}=\frac{|N(u)\bigcap N(v)|}{\sqrt{|N(u)||N(v)|}}Wuv?=∣N(u)∣∣N(v)∣?∣N(u)?N(v)∣?
源代碼實現
import os import math import numpy as np import random NumOfMovies = 9000 NumOfUsers = 700def get_data(file):"""讀取數據"""if not os.path.exists(file):return {}fp = open(file)data = {}linenum = 0for line in fp:if linenum == 0:linenum += 1continueline = line.split(',')userid,itemid = int(line[0]),int(line[1])if userid not in data:data[userid] = []data[userid].append(itemid)fp.close()return datadef split_data(data,M,k,seed):#將數據劃分成為測試集和訓練集test = {}train = {}random.seed(seed)for user,items in data.items():for i in items:if random.randint(0,M) == k:if user not in test:test[user] =[]test[user].append(i)else:if user not in train:train[user] = []train[user].append(i)return train,testdef UserSimilarity(train):#得到用戶相似集合W#建立電影用戶倒排表item_user = {}for u,items in train.items():for i in items:if i not in item_user:item_user[i] = []item_user[i].append(u)#計算C[u][v]即u和v共同觀看的電影數C = {}N = np.zeros([NumOfUsers],dtype = np.int32)user_related = {}for i,users in item_user.items():for u in users:N[u] += 1if u not in C:C[u] = {}for v in users:if u == v:continueif v not in C[u]:C[u][v] = 0C[u][v] += (1/math.log(1+len(users)))if u not in user_related:user_related[u] = []user_related[u].append(v)#求用戶相似矩陣WW = np.zeros([NumOfUsers,NumOfUsers],dtype = np.float)for u,users in C.items():for v in users:W[u][v] += C[u][v] / math.sqrt(N[u] * N[v])return W ,user_relateddef recommend(User,train,K,N,W,user_related):#通過相似矩陣W給用戶產生推薦recordk_user = {}rank ={}for v in user_related[User]:k_user[v] = W[User][v]k_user = sorted(k_user.items(),key = lambda x:x[1],reverse = True)[:K]for v,w in k_user:for item in train[v] :if item in train[User]:continueif item not in rank:rank[item] = 0rank[item] += wrank = sorted(rank.items(),key = lambda x:x[1],reverse = True)[:N]return rankdef Recall(train,test,N,k,W,user_related):#計算召回率hit = 0totla = 0for user in train:tu =test[user]rank = recommend(user,train,k,N,W,user_related)for item in rank :if item[0] in tu :hit += 1totla += len(tu)return hit/(totla*1.0)def Precision(train,test,N,k,W,user_related):#計算召回率hit = 0totla = 0for user in train:tu =test[user]rank = recommend(user,train,k,N,W,user_related)for item in rank :if item[0] in tu :hit += 1totla += len(rank)return hit/(totla*1.0)if __name__ == "__main__":data = get_data(r"F:\個性化推薦算法\UserCF\data\ratings.csv")train,test = split_data(data,2,1,1)del dataW,user_relatde = UserSimilarity(train)recall = Recall(train,test,10,10,W,user_relatde)precision = Precision(train,test,10,10,W,user_relatde)print(recall,precision)注:以上參考《推薦系統實踐》一書
總結
以上是生活随笔為你收集整理的基于用户行为分析的推荐算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北京理工大学matlab,北京理工大学机
- 下一篇: 以精益思想为产品方法