梯度下降法求解logisitic回歸及其python代碼實現

01 logisitic回歸與梯度下降法

logisitic回歸是因變數是分類的回歸模型或演算法,它實際上是一種分類方法,主要用於兩分類問題(即輸出只有兩種,分別代表兩個類別),所以利用了Logistic函數(或稱為Sigmoid函數),函數形式為:

g(z)=frac{1}{1+{e}^{-z}}

其中,其中, z={	heta }_{0}{x }_{0}+{	heta }_{1}{x }_{1}+...+{	heta }_{n}{x }_{n} ,向量表示為: Z={Theta}^{T}X

梯度下降法則是一種最優化演算法,它是用迭代的方法求解目標函數得到最優解,是在最小二乘法cost function(成本函數)的基礎上,利用梯度迭代求出局部最優解。在這裡關於梯度下降法不做過多介紹,相關資料已經很多且後邊還會分析,對其的理解借用一位網友的描述吧:

梯度下降法被比喻成一種方法,一個人蒙著眼睛去找從山坡到溪谷最深處的路。 他看不到地形圖,所以只能沿著最陡峭的方向一步一步往前走。

每一步的大小(也就是梯度)與地勢陡峭的程度成正比。 如果地勢很陡峭,他就走一大步,因為他相信他仍在高出,還沒有錯過溪谷的最低點。如果地勢比較平坦,他就走一小步。

這時如果再走大步,可能會與最低點失之交臂。 如果真那樣,他就需要改變方向,重新朝著溪谷的最低點前進。 他就這樣一步一步的走啊走,直到有一個點走不動了,因為路是平的了,於是他卸下眼罩,已經到了谷底深處。

02 用梯度下降法求解logisitic回歸

用梯度下降法求解logisitic回歸的步驟為:

(1)構建損失函數

預測函數為:

函數hθ(x)的值有特殊的含義,它表示結果取1的概率,因此對於輸入x分類結果為類別1和類別0的概率分別為:

(1)式綜合起來可以寫成:

取似然函數為:

對數似然函數為:

最大似然估計就是求使l(θ)取最大值時的θ,將J(θ)取為下式,即:

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

註:在這裡為什麼加了個係數-1/m,編者翻閱了相關資料,因為不加的話,說是不能用梯度下降法(而是梯度上升法),所以要加負號,而1/m代表了樣本平均。

最終得到:

(2)梯度下降法求解最小值

採用與線性回歸中一樣的梯度下降法來確定θ的值,即設置一個合適的學習率α之後,同步更新所有j=1 to n:

θ更新過程可以寫成:

重複更新步驟,直到損失函數的值收斂為止。

03 python代碼的實現

在這裡採用了python2.7 版本,並分為兩大步驟:構建梯度下降法函數與創建數據函數。而經過上面的推導,對我們編程最有用的不是那些過程,而是得到的結果,即最後一個公式,因此,將圍繞最後得到的梯度下降法求解公式來構建函數。

-*- coding: UTF-8 -*-import numpy as np #科學計算(矩陣)包import random #生成隨機數的包#梯度下降演算法函數,x/y是輸入變數,theta是參數,alpha是學習率,m是實例,numIterations梯度下降迭代次數def gradientDescent(x, y, theta, alpha, m, numIterations): xTrans = x.transpose() #矩陣轉置 #在1-numIterations之間for循環 for i in range(0,numIterations): hypothesis = np.dot(x,theta) #矩陣相乘 loss = hypothesis - y #預測值減去實際值 # avg cost per example (the 2 in 2*m doesn"t really matter here. # But to be consistent with the gradient, I include it) cost = np.sum(loss **2)/(2 * m) #成本函數:loss方差的平均加總,在這裡採用了常用的成本函數,而非logistic特有的 print("Iteration %d | Cost: %f" % (i, cost)) # avg gradient per example gradient = np.dot(xTrans, loss) / m #計算梯度 # update theta = theta - alpha * gradient #參數theta的計算,即更新法則 return theta#創建數據,numPoints實例數,bias加一些偏倚或偏差,variance:方差def genData(numPoints,bias,variance): x = np.zeros(shape=(numPoints,2)) #生成0矩陣,shape表示矩陣的形狀,參數1是行,後邊是列 y = np.zeros(shape=(numPoints)) #對x、y的0矩陣填充數值 for i in range(0,numPoints): x[i][0] = 1 #第i行第1列全部等於1 x[i][1] = i # 第i行第2列等於i y[i] = (i + bias) + random.uniform(0,1) * variance # 第i行第2列等於i+bias(偏倚),再加,0-1的隨機數,以及方差 return x, yx, y = genData(100, 25, 10) #傳入參數print "x:"print xprint "y:"print ym, n = np.shape(x) #檢查x的行列數,是否一致numIterations = 100000alpha = 0.0005 #學習率,不能太大也不能太小theta = np.ones(n) #初始化theta = gradientDescent(x, y, theta, alpha, m, numIterations)print(theta)

可以根據不同的數據,利用gradientDescent()函數來求解。


推薦閱讀:

數學 · 神經網路(二)· BP(反向傳播)
Python · 神經網路(三*)· 網路
【啄米日常】3:一個不負責任的Keras介紹(下)
CTR預估[四]: Algorithm-LR Bias和Q分布
深度學習(Deep Learning)基礎概念7:搭建多層神經網路的python實現

TAG:机器学习 | Python |