2014-12-02 40 views
5

Vorrei sapere come limitare determinati parametri in lm() per avere un coefficiente positivo. Ci sono alcuni pacchetti o funzioni (ad esempio display) in grado di rendere tutti i coefficienti e le intercettazioni positive.R - Forza certi parametri per avere coefficiente positivo in lm()

Ad esempio, in questo esempio, mi piacerebbe solo forzare x1 e x2 ha coefficienti positivi.

x1=c(NA,rnorm(99)*10) 
    x2=c(NA,NA,rnorm(98)*10) 
    x3=rnorm(100)*10 
    y=sin(x1)+cos(x2)-x3+rnorm(100) 

    lm(y~x1+x2+x3) 

    Call: 
     lm(formula = y ~ x1 + x2 + x3)  
    Coefficients: 
     (Intercept)   x1   x2   x3 
    -0.06278  0.02261  -0.02233  -0.99626 

ho funzione nnnpls() provato in pacchetto 'nnls', può controllare il segno coefficiente facilmente. Purtroppo non posso usarlo a causa di problemi con NA nei dati in quanto questa funzione non consente NA.

Ho visto la funzione glmc() può essere utilizzata per applicare i vincoli ma non ho potuto farlo funzionare.

Qualcuno potrebbe farmi sapere cosa devo fare?

risposta

2

You can use package penalized:

set.seed(1) 

x1=c(NA,rnorm(99)*10) 
x2=c(NA,NA,rnorm(98)*10) 
x3=rnorm(100)*10 
y=sin(x1)+cos(x2)-x3+rnorm(100) 
DF <- data.frame(x1,x2,x3,y) 

lm(y~x1+x2+x3, data=DF) 
#Call: 
#lm(formula = y ~ x1 + x2 + x3, data = DF) 
# 
#Coefficients: 
#(Intercept)   x1   x2   x3 
# -0.02438  -0.01735  -0.02030  -0.98203 

Questo dà lo stesso:

library(penalized) 

mod1 <- penalized(y, ~ x1 + x2 + x3, ~1, 
        lambda1=0, lambda2=0, positive = FALSE, data=na.omit(DF)) 
coef(mod1) 
#(Intercept)   x1   x2   x3 
#-0.02438357 -0.01734856 -0.02030120 -0.98202831 

Se vincolo i coefficienti di x1 e x2 di essere positivi, diventano zero (come previsto):

mod2 <- penalized(y, ~ x1 + x2 + x3, ~1, 
        lambda1=0, lambda2=0, positive = c(T, T, F), data=na.omit(DF)) 
coef(mod2) 
#(Intercept)   x3 
#-0.03922266 -0.98011223 
+0

Grazie, hai detto "Se vincoli i coefficienti di x1 e x2 per essere positivi, diventano zero (come previsto)", ma perché è? Inoltre, nella funzione penalizzata(), sembra che tu debba definire ogni parametro come positivo o negativo, puoi renderli liberi (ad esempio lambda3 può essere sia positivo che negativo senza specificarlo). –

+0

No, 'positivo = FALSE' significa" libero ". Inoltre, se il minimo effettivo della somma dei quadrati si verifica per le stime negative, è molto probabile che il minimo nello spazio dei parametri vincolato si verifichi per zero. – Roland

+0

Sarebbe più interessante se non fosse coinvolto alcun pacchetto; Diciamo che si vorrebbe applicarlo in un'impostazione non OLS. –

0

Vecchia domanda ma dal momento che attira ancora a tention:

Per questo è possibile utilizzare il pacchetto colf. E 'attualmente offre due minimi quadrati ottimizzatori non lineari, vale a dire nls o nlxb:

library(colf) 

colf_nlxb(y ~ x1 + x2 + x3, data = DF, lower = c(-Inf, 0, 0, -Inf)) 
#nlmrt class object: x 
#residual sumsquares = 169.53 on 98 observations 
# after 3 Jacobian and 3 function evaluations 
#    name  coeff SEs tstat pval gradient JSingval 
#1 param_X.Intercept. -0.0066952 NA NA NA 3.8118 103.3941 
#2   param_x1 0.0000000 NA NA NA 103.7644 88.7017 
#3   param_x2 0.0000000 NA NA NA 0.0000 9.8032 
#4   param_x3 -0.9487088 NA NA NA 330.7776 0.0000 

colf_nls(y ~ x1 + x2 + x3, data = DF, lower = c(-Inf, 0, 0, -Inf)) 
#Nonlinear regression model 
# model: y ~ param_X.Intercept. * X.Intercept. + param_x1 * x1 + param_x2 *   
# x2 + param_x3 * x3 
# data: model_ingredients$model_data 
#param_X.Intercept.   param_x1   param_x2   param_x3 
#   -0.0392    0.0000    0.0000   -0.9801 
# residual sum-of-squares: 159 
# 
#Algorithm "port", convergence message: both X-convergence and relative convergence (5) 

È possibile impostare il lower e/o upper limiti per specificare i limiti a piacere per ciascuno dei coefficienti.