Как делать бинаризацию факторов, например возраста
Что проверяют
Понимаете ли вы, зачем резать непрерывный признак на интервалы и какой ценой. Под бинаризацией на собеседовании обычно имеют в виду биннинг: разбиение возраста на группы с последующим one-hot кодированием. Следом спрашивают, как выбирать границы и нужна ли эта операция для бустинга.
Как отвечать
Сначала назовите цель. Биннинг помогает линейным моделям поймать нелинейную зависимость: риск по возрасту часто U-образный, и один линейный коэффициент его не описывает. Ещё он гасит выбросы и делает модель читаемой, на этом построены скоринговые карты. Способы выбора границ:
- по предметной области: пороги 18, 25, 35, 45, 60, если за ними стоят реальные правила или поведение;
- равная ширина:
pd.cutилиKBinsDiscretizer(strategy="uniform"). Просто, но на скошенном распределении крайние бины почти пустые; - равная частота:
pd.qcutилиstrategy="quantile", в каждом бине примерно одинаковое число объектов; - с учётом таргета: границы по разбиениям неглубокого дерева или оптимальный биннинг с WoE, как в кредитном скоринге;
- один порог:
Binarizer(threshold=18)из sklearn, если нужен признак вида «старше 18».
Границы подбирают только на обучающей выборке и внутри Pipeline, иначе квантили и тем более таргетные границы протекают из теста. Пропуски лучше вынести в отдельный бин: у пустого возраста часто своя логика. Для деревьев и градиентного бустинга биннинг обычно не нужен: они сами находят пороги, а LightGBM и CatBoost и так квантуют признаки в гистограммы.
Где спотыкаются
Режут на бины по таргету на всём датасете до разбиения на выборки. Метрика на валидации завышена, в проде качество падает.
Делают слишком много узких бинов. После one-hot получается разреженная матрица, где у редких бинов десяток объектов, и модель переобучается на них.
Не проверяют значения вне обучающего диапазона. pd.cut с явными границами вернёт для них NaN, поэтому крайние бины делают открытыми через -np.inf и np.inf.