【问题标题】:Cross validation with multiple parameters using f1-score使用 f1-score 对多个参数进行交叉验证
【发布时间】:2019-11-14 05:39:21
【问题描述】:

我正在尝试使用 SelectKBest 进行特征选择,并使用 f1-score 进行二元分类的最佳树深度。我创建了一个记分器功能来选择最佳功能并评估网格搜索。当分类器试图适应训练数据时,会弹出“call() missing 1 required positional argument: 'y_true'”的错误。

#Define scorer
f1_scorer = make_scorer(f1_score)
#Split data into training, CV and test set
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.25, random_state = 0)

#initialize tree and Select K-best features for classifier   
kbest = SelectKBest(score_func=f1_scorer, k=all)
clf = DecisionTreeClassifier(random_state=0)

#create a pipeline for features to be optimized
pipeline = Pipeline([('kbest',kbest),('dt',clf)])

#initialize a grid search with features to be optimized
gs = GridSearchCV(pipeline,{'kbest__k': range(2,11), 'dt__max_depth':range(3,7)}, refit=True, cv=5, scoring = f1_scorer)

gs.fit(X_train,y_train)

#order best selected features into a single variable
selector = SelectKBest(score_func=f1_scorer, k=gs.best_params_['kbest__k'])
X_new = selector.fit_transform(X_train,y_train)  

On the fit line I get a TypeError: __call__() missing 1 required positional argument: 'y_true'.

【问题讨论】:

    标签: python scikit-learn


    【解决方案1】:

    问题在于您用于SelectKBest 的score_func。 score_func 是一个函数,它接受两个数组 X 和 y,并返回一对数组(分数、pvalues)或一个带有分数的数组,但在您的代码中你已经将可调用的f1_scorer 提供为score_func,它只需要你的y_true 和y_pred 并计算f1 score。您可以使用chi2、f_classif 或mutual_info_classif 之一作为您的score_func 进行分类任务。此外,SelectKBest 的参数k 中有一个小错误,它应该是"all" 而不是all。我已经修改了包含这些更改的代码,

    from sklearn.tree import DecisionTreeClassifier
    from sklearn.feature_selection import SelectKBest
    from sklearn.pipeline import Pipeline
    from sklearn.model_selection import GridSearchCV
    from sklearn.feature_selection import f_classif  
    from sklearn.metrics import f1_score, make_scorer
    from sklearn.datasets import make_classification
    
    X, y = make_classification(n_samples=1000, n_classes=2,
                           n_informative=4, weights=[0.7, 0.3],
                           random_state=0)
    
    f1_scorer = make_scorer(f1_score)
    #Split data into training, CV and test set
    X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.25, random_state = 0)
    
    #initialize tree and Select K-best features for classifier   
    kbest = SelectKBest(score_func=f_classif)
    clf = DecisionTreeClassifier(random_state=0)
    
    #create a pipeline for features to be optimized
    pipeline = Pipeline([('kbest',kbest),('dt',clf)])
    gs = GridSearchCV(pipeline,{'kbest__k': range(2,11), 'dt__max_depth':range(3,7)}, refit=True, cv=5, scoring = f1_scorer)
    gs.fit(X_train,y_train)
    gs.best_params_
    

    输出

    {'dt__max_depth': 6, 'kbest__k': 9}

    同时修改你的最后两行如下:

    selector = SelectKBest(score_func=f_classif, k=gs.best_params_['kbest__k'])
    X_new = selector.fit_transform(X_train,y_train)  
    

    希望这会有所帮助!

    【讨论】:

    • 您好 Parthasarathy,谢谢您。有什么方法可以使用 f1-score 作为得分函数来选择最佳 K 特征?我尝试使用 f_classif,但性能比我考虑整个功能集时要差。
    • 在上面的代码中,当您说scoring = f1_scorer 时,您使用f1_score 来评估SelectKBest 返回的最佳k 有多好。但是对于选择 k 个最佳特征,您不能使用 f1-score,这基本上是一种评估模型执行情况的衡量标准。你需要chi2、f_classif 或mutual_info_classif 之类的东西来执行此操作。我还稍微修正了代码。
    • 您好 ABB,如果您认为此答案帮助您解决了问题,我恳请您接受它的答案,因为如果其他人也遇到类似问题,这将帮助其他人找到正确的答案。提前致谢!更多详情请参考stackoverflow.com/help/someone-answers
    猜你喜欢
    • 1970-01-01
    • 2015-03-25
    • 2020-08-21
    • 2018-10-02
    • 2018-01-06
    • 2018-11-23
    • 2015-06-11
    • 2020-07-13
    • 2019-09-06
    相关资源
    最近更新 更多