使用自定义词汇表调用CountVectorizer返回全零矩阵问题求助
问题原因
CountVectorizer默认的分词规则(token_pattern=r'(?u)\b\w\w+\b')仅会匹配由字母、数字、下划线组成的连续字符串,会将你词汇中包含的/、{、}等特殊字符识别为分词分隔符,把完整的长词汇拆成多个短碎片,无法和你传入的vocab列表里的完整词汇匹配,最终导致统计矩阵全零。
解决方案
根据你的文档内容格式,选择以下任意一种适配方案即可:
方案1:调整分词正则规则
如果你的词汇都是由大小写字母、数字、/、_、{、}、.组成的连续串,直接修改token_pattern参数适配你的词汇字符范围:
tf_vectorizer = CountVectorizer( input='filename', lowercase=False, vocabulary=vocab, # 匹配所有你词汇中包含的字符组成的连续串 token_pattern=r'[A-Za-z0-9/{}\._]+' ) tf = tf_vectorizer.fit_transform(doc_paths) X = tf.toarray()
方案2:自定义分词器
如果你的文档内词汇之间用空白/换行分隔,直接自定义分词逻辑避免拆分特殊字符,可靠性更高:
def custom_tokenizer(text): # 按任意空白字符(空格、换行、制表符等)拆分文本,不额外切割特殊字符 return text.split() tf_vectorizer = CountVectorizer( input='filename', lowercase=False, vocabulary=vocab, tokenizer=custom_tokenizer, token_pattern=None # 自定义分词器时必须关闭默认正则匹配规则 ) tf = tf_vectorizer.fit_transform(doc_paths) X = tf.toarray()
额外排查点
- 读取词汇表时建议过滤空行,避免无效词汇干扰:
with open(Path(VOCAB_FILE), "r") as f: vocab = [line.strip() for line in f if line.strip()] - 确认文档内的目标词汇和词汇表完全一致:如果文档里的路径是实际值(比如
{accountId}的位置是具体的数字ID),需要先把文档内的路径参数替换为对应占位符,才能匹配到词汇表的条目。 - 确认
doc_paths列表的路径指向正确,文档编码和CountVectorizer默认的utf-8编码一致,如果是其他编码可以加encoding='你文档的编码'参数。
内容的提问来源于stack exchange,提问作者Kaushal Kishore
相关产品推荐
相关产品推荐

