假設現在有一些點,我們用一條直線對這些點進行擬合(該線稱為最佳擬合直線),這個擬合過程就稱作回歸。
利用Logistic回歸進行分類的主要思想是:根據現有數據對分類邊界線建立回歸公式,依次進行分類。
Logistic回歸的一般過程
(1)收集數據:采用任意方法收集數據
(2)准備數據:由於需要進行距離計算,因此要求數據類型為數值型。另外,結構化數據格式則最佳
(3)分析數據:采用任意方法對數據進行分析
(4)訓練算法:大部分時間將用於訓練,訓練的目的是為了找到最佳的分類回歸系數
(5)測試算法:一旦訓練步驟完成,分類將會很快
(6)使用算法:首先,我們需要輸入一些數據,並將其轉換成對應的結構化數值;接着,
基於訓練好的回歸系數就可以對這些數值進行簡單的回歸計算,判定他們屬於哪個類別;在這之后,我們就可以
在輸出的類別上做一些其他分析工作
優化算法:梯度上升
優缺點:
優點:計算代價不高,易於理解和實現
缺點:容易欠擬合,分類精度可能不高。
使用數據類型:數值型和標稱型數據
我們想要的函數應該是,能接受所有的輸入然后預測出類別。例如,在兩個類的情況下,
上述函數輸出0或1,我們之前也接觸過這種性質的函數,該函數稱為海維賽德階躍函數,
或者直接稱為單位節約函數,然而,這些函數的問題在於:該函數在跳躍點上從0瞬間跳躍到1,這個瞬間過程有時很難處理,
幸好,另一個函數也有類似的性質,且數學上更易理解,這就是sigmoid函數。
因此為了實現Logistic回歸分類器,我們可以在每個特征上都乘以一個回歸系數,然后把所有的結果相加,
將這個總和帶入sigmoid函數中,進而得到一個范圍為0-1之間的數值,任何大於0.5的數據被分為1類,小於0.5的即被歸入0類。
所以,Logistic回歸也可以被看成是一種概率估計。
確定了分類器的函數形式后,現在的問題就變成了:最佳回歸系數是多少?如何確定他們的大小?
邏輯斯蒂回歸采用梯度上升法找到最優值,我們經常聽到的是梯度下降法,實際上,只是公式中的加法變成減法,
梯度上升算法用來求函數的最大值,而梯度下降法用來求函數的最小值
訓練算法:使用梯度上升算法找到最佳參數,在數據集上,我們將通過使用梯度上升算法找到最佳回歸系數,
也就是擬合logitic回歸模型的最佳參數。
梯度上升法的偽代碼如下:
每個回歸系數初始化為1
重復R次:
計算整個數據集的梯度
使用alpha*gradient更新回歸系數的向量
返回回歸系數
1 from numpy import * 2 3 #打開文本文件並逐行讀取 4 def loadDataSet(): 5 dataMat = []; labelMat = [] 6 fr = open('testSet.txt') 7 for line in fr.readlines(): 8 lineArr = line.strip().split() 9 dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) 10 labelMat.append(int(lineArr[2])) 11 return dataMat,labelMat 12 13 #sigmod函數 14 def sigmoid(inX): 15 return 1.0/(1+exp(-inX)) 16 17 #梯度上升算法 18 19 def gradAscent(dataMatIn, classLabels): 20 dataMatrix = mat(dataMatIn) #convert to NumPy matrix 21 labelMat = mat(classLabels).transpose() #convert to NumPy matrix 22 m,n = shape(dataMatrix) 23 #目標移動的步長 24 alpha = 0.001 25 #迭代次數 26 maxCycles = 500 27 weights = ones((n,1)) 28 #在for循環迭代完成后,將返回訓練好的回歸系數。 29 for k in range(maxCycles): #heavy on matrix operations 30 h = sigmoid(dataMatrix*weights) #matrix mult 31 error = (labelMat - h) #vector subtraction 32 weights = weights + alpha * dataMatrix.transpose()* error #matrix mult 33 return weights 34 #畫出數據集和logistic回歸最佳擬合直線函數 35 def plotBestFit(weights): 36 import matplotlib.pyplot as plt 37 dataMat,labelMat=loadDataSet() 38 dataArr = array(dataMat) 39 n = shape(dataArr)[0] 40 xcord1 = []; ycord1 = [] 41 xcord2 = []; ycord2 = [] 42 for i in range(n): 43 if int(labelMat[i])== 1: 44 xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2]) 45 else: 46 xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) 47 fig = plt.figure() 48 ax = fig.add_subplot(111) 49 ax.scatter(xcord1, ycord1, s=30, c='red', marker='s') 50 ax.scatter(xcord2, ycord2, s=30, c='green') 51 x = arange(-3.0, 3.0, 0.1) 52 #最佳擬合直線 53 y = (-weights[0]-weights[1]*x)/weights[2] 54 ax.plot(x, y) 55 plt.xlabel('X1'); plt.ylabel('X2'); 56 plt.show()
梯度上升算法在每次更新回歸系數時都需要遍歷整個數據集,該方法在處理
100個左右的數據集尚可,但如果有數十億樣本和成千上萬的特征,那么該
方法的計算復雜度就太高了。一種改進方法是依次僅用一個樣本點來更新回
歸系數,該方法稱為隨機梯度上升算法。由於可以在新樣本到來時對分類器
進行增量式更新,因而隨機梯度上升算法是一個在線學習算法。與‘在線學習’
相對應,依次處理所有數據被稱作是“批處理”
'''
隨機梯度上升算法可以寫成如下的偽代碼:
所有回歸系數初始化為1
對數據集中每個樣本
計算該樣本的梯度
使用alpha*gradient更新回歸系數值
返回回歸系數
1 def stocGradAscent0(dataMatrix, classLabels): 2 m,n = shape(dataMatrix) 3 alpha = 0.01 4 weights = ones(n) #initialize to all ones 5 for i in range(m): 6 h = sigmoid(sum(dataMatrix[i]*weights)) 7 error = classLabels[i] - h 8 weights = weights + alpha * error * dataMatrix[i] 9 return weights
改進梯度上升算法
第一處改進:一方面,alpha在每次迭代的時候都會調整,這樣可以緩解數據波動或者高頻波動。
另外,雖然alpha會隨着迭代次數不斷減小,但永遠不會減小到0,這是因為式子中還存在一個常
數項。必須這樣做的原因是為了保證在多次迭代后新數據仍然具有一定的影響。
第二處改進是這里通過隨機選取樣本來更新回歸系數。這種方法將減少周期的波動,
此外,改進算法還增加了一個迭代次數作為第3個參數,如果該參數沒有給定的話,算法將默認迭代150次。
如果給定,那么算法將按照新的參數值進行迭代
1 def stocGradAscent1(dataMatrix, classLabels, numIter=150): 2 m,n = shape(dataMatrix) 3 weights = ones(n) #initialize to all ones 4 for j in range(numIter): 5 dataIndex = range(m) 6 for i in range(m): 7 alpha = 4/(1.0+j+i)+0.0001 #apha decreases with iteration, does not 8 #使用logistic回歸進行分類並不需要做很多宮祖宗,所需要的知識把測試集上的每個特征向量 9 # 乘以最優化方法的來的回歸系數,再將該乘積結果求和,最后輸入到sigmoid函數中即可。 10 randIndex = int(random.uniform(0,len(dataIndex)))#go to 0 because of the constant 11 h = sigmoid(sum(dataMatrix[randIndex]*weights)) 12 error = classLabels[randIndex] - h 13 weights = weights + alpha * error * dataMatrix[randIndex] 14 del(randIndex) 15 return weights 16 17 dataArr,labelMat=loadDataSet() 18 weights=stocGradAscent1(array(dataArr),labelMat) 19 plotBestFit(weights)
小結:logistic回歸的目的是尋找一個非線性函數sigmoid的最佳擬合參數,求解過程可以由最優化算法來完成。在最優化算法中,最常用的就是梯度上升算法,而梯度上升算法又可以簡化為隨機梯度上升算法
隨機梯度上升算法與梯度上升算法的效果相當,但占用更少的計算資源,此外,隨機梯度上升是一個在線算法,它可以在新數據到來時就完成參數更新,而不需要重新讀取整個數據集來進行批處理運算。
機器學習的一個重要問題就是如何處理缺失數據。這個問題沒有標准的答案,取決於實際應用中的需求。現有的一些解決方案,每種方案都各有優缺點。