第12章封面

数据洗干净了、图表也漂亮了,然后呢?第 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 的气质是「预测优先」,接口统一到可怕:任何模型都是 fitpredict 两步。

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 章的功夫在这里兑现。