使用spaCy提取不规范语句名词时,如何过滤无意义词汇、保留有效语义名词
分层过滤实现方案
前置预处理:从源头剔除明显无效候选
现有预处理逻辑对带数字、孤立短缩写、超长硬拼串的过滤不足,可先通过正则初筛缩窄候选范围,从源头减少无效词进入后续词性判断流程:
- 直接过滤文本中混杂阿拉伯数字的片段(如
foward2、64x这类带版本/单位标记的词汇) - 过滤长度小于3个字符的孤立短串(如单字母
r、两字母缩写ms) - 过滤长度超过12个字符的无分隔长连写串(如
brailledisplayfastmovement这类人工拼接的无意义组合)
对应优化后的预处理代码:
import spacy import re nlp = spacy.load("en_core_web_sm") sentence = "HANDBRAKE - slow and fast (SFX)" cleanString = re.sub(r'[^\w\s]', ' ', sentence.lower()) # 初筛有效候选片段 raw_candidates = [ t for t in cleanString.split() if not re.search(r'\d', t) # 剔除带数字的片段 and 3 <= len(t) <= 12 # 剔除过短/过长的无意义片段 ] processed_text = " ".join(raw_candidates) doc = nlp(processed_text)
核心语义校验:替代死板的Wordnet交集过滤
之前用Wordnet做交集过滤的核心问题是覆盖范围窄、规则刚性强,容易误杀拟声词、日常通用名词。可直接利用spaCy模型内置的词频属性做通用语义判断,精度远高于静态词表交集:
- 叠加
token.is_oov判断:该属性会直接标记当前词汇是否属于模型内置的核心常用英语词汇表,那些行业专属缩写(如sfx、pwm)、拼写错误的乱串、非通用专业术语,都会被标记为OOV(超出核心词汇范围),直接被滤除 - 搭配
token.pos_词性判断,只保留同时满足“通用核心词”+“名词词性”的候选,这类词基本就是broom、ticker、pool、highway、motorbike、whoosh、suitcase这类具备通用实际语义的词汇
对应核心过滤逻辑代码:
# 自定义已知无效词黑名单兜底 blacklist = {"sfx", "pwm", "ms", "bit", "brailledisplayfastmovement"} valid_nouns = [] for token in doc: if token.pos_ == "NOUN" \ and not token.is_oov \ and token.text not in blacklist: valid_nouns.append(token.text)
方案效果验证
针对提到的两个测试场景,优化后的输出结果为:
- 输入语句
"HANDBRAKE - slow and fast (SFX)":sfx会因为属于黑名单/超出核心词汇范围被剔除,通用名词handbrake会被正确保留 - 输入语句
"fast foward2":foward2因为带数字,在预处理阶段就被剔除,不会进入后续判断流程
该方案既不会因为Wordnet的刚性规则误杀motorbike、whoosh、trolley这类有效名词,也能把行业缩写、拼写错误、硬拼长串这类无意义混杂词全部过滤掉。
内容的提问来源于stack exchange,提问作者Saba Nazir
相关产品推荐
相关产品推荐

