1. 程式人生 > >線性迴歸理解(附純python實現)

線性迴歸理解(附純python實現)

線性迴歸是機器學習中最基本的一個演算法,但是那些所謂的效果很好的演算法也無非是從這些基礎演算法慢慢演變而來。高中時候的數學老師給我講過一個喬峰的故事,我今天再添油加醋的給你們說下。天龍八部中,喬峰在聚賢莊大戰江湖群雄這個算是經典了,當時各路武林豪傑紛紛使出自家的看門絕學,什麼易筋經啊,九陰真經啊,葵花點穴手啊等等,但統統都被喬峰一拳KO,直接秒殺,竟無一人是其敵手,那喬峰用的是什麼高深武學呢?其實他用的是拳法當作最為基礎的一套拳法,名為長拳,有點拳法方面知識的人都知道,長拳其實一套最最基礎的拳法,大家可以把它想成軍訓時候的匕首操。但就是這麼個匕首操把這麼多絕世武功都KO了。為啥?因為喬峰小時候在少林寺山腳住的時候,就開始苦練基本功,苦練長拳,並沒用刻意的去最求一些更高水平的武學,這才將一套基礎拳法發揮得如此淋漓盡致。

這個故事我也只聽了個大概,上面我很大部分都自己瞎寫的,我就是要說一個道理。
第一:基礎很重要
第二:一些簡單的東西,學好了不比很多複雜的高深的東西差。
說了這麼多,其實就是要引出今天的主題——-線性迴歸。線性迴歸我覺得可以當成是機器學習中的長拳。

線性迴歸

線性迴歸包括一元線性迴歸和多元線性迴歸,一元的是隻有一個x和一個y。多元的是指有多個x和一個y。
下面我只講下一元的,多元只是將這裡寫圖片描述 變成了這裡寫圖片描述

一元線性迴歸其實就是去找到一條直線,這條直線能以最小的誤差(Loss)來擬合數據。
這裡寫圖片描述

怎麼來表示誤差呢?

這裡寫圖片描述
如上圖所示,橫座標表示x,縱座標表示y。我們要找的就是圖中的這條直線。我們要去找到這條直線,大家可以想象,我們肯定希望找到的那條線,距離每個點都很近,最好所有的點上都在這條線上,但是一條直線去擬合所有的點都在這條直線上肯定不現實,所以我們希望這些點儘量離這條直線近一點。即去找每個點和直線的距離 這裡寫圖片描述

最小的那條線,為了簡單起見,將絕對值轉化為平方,那麼誤差可以表示為這裡寫圖片描述,這裡i表示第i個數據,N表示總的樣本個數。一般我們還會把Loss求和平均,來當作最終的損失,
這裡寫圖片描述

怎麼去最小化誤差?

我們要怎麼去找到最能擬合數據的直線?即最小化誤差呢?
一般有兩個方法:

最小二乘法

上面我們講了我們定義的損失這裡寫圖片描述,其中的x,y,i,N都是已知的,那麼我們就可以把這個方程看作是m和b的方程。作為一個m和b的二次方程。那麼求Loss最小值的問題就轉變成了求極值問題,這個高數學過的都應該知道點。

怎麼求極值呢?

令每個變數的偏導數為零,求方程組的解唄,這個是很基礎的高數問題了。
我們可以得到下面的方程組
這裡寫圖片描述


這裡寫圖片描述
然後就是巴拉巴拉巴拉把m和b求出來,這樣就得到我們要的線性方程了。

梯度下降法

沒有梯度下降就沒有現在的深度學習,這是一個神奇的演算法。
最小二乘法可以一步到位,直接算出m和b,但他是有前提的,具體我有點記不清了,好像是需要滿秩什麼的。梯度下降法和最小二乘不一樣,它通過一步一步的迭代,慢慢的去靠近到那條最優直線。
最小二乘法裡面我們提到了兩個偏導數,分別為
這裡寫圖片描述
這裡寫圖片描述
我們要去找Loss這個方程的最小值,最小值怎麼求?按數學的求法就是最小二乘法唄,但是大家可以直觀的想一下,很多地方都會用一個碗來形容,那我也找個碗來解釋吧。
這裡寫圖片描述
大家把這個Loss函式想象成這個碗,而我們要求的最小值就是碗底。假設我們現在不能用最小二乘法求極小值,但是我們的計算機的計算能量很強,我們可以用計算量換結果,不管我們位於這個碗的什麼位置,只要我們想去碗底,就要往下走。
往下走????????
這個下不就是往梯度方向走嗎,那我們沿著梯度一點一點滑下去唄,反正計算機不嫌累。梯度不就是上面那兩個公式唄。現在梯度有了,那每次滑多遠呢,一滑劃過頭了不久白算半天了嗎,所以還得定義步長,用來表示每次滑多長。這樣我們就能每次向下走一點點,再定義一個迭代值用來表示滑多少次,這樣我們就能慢慢的一點點的靠近最小值了,不出意外還是能距離最優值很近的。

順便把上面這個梯度下降法實現下

每次向下滑要慢慢滑,就是要個步長,我們定義為learning_rate,往往很小的一個值。

向下滑動的次數,就是迭代的次數,我定義為num_iter,相對learning_rate往往很大。

定義好這兩個,我們就可以一邊求梯度,一邊向下滑了。就是去更新m和b。
這裡寫圖片描述
這裡寫圖片描述
我這裡用了加號,很多人會誤以為梯度下降就要減,但是其實梯度本身是有方向的,所以這裡直接加就可以。

如下圖所示,我們做的初始化

這裡寫圖片描述

然後就是優化器,優化器就是去做梯度下降

這裡寫圖片描述

它裡面的具體步驟,如下

這裡寫圖片描述

裡面的compute_gradient方法就是去計算梯度做引數更新

這裡寫圖片描述

Notes:
線性迴歸適用於線性變換資料
線性迴歸受噪聲影響較大