public override ExpertOpinionSharp.Distributions.IDistribution Fit(string variableName)
        {
            var variable = Variables.Single(x => x.Name == variableName);
            var bounds   = GetBounds(variable);

            var w = new double[Experts.Count() + 1];
            var d = new QuantileDistribution[Experts.Count()];

            w [0]            = 0;
            w [w.Length - 1] = 1;

            var weights = UseOptimalAlpha ? GetOptimalWeights() : GetWeights(_alpha);

            int i = 0;

            foreach (var kv in weights)
            {
                var p = Estimates [kv.Item1, variable];
                var t = new [] { bounds.Item1, p [0], p [1], p [2], bounds.Item2 };
                d [i]     = new QuantileDistribution(QuantileVector, t);
                w [i + 1] = w [i] + kv.Item2;
                i++;
            }

            var dist = new MixtureDistribution(w, d);

            return(dist);
        }
Example #2
0
 private Formulator.Formula GetFormula(StringBuilder sb)
 {
     sb.Length--;
     sb.Insert(0, '('); sb.Append(')'); sb.Append('/');
     sb.Append(Experts.Count());
     return(GetFormula(sb.ToString()));
 }
Example #3
0
        /// <summary>
        /// Build the array <c>Pr</c>.
        /// </summary>
        protected void BuildPr()
        {
            Pr = new double[M];
            for (int h = 0; h < M; h++)
            {
                double product = 1;
                var    hashI   = h;
                for (int i = 0; i < Experts.Count(); i++)
                {
                    var index = hashI % (NbQuantiles + 1);
                    product *= ExpectedDensity[index];
                    hashI    = hashI / (NbQuantiles + 1);
                }

                Pr[h] = (S[h] + 1) / (Variables.Count(x => x.Calibration) + (1 / product));
            }

            Pr = Pr.Select(x => x / Pr.Sum()).ToArray();
        }
Example #4
0
        public override IDistribution Fit(string variableName)
        {
            /* **** */

            orderedExpertNames = new string[Experts.Count()];
            int j = 0;

            foreach (var e in Experts)
            {
                orderedExpertNames [j] = e.Name;
                j++;
            }

            /* ---- */

            Buildz();
            BuildZ();
            BuildS();
            BuildPr();

            /* **** */

            var variable = Variables.Single(x => x.Name == variableName);

            var bounds = GetBounds(variable);
            var min    = bounds.Item1;
            var max    = bounds.Item2;

            var xx = Estimates.Get(variable);
            // var xx = expertEstimates.SelectMany(t => t);

            var xlist = new List <double> (xx);

            xlist.Add(min);
            xlist.Add(max);
            xlist.Sort();

            var probabilities = new double[xlist.Count - 1];

            for (int i = 0; i < xlist.Count - 1; i++)
            {
                var v = xlist[i];
                probabilities[i] = 1;
                var h = 0;

                // for getting the correct h, we need to compute it in the opposite
                // direction; as h = ((...) * (m + 1) + j ) * (m + 1) + k for [...,j,k]
                for (int l = Experts.Count() - 1; l >= 0; l--)
                {
                    var currentExpert = Experts.Single(x => x.Name == orderedExpertNames [l]);
                    var ll            = Estimates [currentExpert, variable].ToList();
                    // expertEstimates[l].ToList();
                    var index = ll.FindIndex(y => y > v);
                    if (index < 0)
                    {
                        index = NbQuantiles;
                    }

                    h = (h * (NbQuantiles + 1)) + index;
                }
                probabilities[i] *= Pr[h];
            }

            var sum = probabilities.Sum();

            probabilities = probabilities.Select(t => t / sum).ToArray();
            var stops = xlist.ToArray();

            var quantiles = new double [probabilities.Length + 1];

            quantiles [0] = 0;
            int ij;

            for (ij = 1; ij < probabilities.Length; ij++)
            {
                quantiles [ij] = quantiles[ij - 1] + probabilities[ij - 1];
            }

            quantiles [ij] = 1;

            var dist = new QuantileDistribution(quantiles, stops);

            return(dist);
        }
Example #5
0
        public override void Calculate()
        {
            var qCount = Questions.Count();
            var eCount = Experts.Count();

            var qDict      = Questions.ToDictionary(x => x, x => 0d);
            int index      = 0;
            var qIndexDict = Questions.ToDictionary(x => x, x => index++);

            index = 0;
            var eIndexDict = Experts.ToDictionary(x => x, x => index++);

            var matrix = new double[eCount, qCount];

            var coeffitient = (double)qCount / MaxNormalizedAnswer;

            //Нормализую ответы, относительно максимума, чтобы результат был меньше кол-ва вопросов
            foreach (var answer in ExpertAnswer)
            {
                var qIndex = qIndexDict[answer.Question];
                var eIndex = eIndexDict[answer.Expert];

                matrix[eIndex, qIndex] = answer.NormalizedAnswer * coeffitient;
            }

            //Нормализую ответы, убирая одинаковые ответы, не соотносящиеся с рангами
            Normalize(matrix);

            _normalizedMartix = matrix;

            //Сумма ответов по вопросам
            var totalSum = 0d;
            //Среднее значение ответов от сумм ответов по вопросам
            var middleSum = 0d;
            //Суммы ответов по вопросам
            var qSumm = new double[qCount]; QSumms = qSumm;
            //Отклонение от средней суммы ответов по вопросам
            var qDSumm = new double[qCount]; QDSumms = qDSumm;
            //Квадраты ответов по вопросам
            var qDoubleSumm = new double[qCount]; QDoubleSumms = qDoubleSumm;

            for (int q = 0; q < qCount; q++)
            {
                var qSum = 0d;

                for (int e = 0; e < eCount; e++)
                {
                    qSum += matrix[e, q];
                }

                totalSum += qSum;

                qSumm[q] = qSum;
            }

            middleSum = qSumm.Sum() / qSumm.Length;

            for (int q = 0; q < qDSumm.Length; q++)
            {
                qDSumm[q] = qSumm[q] - middleSum;
            }

            for (int q = 0; q < qDoubleSumm.Length; q++)
            {
                qDoubleSumm[q] = qDSumm[q] * qDSumm[q];
            }

            S = qDoubleSumm.Sum();

            const string sName   = "S";
            const string expName = "exp";
            const string queName = "que";

            CoefficientOfConcordance = GetFormula($"(12*{sName})/(({expName}*{expName})*({queName}*{queName}*{queName}-{queName}))");
            CoefficientOfConcordance.TrySetValue(sName, (decimal)S);
            CoefficientOfConcordance.TrySetValue(expName, eCount);
            CoefficientOfConcordance.TrySetValue(queName, qCount);
        }