Commit f2d1534c authored by Alexander David Hellwig's avatar Alexander David Hellwig

Add SilhouetteIndex

parent c878fa79
Pipeline #110707 failed with stages
in 32 minutes and 3 seconds
package de.monticore.lang.monticar.generator.middleware.clustering.qualityMetric;
import java.util.HashSet;
import java.util.Set;
public class SilhouetteIndex {
private double[][] distanceMatrix;
private int[] clusteringLabels;
public SilhouetteIndex(double[][] distanceMatrix, int[] clusteringLabels) {
this.distanceMatrix = distanceMatrix;
this.clusteringLabels = clusteringLabels;
}
public double getSilhouetteScore(){
double sum = 0d;
for (int i = 0; i < clusteringLabels.length; i++) {
sum += S(i);
}
return sum/clusteringLabels.length;
}
public double S(int o){
double a = distA(o);
double b = distB(o);
if(a <= 0.0000000d && b <= 0.0000000d){
return 0;
}else{
return (b-a)/Math.max(a,b);
}
}
public double distA(int o){
int clusterOfO = clusteringLabels[o];
return averageDistToCluster(o, clusterOfO);
}
public double distB(int o){
Set<Integer> processedLabels = new HashSet<>();
int clusterOfO = clusteringLabels[o];
double minDist = Double.MAX_VALUE;
for (int label : clusteringLabels) {
if(label != clusterOfO) {
if (!processedLabels.contains(label)) {
double d = averageDistToCluster(o, label);
if (d < minDist) {
minDist = d;
}
processedLabels.add(label);
}
}
}
return minDist;
}
private double averageDistToCluster(int o, int clusterLabel){
int numInCluster = 0;
double sum = 0d;
for (int i = 0; i < clusteringLabels.length; i++) {
if(clusteringLabels[i] == clusterLabel){
sum += distanceMatrix[o][i];
numInCluster++;
}
}
return sum/((double)numInCluster);
}
}
......@@ -6,6 +6,7 @@ import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instance
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAPortInstanceSymbol;
import de.monticore.lang.monticar.generator.middleware.clustering.*;
import de.monticore.lang.monticar.generator.middleware.clustering.algorithms.*;
import de.monticore.lang.monticar.generator.middleware.clustering.qualityMetric.SilhouetteIndex;
import de.monticore.lang.monticar.generator.middleware.clustering.visualization.ModelVisualizer;
import de.monticore.lang.monticar.generator.middleware.helpers.ComponentHelper;
import de.monticore.lang.monticar.generator.middleware.impls.CPPGenImpl;
......@@ -144,6 +145,41 @@ public class AutomaticClusteringTest extends AbstractSymtabTest{
}
@Test
public void testSilhouetteIndex(){
// graph:
// a,b close to each other
// c,d close to each other
// big difference between a and c as well as b and d
double[][] adjMat = {
{0, 10, 1000, 1000},
{10, 0, 1000, 1000},
{1000, 1000, 0, 10},
{1000, 1000, 10, 0}
};
double[][] dist = AutomaticClusteringHelper.getDistanceMatrix(adjMat);
int[] correctCustering = {0,0,1,1};
SilhouetteIndex index1 = new SilhouetteIndex(dist, correctCustering);
assertTrue(index1.S(0) > 0.5);
assertTrue(index1.S(1) > 0.5);
assertTrue(index1.S(2) > 0.5);
assertTrue(index1.S(3) > 0.5);
int[] badClustering = {0,0,0,1};
SilhouetteIndex index2 = new SilhouetteIndex(dist, badClustering);
assertTrue(index2.S(0) > 0.5);
assertTrue(index2.S(1) > 0.5);
assertTrue(index2.S(2) < -0.5);
assertTrue(index2.S(3) > 0.5);
assertTrue(index1.getSilhouetteScore() > index2.getSilhouetteScore());
}
@Test
public void testSpectralClustering(){
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment