testing out the new model - more reasonable behaviour

This commit is contained in:
Khalim Conn-Kowlessar 2024-08-09 08:52:34 +01:00
parent 58374e7a6d
commit 935cfb24cf
6 changed files with 51 additions and 107 deletions

View file

@ -384,8 +384,9 @@ class Property:
types = [x["type"] for x in previous_phase_representatives] types = [x["type"] for x in previous_phase_representatives]
if "external_wall_insulation" in types and "internal_wall_insulation" in types: if "external_wall_insulation" in types and "internal_wall_insulation" in types:
raise Exception("We shouldn't have this in the representative recommendations") raise Exception("We shouldn't have this in the representative recommendations")
# We include previous phases + the recommendation itself in the EPC transformations
epc_transformations = [ epc_transformations = [
x["description_simulation"] for x in previous_phase_representatives x["description_simulation"] for x in previous_phase_representatives + [rec]
] ]
# It is possible that we could have two simulations applied to the same descriptions # It is possible that we could have two simulations applied to the same descriptions
@ -439,8 +440,6 @@ class Property:
sim_epc.update( sim_epc.update(
{ {
"heating-cost-current": rec_impact["epc_heating_cost"],
"hot-water-cost-current": rec_impact["epc_hot_water_cost"],
# CO₂ emissions per square metre floor area per year in kg/m². Since CO₂ emissions are in tonnes # CO₂ emissions per square metre floor area per year in kg/m². Since CO₂ emissions are in tonnes
# per year, we multiply by 1000 to get kg/m² # per year, we multiply by 1000 to get kg/m²
"co2-emiss-curr-per-floor-area": round( "co2-emiss-curr-per-floor-area": round(
@ -450,7 +449,6 @@ class Property:
"current-energy-rating": sap_to_epc(rec_impact["sap"]), "current-energy-rating": sap_to_epc(rec_impact["sap"]),
"current-energy-efficiency": int(np.floor(rec_impact["sap"])), "current-energy-efficiency": int(np.floor(rec_impact["sap"])),
"energy-consumption-current": rec_impact["heat_demand"], "energy-consumption-current": rec_impact["heat_demand"],
"lighting-cost-current": rec_impact["epc_lighting_cost"],
"id": "+".join([str(self.id), rec_id]) "id": "+".join([str(self.id), rec_id])
} }
) )
@ -594,8 +592,7 @@ class Property:
Given the cleaning that has been performed, we'll use this to identify the property Given the cleaning that has been performed, we'll use this to identify the property
components, from roof to walls to windows, heating and hot water components, from roof to walls to windows, heating and hot water
:param cleaned: This is the dictionary of components found in cleaner.cleaned :param cleaned: This is the dictionary of components found in cleaner.cleaned
:param energy_consumption_client: Contains the heating and hot water kwh models - used to predict current :param energy_consumption_client: The client that will be used to convert the energy costs to today's costs
energy annual consumption in kWh
:param kwh_predictions: Contains the kwh predictions for heating and hot water :param kwh_predictions: Contains the kwh predictions for heating and hot water
:return: :return:
""" """
@ -686,14 +683,6 @@ class Property:
# 2) Predicted KwH # 2) Predicted KwH
# Today's costs # Today's costs
todays_heating_cost = energy_consumption_client.convert_cost_to_today(
original_cost=float(self.data["heating-cost-current"]),
lodgement_date=pd.Timestamp(self.epc_record.prepared_epc["lodgement_date"]).tz_localize(None)
)
todays_hot_water_cost = energy_consumption_client.convert_cost_to_today(
original_cost=float(self.data["hot-water-cost-current"]),
lodgement_date=pd.Timestamp(self.epc_record.prepared_epc["lodgement_date"]).tz_localize(None)
)
todays_lighting_cost = energy_consumption_client.convert_cost_to_today( todays_lighting_cost = energy_consumption_client.convert_cost_to_today(
original_cost=float(self.data["lighting-cost-current"]), original_cost=float(self.data["lighting-cost-current"]),
lodgement_date=pd.Timestamp(self.epc_record.prepared_epc["lodgement_date"]).tz_localize(None) lodgement_date=pd.Timestamp(self.epc_record.prepared_epc["lodgement_date"]).tz_localize(None)
@ -702,15 +691,6 @@ class Property:
# If we have the kwh figures, we don't need to predict them # If we have the kwh figures, we don't need to predict them
condition_data = self.energy_assessment_condition_data.copy() condition_data = self.energy_assessment_condition_data.copy()
# scoring_df = pd.DataFrame([self.epc_record.prepared_epc])
# # Change columns from underscores to hyphens
# scoring_df.columns = [
# x.lower().replace("_", "-") for x in scoring_df.columns
# ]
# for col in ["heating_kwh", "hot_water_kwh"]:
# scoring_df[col] = None
#
# energy_consumption_client.data = None
heating_kwh_predictions = kwh_predictions["heating_kwh_predictions"] heating_kwh_predictions = kwh_predictions["heating_kwh_predictions"]
hotwater_kwh_predictions = kwh_predictions["hotwater_kwh_predictions"] hotwater_kwh_predictions = kwh_predictions["hotwater_kwh_predictions"]

View file

@ -588,7 +588,7 @@ async def trigger_plan(body: PlanTriggerRequest):
raise Exception("Missed setting of spatial data for a property") raise Exception("Missed setting of spatial data for a property")
p.get_components( p.get_components(
cleaned=cleaned, cleaned=cleaned,
energy_consumption_client=energy_consumption_client, # TODO: Full remove me energy_consumption_client=energy_consumption_client,
kwh_predictions=kwh_predictions kwh_predictions=kwh_predictions
) )
@ -799,7 +799,6 @@ async def trigger_plan(body: PlanTriggerRequest):
logger.info("Optimising recommendations") logger.info("Optimising recommendations")
scoring_epcs = [] # For scoring the kwh models scoring_epcs = [] # For scoring the kwh models
for property_id in recommendations.keys(): for property_id in recommendations.keys():
property_instance = [p for p in input_properties if p.id == property_id][0] property_instance = [p for p in input_properties if p.id == property_id][0]
recommendations_with_impact, impact_summary = ( recommendations_with_impact, impact_summary = (
@ -880,6 +879,8 @@ async def trigger_plan(body: PlanTriggerRequest):
extract_ids=True extract_ids=True
) )
# TODO: Costing model, which should include today's costs!
# We now insert into the recommendations # We now insert into the recommendations
for property_id in recommendations.keys(): for property_id in recommendations.keys():
property_recommendations = recommendations[property_id] property_recommendations = recommendations[property_id]

View file

@ -12,20 +12,20 @@ class ModelApi:
"sap_change_predictions", "sap_change_predictions",
"heat_demand_predictions", "heat_demand_predictions",
"carbon_change_predictions", "carbon_change_predictions",
"lighting_cost_predictions", # "lighting_cost_predictions",
"heating_cost_predictions", # "heating_cost_predictions",
"hot_water_cost_predictions", # "hot_water_cost_predictions",
] ]
MODEL_URLS = { MODEL_URLS = {
"sap_change_predictions": "sapmodel", "sap_change_predictions": "sapmodel",
"heat_demand_predictions": "heatmodel", "heat_demand_predictions": "heatmodel",
"carbon_change_predictions": "carbonmodel", "carbon_change_predictions": "carbonmodel",
"lighting_cost_predictions": "lightingmodel",
"heating_cost_predictions": "heatingmodel",
"hot_water_cost_predictions": "hotwatermodel",
"hotwater_kwh_predictions": "hotwaterkwhmodel", "hotwater_kwh_predictions": "hotwaterkwhmodel",
"heating_kwh_predictions": "heatingkwhmodel", "heating_kwh_predictions": "heatingkwhmodel",
# "lighting_cost_predictions": "lightingmodel",
# "heating_cost_predictions": "heatingmodel",
# "hot_water_cost_predictions": "hotwatermodel",
} }
def __init__( def __init__(

View file

@ -134,8 +134,8 @@ def app():
for i, directory in tqdm(enumerate(epc_directories), total=len(epc_directories)): for i, directory in tqdm(enumerate(epc_directories), total=len(epc_directories)):
# Skip the first 50 # Skip the first 50
# if i < 57: if i < 18:
# continue continue
data = pd.read_csv(directory / "certificates.csv", low_memory=False) data = pd.read_csv(directory / "certificates.csv", low_memory=False)
# Rename the columns to the same format as the api returns # Rename the columns to the same format as the api returns

View file

@ -226,16 +226,18 @@ base_prediction = model_api.predict_all(
extract_ids=False extract_ids=False
) )
cwi_epc = epcs_for_scoring.copy() cwi_epc = pd.DataFrame([property_scoring_epcs[1].copy()])
cwi_epc["walls-description"] = "Cavity wall, filled cavity" cwi_epc = add_features_from_code(cwi_epc)
cwi_epc["walls-energy-eff"] = "Good" cwi_epc = add_estimate_annual_kwh(cwi_epc)
cwi_epc["heating-cost-current"] = 1650 # cwi_epc["walls-description"] = "Cavity wall, filled cavity"
cwi_epc["current-energy-efficiency"] = 72 # cwi_epc["walls-energy-eff"] = "Good"
cwi_epc["current-energy-rating"] = "C" # cwi_epc["heating-cost-current"] = 1650
cwi_epc["co2-emissions-current"] = 3.7 # cwi_epc["current-energy-efficiency"] = 72
cwi_epc["energy-consumption-current"] = 121 # cwi_epc["current-energy-rating"] = "C"
cwi_epc["co2-emiss-curr-per-floor-area"] = 19 # cwi_epc["co2-emissions-current"] = 3.7
cwi_epc["photo-supply"] = 0 # cwi_epc["energy-consumption-current"] = 121
# cwi_epc["co2-emiss-curr-per-floor-area"] = 19
# cwi_epc["photo-supply"] = 0
# cwi_epc["energy-consumption-current"] = # cwi_epc["energy-consumption-current"] =
# cwi_epc["roof-description"] = "Pitched, 300 mm loft insulation" # cwi_epc["roof-description"] = "Pitched, 300 mm loft insulation"
# cwi_epc["roof-energy-eff"] = "Very Good" # cwi_epc["roof-energy-eff"] = "Very Good"
@ -259,7 +261,27 @@ cwi_prediction = model_api.predict_all(
df=cwi_epc, df=cwi_epc,
bucket=get_settings().DATA_BUCKET, bucket=get_settings().DATA_BUCKET,
prediction_buckets=get_prediction_buckets(), prediction_buckets=get_prediction_buckets(),
model_prefixes=["heating_kwh_predictions"], model_prefixes=["heating_kwh_predictions", "hotwater_kwh_predictions"],
extract_ids=False extract_ids=False
) )
2344 - 2060
# 77 perryn
starting_heating = 19837.2
starting_hot_water = 2974.1
ending_heating = 17041.1
ending_hot_water = 2735.3
# 44 lindlings
starting_heating = 13327.1
starting_hot_water = 2349.5
ending_heating = 9672.3
ending_hot_water = 2030.2
ending_heating = 8695.1
ending_hot_water = 2437.0
heating_impact = starting_heating - ending_heating
hot_water_impact = starting_hot_water - ending_hot_water
total_impact = heating_impact + hot_water_impact

View file

@ -379,26 +379,13 @@ class Recommendations:
property_predictions = { property_predictions = {
prefix + "_predictions": all_predictions[prefix + "_predictions"][ prefix + "_predictions": all_predictions[prefix + "_predictions"][
all_predictions[prefix + "_predictions"]["property_id"] == str(property_instance.id) all_predictions[prefix + "_predictions"]["property_id"] == str(property_instance.id)
].copy() for prefix in [ ].copy() for prefix in ["sap_change", "heat_demand", "carbon_change"]
"sap_change", "heat_demand", "carbon_change", "lighting_cost", "heating_cost", "hot_water_cost"
]
} }
# We apply adjustments to each of the heating costs
for prefix in ["lighting_cost", "heating_cost", "hot_water_cost"]:
property_predictions[f"{prefix}_predictions"]["adjusted_cost"] = (
property_predictions[f"{prefix}_predictions"]["predictions"].apply(
lambda x: AnnualBillSavings.adjust_energy_to_metered(
x, current_epc_rating=property_instance.data["current-energy-rating"]
)
)
)
property_recommendations = recommendations[property_instance.id].copy() property_recommendations = recommendations[property_instance.id].copy()
# TODO: should fabric upgrades have an impact on hot water costs/kwh? increasing_variables = ["sap"]
# TODO: Generally, the costing models are just increasing. Maybe they're including something in the model decreasing_variables = ["carbon", "heat_demand"]
# that they shouldn't e.g. SAP, carbon, heat demand etc?
impact_summary = [] impact_summary = []
for recommendations_by_type in property_recommendations: for recommendations_by_type in property_recommendations:
@ -414,14 +401,6 @@ class Recommendations:
)]["predictions"].values[0] for prefix in ["sap_change", "heat_demand", "carbon_change"] )]["predictions"].values[0] for prefix in ["sap_change", "heat_demand", "carbon_change"]
} }
# For phase costs, we need adusted and unadjusted values
phase_cost = {
prefix: property_predictions[prefix + "_predictions"][
property_predictions[prefix + "_predictions"]["recommendation_id"] ==
str(rec["recommendation_id"])
] for prefix in ["lighting_cost", "heating_cost", "hot_water_cost"]
}
# We structure this so that depending on the phase, we capture the previous phase impacts and # We structure this so that depending on the phase, we capture the previous phase impacts and
# then just have one piece of code to calculate the difference # then just have one piece of code to calculate the difference
if rec["phase"] == 0: if rec["phase"] == 0:
@ -433,9 +412,6 @@ class Recommendations:
"sap": float(property_instance.data["current-energy-efficiency"]), "sap": float(property_instance.data["current-energy-efficiency"]),
"carbon": float(property_instance.data["co2-emissions-current"]), "carbon": float(property_instance.data["co2-emissions-current"]),
"heat_demand": float(property_instance.data["energy-consumption-current"]), "heat_demand": float(property_instance.data["energy-consumption-current"]),
"epc_heating_cost": float(property_instance.data["heating-cost-current"]),
"epc_hot_water_cost": float(property_instance.data["hot-water-cost-current"]),
"epc_lighting_cost": float(property_instance.data["lighting-cost-current"])
} }
else: else:
@ -463,26 +439,6 @@ class Recommendations:
"heat_demand": phase_energy_efficiency_metrics["heat_demand"], "heat_demand": phase_energy_efficiency_metrics["heat_demand"],
} }
static_cost_variables = (
["epc_heating_cost", "epc_hot_water_cost"] if
rec["type"] == "low_energy_lighting" else ["epc_lighting_cost"]
)
dynamic_cost_variables = [
v for v in ["epc_heating_cost", "epc_hot_water_cost", "epc_lighting_cost"]
if v not in static_cost_variables
]
# Take the static variables from the previous phase
current_phase_costs = {k: v for k, v in previous_phase_values.items() if k in static_cost_variables}
# Insert the dynamic variables from the current phase
for v in dynamic_cost_variables:
current_phase_costs[v] = phase_cost[v.split("epc_")[1]]["adjusted_cost"].values[0]
current_phase_values.update(current_phase_costs)
increasing_variables = ["sap"]
decreasing_variables = [
"carbon", "heat_demand", "epc_heating_cost", "epc_hot_water_cost", "epc_lighting_cost"
]
# For increasing variables, the new value needs to be higher than the previous, otherwise we set it to # For increasing variables, the new value needs to be higher than the previous, otherwise we set it to
# the previous # the previous
# For decreasing variables, the new value should be lower than the previous, otherwise we set it to # For decreasing variables, the new value should be lower than the previous, otherwise we set it to
@ -507,21 +463,6 @@ class Recommendations:
"carbon": previous_phase_values["carbon"] - current_phase_values["carbon"], "carbon": previous_phase_values["carbon"] - current_phase_values["carbon"],
# Decreasing # Decreasing
"heat_demand": previous_phase_values["heat_demand"] - current_phase_values["heat_demand"], "heat_demand": previous_phase_values["heat_demand"] - current_phase_values["heat_demand"],
# Decreasing
"epc_heating_cost": (
previous_phase_values["epc_heating_cost"] -
current_phase_values["epc_heating_cost"]
),
# Decreasing
"epc_hot_water_cost": (
previous_phase_values["epc_hot_water_cost"] -
current_phase_values["epc_hot_water_cost"]
),
# Decreasing
"epc_lighting_cost": (
previous_phase_values["epc_lighting_cost"] -
current_phase_values["epc_lighting_cost"]
)
} }
# Prevent from being negative # Prevent from being negative