← projects

Activity Detection from Network Traffic

Bachelor's dissertation project. The question: can an outside observer (someone who can only see encrypted traffic metadata, not payloads) work out what's happening inside a home just from packet timing and size of IoT network traffic? That's the same capability a network-level spyware or ISP-level surveillance system would have, which is what makes it worth measuring. The live dashboard below is that capability made visible.

Python · pandas/pyarrow · scikit-learn, imbalanced-learn, XGBoost · source · dashboard source

Live demo: what the observer sees

This is the dashboard from the same dissertation, reconstructing an activity feed straight from windowed traffic features: no payload, ever. It loads real captured data below, or drop in a CSV produced by the pipeline's windowAnalysis.py. Events within 15 seconds of each other get chained into higher-level inferences (motion inside → motion outside within 15s reads as someone left the house); click an inferred card to see the raw events behind it.

Loading…

Setup

A small home IoT network (two smart bulbs, a camera, a motion sensor, a smart plug, and an Alexa device, each on a fixed IP) was captured to .pcap while a set of labelled activities happened (device turned on, motion triggered, camera stream started, and so on). Packet headers were extracted to CSV; activity timestamps became a separate labelled events file. Everything downstream works on metadata only: frame length, inter-arrival time, TCP flags, TTL, TLS record type/length, which fixed device IP a packet was to/from, never payload content, which is the whole point: this has to work even against fully encrypted traffic.

Five ways to slice packets into windows

A classifier needs fixed-shape input, but network activity doesn't come in fixed-length chunks: a "camera stream started" event might last eight seconds, a "motion detected" ping might be one packet. Before any model, the real design problem was how to turn a continuous packet stream plus a list of labelled time intervals into a table of (features, label) rows. Five strategies ended up implemented, each a different answer to that:

None of these is strictly correct: it's a genuine tradeoff between label purity, how much of the capture gets used, and whether window duration leaks into the feature set. Running all five through the same downstream pipeline was the only honest way to see which one the choice of model actually cared about.

Class imbalance was the real problem

In any of the five window strategies, idle dominates: most of a home network's life is quiet. A model that just predicts idle every time posts a deceptively high plain accuracy while being useless. Every model trained here (logistic regression, random forest, a balanced random forest, XGBoost, SVM, and naive Bayes) goes through a SMOTE oversampling step in the training pipeline, uses class-weighted variants where available, and is grid-searched and refit on balanced accuracy, not accuracy, specifically so the search can't reward a model for ignoring the minority classes. Balanced random forest (which subsamples the majority class per tree instead of oversampling the minority one) was included specifically as a comparison against SMOTE-based balancing on the same folds.

What the dashboard is actually doing

Nothing in the feed above is a model prediction: the underlying windows are already labelled (by the same ground-truth activity log used to train the classifiers). What the dashboard adds is the second layer: turning a list of labelled windows into a narrative a human would recognise, and demonstrating that the raw material for that narrative was metadata the whole way down. The two-event inference rule (motion inside then outside within 15 seconds, or the reverse) is deliberately simple: it's meant to show how little correlation is needed to turn "device activity" into "person activity," not to be a general-purpose activity-recognition engine.

Stack

Packet extraction: tshark via shell scripts into CSV. Feature engineering and windowing: pandas, loaded with the pyarrow engine for speed on larger captures. Modeling: scikit-learn, imbalanced-learn (SMOTE, BalancedRandomForestClassifier), XGBoost, LightGBM, all tuned with grid search over 5-fold CV. Dashboard: vanilla JS, Chart.js, PapaParse. Pipeline source · dashboard source.