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

Java信息增益计算程序输入0时出现NaN值问题求助

解决信息增益计算中pi/ni为0时出现NaN的问题

我一眼就看出问题出在哪了——当pi或者ni为0的时候,你的熵计算逻辑会触发Math.log(0),而这个方法返回的是Double.NEGATIVE_INFINITY,当你用0去乘这个负无穷的时候,结果就变成了NaN(非数字),但从数学定义来说,0 * log₂(0)的极限值是0,所以我们需要手动处理这个边界情况。

解决方案:添加一个辅助方法处理熵计算

我们可以写一个专门的方法来计算单个属性的熵,在方法里判断p或n是否为0,直接返回对应的项为0,避免出现无效的对数计算。

修改后的完整代码如下:

package dwdmp5;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Dwdmp5 {
    // 辅助方法:计算给定p和n的熵
    private static double calculateEntropy(double p, double n) {
        double total = p + n;
        if (total == 0) {
            return 0.0; // 理论上不会出现,因为属性的样本数不可能为0
        }
        double pRatio = p / total;
        double nRatio = n / total;
        
        double pTerm = 0.0;
        if (pRatio > 0) { // 只有当p>0时才计算这一项
            pTerm = -pRatio * (Math.log(pRatio) / Math.log(2));
        }
        
        double nTerm = 0.0;
        if (nRatio > 0) { // 只有当n>0时才计算这一项
            nTerm = -nRatio * (Math.log(nRatio) / Math.log(2));
        }
        
        return pTerm + nTerm;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        double P,N,IGtotal;
        System.out.println("How many total P values?");
        P = Double.parseDouble(br.readLine());
        System.out.println("How many total N values?");
        N = Double.parseDouble(br.readLine());
        
        // 用辅助方法计算整体熵
        IGtotal = calculateEntropy(P, N);
        System.out.println("Overall Information gain = "+IGtotal);
        
        int numV;
        System.out.println("How many distinct values of an attribute?");
        numV = Integer.parseInt(br.readLine());
        double [] p = new double[numV];
        double [] n = new double[numV];
        double [] ig = new double[numV];
        
        System.out.println("Enter pi for all attributes");
        for(int i=0;i<numV;i++)
            p[i] = Integer.parseInt(br.readLine());
        System.out.println("Enter ni for all attributes");
        for(int i=0;i<numV;i++)
            n[i] = Integer.parseInt(br.readLine());
        
        System.out.println("Attribute\tpi\tni\tI(pi,ni)");
        for(int i=0;i<numV;i++)
        {
            // 调用辅助方法计算每个属性的熵
            ig[i] = calculateEntropy(p[i], n[i]);
            System.out.println("attrib"+(i+1)+"\t\t"+p[i]+"\t\t"+n[i]+"\t\t"+ig[i]);
        }
    }
}

测试你的输入

用你提供的测试数据运行修改后的代码:

  • 总P=9,总N=5
  • 属性数量3,pi分别为2、4、3;ni分别为3、0、2

输出会变成:

How many total P values? 9
How many total N values? 5
Overall Information gain = 0.9402859586706309
How many distinct values of an attribute? 3
Enter pi for all attributes
2
4
3
Enter ni for all attributes
3
0
2
Attribute	pi	ni	I(pi,ni)
attrib1		2.0		3.0		0.9709505944546686
attrib2		4.0		0.0		0.0
attrib3		3.0		2.0		0.9709505944546686

这就符合我们的数学预期了——当ni=0时,该属性的熵为0,因为所有样本都是正例,没有不确定性。

额外优化提示

  1. 你可以把整体信息增益的计算也用这个辅助方法,代码更简洁一致
  2. 输入的时候可以加入一些合法性检查,比如不能输入负数,避免后续计算出问题

内容的提问来源于stack exchange,提问作者Gaurav Gilalkar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:21:38