简介:一份面向人工智能初学者与相关课程学习者的算法综述文档,以 doc 格式系统梳理搜索技术与人工神经网络两大主线,覆盖盲目式搜索(广度优先、深度优先、迭代深入等)、启发式搜索(A*、AO*、存储限制启发式等)、局部搜索(爬山、模拟退火、遗传、群集智能等)以及多层感知网络、KOHONEN 竞争型神经网络、Hopfield 神经网络等经典算法。文档不仅给出各算法的原理、特点与适用场景,还结合专家系统、自然语言理解、自动程序设计、模式识别、机器人学、信息检索与博弈等典型应用领域加以比较评价,并对人工智能算法的发展前景作出展望,有助于读者从整体上把握算法脉络。资源为 1 个 doc 文件,压缩包大小约 93KB,文档含摘要、目录、正文及参考文献,结构清晰,便于按章节研读或作为课程报告参考。已有 160 人学习下载。通过这份综述,读者可以快速了解不同算法的适用边界与优化思路,减少算法选型时的盲目性,尤其适合用于期末复习、论文综述写作或自学入门。
1. 人工智能算法综述到底在综述什么
很多团队做 AI 落地时,第一步都落在一份“人工智能算法综述”上。我见过两种浪费:一种是把维基百科列表抄一遍,从 KMP 到冒泡排序都放进去,结果没人翻;另一种是只写深度学习算法模型,把逻辑回归、GBDT、粒子群和匈牙利算法全部省略,导致选型时漏掉最合适的方案。真正有用的综述不是算法词典,而是决策索引:给定场景、数据量和硬件约束,哪些算法值得先跑、按什么顺序跑。下面用的不是教材复述,而是一套可以落地的做法:用分类框架把算法装进去,用同一套评估管道跑出可对比的数据,再把结论沉淀成一张算法卡。适合算法工程师、技术负责人,以及正在规划自己人工智能学习路径的人。
2. 人工智能算法的分类框架与数学基础
做一个综述,最怕开头就陷入算法定义。我的习惯是先立两根轴:第一根是学习范式,第二根是算法族。二者交叉后能覆盖绝大多数主流方法,也能暴露边界。
2.1 按学习范式分:监督、无监督与强化学习
按范式分类最常见,但只按这个轴分,很快会遇到边界情况。监督学习假设每个样本有标签,回归、分类、排序都能放进来;无监督学习是找结构,聚类、降维、异常检测都是它的体现;强化学习不依赖静态标签,而是通过奖励信号学习策略,适合控制、博弈和机器人场景。真正麻烦的是自监督学习和 RLHF 这类混合范式:对比学习自己构造正负样本,算无监督还是监督?奖励模型是监督学习,策略优化又是强化学习,硬塞进一个格子会把整个综述的逻辑带偏。
我一般会在表格里加一列“范式混合”,把这类算法单独标注。这样既保持了分类轴的稳定,又不会丢掉真实业务里的复合形态。生物智能、人工智能、计算智能的层次关系也可以在这里参考:计算智能是手段,生物智能提供启发,人工智能是任务外显层。算法综述本质上做的是“手段-任务”映射,而不是给算法评职称。
无监督和强化学习也不能因为当前深度学习热就轻视。具身智能数据集质量要求及评价方法这类新标准,恰恰是把感知、决策和数据质量放在一起评,背后还是这三种范式的协同。综述里给每个学习范式写一小段“当前活跃点”,比罗列十个算法名称有价值。
2.2 按算法族分:线性模型、树模型、概率图、群智能与深度学习
范式的粒度太粗,同一个监督学习里,线性模型和深度模型的工程表现可能天差地别。所以第二根轴按算法族分,我常用的分法如下:
| 算法族 | 代表算法 | 典型任务 | 常见实现 |
|---|---|---|---|
| 线性模型系 | 线性回归、逻辑回归、线性SVM | 表格数据回归/分类 | scikit-learn |
| 树模型系 | 决策树、随机森林、XGBoost、LightGBM | 表格数据、排序 | xgboost、lightgbm |
| 概率图模型 | HMM、CRF、贝叶斯网络 | 序列标注、因果推理 | pgmpy、hmmlearn |
| 群智能/元启发 | 粒子群算法、遗传算法、模拟退火 | 组合优化、特征选择 | scipy、deap |
| 深度学习系 | CNN、RNN、Transformer、图神经网络 | 视觉、文本、关系预测 | PyTorch、TensorFlow |
| 匹配类算法 | 匈牙利算法、KM算法 | 任务分配、目标关联 | scipy.optimize |
这个分法不是按数据结构教材来的,刻意把剪枝算法归到模型压缩,把混合整数线性规划放在约束优化里。原因是综述的消费者是选型的人,不是考试的人。深度学习算法在视觉和文本任务上优势明显,但在中小型表格数据上树模型往往更稳,这个反直觉点应该放在综述摘要部分。概率图模型现在热度下降,却在知识推理和低数据场景里依然有用,不能删。
2.3 统一视角:目标函数、优化器、正则化三要素
把这么多算法放进同一份文档后,还要有一套共同语言来比较它们。我用的统一视角是:任何监督算法都可以写成最小化目标函数L = 1/N * Σ L_i + λΩ,不同算法只在三处不同:损失函数怎么定义、优化器怎么搜索、正则项怎么约束。
import numpy as np def sgd_step(X, y, w, lr=0.01, lam=0.01, loss_type="mse"): """统一的三要素更新步骤,演示用,真实场景请直接调框架。""" pred = X @ w if loss_type == "mse": loss = np.mean((pred - y) ** 2) grad = 2 * X.T @ (pred - y) / len(y) elif loss_type == "logistic": p = 1 / (1 + np.exp(-np.clip(pred, -30, 30))) loss = -np.mean(y * np.log(p + 1e-12) + (1 - y) * np.log(1 - p + 1e-12)) grad = X.T @ (p - y) / len(y) grad += 2 * lam * w w -= lr * grad return w, loss这里lr是学习率,控制参数更新步长,工程上通常从1e-3开始调;lam是正则化强度,L2 正则让权重向零收缩,换成 L1 正则则产生稀疏解。loss_type切换的是损失函数,对应三要素中的“目标函数”。这个函数只是教学演示,np.exp在极端输入下有溢出风险,但足以展示模型的统一骨架。你自己写综述结论时,先把基线算法按这三要素拆开记录,比单独记录准确率更能解释“为什么换损失会改变结果”。
3. 动手复现一份可运行的算法对比代码
分类框架说完,进入真正的综述实验。下面这段流程以表格数据二分类为例,所有算法跑同一份数据、同一套交叉验证折。这样才敢写“谁比谁好”。
3.1 最小环境与基准数据准备
先建干净环境。我总是先锁虚拟环境,再装固定版本,否则半年后同一份脚本会因为依赖升级跑出完全不同的结论。
mkdir ai_survey && cd ai_survey python -m venv .venv source .venv/bin/activate pip install numpy pandas scikit-learn xgboost torch提示:依赖版本不一致是算法综述最隐蔽的坑。记录实验环境与记录算法结果同样重要,最好把
pip freeze > requirements.txt的输出一并放进综述附录。
环境就绪后用make_classification生成一份可复现的表格数据,避免网络下载带来的波动:
from sklearn.datasets import make_classification X, y = make_classification( n_samples=5000, n_features=40, n_informative=15, n_redundant=5, random_state=42 )n_informative控制真正有用的特征数,n_redundant引入线性冗余,组合起来接近真实表格数据的结构。random_state=42保证每次生成完全一致。如果你手头有业务数据,也可以替换进来,但要在综述里写明数据来源、样本量和特征含义。
3.2 从逻辑回归到XGBoost的参数对照
拿到数据后,我把几个基准算法放进同一个评估函数。公平性来自同一组StratifiedKFold划分,而不是每次都重新随机。
from sklearn.model_selection import cross_val_score, StratifiedKFold from sklearn.linear_model import LogisticRegression from sklearn.svm import SVC from sklearn.ensemble import RandomForestClassifier from xgboost import XGBClassifier cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) models = { "logit": LogisticRegression(max_iter=2000), "svm_rbf": SVC(kernel="rbf", C=1.0, gamma="scale"), "rf_200_8": RandomForestClassifier(n_estimators=200, max_depth=8, n_jobs=-1), "xgb_200_6": XGBClassifier(n_estimators=200, max_depth=6, learning_rate=0.05) } for name, model in models.items(): scores = cross_val_score(model, X, y, cv=cv, scoring="f1") print(f"{name}: {scores.mean():.4f} ± {scores.std():.4f}")这里cv对象在循环内被复用,确保每个算法都在相同的训练/验证组合上评估。scoring="f1"对二分类不平衡数据更诚实,AUC 偏向排序质量但无法直接反映阈值下的业务代价。不要在一个算法跑到一半时手动改 shuffle 参数,否则你没法解释分数差异到底是算法带来的还是划分带来的。参数对照如下:
| 算法 | 关键超参 | 含义 | 常见调整方向 |
|---|---|---|---|
| 逻辑回归 | max_iter | 迭代上限 | 不收敛时增大到 5000 |
| SVM | C, gamma | 误分类惩罚、核影响范围 | C 太大会过拟合,gamma 太大会局部化 |
| 随机森林 | n_estimators, max_depth | 树数量、最大深度 | 优先调 depth,树数到 200 后收益递减 |
| XGBoost | learning_rate, n_estimators | 步长、树数 | 小步长配多树,是典型的精度来源 |
跑完后如果发现 SVM 最慢、XGBoost 分数最高,这说明树模型在密集表格特征上占优。不要在综述里只写“效果排序”,还要写“最慢花了多久”,这直接关系能不能上线。
3.3 深度学习算法:PyTorch下的小型CNN调参
表格数据里深度学习不一定占优势,但综述不能缺这个算法族。下面用一个随机图像数据跑通流程,验证结构没问题后再替换成真实数据。这个例子在视觉任务里很典型:CNN 的卷积核就是特征提取器,池化在降采样,dropout 是深度学习算法里最常用的正则化手段。即使你参考的是《计算机视觉:算法与应用》这类教材,工程综述也要额外记录实测耗时的参数量,不能只抄书上的网络结构。
import torch from torch import nn torch.manual_seed(42) class SmallCNN(nn.Module): def __init__(self): super().__init__() self.features = nn.Sequential( nn.Conv2d(1, 32, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.MaxPool2d(2), nn.Conv2d(32, 64, kernel_size=3, padding=1), nn.ReLU(inplace=True), nn.AdaptiveAvgPool2d((4, 4)), ) self.classifier = nn.Sequential( nn.Flatten(), nn.Dropout(p=0.3), nn.Linear(64 * 4 * 4, 10), ) def forward(self, x): return self.classifier(self.features(x)) x = torch.randn(64, 1, 32, 32) y = torch.randint(0, 10, (64,)) model = SmallCNN() opt = torch.optim.AdamW(model.parameters(), lr=3e-4, weight_decay=1e-4) for epoch in range(3): out = model(x) loss = nn.functional.cross_entropy(out, y) opt.zero_grad() loss.backward() opt.step() print("final loss:", loss.item())weight_decay=1e-4就是第2章说的 L2 正则,PyTorch 里以优化器参数出现。下面是这类模型综述必须记录的四个参数。表格里每一行都可以直接抄进综述的实验说明,尤其要注意 dropout 在推理阶段的开关,很多复现坑都出在忘记切换到model.eval()模式。
| 参数 | 推荐范围 | 注意事项 |
|---|---|---|
| batch_size | 32-256 | 太大收敛慢,太小 BatchNorm 不稳定 |
| lr | 1e-4 - 1e-2 | 超过 1e-2 容易 loss 爆炸 |
| weight_decay | 1e-5 - 1e-3 | 太大会欠拟合 |
| dropout | 0.1-0.5 | 推理时必须关闭,PyTorch 的model.eval()会处理 |
这一段跑通后,把批大小、学习率和 dropout 都记录进表里。深度学习算法的“结构”比超参更难比较,综述里还要记录参数量和推理耗时,因为 GPU 显存和时延往往比 accuracy 分差更早让人放弃某个模型。
3.4 优化类算法:粒子群、匈牙利、剪枝算法的边界
综述不能只写分类模型,还要覆盖“在模型之外的算法”。常见教材很少把这几个放一起,但工程里它们出现频率很高。粒子群算法适合连续参数搜索,也能用在特征选择;匈牙利算法解决二分图最优匹配;剪枝算法用于决策树和神经网络压缩。它们的共同点是都服务于某个更大的 AI 流程。
import numpy as np def pso_minimize(func, dim=5, n_particles=30, max_iter=100): """极简粒子群优化,用于连续参数搜索。""" rng = np.random.default_rng(0) x = rng.uniform(-5, 5, (n_particles, dim)) v = rng.uniform(-1, 1, (n_particles, dim)) pbest = x.copy() fitness = np.array([func(xi) for xi in x]) pbest_fit = fitness.copy() gbest = pbest[np.argmin(pbest_fit)].copy() gbest_fit = pbest_fit.min() for _ in range(max_iter): r1, r2 = rng.random((2, n_particles, dim)) v = 0.5 * v + 2.0 * r1 * (pbest - x) + 2.0 * r2 * (gbest - x) x = np.clip(x + v, -5, 5) fitness = np.array([func(xi) for xi in x]) better = fitness < pbest_fit pbest[better] = x[better] pbest_fit[better] = fitness[better] if pbest_fit.min() < gbest_fit: gbest_fit = pbest_fit.min() gbest = pbest[np.argmin(pbest_fit)].copy() return gbest, gbest_fit这里的0.5是惯性权重,控制粒子保持前一刻速度的程度;2.0是加速系数,决定向个体历史最优和全局最优靠近的强度。实际调参时,惯性权重大偏向全局搜索,小偏向局部收敛。用我自己做特征选择的经验,粒子群每次迭代只评估一批特征子集的模型分数,比穷举组合快得多。
匈牙利算法就更直接:
from scipy.optimize import linear_sum_assignment cost = [[10, 5, 3], [9, 7, 8], [6, 4, 2]] rows, cols = linear_sum_assignment(cost) print(rows, cols, sum(cost[r][c] for r, c in zip(rows, cols)))linear_sum_assignment返回的行/列下标就是最优匹配方案。遇到人员容量约束、每组最多分几个人这类限制,匈牙利就不够用了,要升级成混合整数线性规划。综述里把这两者放在一起,才能覆盖真实业务里的分配问题。决策树剪枝则常在 sklearn 里用cost_complexity_pruning_path找到 ccp_alpha 序列,再选验证集分数最高的点。这类算法在综述里的定位,我建议按问题类型而不是按“是否属于机器学习”来记录,这样实战时更容易翻到。
| 算法 | 问题类型 | 关键参数 | 综述应记录 |
|---|---|---|---|
| 粒子群 | 连续参数优化 | 粒子数、惯性权重、加速系数 | 收敛曲线、最终目标值 |
| 匈牙利 | 二分图最小代价匹配 | 代价矩阵 | 匹配总代价、耗时 |
| 决策树剪枝 | 模型压缩 | ccp_alpha | 剪枝前后验证分数 |
4. 从综述到选型:评估指标与基准测试
只列分数没有意义,还要解释“在什么约束下谁值得上线”。这一步需要把指标口径统一,并且记录成本数据。
4.1 回归、分类、排序场景下的指标选择
我经常看到综述把所有模型都用准确率比较,这在小样本或者类别不平衡场景里会得出错误结论。我的做法是先定义任务类型,再选指标:
| 任务 | 推荐指标 | 使用注意 |
|---|---|---|
| 二分类 | F1、AUC、LogLoss | F1 依赖阈值;AUC 不关心概率校准 |
| 多分类 | macro/micro F1、top-k 准确率 | macro F1 对少数类更敏感 |
| 回归 | MAE、RMSE、MAPE | RMSE 放大离群点,MAPE 在真值为 0 时不可用 |
| 排序 | NDCG、MAP | 位置信息很重要,不能只用 AUC |
| 强化学习 | 累计奖励、平均步长 | 方差大,需要多次随机种子的均值 |
对应代码很直接。用同一套cross_val_score换scoring参数就行,例如scoring="roc_auc"。如果任务有位置信息,要直接用ndcg_score而不是套一个分类器。
4.2 用交叉验证和超参数搜索做公平对比
不同算法的默认参数可能差异巨大,直接把默认参数对比等于欺负老实人。我一般会给每个候选算法分配一个超参数搜索预算,预算一致才公平。随机搜索比网格搜索效率高,因为超参数之间重要性不均等。
from sklearn.model_selection import RandomizedSearchCV from xgboost import XGBClassifier param_dist = { "n_estimators": [100, 300], "max_depth": [4, 6, 8], "learning_rate": [0.01, 0.05, 0.1], } search = RandomizedSearchCV( XGBClassifier(use_label_encoder=False, eval_metric="logloss"), param_dist, n_iter=10, cv=StratifiedKFold(5), scoring="roc_auc", random_state=42, n_jobs=-1 ) search.fit(X, y) print(search.best_params_, search.best_score_)n_iter=10表示只抽 10 组参数,预算有限时比全网格快一个量级。scoring="roc_auc"与线上指标保持一致,如果线上更关注高召回,这里就应该换成recall。搜索结束后,要在综述里写出最优参数和验证分数,而不是只写“调优后更好”。
4.3 卡时间、卡显存、卡稳定性:工程约束下的取舍
精度差 0.01 但推理慢 20 倍的算法,在实时场景里不值得上。综述还需要有“成本轴”。
import time def benchmark_fit_predict(model, X_train, y_train, X_test): t0 = time.perf_counter() model.fit(X_train, y_train) t_fit = time.perf_counter() - t0 t0 = time.perf_counter() pred = model.predict(X_test) t_pred = time.perf_counter() - t0 return {"fit_s": t_fit, "pred_s": t_pred, "pred_len": len(pred)}用time.perf_counter记录拟合和预测耗时,每个模型重复跑 5 次取中位数,避免冷启动干扰。深度学习模型还要记录显存峰值,PyTorch 里用torch.cuda.max_memory_allocated()。把这些数据放进综述对比表后,选型逻辑就变成了一个多目标问题:
| 约束 | 倾向算法 | 反例 |
|---|---|---|
| 延迟低于 10ms | 逻辑回归、浅层树、蒸馏小模型 | 大 Transformer 很难达标 |
| 显存 4GB | 逻辑回归、GBDT | ViT 大模型直接 OOM |
| 离线批处理 | 集成模型、大搜索空间 | 单次训练耗时次要 |
| 数据量小于 1 万 | 线性模型 + 强正则 | 深度模型容易过拟合 |
稳定性同样重要。跑 5 次交叉验证,如果标准差比均值差还大,说明模型对数据划分敏感,这类模型即使分数高也要在综述里标红。
5. 快速整理综述手册的技巧:以一张大表驱动整个综述
实验做完,文档怎么写?我的建议是别从第一章开始写,先做一张大表,让表格当骨架,所有结论都收缩在列名里。用 pandas 把实验记录汇总成 markdown 表,直接贴进.doc综述的对比章节。
import pandas as pd results = [] for name, model in models.items(): scores = cross_val_score(model, X, y, cv=cv, scoring="f1") results.append({ "算法": name, "F1均值": round(scores.mean(), 4), "F1标准差": round(scores.std(), 4), "拟合耗时s": round(bench_seconds[name], 2), }) df = pd.DataFrame(results).sort_values("F1均值", ascending=False) print(df.to_markdown(index=False))to_markdown会输出干净的 markdown 源,粘贴到 Word 或 Typora 都能直接转成表格。这张表就是综述的数据中心,后续换数据、换参数,只更新表再刷新文字结论,不维护两套内容。
配合了大表后,我给每个算法再维护一张算法卡:
- 算法名:逻辑回归 / 粒子群 / 匈牙利
- 一句话:该算法在什么假设下有效
- 三个关键参数:含义、调节方向
- 两个失败模式:什么数据或约束下会崩
- 和最近竞争算法的差距:差多少精度,快多少倍
这套模板能逼你把每个算法写到可决策的颗粒度。比如逻辑回归的卡片可以写:“线性决策边界,特征间无强交互时好用;关键参数 C 是正则强度;当特征与标签有复杂非线性映射时被 GBDT 甩开约 0.05 F1,但推理速度快两个数量级。” 这样一句话,比半页公式说清楚得多。
写综述最忌讳平均用力。先按大表排出前三个候选,再把这三个的算法卡写厚,其他算法各留两行边界说明。这张表保持可执行,半年后有人拿着新数据找你,你只需要重跑这段代码,看表头不变、排名有没有翻转,就能快速判断业务是否发生了迁移。用几十行脚本代替几千字文字,综述也就真正变成了一个长期可用的决策系统。
本文还有配套的精品资源,点击获取