Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import pickle | |
| import plotly.express as px | |
| import os | |
| # 1. Sayfa Ayarları | |
| st.set_page_config(page_title="Movie Recommender AI", layout="wide") | |
| # 2. Şık Görsel Stil (CSS) - Senin beğendiğin tam tasarım | |
| st.markdown(""" | |
| <style> | |
| .stApp { background-color: #141414; color: white; } | |
| .stButton>button { | |
| width: 100%; | |
| background-color: #333333; | |
| color: white; | |
| font-weight: bold; | |
| border: 1px solid #555; | |
| border-radius: 5px; | |
| height: 3em; | |
| } | |
| .stButton>button:hover { background-color: #e50914; border: 1px solid #e50914; color: white; } | |
| .stSelectbox label { color: white !important; font-size: 16px !important; } | |
| .movie-card { | |
| background-color: #262730; | |
| padding: 20px; | |
| border-radius: 10px; | |
| border-top: 5px solid #e50914; | |
| height: 520px; | |
| margin-bottom: 20px; | |
| } | |
| h1, h2, h3, h4, p, span { color: white !important; } | |
| .match-tag { | |
| background-color: #e50914; | |
| color: white; | |
| text-align: center; | |
| border-radius: 5px; | |
| padding: 5px; | |
| font-size: 14px; | |
| font-weight: bold; | |
| margin-top: 10px; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # 3. Veri ve Model Yükleme (Hugging Face / Xet uyumlu) | |
| def load_assets(): | |
| try: | |
| # Dosya kontrolü | |
| if not os.path.exists('netflix_titles.csv'): | |
| return None, None, None | |
| df = pd.read_csv('netflix_titles.csv') | |
| with open('similarity.pkl', 'rb') as f: | |
| similarity = pickle.load(f) | |
| with open('indices.pkl', 'rb') as f: | |
| indices = pickle.load(f) | |
| return df, similarity, indices | |
| except Exception as e: | |
| st.error(f"Yükleme hatası: {e}") | |
| return None, None, None | |
| df, similarity, indices = load_assets() | |
| # Türkçe Çeviri Simülasyonu | |
| def get_turkish_desc(text): | |
| return f"Bu yapım genel olarak şunu konu almaktadır: {text[:100]}..." | |
| # Uygulama Başlangıcı | |
| if df is not None: | |
| st.title("🎬 Movie Recommendation System / Film Öneri Sistemi") | |
| st.write("---") | |
| col_left, col_main = st.columns([1.5, 3]) | |
| # --- SOL TARAF: ÖRNEKLER --- | |
| with col_left: | |
| st.subheader("💡 Suggestions / Örnekler") | |
| samples = [ | |
| ("Kota Factory", "Eğitim"), ("Ganglands", "Aksiyon"), | |
| ("Midnight Mass", "Korku"), ("Squid Game", "Gerilim"), | |
| ("The Witcher", "Fantastik"), ("Peaky Blinders", "Dram"), | |
| ("Dark", "Gizem"), ("Lucifer", "Suç") | |
| ] | |
| for i in range(0, len(samples), 2): | |
| c1, c2 = st.columns(2) | |
| with c1: | |
| if st.button(samples[i][0], key=f"btn_{samples[i][0]}"): | |
| st.session_state.selected_movie = samples[i][0] | |
| st.caption(f"({samples[i][1]})") | |
| with c2: | |
| if i+1 < len(samples): | |
| if st.button(samples[i+1][0], key=f"btn_{samples[i+1][0]}"): | |
| st.session_state.selected_movie = samples[i+1][0] | |
| st.caption(f"({samples[i+1][1]})") | |
| st.markdown(""" | |
| <div style="background-color: #1c1c1c; padding: 15px; border-radius: 8px; border: 1px solid #444; margin-top: 25px;"> | |
| <p style="font-size:14px; margin:0; color: #ddd !important;"> | |
| <b>İpucu:</b> Beğendiğiniz bir filmi sağdaki listeden seçebilir veya ismini yazarak aratabilirsiniz. | |
| </p> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| # --- SAĞ TARAF: ANALİZ VE SEÇİM --- | |
| with col_main: | |
| df['display_name'] = df['title'] + " (" + df['listed_in'] + ")" | |
| # Seçim kutusunda varsayılan değer kontrolü | |
| default_index = 0 | |
| if 'selected_movie' in st.session_state: | |
| try: | |
| default_index = list(df['title']).index(st.session_state.selected_movie) | |
| except: | |
| default_index = 0 | |
| selected_display = st.selectbox( | |
| "Bir Film veya Dizi Seçin / Select a Movie or TV Show:", | |
| df['display_name'].values, | |
| index=default_index | |
| ) | |
| selected_movie = selected_display.split(" (")[0] | |
| process_btn = st.button('ÖNERİLERİ ANALİZ ET VE GETİR / ANALYZE') | |
| # --- ANALİZ SONUÇLARI --- | |
| if process_btn: | |
| idx = indices[selected_movie] | |
| sim_scores = sorted(list(enumerate(similarity[idx])), key=lambda x: x[1], reverse=True) | |
| top_indices = [i[0] for i in sim_scores[1:6]] | |
| top_scores = [i[1] for i in sim_scores[1:6]] | |
| recs = df.iloc[top_indices].copy() | |
| recs['Score'] = top_scores | |
| st.subheader("📊 Benzerlik Oranları / Similarity Analysis") | |
| fig = px.bar(recs, x='Score', y='title', orientation='h', color='Score', | |
| color_continuous_scale='Reds', template="plotly_dark", height=300) | |
| fig.update_layout(yaxis={'categoryorder':'total ascending'}) | |
| st.plotly_chart(fig, use_container_width=True) | |
| st.write("---") | |
| st.subheader("Tavsiye Edilen Yapımlar / Recommendations") | |
| cols = st.columns(5) | |
| for i, col in enumerate(cols): | |
| with col: | |
| row = recs.iloc[i] | |
| st.markdown(f""" | |
| <div class="movie-card"> | |
| <h4 style="color: #e50914; font-size: 16px; margin-bottom: 2px;">{row['title']}</h4> | |
| <p style="font-size: 11px; color: #aaa !important;">{row['listed_in']}</p> | |
| <hr style="border-color: #444; margin: 10px 0;"> | |
| <p style="font-size: 12px; color: white !important;"><b>🇬🇧 Summary:</b><br>{row['description'][:60]}...</p> | |
| <p style="font-size: 12px; color: #ffcc00 !important;"><b>🇹🇷 Özet:</b><br>{get_turkish_desc(row['description'])}</p> | |
| <div class="match-tag">%{int(row['Score']*100)} Match</div> | |
| </div> | |
| """, unsafe_allow_html=True) | |
| else: | |
| st.error("Dosyalar yüklenemedi! 'netflix_titles.csv', 'similarity.pkl' ve 'indices.pkl' dosyalarını kontrol edin.") |