Ejemplo n.º 1
1
        /// <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;
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 5
0
        //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);
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
    // 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);
        }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        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;
        }
Ejemplo n.º 13
0
        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);
        }
Ejemplo n.º 14
0
        /// <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;
        }
Ejemplo n.º 15
0
        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]);
            }
        }
Ejemplo n.º 16
0
        /// <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);
        }
Ejemplo n.º 17
0
        /// <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;
                }
            }
        }
Ejemplo n.º 18
0
        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());
        }
Ejemplo n.º 19
0
        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));
            }
        }
Ejemplo n.º 20
0
        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());
        }
Ejemplo n.º 22
0
        /// <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);
        }
Ejemplo n.º 23
0
        /**
         * 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();
        }
Ejemplo n.º 24
0
        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]);
            }
        }
Ejemplo n.º 25
0
            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());
        }
Ejemplo n.º 27
0
        /// <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;
        }
Ejemplo n.º 28
0
        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");
        }
Ejemplo n.º 29
0
        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));
                        }
                    }
                }
            }
        }
Ejemplo n.º 30
0
        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]);
            }
        }
Ejemplo n.º 31
0
        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);
        }
Ejemplo n.º 33
0
        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();
        }
Ejemplo n.º 34
0
        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"));
        }