MixtureDistribution.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 7k
Category:

Windows Develop

Development Platform:

Java

  1. /*
  2.  *    This program is free software; you can redistribute it and/or modify
  3.  *    it under the terms of the GNU General Public License as published by
  4.  *    the Free Software Foundation; either version 2 of the License, or (at
  5.  *    your option) any later version.
  6.  *
  7.  *    This program is distributed in the hope that it will be useful, but
  8.  *    WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  10.  *    General Public License for more details.
  11.  *
  12.  *    You should have received a copy of the GNU General Public License
  13.  *    along with this program; if not, write to the Free Software
  14.  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  15. /*
  16.  *    MixtureDistribution.java
  17.  *    Copyright (C) 2002 Yong Wang
  18.  *
  19.  */
  20. package weka.classifiers.functions.pace;
  21. import java.util.Random;
  22. import weka.core.Statistics;
  23. /**
  24.  * Abtract class for manipulating mixture distributions. <p>
  25.  *
  26.  * REFERENCES <p>
  27.  * 
  28.  * Wang, Y. (2000). "A new approach to fitting linear models in high
  29.  * dimensional spaces." PhD Thesis. Department of Computer Science,
  30.  * University of Waikato, New Zealand. <p>
  31.  * 
  32.  * Wang, Y. and Witten, I. H. (2002). "Modeling for optimal probability
  33.  * prediction." Proceedings of ICML'2002. Sydney. <p>
  34.  *
  35.  * @author Yong Wang (yongwang@cs.waikato.ac.nz)
  36.  * @version $Revision: 1.1 $ */
  37. public abstract class  MixtureDistribution 
  38. {
  39.   protected DiscreteFunction mixingDistribution;
  40.   /** The nonnegative-measure-based method */
  41.   public static final int NNMMethod = 1; 
  42.     
  43.   /** The probability-measure-based method */
  44.   public static final int PMMethod = 2;
  45.   // The CDF-based method
  46.   // public static final int CDFMethod = 3;
  47.     
  48.   // The method based on the Kolmogrov and von Mises measure
  49.   // public static final int ModifiedCDFMethod = 4; 
  50.     
  51.   /** Gets the mixing distribution
  52.    */
  53.   public DiscreteFunction getMixingDistribution() 
  54.   {
  55.     return mixingDistribution;
  56.   }
  57.   /** Sets the mixing distribution
  58.    *  @param d the mixing distribution
  59.    */
  60.   public void  setMixingDistribution( DiscreteFunction d ) 
  61.   {
  62.     mixingDistribution = d;
  63.   }
  64.   /** Fits the mixture (or mixing) distribution to the data. The default
  65.    *  method is the nonnegative-measure-based method.
  66.    * @param data the data, supposedly generated from the mixture model */
  67.   public void fit( DoubleVector data ) 
  68.   {
  69.     fit( data, NNMMethod );
  70.   }
  71.   /** Fits the mixture (or mixing) distribution to the data.
  72.    *  @param data the data supposedly generated from the mixture 
  73.    *  @param method the method to be used. Refer to the static final
  74.    *  variables of this class. */
  75.   public void fit( DoubleVector data, int method ) 
  76.   {
  77.     DoubleVector data2 = (DoubleVector) data.clone();
  78.     if( data2.unsorted() ) data2.sort();
  79.     int n = data2.size();
  80.     int start = 0;
  81.     DoubleVector subset;
  82.     DiscreteFunction d = new DiscreteFunction();
  83.     for( int i = 0; i < n-1; i++ ) {
  84.       if( separable( data2, start, i, data2.get(i+1) ) &&
  85.   separable( data2, i+1, n-1, data2.get(i) ) ) {
  86. subset = (DoubleVector) data2.subvector( start, i );
  87. d.plusEquals( fitForSingleCluster( subset, method ).
  88.       timesEquals(i - start + 1) );
  89. start = i + 1;
  90.       }
  91.     }
  92.     subset = (DoubleVector) data2.subvector( start, n-1 );
  93.     d.plusEquals( fitForSingleCluster( subset, method ).
  94.   timesEquals(n - start) ); 
  95.     d.sort();
  96.     d.normalize();
  97.     mixingDistribution = d;
  98.   }
  99.     
  100.   /** Fits the mixture (or mixing) distribution to the data. The data is
  101.    *  not pre-clustered for computational efficiency.
  102.    *  @param data the data supposedly generated from the mixture 
  103.    *  @param method the method to be used. Refer to the static final
  104.    *  variables of this class. */
  105.   public DiscreteFunction fitForSingleCluster( DoubleVector data, 
  106.        int method )
  107.   {
  108.     if( data.size() < 2 ) return new DiscreteFunction( data );
  109.     DoubleVector sp = supportPoints( data, 0 );
  110.     PaceMatrix fi = fittingIntervals( data );
  111.     PaceMatrix pm = probabilityMatrix( sp, fi );
  112.     PaceMatrix epm = new 
  113.       PaceMatrix( empiricalProbability( data, fi ).
  114.   timesEquals( 1. / data.size() ) );
  115.     
  116.     IntVector pvt = (IntVector) IntVector.seq(0, sp.size()-1);
  117.     DoubleVector weights;
  118.     
  119.     switch( method ) {
  120.     case NNMMethod: 
  121.       weights = pm.nnls( epm, pvt );
  122.       break;
  123.     case PMMethod:
  124.       weights = pm.nnlse1( epm, pvt );
  125.       break;
  126.     default: 
  127.       throw new IllegalArgumentException("unknown method");
  128.     }
  129.     
  130.     DoubleVector sp2 = new DoubleVector( pvt.size() );
  131.     for( int i = 0; i < sp2.size(); i++ ){
  132.       sp2.set( i, sp.get(pvt.get(i)) );
  133.     }
  134.     
  135.     DiscreteFunction d = new DiscreteFunction( sp2, weights );
  136.     d.sort();
  137.     d.normalize();
  138.     return d;
  139.   }
  140.     
  141.   /** Return true if a value can be considered for mixture estimatino
  142.    *  separately from the data indexed between i0 and i1 
  143.    *  @param data the data supposedly generated from the mixture 
  144.    *  @param i0 the index of the first element in the group
  145.    *  @param i1 the index of the last element in the group
  146.    *  @param x the value
  147.    */
  148.   public abstract boolean separable( DoubleVector data, 
  149.      int i0, int i1, double x );
  150.     
  151.   /** Contructs the set of support points for mixture estimation.
  152.    *  @param data the data supposedly generated from the mixture 
  153.    *  @param ne the number of extra data that are suppposedly discarded
  154.    *  earlier and not passed into here */
  155.   public abstract DoubleVector  supportPoints( DoubleVector data, int ne );
  156.     
  157.   /** Contructs the set of fitting intervals for mixture estimation.
  158.    *  @param data the data supposedly generated from the mixture 
  159.    */
  160.   public abstract PaceMatrix  fittingIntervals( DoubleVector data );
  161.   
  162.   /** Contructs the probability matrix for mixture estimation, given a set
  163.    *  of support points and a set of intervals.
  164.    *  @param s  the set of support points
  165.    *  @param intervals the intervals */
  166.   public abstract PaceMatrix  probabilityMatrix( DoubleVector s, 
  167.  PaceMatrix intervals );
  168.     
  169.   /** Computes the empirical probabilities of the data over a set of
  170.    *  intervals.
  171.    *  @param data the data
  172.    *  @param intervals the intervals 
  173.    */
  174.   public PaceMatrix  empiricalProbability( DoubleVector data, 
  175.    PaceMatrix intervals )
  176.   {
  177.     int n = data.size();
  178.     int k = intervals.getRowDimension();
  179.     PaceMatrix epm = new PaceMatrix( k, 1, 0 );
  180.     
  181.     double point;
  182.     for( int j = 0; j < n; j ++ ) {
  183.       for(int i = 0; i < k; i++ ) {
  184. point = 0.0;
  185. if( intervals.get(i, 0) == data.get(j) || 
  186.     intervals.get(i, 1) == data.get(j) ) point = 0.5;
  187. else if( intervals.get(i, 0) < data.get(j) && 
  188.  intervals.get(i, 1) > data.get(j) ) point = 1.0;
  189. epm.setPlus( i, 0, point);
  190.       }
  191.     }
  192.     return epm;
  193.   }
  194.   
  195.   /** Converts to a string
  196.    */
  197.   public String  toString() 
  198.   {
  199.     return "The mixing distribution:n" + mixingDistribution.toString();
  200.   }
  201.     
  202. }