ConceptNet 常識知識庫(knowledge base, KB)


什么是 ConceptNet

ConceptNet是一個免費提供的語義網絡(semantic network),旨在幫助計算機理解人們使用的詞語的含義。ConceptNet起源於眾包項目Open Mind Common Sense,該項目於1999年在麻省理工學院媒體實驗室啟動。自那以后,該項目已經發展到包括來自其他眾包資源的知識、專家創造的資源和有目的的游戲。(上面翻譯自官網 http://conceptnet.io/)。

聯系與區別

從上圖中可以看出,ConceptNet既是一個語義網絡也是一個知識圖譜。但是網絡上很多地方也將 ConceptNet 叫做常識知識庫(knowledge base, KB)。知識庫是用於信息系統中的結構化或非結構化數據的大型存儲庫。最初創造這個術語是為了區分數據庫(當時的數據庫包含扁平的表格數據)和具有關系和層次數據的新知識庫。今天的數據庫可以像以前的知識庫一樣具有多面性。這意味着今天的知識庫更接近語義和組織的多層面數據。當一些研究者交替使用術語知識庫知識圖時,術語的使用是有意的,它們是有區別的。所有的知識圖都是知識庫,但並不是所有的知識庫都是知識圖。知識圖和基礎之間的關鍵區別在於,圖以實體之間的關系為中心。圖是可變的,也是語義的,這意味着數據的含義是與數據一起編碼的。這為機器學習在自動化知識庫或知識圖等方面提供了巨大的可能性。知識庫中的知識有很多種不同的形式,例如本體知識、關聯性知識、規則庫、案例知識等。相比於知識庫的概念,知識圖譜更加側重關聯性知識的構建,如三元組。semantic network語義網絡。語義網絡最早是1960年由認知科學家Allan M. Collins作為知識表示的一種方法提出。WordNet是最典型的語義網絡。相比起知識圖譜,早期的語義網絡更加側重描述概念以及概念之間的關系,而知識圖譜更加強調數據或事物之間的鏈接。

ConceptNet知識庫以三元組形式的關系型知識構成。ConceptNet5版本已經包含有2800萬關系描述。與Cyc相比,ConceptNet采用了非形式化、更加接近自然語言的描述,而不是像Cyc那樣采用形式化的謂詞邏輯。與鏈接數據和谷歌知識圖譜相比,ConceptNet比較側重於詞與詞之間的關系。從這個角度看,ConceptNet更加接近於WordNet,但是又比WordNet包含的關系類型多。

概念演變

使用 ConceptNet

數據格式

原始 ConceptNet 數據集是 csv 格式,下面這樣

uri relation start end json
/a/[/r/Synonym/,/c/zh/馬匹/,/c/zh/馬匹/] /r/Synonym /c/zh/馬匹 /c/zh/馬匹 {"dataset": "/d/cc_cedict", "license": "cc:by-sa/4.0", "sources": [{"contributor": "/s/resource/cc_cedict/2017-10"}], "weight": 1.0}
/a/[/r/Synonym/,/c/zh/馬匹/,/c/en/horse/] /r/Synonym /c/zh/馬匹 /c/en/horse {"dataset": "/d/cc_cedict", "license": "cc:by-sa/4.0", "sources": [{"contributor": "/s/resource/cc_cedict/2017-10"}], "weight": 1.0}
/a/[/r/Synonym/,/c/zh/馬匹/,/c/en/horse/] /r/Synonym /c/zh/馬匹 /c/en/horse {"dataset": "/d/cc_cedict", "license": "cc:by-sa/4.0", "sources": [{"contributor": "/s/resource/cc_cedict/2017-10"}], "weight": 1.0}
/a/[/r/Synonym/,/c/zh/馬南邨/,/c/zh/馬南邨/] /r/Synonym /c/zh/馬南邨 /c/zh/馬南邨 {"dataset": "/d/cc_cedict", "license": "cc:by-sa/4.0", "sources": [{"contributor": "/s/resource/cc_cedict/2017-10"}], "weight": 1.0}

符號與含義之間的對應關系如下

符號 含義
/r 關系,relation,邊
/c 概念,concept,節點
/en 英文
/zh 中文
uri 把(關系,起點,終點)三元組拼接成字符串,可作為索引
json 附加信息

除了這種數據格式,ConceptNet還提供一個 REST API 可以獲取 JSON-LD 格式的數據。在python中可以使用如下的方式獲取數據。

>>> import requests

>>> obj = requests.get('http://api.conceptnet.io/c/en/example').json()
>>> obj.keys()
dict_keys(['view', '@context', '@id', 'edges'])

>>> len(obj['edges'])
20

>>> obj['edges'][2]
{'@id': '/a/[/r/IsA/,/c/en/example/n/,/c/en/information/n/]',
 'dataset': '/d/wordnet/3.1',
 'end': {'@id': '/c/en/information/n',
  'label': 'information',
  'language': 'en',
  'sense_label': 'n',
  'term': '/c/en/information'},
 'license': 'cc:by/4.0',
 'rel': {'@id': '/r/IsA', 'label': 'IsA'},
 'sources': [{'@id'    : '/s/resource/wor  dnet/rdf/3.1',
   'contributor': '/s/resource/wordnet/rdf/3.1'}],
 'start': {'@id': '/c/en/example/n',
  'label': 'example',
  'language': 'en',
  'sense_label': 'n',
  'term': '/c/en/example'},
 'surfaceText': [[example]] is a type of [[information]]',
 'weight': 2.0}

節點和邊

節點 Node

ConceptNet 的節點是自然語言的單詞或者短語。每個節點在 ConceptNet中 都有一個以/c/開頭的 URI 和一個語言代碼,比如/c/en/example。如果已知一個節點的URI,就可以通過http://api.conceptnet.io + URI獲取節點,例如,單詞 example 對應的鏈接是http://api.conceptnet.io/c/en/example
當使用API查找節點的時候,可以得到如下格式的一個數據

{

  "@context": [

    "http://api.conceptnet.io/ld/conceptnet5.7/context.ld.json"

  ],

  "@id": "/c/en/example",
  "edges": [...],
  "view": {
    "@id": "/c/en/example?offset=0&limit=20",
    "firstPage": "/c/en/example?offset=0&limit=20",
    "nextPage": "/c/en/example?offset=20&limit=20",
    "paginatedProperty": "edges"
  }
}

真正有意思的信息在edges里面,稍后討論。
首先,上面的數據是個標准的JSON格式,但是有些屬性前面有一個@,這些屬性是為了JSON-LD存在的。JSON-LD是一個關聯數據API(Linked Data APIs)的標准。通過使用JSON-LD,可以提供隨元數據而來的信息,這些信息是關於它的含義以及如何檢索它,並且這些信息可以被轉換、重用並鏈接到其他系統。

@context鏈接到一個含有幫助JSON-LD工具理解這個API的信息的文件(就像上面代碼中的那個連接,打開看一下就明白了),這個文件還包含幫助人類理解的注釋。這個上下文文件(context)用RDF格式和英文解釋了那些前面沒有@的屬性,例如:edges 和 view 都是什么意思。
大部分從API返回的對象都有一個@id屬性,這個屬性可以告訴我們這個對象的URI。最頂層的@id表示的是本次查找的對象,在查詢返回中可能有更多的@id指向一些相關的信息。
有一些對象有大量的信息,但是有時候我們並不想讓它一次性返回。其中的view對象就描述了一個長列表的分頁方式:這個對象有一個@id屬性,指向你正在看的頁面,還有firstPage,previousPagelastPage屬性,它們的值指向其他的多種頁面。"paginatedProperty": "edges"屬性是告訴你,你當前一頁一頁瀏覽的是edges列表。
有三種方式可以通過ConceptNet 5 API訪問數據:

  • Loopup,當已知URI,求包含這個URI的邊(edges)時使用
  • Search,找到滿足當前條件的邊(edges)的列表
  • Association,尋找一個或者多個概念的相似概念時使用

edge 的結構

edges列表中,可以看到代表圖的邊的對象。邊是連接一個節點和另一個節點的知識單元。下面就是一個邊(edge):

{

  "@id": "/a/[/r/UsedFor/,/c/en/example/,/c/en/explain/]",

  "dataset": "/d/conceptnet/4/en",

  "end": {

    "@id": "/c/en/explain",
    "label": "explain something",
    "language": "en",
    "term": "/c/en/explain"
  },
  "license": "cc:by-sa/4.0",
  "rel": {
    "@id": "/r/UsedFor",
    "label": "UsedFor"
  },
  "sources": [
    {
      "@id": "/and/[/s/activity/omcs/omcs1_possibly_free_text/,/s/contributor/omcs/pavlos/]",
      "activity": "/s/activity/omcs/omcs1_possibly_free_text",
      "contributor": "/s/contributor/omcs/pavlos"
    }
  ],
  "start": {
    "@id": "/c/en/example",
    "label": "an example",
    "language": "en",
    "term": "/c/en/example"
  },
  "surfaceText": "You can use [[an example]] to [[explain something]]",
  "weight": 1.0,
  "@context": [
    "http://api.conceptnet.io/ld/conceptnet5.5/context.ld.json",
    "http://api.conceptnet.io/ld/conceptnet5.5/pagination.ld.json"
  ]
}

這個邊的@id屬性是 /a/[/r/UsedFor/,/c/en/example/,/c/en/explain/]。這個看起來比較復雜的URI,通過包含連接的節點以及它們是如何連接的來唯一標識一個邊。不必從這個URI中提取信息,這些信息在start, endrel屬性中以更方便的格式表示了出來。

start 和 end

"start": {
    "@id": "/c/en/example",
    "label": "an example",
    "language": "en",
    "term": "/c/en/example"
 }

startend指向ConceptNet中的節點。他們包含@id屬性,可以從這個屬性的值URI中查看這個節點的信息。startend還提供:

  • 人類可讀的label,可能是個更完整的短語而不僅僅是URI中的簡單的單詞(我想,大概就類似web應用的API接口文檔中的 description 吧)
  • language,label中使用的語言代碼(總是和URI中的語言代碼相同)
  • term,指向這個詞條的最通用的版本。在大多數情況下,這個是和URI一樣的。但是,如果查詢的是某個特殊的詞性,例如使用/c/en/example/n來查詢"example"的名詞條目,這個term鏈接就會指向更通用的/c/en/example

rel

"rel": {
    "@id": "/r/UsedFor",
    "label": "UsedFor"
  }

rel描述ConceptNet中定義的連接節點的大概40(40-ish,大概40個,到寫博客的時候是34個,https://github.com/commonsense/conceptnet5/wiki/Relations)個關系之一,關系用諸如“UsedFor”這樣的人造名稱來標記。即使它們用不同的語言或來自不同的數據源描述信息,它們也保持不變。

surfaceText
"surfaceText": "You can use [[an example]] to [[explain something]]"
一些ConceptNet的數據是從自然語言文本中提取的,surfaceText的值展示提取這個數據的原始文本是什么。

sources

"sources": [

    {
      "@id": "/and/[/s/activity/omcs/omcs1_possibly_free_text/,/s/contributor/omcs/pavlos/]",
      "activity": "/s/activity/omcs/omcs1_possibly_free_text",
      "contributor": "/s/contributor/omcs/pavlos"
    }
  ]

sources告訴我們為什么ConceptNet相信這個信息。每個邊(edge)可能來自一個或多個源。每個源(sources)都是一個對象,並且有它自己的@id屬性。但是這個ID只包含對象的其余部分中的信息(為了讓RDF數據更好,我們使用了冗余)(這個不是太懂)
source可以包含提供這些知識的各種因素。例如,contributor代表一個參與眾包網站來提供數據的人。activity代表他們正在做什么,或者process代表自動提取知識的過程。
因此,如果source是一個叫"pavlos"的contributor,很久之前這個人從Open Mind Common Sense (OMCS)網站鍵入信息。我們那時的記錄方式並不完美,但我們認為他們是在把句子輸入OMCS的自由文本框,所以我們將其叫做omcs1_possibly_free_text

license
"license": "cc:by-sa/4.0"
許可證(license)告訴我們可以如何使用獲取到的信息。這個內容並不指向ConceptNet中的API,而是指向知識共享(Creative Common)的鏈接數據API。前綴cc:是由http://creativecommons.org/licenses/里的內容文件定義的。這意味着你可以在 http://creativecommons.org/licenses/by-sa/4.0 找到這個邊(edge)的許可證信息,包含人類可讀的許可證以及計算機可讀的許可證。
(有些邊(edge)沒有相同方式分享(ShareAlike)的要求,但是既然整體上是使用的ConceptNet就要遵循相同方式分享(ShareAlike)的要求。詳見 https://github.com/commonsense/conceptnet5/wiki/Copying-and-sharing-ConceptNet)

weight
"weight": 1.0
weight值顯示這個信息有多可信。一個典型的權重是1.0,當信息來自更多的來源或更可靠的來源時,這個數字會更高。

dataset
dataset值是在ConceptNet構建的過程中記錄使用的,並不是很重要。

術語的層級

這些術語(term)的URI(或者叫這些概念(concept)的URI)。都是由/c/開始,並且遵循一個從語言(zh, en,...)到術語(term)再到術語的詞性(senses of terms)的層次結構。例如這個術語/c/it/esempio/n代表意大利語的名詞 "esempio"。
/c/it/esempio就僅僅代表意大利語的"esempio",不管是不是名詞。當你瀏覽/c/it/esempio/n的時候可以得到這個結果。任何術語URI都隱式地包含其所有更特定的URI。
/c/it代表所有意大利語的ConceptNet的知識,可以瀏覽它來獲取ConceptNet中的意大利語部分的樣例。在長長的分頁列表的某個地方將是/c/it/esempio/n的信息。
/c不是一個可用的URI的時候,層級關系就結束了。
對於各種各樣的URI的含義的信息,可以查看 https://github.com/commonsense/conceptnet5/wiki/URI-hierarchy。

獲取短語的URI

給你一個自然語言中的短語,你大概可以知道它的ConceptNet URI是什么。將空格替換為_,在前面加上代表語言的代碼,短語"french toast" 的URI就是/c/en/french_toast
這在ConceptNet的舊版本中是比較復雜的。
如果你想更清楚地得到一個URI,或者你是一個使用Linked Data API的計算機,那你可以向http://api.conceptnet.io/uri發送GET請求,同時帶上以下參數:

可以查詢的其他內容

ConceptNet中的其他對象也有URI。
就像之前提到的,你可以通過URI /a/[/r/UsedFor/,/c/en/example/,/c/en/explain/] 來查詢一個邊(edge)
通過使用/r/Antonym可以查找一個關系,查看邊的示例。
通過使用/s/contributor/omcs/dev來查詢一個來源(source)獲得它貢獻的邊(edges)

復雜查詢

為了過濾一些特定的信息,可以通過向 http://api.conceptnet.io/query傳遞參數,然后就會得到符合條件的邊(edge)的列表。
你可以指定任意下面的參數:

  • startstartsubject位置必須匹配的URI
  • endend或者object位置必須匹配的URI
  • rel:一個關系
  • node:必須與開始(start)或者結束(end)匹配的URI
  • other:必須與開始(start)或者結束(end)匹配的URI,並且與node不同
  • sources:必須與邊(edge)的源(source)之一匹配的URI
    查看連接dogdark的所有關系/query?node=/c/en/dog&other=/c/en/bark
    查看原始的 OMCS dev team 記錄的關於ferrets的信息 /query?node=/c/en/ferret&sources=/s/contributor/omcs/dev
    查看日語中的所有關於貓的斷言/query?node=/c/ja/貓&other=/c/ja
    下面有一個例子是在python中使用這個API獲取與ConceptNet中的"apple"聯系的所有的外部連接數據(external Linked Data)

查詢相關術語(term)

這個API使用從ConceptNet和其他輸入構建的詞嵌入(word embedding)來查找相關術語(related terms)。這個詞嵌入(word embedding)是ConceptNet Numberbatch(https://github.com/commonsense/conceptnet-numberbatch)的一個版本,減少了一些詞匯量來適應網絡傳輸。
例如,查找"tea kettle"相關的術語,/related/c/en/tea_kettle (http://api.conceptnet.io/related/c/en/tea_kettle)

{

  "@id": "/c/en/tea_kettle",

  "related": [

    {

      "@id": "/c/en/tea_kettle",

      "weight": 1.0

    },

    {

      "@id": "/c/en/teakettle",

      "weight": 0.771
    },
    {
      "@id": "/c/nl/ketel",
      "weight": 0.723
    },
    {
      "@id": "/c/ja/釜",
      "weight": 0.718
    },
    {
      "@id": "/c/zh/水壺",
      "weight": 0.712
    },
    ...
  ]
}

默認這個返回結果將包含ConceptNet的核心語言(https://github.com/commonsense/conceptnet5/wiki/Languages)中的任意10個。可以使用filter參數獲取指定語言的數據。因此,"tea kettle"最接近的英文條目是/related/c/en/tea_kettle?filter=/c/en

一組特定術語之間的關聯值

/relatednessAPI和/related很想,但是前者並不是返回查詢的相關的術語的列表,而是返回一組指定術語的關聯值(relatedness value )
例子:
/relatedness?node1=/c/en/tea_kettle&node2=/c/en/coffee_pot (http://api.conceptnet.io/relatedness?node1=/c/en/tea_kettle&node2=/c/en/coffee_pot)

{
  "@id": "/relatedness?node1=/c/en/tea_kettle&node2=/c/en/coffee_pot",
  "value": 0.543
}

本地 python API

如果你的計算機上安裝了ConceptNet的代碼和數據,你也可以通過Python的AssertionFinder.lookup()AssertionFinder.query()方法訪問這個API。

>>> from conceptnet5.db.query import AssertionFinder
>>> cnfinder = AssertionFinder()
>>> cnfinder.lookup('/c/en/example')
[... lots of edges ...]
>>> cnfinder.query({'node': '/c/en/example'})
[... the same edges ...]

版本信息

在ConceptNet 5.5版本中,重構了API以支持JSON-LD數據格式,並且讓每個術語的URI更加明顯(意思應該是類似上面的獲取短語的URI中的可以更容易地從自然語言的術語猜出它的URI吧)。ConceptNet 5.1 到 5.4 版本的API稍有不同,可以在 https://github.com/commonsense/conceptnet5/wiki/API/2349f2bbd1d7fb726b3bbdc14cbeb18f0a40ef18 位置查看它們的歷史文檔。

速度限制

每個小時你可以向ConceptNet發送3600個請求。峰值是每分鍾120個請求。relatedrelatedness是作為兩個請求來算的。
這意味着需要好好設計對API的使用,平均每秒不超過一個請求。

參考

ConceptNet官網 http://conceptnet.io/
知識圖譜相關的名詞解釋 http://wp.openkg.cn/?p=105
什么是JSON-LD http://wp.openkg.cn/?p=69
什么是知識圖譜 http://wp.openkg.cn/?p=119
Knowledge Base https://blog.diffbot.com/knowledge-graph-glossary/knowledge-base/
MIT - ConceptNet5的中文部分-截至2017年1月 http://openkg.cn/dataset/conceptnet5-chinese
ConceptNet — A Practical Commonsense Reasoning Tool-Kit https://agents.media.mit.edu/projects/commonsense/ConceptNet-BTTJ.pdf
API文檔(文中有一大部分由此翻譯而來) https://github.com/commonsense/conceptnet5/wiki/API


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM