《sklearn機器學習——管道和復合估計器》聯合特征(FeatureUnion)

超詳細解說 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"…