BERT NER提取ORG实体返回“company”而非实际公司名的问题咨询
BERT NER提取固定格式公司名误判通用词解决方案
问题核心
基于transformers库的预训练BERT NER模型做公司名提取时,因输入截取逻辑未过滤固定模板内容,导致模板内通用词company被误判为ORG类实体,无法获取真实公司名。
已知待处理文本的公司名遵循固定格式:
- 格式1:
COMPANY NAME: the company's name is XXX - 格式2:
NAME: the company's name is XXX
原有实现仅通过匹配name关键词截取后续100字符传入模型,未排除模板内的无效内容,且因部分文本存在连续两次company表述,无法直接通过单次匹配company截断前缀。
无需微调模型,规则+NER组合方案即可100%规避问题
固定模板场景下微调模型性价比极低,用简单规则预处理即可解决问题,开发成本远低于微调,准确率更高。
第一步:用正则精准定位真实公司名起始位置
不要仅匹配name关键词做截断,直接写兼容两种格式、兼容多连续company场景的正则,匹配从字段开头到is 的完整固定前缀,从前缀结束位置开始截取待识别文本,从根源上避免模板内的company词汇进入NER输入。
正则规则兼容大小写、标点、单复数、所有格、多连续company变体:
import re # 匹配固定前缀的正则 COMPANY_PREFIX_PATTERN = re.compile( r'(company\s+)?name\s*:?\s*(the\s+(company[\'s]?\s+)+name\s+is\s+)', re.IGNORECASE )
第二步:增加实体结果兜底过滤
如果存在少量模板变体,正则没有完全截掉前缀,就在NER返回结果层加一层过滤,跳过所有值为company/companies的ORG实体,取后续第一个有效ORG实体即可。真实公司名均为专有名词,首字母大写,不会被该规则误杀。
完整修改后代码
def get_company_info(text, tokenizer_1, model_1, tokenizer_2, model_2): company_info = {"name": None} try: prefix_match = COMPANY_PREFIX_PATTERN.search(text) if not prefix_match: return company_info # 从真实公司名起始位置截取文本,避免模板内容干扰 valid_segment = text[prefix_match.end():prefix_match.end()+100] ner_result = NLP_2(valid_segment, tokenizer_2, model_2) for entity in ner_result: if entity['entity_group'] != 'ORG': continue # 兜底过滤通用词 entity_word = entity['word'].strip() if entity_word.lower() in ['company', 'companies']: continue company_info['name'] = entity_word break except: pass return company_info
什么时候需要微调
只有当待处理文本无统一固定格式、通用词误判占比超过10%、规则无法覆盖所有场景时,才需要标注业务数据做模型微调。当前固定模板场景下,上述规则方案的效果、开发效率、维护成本都远优于模型微调。
内容的提问来源于stack exchange,提问作者EscStack
相关产品推荐
相关产品推荐

