该项目从华为应用市场爬取 app 数据,存到 MongoDB 中,再经过推荐算法更新数据,展示到前端。项目综合了之前讲到的所有爬虫技巧,来源自 BitTiger 的组织。项目共分为 爬虫模块、推荐模块、网站模块 三部分。
技术需求文档
爬虫模块
从 http://appstore.huawei.com/more/all 爬取总排行榜所有APP数据
- Title
- AppId
- 缩略图
- 介绍
从 http://appstore.huawei.com/topics/ 爬取所有专题
每个专题包括
- Title
- AppId List
每个包含在专题中的APP,都爬取
- Title
- AppId
- 缩略图
- 介绍
从http://appstore.huawei.com/ 做为种子,抓取所有App信息
- App List的信息
- App 的信息
推荐模块
根据输入的App List,输出与这个List最相关的App List
- 基础数据:AppId List的集合
- 输入AppId List
- 输出AppId List
网站模块
首页 - A List of most popular Apps(类似于AppStore的Top Charts)
- Title
- 缩略图
- 介绍的前20个字符
详情页
- Title
- 缩略图
- 完整介绍
- 相关推荐的App List
爬虫模块
简介
Skill
- Python
- scrapy
- mongodb
- proxy
- scrapyjs
Performance
- 100 pages/second(vs 30k/second)
爬取
要点:
利用 Proxy 更换 user-agent
srcapy 发出请求的 user agent 的默认值为Scrapy/version,和普通浏览器的不同,所以网站就会识别出这不是真的用户而是爬虫,就会屏蔽这些请求。所以我们就使用 proxy 随机模拟了不同的 user agent 来“欺骗”网站,才能成功地爬取页面。这一部分是使用 Scrapy middleware 实现的。
博客利用 scrapy-redis 分布式架构加快爬取速度
博客怎样获取更多数据
- 通过相似 app
- 通过搜索
- 扩展链接
解析
涉及到 ‘下一页’ 的爬取,见爬虫总结-五-其他技巧 使用 scrapy-splash 部分的实例。
存储
文件
appstore.dat 存储基本信息,格式
id \t title \t intro
|
|
appstore_re.dat 存储推荐信息,格式
id \t url \t title \t recommended_appid
|
|
app_info.json 存储 app 所有信息
MongoDB
MongoDB 中新建 database appstore,新建 collections user_download_history 和 app_info,导入相应文件。
将文件导入 MongoDB。
$ mongoimport --db appstore --collection user_download_history --drop --file user_download_history.json $ mongoimport --db appstore --collection app_info --drop --file app_info.json
|
|
|
|
推荐模块
简介
Skill
- Python
- collaborative-filtering algorithm
- cosine_similarity
Performance
- 1 second/app(vs with 10ms/app)
推荐算法
协同过滤算法简述
基于用户的协同过滤算法(User CF)
强调 把和你有相似爱好的其他的用户的物品推荐给你
基于用户对物品的偏好找到相邻邻居用户,然后将邻居用户喜欢的推荐给当前用户。
过程:
- 将一个用户对所有物品的偏好作为一个向量来计算用户之间的相似度,找到和目标用户兴趣相似的用户集合;
- 找到这个集合中的用户喜欢的,且目标用户没有访问过的物品,计算得到一个排序的物品列表作为推荐。
优点和适用场景:
- 可以发现用户感兴趣的热门物品
- 用户有新行为,不一定造成推荐结果的立即变化
- 适用于用户较少的场合,否则用户相似度矩阵计算代价很大
- 适合时效性较强,用户个性化兴趣不太明显的领域
缺点:
- 数据稀疏性。一个大型的电子商务推荐系统一般有非常多的物品,用户可能买的其中不到1%的物品,不同用户之间买的物品重叠性较低,导致算法无法找到一个用户的邻居,即偏好相似的用户。
- 算法扩展性。最近邻居算法的计算量随着用户和物品数量的增加而增加,不适合数据量大的情况使用。
- 对新用户不友好,对新物品友好,因为用户相似度矩阵不能实时计算
- 很难提供令用户信服的推荐解释
基于物品的协同过滤算法
强调 把和你喜欢的物品相似的物品推荐给你
基于物品的 CF 的原理和基于用户的 CF 类似,只是在计算邻居时采用物品本身,而不是从用户的角度。在京东、天猫上看到「购买了该商品的用户也经常购买的其他商品」,就是主要基于 ItemBasedCF。
过程:
- 基于用户对物品的偏好计算相似度,找到相似的物品;
- 根据物品的相似度和用户的历史行为预测当前用户还没有表示偏好的物品,计算得到一个排序的物品列表作为推荐。
因为物品直接的相似性相对比较固定,所以可以预先在线下计算好不同物品之间的相似度,把结果存在表中,当推荐时进行查表,计算用户可能的打分值。
优点和适用场景:
- 可以发现用户潜在的但自己尚未发现的兴趣爱好
- 有效的进行长尾挖掘
- 利用用户的历史行为给用户做推荐解释,使用户比较信服
- 适用于物品数明显小于用户数的场合,否则物品相似度矩阵计算代价很大
- 适合长尾物品丰富,用户个性化需求强的领域
缺点:
- 对新用户友好,对新物品不友好,因为物品相似度矩阵不需要很强的实时性
Item CF 和 User CF 是基于协同过滤推荐的两个最基本的算法,大家都觉得 Item CF 从性能和复杂度上比 User CF 更优,其中的一个主要原因就是对于一个在线网站,用户的数量往往大大超过物品的数量,同时物品的数据相对稳定,因此计算物品的相似度不但计算量较小,但这种情况只适应于提供商品的电子商务网站,对于新闻,博客或者微内容的推荐系统,情况往往是相反的,物品的数量是海量的,同时也是更新频繁的,所以单从复杂度的角度,这两个算法在不同的系统中各有优势,推荐引擎的设计者需要根据自己应用的特点选择更加合适的算法。
两个例子:
非社交网络:在非社交网络的网站中,内容内在的联系是很重要的推荐原则,它比基于相似用户的推荐原则更加有效。比如在购书网站上,当你看一本书的时候,推荐引擎会给你推荐相关的书籍,这个推荐的重要性远远超过了网站首页对该用户的综合推荐。可以看到,在这种情况下,Item CF 的推荐成为了引导用户浏览的重要手段。同时 Item CF 便于为推荐做出解释,在一个非社交网络的网站中,给某个用户推荐一本书,因为这本书和你以前看的某本书相似,用户可能就觉得合理而采纳了此推荐。
社交网络:在现今很流行的社交网络站点中,User CF 是一个更不错的选择,User CF 加上社会网络信息,可以增加用户对推荐解释的信服程度。
项目算法
采用的是基于物品的协同过滤算法,相似度算法用的是 cosine similarity。通过计算 similarity between a1 and all user download history 来推导 similarity between a1 and all other apps,前提是假定每个 user download history list 里的 app 是相互关联的。看下面的具体例子。
cosine similarity
similarity between a3 and a5
a3’s top-5 related apps
实现
首先读取 MongoDB 的数据,过程略。这里主要展示算法实现。
cosine similarity
top-5 related app_list1
最后要更新 MongoDB 中的数据。更新后的数据如下
网站模块
Skill
- javascript
- node.js
- meteor
- mongodb
Performance
- 1k QPS (vs 10k QPS)