新闻中心

自定义分词器:解决Python CountVectorizer忽略数字符号问题

2025-12-05
浏览次数:
返回列表

自定义分词器:解决Python CountVectorizer忽略数字符号问题

python的`countvectorizer`在默认分词时会忽略非字母数字字符,导致在处理如“+83”或“-193”这类带有正负号的数字字符串时,符号被丢弃。本文将详细介绍如何通过编写一个自定义的正则表达式分词器,并将其集成到`countvectorizer`中,以确保在构建词袋模型时,数字及其前缀符号(正负号)能够被完整保留,从而生成符合预期的特征名称。

理解CountVectorizer的默认分词行为

CountVectorizer是Scikit-learn库中用于将文本数据转换为词频矩阵(词袋模型)的关键工具。它通过fit_transform方法对文本进行分词、构建词汇表并计算词频。然而,其默认的分词器(基于正则表达式r'(?u)\b\w\w+\b')旨在提取单词,通常会忽略非字母数字字符。这意味着,当遇到像+83或-193这样的字符串时,+和-这些符号会被视为分隔符或噪声而被丢弃,只留下纯数字83或193作为词汇表中的特征。

考虑以下数据框:

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

如果直接使用默认的CountVectorizer,我们期望的列名是+83, -193等,但实际输出的列名将是83, 193等,丢失了重要的符号信息。

解决方案:自定义分词器

为了解决CountVectorizer默认行为带来的问题,我们需要提供一个自定义的分词函数。这个函数将负责以我们期望的方式解析文本,确保带有正负号的数字被视为一个完整的词元(token)。

1. 创建自定义分词函数

我们将使用Python的re模块来构建一个正则表达式,该表达式能够识别并捕获带有可选正负号的数字。re.split()函数在这里非常有用,它可以根据正则表达式将字符串分割成列表,并且如果正则表达式包含捕获组(括号),那么匹配到的分隔符也会被包含在结果列表中。

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

def custom_tokenizer(text):
    """
    自定义分词器,用于将文本分割成词元,并保留数字前的正负号。
    例如:"+83 -193" 会被分割为 ['+83', '-193']。
    """
    # 正则表达式解释:
    # ([+-]?\d+)
    #   - [+-]?  : 匹配一个可选的 '+' 或 '-' 符号
    #   - \d+    : 匹配一个或多个数字
    # 整个表达式作为一个捕获组,确保匹配到的符号和数字组合被保留为词元。
    tokens = [token.strip() for token in re.split('([+-]?\d+)', text) if token.strip()]
    return tokens

在custom_tokenizer函数中,re.split('([+-]?\d+)', text)会根据匹配到的[+-]?\d+模式来分割文本。由于([+-]?\d+)是一个捕获组,所以匹配到的部分(即带有符号的数字)也会作为列表元素返回。[token.strip() for token in ... if token.strip()]确保移除了空字符串和多余的空白。

2. 将自定义分词器集成到CountVectorizer

创建了自定义分词器后,只需在初始化CountVectorizer时,通过tokenizer参数指定这个函数即可。

Mistral AI Mistral AI

Mistral AI被称为“欧洲版的OpenAI”,也是目前欧洲最强的 LLM 大模型平台

Mistral AI 182 查看详情 Mistral AI
def BOW_with_custom_tokenizer(df_column_series):
    """
    使用自定义分词器生成词袋模型的数据框。

    参数:
    df_column_series (pd.Series): 包含文本数据的DataFrame列。

    返回:
    pd.DataFrame: 包含词袋模型结果的数据框,列名保留了数字的正负号。
    """
    # 初始化CountVectorizer,并传入自定义分词器
    CountVec = CountVectorizer(tokenizer=custom_tokenizer)

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

    # 将稀疏矩阵转换为密集数组,并指定数据类型以节省内存
    Count_data = Count_data.astype(np.uint8)

    # 创建Pandas DataFrame,列名为词汇表中的特征(已保留符号)
    cv_dataframe = pd.DataFrame(
        Count_data.toarray(), 
        columns=CountVec.get_feature_names_out(), 
        index=df_column_series.index
    )

    return cv_dataframe.astype(np.uint8)

注意事项:

  • CountVectorizer的tokenizer参数期望一个可调用对象(函数),该对象接收一个字符串并返回一个字符串列表。
  • ngram_range等其他参数仍然可以根据需求进行设置。如果同时使用ngram_range和tokenizer,CountVectorizer会先通过tokenizer分词,然后基于这些词元生成n-gram。

完整示例

让我们使用之前的数据框来测试这个改进后的BOW函数。

# 导入必要的库
import pandas as pd
import numpy as np
import re
from sklearn.feature_extraction.text import CountVectorizer

# 自定义分词器函数
def custom_tokenizer(text):
    tokens = [token.strip() for token in re.split('([+-]?\d+)', text) if token.strip()]
    return tokens

# 改进的BOW函数
def BOW_with_custom_tokenizer(df_column_series):
    CountVec = CountVectorizer(tokenizer=custom_tokenizer)
    Count_data = CountVec.fit_transform(df_column_series)
    Count_data = Count_data.astype(np.uint8)
    cv_dataframe = pd.DataFrame(
        Count_data.toarray(), 
        columns=CountVec.get_feature_names_out(), 
        index=df_column_series.index
    )
    return cv_dataframe.astype(np.uint8)

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

# 应用改进的BOW函数
result_df = BOW_with_custom_tokenizer(df['Txt'])
print(result_df)

输出结果:

   +2892  +3993  +44  +55  +7010  +83  +901  -193  -380  -3840  -60  -94
0      0      0    0    1      0    1     1     1     1      0    0    0
1      1      0    1    0      0    0     0     0     0      0    1    1
2      0      1    0    0      1    0     0     0     0      1    0    0

从输出可以看出,列名现在正确地包含了数字前的正负号,如+83、-193等,这正是我们期望的结果。

总结与扩展

通过为CountVectorizer提供一个自定义分词器,我们成功解决了其默认行为中忽略非字母数字字符的问题,尤其是在需要保留数字符号的场景下。这种方法不仅适用于处理数字符号,还可以推广到其他需要特殊分词规则的场景,例如:

  • 特定格式的ID或编码: 如果文本中包含ABC-123或REF_XYZ等需要作为整体识别的字符串。
  • 词形还原或词干提取: 在分词阶段集成nltk或spaCy等库的词形还原或词干提取功能。
  • 过滤特定模式: 在分词时直接过滤掉不符合特定模式的词元。
  • 复合词处理: 将某些由空格分隔但语义上紧密的词语(如“机器学习”)视为一个单一词元。

理解并掌握CountVectorizer的tokenizer参数的用法,极大地增强了其灵活性和适应性,使其能够满足更复杂的文本预处理需求。在实际应用中,根据数据的特点和分析目标,选择或设计合适的自定义分词器是构建高质量词袋模型的重要一步。

以上就是自定义分词器:解决Python CountVectorizer忽略数字符号问题的详细内容,更多请关注其它相关文章!


# 数据包  # 重庆网站关键词优化系统  # 酒店宣传网站建设教程  # 静海区市场营销推广方案  # 正规seo推广有哪些seo博客  # 天津网站建设制作流程  # 吴忠网站推广招聘  # ai智能推广营销策略  # 范文网站建设  # 怎样进行seo推广代做  # 怎么知道推广网站  # 如何将  # python  # 提供一个  # 可选  # 欧洲  # 也会  # 转换为  # 词汇表  # 自定义  # 工具  # 编码  # 正则表达式 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: 解决Flask中Quill编辑器内容提交失败及TypeError的指南  如何将一个大型PHP应用拆分为多个Composer包_微服务与模块化架构的Composer实践  优化LangChain文档加载与ChromaDB集成:解决多文档处理与分块问题  Surface怎么安装系统 微软Surface Pro U盘重装win11教程  漫蛙2网页版漫画入口 漫蛙漫画在线官方登录  win11专注助手在哪 Win11免打扰模式设置与自动化规则【指南】  Mac终端命令大全_Mac常用Terminal指令速查  Win10快速启动功能利弊分析 Win10开启或关闭快速启动教程【技巧】  从OpenAI API响应中高效提取生成文本  新手怎么开始学化妆 零基础化妆入门教程  怎么在浏览器上运行HTML文件_浏览器运行HTML文件技巧【技巧】  腾讯QQ邮箱官方网站_QQ邮箱网页版在线登录  mysql密码锁定怎么解锁_mysql密码锁定解锁后修改密码步骤  TikTok搜索不到用户发布内容怎么办 TikTok用户内容搜索优化方法  黑鲨3Pro怎样在相册开漫画风滤镜_iPhone黑鲨3Pro相册开漫画风滤镜【趣味滤镜】  痛风发作了怎么办? 快速止痛和后期饮食调理  c++ 获取系统当前时间 c++时间戳获取方法  QQ邮箱官方网站登录入口_QQ邮箱网页版在线使用  学习通网页版快速入口 学习通官网网页版直接打开  俄罗斯方块最新版入口 俄罗斯方块在线玩官网入口  火锅吃太多会怎样 火锅吃太多会上火吗  UE5.7引擎表现爆炸优化无敌!5090跑4K稳定60FPS  vivo浏览器自带的下载器速度慢怎么办 vivo浏览器提升文件下载速度的技巧  qq游戏手机版下载安装_qq游戏移动端入口  一加Ace 6T实拍样张首次公布!李杰:主摄实力完全看齐4K档性能旗舰  Excel组合图表怎么做 Excel创建柱状图与折线组合图教程【图表】  Go与Ruby之间实现AES加密互通:CFB模式下的密钥长度匹配策略  高德地图家和公司地址在哪设置 高德地图通勤路线设置方法【超详细】  怎么在html里运行vbs脚本_html中运行vbs脚本方法【教程】  如何使用Node.js csv 包按条件移除含空字段的CSV记录  Composer的 "licenses" 命令如何帮助你遵守开源协议_检查项目依赖的许可证合规性  微信网页版官方入口教程 微信网页版网页版快速登录步骤  sublime如何处理大型CSV文件的列对齐_sublime高级表格编辑插件指南  夸克浏览器网页版最新地址 夸克浏览器官方入口合集  mc.js游戏直达 mc.js网页免下载版本秒进地址  html5 app怎么运行环境_配html5 app运行环境【教程】  蓝湖怎样用切图标注提对接效率_蓝湖用切图标注提对接效率【设计对接】  css元素hover动画延迟生效怎么办_使用animation-delay调整触发时间  126邮箱账号注册 电脑版登录入口  AO3最新官网入口公告_2025AO3镜像站实时查询方法  支付宝解绑银行卡步骤_支付宝如何解除绑定银行卡  win11开机启动修复循环怎么办 Win11无法进入系统高级启动解决方法【修复】  b站赚钱渠道_b站收益来源  三星GalaxyZFold5怎样在相册制作折叠屏分镜_iPhone三星GalaxyZFold5相册制作折叠屏分镜【创意编辑】  深入理解J*aScript中的B样条曲线与节点向量生成  Golang如何通过reflect操作map_Golang reflect map操作与遍历技巧  深入理解Go语言中的指针类型:以*string为例  Kafka Streams中基于消息头条件过滤消息的实现指南  漫蛙2漫画入口 漫蛙正版网页漫画直达网址  css绝对定位元素脱离父容器怎么办_确保父元素position非static 

搜索