在 CNmixt fn(ContaminatedMixt pkg)中绕过“BLAS/LAPACK 例程 'DGEBAL' 给出了错误代码 -3”

Bypassing 'BLAS/LAPACK routine 'DGEBAL' gave error code -3' in CNmixt fn (ContaminatedMixt pkg)

我正在使用 ContaminatedMixt package, CNmixt function 对多维数据进行聚类。我的数据维度范围从 3 到 9。大多数数据都可以毫无问题地聚类,但我一直在努力聚类 7 维数据。

抱歉无法包含独立的 reprex,但我知道我自己的数据确实会发生错误。您可以通过 GoogleDrive 下载 .csv of the data

重现错误:

library(ContaminatedMixt)
df = read.csv (file = "210102_7clickcodas.csv",
                     header = TRUE,
                     fileEncoding =  "UTF-8-BOM")
df = round(df, 3) 
clusters = CNmixt (
  df,
  G = 2:10,
  contamination = TRUE,
  model = NULL,
  initialization = "kmeans",
  parallel = TRUE)

我要求 CNmixt 做的是将 2、然后 3、然后 4、...、然后 10 个聚类拟合到数据中并选择最佳的聚类数(基于一个标准 - 我使用ICL 但 BIC、AIC 等也是选项)。然而,当我运行这段代码时,我总是遇到以下错误:

Error in checkForRemoteErrors(val) : 
  one node produced an error: BLAS/LAPACK routine 'DGEBAL' gave error code -3

有时不止一个节点产生错误,但错误信息总是相同的。我试图通过将 G 设置为 2:10 范围内的每个值而不是范围本身(G=2,然后是 G=3,然后是 G=4,等等)来解决导致问题的 G 值。 ).看起来 CNmixt 无法将 7D 数据分成 4 个簇。这样做会导致抛出错误并停止程序 运行ning.

最重要的是,我想: a) 告诉 CNmixt 程序 bypass 任何导致错误的 G 值并继续。因此,如果 G=4 是问题所在,程序将拟合 2 个簇、3 个簇,尝试拟合 4 个簇但失败,然后 继续 拟合 5 个簇。在拟合 2:9 个簇结束时,它将选择优化标准并成功拟合的簇数。我认为这将涉及直接调整 CNmixt source code(我认为是 .CNmixtG2 函数),但不修改 CNmixt 源代码的方法也很棒。

b) 了解为什么 会出现此错误也很好。我知道之前有人问过这个错误(例如,r msm BLAS/LAPACK routine 'DGEBAL' gave error code -3),根据我的阅读,错误代码-3 似乎意味着第三个 INFO 参数中存在非法值。但事实证明,要弄清楚 'DGEBAL' 函数在 CNmixt 代码中的哪个位置被调用、它到底在做什么以及它为什么失败,对我来说真的很有挑战性。

任何有关如何执行此操作的建议将不胜感激!

这种方式可能适合你。如果您查看 CNmixt() 函数的 R 代码,它只是重复调用 CNmixt_main() 函数,尽管此函数并未从命名空间中导出。我做的第一件事是使用 expand.grid() 设置搜索网格以获取集群数量和模型的所有组合。

eg <- expand.grid(G=2:10, 
            model=c("EII", "VII", "EEI", "VEI", "EVI", "VVI", 
                    "EEE", "VEE", "EVE", "EEV", "VVE", "VEV", 
                    "EVV", "VVV"), 
            stringsAsFactors=FALSE)

接下来,我初始化一个输出对象 (ICS),然后遍历 eg 的行。对于每一行(模型和簇数的组合),我估计了包裹在 try() 中的模型,这样即使模型抛出错误也不会停止循环。对象 out 将只包含错误,它是 class "try-error"。如果函数没有因错误而终止,它 returns IC 值否则,它 returns 一个 NA 值的向量,它与 IC 值的向量一样长否则返回。最后,将 IC 值添加为 ICS 的新行,它会累积每个模型的值。

ICS <- NULL
for(i in 1:nrow(eg)){
  out <- try(ContaminatedMixt:::CNmixt_main (
    df,
    G = eg$G[i],
    contamination = TRUE,
    model = eg$model[i],
    initialization = "kmeans",
    alphafix = NULL, 
    alphamin = .5, 
    seed = NULL, 
    start.z=NULL, 
    start.v = NULL, 
    start = 0, 
    label = NULL, 
    AICcond = FALSE, 
    iter.max = 1000, 
    threshold = 1e-10, 
    parallel=FALSE, 
    eps=1e-100, 
    verbose=TRUE, 
    doCV = FALSE))
    if(inherits(out, "try-error")){
      ics <- rep(NA, 8)
    }else{
      ics <- unlist(out$models[[1]]$IC)
    }
  ICS <- rbind(ICS, ics)
}

接下来,我们可以将 IC 值附加到我们搜索的参数上。

eg <- bind_cols(eg, as_tibble(ICS))

接下来,我们可以根据簇大小找到最佳的ICL值。这是假设最好的 ICL 是最小的,如果它是最大的,只需将 min(ICL, na.rm=TRUE) 替换为 max(ICL, na.rm=TRUE)

best_per_cluster <- eg %>% 
  group_by(G) %>% 
  filter(ICL == min(ICL, na.rm=TRUE)) %>% 
  arrange(G)
best_per_cluster 
# # A tibble: 9 x 10
# # Groups:   G [9]
#      G model    AIC    BIC   AIC3   CAIC    AWE    ICL   AICc   AICu
#   <int> <chr>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
# 1     2 VII   28960. 28854. 28941. 28835. 28653. 28724. 28960. 28940.
# 2     3 EVI   31190. 30955. 31148. 30913. 30511. 30786. 31188. 31145.
# 3     4 VEI   34230. 33984. 34186. 33940. 33518. 33702. 34228. 34183.
# 4     5 EVI   35896. 35504. 35826. 35434. 34763. 35373. 35891. 35818.
# 5     6 EEI   34959. 34629. 34900. 34570. 34004. 34446. 34955. 34894.
# 6     7 EVI   38211. 37663. 38113. 37565. 36625. 37450. 38201. 38099.
# 7     8 EEI   39301. 38870. 39224. 38793. 38054. 38058. 39294. 39215.
# 8     9 EEI   37999. 37518. 37913. 37432. 36607. 37259. 37991. 37902.
# 9    10 EII   34709. 34205. 34619. 34115. 33252. 33900. 34700. 34607.

最后,我们可以选择最佳模型,再次假设最佳 ICL 是最小的模型。

best_per_cluster %>% 
  ungroup %>% 
  filter(ICL == min(ICL))
# # A tibble: 1 x 10
#         G model    AIC    BIC   AIC3   CAIC    AWE    ICL   AICc   AICu
#     <int> <chr>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
#   1     2 VII   28960. 28854. 28941. 28835. 28653. 28724. 28960. 28940.

显然,获得每个簇大小的最佳模型是一个不必要的步骤,但同样看一下可能会很有趣。

此外,我还没有回答您关于为什么会出现错误的其他问题。当我 运行 CNmixt() 函数时,我直到 G=10 才得到错误,但是当我 运行 使用 CNmixt_main() 的模型时,我在过程(例如,EVE 模型的 G=3 和 G=4)。在我的特殊情况下,错误并不像对您来说那么可靠。下面是我的会话信息,仅供参考。

> sessionInfo()
R version 4.0.3 (2020-10-10)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Catalina 10.15.4

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib

locale:
[1] en_CA.UTF-8/en_CA.UTF-8/en_CA.UTF-8/C/en_CA.UTF-8/en_CA.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ContaminatedMixt_1.3.4.1

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.5           pillar_1.4.6         compiler_4.0.3      
 [4] gower_0.2.1          plyr_1.8.6           class_7.3-17        
 [7] iterators_1.0.12     tools_4.0.3          rpart_4.1-15        
[10] ipred_0.9-9          mclust_5.4.6         lubridate_1.7.9     
[13] mixture_1.5.1        lifecycle_0.2.0      tibble_3.0.3        
[16] gtable_0.3.0         nlme_3.1-149         lattice_0.20-41     
[19] pkgconfig_2.0.3      rlang_0.4.7          Matrix_1.2-18       
[22] foreach_1.5.0        rstudioapi_0.11      parallel_4.0.3      
[25] mvtnorm_1.1-1        prodlim_2019.11.13   stringr_1.4.0       
[28] withr_2.2.0          dplyr_1.0.2          pROC_1.16.2         
[31] generics_0.0.2       vctrs_0.3.4          recipes_0.1.12      
[34] stats4_4.0.3         nnet_7.3-14          grid_4.0.3          
[37] caret_6.0-86         tidyselect_1.1.0     data.table_1.13.0   
[40] glue_1.4.2           R6_2.4.1             survival_3.2-7      
[43] lava_1.6.7           reshape2_1.4.4       ggplot2_3.3.2       
[46] purrr_0.3.4          magrittr_1.5         ModelMetrics_1.2.2.2
[49] splines_4.0.3        MASS_7.3-53          scales_1.1.1        
[52] codetools_0.2-16     ellipsis_0.3.1       mnormt_2.0.1        
[55] timeDate_3043.102    colorspace_1.4-1     stringi_1.5.3       
[58] munsell_0.5.0        tmvnsim_1.0-2        crayon_1.3.4