1. 程式人生 > >《機器學習實戰》Logistics迴歸學習心得

《機器學習實戰》Logistics迴歸學習心得

第一次接觸機器學習的東西,現在看到《機器學習實戰》第五章,分享一下學習心得

Logistics迴歸就是為了找一條能夠進行盡最大能力進行分類的擬合線,包括直線和曲線,但是要符合函式,也就是說這條線可以用函式進行表達,不然不能夠進行分類。


如上圖所示,要用一條直線將綠色的原點與紅色的框點進行分成兩類,很明顯,無法用一條直線能夠將他們完全正確的進行分類,因此需要找到一條擬合線盡最大限度進行分類,使得誤差最小。如下圖所示:


演算法比較簡單,書中的實現程式碼也比較好理解,用的事Python語言,在這裡主要講解下書中程式碼的實現方式,因為有幾個人來請教我說演算法大概知道,但是書中的程式碼沒看懂。其實書中的程式碼主要以矩陣的方式處理。

其中從檔案中獲取原始資料的程式碼很簡單,不做詳細說明,貼圖即可:

原始資料:


最後一列0和1代表型別,例如1代表綠色的圓點,0代表紅色的框點,如果你缺少這個資料檔案可以評論區回覆我

LoadDataSet函式:

  1. def loadDataSet():  
  2.     dataMat=[];labelMat=[]  
  3.     fr=open('testSet.txt')  
  4.     for line in fr.readlines():  
  5.         lineArr=line.strip().split()  
  6.         dataMat.append([1.0,float(lineArr[
    0]),float(lineArr[1])])  
  7.         labelMat.append(int(lineArr[2]))  
  8.     return dataMat,labelMat  

由於要擬合一條直線,所以假設該直線為a+bx+cy=0。其中a為常數,其他的不說也應該知道,之所以dataMat第一個數為1.0,因為我們要擬合的直線的引數為(a,b,c),其實就是假設a*1.0+b*x+c*y=0,因此dataMat第一個數為1.0,其他兩個不解釋了。而labelsMat就是型別了。因此得到返回值是:


現在講一下分類函數了,先來一波程式碼:

  1. def gradAscent(dataMat,labelMat):  
  2.     dataMatrix=mat(dataMat)  
  3.     labelMatrix=mat(labelMat).transpose()  
  4.     m,n=shape(dataMatrix)  
  5.     alpha=0.001
  6.     maxCycle=500
  7.     weights=ones((n,1))  
  8.     for k in range(maxCycle):  
  9.         h=sigmod(dataMatrix*weights)  
  10.         error=(labelMatrix-h)  
  11.         weights=weights+alpha*dataMatrix.transpose()*error  
  12.     return weights  
其中mat函式是將陣列轉變為矩陣,因此dataMat和labelsMat已經轉為矩陣形式,方便進行矩陣乘法計算。這個函式就是求解(a,b,c)三個數。weights初始化為(1,1,1),假設dataMatrix某一行為(1,x,y),則dataMatirx與weights的乘積結果就是1+x+y,因此dataMatrix與weights第一次的乘積結果就是:

他們的結果:1.0+x+y有大於0的,也有小於0的,也有等於0的,現在的假設這條直線函式為1+x+y=0,因為weights初始化為(1,1,1)嘛,所以當上面的結果大於0時候也就是(x,y)在直線的上方,等於0說明該店(x,y)在直線上,小於0說明該店(x,y)在該直線的下方,因此現在要判斷是否有錯,因為labelsMat中只有0和1兩種型別,所以要將1+x+y的結果進行二值化,這時候就是Sigmiod函式的作用,函式為:

  1. def sigmod(inX):  
  2.     return1.0/(1+exp(-inX))  

也就是:


該曲線圖是盜圖,所以將就著看吧,這裡講下該曲線,該曲線就是將大於0的數趨向於1,小於0的數趨向於0,因此,上面的1+x+y中,如果大於0,也就是在擬合線的上方,這結果為1,在擬合線的下方或者在曲線上則結果為0,這樣就可以得到一個利用初始擬合線計算之後的1+x+y的結果集,結果集只包含了0和1,跟labelsMat差不多,知識labelsMat的0和1是正確的分類,而h中的0和1是利用weights中的引數的擬合線進行計算的分類,不一定正確,所以需要對weights中的引數(a,b,c)進行逐次趨近。

error利用labelsMat-h,也就是用已經有正確分類的減去用weights引數的擬合線進行計算的估計分類進行相減,這樣就會出現(正確分類,估計分類)有(0,0)、(0,1)、(1,0)、(1,1)四種,結果error中就有三種類型:-1,0,1。-1表示(0,1),也就是本應該在正確擬合線的下方,可是用該擬合線計算之後,該點卻在擬合線的上方,0表示分類正確,1表示(1,0),本應該在正確擬合線上方的,卻在該擬合線的下方,因此需要對擬合線(a,b,c)的引數進行調整:

  1. weights=weights+alpha*dataMatrix.transpose()*error  

比如上面的調整利用隨機梯度上升的演算法進行調整a、b和c,然後再重複計算error,直到weights中的引數的擬合線能夠正確分類,也就是當h與labelsMat相等,error全部為0時候,該擬合線為最優擬合線,達到分類效果