1. 程式人生 > >基於鄰域的協同過濾演算法(一)

基於鄰域的協同過濾演算法(一)

  兩個月前我開始學習機器學習,這兩個月期間學習了一些基礎的機器學習演算法及其Python實現。這周我剛開始學習《推薦系統實踐》這本書,並打算以後定期將自己的學習情況做個簡單的總結。這份總結是我這個部落格上的第一篇文章。這周的學習的主要內容是基於鄰域的協同過濾演算法。基於使用者行為分析的推薦演算法是個性化推薦系統的重要演算法,學術界一般將這種型別的演算法稱為協同過濾演算法。

  協同過濾,從名字就可以看出這種方法的本質是先有協同(使用者齊心協力)再有過濾(每個使用者的推薦列表能夠過濾掉他不喜歡的物品)。對協同過濾演算法,學術屆提出了了很多種方法,比如基於鄰域的方法(neighborhood-based)、隱語義模型(laten factor model)、基於圖的隨機遊走演算法(random walk on graph)等。

  基於鄰域的方法主要包括兩種演算法:基於使用者的協同過濾演算法(UserCF)和基於物品的協同過濾演算法(ItemCF)。

基於使用者的協同過濾演算法(UserCF):

  UserCF的本質就是我要給你推薦物品,我先找到與你興趣最相似的K個使用者,然後把他們喜歡的而你卻沒產生過行為的物品推薦給你。當然不是把所有的他們喜歡的且你沒產生過行為的都推薦給你,而是推薦你最感興趣的 N個產品。根據上面這些描述,我們看到使用 UserCF需要兩步:

  1. 找到與你興趣相似的K個使用者。
  2. 確定你最感興趣的N個物品?

  在第一步中,我們需要去計算你與每個使用者的興趣相似度,然後按相似度降序排列,所對應的前K個使用者就是我們要找的。

  對於使用者u和v我們可以通過如下的Jaccard公式來計算:
wuv=N(u)N(v)N(u)N(v),

或者通過餘弦相似度計算:
wuv=N(u)N(v)N(u)N(v),
計算相似度的時候,為了減少時間複雜度,需要建立一個物品-使用者倒排表。因為當用戶數很大時,直接從資料集很費時間,很多時間浪費在了計算 N(u)N(v)=0上。另外,兩個使用者對冷門物品採取過同樣的行為更能說明他們興趣的相似度。所以書中指出 John S. Breese 在論文中提出如下計算相似度的公式:

wuv=iN(u)N(v)1ln(1+N(i))N(u)
N(v)
.

這個公式通過1ln(1+N(i)) 懲罰了使用者u和使用者v共同興趣列表中熱門物品對他們相似度的影響。
這裡用字典格式來儲存資料集和相似度,如:
train={'user1':['a', 'b', 'c'], 'user2':['a','b'],....,'userN':[...]}]
W={('user1', 'user2'): w12, ('user1', 'user3'): w13,.....}

  下面是計算相似度的程式碼

def UserSimilarity2(train, flag=1):
    item_users = dict()  
    for u, item in train.items():
        for i in item:
            if i not in item_users:
                item_users[i] = set()  # 生成一個集合
            item_users[i].add(u)
    C = dict()  # C為分子
    N = dict()  # N[u]表示使用者u喜歡的物品個數
    ""
    #使用者數很大時計算C耗時
    for u in train.keys():
        for v in train.keys():
            if u==v:
                continue
            else:
                if len(set(train[u] ) & set(train[v]))!=0:
                    C[(u, v)]=len(set(train[u] ) & set(train[v]))
    for u in train.keys():
        N[u]=len(train[u])
    print C
    print N
    ""
    for item, users in item_users.items():

        for u in users:
            if u not in N:
                N[u] = 1  # 如果使用者u不在字典N裡面,先建立
            else:
                N[u] += 1
            for v in users:
                if u != v:
                    if flag == 0:  # 修正前
                        if (u, v) not in C:
                            C[(u, v)] = 1
                        else:
                            C[(u, v)] += 1
                    elif flag == 1: # 修正後
                        if (u, v) not in C:
                            C[(u, v)] = 1 / log(1 + len(users))
                        else:
                            C[(u, v)] += 1 / log(1 + len(users))
    W = dict()
    for uv in C.keys():
        # pdb.set_trace()
        u = uv[0]
        v = uv[1]
        if u not in W:
            W[u] = set()
        # 新增與使用者u相關的使用者v,第二個意思是他們的權重Wuv
        W[u].add((v, C[uv] / sqrt(N[u] * N[v])))
    return W

這個程式碼中 flag=0對應的是第一個沒有修正的相似度計算公式,flag=1對應的就是修正後的相似度計算公式。
計算出相似度後,下來要做的就是找出與你相似度高的前K個使用者,然後去把他們喜歡的你沒發生過行為的物品(記為Itemj)卻很感興趣的物品推薦給你。

  第二步和第一步的思路差不多,定性問題定量化。計算你對Itemj的感興趣程度,然後降序排列,選出感興趣程度最高的前N個推薦給你。
這裡,感興趣程度是用下面的公式來度量的:

p(u,i)=vS(u,K)N(i)wuvrvi
S(u,K)就是那K個使用者的集合,N(i)是對物品i有過行為的使用者集合,wuv就不說了,rvi 是使用者v對i物品的興趣。簡單的說,v對i產生了行為rvi就是1,沒產生就是0,當然這裡的rvi只有這兩種值。

  下面是實現推薦的程式碼:

def Recommend(user, train, W, N, K=10):
    rank = dict()
    interacted_items = train[user]
    for v, wuv in sorted(W[user], key=lambda x: x[1], reverse=True)[0:K]:  # 相似度最大的K個使用者
        for i in train[v]:  # v產生過行為的物品
            if i not in interacted_items:  
                if i not in rank:
                    rank[i] = wuv * 1
                else:
                    rank[i] += wuv * 1

    rank = sorted(rank.items(), key=lambda x: x[1], reverse=True)
    rank = rank[:N]
    return rank

這裡的K是一個很關鍵的引數,K的選取會影響最後的推薦結果。這本書中K對TopN推薦的好壞,是用這幾個指標來衡量的:準確率,召回率,覆蓋率 和 流行度。
記U為系統的使用者集合,R(u)為訓練集上得出的推薦列表, T(u)為測試集上的行為列表。
推薦結果的準確率可定義為:

Precision=uU|R(u)T(u)|uU|R(u)|
召回率被定義為
Recall=uU|R(u)T(u)|uU|T(u)|
def PrecisionRecall(train, test, N):
    hit = 0 #兩者的分子
    n_precision=0 # 準確率的分母
    n_recall = 0 #召回率的分母
    W = UserSimilarity2(train)
    for user in train.keys():
        try:  # 計算分子分母
            te_user_items = test[user]
            recomRank = Recommend(user, train, W, N)
            for recom_item, w in recomRank:
                if recom_item in te_user_items:
                    hit += 1
            n_precision += N
            n_recall+=len(te_user_items)
        except:
            pass
    return [hit / (1.0*n_precision), hit/(1.0*n_recall)]

覆蓋率的計算公式為:

Coverage=uUR(u)I
這裡I所有物品的集合。那麼覆蓋率就是推薦出去的物品佔總物品的比率,商家們會關心的指標。下面是計算覆蓋率的程式碼:
def Coverage(train, N):
    recommend_items = set() #分子
    all_items = set() #分母
    W = UserSimilarity2(train)
    for user in train.keys():
        for item in train[user]:
            all_items.add(item)
        rank = Recommend(user, train, W, N)
        for item in rank[0]:
            recommend_items.add(item)
    return len(recommend_items) / (len(all_items) * 1.0)

這本書上,目前看的這一章,我沒有看到流行度的具體定義,但從給的程式碼看,似乎平均流行度是這麼定義的:

p=

相關推薦

基於協同過濾演算法

  兩個月前我開始學習機器學習,這兩個月期間學習了一些基礎的機器學習演算法及其Python實現。這周我剛開始學習《推薦系統實踐》這本書,並打算以後定期將自己的學習情況做個簡單的總結。這份總結是我這個部落格上的第一篇文章。這周的學習的主要內容是基於鄰域的協同過濾演

《推薦系統實踐》——基於物品的協同過濾演算法程式碼實現

一、基礎演算法 基於物品的協同過濾演算法(簡稱ItemCF)給使用者推薦那些和他們之前喜歡的物品相似的物品。不過ItemCF不是利用物品的內容計算物品之間相似度,而是利用使用者的行為記錄。 該演算法認為,物品A和物品B具有很大的相似度是因為喜歡物品A的使用者

推薦系統實踐----基於使用者的協同過濾演算法python程式碼實現書中案例

本文參考項亮的《推薦系統實踐》中基於使用者的協同過濾演算法內容。因其中程式碼實現部分只有片段,又因本人初學,對python還不是很精通,難免頭大。故自己實現了其中的程式碼,將整個過程走了一遍。 1. 過程簡述 a. 首先我們因該先找到和目標使用者興趣相似的使用者集合。簡單來

基於Spark MLlib平臺和基於模型的協同過濾演算法的電影推薦系統 協同過濾演算法概述&&基於模型的協同過濾演算法思想演算法模型和結構待補充

本文暫時分為三部分: (一)基於Spark MLlib平臺和基於模型的協同過濾演算法的電影推薦系統(一)            → 協同過濾演算法概述&&基於模型的協同過濾的演算法思想 (二)基於Spark MLlib平臺和基於模型的協同過濾演算法的電影推薦

人工智慧演算法協同過濾演算法

這是本人第一篇介紹人工智慧演算法的部落格。之前寫的大部分部落格都是為了解決具體問題或者解決問題中的思考。這次想籠統而又概括的去總結一些自己學習的演算法。 廢話少說,進入正題。 一、什麼是協同過濾演算法? 協同過濾演算法,英文Collaborative Filtering。這個名詞的意思有

基於使用者的協同過濾演算法實現的商品推薦系統

基於使用者的協同過濾演算法實現的商品推薦系統   專案介紹 商品推薦是針對使用者面對海量的商品資訊而不知從何下手的一種解決方案,它可以根據使用者的喜好,年齡,點選量,購買量以及各種購買行為來為使用者推薦合適的商品。在本專案中採用的是基於使用者的協同過濾的推薦演算法來實現

3、前奏之基於物品的協同過濾演算法:ItemsCF

兩步走: 計算物品間的相似度 根據1和使用者歷史行為給使用者生成推薦列表 一、計算物品間的相似度 1、相似度演算法           喜歡物品i的使用者中有多少比例的使用者也喜歡j;問題:j存在熱門商品問題,因為j很流行,喜

基於使用者的協同過濾演算法

基本思想 俗話說“物以類聚、人以群分”,拿看電影這個例子來說,如果你喜歡《蝙蝠俠》、《碟中諜》、《星際穿越》、《原始碼》等電影,另外有個人也都喜歡這些電影,而且他還喜歡《鋼鐵俠》,則很有可能你也喜歡《鋼鐵俠》這部電影。 所以說,當一個使用者 A 需要個性化推薦時

基於使用者的協同過濾演算法(Java實現或R語言實現

  協同過濾的步驟是:   建立資料模型 —> 使用者相似度演算法 —>使用者近鄰演算法 —>推薦演算法。   基於使用者的協同過濾演算法在Mahout庫中已經模組化了,通過4個模組進行統一的方法呼叫。首先,建立資料模型(DataModel

基於改進的協同過濾演算法的使用者評分預測模型

目標:精確預測某目標使用者對目標電影M的評分值。 步驟:1得到與目標電影M最相似的K個電影集合ci。 2.基於ci,計算評論過m電影且與目標使用者最相似的k2個使用者 3.將與目標使用者最相似的k2個使用者對目標電影M的評分值加權平均值作為目標使用者對目標電影評分預測值。

Mahout基於使用者的協同過濾演算法的例子

每行測試資料分別標識使用者id(uid),物品id(itemid),評分(rating),評分時間(time) 3464,2502,3,973282547 3464,3160,2,973282494 3464,2505,3,967175070 3464,

基於近鄰使用者協同過濾演算法的音樂推薦系統

0. 摘 要 基於近鄰使用者的協同過濾音樂推薦系統,主要是將與目標使用者有相同行為和興趣愛好的使用者,形成一個最近鄰的推薦群組,從最近鄰推薦群組中產生最終的目標使用者推薦列表。該推薦系統通過網路爬蟲獲取蝦米音樂網站真實未脫敏使用者的行為資訊,採用餘弦相似度作為

推薦系統學習--基於item的協同過濾演算法及python實現

轉載地址:http://blog.csdn.net/gamer_gyt/article/details/51346159 1:協同過濾演算法簡介 2:協同過濾演算法的核心 3:協同過濾演算法的應用方式 4:基於使用者的協同過濾演算法實現

基於cnn的影象二分類演算法

本演算法是基於tensorflow,使用python語言進行的一種影象分類演算法,參考於谷歌的mnist手寫識別,包括以下幾個模組:影象讀取,影象處理,影象增強。卷積神經網路部分包括:卷積層1,匯合層1(部分文獻也有叫池化層的),卷積層2,匯合層2,全連線層1,全連線層2,共

spark基於使用者的協同過濾演算法與坑點,提交job

承接上文: http://blog.csdn.net/wangqi880/article/details/52875524 對了,每臺機子的防火牆要關閉哈,不然spark叢集啟動不起來 前一次,已經把spark的分散式叢集佈置好了,今天寫一個簡單的案例來執

點雲分割之基於邊界的分割演算法

基於邊界的點雲分割演算法通過檢測區域邊界得到分割塊。主要演算法有: 一、通過點雲強度的劇烈變化得到點雲邊界; 二、計算邊界梯度,計算點雲表面的法矢方向梯度變化以及3D線匹配; 三、對於距離影象的掃描線分割演算法,但不適用於密度不均勻的點雲資料。 四、通過

基於使用者的協同過濾演算法的電影推薦系統

上一篇講解了推薦演算法的分類,這裡電影推薦系統具體分析一下 第一步:建立使用者電影矩陣模型         如表1所示,協同過濾演算法的輸入資料通常表示為一個m*n的使用者評價矩陣Matrix,m是使

初探推薦演算法基於使用者的協同過濾演算法

基於使用者的協同過濾演算法 一、基本思路 在一個推薦場景,你需要給使用者推薦一些商品,基本思路是: (1)找到和目標使用者興趣相似的使用者集合。 (2)找到這個集合中的使用者喜歡的,且目標使用者沒有聽說過的物品推薦給目標使用者。 二、相似度度量

影象配準】基於灰度的模板匹配演算法:MAD、SAD、SSD、MSD、NCC、SSDA、SATD演算法

簡介:        本文主要介紹幾種基於灰度的影象匹配演算法:平均絕對差演算法(MAD)、絕對誤差和演算法(SAD)、誤差平方和演算法(SSD)、平均誤差平方和演算法(MSD)、歸一化積相關演算法(NCC)、序貫相似性檢測演算法(SSDA)、hadamard變換演算法(

[推薦演算法]UserCF,基於使用者的協同過濾演算法

UserCF:UserCollaborationFilter,基於使用者的協同過濾 演算法核心思想:在一個線上推薦系統中,當用戶A需要個性化推薦時,可以先找到和他有相似興趣的其它使用者,然後把那些使用者喜歡的、而使用者A沒有聽說過的物品推薦給A,這種方法稱為基於使用者的協