Spaces:
Sleeping
Sleeping
File size: 5,822 Bytes
ce6b970 a6df996 025c561 85322bf 7fcf7cd ed60599 a6df996 7fcf7cd 54d48f5 a6df996 ed60599 a6df996 ad72163 a6df996 ed60599 a6df996 2913017 a6df996 85322bf a6df996 54d48f5 a6df996 2913017 a6df996 2913017 a6df996 85322bf a6df996 85322bf a6df996 85322bf 7fcf7cd a6df996 85322bf a6df996 85322bf a6df996 85322bf a6df996 85322bf a6df996 7fcf7cd 54d48f5 a6df996 85322bf a6df996 85322bf a6df996 7fcf7cd b558acd a6df996 85322bf a6df996 a91e59d a6df996 85322bf ce6b970 a6df996 85322bf a6df996 85322bf a6df996 85322bf a6df996 996b756 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | 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
@st.cache_resource
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.") |