(clustMixType好像没有标签,欢迎标签建议)
我正在尝试使用库 clustMixType 来创建一些集群。
library(tidyverse)
library(clustMixType)
# no scaling or real data prep here, just reproducing an issue with minimal code
my_diamonds <- diamonds %>%
mutate(is_color_g = factor(ifelse(color == 'G', 1, 0))) %>%
select(cut, carat, is_color_g, depth, table, price) %>%
group_by(cut) %>%
nest %>%
mutate(k = 3)
my_diamonds <- my_diamonds %>%
mutate(mod.kproto = map2(data, k, ~kproto(.x, k = .y, lambda = NULL, iter.max = 100, nstart = 1, na.rm = 'no')))
这会产生一个列表列,其中每个切割都有一个聚类模型:
my_diamonds
# A tibble: 5 × 4
# Groups: cut [5]
cut data k mod.kproto
<ord> <list> <dbl> <list>
1 Ideal <tibble [21,551 × 5]> 3 <kproto>
2 Premium <tibble [13,791 × 5]> 3 <kproto>
3 Good <tibble [4,906 × 5]> 3 <kproto>
4 Very Good <tibble [12,082 × 5]> 3 <kproto>
5 Fair <tibble [1,610 × 5]> 3 <kproto>
根据库文档(pdf),我们可以使用预测将新数据分配给最近的集群。
在
predict.kproto
下有一个示例:predicted.clusters <- predict(kpres, x)
,其中x是新数据。我尝试了一下:
my_diamonds <- my_diamonds %>%
+ mutate(preds = map2(data, mod.kproto, ~predict(.y, .x)))
Error in `mutate()`:
! Problem while computing `preds = map2(data, mod.kproto, ~predict(.y, .x))`.
ℹ The error occurred in group 1: cut = Fair.
Caused by error in `x[, j] != rep(protos[i, j], nrows)`:
! comparison of these types is not implemented
Run `rlang::last_error()` to see where the error occurred.
Warning message:
Problem while computing `preds = map2(data, mod.kproto, ~predict(.y, .x))`.
ℹ Incompatible methods ("Ops.data.frame", "Ops.factor") for "!="
ℹ The warning occurred in group 1: cut = Fair.
为什么会出现此错误?如何克服它以使用 clustMixType 的预测函数将集群分配给 newdata?
似乎将
x
作为标准 data.frame
可以解决问题:
my_diamonds %>%
mutate(preds = map2(data, mod.kproto, ~predict(.y, as.data.frame(.x))))
#> # A tibble: 5 × 5
#> # Groups: cut [5]
#> cut data k mod.kproto preds
#> <ord> <list> <dbl> <list> <list>
#> 1 Ideal <tibble [21,551 × 5]> 3 <kproto> <named list [2]>
#> 2 Premium <tibble [13,791 × 5]> 3 <kproto> <named list [2]>
#> 3 Good <tibble [4,906 × 5]> 3 <kproto> <named list [2]>
#> 4 Very Good <tibble [12,082 × 5]> 3 <kproto> <named list [2]>
#> 5 Fair <tibble [1,610 × 5]> 3 <kproto> <named list [2]>
由 reprex 包于 2023 年 9 月 19 日创建(v2.0.1)
我做了更多的调试,发现错误是由这一行:
产生的d2 <- sapply(which(catvars), function(j) return(x[,j] != rep(protos[i,j], nrows)) )
这里发生的事情是,我们将
x
与 [, j]
进行子集化,其中 j
等于 which(catvars)
返回的结果
is_color_g
2
就你的情况而言。
出现错误的原因是
base::data.frame()
和 tibble::tibble()
处理子集运算的一维结果的方式不同。摘自这个答案:
[.data.frame
将删除维度,类似于矩阵子集的工作原理。所以结果是一个向量。[.tbl_df
永远不会像这样删除维度;它总是返回一个表。亲自看看:
iris[,1]
#> [1] 5.1 4.9 4.7 4.6 5.0 5.4 4.6 5.0 4.4 4.9 5.4 4.8 4.8 4.3 5.8 5.7 5.4 5.1
#> [19] 5.7 5.1 5.4 5.1 4.6 5.1 4.8 5.0 5.0 5.2 5.2 4.7 4.8 5.4 5.2 5.5 4.9 5.0
#> [37] 5.5 4.9 4.4 5.1 5.0 4.5 4.4 5.0 5.1 4.8 5.1 4.6 5.3 5.0 7.0 6.4 6.9 5.5
#> [55] 6.5 5.7 6.3 4.9 6.6 5.2 5.0 5.9 6.0 6.1 5.6 6.7 5.6 5.8 6.2 5.6 5.9 6.1
#> [73] 6.3 6.1 6.4 6.6 6.8 6.7 6.0 5.7 5.5 5.5 5.8 6.0 5.4 6.0 6.7 6.3 5.6 5.5
#> [91] 5.5 6.1 5.8 5.0 5.6 5.7 5.7 6.2 5.1 5.7 6.3 5.8 7.1 6.3 6.5 7.6 4.9 7.3
#> [109] 6.7 7.2 6.5 6.4 6.8 5.7 5.8 6.4 6.5 7.7 7.7 6.0 6.9 5.6 7.7 6.3 6.7 7.2
#> [127] 6.2 6.1 6.4 7.2 7.4 7.9 6.4 6.3 6.1 7.7 6.3 6.4 6.0 6.9 6.7 6.9 5.8 6.8
#> [145] 6.7 6.7 6.3 6.5 6.2 5.9
tibble::as_tibble(iris)[,1]
#> # A tibble: 150 × 1
#> Sepal.Length
#> <dbl>
#> 1 5.1
#> 2 4.9
#> 3 4.7
#> 4 4.6
#> 5 5
#> 6 5.4
#> 7 4.6
#> 8 5
#> 9 4.4
#> 10 4.9
#> # … with 140 more rows
由 reprex 包于 2023 年 9 月 19 日创建(v2.0.1)
这意味着当
x
是 tibble
时,结果将是一列 tibble
而不是向量,从而导致遇到语法错误。