Перейти к содержанию

Статистические тесты

Модуль содержит различные статистические тесты для A/B-тестирования.

AbsoluteIndependentTTest

Исходный код

Независимый t-тест для абсолютной разницы между двумя группами.

Этот тест сравнивает средние значения двух независимых групп, чтобы определить, существует ли статистически значимая разница между ними в абсолютных величинах.

Инициализация

def __init__(
    self,
    value_column="target",
    equal_var=True,
    random_state=None,
    alternative="two-sided",
    alpha=0.05
)

Параметры

  • value_column (str): Название столбца, содержащего значения для тестирования. По умолчанию "target".
  • equal_var (bool): Если True, выполняется стандартный независимый двухвыборочный тест, предполагающий равные дисперсии популяций. Если False, выполняется t-тест Уэлча, который не предполагает равных дисперсий популяций. По умолчанию True.
  • random_state (int или None): Начальное значение для генератора случайных чисел. По умолчанию None.
  • alternative (str): Определяет альтернативную гипотезу. Варианты: 'two-sided' (по умолчанию), 'less' или 'greater'. По умолчанию "two-sided".
  • alpha (float): Уровень значимости для доверительных интервалов. По умолчанию 0.05.

Методы

test

def test(self, groups: List[pd.DataFrame]) -> TestResult

Выполняет независимый t-тест на предоставленных группах.

Параметры:

  • groups (List[pd.DataFrame]): Список из двух DataFrame, представляющих группы для сравнения.

Возвращает:

  • TestResult: Объект, содержащий p-value, эффект и доверительный интервал.

Пример использования

import pandas as pd
import numpy as np
from aboba.tests.absolute_ttest import AbsoluteIndependentTTest

# Создание примерных данных
np.random.seed(42)
group_a = pd.DataFrame({'target': np.random.normal(10, 2, 100)})
group_b = pd.DataFrame({'target': np.random.normal(12, 2, 100)})

# Выполнение теста
test = AbsoluteIndependentTTest(value_column='target')
result = test.test([group_a, group_b])
print(f"P-value: {result.pvalue:.4f}")
print(f"Effect: {result.effect:.4f}")

AbsoluteRelatedTTest

Исходный код

Парный (связанный) t-тест для абсолютной разницы между двумя группами.

Этот тест сравнивает средние значения двух связанных групп, чтобы определить, существует ли статистически значимая разница между ними в абсолютных величинах. Обычно используется, когда одни и те же субъекты измеряются дважды (до/после).

Инициализация

def __init__(
    self,
    value_column="target",
    alternative="two-sided",
    alpha=0.05
)

Параметры

  • value_column (str): Название столбца, содержащего значения для тестирования. По умолчанию "target".
  • alternative (str): Определяет альтернативную гипотезу. По умолчанию "two-sided". Доступны следующие варианты:
    • 'two-sided': средние значения распределений, лежащих в основе выборок, не равны.
    • 'greater': среднее значение распределения, лежащего в основе первой выборки, больше.
    • 'less': среднее значение распределения, лежащего в основе первой выборки, меньше.
  • alpha (float): Уровень значимости для доверительных интервалов. По умолчанию 0.05.

Методы

test

def test(self, groups: List[pd.DataFrame]) -> TestResult

Выполняет парный t-тест на предоставленных группах.

Параметры:

  • groups (List[pd.DataFrame]): Список из двух DataFrame одинакового размера, представляющих связанные группы.

Возвращает:

  • TestResult: Объект, содержащий p-value, эффект и доверительный интервал.

Пример использования

import pandas as pd
import numpy as np
from aboba.tests.absolute_ttest import AbsoluteRelatedTTest

# Создание примерных парных данных
np.random.seed(42)
before = np.random.normal(10, 2, 50)
after = before + np.random.normal(0.5, 1, 50)  # Добавление эффекта
group_a = pd.DataFrame({'target': before})
group_b = pd.DataFrame({'target': after})

# Выполнение теста
test = AbsoluteRelatedTTest(value_column='target')
result = test.test([group_a, group_b])
print(f"P-value: {result.pvalue:.4f}")
print(f"Effect: {result.effect:.4f}")

RelativeIndependentTTest

Исходный код

Независимый t-тест для относительной разницы между двумя группами.

Этот тест сравнивает средние значения двух независимых групп, чтобы определить, существует ли статистически значимая относительная разница между ними. Относительная разница рассчитывается как (среднее_тест - среднее_контроль) / среднее_контроль.

Инициализация

def __init__(
    self,
    value_column="target",
    alternative="two-sided",
    alpha=0.05
)

Параметры

  • value_column (str): Название столбца, содержащего значения для тестирования. По умолчанию "target".
  • alternative (str): Определяет альтернативную гипотезу. Варианты: 'two-sided', 'less' или 'greater'. По умолчанию "two-sided".
  • alpha (float): Уровень значимости для доверительных интервалов. По умолчанию 0.05.

Методы

test

def test(self, groups: List[pd.DataFrame]) -> TestResult

Выполняет относительный независимый t-тест на предоставленных группах.

Параметры:

  • groups (List[pd.DataFrame]): Список из двух DataFrame, представляющих группы для сравнения. Первая группа рассматривается как контрольная, вторая как тестовая.

Возвращает:

  • TestResult: Объект, содержащий p-value и относительный эффект.

Пример использования

import pandas as pd
import numpy as np
from aboba.tests.relative_ttest import RelativeIndependentTTest

# Создание примерных данных
np.random.seed(42)
control = pd.DataFrame({'target': np.random.normal(100, 10, 100)})
test = pd.DataFrame({'target': np.random.normal(105, 10, 100)})  # Увеличение на 5%

# Выполнение теста
test_instance = RelativeIndependentTTest(value_column='target')
result = test_instance.test([control, test])
print(f"P-value: {result.pvalue:.4f}")
print(f"Relative Effect: {result.effect:.4f}")

StratifiedTTest

Исходный код

Стратифицированный t-тест для данных с учетом стратификации.

Этот тест выполняет t-тест с учетом стратификации в данных. Тест определяет, какой сэмплер использовать, на основе переданного метода.

Инициализация

def __init__(
    self,
    group_column: str,
    group_size: int,
    method: str,
    strata_columns: List[str],
    strata_weights: Union[pd.Series, dict],
    col_name: str = "target",
    alpha: float = 0.05
)

Параметры

  • group_column (str): Название столбца, содержащего идентификаторы групп.
  • group_size (int): Размер групп для выборки (используется внешними сэмплерами).
  • method (str): Метод взвешивания. Один из: 'random', 'stratified', 'post_stratified'.
  • strata_columns (List[str]): Список столбцов для стратификации.
  • strata_weights (Union[pd.Series, dict]): Обязательный параметр. Глобальные (популяционные) веса страт — задаются пользователем и отражают реальное распределение в генеральной совокупности, а не в выборке. Нормируются до суммы 1 автоматически.
  • col_name (str): Название столбца для тестирования. По умолчанию "target".
  • alpha (float): Уровень значимости для доверительных интервалов. По умолчанию 0.05.

Методы

test

def test(self, groups: List[pd.DataFrame], artefacts=None) -> TestResult

Выполняет стратифицированный t-тест на предоставленных группах.

Параметры:

  • groups (List[pd.DataFrame]): Список из двух DataFrame, представляющих группы для сравнения.
  • artefacts (dict, optional): Дополнительные артефакты (необязательно, для совместимости интерфейса).

Возвращает:

  • TestResult: Объект, содержащий p-value и эффект.

Пример использования

import pandas as pd
import numpy as np
from aboba.tests.stratified_ttest import StratifiedTTest

np.random.seed(42)
data = pd.DataFrame({
    'group':  np.repeat(['A', 'B'], 100),
    'strata': np.tile(['X', 'Y'], 100),
    'target': np.concatenate([
        np.random.normal(10, 2, 100),
        np.random.normal(12, 2, 100)
    ])
})

# Популяционные веса страт задаются явно
population_weights = pd.Series({'X': 0.6, 'Y': 0.4})

test = StratifiedTTest(
    group_column='group',
    group_size=50,
    method='post_stratified',
    strata_columns=['strata'],
    strata_weights=population_weights,
    col_name='target',
)

groups = [data[data['group'] == 'A'], data[data['group'] == 'B']]
result = test.test(groups)
print(f"P-value: {result.pvalue:.4f}")
print(f"Effect: {result.effect:.4f}")

CupedLinearRegressionTTest

Исходный код

CUPED (Controlled-experiment Using Pre-Experiment Data) через линейную регрессию.

Этот тест использует линейную регрессию для корректировки на предэкспериментальные ковариаты, снижая дисперсию и увеличивая статистическую мощность. Метод центрирует ковариаты по среднему значению контрольной группы и оценивает эффект воздействия с использованием OLS или WLS регрессии с гетероскедастичностью-устойчивыми стандартными ошибками (HC3).

Инициализация

def __init__(
    self,
    covariate_names: Optional[List[str]] = None,
    group_column: str = "group",
    value_column: str = "target",
    alpha: float = 0.05,
    center_on_control: bool = True,
    weight_column: Optional[str] = None,
    include_extra: bool = False,
    strata_column: Optional[str] = None,
    strata_weights: Optional[Union[dict, pd.Series]] = None
)

Параметры

  • covariate_names (List[str], optional): Список предэкспериментальных ковариат для корректировки. Это должны быть переменные, измеренные до эксперимента, которые коррелируют с целевой метрикой.
  • group_column (str): Название столбца, содержащего назначение группы (A/B). По умолчанию "group".
  • value_column (str): Название столбца, содержащего значения метрики для тестирования. По умолчанию "target".
  • alpha (float): Уровень значимости для доверительного интервала. По умолчанию 0.05.
  • center_on_control (bool): Если True, ковариаты центрируются по их среднему значению в контрольной группе. Это рекомендуется для снижения дисперсии. По умолчанию True.
  • weight_column (Optional[str]): Столбец с весами наблюдений для взвешенной регрессии (WLS). Если None, используется обычный МНК.
  • include_extra (bool): Если True, включает дополнительные артефакты регрессии (параметры, матрицу дизайна, остатки) в TestResult.extra. По умолчанию False.
  • strata_column (Optional[str]): Колонка с номером страты. Используется совместно с strata_weights для автоматического вычисления весов наблюдений при отсутствии weight_column.
  • strata_weights (Optional[Union[dict, pd.Series]]): Глобальные (популяционные) веса страт. Если заданы strata_column и strata_weights, но не задан weight_column, вес каждого наблюдения вычисляется как w_i = вес_страты_i / количество_наблюдений_страты_i_в_группе.

Методы

test

def test(self, groups: List[pd.DataFrame]) -> TestResult

Выполняет CUPED тест на предоставленных группах.

Параметры:

  • groups (List[pd.DataFrame]): Список из двух DataFrame, представляющих группы для сравнения. Первая группа рассматривается как контрольная, вторая как тестовая.

Возвращает:

  • TestResult: Объект, содержащий p-value, эффект и доверительный интервал. Если include_extra=True, также содержит дополнительные артефакты регрессии.

Пример использования

import pandas as pd
import numpy as np
from aboba.tests.cuped_lreg import CupedLinearRegressionTTest

# Создание примерных данных с предэкспериментальной ковариатой
np.random.seed(42)
n = 200
pre_metric = np.random.normal(100, 15, n)

# Контрольная группа
group_a = pd.DataFrame({
    'target': pre_metric[:100] + np.random.normal(0, 10, 100),
    'pre_metric': pre_metric[:100],
    'group': 0
})

# Тестовая группа с эффектом
group_b = pd.DataFrame({
    'target': pre_metric[100:] + np.random.normal(5, 10, 100),
    'pre_metric': pre_metric[100:],
    'group': 1
})

# Выполнение CUPED теста
test = CupedLinearRegressionTTest(
    covariate_names=['pre_metric'],
    value_column='target',
    group_column='group'
)
result = test.test([group_a, group_b])
print(f"P-value: {result.pvalue:.4f}")
print(f"Effect: {result.effect:.4f}")
print(f"CI: [{result.effect_interval[0]:.4f}, {result.effect_interval[1]:.4f}]")