用深度學(xué)習(xí)做命名實(shí)體識(shí)別(附代碼)

標(biāo)簽: BILSTM-CRF
作者: 煉己者


歡迎大家訪問(wèn)我的簡(jiǎn)書以及我的博客
本博客所有內(nèi)容以學(xué)習(xí)、研究和分享為主,如需轉(zhuǎn)載,請(qǐng)聯(lián)系本人,標(biāo)明作者和出處,并且是非商業(yè)用途,謝謝!

基于CRF做命名實(shí)體識(shí)別系列
用CRF做命名實(shí)體識(shí)別(一)
用CRF做命名實(shí)體識(shí)別(二)
用CRF做命名實(shí)體識(shí)別(三)

一. 摘要

  • 之前用CRF做了命名實(shí)體識(shí)別,效果還可以,最高達(dá)到0.9293,當(dāng)然這是自己用sklearn寫的計(jì)算F1值,后來(lái)用conlleval.pl對(duì)CRF測(cè)試結(jié)果進(jìn)行評(píng)價(jià),得到的F1值是0.9362。
  • 接下來(lái)基于BILSTM-CRF做命名實(shí)體識(shí)別,代碼不是自己寫的,用的github上的一個(gè)大佬寫的,換了自己的數(shù)據(jù)集,得到最終的結(jié)果是0.92
  • 本文主要簡(jiǎn)單的介紹下BILSTM-CRF的原理,以及如何把大佬的數(shù)據(jù)集換成我們自己的數(shù)據(jù)集,進(jìn)行訓(xùn)練。

二. 正文

如果你想細(xì)致地了解BILSTM,那你首先得去看RNN(循環(huán)神經(jīng)網(wǎng)絡(luò)),然后再看RNN的升級(jí)版本LSTM,最好才能過(guò)渡到BILSTM。了解完這些再去看CRF(條件隨機(jī)場(chǎng)),CRF這邊可又是一番天地了,等你了解完你的老板該炒你魷魚了。所以對(duì)于初學(xué)者我一向主張不擇手段先把模型跑下來(lái),跑出結(jié)果,然后才有信心去好好學(xué)習(xí)原理。在這里還是要好好感謝那位大佬。

1. BILSTM-CRF的原理簡(jiǎn)介

如果你不懂什么叫做BILSTM,CRF,沒(méi)關(guān)系,你只要知道他們是命名實(shí)體識(shí)別里兩個(gè)層就行,就像神經(jīng)網(wǎng)絡(luò)里的概念一樣,層次結(jié)構(gòu)。


BILSTM-CRF

如上圖,這里面做了一件什么事情呢?

  • 輸入是詞向量,這個(gè)直接用word2vec訓(xùn)練就能得到
  • 輸出是每個(gè)句子預(yù)測(cè)的標(biāo)簽

流程

詞向量輸入到 BILSTM層 ,然后輸出值是這句話每個(gè)標(biāo)簽的預(yù)測(cè)分?jǐn)?shù),這些分?jǐn)?shù)便是 CEF層 的輸入,其實(shí)沒(méi)有CRF層我們也可以訓(xùn)練 BILSTM,但是我們就不能保證每次預(yù)測(cè)的都是對(duì)的,因?yàn)樗锌赡芎鷣?lái),比如第一個(gè)預(yù)測(cè)的是B-PER,下一個(gè)預(yù)測(cè)的是B-ORG,這就不符合自然語(yǔ)言的規(guī)則了,所以我們加入了CRF這一層,用來(lái)約束這些標(biāo)簽,它可以自動(dòng)地去學(xué)習(xí)這些約束。
那么CRF是怎么學(xué)習(xí)這些約束的呢?
簡(jiǎn)單地說(shuō)就是計(jì)算每個(gè)標(biāo)簽下一個(gè)標(biāo)簽地概率,概率大就有可能出現(xiàn)這樣的標(biāo)簽,概率小就不會(huì)出現(xiàn)了。


2. 他山之石,可以攻玉

1). 保證代碼運(yùn)行正確

Chinese NER
大家點(diǎn)擊去Clone下來(lái)就行
然后就是重點(diǎn)來(lái)了!??!
下載下來(lái)運(yùn)行并不會(huì)那么順利,會(huì)報(bào)錯(cuò)的

首先打開(kāi)main.py文件,如果訓(xùn)練的話就是圖中的兩個(gè)True,如果測(cè)試的話就把圖中的兩個(gè)True改成False

flags = tf.app.flags
flags.DEFINE_boolean("clean",       True,      "clean train folder")
flags.DEFINE_boolean("train",       True,      "Wither train the model")
  • 錯(cuò)誤1
    TypeError: slice indices must be integers or None or have an index method
    解決方案:遇到這個(gè)錯(cuò)誤你就去data_utils.py文件里找到下面的代碼,改一下即可
    def sort_and_pad(self, data, batch_size):
        num_batch = int(math.ceil(len(data) /batch_size))
        sorted_data = sorted(data, key=lambda x: len(x[0]))
        batch_data = list()
        for i in range(num_batch):
            batch_data.append(self.pad_data(sorted_data[i*int(batch_size) : (i+1)*int(batch_size)]))
        return batch_data
  • 錯(cuò)誤2
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa3 in position 0: invalid start byte
    解決方案:這個(gè)是編碼問(wèn)題,遇到這個(gè)問(wèn)題你就進(jìn)到utils.py里,找到下面的代碼,加上一句encoding = 'utf-8'就OK了。我印象中是這幾處,如果還報(bào)這個(gè)錯(cuò)誤就繼續(xù)排查類似的即可
def test_ner(results, path):
    """
    Run perl script to evaluate model
    """
    output_file = os.path.join(path, "ner_predict.utf8")
    with open(output_file, "w", encoding='utf-8') as f:
        to_write = []
        for block in results:
            for line in block:
                to_write.append(line + "\n")
            to_write.append("\n")

        f.writelines(to_write)
    eval_lines = return_report(output_file)
    return eval_lines

def save_config(config, config_file):
    """
    Save configuration of the model
    parameters are stored in json format
    """
    with open(config_file, "w", encoding="utf8") as f:
        json.dump(config, f, ensure_ascii=False, indent=4)


def load_config(config_file):
    """
    Load configuration of the model
    parameters are stored in json format
    """
    with open(config_file, encoding="utf8") as f:
        return json.load(f)
  • 錯(cuò)誤3
    NameError: name 'os' is not defined
    這個(gè)錯(cuò)誤很奇怪,我是看到作者代碼里有導(dǎo)入os的
    解決方案:import os

2). 更換數(shù)據(jù)集

打開(kāi)下載下來(lái)的文件,data文件夾里面有三個(gè)文件,分別為驗(yàn)證,測(cè)試,訓(xùn)練數(shù)據(jù)集,你只需把你的數(shù)據(jù)集切分成這三份即可(比例自己定,我的是7:2:1)。

  • 標(biāo)簽必須得是BIO格式,總之你的標(biāo)簽要和它的一模一樣。
  • 還有標(biāo)識(shí)符,windows生成的數(shù)據(jù)集文件我們發(fā)現(xiàn)換行符都是\r\n,也就是在notpad++上打開(kāi)的話,顯示所有標(biāo)識(shí)符后會(huì)發(fā)現(xiàn)CRLF,我們要把它改成LF。
    可以用替換的方法,直接把\r\n替換成\n,這樣就滿足條件了

3). 訓(xùn)練

這些操作之后你就可以運(yùn)行main.py了

三. 總結(jié)與展望

最近一直在努力地理解這些個(gè)原理,爭(zhēng)取早日攻克它們。大家工作的話一般項(xiàng)目會(huì)比較緊急,沒(méi)有時(shí)間給你慢慢理解原理,然后再去寫代碼做項(xiàng)目。所以要學(xué)會(huì)用別人的代碼,改造它們,讓它為自己所用。最后很感謝github的那位大佬,真的很厲害。希望這篇博客能幫到大家,謝謝各位


以下是我所有文章的目錄,大家如果感興趣,也可以前往查看
??戳右邊:打開(kāi)它,也許會(huì)看到很多對(duì)你有幫助的文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、meta標(biāo)簽的三個(gè)屬性 title: 30字以內(nèi),簡(jiǎn)約且全面,避免重復(fù),可以用主關(guān)鍵詞+吸引用戶詞+品牌詞,以...
    TTTXTTT閱讀 376評(píng)論 0 1
  • 1.JDBC 作用:連接數(shù)據(jù)庫(kù)并發(fā)送SQL語(yǔ)句,本身不具備操作數(shù)據(jù)庫(kù)的能力。 流程:1)注冊(cè)驅(qū)動(dòng); Class.f...
    sunnysans閱讀 340評(píng)論 0 1
  • 原創(chuàng)教程:PC機(jī)安裝黑蘋果 主板bios與硬盤分區(qū)格式 選擇安裝方式初探 其實(shí)安裝黑蘋果機(jī)器這么多,現(xiàn)在的新手遇到...
    易江南從心出發(fā)閱讀 1,358評(píng)論 0 2
  • 所有人都朝聲音的方向看去,原來(lái)是飯館的老板。 飯店老板胡不吃站在臺(tái)階上面,一臉兇相,俯視著眾人,他圓腦袋,圓脖子,...
    小眼睛大鼻子閱讀 308評(píng)論 0 1

友情鏈接更多精彩內(nèi)容