天天看點

Logistic Regression---自我實作和學習筆記

Logistic Regression

最近在Github上學習機器學習,主要是在黃海廣博士的項目下學習吳恩達的機器學習教程,做下筆記。

如有需要:連結自取(click)

預測函數 Predict Function

分類問題中的y值隻有0或1,是以當使用線性回歸在做分類問題時,y值就會超過或者低于1,這顯然不是我們想要的。

Logistic Regression---自我實作和學習筆記

是以預測函數需要一些限制(限制感覺有點奇妙),這裡就引入了邏輯(sigmod)函數g(z),如下。

h θ ( X ) = g ( θ T X ) = 1 1 + e − θ T X h_\theta(X)=g(\theta^TX)=\frac{1}{1+e^{-\theta^TX}} hθ​(X)=g(θTX)=1+e−θTX1​

g ( z ) = 1 1 + e − z g(z)=\frac{1}{1+e^{-z}} g(z)=1+e−z1​

Logistic Regression---自我實作和學習筆記

數學分析:

上面為該函數的圖像保證了預測值在0到1之間。

h θ ( X ) > = 0.5 → θ T X > = 0 → h_\theta(X)>=0.5\to\theta^TX>=0\to hθ​(X)>=0.5→θTX>=0→預測y為1。

h θ ( X ) < 0.5 → θ T X < 0 → h_\theta(X)<0.5\to\theta^TX<0\to hθ​(X)<0.5→θTX<0→預測y為0。

代碼分析:

def sigmod(z):
	return 1/(1+np.exp(-z))
           

同時這也是和線性回歸非常不同的一點,邏輯回歸的公式和線性回歸的公式十分相像,但是基本的預測函數是不同的。

判定邊界 Decision Boundary

假設隻有兩個特征,他們的分布如下圖所示:

Logistic Regression---自我實作和學習筆記

模型為 θ T X = θ 0 + θ 1 x 1 + θ 2 x 2 \theta^TX=\theta_0+\theta_1x_1+\theta_2x_2 θTX=θ0​+θ1​x1​+θ2​x2​,可知 θ T X = 0 \theta^TX=0 θTX=0是一條分界線,上面預測為1,下面預測為0。

Logistic Regression---自我實作和學習筆記

這裡需要弄清楚的就是,判定邊界并不是資料的特征,而是這個預測函數,這個模型的特征,為什麼這麼說呢?因為如果建立模型的時候,不再是這個模型(二次,三次都可以),判定邊界就會随之改變。

代價函數 Cost Function

邏輯函數的代價函數:

J ( θ ) = 1 m ∑ i = 1 m C o s t ( h θ ( x ( i ) ) − y ( i ) ) J(\theta)=\frac{1}{m}\sum_{i=1}^mCost(h_\theta(x^{(i)})-y^{(i)}) J(θ)=m1​∑i=1m​Cost(hθ​(x(i))−y(i))

C o s t ( h θ ( x ) , y ) = − y log ⁡ ( h θ ( x ) ) − ( 1 − y ) log ⁡ ( 1 − h θ ( x ) ) Cost(h_\theta(x),y)=-y\log(h_\theta(x))-(1-y)\log(1-h_\theta(x)) Cost(hθ​(x),y)=−ylog(hθ​(x))−(1−y)log(1−hθ​(x))

Cost函數圖

Logistic Regression---自我實作和學習筆記

數學分析:

當y=1,然而預測值接近0時,你所需要付出的代價就非常大;

同理,可了解其他的。

代碼分析:

def Cost(theta,X,y):
	theta=np.matrix(theta.values)
	X=np.matrix(X.values)
	y=np.matrix(y.values)
	first=np.multiply(-y,np.log(sigmod(theta.[email protected])))
	second=np.multiply((1-y),np.log(1-sigmod(theta.[email protected])))
	#這裡都是矩陣計算,first和second相當于将每個訓練元組的Cost算了出來,并且
	#列成一列矩陣,而np.sum()就當于數學公式中的自動求和。
	return np.sum(first-second)/len(X)
           

梯度下降 Gradient Descent

正如前面所說邏輯回歸和線性回歸公式大部分看上去是相同的,比如這裡梯度下降的最後簡化公式。

Repeat{

θ j : = θ j − α ∂ ∂ θ j J ( θ ) = θ j − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta_j:=\theta_j-\alpha\frac{\partial}{\partial\theta_j}J(\theta)=\theta_j-\alpha\frac{1}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_j^{(i)} θj​:=θj​−α∂θj​∂​J(θ)=θj​−αm1​∑i=1m​(hθ​(x(i))−y(i))xj(i)​

}

資料分析:

這與線性回歸的了解相同,也是一步一步的去找到最優解。

代碼分析:

def gradient(theta,X,y):
	#這裡隻是在算J(θ)的梯度
	theta=np.matrix(theta.values)
	X=np.matrix(X.values)
	y=np.matrix(y.values)
	
	parameters=int(theta.ravel().shape[1])
	grad=np.zeros(parameters)
	error=sigmod(X*theta.T)-y
	
	for i in range(parameters):
		term=np.multiply(error,X[:,i])
		grad[i]=np.sum(term)/len(X)
	#自動求和在除以m就好了
	return grad
           
#直接調用函數在尋找最有模型參數
import scipy.optimize as opt
res=opt.fmin_tnc(func=cost,x0=theta,fprime=gradient,args=(X,y))
           

Scipy優化算法 fmin_tnc

Scipy優化算法簡介(click)

fmin_tnc()适用于有限制(再次提到)的多元函數問題,提供梯度資訊,使用截斷牛頓法。

最常使用的參數 介紹
func 優化的目标函數
x0 初值
fprime 提供優化函數func的梯度函數,不然優化函數func必須傳回函數值和梯度,或者設定approx_grad=True
approx_grad 如果設定為True,會給出近似梯度
args 元組,是傳遞給優化函數的參數
傳回值 介紹
x 數組,傳回優化問題的目标值(模型參數)
nfeval 整數,目标優化函數被調用的次數
rc Ruturn Code

多類别分類 Multiclass Classification

當y可以等于1,2,3…時,就需要多類别分類,隻需要将一種情況看作1,另外其他的所有情況都看作0作為一次 h θ ( 1 ) ( X ) h_\theta^{(1)}(X) hθ(1)​(X)就可以了,然後還會存在更多的 h θ ( 2 ) ( X ) h_\theta^{(2)}(X) hθ(2)​(X)等等。

Logistic Regression---自我實作和學習筆記

取 m a x ( h θ ( i ) ( X ) ) max(h_\theta^{(i)}(X)) max(hθ(i)​(X))的最大的i,将其分為i類。

正則化 Regularization

正則化是為了防止出現過拟合的問題,也就是說避免讓判定邊界都十分接近每一個點(overfitting or high varance),是以我們需要加上一個懲罰系數λ。

Logistic Regression---自我實作和學習筆記

代價函數:

J ( θ ) = 1 2 m [ ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 + ∑ j = 1 n θ j 2 ] = 1 m ∑ i = 1 m C o s t ( h θ ( x ( i ) ) ) + 1 2 m ∑ j = 1 n θ j 2 J(\theta)=\frac{1}{2m}[\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})^2+\sum_{j=1}^n\theta_j^2]=\frac{1}{m}\sum_{i=1}^mCost(h_\theta(x^{(i)}))+\frac{1}{2m}\sum_{j=1}^n\theta_j^2 J(θ)=2m1​[∑i=1m​(hθ​(x(i))−y(i))2+∑j=1n​θj2​]=m1​∑i=1m​Cost(hθ​(x(i)))+2m1​∑j=1n​θj2​

梯度下降:

這裡有一個約定,不懲罰系數 θ 0 \theta_0 θ0​

同時懲罰系數不能過大,不然就隻剩 θ 0 \theta_0 θ0​了

Repeat until convergence{

θ 0 : = θ 0 − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x 0 ( i ) \theta_0:=\theta_0-\alpha\frac{1}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_0^{(i)} θ0​:=θ0​−αm1​∑i=1m​(hθ​(x(i))−y(i))x0(i)​

θ j : = θ j − α [ 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x 0 ( i ) + λ m θ j ] \theta_j:=\theta_j-\alpha[\frac{1}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_0^{(i)}+\frac{\lambda}{m}\theta_j] θj​:=θj​−α[m1​∑i=1m​(hθ​(x(i))−y(i))x0(i)​+mλ​θj​]

}

代碼分析:

def Cost(theta,X,y,learningRate):
	theta=np.matrix(theta.values)
	X=np.matrix(X.values)
	y=np.matrix(y.values)
	first=np.multiply(-y,np.log(sigmod(theta.[email protected])))
	second=np.multiply((1-y),np.log(1-sigmod(theta.[email protected]))) 
	reg=(learningRate/(2*len(X))*np.sum(np.power(theta[:,1:theta.shape[1]],2))
	#注意這裡的theta的範圍
	return np.sum(first-second)/len(X)+reg
           
def gradientReg(theta,X,y,learningRate):
	#這裡隻是在算J(θ)的梯度
	theta=np.matrix(theta.values)
	X=np.matrix(X.values)
	y=np.matrix(y.values)
	
	parameters=int(theta.ravel().shape[1])
	grad=np.zeros(parameters)
	error=sigmod(X*theta.T)-y
	
	for i in range(parameters):
		term=np.multiply(error,X[:,i])
		grad[i]=np.sum(term)/len(X)
		if i!=0:
			grad[i]+=learningRate/len(X)*theta[:,i]
			
	return grad
	#同時擁有了目标優化函數和梯度函數就可使用上述的優化方法了。
           

sklearn.linear_model.LogisticRegression

學習連結(click)