Keras中自定义加权F1-Score出现NaN值问题
针对不平衡二分类的加权F1-Score实现方案
我明白你想通过加权F1-score来重点惩罚对少数类的错误分类,刚好可以帮你把缺失的部分补全,并且实现符合需求的加权指标:
1. 补全基础指标函数
先把你没写完的特异度函数补好,同时补上精确率函数——这两个是计算F1的核心基础:
import tensorflow.keras.backend as K def sensitivity(y_true, y_pred): true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1))) possible_positives = K.sum(K.round(K.clip(y_true, 0, 1))) return true_positives / (possible_positives + K.epsilon()) def specificity(y_true, y_pred): true_negatives = K.sum(K.round(K.clip((1 - y_true) * (1 - y_pred), 0, 1))) possible_negatives = K.sum(K.round(K.clip(1 - y_true, 0, 1))) return true_negatives / (possible_negatives + K.epsilon()) def precision(y_true, y_pred): true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1))) predicted_positives = K.sum(K.round(K.clip(y_pred, 0, 1))) return true_positives / (predicted_positives + K.epsilon())
2. 实现加权F1-Score函数
核心思路是给少数类(假设是y_true=1的正类)设置更高权重,你可以手动指定权重,也可以根据数据集占比动态计算:
手动指定权重版本
适合你已经提前知道少数类占比的情况,比如少数类占10%,可以把权重设为9(和占比成反比):
def weighted_f1_score(y_true, y_pred, minority_weight=2.0): prec = precision(y_true, y_pred) rec = sensitivity(y_true, y_pred) # 加权F1公式:( (w1 + w2)*prec*rec ) / (w1*prec + w2*rec ) # w1是少数类权重,w2设为1(多数类权重) w1 = minority_weight w2 = 1.0 return ( (w1 + w2) * prec * rec ) / (w1 * prec + w2 * rec + K.epsilon())
动态计算权重版本
不用提前统计,函数内部自动根据当前batch的正类占比生成权重:
def dynamic_weighted_f1(y_true, y_pred): # 计算当前batch中正类的数量和占比 pos_count = K.sum(K.round(K.clip(y_true, 0, 1))) total_count = K.cast(K.shape(y_true)[0], K.floatx()) minority_ratio = pos_count / total_count # 避免除以0,当batch中没有正类时权重设为1 minority_weight = K.switch(minority_ratio == 0, 1.0, 1 / minority_ratio) w2 = 1.0 prec = precision(y_true, y_pred) rec = sensitivity(y_true, y_pred) return ( (minority_weight + w2) * prec * rec ) / (minority_weight * prec + w2 * rec + K.epsilon())
3. 使用方法
在Keras模型编译时,直接把这个指标函数传入即可:
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=[dynamic_weighted_f1])
这个方案会让模型更关注少数类的分类结果,有效惩罚对它的错误判断,解决不平衡数据集下普通F1-score失效的问题。
内容的提问来源于stack exchange,提问作者Guido
相关产品推荐
相关产品推荐

