使用管道和 GridSearchCV 选择降维#

此示例构建了一个管道,该管道执行降维,然后使用支持向量分类器进行预测。它演示了如何使用 GridSearchCVPipeline 在单个 CV 运行中优化不同类型的估计器 - 无监督 PCANMF 降维在网格搜索期间与单变量特征选择进行比较。

此外,Pipeline 可以使用 memory 参数实例化,以记忆管道中的转换器,避免对相同的转换器反复拟合。

请注意,当转换器的拟合成本很高时,使用 memory 来启用缓存会很有趣。

# Authors: Robert McGibbon
#          Joel Nothman
#          Guillaume Lemaitre

管道和 GridSearchCV 的图示#

import matplotlib.pyplot as plt
import numpy as np

from sklearn.datasets import load_digits
from sklearn.decomposition import NMF, PCA
from sklearn.feature_selection import SelectKBest, mutual_info_classif
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import MinMaxScaler
from sklearn.svm import LinearSVC

X, y = load_digits(return_X_y=True)

pipe = Pipeline(
    [
        ("scaling", MinMaxScaler()),
        # the reduce_dim stage is populated by the param_grid
        ("reduce_dim", "passthrough"),
        ("classify", LinearSVC(dual=False, max_iter=10000)),
    ]
)

N_FEATURES_OPTIONS = [2, 4, 8]
C_OPTIONS = [1, 10, 100, 1000]
param_grid = [
    {
        "reduce_dim": [PCA(iterated_power=7), NMF(max_iter=1_000)],
        "reduce_dim__n_components": N_FEATURES_OPTIONS,
        "classify__C": C_OPTIONS,
    },
    {
        "reduce_dim": [SelectKBest(mutual_info_classif)],
        "reduce_dim__k": N_FEATURES_OPTIONS,
        "classify__C": C_OPTIONS,
    },
]
reducer_labels = ["PCA", "NMF", "KBest(mutual_info_classif)"]

grid = GridSearchCV(pipe, n_jobs=1, param_grid=param_grid)
grid.fit(X, y)
GridSearchCV(estimator=Pipeline(steps=[('scaling', MinMaxScaler()),
                                       ('reduce_dim', 'passthrough'),
                                       ('classify',
                                        LinearSVC(dual=False,
                                                  max_iter=10000))]),
             n_jobs=1,
             param_grid=[{'classify__C': [1, 10, 100, 1000],
                          'reduce_dim': [PCA(iterated_power=7),
                                         NMF(max_iter=1000)],
                          'reduce_dim__n_components': [2, 4, 8]},
                         {'classify__C': [1, 10, 100, 1000],
                          'reduce_dim': [SelectKBest(score_func=<function mutual_info_classif at 0x7f4e3209cee0>)],
                          'reduce_dim__k': [2, 4, 8]}])
在 Jupyter 环境中,请重新运行此单元格以显示 HTML 表示或信任笔记本。
在 GitHub 上,HTML 表示无法呈现,请尝试使用 nbviewer.org 加载此页面。


import pandas as pd

mean_scores = np.array(grid.cv_results_["mean_test_score"])
# scores are in the order of param_grid iteration, which is alphabetical
mean_scores = mean_scores.reshape(len(C_OPTIONS), -1, len(N_FEATURES_OPTIONS))
# select score for best C
mean_scores = mean_scores.max(axis=0)
# create a dataframe to ease plotting
mean_scores = pd.DataFrame(
    mean_scores.T, index=N_FEATURES_OPTIONS, columns=reducer_labels
)

ax = mean_scores.plot.bar()
ax.set_title("Comparing feature reduction techniques")
ax.set_xlabel("Reduced number of features")
ax.set_ylabel("Digit classification accuracy")
ax.set_ylim((0, 1))
ax.legend(loc="upper left")

plt.show()
Comparing feature reduction techniques

在管道中缓存转换器#

有时,将特定转换器的状态存储起来是值得的,因为它可以再次使用。在 GridSearchCV 中使用管道会触发这种情况。因此,我们使用参数 memory 来启用缓存。

警告

请注意,此示例仅为说明,因为在此特定情况下,拟合 PCA 不一定比加载缓存慢。因此,当转换器的拟合成本很高时,请使用 memory 构造函数参数。

from shutil import rmtree

from joblib import Memory

# Create a temporary folder to store the transformers of the pipeline
location = "cachedir"
memory = Memory(location=location, verbose=10)
cached_pipe = Pipeline(
    [("reduce_dim", PCA()), ("classify", LinearSVC(dual=False, max_iter=10000))],
    memory=memory,
)

# This time, a cached pipeline will be used within the grid search


# Delete the temporary cache before exiting
memory.clear(warn=False)
rmtree(location)

仅在评估 LinearSVC 分类器 C 参数的第一个配置时计算 PCA 拟合。C 的其他配置将触发加载缓存的 PCA 估计器数据,从而节省处理时间。因此,当拟合转换器成本很高时,使用 memory 缓存管道非常有利。

脚本总运行时间:(0 分钟 47.213 秒)

相关示例

增量 PCA

增量 PCA

平衡模型复杂度和交叉验证得分

平衡模型复杂度和交叉验证得分

缓存最近邻

缓存最近邻

连接多个特征提取方法

连接多个特征提取方法

由 Sphinx-Gallery 生成的画廊