Улучшен алгоритм расчета score: использование топ-k вместо среднего для большей чувствительности
This commit is contained in:
@@ -244,9 +244,9 @@ class VectorStore:
|
|||||||
Рассчитывает скор на основе сходства с примерами.
|
Рассчитывает скор на основе сходства с примерами.
|
||||||
|
|
||||||
Алгоритм:
|
Алгоритм:
|
||||||
1. Вычисляем среднее косинусное сходство с положительными примерами
|
1. Вычисляем косинусное сходство со всеми примерами
|
||||||
2. Вычисляем среднее косинусное сходство с отрицательными примерами
|
2. Используем топ-k ближайших примеров для более чувствительной оценки
|
||||||
3. Финальный скор = pos_sim / (pos_sim + neg_sim + eps)
|
3. Сравниваем топ-k положительных с топ-k отрицательными
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
vector: Векторное представление нового поста
|
vector: Векторное представление нового поста
|
||||||
@@ -275,28 +275,47 @@ class VectorStore:
|
|||||||
# Косинусное сходство с положительными примерами
|
# Косинусное сходство с положительными примерами
|
||||||
# Для нормализованных векторов это просто скалярное произведение
|
# Для нормализованных векторов это просто скалярное произведение
|
||||||
pos_similarities = np.dot(pos_matrix, normalized)
|
pos_similarities = np.dot(pos_matrix, normalized)
|
||||||
pos_sim = float(np.mean(pos_similarities))
|
|
||||||
|
|
||||||
# Косинусное сходство с отрицательными примерами
|
# Косинусное сходство с отрицательными примерами
|
||||||
if self.negative_count > 0:
|
if self.negative_count > 0:
|
||||||
neg_matrix = np.array(self._negative_vectors)
|
neg_matrix = np.array(self._negative_vectors)
|
||||||
neg_similarities = np.dot(neg_matrix, normalized)
|
neg_similarities = np.dot(neg_matrix, normalized)
|
||||||
neg_sim = float(np.mean(neg_similarities))
|
else:
|
||||||
|
neg_similarities = np.array([])
|
||||||
|
|
||||||
|
# Используем топ-k ближайших примеров для более чувствительной оценки
|
||||||
|
# k выбирается динамически: минимум 10, но не больше 20% от общего количества
|
||||||
|
k_pos = min(max(10, self.positive_count // 10), 50)
|
||||||
|
k_pos = min(k_pos, len(pos_similarities))
|
||||||
|
|
||||||
|
# Топ-k положительных примеров
|
||||||
|
top_k_pos_sim = float(np.mean(np.sort(pos_similarities)[-k_pos:]))
|
||||||
|
|
||||||
|
# Для отрицательных: если их меньше k, берем все, иначе топ-k
|
||||||
|
if len(neg_similarities) > 0:
|
||||||
|
k_neg = min(max(10, self.negative_count // 10), 50)
|
||||||
|
k_neg = min(k_neg, len(neg_similarities))
|
||||||
|
top_k_neg_sim = float(np.mean(np.sort(neg_similarities)[-k_neg:]))
|
||||||
else:
|
else:
|
||||||
# Если нет отрицательных примеров, используем нейтральное значение
|
# Если нет отрицательных примеров, используем нейтральное значение
|
||||||
neg_sim = pos_sim # Нейтральный скор = 0.5
|
top_k_neg_sim = top_k_pos_sim # Нейтральный скор = 0.5
|
||||||
|
|
||||||
# === Вариант 1: neg/pos (разница между положительными и отрицательными) ===
|
# === Вариант 1: neg/pos (разница между топ-k положительными и отрицательными) ===
|
||||||
diff = pos_sim - neg_sim
|
# Используем более агрессивную нормализацию для малых различий
|
||||||
score_neg_pos = 0.5 + (diff * self.score_multiplier)
|
diff = top_k_pos_sim - top_k_neg_sim
|
||||||
|
|
||||||
|
# Адаптивный множитель: чем больше примеров, тем выше чувствительность
|
||||||
|
adaptive_multiplier = self.score_multiplier * (1.0 + min(1.0, (self.positive_count + self.negative_count) / 1000))
|
||||||
|
|
||||||
|
score_neg_pos = 0.5 + (diff * adaptive_multiplier)
|
||||||
score_neg_pos = max(0.0, min(1.0, score_neg_pos))
|
score_neg_pos = max(0.0, min(1.0, score_neg_pos))
|
||||||
|
|
||||||
# === Вариант 2: pos only (только положительные, топ-k ближайших) ===
|
# === Вариант 2: pos only (только положительные, топ-k ближайших) ===
|
||||||
# Берём топ-5 ближайших положительных примеров
|
# Берём топ-5 ближайших положительных примеров
|
||||||
top_k = min(5, len(pos_similarities))
|
top_5_k = min(5, len(pos_similarities))
|
||||||
top_k_sim = float(np.mean(np.sort(pos_similarities)[-top_k:]))
|
top_5_sim = float(np.mean(np.sort(pos_similarities)[-top_5_k:]))
|
||||||
# Нормализуем: 0.85 -> 0.0, 0.95 -> 1.0 (типичный диапазон для BERT)
|
# Нормализуем: 0.85 -> 0.0, 0.95 -> 1.0 (типичный диапазон для BERT)
|
||||||
score_pos_only = (top_k_sim - 0.85) / 0.10
|
score_pos_only = (top_5_sim - 0.85) / 0.10
|
||||||
score_pos_only = max(0.0, min(1.0, score_pos_only))
|
score_pos_only = max(0.0, min(1.0, score_pos_only))
|
||||||
|
|
||||||
# Основной скор — neg/pos
|
# Основной скор — neg/pos
|
||||||
@@ -306,10 +325,27 @@ class VectorStore:
|
|||||||
total_examples = self.positive_count + self.negative_count
|
total_examples = self.positive_count + self.negative_count
|
||||||
confidence = min(1.0, total_examples / 1000)
|
confidence = min(1.0, total_examples / 1000)
|
||||||
|
|
||||||
|
# Дополнительная диагностическая информация
|
||||||
|
pos_mean = float(np.mean(pos_similarities))
|
||||||
|
pos_std = float(np.std(pos_similarities))
|
||||||
|
pos_min = float(np.min(pos_similarities))
|
||||||
|
pos_max = float(np.max(pos_similarities))
|
||||||
|
|
||||||
|
if len(neg_similarities) > 0:
|
||||||
|
neg_mean = float(np.mean(neg_similarities))
|
||||||
|
neg_std = float(np.std(neg_similarities))
|
||||||
|
neg_min = float(np.min(neg_similarities))
|
||||||
|
neg_max = float(np.max(neg_similarities))
|
||||||
|
else:
|
||||||
|
neg_mean = neg_std = neg_min = neg_max = 0.0
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"VectorStore: pos_sim={pos_sim:.4f}, neg_sim={neg_sim:.4f}, "
|
f"VectorStore: top_k_pos={k_pos}, top_k_neg={k_neg if len(neg_similarities) > 0 else 0}, "
|
||||||
f"top_k_sim={top_k_sim:.4f}, score_neg_pos={score_neg_pos:.4f}, "
|
f"top_k_pos_sim={top_k_pos_sim:.4f}, top_k_neg_sim={top_k_neg_sim:.4f}, "
|
||||||
f"score_pos_only={score_pos_only:.4f}"
|
f"diff={diff:.4f}, adaptive_mult={adaptive_multiplier:.2f}, "
|
||||||
|
f"score_neg_pos={score_neg_pos:.4f}, score_pos_only={score_pos_only:.4f}, "
|
||||||
|
f"pos_mean={pos_mean:.4f}±{pos_std:.4f}[{pos_min:.4f}-{pos_max:.4f}], "
|
||||||
|
f"neg_mean={neg_mean:.4f}±{neg_std:.4f}[{neg_min:.4f}-{neg_max:.4f}]"
|
||||||
)
|
)
|
||||||
|
|
||||||
return score, confidence, score_pos_only
|
return score, confidence, score_pos_only
|
||||||
|
|||||||
Reference in New Issue
Block a user