Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import pickle | |
| from nltk.tokenize import word_tokenize | |
| from nltk.stem import WordNetLemmatizer | |
| from typing import Dict, Any, List | |
| import nltk | |
| import os | |
| # --- NLTK PATH FIX (CRITICAL) --- | |
| # setup.sh, NLTK verilerini 'src/' içine indirir. | |
| # Uygulamanın da bu klasöre bakması gerektiğini belirtiyoruz. | |
| NLTK_DATA_PATH = os.path.join(os.getcwd(), 'src') | |
| if NLTK_DATA_PATH not in nltk.data.path: | |
| # 'src/' yolunu NLTK arama yollarına ekliyoruz. | |
| nltk.data.path.append(NLTK_DATA_PATH) | |
| # --- Streamlit Sayfa Ayarları --- | |
| st.set_page_config( | |
| # Sayfa başlığına bina emojisi (🏢) eklendi | |
| page_title="🏢 Hotel Recommendation System", | |
| layout="wide", | |
| initial_sidebar_state="collapsed" | |
| ) | |
| # ---------------------------------------------------- | |
| # 1. Veri ve NLP Araçlarını Yükleme | |
| # ---------------------------------------------------- | |
| # Verinin her etkileşimde yeniden yüklenmesini engellemek için önbelleğe alma | |
| def load_data(): | |
| """Pickle dosyalarını yükler ve DataFrame ile NLP araçlarını döndürür.""" | |
| try: | |
| # Dosyalar 'src/' içinden okunuyor (Lütfen dosya yollarınızın doğru olduğundan emin olun) | |
| with open('src/hotel_data.pkl', 'rb') as file: | |
| df_loaded = pickle.load(file) | |
| with open('src/nlp_tools.pkl', 'rb') as file: | |
| nlp_tools_loaded = pickle.load(file) | |
| return { | |
| 'df': df_loaded, | |
| 'stop_words': nlp_tools_loaded['stop_words'], | |
| 'lemmatizer': nlp_tools_loaded['lemmatizer'] | |
| } | |
| except FileNotFoundError as e: | |
| st.error(f"Error: Required file not found: {e.filename}. Please ensure all required files are in the 'src/' directory.") | |
| return None | |
| except Exception as e: | |
| st.error(f"An error occurred during loading: {e}") | |
| return None | |
| # Load the data bundle and unpack components | |
| data_bundle = load_data() | |
| if data_bundle is not None: | |
| df = data_bundle['df'] | |
| # NLP araçları global değişkenlere atanır | |
| STOP_WORDS = data_bundle['stop_words'] | |
| LEMMATIZER = data_bundle['lemmatizer'] | |
| else: | |
| # Veri yüklenemezse uygulamayı durdur | |
| st.stop() | |
| # ---------------------------------------------------- | |
| # 2. Tavsiye Fonksiyonu (Optimize Edilmiş) | |
| # ---------------------------------------------------- | |
| def recommend_hotel(location: str, description: str, data_df: pd.DataFrame) -> pd.DataFrame: | |
| """Kullanıcı açıklamasına göre otel benzerliğini hesaplar ve en iyi 5 öneriyi döndürür.""" | |
| if not isinstance(description, str): | |
| return pd.DataFrame({'Error': ['Description must be a string.']}) | |
| # 1. Kullanıcı Açıklamasını İşleme | |
| # NLTK, ayarlanmış yol sayesinde verileri bulacaktır. | |
| description_tokens = word_tokenize(description.lower()) | |
| user_processed_set = set() | |
| for word in description_tokens: | |
| if word not in STOP_WORDS: | |
| user_processed_set.add(LEMMATIZER.lemmatize(word)) | |
| if not user_processed_set: | |
| return pd.DataFrame({'Error': ['Please enter a more descriptive query.']}) | |
| # 2. Konuma Göre Filtreleme | |
| country = data_df[data_df['Country'] == location.lower()].copy() | |
| if country.empty: | |
| return pd.DataFrame({'Error': [f"No hotels found in '{location}'."]}) | |
| # 3. Benzerlik Hesaplama (Küme Kesişimi) | |
| similarity_scores = country['Processed_Tags'].apply( | |
| lambda hotel_tags: len(hotel_tags.intersection(user_processed_set))) | |
| country['similarity'] = similarity_scores | |
| # 4. Sıralama ve Filtreleme | |
| country.sort_values(by=['similarity', 'Average_Score'], | |
| ascending=[False, False], | |
| inplace=True) | |
| country.drop_duplicates(subset='Hotel_Name', keep='first', inplace=True) | |
| country.reset_index(drop=True, inplace=True) | |
| return country[["Hotel_Name", "Average_Score", "Hotel_Address"]].head(5) | |
| # ---------------------------------------------------- | |
| # 3. Streamlit Arayüzü | |
| # ---------------------------------------------------- | |
| # Ana başlıkta bina emojisi (🏢) | |
| st.title("🏢 Hotel Recommendation System") | |
| st.markdown("Find the top 5 hotels based on your preferred location and description.") | |
| # --- Kullanıcı Girişleri --- | |
| st.subheader("Find Your Optimal Hotel") | |
| # Mevcut ülke listesini alma | |
| available_countries = sorted(df['Country'].unique().tolist()) | |
| default_country = available_countries[0] if available_countries else "" | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| location = st.selectbox( | |
| "Select Location (Country)", | |
| options=available_countries, | |
| # Hata düzeltildi | |
| index=available_countries.index(default_country) if default_country else 0 | |
| ) | |
| with col2: | |
| description = st.text_area( | |
| "Preference Description", | |
| placeholder="E.g., romantic trip with great breakfast and spa, or: business needs quiet room and gym", | |
| height=100 | |
| ) | |
| # --- Buton ve Çıktı --- | |
| if st.button("Get Recommendations", type="primary"): | |
| if location and description: | |
| # Tavsiye fonksiyonunu çağır | |
| recommendations_df = recommend_hotel(location, description, df) | |
| st.subheader("Top Recommended Hotels") | |
| # Sonuçları görüntüle | |
| if 'Error' in recommendations_df.columns: | |
| st.error(recommendations_df.iloc[0]['Error']) | |
| else: | |
| # Sütun isimlerini daha okunaklı hale getir | |
| recommendations_df.columns = ["Hotel Name", "Average Score", "Address"] | |
| st.dataframe(recommendations_df, use_container_width=True) | |
| else: | |
| st.warning("Please enter both location and description.") |