
简介一套面向西电机器学习课程的大作业资料包适合计算机、电子信息、数学等专业学生完成期末大作业或课程设计时参考。内容覆盖10个实验包括逻辑与二分类C2-1、带噪声的线性回归C3-1、神经网络预测森林火灾面积C4-2、类别不平衡二分类C5-1等典型任务并附带详细文档说明与完整实验报告。包内含16个文件以10个Python程序为主配合csv/data数据集、txt说明、docx实验报告及license文件整体压缩包仅2.95MB轻量但结构完整。所有代码均经过运行测试采用参数化编程注释详细便于修改和复现已上传运行结果遇到问题可联系博主交流。目前已有2174人学习下载是快速梳理实验思路、借鉴代码实现和报告写法的实用参考。1. 西电机器学习大作业到底包含什么一份完整的机器学习大作业往往比单独的算法实现更有价值。这套资源来自西安电子科技大学的机器学习课程作业整理成了MachineLearningHomework-master工程包里面包含 10 个实验的源代码、实验数据、机器学习实验报告.docx文档说明以及一份作者自己写的运行说明。实验从最基础的逻辑与AND二分类开始覆盖线性回归、神经网络预测、类别不平衡分类、树模型或支持向量机等知识点每个代码文件都带有注释和运行结果属于那种拿过来就能跑、跑完能写报告、写完能讲清楚原理的完整闭环。适合的人群很明确正在做课程设计、期末大作业的计算机、电子信息工程、数学专业学生以及希望快速回顾机器学习基础算法的从业者。对于有经验的工程师这份材料的价值在于看作者如何把“参数化编程”的思路塞进每个实验里以及如何组织文档说明和实验报告这些反而是平时写代码最容易忽略的部分。下面按实验顺序拆开讲从理论到可复现的实操把每个实验的关键代码和参数设计都过一遍。2. 逻辑回归与线性回归从 AND 到噪声数据2.1 C2-1 逻辑与 AND 问题二分类器的第一课C2-1 实验要求构造一个“逻辑与”的二分类问题也就是典型的 AND 门输入两个布尔变量输出为 1 当且仅当两个输入都为 1。这个实验虽然简单但它是理解逻辑回归、感知机、决策边界的最佳起点。常见做法是先用numpy生成四个样本点然后送入逻辑回归模型训练最后把决策边界画出来。import numpy as np from sklearn.linear_model import LogisticRegression # AND 数据两个特征 x1, x2标签 y X np.array([[0, 0], [0, 1], [1, 0], [1, 1]], dtypefloat) y np.array([0, 0, 0, 1]) # 逻辑回归模型C 控制正则化强度 model LogisticRegression(C1.0, solverliblinear) model.fit(X, y) # 打印学到的系数和截距 print(w:, model.coef_) print(b:, model.intercept_)逻辑回归的决策边界由w1*x1 w2*x2 b 0决定。对于 AND 问题学到的权重通常是w1 ≈ w2 ≈ 1b ≈ -1.5。这里C1.0是正则化强度的倒数C越小正则化越强如果训练数据存在共线性或离群点可以适当调低C。solverliblinear适合小数据集如果换成大数据集可以用lbfgs。这个实验容易踩的坑是直接拿原始特征做逻辑回归特征尺度差异大时收敛慢。虽然 AND 问题只有 0/1 特征但后续实验里如果有连续特征一定要先做标准化。另外predict_proba输出的概率不是“信心值”它反映的是模型对决策边界的距离写报告时不要过度解读。2.2 C3-1 线性回归反过来回归会怎样C3-1 实验生成 500 个数据点(x, y)其中y x nn是均值为 0、标准差为delta的正态分布。要求从x估计y然后再做一次反方向从y估计x最后比较两条回归曲线。这个实验的深层目的是展示“回归稀释效应”regression dilution——当自变量有噪声时斜率会被低估。import numpy as np from sklearn.linear_model import LinearRegression delta 0.5 rng np.random.default_rng(42) x rng.uniform(0, 10, 500) n rng.normal(0, delta, 500) y x n # 正向回归用 x 预测 y reg_xy LinearRegression().fit(x.reshape(-1, 1), y) print(正向斜率:, reg_xy.coef_[0], 截距:, reg_xy.intercept_) # 反向回归用 y 预测 x reg_yx LinearRegression().fit(y.reshape(-1, 1), x) print(反向斜率:, reg_yx.coef_[0], 截距:, reg_yx.intercept_)按理论推导正向回归的斜率约为σ_x^2 / (σ_x^2 δ^2)反向回归的斜率约为σ_x^2 / (σ_x^2 δ^2)的倒数关系但直接用最小二乘拟合时反向回归的斜率会比 1 小。真实数据中如果两个变量都带噪声两方向的斜率会形成“剪刀差”这在仪器校准、测量系统分析中非常常见。实验报告里可以把两条回归曲线画在一张图上配上原始散点能清晰看出差异。参数delta控制噪声标准差建议在0.1到1.0之间多试几个值观察斜率变化趋势。如果把delta设得过大比如50数据点会完全散开回归结果失去意义。这也是一个很好的调参切入点报告里画一张“delta 与斜率”的曲线图比单纯贴代码更有说服力。下面用表格对比两种回归的关键差异回归方向自变量因变量斜率变化实际含义正向x无噪声y x n接近 1标准最小二乘反向y含噪声x小于 1因变量噪声被“稀释”3. 神经网络实战森林火灾面积预测3.1 C4 系列实验的输入与输出C4 系列实验C4-1、C4-2、C4-3要求训练神经网络预测森林火灾面积。这个问题比前两个实验复杂得多典型的数据集来自 UCI 的 Forest Fires特征包括月份、星期、FFMC、DMC、DC、ISI、温度、相对湿度、雨量、风速目标值是火灾面积单位为公顷。由于面积分布极度偏斜直接回归往往效果很差常见做法是将目标值取对数log1p让分布更接近高斯分布。import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense # 读取数据 df pd.read_csv(forest_fires.csv) # 将月份和星期做简单数值映射 df[month] df[month].map({jan:1, feb:2, mar:3, apr:4, may:5, jun:6, jul:7, aug:8, sep:9, oct:10, nov:11, dec:12}) df[day] df[day].map({mon:1, tue:2, wed:3, thu:4, fri:5, sat:6, sun:7}) # 特征和标签对面积做 log1p X df.drop(area, axis1).values y np.log1p(df[area].values) # 划分训练集和测试集 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42) # 标准化特征 scaler StandardScaler() X_train scaler.fit_transform(X_train) X_test scaler.transform(X_test)这里用log1p而不是log是因为面积可能为 0log1p保证输入大于等于 0 时输出依然有定义。train_test_split的random_state固定后报告里的结果可以复现。标准化用的是训练集的均值和方差去转换测试集这是防止数据泄露的关键一步很多新手会不小心对整个数据集做标准化导致测试集信息提前进入训练过程。3.2 网络结构设计与训练参数对于这种小规模表格数据全连接网络就够用。我一般会设计三层网络输入维度对应特征数量中间层用 ReLU输出层用线性激活。损失函数用均方误差MSE优化器用 Adam。下面是一个可复现的 Keras 实现from tensorflow.keras.optimizers import Adam from tensorflow.keras.callbacks import EarlyStopping model Sequential([ Dense(64, activationrelu, input_shape(X_train.shape[1],)), Dense(32, activationrelu), Dense(1, activationlinear) ]) model.compile(optimizerAdam(learning_rate0.001), lossmse, metrics[mae]) # 早停验证集 loss 不再下降就停止 early_stop EarlyStopping(monitorval_loss, patience20, restore_best_weightsTrue) history model.fit( X_train, y_train, validation_split0.2, epochs200, batch_size16, callbacks[early_stop], verbose1 )参数说明第一层64个神经元第二层32个层数不要太多否则过拟合。learning_rate0.001是 Adam 默认值如果损失不下降可以先调大到0.01如果震荡就调小到0.0001。batch_size16对小数据集较稳定数据量增大后可改为 32 或 64。EarlyStopping的patience20表示连续 20 个 epoch 验证 loss 不下降就停止并用验证 loss 最小的那组权重。3.3 训练中的坑森林火灾面积预测最大的坑是目标值极度偏斜即使做了log1p预测结果还原为实际面积时误差仍然很大。另一个坑是月份、星期这类循环特征被直接作为数值输入模型会认为 12 月比 1 月大但实际它们是循环关系。更合理的做法是用 one-hot 编码或正弦/余弦变换。表格列出我实际训练中遇到的问题及对策问题现象对策损失不下降训练和验证 loss 均不变化检查特征是否标准化学习率是否过大或过小过拟合训练 loss 低验证 loss 高增加 Dropout或减少网络层数预测值为负还原后面积出现负数输出层改用 softplus 或直接加max(0, x)数据泄露验证集效果异常好检查是否在fit前对全量数据做标准化4. 类别不平衡与其余实验分类器的边界4.1 C5-1 类别不平衡二分类问题C5-1 实验要求构建一个类别不平衡的二分类问题。在真实业务中比如欺诈检测、异常流量识别正样本占比可能只有 1%此时准确率没有意义模型需要优化 Precision、Recall 和 AUC。常见做法有三种重采样、修改损失函数、使用集成方法。from sklearn.datasets import make_classification from sklearn.model_selection import train_test_split from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import classification_report, roc_auc_score # 生成 1000 个样本正类占比 5% X, y make_classification( n_samples1000, n_features20, n_informative15, n_redundant5, weights[0.95, 0.05], random_state42 ) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, stratifyy, random_state42) # 使用 class_weight 给少数类更高权重 model RandomForestClassifier( n_estimators100, class_weightbalanced, random_state42 ) model.fit(X_train, y_train) y_pred model.predict(X_test) print(classification_report(y_test, y_pred)) print(AUC:, roc_auc_score(y_test, model.predict_proba(X_test)[:, 1]))class_weightbalanced会自动根据类别频率调整权重少数类样本的误分类代价更高。stratifyy保证训练集和测试集的正负样本比例一致这是不平衡实验里必须做的否则测试集可能全是负样本评估失真。n_estimators100是随机森林中树的数量树越多越稳定但训练时间也越长。除了class_weight还可以用imbalanced-learn库做 SMOTE 过采样。但要注意SMOTE 必须在划分训练集之后再使用而且只能对训练集做否则会生成重叠样本导致验证结果虚高。实验报告里建议同时给出class_weightbalanced和 SMOTE 两种方案的对比这会让报告厚度明显提升。4.2 剩余实验C6、C7、C8快速拆解除了前面重点讲的 C2、C3、C4、C5资源里还有 C6-1、C6-2、C7-1、C8-1 等实验。这些实验的定位各不相同我用下面的表格总结每个实验对应的核心知识点和实现要点方便你有针对性地看源代码实验编号核心知识点代码关键点可能的扩展方向C6-1决策树 / 集成学习特征重要性排序、树深度限制换成梯度提升树对比C6-2聚类 / 降维KMeans 的肘部法则、PCA 可视化用 t-SNE 观察聚类结构C7-1支持向量机核函数选择、惩罚系数 C对比线性核与 RBF 核C8-1模型评估交叉验证、混淆矩阵加入 ROC 曲线与 PR 曲线这些实验我建议不要只看单个代码而是把它们按“预处理、建模、评估”三个阶段拆开。同一个数据集先用 C6 的树模型跑一遍再用 C7 的 SVM 跑一遍最后用 C8 的评估方法做对比这样就能自然形成一组对照实验。很多同学在期末大作业里只贴孤立的代码缺少“为什么用这个模型”的论证这是拿不到高分的主要原因。4.3 从实验到期末大作业的衔接把这 10 个实验串联起来看刚好对应机器学习课程的主线分类、回归、神经网络、不平衡学习、模型评估。做期末大作业时不建议直接堆砌所有实验而是挑一条线深入。比如选“森林火灾面积预测”作为主题把 C3 的线性回归当作基线C4 的神经网络作为主模型C5 的不平衡处理思路用在面积大于阈值的二分类延伸上最后用 C8 的评估方法收尾。这样既有基础又有深度还能展示你对多个知识点的控制能力。源代码里的注释风格是“参数化编程”这意味着很多超参数都提取到了文件顶部或配置区域修改起来不需要在代码里到处找。这个习惯非常值得借鉴写大作业时我也建议把LEARNING_RATE、BATCH_SIZE、EPOCHS等变量集中管理这样报告里写参数分析时直接引用变量名就行。5. 实验报告的写法与调试技巧5.1 报告结构让代码可复现拿到这套资源后最容易忽视的是机器学习实验报告.docx。这份报告的价值在于告诉你老师的评分点在哪里一般包括实验目的、算法原理、实验步骤、结果分析、参数调优、结论和参考文献。但很多人的报告只写了“实验步骤”和“代码”缺少“为什么这么设计”的说明。我的建议是每一章都加一小节“关键参数说明”用表格列出参数名、默认值、修改影响例如参数默认值调高效果调低效果C逻辑回归1.0过拟合风险降低决策边界更平滑对离群点更敏感delta线性回归噪声0.5数据更散乱回归斜率下偏接近标准直线learning_rate0.001收敛快但可能震荡收敛慢但稳定n_estimators100模型更稳训练更慢方差增大报告里如果能附上每次实验的运行截图或损失曲线说服力会强很多。源代码文件里已经包含运行结果直接截图即可不用重新跑。5.2 参数化编程与运行排错“参数化编程”是这套代码的一个特点但很多人拿到后不知道如何改参数。常见做法是把所有可调参数集中到一个字典或argparse配置里这样既方便命令行调试也方便写报告时记录实验记录。下面是一个小型示例import argparse def parse_args(): parser argparse.ArgumentParser(descriptionML Homework Experiment) parser.add_argument(--delta, typefloat, default0.5, helpnoise std for data generation) parser.add_argument(--lr, typefloat, default0.001, helplearning rate) parser.add_argument(--batch_size, typeint, default16, helpbatch size for training) return parser.parse_args() if __name__ __main__: args parse_args() print(fdelta{args.delta}, lr{args.lr}, batch_size{args.batch_size})这样改参数时不需要动核心代码只需在命令行传入--delta 0.8。运行报错时先看是不是路径问题data文件夹和代码同级时用相对路径但如果从其他目录调用脚本open(data.csv)会找不到文件建议在代码开头用os.path.dirname(__file__)拼绝对路径。另一个高频错误是sklearn或tensorflow版本不兼容比如新版本里LogisticRegression的solver参数默认值变了报错时先检查依赖版本。5.3 快速验证模型效果的小技巧在提交前我习惯用一个小脚本快速验证所有实验是否都能跑通。不要直接运行每个文件而是按实验顺序逐个执行并设置一个简单的断言检查输出范围。例如线性回归的斜率应该在0.5到1.5之间逻辑回归的准确率应该大于0.9神经网络预测的log1p值不应出现NaN。跑完后再检查data目录下是否有缺失文件最后统一查看实验报告里的截图是否与当前代码运行结果一致。调参时优先用matplotlib画出损失曲线如果前 10 个 epoch 没有明显下降先调学习率而不是调网络结构。这套排查顺序能帮你省下大量重复训练的时间。本文还有配套的精品资源点击获取