Machine learning over a coal mine's operational data to predict operator fatigue before the in-cab camera catches it. Peer-reviewed and published in Minerals in 2021.
The copper mine project left a chip on my shoulder. We'd gone hunting for predictors of safety incidents in a mine's operational data, and the honest answer we brought back was that nothing beat labor hours. I still thought there was merit in the data, but predicting safety incidents was just too hard a problem for the tools of the time, and it probably always will be, right up until the day we have precogs. So Pratt Rogers, the University of Utah professor who'd led that project, and I kept turning the same question over. What could we do with this kind of data if we aimed it at a simpler problem?
The simpler problem found us through Frank Drews, a University of Utah psychologist Pratt had been working with, who studied how mine sites used their fatigue-monitoring systems. The mines had spent real money to know when their drivers were tired. Every haul truck cab carried a camera tracking the operator's eyes, and if the system couldn't find them open for three seconds it buzzed the seat and paged dispatch. The monitoring worked, but it fired at the last possible moment, after a fatigued operator was already rolling in a truck that hauls 400 tons. And it fired a lot. At the site we would end up studying, cameras caught a driver with his eyes closed thirty-three times a day on average, and 98 percent of days included at least one on-camera micro-sleep.
That frequency is exactly what made fatigue a better target than safety incidents. Incidents are rare, so the data on them is thin. Fatigue events happened dozens of times a day, on camera, timestamped, which gave us far more examples to learn from. The signal was more plausible too. Could the weather predict a safety incident? That was always a stretch. Could one kind of fatigue event predict another? That sounded like a question with an answer.
So we took another crack at it. NIOSH funded the work through the University of Utah, and we found our site in a coal mine whose operational systems looked a lot like the copper mine's, which meant the hard lessons about blending that data carried straight over. But we weren't just rerunning the copper study on new rows. This time we had the fatigue-monitoring data on top of the operational data, and it could play both sides. It was the thing we were trying to predict, and it was potentially predictive itself, since one kind of fatigue event might foreshadow another. The question was whether any of it, the shift roster, the maintenance log, the weather station, the cameras themselves, held leading indicators that could warn you hours before the camera had anything to see.
The data work was mine again, but this time I wasn't starting from zero. Most of the datasets came out of the same kinds of systems the copper mine ran, fleet management, equipment health alarms, time and attendance, a weather station, so I already knew their shape and how to turn their raw event streams into the state-based data models can learn from. The pipeline strategy carried over too, Dask dataframes for data bigger than memory with incremental Feather caches between stages, the same recipe that had kept iteration fast on the copper study, now battle-tested instead of improvised. All that reuse freed the real effort for what was new. The fatigue system's data had to be massaged into the shapes we needed, clean event streams to predict against and features that could feed back in as predictors. Our thinking on granularity had evolved as well. At the copper mine we'd rolled everything up to a day-and-shift grain and come away suspecting the aggregation was burying signal, so this time we kept the shift grain and added a finer hourly cut to test whether it had been. The models stayed random forests, an informed choice by now rather than a default, because they generalize well on messy tabular data and carry the interpretation tooling, feature importance, drop-column tests, dependence plots, that lets a finding be explained instead of just asserted.
The difference from every project before it was that this code had to outlive me. The copper study had been Pratt and me, and a codebase two people share can live in two heads. This time the plan was for Elaheh Talebi, a University of Utah graduate student, to refine the final models as her thesis. Handing two years of your own code to someone new to the field is a test most codebases fail, so I built the handoff like a product: numbered pipeline stages from import to features to model, documentation on every sheet and every decision, pairing sessions to walk her through the analysis, even recorded video walkthroughs she could replay on her own. She needed to drive it without me in the room, and she did. She's first author on the paper. Pratt ran the program as principal investigator, and Frank brought the psychology of fatigue.
The research was published in Minerals in 2021: "Modeling Mine Workforce Fatigue: Finding Leading Indicators of Fatigue in Operational Data Sets." Peer-reviewed, open access, NIOSH-funded, with me credited for methodology, software, and data curation. The best model, a random forest over the shift-grain data, explained about a third of the variance in fatigue events on held-out data; the hourly cut surfaced hour of day and temperature but couldn't match it. Respectable territory for a phenomenon as human as being tired. What mattered more than the score was what the model pointed at. Shift type, day versus night, towered over everything, nearly triple the importance of the next feature; drop that single column and the model gives back 0.29 of its 0.36 R². Then unscheduled equipment downtime, production variables, ambient temperature. The same shape as the copper answer, confirmed at a second mine in a different commodity: fatigue looks like a personal failing, but the model keeps pointing at the roster. You can't schedule away the 2 a.m. eyelid. You can decide what the night shift looks like.
There's a coda I'm proud of. In 2022 Elaheh published a follow-up study, moving from mine-level fatigue down to individual operators, built on this work. I'm not an author on it. That's what a real handoff looks like. The code kept producing research after I left the room.
Say hi.
Got a problem that looks like this one? I want it.
Got one so new nobody's even scoped it? I want that one more.