Трансформация Бокса-Кокса позволяет привести данные к нормальному распределению. Проблема возникает в тот момент, когда мы представляем результаты заказчику. Если у нас целевая переменная - рубли, то трансформация превращает рубли в непонятно во что. И после обучения модели, в уже промышленном применения, нам необходима обратная трансформация из Бокса-Кокса в рубли.
Я нигде не нашел полного поста, как это делается (может просто я не там искал), но решил сделать пост с инструкцией по обратной трансформации Бокса - Кокса.
Итак
Необходимый пакет
library(caret)Создаем данные
set.seed(1) a = rnorm(100, mean = 80, sd = 40) b = rnorm(200, mean = 40, sd =20) c = c(a,b) df = as.data.frame(c) df = subset(df, df$c > 0) # удаляем значение менее нуля summary(df) c Min. : 0.4259 1st Qu.: 33.3343 Median : 48.8389 Mean : 56.0041 3rd Qu.: 74.5428 Max. :176.0647
hist(df$c)Данные создаем так, чтобы они были не нормально распределены. У вас будут свои данные.
shapiro.test(df$c) Shapiro-Wilk normality test data: df$c W = 0.93822, p-value = 9.752e-10Результаты теста нас вполне устраивают: данные далеки от нормальных. Теперь сама трансформация
trans = BoxCoxTrans(df$c) # задаем правило трансформации transc = predict(trans, df$c) # трансофрмируем hist(transc) # смотрим, что получилось
shapiro.test(transc) Shapiro-Wilk normality test data: transc W = 0.99504, p-value = 0.465Трансформация Бокса-Кокса получилась успешной. Что бывает далеко не всегда: очень часто трансформация Бокса-Кокса не превращает распределение в нормальное.
Обратная трансформация Бокса-Бокса
Нас интересует обратная трансформация Бокса-Кокса. Например, мы получили прогноз регрессии по трансформированным данным, нам необходимо получить значения в первоначальной переменной.Для начала узнаем лямбу (коэффициент трансформации) Бокса-Кокса. Ее можно узнать в правиле трансформации.
trans Box-Cox Transformation 294 data points used to estimate Lambda Input data summary: Min. 1st Qu. Median Mean 3rd Qu. Max. 0.4259 33.3300 48.8400 56.0000 74.5400 176.1000 Largest/Smallest: 413 Sample Skewness: 0.956 Estimated Lambda: 0.4Лямбда = 0.4 Формула трансформации Бокса-Кокса такова
y = (x^lmbda - 1) / lmbdaИз этой формулы мы получаем формулу обратной трансформации Бокса-Кокса
x = (y*lmbda + 1)^(1/lmbda)ВАЖНО; эта формула корректна для лямбды не равной нулю. Если ламбда принимает значение 0, то преобразование Бокса-Кокса представляет логарифмирование, а обратная трансформация Бокса-Кокса, следовательно, экспонирование, т.е.
x = exp(y)Давайте проверим корректность трансформации для нашего случая
lmbda=0.4 y = transc x = (y*lmbda + 1)^(1/lmbda) summary(x) Min. 1st Qu. Median Mean 3rd Qu. Max. 0.4259 33.3300 48.8400 56.0000 74.5400 176.1000Данные обратной трансформации Бокса-Кокса не идентичны данных первоначального набора данных df$c, но различия в пределах сотых: в оригинальном датасете, например, максимальное значение 176.06, в датасете обратной трансформации Бокса-Кокса 176.1.
Думаю, что нас устроит такая погрешность.
Простое и понятное объяснение с примером кода! Сейчас попробую! Спасибо!
ОтветитьУдалить