從原理到策略算法再到架構產品看推薦系統(tǒng)[轉]

作者 | HCY崇遠

01 前言

本文源自于前陣子連續(xù)更新的推薦系統(tǒng)系列,前段時間給朋友整理一個關于推薦系統(tǒng)相關的知識教學體系茄螃,剛好自身業(yè)務中缝驳,預計明年初隨著業(yè)務規(guī)模增長,估摸著又要啟動推薦相關的項目了归苍,所以也是趁機把相關的知識結構梳理了一遍用狱。這這里重新做整理,并額外做了一些增減拼弃,讓整體邏輯會更通順一點夏伊。

整個文章的結構邏輯,先從推薦系統(tǒng)的基礎知識結構講起吻氧,然后由淺入深過渡到幾個推薦策略算法上溺忧,并且為每個推薦策略算法提供一些簡單的入門Spark案例代碼,再從策略過渡到系統(tǒng)層級盯孙,包括數據架構鲁森、策略組合、效果評估等振惰,最終再從上層產品設計的角度去補充整個系統(tǒng)知識結構歌溉。

整體來看,通篇并沒有涉及到特別高深的推薦算法(部分專門講這部分的文章骑晶,只有有一定基礎的朋友才更容易接受痛垛,本文章的邏輯略有不同),大多都是常規(guī)的策略模型透罢,核心在于對整個推薦系統(tǒng)的知識結構進行解構榜晦,讓那些對于推薦系統(tǒng)感興趣的朋友能快速的建立起對于推薦系統(tǒng)的知識體系結構,甚至能夠通過文章中的算法案例羽圃,做簡單的實踐乾胶,從而達到快速入門的目的抖剿。

友情提示:據不完全統(tǒng)計,包含代碼片识窿,通篇大約接近1萬字斩郎,預計閱讀時間?我也不知道喻频,哈哈缩宜,可以當成短篇小說來讀了。

02 推薦系統(tǒng)場景需求

本章節(jié)從場景的需求出發(fā)甥温,試圖來分析推薦系統(tǒng)需求的必須性锻煌,以及很多平臺言必談個性化推薦的現狀。

0.2.1 先從人工智能話題出發(fā)

說推薦系統(tǒng)之前先掰掰人工智能姻蚓,這個詞估計大家能能聽得懂宋梧,畢竟是風口上的名詞,想沒聽過也難狰挡。那么問題來了捂龄,你覺得推薦系統(tǒng)與人工智能有什么關系?

或許大半的人會認為沒有半毛錢的關系加叁,這讓我想到了前幾天周末在知乎上懟的一個問題倦沧,問題的核心就是:“現在大數據都很low了,大家都是去搞人智能了”它匕。

這典型就是對于人工智能定義認知的問題展融,個人認為人工智能就是一個偏業(yè)務的定義,多維度多學科交叉的概念豫柬,壓根兒就不好以技術維度去對比去評判愈污。其核心的三要素就是:算法、計算能力以及數據轮傍。

圍繞大量的基礎數據暂雹,對基礎數據進行特征處理,然后構建有用的業(yè)務算法模型创夜,然后基于分布式的基礎架構計算能力杭跪,將算法模型的用于實際的生產環(huán)境,以機器替代人工的作業(yè)驰吓,以提升效果與效率涧尿,達到機器智能化的目標。

那再回到推薦系統(tǒng)的話題檬贰,在過去傳統(tǒng)的門戶網站或者其他領域姑廉,也是有推薦場景的,不過大部分都是基于編輯或者運營手動進行配置推送翁涤,隨著對數據桥言、對算法模型的進一步應用萌踱,才逐漸有算法機器替代人工進行推薦,并且達到諸如“千人千面”号阿、“個性化”推薦的效果并鸵。

所以,追究其本質扔涧,其實也是算法模型+計算過程+基礎數據的流程园担,并且最終達到了機器自動化、智能化的效果枯夜,從廣義的角度來說弯汰,或許復雜一些的推薦系統(tǒng)或許也能納入人工智能的范疇了(真心怕那種一說到人工智能=神經網絡的選手)。

0.2.2 推薦與檢索兩種信息獲取的方式

說到推薦系統(tǒng)湖雹,就不得不說一下搜索引擎蝙泼。不管是搜索也好、推薦也好劝枣,他們都是信息獲取的一種機制,核心區(qū)別在于主動與被動织鲸。

搜索引擎是典型的主動觸發(fā)的形態(tài)舔腾,即用戶已經有明確的信息獲取意圖,渴望得到自身既定的目標信息搂擦,讓后通過搜索規(guī)則進行最終信息的獲取稳诚。

比如,你好奇什么是人工智能瀑踢,那么你就會用諸如谷歌扳还、或者國產大百度去搜索,然后獲取到相關網頁橱夭,去點擊查看氨距,最終完成你了解人工智能這個信息獲取的目的。這就是檢索的機制棘劣,你先要告訴系統(tǒng)你的意圖俏让,然后在給你篩選你要的信息。

而推薦系統(tǒng)則大大的不同茬暇,它是一種系統(tǒng)主動的行為首昔,對于用戶來說是一個被動的行為,被動的接受系統(tǒng)推送過來的信息糙俗。那這樣強扭是不是很尷尬呢勒奇?怎么有這么SHA叉的機制?

其實不是的巧骚,尷尬的是推的不對赊颠,東西推對了就尷尬了格二,比如你正在瀏覽一個信息,正在愁這個信息還沒解決你的問題的時候巨税,系統(tǒng)啪丟給你幾個新增的信息蟋定,說這個幾個信息可能能解決的問題,你一看我湊草添,這正是我要的驶兜,感謝萬能的推薦系統(tǒng)!

所以远寸,推薦核心解決的還是用戶額外信息獲取的問題抄淑,以及提升用戶的進一步轉化,停留時間的延長(只要停留時間延長驰后,商業(yè)轉化機會就會加大肆资,也是粘性提升的體現),而問題的核心就是要推的準灶芝,推的恰到好處郑原,不然就是反作用。

因為推薦要解決的就是海量信息冗余夜涕,用戶在目的不算很明確的情況犯犁,進一步幫助其確定目標,主動篩選信息的過程女器,推的不好那對于用戶來說就更冗余了酸役。

關于信息的獲取,其實還有一種常見的形態(tài)驾胆,那就是結構化導航涣澡,比如電商平臺的分門別類羅列,門戶網站的結構化頻道信息丧诺。它是通過把信息進行結構化了入桂,構建脈絡結構,幫助你去獲取你要的信息驳阎。不過事格,這個就不在我們的討論范圍內了。

0.2.3 推薦系統(tǒng)的場景

說了這么多篇邏輯理論的東西搞隐,或許很多朋友依然對推薦系統(tǒng)沒有一個很場景化的認知驹愚,比如具體什么場景?具體什么形態(tài)劣纲?

image

這是我在騰訊視頻上截的圖逢捺,這就是典型的視頻推薦場景,我不是鵝廠騰訊視頻業(yè)務的算法工程師癞季,所以我無法回答你他們的推薦機制劫瞳,但我可以告訴你倘潜,當時我的觀看主體是“地球脈動”,結合推薦列表志于,大伙兒可以揣摩一下他的推薦機制涮因。當前觀看的屬性相關?導演關聯性伺绽?我的觀看記錄偏好养泡?從我個人的評估來看,這些因素應該都有奈应。

順帶說一下的就是澜掩,一個完整的好的推薦系統(tǒng),一定不會單純的依賴于某個推薦算法杖挣,雖然這個系列的后面文章中肩榕,我會講一些推薦機制或者算法邏輯,甚至附上簡單的案例代碼惩妇,但還是要提前說一下這個問題株汉。

我們再來看幾個同樣是騰訊系的產品推薦場景:

image

QQ音樂平臺的推薦,分析來看應該跟我當前主頁音樂的風格歌殃、以及我的歷史瀏覽相關乔妈。

image

這是閱文網站的小說小說推薦,即當你瀏覽一本小說時挺份,下面會給這個推薦列表,從其描述以及個人分析來看贮懈,好像與個人的行為相關性會小一些匀泊,應該是基于大盤用戶的瀏覽軌跡做的關聯分析,進而進行關聯推薦朵你。

image

最后是電商平臺的典型案例各聘,即你在瀏覽商品時,一般都有猜你喜歡模塊抡医,并且推薦系統(tǒng)得以大放光彩刻蟹,成為應用領域里典型的應用場景扣汪,還是得益于亞馬遜。當年亞馬遜使用推薦算法幫助其提升了XX(具體多少忘了)的年度利潤,從此一炮而紅膨桥,基本上電商平臺中的推薦系統(tǒng)就成了標配。

0.2.4 推薦系統(tǒng)的一些坑

看了這么多例子蓝角,再結合自己身邊實際的體驗径簿,確實不難發(fā)現,各色各樣的產品俘种、平臺秤标,都在打造自己的推薦產品绝淡,恨不得用戶一直點下去,永不跳出苍姜。鑒于這種情況牢酵,那些尚未為自己產品或者平臺開發(fā)推薦邏輯的,是不是感覺自己少了個推薦系統(tǒng)衙猪,哈哈馍乙。

其實核心還是那句話,推薦本身就是個雙刃劍屈嗤,用的不好只會讓用戶徒增煩惱潘拨,這里所說的好不好,不單純是說準不準的問題饶号,準是前提铁追,即推薦給用戶切身所需肯定是好的,但這還不夠茫船,你還需要在他需要的時候給他推琅束,時機不對、場景不對算谈,即使你推的東西再準涩禀,那也是瞎比推。

所以然眼,即使你覺得你少了個推薦系統(tǒng)艾船,也是需要慎重,或許跟完這個系列會好點高每?正如上面說的屿岂,一些坑還是需要注意的。上面所說的推薦時機以及場景就不再重復了鲸匿。

第一爷怀,好的推薦系統(tǒng)一般情況下很依賴于用戶的行為數據,因為從用戶行為中自然能一窺用戶的一些偏好所在带欢,但實際情況是运授,用戶的行為數據并不是這么容易的,當用戶行為數據不夠的時候乔煞,基于用戶行為的分析結論就是個偽命題吁朦,甚至會把你帶向錯誤的方向。

第二渡贾,用戶的偏好一定是會時間偏移進行轉變的喇完,所以用戶行為的有效性又會是一個問題。

第三,假設這個是新用戶呢锦溪?完全沒有軌跡信息不脯,怎么破。

第四刻诊,實際影響用戶的選擇的因素太多防楷,我們容易陷入主觀臆斷的誤區(qū),綜合性考慮是一個完善推薦系統(tǒng)的必須思考的地方则涯。

第五复局,產品層面的邏輯有時候比底層算法更有效,典型如上面閱文的截圖例子粟判,“喜歡這本書的人也喜歡”亿昏,這就是一種策略,也是一種推薦解釋档礁,可解釋性會提升推薦的可信度角钩,諸如還有一些交互方式、產品形態(tài)都是對推薦轉化有影響的呻澜。

03 推薦系統(tǒng)的基礎知識

基于上面章節(jié)的內容递礼,我們對于推薦系統(tǒng)的常見場景有了一個大概的認知,這個章節(jié)羹幸,我們從推薦系統(tǒng)本身的基礎知識進行拆解脊髓,幫我們從理論上掌握更多關于推薦系統(tǒng)相關的知識。

0.3.1 推薦系統(tǒng)概述

在上個章節(jié)栅受,我們也大致的提到過将硝,需要先明確的一點就是推薦算法或者推薦機制并不嚴格等同推薦系統(tǒng),推薦系統(tǒng)是一個相對復雜的業(yè)務系統(tǒng)屏镊,里頭涉及到數據的處理依疼、架構的構成、推薦的邏輯機制闸衫,反饋數據的回收涛贯、效果的跟蹤诽嘉、AB測試等等蔚出。

并且,很多我們耳熟能詳的推薦算法虫腋,他只是解決的某種特定情況下的推薦機制問題骄酗,而整個系統(tǒng)很多時候是復合了多種算法結果,綜合呈現的一種結果悦冀。但可以肯定的是趋翻,各種理論邏輯、算法機制是構建推薦系統(tǒng)的核心支撐盒蟆,所以踏烙,學習推薦系統(tǒng)师骗,首先學習各種推薦算法并沒有毛病。

推薦算法概述-基于內容屬性相似的推薦

從原始數據依賴的層面來說讨惩,常見的有基于內容屬性的推薦機制辟癌,這種推薦邏輯很簡單,只是單純的依賴物品之間的屬性相似來構建推薦關系荐捻,容易理解黍少,有時間還是有一定效果的,但實際上很多時候會存在這幾種情況处面,導致了這種原始推薦失效厂置。

如果用戶瀏覽當前的物品本身就不是用戶的菜,甚至是一個非優(yōu)質信息(當前主體不可控)魂角,再基于當前物品進行推薦就是個偽命題昵济。

基于上面這條,即使當前主體是用戶的目標或颊,但再推類似主體會造成信息冗余砸紊,即當前主體信息已經解決了用戶的問題。

所以囱挑,由于用戶行為的不可控醉顽,基于內容屬性相似的推薦,風險還是挺高的平挑,這是導致了這種原始直接的機制并不會得到廣泛的推廣游添。但與亂推薦相比,還是有一定正向作用的通熄,畢竟用戶瀏覽的主體是自身選擇的結果唆涝,本身用戶對于其選擇的信息主體是有一定偏好性的。

推薦算法概述-基于用戶畫像的推薦

基于物品本身屬性的推薦唇辨,其實與個性化是沒有半毛錢的關系的廊酣,畢竟推薦候選集只跟物品主體有關,與用戶無關赏枚,就談不上什么個性化了亡驰。

而基于用戶畫像(更多人喜歡用基于用戶標簽)的推薦,則更大程度上依賴于用戶的畫像屬性來推薦饿幅,這就體現了用戶偏好信息凡辱,根據偏好信息來選擇候選集。

這是一種很通用的做法栗恩,并且在大規(guī)模數據集情況下透乾,很多實際的產生過程中喜歡使用這種機制。而用戶的畫像,或者更具體點用戶的興趣標簽如何構建呢乳乌?其實就是依賴用戶累積的行為數據了捧韵,通過行為數據生成用戶的興趣標簽。

這看似是一種相對靠譜的做法汉操,畢竟如果把用戶的愛好都分析清楚了纫版,主動給用戶做推薦不就顯得很個性化了嗎?在實際的場景中客情,首先其弊,并不是所有用戶的行為都足夠用來表征其興趣偏好的,即我們會高估用戶的行為集合膀斋,從而產生有偏差的畫像屬性梭伐,更甚者,如果用戶完全沒有行為怎么辦呢仰担?

其次糊识,通常來說,用戶的興趣愛好是會隨時間遷移而改變的摔蓝,所以赂苗,把我用戶的興趣程度以及其變化并不是一個容易的事情,更何況用戶實際的選擇還會受很多因素影響贮尉,比如拌滋,我當前查找的一個信息并不是我之前掌握的信息,那意味著這些信息偏好在我的歷史軌跡中都體現不出來猜谚,那單純的通過我的興趣去推薦就顯得不靠譜了败砂。

但不管怎么說,根據用戶的偏好來做推薦魏铅,大方向肯定是沒有問題的昌犹。

推薦算法概述-基于協同過濾的推薦

協同過濾,或許了解過推薦系統(tǒng)的的朋友览芳,多多少少都能聽過一些斜姥,并且協同推薦可是作為推薦領域典型案例的存在。

協同過濾同樣不會去研究物品的本身屬性沧竟,甚至也沒有空去構建用戶的畫像標簽铸敏,正如他的名字描述的一樣,他嚴重依靠于用戶的行為以及其周邊用戶的協同行為屯仗。舉個例子搞坝,為一個用戶推薦信息搔谴,那么我只需要參考其周邊用戶在看什么信息魁袜,就給他推薦什么信息就好了。

重點在于,如何限定周邊這個范圍峰弹,比如根據兩個用戶的行為店量,去構建相關關系,從而判斷用戶之間的相似程度鞠呈,把相似用戶的行為推薦給當前用戶融师,這就是協同中典型的基于用戶推薦。

而如果以物品為維度蚁吝,以用戶的購買或者觀看記錄為向量旱爆,則可以構建物品的相似度量,針對于每一個待推薦選項窘茁,用戶的歷史軌跡就是其向量構成怀伦,就可以判斷該用戶歷史的軌跡信息與當前的待選物品的向量相關度了,從而判斷是否要推薦山林,這就是基于物品的協同邏輯房待。

與基于用戶畫像的推薦對比,這種推薦有一定幾率可以發(fā)現新物品驼抹,即并不嚴格依賴用戶的興趣桑孩。舉個例子,假設幾個信息的層級是ABC框冀,并且ABC是層級遞進關系流椒,并不是同一個東西,對于一個用戶來說明也,他掌握的是A镣隶,則意味著他的興趣偏好大多偏向于A,根據興趣標簽诡右,其實是很難推薦這種遞進相關的信息安岂。

但是,如果其他用戶的學習軌跡都是A->B->C這種軌跡帆吻,這意味著ABC三者之間本身就有前后潛在邏輯關系存在的域那,基于協同,即可為該用戶在掌握A的基礎上猜煮,推薦BC的內容次员,這也是基于興趣所做不到的地方。

當前王带,基于協同行為的推薦淑蔚,除了基于物品還有基于用戶,還有其他諸如基于模型的協同愕撰,典型如最近鄰模型刹衫、基于矩陣分解醋寝、以及基于圖關系模型的構建的推薦機制。

推薦算法概述-其他

其實在我們實際的操作過程中带迟,并不會嚴格的依賴于這種條條框框音羞、只要合理即可行,比如我們完全可以把推薦問題轉化為分類問題仓犬,針對于每個待選項嗅绰,他都是YES OR NO的問題,即一個二值分類搀继。

又比如在上一篇我們學習的一個場景窘面,即閱文網站的小說推薦,還記得他的推薦標題嗎叽躯?“喜歡這本書的人還喜歡”民镜,這就是典型的“啤酒與尿布”的解法,即貨架思維险毁,關聯銷售制圈,也是可以作為一種推薦機制而存在的。

在比如微信朋友圈畔况,微信一定是會研究用戶的朋友圈關系的鲸鹦,比如你對哪類朋友點贊、互動行為最多跷跪,它是不是會考慮推薦你欣賞的朋友偏好內容給你馋嗜?畢竟微信是一個典型的熟人社交模型。

所以吵瞻,推薦算法看似重要葛菇,但其實想想又沒有這么重要,很多時候并不是一成不變的橡羞,都要我們根據場景去考慮眯停,最最最重要的是,需要我們用實際效果來選擇機制卿泽,也或許是多種機制共同生效的結果莺债。

0.3.2 相似度量

在我們上面的推薦算法機制中,有個不得不提的操作處理就是各種相似相關度的計算签夭,我們來簡單分享一下幾種相似或者相關度量的方式齐邦。

歐幾里得距離(Euclidean Distance)

最常見的距離度量方式,衡量多維空間中兩點之間的絕對距離第租,要求維度的統(tǒng)一措拇。

明可夫斯基距離(Minkowski Distance)

明氏距離是歐氏距離的擴展,是對多個距離度量公式的概括性的表述(可以看到慎宾,當p=2時丐吓,其實就是歐式距離)浅悉。

曼哈頓距離(Manhattan Distance)

曼哈頓距離來源于城市區(qū)塊距離,是將多個維度上的距離進行求和后的結果汰蜘,即當上面的明氏距離中p=1時得到的距離度量。

//還有其他的一些距離度量之宿,但是都不太常用族操,最常用的依然是歐式距離度量。

向量空間余弦相似度(Cosine Similarity)

余弦相似度用向量空間中兩個向量夾角的余弦值作為衡量兩個個體間差異的大小比被。相比距離度量色难,余弦相似度更加注重兩個向量在方向上的差異,而非距離或長度上等缀。

皮爾森相關系數(Pearson Correlation Coefficient)

即相關分析中的相關系數r枷莉,分別對X和Y基于自身總體標準化后計算空間向量的余弦夾角〕哂兀基于內容的推薦笤妙,還有一點需要注意的就是,對于物品自身屬性噪裕,如果屬性值過少蹲盘,我們需要適當進行擴大維度,如果維度過多膳音,則需要進行降維召衔。

關于降維和升維,都是一個很大的研究方向祭陷,大體上可以說一下幾種常見的方式苍凛。例如降維,我們可以進行維度聚類兵志、主題抽取醇蝴,進一步把相關維度進行合并,進一步減少維度想罕;而對于升維哑蔫,我們可以把維度進行矩陣化,例如假設物品X有A和B兩個維度屬性弧呐,那么我們通過生成AB矩陣的方式闸迷,把維度擴充到AB個維度。

0.3.3 冷啟動問題的解決

所謂冷啟動俘枫,即在推薦系統(tǒng)初期時腥沽,沒有任何用戶與物品的交集信息,即無用戶的行為軌跡鸠蚪,無法通過類似協同或者用戶偏好等方式進行推薦今阳,這種時候师溅,我們就稱推薦系統(tǒng)處于冷啟動狀態(tài)。

這種情況盾舌,我們需要盡快的累積起第一批用戶行為軌跡墓臭。我們可以通過基于內容的推薦,或者做一些其他類似的操作妖谴,快速有效的進行物品推薦窿锉。一段時間后,累積到一定的用戶行為時膝舅,整個系統(tǒng)就能夠正常使用協同過濾等方式進行推薦了嗡载。

但是,針對于新加入的用戶仍稀,或者新加入的物品洼滚,同樣也是出于冷啟動狀態(tài)的,這個時候技潘,我們通過需要對這種物品或者用戶做特殊的處理遥巴。

除了基于內容屬性的推薦,我們還有其他的一些策略用于彌補這種行為數據不足的情況享幽,比如典型的熱度模型挪哄,推薦熱點信息這種行為雖然low,但是從整體的反饋來看琉闪,還是有一定效果的迹炼,此外,還可以根據一些統(tǒng)計學上的結論颠毙,進行基于統(tǒng)計分析結論的推薦斯入。

除此之外,我們也可以通過其他渠道收集用戶的數據蛀蜜,比如用戶注冊的時候所填寫的個人資料刻两,這些都是可以作為推薦的原始依賴數據。

0.3.4 馬太效應

馬太效應或者說長尾效應滴某,即熱者愈熱磅摹,實際舉例來說就是,在實際的購買場景中霎奢,由于你推薦的次數越多户誓,部分優(yōu)質的商品購買或者點擊的次數就越多,形成的用戶購買軌跡就越多幕侠,所以得到的推薦機會就越多帝美,進而產生的推薦也越多,變得越熱晤硕。

隨著不斷迭代悼潭,子子孫孫無窮盡也庇忌,這樣得到推薦的商品就會集中在少部分商品中,而大部分長尾商品是沉寂的舰褪,一個推薦系統(tǒng)如果長時間處于長尾效應中皆疹,造成推薦疲勞,其推薦效果就會減弱占拍。

所以略就,一個好的推薦系統(tǒng),要考慮到適當的挖掘長尾商品刷喜,通過真的個性化残制,把適當的長尾商品送到真正需要他們的人手里立砸,在實際的操作過程中掖疮,我們可以適當的進行熱度降權,從而讓一些中下層的商品得到更多的曝光機會颗祝,當然前提是保證點擊率的情況下浊闪。

另外一個場景會形成馬太效應的是熱度模型,即我們的熱度榜單螺戳,長時間的高居榜首搁宾,一定會獲得更多的點擊,而點擊越多其熱度越高倔幼,但我們的信息是需要保持新鮮度的盖腿,不然點擊率遲早會下架的。

所以损同,我們使用一些機制讓處于頭部的商品或者信息降權翩腐,時間衰減是一個比較通用的做法,即隨著時間的遷移膏燃,其整體熱度會不斷的下降茂卦,至于說下降的方式,速率就看模型的設計了组哩。

0.3.5 AB測試

關于推薦的效果等龙,之前我們說過其核心的考核標準就是點擊率,點擊的越多說明推薦的越準確伶贰,用戶的停留時長也會越長蛛砰,只要把用戶留在平臺中,機會總是會有的黍衙。其實就是一層漏斗嘛暴备?這一層的基數越大,下一層轉換的量就會越高们豌,這也是推薦系統(tǒng)的核心存在意義涯捻。

并且之前也說到過浅妆,一個不好的推薦系統(tǒng)有時間反而會形成反向作用,所以障癌,一個推薦系統(tǒng)的迭代更新至關重要凌外。離線的效果評估一定是要做的,最起碼在離線實驗的階段需要保證當前的效果優(yōu)于線上效果涛浙,才能進行迭代康辑。

但是,實際情況是復雜的轿亮,對于推薦的模型來說疮薇,離線的實驗其實并沒有想象中靠譜,那么我注,就丟到線上去真多真槍的實驗一把按咒,就知道效果了。但是但骨,實際的生產環(huán)境中励七,任何一點轉化波動的影響都是極其嚴重的,誰也不敢拿實際生產開玩笑奔缠。

于是掠抬,就有了AB測試機制的產生,所謂AB測試機制校哎,即將流量分為AB兩類两波,A流量走原始的舊模型,B流量走新模型闷哆,同步測試同步對比腰奋,效果一目了然。

當然阳准,在實際的AB測試流程中氛堕,首先流量是可以自由分配的,一般情況下新模型在最終確認之前流量一定是少量的野蝇,隨著模型逐漸被驗證讼稚,流量比重會逐漸加大,最終確認后流量全部導向新模型绕沈,完成新模型的正式上線锐想。

并且,通常,在實際的環(huán)境中,或許我們會同時有十多個甚至是幾十個新模型在同時實驗芍瑞,每個模型調整的因子都不一樣拘领,最終選擇最適合的因素進行調整藕帜,達到效果最優(yōu)烫罩,這也就是AB測試機制的魅力所在。

所以洽故,打造一個好的AB測試系統(tǒng)贝攒,首先流量是需要可控的,其次模型的迭代上線是需要高度靈活的时甚,最后隘弊,肯定是需要有完整的數據回收、數據分析對比機制存在的荒适。

04 基于內容屬性的推薦策略算法

從這個章節(jié)開始梨熙,我們將從理論進一步過渡到具體的推薦策略算法,我們先從最簡單的基于內容屬性相關的策略算法著手刀诬。

0.4.1 最簡單的推薦機制

如標題咽扇,既然是“最最最簡單”的推薦系統(tǒng),其實也不能說是推薦系統(tǒng)舅列,之前也說了肌割,系統(tǒng)是一個復合的完整系統(tǒng)卧蜓,所以這里說推薦機制可能會更恰當些帐要。結合之前大致陳述的一些推薦機制,最最最簡單的推薦機制弥奸,無疑是基于主體屬性相似或者相關推薦了榨惠,連個性化都說不上,鐵定最最最簡單了盛霎。

說到這赠橙,說不定有些人不愿意干了,既然如此簡陋的推薦機制愤炸,不看也罷期揪。BUT,真的不要小看基于內容相似的推薦规个,存在即合理凤薛。我們在進行信息獲取時,其實本身就是具有一定識別能力的诞仓,這意味著我們最終選擇查看的信息都是經過我們大腦大致思考的結論缤苫,這意味著這些信息是有參考價值的。

并且墅拭,在很多時候活玲,我們是需要同類信息進行我們獲取到的信息進行補全的,完善我們對目標信息的獲取程度∈婧叮基于這個考量镀钓,基于內容屬性的推薦其實是說的過去的。

別不服镀迂,我們來上例子掸宛,還是以前面文章那個騰訊視頻的推薦場景圖為例。

image.gif

圖是在使用騰訊視頻觀看視頻時招拙,我親手截推薦欄位的內容唧瘾,補充一下背景(很重要,請注意):

1 我當時觀看的是應該是《藍色星球第二季》紀錄片

2 我經常在騰訊視頻上看的一般是大片别凤,并且一般是國外的

3 由于是VIP賬號饰序,梓塵兄也經常用這個賬號看動畫片,諸如《小豬佩奇》之類的

4 在騰訊視頻上规哪,紀錄片中求豫,我只看過《地球脈動》和《藍色星球》,并且诉稍,我真不是紀錄片的愛好者蝠嘉,只是喜歡這兩部而已

基于上面我提供的個人行為數據,再結合看這批推薦列表杯巨,不難發(fā)現蚤告,上面有很多的紀錄片,你覺得跟我們當時正在瀏覽的內容有沒有關系服爷?或者你認為我行為記錄中很多紀錄片的記錄杜恰?又或者是我是紀錄片的狂熱者,導致了騰訊視頻給我猛推紀錄片仍源。

所以心褐,連騰訊視頻都會考慮基于當前瀏覽內容的屬性進行推薦(并且是大范圍),你還覺得這種做法十分之LOW嗎笼踩?當然你也可以認為騰訊視頻推的不準逗爹,瞎J吧推,也是可以的嚎于,我也認同掘而,不是非常準(哈哈,《地球脈動》所有我都看過了匾旭,還給我瞎推镣屹,上面給推的沒幾個有欲望去點的,給騰訊視頻推薦的開發(fā)兄弟們打臉了价涝,不好意思)女蜈。

我只想表達的是,這種簡單的推薦機制,在整個推薦系統(tǒng)中真的是不可缺少的部分伪窖,很多時候簡單并不代表無效逸寓,類似上面這種情況,我可以舉出太多有名有姓的實際案例來覆山,說多了沒意義竹伸,所以,咱繼續(xù)簇宽。

0.4.2 過程并沒有這么簡單

從直接的推薦機制來看勋篓,整個實現流程看著真的很簡單,但是在實際的操作過程中魏割,還是有一些東西值得探討以及注意的譬嚣。

第一、首先是钞它,相似計算的過程

之前文章有大致提到過拜银,相似或者相關計算還是有很多可以選擇的,他們每一種都有各自的特點以及適應性遭垛。以相似計算中使用最多的歐式距離與余弦相似為例尼桶,專業(yè)點的說法就是余弦夾角可以有效規(guī)避個體相同認知中不同程度的差異表現,更注重維度之間的差異锯仪,而不注重數值上的差異泵督,而歐式距離則是對個體異常數值會比較敏感。

這意味著卵酪,在我們需要區(qū)分異常樣本時幌蚊,使用距離計算會更恰當谤碳,聚個栗子溃卡,比如電商領域中高價值與低價值用戶的區(qū)分,其實我們核心是想把他們的差異性拉大的蜒简,得以體現出對比瘸羡,這個時候使用余弦就是不合理的。

在回歸到距離上說搓茬,市面上除了歐式距離犹赖,還有好幾種距離度量,諸如馬氏卷仑、曼哈頓距離等等峻村,其實其度量側重都是不一樣的,我們需要結合實際的場景去使用锡凝。還有更偏向于相關度量的皮爾森相關系數等粘昨。

第二、需要解決相似計算中,計算矩陣過大的問題

按照標準流程张肾,假設有1萬個物品芭析,則對于每個物品來說,需要與其他物品計算與其的相似度或者相關度吞瞪,然后再排個序馁启,取TopN形成自身的待推薦列表。那么芍秆,簡單的數學題來了10000*10000=10000萬次計算惯疙,這顯然是不合理的。

所以妖啥,優(yōu)化這個過程是必然的螟碎,關鍵是如何優(yōu)化。核心思想其實就是初篩嘛迹栓!把那些完全沒啥多大鳥關系的直接干掉掉分,省掉計算相似的過程,節(jié)省資源克伊。如何篩選酥郭?一個比較常見的做法是,尋找核心關鍵影響因素愿吹,保證關鍵因素的相關性不从。

比如,在實際的生產操作過程中犁跪,很多時候會通過關鍵屬性是否基本匹配作為判斷依據椿息,或者直接通過搜索構建進行檢索初篩,把大致相關的先過濾一遍坷衍,通過這種簡單而粗暴的方式寝优,其實已經能把大部分相關度很低的候選集給過濾掉,對于整體計算量級來說枫耳,計算復雜度直接下降乏矾。

第三、多個因子如何權衡影響權重

基于屬性計算相似迁杨,從整體上來看钻心,其實一般主體都不止一個屬性,那么計算相關的時候到底看那個屬性呢铅协?或者說哪些屬性應該占有更高的權重捷沸,哪些因素是次要因素。

還是以上面的騰訊視頻的推薦為例狐史,從結果上來反推相似推薦的部分(當然痒给,實際情況不詳哈坯钦,只是推斷而已),顯然當前視頻的類別占了很大的權重(記錄片)侈玄,除此之外包括導演啊婉刀,一些其他特征屬性應該也會參考在內的。

回到常規(guī)問題序仙,如何確定影響權重是個操作難題突颊。最簡單并且實際上還挺有效的一種方式就是專家評判法,即通過權威經驗來劃定影響因子的權重潘悼,還有就是通過標注的樣本進行反向擬合每種因素的占比權重律秃。除此之外還有一些其他學術上的方法,包括什么主成分分析法治唤,層次分析法棒动,還有什么熵權法,其實都是找因子影響能力的主次關系宾添。

最終確定好了影響因素船惨,在實際上線回收到數據之后,依然是需要逐步的進行權重影響調整的缕陕,我們可以通過結果的樣本數據粱锐,進行LR的回歸擬合,尋找最合適的權重配比扛邑。

0.4.3 最簡單的推薦策略算法實踐

說了這么多理論怜浅,不能光說不練,標題上寫著“附Spark案例”蔬崩,很多人都是沖著這來的呢恶座,前面BB了這么多屁話,還不見代碼沥阳。來跨琳,我們這就上正文。

不過不用期待過多沪袭,畢竟這只是一個簡單的相似計算的過程而已湾宙,所以權當屬性實驗數據以及Spark開發(fā)了,高手可以略過了冈绊。

一、實驗數據簡介

image.gif

其實看到這三部分數據的簡介埠啃,一些老手估計已經知道是什么數據了死宣,是的,就是那份有名的電影數據集(MovieLens開放數據)碴开,并且取的是完全版的那份毅该,簡直成了推薦系統(tǒng)的標配實驗數據了博秫。

三個文件,其中電影數據集共1萬多個電影基礎數據眶掌,評分數據集最大共100萬條評分數據挡育,以及10萬條的用戶對電影的打標簽數據,總大小約為幾百兆朴爬,不大即寒,但是用來做實驗玩玩那是相當足夠了。

二召噩、推薦機制邏輯

我們的核心計算邏輯還是內容屬性上的相似嘛母赵,所以核心是看看圍繞電影,有哪些屬性是可以抽取出來的具滴,并且參與計算的凹嘲。

第一,電影的類別构韵,基于上面騰訊視頻的考慮周蹭,其實這個顯然很重要,而電影的類別信息存儲于電影數據集中疲恢,并且是一對多的關系谷醉,即一個電影可以對應多個類目,我們需要進行切割冈闭,由于計算這個維度相似的時候俱尼,是多對多的關系,天然的計算相似或者相關的特征萎攒。

第二遇八、電影的播放年份,電影的年份其實有種潛在的關聯關系耍休,舉個例子可以說明刃永,比如說零幾年的電影與現狀的電影風格是不同的,當時間跨度有一定差距時羊精,這個還是蠻明顯的斯够。關于電影的年份數據,從數據樣本可以知道喧锦,它隱藏在電影的名字中读规,寫個正則過濾出來即可。至于說如何計算這個維度的相關燃少,我們可以用兩者差距來算相關束亏,比如年份絕對值越遠,這個值越小阵具,越近甚至是重疊就越大碍遍。

第三定铜,電影的標簽,電影本身是沒有標簽屬性的怕敬,但它有用戶對他打的標簽信息揣炕,所以我們需要進一步處理,把它變成電影的屬性东跪,需要清洗畸陡、規(guī)整以及處理。標簽本身也是多對多的關系越庇,同樣可以計算相似度罩锐,比如歐式或者余弦。

第四卤唉、電影的名稱涩惑,名稱上進行尋找關聯性,聽上去很扯桑驱,但其實有一定的邏輯在里頭竭恬,比如我在視頻網站搜索“三國”,顯然我期望從名稱上尋找三國相關題材的視頻熬的,他們就是在名稱上建立起關聯關系的痊硕,所以,名稱從某種程度上來說押框,可以體現相關性岔绸。在計算相似或者相關方式上,我們可以進行分詞橡伞,去除停詞盒揉,然后再以詞維度進行余弦計算。

第五兑徘、候選集電影的評分刚盈,對于做推薦來說,首先需要保證的推薦的候選集一定是優(yōu)質的挂脑,從這個維度上說藕漱,拋開其他因素,那么就是整體評分高的電影是相對優(yōu)質的電影崭闲。在處理的過程中肋联,由于一個電影對應多個評分,所以镀脂,我們需要進行進行歸一計算牺蹄,最簡單的做法就是計算整體評分的平均值,作為電影的評分數據薄翅,評分過低的數據直接從候選集中干掉沙兰,又大大的降低了計算次數。

三翘魄、代碼邏輯

Spark2.0之后鼎天,不用再構建sparkcontext了,以創(chuàng)建一個復合多功能的SparkSession替代暑竟,可以正常的從HDFS讀取文件斋射,也可以從Hive中獲取DataFrame等等。

val sparkSession = SparkSession

.builder()

.appName("base-content-Recommand") //spark任務名稱

.enableHiveSupport()

.getOrCreate()

那三個表可以先load到Hive中但荤,然后spark直接從Hive中讀取罗岖,形成DataFrame。

//從hive中腹躁,獲取rating評分數據集桑包,最終形成如下格式數據(movie,avg_rate)

val movieAvgRate = sparkSession.sql("select movieid,round(avg(rate),1) as avg_rate? from tx.tx_ratings group by movieid").rdd.map{

f=>

(f.get(0),f.get(1))

}

//獲取電影的基本屬性數據,包括電影id纺非,名稱哑了,以及genre類別

val moviesData = sparkSession.sql("select movieid,title,genre from tx.tx_movies").rdd

//獲取電影tags數據,這里取到所有的電影tag

val tagsData = sparkSession.sql("select movieid,tag from tx.tx_tags").rdd

對tag進行處理烧颖,很多tag其實說的是同一個東西弱左,我們需要進行一定程度上的合并,這樣才能讓tag更加的合理(有朋友有意見了炕淮,就一個實驗案例而已拆火,搞這么復雜),舉個簡單例子涂圆,blood们镜、bloods、bloody其實都是想說這個電影很血腥暴力乘综,但是不同的人使用的詞不同的(這點大伙兒可以自由查看實驗數據)憎账,所以我們需要進行一定程度上的合并。

val tagsStandardizeTmp = tagsStandardize.collect()

val tagsSimi = tagsStandardize.map{

f=>

var retTag = f._2

if (f.2.toString.split(" ").size == 1) {

var simiTmp = ""

val tagsTmpStand = tagsStandardizeTmp

.filter(

._2.toString.split(" ").size != 1 )

.filter(f._2.toString.size < _.2.toString.size)

.sortBy(

._2.toString.size)

var x = 0

val loop = new Breaks

tagsTmpStand.map{

tagTmp=>

val flag = getEditSize(f._2.toString,tagTmp._2.toString)

if (flag == 1){

retTag = tagTmp._2

loop.break()

}

}

((f._1,retTag),1)

} else {

((f._1,f._2),1)

}

}

其中getEditSize是求取卡辰,兩個詞的編輯距離的胞皱,編輯距離在一定時候,進行合并九妈,具體邏輯見代碼了反砌,不復雜。

def getEditSize(str1:String,str2:String): Int ={

if (str2.size > str1.size){

0

} else {

//計數器

var count = 0

val loop = new Breaks

//以較短的str2為中心萌朱,進行遍歷宴树,并逐個比較字符

val lengthStr2 = str2.getBytes().length

var i = 0

for ( i <- 1 to lengthStr2 ){

if (str2.getBytes()(i) == str1.getBytes()(i)) {

//逐個匹配字節(jié),相等則計數器+1

count += 1

} else {

//一旦出現前綴不一致則中斷循環(huán)晶疼,開始計算重疊度

loop.break()

}

}

//計算重疊度,當前綴重疊度大于等于2/7時酒贬,進行字符串合并又憨,從長的往短的合并

if (count.asInstanceOf[Double]/str1.getBytes().size.asInstanceOf[Double] >= (1-0.286)){

1

}else{

0

}

}

}

繼續(xù)對tag進行處理,統(tǒng)計tag頻度锭吨,取TopN個作為電影對應的tag屬性蠢莺。

val movieTag = tagsSimi.reduceByKey(+).groupBy(k=>k._1._1).map{

f=>

(f._1,f._2.map{

ff=>

(ff._1._2,ff.2)

}.toList.sortBy(

._2).reverse.take(10).toMap)

}

接下來處理年齡、年份和名稱零如,這個會簡單點躏将,進行分詞處理的話,怎么簡單怎么來了考蕾,直接使用第三方的HanLP進行關鍵詞抽取作為分詞結果祸憋,直接屏蔽了停用詞。

val moviesGenresTitleYear = moviesData.map{

f=>

val movieid = f.get(0)

val title = f.get(1)

val genres = f.get(2).toString.split("|").toList.take(10)

val titleWorlds = HanLP.extractKeyword(title.toString, 10).toList

val year = movieYearRegex.movieYearReg(title.toString)

(movieid,(genres,titleWorlds,year))

}

取年份的正則函數如下肖卧,是個Java寫的精通工具類(Scala和Java混寫蚯窥,簡直無比美妙)。

package utils;

import java.util.regex.Matcher;

import java.util.regex.Pattern; /**

Desc: 抽取年份公式

/ public class movieYearRegex {

private? static String moduleType = ".

\(([1-9][0-9][0-9][0-9])\).*";

public static void main(String[] args){

System.out.println(movieYearReg("GoldenEye (1995)"));

}

public static int movieYearReg(String str){

int retYear = 1994;

Pattern patternType = Pattern.compile(moduleType);

Matcher matcherType = patternType.matcher(str);

while (matcherType.find()) {

retYear = Integer.parseInt(matcherType.group(1));

}

return retYear;

}

}

通過join進行數據合并喜命,生成一個以電影id為核心的屬性集合沟沙。

val movieContent = movieTag.join(movieAvgRate).join(moviesGenresTitleYear).map{

f=>

//(movie,tagList,titleList,year,genreList,rate)

(f._1,f._2._1._1,f._2._2._2,f._2._2._3,f._2._2._1,f._2._1._2)

}

相似計算開始之前,還記得我們之前說的嗎壁榕,可以進行候選集閹割矛紫,我們先根據一些規(guī)則裁剪一下候選集。

val movieConetentTmp = movieContent.filter(f=>f._6.asInstanceOf[java.math.BigDecimal].doubleValue() < 3.5).collect()

然后真正的開始計算相似牌里,使用余弦相似度計算颊咬,取排序之后的Top20作為推薦列表。

val movieContentBase = movieContent.map{

f=>

val currentMoiveId = f._1val currentTagList = f._2//[(tag,score)]val currentTitleWorldList = f._3val currentYear = f._4val currentGenreList = f._5val currentRate = f._6.asInstanceOf[java.math.BigDecimal].doubleValue()val recommandMovies = movieConetentTmp.map{? ff=>? ? val tagSimi = getCosTags(currentTagList,ff._2)? ? val titleSimi = getCosList(currentTitleWorldList,ff._3)? ? val genreSimi = getCosList(currentGenreList,ff._5)? ? val yearSimi = getYearSimi(currentYear,ff._4)? ? val rateSimi = getRateSimi(ff._6.asInstanceOf[java.math.BigDecimal].doubleValue())? ? val score =0.4*genreSimi +0.25*tagSimi +0.1*yearSimi +0.05*titleSimi +0.2*rateSimi? ? (ff._1,score)}.toList.sortBy(k=>k._2).reverse.take(20)(currentMoiveId,recommandMovies)

}.flatMap(f=>f._2.map(k=>(f._1,k._1,k._2))).map(f=>Row(f._1,f._2,f._3))

最后牡辽,將結果存入Hive中喳篇,Hive中提前建好結果表。

//我們先進行DataFrame格式化申明

val schemaString2 = "movieid movieid_recommand score"

val schemaContentBase = StructType(schemaString2.split(" ")

.map(fieldName=>StructField(fieldName,if (fieldName.equals("score")) DoubleType else? StringType,true)))

val movieContentBaseDataFrame = sparkSession.createDataFrame(movieContentBase,schemaContentBase)

//將結果存入hive,需要先進行臨時表創(chuàng)建

val userTagTmpTableName = "mite_content_base_tmp"

val userTagTableName = "mite8.mite_content_base_reco"

movieContentBaseDataFrame.registerTempTable(userTagTmpTableName)

sparkSession.sql("insert into table " + userTagTableName + " select * from " + userTagTmpTableName)

到這里态辛,基本大的代碼邏輯就完了麸澜,可能還有一些邊邊角角的代碼遺漏了,但不妨礙主干了奏黑。

05 融合用戶興趣的推薦才個性

接上個章節(jié)炊邦,我們給了一個最最最簡單的推薦系統(tǒng)機制,即基于內容屬性的相似或者相關推薦熟史,我們知道這種推薦機制基本只基于內容本身的屬性進行推薦馁害,與用戶沒有半毛錢關系,所以蹂匹,當然也就說不上個性化了碘菜。

0.5.1 個性化與用戶畫像

在說具體的情況之前,我們先來思考一個問題,什么是個性化忍啸?個性化一定是與人相關的仰坦,只有人才有個性,每個人可能都有自己的個性吊骤,推送的信息如果能滿足用戶的個性缎岗,才是一個好的推薦系統(tǒng)静尼,才具有足夠的智能白粉。

而今天,我們要討論的就是鼠渺,如何讓推薦從非智能的過程演變?yōu)橹獣杂脩魝€性鸭巴,基于用戶偏好進行推薦,從而變得更“聰明”點拦盹,也就是智能化鹃祖。

要實現推薦個性化,那么先需要對用戶進行分析普舆,分析用戶的偏好恬口,然后根據偏好來做推薦,就順其自然了沼侣。而要分析用戶的偏好祖能,那么自然就少不了對用戶行為的分析。

所以蛾洛,核心還是用戶畫像的分析养铸,然后我們再基于用戶畫像屬性進行推薦,由于用戶畫像體現的是每個用戶的偏好數據轧膘,所以钞螟,不管怎么樣,這種推薦機制或多或少都是能體現一些個性化的東西的谎碍。

need-to-insert-img

image

沿著這個路徑鳞滨,我們依然是結合實際數據以及代碼案例來分解這個個性化推薦的過程。

0.5.2 基于用戶畫像的個性化推薦策略

整個案例代碼的邏輯是蟆淀,我們先根據行為數據拯啦,進行用戶的畫像描述抽取,然后再結合用戶的畫像數據為用戶進行信息推薦扳碍,注意提岔,這里與之前的實例不同的是,我們是基于用戶進行推薦的笋敞,而上個實例是在瀏覽某個內容的時候碱蒙,進行相關內容推薦,這里以及進化到了根據人進行推薦了。

實踐數據源

關于數據源赛惩,依然使用的是上個案例中的實驗數據哀墓,不清楚的見上一個章節(jié)(最簡單的推薦系統(tǒng))的原始數據說明,從上次的數據源說明情況看喷兼,實際上打標行為數據有10萬條篮绰,評分數據有100萬條,相對于電影內容數據實體來說季惯,其實已經算不少了吠各,所以,不用擔心勉抓,針對于有行為記錄的用戶贾漏,或多或少還是能描述出他們各自的一些行為偏好的。

用戶興趣標簽提取

基于上個小節(jié)的流程圖藕筋,所以纵散,在實踐中,我們首先需要做的就是用戶興趣標簽的提取隐圾。我們核心擁有的就是用戶對電影的打標簽數據伍掀,以及用戶對電影的評分數據。

所以暇藏,從上面兩個行為數據集中蜜笤,我們可以嘗試提取以下幾個維度的用戶偏好數據:

用戶對電影類目偏好數據,即用戶對那些類目偏好叨咖。

用戶的偏好興趣標簽瘩例,即通過用戶對電影的偏好標簽打標行為,進一步可以提取用戶的興趣標簽甸各。

用戶的偏好年份垛贤,通過打分數據,描述用戶偏好哪個年代的電影趣倾。

我們先解決用戶的偏好標簽問題聘惦,我們已有的是用戶對電影的打標行為數據,實際上這是電影層級的標簽儒恋,所以我們需要在這個基礎上善绎,最終直接為用戶映射上這些特征標簽。

所以诫尽,我們需要對單個用戶的所有打標數據進行合并(標簽會做預處理)禀酱,然后如果用戶對剛好打標的電影有評分的話,還需要帶上評分權重牧嫉,最終合并這些標簽剂跟,形成用戶帶權重(本身的頻度减途、對應電影的評分)的標簽集,這就是用戶的一些興趣點曹洽。

對于類目偏好鳍置,說起來就簡單了,比如通過評分表送淆,我們把對應所有的電影都取出來税产,然后分析其類目,將評分作為對應類目的權重偷崩,然后將類目進行合并屡拨,最終求取用戶的類目偏好合集僚害。

對于電影年份哭靖,過程與上述取類目的過程類似蹬耘,最終獲取到年份偏好卖宠。

電影數據的處理

假設在上面的基礎上乍炉,我們已經獲取了用戶層級的畫像屬性信息抡锈,比如偏好的電影類別怜珍,偏好的特征標簽渡紫,偏好的某些年份的電影(同個時代電影具有一些相同的電影到推,比如10年前的電影風格與現在的儼然不同,年份在某種程度上說還是有影響的惕澎,雖然很弱)莉测。

接下來,我們需要繪制候選集電影的屬性(取之前唧喉,做一些初篩過濾操作捣卤,減少計算量),對應用戶的屬性八孝,同樣是三個董朝,其中年份、類目都是直接存放于電影表中干跛,唯一需要額外處理的就是特征Tag了子姜,由于不同人對不同的電影進行Tag標記,上面進行用戶畫像繪制的時候楼入,是以人為維度的哥捕,現在已電影為維度,進行標簽合并嘉熊,最終同樣可以形成電影維度的標簽集遥赚。

關聯推薦計算

每個維度分別進行計算相似度或者相關度,然后不同維度進行合并歸一計算最終的用戶與電影的相關度阐肤。最外層我們依然以權重模型去做凫佛,以經驗來看,類目是最重要的,其次是Tag御蒲,最后才是年份屬性衣赶,至于最終怎么調整還是需要根據實際反饋數據來做微調,現在就拍腦袋吧厚满。

image


作者:daos

鏈接:http://www.reibang.com/p/db181f4b5f2b

來源:簡書

簡書著作權歸作者所有府瞄,任何形式的轉載都請聯系作者獲得授權并注明出處。

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末碘箍,一起剝皮案震驚了整個濱河市遵馆,隨后出現的幾起案子,更是在濱河造成了極大的恐慌丰榴,老刑警劉巖货邓,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異四濒,居然都是意外死亡换况,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門盗蟆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來戈二,“玉大人,你說我怎么就攤上這事喳资【蹩裕” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵仆邓,是天一觀的道長鲜滩。 經常有香客問我,道長节值,這世上最難降的妖魔是什么徙硅? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮察署,結果婚禮上闷游,老公的妹妹穿的比我還像新娘。我一直安慰自己贴汪,他們只是感情好脐往,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著扳埂,像睡著了一般业簿。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上阳懂,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天梅尤,我揣著相機與錄音柜思,去河邊找鬼。 笑死巷燥,一個胖子當著我的面吹牛赡盘,可吹牛的內容都是我干的。 我是一名探鬼主播缰揪,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼陨享,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了钝腺?” 一聲冷哼從身側響起抛姑,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎艳狐,沒想到半個月后定硝,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡毫目,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年蔬啡,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒜茴。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡星爪,死狀恐怖,靈堂內的尸體忽然破棺而出粉私,到底是詐尸還是另有隱情,我是刑警寧澤近零,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布诺核,位于F島的核電站,受9級特大地震影響久信,放射性物質發(fā)生泄漏窖杀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一裙士、第九天 我趴在偏房一處隱蔽的房頂上張望入客。 院中可真熱鬧,春花似錦腿椎、人聲如沸桌硫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铆隘。三九已至,卻和暖如春南用,著一層夾襖步出監(jiān)牢的瞬間膀钠,已是汗流浹背掏湾。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留肿嘲,地道東北人融击。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像雳窟,于是被迫代替她去往敵國和親尊浪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內容