import gradio as gr import os import pickle import numpy as np from surprise import SVDpp from sklearn.metrics.pairwise import cosine_similarity # --- Download Model from Kaggle --- def download_kaggle_model(): kaggle_username = os.environ.get("KAGGLE_USERNAME") kaggle_key = os.environ.get("KAGGLE_KEY") if not kaggle_username or not kaggle_key: raise ValueError("Set KAGGLE_USERNAME and KAGGLE_KEY as HF secrets!") os.system("mkdir -p ~/.kaggle") with open("/root/.kaggle/kaggle.json", "w") as f: f.write(f'{{"username":"{kaggle_username}","key":"{kaggle_key}"}}') os.chmod("/root/.kaggle/kaggle.json", 0o600) # Download your Kaggle model print("📥 Downloading model from Kaggle...") os.system("kaggle datasets download -d / -p ./model --unzip") # --- Load Models --- def load_models(): with open("./model/svdpp_model.pkl", "rb") as f: svdpp_model = pickle.load(f) with open("./model/content_features.pkl", "rb") as f: content_features = pickle.load(f) with open("./model/mappings.pkl", "rb") as f: mappings = pickle.load(f) return svdpp_model, content_features, mappings # --- Hybrid Prediction --- def hybrid_predict(user_id, book_id, alpha=0.7): try: uid = user_encoder.transform([user_id])[0] iid = item_encoder.transform([book_id])[0] except: return "Unknown user_id or book_id" svd_pred = svdpp_model.predict(uid, iid).est user_liked = np.where(svdpp_model.trainset.ur[uid])[0] if len(user_liked) == 0: content_score = 0 else: similarities = cosine_similarity(content_features[iid], content_features[user_liked]) content_score = np.mean(similarities) hybrid_score = alpha * svd_pred + (1 - alpha) * content_score * 5 return round(hybrid_score, 2) # --- Gradio Interface --- def recommend(user_id, book_id, alpha=0.7): return f"Predicted Rating: {hybrid_predict(user_id, book_id, alpha)}" # Download model from Kaggle and load download_kaggle_model() svdpp_model, content_features, mappings = load_models() user_encoder = mappings["user_encoder"] item_encoder = mappings["item_encoder"] # Start Gradio app demo = gr.Interface( fn=recommend, inputs=[ gr.Textbox(label="User ID"), gr.Textbox(label="Book ID"), gr.Slider(0, 1, value=0.7, step=0.1, label="Hybrid Weight (alpha)") ], outputs="text", title="📚 Hybrid Book Recommender", description="Enter a user_id and book_id to get a predicted rating using a Hybrid SVD++ and Content-based model." ) demo.launch()