ALL PROJECTS/FLEET DRIVER RISK ANALYTICS

Overview

A US trucking fleet wanted to know which of its drivers actually carried risk — not by reputation or by gut feel, but from the data it was already collecting. Three sources held the answer between them and none of them held it alone: the carrier's federal roadside-inspection record, which lists violations by safety category; a DOT inspection-compliance report, which gives each driver a single percentage; and telematics, which counts what drivers do behind the wheel — speeding, harsh braking, rolling stops, hours-of-service breaches.

The engagement was to turn those three into one thing: a per-driver risk band that a Power BI dashboard could put in front of a safety manager. This is an analytics engagement rather than a system — the deliverable is the scoring design and the artifacts it produces, not a service. What makes it worth writing up is where the difficulty actually sat: not in the clustering, but in modelling a regulatory domain honestly and turning a statistical grouping into a label a human can act on.

Problem

Three problems stood between the raw exports and a usable risk band.

The three sources do not speak the same language. The federal safety record is one row per violation, so a driver with eleven violations appears eleven times. The compliance report is one row per driver carrying a single percentage. Telematics is a count per event type. Before anything can be compared, all three have to be reduced to the same shape — one row per driver — without losing what makes each source informative.

A percentage is not a risk. The gap between a driver at 94% inspection compliance and one at 34% is not "sixty points" of danger — nearly all of the real exposure sits in the tail. Scoring that linearly would flatten precisely the signal the fleet was paying to find, and would spend the score's range on drivers who are already fine.

Clustering gives you groups, not meaning. K-means will happily return clusters 0, 1 and 2 — and it will number them differently the next time the data shifts, because the numbering is arbitrary. A dashboard that tells a safety manager "this driver is in cluster 2" has converted a data problem into a different data problem. The grouping has to be turned into an ordered, stable, human word before it is worth putting on a screen.

System Design

How It Works

01/04
01

Violations become a per-driver profile

How a violation log is reshaped into something that can be joined to everything else.

  1. 1The federal roadside-inspection record arrives as one row per violation
  2. 2It is pivoted by driver and safety category, so each driver gets a count per category
  3. 3The result is one row per driver — the shape every other source has to match
  4. 4It is exported as a settled file rather than held in memory for the next step
02

A compliance percentage becomes a weighted penalty

Why the score is a step function and not a straight line.

  1. 1Each driver's DOT inspection percentage is read from the compliance report
  2. 2It passes through a step function of thirteen weighted bands and then zero, rather than a linear scale
  3. 3Below 35% the percentage is weighted thirty-fold; at 95% and above it is weighted at zero
  4. 4The result is a penalty that concentrates on the tail, where the real exposure sits
03

Sixteen signals become three risk bands

The analytical core — and the step that turns a cluster into something a person can use.

  1. 1Sixteen driving-behaviour and compliance signals are standardised onto a common scale
  2. 2K-means segments the drivers into three groups with a fixed seed for reproducibility
  3. 3Each cluster's mean risk score is computed and the clusters are sorted by it
  4. 4The sorted clusters are mapped in order to Low, Medium and High Risk, and the raw cluster number is dropped
04

The stages stay independent

Why any one notebook can be re-run without replaying the other two.

  1. 1Each notebook opens its own export — none of them reads another's output
  2. 2The two reshaping stages each settle a workbook the reporting layer can read
  3. 3The segmentation stage settles the risk-score distribution plot beside its result
  4. 4So any single stage can be re-run or inspected without disturbing the others

Key Features

  • One risk band per driver — Low, Medium or High — derived from three independent sources rather than one
  • Federal roadside-inspection violations pivoted into a per-driver profile by safety category
  • A non-linear weighting of DOT inspection compliance — thirteen weighted bands and then zero — concentrating the score on the tail where exposure lives
  • Sixteen behaviour and compliance signals — speeding severity, following distance, harsh braking and turning, rolling stops, hours-of-service breaches and safety-category counts
  • Standardisation before clustering, so no metric dominates on units alone
  • A fixed random seed, so the same data reproduces the same segmentation
  • Clusters ranked by mean risk score and mapped in order to named bands, so no arbitrary cluster number reaches the dashboard
  • Independent stages — no notebook reads another's output, so any one can be re-run alone — plus a saved risk-score distribution plot, so the banding can be checked against the population

Outcomes

  • Turned three unrelated exports — a federal violation log, a compliance percentage and telematics event counts — into a single per-driver risk band a safety manager can act on
  • Designed a scoring curve that reflects how risk actually behaves, weighting the worst compliance band thirty-fold and the best at zero rather than treating the percentage as linear
  • Made the segmentation reproducible and interpretable: a fixed seed for stability, and clusters ranked against the risk score so the output is a named band rather than an arbitrary cluster id
  • Kept the three stages independent — none reads another's output, so any one can be re-run or inspected on its own without replaying the rest
  • Modelled a real regulatory domain — federal safety categories, DOT inspection compliance and hours-of-service breaches — rather than treating the columns as anonymous numbers

More work