推薦系統在現代網站中常常用到,不一樣類型的運營須要不一樣的推薦策略,而且推薦策略須要簡單易懂,能方便運維人員人工調整。本文以全文搜索引擎爲例子講解如何定製爲一個推薦系統。html
###基本原理 推薦系統的基本原理是先把相關的產品項分析出來,如java
"male age18 1000 1010 1020 ..."
這裏的"1000 1010 1020"是產品的ID。當有一個18歲男性用戶關注了"1000 1020"這兩個產品,就以條件git
"male age18 1000 1020"
進行搜索,取得包括這所有條件的文本,而後把"1010"這個產品推薦給用戶。github
###實時推薦 有些有熱度的關聯產品只有幾天的時間,過了後關聯性就迅速減弱,這時須要實時推薦。實時推薦的原理是把每一個用戶當天(或者最近幾天)花長時間瀏覽的產品記錄下來,當新用戶也在看類似的產品時,把前面幾個看相同產品的用戶的關注推薦給新用戶算法
####代碼實現 這些功能可使用一個全文搜索引擎實現,以FTServer使用的引擎爲例,當用戶關注一個產品時,把產品做爲文本內容,把用戶做爲文本ID,生成搜索索引dailyEngine.indexText(),這個索引至關於一個複合主鍵(產品-用戶),每關注一個新產品,調用一次FavorWhenStay10Sec(),這個函數除了有包括生成搜索索引的代碼indexText(),還有一個iBoxDB數據庫的**insert()**操做,用於記錄用戶的關注數據庫
private static void FavorWhenStay10Sec(Engine dailyEngine, AutoBox autoDaily, long userId, long itemId) { try (Box box = autoDaily.cube()) { box.d("/Favor").insert(new Favor(userId, itemId)); dailyEngine.indexText(box, userId, Long.toString(itemId)); box.commit(); } }
當有新用戶關注了"1055 1058"兩個產品時,以這兩個產品爲全文搜索關鍵字進行搜索運維
RealTimeRecommendPrint(engine, autoDaily, new long[]{1055, 1058});
經過dailyEngine.searchDistinct()查找方法,能夠取得關注相同產品的用戶(生成索引時設置的文本ID爲用戶ID)函數
for (KeyWord kw : dailyEngine.searchDistinct(box, sb.toString(), startId, HowManyUsersAsReference)) { long userId = kw.getID(); .... }
而後把有相同愛好用戶的關注推薦給新用戶網站
for (Favor favor : box.select(Favor.class, "from /Favor where userId == ?", userId)) { System.out.print(favor.itemId + ","); }
這裏的HowManyUsersAsReference設置返回的用戶個數,由於作實時推薦,不少時候不須要取所有相同愛好的用戶。搜索引擎
###深度推薦 當有了大量用戶關注數據後,就不須要以個別用戶組織數據,能夠定製各類算法分析產品的關聯,也能夠人工分析產品關聯,而後回到第一節關於基本原理的實現,具體實現代碼與直接調用全文搜索引擎同樣,把多個關聯產品的ID組成一個文本,而後輸入全文索引,推薦時當匹配到其中的產品ID,就把文本中關聯的其它產品ID做爲推薦的內容。