Trong trường hợp của các mô hình Poisson, tôi cũng sẽ nói rằng ứng dụng thường ra lệnh xem liệu các đồng biến của bạn có hành động bổ sung hay không (sau đó sẽ ngụ ý một liên kết nhận dạng) hoặc nhân lên theo tỷ lệ tuyến tính (sau đó sẽ ngụ ý liên kết nhật ký). Nhưng các mô hình Poisson với một liên kết nhận dạng thường chỉ có ý nghĩa và chỉ có thể phù hợp một cách ổn định nếu người ta áp đặt các ràng buộc không âm trên các hệ số được trang bị - điều này có thể được thực hiện bằng cách sử dụng nnpois
hàm trong addreg
gói R hoặc sử dụng nnlm
hàm trongNNLM
gói. Vì vậy, tôi không đồng ý rằng người ta phải phù hợp với các mô hình Poisson với cả liên kết danh tính và nhật ký và xem cái nào kết thúc có AIC tốt nhất và suy ra mô hình tốt nhất dựa trên cơ sở thống kê thuần túy - thay vào đó, trong hầu hết các trường hợp, nó được quyết định bởi cấu trúc cơ bản của vấn đề mà người ta cố gắng giải quyết hoặc dữ liệu trong tầm tay.
Ví dụ, trong sắc ký (phân tích GC / MS) người ta thường đo tín hiệu chồng chất của một số đỉnh hình Gauss xấp xỉ và tín hiệu chồng chất này được đo bằng hệ số nhân electron, có nghĩa là tín hiệu đo được là ion và do đó phân phối Poisson. Do mỗi đỉnh có định nghĩa là chiều cao dương và hành động cộng gộp và nhiễu là Poisson, nên mô hình Poisson không âm với liên kết nhận dạng sẽ phù hợp ở đây và mô hình Poisson liên kết nhật ký sẽ hoàn toàn sai. Trong kỹ thuật , mất Kullback-Leibler thường được sử dụng như một hàm mất cho các mô hình đó và giảm thiểu tổn thất này tương đương với việc tối ưu hóa khả năng của mô hình Poisson liên kết nhận dạng không âm (cũng có các biện pháp phân kỳ / mất mát khác như phân kỳ alpha hoặc beta có Poisson như một trường hợp đặc biệt).
Dưới đây là một ví dụ bằng số, bao gồm một minh chứng rằng liên kết nhận dạng không bị ràng buộc thông thường Poisson GLM không phù hợp (vì thiếu các ràng buộc không âm) và một số chi tiết về cách phù hợp với các mô hình Poisson liên kết nhận dạng không âmnnpois
, ở đây trong bối cảnh giải mã một sự chồng chất đo của các đỉnh sắc ký với nhiễu Poisson trên chúng bằng cách sử dụng ma trận đồng biến dải có chứa các bản sao thay đổi của hình dạng đo được của một đỉnh đơn. Tính không âm ở đây rất quan trọng vì nhiều lý do: (1) đây là mô hình thực tế duy nhất cho dữ liệu trong tay (các đỉnh ở đây không thể có độ cao âm), (2) đó là cách duy nhất để phù hợp ổn định với mô hình Poisson với liên kết nhận dạng (như mặt khác, các dự đoán có thể cho một số giá trị đồng biến trở nên tiêu cực, điều này sẽ không có ý nghĩa và sẽ đưa ra các vấn đề về số khi người ta cố gắng đánh giá khả năng), (3) hành động không âm để bình thường hóa vấn đề hồi quy và giúp rất nhiều để có được ước tính ổn định (ví dụ bạn thường không gặp phải các vấn đề quá mức như với hồi quy không giới hạn thông thường,các hạn chế không âm thanh dẫn đến các ước tính thưa thớt thường gần với sự thật mặt đất hơn; đối với vấn đề giải mã bên dưới, ví dụ hiệu năng cũng tương đương với chính quy LASSO, nhưng không yêu cầu một điều chỉnh bất kỳ tham số chính quy nào. ( Hồi quy bị phạt L0-pseudonorm vẫn hoạt động tốt hơn một chút nhưng với chi phí tính toán lớn hơn )
# we first simulate some data
require(Matrix)
n = 200
x = 1:n
npeaks = 20
set.seed(123)
u = sample(x, npeaks, replace=FALSE) # unkown peak locations
peakhrange = c(10,1E3) # peak height range
h = 10^runif(npeaks, min=log10(min(peakhrange)), max=log10(max(peakhrange))) # unknown peak heights
a = rep(0, n) # locations of spikes of simulated spike train, which are assumed to be unknown here, and which needs to be estimated from the measured total signal
a[u] = h
gauspeak = function(x, u, w, h=1) h*exp(((x-u)^2)/(-2*(w^2))) # peak shape function
bM = do.call(cbind, lapply(1:n, function (u) gauspeak(x, u=u, w=5, h=1) )) # banded matrix with peak shape measured beforehand
y_nonoise = as.vector(bM %*% a) # noiseless simulated signal = linear convolution of spike train with peak shape function
y = rpois(n, y_nonoise) # simulated signal with random poisson noise on it - this is the actual signal as it is recorded
par(mfrow=c(1,1))
plot(y, type="l", ylab="Signal", xlab="x", main="Simulated spike train (red) to be estimated given known blur kernel & with Poisson noise")
lines(a, type="h", col="red")
# let's now deconvolute the measured signal y with the banded covariate matrix containing shifted copied of the known blur kernel/peak shape bM
# first observe that regular OLS regression without nonnegativity constraints would return very bad nonsensical estimates
weights <- 1/(y+1) # let's use 1/variance = 1/(y+eps) observation weights to take into heteroscedasticity caused by Poisson noise
a_ols <- lm.fit(x=bM*sqrt(weights), y=y*sqrt(weights))$coefficients # weighted OLS
plot(x, y, type="l", main="Ground truth (red), unconstrained OLS estimate (blue)", ylab="Peak shape", xlab="x", ylim=c(-max(y),max(y)))
lines(x,-y)
lines(a, type="h", col="red", lwd=2)
lines(-a_ols, type="h", col="blue", lwd=2)
# now we use weighted nonnegative least squares with 1/variance obs weights as an approximation of nonnegative Poisson regression
# this gives very good estimates & is very fast
library(nnls)
library(microbenchmark)
microbenchmark(a_wnnls <- nnls(A=bM*sqrt(weights),b=y*sqrt(weights))$x) # 7 ms
plot(x, y, type="l", main="Ground truth (red), weighted nnls estimate (blue)", ylab="Signal (black) & peaks (red & blue)", xlab="Time", ylim=c(-max(y),max(y)))
lines(x,-y)
lines(a, type="h", col="red", lwd=2)
lines(-a_wnnls, type="h", col="blue", lwd=2)
# note that this weighted least square estimate in almost identical to the nonnegative Poisson estimate below and that it fits way faster!!!
# an unconstrained identity-link Poisson GLM will not fit:
glmfit = glm.fit(x=as.matrix(bM), y=y, family=poisson(link=identity), intercept=FALSE)
# returns Error: no valid set of coefficients has been found: please supply starting values
# so let's try a nonnegativity constrained identity-link Poisson GLM, fit using bbmle (using port algo, ie Quasi Newton BFGS):
library(bbmle)
XM=as.matrix(bM)
colnames(XM)=paste0("v",as.character(1:n))
yv=as.vector(y)
LL_poisidlink <- function(beta, X=XM, y=yv){ # neg log-likelihood function
-sum(stats::dpois(y, lambda = X %*% beta, log = TRUE)) # PS regular log-link Poisson would have exp(X %*% beta)
}
parnames(LL_poisidlink) <- colnames(XM)
system.time(fit <- mle2(
minuslogl = LL_poisidlink ,
start = setNames(a_wnnls+1E-10, colnames(XM)), # we initialise with weighted nnls estimates, with approx 1/variance obs weights
lower = rep(0,n),
vecpar = TRUE,
optimizer = "nlminb"
)) # very slow though - takes 145s
summary(fit)
a_nnpoisbbmle = coef(fit)
plot(x, y, type="l", main="Ground truth (red), nonnegative Poisson bbmle ML estimate (blue)", ylab="Signal (black) & peaks (red & blue)", xlab="Time", ylim=c(-max(y),max(y)))
lines(x,-y)
lines(a, type="h", col="red", lwd=2)
lines(-a_nnpoisbbmle, type="h", col="blue", lwd=2)
# much faster is to fit nonnegative Poisson regression using nnpois using an accelerated EM algorithm:
library(addreg)
microbenchmark(a_nnpois <- nnpois(y=y,
x=as.matrix(bM),
standard=rep(1,n),
offset=0,
start=a_wnnls+1.1E-4, # we start from weighted nnls estimates
control = addreg.control(bound.tol = 1e-04, epsilon = 1e-5),
accelerate="squarem")$coefficients) # 100 ms
plot(x, y, type="l", main="Ground truth (red), nonnegative Poisson nnpois estimate (blue)", ylab="Signal (black) & peaks (red & blue)", xlab="Time", ylim=c(-max(y),max(y)))
lines(x,-y)
lines(a, type="h", col="red", lwd=2)
lines(-a_nnpois, type="h", col="blue", lwd=2)
# or to fit nonnegative Poisson regression using nnlm with Kullback-Leibler loss using a coordinate descent algorithm:
library(NNLM)
system.time(a_nnpoisnnlm <- nnlm(x=as.matrix(rbind(bM)),
y=as.matrix(y, ncol=1),
loss="mkl", method="scd",
init=as.matrix(a_wnnls, ncol=1),
check.x=FALSE, rel.tol=1E-4)$coefficients) # 3s
plot(x, y, type="l", main="Ground truth (red), nonnegative Poisson nnlm estimate (blue)", ylab="Signal (black) & peaks (red & blue)", xlab="Time", ylim=c(-max(y),max(y)))
lines(x,-y)
lines(a, type="h", col="red", lwd=2)
lines(-a_nnpoisnnlm, type="h", col="blue", lwd=2)