May 2, 2022

Когда лучше масштабировать данные с RobustScaler

В этой статье рассмотрим опасность применения самого распространенного способа масштабирования данных - StandardScaler (подробнее зачем и как писал здесь) и чем лучше его брат заменитель - RobustScaler. Сначала на примере следующего датафрейма познакомимся с работой RobustScaler:

import pandas as pd
from sklearn.preprocessing import RobustScaler, StandardScaler
import numpy as np
np.random.seed(0)

df = pd.DataFrame([[ 1, -5,  2],
                    [ -1,  2,  3],
                   [ 8,  2, 12],
                    [ 4,  4, -4]])
df

В отличие от StandardScaler при масштабировании RobustScaler вычитает из данных медиану и делит результат на интерквартильный размах (75% квантиль - 25% квантиль):

sr = RobustScaler()
df_sr = sr.fit_transform(df)
df_sr

А так можно получить вычитаемые и делители:

sr.center_, sr.scale_

Изменения в масштабировании с RobustScaler продиктованы уязвимостью StandardScaler к выбросам. В этих случаях применять StandardScaler опасно, так как можно ввести в заблуждение модель машинного обучения. Особо часто "выбросы" возникают при масштабировании с StandardScaler one-hot признаков с редкими единицами (еще одна причина не масштабировать one-hot признаки).

Сгенерируем показательный набор данных, в котором будет один one-hot признак с только одной 1:

ss = StandardScaler()
sr = RobustScaler()

df = pd.DataFrame(np.random.normal(size=(1000,2)))
df[2] = 0
df.loc[4,2] = 1
df

Сравните результаты масштабирования с StandardScaler и RobustScaler:

df_ss = pd.DataFrame(ss.fit_transform(df), columns=df.columns)
df_ss[2].value_counts()
df_sr = pd.DataFrame(sr.fit_transform(df), columns=df.columns)
df_sr[2].value_counts()

Обратите внимание на результаты масштабирования StandardScaler. Когда мы ожиданием, что подавляющая часть значений будет едва ли по модулю больше 2, поступление на вход модели 31,6 может критически повлиять на результат.

Следует отметить, что формально интерквартильный размах для столбца 2 равен 0, но RobustScaler заменил его на 1, чтобы не возникло проблем с масштабированием:

sr.center_, sr.scale_

Не пропустите ничего интересного и подписывайтесь на страницы канала в других социальных сетях:

Яндекс Дзен

Telegram