背景
比如我们有比较确定的几十类实体,并且每一类实体的值都是已知的,也就是在一个有限集合类做NER实体识别。
基于lucene的召回
- 把实体做成字典,比如 公司名,公司简称
- 设置实体识别的一些黑名单,比如【行业,公司,基金等等】
- 使用lucence对 数据字典中 name,alias等进行索引化。
- 对query 进行parer,然后使用lucence 查询索引中top10的排序。
自定义排序
- 对query 和 doc 进行2-gram的分词。
- 基于token list 计算最大的连续token序列,比如 query=“上海实业基金公司的业绩”,那么doc1=“上海实业”,doc2=“上海实业基金”
doc2的最大序列更长,那么应该就是doc2的得分更高。
正则表达进一步增强
- 使用正则表达式去识别一些时间,数字,公式等特殊的实体。
- 使用正则表达式去识别一些 有 数据字时间组合的实体,比如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)