邏輯回歸(logistic regression)
基本概念
邏輯回歸雖然名字中帶有回歸,但應(yīng)該是歷史遺留問題。他主要解決的問題是二分類問題,也可以解決多分類(Multi-class)問題。在二分類的邏輯回歸中目標(biāo)變量的取值只能為0和1,邏輯回歸主要應(yīng)用于研究目標(biāo)事件發(fā)生的概率。其與上一篇文章講的多重線性回歸主要的部分都差不多,主要是因變量不同,線性回歸的因變量是連續(xù)的,也因此被歸為一個(gè)家族——廣義線性模型(generalized linear model).
模型
邏輯回歸的模型是利用最大似然估計(jì)的方法,構(gòu)造了一個(gè)sigmoid函數(shù),將線性回歸的假設(shè)函數(shù)值投影到(0,1)之間。很多教材將投影后的值直接告訴學(xué)習(xí)者說,這就是 y取某一類的概率值,即P(y = Ck|x,θ). 比如給定一個(gè)腫瘤的尺寸,經(jīng)過hθ作用后輸出結(jié)果為他為惡性或良性(取決于你類的定義)的概率值。但是數(shù)學(xué)證明也并不復(fù)雜,利用貝葉斯公式可以比較簡(jiǎn)單的推導(dǎo)出來,借鑒知乎上的一個(gè)回答。Andrea 在模型中介紹了決策邊界(decision boundary)以便我們能更好的理解模型。決策邊界是針對(duì)特定的輸入變量X(i),有一個(gè)參數(shù)為θ的超平面(取決于X中特征的個(gè)數(shù),如果i為2,則就是一條直線,下面以直線為例),在這條線上方的我們將其劃分為某一類,在這條線下方的為另外一類。這條線或者超平面稱為決策邊界。圖中的是由不同的訓(xùn)練集確定的不同的決策邊界,圖一是一條直線,圖二是一個(gè)圓。決策邊界由訓(xùn)練集學(xué)習(xí)得到參數(shù)θ決定,理論上可以為任意形狀
要注意理解假設(shè)函數(shù)和決策邊界函數(shù)的區(qū)別與聯(lián)系。決策邊界是假設(shè)函數(shù)的屬性,由假設(shè)函數(shù)的參數(shù)決定。
在邏輯回歸中,假設(shè)函數(shù)(h=g(z))用于計(jì)算樣本屬于某類別的可能性;決策函數(shù)(h=1(g(z)>0.5))用于計(jì)算(給出)樣本的類別;決策邊界(θ^Tx=0)是一個(gè)方程,用于標(biāo)識(shí)出分類函數(shù)(模型)的分類邊界。
原文:https://blog.csdn.net/walilk/article/details/51107380?utm_source=copy





策略
logistic regression 采用的策略也為代價(jià)函數(shù)的方式(cost function), 只不過這里不再是適用線性回歸模型的均方誤差的代價(jià)函數(shù),而是采用交叉熵(cross entropy),關(guān)于交叉熵的直觀理解,《神經(jīng)網(wǎng)絡(luò)與深度學(xué)習(xí)》中說的比較直觀。
交叉熵是對(duì)「出乎意料」(譯者注:原文使用suprise)的度量。神經(jīng)元的目標(biāo)是去計(jì)算函數(shù)y, 且y=y(x)。但是我們讓它取而代之計(jì)算函數(shù)a, 且a=a(x)。假設(shè)我們把a(bǔ)當(dāng)作y等于1的概率,1?a是y等于0的概率。那么,交叉熵衡量的是我們?cè)谥纘的真實(shí)值時(shí)的平均「出乎意料」程度。當(dāng)輸出是我們期望的值,我們的「出乎意料」程度比較低;當(dāng)輸出不是我們期望的,我們的「出乎意料」程度就比較高。
其實(shí)從函數(shù)的角度也不難理解代價(jià)函數(shù)在計(jì)算什么。在二分類問題下,y的取值只能為0或1,當(dāng)y = 0, 代價(jià)函數(shù)只有第二項(xiàng)為log(1-hθ),當(dāng)hθ預(yù)測(cè)也為零,那么損失函數(shù)為0,如果預(yù)測(cè)為1那么損失函數(shù)為無窮大,即完全預(yù)測(cè)錯(cuò)誤的話會(huì)有一個(gè)很大的懲罰(penalty),那如果預(yù)測(cè)為0.6,表示其屬于正類的概率為0.6,那么交叉熵計(jì)算的就是我們出乎意料(竟然不是0 orz)的程度了。

關(guān)于交叉熵的推導(dǎo),其實(shí)利用的是極大似然函數(shù)。

方法
關(guān)于求解θ的方法,Andrea 提出了很多高級(jí)算法,包括共軛梯度,擬牛頓法(BFGS)等,但是只是介紹了如何在Octave中調(diào)用而沒有介紹細(xì)節(jié),所以這里還是使用梯度下降法來求解。首先對(duì)于sigmoid 函數(shù)有一個(gè)性質(zhì)就是g'(x) = g(x)(1-g(x)),這在之后的推到中也常用到。

發(fā)現(xiàn)最后的形式和線性回歸一樣,只不過hθ的形式改變了而已。所以也難怪他們都叫做泛線性回歸模型(generalized linear regression).
多分類問題
如果實(shí)際的問題目標(biāo)變量不止有兩種,采用的方法叫做一對(duì)多(1 vs all)。就是在計(jì)算某一類的時(shí)候?qū)⑵渌惾孔鳛榈诙悾瑥亩D(zhuǎn)化為二分類問題。最后在每一類都會(huì)計(jì)算出一個(gè)hθi(i = 1,2,3...),最后返回最大的hθ,直觀上的理解就是這些劃分到這所類的不同概率中取最大的,作為最可能被分到的類。這也樸素的反映了神經(jīng)網(wǎng)絡(luò)的思想,畢竟邏輯回歸本質(zhì)上就是一個(gè)沒有隱藏層的神經(jīng)網(wǎng)絡(luò)。
但是我之前上過一門數(shù)據(jù)挖掘到網(wǎng)課中提到了一個(gè)錯(cuò)分類權(quán)重的問題,就是說不同錯(cuò)分類之間的權(quán)重或者說嚴(yán)重性是不同的。比如,你把一個(gè)癌癥患者分類為健康和把一個(gè)健康患者分類為癌癥,一種情況會(huì)導(dǎo)致貽誤治療時(shí)機(jī),一種情況不過是多花一點(diǎn)檢查費(fèi)用而已,在這種情況下,可能需要不同的懲罰項(xiàng)來約束,而不能簡(jiǎn)單的將其描述為一對(duì)多。

附代碼(python)
import matplotlib.pyplot as plt
import numpy as np
class Logistic_Regression(object):
def __init__(self):
self.theta = None
self.theta0 = None
self.alpha = 0.001
def sigmoid(self,x):
y = 1.0 / (1+np.exp(-x))
return y
def cost(self,X_train,y):
m = X_train.shape[0]
h = (self.sigmoid(X_train.dot(self.theta)+self.theta0)).reshape((-1,1))
c0 = 0
for i in range(m):
c0 += y[i]*np.log(h[i]) +(1-y[i])*np.log(1-h[i])
cost = -c0/m
dtheta = (self.alpha/m)*(X_train.T.dot(h-y))
dtheta0 = (self.alpha/m)*np.sum(h-y)
return cost,dtheta,dtheta0
def train(self,X_train,y,iter = 5000):
m = X_train.shape[0]
n = X_train.shape[1]
self.theta = np.ones(n).reshape((-1,1))
self.theta0 = 0
cost_list = []
colors = []
for item in Y_train:
if item == 1:
colors.append("red")
else:
colors.append("blue")
x = np.linspace(3, 8, 1000)
plt.ion()
for i in range(iter):
c, dtheta, dtheta0 = self.cost(X_train,y)
cost_list.append(c)
self.theta -= dtheta
self.theta0 -= dtheta0
if i % 500 == 0:
plt.clf()
plt.scatter(X_train[:, 0], X_train[:, 1], c=colors)
x2 = -(self.theta[0] / self.theta[1]) * x + self.theta0 / self.theta[1]
plt.plot(x, x2, "g-")
plt.pause(0.5)
return cost_list
def predict(self,X_test):
y_pred = self.sigmoid(X_test.dot(self.theta)+self.theta0)
return y_pred
if __name__ == "__main__":
iris = load_iris()
data = iris.data
target = iris.target
X = data[:100,:2]
X_train = X[:-20,:2]
X_test = X[-20:,:2]
Y = target[:100]
Y_train = Y[:-20].reshape((-1,1))
Y_test = Y[-20:].reshape((-1,1))
logisticR = Logistic_Regression()
L = logisticR.train(X_train,Y_train)
theta = logisticR.theta
theta0 = logisticR.theta0
