Как выполнить нормализацию функций Yeo Johnson для тестовых данных?

#scikit-learn #scipy #normalization

Вопрос:

У меня есть обучающие и тестовые данные в рамках перекрестной проверки. Поскольку я нормализую обучающие данные с помощью преобразования Йо Джонсона, чтобы предотвратить утечку данных, я планирую сохранить ламбаду от нормализации обучающих данных и использовать ее для нормализации тестовых данных. Я написал небольшой фрагмент, чтобы проверить это, как показано ниже:

 import seaborn as sns
from scipy import stats
import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
# fig = plt.figure(figsize=(10,10), dpi=600)
ax1 = fig.add_subplot(421)
xTr = stats.loggamma.rvs(5, size=500)   5
prob = stats.probplot(xTr, dist=stats.norm, plot=ax1)
ax1.set_xlabel('')
ax1.set_title('Probplot:Train')

ax2 = fig.add_subplot(422)
sns.distplot(xTr, color="skyblue")
ax2.set_title('Distribution of Training Data')

ax3 = fig.add_subplot(423)
xt_scipy, lmbda = stats.yeojohnson(xTr)
prob = stats.probplot(xt_scipy, dist=stats.norm, plot=ax3)
ax3.set_title('Probplot:Yeo-Johnson:Scipy on train')

ax4 = fig.add_subplot(424)
sns.distplot(xt_scipy, color="skyblue")
ax4.set_title('Distribution of Transformed Train Data')

ax5 = fig.add_subplot(425)
xTst = stats.loggamma.rvs(10, size=500)   5
# xTst = stats.loglaplace.rvs(7, size=500)
prob = stats.probplot(xTst, dist=stats.norm, plot=ax5)
ax5.set_xlabel('')
ax5.set_title('Probplot:Test')

ax6 = fig.add_subplot(426)
sns.distplot(xTst, color="skyblue")
ax6.set_title('Distribution of Test Data')

ax7 = fig.add_subplot(427)
xtst_scipy = stats.yeojohnson(xTst, lmbda=lmbda)
prob = stats.probplot(xtst_scipy, dist=stats.norm, plot=ax7)
ax7.set_title('Probplot:Yeo-Johnson:Scipy on Test')

ax8 = fig.add_subplot(428)
sns.distplot(xtst_scipy, color="skyblue")
ax8.set_title('Distribution of Transformed Test Data')
plt.tight_layout(h_pad=0.9, w_pad=0.9)
plt.show()
 

Это дает следующие графики.
Рис. 1
У меня есть следующие вопросы:

  1. Правильно ли выполняется этап нормализации тестовых данных с помощью Scipy, как показано в моем коде ?
  2. Как это можно сделать в SKlearn , используя ранее вычисленную лямбду из обучающих данных? Причина, по которой я спрашиваю, заключается в том, что Sklearn PowerTransformer и fit_transform для Yeo Johnson не позволяют передавать предварительно вычисленную лямбду.

Спасибо, Седи

Ответ №1:

Я думаю, что вы неправильно понимаете функцию трансформаторов. fit_transform() выполняется на наборе поездов и вычисляет функцию лямбды и масштабирования. Как только они будут вычислены, вы можете использовать transform() функцию для применения этого преобразования к набору тестов.

Что касается вашего первого вопроса, разумно использовать трансформатор scikit-learn вместо преобразования scipy, поскольку они являются стандартными и могут быть добавлены в конвейер.

Для второго вопроса вы можете использовать PowerTransformer его без подгонки, установив лямбды вручную следующим образом:

 from sklearn.preprocessing import PowerTransformer

pt = PowerTransformer(method='yeo-johnson', standardize=False)
pt.lambdas_=[1,2]
pt.transform([[10,20]])