單變量的線性回歸非常容易理解,就是生成一元一次方程:
地推人員數量 | 賣出會員數量 |
1 | 14 |
2 | 24 |
2 | 18 |
1 | 17 |
3 | 27 |
應用層面可以直接拿公式套,甚至公式也不用記,開源庫都封裝好了方法,傳入樣本數據即可得方程式。
本着不光知其然還要知其所以然的態度,查閱了一些資料,總結成自己最易理解的語言闡述下求解過程。
求解過程:
令f(x,y)=∑(Yi-(a*Xi+b))^2,將樣本點代入,並將a、b轉為常見的x、y變量。得出:
f(x,y)=(1x+y-14)^2+ (2x+y-24)^2+ (2x+y-18)^2 + (1x+y-17)^2+ (3x+y-27)^2
f(x,y)是一個二元二次分布式,看一下它的三維圖像:
上圖x、y坐標顯示很清晰,但是z坐標不立體,換個角度看:
從上圖可以看出,這個圖像是有谷底的,谷底就是f(x,y)的最小值。
在谷底處,不管x坐標,還是y坐標,其斜率都是0,也就是x和y的導數都是0。
所以,求f(x,y)的最小值就是求x導數=0和y導數=0。這個結論是重點、重點、重點!
為什么強調它,是因為查閱的N多文章都直接拋出:求f(x,y)的最小值就是求x和y的導數。這句話有2個問題:
一、怎么得出這個結論的?
二、x和y的導數是個函數,f(x,y)的最小值應該是個固定值,怎么能划等號?
后來看到一篇嚴謹的文章說:求f(x,y)的最小值是求x和y的導數等於0,並不能僅僅說求x和y的導數。
問題二解決了,可是問題一依然困惑。
一元二次方程求極值=求一元變量導數等於0,這個容易理解是因為拋物線的圖像深入我心。
那不如類比一下,看看二元二次方程的圖像吧。這才有了上面兩個三維圖像的來源。用python Axes3D畫的。
看這個圖像就很容易理解為什么要求導、為什么求兩個變量的、為什么導數應該等於0了!
現在來重溫下求導的知識點:
- 基本求導公式




比如 y=x^2,求y的導數,按照上述步驟:
Δy=(x+Δx)^2-x^2=2xΔx+Δx^2 ;Δy/Δx=2x+Δx ;Δx趨於0,所以y的導數=2x。
- 導數的四則運算法則
(u+v)'=u'+v'
(u-v)'=u'-v'
(uv)'=u'v+uv'
(u/v)'=(u'v-uv')/v^2
- 復合函數維度下降法求導
f[g(x)]中,設g(x)=u,則f[g(x)]=f(u),f'[g(x)]=f'(u)*g'(x)
比如y=(3x-2)^2,令y=u^2,u=3x-2. y'(x)=y'(u)*u'(x)=2*(3x-2)*3=18x-12.
現在可以對 f(x,y)=(1x+y-14)^2+ (2x+y-24)^2+ (2x+y-18)^2 + (1x+y-17)^2+ (3x+y-27)^2 求導了 :
x導數=2*(x+y-14)*1+2*(2x+y-24)*2+2*(2x+y-18)*2+2*(x+y-17)*1+2*(3x+y-27)*3
y導數=2*(x+y-14)*1+2*(2x+y-24)*1+2*(2x+y-18)*1+2*(1x+y-17)*1+2*(3x+y-27)*1
目的是求得x導數=0、y導數=0時的x、y值。即:
(x+y-14)+(2x+y-24)*2+(2x+y-18)*2+(x+y-17)+(3x+y-27)*3=0
(x+y-14)+(2x+y-24)+(2x+y-18)+(x+y-17)+(3x+y-27)=0
即:
19x+9y=196
9x+5y=100
這是一個二元一次方程,很容易求得:x=5.7142,y=9.7142.
下面證明簡化版的求解公式是怎么來的:
分別對a和b求一階偏導,求導后讓其等於0,然后聯立方程組解得參數a和b。
套用這個公式,依然求得:a=5.7142,b=9.7142.
看下二元方程圖像求極值的代碼,比較結果是否和求導/套用公式的一致:
import numpy as np
if __name__ == '__main__':
x = np.arange(0, 20, 0.1)
y = np.arange(0, 20, 0.1)
x, y = np.meshgrid(x, y)
z = (1*x+y-14)**2+ (2*x+y-24)**2+ (2*x+y-18)**2 + (1*x+y-17)**2+ (3*x+y-27)**2
q=[]
for i in range(0,200,1):
q.append(z[i])
z=z.flatten()
w= min(z)
print ("損失函數的最小值是: "+str(w))
for i in range(200):
for j in range(200):
if q[i][j]==w:
break
else:
continue
break
print ("a、b參數的值分別是: "+str(x[i][j])+" , "+str(y[i][j]))
輸出:
損失函數的最小值是: 22.58
a、b參數的值分別是:5.7 , 9.7
這個結果精度不如前面兩個。原因在於x、y坐標移動步長0.1還可以更小。
如果步長太小又會導致性能變差。順着這個思路,就不難理解梯度下降法了。
實際項目都是用計算機的梯度下降法來求極值,所以求導部分理解即可,不用強記。
最后看下最優直線長什么樣子吧: