学术分享搜索平台——中期报告
一、 项目概况
学术分享搜索引擎主要基于爬取的学术数据,提供搜索,可视化,推荐三大块功能,并且支持用户分享感兴趣的学术资源,结合“众包”来打造一个更社交化的学术搜索平台。相比于传统的学术搜索,可视化和用户的加入能让平台帮助用户发现更多的东西。
我的工作是整个平台的开发和搭建。从数据上说,涵盖了数据爬取,数据处理,分布式存储,建立索引等工作;从功能上说,涵盖了网站搭建,搜索服务,可视化模块,推荐功能,以及用户的登录、注册、分享模块的实现。
从底层数据,项目管理一直到上层功能,我的工作从爬取的大量元数据入手,打通并综合了搜索,推荐,可视化几大块内容。从技术角度看,该平台整合了不少技术和必要的开源工具,工作量比较大,整体实现难度不低;从平台价值看,可视化和社交化,以及众包的结合,具备一定创新性和前沿性;从工程角度看,这一个平台是一个实际可投入使用的项目,代码管理依托Github,单点登录又整合了企业级解决方案CAS,平台的开发具备专业性。
下图是整个系统的架构图,比较清晰地描述了底层数据,后台模块,各块服务之间的逻辑交互。我需要实现的模块和功能也都涵盖在了图中。
图0 系统总体架构图
二、 工作成果及水平
1. 已完成工作
从着手开发到现在,目前已经实现的工作有:数据的爬取、存储和处理,索引服务的建立,网站前后台的搭建,搜索功能的实现,可视化功能的实现,单点登录服务,用户注册、登录、收藏模块的实现。
整个项目的代码管理托管在Github上,所以项目开发情况和commit历史都在我的Github项目地址( https://github.com/pelick/VerticleSearchEngine)上可以直接看到。
图1 Github项目截图
截至到5.3日,总共提交了52次commit,里面详细记录了每次提交的修改记录和开发进度。
2. 数据爬取及存储
我的数据主要从微软学术搜索( http://academic.research.microsoft.com/)爬取,定制了python的开源爬虫Scrapy来做数据的爬取。爬虫主要通过XPath获取指定的内容。爬取的数据存在自己搭建的MongoDB集群里。目前爬取的学者数目为十万,论文元数据五十四万,并额外爬取了一万多位学者的个人主页和一万多份带有pdf下载url的论文。
图2 爬取数据统计
学者的元数据主要包括了他的name,Homepage的url,研究领域field,工作地,具体publication获取地址(会单独爬取存在publications里),从其发表的论文提取出来的关键词集合tags。
图3 学者的元数据存储格式及内容
论文的元数据存储主要包括了title,会议/期刊,作者,摘要以及它的可浏览或者可下载的url链接。
图4 论文的元数据存储格式及内容
这些数据都存储在我的MongoDB集群里,用Replica Set保证了单个分片上数据的容错,用多个分片的部署保证了数据存取的负载均衡以及数据存储的可扩展性,避免单个collection内数据量过大影响读取性能。更多关于MongoDB单机,主从,分布式部署的内容详细记录在了我的一篇博文里。
详见( http://blog.csdn.net/zbf8441372/article/details/8644116)
图5 MongoDB分片集群部署
我还额外批量下载了一部分带有pdf链接的论文,存在本地文件系统内,通过Tika提取和分析pdf文本内容,一方面建立了这些论文的全文索引,提供搜索;另一方面可以粗糙地分割出论文里标题、介绍、正文、总结、引用几块内容,而这样的相对结构化的文本内容可以进一步提供基于论文全文的相关研究工作。
图6 下载到本地文件系统的论文
3. 索引服务
我通过Lucene对MongoDB中爬取的数据建立索引,通过单独开启一个Tomcat容器 (端口为9080) 来搭建Solr搜索服务。平台后台通过Solrj访问Solr Server,支撑几乎所有搜索请求。Solr服务的配置是multicore的配置,即多份配置文件对应多份索引文件,提供不同的搜索服务,core0对应学者元数据,core1对应论文元数据,core2对应论文全文。具体的搜索结果就不截图展示了。
图7 Solr Admin
4. 平台展示
网站的前后台都由我一人完成。基于J2EE的一些网站开发技术,后台采用的是Struts2,前台主要采用的是Jquery,Bootstrap和D3这个可视化库,也涉及到了CSS3和HTML5的技术。下面具体展示一下目前各个页面。
主页
图8,9 主页
搜索页(学者)
左侧展示的是搜索结果中学者的领域和工作地统计,方便用户缩小检索范围。中栏展示了相关学者的基本信息,包括姓名,工作地,研究领域,个人主页链接。
图10 学者搜索
搜索页(论文)
搜索结果里展现了相关论文的标题,作者,摘要,会议/期刊,链接。
图11 论文搜索
搜索页(全文)
图12 全文搜索
学者主页
目前学者主页主要展示三部分内容,最上面一栏是学者相关信息:姓名、个人主页、工作地、研究领域。中间一栏是标签云,内容源自于我爬取的所有他参与发表的论文的标题和摘要切分词结果。下面一栏是论文列表。
图13 学者主页:个人信息及标签云
图14 学者主页:论文列表
发现页
发现页借助可视化效果,提供了比较有趣的学者共生关系发现检索。目的是通过不同维度的检索方式,用可视化展现学者之间共同发表论文的共生关系。
现在主要提供四种发现检索方式来得到Coauther集合。第一种是检索学者姓名,系统会从底层数据中找到和该学者共同发表论文的其他学者;第二种是检索论文标题,得到所有相关论文的相关作者集合;第三种是研究领域检索,得到该领域的相关学者集合;第四种是工作地检索,得到同一工作地的学者集合。
图15 发现页检索示例
下图以检索学者姓名“Andrew Y. Ng”的可视化结果为例。左侧是可视化中的力导向图(Force-DirectedGraph)。每个点代表一位学者,点与点之间的连线代表两位学者共同发表论文,且连线越粗,代表共同发表论文次数越多。右侧是一个共生矩阵(co-occurrence matrix),着色块代表两位作者共同发表过论文,颜色越深表示发表次数越多,图中显示Andrew Y. Ng与Pieter Abbeel,J. Zico Kolter有至少两次合作。此外,颜色还代表了工作地这一维度,比如Adam Coates,Andrew Y. Ng,Anna Petrovskaya在同一工作地工作。
图16 可视化展示
分享页(用户主页)
分享页是需要登录才能进入的用户主页。目前显示了用户注册时候登记的基本信息,主要包括姓名,邮件,感兴趣的领域,微博、Github、个人主页地址。同时,两个“Favor”栏里展现了用户在平台上的收藏历史。其他一些搜索,发现,分享等历史记录后续也考虑适当呈现出来。
分享页之后还会支持用户分享功能,而这些用户数据的记录和呈现将为推荐功能提供数据支持和推荐依据。
图17 用户主页
登录注册
用户登录模块考虑到本系统与项目其他系统的无缝结合,采用了一个企业级的开源解决方案——CAS,来实现了单点登录(SSO)。每次登录和登出都会跳转到CAS Server端做处理,校验成功后会自动跳转回跳转源并在传回来的session中保存已登录用户的基本信息。具体单点登录的实现细节会在下一章节里详细说明。
图18 提示登录页
图19 注册页
图20 单点登录跳转页
三、 项目收获
项目开发中,尝试使用Scrapy+MongoDB来做数据的爬取和存储,借用D3这个可视化库,结合CSS3和HTML5的一些元素来实现了几个可视化的demo,此外还使用CAS这个开源的企业级解决方案来实现了单点登录。
1. 数据的爬取和存储
第一次使用python的开源爬虫Scrapy来做学术数据的爬取。Python程序比较简短,而Scrapy基于优秀的twisted框架实现,多线程的问题也不需要开发者担心,我所要做的就是借助Scrapy,通过XPath的解析来提取出我想要的数据。爬到的数据最后是以json的格式输出的,考虑到学者,论文的元数据存储格式,我选择了更灵活的面向文档的NoSQL,即MongoDB来做爬虫数据的存取工作。
MongoDB是最易用的NoSQL,提供pymongo-driver支持python程序的数据库连接。MongoDB是面向文档的NoSQL,他的副本集和分片部署让存储更容错并且负载均衡,可扩容。在实践过程中,我搭建了MongoDB的分片集群,在Academic这个数据库中建立了Researchers,Publications等collections(类似MySQL里的table) 来存储Scrapy爬取的数据。
Scrapy和MongoDB的结合,除了满足我的需求外,很大一部分原因也是我兴趣使然。能尝试使用我感兴趣的技术并解决实际问题的确一举两得。
2. 可视化的实现
基于爬取并处理之后的大量数据,我做了可视化效果,试图通过更直观的展示发现学术资源里潜在的关系,例如学者和学者之间可以通过发表论文,工作地,研究领域产生一些共生关系或者合作关系。我使用了d3这个优秀的开源可视化库。D3全称为Data-Driven Documents,本质上还是js库,结合了CSS3,HTML5里的前端元素,把可视化效果做得比较炫比较酷。从他提供的example里我挑选了下面三个demo。
图21 力导向图
图22 共生矩阵图
图23 词云
我使用力导向图和共生矩阵来发现学者之间共同发表论文的关系,并额外结合了工作地这个维度。使用词云来给每位学者做一个类似tag的事情,词提取自他所发表的论文的标题和摘要文本内容。
3. 单点登录问题
整个平台始终是实验室知识中心项目的一部分,需要考虑到和别的平台的整合。关于数据的存取,界面的统一其实难度不大,关键是在用户管理这块上。因此,在项目开发过程中,我调研了OAuth和CAS两个解决方案,最后决定使用CAS来解决SSO(Single Sign On)。
所谓单点登录,就是要解决同一个系统中,不同模块,不同开发者之间统一登录,统一注销的问题。我使用的是耶鲁大学开源的CAS。解决思路是单独启动CASServer,让客户端(即各个其他模块)所有用户登录登出相关的操作跳转到这个server上,在完成登录登出操作后,跳转回跳转源,且能获得传回来的session内的登录用户的相关信息。具体CAS的原理我不再阐述,下图是知识中心解决单点登录问题的一个架构思路。
图24 知识中心单点登录解决方案
图中的SSO Server通过配置使其与MySQL里存储的用户信息做登录的校验,然后把成功登录的用户信息存到session里让客户端获取,而我们的应用或者服务都是一个个独立的CAS的客户端,当要登录登出的时候跳转到CAS Server就可以了,其余工作都一并交给Server完成。这样的解决思路让平台各个模块和服务的用户管理成功地无缝结合。
四、 存在问题
1. 数据问题
在体验“发现”模块的时候,我看到许多稀疏的点,两两之间的连线很少。一方面可能的确,不是说同一领域,同一工作地的学者就会相互之间有合作发表论文的习惯;另一方面也是由于我拥有的学者元数据相对于论文元数据来说是比较富裕的,很多学者的论文列表并没有爬取完整,导致论文信息其实不够齐全,学者数据相对比较充足。
2. 推荐功能
由于平台刚启动时没有用户,推荐服务无法依赖于用户之间的协同过滤,或者是基于用户收藏记录的论文之间的协同过滤。在推荐系统中这属于一个冷启动的问题。
冷启动问题一般有一些常见的解决思路。一方面,在用户注册的时候,需要用户填写感兴趣的领域,帮助系统在初始阶段给用户进行简单的基于内容类别的推荐。另一方面,在用户收藏感兴趣的学者或者论文的时候,需要提供标签,即做成UGC(User-generatedContent)来辅助系统推荐。
对于系统的推荐功能并不需要十分复杂,简单可行的推荐方式就可满足我的需求。我尝试了使用PageRank来在一堆论文数据中游走出一些我认为比较“主要”的论文排名。思路是基于论文之间的相似度计算,用哈希+余弦距离的方式定义论文之间的初始pagerank值,进行若干次迭代之后得到一个排序。实践之后还没有把它投入到系统排序模块里,还需要完善和进一步考虑。
针对推荐功能,我已经做了以下一些数据储备:每位学者都建立了一个tag向量,向量里的词来自于论文集合的标题和摘要切分词结果;每位用户的搜索,收藏,发现,分享记录都存在数据库中,以备任何推荐需求;用户注册需要填写感兴趣的领域,用户收藏需要为内容添加标签。