Java 计算信息增益时显示NaN作为输出的双变量数组
我一直在尝试用Java编写一个程序来计算属性的信息增益,给定它的不同值和所有其他必需值。 下面是我的节目Java 计算信息增益时显示NaN作为输出的双变量数组,java,Java,我一直在尝试用Java编写一个程序来计算属性的信息增益,给定它的不同值和所有其他必需值。 下面是我的节目 package dwdmp5; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * * @author Gaurav */ public class Dwdmp5 { /** * @param args the com
package dwdmp5;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
*
* @author Gaurav
*/
public class Dwdmp5 {
/**
* @param args the command line arguments
*/
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 = ((-1)*(P/(P+N))*((Math.log(P/(P+N)))/Math.log(2))) + ((-1)*(N/(P+N))*((Math.log(N/(P+N)))/Math.log(2)));
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];
int i,temp=0;
System.out.println("Enter pi for all attributes");
for(i=0;i<numV;i++)
p[i] = Integer.parseInt(br.readLine());
System.out.println("Enter ni for all attributes");
for(i=0;i<numV;i++)
n[i] = Integer.parseInt(br.readLine());
System.out.println("Attribute\tpi\tni\tI(pi,ni)");
for(i=0;i<numV;i++)
{ temp = i;
ig[i] = ((-1)*(p[i]/(p[i]+n[i]))*((Math.log(p[i]/(p[i]+n[i])))/Math.log(2))) + ((-1)*(n[i]/(p[i]+n[i]))*((Math.log(n[i]/(p[i]+n[i])))/Math.log(2)));
System.out.println("attrib"+(temp+1)+"\t\t"+p[i]+"\t\t"+n[i]+"\t\t"+ig[i]);
}
}
}
程序没有显示任何错误。使用科学计算器计算时,相同的值显示正确答案。请帮我解决这个问题 (Java语言规范)规定:
没有数学上确定结果的浮点运算产生NaN
所有以NaN作为操作数的数值运算都会产生NaN作为结果
现在,当您在上阅读JavaDoc时
您将看到:
如果参数为正零或负零,则结果为负无穷大
如果你看一下你的计算,你会发现对于p=4和n=0,你会得到0.0*Math.log(0.0/(4.0+0.0))
=>0.0*Math.log(0.0)
=>0.0*-无穷大
=>NaN
根据JLS定义的规则,接下来的计算将产生NaN
为什么0.0*-无限
不等于0?请看这里:(Java语言规范)说明:
没有数学上确定结果的浮点运算产生NaN
所有以NaN作为操作数的数值运算都会产生NaN作为结果
现在,当您在上阅读JavaDoc时
您将看到:
如果参数为正零或负零,则结果为负无穷大
如果你看一下你的计算,你会发现对于p=4和n=0,你会得到0.0*Math.log(0.0/(4.0+0.0))
=>0.0*Math.log(0.0)
=>0.0*-无穷大
=>NaN
根据JLS定义的规则,接下来的计算将产生NaN
为什么
0.0*-无限
不等于0?请看这里:该计算有点复杂,因此我没有彻底检查它(这将是您的工作),但由于您的输入值为4.0和0.0,我猜您在某个点进行了0除法,这将导致NaN(不是数字)。使用调试器查找哪个子表达式导致NaN。任何使用NaN作为操作数的操作都会产生NaN。您的代码有点凌乱,一些空格也可以,但NaN可以被例如除零或类似的情况。刚刚测试了您的计算,似乎您得到了以下情况:Math.log(n[i]/(p[i]+n[i]))
将有效地导致-无穷大
,因为0.0/4.0
将是0
,因此Math.log(0)
将是负无穷大。现在,您的计算将执行-Infinity*0.0
,这将导致NaN
。在该迭代中,您将得到一个Math.sqrt(0),从而产生NaN。这不会引发异常。该计算有点复杂,因此我没有彻底检查它(这将是您的工作),但由于您的输入值为4.0和0.0,我猜您在某个点进行了0除法,这将导致NaN(不是数字)。使用调试器查找哪个子表达式导致NaN。任何使用NaN作为操作数的操作都会产生NaN。您的代码有点凌乱,一些空格也可以,但NaN可以被例如除零或类似的情况。刚刚测试了您的计算,似乎您得到了以下情况:Math.log(n[i]/(p[i]+n[i]))
将有效地导致-无穷大
,因为0.0/4.0
将是0
,因此Math.log(0)
将是负无穷大。现在,您的计算将执行-Infinity*0.0
,这将导致NaN
。在该迭代中,您将得到一个Math.sqrt(0),从而产生NaN。这不会引发异常。非常感谢。哥特查塔克人很多。明白了
run:
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 NaN
attrib3 3.0 2.0 0.9709505944546686
BUILD SUCCESSFUL (total time: 17 seconds)