多元回归和方差分析
多元线性回归¶
Python 中的线性代数¶
矩阵¶
初始化矩阵¶
# 注意两个括号
A = np.zeros((2,2))
B = np.ones((2,2))
C = np.eye(2) # 谐音 I
D = np.diag([1,2,3])
E = np.array(np.random.randint(10,size=(3,4))) # 随机数矩阵
取值¶
矩阵运算¶
- Broadcast
# Broadcast
C = np.array(np.random.randint(3,size=(1,4)))
# C: 1x4, E: 3x4
C*E # C与E的每一行相乘
# F: 3x1
F = np.array(np.random.randint(3,size=(3,1)))
F*E # F与E的每一列相乘
矩阵转置¶
矩阵乘法¶
- 查看矩阵的形状
矩阵求逆¶
# 解 Ax = b
b = np.array(np.random.randint(10,size=(3,1)))
A = np.array(np.random.randint(10,size=(3,3)))
# 逆矩阵
A_inv = np.linalg.inv(A)
# 解方程
np.linalg.solve(A,b)
np.linalg.inv(A)@b # 更慢
solve(A,b)
与inv(A)@b
solve
更快,因为它使用了更高效的算法
计时比较:
多变量的回归¶
- 若
由多个变量控制:
- 写为
的形式:
多元线性函数的矩阵表示¶
- 用列向量来表示
和 的测量值
- 用矩阵表示
的测量值
残差
最小二乘法求解¶
- 求解
使得 最小
- 矩阵求导(
为列向量)
一顿推导TAT...
得到
令
-
-
仍然可用残差来估计
的区间估计¶
from sklearn import linear_model
import numpy as np
# x,y 为 1*20 的行向量
X = np.vstack([x,y]).T # 20*2
ols = linear_model.LinearRegression() # 创建线性回归对象. OLS: Ordinary Least Squares
model = ols.fit(X, z) # 拟合
x_pred = np.linspace(0, 10, 50) # 生成预测值
y_pred = np.linspace(0, 8, 50)
x_predmesh, y_predmesh = np.meshgrid(x_pred, y_pred) # 生成网格
# flatten() 将多维数组转换为一维数组
model_viz = np.array([x_predmesh.flatten(), y_predmesh.flatten()]).T # 2500*2
print(model_viz.shape)
predicted = model.predict(model_viz)
fig = plt.figure(figsize=(4, 4))
ax = fig.add_subplot(111, projection='3d')
ax.plot(x_predmesh.flatten(), y_predmesh.flatten(), predicted, , alpha=0.9)
ax.scatter(x, y, z, color='red')
矩阵运算求线性回归系数¶
ones = np.ones(20)
Xm = np.vstack([ones, x, y]).T
Y = np.array(z).reshape(20, 1)
b = np.linalg.solve(Xm.T @ Xm, Xm.T @ Y)
print(b)
矩阵运算求线性回归误差¶
statsmodels
无脑求解:
import statsmodel.api as sm
Xp = sm.add_constant(X) # Xp = np.vstack([ones, x, y]).T
# OLS 拟合
model = sm.OLS(z, Xp)
Fit_result = model.fit()
print(Fit_result.summary())
多元线性回归的假设检验¶
- 单个系数
是否为0,由 的 分布得到:
\(
- 一系列
为0,即 对 无显著影响 :
\(
\(
转化为线性回归的模型¶
- 多项式回归
- 指数拟合
from sklearn.preprocessing import PolynomialFeatures
a = 0.3
b = -4
c = 10
d = 8
x2 = st.uniform(0, 10).rvs(40)
x2 = np.sort(x2)
y2 =
偏相关¶
- 一组观测量
中,相互之间有关联 - 若
为一个人的收入, 为ta在吃和穿上的花费 - 观察到
之间的正相关 - 但实际上
均由 所带动,使得它们呈现正相关 - 若能去掉
的影响, 之间的实际相关性可能转为负相关 - 重新定义
\(
\(
\(
- 将原本
的相关矩阵写为
\(
记
大作业 ¶
自己找数据和主题!
参考数据来源: - Our World in Data
方差分析(ANOVA)¶
单因素¶
同因素的不同水平对结果的影响是否显著不同
- 例:配方A,B,各自得到一组关于指标Y的数据
配方A、B对结果的影响是否显著不同?
- 计算Y在A、B配方下的平均值. 假设
水平
水平
- 假设
- 各水平间的差异:
- 同水平内样本的差异:
- 总样本差异:
可以证明
- 当
时,假设 成立
meanx = np.mean(x)
meany = np.mean(y)
meanall = np.float64(sum(x+y)/len(x+y))
ssa = len(x)*((meanx-meanall)**2)+len(y)*((meany-meanall)**2)
sse = sum((x-meanx)**2)+sum((y-meany)**2)
sta = ssa/(sse/(len(x)+len(y)-2))
print(sta,1-st.f(1,len(x)+len(y)-2).cdf(sta))
print(st.f_oneway(x,y)) # 单因素 F-test
print(st.ttest_ind(x,y))
可以发现三种方式得到的 p-value 是一样的!
多因素¶
当因素有多种时,分析每种因素对结果的影响
因素