信息是指外部客觀存在的內容,知識是對外部客觀規律的歸納和總結。知識圖譜於2012年5月17日被Google正式提出,初衷是為了提高搜索引擎的能力,增強用戶的搜索質量以及搜索體驗。
知識圖譜的定義
知識圖譜是一種解釋實體之間關系的語義網絡,可以實現對現實世界的事物以及相互關系進行形式化地描述。現在的知識圖譜已被用來泛指各種大規模的知識庫。
知識圖譜中存的是什么
三元組是知識圖譜的一種通用表示方式,具有三種基本形態:
- 實體-關系-實體
- 實體-屬性-屬性值
- 實體-標簽-標簽值
知識圖譜的構建
如何決定哪些是實體,哪些是屬性,哪些是關系?取決於圖譜的使用方式和想要完成的任務。
關系查找:xx的老婆的父親是誰?
屬性對比:xx的身高比xx高多少?
數據類型和存儲方式
結構化數據(Structed Data): 如關系數據庫
半結構化數據(Semi-Structed Data): 如XML、JSON、百科
非結構化數據(UNStructed Data): 如圖片、音頻、視頻、文本
知識圖譜的架構
邏輯架構
知識圖譜在邏輯上分為模式層和數據層兩個層次。
模式層構建在數據層之上,是知識圖譜的核心,通常采用本體庫來管理知識圖譜的模式層。本體是結構化知識庫的概念模板,通過本體庫而形成的知識庫不僅層次結構較強,並且冗余程度較小。
模式層:實體-關系-實體、實體-屬性-屬性值
數據層主要是由一系列的事實組成,而知識將以事實為單位進行存儲。如果用(實體1,關系,實體2)、(實體、屬性,屬性值)這樣的三元組來表達事實,可選擇圖數據庫作為存儲介質,例如開源的Neo4j、Twitter的FlockDB、sones的GraphDB等。
數據層:比爾蓋茨-妻子-梅琳達·蓋茨,比爾蓋茨-總裁-微軟
技術架構
知識圖譜的構建
關鍵技術
知識抽取:非結構化->結構化
知識融合:消歧提升數據質量
知識推理:挖掘擴充或補全數據
知識表達:為應用做准備
知識抽取
面向非結構化數據,通過自動化的技術抽取出可用的知識單元
- 實體抽取
- 關系抽取
- 屬性抽取
實體抽取
實體是知識圖譜中的最基本的元素,其抽取的完整性、准確性、召回率等將直接影響到知識庫的質量,命名實體識別通常采用:1.基於規則和詞典的方法;2.基於機器學習的模型預測方法(序列標注問題)
關系抽取
判斷實體之間關聯關系
- 限定領域關系抽取
從預設好的數個關系中判斷,給定的實體對是否滿足某一個關系:
F(實體1,實體2,文本)——>關系
屬於有監督分類任務
pipeline vs 聯合訓練
pipeline
先用一個模型抽取出實體,再用一個模型根據實體抽取出屬性。
B-Bert用[CLS]token作為整個句子信息的輸出,用實體的輸出的加權和作為實體信息的向量,然后將它們拼接在一起。
聯合訓練
在一個模型中抽取實體和屬性,一般模型中具有兩個loss。
# -*- coding: utf-8 -*-
import torch
import torch.nn as nn
from torch.optim import Adam, SGD
#from torchcrf import CRF
#from transformers import T5Model
"""
建立網絡模型結構
"""
class TorchModel(nn.Module):
def __init__(self, config):
super(TorchModel, self).__init__()
hidden_size = config["hidden_size"]
vocab_size = config["vocab_size"] + 1
self.embedding = nn.Embedding(vocab_size, hidden_size, padding_idx=0)
self.layer = nn.LSTM(hidden_size, hidden_size, batch_first=True, bidirectional=True, num_layers=1)# 此為雙向LSTM
self.bio_classifier = nn.Linear(hidden_size * 2, config["bio_count"]) # 因為前面經過了雙向LSTM,所以輸入維度為hidden_size*2,此層用來找出實體
self.attribute_classifier = nn.Linear(hidden_size * 2, config["attribute_count"]) # 此層用來找出屬性
self.attribute_loss_ratio = config["attribute_loss_ratio"]
self.loss = torch.nn.CrossEntropyLoss(ignore_index=-100) #loss采用交叉熵損失
#當輸入真實標簽,返回loss值;無真實標簽,返回預測值
def forward(self, x, attribute_target=None, bio_target=None):
x = self.embedding(x)
x, _ = self.layer(x)
#序列標注
bio_predict = self.bio_classifier(x)
#文本分類
self.pooling_layer = nn.AvgPool1d(x.shape[1]) #inpt:(batch, sen_len, hidden_size) -> (batch, hidden_size)
x = self.pooling_layer(x.transpose(1, 2)).squeeze()
attribute_predict = self.attribute_classifier(x)
#multi-task訓練
if bio_target is not None:
bio_loss = self.loss(bio_predict.view(-1, bio_predict.shape[-1]), bio_target.view(-1))
attribute_loss = self.loss(attribute_predict.view(x.shape[0], -1), attribute_target.view(-1))
return bio_loss + attribute_loss * self.attribute_loss_ratio # 計算復合loss,這是聯合訓練的關鍵
else:
return attribute_predict, bio_predict
def choose_optimizer(config, model):
optimizer = config["optimizer"]
learning_rate = config["learning_rate"]
if optimizer == "adam":
return Adam(model.parameters(), lr=learning_rate)
elif optimizer == "sgd":
return SGD(model.parameters(), lr=learning_rate)
if __name__ == "__main__":
from config import Config
model = TorchModel(Config)
- 開方領域關系抽取
- 基於依存句法分析+規則
比如:主謂賓關系 - 基於序列標注
屬性抽取
實體的屬性可以看成是實體與屬性值之間的一種名稱性關系,因此可以將實體屬性的抽取問題轉換為關系抽取問題。可以借鑒大部分關系抽取的方法。
知識融合
由於知識圖譜中的知識來源廣泛,存在知識質量良莠不齊、來自不同數據庫的知識重復、知識間的關聯不夠明確等問題,所以必須要進行知識融合。具體方法包括:
- 實體對齊
- 實體消歧
- 屬性對齊
實體對齊
將不同來源的知識認定為真實世界的同一。
可以依據不同實體所包含的屬性之間的相似度來判斷實體是否為同一實體:
實體消歧
將同一名稱但指代不同事物的實體區分開:
屬性對齊
不同數據源對於實體屬性的記錄可能使用不同的語言:
- 百度:姚明-生日-1980年9月12日
- 搜狗:姚明-出生日期-1980年9月12日
- 維基:姚明-出生年月-1980年9月12日
使用屬性和屬性值做相似度計算
知識推理
在已知的知識庫基礎上進一步挖掘隱含的知識,從而豐富、擴展知識庫。
傳遞性:A-兒子-B,B-兒子-C,A-?-C
實例性:A-是-B,B屬於C,A-?-C
基於模型的知識補全
給出兩個實體,推斷其關系:
h+r->t,h+t->r,(h,r,t)->{0,1}
相關論文:KG-Bert
KG-Bert
將三元組放入Bert模型中,讓模型給三元組打分。
知識表示
將知識圖譜中的實體,關系,屬性等轉化為向量,利用向量間的計算關系,反映實體間的關聯性。
TransE:對於三元組(h,r,t),學習其向量表示\(I_h,I_r,I_t\),使其滿足\(I_h+I_r\approx I_t\)
融合文本
融合文本的知識表示,將文本表示和知識圖譜中的實體關系表示放入同一個空間,使得學習到的實體表示可以在文本相關的任務中使用。
優勢:發掘實體之間的語義相關性,精確的語義表述能夠提升三元組的可區分性。當一些實體對於現有的知識圖譜來說是新的,並且僅僅帶有描述性信息的時候,傳統知識圖譜表示學習方法不能夠表示這些新實體,但融入了文本描述的模型,能通過描述信息構建實體表示。