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); }
private Formulator.Formula GetFormula(StringBuilder sb) { sb.Length--; sb.Insert(0, '('); sb.Append(')'); sb.Append('/'); sb.Append(Experts.Count()); return(GetFormula(sb.ToString())); }
/// <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(); }
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); }
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); }