Scikit-Learn网格搜索自定义评分函数

9

我需要对一个维度为(5000,26421)的数据集执行核PCA以获得较低维度的表示。为了选择组件数(例如k)参数,我正在对数据进行缩减和重构到原始空间,并针对不同的k值获取重构和原始数据的均方误差。

我发现sklearn的gridsearch功能,并希望将其用于上述参数估计。由于核PCA没有评分函数,因此我已经实现了自定义评分函数并将其传递给Gridsearch。

from sklearn.decomposition.kernel_pca import KernelPCA
from sklearn.model_selection import GridSearchCV
import numpy as np
import math

def scorer(clf, X):
    Y1 = clf.inverse_transform(X)
    error = math.sqrt(np.mean((X - Y1)**2))
    return error

param_grid = [
    {'degree': [1, 10], 'kernel': ['poly'], 'n_components': [100, 400, 100]},
    {'gamma': [0.001, 0.0001], 'kernel': ['rbf'], 'n_components': [100, 400, 100]},
]

kpca = KernelPCA(fit_inverse_transform=True, n_jobs=30)
clf = GridSearchCV(estimator=kpca, param_grid=param_grid, scoring=scorer)
clf.fit(X)

然而,它导致以下错误:
/usr/lib64/python2.7/site-packages/sklearn/metrics/pairwise.py in check_pairwise_arrays(X=array([[ 2.,  2.,  1., ...,  0.,  0.,  0.],
    ....,  0.,  1., ...,  0.,  0.,  0.]], dtype=float32), Y=array([[-0.05904257, -0.02796719,  0.00919842, ....        0.00148251, -0.00311711]], dtype=float32), precomp
uted=False, dtype=<type 'numpy.float32'>)
    117                              "for %d indexed." %
    118                              (X.shape[0], X.shape[1], Y.shape[0]))
    119     elif X.shape[1] != Y.shape[1]:
    120         raise ValueError("Incompatible dimension for X and Y matrices: "
    121                          "X.shape[1] == %d while Y.shape[1] == %d" % (
--> 122                              X.shape[1], Y.shape[1]))
        X.shape = (1667, 26421)
        Y.shape = (112, 100)
    123 
    124     return X, Y
    125 
    126 

ValueError: Incompatible dimension for X and Y matrices: X.shape[1] == 26421 while Y.shape[1] == 100

有人能指出我到底做错了什么吗?

首先,PCA有一个score()函数。其次,使用make_scorer()将自定义的得分函数传递给gridSearch。 - Vivek Kumar
我在这种情况下没有使用PCA,而是使用没有分数函数的Kernel PCA。我也尝试使用make_scorer函数,但该方法无效。 - user1683894
我也遇到了这个问题。你解决了吗? - MikeB2019x
1个回答

11

评分函数的语法不正确。你只需要传递分类器的预测真实值即可。因此,这是声明自定义评分函数的方法:

def my_scorer(y_true, y_predicted):
    error = math.sqrt(np.mean((y_true - y_predicted)**2))
    return error

然后您可以在Sklearn中使用make_scorer函数将其传递给GridSearch。请确保相应地设置greater_is_better属性:

score_func是得分函数(默认),表示高分好,还是损失函数,表示低分好。在后一种情况下,评分器对象将签署翻转score_func的结果。

我假设您正在计算错误,因此此属性应设置为False,因为误差越小越好:

from sklearn.metrics import make_scorer
my_func = make_scorer(my_scorer, greater_is_better=False)

然后你将其传递给GridSearch:

GridSearchCV(estimator=my_clf, param_grid=param_grid, scoring=my_func)

其中,my_clf是您的分类器。

还有一件事,我认为GridSearchCV并不完全是您要寻找的。它基本上接受以训练和测试集形式提供的数据。但是在这里,您只想转换输入数据。您需要使用Sklearn中的Pipeline。请查看此处提到的结合PCA和GridSearchCV的示例(链接)


1
我需要调整Kernel Pca的超参数,以找到最小重构误差的参数设置,并发现GridSearch也可以做到这一点。在上述情况下,来自于 y_predicted = kpca.fit_transform(input_data) y_true = kpca.inverse_transform(y_predicted) 因此,在错误函数中有clf参数。即使按照您的方法,我仍然会收到一个错误“TypeError: call()至少需要4个参数(已给出3个)”。 - user1683894

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接