亲爱的大家,
我希望我可以询问您关于预测任务的专业知识在R/Tidymodels。我打算预测跑步者的受伤情况。的预测所依据的每日/每周训练数据为从而在几个时间框架内嵌套在单个运行程序中个月。这让我考虑多层模型——多层二进制逻辑回归(MLBLR)。
由于数据也很不平衡,我进一步尝试参与通过SMOTE重新采样。因为一半的跑步者没有受伤而另一半,基本上只有一个,我也不确定这次任务的成功,因为不会有或只有一次受伤训练集中每个跑步者的实例作为重新采样的基础,因此在测试集中没有受伤的例子观察试验组内损伤情况。这就是SMOTE重新采样很可能是不可能的。
到目前为止,我试图通过MLBLR手动预测伤害重采样,只适应预测概率阈值,用结果只因为负面的预测不平衡的天性。可以理解,我没能重新取样在这种情况下,我是否应该考虑其他方法,如例如,欠采样非伤害实例或是否有任何特定的的重新采样过程(优选合成数据创建)多层数据,考虑嵌套结构
?我进一步尝试在首选中实现多层建模Tidymodel工作流,因为重新采样也很容易。因此,我首先看了"多层模式">包诱导工作流的多级引擎(lme4)。其次,我努力使使用多个模型结构通过嵌套由每个运行器然后不幸的是,我只得到了后者工作方法。前者,我很可能错误地使用了"stan-glmer">作为引擎(代码1),后者,我通过混合结果工作简单过采样(截图2 -)。第三,我不确定是否还要考虑拟合广义线性模型通过Tidymodels中的嵌入包使用混合模型。
我将非常感激听到你对这个问题的看法,特别是如何处理这个问题,实现多层次模型+重新采样Tidymodels工作流提前谢谢你。
亲切的问候!
multilevelmod: https://github.com/tidymodels/multilevelmod许多型号:https://r4ds.had.co.nz/many-models.htmlhttps://embed.tidymodels.org/articles/Applications/GLM.html
代码1:
mlbr_mod % set_engine("stan-glmer") # Recipe: mlbr_mod_recipe % step_dummy(all_nominal_predictors()) %>% step_string2factor(Runner) %>% step_smote(NewRRI, over_ratio =0.5) mlbr_mod_workflow % add_recipe(mlbr_mod_recipe) %>% add_model(mlbr_mod, formula = NewRRI ~ . -Runner + (1|Runner)) # Fit the model: mlbr_mod_workflow %>% fit(data = RunningData_train) # Train on original set and test on test set using last_fit() mlbr_last_fit % last_fit(RunningData_splits, metrics = metric_set(bal_accuracy, accuracy, f_meas, precision, roc_auc,sensitivity, recall, kap)) # Performance on test set: mlbr_metrics % collect_metrics() mlbr_metrics
代码在我尝试拟合模型的步骤失败。这给出错误消息,提示不能对不存在的列进行子集
- X列"患者"不存在。输入数据的结构如下:
Runner - factor: A1, A1, A1, B1, B1, B1, C1, C1, C1 ... (=IDs) NewRRI - factor: 0, 0, 1, 0, 0, 0, 0, 0, 0 ... Distance - numeric:340,500,734,110,389,766,833,420,1100 ... HR - numeric: 120,110,130,142,98, 112,104,117,130 ... Gender - factor: Male,Female,Male,Male,Male,Female,Male,Female,Female, ... Age - numeric: 23, 36, 56, 35, 67, 24, 52, 39, 29, ... BMI - numeric: 18, 20, 21, 25, 23, 24, 21, 22, 20, ... PreviousRRI -factor:0, 0, 1, 0, 0, 1, 1, 0, 0, ...
编辑(可复制示例):
Df <- tibble::tribble(
~year_week,~Runner,~NewRRI,~Distance, ~HR, ~Gender,~Age,~BMI,~PreviousRRI,
"2019-41", "M01" , 0, 5000, 120, "Male", 23, 18, 1,
"2019-41", "M02" , 0, 6000, 125,"Female", 36, 20, 0,
"2019-41", "M03" , 0, 8000, 130, "Male", 56, 21, 0,
"2019-42", "M01" , 0, 5500, 122, "Male", 23, 18, 1,
"2019-42", "M02" , 0, 7000, 128,"Female", 36, 20, 0,
"2019-42", "M03" , 0, 15000, 132, "Male", 56, 21, 0,
"2019-43", "M01" , 1, 3000, 120, "Male", 23, 18, 1,
"2019-43", "M02" , 0, 9000, 127,"Female", 36, 20, 0,
"2019-43", "M03" , 0, 9500, 131, "Male", 56, 21, 0,
"2019-44", "M01" , 0, 15000, 125, "Male", 23, 18, 1,
"2019-44", "M02" , 0, 9000, 127,"Female", 36, 20, 0,
"2019-44", "M03" , 0, 9500, 131, "Male", 56, 21, 0,
) %>%
mutate(Gender = as.factor(Gender),
PreviousRRI = as.factor(PreviousRRI),
NewRRI = as.factor(NewRRI),
Runner = as.factor(Runner))
library(tidyverse)
library(tidymodels)
library(multilevelmod)
library(themis)
Df <- Df %>% arrange(year_week)
Df_splits <- initial_time_split(Df, prop = 0.8)
RunningData_train <- training(Df_splits)
RunningData_test <- testing(Df_splits)
# Now apply original code
我得到以下错误信息:
Error: All columns selected for the step should be numeric
I am not sure what to change within the code to avoid this error message?
如果这不起作用,具有许多模型结构的替代方法很可能也有其局限性,因为运行程序嵌套在"nest()"并且各自的模型被映射到每个嵌套的单个跑步者,所以我猜这也不是一个可行的策略来模仿多层结构?
最后,我找到了这篇关于"SMOTE-NC/encp"的文章。使SMOTE算法的应用成为可能,但很可能存在一些缺点,因为新数据会添加到现有的Runner/Patient id上:
https://arxiv.org/abs/2103.07612
再次感谢您的帮助和考虑,非常感谢。亲切的问候!
看起来是您的食谱顺序导致了问题。首先是step_dummy,因此它将'Runner'更改为Runner_M02和Runner_M03
颠倒顺序将允许你使用它。为SMOTE提供足够的样本是另一个问题,也许您可以使用step_upsample()或step_downsample()
而且,看起来你已经有了因子,所以你实际上不需要这一步。
我从未使用过glm-stan,所以我使用lmer制作了这个示例来展示引导(并将结果更改为数字变量)。
model_spec <- linear_reg() %>% set_engine("lmer")
model_rec <- recipe(Distance ~ ., data = RunningData_train) %>%
step_dummy(all_nominal_predictors()) #%>% #smote would work with a larger dataset
step_smote(NewRRI, over_ratio =0.5)
model_rec %>% prep() %>% juice() %>% glimpse()
mixed_model_wf <- workflow() %>%
add_model(model_spec, formula = Distance ~ . -Runner + (1|Runner)) %>%
add_variables(outcomes = Distance, predictors = colnames(RunningData_train %>% dplyr::select(-Distance)))
fit1 <- fit(mixed_model_wf, RunningData_train)
boots <- bootstraps(Df)
fit2_boots <- fit_resamples(mixed_model_wf, boots)
fit2_boots %>% collect_metrics()