前一篇博客介紹了線性迴歸,縱使可以撇開 y 是離散值得事實,給定 x, 使用線性迴歸對 y 進行預測,可以找到很多示例說明這種預測結果不會很好,比如說,房價不可能隨着面積大小線性增長。並且當我們知道 y 的取值範圍在{0,1}時,預測結果大於 1 或者小於 0 已經沒有了意義。怎樣解決這個問題?可以使用邏輯迴歸。
邏輯迴歸於線性迴歸有很多相似之處,最大的不同在於他們的因變量不同。線性迴歸用來預測連續變量的值,而邏輯迴歸是用來求分類的,可以用來解決二分類問題,也可以用於解決多分類問題,但是解決二分類問題更爲常見。
稱爲logistic 函數或者 sigmod 函數。函數圖像如下所示:
假設有:
更爲一般的形式 :
最大似然函數爲:
上式求對數得:
對
所以隨機梯度下降規則爲 :
實驗代碼如下 :
# encoding=utf-8
import numpy as np
def gradAscent(dataMatIn, classLabels):
dataMatrix = np.mat(dataMatIn) # 數據列表轉換成矩陣
labelMat = np.mat(classLabels).transpose() # 類標籤列表轉換成矩陣
m, n = np.shape(dataMatrix) # 得到dataMatrix矩陣大小
alpha = 0.001 # 每次上升的步長
maxCycles = 500 # 迭代次數
weights = np.ones((n, 1))
for k in range(maxCycles):
h = sigmoid(dataMatrix * weights) # 計算假設函數h(列向量)
error = (labelMat - h) # 類標籤和假設函數的誤差
weights = weights + alpha * dataMatrix.transpose() * error # 對weights進行迭代更新
return weights
def sigmoid(inX):
return 1.0 / (1 + np.exp(-inX))
def loadDataSet():
dataMat = []
labelMat = []
fr = open('../resources/lr.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
if __name__ == '__main__':
data, lable = loadDataSet()
weights = gradAscent(data, lable)
print(weights)
源代碼以及實驗數據存儲在github