面向数据科学的概率论——第二十四章 简单线性回归
原文:https://nbviewer.jupyter.org/github/prob140/textbook/tree/gh-pages/notebooks/Chapter_24/
译者:ThomasCai
自豪地采用谷歌翻译
文章目录
00 简单线性回归
在数据科学中,回归模型被广泛地应用于预测。本章从概率论的角度来研究线性最小二乘法。重点是简单回归,即基于一个数值属性的预测。
当属性X和响应Y的联合分布为二元正态分布时,(X,Y)的经验分布是橄榄球的形状,与数字8的非常相似。我们将从相关的几何解释开始,因为这有助于理解回归和二元正态分布。我们要推导的线性回归的方程,可以用几种方法来表示;在本章的末尾,我们将以最容易扩展到多元回归的方式来表示它。
01 二元正态分布
# HIDDEN
from datascience import *
from prob140 import *
import numpy as np
import warnings
import matplotlib.cbook
warnings.filterwarnings("ignore",category=matplotlib.cbook.mplDeprecation)
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')
%matplotlib inline
from scipy import stats
# HIDDEN
def sin(theta):
return np.sin(theta * np.pi/180)
def cos(theta):
return np.cos(theta * np.pi/180)
def tan(theta):
return sin(theta)/cos(theta)
def projection_1_2(theta):
x = 1
z = 2
y = x*cos(theta) + z*sin(theta)
plt.figure(figsize=(6, 6))
plt.scatter(x, z, s=40, color='green')
plt.plot([-3, 3], [0, 0], color='grey', lw=2, label=r'$X$'+' axis')
plt.plot([0, 0], [-3, 3], color='grey', lw=2)
plt.plot([-3, 3], [tan(theta)*(-3), tan(theta)*3], color='gold', lw=2, label='New axis at positive angle '+r'$\theta$ to the '+r'$X$'+' axis')
plt.plot([0, x], [0, 0], color='blue', lw=2)
plt.plot([x, x], [0, z], color='green', linestyle='--', lw=2)
plt.plot([x, cos(theta)*y], [z, sin(theta)*y], color='green', linestyle='--', lw=2)
plt.plot([0, cos(theta)*y], [0, sin(theta)*y], color='red', lw=2)
plt.axes().set_aspect('equal')
plt.legend(bbox_to_anchor=(1.92, 1.02))
plt.xlabel('$X$')
plt.ylabel('$Z$', rotation=0)
plt.title('Projection of $(X, Z) = (1, 2)$ on Gold Axis')
plt.xlim(-3, 3)
plt.ylim(-3, 3)
def projection_trig():
x = 1
z = 2
x1 = x*cos(theta)
x2 = z*sin(theta)
y = x1 + x2
plt.figure(figsize=(8, 8))
plt.scatter(x, z, s=40, color='green')
plt.plot([-3, 3], [0, 0], color='grey', lw=2)
plt.plot([0, 0], [-3, 3], color='grey', lw=2)
plt.plot([-3, 3], [tan(theta)*(-3), tan(theta)*3], color='gold', lw=2)
plt.plot([0, x], [0, 0], color='blue', lw=2)
plt.plot([x, x], [0, z], color='green', linestyle='--', lw=2)
plt.plot([x, cos(theta)*y], [z, sin(theta)*y], color='green', linestyle='--', lw=2)
plt.plot([x, cos(theta)*x1], [0, sin(theta)*x1], color='k', linestyle='--', lw=2)
plt.plot([cos(theta)*y, x+cos(theta)*x2], [sin(theta)*y, sin(theta)*x2], color='k', linestyle='--', lw=2)
plt.plot([x, x+cos(theta)*x2], [0, sin(theta)*x2], color='k', linestyle='--', lw=2)
plt.plot([0, cos(theta)*x1], [0, sin(theta)*x1], color='brown', lw=3, label='Length = '+r'$X\cos(\theta)$')
plt.plot([cos(theta)*x1, cos(theta)*y], [sin(theta)*x1, sin(theta)*y], color='darkblue', lw=3, label='Length = '+r'$Z\sin(\theta)$')
plt.text(0.3, 0.06, r'$\theta$', fontsize=20)
plt.text(1.03, 1.6, r'$\theta$', fontsize=20)
plt.text(0.8, 2.1, r'$(X, Z)$', fontsize=15)
plt.legend(bbox_to_anchor=(1.35, 1))
plt.axes().set_aspect('equal')
plt.xlabel('$X$')
plt.ylabel('$Z$', rotation=0)
plt.title('$Y =$ '+r'$X\cos(\theta) + Z\sin(\theta)$')
plt.xlim(-0.5, 3)
plt.ylim(-0.5, 3)
二元正态分布
多元正态分布由均值向量和协方差矩阵定义。协方差的单位通常难以理解,因为它们是两个变量的单位的乘积。
将协方差归一化以使其更容易解释是个好主意。正如你们在练习中看到的,对于联合分布的随机变量X和Y, X和Y之间的相关性(译者注:相关系数)定义为:
τX,Y=σXσYCov(X,Y)=E(σXX−μX⋅σYY−μY)=E(X∗Y∗)
其中X∗是标准单位的X,Y∗是标准单位的Y。
相关性的性质
你在练习中可以看到这些。
- τX,Y只依赖于标准单位,因此它是一个没有单位的纯数
- τX,Y=τY,X
- −1≤τX,Y≤1
- 如果Y=aX+b,然后τX,Y是1或-1,这根据a的符号是正还是负。
我们认为τX,Y衡量了X和Y的线性关系。
和的方差
重写一下相关性的公式
Cov(X,Y)=τX,YσXσY
所以X+Y的方差是
σX+Y2=σX2+σY2+2τX,YσXσY
注意与两个向量之和的长度的公式并行,相关性扮演着两个向量夹角的余弦的角色。如果这个角是90度,那么cos值为0。这对应于相关性也为零,因此随机变量是不相关的。
在X和Y的联合分布是二元正态分布的情况下,我们将可视化这个想法。
标准二元正态分布
令X和Z是独立的标准正态变量,即具有均值向量0和协方差矩阵等于单位矩阵的二元正态随机变量。 现在确定一个数ρ(即希腊字母rho,小写r),使−1<ρ<1,并令
A=[1ρ01−ρ2]
定义一个新的随机变量Y=ρX+1−ρ2Z,并注意到
[XY]=[1ρ01−ρ2][XZ]=A[XZ]
所以X和Y是均值向量为0和协方差矩阵的二元正态分布。
AIAT=[1ρ01−ρ2][10ρ1−ρ2]=[1ρρ1]
我们说X和Y有标准的二元正态分布,相关性ρ。
下图显示了在ρ=0.6的情况下1000个(X,Y)点的经验分布。 您可以改变rho的值(译者注:也就是ρ)并观察散点图是如何变化的。 它将使您想起数据8中的许多此类模拟。
# Plotting parameters
plt.figure(figsize=(5, 5))
plt.axes().set_aspect('equal')
plt.xlabel('$X$')
plt.ylabel('$Y$', rotation=0)
plt.xticks(np.arange(-4, 4.1))
plt.yticks(np.arange(-4, 4.1))
# X, Z, and Y
x = stats.norm.rvs(0, 1, size=1000)
z = stats.norm.rvs(0, 1, size=1000)
rho = 0.6
y = rho*x + np.sqrt((1-rho**2))*z
plt.scatter(x, y, color='darkblue', s=10);