一、算法
1、logistic回歸用回歸思想的分類算法
利用Logistic回歸進行分類的主要思想是:根據現(xiàn)有數據對分類邊界線建立回歸公式,以此進行分類。
優(yōu)點:計算代價不高,易于理解和實現(xiàn)。
缺點:容易欠擬合,分類精度可能不高。
適用數據類型:數值型和標稱型。
2、Sigmoid函數
在Logistic回歸中,我們需要的函數是,能接受所有的輸入然后預測類別。
LR一般應用Sigmoid函數:

當x為0時,Sigmoid函數值為0.5,隨著x的增大,對應的Sigmoid函數值將逼近于1;而隨著x的減小,Sigmoid函數值將逼近于0。橫坐標足夠大時,Sigmoid函數看起來像一個階躍函數。

為了實現(xiàn)LR回歸分類器,我們在每個特征上都乘以一個回歸系數,然后把所有的結果值相加,即z=w0x0+w1x1+w2x2+...+wnxn,代入到Sigmoid函數中,進而得到一個范圍在0~1之間的數值。大于0.5的數據被分入1類,小于0.5即被分入0類。
二、目標函數
因為Sigmoid函數是非凸函數,如果采用平方誤差和作為目標優(yōu)化函數,則無法直接使用梯度上升法。于是我們應用極大似然估計法估計模型參數。
設:

得到目標函數:

對L(W)求極大值,得到w回歸系數的估計值。
三、最優(yōu)化方法
梯度上升法
確定分類器函數形式之后,現(xiàn)在問題變成了:找到最佳回歸系數,從而使分類器盡可能地準確。
梯度上升法基于的思想是:要找到某函數的最大值,最好的方法是沿著該函數的梯度方向探尋。
迭代公式如下:
w:w+aDwf(w)
f為目標函數,D為梯度,a為步長。停止的條件是迭代次數達到某個指定值或者算法達到某個允許的誤差范圍。
類比梯度下降法:w:w-aDwf(w)
四、訓練算法
偽代碼如下:
(1)每個回歸系數初始化為1
(2)重復R次:
計算整個數據集的梯度
使用alpha*gradient更新回歸系數的向量
(3)返回回歸系數
下面是梯度上升算法的具體實現(xiàn)邏輯斯諦回歸:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
% matplotlib inline
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import math
# 生成鳶尾花數據
def create_data():
iris = load_iris()
df=pd.DataFrame(iris.data,columns=iris.feature_names)
df['label']=iris.target
df.columns=['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
data=np.array(df.iloc[:100,[0,1,-1]])
return data[:,:2], data[:,-1]
X,y=create_data()
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.3)
# 梯度上升法更新權值向量w
class LogisticRegressionClassifier:
def __init__(self, max_iter=200, learning_rate=0.01):
self.max_iter=max_iter # 迭代次數
self.learning_rate = learning_rate # 學習率
def sigmoid(self,x):
return 1/(1+math.exp(-x)) #sigmoid函數1/1+e(-x)
def data_matrix(self, X):
data_mat=[]
for d in X:
data_mat.append([1.0,*d]) #解包, 第一列增加1,其實為計算b
return data_mat
def fit(self, X, y):
data_mat=self.data_matrix(X)
self.weights = np.zeros((len(data_mat[0]),1),dtype=np.float32)
for iter_ in range(self.max_iter):
for i in range(len(X)):
result = self.sigmoid(np.dot(data_mat[i],self.weights))
error = y[i]-result #偏差
self.weights += self.learning_rate*error* np.transpose([data_mat[i]]) #梯度上升進行更新w
def score(self, X_test, y_test):
# 計算測試樣本預測正確率
right=0
X_test=self.data_matrix(X_test)
for x, y in zip(X_test, y_test):
result = np.dot(x, self.weights)
if (result>0 and y==1) or (result<0 and y==0):
right += 1
return right/len(X_test)
lr_clf = LogisticRegressionClassifier()
lr_clf.fit(X_train, y_train)
lr_clf.score(X_test,y_test)
x_ponits = np.arange(4, 8)
y_fit = -(lr_clf.weights[1]*x_ponits + lr_clf.weights[0])/lr_clf.weights[2]
plt.plot(x_ponits, y_fit, c='r')
plt.scatter(X[:50,0],X[:50,1], label='0')
plt.scatter(X[50:,0],X[50:,1], label='1')
plt.legend()

scikit-learn實例:
sklearn.linear_model.LogisticRegression
solver參數決定了我們對邏輯回歸損失函數的優(yōu)化方法,有四種算法可以選擇,分別是:
a) liblinear:使用了開源的liblinear庫實現(xiàn),內部使用了坐標軸下降法來迭代優(yōu)化損失函數。
b) lbfgs:擬牛頓法的一種,利用損失函數二階導數矩陣即海森矩陣來迭代優(yōu)化損失函數。
c) newton-cg:也是牛頓法家族的一種,利用損失函數二階導數矩陣即海森矩陣來迭代優(yōu)化損失函數。
d) sag:即隨機平均梯度下降,是梯度下降法的變種,和普通梯度下降法的區(qū)別是每次迭代僅僅用一部分的樣本來計算梯度,適合于樣本數據多的時候