使用预测时“未实现这些类型的比较”

问题描述 投票:0回答:1

(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?

r cluster-analysis clustmixtype
1个回答
1
投票

似乎将

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()
处理子集运算的一维结果的方式不同。摘自这个答案

  • 默认情况下,如果结果只有 1 列,
    [.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
而不是向量,从而导致遇到语法错误。

© www.soinside.com 2019 - 2024. All rights reserved.