public double CalculateSilhouette(List <ClusterDistanceModel> clusteringResult) { Dictionary <int, double> lowestDissimilarities = new Dictionary <int, double>(); Dictionary <int, double> sameClusterDissimilarity = new Dictionary <int, double>(); for (int i = 0; i < NumberOfClusters; i++) { List <TransactionMatrixModel> clusterIPersons = TransactionMatrix.Where( m => clusteringResult.Where(n => n.CurrentCluster == i) .Select(b => b.PersonId) .Contains(m.PersonId)).ToList(); for (int j = 0; j < NumberOfClusters; j++) { List <TransactionMatrixModel> clusterJPersons = TransactionMatrix.Where( m => clusteringResult.Where(n => n.CurrentCluster == j) .Select(b => b.PersonId) .Contains(m.PersonId)).ToList(); foreach (TransactionMatrixModel personI in clusterIPersons) { double dissimilarity = CalculateDissimilarity(personI, clusterJPersons); if ( clusteringResult.Where(m => m.CurrentCluster == j) .Count(m => m.PersonId == personI.PersonId) == 0) { SaveDissimilarities(lowestDissimilarities, dissimilarity, personI.PersonId); } else { SaveDissimilarities(sameClusterDissimilarity, dissimilarity, personI.PersonId); } } } } double resultSilhouette = 0; foreach (KeyValuePair <int, double> lowestDissimilarity in lowestDissimilarities) { int personId = lowestDissimilarity.Key; double silhouette = (lowestDissimilarities[personId] - sameClusterDissimilarity[personId]) / Math.Max(lowestDissimilarities[personId], sameClusterDissimilarity[personId]); resultSilhouette += silhouette; } return(resultSilhouette / lowestDissimilarities.Count); }
private double[,] RecalculateCentroids(List <ClusterDistanceModel> results, double[,] prevCentroids) { double[,] centroids = new double[NumberOfClusters, 32]; //foreach person sum total values / total in cluster for (int i = 0; i < NumberOfClusters; i++) { for (int j = 0; j < NumberOfVectors; j++) { List <int> persons = results.Where(m => m.CurrentCluster == i).Select(m => m.PersonId).ToList(); int count = TransactionMatrix.Count(m => persons.Contains(m.PersonId)); double sum = TransactionMatrix.Where(m => persons.Contains(m.PersonId)).Sum(m => m.Values[j]); double mean = sum / count; centroids[i, j] = count > 0 ? mean : prevCentroids[i, j]; } } return(centroids); }
public Clustering(List <TransactionModel> transactions) { TransactionMatrix = TransformData(transactions); NumberOfVectors = TransactionMatrix.Select(m => m.Values.Count()).First(); }