Ограничить член перехвата в H2O GLM - PullRequest
0 голосов
/ 16 января 2019

Я знаком с тем, как ограничить Betas (параметры регрессии) в h2o.glm(), но изо всех сил пытался понять, как это можно расширить, чтобы ограничить перехват.

(я понимаю, что intercept=FALSE ограничивает его до нуля, но меня интересует ненулевое ограничение.)

Пример условного набора данных:

n <- 100

set.seed(1)

getPoints <- function(n){
    rbind(
        data.frame(col= factor('red', levels=c('red','blue')), 
                   x1 = rnorm(n=n,mean=11,sd = 2), 
                   x2 = rnorm(n=n,mean=5,sd=1)),
        data.frame(col='blue', 
                   x1 = rnorm(n=n,mean=13,sd = 2), 
                   x2 = rnorm(n=n,mean=7,sd=1))
        )
}

df1     <- getPoints(n)

Пример ограничений:

param_names <- c('Intercept', 'x1', 'x2')
param_vals  <- c(       27.5, -1.1, -2.7)

beta_const_df <- data.frame(names = c('Intercept','x1','x2'),
                            lower_bounds = param_vals-0.1,
                            upper_bounds = param_vals+0.1,
                            beta_start   = param_vals)

Ограничения будут работать, если я опущу ограничение "Перехват":

glm1 <- h2o.glm(x=c('x1','x2'),
                y='col',
                family='binomial',
                lambda=0,
                alpha=0,
                training_frame = 'df1',
                beta_constraints=beta_const_df[-1,] 
                )
glm1@model$coefficients
# Intercept        x1        x2 
#  27.68408  -1.00000  -2.60000 

Но если я включу ограничение "Перехват", другие ограничения тоже не будут выполнены.

glm2 <- h2o.glm(x=c('x1','x2'),
                y='col',
                family='binomial',
                lambda=0,
                alpha=0,
                training_frame = 'df1',
                beta_constraints=beta_const_df)   
glm2@model$coefficients
#  Intercept          x1          x2 
# 0.67783085 -0.01185921 -0.03083395 

Каков правильный синтаксис для ограничения перехвата?

Ответы [ 2 ]

0 голосов
/ 17 января 2019

Попробуйте установить аргумент standardize равным False (как показано в приведенном ниже коде), вы можете узнать больше о параметре beta_constraints здесь :

glm1 <- h2o.glm(x=c('x1','x2'),
                y='col',
                family='binomial',
                lambda=0,
                alpha=0,
                training_frame = as.h2o(df1),
                beta_constraints=beta_const_df,
                standardize = F
)
glm1@model$coefficients
> glm1@model$coefficients
#Intercept        x1        x2 
#27.6      -1.0      -2.6 
0 голосов
/ 16 января 2019

Обходной путь, если все ограничения строго равны

Я могу наложить серьезный штраф L2 rho за отклонение от beta_given, и, похоже, здесь поддерживается Intercept:

beta_const_df <- data.frame(names = c('Intercept','x1','x2'),
                            #lower_bounds = param_vals-0.1, #don't bound
                            #upper_bounds = param_vals+0.1,
                            #beta_start   = param_vals, # use beta_given
                            beta_given   = param_vals, # new
                            rho          = 1e9 )       # new

Тогда это работает:

glm2 <- h2o.glm(x=c('x1','x2'),
                y='col',
                family='binomial',
                lambda=0,
                alpha=0,
                training_frame = 'df1',
                beta_constraints=beta_const_df)

glm2@model$coefficients
# Intercept        x1        x2 
#      27.5      -1.1      -2.7 
all.equal(glm2@model$coefficients, param_vals, check.names=FALSE) # TRUE

Это работает, только если у вас есть все ограничения равенства (не различаются верхняя и нижняя границы).

В любом случае, все еще интересно, есть ли менее хакерский способ сделать это.

...