//--------------------------------------------------------------------------------// // COPYRIGHT NOTICE // //--------------------------------------------------------------------------------// // Copyright (c) 2012, Instituto de Microelectronica de Sevilla (IMSE-CNM) // // // // All rights reserved. // // // // Redistribution and use in source and binary forms, with or without // // modification, are permitted provided that the following conditions are met: // // // // * Redistributions of source code must retain the above copyright notice, // // this list of conditions and the following disclaimer. // // // // * Redistributions in binary form must reproduce the above copyright // // notice, this list of conditions and the following disclaimer in the // // documentation and/or other materials provided with the distribution. // // // // * Neither the name of the IMSE-CNM nor the names of its contributors may // // be used to endorse or promote products derived from this software // // without specific prior written permission. // // // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE // // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //--------------------------------------------------------------------------------// package xfuzzy.xfsp.model.types; /** * <p> <b>Descripci�n:</b> clase que implementa el m�todo de validaci�n de * clusters mediante los �ndices de Davies & Bouldin. * <p> <b>E-mail</b>: <ADDRESS>joragupra@us.es</ADDRRESS> * @author Jorge Agudo Praena * @version 1.2 * @see IXfspTypeSimplifier * @see IXfspValidityMeasure * @see XfspTypeSimplifierFactory * */ public class XfspDaviesBouldinValidityMeasure implements IXfspValidityMeasure { //array de datos para los que queremos saber cu�l es el mejor n�mero de //clusters en que se pueden agrupar private double[][] data; //pesos que se quiere dar a los elementos de que consta cada dato private double[] weights; //par�metro utilizado a la hora de calcular la Q-norma de Minkowski durante //la evaluaci�n de los clusters private int q; //par�metro que se utiliza para calcular el valor de alfa de un determinado //cluster private int t; /** * <p> <b>Descripci�n:</b> crea un nuevo objeto de tipo * <b>XfspDaviesBouldinValidityMeasure</b> que permite evaluar el mejor * n�mero de clusters en que agrupar un conjunto de datos bas�ndose en el * m�todo de validez de Davies & Bouldin (1979). * @param data Conjunto de datos de partida, cada uno de los cuales viene * representado como un array de <i>double</i>. * @param weights Pesos que se quieren otorgar a cada uno de los elementos * que compone un dato. * @param t Par�metro utilizado en el c�lculo del valor alfa de un cluster * @para q Par�metro utilzado en el c�lculo de la Q-Norma de Minkowski de un * vector. * */ public XfspDaviesBouldinValidityMeasure(double[][] data, double[] weights, int t, int q) { this.data = data; this.weights = weights; this.t = t; this.q = q; } /** * <p> <b>Descripci�n:</b> calcula el n�mero �ptimo de clusters para agrupar * un conjunto de datos seg�n el m�todo de validez de Davies & Bouldin (1979). * @return N�mero de clusters m�s adecuado para agrupar un conjunto de datos * num�ricos de tipo <i>double</i>. * */ public int getNumClusters() { //como primera referencia consideraremos tantos clusters como datos tenemos int num = data.length; //creamos un objeto que permite representar clusters con los datos de //partida los pesos que queremos dar a cada uno de los elementos que forman //los datos de partida y un n�mero inicial de clusters igual al n�mero de //datos de partida de que disponemos... XfspCluster c = new XfspCluster(data, data.length, weights); //...y evaluamos la asignaci�n anterior para tener una primera referencia double min = evaluation(c); //para todos los posibles n�meros de clusters con que podemos agrupar los //datos (con un m�nimo de dos) y sin tener en cuenta el caso de agrupar //los datos en tantos clusters como datos haya... for (int i = 2; i <= (data.length - 1); i++) { //...creamos un objeto que permite representar clusters con los mismos //datos y pesos que antes, pero con el n�mero de cluster que estamos //considerando ahora... c = new XfspCluster(data, i, weights); //...y evaluamos dicha agrupaci�n de datos en clusters double eval = evaluation(c); //si la nueva agrupaci�n de datos en clusters mejora a la anterior... if (eval < min) { //...actualizamos tanto el n�mero de clusters �ptimo encontrado hasta //ahora como la evaluaci�n �ptima obtenida hasta ahora min = eval; num = i; } } //devolvemos el mejor valor para el n�mero de cluster en que debemos agrupar //los datos return num; } /** * <p> <b>Descripci�n:</b> devuelve el resultado de la evaluaci�n de las * asignaciones de los datos a los distintos clusters que se han hecho. * @param c Cluster que se quiere evaluar. * @return Valoraci�n de las asignaciones de los datos de partida a los * distintos clusters. * */ private double evaluation(XfspCluster c) { //n�mero de clusters en que se han agrupado los datos int C = c.cluster.length; //creamos un objeto que nos permite calcular distancias entre datos y //clusters IXfspDistance d = new XfspEuclideanDistance(weights); //elemento aculumador que inicializamos a cero double accumulative = 0; //para cada pareja de clusters distintos... for (int i = 0; i < C; i++) { //...inicializamos el valor m�ximo al m�nimo que puede tomar... double max = 0; for (int j = 0; j < C; j++) { //si se trata de dos clusters distintos... if (j != i) { //calculamos la diferencia entre los centros de dicha pareja de //clusters double[] diff = d.difference(c.cluster[i], c.cluster[j]); //calculamos el valor alfa correspondiente al cluster i-�simo y al //cluster j-�simo (ambos con par�metro t) y los sumamos... double aux = d.alpha(data, c.assign, c.cluster, i, t) + d.alpha(data, c.assign, c.cluster, j, t); //...y dividimos el resultado de dicha suma entre la Q-norma de //Minkowski de la diferencia entre los centros de los clusters aux /= d.minkowskiQNorm(diff, q); //si dicho valor supera al m�ximo que hab�amos alcanzado hasta //ahora... if (aux > max) { //...actulizamos el m�ximo encontrado al nuevo valor... max = aux; } } } //...y vamos acumulando lso valores m�ximos en nuestro acumulador accumulative += max; } //el resultado de la funci�n de evaluaci�n es el cociente entre la suma de //los m�ximos y el numero de clusters en que hemos agrupado los datos return accumulative / C; } }