szili2011 commited on
Commit
0164c97
·
verified ·
1 Parent(s): dd24533

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -27
app.py CHANGED
@@ -1,4 +1,4 @@
1
- # app.py - FINAL PROFESSIONAL version with input validation and guardrails
2
 
3
  import gradio as gr
4
  import joblib
@@ -6,7 +6,7 @@ import pandas as pd
6
  import os
7
  import subprocess
8
 
9
- # --- STEP 1: Download the Model Files from the Hub (same as before) ---
10
  MODEL_URL = "https://huggingface.co/szili2011/ai-house-price-predictor/resolve/main/housing_model.joblib"
11
  COLUMNS_URL = "https://huggingface.co/szili2011/ai-house-price-predictor/resolve/main/model_columns.joblib"
12
  MODEL_LOCAL_PATH = "housing_model.joblib"
@@ -18,11 +18,9 @@ if not os.path.exists(MODEL_LOCAL_PATH):
18
  subprocess.run(["wget", "-O", COLUMNS_LOCAL_PATH, COLUMNS_URL])
19
  print("--- Download Complete ---")
20
 
21
- # --- STEP 2: Load the Now-Local Model and Columns (same as before) ---
22
  try:
23
- print(f"Loading model from local path: '{MODEL_LOCAL_PATH}'")
24
  model = joblib.load(MODEL_LOCAL_PATH)
25
- print(f"Loading columns from local path: '{COLUMNS_LOCAL_PATH}'")
26
  model_columns = joblib.load(COLUMNS_LOCAL_PATH)
27
  print("✅ Model and columns loaded successfully.")
28
  model_loaded_successfully = True
@@ -31,31 +29,44 @@ except Exception as e:
31
  model_loaded_successfully = False
32
 
33
 
34
- # --- This is the core prediction function with the new validation logic ---
35
  def predict_price(sqft, bedrooms, house_age, condition, year_sold, interest_rate, region, sub_type, style, has_garage, has_pool):
36
  if not model_loaded_successfully:
37
  raise gr.Error("Model is not loaded. Please check the Space logs for errors.")
38
 
39
- # --- NEW: Input Validation Guardrails ---
40
- # Before we do anything, we check if the user's inputs are reasonable.
41
- # If not, we stop and send back a helpful error message.
42
- if not (300 <= sqft <= 30000):
43
- raise gr.Error(f"Input Error: Square Footage must be between 300 and 30,000. You entered {sqft}.")
44
- if not (1 <= bedrooms <= 20):
45
- raise gr.Error(f"Input Error: Number of Bedrooms must be between 1 and 20. You entered {bedrooms}.")
46
- if not (0 <= house_age <= 200):
47
- raise gr.Error(f"Input Error: House Age must be between 0 and 200. You entered {house_age}.")
48
- if not (2000 <= year_sold <= 2030):
49
- raise gr.Error(f"Input Error: Year Sold must be between 2000 and 2030. You entered {year_sold}.")
50
- if not (0 <= interest_rate <= 25):
51
- raise gr.Error(f"Input Error: Interest Rate must be between 0 and 25. You entered {interest_rate}.")
 
 
 
 
 
 
52
 
53
- # If all checks pass, we proceed with the prediction.
54
  input_data = {
55
- 'SquareFootage': sqft, 'Bedrooms': bedrooms, 'HouseAge': house_age,
56
- 'PropertyCondition': condition, 'HasGarage': has_garage, 'HasPool': has_pool,
57
- 'YearSold': year_sold, 'InterestRate': interest_rate,
58
- 'Region': region, 'SubType': sub_type, 'ArchitecturalStyle': style
 
 
 
 
 
 
 
59
  }
60
  input_df = pd.DataFrame([input_data])
61
 
@@ -66,11 +77,11 @@ def predict_price(sqft, bedrooms, house_age, condition, year_sold, interest_rate
66
 
67
  return f"${predicted_price:,.0f}"
68
 
69
- # --- Create the Gradio Interface with better UI limits ---
 
70
  demo = gr.Interface(
71
  fn=predict_price,
72
  inputs=[
73
- # --- NEW: Added minimum and maximum values to the UI components ---
74
  gr.Number(label="Square Footage", value=2500, minimum=300, maximum=30000),
75
  gr.Number(label="Bedrooms", value=4, minimum=1, maximum=20),
76
  gr.Number(label="House Age (years)", value=15, minimum=0, maximum=200),
@@ -85,7 +96,7 @@ demo = gr.Interface(
85
  ],
86
  outputs=gr.Textbox(label="Predicted Price"),
87
  title="AI House Price Predictor",
88
- description="Describe a property, and our AI will estimate its market value. This AI was trained on a 9.2GB simulated dataset and is hosted on Hugging Face."
89
  )
90
 
91
  # Launch the app
 
1
+ # app.py - FINAL POLISHED version with forgiving input clamping
2
 
3
  import gradio as gr
4
  import joblib
 
6
  import os
7
  import subprocess
8
 
9
+ # --- STEP 1: Download Model Files ---
10
  MODEL_URL = "https://huggingface.co/szili2011/ai-house-price-predictor/resolve/main/housing_model.joblib"
11
  COLUMNS_URL = "https://huggingface.co/szili2011/ai-house-price-predictor/resolve/main/model_columns.joblib"
12
  MODEL_LOCAL_PATH = "housing_model.joblib"
 
18
  subprocess.run(["wget", "-O", COLUMNS_LOCAL_PATH, COLUMNS_URL])
19
  print("--- Download Complete ---")
20
 
21
+ # --- STEP 2: Load Model and Columns ---
22
  try:
 
23
  model = joblib.load(MODEL_LOCAL_PATH)
 
24
  model_columns = joblib.load(COLUMNS_LOCAL_PATH)
25
  print("✅ Model and columns loaded successfully.")
26
  model_loaded_successfully = True
 
29
  model_loaded_successfully = False
30
 
31
 
32
+ # --- Core prediction function with the new, forgiving clamping logic ---
33
  def predict_price(sqft, bedrooms, house_age, condition, year_sold, interest_rate, region, sub_type, style, has_garage, has_pool):
34
  if not model_loaded_successfully:
35
  raise gr.Error("Model is not loaded. Please check the Space logs for errors.")
36
 
37
+ # --- NEW: Forgiving Input Clamping ---
38
+ # Instead of raising an error, we gently guide extreme inputs back into a reasonable range.
39
+ # The min() function takes the smaller of two numbers, the max() function takes the larger.
40
+ # This "clamps" the value between a minimum and a maximum.
41
+
42
+ # Clamp square footage between 300 and 30,000
43
+ sqft_clamped = max(300, min(sqft, 30000))
44
+
45
+ # Clamp bedrooms between 1 and 20
46
+ bedrooms_clamped = max(1, min(bedrooms, 20))
47
+
48
+ # Clamp house age between 0 and 200
49
+ house_age_clamped = max(0, min(house_age, 200))
50
+
51
+ # Clamp year sold between 2000 and 2030
52
+ year_sold_clamped = max(2000, min(year_sold, 2030))
53
+
54
+ # Clamp interest rate between 0 and 25
55
+ interest_rate_clamped = max(0.0, min(interest_rate, 25.0))
56
 
57
+ # We now use these "safe" clamped values for the prediction.
58
  input_data = {
59
+ 'SquareFootage': sqft_clamped,
60
+ 'Bedrooms': bedrooms_clamped,
61
+ 'HouseAge': house_age_clamped,
62
+ 'PropertyCondition': condition,
63
+ 'HasGarage': has_garage,
64
+ 'HasPool': has_pool,
65
+ 'YearSold': year_sold_clamped,
66
+ 'InterestRate': interest_rate_clamped,
67
+ 'Region': region,
68
+ 'SubType': sub_type,
69
+ 'ArchitecturalStyle': style
70
  }
71
  input_df = pd.DataFrame([input_data])
72
 
 
77
 
78
  return f"${predicted_price:,.0f}"
79
 
80
+ # --- Gradio Interface with UI limits ---
81
+ # The UI limits still provide a good first line of guidance for the user.
82
  demo = gr.Interface(
83
  fn=predict_price,
84
  inputs=[
 
85
  gr.Number(label="Square Footage", value=2500, minimum=300, maximum=30000),
86
  gr.Number(label="Bedrooms", value=4, minimum=1, maximum=20),
87
  gr.Number(label="House Age (years)", value=15, minimum=0, maximum=200),
 
96
  ],
97
  outputs=gr.Textbox(label="Predicted Price"),
98
  title="AI House Price Predictor",
99
+ description="Describe a property, and our AI will estimate its market value. The model is robust and will provide estimates even for extreme values by capping them to its known limits."
100
  )
101
 
102
  # Launch the app