diff --git a/backend/app/plan/router.py b/backend/app/plan/router.py index e75e65a1..985588e9 100644 --- a/backend/app/plan/router.py +++ b/backend/app/plan/router.py @@ -642,7 +642,6 @@ async def trigger_plan(body: PlanTriggerRequest): recommendations_scoring_data.extend(p.recommendations_scoring_data) # TODO: Make sure that number_habitable_rooms has been dropped - logger.info("Preparing data for scoring in sap change api") recommendations_scoring_data = pd.DataFrame(recommendations_scoring_data) @@ -651,18 +650,11 @@ async def trigger_plan(body: PlanTriggerRequest): "carbon_ending"] ) - all_predictions = model_api.predictions_template() - to_loop_over = range(0, recommendations_scoring_data.shape[0], SCORING_BATCH_SIZE) - for chunk in tqdm(to_loop_over, total=len(to_loop_over)): - predictions_dict = model_api.predict_all( - df=recommendations_scoring_data.iloc[chunk:chunk + SCORING_BATCH_SIZE], - bucket=get_settings().DATA_BUCKET, - prediction_buckets=get_prediction_buckets(), - ) - - # Append the predictions to the predictions dictionary - for key, scored in predictions_dict.items(): - all_predictions[key] = pd.concat([all_predictions[key], scored]) + all_predictions = model_api.paginated_predictions( + data=recommendations_scoring_data, + bucket=get_settings().DATA_BUCKET, + batch_size=SCORING_BATCH_SIZE + ) # Insert the predictions into the recommendations, and get the impact summary scoring_epcs = [] # For scoring the kwh models @@ -687,14 +679,29 @@ async def trigger_plan(body: PlanTriggerRequest): scoring_epcs = pd.DataFrame(scoring_epcs) scoring_epcs = kwh_client.transform(data=scoring_epcs, cleaned=cleaned) - kwh_simulation_predictions = model_api.predict_all( - df=scoring_epcs, + # There should be no difference between index 9 and index 8, apart from photo-supply (other that sap, etc) + a = scoring_epcs[scoring_epcs.index == 6] + b = scoring_epcs[scoring_epcs.index == 11] + difference = [] + for col in a.columns: + if a[col].values[0] != b[col].values[0]: + difference.append( + { + "col": col, + "without_solar": a[col].values[0], + "with_solar": b[col].values[0] + } + ) + difference = pd.DataFrame(difference) + + kwh_simulation_predictions = model_api.paginated_predictions( + data=scoring_epcs, bucket=get_settings().DATA_BUCKET, model_prefixes=["heating_kwh_predictions", "hotwater_kwh_predictions"], + batch_size=SCORING_BATCH_SIZE ) - # TODO: Costing model, which should include today's costs! - # We now insert into the recommendations + # We now insert kwh estimates and costs into the recommendations for property_id in recommendations.keys(): property_recommendations = recommendations[property_id] property_instance = [p for p in input_properties if p.id == property_id][0] @@ -1128,7 +1135,9 @@ async def build_mds(body: MdsRequest): "carbon_ending"] ) - model_api = ModelApi(portfolio_id=body.portfolio_id, timestamp=created_at) + model_api = ModelApi( + portfolio_id=body.portfolio_id, timestamp=created_at, prediction_buckets=get_prediction_buckets() + ) all_predictions = { "sap_change_predictions": pd.DataFrame(), diff --git a/backend/ml_models/api.py b/backend/ml_models/api.py index fab28e89..e922d7fc 100644 --- a/backend/ml_models/api.py +++ b/backend/ml_models/api.py @@ -1,4 +1,5 @@ import pandas as pd +from tqdm import tqdm import requests from requests.exceptions import RequestException from utils.logger import setup_logger @@ -55,9 +56,8 @@ class ModelApi: "sap_change_predictions": pd.DataFrame(), "heat_demand_predictions": pd.DataFrame(), "carbon_change_predictions": pd.DataFrame(), - "lighting_cost_predictions": pd.DataFrame(), - "heating_cost_predictions": pd.DataFrame(), - "hot_water_cost_predictions": pd.DataFrame(), + "hotwater_kwh_predictions": pd.DataFrame(), + "heating_kwh_predictions": pd.DataFrame(), } def upload_scoring_data(self, df: pd.DataFrame, bucket: str, model_prefix: str) -> str: @@ -179,3 +179,20 @@ class ModelApi: predictions[model_prefix] = predictions_df return predictions + + def paginated_predictions(self, data, bucket, batch_size, model_prefixes=None, extract_ids=True): + all_predictions = self.predictions_template() + to_loop_over = range(0, data.shape[0], batch_size) + for chunk in tqdm(to_loop_over, total=len(to_loop_over)): + predictions_dict = self.predict_all( + df=data.iloc[chunk:chunk + batch_size], + bucket=bucket, + model_prefixes=model_prefixes, + extract_ids=extract_ids + ) + + # Append the predictions to the predictions dictionary + for key, scored in predictions_dict.items(): + all_predictions[key] = pd.concat([all_predictions[key], scored]) + + return all_predictions diff --git a/recommendations/HeatingControlRecommender.py b/recommendations/HeatingControlRecommender.py index 6e827084..3e47c355 100644 --- a/recommendations/HeatingControlRecommender.py +++ b/recommendations/HeatingControlRecommender.py @@ -43,7 +43,7 @@ class HeatingControlRecommender: # For an ASHP, we can recommend time and temperature zone controls, as well as programmer, trvs and a bypass # which are common configurations for ASHPs self.recommend_time_temperature_zone_controls() - self.recommend_programmer_trvs_bypass() + # self.recommend_programmer_trvs_bypass() def recommend_room_heaters_electric_controls(self): """ diff --git a/recommendations/Recommendations.py b/recommendations/Recommendations.py index b8174ae0..588d2316 100644 --- a/recommendations/Recommendations.py +++ b/recommendations/Recommendations.py @@ -419,10 +419,7 @@ class Recommendations: previous_phase_values_multiple = [x for x in impact_summary if x["phase"] == (rec["phase"] - 1)] if len(previous_phase_values_multiple) != 1: # Take an average of each of the previous phases - keys_to_median = [ - "sap", "carbon", "heat_demand", "epc_heating_cost", "epc_hot_water_cost", - "epc_lighting_cost" - ] + keys_to_median = ["sap", "carbon", "heat_demand"] previous_phase_values = {} for key in keys_to_median: