如何利用spaCy的NOT_IN属性过滤含ID、ACTIVE的目标Token?
问题
现有Token集合:ADDRESS_ID、NAME、ADDRESS、CATEGORY_ID、FIRST_NAME、DAILY_ACTIVE,需要筛选出NAME、ADDRESS、FIRST_NAME这类Token,忽略所有包含ID、ACTIVE字样的Token。
尝试通过读取文件中的允许Token(如Name、Address)编写spaCy匹配模式,但当前模式无法过滤ADDRESS_ID这类带ID的Token,使用的模式如下:
newPattern = [{"LOWER": line.rstrip()}] newPattern2 = [{"LOWER": {"NOT_IN":["ID"], "REGEX": "[_]{}".format(line.rstrip())}}] newPattern3 = [{"LOWER": {"REGEX": "{}[_]".format(line.rstrip()), "NOT_IN":["ID"]}}]
解决方法
方法1:预处理阶段直接过滤Token
在spaCy匹配前,先对Token列表做一次过滤,直接排除包含禁用关键词的Token,同时保留允许的Token:
# 从文件读取允许的Token并转为小写集合 allowed_tokens = {line.rstrip().lower() for line in open("allowed_tokens.txt")} # 定义禁用关键词 blocked_keywords = {"id", "active"} # 过滤Token:在允许列表中,且不包含任何禁用关键词 filtered_tokens = [ tok for tok in doc if tok.lower() in allowed_tokens and not any(keyword in tok.lower() for keyword in blocked_keywords) ]
方法2:修正spaCy匹配模式(精确匹配)
之前的模式问题在于只做了局部片段匹配,没有从整体上检查Token是否包含禁用词。可以调整为匹配完整允许Token且排除含禁用词的Token:
allowed = {line.rstrip().lower() for line in open("allowed_tokens.txt")} blocked = {"id", "active"} # 模式1:用IN匹配允许Token,同时用REGEX排除含禁用词的情况 pattern = [ { "LOWER": { "IN": list(allowed), "REGEX": r"^(?!.*(id|active)).*$" } } ] # 模式2:拆分条件,更直观 pattern = [ { "LOWER": {"IN": list(allowed)}, "LOWER": {"NOT_REGEX": r".*(id|active).*"} } ]
失效原因说明
之前的newPattern2和newPattern3是匹配Token中包含_允许词或允许词_的局部片段,但ADDRESS_ID的小写是address_id,其中address属于允许词,但整个Token包含id,你的模式没有检查整个Token是否包含禁用词,只是做了局部匹配,因此会误匹配到ADDRESS_ID。
内容的提问来源于stack exchange,提问作者Vibs
相关产品推荐
相关产品推荐

