1. 程式人生 > >基於keras實現的中文實體識別

基於keras實現的中文實體識別

1、簡介

NER(Named Entity Recognition,命名實體識別)又稱作專名識別,是自然語言處理中常見的一項任務,使用的範圍非常廣。命名實體通常指的是文字中具有特別意義或者指代性非常強的實體,通常包括人名、地名、機構名、時間、專有名詞等。NER系統就是從非結構化的文字中抽取出上述實體,並且可以按照業務需求識別出更多類別的實體,比如產品名稱、型號、價格等。

命名實體識別是資訊提取、問答系統、句法分析、機器翻譯等應用領域的重要基礎工具,作為結構化資訊提取的重要步驟。

2、常見演算法

2.1、基於規則和詞典的方法

基於規則和詞典的方法是命名實體識別中最早使用的方法,多采用語言學專家構造規則模板,選用特徵包括統計資訊、標點符號、關鍵字、指示詞和方向詞、位置詞、中心詞等方法,以模式和字串相匹配為主要手段,這類系統大多依賴於知識庫和詞典的建立。

2.2、基於統計的方法 

基於統計機器學習的方法主要包括:隱馬爾可夫模型、最大熵、支援向量機、條件隨機場等。

在這4種學習方法中,最大熵模型結構緊湊,具有較好的通用性,主要缺點是訓練時間複雜性非常高,有時甚至導致訓練代價難以承受,另外由於需要明確的歸一化計算,導致開銷比較大。而條件隨機場為命名實體識別提供了一個特徵靈活、全域性最優的標註框架,但同時存在收斂速度慢、訓練時間長的問題。一般說來,最大熵和支援向量機在正確率上要比隱馬爾可夫模型高一些,但是隱馬爾可夫模型在訓練和識別時的速度要快一些,主要是由於在利用維特比演算法求解命名實體類別序列的效率較高。隱馬爾可夫模型更適用於一些對實時性有要求以及像資訊檢索這樣需要處理大量文字的應用,如短文字命名實體識別。

 2.3、基於深度學習的方法

隨著深度學習的興起,RNN、LSTM、Bi-LSTM等模型已經被證明在NLP任務上有著良好的表現。相比傳統模型,RNN能夠考慮長遠的上下文資訊,並且能夠解決CRF特徵選擇的問題,可以將主要的精力花在網路設計和引數調優上,但RNN一般需要較大的訓練資料,在小規模資料集上,CRF表現較好。 

3、中文實體識別

目前比較流行的做法是將Bi-LISTM和CRF進行結合,借鑑兩個模型各自的優點,來達到更好的效果。模型圖如下:

 

LSTM的全稱是Long Short-Term Memory,它是RNN(Recurrent Neural Network)的一種。LSTM由於其設計的特點,非常適合用於對時序資料的建模,如文字資料。Bi-LSTM是Bi-directional Long Short-Term Memory的縮寫,是由前向LSTM與後向LSTM組合而成。兩者在自然語言處理任務中都常被用來建模上下文資訊。

CRF(Conditional random field,條件隨機場)是一種判別式模型,是給定一組輸入隨機變數條件下另一組輸出隨機變數的條件概率分佈模型。

3.1 實體類別定義

實體類別包括以下6種:

time: 時間

location: 地點

person_name: 人名

org_name: 組織名

company_name: 公司名

product_name: 產品名 

3.2 資料標註

採用UTF-8進行編碼,每行為一個段落標註。所有的實體以如下的格式進行標註: 

{{實體型別:實體文字}}

示例:

此次{{location:中國}}個展,{{person_name:蘇珊}}將與她80多歲高齡的父親一起合作,哼唱一首古老的{{location:威爾士}}民歌{{product_name:《白蠟林》}}。屆時在{{location:畫廊大廳}}中將安放6個音箱進行播放,藝術家還特意回到家鄉{{location:格拉斯哥}},同父親一起在{{org_name:中國音樂學院}}裡為作品錄製了具有{{location:中國}}元素的音樂片段。 

3.3 標籤體系

對於NER任務,常見的標籤體系包括IO、BIO、BMEWO、BMEWO+。下面舉例說明不同標籤體系的區別。

 

 

 大部分情況下,標籤體系越複雜準確度也越高,但相應的訓練時間也會增加。因此需要根據實際情況選擇合適的標籤體系。這裡選擇和分詞系統類似的BMEWO標籤體系。

3.4 環境搭建

基於keras + tensorflow實現Bi-LSTM + CRF實體識別。目前使用2.2.4版本的keras,在keras版本里面已經包含bilstm模型,但crf的loss function還沒有,可以從keras contribute中獲得,具體可參看:

https://github.com/keras-team/keras-contrib

環境搭建請參考這篇博文: https://www.cnblogs.com/MikeZhang/p/createKerasEnv-20210228.html

3.5 示例程式碼

訓練程式碼:

#! /usr/bin/env python3
#-*- coding:utf-8 -*- 

import process_data,os
from bilsm_crf_model import create_model

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
EPOCHS = 1

(train_x, train_y), (test_x, test_y), (vocab, chunk_tags) = process_data.load_data()
model = create_model(len(vocab),len(chunk_tags))
# train model
model.fit(train_x, train_y,batch_size=128,epochs=EPOCHS, validation_data=[test_x, test_y])
model.save('model/ner_crf.h5')

測試程式碼:

#! /usr/bin/env python3
#-*- coding:utf-8 -*- 

import bilsm_crf_model
import process_data
import numpy as np
import pickle

def doParse(predict_text):
    model,vocab,chunk_tags = None,None,None
    with open('model/config.pkl', 'rb') as inp:
        (vocab, chunk_tags) = pickle.load(inp)
        model = bilsm_crf_model.create_model(len(vocab),len(chunk_tags))
    if not model : return None
    model.load_weights('model/ner_crf.h5')
    
    str,length = process_data.process_data(predict_text, vocab)
    raw = model.predict(str)[0][-length:]
    result = [np.argmax(row) for row in raw]
    result_tags = [chunk_tags[i] for i in result]

    per, loc, org,company,product = '', '', '','',''
    #print(result_tags)
    resultMap = {}
    for s, t in zip(predict_text, result_tags):
        #print(s,t)
        if 'O' == t : continue
        key = t[2:]
        if t.startswith('B_'):
            if key not in resultMap : resultMap[key] = ''
            resultMap[key] += ' ' + s
        else:
            resultMap[key] += s
    return resultMap

predict_text = '中華人民共和國國務院總理在外交部長的陪同下,連續訪問了衣索比亞等非洲10國以及阿爾巴尼亞'
resultMap = doParse(predict_text)
print(predict_text)
for k,v in resultMap.items():
    print("%s : %s" % (k,v))

示例程式碼目錄結構:

 本文涉程式碼及資源下載地址:https://pan.baidu.com/s/1w9T_mDxwqfzQ3Xf8_3FLrw

可關注微信公眾號(聊聊博文)後回覆 2021022801 獲取提取