0

0

解决Python CountVectorizer忽略数字符号的问题

心靈之曲

心靈之曲

发布时间:2025-12-08 15:30:01

|

380人浏览过

|

来源于php中文网

原创

解决python countvectorizer忽略数字符号的问题

本文旨在探讨并解决在使用Python的`CountVectorizer`进行文本向量化时,默认行为会忽略数字前的正负号(如`+83`、`-193`)的问题。我们将深入分析`CountVectorizer`的默认分词机制,并提供一种基于自定义分词器的解决方案,通过结合正则表达式精确捕捉并保留带有符号的数字,从而生成更符合预期的词袋模型。

理解CountVectorizer的默认分词机制

CountVectorizer是scikit-learn库中一个强大的文本特征提取工具,它通过将文本文档转换为词频矩阵(或称词袋模型,Bag of Words)来为机器学习模型准备数据。然而,在处理包含数字及其符号(如+83、-193)的文本时,用户可能会发现最终生成的特征列名称中,这些符号被意外地移除了。例如,+83和-193可能都被识别为83和193。

这种行为并非错误,而是CountVectorizer默认分词器设计的结果。默认情况下,CountVectorizer使用一个正则表达式来识别“词”(token)。这个默认的正则表达式通常旨在匹配字母数字字符序列,而会忽略标点符号和特殊字符,包括+和-。这意味着,当它遇到+83时,+会被视为分隔符或非词字符,而83则被识别为一个词。同理,-193中的-也会被忽略,只留下193。

例如,对于以下文本数据:

立即学习Python免费学习笔记(深入)”;

RepID, Txt
1, +83 -193 -380 +55 +901
2, -94 +44 +2892 -60
3, +7010 -3840 +3993

如果直接使用默认的CountVectorizer进行处理,其输出的特征名称将是83, 193, 380, 55等,而非+83, -193。

解决方案:实现自定义分词器

要解决CountVectorizer忽略数字符号的问题,核心在于提供一个自定义的分词器(tokenizer)。这个自定义分词器需要能够识别并保留数字前的正负号。我们可以利用Python的re模块和正则表达式来精确地实现这一点。

InstantMind
InstantMind

AI思维导图生成器,支持30+文件格式一键转换,包括PDF、Word、视频等。

下载

构建自定义分词函数

我们的自定义分词函数需要能够将输入字符串按照数字(包括其可选的正负号)进行分割,并确保每个数字(带符号)作为一个独立的词项被返回。

考虑使用re.split()函数,它可以通过正则表达式将字符串分割成列表。关键在于构建一个能够捕获数字及其符号的正则表达式,并利用括号将其作为分割结果的一部分保留。

import re
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
import numpy as np

def custom_tokenizer(text):
    """
    自定义分词器,用于将文本分割成词项,同时保留数字前的正负号。

    参数:
        text (str): 输入的文本字符串。

    返回:
        list: 包含所有词项的列表,例如 ['+83', '-193']。
    """
    # 正则表达式解释:
    # ([+-]?\d+)
    #   [+-]?  : 匹配一个可选的 '+' 或 '-' 符号。
    #   \d+    : 匹配一个或多个数字。
    #   ()     : 捕获组,确保匹配到的数字及其符号作为独立的词项被返回。
    # re.split() 会在匹配到的模式处分割字符串,并因为捕获组的存在,将匹配到的模式也包含在结果列表中。
    tokens = [token.strip() for token in re.split('([+-]?\d+)', text) if token.strip()]
    return tokens

在这个custom_tokenizer函数中:

  • ([+-]?\d+) 是核心正则表达式。
    • [+-]? 匹配一个可选的加号或减号。
    • \d+ 匹配一个或多个数字。
    • 外层的括号 () 将整个模式(带符号的数字)作为一个捕获组,这意味着re.split在分割字符串时,会把这个捕获到的部分也包含在结果列表中。
  • [token.strip() for token in ... if token.strip()] 用于清理结果,去除可能因re.split产生的空字符串。

将自定义分词器集成到CountVectorizer

一旦定义了custom_tokenizer,就可以将其作为参数传递给CountVectorizer的tokenizer参数。

def BOW(df_txt_series):
    """
    使用自定义分词器生成词袋模型DataFrame。

    参数:
        df_txt_series (pd.Series): 包含待处理文本的DataFrame列。

    返回:
        pd.DataFrame: 词袋模型DataFrame,特征列包含带符号的数字。
    """
    # 实例化CountVectorizer,并指定自定义分词器
    # 注意:这里CountVectorizer的输入应是Series,而不是整个DataFrame
    CountVec = CountVectorizer(tokenizer=custom_tokenizer) 

    # 对文本数据进行拟合和转换
    Count_data = CountVec.fit_transform(df_txt_series)

    # 将稀疏矩阵转换为密集数组,并创建DataFrame
    cv_dataframe = pd.DataFrame(
        Count_data.toarray(), 
        columns=CountVec.get_feature_names_out(), 
        index=df_txt_series.index
    )

    # 转换为np.uint8以节省内存,如果计数不会超过255
    return cv_dataframe.astype(np.uint8)

完整示例代码

下面是一个完整的示例,演示如何应用上述解决方案来处理包含带符号数字的文本数据:

import re
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
import numpy as np

# 1. 定义自定义分词器
def custom_tokenizer(text):
    """
    自定义分词器,用于将文本分割成词项,同时保留数字前的正负号。
    """
    tokens = [token.strip() for token in re.split('([+-]?\d+)', text) if token.strip()]
    return tokens

# 2. 定义词袋模型生成函数
def BOW(df_txt_series):
    """
    使用自定义分词器生成词袋模型DataFrame。
    """
    CountVec = CountVectorizer(tokenizer=custom_tokenizer) 
    Count_data = CountVec.fit_transform(df_txt_series)
    cv_dataframe = pd.DataFrame(
        Count_data.toarray(), 
        columns=CountVec.get_feature_names_out(), 
        index=df_txt_series.index
    )
    return cv_dataframe.astype(np.uint8)

# 3. 准备测试数据
data = {'RepID': [1, 2, 3],
        'Txt': ['+83 -193 -380 +55 +901', '-94 +44 +2892 -60', '+7010 -3840 +3993']}
df = pd.DataFrame(data)

# 4. 调用BOW函数并打印结果
result = BOW(df['Txt'])
print("使用自定义分词器后的词袋模型:")
print(result)

# 预期输出示例:
# 使用自定义分词器后的词袋模型:
#    +2892 +380 +3993 +44 +55 +7010 +83 +901 -193 -3840 -60 -94
# 0      0    1     0   0   1     0   1    1    1     0   0   0
# 1      1    0     0   1   0     0   0    0    0     0   1   1
# 2      0    0     1   0   0     1   0    0    0     1   0   0

注意事项与总结

  • 灵活性: CountVectorizer的tokenizer参数提供了极大的灵活性,允许用户根据特定的文本处理需求(如保留特殊字符、处理复合词、特定语言分词等)定制分词逻辑。
  • 正则表达式: 正则表达式的编写是关键。一个精准的正则表达式能够确保正确地识别和提取所需的词项。对于更复杂的文本结构,可能需要更复杂的正则表达式。
  • 性能: 自定义分词器可能会比CountVectorizer的默认分词器略慢,尤其是在处理海量文本数据时。这是因为Python函数调用和正则表达式匹配的开销。对于大多数应用场景,这种性能差异通常可以接受。
  • 词项选择: 除了tokenizer,CountVectorizer还提供了ngram_range(N-gram)、stop_words(停用词)、min_df(最小文档频率)、max_df(最大文档频率)等参数,可以进一步控制生成的词袋模型的特征。
  • 数据类型: 在示例中,我们将最终的DataFrame转换为np.uint8类型。如果词项的计数可能超过255,应考虑使用更大的整数类型,如np.uint16或np.int32。

通过上述方法,我们成功地解决了CountVectorizer在处理带符号数字时忽略符号的问题,确保了文本特征提取的准确性和完整性,这对于依赖数字符号含义的分析任务至关重要。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

512

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

251

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

745

2023.07.05

java正则表达式匹配字符串
java正则表达式匹配字符串

在Java中,我们可以使用正则表达式来匹配字符串。本专题为大家带来java正则表达式匹配字符串的相关内容,帮助大家解决问题。

214

2023.08.11

正则表达式空格
正则表达式空格

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。本专题为大家提供正则表达式相关的文章、下载、课程内容,供大家免费下载体验。

351

2023.08.31

Python爬虫获取数据的方法
Python爬虫获取数据的方法

Python爬虫可以通过请求库发送HTTP请求、解析库解析HTML、正则表达式提取数据,或使用数据抓取框架来获取数据。更多关于Python爬虫相关知识。详情阅读本专题下面的文章。php中文网欢迎大家前来学习。

293

2023.11.13

正则表达式空格如何表示
正则表达式空格如何表示

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。想了解更多正则表达式空格怎么表示的内容,可以访问下面的文章。

236

2023.11.17

正则表达式中如何匹配数字
正则表达式中如何匹配数字

正则表达式中可以通过匹配单个数字、匹配多个数字、匹配固定长度的数字、匹配整数和小数、匹配负数和匹配科学计数法表示的数字的方法匹配数字。更多关于正则表达式的相关知识详情请看本专题下面的文章。php中文网欢迎大家前来学习。

532

2023.12.06

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

10

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.3万人学习

Django 教程
Django 教程

共28课时 | 3.6万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号