百度百科知识库构建 整体过程 李昊轩
Outline 页面爬取 信息抽取 实体链接
页面爬取 由于百度百科数据不提供下载,所以我们必须直接爬取百度百科的 每个词条页面。 困难: 突破百度百科的反爬虫措施 将正常页面重定向至error页面 要求验证码 屏蔽ip 充分利用网络IO资源 naive的同步式访问IO会导致网络IO的占用呈现波峰波谷的现象。 过快访问会导致百度百科的反爬虫措施出现地更频繁 为了解决上述困难,我们使用了Scrapy框架进行页面爬取。
Scrapy Scrapy是一个基于Python的网络爬虫框架 为什么使用Scrapy 关于Twisted 轻量灵活,高度可定制化 使用Twisted异步网络库提高了网络IO的使用效率 关于Twisted Twisted是一个Python实现的基于事件驱动的网络引擎框架。 当我们面对如下的环境时,事件驱动模型通常是一个好的选择: 程序中有许多任务 任务之间高度独立(因此它们不需要互相通信,或者等待彼此) 在等待事件到来时,某些任务会阻塞
事件驱动模型 在单线程同步模型中,任务按照顺序 执行。如果某个任务因为I/O而阻塞, 其他所有的任务都必须等待,直到它 完成之后它们才能依次执行。 在多线程版本中,这3个任务分别在 独立的线程中并行执行。这使得当某 个线程阻塞在某个资源的同时其他线 程得以继续执行。但程序员必须写代 码来保护共享资源,防止其被多个线 程同时访问。 在事件驱动版本的程序中,3个任务 交错执行,但仍然在一个单独的线程 控制中。当处理I/O或者其他昂贵的操 作时,注册一个回调到事件循环中, 然后当I/O操作完成时继续执行。程序 员不需要关心线程安全问题。
Scrapy Scrapy架构模仿基于MVT的Python Web框架Django。 Scrapy Engine 控制数据流处理流程与事务 处理的触发。 Scheduler 接受请求并排序列入队列并 返回请求。 Spider 用户定义的解析方法。 Item Pipeline 验证检查处理item Scrapy很多功能是用于网络爬虫的,我们并没有使用。这里主要介绍我们使用到的部分。
反反爬虫策略 动态设置user agent 禁用cookies 设置延迟下载 使用IP地址池( 代理IP) 增加一个设置user agent的中间件,每次请求都随机更换 一个 user agent 禁用cookies 设置延迟下载 防止Downloader并发请求过快 使用IP地址池( 代理IP) 增加一个设置代理的中间件,每次请求都随机更换一个代 理并且一段时间更新IP地址池
信息抽取 对20,000,000编号内的百度 百科页面进行爬取,共获得 了13,068,511个页面。 我们对这些页面抽取了以下 信息并结构化: Title & Subtitle Abstract Infobox Catalog & main text Section & paragraph Open tags Internal links Redirects
实体链接 将百度词条实体与DBpedia、Geonames进行链接 具体过程如下,输入为百度百科词条的url和title: 根据重定向信息扩展url得到url set 根据url set查询数据库得到subtitle set 对url set中每个url获取其别名得到name set 根据name set中的name将该百度百科词条链接到 DBpedia、Geonames 如果subtitle set非空则执行消歧义过程 url 根据重定向信息 拓展的url set 获取词条别名 name set 链接 entity set 查询数据库 subtitle set 消歧义
词条名称信息挖掘 百度百科词条的infobox中包含了比title更为丰富 的名称信息。 我们将百度百科词条infobox中的名称信息挖掘 出来构建了baidu name数据库。 主要方法是枚举infobox中表示名称的key。
获取词条别名 输入为url set 对于url set中的每个url,查询baidu name 数据库其和 title数据库构建key set 通过OpenCC繁简体转换扩展key set 通过 wikidata 的中英文 label 扩展key set 从key set中去掉长度过短的key title wikidata 中英文 label 长度过滤 url set 查询数据库 key set key set key set name OpenCC OpenCC
消歧义 在链接的过程中,以下的情况大量出现: 为了解决上述问题,我们在链接的最后一步进行 消歧义操作。 对于所有名叫“城关镇”的实体(精确匹配) 百度百科数据库中有143个 Dbpedia中有184个 Geonames中有22个 由此可见,同名实体在各个数据集中都比较多。此时 链接的结果为一个完全二部图,包含了大量的错误链 接,严重影响了结果的精度。 为了解决上述问题,我们在链接的最后一步进行 消歧义操作。
消歧义 消歧义的过程: 提取的特征目前比较简单: Geonames 对于每个链接 输出相似度最高的链接 百度百科词条 Dbpedia 提取当前词条与被链接实体的特征 计算特征之间的相似度 输出相似度最高的链接 提取的特征目前比较简单: 百度百科词条 title 和 subtitle (对于没有subtitle的词条,由于特征较少暂不处理) Dbpedia rdfs:label(包括处理消歧义项的括号与空格) Geonames gn:name 与 gn:alternateName parentFeature 的 gn:name 与 gn:alternateName
相似度计算 常见的计算字符串相似度的算法有 Levenshtein ratio Jaro Jaro Winkler Jacard (sum - ldist) / sum sum是指str1 和 str2 字串的长度总和 ldist是类编辑距离(替换产生的距离为2) Jaro m为str1,和str2的匹配长度 t是换位的数目 Jaro Winkler dj是两个str1 和 str2的Jaro Distance,是前缀的相同的长度,但是规定最大为4 p则是调整分数的常数,规定不能超过0.25 Jacard |S ∩ T| / |S ∪ T| Dice’s coefficient 2 * |S ∩ T| / (|S| + |T|) 戴斯相似性系数
消歧义 对于上述方法进行了小规模的测试,结果如下: 综上,在计算相似度的过程中使用Levenshtein ratio ratio的效果最好,Jacard和Dice’s coefficient其次。其 余方法几乎不可用。 综上,在计算相似度的过程中使用Levenshtein ratio 消歧义中具体用来计算相似度的方法: 对于输入的特征集合s1, s2 使用jieba对每个集合中的每个特征进行分词 去除停止词(空格、半角符号、全角符号等) 计算两个集合的最大匹配相似度作为集合间的相似度
链接结果 对提取的807,181百度百科地理相关词条进行链 接,其中 DBpedia Geonames 共有183,346个链接 共有166,054个链接 有91,004个不同的百度词条分别链接到100,391个不同的 Geonames实体
链接结果分析 对每个子分类随机抽取了10个链接人工进行校验 DBpedia Geonames 共抽取了780个链接 其中正确的链接有742个 精度约为95.13% Geonames 共抽取了689个链接 其中正确的链接有533个 精度约为77.36%
Thanks