天天看點

Python機器學習Logistic回歸

一,Logistic回歸基本原理

Logistic Regression和Linear Regression的原理是相似的。原理可如下描述:

(1)找一個合适的預測函數(Andrew Ng的公開課中稱為hypothesis),一般表示為h函數,該函數就是我們需要找的分類函數,它用來預測輸入資料的判斷結果。這個過程時非常關鍵的,需要對資料有一定的了解或分析,知道或者猜測預測函數的“大概”形式,比如是線性函數還是非線性函數。

(2)構造一個Cost函數(損失函數),該函數表示預測的輸出(h)與訓練資料類别(y)之間的偏差,可以是二者之間的差(h-y)或者是其他的形式。綜合考慮所有訓練資料的“損失”,将Cost求和或者求平均,記為J(θ)函數,表示所有訓練資料預測值與實際類别的偏差。

(3)顯然,J(θ)函數的值越小表示預測函數越準确(即h函數越準确),是以這一步需要做的是找到J(θ)函數的最小值。找函數的最小值有不同的方法,Logistic Regression實作時有的是梯度下降法(Gradient Descent)。

二,具體過程

1,構造預測函數

Logistic Regression雖然名字裡帶“回歸”,但是它實際上是一種分類方法,用于兩分類問題(即輸出隻有兩種)。根據第二章中的步驟,需要先找到一個預測函數(h),顯然,該函數的輸出必須是兩個值(分别代表兩個類别),是以利用了Logistic函數(或稱為Sigmoid函數),函數形式為:

Python機器學習Logistic回歸

對應的函數圖像是一個取值在0和1之間的S型曲線(圖1)。

Python機器學習Logistic回歸

接下來需要确定資料劃分的邊界類型,對于圖2和圖3中的兩種資料分布,顯然圖2需要一個線性的邊界,而圖3需要一個非線性的邊界。接下來我們隻讨論線性邊界的情況。

Python機器學習Logistic回歸
Python機器學習Logistic回歸

對于線性邊界的情況,邊界形式如下:

Python機器學習Logistic回歸

構造預測函數為:

Python機器學習Logistic回歸

hθ(x)函數的值有特殊的含義,它表示結果取1的機率,是以對于輸入x分類結果為類别1和類别0的機率分别為:

Python機器學習Logistic回歸
2,構造Cost函數

課程中直接給出了Cost函數及J(θ)函數如式(5)和(6),但是并沒有給出具體的解釋,隻是說明了這個函數來衡量h函數預測的好壞是合理的。

Python機器學習Logistic回歸
Python機器學習Logistic回歸

實際上這裡的Cost函數和J(θ)函數是基于最大似然估計推導得到的(回顧數理統計中最大似然估計)。下面詳細說明推導的過程。(4)式綜合起來可以寫成:

Python機器學習Logistic回歸

取似然函數:

Python機器學習Logistic回歸

對數似然函數為:

Python機器學習Logistic回歸

最大似然估計就是要求得使l(θ)取最大值時的θ,其實這裡可以使用梯度上升法求解,求得的θ就是要求的最佳參數。将J(θ)取為(6)式,即:

Python機器學習Logistic回歸

因為乘了一個負的系數-1/m,是以J(θ)取最小值時的θ為要求的最佳參數。

3,梯度下降法求J(θ)的最小值

求J(θ)的最小值可以使用梯度下降法,根據梯度下降法可得θ的更新過程:

Python機器學習Logistic回歸

式中為α學習步長,下面來求偏導:

Python機器學習Logistic回歸

上式求解過程中用到如下的公式:

Python機器學習Logistic回歸

是以,(11)式的更新過程可以寫成:

Python機器學習Logistic回歸

因為式中α本來為一常量,是以1/m一般将省略,是以最終的θ更新過程為:

Python機器學習Logistic回歸

另外,補充一下,3.2節中提到求得l(θ)取最大值時的θ也是一樣的,用梯度上升法求(9)式的最大值,可得:

Python機器學習Logistic回歸

觀察上式發現跟(14)是一樣的,是以,采用梯度上升發和梯度下降法是完全一樣的,這也是《機器學習實戰》中采用梯度上升法的原因。

三,Python算法實作

梯度上升法求最佳回歸系數

首先,資料取自《機器學習實戰》中的資料,部分資料如下:

-0.017612   14.053064   0
-1.395634   4.662541    1
-0.752157   6.538620    0
-1.322371   7.152853    0
0.423363    11.054677   0
0.406704    7.067335    1
           

先定義函數來擷取數去,然後定義分類函數Sigmoid函數,最後利用梯度上升法求解回歸系數θ。建立一個logRegres.py檔案,輸入如下代碼:

from numpy import *
#構造函數來擷取資料
def loadDataSet():
	dataMat=[];labelMat=[]
	fr=open('machinelearninginaction/Ch05/testSet.txt')
	for line in fr.readlines():
    	lineArr=line.strip().split()
    	dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])])#特征資料集,添加1是構造常數項x0
    	labelMat.append(int(lineArr[-1]))#分類資料集
	return dataMat,labelMat

def sigmoid(inX):
	return 1/(1+exp(-inX))

def gradAscent(dataMatIn,classLabels):
	dataMatrix=mat(dataMatIn) #(m,n)
	labelMat=mat(classLabels).transpose() #轉置後(m,1)
	m,n=shape(dataMatrix)
	weights=ones((n,1)) #初始化回歸系數,(n,1)
	alpha=0.001 #定義步長
	maxCycles=500 #定義最大循環次數
	for i in range(maxCycles):
    	h=sigmoid(dataMatrix * weights) #sigmoid 函數
    	error=labelMat - h #即y-h,(m,1)
    	weights=weights + alpha * dataMatrix.transpose() * error #梯度上升法
	return weights
           

于是得到了回歸系數。接下來根據回歸系數畫出決策邊界,定義作圖函數:

def plotBestFit(weights):
import matplotlib.pyplot as plt
dataMat,labelMat=loadDataSet()
n=shape(dataMat)[0]
xcord1=[];ycord1=[]
xcord2=[];ycord2=[]
for i in range(n):
    if labelMat[i]==1:
        xcord1.append(dataMat[i][1])
        ycord1.append(dataMat[i][2])
    else:
        xcord2.append(dataMat[i][1])
        ycord2.append(dataMat[i][2])
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(xcord1,ycord1,s=30,c='red',marker='s')
ax.scatter(xcord2,ycord2,s=30,c='green')
x=arange(-3,3,0.1)
y=(-weights[0,0]-weights[1,0]*x)/weights[2,0] #matix
ax.plot(x,y)
plt.xlabel('X1')
plt.ylabel('X2')
plt.show()
           
Python機器學習Logistic回歸