为了调整机器学习(甚至是管道)的超参数,sklearn提出了详尽的”GridsearchCV”和随机的”RandomizedSearchCV“。后者会对提供的分布进行抽样并进行测试,最终选出最佳模型(并提供每次尝试的结果)。
假设我使用这种随机方法训练了1000个模型。后来,我觉得不够精确,想再尝试1000个模型。我能继续训练吗?也就是说,要求更多抽样,尝试更多模型而不会丢失当前进度。第二次调用fit()
会“重新开始”并丢弃之前的超参数组合。
我的情况如下所示:
pipeline_cv = RandomizedSearchCV(pipeline, distribution, n_iter=1000, n_jobs=-1)pipeline_cv = pipeline_cv.fit(trainX, trainy)predictions = pipeline_cv.predict(targetX)
然后,后来我决定1000次迭代不足以覆盖我的分布空间,所以我想做类似的事情
pipeline_cv = pipeline_cv.resume(trainX, trainy, n_iter=1000) # 不存在?
然后我将拥有一个跨2000个超参数组合训练的模型。
我的目标可以实现吗?
回答:
有一个Github问题从2017年9月开始就存在,但仍然未解决:
在实践中,搜索某个参数空间然后继续搜索相关空间是有用的。我们可以提供一个
warm_start
参数,使得将进一步候选的结果累积到cv_results_
中变得简单(而不需要重新评估已经测试过的参数组合)。
在Cross Validated上有一个类似的提问也未得到有效回答。
所以,答案似乎是不可以(而且scikit-learn社区还没有感到需要包含这样的可能性)。
但是,让我们停下来思考一下这样的功能是否真的有价值…
RandomizedSearchCV本质上是通过从给定分布中随机抽样参数值来工作的;例如,使用文档中的示例:
distributions = dict(C=uniform(loc=0, scale=4), penalty=['l2', 'l1'])
根据这种随机抽样和随机数生成(RNG)的基本原则,无法保证随机抽样的值不会被多次抽样,特别是当迭代次数很大时。考虑到RandomizedSearchCV本身不进行任何记录,因此原则上在任何一次运行中都可能发生相同的参数组合被多次尝试(再次假设迭代次数足够大)。
即使在连续分布(如上文使用的均匀分布)的情况下,已经抽样的确切值的概率可能非常小,但常规情况是两个样本如0.678918
和0.678919
,尽管非常接近,但它们仍然是不同的,并被视为不同的试验。
鉴于以上情况,我看不出“热启动”RandomizedSearchCV有什么实际用处。RandomizedSearchCV的真正价值在于能够抽样通常很大的参数值区域 – 如此之大以至于我们认为使用简单随机抽样的力量是有用的,让我重复一遍,这本身并不“记住”过去的样本,并且很可能返回与过去已经返回的样本(完全或近似)相同的样本,从而使任何“热启动”实际上变得无关紧要。
因此,有效地,简单地顺序运行两个(或更多)RandomizedSearchCV过程(并存储它们的结果)就可以很好地完成任务,前提是我们不对不同的运行使用相同的随机种子(即在上面提到的Cross Validated线程中有效建议的内容)。