知识图谱三元组关系的抽取

最近在研究关系抽取,由于人工标注太麻烦,所以想用远程监督生成更多数据。那么就必须找相对准确的关系模式,比如在已有知识图谱关系三元组,这就涉及到知识图谱三元组抽取了。其实,也可以人工定制少量的准确的关系三元组作为远程监督的种子,不过太麻烦了。

在线查看(以wikidata知识图谱为例)

得到和用户输入有关的实体id

https://www.wikidata.org/w/api.php?action=wbsearchentities&search=Fudan&language=en&limit=20&format=json

实体信息获取

https://www.wikidata.org/w/api.php?action=wbgetentities&ids=Q495015&format=json&languages=en

entity顶级字段:

id: 实体id。

type: 实体类型。

labels: 不同语言描述的实体标签。

descriptions: 不同语言的实体描述。

aliases: 不同语言描述的实体别名。

claims: 以属性分组的实体声明(claims)或者陈述(statements)。

sitelinks: 各种网站上关于此实体的描述。

lastrevid: 当前json文件的版本。

modified: 当前json文件的发布日期。

而entity中的具体数据被称为claim,一个entity可以有许多
claim.每个claim总是与一个属性(property)关联,并且在一个实体中可以有多条claim与同一property关联。从结果可以看出,P109属性的结构
[ { },{ },……],是一个Json数组,对应到维基数据上:

左侧栏目定义了属性,右侧是与该属性关联的claims,可以有一个,也可以有多个。

id: 识别码,只能保证当前数据库中唯一,不包含其他信息。

type: claim的类型,目前只有statement和claim两种。

mainsnak:
如果claim含有type值,那么它具有mainsnak字段包含与property相关的主体信息。注意:mainsnak中的datavalue也可以为其它关联实体(提供实体id)

rank: 表示claim是否应该显示在查询结果中,为preferred, normal 或者 deprecated.

qualifiers:
修饰信息,一般为主体信息的上下文信息,每一条都与一个属性(property)关联。

references: 如果claim是statement,那么会有一个参考资料的列表。

属性详情查看

https://www.wikidata.org/wiki/Property:P580

参考网站:https://www.ibm.com/developerworks/cn/java/j-sparql/\#fig1

解析RDF数据得到语义Net

RDF图模式解析

主题是节点,谓词是圆弧,值在圆弧的另一边

需要将我的生日发布为一个机器可以处理的事实,可以使用一个称为 N-Triples
的简单的 RDF
序列化,将语句存储到一个文件中。采用这种格式时,每行都有一个用句点终止的事实如下:

\https://w3id.org/people/bsletten\\http://xmlns.com/foaf/0.1/birthday\
“05-26”

\https://w3id.org/people/bsletten\ \http://xmlns.com/foaf/0.1/name\
“Brian Sletten”

不管这两个事实是存储在同一个文件中,还是存储在两个不同的文件中,如果它们被读入相同的模型中,那么属性和值将会针对主题进行累积(如图
3 所示),因为这两个语句引用了使用相同标示符的同一个主题。

\https://w3id.org/people/bsletten\ \http://xmlns.com/foaf/0.1/birthday\
“05-26”

\https://w3id.org/people/bsletten\ \http://xmlns.com/foaf/0.1/name\
“Brian Sletten”

如何定义实例所属关系:需要一个特殊的谓词来表明资源是某个类的一个实例。RDF
为这种类型的关系提供了一个术语:http://www.w3.org/1999/02/22-rdf-syntax-ns\#type。这种类型的语句具有与您目前为止看到的属性关系不同的语义,但表达方式是相同的:

\https://w3id.org/people/bsletten\\http://www.w3.org/1999/02/22-rdf-syntax-ns\#type\ \http://xmlns.com/foaf/0.1/Person\
.

所以,最后的N-triples描述文件如:

\https://w3id.org/people/bsletten\ \http://xmlns.com/foaf/0.1/birthday\
“05-26”

\https://w3id.org/people/bsletten\ \http://xmlns.com/foaf/0.1/name\
“Brian Sletten”

\https://w3id.org/people/bsletten\\http://www.w3.org/1999/02/22-rdf-syntax-ns\#type\ \http://xmlns.com/foaf/0.1/Person\

应用

数据如下所示:

基础查询:sparql –query query.rq –data basic.nt

在 RDF
中,节点转换为主语实体,连接到属性的圆弧将它们连接到图形中的其他节点。

找到指定图形模式中的主语:主语通过uri指定

SELECT ?p ?o WHERE { \https://w3id.org/people/mcarducci\ ?p ?o }

找到一个主语标识符:

PREFIX foaf: \http://xmlns.com/foaf/0.1/\

SELECT ?s WHERE { ?s foaf:name “Michael Carducci” }

在知道要使用哪个标识符后,您可以运行之前的查询来获取 Michael 的信息,如下:

PREFIX foaf: \http://xmlns.com/foaf/0.1/\

SELECT ?p ?o

Where

{

?s foaf:name "Michael Carducci" ;
?p ?o .

}

上面的 ?s foaf:name “Michael Carducci”
;必须要写,因为要先匹配到该模式后,再选择?p ?o 作为输出。

查询多个数据集

通过 foaf:knows 关系将 Brian 的节点连接到 Michael 的节点

PREFIX ex: \http://example.com/ns/\

PREFIX foaf: \http://xmlns.com/foaf/0.1/\

SELECT ?magician ?name

WHERE {

?s foaf:name "Brian Sletten" ;
foaf:knows ?magician .
?magician a ex:Magician ;
foaf:name ?name .

}

告诉我任何 (?s) 名叫 Brian Sletten
的人,这个人需要知道某个是 ex:Magician 类的实例 (?magician)
的人。另外,获取另一个人的姓名。查询过程如下:先匹配模式?s foaf:name
“Brian Sletten” ;并且可以连接Michael (foaf:knows
?magician)的节点的ex:Magician类型(?magician a
ex:Magician),才算匹配成功,并且返回其name值。

PREFIX foaf: \http://xmlns.com/foaf/0.1/\

SELECT ?url

FROM \<bloggers.rdf>

WHERE {

?contributor foaf:name "Jon Foobar" .
?contributor foaf:weblog ?url .

}

第一个三元组与 foaf:name 属性为“Jon
Foobar”的节点匹配,并且赋给contributor相应的值。在 bloggers.rdf
模型中,contributor 会和顶部的空节点id123456匹配。图形模式的第二个三元组与 contributor 的 foaf:weblog 属性对应的对象匹配。要两个模式同时匹配才算成功,最后返回url的值。

可选匹配

可选块 定义了附加图形模式,即使模式不匹配,不会造成结果被拒绝,但在匹配的时候,图形模式会被绑定到图形上

替换匹配

替换匹配的定义方式是写出多个替换图形模式,中间用 UNION 关键字连接

值约束条件

SPARQL
中的 FILTER 关键字对绑定变量的值进行约束,从而限制查询的结果。这些值约束条件是对布尔值进行计算的逻辑表达式,并且可以与逻辑操作符 && 和 ||组合使用

查找包含某个模式的图

使用 GRAPH 的另一种方法是在它后面跟一个未绑定变量。在这种情况下,图形模式被应用到查询可以使用的每个命名图中。如果模式和其中一个命名图匹配,那么这个图的
URI 就被绑定到 GRAPH 的变量上

其他:

查询所有属性

查询一个类的所有子类

查询一个类的所有超类

查询一个属性的子属性

列出一个类的所有属性

使用FILTER正则匹配:FILTER regex(?x, “pattern” [, “flags”])

SELECT DISTINCT ?p

Where {

?p a rdf:Property.

?s ?p ?o.

FILTER (REGEX(str(?p), “date”, “i”)) #
“i”代表大小写不敏感,匹配?p中出现date

}

聚合语句的写法(显示配偶信息大于1条的演员)

SELECT ?s, (COUNT(?s) AS ?cnt)

{

?s a ont:Actor.

?s prop:spouse ?o.

FILTER(isLiteral(?o))

}

GROUP BY ?s

HAVING (COUNT(?s) > 1)