← Back to work

Self-Directed ML Curriculum · In progress

CineML

A machine learning curriculum I set for myself, working from data cleaning up through neural networks and recommender systems, deliberately using the same 5,000 movies at every stage instead of a new toy dataset for each topic.

Role
Solo project
Status
7 of 9 stages done, 8th underway
Stack
Python · scikit-learn · PyTorch · pandas · Surprise
Dataset
TMDB 5000 Movies

One dataset, on purpose

Most ML learning material hands you a different dataset for every technique: irises for classification, handwritten digits for neural networks, house prices for regression. Each one is chosen to make its technique look good, which is efficient for explaining the algorithm and useless for building judgment. You never develop a feel for any of the data, so you can't tell whether a result is impressive or whether the dataset was just easy.

CineML runs every stage on the same ~5,000 movies: budgets, revenue, genres, cast, crew, ratings, and reviews. By the third stage I knew what the data actually looked like: which fields were sparse, which correlations were real, where the outliers hid. That meant when a model performed well I could usually say why, and when it performed badly I could tell whether the problem was the model or the data.

9
Stages
~5,000
Movies
1
Dataset, stages 1–6
Solo
Self-directed

The stage where the neural network lost

Stage 5 built sentiment classification the classical way: TF-IDF to turn review text into numbers, then logistic regression on top. It worked well.

Stage 6 was deep learning, so I rebuilt the same sentiment task as a neural network in PyTorch, fully expecting it to win. It didn't. The neural network was less accurate than the logistic regression it was supposed to improve on.

The reason is the dataset size. Neural networks earn their advantage by learning representations from large amounts of data; with only a few thousand examples there isn't enough signal to justify the extra capacity, and a well-chosen classical model with sensible features is simply the better tool. TF-IDF plus logistic regression is a strong baseline precisely because it doesn't need to learn what words mean from scratch.

Why this is the most useful thing in the project

It's easy to come out of an ML course believing newer means better. Having actually built both and watched the sophisticated one lose is a much more durable lesson than reading that it might. The real skill isn't knowing how to build a neural network; it's knowing when not to.

Other things that surprised me

Engineering, not just notebooks

Stage 4 was the one with no new algorithms in it. It was about turning experiments into something reusable: chaining the scaling, encoding, fitting, and prediction steps into a single pipeline so the same transformations apply identically to training and new data, then saving the trained models to disk.

That stage is why there's a predict.py in the repository rather than only notebooks. You can hand it a movie's details and get a profitability prediction back with a confidence score, loading the saved model instead of retraining. It's a small thing, but it's the difference between an experiment and something another person can run.

Stage 7: where the one-dataset rule had to bend

Stage 7 is recommendation systems, the natural endpoint for a movie dataset, and it's the stage that broke the rule the whole project is built on.

Collaborative filtering learns from who rated what. It doesn't care what a film is about; it cares that people who liked the ones you liked also liked this other one. The TMDB set has an average rating per film and no individual users at all, so there is no user-item matrix in it to factorise. No amount of feature engineering conjures one. The collaborative half runs on MovieLens ratings instead: an SVD matrix factorisation over roughly 800 MB of real user-item ratings, trained with Surprise.

The content-based half stays on the original data, and it's the more satisfying one because it reuses earlier stages rather than starting over. It takes the plot overviews, vectorises them with the same TF-IDF vectoriser saved back in stage 5, and ranks films by cosine similarity between those vectors. The sentiment stage's artefact became the recommender's feature extractor, which is exactly the compounding that a single-dataset curriculum is supposed to produce.

The lesson in having to bring a second dataset

I set the one-dataset rule to build familiarity, and it held for six stages. Stage 7 is where it stopped being a virtue: some techniques have a shape of data they require, and if your data isn't that shape, the honest move is to admit it rather than to force a proxy and call the result a recommender. Knowing which question a dataset simply cannot answer is its own skill.

Where it's going

Stage 7 is in progress: both recommenders run, and what's left is evaluation and turning them into something callable rather than notebook cells. Stage 8 is a stretch list: fine-tuning a transformer, computer vision, and deploying a model behind an API rather than leaving it in a notebook.

The project is deliberately unfinished. It's a curriculum, and the point is the progression rather than a finished product at the end.