跳转至

机器学习基础

一句话说明

机器学习是让计算机从数据中自动找规律、做预测的技术。在生信中,它是从高维组学数据(如菌群丰度表)中筛选生物标志物、做疾病分类预测的核心工具。


核心概念(白话版)

1. 什么是机器学习

  • 定义:机器学习(Machine Learning, ML)是人工智能的一个分支,核心思想是让计算机通过"看数据"自动学会规律,而不需要人类一条条写规则。
  • 白话比方:就像你学打篮球——不是靠看说明书,而是靠反复投篮、根据进没进来调整姿势。计算机也一样,喂它大量数据(投篮经验),它自己调整内部参数(姿势),最终学会预测(投进)。

三大类型

类型英文白话解释生信例子
监督学习Supervised Learning有标准答案的考试——给你题目和答案,让你学会做新题用已知健康/T2D标签的菌群数据训练分类器
无监督学习Unsupervised Learning没有标准答案——让你自己把一堆东西分分类对样本做聚类看有没有自然分群
强化学习Reinforcement Learning打游戏学习——做对了奖励,做错了惩罚,慢慢变强生信中很少用,主要用在药物设计等

2. 监督学习常用算法

随机森林(Random Forest)

  • 白话比方:你生病了去看诊,不是只找一个医生,而是同时找 500 个医生各自独立诊断,最后"投票表决"——多数医生说的结论就是最终结论。每个医生(决策树)可能有偏见,但 500 个人一起投票就很稳。
  • 原理
  • 决策树(Decision Tree):像一棵倒着的树,每个节点问一个问题(比如"Prevotella 丰度 > 0.05 吗?"),根据回答往左走或往右走,最终到达叶子节点得出结论。
  • 随机森林 = 很多棵决策树的集合
    • 每棵树只看"部分样本"(有放回随机抽样,叫 Bootstrap)
    • 每个节点只考虑"部分特征"(随机选一部分菌属来做分裂判断)
    • 最终预测 = 所有树投票取多数(分类)或取平均(回归)
  • 这种"随机 + 集成"的方式让模型既不容易过拟合,又能捕捉复杂关系
  • 生信应用
  • 疾病分类预测(如 T2D vs 健康人的菌群分类)
  • 特征重要性排序(找出哪些菌属对分类最有贡献 = 候选标志物)
  • 基因表达分类(肿瘤 vs 正常)
  • 微生物组关联分析
  • 优缺点
优点缺点
不容易过拟合(相比单棵决策树)模型是"黑盒",不如逻辑回归好解释因果
能处理高维数据(特征比样本多)样本极少时效果可能一般
自带特征重要性排序对极度不平衡数据需要额外处理
不要求数据标准化训练时间比简单模型长
能处理非线性关系和高维特征交互预测结果不容易做因果解释

注意:sklearn 的 RandomForestClassifier 不能直接处理缺失值(NaN 会报错),需要先做缺失值填充。R 的经典 randomForest 包默认不处理 NA(会报错),需指定 na.action=na.omit 或提前填充缺失值。能原生处理缺失值的是 R 的 ranger 包、XGBoost 和 LightGBM。

支持向量机(SVM, Support Vector Machine)

  • 白话比方:在两类数据点之间画一条"最宽的分界线"。想象桌上有红球和蓝球,你要放一根尺子把它们分开——SVM 就是找那个让两边球离尺子都最远的摆法。
  • 原理:找到一个超平面(hyperplane,你只需要理解为"把两堆数据分开的那条线/面"),使得两类样本到这个超平面的最小距离(margin,间隔)最大。用"核函数"(kernel)可以处理线性不可分的情况——线性不可分 = 画一条直线分不开。核函数相当于把数据"抛到高处",在高处就能用一个平面分开。
  • 生信应用:基因表达谱分类、蛋白质功能预测、DNA 甲基化分析
  • 优缺点
优点缺点
高维数据表现好样本量大时训练很慢
核函数灵活参数调优复杂(C、gamma)
理论基础扎实不直接给出概率,需要额外处理

逻辑回归(Logistic Regression)

  • 白话比方:用一个 S 形曲线把"得分"转换成"概率"。比如你考试得了 70 分,逻辑回归告诉你"及格概率 85%"。它本质上是在算各个特征对结果的"加权投票"。
  • 原理:对特征做线性组合得到一个分数,再用 sigmoid 函数(S 形曲线,不用记名字,只要知道它把任意数字"压"到 0-1 之间就行)把分数映射到 0-1 之间作为概率。如果概率 > 0.5 就预测为正类。
  • 生信应用:风险预测(如患病概率)、GWAS 中的关联分析、简单的二分类基线模型
  • 优缺点
优点缺点
简单快速,容易解释(系数=贡献度)只能学线性关系
直接输出概率特征间有复杂交互时效果差
适合做基线模型对比高维且特征相关时不稳定

3. 无监督学习常用算法

K-means 聚类

  • 白话比方:你要把一堆没有标签的球分成 K 组,先随便放 K 个"中心点",然后每个球跑向离自己最近的中心,之后把中心挪到每组球的正中间,反复几轮直到稳定。
  • 原理
  • 指定 K 个簇(cluster)的数量
  • 随机初始化 K 个质心(centroid)
  • 每个样本分配给最近的质心
  • 重新计算每个簇的质心
  • 重复 3-4 直到收敛
  • 生信应用:样本分群(如把患者分成不同亚型)、基因表达模式聚类
  • 优缺点
优点缺点
简单直观,速度快必须预先指定 K
适合大数据集对初始质心敏感
结果容易解释只能找"球形"簇,不能处理复杂形状

层次聚类(Hierarchical Clustering)

  • 白话比方:像画家谱——先把最相似的两个人合成一个小家庭,再把最相似的两个家庭合成一个大家族,一层层往上合并,最终画出一棵"族谱树"(dendrogram,树状图)。
  • 原理
  • 凝聚式(Agglomerative):自底向上,从每个样本单独一类开始,逐步合并最相似的两类
  • 分裂式(Divisive):自顶向下,把所有样本当一类,逐步分裂
  • 生信应用:样本聚类热图(heatmap)、物种进化关系推断、基因共表达模块发现
  • 优缺点
优点缺点
不需要预先指定 K计算量随样本数增加会急剧增大,样本多了会非常慢
能产生树状图,信息更丰富大样本量时很慢
对簇形状没有限制一旦合并/分裂不可撤销

4. 模型评估

交叉验证(Cross Validation, CV)

  • 白话解释:考试不能只考一次——你可能碰巧抽到会的题。交叉验证就是反复考多次,每次换一部分题当考卷,其他题拿来复习,最后取平均分才算你的真实水平。
  • 常用方式:K 折交叉验证(K-Fold CV)——把数据分成 K 份,轮流拿 1 份当测试、其余 K-1 份当训练,重复 K 次取平均。
  • 为什么要用:避免因为数据分割的偶然性(运气好/运气差)而高估或低估模型表现。样本量小的时候尤其重要。
  • 分层交叉验证(Stratified K-Fold):保证每一折中正负样本比例和总体一致。在类别不平衡时必须用。

过拟合与欠拟合

  • 过拟合(Overfitting)
  • 白话比方:考试前把答案背下来了,原题全会,但换个说法就不会了。模型"记住了"训练数据的噪声,对新数据预测很差。
  • 表现:训练集准确率 99%,测试集 60%。
  • 解决:增加数据量、减少模型复杂度、正则化、交叉验证、early stopping。

  • 欠拟合(Underfitting)

  • 白话比方:上课没听懂,考什么都不会。模型太简单,连训练数据的规律都没学到。
  • 表现:训练集和测试集准确率都很低。
  • 解决:用更复杂的模型、增加特征、减少正则化。

评估指标

指标英文白话解释公式
准确率Accuracy判对的占总数的比例。"100个人判对了多少个"(TP+TN)/(TP+TN+FP+FN)
精确率Precision你说"有病"的人里面,真的有病的比例。"抓的人里有几个是真犯人"TP/(TP+FP)
召回率Recall/Sensitivity真正有病的人里面,你找出来了多少。"10个犯人你抓到了几个"TP/(TP+FN)
F1 分数F1-Score精确率和召回率的"调和平均"。两个都高 F1 才高2PR/(P+R)
AUC-ROCAUC-ROC不管阈值怎么设,模型区分正负样本的整体能力。0.5=瞎猜,1.0=完美ROC曲线下面积
MCCMatthews Correlation Coefficient综合考虑 TP/TN/FP/FN 四个值的相关系数,不平衡数据下最可靠的单一指标(TPTN-FPFN)/sqrt((TP+FP)(TP+FN)(TN+FP)(TN+FN))
特异度Specificity真正健康的人中,你正确判为健康的比例TN/(TN+FP)

注意:样本不平衡时不能只看 Accuracy!比如 100 人中 95 个健康、5 个有病,全猜"健康"准确率就 95% 但完全没用。此时应该看 AUC、F1、MCC、PR-AUC。

📌 MCC 补充说明:MCC 值域为 -1 到 +1。+1 = 完美预测,0 = 随机猜测水平,-1 = 完全相反。MCC 的优势是同时考虑了混淆矩阵的全部四个值(TP/TN/FP/FN),在类别不平衡时比 F1 和 Accuracy 更可靠。sklearn 中用 from sklearn.metrics import matthews_corrcoef 计算。

混淆矩阵(Confusion Matrix)

  • 白话解释:一个 2x2 的表格,记录模型把每类样本判对了多少、判错了多少。
                 预测为正(有病)   预测为负(健康)
实际为正(有病)      TP              FN
实际为负(健康)      FP              TN
  • TP(True Positive):有病,判对了——"真阳性"
  • FP(False Positive):没病,误判为有病——"假阳性"(误报)
  • FN(False Negative):有病,漏判了——"假阴性"(漏报)
  • TN(True Negative):没病,判对了——"真阴性"

5. 特征选择与特征工程

为什么要做特征选择

  • 高维数据(如 245 个菌属特征)中很多是噪声,会干扰模型
  • 减少特征可以降低过拟合风险
  • 让结果更可解释("这 10 个菌属最关键"比"这 245 个菌属一起用"更有意义)
  • 减少训练时间

常用方法

方法白话解释适用场景
随机森林特征重要性看哪个特征被用得最多、对预测贡献最大通用,非线性
Permutation Importance随机打乱某个特征的值,看模型准确率掉多少——掉得越多说明这个特征越重要更可靠,该 T2D 项目就用了这个
LASSO——一种自动"砍"掉不重要特征的方法自动把不重要的特征系数压到 0线性模型
Prevalence 过滤只保留在足够多样本中出现的特征(过滤掉太稀有的菌)微生物组数据预处理
方差过滤去掉所有样本中值都一样的特征(零方差=无信息)通用预处理

6. 数据预处理

标准化(Standardization)vs 归一化(Normalization)

方法操作结果适用算法
标准化(x - 均值) / 标准差均值=0, 标准差=1SVM、逻辑回归、PCA
归一化(x - min) / (max - min)值映射到 [0,1]神经网络、K-means

随机森林不需要标准化或归一化,因为它是基于"大小比较"做分裂的,值的缩放不影响排序。

缺失值处理

  • 直接删除(样本少时不推荐)
  • 均值/中位数填充
  • 在微生物组中:丰度为 0 通常表示"未检测到",不一定要当缺失值处理

类别不平衡问题

  • 问题:正负样本数量差很多(如 T2D 78 例 vs 健康 104 例)
  • 常用方法
  • class_weight='balanced':让模型对少数类给更高的关注
  • SMOTE:人工生成少数类的"合成样本"
  • 下采样:减少多数类样本
  • 评估时用 AUC / F1 / PR-AUC 而不是 Accuracy

常用工具/命令

工具/库语言用途安装方式
scikit-learnPython机器学习核心框架(分类、回归、聚类、评估),最新 v1.8pip install scikit-learn(注意:不能用 pip install sklearn,该包名已废弃)
pandasPython数据读取和处理pip install pandas
numpyPython数值计算pip install numpy
matplotlibPython画图(ROC、特征重要性等)pip install matplotlib
seabornPython更美观的统计图pip install seaborn
XGBoostPython梯度提升树,常作为 RF 的对比模型pip install xgboost
imbalanced-learnPython处理类别不平衡(SMOTE等)pip install imbalanced-learn
joblibPython模型保存与加载sklearn 自带

实操代码

随机森林分类完整示例

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
随机森林分类完整示例 —— 从数据加载到模型评估
使用 sklearn 内置的乳腺癌数据集(二分类,类似 T2D 项目场景)
"""

import numpy as np
import pandas as pd
from sklearn.datasets import load_breast_cancer  # 加载内置数据集(乳腺癌,569样本×30特征)
from sklearn.model_selection import StratifiedKFold, cross_val_predict  # 分层交叉验证
from sklearn.ensemble import RandomForestClassifier  # 随机森林分类器
from sklearn.metrics import (
    roc_auc_score,           # AUC 评估
    classification_report,   # 分类报告(精确率、召回率、F1)
    confusion_matrix,        # 混淆矩阵
)
import matplotlib.pyplot as plt  # 画图

# ========== 第1步:加载数据 ==========
data = load_breast_cancer()  # 加载数据
X = pd.DataFrame(data.data, columns=data.feature_names)  # 特征矩阵(569×30)
y = pd.Series(data.target, name="label")  # 标签(0=恶性, 1=良性)

print(f"样本数: {X.shape[0]}, 特征数: {X.shape[1]}")
print(f"标签分布:\n{y.value_counts()}")  # 查看正负样本比例

# ========== 第2步:定义模型和交叉验证策略 ==========
# 5折分层交叉验证——保证每折中正负样本比例一致
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

# 随机森林模型配置
rf_model = RandomForestClassifier(
    n_estimators=500,           # 500棵决策树
    max_depth=None,             # 树的深度不限制(让每棵树充分生长)
    min_samples_split=2,        # 节点最少2个样本才继续分裂
    max_features="sqrt",        # 每次分裂时随机选 sqrt(n_features) 个特征
    class_weight="balanced",    # 自动根据类别频率调整权重(处理不平衡)
    random_state=42,            # 随机种子,保证可复现
    n_jobs=-1,                  # 用所有CPU核心并行训练
)

# ========== 第3步:交叉验证获取 OOF 预测 ==========
# cross_val_predict: 每个样本只在作为测试集时被预测一次(Out-of-Fold)
oof_proba = cross_val_predict(
    rf_model, X, y,
    cv=cv,
    method="predict_proba",  # 获取概率预测
    n_jobs=-1,
)[:, 1]  # 取第二列,即正类的概率值(第一列是负类概率)

# ========== 第4步:模型评估 ==========
# AUC-ROC
oof_auc = roc_auc_score(y, oof_proba)
print(f"\nOOF AUC-ROC: {oof_auc:.4f}")

# 用 0.5 作为阈值转换为 0/1 预测
oof_pred = (oof_proba >= 0.5).astype(int)

# 分类报告
print("\n分类报告:")
print(classification_report(y, oof_pred, target_names=["恶性(0)", "良性(1)"]))

# 混淆矩阵
cm = confusion_matrix(y, oof_pred)
print(f"混淆矩阵:\n{cm}")
# 解读: 行=真实标签, 列=预测标签
# [[TN, FP], [FN, TP]]

交叉验证示例

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
交叉验证示例 —— 展示 5 折 CV 每折的性能指标
"""

from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import StratifiedKFold, cross_val_score
import numpy as np

# 加载数据
X, y = load_breast_cancer(return_X_y=True)

# 定义模型
rf = RandomForestClassifier(n_estimators=300, random_state=42, n_jobs=-1)

# 定义 5 折分层交叉验证
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

# 用 AUC 作为评分指标进行交叉验证
scores = cross_val_score(rf, X, y, cv=cv, scoring="roc_auc")

# 打印每折的 AUC 和汇总
print("各折 AUC:")
for i, score in enumerate(scores, 1):
    print(f"  Fold {i}: {score:.4f}")

print(f"\n平均 AUC: {scores.mean():.4f} (+/- {scores.std():.4f})")
# 白话解读: 如果 std > 0.05,说明模型稳定性不够,可能数据太少或模型过拟合
# 参考: std < 0.02 很稳定; 0.02-0.05 基本可以; > 0.05 需要关注

特征重要性可视化

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
特征重要性可视化 —— 使用 Permutation Importance
(该 T2D 项目就用了这个方法来找候选核心菌属)
"""

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
from sklearn.inspection import permutation_importance  # permutation importance
from sklearn.model_selection import train_test_split

# ========== 加载并拆分数据 ==========
data = load_breast_cancer()
X = pd.DataFrame(data.data, columns=data.feature_names)
y = data.target

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y  # stratify 保证分层
)

# ========== 训练模型 ==========
rf = RandomForestClassifier(n_estimators=500, random_state=42, n_jobs=-1)
rf.fit(X_train, y_train)

# ========== 计算 Permutation Importance ==========
# 原理:随机打乱某个特征的值,看模型在测试集上的性能掉多少
# 掉得越多 = 这个特征越重要
perm_result = permutation_importance(
    rf, X_test, y_test,
    n_repeats=10,          # 每个特征重复打乱10次取平均
    random_state=42,
    scoring="roc_auc",     # 用 AUC 衡量性能变化
    n_jobs=-1,
)

# 整理为 DataFrame
importance_df = pd.DataFrame({
    "feature": X.columns,
    "importance_mean": perm_result.importances_mean,
    "importance_std": perm_result.importances_std,
}).sort_values("importance_mean", ascending=False)

# ========== 可视化 Top 15 ==========
top_n = 15
top_df = importance_df.head(top_n).iloc[::-1]  # 倒序方便画横向条形图

plt.figure(figsize=(10, 8))
plt.barh(range(top_n), top_df["importance_mean"], xerr=top_df["importance_std"])
plt.yticks(range(top_n), top_df["feature"])
plt.xlabel("Permutation Importance (AUC drop)")
plt.title(f"Top {top_n} Features by Permutation Importance")
plt.tight_layout()
plt.savefig("feature_importance.png", dpi=150)
plt.show()
print("Top 5 most important features:")
print(importance_df.head(5).to_string(index=False))

和你项目的关联

宏基因组示例项目具体做了什么

根据研究项目(train_rf_model.py),整体流程如下:

  1. 数据来源:公共数据集编号数据集,从 GMrepo 获取的公开肠道微生物组数据(属水平丰度矩阵)
  2. 任务:Healthy vs T2D 二分类(健康 104 例,T2D 78 例,共 182 个样本)
  3. 特征处理
  4. 原始 245 个属特征
  5. Prevalence 过滤(出现率 < 5% 的属被移除)
  6. 零方差过滤
  7. 无效特征移除(未知菌属)
  8. 最终保留约 134 个特征
  9. log1p 变换(对丰度取 log(1+x),压缩极端值)
  10. 模型:RandomForestClassifier
  11. 外层:5 折分层交叉验证(StratifiedKFold)
  12. 内层:3 折 + RandomizedSearchCV(12 次随机搜索调参)
  13. 参数搜索范围:n_estimators=[200,300,500,800]、max_depth=[None,5,8,12]等
  14. class_weight="balanced" / "balanced_subsample"(处理轻度不平衡)
  15. 特征选择:Permutation Importance(在测试折上计算,重复 10 次取平均)
  16. 评估指标
  17. OOF AUC = 0.5163(接近随机水平 0.5,说明区分能力有限)
  18. OOF AP = 0.4874
  19. 默认阈值 0.5 混淆矩阵:[[80,24],[55,23]]
  20. 结果解读
  21. 模型预测性能有限,接近随机水平
  22. 但 Permutation Importance 排序出了 Anaerobutyricum、Prevotella 等候选菌属
  23. 定位为"探索性分析",候选菌属作为后续验证的线索

关键数字(面试必记)

  • 样本量:182(Healthy 104 / T2D 78)
  • 原始特征:245 属 -> 过滤后 134 属
  • 交叉验证:5折外层 + 3折内层
  • OOF AUC:0.5163
  • 候选核心菌属:Anaerobutyricum、Evtepia、Prevotella、Dysosmobacter 等

面试怎么答

Q1: 解释一下随机森林的原理

A: "随机森林是一种集成学习方法。它的核心思想是'三个臭皮匠赛过诸葛亮'——训练很多棵决策树,每棵树只看部分样本和部分特征,最后投票表决。具体来说有两个随机:第一,每棵树用 Bootstrap 方式随机抽一部分样本来训练;第二,每个节点分裂时只随机选一部分特征来比较。这两个随机降低了模型方差,让整体不容易过拟合。最终预测就是所有树投票取多数。在该项目中用了 200-800 棵树,用 StratifiedKFold 来评估。"

Q2: 什么是过拟合?怎么避免?

A: "过拟合就是模型把训练数据的噪声也'背'下来了,在训练集上表现好但在新数据上表现差。就像考试背答案,原题全会但换个说法就不行了。避免过拟合常用的方法有:一、交叉验证——让模型在不同数据划分上都表现好才算好;二、控制模型复杂度——比如限制树的深度、增加最小叶节点样本数;三、集成方法——随机森林本身就是通过多棵树平均来降低方差;四、正则化——比如 LASSO 对特征系数做惩罚。该项目用了嵌套交叉验证:外层 5 折评估真实性能,内层 3 折做参数调优,严格防止信息泄漏。"

Q3: 该项目中为什么选择随机森林?

A: "选随机森林有几个原因:第一,我的数据是属水平丰度表,特征维度高(245个属)、样本量相对小(182例),随机森林在这种高维小样本场景下比较稳健,不容易过拟合;第二,随机森林自带特征重要性排序,我可以直接用 Permutation Importance 找出对分类贡献最大的菌属作为候选标志物;第三,它对数据预处理要求低,不需要标准化,对缺失值也有一定容忍度;第四,作为本科论文,方法不宜过于复杂,随机森林是成熟、被广泛认可的方法。当然,最终 AUC 只有 0.52 左右,说明属水平数据在这个数据集上区分能力有限,这也是诚实的结论。面试时不要回避数字,但要紧跟解释原因和你学到了什么。"

Q4: 交叉验证是什么?为什么要用?

A: "交叉验证是把数据分成 K 份,轮流拿 1 份做测试、K-1 份做训练,重复 K 次后取平均作为模型评估结果。为什么要用?因为样本量有限的时候,如果只做一次 train/test split,结果受数据分割的偶然性影响很大——可能碰巧分到'简单'的测试集就高估了模型。交叉验证相当于考多次试取平均,结果更可靠。另外在该项目中用了'分层'交叉验证,保证每折里 T2D 和健康人的比例和总体一致,避免某一折正好没有 T2D 样本的极端情况。"

Q5: AUC-ROC 曲线怎么解读?

A: "ROC 曲线的横轴是假阳性率(FPR),纵轴是真阳性率(TPR),它展示了在不同分类阈值下模型的表现。AUC 就是这条曲线下面的面积。AUC=0.5 表示模型和随机猜一样没用;AUC=1.0 表示完美分类。一般 0.7-0.8 算可以接受,0.8-0.9 算比较好。该项目 OOF AUC = 0.52,说明模型整体区分能力接近随机水平。但这并不意味着没有价值——通过 Permutation Importance 我们仍然能找到一些有相对区分力的候选菌属,作为后续深入研究的线索。"

Q6: 你的模型效果怎么样?怎么评估的?

A: "说实话,模型效果有限。OOF AUC 约 0.52,接近随机水平。评估方式是 5 折分层交叉验证 + 内层 3 折参数搜索的嵌套设计,确保评估结果不受调参过拟合的影响。除了 AUC,我还看了 Average Precision(0.49)、不同阈值下的混淆矩阵、F1 分数和平衡准确率。效果不好的原因可能有:一、属水平丰度数据本身分辨率不够,种水平或功能层面可能更有信息量;二、样本量只有 182 例,统计力不足;三、T2D 是复杂疾病,单纯菌群丰度可能不够。但作为探索性分析,能找到候选菌属线索就是有价值的贡献。"


延伸阅读

  1. scikit-learn 官方文档 - Ensemble Methods:https://scikit-learn.org/stable/modules/ensemble.html
  2. 最权威的随机森林和梯度提升实现文档,含代码示例
  3. StatQuest with Josh Starmer (YouTube):搜索 "StatQuest Random Forest"
  4. 用动画讲解 ML 概念,非常适合入门,有英文字幕
  5. 《Pattern Recognition and Machine Learning》Bishop (2006)
  6. 机器学习经典教材,适合想深入理论的同学(有中文翻译版)

📌 sklearn 版本说明(2026年5月): - 当前最新版为 scikit-learn 1.8.0,支持 Python 3.11-3.14 - 安装必须用 pip install scikit-learnpip install sklearn 会报错(该包名已于 2023 年废弃) - 本文档中所有代码示例均已验证兼容 sklearn 1.6-1.8 版本,无废弃 API 使用