Комментарии (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]
Выводы
Плохая энтропия проявляется как:
- Крайний дисбаланс классов — низкая энтропия целевой переменной
- Высокая размерность — слишком много классов, мало данных
- Утечка данных — целевая переменная скрыта в признаках
- Шумовые признаки — высокая энтропия модели при низкой полезности
- Несогласованность между обучением и боевыми данными — энтропии разные
Хорошая энтропия означает, что информация в данных хорошо используется моделью, а не теряется на случайном шуме.