一文让你彻底搞懂最小二乘法(超详细推导)

1

x_0=1

x0​=1,于是上述方程可以用矩阵表示为:

h

=

X

θ

\mathbf{h}=\mathbf{X} \theta

h=Xθ其中,

h

\mathbf{h}

h为mx1的向量, 代表模型的理论值,

θ

\theta

θ 为nx1的向量,

X

X

X为mxn维的矩阵,

m

m

m代表样本的个数,

n

n

n代表样本的特征数,于是目标损失函数用矩阵表示为:

J

(

θ

)

=

h

Y

2

=

X

θ

Y

2

=

(

X

θ

Y

)

T

(

X

θ

Y

)

J(\theta)=|\mathbf{h}-\mathbf{Y}|^2 =|\mathbf{X}\theta-\mathbf{Y}|^2= (\mathbf{X} \theta-\mathbf{Y})^{T}(\mathbf{X} \theta-\mathbf{Y})

J(θ)=∥h−Y∥2=∥Xθ−Y∥2=(Xθ−Y)T(Xθ−Y)其中

Y

\mathbf{Y}

Y是样本的输出向量, 维度为mx1。

根据高数知识我们知道函数取得极值就是导数为0的地方,所以我们只需要对损失函数求导令其等于0就可以解出

θ

\theta

θ。矩阵求导属于矩阵微积分的内容,我也是现学的(…,这里先介绍两个用到的公式:

x

T

a

x

=

a

T

x

x

=

a

\frac{\partial x^{T} a}{\partial x}=\frac{\partial a^{T} x}{\partial x}=a

∂x∂xTa​=∂x∂aTx​=a

x

T

A

x

x

=

A

x

A

T

x

\frac{\partial x^{T} A x}{\partial x}=A x+A^{T} x

∂x∂xTAx​=Ax+ATx如果矩阵A是对称的:

A

x

A

T

x

=

2

A

x

A x+A^{T} x=2 A x

Ax+ATx=2Ax对目标函数化简:

J

(

θ

)

=

θ

T

X

T

X

θ

θ

T

X

T

Y

Y

T

X

θ

Y

T

Y

J(\theta)=\theta^{T} X^{T} X \theta-\theta^{T} X{T}Y-Y{T} X\theta+Y^{T} Y

J(θ)=θTXTXθ−θTXTY−YTXθ+YTY求导令其等于0:

θ

J

(

θ

)

=

2

X

T

X

θ

2

X

T

Y

=

0

\frac{\partial}{\partial \theta} J(\theta)=2X^{T} X \theta-2X^TY=0

∂θ∂​J(θ)=2XTXθ−2XTY=0解得

θ

=

(

X

T

X

)

1

X

T

Y

\theta=\left(X{T}X\right){-1} X^{T}Y

θ=(XTX)−1XTY,经过推导我们得到了

θ

\theta

θ的解析解,现在只要给了数据,我们就可以带入解析解中直接算出

θ

\theta

θ。

几何意义

几何意义会直观的帮助你理解最小二乘法究竟在干什么。首先先来解释一下矩阵乘法的几何意义,对于一个方程组

A

x

Ax

Ax,我们可以看做是

x

x

x对矩阵

A

A

A的列向量的线性组合,比如:

{

1

×

x

1

x

2

=

3

1

×

x

1

x

2

=

1

[

1

1

1

1

]

[

x

1

x

2

]

=

[

3

1

]

A

×

x

=

b

\left{\begin{array}{l} 1 \times x_{1}+x_{2}=3 \ -1 \times x_{1}+x_{2}=1 \end{array} \Leftrightarrow\left[\begin{array}{ll} 1 & 1 \ -1 & 1 \end{array}\right]\left[\begin{array}{l} x_{1} \ x_{2} \end{array}\right]=\left[\begin{array}{l} 3 \ 1 \end{array}\right] \Leftrightarrow A \times x=b\right.

{1×x1​+x2​=3−1×x1​+x2​=1​⇔[1−1​11​][x1​x2​​]=[31​]⇔A×x=b
可以看作:

[

1

1

]

×

x

1

[

1

1

]

×

x

2

=

[

3

1

]

a

1

×

x

1

a

2

×

x

2

=

b

\left[\begin{array}{c} 1 \ -1 \end{array}\right] \times x_{1}+\left[\begin{array}{c} 1 \ 1 \end{array}\right] \times x_{2}=\left[\begin{array}{l} 3 \ 1 \end{array}\right] \Leftrightarrow a_{1} \times x_{1}+a_{2} \times x_{2}=b

[1−1​]×x1​+[11​]×x2​=[31​]⇔a1​×x1​+a2​×x2​=b
画在坐标轴上可以看到,向量

b

\mathbf{b}

b其实就是向量

a

1

\mathbf{a_1}

a1​与

a

2

\mathbf{a_2}

a2​的线性组合,因为他们都是在一个平面上,显然是有解的。
在这里插入图片描述
但是如文章开头所说,由于存在观测误差,我们往往会做多余观测,比如要拟合一次方程

y

=

k

x

b

y=k x+b

y=kx+b,我们可能观测了三个点(0,2),(1,2),(2,3),写成矩阵形式如下(为表述方便,用x1代替k,x2代替b ):

{

1

×

x

1

x

2

=

2

0

×

x

1

x

2

=

2

2

×

x

1

x

2

=

3

[

1

1

0

1

2

1

]

[

x

1

x

2

]

=

[

2

2

3

]

A

×

x

=

b

\left{\begin{array}{l} 1 \times x_{1}+x_{2}=2 \ 0 \times x_{1}+x_{2}=2 \ 2 \times x_{1}+x_{2}=3 \end{array} \Leftrightarrow\left[\begin{array}{ll} 1 & 1 \ 0 & 1 \ 2 & 1 \end{array}\right]\left[\begin{array}{l} x_{1} \ x_{2} \end{array}\right]=\left[\begin{array}{l} 2 \ 2 \ 3 \end{array}\right] \Leftrightarrow A \times x=b\right.

⎩⎨⎧​1×x1​+x2​=20×x1​+x2​=22×x1​+x2​=3​⇔⎣⎡​102​111​⎦⎤​[x1​x2​​]=⎣⎡​223​⎦⎤​⇔A×x=b
表示成线性组合的方式:

[

1

0

2

]

×

x

1

[

1

1

1

]

×

x

2

=

[

2

2

3

]

a

1

×

x

1

a

2

×

x

2

=

b

\left[\begin{array}{l} 1 \ 0 \ 2 \end{array}\right] \times x_{1}+\left[\begin{array}{l} 1 \ 1 \ 1 \end{array}\right] \times x_{2}=\left[\begin{array}{l} 2 \ 2 \ 3 \end{array}\right] \Leftrightarrow a_{1} \times x_{1}+a_{2} \times x_{2}=b

⎣⎡​102​⎦⎤​×x1​+⎣⎡​111​⎦⎤​×x2​=⎣⎡​223​⎦⎤​⇔a1​×x1​+a2​×x2​=b

画在图中如下:
在这里插入图片描述
从图中我们可以看到,无论

a

1

\mathbf{a_1}

a1​ 和

a

2

\mathbf{a_2}

a2​ 怎么线性组合都不可能得到

b

\mathbf{b}

b,因为

a

1

\mathbf{a_1}

a1​ 和

a

2

\mathbf{a_2}

a2​ 的线性组合成的向量只能落在它们组成的子空间

S

\mathbf{S}

S 中。

退而求其次,虽然我们不可能得到

b

\mathbf{b}

b,但在

S

\mathbf{S}

S上找一个和

b

\mathbf{b}

b最接近的总可以吧。那么将

b

\mathbf{b}

b投影 在平面

S

\mathbf{S}

S上得到的向量

p

\mathbf{p}

p就是和

b

\mathbf{b}

b最接近的向量(把向量看作点,最接近的意思就是点到平面某点取得距离最短,自然就是投影所成的交点)。
在这里插入图片描述

换句话说,方程组

A

x

=

b

Ax=b

Ax=b虽然无解,也就是b不在A的列空间中,但是我们可以在

A

A

A的列空间中找到一个和

b

b

b最接近的向量

p

p

p,

p

p

p就是

b

b

b在

A

A

A的列空间中的投影,通过求

A

x

=

p

Ax=p

Ax=p的解,就是原方程的最小二乘解。

由几何意义可知垂线

e

=

b

p

=

b

A

x

e=b-p=b-Ax

e=b−p=b−Ax正交于平面

S

\mathbf{S}

S,也就是

a

1

T

e

=

0

,

a

2

T

e

=

0

a_{1}^{T} e=0, a_{2}^{T} e=0

a1T​e=0,a2T​e=0,写成矩阵形式:

A

T

e

=

A

T

(

b

A

x

)

=

A

T

b

A

T

A

x

=

0

\begin{array}{c} A^{T} e=A{T}(b-Ax)=A{T} b-A^{T} Ax=0 \end{array}

ATe=AT(b−Ax)=ATb−ATAx=0​解得

x

=

(

A

T

A

)

1

A

T

b

x=\left(A^{T} A\right)^{-1} A^{T} b

x=(ATA)−1ATb,可以看到推导结果和矩阵法一样。从上面可以看到,最小二乘法的几何意义就是**求解

b

b

b 在

A

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

向量(把向量看作点,最接近的意思就是点到平面某点取得距离最短,自然就是投影所成的交点)。
在这里插入图片描述

换句话说,方程组

A

x

=

b

Ax=b

Ax=b虽然无解,也就是b不在A的列空间中,但是我们可以在

A

A

A的列空间中找到一个和

b

b

b最接近的向量

p

p

p,

p

p

p就是

b

b

b在

A

A

A的列空间中的投影,通过求

A

x

=

p

Ax=p

Ax=p的解,就是原方程的最小二乘解。

由几何意义可知垂线

e

=

b

p

=

b

A

x

e=b-p=b-Ax

e=b−p=b−Ax正交于平面

S

\mathbf{S}

S,也就是

a

1

T

e

=

0

,

a

2

T

e

=

0

a_{1}^{T} e=0, a_{2}^{T} e=0

a1T​e=0,a2T​e=0,写成矩阵形式:

A

T

e

=

A

T

(

b

A

x

)

=

A

T

b

A

T

A

x

=

0

\begin{array}{c} A^{T} e=A{T}(b-Ax)=A{T} b-A^{T} Ax=0 \end{array}

ATe=AT(b−Ax)=ATb−ATAx=0​解得

x

=

(

A

T

A

)

1

A

T

b

x=\left(A^{T} A\right)^{-1} A^{T} b

x=(ATA)−1ATb,可以看到推导结果和矩阵法一样。从上面可以看到,最小二乘法的几何意义就是**求解

b

b

b 在

A

[外链图片转存中…(img-nwCPMa7i-1719249028322)]
[外链图片转存中…(img-WPMJau8m-1719249028322)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python面向对象编程(Object-Oriented Programming,简称OOP)是一种程序设计方法,它将数据和操作数据的方法组合成对象,通过定义类(class)来创建对象。下面是一些概念和原则,可以帮助你更好地理解Python面向对象编程。 1. 类和对象: - 类是一种抽象的数据类型,它定义了对象的属性和方法。 - 对象是类的实例,它具有类定义的属性和方法。 2. 属性和方法: - 属性是对象的数据,可以是整数、字符串、列表等。 - 方法是对象的行为,可以是函数或过程。 3. 封装: - 封装是将数据和对数据的操作封装在一起,以创建一个独立的实体。 - 使用类来封装数据和方法,可以隐藏实现细节,提高代码的可读性和可维护性。 4. 继承: - 继承是一种机制,允许一个类继承另一个类的属性和方法。 - 子类可以重用父类的代码,并且可以添加新的属性和方法。 5. 多态: - 多态是指同一个方法可以在不同的类中具有不同的实现方式。 - 多态可以提高代码的灵活性和可扩展性。 下面是一个简单的例子,展示了如何定义一个类、创建对象并调用对象的方法: ```python class Person: def __init__(self, name, age): self.name = name self.age = age def say_hello(self): print(f"Hello, my name is {self.name} and I'm {self.age} years old.") # 创建对象 person = Person("Alice", 25) # 调用对象的方法 person.say_hello() ``` 这个例子定义了一个名为`Person`的类,它有两个属性(`name`和`age`)和一个方法(`say_hello`)。我们通过`Person`类创建了一个名为`person`的对象,并调用了它的`say_hello`方法。 希望这个简单的例子能帮助你更好地理解Python面向对象编程。如果你有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值