<- "https://raw.githubusercontent.com/sebastiansauer/Lehre/main/data/tmdb-box-office-prediction/train.csv"
d_train_path <- "https://raw.githubusercontent.com/sebastiansauer/Lehre/main/data/tmdb-box-office-prediction/test.csv" d_test_path
tmdb02
Aufgabe
Wir bearbeiten hier die Fallstudie TMDB Box Office Prediction - Can you predict a movie’s worldwide box office revenue?, ein Kaggle-Prognosewettbewerb.
Ziel ist es, genaue Vorhersagen zu machen, in diesem Fall für Filme.
Die Daten können Sie von der Kaggle-Projektseite beziehen oder so:
Aufgabe
Reichen Sie bei Kaggle eine Submission für die Fallstudie ein! Berichten Sie den Kaggle-Score
Hinweise:
- Sie müssen sich bei Kaggle ein Konto anlegen (kostenlos und anonym möglich); alternativ können Sie sich mit einem Google-Konto anmelden.
- Berechnen Sie einen Entscheidungsbaum und einen Random-Forest.
- Tunen Sie nach Bedarf; verwenden Sie aber Default-Werte.
- Verwenden Sie Tidymodels.
Lösung
Vorbereitung
library(tidyverse)
library(tidymodels)
library(tictoc)
library(doParallel) # mehrere CPUs nutzen
library(finetune) # Tune Anova
<- read_csv(d_train_path)
d_train <- read_csv(d_test_path)
d_test
glimpse(d_train)
glimpse(d_test)
Rezept
Rezept definieren
<-
rec1 recipe(revenue ~ ., data = d_train) %>%
update_role(all_predictors(), new_role = "id") %>%
update_role(popularity, runtime, revenue, budget) %>%
update_role(revenue, new_role = "outcome") %>%
step_mutate(budget = ifelse(budget < 10, 10, budget)) %>%
step_log(budget) %>%
step_impute_knn(all_predictors())
rec1
Check das Rezept
<-
rec1_prepped prep(rec1, verbose = TRUE)
rec1_prepped
<-
d_train_baked %>%
rec1_prepped bake(new_data = NULL)
head(d_train_baked)
Die AV-Spalte sollte leer sein:
bake(rec1_prepped, new_data = head(d_test), all_outcomes())
%>%
d_train_baked map_df(~ sum(is.na(.)))
Keine fehlenden Werte mehr in den Prädiktoren.
Nach fehlenden Werten könnte man z.B. auch so suchen:
::describe_distribution(d_train_baked) datawizard
So bekommt man gleich noch ein paar Infos über die Verteilung der Variablen. Praktische Sache.
Das Test-Sample backen wir auch mal:
<-
d_test_baked bake(rec1_prepped, new_data = d_test)
%>%
d_test_baked head()
Kreuzvalidierung
<- vfold_cv(d_train,
cv_scheme v = 5,
repeats = 1)
Modelle
Baum
<-
mod_tree decision_tree(cost_complexity = tune(),
tree_depth = tune(),
mode = "regression")
Random Forest
<-
mod_rf rand_forest(mtry = tune(),
min_n = tune(),
trees = 1000,
mode = "regression") %>%
set_engine("ranger", num.threads = 4)
Workflows
<-
wf_tree workflow() %>%
add_model(mod_tree) %>%
add_recipe(rec1)
<-
wf_rf workflow() %>%
add_model(mod_rf) %>%
add_recipe(rec1)
Fitten und tunen
Um Rechenzeit zu sparen, kann man den Parameter grid
bei tune_grid()
auf einen kleinen Wert setzen. Der Default ist 10. Um gute Vorhersagen zu erzielen, sollte man den Wert tendenziell noch über 10 erhöhen.
Tree
Parallele Verarbeitung starten:
<- makePSOCKcluster(4) # Create 4 clusters
cl registerDoParallel(cl)
tic()
<-
tree_fit %>%
wf_tree tune_race_anova(
resamples = cv_scheme,
#grid = 2
)toc()
Hilfe zu tune_grid()
bekommt man hier.
tree_fit
Steht was in den .notes
?
".notes"]][[2]] tree_fit[[
Nein.
collect_metrics(tree_fit)
show_best(tree_fit)
Finalisieren
<-
best_tree_wf %>%
wf_tree finalize_workflow(select_best(tree_fit))
best_tree_wf
<-
tree_last_fit fit(best_tree_wf, data = d_train)
tree_last_fit
Vorhersage Test-Sample
predict(tree_last_fit, new_data = d_test)
RF
Fitten und Tunen
Um Rechenzeit zu sparen, kann man das Objekt, wenn einmal berechnet, abspeichern unter result_obj_path
auf der Festplatte und beim nächsten Mal importieren, das geht schneller als neu berechnen.
Das könnte dann z.B. so aussehen:
if (file.exists(result_obj_path)) {
<- read_rds(result_obj_path)
rf_fit else {
} tic()
<-
rf_fit %>%
wf_rf tune_grid(
resamples = cv_scheme)
toc()
}
Achtung Ein Ergebnisobjekt von der Festplatte zu laden ist gefährlich. Wenn Sie Ihr Modell verändern, aber vergessen, das Objekt auf der Festplatte zu aktualisieren, werden Ihre Ergebnisse falsch sein (da auf dem veralteten Objekt beruhend), ohne dass Sie durch eine Fehlermeldung von R gewarnt würden!
So kann man das Ergebnisobjekt auf die Festplatte schreiben:
#write_rds(rf_fit, file = "objects/tmbd_rf_fit1.rds")
Aber wir berechnen lieber neu:
tic()
<-
rf_fit %>%
wf_rf tune_grid(
resamples = cv_scheme
#grid = 2
)toc()
collect_metrics(rf_fit)
select_best(rf_fit)
Finalisieren
<-
final_wf %>%
wf_rf finalize_workflow(select_best(rf_fit))
<-
final_fit fit(final_wf, data = d_train)
<-
final_preds %>%
final_fit predict(new_data = d_test) %>%
bind_cols(d_test)
<-
submission %>%
final_preds select(id, revenue = .pred)
Abspeichern und einreichen:
write_csv(submission, file = "submission.csv")
Kaggle Score
Diese Submission erzielte einen Score von 2.7664 (RMSLE).
<- 2.7664 sol
Categories:
- ds1
- tidymodels
- statlearning
- tmdb
- trees
- num