在管道中对有限数量的变量实施 sklearn PCA

Implementing sklearn PCA on limited number of variables in a pipeline

我正在设置机器学习管道来对一些数据进行分类。数据源之一是 PCA 的非常好的候选者,构成了数据集的最后 n 个维度。我想对这些变量而不是前面的变量使用 PCA。通过 stackexchange 搜索,这似乎也是一个普遍面临的问题——人们只想将 PCA 应用于一部分数据。

显然,我可以先进行 PCA,然后连接数据集,然后将其传递给管道,但据我所知,PCA 应该是管道的一部分,否则来自测试样本的信息会渗入训练数据中。

我想使用 sklearn 的 PCA 函数(但我也愿意接受建议)但它不接受任何参数来定义对哪些变量进行 PCA,因此很难将其合并到管道中。

我目前的解决方法是定义一个新的 PCA,它选择所需的特征,看起来像这样:

class new_PCA(PCA):
    
    @staticmethod
    def reduce(X):
        return X.iloc[:,NUMBER_NONPCA_FEATURES:]

    # Define PCA for limited number of columns
    def _fit(self, X):
        part_X = self.reduce(X)
        PCA._fit(self,part_X)

    def transform(self, X):
        part_X = self.reduce(X)
        pca_part = PCA.transform(self, part_X)
        X_new = np.concatenate([X.iloc[:,:NUMBER_NONPCA_FEATURES],pca_part],axis=1)
        return X_new

    def score_samples(self, X):
        part_X = self.reduce(X)
        PCA.score_samples(self,part_X)

    def inverse_transform(self, X):
        part_X = self.reduce(X)
        PCA.inverse_transform(self,part_X)

所以基础_fit()方法和transform()都限制在当前变量。这似乎可行,通过检查源代码,我认为这涵盖了所有将训练数据 (X) 作为输入的方法。

我只是有点担心我可能忽略了一些东西,这可能会在某处产生一些意想不到的后果。这看起来不错吗?

您的解决方法不是必需的,因为 sklearn 已经涵盖了这个用例。可以通过包含 ColumnTransformer in the pipeline.

来实现针对不同特征的不同转换

考虑下面的例子:

pipe = Pipeline(
    [
        ('ct', 
            ColumnTransformer(
             [("PCA", PCA(), [0, 1, 2]),
             ("pass", "passthrough", [3, 4, 5])])
        ),
         ('svc', SVC())
    ]
)

管道的 ColumnTransformer 阶段可以看作是一个连接点,将进入的列分成子集,并将指定的转换器应用于传递的列(此处作为索引传递,但也可以是列名)。
在示例中,PCA 仅应用于索引为 0、1 和 2 的列,而列 3、4 和 5 不进行任何转换就传递到管道的下一阶段。