如何向向量化数据集添加特征?——基于Sklearn朴素贝叶斯分类场景
给TF-IDF向量化后的数据集添加额外特征的实用方法
嘿,刚好我对这个场景很熟,给你两种靠谱的方法,你可以根据自己的数据集情况来选:
方法1:手动拼接稀疏矩阵(适合快速验证)
TfidfVectorizer输出的是稀疏矩阵(scipy.sparse类型),直接用numpy拼接会把它转成密集矩阵,大数据集下内存很容易爆。所以正确的姿势是把额外特征也转成稀疏矩阵,再用专门的稀疏矩阵拼接工具:
举个具体例子,假设你想加两个额外特征:URL的长度、是否包含"admin"关键词:
- 先从原始数据里提取额外特征:
import numpy as np # 提取URL长度特征,转成二维数组(因为scipy要求输入是二维) X_train_url_len = X_train_raw['url'].apply(lambda x: len(x)).values.reshape(-1, 1) # 提取是否包含"admin"的二进制特征 X_train_has_admin = X_train_raw['url'].apply(lambda x: 1 if 'admin' in x.lower() else 0).values.reshape(-1, 1) # 把多个额外特征合并成一个矩阵 X_train_extra = np.hstack([X_train_url_len, X_train_has_admin])
- 把额外特征转换成稀疏矩阵:
from scipy.sparse import csr_matrix X_train_extra_sparse = csr_matrix(X_train_extra)
- 和TF-IDF的结果拼接:
from scipy.sparse import hstack # 拼接后得到包含所有特征的最终稀疏矩阵 X_train_final = hstack([X_train_transformed, X_train_extra_sparse])
现在X_train_final就可以直接喂给你的朴素贝叶斯分类器啦~测试集的处理逻辑和训练集完全一致,记得要对齐哦。
方法2:用ColumnTransformer统一构建管道(更推荐长期维护)
如果你的数据集里还有其他类型的特征(比如数值、类别型),用sklearn的ColumnTransformer可以把文本向量化和特征拼接的流程统一起来,代码更整洁,测试集处理也更省心:
- 先导入需要的工具:
from sklearn.compose import ColumnTransformer from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.pipeline import Pipeline
- 分别定义文本特征和额外特征的处理逻辑:
# 处理文本特征:对url列做TF-IDF text_pipeline = Pipeline(steps=[ ('tfidf', TfidfVectorizer(sublinear_tf=True, max_df=0.5, stop_words='english')) ]) # 处理额外特征:这里假设你的额外特征是数值型,直接保留(如果是类别型可以换OneHotEncoder) extra_pipeline = Pipeline(steps=[ ('passthrough', 'passthrough') # 直接传递原始值,不需要额外转换 ])
- 组合所有特征处理流程:
# 定义转换器:指定哪些列用文本处理,哪些用额外特征处理 preprocessor = ColumnTransformer( transformers=[ ('text', text_pipeline, 'url'), ('extra_features', extra_pipeline, ['url_length', 'has_admin']) # 这里填你的额外特征列名 ])
- 构建完整的分类管道并训练:
# 把预处理和分类器连起来 nb_classifier = Pipeline(steps=[ ('preprocessor', preprocessor), ('classifier', MultinomialNB()) ]) # 直接用原始数据训练,不需要手动处理特征转换和拼接! nb_classifier.fit(X_train_raw, y_train)
用这个方法的话,测试集直接调用nb_classifier.predict(X_test_raw)就行,所有特征处理都会自动完成,完全不用重复写转换代码~
小提醒
- 如果你用的是
MultinomialNB,它要求特征是非负的,所以额外特征尽量用非负数值(比如长度、二进制标记都没问题);如果是GaussianNB就没这个限制。 - 稀疏矩阵拼接一定要用
scipy.sparse.hstack,别用numpy的hstack,不然大数据集会直接把内存撑爆哦。
内容的提问来源于stack exchange,提问作者Ignacy Ślusarczyk
相关产品推荐
相关产品推荐

