ESMATUGBA commited on
Commit
ced281e
·
verified ·
1 Parent(s): 7a4bc90

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +131 -63
app.py CHANGED
@@ -4,95 +4,163 @@ import pickle
4
  import plotly.express as px
5
  import os
6
 
7
- # 1. Sayfa Ayarları (Hugging Face üzerinde düzgün görünmesi için)
8
- st.set_page_config(page_title="Movie Similarity Analysis", layout="wide")
9
 
10
- # 2. Şık Arayüz Tasarımı (CSS)
11
  st.markdown("""
12
  <style>
13
- .stApp { background-color: #111111; color: white; }
 
 
 
 
 
 
 
 
 
 
 
14
  .movie-card {
15
- background-color: #1e1e1e; padding: 15px; border-radius: 10px;
16
- border-top: 4px solid #e50914; height: 420px; margin-bottom: 20px;
 
 
 
 
17
  }
 
18
  .match-tag {
19
- background-color: #e50914; color: white; text-align: center;
20
- border-radius: 5px; padding: 3px; font-size: 12px; font-weight: bold;
 
 
 
 
 
 
21
  }
22
- h1, h2, h3, h4 { color: #e50914 !important; }
23
  </style>
24
  """, unsafe_allow_html=True)
25
 
26
- # 3. Bellek Dostu Veri Yükleme
27
  @st.cache_resource
28
- def load_data():
29
  try:
30
- # Dosya yollarını kontrol et
31
  if not os.path.exists('netflix_titles.csv'):
32
- return "csv_error", None, None
33
-
34
- # CSV'yi sadece gerekli sütunlarla oku (RAM tasarrufu için)
35
- df = pd.read_csv('netflix_titles.csv', usecols=['title', 'listed_in', 'description'])
36
 
37
- # Model dosyalarını yükle
38
  with open('similarity.pkl', 'rb') as f:
39
  similarity = pickle.load(f)
 
40
  with open('indices.pkl', 'rb') as f:
41
  indices = pickle.load(f)
42
 
43
  return df, similarity, indices
44
  except Exception as e:
45
- return str(e), None, None
 
46
 
47
- df, similarity, indices = load_data()
48
 
49
- # 4. Uygulama Arayüzü
50
- if isinstance(df, pd.DataFrame):
51
- st.title("🎬 Movie Similarity Analysis")
52
- st.write("Film/Dizi Benzerlik Analizi ve Öneri Sistemi")
53
- st.markdown("---")
54
 
55
- # Seçim Kutusu
56
- selected_movie = st.selectbox("Bir yapım seçin veya aratın:", df['title'].values)
 
 
57
 
58
- if st.button("ANALİZ ET VE BENZERLERİ GETİR"):
59
- try:
60
- # Benzerlik hesaplama
61
- idx = indices[selected_movie]
62
- sim_scores = sorted(list(enumerate(similarity[idx])), key=lambda x: x[1], reverse=True)
63
-
64
- # En yakın 5 film (kendisi hariç)
65
- top_indices = [i[0] for i in sim_scores[1:6]]
66
- top_scores = [i[1] for i in sim_scores[1:6]]
67
-
68
- recs = df.iloc[top_indices].copy()
69
- recs['Score'] = top_scores
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
- # Grafik Çizimi
72
- fig = px.bar(recs, x='Score', y='title', orientation='h',
73
- color='Score', color_continuous_scale='Reds',
74
- template="plotly_dark", title="Benzerlik Puanları")
75
- st.plotly_chart(fig, use_container_width=True)
76
 
77
- # Film Kartları
78
- st.write("### 🍿 Sizin İçin Öneriler")
79
- cols = st.columns(5)
80
- for i, col in enumerate(cols):
81
- with col:
82
- row = recs.iloc[i]
83
- st.markdown(f"""
84
- <div class="movie-card">
85
- <h4>{row['title']}</h4>
86
- <p style="font-size: 11px; color: #aaa;">{row['listed_in']}</p>
87
- <hr style="border-color: #333;">
88
- <p style="font-size: 11px;">{row['description'][:140]}...</p>
89
- <div class="match-tag">%{int(row['Score']*100)} Benzerlik</div>
90
- </div>
91
- """, unsafe_allow_html=True)
92
- except Exception as e:
93
- st.error(f"Analiz sırasında bir hata oluştu: {e}")
94
 
95
- elif df == "csv_error":
96
- st.error("⚠️ 'netflix_titles.csv' dosyası bulunamadı! Lütfen Files sekmesinden bu dosyayı yükleyin.")
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  else:
98
- st.error(f"⚠️ Hata oluştu: {df}")
 
4
  import plotly.express as px
5
  import os
6
 
7
+ # 1. Sayfa Ayarları
8
+ st.set_page_config(page_title="Movie Recommender AI", layout="wide")
9
 
10
+ # 2. Şık Görsel Stil (CSS) - Senin beğendiğin tam tasarım
11
  st.markdown("""
12
  <style>
13
+ .stApp { background-color: #141414; color: white; }
14
+ .stButton>button {
15
+ width: 100%;
16
+ background-color: #333333;
17
+ color: white;
18
+ font-weight: bold;
19
+ border: 1px solid #555;
20
+ border-radius: 5px;
21
+ height: 3em;
22
+ }
23
+ .stButton>button:hover { background-color: #e50914; border: 1px solid #e50914; color: white; }
24
+ .stSelectbox label { color: white !important; font-size: 16px !important; }
25
  .movie-card {
26
+ background-color: #262730;
27
+ padding: 20px;
28
+ border-radius: 10px;
29
+ border-top: 5px solid #e50914;
30
+ height: 520px;
31
+ margin-bottom: 20px;
32
  }
33
+ h1, h2, h3, h4, p, span { color: white !important; }
34
  .match-tag {
35
+ background-color: #e50914;
36
+ color: white;
37
+ text-align: center;
38
+ border-radius: 5px;
39
+ padding: 5px;
40
+ font-size: 14px;
41
+ font-weight: bold;
42
+ margin-top: 10px;
43
  }
 
44
  </style>
45
  """, unsafe_allow_html=True)
46
 
47
+ # 3. Veri ve Model Yükleme (Hugging Face / Xet uyumlu)
48
  @st.cache_resource
49
+ def load_assets():
50
  try:
51
+ # Dosya kontrolü
52
  if not os.path.exists('netflix_titles.csv'):
53
+ return None, None, None
54
+
55
+ df = pd.read_csv('netflix_titles.csv')
 
56
 
 
57
  with open('similarity.pkl', 'rb') as f:
58
  similarity = pickle.load(f)
59
+
60
  with open('indices.pkl', 'rb') as f:
61
  indices = pickle.load(f)
62
 
63
  return df, similarity, indices
64
  except Exception as e:
65
+ st.error(f"Yükleme hatası: {e}")
66
+ return None, None, None
67
 
68
+ df, similarity, indices = load_assets()
69
 
70
+ # Türkçe Çeviri Simülasyonu
71
+ def get_turkish_desc(text):
72
+ return f"Bu yapım genel olarak şunu konu almaktadır: {text[:100]}..."
 
 
73
 
74
+ # Uygulama Başlangıcı
75
+ if df is not None:
76
+ st.title("🎬 Movie Recommendation System / Film Öneri Sistemi")
77
+ st.write("---")
78
 
79
+ col_left, col_main = st.columns([1.5, 3])
80
+
81
+ # --- SOL TARAF: ÖRNEKLER ---
82
+ with col_left:
83
+ st.subheader("💡 Suggestions / Örnekler")
84
+ samples = [
85
+ ("Kota Factory", "Eğitim"), ("Ganglands", "Aksiyon"),
86
+ ("Midnight Mass", "Korku"), ("Squid Game", "Gerilim"),
87
+ ("The Witcher", "Fantastik"), ("Peaky Blinders", "Dram"),
88
+ ("Dark", "Gizem"), ("Lucifer", "Suç")
89
+ ]
90
+
91
+ for i in range(0, len(samples), 2):
92
+ c1, c2 = st.columns(2)
93
+ with c1:
94
+ if st.button(samples[i][0], key=f"btn_{samples[i][0]}"):
95
+ st.session_state.selected_movie = samples[i][0]
96
+ st.caption(f"({samples[i][1]})")
97
+ with c2:
98
+ if i+1 < len(samples):
99
+ if st.button(samples[i+1][0], key=f"btn_{samples[i+1][0]}"):
100
+ st.session_state.selected_movie = samples[i+1][0]
101
+ st.caption(f"({samples[i+1][1]})")
102
+
103
+ st.markdown("""
104
+ <div style="background-color: #1c1c1c; padding: 15px; border-radius: 8px; border: 1px solid #444; margin-top: 25px;">
105
+ <p style="font-size:14px; margin:0; color: #ddd !important;">
106
+ <b>İpucu:</b> Beğendiğiniz bir filmi sağdaki listeden seçebilir veya ismini yazarak aratabilirsiniz.
107
+ </p>
108
+ </div>
109
+ """, unsafe_allow_html=True)
110
+
111
+ # --- SAĞ TARAF: ANALİZ VE SEÇİM ---
112
+ with col_main:
113
+ df['display_name'] = df['title'] + " (" + df['listed_in'] + ")"
114
+
115
+ # Seçim kutusunda varsayılan değer kontrolü
116
+ default_index = 0
117
+ if 'selected_movie' in st.session_state:
118
+ try:
119
+ default_index = list(df['title']).index(st.session_state.selected_movie)
120
+ except:
121
+ default_index = 0
122
+
123
+ selected_display = st.selectbox(
124
+ "Bir Film veya Dizi Seçin / Select a Movie or TV Show:",
125
+ df['display_name'].values,
126
+ index=default_index
127
+ )
128
+ selected_movie = selected_display.split(" (")[0]
129
+ process_btn = st.button('ÖNERİLERİ ANALİZ ET VE GETİR / ANALYZE')
130
+
131
+ # --- ANALİZ SONUÇLARI ---
132
+ if process_btn:
133
+ idx = indices[selected_movie]
134
+ sim_scores = sorted(list(enumerate(similarity[idx])), key=lambda x: x[1], reverse=True)
135
+
136
+ top_indices = [i[0] for i in sim_scores[1:6]]
137
+ top_scores = [i[1] for i in sim_scores[1:6]]
138
+
139
+ recs = df.iloc[top_indices].copy()
140
+ recs['Score'] = top_scores
141
 
142
+ st.subheader("📊 Benzerlik Oranları / Similarity Analysis")
143
+ fig = px.bar(recs, x='Score', y='title', orientation='h', color='Score',
144
+ color_continuous_scale='Reds', template="plotly_dark", height=300)
145
+ fig.update_layout(yaxis={'categoryorder':'total ascending'})
146
+ st.plotly_chart(fig, use_container_width=True)
147
 
148
+ st.write("---")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
 
150
+ st.subheader("Tavsiye Edilen Yapımlar / Recommendations")
151
+ cols = st.columns(5)
152
+ for i, col in enumerate(cols):
153
+ with col:
154
+ row = recs.iloc[i]
155
+ st.markdown(f"""
156
+ <div class="movie-card">
157
+ <h4 style="color: #e50914; font-size: 16px; margin-bottom: 2px;">{row['title']}</h4>
158
+ <p style="font-size: 11px; color: #aaa !important;">{row['listed_in']}</p>
159
+ <hr style="border-color: #444; margin: 10px 0;">
160
+ <p style="font-size: 12px; color: white !important;"><b>🇬🇧 Summary:</b><br>{row['description'][:60]}...</p>
161
+ <p style="font-size: 12px; color: #ffcc00 !important;"><b>🇹🇷 Özet:</b><br>{get_turkish_desc(row['description'])}</p>
162
+ <div class="match-tag">%{int(row['Score']*100)} Match</div>
163
+ </div>
164
+ """, unsafe_allow_html=True)
165
  else:
166
+ st.error("Dosyalar yüklenemedi! 'netflix_titles.csv', 'similarity.pkl' ve 'indices.pkl' dosyalarını kontrol edin.")