deepdive python3 環境下多種實體關係抽取流程

前言:

deepdive是基於python2的,如果寫腳本時使用python3,就會出現一系列問題,例如最開始可能遇到的報錯就是:即找不到dd文件等等

22:38:04 [Helpers$(akka://deepdive)] INFO  Traceback (most recent call last):
22:38:04 [Helpers$(akka://deepdive)] INFO    File "/opt/elementary-memex-ddlog/escort-review/udf/extract_test.py", line 12, in <module>
22:38:04 [Helpers$(akka://deepdive)] INFO      import ddlib
22:38:04 [Helpers$(akka://deepdive)] INFO    File "/home/eve/local/lib/python/ddlib/__init__.py", line 1, in <module>
22:38:04 [Helpers$(akka://deepdive)] INFO      from dd import *
22:38:04 [Helpers$(akka://deepdive)] INFO  ImportError: No module named 'dd'

本篇目的就是修改相關源碼,使我們可以使用python3

最後會具體給出兩個實踐,第一個還是官方的基本demo,第二個是綜合了多種關係抽取,且加了性能評價部分

關於deepdive更多使用細節:中文翻譯版

https://github.com/theDoctor2013/DeepDive-tutorial/blob/master/Deepdive_new.md

本篇兩個實踐代碼:

https://github.com/Mryangkaitong/python-Machine-learning/tree/master/deepdive/demo_version_2

https://github.com/Mryangkaitong/python-Machine-learning/tree/master/deepdive/demo_version_3

建議從如下第一篇博客看起,如果比較熟悉可以直接跳到實踐二部分

https://blog.csdn.net/weixin_42001089/article/details/90749577

調試:

:在進行修改源碼時,首先要知道哪裏錯了,即調試,可以使用如下兩種方法:

一  deepdive 自帶的調試API:

deepdive env python udf/my.py

對應到py3便是:

deepdive env python3 udf/my.py

二:print大法

除了上述方法外,我們知道在python 中經常可以使用print大法來看某些輸出進而可以定位錯誤,但是DeepDive的UDF的所有標準輸出都被轉換爲TSJ或者TSV格式並存到數據庫裏,所以像Python中的print這樣的語句是不可以作爲屏幕信息輸出的,這樣會破壞我們的數據。所以正確的用法是把屏幕信息使用標準錯誤流standard error中進行輸出(其他語言一樣):

#!/usr/bin/env python
from deepdive import *
import sys

@tsj_extractor
@returns( ... )
def extract( ... ):
    ...
    print >>sys.stderr, 'This prints some_object to logs :', some_object
    ...

當然了,上述對應的是python2的寫法,在python3中是:

#!/usr/bin/env python
from deepdive import *
import sys

@tsj_extractor
@returns( ... )
def extract( ... ):
    ...
    print('This prints some_object to logs :', some_object, file=sys.stderr)
    ...

修改:

涉及到的源碼主要是在$HOME/local/lib/python/ddlib下的四個文件

__init__.py

dd.py

gen_feats.py

util.py

一個一個來看

__init__.py

需要將路徑修改爲當前路徑,負責會找不到相關py文件:

gen_feats.py

首先也是要改一下爲當前路徑

還有就是修改一下運行環境

util.py

這裏需要改成對應的list,不然python3中zip 是沒有len()的,後續代碼中會用到len()

還有就是這裏改爲字符串標示

其次就是一些print需要加括號,對應的改一下就好啦

上面就是主要的修改成分,其他的一些都修改都很簡單這裏就不說啦,筆者這裏已經修改好,直接複製這4個文件覆蓋掉源碼中的四個文件即可.

這樣我們就可以使用python3腳本了,即udf下的腳本都可以換成python3,如果還是想在python3下用原demo中的部分腳本,一個是要將腳本開頭指定爲python3環境,另一個是要注意原demo中有幾個腳本需要改下

比如原demo中給的trasform.py中要將print加括號等等。

map_company_mention.py中

xrange替換爲range,因爲python3中是沒有xrange的,且在python3中unicode這種寫法是不對的,直接改爲str即可

實踐一:

由於使用使用deepdive 原始的斯坦福的nlp包進行文本信息提取時間過長,故換用ltp處理,本例子還是實現交易記錄的預測,只不過nlp處理部分替換了

即主要寫了一個nlp_markup.py替換原來的nlp_markup.sh,注意這裏爲了演示統一將udf下的所有python腳本指定爲了python3環境

首先爲了使用ltp要將app.ddlog中要調用nlp_markup.sh換爲調用nlp_markup.py腳本

運行流程的命令沒有變:

即先是導入文章

 deepdive compile && deepdive do articles

提取文本信息,基本需要幾秒就可以結束該過程,而之前需要數小時

 deepdive compile && deepdive do sentences

看一下結果

生成候選實體

deepdive compile && deepdive do company_mention

生成候選實體對

deepdive compile && deepdive do transaction_candidate

提取特徵

deepdive compile && deepdive do transaction_feature

打標

deepdive do transaction_label_resolved

變量表定義:

deepdive compile && deepdive do has_transaction

預測:

deepdive compile && deepdive do probabilities

看一下結果:

deepdive sql "SELECT p1_id, p2_id, expectation FROM has_transaction_label_inference
ORDER BY expectation desc"

實踐二:

該部分實現擔保和股權質押兩種關係抽取,

如果臨時是想多加一種關係也按如下流程走便可,假設當前增加的關係爲A,那麼就是在app.ddlog中參照zhiya或danbao在如下每一部分中相應的增加A的定義即可

導入所有原始數據

原始數據:兩種關係的文章以及兩種關係的部分少量 label

在app.ddlog中定義了相關的存儲結構:

 

運行導入:

deepdive compile && deepdive do zhiya_articles
deepdive compile && deepdive do zhiya_record

deepdive compile && deepdive do danbao_articles
deepdive compile && deepdive do danbao_record

用pyltp模塊進行文本處理

在app.ddlog中定義相關的存儲結構和處理的python腳本:

運行

deepdive compile && deepdive do zhiya_sentences
deepdive compile && deepdive do danbao_sentences

實體抽取

抽取公司

在app.ddlog中定義相關的存儲結構和處理的python腳本:

運行:

deepdive compile && deepdive do zhiya_company_mention
deepdive compile && deepdive do danbao_company_mention

生成候選實體對

將每一句話中出現的所有公司名兩兩組合生成候選實體對

在app.ddlog中定義相關的存儲結構和處理的python腳本:

運行

deepdive compile && deepdive do zhiya_candidate
deepdive compile && deepdive do danbao_candidate

特徵提取

提取候選實體對的一些窗口特徵

在app.ddlog中定義相關的存儲結構和處理的python腳本:

運行:

deepdive compile && deepdive do zhiya_feature
deepdive compile && deepdive do danbao_feature

打標以及劃分訓練集和測試集

首先定義label的存儲結構:

初始化標籤權重(所有候選實體對權重是0),然後導入label(將相關候選實體對的權重賦值爲3)

調用相應的腳本(人爲定義的一些規則)進行預打標:

對多種權重進行加和:

通過調用generate_train_test_flag.py腳本隨機生成訓練集和測試集的flag(1~10內的一個數字)

運行

deepdive compile && deepdive do zhiya_label_test_train
deepdive compile && deepdive do danbao_label_test_train

----------------------------下是模型構建部分-----------------------------------------

 

變量表定義

首先定義存儲結構和生成正負樣本規則(很簡單看權重是正數還是負數)

這裏需要注意的是,劃分了訓練集和測試集,如下是劃分出來20%作爲了測試集,假如需要劃分40%,那麼對應位置改爲4,以此類推。

 

運行:

deepdive compile && deepdive do has_zhiya
deepdive compile && deepdive do has_danbao

因子圖構建

這裏定義了一條依賴關係,即如果A將股權質押過給B,那麼一般來說認爲B不會質押給A

運行形成兩種關係的概率模型:

deepdive compile && deepdive do probabilities

----------------------------下是性能評價部分-----------------------------------------

運行Performance_evaluation.py腳本生成相關的性能評價結果

python3 Performance_evaluation.py transaction zhiya danbao 2

API 參數說明

python3 Performance_evaluation.py database relation_1 relation_2 test_size

database:數據庫名稱,如上述例子是transaction

relation : 是要看的哪些關係的結果,上述例子是查看了所有關係即zhiya,danbao

test_size:測試集大小,記得和打標部分設置的測試集大小保持一致

 

運行完上述結果後,會在當前路徑下生產一個Performance_evaluation文件夾,裏面包括如下:

一:每一種關係的性能圖

二:所有結果的csv文件

上述例子結果:

另外deepdive 自帶了評價性能的API即運行

deepdive do model/calibration-plots

其在下面的位置生成了tsv文件,相關圖片保存在run/model/calibration-plots/目錄中,具體含義爲:

上述圖片來源於開頭給的中文翻譯版鏈接

----------------------------以下是結束語----------------------------------------

到這裏就結束了,最後再總體歸納以下:

一:抽取一種新的實體關係時,需要做的改動就是app.ddlog,在其中定義相應的存儲結構和處理流程(主要就是調用腳本如python),其他的不用變,如果有特殊需求,需要做的就是編寫相應的python腳本即可,如上述的Performance_evaluation.py等等

二:deepdive的好壞,主要就是打標部分規則的定義以及因子圖部分的依賴關係規則的定義,其中前者尤爲主要,但是這也是目前關係抽取面臨的通病,那就是數據集構建的困難,如果人工構建耗時耗力,所以deeepdive採用的是使用規則去部分打標,目前使用比較多的就是“遠程監督”

三:上述多種關係的抽取其實可以看成是一種多標籤分類(多個二分類模型),如果多種關係之間存在互斥比如目前待抽取的關係是母子和姐妹即不會有同時滿足兩種關係的樣本,那麼其實還可以當前一個多分類來做,deepdive中提供了多分類做法,對應到上述類子就是

has_zhiya?(p1_id text, p2_id text).

改爲

tag?(word_id bigint) Categorical(13).

相當於定於就定義了tag就是一個有13種類型的類別變量關係

四:其中打標過程需要定義規則,比較耗時耗力,這也是一大缺點,爲此這裏寫了一個簡單的腳本,用以統計一些文本信息,定義規則的時候可以參考這些統計信息,具體使用很簡單(更多該方面的探索:https://blog.csdn.net/weixin_42001089/article/details/99408070):

一 模型下載

過程中主要使用了pyltp包,下載其預訓練好的一些模型和停用詞放到一個目錄如ltp_data_v3.4.0/目錄下

 

其中stopwords.txt就是停用詞,下載地址https://github.com/goto456/stopwords

二 數據準備

將要統計的兩個csv表格放到當前目錄,如danbao_articles.csv,danbao_record.csv

三 運行

python text_statistics.py -input_articles danbao_articles.csv -input_record danbao_record.csv

最後輸出的是一個rule_reference.txt,以下是部分截圖:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章