ML 算法速查

什么是机器学习

机器学习(Machine Learning, ML)是人工智能的核心分支,通过从数据中自动学习规律来进行预测或决策,而无需显式编程每一条规则。机器学习主要分为三大范式:监督学习(使用标注数据训练模型,如分类和回归)、无监督学习(从无标注数据中发现结构,如聚类和降维)和强化学习(智能体通过与环境交互学习最优策略)。本指南聚焦于监督学习和无监督学习中最常用的算法,涵盖原理、代码、优缺点和适用场景,帮助你快速选择合适的算法。

算法选择决策流程

Step 1: 你有标注数据吗?
  ├─ 是 → 监督学习
  │  ├─ 需要预测类别(离散值)? → 分类算法(逻辑回归、决策树、SVM、KNN...)
  │  └─ 需要预测数值(连续值)? → 回归算法(线性回归、Ridge、SVR...)
  └─ 否 → 无监督学习
     ├─ 需要发现数据分组? → 聚类算法(K-Means、DBSCAN...)
     └─ 需要减少特征维度? → 降维算法(PCA、t-SNE...)

监督学习 — 分类算法

逻辑回归 (Logistic Regression)

尽管名字包含"回归",逻辑回归实际上是最经典的二分类算法。它通过 sigmoid 函数将线性组合映射到 [0,1] 区间,输出概率值。模型简单、可解释性强,训练速度极快,适合作为分类问题的基线模型。在特征工程做得好的情况下,逻辑回归往往能取得出乎意料的好效果。

优点:训练快、可解释、不易过拟合、输出概率
缺点:只能学习线性决策边界、复杂关系需手动特征工程
from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) model = LogisticRegression(max_iter=1000) model.fit(X_train, y_train) y_pred = model.predict(X_test) print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")

适用场景:二分类基线、信用评分、广告点击预测、特征效应分析。

决策树 (Decision Tree)

决策树通过递归地将数据按特征值分裂来构建树结构,每个叶节点对应一个预测类别。使用信息增益(ID3)、增益率(C4.5)或基尼不纯度(CART)来选择最优分裂特征。决策树直观易懂,可以直接可视化,但容易过拟合,通常需要剪枝或结合集成方法使用。

优点:可解释性极强、无需标准化、可处理混合类型特征
缺点:容易过拟合、对数据变化敏感、决策边界为轴对齐
from sklearn.tree import DecisionTreeClassifier model = DecisionTreeClassifier(max_depth=5, min_samples_leaf=10) model.fit(X_train, y_train) y_pred = model.predict(X_test) print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")

适用场景:需要可解释性的业务决策、特征重要性分析、规则提取。

随机森林 (Random Forest)

随机森林是 Bagging 策略的经典实现:通过训练多棵决策树并取多数投票来进行预测。每棵树使用随机采样的数据子集和特征子集,有效降低方差和过拟合风险。随机森林是实践中最常用的算法之一,开箱即用效果好,对超参数不太敏感,且能提供特征重要性评估。

优点:精度高、不易过拟合、可并行训练、提供特征重要性
缺点:模型较大、推理较慢、可解释性不如单棵决策树
from sklearn.ensemble import RandomForestClassifier model = RandomForestClassifier(n_estimators=100, max_depth=10, random_state=42) model.fit(X_train, y_train) y_pred = model.predict(X_test) print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}") print(f"Feature importances: {model.feature_importances_}")

适用场景:通用分类任务、特征选择、缺少领域知识时的首选算法。

支持向量机 (SVM)

SVM 通过寻找最大间隔超平面来分割不同类别的数据点。使用核技巧(如 RBF、多项式核)可以在高维空间中处理非线性可分问题。SVM 在中小规模数据集上表现优异,泛化能力强,但在大数据集上训练较慢,且对特征缩放敏感。

优点:高维空间表现好、泛化能力强、核技巧处理非线性
缺点:大数据训练慢、对缩放敏感、不直接输出概率
from sklearn.svm import SVC from sklearn.preprocessing import StandardScaler scaler = StandardScaler() X_train_s = scaler.fit_transform(X_train) X_test_s = scaler.transform(X_test) model = SVC(kernel='rbf', C=1.0, gamma='scale') model.fit(X_train_s, y_train) y_pred = model.predict(X_test_s) print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")

适用场景:文本分类、图像分类、生物信息学、中小规模高维数据。

K-近邻 (KNN)

KNN 是最直观的分类算法:对于待预测样本,找到训练集中距离最近的 K 个邻居,以多数投票决定类别。KNN 属于惰性学习(lazy learning),不需要训练过程,但预测时需遍历所有训练数据,因此在大数据集上效率较低。距离度量的选择和 K 值对结果影响很大。

优点:无需训练、直觉简单、天然支持多分类
缺点:预测慢、维度灾难、对噪声敏感、需特征缩放
from sklearn.neighbors import KNeighborsClassifier model = KNeighborsClassifier(n_neighbors=5, metric='minkowski') model.fit(X_train_s, y_train) y_pred = model.predict(X_test_s) print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")

适用场景:推荐系统原型、小数据集快速验证、异常检测辅助。

朴素贝叶斯 (Naive Bayes)

朴素贝叶斯基于贝叶斯定理,假设特征之间条件独立。尽管这个假设在现实中很少完全成立,但该算法在文本分类(垃圾邮件过滤、情感分析)中表现出色。训练和预测速度极快,在高维稀疏数据上表现良好,适合作为 NLP 任务的基线模型。

优点:极快速、高维稀疏数据表现好、少量数据也有效
缺点:条件独立假设过强、连续特征处理不理想
from sklearn.naive_bayes import MultinomialNB from sklearn.feature_extraction.text import TfidfVectorizer vectorizer = TfidfVectorizer(max_features=5000) X_train_v = vectorizer.fit_transform(X_train_text) X_test_v = vectorizer.transform(X_test_text) model = MultinomialNB(alpha=1.0) model.fit(X_train_v, y_train) y_pred = model.predict(X_test_v) print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")

适用场景:文本分类、垃圾邮件过滤、情感分析、实时分类系统。

梯度提升 (XGBoost / LightGBM)

梯度提升通过顺序训练弱学习器(通常是决策树),每一轮新模型拟合前一轮的残差,逐步减少预测误差。XGBoost 和 LightGBM 是两种高效实现,在 Kaggle 竞赛和工业界广泛应用。XGBoost 使用二阶泰勒展开优化,LightGBM 使用直方图和 GOSS 采样加速训练。这是表格数据上表现最好的算法类型之一。

优点:精度极高、内置正则化、处理缺失值、特征重要性
缺点:超参数较多、训练较慢、可能过拟合小数据
import xgboost as xgb model = xgb.XGBClassifier( n_estimators=200, max_depth=6, learning_rate=0.1, subsample=0.8, colsample_bytree=0.8, random_state=42 ) model.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False) y_pred = model.predict(X_test) print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}") # LightGBM alternative import lightgbm as lgb model_lgb = lgb.LGBMClassifier(n_estimators=200, learning_rate=0.1) model_lgb.fit(X_train, y_train)

适用场景:表格数据竞赛、金融风控、推荐系统排序、CTR 预估。

监督学习 — 回归算法

线性回归 (Linear Regression)

线性回归通过最小二乘法拟合特征与目标变量之间的线性关系。它是回归问题的基线模型,简单高效且可解释性强。模型输出每个特征的系数,直观展示特征对目标的影响方向和强度。

优点:训练极快、可解释、数学基础扎实
缺点:只能拟合线性关系、对异常值敏感
from sklearn.linear_model import LinearRegression from sklearn.metrics import mean_squared_error, r2_score model = LinearRegression() model.fit(X_train, y_train) y_pred = model.predict(X_test) print(f"MSE: {mean_squared_error(y_test, y_pred):.4f}") print(f"R2: {r2_score(y_test, y_pred):.4f}") print(f"Coefficients: {model.coef_}")

适用场景:价格预测基线、趋势分析、经济学建模。

Ridge / Lasso 回归

Ridge(L2 正则化)和 Lasso(L1 正则化)在线性回归的基础上增加了正则化项来防止过拟合。Ridge 倾向于缩小所有系数但不会置零,适合特征间存在多重共线性的情况。Lasso 可以将部分系数压缩为零,实现自动特征选择。ElasticNet 结合了两者的优点。

优点:防止过拟合、Lasso 自动特征选择、处理多重共线性
缺点:仍限于线性关系、需调节正则化强度 alpha
from sklearn.linear_model import Ridge, Lasso, ElasticNet ridge = Ridge(alpha=1.0).fit(X_train, y_train) lasso = Lasso(alpha=0.1).fit(X_train, y_train) enet = ElasticNet(alpha=0.1, l1_ratio=0.5).fit(X_train, y_train) # Lasso 自动特征选择:系数为 0 的特征被剔除 print(f"Lasso non-zero features: {(lasso.coef_ != 0).sum()}")

适用场景:高维数据回归、特征选择、存在共线性的数据集。

决策树回归 (Decision Tree Regression)

决策树回归使用与分类树类似的递归分裂策略,但在叶节点输出连续值(通常为该区域内目标变量的均值)。能够捕捉非线性关系,无需特征缩放,但同样面临过拟合风险。

优点:捕捉非线性、无需缩放、直观
缺点:易过拟合、预测不连续(阶梯状)
from sklearn.tree import DecisionTreeRegressor model = DecisionTreeRegressor(max_depth=8, min_samples_leaf=20) model.fit(X_train, y_train) print(f"R2: {model.score(X_test, y_test):.4f}")

随机森林回归 (Random Forest Regression)

随机森林回归集成多棵决策回归树,取所有树预测值的平均。继承了随机森林抗过拟合的优势,是回归任务中最可靠的选择之一,尤其适合中等规模数据集。

优点:精度高、鲁棒、特征重要性评估
缺点:无法外推(预测值不超出训练范围)、模型大
from sklearn.ensemble import RandomForestRegressor model = RandomForestRegressor(n_estimators=100, max_depth=12, random_state=42) model.fit(X_train, y_train) print(f"R2: {model.score(X_test, y_test):.4f}")

支持向量回归 (SVR)

SVR 将 SVM 的思想扩展到回归问题,通过定义 epsilon 不敏感损失函数,在误差管内不施加惩罚。使用核技巧可以拟合复杂的非线性关系,在中小规模数据上效果好。

优点:核技巧处理非线性、鲁棒、泛化好
缺点:大数据慢、需缩放、超参数调优困难
from sklearn.svm import SVR model = SVR(kernel='rbf', C=100, epsilon=0.1) model.fit(X_train_s, y_train) print(f"R2: {model.score(X_test_s, y_test):.4f}")

无监督学习 — 聚类算法

K-Means

K-Means 是最常用的聚类算法,通过迭代将数据分为 K 个簇,使每个样本到其所属簇中心的距离最小。算法简单高效,适合球形簇结构的数据。需要预先指定 K 值,可通过肘部法则或轮廓系数选择最优 K。

优点:简单高效、可扩展到大数据集
缺点:需预设 K、只能发现球形簇、对初始化和异常值敏感
from sklearn.cluster import KMeans from sklearn.metrics import silhouette_score # 肘部法则选 K inertias = [] for k in range(2, 11): km = KMeans(n_clusters=k, random_state=42, n_init=10) km.fit(X_scaled) inertias.append(km.inertia_) # 最终模型 model = KMeans(n_clusters=4, random_state=42, n_init=10) labels = model.fit_predict(X_scaled) print(f"Silhouette Score: {silhouette_score(X_scaled, labels):.4f}")

DBSCAN

DBSCAN(基于密度的空间聚类)通过定义核心点、边界点和噪声点,自动发现任意形状的簇。无需预设簇数 K,能自动识别噪声点(异常值)。参数 eps(邻域半径)和 min_samples(最小样本数)对结果影响很大。

优点:无需预设 K、发现任意形状簇、自动识别噪声
缺点:对参数敏感、不适合密度差异大的数据
from sklearn.cluster import DBSCAN model = DBSCAN(eps=0.5, min_samples=5) labels = model.fit_predict(X_scaled) n_clusters = len(set(labels)) - (1 if -1 in labels else 0) n_noise = (labels == -1).sum() print(f"Clusters: {n_clusters}, Noise points: {n_noise}")

层次聚类 (Hierarchical Clustering)

层次聚类构建簇的树形结构(树状图),可以自底向上(凝聚)或自顶向下(分裂)。通过树状图可以直观选择合适的簇数。不需要预设 K,但计算复杂度为 O(n^3),不适合大规模数据。

优点:无需预设 K、可视化树状图、灵活的距离度量
缺点:计算复杂度高、不可逆(凝聚过程无法撤销)
from sklearn.cluster import AgglomerativeClustering model = AgglomerativeClustering(n_clusters=4, linkage='ward') labels = model.fit_predict(X_scaled) print(f"Silhouette Score: {silhouette_score(X_scaled, labels):.4f}")

降维算法

主成分分析 (PCA)

PCA 通过正交变换将数据投影到方差最大的方向上,从而减少特征维度。保留数据中最重要的信息(解释方差最大的成分),广泛用于数据可视化、噪声过滤和加速后续模型训练。PCA 是线性降维方法,适合数据呈线性结构的情况。

优点:高效、去噪、消除多重共线性
缺点:只能捕捉线性结构、成分可解释性差
from sklearn.decomposition import PCA import numpy as np pca = PCA(n_components=0.95) # 保留 95% 方差 X_reduced = pca.fit_transform(X_scaled) print(f"Original dims: {X_scaled.shape[1]}") print(f"Reduced dims: {X_reduced.shape[1]}") print(f"Explained variance: {np.sum(pca.explained_variance_ratio_):.4f}")

t-SNE

t-SNE 是一种非线性降维方法,特别擅长将高维数据可视化到 2D 或 3D 空间中。它通过保持数据点之间的局部相似性结构来创建低维表示。t-SNE 主要用于探索性数据分析和可视化,不适合用于特征工程或降维后接后续模型。

优点:可视化效果优秀、保持局部结构
缺点:计算慢、不确定性(每次运行结果不同)、不适合降维后建模
from sklearn.manifold import TSNE tsne = TSNE(n_components=2, perplexity=30, random_state=42) X_2d = tsne.fit_transform(X_scaled) # 通常接下来用 matplotlib 可视化 # plt.scatter(X_2d[:, 0], X_2d[:, 1], c=labels, cmap='tab10')

算法综合对比表

算法类型时间复杂度可解释性非线性最适场景
逻辑回归分类O(nd)二分类基线
决策树分类/回归O(nd log n)极高规则提取
随机森林分类/回归O(knd log n)通用任务
SVM / SVR分类/回归O(n^2 ~ n^3)是(核)中小数据
KNN分类/回归O(nd) 预测小数据原型
朴素贝叶斯分类O(nd)文本分类
XGBoost/LGBM分类/回归O(knd log n)表格数据竞赛
线性回归回归O(nd^2)极高回归基线
Ridge / Lasso回归O(nd^2)高维正则化
K-Means聚类O(nkd)客户分群
DBSCAN聚类O(n log n)异常检测
PCA降维O(nd^2)特征压缩
t-SNE降维O(n^2)数据可视化

模型评估指标

分类指标

准确率 (Accuracy):正确预测数 / 总样本数。Accuracy = (TP + TN) / (TP + TN + FP + FN)
适用于类别平衡的数据集。

精确率 (Precision):预测为正的样本中实际为正的比例。Precision = TP / (TP + FP)
关注"预测正确的成本"时使用,如垃圾邮件过滤。

召回率 (Recall):实际为正的样本中被正确预测的比例。Recall = TP / (TP + FN)
关注"漏检成本"时使用,如疾病诊断。

F1 分数:精确率和召回率的调和平均。F1 = 2 * Precision * Recall / (Precision + Recall)
类别不平衡时比准确率更有意义。

AUC-ROC:ROC 曲线下面积,衡量模型在所有阈值下的分类能力。AUC = 1 表示完美分类,0.5 表示随机猜测
不受分类阈值影响,适合比较不同模型。

from sklearn.metrics import (accuracy_score, precision_score, recall_score, f1_score, roc_auc_score, classification_report) print(classification_report(y_test, y_pred)) print(f"AUC-ROC: {roc_auc_score(y_test, y_prob[:, 1]):.4f}")

回归指标

MSE (均方误差):MSE = (1/n) * sum((y_true - y_pred)^2)
对大误差惩罚更重。

RMSE (均方根误差):RMSE = sqrt(MSE)
与目标变量同单位,更易解读。

MAE (平均绝对误差):MAE = (1/n) * sum(|y_true - y_pred|)
对异常值不敏感。

R^2 (决定系数):R^2 = 1 - SS_res / SS_tot
表示模型解释的方差比例。1.0 = 完美拟合,0 = 等同于预测均值。

from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score import numpy as np mse = mean_squared_error(y_test, y_pred) rmse = np.sqrt(mse) mae = mean_absolute_error(y_test, y_pred) r2 = r2_score(y_test, y_pred) print(f"MSE: {mse:.4f} | RMSE: {rmse:.4f} | MAE: {mae:.4f} | R2: {r2:.4f}")

常见问题 (FAQ)

Q: 如何选择分类还是回归算法?

如果目标变量是离散类别(如"是/否"、"猫/狗/鸟"),使用分类算法;如果目标变量是连续数值(如"房价"、"温度"),使用回归算法。有时可以将连续值离散化后使用分类算法,或将类别编码为数值后使用回归算法,但通常不推荐。

Q: 随机森林和 XGBoost 哪个更好?

没有绝对的优劣。随机森林更简单、超参数更少、不易过拟合,适合快速建模;XGBoost/LightGBM 通常精度更高但需要更多调参。实际项目中建议两者都尝试,通过交叉验证比较。在 Kaggle 竞赛中,梯度提升方法通常表现更好。

Q: 什么时候需要做特征缩放(标准化/归一化)?

基于距离的算法(KNN、SVM、K-Means)和梯度下降优化的模型(逻辑回归、神经网络)需要特征缩放。树模型(决策树、随机森林、XGBoost)不需要特征缩放,因为它们基于特征值的排序来分裂节点。

Q: 数据量小时应该选什么算法?

小数据集(<1000 样本)推荐:SVM(泛化好)、朴素贝叶斯(少量数据也有效)、KNN(简单直接)。避免使用深度学习和复杂集成方法,容易过拟合。同时注意使用交叉验证而非简单的训练/测试划分来评估模型。

Q: 如何处理类别不平衡问题?

常用策略包括:1) 过采样少数类(SMOTE);2) 欠采样多数类;3) 调整类别权重(class_weight='balanced');4) 使用 F1/AUC-ROC 而非准确率作为评估指标;5) 使用集成方法如 BalancedRandomForest。选择策略取决于数据量和不平衡程度。