Skip to content

Commit

Permalink
#22 compute probabilities of different amounts of ridership for a leg
Browse files Browse the repository at this point in the history
  • Loading branch information
dmnisson committed Nov 19, 2018
1 parent 84ab5e2 commit 953c099
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 38 deletions.
5 changes: 2 additions & 3 deletions DriverTracker/Controllers/AnalysisApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public LogisticFarePredictionResult GetLogistic(int id)
result.DriverID = id;
result.FromDateTime = fromDateTime;
result.ToDateTime = toDateTime;
result.RegressionResult = farePrediction.GetRegressionModel();
result.RegressionResult = farePrediction.GetRegressionModels();

return result;
}
Expand All @@ -82,8 +82,7 @@ public double[] GetMultiPickupProb(int id, double delay, double duration, double
DateTime toDateTime = DateTime.Now;
farePrediction.LearnFromDates(fromDateTime, toDateTime);

LogisticRegression regression = farePrediction.GetRegressionModel();
return regression?.Probabilities(new double[] { delay, duration, fare });
return farePrediction.RidershipClassProbabilities(delay, duration, fare);
}
}
}
56 changes: 33 additions & 23 deletions DriverTracker/Domain/FarePrediction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,26 @@ namespace DriverTracker.Domain
{
public class FarePrediction
{
private readonly LogisticRegressionAnalysis _logisticRegressionAnalysis;
private LogisticRegression _logisticRegression;
private readonly List<LogisticRegressionAnalysis> _logisticRegressionAnalyses;
private List<LogisticRegression> _logisticRegressions;
private readonly MvcDriverContext _context;
private readonly int _DriverID;

public FarePrediction(MvcDriverContext context, int DriverID) {
_logisticRegressionAnalysis = new LogisticRegressionAnalysis();
public FarePrediction(MvcDriverContext context, int DriverID, int maxPickups = 4) {
_logisticRegressionAnalyses = new List<LogisticRegressionAnalysis>();
for (int i = 0; i < maxPickups; i++) {
_logisticRegressionAnalyses.Add(new LogisticRegressionAnalysis());
}
_context = context;
_DriverID = DriverID;

_logisticRegressionAnalysis.Inputs = new string[] { "delay", "legDuration", "fare" };
_logisticRegressionAnalysis.Output = "multiplePickups";
_logisticRegressionAnalyses.ForEach(lra => lra.Inputs = new string[] { "delay", "duration", "fare" });
for (int i = 0; i < _logisticRegressionAnalyses.Count; i++) {
_logisticRegressionAnalyses[i].Output = "_" + (i + 1) + "PlusPickups";
}


_logisticRegressions = new List<LogisticRegression>();
}

/* Learn from legs with specified request times in a given date range */
Expand All @@ -43,29 +51,31 @@ public async void LearnFromDates(DateTime from, DateTime to) {
decimal.ToDouble(leg.Fare)
};
}).ToArray();

/*{
// delays in minutes
legs.Select(leg => leg.StartTime.Subtract(leg.PickupRequestTime.Value).TotalMinutes)
.ToArray(),
// leg duration in minutes
legs.Select(leg => leg.ArrivalTime.Subtract(leg.StartTime).TotalMinutes)
.ToArray(),

// fare collected in local currency units
legs.Select(leg => decimal.ToDouble(leg.Fare)).ToArray()
};*/

double[] trainingOutputs =
legs.Select(leg => leg.NumOfPassengersPickedUp > 1 ? 1.0 : 0.0).ToArray();

_logisticRegression = _logisticRegressionAnalysis.Learn(trainingInputs, trainingOutputs);
_logisticRegressions.Clear();
_logisticRegressions.AddRange(_logisticRegressionAnalyses.Select((lra, i) => {
double[] trainingOutputs =
legs.Select(leg => leg.NumOfPassengersPickedUp > i + 1 ? 1.0 : 0.0).ToArray();
return lra.Learn(trainingInputs, trainingOutputs);
}));
}

/* Get the regression result */
public LogisticRegression GetRegressionModel() {
return _logisticRegression;
public IEnumerable<LogisticRegression> GetRegressionModels() {
return _logisticRegressions;
}

/* Get a list of the probabilities of n or more pickups as an array of
* doubles with indices corresponding to n - 2 */
public double[] RidershipClassProbabilities(double delay, double duration, double fare) {
double[] result = new double[_logisticRegressions.Count];
for (int i = 0; i < _logisticRegressions.Count; i++) {
result[i] = _logisticRegressions[i].Probabilities(new double[] { delay, duration, fare })[1];
if (i > 0) result[i - 1] -= result[i];
}
return result;
}
}
}
3 changes: 2 additions & 1 deletion DriverTracker/Domain/LogisticFarePredictionResult.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;

using Accord.Statistics.Models.Regression;

Expand All @@ -9,6 +10,6 @@ public class LogisticFarePredictionResult
public int DriverID { get; set; }
public DateTime FromDateTime { get; set; }
public DateTime ToDateTime { get; set; }
public LogisticRegression RegressionResult { get; set; }
public IEnumerable<LogisticRegression> RegressionResult { get; set; }
}
}
Binary file modified DriverTracker/DriverTracker.db
Binary file not shown.
19 changes: 10 additions & 9 deletions DriverTracker/src/app/predictor/predictor.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ <h2>Ridership Prediction for Driver: {{driver.name}}</h2>
<button type="submit" class="btn btn-success" [disabled]="!riderPredictionForm.form.valid">Predict</button>
</form>


<div class="row" *ngIf="ridershipProbabilities != null">
<div class="col">
<p class="p-5">Probability of multiple ridership:</p>
</div>
<div class="col">
<p class="p-5">{{ridershipProbabilities[1] * 100}}%</p>
</div>
</div>
<ng-template [ngIf]="ridershipProbabilities != null">
<div class="row" *ngFor="let i of ridershipProbabilityIndices">
<div class="col">
<p class="p-5">Probability of {{i+2}}<ng-template [ngIf]="i == 3">+</ng-template> riders:</p>
</div>
<div class="col">
<p class="p-5">{{ridershipProbabilities[i] * 100}}%</p>
</div>
</div>
</ng-template>
2 changes: 2 additions & 0 deletions DriverTracker/src/app/predictor/predictor.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class PredictorComponent implements OnInit {
duration: number;
fare: number;
ridershipProbabilities: number[];
ridershipProbabilityIndices: number[];

getDriver(id: number): void {
this.driverService.getDriver(id).subscribe(driver => this.driver = driver);
Expand All @@ -33,6 +34,7 @@ export class PredictorComponent implements OnInit {
private driverService: DriverService,
private aRoute: ActivatedRoute) {
this.aRoute.params.subscribe(p => this.getDriver(p['id']));
this.ridershipProbabilityIndices = (new Array(4)).fill(0).map((x,i) => i);
}

ngOnInit() {
Expand Down
3 changes: 2 additions & 1 deletion DriverTracker/wwwroot/libs/main.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion DriverTracker/wwwroot/libs/main.js.map

Large diffs are not rendered by default.

0 comments on commit 953c099

Please sign in to comment.