Trình tối ưu hóa lme4 mặc định yêu cầu nhiều lần lặp lại cho dữ liệu chiều cao


12

TL; DR: lme4tối ưu hóa dường như là tuyến tính trong số các thông số mô hình theo mặc định, và là cách chậm hơn so với một tương đương glmmô hình với biến giả cho các nhóm. Có bất cứ điều gì tôi có thể làm để tăng tốc nó?


Tôi đang cố gắng phù hợp với mô hình logit phân cấp khá lớn (~ 50k hàng, 100 cột, 50 nhóm). Kết hợp mô hình logit bình thường với dữ liệu (với các biến giả cho nhóm) hoạt động tốt, nhưng mô hình phân cấp dường như bị kẹt: giai đoạn tối ưu hóa đầu tiên hoàn thành tốt, nhưng lần thứ hai trải qua rất nhiều lần lặp mà không có gì thay đổi và không dừng lại .

EDIT: Tôi nghi ngờ vấn đề chủ yếu là tôi có quá nhiều tham số, bởi vì khi tôi cố gắng đặt thành maxfngiá trị thấp hơn, nó sẽ đưa ra cảnh báo:

Warning message:
In commonArgs(par, fn, control, environment()) :
  maxfun < 10 * length(par)^2 is not recommended.

Tuy nhiên, ước tính tham số không thay đổi trong suốt quá trình tối ưu hóa, vì vậy tôi vẫn bối rối không biết phải làm gì. Khi tôi cố gắng thiết lập maxfntrong các điều khiển tối ưu hóa (bất chấp cảnh báo), nó dường như bị treo sau khi hoàn thành tối ưu hóa.

Đây là một số mã tái tạo vấn đề cho dữ liệu ngẫu nhiên:

library(lme4)

set.seed(1)

SIZE <- 50000
NGRP <- 50
NCOL <- 100

test.case <- data.frame(i=1:SIZE)
test.case[["grouping"]] <- sample(NGRP, size=SIZE, replace=TRUE, prob=1/(1:NGRP))
test.case[["y"]] <- sample(c(0, 1), size=SIZE, replace=TRUE, prob=c(0.05, 0.95))

test.formula = y ~ (1 | grouping)

for (i in 1:NCOL) {
    colname <- paste("col", i, sep="")
    test.case[[colname]] <- runif(SIZE)
    test.formula <- update.formula(test.formula, as.formula(paste(". ~ . +", colname)))
}

print(test.formula)

test.model <- glmer(test.formula, data=test.case, family='binomial', verbose=TRUE)

Kết quả này:

start par. =  1 fn =  19900.78 
At return
eval:  15 fn:      19769.402 par:  0.00000
(NM) 20: f = 19769.4 at           0     <other numbers>
(NM) 40: f = 19769.4 at           0     <other numbers>

Tôi đã thử thiết lập ncolcác giá trị khác và có vẻ như số lần lặp được thực hiện là (khoảng) 40 mỗi cột. Rõ ràng, điều này trở thành một nỗi đau lớn khi tôi thêm nhiều cột. Có những chỉnh sửa nào tôi có thể thực hiện đối với thuật toán tối ưu hóa sẽ làm giảm sự phụ thuộc vào số lượng cột?


1
Sẽ rất hữu ích khi biết mô hình cụ thể mà bạn đang cố gắng phù hợp (đặc biệt là cấu trúc hiệu ứng ngẫu nhiên).
Patrick S. Forscher

Thật không may, mô hình chính xác là độc quyền. Có một mức hiệu ứng ngẫu nhiên, với kích thước nhóm nằm trong khoảng ~ 100 đến 5000. Hãy cho tôi biết nếu tôi có thể cung cấp bất kỳ thông tin liên quan nào khác về mô hình.
Ben Kuhn

OK, tôi đã thêm một số mã tái tạo vấn đề.
Ben Kuhn

1
Tôi không có câu trả lời đầy đủ cho bạn, vì vậy tôi sẽ để lại nhận xét này. Theo kinh nghiệm của tôi, glmerkhá chậm, đặc biệt đối với các mô hình có cấu trúc hiệu ứng ngẫu nhiên phức tạp (ví dụ: nhiều độ dốc ngẫu nhiên, hiệu ứng ngẫu nhiên chéo, v.v.). Đề nghị đầu tiên của tôi sẽ là thử lại với cấu trúc hiệu ứng ngẫu nhiên đơn giản hóa. Tuy nhiên, nếu bạn chỉ gặp vấn đề này với một mô hình chặn ngẫu nhiên, vấn đề của bạn có thể chỉ đơn giản là số lượng các trường hợp, trong trường hợp đó bạn sẽ cần thử một số công cụ chuyên dùng cho dữ liệu lớn.
Patrick S. Forscher

Nó có cùng một vấn đề với 2 nhóm thay vì 50. Ngoài ra, thử nghiệm với số lượng cột nhỏ hơn, có vẻ như số lần lặp gần như tuyến tính trong số cột ... Có phương pháp tối ưu hóa nào sẽ làm tốt hơn ở đây không ?
Ben Kuhn

Câu trả lời:


12

Một điều bạn có thể thử là thay đổi trình tối ưu hóa. Xem bình luận của Ben Bolker tại vấn đề github này . Việc thực hiện nlopt của bobyqa thường nhanh hơn nhiều so với mặc định (ít nhất là bất cứ khi nào tôi thử nó).

library(nloptr)
defaultControl <- list(algorithm="NLOPT_LN_BOBYQA",xtol_rel=1e-6,maxeval=1e5)
nloptwrap2 <- function(fn,par,lower,upper,control=list(),...) {
    for (n in names(defaultControl)) 
      if (is.null(control[[n]])) control[[n]] <- defaultControl[[n]]
    res <- nloptr(x0=par,eval_f=fn,lb=lower,ub=upper,opts=control,...)
    with(res,list(par=solution,
                  fval=objective,
                  feval=iterations,
                  conv=if (status>0) 0 else status,
                  message=message))
}

system.time(test.model <- glmer(test.formula, data=test.case, 
family='binomial', verbose=TRUE))

system.time(test.model2 <- update(test.model,
control=glmerControl(optimizer="nloptwrap2"))

Ngoài ra, hãy xem câu trả lời này để biết thêm các tùy chọn và chủ đề này từ các mô hình hỗn hợp R-sig (có vẻ phù hợp hơn với vấn đề của bạn).

Chỉnh sửa: Tôi đã cung cấp cho bạn một số thông tin lỗi thời liên quan đến nloptr. Trong lme4 1.1-7và lên, nloptrđược nhập tự động (xem ?nloptwrap). Tất cả bạn phải làm là thêm

control = [g]lmerControl(optimizer = "nloptwrap") # +g if fitting with glmer

để gọi cho bạn


Cảm ơn bạn! Tôi đang thử mã nlopt ngay bây giờ. Tôi tự hỏi liệu có điều gì khác ngoài việc thực hiện tối ưu hóa tồi tệ đang diễn ra hay không, vì việc lắp một glm giả gần như tương đương nhanh hơn rất nhiều, nhưng tôi sẽ thấy ...
Ben Kuhn

Chà, nó chắc chắn nhanh hơn, nhưng nó đã dừng lại với một lỗi : PIRLS step-halvings failed to reduce deviance in pwrssUpdate. Bạn có biết những gì có thể xảy ra ở đây? Thông báo lỗi không chính xác trong suốt ...
Ben Kuhn

Đối với các cú đá, bạn có thể thử đặt nAGQ = 0 (xem chủ đề tôi đã liên kết để biết thêm một vài ý tưởng). Tôi không nhớ nguyên nhân gây ra lỗi PIRLS, nhưng tôi sẽ xem xét xung quanh.
alexforrence

Cám ơn rất nhiều! Bạn có thể chỉ cho tôi một tài nguyên nơi tôi có thể tìm hiểu thêm về các chi tiết của các phương pháp này để tôi có thể tự giải quyết các vấn đề như thế này trong tương lai không? Tối ưu hóa cảm thấy rất giống ma thuật đen với tôi vào lúc này.
Ben Kuhn

2
nAGQ = 0 đã làm việc với tôi trong ví dụ thử nghiệm của bạn với bobyqa mặc định (chạy trong ~ 15 giây) và trong 11 giây với nloptrbobyqa. Đây là một cuộc phỏng vấn với John C. Nash (đồng tác giả của các gói optimoptimx) nơi ông thực hiện một lời giải thích cấp cao về tối ưu hóa. Nếu bạn tra cứu optimxhoặc nloptrtrên CRAN, hướng dẫn tham khảo tương ứng của họ sẽ cho bạn biết thêm về cú pháp. nloptrcũng có một họa tiết có sẵn, đi sâu hơn một chút vào chi tiết.
alexforrence 16/1/2015
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.