public void evaluateClustering()

in samoa-api/src/main/java/org/apache/samoa/evaluation/measures/SilhouetteCoefficient.java [46:123]


  public void evaluateClustering(Clustering clustering, Clustering trueClustering, ArrayList<DataPoint> points) {
    int numFCluster = clustering.size();

    double[][] pointInclusionProbFC = new double[points.size()][numFCluster];
    for (int p = 0; p < points.size(); p++) {
      DataPoint point = points.get(p);
      for (int fc = 0; fc < numFCluster; fc++) {
        Cluster cl = clustering.get(fc);
        pointInclusionProbFC[p][fc] = cl.getInclusionProbability(point);
      }
    }

    double silhCoeff = 0.0;
    int totalCount = 0;
    for (int p = 0; p < points.size(); p++) {
      DataPoint point = points.get(p);
      ArrayList<Integer> ownClusters = new ArrayList<>();
      for (int fc = 0; fc < numFCluster; fc++) {
        if (pointInclusionProbFC[p][fc] > pointInclusionProbThreshold) {
          ownClusters.add(fc);
        }
      }

      if (ownClusters.size() > 0) {
        double[] distanceByClusters = new double[numFCluster];
        int[] countsByClusters = new int[numFCluster];
        // calculate averageDistance of p to all cluster
        for (int p1 = 0; p1 < points.size(); p1++) {
          DataPoint point1 = points.get(p1);
          if (p1 != p && point1.classValue() != -1) {
            for (int fc = 0; fc < numFCluster; fc++) {
              if (pointInclusionProbFC[p1][fc] > pointInclusionProbThreshold) {
                double distance = point.getDistance(point1);
                distanceByClusters[fc] += distance;
                countsByClusters[fc]++;
              }
            }
          }
        }

        // find closest OWN cluster as clusters might overlap
        double minAvgDistanceOwn = Double.MAX_VALUE;
        int minOwnIndex = -1;
        for (int fc : ownClusters) {
          double normDist = distanceByClusters[fc] / (double) countsByClusters[fc];
          if (normDist < minAvgDistanceOwn) {// && pointInclusionProbFC[p][fc] > pointInclusionProbThreshold){
            minAvgDistanceOwn = normDist;
            minOwnIndex = fc;
          }
        }

        // find closest other (or other own) cluster
        double minAvgDistanceOther = Double.MAX_VALUE;
        for (int fc = 0; fc < numFCluster; fc++) {
          if (fc != minOwnIndex) {
            double normDist = distanceByClusters[fc] / (double) countsByClusters[fc];
            if (normDist < minAvgDistanceOther) {
              minAvgDistanceOther = normDist;
            }
          }
        }

        double silhP = (minAvgDistanceOther - minAvgDistanceOwn) / Math.max(minAvgDistanceOther, minAvgDistanceOwn);
        point.setMeasureValue("SC - own", minAvgDistanceOwn);
        point.setMeasureValue("SC - other", minAvgDistanceOther);
        point.setMeasureValue("SC", silhP);

        silhCoeff += silhP;
        totalCount++;
        // System.out.println(point.getTimestamp()+" Silh "+silhP+" / "+avgDistanceOwn+" "+minAvgDistanceOther+" (C"+minIndex+")");
      }
    }
    if (totalCount > 0)
      silhCoeff /= (double) totalCount;
    // normalize from -1, 1 to 0,1
    silhCoeff = (silhCoeff + 1) / 2.0;
    addValue(0, silhCoeff);
  }