假設如今有一些點,咱們用一條直線對這些點進行擬合(該線稱爲最佳擬合直線),這個擬合過程就稱做迴歸。
利用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更新迴歸係數的向量
返回迴歸係數git
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次。
若是給定,那麼算法將按照新的參數值進行迭代app
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的最佳擬合參數,求解過程能夠由最優化算法來完成。在最優化算法中,最經常使用的就是梯度上升算法,而梯度上升算法又能夠簡化爲隨機梯度上升算法dom
隨機梯度上升算法與梯度上升算法的效果至關,但佔用更少的計算資源,此外,隨機梯度上升是一個在線算法,它能夠在新數據到來時就完成參數更新,而不須要從新讀取整個數據集來進行批處理運算。機器學習
機器學習的一個重要問題就是如何處理缺失數據。這個問題沒有標準的答案,取決於實際應用中的需求。現有的一些解決方案,每種方案都各有優缺點。函數