Java

java实现Fisher-LSD检验

2020-03-16  本文已影响0人  lazyM

描述

多重比较方法:在成对的总体均值之间进行统计比较。

Demo

package com.math.demo;

import com.math.statistics.FisherLSD;

public class FishLSDDemo {

    public static void main(String[] args) {
        FisherLSD fisher=new FisherLSD();
        double[] a= {58,64,55,66,67};
        double[] b= {58,69,71,64,68};
        double[] c= {48,57,59,47,49};
        fisher.addE("a", a);
        fisher.addE("b", b);
        fisher.addE("c", c);        
        System.out.println(fisher.getPValue("a", "b"));

    }

}

实现代码

package com.math.statistics;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.math3.stat.descriptive.moment.Mean;
import org.apache.commons.math3.stat.descriptive.moment.Variance;
import org.apache.commons.math3.stat.descriptive.summary.Sum;

import JSci.maths.statistics.TDistribution;
/***
 * @author miaoyibo
 *
 */
public class FisherLSD {

    Variance variance = new Variance();

    Mean meanUtil = new Mean();
    Sum sumUtil = new Sum();
    private Map<String, double[]> map = new HashMap<String, double[]>();

    public void addE(String key, double[] e) {
        map.put(key, e);
    }

    public double getMean(String key1, String key2) {
        double[] d1 = map.get(key1);
        double[] d2 = map.get(key2);
        return meanUtil.evaluate(d1) - meanUtil.evaluate(d2);
    }

    public int getSumNum() {
        int n = 0;
        for (Entry<String, double[]> e : map.entrySet()) {
            n = n + e.getValue().length;
        }

        return n;
    }

    public double getMSE() {
        double numerator = 0;
        for (Entry<String, double[]> e : map.entrySet()) {
            double v = variance.evaluate(e.getValue());
            numerator = numerator + (e.getValue().length - 1) * v;
        }
        double denominator = getSumNum() - map.keySet().size();
        return numerator / denominator;
    }

    public double getPValue(String key1, String key2) {
        double numerator = getMean(key1, key2);

        double mse = getMSE();

        double a = 1.0 / map.get(key1).length + 1.0 / map.get(key2).length;

        double denominator = Math.sqrt(mse * a);

        double t = numerator / denominator;
        int free = getSumNum() - map.keySet().size();
        TDistribution td = new TDistribution(free);
        double cumulative = td.cumulative(t);
        double p;
        if (t > 0) {
            p = (1 - cumulative) * 2;
        } else {
            p = cumulative * 2;
        }
        return p;
    }

}

后记

在进行三次成对的两两比较时,三次检验中至少有一次犯第一类错误的概率是多少?
三次检验都不犯第一类错误的概率为0.950.950.95=0.8574。因此,至少有一次犯第一类错误的概率为1-0.8574=0.1426。这样当我们用Fisher的LSD方法进行三次成对的两两比较时,对应的犯第一类错误的概率已经不是0.05,其实是0.1426。我们将这个错误概率称为总的或实验方式的第一类错误概率。
对于总体个数较多的问题,犯实验方式第一类错误的概率会变得比较大,例如对于有5个总体,,如果利用Fisher的LSD方法,需要进行10次两两的比较,则犯实验方式第一类错误的概率将是1-(1-0.05)^10=0.40。在这种情形下,有实际经验的专业人员将会寻找其他方法,以更好地控制犯实验方式第一类错误的概率。

参考

《商务与经济统计》

上一篇下一篇

猜你喜欢

热点阅读