选择内核和超参数以减少内核 PCA

Mar*_*zee 3 python scikit-learn

我正在阅读《使用 Scikit-Learn 和 TensorFlow 进行机器学习实践:构建智能系统的概念、工具和技术》

我正在尝试优化无监督内核 PCA 算法。这是一些背景:

另一种完全无监督的方法是选择产生最低重建误差的内核和超参数。然而,重建并不像线性 PCA 那么容易

....

幸运的是,可以在原始空间中找到一个接近重建点的点。这称为重建原像。获得此原像后,您可以测量其到原始实例的平方距离。然后,您可以选择最小化此重建原像误差的内核和超参数。

一种解决方案是训练有监督回归模型,以投影实例作为训练集,以原始实例作为目标。

现在,您可以使用带有交叉验证的网格搜索来查找可最小化此前图像重建误差的内核和超参数。

书中提供的无需交叉验证即可执行重建的代码是:

rbf_pca = KernelPCA(n_components = 2, kernel="rbf", gamma=0.0433,fit_inverse_transform=True)
X_reduced = rbf_pca.fit_transform(X)
X_preimage = rbf_pca.inverse_transform(X_reduced)

>>> from sklearn.metrics import mean_squared_error
>>> mean_squared_error(X, X_preimage)
32.786308795766132
Run Code Online (Sandbox Code Playgroud)

我的问题是,如何实施交叉验证来调整内核和超参数以最小化原像重建误差?

到目前为止,这是我的尝试:

from sklearn.metrics import mean_squared_error
from sklearn.decomposition import KernelPCA

mean_squared_error(X, X_preimage)

kpca=KernelPCA(fit_inverse_transform=True, n_jobs=-1) 

from sklearn.model_selection import GridSearchCV

param_grid = [{
        "kpca__gamma": np.linspace(0.03, 0.05, 10),
        "kpca__kernel": ["rbf", "sigmoid", "linear", "poly"]
    }]

grid_search = GridSearchCV(clf, param_grid, cv=3, scoring='mean_squared_error')
X_reduced = kpca.fit_transform(X)
X_preimage = kpca.inverse_transform(X_reduced)
grid_search.fit(X,X_preimage)
Run Code Online (Sandbox Code Playgroud)

谢谢

Viv*_*mar 5

GridSearchCV能够对无监督学习进行交叉验证(没有),如文档中y所示:

适合(X,y=无,组=无,**fit_params)

...
y : array-like, shape = [n_samples] or [n_samples, n_output], optional 
Target relative to X for classification or regression; 
None for unsupervised learning
...
Run Code Online (Sandbox Code Playgroud)

因此,唯一需要处理的是如何scoring完成遗嘱。

GridSearchCV 中将发生以下情况:

  1. 数据将根据参数X中定义的折叠分为训练测试分割cv

  2. 对于您在 中指定的每个参数组合param_grid,模型将train在上述步骤中的零件上进行训练,然后scoring在零件上使用test

  3. 每个参数组合scores将针对所有折叠进行组合并求平均值。将选择性能最高的参数组合。

现在最棘手的部分是 2。默认情况下,如果您'string'在其中提供 a,它将在内部转换为make_scorer对象。相关'mean_squared_error'代码在这里

....
neg_mean_squared_error_scorer = make_scorer(mean_squared_error,
                                        greater_is_better=False)
....
Run Code Online (Sandbox Code Playgroud)

这是你不想要的,因为这需要y_truey_pred

另一种选择是制作您自己的自定义记分器,如此处讨论的那样带有签名(estimator, X, y)。对于您的情况,如下所示:

from sklearn.metrics import mean_squared_error
def my_scorer(estimator, X, y=None):
    X_reduced = estimator.transform(X)
    X_preimage = estimator.inverse_transform(X_reduced)
    return -1 * mean_squared_error(X, X_preimage)
Run Code Online (Sandbox Code Playgroud)

然后在 GridSearchCV 中使用它,如下所示:

param_grid = [{
        "gamma": np.linspace(0.03, 0.05, 10),
        "kernel": ["rbf", "sigmoid", "linear", "poly"]
    }]

kpca=KernelPCA(fit_inverse_transform=True, n_jobs=-1) 
grid_search = GridSearchCV(kpca, param_grid, cv=3, scoring=my_scorer)
grid_search.fit(X)
Run Code Online (Sandbox Code Playgroud)