Spaces:
Sleeping
Sleeping
File size: 7,521 Bytes
11b1420 fd1ef54 c9131d2 fd1ef54 11b1420 fd1ef54 010a1cb fd1ef54 010a1cb fd1ef54 a45b603 fd1ef54 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
---
title: "Coffee Cup Points Estimator"
emoji: "☕️"
colorFrom: "gray"
colorTo: "green"
sdk: "gradio"
sdk_version: "5.49.1"
app_file: "app.py"
pinned: false
---
# Module3Project
# Overview
Predict coffee quality scores based on sensory attributes using a RandomForest model and an MLOps pipeline.
This project demonstrates an end-to-end MLOps pipeline: data ingestion, preprocessing, model training, containerization, cloud deployment, and front-end integration.
# Data
For this project, we are using data on coffee quality found here:
https://www.kaggle.com/datasets/volpatto/coffee-quality-database-from-cqi
The cleaned coffee dataset is publicly hosted on Google Cloud Storage for reproducibility.
The preprocessing pipeline automatically downloads it via the data.url field in config.yaml.
Cleaned data is hosted in Google Cloud Storage:
https://storage.googleapis.com/coffee-quality-data/preprocessed_data.csv
# Architecture
Data → Cloud (GCS) → Preprocess (ColumnTransformer) → Train (RandomForest) → FastAPI → Gradio frontend
## Frontend Architecture
```
┌───────────────┐ ┌─────────────┐ ┌───────────────┐ ┌──────────────┐
│ Kaggle Data │ → │ GCS Bucket │ → │ FastAPI (API)│ → │ Gradio UI │
└───────────────┘ └─────────────┘ └───────────────┘ └──────────────┘
```
# Frontend
The Gradio-based frontend is deployed at: https://huggingface.co/spaces/averye-duke/Module3
Hugging face was used to deploy the app.
# Cloud Deployment:
The FastAPI container is deployed on Google Cloud Run at:
Base URL:
https://coffee-api-354131048216.us-central1.run.app
Endpoints:
- /health – Health check
- /predict_named – POST endpoint for predictions
- /docs - API documentation (Swagger)
Example cURL:
```
curl -X POST "https://coffee-api-354131048216.us-central1.run.app/predict_named" \
-H "Content-Type: application/json" \
-d '{"rows":[{"Aroma":7.5,"Flavor":6.0,"Body":5.5,"Acidity":8.0,"Sweetness":9.0,"Balance":7.0,"Aftertaste":6.5,"Clean.Cup":9.0}]}'
```
# Setup:
```
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install --upgrade pip
pip install -r requirements.txt
```
# Testing/running scripts
To test preprocess.py:
```
python scripts/preprocess.py
```
Confirm all output files exist by running:
```
ls -l data/cleaned/X_train.csv data/cleaned/X_test.csv data/cleaned/y_train.csv data/cleaned/y_test.csv artifacts/preprocessor.joblib
```
We wrote a unit test script tests/test_preprocessor.py, to run it:
```
pip install pytest
pytest -q
```
To run the server, do health check use sample predict payload:
```
uvicorn app.server:app --reload --port 8000
curl http://127.0.0.1:8000/health
curl -X POST "http://127.0.0.1:8000/predict_named" \
-H "Content-Type: application/json" \
-d '{"rows":[ {"Aroma":7.5,"Flavor":6.0,"Number.of.Bags":1,"Category.One.Defects":0} ] }'
```
To train the model:
```
python scripts/train.py
```
Ensure artifacts/model.joblib was built
To run the UI app start the server and type in CLI:
```
python app/frontend.py
Enter 3 when prompted:
wandb: (1) Create a W&B account
wandb: (2) Use an existing W&B account
wandb: (3) Don't visualize my results
My personal login is needed to sign in here to update to wandb website
```
Open link in browser
# Model
We used a RandomForestRegression for the model. Test size is 20% of dataset. Model has accuracy of 94.2% with 100 estimators.
W and B tracks model performance. Data can be found in wandb/run.../files/wandb-summary.json. Data is presented like this:
```
{
"_timestamp":1.763876781125257e+09,
"_wandb":{"runtime":2},
"_runtime":2,
"_step":0,
"R2":0.9424069488737763,
"RMSE":0.5528660703704987,
"MAE":0.31615526315789416,
"MAPE":0.39006294567905464
}
```
These perfomance metrics are also stored in artifacts.metrics.json like this:
```
{
"R2": 0.9424069488737761,
"RMSE": 0.5528660703704994,
"MAE": 0.31615526315789455,
"MAPE": 0.39006294567905514
}
```
The 94.2% R2 value shows very good fit and a cup score that correlates strongly with the other columns. The RMSE 0f 0.55 shows a small predicition error and therefore reinforces the model's high preformance. The MAE of 0.314 also shows a small error to the actual cup points. MAPE shows average percentage error of 39% which shows medium accuracy. This could be due to the small size dataset the model was trained on.
# 🐳 Docker and Testing
## Build the image
```
# from the project root
docker build -t coffee-api:dev .
docker run --rm -e WANDB_MODE=offline -p 8000:8000 coffee-api:dev
```
Note: Use WANDB_MODE=offline (as shown above) when running inside Docker or CI to prevent login prompts from Weights & Biases. If you have a W&B API key, set it via WANDB_API_KEY=your_key to enable cloud logging.
## Run the container
```
docker run --rm -p 8000:8000 \
-v "$(pwd)/artifacts":/app/artifacts \
-v "$(pwd)/config.yaml":/app/config.yaml \
-v "$(pwd)/data":/app/data \
coffee-api:dev
```
Then open:
• Health check: http://127.0.0.1:8000/health
• Interactive docs: http://127.0.0.1:8000/docs
If artifacts are missing, the container automatically runs scripts/preprocess.py to generate them.
## Run tests inside the container
To verify reproducibility of preprocessing and data pipeline:
```
docker run --rm -v "$(pwd)":/app -w /app coffee-api:dev python -m pytest -q
```
Expect output:
```
...
3 passed in ~0.9s
```
## Docker-related notes:
- Ports: container exposes 8000 (mapped to host port 8000)
- Artifacts (preprocessor.joblib, model.joblib) are mounted from the host for faster iteration
# Limitations & Ethics
Predictions depend on sensory ratings, which are subjective.
The model is not suitable for real-world evaluation of coffee quality without expert calibration.
The dataset may contain sampling bias by country or producer, and model predictions should not be used for commercial grading without calibration against expert cuppers.
# Notes / Gotchas
- config.yaml may include data.input_columns — if present the server will require/expect those columns and reindex incoming payloads automatically.
- The server will try to load artifacts/preprocessor.joblib and artifacts/model.joblib. If those are missing the server returns deterministic dummy predictions (development mode).
# ☁️ Cloud Services Used
- **Google Cloud Storage (GCS):** Stores the cleaned dataset (`preprocessed_data.csv`) publicly.
- **Google Cloud Run:** Hosts and serves the FastAPI model API container.
- **Weights & Biases (W&B):** Tracks model training metrics and performance.
# 🧠 Authors
- Eugenia Tate
- Avery Estopinal
# References:
- OpenAI. (2025). ChatGPT (Version 5.1) [Large language model]. https://chat.openai.com We used ChatGPT (OpenAI GPT-5.1) to assist with code snippets.
Portions of the preprocessing, frontend, train and most of server code were assisted by ChatGPT (OpenAI GPT-5.1). Authors verified and adapted the generated code.
Authors fully understand what the code does and how to apply the knowledge in the future.
- Kaggle Coffee Quality Data (Volpatto, 2020) https://www.kaggle.com/datasets/volpatto/coffee-quality-database-from-cqi
|