I've trained a random forests for a regression problem. Now, I want to check if the model is not overfitted. I have tuned the parameters and then compared the R-Squared of Train and Test dataset as below

test_predict <- model%>% predict(test_data) %>% predictions
R2_test <- 1 - (sum((test_actual-test_predict )^2)/sum((test_actual-mean(test_actual))^2))

train_predict <- model%>% predict(train_data) %>% predictions
R2_train <- 1 - (sum((train_actual-train_predict )^2)/sum((train_actual-mean(train_actual))^2))

The R-Squared on train dataset is significantly higher (close to 0.9) which made think the model is overfit. Then I came across to this question Random Forest - How to handle overfitting. It is saying that predict(model, newdata=train) "treats your training data as if it was a new dataset, and runs the observations down each tree. This will result in an artificially close correlation between the predictions and the actuals, since the RF algorithm generally doesn't prune the individual trees, relying instead on the ensemble of trees to control overfitting."

I don't know what would be the best way to compare the performance of model between train and test dataset.


2 Answers 2


The gist of $R^2$ is that you compare your performance to a naïve model that always guesses the same value.

$$R^2 = 1-\dfrac{\sum\big(y_i - \hat y_i \big)^2}{\sum\big(y_i - \bar y\big)^2}$$

In the numerator, we subtract the predictions from our model from the observed value. The closer to the observed values are predictions are, the better.

The the denominator, we do the same, but we consider a model that always guesses the mean of the observed $y$ values. If you have no idea how to model the conditional expected value, the reasonable but naive model would always predict the unconditional expected value.

You know how to calculate the numerator and denominator in your software, so calculate them.

You are likely to be interested in how your model does out-of-sample (OOS), and that follows similar logic.

$$R^2_{OOS} = 1-\dfrac{\sum\big(y_{i, OOS} - \hat y_{i, OOS} \big)^2}{\sum\big(y_{i, OOS} - \bar y_{in}\big)^2}$$.

The trick is to keep the denominator as the square loss of a model that naively guesses the same value every time, and the value you guess is still the in-sample mean, since that's the model learned at training time. Don't use the out-of-sample $\bar y$, since you don't know it. (If you knew the $y_i$-values that you would need to calculate out-of-sample $\bar y$, you wouldn't need a model to predict those values. You'd just look them up and have perfect predictions.)

I discuss more here my thoughts on why the denominator should use the in-sample $\bar y$ instead of out-of-sample. As long as you divide by the same number, you will rank models in the same order, but using our-of-sample $\bar y$ seems to lack statistical motivation. Crucially, however, just squaring the Pearson correlation between the out-of-sample predictions and true observations is likely to miss crucial information, a topic I discuss here and demonstrate with pictures here.


Good afternoon!

  1. You have provided a good link in your post. It shows that you need

Why? Because it's Out Of Bag forecast (the OOB score is calculated using only a subset of decision trees not containing the OOB sample in their training dataset), as far as I know, so it's similar to cross-validation. Using

predict(model, newdata=train)

you will make predictions using train data and model trained on that data, which seems confusing and may provide unrealistically high model performance.

  1. I personally would pay attention to model performance on test, because model was fitted on train so it 'knows' train and will perform on train better.

  2. Is R-squared the metric you really want to work with? It just indicates the percentage of target variable variance explained by model. Since ML models are used for forecasting, the most concern is about (surprisingly!) the accuracy of forecast. So for regression problem people usually use RMSE, MAPE etc. which describe better the average error of forecast.

  • $\begingroup$ $$R^2 = \dfrac{n(RMSE)^2}{\sum\big(y_i - \bar y\big)^2}$$ Consequently, any comparison of models based on which has higher $R^2$ is equivalent to asking which model has lower $RMSE$. $\endgroup$
    – Dave
    Mar 16, 2022 at 14:15
  • $\begingroup$ Good point, I have never thought about comparison by $R^2$ as of comparison by RMSE just scaled with some constant multiple. However, it seems not to work so straightforward as comparing just RMSE when we compare train and test results, since sample variance of the target variable may differ in train and test. $\endgroup$
    – rsx
    Mar 16, 2022 at 15:39
  • $\begingroup$ Please refer to my answer for how to think about out-of-sample $R^2$. // I missed the $1-$ in my comment above, yes. $\endgroup$
    – Dave
    Mar 16, 2022 at 15:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.