intentfinder-api / search_path.py
youngryong's picture
deploy: IntentFinder API (HF Docker Space)
21bdc64
Raw
History Blame Contribute Delete
1.88 kB
# ์ž„๋ฒ ๋”ฉ ์ฝ”์‚ฌ์ธ ์œ ์‚ฌ๋„๋กœ ์‹œ๋“œ ์ค‘์‹ฌ์˜ ์ถ”์ • ์—ฐ๊ด€ ๊ฒฝ๋กœ(ํŠธ๋ฆฌํ˜• ๋„คํŠธ์›Œํฌ)๋ฅผ ๋งŒ๋“œ๋Š” ๋ชจ๋“ˆ
import numpy as np
from clusterer import _model
def build_search_path(seed: str, df, embeddings, top_n: int = 12) -> dict:
# df์™€ embeddings๋Š” ๊ฐ™์€ ์ˆœ์„œ๋กœ ์ •๋ ฌ๋ผ ์žˆ์–ด์•ผ ํ•œ๋‹ค (filter_by_relevance ์ถœ๋ ฅ)
# ์‹ค์ œ ์ˆœ์ฐจ ๊ฒ€์ƒ‰ ๋กœ๊ทธ๊ฐ€ ์•„๋‹ˆ๋ผ, ์˜๋ฏธ ์œ ์‚ฌ๋„ ๊ธฐ๋ฐ˜ ์ถ”์ • ์—ฐ๊ฒฐ๋ง์ด๋‹ค.
if len(df) < 2:
return {"nodes": [], "edges": []}
df = df.reset_index(drop=True).copy()
df["total_volume"] = df["search_volume_pc"].fillna(0) + df["search_volume_mobile"].fillna(0)
emb = np.asarray(embeddings)
# ๊ฒ€์ƒ‰๋Ÿ‰ ์ƒ์œ„ ํ‚ค์›Œ๋“œ๋ฅผ ๋…ธ๋“œ ํ›„๋ณด๋กœ (์‹œ๋“œ ์ž์‹ ์€ ์ œ์™ธ)
order = df.sort_values("total_volume", ascending=False)
picked = [i for i in order.index if df.loc[i, "keyword"] != seed][:top_n]
seed_emb = _model().encode([seed], normalize_embeddings=True)[0]
seed_vol = int(df.loc[df["keyword"] == seed, "total_volume"].max()) if (df["keyword"] == seed).any() else None
nodes = [{"id": 0, "keyword": seed, "volume": seed_vol, "depth": 0}]
node_vecs = [seed_emb]
edges = []
# ๊ฐ ํ‚ค์›Œ๋“œ๋ฅผ "์ด๋ฏธ ๋ฐฐ์น˜๋œ ๋…ธ๋“œ ์ค‘ ๊ฐ€์žฅ ์œ ์‚ฌํ•œ ๊ฒƒ"์— ๋ถ™์—ฌ ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“ ๋‹ค
for rank, i in enumerate(picked, start=1):
vec = emb[i]
sims = [float(np.dot(vec, nv)) for nv in node_vecs] # ์ •๊ทœํ™” ์ž„๋ฒ ๋”ฉ โ†’ ๋‚ด์ =์ฝ”์‚ฌ์ธ
parent = int(np.argmax(sims))
nodes.append({
"id": rank,
"keyword": df.loc[i, "keyword"],
"volume": int(df.loc[i, "total_volume"]),
"depth": nodes[parent]["depth"] + 1,
})
node_vecs.append(vec)
edges.append({"source": parent, "target": rank, "relation": round(sims[parent], 3)})
return {"nodes": nodes, "edges": edges}