使用存储为矩阵或 data.frame 的数据,rstan 会更快地拟合模型吗?
Will rstan fit models faster with data stored as matrix or data.frame?
我正在通过 rethinking
库中的 map2stan
函数使用 rstan
拟合一系列 多级逻辑回归 。一切正常,模型都正确拟合并收敛。但是,我正在处理的数据集非常大,因此 运行 适合每个模型的时间相当长(以天为单位)。因此,我正在寻找我能找到的任何潜在的加速。
现在,我的数据存储在 data.frames
中,所有数据都具有相似的结构,比例连续变量和分类变量分为 0/1 虚拟变量。例如:
> str(dcc.s.dummy)
'data.frame': 85604 obs. of 34 variables:
$ COST_DIST_ECOTONE : num -0.594 -0.593 -0.596 -0.591 -0.591 ...
$ COST_DIST_HEA : num -0.663 -0.66 -0.672 -0.652 -0.65 ...
$ COST_DIST_HISTOSOLS : num -2.09 -2.09 -2.09 -2.09 -2.09 ...
$ COST_DIST_MEDSTR : num -0.178 -0.176 -0.177 -0.176 -0.174 ...
$ COST_DIST_RIV_COAST : num 0.34 0.337 0.335 0.341 0.338 ...
$ DEM30_ASP_RE_2 : num 0 0 0 0 0 1 0 0 0 0 ...
$ DEM30_ASP_RE_3 : num 0 0 0 0 0 0 0 0 0 0 ...
$ DEM30_ASP_RE_4 : num 1 0 0 1 0 0 0 0 0 1 ...
$ DEM30_ASP_RE_5 : num 0 1 0 0 1 0 0 0 0 0 ...
$ DEM30_M : num 2.19 2.19 2.2 2.18 2.19 ...
$ DEM30_SLOPE : num -0.797 -0.782 -0.839 -0.817 -0.76 ...
$ DRIFT_THICK_1 : num 0 0 0 0 0 0 0 0 0 0 ...
$ DRIFT_THICK_2 : num 0 0 0 0 0 0 0 0 0 0 ...
$ DRIFT_THICK_3 : num 1 1 1 1 1 1 1 1 1 1 ...
$ DRIFT_THICK_4 : num 0 0 0 0 0 0 0 0 0 0 ...
$ LOC_REL_RE : num -0.862 -0.857 -0.857 -0.845 -0.84 ...
$ LOC_SD_SLOPE : num -1.08 -1.08 -1.08 -1.06 -1.06 ...
$ SITE_NONSITE : int 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_DRAINAGE_RE_2: num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_DRAINAGE_RE_3: num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_DRAINAGE_RE_4: num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_DRAINAGE_RE_5: num 0 1 1 0 1 1 0 0 0 0 ...
$ SSURGO_ESRI_DRAINAGE_RE_6: num 1 0 0 1 0 0 1 1 1 1 ...
$ SSURGO_ESRI_DRAINAGE_RE_7: num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_EROSION_RE_2 : num 1 0 0 1 0 0 1 1 1 1 ...
$ SSURGO_ESRI_EROSION_RE_3 : num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_EROSION_RE_4 : num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_EROSION_RE_5 : num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_LOC_DIV : num -0.184 -0.22 -0.168 -0.316 -0.322 ...
$ SSURGO_ESRI_NATIVEVEG_2 : num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_NATIVEVEG_3 : num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_NATIVEVEG_4 : num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_PH : num 0.86 0.632 0.518 0.86 0.518 ...
$ WATERSHED_INDEX : int 3 3 3 3 3 3 3 3 3 3 ...
使用 data.matrix(frame, rownames.force = NA)
或类似方法将 data.frame
转换为 matrix
会减少 rstan
/ [=13= 所花费的时间] 完成采样并拟合模型?
我已经 运行 在许多地方讨论了在矩阵上执行的操作通常比在 data.frames 上执行的操作更快的论点。 Rstan
虽然在 C++ 中完成了所有繁重的工作,但据我所知,作为其操作的一部分,它已经在进行类似的转换。如有任何见解或建议,我们将不胜感激。
如果 运行时间是天数,编译时间大约是一分钟,你不会注意到首先在 R 端做任何事情所花费的时间,包括是否数据存储为矩阵或 data.frame.
换句话说,在这种情况下你应该更担心,更多的是我的rethinking::map2stan
生成的Stan代码是否低效而不是rethinking[=20中的数据处理代码是否=] 效率低下。由于 rethinking 未针对您的用例进行优化,因此 rstanarm、brms 或手写 Stan 代码 --- 特别是使用线性代数而不是 rethinking::map2stan
生成的更多标量代数代码 --- 会 运行 快很多。
我正在通过 rethinking
库中的 map2stan
函数使用 rstan
拟合一系列 多级逻辑回归 。一切正常,模型都正确拟合并收敛。但是,我正在处理的数据集非常大,因此 运行 适合每个模型的时间相当长(以天为单位)。因此,我正在寻找我能找到的任何潜在的加速。
现在,我的数据存储在 data.frames
中,所有数据都具有相似的结构,比例连续变量和分类变量分为 0/1 虚拟变量。例如:
> str(dcc.s.dummy)
'data.frame': 85604 obs. of 34 variables:
$ COST_DIST_ECOTONE : num -0.594 -0.593 -0.596 -0.591 -0.591 ...
$ COST_DIST_HEA : num -0.663 -0.66 -0.672 -0.652 -0.65 ...
$ COST_DIST_HISTOSOLS : num -2.09 -2.09 -2.09 -2.09 -2.09 ...
$ COST_DIST_MEDSTR : num -0.178 -0.176 -0.177 -0.176 -0.174 ...
$ COST_DIST_RIV_COAST : num 0.34 0.337 0.335 0.341 0.338 ...
$ DEM30_ASP_RE_2 : num 0 0 0 0 0 1 0 0 0 0 ...
$ DEM30_ASP_RE_3 : num 0 0 0 0 0 0 0 0 0 0 ...
$ DEM30_ASP_RE_4 : num 1 0 0 1 0 0 0 0 0 1 ...
$ DEM30_ASP_RE_5 : num 0 1 0 0 1 0 0 0 0 0 ...
$ DEM30_M : num 2.19 2.19 2.2 2.18 2.19 ...
$ DEM30_SLOPE : num -0.797 -0.782 -0.839 -0.817 -0.76 ...
$ DRIFT_THICK_1 : num 0 0 0 0 0 0 0 0 0 0 ...
$ DRIFT_THICK_2 : num 0 0 0 0 0 0 0 0 0 0 ...
$ DRIFT_THICK_3 : num 1 1 1 1 1 1 1 1 1 1 ...
$ DRIFT_THICK_4 : num 0 0 0 0 0 0 0 0 0 0 ...
$ LOC_REL_RE : num -0.862 -0.857 -0.857 -0.845 -0.84 ...
$ LOC_SD_SLOPE : num -1.08 -1.08 -1.08 -1.06 -1.06 ...
$ SITE_NONSITE : int 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_DRAINAGE_RE_2: num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_DRAINAGE_RE_3: num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_DRAINAGE_RE_4: num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_DRAINAGE_RE_5: num 0 1 1 0 1 1 0 0 0 0 ...
$ SSURGO_ESRI_DRAINAGE_RE_6: num 1 0 0 1 0 0 1 1 1 1 ...
$ SSURGO_ESRI_DRAINAGE_RE_7: num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_EROSION_RE_2 : num 1 0 0 1 0 0 1 1 1 1 ...
$ SSURGO_ESRI_EROSION_RE_3 : num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_EROSION_RE_4 : num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_EROSION_RE_5 : num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_LOC_DIV : num -0.184 -0.22 -0.168 -0.316 -0.322 ...
$ SSURGO_ESRI_NATIVEVEG_2 : num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_NATIVEVEG_3 : num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_ESRI_NATIVEVEG_4 : num 0 0 0 0 0 0 0 0 0 0 ...
$ SSURGO_PH : num 0.86 0.632 0.518 0.86 0.518 ...
$ WATERSHED_INDEX : int 3 3 3 3 3 3 3 3 3 3 ...
使用 data.matrix(frame, rownames.force = NA)
或类似方法将 data.frame
转换为 matrix
会减少 rstan
/ [=13= 所花费的时间] 完成采样并拟合模型?
我已经 运行 在许多地方讨论了在矩阵上执行的操作通常比在 data.frames 上执行的操作更快的论点。 Rstan
虽然在 C++ 中完成了所有繁重的工作,但据我所知,作为其操作的一部分,它已经在进行类似的转换。如有任何见解或建议,我们将不胜感激。
如果 运行时间是天数,编译时间大约是一分钟,你不会注意到首先在 R 端做任何事情所花费的时间,包括是否数据存储为矩阵或 data.frame.
换句话说,在这种情况下你应该更担心,更多的是我的rethinking::map2stan
生成的Stan代码是否低效而不是rethinking[=20中的数据处理代码是否=] 效率低下。由于 rethinking 未针对您的用例进行优化,因此 rstanarm、brms 或手写 Stan 代码 --- 特别是使用线性代数而不是 rethinking::map2stan
生成的更多标量代数代码 --- 会 运行 快很多。