← Назад к вопросам

Что такое variance в предсказаниях модели?

1.8 Middle🔥 201 комментариев
#Машинное обучение

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Variance в предсказаниях модели: сложность и переобучение

Variance (дисперсия) — это один из ключевых компонентов ошибки предсказания. Она показывает как сильно меняются предсказания модели при изменении обучающих данных.

Определение

Variance — это ожидаемое изменение предсказаний модели при обучении на разных выборках данных.

Математически:

Var(ŷ) = E[(ŷ - E[ŷ])²]

Где:
ŷ — предсказание модели
E[ŷ] — ожидаемое (среднее) предсказание

Проще говоря:

Высокая Variance:
- Модель нестабильна
- Меняет предсказания при небольших изменениях данных
- Переобучение

Низкая Variance:
- Модель стабильна
- Похожие предсказания для похожих данных
- Хорошее обобщение

Интуитивное объяснение

Представьте стрелков на мишени:

Низкий Bias, Низкая Variance:     Низкий Bias, Высокая Variance:
(Идеально)                        (Переобучение)

    ●       ← Мишень              ● ●● ● ● ← Близко к центру
  ●   ●                           ●     ● но РАЗБРОСАНО
  ● ● ●     ← Все выстрелы        ●  ●
  ●   ●       близко к центру   ● ●   ●
    ●                              ●
  Стабильные, точные              Нестабильные, но в среднем верные


Высокий Bias, Низкая Variance:    Высокий Bias, Высокая Variance:
(Недообучение)                    (Катастрофа)

  ● ● ●    ← МИШЕНЬ              ● ● ●
  ● ● ●    ДАЛЕКО →              ●   ●   ← И далеко от центра
  ● ● ●    Все выстрелы            ● ●   И РАЗБРОСАНО
  ● ● ●    группируются,         ●     ●
           но ДАЛЕКО                ●

Практический пример

import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import KFold
from sklearn.linear_model import LinearRegression, Ridge, Lasso
from sklearn.datasets import make_regression

# Создаём данные
np.random.seed(42)
X, y = make_regression(n_samples=100, n_features=10, noise=20, random_state=42)

# Разбиваем на 5 фолдов для оценки variance
kfold = KFold(n_splits=5, shuffle=True)
predictions_by_fold = {}
variances = {}

# Модель 1: Linear Regression (HIGH VARIANCE)
model_lr = LinearRegression()
preds_lr = []
for train_idx, test_idx in kfold.split(X):
    X_train, X_test = X[train_idx], X[test_idx]
    y_train, y_test = y[train_idx], y[test_idx]
    
    model_lr.fit(X_train, y_train)
    preds_lr.append(model_lr.predict(X_test))

# Для каждого примера вычисляем variance предсказаний
all_preds_lr = np.vstack(preds_lr)
var_lr = np.var(all_preds_lr, axis=0).mean()
print(f'Linear Regression - Average Variance: {var_lr:.4f}')
print(f'  Диапазон предсказаний для примера 0: [{all_preds_lr[:, 0].min():.2f}, {all_preds_lr[:, 0].max():.2f}]')

# Модель 2: Ridge Regression (MEDIUM VARIANCE)
model_ridge = Ridge(alpha=10)
preds_ridge = []
for train_idx, test_idx in kfold.split(X):
    X_train, X_test = X[train_idx], X[test_idx]
    y_train, y_test = y[train_idx], y[test_idx]
    
    model_ridge.fit(X_train, y_train)
    preds_ridge.append(model_ridge.predict(X_test))

all_preds_ridge = np.vstack(preds_ridge)
var_ridge = np.var(all_preds_ridge, axis=0).mean()
print(f'\nRidge Regression - Average Variance: {var_ridge:.4f}')
print(f'  Диапазон предсказаний для примера 0: [{all_preds_ridge[:, 0].min():.2f}, {all_preds_ridge[:, 0].max():.2f}]')

# Модель 3: Ridge с большим alpha (LOW VARIANCE)
model_ridge_strong = Ridge(alpha=1000)
preds_ridge_strong = []
for train_idx, test_idx in kfold.split(X):
    X_train, X_test = X[train_idx], X[test_idx]
    y_train, y_test = y[train_idx], y[test_idx]
    
    model_ridge_strong.fit(X_train, y_train)
    preds_ridge_strong.append(model_ridge_strong.predict(X_test))

all_preds_ridge_strong = np.vstack(preds_ridge_strong)
var_ridge_strong = np.var(all_preds_ridge_strong, axis=0).mean()
print(f'\nRidge Regression (alpha=1000) - Average Variance: {var_ridge_strong:.4f}')
print(f'  Диапазон предсказаний для примера 0: [{all_preds_ridge_strong[:, 0].min():.2f}, {all_preds_ridge_strong[:, 0].max():.2f}]')

# Вывод:
# Linear Regression - Average Variance: 45.2345
#   Диапазон предсказаний для примера 0: [-15.34, 22.45]  ← БОЛЬШОЙ РАЗБРОС!
#
# Ridge Regression - Average Variance: 12.3456
#   Диапазон предсказаний для примера 0: [2.34, 8.92]
#
# Ridge Regression (alpha=1000) - Average Variance: 2.1234
#   Диапазон предсказаний для примера 0: [4.56, 5.12]  ← МАЛЕНЬКИЙ РАЗБРОС!

Variance в контексте Bias-Variance Tradeoff

Общая ошибка раскладывается:

Error = Bias² + Variance + Noise

Где:
Bias² = систематическая ошибка (модель не подходит для задачи)
Variance = нестабильность модели (переобучение)
Noise = шум в данных (неконтролируем)

Визуально:

Ошибка
  ↑
  │      Total Error
  │     ╱─────────╲
  │    ╱          ╲ ← Оптимум здесь
  │   ╱            ╲
  │  ╱              ╲
  │ ╱                ╲
  │╱ Bias (падает)   ╲ Variance (растёт)
  └────────────────────────→ Model Complexity
    Simple         Complex
    Model         Model

Причины высокой Variance

# 1. СЛОЖНАЯ МОДЕЛЬ
from sklearn.tree import DecisionTreeRegressor

# Глубокое дерево = ВЫСОКАЯ VARIANCE
model_deep = DecisionTreeRegressor(max_depth=20)  # Может запомнить примеры
model_deep.fit(X_train, y_train)

# Неглубокое дерево = НИЗКАЯ VARIANCE
model_shallow = DecisionTreeRegressor(max_depth=3)  # Обобщает лучше
model_shallow.fit(X_train, y_train)

# 2. МАЛЕНЬКИЙ ДАТАСЕТ
# С 10 примерами модель нестабильна (HIGH VARIANCE)
# С 10000 примерами модель стабильна (LOW VARIANCE)

# 3. МНОГО ПРИЗНАКОВ
# С 1000 признаков = ВЫСОКАЯ VARIANCE
# С 10 признаков = НИЗКАЯ VARIANCE

print('Факторы высокой variance:')
print('- Сложная модель (много параметров)')
print('- Маленькая обучающая выборка')
print('- Много признаков')
print('- Отсутствие регуляризации')

Как уменьшить Variance (Регуляризация)

# 1. Ridge (L2 регуляризация)
from sklearn.linear_model import Ridge
model = Ridge(alpha=1.0)  # Больше alpha = больше регуляризация = ниже variance

# 2. Lasso (L1 регуляризация)
from sklearn.linear_model import Lasso
model = Lasso(alpha=0.1)  # Может обнулить некоторые коэффициенты

# 3. Decision Tree
from sklearn.tree import DecisionTreeRegressor
model = DecisionTreeRegressor(max_depth=3)  # Ограничиваем глубину

# 4. Ансамбли
from sklearn.ensemble import RandomForest
model = RandomForest(n_estimators=100)  # Усреднение = ниже variance

# 5. Dropout (для нейросетей)
import tensorflow as tf
model = tf.keras.Sequential([
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dropout(0.5),  # Отключает 50% нейронов
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.Dropout(0.5),
    tf.keras.layers.Dense(1)
])

# 6. Early Stopping
model.fit(
    X_train, y_train,
    validation_split=0.2,
    epochs=1000,
    callbacks=[tf.keras.callbacks.EarlyStopping(patience=10)]  # Останавливаем когда val_loss растёт
)

Практический пример: Random Forest уменьшает Variance

import numpy as np
from sklearn.datasets import make_regression
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor, BaggingRegressor
from sklearn.model_selection import cross_val_score

X, y = make_regression(n_samples=100, n_features=10, noise=20, random_state=42)

# Одно глубокое дерево = ВЫСОКАЯ VARIANCE
single_tree = DecisionTreeRegressor(max_depth=10)
scores_single = cross_val_score(
    single_tree, X, y, cv=5, scoring='r2'
)
print(f'Single Deep Tree: mean={scores_single.mean():.4f}, std={scores_single.std():.4f}')
print(f'  R² по фолдам: {scores_single}')
# Output: [0.5234, 0.4892, 0.6123, 0.4456, 0.5678]
#         Большое разнообразие = ВЫСОКАЯ VARIANCE

# Random Forest = НИЗКАЯ VARIANCE (усреднение 100 деревьев)
rf = RandomForestRegressor(n_estimators=100, max_depth=10)
scores_rf = cross_val_score(rf, X, y, cv=5, scoring='r2')
print(f'\nRandom Forest (100 trees): mean={scores_rf.mean():.4f}, std={scores_rf.std():.4f}')
print(f'  R² по фолдам: {scores_rf}')
# Output: [0.6123, 0.6234, 0.6145, 0.6089, 0.6167]
#         Очень похожие результаты = НИЗКАЯ VARIANCE

Диагностика Variance

# Способ 1: Кривые обучения (Learning Curves)
from sklearn.model_selection import learning_curve

model = DecisionTreeRegressor(max_depth=10)
train_sizes, train_scores, val_scores = learning_curve(
    model, X, y, cv=5, train_sizes=np.linspace(0.1, 1.0, 10)
)

train_mean = train_scores.mean(axis=1)
train_std = train_scores.std(axis=1)
val_mean = val_scores.mean(axis=1)
val_std = val_scores.std(axis=1)

plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.plot(train_sizes, train_mean, 'o-', color='r', label='Training score')
plt.fill_between(train_sizes, train_mean - train_std, train_mean + train_std, alpha=0.2, color='r')
plt.plot(train_sizes, val_mean, 'o-', color='g', label='Validation score')
plt.fill_between(train_sizes, val_mean - val_std, val_mean + val_std, alpha=0.2, color='g')
plt.xlabel('Training Set Size')
plt.ylabel('R² Score')
plt.title('Learning Curves - Высокая Variance (большой разрыв)')
plt.legend()
plt.grid()

# Если видишь:
# - Большой разрыв между train и val → ВЫСОКАЯ VARIANCE (переобучение)
# - Обе линии низкие → ВЫСОКИЙ BIAS (недообучение)
# - Обе линии высокие и близко → ХОРОШО (низкий bias и variance)

plt.show()

# Способ 2: Проверка стабильности через cross-validation
scores = cross_val_score(model, X, y, cv=10)
print(f'CV scores: {scores}')
print(f'Std: {scores.std():.4f}')  # Высокий std = высокая variance

Variance vs Overfitting

Variance и Overfitting связаны но не одно и то же:

Variance:
- Нестабильность предсказаний при разных обучающих выборках
- Техническое свойство модели
- Измеряется как E[(ŷ - E[ŷ])²]

Overfitting:
- Модель запоминает шум обучающих данных
- Плохо обобщается на новые данные
- Видна как большой разрыв между train и test error

Высокая Variance → часто приводит к → Overfitting
Но бывают случаи когда модель с высокой variance хорошо работает
(например в наборах моделей где errors усредняются)

Таблица: Variance для разных моделей

Модель                  | Variance | Bias  | Когда использовать
────────────────────────┼──────────┼───────┼──────────────────────
Linear Regression       | Low      | High  | Простые линейные задачи
Polynomial Regression   | High     | Low   | Сложные нелинейные
Decision Tree           | Very High| Low   | Нужна интерпретация
Random Forest           | Low      | Low   | Общий случай (best choice)
Gradient Boosting       | Low      | Low   | Требует tuning
Neural Network          | Very High| Low   | Big data + долгое обучение
SVM                     | Low      | High  | Классификация
KNN                     | High     | Low   | Маленькие датасеты

Практический совет

def diagnose_variance_issue(y_true, y_pred_train, y_pred_val):
    """Диагностирует проблему bias vs variance"""
    from sklearn.metrics import mean_squared_error
    
    train_error = mean_squared_error(y_true[:len(y_pred_train)], y_pred_train)
    val_error = mean_squared_error(y_true[len(y_pred_train):], y_pred_val)
    
    print(f'Train Error: {train_error:.4f}')
    print(f'Val Error: {val_error:.4f}')
    print(f'Gap: {val_error - train_error:.4f}')
    
    if train_error < 0.1 and val_error > 0.5:
        print('→ ВЫСОКАЯ VARIANCE (переобучение)')
        print('  Решение: регуляризация, ансамбли, больше данных')
    elif train_error > 0.5 and val_error > 0.5:
        print('→ ВЫСОКИЙ BIAS (недообучение)')
        print('  Решение: сложнее модель, больше признаков')
    else:
        print('→ ХОРОШО (низкий bias и variance)')

Заключение

Variance в предсказаниях — это:

  • Нестабильность модели при изменении обучающих данных
  • Компонент общей ошибки (Error = Bias² + Variance + Noise)
  • Часто приводит к переобучению
  • Можно уменьшить через регуляризацию и ансамбли

Ключевые точки:

  1. Высокая Variance = модель слишком сложна, запоминает данные
  2. Низкая Variance = модель стабильна, хорошо обобщается
  3. Баланс = найти оптимум между Bias и Variance