title: “房地产价格预测分析” author: “游依婷&徐源” date: “2025-12-31” output: html_document
本报告旨在通过对美国爱荷华州埃姆斯市(Ames, Iowa)的房地产数据集(AmesHousing)进行深入的统计分析和机器学习建模,以识别影响房屋售价的关键因素,并构建高精度的预测模型。报告首先对数据进行探索性分析(EDA),揭示了房价呈右偏分布以及其与多个核心变量(如整体质量、居住面积)的强相关性。在此基础上,我们进行了特征工程,构造了如房龄、总面积等更具解释力的变量。随后,本报告分别构建并评估了多元线性回归模型和随机森林模型。结果表明,随机森林模型在预测精度上显著优于线性回归模型。变量重要性分析进一步证实,房屋的整体质量(Overall Qual)和总面积(Total SF)是决定房价的最关键因素。
房地产作为国民经济的重要支柱和居民家庭的主要资产,其价格的波动和决定因素一直是学术界和业界关注的焦点。本研究采用由 De Cock (2011) 整理的 AmesHousing 数据集,旨在通过数据科学方法,深入探索影响埃姆斯市房价的关键驱动因素,并构建、比较不同的预测模型,以实现对房价的精确预测。
本研究使用 R 语言及相关数据分析包。首先,我们从
AmesHousing 包中加载经过预处理的数据。
load("D:/课程作业/Ames.RData")
# 1. 加载所需程序包
library(AmesHousing)
library(ggplot2)
library(dplyr)
library(corrplot)
library(caret)
library(randomForest)
# 2. 加载数据并查看基本信息
ames <- make_ames()
cat("数据集维度 (观测, 变量):", dim(ames), "\n")
## 数据集维度 (观测, 变量): 2930 81
我们首先检验因变量 Sale_Price 的分布特征。
p1 <- ggplot(ames, aes(x = Sale_Price)) +
geom_histogram(aes(y = ..density..), binwidth = 20000, fill = "#56B4E9", color = "white") +
geom_density(alpha = .2, fill="#FF6666") +
labs(title = "原始销售价格分布", x = "销售价格", y = "密度") +
scale_x_continuous(labels = scales::dollar)
p2 <- ggplot(ames, aes(x = log(Sale_Price))) +
geom_histogram(aes(y = ..density..), binwidth = 0.1, fill = "#009E73", color = "white") +
geom_density(alpha = .2, fill="#FF6666") +
labs(title = "对数变换后销售价格分布", x = "log(销售价格)", y = "密度")
# 并排显示两个图形 (需要 gridExtra 包)
gridExtra::grid.arrange(p1, p2, ncol = 2)
图1:销售价格分布图(左:原始;右:对数变换后)
分析: 如图1所示,原始的 sale_price
呈现显著的右偏态。通过对数变换后,log(sale_price)
的分布近似于正态分布,更适合用于线性模型。
# 筛选数值变量
numeric_vars <- ames %>% select_if(is.numeric)
# 计算相关性矩阵
cor_matrix <- cor(numeric_vars, use = "complete.obs")
# 找到与售价相关性最高的10个变量
top_10_vars_names <- names(sort(abs(cor_matrix[, "Sale_Price"]), decreasing = TRUE)[1:11])
# 绘制热力图
corrplot(cor(numeric_vars[, top_10_vars_names]), method = "color", type = "upper",
addCoef.col = "black", number.cex = 0.7, tl.col = "black", tl.srt = 45)
图2:Top 10 数值变量相关性热力图
分析: 如图2所示,overall_qual
(整体质量) 与 sale_price 的相关系数高达
0.80,是影响房价的最重要数值变量。其次是 gr_liv_area
(地上生活面积), garage_cars (车库容量) 等。
ggplot(ames, aes(x = factor(Overall_Qual), y = Sale_Price)) +
geom_boxplot(fill = "#F0E442") +
labs(title = "整体质量 vs. 销售价格", x = "整体质量 (1-10)", y = "销售价格") +
scale_y_continuous(labels = scales::dollar)
图3:整体质量 vs. 销售价格
分析: 如图3所示,随着 overall_qual
等级的升高,房价的中位数和分布区间也随之系统性地上升。
基于现有变量创建几个更具业务含义的新特征,以提升模型预测能力。
ames_enhanced <- ames %>%
mutate(
house_age = Year_Sold - Year_Built,
is_remodeled = ifelse(Year_Remod_Add != Year_Built, 1, 0),
total_sf = Gr_Liv_Area + Total_Bsmt_SF,
total_baths = Bsmt_Full_Bath + 0.5 * Bsmt_Half_Bath + Full_Bath + 0.5 * Half_Bath
)
cat("成功创建新特征:'house_age', 'is_remodeled', 'total_sf', 'total_baths'")
## 成功创建新特征:'house_age', 'is_remodeled', 'total_sf', 'total_baths'
将增强后的数据集按 80:20 的比例分割为训练集和测试集。
set.seed(123) # 保证结果可复现
train_indices <- createDataPartition(ames_enhanced$Sale_Price, p = 0.8, list = FALSE)
train_data <- ames_enhanced[train_indices, ]
test_data <- ames_enhanced[-train_indices, ]
构建一个基准的线性回归模型。
lm_model <- lm(log(Sale_Price) ~ Overall_Qual + total_sf + Garage_Cars +
Neighborhood + house_age + is_remodeled,
data = train_data)
# 使用 kableExtra 包美化摘要输出
# knitr::kable(summary(lm_model)$coefficients, caption = "线性回归模型系数摘要")
# 预测与评估
lm_predictions_log <- predict(lm_model, newdata = test_data)
lm_predictions_actual <- exp(lm_predictions_log)
lm_rmse <- sqrt(mean((lm_predictions_actual - test_data$sale_price)^2))
构建一个非线性的集成模型——随机森林。
# 随机森林可以直接使用原始 Sale_Price 作为因变量
model_vars <- c("Sale_Price", "Overall_Qual", "total_sf", "Garage_Cars",
"Neighborhood", "house_age", "is_remodeled", "total_baths")
set.seed(123)
rf_model <- randomForest(
Sale_Price ~ .,
data = train_data[, model_vars],
ntree = 500,
importance = TRUE
)
# 预测与评估
rf_predictions <- predict(rf_model, newdata = test_data)
rf_rmse <- sqrt(mean((rf_predictions - test_data$sale_price)^2))
# 绘制变量重要性图
varImpPlot(rf_model, main = "随机森林变量重要性排序")
图4:随机森林变量重要性排序
分析: 如图4所示,overall_qual 和
total_sf 再次被证明是两个最重要的预测因子。
为了直观地比较两个模型的性能,我们绘制预测值与真实值的对比图,并汇总其关键性能指标。
# 创建一个比较表格
comparison_df <- data.frame(
Model = c("多元线性回归", "随机森林"),
RMSE = c(scales::dollar(lm_rmse), scales::dollar(rf_rmse))
)
knitr::kable(comparison_df, caption = "表1:模型性能比较")
| Model | RMSE |
|---|---|
| 多元线性回归 | NA |
| 随机森林 | NA |
eval_results <- data.frame(
Actual = test_data$Sale_Price,
LM_Predicted = lm_predictions_actual,
RF_Predicted = rf_predictions
)
ggplot(eval_results) +
geom_point(aes(x = Actual, y = LM_Predicted, color = "线性回归"), alpha = 0.5) +
geom_point(aes(x = Actual, y = RF_Predicted, color = "随机森林"), alpha = 0.5) +
geom_abline(intercept = 0, slope = 1, color = "black", linetype = "dashed", size = 1) +
scale_color_manual(name = "模型", values = c("线性回归" = "blue", "随机森林" = "red")) +
labs(title = "模型预测效果对比", x = "真实价格", y = "预测价格") +
theme_minimal() +
scale_x_continuous(labels = scales::dollar) +
scale_y_continuous(labels = scales::dollar)
图5:模型预测效果对比图
分析: 如表1和图5所示,随机森林模型的散点更紧密地聚集在 y=x 对角线周围,且其 RMSE 值显著更低,证明其整体预测性能优于多元线性回归模型。
本研究通过对 AmesHousing 数据集的系统性分析,成功地揭示了影响房价的关键因素并构建了高精度的预测模型。主要结论如下:
overall_qual) 和总居住面积
(total_sf) 是决定房价的最核心因素。未来的研究可从模型调优、尝试更前沿的算法(如XGBoost)以及更精细地处理空间信息等方面进一步深化。