code: @Override
      public double calculateAnomalyScore(double value) {
          int instanceIndex = metricDataValues.indexOf(value);
          Instance valueInstance = trainingData.instance(instanceIndex);
          //Centroid that is assigned to valueInstance
          Instance centroidInstance = clusterCentroids.instance(centroidAssignments[instanceIndex]);
  
          if (meanDistancesToCentroids.get(centroidInstance) == 0.0) {
              throw new ArithmeticException("Cannot divide by 0");
          }
  
          double distanceToCentroid = Math.abs(valueInstance.value(0) - centroidInstance.value(0));
          double relativeDistanceToCentroid = distanceToCentroid / meanDistancesToCentroids.get(centroidInstance);
          return relativeDistanceToCentroid;
      }
docs: Calculates the relative distance of the data point to the centroid,
  which is the ratio of the distance of the point to the centroid to
  the mean distance of all points in that cluster to the centroid.
  
  Anomaly score here is defined as how "far" a data point is from its
  assigned centroid. Relative distance is used to ensure normalization
  of distances since clusters can have different densities.
  
  @param value value the value of the data point
  @return the relative distance of the data point from the centroid