1. 程式人生 > >《推薦系統實踐》 程式實現 ——2.6 基於圖的模型

《推薦系統實踐》 程式實現 ——2.6 基於圖的模型

PersonalRank演算法

在這裡插入圖片描述 在基於圖的模型中,給使用者A進行個性化推薦,實際是計算使用者A對所有物品的感興趣程度。 在PersonalRank演算法中,不區分使用者和商品,所以計算使用者A對所有物品的感興趣程度,即計算除使用者A外的所有節點B,C,a,b,c,d對使用者A的重要度。

原理如下,其中PR(v)表示重要度(物品結點的訪問概率)。 在這裡插入圖片描述 具體過程描述1: 在這裡插入圖片描述 具體過程描述2: 初始賦予 ,即對於A來說,他自身的重要度為滿分,其他節點的重要度均為0。

然後開始在圖上游走。每次都是從PR不為0的節點開始遊走,往前走一步。繼續遊走的概率是alpha,停留在當前節點的概率是(1-alpha)。

第一次遊走, 從A節點以各自50%的概率走到了a和c,這樣a和c就分得了A的部分重要度α*PR(A)*0.5。第一次遊走結束後PR不為0的節點有A a c。

第二次遊走,分別從節點A a c開始,往前走一步。這樣節點a分得A 的重要度,節點c分得A 的重要度,節點A分得a 的重要度,節點A分得c 的重要度,節點B分得a 的重要度,節點B分得c 的重要度,節點C分得c 的重要度。最後要加上(1-α)。

程式實現:

def PersonalRank(G,alpha,root,max_step):

	rank = dict()#
	rank = {x: 0 for x in G.keys()}#初始化,將二分圖中所有結點(包括所有的使用者結點和物品結點)的訪問概率(即PR,也可稱為重要度)初始化為0
	rank[root] = 1 #為使用者root進行推薦(即計算使用者u對所有物品感興趣的程度)

	for k in range(max_step):
		tmp = {x: 0 for x in G.keys()}
		for i, ri in G.items():
			for j, wij in ri.items():
				if j not in tmp: #保險起見,其實上邊tmp在初始化時已經將所有的結點都包含進了
					tmp.update({j: 0})
				tmp[j] += alpha * rank[i] / (1.0 * len(ri))
				if j == root:
					tmp[j] += 1 - alpha
		rank = tmp
	return rank

G = {'A': {'a': 1, 'c': 1},
     'B': {'a': 1, 'b': 1, 'c': 1, 'd': 1},
     'C': {'c': 1, 'd': 1},
     'a': {'A': 1, 'B': 1},
     'b': {'B': 1},
     'c': {'A': 1, 'B': 1, 'C': 1},
     'd': {'B': 1, 'C': 1}} #節點和出邊的尾節點,構成了二分圖G; 邊E(i,j)的權重wij設定為1。

alpha = 0.85
result = PersonalRank(G,alpha,'A',100)
print(result)

執行結果

{'A': 0.5386042757187186, 'B': 0.37000524566306364, 'C': 0.17247155260659047, 'a': 0.30753291329505, 'b': 0.0786261054089978, 'c': 0.3808333138584477, 'd': 0.15192650597239551}

可以看出,使用者A已經對物品a、c有過行為了,所以只對物品b、d按照重要度進行排序為{d,b}。故給A的推薦列表就是{d,b}。

參考文獻