Как обучить модель предсказывать распределение, а не одно число?

«Как обучить модель предсказывать распределение, а не одно число?» — вопрос из категории Классическое ML, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для предсказания полного распределения вместо точечной оценки я использовал несколько подходов в зависимости от задачи:

  1. Квантильная регрессия (например, с Gradient Boosting) для получения доверительных интервалов:

    from sklearn.ensemble import GradientBoostingRegressor
    
    # Обучаем отдельные модели для разных квантилей
    quantiles = [0.05, 0.25, 0.5, 0.75, 0.95]
    models = {}
    for q in quantiles:
        model = GradientBoostingRegressor(loss='quantile', alpha=q, n_estimators=100)
        model.fit(X_train, y_train)
        models[q] = model
    
    # Предсказание: для каждого объекта получаем 5 квантилей
    predictions = {q: models[q].predict(X_test) for q in quantiles}
  2. Модели, предсказывающие параметры распределения (Probabilistic Forecasting). Например, в задаче прогнозирования спроса я применял:

    • Gaussian Process Regression (через sklearn.gaussian_process) — модель предсказывает среднее и дисперсию нормального распределения.
    • Bayesian Neural Networks (Pyro/PyMC3) — получаем апостериорное распределение весов, что даёт распределение предсказаний.
  3. Генеративные модели для сложных непараметрических распределений:

    • Conditional Variational Autoencoder (CVAE) — обучал для генерации возможных сценариев временных рядов.
    • Normalizing Flows (через nflows или Pyro) — для моделирования сложных многомодальных распределений.

Критерии оценки: Для сравнения таких моделей я использовал Continuous Ranked Probability Score (CRPS) — он измеряет расстояние между предсказанным и истинным распределением. Также проверял покрытие доверительных интервалов (например, 90% интервал должен содержать ~90% истинных значений).