用Lucene和Bert做有限集合的NER識別

背景

比如我們有比較確定的幾十類實體,并且每一類實體的值都是已知的,也就是在一個有限集合類做NER實體識別。

基于lucene的召回

  • 把實體做成字典,比如 公司名,公司簡稱
  • 設置實體識別的一些黑名單,比如【行業(yè),公司,基金等等】
  • 使用lucence對 數(shù)據(jù)字典中 name,alias等進行索引化。
  • 對query 進行parer,然后使用lucence 查詢索引中top10的排序。

自定義排序

  • 對query 和 doc 進行2-gram的分詞。
  • 基于token list 計算最大的連續(xù)token序列,比如 query=“上海實業(yè)基金公司的業(yè)績”,那么doc1=“上海實業(yè)”,doc2=“上海實業(yè)基金”
    doc2的最大序列更長,那么應該就是doc2的得分更高。

正則表達進一步增強

  • 使用正則表達式去識別一些時間,數(shù)字,公式等特殊的實體。
  • 使用正則表達式去識別一些 有 數(shù)據(jù)字時間組合的實體,比如2021年到2022年。

Bert 做NER

from transformers import AutoTokenizer, AutoModelForTokenClassification
from transformers import pipeline
from flask import Flask, request, jsonify
import numpy as np
import json

tokenizer = AutoTokenizer.from_pretrained("xlm-roberta-large-finetuned-conll03-english")
model = AutoModelForTokenClassification.from_pretrained("xlm-roberta-large-finetuned-conll03-english")
classifier = pipeline("ner", model=model, tokenizer=tokenizer,grouped_entities=True)

app = Flask(__name__)


def jsonify_with_numpy(obj):
    def default_converter(o):
        if isinstance(o, np.float32):
            return float(o)
        raise TypeError(f"Object of type {o.__class__.__name__} is not JSON serializable")
    return jsonify(json.dumps(obj, default=default_converter,ensure_ascii=False))

@app.route('/api/ner/rbt_qa/predict', methods=['POST'])
def predict():
    data = request.get_json()
    text = data['user_query']
    res = classifier(text)
    for r in res:
        if isinstance(r['score'],np.float32):
            r['score']=float(r['score'])
    return res

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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