ericjedha commited on
Commit
d454b2b
·
verified ·
1 Parent(s): 7d8cae7

Upload 5 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ get_around_delay_analysis.xlsx filter=lfs diff=lfs merge=lfs -text
car.csv ADDED
The diff for this file is too large to render. See raw diff
 
get_around_delay_analysis.xlsx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:122bf01212096777918a728401dc65a8a63489792be6bb4a3e507d4ea6f07a67
3
+ size 751556
pages/1_ETL_GetAround.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import plotly.express as px
4
+ WIDTH = 800
5
+ HEIGHT = 700
6
+
7
+ st.write("Bienvenue dans le Dashboard de GetAround")
8
+
9
+ df = pd.read_excel("get_around_delay_analysis.xlsx")
10
+
11
+ # Calculer le nombre de valeurs manquantes par colonne
12
+ missing_values_count = df.isnull().sum()
13
+
14
+ # Calculer le pourcentage de valeurs manquantes par colonne
15
+ missing_values_percent = (missing_values_count / len(df)) * 100
16
+
17
+ # Créer un nouveau DataFrame pour afficher les résultats
18
+ missing_data = pd.DataFrame({
19
+ 'missing_values_count': missing_values_count,
20
+ 'missing_values_percent': missing_values_percent
21
+ })
22
+
23
+ missing_df = missing_data[missing_data['missing_values_count'] > 0]
24
+ missing_df_percent = missing_df['missing_values_percent'].reset_index()
25
+
26
+ missing = px.bar(missing_df_percent, x = "index", y = "missing_values_percent",
27
+ hover_data=['index'], title="Données manquantes en pourcentage", color='index', text_auto='.2s')
28
+
29
+ st.plotly_chart(missing)
30
+
31
+ state_car = df['state'].value_counts()
32
+ state_car = pd.DataFrame(state_car).reset_index()
33
+ state_car.columns = ['state', 'count']
34
+ state = px.pie(state_car, values='count', names='state', title='State of the Car', color = 'state', width=WIDTH)
35
+
36
+ st.plotly_chart(state)
37
+
38
+
39
+ import plotly.graph_objects as go
40
+
41
+
42
+ fig = go.Figure()
43
+
44
+
45
+ # Mask sur les types de checkin vs ended canceled
46
+ checkin_df = df.groupby('checkin_type')['state'].value_counts()
47
+ checkin_df = pd.DataFrame(checkin_df).reset_index()
48
+ checkin_df_connect = checkin_df[checkin_df['checkin_type'] == 'connect']['count'].sum()
49
+ checkin_df_mobile = checkin_df[checkin_df['checkin_type'] == 'mobile']['count'].sum()
50
+ total_checkin = checkin_df['count'].sum()
51
+ checkin_df = checkin_df.assign(percent=lambda x: (x['count'] / total_checkin) * 100)
52
+
53
+ # Créer la figure Plotly
54
+ fig = go.Figure()
55
+
56
+ # Ajout des barres pour chaque état
57
+ for state in checkin_df['state'].unique():
58
+ df_state = checkin_df[checkin_df['state'] == state]
59
+ fig.add_trace(go.Bar(
60
+ x=df_state['checkin_type'],
61
+ y=df_state['percent'],
62
+ name=state,
63
+ text=df_state['percent'].apply(lambda x: f'{round(x, 2)}% 🚗'),
64
+ textfont=dict(size=12, weight='bold'),
65
+ textposition="outside",
66
+ ))
67
+
68
+ # Mise en page
69
+ fig.update_layout(
70
+ title='Type of Checkin vs State',
71
+ xaxis_title='Checkin Type',
72
+ yaxis_title='Percent',
73
+ barmode='group',
74
+ width=800, # Assurez-vous que WIDTH est défini
75
+ height=600 # Assurez-vous que HEIGHT est défini
76
+ )
77
+
78
+ # Affichage du graphique dans Streamlit
79
+ st.plotly_chart(fig)
80
+
81
+ # Mask sur les Canceled
82
+
83
+ mask_canceled = df['state'] == 'canceled'
84
+ car_canceled_detail = df[mask_canceled]
85
+
86
+ car_canceled_detail = car_canceled_detail['checkin_type'].value_counts()
87
+ car_canceled_detail = pd.DataFrame(car_canceled_detail).reset_index()
88
+ car_canceled_detail.columns = ['checkin_type', 'count']
89
+
90
+ cancel_device = px.pie(car_canceled_detail, values='count', names='checkin_type', title='Groupe Cancel : Checkin Type', color = 'checkin_type', width=WIDTH)
91
+ st.plotly_chart(cancel_device)
92
+
93
+ #Visualisation des Cancels et les outliers
94
+
95
+ delay_mask = df['delay_at_checkout_in_minutes'] > 0
96
+ delay_dataf = df[delay_mask]
97
+ fig = px.scatter(delay_dataf, x = "delay_at_checkout_in_minutes")
98
+ st.plotly_chart(fig)
99
+
100
+ #Transformation des status Early en On Time
101
+
102
+ def status_time(x):
103
+ if x <0:
104
+ return 'ONTIME'
105
+ elif x > 0:
106
+ return "DELAY"
107
+ else:
108
+ return "NOFINFO"
109
+
110
+
111
+ df['time'] = df['delay_at_checkout_in_minutes'].apply(status_time)
112
+ df['time'] = df.apply(lambda row: row['state'].upper() if row['time'] == 'NOFINFO' else row['time'], axis=1)
113
+ df_state = df['time'].value_counts()
114
+ df_state_detail = pd.DataFrame(df_state).reset_index()
115
+ status = px.pie(df_state_detail, values='count', names = 'time', width=WIDTH, title="State of the Car")
116
+ st.plotly_chart(status)
pages/2_Simulateur_Seuil.py ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #https://www.youtube.com/watch?v=D0D4Pa22iG0&t=41s
3
+
4
+ import streamlit as st
5
+ import pandas as pd
6
+ import plotly.express as px
7
+
8
+
9
+ st.title("Simulateur de Seuil")
10
+
11
+ df = pd.read_excel("get_around_delay_analysis.xlsx")
12
+
13
+ #st.write(df)
14
+
15
+ # Mask sur les Canceled
16
+ mask_canceled = df['state'] == 'canceled'
17
+
18
+ # Mask Delay Checkout supérieur à zéro (donc retard)
19
+ mask_delay = df['delay_at_checkout_in_minutes'] > 0
20
+ df_delay = df[mask_delay]
21
+
22
+ #Mask sur les Canceled Vs Delay
23
+ df_delay_canceled = df_delay['state'] == 'canceled'
24
+ df_canceled_data = df_delay[df_delay_canceled]
25
+
26
+ # Groupe "canceled" et Filtre NA sur time_delta
27
+ canceled_vs_delta = df[mask_canceled]
28
+ mask_delta = canceled_vs_delta['time_delta_with_previous_rental_in_minutes'].isna()==False
29
+ canceled_vs_delta_1 = canceled_vs_delta[mask_delta]
30
+
31
+ # Filtre time_delta > 0
32
+ delta_nb_mask = df['time_delta_with_previous_rental_in_minutes'] > 0
33
+
34
+ # DataFrame time_delta > 0
35
+ delta_nb_dataf = df[delta_nb_mask]
36
+
37
+ # Mask time_delta > 0 et state = canceled
38
+ delta_mask_canceled = delta_nb_dataf['state']=='canceled'
39
+
40
+ #Nombre de cancel avec time_delta > 0
41
+ delta_mask_nb = delta_nb_dataf[delta_mask_canceled]
42
+ #st.write(f'Nombre de Canceled à la 2e location : {delta_mask_nb.shape[0]}')
43
+ delta_mask_ended= delta_nb_dataf['state']=='ended'
44
+
45
+ #nombre de Ended avec time_delta > 0
46
+ delta_mask_ended_nb = delta_nb_dataf[delta_mask_ended]
47
+ #st.write(f'Nombre de Ended à la 2e location : {delta_mask_ended_nb.shape[0]}')
48
+ #st.write(f"Pourcentage de perte ou de cancel avec un Time Delta > 0 : {round(delta_mask_nb.shape[0] / (delta_mask_nb.shape[0] + delta_mask_ended_nb.shape[0]) * 100, 2)}%")
49
+
50
+ # canceled_vs_delta_1 = Filtre sur Cancel
51
+ # Calcul nombre de cancel (nombre de lignes) (time_delta en fonction des minutes de temps_cancel donné)
52
+
53
+ delta_nb_dataf = df[delta_nb_mask]
54
+ delta_nb = delta_nb_dataf.shape[0]
55
+
56
+ #temps_cancel = [1, 5, 10, 15, 20, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 400, 500, 600, 700, 750]
57
+
58
+ #Annulation au total
59
+ def cancel(tps_cancel):
60
+ cancel_10min = (canceled_vs_delta_1[(canceled_vs_delta_1["time_delta_with_previous_rental_in_minutes"] <= tps_cancel)])
61
+ pourcent_annul = round((cancel_10min.shape[0]/delta_nb)*100,2)
62
+ #st.write(f"Pourcentage d'annulation après {tps_cancel}min d'attente pour 2e location : {round((cancel_10min.shape[0]/delta_nb)*100,2)}% 😤")
63
+ return pourcent_annul
64
+
65
+ # Pourcentage de d'annulation en Mobile selon le temps d'attente
66
+
67
+ delta_mask_mobile = delta_mask_nb['checkin_type']== 'mobile'
68
+ delta_mobile_nb = delta_mask_nb[delta_mask_mobile]
69
+
70
+ #Annulation par device : ici mobile
71
+ def cancel_mobile(tps_cancel):
72
+ cancel_10min = (delta_mobile_nb[(delta_mobile_nb["time_delta_with_previous_rental_in_minutes"] <= tps_cancel)])
73
+ pourcent_annul_mobile = round((cancel_10min.shape[0]/delta_nb)*100,2)
74
+ #print(f"Pourcentage d'annulation mobile - 📵 - après {i}min d'attente pour 2e location : {round((cancel_10min.shape[0]/delta_nb)*100,2)} %")
75
+ return pourcent_annul_mobile
76
+
77
+ # Pourcentage de d'annulation en Desktop (connect) selon le temps d'attente
78
+ delta_mask_connect = delta_mask_nb['checkin_type']== 'connect'
79
+ delta_connect_nb = delta_mask_nb[delta_mask_connect]
80
+
81
+ #Annulation par device : ici Desktop
82
+ def cancel_desktop(tps_cancel):
83
+ cancel_10min = (delta_connect_nb [(delta_connect_nb["time_delta_with_previous_rental_in_minutes"] <= tps_cancel)])
84
+ pourcent_annul_desktop = round((cancel_10min.shape[0]/delta_nb)*100,2)
85
+ #print(f"Pourcentage d'annulation - Desktop 🖥 - après {i}min d'attente pour 2e location : {round((cancel_10min.shape[0]/delta_nb)*100,2)}%")
86
+ return pourcent_annul_desktop
87
+
88
+ mask_delta = df['time_delta_with_previous_rental_in_minutes'] >= 0
89
+ delta = df[mask_delta]
90
+ delta_canceled = delta[delta['state'] == 'canceled']
91
+ # Manque à gagner
92
+ def manque_a_gagner(tps_cancel):
93
+ cancel_now = (delta_canceled [(delta_canceled["time_delta_with_previous_rental_in_minutes"] <= tps_cancel)])
94
+ client_perdus = cancel_now.shape[0]
95
+ pourcent_clients_total = round((cancel_now.shape[0]/df.shape[0])*100, 2)
96
+ client_sauves = round(((delta_canceled.shape[0]-cancel_now.shape[0]) / delta_canceled.shape[0])*100, 2)
97
+ return client_perdus, pourcent_clients_total, client_sauves
98
+
99
+
100
+
101
+ st.write("### Delta temps entre 2 locations 🚗 ⏱️ 🚗 ")
102
+ time_delta = st.slider("en minutes", min_value=0, max_value=750, value=5)
103
+ col1, col2, col3 = st.columns(3)
104
+
105
+
106
+
107
+ #HTML et CSS pour formater les titres
108
+
109
+ # Utilisation de HTML et CSS pour renforcer la typographie
110
+ col1.markdown(
111
+ """
112
+ <style>
113
+ .big-font {
114
+ font-size: 20px !important;
115
+ font-weight: bold;
116
+ }
117
+ </style>
118
+ <div class="big-font">🚘 Total annulations</div>
119
+ """,
120
+ unsafe_allow_html=True
121
+ )
122
+ col1.metric(label="", value=f"{cancel(time_delta):,.1f}%")
123
+
124
+ col2.markdown(
125
+ """
126
+ <style>
127
+ .big-font {
128
+ font-size: 20px !important;
129
+ font-weight: bold;
130
+ }
131
+ </style>
132
+ <div class="big-font">Mobile annulations 📱</div>
133
+ """,
134
+ unsafe_allow_html=True
135
+ )
136
+ col2.metric(label="", value=f"{cancel_mobile(time_delta):,.1f}%")
137
+
138
+ col3.markdown(
139
+ """
140
+ <style>
141
+ .big-font {
142
+ font-size: 20px !important;
143
+ font-weight: bold;
144
+ }
145
+ </style>
146
+ <div class="big-font">Desktop annulations 💻</div>
147
+ """,
148
+ unsafe_allow_html=True
149
+ )
150
+ col3.metric(label="", value=f"{cancel_desktop(time_delta):,.1f}%")
151
+
152
+ col1, col2, col3 = st.columns(3)
153
+
154
+ client_perdus, pourcent_clients_total, client_sauves = manque_a_gagner(time_delta)
155
+
156
+
157
+ #HTML et CSS pour formater les titres
158
+
159
+ # Utilisation de HTML et CSS pour renforcer la typographie
160
+ col1.markdown(
161
+ """
162
+ <style>
163
+ .big-font {
164
+ font-size: 20px !important;
165
+ font-weight: bold;
166
+ }
167
+ </style>
168
+ <div class="big-font">🤦‍♀️ Clients perdus en nb</div>
169
+ """,
170
+ unsafe_allow_html=True
171
+ )
172
+ col1.metric(label="", value=f"{(client_perdus):,.0f}")
173
+
174
+ col2.markdown(
175
+ """
176
+ <style>
177
+ .big-font {
178
+ font-size: 20px !important;
179
+ font-weight: bold;
180
+ }
181
+ </style>
182
+ <div class="big-font">🤷‍♂️ Clients perdus en % </div>
183
+ """,
184
+ unsafe_allow_html=True
185
+ )
186
+ col2.metric(label="", value=f"{(pourcent_clients_total):,.1f}%")
187
+
188
+ col3.markdown(
189
+ """
190
+ <style>
191
+ .big-font {
192
+ font-size: 20px !important;
193
+ font-weight: bold;
194
+ }
195
+ </style>
196
+ <div class="big-font">🙋‍♀️ Clients sauvés en % </div>
197
+ """,
198
+ unsafe_allow_html=True
199
+ )
200
+ col3.metric(label="", value=f"{(client_sauves):,.1f}%")
pages/3_Prediction_Prix.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import streamlit as st
3
+ import requests
4
+
5
+ # URL de l'API
6
+ api_url = "https://ericjedha-getaroundapi.hf.space/predict/"
7
+
8
+ # Titre de l'application
9
+ st.title("Application de requête à l'API GetAround")
10
+
11
+ # Formulaire pour saisir les informations
12
+ with st.form("api_form"):
13
+ model_key = st.text_input("Model Key")
14
+ mileage = st.number_input("Mileage", min_value=0)
15
+ engine_power = st.number_input("Engine Power", min_value=0)
16
+ fuel = st.text_input("Fuel")
17
+ paint_color = st.text_input("Paint Color")
18
+ car_type = st.text_input("Car Type")
19
+ private_parking_available = st.number_input("Private Parking Available", min_value=0, max_value=1)
20
+ has_gps = st.number_input("Has GPS", min_value=0, max_value=1)
21
+ has_air_conditioning = st.number_input("Has Air Conditioning", min_value=0, max_value=1)
22
+ automatic_car = st.number_input("Automatic Car", min_value=0, max_value=1)
23
+ has_getaround_connect = st.number_input("Has GetAround Connect", min_value=0, max_value=1)
24
+ has_speed_regulator = st.number_input("Has Speed Regulator", min_value=0, max_value=1)
25
+ winter_tires = st.number_input("Winter Tires", min_value=0, max_value=1)
26
+
27
+ # Bouton pour envoyer la requête
28
+ submitted = st.form_submit_button("Envoyer la requête")
29
+
30
+ # Si le formulaire est soumis
31
+ if submitted:
32
+ # Préparer les données à envoyer
33
+ data = {
34
+ "model_key": model_key,
35
+ "mileage": mileage,
36
+ "engine_power": engine_power,
37
+ "fuel": fuel,
38
+ "paint_color": paint_color,
39
+ "car_type": car_type,
40
+ "private_parking_available": private_parking_available,
41
+ "has_gps": has_gps,
42
+ "has_air_conditioning": has_air_conditioning,
43
+ "automatic_car": automatic_car,
44
+ "has_getaround_connect": has_getaround_connect,
45
+ "has_speed_regulator": has_speed_regulator,
46
+ "winter_tires": winter_tires
47
+ }
48
+
49
+ # Envoyer la requête POST
50
+ response = requests.post(api_url, json=data)
51
+
52
+ # Afficher la réponse de l'API
53
+ st.write("Réponse de l'API:")
54
+ st.json(response.json())