基於BERT的知識庫問答系統(KBQA)
簡介
知識庫問答系統主要要做的兩點分別是識別問題中的實體和提取問題中我們需要從知識庫中查找的屬性,針對這兩個方面我採用了NLP預訓練模型BERT分別訓練了基於BERT-LSTM-CRF的命名實體識別模型(框架來源於https://blog.csdn.net/macanv/article/details/85684284),基於BERT的分類模型,用於匹配問題和知識庫三元組中的屬性。
數據集
此次使用的數據集來自NLPCC ICCPOL 2016 KBQA 任務集,其包含 14 609 個問答對的訓練集和包含 9 870 個問答對的測試集。 並提供一個知識庫,包含 6 502 738 個實體、 587 875 個屬性以及 43 063 796 個 三元組。知識庫文件中每行存儲一個事實( fact) ,即三元組 ( 實體、屬性、屬性值) 。
知識庫樣例如下,共有43063796行:
技術方案
剛剛已經提到基於知識庫的問答主要可以拆分爲兩個步驟,問句中的實體識別以及屬性映射。
- 命名實體識別部分採用BERT+LSTM+CRF的方法。
- 屬性映射部分轉換成用BERT做二分類的任務。
項目結構
├─.idea
├─bert
│ ├─chinese_L-12_H-768_A-12 # BERT預訓練模型
│ └─__pycache__
├─Data
│ ├─DB_Data
│ │ └─clean_triple.csv # 由tripe_clean.py生成的要存入數據庫的文件(把原始三元組處理成csv格式)
│ ├─NER_Data # 用於訓練和測試NER模型的數據,由construct_dataset.py生成
│ ├─NLPCC2016KBQA #NLPCC2016原始數據
│ │ └─kb
│ ├─Sim_Data # 用於訓練BERT二分類模型的數據, 由construct_dataset_attribute.py生成
│ ├─construct_dataset.py
│ ├─construct_dataset_attribute.py
│ ├─load_dbdata.py # 數據庫查詢插入等操作
│ ├─triple_clean.py
├─Output
│ ├─NER
│ └─SIM
├─args.py #參數設置
├─bert_lstm_ner.py # NER訓練
├─kbqa.py #可以運行的問答系統(目前速度非常慢)
├─kbqa_test.py #進行問答準確率測試
├─lstm_crf_layer.py #lstm+crf模型
├─run_similarity.py #BERT二分類模型(可訓練,可預測)
├─terminal_predict.py #NER的預測,可以outline,可以online
└─__pycache__
運行效果
目前效果如下圖,由於mysql數據庫中直接存入了四千多萬條三元組數據,由於我是初學數據庫,只是用select來進行暴力搜索,所以速度相當慢,基本回答一個問題要一分鐘左右,快的也要半分鐘,這是接下來要主要優化的點。
TO DO
學習mysql知識,提高搜索效率
目前的屬性匹配方式用問題和備選屬性做相似度匹配直覺上的感覺不是特別好,可以探索下有沒有更快的方法來進行屬性匹配。