.

Сделать репост в соц сети!

понедельник, 14 мая 2018 г.

Обратная трансформация Бокса-Кокса в R



Трансформация Бокса-Кокса позволяет привести данные к нормальному распределению. Проблема возникает в тот момент, когда мы представляем результаты заказчику. Если у нас целевая переменная - рубли, то трансформация превращает рубли в непонятно во что. И после обучения модели, в уже промышленном применения, нам необходима обратная трансформация из Бокса-Кокса в рубли.
Я нигде не нашел полного поста, как это делается (может просто я не там искал), но решил сделать пост с инструкцией по обратной трансформации Бокса - Кокса.

Итак

Необходимый пакет

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)
Данные создаем так, чтобы они были не нормально распределены. У вас будут свои данные.
Обратная трансформация Бокса-Кокса в R

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) # смотрим, что получилось
Обратная трансформация Бокса-Кокса в R

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.
Думаю, что нас устроит такая погрешность.



1 комментарий:

  1. Простое и понятное объяснение с примером кода! Сейчас попробую! Спасибо!

    ОтветитьУдалить