Пример #1
0
        /// <summary>
        ///   Computes the most likely label of a new given point.
        /// </summary>
        ///
        /// <param name="input">A point to be classified.</param>
        /// <param name="scores">The distance score for each possible class.</param>
        ///
        /// <returns>The most likely label for the given point.</returns>
        ///
        public virtual int Compute(T input, out double[] scores)
        {
            // Compute all distances
            for (int i = 0; i < inputs.Length; i++)
            {
                distances[i] = distance.Distance(input, inputs[i]);
            }

            int[] idx = distances.Bottom(k, inPlace: true);

            scores = new double[classCount];

            for (int i = 0; i < idx.Length; i++)
            {
                int j = idx[i];

                int    label = outputs[j];
                double d     = distances[i];

                // Convert to similarity measure
                scores[label] += 1.0 / (1.0 + d);
            }

            // Get the maximum weighted score
            int result; scores.Max(out result);

            return(result);
        }
Пример #2
0
        public int Compute(double[] input, out double[] distances)
        {
            distances = new double[means.Length];
            for (int i = 0; i < distances.Length; i++)
            {
                distances[i] = distance.Distance(input, means[i]);
            }

            int imin;

            distances.Min(out imin);

            return(imin);
        }
Пример #3
0
        /// <summary>
        /// Get distance between two time series given a certain width.
        /// </summary>
        /// <param name="seriesA"></param>
        /// <param name="seriesB"></param>
        /// <param name="distance"></param>
        /// <param name="width"></param>
        /// <returns></returns>
        public static double Distance(List <T> seriesA, List <T> seriesB, IDistance <T> distance, int width)
        {
            // Initialize.
            var dtw = new double[seriesA.Count, seriesB.Count];

            for (var i = 0; i < seriesA.Count; i++)
            {
                for (var j = 0; j < seriesB.Count; j++)
                {
                    dtw[i, j] = Double.PositiveInfinity;
                }
            }

            dtw[0, 0] = 0;

            width = Math.Max(width, Math.Abs(seriesA.Count - seriesB.Count));

            // Calculate.
            for (var i = 1; i < seriesA.Count; i++)
            {
                for (var j = (int)Math.Max(1, i - width); j < Math.Min(seriesB.Count, i + width); j++)
                {
                    var cost = distance.Distance(seriesA[i], seriesB[j]);
                    dtw[i, j] = cost + Math.Min(dtw[i - 1, j], Math.Min(dtw[i, j - 1], dtw[i - 1, j - 1]));
                }
            }

            return(dtw[seriesA.Count - 1, seriesB.Count - 1]);
        }
Пример #4
0
        /// <summary>
        /// Get distance between two time series.
        /// </summary>
        /// <param name="seriesA"></param>
        /// <param name="seriesB"></param>
        /// <param name="distance"></param>
        /// <returns></returns>
        public static double Distance(List <T> seriesA, List <T> seriesB, IDistance <T> distance)
        {
            // Initialize.
            var dtw = new double[seriesA.Count + 1, seriesB.Count + 1];

            for (var i = 1; i < seriesA.Count; i++)
            {
                dtw[i, 0] = Double.PositiveInfinity;
            }

            for (var i = 1; i < seriesB.Count; i++)
            {
                dtw[0, i] = Double.PositiveInfinity;
            }

            dtw[0, 0] = 0;

            // Calculate.
            for (var i = 1; i <= seriesA.Count; i++)
            {
                for (var j = 1; j <= seriesB.Count; j++)
                {
                    var cost = distance.Distance(seriesA[i - 1], seriesB[j - 1]);
                    dtw[i, j] = cost + Math.Min(dtw[i - 1, j], Math.Min(dtw[i, j - 1], dtw[i - 1, j - 1]));
                }
            }

            return(dtw[seriesA.Count - 1, seriesB.Count - 1]);
        }
Пример #5
0
 internal static double[][] GetDistances(IDistance <double[], double[]> distance, double[][] points, double[][] centroids, int k, double[][] result)
 {
     for (int i = 0; i < result.Length; i++)
     {
         for (int j = 0; j < result[i].Length; j++)
         {
             result[i][j] = distance.Distance(points[j], centroids[GetIndex(k, i)]);
         }
     }
     return(result);
 }
 public void DistanceMatrix(List <Point> points)
 {
     for (var customer = 0; customer < points.Count; customer++)
     {
         var dist_other_customers = new Dictionary <int, double>(); //a list to add the distance between the customer i and customer j
         for (var other_customer = customer + 1; other_customer < points.Count; other_customer++)
         {                                                          //calculate the distance between customer i and all the customers j. except where a> b & b > a in order to avoid duplicate values.
             var distance = distanceType.Distance(points[customer].Data, points[other_customer].Data);
             dist_other_customers.Add(other_customer, distance);    //Add the current customer i and the distance between customer i and customer j to this list.
         }
         Distance_Matrix.Add(customer, dist_other_customers);       //add the result of all the distance between the customers.
     }
 }
Пример #7
0
        public void DistanceObjectToCentroids(List <Point> datapoints, List <Centroid> Centroids, IDistance distanceType)
        {
            // 1.foreach datapoint calculate the distance measure the distance of the centroids and datapoints.
            datapoints.ForEach(datapoint => {
                var centroidDistances = new List <(int, double)>();

                Centroids.ForEach(Centroid => {
                    //2. calculate the distance between the datapoint and the centroids.

                    //  var distanceCentroid =  new DistanceFactory().ChooseTypeDistance(Centroid.Points, datapoint.Data, distanceType);
                    var distanceCentroid = distanceType.Distance(Centroid.Points, datapoint.Data);

                    //3. Add the distances between the centroid and the datapoint into a list
                    centroidDistances.Add((Centroid.Id, distanceCentroid)); //Add the calculated distances between the customer and all centroids
                });

                //.4 take the centroid with the least distance compared to the centroid and set the id of the centroid to the datapoint.
                datapoint.Centroid = centroidDistances.OrderBy(centroid => centroid.Item2).First().Item1;
            });
        }
        public double CalcSSE(List <Centroid> Centroids, List <Point> datapoints, int iteration, IDistance distanceType)
        {
            double SSE = 0;

            for (int i = 0; i < Centroids.Count; i++)
            {
                var clusterSet = datapoints.Where(vector => vector.Centroid == i).ToList();

                foreach (var datapoint in clusterSet)
                {
                    SSE += Math.Pow(distanceType.Distance(Centroids[i].Points, datapoint.Data), 2);
                }
            }
            if (LowestSSE < SSE)
            {
                LowestSSE = SSE;
            }

            //   Console.WriteLine("SSE of iteration " + iteration + ":" + SSE);
            return(SSE);
        }
Пример #9
0
        public void getdistance_test()
        {
            #region doc_getdistance
            // Let's say you have been using the static Distance.Euclidean() method in
            // your code, and now you would like to obtain a reference to a class that
            // implements the IDistance interface for this same distance, such that you
            // could pass it to some other method in the framework:

            double[] x = new double[] { 2, 4, 1 };
            double[] y = new double[] { 0, 0, 0 };

            double a = Distance.Euclidean(x, y); // should be 4.58257569495584

            // Use the GetDistance method to obtain an IDistance that implements it:
            IDistance <double[]> obj = Distance.GetDistance <double[]>(Distance.Euclidean);

            // We can continue computing the same distances as before using:
            double b = obj.Distance(x, y); // should be 4.58257569495584
            #endregion

            double expected = 4.58257569495584;
            Assert.AreEqual(a, expected);
            Assert.AreEqual(b, expected);
        }
        /// <summary>
        ///   Reverts a set of projected data into it's original form. Complete reverse
        ///   transformation is not always possible and is not even guaranteed to exist.
        /// </summary>
        ///
        /// <remarks>
        /// <para>
        ///   This method works using a closed-form MDS approach as suggested by
        ///   Kwok and Tsang. It is currently a direct implementation of the algorithm
        ///   without any kind of optimization.
        /// </para>
        /// <para>
        ///   Reference:
        ///   - http://cmp.felk.cvut.cz/cmp/software/stprtool/manual/kernels/preimage/list/rbfpreimg3.html
        /// </para>
        /// </remarks>
        ///
        /// <param name="data">The kpca-transformed data.</param>
        /// <param name="neighbors">The number of nearest neighbors to use while constructing the pre-image.</param>
        ///
        public double[,] Revert(double[,] data, int neighbors)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (sourceCentered == null)
            {
                throw new InvalidOperationException("The analysis must have been computed first.");
            }

            if (neighbors < 2)
            {
                throw new ArgumentOutOfRangeException("neighbors", "At least two neighbors are necessary.");
            }

            // Verify if the current kernel supports
            // distance calculation in feature space.
            IDistance distance = kernel as IDistance;

            if (distance == null)
            {
                throw new NotSupportedException("Current kernel does not support distance calculation in feature space.");
            }


            int rows = data.GetLength(0);

            double[,] reversion = new double[rows, sourceCentered.GetLength(1)];

            // number of neighbors cannot exceed the number of training vectors.
            int nn = System.Math.Min(neighbors, sourceCentered.GetLength(0));


            // For each point to be reversed
            for (int p = 0; p < rows; p++)
            {
                // 1. Get the point in feature space
                double[] y = data.GetRow(p);

                // 2. Select nn nearest neighbors of the feature space
                double[,] X = sourceCentered;
                double[] d2  = new double[Result.GetLength(0)];
                int[]    inx = new int[Result.GetLength(0)];

                // 2.1 Calculate distances
                for (int i = 0; i < X.GetLength(0); i++)
                {
                    inx[i] = i;
                    d2[i]  = distance.Distance(y, Result.GetRow(i).Submatrix(y.Length));
                }

                // 2.2 Order them
                Array.Sort(d2, inx);

                // 2.3 Select nn neighbors
                inx = inx.Submatrix(nn);
                X   = X.Submatrix(inx).Transpose(); // X is in input space
                d2  = d2.Submatrix(nn);             // distances in input space


                // 3. Perform SVD
                //    [U,L,V] = svd(X*H);

                // TODO: If X has more columns than rows, the SV decomposition should be
                //  computed on the transpose of X and the left and right vectors should
                //  be swapped. This should be fixed after more unit tests are elaborated.
                SingularValueDecomposition svd = new SingularValueDecomposition(X);
                double[,] U = svd.LeftSingularVectors;
                double[,] L = Matrix.Diagonal(nn, svd.Diagonal);
                double[,] V = svd.RightSingularVectors;


                // 4. Compute projections
                //    Z = L*V';
                double[,] Z = L.Multiply(V.Transpose());


                // 5. Calculate distances
                //    d02 = sum(Z.^2)';
                double[] d02 = Matrix.Sum(Matrix.ElementwisePower(Z, 2));


                // 6. Get the pre-image using z = -0.5*inv(Z')*(d2-d02)
                double[,] inv = Matrix.PseudoInverse(Z.Transpose());

                double[] z = (-0.5).Multiply(inv).Multiply(d2.Subtract(d02)).Submatrix(U.GetLength(0));


                // 8. Project the pre-image on the original basis
                //    using x = U*z + sum(X,2)/nn;
                double[] x = (U.Multiply(z)).Add(Matrix.Sum(X.Transpose()).Multiply(1.0 / nn));


                // 9. Store the computed pre-image.
                for (int i = 0; i < reversion.GetLength(1); i++)
                {
                    reversion[p, i] = x[i];
                }
            }



            // if the data has been standardized or centered,
            //  we need to revert those operations as well
            if (this.Method == AnalysisMethod.Standardize)
            {
                // multiply by standard deviation and add the mean
                for (int i = 0; i < reversion.GetLength(0); i++)
                {
                    for (int j = 0; j < reversion.GetLength(1); j++)
                    {
                        reversion[i, j] = (reversion[i, j] * StandardDeviations[j]) + Means[j];
                    }
                }
            }
            else if (this.Method == AnalysisMethod.Center)
            {
                // only add the mean
                for (int i = 0; i < reversion.GetLength(0); i++)
                {
                    for (int j = 0; j < reversion.GetLength(1); j++)
                    {
                        reversion[i, j] = reversion[i, j] + Means[j];
                    }
                }
            }


            return(reversion);
        }