Download src/utils/inference.py from dahutapea/Topic-Modeling-Tokopedia-Reviews: direct link, hf CLI and curl.
- Browser
- Download file 1.74 kB
-
https://huggingface.co/spaces/dahutapea/Topic-Modeling-Tokopedia-Reviews/resolve/main/src/utils/inference.py
- Command line
-
hf download hf://spaces/dahutapea/Topic-Modeling-Tokopedia-Reviews/src/utils/inference.py
-
curl -L -o inference.py https://huggingface.co/spaces/dahutapea/Topic-Modeling-Tokopedia-Reviews/resolve/main/src/utils/inference.py
1.74 kB
| """Theme prediction without the full BERTopic stack: embed the review, then cosine-match it | |
| against the exported topic vectors (artifacts/topic_index.*). Pure functions (no Streamlit) so | |
| they can be unit-tested. The heavy model loads once and is cached as a module-level singleton. | |
| """ | |
| import os | |
| import json | |
| import numpy as np | |
| from utils.paths import ARTIFACTS | |
| from utils.preprocess import clean_review | |
| _E = None # normalized topic-vector matrix (n_topics x dim) | |
| _meta = None # list of {topic, theme, sentiment} | |
| _model = None # SentenceTransformer | |
| def _load(): | |
| global _E, _meta, _model | |
| if _model is None: | |
| from sentence_transformers import SentenceTransformer | |
| _E = np.load(os.path.join(ARTIFACTS, "topic_index.npz"))["embeddings"] | |
| cfg = json.load(open(os.path.join(ARTIFACTS, "topic_index.json"), encoding="utf-8")) | |
| _meta = cfg["topics"] | |
| _model = SentenceTransformer(cfg["model_name"]) | |
| return _E, _meta, _model | |
| def predict_theme(text: str, topk: int = 3): | |
| """Return (cleaned_text, [(sentiment, theme, similarity), ...]) ranked best-first. | |
| Similarity is aggregated to theme level (best matching topic per theme).""" | |
| E, meta, model = _load() | |
| cleaned = clean_review(text) | |
| if not cleaned: | |
| return cleaned, [] | |
| q = model.encode([cleaned])[0] | |
| q = q / (np.linalg.norm(q) + 1e-9) | |
| sims = E @ q # cosine (E is pre-normalized) | |
| best = {} | |
| for i, t in enumerate(meta): | |
| key = (t["sentiment"], t["theme"]) | |
| if key not in best or sims[i] > best[key]: | |
| best[key] = float(sims[i]) | |
| ranked = sorted(best.items(), key=lambda kv: -kv[1]) | |
| return cleaned, [(s, th, sim) for (s, th), sim in ranked[:topk]] | |