線性回歸算法
注:本文所有代碼和數(shù)據(jù)均在個(gè)人github下click me
回歸算法一般是針對(duì)預(yù)測(cè)是連續(xù)的情況下攻晒,對(duì)于預(yù)測(cè)值是離散的,采用的算法是分類算法奏瞬。線性回歸算法包括很多種變形枫绅,這里提到的線性回歸算法是其中的幾種典型算法。在實(shí)際應(yīng)用中硼端,我們采用線性算法可以預(yù)測(cè)商品的價(jià)格并淋,預(yù)測(cè)房子的房?jī)r(jià)等等,雖然線性回歸算法比較簡(jiǎn)單珍昨,但是在實(shí)際中還是有很多的使用的县耽。
在機(jī)器學(xué)習(xí)中,我們要緊盯三件事情镣典。第一兔毙,算法的損失函數(shù);第二兄春,采用什么求值算法求損失函數(shù)的最小值澎剥;第三,算法的評(píng)價(jià)指標(biāo)
一般線性回歸算法
一般的線性回歸又叫做最小二乘算法赶舆,最小二乘是因?yàn)樗惴ǖ膿p失函數(shù)是最小二乘的肴裙,損失函數(shù)如下:
其中是算法針對(duì)數(shù)據(jù)的預(yù)測(cè)值趾唱,而是數(shù)據(jù)的真實(shí)值,表示訓(xùn)練數(shù)據(jù)的條數(shù)蜻懦,而是為了此公式求導(dǎo)方便而加入的。而是算法的參數(shù)夕晓,在這里就是線性回歸的權(quán)重值宛乃。通過此公式我們可以得到,線性回歸算法的損失函數(shù)就是針對(duì)每個(gè)樣本計(jì)算預(yù)測(cè)值和真實(shí)值得差蒸辆,然后將差求平方征炼,之后將全體樣本的差平方相加即得到損失函數(shù)。
針對(duì)損失函數(shù)躬贡,我們有兩種算法可以求取損失函數(shù)的最小值谆奥。
梯度下降算法
梯度下降算法的一般形式:
這里寫的是梯度下降算法的標(biāo)量形式。這個(gè)公式描述了梯度下降算法是如何更新算法的參數(shù)的拂玻,其中是參數(shù)的更新步長(zhǎng)酸些。可以看到這里的關(guān)鍵是如何求取損失函數(shù)關(guān)于參數(shù)j的偏導(dǎo)數(shù)檐蚜。
將損失函數(shù)帶入到梯度下降算法,即公式中魄懂,并且求導(dǎo),可以得到下式:
我們重復(fù)的使用公式直到達(dá)到收斂條件闯第,即可以求得線性回歸算法中的參數(shù)值市栗。
從公式中,可以看到用真實(shí)值和預(yù)測(cè)值之間的差值來更新參數(shù)值咳短,這種方式或者思想在很多的機(jī)器學(xué)習(xí)算法中可以看到填帽,包括深度學(xué)習(xí)的后向傳播算法。同時(shí)咙好,可以看到每一次的迭代都要使用整個(gè)數(shù)據(jù)集篡腌。這種方式叫做批量梯度下降算法。還有一種方式可以求取值敷扫,叫做隨機(jī)梯度下降算法哀蘑,算法如下:
從中我們可以看到,隨機(jī)梯度下降算法每次采用一個(gè)訓(xùn)練樣本取更新所有的參數(shù)值葵第,注意那里的(for every j)绘迁。當(dāng)訓(xùn)練樣本很多時(shí),相比于批量梯度下降算法卒密,隨機(jī)梯度下降算法能夠更快的更新算法的參數(shù)值缀台,并且能夠更快的逼近損失函數(shù)的最小值。
代數(shù)解
我們將損失函數(shù)用向量表示哮奇,如下所示:
公式中的表示訓(xùn)練數(shù)據(jù)的矩陣膛腐。因?yàn)閾p失函數(shù)是凸二次函數(shù)睛约,所以只有一個(gè)最小值,所以導(dǎo)數(shù)為0的點(diǎn)就是損失函數(shù)的最小值哲身。
具體的推導(dǎo)過程如下(主要利用了矩陣的跡運(yùn)算):
令導(dǎo)數(shù)等于0辩涝,從而得到:
回歸模型的概率解釋
大家想過沒有,為什么在線性回歸模型里面選擇最小二乘作為損失函數(shù)勘天?接下來從概率的角度來解釋選擇最小二乘作為損失函數(shù)的原因怔揩。
首先怔锌,假設(shè)目標(biāo)變量和輸入數(shù)據(jù)存入如下的關(guān)系:
這里的是誤差項(xiàng)催束,包括模型未考慮到影響目標(biāo)變量的因素和隨機(jī)噪聲万俗。
接下來假設(shè)宽涌,誤差項(xiàng)相互獨(dú)立同分布糊肠,并且服從高斯分布(即正態(tài)分布)
為什么要假設(shè)誤差項(xiàng)服從高斯分布? 第一是因?yàn)椴捎酶咚狗植伎裳担跀?shù)學(xué)上處理會(huì)比較簡(jiǎn)單绘梦;第二是因?yàn)楦鶕?jù)中心極限定理嘀掸,獨(dú)立的隨機(jī)變量的和材蹬,其總的影響接近高斯分布
誤差項(xiàng)的概率密度函數(shù)為:
根據(jù)公式和公式,我們可以得出如下結(jié)論:
在公式中实幕,不是隨機(jī)變量,而是實(shí)際存在的值赚导,雖然我們不知道真實(shí)值是多少茬缩。的含義是給定,參數(shù)設(shè)定為時(shí),的概率密度。注意公式中用的分號(hào)吼旧。
數(shù)據(jù)的概率是由給出的凰锡,而總的概率可以看成是在固定時(shí),關(guān)于的函數(shù)圈暗。換個(gè)角度掂为,我們想要將這個(gè)函數(shù)明確的看成是關(guān)于的函數(shù),所以我們將其稱作似然函數(shù)员串,從而我們得到關(guān)于的似然函數(shù):
似然(likelihood)和概率(probability)實(shí)際上是一個(gè)東西勇哗,但是似然函數(shù)是對(duì)參數(shù)定義的,為了加以區(qū)分寸齐,使用了似然這一術(shù)語欲诺。我們可以說參數(shù)的似然,數(shù)據(jù)的概率渺鹦,但不能說數(shù)據(jù)的似然扰法,參數(shù)的概率。
極大似然估計(jì)就是選擇,使參數(shù)的似然函數(shù)最大化毅厚,也就是選擇參數(shù)使得已有樣本的出現(xiàn)概率最大塞颁。
因?yàn)?img class="math-inline" src="https://math.jianshu.com/math?formula=L(%5Ctheta)" alt="L(\theta)" mathimg="1">是嚴(yán)格單調(diào)遞增的,并且對(duì)數(shù)函數(shù)也是遞增的,所以取對(duì)數(shù)祠锣,得到的跟不取對(duì)象是一樣的酷窥。
對(duì)數(shù)似然函數(shù):
最大化似然函數(shù),就是最大化對(duì)數(shù)似然函數(shù)伴网,即最小化
這個(gè)式子剛好是線性回歸算法中采用的損失函數(shù)蓬推。總結(jié)一下澡腾,最小二乘回歸模型剛好就是在假設(shè)了誤差獨(dú)立同服從正態(tài)分布后拳氢,得到的最大似然估計(jì)。同時(shí)注意到蛋铆,正態(tài)分布中的方差的取值對(duì)模型并沒有影響。
編程實(shí)現(xiàn)
代數(shù)解實(shí)現(xiàn)線性回歸算法
def standard_regression(x_arr, y_arr):
"""
這里直接采用代數(shù)解直接求取權(quán)重大小.這里有個(gè)條件是xTx的逆必須存在,
如果不存在,則直接返回
:param x_arr:
:param y_arr:
:return:
"""
x_mat = np.mat(x_arr)
y_mat = np.mat(y_arr).T
xTx = x_mat.T * x_mat
if np.linalg.det(xTx) == 0.0:
print("矩陣是奇異的,逆不存在")
return
ws = xTx.I * (x_mat.T * y_mat)
return ws
根據(jù)standard_regression
函數(shù)可以直接求取算法的權(quán)重放接。然后根據(jù)權(quán)重就可以求得數(shù)據(jù)的預(yù)測(cè)結(jié)果刺啦,這里選擇的數(shù)據(jù)在點(diǎn)我
畫出的圖像如下:
直線為擬合直線,散點(diǎn)是真實(shí)值纠脾。
隨機(jī)梯度下降實(shí)現(xiàn)線性回歸
由于代碼篇幅比較長(zhǎng)玛瘸,所以可以直接上我的github上面看。代碼
局部加權(quán)線性回歸算法
每個(gè)點(diǎn)都對(duì)應(yīng)一個(gè)不同的苟蹈,利用計(jì)算預(yù)測(cè)值糊渊。
下面我們用剛才介紹的局部加權(quán)線性回歸來擬合一下這個(gè)模型,簡(jiǎn)單回顧一下過程:
1.用高斯核函數(shù)計(jì)算出第i個(gè)樣本處慧脱,其它所有樣本點(diǎn)的權(quán)重W
2.用權(quán)重w對(duì)第i個(gè)樣本作加權(quán)線性回歸渺绒,得到回歸方程,即擬合的直線方程
3.用剛才得到的經(jīng)驗(yàn)回歸直線計(jì)算出處的估計(jì)值
4.重復(fù)一至三步菱鸥,得到每個(gè)樣本點(diǎn)的估計(jì)值
同時(shí),從計(jì)算公式中宗兼,可以看到對(duì)于每個(gè)點(diǎn)的預(yù)測(cè)值,需要利用所有的數(shù)據(jù)樣本進(jìn)行計(jì)算氮采。如果數(shù)據(jù)量比較大殷绍,計(jì)算量就會(huì)是一個(gè)大問題。
相比于上面提到線性回歸算法(參數(shù)算法)鹊漠,局部加權(quán)線性回歸算法是非參數(shù)算法主到。
參數(shù)算法vs非參數(shù)算法
引用地址
參數(shù)算法:
如果我們對(duì)所要學(xué)習(xí)的問題有足夠的認(rèn)識(shí),具備一定的先驗(yàn)知識(shí)躯概,此時(shí)我們一般會(huì)假定要學(xué)習(xí)的目標(biāo)函數(shù)f(x)或分布P(y|x)的具體形式登钥。然后,通過訓(xùn)練數(shù)據(jù)集楞陷,基于ERM怔鳖、SRM、MLE、MAP等學(xué)習(xí)策略结执,可以估計(jì)出f(x)或P(y|x)中含有的未知參數(shù)度陆。一旦未知參數(shù)估計(jì)完畢,訓(xùn)練數(shù)據(jù)一般來說献幔,就失去其作用了懂傀,因?yàn)檫@些估計(jì)出來的參數(shù)就是訓(xùn)練數(shù)據(jù)的濃縮。通過這種方式建立起來的模型就是參數(shù)模型蜡感。參數(shù)模型的一個(gè)很重要的特點(diǎn)是蹬蚁,如果對(duì)于模型的假設(shè)正確,那么只需要很少的訓(xùn)練數(shù)據(jù)就可以從假設(shè)空間中學(xué)出一個(gè)很好的模型郑兴。但是犀斋,如果模型的假設(shè)錯(cuò)誤,那么無論訓(xùn)練的數(shù)據(jù)量有多大情连,甚至趨于無窮大叽粹,學(xué)出的模型都會(huì)與實(shí)際模型出現(xiàn)不可磨滅的偏差。感知機(jī)却舀、邏輯斯特回歸虫几、高斯判別分析、樸素貝葉斯挽拔、線性支持向量機(jī)都屬于參數(shù)模型辆脸。對(duì)于神經(jīng)網(wǎng)絡(luò)來說,當(dāng)固定了隱層的數(shù)目以及每一層神經(jīng)元的個(gè)數(shù)螃诅,它也屬于參數(shù)模型啡氢。但由于隱層數(shù)目與每一層神經(jīng)元個(gè)數(shù)的不確定性,很多時(shí)候州刽,神經(jīng)網(wǎng)絡(luò)都被歸類為半?yún)?shù)模型空执。
非參數(shù)算法:
當(dāng)我們對(duì)所要學(xué)習(xí)的問題知之甚少,此時(shí)我們一般不會(huì)對(duì)潛在的模型做過多的假設(shè)穗椅。在面對(duì)預(yù)測(cè)任務(wù)的時(shí)候辨绊,我們通常會(huì)用上所有的訓(xùn)練數(shù)據(jù)。例如簡(jiǎn)單的核密度估計(jì)(KDE)的表達(dá)式中匹表,就帶有所有訓(xùn)練數(shù)據(jù)的信息门坷。通過這種方式建立的模型就是非參數(shù)模型。非參數(shù)模型的一個(gè)很重要的特點(diǎn)就是:let the data speak for itself. 正因?yàn)槿绱伺鄱疲菂?shù)模型的存儲(chǔ)開銷默蚌、計(jì)算開銷都會(huì)比參數(shù)模型大的多。但是苇羡,由于不存在模型的錯(cuò)誤假定問題绸吸,可以證明,當(dāng)訓(xùn)練數(shù)據(jù)量趨于無窮大的時(shí)候,非參數(shù)模型可以逼近任意復(fù)雜的真實(shí)模型锦茁。這正是非參數(shù)模型誘人的一點(diǎn)攘轩。另外需要說明的一點(diǎn)是,非參數(shù)模型之所以叫做非參數(shù)码俩,并不是因?yàn)槟P椭袥]有參數(shù)度帮。實(shí)際上,非參數(shù)模型中一般會(huì)含有一個(gè)或多個(gè)超參數(shù)稿存,外加無窮多個(gè)普通的參數(shù)笨篷。k近鄰就是典型的非參數(shù)模型。
總結(jié)就是所謂參數(shù)學(xué)習(xí)算法它有固定的明確的參數(shù)瓣履,參數(shù) 一旦確定率翅,就不會(huì)改變了,我們不需要在保留訓(xùn)練集中的訓(xùn)練樣本袖迎。而非參數(shù)學(xué)習(xí)算法安聘,每進(jìn)行一次預(yù)測(cè),就需要重新學(xué)習(xí)一組 瓢棒, 是變化的,所以需要一直保留訓(xùn)練樣本丘喻。
實(shí)際使用
這里采用的數(shù)據(jù)跟線性回歸算法采用的相同脯宿。選取不同的k值,得到的擬合曲線如下圖:
從圖中可以看到泉粉,當(dāng)k值較小時(shí)连霉,對(duì)于訓(xùn)練數(shù)據(jù)有很好的擬合效果;當(dāng)k值較大時(shí)(比如取1)嗡靡,對(duì)于訓(xùn)練數(shù)據(jù)擬合的效果不是很好跺撼。當(dāng)然這都是針對(duì)訓(xùn)練數(shù)據(jù),在實(shí)際使用中讨彼,我們更關(guān)注的是對(duì)于測(cè)試數(shù)據(jù)的效果如何歉井。在實(shí)際中,我們可以將數(shù)據(jù)進(jìn)行十倍交叉驗(yàn)證哈误,選擇最合適的k值哩至。
從高斯公式中,我們從兩個(gè)方面看蜜自。首先菩貌,我們固定k值,那么距離較遠(yuǎn)的樣本重荠,其對(duì)應(yīng)的權(quán)重相對(duì)較屑住;距離較近的樣本,其對(duì)應(yīng)的權(quán)重相對(duì)較大仇参,當(dāng)x取時(shí)嘹叫,對(duì)應(yīng)的權(quán)重為1。而如果我們固定x(即只看某一特定樣本點(diǎn))冈敛,k取值較大時(shí)待笑,此樣本點(diǎn)對(duì)應(yīng)的權(quán)重相對(duì)較大;k取值較小時(shí)抓谴,此樣本點(diǎn)對(duì)應(yīng)的權(quán)重相對(duì)較大暮蹂。所以k可以控制算法選擇點(diǎn)附近有多少樣本參與計(jì)算。
最上面的圖是樣本點(diǎn)癌压,剩下三幅圖都是針對(duì)樣本點(diǎn)x=0.5,根據(jù)不同的k值仰泻,畫出的x附近樣本的權(quán)重變化√步欤可以看到集侯,當(dāng)k取0.5時(shí),當(dāng)計(jì)算x=0.5時(shí)的預(yù)測(cè)值時(shí)帜消,幾乎所有的樣本點(diǎn)都包括了棠枉;而當(dāng)k=0.01時(shí),僅僅取了x=0.5附近的點(diǎn)參與計(jì)算泡挺。如果k值取無窮大辈讶,那么w對(duì)于所有的點(diǎn)的權(quán)重都是1,那么局部加權(quán)線性回歸就變成了普通的線性回歸算法娄猫。
嶺回歸算法(Ridge Regression)
上面介紹的線性回歸算法里面可以看到需要計(jì)算的逆贱除,那么如果逆不存在呢?首先思考第一個(gè)問題媳溺,什么情況下月幌,的逆不存在呢?
- X本身存在相關(guān)關(guān)系悬蔽,即非滿秩矩陣扯躺。比如其中兩列是具有線性關(guān)系
- 如果特征列多余樣本數(shù)量,那么也是非滿秩的蝎困。
對(duì)于逆不存在的情況下缅帘,我們需要將原來的線性回歸算法進(jìn)行處理,使原先無法求逆的變成非奇異的难衰∏瘴蓿可以通過縮減的方式來處理這類問題,比如嶺回歸算法和LASSO算法盖袭。同時(shí)由于能夠調(diào)整算法中權(quán)重的大小失暂,能夠防止線性回歸算法的過擬合問題彼宠。
嶺回歸算法損失函數(shù)
通過改變的值,可以使得算法的方差和偏差之間達(dá)到平衡弟塞,增加,模型的方差減小而偏差增加凭峡。
對(duì)損失函數(shù)求取一階導(dǎo)數(shù),并另導(dǎo)數(shù)等于0决记,求得權(quán)重如下式:
在嶺回歸算法中的選擇對(duì)于算法有很大的影響摧冀。下圖展示了不同的的取值對(duì)于權(quán)重的影響,因?yàn)閿?shù)據(jù)有八個(gè)特征系宫,所以這里有八個(gè)權(quán)重索昂。當(dāng)較小時(shí),權(quán)重的值跟采用常規(guī)的線性回歸差不多扩借;而當(dāng)較大時(shí)椒惨,權(quán)重的值都會(huì)被調(diào)解的較小。
為了找到合適的值康谆,我們?cè)趯?shí)踐中往往會(huì)采用交叉測(cè)試來找到合適的值。
lasso回歸算法(Least Absolute Shrinkage and Selection Operator)
從嶺回歸算法中嫉到,我們可以看到沃暗,算法防止過擬合主要是在損失函數(shù)中添加懲罰項(xiàng)。在嶺回歸中何恶,懲罰項(xiàng)如下所示:
而在lasso回歸算法中描睦,懲罰項(xiàng)變成下式:
即將權(quán)重的平方和小于,替換為權(quán)重的絕對(duì)值和小于.進(jìn)行了這個(gè)變化后导而,能夠?qū)?quán)重縮小到0,而嶺回歸中無法將權(quán)重值縮小到0隔崎,只能接近0.
lasso回歸算法損失函數(shù)
我們也可以結(jié)合嶺回歸算法和lasso的損失函數(shù)今艺,構(gòu)建新的損失函數(shù)。這就是彈性網(wǎng)絡(luò)(ElasticNet)
逐步向前回歸
LASSO計(jì)算復(fù)雜度相對(duì)較高爵卒,本部分稍微介紹一下逐步向前回歸虚缎,他屬于一種貪心算法,給定初始系數(shù)向量钓株,然后不斷迭代遍歷每個(gè)系數(shù)实牡,增加或減小一個(gè)很小的數(shù),看看代價(jià)函數(shù)是否變小轴合,如果變小就保留创坞,如果變大就舍棄,然后不斷迭代直到回歸系數(shù)達(dá)到穩(wěn)定受葛。代碼如下:
def run_stage():
x_arr, y_arr = load_data_set('./data/abalone.txt')
all_w_001 = stage_wise(x_arr, y_arr, 0.001, 5000)
print(all_w_001)
all_w_01 = stage_wise(x_arr, y_arr, 0.01, 200)
print(all_w_01)
def stage_wise(x_arr, y_arr, eps=0.01, num_iter=100):
"""
forward stagewise regression算法(前向梯度算法)
是一種近似的 lasso算法
:param x_arr:
:param y_arr:
:param eps:每次特征權(quán)重的變化步長(zhǎng)
:param num_iter: 迭代次數(shù)
:return:
"""
x_mat = np.mat(x_arr)
y_mat = np.mat(y_arr).T
y_mean = np.mean(y_mat, 0)
y_mat = y_mat - y_mean
x_mean = np.mean(x_mat, 0)
x_var = np.var(x_mat, 0)
x_mat = (x_mat - x_mean) / x_var
m, n = np.shape(x_mat)
ws = np.zeros((n, 1))
ws_best = ws.copy()
return_mat = np.zeros((num_iter, n)) # 保存每次迭代最好的權(quán)重值
for i in range(num_iter):
# print(ws.T)
lowest_error = np.inf
for j in range(n):
for sign in [-1, 1]:
ws_test = ws.copy()
ws_test[j] += eps * sign
y_test = x_mat * ws_test
rss_err = rss_error(y_mat.A, y_test.A) # 將矩陣轉(zhuǎn)為數(shù)組
if rss_err < lowest_error:
lowest_error = rss_err
ws_best = ws_test
ws = ws_best.copy()
return_mat[i, :] = ws.T
return return_mat
逐步回歸算法的主要有點(diǎn)在于他可以幫助人們理解現(xiàn)有的模型并作出改進(jìn)题涨。當(dāng)構(gòu)建了一個(gè)模型后偎谁,可以運(yùn)行逐步回歸算法找出重要的特征,即使停止那些不重要特征的收集纲堵。
總結(jié)
上面提到的這些線性回歸算法巡雨,我們應(yīng)該怎么選擇呢?一般來說有一點(diǎn)正則項(xiàng)的表現(xiàn)更好席函,因此通常你應(yīng)該避免使用簡(jiǎn)單的線性回歸铐望。嶺回歸是一個(gè)很好的首選項(xiàng),但是如果你的特征僅有少數(shù)是真正有用的茂附,你應(yīng)該選擇Lasso和彈性網(wǎng)絡(luò)正蛙。就像我們討論的那樣,它兩能夠?qū)o用特征的權(quán)重降為零何之。一般來說跟畅,彈性網(wǎng)絡(luò)的表現(xiàn)要比Lasso好,因?yàn)楫?dāng)特征數(shù)量比樣例的數(shù)量大的時(shí)候溶推,或者特征之間有很強(qiáng)的相關(guān)性時(shí)徊件,Lasso可能會(huì)表現(xiàn)的不規(guī)律。
參考文檔
- 《吳恩達(dá)cs229 課程講義》
- 《機(jī)器學(xué)習(xí)實(shí)戰(zhàn)》
- 機(jī)器學(xué)習(xí)實(shí)戰(zhàn)_線性回歸&邏輯回歸(二)