A rigorous machine learning framework and interactive operational console for botanical specimen classification based on Sir Ronald Fisher's seminal 1936 morphometric dataset and Gaussian Naive Bayes probabilistic inference.
- Abstract & Project Summary
- Research Problem & Objectives
- Scientific Methodology
- Repository Structure
- Jupyter Research Notebooks
- Dataset Provenance & Schema
- Prediction Results & Key Findings
- Embedded Research Figures
- Demonstration Video
- Reproducibility & Installation
- Running the Web Application
- Deployment to Render
- Hosted Frontend-Only Exploration
- Technology Stack
- Limitations & Future Research
- Academic References
Morphological differentiation of biological taxa requires quantitative modeling of continuous anatomical traits. This research project presents a reproducible computational pipeline and deployment architecture for classifying Iris species (I. setosa, I. versicolor, I. virginica) using 4 morphometric continuous dimensions.
Using maximum-likelihood parameter estimation for Gaussian Naive Bayes, the system learns class-conditional probability distributions across the 150 historical observations recorded by Edgar Anderson (1936). The empirical model attains an overall classification accuracy of 96.0% (
Accurate botanical identification from physical morphology often encounters overlapping phenotypic variations between closely related sister species. In particular, Iris versicolor and Iris virginica share overlapping sepal dimensions and petal length transitions (
- Model Calibration: Fit multivariate class-conditional probability distributions to four continuous morphological attributes.
-
Uncertainty Quantification: Compute continuous posterior class probabilities
$\hat{P}(C_k \mid \mathbf{x})$ rather than uncalibrated deterministic classifications. - Reproducibility & Operationalization: Provide self-contained Jupyter workflows, automated tests, a REST API endpoint, and an accessible graphical user interface.
The system evaluates feature vector
Classification follows the Maximum A Posteriori (MAP) decision rule:
flowchart TD
In["Morphological Continuous Input Vector<br/>[sepal_len, sepal_wid, petal_len, petal_wid]"] --> Calc["Class-Conditional Likelihood Estimation<br/>P(x_i | C_k) ~ N(mu_ki, sigma_ki^2)"]
Calc --> Bayes["Bayesian Posterior Formulation<br/>P(C_k | x) proportional to P(C_k) * prod P(x_i | C_k)"]
Bayes --> MAP["Maximum A Posteriori (MAP) Selection<br/>y_hat = argmax P(C_k | x)"]
MAP --> Out["Output Taxon & Calibrated Posterior Probabilities<br/>(setosa / versicolor / virginica)"]
For detailed derivations and mathematical formulation, see docs/methodology.md.
Iris_classification/
├── README.md # Master project research documentation
├── requirements.txt # Project dependencies
├── app.py # Flask application & REST API
├── iris_model.pkl # Serialized Gaussian Naive Bayes estimator
│
├── notebooks/
│ ├── README.md # Notebook execution index
│ └── 01_iris_morphometric_classification.ipynb # Exploratory & model training workflow
│
├── data/
│ ├── README.md # Dataset documentation & provenance
│ └── raw/
│ └── iris.csv # 150 botanical records (Fisher, 1936)
│
├── results/
│ ├── README.md # Experimental summary
│ ├── figures/
│ │ ├── README.md # Figures catalog
│ │ ├── iris_specimen_morphology.png# Bivariate distributions & decision regions
│ │ └── iris_botany_anatomy.svg # Floral morphological landmarks
│ ├── metrics/
│ │ └── classification_report.json # Serialized empirical performance metrics
│ └── predictions/
│ ├── README.md # Prediction schemas
│ └── sample_predictions.json # Empirical sample predictions
│
├── docs/
│ ├── methodology.md # Statistical & mathematical formulation
│ ├── architecture.md # System components & API contracts
│ └── references.md # Academic literature citations
│
├── static/ # Web interface styles & favicon assets
└── templates/ # Jinja2 HTML user interface
| Notebook | Focus | Inputs | Outputs |
|---|---|---|---|
notebooks/01_iris_morphometric_classification.ipynb |
Exploratory data analysis, bivariate feature distributions, GNB training, probability calibration, and model export | data/raw/iris.csv or sklearn.datasets.load_iris |
iris_model.pkl, evaluation matrices, classification reports |
For execution details and environment preparation, refer to the Notebooks Index.
- Source: Edgar Anderson (1936), published in Sir Ronald A. Fisher (1936).
- Observations: 150 specimens across 3 balanced taxa (50 setosa, 50 versicolor, 50 virginica).
-
Physical Features:
-
sepal length (cm): Outer calyx length ($4.3 - 7.9\text{cm}$ , mean:$5.84\text{cm}$ ) -
sepal width (cm): Outer calyx width ($2.0 - 4.4\text{cm}$ , mean:$3.06\text{cm}$ ) -
petal length (cm): Inner blade length ($1.0 - 6.9\text{cm}$ , mean:$3.76\text{cm}$ ) -
petal width (cm): Inner blade width ($0.1 - 2.5\text{cm}$ , mean:$1.20\text{cm}$ )
-
Further details are archived in data/README.md.
Empirical evaluation on the full calibrated dataset yields:
| Class | Precision | Recall | F1-Score | Support |
|---|---|---|---|---|
| Iris setosa | 50 | |||
| Iris versicolor | 50 | |||
| Iris virginica | 50 | |||
| Overall Accuracy | — | — | 0.960 | 150 |
| Macro Average | 0.960 | 150 |
Predicted Setosa Versicolor Virginica
True Setosa 50 0 0
True Versicolor 0 47 3
True Virginica 0 3 47
Key analytical conclusions:
-
Iris setosa occupies a disjoint morphological manifold driven by diminutive petal dimensions (
$\le 1.9\text{cm}$ ). - Misclassifications (
$6 / 150$ ) occur exclusively along the boundary between versicolor and virginica where individual specimens exhibit intermediate petal width ($1.6 - 1.8\text{cm}$ ).
Figure 1: Pairwise feature scatter matrix, univariate kernel density estimations, and Gaussian Naive Bayes decision contours illustrating the linear separation of I. setosa and the continuous boundary between I. versicolor and I. virginica.
Figure 2: Vector anatomical schematic detailing measurement landmarks for upright standard petals and reflexed falling sepals according to historical botanical standards.
Watch the operational walkthrough of the Iris Botanical Morphometric Classification interface below:
Iris_demo.mp4
Direct repository link:
results/Iris_demo.mp4
Requires Python 3.10+:
# Clone and enter directory
cd Iris_classification
# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txtjupyter lab notebooks/01_iris_morphometric_classification.ipynbLaunch the Flask operational console and REST API:
python app.pyDefault URL: http://127.0.0.1:5001/
curl -X POST http://127.0.0.1:5001/predict \
-H "Content-Type: application/json" \
-d '{
"sepal length (cm)": 5.1,
"sepal width (cm)": 3.5,
"petal length (cm)": 1.4,
"petal width (cm)": 0.2
}'Expected response:
{
"class_flower": "setosa",
"prediction": 0,
"probabilities": {
"setosa": 1.0,
"versicolor": 0.0,
"virginica": 0.0
}
}The web application is pre-configured for automated continuous deployment to Render as a production-grade Web Service using Gunicorn.
- Build System: Python 3.10 runtime (configured via
runtime.txt) - Web Server: Gunicorn WSGI (
gunicorn app:app) - Process Entry: Defined in
Procfile(web: gunicorn app:app) - Infrastructure Blueprint: Defined in
render.yaml
- Log into your Render Dashboard and click New +
$\rightarrow$ Web Service. - Connect your Git repository containing the project.
- Configure the following service settings:
-
Name:
iris-classification-service(or your preferred name) - Region: Any preferred region (e.g., Frankfurt, Oregon, Ohio)
-
Branch:
main -
Root Directory:
Iris_classification(leave blank if this folder is the repository root) -
Runtime:
Python 3 -
Build Command:
pip install -r requirements.txt -
Start Command:
gunicorn app:app -
Instance Type:
Free
-
Name:
- Under Advanced
$\rightarrow$ Environment Variables, add:-
PYTHON_VERSION:3.10.14
-
- Click Create Web Service. Render will install dependencies and launch the live web console.
- On the Render Dashboard, select Blueprints
$\rightarrow$ New Blueprint Instance. - Connect the repository. Render will automatically detect
render.yamland configure build commands, entry points, and environment variables with zero manual entry.
The web console (templates/index.html) includes a zero-dependency client-side Gaussian likelihood inference engine:
- Hosted Mode Capabilities: Real-time multi-attribute sliders, preset specimen archetype selection, and instant Bayesian posterior visualization directly within the browser without requiring a live Python backend.
- Backend-Connected Mode: Sends live asynchronous requests to
POST /predictfor server-side verification against the trained scikit-learn model.
- Runtime & Language: Python 3.10
- Scientific Computing & ML: NumPy, Pandas, Scikit-Learn, Joblib
- Web Application & API: Flask, Jinja2, Werkzeug
- Visualization: Matplotlib, Seaborn
- Design & Typography: Canonical Ubuntu font family, responsive semantic HTML5
- Dimensional Scope: The model utilizes 4 continuous landmark attributes; future extensions could incorporate hyperspectral petal imaging or genetic markers.
- Covariance Assumption: Standard Gaussian Naive Bayes assumes zero inter-feature covariance within classes; evaluating Quadratic Discriminant Analysis (QDA) or Gaussian Mixture Models (GMM) may better capture correlated growth trajectories.
- Fisher, R. A. (1936). The use of multiple measurements in taxonomic problems. Annals of Eugenics, 7(2), 179–188.
- Anderson, E. (1936). The species problem in Iris. Annals of the Missouri Botanical Garden, 23(3), 457–509.
- Pedregosa, F., et al. (2011). Scikit-learn: Machine Learning in Python. JMLR, 12, 2825–2830.