数据洗干净了、图表也漂亮了,然后呢?第 12 章是本书的「毕业典礼」:把 pandas 的世界接到统计建模与机器学习的世界。这一章不教机器学习本身,而是教那座桥怎么过。
🌉 第一课:模型吃的是 NumPy 数组
所有主流建模库(sklearn/statsmodels)的接口都围绕 NumPy 数组设计。所以从 DataFrame 出发的第一步永远是「提取特征矩阵和目标向量」:
data = pd.DataFrame(rng.standard_normal((100, 4)), columns=list("ABCD"))
data["y"] = data["A"] + data["B"] * 2 + rng.standard_normal(100)
X = data[["A", "B", "C", "D"]].to_numpy() # 特征矩阵 (100, 4)
y = data["y"].to_numpy() # 目标向量 (100,)
高维/大数据集的行选择要会 data.take(idx)——从数组风格的索引批量取行,速度接近 NumPy。
📐 Patsy:用公式描述模型
Patsy 允许你用数学公式语言描述模型,自动生成设计矩阵——R 语言风格的体验:
import patsy
y, X = patsy.dmatrices("y ~ A + B + A:B + I(A**2)", data, return_type="dataframe")
# y 目标向量
# X 设计矩阵:Intercept, A, B, A:B 交互项, I(A^2) 非线性项
几个必须懂的语法糖:
A:B交互项;I(A**2)用 I() 包住任意 Python 表达式;C(category):把分类变量自动 one-hot 编码,并处理基准水平(避免完全共线);y ~ .用全部其余列;y ~ A + C(cat) - 1去掉截距。
# 分类变量演示:三个类别自动展开成两列哑变量
y, X = patsy.dmatrices("y ~ C(category)", data, return_type="dataframe")
build_design_matrices 还能把新数据按训练集同样的规则编码——保证预测时的列对齐,这是初学者最容易翻车的地方,Patsy 帮你兜住了。
📊 statsmodels:统计学家的回归
statsmodels 的气质是「解释优先」:它要回答「哪些变量重要、有多重要」。
import statsmodels.api as sm
import statsmodels.formula.api as smf
# 公式语法一条龙
model = smf.ols("y ~ A + B + C(category)", data=data).fit()
model.params # 系数
model.summary() # 完整统计报告:R²、p 值、置信区间……
时间序列模型也在同一个门里:
init_x = 4; values = [init_x, init_x] # AR(2) 过程模拟
N = 1000
b0, b1, b2 = 0.8, -0.4, 0.25
for i in range(N):
values.append(b0 + b1*values[-1] + b2*values[-2] + noise)
MAXLAGS = 5
model = sm.AR(values[:200]).fit(maxlags=MAXLAGS) # 自回归
model.params # 估计出的自回归系数
解读要点:看 p 值(P>|t|)判断变量是否显著,看 R² 判断解释力,看系数符号方向——这是与「只管预测准」的机器学习最大的分工。
🤖 scikit-learn:工程师的建模
sklearn 的气质是「预测优先」,接口统一到可怕:任何模型都是 fit → predict 两步。
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
model = LogisticRegression(C=1.0) # C 越小正则化越强
model.fit(X_train, y_train) # 训练
model.predict(X_test) # 预测
model.predict_proba(X_test) # 概率输出
# 交叉验证一行:5 折,看稳定性
scores = cross_val_score(model, X, y, cv=5)
书里的示例用经典的泰坦尼克数据走完整流程:构造数值特征(年龄、pclass)→ 简单填充缺失 → LogisticRegression → 交叉验证打分。想强调的一点是:sklearn 不吃 NaN 也不吃字符串,所以第 7 章的清洗(fillna、get_dummies)就是为这一刻准备的。
📌 本章小结:模型吃 NumPy 数组,
to_numpy()是起点;Patsy 公式语法自动处理交互项与分类变量编码;statsmodels 管解释(p 值/R²),scikit-learn 管预测(fit/predict);建模前的清洗质量决定建模上限——第 7 章的功夫在这里兑现。