File size: 1,779 Bytes
3a81580
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity


def evaluasi_pilar_1(motion: str, paragraph_list: list[str], embedding_model) -> dict:
    """

    Mengevaluasi kepadatan semantik dan kedekatan argumen terhadap mosi.

    Menghasilkan skor relevansi mosi dan kekompakan argumen internal.

    """
    clean_paragraphs = [p.strip() for p in paragraph_list if p and len(p.strip()) > 10]
    if not clean_paragraphs:
        return {"skor": 0.0, "status": "Tidak ada paragraf valid", "detail": {}}

    motion_vector = embedding_model.encode(motion, normalize_embeddings=True).reshape(1, -1)
    paragraph_vectors = embedding_model.encode(clean_paragraphs, normalize_embeddings=True)

    similarity_per_paragraph = cosine_similarity(paragraph_vectors, motion_vector).flatten()
    raw_similarity = float(np.mean(similarity_per_paragraph))

    speech_centroid = np.mean(paragraph_vectors, axis=0, keepdims=True)
    similarity_to_centroid = cosine_similarity(paragraph_vectors, speech_centroid).flatten()
    internal_density = float(np.mean(similarity_to_centroid))

    motion_relevance_score = float(np.clip((raw_similarity - 0.15) / (0.48 - 0.15), 0.0, 1.0)) * 100.0
    density_score = float(np.clip((internal_density - 0.35) / (0.75 - 0.35), 0.0, 1.0)) * 100.0

    final_score = (0.60 * motion_relevance_score) + (0.40 * density_score)

    return {
        "skor": round(float(final_score), 2),
        "detail": {
            "rata_rata_kemiripan_mosi_raw": round(raw_similarity, 4),
            "kepadatan_centroid_internal": round(internal_density, 4),
            "skor_relevansi_mosi_terkalibrasi": round(motion_relevance_score, 2),
            "skor_fokus_centroid": round(density_score, 2)
        }
    }