pram2601 commited on
Commit
c8ba0cf
1 Parent(s): 5aa4d0e

Upload 10 files

Browse files
Files changed (10) hide show
  1. app.py +10 -0
  2. eda.py +212 -0
  3. images.jpg +0 -0
  4. list_cat_cols.txt +1 -0
  5. list_num_cols.txt +1 -0
  6. model_encoder.pkl +3 -0
  7. model_rfc.pkl +3 -0
  8. model_scaler.pkl +3 -0
  9. prediction.py +91 -0
  10. requirements.txt +7 -0
app.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import eda
3
+ import prediction
4
+
5
+ navigation = st.sidebar.selectbox('Pilih Halaman : ', ('EDA','Predict'))
6
+
7
+ if navigation == 'EDA':
8
+ eda.run()
9
+ else:
10
+ prediction.run()
eda.py ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import seaborn as sns
4
+ import matplotlib.pyplot as plt
5
+ import plotly.express as px
6
+ from PIL import Image
7
+
8
+ st.set_page_config(
9
+ page_icon='Hotel Reservation and Prediction',
10
+ layout='wide',
11
+ initial_sidebar_state='expanded')
12
+
13
+ def run():
14
+
15
+ # membuat judul
16
+ st.title('Hotel Reservation and Prediction')
17
+
18
+ # Membuat Sub header
19
+ st.subheader ('EDA Hotel Reservation and Prediction')
20
+
21
+ # Menambahkan gambar
22
+ image = Image.open('images.jpg')
23
+ st.image(image)
24
+
25
+ # Menambahkan deskripsi
26
+ st.write('Ditengah ramainya pertumbuhan era digitalisasi, maka industri perhotelan pun tidak ikut ketinggalan dalam era ini, dimana reservasi sekarang mulai di kolaborasikan dengan berbagai macam aplikasi, namun ini menyebabkan masalah baru juga, dimana pelangan dapat dengan mudah membatalkan reservasi yang dapat berdampak pada pendapatan hotel yang berkurang dari efek tersebut.')
27
+
28
+ # mbuat garis lurus
29
+ st.write('---')
30
+
31
+ # Magic Syntax
32
+ '''
33
+ Dataset ini berisisikan data reservasi dari suatu hotel baik online maupun offline. Selain itu ada dataset juga berisi booking status dari reservasi tersebut, ada yang di cancel dan ada yang tidak. Disini saya akan mencoba untuk menganalisis data reservasi yang berstatus cancel berdasarkan berbagai kolom-kolom lainnya.
34
+ '''
35
+ # menambhakan dataframe
36
+ data=pd.read_csv('https://raw.githubusercontent.com/pram2601/Hacktiv8/main/Hotel%20Reservations.csv')
37
+ st.dataframe(data)
38
+
39
+ # memuat data pada kolom booking_status yang berstatus canceled
40
+ data_canceled= data[data['booking_status']=='Canceled']
41
+
42
+ # menampilkan pie chart untuk kolom kolom pada dataset
43
+ st.write('### Data Booking Status Cancel Berdasarkan Kondisi')
44
+ fig= plt.figure(figsize=(20, 5))
45
+
46
+ plt.subplot(1, 3, 1)
47
+ plt.pie(data['booking_status'].value_counts(), labels=['Not Canceled', 'Canceled'], autopct='%1.1f%%')
48
+ plt.title('Booking Status')
49
+
50
+ plt.subplot(1, 3, 2)
51
+ plt.pie(data_canceled['arrival_year'].value_counts(), labels=['2018', '2017'],autopct='%1.1f%%')
52
+ plt.title('Booking Status Canceled By Arival Year')
53
+
54
+ plt.subplot(1, 3, 3)
55
+ plt.pie(data_canceled['required_car_parking_space'].value_counts(),labels=['No', 'Yes'],autopct='%1.1f%%')
56
+ plt.title('Booking Status Canceled By Required Car Carking Spaces')
57
+
58
+ st.pyplot(fig)
59
+
60
+ # menambahkan deskripsi
61
+ st.write('- Dari chart diatas data imbalance dimana banyak yang tidak cancel, dan yang cancel lebih sedikit. Dalam hal bisnis ini cukup baik untuk pihak hotelnya, karena hanya sedikit yang sudah reservasi dan membatalkannya, hanya 11.885 dari total keseluruhan data yaitu 36.275')
62
+ st.write('- Kebanyakan pembatalan reservasi terjadi pada tahun 2018')
63
+ st.write('- Hampir padad semua pembatalan reservasi, kebanyakan pelanggan tidak membutuhkan parkiran mobil')
64
+
65
+ # memnampilkan booking status canceled berdasarkan kolom lain ke dalam chart
66
+
67
+ fig = plt.figure(figsize=(30, 5))
68
+
69
+ plt.subplot(1, 3, 1)
70
+ sns.countplot(x=data_canceled['room_type_reserved'])
71
+ plt.title('Booking Status Canceled By Room Type Reserved')
72
+
73
+ plt.subplot(1, 3, 2)
74
+ sns.countplot(x=data_canceled['no_of_adults'])
75
+ plt.title('Booking Status Canceled By Number Of Adults')
76
+
77
+ plt.subplot(1, 3, 3)
78
+ sns.countplot(x=data_canceled['no_of_children'])
79
+ plt.title('Booking Status Canceled By Number of Children')
80
+
81
+ st.pyplot(fig)
82
+
83
+ # menambahkan deskripsi
84
+ st.write('- Pembatalan reservasi kebanyakan terjadi pada room type 1')
85
+ st.write('- Pembatalan paling banyak ada pada pemesanan yang satu kamar akan ditempati oleh 2 orang dewasa saja')
86
+ st.write('- Kebanyakan pelanggan yang membatalkan reservasi tidak membawa anak, makanya grafik pada no_of_childrennya untuk 0 sangat tinggi di bandingkan yang lainnya')
87
+
88
+ # memnampilkan booking status canceled berdasarkan kolom lain ke dalam chart
89
+ fig = plt.figure(figsize=(20, 5))
90
+
91
+ plt.subplot(1, 3, 1)
92
+ sns.countplot(x=data_canceled['no_of_weekend_nights'])
93
+ plt.title('Booking Status Canceled By No of Weekend Nights')
94
+
95
+ plt.subplot(1, 3, 2)
96
+ sns.countplot(x=data_canceled['no_of_week_nights'])
97
+ plt.title('Booking Status Canceled By Number of Week Nights')
98
+
99
+ plt.subplot(1, 3, 3)
100
+ sns.countplot(x=data_canceled['no_of_special_requests'])
101
+ plt.title('Booking Status Canceled By Repeated Guest')
102
+
103
+ st.pyplot(fig)
104
+
105
+ # menambahkan deskripsi
106
+ st.write('- Dari chart number of weekend night dapat terlihat bahwa reservasi yang cancel kebanyakan tidak mengambil weekend night (sabtu atau minggu) pada saat reservasi. dapat terlihat dari pada chart weekend night 0 nya yang tinggi')
107
+ st.write('- Dari chart Number of Week Nights, orang orang yang melakukan cancel kebanyakan memesaan 1-3 hari pada hari biasa, antara senin sampai jumat')
108
+ st.write('- Kebanyakan reservasi yang dicancel mayoritas tidak mennyebutkan spesial request, jadi langsung pesan ssaja tanpa ada pesan khusus')
109
+
110
+ # membuat fungsi untuk kolom avg_price_per_room dan kolom lead_time
111
+ def avg_price_per_room_group(x):
112
+ if x <= 50.0 :
113
+ x= 'Price below 50'
114
+ elif x >50.0 and x <=150.0:
115
+ x= 'Price from 50 to 150'
116
+ elif x >150.0 and x <=300.0:
117
+ x= 'Price from 150 to 300'
118
+ elif x >300.0 and x <=450.0:
119
+ x= 'Price from 300 to 450'
120
+ else:
121
+ x= 'Price 450+'
122
+ return x
123
+
124
+ def lead_time_group(x):
125
+ if x <= 30.0 :
126
+ x= 'Dibawah 1 Bulan'
127
+ elif x >30.0 and x <= 60:
128
+ x= 'Dibawah 2 Bulan'
129
+ elif x > 60.0 and x <=90.0:
130
+ x= 'Dibawah 3 Bulan'
131
+ else:
132
+ x= 'Diatas 3 Bulan'
133
+ return x
134
+
135
+ # menambhakan kolom baru hasil fungsi
136
+ data_canceled['price_per_room_group']=data_canceled['avg_price_per_room'].apply(avg_price_per_room_group)
137
+ data_canceled['lead_time_group']=data_canceled['lead_time'].apply(lead_time_group)
138
+
139
+ # memnampilkan booking status canceled berdasarkan kolom lain ke dalam chart
140
+ fig = plt.figure(figsize=(20, 5))
141
+
142
+ plt.subplot(1, 3, 1)
143
+ sns.countplot(x=data_canceled['price_per_room_group'])
144
+ plt.title('Booking Status Canceled By Price Per Room Group')
145
+ plt.xticks(rotation=90)
146
+
147
+ plt.subplot(1, 3, 2)
148
+ sns.countplot(x=data_canceled['lead_time_group'])
149
+ plt.title('Booking Status Canceled By Lead Time Group')
150
+ plt.xticks(rotation=90)
151
+
152
+ plt.subplot(1, 3, 3)
153
+ sns.countplot(x=data_canceled['market_segment_type'])
154
+ plt.title('Booking Status Canceled By Market Segment Type')
155
+
156
+ st.pyplot(fig)
157
+
158
+ # menambahkan deskripsi
159
+ st.write('- Reservasi yang di cancel mayoritas berada pada range harga 50-150, pada range harga tersebut banyak yang membatalkan reservasinya')
160
+ st.write('- Selisih waktu booking dan kedatangan pelanggan yang diatas 3 bulan sangat rawan sekali terjadi pembatalan, terlihat pada grafik Booking Status Canceled By Lead Time Group diatas')
161
+ st.write('- Kebanyakan pembatalan berada pada market segment online, dimana memang ini adalah masalah baru dalam dunia bisnis hotel sejak merambah ke pasar online, dimana fee pembatalan yang rendah, dengan mudahnya mengcancele dari aplikasi')
162
+
163
+
164
+ # memnampilkan booking status canceled berdasarkan kolom lain ke dalam chart
165
+
166
+ fig = plt.figure(figsize=(30, 5))
167
+
168
+ plt.subplot(1, 3, 1)
169
+ sns.countplot(x=data_canceled['type_of_meal_plan'])
170
+ plt.title('Booking Status Canceled By type of Meal Plan')
171
+
172
+ plt.subplot(1, 3, 2)
173
+ sns.countplot(x=data_canceled['arrival_month'])
174
+ plt.title('Booking Status Canceled By Arrival Month')
175
+
176
+ plt.subplot(1, 3, 3)
177
+ sns.countplot(x=data_canceled['arrival_date'])
178
+ plt.title('Booking Status Canceled By Arrival Date')
179
+
180
+ st.pyplot(fig)
181
+
182
+ # menambahkan deskripsi
183
+ st.write('- Dalam kolom meal plan, yang mengcancel reservasi kebanyakan memilih meal plan 1')
184
+ st.write('- Reservasi yang dibatalkan kebanyakan pelanggan yang akan menginap pada bulan 10 atau oktober, diamana pada akhir tahun lebih sedikit pelanggan yang membatalkan reservasi')
185
+ st.write('- Untuk reservasi yang cancel berdasarkan tanggal kedatangan ini hasilnya rata, tidak ada tanggal yang benar benar mencolok')
186
+
187
+ # memnampilkan booking status canceled berdasarkan kolom lain ke dalam chart
188
+
189
+ fig = plt.figure(figsize=(30, 5))
190
+
191
+ plt.subplot(1, 3, 1)
192
+ plt.pie(data['repeated_guest'].value_counts(), labels=['No', 'Yes'], autopct='%1.1f%%')
193
+ plt.title('Booking Status Canceled By Repeated Guest')
194
+
195
+ plt.subplot(1, 3, 2)
196
+ sns.countplot(x=data_canceled['no_of_previous_cancellations'])
197
+ plt.title('Booking Status Canceled By No of Previous Cancellation')
198
+
199
+ plt.subplot(1, 3, 3)
200
+ sns.countplot(x=data_canceled['no_of_previous_bookings_not_canceled'])
201
+ plt.title('Booking Status Canceled By No of Previous Bookings Not Canceled')
202
+
203
+ st.pyplot(fig)
204
+
205
+ # menambahkan deskripsi
206
+ st.write('- Ada sedikit pelanggan yang pernah menginap lalu reservasi lagi dan tiba-tiba membatalkan reservasi tersebut')
207
+
208
+ # mmebuat garis lurus
209
+ st.write('---')
210
+ st.write('Dari hasil EDA didapati bahwa pelanggan yang mungkin akan membatalkan reservasi adalah pelanngan yang memesan pada tahun 2018 untuk 2 orang dewasa tanpa membawa anak, dan memiliki waktu pemesanan dengan kedatangan memiliki selisih waktu diatas 3 bulan bertipe segment online dan dengan room type 1 dengan rentang harga per room 50 - 150')
211
+
212
+ if __name__ == '__main__': run()
images.jpg ADDED
list_cat_cols.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ ["market_segment_type"]
list_num_cols.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ ["lead_time", "arrival_year", "repeated_guest", "avg_price_per_room", "no_of_special_requests"]
model_encoder.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:dc082ebb3873ddd156c01d14325753cf6edd4522ef23589e49d869a8bf1b1768
3
+ size 604
model_rfc.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:df7e1c1f3623452fd115b8ef93dbc7f534ca62e38b8a681c7326a4d335b36e49
3
+ size 39833089
model_scaler.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7be3fad98c5c0aa9666be60208cef8781c991ae191c7e789528bfb712fb043d4
3
+ size 650
prediction.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ import pickle
5
+ import json
6
+
7
+ # load semua file yang telah disimpan
8
+
9
+ with open('model_rfc.pkl', 'rb') as file_1:
10
+ rfc = pickle.load(file_1)
11
+
12
+ with open('model_scaler.pkl', 'rb') as file_2:
13
+ scaler = pickle.load(file_2)
14
+
15
+ with open('model_encoder.pkl', 'rb') as file_3:
16
+ encoder = pickle.load(file_3)
17
+
18
+ with open('list_num_cols.txt', 'r') as file_4:
19
+ list_num_cols = json.load(file_4)
20
+
21
+ with open('list_cat_cols.txt', 'r') as file_5:
22
+ list_cat_cols = json.load(file_5)
23
+
24
+ def run():
25
+ # membuat judul
26
+ st.title('Booking Status Prediction')
27
+
28
+ with st.form(key='Booking Status'):
29
+ booking_id = st.text_input('Booking ID', value='')
30
+ no_of_adults = st.number_input('Number of Adults', min_value=0, max_value=4, value=0, step=1)
31
+ no_of_children = st.number_input('Number of Children', min_value=0, max_value=10, value=0, step=1)
32
+ no_of_weekend_nights = st.number_input('Number of Weekend Nights',min_value=0, max_value=7, value=0, step=1 )
33
+ no_of_week_nights = st.number_input('Numer of Week Nights', min_value=0, max_value=17, value=0, step=1)
34
+ type_of_meal_plan = st.selectbox('Type of Meal Plan',('Meal Plan 1','Not Selected','Meal Plan 2','Meal Plan 3'),index=1)
35
+ required_car_parking_space = st.number_input('Required Car Parking Space', min_value=0, max_value=1, value=0, step=1)
36
+ room_type_reserved = st.selectbox('Room Type Reserved',('Room_Type 1','Room_Type 2','Room_Type 3','Room_Type 4','Room_Type 5','Room_Type 6'),index=1)
37
+ lead_time = st.number_input('Lead Time', min_value=0, max_value=500, value=0, step=1)
38
+ arrival_year = st.number_input('Arrival Year', min_value=2017, max_value=2025, value=2017, step=1)
39
+ arrival_month = st.number_input('Arrival Month', min_value=1, max_value=12, value=1, step=1)
40
+ arrival_date= st.number_input('Arrival Date', min_value=1, max_value=31, value=26, step=1)
41
+ market_segment_type = st.selectbox('Market Segment Type', ('Online','Aviation','Corporate','Offline'),index=1)
42
+ repeated_guest= st.number_input('Repeated Guest', min_value=0, max_value=1, value=0, step=1)
43
+ no_of_previous_cancellations= st.number_input('Number of Previous Cancellations', min_value=0, max_value=13, value=0, step=1)
44
+ no_of_previous_bookings_not_canceled= st.number_input('Number of Previous Nookings Not Canceled', min_value=0, max_value=58, value=0, step=1)
45
+ avg_price_per_room= st.number_input('Avarage Price Per Room', min_value=0, max_value=540, value=50, step=1)
46
+ no_of_special_requests = st.number_input('Number of Special Requests', min_value=0, max_value=5, value=0, step=1)
47
+
48
+ submitted = st.form_submit_button('Predict')
49
+
50
+ # membuat data-set baru
51
+
52
+ data_inf = {
53
+ 'Booking_ID':booking_id,
54
+ 'no_of_adults':no_of_adults,
55
+ 'no_of_children':no_of_children,
56
+ 'no_of_weekend_nights':no_of_weekend_nights,
57
+ 'no_of_week_nights':no_of_week_nights,
58
+ 'type_of_meal_plan': type_of_meal_plan,
59
+ 'required_car_parking_space': required_car_parking_space ,
60
+ 'room_type_reserved': room_type_reserved ,
61
+ 'lead_time':lead_time,
62
+ 'arrival_year':arrival_year,
63
+ 'arrival_month':arrival_month,
64
+ 'arrival_date':arrival_date,
65
+ 'market_segment_type': market_segment_type,
66
+ 'repeated_guest':repeated_guest,
67
+ 'no_of_previous_cancellations':no_of_previous_cancellations,
68
+ 'no_of_previous_bookings_not_canceled':no_of_previous_bookings_not_canceled,
69
+ 'avg_price_per_room':avg_price_per_room,
70
+ 'no_of_special_requests':no_of_special_requests }
71
+
72
+
73
+ data_inf = pd.DataFrame([data_inf])
74
+ data_inf
75
+
76
+ if submitted:
77
+ # Split between Numerical Columns and Categorical Columns
78
+ data_inf_num = data_inf[list_num_cols]
79
+ data_inf_cat = data_inf[list_cat_cols]
80
+
81
+ # Feature Scaling and Feature Encoding
82
+ data_inf_num_scaled = scaler.transform(data_inf_num)
83
+ data_inf_cat_encoded = encoder.transform(data_inf_cat)
84
+ data_inf_final = np.concatenate((data_inf_num_scaled, data_inf_cat_encoded.toarray()), axis=1)
85
+
86
+ # Predict
87
+ y_pred_inf = rfc.predict(data_inf_final)
88
+ st.write('# Prediksi : ', str(int(y_pred_inf)))
89
+ st.write('Jika prediksi menunjukan angka 1 maka ada kemungkinan booking tersebut akan di cancel oleh pelanggan')
90
+
91
+ if __name__ == '__main__': run()
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ streamlit
2
+ pandas
3
+ seaborn
4
+ matplotlib
5
+ numpy
6
+ scikit-learn==1.2.1
7
+ plotly