[機器學習] 推薦系統之協同過濾算法(轉)

[機器學習]推薦系統之協同過濾算法

在現今的推薦技術和算法中,最被大家廣泛認可和采用的就是基于協同過濾的推薦方法。本文將帶你深入了解協同過濾的秘密。下面直接進入正題.

1. 什么是推薦算法

推薦算法最早在1992年就提出來了,但是火起來實際上是最近這些年的事情,因為互聯網的爆發,有了更大的數據量可以供我們使用,推薦算法才有了很大的用武之地。

最開始,所以我們在網上找資料,都是進yahoo,然后分門別類的點進去,找到你想要的東西,這是一個人工過程,到后來,我們用google,直接搜索自己需要的內容,這些都可以比較精準的找到你想要的東西,但是,如果我自己都不知道自己要找什么腫么辦?最典型的例子就是,如果我打開豆瓣找電影,或者我去買說,我實際上不知道我想要買什么或者看什么,這時候推薦系統就可以派上用場了。

2. 推薦算法的條件

現在的各種各樣的推薦算法,但是不管怎么樣,都繞不開幾個條件,這是推薦的基本條件

1.根據和你共同喜好的人來給你推薦?
2.根據你喜歡的物品找出和它相似的來給你推薦?
3.根據你給出的關鍵字來給你推薦,這實際上就退化成搜索算法了?
4.根據上面的幾種條件組合起來給你推薦

3. 推薦算法分類

推薦算法大致可以分為三類:

3.1 基于內容的推薦算法

基于內容的推薦算法,原理是用戶喜歡和自己關注過的Item在內容上類似的Item,比如你看了哈利波特I,基于內容的推薦算法發現哈利波特II-VI,與你以前觀看的在內容上面(共有很多關鍵詞)有很大關聯性,就把后者推薦給你,這種方法可以避免Item的冷啟動問題(冷啟動:如果一個Item從沒有被關注過,其他推薦算法則很少會去推薦,但是基于內容的推薦算法可以分析Item之間的關系,實現推薦),弊端在于推薦的Item可能會重復,典型的就是新聞推薦,如果你看了一則關于MH370的新聞,很可能推薦的新聞和你瀏覽過的,內容一致;另外一個弊端則是對于一些多媒體的推薦(比如音樂、電影、圖片等)由于很難提內容特征,則很難進行推薦,一種解決方式則是人工給這些Item打標簽。

3.2 協同過濾推薦算法

協同過濾算法,原理是用戶喜歡那些具有相似興趣的用戶喜歡過的商品,比如你的朋友喜歡電影哈利波特I,那么就會推薦給你,這是最簡單的基于用戶的協同過濾算法(user-based collaboratIve filtering),還有一種是基于Item的協同過濾算法(item-based collaborative filtering),這兩種方法都是將用戶的所有數據讀入到內存中進行運算的,因此成為Memory-based Collaborative Filtering,另一種則是Model-based collaborative filtering,包括Aspect Model,pLSA,LDA,聚類,SVD,Matrix Factorization等,這種方法訓練過程比較長,但是訓練完成后,推薦過程比較快。

3.3基于知識的推薦算法。

最后一種方法是基于知識的推薦算法,也有人將這種方法歸為基于內容的推薦,這種方法比較典型的是構建領域本體,或者是建立一定的規則,進行推薦。 混合推薦算法,則會融合以上方法,以加權或者串聯、并聯等方式盡心融合。 當然,推薦系統還包括很多方法,其實機器學習或者數據挖掘里面的方法,很多都可以應用在推薦系統中,比如說LR、GBDT、RF(這三種方法在一些電商推薦里面經常用到),社交網絡里面的圖結構等,都可以說是推薦方法。

今天這篇文章要講的基于用戶的協同過濾算法.

3 什么是協同過濾

協同過濾是利用集體智慧的一個典型方法。要理解什么是協同過濾 (Collaborative Filtering, 簡稱 CF),首先想一個簡單的問題,如果你現在想看個電影,但你不知道具體看哪部,你會怎么做?大部分的人會問問周圍的朋友,看看最近有什么好看的電影推薦,而我們一般更傾向于從口味比較類似的朋友那里得到推薦。這就是協同過濾的核心思想。

換句話說,就是借鑒和你相關人群的觀點來進行推薦,很好理解。

4 協同過濾的實現

要實現協同過濾的推薦算法,要進行以下三個步驟:

4.1)收集數據

4.2)找到相似用戶和物品

4.3進行推薦

4.1 收集數據

這里的數據指的都是用戶的歷史行為數據,比如用戶的購買歷史,關注,收藏行為,或者發表了某些評論,給某個物品打了多少分等等,這些都可以用來作為數據供推薦算法使用,服務于推薦算法。需要特別指出的在于,不同的數據準確性不同,粒度也不同,在使用時需要考慮到噪音所帶來的影響。

4.2找到相似用戶和物品

這一步也很簡單,其實就是計算用戶間以及物品間的相似度。以下是幾種計算相似度的方法:?
這里寫圖片描述

4.3 進行推薦

在知道了如何計算相似度后,就可以進行推薦了。

在協同過濾中,有兩種主流方法:

1)基于用戶的協同過濾

2)基于物品的協同過濾

具體怎么來闡述他們的原理呢,看個圖大家就明白了

基于用戶的 CF 的基本思想相當簡單,基于用戶對物品的偏好找到相鄰鄰居用戶,然后將鄰居用戶喜歡的推薦給當前用戶。計算上,就是將一個用戶對所有物品的偏好作為一個向量來計算用戶之間的相似度,找到 K 鄰居后,根據鄰居的相似度權重以及他們對物品的偏好,預測當前用戶沒有偏好的未涉及物品,計算得到一個排序的物品列表作為推薦。 下圖給出了一個例子,對于用戶 A,根據用戶的歷史偏好,這里只計算得到一個鄰居 - 用戶 C,然后將用戶 C 喜歡的物品 D 推薦給用戶 A。?
這里寫圖片描述?
基于物品的 CF 的原理和基于用戶的 CF 類似,只是在計算鄰居時采用物品本身,而不是從用戶的角度,即基于用戶對物品的偏好找到相似的物品,然后根據用戶的歷史偏好,推薦相似的物品給他。從計算的角度看,就是將所有用戶對某個物品的偏好作為一個向量來計算物品之間的相似度,得到物品的相似物品后,根據用戶歷史的偏好預測當前用戶還沒有表示偏好的物品,計算得到一個排序的物品列表作為推薦。下圖給出了一個例子,對于物品 A,根據所有用戶的歷史偏好,喜歡物品 A 的用戶都喜歡物品 C,得出物品 A 和物品 C 比較相似,而用戶 C 喜歡物品 A,那么可以推斷出用戶 C 可能也喜歡物品 C。?
這里寫圖片描述

算法存在的問題

這個算法實現起來也比較簡單,但是在實際應用中有時候也會有問題的。

比如一些非常流行的商品可能很多人都喜歡,這種商品推薦給你就沒什么意義了,所以計算的時候需要對這種商品加一個權重或者把這種商品完全去掉也行。

再有,對于一些通用的東西,比如買書的時候的工具書,如現代漢語詞典,新華字典神馬的,通用性太強了,推薦也沒什么必要了。

適用場景

  在非社交網絡的網站中,內容內在的聯系是很重要的推薦原則,它比基于相似用戶的推薦原則更加有效。比如在購書網站上,當你看一本書的時候,推薦引擎會給你推薦相關的書籍,這個推薦的重要性遠遠超過了網站首頁對該用戶的綜合推薦。可以看到,在這種情況下,Item CF 的推薦成為了引導用戶瀏覽的重要手段。同時 Item CF 便于為推薦做出解釋,在一個非社交網絡的網站中,給某個用戶推薦一本書,同時給出的解釋是某某和你有相似興趣的人也看了這本書,這很難讓用戶信服,因為用戶可能根本不認識那個人;但如果解釋說是因為這本書和你以前看的某本書相似,用戶可能就覺得合理而采納了此推薦。

具體實現

# -*- coding=utf-8 -*-import math
import sys
from texttable import Texttable # # 使用 |A&B|/sqrt(|A || B |)計算余弦距離 # # # def calcCosDistSpe(user1,user2): avg_x=0.0 avg_y=0.0 for key in user1: avg_x+=key[1] avg_x=avg_x/len(user1) for key in user2: avg_y+=key[1] avg_y=avg_y/len(user2) u1_u2=0.0 for key1 in user1: for key2 in user2: if key1[1] > avg_x and key2[1]>avg_y and key1[0]==key2[0]: u1_u2+=1 u1u2=len(user1)*len(user2)*1.0 sx_sy=u1_u2/math.sqrt(u1u2) return sx_sy # # 計算余弦距離 # # def calcCosDist(user1,user2): sum_x=0.0 sum_y=0.0 sum_xy=0.0 for key1 in user1: for key2 in user2: if key1[0]==key2[0] : sum_xy+=key1[1]*key2[1] sum_y+=key2[1]*key2[1] sum_x+=key1[1]*key1[1] if sum_xy == 0.0 : return 0 sx_sy=math.sqrt(sum_x*sum_y) return sum_xy/sx_sy # # # 相似余弦距離 # # # def calcSimlaryCosDist(user1,user2): sum_x=0.0 sum_y=0.0 sum_xy=0.0 avg_x=0.0 avg_y=0.0 for key in user1: avg_x+=key[1] avg_x=avg_x/len(user1) for key in user2: avg_y+=key[1] avg_y=avg_y/len(user2) for key1 in user1: for key2 in user2: if key1[0]==key2[0] : sum_xy+=(key1[1]-avg_x)*(key2[1]-avg_y) sum_y+=(key2[1]-avg_y)*(key2[1]-avg_y) sum_x+=(key1[1]-avg_x)*(key1[1]-avg_x) if sum_xy == 0.0 : return 0 sx_sy=math.sqrt(sum_x*sum_y) return sum_xy/sx_sy # # 讀取文件 # # def readFile(file_name): contents_lines=[] f=open(file_name,"r") contents_lines=f.readlines() f.close() return contents_lines # # 解壓rating信息,格式:用戶id\t硬盤id\t用戶rating\t時間 # 輸入:數據集合 # 輸出:已經解壓的排名信息 # def getRatingInformation(ratings): rates=[] for line in ratings: rate=line.split("\t") rates.append([int(rate[0]),int(rate[1]),int(rate[2])]) return rates # # 生成用戶評分的數據結構 # # 輸入:所以數據 [[2,1,5],[2,4,2]...] # 輸出:1.用戶打分字典 2.電影字典 # 使用字典,key是用戶id,value是用戶對電影的評價, # rate_dic[2]=[(1,5),(4,2)].... 表示用戶2對電影1的評分是5,對電影4的評分是2 # def createUserRankDic(rates): user_rate_dic={} item_to_user={} for i in rates: user_rank=(i[1],i[2]) if i[0] in user_rate_dic: user_rate_dic[i[0]].append(user_rank) else: user_rate_dic[i[0]]=[user_rank] if i[1] in item_to_user: item_to_user[i[1]].append(i[0]) else: item_to_user[i[1]]=[i[0]] return user_rate_dic,item_to_user # # 計算與指定用戶最相近的鄰居 # 輸入:指定用戶ID,所以用戶數據,所以物品數據 # 輸出:與指定用戶最相鄰的鄰居列表 # def calcNearestNeighbor(userid,users_dic,item_dic): neighbors=[] #neighbors.append(userid) for item in users_dic[userid]: for neighbor in item_dic[item[0]]: if neighbor != userid and neighbor not in neighbors: neighbors.append(neighbor) neighbors_dist=[] for neighbor in neighbors: dist=calcSimlaryCosDist(users_dic[userid],users_dic[neighbor]) #calcSimlaryCosDist calcCosDist calcCosDistSpe neighbors_dist.append([dist,neighbor]) neighbors_dist.sort(reverse=True) #print neighbors_dist return neighbors_dist # # 使用UserFC進行推薦 # 輸入:文件名,用戶ID,鄰居數量 # 輸出:推薦的電影ID,輸入用戶的電影列表,電影對應用戶的反序表,鄰居列表 # def recommendByUserFC(file_name,userid,k=5): #讀取文件數據 test_contents=readFile(file_name) #文件數據格式化成二維數組 List[[用戶id,電影id,電影評分]...] test_rates=getRatingInformation(test_contents) #格式化成字典數據 # 1.用戶字典:dic[用戶id]=[(電影id,電影評分)...] # 2.電影字典:dic[電影id]=[用戶id1,用戶id2...] test_dic,test_item_to_user=createUserRankDic(test_rates) #尋找鄰居 neighbors=calcNearestNeighbor(userid,test_dic,test_item_to_user)[:k] recommend_dic={} for neighbor in neighbors: neighbor_user_id=neighbor[1] movies=test_dic[neighbor_user_id] for movie in movies: #print movie if movie[0] not in recommend_dic: recommend_dic[movie[0]]=neighbor[0] else: recommend_dic[movie[0]]+=neighbor[0] #print len(recommend_dic) #建立推薦列表 recommend_list=[] for key in recommend_dic: #print key recommend_list.append([recommend_dic[key],key]) recommend_list.sort(reverse=True) #print recommend_list user_movies = [ i[0] for i in test_dic[userid]] return [i[1] for i in recommend_list],user_movies,test_item_to_user,neighbors # # # 獲取電影的列表 # # # def getMoviesList(file_name): 

轉載于:https://www.cnblogs.com/lixiaozhi/p/8432080.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/252370.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/252370.shtml
英文地址,請注明出處:http://en.pswp.cn/news/252370.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

BundleFusion代碼框架講解

背景:前面用了幾篇文章來記錄和總結了,我在研究bundlefusion過程中遇到的一些問題以及解決方法,本來想實現給bundlefusion輸入先驗軌跡,然后讓其根據給定的軌跡進行重建,這樣即便在環境比較惡劣的情況下,也…

BundlePhobia

1、BundlePhobia用于分析npm package的依賴、bundle后的大小、下載速度預估等等,幫助你在引用一個package之前了解引入該package的代價。 2、也可以將項目的package.json文件上傳,BundlePhobia會幫你評估項目中所有包的大小和加載速度。

VFL演示樣例

VFL演示樣例 上篇文章向大家介紹了VFL的基本的語法點,假設對下面演示樣例不熟的童鞋,能夠前去參考。廢話不多說。我們直接來看演示樣例。演示樣例一 將五個大小同樣、顏色不同的view排成一行,view間的間隔為15px,第一個view的間隔與屏幕的左邊…

evo實用指令指南

下面這篇文章中有比較具體的關于evo的安裝以及使用的介紹,其中一點很重要,就是可以把euroc形式的.csv的軌跡格式轉換為tum格式的軌跡。 https://zhuanlan.zhihu.com/p/88223106#single evo_traj tum orb_slam2_tum.txt --reftum_groundtruth.txt -p --pl…

MailUtils

/***包名:com.thinkgem.jeesite.test*描述:package com.thinkgem.jeesite.test;*/ package com.thinkgem.jeesite.test;import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.regex.Matcher; import java.u…

ES6遍歷對象

遍歷對象 E S 6 一共有 5 種方法可以遍歷對象的屬性 。 for ... in for . . . in 循環遍歷對象自身的和繼承的可枚舉屬性(不含 Symbol 屬性)。 Object.keys(obj)Object . keys 返回 一個數組,包括對象自身的(不含繼承的 &#xff…

SpringMvc中ModelAndView模型的應用

/** * 目標方法的返回值可以是 ModelAndView 類型。 * 其中可以包含視圖和模型信息 * SpringMVC 會把 ModelAndView 的 model 中數據放入到 request 域對象中. * return */ RequestMapping("/testModelAndView") public ModelAndView testModelAndView(){ String v…

ubuntu16.04 + ros-kinetic 配置cartographer

其實一直以來都感覺純視覺SLAM很難落地產品,所以一直在找機會學習激光slam,之前也在深藍學院上買了一個激光salm的課程,慚愧,至今也沒開始學呢,年底之前,我想工作之余研究一下激光slam和ros,我感覺這兩個東…

virtualbox中安裝ubuntu

為什么80%的碼農都做不了架構師?>>> virtualboxubuntu 安裝virtualbox,當前版本是6.0.4下載ubuntu安裝盤,建議lubuntu,鏈接是http://mirrors.ustc.edu.cn/ubuntu-cdimage/lubuntu/releases/18.04.2/release/lubuntu-1…

面向對象重寫(override)與重載(overload)區別

一、重寫(override) override是重寫(覆蓋)了一個方法,以實現不同的功能。一般是用于子類在繼承父類時,重寫(重新實現)父類中的方法。 重寫(覆蓋)的規則&#…

cartographer學習筆記--如何保存cartagrapher_ros建好的地圖

今天開始跟著網友大佬學習cartographer. 1. 如何保存cartographer的地圖數據 在運行cartographer過程中可以隨時保存建好的地圖,步驟如下: 首先是重新打開一個terminal, 如果你沒有將你的cartographer_ros下的setup.bash文件寫入到.bashrc中&#xff…

Java微信公眾號開發(五)—— SVN版本控制工具

1 作用 兩個疑問: 什么是版本控制?為什么要用版本控制工具?作用: 受保護受約束合作開發中,版本控制工具更重要的作用就是讓開發者更好地協作,每個人的代碼既能互相調用,來共同完成一個較大的功…

Linux之《荒島余生》(二)CPU篇

為什么80%的碼農都做不了架構師?>>> 溫馨提示,動圖已壓縮,流量黨放心查看。CPU方面內容不多,我們順便學點命令。本篇是《荒島余生》系列第二篇,垂直觀測CPU。其余參見: Linux之《荒島余生》&am…

PTA 06-圖2 Saving James Bond - Easy Version (25分)

題目地址 https://pta.patest.cn/pta/test/16/exam/4/question/672 5-10 Saving James Bond - Easy Version (25分) This time let us consider the situation in the movie "Live and Let Die" in which James Bond, the worlds most famous spy, was captured by…

Ubuntu16.04上安裝kitti2bag

kitti2bag是一個可以將kitti數據集轉換為bag文件的工具,可以直接通過pip進行安裝。由于kitti2bag中使用到ros,所以安裝時你使用的python版本應該是2.7的因為ros只有在Python2.7時才能正常工作。比如說我,我安裝了conda,在conda中安…

Nginx之windows下搭建

去nginx.org下載nginx 以nginx-1.8.1為例解壓到D盤nginx-1.8.1目錄 假設NGINX_HOME為D:\nginx-1.8.1 3種啟動途徑: 一、雙擊nginx.exe圖標,可見黑窗口一閃而過,啟動完畢。 二、命令行到nginx目錄,輸入nginx啟動。(注&a…

單片機錯誤筆記

記錄下使用單片機過程中的一些錯誤,便于以后查詢: 單片機型號:STC15F2K60S2 晶振:18.432 報錯代碼: *** WARNING L1: UNRESOLVED EXTERNAL SYMBOLSYMBOL: REC_DAT1MODULE: .\Objects\usart.obj (USART) …

軟件開發記錄03

今天我完成了軟件設置&#xff0c;預算列表&#xff0c;添加預算的頁面布局。 &#xff08;1&#xff09;軟件設置 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"…

395. Longest Substring with At Least K Repeating Characters

題目要求 Find the length of the longest substring T of a given string (consists of lowercase letters only) such that every character in T appears no less than k times.Example 1:Input: s "aaabb", k 3Output: 3The longest substring is "aaa&qu…

UICollectionView 具體解說學習

UICollectionView 和UITableView非常像,是APPLE公司在iOS 6后推出的用于處理圖片這類UITableView 布局困難的控件,和UITableView 一樣,它也有自己的Datasource和delegate。以下具體說下像這種方式的效果. 首先來看看UICollectionView 的DataSource。protocol UICollectionView…