Spaces:
Sleeping
Sleeping
File size: 4,646 Bytes
a08a8a1 456294b f79661f 456294b aadcdbf f79661f 31ac050 f79661f 456294b 4c57269 f79661f a08a8a1 5b1d7f6 f79661f a08a8a1 4c57269 a08a8a1 4c57269 a08a8a1 4c57269 f79661f a08a8a1 31ac050 a08a8a1 4c57269 31ac050 4c57269 a08a8a1 188425d 4c57269 a08a8a1 188425d 4c57269 a08a8a1 31ac050 188425d 31ac050 188425d 31ac050 4c57269 a08a8a1 f79661f a08a8a1 31ac050 f79661f 31ac050 f79661f 4c57269 f79661f 4c57269 f79661f 4c57269 f79661f | 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 166 167 168 | from sklearn.decomposition import TruncatedSVD
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.neighbors import NearestNeighbors
from sklearn.cluster import KMeans
from sklearn.metrics.pairwise import cosine_similarity
import gradio as gr
def custom_similarity_by_index(idx1, idx2):
row1 = df.iloc[idx1]
row2 = df.iloc[idx2]
def to_set(text):
if pd.isna(text):
return set()
return set(text.lower().split())
g1, g2 = to_set(row1["genres"]), to_set(row2["genres"])
k1, k2 = to_set(row1["keywords"]), to_set(row2["keywords"])
genre_sim = len(g1 & g2) / len(g1 | g2) if g1 and g2 else 0
keyword_sim = len(k1 & k2) / len(k1 | k2) if k1 and k2 else 0
d1 = str(row1["director"]).lower()
d2 = str(row2["director"]).lower()
director_sim = 1 if d1 == d2 else 0
return 0.4 * genre_sim + 0.4 * keyword_sim + 0.2 * director_sim
# ------------------ LOAD DATA ------------------
df = pd.read_csv("mov_dataset.csv")
df["title_lower"] = df["title"].str.lower()
tfidf = TfidfVectorizer()
X = tfidf.fit_transform(df["combined_features"])
# ------------------ SVD ------------------
svd = TruncatedSVD(n_components=50, random_state=42)
X_svd = svd.fit_transform(X)
# ------------------ MODELS ------------------
knn = NearestNeighbors(metric='cosine', algorithm='brute')
knn.fit(X_svd)
kmeans = KMeans(n_clusters=10, random_state=42)
clusters = kmeans.fit_predict(X_svd)
cosine_sim = cosine_similarity(X_svd)
# ------------------ RECOMMEND FUNCTION ------------------
def recommend(movie_name, model_type):
movie_name = movie_name.strip().lower()
if not movie_name:
return ["Please enter a movie name"]
if movie_name not in df["title_lower"].values:
return ["Movie not found"]
idx = df[df["title_lower"] == movie_name].index[0]
if model_type == "KNN":
distances, indices = knn.kneighbors([X_svd[idx]], n_neighbors=6)
results = []
for i in indices[0][1:]:
score = custom_similarity_by_index(idx, i)
results.append((df.iloc[i]["title"], score))
return sorted(results, key=lambda x: x[1], reverse=True)
elif model_type == "Cosine":
scores = list(enumerate(cosine_sim[idx]))
scores = sorted(scores, key=lambda x: x[1], reverse=True)
results = []
for i, _ in scores[1:6]:
score = custom_similarity_by_index(idx, i)
results.append((df.iloc[i]["title"], score))
return sorted(results, key=lambda x: x[1], reverse=True)
elif model_type == "KMeans":
cluster_id = clusters[idx]
cluster_indices = [i for i in range(len(df)) if clusters[i] == cluster_id and i != idx]
if not cluster_indices:
return ["No similar movies found"]
results = []
for i in cluster_indices:
score = custom_similarity_by_index(idx, i)
results.append((df.iloc[i]["title"], score))
results = sorted(results, key=lambda x: x[1], reverse=True)
return results[:5]
# ------------------ CARD STYLE OUTPUT ------------------
def recommend_ui(movie, model):
results = recommend(movie, model)
if isinstance(results, list) and isinstance(results[0], str):
return f"❌ {results[0]}"
cards = ""
for i, (title, score) in enumerate(results):
cards += f"""
<div style="
background-color:#1f1f1f;
padding:15px;
margin:10px;
border-radius:10px;
box-shadow:0px 0px 10px rgba(255,0,0,0.3);
">
<h3 style="color:#E50914;">{i+1}. {title}</h3>
<p style="color:white;">⭐ Similarity Score: <b>{score}</b></p>
</div>
"""
return cards
# ------------------ NETFLIX STYLE UI ------------------
css = """
body {
background-color: #141414;
color: white;
}
.gradio-container {
background-color: #141414 !important;
}
h1 {
text-align: center;
color: #E50914;
font-size: 42px;
}
"""
with gr.Blocks(css=css) as demo:
gr.Markdown("# 🎬 Netflix Movie Recommender")
with gr.Row():
movie_input = gr.Textbox(
label="Enter Movie Name",
placeholder="Try: Avatar"
)
model_input = gr.Dropdown(
["KNN", "Cosine", "KMeans"],
value="KNN",
label="Select Model"
)
btn = gr.Button("🔥 Recommend")
output = gr.HTML()
btn.click(fn=recommend_ui, inputs=[movie_input, model_input], outputs=output)
demo.launch() |