簡體   English   中英

廣義線性混合 model 交叉驗證中的錯誤:“data[[cat_col]]”中的值必須在每個 ID 內保持不變

[英]Error in generalized linear mixed model cross-validation: The value in 'data[[cat_col]]' must be constant within each ID

我正在嘗試使用 groupdata2 和 cvms 包對廣義線性混合 model 進行 5 折交叉驗證。 這是我嘗試運行的代碼:

data <- groupdata2::fold(detect, k = 5,
                            cat_col = 'outcome',
                            id_col = 'bird') %>% 
                            arrange(.folds)

cvms::cross_validate(
data,
"outcome ~ sex  + year + season + (1 | bird) + (1 | obsname)",
family="binomial",
fold_cols = ".folds",
control = NULL,
REML = FALSE)

這是我收到的錯誤:

Error in groupdata2::fold(detect, k = 4, cat_col = "outcome", id_col = "bird") %>%  : 
  1 assertions failed:
 * The value in 'data[[cat_col]]' must be constant within each ID.

在 package 小插圖中,給出了以下解釋:“參與者在整個數據集中必須始終具有相同的診斷('a' 或 'b')。否則,參與者可能被置於多個折疊中。” 這在示例中是有意義的。 但是,我的數據是基於重新觀察鳥類的結果,因此結果會根據是否在特定調查中觀察到鳥類而有所不同。 有沒有解決的辦法?

可重現的例子:

bird <- c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3)
outcome <- c(0,1,1,1,0,0,0,1,0,1,0,1,0,0,1)
df <- data.frame(bird, outcome)
df$outcome <- as.factor(df$outcome)
df$bird <- as.factor(df$bird)

data <- groupdata2::fold(df, k = 5,
cat_col = 'outcome',
id_col = 'bird') %>% 
arrange(.folds)

完整的文檔說:

cat_col :用於在折疊之間平衡的分類變量的名稱。 例如,在預測二元變量(a 或 b)時,我們通常希望在每個折疊中都表示兩個類。 注意如果還傳遞了“ id_col ”,則“ cat_col ”應該在每個 ID 中保持不變。

因此,在這種情況下,如果個別鳥類 ( id_col ) 內的結果不同,您根本無法指定折疊在結果方面是平衡的。 (我不是 100% 理解軟件中的這種限制:似乎應該可以通過選擇具有平衡結果范圍的組(鳥)來至少進行近似平衡,但我可以看到它如何進行平衡程序更難)。

不過,在我看來,平衡結果的重要性總體上被高估了。 缺乏平衡意味着?binomial_metrics中的一些更簡單的指標(例如准確度、靈敏度、特異性)不是很有用,但其他的(平衡准確度、AUC、aic)應該沒問題。

一個潛在的更大問題是您似乎(可能)具有交叉隨機效應(即(1|bird) + (1|obsname) )。 我猜obsname是觀察者的名字:如果一些觀察者檢測到(或未能檢測到)多只鳥,而一些鳥被多個觀察者檢測到/失敗,那么可能無法定義實際上獨立的折疊,或者至少這可能非常困難。

您可以在 groupdata2 v2.0.0 中使用新的collapse_groups() groupdata2 v2.0.0而不是fold() 它允許您采用現有組(例如bird )並將它們折疊到更少的組(例如折疊),並嘗試平衡多個分類列、數字列和因子列(唯一級別的數量 - 盡管相同的級別可能在多個組中)。

它沒有fold()關於改變結果的約束,但另一方面,在“不變的結果”上下文中沒有相同的“保證”。 例如,它不保證所有折疊中的每個結果級別中的至少一個。

你需要的鳥比折疊的數量多,所以我在測試數據中添加了一些:


bird <- c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,
          4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,7)
outcome <- c(0,1,1,1,0,0,0,1,0,1,0,1,0,0,1,0,1,
             0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,1,1)
df <- data.frame(bird, outcome)
df$outcome <- as.factor(df$outcome)
df$bird <- as.factor(df$bird)

# Combine 'bird' groups to folds
data <- groupdata2::collapse_groups(
  data = df, 
  n = 3, 
  group_cols="bird", 
  cat_col="outcome", 
  col_name = ".folds"
) %>% 
  arrange(.folds)

# Check the balance of the relevant columns
groupdata2::summarize_balances(
  data=data, 
  group_cols=".folds", 
  cat_cols="outcome"
)$Groups

> # A tibble: 3 × 6
>   .group_col .group `# rows` `# bird` `# outc_0` `# outc_1`
>   <fct>      <fct>     <int>    <int>      <dbl>      <dbl>
> 1 .folds     1            14        3          7          7
> 2 .folds     2            10        2          6          4
> 3 .folds     3            10        2          4          6

summarize_balances()向我們展示了我們創建了 3 個折疊,第一個折疊有 14 行,其他折疊有 10 行。 在第一個折疊中有 3 個獨特的鳥類級別,在其他折疊中有 2 個(通常只在組內唯一,但在這里我們知道鳥類只在一個組中,因為collapse_groups()與它的group_cols參數一起工作)。 結果變量(此處# outc_0# outc_1 )有些平衡。

對於較大的數據集,您可能希望運行多個折疊並從摘要中選擇具有最佳平衡的一個。 這可以通過將num_new_group_cols = 10添加到collapse_groups()來完成(為了獲得更好的結果,請啟用auto_tune設置),然后在運行summarize_balances()時列出所有創建的組列。

希望這可以幫助您或其他類似 position 的人。 fold()中的約束很難用其當前的內部方法解決,但collapse_groups希望在這些情況下能解決問題。

查看更多https://rdrr.io/cran/groupdata2/man/collapse_groups.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM