Repository /Rseslib/rseslib-3.0.2.jar:rseslib.structure.function.doubleval.Radial


Back

No file description

Source code

/*
 * $RCSfile: Radial.java,v $
 * $Revision: 1.12 $
 * $Date: 2007/06/30 17:30:33 $
 * $Author: wojna $
 * 
 * Copyright (C) 2002 - 2007 Logic Group, Institute of Mathematics, Warsaw University
 * 
 *  This file is part of Rseslib.
 *
 *  Rseslib is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Rseslib is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


package rseslib.structure.function.doubleval;

import java.util.Random;

import rseslib.structure.data.DoubleData;
import rseslib.structure.data.DoubleDataWithDecision;
import rseslib.structure.table.DoubleDataTable;

/**
 * Euclidean distance between the vector of function values
 * for a given data object and a fixed centre.
 */
public class Radial implements DoubleFunction
{
    /** Energy value obtained in the previous training step. */
    private static double prevEnergy = 0;

     /** Array of functions. */
    DoubleFunction[] m_arrComponents;
   /** Coordinates of the centre of this radial function. */
    double[] m_nCentre;

    /**
     * Constructor.
     *
     * @param components Array of functions.
     * @param centre     Coordinates of the centre of this radial function
     */
    public Radial(DoubleFunction[] components, double[] centre)
    {
        m_arrComponents = components;
        m_nCentre = centre;
    }

    /**
     * Returns the value of this function for a given double data.
     *
     * @param dObj Double data to be evaluated.
     * @return     Value of this function for a given double data.
     */
    public double doubleVal(DoubleData dObj)
    {
        double d = 0;
        for (int i = 0; i < m_arrComponents.length; i++)
            d += (m_nCentre[i] - m_arrComponents[i].doubleVal(dObj))*(m_nCentre[i] - m_arrComponents[i].doubleVal(dObj));
        return Math.sqrt(d);
    }

    /**
     * Returns an array of numeric attributes as the array of functions.
     *
     * @param size Number of attributes.
     * @return     Array of numeric attributes.
     */
    public static DoubleFunction[] initAttributes(int size)
    {
        DoubleFunction[] nf = new DoubleFunction[size];
        for (int i = 0; i < nf.length; i++) nf[i] = new AttributeValue(i);
        return nf;
    }

    /**
     * Constructs a radial function
     * with the mean of a given decision class
     * from a training table as the centre.
     *
     * @param tab Training table.
     * @param dec Decision class providing the mean.
     * @return    Constructed radial function.
     */
    public static Radial mean(DoubleDataTable tab, int dec)
    {
        DoubleFunction[] attributes = null;
        double[] coefficients = null;
        for (DoubleData dObj : tab.getDataObjects())
        {
            if (((DoubleDataWithDecision)dObj).getDecision() == dec)
            {
                if (attributes == null)
                {
                    attributes = initAttributes(dObj.attributes().noOfAttr());
                    if (coefficients == null)
                    {
                        coefficients = new double[dObj.attributes().noOfAttr()];
                        for (int i = 0; i < coefficients.length; i++)
                            coefficients[i] = dObj.get(i);
                    }
                }
                for (int i = 0; i < coefficients.length; i++) coefficients[i] += dObj.get(i);
            }
        }
        for (int i = 0; i < coefficients.length; i++) coefficients[i] /= tab.noOfObjects();
        return new Radial(attributes, coefficients);
    }

    /**
     * Constructs k radial function
     * using the algorithm of k-means.
     * The algorithm stops when the difference in energy
     * between the last and the last but one step
     * is less than 1.
     *
     * @param tab         Training table.
     * @param dec         Decision class used to generate k means.
     * @param noOfCenters Number of means in the algorithm.
     * @return            Array of constructed radial functions.
     */
    public static Radial[] kMeans(DoubleDataTable tab, double dec, int noOfCenters)
    {
        Random rnd = new Random();
        double[] min = null;
        double[] max = null;
        for (DoubleData dObj : tab.getDataObjects())
        {
            if (min==null)
            {
                min = new double[dObj.attributes().noOfAttr()];
                for (int i = 0; i < min.length; i++) min[i] = dObj.get(i);
            }
            if (max==null)
            {
                max = new double[dObj.attributes().noOfAttr()];
                for (int i = 0; i < max.length; i++) max[i] = dObj.get(i);
            }
            for (int i = 0; i < min.length; i++)
                if (dObj.get(i) < min[i]) min[i] = dObj.get(i);
            for (int i = 0; i < max.length; i++)
                if (dObj.get(i) > max[i]) max[i] = dObj.get(i);
        }
        DoubleFunction[] attributes = null;
        double[][] coefficients = null;
        double[][] sum = null;
        double oldEnergy = 0;
        double energy = -100;
        while (energy - oldEnergy > 1 || energy - oldEnergy < -1)
        {
            if (sum!=null)
                for (int c = 0; c < sum.length; c++)
                    for (int i = 0; i < sum[c].length; i++) sum[c][i] = 0;
            oldEnergy = energy;
            energy = 0;
            int number = 0;
            for (DoubleData dObj : tab.getDataObjects())
            {
                if (attributes == null)
                {
                    attributes = initAttributes(dObj.attributes().noOfAttr());
                    if (coefficients == null)
                    {
                        coefficients = new double[noOfCenters][];
                        for (int c = 0; c < coefficients.length; c++)
                        {
                            coefficients[c] = new double[dObj.attributes().noOfAttr()];
                            for (int i = 0; i < coefficients[c].length; i++)
                                coefficients[c][i] = min[i] + rnd.nextDouble()*(max[i] - min[i]);
                        }
                    }
                    if (sum == null)
                    {
                        sum = new double[noOfCenters][];
                        for (int c = 0; c < sum.length; c++)
                        {
                            sum[c] = new double[dObj.attributes().noOfAttr()];
                            for (int i = 0; i < sum[c].length; i++) sum[c][i] = 0;
                        }
                    }
                }
                if (((DoubleDataWithDecision)dObj).getDecision() == dec)
                {
                    number++;
                    int best = -1;
                    double bestDist = 0;
                    for (int c = 0; c < coefficients.length; c++)
                    {
                        double dist = 0;
                        for (int i = 0; i < coefficients[c].length; i++)
                        {
                            double diff = (dObj.get(i)-coefficients[c][i]);
                            dist += (diff*diff);
                        }
                        if (best==-1 || dist < bestDist)
                        {
                            best = c;
                            bestDist = dist;
                        }
                    }
                    for (int i = 0; i < coefficients[best].length; i++)
                    {
                        double diff = dObj.get(i)-coefficients[best][i];
                        energy += (diff*diff);
                        sum[best][i] += dObj.get(i);
                    }
                }
            }
            for (int c = 0; c < coefficients.length; c++)
                for (int i = 0; i < coefficients[c].length; i++)
                    coefficients[c][i] = sum[c][i] / number;
        }
        prevEnergy = energy;
        Radial[] radials = new Radial[coefficients.length];
        for (int i = 0; i < radials.length; i++) radials[i] = new Radial(attributes, coefficients[i]);
        return radials;
    }

    /**
     * algorytm k centroidow z iteracyjnie rosnaco liczba centroidow
     * dla wybranej klasy decyzyjnej
     */
    /**
     * Algorytm k centroidow z iteracyjnie rosnaco liczba centroidow
     * dla wybranej klasy decyzyjnej.
     * Warunkiem zakonczenia algorytmu jest roznica w energii
     * funkcji pomiedzy ostatnia i przedostatnia iteracja nie wieksza niz 1.
     *
     * @param tab Tabela treningowa.
     * @param dec Klasa decyzyjna.
     * @return Zbior wyuczonych funkcji odleglosci, jedna dla kazdego centroidu.
     */
    /**
     *
     * Constructs k radial function
     * using the algorithm of k-means with increasing number of means.
     * The algorithm stops when the difference in energy
     * between the last and the last but one iteration
     * is less than 1.
     *
     * @param tab         Training table.
     * @param dec         Decision class used to generate k means.
     * @return            Array of constructed radial functions.
     */
    public static Radial[] iterativeKMeans(DoubleDataTable tab, double dec)
    {
        double energy = -100;
        int noOfCenters = 1;
        Radial[] radials = kMeans(tab, dec, noOfCenters);
        Radial[] oldRadials = null;
        while (energy - prevEnergy > 1 || prevEnergy - energy > 1)
        {
            energy = prevEnergy;
            noOfCenters++;
            oldRadials = radials;
            radials = kMeans(tab, dec, noOfCenters);
        }
        return oldRadials;
    }
}

Copyright © 2008-2011 by TunedIT
Design by luksite