# Regression: Diamonds

```{r, load-packages, message = FALSE, warning = FALSE}
library(ggplot2)
library(rsample)
library(caret)
library(rpart)
library(rpart.plot)
library(purrr)
```

```{r}
diamonds
```

```{r}
set.seed(42)
diamonds = diamonds[sample(nrow(diamonds), size = 2500), ]
diamonds$carat = jitter(diamonds$carat)
diamonds$cut = factor(diamonds$cut, ordered = FALSE)
diamonds$color = factor(diamonds$color, ordered = FALSE)
diamonds$clarity = factor(diamonds$clarity, ordered = FALSE)
```

```{r}
diamonds
```

```{r}
set.seed(1)

# test-train split
dmnd_tst_trn_split = initial_split(diamonds, prop = 0.80)
dmnd_trn = training(dmnd_tst_trn_split)
dmnd_tst = testing(dmnd_tst_trn_split)

# estimation-validation split
dmnd_est_val_split = initial_split(dmnd_trn, prop = 0.80)
dmnd_est = training(dmnd_est_val_split)
dmnd_val = testing(dmnd_est_val_split)
```

```{r}
dmnd_trn %>% 
  ggplot(aes(x = price)) + 
  geom_histogram(bins = 30)
```

```{r}
dmnd_trn %>% 
  ggplot(aes(x = carat, y = price)) + 
  geom_point()
```

```{r}
calc_rmse = function(actual, predicted) {
  sqrt(mean( (actual - predicted) ^ 2) )
}
```

```{r}
lm_fit   = lm(price ~ carat, data = dmnd_est)
knn_fit  = knnreg(price ~ carat, data = dmnd_est)
tree_fit = rpart(price ~ carat, data = dmnd_est)
```

```{r}
lm_fit
```

```{r}
knn_fit
```

```{r}
tree_fit
```

```{r}
rpart.plot(tree_fit)
```

```{r}
calc_rmse(actual = dmnd_val$price, predicted = predict(lm_fit, dmnd_val))
calc_rmse(actual = dmnd_val$price, predicted = predict(knn_fit, dmnd_val))
calc_rmse(actual = dmnd_val$price, predicted = predict(tree_fit, dmnd_val))
```

```{r, fig.height = 4, fig.width = 12}
par(mfrow = c(1, 3))

plot(predict(lm_fit, dmnd_val), dmnd_val$price,
     xlim = c(0, 20000), ylim = c(0, 20000), pch = 20, col = "darkgrey",
     xlab = "Predicted", ylab = "Actual",
     main = "Linear Model")
abline(a = 0, b = 1, col = "green")
grid()

plot(predict(knn_fit, dmnd_val), dmnd_val$price,
     xlim = c(0, 20000), ylim = c(0, 20000), pch = 20, col = "darkgrey",
     xlab = "Predicted", ylab = "Actual",
     main = "KNN Model")
abline(a = 0, b = 1, col = "blue")
grid()

plot(predict(tree_fit, dmnd_val), dmnd_val$price,
     xlim = c(0, 20000), ylim = c(0, 20000), pch = 20, col = "darkgrey",
     xlab = "Predicted", ylab = "Actual",
     main = "Tree Model")
abline(a = 0, b = 1, col = "orange")
grid()
```

```{r}
for (k in 1:200) {
  # fit knn model to estimation data
  # make predictions with knn model
  # calculate validation rmse with knn model
  # store results
}
```

```{r}
k = 1:200
knn_mods = map(k, ~knnreg(price ~ carat, data = dmnd_est, k = .x))
knn_preds = map(knn_mods, predict, dmnd_val)
knn_val_rmse = map_dbl(knn_preds, calc_rmse, actual = dmnd_val$price)
```

```{r}
plot(x = k, y = knn_val_rmse, type = "b", col = "darkred", ylab = "Validation RMSE")
grid()
```

```{r}
min(knn_val_rmse)
which.min(knn_val_rmse)
```

```{r, fig.height = 6, fig.width = 10}
knn_plot = data.frame(
  carat = seq(0, 4, by = 0.00001)
)

plot(price ~ carat, data = dmnd_est, pch = 20, col = "grey")
grid()

# lines(x = knn_plot$carat,
#       y = predict(lm_fit, knn_plot),
#       col = "black", lwd = 2)
# 
# lines(x = knn_plot$carat,
#       y = predict(tree_fit, knn_plot),
#       col = "dodgerblue", lwd = 2)

lines(x = knn_plot$carat,
      y = predict(knnreg(price ~ carat, data = dmnd_est, k = 1), knn_plot),
      col = "darkorange", lwd = 1)

lines(x = knn_plot$carat,
      y = predict(knnreg(price ~ carat, data = dmnd_est, k = 67), knn_plot),
      col = "dodgerblue", lwd = 1)

lines(x = knn_plot$carat,
      y = predict(knnreg(price ~ carat, data = dmnd_est, k = 200), knn_plot),
      col = "black", lwd = 1)
```

```{r}
lm_fit_all   = lm(price ~ ., data = dmnd_est)
knn_fit_all  = knnreg(price ~ ., data = dmnd_est)
tree_fit_all = rpart(price ~ ., data = dmnd_est)
```

```{r}
lm_fit_all
```

```{r}
knn_fit_all
```

```{r}
tree_fit_all
```

```{r}
rpart.plot(tree_fit_all)
```

```{r}
calc_rmse(dmnd_val$price, predicted = predict(lm_fit_all, dmnd_val))
calc_rmse(dmnd_val$price, predicted = predict(knn_fit_all, dmnd_val))
calc_rmse(dmnd_val$price, predicted = predict(tree_fit_all, dmnd_val))
```

```{r, fig.height = 4, fig.width = 12}
par(mfrow = c(1, 3))

plot(predict(lm_fit_all, dmnd_val), dmnd_val$price,
     xlim = c(0, 20000), ylim = c(0, 20000), pch = 20, col = "darkgrey",
     xlab = "Predicted", ylab = "Actual",
     main = "Linear Model")
abline(a = 0, b = 1, col = "green")
grid()

plot(predict(knn_fit_all, dmnd_val), dmnd_val$price,
     xlim = c(0, 20000), ylim = c(0, 20000), pch = 20, col = "darkgrey",
     xlab = "Predicted", ylab = "Actual",
     main = "KNN Model")
abline(a = 0, b = 1, col = "blue")
grid()

plot(predict(tree_fit_all, dmnd_val), dmnd_val$price,
     xlim = c(0, 20000), ylim = c(0, 20000), pch = 20, col = "darkgrey",
     xlab = "Predicted", ylab = "Actual",
     main = "Tree Model")
abline(a = 0, b = 1, col = "orange")
grid()
```

```{r}
knn_mods_all = map(k, ~knnreg(price ~ ., data = dmnd_est, k = .x))
knn_preds_all = map(knn_mods_all, predict, dmnd_val)
knn_val_rmse_all = map_dbl(knn_preds_all, calc_rmse, actual = dmnd_val$price)
```

```{r}
plot(x = k, y = knn_val_rmse_all, type = "b", col = "darkred", ylab = "Validation RMSE")
grid()
```

```{r}
min(knn_val_rmse_all)
which.min(knn_val_rmse_all)
```
