如何无需循环找到波士顿房价数据集的最优训练测试划分以最小化RMSE
波士顿房价数据集:测试集RMSE与训练/测试样本量的问题
我正在尝试最小化波士顿房价数据集的RMSE,基础实现结果如下:
library(Metrics) df <- MASS::Boston train <- df[1:400, ] test <- df[401:506, ] Boston_lm <- lm(medv ~., data = train) Boston_lm_RMSE <- Metrics::rmse(actual = test$medv, predicted = predict(object = Boston_lm, newdata = test)) # 6.155792
但调整训练集与测试集的样本量后,RMSE差异极大:
df <- MASS::Boston train <- df[1:300, ] test <- df[301:506, ] Boston_lm <- lm(medv ~., data = train) Boston_lm_RMSE <- Metrics::rmse(actual = test$medv, predicted = predict(object = Boston_lm, newdata = test)) # 19.13284
是否存在无需遍历所有可能值,即可确定使测试集RMSE最低的训练测试样本量的方法?
问题根源与解决方案
首先要明确:你遇到的RMSE骤变不是样本量本身的问题,而是按原始行顺序划分训练/测试集导致的数据分布严重偏移——波士顿数据集的行是按特定顺序排列的(比如对应地理位置或房价梯度),直接取前N行当训练集,会让训练集和测试集的样本分布完全不同,模型泛化能力自然会暴跌。
1. 先修正数据划分方式
必须用随机划分保证训练/测试集分布一致,这是后续分析的前提:
library(Metrics) set.seed(123) # 固定随机种子,结果可复现 df <- MASS::Boston train_idx <- sample(nrow(df), size = 0.7 * nrow(df)) # 按70%比例抽取训练集索引 train <- df[train_idx, ] test <- df[-train_idx, ] Boston_lm <- lm(medv ~., data = train) Boston_lm_RMSE <- Metrics::rmse(actual = test$medv, predicted = predict(Boston_lm, newdata = test))
2. 关于“无需遍历找最优样本量”
不存在绝对的“最优样本量”,但可以通过以下高效方法确定合适的样本范围:
- 遵循通用比例原则:训练集占总样本的60%-80%是常规选择,既能保证模型学到足够分布信息,又能让测试集有足够样本稳定评估泛化能力。
- 绘制学习曲线:固定模型结构,用不同比例的训练数据训练模型,绘制测试集RMSE随训练样本量变化的曲线。当曲线趋于平稳时,对应的训练样本量就是合适的阈值,无需盲目遍历所有可能值。
学习曲线实现示例:set.seed(123) # 定义训练集比例范围:从50%到90%,步长5% sample_ratios <- seq(0.5, 0.9, by = 0.05) rmse_results <- c() for (ratio in sample_ratios) { train_idx <- sample(nrow(df), size = ratio * nrow(df)) train_data <- df[train_idx, ] test_data <- df[-train_idx, ] model <- lm(medv ~., data = train_data) current_rmse <- Metrics::rmse(test_data$medv, predict(model, newdata = test_data)) rmse_results <- c(rmse_results, current_rmse) } # 绘制学习曲线 plot(sample_ratios, rmse_results, type = "b", xlab = "训练集占比", ylab = "测试集RMSE", main = "RMSE随训练集比例变化曲线") - 优先优化模型而非样本量:降低RMSE的核心是模型本身的优化(比如特征选择、加入正则化的
glmnet模型),调整样本量的影响远小于模型优化。
内容的提问来源于stack exchange,提问作者Russ Conte
相关产品推荐
相关产品推荐

