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