Субтрактивная реализация Clustring - PullRequest
0 голосов
/ 01 апреля 2012

Моя цель - кластеризовать мои данные с использованием субтрактивной кластеризации, чтобы в дальнейшем я мог извлечь из них нечеткие правила.

предположим, у меня есть следующие 2-мерные данные: -

X[]=[  {0,.16,.24,.42,.48,.66,.83,.24,.42,.48,.66,.66,.16,.24,.42,.42,.48,.48,.48,.66,.66,.66,.66,.66,.66,.66,.83,.83,.83,.66},

       {0,0,0,0,0,0,0,.15,.13,.1,.12,.18,.58,.78,.59,.78,.45,.49,.58,.45,.49,.58,.65,.71,.715,.72,.66,.725,.726,.455}
     ]

приведите примеры того, как реализовать субтрактивную кластеризацию в Java.

Кстати, я провел некоторую исследовательскую работу и нашел следующий алгоритм для этого

алгоритм: -

  1. нормализует данные, используя значения Max и Min из обоих измерений
  2. рассчитать потенциалы, используя

http://i.stack.imgur.com/i9ULH.jpg

где m - размеры или тип данных (в моем случае 2), n - количество точек.

3 выбирая наибольшее значение потенциала в качестве первого центра кластера и пересматривая потенциал всех точек данных до

h**p://i.stack.imgur.com/fuyjk.jpg

h**p://i.stack.imgur.com/K6res.jpg

кое-как, как я реализовал это с помощью Java, код: - (обратите внимание, что по какой-то причине я не могу предоставить полный работающий код, поэтому я прилагаю код, который выполняет представленные шаги алгоритма)

class SClustering {



double[][]data;
double normData[][];
ArrayList Potentials=new ArrayList();
ArrayList sortedPotentials;            
ArrayList clusters=new ArrayList();            
double rj[];
double radii;                        // radius
double squashFactor=1.5;  
double acceptRatio=.5;  
double rejectFactor=0.3;                         
double rb=radii*squashFactor;;                
double alpha=4.0/(radii*radii);      
double beta=4.0/(Math.pow(rb,2.0));   
double max[];
double min[];
int numofdimen=2;    // as according to the input dataset
int numofPoints=29; // as according to the input dataset
ArrayList centersArrayList=new ArrayList();
Potential p=new Potential();
double Pi=0;
boolean noCenter=false;
boolean flag=false;

public Clustering(double data[][], double Radii) 
{
    radii= Radii;
    data=new double[2][29];
    normData=new double[2][29];
    max=new double[2];
    min=new double[2];
    rj=new double[2];
    double[] sigmas=new double[centersArrayList.size()];
    rj[0]=100;
    rj[1]=50;
    int index;
    for(int i=0;i<29;i++)
    {
        for(int j=0;j<2;j++)
        {
            data[j][i]=data[j][i];
        }          

    }    
    dataNormalize();
    calculatePotential();       

    int m=0;
    while(!flag)
    {
      sortPotentials();                              
      index=setCenters(Potentials.size()-1);         
      sigmas=calculateSigmas();                      
      if(index!=-1)
      {
     new cluster()
          //setting the cluster
        cluster.setCentroid(getCenterPoint(index));       
        cluster.setSigmas(sigmas);                        

        RecalculatePotential(index);        
      }
      else
      {
        flag=true;
      }
    }
}


public void dataNormalize()

{   
//getting the max and min data point        
for(int m=0;m<numofdimen;m++)
    {
        min[m]=data[m][0];

        for(int i=0;i<numofPoints;i++)
        {                
            if(min[m]>data[m][i])
            {
                min[m]=data[m][i];
            }

        }    

    }
    for(int m=0;m<numofdimen;m++)
    {
        max[m]=data[m][0];

        for(int i=0;i<numofPoints;i++)
        {                
            if(max[m]<data[m][i])
            {
                max[m]=data[m][i];
            }

        }     

    }

    //normalizing 
    for(int m=0;m<numofdimen;m++)
    {            
        for(int i=0;i<numofPoints;i++)
        {                
            normData[m][i]=(data[m][i]-min[m])/(max[m]-min[m]);  

        }

     }
}

public void calculatePotential(){

    double distance=0;
    double tempPotential=0;


    for(int k=0;k<numofPoints;k++)
    {
        for(int i=0;i<numofPoints;i++)
        {
          if(k!=i)
          {
            for(int m=0;m<numofdimen;m++)
            {
                distance+=normData[m][k]-normData[m][i];

            }


             tempPotential=(Math.exp(-1* alpha *Math.pow(distance,2))); 

             if(i!=0)
             {

                 //here p is an object of potential class and here we are getting the previous set potentials
                 tempPotential+=previousPotentials.getValue();
             }
          }

         }
        p.setPotentials(k,tempPotential);
       Potentials.add(p);            
        p=new Potential();
    }

}

void RecalculatePotential(int index_of_center)
{
    double distance=0;
    double tempPotential;

    for(int k=0;k<numofPoints;k++)
    {
       if(k!=index_of_center)
       {
            for(int m=0;m<numofdimen;m++)
              {
                 distance+=normData[m][k]-normData[m][index_of_center];  

              }
                  tempPotential=(Math.exp(-1*beta*Math.pow(distance,2)));          
                  tempPotential=((Potentials.get(k))-(((Potentials.get(index_of_center)))*tempPotential);

                  p =new Potential();
                  p.setPotentials(k,tempPotential);
                  Potentials.set(k,p);           
                  p=new Potential();
       }
     }

}

   boolean ifNewCenter(int index_of_center)
    {
                       //if not new return false
                       //if new return true
    }

    double getMinDistance(int index_of_center)
    {

    double vectorDistances[]=new double[numofdimen];
    double distances[]=new double[centersArrayList.size()];
    double minDistanceistance;   
    for(int j=0;j<centersArrayList.size();j++)
    {
       for(int m=0;m<numofdimen;m++)
       {
          if(index_of_center!=j)
          {
            vectorDistances[m]=normData[m][index_of_center]-normData[m][((Integer)(centers.get(j))).intValue()];   
          }
       }
          distances[j]=calculateVLength(vectorDistances);                   
    }


    //sort the distances
     return distances[0];
}

 public void sortPotentials()
 {
    //returns the sorted list of potentials
 }

 public int setCenters(int maxIndex)
 {


     double minDistance;
     double PotentialCenter;
    PotentialCenter=((Double)(sortedPotentials.get(maxIndex))).doubleValue();
       if(centersArrayList.size()!=0)
        {



            if(ifNewCenter()) // here we are checking the the center is new or not
             {
                 minDistance=getMinDistance(maxIndex);

                   if(PotentialCenter>((acceptRatio)*((Potential)Potentials.get(Potentials.size()-1)).getValue()))
            centersArrayList.add(((Integer)((Potential)(sortedPotentials.get(maxIndex))).getIndex()).intValue());    
                   else if(clusteringEnd(maxIndex))
                         flag=true;
               else if((minDistance/radii)+(PotentialCenter/Pi)<1)
                 {
                     p=new Potential();
                     p.setPotentials(maxIndex,0);
                     Potentials.set(maxIndex,p);

                     if(maxIndex>0)
                     {
                         setCenters(maxIndex-1);
                     }                       
                     else 
                     {
                         noCenter=true;
                         return 0;
                     }
                 }
                 else

                 {
                 //   System.out.println("flag is true nwo------------------------------------");

                    centersArrayList.add(((Integer)((Potential)(sortedPotentials.get(maxIndex))).getIndex()).intValue());  
                 }
             }
             else
             {
                if(maxIndex>0)
                {
                    setCenters(maxIndex-1);
                }   
                else 
                {
                    noCenter=true;
                    return 0;
                }
             }
        }
        else
        {
            centersArrayList.add(((Integer)((Potential)(sortedPotentials.get(maxIndex))).getIndex()).intValue());  
            Pi=PotentialCenter;
        }    
    if(!noCenter || !flag)
    {
     return ((Integer)(centersArrayList.get(centersArrayList.size()-1))).intValue();
    }
    else 
    {
        return -2;
    }
 }

public boolean clusteringEnd(int centerindex)
{   

        //comparing the current potential with the rejectFactor* first largest potential
        if((((Potential)(Potentials.get(centerindex))))<(rejectFactor*(((Potential)(Potentials.get(Potentials.size()-1))))))
                return true;

    return false;
}
  public double[] calculateSigmas()
  {
    double sigmas[]=new double[numofdimen];

        for(int m=0;m<numofdimen;m++)
        {
           sigmas[m]=(rj[m]*(max[m]-min[m]))/(Math.sqrt(8.0));
      }
    return sigmas;
}
 public double calculateVLength(double input[]){
    double temp=0;
    double length=0;

    for(int i=0;i<input.length;i++)
    {
        temp+=Math.pow(input[i],2);
    }
    length=Math.sqrt(temp);

    return length;
}

   public static void main(String[] args) {

   double Points[][]={  {0,.16,.24,.42,.48,.66,.83,.24,.42,.48,.66,.66,.16,.24,.42,.42,.48,.48,.48,.66,.66,.66,.66,.66,.66,.66,.83,.83,.83,.66},
                    {0,0,0,0,0,0,0,.15,.13,.1,.12,.18,.58,.78,.59,.78,.45,.49,.58,.45,.49,.58,.65,.71,.715,.72,.66,.725,.726,.455}
                 };
    SClustering sc;
    sc=new SClustering(Points,.4);
   }
}

но моя проблема в коде: -

когда я запускаю свою программу, я получаю только два кластера с centroid1: 0,83,0,725 centroid2: - 0,83,0,726

но когда я запускаю программу Matlab 'clusterfind' для того же вышеупомянутого набора данных, я получаю 3 кластера с

centroid1: 0,66,0,65 centroid2: - 0,48,0,10 centroid3: - 0,16,0,0

различные значения параметров, показанные на рисунке ниже, также совпадают в моей реализации

http://i.stack.imgur.com/f5qiB.jpg

поэтому есть ли проблема в алгоритме, который я реализую, пожалуйста, предоставьте мне руководство

...