我想使用scikit-learn管道的第一步来生成一个玩具数据集,以便评估我的分析的性能。我想出了一个尽可能简单的解决方案,如下所示:
import numpy as np
from sklearn.pipeline import Pipeline
from sklearn.grid_search import GridSearchCV
from sklearn.base import TransformerMixin
from sklearn import cluster
class FeatureGenerator(TransformerMixin):
def __init__(self, num_features=None):
self.num_features = num_features
def fit(self, X, y=None, **fit_params):
return self
def transform(self, X, **transform_params):
return np.array(
range(self.num_features*self.num_features)
).reshape(self.num_features,
self.num_features)
def get_params(self, deep=True):
return {"num_features": self.num_features}
def set_params(self, **parameters):
self.num_features = parameters["num_features"]
return self
这个变压器在运行时可以这样调用:
pipeline = Pipeline([
('pick_features', FeatureGenerator(100)),
('kmeans', cluster.KMeans())
])
pipeline = pipeline.fit(None)
classes = pipeline.predict(None)
print classes
当我尝试在这个管道上进行网格搜索时,它对我来说就变得棘手了:
parameter_sets = {
'pick_features__num_features' : [10,20,30],
'kmeans__n_clusters' : [2,3,4]
}
pipeline = Pipeline([
('pick_features', FeatureGenerator()),
('kmeans', cluster.KMeans())
])
g_search_estimator = GridSearchCV(pipeline, parameter_sets)
g_search_estimator.fit(None,None)
网格搜索期望样本和标签作为输入,并且不像管道那样鲁棒,管道不会抱怨None
作为输入参数:
TypeError: Expected sequence or array-like, got <type 'NoneType'>
这是有意义的,因为网格搜索需要将数据集划分为不同的cv-partition。
除了上面的例子,我还有很多参数,可以在数据集生成步骤中进行调整。因此,我需要一个解决方案,将这一步纳入我的参数选择交叉验证。
问题:是否有办法从第一个变压器内部设置GridSearch的X
s和y
s ?或者用多个不同的数据集(最好是并行的)调用GridSearch的解决方案是什么样子的?或者有人尝试定制GridSearchCV
或者可以指出一些阅读材料吗?
您的代码非常干净,所以很高兴为您提供这个快速而肮脏的解决方案:
g_search_estimator.fit([1., 1., 1.],[1., 0., 0.])
g_search_estimator.best_params_
输出:[tons of int64 to float64 conversion warnings]
{'kmeans__n_clusters': 4, 'pick_features__num_features': 10}
注意你需要3个样本,因为你正在做(默认)3次交叉验证。
您得到的错误是因为GridSearchCV
对象执行的检查而发生的,所以它发生在您的转换器有机会做任何事情之前。所以我对你的第一个问题说"不":
编辑:是否有办法设置的x和ys的GridSearch从内部第一次变压器吗?
我意识到这是不必要的混淆,以下三行是等效的:g_search_estimator.fit([1。1。1。[1]。, 0。, 0。)g_search_estimator.fit([1。1。1。),没有一个)g_search_estimator.fit([1。1。1。)
很抱歉匆忙地把随机的y
s扔在那里。
关于网格搜索如何计算不同网格点的分数的一些解释:当你将scoring=None
传递给GridSearchCV
构造函数时(这是默认的,所以这就是你在这里所拥有的),它要求估计器提供分数函数。如果有这样一个函数,它将用于评分。对于KMeans
,默认的分数函数本质上是与聚类中心的距离和相反。
这是一个无监督指标,所以这里不需要y
。
总而言之,你将永远能够:
从第一个变压器内部设置GridSearch的x
把输入的X
"转换"成完全不相关的东西,没有人会抱怨的。你需要一些输入random_X
。
现在,如果你想使用监督指标(我从你的问题中有这种感觉),你也需要指定y
。
一个简单的场景是你有一个固定的y
向量,你想用它尝试几个X
。然后输入:
g_search_estimator.fit(random_X, y, scoring=my_scoring_function)
,它应该运行良好。如果你想搜索不同的y
值,这可能会有点棘手。