Разница в подготовке данных для BI и ML
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница в подготовке данных для BI и ML
Основные различия
Business Intelligence (BI) нужны данные для отчётов, дашбордов и аналитики. Machine Learning (ML) нужны данные для обучения моделей. Подход существенно отличается.
1. Уровень агрегации
BI: Высокий уровень агрегации
-- Дашборд для руководства
SELECT
DATE_TRUNC(day, order_date) as day,
SUM(amount) as daily_revenue,
COUNT(*) as order_count,
AVG(amount) as avg_order_value
FROM orders
GROUP BY DATE_TRUNC(day, order_date)
ORDER BY day DESC;
Людям нужны сводки, тренды, сравнения по отделам/категориям.
ML: Детальный уровень (примеры)
# Для предсказания чёрна (churn) нужны индивидуальные признаки
import pandas as pd
df = pd.DataFrame({
user_id: [1, 2, 3, ...],
last_login_days_ago: [5, 1, 30, ...], # Дни с последнего визита
total_purchases: [10, 50, 2, ...], # Всего покупок
days_active: [365, 180, 30, ...], # Дни с регистрации
support_tickets: [0, 1, 5, ...], # Обращения в поддержку
churn: [0, 0, 1, ...] # Целевая переменная
})
Моделям нужны детальные признаки каждого объекта.
2. Обработка пропусков
BI: Игнорируются или показываются отдельно
-- BI дашборд
SELECT department, COUNT(*) as employees
FROM employees
WHERE department IS NOT NULL -- просто исключаем
GROUP BY department;
ML: Должны быть обработаны
# ML требует полных данные
from sklearn.impute import SimpleImputer
# Заполнение пропусков средним значением
imputer = SimpleImputer(strategy=mean)
X_filled = imputer.fit_transform(X)
# Или удаление строк с пропусками
df_clean = df.dropna()
3. Масштабирование признаков
BI: Не требуется
Выручка: $100 000
Средний чек: $50
Количество заказов: 2000
-- Люди видят понятные числа
ML: КРИТИЧНО
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# Почему?
# Без масштабирования:
# revenue (1..1000000) доминирует над age (18..80)
# Модель учится неправильно
4. Временные ряды
BI: Просто показываем исторические значения
SELECT date, SUM(revenue) as daily_revenue
FROM sales
GROUP BY date
ORDER BY date;
-- Вывод: тренд график
ML: Создаём лаговые признаки
import pandas as pd
df = pd.DataFrame({
date: [2024-01-01, 2024-01-02, 2024-01-03, ...],
revenue: [1000, 1200, 1100, ...]
})
# Лаговые признаки (предыдущие дни)
df[revenue_lag_1] = df[revenue].shift(1) # вчера
df[revenue_lag_7] = df[revenue].shift(7) # неделю назад
df[revenue_ma7] = df[revenue].rolling(7).mean() # средний за 7 дней
# Результат:
# date revenue revenue_lag_1 revenue_lag_7 revenue_ma7
# 0 2024-01-01 1000 NaN NaN NaN
# 1 2024-01-02 1200 1000 NaN NaN
# 2 2024-01-03 1100 1200 NaN NaN
5. Категориальные переменные
BI: Используют как есть
SELECT category, SUM(revenue)
FROM products
GROUP BY category;
-- Электроника: $500K
-- Одежда: $300K
-- Книги: $100K
ML: One-Hot Encoding или Label Encoding
import pandas as pd
df = pd.DataFrame({
category: [electronics, clothes, books, electronics, ...],
price: [500, 50, 20, 1000, ...]
})
# One-Hot Encoding
df_encoded = pd.get_dummies(df, columns=[category], drop_first=True)
# Результат:
# price category_clothes category_electronics
# 0 500 0 1
# 1 50 1 0
# 2 20 0 0
# 3 1000 0 1
6. Outliers (выбросы)
BI: Показываем как есть (важно видеть аномалии)
-- Дашборд показывает все значения
SELECT product, SUM(quantity) as sold
FROM orders
GROUP BY product
ORDER BY sold DESC;
-- iPhone Продали 500 (выброс) — это нормально видеть!
ML: Часто удаляют или трансформируют
from scipy.stats import zscore
# Удаление выбросов (> 3 standard deviations)
df_clean = df[abs(zscore(df[price])) < 3]
# Или логарифмическая трансформация
df[log_price] = np.log1p(df[price])
7. Data Leakage
BI: Не критично
Можно использовать будущие данные для исторических отчётов.
ML: КРИТИЧНО избежать!
# ПЛОХО: Data Leakage
df[is_high_value] = (df[total_purchases] > 10) & (df[churn] == 0)
# ^^ Используем целевую переменную при создании признака!
# ХОРОШО: Признаки только из прошлого
df[avg_purchase_30d_ago] = df[purchases].rolling(30).mean()
df[churn] = df[status] == inactive # Целевая переменная отдельно
8. Таблица vs Features
BI: Витрина = готовый отчет
CREATE TABLE sales_dashboard AS
SELECT
date,
department,
SUM(amount) as revenue,
COUNT(*) as orders
FROM sales
GROUP BY date, department;
ML: Feature Store для переиспользования
# Feature Store (например, Tecton, Feast)
feature_store = {
user_1: {
lifetime_value: 5000,
days_since_purchase: 10,
purchase_frequency: 0.5,
churn_prob: 0.1 # Может использоваться в разных моделях
}
}
9. Сравнение подхода
| Аспект | BI | ML |
|---|---|---|
| Агрегация | Высокая | Детальная |
| Пропуски | Исключаются | Заполняются/обрабатываются |
| Масштабирование | Не нужно | Критично |
| Outliers | Показываются | Часто удаляются |
| Лаги | Не используются | Essential для временных рядов |
| Категории | Как есть | One-Hot/Label Encoding |
| Data Leakage | Не проблема | ПРОБЛЕМА! |
| Цель | Insights | Predictions |
Примеры реальных различий
Сценарий: Прогноз неуплаты счетов (ML) vs Анализ неплатежей (BI)
BI подход (в SQL):
SELECT
month,
COUNT(*) as total_invoices,
COUNT(CASE WHEN status = unpaid THEN 1 END) as unpaid,
ROUND(100.0 * COUNT(CASE WHEN status = unpaid THEN 1 END) / COUNT(*), 2) as percent
FROM invoices
GROUP BY month
ORDER BY month DESC;
ML подход (на Spark):
from pyspark.sql.functions import col, when, datediff, row_number
from pyspark.sql.window import Window
from pyspark.ml.feature import StandardScaler, VectorAssembler
# Для каждого счёта — вычислить признаки
df = spark.read.parquet(invoices)
window = Window.partitionBy(customer_id).orderBy(date)
features = df.select(
invoice_id,
amount,
datediff(col(current_date), col(invoice_date)).alias(days_since_invoice),
(col(amount) > 10000).cast(int).alias(high_amount),
row_number().over(window).alias(customer_invoice_count),
is_unpaid # целевая переменная
)
# Масштабирование
assembler = VectorAssembler(inputCols=[amount, days_since_invoice, customer_invoice_count], outputCol=features)
scaler = StandardScaler(inputCol=features, outputCol=scaled_features)
Вывод
BI:
- Готовят данные для анализа и отчётов
- Работают с агрегированными данными
- Не беспокоятся о масштабировании, пропусках, outliers
ML:
- Готовят данные для обучения моделей
- Работают с детальными признаками
- Критична чистота, масштабирование, избежание data leakage
Для Data Engineer это означает: нужно подготовить две разные витрины данных, даже если источники одинаковые!