超详细解说 sklearn 中的联合特征(FeatureUnion)

1. FeatureUnion 简介

FeatureUnion 是 scikit-learn 中的一个工具,用于并行地组合多个特征提取器的输出。它允许你将不同的特征提取方法(如文本向量化、数值特征缩放、自定义特征工程等)的结果**横向拼接(concatenate)**成一个更大的特征矩阵。

核心思想:

  • 并行处理:每个特征提取器独立处理原始数据。
  • 特征拼接:将所有提取器的输出在特征维度(列方向)上拼接
  • 统一接口:对外提供与单个转换器相同的 fittransformfit_transform 接口。

适用场景:

  • 同时使用多种特征提取方法(如 TF-IDF + 词袋模型 + 自定义统计特征)。
  • 处理异构数据(如文本 + 数值 + 分类特征)。
  • 构建复杂特征工程流水线。

2. FeatureUnion 基本语法

from sklearn.pipeline import FeatureUnion
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA# 创建多个特征提取器
tfidf = TfidfVectorizer()
bow = CountVectorizer()
scaler = StandardScaler()# 使用 FeatureUnion 组合
combined_features = FeatureUnion([('tfidf', tfidf),('bow', bow),# ('scaler', scaler)  # 注意:scaler 通常用于数值特征,不能直接用于文本
])# 使用方法
X_transformed = combined_features.fit_transform(X)

!注意:所有特征提取器必须能处理相同的输入数据格式(如都是文本或都是数值数组)。

3.完整代码示例

示例1:文本特征组合(TF-IDF+词袋模型)

from sklearn.pipeline import FeatureUnion
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.datasets import fetch_20newsgroups
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report# 加载数据
categories = ['alt.atheism', 'soc.religion.christian']
newsgroups = fetch_20newsgroups(subset='all', categories=categories, remove=('headers', 'footers', 'quotes'))
X, y = newsgroups.data, newsgroups.target# 划分训练测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# 创建 FeatureUnion
feature_union = FeatureUnion([('tfidf', TfidfVectorizer(max_features=1000, stop_words='english')),('bow', CountVectorizer(max_features=500, ngram_range=(1, 2), stop_words='english'))
])# 训练特征提取器
X_train_features = feature_union.fit_transform(X_train)
X_test_features = feature_union.transform(X_test)print(f"训练集特征维度: {X_train_features.shape}")  # (样本数, 1500) = 1000(TF-IDF) + 500(BOW)
print(f"测试集特征维度: {X_test_features.shape}")# 训练分类器
clf = LogisticRegression(random_state=42)
clf.fit(X_train_features, y_train)# 预测
y_pred = clf.predict(X_test_features)
print("\n分类报告:")
print(classification_report(y_test, y_pred, target_names=newsgroups.target_names))

示例2:数值特征组合(PCA+原始特征)

from sklearn.pipeline import FeatureUnion
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
import numpy as np# 加载数据
iris = load_iris()
X, y = iris.data, iris.target# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)# 创建 FeatureUnion
feature_union = FeatureUnion([('pca', PCA(n_components=2)),  # 降维到2个主成分('scaler', StandardScaler())   # 标准化原始特征
])# 训练并转换
X_train_combined = feature_union.fit_transform(X_train)
X_test_combined = feature_union.transform(X_test)print(f"原始特征维度: {X_train.shape[1]}")           # 4
print(f"组合后特征维度: {X_train_combined.shape[1]}") # 6 = 2(PCA) + 4(标准化)# 训练分类器
clf = RandomForestClassifier(n_estimators=100, random_state=42)
clf.fit(X_train_combined, y_train)# 评估
accuracy = clf.score(X_test_combined, y_test)
print(f"\n测试集准确率: {accuracy:.4f}")

示例3:自定义特征提取器+内置提取器

from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.pipeline import FeatureUnion
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
import reclass TextStatsExtractor(BaseEstimator, TransformerMixin):"""自定义文本统计特征提取器"""def fit(self, X, y=None):return selfdef transform(self, X):# 提取文本长度、单词数、大写字母比例等统计特征features = []for text in X:length = len(text)word_count = len(text.split())uppercase_ratio = sum(1 for c in text if c.isupper()) / (len(text) + 1e-8)exclamation_count = text.count('!')question_count = text.count('?')features.append([length, word_count, uppercase_ratio, exclamation_count, question_count])return np.array(features)# 示例数据
texts = ["This is a GREAT product!!!","I hate this item... it's terrible.","Average quality, nothing special.","AMAZING!!! Best purchase ever!!!","Not bad, but could be better?"
]# 创建 FeatureUnion
feature_union = FeatureUnion([('tfidf', TfidfVectorizer(max_features=50, stop_words='english')),('stats', TextStatsExtractor())
])# 转换数据
X_combined = feature_union.fit_transform(texts)print("特征名称:")
feature_names = []
# TF-IDF 特征名
tfidf_names = feature_union.transformer_list[0][1].get_feature_names_out()
feature_names.extend([f"tfidf_{name}" for name in tfidf_names])
# 统计特征名
stat_names = ['length', 'word_count', 'uppercase_ratio', 'exclamation_count', 'question_count']
feature_names.extend(stat_names)print(f"总特征数: {X_combined.shape[1]}")
print("前5个特征名:", feature_names[:5])
print("后5个特征名:", feature_names[-5:])print("\n转换后的特征矩阵:")
print(X_combined.toarray())

4.高级用法

4.1设置权重(transformer_weights)

from sklearn.pipeline import FeatureUnion
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer# 为不同特征提取器设置权重
feature_union = FeatureUnion([('tfidf', TfidfVectorizer(max_features=100)),('bow', CountVectorizer(max_features=100))
], transformer_weights={'tfidf': 1.0,'bow': 0.5  # 词袋模型的特征乘以0.5
})# 权重会在 transform 后应用
X_weighted = feature_union.fit_transform(texts)

4.2与Pipeline结合使用

from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.datasets import fetch_20newsgroups# 创建复杂的流水线
pipeline = Pipeline([('features', FeatureUnion([('tfidf', TfidfVectorizer(max_features=1000)),('stats', TextStatsExtractor())  # 假设已定义])),('scaler', StandardScaler(with_mean=False)),  # 稀疏矩阵不能用 with_mean=True('classifier', SVC(kernel='linear'))
])# 使用流水线
newsgroups = fetch_20newsgroups(subset='train', categories=['alt.atheism', 'soc.religion.christian'])
pipeline.fit(newsgroups.data, newsgroups.target)

4.3使用make_union快捷方式

from sklearn.pipeline import make_union
from sklearn.decomposition import PCA
from sklearn.feature_selection import SelectKBest# 简化语法
union = make_union(PCA(n_components=2),SelectKBest(k=3),n_jobs=1  # 并行处理的作业数
)

5.重要注意事项

5.1输入数据一致性

# × 错误:混合不同类型的数据处理
feature_union = FeatureUnion([('tfidf', TfidfVectorizer()), #处理文本('scaler', StandardScaler()) #处理数值-会报错!
])

5.2稀疏矩阵处理

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.preprocessing import StandardScaler
# TF-IDF 产生稀疏矩阵
tfidf = TfidfVectorizer()
X_sparse = tfidf.fit_transform(texts)
# StandardScaler 不能直接处理稀疏矩阵
# scalar = StandardScaler() # 会报错!
# 解决方案:使用 with_mean=False
scaler=StandardScaler(with_mean=False) # 可以处理稀疏矩阵

5.3 并行处理 (n_jobs)

feature_union = FeatureUnion([('tfidf1', TfidfVectorizer(max_features=1000)),('tfidf2', TfidfVectorizer(max_features=1000, ngram_range=(2,2)))
], n_jobs=-1) # 使用所有CPU核心并行处理

6.调试与检查

6.1查看各组件输出维度

feature_union = FeatureUnion([('tfidf', TfidfVectorizer(max_features=500)),('bow', CountVectorizer(max_features=300))
])X_combined = feature_union.fit_transform(texts)# 检查每个组件的输出
for name, transformer in feature_union.transformer_list:X_part = transformer.transform(texts)print(f"{name}: {X_part.shape}")print(f"Combined: {X_combined.shape}")

6.2 获取特征名称

def get_feature_names(feature_union):"""获取 FeatureUnion 的所有特征名称"""feature_names = []for name, transformer in feature_union.transformer_list:if hasattr(transformer, 'get_feature_names_out'):names = transformer.get_feature_names_out()elif hasattr(transformer, 'get_feature_names'):names = transformer.get_feature_names()else:# 对于自定义转换器,可能需要手动定义n_features = transformer.transform([texts[0]]).shape[1]names = [f"{name}_feature_{i}" for i in range(n_features)]feature_names.extend([f"{name}__{n}" for n in names])return feature_names# 使用示例
feature_names = get_feature_names(feature_union)
print(f"总特征数: {len(feature_names)}")
print("前10个特征名:", feature_names[:10])

7. 替代方案:ColumnTransformer

对于异构数据(不同列不同类型),推荐使用 ColumnTransformer:

from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd# 创建示例数据框
df = pd.DataFrame({'text': ['good product', 'bad service', 'excellent quality'],'price': [100, 200, 150],'category': ['A', 'B', 'A']
})# 使用 ColumnTransformer 处理不同列
preprocessor = ColumnTransformer([('text', TfidfVectorizer(), 'text'),('num', StandardScaler(), ['price']),('cat', OneHotEncoder(), ['category'])
])X_transformed = preprocessor.fit_transform(df)
print(f"转换后形状: {X_transformed.shape}")

8. 总结

FeatureUnion 的优势:

  • ✅ 简化多特征提取器的组合
  • ✅ 提供统一的接口
  • ✅ 支持并行处理
  • ✅ 可与 Pipeline 无缝集成

使用建议

  • 当需要组合同类型数据的多种特征提取方法时使用
  • 对于异构数据,优先考虑 ColumnTransformer
  • 注意稀疏矩阵的处理
  • 合理设置特征权重
  • 使用 make_union 简化代码

最佳实践

# 推荐的完整流程
from sklearn.pipeline import Pipeline, FeatureUnion
from sklearn.model_selection import cross_val_score# 1. 定义特征组合
features = FeatureUnion([('tfidf', TfidfVectorizer(max_features=1000)),('custom', CustomFeatureExtractor())
])# 2. 创建完整流水线
pipeline = Pipeline([('features', features),('classifier', LogisticRegression())
])# 3. 交叉验证评估
scores = cross_val_score(pipeline, X, y, cv=5)
print(f"平均准确率: {scores.mean():.4f} (+/- {scores.std() * 2:.4f})")

通过合理使用 FeatureUnion,你可以构建强大的特征工程系统,显著提升机器学习模型的性能!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/98609.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/98609.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/98609.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Eyeshot 2025.3 3D 图形工具包

Eyeshot 2025.3 现在支持 E57 格式Eyeshot 2025.3 现在支持 E57 格式,可直接从 3D 扫描系统导入点云、图像和元数据。Eyeshot 由 devDept 开发,是一款功能全面的 3D 图形工具包,专为构建工程和 CAD(计算机辅助设计)应用程序的 .NET 开发人员而…

OpenResty 配合 Lua 脚本的使用

OpenResty 配合 Lua 脚本的使用实践 在高并发互联网服务中,传统的 Web 服务器往往难以同时兼顾性能与灵活性。而 OpenResty 作为一个基于 Nginx LuaJIT 的高性能 Web 平台,能够让我们在保持 Nginx 高并发性能的同时,使用 Lua 脚本 动态扩展其…

香港券商櫃台系統發展分析與市場觀察

香港券商櫃台系統發展分析與市場觀察 一、市場環境與交易機制變革 2025年以來,香港證券市場表現活躍。港交所現貨市場平均每日成交金額達2,402億港元,同比增長118%。南向交易(港股通)日均成交額佔比提升至23%,單日淨…

AR技术:多行业数字化转型的加速引擎

在数字化浪潮的推动下,增强现实(AR www.teamhelper.cn )技术正突破传统娱乐和游戏领域的局限,成为各行业数字化转型的重要力量。从工业制造到医疗健康,从教育培训到零售购物,AR技术以其独特的虚实融合能力&…

第6篇、Kafka 高级实战:生产者路由与消费者管理

Kafka 高级实战:生产者路由与消费者管理(Python 版)从基础到进阶:深入理解 Kafka 的生产者消息路由、消费者 Offset 管理,以及 Exactly-Once 语义实现 实战导向:提供完整的可运行代码示例,涵盖自…

基于Python读取多个excel竖向拼接为一个excel

在Python中,可以使用pandas库结合glob模块来遍历读取多个Excel文件,并将它们竖向拼接为一个DataFrame对象。以下是完整的实现方法: 文章目录方法1:使用glob匹配文件 pd.concat()方法2:使用列表推导式(更简…

Linux《进程信号(下)》

在之前的Linux《进程信号(上)》当中我们已经了解了进程信号的基本概念以及知道了信号产生的方式有哪些,还了解了信号是如何进行保存的,那么接下来在本篇当中就将继续之前的学习了解信号是如何处理的。除此之外还会了解到中断的概念…

android 性能优化—ANR

ANR产生原理ANR(Application Not Responding)是 Android 对 “应用主线程卡死” 的系统级保护机制: 当 输入事件、广播、服务 等在规定时间内未被处理完毕,SystemServer 会弹框并杀进程,防止整个系统跟着假死。计时起点…

stm32——单总线,DHT11

目录 一、单总线协议的原理和应用 单总线协议指的是只采用一根信道来进行数据传输,通信指的是双方(MCU与传感器)通过一根信道进行数据交互,所以按照数据的传输方向,只能采用半双工通信方式,比较典型的传感器…

css3之grid布局

容器:gird container开启grid布局的元素 项目:grid items容器里面的子元素,不包括后代元素 显式网格(单元格):通过grid-template-columns和grid-template-rows指定的网格,注意项目不等于单元格,…

C++容器:list

一、list的介绍及使用 list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素…

STL库——map/set(类函数学习)

ʕ • ᴥ • ʔ づ♡ど 🎉 欢迎点赞支持🎉 个人主页:励志不掉头发的内向程序员; 专栏主页:C语言; 文章目录 前言 一、序列式容器和关联式容器 二、set 系列的使用 2.1、set 和 multiset 参考文档 2.2、set…

计算机网络IP协议

1.TCP协议1.1 确认应答1.2 超时重传1.3 连接管理1.4 滑动窗口1.5 流量控制1.6 拥塞控制 1.7 延时应答1.8 稍带应答1.9 粘包问题1.10 异常情况2.IP协议 网络层2.1 NAT机制下的几种情况:同一个局域网中,内网ip访问 内网 ip,可以的不同局域网中,内网IP访问 内网IP,不行~~外网IP访…

Windows电脑如何查看wifi连接记录及连接时间

查询WIFI 连接的记录 echo netsh wlan show profiles netsh wlan show wlanreport POWERSHELL 脚本 Get-WinEvent -LogName Microsoft-Windows-WLAN-AutoConfig/Operational | Where-Object { $_.Id -in (8001,8002) } | Select-Object TimeCreated, Id, {Name"Action…

【golang学习笔记 gin 】1.2 redis 的使用

安装redis go get -u github.com/gin-gonic/gin go get -u github.com/go-redis/redis/v8创建相关目录 gotest->conifg->database.go->redis.go->controller ->index.go->model->user.go->router->router.gomain.go 封装Redis package config impor…

Java学习之——“IO流“的进阶流之序列化流的学习

一、核心概念:什么是序列化与反序列化?序列化 (Serialization): 将一个对象(在内存中的状态)转换成一个字节序列的过程。这个字节序列包含了对象的数据、对象的类型以及对象中存储的属性等信息。反序列化 (Deserializa…

机器学习04——决策树(信息增益、信息增益率、ID3、C4.5、CART、剪枝、连续值缺失值处理)

上一章:机器学习03——线性模型 下一章:机器学习05——多分类学习与类别不平衡 机器学习实战项目:【从 0 到 1 落地】机器学习实操项目目录:覆盖入门到进阶,大学生就业 / 竞赛必备 文章目录一、决策树的基本流程&#…

(论文速读)从语言模型到通用智能体

论文题目:From Multimodal LLMs to Generalist Embodied Agents: Methods and Lessons(从多模式大型语言模型到多面手具身代理:方法和教训)会议:CVPR2025摘要:我们研究了多模态大型语言模型(Multimodal Large Language…

【Epiq Solutions】Matchstiq™ G20 和 Matchstiq™ G40 AI SDR

Matchstiq™ G20 和 Matchstiq™ G40 产品简介 Matchstiq™ G20 和 Matchstiq™ G40 是 Epiq Solutions 推出的 紧凑型、高性能软件定义无线电(SDR)平台,专为满足 严苛 SWaP-C(体积、重量、功耗受限)场景下的战术与移动…

基于Echarts+HTML5可视化数据大屏展示-旅游智慧中心

效果展示&#xff1a; 代码结构&#xff1a;主要代码实现 index.html布局 <!DOCTYPE html> <html lang"en" style"font-size: 97.5px;"> <head><meta http-equiv"Content-Type" content"text/html; charsetUTF-8"…