You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:26:32