背景
比如我們有比較確定的幾十類實體,并且每一類實體的值都是已知的,也就是在一個有限集合類做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)