public async Task <PredictionResponse> Post(PredictionRequest request) { var year = DateTime.Now.Year; var tasks = new Dictionary <int, AsyncUnaryCall <CalculatePredictionResponse> >(); var yearAverages = new Dictionary <int, double>(); for (int y = year; y >= year - 4; y--) { tasks.Add(y, agents[y % agents.Count].GetProbabilityAsync(request.ToAgentRequest(y))); } foreach (var task in tasks) { yearAverages.Add(task.Key, (await task.Value).Probability); } var expectation = calculator.GetAverageOfPreviousYears(yearAverages); var recentCrimes = await statisticProvider.GetCrimesOneMonthBack(); var lastMonthData = calculator.FindDaysSinceLastCrime(CaseSimple.FromApiRequest(request), recentCrimes); var probability = calculator.CalculateCrimeProbability(expectation, lastMonthData); return(new PredictionResponse { Probability = probability }); }
public void PredictNextCrimeType(IEnumerable <CaseSimple> disctictScores, CaseSimple givenCase) => disctictScores .OrderBy(x => x.DistanceTo(givenCase)) .Take(15) .GroupBy(x => x.Type) .ToDictionary(grp => grp.Key, grp => grp.Count()) .OrderByDescending(x => x.Value) .First();
public override async Task <CalculatePredictionResponse> GetProbability(CalculatePredictionRequest request, ServerCallContext context) { Console.WriteLine("GetProbability average request recieved"); var dbData = await statisticProvider.CalculateAllCrimesByDistrctsByYear(request.Year); var res = posCalculator.CalculateAverageCrimes(CaseSimple.FromAgentRequest(request), dbData); return(new CalculatePredictionResponse() { Probability = res }); }
public int FindDaysSinceLastCrime(CaseSimple given, IEnumerable <CaseSimple> lastMonthData) { var lastCase = lastMonthData.OrderBy(item => item.DistanceTo(given)).FirstOrDefault(); if (lastCase == null) { return(30); } var time = new DateTime(given.Year, given.Month, given.Date) - new DateTime(lastCase.Year, lastCase.Month, lastCase.Date); return(time.Days); }
/// <summary> /// <para> The significance is a number between 0 and 1 </para> /// <para> The closer the distance is to 0, the closer the significance is to 1 </para> /// <para> Distances of 100 and above will have 0 significance </para> /// </summary> private double GetSignificance(CaseSimple first, CaseSimple second) { var distance = first.DistanceTo(second); return((distance > 100) ? 0 : Math.Cos(distance / 65)); }
private double CountIncidentsInTheArea(CaseSimple given, IEnumerable <CaseSimple> cases) => cases.Sum(item => GetSignificance(given, item));
=> 1 - Math.Pow((1 - averagePerDay), daysSinceLastCrime); // some sort of geometric distribution, commulative formula public double CalculateAverageCrimes(CaseSimple given, IEnumerable <CaseSimple> yearlySamples) => CountIncidentsInTheArea(given, yearlySamples) / 365;