public void Run() { using (var db = new TcAnalysisDataModel()) { var rounds = db.Rounds.OrderBy(r => r.Date).ToList(); foreach (var round in rounds) { var unratedDivRoundResults = round.RoundResults.Where(x => !x.IsRated).ToList(); foreach (var rr in unratedDivRoundResults) { rr.Tc_Weight = 0; rr.Tc_KFactor = 0; rr.Tc_ActualRank = 0; rr.Tc_ExpectedRank = 0; rr.Tc_ActualPerf = 0; rr.Tc_ExpectedPerf = 0; rr.Tc_Cap = 0; rr.Tc_NewRating = 0; rr.Tc_NewVolatility = 0; } foreach (var div in new[] { 1, 2 }) { var ratedDivRoundResults = round.RoundResults.Where(x => x.Division == div && x.IsRated).ToList(); var codersInDiv = ratedDivRoundResults.Select(y => new Functions.Coder(y.OldRating, y.OldVolatility)).ToList(); var scoresInDiv = ratedDivRoundResults.Select(y => y.Points).ToList(); if (!codersInDiv.Any()) { continue; } var cf = new CompetitionFactorFunction().Calculate(codersInDiv); if (div == 1) { round.DivOneCompetitionFactor = cf; } if (div == 2) { round.DivTwoCompetitionFactor = cf; } foreach (var rr in ratedDivRoundResults) { var w = new CoderCompetitionWeightFunction().Calculate(rr.OldRating, rr.NumberOfRatings - 1); rr.Tc_Weight = w; var k = new KFactorFunction().Calculate((div == 1) ? round.DivOneCompetitionFactor : round.DivTwoCompetitionFactor, rr.Tc_Weight); rr.Tc_KFactor = k; var arank = new ActualRankFunction().Calculate(rr.Points, scoresInDiv); rr.Tc_ActualRank = arank; var erank = new ExpectedRankFunction().Calculate(new Functions.Coder(rr.OldRating, rr.OldVolatility), codersInDiv); rr.Tc_ExpectedRank = erank; var aperf = new PerformanceFunction().Calculate(rr.Tc_ActualRank, codersInDiv.Count); rr.Tc_ActualPerf = aperf; var eperf = new PerformanceFunction().Calculate(rr.Tc_ExpectedRank, codersInDiv.Count); rr.Tc_ExpectedPerf = eperf; var cap = new CapFunction().Calculate(rr.NumberOfRatings - 1); rr.Tc_Cap = cap; var updatedRating = new UpdateRuleFunction().Calculate(rr.OldRating, rr.Tc_ExpectedPerf, rr.Tc_ActualPerf, rr.Tc_KFactor); var newRating = new NewRatingFunction().Calculate(rr.OldRating, updatedRating, rr.Tc_Cap); rr.Tc_NewRating = newRating; var newVolatility = new NewVolatilityFunction().Calculate(rr.OldRating, rr.OldVolatility, rr.Tc_NewRating, rr.Tc_Weight, rr.NumberOfRatings - 1); rr.Tc_NewVolatility = newVolatility; } } db.SaveChanges(); Console.WriteLine(round.Name); } } }
public void Run() { using (var db = new TcAnalysisDataModel()) { var coders = new Dictionary<int, int>(); var rounds = db.Rounds.OrderBy(r => r.Date).ToList(); foreach (var round in rounds) { round.NewRatingsDiffSum = 0; foreach (var div in new[] { 1, 2 }) { var ratedDivRoundResults = round.RoundResults.Where(x => x.Division == div && x.IsRated).ToList(); if (!ratedDivRoundResults.Any()) { continue; } var divN = ratedDivRoundResults.Count; var divRatings = ratedDivRoundResults.Select(x => x.OldRating).ToList(); var divMean = divRatings.Average(); var divStdev = Math.Sqrt(divRatings.Sum(r => Math.Pow(r - divMean, 2)) / divN); var divRatingsDiffMean = ratedDivRoundResults.Average(x => Math.Abs(x.NewRating - x.Tc_NewRating)); var divVolatilityDiffMean = ratedDivRoundResults.Average(x => Math.Abs(x.NewVolatility - x.Tc_NewVolatility)); var divNewRatingsDiffSum = ratedDivRoundResults.Sum(x => x.NewRating - x.OldRating); round.NewRatingsDiffSum += divNewRatingsDiffSum; var kendalTauDist = (from xi in ratedDivRoundResults.Select((x, i) => new { val = x, idx = i }) from xj in ratedDivRoundResults.Select((x, i) => new { val = x, idx = i }) where xi.idx < xj.idx where (xi.val.Tc_ActualRank < xj.val.Tc_ActualRank && xi.val.Tc_ExpectedRank > xj.val.Tc_ExpectedRank || xi.val.Tc_ActualRank > xj.val.Tc_ActualRank && xi.val.Tc_ExpectedRank < xj.val.Tc_ExpectedRank) select 1 ).Count() / (divN * (divN - 1) / 2.0); var tc3KendalTauDist = (from xi in ratedDivRoundResults.Select((x, i) => new { val = x, idx = i }) from xj in ratedDivRoundResults.Select((x, i) => new { val = x, idx = i }) where xi.idx < xj.idx where (xi.val.Tc_ActualRank < xj.val.Tc_ActualRank && xi.val.Tc3_ExpectedRank > xj.val.Tc3_ExpectedRank) || (xi.val.Tc_ActualRank > xj.val.Tc_ActualRank && xi.val.Tc3_ExpectedRank < xj.val.Tc3_ExpectedRank) select 1 ).Count() / (divN * (divN - 1) / 2.0); if (div == 1) { round.DivOneCodersCount = divN; round.DivOneRatingsMean = divMean; round.DivOneRatingsDeviation = divStdev; round.DivOneTcRatingsDiffMean = divRatingsDiffMean; round.DivOneTcVolatilityDiffMean = divVolatilityDiffMean; round.DivOneKendalTauDist = kendalTauDist; round.Tc3_DivOneKendalTauDist = tc3KendalTauDist; } if (div == 2) { round.DivTwoCodersCount = divN; round.DivTwoRatingsMean = divMean; round.DivTwoRatingsDeviation = divStdev; round.DivTwoTcRatingsDiffMean = divRatingsDiffMean; round.DivTwoTcVolatilityDiffMean = divVolatilityDiffMean; round.DivTwoKendalTauDist = kendalTauDist; round.Tc3_DivTwoKendalTauDist = tc3KendalTauDist; } foreach (var rr in ratedDivRoundResults) { coders[rr.CoderId] = rr.NewRating; } } var ratings = coders.Values; var n = ratings.Count; var mean = ratings.Average(); var stdev = Math.Sqrt(ratings.Sum(r => Math.Pow(r - mean, 2)) / n); round.GlobalCodersCount = n; round.GlobalRatingsMean = mean; round.GlobalRatingsDeviation = stdev; db.SaveChanges(); Console.WriteLine(round.Name); } } }
public void Run() { using (var db = new TcAnalysisDataModel()) { var defaultCoder = new { Rating = 1200, Volatility = 535, NumberOfRatings = 0 }; var coders = new int[0].ToDictionary(x => 1, x => defaultCoder); var rounds = db.Rounds.Where(x => x.Date.Year >= _Year).OrderBy(r => r.Date).ToList(); foreach (var round in rounds) { var ratedRoundResults = round.RoundResults.Where(x => x.IsRated).ToList(); foreach (var rr in ratedRoundResults) { var coder = coders.ContainsKey(rr.CoderId) ? coders[rr.CoderId] : defaultCoder; rr.Tc2_OldRating = coder.Rating; rr.Tc2_OldRating = coder.Rating; rr.Tc2_OldVolatility = coder.Volatility; rr.Tc2_NumberOfRatings = coder.NumberOfRatings + 1; } foreach (var div in new[] { 1, 2 }) { var ratedDivRoundResults = ratedRoundResults.Where(x => x.Division == div).ToList(); var codersInDiv = ratedDivRoundResults.Select(y => new Functions.Coder(y.Tc2_OldRating, y.Tc2_OldVolatility)).ToList(); var scoresInDiv = ratedDivRoundResults.Select(y => y.Points).ToList(); if (!codersInDiv.Any()) { continue; } var cf = new CompetitionFactorFunction().Calculate(codersInDiv); foreach (var rr in ratedDivRoundResults) { var w = new CoderCompetitionWeightFunction().Calculate(rr.Tc2_OldRating, rr.Tc2_NumberOfRatings - 1); var k = new KFactorFunction().Calculate(cf, w); var arank = new ActualRankFunction().Calculate(rr.Points, scoresInDiv); var erank = new ExpectedRankFunction().Calculate(new Functions.Coder(rr.Tc2_OldRating, rr.Tc2_OldVolatility), codersInDiv); var aperf = new PerformanceFunction().Calculate(arank, codersInDiv.Count); var eperf = new PerformanceFunction().Calculate(erank, codersInDiv.Count); var cap = new CapFunction().Calculate(rr.Tc2_NumberOfRatings - 1); var updatedRating = new UpdateRuleFunction().Calculate(rr.Tc2_OldRating, eperf, aperf, k); var newRating = new NewRatingFunction().Calculate(rr.Tc2_OldRating, updatedRating, cap); rr.Tc2_NewRating = newRating; var newVolatility = new NewVolatilityFunction().Calculate(rr.Tc2_OldRating, rr.Tc2_OldVolatility, newRating, w, rr.Tc2_NumberOfRatings - 1); rr.Tc2_NewVolatility = newVolatility; coders[rr.CoderId] = new { Rating = rr.Tc2_NewRating, Volatility = rr.Tc2_NewVolatility, NumberOfRatings = rr.Tc2_NumberOfRatings }; } } db.SaveChanges(); Console.WriteLine(round.Name); } foreach (var coder in coders) { var dbCoder = db.Coders.First(x => x.Id == coder.Key); dbCoder.Tc2_Rating = coder.Value.Rating; dbCoder.Tc2_Volatility = coder.Value.Volatility; dbCoder.Tc2_RoundsCount = coder.Value.NumberOfRatings; } db.SaveChanges(); Console.WriteLine("Coder data saved."); } }