← Назад к вопросам
Как определить влияют ли офлайн-метрики на онлайн-метрики?
3.0 Senior🔥 151 комментариев
#Метрики и оценка моделей#Статистика и A/B тестирование
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Определение влияния офлайн-метрик на онлайн-метрики — один из ключевых вызовов в Machine Learning. Офлайн-метрики (например, точность модели) часто не коррелируют с тем, что пользователи на самом деле ценят. Рассмотрим проверенные методы.
Проблема: офлайн vs онлайн метрики
Офлайн-метрики:
- RMSE, MAE для регрессии
- Accuracy, Precision, Recall, F1 для классификации
- NDCG, MAP для ранжирования
- Вычисляются на фиксированном датасете
Онлайн-метрики:
- CTR (click-through rate)
- Конверсия
- Time on page
- Revenue per user
- User retention
- Вычисляются на живых пользователях
1. Корреляционный анализ
Наиболее простой и популярный метод:
import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
# Предположим, у вас есть данные A/B тестов
results = pd.DataFrame({
"offline_metric": [0.85, 0.87, 0.88, 0.82, 0.90, 0.86, 0.89, 0.83],
"online_metric_ctr": [0.042, 0.048, 0.051, 0.038, 0.055, 0.045, 0.052, 0.040],
"online_metric_revenue": [1.2, 1.35, 1.42, 1.1, 1.58, 1.28, 1.48, 1.15]
})
# Корреляция Пирсона
corr_ctr = results["offline_metric"].corr(results["online_metric_ctr"])
corr_revenue = results["offline_metric"].corr(results["online_metric_revenue"])
print(f"Корреляция с CTR: {corr_ctr:.4f}")
print(f"Корреляция с Revenue: {corr_revenue:.4f}")
# Проверка статистической значимости
spearman_corr, p_value = stats.spearmanr(results["offline_metric"], results["online_metric_ctr"])
print(f"Spearman корреляция: {spearman_corr:.4f}, p-value: {p_value:.4f}")
if p_value < 0.05:
print("Корреляция статистически значима на уровне 5%")
else:
print("Нет статистической значимости")
# Визуализация
plt.scatter(results["offline_metric"], results["online_metric_ctr"])
plt.xlabel("Офлайн метрика (например, точность)")
plt.ylabel("CTR (онлайн метрика)")
plt.title(f"Корреляция = {corr_ctr:.4f}")
plt.show()
2. A/B тестирование
Золотой стандарт для определения причинно-следственной связи:
from scipy import stats
# Результаты A/B теста
control_group = {
"offline_auc": 0.82,
"online_ctr": 0.040,
"conversion_rate": 0.05,
"users": 10000
}
treatment_group = {
"offline_auc": 0.88,
"online_ctr": 0.048,
"conversion_rate": 0.058,
"users": 10000
}
# Chi-square test для бинарной метрики (конверсия)
control_conversions = control_group["conversion_rate"] * control_group["users"]
treatment_conversions = treatment_group["conversion_rate"] * treatment_group["users"]
control_non_conversions = control_group["users"] - control_conversions
treatment_non_conversions = treatment_group["users"] - treatment_conversions
contingency_table = [
[int(control_conversions), int(control_non_conversions)],
[int(treatment_conversions), int(treatment_non_conversions)]
]
chi2, p_value, dof, expected = stats.chi2_contingency(contingency_table)
print(f"Chi-square test p-value: {p_value:.4f}")
if p_value < 0.05:
print("Разница статистически значима!")
else:
print("Нет статистической значимости")
# Размер эффекта (Cohen's h)
from math import asin, sqrt
cohen_h = 2 * (asin(sqrt(treatment_group["conversion_rate"])) -
asin(sqrt(control_group["conversion_rate"])))
print(f"Cohen's h (размер эффекта): {cohen_h:.4f}")
3. Регрессионный анализ
Для контроля за конфаундерами (переменными, влияющими на обе метрики):
from sklearn.linear_model import LinearRegression
import statsmodels.api as sm
# Подготовка данных (из разных экспериментов)
X = results[[
"offline_metric",
"model_version",
"user_segment",
"time_of_day"
]]
y = results["online_metric_ctr"]
# Добавляем константу
X = sm.add_constant(X)
# Логистическая регрессия
model = sm.OLS(y, X).fit()
print(model.summary())
# Коэффициент при offline_metric показывает влияние
offline_coef = model.params["offline_metric"]
offline_pval = model.pvalues["offline_metric"]
print(f"\nВлияние офлайн-метрики: {offline_coef:.4f}")
print(f"P-value: {offline_pval:.4f}")
if offline_pval < 0.05:
print("Офлайн-метрика статистически влияет на онлайн-метрику")
4. Анализ временных рядов
Для отслеживания влияния во времени:
import pandas as pd
# Данные за каждый день последние 30 дней
daily_data = pd.DataFrame({
"date": pd.date_range("2026-02-27", periods=30),
"offline_metric": np.random.uniform(0.80, 0.92, 30),
"online_metric": np.random.uniform(0.035, 0.055, 30)
})
# Скользящая корреляция (7 дней)
daily_data["rolling_corr"] = daily_data["offline_metric"].rolling(7).corr(
daily_data["online_metric"]
)
print(daily_data[["date", "rolling_corr"]].tail(10))
# График
plt.figure(figsize=(12, 4))
plt.plot(daily_data["date"], daily_data["rolling_corr"], marker="o")
plt.axhline(y=0, color="r", linestyle="--", alpha=0.5)
plt.xlabel("Дата")
plt.ylabel("7-дневная скользящая корреляция")
plt.title("Эволюция влияния офлайн-метрики")
plt.grid(True, alpha=0.3)
plt.show()
5. Причинный вывод (Causal Inference)
Для более сложных причинно-следственных связей:
from causalml.inference.tree_based import CausalTreeRegressor
from causalml.inference.meta import BaseTRegressor
# Определяем лечение: использование новой модели (1) vs старой (0)
X = results[[
"user_segment",
"time_of_day",
"device_type"
]]
treatment = (results["offline_metric"] > 0.85).astype(int)
y = results["online_metric_ctr"]
# Оцениваем средний эффект лечения (ATE)
from causalml.inference.meta import XLearner
learner = XLearner()
learner.fit(X, treatment, y)
# Условный средний эффект лечения (CATE) для каждого примера
treatment_effect = learner.predict(X)
print(f"Средний эффект: {treatment_effect.mean():.4f}")
print(f"Доверительный интервал: [{treatment_effect.mean() - 2*treatment_effect.std():.4f}, "
f"{treatment_effect.mean() + 2*treatment_effect.std():.4f}]")
6. Метрики согласованности (Consistency)
Рейнговая корреляция
Не требует линейности:
from scipy.stats import spearmanr, kendalltau
# Тест Спирмена (более робустен к выбросам)
spearman, p_spearman = spearmanr(results["offline_metric"], results["online_metric_ctr"])
print(f"Spearman rho: {spearman:.4f}, p-value: {p_spearman:.4f}")
# Тест Кендалла Тау (для малых выборок)
kendall, p_kendall = kendalltau(results["offline_metric"], results["online_metric_ctr"])
print(f"Kendall tau: {kendall:.4f}, p-value: {p_kendall:.4f}")
# Если оба теста дают положительный результат — связь устойчива
if p_spearman < 0.05 and p_kendall < 0.05:
print("Связь между метриками статистически значима")
Практическая стратегия
- Начните с корреляционного анализа — быстро и просто
- Проведите A/B тест — золотой стандарт
- Анализируйте временные ряды — отслеживайте изменения
- Используйте причинный вывод — для сложных случаев
- Валидируйте в разных сегментах — разные юзеры ведут себя по-разному
Красные флаги
- Высокая офлайн-метрика, но низкая онлайн-метрика — проблема с моделью
- Высокая корреляция на исторических данных, но отсутствие в A/B тесте — confounding
- Разные результаты для разных сегментов — нужна сегментированная оптимизация
Цель — убедиться, что оптимизация офлайн-метрики действительно улучшает бизнес-метрики, которые интересуют компанию.