1.sigmoid函數
當x爲0時,Sigmoid函數值爲0.5。隨着x的增大,對應的sigmiod值將逼近於1; 而隨着x的減小,Sigmoid值將逼近於0。任何sigmoid值大於0.5的數據,都被分類爲1類,任何sigmoid值小於0.5的數據,都被分類爲0類。以下是sigmoid函數在兩種不同尺度的座標系下的圖解:
可以看出來,只要橫座標的尺度足夠大,在x=0處,sigmoid函數看起來就像個階躍函數,具有比較好的分類特性。
2.梯度法求函數最值
所謂的梯度其實就是某個方向唉,沿着梯度的方向,可以最快尋找到函數的最值。其中梯度上升方向是最快找到函數最大值的方向,而梯度下降則是最快找到函數最小值的方向。不懂梯度的建議再翻一翻高數的課本!這裏直接給出梯度法更新邏輯迴歸中權重的迭代公式:
這裏的α是每次迭代的步長,α後面那一塊就是所謂的梯度。這個公式會一直被迭代,直到達到某個條件爲止。
3.logisic迴歸梯度上升算法
以下分析一下logistic迴歸的梯度上升的代碼:
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
##這裏inX可以是矩陣運算,當inX是向量是,則exp(inX)是對inX中的每個元素取指數,然後返回一個與inX等長的向量。另外,這裏的X是inX=w0*x0+w1*x1+w2*x2...wn*xn##
def sigmod(inX):
return 1/(1+np.exp(-inX))
def gradAscent(dataMatIn,classLabels):
dataMatrix=np.mat(dataMatIn)
labelMat=np.mat(classLabels).transpose()
m,n=np.shape(dataMatrix)
alpha=0.001
maxCycles=500
weights=np.ones((n,1))
h=sigmod(dataMatrix*weights)
#數據集中的每個樣本都會更新權重一次,而這裏還設置最大循環次數,即循環整個數據集的次數
for k in range(maxCycles):
h=sigmod(dataMatrix*weights)
error=labelMat-h
#加號後面一塊我認爲可以理解成每個樣本對某個特徵的誤差的貢獻之和
weights=weights+alpha*dataMatrix.transpose()*error
return weights
上面的算法更新權重的話,會有一個問題,那就是運算量太大,所以有對上述算法的一種更新,那就是隨機梯度上升算法,具體的執行代碼:
def stocGradAscent1(dataMatrix,classLabels,numIter=150):
m,n=np.shape(dataMatrix)
weights=np.ones(n)
for j in range(numIter):
dataIndex=range(m)
for i in range(m):
alpha=4/(1.0+j+i)+0.01
randIndex=int(np.random.uniform(0,len(dataIndex)))
h=sigmod(sum(dataMatrix[randIndex]*weights))
error=classLabels[randIndex]-h
weights=weights+alpha*error*dataMatrix[randIndex]
del(dataIndex[randIndex])
return weights
這個算法每次會隨機抽取數據集中的一個樣本去更新權值,同時,在更新步長也會進行更新。步長的更新可以緩解數據波動和高頻波動。
總結:努力啊!