tokenizers无encode_plus方法时如何构建m×n文本特征矩阵
基于tokenizers库高效构建m×n特征矩阵方案
你需要的m×n矩阵(m为样本数、n为词表总token数)本质是词袋形式的特征矩阵,完全不需要依赖encode_plus方法,基于你现有可用的encode_batch接口配合numpy向量化操作即可实现最高效的构建,全程无冗余Python循环,性能远高于逐样本遍历统计的方案。
步骤1:补全批量编码的截断配置
你当前封装的批量编码函数仅配置了padding,未开启截断,长文本会产生溢出token导致输出长度不一致,先补全配置:
def tokenize_sentences(sentences, tokenizer, max_seq_len = 128): # 固定padding长度,同时开启截断,保证所有输出序列长度统一 tokenizer.enable_padding(pad_id=3, pad_token="[PAD]", direction='right', length=max_seq_len) tokenizer.enable_truncation(max_length=max_seq_len) tokenized_sentences = tokenizer.encode_batch(sentences) return tokenized_sentences
步骤2:获取词表总大小n
直接从tokenizer实例读取词表大小,不需要手动统计:
n = tokenizer_WLV.get_vocab_size()
步骤3:向量化批量生成特征矩阵(核心最优实现)
全程使用numpy向量化操作,避免Python层面的逐样本、逐token循环,所有计数逻辑在C层完成,十万级样本可秒级处理:
import numpy as np # 加载所有样本并批量编码 sentences = [...] # 替换为你的待处理文本列表 all_encodings = tokenize_sentences(sentences, tokenizer_WLV, max_seq_len=128) m = len(all_encodings) # 一次性提取所有样本的token id,形状为(m, max_seq_len) all_token_ids = np.array([enc.ids for enc in all_encodings], dtype=np.int32) # 一次性提取所有样本的attention mask,用于后续过滤填充位 all_attention_masks = np.array([enc.attention_mask for enc in all_encodings], dtype=bool) # 初始化m×n全零特征矩阵,根据最大词频选择合适的dtype节省内存 feature_matrix = np.zeros((m, n), dtype=np.int16) # 批量统计每个token在对应样本中的出现次数 row_index = np.repeat(np.arange(m), all_token_ids.shape[1]) col_index = all_token_ids.flatten() valid_mask = all_attention_masks.flatten() # 自动过滤[PAD]填充位 np.add.at(feature_matrix, (row_index[valid_mask], col_index[valid_mask]), 1)
最终得到的feature_matrix就是你需要的m×n特征矩阵,矩阵中第i行第j列的值代表第i个样本中,词表id为j的token出现的次数。
补充说明
- 如果你需要的不是词袋特征,而是可直接输入深度模型的等长序列输入,不需要构建m×n的全词表矩阵,直接使用
all_token_ids和all_attention_masks两个数组即可,形状均为(m, max_seq_len),完全匹配Transformer类模型的输入要求。 - 如果需要TF-IDF加权特征,直接将生成的词袋特征矩阵输入sklearn的
TfidfTransformer拟合转换即可,不需要重复做分词编码。 - 可根据需求在
valid_mask中额外增加[UNK]等特殊token的过滤逻辑,避免无意义特征干扰分类器效果。
内容的提问来源于stack exchange,提问作者Areza
相关产品推荐
相关产品推荐

