Spaces:
Sleeping
Sleeping
import streamlit as st | |
import joblib | |
import numpy as np | |
import pandas as pd | |
# --- 1. Load Model and Dataset for Feature Information --- | |
def load_data_and_model(): | |
""" | |
Loads the saved model and the dataset from the Excel file. | |
Using st.cache_data to avoid reloading on every interaction. | |
""" | |
try: | |
# Load the pre-trained Voting Classifier model | |
model = joblib.load('voting_classifier_model.joblib') | |
except FileNotFoundError: | |
st.error("The model file 'voting_classifier_model.joblib' was not found.") | |
st.info("Please ensure the model file is in the same directory as this script.") | |
st.stop() | |
try: | |
# Load your specific dataset to get feature names and default values | |
df = pd.read_excel('breast-cancer.xls') | |
# Assuming the first column is 'id' and the second is 'diagnosis' (the target) | |
# The rest are the features. | |
feature_names = df.columns[2:].tolist() | |
# Store the dataframe for calculating min/max/mean values for sliders | |
feature_data = df[feature_names] | |
except FileNotFoundError: | |
st.error("The dataset file 'breast-cancer.xls' was not found.") | |
st.info("Please ensure your Excel file is in the same directory as this script.") | |
st.stop() | |
except Exception as e: | |
st.error(f"Could not load or process the dataset file. Error: {e}") | |
st.stop() | |
return model, feature_names, feature_data | |
model, feature_names, feature_data = load_data_and_model() | |
# --- 2. Streamlit App Interface --- | |
st.set_page_config(page_title="Breast Cancer Predictor", layout="wide") | |
# Main Title | |
st.title("π¬ Breast Cancer Prediction Interface") | |
st.markdown(""" | |
This application uses your pre-trained model to predict whether a breast tumor is **Malignant** or **Benign**. | |
The input fields below are based on the columns from your `breast-cancer.xls` file. | |
""") | |
st.write("---") | |
# --- 3. User Input via Sliders --- | |
st.sidebar.header("Input Tumor Features") | |
st.sidebar.markdown("Use the sliders to provide the feature values.") | |
# Dictionary to hold the user's input | |
input_features = {} | |
# Create sliders for all features based on your Excel file | |
for feature in feature_names: | |
# Set min/max/default values from the actual data for better usability | |
min_val = float(feature_data[feature].min()) | |
max_val = float(feature_data[feature].max()) | |
mean_val = float(feature_data[feature].mean()) | |
# Create a slider for each feature | |
input_features[feature] = st.sidebar.slider( | |
label=f"{feature.replace('_', ' ').title()}", | |
min_value=min_val, | |
max_value=max_val, | |
value=mean_val, | |
key=f"slider_{feature}" | |
) | |
st.sidebar.write("---") | |
# --- 4. Prediction Logic --- | |
# Convert the dictionary of input features into a NumPy array | |
# The order of features must match the order in the feature_names list | |
input_data = np.array([list(input_features.values())]) | |
# Main section for displaying inputs and results | |
st.header("Prediction Results") | |
col1, col2 = st.columns([2, 1]) | |
with col1: | |
st.subheader("Current Input Values") | |
st.json(input_features) | |
# "Predict" button | |
if st.button("β¨ Predict Diagnosis", key="predict_button"): | |
try: | |
# Make prediction. This returns the string label directly (e.g., 'M' or 'B'). | |
prediction_label = model.predict(input_data)[0] | |
# Get prediction probabilities. The order corresponds to model.classes_ | |
prediction_proba = model.predict_proba(input_data)[0] | |
with col2: | |
st.subheader("Diagnosis") | |
# Display the predicted label directly | |
# We check for 'M' or 'B' as is common in this dataset | |
if prediction_label.upper() == 'M': | |
st.error("Predicted Diagnosis: **Malignant**") | |
else: | |
st.success("Predicted Diagnosis: **Benign**") | |
st.subheader("Prediction Confidence") | |
# Get the class labels from the model itself to ensure correct order | |
class_labels = list(model.classes_) | |
# Display probabilities for each class using the model's class order | |
for i, label in enumerate(class_labels): | |
display_label = "Malignant" if label.upper() == 'M' else "Benign" | |
st.write(f"Confidence for **{display_label}**: `{prediction_proba[i]:.2%}`") | |
except Exception as e: | |
st.error(f"An error occurred during prediction: {e}") | |
st.write("---") |