Математика Дата саентиста
@workakkk - админ @data_analysis_ml - ds https://gosuslugi.ru/snet/67b55bb01a1c5a6fb6ecc946
Show more📈 Analytical overview of Telegram channel Математика Дата саентиста
Channel Математика Дата саентиста (@data_math) in the Russian language segment is an active participant. Currently, the community unites 14 427 subscribers, ranking 8 862 in the Technologies & Applications category and 45 023 in the Russia region.
📊 Audience metrics and dynamics
Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 14 427 subscribers.
According to the latest data from 11 November, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by 170 over the last 30 days and by 5 over the last 24 hours, overall reach remains high.
- Verification status: Not verified
- Engagement rate (ER): The average audience engagement rate is 12.78%. Within the first 24 hours after publication, content typically collects 6.09% reactions from the total number of subscribers.
- Post reach: On average, each post receives 1 844 views. Within the first day, a publication typically gains 878 views.
- Reactions and interaction: The audience actively supports content: the average number of reactions per post is 18.
- Thematic interests: Content is focused on key topics such as llm, программирование, параметр, визуализация, stepik.
📝 Description and content policy
The author describes the resource as a platform for expressing subjective opinions:
“@workakkk - админ
@data_analysis_ml - ds
https://gosuslugi.ru/snet/67b55bb01a1c5a6fb6ecc946”
Thanks to the high frequency of updates (latest data received on 12 November, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.
import pandas as pd
import numpy as np
np.random.seed(42)
days = pd.date_range("2023-01-01", periods=10, freq="D")
true_temp = np.sin(np.linspace(0, 3 * np.pi, 240)) * 10 + 20
bias_per_day = np.random.uniform(-2, 2, size=len(days))
df = pd.DataFrame({
"datetime": pd.date_range("2023-01-01", periods=240, freq="H"),
})
df["day"] = df["datetime"].dt.date
df["true_temp"] = true_temp
df["bias"] = df["day"].map(dict(zip(days.date, bias_per_day)))
df["measured_temp"] = df["true_temp"] + df["bias"] + np.random.normal(0, 0.5, size=240)
🔍 Разбор: как оценить смещение
Идея: температура в течение дня плавно колеблется, но bias в этот день одинаков для всех точек. Если мы "сгладим" значения (например, скользящим средним), то можем аппроксимировать общий тренд — и вычесть его, получив оценку bias.
🔧 Способ: вычтем сглаженный тренд, затем усредним остатки по дню:
```python
# Сглаживаем тренд
df["trend"] = df["measured_temp"].rolling(window=12, center=True, min_periods=1).mean()
# Остатки (приближение к bias)
df["residual"] = df["measured_temp"] - df["trend"]
# Оценка bias как среднее отклонение внутри дня
bias_est = df.groupby("day")["residual"].mean()
df["estimated_bias"] = df["day"].map(bias_est)
# Восстановим температуру: measured - bias
df["restored_temp"] = df["measured_temp"] - df["estimated_bias"]
```
📊 Результаты
Оценим ошибку восстановления:
```python
from sklearn.metrics import mean_squared_error
rmse = mean_squared_error(df["true_temp"], df["restored_temp"], squared=False)
print(f"RMSE восстановления: {rmse:.4f}")
```
> ✅ Обычно RMSE ≈ 0.5–0.7 — это близко к стандартному отклонению шума, значит bias устранён успешно!
💡 Вывод
✔️ Простая техника — сглаживание + усреднение отклонений — позволяет оценить дневные смещения
✔️ Без знания "истинной" температуры можно получить довольно точную реконструкцию
✔️ Это напоминает реальные задачи очистки данных от сенсорных сдвигов или ошибок калибровки
📈 Отличный пример практики Data Science с уклоном в математику, временные ряды и обработку шумов!List[float], представляющий одномерное распределение (например, значения метрики или зарплаты).
Нужно определить: существует ли индекс, на котором можно разделить массив на две части так, чтобы стандартное отклонение слева и справа отличалось не более чем на ε (например, 0.1).
Формат:
def has_balanced_std_split(data: list[float], epsilon: float = 0.1) -> bool:
...
Пример:
data = [1.0, 2.0, 3.0, 4.0, 5.0]
# Разделение после 2 → [1.0, 2.0], [3.0, 4.0, 5.0]
# std слева ≈ 0.5, справа ≈ 0.816 → разница = 0.316 > 0.1 → не подходит
🔍 Подсказка
Используй statistics.stdev() или numpy.std(ddof=1) (с выборочной коррекцией).
Но не забывай, что длина подмассива должна быть как минимум 2.
---
✅ Пример реализации:
```python
import statistics
def has_balanced_std_split(data: list[float], epsilon: float = 0.1) -> bool:
n = len(data)
if n < 4:
return False # Нужны хотя бы 2 элемента в каждой части
for i in range(2, n - 1):
left = data[:i]
right = data[i:]
if len(left) < 2 or len(right) < 2:
continue
std_left = statistics.stdev(left)
std_right = statistics.stdev(right)
if abs(std_left - std_right) <= epsilon:
return True
return False
```
📌 Пример использования:
```python
data = [10, 12, 11, 20, 21, 19]
print(has_balanced_std_split(data, epsilon=0.5)) # True или False в зависимости от разбивки
```
🎯 Что проверяет задача:
• понимание **дисперсии и стандартного отклонения**
• знание **статистических библиотек Python**
• работа с ограничениями на длину срезов
• мышление в духе «разделяй и анализируй»
| user_id | group | conversion_rate |
|---------|--------|-----------------|
| 1001 | A | 0 |
| 1002 | A | 1 |
| 1003 | B | 0 |
| 1004 | B | 1 |
| ... | ... | ... |
По результатам A/B теста кажется, что разницы между группами нет. Вы проверили chi-squared test и Mann-Whitney — тоже ничего.
🧩 Однако ваш коллега утверждает, что в данных явно зарыта сильная зависимость, которую можно выявить, если «включить голову».
---
🔍 Вопрос:
Какой скрытый фактор мог полностью «маскировать» эффект от теста и как его можно вычислить, даже если он отсутствует в таблице напрямую?
💡 Подсказка: данные собирались в течение 30 дней, но колонка с датой/временем была потеряна при сохранении. Однако user_id — это не случайное число.
🎯 Что нужно сделать:
1. 🧠 Предположить, что user_id содержит зашумлённую информацию о времени регистрации (например, ID выдаются монотонно)
2. 🧮 Смоделировать зависимость результата от user_id и проверить, не является ли тест несбалансированным по времени
3. 📈 Построить метрику на основе сгруппированных окон по user_id и визуализировать смещение между группами A и B
🎯 Ключевая идея решения:
Хотя колонка с датой была потеряна, можно сделать разумное предположение:
🔸 `user_id` назначается **монотонно**, т.е. пользователи с меньшими ID пришли раньше.
Если эксперимент длился 30 дней, а пользователи приходили неравномерно, то:
- группа A могла доминировать в начале
- группа B — в конце
📉 А что, если в эти периоды поведение пользователей менялось? Например, была акция, баг, праздник?
🔍 **Решение: как восстановить эффект**
1. 🟤 Добавим к данным колонку `bucket = user_id // 100`, чтобы разбить пользователей на условные "временные окна"
2. 🟤 Для каждого `bucket` считаем среднюю `conversion_rate` отдельно по группам A и B
3. 🟤 Строим график `conversion_A - conversion_B` по bucket
Если кривая скачет — тест **несбалансирован по времени** и глобальное сравнение групп вводит в заблуждение.p.
- У вас есть N исторических наблюдений: x1, x2, ..., xN, где каждое xi равно 0 или 1.
Вопросы:
1. Построить оценку вероятности успеха p и доверительный интервал на уровне 95%.
2. Рассчитать, сколько экспериментов нужно запустить, чтобы вероятность выхода в прибыль была выше 95%, учитывая:
- стоимость одного запуска C;
- прибыль от одного успешного эксперимента R.
---
▪️ Подсказки:
- Для оценки p используйте биномиальную модель.
- Для доверительного интервала:
- Можно использовать нормальное приближение (если выборка большая),
- Или Wilson-интервал для аккуратности.
---
▪️ Что оценивается:
- Правильная работа с вероятностями и доверием.
- Способность адекватно аппроксимировать биномиальные распределения.
- Чистота и практичность вычислений.
---
▪️ Разбор возможного решения:
▪️ 1. Оценка вероятности успеха:
# p_hat - оценка вероятности успеха
p_hat = sum(xi_list) / N
где xi_list — список из 0 и 1 (результаты экспериментов).
▪️ 2. Доверительный интервал через нормальное приближение:
import math
z = 1.96 # для 95% доверия
std_error = math.sqrt(p_hat * (1 - p_hat) / N)
lower_bound = p_hat - z * std_error
upper_bound = p_hat + z * std_error
▪️ 3. Wilson-интервал (более аккуратный):
z = 1.96 # для 95% доверия
center = (p_hat + z**2 / (2 * N)) / (1 + z**2 / N)
margin = (z * math.sqrt((p_hat * (1 - p_hat) / N) + (z**2 / (4 * N**2)))) / (1 + z**2 / N)
lower_bound = center - margin
upper_bound = center + margin
---
▪️ 4. Прибыльность эксперимента:
Формула прибыли при n экспериментах:
profit = successes * R - n * C
Требуется:
P(profit > 0) >= 0.95
Число успехов должно быть больше определённой границы:
min_successes = (n * C) / R
Если n велико, количество успехов приближается к нормальному распределению:
mean_successes = n * p_hat
std_successes = math.sqrt(n * p_hat * (1 - p_hat))
Для нормального приближения можно написать:
# Вероятность успешности через нормальное распределение
from scipy.stats import norm
# Вероятность, что количество успехов больше нужного
prob = 1 - norm.cdf(min_successes, loc=mean_successes, scale=std_successes)
Тогда перебором или через уравнение ищем минимальное n, чтобы prob >= 0.95.
---
▪️ Возможные подводные камни:
- Нельзя использовать нормальное приближение при малом N — нужна биномиальная модель.
- Неверное задание границ доверительного интервала может привести к неправильной стратегии запуска.
- Плохое понимание соотношения C и R приводит к ошибочным выводам об окупаемости.
---
📌Дополнительные вопросы:
- Как бы вы учли, что прибыль от успеха — случайная величина?
- Как пересчитать стратегии, если вероятность успеха зависит от времени (`p = f(t)`)?
- Как применить байесовский апдейт для оценки вероятности успеха?
---