邏輯回歸是線性回歸的變形送滞,看了很多機(jī)器學(xué)習(xí)書籍是晨,吳恩達(dá)的課程對(duì)線性回歸和邏輯回歸的講解非常清晰竟稳,原理性和推導(dǎo)都很好理解。
我一直認(rèn)為好老師標(biāo)準(zhǔn)不在于擁有多深?yuàn)W的知識(shí)沦补,而在于能否良好的傳授乳蓄,不僅僅是知識(shí),而是學(xué)習(xí)的思路夕膀。獨(dú)孤九劍還需要好老師傳授才能發(fā)揚(yáng)廣大~虚倒。
網(wǎng)易:http://study.163.com/course/courseMain.htm?courseId=1004570029
coursera原版:https://www.coursera.org/learn/machine-learning
筆記包括:
課程理論學(xué)習(xí)
算法實(shí)現(xiàn):Octave
算法應(yīng)用:Spark監(jiān)控事件根源分析。我從事的IT運(yùn)營(yíng)支撐領(lǐng)域产舞,每天產(chǎn)生大量的監(jiān)測(cè)異常事件魂奥,很多事件是關(guān)聯(lián)引發(fā),而不是根源問題易猫,從成千上百個(gè)事件中定位耻煤,找到根源一直是十分令人頭疼的事情。嘗試通過(guò)邏輯回歸准颓,結(jié)合人工打標(biāo)注的方式哈蝇,根據(jù)歷史數(shù)據(jù),對(duì)新產(chǎn)生的事件進(jìn)行預(yù)測(cè)攘已,是根源的可能性炮赦,幫助快速的定位。例如:網(wǎng)絡(luò)故障/不穩(wěn)定样勃,引發(fā)一些列的應(yīng)用訪問異常吠勘、業(yè)務(wù)(訂單/產(chǎn)品)異常等事件,隨著IT系統(tǒng)規(guī)模的增大/快速變化峡眶,建立專家?guī)烊ナ崂硪?guī)則不適合剧防,通過(guò)邏輯回歸算法做分類是一種嘗試。?
涉及到推導(dǎo)部分的數(shù)學(xué)基礎(chǔ)辫樱,主要是微積分和矩陣計(jì)算峭拘,可以看看以下課程前幾章:
麻省理工的微積分,會(huì)求導(dǎo)就行: http://study.163.com/course/courseMain.htm?courseId=1003649073
麻省理工的線性代數(shù),會(huì)矩陣計(jì)算棚唆,求逆轉(zhuǎn)置:?http://study.163.com/course/courseMain.htm?courseId=1003649037
1. 理論學(xué)習(xí)
1.1 概覽
線性回歸是通過(guò)連續(xù)數(shù)據(jù)預(yù)測(cè)連續(xù)結(jié)果,而邏輯回歸是通過(guò)連續(xù)數(shù)據(jù)心例,預(yù)測(cè)離散結(jié)果宵凌。說(shuō)白話就是一堆數(shù)據(jù),得出分類結(jié)果(如yes/no)止后。邏輯回歸的結(jié)果 0<=h(x)<=1瞎惫。
0和1的二分法則適用于很多場(chǎng)景,例如垃圾郵件監(jiān)測(cè)译株、活躍用戶監(jiān)測(cè)瓜喇、分類。舉個(gè)栗子:如果獲取到醫(yī)療有關(guān)惡性腫瘤的數(shù)據(jù)歉糜,得到數(shù)據(jù)特征:腫瘤大小(Tumor Size)乘寒,以及醫(yī)生判定結(jié)果1:惡性,0:良性匪补;建立起模型(計(jì)算函數(shù))就可以實(shí)現(xiàn)預(yù)測(cè)伞辛,已知腫瘤大小,預(yù)測(cè)是否惡性夯缺。這是最簡(jiǎn)化的單變量(特征)的預(yù)測(cè)蚤氏。
1.2 與線性回歸的差異
假如我們使用線性回歸Linear Regression,看看是否可以建立起一個(gè)函數(shù)h(x)=θ'X做預(yù)測(cè):
通過(guò)線性回歸函數(shù)踊兜,可以(計(jì)算)畫一根線竿滨,得出結(jié)論當(dāng)h(x)>=0.5就可以判定是惡性腫瘤。如果存在異常值后捏境,線性回歸會(huì)擬合新的數(shù)據(jù)于游,出現(xiàn)了新的線(上圖藍(lán)色線),那么當(dāng)使用0.5閾值時(shí)典蝌,就會(huì)出現(xiàn)很差勁的效果曙砂,上圖看至少有幾個(gè)點(diǎn)出現(xiàn)判斷錯(cuò)誤。所以線性回歸并不適合骏掀,所以需要做些修改鸠澈,這就引入了邏輯回歸 Logistic Regression.
1.3 邏輯回歸公式推導(dǎo)
簡(jiǎn)書不好編輯數(shù)學(xué)公式,只好貼圖了~截驮。
(1) 假設(shè)數(shù)據(jù)抽取的特征為X(i)={x1,x2,...xn}, 那么一系列的數(shù)據(jù)建立的就是m行n列的矩陣X笑陈,其中列一般是n,意味著n個(gè)特征葵袭。
(2) 假設(shè)θ是回歸參數(shù)向量(一階矩陣)涵妥,θ={θ0,θ1,θ2...,θn},是n+1坡锡,對(duì)應(yīng)n個(gè)特征蓬网。具體是神馬暫不用理解.
(3) 假設(shè)h(x)是預(yù)測(cè)函數(shù)窒所。線性回歸是h(x)=θ'X,?θ'是θ的轉(zhuǎn)置,最后預(yù)測(cè)函數(shù)h(x)范圍是[0,1]帆锋。
結(jié)果為y(i)在{0,1}范圍吵取。需要建立的預(yù)測(cè)函數(shù)h(x)
由于最終取值是0,1,這里一般選擇了一個(gè)回歸函數(shù)锯厢,也叫sigmoid函數(shù)?
z=θ'X
g(z)=1/(1+e^-z)
選擇g(z)作為回歸函數(shù)皮官,很大程度就是因?yàn)橹笖?shù)方式圖形,最后是在[0,1]之間实辑,而且很好理解的是當(dāng)z>>0 遠(yuǎn)遠(yuǎn)大于0時(shí)捺氢,h(x)≈ 1,或者是z>0 剪撬,h(x) >0.5 預(yù)測(cè)值=1摄乒;相反則是0,很好的符合[0,1]的判斷婿奔。
匯總一下缺狠,回歸函數(shù)就是:
h(x)=1/(1+e^-θ'X)
怎么理解這個(gè)函數(shù)呢?可以理解為當(dāng)輸入x后萍摊,y=1的可能性概率挤茄。如果h(x)=0.7,那么意味這y=1的可能性概率高冰木。也可以換成概率論理解h(x)=P(y=1 | X;θ)穷劈,已知參數(shù)θ和X,y=1的概率踊沸。
邏輯回歸函數(shù)h(x)=1/(1+e^-θ'X)歇终,我們?nèi)绻蠼饬嘶貧w參數(shù)θ,那么代入新的x值逼龟,就可以實(shí)現(xiàn)預(yù)測(cè)了评凝,如上圖x=[1; 2(腫瘤大小)]; 假設(shè)θ=[3;4],那么:
z=θ'X=3*1+4*2=11
h(x)=g(z)=1/(1+e^-11)=0.99998
那么很遺憾腺律,有0.99998的概率是惡性腫瘤y=1奕短。暢想下,醫(yī)療行業(yè)的數(shù)據(jù)積累如果能夠共享匀钧,建立數(shù)據(jù)集翎碑,就可以通過(guò)技術(shù)手段做一些輔助決策判斷,提升效率~
1.4 代價(jià)函數(shù)
得到回歸函數(shù)之斯,我們就要計(jì)算代價(jià)函數(shù)日杈,通過(guò)代價(jià)函數(shù),計(jì)算對(duì)應(yīng)的θ值,就可以建立h(x)了莉擒。
吳恩達(dá)老師從線性回歸的代價(jià)函數(shù)酿炸,推導(dǎo)出了邏輯回歸的新代價(jià)函數(shù)。我們先看看線性回歸的代價(jià)函數(shù)J(θ)
那么用這個(gè)線性回歸的代價(jià)函數(shù)涨冀,有什么問題呢梁沧?可以用,但是效果不理想蝇裤。將h(x)代入上述公式,得出下圖左側(cè)的“non-convex”圖看频鉴,代價(jià)函數(shù)J(θ)圖形是非凸函數(shù)栓辜,直白點(diǎn)來(lái)說(shuō),就是有很多切線(導(dǎo)數(shù))為0的點(diǎn)垛孔。按照線性回歸那章說(shuō)的梯度下降法藕甩,就是要尋找導(dǎo)數(shù)為0的點(diǎn)。也就是說(shuō)如果代價(jià)函數(shù)不是凸函數(shù)周荐,那么就存在局部的最低點(diǎn)狭莱,效果不理想,會(huì)欠擬合(不準(zhǔn)確)概作。所以我們期望J(θ)是一個(gè)convex 凸函數(shù)腋妙,碗底就是要求解的點(diǎn)(全局最小值)。
其實(shí)回想下h(x)=1/(1+e^-θ'X) 該函數(shù)就不是一個(gè)線性函數(shù)讯榕,對(duì)應(yīng)的代價(jià)函數(shù)J(θ)必然也不是線性的骤素。
簡(jiǎn)化后就是:
Cost(h(x),y)=-ylog(h(x))-(1-y)log(1-h(x))
J(θ)出來(lái)后,這個(gè)就是一個(gè)線性凸函數(shù)愚屁,可以看到很巧妙的將y=1時(shí)-log(h(x)), y=0時(shí)-log(1-h(x))結(jié)合起來(lái)济竹,因?yàn)閥={0,1},因?yàn)闊o(wú)論y是那個(gè)取值霎槐,必然是線性的對(duì)數(shù)函數(shù)log送浊。
1.5 梯度下降求解θ
對(duì)于J(θ)函數(shù)求最小值,梯度下降的算法就是對(duì)J(θ)求導(dǎo).
詳細(xì)的求解過(guò)程如下圖丘跌,介紹幾個(gè)微積分求導(dǎo)的公式有助于理解:?
(uv)'=u'v+uv';
(u/v)'=(u'v-uv')/v^2; ?當(dāng)u=1時(shí)袭景,常量導(dǎo)數(shù)=0 ?(1/(1+e^-x))'=-(1+e^-x)'/(1+e^-x)^2;
?(u+v)'=u'+v';
1.6 算法小結(jié)
基本上邏輯回歸Logistic Regression方法是很有效的分類方法,在進(jìn)行實(shí)際生產(chǎn)中碍岔,可以快速的應(yīng)用并得到比較不錯(cuò)的效果浴讯。
由于單類別(二分)的計(jì)算,實(shí)際上在此基礎(chǔ)上可以進(jìn)行多分類劃分蔼啦,就需要加一些步驟榆纽。這個(gè)在下面算法實(shí)現(xiàn)中會(huì)提到。
2. 算法實(shí)現(xiàn)
使用開源的Octave(有錢的可以用Matlab),這是一個(gè)非常優(yōu)秀的數(shù)學(xué)計(jì)算工具奈籽,安裝簡(jiǎn)單饥侵,適用與demo和早期算法模型驗(yàn)證。畢竟一開始就動(dòng)手寫大段Java/Python代碼去驗(yàn)證一個(gè)模型和算法衣屏,代價(jià)較大躏升。
這里用到線性代數(shù),矩陣計(jì)算的方式來(lái)進(jìn)行狼忱,基本上機(jī)器學(xué)習(xí)大多基于矩陣進(jìn)行計(jì)算膨疏。線性代數(shù)不好的同學(xué),看下麻省線性代數(shù)前幾章就能理解了: http://study.163.com/course/courseMain.htm?courseId=1003649037
下載代碼
這里使用了測(cè)試數(shù)據(jù)是入學(xué)考試成績(jī)钻弄,x1是第一次成績(jī)佃却,x2是第二次成績(jī)
2.1 計(jì)算過(guò)程
計(jì)算過(guò)程大致如下:
1. 已知數(shù)據(jù)X,結(jié)果y窘俺。
2. 隨機(jī)初始化θ
3. 計(jì)算代價(jià)函數(shù)J(θ)饲帅,得到代價(jià)值
4. 梯度下降,得到J(θ)導(dǎo)數(shù)瘤泪,更新θ
5. 重復(fù)2-4灶泵,遍歷N次。
6. 求得θ对途,獲取h(x)函數(shù)赦邻,進(jìn)行預(yù)測(cè)。
簡(jiǎn)單起見实檀,這里省略掉了交叉驗(yàn)證環(huán)節(jié)深纲。
2.2 代價(jià)函數(shù)
代價(jià)函數(shù)lrCost.m
function [J,grad]=lrCost(theta,X,y)?
? m=length(y);?
? X=[ones(m,1),X];? %新增x0列=1hx=X*theta;? ??
? h=zeros(m,1);?
? h=sigmoid(hx);? %g(z)=1/(1+e^-z)? ? ??
? Jtmp=0;?
? for i=1:m,? ?
? ? Jtmp=Jtmp+(-y(i)*log(h(i))-(1-y(i))*log(1-h(i)));?
? end;?
J=(1/m)*Jtmp;? ? ?%計(jì)算cost函數(shù)J(θ)
grad=(1/m)*X'*(h-y);??% 求導(dǎo)J,梯度下降
end?
回歸函數(shù)g(z), sigmoid.m
function g=sigmoid(z)?
[m n]=size(z);?
g=zeros(size(z));?
for i=1:m,? ?
? for j=1:n,? ? ?
? ? g(i,j)=1/(1+e^(-z(i,j)));? ?
? end;?
end;
end
好了現(xiàn)在就可以開始使用了,請(qǐng)保證Octave的目錄與代碼同目錄
data=load('ex2data1.txt');
X=data(:,1:2);
y=data(:,3);
initial_theta=[0;0;0];
options = optimset('GradObj', 'on', 'MaxIter', 400);
[theta, cost] = fminunc(@(t)(lrCost(t, X, y)), initial_theta, options);
調(diào)用octave的內(nèi)建函數(shù)fminunc();來(lái)獲得最優(yōu)的theta和最小的cost劲妙。大致含義就是使用梯度下降湃鹊,執(zhí)行400次cost函數(shù)lrCost,求得最后的θ和代價(jià)J(θ)镣奋。
如上圖币呵,計(jì)算得出θ =[-25.16;0.20;0.20];? h(x)=-25.16+0.20*x1+0.20*x1;
寫個(gè)預(yù)測(cè)程序predict.m
function y=predict(theta,X)?
X=[ones(size(X,1),1),X];?
disp(X);?
y=sigmoid(X*theta);?
y=y>0.5;
end
預(yù)測(cè)值>0.5就是y=1;
3. 算法應(yīng)用
先占坑,后面在用spark寫個(gè)應(yīng)用侨颈。
spark 官方git 示例:?https://github.com/apache/spark/blob/master/examples/src/main/java/org/apache/spark/examples/ml/JavaLogisticRegressionSummaryExample.java