You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sklearn CountVectorizer自定义分词器tokenize2输出异常问题

问题分析与解决

问题重现

你尝试用自定义分词器构建CountVectorizer,但tokenize2的向量输出不符合预期:

temp_tok = ["or", "Normal sinus rhythm", "sinus", "anuj","Normal sinus"]

def tokenize(text):
    return [temp_tok[0],temp_tok[1], "sinus", "Normal sinus"]

def tokenize2(text):
    return [i for i in temp_tok if i in text]

text = "Normal sinus rhythm"

# 直接调用分词器,输出一致
print(tokenize(text))
# 输出: ['or', 'Normal sinus rhythm', 'sinus', 'Normal sinus']
print(tokenize2(text))
# 输出: ['or', 'Normal sinus rhythm', 'sinus', 'Normal sinus']

# 构建向量器
vectorizer = CountVectorizer(vocabulary=temp_tok,tokenizer = tokenize)
vectorizer2 = CountVectorizer(vocabulary=temp_tok,tokenizer = tokenize2)

# 向量输出差异
print(vectorizer.transform([text]).toarray())
# 输出: array([[1, 1, 1, 0, 1]])
print(vectorizer2.transform([text]).toarray())
# 输出: array([[1, 0, 1, 0, 0]])

核心原因

问题出在CountVectorizer的默认预处理逻辑,以及直接调用分词器和向量器内部调用的差异:

  1. 默认小写转换:CountVectorizer默认开启lowercase=True,会先把输入文本转为小写,再传给自定义分词器。
    • 你直接调用tokenize2(text)时,传入的是原始大写开头的"Normal sinus rhythm",所以"Normal sinus rhythm" in text为True;
    • 但向量器内部调用tokenize2时,传入的是预处理后的小写文本"normal sinus rhythm",此时大写的"Normal sinus rhythm"和"Normal sinus"无法匹配小写文本,导致这两个token不会被返回。
  2. "or"的误匹配:原始文本中的"Normal"包含子串"or",所以直接调用时"or" in text为True,向量器内部处理时小写的"normal"也包含"or",所以这个token会被保留。

解决方法

针对这个问题,有两种可行的修复方式:

方式一:关闭默认小写转换

初始化CountVectorizer时设置lowercase=False,让向量器不修改原始文本的大小写,这样分词器能正确匹配词汇表中的内容:

vectorizer2 = CountVectorizer(vocabulary=temp_tok, tokenizer=tokenize2, lowercase=False)
print(vectorizer2.transform([text]).toarray())
# 输出: array([[1, 1, 1, 0, 1]])

方式二:统一分词器和词汇表的大小写

如果需要保留小写转换的逻辑,可将词汇表转为小写,同时修改分词器的匹配逻辑:

# 将词汇表转为小写
temp_tok_lower = [tok.lower() for tok in temp_tok]

def tokenize2_lower(text):
    # 此时text已经是小写,匹配小写的词汇表元素
    return [i for i in temp_tok_lower if i in text]

vectorizer2 = CountVectorizer(vocabulary=temp_tok_lower, tokenizer=tokenize2_lower)
print(vectorizer2.transform([text]).toarray())
# 输出: array([[1, 1, 1, 0, 1]])

额外说明

  • 自定义分词器在CountVectorizer中的执行时机是预处理之后,所以必须考虑预处理步骤(如小写转换、去除标点等)对输入文本的影响;
  • 当使用vocabulary参数时,确保分词器返回的token与词汇表的格式(大小写、字符串完全匹配)一致,否则无法正确计数。

内容的提问来源于stack exchange,提问作者Anuj Chopra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 00:31:14