Nidan / server /utils /active_learning.py
Saivats's picture
feat: initial Nidan environment
e6afd7e
Raw
History Blame Contribute Delete
2.68 kB
from __future__ import annotations
from typing import List
import numpy as np
from sklearn.metrics import roc_auc_score
from sklearn.preprocessing import label_binarize
def compute_binary_auc(
y_true: np.ndarray,
y_scores: np.ndarray,
pos_label: str = None,
classes: List[str] = None,
) -> float:
if len(np.unique(y_true)) < 2:
return 0.5
try:
if len(classes) == 2:
pos = classes[1] if classes else pos_label
binary_true = (y_true == pos).astype(int)
return float(roc_auc_score(binary_true, y_scores[:, 1]))
else:
y_bin = label_binarize(y_true, classes=classes)
return float(
roc_auc_score(y_bin, y_scores, multi_class="ovr", average="macro")
)
except Exception:
return 0.5
def compute_uncertainty_entropy(proba: np.ndarray) -> float:
clipped = np.clip(proba, 1e-10, 1.0)
entropy = -np.sum(clipped * np.log(clipped), axis=1)
max_entropy = np.log(proba.shape[1])
return float(np.mean(entropy / max_entropy)) if max_entropy > 0 else 0.0
def per_sample_uncertainty(proba: np.ndarray) -> np.ndarray:
clipped = np.clip(proba, 1e-10, 1.0)
entropy = -np.sum(clipped * np.log(clipped), axis=1)
max_entropy = np.log(proba.shape[1])
return (entropy / max_entropy) if max_entropy > 0 else entropy
def cosine_similarity_to_set(
embedding: np.ndarray, labeled_embeddings: np.ndarray
) -> float:
if labeled_embeddings.shape[0] == 0:
return 0.0
mean_labeled = labeled_embeddings.mean(axis=0)
norm_emb = np.linalg.norm(embedding)
norm_mean = np.linalg.norm(mean_labeled)
if norm_emb < 1e-10 or norm_mean < 1e-10:
return 0.0
return float(np.dot(embedding, mean_labeled) / (norm_emb * norm_mean))
def per_sample_diversity(
pool_embeddings: np.ndarray, labeled_embeddings: np.ndarray
) -> np.ndarray:
if labeled_embeddings.shape[0] == 0:
return np.ones(pool_embeddings.shape[0])
mean_labeled = labeled_embeddings.mean(axis=0)
pool_norms = np.linalg.norm(pool_embeddings, axis=1, keepdims=True)
mean_norm = np.linalg.norm(mean_labeled)
safe_pool_norms = np.where(pool_norms < 1e-10, 1.0, pool_norms)
safe_mean_norm = mean_norm if mean_norm > 1e-10 else 1.0
cosines = pool_embeddings.dot(mean_labeled) / (
safe_pool_norms.squeeze() * safe_mean_norm
)
return 1.0 - np.clip(cosines, -1.0, 1.0)
def compute_mean_diversity_score(
pool_embeddings: np.ndarray, labeled_embeddings: np.ndarray
) -> float:
scores = per_sample_diversity(pool_embeddings, labeled_embeddings)
return float(np.mean(scores))