Spaces:
Running
Running
File size: 2,195 Bytes
aa16784 |
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 |
import pandas as pd
from sentence_transformers import SentenceTransformer, util
import gradio as gr
# βββ Load catalog & compute embeddings βββββββββββββββββββββββββ
PRODUCTS_CSV = "products.csv"
df = pd.read_csv(PRODUCTS_CSV)
descriptions = df["description"].tolist()
model = SentenceTransformer("sentence-transformers/all-MiniLM-L6-v2")
embeddings = model.encode(descriptions, convert_to_tensor=True, normalize_embeddings=True)
# βββ Semantic-search function βββββββββββββββββββββββββββββββββ
def search_products(query: str, top_k: int = 5):
if not query.strip():
return pd.DataFrame(columns=df.columns.tolist() + ["score"])
q_emb = model.encode(query, convert_to_tensor=True, normalize_embeddings=True)
hits = util.cos_sim(q_emb, embeddings)[0].topk(k=top_k)
indices = hits.indices.cpu().tolist()
scores = [round(float(s), 3) for s in hits.values.cpu().tolist()]
results = df.iloc[indices].copy()
results["score"] = scores
return results.reset_index(drop=True)
# βββ Gradio UI ββββββββββββββββββββββββββββββββββββββββββββββββ
with gr.Blocks(title="ποΈ Salon Catalog Semantic Search") as demo:
gr.Markdown("""
# ποΈ Salon Product Search
**Natural-language queries** β **top matching products** via MiniLM embeddings
(Runs entirely on free CPU; no paid APIs)
""")
with gr.Row():
query_in = gr.Textbox(placeholder="e.g. sulfate-free shampoo under $15", label="Search query")
topk = gr.Slider(1, 10, value=5, step=1, label="Number of results")
search_btn = gr.Button("Search π", variant="primary")
table = gr.Dataframe(
headers=list(df.columns) + ["score"],
datatype=["number","str","str","str","number","number"],
interactive=False,
row_count= topk.value,
label="Results"
)
search_btn.click(search_products, [query_in, topk], table)
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0")
|