예제 #1
0
        private static void TestMath()
        {
            var observed = new double[] { 1, 2, 3, 4, 5 };
            var modelled = new double[] { 1.1, 2.1, 3.1, 4.1, 5.1 };

            var a = GoodnessOfFit.CoefficientOfDetermination(observed, modelled);
            var b = GoodnessOfFit.RSquared(observed, modelled);
        }
        CalculateCoefficientOfDetermination(IModelledFunction modelledFunction,
                                            IEnumerable <double> observedValues)
        {
            double coefficientOfDetermination = GoodnessOfFit.CoefficientOfDetermination(
                observedValues, modelledFunction.Calculate(observedValues)
                );

            return(modelledFunction, coefficientOfDetermination);
        }
예제 #3
0
        /// <summary>
        /// Calculates adjusted coefficient of determination value for a fitted model.
        /// </summary>
        /// <param name="y">List containing the response values.</param>
        /// <param name="x">List containing lists for all explanatory variables.</param>
        /// <returns>Coefficient of determination adjusted with number of explanatory variables
        /// and observations.</returns>
        /// <exception cref="MathError">Thrown when parameter lists are of different length.</exception>
        /// <exception cref="ArgumentException">Thrown when matrix created from parameters is not valid.</exception>
        public static double AdjustedR2(List <double> y, List <List <double> > x)
        {
            List <double> fitted;
            int           n = y.Count;
            int           k = x.Count;

            fitted = FittedValues(y, x);

            double R2 = GoodnessOfFit.CoefficientOfDetermination(fitted, y);

            return(1 - (((1 - R2) * (n - 1)) / (n - k - 1)));
        }
 public ModelScore(int nParams, Func<double, double> predictor, double[] x, double[] observed) : this()
 {
     int k = nParams, n = x.Length;
     var predicted = x.Select(predictor).ToArray();
     Rss = predicted.Zip(observed, (p, o) => Square(p - o)).Sum();
     Mse = Rss / n;
     Rmse = Math.Sqrt(Mse);
     var observedMean = observed.Average();
     var tss = Math.Sqrt(observed.Select(d => Square(d - observedMean)).Sum());
     R2 = GoodnessOfFit.CoefficientOfDetermination(predicted, observed);
     Aic = CalcAic(k, n, Rss);
     AicC = CalcAicC(k, n, Aic);
     // Note that AIC tells nothing about the absolute quality of a model, only the quality relative to other models.
     // Lets compare the rss to original values to approve only good accuracy
 }
예제 #5
0
        private List <BalancePointPair> CalculateLinearRegression(List <BalancePointPair> allBalancePointPairs, WthNormalParams normalParamsKey)
        {
            var updatedBalancePointPairs = new List <BalancePointPair>();

            var allBalancePointGroups = allBalancePointPairs.GroupBy(s => new { s.CoolingBalancePoint, s.HeatingBalancePoint });

            foreach (var group in allBalancePointGroups)
            {
                List <BalancePointPair> IdenticalBalancePointPairsForAllReadings = group.ToList();

                int readingsCount           = IdenticalBalancePointPairsForAllReadings.Count;
                BalancePointPair _pointPair = IdenticalBalancePointPairsForAllReadings.First();

                bool NonWeatherDependant = (normalParamsKey.B2_Original == 0 && normalParamsKey.B4_Original == 0);

                //List<double> expUsageDaily = new List<double>();
                //List<double> hddsDaily = new List<double>();
                //List<double> cddsDaily = new List<double>();
                //List<double> actualUsageDaily = new List<double>();
                double[] fullXData = new double[readingsCount];
                //double[] fullXData_Original = new double[12 * balancePointPairGroup.Count];
                double[] xDays        = new double[readingsCount];
                double[] fullYData    = new double[readingsCount];
                double[] fullYDataAvg = new double[readingsCount];

                //double?[] hddsDaily = new double?[readingsCount * _pointPair.DaysInNormalYear];
                //double?[] cddsDaily = new double?[readingsCount * _pointPair.DaysInNormalYear];

                //double[][] hcddMatrix = new double[2][];

                //hcddMatrix[0] = new double[readingsCount];
                //hcddMatrix[1] = new double[readingsCount];

                double[][] hcddMatrix = new double[readingsCount][];

                foreach (BalancePointPair balancePointPair in IdenticalBalancePointPairsForAllReadings)
                {
                    //double[] hddsDailyAvgInReading = new double[readingsCount];
                    //double[] cddsDailyAvgInReading = new double[readingsCount];
                    //expUsageDaily.Add(Convert.ToDouble(balancePointPair.ExpUsage) / balancePointPair.Days);
                    //hddsDaily.Add(balancePointPair.HeatingDegreeDays / balancePointPair.Days);
                    //cddsDaily.Add(balancePointPair.CoolingDegreeDays / balancePointPair.Days);
                    //actualUsageDaily.Add(balancePointPair.ActualUsage / balancePointPair.Days);
                    fullXData[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)]    = Convert.ToDouble(balancePointPair.ExpUsage_New);
                    xDays[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)]        = balancePointPair.DaysInReading;
                    fullYData[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)]    = (balancePointPair.ActualUsage);
                    fullYDataAvg[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)] = (balancePointPair.ActualUsage / balancePointPair.DaysInReading);

                    //hddsDaily[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair) * ]
                    //    = balancePointPair.HddList[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)];

                    //cddsDaily[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)]
                    //    = balancePointPair.CddList[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)];

                    //hddsDailyAvgInReading[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)]
                    //    = (balancePointPair.HeatingDegreeDays / balancePointPair.DaysInReading);

                    //cddsDailyAvgInReading[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)]
                    //    = (balancePointPair.CoolingDegreeDays / balancePointPair.DaysInReading);

                    hcddMatrix[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)] = new double[] {
                        (balancePointPair.HeatingDegreeDays / balancePointPair.DaysInReading),
                        (balancePointPair.CoolingDegreeDays / balancePointPair.DaysInReading)
                    };

                    //hcddMatrix[0][IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)] = (balancePointPair.HeatingDegreeDays / balancePointPair.DaysInReading);
                    //hcddMatrix[1][IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)] = (balancePointPair.CoolingDegreeDays / balancePointPair.DaysInReading);
                }

                double[] avgHddsForEachReadingInYear = new double[readingsCount];
                double[] avgCddsForEachReadingInYear = new double[readingsCount];

                for (int i = 0; i < readingsCount; i++)
                {
                    avgHddsForEachReadingInYear[i] = hcddMatrix[i][0];
                    avgCddsForEachReadingInYear[i] = hcddMatrix[i][1];
                }


                //double[] expUsageByDay = new double[daysInYear];
                //double[] fullYDataDaiy = new double[daysInYear];
                //List<double> expUsageByDay = new List<double>();
                //List<double> fullYDataByDay = new List<double>();

                //foreach (BalancePointPair balancePointPair in IdenticalBalancePointPairsForAllReadings)
                //{
                //    double dailyExpusage = 0;

                //    dailyExpusage += normalParamsKey.B3 * balancePointPair.HddList[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)].Value;
                //    dailyExpusage += normalParamsKey.B5 * balancePointPair.CddList[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)].Value;

                //    expUsageByDay.Add(dailyExpusage);
                //    fullYDataByDay.Add(balancePointPair.ActualUsage / balancePointPair.DaysInReading);
                //}

                //double[] hddsDailyArr = hddsDaily.ToArray();
                //double[] cddsDailyArr = cddsDaily.ToArray();
                //double[][] xy = new double[cddsDailyArr.Length][];

                //for (int i = 0; i < cddsDailyArr.Length; i++)
                //{
                //    double[] row = new double[2];
                //    xy[i] = row;
                //}

                //for (int i = 0; i < hddsDailyArr.Length; i++)
                //{
                //    xy[i][0] = hddsDailyArr[i];
                //    xy[i][1] = cddsDailyArr[i];
                //}

                //double[] p = Fit.LinearMultiDim(hcddMatrix, fullYDataAvg,
                //    d => 1.0,
                //    d => d[0],
                //    d => d[1]);
                //Matrix<double>.Build.DenseOfColumnArrays(hcddMatrix);

                //Tuple<double, double> pSingular;
                double[] p = new double[3];
                p[0] = 0;
                p[1] = 0;
                p[2] = 0;

                if (_pointPair.HeatingBalancePoint == 0 && _pointPair.CoolingBalancePoint == 0)
                {
                    double[] onesVector = new double[readingsCount];
                    for (int i = 0; i < readingsCount; i++)
                    {
                        onesVector[i] = 1;
                    }
                    p[0] = Fit.LineThroughOrigin(onesVector, fullYDataAvg);
                }
                else if (_pointPair.CoolingBalancePoint != 0 && _pointPair.HeatingBalancePoint != 0)
                {
                    p = MultipleRegression.QR(hcddMatrix, fullYDataAvg, intercept: true);
                }
                else if (_pointPair.CoolingBalancePoint == 0)
                {
                    Tuple <double, double> heatingTuple = Fit.Line(avgHddsForEachReadingInYear, fullYDataAvg);
                    p[0] = heatingTuple.Item1;
                    p[1] = heatingTuple.Item2;
                }
                else if (_pointPair.HeatingBalancePoint == 0)
                {
                    Tuple <double, double> coolingTuple = Fit.Line(avgCddsForEachReadingInYear, fullYDataAvg);
                    p[0] = coolingTuple.Item1;
                    p[2] = coolingTuple.Item2;
                }

                //double[] p = Fit.MultiDim(hcddMatrix, fullYDataAvg, intercept: true);


                //double[] fullXData_NewFit = new double[fullYDataAvg.Length];

                double[] fullXData_NewFit = new double[readingsCount];

                foreach (BalancePointPair balancePointPair in IdenticalBalancePointPairsForAllReadings)
                {
                    double t1 = 0;
                    if (IsDoubleNotNaNOrInfinity(p[0]))
                    {
                        t1 = p[0] * balancePointPair.DaysInReading;
                    }

                    double t2 = 0;
                    if (IsDoubleNotNaNOrInfinity(p[1]))
                    {
                        t2 = p[1] * balancePointPair.HeatingDegreeDays;
                    }

                    double t3 = 0;
                    if (IsDoubleNotNaNOrInfinity(p[2]))
                    {
                        t3 = p[2] * balancePointPair.CoolingDegreeDays;
                    }

                    fullXData_NewFit[IdenticalBalancePointPairsForAllReadings.IndexOf(balancePointPair)] = t1 + t2 + t3;
                }

                //double rBest = GoodnessOfFit.CoefficientOfDetermination(
                //    hcddMatrix.Select(x => p[0] + (p[1] * x[0]) + (p[2] * x[1])),
                //    fullYDataAvg);

                double rBest = GoodnessOfFit.CoefficientOfDetermination(fullXData_NewFit, fullYData);

                //double[,] comma = new double[hddsDailyArr.Length, hddsDailyArr.Length];

                //for(int i = 0; i < hddsDailyArr.Length; i++)
                //{
                //    double left = xy[i / 2][0];
                //    double right = xy[i / 2][1];
                //    comma[i, i] = [left, right];
                //}

                //double RSquared = GoodnessOfFit.CoefficientOfDetermination(xy.Select((x, y) => p[0], +(p[1] * xy[0]) + (p[2] * y)), ydata);
                //double RSquared = GoodnessOfFit.CoefficientOfDetermination(comma => p[0], +(p[1] * xy[0]) + (p[2] * y))), ydata);

                BalancePointPair groupLeader = _pointPair;

                double rSquared = GoodnessOfFit.CoefficientOfDetermination(fullXData, fullYData);

                //double rSquaredDaily = GoodnessOfFit.CoefficientOfDetermination(expUsageByDay, fullYDataByDay);

                double standardError_New = MathNet.Numerics.GoodnessOfFit.StandardError(fullXData, fullYData, groupLeader.ReadingsInNormalYear - 2);
                groupLeader.StandardError = standardError_New;

                if (!Double.IsNaN(rBest) && !Double.IsInfinity(rBest))
                {
                    groupLeader.RSquared_New = rBest;
                }
                else
                {
                    groupLeader.RSquared_New = null;
                }

                groupLeader.B1_New = decimal.Round(Convert.ToDecimal(p[0]), 9, MidpointRounding.AwayFromZero);
                groupLeader.B2_New = decimal.Round(Convert.ToDecimal(p[1]), 9, MidpointRounding.AwayFromZero);
                groupLeader.B4_New = decimal.Round(Convert.ToDecimal(p[2]), 9, MidpointRounding.AwayFromZero);

                //if (NonWeatherDependant)
                //{
                //    groupLeader.RSquared = 0;
                //    groupLeader.NewRSquaredNonWeather = 0;
                //double b = Fit.LineThroughOrigin(xDays, fullYData);

                //double[] newXData = new double[xDays.Length];

                //for (int i = 0; i < newXData.Length; i++)
                //{
                //    newXData[i] = xDays[i] * b;
                //}

                //double NewRSquaredNonWeather = GoodnessOfFit.CoefficientOfDetermination(newXData, fullYData);

                //if (!Double.IsNaN(NewRSquaredNonWeather) && !Double.IsInfinity(NewRSquaredNonWeather))
                //{
                //    groupLeader.NewRSquaredNonWeather = GoodnessOfFit.CoefficientOfDetermination(newXData, fullYData);
                //    groupLeader.B1_New = decimal.Round(Convert.ToDecimal(b), 9, MidpointRounding.AwayFromZero);
                //}
                //else
                //{
                //    groupLeader.NewRSquaredNonWeather = null;
                //    groupLeader.B1_New = null;
                //}
                //}

                updatedBalancePointPairs.Add(groupLeader);
            }

            return(updatedBalancePointPairs);
        }