File size: 2,108 Bytes
3ac1f08
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import re
import gradio as gr
import pandas as pd
import torch
import torch.nn.functional as F
from sentence_transformers import SentenceTransformer

CSV_PATH = "Shopeasy_product_dataset.csv"
EMB_PATH = "embeddings.pt"
MODEL_NAME = "all-mpnet-base-v2"

# Load catalog
data = pd.read_csv(CSV_PATH, low_memory=True)

# Load embeddings (force CPU so it works on Spaces without GPU)
sentence_embeddings = torch.load(EMB_PATH, map_location="cpu").float()

# Normalize embeddings once (so dot product == cosine similarity)
sentence_embeddings = F.normalize(sentence_embeddings, p=2, dim=1)

# Load model (CPU by default; will still work fine)
mpnet_base = SentenceTransformer(MODEL_NAME, device="cpu")

def clean_text(x: str) -> str:
    x = str(x).lower()
    x = re.sub(r"[^A-Za-z0-9]+", " ", x).strip()
    return x

def get_recommendations(query, top_k=10):
    query = clean_text(query)
    if not query:
        return pd.DataFrame(columns=["Rank", "Product Name"])

    query_embedding = mpnet_base.encode(query, convert_to_tensor=True)
    query_embedding = F.normalize(query_embedding, p=2, dim=0)

    # cosine similarity (since both normalized)
    similarity_scores = sentence_embeddings @ query_embedding

    top_k = int(top_k)
    top_scores, top_indices = torch.topk(similarity_scores, k=min(top_k, similarity_scores.shape[0]))
    top_indices = top_indices.cpu().numpy()

    recs = data.iloc[top_indices]["product_name"].reset_index(drop=True)
    out = recs.to_frame(name="Product Name")
    out.insert(0, "Rank", range(1, len(out) + 1))
    return out

with gr.Blocks() as demo:
    gr.Markdown("## 🤖 AI-Powered Product Recommendation")
    gr.Markdown("Enter a query to see the top recommended products (SentenceTransformer embeddings).")

    query = gr.Textbox(label="Query", placeholder="e.g., wireless headphones noise cancelling")
    top_k = gr.Slider(1, 25, value=10, step=1, label="Top K")

    btn = gr.Button("Recommend")
    table = gr.Dataframe(label="Recommendations", interactive=False)

    btn.click(get_recommendations, inputs=[query, top_k], outputs=table)

demo.launch()