Advertisement
Guest User

Untitled

a guest
Jun 25th, 2019
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.93 KB | None | 0 0
  1. # simulated data
  2. require(Matrix)
  3. n = 200
  4. x = 1:n
  5. npeaks = 20
  6. set.seed(123)
  7. u = sample(x, npeaks, replace=FALSE) # peak locations, which are assumed to be known here
  8. peakhrange = c(10,1E3) # peak height range
  9. h = 10^runif(npeaks, min=log10(min(peakhrange)), max=log10(max(peakhrange))) # peak heights, which are assumed to be known here
  10. a = rep(0, n) # locations of spikes of simulated spike train, which are assumed to be known here
  11. a[u] = h
  12. gauspeak = function(x, u, w, h=1) h*exp(((x-u)^2)/(-2*(w^2))) # simulated peak shape, assumed to be unknown
  13. bM = do.call(cbind, lapply(1:n, function (u) gauspeak(x, u=u, w=5, h=1) )) # banded matrix with theoretical peak shape function used
  14. p = 50 # desired size of peak shape model
  15. g_theor = gauspeak(x=1:p, u=p/2, w=5, h=1) # theoretical unknown peak shape function
  16. y_nonoise = as.vector(bM %*% a) # noiseless simulated signal = linear convolution of spike train with peak shape function
  17. y = rpois(n, y_nonoise) # simulated signal with random poisson noise on it
  18. G = matrix(0, n + p - 1, p)
  19. G = Matrix(G, sparse=TRUE)
  20. for (k in 1:p) G[(1:n) + k - 1, k] = a
  21. G = G[(1:n) + floor(p/2) - 1, ]
  22. par(mfrow=c(1,1))
  23. plot(y, type="l", ylab="Signal", xlab="x", main="Known spike train (red) convoluted with unknown blur kernel and Poisson noise")
  24. lines(a, type="h", col="red")
  25.  
  26. # peak shape function estimated using weighted nnls ridge regression via nnls with a row augmented covariate matrix
  27. weights = 1/(y+1) # 1/variance obs weights to account for Poisson noise in weighted nonnegative least square approximation
  28. weights = n*weights/sum(weights)
  29. library(nnls)
  30. lambda = 1E4 # regularization parameter for ridge penalty
  31. library(microbenchmark)
  32. microbenchmark(g_wnnls <- nnls(A=as.matrix(rbind(G*sqrt(weights), diag(sqrt(lambda),p))), b=c(y*sqrt(weights),rep(0,p)))$x) # 1.4 ms
  33. g_wnnls = (g_wnnls-min(g_wnnls))/(max(g_wnnls)-min(g_wnnls))
  34. dev.off()
  35. par(mfrow=c(2,1))
  36. plot(g_theor, type="l", lwd=7, col="grey", main="Ground truth (grey), nonnegative weighted LS ridge estimate (red)", ylab="Peak shape", xlab="x")
  37. lines(g_wnnls, col="red", lwd=2)
  38.  
  39. # peak shape function estimated using nonnegative Poisson adaptive ridge regression via nnpois with a row augmented covariate matrix
  40. library(addreg)
  41. lambda = 1E6 # regularization parameter for ridge penalty
  42. adpenweights = (1/(g_wnnls^2+1E-5)) # adaptive penalty weights to do adaptive ridge regression using wnnls estimates as truncated Gaussian prior
  43. adpenweights = n*adpenweights/sum(adpenweights)
  44. lambdas = lambda*adpenweights # adaptive penalties for adaptive ridge penalty
  45. system.time(g_nnpoisridge <- nnpois(y=c(y,rep(0,p)), # nonnegative identity link Poisson adaptive ridge regression, solved using EM algo
  46. x=as.matrix(rbind(G, diag(sqrt(lambdas),p))),
  47. standard=rep(1,p),
  48. offset=0,
  49. start=rep(1E-5, p), # or we can use g_wnnls+1E-5
  50. accelerate="squarem")$coefficients) # 0.02
  51. g_nnpoisridge = (g_nnpoisridge-min(g_nnpoisridge))/(max(g_nnpoisridge)-min(g_nnpoisridge))
  52. plot(gauspeak(x=1:p, u=25, w=5, h=1), type="l", lwd=7, col="grey", main="Ground truth (grey), nonnegative Poisson adaptive ridge estimate (red)", ylab="Peak shape", xlab="x")
  53. lines(g_nnpoisridge, col="red", lwd=2)
  54. # PS: instead of using nnpois we could also use nnlm (NNLM package) with loss="mkl" (Kullback-Leibler) which is then solved using coordinate descent and gives almost the same result
  55.  
  56. # check that nonnegative poisson adaptive ridge regression is calculated correctly using ML maximization with port algo (Quasi-Newton BFGS)
  57. # negative log-likelihood for identity link poisson ridge regression
  58. NLL_RIDGEPOIS = function(coefs, X, y, lambdas) {
  59. preds = X %*% coefs
  60. LLs = stats::dpois(y, lambda=preds, log=TRUE) # log likelihood contributions of each observation
  61. n = nrow(X)
  62. -(1/n)*sum(LLs) - lambdas*sum(coefs^2)
  63. }
  64. g_nnpoisridgeML = nlminb(start = g_nnpoisridge, # we use our estimates above as starting values
  65. objective = NLL_RIDGEPOIS, X = as.matrix(G), y = y, lambdas=lambdas,
  66. control = list(iter.max=1000, abs.tol=1E-20, rel.tol=1E-15),
  67. lower = rep(0,p) # we use nonnegativity constraints
  68. )$par
  69. max(g_nnpoisridgeML) # not sure why I get such a large value here, 6.269765e+68, should be around 1 as above - maybe mistake here?
  70. # as a quick fix I rescale coefficients
  71. g_nnpoisridgeML = (g_nnpoisridgeML-min(g_nnpoisridgeML))/(max(g_nnpoisridgeML)-min(g_nnpoisridgeML))
  72. max(abs(g_nnpoisridgeML-g_nnpoisridge)) # 0.01726672 - ML estimate is close to solution above, but not identical - could be optimizer issue though or mistake in code...
  73. par(mfrow=c(1,1))
  74. plot(g_theor,col="grey", type="l", lwd=5, main="Ground truth (grey), nonnegative Poisson adaptive ridge estimate (red),n nonnegative Poisson adaptive ridge ML estimate (blue)", ylab="Peak shape", xlab="x")
  75. lines(g_nnpoisridge,col="red",lwd=2)
  76. lines(g_nnpoisridgeML,col="blue",lwd=2)
  77.  
  78. library(h2o)
  79. library(data.table)
  80. h2o.init()
  81. df = data.frame(X=as.matrix(G), y=y)
  82. lambda = 1E6 # regularization parameter for ridge penalty, note that h2o does not support adaptive penalty weights for the moment
  83. system.time(data_h2o <- as.h2o(df)) # 0.47s - really slow...
  84. system.time(nnpois_h2o <- h2o.glm(y = "y", training_frame = data_h2o,
  85. family = "poisson", link = "identity", solver = "L_BFGS", lambda = lambda, objective_epsilon=1E-20, non_negative=TRUE,
  86. standardize = FALSE, intercept = FALSE)) # 0.21s - really slow...
  87. g_nnpoisridge_h2o = as.vector(as.data.frame(nnpois_h2o@model$coefficients_table)[-1,2])
  88. g_nnpoisridge_h2o = (g_nnpoisridge_h2o-min(g_nnpoisridge_h2o))/(max(g_nnpoisridge_h2o)-min(g_nnpoisridge_h2o))
  89. plot(g_theor,col="grey", type="l", lwd=5, main="Ground truth (grey), nonnegative Poisson adaptive ridge estimate (red),n nonnegative Poisson adaptive ridge h2o estimate (blue)", ylab="Peak shape", xlab="x")
  90. lines(g_nnpoisridge,col="red",lwd=2)
  91. lines(g_nnpoisridge_h2o,col="blue",lwd=2)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement