# 4.1. Pipeline(管道)和 FeatureUnion(特征聯合): 合并的評估器
校驗者:
[@程威](https://github.com/apachecn/scikit-learn-doc-zh)
翻譯者:
[@Sehriff](https://github.com/apachecn/scikit-learn-doc-zh)
## 4.1.1. Pipeline: 鏈式評估器
[`Pipeline`](generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline "sklearn.pipeline.Pipeline") 可以把多個評估器鏈接成一個。這個是很有用的,因為處理數據的步驟一般都是固定的,例如特征選擇、標準化和分類。[`Pipeline`](generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline "sklearn.pipeline.Pipeline") 主要有兩個目的:便捷性和封裝性你只要對數據調用 [``](#id2)fit``和 [``](#id4)predict``一次來適配所有的一系列評估器。聯合的參數選擇你可以一次 :ref:[`](#id6)grid search <grid\_search>`管道中所有評估器的參數。安全性訓練轉換器和預測器使用的是相同樣本,管道有助于防止來自測試數據的統計數據泄露到交叉驗證的訓練模型中。管道中的所有評估器,除了最后一個評估器,管道的所有評估器必須是轉換器。 (例如,必須有 `transform` 方法). 最后一個評估器的類型不限(轉換器、分類器等等)
### 4.1.1.1. 用法
> [`Pipeline`](generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline "sklearn.pipeline.Pipeline") 使用一系列 `(key, value)` 鍵值對來構建,其中 `key` 是你給這個步驟起的名字, `value` 是一個評估器對象:
>
>
> ```
> >>> from sklearn.pipeline import Pipeline
> >>> from sklearn.svm import SVC
> >>> from sklearn.decomposition import PCA
> >>> estimators = [('reduce_dim', PCA()), ('clf', SVC())]
> >>> pipe = Pipeline(estimators)
> >>> pipe
> Pipeline(memory=None,
> steps=[('reduce_dim', PCA(copy=True,...)),
> ('clf', SVC(C=1.0,...))])
>
> ```
功能函數 [`make_pipeline`](generated/sklearn.pipeline.make_pipeline.html#sklearn.pipeline.make_pipeline "sklearn.pipeline.make_pipeline") 是構建管道的縮寫; 它接收多個評估器并返回一個管道,自動填充評估器名:
```
>>> from sklearn.pipeline import make_pipeline
>>> from sklearn.naive_bayes import MultinomialNB
>>> from sklearn.preprocessing import Binarizer
>>> make_pipeline(Binarizer(), MultinomialNB())
Pipeline(memory=None,
steps=[('binarizer', Binarizer(copy=True, threshold=0.0)),
('multinomialnb', MultinomialNB(alpha=1.0,
class_prior=None,
fit_prior=True))])
```
管道中的評估器作為一個列表保存在 `steps` 屬性內:
```
>>> pipe.steps[0]
('reduce_dim', PCA(copy=True, iterated_power='auto', n_components=None, random_state=None,
svd_solver='auto', tol=0.0, whiten=False))
```
并作為 `dict` 保存在 `named_steps`:
```
>>> pipe.named_steps['reduce_dim']
PCA(copy=True, iterated_power='auto', n_components=None, random_state=None,
svd_solver='auto', tol=0.0, whiten=False)
```
管道中的評估器參數可以通過 `<estimator>__<parameter>` 語義來訪問:
```
>>> pipe.set_params(clf__C=10)
Pipeline(memory=None,
steps=[('reduce_dim', PCA(copy=True, iterated_power='auto',...)),
('clf', SVC(C=10, cache_size=200, class_weight=None,...))])
```
named\_steps 的屬性映射到多個值,在交互環境支持 tab 補全:
```
>>> pipe.named_steps.reduce_dim is pipe.named_steps['reduce_dim']
True
```
這對網格搜索尤其重要:
```
>>> from sklearn.model_selection import GridSearchCV
>>> param_grid = dict(reduce_dim__n_components=[2, 5, 10],
... clf__C=[0.1, 10, 100])
>>> grid_search = GridSearchCV(pipe, param_grid=param_grid)
```
單獨的步驟可以用多個參數替換,除了最后步驟,其他步驟都可以設置為 `None` 來跳過
```
>>> from sklearn.linear_model import LogisticRegression
>>> param_grid = dict(reduce_dim=[None, PCA(5), PCA(10)],
... clf=[SVC(), LogisticRegression()],
... clf__C=[0.1, 10, 100])
>>> grid_search = GridSearchCV(pipe, param_grid=param_grid)
```
例子:
- [Pipeline Anova SVM](../auto_examples/feature_selection/plot_feature_selection_pipeline.html#sphx-glr-auto-examples-feature-selection-plot-feature-selection-pipeline-py)
- [Sample pipeline for text feature extraction and evaluation](../auto_examples/model_selection/grid_search_text_feature_extraction.html#sphx-glr-auto-examples-model-selection-grid-search-text-feature-extraction-py)
- [Pipelining: chaining a PCA and a logistic regression](../auto_examples/plot_digits_pipe.html#sphx-glr-auto-examples-plot-digits-pipe-py)
- [Explicit feature map approximation for RBF kernels](../auto_examples/plot_kernel_approximation.html#sphx-glr-auto-examples-plot-kernel-approximation-py)
- [SVM-Anova: SVM with univariate feature selection](../auto_examples/svm/plot_svm_anova.html#sphx-glr-auto-examples-svm-plot-svm-anova-py)
- [Selecting dimensionality reduction with Pipeline and GridSearchCV](../auto_examples/plot_compare_reduction.html#sphx-glr-auto-examples-plot-compare-reduction-py)
也可以參閱:
- [調整估計器的超參數](grid_search.html#grid-search)
### 4.1.1.2. 注意點
對管道調用 `fit` 方法的效果跟依次對每個評估器調用 `fit` 方法一樣, 都是``transform`` 輸入并傳遞給下個步驟。 管道中最后一個評估器的所有方法,管道都有,例如,如果最后的評估器是一個分類器, [`Pipeline`](generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline "sklearn.pipeline.Pipeline") 可以當做分類器來用。如果最后一個評估器是轉換器,管道也一樣可以。
### 4.1.1.3. 緩存轉換器:避免重復計算
適配轉換器是很耗費計算資源的。設置了``memory`` 參數, [`Pipeline`](generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline "sklearn.pipeline.Pipeline") 將會在調用``fit``方法后緩存每個轉換器。 如果參數和輸入數據相同,這個特征用于避免重復計算適配的轉換器。典型的例子是網格搜索轉換器,該轉化器只要適配一次就可以多次使用。
> `memory` 參數用于緩存轉換器。
`memory` 可以是包含要緩存的轉換器的目錄的字符串或一個 [joblib.Memory](https://pythonhosted.org/joblib/memory.html)對象:
```
>>> from tempfile import mkdtemp
>>> from shutil import rmtree
>>> from sklearn.decomposition import PCA
>>> from sklearn.svm import SVC
>>> from sklearn.pipeline import Pipeline
>>> estimators = [('reduce_dim', PCA()), ('clf', SVC())]
>>> cachedir = mkdtemp()
>>> pipe = Pipeline(estimators, memory=cachedir)
>>> pipe
Pipeline(...,
steps=[('reduce_dim', PCA(copy=True,...)),
('clf', SVC(C=1.0,...))])
>>> # Clear the cache directory when you don't need it anymore
>>> rmtree(cachedir)
```
Warning
**Side effect of caching transfomers**
使用 [`Pipeline`](generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline "sklearn.pipeline.Pipeline") 而不開啟緩存功能,還是可以通過查看原始實例的,例如:
```
>>> from sklearn.datasets import load_digits
>>> digits = load_digits()
>>> pca1 = PCA()
>>> svm1 = SVC()
>>> pipe = Pipeline([('reduce_dim', pca1), ('clf', svm1)])
>>> pipe.fit(digits.data, digits.target)
...
Pipeline(memory=None,
steps=[('reduce_dim', PCA(...)), ('clf', SVC(...))])
>>> # The pca instance can be inspected directly
>>> print(pca1.components_)
[[ -1.77484909e-19 ... 4.07058917e-18]]
```
開啟緩存會在適配前觸發轉換器的克隆。因此,管道的轉換器實例不能被直接查看。 在下面例子中, 訪問 `PCA` 實例 `pca2`將會引發 `AttributeError` 因為 `pca2` 是一個未適配的轉換器。 這時應該使用屬性 `named_steps` 來檢查管道的評估器:
```
>>> cachedir = mkdtemp()
>>> pca2 = PCA()
>>> svm2 = SVC()
>>> cached_pipe = Pipeline([('reduce_dim', pca2), ('clf', svm2)],
... memory=cachedir)
>>> cached_pipe.fit(digits.data, digits.target)
...
Pipeline(memory=...,
steps=[('reduce_dim', PCA(...)), ('clf', SVC(...))])
>>> print(cached_pipe.named_steps['reduce_dim'].components_)
...
[[ -1.77484909e-19 ... 4.07058917e-18]]
>>> # Remove the cache directory
>>> rmtree(cachedir)
```
例子:
- [Selecting dimensionality reduction with Pipeline and GridSearchCV](../auto_examples/plot_compare_reduction.html#sphx-glr-auto-examples-plot-compare-reduction-py)
## 4.1.2. FeatureUnion(特征聯合): 個特征層面
[`FeatureUnion`](generated/sklearn.pipeline.FeatureUnion.html#sklearn.pipeline.FeatureUnion "sklearn.pipeline.FeatureUnion") 合并了多個轉換器對象形成一個新的轉換器,該轉換器合并了他們的輸出。一個 [`FeatureUnion`](generated/sklearn.pipeline.FeatureUnion.html#sklearn.pipeline.FeatureUnion "sklearn.pipeline.FeatureUnion") 可以接收多個轉換器對象。在適配期間,每個轉換器都單獨的和數據適配。 對于轉換數據,轉換器可以并發使用,且輸出的樣本向量被連接成更大的向量。
[`FeatureUnion`](generated/sklearn.pipeline.FeatureUnion.html#sklearn.pipeline.FeatureUnion "sklearn.pipeline.FeatureUnion") 功能與 [`Pipeline`](generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline "sklearn.pipeline.Pipeline") 一樣- 便捷性和聯合參數的估計和驗證。
可以結合:class:FeatureUnion 和 [`Pipeline`](generated/sklearn.pipeline.Pipeline.html#sklearn.pipeline.Pipeline "sklearn.pipeline.Pipeline") 來創造出復雜模型。
(一個 [`FeatureUnion`](generated/sklearn.pipeline.FeatureUnion.html#sklearn.pipeline.FeatureUnion "sklearn.pipeline.FeatureUnion") 沒辦法檢查兩個轉換器是否會產出相同的特征。它僅僅在特征集合不相關時產生聯合并確認是調用者的職責。)
### 4.1.2.1. 用法
一個 [`FeatureUnion`](generated/sklearn.pipeline.FeatureUnion.html#sklearn.pipeline.FeatureUnion "sklearn.pipeline.FeatureUnion") 是通過一系列 `(key, value)` 鍵值對來構建的,其中的 `key` 給轉換器指定的名字 (一個絕對的字符串; 他只是一個代號), `value` 是一個評估器對象:
```
>>> from sklearn.pipeline import FeatureUnion
>>> from sklearn.decomposition import PCA
>>> from sklearn.decomposition import KernelPCA
>>> estimators = [('linear_pca', PCA()), ('kernel_pca', KernelPCA())]
>>> combined = FeatureUnion(estimators)
>>> combined
FeatureUnion(n_jobs=1,
transformer_list=[('linear_pca', PCA(copy=True,...)),
('kernel_pca', KernelPCA(alpha=1.0,...))],
transformer_weights=None)
```
跟管道一樣,特征聯合有一個精簡版的構造器叫做:func:make\_union ,該構造器不需要顯式給每個組價起名字。
正如 `Pipeline`, 單獨的步驟可能用``set\_params``替換 ,并設置為 [``](#id12)None``來跳過:
```
>>> combined.set_params(kernel_pca=None)
...
FeatureUnion(n_jobs=1,
transformer_list=[('linear_pca', PCA(copy=True,...)),
('kernel_pca', None)],
transformer_weights=None)
```
例子:
- [Concatenating multiple feature extraction methods](../auto_examples/plot_feature_stacker.html#sphx-glr-auto-examples-plot-feature-stacker-py)
- [Feature Union with Heterogeneous Data Sources](../auto_examples/hetero_feature_union.html#sphx-glr-auto-examples-hetero-feature-union-py)
- scikit-learn 0.19 中文文檔
- 用戶指南
- 1. 監督學習
- 1.1. 廣義線性模型
- 1.2. 線性和二次判別分析
- 1.3. 內核嶺回歸
- 1.4. 支持向量機
- 1.5. 隨機梯度下降
- 1.6. 最近鄰
- 1.7. 高斯過程
- 1.8. 交叉分解
- 1.9. 樸素貝葉斯
- 1.10. 決策樹
- 1.11. 集成方法
- 1.12. 多類和多標簽算法
- 1.13. 特征選擇
- 1.14. 半監督學習
- 1.15. 等式回歸
- 1.16. 概率校準
- 1.17. 神經網絡模型(有監督)
- 2. 無監督學習
- 2.1. 高斯混合模型
- 2.2. 流形學習
- 2.3. 聚類
- 2.4. 雙聚類
- 2.5. 分解成分中的信號(矩陣分解問題)
- 2.6. 協方差估計
- 2.7. 經驗協方差
- 2.8. 收斂協方差
- 2.9. 稀疏逆協方差
- 2.10. Robust 協方差估計
- 2.11. 新奇和異常值檢測
- 2.12. 密度估計
- 2.13. 神經網絡模型(無監督)
- 3. 模型選擇和評估
- 3.1. 交叉驗證:評估估算器的表現
- 3.2. 調整估計器的超參數
- 3.3. 模型評估: 量化預測的質量
- 3.4. 模型持久化
- 3.5. 驗證曲線: 繪制分數以評估模型
- 4. 數據集轉換
- 4.1. Pipeline(管道)和 FeatureUnion(特征聯合): 合并的評估器
- 4.2. 特征提取
- 4.3. 預處理數據
- 4.4. 無監督降維
- 4.5. 隨機投影
- 4.6. 內核近似
- 4.7. 成對的矩陣, 類別和核函數
- 4.8. 預測目標 (y) 的轉換
- 5. 數據集加載工具
- 6. 大規模計算的策略: 更大量的數據
- 7. 計算性能
- 教程
- 使用 scikit-learn 介紹機器學習
- 關于科學數據處理的統計學習教程
- 機器學習: scikit-learn 中的設置以及預估對象
- 監督學習:從高維觀察預測輸出變量
- 模型選擇:選擇估計量及其參數
- 無監督學習: 尋求數據表示
- 把它們放在一起
- 尋求幫助
- 處理文本數據
- 選擇正確的評估器(estimator)
- 外部資源,視頻和談話