简介这是一套基于Jupyter Notebook的机器学习入门实践资源面向希望从零掌握常见算法并落地代码的Python开发者与数据科学初学者。内容覆盖数据预处理、线性回归、逻辑回归、决策树、随机森林、SVM、K-Means聚类以及模型评估与参数调优配有房价预测、贷款违约、市场细分、手写数字识别等案例帮助读者理解算法原理并在Notebook中逐步复现完整流程。资源共25个文件以10个Markdown说明文档、8个Jupyter Notebook代码、3个CSV数据集为主另含Python脚本与配置文件压缩包仅2.97MB轻量易下载结构按模型模块归类便于按需查阅。已有2044人学习适合作为课内实验或自学实战的参照资料。通过学习读者可以获得从数据清洗、特征工程到模型训练与评估的完整思路以及可直接运行的示例代码和配套数据快速搭建自己的机器学习项目。1. 为什么应该在 Jupyter Notebook 里学习机器学习基本模型算法Jupyter Notebook 常被当成高级记事本整段脚本丢进单元格运行和直接跑 Python 文件没区别。真正有用的用法是把数据形状、模型参数、输出结果拆成独立可改的单元。机器学习基本模型算法的难点在参数敏感性决策树不加 max_depth训练集接近 100%、测试集下滑KNN 把 n_neighbors 从 1 改成 5决策边界立刻变平滑。这种直觉靠背公式很难建立在 Jupyter 里边改边看图却很自然。接下来按“搭环境、认算法、跑三个模型、做一个附加案例”的顺序展开新手能逐步复现熟手可直接看后文的参数边界和踩坑点。2. 在 Jupyter Notebook 搭建机器学习算法环境安装、镜像与算法选型2.1 用 Miniconda 在本地跑通 Jupyter Notebook 的最小命令“机器学习 python 环境配置”是入门遇到的第一个坎常见问题是系统 Python 里装着老版本 numpy再 pip install scikit-learn 时把整个环境弄崩。我一般用 Miniconda 把机器学习环境隔离出来后续即使模型包升级失败删掉这个环境重来即可。终端执行conda create -n mlp python3.11 -y conda activate mlp pip install jupyterlab notebook numpy pandas matplotlib seaborn scikit-learn python -m ipykernel install --user --name mlp第一行创建独立环境 mlp并固定 Python 3.11避免依赖随系统更新漂移第二行激活环境后续所有包都装进 mlp 里第三行一次装齐 Jupyter 和数据科学常用库其中 jupyterlab 负责网页端交互notebook 是经典界面scikit-learn 提供本次要用到的大部分机器学习模型算法第四行把当前环境注册为 Jupyter 内核。注册完启动即可jupyter notebook浏览器打开后新建 Notebook 时选择 mlp 内核。如果下载慢把 pip 临时指向国内镜像源再重复安装命令即可不建议在系统 Python 里硬装。这个流程解决的是“环境隔离”和“内核识别”两个问题。之后每次换机器只需重跑这几行命令。实际使用中如果从 conda 某环境切回 base 后找不到内核通常不是安装失败而是内核注册信息没刷新这时运行jupyter kernelspec list看看当前可用名称再判断。2.2 机器学习基本模型算法有哪些一张表看清分类与回归机器学习期末复习时最常被问到的就是“有哪些基本模型”很多教材喜欢按李宏毅的课程或周志华《机器学习》书里的顺序排但落到代码层面其实用一张表就能说清模型监督类型典型任务适合场景可解释性线性回归回归房价、销量预测特征与目标接近线性高逻辑回归分类点击率、患病概率二分类基线高决策树分类/回归规则提取、风控小样本且需要解释很高KNN分类/回归推荐、图像分类低维、样本量适中中朴素贝叶斯分类文本分类高维稀疏特征中SVM分类/回归文本、图像小样本中等样本、特征稠密低这些模型的差别不在准确率而在归纳偏好线性模型假设类别边界接近线性KNN 假设相近的样本有相近输出决策树则用一组特征阈值把样本逐步切开。没有谁绝对最优scikit-learn 自带数据集里很多任务用逻辑回归就能跑出不错的基线。学习时不要在“哪个算法更强”上纠结先弄清楚各自的假设适不适合当前数据。2.3 算法选型的三条经验选型可以按三条线记比背算法流程图更快落地从简单开始回归问题先跑线性回归分类问题先跑逻辑回归把它们的指标当作基线。基线差到不能看再换复杂模型才有意义。看解释需求业务要求说清“为什么判负”优先决策树因为可以输出路径规则如果只是预测概率SVM 或集成模型放在后期再试。数据规模决定选择样本几千以内决策树、KNN、逻辑回归足够到几十万上百万样本KNN 因每条样本都要算距离延迟明显上升线性模型和树模型更合适。在 Jupyter 里落实这三条经验就是给每个模型开一个单元格用同一个cross_val_score跑一遍比较均值和标准差。理解了单棵树之后再看随机森林、梯度提升树这些“多个决策树组合”的思路会轻松得多。3. 用 Jupyter Notebook 跑通三个机器学习基本模型算法线性回归、KNN 与决策树下面的代码按“一个模型一组单元格”组织数据处理、模型训练、结果可视化分区放不要把所有代码塞进一个格子里否则又回到“跑大脚本”的老路。3.1 线性回归先看系数再谈 R2先用 scikit-learn 内置的糖尿病数据集跑一个多元线性回归from sklearn.datasets import load_diabetes from sklearn.linear_model import LinearRegression from sklearn.model_selection import train_test_split import pandas as pd diabetes load_diabetes() X pd.DataFrame(diabetes.data, columnsdiabetes.feature_names) y pd.Series(diabetes.target, nametarget) 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.coef_) print(截距:, round(model.intercept_, 4)) print(R2:, round(model.score(X_test, y_test), 4))load_diabetes()读取内置的 442 条数据无需联网下载train_test_split按 8:2 切分random_state42保证每次运行结果一致方便复现和对比。model.coef_是 10 个特征的系数正数代表该特征越大目标值越高负数相反这是线性回归最直接的可解释输出。score返回 R2表示模型解释目标值方差的比例这个数据集上普通线性回归得到 0.4 到 0.5 是正常水平不用因为不是 0.9 就怀疑代码出错。跑完后建议做一个实验在训练前加一步StandardScaler标准化再跑一遍同一个模型。线性回归对特征尺度不敏感R2 几乎不变这个结论能帮助你理解后来的 KNN 和 SVM 为什么要标准化而树模型不需要。3.2 KNN 分类器调 n_neighbors 看到过拟合KNN 是所有机器学习基本模型算法里最没有“训练”过程的它把训练样本直接存下来预测新样本时算它与所有记忆样本的距离再投票。唯一关键参数是邻居数n_neighbors在 Jupyter 里最适合用循环看变化from sklearn.datasets import load_iris from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import cross_val_score X, y load_iris(return_X_yTrue) for k in [1, 3, 5, 7, 10, 15]: knn KNeighborsClassifier(n_neighborsk) scores cross_val_score(knn, X, y, cv5) print(fk{k:2d} acc{scores.mean():.4f} std{scores.std():.4f})cross_val_score把数据分成 5 份每份轮流做验证集得到 5 个准确率后取均值和标准差比单次train_test_split更可信。运行输出通常能看到k1 时准确率不一定最高且标准差偏大k 到 5 到 7 附近达到峰值继续增大后开始下滑。k1 的决策区域完全贴着训练数据属于典型过拟合k15 又因为决策边界太粗糙而欠拟合。KNeighborsClassifier还有一个值得对比的参数weights默认uniform表示所有邻居一票平等改成distance后距离越近权重越大通常会带来一两个百分点的变化但也更容易受局部噪声影响。3.3 决策树max_depth 与预剪枝决策树是可解释性最高的分类器训练后能输出一条明确的“特征 阈值”路径业务方接受度远高于 SVM。但它的过拟合风险也最明显不加限制时树会一直长到每个叶子只含一条样本训练集接近满分。Jupyter 里可以直接观察这个变化from sklearn.datasets import load_iris from sklearn.tree import DecisionTreeClassifier, plot_tree import matplotlib.pyplot as plt iris load_iris() model DecisionTreeClassifier(max_depth3, min_samples_leaf5, random_state0) model.fit(iris.data, iris.target) plt.figure(figsize(12, 6)) plot_tree(model, filledTrue, feature_namesiris.feature_names, class_namesiris.target_names) plt.show()max_depth3限制树的层数min_samples_leaf5要求每个叶子至少包含 5 个样本这两个参数组合起来就是“预剪枝”的常用手段。很多文章把max_depth直接叫剪枝严格说它只是限制高度真正剪枝还要结合叶子样本量、基尼增益阈值等条件。把max_depth从 2 改到 8 逐个跑一遍训练集准确率递增、测试集先升后降的过程非常直观。plot_tree输出的树结构可以直接截图放进周报或课程报告叶子颜色深浅代表类别概率。DecisionTreeClassifier的criterion参数默认gini改成entropy后树的形态可能不同但在这个数据集上效果差别很小。入门阶段固定一个标准重点研究max_depth和min_samples_leaf就够用。4. 附加案例用乳腺癌公开数据集把机器学习算法从 EDA 串到调参前面对三个模型做了单独演示这一节放进同一个附加案例完整走一遍读数据、EDA、建模比较、调参。数据集用load_breast_cancer属于 scikit-learn 内置的公开数据不需要额外下载适合直接复现。4.1 建模前先看数据缺失值、数值范围和类别分布from sklearn.datasets import load_breast_cancer import pandas as pd import seaborn as sns import matplotlib.pyplot as plt data load_breast_cancer() df pd.DataFrame(data.data, columnsdata.feature_names) df[target] data.target print(df.shape) print(df.isnull().sum().sum()) print(df.describe().T[[mean, min, max]]) print(df[target].value_counts()) sns.countplot(xtarget, datadf) plt.xticks([0, 1], data.target_names) plt.show()输出要点样本 569 个、特征 30 个缺失值数量为 0正负样本比例约 1.3:1属于比较均衡的二分类。更值得看的是describe里的 min 和 maxmean radius范围在 7 到 30mean concavity可能在 0 到 0.5量纲差距接近两个数量级。这一观察直接决定了后面必须做标准化。很多入门教程跳过这步直接 fitNotebook 里不会报错但 KNN 和 SVM 这类基于距离的模型结果会明显偏移。4.2 用 Pipeline 把标准化放进交叉验证避免数据泄漏常见错误是“先标准化全量数据再切分训练测试集”。标准化器在全量数据上算均值方差等于把测试集信息代入训练过程验证指标会偏乐观。正确做法是把标准化放进交叉验证的每一折内部from sklearn.model_selection import cross_val_score from sklearn.pipeline import make_pipeline from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression from sklearn.neighbors import KNeighborsClassifier from sklearn.tree import DecisionTreeClassifier X df.drop(columnstarget) y df[target] models { logistic: LogisticRegression(max_iter2000), knn: KNeighborsClassifier(n_neighbors5), tree: DecisionTreeClassifier(max_depth3, random_state0), } for name, clf in models.items(): pipe make_pipeline(StandardScaler(), clf) scores cross_val_score(pipe, X, y, cv5, scoringaccuracy) print(f{name:8s} acc{scores.mean():.4f} std{scores.std():.4f})make_pipeline(StandardScaler(), clf)把标准化和模型包成一个整体交叉验证切出的每个训练折都先拟合 scaler再用同一组均值方差去变换对应的验证折杜绝信息泄漏。三个模型跑完后逻辑回归和 KNN 标准化后通常接近决策树则不论是否标准化差异都小这与树模型按阈值切分、不依赖距离度量一致。准确率对类别不平衡不够敏感但这个案例样本均衡可以先用 accuracy 做横向比较之后再补recall或roc_auc。4.3 用 GridSearchCV 同时调两个超参数交叉验证发现“标准化 KNN”值得继续优化后进入参数搜索。新手最容易用双重 for 循环手动调参能跑但代码冗长且无法自动比较。scikit-learn 的GridSearchCV更适合from sklearn.model_selection import GridSearchCV from sklearn.neighbors import KNeighborsClassifier pipe make_pipeline(StandardScaler(), KNeighborsClassifier()) params { kneighborsclassifier__n_neighbors: [3, 5, 7, 10], kneighborsclassifier__weights: [uniform, distance], } grid GridSearchCV(pipe, params, cv5, scoringaccuracy) grid.fit(X, y) print(best params:, grid.best_params_) print(best score:, round(grid.best_score_, 4)) print(grid.cv_results_[mean_test_score])params的 key 用双下划线__连接左边是子估计器在管道中的名字右边才是它的参数名这是 Pipeline 的固定语法。GridSearchCV对每组参数组合执行 5 折交叉验证这里共 4×2×540 次模型拟合在 569 条样本上几秒内跑完。best_score_是调参后的平均准确率mean_test_score输出各组参数明细方便看出哪一组波动最大。调完后用同一个流程换LogisticRegression(C0.1)再跑一次你会发现逻辑回归对 C 的敏感度通常低于 KNN 对 n_neighbors 的敏感度这个结论在实际项目中很有参考价值。5. 两个留在最后的实操技巧重复验证与 Jupyter Notebook 无法运行排查案例跑通不意味着流程结束还要养成两个习惯不要用单次切分结果汇报报错时先分清是环境问题还是模型代码问题。5.1 用重复交叉验证代替单次结果交叉验证比单次切分稳定但它仍有随机成分。换一个random_state准确率可能从 90.4% 变成 91.1%。我一般用重复实验看波动import numpy as np from sklearn.model_selection import cross_val_score from sklearn.linear_model import LogisticRegression accs [ cross_val_score(LogisticRegression(max_iter2000), X, y, cv5).mean() for _ in range(10) ] print(mean:, round(np.mean(accs), 4)) print(std:, round(np.std(accs), 4))如果标准差超过 0.02说明模型对这个数据集的划分方式敏感报告里应同时给出均值和标准差而不是只写“准确率 91%”。这个习惯比调出 0.5 个百分点有意义得多。5.2 Jupyter Notebook 无法运行的三步排查“jupyter notebook 无法运行”大多能在三步内定位。第一步看报错位置如果浏览器能打开执行代码时报Kernel Restarting基本是 Python 环境包冲突处理方式是新建 conda 环境重装一套依赖而不是在原环境里继续 pip install。第二步看端口启动时提示端口占用改用jupyter notebook --no-browser --port8899。第三步看内核切换 conda 环境后 Kernel 列表找不到新环境执行python -m ipykernel install --user --name mlp重新注册再用jupyter kernelspec list确认。还有一个易踩的坑Jupyter 里运行的并非当前激活环境可以在单元格里执行import sys; sys.executable看打印出的 Python 路径路径不对就重新选择内核。排查掉这些之后余下最高概率的报错是ValueError: Input contains NaN那就不是环境问题该回头检查数据清洗了。提示写机器学习代码时每改动一个参数就重新运行一次当前单元格看到输出后再改下一个这是 Jupyter Notebook 比普通脚本更适合算法实验的根本原因。本文还有配套的精品资源点击获取