Historical multilabel movie-genre classification project developed in May 2024 in the context of the MIAD master's program at Universidad de los Andes, with an additional AWS serverless inference extension.
Historical naming note: the repository is named
GenderMovieClassification, but the implemented task is movie genre classification, not human gender classification. The historical repository name is intentionally preserved.
| Item | Status |
|---|---|
| Original period | 25–26 May 2024 |
| Academic context | Group master's project / Kaggle competition |
| ML task | 24-label multilabel genre probabilities from an English movie plot |
| Historical representation | Classical NLP: CountVectorizer + TF-IDF + DictVectorizer |
| Learned embeddings | No |
| Historical model artifact | pipeAPIclf.pkl |
| Historical serverless deployment | Yes |
| Serverless contribution | Individual extension by the repository maintainer |
| Current live API | Not claimed until a 2026 deployment smoke test succeeds |
| Project Atlas | Historical strategic evidence — accepted |
The public repository preserves the engineering evidence and architecture while avoiding republication of the original course notebook or competition datasets by default. See NOTICE.md and docs/provenance.md.
The serialized 2024 pipeline is the same modelling lineage documented by the original academic notebook and used to produce pipeAPIclf.csv.
The implementation follows this structure:
movie plot
→ TokenText
→ FeatureUnion
├── CountVectorizer
├── TfidfVectorizer
└── TextToDictTransformer → DictVectorizer
→ ToDense
→ Normalize
→ OneVsRestClassifier
└── StackingClassifier
├── ComplementNB(alpha=0.1)
├── MultinomialNB(alpha=0.099)
└── LogisticRegression(random_state=42)
→ 24 genre probabilities
The 24 output fields are defined in fields.py.
The historical notebook-support copy of preprocesing.py downloaded NLTK stopwords at runtime. The repository copy was later adapted for Lambda packaging by using the bundled path /var/task/nltk_data. The transformer classes and modelling intent remain aligned; the different file fingerprints are therefore documented as a serverless runtime adaptation, not treated as evidence corruption.
See docs/model-development.md and docs/evidence/historical-evidence.yml.
The project was developed for:
MIAD2024-12 – Clasificación de género de películas Kaggle competition: https://www.kaggle.com/competitions/miad-2024-12-clasificacion-de-genero-de-peliculas
Two historical submissions named pipeAPIclf.csv are supported by the preserved audit evidence:
| Submission | Public score | Private score |
|---|---|---|
pipeAPIclf.csv |
0.89269 | 0.89380 |
pipeAPIclf.csv |
0.89407 | 0.89297 |
The original notebook also contains the note kaggle_full=0.89269, providing an additional link to the first result above.
The notebook's later
~0.9960ROC-AUC output is not reported as holdout performance because the final pipeline had already been fitted on the complete training dataset before that calculation.
See docs/competition-results.md.
Beyond the academic modelling work, the trained pipeline was packaged into a Docker-compatible Lambda runtime and exposed through AWS Lambda + Amazon API Gateway, managed with AWS SAM.
This is the repository's main engineering extension:
historical scikit-learn pipeline
→ serialized model artifact
→ Docker image
→ AWS Lambda
→ API Gateway
→ HTTP inference
The original endpoint was historically deployed. During the 2026 audit it was not treated as currently live; the repository now includes an explicit recovery and verification path instead of presenting an unverified historical URL as an active service.
From the repository root:
PYTHON_BIN=python3.11 bash scripts/validate_recovery.shA real AWS recovery is deliberately opt-in because it can create or update cloud resources:
CONFIRM_DEPLOY=YES \
STACK_NAME=GenderMovieClassification \
AWS_REGION=us-east-1 \
bash scripts/deploy_and_verify.shOnly after /health and /inference pass the smoke test should the project metadata be changed to currently_live: true.
See docs/serverless-recovery.md.
The competition data are treated as external academic data. This repository does not automatically copy, download, or relicense them during the 2026 portfolio refresh.
With an authorized local copy:
python training/reproduce_historical_pipeline.py \
--training-data /authorized/local/path/dataTraining.zip \
--mode historical-final \
--output-dir artifacts/reproduction/historical-finalThe reproduction output is intentionally named separately from the preserved historical artifact so that pipeAPIclf.pkl is not silently replaced.
The audit bundle keeps the original academic notebook and Kaggle screenshot outside the public repository. Their fingerprints can be checked from the cloned repository:
python3 scripts/verify_historical_evidence.py \
--notebook ../../private-evidence/API_S7P1_proyecto.ipynb \
--kaggle-screenshot ../../private-evidence/kaggle-submissions-2026-08-07.png \
--historical-preprocessing ../../private-evidence/preprocesing.pyExpected interpretation:
fields.py → identical historical/repository evidence
preprocesing.py (repo) → recognized serverless-adapted variant
preprocesing.py (private) → original historical notebook-support variant
academic notebook → original private evidence
Kaggle screenshot → original private evidence
.
├── README.md
├── NOTICE.md
├── docs/
│ ├── academic-context.md
│ ├── competition-results.md
│ ├── evidence/
│ ├── model-development.md
│ ├── provenance.md
│ └── serverless-recovery.md
├── gender_movie_classification/
│ ├── model_inference/
│ ├── tests/
│ └── template.yaml
├── scripts/
├── src/
│ ├── Pipeline.png
│ └── aws_apiRest_serverless_model.png
├── training/
├── project.meta.yml
└── orchestrator_handoff.yml
The original notebook states that the project was developed in groups as part of the master's coursework and points to the corresponding Kaggle competition. It also credits Fabio González, Ph.D. and John Arevalo for the dataset source.
The 2026 public remediation therefore follows a conservative boundary:
- no competition dataset is added by the remediation;
- the original course notebook is retained as private evidence rather than copied into the public repository;
- course-provided instructions and movie plot text are not relicensed here;
- historical Kaggle scores are documented as historical competition evidence;
- the original ML pipeline is not rewritten merely to modernize the portfolio story;
- the serverless layer is identified separately as an individual engineering extension.
See NOTICE.md, docs/academic-context.md, and docs/provenance.md.
2024 AWS SAM workflow preserved for historical context
The original repository documented a workflow based on AWS SAM, ECR, a Lambda container image, and API Gateway:
cd gender_movie_classification
sam build
sam deploy --guidedThe historical documentation also included browser/Hoppscotch examples for the GET /inference?plot=... route.
Those instructions are preserved as historical evidence only. For a current deployment use scripts/deploy_and_verify.sh, which performs explicit verification before the repository can claim a live API.
- Academic context
- Competition results
- Model development
- Dataset and provenance boundary
- Historical evidence fingerprints
- Serverless recovery
- Project Atlas metadata
- Orchestrator handoff
The refresh does not claim that the historical model used neural embeddings, does not replace the historical artefact with a newly trained model, and does not claim that the historical API is currently operational without a new smoke test.
The goal is to preserve a defensible engineering story:
academic multilabel NLP model
→ serialized reusable artifact
→ inference backend
→ historical AWS serverless delivery

