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() |