更新時(shí)間:2018-07-18 來源:黑馬程序員JavaEE培訓(xùn)學(xué)院 瀏覽量:
Mahout中的推薦器
每天我們都會(huì)對一些喜歡的、不喜歡的甚至不關(guān)心的事物進(jìn)行一些評價(jià)。這中行為往往是無意識(shí)的。你在收音機(jī)上聽到一首歌,你可能會(huì)因?yàn)樗拿烂?或者難聽而注意到它,也可能直接忽略。這樣的情形也會(huì)非常普遍的發(fā)生在人們對于T恤、沙拉醬、滑雪場、發(fā)型、臉型或者電視節(jié)目。
盡管人們的口味多種多樣,但是它遵從一定的模式。人們往往會(huì)喜歡和他們偏好相似的事物。比如我愛吃培根生菜番茄三明治,你可以猜到我也喜歡火雞三明治,因?yàn)檫@兩種三明治很相似?;蛘哒f,我們可以認(rèn)為一個(gè)人很可能會(huì)喜歡一些相似的東西。
這些模式可以幫助我們預(yù)測一個(gè)人的好惡,而推薦就是預(yù)測人們喜好事物的模式,我們可以利用它來發(fā)現(xiàn)一些新的有價(jià)值的東西。
上面已經(jīng)介紹了關(guān)于推薦的一些思路,這一章,我們將會(huì)用Mahout來體驗(yàn)一下如何去構(gòu)建一個(gè)簡單的推薦引擎,然后了解其原理,給你一個(gè)直觀的感受。
1 什么是推薦(recommendation)
一些和你所喜歡的東西相似的事物,你往往也會(huì)喜歡(如:在書架和你喜歡的書擺放的很近的書)。推薦引擎的兩個(gè)基本算 法:”user-based”和”item-based”。
1.1 協(xié)同過濾(Collaborative filtering),不是基于內(nèi)容的推薦
嚴(yán)格的說,上述場景是協(xié)同過濾的例子——它僅僅基于已知的用戶(users)與項(xiàng)目(items)的關(guān)系。這種技術(shù)不需要知道項(xiàng)目本身的屬性特征,從某種角度講這是它的一種優(yōu)勢。而且,這種推薦技術(shù)不關(guān)心項(xiàng)目本身是什么。
還有一些其他基于項(xiàng)目內(nèi)容的推薦技術(shù),這些往往被稱作“content-based”。例如,一個(gè)朋友向你推薦一本書,這本書是錢鐘書寫的,這 樣就可以看做是基于內(nèi)容的,因?yàn)檫@個(gè)推薦的理由是因?yàn)檫@本書的一個(gè)屬性:作者。雖然Mahout對一些基于內(nèi)容的推薦也提供了一些方法,但是Mahout 沒有對于這種框架的推薦直接實(shí)現(xiàn)。
這些基于內(nèi)容的推薦技術(shù)本身并沒有什么錯(cuò),相反它在一些很專門的領(lǐng)域可以有很好的效果。而且也可以被當(dāng)做很有意義的框架去實(shí)現(xiàn)。在構(gòu)建一個(gè)關(guān)于 書的”Content-Based”的框架時(shí),首先要選定書的哪些特征作為屬性,比如:頁數(shù)、作者、出版商、顏色、字體等等。并且你還需要決定這些屬性的 重要程度如何。然而這種技術(shù)就很難在其他的推薦領(lǐng)域中適用,比如你用它去推薦一個(gè)披薩,顯然不合適,因?yàn)榕_沒有“頁數(shù)”這樣的屬性。
因?yàn)檫@個(gè)原因,Mahout沒有過多的去將這種推薦技術(shù)。不過這種類型的推薦Mahout是可以構(gòu)建的,我們將在下一章看到一個(gè)約會(huì)網(wǎng)站用到的相關(guān)推薦技術(shù)。
到此,是時(shí)候該用Mahout體驗(yàn)一下協(xié)同過濾的威力了!
2 構(gòu)建第一個(gè)協(xié)同過濾引擎
Mahout包括了幾種推薦引擎,事實(shí)上它開始就是傳統(tǒng)的基于用戶和基于內(nèi)容的推薦,當(dāng)然它也實(shí)現(xiàn)了其他幾種算法。不過現(xiàn)在我們要先探索一個(gè)基于用戶的推薦器。
2.1 建立輸入
開始探索的一個(gè)好的方法就是先找一個(gè)瑣碎的小例子。數(shù)據(jù)的輸入時(shí)推薦的基礎(chǔ)。這些數(shù)據(jù)會(huì)以Mahout語言來表示一種“偏好”程度,因?yàn)橥扑]系統(tǒng)很擅長表示用戶與項(xiàng)目之間的關(guān)聯(lián)程度,這種“關(guān)聯(lián)”即是所謂的“偏好”。在數(shù)據(jù)中,用戶和項(xiàng)目顯得尤為重要。一個(gè)偏好(preference)包含一個(gè) User ID 和一個(gè) Item ID,然后再用一個(gè)值來代表偏好的程度。ID在Mahout中用整數(shù)表示,而偏好可以使任何數(shù)字類型的,值越大表示偏好程度越高。例如:我們把偏好程度分 為五個(gè)檔次:1-5,那么1可以表示非常討厭,5代表非常喜歡。
新建一個(gè)文本用來存儲(chǔ)輸入數(shù)據(jù),我們用1到5的整數(shù)來表示有五個(gè)用戶,101到104來代表四本書,也就是說這些整數(shù)分別是用戶個(gè)書的ID。每一項(xiàng)采用逗號隔開的方式寫入。
2.2 建立推薦器
你會(huì)向User 1推薦那一本呢?不是101,102或103——因?yàn)樗呀?jīng)知道這些書了,我們推薦給他的必須是他不知道的。直覺上我們知道4和5和1比較像,所以推薦給 1 4和 5都喜歡的可能比較合理。也就是說104、105、106都在備選之列。而104的偏好為4.5和4,所以我們猜最應(yīng)該推薦104。好吧,眼見為實(shí),我們跑一下程序:
class RecommenderIntro {
public static void main(String[] args) throws Exception {
DataModel model = new FileDataModel(new File("intro.csv")); A
UserSimilarity similarity = new PearsonCorrelationSimilarity (model
UserNeighborhood neighborhood =
new NearestNUserNeighborh ood (2, similarity, model);
Recommender recommender = new GenericUserBasedRecommender (
model, neighborhood, similarity); B
List<RecommendedItem > recommendations =
recommender.recommend(1, 1); C
for (RecommendedItem recommendation : recommendations) {
System.out.println(recommendation);
}
}
A 加載數(shù)據(jù)文件
B 建立推薦引擎
C 給User 1 推薦 1 個(gè)項(xiàng)目
2.3 分析輸出結(jié)果
用你所喜歡的IDE去運(yùn)行這個(gè)程序,得出的結(jié)果應(yīng)該如此:RecommendedItem [item:104, value:4.257081]
這個(gè)程序的要求是獲取一個(gè)排名最高的推薦結(jié)果,結(jié)果只有一個(gè)。推薦器把104推薦給了User 1。更進(jìn)一步,推薦器還給出了偏好的一個(gè)量化值4.3,因?yàn)檫@個(gè)值是所有推薦結(jié)果中最高的,所以被輸出了出來。
結(jié)果看起來不太壞,值得被推薦的107并沒有消失,只是因?yàn)?07和一個(gè)口味和1不同的用戶產(chǎn)生了關(guān)聯(lián)。結(jié)果為104是在情理之中的,因?yàn)?04的分?jǐn)?shù)比 106的要高。更進(jìn)一步,104的“偏好指數(shù)”介于4.0與4.5之間也是合理的,因?yàn)?和5對104的偏好指數(shù)分別為4.0和4.5。
光從數(shù)據(jù)的表面很難知道正確結(jié)果,但是推薦引擎可以通過一些絕妙的方法給出很有說服力的結(jié)果。如果你覺得這個(gè)小小的程序從一堆雜亂的數(shù)據(jù)中給出了有用而且不明顯的結(jié)果令你感到一陣愉悅的話,那么說明機(jī)器學(xué)習(xí)的世界是為你而存在的!
簡單的說,像上面的小數(shù)據(jù)對于構(gòu)建推薦系統(tǒng)是微不足道的。在現(xiàn)實(shí)生活中,數(shù)據(jù)是十分龐大的,而且充滿了噪音。例如,一個(gè)新聞網(wǎng)站為讀者推薦新聞文章。偏好 通過點(diǎn)擊數(shù)來計(jì)算,但是這樣得來的偏好指數(shù)很可能是假的——也許某個(gè)讀者點(diǎn)擊進(jìn)去發(fā)現(xiàn)自己不喜歡或者是點(diǎn)擊錯(cuò)誤才進(jìn)去的。也有可能很多的點(diǎn)擊操作是在登錄 之前發(fā)生的,這樣我們就不能把這些點(diǎn)擊數(shù)與某個(gè)用戶關(guān)聯(lián)起來。另外,你也可以試想一下數(shù)據(jù)量,很可能在一個(gè)月中會(huì)有上億計(jì)的點(diǎn)擊數(shù)。
高效準(zhǔn)確的從數(shù)據(jù)集中得出推薦結(jié)果是非常重要的。接下來我們將以案例研究的方式去呈現(xiàn)Mahout是如何解決這些問題的。這些案例將會(huì)展示為何一些標(biāo)準(zhǔn)方 法會(huì)產(chǎn)生非常差的結(jié)果,或者吃掉了很多內(nèi)存和CPU,另外也會(huì)展示如何去配置和自定義Mahout來提升它的性能。
本文版權(quán)歸黑馬程序員JavaEE學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!
首發(fā):http://java.itheima.com/