Spaces:
Sleeping
Sleeping
import streamlit as st | |
import joblib | |
import numpy as np | |
import pickle | |
# --- 1. Load Model and Define Feature Information --- | |
def load_model(): | |
""" | |
Loads the saved model. | |
Using st.cache_resource to load the model only once. | |
""" | |
try: | |
# Load the pre-trained model from a pickle file | |
model = joblib.load('rf_classifier_model.pkl') | |
return model | |
except FileNotFoundError: | |
st.error("The model file 'voting_classifier_model.pkl' was not found.") | |
st.info("Please ensure you have saved your model using pickle and the file is in the same directory.") | |
st.stop() | |
except Exception as e: | |
st.error(f"An error occurred while loading the model: {e}") | |
st.stop() | |
model = load_model() | |
# --- Hardcoded Feature Information --- | |
# We define the feature names and their typical ranges (min, mean, max) | |
# This removes the need to load the original dataset file. | |
FEATURE_INFO = { | |
'radius_mean': [6.98, 14.12, 28.11], | |
'texture_mean': [9.71, 19.28, 39.28], | |
'perimeter_mean': [43.79, 91.96, 188.5], | |
'area_mean': [143.5, 654.8, 2501.0], | |
'smoothness_mean': [0.05, 0.09, 0.16], | |
'compactness_mean': [0.01, 0.10, 0.34], | |
'concavity_mean': [0.0, 0.08, 0.42], | |
'concave points_mean': [0.0, 0.04, 0.20], | |
'symmetry_mean': [0.10, 0.18, 0.30], | |
'fractal_dimension_mean': [0.04, 0.06, 0.09], | |
'radius_se': [0.11, 0.40, 2.87], | |
'texture_se': [0.36, 1.21, 4.88], | |
'perimeter_se': [0.75, 2.86, 21.98], | |
'area_se': [6.80, 40.33, 542.2], | |
'smoothness_se': [0.001, 0.007, 0.031], | |
'compactness_se': [0.002, 0.025, 0.135], | |
'concavity_se': [0.0, 0.031, 0.396], | |
'concave points_se': [0.0, 0.011, 0.052], | |
'symmetry_se': [0.007, 0.020, 0.078], | |
'fractal_dimension_se': [0.0008, 0.003, 0.029], | |
'radius_worst': [7.93, 16.26, 36.04], | |
'texture_worst': [12.02, 25.67, 49.54], | |
'perimeter_worst': [50.41, 107.26, 251.2], | |
'area_worst': [185.2, 880.5, 4254.0], | |
'smoothness_worst': [0.07, 0.13, 0.22], | |
'compactness_worst': [0.02, 0.25, 1.05], | |
'concavity_worst': [0.0, 0.27, 1.25], | |
'concave points_worst': [0.0, 0.11, 0.29], | |
'symmetry_worst': [0.15, 0.29, 0.66], | |
'fractal_dimension_worst': [0.05, 0.08, 0.20] | |
} | |
feature_names = list(FEATURE_INFO.keys()) | |
# --- 2. Streamlit App Interface --- | |
st.set_page_config(page_title="Breast Cancer Diagnosis System", layout="wide") | |
# Main Title | |
st.title("π¬ Breast Cancer Diagnosis System Interface") | |
st.markdown(""" | |
This application uses a pre-trained model to predict whether a breast tumor is **Malignant** or **Benign**. | |
""") | |
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 the hardcoded info | |
for feature, values in FEATURE_INFO.items(): | |
min_val, mean_val, max_val = values | |
input_features[feature] = st.sidebar.slider( | |
label=f"{feature.replace('_', ' ').title()}", | |
min_value=float(min_val), | |
max_value=float(max_val), | |
value=float(mean_val), # Default to the mean value | |
key=f"slider_{feature}" | |
) | |
st.sidebar.write("---") | |
# --- 4. Prediction Logic --- | |
# Convert the dictionary of input features into a NumPy array | |
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 | |
prediction_label = model.predict(input_data)[0] | |
# Get prediction probabilities | |
prediction_proba = model.predict_proba(input_data)[0] | |
with col2: | |
st.subheader("Diagnosis") | |
# Display the predicted label | |
if str(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 | |
for i, label in enumerate(class_labels): | |
display_label = "Malignant" if str(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("---") |