
本文详细介绍了如何针对包含特殊负号前缀词汇的文本数据,自定义实现一个Bag-of-Words(词袋模型)向量化器。传统词袋模型通常将带负号的词汇视为独立特征,或无法正确处理其语义。本教程通过Python代码演示了一种灵活的解决方案,它能识别词汇前的负号,并将其计数贡献为负值,从而在同一个特征维度上实现正负抵消,生成更符合特定业务逻辑的特征表示,尤其适用于科学术语或特定编码文本的分析。
Bag-of-Words (BOW) 模型是自然语言处理中一种常用的文本表示方法,它将文本视为一个词语的集合,忽略词语的顺序和语法,只统计每个词语出现的频率。通过sklearn.feature_extraction.text.CountVectorizer等工具,我们可以方便地将文本文档转换为数值向量。
然而,在某些特定场景下,标准BOW模型可能无法满足所有需求。例如,在处理包含科学术语、编码或特定领域文本时,我们可能会遇到一些带有特殊前缀(如负号“-”)的词汇。如果一个词汇前面带有“-”,它可能表示该词汇的“否定”或“缺失”状态。在这种情况下,我们期望“Q207KL41”和“-Q207KL41”能够映射到同一个特征维度上,但“-Q207KL41”的出现应导致该特征的计数减少,而非增加一个独立的“-Q207KL41”特征。
标准CountVectorizer会将“Q207KL41”和“-Q207KL41”视为两个完全不同的词汇,并为它们创建两个独立的特征维度。这不符合我们希望将带负号词汇视为原始词汇的负面贡献的语义。因此,我们需要一种自定义的向量化方法来解决这一挑战。
为了实现对带负号词汇的特殊处理,最直接有效的方法是编写一个自定义的向量化函数。该函数将遍历每个文档,对其中的词汇进行解析,识别并处理前缀负号。具体步骤如下:
下面是使用Python实现这一自定义Bag-of-Words向量化器的代码示例:
import io
import pandas as pd
import numpy as np
from collections import defaultdict
# 模拟输入数据
s = """
RepID,Txt
1,K9G3P9 4H477 -Q207KL41 98464 Q207KL41
2,D84T8X4 -D9W4S2 -D9W4S2 8E8E65 D9W4S2
3,-05L8NJ38 K2DD949 0W28DZ48 207441 K2D28K84"""
df_reps = pd.read_csv(io.StringIO(s))
def custom_bow_vectorizer(documents):
"""
自定义Bag-of-Words向量化器,处理带负号的词汇。
参数:
documents (pd.Series或list): 包含文本内容的序列或列表。
返回:
pd.DataFrame: 向量化后的特征矩阵。
"""
# ret 用于存储每个文档的词汇计数结果
ret = []
# vocabulary 用于构建词汇表,将每个唯一的词汇映射到一个整数索引
# defaultdict(vocabulary.__len__) 的作用是,当访问一个新词汇时,
# 自动将其添加到词汇表并赋予一个新的索引。
vocabulary = defaultdict()
vocabulary.default_factory = vocabulary.__len__
for document in documents:
# feature_counter 存储当前文档中每个词汇的计数
feature_counter = defaultdict(int)
# 将文档分割成词汇
for token in document.split():
sign = 1 # 默认计数为正
# 检查词汇是否以负号开头
if token.startswith("-"):
token = token[1:] # 移除负号,得到基础词汇
sign = -1 # 设置计数为负
# 将基础词汇映射到其在词汇表中的索引
# 如果是新词汇,vocabulary会自动为其分配一个新索引
feature_idx = vocabulary[token]
# 更新当前文档中该词汇的计数
feature_counter[feature_idx] += sign
# 将当前文档的词汇计数结果添加到ret列表
ret.append(feature_counter)
# 将列表中的字典转换为DataFrame
# from_records 会自动将字典的键(feature_idx)作为列
df = pd.DataFrame.from_records(ret)
# 填充DataFrame中的NaN值(表示某些文档不包含某些词汇)为0
df = df.fillna(0)
# 将DataFrame的列名从索引(feature_idx)替换为实际的词汇名称
# vocabulary.keys() 按照词汇被添加的顺序返回词汇
df.columns = vocabulary.keys()
# 将DataFrame的数据类型转换为int8,节省内存
df = df.astype(np.int8)
return df
# 使用自定义向量化器处理文本数据
result_df = custom_bow_vectorizer(df_reps["Txt"])
print(result_df)使用上述代码运行模拟数据 df_reps["Txt"],将得到以下输出:
K9G3P9 4H477 Q207KL41 98464 D84T8X4 D9W4S2 8E8E65 05L8NJ38 K2DD949 0W28DZ48 207441 K2D28K84 0 1 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 -1 1 0 0 0 0 0 2 0 0 0 0 0 0 0 -1 1 1 1 1
结果分析:
可以看到,输出结果完全符合预期,带负号的词汇被正确地处理为对相应基础词汇的负面贡献。
本教程展示了如何通过自定义Python函数,有效地解决标准Bag-of-Words模型在处理带有特殊负号前缀词汇时的局限性。通过识别并调整这些词汇的计数贡献,我们能够生成更符合特定语义需求的特征表示。这种方法在处理特定领域的文本数据,尤其是需要精细控制词汇权重的场景中,具有重要的实用价值。虽然自定义实现需要更多代码,但它提供了无与伦比的灵活性,能够适应各种独特的文本处理需求。
以上就是自定义Bag-of-Words实现:处理带负号的词汇权重的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号