邏輯回歸是一種常見的分類算法败去,通常用來處理二分類問題放航。邏輯回歸名字中帶有回歸兩個(gè)字烈拒,卻用于處理分類問題厂僧,是因?yàn)檫壿嫽貧w利用了回歸的思想彤蔽,先利用回歸思想計(jì)算出一個(gè)預(yù)測值销凑,再將該預(yù)測值轉(zhuǎn)化為分為某一類別的概率文兢。利用回歸方法算出來的預(yù)測值的值域是從負(fù)無窮到正無窮的捺球,而概率P的值域是從0到1吕粗,那么如何將預(yù)測值轉(zhuǎn)化為一個(gè)概率值呢债蜜,這里就要利用到sigmoid函數(shù)了梨州,該函數(shù)的表達(dá)式為:
先來簡單看一下該函數(shù)的圖像
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(t):
return 1. / (1. + np.exp(-t))
x_plot = np.linspace(-10., 10., 5000)
y_plot = sigmoid(x_plot)
plt.plot(x_plot, y_plot)
plt.show()
從圖中可以看出祖秒,sigmoid函數(shù)將(-10诞吱, 10)中的元素映射到了區(qū)間(0舟奠, 1)中,實(shí)際上房维,sigmoid函數(shù)能將(?∞沼瘫,+∞)的元素都映射到(0, 1)中咙俩。因此耿戚,想要利用邏輯回歸解決分類問題,我們只需要先利用回歸思想獲得一個(gè)處于(?∞阿趁,+∞)的預(yù)測值膜蛔,再利用sigmoid函數(shù)轉(zhuǎn)化為處于(0, 1)的概率脖阵,再根據(jù)概率值對(duì)樣本進(jìn)行分類皂股。在處理二分類問題時(shí),我們認(rèn)為當(dāng)sigmoid(t)的值大于0.5時(shí)独撇,將該樣本分類為1的概率大于0.5屑墨,因此將改樣本分類為1,當(dāng)sigmoid(t)的值小于0.5時(shí)纷铣,將該樣本分類為0卵史。sigmoid(t)可以看做是樣本 t 分類為1的概率。
利用sigmoid函數(shù)我們就將邏輯回歸的分類問題轉(zhuǎn)化為了回歸問題的求解搜立。依然是利用梯度下降法對(duì)損失函數(shù)求極小值以躯,數(shù)學(xué)推導(dǎo)過程在這里略去。直接上結(jié)論:
J(θ) = -(y*(ln(σ(Xθ))) + (1-y)(1-ln(σ(Xθ)))) / m
其中的 σ 代表sigmoid函數(shù),m代表樣本數(shù)量
▽J(θ) = (X.T(σ(Xθ) - y)) / m
其中X.T代表X矩陣的轉(zhuǎn)置
得到了損失函數(shù)J(θ)以及損失函數(shù)對(duì)θ的偏導(dǎo)數(shù)之后啄踊,就可以用梯度下降法來實(shí)現(xiàn)邏輯回歸了
使用的示例數(shù)據(jù)是sklearn中的鳶尾花數(shù)據(jù)集
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn import datasets
# 鳶尾花數(shù)據(jù)集有三種花忧设,因此舍棄分類為2的花,用來進(jìn)行二分類
iris = datasets.load_iris()
x = iris.data
y = iris.target
X = x[y<2, :]
y = y[y < 2]
# 進(jìn)行訓(xùn)練驗(yàn)證數(shù)據(jù)集分割
X = np.hstack((np.ones((X.shape[0],1)), X))
X_train, X_test, y_train, y_test = train_test_split(X, y)
initial_theta = np.zeros(X.shape[1])
定義sigmoid函數(shù)
def sigmoid(t):
return 1. / (1.+np.exp(-t))
定義損失函數(shù):
def j(X, y, theta):
return -(y.dot(np.log(sigmoid(X.dot(theta)))) + (1-y).dot(1-np.log(sigmoid(X.dot(theta))))) / len(y)
定義損失函數(shù)的梯度:
def dj(X, y, theta):
return (X.T.dot(sigmoid(X.dot(theta)) - y)) / len(y)
梯度下降過程:
def gd(X, y, theta=initial_theta, eta=0.1, n_iters=1e4, epsilon=1e-8):
cur_iters = 0
theta = initial_theta
while cur_iters < n_iters:
next_theta = theta - eta*dj(X, y, theta)
if abs(j(X, y, theta) - j(X, y, next_theta)) < epsilon:
break
else:
theta = next_theta
cur_iters += 1
return theta
通過梯度下降過程颠通,我們就能找到一個(gè)最優(yōu)的theta向量
best_theta = gd(X_train, y_train)
看看模型在訓(xùn)練數(shù)據(jù)集以及驗(yàn)證數(shù)據(jù)集中的準(zhǔn)確度,首先定義一個(gè)預(yù)測函數(shù)
def predict(X, best_theta=best_theta):
temp = X.dot(best_theta)
y_predict = np.array(temp>0, dtype=int)
return y_predict
y_train_predict = predict(X_train, best_theta)
train_score = np.sum(y_train_predict==y_train)/len(y_train)
y_test_predict = predict(X_test, best_theta)
test_score = np.sum(y_test_predict==y_test)/len(y_test)
print('在訓(xùn)練數(shù)據(jù)集的準(zhǔn)確度為{}, 在驗(yàn)證數(shù)據(jù)集的準(zhǔn)確度為{}'.format(train_score, test_score))
結(jié)果如下
在訓(xùn)練數(shù)據(jù)集的準(zhǔn)確度為1.0, 在驗(yàn)證數(shù)據(jù)集的準(zhǔn)確度為1.0
可以看到址晕,通過對(duì)75個(gè)樣本的訓(xùn)練,我們對(duì)剩下25個(gè)樣本的預(yù)測準(zhǔn)確率達(dá)到了100%顿锰,其實(shí)在實(shí)際應(yīng)用中一般不會(huì)有這么高的準(zhǔn)確率谨垃,因?yàn)轼S尾花數(shù)據(jù)集比較好區(qū)分而且有四個(gè)特征所以才能達(dá)到100%的準(zhǔn)確率。但是通過這個(gè)例子也可以很好的學(xué)習(xí)到邏輯回歸的思路硼控。