【问题标题】:Sparklyr handing categorical variablesSparklyr 处理分类变量
【发布时间】:2018-01-22 12:20:46
【问题描述】:

Sparklyr 处理分类变量

我来自 R 背景,习惯于在后端处理分类变量(作为因素)。在 Sparklyr 中,使用 string_indexeronehotencoder 会让人很困惑。

例如,我有许多变量在原始数据集中被编码为数字变量,但它们实际上是分类的。我想将它们用作分类变量,但不确定我做得是否正确。

library(sparklyr)
library(dplyr)
sessionInfo()
sc <- spark_connect(master = "local", version = spark_version)
spark_version(sc)
set.seed(1)    
exampleDF <- data.frame (ID = 1:10, Resp = sample(c(100:205), 10, replace = TRUE), 
                     Numb = sample(1:10, 10))

example <- copy_to(sc, exampleDF) 
pred <- example %>% mutate(Resp = as.character(Resp)) %>%
                sdf_mutate(Resp_cat = ft_string_indexer(Resp)) %>%
                ml_decision_tree(response = "Resp_cat", features = "Numb") %>%
                sdf_predict()
pred

模型的预测不是分类的。见下文。这是否意味着我还必须从预测转换回 Resp_cat,然后再转换为 Resp?

R version 3.4.0 (2017-04-21)
Platform: x86_64-redhat-linux-gnu (64-bit)
Running under: CentOS Linux 7 (Core)

spark_version(sc)
[1] ‘2.1.1.2.6.1.0’

Source:   table<sparklyr_tmp_74e340c5607c> [?? x 6]
Database: spark_connection
      ID  Numb  Resp Resp_cat id74e35c6b2dbb prediction
     <int> <int> <chr>    <dbl>          <dbl>      <dbl>
 1     1    10   150        8              0   8.000000
 2     2     3   191        4              1   4.000000
 3     3     4   146        9              2   9.000000
 4     4     9   125        5              3   5.000000
 5     5     8   107        2              4   2.000000
 6     6     2   110        1              5   1.000000
 7     7     5   133        3              6   5.333333
 8     8     7   154        6              7   5.333333
 9     9     1   170        0              8   0.000000
10    10     6   143        7              9   5.333333

【问题讨论】:

    标签: r apache-spark apache-spark-ml sparklyr


    【解决方案1】:

    通常,Spark 在处理分类数据时依赖于列元数据。在您的管道中,这是由StringIndexer (ft_string_indexer) 处理的。 ML 总是预测标签,而不是原始字符串。通常你会使用IndexToStringft_index_to_string 提供的转换器。

    在 Spark IndexToString 中可以使用 a provided list of labelsColumn 元数据。不幸的是,sparklyr 的实现在两个方面受到限制:

    • It can use only metadata,预测列上没有设置。
    • ft_string_indexer 丢弃经过训练的模型,因此它不能用于提取标签。

    我可能错过了一些东西,但看起来你必须手动映射预测,例如 joining 与转换后的数据:

    pred %>% 
      select(prediction=Resp_cat, Resp_prediction=Resp) %>% 
      distinct() %>% 
      right_join(pred)
    
    Joining, by = "prediction"
    # Source:   lazy query [?? x 9]
    # Database: spark_connection
       prediction Resp_prediction    ID  Numb  Resp Resp_cat id777a79821e1e
            <dbl>           <chr> <int> <int> <chr>    <dbl>          <dbl>
     1          7             171     1     3   171        7              0
     2          0             153     2    10   153        0              1
     3          3             132     3     8   132        3              2
     4          5             122     4     7   122        5              3
     5          6             198     5     4   198        6              4
     6          2             164     6     9   164        2              5
     7          4             137     7     6   137        4              6
     8          1             184     8     5   184        1              7
     9          0             153     9     1   153        0              8
    10          1             184    10     2   184        1              9
    # ... with more rows, and 2 more variables: rawPrediction <list>,
    #   probability <list>
    

    说明

    pred %>% 
      select(prediction=Resp_cat, Resp_prediction=Resp) %>% 
      distinct() 
    

    创建从预测(编码标签)到原始标签的映射。我们将Resp_cat 重命名为prediction,以便它可以用作连接键,并将Resp 重命名为Resp_prediction,以避免与实际的Resp 冲突。

    最后我们应用右等值连接:

    ... %>%  right_join(pred)
    

    注意

    你应该指定树的类型:

    ml_decision_tree(
      response = "Resp_cat", features = "Numb",type = "classification")
    

    【讨论】:

    • 这是一个很好的解决方法。谢谢!我确实希望 Sparklyr 可以在内部处理它,为此我开了一个ticket
    猜你喜欢
    • 1970-01-01
    • 2020-06-11
    • 2019-06-19
    • 2020-09-06
    • 2018-12-15
    • 2015-01-18
    • 1970-01-01
    • 2021-12-14
    相关资源
    最近更新 更多