in samoa-api/src/main/java/org/apache/samoa/evaluation/measures/General.java [142:190]
private double computeCompactness() {
if (numFClusters == 0)
return 0;
for (int c = 0; c < numFClusters; c++) {
if (!(clustering.get(c) instanceof SphereCluster)) {
System.out.println("Compactness only supports Sphere Cluster. Found: " + clustering.get(c).getClass());
return Double.NaN;
}
}
// TODO weight radius by number of dimensions
double totalCompactness = 0;
for (int c = 0; c < numFClusters; c++) {
ArrayList<Instance> containedPoints = new ArrayList<Instance>();
for (int p = 0; p < numPoints; p++) {
// p in c
if (clustering.get(c).getInclusionProbability(points.get(p)) >= pointInclusionProbThreshold) {
containedPoints.add(points.get(p));
}
}
double compactness = 0;
if (containedPoints.size() > 1) {
// cluster not empty
SphereCluster minEnclosingCluster = new SphereCluster(containedPoints, numDims);
double minRadius = minEnclosingCluster.getRadius();
double cfRadius = ((SphereCluster) clustering.get(c)).getRadius();
if (Math.abs(minRadius - cfRadius) < 0.1e-10) {
compactness = 1;
}
else if (minRadius < cfRadius)
compactness = minRadius / cfRadius;
else {
System.out.println("Optimal radius bigger then real one (" + (cfRadius - minRadius)
+ "), this is really wrong");
compactness = 1;
}
}
else {
double cfRadius = ((SphereCluster) clustering.get(c)).getRadius();
if (cfRadius == 0)
compactness = 1;
}
// weight by weight of cluster???
totalCompactness += compactness;
clustering.get(c).setMeasureValue("Compactness", Double.toString(compactness));
}
return (totalCompactness / numFClusters);
}