多词/单关键词文档频率统计的鲁棒性问题及替代方案咨询
解决方案:鲁棒性关键词频率统计
正则表达式批量处理方案
针对关键词被额外字符分隔、批量关键词无法逐个编写正则的问题,可以通过批量生成适配分隔符的正则表达式解决,步骤如下:
- 转义正则特殊字符:避免关键词里的
.、*、?等字符干扰正则语法。 - 替换空格为通用分隔匹配规则:把关键词中的空格替换成
\W+,匹配任意非单词字符(多空格、逗号、句号等)的一次或多次出现。 - 合并批量正则:将所有处理后的关键词合并为一个正则表达式,一次性完成匹配,提升效率。
代码实现
import re from collections import defaultdict def count_robust_keywords(text, keywords): # 构建标准化关键词映射(用于匹配后还原原关键词) normalized_kw_map = {} pattern_components = [] for kw in keywords: # 转义正则特殊字符 escaped_kw = re.escape(kw) # 替换空格为匹配任意非单词字符的规则 processed_kw = escaped_kw.replace(r'\ ', r'\W+') pattern_components.append(f'(?:{processed_kw})') # 生成关键词的标准化形式(小写+移除所有非字母数字字符) normalized_kw = re.sub(r'\W', '', kw.lower()) normalized_kw_map[normalized_kw] = kw # 编译合并后的正则(可选忽略大小写) combined_pattern = re.compile('|'.join(pattern_components), re.IGNORECASE) # 统计匹配频率 freq = defaultdict(int) for match in combined_pattern.finditer(text): matched_text = match.group() # 标准化匹配结果,映射回原关键词 normalized_match = re.sub(r'\W', '', matched_text.lower()) if normalized_match in normalized_kw_map: freq[normalized_kw_map[normalized_match]] += 1 return dict(freq) # 测试示例 text = "your work is important. your, work needs polishing. Python code and python; code are useful." keywords = ["your work", "python code"] print(count_robust_keywords(text, keywords)) # 输出:{'your work': 2, 'python code': 2}
NLP工具库方案(spaCy)
如果需要更强的鲁棒性(比如处理换行、括号嵌套等复杂分隔),可以用spaCy的Matcher组件,它基于分词逻辑匹配短语,支持自定义匹配规则:
代码实现
import spacy from spacy.matcher import Matcher from collections import defaultdict def count_keywords_spacy(text, keywords): nlp = spacy.load("en_core_web_sm") matcher = Matcher(nlp.vocab) # 为每个关键词添加匹配规则:允许词之间插入任意数量的非字母token for kw in keywords: word_list = kw.split() pattern = [] for word in word_list: # 匹配对应小写的词 pattern.append({"LOWER": word.lower()}) # 允许插入任意数量的非字母token(标点、空格等) pattern.append({"IS_ALPHA": False, "OP": "*"}) # 移除最后一个多余的非字母token规则 pattern = pattern[:-1] matcher.add(kw, [pattern]) doc = nlp(text) matches = matcher(doc) # 统计频率 freq = defaultdict(int) for match_id, _, _ in matches: kw = nlp.vocab.strings[match_id] freq[kw] += 1 return dict(freq) # 测试示例 text = "your work is important. your, work needs polishing. Python code and python; code are useful." keywords = ["your work", "python code"] print(count_keywords_spacy(text, keywords)) # 输出:{'your work': 2, 'python code': 2}
方案选择
- 若需求简单、追求轻量快速,正则方案足够满足需求,无需额外依赖。
- 若处理复杂文本场景(如多语种、特殊格式文档),spaCy方案的鲁棒性更强,还能扩展支持更复杂的NLP匹配逻辑。
内容的提问来源于stack exchange,提问作者spectre
相关产品推荐
相关产品推荐

