fernandobriann commited on
Commit
0a0b0ba
Β·
verified Β·
1 Parent(s): e410bcd

Upload Deployment

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
+ src/hotel_bookings.csv filter=lfs diff=lfs merge=lfs -text
src/best_model_rf_clean.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7077b3c1db0a8338a4cd7b9736c88cfa2aacac4fb9209db9b8cde0c16de776dc
3
+ size 224368818
src/hotel_bookings.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7c2ae42a7353905ea136e5c2287f17c92c5435826598bfbb8491c6f0c7b1fc06
3
+ size 16855599
src/prediction.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+
3
+ def predict(data, model, prep):
4
+ df = pd.DataFrame([data])
5
+
6
+ # Handle country
7
+ top_country = ['PRT', 'GBR', 'FRA', 'ESP', 'DEU', 'ITA', 'IRL', 'BEL', 'BRA', 'NLD']
8
+ df['country'] = df['country'].apply(lambda x: x if x in top_country else 'Other')
9
+
10
+ # Fix missing columns
11
+ if 'agent' not in df.columns:
12
+ df['agent'] = 0
13
+
14
+ if 'company' not in df.columns:
15
+ df['company'] = 0
16
+
17
+ # Transform
18
+ df_processed = prep.transform(df)
19
+
20
+ # Predict
21
+ result = model.predict(df_processed)
22
+
23
+ return result[0]
src/preprocessor.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4176c338877593df7ae282fe0f0d14d5bd9a30b4b7d8b5294f9143f8d3f0aec2
3
+ size 8806
src/rf_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7a49baba7cadec2ed9f6582887771b89fd05f082febc8f7b5d1c1211c4468522
3
+ size 224350553
src/streamlit_app.py CHANGED
@@ -1,40 +1,136 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
- import streamlit as st
5
-
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import joblib
3
+ import pandas as pd
4
+ import seaborn as sns
5
+ import matplotlib.pyplot as plt
6
+ from prediction import predict
7
+
8
+ # ================================
9
+ # Load model & preprocessor
10
+ # ================================
11
+ model = joblib.load('rf_model.pkl')
12
+ prep = joblib.load('preprocessor.pkl')
13
+
14
+ # ================================
15
+ # Sidebar Navigation
16
+ # ================================
17
+ st.sidebar.title("Navigation")
18
+ page = st.sidebar.selectbox("Choose Page", ["Prediction", "EDA"])
19
+
20
+ st.sidebar.markdown("### Created by Fernando Brian")
21
+ st.sidebar.markdown("### Deployed on Hugging Face")
22
+
23
+ # ================================
24
+ # πŸ“Š PAGE 1: PREDICTION
25
+ # ================================
26
+ if page == "Prediction":
27
+
28
+ st.title("Hotel Booking Cancellation Prediction")
29
+
30
+ st.write("Masukkan data booking untuk memprediksi kemungkinan pembatalan.")
31
+
32
+ # ================================
33
+ # Input User
34
+ # ================================
35
+ lead_time = st.slider("Lead Time", 0, 365, 50)
36
+ hotel = st.selectbox("Hotel Type", ["City Hotel", "Resort Hotel"])
37
+ deposit_type = st.selectbox("Deposit Type", ["No Deposit", "Non Refund", "Refundable"])
38
+ market_segment = st.selectbox("Market Segment", ["Online TA", "Offline TA/TO", "Direct", "Corporate"])
39
+ country = st.text_input("Country (contoh: PRT, GBR)", "PRT")
40
+
41
+ # ================================
42
+ # Prediction Button
43
+ # ================================
44
+ if st.button("Predict"):
45
+
46
+ data = {
47
+ 'hotel': hotel,
48
+ 'lead_time': lead_time,
49
+ 'arrival_date_year': 2017,
50
+ 'arrival_date_month': 'July',
51
+ 'arrival_date_week_number': 27,
52
+ 'arrival_date_day_of_month': 1,
53
+ 'stays_in_weekend_nights': 1,
54
+ 'stays_in_week_nights': 2,
55
+ 'adults': 2,
56
+ 'children': 0,
57
+ 'babies': 0,
58
+ 'meal': 'BB',
59
+ 'country': country,
60
+ 'market_segment': market_segment,
61
+ 'distribution_channel': 'TA/TO',
62
+ 'is_repeated_guest': 0,
63
+ 'previous_cancellations': 0,
64
+ 'previous_bookings_not_canceled': 0,
65
+ 'reserved_room_type': 'A',
66
+ 'assigned_room_type': 'A',
67
+ 'booking_changes': 0,
68
+ 'deposit_type': deposit_type,
69
+ 'days_in_waiting_list': 0,
70
+ 'customer_type': 'Transient',
71
+ 'adr': 100.0,
72
+ 'required_car_parking_spaces': 0,
73
+ 'total_of_special_requests': 1,
74
+ 'agent': 0,
75
+ 'company': 0
76
+ }
77
+
78
+ # Predict
79
+ result = predict(data, model, prep)
80
+
81
+ # Output
82
+ if result == 1:
83
+ st.error("❌ Booking kemungkinan akan dibatalkan")
84
+ else:
85
+ st.success("βœ… Booking kemungkinan tidak dibatalkan")
86
+
87
+ # ================================
88
+ # πŸ“ˆ PAGE 2: EDA
89
+ # ================================
90
+ elif page == "EDA":
91
+
92
+ st.title("Exploratory Data Analysis")
93
+
94
+ # Load dataset
95
+ df = pd.read_csv("hotel_bookings.csv")
96
+
97
+ # ================================
98
+ # Dataset Preview
99
+ # ================================
100
+ st.subheader("Dataset Preview")
101
+ st.dataframe(df.head())
102
+
103
+ # ================================
104
+ # Plot 1 - Cancellation Distribution
105
+ # ================================
106
+ st.subheader("Distribusi Pembatalan")
107
+
108
+ fig, ax = plt.subplots()
109
+ sns.countplot(x='is_canceled', data=df, ax=ax)
110
+ ax.set_title("Cancellation Distribution")
111
+ st.pyplot(fig)
112
+
113
+ # ================================
114
+ # Plot 2 - Lead Time vs Cancellation
115
+ # ================================
116
+ st.subheader("Lead Time vs Cancellation")
117
+
118
+ fig, ax = plt.subplots()
119
+ sns.boxplot(x='is_canceled', y='lead_time', data=df, ax=ax)
120
+ ax.set_title("Lead Time vs Cancellation")
121
+ st.pyplot(fig)
122
+
123
+ # ================================
124
+ # Plot 3 - Market Segment Distribution
125
+ # ================================
126
+ st.subheader("Market Segment Distribution")
127
+
128
+ fig, ax = plt.subplots()
129
+ sns.countplot(
130
+ y='market_segment',
131
+ data=df,
132
+ order=df['market_segment'].value_counts().index,
133
+ ax=ax
134
+ )
135
+ ax.set_title("Market Segment Distribution")
136
+ st.pyplot(fig)