打包教你推薦系統(tǒng)的開(kāi)源工具和框架
如果我們懂得了原理,知道了實(shí)際推薦系統(tǒng)需要考慮哪些元素之后,卻在你摩拳擦掌之際,發(fā)現(xiàn)要先從挖地基開(kāi)始,你整個(gè)人可能是崩潰的。
輪子不要重復(fù)造
但是事實(shí)上你沒(méi)必要這樣做也不應(yīng)該這樣做。大廠研發(fā)力量雄厚,業(yè)務(wù)場(chǎng)景復(fù)雜,數(shù)據(jù)量大,自己從挖地基開(kāi)始研發(fā)自己的推薦系統(tǒng)則是非常常見(jiàn)的,然而中小廠職工們則要避免重復(fù)造輪子。這是因?yàn)橄旅娴脑颉?/p>
1、中小企業(yè),或者剛剛起步的推薦系統(tǒng),要達(dá)成的效果往往是基準(zhǔn)線,通用的和開(kāi)源的已經(jīng)能夠滿足;
2、開(kāi)源的輪子有社區(qū)貢獻(xiàn),經(jīng)過(guò)若干年的檢驗(yàn)后,大概率上已經(jīng)好于你自己從零開(kāi)始寫(xiě)一個(gè)同樣功能的輪子;
3、對(duì)于沒(méi)有那么多研發(fā)力量的廠來(lái)說(shuō),時(shí)間還是第一位的,先做出來(lái),這是第一要義。
既然要避免重復(fù)造輪子,就要知道有哪些輪子。
有別于介紹一個(gè)籠統(tǒng)而大全的“推薦系統(tǒng)”輪子,我更傾向于把粒度和焦點(diǎn)再縮小一下,介于底層的編程語(yǔ)言 API 和大而全的”推薦系統(tǒng)”之間,本文按照本專欄的目錄給你梳理一遍各個(gè)模塊可以用到的開(kāi)源工具。
這里順帶提一下,選擇開(kāi)源項(xiàng)目時(shí)要優(yōu)先選擇自己熟悉的編程語(yǔ)言、還要選有大公司背書(shū)的,畢竟基礎(chǔ)技術(shù)過(guò)硬且容易形成社區(qū)、除此之外要考慮在實(shí)際項(xiàng)目中成功實(shí)施過(guò)的公司、最后還要有活躍的社區(qū)氛圍。
內(nèi)容分析
基于內(nèi)容的推薦,主要工作集中在處理文本,或者把數(shù)據(jù)視為文本去處理。文本分析相關(guān)的工作就是將非結(jié)構(gòu)化的文本轉(zhuǎn)換為結(jié)構(gòu)化。主要的工作就是三類。
1、主題模型;
2、詞嵌入;
3、文本分類。
可以做這三類工作的開(kāi)源工具有下面的幾種。

由于通常我們遇到的數(shù)據(jù)量還沒(méi)有那么大,并且分布式維護(hù)本身需要專業(yè)的人和精力,所以請(qǐng)慎重選擇分布式的,將單機(jī)發(fā)揮到極致后,遇到瓶頸再考慮分布式。
這其中 FastText 的詞嵌入和 Word2vec 的詞嵌入是一樣的,但 FastText 還提供分類功能,這個(gè)分類非常有優(yōu)勢(shì),效果幾乎等同于 CNN,但效率卻和線性模型一樣,在實(shí)際項(xiàng)目中久經(jīng)考驗(yàn)。LightLDA 和 DMWE 都是微軟開(kāi)源的機(jī)器學(xué)習(xí)工具包。
協(xié)同過(guò)濾和矩陣分解
基于用戶、基于物品的協(xié)同過(guò)濾,矩陣分解,都依賴對(duì)用戶物品關(guān)系矩陣的利用,這里面常常要涉及的工作有下面幾種。
1、KNN 相似度計(jì)算;
2、SVD 矩陣分解;
3、SVD++ 矩陣分解;
4、ALS 矩陣分解;
5、BPR 矩陣分解;
6、低維稠密向量近鄰搜索。
可以做這些工作的開(kāi)源工具有下面幾種。

這里面的工作通常是這樣:基礎(chǔ)協(xié)同過(guò)濾算法,通過(guò)計(jì)算矩陣的行相似和列相似得到推薦結(jié)果。
矩陣分解,得到用戶和物品的隱因子向量,是低維稠密向量,進(jìn)一步以用戶的低維稠密向量在物品的向量中搜索得到近鄰結(jié)果,作為推薦結(jié)果,因此需要專門(mén)針對(duì)低維稠密向量的近鄰搜索。
同樣,除非數(shù)據(jù)量達(dá)到一定程度,比如過(guò)億用戶以上,否則你要慎重選擇分布式版本,非常不劃算。
模型融合
模型融合這部分,有線性模型、梯度提升樹(shù)模型。

線性模型復(fù)雜在模型訓(xùn)練部分,這部分可以離線批量進(jìn)行,而線上預(yù)測(cè)部分則比較簡(jiǎn)單,可以用開(kāi)源的接口,也可以自己實(shí)現(xiàn)。
其他工具
Bandit 算法比較簡(jiǎn)單,自己實(shí)現(xiàn)不難,這里不再單獨(dú)列舉。至于深度學(xué)習(xí)部分,則主要基于 TensorFlow 完成。
存儲(chǔ)、接口相關(guān)開(kāi)源項(xiàng)目和其他互聯(lián)網(wǎng)服務(wù)開(kāi)發(fā)一樣,也在對(duì)應(yīng)章節(jié)文章列出,這里不再單獨(dú)列出了。
完整推薦系統(tǒng)
這里也梳理一下有哪些完整的推薦系統(tǒng)開(kāi)源項(xiàng)目,可以作為學(xué)習(xí)和借鑒。 所謂完整的推薦系統(tǒng)是指:包含推薦算法實(shí)現(xiàn)、存儲(chǔ)、接口。

總結(jié)
你可能注意到了,這里的推薦系統(tǒng)算法部分以 Python 和 C++ 為主,甚至一些 Python 項(xiàng)目,底層也都是用 C++ 開(kāi)發(fā)而成。
因此在算法領(lǐng)域,以 Python 和 C++ 作為開(kāi)發(fā)語(yǔ)言會(huì)有比較寬泛的選擇范圍。
至于完整的推薦系統(tǒng)開(kāi)源項(xiàng)目,由于其封裝過(guò)于嚴(yán)密,比自己將大模塊組合在一起要黑盒很多,因此在優(yōu)化效果時(shí),不是很理想,需要一定的額外學(xué)習(xí)成本,學(xué)習(xí)這個(gè)系統(tǒng)本身的開(kāi)發(fā)細(xì)節(jié),這個(gè)學(xué)習(xí)成本是額外的,不是很值得投入。
因此,我傾向于選擇各個(gè)模塊的開(kāi)源項(xiàng)目,再將其組合集成為自己的推薦系統(tǒng)。這樣做的好處是有下面幾種。
1、單個(gè)模塊開(kāi)源項(xiàng)目容易入手,學(xué)習(xí)成本低,性能好;
2、自己組合后更容易診斷問(wèn)題,不需要的不用開(kāi)發(fā);
3、單個(gè)模塊的性能和效果更有保證。
當(dāng)然,還是那句話,實(shí)際問(wèn)題實(shí)際分析,也許你在你的情境下有其他考慮和選擇。