机器学习作业

Published

December 8, 2025


机器学习课后作业说明

作业目的

  • 加深对机器学习中回归、树模型与随机森林等算法的理解。
  • 掌握从真实公共管理相关数据出发,从数据准备、模型训练、模型评估、结果解释的完整流程。
  • 掌握选择模型和算法的能力,并理解模型优劣、过拟合、泛化、变量重要性等核心概念。
  • 为后续整体课程论文做好准备。

作业要求与步骤

  1. 选数据

    • 依据上次作业整理好的数据集。
    • 数据应包含多个特征变量(包括分类变量和尺度变量),以及一个清晰的目标变量,以便用于回归或分类任务。
  2. 数据预处理

    • 对数据进行必要清洗与预处理,包括处理缺失值、异常值,进行变量编码和转换,如标准化等。
    • 拆分数据集为训练集与测试集,以便后续模型评估。
  3. 模型训练与比较

    • 根据数据与研究目标,分别训练以下模型(至少每个类别各选1个,至少三个):

      模型类别 算法建议
      回归 线性回归、正则化回归(如 Ridge/Lasso)
      树模型 决策树
      集成模型 随机森林
    • 对于每个模型:训练模型、用测试集进行预测。

    • 如果你选择分类任务(categorical target),计算评价指标如准确率 (accuracy)、混淆矩阵 (confusion matrix)、召回率 (recall)、精确率 (precision) 等。

    • 如果是回归任务 (continuous target),计算例如均方根误差(RMSE)、R² 等指标。

  4. 变量重要性与模型解释

    • 对于决策树 / 随机森林模型,提取、报告变量 (feature) 重要性 (feature importance)。
    • 结合变量重要性与回归或分类系数,分析哪些变量对结果影响最大。
    • 讨论为什么这些变量重要?是否符合公共管理或公共政策的逻辑,有什么政策含义?
  5. 结果报告

    • 制作至少 3个图表 例如:目标变量分布图 (histogram),预测 vs 实际值散点图 (scatter + line),特征变量重要性条形图 (bar chart),决策树图 (tree plot)等。
    • 结合图表报告结果,内容包括:
      • 数据来源与简要描述 (变量、样本量、特征)
      • 预处理步骤说明 (缺失值、异常值、编码等)
      • 每个模型的训练过程与结果 (包括评价指标)
      • 模型比较 (优劣、适合场景)
      • 变量重要性与结果解释,对公共管理或公共政策的启示
      • 局限性和后续可以改进的方向

格式与提交

  • 提交形式:R 脚本文件(.R 或 .Rmd)、清洗后的数据(CSV / RData)和结果报告(PDF)

评分标准

评分维度 比例
数据预处理合理性与清晰度 20%
模型训练 + 结果 (至少三种模型) 完整性 25%
模型比较与选择理由 + 变量重要性分析 20%
可视化和结果解释 (公共管理和政策意义) 20%
报告结构、语言、引用规范、代码清晰度 15%

  • 提交时间和方式:两周之后,具体见数字化教学平台。

简要示例:城市空气质量与影响因素分析

数据字段说明

变量名 含义 类型
pm25 城市空气污染(PM2.5 浓度,目标变量) 连续型
temp 温度(℃) 连续
humidity 湿度(%) 连续
windspeed 风速(m/s) 连续
rainfall 降雨量(mm) 连续
industrial_index 工业活动指数(反映排放强度) 连续
pop_density 人口密度 连续
green_rate 城市绿地率(%) 连续
weekday 星期几(1–7) 分类
region 城市区域类型(urban / suburban / rural) 分类

机器学习任务:预测 PM2.5 浓度(回归)

适合:

  • 线性回归
  • 决策树回归
  • 随机森林回归
  • 模型比较
  • 特征重要性分析
  • 可视化分析

R 代码模板

以下模板包含:

  1. 数据加载
  2. 清洗与预处理
  3. 训练–测试集拆分
  4. 三类模型训练
  5. 模型比较
  6. 特征重要性
  7. 可视化
# ================================
# 0. 加载包
# ================================
library(tidyverse)
library(caret)
library(rpart)
library(rpart.plot)
library(randomForest)
library(ggplot2)

# ================================
# 1. 导入数据
# ================================
data <- read_csv("AirQuality_PM25.csv")

glimpse(data)

# ================================
# 2. 数据预处理
# ================================

# 将分类变量转换成 factor
data <- data %>%
  mutate(
    weekday = factor(weekday),
    region = factor(region)
  )

# 检查缺失
colSums(is.na(data))

# 简单缺失值处理(示例:用均值填补)
data$rainfall[is.na(data$rainfall)] <- mean(data$rainfall, na.rm = TRUE)

# ================================
# 3. 训练集与测试集拆分
# ================================
set.seed(123)
train_index <- createDataPartition(data$pm25, p = 0.75, list = FALSE)
train <- data[train_index, ]
test  <- data[-train_index, ]

# ================================
# 4. 模型训练
# ================================

# --- model 1: 线性回归 ---
lm_model <- lm(pm25 ~ ., data = train)
summary(lm_model)

# 预测
lm_pred <- predict(lm_model, newdata = test)


# --- model 2: 决策树 ---
tree_model <- rpart(pm25 ~ ., data = train, method = "anova")
rpart.plot(tree_model)

tree_pred <- predict(tree_model, newdata = test)


# --- model 3: 随机森林 ---
rf_model <- randomForest(pm25 ~ ., data = train, ntree = 500, mtry = 4)
print(rf_model)

rf_pred <- predict(rf_model, newdata = test)

# ================================
# 5. 模型评估
# ================================
# 定义一个 RMSE 函数
rmse <- function(actual, predicted) {
  sqrt(mean((actual - predicted)^2))
}

data.frame(
  Model = c("Linear Regression", "Decision Tree", "Random Forest"),
  RMSE = c(
    rmse(test$pm25, lm_pred),
    rmse(test$pm25, tree_pred),
    rmse(test$pm25, rf_pred)
  )
)

# ================================
# 6. 随机森林:特征重要性
# ================================
importance <- importance(rf_model)
varImpPlot(rf_model)

print(importance)

# ================================
# 7. 可视化示例
# ================================

# 真实 vs 预测(随机森林)
plot_df <- data.frame(
  actual = test$pm25,
  predicted = rf_pred
)

ggplot(plot_df, aes(x = actual, y = predicted)) +
  geom_point(alpha = 0.6) +
  geom_abline(color = "red", linetype = "dashed") +
  labs(
    title = "真实值 vs 预测值(随机森林)",
    x = "真实 PM2.5",
    y = "预测 PM2.5"
  ) +
  theme_minimal()