import os os.environ["PGEOCODE_CACHE_DIR"] = "/tmp/pgeocode" import streamlit as st import pandas as pd import joblib def create_dataframe_from_user_input(): """ Collects user input for house features using Streamlit and returns a Pandas DataFrame. The input fields are organized into categorized sections for better usability. """ # Define the lists of possible values for dropdown selections type_list = ['HOUSE', 'APARTMENT'] subtype_list = ['HOUSE', 'APARTMENT', 'VILLA', 'APARTMENT_BLOCK', 'APARTMENT_GROUP', 'MIXED_USE_BUILDING', 'GROUND_FLOOR', 'DUPLEX', 'HOUSE_GROUP', 'FLAT_STUDIO', 'PENTHOUSE', 'EXCEPTIONAL_PROPERTY', 'MANSION', 'TOWN_HOUSE', 'SERVICE_FLAT', 'BUNGALOW', 'KOT', 'COUNTRY_COTTAGE', 'FARMHOUSE', 'LOFT', 'CHALET', 'TRIPLEX', 'CASTLE', 'OTHER_PROPERTY', 'MANOR_HOUSE', 'PAVILION'] province_list = ['West Flanders', 'Antwerp', 'East Flanders', 'Brussels', 'Hainaut', 'Liège', 'Flemish Brabant', 'Limburg', 'Walloon Brabant', 'Namur', 'Luxembourg'] building_condition_list = ['GOOD', 'AS_NEW', 'TO_RENOVATE', 'TO_BE_DONE_UP', 'JUST_RENOVATED', 'TO_RESTORE'] flood_zone_type_list = ['NON_FLOOD_ZONE', 'POSSIBLE_FLOOD_ZONE', 'RECOGNIZED_FLOOD_ZONE', 'RECOGNIZED_N_CIRCUMSCRIBED_FLOOD_ZONE', 'CIRCUMSCRIBED_WATERSIDE_ZONE', 'CIRCUMSCRIBED_FLOOD_ZONE', 'POSSIBLE_N_CIRCUMSCRIBED_FLOOD_ZONE', 'POSSIBLE_N_CIRCUMSCRIBED_WATERSIDE_ZONE', 'RECOGNIZED_N_CIRCUMSCRIBED_WATERSIDE_ZONE'] heating_type_list = ['GAS', 'FUELOIL', 'ELECTRIC', 'PELLET', 'WOOD', 'SOLAR', 'CARBON'] kitchen_type_list = ['INSTALLED', 'HYPER_EQUIPPED', 'SEMI_EQUIPPED', 'NOT_INSTALLED', 'USA_HYPER_EQUIPPED', 'USA_INSTALLED', 'USA_SEMI_EQUIPPED', 'USA_UNINSTALLED'] garden_orientation_list = ['SOUTH', 'SOUTH_WEST', 'SOUTH_EAST', 'WEST', 'EAST', 'NORTH_WEST', 'NORTH_EAST', 'NORTH'] terrace_orientation_list = ['SOUTH', 'SOUTH_WEST', 'SOUTH_EAST', 'WEST', 'EAST', 'NORTH_WEST', 'NORTH_EAST', 'NORTH'] epc_score_list = ['B', 'C', 'D', 'A', 'F', 'E', 'G', 'A+', 'A++'] # Create Streamlit input fields st.header("Enter House Information") # --- Property Details --- st.subheader("Property Details") col1, col2 = st.columns(2) with col1: property_type = st.selectbox("Property Type", type_list, key='type') property_subtype = st.selectbox("Subtype", subtype_list, key='subtype') province = st.selectbox("Province", province_list, key='province') locality = st.text_input("Locality", key='locality') post_code = st.number_input("Post Code", min_value=1000, max_value=9999, step=1, key='postCode') with col2: building_condition = st.selectbox("Building Condition", building_condition_list, key='buildingCondition') building_construction_year = st.number_input("Building Construction Year", min_value=1000, max_value=2024, step=1, key='buildingConstructionYear') facade_count = st.number_input("Facade Count", min_value=0, step=1, key='facadeCount') floor_count = st.number_input("Floor Count", min_value=0, step=1, key='floorCount') flood_zone_type = st.selectbox("Flood Zone Type", flood_zone_type_list, key='floodZoneType') epc_score = st.selectbox("EPC Score", epc_score_list, key='epcScore') # --- Room Information --- st.subheader("Room Information") col3, col4 = st.columns(2) with col3: bedroom_count = st.number_input("Bedroom Count", min_value=0, step=1, key='bedroomCount') bathroom_count = st.number_input("Bathroom Count", min_value=0, step=1, key='bathroomCount') room_count = st.number_input("Room Count", min_value=0, step=1, key='roomCount') has_attic = st.selectbox("Has Attic", ['Yes', 'No'], key='hasAttic') has_basement = st.selectbox("Has Basement", ['Yes', 'No'], key='hasBasement') has_dressing_room = st.selectbox("Has Dressing Room", ['Yes', 'No'], key='hasDressingRoom') has_dining_room = st.selectbox("Has Dining Room", ['Yes', 'No'], key='hasDiningRoom') dining_room_surface = st.number_input("Dining Room Surface (sqm)", min_value=0.0, key='diningRoomSurface') with col4: has_living_room = st.selectbox("Has Living Room", ['Yes', 'No'], key='hasLivingRoom') living_room_surface = st.number_input("Living Room Surface (sqm)", min_value=0.0, key='livingRoomSurface') kitchen_surface = st.number_input("Kitchen Surface (sqm)", min_value=0.0, key='kitchenSurface') kitchen_type = st.selectbox("Kitchen Type", kitchen_type_list, key='kitchenType') toilet_count = st.number_input("Toilet Count", min_value=0, step=1, key='toiletCount') has_office = st.selectbox("Has Office", ['Yes', 'No'], key='hasOffice') has_lift = st.selectbox("Has Lift", ['Yes', 'No'], key='hasLift') # --- Surface Areas --- st.subheader("Surface Areas") col5, col6 = st.columns(2) with col5: habitable_surface = st.number_input("Habitable Surface (sqm)", min_value=0.0, key='habitableSurface') land_surface = st.number_input("Land Surface (sqm)", min_value=0.0, key='landSurface') garden_surface = st.number_input("Garden Surface (sqm)", min_value=0.0, key='gardenSurface') with col6: terrace_surface = st.number_input("Terrace Surface (sqm)", min_value=0.0, key='terraceSurface') street_facade_width = st.number_input("Street Facade Width (m)", min_value=0.0, key='streetFacadeWidth') monthly_cost = st.number_input("Monthly Cost (€)", min_value=0.0, key='monthlyCost') # --- Outdoor Features --- st.subheader("Outdoor Features") col7, col8 = st.columns(2) with col7: has_garden = st.selectbox("Has Garden", ['Yes', 'No'], key='hasGarden') garden_orientation = st.selectbox("Garden Orientation", garden_orientation_list, key='gardenOrientation') has_balcony = st.selectbox("Has Balcony", ['Yes', 'No'], key='hasBalcony') has_terrace = st.selectbox("Has Terrace", ['Yes', 'No'], key='hasTerrace') terrace_orientation = st.selectbox("Terrace Orientation", terrace_orientation_list, key='terraceOrientation') with col8: parking_count_indoor = st.number_input("Indoor Parking Count", min_value=0, step=1, key='parkingCountIndoor') parking_count_outdoor = st.number_input("Outdoor Parking Count", min_value=0, step=1, key='parkingCountOutdoor') has_swimming_pool = st.selectbox("Has Swimming Pool", ['Yes', 'No'], key='hasSwimmingPool') # --- Additional Features --- st.subheader("Additional Features") col9, col10 = st.columns(2) with col9: heating_type = st.selectbox("Heating Type", heating_type_list, key='heatingType') has_heat_pump = st.selectbox("Has Heat Pump", ['Yes', 'No'], key='hasHeatPump') has_photovoltaic_panels = st.selectbox("Has Photovoltaic Panels", ['Yes', 'No'], key='hasPhotovoltaicPanels') has_thermic_panels = st.selectbox("Has Thermic Panels", ['Yes', 'No'], key='hasThermicPanels') with col10: has_air_conditioning = st.selectbox("Has Air Conditioning", ['Yes', 'No'], key='hasAirConditioning') has_armored_door = st.selectbox("Has Armored Door", ['Yes', 'No'], key='hasArmoredDoor') has_visiophone = st.selectbox("Has Visiophone", ['Yes', 'No'], key='hasVisiophone') has_fireplace = st.selectbox("Has Fireplace", ['Yes', 'No'], key='hasFireplace') accessible_disabled_people = st.selectbox("Accessible Disabled People", ['True', 'False'], key='accessibleDisabledPeople') # Create a button to trigger DataFrame creation if st.button("Predict"): # Create the DataFrame data = { 'type': property_type, 'subtype': property_subtype, 'bedroomCount': bedroom_count, 'bathroomCount': bathroom_count, 'province': province, 'locality': locality, 'postCode': post_code, 'habitableSurface': habitable_surface, 'roomCount': room_count, 'monthlyCost': monthly_cost, 'hasAttic': has_attic == 'Yes', 'hasBasement': has_basement == 'Yes', 'hasDressingRoom': has_dressing_room == 'Yes', 'diningRoomSurface': dining_room_surface, 'hasDiningRoom': has_dining_room == 'Yes', 'buildingCondition': building_condition, 'buildingConstructionYear': building_construction_year, 'facadeCount': facade_count, 'floorCount': floor_count, 'streetFacadeWidth': street_facade_width, 'hasLift': has_lift == 'Yes', 'floodZoneType': flood_zone_type, 'heatingType': heating_type, 'hasHeatPump': has_heat_pump == 'Yes', 'hasPhotovoltaicPanels': has_photovoltaic_panels == 'Yes', 'hasThermicPanels': has_thermic_panels == 'Yes', 'kitchenSurface': kitchen_surface, 'kitchenType': kitchen_type, 'landSurface': land_surface, 'hasLivingRoom': has_living_room == 'Yes', 'livingRoomSurface': living_room_surface, 'hasBalcony': has_balcony == 'Yes', 'hasGarden': has_garden == 'Yes', 'gardenSurface': garden_surface, 'gardenOrientation': garden_orientation, 'parkingCountIndoor': parking_count_indoor, 'parkingCountOutdoor': parking_count_outdoor, 'hasAirConditioning': has_air_conditioning == 'Yes', 'hasArmoredDoor': has_armored_door == 'Yes', 'hasVisiophone': has_visiophone == 'Yes', 'hasOffice': has_office == 'Yes', 'toiletCount': toilet_count, 'hasSwimmingPool': has_swimming_pool == 'Yes', 'hasFireplace': has_fireplace == 'Yes', 'hasTerrace': has_terrace == 'Yes', 'terraceSurface': terrace_surface, 'terraceOrientation': terrace_orientation, 'accessibleDisabledPeople': accessible_disabled_people == 'True', 'epcScore': epc_score } df = pd.DataFrame(data, index=[0]) pipeline = joblib.load('saved/pipeline.pkl') model = joblib.load('saved/model.pkl') expected_columns = joblib.load('saved/columns.pkl') df_test = pipeline.transform(df) for col in expected_columns: if col not in df_test.columns: df_test[col] = 0 df_test = df_test[expected_columns] preds = model.predict(df_test) st.subheader("Price prediction") st.markdown(f"

{preds[0]:.2f} €

", unsafe_allow_html=True) return df if __name__ == "__main__": create_dataframe_from_user_input()