推荐系统在现代网站中常常用到,不一样类型的运营须要不一样的推荐策略,而且推荐策略须要简单易懂,能方便运维人员人工调整。本文以全文搜索引擎为例子讲解如何定制为一个推荐系统。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做为推荐的内容。