为什么 ml_create_dummy_variables 在 sparklyr 中不显示新的虚拟变量列

我在尝试在 sparklyr 中创建模型矩阵。有一个函数 ml_create_dummy_variables() 可以一次为一个分类变量创建虚拟变量。据我所知,没有像 model.matrix() 那样一次性创建模型矩阵的等效函数。使用 ml_create_dummy_variables() 很简单,但我不知道为什么新的虚拟变量没有存储在 Spark 数据框中。

考虑以下示例:

    ### 创建虚拟数据以了解在 sparklyr 中模型矩阵公式的工作原理
v1 <- sample( LETTERS[1:4], 50000, replace=TRUE, prob=c(0.1, 0.2, 0.65, 0.05))
v2 <- sample( LETTERS[5:6], 50000, replace=TRUE, prob=c(0.7,0.3))
v3 <- sample( LETTERS[7:10], 50000, replace=TRUE, prob=c(0.3, 0.2, 0.4, 0.1))
v4 <- sample( LETTERS[11:15], 50000, replace=TRUE, prob=c(0.1, 0.1, 0.3, 0.05,.45))
v5 <- sample( LETTERS[16:17], 50000, replace=TRUE, prob=c(0.4,0.6))
v6 <- sample( LETTERS[18:21], 50000, replace=TRUE, prob=c(0.1, 0.1, 0.65, 0.15))
v7 <- sample( LETTERS[22:26], 50000, replace=TRUE, prob=c(0.1, 0.2, 0.65, 0.03,.02))
v8 <- rnorm(n=50000,mean=.5,sd=.1)
v9 <- rnorm(n=50000,mean=5,sd=3)
v10 <- rnorm(n=50000,mean=3,sd=.5)
response <- rnorm(n=50000,mean=10,sd=2)
dat <- data.frame(v1,v2,v3,v4,v5,v6,v7,v8,v9,v10,response)
write.csv(dat,file='fake_dat.csv',row.names = FALSE)
# 将 "fake_dat.csv" 推送到 hdfs
library(dplyr)
library(sparklyr)
# 配置 Spark 会话并连接
config <- spark_config()
config$`sparklyr.shell.driver-memory` <- "2G" # 根据数据大小进行调整
config$`sparklyr.shell.executor-memory` <- "2G"
sc <-  spark_connect(master='yarn-client', spark_home='/usr/hdp/2.5.0.0-1245/spark',config = config)
sc
# 也可以将 spark_home 设置为 ‘/usr/hdp/current/spark-client’
# 从 hdfs 读取数据
df <- spark_read_csv(sc,name='fdat',path='hdfs://pnhadoop/user/stc004/fake_dat.csv')
# 创建 Spark 表
dat <- tbl(sc,'fdat')
# 创建虚拟变量
ml_create_dummy_variables(x=dat,'v1', reference = NULL)

现在我从 sparklyr 得到以下通知:

Source:   query [5e+04 x 15]
Database: spark connection master=yarn-client app=sparklyr local=FALSE
     v1    v2    v3    v4    v5    v6    v7        v8        v9      v10
  <chr> <chr> <chr> <chr> <chr> <chr> <chr>     <dbl>     <dbl>    <dbl>
1      A     F     I     O     Q     T     X 0.4518162 12.281566 3.915094
2      C     E     H     L     Q     T     X 0.3967605  2.131341 3.373347
3      C     F     I     O     P     S     W 0.4458047  7.167670 2.737003
4      C     E     G     M     P     T     X 0.4822457  5.946978 2.375309
5      B     E     H     L     P     U     W 0.4756011  9.456327 2.406996
6      C     F     H     L     P     U     X 0.5064916  2.920591 3.111827
7      C     F     I     O     Q     T     W 0.3060585  1.611517 2.242328
8      B     F     J     L     Q     T     V 0.6238052  9.821750 2.670400
9      C     E     I     O     Q     U     X 0.4249922  2.141794 3.020958
10     B     F     G     K     P     T     X 0.5348334  1.461034 3.057635
# ... with 4.999e+04 more rows, and 5 more variables: response <dbl>,
#   v1_A <dbl>, v1_B <dbl>, v1_C <dbl>, v1_D <dbl>

当我检查列数时,新的虚拟变量并没有出现。

> colnames(dat) 
 [1] "v1"       "v2"       "v3"       "v4"       "v5"       "v6" 
 [7] "v7"       "v8"       "v9"       "v10"      "response"
>

为什么会这样?此外,有没有一种简单的方法可以一次性转换所有列?我处理的数据集有超过1000个变量,所以我需要一种快速的方法来做这件事。我尝试过创建循环,但那没有任何效果:

for(i in 1:7){
  ml_create_dummy_variables(x=dat,colnames(dat)[i],reference=NULL)
}

回答:

ml_create_dummy_variables 不会修改现有表,而是创建新表,你的代码只是丢弃了结果。你需要存储结果:

tmp <- ml_create_dummy_variables(x=dat,'v1', reference = NULL)

此外,有没有一种简单的方法可以一次性转换所有列?我处理的数据集有超过1000个变量,所以我需要一种快速的方法来做这件事

使用循环或 Reduce 函数是可以的,但没有快速的方法来实现。为了创建虚拟变量,你必须首先[确定所有可能的水平,这需要对每个变量进行完整的列扫描

此外,对于超过1000列的数据集,尤其是当水平数很多时,你会开始遇到Spark优化器的不同限制。sparklyr(与使用Vector UDT的Spark ML不同)会展开所有列,这种方法扩展性不佳。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注