Как вы измеряете diversity синтетического датасета?

Краткий тезис

Diversity (разнообразие) синтетического датасета — критическая характеристика, определяющая, насколько хорошо модель, обученная на нём, обобщается на реальные данные. Измерение diversity включает три основных подхода: лексическое разнообразие (Type-Token Ratio, TTR), семантическое разнообразие (среднее попарное расстояние между эмбеддингами) и эмбеддинг-разнообразие (кластеризация эмбеддингов, отношение числа кластеров к числу примеров). Выбор метрики зависит от типа данных (текст, изображения, таблицы) и цели синтеза. Высокий diversity снижает риск переобучения и улучшает робастность модели.


1. Зачем измерять diversity синтетического датасета?

Синтетические датасеты часто страдают от mode collapse — генерации однотипных примеров, которые не покрывают всё пространство признаков реальных данных. Если diversity низкий:

  • Модель запоминает узкие паттерны и плохо обобщается.
  • Оценка качества (accuracy, F1) на синтетическом тесте может быть завышена, а на реальном — провальной.
  • В Agentic RAG синтетические данные используются для fine-tuning ретривера или генератора; низкое разнообразие приводит к тому, что агент не справляется с нестандартными запросами.

Измерение diversity позволяет:

  • Контролировать качество генерации.
  • Сравнивать разные пайплайны синтеза (LLM, rule-based, GAN).
  • Оптимизировать параметры генерации (temperature, top-p, промпты).

2. Типы diversity: лексическое, семантическое, эмбеддинг-разнообразие

ТипЧто измеряетПрименимостьПример метрики
ЛексическоеРазнообразие слов/символовТексты, кодыTTR, MATTR, Hapax Legomena Ratio
СемантическоеРазнообразие смысловЛюбые данные с эмбеддингамиСреднее косинусное расстояние, pairwise distance
Эмбеддинг-разнообразиеСтруктуру кластеров в латентном пространствеВсе типы (текст, изображения, таблицы)Число кластеров / N, Silhouette Score, Davies–Bouldin Index

Каждый тип дополняет друг друга. Например, лексически разнообразный текст может быть семантически однообразным (синонимы одной темы), а семантически разнообразный — лексически бедным (короткие фразы на разные темы).


3. Лексическое разнообразие (Lexical diversity)

3.1 Type-Token Ratio (TTR)

TTR = (количество уникальных слов) / (общее количество слов). Значение от 0 до 1. Чем ближе к 1, тем выше diversity|лексическое разнообразие.

Недостаток TTR зависит от длины текста — в длинных текстах он искусственно занижается, так как служебные слова повторяются.

Улучшенные версии

  • MATTR (Moving Average TTR) — среднее TTR по окнам фиксированной длины.
  • Hapax Legomena Ratio — доля слов, встретившихся ровно один раз.

Пример расчёта TTR на Python

from collections import Counter

def ttr(text: str) -> float:
    tokens = text.lower().split()
    if not tokens:
        return 0.0
    unique = len(set(tokens))
    total = len(tokens)
    return unique / total

sample = "кошка собака кошка птица"
print(ttr(sample))  # 0.75 (3 уникальных / 4 всего)

3.2 Когда использовать лексическое разнообразие?

  • Для текстовых датасетов (вопросы, ответы, диалоги).
  • Для оценки генерации кода (разнообразие идентификаторов, ключевых слов).
  • Не подходит для изображений или табличных данных.

4. Семантическое разнообразие (Semantic diversity)

4.1 Среднее попарное расстояние между эмбеддингами

Идея: преобразовать каждый пример в эмбеддинг (вектор фиксированной размерности) с помощью предобученной модели (например, text-embedding-ada-002, all-MiniLM-L6-v2 для текста; ResNet для изображений). Затем вычислить среднее косинусное расстояние (или евклидово) между всеми парами векторов.

Формула

Semantic Diversity = (2 / (N*(N-1))) * Σ_{i<j} (1 - cos(emb_i, emb_j))

где N — число примеров, cos — косинусное сходство.

Значение от 0 (все векторы одинаковы) до 1 (все ортогональны). На практике редко превышает 0.5–0.7.

Пример кода

from sklearn.metrics.pairwise import cosine_similarity
import numpy as np

def semantic_diversity(embeddings: np.ndarray) -> float:
    # embeddings: (N, D)
    sim_matrix = cosine_similarity(embeddings)
    # убираем диагональ (сравнение с собой)
    np.fill_diagonal(sim_matrix, 0)
    n_pairs = embeddings.shape[0] * (embeddings.shape[0] - 1)
    return 1 - sim_matrix.sum() / n_pairs

# Пример: 100 эмбеддингов размерности 768
embs = np.random.randn(100, 768)
print(semantic_diversity(embs))  # около 0.5–0.6 для случайных

4.2 Преимущества и ограничения

  • Плюсы универсальность (работает для любых данных, которые можно эмбеддировать).
  • Минусы вычислительно дорого при больших N (O(N²)); чувствителен к качеству эмбеддингов; не даёт информации о структуре (например, есть ли изолированные кластеры).

5. Эмбеддинг-разнообразие (Embedding diversity) через кластеризацию

5.1 Отношение числа кластеров к числу примеров

Pipeline

  1. Получить эмбеддинги для всех примеров.
  2. Применить алгоритм кластеризации (например, K-Means или HDBSCAN).
  3. Определить оптимальное число кластеров (k) — либо задать априори, либо использовать Elbow method или Silhouette Score.
  4. Вычислить метрику: cluster_ratio = k / N.

Интерпретация Если cluster_ratio близок к 1 (каждый пример — отдельный кластер) — diversity максимален, но возможен оверфиттинг на шум. Если cluster_ratio мал (например, 0.01) — данные сконцентрированы в нескольких режимах, diversity низкий.

Пример:

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

def cluster_diversity(embeddings: np.ndarray, max_k: int = 20) -> dict:
    best_k = 2
    best_score = -1
    for k in range(2, min(max_k, len(embeddings))):
        km = KMeans(n_clusters=k, random_state=42, n_init=10)
        labels = km.fit_predict(embeddings)
        score = silhouette_score(embeddings, labels)
        if score > best_score:
            best_score = score
            best_k = k
    return {
        "optimal_k": best_k,
        "silhouette": best_score,
        "cluster_ratio": best_k / len(embeddings)
    }

5.2 Дополнительные метрики на основе кластеризации

  • Davies–Bouldin Index — среднее сходство каждого кластера с его наиболее похожим кластером. Чем меньше, тем лучше разделение.
  • Coverage — доля примеров, попавших в кластеры с размером > 1 (игнорируем выбросы). Высокий coverage при большом числе кластеров — признак хорошего diversity.

6. Дополнительные метрики diversity

6.1 Novelty (новизна) и Coverage (покрытие)

Эти метрики часто используются в контексте Agentic RAG, где синтетические данные генерируются для покрытия редких запросов.

  • Novelty — доля примеров, которые не похожи (по эмбеддингу) ни на один пример из обучающего набора реальных данных. Измеряется через расстояние до ближайшего соседа.
  • Coverage — доля «регионов» пространства признаков, покрытых хотя бы одним синтетическим примером. Оценивается через Voronoi-диаграммы или kernel density estimation.

6.2 Intra-cluster vs Inter-cluster diversity

Для датасетов с метками классов (например, синтетические диалоги по темам) полезно разделять:

  • Intra-cluster diversity — разнообразие внутри одного класса (чтобы модель не запомнила один шаблон).
  • Inter-cluster diversity — различие между классами (чтобы классы были разделимы).

Метрики: среднее внутрикластерное расстояние (чем больше, тем лучше) и среднее межкластерное расстояние (чем больше, тем лучше).


7. Инструменты и библиотеки для измерения diversity

БиблиотекаНазначениеПримеры функций
nltkЛексическое разнообразиеnltk.tokenize, FreqDist
scipy.spatial.distanceПопарные расстоянияpdist, squareform
sklearn.metricsКластеризация и метрикиsilhouette_score, davies_bouldin_score
sentence-transformersЭмбеддинги текстаSentenceTransformer.encode()
umap-learnВизуализация кластеровUMAP для 2D-проекции

Пример полного пайплайна для текстового датасета:

from sentence_transformers import SentenceTransformer
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
import numpy as np

model = SentenceTransformer('all-MiniLM-L6-v2')
texts = [...]  # список строк
embeddings = model.encode(texts, show_progress_bar=True)

# 1. Семантическое разнообразие
from scipy.spatial.distance import pdist
pairwise = pdist(embeddings, metric='cosine')
sem_div = np.mean(pairwise)
print(f"Semantic diversity: {sem_div:.3f}")

# 2. Кластерное разнообразие
k_range = range(2, min(50, len(embeddings)))
best_k = 2
best_sil = -1
for k in k_range:
    km = KMeans(n_clusters=k, random_state=42, n_init=10)
    labels = km.fit_predict(embeddings)
    sil = silhouette_score(embeddings, labels)
    if sil > best_sil:
        best_sil = sil
        best_k = k
print(f"Optimal clusters: {best_k}, Silhouette: {best_sil:.3f}")
print(f"Cluster ratio: {best_k / len(embeddings):.3f}")

8. Практические рекомендации

СценарийРекомендуемые метрикиПочему
Синтетические QA-пары для RAGTTR + Semantic diversityВажно лексическое разнообразие вопросов и семантическое покрытие тем
Синтетические диалоги для fine-tuning LLMCluster ratio + NoveltyНужно избежать mode collapse и покрыть редкие сценарии
Синтетические изображения (GAN)FID + Intra-cluster distanceFID измеряет сходство с реальными данными, а внутрикластерное — разнообразие генераций
Табличные данные (CTGAN)Coverage + Pairwise distanceВажно покрытие всех комбинаций признаков

Общее правило используйте как минимум две метрики из разных категорий (лексическая/семантическая/кластерная). Если все метрики показывают высокий diversity, датасет, скорее всего, качественный.


9. Связь с качеством модели

Низкий diversity → модель переобучается на узкие паттерны → падает robustness (робастность) и generalization (обобщение). Высокий diversity, напротив, улучшает:

  • Coverage — модель видит больше вариантов.
  • Calibration — уверенность модели лучше соответствует точности.
  • Fairness — меньше bias к частым паттернам.

Однако чрезмерный diversity (каждый пример уникален) может привести к шуму и затруднить обучение. Оптимум — когда diversity соответствует распределению реальных данных.


Пет-проект для закрепления

Задача Сгенерировать синтетический датасет вопросов по математике с помощью LLM (например, GPT-4o-mini) и измерить его diversity. Сравнить два промпта: один с низкой temperature (0.2), другой с высокой (1.0).

Инструменты

Шаги:

  1. Написать промпт: «Сгенерируй 100 вопросов по математике для школьников 7 класса». Запустить с temperature=0.2 и temperature=1.0.
  2. Для каждого набора вычислить:
  3. Визуализировать эмбеддинги с UMAP, раскрасить по кластерам.
  4. Сделать вывод: какой промпт даёт более разнообразный датасет? Соответствует ли это ожиданиям?

Ожидаемый результат При высокой temperature diversity выше (больше уникальных слов, больше кластеров, выше семантическое расстояние). При низкой temperature вопросы становятся шаблонными (низкий TTR, один-два кластера).


Связь с другими вопросами

ВопросТема
689Генерация синтетических данных для RAG
691Оценка качества синтетического датасета (accuracy, faithfulness)
692Баланс классов в синтетических данных
693Аугментация данных для улучшения diversity
694Фильтрация низкокачественных синтетических примеров
695Оптимальный размер синтетического датасета

Навигация