Dav*_*idS 3 python scikit-learn
我有一组要建模的特征,其中一个实际上是在 100 个不同点采样的直方图。因此这个直方图特征实际上是 100 个不同的特征。我想通过对直方图特征执行 PCA 来降低建模问题的维度,但是我不想在 PCA 中包含其他特征以保持模型的可解释性。
理想情况下,我想与 PCA 形成一个管道来转换直方图特征和 SVC 以执行拟合,我将其提供给 GridSearchCV 以确定 SVC 超参数。在这个设置中是否有可能让 PCA 只转换我的特征的一个子集(直方图箱)?最简单的方法是编辑 PCA 对象以接受特征掩码,但我当然更愿意使用现有功能。
编辑
在实施@eickenberg 的回答后,我意识到我还需要一个用于新 PCA 类的 inverse_transform 方法。此方法使用列的原始顺序重新创建初始特征集。下面为有兴趣的其他人提供:
def inverse_transform(self, X):
if self.mask is not None:
# Inverse transform appropriate data
inv_mask = np.arange(len(X[0])) >= sum(~self.mask)
inv_transformed = self.pca.inverse_transform(X[:, inv_mask])
# Place inverse transformed columns back in their original order
inv_transformed_reorder = np.zeros([len(X), len(self.mask)])
inv_transformed_reorder[:, self.mask] = inv_transformed
inv_transformed_reorder[:, ~self.mask] = X[:, ~inv_mask]
return inv_transformed_reorder
else:
return self.pca.inverse_transform(X)
Run Code Online (Sandbox Code Playgroud)
这在scikit learn中开箱即用是不可能的。为了能够利用的全部功能Pipeline,并GridSearchCV考虑创建一个对象MaskedPCA,继承sklearn.base.BaseEstimator和揭露方法fit和transform。在其中,您应该PCA在蒙版特征上使用一个对象。掩码应该传递给构造函数。
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.decomposition import PCA
class MaskedPCA(BaseEstimator, TransformerMixin):
def __init__(self, n_components=2, mask=None):
# mask should contain selected cols. Suppose it is boolean to avoid code overhead
self.n_components = n_components
self.mask = mask
def fit(self, X):
self.pca = PCA(n_components=self.n_components)
mask = self.mask
mask = self.mask if self.mask is not None else slice(None)
self.pca.fit(X[:, mask])
return self
def transform(self, X):
mask = self.mask if self.mask is not None else slice(None)
pca_transformed = self.pca.transform(X[:, mask])
if self.mask is not None:
remaining_cols = X[:, ~mask]
return np.hstack([remaining_cols, pca_transformed])
else:
return pca_transformed
Run Code Online (Sandbox Code Playgroud)
您可以在一些生成的数据上对其进行测试
import numpy as np
X = np.random.randn(100, 20)
mask = np.arange(20) > 4
mpca = MaskedPCA(n_components=2, mask=mask)
transformed = mpca.fit(X).transform(X)
# check whether first five columns are equal
from numpy.testing import assert_array_equal
assert_array_equal(X[:, :5], transformed[:, :5])
Run Code Online (Sandbox Code Playgroud)
观察transformed现在有(~mask).sum + mpca.n_components == 7列
| 归档时间: |
|
| 查看次数: |
1937 次 |
| 最近记录: |