/// <summary> /// Computes the natural clustering of the resulting trajectories (behaviors) along with the behavioral entropy /// (diversity). /// </summary> /// <param name="evaluationUnits">The agent/maze evaluations to cluster and compute entropy.</param> /// <param name="clusterImprovementThreshold"> /// The number of cluster additions that are permitted without further /// maximization of silhouette width. When this is exceeded, the incremental cluster additions will stop and the /// number of clusters resulting in the highest silhouette width will be considered optimal. /// </param> /// <returns></returns> public static ClusterDiversityUnit CalculateNaturalClustering( IList<MazeNavigatorEvaluationUnit> evaluationUnits, int clusterImprovementThreshold) { Dictionary<int, double> clusterSilhoutteMap = new Dictionary<int, double>(); Tuple<int, double> clusterWithMaxSilhouetteWidth = null; // Always start with zero clusters and increment on first iteration of loop const int initClusterCnt = 0; // Only consider successful trials IList<MazeNavigatorEvaluationUnit> successfulEvaluations = evaluationUnits.Where(eu => eu.IsMazeSolved).ToList(); // Define the trajectory matrix in which to store all trajectory points for each trajectory // (this becomes a collection of observation vectors that's fed into k-means) double[][] trajectoryMatrix = new double[successfulEvaluations.Count][]; // Get the maximum observation vector length (max simulation runtime) // (multiplied by 2 to account for each timestep containing a 2-dimensional position) int maxObservationLength = successfulEvaluations.Max(x => x.NumTimesteps)*2; for (int idx = 0; idx < successfulEvaluations.Count; idx++) { // If there are few observations than the total elements in the observation vector, // fill out the vector with the existing observations and set the rest equal to the last // position in the simulation if (successfulEvaluations[idx].AgentTrajectory.Length < maxObservationLength) { trajectoryMatrix[idx] = successfulEvaluations[idx].AgentTrajectory.Concat( Enumerable.Repeat( successfulEvaluations[idx].AgentTrajectory[ successfulEvaluations[idx].AgentTrajectory.Length - 1], maxObservationLength - successfulEvaluations[idx].AgentTrajectory.Length)).ToArray(); } // If they are equal, just set the trajectory points else { trajectoryMatrix[idx] = successfulEvaluations[idx].AgentTrajectory; } } // Set the initial cluster count int clusterCount = initClusterCnt; // Continue loop until the maximum number of iterations without silhouette width improvement has elapsed // (also don't allow number of clusters to match the number of observations) while (clusterWithMaxSilhouetteWidth == null || (clusterSilhoutteMap.Count <= clusterImprovementThreshold || clusterSilhoutteMap.Where( csm => (csm.Key - initClusterCnt) >= clusterSilhoutteMap.Count - clusterImprovementThreshold) .Any( csm => csm.Value >= clusterWithMaxSilhouetteWidth.Item2)) && clusterCount < trajectoryMatrix.Length - 1) { // Increment cluster count clusterCount++; // Create a new k-means instance with the specified number of clusters var kmeans = new KMeans(clusterCount); // TODO: The below logic is in support of a work-around to an Accord.NET bug wherein // TODO: an internal random number generator sometimes generates out-of-bounds values // TODO: (i.e. a probability that is not between 0 and 1) // TODO: https://github.com/accord-net/framework/issues/259 // Use uniform initialization kmeans.UseSeeding = Seeding.Uniform; // Determine the resulting clusters var clusters = kmeans.Learn(trajectoryMatrix); // Compute the silhouette width for the current number of clusters double silhouetteWidth = ComputeSilhouetteWidth(clusters, trajectoryMatrix); // Compute silhouette width and add to map with the current cluster count clusterSilhoutteMap.Add(clusterCount, silhouetteWidth); // If greater than the max silhouette width, reset the cluster with the max if (clusterWithMaxSilhouetteWidth == null || silhouetteWidth > clusterWithMaxSilhouetteWidth.Item2) { clusterWithMaxSilhouetteWidth = new Tuple<int, double>(clusterCount, silhouetteWidth); } } // Rerun kmeans for the final cluster count var optimalClustering = new KMeans(clusterCount); // TODO: The below logic is in support of a work-around to an Accord.NET bug wherein // TODO: an internal random number generator sometimes generates out-of-bounds values // TODO: (i.e. a probability that is not between 0 and 1) // TODO: https://github.com/accord-net/framework/issues/259 // Use uniform initialization optimalClustering.UseSeeding = Seeding.Uniform; // Determine cluster assignments optimalClustering.Learn(trajectoryMatrix); double sumLogProportion = 0.0; // Compute the shannon entropy of the population for (int idx = 0; idx < optimalClustering.Clusters.Count; idx++) { sumLogProportion += optimalClustering.Clusters[idx].Proportion* Math.Log(optimalClustering.Clusters[idx].Proportion, 2); } // Multiply by negative one to get the Shannon entropy double shannonEntropy = sumLogProportion*-1; // Return the resulting cluster diversity info return new ClusterDiversityUnit(optimalClustering.Clusters.Count, shannonEntropy); }
/// <summary> /// The cluster. /// </summary> /// <param name="clustersCount"> /// The clusters count. /// </param> /// <param name="data"> /// The data. /// </param> /// <returns> /// The <see cref="T:int[]"/>. /// </returns> public int[] Cluster(int clustersCount, double[][] data) { KMeans kMeans = new KMeans(clustersCount); var clusters = kMeans.Learn(data); var result = new int[data.Length]; for (int i = 0; i < result.Length; i++) { result[i] = clusters.Decide(data[i]); } return result; }
public static List <Point2D> FindBaseLocation(this List <Unit> self) { List <Point2D> ret = new List <Point2D>(); List <Unit> gas = self.GetUnits(UNIT_TYPEID.NEUTRAL_VESPENEGEYSER); double[][] data = new double[gas.Count][]; for (int i = 0; i < gas.Count; i++) { data[i] = new double[] { gas[i].Pos.X, gas[i].Pos.Y }; } KMeans kmeans = new KMeans(k: gas.Count / 2); KMeansClusterCollection clusters = kmeans.Learn(data); for (int i = 0; i < kmeans.Centroids.Length; i++) { ret.Add(new Point2D { X = (float)kmeans.Centroids[i][0], Y = (float)kmeans.Centroids[i][1] }); } return(ret); }
private async Task RetrainAsync(Expression <Func <Leg, bool> > predicate) { await _geocodingDbSync.UpdateAllAsync(); KMeans kMeans = new KMeans(NumberOfClusters) { Distance = new GeographicDistance() }; double[][] dataset = GetDataset(predicate == null ? await _legRepository.ListAsync() : await _legRepository.ListAsync(predicate)); ClusterCollection = await Task.Run(() => kMeans.Learn(dataset)); IEnumerable <DateTime> startTimes = (await _legRepository.ListAsync(predicate)).Select(leg => leg.StartTime); _RetrainedEarliestDate = startTimes.Min(); _RetrainedLatestDate = startTimes.Max(); _LastRetrained = DateTime.Now; }
//sets the values in kmeansArr[] public static void runKMeans(ref Group[] gs) { int numGroups = gs.Count(); // Declaring and intializing array for K-Means double[][] observations = new double[numGroups][]; for (int i = 0; i < observations.Length; i++) { observations[i] = new double[2]; observations[i][0] = gs[i].destination.coords[0]; observations[i][1] = gs[i].destination.coords[1]; } int numClusters = (gs.Count() / 6) + 1; //THIS WHAT WE WANT? KMeans km = new KMeans(numClusters); KMeansClusterCollection clust = km.Learn(observations); kmeansArr = clust.Decide(observations); }
static void Main(string[] args) { var filePath = @"D:\Repo\Magisterka\zbiory\glass1.dat"; string [][] data = File.ReadLines(filePath).Where(line => line != "").Select(x => x.Split(';')).ToArray(); double [][] dataNumber = ConvertArray(data); Dictionary <int, int> population = GetPopulationOfClassess(dataNumber); int majorityLabel = GetLabelOfMajorityClass(population); int minorityLabel = GetLabelOfMinorityClass(population); int majorityPopulation = population[majorityLabel]; int minorityPopulation = population[minorityLabel]; double[][] majorityClass = GetWholeClass(majorityLabel, dataNumber, majorityPopulation); double[][] minorityClass = GetWholeClass(minorityLabel, dataNumber, minorityPopulation); double[][] majorityWithoutLabels = GetSamplesWithoutLabels(majorityClass); KMeans kmeans = new KMeans(k: minorityPopulation); var clusters = kmeans.Learn(majorityWithoutLabels); double[][] centroids = clusters.Centroids; WriteToFile(centroids, minorityClass, majorityLabel); }
private List <Point3d> KMeansReduce(List <Point3d> points, Mesh m) { List <Point3d> reduced = new List <Point3d>(); Polyline[] outlines = m.GetOutlines(Plane.WorldXY); double area = 0; foreach (Polyline pl in outlines) { AreaMassProperties amp = AreaMassProperties.Compute(pl.ToNurbsCurve()); area += amp.Area; } int nClusters = (int)(area / 1000000); List <double[]> pts2d = new List <double[]>(); if (nClusters == 0) { double minZ = points.Min(x => x.Z); reduced.Add(points.Find(p => p.Z == minZ)); return(reduced); } foreach (Point3d p in points) { pts2d.Add(new double[] { p.X, p.Y }); } if (points.Count < nClusters) { return(points); } KMeans kmeans = new KMeans(k: nClusters); // Compute and retrieve the data centroids var clusters = kmeans.Learn(pts2d.ToArray()); // Use the centroids to parition all the data int[] labels = clusters.Decide(pts2d.ToArray()); return(reduced); }
// Called by LandMap.GetZones (), returns number of subregions public int ClusterLocationsAccordKMeans(MapPoint[,] points) { // K-means cluster algorithm to separate locations in the regions int regionId = 0; for (int isleId = 0; isleId < regions.Count; isleId++) { MapRegion region = regions[isleId]; double[][] tileLocations = new double[region.turf.Count][]; for (int i = 0; i < tileLocations.Length; i++) { tileLocations[i] = new double[2]; tileLocations[i][0] = region.turf[i].x; tileLocations[i][1] = region.turf[i].y; } int k = InitializeNumOfK(region.turf.Count); Debug.Log(k + " centroid(s)"); KMeans kmeans = new KMeans(k); KMeansClusterCollection clusters = kmeans.Learn(tileLocations); int[] labels = clusters.Decide(tileLocations); Debug.Log("Number of labels (clusters) = " + labels.Length); for (int i = 0; i < labels.Length; i++) { points[(int)tileLocations[i][0], (int)tileLocations[i][1]].areaValue = regionId + labels[i]; } regionId += k; } return(regionId); }
public static Output Clustering(double[,] patches, int numberOfClusters, string pathToCentroidFile) { // "Generator.Seed" sets a random seed for the framework's main internal number generator, which // gets a reference to the random number generator used internally by the Accord.NET classes and methods. // If set to a value less than or equal to zero, all generators will start with the same fixed seed, even among multiple threads. // If set to any other value, the generators in other threads will start with fixed, but different, seeds. // this method should be called before other computations. Accord.Math.Random.Generator.Seed = 0; KMeans kmeans = new KMeans(k: numberOfClusters) { UseSeeding = Seeding.KMeansPlusPlus, Distance = default(Cosine), }; var clusters = kmeans.Learn(patches.ToJagged()); // get the cluster size Dictionary <int, double> clusterIdSize = new Dictionary <int, double>(); Dictionary <int, double[]> clusterIdCentroid = new Dictionary <int, double[]>(); foreach (var clust in clusters.Clusters) { clusterIdSize.Add(clust.Index, clust.Proportion); clusterIdCentroid.Add(clust.Index, clust.Centroid); } Csv.WriteToCsv(pathToCentroidFile.ToFileInfo(), clusterIdCentroid); var output = new Output() { ClusterIdCentroid = clusterIdCentroid, ClusterIdSize = clusterIdSize, Clusters = clusters, }; return(output); }
public int[] KMeansClustering(List <double> column) { var orderedColumn = column.OrderBy(x => x).ToList(); double maxValue = orderedColumn.Last(); double smallestValue = orderedColumn.First(); KMeans kmeans = new KMeans(k: 10); double[][] data = new double[column.Count][]; for (int i = 0; i < column.Count; i++) { data[i] = new double[] { 1, column[i] }; } // Compute and retrieve the data centroids var clusters = kmeans.Learn(data); // Use the centroids to parition all the data int[] labels = clusters.Decide(data); return(labels); }
private void cluster(ushort j) { cvsbmp = UtilFn.BitmapImage2Bitmap(images[j]); var imageToArray = new ImageToArray(min: -1, max: +1); var arrayToImage = new ArrayToImage(cvsbmp.Width, cvsbmp.Height, min: -1, max: +1); int kk; double[][] pixels; imageToArray.Convert(cvsbmp, out pixels); try { kk = Int16.Parse(kCluster.Text); } catch (Exception) { return; } if (kk < 1) { return; } KMeans kmeans = new KMeans(k: kk) { Distance = new SquareEuclidean(), Tolerance = 0.05 }; var clusters = kmeans.Learn(pixels); int[] labels = clusters.Decide(pixels); double[][] replaced = pixels.Apply((x, i) => clusters.Centroids[labels[i]]); Bitmap result; arrayToImage.Convert(replaced, out result); imagesEdited.Add(converter.Convert(result, Type.GetType("BitmapImage"), null, null) as BitmapImage); }
private void runKMeans() { int k = (int)numClusters.Value; Bitmap image = img; ImageToArray imageToArray = new ImageToArray(min: -1, max: +1); ArrayToImage arrayToImage = new ArrayToImage(image.Width, image.Height, min: -1, max: +1); double[][] pixels; imageToArray.Convert(image, out pixels); KMeans kmeans = new KMeans(k, new SquareEuclidean()) { Tolerance = 0.05 }; int[] idx = kmeans.Learn(pixels).Decide(pixels); pixels.Apply((x, i) => kmeans.Clusters.Centroids[idx[i]], result: pixels); Bitmap result; arrayToImage.Convert(pixels, out result); pictureBox1.Image = result; }
private static string GenerateColorPalette(byte[] imgData, int numClusters) { var img = Cv2.ImDecode(imgData, ImreadModes.Color); var colors = new List <Vec3b>(); var mat3 = new Mat <Vec3b>(img); var indexer = mat3.GetIndexer(); for (int y = 0; y < img.Height / 10; y++) { for (int x = 0; x < img.Width / 10; x++) { var color = indexer[y, x]; byte temp = color.Item0; color.Item0 = color.Item2; color.Item2 = temp; indexer[y, x] = color; colors.Add(indexer[y, x]); } } var observations = colors.Select(c => new double[] { c.Item0, c.Item1, c.Item2 }).ToArray(); var kmeans = new KMeans(numClusters, new SquareEuclidean()) { Tolerance = 0.05 }; var clusters = kmeans.Learn(observations); var computedColors = clusters.Select(c => new Color { R = (byte)Math.Round(c.Centroid[0], 0), G = (byte)Math.Round(c.Centroid[1], 0), B = (byte)Math.Round(c.Centroid[2], 0) }).ToList(); string json = JsonConvert.SerializeObject(computedColors, Formatting.Indented); return(json); }
/// <summary> /// Runs the K-Means algorithm. /// </summary> /// private void runKMeans() { // Retrieve the number of clusters int k = (int)numClusters.Value; // Load original image Bitmap image = Properties.Resources.leaf; // Create converters ImageToArray imageToArray = new ImageToArray(min: -1, max: +1); ArrayToImage arrayToImage = new ArrayToImage(image.Width, image.Height, min: -1, max: +1); // Transform the image into an array of pixel values double[][] pixels; imageToArray.Convert(image, out pixels); // Create a K-Means algorithm using given k and a // square Euclidean distance as distance metric. KMeans kmeans = new KMeans(k, new SquareEuclidean()) { Tolerance = 0.05 }; // Compute the K-Means algorithm until the difference in // cluster centroids between two iterations is below 0.05 int[] idx = kmeans.Learn(pixels).Decide(pixels); // Replace every pixel with its corresponding centroid pixels.Apply((x, i) => kmeans.Clusters.Centroids[idx[i]], result: pixels); // Show resulting image in the picture box Bitmap result; arrayToImage.Convert(pixels, out result); pictureBox.Image = result; }
public void learn_test() { #region doc_learn Accord.Math.Random.Generator.Seed = 0; // Declare some observations double[][] observations = { new double[] { -5, -2, -1 }, new double[] { -5, -5, -6 }, new double[] { 2, 1, 1 }, new double[] { 1, 1, 2 }, new double[] { 1, 2, 2 }, new double[] { 3, 1, 2 }, new double[] { 11, 5, 4 }, new double[] { 15, 5, 6 }, new double[] { 10, 5, 6 }, }; // Create a new K-Means algorithm KMeans kmeans = new KMeans(k: 3); // Compute and retrieve the data centroids var clusters = kmeans.Learn(observations); // Use the centroids to parition all the data int[] labels = clusters.Decide(observations); #endregion Assert.AreEqual(labels[0], labels[1]); Assert.AreEqual(labels[2], labels[3]); Assert.AreEqual(labels[2], labels[4]); Assert.AreEqual(labels[2], labels[5]); Assert.AreEqual(labels[6], labels[7]); Assert.AreEqual(labels[6], labels[8]); Assert.AreNotEqual(labels[0], labels[2]); Assert.AreNotEqual(labels[2], labels[6]); Assert.AreNotEqual(labels[0], labels[6]); int[] labels2 = kmeans.Clusters.Decide(observations); Assert.IsTrue(labels.IsEqual(labels2)); // the data must not have changed! double[][] orig = { new double[] { -5, -2, -1 }, new double[] { -5, -5, -6 }, new double[] { 2, 1, 1 }, new double[] { 1, 1, 2 }, new double[] { 1, 2, 2 }, new double[] { 3, 1, 2 }, new double[] { 11, 5, 4 }, new double[] { 15, 5, 6 }, new double[] { 10, 5, 6 }, }; Assert.IsTrue(orig.IsEqual(observations)); var c = new KMeansClusterCollection.KMeansCluster[clusters.Count]; int i = 0; foreach (var cluster in clusters) { c[i++] = cluster; } for (i = 0; i < c.Length; i++) { Assert.AreSame(c[i], clusters[i]); } }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { int i, j, k; bool IsPointData = false; GH_Structure <IGH_Goo> data = new GH_Structure <IGH_Goo>(); GH_Structure <IGH_GeometricGoo> geo = new GH_Structure <IGH_GeometricGoo>(); List <int> numCluster = new List <int>(); if (!DA.GetDataTree(0, out data)) { return; } if (!DA.GetDataTree(1, out geo)) { return; } if (!DA.GetDataList(2, numCluster)) { return; } data.Simplify(GH_SimplificationMode.CollapseAllOverlaps); DataTree <IGH_Goo> outputData = new DataTree <IGH_Goo>(); DataTree <IGH_GeometricGoo> outputGeo = new DataTree <IGH_GeometricGoo>(); DataTree <Point3d> outputCentroids = new DataTree <Point3d>(); for (i = 0; i < data.Branches.Count; i++) { double[] x = new double[data.Branches[i].Count]; double[] y = new double[data.Branches[i].Count]; double[] z = new double[data.Branches[i].Count]; for (j = 0; j < data.Branches[i].Count; j++) { if (data.Branches[i][j] is GH_Point) { IsPointData = true; GH_Point target = new GH_Point(); if (GH_Convert.ToGHPoint(data.Branches[i][j], GH_Conversion.Both, ref target)) { x[j] = target.Value.X; y[j] = target.Value.Y; z[j] = target.Value.Z; } } else { break; } } if (IsPointData) { List <double[]> datalist = new List <double[]> { x, y, z }; double[][] _data = ArrayConvert.To2DArray(datalist); KMeans m = new KMeans(numCluster[i]); KMeansClusterCollection cluster = m.Learn(_data); int[] labels = cluster.Decide(_data); double[][] centroids = m.Centroids; for (j = 0; j < data.Branches[i].Count; j++) { GH_Path path = new GH_Path(i, labels[j]); outputData.Add(data.Branches[i][j], path); outputGeo.Add(geo.Branches[i][j], path); } for (k = 0; k < centroids.Length; k++) { outputCentroids.Add(new Point3d(centroids.ElementAt(k).ElementAt(0), centroids.ElementAt(k).ElementAt(1), centroids.ElementAt(k).ElementAt(2)), new GH_Path(k)); } } else { break; } } if (!IsPointData) { GH_Path oldPath = new GH_Path(); GH_Path newPath = new GH_Path(); int DataGroupCount = 0; for (i = 0; i < data.PathCount; i++) { if (data.Paths[i].Indices.Length == 1) { DataGroupCount = 1; break; } else { int[] pp = new int[data.Paths[i].Indices.Length - 1]; for (j = 0; j < data.Paths[i].Indices.Length - 1; j++) { pp[j] = data.Paths[i].Indices[j]; } newPath.Indices = pp; if (newPath != oldPath) { DataGroupCount++; oldPath = newPath; } newPath = new GH_Path(); } } for (i = 0; i < DataGroupCount; i++) { List <double[]> datalist = new List <double[]>(); for (j = 0; j < data.Branches.Count / DataGroupCount; j++) { double[] values = new double[data.Branches[DataGroupCount * i + j].Count]; for (k = 0; k < data.Branches[DataGroupCount * i + j].Count; k++) { if (data.Branches[DataGroupCount * i + j][k] is GH_Number) { if (GH_Convert.ToDouble(data.Branches[DataGroupCount * i + j][k], out double value, GH_Conversion.Both)) { values[k] = value; } } else { break; } } datalist.Add(values); } double[][] _data = ArrayConvert.ToDoubleArray(datalist); KMeans m = new KMeans(numCluster[0]); KMeansClusterCollection cluster = m.Learn(_data); int[] labels = cluster.Decide(_data); for (j = 0; j < labels.Length; j++) { List <IGH_Goo> numbers = new List <IGH_Goo>(); List <IGH_GeometricGoo> geos = new List <IGH_GeometricGoo>(); for (k = 0; k < data.Branches[DataGroupCount * i + j].Count; k++) { numbers.Add(data.Branches[DataGroupCount * i + j][k]); geos.Add(geo.Branches[DataGroupCount * i + j][k]); } GH_Path path = new GH_Path(i, j, labels[j]); outputData.AddRange(numbers, path); outputGeo.AddRange(geos, path); } } } DA.SetDataTree(0, outputData); DA.SetDataTree(1, outputGeo); DA.SetDataTree(2, outputCentroids); }
/// <summary> /// Train on number of clusters using gap statistic /// </summary> private async Task ComputeK(int maxK = 100, int B = 10, int driverID = 0, DateTime?startDate = null, DateTime?endDate = null) { double[] Wk = new double[maxK]; double[][] Wref_kb = new double[maxK][]; double[] Gap = new double[maxK]; double[] sd = new double[maxK]; KMeansClusterCollection[] clusterCollections = new KMeansClusterCollection[maxK]; // obtain dataset IEnumerable <Leg> legs = driverID == 0 ? await _legRepository.ListAsync() : await _legRepository.ListForDriverAsync(driverID); if (startDate == null) { startDate = DateTime.MinValue; } if (endDate == null) { endDate = DateTime.MaxValue; } legs = legs.Where(leg => leg.StartTime.CompareTo(startDate) >= 0 && leg.StartTime.CompareTo(endDate) < 0); double[][] dataset = GetDataset(legs); // first cluster the dataset varying K for (int k = 1; k <= maxK; k++) { KMeans kMeans = new KMeans(k) { // distance function for geographic coordinates Distance = new GeographicDistance() }; clusterCollections[k - 1] = kMeans.Learn(dataset); double[][][] clusterData = ClusterPoints(dataset, k, clusterCollections[k - 1]); // sum of pairwise distances Wk[k - 1] = ComputeWk(clusterData, clusterCollections[k - 1]); } // then generate the reference data sets double[] lowerBounds = new double[4]; double[] boxDimensions = new double[4]; for (int i = 0; i < 4; i++) { lowerBounds[i] = dataset.Select(l => l[i]).Min(); boxDimensions[i] = dataset.Select(l => l[i]).Max() - lowerBounds[i]; } CorrectLongitudeBounds(lowerBounds, boxDimensions, 1); CorrectLongitudeBounds(lowerBounds, boxDimensions, 3); Random random = new Random(); for (int k = 1; k <= maxK; k++) { Wref_kb[k - 1] = new double[B]; for (int c = 0; c < B; c++) { double[][] refDataset = new double[dataset.Length][]; for (int i = 0; i < refDataset.Length; i++) { double[] dataPoint = new double[4]; for (int j = 0; j < 4; j++) { dataPoint[j] = random.NextDouble() * boxDimensions[j] + lowerBounds[j]; if ((j == 1 || j == 3) && dataPoint[j] > 180) { dataPoint[j] -= 360; } } refDataset[i] = dataPoint; } // cluster reference dataset KMeans refKmeans = new KMeans(k); refKmeans.Distance = new GeographicDistance(); KMeansClusterCollection refClusters = refKmeans.Learn(refDataset); // points in each cluster double[][][] refClusterData = ClusterPoints(refDataset, k, refClusters); // compute pairwise distance sum for refDataset Wref_kb[k - 1][c] = ComputeWk(refClusterData, refClusters); } // compute gap statistic double l_avg = Wref_kb[k - 1].Select(x => Log(x)).Average(); Gap[k - 1] = l_avg - Log(Wk[k - 1]); sd[k - 1] = Sqrt(Wref_kb[k - 1].Select(x => (Log(x) - l_avg) * (Log(x) - l_avg)).Average()); // decide optimal k if (k > 1 && Gap[k - 2] >= Gap[k - 1] - sd[k - 1]) { ClusterCollection = clusterCollections[k - 2]; NumberOfClustersLastChanged = DateTime.Now; return; } } }
private static Tuple<double[][], double[][]> split(double[][] cluster, KMeans kmeans) { kmeans.Randomize(cluster); int[] idx = kmeans.Learn(cluster).Decide(cluster); List<double[]> a = new List<double[]>(); List<double[]> b = new List<double[]>(); for (int i = 0; i < idx.Length; i++) { if (idx[i] == 0) a.Add(cluster[i]); else b.Add(cluster[i]); } return Tuple.Create(a.ToArray(), b.ToArray()); }
public IActionResult Partition2(int partitionCount) { using (var db = new FusekiContext()) { var articles = db.Articles.Where(el => el.Published == true) .Include(el => el.Tags).Take(20).ToList(); //get a tag vector for each article. var allTags = new HashSet <string>(); //TODO: What happens if we remove all tags which only occur once. foreach (var article in articles) { foreach (var tag in article.Tags) { allTags.Add(tag.Name); } } var newAllTags = new HashSet <string>(); foreach (var t in allTags) { var relatedArticles = db.Articles.Where(el => el.Tags.Select(tag => tag.Name).Contains(t)); if (relatedArticles.Count() > 1) { newAllTags.Add(t); } } allTags = newAllTags; var allTagsOrdered = allTags.OrderBy(el => el); var obs = new List <List <double> >(); var dict = new Dictionary <string, object>(); foreach (var article in articles) { var articleTags = article.Tags.Select(el => el.Name); var vector = new List <double>(); foreach (var tag in allTagsOrdered) { if (articleTags.Contains(tag)) { vector.Add(1); } else { vector.Add(0); } } obs.Add(vector); } var vecvec = obs.Select(el => el.ToArray()).ToArray(); var kmeans = new KMeans(k: partitionCount); var clusters = kmeans.Learn(vecvec); dict["Kmeans Error"] = kmeans.Error; dict["dimensionality"] = kmeans.Dimension; dict["Iterations"] = kmeans.Iterations; dict["MaxIterations"] = kmeans.MaxIterations; dict["Tolerance"] = kmeans.Tolerance; int[] labels = clusters.Decide(vecvec); //labels is array[articleId] => partitionNumber var ii = 0; var psets = new List <PartitionSet <Article> >(); //this is totally fake. TODO: refactor these to be dumber - no need to have comparators etc. var dm = new DistanceMetrics <Article>((a, b) => Comparators.GetTagCommonality(a, b), (a, b) => Comparators.ArticleKeyLookup(a, b)); while (ii < partitionCount) { //TODO: is accord zero indexed? psets.Add(new PartitionSet <Article>(dm, ii)); ii++; } var index = 0; foreach (var l in labels) { var article = articles[index]; index++; psets[l].Add(article); } var partitiondata = new PartitionData <Article>(psets, dict); var model = new ArticlePartitionModel(partitiondata); return(View("ArticlePartitions", model)); } }
private void bClus_Click(object sender, RoutedEventArgs e) { int k = Int16.Parse(kKmeans.Text); int nB = classPoints[false].Count; int nR = classPoints[true].Count; if (nR + nB < 1) { textBlock.Text = "No dots."; return; } if (k < 1) { textBlock.Text = "Number of classes must be > 0."; return; } double[][] inputs = new double[nB + nR][]; int i = 0; foreach (System.Windows.Point p in classPoints[false]) { inputs[i++] = new double[] { p.X, p.Y }; } foreach (System.Windows.Point p in classPoints[true]) { inputs[i++] = new double[] { p.X, p.Y }; } KMeans kmeans = new KMeans(k: k); var clusters = kmeans.Learn(inputs); int[] labels = clusters.Decide(inputs); var centroids = clusters.Centroids; for (int j = 0; j < k; ++j) { Ellipse dot = new Ellipse(); dot.Width = 11; dot.Height = 11; dot.StrokeThickness = 2; dot.Fill = blackBrush; Canvas.SetTop(dot, centroids[j][1] - 5); Canvas.SetLeft(dot, centroids[j][0] - 5); cvsML.Children.Add(dot); double max = 0; for (int z = 0; z < labels.Length; ++z) { if (labels[z] == j) { double d = Math.Sqrt(Math.Pow(centroids[j][0] - inputs[z][0], 2) + Math.Pow(centroids[j][1] - inputs[z][1], 2)); if (d > max) { max = d; } } } Ellipse circle = new Ellipse(); circle.Width = 2 * max + 10; circle.Height = 2 * max + 10; circle.StrokeThickness = 2; circle.Stroke = blackBrush; Canvas.SetTop(circle, centroids[j][1] - max - 5); Canvas.SetLeft(circle, centroids[j][0] - max - 5); cvsML.Children.Add(circle); } }
// GET: DataAnalysis/KmeansAnalysis/id public async Task <IActionResult> KmeansAnalysis(int?id, int?numOfClusters) { if (id == null) { return(NotFound()); } var dataAnalysis = await _context.FilesInformation.FindAsync(id); if (dataAnalysis == null) { return(NotFound()); } string path = await _context.FilesInformation.Where(m => m.Id == id).Select(d => d.Path).FirstOrDefaultAsync(); CsvReader reader = new CsvReader(_appEnvironment.WebRootPath + path, hasHeaders: true); DataTable dataTable = reader.ToTable(); var headers = reader.GetFieldHeaders(); double[][] arrayOfData = dataTable.AsEnumerable().Select(x => new[] { Convert.ToDouble(x[headers[0]]), Convert.ToDouble(x[headers[1]]), Convert.ToDouble(x[headers[2]]) }).ToArray(); int numOfClustersOnPost = numOfClusters ?? default(int); if (numOfClusters == null) { numOfClustersOnPost = 3; } // Create a new K-Means algorithm KMeans kmeans = new KMeans(k: numOfClustersOnPost); // Compute and retrieve the data centroids var clusters = kmeans.Learn(arrayOfData); // Use the centroids to parition all the data int[] clusterId = clusters.Decide(arrayOfData); ViewBag.data = arrayOfData; ViewBag.columns = 3; ViewBag.rows = arrayOfData.Length; List <double> field1 = new List <double>(); List <double> field2 = new List <double>(); List <double> field3 = new List <double>(); for (int i = 0; i < ViewBag.data.Length; i++) { for (int j = 0; j < ViewBag.columns; j += 3) { field1.Add(ViewBag.data[i][j]); field2.Add(ViewBag.data[i][j + 1]); field3.Add(ViewBag.data[i][j + 2]); } } ViewBag.field1 = field1; ViewBag.field2 = field2; ViewBag.field3 = field3; ViewBag.nameField1 = headers[0]; ViewBag.nameField2 = headers[1]; ViewBag.nameField3 = headers[2]; ViewBag.clusters = clusterId; return(View()); }
/// <summary> /// Initializes the Gaussian Mixture Models using K-Means /// parameters as an initial parameter guess. /// </summary> /// private void btnInitialize_Click(object sender, EventArgs e) { // Creates and computes a new // K-Means clustering algorithm: kmeans = new KMeans(k); KMeansClusterCollection clustering = kmeans.Learn(observations); // Classify all instances in mixture data int[] classifications = clustering.Decide(observations); // Draw the classifications updateGraph(classifications); }
/** * Get related post for each post * Use k-means cluster algorithm */ public void PostetsRelatedAi() { // Get all posts from db var posts = (from p in db.Posts where p.Content.Length > 50 // Avoid uneccesary outliers select p).ToList(); // Create Array of all posts content string[] documents = (from p in db.Posts where p.Content.Length > 50 // Avoid uneccesary outliers select p.Content).ToArray(); ///Apply TF*IDF on the documents and get the resulting vectors. double[][] inputs = TFIDFEX.TFIDF.Transform(documents); inputs = TFIDFEX.TFIDF.Normalize(inputs); // Create a new K-Means algorithm with Posts/2 clusters (create couples) KMeans kmeans = new KMeans(Convert.ToInt32(posts.Count() / 2)); // Compute the algorithm, retrieving an integer array // containing the labels for each of the observations KMeansClusterCollection clusters = kmeans.Learn(inputs); int[] labels = clusters.Decide(inputs); // Create more handy list of clusters and their vectors var clustersList = new List <List <int> >(); for (int j = 0; j < Convert.ToInt32(posts.Count() / 2); j++) { clustersList.Add(labels.Select((s, i) => new { i, s }) .Where(t => t.s == j) .Select(t => t.i) .ToList()); } // Adjust all posts and thier related according to clustering results foreach (var clusetr in clustersList) { // Handle clusters with 2 and more vectors if (clusetr.Count() >= 2) { for (int i = 1; i < clusetr.Count(); i++) { // Attach each post in the cluster to it's neighbor posts[clusetr[i - 1]].relatedPost = posts[clusetr[i]].Title; } // Attach the last post to the first one in the list posts[clusetr.Last()].relatedPost = posts[clusetr.First()].Title; } // Handle clusters with only one vector else if (clusetr.Count() > 0) { // In case matching not found posts[clusetr.First()].relatedPost = null; } } // Update Changes in DB foreach (var p in posts) { db.Entry(p).State = EntityState.Modified; } db.SaveChanges(); }
public void learn_test_mixed() { #region doc_learn_mixed Accord.Math.Random.Generator.Seed = 0; // Declare some mixed discrete and continuous observations double[][] observations = { // (categorical) (discrete) (continuous) new double[] { 1, -1, -2.2 }, new double[] { 1, -6, -5.5 }, new double[] { 2, 1, 1.1 }, new double[] { 2, 2, 1.2 }, new double[] { 2, 2, 2.6 }, new double[] { 3, 2, 1.4 }, new double[] { 3, 4, 5.2 }, new double[] { 1, 6, 5.1 }, new double[] { 1, 6, 5.9 }, }; // Create a new codification algorithm to convert // the mixed variables above into all continuous: var codification = new Codification <double>() { CodificationVariable.Categorical, CodificationVariable.Discrete, CodificationVariable.Continuous }; // Learn the codification from observations var model = codification.Learn(observations); // Transform the mixed observations into only continuous: double[][] newObservations = model.ToDouble().Transform(observations); // (newObservations will be equivalent to) double[][] expected = { // (one hot) (discrete) (continuous) new double[] { 1, 0, 0, -1, -2.2 }, new double[] { 1, 0, 0, -6, -5.5 }, new double[] { 0, 1, 0, 1, 1.1 }, new double[] { 0, 1, 0, 2, 1.2 }, new double[] { 0, 1, 0, 2, 2.6 }, new double[] { 0, 0, 1, 2, 1.4 }, new double[] { 0, 0, 1, 4, 5.2 }, new double[] { 1, 0, 0, 6, 5.1 }, new double[] { 1, 0, 0, 6, 5.9 }, }; // Create a new K-Means algorithm KMeans kmeans = new KMeans(k: 3); // Compute and retrieve the data centroids var clusters = kmeans.Learn(observations); // Use the centroids to parition all the data int[] labels = clusters.Decide(observations); #endregion Assert.IsTrue(expected.IsEqual(newObservations, 1e-8)); Assert.AreEqual(3, codification.NumberOfInputs); Assert.AreEqual(5, codification.NumberOfOutputs); Assert.AreEqual(3, codification.Columns.Count); Assert.AreEqual("0", codification.Columns[0].ColumnName); Assert.AreEqual(3, codification.Columns[0].NumberOfSymbols); Assert.AreEqual(1, codification.Columns[0].NumberOfInputs); Assert.AreEqual(1, codification.Columns[0].NumberOfOutputs); Assert.AreEqual(3, codification.Columns[0].NumberOfClasses); Assert.AreEqual(CodificationVariable.Categorical, codification.Columns[0].VariableType); Assert.AreEqual("1", codification.Columns[1].ColumnName); Assert.AreEqual(1, codification.Columns[1].NumberOfSymbols); Assert.AreEqual(1, codification.Columns[1].NumberOfInputs); Assert.AreEqual(1, codification.Columns[1].NumberOfOutputs); Assert.AreEqual(1, codification.Columns[1].NumberOfClasses); Assert.AreEqual(CodificationVariable.Discrete, codification.Columns[1].VariableType); Assert.AreEqual("2", codification.Columns[2].ColumnName); Assert.AreEqual(1, codification.Columns[2].NumberOfSymbols); Assert.AreEqual(1, codification.Columns[2].NumberOfInputs); Assert.AreEqual(1, codification.Columns[2].NumberOfOutputs); Assert.AreEqual(1, codification.Columns[2].NumberOfClasses); Assert.AreEqual(CodificationVariable.Continuous, codification.Columns[2].VariableType); Assert.AreEqual(labels[0], labels[2]); Assert.AreEqual(labels[0], labels[3]); Assert.AreEqual(labels[0], labels[4]); Assert.AreEqual(labels[0], labels[5]); Assert.AreEqual(labels[6], labels[7]); Assert.AreEqual(labels[6], labels[8]); Assert.AreNotEqual(labels[0], labels[1]); Assert.AreNotEqual(labels[0], labels[6]); int[] labels2 = kmeans.Clusters.Decide(observations); Assert.IsTrue(labels.IsEqual(labels2)); var c = new KMeansClusterCollection.KMeansCluster[clusters.Count]; int i = 0; foreach (var cluster in clusters) { c[i++] = cluster; } for (i = 0; i < c.Length; i++) { Assert.AreSame(c[i], clusters[i]); } }
public (List <string> classes, KMeans kmeans, OneVsAllSupportVectorMachine svm) FinishLearning( int vectorLength, CancellationToken cancellationToken) { // count classes List <string> classes = new List <string>(this.features.Select(x => x.truth).ToLookup(x => x).Select(x => x.Key)); if (classes.Count < 2) { throw new ArgumentException(); } classes.Sort(); // count vectors int numberOfVectors = this.features.Sum(x => x.features.Count); // copy vectors Dictionary <IVector <float>, float> vectors = new Dictionary <IVector <float>, float>(numberOfVectors); for (int i = 0, ii = this.features.Count; i < ii; i++) { FeatureDetectors.Features f = this.features[i].features; for (int j = 0, jj = f.Count, len = f.Length, off = 0; j < jj; j++, off += len) { ////DenseVectorF vector = new DenseVectorF(len, f.X, off); SparseVectorF vector = SparseVectorF.FromDense(len, f.X, off); vectors[vector] = vectors.TryGetValue(vector, out float weight) ? weight + 1.0f : 1.0f; } } cancellationToken.ThrowIfCancellationRequested(); // learn k-means KMeans kmeans = KMeans.Learn( vectorLength, KMeansSeeding.Random, 2, default(EuclideanDistance), vectors.Keys.ToList(), vectors.Values.ToList(), cancellationToken); cancellationToken.ThrowIfCancellationRequested(); // learn svm Dictionary <string, int> classesLookup = classes.ToDictionary((x, i) => x, (x, i) => i); SequentualMinimalOptimization smo = new SequentualMinimalOptimization(new ChiSquare()) { Algorithm = SMOAlgorithm.LibSVM, Tolerance = 0.01f, }; List <float[]> svmx = new List <float[]>(this.features.Count); List <int> svmy = new List <int>(this.features.Count); for (int i = 0, ii = this.features.Count; i < ii; i++) { (FeatureDetectors.Features features, string truth) = this.features[i]; svmx.Add(PointsOfInterestClassifier.PrepareVector(kmeans, features, cancellationToken)); svmy.Add(classesLookup[truth]); } cancellationToken.ThrowIfCancellationRequested(); OneVsAllSupportVectorMachine svm = OneVsAllSupportVectorMachine.Learn( smo, classes.Count, svmx, svmy, null, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); return(classes, kmeans, svm); }
// GET: DataAnalysis/CombinedAnalysis/id public async Task <IActionResult> CombinedAnalysis(int?id, int?numOfClusters) { if (id == null) { return(NotFound()); } var dataAnalysis = await _context.FilesInformation.FindAsync(id); if (dataAnalysis == null) { return(NotFound()); } string path = await _context.FilesInformation.Where(m => m.Id == id).Select(d => d.Path).FirstOrDefaultAsync(); CsvReader reader = new CsvReader(_appEnvironment.WebRootPath + path, hasHeaders: true); double[][] actual = reader.ToJagged(); var pcaTool = new KernelPrincipalComponentAnalysis(); pcaTool.Learn(actual); pcaTool.NumberOfOutputs = 3; var outputMatrix = pcaTool.Transform(actual); int numOfClustersOnPost = numOfClusters ?? default(int); if (numOfClusters == null) { numOfClustersOnPost = 3; } KMeans kmeans = new KMeans(k: numOfClustersOnPost); var clusters = kmeans.Learn(outputMatrix); int[] clusterId = clusters.Decide(outputMatrix); ViewBag.columns = pcaTool.NumberOfOutputs; ViewBag.rows = outputMatrix.Length; List <double> PC1 = new List <double>(); List <double> PC2 = new List <double>(); List <double> PC3 = new List <double>(); for (int i = 0; i < outputMatrix.Length; i++) { for (int j = 0; j < ViewBag.columns; j += 3) { outputMatrix[i][j] = Math.Round(outputMatrix[i][j], 3); outputMatrix[i][j + 1] = Math.Round(outputMatrix[i][j + 1], 3); outputMatrix[i][j + 2] = Math.Round(outputMatrix[i][j + 2], 3); PC1.Add(outputMatrix[i][j]); PC2.Add(outputMatrix[i][j + 1]); PC3.Add(outputMatrix[i][j + 2]); } } ViewBag.data = outputMatrix; ViewBag.pc1 = PC1; ViewBag.pc2 = PC2; ViewBag.pc3 = PC3; ViewBag.clusters = clusterId; return(View()); }
/// <summary> /// Runs the K-Means algorithm. /// </summary> /// private void runKMeans() { // Retrieve the number of clusters int k = (int)numClusters.Value; // Load original image Bitmap image = Properties.Resources.leaf; // Create converters ImageToArray imageToArray = new ImageToArray(min: -1, max: +1); ArrayToImage arrayToImage = new ArrayToImage(image.Width, image.Height, min: -1, max: +1); // Transform the image into an array of pixel values double[][] pixels; imageToArray.Convert(image, out pixels); // Create a K-Means algorithm using given k and a // square Euclidean distance as distance metric. KMeans kmeans = new KMeans(k, new SquareEuclidean()) { Tolerance = 0.05 }; // Compute the K-Means algorithm until the difference in // cluster centroids between two iterations is below 0.05 int[] idx = kmeans.Learn(pixels).Decide(pixels); // Replace every pixel with its corresponding centroid pixels.Apply((x, i) => kmeans.Clusters.Centroids[idx[i]], result: pixels); // Show resulting image in the picture box Bitmap result; arrayToImage.Convert(pixels, out result); pictureBox.Image = result; }
public void objectClustering() { int applyClusterNum = clusterNum; if (applyClusterNum > objectidList.Count) { applyClusterNum = objectidList.Count; } var kmeans = new KMeans(k: applyClusterNum); double[][] points = new double[objectidList.Count][]; for (int i = 0; i < objectidList.Count; i++) { int id = objectidList[i]; points[i] = ObjList[idxbyObjid[id]].getStartingPoint(); } KMeansClusterCollection clusters = kmeans.Learn(points); int[] output = clusters.Decide(points); setStartingGroup(); int maxClusterLength = objectidList.Count / applyClusterNum; for (int i = 0; i < objectidList.Count; i++) { int id = objectidList[i]; //startingGroup[output[i]].Add(id); if (startingGroup[output[i]].idList.Count < maxClusterLength) { startingGroup[output[i]].Add(id); } else { for (int j = output[i]; j < applyClusterNum + output[i]; j++) { if (startingGroup[(j + 1) % applyClusterNum].idList.Count < maxClusterLength) { startingGroup[(j + 1) % applyClusterNum].Add(id); break; } } } //^ } //sort int maxFrameLength = 0; for (int k = 0; k < startingGroup.Count; k++) { startingGroup[k].sort(ref ObjList, ref idxbyObjid); int curFrameLength = startingGroup[k].getFrameLength(); if (maxFrameLength < curFrameLength) { maxFrameLength = curFrameLength; } } //set maxFrmae //MessageBox.Show(overlayFrameNum.ToString()); outputFrameNum = trackingBar.Maximum = maxFrameLength - 1; if (videoInfo3Flag == true) { strVideoInfo3 += "\nresult Frame: " + outputFrameNum; } videoInfo3Flag = false; labelVideoInfo3.Text = strVideoInfo3; labelProgress.Text = "Detection 100%\nTracking 100%\nOverlay 100%"; int min = outputFrameNum / analysisFPS / 60; int sec = outputFrameNum / analysisFPS % 60; labelEndTime.Text = min.ToString("00") + ":" + sec.ToString("00"); }
public void dayWorkSchedule(DateTime date) { Func <WorkSchedule, bool> predicat = (w => w.workSchedule_date == date); List <WorkSchedule> workSchedules = selectWorkSchedule(predicat); List <Distributors> alldistributors = new List <Distributors>(); List <Distributors> ezerList = new List <Distributors>(); foreach (WorkSchedule item in workSchedules) { ezerList = selectDistributors(d => d.distributors_id == item.distributor_id); if (ezerList.Count != 1) { throw new Exception("שגיאה בחיפוש אחרי מחלק זה"); } alldistributors.Add(ezerList[0]); } List <Recipients> allrecipients = recipientsPackageByDay(date); double[][] Coordinates = new double[allrecipients.Count][]; int i = 0; foreach (Recipients item in allrecipients) { Coordinates[i] = getLatLongFromAddress(item.recipients_address); i++; } // Create a new K-Means algorithm with 3 clusters KMeans kmeans = new KMeans(3); // Compute the algorithm, retrieving an integer array // containing the labels for each of the observations KMeansClusterCollection clusters = kmeans.Learn(Coordinates); // As a result, the first two observations should belong to the // same cluster (thus having the same label). The same should // happen to the next four observations and to the last three. int[] labels = clusters.Decide(Coordinates); List <Recipients> group0 = new List <Recipients>(); List <Recipients> group1 = new List <Recipients>(); List <Recipients> group2 = new List <Recipients>(); for (int k = 0; k < labels.Length; k++) { if (labels[k] == 0) { group0.Add(allrecipients[k]); } if (labels[k] == 1) { group1.Add(allrecipients[k]); } if (labels[k] == 2) { group2.Add(allrecipients[k]); } } double lat = 0; double lon = 0; double[] d0 = new double[2]; double[] d1 = new double[2]; double[] d2 = new double[2]; foreach (var item in group0) { d0 = getLatLongFromAddress(item.recipients_address); lat += d0[0]; lon += d0[1]; } d0[0] = lat / group0.Count; d0[1] = lon / group0.Count; lat = 0; lon = 0; foreach (var item in group1) { d1 = getLatLongFromAddress(item.recipients_address); lat += d1[0]; lon += d1[1]; } d1[0] = lat / group1.Count; d1[1] = lon / group1.Count; lat = 0; lon = 0; foreach (var item in group2) { d2 = getLatLongFromAddress(item.recipients_address); lat += d2[0]; lon += d2[1]; } d2[0] = lat / group2.Count; d2[1] = lon / group2.Count; // double[] d0 = getLatLongFromAddress(group0[0].recipients_address); // double[] d1 = getLatLongFromAddress(group1[0].recipients_address); // double[] d2 = getLatLongFromAddress(group2[0].recipients_address); double[,] distance = new double[3, 3]; for (i = 0; i < 3; i++) { double[] d3 = getLatLongFromAddress(alldistributors[i].distributors_address); for (int j = 0; j < 3; j++) { if (j == 0) { distance[i, j] = dalImp.addressCalculations.calculateDistance(d0, d3); } if (j == 1) { distance[i, j] = dalImp.addressCalculations.calculateDistance(d1, d3); } if (j == 2) { distance[i, j] = dalImp.addressCalculations.calculateDistance(d2, d3); } } } int [,] minIndex = new int[3, 3]; for (i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { minIndex[i, j] = findMinDist(distance[i, 0], distance[i, 1], distance[i, 2], j); } } if ((minIndex[0, 0] != minIndex[2, 0]) && (minIndex[0, 0] != minIndex[1, 0]) && (minIndex[2, 0] != minIndex[1, 0])) { if (minIndex[0, 0] == 0) { UpdateWorkSchedule(new WorkSchedule(alldistributors[0].distributors_id, date, group0)); if (minIndex[1, 0] == 1) { UpdateWorkSchedule(new WorkSchedule(alldistributors[1].distributors_id, date, group1)); UpdateWorkSchedule(new WorkSchedule(alldistributors[2].distributors_id, date, group2)); } else if (minIndex[1, 0] == 2) { UpdateWorkSchedule(new WorkSchedule(alldistributors[1].distributors_id, date, group2)); UpdateWorkSchedule(new WorkSchedule(alldistributors[2].distributors_id, date, group1)); } } else if (minIndex[0, 0] == 1) { UpdateWorkSchedule(new WorkSchedule(alldistributors[0].distributors_id, date, group1)); if (minIndex[1, 0] == 0) { UpdateWorkSchedule(new WorkSchedule(alldistributors[1].distributors_id, date, group0)); UpdateWorkSchedule(new WorkSchedule(alldistributors[2].distributors_id, date, group2)); } else if (minIndex[1, 0] == 2) { UpdateWorkSchedule(new WorkSchedule(alldistributors[1].distributors_id, date, group2)); UpdateWorkSchedule(new WorkSchedule(alldistributors[2].distributors_id, date, group0)); } } else if (minIndex[0, 0] == 2) { UpdateWorkSchedule(new WorkSchedule(alldistributors[0].distributors_id, date, group2)); if (minIndex[1, 0] == 0) { UpdateWorkSchedule(new WorkSchedule(alldistributors[1].distributors_id, date, group0)); UpdateWorkSchedule(new WorkSchedule(alldistributors[2].distributors_id, date, group1)); } else if (minIndex[1, 0] == 1) { UpdateWorkSchedule(new WorkSchedule(alldistributors[1].distributors_id, date, group1)); UpdateWorkSchedule(new WorkSchedule(alldistributors[2].distributors_id, date, group0)); } } } else { if ((minIndex[0, 0] == minIndex[2, 0]) && (minIndex[0, 0] == minIndex[1, 0]) && (minIndex[2, 0] == minIndex[1, 0])) { UpdateWorkSchedule(new WorkSchedule(alldistributors[minIndex[0, 0]].distributors_id, date, group0)); if ((minIndex[1, 1] == minIndex[2, 1])) { UpdateWorkSchedule(new WorkSchedule(alldistributors[minIndex[1, 1]].distributors_id, date, group1)); UpdateWorkSchedule(new WorkSchedule(alldistributors[minIndex[2, 2]].distributors_id, date, group2)); } else { UpdateWorkSchedule(new WorkSchedule(alldistributors[minIndex[1, 1]].distributors_id, date, group1)); UpdateWorkSchedule(new WorkSchedule(alldistributors[minIndex[2, 1]].distributors_id, date, group2)); } } else { int place; if (minIndex[1, 0] == minIndex[2, 0]) { UpdateWorkSchedule(new WorkSchedule(alldistributors[minIndex[0, 0]].distributors_id, date, group0)); place = minIndex[1, 1] + minIndex[1, 1] % 3; UpdateWorkSchedule(new WorkSchedule(alldistributors[minIndex[1, 0]].distributors_id, date, group1)); UpdateWorkSchedule(new WorkSchedule(alldistributors[place].distributors_id, date, group2)); } else { if (minIndex[0, 0] == minIndex[2, 0]) { UpdateWorkSchedule(new WorkSchedule(alldistributors[minIndex[1, 0]].distributors_id, date, group1)); place = minIndex[0, 0] + minIndex[1, 0] % 3; UpdateWorkSchedule(new WorkSchedule(alldistributors[minIndex[0, 0]].distributors_id, date, group1)); UpdateWorkSchedule(new WorkSchedule(alldistributors[place].distributors_id, date, group2)); } else { UpdateWorkSchedule(new WorkSchedule(alldistributors[minIndex[2, 0]].distributors_id, date, group2)); place = minIndex[0, 0] + minIndex[2, 0] % 3; UpdateWorkSchedule(new WorkSchedule(alldistributors[minIndex[1, 1]].distributors_id, date, group0)); UpdateWorkSchedule(new WorkSchedule(alldistributors[place].distributors_id, date, group1)); } } } } }
public void learn_test() { #region doc_learn Accord.Math.Random.Generator.Seed = 0; // Declare some observations double[][] observations = { new double[] { -5, -2, -1 }, new double[] { -5, -5, -6 }, new double[] { 2, 1, 1 }, new double[] { 1, 1, 2 }, new double[] { 1, 2, 2 }, new double[] { 3, 1, 2 }, new double[] { 11, 5, 4 }, new double[] { 15, 5, 6 }, new double[] { 10, 5, 6 }, }; double[][] orig = observations.MemberwiseClone(); // Create a new K-Means algorithm with 3 clusters KMeans kmeans = new KMeans(3); // Compute the algorithm, retrieving an integer array // containing the labels for each of the observations KMeansClusterCollection clusters = kmeans.Learn(observations); // As a result, the first two observations should belong to the // same cluster (thus having the same label). The same should // happen to the next four observations and to the last three. int[] labels = clusters.Decide(observations); #endregion Assert.AreEqual(labels[0], labels[1]); Assert.AreEqual(labels[2], labels[3]); Assert.AreEqual(labels[2], labels[4]); Assert.AreEqual(labels[2], labels[5]); Assert.AreEqual(labels[6], labels[7]); Assert.AreEqual(labels[6], labels[8]); Assert.AreNotEqual(labels[0], labels[2]); Assert.AreNotEqual(labels[2], labels[6]); Assert.AreNotEqual(labels[0], labels[6]); int[] labels2 = kmeans.Clusters.Nearest(observations); Assert.IsTrue(labels.IsEqual(labels2)); // the data must not have changed! Assert.IsTrue(orig.IsEqual(observations)); var c = new KMeansClusterCollection.KMeansCluster[clusters.Count]; int i = 0; foreach (var cluster in clusters) { c[i++] = cluster; } for (i = 0; i < c.Length; i++) { Assert.AreSame(c[i], clusters[i]); } }
public void learn_test_weights() { #region doc_learn_weights Accord.Math.Random.Generator.Seed = 0; // A common desire when doing clustering is to attempt to find how to // weight the different components / columns of a dataset, giving them // different importances depending on the end goal of the clustering task. // Declare some observations double[][] observations = { new double[] { -5, -2, -1 }, new double[] { -5, -5, -6 }, new double[] { 2, 1, 1 }, new double[] { 1, 1, 2 }, new double[] { 1, 2, 2 }, new double[] { 3, 1, 2 }, new double[] { 11, 5, 4 }, new double[] { 15, 5, 6 }, new double[] { 10, 5, 6 }, }; // Create a new K-Means algorithm KMeans kmeans = new KMeans(k: 3) { // For example, let's say we would like to consider the importance of // the first column as 0.1, the second column as 0.7 and the third 0.9 Distance = new WeightedSquareEuclidean(new double[] { 0.1, 0.7, 1.1 }) }; // Compute and retrieve the data centroids var clusters = kmeans.Learn(observations); // Use the centroids to parition all the data int[] labels = clusters.Decide(observations); #endregion Assert.AreEqual(labels[0], labels[2]); Assert.AreEqual(labels[0], labels[2]); Assert.AreEqual(labels[0], labels[3]); Assert.AreEqual(labels[0], labels[4]); Assert.AreEqual(labels[0], labels[4]); Assert.AreEqual(labels[6], labels[7]); Assert.AreEqual(labels[6], labels[8]); Assert.AreNotEqual(labels[0], labels[1]); Assert.AreNotEqual(labels[2], labels[6]); Assert.AreNotEqual(labels[0], labels[6]); int[] labels2 = kmeans.Clusters.Decide(observations); Assert.IsTrue(labels.IsEqual(labels2)); var c = new KMeansClusterCollection.KMeansCluster[clusters.Count]; int i = 0; foreach (var cluster in clusters) { c[i++] = cluster; } for (i = 0; i < c.Length; i++) { Assert.AreSame(c[i], clusters[i]); } }
/// <summary> /// Computes the optimal number of clusters for the given observations. /// </summary> /// <param name="observationMatrix">The matrix of observations.</param> /// <param name="initialClusterCount">The initial number of clusters to start with.</param> /// <param name="isAgentTrajectoryClustering"> /// Dictates whether the clustering that is being performed is specific to /// two-dimensional agent trajectories (otherwise, distance calculations assume one-dimensional observation vectors). /// </param> /// <param name="isGreedySilhouetteCalculation"> /// Dictates whether optimal clustering is based on number of clusters that /// maximize silhouette score until the first decrease in score (true), or based on the silhouette score calculated for /// a range of clusters with the number of clusters resulting in the maximum score used as the optimal number of /// clusters (false). /// </param> /// <param name="clusterRange">The range of clusters values for which to compute the silhouette width (optional).</param> /// <returns>The cluster assignments and their proportions (as well as other K-Means stats).</returns> private static KMeans DetermineOptimalClusters(double[][] observationMatrix, int initialClusterCount, bool isAgentTrajectoryClustering, bool isGreedySilhouetteCalculation, int clusterRange = 0) { var clusterSilhouetteMap = new Dictionary <int, double>(); double maxSilhouetteWidth; // Initialize current silhouette width double curSilhouetteWidth = 0; // Set the initial cluster count var clusterCount = initialClusterCount; do { // Set max silhouette with the value on the previous loop iteration (since it was an improvement) maxSilhouetteWidth = curSilhouetteWidth; // Increment cluster count clusterCount++; // TODO: The below logic is in support of a work-around to an Accord.NET bug wherein // TODO: an internal random number generator sometimes generates out-of-bounds values // TODO: (i.e. a probability that is not between 0 and 1) // TODO: https://github.com/accord-net/framework/issues/259 // Create a new k-means instance with the specified number of clusters and uniform seeding var kmeans = new KMeans(clusterCount) { UseSeeding = Seeding.Uniform }; // Determine the resulting clusters var clusters = kmeans.Learn(observationMatrix); // Compute the silhouette width for the current number of clusters curSilhouetteWidth = ComputeSilhouetteWidth(clusters, observationMatrix, isAgentTrajectoryClustering); // If this is non-greedy silhouette calculation, record the silhouette width associated with // the current number of clusters if (isGreedySilhouetteCalculation == false) { clusterSilhouetteMap.Add(clusterCount, curSilhouetteWidth); } // Continue to increment number of clusters while there is a silhouette width improvement // (in the case of greedy silhouette calculation) or we have reached the max cluster range, // and we have not yet reached a number of clusters equivalent to the number of observations } while ((isGreedySilhouetteCalculation ? curSilhouetteWidth >= maxSilhouetteWidth : clusterCount < clusterRange) && clusterCount < observationMatrix.Length); // If this is non-greedy silhouette calculation, set the cluster count to the number of clusters // within the given range that results in the highest silhouette width (i.e. highest cluster validity) if (isGreedySilhouetteCalculation == false) { clusterCount = clusterSilhouetteMap.FirstOrDefault(csm => csm.Value == clusterSilhouetteMap.Values.Max()).Key; } // TODO: The below logic is in support of a work-around to an Accord.NET bug wherein // TODO: an internal random number generator sometimes generates out-of-bounds values // TODO: (i.e. a probability that is not between 0 and 1) // TODO: https://github.com/accord-net/framework/issues/259 // Rerun kmeans for the final cluster count with uniform seeding var optimalClustering = new KMeans(clusterCount) { UseSeeding = Seeding.Uniform }; // Determine cluster assignments optimalClustering.Learn(observationMatrix); return(optimalClustering); }
static void Main() { Accord.Math.Random.Generator.Seed = 1232; // Declare some observations double[][] observations = { new double[] { 291.5, 81.5 }, new double[] { 316, 87.5 }, new double[] { 337, 92.5 }, new double[] { 367, 87 }, new double[] { 363.5, 102 }, new double[] { 378, 105 }, new double[] { 411, 108.5 }, new double[] { 428.5, 116.5 }, new double[] { 465.5, 120 }, new double[] { 477, 111.5 }, new double[] { 448.5, 124.5 }, new double[] { 276, 126.5 }, new double[] { 503.5, 129 }, new double[] { 474, 126.5 }, new double[] { 485.5, 129 }, new double[] { 293.5, 134.5 }, new double[] { 313, 138.5 }, new double[] { 333.5, 146.5 }, new double[] { 355, 147.5 }, new double[] { 373.5, 152.5 }, new double[] { 393, 160 }, new double[] { 413.5, 161 }, new double[] { 98.5, 327.5 }, new double[] { 113, 338.5 }, new double[] { 130.5, 344.5 }, new double[] { 146.5, 347.5 }, new double[] { 171, 355 }, new double[] { 189, 364.5 }, new double[] { 223.5, 372 }, new double[] { 208, 374.5 }, new double[] { 237, 365.5 }, new double[] { 74, 379 }, new double[] { 232, 379.5 }, new double[] { 262, 385.5 }, new double[] { 244, 384 }, new double[] { 92, 388.5 }, new double[] { 112, 395 }, new double[] { 131, 405 }, new double[] { 152, 408.5 }, new double[] { 170.5, 415.5 }, new double[] { 485, 421.5 }, new double[] { 546, 421.5 }, new double[] { 742, 421.5 }, new double[] { 189, 425 }, new double[] { 506.5, 424.5 }, new double[] { 528.5, 424.5 }, new double[] { 583, 424.5 }, new double[] { 604, 424.5 }, new double[] { 624.5, 424.5 }, new double[] { 653, 430 }, new double[] { 695, 424.5 }, new double[] { 764.5, 424.5 }, new double[] { 721, 425 }, new double[] { 208, 428.5 }, new double[] { 242, 436.5 }, new double[] { 267, 445 }, new double[] { 286.5, 452 }, }; //observations.Add(new double[][] { (double)2.8, 3.3 }); // Create a new K-Means algorithm KMeans kmeans = new KMeans(k: 3); // Compute and retrieve the data centroids var clusters = kmeans.Learn(observations); // Use the centroids to parition all the data int[] labels = clusters.Decide(observations); Console.WriteLine("Hello World!"); // Keep the console window open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); }
public ActionResult Index() { User usrCon = (User)HttpContext.Session["user"]; if (usrCon != null) { Accord.Math.Random.Generator.Seed = 0; List <Product> boughtP = (from prd in db.Products join perord in db.ProductsPerOrder on prd.ProductId equals perord.ProductId join ord in db.Orders on perord.OrderId equals ord.OrderId join usr in db.Users on ord.UserId equals usr.UserId where ord.isOpen == false && usr.UserId == usrCon.UserId select prd).ToList(); if (boughtP.Count <= 5) { return(View(db.Products.ToList())); } Dictionary <double, double> countDic = new Dictionary <double, double> { { 1, 0 }, { 2, 0 }, { 3, 0 }, { 4, 0 }, { 5, 0 } }; foreach (var p in boughtP) { countDic[p.ProductCategory.ProductCategoryID]++; } // Declare some observations double[][] observations = new double[boughtP.Count][]; for (int j = 0; j < boughtP.Count; j++) { observations[j] = new double[2]; } int i = 0, k = 0; foreach (var item in countDic) { for (int j = 0; j < countDic[i + 1]; j++) { observations[j + k][0] = item.Key; observations[j + k][1] = item.Value; } k = (int)countDic[i + 1] + k; i++; } // Create a new K-Means algorithm with 3 clusters KMeans kmeans = new KMeans(5); // Compute the algorithm, retrieving an integer array // containing the labels for each of the observations KMeansClusterCollection clusters = kmeans.Learn(observations); // As a result, the first two observations should belong to the // same cluster (thus having the same label). The same should // happen to the next four observations and to the last three. //int[] labels = clusters.Decide(/*observations);*/ int chosenCatId = (int)clusters.Clusters.SingleOrDefault(y => y.Proportion == clusters.Clusters.Max(x => x.Proportion)).Centroid[0]; return(View(db.Products.Where(x => x.ProductCategoryID == chosenCatId).ToList())); } return(View("~/Views/User/Login.cshtml")); }