java中用于图范围内社区检测的规范化互信息植入不在0和1之间

java中用于图范围内社区检测的规范化互信息植入不在0和1之间,java,machine-learning,bayesian,information-theory,Java,Machine Learning,Bayesian,Information Theory,我编写了一个计算归一化互信息的程序,用于评估社区检测。但是对于nmi,我得到的值大于1。通常它应该在0和1之间。我在计算机中实现这个公式 我的代码有什么问题 这是我的密码: public void calNmi(int size, Map<Integer, List<Integer>> realcom, Map<Integer, List<Integer>> foundcom){ List<Double> hf = n

我编写了一个计算归一化互信息的程序,用于评估社区检测。但是对于nmi,我得到的值大于1。通常它应该在0和1之间。我在计算机中实现这个公式

我的代码有什么问题

这是我的密码:

    public void calNmi(int size, Map<Integer, List<Integer>> realcom, Map<Integer, List<Integer>> foundcom){

    List<Double> hf = new ArrayList<>();
    List<Double> hr = new ArrayList<>();
    double I = 0;

    for (Map.Entry<Integer, List<Integer>> found : foundcom.entrySet()) {
        int comSize = found.getValue().size();
        double p = (double) comSize/size;
        hf.add( -p * (Math.log(p)/Math.log(2)));
     }


    for (Map.Entry<Integer, List<Integer>> real : realcom.entrySet()) {
        int comSize = real.getValue().size();
        double p = (double) comSize/size;
        hr.add(-p * (Math.log(p)/Math.log(2)));
    }

    int i =0;
    for (Map.Entry<Integer, List<Integer>> real : realcom.entrySet()) {
        if(i%100 == 0){
            System.out.println(i);
        }
        List<Integer> rCom = real.getValue();
        double pr = (double) rCom.size()/size;
        for (Map.Entry<Integer, List<Integer>> found : foundcom.entrySet()) {
            List<Integer> fCom = found.getValue();
            double pf = (double) fCom.size()/size;
            int intersect = foundIntersect(rCom, fCom);
            if(intersect != 0) {
                double p = (double) intersect / size;
                I += p * (Math.log(p / (pr * pf))) / Math.log(2);
            }
        }
        i++;
    }
    double sumH  = 0;
    for (Double sumh : hr) {
        sumH += sumh;
    }
    double sumF = 0;
    for (Double sumf : hf) {
        sumF += sumf;
    }
    System.out.println("I = " + I + " hf = "+ sumF + " hr " + sumH);
    double nmi = (2 * I)/(sumF + sumH);
    System.out.println("nmi = " + nmi);

}

private int foundIntersect(List<Integer> rCom, List<Integer> fCom) {
    int count = 0;
    for (Integer r : rCom) {
        if(fCom.contains(r)) {
            count++;
        }
    }
    return count;
}
public void calNmi(整数大小、Map realcom、Map foundcom){
List hf=new ArrayList();
List hr=new ArrayList();
双I=0;
对于(找到Map.Entry:foundcom.entrySet()){
int comSize=found.getValue().size();
双p=(双)comSize/size;
hf.add(-p*(Math.log(p)/Math.log(2));
}
对于(Map.Entry real:realcom.entrySet()){
int comSize=real.getValue().size();
双p=(双)comSize/size;
人力资源添加(-p*(Math.log(p)/Math.log(2));
}
int i=0;
对于(Map.Entry real:realcom.entrySet()){
如果(i%100==0){
系统输出打印LN(i);
}
List rCom=real.getValue();
double pr=(double)rCom.size()/size;
对于(找到Map.Entry:foundcom.entrySet()){
List fCom=found.getValue();
double pf=(double)fCom.size()/size;
int intersect=FOUNDCERSECT(rCom,fCom);
如果(相交!=0){
双p=(双)相交/大小;
I+=p*(数学日志(p/(pr*pf)))/Math.log(2);
}
}
i++;
}
双sumH=0;
用于(双sumh:hr){
sumH+=sumH;
}
双集水坑=0;
用于(双集水坑:hf){
sumF+=sumF;
}
System.out.println(“I=“+I+”hf=“+sumF+”hr“+sumH”);
双nmi=(2*I)/(sumF+sumH);
System.out.println(“nmi=“+nmi”);
}
专用int foundIntersect(列表rCom、列表fCom){
整数计数=0;
for(整数r:rCom){
如果(fCom.contains(r)){
计数++;
}
}
返回计数;
}

我在代码中看到了一些不一致的想法,但要知道哪一个是问题所在,哪一个是您想要的,我需要更多的信息。具体来说,请更新您的问题,告诉我realcom和foundcom实际上代表了什么。从您的代码来看,它们可能是表示要比较的离散化信号的列表映射,但您的代码在某些地方是错误的,在其他地方是正确的。或者,它们可以是数据集的柱状图,但我不希望列表嵌入到地图中。我在代码中看到一些不一致的想法,但要知道哪一个是问题所在,哪一个是您想要的,我需要更多的信息。具体来说,请更新您的问题,告诉我realcom和foundcom实际上代表了什么。从您的代码来看,它们可能是表示要比较的离散化信号的列表映射,但您的代码在某些地方是错误的,在其他地方是正确的。或者,它们可以是数据集的直方图,但我不希望列表嵌入到地图中。