one_to_many_pipeline
featminer.pipelines.one_to_many.one_to_many_pipeline
one_to_many_pipeline(
*,
df: DataFrame,
target_col: str,
aggregation_key: str,
event_times: Collection[str] | None = None,
prediction_time: str | None = None,
cutoff_by: str | None = None,
relative_time_columns: Collection[RelativeTime]
| None = None,
sampling_key: str | None = None,
max_sampling_groups: int | None = None,
max_cells_threshold: int = 100000000,
candidate_screening: CandidateScreening | None = None,
cat_features: Collection[str] | None = None,
baseline_features: DataFrame | None = None,
min_category_fraction: float = 0.01,
selection: SelectionConfig | None = None,
formulas: FormulaSet
| Sequence[OneToManyFormula] = "basic",
derived_columns: DerivedColumnsConfig = DEFAULT_DERIVED_COLUMNS,
generate_report: bool = True,
open_browser: bool = True,
verbose: Literal[
"off", "warning", "info", "debug"
] = "info",
) -> pd.DataFrame
Генерирует и отбирает агрегированные признаки по связанным строкам исторической таблицы. В результате возвращает по одной строке на каждый объект.
Параметры
| Параметр | По умолчанию | Описание |
|---|---|---|
df |
— | Исходная таблица, содержащая одну или несколько строк на каждый объект. |
target_col |
— | Колонка с бинарным таргетом. Значение должно быть одинаковым внутри одного объекта. |
aggregation_key |
— | Колонка, по которой строки объединяются в объекты. |
event_times |
None |
Временные оси для time-aware формул. Могут включать известные заранее плановые даты из будущего. |
prediction_time |
None |
Момент построения прогноза. Используется как опорное время формул и включает point-in-time-фильтрацию. |
cutoff_by |
None |
Колонка из event_times, определяющая доступность строки. Строки после prediction_time исключаются. При единственной временной оси определяется автоматически. |
relative_time_columns |
None |
Числовые временные смещения с явно заданными единицами измерения. |
sampling_key |
None |
Ключ, полные группы которого сохраняются при формировании подвыборки. По умолчанию используется aggregation_key. |
max_sampling_groups |
None |
Максимальное число полных групп для отбора признаков. None не ограничивает количество групп. |
max_cells_threshold |
100_000_000 |
Максимальный размер входной таблицы строки × колонки до автоматического downsampling. |
candidate_screening |
None |
Необязательный быстрый предварительный отбор колонок и масок перед полным перебором. |
cat_features |
None |
Колонки, которые нужно обрабатывать как категориальные. Если параметр не задан, категориальные колонки определяются по типам данных. |
baseline_features |
None |
Существующие числовые признаки. Учитываются при корреляционном отборе, чтобы новые признаки не дублировали их. |
min_category_fraction |
0.01 |
Минимальная доля категории, необходимая для участия в генерации признаков. |
selection |
None |
Декларативная политика отбора. None включает SelectionConfig.auc() с прежними порогами по умолчанию. Все пороги основного отбора задаются внутри конфига. |
formulas |
"basic" |
Формулы для генерации: быстрый набор "basic", дополнительный "advanced", объединяющий их "all" или явная последовательность экземпляров формул (Sequence[OneToManyFormula]). Расширение набора может повысить качество ценой времени расчёта. |
derived_columns |
DEFAULT_DERIVED_COLUMNS |
Настройки производных колонок и условий (DerivedColumnsConfig). По умолчанию создаются дни между парами дат и условия по одной колонке; попарные разности и отношения выключены. |
generate_report |
True |
Формировать HTML-отчёт и воспроизводимый Python-код. Если False, отчёт не создаётся, а open_browser игнорируется. |
open_browser |
True |
Открывать сформированный HTML-отчёт в браузере. |
verbose |
"info" |
Уровень журналирования: "off", "warning", "info" или "debug". |
Выбор формул
В API используется параметр formulas.
Он принимает строковый пресет "basic", "advanced" или "all", а также
явную последовательность экземпляров формул. По умолчанию используется
"basic".
Выбор готового набора:
# Быстрый базовый набор используется по умолчанию.
features = one_to_many_pipeline(..., formulas="basic")
# Только дополнительные формулы.
features = one_to_many_pipeline(..., formulas="advanced")
# Базовые и дополнительные формулы вместе.
features = one_to_many_pipeline(..., formulas="all")
Если выбранной формуле не хватает временной конфигурации, pipeline выводит
warning с именами таких формул, пропускает их и продолжает расчёт. Без
event_times не запускаются формулы, которым
нужен порядок событий. При календарных Date-осях без
prediction_time пропускаются формулы,
которые считают значения относительно момента прогноза. First и Last при
этом продолжают работать, а RelativeTime использует нулевую точку прогноза.
| Набор | Формулы |
|---|---|
basic |
Fraction, Count, Max, Sum, Mean, Min, Nunique, Std, First, Last |
advanced |
NumMax, NumMin, Kurtosis, Skew, Mode, EventRange, FirstCategory, LastCategory, IntervalMax, IntervalMean, IntervalMin, IntervalStd, Trend, TimeSinceFirstMaximum, TimeSinceFirstMinimum, TimeSinceLastMaximum, TimeSinceLastMinimum, Quantile, Slope, Ewa, EwaFraction, Ews, EwsCount, EwmaTrend, WindowSum, WindowCount, WindowFraction, WindowMean, WindowMax, WindowMin, WindowStd |
all |
basic + advanced |
Можно собрать собственный набор:
from featminer import one_to_many_pipeline
from featminer.formulas import Count, Ews, Quantile, Slope, WindowSum
FORMULAS = (
Count(),
WindowSum(days=7),
WindowSum(days=30),
WindowSum(days=90),
Ews(half_life_days=7),
Ews(half_life_days=30),
Quantile(q=0.33),
Quantile(q=0.8),
Slope(last_k=10),
Slope(last_k=100),
)
features = one_to_many_pipeline(
df=transactions,
aggregation_key="client_id",
target_col="target",
event_times=("event_date",),
prediction_time="prediction_date",
formulas=FORMULAS,
)
Формулы без числовых параметров тоже передаются экземплярами: Count(),
Mean(), EventRange(), IntervalMean() и так далее.
Готовый набор можно расширить явно:
from featminer.formulas import EventRange, WindowSum
from featminer.formulas.sets import BASIC_FORMULAS
FORMULAS = (
*BASIC_FORMULAS,
EventRange(),
WindowSum(days=14),
WindowSum(days=60),
)
Time-series формулы участвуют в генерации только при наличии
event_times.
Производные колонки
Параметр derived_columns управляет арифметическими колонками, которые
создаются до применения формул:
from featminer import DerivedColumnsConfig, one_to_many_pipeline
features = one_to_many_pipeline(
df=transactions,
aggregation_key="client_id",
target_col="target",
derived_columns=DerivedColumnsConfig(
days_between=True,
differences=True,
ratios=False,
conditions=True,
max_condition_columns=1,
),
)
Параметры DerivedColumnsConfig
Значения по умолчанию сохраняют базовый режим:
DerivedColumnsConfig(
days_between=True,
differences=False,
ratios=False,
conditions=True,
max_condition_columns=1,
)
conditions=False отключает условные
признаки, но сохраняет обычные агрегаты без фильтрации.
max_condition_columns
задаёт максимальное число колонок в одном условии.
Подробнее о временных параметрах: Защита от утечки из будущего.
Подробнее о выборе AUC или корреляции Пирсона: Конфигурация отбора признаков.
Список формул
| Формула | Обязательные временные колонки | Что считает |
|---|---|---|
Fraction |
— | Долю строк внутри объекта, где выполнено условие. |
Count |
— | Количество строк внутри объекта, где выполнено условие. |
Max |
— | Максимум значения внутри объекта. |
Sum |
— | Сумму значений внутри объекта. |
Mean |
— | Среднее значение внутри объекта. |
Min |
— | Минимум значения внутри объекта. |
Nunique |
— | Количество уникальных значений внутри объекта. |
Std |
— | Стандартное отклонение внутри объекта. |
First |
event_times |
Значение в первой строке объекта по event_time. |
Last |
event_times |
Значение в последней строке объекта по event_time. |
Slope(last_k=...) |
event_times |
Линейный тренд последних last_k значений; 0 использует всю историю. Набор по умолчанию: 0, 10, 100. |
Trend |
event_times + prediction_time |
Строит линейную регрессию значения по возрасту события и возвращает значение линии в prediction_time. |
EwmaTrend(half_life_days=...) |
event_times + prediction_time |
Взвешенный Trend: вес события уменьшается вдвое каждые half_life_days. Набор по умолчанию: 1, 7, 30, 90, 365 дней. |
Quantile(q=...) |
— | Квантиль значения внутри объекта. Набор q по умолчанию: 0.01, 0.05, 0.10, 0.25, 0.50, 0.75, 0.90, 0.95, 0.99; можно передать собственный q от 0 до 1. |
Kurtosis |
— | Эксцесс распределения значений внутри объекта. |
Skew |
— | Асимметрию распределения значений внутри объекта. |
Mode |
— | Самое частое значение внутри объекта. |
NumMax |
— | Количество строк со значением, равным максимуму внутри объекта. |
NumMin |
— | Количество строк со значением, равным минимуму внутри объекта. |
Ewa(half_life_days=...) |
event_times + prediction_time |
Экспоненциально взвешенное среднее. Набор по умолчанию: 1, 7, 30, 90, 365 дней. |
EwaFraction(half_life_days=...) |
event_times + prediction_time |
Экспоненциально взвешенную долю строк, удовлетворяющих условию. Набор по умолчанию: 1, 7, 30, 90, 365 дней. |
Ews(half_life_days=...) |
event_times + prediction_time |
Экспоненциально взвешенную сумму. Набор по умолчанию: 1, 7, 30, 90, 365 дней. |
EwsCount(half_life_days=...) |
event_times + prediction_time |
Экспоненциально взвешенное количество событий. Набор по умолчанию: 1, 7, 30, 90, 365 дней. |
EventRange |
event_times |
Время между первым и последним событием объекта. |
IntervalMean |
event_times |
Средний интервал между соседними событиями. |
IntervalMin |
event_times |
Минимальный интервал между соседними событиями. |
IntervalMax |
event_times |
Максимальный интервал между соседними событиями. |
IntervalStd |
event_times |
Стандартное отклонение интервалов между соседними событиями. |
WindowSum(days=...) |
event_times + prediction_time |
Сумму значений в окне перед текущим событием. Набор по умолчанию: 1, 7, 30, 90, 365, 730, 1095 дней. |
WindowCount(days=...) |
event_times + prediction_time |
Количество событий в окне. Набор по умолчанию: 1, 7, 30, 90, 365, 730, 1095 дней. |
WindowFraction(days=...) |
event_times + prediction_time |
Долю строк, удовлетворяющих условию, в окне. Набор по умолчанию: 1, 7, 30, 90, 365, 730, 1095 дней. |
WindowMean(days=...) |
event_times + prediction_time |
Среднее значение в окне перед текущим событием. Набор по умолчанию: 1, 7, 30, 90, 365, 730, 1095 дней. |
WindowMax(days=...) |
event_times + prediction_time |
Максимум значения в окне перед текущим событием. Набор по умолчанию: 1, 7, 30, 90, 365, 730, 1095 дней. |
WindowMin(days=...) |
event_times + prediction_time |
Минимум значения в окне перед текущим событием. Набор по умолчанию: 1, 7, 30, 90, 365, 730, 1095 дней. |
WindowStd(days=...) |
event_times + prediction_time |
Стандартное отклонение в окне перед текущим событием. Набор по умолчанию: 1, 7, 30, 90, 365, 730, 1095 дней. |
Ratio |
Зависит от формул в правилах | Декларативные отношения, задаваемые списком RatioRule. Каждое правило независимо определяет допустимые формулы и колонки числителя и знаменателя. |
TimeSinceFirstMaximum |
event_times + prediction_time |
Время от первого максимума до опорного события объекта. |
TimeSinceLastMaximum |
event_times + prediction_time |
Время от последнего максимума до опорного события объекта. |
TimeSinceFirstMinimum |
event_times + prediction_time |
Время от первого минимума до опорного события объекта. |
TimeSinceLastMinimum |
event_times + prediction_time |
Время от последнего минимума до опорного события объекта. |
FirstCategory |
event_times |
Бинарный признак: первая категория по event_time равна выбранному значению. |
LastCategory |
event_times |
Бинарный признак: последняя категория по event_time равна выбранному значению. |
Настраиваемые отношения Ratio
Ratio создаёт признаки вида «числитель / знаменатель» по декларативному
списку правил. Декартово произведение строится только внутри одного
RatioRule: формулы из разных правил никогда не смешиваются. Так можно явно
разрешить Ews / Ews и WindowMean / WindowMean, не создавая
Ews / WindowMean.
| Объект или параметр | Значение по умолчанию | Назначение |
|---|---|---|
Ratio.rules |
Обязательный | Непустой список независимых правил деления. |
RatioRule.numerator |
Обязательный | Формулы и колонки, разрешённые в числителе. |
RatioRule.denominator |
Обязательный | Формулы и колонки, разрешённые в знаменателе. |
RatioRule.same_column |
False |
False строит отношения разных колонок; True использует одну колонку с обеих сторон. |
RatioRule.same_family |
True |
Оставляет только пары одного семейства агрегаций; несовместимые пары молча пропускаются. |
RatioRule.columns |
None |
Общий список колонок при same_column=True; None разрешает все совместимые колонки. |
RatioSide.formulas |
Sum, стандартные Ews и WindowSum |
Непустой список формул с параметрами, например WindowSum(days=30). |
RatioSide.columns |
None |
Колонки одной стороны при same_column=False; None разрешает все совместимые колонки. |
В компонентах отношения поддерживаются Sum, Count, Mean, Ews,
EwsCount, EwaFraction, WindowSum, WindowCount, WindowFraction и
WindowMean.
Если RatioSide.formulas не передан, сторона включает Sum(), все стандартные
Ews(half_life_days=...) (1, 7, 30, 90, 365) и все стандартные
WindowSum(days=...) (1, 7, 30, 90, 365, 730, 1095).
По умолчанию совместимы Sum ↔ WindowSum, Count ↔ WindowCount,
Mean ↔ WindowMean, а также одинаковые формулы Ews, EwsCount,
EwaFraction и WindowFraction. Например, Sum / Mean и
Ews / WindowSum пропускаются. Для намеренного отношения разных семейств
передайте same_family=False в соответствующий RatioRule.
Пример создаёт WindowSum / Sum для разных колонок, а также две изолированные
группы отношений одной колонки на разных горизонтах:
from featminer import one_to_many_pipeline
from featminer.formulas import (
Ews,
Ratio,
RatioRule,
RatioSide,
Sum,
WindowMean,
WindowSum,
)
ratios = Ratio(
rules=[
RatioRule(
numerator=RatioSide(
formulas=[WindowSum(days=7), WindowSum(days=30)],
columns=["payments"],
),
denominator=RatioSide(
formulas=[Sum()],
columns=["income"],
),
),
RatioRule(
numerator=RatioSide(formulas=[Ews(half_life_days=7)]),
denominator=RatioSide(formulas=[Ews(half_life_days=30)]),
columns=["balance"],
same_column=True,
),
RatioRule(
numerator=RatioSide(formulas=[WindowMean(days=7)]),
denominator=RatioSide(formulas=[WindowMean(days=30)]),
columns=["balance"],
same_column=True,
),
]
)
features = one_to_many_pipeline(
df=events,
target_col="target",
aggregation_key="client_id",
event_times=("event_date",),
prediction_time="prediction_date",
formulas=(ratios,),
)
В первом правиле одинаковая колонка с двух сторон исключается. Во втором и
третьем правилах колонка должна входить в общий RatioRule.columns. Если
нужны все подходящие колонки, соответствующий columns можно не передавать.
Параметры формул
q— квантиль от0до1дляQuantile;last_k— число последних событий дляSlope;0означает всю доступную историю;half_life_days— период полураспада веса в днях дляEwa,EwaFraction,Ews,EwsCountиEwmaTrend;days— размер временного окна в днях для семействаWindow*.
First и Last появляются в генерации только если в one_to_many_pipeline()
передан параметр event_times. Без него pipeline не знает порядок исторических
строк и использует только формулы, которым время не требуется.
Тренд к моменту прогноза
Trend и EwmaTrend используют возраст события относительно
prediction_time: текущее время имеет координату 0, прошлые события —
положительный возраст. Обе формулы аппроксимируют значения линией
value = intercept + slope * age и возвращают intercept, то есть оценку
значения непосредственно в момент прогноза. В отличие от них, Slope
возвращает сам коэффициент наклона.
EwmaTrend строит ту же регрессию с весом
0.5 ** (age / half_life_days). Поэтому событие возрастом ровно один период
полураспада получает вес 0.5, два периода — 0.25. События после
prediction_time не участвуют в расчёте. Если у всех доступных событий
одинаковое время, обе формулы возвращают среднее значение: обычное или
взвешенное соответственно.
Готовый advanced-набор содержит периоды 1, 7, 30, 90 и 365
дней. Собственный положительный целочисленный период можно передать явно:
from featminer.formulas import EwmaTrend
FORMULAS = (
EwmaTrend(half_life_days=3),
EwmaTrend(half_life_days=14),
EwmaTrend(half_life_days=180),
)
Интервалы между событиями
IntervalMean, IntervalMin, IntervalMax и IntervalStd сначала применяют
условия формулы, затем сортируют выбранные события внутри объекта и вычисляют
разности между соседними временными метками. Поэтому условие
status = "overdue" описывает интервалы именно между просроченными платежами,
а не между всеми платежами.
Для календарных дат интервалы измеряются в днях, включая дробную часть суток.
Для RelativeTime сохраняется единица исходной временной оси. Одинаковые
временные метки образуют нулевой интервал. Если у объекта осталось меньше двух
событий, интервальная статистика не определена.
EventRange считает расстояние между первым и последним выбранным событием.
Для единственного события результат равен нулю. В отличие от интервальных
формул, EventRange не описывает регулярность событий — только общую
продолжительность истории.