Quello che stai proponendo di fare è una pessima idea, tanto che sono riluttante a mostrarti come farlo. Il motivo è che per OLS, supponendo che i residui siano normalmente distribuiti con varianza costante, le stime dei parametri seguono una distribuzione t multivariata e possiamo calcolare limiti di confidenza e valori p nel solito modo.
Tuttavia, se facciamo NNLS sugli stessi dati, i residui non saranno normalmente ditributed, e le tecniche standard di calcolo dei valori di p, ecc produrranno rifiuti. Esistono metodi per stimare i limiti di confidenza sui parametri di un adattamento NNLS (per esempio, vedere this reference), ma sono approssimativi e di solito si basano su ipotesi abbastanza restrittive sul set di dati.
D'altra parte, sarebbe bello se alcune delle funzioni più basilari di un oggetto lm
, come ad esempio predict(...)
, coeff(...)
, residuals(...)
, ecc lavorato anche per il risultato di una misura NNLS. Quindi, un modo per ottenere ciò che si utilizza è nls(...)
: solo perché un modello è lineare nei parametri non significa che non è possibile utilizzare i minimi quadrati non lineari per trovare i parametri. nls(...)
offre l'opzione di impostare limiti inferiori (e superiori) sui parametri se si utilizza l'algoritmo port
.
set.seed(1) # for reproducible example
data <- as.data.frame(matrix(runif(1e4, min = -1, max = 1),nc=4))
colnames(data) <-c("y", "x1", "x2", "x3")
data$y <- with(data,-10*x1+x2 + rnorm(2500))
A <- as.matrix(data[,c("x1", "x2", "x3")])
b <- data$y
test <- nnls(A,b)
test
# Nonnegative least squares model
# x estimates: 0 1.142601 0
# residual sum-of-squares: 88391
# reason terminated: The solution has been computed sucessfully.
fit <- nls(y~b.1*x1+b.2*x2+b.3*x3,data,algorithm="port",lower=c(0,0,0))
fit
# Nonlinear regression model
# model: y ~ b.1 * x1 + b.2 * x2 + b.3 * x3
# data: data
# b.1 b.2 b.3
# 0.000 1.143 0.000
# residual sum-of-squares: 88391
Come si può vedere, il risultato dell'utilizzo nnls(...)
e il risultato dell'utilizzo di nls(...)
con lower-c(0,0,0)
sono identici. Ma nls(...)
produce un oggetto nls
, che supporta (la maggior parte degli) gli stessi metodi di un oggetto lm
. Così si può scrivere precict(fit)
, coef(fit)
, residuals(fit)
, AIC(fit)
ecc È inoltre possibile scrivere summary(fit)
e confint(fit)
ma attenzione: i valori che si ottengono non sono significativi !!!
Per illustrare il punto sui residui, confrontiamo i residui per un OLS adatto a questi dati, con i residui per l'adattamento NNLS.
par(mfrow=c(1,2),mar=c(3,4,1,1))
qqnorm(residuals(lm(y~.,data)),main="OLS"); qqline(residuals(lm(y~.,data)))
qqnorm(residuals(fit),main="NNLS"); qqline(residuals(fit))

In questo set di dati, la parte stocastica della variabilità in y
è N (0,1) di progettazione, in modo che i residui dalle OLS fit (terreno QQ a sinistra) sono normali . Ma i residui della stessa serie di dati montati utilizzando NNLS non sono lontanamente normali. Questo perché la vera dipendenza di y
su x1
è -10
, ma l'adattamento NNLS lo sta forzando a 0. Di conseguenza, la proporzione di residui molto grandi (sia positivi che negativi) è molto più alta di quanto ci si aspetterebbe dalla distribuzione normale.
Ciao @jlhoward, non ho potuto ringraziarti abbastanza per una buona risposta. Ho sempre avuto la sensazione che ci fosse un motivo per un output diverso tra nnls/nls e lm, e la tua risposta indicherà sicuramente il perché della situazione. Sarò molto attento con l'uso di nls e il suo risultato, e molto probabilmente riconsidererò il mio modello per adattarlo in modo non vincolato. Grazie ancora per il tuo gentile aiuto e per il tempo che hai impiegato per rispondere correttamente. – Romain
Perché qualcuno dovrebbe voler fare questo, invece di lasciare semplicemente la variabile? Il risultato è lo stesso, vero? –