1. Logistic迴歸
1.1 基本原理
Logistic Regression 是一種分類模型,其基本思路是尋找超平面把數據區分開,因此其基本思想就是尋找超平面,也就求多元係數的問題,這裏採取了梯度下降法來求係數。邏輯迴歸步驟如下:
列出迴歸方程,估計迴歸係數
迴歸方程:Y=WX
1.2 Sigmoid函數
Sigmoid函數是閾值函數,什麼作用呢?一般對於分類問題,總以結果大於零或者小於0來分是屬於哪一類,但是在實際問題中,二元類一般劃分爲0類或者1類,也就是數據集的標籤爲0或者1。那麼直接使用結果來劃分類別,以小於0爲0類,以大於0爲1類,這樣處理的話,不利於後面的求解損失函數,因此需要將其轉換,最後轉化後的結果能落在0,1之間,因此我們就使用了閾值函數,f(t) = 1/(1+e-t),其值域爲(0, 1)。該閾值函數使用後,結果如下
1.3 梯度下降法
梯度下降法,只需要求解一階導數,因此計算的成本比較小,這在大規模的數據集上應用比較廣泛。梯度下降法的含義是通過當前點的梯度方向尋找新的迭代點,並從當前點移動到新的迭代點繼續重複此過程,一直到尋找到最優解,或者到最大迭代次數。
梯度下降法的流程如下:
1.4 代碼實現
定義了一個logisticregression類,類中定義如下:
定義了一個參數數組self.W,訓練數據得到的參數就存放於該數組;
定義了sigmoid函數def sig(self, t)
定義了一個訓練函數train(self,X,y,alpha, iters),其中將偏置也合併到W數組中,X爲輸入數據,不過其在fit函數中經過處理,在最後一列添加了一列全爲1的常數項,目的是爲了將偏置也一併歸到W中去,alpha爲訓練步長,iters爲最大迭代次數。
定義了擬合函數fit(self, X, y),其中X爲原始輸入數據,y爲標籤,X經過處理,添加了一列全爲1的常數項。fit中調用了train()函數進行擬合。
定義了預測函數predict(self, X),這裏X也要添加常數項,然後與訓練得出的參數進行矩陣運算,得出結果。(代碼很簡單,就不寫註解了)
class LogisticRegression:
def __init__(self):
self.W = []
def sig(self, t):
return 1/(1 + np.exp(-t))
def train(self, X, y, alpha, iters):
w = np.random.rand(X.shape[1])
w = w.reshape(-1, 1)
for i in range(iters):
h = self.sig(X*w)
err = y - h
delta = X.T * err
w += alpha * delta
if i % 100 == 0:
print('error is ', self.error_rate(h, y))
return w
def error_rate(self, h, y):
sum_err = 0
sum_err -= y.T * np.log(h) + (1 - y.T)*np.log(1 - h)
return sum_err
def fit(self, X, y):
X = np.c_[X, np.ones(X.shape[0])]
X = np.mat(X)
y = np.mat(y.reshape(-1, 1))
self.W = self.train(X, y, 0.01, 1000)
def predict(self, X):
X = np.c_[X, np.ones(X.shape[0])]
X = np.mat(X)
h = self.sig(X * self.W)
h = map(lambda x:0 if x<0.5 else 1, h)
h = list(h)
return h
1.5 測試代碼
def load_data():
data = load_iris()
x = data.data
y = data.target
x = x[y < 2]
y = y[y < 2]
return x, y
if __name__ == '__main__':
x, y = load_data()
model = LogisticRegression()
model.fit(x, y)
y_pred = model.predict(x)
label = np.c_[y, y_pred]
print(label)