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

Расскажи об опыте использования линейных моделей

1.0 Junior🔥 251 комментариев
#Машинное обучение#Опыт и проекты#Статистика и A/B тестирование

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

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

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

Мой опыт использования линейных моделей

Линейные модели — это фундамент машинного обучения, и я использовал их буквально в каждом проекте. Расскажу о реальных кейсах из своей практики.

Кейс 1: Churn prediction в телеком-компании

Контекст:

  • Датасет: 100K клиентов, 50 признаков
  • Цель: предсказать уход клиента в течение месяца
  • Требование: модель должна быть интерпретируемой (compliance)

Почему логистическая регрессия? Когда я применил и XGBoost (AUC=0.89), и логрег (AUC=0.87), бизнес выбрал логистическую регрессию, потому что:

# Логистическая регрессия: интерпретируемость
from sklearn.linear_model import LogisticRegression
import numpy as np

model = LogisticRegression(max_iter=1000, C=0.1)
model.fit(X_train_scaled, y_train)

# Коэффициенты показывают влияние каждого признака
coefficients = pd.DataFrame({
    'Feature': feature_names,
    'Coefficient': model.coef_[0],
    'Abs_Coefficient': np.abs(model.coef_[0])
}).sort_values('Abs_Coefficient', ascending=False)

print(coefficients.head(10))
# Результат:
#                        Feature  Coefficient  Abs_Coefficient
# 0        contract_duration_months      -0.847           0.847
# 1           monthly_charges_usd       0.234           0.234
# 2              customer_age_years      -0.156           0.156
# 3         technical_support_yes      -0.412           0.412

Бизнес-смысл:

  • Долгосрочный контракт (-0.847) → клиент менее вероятно уходит
  • Технподдержка (-0.412) → очень эффективна!
  • Высокие платежи (0.234) → клиент хочет уйти

Это позволило компании:

  • Улучшить техподдержку (ROI очень высокий)
  • Предложить скидку клиентам с высокими платежами
  • Стимулировать долгосрочные контракты

Кейс 2: Прогноз цен недвижимости (Airbnb-like)

Контекст:

  • Датасет: 50K объявлений, 100 признаков
  • Цель: предсказать цену за ночь
  • Бизнес-метрика: MAE < $50

Проблема: квартира с комнатой 20 кв.м стоит $50, а с комнатой 100 кв.м стоит $300. Зависимость цены от размера нелинейна.

# ❌ Первая попытка: линейная регрессия
from sklearn.linear_model import LinearRegression

model = LinearRegression()
model.fit(X_train[['room_size_sqm']], y_train)

# R² = 0.62, MAE = $120 ❌ Очень плохо

# ✅ Решение: логарифмическое преобразование
X_train['log_room_size'] = np.log1p(X_train['room_size_sqm'])
model = LinearRegression()
model.fit(X_train[['log_room_size']], y_train)

# R² = 0.81, MAE = $45 ✅ Отлично!

Что сделал:

  1. Анализ остатков (residuals plot) показал нелинейность
  2. Попробовал log, sqrt, полиномиальные трансформации
  3. log работал лучше всех
# Итоговая модель с feature engineering
X_train_engineered = X_train.copy()
X_train_engineered['log_room_size'] = np.log1p(X_train['room_size_sqm'])
X_train_engineered['reviews_sqrt'] = np.sqrt(X_train['number_of_reviews'])
X_train_engineered['is_entire_home'] = (X_train['room_type'] == 'Entire home').astype(int)
X_train_engineered['is_superhost'] = (X_train['host_is_superhost'] == True).astype(int)

model = LinearRegression()
model.fit(X_train_engineered, y_train)

# R² = 0.87, MAE = $42 ✅✅ Best!

Кейс 3: Fraud detection в платёжной системе

Контекст:

  • Real-time система: должна принять решение за 100ms
  • Датасет: 10M транзакций
  • Fraud rate: 0.1% (очень imbalanced)

Почему линейная логрегрессия?

  • XGBoost: 200ms обучение и inference ❌ (слишком медленно)
  • Логрегрессия: 5ms inference ✅ (в 40x быстрее)
  • Качество: AUC logistic=0.82, XGBoost=0.85 (разница в 3% не стоит 40x замедления)
# Балансировка классов при high imbalance
from sklearn.utils.class_weight import compute_class_weight

class_weights = compute_class_weight(
    'balanced',
    classes=np.unique(y_train),
    y=y_train
)
# class_weights = [0.5, 499.5] — fraud взвешен в 1000 раз!

model = LogisticRegression(
    class_weight='balanced',  # Автоматически
    max_iter=1000,
    solver='saga',
    n_jobs=-1  # Параллельное обучение
)
model.fit(X_train, y_train)

# Результат: Precision=0.75, Recall=0.82, AUC=0.82
# В production обработано 100M+ транзакций за неделю

Кейс 4: Предсказание открытия писем в email-маркетинге

Контекст:

  • A/B тестирование subject lines
  • Нужно быстро понять какой subject лучше
  • 100K писем в день

Линейная вероятность вместо логистической:

# Иногда линейная модель проще и быстрее!
from sklearn.linear_model import LinearRegression

# Targets: 0 или 1 (email opened or not)
model = LinearRegression()
model.fit(X_train, y_train)  # y ∈ {0, 1}
y_pred = model.predict(X_test)
y_pred = np.clip(y_pred, 0, 1)  # Clip в [0, 1] для вероятностей

# Интерпретация коэффициентов как вероятность
# Если subject содержит "[URGENT]" → +0.03 вероятность открыть

Кейс 5: Time series прогнозирование (попыта и неудача)

Контекст: Попытка использовать линейную регрессию для прогноза продаж.

# ❌ Попытка 1: простая линейная регрессия с лагами
from sklearn.linear_model import LinearRegression

# Создаём features: лаги продаж
X_train['sales_lag1'] = X_train['sales'].shift(1)
X_train['sales_lag7'] = X_train['sales'].shift(7)
X_train['sales_lag30'] = X_train['sales'].shift(30)

model = LinearRegression()
model.fit(X_train[['sales_lag1', 'sales_lag7', 'sales_lag30']], X_train['sales'])

# MAPE = 22% ❌ Очень плохо
# Модель не захватывает сезонность и тренды

# ✅ Вывод: для time series нужны более сложные модели
# (ARIMA, Prophet, RNN, Temporal Fusion Transformer)

Мой личный чек-лист для линейных моделей

Когда использовать линейные модели:

def should_use_linear_model(task):
    checks = {
        'Нужна интерпретируемость': True,  # ✅ Главное преимущество
        'Датасет < 1M примеров': True,     # ✅ Хватает мощности
        'Признаки независимы': True,       # ✅ Нет сильных взаимодействий
        'Зависимость примерно линейна': True,  # ✅ После feature engineering
        'Нужна скорость inference': True,  # ✅ Мс вместо сек
        'Требования к memory малы': True,  # ✅ Мегабайты вместо гигабайт
        'Baseline для сравнения': True,    # ✅ Всегда начинаю с этого
    }
    return all(checks.values())

Проверки перед использованием:

def validate_linear_model(X_train, y_train, y_pred):
    import scipy.stats as stats
    
    residuals = y_train - y_pred
    
    # 1. Нормальность остатков
    _, p_value = stats.normaltest(residuals)
    print(f"Остатки нормальны? {p_value > 0.05}")
    
    # 2. Гомоскедастичность (постоянная дисперсия)
    from statsmodels.stats.diagnostic import het_breuschpagan
    _, p_value, _, _ = het_breuschpagan(residuals, X_train)
    print(f"Гомоскедастичность? {p_value > 0.05}")
    
    # 3. Отсутствие мультиколлинеарности
    from statsmodels.stats.outliers_influence import variance_inflation_factor
    vif = variance_inflation_factor(X_train.values, 0)
    print(f"VIF < 10? {vif < 10}")
    
    # 4. Нет autocorrelation в временных рядах
    from statsmodels.stats.diagnostic import acorr_ljungbox
    _, p_value = acorr_ljungbox(residuals, lags=10)
    print(f"Нет autocorrelation? {np.all(p_value > 0.05)}")

Итоговый опыт

Какой процент моих production моделей используют линейные модели?

  • Baseline: 100% (всегда начинаю с этого)
  • Production: ~30-40% (остальное — gradient boosting)

Что я выучил:

  1. Линейные модели недооценивают — они работают лучше, чем думают
  2. Feature engineering > сложный алгоритм — правильные признаки + линейная модель > сложная модель + плохие признаки
  3. Интерпретируемость стоит денег — клиенты платят больше за объяснения
  4. Статистическая значимость — линейные модели дают p-values для признаков (XGBoost нет)
  5. Production простота — логрег в базе данных как функция SQL это реально

Золотое правило: Если можешь объяснить CEO какой признак влияет и как — используй линейную модель. Если нужна максимальная точность и объяснение можно пропустить — используй XGBoost.