什么是 dmatrices?
dmatrices 是 patsy 库中的一个核心函数,它的主要作用是根据一个公式字符串,自动地将你的数据(通常是 Pandas DataFrame)转换成 NumPy 数组或稀疏矩阵,这些格式可以直接被各种统计建模库(如 statsmodels 和 scikit-learn)使用。

公式 是一种简洁的、类似 R 语言的语法,用来描述变量之间的关系。dmatrices 会解析这个公式,并为你创建两个关键的矩阵:
- 设计矩阵:通常称为
X,包含了所有的自变量(特征)。dmatrices会自动处理分类变量的虚拟变量编码、变量间的交互作用等。 - 响应向量:通常称为
y,包含了因变量(目标值)。
函数名 dmatrices 是 "design matrices" 的缩写,它返回两个矩阵,这正是它与 dmatrix(只返回一个设计矩阵)的主要区别。
为什么使用 dmatrices?
相比于手动创建 X 和 y,使用 dmatrices 有以下巨大优势:
- 简洁性:用一行公式就能完成复杂的特征工程,代码可读性极高。
- 自动化处理:
- 分类变量:自动将字符串类型的分类变量转换为虚拟变量/哑变量,一个有 "男"、"女" 两类别的列,会自动变成两列(如
gender[T.male],gender[T.female]),并避免多重共线性问题(通常会默认省略一个类别作为基准)。 - 交互项:轻松创建变量间的交互项,
age:gender。 - 多项式特征:可以方便地创建多项式特征,如
np.power(age, 2)可以写成I(age**2)。
- 分类变量:自动将字符串类型的分类变量转换为虚拟变量/哑变量,一个有 "男"、"女" 两类别的列,会自动变成两列(如
- 与统计模型无缝集成:
statsmodels库的线性回归模型(如OLS、GLM)可以直接接受dmatrices的输出,使得建模流程非常顺畅。 - 避免错误:手动处理数据时,容易忘记处理分类变量或创建截距项,
dmatrices能帮你自动完成这些步骤。
核心语法
dmatrices 的基本语法如下:

from patsy import dmatrices
# y, X = dmatrices("formula_string", data, return_type='dataframe')
参数说明:
"formula_string": 一个描述模型的公式字符串。- (tilde) 是分隔符,左边是因变量
y,右边是自变量x。 - 表示添加一个变量。
- 表示创建交互项。
- 表示包含所有主效应和它们的交互项(
a*b等价于a + b + a:b)。 C():显式地将一个变量视为分类变量,虽然patsy通常能自动识别,但在必要时使用可以增加代码的明确性。I():表示“作为-is”,用来执行算术运算,而不是公式的特殊含义。I(x**2)创建x的平方项。
- (tilde) 是分隔符,左边是因变量
data: 一个 Pandas DataFrame,包含了公式中所有用到的变量。return_type(可选): 返回结果的类型。'dataframe'(默认): 返回 Pandas DataFrame/Series,列名非常有用,便于后续分析。'matrix': 返回 NumPy 数组。'dataframeSparse'或'sparse': 返回稀疏矩阵,当数据量很大且稀疏时非常有用。
返回值:
它返回一个元组 (y, X):
y: 设计好的响应变量矩阵/向量。X: 设计好的自变量矩阵(通常包含一个名为Intercept的截距列)。
实例演示
让我们通过一个完整的例子来理解 dmatrices 的强大之处。

准备数据
我们创建一个包含数值型和分类型变量的 Pandas DataFrame。
import pandas as pd
import numpy as np
# 创建示例数据
data = {
'salary': [50000, 60000, 80000, 75000, 90000, 110000, 95000, 105000, 45000, 55000],
'experience': [2, 3, 5, 4, 6, 8, 7, 9, 1, 2],
'gender': ['Male', 'Female', 'Male', 'Female', 'Male', 'Female', 'Male', 'Female', 'Female', 'Male'],
'education_level': ['Bachelor', 'Master', 'Bachelor', 'PhD', 'Master', 'PhD', 'PhD', 'Master', 'Bachelor', 'Bachelor']
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)
使用 dmatrices 创建模型矩阵
假设我们想用 salary 作为因变量,experience, gender, 和 education_level 作为自变量。
from patsy import dmatrices
# 定义公式
formula = "salary ~ experience + gender + education_level"
# 使用 dmatrices 创建设计矩阵
y, X = dmatrices(formula, data=df, return_type='dataframe')
print("\n因变量 y:")
print(y)
print("\n自变量 X:")
print(X)
输出结果分析:
因变量 y:
salary
0 50000
1 60000
2 80000
3 75000
4 90000
5 110000
6 95000
7 105000
8 45000
9 55000
y 就是一个包含 salary 列的 DataFrame。
自变量 X:
Intercept experience gender[T.Male] education_level[T.Master] education_level[T.PhD]
0 1.0 2.0 1.0 0.0 0.0
1 1.0 3.0 0.0 1.0 0.0
2 1.0 5.0 1.0 0.0 0.0
3 1.0 4.0 0.0 0.0 1.0
4 1.0 6.0 1.0 1.0 0.0
5 1.0 8.0 0.0 0.0 1.0
6 1.0 7.0 1.0 0.0 1.0
7 1.0 9.0 0.0 1.0 0.0
8 1.0 1.0 0.0 0.0 0.0
9 1.0 2.0 1.0 0.0 0.0
观察 X 矩阵,dmatrices 自动为我们做了以下事情:
- 截距项:自动添加了一列名为
Intercept的列,值全为 1,这是线性回归的默认设置。 - 数值变量:
experience列被原样保留。 - 分类变量处理:
gender有两个类别:"Male" 和 "Female"。dmatrices创建了一个虚拟变量gender[T.Male],当性别为 "Male" 时,值为 1;为 "Female" 时,值为 0,这里 "Female" 是基准(或参考)类别。education_level有三个类别:"Bachelor", "Master", "PhD",它创建了两个虚拟变量education_level[T.Master]和education_level[T.PhD],基准类别是 "Bachelor",当学历为 "Master" 时,education_level[T.Master]为 1;为 "PhD" 时,education_level[T.PhD]为 1。
与 statsmodels 结合进行回归分析
我们可以直接将 y 和 X 传递给 statsmodels 的 OLS (普通最小二乘法) 模型。
import statsmodels.api as sm
# statsmodels 默认不包含截距项,因为我们已经在 X 中有了,所以需要设置 hasconst=True
# 或者,我们可以从 X 中移除截距项,然后在模型中添加它,这里我们保留它。
model = sm.OLS(y, X)
# 拟合模型
results = model.fit()
# 打印模型摘要
print("\n回归模型摘要:")
print(results.summary())
解读:**
- Intercept: 截距项的系数,当所有自变量为0时的预测值。
- experience: 工作经验的系数,表示每增加一年经验,薪资的变化量。
- gender[T.Male]: 性别为男性相对于女性(基准)的薪资差异。
- education_level[T.Master]: 拥有硕士学位相对于学士学位(基准)的薪资差异。
- education_level[T.PhD]: 拥有博士学位相对于学士学位(基准)的薪资差异。
- R-squared: 模型的拟合优度。
常用公式技巧
| 公式 | 描述 | 示例 |
|---|---|---|
y ~ x1 + x2 |
基本线性模型,包含 x1 和 x2 两个自变量。 |
salary ~ experience + gender |
y ~ x1 * x2 |
包含 x1, x2 以及它们的交互项 x1:x2。 |
salary ~ experience * gender (等价于 experience + gender + experience:gender) |
y ~ (x1 + x2)**2 |
与 y ~ x1 * x2 相同,包含所有主效应和两两交互项。 |
salary ~ (experience + gender)**2 |
y ~ C(x) |
强制将变量 x 视为分类变量。 |
salary ~ C(education_level) |
y ~ x1 + I(x1**2) |
包含 x1 的线性项和平方项(用于多项式回归)。 |
salary ~ experience + I(experience**2) |
y ~ x1 + np.log(x2) |
在公式中直接使用 NumPy 函数。 | salary ~ experience + np.log(salary) |
y ~ 0 或 y ~ -1 |
不包含截距项。 | salary ~ 0 + experience + gender |
dmatrices 是 Python 数据科学工具箱中一个优雅而强大的函数,它极大地简化了为回归模型准备数据的过程,通过公式化的接口,它让数据预处理和模型构建变得更加清晰、高效且不易出错,对于任何需要进行统计回归分析的人来说,掌握 patsy 和 dmatrices 都是一项非常有价值的技能。
