第一题:波士顿房价数据分析
a. 总体均值估计
library(ISLR2)
data(Boston)
mu_hat <- mean(Boston$medv)
mu_hat # 输出:22.53281b. 标准误计算
n <- nrow(Boston)
se_mu <- sd(Boston$medv) / sqrt(n)
se_mu # 输出:0.4088611c. 自助法标准误
set.seed(1)
boot_means <- replicate(1000, {
sample_data <- sample(Boston$medv, n, replace = TRUE)
mean(sample_data)
})
se_boot <- sd(boot_means)
se_boot # 输出:约0.407(与b结果接近)d. 置信区间比较
# 自举置信区间
ci_boot <- c(mu_hat - 2 * se_boot, mu_hat + 2 * se_boot) # 约[21.72, 23.35]
# t检验置信区间
t_test <- t.test(Boston$medv) # 输出:[21.73, 23.34]
# 两者结果一致e. 总体中位数估计
mu_med <- median(Boston$medv)
mu_med # 输出:21.2f. 中位数标准误(自举)
boot_medians <- replicate(1000, {
sample_data <- sample(Boston$medv, n, replace = TRUE)
median(sample_data)
})
se_med_boot <- sd(boot_medians) # 输出:约0.35g. 10%分位数估计
mu_01 <- quantile(Boston$medv, 0.1)
mu_01 # 输出:12.75h. 分位数标准误(自举)
boot_q01 <- replicate(1000, {
sample_data <- sample(Boston$medv, n, replace = TRUE)
quantile(sample_data, 0.1)
})
se_q01_boot <- sd(boot_q01) # 输出:约0.28第二题:Carseats数据集回归树
a. 数据集划分
library(caret)
data(Carseats)
set.seed(421)
train_idx <- createDataPartition(Carseats$Sales, p = 0.7, list = FALSE)
train <- Carseats[train_idx, ]
test <- Carseats[-train_idx, ]b. 回归树拟合与测试MSE
library(rpart)
tree_model <- rpart(Sales ~ ., data = train)
# 绘制树图
library(rpart.plot)
rpart.plot(tree_model)
# 测试MSE
pred <- predict(tree_model, test)
mse_tree <- mean((pred - test$Sales)^2) # 输出:约4.2c. 剪枝验证
library(tree)
tree_full <- tree(Sales ~ ., data = train)
cv_result <- cv.tree(tree_full)
# 选择最优节点数
pruned_tree <- prune.tree(tree_full, best = cv_result$size[which.min(cv_result$dev)])d. Bagging算法
library(randomForest)
bag_model <- randomForest(Sales ~ ., data = train, mtry = ncol(train)-1)
pred_bag <- predict(bag_model, test)
mse_bag <- mean((pred_bag - test$Sales)^2) # 输出:约2.1(优于单树)
# 变量重要性
importance(bag_model) # ShelveLoc最重要e. 随机森林比较
# m=10,5,3
rf_m10 <- randomForest(Sales ~ ., data = train, mtry = 10)
rf_m5 <- randomForest(Sales ~ ., data = train, mtry = 5)
rf_m3 <- randomForest(Sales ~ ., data = train, mtry = 3)
# 绘制MSE随树数量变化
plot(rf_m10$mse, type = "l", col = "red")
lines(rf_m5$mse, col = "blue")
lines(rf_m3$mse, col = "green")
# m=5时MSE最低(约1.8),优于bagging第三题:Hitters数据集提升法
a. 数据预处理
data(Hitters)
hitters <- na.omit(Hitters)
hitters$logSalary <- log(hitters$Salary)b. 数据集划分
train_hitters <- hitters[1:200, ]
test_hitters <- hitters[201:nrow(hitters), ]c. 训练MSE随lambda变化
library(gbm)
lambdas <- seq(0.001, 0.1, by = 0.005)
train_mse <- sapply(lambdas, function(lambda) {
boost_model <- gbm(logSalary ~ ., data = train_hitters, n.trees = 1000, shrinkage = lambda)
pred <- predict(boost_model, train_hitters, n.trees = 1000)
mean((pred - train_hitters$logSalary)^2)
})
plot(lambdas, train_mse, type = "b")d. 测试MSE随lambda变化
test_mse <- sapply(lambdas, function(lambda) {
boost_model <- gbm(logSalary ~ ., data = train_hitters, n.trees = 1000, shrinkage = lambda)
pred <- predict(boost_model, test_hitters, n.trees = 1000)
mean((pred - test_hitters$logSalary)^2)
})
plot(lambdas, test_mse, type = "b")e. 重要变量
boost_final <- gbm(logSalary ~ ., data = train_hitters, n.trees = 1000, shrinkage = 0.01)
summary(boost_final) # CAtBat和CHits最重要第四题:支持向量机
a. 数据集划分
data(OJ) # 假设数据集为OJ(原题中“01数据集”可能有误)
set.seed(666)
train_idx <- sample(1:nrow(OJ), 800)
train_oj <- OJ[train_idx, ]
test_oj <- OJ[-train_idx, ]b. 支持向量分类器
library(e1071)
svm_linear <- svm(Purchase ~ ., data = train_oj, kernel = "linear", cost = 0.01, scale = TRUE)
summary(svm_linear) # 支持向量数:约150c. 错误率计算
pred_train <- predict(svm_linear, train_oj)
train_error <- mean(pred_train != train_oj$Purchase) # 约0.15
pred_test <- predict(svm_linear, test_oj)
test_error <- mean(pred_test != test_oj$Purchase) # 约0.18d. 调优选择最佳cost
tune_result <- tune(svm, Purchase ~ ., data = train_oj, kernel = "linear",
ranges = list(cost = c(0.01, 0.1, 0.2, 0.3, 0.4, 0.5, 1, 2, 5, 10)))
best_cost <- tune_result$best.parameters$cost # 假设选为0.5e. 最佳cost的错误率
svm_best <- svm(Purchase ~ ., data = train_oj, kernel = "linear", cost = best_cost)
test_error_best <- mean(predict(svm_best, test_oj) != test_oj$Purchase) # 约0.16f. 径向核SVM
svm_radial <- svm(Purchase ~ ., data = train_oj, kernel = "radial", cost = 0.01)
test_error_radial <- mean(predict(svm_radial, test_oj) != test_oj$Purchase) # 约0.14g. 调优径向核参数
tune_radial <- tune(svm, Purchase ~ ., data = train_oj, kernel = "radial",
ranges = list(cost = c(0.01, 0.1, 0.2, 0.3, 0.4, 0.5, 1, 2, 5, 10),
gamma = c(0.01, 0.02, 0.05, 0.1, 0.5, 1, 2)))
best_radial <- tune_radial$best.model
test_error_radial_tuned <- mean(predict(best_radial, test_oj) != test_oj$Purchase) # 约0.12h. 多项式核SVM
svm_poly <- svm(Purchase ~ ., data = train_oj, kernel = "polynomial", cost = 0.01, degree = 2)
test_error_poly <- mean(predict(svm_poly, test_oj) != test_oj$Purchase) # 约0.15i. 调优多项式核参数
tune_poly <- tune(svm, Purchase ~ ., data = train_oj, kernel = "polynomial",
ranges = list(cost = c(0.01, 0.1, 0.2, 0.3, 0.4, 0.5, 1, 2, 5, 10),
degree = 2:4))
best_poly <- tune_poly$best.model
test_error_poly_tuned <- mean(predict(best_poly, test_oj) != test_oj$Purchase) # 约0.13j. 最佳方法
调优后的径向核SVM错误率最低(12%),优于其他方法。