【发布时间】:2019-06-27 05:11:15
【问题描述】:
我目前正在 R 中处理 For 循环。如果我对自己的数据运行 For 循环,则需要很长时间,我相信是因为我在代码中做了一些低效的事情。你能帮我改进一下吗?
# Loop through the samples, explaining one instance at a time.
shap_values <- vector("list", nrow(X)) # initialize the results list.
system.time({
for (i in seq_along(shap_values)) {
set.seed(224)
shap_values[[i]] <- iml::Shapley$new(predictor, x.interest = X[i, ],sample.size = 30)$results
shap_values[[i]]$predicted_value <- iml::Shapley$new(predictor, x.interest = X[i, ],sample.size = 30)$y.hat.interest
shap_values[[i]]$sample_num <- i # identifier to track our instances.
}
data_shap_values <- dplyr::bind_rows(shap_values) # collapse the list.
})
我相信我的问题出在
shap_values[[i]]$sample_num
变量,因为我在那里重做之前的计算
shap_values[[i]]$predicted_value
变量。我添加该变量的原因是因为我需要
$y.hat.interest
作为新数据框的一部分(称为“shap_values”,后来称为“data_shap_values”)。
可重复的示例:(从“这是重要的部分:)开始:)
#Example Shapley
#https://cran.r-project.org/web/packages/iml/vignettes/intro.html
data("Boston", package = "MASS")
head(Boston)
set.seed(42)
#install.packages("iml")
library("iml")
library("randomForest")
data("Boston", package = "MASS")
rf = randomForest(medv ~ ., data = Boston, ntree = 50)
# We create a Predictor object, that holds the model and the data.
# The iml package uses R6 classes: New objects can be created by calling Predictor$new()
X = Boston[which(names(Boston) != "medv")]
predictor = Predictor$new(rf, data = X, y = Boston$medv)
# Feature Importance
## Shifting each future, and measring how much the performance drops ##
imp = FeatureImp$new(predictor, loss = "mae")
plot(imp)
# Shapley value. Assume that for 1 data point, the feature values play a game together, in which
# they get the prediction as payout. Tells us how fairly distibute the payout among the feature values.
View(X)
shapley = Shapley$new(predictor, x.interest = X[1,])
shapley$plot()
# Reuse the object to explain other data points
shapley$explain(x.interest = X[2,])
shapley$plot()
# Results in data.frame form can be extracted like this:
results = shapley$results
head(results)
# THIS IS THE IMPORTANT PART:
# It might make sense for testing, to reduce the data:
X = X[1:10,]
# Loop through the samples, explaining one instance at a time.
shap_values <- vector("list", nrow(X)) # initialize the results list.
system.time({
for (i in seq_along(shap_values)) {
set.seed(224)
shap_values[[i]] <- iml::Shapley$new(predictor, x.interest = X[i, ],sample.size = 30)$results
shap_values[[i]]$predicted_value <- iml::Shapley$new(predictor, x.interest = X[i, ],sample.size = 30)$y.hat.interest
shap_values[[i]]$sample_num <- i # identifier to track our instances.
}
data_shap_values <- dplyr::bind_rows(shap_values) # collapse the list.
})
更新
根据@Ralf Stubner 的要求,分析 for 循环:
【问题讨论】:
-
您是否对代码进行了分析以识别瓶颈?
-
嗨拉尔夫,感谢您的回复。不,我没有,我不知道我该怎么做
-
请参阅blog.rstudio.com/2016/05/23/profiling-with-rstudio-and-profvis 了解集成到 RStudio 中的简单方法(参见“配置文件”菜单)。
-
感谢更新了我的答案。但我仍然坚持如何让它更快,除非新的见解
标签: r for-loop optimization