在递归特征消除的每一步中对估计器进行超参数估计
Doing hyperparameter estimation for the estimator in each fold of Recursive Feature Elimination
我正在使用 sklearn 通过交叉验证执行递归特征消除,使用 RFECV 模块。 RFE 涉及在完整的特征集上重复训练估计器,然后删除信息量最少的特征,直到收敛到最佳数量的特征。
为了获得估计器的最佳性能,我想select估计器的最佳超参数每个特征数量(为清楚起见进行了编辑)。估计器是一个线性 SVM,所以我只研究 C 参数。
最初,我的代码如下。然而,这只是在开始时对C进行了一次网格搜索,然后每次迭代都使用相同的C。
from sklearn.cross_validation import StratifiedKFold
from sklearn.feature_selection import RFECV
from sklearn import svm, grid_search
def get_best_feats(data,labels,c_values):
parameters = {'C':c_values}
# svm1 passed to clf which is used to grid search the best parameters
svm1 = SVC(kernel='linear')
clf = grid_search.GridSearchCV(svm1, parameters, refit=True)
clf.fit(data,labels)
#print 'best gamma',clf.best_params_['gamma']
# svm2 uses the optimal hyperparameters from svm1
svm2 = svm.SVC(C=clf.best_params_['C'], kernel='linear')
#svm2 is then passed to RFECVv as the estimator for recursive feature elimination
rfecv = RFECV(estimator=svm2, step=1, cv=StratifiedKFold(labels, 5))
rfecv.fit(data,labels)
print "support:",rfecv.support_
return data[:,rfecv.support_]
RFECV 的文档给出了参数 "estimator_params : Parameters for the external estimator. Useful for doing grid searches when an RFE object is passed as an argument to, e.g., a sklearn.grid_search.GridSearchCV object."
因此我想尝试将我的对象'rfecv'传递给网格搜索对象,如下:
def get_best_feats2(data,labels,c_values):
parameters = {'C':c_values
svm1 = SVC(kernel='linear')
rfecv = RFECV(estimator=svm1, step=1, cv=StratifiedKFold(labels, 5), estimator_params=parameters)
rfecv.fit(data, labels)
print "Kept {} out of {} features".format((data[:,rfecv.support_]).shape[1], data.shape[1])
print "support:",rfecv.support_
return data[:,rfecv.support_]
X,y = get_heart_data()
c_values = [0.1,1.,10.]
get_best_feats2(X,y,c_values)
但是这个returns错误:
max_iter=self.max_iter, random_seed=random_seed)
File "libsvm.pyx", line 59, in sklearn.svm.libsvm.fit (sklearn/svm /libsvm.c:1674)
TypeError: a float is required
所以我的问题是:如何将 rfe 对象传递给网格搜索,以便对递归特征消除的每次迭代进行交叉验证?
谢谢
所以你想对 RFE 中的每个特征数量的 SVM 中的 C 进行网格搜索?或者对于 RFECV 中的每个 CV 迭代?从你最后一句话来看,我猜是前者。
您可以 RFE(GridSearchCV(SVC(), param_grid))
实现这一目标,
虽然我不确定这是否真的有用。
我认为第二种现在不可能(但很快)。您可以这样做 GridSeachCV(RFECV(), param_grid={'estimator__C': Cs_to_try})
,但这会将两组交叉验证嵌套在一起。
更新:
GridSearchCV 没有 coef_
,所以第一个失败。
一个简单的修复:
class GridSeachWithCoef(GridSearchCV):
@property
def coef_(self):
return self.best_estimator_.coef_
然后改用它。
我正在使用 sklearn 通过交叉验证执行递归特征消除,使用 RFECV 模块。 RFE 涉及在完整的特征集上重复训练估计器,然后删除信息量最少的特征,直到收敛到最佳数量的特征。
为了获得估计器的最佳性能,我想select估计器的最佳超参数每个特征数量(为清楚起见进行了编辑)。估计器是一个线性 SVM,所以我只研究 C 参数。
最初,我的代码如下。然而,这只是在开始时对C进行了一次网格搜索,然后每次迭代都使用相同的C。
from sklearn.cross_validation import StratifiedKFold
from sklearn.feature_selection import RFECV
from sklearn import svm, grid_search
def get_best_feats(data,labels,c_values):
parameters = {'C':c_values}
# svm1 passed to clf which is used to grid search the best parameters
svm1 = SVC(kernel='linear')
clf = grid_search.GridSearchCV(svm1, parameters, refit=True)
clf.fit(data,labels)
#print 'best gamma',clf.best_params_['gamma']
# svm2 uses the optimal hyperparameters from svm1
svm2 = svm.SVC(C=clf.best_params_['C'], kernel='linear')
#svm2 is then passed to RFECVv as the estimator for recursive feature elimination
rfecv = RFECV(estimator=svm2, step=1, cv=StratifiedKFold(labels, 5))
rfecv.fit(data,labels)
print "support:",rfecv.support_
return data[:,rfecv.support_]
RFECV 的文档给出了参数 "estimator_params : Parameters for the external estimator. Useful for doing grid searches when an RFE object is passed as an argument to, e.g., a sklearn.grid_search.GridSearchCV object."
因此我想尝试将我的对象'rfecv'传递给网格搜索对象,如下:
def get_best_feats2(data,labels,c_values):
parameters = {'C':c_values
svm1 = SVC(kernel='linear')
rfecv = RFECV(estimator=svm1, step=1, cv=StratifiedKFold(labels, 5), estimator_params=parameters)
rfecv.fit(data, labels)
print "Kept {} out of {} features".format((data[:,rfecv.support_]).shape[1], data.shape[1])
print "support:",rfecv.support_
return data[:,rfecv.support_]
X,y = get_heart_data()
c_values = [0.1,1.,10.]
get_best_feats2(X,y,c_values)
但是这个returns错误:
max_iter=self.max_iter, random_seed=random_seed)
File "libsvm.pyx", line 59, in sklearn.svm.libsvm.fit (sklearn/svm /libsvm.c:1674)
TypeError: a float is required
所以我的问题是:如何将 rfe 对象传递给网格搜索,以便对递归特征消除的每次迭代进行交叉验证?
谢谢
所以你想对 RFE 中的每个特征数量的 SVM 中的 C 进行网格搜索?或者对于 RFECV 中的每个 CV 迭代?从你最后一句话来看,我猜是前者。
您可以 RFE(GridSearchCV(SVC(), param_grid))
实现这一目标,
虽然我不确定这是否真的有用。
我认为第二种现在不可能(但很快)。您可以这样做 GridSeachCV(RFECV(), param_grid={'estimator__C': Cs_to_try})
,但这会将两组交叉验证嵌套在一起。
更新:
GridSearchCV 没有 coef_
,所以第一个失败。
一个简单的修复:
class GridSeachWithCoef(GridSearchCV):
@property
def coef_(self):
return self.best_estimator_.coef_
然后改用它。