Моя цель - кластеризовать мои данные с использованием субтрактивной кластеризации, чтобы в дальнейшем я мог извлечь из них нечеткие правила.
предположим, у меня есть следующие 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.
Кстати, я провел некоторую исследовательскую работу и нашел следующий алгоритм для этого
алгоритм: -
- нормализует данные, используя значения Max и Min из обоих измерений
- рассчитать потенциалы, используя
где m - размеры или тип данных (в моем случае 2), n - количество точек.
3 выбирая наибольшее значение потенциала в качестве первого центра кластера и пересматривая потенциал всех точек данных до
кое-как, как я реализовал это с помощью 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
различные значения параметров, показанные на рисунке ниже, также совпадают в моей реализации
поэтому есть ли проблема в алгоритме, который я реализую, пожалуйста, предоставьте мне руководство