Logistic Regression
最近在Github上學習機器學習,主要是在黃海廣博士的項目下學習吳恩達的機器學習教程,做下筆記。
如有需要:連結自取(click)
預測函數 Predict Function
分類問題中的y值隻有0或1,是以當使用線性回歸在做分類問題時,y值就會超過或者低于1,這顯然不是我們想要的。

是以預測函數需要一些限制(限制感覺有點奇妙),這裡就引入了邏輯(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
數學分析:
上面為該函數的圖像保證了預測值在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
假設隻有兩個特征,他們的分布如下圖所示:
模型為 θ T X = θ 0 + θ 1 x 1 + θ 2 x 2 \theta^TX=\theta_0+\theta_1x_1+\theta_2x_2 θTX=θ0+θ1x1+θ2x2,可知 θ T X = 0 \theta^TX=0 θTX=0是一條分界線,上面預測為1,下面預測為0。
這裡需要弄清楚的就是,判定邊界并不是資料的特征,而是這個預測函數,這個模型的特征,為什麼這麼說呢?因為如果建立模型的時候,不再是這個模型(二次,三次都可以),判定邊界就會随之改變。
代價函數 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=1mCost(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函數圖
數學分析:
當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)等等。
取 m a x ( h θ ( i ) ( X ) ) max(h_\theta^{(i)}(X)) max(hθ(i)(X))的最大的i,将其分為i類。
正則化 Regularization
正則化是為了防止出現過拟合的問題,也就是說避免讓判定邊界都十分接近每一個點(overfitting or high varance),是以我們需要加上一個懲罰系數λ。
代價函數:
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=1mCost(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)