
1. 十大基础算法全景图1.1 为什么必须有“基础算法”这个概念人工智能这个领域现在热闹到什么程度呢随便打开一个招聘网站AI相关岗位的薪资都很高随便刷一条短视频都能看到大模型、智能体的消息。但热闹归热闹真正想进入这个领域、或者说想把AI用明白的人很快就会撞上一堵墙理论太多、框架太多、名词太多根本不知道从哪下手。我的建议一直很直接别急着追大模型先把基础算法吃透。原因很简单今天所有看起来高大上的人工智能应用包括大语言模型、自动驾驶、推荐系统、人脸识别底层都是这些基础算法在支撑。你可以把基础算法理解为“内功”把TensorFlow、PyTorch这些框架理解为“兵器”。兵器再锋利内功不够使出来的招式也是飘的。那什么叫“基础算法”呢业内比较公认的说法是下面这十种线性回归、逻辑回归、决策树、随机森林、支持向量机SVM、K近邻KNN、K-Means聚类、朴素贝叶斯、主成分分析PCA、AdaBoost。这十种算法覆盖了机器学习里最核心的两大分支——监督学习和无监督学习也覆盖了分类、回归、聚类、降维这四类最常见的任务。不管你是做数据分析、算法工程师还是想搞AI产品设计这十个算法都是绕不过去的基本功。我见过不少学生和转行的朋友上来就报班学深度学习学了一个月卷积神经网络、循环神经网络结果连过拟合和欠拟合都说不清楚连训练集和测试集为什么要分开都理解不了。这种基础不牢的情况后期写论文、做项目、调模型的时候会非常痛苦。反过来如果你把这十个算法真正弄明白了再看深度学习的内容会发现很多概念其实是相通的只是表达方式变了而已。1.2 十大算法分类与学习路线这十个算法不是随便排在一起的它们之间有清晰的内在逻辑。我习惯把它们分成四组来理解第一组是回归家族包括线性回归和逻辑回归。线性回归解决的是“预测一个数值”的问题比如预测房价、预测销量逻辑回归解决的是“判断是A还是B”的问题比如判断邮件是不是垃圾邮件、判断用户会不会流失。虽然名字里都带“回归”但逻辑回归实际上是分类算法这是新手最容易搞混的地方。第二组是树模型家族包括决策树和随机森林。决策树的特点是“可解释性强”它能告诉你它为什么做出这个判断就像医生根据症状一步步推断病情一样。随机森林则是把很多棵决策树组合在一起用“投票”的方式做决定准确率更高但解释性会差一些。第三组是基于距离和概率的算法包括K近邻和朴素贝叶斯。K近邻的思路非常朴素跟你最像的那群人是什么样子你大概就是什么样子。朴素贝叶斯则是用概率论来做判断它在文本分类领域表现非常好垃圾邮件过滤的经典方案就是它。第四组是优化和集成类算法包括支持向量机、K-Means、PCA和AdaBoost。支持向量机擅长处理高维数据在图像识别和文本分类上都曾大放异彩K-Means是聚类算法解决的是“无监督”的问题也就是没有标准答案、需要自动分组的场景PCA用于降维可以把几百个特征压缩成几十个同时保留大部分有效信息AdaBoost则是集成学习的代表把多个表现一般的模型组合成一个强模型。我给新人的学习路线通常是这样的先学线性回归和逻辑回归把损失函数、梯度下降这些最核心的概念搞清楚然后学决策树和随机森林理解集成学习的思想接着学K近邻和朴素贝叶斯这两个相对简单的算法增强信心再啃SVM和PCA这两个数学要求稍高的算法最后学K-Means和AdaBoost。这个顺序由易到难知识点之间有递进关系学起来不会那么痛苦。2. 回归家族从线性回归到逻辑回归2.1 线性回归一切预测问题的起点线性回归是机器学习里最基础、也最容易被低估的算法。它的数学形式非常简单就是 y wx b高中就学过的一次函数。但在机器学习语境下这个公式的含义是我们有一堆数据点每个点有若干特征x还有一个真实的结果y我们需要找到一组参数w和b让预测值和真实值之间的差距尽可能小。这个“让差距尽可能小”的过程就是机器学习里最核心的概念之一优化。我们需要定义一个损失函数最常见的是均方误差MSE然后通过梯度下降法不断调整参数把损失函数的值降下来。梯度下降这个思想贯穿了整个机器学习领域包括深度学习的反向传播本质上也是梯度下降的一种复杂应用。实际操作中线性回归有不少需要注意的坑。第一个坑是特征需要归一化。如果某个特征的数值范围是0到1另一个是0到10000那梯度下降的速度会非常慢甚至不收敛。第二个坑是异常值影响很大。线性回归对异常值非常敏感一个极端值就可能把回归线拉偏所以在建模之前先做异常值检测非常关键。第三个坑是多重共线性也就是特征之间高度相关这会导致参数估计不稳定。我当年刚学的时候犯过一个特别蠢的错误直接用Sklearn里的LinearRegression跑数据也没看特征分布结果模型效果极差。后来才发现数据里有几个离群点把回归线带偏了。从那以后我养成了一个习惯训练任何模型之前先画图用散点图看数据分布这比任何高级技巧都管用。用Python实现线性回归非常容易Sklearn几行代码就搞定了from sklearn.linear_model import LinearRegression from sklearn.model_selection import train_test_split import numpy as np # 假设X是特征矩阵y是目标值 X, y np.random.rand(100, 3), np.random.rand(100) X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) model LinearRegression() model.fit(X_train, y_train) print(训练集评分, model.score(X_train, y_train)) print(测试集评分, model.score(X_test, y_test)) print(系数, model.coef_) y_pred model.predict(X_test)注意这里我用了train_test_split把数据分成了训练集和测试集这是机器学习里最基本的规矩不能用训练模型的数据来评估模型。如果你用训练集评分来炫耀模型多好那基本等于考试前先看了答案再参加考试分数再高也没有意义。评估模型一定要看它在没见过的数据上的表现也就是测试集上的表现。2.2 逻辑回归披着回归外衣的分类器逻辑回归这个名字很有迷惑性很多初学者以为它是做回归的其实它是最经典二分类算法。它的思路是这样的在线性回归的基础上加一个Sigmoid函数也叫Logistic函数把输出压缩到0到1之间然后把这个值理解为“属于正类的概率”。如果概率大于0.5就判为正类否则判为负类。逻辑回归的数学表达式是P(y1|x) 1 / (1 e^(-z))其中z wx b。这个Sigmoid函数很有意思它在z很大时趋近于1z很小时趋近于0在z0附近有一个平滑的过渡。这个“平滑”很重要它让模型不仅能给出分类结果还能给出概率这对很多业务场景很有价值。比如在风控领域银行不仅要判断一笔交易是不是欺诈还要知道欺诈的概率有多大概率高的优先处理。逻辑回归的损失函数和线性回归不一样它用的是对数损失函数Log Loss也叫交叉熵损失。这也是一个贯穿深度学习的重要概念后面学神经网络的时候会反复遇到它。实操中逻辑回归有几个优势让它至今仍然被广泛使用。第一是可解释性强每个特征的系数都能直接说明“这个特征每增加一个单位目标概率会怎么变化”这在金融、医疗等需要解释原因的行业非常重要。第二是训练速度快即使数据量很大逻辑回归也能很快训练完。第三是对内存要求低部署起来很方便。但逻辑回归也有它的短板。它对特征之间关系的表达能力有限如果数据里有复杂的非线性关系逻辑回归的表现就不太够。这时候要么做特征工程把非线性关系显式地构造出来要么就直接换更复杂的模型比如树模型或者神经网络。给个简单的逻辑回归代码示例from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report model LogisticRegression() model.fit(X_train, y_train_binary) # y_train_binary是0/1标签 y_pred model.predict(X_test) print(classification_report(y_test_binary, y_pred)) # 查看每个特征的系数理解模型逻辑 for feature, coef in zip(feature_names, model.coef_[0]): print(f{feature}: {coef:.4f})一个我踩过的坑逻辑回归默认带L2正则化正则化系数C默认是1.0。在很多情况下默认值就能工作但如果特征非常多或者数据量很小需要手动调C值。C值越小正则化越强模型越简单越不容易过拟合C值越大正则化越弱模型越复杂。调参的时候可以试几个数量级0.01、0.1、1、10、100看验证集上哪个表现最好。3. 树模型从决策树到随机森林3.1 决策树人类决策过程的机器化决策树是我个人非常喜欢的一种算法因为它太符合人类的思维方式了。我们在生活中做决定时往往是按条件一步步判断的今天出门要不要带伞先看天气如果下雨就带不下就不带。如果天气预报不准再看云层厚度云厚就带云薄就不带。决策树就是把这种“如果有这种情况那么走那条路”的判断过程形式化用一棵倒着长的树来表示。树模型的训练过程和人类学习的过程也很像从根节点开始每一次都找一个最优的特征和最优的切分点把数据分成两组然后在每一组里继续找下一个特征继续切分直到满足停止条件。这个“最优”怎么衡量呢常见的有三种标准信息增益ID3算法用、信息增益率C4.5用、基尼系数CART用。信息增益的概念来自信息论核心思想是切分之后数据的“纯度”提升得越多这个特征就越好。基尼系数的思路类似也是衡量数据的不纯度。这么多标准怎么选呢实践中98%的情况下用基尼系数就够了。决策树的优点是解释性极强训练完之后你可以把整棵树画出来每一步判断都清清楚楚这在需要向业务方解释模型的场景下特别好用。它也不需要做特征归一化数值型和类别型特征都能处理这点比线性模型省事很多。但决策树最大的问题在于容易过拟合。如果你不限制树的深度它会一直生长直到每一个叶子节点都只包含一个样本为止。这样训练集准确率100%但测试集上表现一塌糊涂。控制过拟合的办法就是加约束限制最大深度、限制叶子节点的最小样本数、设置分裂所需的最小样本数。用Sklearn实现决策树from sklearn.tree import DecisionTreeClassifier from sklearn.tree import plot_tree import matplotlib.pyplot as plt model DecisionTreeClassifier( max_depth5, # 限制最大深度防止过拟合 min_samples_split10, # 内部节点至少需要10个样本才继续分裂 min_samples_leaf5, # 叶子节点至少包含5个样本 random_state42 ) model.fit(X_train, y_train) # 可视化树结构 plt.figure(figsize(20, 10)) plot_tree(model, filledTrue, feature_namesfeature_names, class_names[0, 1]) plt.show()这里需要特别强调一下max_depth这个参数。我在教学中发现很多同学喜欢把max_depth设得很大觉得树越深模型越准确这是典型的误解。模型复杂度和模型效果之间不是简单的正比关系而是倒U型关系。树太浅欠拟合学不到规律树太深过拟合记住了太多噪声。找到中间那个平衡点才是真正考验功夫的地方。3.2 随机森林一群树的智慧接着上面的问题说既然单棵决策树容易过拟合那怎么办一个非常朴素的想法是一棵树容易犯错那一百棵树一起投票总该靠谱了吧这就是随机森林的核心思想用很多棵决策树组成的“森林”来集体决策同时引入随机性让每棵树都不完全一样。随机性体现在两个地方这也是“随机森林”这个“随机”二字的来源。第一是样本随机训练每一棵树的时候从原始数据中有放回地抽取一部分样本这叫Bootstrap抽样。这样每一棵树用的数据都不完全一样大家看到的视角不同综合起来就更全面。第二是特征随机在每个节点分裂时不是从所有特征中找最优而是随机抽一部分特征再从这些特征中找最优。这样保证了每棵树的侧重点不同减少了树与树之间的相关性。为什么要刻意让树之间有差异呢这个道理可以用一个生活场景来说。如果你要做一个重大决定你会只听一个人的意见还是听十个背景不同、经历不同的朋友一起商量群体决策在大多数情况下都比个体决策更可靠前提是这个群体内部要有足够多的不同观点。如果十个人都是同一个思维模式那跟听一个人意见没什么区别。随机森林在绝大多数表格数据上表现都相当好被称为“没有超参数也能用”的算法虽然这话有点夸张但也说明了它的鲁棒性。它还能输出特征重要性排名告诉你说这个模型主要靠哪些特征做判断这个功能在业务分析中特别实用可以用来发现影响结果的关键因素。代码示例from sklearn.ensemble import RandomForestClassifier model RandomForestClassifier( n_estimators200, # 树的数量通常100-500之间 max_depth10, max_featuressqrt, # 每个节点随机抽取的特征数 random_state42, n_jobs-1 # 使用所有CPU核心加速训练 ) model.fit(X_train, y_train) print(训练集准确率, model.score(X_train, y_train)) print(测试集准确率, model.score(X_test, y_test)) # 特征重要性 importance model.feature_importances_ for i, imp in enumerate(importance): print(f特征{i}: {imp:.4f})这里n_estimators是个值得聊的参数。树的数量太少比如50棵以下模型的稳定性不够每次运行结果差异比较大但也不是越多越好超过500棵之后提升非常小反而增加训练和预测的时间。折中来看200到300棵是性价比最高的区间。随机森林还有一个隐藏优势它不需要太精细的调参用默认参数往往就能达到不错的基线效果。做项目的时候我经常拿随机森林的结果作为“及格线”如果辛辛苦苦调出来的神经网络模型还不如随机森林那说明问题不在模型复杂度上而可能出在特征工程或数据质量上。4. 距离与概率驱动的算法4.1 K近邻靠投票完成分类K近邻K-Nearest NeighborsKNN可能是机器学习里最直观的算法了一句话就能说清楚一个样本的类别由离它最近的K个样本投票决定。比如说K取5那就找到离这个待预测样本最近的5个已知样本看这5个样本里哪一类占多数就把它判为哪一类。这个算法听起来简单到不像机器学习但它背后有一个非常深刻的假设相似的样本在空间中距离接近。这个假设在很多时候是成立的。比如你想判断一个人是不是经常运动那你看看他身边最亲近的5个朋友是不是都在运动大概率就能猜个八九不离十。KNN有几个关键的细节需要注意。第一个是K值的选择。K太小比如K1模型很容易受到单个噪声点的影响K太大比如K100会把太远的样本也拉进来投票导致分类边界过于平滑。通常的做法是用交叉验证来选K在3到20之间试。第二个是距离度量方式。最常用的是欧氏距离但如果特征维度很高欧氏距离的效果会变差这时可以考虑余弦相似度或曼哈顿距离。第三个是特征归一化这一点尤其重要。KNN是靠距离来判断相似度的如果某个特征的数值范围特别大它会主导整个距离计算其他特征就形同虚设了。归一化到同一个量纲才能保证每个特征公平地参与投票。KNN最明显的缺点就是计算量大。因为它“懒惰学习”的特性——训练阶段几乎不做什么只是把所有数据存下来真正的工作都在预测阶段做——如果训练集有100万个样本每预测一个新样本都要计算它到100万个样本的距离这个开销相当大。所以KNN适合中小规模的数据集不适合大规模生产环境。代码示例from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import StandardScaler from sklearn.model_selection import GridSearchCV # 先归一化KNN对尺度敏感 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test) # 用网格搜索找最优K param_grid {n_neighbors: range(3, 20)} grid GridSearchCV( KNeighborsClassifier(), param_grid, cv5, # 5折交叉验证 scoringaccuracy ) grid.fit(X_train_scaled, y_train) print(最优K值, grid.best_params_) print(交叉验证最佳准确率, grid.best_score_) print(测试集准确率, grid.score(X_test_scaled, y_test))这里的StandardScaler就是做归一化的标准做法把每个特征变成均值为0、标准差为1的分布。我见过太多人用KNN不归一化结果是数值范围大的特征完全主导了预测结果模型准确率上不去还找不到原因最后只能怪数据集不好。4.2 朴素贝叶斯用概率做判断朴素贝叶斯是另一个看起来简单但非常强大的算法它基于贝叶斯定理。贝叶斯定理用一句话说就是当你获得新信息后你的信念应该更新。放到分类问题里就是先计算每个类别的先验概率在所有样本中这个类别占多少比例然后根据当前样本的特征计算后验概率最后选择后验概率最大的类别。“朴素”这个字眼是关键。它的意思是假设所有特征之间相互独立。这个假设在现实中几乎不可能完全成立——比如在文本分类里“价格”和“便宜”两个词就不是独立的它们经常一起出现。但神奇的是即使这个假设被违背了朴素贝叶斯在很多场景下依然表现得非常好尤其是在文本分类、垃圾邮件过滤这类问题上。朴素贝叶斯为什么面对“错误假设”还能表现好一个解释是虽然特征独立性假设不成立但分类决策需要的往往是各类别后验概率的相对大小关系而这种大小关系在特征相关性不是特别强的时候依然能被准确估计。也就是说它不一定能给出准确的概率但能给出正确的排名。朴素贝叶斯的优势非常突出训练和预测速度极快、对高维数据表现好、在小样本场景下表现稳定、不容易过拟合。它需要调节的超参数也极少基本上是“开箱即用”的算法。但它也有硬伤假设特征独立在特征强相关的场景下效果会打折扣另外它只适用于离散特征或者需要把连续特征离散化的情况。代码示例from sklearn.naive_bayes import MultinomialNB from sklearn.feature_extraction.text import CountVectorizer # 假设有一组文本数据和标签 texts [价格便宜质量好, 发给我价格吧, 质量真的很差, 这家店服务态度不错] labels [1, 1, 0, 1] # 1表示好评0表示差评 # 文本向量化把文本变成词频矩阵 vectorizer CountVectorizer() X vectorizer.fit_transform(texts) model MultinomialNB() model.fit(X, labels) # 预测新文本 new_text [价格便宜吗] X_new vectorizer.transform(new_text) print(预测结果, model.predict(X_new))这里的MultinomialNB是朴素贝叶斯的其中一个变体适合处理离散计数的特征比如词频。还有高斯朴素贝叶斯GaussianNB适合处理连续特征伯努利朴素贝叶斯BernoulliNB适合处理0/1二值特征。选哪个变体取决于数据形态不要一股脑都用MultinomialNB。5. 边界与聚类SVM 与 K-Means5.1 支持向量机寻找最大边距的超平面支持向量机Support Vector MachineSVM在深度学习流行之前是机器学习界的“当红花旦”。它解决的是分类问题核心思想非常优美在两类数据之间画一条分界线让这条线离两边最近的数据点都尽可能远。这个“离两边最近的数据点”就是支持向量这条线在二维空间叫线在高维空间叫超平面。为什么非要“最大化边距”呢因为边距越大模型的泛化能力通常越强对新样本的分类就越稳健。你可以想象一下如果你的分类边界紧贴着训练数据那稍微来个之前没见过的新样本很可能就落在了边界另一边分类就错了但如果边界离训练数据很远两边都留有充足的“缓冲区”新样本即使有点偏差也大概率能被正确分类。SVM另一个杀手锏是核函数Kernel Function。当数据在当前维度下线性不可分时核函数可以把数据映射到更高维的空间在高维空间里找到一个超平面把它们分开。最常见的核函数有线性核、多项式核、高斯径向基核RBF。RBF核在实践中最常用因为它能处理绝大多数非线性问题而且只有一个超参数gamma需要调节。SVM的优点是在高维空间表现优秀即使特征数量远大于样本数量也能工作泛化能力强不容易过拟合。缺点是训练时间较长尤其在大数据集上对参数C和gamma敏感需要仔细调参模型可解释性较弱。用Sklearn实现SVMfrom sklearn.svm import SVC from sklearn.pipeline import Pipeline from sklearn.model_selection import GridSearchCV from sklearn.preprocessing import StandardScaler # 注意SVM对特征尺度非常敏感必须先归一化 pipeline Pipeline([ (scaler, StandardScaler()), (svm, SVC()) ]) param_grid { svm__C: [0.1, 1, 10, 100], svm__gamma: [0.01, 0.1, 1], svm__kernel: [rbf] } grid GridSearchCV(pipeline, param_grid, cv5, scoringaccuracy, n_jobs-1) grid.fit(X_train, y_train) print(最优参数, grid.best_params_) print(测试集准确率, grid.score(X_test, y_test))这里的Pipeline管道是用来串联多个步骤的工具它保证归一化操作是在每一折交叉验证内部独立进行的避免了“数据泄露”。很多新手容易犯一个错误先对整个数据集做归一化再划分训练集和测试集做交叉验证。这会导致测试集的信息泄露到训练过程中得到的评估结果虚高。5.2 K-Means无监督的自动分组前面讲的所有算法都属于监督学习——训练数据里有“标准答案”算法学习的是从特征到答案的映射。K-Means则是完全不同的逻辑它是聚类算法属于无监督学习训练数据里没有任何标签算法要自己发现数据中的结构把相似的样本自动分成K组。K-Means的工作过程是这样先随机选K个点作为初始中心然后计算每个样本到这K个中心的距离把样本归到最近的那个中心所在的类接着重新计算每个类的质心组内所有样本的平均位置把它作为新的聚类中心然后重复“分配样本-更新中心”这个过程直到聚类中心不再变化或达到最大迭代次数。用生活化的例子来说K-Means就像管理员给书分类先随便放几个空书架的标签在房间里然后把每本书放到离它最近的那个标签对应的书架上全部放完后发现有些书架的书分布不太均匀于是移动标签的位置让它正好位于一堆书的“中心点”再次重新分配书本反复几次之后每本书都会稳定地待在离自己最近的书架上了。K-Means最大的难点在于选择K值。这个K值事先是不知道的需要结合业务和算法来定。常用的方法是“肘部法则”画一条“聚类数K vs 簇内平方和”的曲线找到曲线的“肘部”位置那个K值就是推荐值。还有一个更实用但计算量稍大的方法是轮廓系数法轮廓系数越接近1说明聚类效果越好。from sklearn.cluster import KMeans import matplotlib.pyplot as plt # 用肘部法则选K inertia [] K_range range(1, 11) for k in K_range: kmeans KMeans(n_clustersk, random_state42, n_init10) kmeans.fit(X) inertia.append(kmeans.inertia_) plt.plot(K_range, inertia, bo-) plt.xlabel(K) plt.ylabel(Inertia) plt.title(肘部法则确定K值) plt.show() # 选定K后训练 kmeans KMeans(n_clusters3, random_state42, n_init10) labels kmeans.fit_predict(X) print(聚类标签, labels) print(聚类中心, kmeans.cluster_centers_)这里有个n_init参数意思是算法会从随机位置开始跑10次取效果最好的那个结果。千万不要把n_init设成1K-Means的初始中心选择是随机的不同的初始点可能收敛到不同的局部最优解多跑几次取最优是保证结果稳定的基本操作。Sklearn新版默认n_init10但有些老代码里没设这个参数跑出来的结果每次都不一样还以为是代码bug其实只是初始中心随机性导致的。K-Means也有明显的局限。第一它假设每个簇是凸形的对非凸形状的簇效果不好。第二它基于距离计算对异常值敏感。第三它不适用于类别型特征只能处理数值型特征。在很多实际业务中K-Means主要作为探索性分析的工具用来初步理解数据结构而不是作为最终解决方案。6. 特征工程与集成学习6.1 PCA降维的经典工具主成分分析Principal Component AnalysisPCA严格来说不算一个“模型”它是特征工程里最经典的降维工具。它的作用是在保留数据大部分信息的前提下把高维数据压缩到低维。为什么需要降维因为数据维度太高会带来很多问题计算量增大、存储成本增高、模型容易过拟合还会出现“维度灾难”——在高维空间里样本之间的距离会趋于相似很多基于距离的算法会完全失效。PCA的原理用大白话讲是这样的你要在n维空间里找一个新方向使得所有样本投影到这个方向上之后方差数据的离散程度最大。这个方向就是第一主成分。然后再找一个与它正交的方向使剩余方差最大这就是第二主成分。以此类推。因为方差大的方向承载的信息多方差小的方向承载的往往是噪声所以我们可以只保留前几个主成分丢掉后面的实现降维。用PCA有几点必须注意。第一是数据必须先归一化否则数值范围大的特征会主导主成分方向PCA就不是提取“数据的结构”了而是提取“数值范围的分布”。第二是PCA后得到的特征是原有特征的线性组合可解释性会大打折扣。第三是PCA是无监督的方法它不关心标签所以降维后的特征不一定对分类任务最有帮助。如果是为了提升分类效果可以考虑有监督的降维方法比如LDA线性判别分析。实操中PCA还有个有趣的玩法用PCA做数据可视化。高维数据没法直接画图但用PCA降到2维或3维之后就可以用散点图直观地看数据的分布结构。我做过一个项目把用户行为特征用PCA降维后画出来发现不同群体在二维平面上分得很开这个发现直接指导了后续的精细化运营策略。代码示例from sklearn.decomposition import PCA from sklearn.preprocessing import StandardScaler # 先归一化 scaler StandardScaler() X_scaled scaler.fit_transform(X) # 查看每个主成分能解释多少方差 pca_full PCA() pca_full.fit(X_scaled) explained_variance pca_full.explained_variance_ratio_ # 累计解释方差比达到95%的维度数量 cumsum 0 n_components 0 for i, var in enumerate(explained_variance): cumsum var n_components i 1 if cumsum 0.95: break print(f保留95%信息需要 {n_components} 个主成分) # 降维 pca PCA(n_componentsn_components) X_pca pca.fit_transform(X_scaled) print(降维前, X_scaled.shape) print(降维后, X_pca.shape)这里“累计解释方差比达到95%”是一个常用的经验准则但它不是绝对的标准。在有些场景下保留80%就够了在另一些场景下比如金融风控追求精确可能需要保留99%以上。关键在于你要清楚自己降维的目的是什么。为了可视化2到3个维度就够为了加速训练可以适当压缩为了压缩存储就需要在信息和空间之间权衡。6.2 AdaBoost把弱学习器变成强学习器集成学习Ensemble Learning的思想在前面随机森林里已经提到过了AdaBoost是集成学习里另一个经典代表。不同之处在于随机森林是“并行”的——所有树同时构建互相独立AdaBoost是“串行”的——每一轮训练都关注上一轮犯过的错误按顺序迭代。AdaBoost的核心思路是这样的先用原始数据训练一个弱学习器通常是深度很浅的决策树也叫决策树桩然后增大被这个学习器分错的样本的权重减少分对的样本的权重再用调整权重后的数据训练下一个弱学习器。如此反复迭代最后把这一堆弱学习器加权组合起来权重大小取决于每个学习器的表现。打个比方AdaBoost就像老师在给学生出题第一套题大家考完了发现有些知识点大家普遍容易错第二套题就专门出这些容易错的知识点让大家多练练完后那些被反复练熟的知识点在最终考试里的比重就会相应提高。通过这样有针对性的反复强化整体水平就上来了。这样做的好处是即使每个弱学习器只有比随机猜测好一点点的能力组合起来也能变成一个非常强的模型。但在实际应用时AdaBoost对异常值和噪声比较敏感。因为异常值的样本会被赋予越来越高的权重导致后续的学习器过度关注这些异常点。如果数据集里有比较多噪声要谨慎使用AdaBoost这种情况下随机森林或梯度提升树Gradient Boosting可能是更好的选择。from sklearn.ensemble import AdaBoostClassifier from sklearn.tree import DecisionTreeClassifier # 基学习器用深度为1的决策树桩 base_estimator DecisionTreeClassifier(max_depth1) model AdaBoostClassifier( estimatorbase_estimator, # 新版Sklearn参数名是estimator n_estimators100, learning_rate1.0, random_state42 ) model.fit(X_train, y_train) print(AdaBoost测试集准确率, model.score(X_test, y_test)) # 查看每个弱学习器的权重 print(弱学习器权重, model.estimator_weights_)learning_rate是AdaBoost另一个重要参数控制每轮迭代对最终结果的贡献。learning_rate越小模型学习越保守需要更多的弱学习器learning_rate太大模型可能过于激进导致波动。通常建议learning_rate设小一点0.1到1之间配合较多的n_estimators使用。需要提醒一下Sklearn 1.2版本之后AdaBoostClassifier的base_estimator参数改名为estimator了如果你用的是新版本还按旧参数名写会直接报错。这种API变动是Sklearn每个大版本都可能出现的情况遇到报错先检查一下版本号和API说明别急着怀疑自己的代码逻辑。7. 从传统算法到深度学习的升级路径7.1 感知机到神经网络前面讲的九个传统算法如果都掌握了再来看深度学习你会发现很多东西是相通的。深度学习的基础单位——感知机Perceptron本质上就是逻辑回归的简化版把输入特征加权求和经过一个激活函数得到输出。多个感知机堆叠成多层结构就是神经网络。为什么多层结构能解决单层解决不了的问题呢单层感知机本质上只能学习线性决策边界就像逻辑回归只能画一条直线来分类。但如果把多个感知机分层连接起来每一层都在学习上一层的特征组合模型就能表达非常复杂的非线性关系。比如一个圆形分布的数据单层感知机无论怎么画一条直线都分不开但两层神经网络可以学出一个非线性边界把内外分开。深度学习之所以后来居上把传统算法甩在后面靠的就是这种“多层抽象”的能力。第一层学的是边缘、纹理这些底层特征第二层把边缘组合成形状、局部模式第三层再把形状组合成更抽象的概念。在大语言模型里这种层级抽象体现得更加充分低层学到词法和语法中层学到语义关系高层学到跨句子的推理能力。但这也带出了深度学习的代价计算量巨大、需要海量数据、超参数多到让人头皮发麻。传统算法的好处恰恰是数据量小也能用、可解释性强、训练速度快、对硬件要求低。我在实际项目里见过很多团队一上来就想用深度神经网络其实他们的数据和问题规模用随机森林或XGBoost解决就绰绰有余了硬上深度模型反而效果不好。选型的基本原则是这样的数据量小、特征维度中等几十到几百、业务要解释模型逻辑时优先传统算法。数据量大百万级、输入是图像或文本这类非结构化数据、计算资源充足时深度神经网络是更好的选择。7.2 CNN、RNN 与 Transformer 的基础概念几个最重要的深度学习模型结构也需要了解一下。CNN卷积神经网络是专门为图像数据设计的它的核心操作是“卷积”本质上是在图像上滑动一个小窗口比如3x3的网格逐区域提取特征。这样就利用了图像的空间局部性——相邻像素之间的联系比远处像素更紧密。RNN循环神经网络是为序列数据设计的比如文字、语音、股票价格。它的核心特点是“记忆”处理序列的每一步网络不仅看当前的输入还看前一步的记忆状态。这样就能捕捉时间上的依赖关系。但RNN有个出名的问题——梯度消失/梯度爆炸导致它很难记住很早期的信息。为了解决这个问题出现了LSTM长短期记忆网络和GRU门控循环单元通过引入“门”机制来控制信息的记忆和遗忘。Transformer则是当前大语言模型的基础架构它的核心机制叫“自注意力”Self-Attention。自注意力让序列中的每个位置都能直接关注到序列中所有其他位置不管距离有多远。这种“全连接”的注意力机制解决了RNN无法处理长距离依赖的问题而且整个计算过程可以完全并行化训练效率远高于RNN。理解了这些背景之后你会发现“人工智能十大基础算法”不是孤立的知识点它们是大模型时代的基石。比如大模型在微调和推理过程中的很多优化问题本质上还是梯度下降和损失函数的问题Transformer里的注意力机制距离的计算方式和KNN的距离计算底层逻辑相通PCA的思想被用在CLIP等模型的可解释性分析里。地基打得牢后面盖高楼才有底气。8. 新手常见问题与实操排坑8.1 入门阶段最容易踩的五个理解误区第一个误区是混淆“训练集准确率高”和“模型好”。我见过太多人拿着训练集准确率90%的模型欣喜若狂结果在测试集上只有60%。这就是典型的过拟合。判断模型好坏永远看它在未见过的数据上的表现。交叉验证的意义也在于此它模拟的是“模型在没见过的数据上表现如何”这个最关键的问题。第二个误区是不做特征工程上来就套模型。很多初学者以为机器学习就是调包拿到数据直接敲fit方法完事。其实特征工程在整个机器学习流程里的重要性远大于模型选择。同样的数据认真做特征工程后可能用线性回归就能达到80%的准确率不做特征工程即使用随机森林可能也只有70%。第三个误区是忽视数据不平衡问题。比如一个二分类任务正类样本占比95%负类只占5%。如果直接训练模型模型只需要把所有样本都预测成正类准确率就有95%。但这个模型完全没有实际价值。处理数据不平衡的方法有很多过采样、欠采样、调整类别权重、使用F1分数等指标评估。核心思想是想办法让模型对少数类样本敏感。第四个误区是归一化的时机搞错。归一化必须在划分训练集和测试集之后只在训练集上计算归一化参数均值和标准差然后用训练集的参数去变换测试集。如果把所有数据放一起归一化再划分会发生数据泄露。这个错误极其隐蔽但后果严重会让评估结果虚高。第五个误区是一次性把大招全用上。我理解新手的好奇心但用网格搜索调参、用集成学习、堆特征、做交叉验证这些手段不是越多越好。最佳实践是先用最简单的模型和默认参数跑通全流程确认没有bug然后逐步增加复杂度。每增加一个复杂度都要确保带来了明确的收益提升否则就回退。8.2 算法作业的三个核心排坑技巧如果你是在校学生正被“算法设计与分析实验”或者“人工智能大作业”折磨这里有几个从实际教学和作业批改中总结出来的技巧。第一先画数据分布图再写模型。这是我最强调的习惯。拿到任何数据集第一步不是敲代码而是用matplotlib或seaborn画几个关键图各类别的分布、特征之间的相关性、是否存在明显的离群点。这些图会指导你后续所有决策要不要归一化、特征是否要删掉、用什么模型合适。我批改作业时一眼就能看出哪个学生是认真做了数据探索的哪个是直接跑示例代码的。第二建立“基础模型-改进-调参”的标准流程。不要一上来就GridSearchCV先跑一个baseline模型把这个baseline的结果记录下来。然后尝试特征工程、模型改进每一次改动都记录效果变化。最后再针对表现最好的模型调参。这样做的好处是大作业报告好写而且你能准确知道每一步改动带来多少提升——这个信息在面试聊项目时会很有价值。第三代码报错先读最后一行再逆推。机器学习代码报错通常信息量很大但新手容易一看红屏就慌。报错信息最后一行是错误类型的核心描述先搞清楚类型是什么。如果是ValueError通常是数据形状或取值有问题如果是AttributeError通常是API版本变了或参数名不对如果是ConvergenceWarning通常是模型没收敛需要增大迭代次数或归一化数据。按这个思路排查90%的问题几分钟就能定位。最后分享一个我每年带新人都会说的经验学这十个基础算法不要贪快每个算法至少完成三件事——一是用手写代码的方式实现一遍最朴素版本不用任何机器学习库只靠numpy和数学公式二是用Sklearn实现一遍标准版本跑通流程三是找一个真实数据集应用一遍把结果展示出来。手写实现是最痛苦但收获最大的步骤它能逼你把数学公式真正看懂。等这十种算法都过完一遍你会发现看任何新模型、新论文都不会再觉得一头雾水了。