Interactive Iris Flower Classifier
Client-Side ML Active
Input
Live View
Predicted Species
Iris Versicolor
Sandbox
Metrics
Accuracy
100.0%
On test split (80/20)
Total Features
4
Sepal/Petal DimensionsClassification Report (Test Data)
| Class | Precision | Recall | F1-Score |
|---|---|---|---|
| Setosa (0) | 1.00 | 1.00 | 1.00 |
| Versicolor (1) | 1.00 | 1.00 | 1.00 |
| Virginica (2) | 1.00 | 1.00 | 1.00 |
Confusion Matrix
Pred 0
Pred 1
Pred 2
Act 0
10
0
0
Act 1
0
9
0
Act 2
0
0
11
Setosa: 0
Versicolor: 1
Virginica: 2
A clean diagonal means perfect classification with zero misclassifications.
Visualization
Setosa
Versicolor
Virginica
Your Custom Input
Documentation
Code Compare
# Training code in Python (iris_classification.ipynb)
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
import pandas as pd
# Load dataset
iris_df = pd.read_csv('Iris.csv')
# Drop duplicates & encode labels
iris_df.drop_duplicates(inplace=True)
le = LabelEncoder()
iris_df['Species_encoded'] = le.fit_transform(iris_df['Species'])
# Split Features & Target
X = iris_df.drop(['Id', 'Species', 'Species_encoded'], axis=1, errors='ignore')
y = iris_df['Species_encoded']
# Split train/test sets (80% / 20%)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Fit Logistic Regression model
model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)
# Output evaluation metrics
y_pred = model.predict(X_test)
print("Accuracy:", model.score(X_test, y_test))
// K-Nearest Neighbors Classifier written in Vanilla JavaScript
class KNNClassifier {
constructor(k = 3, metric = 'euclidean') {
this.k = k;
this.metric = metric;
}
fit(X, y) {
this.X_train = X;
this.y_train = y;
}
distance(pt1, pt2) {
if (this.metric === 'manhattan') {
return pt1.reduce((sum, val, idx) => sum + Math.abs(val - pt2[idx]), 0);
}
// Default: Euclidean
const sumSq = pt1.reduce((sum, val, idx) => sum + Math.pow(val - pt2[idx], 2), 0);
return Math.sqrt(sumSq);
}
predictSingle(xQuery) {
// Calculate distances from query point to all training points
const dists = this.X_train.map((xTrain, idx) => ({
dist: this.distance(xQuery, xTrain),
label: this.y_train[idx]
}));
// Sort by ascending distance and get top K
dists.sort((a, b) => a.dist - b.dist);
const kNearest = dists.slice(0, this.k);
// Count votes per class
const votes = [0, 0, 0];
kNearest.forEach(n => votes[n.label]++);
// Calculate probabilities
const sum = votes.reduce((a, b) => a + b, 0);
const probs = votes.map(v => v / sum);
return {
predictedClass: votes.indexOf(Math.max(...votes)),
probabilities: probs
};
}
}
# Backend Serving API (app.py) using FastAPI
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import joblib
import numpy as np
app = FastAPI(title="Iris Classifier API", description="Serves Scikit-Learn models")
# Enable CORS for local deployment
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Load trained Model
try:
model = joblib.load("iris_logistic_model.pkl")
except:
model = None
class FlowerFeatures(BaseModel):
sepal_length: float
sepal_width: float
petal_length: float
petal_width: float
@app.post("/predict")
def predict(features: FlowerFeatures):
if model is None:
return {"error": "Model pickle file not found. Place 'iris_logistic_model.pkl' in the directory."}
input_data = np.array([[
features.sepal_length,
features.sepal_width,
features.petal_length,
features.petal_width
]])
prediction = int(model.predict(input_data)[0])
probs = model.predict_proba(input_data)[0].tolist()
species_map = {0: "Setosa", 1: "Versicolor", 2: "Virginica"}
return {
"species_id": prediction,
"species_name": species_map[prediction],
"probabilities": probs
}