/// <summary>
        /// This method reads the training data and calculates a variety of statistical data about each column.
        /// </summary>
        public static MetricStatistics UnderstandData(DataSetColumns dataSetColumns)
        {
            //Calculate and output the statistics for your pleasure
            var stats = MetricStatistics.CalculateMetricStatisticsAsync(dataSetColumns.TimeSeries, DateTime.Now, TimeSpan.FromSeconds(1)).Result;

            Console.WriteLine("Time Series Statistics:");
            Console.WriteLine(stats.ToString());
            return(stats);
        }
Example #2
0
        /// <summary>
        /// Computes statistics for a data serie (metric)
        /// </summary>
        /// <param name="values">Serie of data</param>
        /// <param name="startTime">Begining of the time period the statistics are computed for</param>
        /// <param name="duration">Length of the time period the statistics are computed for</param>
        /// <returns>Computed statistics</returns>
        public static Task <MetricStatistics> CalculateMetricStatisticsAsync(double[] values, DateTime startTime, TimeSpan duration)
        {
            if (values == null || values.Length < RequiredValuesCountForComputation)
            {
                throw new ArgumentException($"{nameof(values)} is expected to be not null and have a length >= {RequiredValuesCountForComputation}.");
            }

            return(Task.Run(() =>
            {
                var retval = new MetricStatistics
                {
                    StartTime = startTime,
                    Duration = duration
                };

                var sortedArray = new double[values.Length];
                Array.Copy(values, sortedArray, values.Length);
                Array.Sort(sortedArray);

                var slopeIntercept = CalculateSlope(values);

                retval.Slope = slopeIntercept.Item1;
                retval.SlopeYIntercept = slopeIntercept.Item2;
                retval.MeanSquaredError = slopeIntercept.Item3;

                retval.Maximum = sortedArray[sortedArray.Length - 1];
                retval.Minimum = sortedArray[0];
                retval.Count = sortedArray.Length;
                retval.Sum = sortedArray.Sum();
                retval.Mean = retval.Sum / retval.Count;

                var quartiles = GetQuartiles(sortedArray);
                retval.Median = quartiles.Item2;
                retval.FirstQuartile = quartiles.Item1;
                retval.ThirdQuartile = quartiles.Item3;

                var stdDevSum = sortedArray.Sum(i => Math.Pow(i - retval.Mean, 2));
                retval.VarianceSum = stdDevSum;
                retval.Variance = stdDevSum / (retval.Count - 1);
                retval.StandardDeviation = Math.Sqrt(retval.Variance);
                retval.GesdValue = retval.StandardDeviation < double.Epsilon
                    ? 0.0
                    : Math.Max(retval.Mean - retval.Minimum, retval.Maximum - retval.Mean) / retval.StandardDeviation;

                var skewnessValue = values.Sum(d => Math.Pow(d - retval.Mean, 3));
                var kurtosisValue = values.Sum(d => Math.Pow(d - retval.Mean, 4));
                retval.Kurtosis = kurtosisValue / retval.Count / Math.Pow(retval.Variance, 2) - 3;
                retval.Skewness = Math.Sqrt((long)retval.Count * ((long)retval.Count - 1)) / (retval.Count - 2) *
                                  (skewnessValue / retval.Count) / Math.Pow(retval.StandardDeviation, 3);

                //sorted array will now contain sorted values of absolute deviation
                for (int i = 0; i < sortedArray.Length; i++)
                {
                    sortedArray[i] = Math.Abs(sortedArray[i] - retval.Median);
                }

                Array.Sort(sortedArray);

                retval.MedianAbsoluteDeviation = MedianOfSortedArrayRange(sortedArray, 0, sortedArray.Length - 1);

                retval.Cardinality = values.Distinct().Count();
                retval.CardinalityRatio = (double)retval.Cardinality / retval.Count;

                return retval;
            }));
        }