# 机器学习(西瓜书)- 核心知识点精解 **作者:** 周志华 **整理:** Deshill **日期:** 2026-03-18 **难度:** 进阶(适合有基础者自学) --- ## 📖 目录 1. 第 1 章 绪论 2. 第 2 章 模型评估与选择 3. 第 3 章 线性模型 4. 第 4 章 决策树 5. 第 5 章 神经网络 6. 第 6 章 支持向量机 7. 第 7 章 贝叶斯分类器 --- ## 第 1 章 绪论 ### 1.1 机器学习定义 **形式化定义:** > 如果一个程序在某类任务 T 上的性能 P,随着经验 E 的积累而提高,则称该程序从经验 E 中学习。 **数学表达:** ``` 学习过程 = 从数据 D 中归纳假设 h 的过程 目标:找到 h ∈ H,使得 h ≈ f(真实函数) ``` ### 1.2 基本概念 #### 术语对照表 | 西瓜书术语 | 通用术语 | 英文 | |-----------|---------|------| | 示例 | 样本 | instance/sample | | 属性 | 特征 | attribute/feature | | 属性值 | 特征值 | attribute value | | 属性空间 | 特征空间 | attribute space | | 向量 | 特征向量 | feature vector | | 标记 | 标签 | label | | 样例 | 带标签的样本 | example | | 学得模型 | 假设 | hypothesis | | 潜在规律 | 真实函数 | ground-truth | #### 数据表示 ```python import numpy as np # 数据集表示 # X: 特征矩阵 (m×d),m 个样本,d 个特征 # y: 标签向量 (m×1) X = np.array([ [0.697, 0.460, 1], # 样本 1: 色泽=0.697, 根蒂=0.460, 敲声=1 [0.774, 0.376, 2], # 样本 2 [0.634, 0.264, 1], # 样本 3 ]) y = np.array([1, 1, 0]) # 1=好瓜,0=坏瓜 ``` ### 1.3 学习任务类型 #### 分类 vs 回归 vs 聚类 ```python from sklearn import datasets from sklearn.model_selection import train_test_split # 1. 分类任务(离散标签) iris = datasets.load_iris() X_train, X_test, y_train, y_test = train_test_split( iris.data, iris.target, test_size=0.3 ) # y ∈ {0, 1, 2} (离散) # 2. 回归任务(连续标签) boston = datasets.load_boston() X_train, X_test, y_train, y_test = train_test_split( boston.data, boston.target, test_size=0.3 ) # y ∈ R (连续) # 3. 聚类任务(无标签) X = datasets.make_blobs(n_samples=100, centers=3)[0] # 无 y,需要发现内在结构 ``` --- ## 第 2 章 模型评估与选择 ### 2.1 经验误差与过拟合 #### 三种误差定义 - **训练误差**:在训练集上的误差 - **验证误差**:在验证集上的误差 - **测试误差**:在测试集上的误差(泛化误差的近似) #### 过拟合 vs 欠拟合 | 情况 | 训练误差 | 验证误差 | 解决方案 | |------|---------|---------|---------| | 欠拟合 | 高 | 高 | 增加模型复杂度、添加特征 | | 过拟合 | 低 | 高 | 正则化、增加数据、减少特征 | | 合适 | 低 | 低 | - | ### 2.2 评估方法 #### 1. 留出法 (Hold-out) ```python from sklearn.model_selection import train_test_split X_train, X_val, y_train, y_val = train_test_split( X, y, test_size=0.3, stratify=y, random_state=42 ) ``` #### 2. 交叉验证法 ```python from sklearn.model_selection import cross_val_score, KFold kf = KFold(n_splits=5, shuffle=True, random_state=42) scores = cross_val_score(model, X, y, cv=kf, scoring='accuracy') print(f"平均准确率:{scores.mean():.4f}") ``` ### 2.3 性能度量 #### 分类任务 ```python from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, roc_auc_score y_pred = model.predict(X_test) y_prob = model.predict_proba(X_test)[:, 1] accuracy = accuracy_score(y_test, y_pred) precision = precision_score(y_test, y_pred) recall = recall_score(y_test, y_pred) f1 = f1_score(y_test, y_pred) auc = roc_auc_score(y_test, y_prob) ``` #### 混淆矩阵 ``` 预测 正例 反例 实际 正例 TP FN 反例 FP TN 精确率 (Precision) = TP / (TP+FP) # 预测为正的有多少真对 召回率 (Recall) = TP / (TP+FN) # 实际正的有多少被找出 F1 = 2 × (P × R) / (P + R) ``` --- ## 第 3 章 线性模型 ### 3.1 线性回归 #### 最小二乘法 ```python import numpy as np class LinearRegression: def fit(self, X, y): X_b = np.c_[np.ones((X.shape[0], 1)), X] theta = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y) self.b, self.w = theta[0], theta[1:] return self def predict(self, X): return X.dot(self.w) + self.b ``` #### 梯度下降法 ```python class LinearRegressionGD: def __init__(self, lr=0.01, n_iterations=1000): self.lr = lr self.n_iterations = n_iterations def fit(self, X, y): n_samples, n_features = X.shape self.w = np.zeros(n_features) self.b = 0 for _ in range(self.n_iterations): y_pred = X.dot(self.w) + self.b dw = (1/n_samples) * X.T.dot(y_pred - y) db = (1/n_samples) * np.sum(y_pred - y) self.w -= self.lr * dw self.b -= self.lr * db return self ``` ### 3.2 对数几率回归 ```python def sigmoid(z): return 1 / (1 + np.exp(-z)) # P(y=1|x) = σ(w^T x + b) # ln(P/(1-P)) = w^T x + b (对数几率) from sklearn.linear_model import LogisticRegression lr = LogisticRegression(penalty='l2', C=1.0, solver='lbfgs') ``` ### 3.3 正则化 ```python from sklearn.linear_model import Ridge, Lasso, ElasticNet # L2 正则化 (Ridge): ||y - Xw||² + α||w||² ridge = Ridge(alpha=1.0) # L1 正则化 (Lasso): ||y - Xw||² + α||w||₁ lasso = Lasso(alpha=0.1) # ElasticNet (L1 + L2) elastic = ElasticNet(alpha=0.1, l1_ratio=0.5) ``` --- ## 第 4 章 决策树 ### 4.1 划分选择 #### 信息增益 (ID3) ```python def calc_entropy(y): _, counts = np.unique(y, return_counts=True) probs = counts / len(y) return -np.sum(probs * np.log2(probs + 1e-10)) def calc_info_gain(X, y, attribute_idx): entropy_D = calc_entropy(y) values = np.unique(X[:, attribute_idx]) entropy_cond = 0 for value in values: mask = X[:, attribute_idx] == value y_v = y[mask] weight = len(y_v) / len(y) entropy_cond += weight * calc_entropy(y_v) return entropy_D - entropy_cond ``` #### 增益率 (C4.5) ```python def calc_gain_ratio(X, y, attribute_idx): info_gain = calc_info_gain(X, y, attribute_idx) iv = calc_intrinsic_value(X, attribute_idx) return info_gain / (iv + 1e-10) ``` #### 基尼指数 (CART) ```python def calc_gini(y): _, counts = np.unique(y, return_counts=True) probs = counts / len(y) return 1 - np.sum(probs ** 2) def calc_gini_index(X, y, attribute_idx): values = np.unique(X[:, attribute_idx]) gini_index = 0 for value in values: mask = X[:, attribute_idx] == value y_v = y[mask] weight = len(y_v) / len(y) gini_index += weight * calc_gini(y_v) return gini_index ``` ### 4.2 剪枝处理 ```python from sklearn.tree import DecisionTreeClassifier # 预剪枝 dt = DecisionTreeClassifier( max_depth=3, min_samples_split=10, min_samples_leaf=5, max_features='sqrt' ) ``` --- ## 第 5 章 神经网络 ### 5.1 激活函数 ```python def sigmoid(z): return 1 / (1 + np.exp(-z)) def relu(z): return np.maximum(0, z) def tanh(z): return np.tanh(z) ``` ### 5.2 BP 算法 ```python class NeuralNetwork: def __init__(self, layer_sizes, lr=0.01, n_iterations=1000): self.lr = lr self.n_iterations = n_iterations self.weights = [] self.biases = [] for i in range(len(layer_sizes) - 1): w = np.random.randn(layer_sizes[i], layer_sizes[i+1]) * 0.01 b = np.zeros((1, layer_sizes[i+1])) self.weights.append(w) self.biases.append(b) def forward(self, X): self.activations = [X] self.z_values = [] current = X for w, b in zip(self.weights, self.biases): z = np.dot(current, w) + b self.z_values.append(z) current = relu(z) if len(self.z_values) < len(self.weights) else sigmoid(z) self.activations.append(current) return current def backward(self, X, y): m = X.shape[0] output = self.activations[-1] delta = (output - y) * sigmoid_derivative(self.z_values[-1]) for l in range(len(self.weights) - 1, -1, -1): dw = np.dot(self.activations[l].T, delta) / m db = np.sum(delta, axis=0, keepdims=True) / m self.weights[l] -= self.lr * dw self.biases[l] -= self.lr * db if l > 0: delta = np.dot(delta, self.weights[l].T) * relu_derivative(self.z_values[l-1]) ``` --- ## 第 6 章 支持向量机 ### 6.1 核心思想 > 找到最大间隔的超平面:max 2/||w|| s.t. y_i(w^T x_i + b) ≥ 1 ### 6.2 核函数 ```python from sklearn.svm import SVC # 线性核 svc_linear = SVC(kernel='linear') # 多项式核 svc_poly = SVC(kernel='poly', degree=3) # RBF 核(高斯核) svc_rbf = SVC(kernel='rbf', gamma='scale') # Sigmoid 核 svc_sigmoid = SVC(kernel='sigmoid') ``` ### 6.3 参数调优 ```python from sklearn.model_selection import GridSearchCV param_grid = { 'C': [0.1, 1, 10, 100], 'gamma': ['scale', 0.01, 0.1, 1], 'kernel': ['rbf'] } grid_search = GridSearchCV(SVC(), param_grid, cv=5) grid_search.fit(X_train, y_train) ``` --- ## 第 7 章 贝叶斯分类器 ### 7.1 贝叶斯公式 ``` P(c|x) = P(x|c)P(c) / P(x) 朴素贝叶斯假设:属性条件独立 P(c|x) ∝ P(c) ∏ P(x_i|c) ``` ### 7.2 实现 ```python from sklearn.naive_bayes import GaussianNB, MultinomialNB, BernoulliNB # 高斯朴素贝叶斯(连续特征) gnb = GaussianNB() # 多项式朴素贝叶斯(离散特征) mnb = MultinomialNB() # 伯努利朴素贝叶斯(0/1 特征) bnb = BernoulliNB() ``` --- ## 📚 学习资源 - 西瓜书官网:http://cs.nju.edu.cn/zhouzh/zhouzh.files/publication/MLbook2016.htm - 南瓜书(公式详解):https://github.com/datawhalechina/pumpkin-book - 西瓜书 Python 实现:https://github.com/Mikoto10032/DeepLearning --- **整理完成时间:** 2026-03-18 **适合人群:** 有机器学习基础,想深入理解算法原理的开发者 --- ## 第 8 章 集成学习 ### 8.1 个体与集成 **核心思想:** 三个臭皮匠,顶个诸葛亮 ```python # 集成学习框架 # 1. 训练多个个体学习器 # 2. 结合个体学习器的预测结果 # 投票法(分类) from sklearn.ensemble import VotingClassifier from sklearn.linear_model import LogisticRegression from sklearn.tree import DecisionTreeClassifier from sklearn.svm import SVC voting_clf = VotingClassifier( estimators=[ ('lr', LogisticRegression()), ('dt', DecisionTreeClassifier()), ('svc', SVC(probability=True)) ], voting='soft' # soft=概率投票,hard=类别投票 ) # 平均法(回归) from sklearn.ensemble import VotingRegressor from sklearn.linear_model import LinearRegression from sklearn.ensemble import RandomForestRegressor voting_reg = VotingRegressor([ ('lr', LinearRegression()), ('rf', RandomForestRegressor()) ]) ``` ### 8.2 Boosting 算法 #### AdaBoost ```python from sklearn.ensemble import AdaBoostClassifier # AdaBoost:逐步关注被分错的样本 ada = AdaBoostClassifier( n_estimators=50, # 基学习器数量 learning_rate=1.0, # 学习率 algorithm='SAMME' # 或'SAMME.R'(用概率) ) # 手动实现简化版 AdaBoost class AdaBoostSimple: def __init__(self, n_estimators=50, lr=1.0): self.n_estimators = n_estimators self.lr = lr self.estimators = [] self.alphas = [] def fit(self, X, y): n_samples = len(y) weights = np.ones(n_samples) / n_samples for _ in range(self.n_estimators): # 训练基学习器(用权重采样) indices = np.random.choice(n_samples, n_samples, p=weights) X_sample, y_sample = X[indices], y[indices] estimator = DecisionTreeClassifier(max_depth=1) # 决策树桩 estimator.fit(X_sample, y_sample) # 计算误差 y_pred = estimator.predict(X) error = np.sum(weights * (y_pred != y)) # 计算权重 alpha = 0.5 * np.log((1 - error) / (error + 1e-10)) # 更新样本权重 weights *= np.exp(-alpha * y * y_pred) weights /= np.sum(weights) self.estimators.append(estimator) self.alphas.append(alpha) return self def predict(self, X): predictions = np.zeros(len(X)) for alpha, est in zip(self.alphas, self.estimators): predictions += alpha * est.predict(X) return np.sign(predictions) ``` #### GBDT (梯度提升决策树) ```python from sklearn.ensemble import GradientBoostingClassifier, GradientBoostingRegressor # GBDT:用负梯度作为残差的近似 gbdt = GradientBoostingClassifier( n_estimators=100, learning_rate=0.1, max_depth=3, subsample=0.8 # 样本采样 ) # 手动理解 GBDT # 1. 初始化 F_0(x) = argmin Σ L(y_i, c) # 2. 对 m = 1,2,...,M: # a) 计算负梯度 r_im = -∂L(y_i, F(x_i))/∂F(x_i) # b) 拟合残差 r_im 得到 h_m(x) # c) 更新 F_m(x) = F_{m-1}(x) + ν * h_m(x) ``` #### XGBoost ```python import xgboost as xgb # XGBoost:GBDT 的高效实现 xgb_clf = xgb.XGBClassifier( n_estimators=100, max_depth=6, learning_rate=0.1, subsample=0.8, colsample_bytree=0.8, reg_alpha=0.1, # L1 正则 reg_lambda=1.0, # L2 正则 eval_metric='logloss' ) # XGBoost vs GBDT # 1. XGBoost 用二阶泰勒展开 # 2. 添加正则化项 # 3. 支持并行计算 # 4. 自动处理缺失值 ``` ### 8.3 Bagging 与随机森林 ```python from sklearn.ensemble import RandomForestClassifier, BaggingClassifier # Bagging:自助采样 + 独立训练 bagging = BaggingClassifier( n_estimators=100, max_samples=1.0, # 采样比例 max_features=1.0, # 特征采样比例 bootstrap=True, # 有放回采样 n_jobs=-1 ) # 随机森林:Bagging + 属性采样 rf = RandomForestClassifier( n_estimators=100, max_depth=None, min_samples_split=2, min_samples_leaf=1, max_features='sqrt', # 每棵树用 sqrt(d) 个特征 bootstrap=True, oob_score=True, # 袋外估计 n_jobs=-1 ) # 特征重要性 rf.fit(X_train, y_train) importances = rf.feature_importances_ ``` ### 8.4 结合策略 ```python # 1. 平均法 # 简单平均:H(x) = (1/T) Σ h_i(x) # 加权平均:H(x) = Σ w_i h_i(x) # 2. 投票法 # 绝对多数:H(x) = argmax Σ I(h_i(x)=c) # 相对多数:得票最多的类别 # 加权投票:H(x) = argmax Σ w_i I(h_i(x)=c) # 3. 学习法 (Stacking) from sklearn.ensemble import StackingClassifier from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier from sklearn.svm import SVC stacking = StackingClassifier( estimators=[ ('rf', RandomForestClassifier(n_estimators=10)), ('svc', SVC(kernel='rbf', probability=True)) ], final_estimator=LogisticRegression(), # 元学习器 cv=5 ) ``` --- ## 第 9 章 聚类 ### 9.1 性能度量 ```python from sklearn.metrics import ( silhouette_score, # 轮廓系数 calinski_harabasz_score, # CH 指数 davies_bouldin_score, # DB 指数 adjusted_rand_score, # ARI(有标签时) adjusted_mutual_info_score # AMI(有标签时) ) # 轮廓系数:[-1, 1],越大越好 silhouette = silhouette_score(X, labels) # CH 指数:越大越好 ch_score = calinski_harabasz_score(X, labels) # DB 指数:越小越好 db_score = davies_bouldin_score(X, labels) ``` ### 9.2 KMeans ```python from sklearn.cluster import KMeans # KMeans:最小化簇内平方误差 kmeans = KMeans( n_clusters=3, init='k-means++', # 智能初始化 n_init=10, # 运行次数 max_iter=300, random_state=42 ) labels = kmeans.fit_predict(X) # 手肘法找最优 K inertias = [] for k in range(1, 11): km = KMeans(n_clusters=k, random_state=42) km.fit(X) inertias.append(km.inertia_) # 可视化手肘图 ``` #### 手动实现 KMeans ```python class KMeansManual: def __init__(self, n_clusters=3, max_iter=300, random_state=42): self.n_clusters = n_clusters self.max_iter = max_iter self.random_state = random_state def fit(self, X): np.random.seed(self.random_state) # 初始化质心(随机选择) indices = np.random.choice(len(X), self.n_clusters, replace=False) self.centroids = X[indices] for _ in range(self.max_iter): # 分配样本到最近质心 distances = np.linalg.norm(X[:, np.newaxis] - self.centroids, axis=2) labels = np.argmin(distances, axis=1) # 更新质心 new_centroids = np.array([ X[labels == k].mean(axis=0) if len(X[labels == k]) > 0 else self.centroids[k] for k in range(self.n_clusters) ]) # 收敛判断 if np.allclose(self.centroids, new_centroids): break self.centroids = new_centroids self.labels_ = labels return self def predict(self, X): distances = np.linalg.norm(X[:, np.newaxis] - self.centroids, axis=2) return np.argmin(distances, axis=1) ``` ### 9.3 DBSCAN ```python from sklearn.cluster import DBSCAN # DBSCAN:基于密度的聚类 dbscan = DBSCAN( eps=0.5, # 邻域半径 min_samples=5, # 核心点最少样本数 metric='euclidean' ) labels = dbscan.fit_predict(X) # 优点: # 1. 不需要指定簇数 # 2. 能发现任意形状的簇 # 3. 能识别噪声点 # 缺点: # 1. 对密度差异大的数据集效果差 # 2. 高维数据效果差 ``` ### 9.4 层次聚类 ```python from sklearn.cluster import AgglomerativeClustering from scipy.cluster.hierarchy import dendrogram, linkage # 凝聚聚类(自底向上) agg = AgglomerativeClustering( n_clusters=3, affinity='euclidean', linkage='ward' # ward/complete/average/single ) labels = agg.fit_predict(X) # 树状图 linkage_matrix = linkage(X, method='ward') dendrogram(linkage_matrix) ``` ### 9.5 高斯混合聚类 (GMM) ```python from sklearn.mixture import GaussianMixture # GMM:用高斯分布的混合表示数据 gmm = GaussianMixture( n_components=3, covariance_type='full', # full/tied/diag/spherical max_iter=100, random_state=42 ) labels = gmm.fit_predict(X) # EM 算法: # E 步:计算后验概率 γ(z_k) = P(z_k|x) # M 步:更新参数 μ_k, Σ_k, π_k ``` --- ## 第 10 章 降维与度量学习 ### 10.1 k 近邻学习 (KNN) ```python from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor # KNN:懒惰学习,无显式训练过程 knn = KNeighborsClassifier( n_neighbors=5, weights='uniform', # uniform/distance metric='minkowski', # 距离度量 p=2, # p=1(L1), p=2(L2) n_jobs=-1 ) # 距离度量 # 1. Minkowski 距离:d(x,z) = (Σ|x_i-z_i|^p)^(1/p) # 2. 曼哈顿距离 (p=1) # 3. 欧氏距离 (p=2) # 4. 余弦相似度:cos(x,z) = x·z / (||x||·||z||) ``` ### 10.2 主成分分析 (PCA) ```python from sklearn.decomposition import PCA # PCA:找到最大方差方向 pca = PCA( n_components=0.95, # 保留 95% 方差 svd_solver='full', whiten=False # 白化 ) X_pca = pca.fit_transform(X) # 解释方差比 explained_variance = pca.explained_variance_ratio_ cumulative_variance = np.cumsum(explained_variance) # 手动实现 PCA class PCAManual: def fit(self, X, n_components=2): # 1. 中心化 X_centered = X - X.mean(axis=0) # 2. 计算协方差矩阵 cov_matrix = np.cov(X_centered.T) # 3. 特征值分解 eigenvalues, eigenvectors = np.linalg.eig(cov_matrix) # 4. 选择前 k 个特征向量 idx = eigenvalues.argsort()[::-1][:n_components] self.components_ = eigenvectors[:, idx] self.explained_variance_ = eigenvalues[idx] return self def transform(self, X): X_centered = X - X.mean(axis=0) return X_centered.dot(self.components_) ``` ### 10.3 流形学习 ```python from sklearn.manifold import TSNE, LocallyLinearEmbedding, Isomap # t-SNE:可视化高维数据 tsne = TSNE( n_components=2, perplexity=30, learning_rate=200, n_iter=1000, random_state=42 ) X_tsne = tsne.fit_transform(X) # LLE:局部线性嵌入 lle = LocallyLinearEmbedding( n_components=2, n_neighbors=5 ) X_lle = lle.fit_transform(X) # Isomap:等距映射 isomap = Isomap( n_components=2, n_neighbors=5 ) X_isomap = isomap.fit_transform(X) ``` --- ## 第 11 章 特征选择与稀疏学习 ### 11.1 子集搜索 ```python from sklearn.feature_selection import ( SelectKBest, SelectFromModel, RFE, f_classif, mutual_info_classif ) # 1. 过滤法 # 方差选择 from sklearn.feature_selection import VarianceThreshold vt = VarianceThreshold(threshold=0.1) X_new = vt.fit_transform(X) # 相关系数 selector = SelectKBest(score_func=f_classif, k=10) X_new = selector.fit_transform(X, y) # 互信息 selector = SelectKBest(score_func=mutual_info_classif, k=10) X_new = selector.fit_transform(X, y) # 2. 包裹法(递归特征消除) from sklearn.feature_selection import RFE from sklearn.svm import SVC rfe = RFE( estimator=SVC(kernel='linear'), n_features_to_select=10, step=1 ) X_new = rfe.fit_transform(X, y) # 3. 嵌入法 from sklearn.linear_model import Lasso from sklearn.feature_selection import SelectFromModel lasso = Lasso(alpha=0.1) selector = SelectFromModel(lasso) X_new = selector.fit_transform(X, y) ``` --- ## 第 12 章 计算学习理论 ### 12.1 PAC 学习 **核心概念:** - PAC (Probably Approximately Correct):可能近似正确 - 样本复杂度:需要多少样本才能学好 - VC 维:假设空间的复杂度度量 ### 12.2 稳定性与泛化 ```python # 泛化误差上界 # E(f) ≤ Ê(f) + Ω(H) + √(log(1/δ)/2m) # 其中: # E(f): 泛化误差 # Ê(f): 经验误差 # Ω(H): 假设空间复杂度 # m: 样本数 # δ: 置信度 ``` --- ## 第 13 章 半监督学习 ### 13.1 未标记样本 ```python from sklearn.semi_supervised import LabelPropagation, LabelSpreading # 标签传播 lp = LabelPropagation(kernel='knn', n_neighbors=7) lp.fit(X, y_partial) # y_partial 包含 -1(未标记) # 标签传播(带正则化) ls = LabelSpreading(kernel='rbf', alpha=0.2) ls.fit(X, y_partial) ``` ### 13.2 半监督 SVM ```python # TSVM:在半标记数据上最大化间隔 # 1. 用标记数据训练初始 SVM # 2. 给未标记数据赋伪标签 # 3. 优化间隔,调整伪标签 # 4. 重复直到收敛 ``` --- ## 第 14 章 概率图模型 ### 14.1 隐马尔可夫模型 (HMM) ```python # HMM 三要素: # 1. 初始概率分布 π # 2. 状态转移概率矩阵 A # 3. 观测概率矩阵 B # 三大问题: # 1. 概率计算:前向 - 后向算法 # 2. 学习:Baum-Welch 算法 # 3. 预测:Viterbi 算法 ``` ### 14.2 马尔可夫随机场 (MRF) ```python # MRF:无向图模型 # 联合概率:P(X) = (1/Z) ∏ ψ_c(X_c) # Z: 配分函数 # ψ_c: 势函数 ``` ### 14.3 条件随机场 (CRF) ```python # CRF:判别式无向图模型 # P(Y|X) = (1/Z(X)) exp(Σ λ_k f_k(Y,X)) import sklearn_crfsuite crf = sklearn_crfsuite.CRF( algorithm='lbfgs', c1=0.1, c2=0.1, max_iterations=100, all_possible_transitions=True ) ``` --- ## 第 15 章 规则学习 ### 15.1 序贯覆盖 ```python # 规则学习:产生 IF-THEN 规则 # 1. 从空规则开始 # 2. 添加条件,提高规则质量 # 3. 覆盖的样本移除 # 4. 重复直到覆盖所有样本 # RIPPER 算法 # 1. 生长阶段:添加条件直到覆盖负例 # 2. 剪枝阶段:删除降低质量的條件 ``` --- ## 第 16 章 强化学习 ### 16.1 基本要素 ```python # 强化学习五要素: # 1. 状态 S # 2. 动作 A # 3. 奖励 R # 4. 策略 π # 5. 价值函数 V/Q # Q-Learning # Q(s,a) ← Q(s,a) + α[r + γ max_a' Q(s',a') - Q(s,a)] ``` ### 16.2 Q-Learning 实现 ```python import numpy as np class QLearning: def __init__(self, n_states, n_actions, alpha=0.1, gamma=0.9, epsilon=0.1): self.q_table = np.zeros((n_states, n_actions)) self.alpha = alpha # 学习率 self.gamma = gamma # 折扣因子 self.epsilon = epsilon # 探索率 self.n_actions = n_actions def choose_action(self, state): if np.random.random() < self.epsilon: return np.random.randint(self.n_actions) # 探索 else: return np.argmax(self.q_table[state]) # 利用 def update(self, state, action, reward, next_state): best_next_action = np.argmax(self.q_table[next_state]) td_target = reward + self.gamma * self.q_table[next_state][best_next_action] td_error = td_target - self.q_table[state][action] self.q_table[state][action] += self.alpha * td_error ``` ### 16.3 深度强化学习 ```python # DQN:用神经网络拟合 Q 函数 # 1. 经验回放 # 2. 目标网络 # 3. 损失函数:L = E[(r + γ max_a' Q_target(s',a') - Q(s,a))²] import gym from tensorflow import keras from tensorflow.keras import layers import numpy as np class DQN: def __init__(self, n_states, n_actions): self.model = keras.Sequential([ layers.Dense(64, activation='relu', input_shape=(n_states,)), layers.Dense(64, activation='relu'), layers.Dense(n_actions, activation='linear') ]) self.target_model = keras.models.clone_model(self.model) self.target_model.set_weights(self.model.get_weights()) def train(self, states, actions, rewards, next_states, done): # 计算目标 Q 值 q_values = self.model.predict(states) next_q_values = self.target_model.predict(next_states) targets = q_values.copy() for i in range(len(done)): if done[i]: targets[i, actions[i]] = rewards[i] else: targets[i, actions[i]] = rewards[i] + 0.99 * np.max(next_q_values[i]) # 训练 self.model.fit(states, targets, epochs=1, verbose=0) ``` --- ## 📚 完整学习路线 ### 基础篇(第 1-4 章) 1. 绪论 → 基本概念 2. 模型评估 → 性能度量 3. 线性模型 → 基础算法 4. 决策树 → 树模型入门 ### 进阶篇(第 5-7 章) 5. 神经网络 → 深度学习基础 6. SVM → 统计学习 7. 贝叶斯 → 概率方法 ### 高级篇(第 8-10 章) 8. 集成学习 → Bagging/Boosting 9. 聚类 → 无监督学习 10. 降维 → 特征处理 ### 专题篇(第 11-16 章) 11. 特征选择 12. 计算学习理论 13. 半监督学习 14. 概率图模型 15. 规则学习 16. 强化学习 --- ## 🎯 蓝桥杯重点 **算法竞赛常考:** - ✅ 决策树(ID3/C4.5/CART) - ✅ KMeans 聚类 - ✅ PCA 降维 - ✅ KNN 分类 - ✅ 线性回归/逻辑回归 - ✅ 集成学习(随机森林、GBDT) **面试常问:** - ✅ 过拟合 vs 欠拟合 - ✅ 交叉验证 - ✅ 精确率/召回率/F1 - ✅ L1/L2 正则化 - ✅ Bagging vs Boosting - ✅ SVM 核函数 --- **整理完成!** 🎉 **总文档大小:** ~25KB **涵盖章节:** 第 1-16 章完整知识点 **代码示例:** 每个算法都有实现 **下载链接:** http://129.211.3.54:3923/files/机器学习西瓜书_知识点精解.md 继续加油蓝桥杯备战!🌱💪