利用Logistics Regression羅杰斯特回歸預(yù)測疝氣病馬死亡率航徙。
1. 收集數(shù)據(jù)
收集的數(shù)據(jù)劃分成訓(xùn)練集和測試集炕泳,每個(gè)樣例包括21個(gè)特征和1個(gè)類別標(biāo)簽斧散。
2. 準(zhǔn)備數(shù)據(jù)
要求數(shù)據(jù)類型為:數(shù)值型搭独;另外鸿市,結(jié)構(gòu)化數(shù)據(jù)格式最佳节值。
用Python解析文本文件并填充缺失值徙硅。
缺失值的填充方式:
--使用可用特征的均值來填補(bǔ);
--使用特殊值來填補(bǔ)搞疗,如-1嗓蘑;
--忽略有缺失值的樣本须肆;
--使用相似樣本的均值填補(bǔ)缺失值;
--使用另外的機(jī)器學(xué)習(xí)算法預(yù)測缺失值桩皿;
不同的處理方式之間各有優(yōu)劣豌汇,同時(shí),具體問題需要具體分析泄隔,沒有普適的處理方法拒贱。
3. 分析數(shù)據(jù)
可視化并觀察數(shù)據(jù)。
4. 訓(xùn)練算法
使用優(yōu)化算法佛嬉,找到最佳的系數(shù)逻澳。
數(shù)據(jù)樣本之間服從羅杰斯特分布。分布函數(shù)為:
函數(shù)定義:
def sigmod(x):
? ? return 1/(1+exp(-x))
Sigmod函數(shù):
優(yōu)化算法暖呕,主要是梯度算法(下降or上升)斜做。
A. 梯度上升算法
設(shè)定循環(huán)迭代次數(shù),權(quán)重系數(shù)的每次更新是通過計(jì)算所有樣本得出來的湾揽。當(dāng)訓(xùn)練集過于龐大時(shí)瓤逼,不利于計(jì)算。
alpha:步長库物,又稱為學(xué)習(xí)率霸旗。
def gradAscent(dataMatIn, classLabels):
? ? dataMat= mat(dataMatIn)
? ? labelMat= mat(classLabels).transpose()
? ? m, n= shape(dataMat)
? ? alpha= 0.001
? ? maxCycles= 500
? ? weights= ones((n,1))
? ? for k in range(maxCycles):
? ? ? ? h= sigmod(dataMat*weights)
? ? ? ? error= (labelMat- h)
? ? ? ? weights= weights+ alpha*dataMat.transpose()*error#省去了數(shù)學(xué)推導(dǎo)式
? ? return weights
B. 隨機(jī)梯度上升
對(duì)梯度上升算法進(jìn)行改進(jìn)。權(quán)重系數(shù)的每次更新通過訓(xùn)練集的每個(gè)記錄計(jì)算得到艳狐。
可以在新樣本到來時(shí)對(duì)分類器進(jìn)行增量式更新定硝,因而,隨機(jī)梯度上升算法是一個(gè)在線學(xué)習(xí)算法毫目。
這種參數(shù)更新算法:容易受到噪聲點(diǎn)的影響蔬啡。在大的波動(dòng)停止后,還有一些小的周期性波動(dòng)镀虐。
def stocGradAscent0(dataMat,classLabels):
? ? m, n=shape(dataMat)
? ? alpha= 0.01
? ? weights= ones(n)
? ? for i in range(m):
? ? ? ? h= sigmod(sum(dataMat[i]*weights))
? ? ? ? error= classLabels[i] - h
????????weights= weights+ alpha*error*dataMat[i]
? ? return weights
C. 改進(jìn)的隨機(jī)梯度上升算法
學(xué)習(xí)率:變化箱蟆。隨著迭代次數(shù)的增多,逐漸變下刮便。
權(quán)重系數(shù)更新:設(shè)定迭代次數(shù)空猜,每次更新選擇的樣例是隨機(jī)的(不是依次選的)。
def stocGradAscent1(dataMat, classLabels, numIter=150):
? ? m,n= shape(dataMat)
? ? weights= ones(n)
? ? for jin range(numIter):#迭代次數(shù)
? ? ? ? dataIndex= range(m)
? ? ? ? for i in range(m):#依據(jù)訓(xùn)練集更新權(quán)重系數(shù)
? ? ? ? ? ? alpha= 4/(1.0+j+i) + 0.1
? ? ? ? ? ? randIndex= int(random.uniform(0,len(dataIndex)))#確保隨機(jī)性
? ? ? ? ? ? h= sigmod(sum(dataMat[randIndex]*weights))?
????????????error= classLabels[randIndex] - h
????????????weights= weights+ alpha*error*dataMat[randIndex]
? ? ? ? ? ? del dataIndex[randIndex]
? ? return weights
分類算法
def classifyVector(inX, weights):
? ? prob= sigmod(sum(inX*weights))
? ? if prob> 0.5:
? ? ? ? return 1.0
? ? else:
? ? ? ? return 0.0
5. 測試算法
為了量化回歸效果恨旱,使用錯(cuò)誤率作為觀察指標(biāo)辈毯。根據(jù)錯(cuò)誤率決定是否回退到訓(xùn)練階段,通過改變迭代次數(shù)和步驟等參數(shù)來得到更好的回歸系數(shù)搜贤。
def colicTest():
? ? frTrain= open('horseColicTraining.txt')
? ? frTest= open('horseColicTest.txt')
? ? trainSet= []; trainLabels= []
? ? for line in frTrain.readlines():
? ? ? ? line= line.strip().split('\t')
? ? ? ? lineArr= []
? ? ? ? for i in range(21):
? ? ? ? ? ? lineArr.append(float(line[i]))
? ? ? ? trainSet.append(lineArr)
? ? ? ? trainLabels.append(float(line[21]))
? ? trainWeights= stocGradAscent1(array(trainSet),trainLabels)
? ? errorCnt= 0; numTestVec= 0.0
? ? for line in frTest.readlines():
? ? ? ? numTestVec+= 1
? ? ? ? currLine= line.strip().split('\t')
? ? ? ? lineArr= []
? ? ? ? for i in range(21):
? ? ? ? ? ? lineArr.append(float(currLine[i]))
? ? ? ? if int(classifyVector(array(lineArr),trainWeights)) != int(currLine[21]):
? ? ? ? ? ? errorCnt+= 1
? ? errorRate= float(errorCnt)/numTestVec
????print ("the error rate of this test is: %f" % errorRate)
? ? return errorRate
通過多次測試谆沃,取平均,作為該分類器錯(cuò)誤率:
def multiTest():
? ? numTests= 10; errorSum= 0.0
? ? for k in range(numTests):
? ? ? ? errorSum+= colicTest()
? ? print ("after %d iterations the average error rate is: %f" %(numTests,float(errorSum)/numTests))
運(yùn)行結(jié)果:
錯(cuò)誤率為36.1%仪芒。
6. 小結(jié)
優(yōu)點(diǎn):計(jì)算代價(jià)不高唁影,易于理解和實(shí)現(xiàn)耕陷;
缺點(diǎn):容易欠擬合,分類進(jìn)度可能不高据沈;
使用數(shù)據(jù)類型:數(shù)值型和標(biāo)稱型數(shù)據(jù)哟沫。
下一章:準(zhǔn)備把羅杰斯特回歸設(shè)計(jì)的梯度上升算法的數(shù)學(xué)推導(dǎo),梳理一下并證明锌介。
To Be Continued!