import streamlit as st import numpy as np import pandas as pd import os import joblib import pickle try: from tensorflow.keras.models import load_model as keras_load_model KERAS_AVAILABLE = True except Exception: KERAS_AVAILABLE = False st.set_page_config(page_title="House Price Predictor (fixed model)", layout="centered") st.title("🏠 Simple House Price Predictor") st.write("This app loads a fixed model file: `house_price_model.h5` and predicts house price from features.") # ----------------------- # HARD-CODED MODEL PATH # ----------------------- MODEL_PATH = "house_price_model.h5" # <-- hard-coded model filename # Utility: load model from path (supports .h5, .joblib, .pkl) def load_model_from_path(path): """Load model from a local path (joblib/pickle/keras .h5).""" ext = os.path.splitext(path)[1].lower() if ext in [".joblib", ".pkl"]: try: return joblib.load(path) except Exception: with open(path, "rb") as f: return pickle.load(f) if ext == ".h5": if not KERAS_AVAILABLE: raise RuntimeError("TensorFlow/Keras not available. Add `tensorflow` to requirements.txt.") return keras_load_model(path) raise ValueError("Unsupported model extension: " + ext) # Cached loader so HF/Streamlit won't reload unnecessarily @st.cache_resource def load_fixed_model(): return load_model_from_path(MODEL_PATH) # Attempt to load the fixed model model = None if os.path.exists(MODEL_PATH): try: model = load_fixed_model() st.sidebar.success(f"Loaded model: {MODEL_PATH}") except Exception as e: st.sidebar.error(f"Failed to load {MODEL_PATH}: {e}") model = None else: st.sidebar.warning(f"Model file not found: {MODEL_PATH}") st.sidebar.info("Add `house_price_model.h5` to the repo root (or your HF Space files) and re-run the app.") st.markdown("---") st.header("Input features") # Feature inputs (keep these in same order your model expects) col1, col2 = st.columns(2) with col1: overall_qual = st.slider("Overall Quality (1 - 10)", 1, 10, 6) gr_liv_area = st.number_input("Ground living area (sq ft)", min_value=100, max_value=10000, value=1500, step=50) garage_cars = st.number_input("Garage capacity (cars)", min_value=0, max_value=10, value=1, step=1) with col2: total_bsmt = st.number_input("Total Basement Area (sq ft)", min_value=0, max_value=10000, value=600, step=50) full_bath = st.number_input("Full bathrooms", min_value=0, max_value=10, value=2, step=1) year_built = st.number_input("Year Built", min_value=1800, max_value=2050, value=1990, step=1) st.markdown("**Feature vector preview (in expected model order):**") input_vector = np.array([overall_qual, gr_liv_area, garage_cars, total_bsmt, full_bath, year_built]) st.write(pd.DataFrame([input_vector], columns=["OverallQual","GrLivArea","GarageCars","TotalBsmtSF","FullBath","YearBuilt"])) predict_button = st.button("Predict House Price") def model_predict(model_obj, features_array): """Unify prediction call for sklearn-like and keras models.""" X = np.array(features_array).reshape(1, -1) # Try sklearn-like predict first try: if hasattr(model_obj, "predict") and not (KERAS_AVAILABLE and hasattr(model_obj, "save")): preds = model_obj.predict(X) if isinstance(preds, (list, np.ndarray)): return float(np.squeeze(preds)) return float(preds) except Exception: pass # Try Keras model if KERAS_AVAILABLE: try: preds = model_obj.predict(X) return float(np.squeeze(preds)) except Exception: pass raise RuntimeError("Model type not supported for prediction or prediction failed.") if predict_button: if model is None: st.error("Model not loaded. Ensure `house_price_model.h5` exists in repo and that `tensorflow` is installed.") else: try: pred = model_predict(model, input_vector) st.success(f"Predicted house price: {pred:,.2f} (units same as model target)") st.info("If value seems off, ensure model expects these features in this order and any scalers/pipelines are included.") except Exception as e: st.exception(f"Prediction failed: {e}")