src/main/java/it/uniroma2/dicii/sabd/covidproject/Query3.java
/*
    * Apply a naive implementation of k-means. This implementation has the following characteristics:
    * - The initial centroids are selected dividing the range between the minimum value and maximum value
    *   in k parts and assigning to cluster i the ((2i-1)/2k)*100th-percentile
    * - The training ends after a maximum of MAX_K_MEANS_ITERATIONS iterations or if the distance
    *   between the vector of new centroids and the vector of old centroids is lower than K_MEANS_ERROR_THRESHOLD
    * - Euclidean distance is used
    * */
Apply a naive implementation of k-means.
Apply a naive implementation of k - means .
private static void kMeansNaive(JavaPairRDD<Double,RegionData> trendRegionPairs, String outputDirectory) {
        List<Double> trendCoefficients = trendRegionPairs.map(x -> x._1).distinct().collect();
        double[] trendCoefficientsArray = new double[trendCoefficients.size()];
        for (int i = 0; i < trendCoefficients.size(); i++) {
            trendCoefficientsArray[i] = trendCoefficients.get(i);
        }
        Double[] newCentroids = new Double[NUM_OF_K_MEANS_CLUSTERS];
        for (int i = 0; i < NUM_OF_K_MEANS_CLUSTERS; i++) {
            newCentroids[i] = StatUtils.percentile(trendCoefficientsArray, (float) 100 * (2 * (i + 1) - 1)/(2 * NUM_OF_K_MEANS_CLUSTERS));
        }
        JavaPairRDD<Integer, RegionData> clusteredTrendCoefficientRegions = null;
        for (int i = 0; i < MAX_K_MEANS_ITERATIONS; i++) {
            Double[] centroids = newCentroids;
            clusteredTrendCoefficientRegions = trendRegionPairs.mapToPair(x -> assignRegionToCluster(x, centroids));
            JavaPairRDD<Integer, Iterable<RegionData>> trendRegionsByCluster = clusteredTrendCoefficientRegions.groupByKey();
            newCentroids = fromDoubleListToDoubleArray(trendRegionsByCluster
                    .mapValues(Query3::computeClusterCentroid)
                    .sortByKey().map(x -> x._2).collect());
            Double distanceFromOlderCentroids = computeEuclideanDistance(centroids, newCentroids);
            if (distanceFromOlderCentroids < K_MEANS_ERROR_THRESHOLD) {
                break;
            }
        }
        clusteredTrendCoefficientRegions.
                map(x -> x._2.getMonth() + "," + x._2.getName() + "," + x._1 + "," + x._2.getLatitude() + "," + x._2.getLongitude() +
                        "," + BigDecimal.valueOf(x._2.getTrendLineCoefficient()).toPlainString()).saveAsTextFile(outputDirectory);
    }
private static void kMeansNaive ( JavaPairRDD < Double , RegionData > trendRegionPairs , String outputDirectory ) { List < Double > trendCoefficients = trendRegionPairs . map ( x -> x . _1 ) . distinct ( ) . collect ( ) ; double [ ] trendCoefficientsArray = new double [ trendCoefficients . size ( ) ] ; for ( int i = 0 ; i < trendCoefficients . size ( ) ; i ++ ) { trendCoefficientsArray [ i ] = trendCoefficients . get ( i ) ; } Double [ ] newCentroids = new Double [ NUM_OF_K_MEANS_CLUSTERS ] ; for ( int i = 0 ; i < NUM_OF_K_MEANS_CLUSTERS ; i ++ ) { newCentroids [ i ] = StatUtils . percentile ( trendCoefficientsArray , ( float ) 100 * ( 2 * ( i + 1 ) - 1 ) / ( 2 * NUM_OF_K_MEANS_CLUSTERS ) ) ; } JavaPairRDD < Integer , RegionData > clusteredTrendCoefficientRegions = null ; for ( int i = 0 ; i < MAX_K_MEANS_ITERATIONS ; i ++ ) { Double [ ] centroids = newCentroids ; clusteredTrendCoefficientRegions = trendRegionPairs . mapToPair ( x -> assignRegionToCluster ( x , centroids ) ) ; JavaPairRDD < Integer , Iterable < RegionData > > trendRegionsByCluster = clusteredTrendCoefficientRegions . groupByKey ( ) ; newCentroids = fromDoubleListToDoubleArray ( trendRegionsByCluster . mapValues ( Query3 :: computeClusterCentroid ) . sortByKey ( ) . map ( x -> x . _2 ) . collect ( ) ) ; Double distanceFromOlderCentroids = computeEuclideanDistance ( centroids , newCentroids ) ; if ( distanceFromOlderCentroids < K_MEANS_ERROR_THRESHOLD ) { break ; } } clusteredTrendCoefficientRegions . map ( x -> x . _2 . getMonth ( ) + "," + x . _2 . getName ( ) + "," + x . _1 + "," + x . _2 . getLatitude ( ) + "," + x . _2 . getLongitude ( ) + "," + BigDecimal . valueOf ( x . _2 . getTrendLineCoefficient ( ) ) . toPlainString ( ) ) . saveAsTextFile ( outputDirectory ) ; }
Apply a naive implementation of k-means.
Apply a naive implementation of k - means .