【问题标题】:How to train a ML model in sparklyr and predict new values on another dataframe?如何在 sparklyr 中训练 ML 模型并预测另一个数据帧上的新值?
【发布时间】:2018-11-05 03:35:50
【问题描述】:

考虑以下示例

dtrain <- data_frame(text = c("Chinese Beijing Chinese",
                              "Chinese Chinese Shanghai",
                              "Chinese Macao",
                              "Tokyo Japan Chinese"),
                     doc_id = 1:4,
                     class = c(1, 1, 1, 0))

dtrain_spark <- copy_to(sc, dtrain, overwrite = TRUE)

> dtrain_spark
# Source:   table<dtrain> [?? x 3]
# Database: spark_connection
  text                     doc_id class
  <chr>                     <int> <dbl>
1 Chinese Beijing Chinese       1     1
2 Chinese Chinese Shanghai      2     1
3 Chinese Macao                 3     1
4 Tokyo Japan Chinese           4     0

这里有一个经典的朴素贝叶斯示例,其中class 标识属于China 类别的文档。

通过执行以下操作,我可以在 sparklyr 中运行朴素贝叶斯分类器:

dtrain_spark %>% 
ft_tokenizer(input.col = "text", output.col = "tokens") %>% 
ft_count_vectorizer(input_col = 'tokens', output_col = 'myvocab') %>% 
  select(myvocab, class) %>%  
  ml_naive_bayes( label_col = "class", 
                  features_col = "myvocab", 
                  prediction_col = "pcol",
                  probability_col = "prcol", 
                  raw_prediction_col = "rpcol",
                  model_type = "multinomial", 
                  smoothing = 0.6, 
                  thresholds = c(0.2, 0.4))

哪个输出:

NaiveBayesModel (Transformer)
<naive_bayes_5e946aec597e> 
 (Parameters -- Column Names)
  features_col: myvocab
  label_col: class
  prediction_col: pcol
  probability_col: prcol
  raw_prediction_col: rpcol
 (Transformer Info)
  num_classes:  int 2 
  num_features:  int 6 
  pi:  num [1:2] -1.179 -0.368 
  theta:  num [1:2, 1:6] -1.417 -0.728 -2.398 -1.981 -2.398 ... 
  thresholds:  num [1:2] 0.2 0.4 

但是,我有两个主要问题:

  1. 如何在样本中评估此分类器的性能?准确度指标在哪里?

  2. 更重要的是,我如何使用这个经过训练的模型来预测新值,例如,在以下 spark 测试数据帧中?

测试数据:

dtest <- data_frame(text = c("Chinese Chinese Chinese Tokyo Japan",
                             "random stuff"))

dtest_spark <- copy_to(sc, dtest, overwrite = TRUE)

> dtest_spark
# Source:   table<dtest> [?? x 1]
# Database: spark_connection
  text                               
  <chr>                              
1 Chinese Chinese Chinese Tokyo Japan
2 random stuff 

谢谢!

【问题讨论】:

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


    【解决方案1】:

    如何在样本中评估此分类器的性能?准确度指标在哪里?

    一般来说(有些模型提供某种形式的总结),训练数据集的评估是 Apache Spark 中的一个单独步骤。这非常适合原生 Pipeline API。

    背景

    Spark ML Pipelines 主要由两种类型的对象构建:

    • Transformers - 提供transform 方法的对象,将DataFrame 映射到更新的DataFrame

      您可以使用Transformerml_transform 方法来transform

    • Estimators - 提供fit 方法的对象,将DataFrame 映射到Transfomer。按照约定,对应的 Estimator / Transformer 对称为 Foo / FooModel

      您可以使用ml_fit 模型在sparklyrfit Estimator

    此外,ML Pipelines 可以与Evaluators(参见ml_*_evaluatorml_*_eval 方法)结合使用,可用于根据模型生成的列(通常是概率列或原始列)计算转换后数据的不同指标预测)。

    您可以使用ml_evaluate 方法申请Evaluator

    相关组件是否包括交叉验证器和训练验证拆分,可用于参数调整。

    示例

    sparklyr PipelineStages 可以通过直接传递数据或通过传递spark_connection 实例并调用上述方法(ml_fitml_transform 等)来急切地评估(如在您自己的代码中)。 )。

    这意味着你可以定义一个Pipeline如下:

    pipeline <- ml_pipeline(
      ft_tokenizer(sc, input.col = "text", output.col = "tokens"),
      ft_count_vectorizer(sc, input_col = 'tokens', output_col = 'myvocab'),
      ml_naive_bayes(sc, label_col = "class", 
                  features_col = "myvocab", 
                  prediction_col = "pcol",
                  probability_col = "prcol", 
                  raw_prediction_col = "rpcol",
                  model_type = "multinomial", 
                  smoothing = 0.6, 
                  thresholds = c(0.2, 0.4),
                  uid = "nb")
    )
    

    适合PipelineModel

    model <- ml_fit(pipeline, dtrain_spark)
    

    转换并应用可用的Evaluators之一:

    ml_transform(model, dtrain_spark) %>% 
      ml_binary_classification_evaluator(
        label_col="class", raw_prediction_col= "rpcol", 
        metric_name = "areaUnderROC")
    
    [1] 1
    

    evaluator <- ml_multiclass_classification_evaluator(
        sc,
        label_col="class", prediction_col= "pcol", 
        metric_name = "f1")
    
    ml_evaluate(evaluator, ml_transform(model, dtrain_spark))
    
    [1] 1
    

    更重要的是,我如何使用这个经过训练的模型来预测新值,例如,在以下 spark 测试数据帧中?

    使用ml_transformml_predict(后者是一个令人信服的包装器,它对输出应用进一步的转换):

    ml_transform(model, dtest_spark)
    
    # Source:   table<sparklyr_tmp_cc651477ec7> [?? x 6]
    # Database: spark_connection
      text                                tokens     myvocab   rpcol   prcol   pcol
      <chr>                               <list>     <list>    <list>  <list> <dbl>
    1 Chinese Chinese Chinese Tokyo Japan <list [5]> <dbl [6]> <dbl [… <dbl …     0
    2 random stuff                        <list [2]> <dbl [6]> <dbl [… <dbl …     1
    

    交叉验证

    示例中数据不足,但你交叉验证和拟合超参数如下所示:

    # dontrun
    ml_cross_validator(
      dtrain_spark,
      pipeline, 
      list(nb=list(smoothing=list(0.8, 1.0))),  # Note that name matches UID
      evaluator=evaluator)
    

    注意事项

    • 请记住,Spark 的多项朴素贝叶斯实现 considers only binary feature (0 or not 0)
    • 如果您将PipelinesVector 列一起使用(不是基于formula 的调用),我强烈建议您使用标准化(默认)列名:

      • label 用于因变量。
      • features 用于组装的自变量。
      • rawPredictionpredictionprobability 分别用于原始预测、预测和概率列。

    【讨论】:

    • 不用担心。感谢您的精确!你对你提到的参数调整有一些想法吗?谢谢!
    • 真的很棒的答案!当之无愧的赏金我的朋友:)
    • @ℕʘʘḆḽḘ 你有什么特别的想法吗?它是否适用于ft_tokenizer 的输出?什么特别不好用? Spark 复杂类型并不完全对 R 友好...
    • 我的意思是在这个例子中可能只是像mutate(myflag = text %rlike% 'China)
    • 您可以执行类似my_sql_transformer &lt;- ft_dplyr_transformer(sc, dtrain_spark %&gt;% mutate(myflag = text %rlike% 'China')) 的操作,它会为您生成SQLTransformer,并且您可以将my_sql_transformer 作为流水线中的一个阶段。不过,您必须将其作为第一阶段,因为 dplyr 明确说明了列选择(即它不会生成 SELECT *)。如果您觉得这种行为阻碍了很多用例,请随时在 repo 上打开一个问题。您还可以按照@user6910411 的建议显式定义 SQL 转换器。
    猜你喜欢
    • 2019-10-01
    • 2023-02-05
    • 2018-10-23
    • 1970-01-01
    • 2019-04-19
    • 2020-05-21
    • 1970-01-01
    • 2019-11-08
    相关资源
    最近更新 更多