| import numpy as np |
| from itertools import combinations |
| from sentence_transformers import SentenceTransformer |
|
|
|
|
| embedding_model = None |
|
|
| def load_embedding_model(): |
| |
| global embedding_model |
|
|
| if embedding_model is not None: |
| return |
|
|
| print("Loading sentence transformer model...") |
| embedding_model = SentenceTransformer('all-MiniLM-L6-v2') |
| print("Embedding model loaded.") |
|
|
|
|
| |
|
|
| def cosine_similarity(vec_a: np.ndarray, vec_b: np.ndarray) -> float: |
| |
| dot_product = np.dot(vec_a, vec_b) |
| magnitude = np.linalg.norm(vec_a) * np.linalg.norm(vec_b) |
|
|
| if magnitude == 0: |
| return 0.0 |
|
|
| score = dot_product / magnitude |
|
|
| return float(np.clip(score, 0.0, 1.0)) |
|
|
|
|
| |
|
|
| async def compute_similarity(texts: dict) -> list[dict]: |
| |
| load_embedding_model() |
|
|
| valid_texts = { |
| strategy: text |
| for strategy, text in texts.items() |
| if text and isinstance(text, str) and text.strip() |
| } |
|
|
| if len(valid_texts) < 2: |
| |
| return [] |
|
|
| strategies = list(valid_texts.keys()) |
| text_list = list(valid_texts.values()) |
|
|
| print(f"Embedding {len(text_list)} texts...") |
| embeddings = embedding_model.encode(text_list, convert_to_numpy=True) |
| print("Embeddings computed.") |
|
|
| scores = [] |
|
|
| for i, j in combinations(range(len(strategies)), 2): |
| score = cosine_similarity(embeddings[i], embeddings[j]) |
|
|
| scores.append({ |
| "strategy_a": strategies[i], |
| "strategy_b": strategies[j], |
| "score": round(score, 4), |
| }) |
|
|
| scores.sort(key=lambda x: x["score"], reverse=True) |
|
|
| return scores |