【转载】KG-知识图谱初探
轉(zhuǎn)載:項目實戰(zhàn)–知識圖譜初探
項目實戰(zhàn):如何構(gòu)建知識圖譜
實踐了下怎么建一個簡單的知識圖譜,兩個版本,一個從 0 開始(start from scratch),一個在 CN-DBpedia 基礎(chǔ)上補(bǔ)充,把 MySQL,PostgreSQL,Neo4j 數(shù)據(jù)庫都嘗試了下。自己跌跌撞撞摸索可能踩坑了都不知道,歡迎討論。
PS:這篇文章寫很不錯,闡釋了知識圖譜的整個構(gòu)建過程,對于剛?cè)腴T的同學(xué)幫助很大,包括我自己在內(nèi)。希望你也能從中有所收獲!
1.CN-DBpedia 構(gòu)建流程
知識庫可以分為兩種類型,一種是以 Freebase,Yago2 為代表的 Curated KBs,主要從維基百科和 WordNet 等知識庫中抽取大量的實體及實體關(guān)系,像是一種結(jié)構(gòu)化的維基百科。另一種是以 Stanford OpenIE,和我們學(xué)校 Never-Ending Language Learning (NELL) 為代表的 Extracted KBs,直接從上億個非結(jié)構(gòu)化網(wǎng)頁中抽取實體關(guān)系三元組。
與 Freebase 相比,這樣得到的知識更加多樣性,但同時精確度要低于 Curated KBs,因為實體關(guān)系和實體更多的是自然語言的形式,如“奧巴馬出生在火奴魯魯。” 可以被表示為(“Obama”, “was also born in”, “ Honolulu”)。
下面以 CN-DBpedia 為例看下知識圖譜大致是怎么構(gòu)建的。
上圖分別是 CN-DBpedia 的構(gòu)建流程和系統(tǒng)架構(gòu)。知識圖譜的構(gòu)建是一個浩大的工程,從大方面來講,分為知識獲取、知識融合、知識驗證、知識計算和應(yīng)用幾個部分,也就是上面架構(gòu)圖從下往上走的一個流程,簡單來走一下這個流程。
2.數(shù)據(jù)支持層
最底下是知識獲取及存儲,或者說是數(shù)據(jù)支持層,首先從不同來源、不同結(jié)構(gòu)的數(shù)據(jù)中獲取知識,CN-DBpedia 的知識來源主要是通過爬取各種百科知識這類半結(jié)構(gòu)化數(shù)據(jù)。
至于數(shù)據(jù)存儲,要考慮的是選什么樣的數(shù)據(jù)庫以及怎么設(shè)計 schema。選關(guān)系數(shù)據(jù)庫還是NoSQL 數(shù)據(jù)庫?要不要用內(nèi)存數(shù)據(jù)庫?要不要用圖數(shù)據(jù)庫?這些都需要根據(jù)數(shù)據(jù)場景慎重選擇。
CN-DBpedia 實際上是基于 mongo 數(shù)據(jù)庫,參與開發(fā)的謝晨昊提到,一般只有在基于特定領(lǐng)域才可能會用到圖數(shù)據(jù)庫,就知識圖譜而言,基于 json (bson) 的 mongo 就足夠了。用到圖查詢的領(lǐng)域如征信,一般是需要要找兩個公司之間的關(guān)聯(lián)交易,會用到最短路徑/社區(qū)計算等。
schema 的重要性不用多說,高質(zhì)量、標(biāo)準(zhǔn)化的 schema 能有效降低領(lǐng)域數(shù)據(jù)之間對接的成本。我們希望達(dá)到的效果是,對于任何數(shù)據(jù),進(jìn)入知識圖譜后后續(xù)流程都是相同的。換言之,對于不同格式、不同來源、不同內(nèi)容的數(shù)據(jù),在接入知識圖譜時都會按照預(yù)定義的 schema 對數(shù)據(jù)進(jìn)行轉(zhuǎn)換和清洗,無縫使用已有元數(shù)據(jù)和資源。
3.知識融合層
我們知道,目前分布在互聯(lián)網(wǎng)上的知識常常以分散、異構(gòu)、自治的形式存在,另外還具有冗余、噪音、不確定、非完備的特點(diǎn),清洗并不能解決這些問題,因此從這些知識出發(fā),通常需要融合和驗證的步驟,來將不同源不同結(jié)構(gòu)的數(shù)據(jù)融合成統(tǒng)一的知識圖譜,以保證知識的一致性。
所以數(shù)據(jù)支持層往上一層實際上是融合層,主要工作是對獲取的數(shù)據(jù)進(jìn)行標(biāo)注、抽取,得到大量的三元組,并對這些三元組進(jìn)行融合,去冗余、去沖突、規(guī)范化。
第一部分 SPO 三元組抽取,對不同種類的數(shù)據(jù)用不同的技術(shù)提取:
從結(jié)構(gòu)化數(shù)據(jù)庫中獲取知識:D2R
難點(diǎn):復(fù)雜表數(shù)據(jù)的處理
從鏈接數(shù)據(jù)中獲取知識:圖映射
難點(diǎn):數(shù)據(jù)對齊
從半結(jié)構(gòu)化(網(wǎng)站)數(shù)據(jù)中獲取知識:使用包裝器
難點(diǎn):方便的包裝器定義方法,包裝器自動生成、更新與維護(hù)
從文本中獲取知識:信息抽取
難點(diǎn):結(jié)果的準(zhǔn)確率與覆蓋率
尤其是純文本數(shù)據(jù)會涉及到的實體識別、實體鏈接、實體關(guān)系識別、概念抽取 等,需要用到許多自然語言處理的技術(shù),包括但不僅限于分詞、詞性標(biāo)注、分布式語義表達(dá)、篇章潛在主題分析、同義詞構(gòu)建、語義解析、依存句法、語義角色標(biāo)注、語義相似度計算等等。
第二部分才到融合,目的是將不同數(shù)據(jù)源獲取的知識進(jìn)行融合構(gòu)建數(shù)據(jù)之間的關(guān)聯(lián)。包括實體對齊、屬性對齊、沖突消解、規(guī)范化等,這一部分很多都是 dirty work,更多的是做一個數(shù)據(jù)的映射、實體的匹配,可能還會涉及的是本體的構(gòu)建和融合。最后融合而成的知識庫存入上一部分提到的數(shù)據(jù)庫中。如有必要,也需要如 Spark 等大數(shù)據(jù)平臺提供高性能計算能力,支持快速運(yùn)算。
知識融合的四個難點(diǎn):
實現(xiàn)不同來源、不同形態(tài)數(shù)據(jù)的融合
海量數(shù)據(jù)的高效融合
新增知識的實時融合
多語言的融合
4.知識驗證
再往上一層主要是驗證,分為補(bǔ)全、糾錯、外鏈、更新各部分,確保知識圖譜的一致性和準(zhǔn)確性。
一個典型問題是,知識圖譜的構(gòu)建不是一個靜態(tài)的過程,當(dāng)引入新知識時,需要判斷新知識是否正確,與已有知識是否一致,如果新知識與舊知識間有沖突,那么要判斷是原有的知識錯了,還是新的知識不靠譜?這里可以用到的證據(jù)可以是權(quán)威度、冗余度、多樣性、一致性等。如果新知識是正確的,那么要進(jìn)行相關(guān)實體和關(guān)系的更新。
5.知識計算和應(yīng)用
這一部分主要是基于知識圖譜計算功能以及知識圖譜的應(yīng)用。知識計算主要是根據(jù)圖譜提供的信息得到更多隱含的知識,像是通過本體或者規(guī)則推理技術(shù)可以獲取數(shù)據(jù)中存在的隱含知識;通過鏈接預(yù)測預(yù)測實體間隱含的關(guān)系;通過社區(qū)計算在知識網(wǎng)絡(luò)上計算獲取知識圖譜上存在的社區(qū),提供知識間關(guān)聯(lián)的路徑……通過知識計算知識圖譜可以產(chǎn)生大量的智能應(yīng)用如專家系統(tǒng)、推薦系統(tǒng)、語義搜索、問答等。
知識圖譜涉及到的技術(shù)非常多,每一項技術(shù)都需要專門去研究,而且已經(jīng)有很多的研究成果。Anyway 這章不是來論述知識圖譜的具體技術(shù),而是講怎么做一個 hello world 式的行業(yè)知識圖譜。
這里講兩個小 demo,一個是爬蟲+mysql+d3 的小型知識圖譜,另一個是基于 CN-DBpedia+爬蟲+PostgreSQL+d3 的”增量型”知識圖譜,要實現(xiàn)的是某行業(yè)上市公司與其高管之間的關(guān)系圖譜。
6.數(shù)據(jù)獲取
第一個重要問題是,我們需要什么樣的知識?需要爬什么樣的數(shù)據(jù)?
一般在數(shù)據(jù)獲取之前會先做個知識建模,建立知識圖譜的數(shù)據(jù)模式,可以采用兩種方法:一種是自頂向下的方法,專家手工編輯形成數(shù)據(jù)模式;另一種是自底向上的方法,基于行業(yè)現(xiàn)有的標(biāo)準(zhǔn)進(jìn)行轉(zhuǎn)換或者從現(xiàn)有的高質(zhì)量行業(yè)數(shù)據(jù)源中進(jìn)行映射。數(shù)據(jù)建模都過程很重要,因為標(biāo)準(zhǔn)化的 schema 能有效降低領(lǐng)域數(shù)據(jù)之間對接的成本。
作為一個簡單的 demo,我們只做上市公司和高管之間的關(guān)系圖譜,企業(yè)信息就用公司注冊的基本信息,高管信息就用基本的姓名、出生年、性別、學(xué)歷這些。
然后開始寫爬蟲,爬蟲看著簡單,實際有很多的技巧,怎么做優(yōu)先級調(diào)度,怎么并行,怎么屏蔽規(guī)避,怎么在遵守互聯(lián)網(wǎng)協(xié)議的基礎(chǔ)上最大化爬取的效率,有很多小的 trick,之前博客里也說了很多,就不展開了,要注意的一點(diǎn)是,高質(zhì)量的數(shù)據(jù)來源是成功的一半!
來扯一扯爬取建議:
從數(shù)據(jù)質(zhì)量來看,優(yōu)先考慮權(quán)威的、穩(wěn)定的、數(shù)據(jù)格式規(guī)整且前后一致、數(shù)據(jù)完整的網(wǎng)頁
從爬取成本來看,優(yōu)先考慮免登錄、免驗證碼、無訪問限制的頁面
爬下來的數(shù)據(jù)務(wù)必保存好爬取時間、爬取來源(source)或網(wǎng)頁地址(url)
source 可以是新浪財經(jīng)這類的簡單標(biāo)識,url 則是網(wǎng)頁地址,這些在后續(xù)數(shù)據(jù)清洗以及之后的糾錯(權(quán)威度計算)、外鏈和更新中非常重要
企業(yè)信息可以在天眼查、啟信寶、企查查各種網(wǎng)站查到,信息還蠻全的,不過有訪問限制,需要注冊登錄,還有驗證碼的環(huán)節(jié),當(dāng)然可以過五關(guān)斬六將爬到我們要的數(shù)據(jù),然而沒這個必要,換別個網(wǎng)站就好。
推薦兩個數(shù)據(jù)來源: 中財網(wǎng)數(shù)據(jù)引擎和巨潮資訊,其中巨潮資訊還可以同時爬取高管以及公告信息。
看一下數(shù)據(jù):
換句話說,我們直接能得到規(guī)范的實體(公司、人),以及規(guī)范的關(guān)系(高管),當(dāng)然也可以把高管展開,用下一層關(guān)系,董事長、監(jiān)事之類,這就需要做進(jìn)一步的清洗,也可能需要做關(guān)系的對齊。
這里爬蟲框架我用的是 scrapy+redis 分布式,每天可以定時爬取,爬下來的數(shù)據(jù)寫好自動化清洗腳本,定時入庫。
7.數(shù)據(jù)存儲
數(shù)據(jù)存儲是非常重要的一環(huán),第一個問題是選什么數(shù)據(jù)庫,這里作為 starter,用的是關(guān)系型數(shù)據(jù)庫 MySQL。設(shè)計了四張表,兩張實體表分別存公司(company)和人物(person)的信息,一張關(guān)系表存公司和高管的對應(yīng)關(guān)系(management),最后一張 SPO 表存三元組。
為什么爬下來兩張表,存儲卻要用 4 張表?
一個考慮是知識圖譜里典型的一詞多義問題,相同實體名但有可能指向不同的意義,比如說 Paris 既可以表示巴黎,也可以表示人名,怎么辦?讓作為地名的 “Paris” 和作為人的 “Paris” 有各自獨(dú)一無二的ID。“Paris1”(巴黎)通過一種內(nèi)在關(guān)系與埃菲爾鐵塔相聯(lián),而 “Paris2”(人)通過取消關(guān)系與各種真人秀相聯(lián)。
這里也是一樣的場景,同名同姓不同人,需要用 id 做唯一性標(biāo)識,也就是說我們需要對原來的數(shù)據(jù)格式做一個轉(zhuǎn)換,不同的張三要標(biāo)識成張三1,張三2… 那么,用什么來區(qū)別人呢?
拍腦袋想用姓名、生日、性別來定義一個人,也就是說我們需要一張人物表,需要(name, birth, sex)來作 composite unique key 表示每個人。公司也是相同的道理,不過這里只有上市公司,股票代碼就可以作為唯一性標(biāo)識。
Person 表和 company 表是多對多的關(guān)系,這里需要做 normalization,用 management 這張表來把多對多轉(zhuǎn)化為兩個一對多的關(guān)系,(person_id, company_id)就表示了這種映射。
management 和 spo 表都表示了這種映射,為什么用兩張表呢?是出于實體對齊的考慮。management 保存了原始的關(guān)系,”董事”、監(jiān)事”等,而 spo 把這些關(guān)系都映射成”高管”,也就是說 management 可能需要通過映射才能得到 SPO 表,SPO 才是最終成型的表。
我們知道知識庫里的關(guān)系其實有兩種,一種是屬性(property),一種是關(guān)系(relation)。那么還有一個問題是 SPO 需不需要存儲屬性?
最初的想法是實體歸實體,屬性歸屬性,SPO 只存實體間的關(guān)系,屬性由實體表檢索得到,然而這樣的話需要多表 JOIN,屬性增加時擴(kuò)展性也很差。因此把屬性也存到 SPO 表中。在 SPO 表中多加一列 type,來區(qū)分這關(guān)系是實體間關(guān)系還是實體與屬性的關(guān)系,便于之后的可視化。
最后要注意的一點(diǎn)是,每條記錄要保存創(chuàng)建時間以及最后更新時間,做一個簡單的版本控制。
8.數(shù)據(jù)可視化
Flask 做 server,d3 做可視化,可以檢索公司名/人名獲取相應(yīng)的圖譜,如下圖。之后會試著更新有向圖版本。
9.Start from CN-DBpedia
把 CN-DBpedia 的三元組數(shù)據(jù),大概 6500 萬條,導(dǎo)入數(shù)據(jù)庫,這里嘗試了 PostgreSQL。然后檢索了 112 家上市公司的注冊公司名稱,只有 69 家公司返回了結(jié)果,屬性、關(guān)系都不是很完善,說明了通用知識圖譜有其不完整性。
也有可能需要先做一次 mention2entity,可能它的標(biāo)準(zhǔn)實體并不是注冊信息的公司名稱,不過 API 小范圍試了下很多是 Unknown Mention。
做法也很簡單,把前面 Start from scratch 中得到的 SPO 表插入到這里的 SPO 表就好了。這么簡單?因為這個場景下不用做實體對齊和關(guān)系對齊。
10.拓展
這只是個 hello world 項目,在此基礎(chǔ)上可以進(jìn)行很多有趣的拓展,最相近的比如說加入企業(yè)和股東的關(guān)系,可以進(jìn)行企業(yè)最終控制人查詢(e.g.,基于股權(quán)投資關(guān)系尋找持股比例最大的股東,最終追溯至自然人或國有資產(chǎn)管理部門)。再往后可以做企業(yè)社交圖譜查詢、企業(yè)與企業(yè)的路徑發(fā)現(xiàn)、企業(yè)風(fēng)險評估、反欺詐等等等等。
具體來說:
重新設(shè)計數(shù)據(jù)模型 引入”概念”,形成可動態(tài)變化的“概念—實體—屬性—關(guān)系”數(shù)據(jù)模型,實現(xiàn)各類數(shù)據(jù)的統(tǒng)一建模;
擴(kuò)展多源、異構(gòu)數(shù)據(jù),結(jié)合實體抽取、關(guān)系抽取等技術(shù),填充數(shù)據(jù)模型;
展開知識融合(實體鏈接、關(guān)系鏈接、沖突消解等)、驗證工作(糾錯、更新等)。
最后補(bǔ)充一下用 Neo4j 方式產(chǎn)生的可視化圖,有兩種方法。
一是把上面說到的 MySQL/PostgreSQL 里的 company 表和 person 表存成 node,node 之間的關(guān)系由 spo 表中 type == relation 的 record 中產(chǎn)生;
二是更直接的,從 spo 表中,遇到 type == property 就給 node(subject) 增加屬性 ({predicate:object}),遇到 type == relation 就給 node 增加關(guān)系 ((Nsubject) - [r:predicate]-> node(Nobject)),得到下面的圖,移動鼠標(biāo)到相應(yīng)位置就可以在下方查看到關(guān)系和節(jié)點(diǎn)的屬性。
?
作者丨徐阿衡
學(xué)校丨卡耐基梅隆大學(xué)碩士
研究方向丨QA系統(tǒng)
總結(jié)
以上是生活随笔為你收集整理的【转载】KG-知识图谱初探的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: wow模型修改器_魔兽世界改模型 wow
- 下一篇: %3c大自然的语言%3e竺可桢题目,大自