gov.sandia.cognition.statistics.method.FisherSignConfidence Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gov-sandia-cognition-learning-core Show documentation
Show all versions of gov-sandia-cognition-learning-core Show documentation
Algorithms and components for machine learning and statistics.
The newest version!
/*
* File: FisherSignConfidence.java
* Authors: Kevin R. Dixon
* Company: Sandia National Laboratories
* Project: Cognitive Foundry
*
* Copyright August 19, 2007, Sandia Corporation. Under the terms of Contract
* DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
* or on behalf of the U.S. Government. Export of this program may require a
* license from the United States Government. See CopyrightHistory.txt for
* complete details.
*
*/
package gov.sandia.cognition.statistics.method;
import gov.sandia.cognition.annotation.PublicationReference;
import gov.sandia.cognition.annotation.PublicationType;
import gov.sandia.cognition.statistics.distribution.BinomialDistribution;
import gov.sandia.cognition.util.AbstractCloneableSerializable;
import java.util.Collection;
import java.util.Iterator;
/**
* This is an implementation of the Fisher Sign Test, which is a robust
* nonparameteric test to determine if two groups have a different mean.
* However, because the test has essentially no assumptions, it generates
* very loose confidence bounds.
* @author Kevin R. Dixon
* @since 2.0
*
*/
@ConfidenceTestAssumptions(
name="Fisher Sign Test",
alsoKnownAs="Sign Test",
description={
"Determines if there is a statistically significant between the means of two groups",
"A robust nonparameteric alternative to the paired Student's t-test."
},
assumptions={
"The data from each group is sampled independently of each other."
},
nullHypothesis="The means of the two groups is the same.",
dataPaired=true,
dataSameSize=true,
distribution=BinomialDistribution.CDF.class,
reference=@PublicationReference(
author="Eric W. Weisstein",
title="Fisher Sign Test",
type=PublicationType.WebPage,
year=2009,
url="http://mathworld.wolfram.com/FisherSignTest.html"
)
)
public class FisherSignConfidence
extends AbstractCloneableSerializable
implements NullHypothesisEvaluator>
{
/**
* Default Constructor
*/
public FisherSignConfidence()
{
}
@Override
public FisherSignConfidence.Statistic evaluateNullHypothesis(
Collection extends Number> data1,
Collection extends Number> data2)
{
if (data1.size() != data2.size())
{
throw new IllegalArgumentException(
"data1 and data2 must have same number of elements.");
}
int N = 0;
int b = 0;
Iterator extends Number> i1 = data1.iterator();
Iterator extends Number> i2 = data2.iterator();
while (i1.hasNext())
{
double v1 = i1.next().doubleValue();
double v2 = i2.next().doubleValue();
// N tells us how many samples aren't equal
if (v1 != v2)
{
N++;
}
// b tells me how many samples where data1 is bigger
if (v1 > v2)
{
b++;
}
}
return new FisherSignConfidence.Statistic(b, N);
}
/**
* Contains the parameters from the Sign Test null-hypothesis evaluation
*/
public static class Statistic
extends AbstractConfidenceStatistic
{
/**
* Number of samples where data1 was different than data2
*/
private int numDifferent;
/**
* Number of sample where data1 was greater than data2
*/
private int numPositiveSign;
/**
* Creates a new instance of Statistic
*
* @param numPositiveSign Number of samples where data1 was greater than data2
* @param numDifferent Number of samples where data1 was different than data2
*/
public Statistic(
int numPositiveSign,
int numDifferent)
{
// Insignificant chance is a binomial with p=0.5, so the pvalue of
// Sign Test is the chance of seeing "b" times where data1 is bigger
// out of N different samples, where chance is 0.5. Thus, we have
// cdf(b,N,0.5) as the chance of seeing more than chance
super(2.0 * Math.min(
BinomialDistribution.CDF.evaluate(numDifferent, numPositiveSign, 0.5),
1.0 - BinomialDistribution.CDF.evaluate(numDifferent, numPositiveSign, 0.5)));
if (numPositiveSign > numDifferent)
{
throw new IllegalArgumentException(
"numPositiveSign must be <= numDifferent");
}
this.setNumPositiveSign(numPositiveSign);
this.setNumDifferent(numDifferent);
}
/**
* Getter for numDifferent
* @return
* Number of samples where data1 was different than data2
*/
public int getNumDifferent()
{
return this.numDifferent;
}
/**
* Setter for numDifferent
* @param numDifferent
* Number of samples where data1 was different than data2
*/
protected void setNumDifferent(
int numDifferent)
{
this.numDifferent = numDifferent;
}
/**
* Getter for numPositiveSign
* @return
* Number of sample where data1 was greater than data2
*/
public int getNumPositiveSign()
{
return this.numPositiveSign;
}
/**
* Setter for numPositiveSign
* @param numPositiveSign
* Number of sample where data1 was greater than data2
*/
protected void setNumPositiveSign(
int numPositiveSign)
{
this.numPositiveSign = numPositiveSign;
}
@Override
public double getTestStatistic()
{
return this.numPositiveSign;
}
}
}