vtreat 8.比例缩放模式
vtreat::prepare(scale=TRUE) 是vtreat::prepare() 准备dataframe的一种变体,因此,所有派生的输入或自x变量需要完全以因变量(y)单位表示。这是对数字y(vtreat::designTreatmentsN和vtreat::mkCrossFrameNExperiment)进行线性回归的意义。对于y版本(或0.5.26更高版本)及更高版本(在此处可用)中的分类问题,可通过逻辑回归“以链接单位”或作为0/1指示符来确定缩放比例,具体取决于或中的catScaling参数设置。在此版本分类之前,始终将缩放计算(仅缩放计算)作为针对0/1指标的线性回归进行处理。vtreat::designTreatmentsCvtreat::mkCrossFrameNExperimentycatScaling=FALSE 可能会更快一些,因为基础回归可能比逻辑回归快一些。
这是对几何/度量敏感的建模步骤(例如主成分分析或聚类(例如k均值聚类))之前的适当准备。
通常(vtreat::prepare(scale=FALSE)) vtreat会以最小的变化(纯数字)传递多个变量,针对各种条件(分类级别,NA的存在等)构建0/1指标变量,并构建一些“y单位”子模型的变量(catN,catB)。然后,将vtreat::prepare(scale=TRUE)所有这些数值变量重新处理为均值零,并在对y变量进行适当回归时将其斜率设为1(如果可能)。
用一个具体的例子最容易说明这一点。
library('vtreat')
dTrainC <- data.frame(x=c('a','a','a','b','b',NA),
y=c(FALSE,FALSE,TRUE,FALSE,TRUE,TRUE))
treatmentsC <- designTreatmentsC(dTrainC,colnames(dTrainC),'y',TRUE,
catScaling=FALSE,
verbose=FALSE)
dTrainCTreatedUnscaled <- prepare(treatmentsC,dTrainC,pruneSig=c(),scale=FALSE)
dTrainCTreatedScaled <- prepare(treatmentsC,dTrainC,pruneSig=c(),scale=TRUE)
请注意,我们已经开始catScaling=FALSE要求我们将其y视为0/1指标,并使用线性回归进行缩放。经标准vtreat转换原始数据:
print(dTrainC)
## x y
## 1 a FALSE
## 2 a FALSE
## 3 a TRUE
## 4 b FALSE
## 5 b TRUE
## 6 <NA> TRUE
print(dTrainCTreatedUnscaled)
## x_catP x_catB x_lev_NA x_lev_x_a x_lev_x_b y
## 1 0.5000000 -0.6930972 0 1 0 FALSE
## 2 0.5000000 -0.6930972 0 1 0 FALSE
## 3 0.5000000 -0.6930972 0 1 0 TRUE
## 4 0.3333333 0.0000000 0 0 1 FALSE
## 5 0.3333333 0.0000000 0 0 1 TRUE
## 6 0.1666667 9.2104404 1 0 0 TRUE
这是“标准的方式”跑vtreat -所不同的是在这个例子中,我们设置pruneSig到NULL压制,而不是将其设置为在区间的数值变量修剪,(0,1)。原理是:vtreat会对数据造成最小的影响,从而尽可能多地留给下游机器学习代码。事实证明,这已经是很多更改了。大多数情况下,vtreat仅采取不安全的步骤留待以后使用:大型分类的重新编码,异常值的重新编码以及变量的大量修剪。
但是,某些过程(尤其是主成分分析或几何聚类)假定所有列均已完全转换。通常的假设(“在违反中比在遵守中更受尊敬”)是列居中(平均为零)并缩放。“缩放”的非y感知含义是单位方差。但是,vtreat旨在强调y感知处理,并且我们认为y感知缩放的感觉应该是:相对于y回归时的单位斜率。如果要标准缩放,可以使用vtreat生成的标准框架并自行缩放。如果您想对vtreat样式y进行缩放(我们强烈认为这是正确的做法),则可以使用vtreat::prepare(scale=TRUE)它生成如下所示的框架:
print(dTrainCTreatedScaled)
## x_catP x_catB x_lev_NA x_lev_x_a x_lev_x_b y
## 1 -0.2 -0.11976374 -0.1 -0.1666667 0 FALSE
## 2 -0.2 -0.11976374 -0.1 -0.1666667 0 FALSE
## 3 -0.2 -0.11976374 -0.1 -0.1666667 0 TRUE
## 4 0.1 -0.07564865 -0.1 0.1666667 0 FALSE
## 5 0.1 -0.07564865 -0.1 0.1666667 0 TRUE
## 6 0.4 0.51058851 0.5 0.1666667 0 TRUE
首先,我们可以检查索赔。相对于y回归时,变量的均值为零且斜率为1吗?
slopeFrame <- data.frame(varName = treatmentsC$scoreFrame$varName,
stringsAsFactors = FALSE)
slopeFrame$mean <-
vapply(dTrainCTreatedScaled[, slopeFrame$varName, drop = FALSE], mean,
numeric(1))
slopeFrame$slope <- vapply(slopeFrame$varName,
function(c) {
lm(paste('y', c, sep = '~'),
data = dTrainCTreatedScaled)$coefficients[[2]]
},
numeric(1))
slopeFrame$sig <- vapply(slopeFrame$varName,
function(c) {
treatmentsC$scoreFrame[treatmentsC$scoreFrame$varName == c, 'sig']
},
numeric(1))
slopeFrame$badSlope <-
ifelse(is.na(slopeFrame$slope), TRUE, abs(slopeFrame$slope - 1) > 1.e-8)
print(slopeFrame)
## varName mean slope sig badSlope
## 1 x_catP 1.850372e-17 1 0.3289524 FALSE
## 2 x_catB 1.387779e-17 1 0.3161341 FALSE
## 3 x_lev_NA -6.938894e-18 1 0.2076623 FALSE
## 4 x_lev_x_a 0.000000e+00 1 0.4097258 FALSE
## 5 x_lev_x_b 0.000000e+00 NA 1.0000000 TRUE
以上声明是正确的,但派生变量除外xlevx.b。这是因为结果变量y在原始变量x==‘b’和何时x!=‘b’(在两种情况下都是一半的时间)上具有相同的分布。这意味着y完全独立,x==‘b’回归斜率必须为零(因此,不能为1)。现在,vtreat将其视为需要按乘数零进行缩放。还要注意,与之相关的重要性级别xlevx.b很大,因此该变量易于修剪。中的varMoves和重要事实treatmentsC$scoreFrame与未缩放的框架有关(xlevx.b实际上在哪里移动)。
要对y感知缩放在主成分分析中的应用进行很好的讨论,请参见此处。
vtreat的早期版本(0.5.22和更早版本)会将无法合理缩放的变量复制到未更改的已处理帧中。这被认为是“最忠实”的事情。但是,我们现在认为这种做法对许多下游过程(例如主成分分析和几何聚类)并不安全。
分类结果模式“ catScaling = TRUE”
从0.5.26版本开始 vtreat还支持“分类结果的缩放模式”。在此模式下,使用分类上的逻辑回归拟合的系数而不是线性拟合的系数(结果编码为0/1指标)执行缩放。
这种模式的想法是,我们将按逻辑回归的方式进行扩展-因此,我们处于逻辑回归的“link space”(逻辑回归假定效果是累加的)。该模式可能非常适合主成分分析或主成分回归,其中目标变量是分类变量(即分类任务)。
为了确保这种效果,我们在vtreat::designTreatmentsC或vtreat::mkCrossFrameCExperiment 中设置了参数 catScaling=TRUE。我们在下面演示。
treatmentsC2 <- designTreatmentsC(dTrainC,colnames(dTrainC),'y',TRUE,
catScaling=TRUE,
verbose=FALSE)
dTrainCTreatedScaled2 <- prepare(treatmentsC2,dTrainC,pruneSig=c(),scale=TRUE)
print(dTrainCTreatedScaled2)
## x_catP x_catB x_lev_NA x_lev_x_a x_lev_x_b y
## 1 -0.9396225 -1.894112 -3.161922 -0.6931472 0 FALSE
## 2 -0.9396225 -1.894112 -3.161922 -0.6931472 0 FALSE
## 3 -0.9396225 -1.894112 -3.161922 -0.6931472 0 TRUE
## 4 0.4698112 -1.196414 -3.161922 0.6931472 0 FALSE
## 5 0.4698112 -1.196414 -3.161922 0.6931472 0 TRUE
## 6 1.8792449 8.075166 15.809611 0.6931472 0 TRUE
请注意,新的缩放dataframe与原始缩放dataframe的缩放比例不同。可能是问题域的功能,缩放更合适或更有用。
新的按比例缩放的列均值为0(因此,它们并非完全是逻辑链接值,可能并没有如此偏移)。新的缩放列不一定像原始缩放列那样具有线性模型斜率1,如下所示:
colMeans(dTrainCTreatedScaled2)
## x_catP x_catB x_lev_NA x_lev_x_a x_lev_x_b y
## 3.700743e-16 7.401487e-17 0.000000e+00 0.000000e+00 0.000000e+00 5.000000e-01
lm(y~x_lev_NA,data=dTrainCTreatedScaled)
##
## Call:
## lm(formula = y ~ x_lev_NA, data = dTrainCTreatedScaled)
##
## Coefficients:
## (Intercept) x_lev_NA
## 0.5 1.0
lm(y~x_lev_NA,data=dTrainCTreatedScaled2)
##
## Call:
## lm(formula = y ~ x_lev_NA, data = dTrainCTreatedScaled2)
##
## Coefficients:
## (Intercept) x_lev_NA
## 0.50000 0.03163
但是,新的缩放列采用良好的逻辑链接单元。
vapply(slopeFrame$varName,
function(c) {
glm(paste('y', c, sep = '~'),family=binomial,
data = dTrainCTreatedScaled2)$coefficients[[2]]
},
numeric(1))
## x_catP x_catB x_lev_NA x_lev_x_a x_lev_x_b
## 1 1 1 1 NA
PCA / PCR
标度模式的预期应用包括为度量敏感的应用(例如KNN分类/回归和主成分分析/回归)准备数据。请参阅此处的描述此类应用程序的文章系列。
总体而言,建议首先使用以下模式:
意义修剪传入变量。使用y感知缩放。显着修剪导致的潜在变量。但是,具有主成分分析经验的从业人员可能对y感知分析返回的特征值或奇异值的范围感到不适。如果需要更熟悉的比例尺,我们建议对其他按比例缩放并居中的y进行y感知比例缩放,以尝试使范围接近传统单位范围。可以如下所示实现。
set.seed(235235)
dTrainN <- data.frame(x1=rnorm(100),
x2=rnorm(100),
x3=rnorm(100),
stringsAsFactors=FALSE)
dTrainN$y <- 1000*(dTrainN$x1 + dTrainN$x2)
cEraw <- vtreat::mkCrossFrameNExperiment(dTrainN,
c('x1','x2','x3'),'y',
scale=TRUE)
newvars <- cEraw$treatments$scoreFrame$varName
print(newvars)
## [1] "x1" "x2" "x3"
dM1 <- as.matrix(cEraw$crossFrame[, newvars])
pCraw <- stats::prcomp(dM1,
scale.=FALSE,center=TRUE)
print(pCraw)
## Standard deviations (1, .., p=3):
## [1] 1160.3144 1057.6874 101.1756
##
## Rotation (n x k) = (3 x 3):
## PC1 PC2 PC3
## x1 0.9653602255 -0.260919781 -0.0007092447
## x2 0.2609205097 0.965359437 0.0012824611
## x3 -0.0003500566 0.001423093 -0.9999989261
dTrainN$yScaled <- scale(dTrainN$y,center=TRUE,scale=TRUE)
cEscaled <- vtreat::mkCrossFrameNExperiment(dTrainN,
c('x1','x2','x3'),'yScaled',
scale=TRUE)
newvars_s <- cEscaled$treatments$scoreFrame$varName
print(newvars_s)
## [1] "x1" "x2" "x3"
dM2 <- as.matrix(cEscaled$crossFrame[, newvars_s])
pCscaled <- stats::prcomp(dM2,
scale.=FALSE,center=TRUE)
print(pCscaled)
## Standard deviations (1, .., p=3):
## [1] 0.7866757 0.6880818 0.1097586
##
## Rotation (n x k) = (3 x 3):
## PC1 PC2 PC3
## x1 0.9700658 -0.24208741 0.01913148
## x2 0.2417583 0.97016953 0.01800061
## x3 -0.0229185 -0.01283658 0.99965492
请注意,的第二个应用对stats::prcomp报告的标准偏差有更多的标准缩放比例(尽管我们仍然不建议仅根据与单位幅度的比较来选择变量)。

