| from datetime import datetime
|
| from pathlib import Path
|
| import joblib
|
| import pandas as pd
|
|
|
| from data_utils import enrich_data, load_raw_data
|
|
|
|
|
| _df = enrich_data(load_raw_data())
|
|
|
| MODEL_DIR = Path("models")
|
| _model = None
|
| try:
|
| if (MODEL_DIR / "gradient_boosting_model.pkl").exists():
|
| _model = joblib.load(MODEL_DIR / "gradient_boosting_model.pkl")
|
| except Exception as e:
|
| print("Model artifact loading warning:", e)
|
|
|
| def predict_price(sqft: float, bedrooms: int, bathrooms: int, year_built: int,
|
| quality: int, city: str, prop_type: str):
|
| if _model is None:
|
|
|
| city_pps = _df[_df["Location_City"] == city]["Price_Per_Sqft"].mean()
|
| if pd.isna(city_pps):
|
| city_pps = _df["Price_Per_Sqft"].mean()
|
| price = sqft * float(city_pps) * (1 + (quality - 5) * 0.02)
|
| return price, False
|
| try:
|
| age = datetime.now().year - year_built
|
| total_rooms = bedrooms + bathrooms
|
| size_per_room = sqft / total_rooms if total_rooms else sqft
|
| row = pd.DataFrame([{
|
| "Square_Footage": sqft,
|
| "Bedrooms": bedrooms,
|
| "Bathrooms": bathrooms,
|
| "Year_Built": year_built,
|
| "Property_Age": age,
|
| "Quality_Score": quality,
|
| "Total_Rooms": total_rooms,
|
| "Size_Per_Room": size_per_room,
|
| "Is_London": 1 if city == "London" else 0,
|
| "Is_Central_London": 0,
|
| "Is_Detached": 1 if prop_type == "Detached House" else 0,
|
| "Is_Townhouse": 1 if prop_type == "Townhouse" else 0,
|
| }])
|
| y = _model.predict(row)[0]
|
| return float(y), True
|
| except Exception:
|
| price = sqft * float(_df["Price_Per_Sqft"].mean())
|
| return price, False
|
|
|