java实现Fisher的LSD方法

场景

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

maven依赖

	<!-- https://mvnrepository.com/artifact/net.sf.jsci/jsci -->
		<dependency>
			<groupId>net.sf.jsci</groupId>
			<artifactId>jsci</artifactId>
			<version>1.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-math3 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-math3</artifactId>
			<version>3.6.1</version>
		</dependency>

	</dependencies>

用法

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;

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。在这种情形下,有实际经验的专业人员将会寻找其他方法,以更好地控制犯实验方式第一类错误的概率。

参考

《商务与经济统计》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值