具有交叉验证的神经网络模型的多个指标

Posted

技术标签:

【中文标题】具有交叉验证的神经网络模型的多个指标【英文标题】:Multiple metrics for neural network model with cross validation 【发布时间】:2019-12-05 11:11:23 【问题描述】:

我正在尝试为 LSTM 模型获得交叉验证的 F1、精度和召回率。

我知道如何显示准确度,但是当我尝试使用 cross_validate 显示其他指标时,我得到了许多不同的错误。

我的代码如下:

def nn_model():
    model_lstm1 = Sequential()
    model_lstm1.add(Embedding(20000, 100, input_length=49))
    model_lstm1.add(LSTM(100, dropout=0.2, recurrent_dropout=0.2))
    model_lstm1.add(Dense(2, activation='sigmoid'))
    model_lstm1.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model_lstm1

classifier = KerasClassifier(build_fn=nn_model, batch_size=10,nb_epoch=10)

scoring = 'precision' : make_scorer(precision_score),
           'recall' : make_scorer(recall_score), 
           'f1_score' : make_scorer(f1_score)

results = cross_validate(classifier, X_train, y_train, cv=skf, scoring = scoring)

print("F1 score SVM: %0.2f (+/- %0.2f)" % (np.mean(results[f1_score]), np.std(results[f1_score])))

print("precision score SVM: %0.2f (+/- %0.2f)" % (np.mean(results[precision]), np.std(results[precision])))
print("recall macro SVM: %0.2f (+/- %0.2f)" % (np.mean(results[recall]), np.std(results[recall])))

我得到的错误如下:

Epoch 1/1 1086/1086 [==============================] - 18s 17ms/step - 损失:0.6014 - 累积:0.7035 -------------------------------------------------- ------------------------- ValueError Traceback(最近一次调用 最后)在 6'f1_score':make_scorer(f1_score) 7 ----> 8 个结果 = cross_validate(分类器,X_train,y_train,cv=skf,评分 = 评分) 9 10 print("F1 score SVM: %0.2f (+/- %0.2f)" % (np.mean(results[f1_score]), np.std(results[f1_score])))

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/model_selection/_validation.py in cross_validate(estimator, X, y, groups, score, cv, n_jobs, 详细,fit_params,pre_dispatch,return_train_score, return_estimator, error_score) 第229章 230 错误分数=错误分数) --> 231 用于训练,在 cv.split(X, y, groups)) 中测试 232 233 zipped_scores = list(zip(*scores))

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/joblib/parallel.py 在调用(自我,可迭代) 919 # 个剩余工作。 第920章 --> 921 if self.dispatch_one_batch(iterator): 第922章 第923章

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/joblib/parallel.py 在 dispatch_one_batch(self, iterator) 757返回假 758 其他: --> 759 self._dispatch(任务) 760 返回真 第761章

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/joblib/parallel.py 在_dispatch(自我,批处理) 带有self._lock的714: 第715章 --> 716 作业 = self._backend.apply_async(batch, callback=cb) 717 # 一个作业完成的速度比它的回调快 718 # 在我们到达之前调用,导致 self._jobs

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/joblib/_parallel_backends.py 在 apply_async(self, func, 回调) 180 def apply_async(自我,功能,回调=无): 181 """安排一个函数运行""" --> 182 结果 = 立即结果(函数) 183 如果回调: 184回调(结果)

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/joblib/_parallel_backends.py 在 init(自我,批处理)中 547 # 不要延迟应用,避免保持输入 第548章 --> 549 self.results = batch() 550 第551章

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/joblib/parallel.py 在通话(自己) 223 与并行后端(self._backend,n_jobs=self._n_jobs): 224 返回 [func(*args, **kwargs) --> 225 用于 self.items 中的 func、args、kwargs] 226 227 def len(自我):

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/joblib/parallel.py 在 (.0) 223 与并行后端(self._backend,n_jobs=self._n_jobs): 224 返回 [func(*args, **kwargs) --> 225 用于 self.items 中的 func、args、kwargs] 226 227 def len(自我):

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/model_selection/_validation.py in _fit_and_score(estimator, X, y, scorer, train, test, verbose, 参数,fit_params,return_train_score,return_parameters, return_n_test_samples,return_times,return_estimator,error_score) 第552章 第553章 --> 554 test_scores = _score(estimator, X_test, y_test, scorer, is_multimetric) 555 score_time = time.time() - start_time - fit_time 556 if return_train_score:

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/model_selection/_validation.py in _score(estimator, X_test, y_test, scorer, is_multimetric) 第595章 596 如果 is_multimetric: --> 597 返回 _multimetric_score(估计器,X_test,y_test,记分器) 598 其他: 599 如果 y_test 为无:

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/model_selection/_validation.py 在_multimetric_score(估计器,X_test,y_test,记分器) 625 得分 = 得分手(估计器,X_test) 626 其他: --> 627 score = scorer(estimator, X_test, y_test) 628 第629章

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/metrics/scorer.py 在调用中(self、estimator、X、y_true、sample_weight) 95 其他: 96 返回 self._sign * self._score_func(y_true, y_pred, ---> 97 **self._kwargs) 98 99

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/metrics/classification.py 在precision_score(y_true,y_pred,标签,pos_label,平均值, 样品重量)1567 平均=平均,1568 warn_for=('精度',), -> 1569 sample_weight=sample_weight) 1570 返回 p 1571

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/metrics/classification.py 在precision_recall_fscore_support(y_true,y_pred,beta,标签, pos_label,平均值,warn_for,sample_weight)1413 提高 ValueError("beta 在 F-beta 分数中应该 >0") 1414 个标签 = _check_set_wise_labels(y_true, y_pred, 平均, 标签, -> 1415 pos_label) 1416 1417 # 计算tp_sum, pred_sum, true_sum ###

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/metrics/classification.py 在 _check_set_wise_labels(y_true, y_pred, 平均, 标签, pos_label) 第1237章 第1238章 -> 1239 y_type, y_true, y_pred = _check_targets(y_true, y_pred) 1240 present_labels = unique_labels(y_true, y_pred) 1241 如果 平均 == '二进制':

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/sklearn/metrics/classification.py 在 _check_targets(y_true, y_pred) 79 如果 len(y_type) > 1: 80 raise ValueError("Classification metrics can't handle a mix of 0" ---> 81 "和 1 个目标".format(type_true, type_pred)) 82 83 # y_type 上的值不能超过一个 => 不再需要该集合

ValueError:分类指标无法处理混合 多标签指标和二元目标

我做错了什么?

【问题讨论】:

【参考方案1】:

代码中的问题

    您不能使用热一编码标签link。使用原始标签。您可以将sparse_categorical_crossentropy loss 与原始标签一起使用。 cross_validate 返回分数为test_scores。对于火车分数集return_train_score

更正的代码

def nn_model():
    model_lstm1 = Sequential()
    model_lstm1.add(Embedding(200, 100, input_length=10))
    model_lstm1.add(LSTM(10, dropout=0.2, recurrent_dropout=0.2))
    model_lstm1.add(Dense(2, activation='sigmoid'))
    model_lstm1.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
    return model_lstm1

classifier = KerasClassifier(build_fn=nn_model, batch_size=10,nb_epoch=10)

scoring = 'precision' : make_scorer(precision_score),
           'recall' : make_scorer(recall_score), 
           'f1_score' : make_scorer(f1_score)

results = cross_validate(classifier, np.random.randint(0,100,(1000,10)), 
                         np.random.np.random.randint(0,2,1000), scoring = scoring, cv=3, return_train_score=True)

print("F1 score SVM: %0.2f (+/- %0.2f)" % (np.mean(results['test_f1_score']), np.std(results['test_f1_score'])))
print("precision score SVM: %0.2f (+/- %0.2f)" % (np.mean(results['test_precision']), np.std(results['test_precision'])))
print("recall macro SVM: %0.2f (+/- %0.2f)" % (np.mean(results['test_recall']), np.std(results['test_recall'])))

输出

Epoch 1/1
666/666 [==============================] - 5s 7ms/step - loss: 0.6932 - acc: 0.5075
Epoch 1/1
667/667 [==============================] - 5s 7ms/step - loss: 0.6929 - acc: 0.5127
Epoch 1/1
667/667 [==============================] - 5s 7ms/step - loss: 0.6934 - acc: 0.5007
F1 score SVM: 0.10 (+/- 0.09)
precision score SVM: 0.43 (+/- 0.07)
recall macro SVM: 0.06 (+/- 0.06)

你可能会得到

UndefinedMetricWarning: ....

首字母时期的警告(如果数据低),您可以忽略。这是因为分类器将所有数据分类到一个类,而没有数据分类到另一个类。

【讨论】:

以上是关于具有交叉验证的神经网络模型的多个指标的主要内容,如果未能解决你的问题,请参考以下文章

Keras训练神经网络进行分类并进行交叉验证(Cross Validation)

为多模型寻找模型最优参数多模型交叉验证可视化指标计算多模型对比可视化(系数图误差图混淆矩阵校正曲线ROC曲线AUCAccuracy特异度灵敏度PPVNPV)结果数据保存

具有分层交叉验证的多个性能指标

R语言编写自定义K折交叉验证(k-fold crossValidation)函数使用使用bootstrap包中的crossval函数来交叉验证模型的R方指标验证模型的效能的可靠性和稳定性

R语言glmnet交叉验证选择(alphalambda)拟合最优elastic回归模型:弹性网络(elasticNet)模型选择最优的alpha值模型最优的lambda值,最终模型的拟合与评估

R语言︱机器学习模型评价指标+(转)模型出错的四大原因及如何纠错