Is there any way to reduce total execution time for the function getSilhouetteIndex
? P.S. I am using weka SimpleKMeans
for getting kmeans and ceval
.
private double getSilhouetteIndex(List<ITSPoI> _POIs, SimpleKMeans kmeans, ClusterEvaluation ceval)
{
double si_index = 0;
double[] ca = ceval.getClusterAssignments();
double[] d_arr = new double[ca.length];
List<Double> si_indexes = new ArrayList<Double>();
for (int i=0; i<ca.length; i++)
{
// STEP 1. Compute the average distance between the i-th PoI and all other points of a given cluster
double a = averageDist(_POIs,ca,i,1);
// STEP 2. Compute the average distance between the i-th PoI and all PoIs of other clusters
for (int j=0; j<ca.length; j++)
{
double d = averageDist(_POIs,ca,j,2);
d_arr[j] = d;
}
// STEP 3. Compute the the distance from the i-th PoI to its nearest cluster to which it does not belong
double b = d_arr[0];
for (Double _d : d_arr)
{
if (_d < b)
b = _d;
}
// STEP 4. Compute the Silhouette index for the i-th PoI
double si = (b - a)/Math.max(a,b);
si_indexes.add(si);
}
// STEP 5. Compute the average index over all observations
double sum = 0;
for(Double _si : si_indexes)
{
sum += _si;
}
si_index = sum/si_indexes.size();
return si_index;
}
private double averageDist(List<ITSPoI> _POIs, double[] ca, int id, int calc)
{
double avgDist = 0;
List<ITSPoI> clusterPOIs = new ArrayList<ITSPoI>();
// Distances inside the cluster
if (calc == 1)
{
for (int i = 0; i<ca.length; i++)
{
if (ca[i] == ca[id])
clusterPOIs.add(_POIs.get(i));
}
}
// Distances outside the cluster
else
{
for (int i = 0; i<ca.length; i++)
{
if (ca[i] != ca[id])
clusterPOIs.add(_POIs.get(i));
}
}
double latx, lonx, laty, lony;
double[] dist = new double[clusterPOIs.size()];
latx = _POIs.get(id).getLat();
lonx = _POIs.get(id).getLon();
for (int i=0; i<clusterPOIs.size(); i++)
{
laty = clusterPOIs.get(i).getLat();
lony = clusterPOIs.get(i).getLon();
dist[i] = distanceGeo(latx,lonx,laty,lony);
}
double sum = 0;
for(Double d : dist)
{
sum += d;
}
avgDist = sum/dist.length;
return avgDist;
}
private double distanceGeo(double lat1, double lon1, double lat2, double lon2)
{
if (lat1 == lat2 && lon1 == lon2)
{
return 0;
}
else
{
double theta = lon1 - lon2;
double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
dist = Math.acos(dist);
dist = rad2deg(dist);
dist = dist * 60 * 1.1515;
dist = dist * 1.609344;
return dist;
}
}
ITSPoI
, what isSimpleKMeans
and what isClusterEvaluation
. To me, you haven't provided much context on this question. \$\endgroup\$