我正在研究一个监督学习算法,它似乎表现出一种奇怪的行为。所以,让我开始吧:
我有一个函数,我会传递不同的分类器、它们的参数、训练数据及其标签:
def HT(targets,train_new, algorithm, parameters):#创建我的评分器scorer=make_scorer(f1_score)#使用函数的参数创建网格搜索对象grid_search = GridSearchCV(algorithm, param_grid=parameters,scoring=scorer, cv=5)#将网格搜索对象拟合到数据上grid_search.fit(train_new, targets.ravel())#打印分类器的名称、最佳得分和最佳参数print algorithm.__class__.__name__print('最佳得分: {}'.format(grid_search.best_score_))print('最佳参数: {}'.format(grid_search.best_params_))#将最佳估计器赋值给pipeline变量pipeline=grid_search.best_estimator_#预测训练集的结果results=pipeline.predict(train_new).astype(int)print results return pipeline
我向这个函数传递的参数如下:
clf_param.append( {'C' : np.array([0.001,0.01,0.1,1,10]), 'kernel':(['linear','rbf']),'decision_function_shape' : (['ovr'])})
好的,这里事情开始变得奇怪了。这个函数返回了一个f1_score,但它与我使用公式手动计算的得分不同:F1 = 2 * (precision * recall) / (precision + recall)
两者之间有相当大的差异(0.68与0.89相比)
我在函数中做错了什么吗?grid_search计算的得分(grid_search.best_score_)应该与整个训练集上的得分(grid_search.best_estimator_.predict(train_new))相同吗?谢谢
回答:
你手动计算的得分考虑了所有类别的全局真阳性和真阴性。但在scikit中,f1_score的默认方法是计算二元平均(即仅针对阳性类)。
因此,为了获得相同的得分,请按如下方式使用f1_score:
scorer=make_scorer(f1_score, average='micro')
或者,在gridSearchCV中简单地使用:
scoring = 'f1_micro'
关于如何进行得分平均的更多信息,请参见: – http://scikit-learn.org/stable/modules/model_evaluation.html#common-cases-predefined-values
你可能还想查看以下回答,其中详细描述了scikit中得分的计算方法:
编辑:已将macro改为micro。如文档中所述:
‘micro’: 通过计算总的真阳性、假阴性和假阳性来全局计算指标。