求推荐替代Spacy的轻量分词工具:需保留Token索引且性能更优
解决方案:优化Spacy或替代分词工具
一、优化Spacy的使用方式
1. 使用纯空白模型(仅保留分词器)
直接创建仅包含分词器的空白模型,比加载轻量模型再排除组件更高效,完全避免冗余组件的性能损耗:
import spacy # 创建仅含英文分词器的空白模型 nlp = spacy.blank("en") text = "I eat mangoes and I eat oranges" doc = nlp(text) for token in doc: print(token, "-->", token.i)
2. 转换为轻量数据结构
后续操作无需携带完整的Doc对象,提前将token的文本和索引转为普通元组列表,消除复杂对象的额外开销:
import itertools # 分词后转换为(文本, 索引)的轻量列表 tokens = [(token.text, token.i) for token in doc] # 改写后续操作函数,基于普通列表处理 def possible_long_forms(tokens_list): window_list_3 = [] for i in range(len(tokens_list)): if (i <= (len(tokens_list) - 5)) or (i == 0): window = tokens_list[i:i+5] window_list_3.append(window) window_list_3 = list(map(lambda x: list(itertools.combinations(x, 3)), window_list_3)) return window_list_3 # 测试 text_new = "I like mobiles and laptops" doc_new = nlp(text_new) tokens_new = [(t.text, t.i) for t in doc_new] results = possible_long_forms(tokens_new) print(results, '\n') first_item = results[0][0][0] print("Check index :", first_item[0], "-->", first_item[1])
二、替代Spacy的分词工具
1. NLTK(分词精度接近,轻量易用)
NLTK的word_tokenize分词精度与Spacy相当,支持处理缩写、标点等场景,通过enumerate直接获取token索引:
import nltk import itertools from nltk.tokenize import word_tokenize # 首次使用需下载分词模型 nltk.download('punkt') text = "I eat mangoes and I eat oranges" tokens = word_tokenize(text) for idx, token in enumerate(tokens): print(token, "-->", idx) # 适配后续操作 def possible_long_forms_nltk(tokens_list): window_list_3 = [] for i in range(len(tokens_list)): if (i <= (len(tokens_list) - 5)) or (i == 0): window = tokens_list[i:i+5] window_list_3.append(window) window_list_3 = list(map(lambda x: list(itertools.combinations(x, 3)), window_list_3)) return window_list_3 tokens_new = list(enumerate(word_tokenize("I like mobiles and laptops"))) tokens_new = [(t, idx) for idx, t in tokens_new] results = possible_long_forms_nltk(tokens_new) print(results, '\n') first_item = results[0][0][0] print("Check index :", first_item[0], "-->", first_item[1])
2. Hugging Face Tokenizers(高性能,匹配Spacy分词规则)
该库支持构建与Spacy对齐的分词逻辑,速度远快于Spacy,同时保证分词精度:
import itertools from tokenizers import Tokenizer from tokenizers.models import WordLevel from tokenizers.pre_tokenizers import WhitespaceSplit, Punctuation from tokenizers.processors import TemplateProcessing # 构建与Spacy对齐的分词器 tokenizer = Tokenizer(WordLevel(unk_token="[UNK]")) tokenizer.pre_tokenizer = WhitespaceSplit() + Punctuation() tokenizer.post_processor = TemplateProcessing( single="$A", special_tokens=[("[UNK]", tokenizer.token_to_id("[UNK]"))], ) text = "I eat mangoes and I eat oranges" output = tokenizer.encode(text) for idx, token in enumerate(output.tokens): print(token, "-->", idx) # 适配后续操作 tokens_new = list(enumerate(tokenizer.encode("I like mobiles and laptops").tokens)) tokens_new = [(t, idx) for idx, t in tokens_new] results = possible_long_forms_nltk(tokens_new) print(results, '\n') first_item = results[0][0][0] print("Check index :", first_item[0], "-->", first_item[1])
关键说明
- 核心优化思路是避免携带复杂对象(如Spacy Doc)进行后续计算,转换为普通元组/列表能大幅提升性能。
- 上述替代工具的分词精度在英文场景下与Spacy基本一致,可满足需求。
内容的提问来源于stack exchange,提问作者newbie101
相关产品推荐
相关产品推荐

