python機(jī)器學(xué)習(xí)理論與實(shí)戰(zhàn)(四)邏輯回歸
從這節(jié)算是開始進(jìn)入“正規(guī)”的機(jī)器學(xué)習(xí)了吧,之所以“正規(guī)”因?yàn)樗_始要建立價(jià)值函數(shù)(cost function),接著優(yōu)化價(jià)值函數(shù)求出權(quán)重,然后測試驗(yàn)證。這整套的流程是機(jī)器學(xué)習(xí)必經(jīng)環(huán)節(jié)。今天要學(xué)習(xí)的話題是邏輯回歸,邏輯回歸也是一種有監(jiān)督學(xué)習(xí)方法(supervised machine learning)。邏輯回歸一般用來做預(yù)測,也可以用來做分類,預(yù)測是某個(gè)類別^.^!線性回歸想比大家都不陌生了,y=kx+b,給定一堆數(shù)據(jù)點(diǎn),擬合出k和b的值就行了,下次給定X時(shí),就可以計(jì)算出y,這就是回歸。而邏輯回歸跟這個(gè)有點(diǎn)區(qū)別,它是一種非線性函數(shù),擬合功能頗為強(qiáng)大,而且它是連續(xù)函數(shù),可以對(duì)其求導(dǎo),這點(diǎn)很重要,如果一個(gè)函數(shù)不可求導(dǎo),那它在機(jī)器學(xué)習(xí)用起來很麻煩,早期的海維賽德(Heaviside)階梯函數(shù)就因此被sigmoid函數(shù)取代,因?yàn)榭蓪?dǎo)意味著我們可以很快找到其極值點(diǎn),這就是優(yōu)化方法的重要思想之一:利用求導(dǎo),得到梯度,然后用梯度下降法更新參數(shù)。
下面來看看邏輯回歸的sigmoid函數(shù),如(圖一)所示:

(圖一)
(圖一)中上圖是sigmoid函數(shù)在定義域[-5,5] 上的形狀,而下圖是在定義域[-60,60]上的形狀,由這兩個(gè)圖可以看出,它比較適合做二類的回歸,因?yàn)閲?yán)重兩級(jí)分化。Sigmoid函數(shù)的如(公式一)所示:

(公式一)
現(xiàn)在有了二類回歸函數(shù)模型,就可以把特征映射到這個(gè)模型上了,而且sigmoid函數(shù)的自變量只有一個(gè)Z,假設(shè)我們的特征為X=[x0,x1,x2…xn]。令
,當(dāng)給定大批的訓(xùn)練樣本特征X時(shí),我們只要找到合適的W=[w0,w1,w2…wn]來正確的把每個(gè)樣本特征X映射到sigmoid函數(shù)的兩級(jí)上,也就是說正確的完成了類別回歸就行了,那么以后來個(gè)測試樣本,只要和權(quán)重相乘后,帶入sigmoid函數(shù)計(jì)算出的值就是預(yù)測值啦,很簡單是吧。那怎么求權(quán)重W呢?
要計(jì)算W,就要進(jìn)入優(yōu)化求解階段咯,用的方法是梯度下降法或者隨機(jī)梯度下降法。說到梯度下降,梯度下降一般對(duì)什么求梯度呢?梯度是一個(gè)函數(shù)上升最快的方向,沿著梯度方向我們可以很快找到極值點(diǎn)。我們找什么極值?仔細(xì)想想,當(dāng)然是找訓(xùn)練模型的誤差極值,當(dāng)模型預(yù)測值和訓(xùn)練樣本給出的正確值之間的誤差和最小時(shí),模型參數(shù)就是我們要求的。當(dāng)然誤差最小有可能導(dǎo)致過擬合,這個(gè)以后再說。我們先建立模型訓(xùn)練誤差價(jià)值函數(shù)(cost function),如(公式二)所示:

(公式二)
(公式二)中Y表示訓(xùn)練樣本真實(shí)值,當(dāng)J(theta)最小時(shí)的所得的theta就是我們要求的模型權(quán)重,可以看出J(theta)是個(gè)凸函數(shù),得到的最小值也是全局最小。對(duì)其求導(dǎo)后得出梯度,如(公式三)所示:

(公式三)
由于我們是找極小值,而梯度方向是極大值方向,因此我們?nèi)∝?fù)號(hào),沿著負(fù)梯度方向更新參數(shù),如(公式四)所示:

(公式四)
按照(公式四)的參數(shù)更新方法,當(dāng)權(quán)重不再變化時(shí),我們就宣稱找到了極值點(diǎn),此時(shí)的權(quán)重也是我們要求的,整個(gè)參數(shù)更新示意圖如(圖二)所示:

(圖二)
原理到此為止邏輯回歸基本就說完了,下面進(jìn)入代碼實(shí)戰(zhàn)階段:
from numpy import *
def loadDataSet():
dataMat = []; labelMat = []
fr = open('testSet.txt')
for line in fr.readlines():
lineArr = line.strip().split()
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
labelMat.append(int(lineArr[2]))
return dataMat,labelMat
def sigmoid(inX):
return 1.0/(1+exp(-inX))
上面兩個(gè)函數(shù)分別是加載訓(xùn)練集和定義sigmoid函數(shù),都比較簡單。下面發(fā)出梯度下降的代碼:
def gradAscent(dataMatIn, classLabels):
dataMatrix = mat(dataMatIn) #convert to NumPy matrix
labelMat = mat(classLabels).transpose() #convert to NumPy matrix
m,n = shape(dataMatrix)
alpha = 0.001
maxCycles = 500
weights = ones((n,1))
for k in range(maxCycles): #heavy on matrix operations
h = sigmoid(dataMatrix*weights) #matrix mult
error = (labelMat - h) #vector subtraction
weights = weights + alpha * dataMatrix.transpose()* error #matrix mult
return weights
梯度下降輸入訓(xùn)練集和對(duì)應(yīng)標(biāo)簽,接著就是迭代跟新參數(shù),計(jì)算梯度,然后更新參數(shù),注意倒數(shù)第二句就是按照(公式三)和(公式四)來更新參數(shù)。
為了直觀的看到我們得到的權(quán)重是否正確的,我們把權(quán)重和樣本打印出來,下面是相關(guān)打印代碼:
def plotBestFit(weights):
import matplotlib.pyplot as plt
dataMat,labelMat=loadDataSet()
dataArr = array(dataMat)
n = shape(dataArr)[0]
xcord1 = []; ycord1 = []
xcord2 = []; ycord2 = []
for i in range(n):
if int(labelMat[i])== 1:
xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])
else:
xcord2.append(dataArr[i,1]); ycord2.append(dataArr[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.0, 3.0, 0.1)
y = (-weights[0]-weights[1]*x)/weights[2]
ax.plot(x, y)
plt.xlabel('X1'); plt.ylabel('X2');
plt.show()
打印的效果圖如(圖三)所示:

(圖三)
可以看出效果蠻不錯(cuò)的,小錯(cuò)誤是難免的,如果訓(xùn)練集沒有錯(cuò)誤反而危險(xiǎn),說到這基本就說完了,但是考慮到這個(gè)方法對(duì)少量樣本(幾百的)還行,在實(shí)際中當(dāng)遇到10億數(shù)量級(jí)時(shí),而且特征維數(shù)上千時(shí),這種方法很恐怖,光計(jì)算梯度就要消耗大量時(shí)間,因此要使用隨機(jī)梯度下降方法。隨機(jī)梯度下降算法和梯度下降算法原理一樣,只是計(jì)算梯度不再使用所有樣本,而是使用一個(gè)或者一小批來計(jì)算梯度,這樣可以減少計(jì)算代價(jià),雖然權(quán)重更新的路徑很曲折,但最終也會(huì)收斂的,如(圖四)所示

(圖四)
下面也發(fā)出隨機(jī)梯度下降的代碼:
def stocGradAscent1(dataMatrix, classLabels, numIter=150):
m,n = shape(dataMatrix)
weights = ones(n) #initialize to all ones
for j in range(numIter):
dataIndex = range(m)
for i in range(m):
alpha = 4/(1.0+j+i)+0.0001 #apha decreases with iteration, does not
randIndex = int(random.uniform(0,len(dataIndex)))#go to 0 because of the constant
h = sigmoid(sum(dataMatrix[randIndex]*weights))
error = classLabels[randIndex] - h
weights = weights + alpha * error * dataMatrix[randIndex]
del(dataIndex[randIndex])
return weights
最后也給出一個(gè)分類的代碼,只要把閾值設(shè)為0.5,大于0.5劃為一類,小于0.5劃為另一類就行了,代碼如下:
def classifyVector(inX, weights): prob = sigmoid(sum(inX*weights)) if prob > 0.5: return 1.0 else: return 0.0
總結(jié):
優(yōu)點(diǎn):計(jì)算量不高,容易實(shí)現(xiàn),對(duì)現(xiàn)實(shí)數(shù)據(jù)也很容易描述
缺點(diǎn):很容易欠擬合,精度可能也會(huì)不高
參考文獻(xiàn):
[1] machine learning in action. Peter Harrington
[2] machine learning.Andrew Ng
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 基于Pytorch實(shí)現(xiàn)邏輯回歸
- PyTorch實(shí)現(xiàn)多維度特征輸入邏輯回歸
- pytorch實(shí)現(xiàn)邏輯回歸
- PyTorch線性回歸和邏輯回歸實(shí)戰(zhàn)示例
- python sklearn庫實(shí)現(xiàn)簡單邏輯回歸的實(shí)例代碼
- python實(shí)現(xiàn)邏輯回歸的方法示例
- python編寫Logistic邏輯回歸
- python代碼實(shí)現(xiàn)邏輯回歸logistic原理
- Python利用邏輯回歸模型解決MNIST手寫數(shù)字識(shí)別問題詳解
- Python實(shí)現(xiàn)的邏輯回歸算法示例【附測試csv文件下載】
- python 牛頓法實(shí)現(xiàn)邏輯回歸(Logistic Regression)
- Python利用邏輯回歸分類實(shí)現(xiàn)模板
- pytorch使用nn.Moudle實(shí)現(xiàn)邏輯回歸
相關(guān)文章
Python批量上傳文件信息到服務(wù)器的實(shí)現(xiàn)示例
在進(jìn)行軟件測試的過程中,經(jīng)常會(huì)需要準(zhǔn)備一批數(shù)據(jù),本文主要介紹了Python批量上傳文件信息到服務(wù)器的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2023-12-12
使用Python腳本來控制Windows Azure的簡單教程
這篇文章主要介紹了使用Python腳本來控制Windows Azure的簡單教程,由于微軟官方提供了Python SDK,使得用戶自己用Python控制Azure成為了可能,需要的朋友可以參考下2015-04-04
關(guān)于Numpy生成數(shù)總結(jié)(隨機(jī)整數(shù)randint,固定步長arange,分布)
這篇文章主要介紹了關(guān)于Numpy生成數(shù)總結(jié)(隨機(jī)整數(shù)randint,固定步長arange,分布),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
GPU狀態(tài)監(jiān)測?nvidia-smi?命令的用法詳解
這篇文章主要介紹了GPU狀態(tài)監(jiān)測?nvidia-smi?命令的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
tensorflow模型保存、加載之變量重命名實(shí)例
今天小編就為大家分享一篇tensorflow模型保存、加載之變量重命名實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-01-01
Python使用Turtle圖形函數(shù)畫圖顏色填充實(shí)例
這篇文章主要介紹了Python使用Turtle圖形函數(shù)畫圖顏色填充實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08

