全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

自定义CountVectorizer分词器:处理带符号数字的文本特征提取

本教程详细介绍了Python CountVectorizer在进行文本特征提取时,默认忽略数字前正负号的问题及其解决方案。通过实现一个自定义分词器,结合正则表达式精确捕获带符号的数字作为独立词元,可以确保 CountVectorizer正确识别并保留这些关键信息,从而生成包含完整符号的特征矩阵。

引言:CountVectorizer与符号数字识别挑战

在自然语言处理(NLP)中,Bag-of-Words (BOW) 模型是一种常用的文本表示方法,它将文本视为一个词袋,忽略词序,只关注词的出现频率。sklearn.feature_extraction.text.CountVectorizer 是Python中实现BOW模型的核心工具。它能够将文本文档集合转换为词频矩阵。然而,当处理包含正负号的数字字符串时,CountVectorizer 的默认行为可能会导致信息丢失。

例如,考虑以下数据框:

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

其中 Txt 字段包含了一系列带符号的数字。如果直接使用 CountVectorizer 进行处理,其默认的分词器通常会忽略非字母数字字符(如 + 和 -),导致生成的特征名称(列名)中丢失这些符号。这意味着 +83 和 83 将被视为同一个词元,这在某些应用场景下是不可接受的。我们期望的输出是能区分 +83 和 -193 等带符号的数字作为独立的特征。

理解分词(Tokenization)

分词是文本处理的第一步,它将连续的文本分解成有意义的最小单元,即词元(tokens)。CountVectorizer 内部有一个 tokenizer 参数,它决定了如何将输入文本字符串分割成词元列表。默认情况下,CountVectorizer 使用一个简单的正则表达式来提取词元,该正则表达式通常只匹配字母数字序列。这就是为什么 + 和 - 符号会被忽略的原因,因为它们不被认为是词元的一部分。

为了解决符号丢失的问题,我们需要提供一个自定义的分词器,它能够识别并保留数字前的正负号。

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

自定义分词器的核心在于使用正则表达式精确地捕获我们希望保留的词元。对于带符号的数字,我们需要确保正负号与数字一起被视为一个整体。

我们将使用Python的 re 模块来构建这个自定义分词器。关键在于 re.split() 函数和合适的正则表达式。

custom_tokenizer 函数详解

import re

def custom_tokenizer(text):
    # 使用正则表达式分割文本,同时捕获带符号的数字
    # ([+-]?\d+):
    #   [+-]? 匹配一个可选的 '+' 或 '-' 符号
    #   \d+ 匹配一个或多个数字
    # 括号 () 创建一个捕获组,确保匹配到的符号和数字作为一个整体被保留
    tokens = [token.strip() for token in re.split('([+-]?\d+)', text) if token.strip()]
    return tokens

正则表达式 ([+-]?\d+) 解析:

  • [+-]?: 这是一个字符集,匹配 + 或 - 字符。? 表示前面的字符(在这里是 [+-])出现零次或一次,即符号是可选的。
  • \d+: 匹配一个或多个数字字符(0-9)。
  • (): 这是一个捕获组。在 re.split() 中,如果正则表达式包含捕获组,那么被捕获的内容也会作为结果列表的一部分返回。这正是我们需要的,它确保 + 或 - 与后面的数字一起被捕获为一个词元。

re.split() 函数会根据正则表达式将字符串分割,并且如果正则表达式中包含捕获组,则捕获到的内容也会包含在结果列表中。最后,我们使用列表推导式 [token.strip() for token in ... if token.strip()] 来清理结果,移除可能产生的空字符串。

整合自定义分词器到CountVectorizer

创建了 custom_tokenizer 后,我们只需将其作为参数传递给 CountVectorizer 的 tokenizer 参数即可。

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

def BOW(df_column):
  # 初始化 CountVectorizer,传入自定义分词器
  CountVec = CountVectorizer(tokenizer=custom_tokenizer)
  # 对指定列进行拟合和转换
  Count_data = CountVec.fit_transform(df_column)
  Count_data = Count_data.astype(np.uint8)
  # 创建DataFrame,列名为 CountVectorizer 提取的特征名
  cv_dataframe = pd.DataFrame(Count_data.toarray(), columns=CountVec.get_feature_names_out(), index=df_column.index)
  return cv_dataframe.astype(np.uint8)

注意点:

  • CountVectorizer(tokenizer=custom_tokenizer):这是关键一步,将我们定义的分词函数传递给 CountVectorizer。
  • Count_data = CountVec.fit_transform(df_column):这里假设 df_column 是一个包含文本数据的 Pandas Series(例如 df['Txt'])。
  • CountVec.get_feature_names_out():这个方法将返回所有识别到的词元,它们将作为结果DataFrame的列名。由于我们使用了自定义分词器,这些列名将包含符号。

完整代码示例与验证

下面是一个完整的示例,展示如何应用自定义分词器来解决 CountVectorizer 忽略符号的问题。

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

# 1. 定义自定义分词器
def custom_tokenizer(text):
    """
    自定义分词器,用于将文本分割成词元,同时保留带符号的数字。
    """
    # 使用正则表达式分割文本,同时捕获带符号的数字
    # ([+-]?\d+) 匹配一个可选的正负号后跟一个或多个数字
    tokens = [token.strip() for token in re.split('([+-]?\d+)', text) if token.strip()]
    return tokens

# 2. 定义 Bag-of-Words (BOW) 函数
def BOW(df_text_column):
    """
    使用自定义分词器生成文本的词袋模型DataFrame。

    参数:
    df_text_column (pd.Series): 包含文本数据的Pandas Series。

    返回:
    pd.DataFrame: 词频矩阵,列名为带符号的数字词元。
    """
    # 初始化 CountVectorizer,传入自定义分词器
    CountVec = CountVectorizer(tokenizer=custom_tokenizer)
    # 对文本列进行拟合和转换
    Count_data = CountVec.fit_transform(df_text_column)
    # 将结果转换为 uint8 类型以节省内存
    Count_data = Count_data.astype(np.uint8)
    # 创建DataFrame,列名为 CountVectorizer 提取的特征名
    cv_dataframe = pd.DataFrame(Count_data.toarray(), 
                                columns=CountVec.get_feature_names_out(), 
                                index=df_text_column.index)
    return cv_dataframe.astype(np.uint8)

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

    print("原始数据框:")
    print(df)
    print("\n" + "="*50 + "\n")

    # 调用 BOW 函数处理 'Txt' 列
    result_df = BOW(df['Txt'])

    print("使用自定义分词器后的词袋模型结果:")
    print(result_df)

    # 预期输出与对比
    print("\n" + "="*50 + "\n")
    print("期望的列名应包含符号,例如:+83, -193, -380, +55, +901 等。")
    print("实际输出的列名:", result_df.columns.tolist())

运行上述代码,您会看到 result_df 的列名正确地包含了 + 或 - 符号,例如 +83, -193, -380 等,这正是我们期望的结果。

注意事项与总结

  • 灵活性: 自定义分词器是 CountVectorizer 强大的一个方面,它允许用户根据具体的文本处理需求,灵活地定义如何将文本分割成词元。
  • 正则表达式的威力: re 模块和正则表达式是处理复杂文本模式匹配和提取的利器。理解并掌握常用的正则表达式语法对于文本预处理至关重要。
  • 性能考量: 复杂的自定义分词器可能会比 CountVectorizer 的默认分词器慢。在处理海量数据时,需要权衡灵活性和性能。
  • 应用场景: 本教程中解决的问题在处理日志文件、金融交易数据、科学测量数据等场景中非常常见,这些场景中数字的正负号具有重要的语义信息。

通过本文,我们学习了 CountVectorizer 默认分词机制的局限性,以及如何通过实现和集成自定义分词器来解决在文本特征提取过程中符号丢失的问题。这种方法不仅限于处理带符号的数字,还可以扩展到处理其他任何需要特殊分词规则的文本数据。


# word  # python  # 正则表达式  # 工具  # ai  # 金融  # 自然语言处理  # 为什么 


相关文章: 高防服务器租用首荐平台,企业级优惠套餐快速部署  小说建站VPS选用指南:性能对比、配置优化与建站方案解析  ppt在线制作免费网站推荐,有什么下载免费的ppt模板网站?  魔毅自助建站系统:模板定制与SEO优化一键生成指南  如何在Ubuntu系统下快速搭建WordPress个人网站?  东莞专业制作网站的公司,东莞大学生网的网址是什么?  建站之星安装失败:服务器环境不兼容?  如何生成腾讯云建站专用兑换码?  如何在万网开始建站?分步指南解析  海南网站制作公司有哪些,海口网是哪家的?  如何在建站之星绑定自定义域名?  制作网站的软件免费下载,免费制作app哪个平台好?  JS中使用new Date(str)创建时间对象不兼容firefox和ie的解决方法(两种)  PHP正则匹配日期和时间(时间戳转换)的实例代码  如何通过免费商城建站系统源码自定义网站主题与功能?  建站主机空间推荐 高性价比配置与快速部署方案解析  建站之星代理商如何保障技术支持与售后服务?  制作电商网页,电商供应链怎么做?  如何在云指建站中生成FTP站点?  如何用好域名打造高点击率的自主建站?  如何在阿里云高效完成企业建站全流程?  Python如何创建带属性的XML节点  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  怀化网站制作公司,怀化新生儿上户网上办理流程?  如何访问已购建站主机并解决登录问题?  制作表格网站有哪些,线上表格怎么弄?  如何用PHP快速搭建高效网站?分步指南  家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?  七夕网站制作视频,七夕大促活动怎么报名?  网站制作多少钱一个,建一个论坛网站大约需要多少钱?  小型网站建站如何选择虚拟主机?  怎么将XML数据可视化 D3.js加载XML  如何选择适合PHP云建站的开源框架?  建站主机服务器选型指南与性能优化方案解析  如何快速生成高效建站系统源代码?  昆明高端网站制作公司,昆明公租房申请网上登录入口?  如何基于PHP生成高效IDC网络公司建站源码?  如何在IIS管理器中快速创建并配置网站?  在线ppt制作网站有哪些,请推荐几个好的课件下载的网站?  平台云上自主建站:模板化设计与智能工具打造高效网站  宠物网站制作html代码,有没有专门介绍宠物如何养的网站啊?  如何使用Golang安装API文档生成工具_快速生成接口文档  如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?  如何通过VPS建站实现广告与增值服务盈利?  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  北京制作网站的公司排名,北京三快科技有限公司是做什么?北京三快科技?  如何挑选优质建站一级代理提升网站排名?  创业网站制作流程,创业网站可靠吗?  Android自定义listview布局实现上拉加载下拉刷新功能  如何在宝塔面板创建新站点? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。