基于用户(user-based)的协同过滤推荐算法的初步理解以及代码实现
2017-08-04 18:21
856 查看
总论
算法基础实现
到这里,已经可以获得相似用户了。
Mahout实现
源码解析
协同过滤是目前最经典的推荐算法。 分而理之,协同,指通过在线数据找到用户可能喜欢的物品;过滤,滤掉一些不值得推荐的数据。 协同过滤推荐分为三种类型。第一种是基于用户(user-based)的协同过滤,第二种是基于项目(item-based)的协同过滤,第三种是基于模型(model based)的协同过滤。 我认为,选择哪种类型,取决于业务场景。需要考虑的是,user和item的数量比,谁的数量级小就选择哪个模式的cf;在业务处于的场景中,user和item的多变性比较,选择多变性较小的一方,在后续的维护,会方便很多;最后一点,明确你的推荐覆盖要求。 今天主要讲基于用户。 凡是推荐算法离不开大数据的基础,基于用户类型的数据一般是如下格式: 用户id,外物id,用户对外物的评分,以上是一般物联网的算法模型,(举一反三,分析系统日志,建立如下模型,用户id,资源id,用户对资源的访问次数,--->实现推荐页面 )
算法基础实现
看这块的时候,我是真的后悔大学没好好学数学!!! 首先让我们拆分下过程。 基于用户的协同过滤 可分为2步, 1.找到相似度高的用户 2.根据1步骤获取的信息,推荐源用户相对喜欢,并且未采取过的行为
下面这个是大名鼎鼎的Jaccard公式,很简单, 取2个用户的选择集的交集,跟2个用户的选择集的并集,进行计算。但很显然,若要计算整个用户集合, 时间复杂度是O(n^2),太慢了。
后续就有了利用倒排查表进行优化如下: 可以建立个5X5矩阵,以用户、行为为维度。
行为 用户 1 1,2,3 2 2,3,5 3 1,3,5 4 3,4,5 5 2,3,4
到这里,已经可以获得相似用户了。
下面这个公式可以完成之前提到的步骤二,p(u,i)-用户u对行为i的权重,S(u,k)表示和用户u相似的K个用户,N(i)表示采取过行为i的用户集合,Wuv表示用户u和用户v的相似度,Rvi表示用户v对行为i的权重。 Rvi部分可以大做文章,用户对某个行为的权重值定义,需要以业务为基础。在这里举个例子,如果某个行为在整个用户群里执行的次数不多,但某两个用户多次执行,可判断这两个用户对该行为权重极大,也就是对该行为兴趣浓厚,也就是这两个用户极其得相似,我把这个现象称为,单热群冷现象。
算法数学总结到此结束,感觉数学功底是真的差,上面那个公式看了半天,后来还是咨询了大学里数学师父~~~
Mahout实现
Mahout是hadoop全家桶里的一员,提供一些可扩展的机器学习领域经典算法的实现,旨在帮助开发人员更加方便快捷地创建智能应用程序。 之前说的一大堆,其实开发中,都是用不到的,它已经在它的库里给你实现了~~直接上代码,代码也很简单。
public class MahoutTest { public static void main(String[] args) throws IOException, TasteException { String file = "D:\\test.txt"; //模型建立 DataModel model = new FileDataModel(new File(file)); //根据模型获取userId迭代器 LongPrimitiveIterator iter = model.getUserIDs(); UserSimilarity user = new EuclideanDistanceSimilarity(model); //2代表--限制在模型中的用户数量 NearestNUserNeighborhood neighbor = new NearestNUserNeighborhood(2, user, model); Recommender r = new GenericUserBasedRecommender(model, neighbor, user); while (iter.hasNext()) { long uid = iter.nextLong(); //3代表--所需要的行为数 List<RecommendedItem> list = r.recommend(uid, 3); System.out.printf("uid:%s", uid); for (RecommendedItem ritem : list) { System.out.printf("(%s,%f)", ritem.getItemID(), ritem.getValue()); } System.out.println(); } } }
源码解析
核心类如下,粗略讲一下我这里用到的genericUserBasedRecommender
与上图代码顺序一致 1.校验传参 2.获取相似用户id 3.获取相似用户的所有行为信息 4.获取评估信息 5.获取结果集 getTopItems方法如下
public static List<RecommendedItem> getTopItems(int howMany, LongPrimitiveIterator possibleItemIDs, IDRescorer rescorer, Estimator<Long> estimator) throws TasteException { Preconditions.checkArgument(possibleItemIDs != null, "argument is null"); Preconditions.checkArgument(estimator != null, "argument is null"); Queue<RecommendedItem> topItems = new PriorityQueue<RecommendedItem>(howMany + 1, Collections.reverseOrder(ByValueRecommendedItemComparator.getInstance())); boolean full = false; double lowestTopValue = Double.NEGATIVE_INFINITY; while (possibleItemIDs.hasNext()) { long itemID = possibleItemIDs.next(); if (rescorer == null || !rescorer.isFiltered(itemID)) { double preference; try { preference = estimator.estimate(itemID); } catch (NoSuchItemException nsie) { continue; } double rescoredPref = rescorer == null ? preference : rescorer.rescore(itemID, preference); if (!Double.isNaN(rescoredPref) && (!full || rescoredPref > lowestTopValue)) { topItems.add(new GenericRecommendedItem(itemID, (float) rescoredPref)); if (full) { topItems.poll(); } else if (topItems.size() > howMany) { full = true; topItems.poll(); } lowestTopValue = topItems.peek().getValue(); } } } int size = topItems.size(); if (size == 0) { return Collections.emptyList(); } List<RecommendedItem> result = Lists.newArrayListWithCapacity(size); result.addAll(topItems); Collections.sort(result, ByValueRecommendedItemComparator.getInstance()); return result; }
这里用了PriorityQueue,利用了其特殊构造函数 指定比较器,指定初始容量。 public PriorityQueue(int initialCapacity, Comparator<? super E> comparator) { if (initialCapacity < 1) throw new IllegalArgumentException(); this.queue = new Object[initialCapacity]; this.comparator = comparator; } 查看了优先级队列的源码,其本质是:PriorityQueue会对入队的元素进行排序,所以在队列顶端的总是最小的元素。
end!
相关文章推荐
- 基于用户的协同过滤推荐算法java实现(UserCF)
- Java编程实现基于用户的协同过滤推荐算法代码示例
- 基于用户最近邻模型的协同过滤算法的Python代码实现
- 基于用户的协同过滤推荐算法原理和实现
- 基于用户的协同过滤推荐算法原理和实现
- 【推荐系统实战】:C++实现基于用户的协同过滤(UserCollaborativeFilter)
- ViewPager实现自动翻页功能 --转载出处找不到了,根据自己的理解写个随笔方便以后的记忆以及代码的共享,感谢给我启发的那位高手--第一次写博客哈
- JavaWeb实现用户登录注册功能实例代码(基于Servlet+JSP+JavaBean模式)
- 基于maven通过spring mvc实现简单用户登录代码下载
- 基于用户的协同过滤推荐算法原理和实现
- 在C#代码中实现在Sqlserver2000中添加用户以及附加数据库
- 基于用户的协同过滤推荐算法原理和实现
- 基于用户的协同过滤推荐算法原理和实现
- 基于用户的协同过滤和基于物品的协同过滤推荐算法原理和实现
- 基于用户的协同过滤推荐算法原理和实现
- 基于cxf实现的webservice,全程开发指南和笔记,以及代码
- c语言部分库函数,代码实现,以及细节理解
- 基于用户的协同过滤推荐算法原理和实现
- 基于用户的协同过滤(UserBased Recommendation)
- 如何在C#代码中实现在Sqlserver2000中添加用户?以及附加数据库?