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

Приведи пример плохой энтропии

1.0 Junior🔥 171 комментариев
#Другое

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

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

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

Энтропия в контексте информационной теории и машинного обучения

Что такое энтропия

Определение Энтропия (Shannon Entropy) измеряет неопределённость или количество информации в системе. Формула:

H(X) = -Σ P(x_i) * log2(P(x_i))

где P(x_i) — вероятность события x_i.

Примеры плохой энтропии

Пример 1: Крайне несбалансированный датасет (очень низкая энтропия)

import numpy as np
from scipy.stats import entropy

# Датасет с классом 99% нулей и 1% единиц (типичная fraud detection)
labels = np.array([0] * 9900 + [1] * 100)

# Вероятности
p_0 = 0.99
p_1 = 0.01

# Энтропия
H = -p_0 * np.log2(p_0) - p_1 * np.log2(p_1)
print(f"Энтропия: {H:.4f}")  # ~0.0081 (очень низкая!)

# Проблема:
# Модель может достичь 99% accuracy, просто всегда предсказывая 0
# Это плохая энтропия, потому что мало информации о классе 1

Почему это плохо:

  • Классификатор может получить 99% accuracy, всегда предсказывая класс 0
  • Метрики accuracy становятся бесполезными
  • Нужны другие метрики: F1-score, precision, recall, ROC-AUC

Решение:

from sklearn.metrics import f1_score, roc_auc_score, precision_recall_curve

# Вместо accuracy
y_true = labels
y_pred = np.zeros_like(labels)  # Наивный классификатор

# Правильные метрики
f1 = f1_score(y_true, y_pred)           # 0.0 (плохо!)
auc = roc_auc_score(y_true, y_pred)     # 0.5 (как монета)

Пример 2: Слишком высокая энтропия (все классы равновероятны)

# Датасет с 1000 классами, каждый встречается 1 раз
# Каждый класс имеет вероятность P(i) = 1/1000 = 0.001

n_classes = 1000
probabilities = np.ones(n_classes) / n_classes

H = -np.sum(probabilities * np.log2(probabilities))
print(f"Энтропия: {H:.2f}")  # 9.97 (максимальная!)

# Проблема:
# Настолько много классов, что предсказать что-либо сложно
# Базовая гипотеза "random guessing" дает 0.1% accuracy
# Переобучение не поможет из-за разреженности данных

Почему это плохо:

  • Слишком высокая сложность задачи (1000 классов из 1 примера каждый)
  • Модель не может выучить паттерны
  • Данных недостаточно для такого количества классов

Решение:

# Сегментировать классы или использовать иерархическую классификацию
# Вместо 1000 независимых классов: жанр → поджанр → конкретный класс

Пример 3: Утечка данных — энтропия целевой переменной в фиче

import pandas as pd

# Плохой сценарий: целевая переменная явно содержится в фиче
df = pd.DataFrame({
    'user_id': [1, 2, 3, 4, 5],
    'is_churn': [1, 0, 1, 0, 1],
    'churn_flag': [1, 0, 1, 0, 1]  # Копия целевой переменной!
})

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score

X = df[['churn_flag']]
y = df['is_churn']

model = RandomForestClassifier()
scores = cross_val_score(model, X, y, cv=5)
print(f"Accuracy: {scores.mean():.2f}")  # 1.0 (ИДЕАЛЬНО, но НЕНАСТОЯЩЕЕ!)

# Проблема:
# - На реальных данных модель упадёт, потому что фича на самом деле не существует
# - Высокая энтропия на обучении маскирует плохую энтропию на валидации
# - Это классический случай overfitting из-за утечки данных

Почему это плохо:

  • Энтропия модели на обучении искусственно низкая
  • На боевых данных модель упадёт
  • Трудно обнаружить такую ошибку без внимательного анализа

Пример 4: Случайные признаки (высокая энтропия модели)

# Датасет с настоящими признаками и случайным шумом
np.random.seed(42)

X = np.random.randn(1000, 10)  # 10 реальных признаков
noise_features = np.random.randn(1000, 90)  # 90 случайных шумовых признаков

X_combined = np.hstack([X, noise_features])

y = (X[:, 0] + X[:, 1] > 0).astype(int)  # Только первые 2 признака важны

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score

model = RandomForestClassifier(n_estimators=100, random_state=42)

# На обучающем наборе
train_score = cross_val_score(model, X_combined, y, cv=5).mean()
print(f"Train accuracy: {train_score:.3f}")  # ~0.95

# На тестовом наборе с чистыми признаками
X_test = np.random.randn(200, 10)
y_test = (X_test[:, 0] + X_test[:, 1] > 0).astype(int)

test_score = model.score(X_test, y_test)
print(f"Test accuracy: {test_score:.3f}")  # ~0.55 (очень плохо!)

# Проблема:
# Модель переобучилась на шумовых признаках
# Энтропия на обучении низкая, но на тестовых данных высокая

Почему это плохо:

  • Модель учится на случайном шуме
  • Высокая вариантность предсказаний на новых данных
  • Плохая обобщаемость

Практический пример: Клиент банка

# Реальный сценарий: предсказание дефолта

# Плохая энтропия:
# - 99.5% клиентов платят, 0.5% дефолтят
# - Наивный классификатор: всегда "платит" → 99.5% accuracy
# - Банк теряет на обнаружении дефолтов

# Хорошая энтропия:
# - Балансируем классы через SMOTE или взвешивание
# - Используем F1-score, precision-recall

from imblearn.over_sampling import SMOTE

X_resampled, y_resampled = SMOTE().fit_resample(X, y)

# Теперь классы более сбалансированы
print(f"До: {np.bincount(y)}")  # [9950, 50]
print(f"После: {np.bincount(y_resampled)}")  # [9950, 9950]

Выводы

Плохая энтропия проявляется как:

  1. Крайний дисбаланс классов — низкая энтропия целевой переменной
  2. Высокая размерность — слишком много классов, мало данных
  3. Утечка данных — целевая переменная скрыта в признаках
  4. Шумовые признаки — высокая энтропия модели при низкой полезности
  5. Несогласованность между обучением и боевыми данными — энтропии разные

Хорошая энтропия означает, что информация в данных хорошо используется моделью, а не теряется на случайном шуме.