我的知识图谱入门笔记
Knowledge Graph
- 信息是指外部的客观事实。举例:这里有一瓶水,它现在是7°。
- 知识是对外部客观规律的归纳和总结。举例:水在零度的时候会结冰。
换句话说,知识图谱是由一条条知识组成,每条知识表示为一个SPO三元组(Subject-Predicate-Object)。
语义网络(Semantic Network)
语义网络由相互连接的节点和边组成,节点表示概念或者对象,边表示他们之间的关系(is-a关系,比如:猫是一种哺乳动物;part-of关系,比如:脊椎是哺乳动物的一部分)
。在表现形式上,语义网络和知识图谱相似,但语义网络更侧重于描述概念与概念之间的关系,(有点像生物的层次分类体系——界门纲目科属种),而知识图谱则更偏重于描述实体之间的关联。
RDF(Resoure Description Framework)
RDF(Resource Description Framework),即资源描述框架,是W3C制定的,用于描述实体/资源的标准数据模型。RDF图中一共有三种类型,International Resource Identifiers(IRIs),blank nodes 和 literals。下面是SPO每个部分的类型约束:
- Subject可以是IRI或blank node。可以理解为
URI
- Predicate是IRI。
- Object三种类型都可以。
也就是说字面量不能做主语?
将罗纳尔多的原名与中文名关联起来的RDF表示:
可见,主语的指代性要强很多,所以字面量(宾语)用作主语会丧失这种精确性(唯一性)。
- "
www.kg.com/person/1
"是一个IRI,用来唯一的表示“罗纳尔多”这个实体。"kg:chineseName"也是一个IRI,用来表示“中文名”这样一个属性。"kg:"是RDF文件中所定义的prefix,如下所示。 - @
prefix kg
: http://www.kg.com/ontology/ 即,kg:chineseName其实就是"http:// www.kg.com/ontology/chineseName"的缩写。
这样知识图谱的正确表示其实是:
2021-08-08-12-06-57.png而不是网传的简单的画几个对象连几根线,也就是说,能用URI表示的,尽量都用URI表示。
Identifying graph-shaped problems(应用场景)
-
does our problem involve understanding
relationships
between entities?- Recommendations
- Next best action
- Fraud detection
- Identity resolution
- Data lineage
-
does our problem involve a lot of
self-referencing
to the same type of entity?- Organisational hierachies
- Social influencers
- Friends of friends
- Churn detection
-
does the problem explore
relationships of varying or unknown depth
?- Supply chain visibility
- Bill of Materials(BOM)
- Network management
-
does our problem involve discovering lots of
different routers or paths
?- Logistics and routing
- Infrastructure management
- Dependency tracing
Neo4j
2021-08-08-01-41-17.png-
:person
,:Car
,:Vehicle
areLabel
- even
relationship
can also have(own) properties
AsciiArt
for Nodes
(p:Person:Mammal{name:'walker'})
for Relationships
- [:HIRED {type: 'fulltime'}] ->
CRUD
Create
2021-08-08-01-57-00.pngConstraints
CREATE CONSTRAINT ON (p:Person)
ASSERT p.name IS UNIQUE
所以如下语句会报错:
CREATE (a:Person {name: "Ann"})
CREATE (a) - [:HAS_PET] -> (:Dog {name: "Sam"})
要用merge
MERGE (a:Person {name: "Ann"})
CREATE (a) - [:HAS_PET] -> (:Dog {name: "Sam"})
Set
属性可以用JSON
格式写,也可以用SET
语法(下面的查询语句也是一样)
MERGE (a:Person {name: "Ann"})
ON CREATE SET
a.twitter = "@ann"
MERGE (a) - [:HAS_PET] -> (:Dog {name: "Sam"})
同时,看到了吗?create
只能出现一次(同一个对象的话)
Read
who drives a car owned by a lover?
MATCH
(p1:Person) - [:DRIVES] -> (c:Car) - [:OWNED_BY] -> (p2:Person) <- [:LOVES] - (P1)
RETURN
p1
其中,因为问的是lover,没有指向性,所以如果是两个互相相爱,后半截也可以是p2指向p1
match p = (n) -[*1..2] -> (m) where n.name='特朗普' return p
match p = ({name: '特朗普'}) - [*1..2] -> () return p # 简化
match p = (n)-[m]->(q) where m.name = '丈夫' return n,q skip 10 limit 5
match p = (n)-[:丈夫]->(q) return n,q skip 10 limit 5 # 简化
解读:
- 上面写法很简略,注意观察一下
- 又一次演示了直接用json来做where和单独用
where
关键字的写法区别(要多命名一个变量) - p跟n的区别,p是返了整个网络,如果
return n
,那么就是n自身(一个节点)。
4, 但是如果return n, m
,那么又把一层网络给select出来了 - [*1..2]表示跟踪两层
- 如果不需要对n,m进行where,set操作,可以不设置变量
-
relationship
也可以过滤,也有name等属性 -
limit
,skip
等用法
Tabular Results
MATCH (p:Person {name: "Tom Hanks"}) - [r:ACTED_IN|DIRECTED] -> (m:Movie)
RETURN p,r,m
RETURN p.name, type(r), m.title
前者返回Graph,后者返回表格数据
Update
P.S.
where
是对属性做限制,所以查询条件既可以写在属性里,也可以用where
语句来做过滤.
要对查询结果进行修改,用set
(有则改,无则加)
MATCH
(:Person {name: "张三"}) - [:LOVES] -> (p:Person)
RETURN
p
MATCH
(p1:Person) - [:LOVES] -> (p2:Person)
WHERE
p1.name = "张三"
SET
p2.age = 33 # set by property
# or
p2 += {age: 33, height: 180} # set by JSON
RETURN
p2
可以把Neo4j
理解为命名实体识别(NER
),即你创造一句话,为句子里的每个实体打上标签,然后你想要谁就用实体标签把它取出来。
比如“张三爱李四”:
step1: 写框架
CREATE () - [] -> ()
step2: 填节点和关联
CREATE (:Person {name: "张三"}) - [:LOVES] -> (:Person {name: "李四"})
而你要问张三爱谁:
MATCH
(:Person {name: "张三"}) - [:LOVES] -> (p:Person)
RETURN
p
看到查询语句了吗?除了CREATE
, MATCH
等关键词,句子顺序是完全一样的,也就是说,一直是在“陈述”一件事。
而事实上,这个NER
在知识图谱中表示为RDF
。
Delete
match p=(n) where n.name = '小明' detach delete n
Query
最短距离
MATCH
(martin:Person {name: 'Martin Sheen'}),
(oliver:Person {name: 'Oliver Stone'}),
p = shortestPath((martin)-[*..15]-(oliver)) # 1
p = allShortestPath(....) # 2
WHERE none(r IN relationships(p) WHERE type(r) = 'FATHER') # 3
RETURN p
- 限定了15层
- Finds
all
the shortest paths between two nodes. - 排除了关系
type
为FATHER的
给你们看一下一个relationships
长啥样:
{
"identity": 36629,
"start": 31343,
"end": 33922,
"type": "author->title",
"properties": {
"name": "author->title"
}
}
模糊匹配(%)
match p = (a)-[*1..2]->(b:content) where a.name = '李白' and b.name =~ '.*明月.*' return a,b
.*
就相当于sql里的%
吧
get by id
MATCH (n)
WHERE id(n) IN [0, 3, 5]
RETURN n
- id(n) -> search with id
- multiple id use
in
outer join (optional relationships)
match (a:author {name:'李白'})
optional match (a)-->(b)
return b
在实例中,b包含了两种实例:
- title
- introduce
等同于sql中user表outer join了两个表(title, introduce)