如何高效从文本中精准提取预定义的含多词、特殊符号的技术关键词
适配场景的最优算法:AC自动机(Aho-Corasick多模式匹配算法)
这个算法是你当前场景的最优解,完全覆盖你的所有需求,且性能完全满足Web接口的低延迟要求:3000个关键词的预处理只需要做一次,单篇5000字符的文本匹配耗时在毫秒级,内存占用可以忽略。
对应问题的解决方案
- 【多词术语被换行拆分】:先对待处理文本做预处理,把所有换行、制表符等各类空白字符统一替换为普通空格,同时统一转小写,不要删除任何特殊符号,避免破坏
c++、c#这类带特殊字符的关键词结构。 - 【多词组合匹配问题】:AC自动机本身支持任意长度的模式串匹配,不需要提前对文本做分词,无论是单字符的
r还是多词的neural networks都可以直接识别。 - 【短术语子串误匹配问题】:匹配到结果后加一步边界校验即可:判断匹配到的关键词前后位置,要么是文本边界,要么是非字母数字字符(空格、标点等)。比如匹配到
c时,如果它后面跟着+或#,就过滤掉该结果,只有前后都没有连续字母数字的c才会保留。如果存在互相包含的关键词(比如同时有neural networks和deep neural networks),可以在匹配完成后保留最长的匹配结果即可。 - 【带特殊符号的关键词匹配问题】:预处理阶段保留关键词和文本中的所有特殊符号,
c++、c#这类词会作为完整模式串存入自动机,可正常匹配。
落地实现参考(Python环境)
直接用成熟的第三方库pyahocorasick即可,不需要手动实现算法,服务启动时构建一次自动机,后续请求直接复用即可,示例代码如下:
import ahocorasick # 服务启动阶段:全局初始化一次AC自动机 ac_automaton = ahocorasick.Automaton() target_keywords = {'machine learning', 'r', 'python', 'neural networks', 'c', 'c#', 'docker'} kw_index_map = {} for idx, kw in enumerate(target_keywords): kw_lower = kw.lower() kw_index_map[idx] = kw_lower ac_automaton.add_word(kw_lower, idx) ac_automaton.make_automaton() # 接口请求阶段:单次文本匹配逻辑 def extract_keywords(raw_text: str) -> list: # 文本预处理:所有空白替换为空格,转小写 processed_text = ' '.join(raw_text.lower().split()) match_results = [] for end_idx, kw_idx in ac_automaton.iter(processed_text): matched_kw = kw_index_map[kw_idx] start_idx = end_idx - len(matched_kw) + 1 # 边界校验,避免子串误匹配 left_valid = start_idx == 0 or not processed_text[start_idx - 1].isalnum() right_valid = end_idx == len(processed_text) - 1 or not processed_text[end_idx + 1].isalnum() if left_valid and right_valid: match_results.append(matched_kw) # 去重后返回 return list(set(match_results))
内容的提问来源于stack exchange,提问作者Greeneco
相关产品推荐
相关产品推荐

