Spaces:
Sleeping
Sleeping
| import os | |
| import warnings | |
| # --- TİTREMEYİ VE GEREKSİZ LOGLARI ENGELLE --- | |
| os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3' | |
| os.environ['TF_ENABLE_ONEDNN_OPTS'] = '0' | |
| warnings.filterwarnings('ignore') | |
| import streamlit as st | |
| import pandas as pd | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import pickle | |
| from tensorflow.keras.models import load_model | |
| # Sayfa Yapılandırması | |
| st.set_page_config(page_title="Hotel AI Decision Support", layout="wide") | |
| def load_assets(): | |
| model_file = "hotel_model.keras" | |
| scaler_file = "scaler.pkl" | |
| if not os.path.exists(model_file) or not os.path.exists(scaler_file): | |
| st.error("❌ Dosyalar bulunamadı! Lütfen Hugging Face klasörünüzü kontrol edin.") | |
| st.stop() | |
| model = load_model(model_file) | |
| with open(scaler_file, "rb") as f: | |
| sc = pickle.load(f) | |
| return model, sc | |
| try: | |
| model, sc = load_assets() | |
| except Exception as e: | |
| st.error(f"⚠️ Yükleme Hatası: {e}") | |
| st.stop() | |
| # ========================================== | |
| # SIDEBAR / SOL PANEL (TÜM BİLGİLER BURADA) | |
| # ========================================== | |
| with st.sidebar: | |
| st.markdown("<h2 style='color: #2980b9;'>📖 User Guide / Rehber</h2>", unsafe_allow_html=True) | |
| # 1. NASIL YÜKLENMELİ? | |
| st.markdown("### 📥 How to Upload? / Nasıl Yüklenmeli?") | |
| st.info(""" | |
| **Format:** Sütun adı **'bookings'** olan bir CSV yükleyin. | |
| | bookings | | |
| | :--- | | |
| | 120 | | |
| | 155 | | |
| """) | |
| # 2. ANALİZİ BAŞLAT (İstediğin yer: Rehberin hemen altı) | |
| st.markdown("### 🚀 Start Analysis / Analizi Başlat") | |
| file = st.file_uploader("Upload CSV / CSV Yükle", type=["csv"]) | |
| st.markdown("---") | |
| # 3. BOOKINGS NEDİR? | |
| st.markdown("### ❓ What is 'Bookings'? / 'Bookings' Nedir?") | |
| st.write(""" | |
| **EN:** Total daily reservations. (Example: 150 means 150 rooms sold) | |
| **TR:** Günlük toplam rezervasyon. (Örn: 150 değeri o gün 150 oda satıldığını gösterir) | |
| """) | |
| st.markdown("---") | |
| # 4. YOĞUNLUK MANTIĞI | |
| st.markdown("### 📊 Thresholds / Yoğunluk") | |
| st.warning("**High (Yoğun):** > Ortalamadan %20 fazla") | |
| st.success("**Stable (Stabil):** Normal aralıkta") | |
| # ========================================== | |
| # MAIN CONTENT / ANA SAYFA | |
| # ========================================== | |
| st.markdown("<h1 style='text-align: center;'>🏨 Hotel Demand Forecasting / Otel Talep Tahmini</h1>", unsafe_allow_html=True) | |
| if file is not None: | |
| df = pd.read_csv(file) | |
| # AI TAHMİN SÜRECİ | |
| raw_data = df[["bookings"]].values | |
| data_scaled = sc.transform(raw_data) | |
| predictions_scaled = model.predict(data_scaled, verbose=0) | |
| predictions = sc.inverse_transform(predictions_scaled).flatten().astype(int) | |
| avg_val = int(predictions.mean()) | |
| busy_limit = int(avg_val * 1.2) | |
| current_max = int(predictions.max()) | |
| # 1. METRİKLER (EN ÜSTTE) | |
| st.markdown("---") | |
| c1, c2, c3 = st.columns(3) | |
| with c1: 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) | |
| with c2: 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) | |
| with c3: | |
| status_color = "#e67e22" if current_max >= busy_limit else "#27ae60" | |
| status_text = "HIGH / YOĞUN" if current_max >= busy_limit else "STABLE / STABİL" | |
| 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) | |
| # 2. YÖNETİM TAVSİYESİ (ÜSTTE) | |
| st.markdown("---") | |
| st.markdown("<h3 style='text-align: center;'>👔 Management Advice / Yönetim Tavsiyesi</h3>", unsafe_allow_html=True) | |
| adv_en, adv_tr = st.columns(2) | |
| with adv_en: | |
| if current_max >= busy_limit: st.warning("**High Demand Advice:** Peak days detected. Increase staff.") | |
| else: st.success("**Stable Demand Advice:** Demand is normal. Focus on maintenance.") | |
| with adv_tr: | |
| if current_max >= busy_limit: st.warning("**Yoğun Talep Tavsiyesi:** Zirve günler tespit edildi. Personel artırın.") | |
| else: st.success("**Stabil Talep Tavsiyesi:** Talep normal. Bakım işlerine odaklanılabilir.") | |
| # 3. SONUÇ TABLOSU (GRAFİK ÜSTÜNDE) | |
| st.markdown("---") | |
| st.subheader("📋 Results Table / Sonuç Tablosu") | |
| res_df = pd.DataFrame({"Actual / Gerçek": raw_data.flatten(), "Predicted / Tahmin": predictions}) | |
| st.dataframe(res_df, width=1200, height=250) | |
| st.download_button("📥 Download Results", res_df.to_csv(index=False).encode('utf-8'), "hotel_results.csv", "text/csv") | |
| # 4. GRAFİK | |
| st.markdown("---") | |
| st.subheader("📈 Prediction Graph / Tahmin Grafiği") | |
| plt.clf() | |
| fig, ax = plt.subplots(figsize=(10, 3.5)) | |
| ax.plot(raw_data, label="Actual / Gerçek", color="#bdc3c7", alpha=0.6, linestyle='--') | |
| ax.plot(predictions, label="AI Forecast / YZ Tahmini", color="#2980b9", linewidth=2) | |
| ax.axhline(y=busy_limit, color='#e74c3c', linestyle=':', label="Limit") | |
| ax.legend(prop={'size': 8}) | |
| st.pyplot(fig, clear_figure=True) | |
| # 5. VERİ ÖN İZLEME (EN ALTTA) | |
| st.markdown("---") | |
| st.subheader("📊 Data Preview / Veri Ön İzleme") | |
| st.dataframe(df, width=1200, height=150) | |
| else: | |
| st.warning("👈 Please upload a CSV file from the left panel. / Lütfen sol panelden bir CSV dosyası yükleyin.") |