Spaces:
Sleeping
Sleeping
# app.py | |
import streamlit as st | |
import pandas as pd | |
import numpy as np | |
from sklearn.datasets import load_iris | |
from sklearn.model_selection import train_test_split | |
from sklearn.preprocessing import StandardScaler | |
from sklearn.linear_model import LogisticRegression | |
from sklearn.tree import DecisionTreeClassifier | |
from sklearn.ensemble import RandomForestClassifier | |
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report | |
import plotly.express as px | |
import plotly.graph_objects as go | |
import seaborn as sns | |
import matplotlib.pyplot as plt | |
class IrisPredictor: | |
def __init__(self): | |
self.iris = load_iris() | |
self.df = pd.DataFrame(data=np.c_[self.iris['data'], self.iris['target']], | |
columns=self.iris['feature_names'] + ['target']) | |
self.models = { | |
'Logistic Regression': LogisticRegression(), | |
'Decision Tree': DecisionTreeClassifier(), | |
'Random Forest': RandomForestClassifier() | |
} | |
self.X = self.df.drop('target', axis=1) | |
self.y = self.df['target'] | |
self.scaler = StandardScaler() | |
def preprocess_data(self): | |
# Split the data | |
X_train, X_test, y_train, y_test = train_test_split( | |
self.X, self.y, test_size=0.2, random_state=42 | |
) | |
# Scale the features | |
X_train_scaled = self.scaler.fit_transform(X_train) | |
X_test_scaled = self.scaler.transform(X_test) | |
return X_train_scaled, X_test_scaled, y_train, y_test | |
def train_model(self, model_name): | |
X_train_scaled, X_test_scaled, y_train, y_test = self.preprocess_data() | |
# Train model | |
model = self.models[model_name] | |
model.fit(X_train_scaled, y_train) | |
# Make predictions | |
y_pred = model.predict(X_test_scaled) | |
# Calculate metrics | |
accuracy = accuracy_score(y_test, y_pred) | |
conf_matrix = confusion_matrix(y_test, y_pred) | |
class_report = classification_report(y_test, y_pred) | |
return { | |
'model': model, | |
'accuracy': accuracy, | |
'confusion_matrix': conf_matrix, | |
'classification_report': class_report, | |
'X_test': X_test_scaled, | |
'y_test': y_test, | |
'y_pred': y_pred | |
} | |
def plot_confusion_matrix(self, conf_matrix): | |
fig = px.imshow(conf_matrix, | |
labels=dict(x="Predicted", y="Actual"), | |
x=['Setosa', 'Versicolor', 'Virginica'], | |
y=['Setosa', 'Versicolor', 'Virginica'], | |
title="Confusion Matrix") | |
return fig | |
def plot_feature_importance(self, model_name, model): | |
if model_name == 'Logistic Regression': | |
importance = abs(model.coef_[0]) | |
else: | |
importance = model.feature_importances_ | |
fig = px.bar(x=self.X.columns, y=importance, | |
title=f"Feature Importance - {model_name}", | |
labels={'x': 'Features', 'y': 'Importance'}) | |
return fig | |
def predict_single_sample(self, model, features): | |
# Scale features | |
scaled_features = self.scaler.transform([features]) | |
# Make prediction | |
prediction = model.predict(scaled_features) | |
probabilities = model.predict_proba(scaled_features) | |
return prediction[0], probabilities[0] | |
def main(): | |
st.title("๐ธ Iris Flower Prediction App") | |
st.write(""" | |
This app predicts the Iris flower type based on its features. | |
Choose a model and see how it performs! | |
""") | |
# Initialize predictor | |
predictor = IrisPredictor() | |
# Model selection | |
st.sidebar.header("Model Selection") | |
model_name = st.sidebar.selectbox( | |
"Choose a model", | |
list(predictor.models.keys()) | |
) | |
# Train model and show results | |
if st.sidebar.button("Train Model"): | |
with st.spinner("Training model..."): | |
results = predictor.train_model(model_name) | |
# Display metrics | |
st.header("Model Performance") | |
st.metric("Accuracy", f"{results['accuracy']:.2%}") | |
# Display confusion matrix | |
st.subheader("Confusion Matrix") | |
conf_matrix_fig = predictor.plot_confusion_matrix(results['confusion_matrix']) | |
st.plotly_chart(conf_matrix_fig) | |
# Display feature importance | |
st.subheader("Feature Importance") | |
importance_fig = predictor.plot_feature_importance(model_name, results['model']) | |
st.plotly_chart(importance_fig) | |
# Display classification report | |
st.subheader("Classification Report") | |
st.text(results['classification_report']) | |
# Store the trained model in session state | |
st.session_state['trained_model'] = results['model'] | |
# Make predictions | |
st.header("Make Predictions") | |
col1, col2 = st.columns(2) | |
with col1: | |
sepal_length = st.slider("Sepal Length", 4.0, 8.0, 5.4) | |
sepal_width = st.slider("Sepal Width", 2.0, 4.5, 3.4) | |
with col2: | |
petal_length = st.slider("Petal Length", 1.0, 7.0, 4.7) | |
petal_width = st.slider("Petal Width", 0.1, 2.5, 1.4) | |
if st.button("Predict"): | |
if 'trained_model' in st.session_state: | |
features = [sepal_length, sepal_width, petal_length, petal_width] | |
prediction, probabilities = predictor.predict_single_sample( | |
st.session_state['trained_model'], features | |
) | |
# Display prediction | |
iris_types = ['Setosa', 'Versicolor', 'Virginica'] | |
st.success(f"Predicted Iris Type: {iris_types[int(prediction)]}") | |
# Display probability distribution | |
st.subheader("Prediction Probabilities") | |
prob_fig = px.bar(x=iris_types, y=probabilities, | |
title="Prediction Probability Distribution", | |
labels={'x': 'Iris Type', 'y': 'Probability'}) | |
st.plotly_chart(prob_fig) | |
else: | |
st.warning("Please train a model first!") | |
if __name__ == "__main__": | |
main() |