File size: 1,998 Bytes
d6c005e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
63
64
65
66
67
68
69
70
71
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.")


# ── Cosine Similarity ──────────────────────────────────────────────────────

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))


# ── Main Entry Point ───────────────────────────────────────────────────────

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