Foundations Review: Building the Knowledge Base for Intermediate ML Learners
如果你已经翻开了这本书,大概率已经写过至少一个线性回归模型、用sklearn调过几次分类器,甚至可能在Kaggle上提交过几次入门赛的预测结果。你或许已经习惯了用`model.fit(X,y)`一行代码训练模型,用`model.predict(X_test)`拿到预测结果,再用`accuracy_score`算个准确率就提交结果——但偶尔遇到效果不好的模型,你可能会疑惑:为什么调参之后效果反而下降了?为什么同样的模型在别人的数据集上表现这么好,在我的数据上就不行?为什么有些场景下准确率99%的模型反而不能用?
这些问题的本质,往往不是模型选得不好,而是你的基础认知里存在一些被忽略的漏洞:比如你以为你会用Pandas,但链式索引的警告你从来没管过,导致数据处理的时候 silently 修改了原始数据;你以为你懂方差,但不知道样本方差和总体方差的区别,导致特征缩放的时候用了错误的公式;你以为你懂准确率,但在不平衡数据集上用准确率选模型,选出来的根本是个“永远预测多数类”的无效模型。这一章的目的,就是帮你把这些零散、有漏洞的基础知识补全,构建一个完整的知识地基,避免你在后续学习线性回归、决策树、集成方法的时候,因为基础问题卡壳,甚至得出错误的结论。
---
1.1 Python数据处理三件套:中级用法与常见坑点
绝大多数机器学习工程师的日常工作里,80%的时间都在做数据清洗和预处理,而NumPy、Pandas、Matplotlib就是完成这些工作的核心工具。很多入门教程只会讲最基础的用法,但中级读者往往会在实际项目中踩一些“看起来很小但影响极大”的坑,这一节我们会聚焦这些容易被忽略的细节。
1.1.1 NumPy:不止是数组计算,更是向量化思维的核心
NumPy的核心是`ndarray`对象,它的优势不是“能存数组”,而是基于C语言实现的向量化运算,比Python原生循环快10~100倍,这是所有高效数据处理的基础。除了基础的数组创建、索引、运算之外,中级读者必须掌握三个核心知识点:
1. 广播机制:不是魔法,是可预测的规则
很多读者会用广播,但不知道它的底层规则,导致遇到形状不匹配的数组时要么报错,要么得到不符合预期的结果。广播的核心规则只有一条:两个数组的维度从后往前逐个比较,如果对应维度的大小相等,或者其中一个为1,就可以进行广播,最终结果的形状是两个数组形状从后往前逐元素取最大值。
我们用具体的例子来理解: ```python import numpy as np
示例1:二维数组和二维数组的广播
a = np.array([[1, 2, 3], [4, 5, 6]]) # 形状 (2, 3) b = np.array([[10], [20]]) # 形状 (2, 1)
广播过程:从后往前比较维度
第2维:3 vs 1 → 1可以广播到3
第1维:2 vs 2 → 相等
最终结果形状:(2, 3)
c = a + b print(c)
输出:
[[11 12 13]
[24 25 26]]
```
再来看一个更复杂的例子,三维数组和二维数组的广播: ```python
示例2:三维数组和二维数组的广播
d = np.random.rand(3, 1, 4) # 形状 (3, 1, 4) e = np.random.rand(1, 5, 4) # 形状 (1, 5, 4)
广播过程:从后往前比较维度
第3维:4 vs 4 → 相等
第2维:1 vs 5 → 1可以广播到5
第1维:3 vs 1 → 1可以广播到3
最终结果形状:(3, 5, 4)
f = d + e print(f.shape) # 输出 (3, 5, 4) ```
> 💡 电子版侧边栏:如果你对广播的规则还是感到困惑,可以点击[这里](https://numpy.org/doc/stable/user/basics.broadcasting.html)查看NumPy官方文档的动画演示,或者观看配套的5分钟短视频讲解。
广播的价值不仅是简化代码,更重要的是避免显式的循环,大幅提升运算效率。比如我们需要给每一行的数据加上不同的偏置,用广播只需要一行代码,而用Python循环需要写两层for,速度差距在数据量达到万级时会非常明显。
2. 花式索引与布尔索引:高效筛选数据的核心
除了基础的切片索引,NumPy的花式索引和布尔索引是处理筛选、排序任务的利器: ```python #