推薦系統(tǒng)的實踐與思考(上篇)
那么當(dāng)我們真正要開始做一個推薦系統(tǒng)時,需要從哪幾個方面考慮問題?不同方面需要注意什么?筆者分享了在實際情況中遇到的一些問題以及總結(jié)出的解決方法。
我之前進(jìn)行過一個小調(diào)查,得知大家普遍在工作中遇到的與推薦系統(tǒng)相關(guān)的問題是:“數(shù)據(jù)太稀疏、數(shù)據(jù)沒有形成閉環(huán)、數(shù)據(jù)沒辦法跟其他系統(tǒng)結(jié)合”等等,這些內(nèi)容,是擺在我們面前的實際問題,那么當(dāng)我們真正要開始做一個推薦系統(tǒng)時,需要從幾方面考慮問題呢?
第一,算法。到底應(yīng)該選擇什么樣的算法?無論是協(xié)同過濾還是其他算法,都要基于自己的業(yè)務(wù)產(chǎn)品;
第二,數(shù)據(jù)。當(dāng)確定了算法時,應(yīng)該選擇什么樣的數(shù)據(jù)?怎樣加工數(shù)據(jù)?用什么樣方法采集數(shù)據(jù)?有句話叫做“機器學(xué)習(xí)=模型+數(shù)據(jù)”,即便擁有了一個很復(fù)雜的模型,在數(shù)據(jù)出現(xiàn)問題的情況下,也無法在推薦系統(tǒng)里面發(fā)揮很好的效果;
第三,在線服務(wù)。當(dāng)模型訓(xùn)練完畢,數(shù)據(jù)準(zhǔn)備充分之后,就會面對接收用戶請求返回推薦結(jié)果的事項,這其中包含兩個問題。其一,返回響應(yīng)要足夠迅速。如果當(dāng)一個用戶請求后的一秒鐘才返回推薦結(jié)果,用戶很可能因喪失耐心而流失。其二,如何讓推薦系統(tǒng)具有高可擴展性。當(dāng) DAU 從最初的十萬漲到一二百萬時,推薦系統(tǒng)還能像最初那樣很好地?fù)踝〈篌w量的請求嗎?這都是在線服務(wù)方面需要考慮和面臨的問題;
第四,評估效果。做好上述三點,并不代表萬事大吉,一方面,我們要持續(xù)迭代推薦算法模型與結(jié)構(gòu),另一方面要去構(gòu)建一套比較完整、系統(tǒng)的評價體系和評估方法,去分析推薦效果的現(xiàn)狀以及后續(xù)的發(fā)展。
我會從以上四個方面,跟大家分享一下我們在實際情況中遇到的一些問題以及總結(jié)出的解決方法。
01 算 法
在各種算法中,大家最容易想到的就是一種基于標(biāo)簽的方法。
如上圖所示,標(biāo)簽可分為兩種:
第一種,用戶標(biāo)簽。假設(shè)我們擁有一部分用戶標(biāo)簽,知道每一個用戶的年齡、性別等信息,當(dāng)某類年齡和某種性別的用戶喜歡過某一個物品時,我們就可以把該物品推薦給具有同樣年齡、性別等用戶標(biāo)簽的其他用戶;
第二種,內(nèi)容標(biāo)簽。與用戶標(biāo)簽的思路相似,如果用戶喜歡過帶有內(nèi)容標(biāo)簽的物品,我們就可以為他推薦具有同樣標(biāo)簽的內(nèi)容。
但很明顯,這種基于標(biāo)簽的方法有一個重要的缺點——它需要足夠豐富的標(biāo)簽。也許在多產(chǎn)品中,可能并沒有標(biāo)簽或者標(biāo)簽數(shù)量非常稀疏,所以標(biāo)簽的方法顯然不足以應(yīng)對。
另外,協(xié)同過濾也是一種非常經(jīng)典、被較多人提及的一種方法,是一種常見且有效的思路。
隨著技術(shù)的不斷發(fā)展,基本從 2012 年以后,深度學(xué)習(xí)幾乎被整個機器學(xué)習(xí)界進(jìn)行反復(fù)的討論和研究。谷歌在 2016 年提出一套基于深度學(xué)習(xí)的推薦模型,用深度學(xué)習(xí)去解決推薦的問題,利用用戶的行為數(shù)據(jù)去構(gòu)建推薦算法。
1. 深度學(xué)習(xí)的目的之一:向量化
推薦系統(tǒng)其實是在做一個關(guān)于“匹配”的事情,把人和物做匹配。看似很難的推薦系統(tǒng),其實也有簡單的思路——做人和物的匹配,把該用戶可能感興趣的物品推薦給他(她)。如果站在數(shù)學(xué)的角度去思考這個問題,我們?nèi)绾稳ビ嬎闳撕臀锏南嗨贫绕ヅ淠兀?/p>
在推薦領(lǐng)域,深度學(xué)習(xí)的目的之一就是嘗試將人和物向量化,即把某個人和某個物品學(xué)習(xí)成一種統(tǒng)一的表示方式,隨后在這個統(tǒng)一的表示方式中計算這個人和物品的相似度,當(dāng)人和物都映射到同一個可比較的空間中時,就能夠基于計算結(jié)果去執(zhí)行相關(guān)的內(nèi)容推薦。
把最終的結(jié)果映射到這張二維的平面圖表里,用戶認(rèn)為相似的內(nèi)容就會映射在向量上,當(dāng)擁有內(nèi)容向量之后,之后再將用戶映射進(jìn)來即可,比如用戶到達(dá)了上圖某個地方,根據(jù)他所處的位置,可以向其推送教育、娛樂、科學(xué)、地理等內(nèi)容。
講到這里,有些朋友就會提出疑問:既然深度學(xué)習(xí)如此復(fù)雜,那在實踐中究竟有沒有作用?其實站在實戰(zhàn)經(jīng)驗的角度來看,當(dāng)具備一定的數(shù)據(jù)量時,會帶來比較明顯的效果提升,但當(dāng)你要去搭建一個深度學(xué)習(xí)模型的時候,可能真的會遇到很多問題。比如:
用多少數(shù)據(jù)量去訓(xùn)練模型是可以的?訓(xùn)練數(shù)據(jù)該用什么格式?多“深”才算深度模型?訓(xùn)練模型太慢了怎么辦等。這些關(guān)于在搭建深度學(xué)習(xí)模型時遇到的困難與解決方法,會在以后跟大家分享。
2. 冷啟動
冷啟動是算法部分經(jīng)常遇到的問題,在冷啟動階段,數(shù)據(jù)比較稀疏,很難利用用戶的行為數(shù)據(jù)實現(xiàn)個性化推薦。冷啟動的問題分為兩種:新內(nèi)容的冷啟動、新用戶的冷啟動。接下來,我們分享一下新內(nèi)容的冷啟動要如何實現(xiàn)。
舉個例子,資訊場景的需求往往是將發(fā)布的新內(nèi)容(如 10 分鐘內(nèi)發(fā)布的內(nèi)容),以實時且個性化的方式分發(fā)到用戶的推薦結(jié)果中去。
上圖這篇文章在 17:41 發(fā)出,那么就需要在極短的時間內(nèi)根據(jù)這篇文章的內(nèi)容去做一些個性化的相關(guān)推薦。此文內(nèi)容圍繞美食展開,用戶點開這篇文章之后,文章的相關(guān)推薦里面就要有跟美食相關(guān)的一些內(nèi)容。當(dāng)我們要在如此實時的環(huán)境中實現(xiàn)推薦效果的話,其實沒辦法去依賴用戶的行為。
這時,我們嘗試提供一種思路,一種基于深度學(xué)習(xí)的語義理解模型。
這個模型跟我們前面分享的內(nèi)容有一個很大的區(qū)別就是——不需要用戶行為,只需要分析用戶文本,基于用戶的內(nèi)容去給每一篇文章生成一個向量。這和前面提到的模型也有相通的地方:第一,用深度學(xué)習(xí)的思路去解決問題;第二,用向量化的思路解決問題。我們只需要訓(xùn)練出文章的語義向量,獲得文章與文章之間的相似度,從而得知文章和用戶之間的相關(guān)性。
3. 召回、排序、規(guī)則
如今的推薦系統(tǒng)已經(jīng)做得相當(dāng)復(fù)雜,特別是在一些大規(guī)模的應(yīng)用場景中,比如說今日頭條的 Feed 流,淘寶的“猜你喜歡”等,都擁有一個非常復(fù)雜的推薦系統(tǒng),這個推薦系統(tǒng)中的各個模塊可能會涉及到很多的實驗算法,在一個系統(tǒng)中,出現(xiàn) 10 個或者 20 個模型都很常見。那么怎么把這些模型有效地融合成一個真正的系統(tǒng)呢?
(1) 召回
召回,即從海量的內(nèi)容里去召回每一個用戶他可能感興趣的內(nèi)容,前提是——擁有海量的內(nèi)容,因為當(dāng)內(nèi)容不足時,也就不需要去搭建復(fù)雜的推薦系統(tǒng)。所以,當(dāng)有海量 Item 時,需要用召回的算法從不同類別的內(nèi)容里為用戶生成他可能感興趣的內(nèi)容。
比如某位用戶既喜歡體育內(nèi)容,也喜歡軍事內(nèi)容,那么在第一步,無論用哪些模型,都希望達(dá)到為該用戶生成一些體育、軍事相關(guān)內(nèi)容的效果。另一個用戶可能喜歡美食和游戲,在召回階段,我們就希望通過模型去為他生成一些美食和游戲相關(guān)的內(nèi)容。
在召回階段可能就會存在許多個模型。而經(jīng)過召回階段之后,盡管生成的是該用戶可能感興趣的內(nèi)容,但這些內(nèi)容實際并沒有融合到一起,是一種亂序的狀態(tài)。
(2) 排序
排序,即將召回出來的內(nèi)容做統(tǒng)一排序。排序過程其實就是給每部分內(nèi)容打分的過程,預(yù)測每一個用戶對每一部分內(nèi)容的感興趣程度,從而獲知每一個用戶對每部分內(nèi)容的偏好程度。
(3) 規(guī)則
推薦系統(tǒng)常常跟產(chǎn)品或者業(yè)務(wù)場景緊密相連,而在產(chǎn)品中一定有一些需求是無法用模型來解決的。因為模型只能從用戶行為或者文本內(nèi)容中去發(fā)掘用戶和物品之間的關(guān)系,所以有些常見的業(yè)務(wù)需求要通過規(guī)則去實現(xiàn)。
舉個例子,部分推薦場景中會出現(xiàn)一些運營精選的內(nèi)容,運營同事的需求是:保證每十條內(nèi)容中都有一條編輯精選內(nèi)容,而這個需求,只能通過規(guī)則實現(xiàn),而不是通過算法。
一個比較復(fù)雜的推薦系統(tǒng)通常分為召回、排序、規(guī)則這三個步驟。首先召回用戶感興趣的內(nèi)容,第二為用戶生成一個排序列表,第三用規(guī)則解決一些產(chǎn)品、運營方面提出的需求。
02 數(shù) 據(jù)
總是會聽到一個這樣的說法,“推薦算法的效果是由模型與數(shù)據(jù)所決定的”,即模型只占推薦效果中的一部分,另外一個非常重要的部分就是數(shù)據(jù)。那么我們究竟需要哪些數(shù)據(jù)?在一個實際的推薦系統(tǒng)中,哪些數(shù)據(jù)是有可能發(fā)揮作用的?我們又能拿到哪些數(shù)據(jù)?
通常來說一般會有四類數(shù)據(jù):用戶行為、物品信息、用戶畫像以及外部數(shù)據(jù)。
1. 用戶行為
用戶行為數(shù)據(jù)最為重要,幾乎沒有哪一個推薦系統(tǒng)可以直接表示不需要用戶行為數(shù)據(jù)。一方面,用戶行為數(shù)據(jù)是訓(xùn)練模型中的一個重要數(shù)據(jù)來源,另外一方面,需要通過用戶的行為反饋,技術(shù)同事才能知道推薦系統(tǒng)到底做得如何。搭建推薦系統(tǒng)的一個秘籍就是積累用戶行為數(shù)據(jù),如果沒有將重要的用戶行為做采集,例如在電商場景中,如果只是記錄最終的下單數(shù)據(jù),那么離推薦系統(tǒng)的數(shù)據(jù)要求還是有一定的距離。
2. 物品信息
物品信息指推薦系統(tǒng)中能采集到的描述每一個內(nèi)容的信息。以電商場景為例,在錄入一件具體物品時,錄入商品的品牌、價格、品類、上架時間等就是我們要收集的物品信息。假設(shè)在電商場景中,如果并不清楚每個商品的品牌,也就無法從一些物體的描述信息中去提取某個商品到底屬于何種品牌,那么推薦效果自然受到限制。當(dāng)物品信息采集的足夠豐富時,對推薦系統(tǒng)的效果就會有一定的幫助。
3. 用戶畫像
在傳統(tǒng)的思路中,認(rèn)為用戶畫像里面存儲的實際還是用戶的標(biāo)簽,但在很多實際場景中標(biāo)簽數(shù)量少、維度粗,可能根本不具備去給用戶打標(biāo)簽的能力,這種傳統(tǒng)的“標(biāo)簽式”想法,就會限制搭建推薦系統(tǒng)的思路。
而從深度學(xué)習(xí)的角度出發(fā),用戶畫像中儲存的并不是通常理解的“標(biāo)簽”,他可能存儲的是這個人的向量,深度學(xué)習(xí)是把人和物品做向量化,但這個向量是不可被理解的,即我們可能并不知道這個向量表示的是什么意思,當(dāng)我們看到某個用戶對應(yīng)的向量,我們也不知道他是對體育、音樂或是娛樂感興趣,但我們?nèi)阅軌蛲ㄟ^向量去為他推薦其感興趣的內(nèi)容。
4. 外部數(shù)據(jù)
有的人會迷信外部數(shù)據(jù),覺得自己的數(shù)據(jù)量不夠,所以一定要去購買阿里或者是騰訊的外部數(shù)據(jù)來充實用戶畫像,從而提高推薦系統(tǒng)的效果。甚至有人認(rèn)為推薦系統(tǒng)效果不好,是因為沒有外部數(shù)據(jù)。
但其實,外部數(shù)據(jù)對于推薦系統(tǒng)的效果,個人認(rèn)為還需要一個極為謹(jǐn)慎的推理和驗證。
首先,要先驗證自己的這批用戶群跟所購買的外部數(shù)據(jù)能發(fā)生多少交集。假如一個游戲平臺,購買了阿里的外部數(shù)據(jù),而這樣的外部數(shù)據(jù)可能只能告訴你用戶到底是喜歡買衣服、買車還是買電子產(chǎn)品,這樣的信息對游戲平臺有用嗎?
假設(shè)購買的外部數(shù)據(jù)恰好命中了業(yè)務(wù)場景,可能會發(fā)揮一定的作用,但實際上,能夠同時命中用戶群體和標(biāo)簽的情況也并不常見。
大家不要認(rèn)為上述的 4 種數(shù)據(jù)比較容易理解,所以獲取時也會比較簡單。其實我和我們神策團隊在去構(gòu)建一個實際的推薦系統(tǒng)時,消耗我們?nèi)肆Φ牡胤酵皇撬惴?,反而是怎么去得到正確的數(shù)據(jù),接下來我們以用戶行為數(shù)據(jù)為例,與大家分享應(yīng)該如何獲取我們所需要的用戶行為數(shù)據(jù)?
這時候我們就要思考,當(dāng)我們想去獲取用戶行為數(shù)據(jù)時,到底希望用戶行為數(shù)據(jù)能給我們帶來什么樣的作用?
我總結(jié)為以下幾個方面:
- 我們希望用戶行為數(shù)據(jù)能用來訓(xùn)練模型,這是非常重要的一個方面。比如我給某個用戶推薦十件商品,其中有兩件商品發(fā)生了點擊行為,模型中就會覺得這兩條數(shù)據(jù)是正例,其他是負(fù)例。所以,我們需要用戶行為數(shù)據(jù)作為模型的訓(xùn)練數(shù)據(jù);
- 我們希望用戶行為數(shù)據(jù)能夠驗證效果。推薦系統(tǒng)上線之后,需要用戶行為數(shù)據(jù)來反饋推薦到底做得怎么樣。比如點擊率上升說明效果變好,點擊率下降、負(fù)反饋變多、用戶流失,說明推薦系統(tǒng)可能出現(xiàn)了問題;
- 我們希望用戶行為數(shù)據(jù)能夠支持我們?nèi)タ?A/B Test 效果。模型上線一定要基于 A/B Test,我們需要知道此次上線到底比之前的推薦算法、推薦系統(tǒng)等效果如何。這樣,我們才能判斷這一次的迭代是否有效,如果有效就將其全量,如果無效,則進(jìn)一步迭代;
- 我們希望它能夠幫助我們分析問題。我們將推薦系統(tǒng)上線之后,可能會碰到一些懊惱的問題,比如點擊率并沒有發(fā)生變化,甚至效果變差,畢竟不可能每一次迭代的效果都是上升的,所以我們希望行為數(shù)據(jù)能夠定位到此次推薦系統(tǒng)上線后效果不理想的原因。如果上線后效果不錯,此時我們希望行為數(shù)據(jù)能夠分析到底是哪些因素使效果變好。
那我們應(yīng)該如何去獲取滿足我們這些需求的行為數(shù)據(jù)呢?以曝光日志中的第一個字段 exp_id 為例,exp_id 的中文的意思是實驗 ID。
前面提到了我們希望用戶行為數(shù)據(jù)是能支持 A/B Test 的,那么如何知道每一條數(shù)據(jù)是來自哪一組實驗?zāi)??此時,我們需要一個 exp_id 字段去記錄每一條曝光日志是來自哪組實驗。當(dāng)我們再次分析 A/B Test 效果時,就可以根據(jù)一個 exp_id 字段去區(qū)分不同實驗所帶來的曝光和點擊。
在曝光日志中我們常常討論如何設(shè)計一些常用字段,而另外一個具體問題就是——我們怎么去采集這些數(shù)據(jù)?
簡單來說,當(dāng)用戶在產(chǎn)品里面發(fā)生一些用戶行為,怎么把這個數(shù)據(jù)最終落到服務(wù)器的日志中,從而用于模型訓(xùn)練和效果分析呢?
做用戶行為的采集,通常有兩種方式。第一種就是自助埋點,客戶端先把用戶的行為記錄下來,之后傳給服務(wù)端,服務(wù)端再去傳給推薦引擎。另外一個埋點方式是 SDK 埋點,我們直接使用 SDK 去做推薦引擎的埋點。
SDK 埋點有兩個方面的優(yōu)勢:
- SDK 埋點的接入成本低,它有比較成熟的埋點事件和埋點驗證方案。另外 SDK 有埋點接口和文檔指導(dǎo)客戶埋點,無需關(guān)注上報問題;
- SDK 埋點的容錯性比較高。如果是自助埋點,從客戶端到推薦引擎經(jīng)過了服務(wù)端,數(shù)據(jù)出現(xiàn)問題,難以回溯埋點問題、傳輸問題、數(shù)據(jù)質(zhì)量維護成本高,SDK 埋點就會相對方便。
那么當(dāng)有了行為數(shù)據(jù)之后,如何去訓(xùn)練模型?通常會有以下幾個步驟:
- 構(gòu)造正負(fù)例。比如給用戶推薦十條商品,有幾條發(fā)生點擊,就有幾條正例,其他沒有發(fā)生點擊就是負(fù)例;
- 構(gòu)造特征工程。稍后會以一個電商場景為例,具體講解通常情況下,如何構(gòu)造特征工程;
- 數(shù)據(jù)采樣。數(shù)據(jù)采樣對整個模型訓(xùn)練的效果影響較大。
下面以電商場景為例,講解如何做特征工程,主要分為 2 個方面:
- 商品維度。在商品的維度里,我們可能關(guān)注一些商品的品類、品牌、價格、所面向的性別,以及各種用戶行為反饋的一些數(shù)據(jù),比如點擊率、收藏比率等,這些內(nèi)容一方面體現(xiàn)了商品本身的一些屬性,同時還體現(xiàn)商品的質(zhì)量;
- 用戶層面,通常首先考慮用戶的年齡和性別。因為在電商領(lǐng)域中男性所偏重的商品和女性之間存在較大差異。另外還有用戶的品類偏好、品牌偏好,以及價格偏好等。
在數(shù)據(jù)方面,跟大家分享一下我在實際工作中遇到的“坑”:某一次小的流量上線之后,我和團隊成員發(fā)現(xiàn)效果不如預(yù)期,根據(jù)以往的實踐經(jīng)驗來說,不應(yīng)該是這么差的結(jié)果,當(dāng)我們?nèi)シ治鰯?shù)據(jù)時,發(fā)現(xiàn)有兩個方面的數(shù)據(jù)異常:
第一,命中行為模型的用戶較少,通常情況下,只要不是一個新用戶,理論上來說,都應(yīng)該能夠命中我的行為模型。我們當(dāng)時的新用戶比例在 20% 以下,而命中模型的用戶大概僅為 30%,說明大量的用戶沒有命中到模型;
第二,很多請求的 ID 未出現(xiàn)在日志中,當(dāng)時我們懷疑,是否我們的推薦結(jié)果被別人作弊刷掉了,因為用“作弊”能很好地解釋這些請求并未落到日志中的原因。
但最終,我們發(fā)現(xiàn)并不是作弊的問題,而是因為用戶 ID 沒有統(tǒng)一。前端在用他們理解的一套用戶 ID 體系打日志,但是后端在用另外一套用戶 ID 體系發(fā)送請求,于是所有的數(shù)據(jù)無法對上,后端過來的請求總是新用戶,而訓(xùn)練出來的模型命中不了任何用戶,最終,我們建立了一系列的方法和工具以及流程去保證整個用戶 ID 體系的一致性。
由于篇幅限制,“在線服務(wù)”和“效果評估”將在下一篇文章進(jìn)行介紹,希望對你有幫助!
本文由 @研如玉 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理,未經(jīng)許可,禁止轉(zhuǎn)載
題圖來自Unsplash,基于CC0協(xié)議
在等下部
這里的用戶畫像和用戶行為有些相似,通過用戶的點擊歷史向量求用戶向量,似乎和用戶行為有些像,能否對這里所說的用戶畫像深度解讀一下,感謝
樓主啥時候?qū)懞罄m(xù)內(nèi)容:“在線服務(wù)”和“效果評估”呢?期待
小看什么時候上呢?