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,因为所有样本都是正例,没有不确定性。
额外优化提示
- 你可以把整体信息增益的计算也用这个辅助方法,代码更简洁一致
- 输入的时候可以加入一些合法性检查,比如不能输入负数,避免后续计算出问题
内容的提问来源于stack exchange,提问作者Gaurav Gilalkar
相关产品推荐
相关产品推荐

