Spaces:
Sleeping
Sleeping
A-New-Day-001
commited on
Commit
•
2670d80
1
Parent(s):
4029cf7
Update screens/predict.py
Browse files- screens/predict.py +126 -118
screens/predict.py
CHANGED
@@ -1,125 +1,133 @@
|
|
1 |
import streamlit as st
|
2 |
-
import
|
3 |
-
import numpy as np
|
4 |
from autogluon.multimodal import MultiModalPredictor
|
5 |
from autogluon.tabular import TabularPredictor
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
submit_icon = "📝"
|
11 |
-
predict_icon = "🔮"
|
12 |
-
|
13 |
-
# Initialize df as a global variable
|
14 |
-
df = None
|
15 |
-
|
16 |
-
def predict_price():
|
17 |
-
global df # Declare df as a global variable
|
18 |
-
# Set the title and subheader
|
19 |
-
st.title("Real Estate Price Prediction")
|
20 |
-
st.subheader("Choose your role and provide property details")
|
21 |
-
|
22 |
-
# User role selection
|
23 |
-
option = st.selectbox("Who are you?", ['Seller', 'Buyer'], index=0)
|
24 |
-
|
25 |
-
if option == "Seller":
|
26 |
-
st.subheader(f"{seller_icon} Seller Information")
|
27 |
-
with st.spinner("Loading model..."):
|
28 |
-
predictor = MultiModalPredictor.load("C:/Users/duong/OneDrive/Desktop/mm-nlp-image-transformer")
|
29 |
-
st.success("Done")
|
30 |
-
description = st.text_area("Property Description", help="Describe your property")
|
31 |
-
title = st.text_input("Property Title", help="Enter a title for your property")
|
32 |
else:
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
124 |
|
|
|
|
|
|
|
125 |
|
|
|
1 |
import streamlit as st
|
2 |
+
import json
|
|
|
3 |
from autogluon.multimodal import MultiModalPredictor
|
4 |
from autogluon.tabular import TabularPredictor
|
5 |
+
import pandas as pd
|
6 |
+
from geopy.geocoders import GoogleV3
|
7 |
+
import os
|
8 |
+
import tempfile
|
9 |
+
|
10 |
+
def predict_page():
|
11 |
+
# Add a title with an icon
|
12 |
+
st.image("icon.png", width=80)
|
13 |
+
st.title("💵 Property Price Estimator")
|
14 |
+
|
15 |
+
# User role selection (buyer or seller)
|
16 |
+
user_role = st.selectbox("Select Your Role", options=["Buyer", "Seller"])
|
17 |
+
|
18 |
+
# Load geocoder and model based on user role
|
19 |
+
@st.cache(allow_output_mutation=True)
|
20 |
+
def load_geocoder():
|
21 |
+
return GoogleV3(api_key=os.environ.get("GOOGLE_MAP_API_KEY"))
|
22 |
|
23 |
+
geocoder = load_geocoder()
|
24 |
+
if user_role == "Buyer":
|
25 |
+
model_path = "models/mm-nlp-image-transformer/"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
else:
|
27 |
+
model_path = "models/tabular/"
|
28 |
+
|
29 |
+
@st.cache(allow_output_mutation=True)
|
30 |
+
def load_mm_text_model():
|
31 |
+
if user_role == "Seller":
|
32 |
+
return MultiModalPredictor.load(model_path, verbosity=0)
|
33 |
+
elif user_role == "Buyer":
|
34 |
+
return TabularPredictor.load(model_path, verbosity=0)
|
35 |
+
|
36 |
+
mm_text_predictor = load_mm_text_model()
|
37 |
+
|
38 |
+
# Common user input fields
|
39 |
+
st.header("Location Details")
|
40 |
+
city_map = json.load(open("city-map.json"))
|
41 |
+
city = st.selectbox("Choose city 🏙️", options=list(city_map.values()))
|
42 |
+
city_district_map = json.load(open("city-district-map.json"))
|
43 |
+
district = st.selectbox("Choose district 🏘️", options=list(city_district_map[city].values()))
|
44 |
+
location = st.text_input("Enter precise location 📍")
|
45 |
+
|
46 |
+
st.header("Property Specifications")
|
47 |
+
area = st.number_input("Area (m2) 📏", min_value=1.0)
|
48 |
+
bedrooms = st.number_input("Number of bedrooms 🛏️", min_value=1, value=1)
|
49 |
+
bathrooms = st.number_input("Number of bathrooms 🚽", min_value=1, value=1)
|
50 |
+
floors = st.number_input("Number of floors 🏢", min_value=1, value=1)
|
51 |
+
front_width = st.number_input("Front width (m) 📏", min_value=0.0, value=0.0, step=0.1)
|
52 |
+
road_width = st.number_input("Road width (m) 🚗", min_value=0.0, value=0.0, step=0.1)
|
53 |
+
|
54 |
+
st.header("Additional Details")
|
55 |
+
timestamp = st.date_input("Date posted 📅")
|
56 |
+
cert_status = st.selectbox("Certification status 📜", options=["Không có", "hợp đồng", "sổ đỏ / sổ hồng"])
|
57 |
+
direction = st.selectbox("Direction 🧭", options=["Không có", "Tây - Nam", "Đông - Nam", "Đông - Bắc", "Tây - Bắc", "Nam", "Tây", "Bắc", "Đông"])
|
58 |
+
balcony_direction = st.selectbox("Balcony direction 🌞", options=["Không có", "Tây - Nam", "Đông - Nam", "Đông - Bắc", "Tây - Bắc", "Nam", "Tây", "Bắc", "Đông"])
|
59 |
+
|
60 |
+
# Description and image upload (conditional for sellers)
|
61 |
+
if user_role == "Seller":
|
62 |
+
description = st.text_area("Description ✍️")
|
63 |
+
title = description.split(".", maxsplit=1)[0]
|
64 |
+
|
65 |
+
uploaded_image = st.file_uploader("Upload an image 📷")
|
66 |
+
image_tmp = None
|
67 |
+
if uploaded_image:
|
68 |
+
image_tmp = tempfile.NamedTemporaryFile(suffix=uploaded_image.name)
|
69 |
+
image_tmp.write(uploaded_image.read())
|
70 |
+
st.image(uploaded_image, caption='Uploaded Image', use_column_width=True)
|
71 |
+
else:
|
72 |
+
description = ""
|
73 |
+
title = ""
|
74 |
+
|
75 |
+
# Calculate latitude and longitude
|
76 |
+
location = (location + ", " if location else "") + city + ", " + district
|
77 |
+
geocode_result = geocoder.geocode(query=location, region="vn", language="vi")
|
78 |
+
latitude = geocode_result.latitude
|
79 |
+
longitude = geocode_result.longitude
|
80 |
+
|
81 |
+
# Display location map
|
82 |
+
st.map([(latitude, longitude)], zoom=15)
|
83 |
+
|
84 |
+
# Create a button with an icon to get estimated price
|
85 |
+
if st.button("Get Estimated Price with Text 💰"):
|
86 |
+
if user_role == "Seller":
|
87 |
+
input_data = {
|
88 |
+
"Title": title,
|
89 |
+
"Area": area,
|
90 |
+
"Location": location,
|
91 |
+
"Time stamp": timestamp,
|
92 |
+
"Certification status": cert_status,
|
93 |
+
"Direction": direction,
|
94 |
+
"Bedrooms": bedrooms,
|
95 |
+
"Bathrooms": bathrooms,
|
96 |
+
"Front width": front_width or float("nan"),
|
97 |
+
"Floor": floors,
|
98 |
+
"Description": description,
|
99 |
+
"Image URL": image_tmp.name if image_tmp else None,
|
100 |
+
"Road width": road_width or float("nan"),
|
101 |
+
"City_code": city,
|
102 |
+
"DistrictId": district,
|
103 |
+
"Lattitude": latitude,
|
104 |
+
"Longitude": longitude,
|
105 |
+
"Balcony_Direction": balcony_direction,
|
106 |
+
}
|
107 |
+
elif user_role == "Buyer":
|
108 |
+
input_data = {
|
109 |
+
"Area": area,
|
110 |
+
"Location": location,
|
111 |
+
"Time stamp": timestamp,
|
112 |
+
"Certification status": cert_status,
|
113 |
+
"Direction": direction,
|
114 |
+
"Bedrooms": bedrooms,
|
115 |
+
"Bathrooms": bathrooms,
|
116 |
+
"Front width": front_width or float("nan"),
|
117 |
+
"Floor": floors,
|
118 |
+
"Image URL": image_tmp.name if image_tmp else None,
|
119 |
+
"Road width": road_width or float("nan"),
|
120 |
+
"City_code": city,
|
121 |
+
"DistrictId": district,
|
122 |
+
"Lattitude": latitude,
|
123 |
+
"Longitude": longitude,
|
124 |
+
"Balcony_Direction": balcony_direction,
|
125 |
+
}
|
126 |
+
|
127 |
+
input_df = pd.DataFrame([input_data])
|
128 |
+
predicted_price = mm_text_predictor.predict(input_df, as_pandas=False).item()
|
129 |
|
130 |
+
# Display the estimated price with an icon
|
131 |
+
st.subheader("Estimated Price 💲")
|
132 |
+
st.write(f"{predicted_price * 1e6:,.0f} VND")
|
133 |
|