知新溫故,從知識圖譜到圖數(shù)據(jù)庫
說到人工智能技術(shù),首先會聯(lián)想到深度學(xué)習(xí)、機(jī)器學(xué)習(xí)技術(shù);談到人工智能應(yīng)用,很可能會馬上想起語音助理、自動駕駛等等。實(shí)際上,人工智能要在行業(yè)中得到應(yīng)用的先決條件是首先要對行業(yè)建立起認(rèn)知,只有理解了行業(yè)和場景,才能真正智能化。簡單的說,就是要建立行業(yè)知識圖譜,才能給行業(yè)AI方案。
機(jī)器通過人工智能技術(shù)與用戶的互動,從中獲取數(shù)據(jù)、優(yōu)化算法,更重要的是構(gòu)建和完善知識圖譜,認(rèn)知和理解世界,進(jìn)而服務(wù)于這個(gè)世界。
那什么是知識圖譜呢?
知識圖譜
知識圖譜本質(zhì)上是語義網(wǎng)絡(luò)的知識庫,從實(shí)際應(yīng)用的角度出發(fā)其實(shí)可以簡單地把知識圖譜理解成多關(guān)系圖。
那什么是多關(guān)系圖呢? 回憶在數(shù)據(jù)結(jié)構(gòu)中的“圖”。圖是由節(jié)點(diǎn)和邊來構(gòu)成,通常用來描述某些事物之間的某種特定關(guān)系。圖用點(diǎn)代表事物,用連接兩點(diǎn)的邊表示相應(yīng)兩個(gè)事物間具有某種關(guān)系,但這些圖通常只包含一種類型的節(jié)點(diǎn)和邊,在IOTA,物聯(lián)網(wǎng)區(qū)塊鏈?一文中就談到了有向無環(huán)圖。多關(guān)系圖一般包含多種類型的節(jié)點(diǎn)和多種類型的邊。 圖的數(shù)學(xué)基礎(chǔ)是圖論,本身是應(yīng)用數(shù)學(xué)的一部分,在往下大概要涉及到拓?fù)鋵W(xué)的領(lǐng)域了。
在知識圖譜里,通常用“實(shí)體”來表達(dá)圖里的節(jié)點(diǎn)、用“關(guān)系”來表達(dá)圖里的“邊”。實(shí)體指的是現(xiàn)實(shí)世界中的事物,關(guān)系則用來表達(dá)不同實(shí)體之間的某種聯(lián)系,實(shí)體和關(guān)系也會擁有各自的屬性。知識圖譜的構(gòu)建是后續(xù)應(yīng)用的基礎(chǔ),而且構(gòu)建的前提是需要把數(shù)據(jù)從不同的數(shù)據(jù)源中抽取出來。數(shù)據(jù)抽取的難點(diǎn)在于處理非結(jié)構(gòu)化數(shù)據(jù),這回涉及到NLP中的相關(guān)技術(shù),例如實(shí)體命名識別、關(guān)系抽取、實(shí)體統(tǒng)一、指代消解等等。
知識圖譜工程本身還是業(yè)務(wù)為重心,以數(shù)據(jù)為中心。不要低估業(yè)務(wù)和數(shù)據(jù)的重要性。
知識圖譜最重要的核心在于對業(yè)務(wù)的理解以及對知識圖譜本身的設(shè)計(jì)。要從業(yè)務(wù)邏輯出發(fā),并且通過觀察知識圖譜的設(shè)計(jì)也很容易推測其背后業(yè)務(wù)的邏輯,而且設(shè)計(jì)時(shí)也要想好未來業(yè)務(wù)可能的變化。讓知識圖譜盡量輕量化、并決定哪些數(shù)據(jù)放在知識圖譜,哪些數(shù)據(jù)不需要放在知識圖譜,在于把知識圖譜設(shè)計(jì)成小而輕的存儲載體。
知識圖譜主要有兩種存儲方式:RDF和圖數(shù)據(jù)庫。它們之間的區(qū)別如下圖所示。RDF一個(gè)重要的設(shè)計(jì)原則是數(shù)據(jù)的易發(fā)布以及共享,圖數(shù)據(jù)庫則把重點(diǎn)放在了高效的圖查詢和搜索上。其次,RDF以三元組的方式來存儲數(shù)據(jù)而且不包含屬性信息,但圖數(shù)據(jù)庫一般以屬性圖為基本的表示形式,所以實(shí)體和關(guān)系可以包含屬性,這就意味著更容易表達(dá)現(xiàn)實(shí)的業(yè)務(wù)場景。
那為什么要用圖數(shù)據(jù)庫呢? 核心在于“關(guān)系”。
重新認(rèn)識“關(guān)系”
關(guān)系是指人與人之間,人與事物之間,事物與事物之間的相互聯(lián)系。
不同事物按著各種不同類型的關(guān)系而彼此聯(lián)系在一起,例如,空間與時(shí)間的關(guān)系,整體與部分的關(guān)系,原因與結(jié)果的關(guān)系,內(nèi)容與形式的關(guān)系以及遺傳關(guān)系、函數(shù)相依關(guān)系、內(nèi)部關(guān)系與外部關(guān)系等等。 數(shù)據(jù)結(jié)構(gòu)中的關(guān)系指的是集合中元素之間的某種相關(guān)性。關(guān)系的運(yùn)算包括集合的子,交,并,補(bǔ)等等。
在數(shù)學(xué)中,相關(guān)關(guān)系是一種非確定的相互依存關(guān)系:
- 按程度:完全相關(guān)、不完全相關(guān)和不相關(guān)
- 按影響: 正相關(guān)和負(fù)相關(guān)
- 按形式:線性相關(guān)和非線性相關(guān)
- 按變量數(shù)目:單相關(guān)、復(fù)相關(guān)和偏相關(guān)
- ......
事物之間的關(guān)系也是復(fù)雜的、無限多樣的。
在現(xiàn)實(shí)生活中,每一個(gè)實(shí)體都和周圍的其他實(shí)體有著千絲萬縷的關(guān)系,這些關(guān)系里面所存儲的信息甚至要大于實(shí)體本身的屬性。
但是數(shù)據(jù)庫有很多,為什么需要圖數(shù)據(jù)庫呢?關(guān)系型數(shù)據(jù)庫和眾多的NoSQL為什么不能完全擁有知識圖譜的構(gòu)建呢?
“關(guān)系”的數(shù)據(jù)庫存儲與表達(dá)
世界是由關(guān)系組成的,關(guān)系型數(shù)據(jù)庫能夠處理好關(guān)系嗎?
關(guān)系型數(shù)據(jù)庫
傳統(tǒng)的關(guān)系型數(shù)據(jù)庫更注重刻畫實(shí)體內(nèi)部的屬性,實(shí)體與實(shí)體之間的關(guān)系通常都是利用外鍵來實(shí)現(xiàn),將所有的數(shù)據(jù)用豎立的堆棧表示,并且保持它們直接的關(guān)系,在求解關(guān)系的時(shí)候通常需要join操作,而join操作通常又是耗時(shí)的。常常被優(yōu)化用于聚合數(shù)據(jù),而非高度關(guān)聯(lián)的數(shù)據(jù)。
互聯(lián)網(wǎng)尤其是移動互聯(lián)網(wǎng)的爆發(fā)式增長本來就使得傳統(tǒng)關(guān)系型數(shù)據(jù)庫不堪重負(fù),再加上諸如社交網(wǎng)絡(luò)等應(yīng)用對于關(guān)系的高需求,關(guān)系型數(shù)據(jù)庫顯得力不從心。
從應(yīng)用開發(fā)的角度上看,不增加關(guān)系型數(shù)據(jù)庫復(fù)雜性就不能建模和存儲數(shù)據(jù)和關(guān)系。隨著關(guān)系數(shù)量和層次的增加,數(shù)據(jù)庫尺寸的增加,性能降低。當(dāng)增加新類型的數(shù)據(jù)和關(guān)系的時(shí)候,需要重新設(shè)計(jì),增加了時(shí)間成本,這些導(dǎo)致傳統(tǒng)數(shù)據(jù)庫不適用于有實(shí)時(shí)價(jià)值的數(shù)據(jù)關(guān)系。
既然這樣,對于高度關(guān)聯(lián)的數(shù)據(jù)存儲與分析就需要求助于NoSQL了。
NoSQL
在NoSQL之于大數(shù)據(jù)一文中將NoSQL分為了4類:key-value,文檔型,列存儲和圖數(shù)據(jù)庫。
Key-Value模型適合用于簡單的數(shù)據(jù)或者列表。當(dāng)數(shù)據(jù)之間不斷交互關(guān)聯(lián)時(shí),實(shí)際上更需要一張圖。文檔型NoSQL用來管理文檔。在傳統(tǒng)的數(shù)據(jù)庫中,信息被分割成離散的數(shù)據(jù)段,而在文檔數(shù)據(jù)庫中,文檔是處理信息的基本單位。文檔可以很長,可以很復(fù)雜,可以是無結(jié)構(gòu)的,與字處理文檔類似。一個(gè)文檔相當(dāng)于關(guān)系數(shù)據(jù)庫中的一條記錄。文檔型NoSQL用文檔進(jìn)行層次劃分,而自由的數(shù)據(jù)規(guī)劃也很容易被表示成一顆樹。成長為一張圖的話,文檔之間的關(guān)聯(lián)需要更有代表性的數(shù)據(jù)結(jié)構(gòu)來存儲,列存儲的NoSQL也是如此。
從應(yīng)用開發(fā)的角度看,這些NoSQL數(shù)據(jù)庫不處理關(guān)系,沒有數(shù)據(jù)結(jié)構(gòu)建?;虼鎯?shù)據(jù)關(guān)系,沒有查詢結(jié)構(gòu)支持些數(shù)據(jù)關(guān)系。而且,在應(yīng)用中連接數(shù)據(jù)同樣需要JOIN操作, 對事務(wù)沒有 ACID 的支持。
ACID,指數(shù)據(jù)庫事務(wù)正確執(zhí)行的四個(gè)基本要素的縮寫。包含:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。
因此,這三種 NoSQL 數(shù)據(jù)庫也不適用于有實(shí)時(shí)價(jià)值的數(shù)據(jù)關(guān)系。
圖數(shù)據(jù)庫終于登場,它作為重點(diǎn)描述數(shù)據(jù)之間關(guān)系的數(shù)據(jù)庫應(yīng)運(yùn)而生,最適合處理關(guān)系,能夠制作從簡單到到復(fù)雜的數(shù)據(jù)結(jié)構(gòu)且互相連接的數(shù)據(jù)。圖數(shù)據(jù)庫成為了NoSQL中非常重要的一部分。
圖數(shù)據(jù)庫
圖數(shù)據(jù)庫是基于數(shù)學(xué)里圖論的思想和算法而實(shí)現(xiàn)的高效處理復(fù)雜關(guān)系網(wǎng)絡(luò)的數(shù)據(jù)庫。圖形數(shù)據(jù)庫善于高效處理大量的、復(fù)雜的、互連的、多變的數(shù)據(jù),計(jì)算效率遠(yuǎn)遠(yuǎn)高于傳統(tǒng)的關(guān)系型數(shù)據(jù)庫。
圖中每個(gè)節(jié)點(diǎn)代表一個(gè)對象,節(jié)點(diǎn)之間的連線代表對象之間的關(guān)系。節(jié)點(diǎn)可帶標(biāo)簽,節(jié)點(diǎn)和關(guān)系都可以帶若干屬性。關(guān)系可以將節(jié)點(diǎn)組織成任意的結(jié)構(gòu),允許一張圖被組織成一個(gè)列表,一棵樹,一張地圖,或者一個(gè)復(fù)雜的實(shí)體。這個(gè)實(shí)體本身也是由復(fù)雜的,關(guān)系高度關(guān)聯(lián)的結(jié)構(gòu)組成。
以圖數(shù)據(jù)庫Neo4J為例,用 Cypher 創(chuàng)建節(jié)點(diǎn)和關(guān)系的示意如下:
- CREATE (:Person { Name:“Abel Cao”} )-[:Love]-> (:Person { Name:“Andy Cao”} )
查詢也很簡單:
- MATCH (:Person { Name:“Abel Cao”} ) -[:Love]-> (:Person { Name:“Andy Cao”} )
一個(gè)節(jié)點(diǎn)可以從單屬性開始,成長為成千上億,雖然會有一點(diǎn)點(diǎn)麻煩。從某種意義上講,將數(shù)據(jù)用關(guān)系連接起來分布到不同節(jié)點(diǎn)上才是有意義的。對于通過某一給定的屬性值來找到節(jié)點(diǎn)或者關(guān)系,對比遍歷圖查找,用索引將會更加高效。
用圖來存儲數(shù)據(jù),是最接近高性能的一種用于存儲數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)方式之一。圖數(shù)據(jù)庫也有很多,常用且比較聞名的應(yīng)該是Neo4j了。
圖數(shù)據(jù)庫中的Neo4j
圖數(shù)據(jù)庫中的 Neo4j 是專為數(shù)據(jù)關(guān)系而生的,模型維護(hù)容易,白板模型即物理模型,查詢也較簡單,表映射關(guān)系變成了圖關(guān)系,使用較少的資源就可以獲得較高的性能。
用圖來表示社交網(wǎng)絡(luò)中人與人的關(guān)系
實(shí)際上,Neo4j最適合一個(gè)完整的企業(yè)部署或者用于一個(gè)輕量級項(xiàng)目中服務(wù)器的一個(gè)子集,有以下幾個(gè)顯著特特性:
ACID支持
ACID操作是保證數(shù)據(jù)一致性的基礎(chǔ)。Neo4j確保了在一個(gè)事務(wù)里面的多個(gè)操作同時(shí)發(fā)生,保證數(shù)據(jù)一致性。不管是采用嵌入模式還是多服務(wù)器集群部署,都支持這一特性。
高可用性
圖存儲可以非常輕松的集成到任何一個(gè)應(yīng)用中。隨著應(yīng)用在運(yùn)營中的不斷發(fā)展,性能問題肯定會逐步凸顯出來,而Neo4j不管應(yīng)用如何變化,只會受到計(jì)算機(jī)硬件性能的影響,而不受業(yè)務(wù)本身的約束。
輕松擴(kuò)展
可以擴(kuò)展到上億級別的節(jié)點(diǎn)和關(guān)系,部署一個(gè)neo4j服務(wù)器便可以承載上億級的節(jié)點(diǎn)和關(guān)系。當(dāng)單節(jié)點(diǎn)無法承載數(shù)據(jù)需求時(shí),可以進(jìn)行分布式集群部署。通常來講,對于10億節(jié)點(diǎn)以下規(guī)模的圖譜來說Neo4j已經(jīng)足夠了。
高速檢索
通過Neo4j提供的遍歷工具,可以非常高效的進(jìn)行數(shù)據(jù)檢索,每秒可以達(dá)到上億級的檢索量。
Neo4j的用戶包括電子港灣、必能寶、沃爾瑪、德國漢莎航空公司、思科、惠普、埃森哲等很多知名企業(yè)。
Neo4j編程概要
Neo4j是是一個(gè)嵌入式的、基于磁盤的、具備完全的事務(wù)特性的Java持久化引擎。主要有三種訪問Neo4j數(shù)據(jù)庫的方式:
嵌入式
通過指定數(shù)據(jù)庫地址直接訪問數(shù)據(jù)庫。
- new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);
REST API
通過請求API訪問數(shù)據(jù)庫。
- curl -D - -H Accept:application/json "http://neo4j:123456@localhost:8474/db/data/"
JDBC
通過Java API的方式訪問數(shù)據(jù)庫。
- DriverManager.getConnection("jdbc:neo4j:123456//localhost:8474/");
人生苦短,我用Python
應(yīng)用Python完成基于Neo4j的應(yīng)用,需要從http://py2neo.org/v3/安裝py2neo:
- 連接Neo4j
- mygraph = Graph(host='localhost', http_port=8474, https_port=8473, bolt_port=8687, username='Abel_Cao', password='xxxxxx')
- 創(chuàng)建節(jié)點(diǎn)和關(guān)系
- abel = Node('Person', name='Abel')
- zmx = Node('Person', name='Zmx')
- abel_love_zmx = Relationship(abel, 'Love', zmx)
- graph.create(abel_love_zmx)
- 修改屬性
- abel.properties['age'] = 47
- andy.properties['age'] = 17
- abel.push()
- andy.push()
- 查找節(jié)點(diǎn)或關(guān)系
- abel = graph.find_one(label='Person', property_key='name', property_value='Abel')
- zmx = graph.find_one(label='Person', property_key='name', property_value=’Zmx')
- abel_love_zmx= graph.match_one(start_node=abel, rel_type='Love’, end_node=zmx)
- 刪除節(jié)點(diǎn)、關(guān)系
- graph.delete(alice_knows_bob)
- graph.delete(alice)
- graph.delete(bob)
自定義查詢
- cursor = graph.run(Cipher_statement)
Cipher 簡要
簡單的類比一下,可以把Cipher查詢語言理解為SQL語句。
- 刪除節(jié)點(diǎn)、關(guān)系
- MATCH (abel:`Person` {name:"Abel"})-[abel_love_andy:`Love`]->(
- 查找路徑
- MATCH p=(abel:`Person` {name:"Abel"})-[]->(andy:`Person` {name:"Andy"}) DELETE p;
- 查找最短路徑
- MATCH p=shortestPath((abel:`Person` {name:"Abel"})-[*..5]->(zmx:`Person` {name:"Zmx"})) DELETE p;
Cipher中的其他操作指令包括:
- 刪除標(biāo)簽和屬性 REMOVE
- 遍歷節(jié)點(diǎn) FOREACH
- 過濾條件 WHERE
- 使用索引 START
- 排序 ORDER BY
- 分頁 LIMIT SKIP
- 索引 INDEX
- 唯一性約束 UNIQUE
- 聚合函數(shù) COUNT SUM AVG DISTINCT 等等
在Neo4j的集群部署中,一般使用zookeeper來負(fù)責(zé)neo4j server的心跳檢測。
需要注意的是,在 zookeeper master選舉期間,write請求不可處理,會直接返回異常,最好在客戶端提供一種故障切換的重試機(jī)制進(jìn)行控制。
各種的圖數(shù)據(jù)庫
在db-engines.com上,可以看到圖數(shù)據(jù)庫的市場排名。
市場有著較大的變化,曾經(jīng)的記憶好像是這樣的:
- AWS使用titan,分布式圖形數(shù)據(jù)庫。
- titan不是數(shù)據(jù)庫,而是客戶端庫,依賴于下面的存儲引擎,例如Cassandra或者Hadoop,也依賴于索引引擎,比如Lucene、ElasticSearch或Solr,來執(zhí)行相關(guān)的查詢。
- arangoDB支持靈活的數(shù)據(jù)模型,比如文檔Document、圖Graph以及鍵值對Key-Value存儲。
- OrientDB的主要特點(diǎn)是支持多模型對象,支持不同的模型,如文檔,圖形,鍵/值和真實(shí)對象。
- GUN是一個(gè)實(shí)時(shí)的、分布式的、嵌入式圖形數(shù)據(jù)庫引擎。
曾經(jīng)關(guān)注的幾種圖數(shù)據(jù)庫部分屬性對比:
由于Neo4j沒有緩存層,將無法支持讀取QPS量,也不能滿足分布式巨量數(shù)據(jù)存儲的需要。許多大廠都有著自己圖數(shù)據(jù)庫,例如百度就開源了他的HugeGraph,可以存儲海量的節(jié)點(diǎn)對象和復(fù)雜的關(guān)系。
圖數(shù)據(jù)庫的應(yīng)用
對于在數(shù)據(jù)捕獲設(shè)計(jì)之后,追求數(shù)據(jù)驅(qū)動運(yùn)營和決策的組織而言,圖分析可能是最有效的競爭優(yōu)勢.因此,圖形數(shù)據(jù)庫在社交網(wǎng)絡(luò)、征信系統(tǒng)等諸多領(lǐng)域有著廣泛的應(yīng)用,例如:
- 實(shí)時(shí)推薦
- 主數(shù)據(jù)管理:組織架構(gòu),社交網(wǎng)絡(luò),產(chǎn)品訂購,IT網(wǎng)絡(luò)
- 欺詐檢測,合成身份詐騙環(huán)
- 基于圖的搜索
- IT網(wǎng)絡(luò)管理
- 身份和訪問管理
- 地理信息系統(tǒng)
其中重要的是,圖數(shù)據(jù)庫能夠?qū)⒋髷?shù)據(jù)洞察付諸于行動,是構(gòu)建知識圖譜的基石之一,在人工智能極其應(yīng)用中有著重要的一席之地。
參考資料
https://neo4j.com/developer
https://www.jiqizhixin.com/articles/2018-06-20-4
https://db-engines.com/
Ian,Robinson、Jim,Webber、Emil,Eifrem 著,劉璐,梁越 譯 《圖數(shù)據(jù)庫(第二版)》,人民郵電出版社,2016
【本文來自51CTO專欄作者“老曹”的原創(chuàng)文章,作者微信公眾號:喔家ArchiSelf,id:wrieless-com】