private void initBaseStats() { _vpipPrior = createVPIPPrior(); _aggressionPrior = createAggressionPrior(); _pfrPrior = createPFRPrior(); _wtpPrior = createWTPPrior(); _baseModels = new List <BaseModel>(); foreach (var stats in _fullStatsList) { _baseModels.Add(null); } // Using prior distributions to estimate key stats for each player (in parallel) Parallel.ForEach(Partitioner.Create(0, _fullStatsList.Count), range => { for (int i = range.Item1; i < range.Item2; i++) { _baseModels[i] = estimateBaseModel(_fullStatsList[i]); } }); /* // Not parallel * foreach (var stats in _fullStatsList) * { * _baseModels[i] = estimateBaseStats(stats); * }*/ }
public HistDistribution(HistDistribution dist) { distribution = new float[dist.distribution.Length]; for (int i = 0; i < dist.distribution.Length; i++) { distribution[i] = dist.distribution[i]; } }
/// <summary> /// Creates VPIP prior distribution according to statistics. /// </summary> private HistDistribution createVPIPPrior() { var dist = new HistDistribution(_options.priorNumBins); foreach (var stats in _fullStatsList) { if (stats.VPIP.TotalSamples > _options.minSamples) { dist.AddSample(stats.VPIP.ToFloat()); } } dist.Normalize(); return(dist); }
/// <summary> /// Creates WTP (Willingnes to Play) prior distribution according to statistics. /// </summary> private HistDistribution createWTPPrior() { var dist = new HistDistribution(_options.priorNumBins); foreach (PlayerStats stats in _fullStatsList) { int positive; int total; stats.calculateWTP(out positive, out total); if (total > _options.minSamples) { dist.AddSample(positive / (float)total); } } dist.Normalize(); return(dist); }
/// <summary> /// Creates Aggression prior distribution according to statistics. /// </summary> private HistDistribution createAggressionPrior() { var dist = new HistDistribution(_options.priorNumBins); foreach (PlayerStats stats in _fullStatsList) { int raiseCount; int totalCount; stats.calculateAggression(out raiseCount, out totalCount); if (totalCount > _options.minSamples) { dist.AddSample(raiseCount / (float)totalCount); } } dist.Normalize(); return(dist); }
/// <summary> /// Estimates expected value of a probability distribution given prior and positive and total samples, /// using Bayes rule. /// </summary> /// <param name="prior">Prior probability distribution.</param> /// <param name="positiveSamples">Number of positive samples.</param> /// <param name="negSamples">Number of negative samples.</param> /// <returns>Estimated expected value.</returns> private void updateDistributionRandom(HistDistribution prior, int positiveSamples, int negSamples) { var pos = positiveSamples; var neg = negSamples; while (pos + neg > 0) { var ratio = pos / (double)(pos + neg); if ((pos > 0) && (_random.NextDouble() < ratio)) { prior.Update(true); pos--; } else { prior.Update(false); neg--; } } Debug.Assert(pos == 0 && neg == 0); }
private GaussianDistribution estimateGaussian(HistDistribution dist, int positiveSamples, int totalSamples) { var newDist = new HistDistribution(dist); // TODO: Privremeno if (totalSamples > 300) { positiveSamples = (300 * positiveSamples) / totalSamples; totalSamples = 300; } var pos = positiveSamples; var neg = totalSamples - positiveSamples; while (pos + neg > 0) { if (pos + neg <= 100) { updateDistributionRandom(newDist, pos, neg); pos = 0; neg = 0; } else { var newPos = (int)(100 * (pos / (float)(pos + neg))); var newNeg = (int)(100 * (neg / (float)(pos + neg))); updateDistributionRandom(newDist, newPos, newNeg); pos -= newPos; neg -= newNeg; } } Debug.Assert(pos == 0 && neg == 0); return(newDist.FitGaussian()); }
private EstimatedAD estimateADPostFlop(PlayerStats playerStats, DifferencePair[] sortedOpponents, PostFlopParams postFlopParams) { Debug.Assert(playerStats != null); var priorBetRaise = new HistDistribution(_options.priorNumBins); var priorCheckCall = new HistDistribution(_options.priorNumBins); var priorFold = new HistDistribution(_options.priorNumBins); var cumulativeActionsStats = new ActionStats(); int k = 0; for (int i = 0; (i < sortedOpponents.Length) && (k < _options.maxSimilarPlayers) && (k == 0 || sortedOpponents[i].Difference < _options.maxDifference); i++) { int playerInd = sortedOpponents[i].Index; if (_baseModels[playerInd].Aggression.Sigma < _options.maxBaseStatsSigma) { ActionStats similarOponentStats = _fullStatsList[playerInd].getPostFlopStats(postFlopParams); if (similarOponentStats.totalSamples() > _options.minSamples) { priorBetRaise.AddSample(similarOponentStats.betRaiseProbability()); priorCheckCall.AddSample(similarOponentStats.checkCallProbability()); priorFold.AddSample(similarOponentStats.foldProbability()); k++; } else { cumulativeActionsStats.append(similarOponentStats); } if (cumulativeActionsStats.totalSamples() > _options.minSamples) { priorBetRaise.AddSample(cumulativeActionsStats.betRaiseProbability()); priorCheckCall.AddSample(cumulativeActionsStats.checkCallProbability()); priorFold.AddSample(cumulativeActionsStats.foldProbability()); cumulativeActionsStats.clear(); k++; } } } priorBetRaise.Normalize(); priorCheckCall.Normalize(); priorFold.Normalize(); // Update prior sa statistikom igraca ActionStats startStats = playerStats.getPostFlopStats(postFlopParams); var estBetRaise = estimateGaussian(priorBetRaise, startStats.BetRaiseSamples, startStats.totalSamples()); var estCheckCall = estimateGaussian(priorCheckCall, startStats.CheckCallSamples, startStats.totalSamples()); var estFold = estimateGaussian(priorFold, startStats.FoldSamples, startStats.totalSamples()); if (postFlopParams.ForcedAction()) { var totalMean = estBetRaise.Mean + estCheckCall.Mean + estFold.Mean; var scale = 1.0f / totalMean; estBetRaise = estBetRaise.Scale(scale); estCheckCall = estCheckCall.Scale(scale); estFold = estFold.Scale(scale); } else { var totalMean = estBetRaise.Mean + estCheckCall.Mean; var scale = 1.0f / totalMean; estBetRaise = estBetRaise.Scale(scale); estCheckCall = estCheckCall.Scale(scale); estFold = new GaussianDistribution(0.0f, 0.0f); } return(new EstimatedAD(estBetRaise, estCheckCall, estFold, k, startStats.totalSamples())); }