1. Dataset: Housing price

df = read.csv("C:/Users/Momo/Desktop/Machine Learning/Housing.csv")

2. Tách dataset

# Tách biến mục tiêu y và các biến độc lập X
y <- df$price
X <- df[, !names(df) %in% "price"]

# Đặt seed để có thể tái lập kết quả
set.seed(123)

# Tạo chỉ mục để phân chia dữ liệu
train_indices <- sample(1:nrow(df), size = 0.8 * nrow(df))

# Tạo train set và test set
train_set <- df[train_indices, ]
test_set <- df[-train_indices, ]

3. DT model: Regression

library(rpart)
## Warning: package 'rpart' was built under R version 4.2.3
library(caret)
## Warning: package 'caret' was built under R version 4.2.3
## Loading required package: ggplot2
## Warning: package 'ggplot2' was built under R version 4.2.3
## Loading required package: lattice
## Warning: package 'lattice' was built under R version 4.2.3
# Xác định lưới các giá trị maxdepth để thử nghiệm
grid <- expand.grid(.maxdepth = 1:20)

# Thiết lập kiểm tra chéo (cross-validation)
control <- trainControl(method = "cv", number = 5)

# Chạy Grid Search với Cross-Validation
train_model <- train(price ~ ., data = train_set, method = "rpart2", 
                     trControl = control, tuneGrid = grid)

train_model
## CART 
## 
## 436 samples
##  12 predictor
## 
## No pre-processing
## Resampling: Cross-Validated (5 fold) 
## Summary of sample sizes: 348, 349, 349, 349, 349 
## Resampling results across tuning parameters:
## 
##   maxdepth  RMSE     Rsquared   MAE      
##    1        1644366  0.2275180  1254469.5
##    2        1563819  0.3103600  1170876.8
##    3        1468249  0.3883325  1112458.1
##    4        1442528  0.4148353  1060303.1
##    5        1398364  0.4489784  1046841.8
##    6        1389617  0.4526032  1027071.0
##    7        1365464  0.4706554  1000152.6
##    8        1360458  0.4761426   997696.3
##    9        1338287  0.4934489   972601.6
##   10        1367388  0.4769118  1001026.4
##   11        1352189  0.4871915   986719.4
##   12        1349728  0.4904161   985056.8
##   13        1361160  0.4873290   990948.4
##   14        1361160  0.4873290   990948.4
##   15        1361160  0.4873290   990948.4
##   16        1361160  0.4873290   990948.4
##   17        1361160  0.4873290   990948.4
##   18        1361160  0.4873290   990948.4
##   19        1361160  0.4873290   990948.4
##   20        1361160  0.4873290   990948.4
## 
## RMSE was used to select the optimal model using the smallest value.
## The final value used for the model was maxdepth = 9.
# Lấy ra giá trị max-depth tốt nhất
best_max_depth <- train_model$bestTune$.maxdepth
print(paste("Best max-depth:", best_max_depth))
## [1] "Best max-depth: "
# Dự đoán và đánh giá mô hình
predictions <- predict(train_model, test_set)
mse <- mean((test_set$price - predictions)^2)
mse
## [1] 2.001963e+12

4. Visualization

library(ggplot2)
# Biểu đồ phân tán cho giá thực tế và giá dự đoán
ggplot() +
  geom_point(aes(x = test_set$price, y = predictions), color = 'blue') +
  labs(title = "Biểu đồ phân tán giá nhà thực tế vs. dự đoán",
       x = "Giá nhà thực tế",
       y = "Giá nhà dự đoán") +
  theme_minimal()

library(scales)
## Warning: package 'scales' was built under R version 4.2.3
# Biểu đồ phân tán cho giá thực tế và giá dự đoán với giá trị đầy đủ
ggplot() +
  geom_point(aes(x = test_set$price, y = predictions), color = 'blue') +
  labs(title = "Biểu đồ phân tán giá nhà thực tế vs. dự đoán",
       x = "Giá nhà thực tế",
       y = "Giá nhà dự đoán") +
  scale_x_continuous(labels = comma) +
  scale_y_continuous(labels = comma) +
  theme_minimal()

5. Performance metrics

# Dự đoán trên tập huấn luyện
train_predictions <- predict(train_model, train_set)

# Dự đoán trên tập kiểm tra
test_predictions <- predict(train_model, test_set)

# Tính toán các chỉ số hiệu suất cho tập huấn luyện
train_mse <- mean((train_set$price - train_predictions)^2)
train_rmse <- sqrt(train_mse)
train_mae <- mean(abs(train_set$price - train_predictions))
train_r2 <- 1 - (sum((train_set$price - train_predictions)^2) / sum((train_set$price - mean(train_set$price))^2))
train_mape <- mean(abs((train_set$price - train_predictions) / train_set$price)) * 100

# Tính toán các chỉ số hiệu suất cho tập kiểm tra
test_mse <- mean((test_set$price - test_predictions)^2)
test_rmse <- sqrt(test_mse)
test_mae <- mean(abs(test_set$price - test_predictions))
test_r2 <- 1 - (sum((test_set$price - test_predictions)^2) / sum((test_set$price - mean(test_set$price))^2))
test_mape <- mean(abs((test_set$price - test_predictions) / test_set$price)) * 100

# In kết quả
cat("Training Set Performance:\n")
## Training Set Performance:
cat("MSE:", train_mse, "\n")
## MSE: 1.251941e+12
cat("RMSE:", train_rmse, "\n")
## RMSE: 1118902
cat("MAE:", train_mae, "\n")
## MAE: 805041.6
cat("R-squared:", train_r2, "\n")
## R-squared: 0.6378368
cat("MAPE:", train_mape, "%\n\n")
## MAPE: 18.11942 %
cat("Test Set Performance:\n")
## Test Set Performance:
cat("MSE:", test_mse, "\n")
## MSE: 2.001963e+12
cat("RMSE:", test_rmse, "\n")
## RMSE: 1414907
cat("MAE:", test_mae, "\n")
## MAE: 1058280
cat("R-squared:", test_r2, "\n")
## R-squared: 0.4445534
cat("MAPE:", test_mape, "%\n")
## MAPE: 24.61423 %

6. Decision tree plot

library(rpart.plot)
## Warning: package 'rpart.plot' was built under R version 4.2.3
# Vẽ cây quyết định
rpart.plot(train_model$finalModel, main = "Decision Tree Plot")

################################################################################
# Vẽ cây quyết định với nhiều tùy chọn để tùy chỉnh
rpart.plot(train_model$finalModel, 
           type = 4,                   # Loại plot để hiện tất cả các nút
           extra = 101,                # Hiển thị thông tin về số lượng mẫu tại mỗi nút
           under = TRUE,              # Hiển thị tên các lớp biến ở dưới cùng của các nút
           cex = 0.8,                  # Kích thước chữ
           main = "Decision Tree Plot") # Tiêu đề

7. Variables Important

# Tính toán độ quan trọng của các biến
importance <- varImp(train_model, scale = FALSE)

# Hiển thị độ quan trọng của các biến
importance
## rpart2 variable importance
## 
##                                  Overall
## airconditioningyes               1.58481
## stories                          1.46013
## area                             1.13645
## bathrooms                        0.92632
## parking                          0.89208
## bedrooms                         0.74806
## furnishingstatusunfurnished      0.58454
## prefareayes                      0.54833
## mainroadyes                      0.39517
## basementyes                      0.26479
## furnishingstatussemi-furnished   0.09635
## `furnishingstatussemi-furnished` 0.00000
## hotwaterheatingyes               0.00000
## guestroomyes                     0.00000
# Chuyển đổi dữ liệu quan trọng thành dataframe
importance_df <- as.data.frame(importance$importance)

# Thay đổi tên cột
importance_df$Variable <- rownames(importance_df)
names(importance_df) <- c("Importance", "Variable")

# Vẽ biểu đồ độ quan trọng
ggplot(importance_df, aes(x = reorder(Variable, Importance), y = Importance)) +
  geom_bar(stat = "identity") +
  coord_flip() +
  labs(title = "Độ Quan Trọng của Các Predictors",
       x = "Predictor",
       y = "Độ Quan Trọng") +
  theme_minimal()

################################################################################
library(ggplot2)
library(scales)

# Biểu đồ phân tán cho giá thực tế và giá dự đoán
ggplot(data = test_set, aes(x = price, y = predictions)) +
  geom_point(color = 'blue', alpha = 0.7, size = 3) +   # Chấm có màu xanh và độ mờ
  geom_smooth(method = "lm", color = "red", se = FALSE) + # Thêm đường hồi quy tuyến tính
  scale_x_continuous(labels = comma) +
  scale_y_continuous(labels = comma) +
  labs(title = "Biểu Đồ Phân Tán Giá Nhà Thực Tế vs. Dự Đoán",
       x = "Giá Nhà Thực Tế",
       y = "Giá Nhà Dự Đoán") +
  theme_minimal(base_size = 15) +   # Kích thước chữ cơ sở lớn hơn
  theme(plot.title = element_text(hjust = 0.5, size = 18), # Canh giữa tiêu đề
        axis.title = element_text(size = 14),             # Kích thước chữ tiêu đề trục
        axis.text = element_text(size = 12))              # Kích thước chữ giá trị trục
## `geom_smooth()` using formula = 'y ~ x'

# Biểu đồ độ quan trọng của các predictors
ggplot(importance_df, aes(x = reorder(Variable, Importance), y = Importance)) +
  geom_bar(stat = "identity", fill = "steelblue") +  # Màu sắc của thanh
  coord_flip() +  # Đảo ngược trục x và y để tên biến nằm ở trục y
  labs(title = "Độ Quan Trọng của Các Predictors",
       x = "Predictor",
       y = "Độ Quan Trọng") +
  theme_minimal(base_size = 15) +   # Kích thước chữ cơ sở lớn hơn
  theme(plot.title = element_text(hjust = 0.5, size = 18), # Canh giữa tiêu đề
        axis.title = element_text(size = 14),             # Kích thước chữ tiêu đề trục
        axis.text = element_text(size = 12))              # Kích thước chữ giá trị trục

8. Comparisons

# Đảm bảo có kết quả cho train_model
results <- train_model$results

# Tính MAE cho tập huấn luyện (training set) và tập kiểm tra (test set)
train_mae <- sapply(results$maxdepth, function(depth) {
  model <- rpart(price ~ ., data = train_set, control = rpart.control(maxdepth = depth))
  mean(abs(train_set$price - predict(model, train_set)))
})

test_mae <- sapply(results$maxdepth, function(depth) {
  model <- rpart(price ~ ., data = train_set, control = rpart.control(maxdepth = depth))
  mean(abs(test_set$price - predict(model, test_set)))
})

# Tạo DataFrame cho MAE
depth_mae_comparison <- data.frame(
  maxdepth = results$maxdepth,
  Train_MAE = train_mae,
  Test_MAE = test_mae
)


# Vẽ đồ thị với hai đường
ggplot(data = depth_mae_comparison) +
  geom_line(aes(x = maxdepth, y = Train_MAE, color = 'Training Set'), size = 1) +  # Đường MAE tập huấn luyện
  geom_point(aes(x = maxdepth, y = Train_MAE, color = 'Training Set'), size = 3) +  # Điểm MAE tập huấn luyện
  geom_line(aes(x = maxdepth, y = Test_MAE, color = 'Test Set'), size = 1, linetype = "dashed") +  # Đường MAE tập kiểm tra
  geom_point(aes(x = maxdepth, y = Test_MAE, color = 'Test Set'), size = 3) +  # Điểm MAE tập kiểm tra
  labs(title = "So Sánh MAE giữa Tập Huấn Luyện và Tập Kiểm Tra",
       x = "Maxdepth",
       y = "Mean Absolute Error (MAE)") +
  scale_color_manual(values = c('Training Set' = 'blue', 'Test Set' = 'red')) +
  theme_minimal(base_size = 15) +  # Kích thước chữ cơ sở lớn hơn
  theme(plot.title = element_text(hjust = 0.5, size = 18),  # Canh giữa tiêu đề
        axis.title = element_text(size = 14),  # Kích thước chữ tiêu đề trục
        axis.text = element_text(size = 12))  # Kích thước chữ giá trị trục
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.