Skip to content

jiogallardy/activity-classification

Repository files navigation

activity-classification

Classify human activity (walking, sitting, standing, laying, stairs) from 3-axis accelerometer streams. Ships a Python CLI plus a small reusable package built around the SVC model from the original research notebook (notebooks/svcModel.ipynb).

Two years of research showed that 3–6 body-worn sensors are enough to reliably classify what someone is doing in real time. This repo turns that finding into something you can actually run on a stream.

Predicted vs. True ROC Curve Pairplot

What's in here

.
├── src/activity_classification/   # CLI + library
│   ├── cli.py            # `activity` entry point
│   ├── features.py       # UCI HAR-style windowed feature pipeline (~85 features)
│   ├── features_v2.py    # Compact 62-feature pipeline (mirrored in Swift)
│   ├── io_streams.py     # file / stdin / TCP adapters
│   ├── mac_sensor.py     # Apple Silicon hidden accelerometer reader
│   └── model.py          # SVC pipeline (StandardScaler + RBF SVM)
├── ios-app/              # Expo React Native iPhone app (CoreML on-device)
│   ├── modules/activity-sensor/   # Local Expo Module (Swift)
│   │   └── ios/          # FeatureExtractor + ActivityClassifier + bridge
│   └── App.tsx           # Live UI showing current activity
├── scripts/              # Training + CoreML conversion scripts
├── notebooks/            # Original research notebooks
├── datasets/             # UCI HAR CSVs + raw IMU recordings
├── models/               # Trained .joblib + .mlmodel artifacts
└── tests/                # Pytest suite for the feature pipeline

iPhone app

There's a full iOS app at ios-app/ that reads your iPhone's accelerometer + gyroscope and classifies your activity live, on-device, with no network. See ios-app/README.md for build instructions (you need Xcode + an Apple ID; ~5 min once Xcode is set up).

Install

git clone https://github.com/jiogallardy/activity-classification
cd activity-classification
python3 -m venv .venv && source .venv/bin/activate
pip install -e .

# For Apple Silicon live sensor support:
pip install -e ".[mac]"

Requires Python 3.10+.

Quick start

1. Train a model

Option A — UCI HAR pre-extracted (561 features, matches the notebook):

Drop the original UCI HAR CSVs into datasets/uci_har/:

datasets/uci_har/
  X_train.csv  y_train.csv
  X_test.csv   y_test.csv

then:

activity train --data datasets/uci_har

Option B — raw labeled (t,x,y,z,label) CSVs:

Drop per-recording CSVs into datasets/raw/ (one row per sample, columns t,x,y,z,label) and run:

activity train-raw --data datasets/raw

This uses the bundled feature pipeline (~85 features) so it works on any 50 Hz tri-axial stream.

2. Classify a stream

Two modes:

Pre-extracted feature vectors (pair with activity train — 561-dim UCI HAR model):

activity classify --file datasets/uci_har/X_test.csv --pre-extracted --json
# → 95.6% accuracy on the UCI HAR test set

Raw (t, x, y, z) stream (pair with activity train-raw — ~85-dim window model):

activity classify --file my_walk.csv                        # from file
activity classify --file my_walk.csv --json --probs         # JSON + probs
cat my_walk.csv | activity classify                         # from stdin
activity classify --host 127.0.0.1 --port 9000              # from TCP JSON

Raw CSVs may be headerless (t,x,y,z or x,y,z) or carry named columns in any order (time,seconds_elapsed,z,y,x works — matches Sensor Logger app).

Each ~2.5 s window produces one prediction:

[0.00s-2.56s] STANDING
[1.28s-3.84s] WALKING
[2.56s-5.12s] WALKING

3. Live from a MacBook (Apple Silicon)

M-series Macs (M1/M2/M3/M4) contain an undocumented MEMS accelerometer managed by the Sensor Processing Unit, accessible via IOKit HID. See olvvier/apple-silicon-accelerometer for the reverse-engineering work this builds on.

activity live --json --probs

The CLI gracefully reports if the SPU backend isn't bundled — see src/activity_classification/mac_sensor.py for how to drop in a working _spu_reader.py. The rest of the CLI is sensor-agnostic, so anything that yields (t, x, y, z) tuples plugs in.

Stream input formats

Source Format
File / stdin CSV, optional header. Columns: t,x,y,z or x,y,z.
TCP socket Newline-delimited JSON: {"t":0.02,"x":0.1,"y":-0.04,"z":9.8}\n
iPhone / Apple Watch Use a Shortcuts recipe or SensorLog to POST/stream to the TCP endpoint.
Apple Silicon Mac activity live (requires [mac] extras).

Activity classes

Inherited from the UCI HAR dataset:

ID Label
1 WALKING
2 WALKING_UPSTAIRS
3 WALKING_DOWNSTAIRS
4 SITTING
5 STANDING
6 LAYING

Additional classes (e.g. DRIVING vs. SITTING) require new labeled data — add recordings with those labels and run activity train-raw.

Sensor reality check

  • Apple Silicon Macs (M1+): hidden MEMS accelerometer via IOKit HID. Wired via activity live.
  • Intel MacBooks (pre-2016, HDD models): Sudden Motion Sensor exposed via AMSSensorUsage. Not wired here but trivially pluggable.
  • iPhone / Apple Watch / Android: stream over TCP as JSON.
  • External IMUs: write a 4-column CSV; pipe via stdin or --file.

Results from the notebook

Original SVC (RBF, C ≈ 47.6, 561 features) on UCI HAR:

  • Cross-validation accuracy: ~95%
  • See docs/figures/predictedVsTrue.png, rocCurve.png, pairplot.png.

Development

pip install -e ".[dev]"
pytest -q
ruff check .

Acknowledgements

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors