bneay commited on
Commit
1abe17f
·
1 Parent(s): 5eea7ba

analysis model

Browse files
Files changed (2) hide show
  1. app.py +96 -0
  2. models/analytics_model.joblib +3 -0
app.py CHANGED
@@ -1,6 +1,7 @@
1
  # app.py
2
  # The core FastAPI application for our IGUDAR model
3
 
 
4
  import joblib
5
  import pandas as pd
6
  import numpy as np
@@ -9,6 +10,7 @@ from pydantic import BaseModel
9
  import warnings
10
  warnings.filterwarnings('ignore')
11
 
 
12
  # --- 1. DEFINE APP AND LOAD MODELS ---
13
 
14
  # Initialize the FastAPI app
@@ -35,6 +37,26 @@ except FileNotFoundError:
35
  print("❌ ERROR: Model or preprocessing files not found. Ensure they are in the /models directory.")
36
  model = None # Set to None to handle errors gracefully
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  # --- 2. DEFINE THE INPUT DATA MODEL ---
39
 
40
  # Pydantic model for input data validation.
@@ -140,6 +162,80 @@ def predict_valuation(property_data: PropertyFeatures):
140
  "model_used": "igudar_valuation_v1_xgboost"
141
  }
142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  @app.get("/")
144
  def read_root():
145
  return {"message": "Welcome to the IGUDAR AI Valuation API. Use the /docs endpoint to test."}
 
1
  # app.py
2
  # The core FastAPI application for our IGUDAR model
3
 
4
+ import os
5
  import joblib
6
  import pandas as pd
7
  import numpy as np
 
10
  import warnings
11
  warnings.filterwarnings('ignore')
12
 
13
+ MODEL_DIR = "./models"
14
  # --- 1. DEFINE APP AND LOAD MODELS ---
15
 
16
  # Initialize the FastAPI app
 
37
  print("❌ ERROR: Model or preprocessing files not found. Ensure they are in the /models directory.")
38
  model = None # Set to None to handle errors gracefully
39
 
40
+ # ... (existing code to load valuation model) ...
41
+
42
+ # --- NEW: Load the Investment Analytics Model ---
43
+ ANALYTICS_MODEL_PATH = os.path.join(MODEL_DIR, "analytics_model.joblib")
44
+ try:
45
+ analytics_bundle = joblib.load(ANALYTICS_MODEL_PATH)
46
+ analytics_models = analytics_bundle['models']
47
+ analytics_scaler = analytics_bundle['scaler']
48
+ analytics_encoders = analytics_bundle['label_encoders']
49
+ analytics_feature_names = analytics_bundle['feature_names']
50
+ analytics_target_names = analytics_bundle['target_names']
51
+
52
+ print("✅ Investment Analytics models loaded successfully.")
53
+
54
+ except Exception as e:
55
+ print(f"❌ ERROR: Could not load analytics model. Error: {e}")
56
+ analytics_models = None
57
+
58
+ # --- (The rest of your startup code remains the same) ---
59
+
60
  # --- 2. DEFINE THE INPUT DATA MODEL ---
61
 
62
  # Pydantic model for input data validation.
 
162
  "model_used": "igudar_valuation_v1_xgboost"
163
  }
164
 
165
+ # --- 4. CREATE THE NEW INVESTMENT ANALYTICS ENDPOINT ---
166
+
167
+ @app.post("/analytics")
168
+ def predict_analytics(property_data: PropertyFeatures):
169
+ """
170
+ Predicts a full suite of 22+ financial and investment indicators for a property.
171
+ """
172
+ if analytics_models is None:
173
+ raise HTTPException(status_code=500, detail="Analytics model is not loaded. Check server logs.")
174
+
175
+ # Convert incoming data to a dictionary
176
+ data_dict = property_data.dict()
177
+
178
+ # --- Feature Preparation (must match analytics training script) ---
179
+
180
+ # Start with a dictionary of all zeros for our feature vector
181
+ features = {name: 0 for name in analytics_feature_names}
182
+
183
+ # Map input data to the feature vector
184
+ features.update({
185
+ 'price_mad': data_dict.get('price_mad', 1500000), # Assume a price if not provided for analytics
186
+ 'size_m2': data_dict.get('size_m2', 100),
187
+ 'bedrooms': data_dict.get('bedrooms', 2),
188
+ 'bathrooms': data_dict.get('bathrooms', 1),
189
+ 'age_years': data_dict.get('age_years', 5),
190
+ 'infrastructure_score': data_dict.get('infrastructure_score', 50),
191
+ 'economic_score': data_dict.get('economic_score', 50),
192
+ 'lifestyle_score': data_dict.get('lifestyle_score', 50),
193
+ 'investment_score': data_dict.get('investment_score', 50),
194
+ 'neighborhood_tier': data_dict.get('neighborhood_tier', 3),
195
+ 'total_amenities': data_dict.get('total_amenities', 20),
196
+ 'data_quality': data_dict.get('data_quality', 0.8)
197
+ })
198
+
199
+ # Calculate price_per_m2
200
+ if features['size_m2'] > 0:
201
+ features['price_per_m2'] = features['price_mad'] / features['size_m2']
202
+
203
+ # Encode categorical features
204
+ for col, le in analytics_encoders.items():
205
+ encoded_col_name = f"{col}_encoded"
206
+ if encoded_col_name in features:
207
+ try:
208
+ value = data_dict.get(col)
209
+ encoded_value = le.transform([value])[0]
210
+ features[encoded_col_name] = encoded_value
211
+ except:
212
+ features[encoded_col_name] = 0 # Default for unseen categories
213
+
214
+ # Create DataFrame in the exact order of feature_names
215
+ df = pd.DataFrame([features])[analytics_feature_names]
216
+
217
+ # Scale the features using the analytics scaler
218
+ df_scaled = analytics_scaler.transform(df)
219
+
220
+ # --- Get predictions from all specialist models ---
221
+ all_predictions = {}
222
+ for group_name, model in analytics_models.items():
223
+ # Predict the targets for this group
224
+ group_predictions = model.predict(df_scaled)[0]
225
+
226
+ # Get the names of the targets this model predicts
227
+ target_list = analytics_bundle['training_metrics'][group_name]['targets']
228
+
229
+ # Map the predicted values to their names
230
+ for i, target_name in enumerate(target_list):
231
+ all_predictions[target_name] = float(group_predictions[i]) # Convert to standard Python float
232
+
233
+ # Here you can add the logic to format the predictions into a nice structure
234
+ # like in your training script's demo (e.g., grouping by 'returns_forecast', 'risk_assessment').
235
+ # For simplicity, we'll return the raw predictions for now.
236
+
237
+ return {"predicted_analytics": all_predictions}
238
+
239
  @app.get("/")
240
  def read_root():
241
  return {"message": "Welcome to the IGUDAR AI Valuation API. Use the /docs endpoint to test."}
models/analytics_model.joblib ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8d8a30c33bd6ff6508a7d7ee41728a12be9869c77f5dd6a71bebe1733cf17fc3
3
+ size 62758342