MikkelONielsen
commited on
Commit
•
99d24ec
1
Parent(s):
aa4ffca
Update app.py
Browse files
app.py
CHANGED
@@ -1,4 +1,3 @@
|
|
1 |
-
# app.py
|
2 |
# Loading packages
|
3 |
import datetime
|
4 |
import joblib
|
@@ -16,10 +15,9 @@ import random
|
|
16 |
|
17 |
# Configuring the web page and setting the page title and icon
|
18 |
st.set_page_config(
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
)
|
23 |
|
24 |
# Ignoring filtering warnings
|
25 |
warnings.filterwarnings("ignore")
|
@@ -28,47 +26,44 @@ warnings.filterwarnings("ignore")
|
|
28 |
st.title('Parking Occupancy Detection')
|
29 |
|
30 |
# Creating tabs for the different features of the application
|
31 |
-
tab1,
|
32 |
-
['Parking lot status', 'Magnetic Field Explorer', 'About', 'Dataset and visualisations', 'Model performance']
|
33 |
-
)
|
34 |
|
35 |
with tab1:
|
36 |
# Logging in to Hopsworks and loading the feature store
|
37 |
-
project = hopsworks.login(project="miknie20", api_key_value=os.environ['HOPSWORKS_API_KEY'])
|
38 |
fs = project.get_feature_store()
|
39 |
|
40 |
col1, col2 = st.columns(2)
|
41 |
|
42 |
-
@st.cache_data()
|
43 |
-
def get_building_model():
|
44 |
-
mr = project.get_model_registry()
|
45 |
-
building_model = mr.get_model("building_hist_model", version=2)
|
46 |
-
building_model_dir = building_model.download()
|
47 |
-
return joblib.load(building_model_dir + "/building_hist_model.pkl")
|
48 |
-
|
49 |
-
@st.cache_data()
|
50 |
-
def retrieve_building():
|
51 |
-
feature_group = fs.get_feature_group(name='api_building_newest', version=1)
|
52 |
-
feature_group = feature_group.select(["time", "x", "y", "z"])
|
53 |
-
return feature_group.read(read_options={"use_hive": True})
|
54 |
-
|
55 |
-
@st.cache_data()
|
56 |
-
def get_bikelane_model():
|
57 |
-
mr = project.get_model_registry()
|
58 |
-
bikelane_model = mr.get_model("bikelane_hist_model", version=1)
|
59 |
-
bikelane_model_dir = bikelane_model.download()
|
60 |
-
return joblib.load(bikelane_model_dir + "/bikelane_hist_model.pkl")
|
61 |
-
|
62 |
-
@st.cache_data()
|
63 |
-
def retrieve_bikelane():
|
64 |
-
feature_group = fs.get_feature_group(name='api_bikelane_newest', version=1)
|
65 |
-
feature_group = feature_group.select(["time", "x", "y", "z"])
|
66 |
-
return feature_group.read(read_options={"use_hive": True})
|
67 |
-
|
68 |
with col1:
|
69 |
st.subheader("Parking place near building:")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
building_hist_model = get_building_model()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
building_new = retrieve_building()
|
|
|
|
|
72 |
building_most_recent_prediction = building_new[['x', 'y', 'z']]
|
73 |
building_most_recent_prediction = building_hist_model.predict(building_most_recent_prediction)
|
74 |
building_new['Status'] = building_most_recent_prediction
|
@@ -79,24 +74,52 @@ with tab1:
|
|
79 |
|
80 |
with col2:
|
81 |
st.subheader("Parking place near bikelane:")
|
82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
bikelane_new = retrieve_bikelane()
|
|
|
|
|
84 |
bikelane_most_recent_prediction = bikelane_new[['x', 'y', 'z']]
|
85 |
bikelane_most_recent_prediction = bikelane_hist_model.predict(bikelane_most_recent_prediction)
|
86 |
bikelane_new['Status'] = bikelane_most_recent_prediction
|
87 |
bikelane_new['Status'].replace(['detection', 'no_detection'], ['Vehicle detected', 'No vehicle detected'], inplace=True)
|
88 |
bikelane_new = bikelane_new.rename(columns={'time': 'Time'})
|
89 |
bikelane_new = bikelane_new.set_index(['Time'])
|
90 |
-
st.dataframe(bikelane_new[['Status']].tail(5))
|
91 |
|
|
|
92 |
if st.button("Update application"):
|
|
|
93 |
st.cache_data.clear()
|
|
|
94 |
st.experimental_rerun()
|
95 |
-
|
96 |
with tab2:
|
|
|
97 |
def explore_magnetic_field(model, x, y, z):
|
98 |
input_list = [x, y, z]
|
99 |
-
res = model.predict(np.asarray(input_list).reshape(1
|
100 |
explorer_prediction = res[0]
|
101 |
if explorer_prediction == 'detection':
|
102 |
label = "Vehicle detected"
|
@@ -104,22 +127,26 @@ with tab2:
|
|
104 |
label = "No vehicle detected"
|
105 |
return label
|
106 |
|
|
|
107 |
st.subheader('Experiment with building model:')
|
108 |
x_input_building = st.slider("Choose your x-value", -232, 909, 0)
|
109 |
y_input_building = st.slider("Choose your y-value", -1112, 435, 0)
|
110 |
z_input_building = st.slider("Choose your z-value", -1648, 226, 0)
|
111 |
|
|
|
112 |
if st.button("Predict building input"):
|
113 |
building_input_prediction = explore_magnetic_field(building_hist_model, x_input_building, y_input_building, z_input_building)
|
114 |
st.write(building_input_prediction)
|
115 |
-
|
116 |
st.divider()
|
117 |
|
|
|
118 |
st.subheader('Experiment with bikelane model:')
|
119 |
x_input_bikelane = st.slider("Choose your x-value", -547, 288, 0)
|
120 |
y_input_bikelane = st.slider("Choose your y-value", -1007, 786, 0)
|
121 |
z_input_bikelane = st.slider("Choose your z-value", -1475, 16, 0)
|
122 |
|
|
|
123 |
if st.button("Predict bikelane input"):
|
124 |
bikelane_input_prediction = explore_magnetic_field(bikelane_hist_model, x_input_bikelane, y_input_bikelane, z_input_bikelane)
|
125 |
st.write(bikelane_input_prediction)
|
@@ -135,7 +162,74 @@ with tab3:
|
|
135 |
st.markdown('* **Model Performance:** The fifth tab explains how the underlying Machine Learning Model performs and how the predictor works.')
|
136 |
|
137 |
with tab4:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
@st.cache_data()
|
139 |
-
def
|
140 |
-
|
141 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
# Loading packages
|
2 |
import datetime
|
3 |
import joblib
|
|
|
15 |
|
16 |
# Configuring the web page and setting the page title and icon
|
17 |
st.set_page_config(
|
18 |
+
page_title='Parking Occupacy Detection',
|
19 |
+
page_icon='🅿️',
|
20 |
+
initial_sidebar_state='expanded')
|
|
|
21 |
|
22 |
# Ignoring filtering warnings
|
23 |
warnings.filterwarnings("ignore")
|
|
|
26 |
st.title('Parking Occupancy Detection')
|
27 |
|
28 |
# Creating tabs for the different features of the application
|
29 |
+
tab1,tab2,tab3,tab4, tab5 = st.tabs(['Parking lot status', 'Magnetic Field Explorer', 'About', 'Dataset and visualisations', 'Model performance'])
|
|
|
|
|
30 |
|
31 |
with tab1:
|
32 |
# Logging in to Hopsworks and loading the feature store
|
33 |
+
project = hopsworks.login(project = "miknie20", api_key_value=os.environ['HOPSWORKS_API_KEY'])
|
34 |
fs = project.get_feature_store()
|
35 |
|
36 |
col1, col2 = st.columns(2)
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
with col1:
|
39 |
st.subheader("Parking place near building:")
|
40 |
+
|
41 |
+
# Function to load the building model
|
42 |
+
|
43 |
+
@st.cache_data()
|
44 |
+
def get_building_model(project=project):
|
45 |
+
mr = project.get_model_registry()
|
46 |
+
building_model = mr.get_model("building_hist_model", version = 2)
|
47 |
+
building_model_dir = building_model.download()
|
48 |
+
return joblib.load(building_model_dir + "/building_hist_model.pkl")
|
49 |
+
|
50 |
+
# Retrieving model
|
51 |
building_hist_model = get_building_model()
|
52 |
+
|
53 |
+
# Loading the feature group with latest data for building
|
54 |
+
api_building_newest_fg = fs.get_feature_group(name = 'api_building_newest', version = 1)
|
55 |
+
|
56 |
+
# Function to loading the feature group with latest data for building as a dataset
|
57 |
+
@st.cache_data()
|
58 |
+
def retrieve_building(feature_group=api_building_newest_fg):
|
59 |
+
api_building_newest_fg = feature_group.select(["time", "x", "y", "z"])
|
60 |
+
df_building = api_building_newest_fg.read(read_options={"use_hive": True})
|
61 |
+
return df_building
|
62 |
+
|
63 |
+
# Retrieving building data
|
64 |
building_new = retrieve_building()
|
65 |
+
|
66 |
+
# Making the predictions and getting the latest data
|
67 |
building_most_recent_prediction = building_new[['x', 'y', 'z']]
|
68 |
building_most_recent_prediction = building_hist_model.predict(building_most_recent_prediction)
|
69 |
building_new['Status'] = building_most_recent_prediction
|
|
|
74 |
|
75 |
with col2:
|
76 |
st.subheader("Parking place near bikelane:")
|
77 |
+
|
78 |
+
# Function to load the bikelane model
|
79 |
+
@st.cache_data()
|
80 |
+
def get_bikelane_model(project=project):
|
81 |
+
mr = project.get_model_registry()
|
82 |
+
bikelane_model = mr.get_model("bikelane_hist_model", version = 1)
|
83 |
+
bikelane_model_dir = bikelane_model.download()
|
84 |
+
return joblib.load(bikelane_model_dir + "/bikelane_hist_model.pkl")
|
85 |
+
|
86 |
+
# Retrieving model
|
87 |
+
bikelane_hist_model = get_bikelane_model()
|
88 |
+
|
89 |
+
# Loading the feature group with latest data for bikelane
|
90 |
+
api_bikelane_newest_fg = fs.get_feature_group(name = 'api_bikelane_newest', version = 1)
|
91 |
+
|
92 |
+
# Function to loading the feature group with latest data for building as a dataset
|
93 |
+
@st.cache_data()
|
94 |
+
def retrieve_bikelane(feature_group=api_bikelane_newest_fg):
|
95 |
+
api_bikelane_newest_fg = feature_group.select(["time", "x", "y", "z"])
|
96 |
+
df_bikelane = api_bikelane_newest_fg.read(read_options={"use_hive": True})
|
97 |
+
return df_bikelane
|
98 |
+
|
99 |
+
# Retrieving building data
|
100 |
bikelane_new = retrieve_bikelane()
|
101 |
+
|
102 |
+
# Making the predictions and getting the latest data
|
103 |
bikelane_most_recent_prediction = bikelane_new[['x', 'y', 'z']]
|
104 |
bikelane_most_recent_prediction = bikelane_hist_model.predict(bikelane_most_recent_prediction)
|
105 |
bikelane_new['Status'] = bikelane_most_recent_prediction
|
106 |
bikelane_new['Status'].replace(['detection', 'no_detection'], ['Vehicle detected', 'No vehicle detected'], inplace=True)
|
107 |
bikelane_new = bikelane_new.rename(columns={'time': 'Time'})
|
108 |
bikelane_new = bikelane_new.set_index(['Time'])
|
109 |
+
st.dataframe(bikelane_new[['Status']].tail(5))
|
110 |
|
111 |
+
# Update button
|
112 |
if st.button("Update application"):
|
113 |
+
# Clear cached data
|
114 |
st.cache_data.clear()
|
115 |
+
# Immediately rerun the application
|
116 |
st.experimental_rerun()
|
117 |
+
|
118 |
with tab2:
|
119 |
+
# Defining a prediction function
|
120 |
def explore_magnetic_field(model, x, y, z):
|
121 |
input_list = [x, y, z]
|
122 |
+
res = model.predict(np.asarray(input_list).reshape(1,-1))
|
123 |
explorer_prediction = res[0]
|
124 |
if explorer_prediction == 'detection':
|
125 |
label = "Vehicle detected"
|
|
|
127 |
label = "No vehicle detected"
|
128 |
return label
|
129 |
|
130 |
+
# Creating sliders for building model
|
131 |
st.subheader('Experiment with building model:')
|
132 |
x_input_building = st.slider("Choose your x-value", -232, 909, 0)
|
133 |
y_input_building = st.slider("Choose your y-value", -1112, 435, 0)
|
134 |
z_input_building = st.slider("Choose your z-value", -1648, 226, 0)
|
135 |
|
136 |
+
# Making a prediction button for building model
|
137 |
if st.button("Predict building input"):
|
138 |
building_input_prediction = explore_magnetic_field(building_hist_model, x_input_building, y_input_building, z_input_building)
|
139 |
st.write(building_input_prediction)
|
140 |
+
|
141 |
st.divider()
|
142 |
|
143 |
+
# Creating sliders for bikelane model
|
144 |
st.subheader('Experiment with bikelane model:')
|
145 |
x_input_bikelane = st.slider("Choose your x-value", -547, 288, 0)
|
146 |
y_input_bikelane = st.slider("Choose your y-value", -1007, 786, 0)
|
147 |
z_input_bikelane = st.slider("Choose your z-value", -1475, 16, 0)
|
148 |
|
149 |
+
# Making a prediction button for bikelane model
|
150 |
if st.button("Predict bikelane input"):
|
151 |
bikelane_input_prediction = explore_magnetic_field(bikelane_hist_model, x_input_bikelane, y_input_bikelane, z_input_bikelane)
|
152 |
st.write(bikelane_input_prediction)
|
|
|
162 |
st.markdown('* **Model Performance:** The fifth tab explains how the underlying Machine Learning Model performs and how the predictor works.')
|
163 |
|
164 |
with tab4:
|
165 |
+
# Loading the feature group with historic data for building
|
166 |
+
api_building_detection_features_fg = fs.get_feature_group(name = 'api_building_detection_features', version = 1)
|
167 |
+
|
168 |
+
# Function to loading the feature group with latest data for building as a dataset
|
169 |
+
@st.cache_data()
|
170 |
+
def retrieve_building_historic(feature_group=api_building_detection_features_fg):
|
171 |
+
api_building_detection_features_fg = feature_group.select_all()
|
172 |
+
df_building_historic = api_building_detection_features_fg.read(read_options={"use_hive": True})
|
173 |
+
return df_building_historic
|
174 |
+
|
175 |
+
# Retrieving building data
|
176 |
+
building_historic = retrieve_building_historic()
|
177 |
+
|
178 |
+
# Display historic building dataset overview
|
179 |
+
st.subheader("Overview of the historic dataframe for the parking place near the building")
|
180 |
+
st.dataframe(building_historic.head())
|
181 |
+
|
182 |
+
st.markdown('Here we can see an overview of the columns in the historic dataframe for the building parking place. There is some missing data in the radar columns, but that does not affect our detection model, as it is built using the magnetic field data.')
|
183 |
+
st.markdown('We have looked a bit into when there is most activity in the parking place. Looking at the two visualisations below, we can see that the parking place near the building has most changes between 03:00-06:00 and 10:00-15:00. We can also see that there is most activity on weekdays, which is as expected, as this parking place is outside an office.')
|
184 |
+
st.image('building_dist_hour.png')
|
185 |
+
st.image('building_dist_week.png')
|
186 |
+
|
187 |
+
st.markdown('The labels used to train the detection model are made on the basis of UML clustering. The clusters for the building parking place can be seen below.')
|
188 |
+
st.image('building_cluster.png')
|
189 |
+
|
190 |
+
st.divider()
|
191 |
+
|
192 |
+
# Loading the feature group with historic data for bikelane
|
193 |
+
api_bikelane_detection_features_fg = fs.get_feature_group(name = 'api_bikelane_detection_features', version = 1)
|
194 |
+
|
195 |
+
# Function to loading the feature group with latest data for building as a dataset
|
196 |
@st.cache_data()
|
197 |
+
def retrieve_bikelane_historic(feature_group=api_bikelane_detection_features_fg):
|
198 |
+
api_bikelane_detection_features_fg = feature_group.select_all()
|
199 |
+
df_bikelane_historic = api_bikelane_detection_features_fg.read(read_options={"use_hive": True})
|
200 |
+
return df_bikelane_historic
|
201 |
+
|
202 |
+
# Retrieving building data
|
203 |
+
bikelane_historic = retrieve_bikelane_historic()
|
204 |
+
|
205 |
+
# Display historic building dataset overview
|
206 |
+
st.subheader("Overview of the historic dataset for the parking place near the bikelane")
|
207 |
+
st.dataframe(bikelane_historic.head())
|
208 |
+
|
209 |
+
st.markdown('Looking at the historic dataframe for the bikelane parking place, we can see that it is quite similar to the one for the building parking place.')
|
210 |
+
st.markdown('There is a bit of difference in the hourly distribution of activity, as the parking place near the bikelane has most changes between 03:00-06:00 and 12:00-17:00. However, the weekly distribution shows the same.')
|
211 |
+
st.image('bikelane_dist_hour.png')
|
212 |
+
st.image('bikelane_dist_week.png')
|
213 |
+
|
214 |
+
st.markdown('Here we can see the clusters used to label the bikelane parking place.')
|
215 |
+
st.image('bikelane_cluster.png')
|
216 |
+
|
217 |
+
with tab5:
|
218 |
+
|
219 |
+
# Model performance of building model
|
220 |
+
st.subheader('Model to predict parking place near building:')
|
221 |
+
st.markdown('The predictions for the parking place near the building are made on the basis of a KNearestNeighbours model')
|
222 |
+
st.write(building_hist_model)
|
223 |
+
st.markdown('The accuracy if the bikelane model is 100%')
|
224 |
+
st.write('**Confusion matrix:**')
|
225 |
+
st.image('building_hist_confusion_matrix.png', caption='Confusion matrix for building model')
|
226 |
+
|
227 |
+
st.divider()
|
228 |
+
|
229 |
+
# Model performance of bikelane model
|
230 |
+
st.subheader('Model to predict parking place near bikelane:')
|
231 |
+
st.markdown('Just like with the other model, the predictions for the parking place near the bikelane are made on the basis of a KNearestNeighbours model')
|
232 |
+
st.write(bikelane_hist_model)
|
233 |
+
st.markdown('The accuracy if the building model is 99%')
|
234 |
+
st.write('**Confusion matrix:**')
|
235 |
+
st.image('bikelane_hist_confusion_matrix.png', caption='Confusion matrix for bikelane model')
|