news 2026/10/15 21:49:08

电子科技大学机器学习期末考点精解:梯度下降、决策树、SVM与PCA实战图谱

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
电子科技大学机器学习期末考点精解:梯度下降、决策树、SVM与PCA实战图谱

简介:本资源为电子科技大学《机器学习》课程期末考试真题及核心知识点精要汇编,面向该校本科生、考研复习者及自学机器学习的进阶学习者,助力系统梳理课程重点、查漏补缺与应试冲刺。压缩包为单个PDF文件(1008KB),内容涵盖梯度下降、交叉验证、过拟合分析、线性回归、决策树、朴素贝叶斯、MP模型、K-means、PCA、SVM、CNN等11大核心模块的定义、原理、公式推导、算法流程与典型考题(含4道简答题+5道计算题),并附有互信息选择特征、软间隔SVM、PCA信号重构、K-means与EM算法对比等高频考点深度解析。目前已有6460人学习下载,内容结构清晰、术语规范、图文结合紧密,既可作为考前速记手册,亦能支撑对监督/无监督/深度学习主线的贯通式理解。

1. 电子科技大学机器学习期末考试:不是刷题手册,而是你手头缺的那套「可执行知识图谱」

如果你正对着“电子科技大学 机器学习”这八个字发愁——不是因为没学过梯度下降,而是不知道考题里那个“用互信息选特征”的决策树题,到底该写公式推导、还是画分裂过程、还是直接套 sklearn 的entropy参数;不是因为不懂 SVM,而是卡在“线性不可分时软间隔的拉格朗日对偶问题怎么列约束”,更别说 K-means 目标函数里那个平方误差和 EM 算法的隐变量期望步到底差在哪——那你手里的这份资源,就是一份带注释的考场黑匣子解包记录。

它不是课程 PPT 的搬运工,也不是某位同学的潦草笔记扫描件。它是把电子科技大学机器学习期末考试中反复出现的 11 类核心考点(梯度下降、交叉验证、过拟合诊断、线性回归变形、决策树剪枝逻辑、朴素贝叶斯独立性假设的失效边界、MP 模型与感知机的数学等价性、K-means 收敛陷阱、PCA 重构误差的显式表达、SVM 支持向量的几何定位、CNN 卷积核参数与感受野的映射关系),全部还原成可运行、可调试、可对照考题逐行验证的代码+推导+参数表。适合两类人:一类是临考前 72 小时想把“概念定义”转化成“得分步骤”的实战派;另一类是刚学完理论、但面对“k-means 流程”四个字仍不知从哪一行 Python 开始写的动手党。它不讲“机器学习有多重要”,只解决“这道简答题第三问,我该写几行公式、几个图、几个 if 判断”。


2. 梯度下降与线性回归:从数学推导到 NumPy 实现,为什么你的 loss 曲线总在震荡?

2.1 梯度下降的本质不是“下山”,而是“局部线性近似下的最优步长选择”

很多初学者把梯度下降理解成“找最陡方向往下走一步”,这没错,但漏掉了关键前提:每一步都默认当前邻域内函数可被一阶泰勒展开良好逼近。也就是说,梯度下降成立的隐含条件是:步长 α 要足够小,使得高阶项(如 Hessian)影响可忽略;同时,目标函数得是连续可微的(否则梯度不存在)。电子科技大学考题常在此设坑——比如给出一个带绝对值的损失函数(如 L1 回归),问能否直接用标准梯度下降?答案是否定的,因为 |x| 在 x=0 不可导,必须改用次梯度(subgradient)或转为坐标下降法。

提示:考试若出现“非光滑损失函数”,优先检查是否可分段求导;若不可分段,则默认考察的是次梯度思想,而非具体计算。

我们以最典型的最小二乘线性回归为例,目标函数为:

$$ J(\theta) = \frac{1}{2m} \sum_{i=1}^{m} (h_\theta(x^{(i)}) - y^{(i)})^2, \quad h_\theta(x) = \theta^T x $$

其梯度为:

$$ \nabla_\theta J(\theta) = \frac{1}{m} X^T (X\theta - y) $$

注意这里多了一个 $\frac{1}{m}$ ——这是电子科大考题中高频出现的缩放因子陷阱。很多学生推导出 $X^T(X\theta - y)$ 就停笔,但实际实现时若漏掉 $\frac{1}{m}$,会导致 learning rate α 必须同步缩小 m 倍才能收敛,否则 loss 爆炸。

2.2 手写 NumPy 版梯度下降:三步封装,拒绝魔数硬编码

下面这段代码不是为了炫技,而是严格对应电子科大实验题“实现单变量线性回归并绘制 loss 曲线”的评分点:① 正确初始化 θ;② 正确计算梯度;③ 正确更新并记录 loss。每行都有考题映射。

import numpy as np import matplotlib.pyplot as plt def gradient_descent_linear(X, y, alpha=0.01, iterations=1500): """ X: (m, n) design matrix, with bias column added (x0 = 1) y: (m,) target vector alpha: learning rate (考题常给 0.01 或 0.001,注意单位一致性) iterations: max iteration count (考题若说"迭代100次",此处填100) """ m, n = X.shape theta = np.zeros(n) # 初始化:考题明确要求"零初始化",不能随机 J_history = np.zeros(iterations) for i in range(iterations): # 核心得分点1:梯度计算必须含 1/m 缩放 predictions = X @ theta error = predictions - y gradient = (1/m) * X.T @ error # ← 这里漏1/m,整题扣3分 # 核心得分点2:参数更新公式必须写成 theta = theta - alpha * gradient theta = theta - alpha * gradient # 核心得分点3:loss 计算必须用均方误差(非平方和) J_history[i] = (1/(2*m)) * np.sum(error ** 2) # ← 注意是 1/(2m),不是 1/2m 或 1/2*m return theta, J_history # 构造考题典型数据:单变量 + 截距项 np.random.seed(42) X_raw = np.random.uniform(0, 10, 100).reshape(-1, 1) y = 3.5 * X_raw.flatten() + 2.1 + np.random.normal(0, 2, 100) # y = 3.5x + 2.1 + noise X = np.column_stack([np.ones(100), X_raw]) # 添加 x0 = 1 theta_final, loss_log = gradient_descent_linear(X, y, alpha=0.01, iterations=1500) # 验证:与 sklearn 结果对比(考试不考,但自测必备) from sklearn.linear_model import LinearRegression lr = LinearRegression().fit(X_raw, y) print(f"手写结果: θ0={theta_final[0]:.3f}, θ1={theta_final[1]:.3f}") print(f"sklearn结果: θ0={lr.intercept_:.3f}, θ1={lr.coef_[0]:.3f}")

参数说明与考题映射:

  • alpha=0.01:电子科大近年考题中 learning rate 固定为 0.01 或 0.001,若题目未指定,必须写“取常用值 0.01”;
  • iterations=1500:考题若说“运行至收敛”,需明确定义收敛条件(如|J(i)-J(i-1)| < 1e-6),但简答题通常给固定轮数;
  • X = np.column_stack([np.ones(m), X_raw]):必须显式添加偏置列,这是线性回归建模的强制步骤,漏写则模型无截距项,与考题“拟合直线 y=ax+b”矛盾。

2.3 为什么你的 loss 曲线总在震荡?三个致命参数错误

现象:loss 曲线先降后升,或持续锯齿状波动

原因:learning rate α 过大,导致每次更新越过极小值点,在谷底两侧反复横跳。数学上,当 α > 2/λ_max(λ_max 为 Hessian 最大特征值)时,GD 发散。
解决:将 α 缩小 10 倍重试(如从 0.01 → 0.001),或改用自适应学习率(如 Adagrad,但考试不考)。

现象:loss 下降极慢,1500 轮后仍远高于 sklearn 结果

原因:未对特征做归一化(feature scaling)。当 X 中一列是房屋面积(单位:平方米,范围 50–500),另一列是房间数(1–10),二者量纲差两个数量级,梯度方向严重倾斜,GD 沿窄谷“之字形”爬行。
解决:考试若给原始数据(如“身高/cm, 体重/kg”),必须先做 Z-score 归一化:X_scaled = (X - X.mean(axis=0)) / X.std(axis=0)。电子科大 2022 年真题明确要求“写出归一化步骤”。

现象:loss 在第 10 轮就降到 1e-10,但预测结果完全偏离

原因:数据中存在异常值(outlier),而 MSE 损失对异常值极度敏感(平方放大效应)。梯度被少数离群点主导,θ 被强行拉偏。
解决:考试中若发现此现象,应立即检查数据分布(画 scatter plot),并在答案中注明:“建议改用鲁棒损失如 Huber Loss,或先用 IQR 法剔除异常值”。这是加分项,体现工程意识。


3. 决策树与朴素贝叶斯:从信息增益到条件独立假设,考题里的“伪代码陷阱”

3.1 决策树三大得分模块:特征选择、生成、剪枝,缺一不可

电子科技大学考题对决策树的考察,绝不止于“画一棵树”。它拆解为三个强耦合步骤,且每步都有明确的数学表达要求:

  1. 特征选择:必须写出信息增益(IG)或信息增益比(GR)的完整公式,并说明为何用 IG 而非纯度(purity);
  2. 树生成:必须描述递归分裂的终止条件(如样本数 < 5,或所有标签相同),不能只说“一直分到叶子”;
  3. 剪枝:必须区分预剪枝(pre-pruning)与后剪枝(post-pruning),并指出电子科大偏好后剪枝(因预剪枝易欠拟合)。

我们以“是否打网球”经典数据集为例,手写信息增益计算逻辑(考试简答题第 2 问标准答案模板):

from collections import Counter import math def entropy(y): """计算标签集合 y 的信息熵""" n = len(y) if n == 0: return 0 counts = Counter(y) return -sum((count/n) * math.log2(count/n) for count in counts.values()) def information_gain(X, y, feature_idx, threshold): """ 计算按第 feature_idx 列、以 threshold 分裂的信息增益 X: (m, n) 特征矩阵;y: (m,) 标签向量 返回: IG 值,及左右子集索引 """ left_mask = X[:, feature_idx] <= threshold right_mask = ~left_mask y_left, y_right = y[left_mask], y[right_mask] n, n_left, n_right = len(y), len(y_left), len(y_right) # 父节点熵 H_parent = entropy(y) # 子节点加权熵 H_children = (n_left/n) * entropy(y_left) + (n_right/n) * entropy(y_right) IG = H_parent - H_children return IG, left_mask, right_mask # 示例:假设数据集中第 0 列是 Outlook,已编码为 [0,1,2],阈值取 1.5(即 <=1 为 Sunny/Overcast,>1 为 Rain) # 考试若给离散特征,阈值为分割点(如 Outlook ∈ {Sunny, Overcast, Rain},则需遍历所有可能二分组合) X_sample = np.array([[0,1,0,0], [0,1,0,1], [1,1,0,0], [2,0,1,0]]) # 简化版 y_sample = np.array(['No', 'No', 'Yes', 'Yes']) IG_val, left_idx, right_idx = information_gain(X_sample, y_sample, feature_idx=0, threshold=1.5) print(f"Outlook 以 1.5 分裂的信息增益: {IG_val:.4f}")

关键得分点解析:

  • entropy()函数中log2不可写成ln或log10,信息论中单位是 bit;
  • H_children的加权必须用样本数比例(n_left/n),不能简单平均;
  • 对离散特征(如 Outlook),考试不会让你算连续阈值,而是要求“列出所有可能的二分方式(Sunny vs {Overcast,Rain} 等),计算每种的 IG,选最大者”——这就是为什么代码里强调“需遍历所有可能二分组合”。

3.2 朴素贝叶斯:独立性假设不是“错”,而是“可控的简化”

学生常误以为“朴素贝叶斯假设属性独立,所以不准”。但电子科大考题恰恰要你解释:为何这个明显违背现实的假设,反而在文本分类等任务中效果惊人?

答案在于:
①计算可行性:若无独立性假设,联合概率 $P(x_1,x_2,...,x_n|y)$ 需估计 $O(K^n)$ 个参数(K 为每维取值数),而朴素假设下只需 $O(nK)$;
②偏差-方差权衡:虽然引入了偏差(bias),但极大降低了方差(variance),在小样本下泛化更好;
③排序不变性:即使联合概率估计不准,但 $P(y=1|x)/P(y=0|x)$ 的比值序往往正确,而分类只依赖序。

考试常考题:“若某数据集里,特征 A 和 B 高度相关(如‘是否下雨’和‘是否带伞’),朴素贝叶斯会怎样?”
标准答案:模型会重复计数相关特征带来的证据,导致后验概率 $P(y|x)$ 被高估,但分类决策边界(即 $P(y=1|x) > P(y=0|x)$)可能不变——这就是“错得一致,仍能分类”。

下面用 NumPy 手写朴素贝叶斯分类器(对应考题“实现离散型朴素贝叶斯”):

class NaiveBayesDiscrete: def __init__(self): self.class_prior = {} self.feature_probs = {} # {class: {feature_idx: {value: prob}}} def fit(self, X, y): m, n = X.shape classes = np.unique(y) # 1. 计算先验概率 P(y) for c in classes: self.class_prior[c] = np.sum(y == c) / m # 2. 计算似然 P(x_i|y) —— 关键:拉普拉斯平滑!考试必写 for c in classes: X_c = X[y == c] # 取出类别 c 的所有样本 self.feature_probs[c] = {} for j in range(n): # 统计第 j 维各取值频次 values, counts = np.unique(X_c[:, j], return_counts=True) total = len(X_c) # 拉普拉斯平滑:分子+1,分母+取值数(避免 0 概率) n_values = len(values) smoothed_probs = (counts + 1) / (total + n_values) self.feature_probs[c][j] = dict(zip(values, smoothed_probs)) def predict(self, X): m, n = X.shape preds = [] for i in range(m): log_probs = {} for c in self.class_prior: # 先验对数概率 log_prob = np.log(self.class_prior[c]) # 似然对数概率(连乘变连加) for j in range(n): val = X[i, j] # 若测试值未在训练中出现,用平滑后概率 1/(total+n_values) if val in self.feature_probs[c][j]: log_prob += np.log(self.feature_probs[c][j][val]) else: # 考试若问“未登录词如何处理”,答:拉普拉斯平滑已覆盖 log_prob += np.log(1 / (len(self.feature_probs[c][j]) + 1)) log_probs[c] = log_prob preds.append(max(log_probs, key=log_probs.get)) return np.array(preds) # 使用示例(模拟考题数据) X_train = np.array([[0,0], [0,1], [1,0], [1,1]]) y_train = np.array(['No', 'No', 'Yes', 'Yes']) nb = NaiveBayesDiscrete() nb.fit(X_train, y_train) print("预测结果:", nb.predict(np.array([[0,0], [1,1]])))

参数与考题强关联:

  • 拉普拉斯平滑:考试必写!若未写,遇到测试样本某特征值未在训练中出现,概率为 0,整个后验为 0,直接判错;
  • 对数概率:必须用log避免浮点下溢(多个小概率连乘趋近 0),这是数值稳定性考点;
  • dict(zip(...)):体现对离散值映射的理解,若用数组索引需先做 label encoding,但考题通常已编码。

3.3 避坑:决策树与朴素贝叶斯的五大翻车现场

翻车 1:信息增益计算中混淆“数据集熵”与“特征熵”

现象:在计算IG = H(D) - Σ |D_v|/|D| * H(D_v)时,把H(D_v)错写成H(特征_v)(即只算该特征取值的熵,而非子集标签的熵)。
原因:没吃透信息增益本质是“用特征划分后,标签不确定性减少了多少”,只关注特征本身分布。
解决:死记硬背:H(D_v)永远是子集D_v中y 的分布熵,与 X 无关。

翻车 2:朴素贝叶斯预测时未取对数,导致 underflow

现象:预测结果全为同一类,或报RuntimeWarning: divide by zero encountered in log。
原因:概率连乘后值极小(如 1e-300),float64 下溢为 0,log(0) 报错。
解决:必须用log(P(y)) + Σ log(P(x_i|y)),且初始化log_prob = log(P(y)),不是log_prob = 0。

翻车 3:决策树生成时忽略“纯度为 0”的终止条件

现象:递归分裂无限进行,或生成深度极大的树(如 20 层),明显过拟合。
原因:只写了if len(y) < 5: return leaf,但没写if len(set(y)) == 1: return leaf(所有标签相同,无需再分)。
解决:考试标准答案必须包含这两个终止条件,缺一不可。

翻车 4:K 折交叉验证中“数据泄露”

现象:验证集准确率虚高(如 98%),但实际部署效果差。
原因:在for fold in folds:循环外做了特征归一化(如X_scaled = StandardScaler().fit_transform(X)),导致验证集信息“提前”流入训练。
解决:每折内独立 fit-transform 训练集,再 transform 验证集。电子科大 2023 年考题明确要求“写出交叉验证中归一化的正确位置”。

翻车 5:SVM 支持向量识别错误

现象:答“支持向量是离超平面最近的点”,但未强调“且满足 y_i(w^T x_i + b) = 1”。
原因:混淆了几何距离与函数间隔。SVM 的约束是函数间隔 ≥1,支持向量是使等号成立的点。
解决:必须写出数学定义:{x_i | y_i(w^T x_i + b) = 1},这是得分关键词。


4. K-means、PCA 与 SVM:从聚类目标函数到核技巧,考场上的“三座大山”怎么拆?

4.1 K-means:目标函数、收敛性与和 EM 算法的本质区别

K-means 表面简单,但电子科技大学考题深挖其优化本质。核心有三问:
① 目标函数是什么?
② 为什么它不保证全局最优?
③ 它和 EM 算法什么关系?

答案如下:
①目标函数:最小化簇内平方误差(WCSS)
$$ \min_{C_1,...,C_k} \sum_{i=1}^k \sum_{x \in C_i} |x - \mu_i|^2, \quad \mu_i = \frac{1}{|C_i|}\sum_{x \in C_i} x $$
注意:μ_i 是显式定义的质心,不是待优化变量——这是 K-means 与一般优化问题的关键区别。

②不保证全局最优:因为算法是坐标下降(coordinate descent):固定质心 → 分配样本;固定分配 → 更新质心。每步下降,但整体可能陷于局部极小。考试若问“如何缓解”,答:多初始化(multiple random restarts),即运行 10 次不同初始质心,选 WCSS 最小者。

③与 EM 区别:EM 算法中隐变量是概率分配(每个样本属于各簇的概率),而 K-means 是硬分配(0-1 分配)。K-means 可视为 EM 在隐变量服从退化分布(degenerate distribution)下的特例。考试若问“K-means 是 EM 吗”,答:是 EM 的硬分配近似,但非严格 EM。

下面实现带多初始化的 K-means(对应考题“编写 K-means 并分析收敛性”):

def kmeans(X, k, max_iters=100, n_init=10): """ X: (m, n) 数据矩阵 k: 簇数(考题若说"k=3",此处填3) n_init: 多初始化次数(考试若问"如何避免局部最优",答:增大n_init) """ m, n = X.shape best_WCSS = float('inf') best_labels = None best_centroids = None for _ in range(n_init): # 随机初始化质心(考题若要求"用k-means++",则此处替换为kmeans++逻辑) centroids = X[np.random.choice(m, k, replace=False)] for _ in range(max_iters): # E-step: 硬分配,计算每个点到各质心距离 distances = np.sqrt(((X - centroids[:, np.newaxis])**2).sum(axis=2)) labels = np.argmin(distances, axis=0) # shape (m,) # M-step: 更新质心 new_centroids = np.array([X[labels == i].mean(axis=0) for i in range(k)]) # 检查收敛:质心不再变化(考试若问"收敛条件",答:||c_new - c_old|| < ε) if np.allclose(centroids, new_centroids): break centroids = new_centroids # 计算本次初始化的 WCSS WCSS = 0 for i in range(k): cluster_points = X[labels == i] if len(cluster_points) > 0: WCSS += np.sum((cluster_points - centroids[i])**2) if WCSS < best_WCSS: best_WCSS = WCSS best_labels = labels best_centroids = centroids return best_labels, best_centroids, best_WCSS # 示例:生成环形数据(考题常见"K-means 对非凸簇失效"案例) from sklearn.datasets import make_moons X_moons, _ = make_moons(n_samples=300, noise=0.05, random_state=42) labels, centroids, wcss = kmeans(X_moons, k=2, n_init=5) print(f"最优 WCSS: {wcss:.2f}")

参数与考题映射:

  • n_init=10:考试若问“如何提高 K-means 稳定性”,必须答“增加初始化次数”,并给出典型值(5–10);
  • np.allclose(centroids, new_centroids):收敛判断必须用范数比较,不能centroids == new_centroids(浮点精度);
  • make_moons:电子科大近年考题多次用环形/半月形数据,考查“K-means 无法处理非凸簇”,需在答案中指出并建议换 DBSCAN。

4.2 PCA:从协方差矩阵特征分解到信号重构,考题最爱的“两问一图”

PCA 在电子科大考试中,几乎必考三连问:
① 推导主成分为何是协方差矩阵的特征向量?
② 如何用前 d 个主成分重构原始信号?重构误差是多少?
③ 画出原始数据、投影后数据、重构后数据的 scatter plot。

我们逐个击破。

① 特征向量推导(考试简答题标准答案):
目标:找单位向量 w,使投影方差最大:$\max_w w^T \Sigma w$,s.t. $w^T w = 1$。
构造拉格朗日函数:$\mathcal{L}(w,\lambda) = w^T \Sigma w - \lambda(w^T w - 1)$。
求导:$\frac{\partial \mathcal{L}}{\partial w} = 2\Sigma w - 2\lambda w = 0$ → $\Sigma w = \lambda w$。
故 w 是 Σ 的特征向量,λ 是对应特征值。最大特征值对应的特征向量,即第一主成分。

② 信号重构与误差(考试计算题核心):
设原始数据 X(中心化后),协方差矩阵 Σ = (1/m) X^T X,特征分解 Σ = V Λ V^T。
取前 d 列 V_d,则:

  • 降维:$Z = X V_d$ (shape: m×d)
  • 重构:$\hat{X} = Z V_d^T = X V_d V_d^T$
  • 重构误差(Frobenius 范数):$|\hat{X} - X|F^2 = \sum{i=d+1}^n \lambda_i$,即舍弃的特征值之和。

这是考试计算题的黄金公式!若给协方差矩阵特征值 [5.2, 2.1, 0.8, 0.1],问“保留前2主成分的重构误差”,答:0.8 + 0.1 = 0.9。

def pca_reconstruct(X, d): """ X: (m, n) 中心化后的数据(考试若给原始数据,必须先 center!) d: 保留主成分数量 返回: 重构数据 X_hat, 重构误差 """ m, n = X.shape # 中心化(考试若数据未中心化,此步必做!) X_centered = X - np.mean(X, axis=0) # 协方差矩阵 & 特征分解 cov = (1/m) * X_centered.T @ X_centered eigenvals, eigenvecs = np.linalg.eigh(cov) # eigh 用于对称阵,更稳定 # 按特征值降序排列 idx = np.argsort(eigenvals)[::-1] eigenvals = eigenvals[idx] eigenvecs = eigenvecs[:, idx] # 取前 d 个主成分 V_d = eigenvecs[:, :d] Z = X_centered @ V_d # 降维 X_hat = Z @ V_d.T # 重构 # 重构误差 = 舍弃特征值之和 reconstruction_error = np.sum(eigenvals[d:]) return X_hat, reconstruction_error, eigenvals # 示例:生成二维高斯数据,验证重构 np.random.seed(42) X_gauss = np.random.multivariate_normal([0,0], [[4,1],[1,1]], 200) X_hat, err, vals = pca_reconstruct(X_gauss, d=1) print(f"保留1主成分的重构误差: {err:.3f} (理论值: {vals[1]:.3f})")

③ 三图同绘(考试绘图题模板):
必须在同一 figure 中画:左图原始数据,中图投影到第一主成分(即 Z),右图重构数据。重点标出主成分方向(特征向量)。

4.3 SVM:从硬间隔到软间隔,核函数不是魔法,是映射工具

SVM 是电子科大考试的压轴题常客。难点不在公式,而在条件反射式匹配场景:

  • 看到“数据线性可分”,立刻写硬间隔优化:$\min \frac{1}{2}|w|^2$ s.t. $y_i(w^T x_i + b) \geq 1$;
  • 看到“有噪声/重叠”,立刻写软间隔:$\min \frac{1}{2}|w|^2 + C \sum \xi_i$ s.t. $y_i(w^T x_i + b) \geq 1 - \xi_i, \xi_i \geq 0$;
  • 看到“图像/文本”,立刻想到 RBF 核:$K(x_i,x_j) = \exp(-\gamma |x_i - x_j|^2)$。

下面实现软间隔 SVM 的对偶问题求解(用 cvxopt,考试允许调库):

from cvxopt import matrix, solvers import numpy as np def svm_dual_soft(X, y, C=1.0): """ 解软间隔SVM对偶问题 X: (m,n), y: (m,) in {-1,1} 返回: alpha, b, support_vectors """ m, n = X.shape y = y.astype(float) # 构造QP问题: min (1/2)α^T P α - 1^T α # s.t. y^T α = 0, 0 ≤ α_i ≤ C K = np.zeros((m, m)) for i in range(m): for j in range(m): # 线性核 K(x_i,x_j) = x_i^T x_j K[i,j] = X[i] @ X[j] P = matrix(np.outer(y,y) * K) # P_ij = y_i y_j K(x_i,x_j) q = matrix(-np.ones(m)) G = matrix(np.vstack([-np.eye(m), np.eye(m)])) # -I and I for 0≤α≤C h = matrix(np.hstack([np.zeros(m), np.ones(m)*C])) A = matrix(y.reshape(1,-1)) b = matrix(0.0) solvers.options['show_progress'] = False solution = solvers.qp(P, q, G, h, A, b) alphas = np.ravel(solution['x']) # 找支持向量 (0 < alpha < C) sv = (alphas > 1e-5) & (alphas < C - 1e-5) # 计算 b (用任意一个支持向量) b = 0 for i in range(m): if sv[i]: b += y[i] for j in range(m): if sv[j]: b -= alphas[j] * y[j] * K[i,j] b /= y[i] break return alphas, b, sv # 示例:线性不可分数据 from sklearn.datasets import make_blobs X_svm, y_svm = make_blobs(n_samples=50, centers=2, cluster_std=1.5, random_state=42) y_svm = np.where(y_svm == 0, -1, 1) # SVM 要求 y in {-1,1} alphas, b, sv_idx = svm_dual_soft(X_svm, y_svm, C=1.0) print(f"支持向量数量: {np.sum(sv_idx)}")

参数与考题强绑定:

  • C=1.0:考试若问“C 的作用”,答:控制间隔最大化与误分类惩罚的权衡;C 大 → 更少误分类,间隔可能变小;C 小 → 更大间隔,容忍更多误分类;
  • K[i,j] = X[i] @ X[j]:这是线性核;若考题说“使用RBF核”,则替换为np.exp(-gamma * np.sum((X[i]-X[j])**2)),gamma 是超参;
  • sv = (alphas > 1e-5) & (alphas < C - 1e-5):支持向量的 alpha 严格在 (0,C) 内,等于 0 或 C 的不是支持向量(等于 C 的是边界上的误分类点)。

5. 模型评估与过拟合诊断:交叉验证不是流程,而是误差估计的统计学实践

5.1 k 折交叉验证:为什么是 k=5 或 k=10?不是 k=2 或 k=100?

学生

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

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

AI辅助软件工程毕业设计全流程:6款工具从需求分析到答辩

又到了一年一度熬夜赶毕设的季节。软件工程专业的毕业设计和别的专业不一样&#xff0c;它不是交一份报告就完事&#xff0c;而是要交付一个真能跑起来、演示得了、答辩经得起追问的系统。需求分析、数据库设计、后端接口、前端页面、测试用例、项目文档、答辩PPT&#xff0c;整…

作者头像 李华
网站建设 2026/10/15 21:48:52

SpringBoot+Vue3前后端分离物资申报系统:库存防超发与权限设计实战

这套仓库是 SpringBoot Vue3 MyBatis 的前后端分离社区防疫物资申报系统&#xff0c;覆盖了物资申报、审核发放、出入库台账、记录归档一整套链路。单看功能&#xff0c;它并不算复杂&#xff0c;但凡是做过管理系统的都知道&#xff0c;这类业务的关键从来不在增删改查&…

作者头像 李华
网站建设 2026/10/15 21:48:14

STL容器竞赛常用操作全指南:从vector到priority_queue避坑技巧

搞竞赛的都清楚&#xff0c;算法思路想明白只是第一步&#xff0c;真正让代码“跑得起来、交得上去”的&#xff0c;往往是你对STL容器操作的熟练程度。STL容器在竞赛里承担的角色很实在&#xff1a;帮你省掉手写平衡树、手写堆、手写链表的那些体力活&#xff0c;把时间留给核…

作者头像 李华
网站建设 2026/10/15 21:48:05

用大模型API打造哄哄模拟器:Prompt工程实战拆解

“哄哄模拟器”这个名字&#xff0c;乍一听像是用来哄对象开心的小游戏&#xff0c;但实际上它是我用大模型API折腾出来的一个“prompt开发游戏”——角色说什么话、情绪怎么变化、你哄得成不成功&#xff0c;全部由Prompt来驱动&#xff0c;代码只是包在外面的一层薄壳。整个玩…

作者头像 李华
网站建设 2026/10/15 21:46:45

ThinkPHP6+Layui后台开发实战:从环境搭建到权限管理

1. 为什么我最终选了tp6layui这个组合来写后台先说结论&#xff1a;这不是什么“最新最潮”的技术栈&#xff0c;但如果你要快速交付一个企业内部可用的后台管理系统&#xff0c;tp6layui至今仍然是非常稳的一套搭配。我这两年用这个组合做过的项目&#xff0c;从进销存后台到内…

作者头像 李华
网站建设 2026/10/15 21:46:31

PyTorch线性层nn.Linear深度拆解:从数学原理到代码实战与避坑指南

1. linear层本质拆解&#xff1a;从数学公式到代码实现很多人第一次接触PyTorch里的nn.Linear&#xff0c;都是从MNIST手写数字识别或者房价预测这类入门Demo开始的。代码里往往就是一行self.fc nn.Linear(784, 10)&#xff0c;跑通之后感觉“哦&#xff0c;就是这么个东西”&…

作者头像 李华