01
什么是机器学习:程序不再由人一行行写死
普通程序是人写规则:数据进,规则加工,答案出。垃圾邮件过滤如果靠人写规则——「含『中奖』就拦」——发件人换个字你就输了。机器学习把方向倒过来:数据 + 答案进,规则(模型)出。你给它几千封标注好的「垃圾 / 正常」邮件,它自己学出一条会随数据变化的决策边界。
它和统计学共用大量数学(回归、最大似然),但侧重不同:统计关心「变量之间为什么有关系」,要解释系数与显著性;机器学习关心「下一次预测得准不准」,要泛化。它和深度学习是包含关系:深度学习是机器学习的一个子分支,靠多层神经网络自动学特征,擅长图像、语音、文本这类非结构化数据;而在 Excel 式的表格数据上,树模型等经典方法至今常常更强、更快、更省数据。
怎么判断你的问题适不适合上机器学习?三个信号:一是规则写不完——垃圾邮件的花样永远在变,写规则追不上;二是数据在积累——历史订单、点击、标签越攒越多,模式藏在里面;三是允许概率性错误——预测 95% 准就能产生价值,不需要数学上 100% 的证明。三条都占,就是机器学习的主场;一条都不占,写个 if-else 更便宜。
- 一句话定义
- 从数据中自动归纳规则,用于预测未知
- 学科包含关系
- 人工智能 ⊃ 机器学习 ⊃ 深度学习
- 三大类问题
- 监督学习 / 无监督学习 / 强化学习
- 核心目标
- 泛化:在没见过的数据上依然准
- 数学基础
- 线性代数、概率统计、微积分(遇到再补即可)
- 主流语言
- Python 生态最完整(sklearn / PyTorch)
- 影响结果的第一因素
- 数据与特征质量,其次才是算法
- 入门硬件
- 经典 ML 不需要 GPU,笔记本就行
02
环境准备:一个虚拟环境,四个包
机器学习的 Python 标配四件套:numpy(数组运算)、pandas(表格处理)、matplotlib(画图)、scikit-learn(经典 ML 算法全集)。装在虚拟环境里,别污染系统 Python。
# 建一个独立环境(Python 建议 3.10 以上,越新越好) python3 -m venv .venv source .venv/bin/activate # Windows 用 .venv\Scripts\activate # 一条命令装齐四件套 python -m pip install numpy pandas matplotlib scikit-learn
# 装了 Anaconda / Miniconda 的话
conda create -n ml python=3.11
conda activate ml
conda install scikit-learn pandas matplotlib
# 浏览器打开 Google Colab 或 Kaggle Notebooks,新建笔记本 # 环境已预装好全部四件套,第一格直接验证: import sklearn print(sklearn.__version__)
03
第一个实验:10 行跑通一次「学习」
概念可以先放一放,用 scikit-learn 内置的手写数字数据集,把「训练 → 预测 → 打分」这个闭环跑起来。整个过程就是三行核心调用。
# 1797 张 8x8 手写数字灰度图:每行一个样本,64 个像素值当特征 from sklearn.datasets import load_digits from sklearn.model_selection import train_test_split from sklearn.svm import SVC X, y = load_digits(return_X_y=True) X_tr, X_te, y_tr, y_te = train_test_split(X, y, random_state=0) model = SVC(gamma=0.001) # 1. 选模型(此刻只是个空壳) model.fit(X_tr, y_tr) # 2. 训练:从数据里学出规则 print(model.score(X_te, y_te)) # 0.9956 —— 打分用的是模型从没见过的数据
-
01
找数据
内置数据集一行拿到,不用下载。真实项目里,「找数据、洗数据」往往占掉八成时间——算法反而是最不花时间的部分。
-
02
先切分,再动手
train_test_split把数据分成训练集和测试集。测试集是一张「密封试卷」,从写下第一行代码起就不许偷看,最后才能拆。 -
03
fit:唯一「学习」发生的地方
调用
fit之前模型只是一堆默认参数;调用之后,模型内部的参数被数据改写——这就是机器学习里「学习」二字的全部含义。 -
04
score:只能考一次的期末考
score/predict只对测试集用。分数不满意,回训练集改特征、换模型,而不是动测试集——动了它,分数就再也不可信。
04
核心概念:三大类、八步流程、两个坑
三大类问题:看数据有没有「标准答案」
区分哪一类问题,看的是你手上有没有标签(正确答案)。有标签就是监督学习,没有就是无监督学习,靠环境给反馈的就是强化学习。绝大多数业务问题落在前两类。
- 监督学习 Supervised
- 有标签。预测数值叫回归(房价、销量),预测类别叫分类(垃圾邮件、疾病诊断)。代表算法:线性回归、逻辑回归、随机森林。
- 无监督学习 Unsupervised
- 无标签。让模型自己找结构:聚类把用户分成几群(K-Means),降维把几百个特征压成几个(PCA),常用于探索数据。
- 强化学习 Reinforcement
- 没有标签,只有奖励信号。智能体试错行动,奖励高就多做。下棋、机器人控制、游戏 AI。概念了解即可,入门阶段动手少。
标准工作流:八步一个闭环
不管什么算法,一个机器学习项目都走这条流水线。顺序不能乱——最常见的事故就是在第 4 步之前就把信息泄漏给了模型。
- 收集数据:明确预测目标是什么、标签从哪来、一条样本代表什么。
- 清洗:处理缺失值、去重、修异常值。垃圾进,垃圾出。
- 特征工程:把原始数据变成模型能吃的数字——类别编码、数值缩放、构造新特征。这一步对结果的影响常常大于换算法。
- 切分数据:先留出测试集,再谈训练。顺序反了就是自欺欺人。
- 训练:从最简单的模型开始(逻辑回归、决策树),先跑通再变强。
- 评估:测试集 + 交叉验证看泛化能力,选对指标(第 05 节速查)。
- 调参:网格搜索或随机搜索超参数;提升有限,别陷进去。
- 部署与监控:导出模型上线,持续监控数据漂移——真实数据会变,模型会过期。
八步里最值钱的往往是第三步。特征工程的典型操作:把「城市名」拆成经纬度或人均收入档位、把「下单时间」拆出星期几和小时、把两个原始字段相除造出「客单价」。原始数据里的一个细节被翻译成模型能直接用的信号,涨分常常比换十次算法都多。
过拟合、欠拟合与偏差-方差
过拟合是把训练集「背」下来了:训练分数极高,测试分数明显掉。原因是模型太复杂或数据太少。欠拟合是模型太简单,连训练集都学不好,两边分数都低。诊断只要一行——把两个分数摆在一起看:
训练集 99.5% | 测试集 71.2% ← 过拟合:背题了,要正则化 / 更多数据 / 简化模型 训练集 62.0% | 测试集 61.8% ← 欠拟合:模型太简单,加特征 / 换更强的模型 训练集 97.8% | 测试集 97.1% ← 健康:两者接近且都高
理论上这叫偏差-方差权衡:模型太简单偏差大(学不会),太复杂方差大(换一批数据结果就变)。实践中不用背术语,记住两条对策即可:正则化(给模型复杂度罚分,比如 L1/L2、限制树的深度)压方差;加数据、加有效特征降偏差。
交叉验证与评估指标
一次 train/test 切分的分数有运气成分。K 折交叉验证把训练集分成 K 份,轮流用 K-1 份训练、1 份验证,取平均——既用了每一条数据,又能看出模型稳不稳:
from sklearn.model_selection import cross_val_score scores = cross_val_score(model, X_tr, y_tr, cv=5) # 5 折各得一个分:例如 [0.96, 0.95, 0.97, 0.94, 0.96] print(scores.mean(), scores.std()) # 均值看水平,标准差看稳定性
指标怎么选:回归看 RMSE、MAE、R²;分类看准确率、精确率、召回率、F1、AUC。类别不平衡时准确率会骗人——99% 的样本是「正常」,无脑全猜「正常」就有 99% 准确率,但对抓坏人毫无用处。这时要看精确率 / 召回率 / F1,甚至只看少数类的召回。完整的指标速查和算法地图在下一节。
05
速查表:工作流、算法、指标、术语
下面这块表格能搜。忘了某个词,直接搜 召回、过拟合、聚类 之类的词。
| 阶段 | 要做什么 |
|---|---|
| 明确问题 | 预测什么?标签从哪来?一条样本代表什么? |
| 探索性分析 EDA | 看分布、缺失比例、异常值、类别是否平衡 |
| 清洗 | 缺失值处理、去重、异常值修正 |
| 特征工程 | 类别编码、数值缩放、构造 / 筛选特征 |
| 切分数据 | 先留测试集(train_test_split),再谈其他 |
| 训练 | 从简单模型开始 fit,先跑通再变强 |
| 评估 | 测试集 + 交叉验证;按业务选对指标 |
| 调参 | GridSearchCV / RandomizedSearchCV 穷举或采样 |
| 部署监控 | 保存模型上线,监控数据漂移与效果衰减 |
| 算法 | 一句话定位 |
|---|---|
| 线性回归 | 回归的第一基线,系数可解释 |
| 逻辑回归 | 分类的第一基线,输出概率,快而稳 |
| KNN | 看 K 个最近邻投票,直观但预测慢 |
| 朴素贝叶斯 | 文本分类的传统强项,训练飞快 |
| 决策树 | 可画图解释,但单棵树容易过拟合 |
| 随机森林 | 多棵树投票(bagging),默认强基线 |
| 梯度提升 XGBoost / LightGBM | 表格数据竞赛冠军常客,梯度提升家族 |
| SVM | 小样本高维数据强,核技巧扩到非线性 |
| K-Means | 无监督聚类:指定 K,按距离分群 |
| PCA | 无监督降维:压缩特征、可视化 |
| 指标 | 含义与适用 |
|---|---|
| 准确率 Accuracy | 全对比例;类别不平衡时会骗人 |
| 精确率 Precision | 预测为正里真正对的比例;误报代价高时看它 |
| 召回率 Recall | 真实为正被抓住的比例;漏报代价高时看它 |
| F1 | 精确率与召回率的调和平均,二者兼顾 |
| ROC-AUC | 与阈值无关的排序能力,比较模型整体好坏 |
| 混淆矩阵 | 四象限看清「错成什么」的原始明细 |
| RMSE | 回归误差(均方根),大误差罚得重 |
| MAE | 回归平均绝对误差,对异常值更鲁棒 |
| R² | 回归解释了多少方差,越接近 1 越好 |
| 交叉验证均值 ± 标准差 | 比单次切分可信,还能看出稳定性 |
| 术语 | 解释 |
|---|---|
| 特征 Feature | 描述样本的一个输入变量,表格里的一列 |
| 标签 Label | 要预测的目标,表格里的「答案」列 |
| 样本 Sample | 一条数据,表格里的一行 |
| 训练集 / 测试集 | 学规则用的 / 最后考试用的,不能混 |
| 验证集 | 调参用的那部分;不参加最终训练 |
| 超参数 Hyperparameter | 训练前由人定的旋钮(树深、学习率) |
| 参数 Parameter | 训练中学出来的内部数值(权重、系数) |
| 泛化 Generalization | 在没见过的数据上的表现,唯一重要的目标 |
| 过拟合 Overfitting | 背题:训练分高测试分低 |
| 正则化 Regularization | 给模型复杂度罚分,压住过拟合 |
| 数据泄漏 Leakage | 考试信息混进了训练过程,分数虚高 |
| 基线 Baseline | 先跑通的简单模型,任何新模型都要打赢它 |
没有匹配的条目。换个词试试,比如「召回」「聚类」「泄漏」。
06
完整实战:用内置数据集走完八步工作流
下面用 scikit-learn 内置的手写数字数据集,把「切分 → 基线 → 调参 → 终评 → 保存」完整走一遍。代码可整体复制运行,只依赖 scikit-learn 和 joblib(sklearn 自带)。
第一步:加载数据并切分
import numpy as np from sklearn.datasets import load_digits from sklearn.model_selection import train_test_split, cross_val_score, GridSearchCV from sklearn.svm import SVC from sklearn.linear_model import LogisticRegression from sklearn.pipeline import make_pipeline from sklearn.preprocessing import StandardScaler from sklearn.metrics import classification_report, confusion_matrix import joblib # 1797 个样本,64 个特征(8x8 像素),10 类数字 X, y = load_digits(return_X_y=True) print(X.shape, y.shape) # (1797, 64) (1797,) X_tr, X_te, y_tr, y_te = train_test_split( X, y, test_size=0.25, random_state=42, stratify=y) # 分层抽样
第二步:基线模型 + 交叉验证
# 规范写法:缩放器包进 Pipeline,随模型一起交叉验证,杜绝泄漏 base = make_pipeline(StandardScaler(), LogisticRegression(max_iter=1000)) scores = cross_val_score(base, X_tr, y_tr, cv=5) print(scores.mean().round(4), scores.std().round(4)) # 5 折平均约 0.97 —— 这就是必须打败的基线
第三步:网格搜索调参
param_grid = {
"C": [0.1, 1, 10], # 正则强度,越大越信数据
"gamma": [0.0001, 0.001, 0.01], # RBF 核的影响半径
}
search = GridSearchCV(SVC(), param_grid, cv=5, n_jobs=-1)
search.fit(X_tr, y_tr) # 3 x 3 = 9 组参数 x 5 折 = 45 次训练
print(search.best_params_)
print(search.best_score_.round(4)) # 交叉验证下的最佳成绩,约 0.99
第四步:测试集终评与保存模型
best = search.best_estimator_ # 已在全量训练集上重新拟合 pred = best.predict(X_te) print(best.score(X_te, y_te)) # 测试集分数:全程只算这一次 print(classification_report(y_te, pred)) # 每一类的精确率 / 召回率 / F1 print(confusion_matrix(y_te, pred)) # 哪些数字容易被认错成哪些 joblib.dump(best, "digits_svc.joblib") # 保存模型 model = joblib.load("digits_svc.joblib") print(model.predict(X_te[:3])) # 加载后直接预测新样本
{'C': 10, 'gamma': 0.001},交叉验证 0.9918;测试集 0.9889。混淆矩阵里最容易混的是 8、9 和 5——符合人眼直觉。param_grid 里那一小段。真正的项目无非是在这条骨架上,把特征工程和指标选择做得更细。07
避坑:四个让分数不可信的经典错误
坑一:数据泄漏——「先标准化后切分」
如果在切分之前对全量数据做标准化、特征选择或填充,测试集的统计信息就混进了训练过程——分数虚高,上线就跌。正确顺序是把预处理装进 Pipeline,让缩放只在训练折内 fit:
# 错:全量数据先标准化,再切分 —— 测试集信息泄漏进训练 X_scaled = StandardScaler().fit_transform(X) X_tr, X_te = train_test_split(X_scaled) # 对:把预处理放进 Pipeline,交给交叉验证分折处理 pipe = make_pipeline(StandardScaler(), LogisticRegression()) cross_val_score(pipe, X, y, cv=5)
坑二:类别不平衡时只看准确率
欺诈检测里 99% 的交易是正常的。一个「全猜正常」的模型准确率 99%,召回率 0%——业务价值为零。凡是不平衡数据,先看混淆矩阵,主指标选少数类的召回率或 F1,而不是 accuracy。
print(np.bincount(y)) 或 y.value_counts(normalize=True)。少数类占比低于两三成,就按下平衡问题对待(分层抽样、class_weight、过采样等)。坑三:在测试集上反复调参
测试集每被「看」一次,就泄一次密。调十轮模型都朝测试集分数优化,它就变成了验证集,最终汇报的数字不再可信。纪律是:调参只用交叉验证,测试集终评只做一次;数据充裕时干脆切成训练 / 验证 / 测试三份。
坑四:一上来就上深度学习
表格数据 + 几万样本,梯度提升树通常比神经网络更强、更快、更可解释,还不需要 GPU。深度学习的主场是图像、语音、文本等非结构化数据。先用简单模型建立基线,再决定要不要上重武器——基线打不赢的复杂模型,不值得上线。
1. 数据是一张表格吗? 是 → 线性模型 / 树模型起步(sklearn) 2. 是图像、语音、文本这类数据吗? 是 → 卷积 / Transformer(深度学习) 3. 样本量 < 1 万,且要能解释? 是 → 逻辑回归 + 特征工程,别上重武器
08
进阶方向与资源
概念立住之后,按「动手 → 课程 → 数据」三路推进,比按顺序啃书有效得多。
- scikit-learn 用户指南——经典 ML 最值得通读的官方文档,每章带代码。
- Andrew Ng《Machine Learning Specialization》(Coursera)——最经典的入门课,概念讲解的地基。
- Kaggle Learn——免费短课(Intro to ML、Feature Engineering),边学边在 Notebook 里练。
- Kaggle Datasets——从入门玩具到百万行业务数据的数据集仓库,配 Notebook 直接练手。
- UCI 机器学习数据集仓库——经典公开数据集的老巢,找中小规模练手数据先来这里。
- Google Machine Learning Crash Course——十几小时的速成课,配练习,概念复习很好用。
- 书:《Hands-On Machine Learning with Scikit-Learn, Keras & TensorFlow》(Aurélien Géron)——从经典 ML 一路写到深度学习的实操圣经。
09
收尾:照着勾一遍
0 / 5