ESMATUGBA commited on
Commit
00d02e3
·
verified ·
1 Parent(s): 7011853

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +115 -123
app.py CHANGED
@@ -1,124 +1,116 @@
1
- import streamlit as st
2
- import pandas as pd
3
- import numpy as np
4
- import matplotlib.pyplot as plt
5
- import pickle
6
- from tensorflow.keras.models import load_model
7
-
8
- # Sayfa Yapılandırması
9
- st.set_page_config(page_title="Hotel AI Decision Support", layout="wide")
10
-
11
- @st.cache_resource
12
- def load_assets():
13
- model = load_model("hotel_model.keras")
14
- with open("scaler.pkl", "rb") as f:
15
- sc = pickle.load(f)
16
- return model, sc
17
-
18
- try:
19
- model, sc = load_assets()
20
- except Exception as e:
21
- st.error(f"Error: Assets not found! / Hata: Dosyalar bulunamadı! {e}")
22
- st.stop()
23
-
24
- # ==========================================
25
- # SIDEBAR / SOL PANEL (REHBER GERİ GELDİ)
26
- # ==========================================
27
- with st.sidebar:
28
- st.markdown("### 📖 Guide & Info / Rehber")
29
- st.info("""
30
- **How to Upload? / Nasıl Yüklenmeli?**
31
- CSV Format:
32
- | bookings |
33
- | :--- |
34
- | 150 |
35
- | 210 |
36
- """)
37
- st.markdown("---")
38
- st.markdown("### ❓ What is 'Bookings'? / 'Bookings' Nedir?")
39
- st.write("""
40
- **EN:** Total daily reservations. If 2023-05-10 is 150, it means 150 rooms were booked.
41
-
42
- **TR:** Günlük toplam rezervasyon. Eğer 2023-05-10 değeri 150 ise, o gün 150 oda satılmış demektir.
43
- """)
44
- st.markdown("---")
45
- st.markdown("### 📊 Thresholds / Yoğunluk")
46
- st.warning("High (Yoğun): > Avg + 20%")
47
- st.success("Stable (Stabil): Normal range")
48
- st.markdown("---")
49
- file = st.sidebar.file_uploader("Upload CSV / CSV Yükle", type=["csv"])
50
-
51
- # ==========================================
52
- # MAIN CONTENT / ANA SAYFA
53
- # ==========================================
54
- st.markdown("<h1 style='text-align: center;'>🏨 Hotel Demand Forecasting / Otel Talep Tahmini</h1>", unsafe_allow_html=True)
55
-
56
- if file is not None:
57
- df = pd.read_csv(file)
58
-
59
- # Hesaplamalar
60
- raw_data = df[["bookings"]].values
61
- data_scaled = sc.transform(raw_data)
62
- predictions_scaled = model.predict(data_scaled)
63
- predictions = sc.inverse_transform(predictions_scaled).flatten().astype(int)
64
-
65
- avg_val = int(predictions.mean())
66
- busy_limit = int(avg_val * 1.2)
67
- current_max = int(predictions.max())
68
-
69
- # 1. METRİKLER
70
- st.markdown("---")
71
- c1, c2, c3 = st.columns(3)
72
- with c1:
73
- st.markdown(f"<div style='text-align: center;'><strong>Avg Forecast / Ort. Tahmin</strong><br><span style='font-size: 45px; color: #2980b9;'>{avg_val}</span></div>", unsafe_allow_html=True)
74
- with c2:
75
- st.markdown(f"<div style='text-align: center;'><strong>Busy Threshold / Yoğunluk Sınırı</strong><br><span style='font-size: 45px; color: #e74c3c;'>{busy_limit}</span></div>", unsafe_allow_html=True)
76
- with c3:
77
- status_color = "#e67e22" if current_max >= busy_limit else "#27ae60"
78
- status_text = "HIGH / YOĞUN" if current_max >= busy_limit else "STABLE / STABİL"
79
- st.markdown(f"<div style='text-align: center;'><strong>Status / Durum</strong><br><span style='font-size: 40px; color: {status_color}; font-weight: bold;'>{status_text}</span></div>", unsafe_allow_html=True)
80
-
81
- # 2. YÖNETİM TAVSİYESİ
82
- st.markdown("---")
83
- st.markdown("<h3 style='text-align: center;'>👔 Management Advice / Yönetim Tavsiyesi</h3>", unsafe_allow_html=True)
84
- advice_col_en, advice_col_tr = st.columns(2)
85
- with advice_col_en:
86
- if current_max >= busy_limit: st.warning("**High Demand:** Peak days detected. Increase staff.")
87
- else: st.success("**Stable Demand:** Demand is normal. Focus on maintenance.")
88
- with advice_col_tr:
89
- if current_max >= busy_limit: st.warning("**Yoğun Talep:** Zirve günler tespit edildi. Personel artırın.")
90
- else: st.success("**Stabil Talep:** Talep normal. Bakım işlerine odaklanılabilir.")
91
-
92
- # 3. SONUÇ TABLOSU (YUKARIYA TAŞINDI)
93
- st.markdown("---")
94
- st.subheader("📋 Results Table / Sonuç Tablosu")
95
- result_df = pd.DataFrame({
96
- "Actual / Gerçek": raw_data.flatten(),
97
- "Predicted / Tahmin": predictions
98
- })
99
- st.dataframe(result_df, use_container_width=True, height=250)
100
-
101
- st.download_button(
102
- label="📥 Download Results / Sonuçları İndir",
103
- data=result_df.to_csv(index=False).encode('utf-8'),
104
- file_name="hotel_forecast_results.csv",
105
- mime="text/csv"
106
- )
107
-
108
- # 4. GRAFİK
109
- st.markdown("---")
110
- st.subheader("📈 Prediction Graph / Tahmin Grafiği")
111
- fig, ax = plt.subplots(figsize=(10, 3.5))
112
- ax.plot(raw_data, label="Actual / Gerçek", color="#bdc3c7", alpha=0.6, linestyle='--')
113
- ax.plot(predictions, label="AI Forecast / YZ Tahmini", color="#2980b9", linewidth=2)
114
- ax.axhline(y=busy_limit, color='#e74c3c', linestyle=':', label="Limit")
115
- ax.legend(prop={'size': 8})
116
- st.pyplot(fig)
117
-
118
- # 5. VERİ ÖN İZLEME (EN ALTTA)
119
- st.markdown("---")
120
- st.subheader("📊 Data Preview / Veri Ön İzleme (Raw Data)")
121
- st.dataframe(df, use_container_width=True, height=150)
122
-
123
- else:
124
  st.warning("👈 Please upload a CSV file from the left panel. / Lütfen sol panelden bir CSV dosyası yükleyin.")
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+ import pickle
6
+ import os
7
+ from tensorflow.keras.models import load_model
8
+
9
+ # Sayfa Yapılandırması
10
+ st.set_page_config(page_title="Hotel AI Decision Support", layout="wide")
11
+
12
+ @st.cache_resource
13
+ def load_assets():
14
+ # Dosya isimlerini burada tanımlıyoruz
15
+ model_file = "hotel_model.keras"
16
+ scaler_file = "scaler.pkl"
17
+
18
+ # Dosya varlık kontrolü
19
+ if not os.path.exists(model_file):
20
+ st.error(f"❌ Model dosyası bulunamadı: {model_file}")
21
+ st.stop()
22
+ if not os.path.exists(scaler_file):
23
+ st.error(f"❌ Scaler dosyası bulunamadı: {scaler_file}")
24
+ st.stop()
25
+
26
+ model = load_model(model_file)
27
+ with open(scaler_file, "rb") as f:
28
+ sc = pickle.load(f)
29
+ return model, sc
30
+
31
+ # Varlıkları yükle
32
+ try:
33
+ model, sc = load_assets()
34
+ except Exception as e:
35
+ st.error(f"⚠️ Yükleme Hatası: {e}")
36
+ st.stop()
37
+
38
+ # ==========================================
39
+ # SIDEBAR / SOL PANEL
40
+ # ==========================================
41
+ with st.sidebar:
42
+ st.markdown("### 📖 Guide & Info / Rehber")
43
+ st.info("**How to Upload? / Nasıl Yüklenmeli?**\n\nCSV Format:\n| bookings |\n| :--- |\n| 150 |")
44
+ st.markdown("---")
45
+ st.markdown("### What is 'Bookings'? / 'Bookings' Nedir?")
46
+ st.write("EN: Total daily reservations.\n\nTR: Günlük toplam rezervasyon.")
47
+ st.markdown("---")
48
+ st.markdown("### 📊 Thresholds / Yoğunluk")
49
+ st.warning("High (Yoğun): > Avg + 20%")
50
+ st.markdown("---")
51
+ file = st.file_uploader("Upload CSV / CSV Yükle", type=["csv"])
52
+
53
+ # ==========================================
54
+ # MAIN CONTENT / ANA SAYFA
55
+ # ==========================================
56
+ st.markdown("<h1 style='text-align: center;'>🏨 Hotel Demand Forecasting / Otel Talep Tahmini</h1>", unsafe_allow_html=True)
57
+
58
+ if file is not None:
59
+ df = pd.read_csv(file)
60
+
61
+ # Tahmin İşlemleri
62
+ raw_data = df[["bookings"]].values
63
+ data_scaled = sc.transform(raw_data)
64
+ predictions_scaled = model.predict(data_scaled)
65
+ predictions = sc.inverse_transform(predictions_scaled).flatten().astype(int)
66
+
67
+ avg_val = int(predictions.mean())
68
+ busy_limit = int(avg_val * 1.2)
69
+ current_max = int(predictions.max())
70
+
71
+ # 1. METRİKLER
72
+ st.markdown("---")
73
+ c1, c2, c3 = st.columns(3)
74
+ with c1:
75
+ st.markdown(f"<div style='text-align: center;'><strong>Avg Forecast / Ort. Tahmin</strong><br><span style='font-size: 45px; color: #2980b9;'>{avg_val}</span></div>", unsafe_allow_html=True)
76
+ with c2:
77
+ st.markdown(f"<div style='text-align: center;'><strong>Busy Threshold / Yoğunluk Sınırı</strong><br><span style='font-size: 45px; color: #e74c3c;'>{busy_limit}</span></div>", unsafe_allow_html=True)
78
+ with c3:
79
+ status_color = "#e67e22" if current_max >= busy_limit else "#27ae60"
80
+ status_text = "HIGH / YOĞUN" if current_max >= busy_limit else "STABLE / STABİL"
81
+ st.markdown(f"<div style='text-align: center;'><strong>Status / Durum</strong><br><span style='font-size: 40px; color: {status_color}; font-weight: bold;'>{status_text}</span></div>", unsafe_allow_html=True)
82
+
83
+ # 2. YÖNETİM TAVSİYESİ
84
+ st.markdown("---")
85
+ st.markdown("<h3 style='text-align: center;'>👔 Management Advice / Yönetim Tavsiyesi</h3>", unsafe_allow_html=True)
86
+ ce, ct = st.columns(2)
87
+ with ce:
88
+ if current_max >= busy_limit: st.warning("**High Demand Advice:** Peak days detected. Increase staff.")
89
+ else: st.success("**Stable Demand Advice:** Demand is normal. Focus on maintenance.")
90
+ with ct:
91
+ if current_max >= busy_limit: st.warning("**Yoğun Talep Tavsiyesi:** Zirve günler tespit edildi. Personel artırın.")
92
+ else: st.success("**Stabil Talep Tavsiyesi:** Talep normal. Bakım işlerine odaklanılabilir.")
93
+
94
+ # 3. SONUÇ TABLOSU
95
+ st.markdown("---")
96
+ st.subheader("📋 Results Table / Sonuç Tablosu")
97
+ res_df = pd.DataFrame({"Actual / Gerçek": raw_data.flatten(), "Predicted / Tahmin": predictions})
98
+ st.dataframe(res_df, use_container_width=True, height=200)
99
+
100
+ # 4. GRAFİK
101
+ st.markdown("---")
102
+ st.subheader("📈 Prediction Graph / Tahmin Grafiği")
103
+ fig, ax = plt.subplots(figsize=(10, 3.5))
104
+ ax.plot(raw_data, label="Actual / Gerçek", color="#bdc3c7", alpha=0.6, linestyle='--')
105
+ ax.plot(predictions, label="AI Forecast / YZ Tahmini", color="#2980b9", linewidth=2)
106
+ ax.axhline(y=busy_limit, color='#e74c3c', linestyle=':', label="Limit")
107
+ ax.legend(prop={'size': 8})
108
+ st.pyplot(fig)
109
+
110
+ # 5. VERİ ÖN İZLEME
111
+ st.markdown("---")
112
+ st.subheader("📊 Data Preview / Veri Ön İzleme")
113
+ st.dataframe(df, use_container_width=True, height=150)
114
+
115
+ else:
 
 
 
 
 
 
 
 
116
  st.warning("👈 Please upload a CSV file from the left panel. / Lütfen sol panelden bir CSV dosyası yükleyin.")