news 2026/9/12 4:07:05

机器学习大作业实战指南:从线性回归到神经网络与不平衡分类

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
机器学习大作业实战指南:从线性回归到神经网络与不平衡分类

简介:一套面向西电机器学习课程的大作业资料包,适合计算机、电子信息、数学等专业学生完成期末大作业或课程设计时参考。内容覆盖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]], dtype=float) y = np.array([0, 0, 0, 1]) # 逻辑回归模型,C 控制正则化强度 model = LogisticRegression(C=1.0, solver='liblinear') model.fit(X, y) # 打印学到的系数和截距 print("w:", model.coef_) print("b:", model.intercept_)

逻辑回归的决策边界由w1*x1 + w2*x2 + b = 0决定。对于 AND 问题,学到的权重通常是w1 ≈ w2 ≈ 1b ≈ -1.5。这里C=1.0是正则化强度的倒数,C越小正则化越强,如果训练数据存在共线性或离群点,可以适当调低Csolver='liblinear'适合小数据集,如果换成大数据集可以用'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.11.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', axis=1).values y = np.log1p(df['area'].values) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42) # 标准化特征 scaler = StandardScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test)

这里用log1p而不是log,是因为面积可能为 0,log1p保证输入大于等于 0 时输出依然有定义。train_test_splitrandom_state固定后,报告里的结果可以复现。标准化用的是训练集的均值和方差去转换测试集,这是防止数据泄露的关键一步,很多新手会不小心对整个数据集做标准化,导致测试集信息提前进入训练过程。

3.2 网络结构设计与训练参数

对于这种小规模表格数据,全连接网络就够用。我一般会设计三层网络:输入维度对应特征数量,中间层用 ReLU,输出层用线性激活。损失函数用均方误差MSE,优化器用 Adam。下面是一个可复现的 Keras 实现:

from tensorflow.keras.optimizers import Adam from tensorflow.keras.callbacks import EarlyStopping model = Sequential([ Dense(64, activation='relu', input_shape=(X_train.shape[1],)), Dense(32, activation='relu'), Dense(1, activation='linear') ]) model.compile(optimizer=Adam(learning_rate=0.001), loss='mse', metrics=['mae']) # 早停:验证集 loss 不再下降就停止 early_stop = EarlyStopping(monitor='val_loss', patience=20, restore_best_weights=True) history = model.fit( X_train, y_train, validation_split=0.2, epochs=200, batch_size=16, callbacks=[early_stop], verbose=1 )

参数说明:第一层64个神经元,第二层32个,层数不要太多,否则过拟合。learning_rate=0.001是 Adam 默认值,如果损失不下降,可以先调大到0.01,如果震荡就调小到0.0001batch_size=16对小数据集较稳定,数据量增大后可改为 32 或 64。EarlyStoppingpatience=20表示连续 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_samples=1000, n_features=20, n_informative=15, n_redundant=5, weights=[0.95, 0.05], random_state=42 ) X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, stratify=y, random_state=42) # 使用 class_weight 给少数类更高权重 model = RandomForestClassifier( n_estimators=100, class_weight='balanced', random_state=42 ) 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_weight='balanced'会自动根据类别频率调整权重,少数类样本的误分类代价更高。stratify=y保证训练集和测试集的正负样本比例一致,这是不平衡实验里必须做的,否则测试集可能全是负样本,评估失真。n_estimators=100是随机森林中树的数量,树越多越稳定,但训练时间也越长。

除了class_weight,还可以用imbalanced-learn库做 SMOTE 过采样。但要注意,SMOTE 必须在划分训练集之后再使用,而且只能对训练集做,否则会生成重叠样本导致验证结果虚高。实验报告里建议同时给出class_weight='balanced'和 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_RATEBATCH_SIZEEPOCHS等变量集中管理,这样报告里写参数分析时,直接引用变量名就行。

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(description='ML Homework Experiment') parser.add_argument('--delta', type=float, default=0.5, help='noise std for data generation') parser.add_argument('--lr', type=float, default=0.001, help='learning rate') parser.add_argument('--batch_size', type=int, default=16, help='batch size for training') return parser.parse_args() if __name__ == '__main__': args = parse_args() print(f'delta={args.delta}, lr={args.lr}, batch_size={args.batch_size}')

这样改参数时不需要动核心代码,只需在命令行传入--delta 0.8。运行报错时,先看是不是路径问题,data文件夹和代码同级时用相对路径,但如果从其他目录调用脚本,open('data.csv')会找不到文件,建议在代码开头用os.path.dirname(__file__)拼绝对路径。另一个高频错误是sklearntensorflow版本不兼容,比如新版本里LogisticRegressionsolver参数默认值变了,报错时先检查依赖版本。

5.3 快速验证模型效果的小技巧

在提交前,我习惯用一个小脚本快速验证所有实验是否都能跑通。不要直接运行每个文件,而是按实验顺序逐个执行,并设置一个简单的断言检查输出范围。例如线性回归的斜率应该在0.51.5之间,逻辑回归的准确率应该大于0.9,神经网络预测的log1p值不应出现NaN。跑完后再检查data目录下是否有缺失文件,最后统一查看实验报告里的截图是否与当前代码运行结果一致。调参时优先用matplotlib画出损失曲线,如果前 10 个 epoch 没有明显下降,先调学习率而不是调网络结构。这套排查顺序能帮你省下大量重复训练的时间。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 4:04:30

中小企业轻量级Agent落地实操指南(2026最新)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 4:03:18

MinIO与kkfileview集成:构建企业级文件在线预览系统的完整实践

先说个场景:项目做到中期,客户提了个需求——“合同、图纸、PDF这些文件,能不能在系统里直接点开看,别让用户下载到本地再找软件打开”。这需求听起来普通,真做起来全是细节。文件预览这件事,最麻烦的地方不…

作者头像 李华
网站建设 2026/9/12 4:03:17

Redis集群Lua脚本跨slot错误解析与共置方案

1. 问题现场还原:为什么集群里跑Lua脚本会突然报错?刚接手一个电商订单履约系统的Redis集群,线上监控突然报警:大量ERR bad lua script for redis cluster, all the keys that the script uses should be in the same hash slot错…

作者头像 李华
网站建设 2026/9/12 4:02:54

C#操作Excel:NPOI与EPPlus对比与实战指南

1. C#操作Excel的两种主流方案对比在.NET生态中,NPOI和EPPlus是处理Excel文件最常用的两个开源库。我经手过的企业级项目中,约60%使用EPPlus,30%使用NPOI,剩下10%会选择付费组件。先来看它们的核心差异:特性NPOIEPPlus…

作者头像 李华
网站建设 2026/9/12 4:02:52

四个月实测SEKO计量泵替代:四款加药设备选型对比与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 4:02:51

PS神经滤镜离线安装包详解:解决下载失败,一步到位

1. 神经滤镜离线包到底解决了什么问题 说实话,我第一次在PS2022里打开神经滤镜Neural Filters面板时,内心是崩溃的。面板能弹出来,但里面大部分滤镜都灰着,点开“皮肤平滑度”或者“智能肖像”,提示莫名其妙&#xff0…

作者头像 李华