Skip to content
AndrM101 edited this page Sep 27, 2026 · 2 revisions

Wine Quality Classification

Multiclass wine-quality prediction (3–9) from 11 physicochemical attributes, on the combined UCI Wine Quality dataset (red + white, 6,497 samples).

Classification experiments comparing KNN, SVM, and Decision Tree baselines against GridSearchCV-tuned versions of the same models plus a tuned Random Forest.

Data

winequality-red.csv + winequality-white.csv (Cortez et al., 2009, Vinho Verde wine samples), concatenated with a binary type indicator and modeled jointly as one multiclass quality-prediction problem. Stratified 80/20 train/test split, random_state=42.

Class imbalance (test set, n=1,300): quality 3 has 6 samples, quality 9 has 1 sample, while qualities 5 and 6 together account for 995 of 1,300 (77%). This makes macro-averaged metrics far more informative than raw accuracy for judging performance on the tails — see Model Comparison & Evaluation Methodology for why accuracy alone is a misleading headline number here.

Results

Model Accuracy Macro F1 Weighted F1
KNN (baseline) 0.559 0.28 0.55
SVM (baseline) 0.572 0.24 0.54
Decision Tree (baseline) 0.595 0.33 0.59
Tuned SVM 0.585 0.29 0.57
Tuned Decision Tree 0.595 0.33 0.59
Tuned KNN 0.670 0.39 0.66
Tuned Random Forest 0.692 0.39 0.68

Tuned Random Forest wins on both accuracy and macro-F1, but macro-F1 (0.39) is far below its accuracy (0.69) — it's essentially unable to classify the rarest classes (quality 3: precision/recall/F1 all 0.00; quality 9: 0.00, n=1). Tuning materially helped every model family except Decision Tree, which was already at its ceiling with default hyperparameters (identical 0.595 before and after tuning).

Figures

Tuned Random Forest confusion matrix Best-performing model — note the near-complete inability to classify quality 3, 4, and 9 despite strong performance on 5-7.

Decision Tree confusion matrix Baseline decision tree — identical accuracy before and after GridSearchCV tuning.

Feature importance, decision tree Which physicochemical attributes drive the decision tree's splits.

Architecture

flowchart TD
    Red["winequality-red.csv"] --> Combine["main.py — concat + type flag"]
    White["winequality-white.csv"] --> Combine
    Combine --> Split["Stratified train/test split 80/20 + StandardScaler"]
    Split --> Baseline["Baseline: KNN / SVM / Decision Tree"]
    Split --> Tuned["GridSearchCV-tuned: Random Forest / KNN / SVM / Decision Tree"]
    Baseline --> Tables["Tables/ — classification reports"]
    Tuned --> Tables
    Baseline --> Plots["Plots/ — confusion matrices + feature importance"]
    Tuned --> Plots
Loading

Pages

Clone this wiki locally