Bewertungsformel
Die Scoring-Pipeline lebt in src/lib/rider-score/. Der reine Kernel ist scoreFromSignals() in compute-trip-score.ts und ist unit-getestet. Der rollierende Score lebt in update-rolling-score.ts.
Score pro Fahrt
Jede abgeschlossene Fahrt erhalt einen Score von 0 bis 100, an beiden Enden abgeschnitten, in ride_safety_signals geschrieben mit einem weights_snapshot, damit historische Scores reproduzierbar bleiben.
Standardformel
score = clamp(
20 * speed_compliance_pct
+ 15 * parking_compliance
+ 15 * (1 - geofence_violation_decay)
+ 10 * (1 - hard_brake_rate)
+ 10 * (1 - throttle_aggression_rate)
+ 10 * clean_end_bool
+ 10 * helmet_verified_bool
+ 10 * (1 - sidewalk_event_rate) // Gewicht 0 bis CV ausgeliefert
- 5 * open_violation_count
- 2 * open_intervention_count,
0, 100
)
Eingaben
| Signal | Quelle | Was es misst |
|---|---|---|
| Geschwindigkeits-Compliance | ride_locations.speed vs. Zonenlimit | % der GPS-Stichproben bei oder unter dem Zonenlimit |
| Park-Compliance | ride_zone_events Ende-Ereignis | Binar: endete die Fahrt in einer zugelassenen Parkzone? |
| Geofence-Verstosse | ride_zone_events mitten in der Fahrt | Anzahl, mit Rezenz abklingend |
| Hartes Bremsen | GPS-Verzogerungs-Deltas | Anzahl der Verzogerungsereignisse uber Schwelle |
| Drossel-Aggression | ride_locations.throttle_position | % der Fahrt uber 85% Drossel |
| Sauberes Ende | rides.end_method | Wahr wenn sauber beendet |
| Helm verifiziert | rider_helmet_selfies.passed_at | Wahr wenn nicht-abgelaufenes Selfie vorliegt |
| Burgersteig-Ereignisse | CV-Pipeline (Projekt 4) | Anzahl, Gewicht 0 bis CV ausgeliefert |
| Offene Verstosse | violations.ride_id | Jeder offene Verstoss entfernt 5 Punkte |
| Offene Interventionen | rider_interventions | Jede offene Intervention entfernt 2 Punkte |
Anfanger-Regel
Bei Fahrten 1-3 ist der Fahrer in der Anfanger-Stufe. Der Score wird aufgezeichnet, treibt aber keine Interventionen und tragt noch nicht zum rollierenden Score bei.
Kurz-Fahrten-Ausschluss
Fahrten kurzer als 60 Sekunden oder 200 Meter werden vom rollierenden Score ausgeschlossen.
Normalisierung nach Fahrtlange
Pro-Fahrt-Scoring ist ratenbasiert. Eine lange Fahrt wird nicht bestraft, weil sie lang ist.
Rollierender Fahrer-Score
Der rollierende Score ist ein exponentiell gewichteter gleitender Durchschnitt der pro-Fahrt-Scores uber die letzten 90 Tage.
rolling_score = clamp(
sum(trip_score_i * weight_i) / sum(weight_i),
0, 100
)
wobei weight_i = exp(-ln(2) * age_days_i / halflife_days)
- Fenster: 90 Tage, konfigurierbar.
- Halbwertszeit: 30 Tage, konfigurierbar.
- Kaltstart: weniger als 3 bewertete Fahrten = Anfanger-Stufe.
Gespeichert in rider_scores.rolling_score.
Stufen-Zuweisung
| Standard-Stufe | Rollierender Score |
|---|---|
| Platin | 90+ |
| Gold | 80 bis 89 |
| Silber | 70 bis 79 |
| Bronze | 50 bis 69 |
| Risikofahrer | unter 50 |
| Anfanger | weniger als 3 bewertete Fahrten |
Stufen-Ubergange losen Pramien-Vergaben und Interventionsleiter-Neubewertungen aus.
Reproduzierbarkeit
Jede pro-Fahrt-Score-Zeile tragt einen weights_snapshot JSON-Blob mit den genauen Gewichten, Schwellenwerten und Signalen.
Was wo lauft
| Code | Zweck |
|---|---|
src/lib/rider-score/compute-trip-score.ts | Zieht Signale, berechnet Score pro Fahrt |
src/lib/rider-score/update-rolling-score.ts | EWMA, wahlt Stufe |
src/lib/rider-score/post-ride.ts | Koordinator, Soft-Fail |
src/lib/rider-score/intervention-engine.ts | Bewertet die Leiter |
src/lib/rider-score/reward-engine.ts | Stellt Pramien durch die Erstattungs-Pipeline aus |
Was nicht passiert
- Wir bewerten weder den Betreiber noch die Flotte.
- Wir bestrafen keine Fahrten, die durch tote Batterie abgebrochen wurden.
- Wir verwenden in v1 keinen Score uber Subkonten hinweg.
Weiter
Siehe Gewichte und Einstellungen zum Optimieren. Siehe Fehlerbehebung wenn ein Score nicht den Erwartungen entspricht.