如何使用Freebase给非常大的未标记NLP数据集打标签?
我在使用的词汇:
名词短语 -- 指的是一个简短的短语,用来表示特定的人、地方或想法。比如“巴拉克·奥巴马”、“奥巴马”、“水瓶”、“黄石国家公园”、“谷歌浏览器”等等,都是名词短语的例子。
类别 -- 是一个语义概念,用来定义哪些名词短语属于这个类别,哪些不属于。比如,“政治家”、“家居用品”、“食物”、“人”、“运动队”等等都是类别的例子。所以,“巴拉克·奥巴马”属于“政治家”和“人”,但不属于“食物”或“运动队”。
我有一个非常大的未标记的自然语言处理(NLP)数据集,里面有数百万个名词短语。我想用Freebase来给这些名词短语打标签。我已经有了Freebase类型和我自己类别之间的对应关系。接下来我需要做的就是下载每一个Freebase类型的所有示例。
我面临的问题是需要弄清楚如何构建这种查询。在高层次上,这个查询应该问Freebase:“主题XX的所有示例是什么?”然后Freebase应该回答:“这是主题XX的所有示例的列表。”如果有人能告诉我这个查询的语法,我将非常感激。如果能用Python来实现,那就太好了 :)
2 个回答
这里提到的一个普遍问题叫做“实体链接”,这是自然语言处理中的一个概念。
顺便自我推荐一下:
可以看看我们书中的一章,里面介绍了这个主题以及如何进行大规模的实体链接。
http://cs.jhu.edu/~delip/entity_linking.pdf
@deliprao
这个查询的基本形式(比如说针对一个人)是
[{
"type":"/people/person",
"name":None,
"/common/topic/alias":[],
"limit":100
}]
你可以在这里找到相关的文档:http://wiki.freebase.com/wiki/MQL_Manual
使用 Python 库中的 freebase.mqlreaditer() 是浏览所有这些数据最简单的方法。在这个情况下,“limit”这个参数决定了查询时每次获取的数据量,但你会在 API 层面上逐个得到每个结果。
顺便问一下,你打算怎么区分总统杰克·肯尼迪、投手、足球运动员和书籍等不同的杰克·肯尼迪呢?http://www.freebase.com/search?limit=30&start=0&query=jack+kennedy 如果你能获取更多的信息(比如出生和死亡日期、书籍作者、其他类型等),可能会帮助你更好地区分这些不同的杰克·肯尼迪。
到了某个程度,直接使用大数据包而不是 API 可能会更简单或者更高效。你可以在这里查看相关信息:http://wiki.freebase.com/wiki/Data_dumps
编辑 - 这里有一个可以运行的 Python 程序,假设你有一个名为 'types.txt' 的文件,里面存放着类型 ID 的列表:
import freebase
f = file('types.txt')
for t in f:
t=t.strip()
q = [{'type':t,
'mid':None,
'name':None,
'/common/topic/alias':[],
'limit':500,
}]
for r in freebase.mqlreaditer(q):
print '\t'.join([t,r['mid'],r['name']]+r['/common/topic/alias'])
f.close()
如果你让查询变得复杂一些,可能需要降低 limit 的值,以免超时,但对于像这样的简单查询,把 limit 提高到 100 以上会让查询更高效,因为这样可以一次性获取更多的数据。