更新、更全的《機器學習》的更新網站,更有python、go、數據結構與算法、爬蟲、人工智能教學等着你:http://www.javashuo.com/article/p-vozphyqp-cm.htmlpython
雖然邏輯迴歸的名字裏有「迴歸」兩個字,可是它並非一個迴歸算法,事實上它是一個分類算法。git
曾經在感知機引入時咱們講過,操場上男生和女生因爲受傳統思想的影響,男生和女生分開站着,而且由於男生和女生散亂在操場上呈線性可分的狀態,所以咱們總能夠經過感知機算法找到一條直線把男生和女生分開,而且最終能夠獲得感知機模型爲
\[ f(x)=sign((w^*)^Tx) \]
若是你細心點會發現,因爲感知模型使用的是sign函數,若是當計算一個樣本點\(w^Tx=0.001\)的時候,\(sign(w^Tx)=1\),即該函數會把該樣本歸爲\(1\),可是爲何他不能是\(0\)類呢?而且因爲sign函數在\(x=0\)處有一個階躍,即函數不連續,該函數在數學上也是不方便處理的。算法
由此邏輯函數使用sigmoid函數對\(w^Tx\)作處理,而且把sigmoid函數獲得的值\(\hat{y}\)當成機率進行下一步處理,這也正是邏輯迴歸對感知機的改進。數據結構
上述整個過程其實就是邏輯迴歸一步一步被假想出來的的一個過程,接下來將從理論層面抽象的講解邏輯迴歸。dom
# 感知機引入圖例 import numpy as np import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties %matplotlib inline font = FontProperties(fname='/Library/Fonts/Heiti.ttc') np.random.seed(1) x1 = np.random.random(20)+1.5 y1 = np.random.random(20)+0.5 x2 = np.random.random(20)+3 y2 = np.random.random(20)+0.5 # 一行二列第一個 plt.subplot(121) plt.scatter(x1, y1, s=50, color='b', label='男孩(+1)') plt.scatter(x2, y2, s=50, color='r', label='女孩(-1)') plt.vlines(2.8, 0, 2, colors="r", linestyles="-", label='$wx+b=0$') plt.title('線性可分', fontproperties=font, fontsize=20) plt.xlabel('x') plt.legend(prop=font) # 一行二列第二個 plt.subplot(122) plt.scatter(x1, y1, s=50, color='b', label='男孩(+1)') plt.scatter(x2, y2, s=50, color='r', label='女孩(-1)') plt.scatter(3.5, 1, s=50, color='b') plt.title('線性不可分', fontproperties=font, fontsize=20) plt.xlabel('x') plt.legend(prop=font) plt.show()
線性迴歸的假設函數爲
\[ \hat{y} = \omega^Tx \]
此時的\(\hat{y}\)是連續值,因此它是一個迴歸模型,若是\(\hat{y}\)是離散值呢?機器學習
可能你已經想到了,對假設函數獲得的連續值再作一次轉換,即\(g(\hat{y})\),而且令\(g(\hat{y})\)函數值在\(\hat{y}\)屬於某個區間時爲\(c_1\)類;\(\hat{y}\)屬於另外一個區間時爲\(c_2\)類,這樣就能獲得一個二元分類模型。函數
上一節講到對線性迴歸的結果經過函數\(g\)作一次轉換便可得邏輯迴歸。在邏輯迴歸當中函數\(g\)一般使用Sigmoid函數替代,即函數\(g\)爲
\[ g(z) = {\frac{1}{1+e^{-z}}} \]學習
讓步比能夠理解成有利於某一特定事件的機率,能夠定義爲
\[ {\frac{p}{1-p}} \]
在已知二分類問題的狀況下每一個分類的機率分別爲\(\hat{y_i}\)和\(1-\hat{y_i}\),能夠定義logit函數,即讓步比的對數形式(log-odds)爲
\[ \begin{align} \log{it}(\hat{y_i}) & = \log{\frac{p(y=1|x,\omega)}{p(y=0|x,\omega)}} \\ & = \log{\frac{\hat{y_i}}{1-\hat{y_i}}} \\ & = \log{\frac{{\frac{1}{1+e^{-\omega^Tx}}}}{{\frac{-\omega^Tx}{1+e^{-\omega^Tx}}}}} \\ & = \omega^Tx \end{align} \]
其中\(\log{it}(p)\)函數等於事件發生的機率除以不發生的機率取對數,即表示特徵值和對數機率之間的線性關係。優化
然而特徵值和對數機率之間的線性關係並不重要,重要的是預測值與它發生的機率的關係,即讓步比的逆形式,也就是上述說到的Sigmoid函數。
\[ w^Tx = \log{\frac{p}{1-p}} \\ e^{w^Tx} = {\frac{p}{1-p}} \\ p = {\frac{1}{1+e^{-w^Tx}}} \\ \]
# Sigmoid函數圖像圖例 import numpy as np import matplotlib.pyplot as plt %matplotlib inline def sigmoid(z): return 1 / (1 + np.exp(-z)) ax = plt.subplot(111) # 描繪十字線 ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') ax.spines['bottom'].set_position(('data', 0)) ax.yaxis.set_ticks_position('left') ax.spines['left'].set_position(('data', 0)) z = np.linspace(-10, 10, 256) hat_y = sigmoid(z) plt.plot(z, hat_y, c='r', label='Sigmoid') # 描繪y=0.5和y=1.0兩條直線 plt.yticks([0.0, 0.5, 1.0]) ax = plt.gca() ax.yaxis.grid(True) plt.xlabel('z') plt.ylabel('$\hat{y}$') plt.legend() plt.show()
上圖爲Sigmoid函數圖像,能夠看出當\(z\)趨於正無窮時,\(g(z)\)趨於1;當\(z\)趨於負無窮時,\(g(z)\)趨於0,這個屬性很是適合上述所說的分類模型。
所以能夠把線性函數的假設函數當作是Sigmoid函數的自變量,即邏輯迴歸的假設函數爲
\[ \hat{y} = {\frac{1}{1+e^{-\omega^Tx}}} \]
雖然改變了邏輯迴歸的假設函數,可是Sigmoid函數的輸出值是\((0,1)\)範圍內的連續值,並非二元分類模型想要的二元離散值,所以須要對邏輯迴歸的假設函數作進一步處理,即
\[ \begin{cases} \hat{y}>0.5即\omega^Tx>0, \quad y=1 \\ \hat{y}<0.5即\omega^Tx<0, \quad y=0 \\ \end{cases} \]
若是\(\hat{y}=0.5即\omega^Tx=0\),不在邏輯迴歸模型的討論範圍內,通常而言視具體狀況而定。
獲得了邏輯迴歸的假設函數,則須要經過最小化目標函數即最小化偏差找到最合適的參數\(\omega\)。
因爲線性迴歸是預測連續值的模型,所以可使用均方偏差代價函數。可是邏輯迴歸是預測離散值的模型,所以可使用極大似然估計推導出邏輯迴歸的目標函數。
上一節假設邏輯迴歸的輸出爲類別\(0\)或類別\(1\),用機率表達方式爲
\[ \begin{align} & p(y=1|x,\omega)=\pi(x) \\ & p(y=0|x,\omega)=1-\pi(x) \end{align} \]
因爲\(y\)只多是\(0\)或\(1\),則能夠把上述兩個公式聯立可得\(y\)的機率分佈函數表達式
\[ p(y|x,\omega) = (\pi(x))^y(1-\pi(x))^{(1-y)} \]
經過\(y\)的機率分佈函數表達式便可得似然函數爲
\[ L(\omega) = \prod_{i=1}^m [\pi(x_i)]^{y_i}[(1-\pi{x_i})]^{(1-y_i)} \]
其中\(m\)爲樣本的個數。
經過似然函數獲得對數似然函數即目標函數(注:該目標函數與交叉熵損失函數的形式一致,二元邏輯迴歸能夠理解爲交叉熵損失函數兩個類變量的特殊形式,交叉熵詳見《熵和信息增益》)爲
\[ \begin{align} J(\omega) & = \log{L(\omega)} \\ & = \sum_{i=1}^m [y_i\log\pi(x_i)+(1-y_i)\log(1-\pi(x_i))] \end{align} \]
對\(J(\omega)\)求極大值,便可獲得\(\omega\)的估計值。
通常採用梯度上升法或擬牛頓法求解\(\omega\)的估計值。
邏輯迴歸的目標函數爲
\[ J(\omega) = \sum_{i=1}^m [y_i\log\pi(x_i)+(1-y_i)\log(1-\pi(x_i))] \]
對於二分類問題,能夠求出\(y=1\)和\(y=0\)的代價函數
\[ J(\omega) = \begin{cases} -\log\pi(x) \quad if y=1 \\ -\log(1-\pi(x)) \quad if y=0 \\ \end{cases} \]
# 不一樣樣本實例分類的代價圖例 def cost_1(z): return -np.log(sigmoid(z)) def cost_0(z): return -np.log(1-sigmoid(z)) z = np.linspace(-10, 10, 256) pi_x = sigmoid(z) c1 = [cost_1(i) for i in z] c0 = [cost_0(i) for i in z] plt.plot(pi_x, c1, c='r', linestyle='--', label='$J(\omega), \quad if \quad y=1$') plt.plot(pi_x, c0, c='g', label='$J(\omega), \quad if \quad y=0$') plt.xlabel('$\pi(x)$') plt.ylabel('$J(\omega)$') plt.legend() plt.show()
上圖能夠看出若是正確地預測樣本屬於第\(1\)類,代價會接近0(虛線);若是正確的預測\(y=0\)(實線),代價也會接近0。若是預測錯誤,代價則會趨近於無窮大,即用愈來愈大的代價懲罰錯誤的預測。
二元邏輯迴歸的目標函數爲
\[ J(\omega) = \sum_{i=1}^m [y_i\ln\pi(x_i)+(1-y_i)\ln(1-\pi(x_i))] \]
獲得二元邏輯迴歸的目標函數,咱們須要最大化似然函數,即最大化二元邏輯迴歸的目標函數。
目標函數對\(\omega\)的偏導爲
\[ \begin{align} {\frac{\partial{J(\omega)}}{\partial{\omega_j}}} & = \sum_{i=1}^m({\frac{y_i}{\pi(x_i)}}-{\frac{1-y_i}{1-\pi(x_i)}}){\frac{\partial{\pi(x_i)}}{\partial{\omega_j}}} \\ & = \sum_{i=1}^m({\frac{y_i}{g(\omega^Tx_i)}}-{\frac{1-y_i}{1-g(\omega^Tx_i)}}){\frac{\partial{g(\omega^Tx_i)}}{\partial{\omega_j}}} \\ & = \sum_{i=1}^m({\frac{y_i}{g(\omega^Tx_i)}}-{\frac{1-y_i}{1-g(\omega^Tx_i)}})g(\omega^Tx_i)(1-g(\omega^Tx_i)){\frac{\partial{\omega^Tx_i}}{\partial{\omega_j}}} \\ & = \sum_{i=1}^m (y_i(1-g(\omega^Tx_i))-(1-y_i)g(\omega^Tx_i)){x_i}_j \\ & = \sum_{i=1}^m (y_i - g(\omega^Tx_i)){x_i}_j \end{align} \]
其中\(i\)爲第\(i\)個樣本,\(j\)爲第\(j\)個特徵。
邏輯迴歸參數的學習規則爲
\[ \omega_j = \omega_j + \alpha{\sum_{i=1}^m (y_i - g(\omega^Tx_i)){x_i}^{(j)}} \]
線性迴歸的參數學習公式爲
\[ \omega_j = \omega_j - \alpha{\sum_{i=1}^m (y_i - h(\omega^Tx_i)){x_i}^{(j)}} \]
邏輯迴歸的參數學習公式爲
\[ \omega_j = \omega_j + \alpha{\sum_{i=1}^m (y_i - g(\omega^Tx_i)){x_i}^{(j)}} \]
從上述兩個參數學習公式能夠看出線性迴歸和邏輯迴歸的參數更新方式有着相同的公式,可是因爲線性迴歸是最小化目標函數,而邏輯迴歸是最大化似然函數即最大化目標函數,所以線性迴歸是梯度降低法、邏輯迴歸是梯度上升法,曾經也講過其實梯度降低法和梯度上升法能夠轉換。
收斂速度更快,可是若是特徵維度較大計算時間漫長。
假設求得邏輯迴歸參數爲爲\(\omega^T\),則二元邏輯迴歸模型爲
\[ \begin{align} & p(y=1|x) = {\frac{e^{-\omega^T{x}}}{1+e^{-\omega^T{x}}}} \\ & p(y=0|x) = {\frac{1}{1+e^{-\omega^T{x}}}} \end{align} \]
二元邏輯迴歸的L1正則化與普通線性迴歸的L1正則化相似,增長了L1範數做爲懲罰,即
\[ J(\omega) = \sum_{i=1}^m [y_i(\omega{x_i} - \ln(1+exp(\omega(x_i))] + \lambda||\omega||_1 \]
二元邏輯迴歸L1正則化目標函數經常使用的優化方法有座標軸降低和最小角迴歸。
二元邏輯迴歸的L2正則化與普通線性迴歸的L2正則化相似,增長了L2範數做爲懲罰,即
\[ J(\omega) = \sum_{i=1}^m [y_i(\omega{x_i} - \ln(1+exp(\omega(x_i))] + {\frac{1}{2}}\lambda||\omega||_2 \]
上面介紹的邏輯迴歸都是二元分類模型,用於二分類問題,可使用如下三種方法將其推廣爲多元邏輯迴歸。OvR和MvM主要是對數據作處理,這裏不介紹其具體過程。而Softmax迴歸則是優化模型,所以主要講解Softmax迴歸。
假設一個數據集\(D\)有\(c_1,c_2,\ldots,c_k\)共\(k\)個類別,則能夠把\(c_1\)當作一個類別,把\(c_2,c_3,\ldots,c_k\)當作另一個類別,即把\(D\)分爲兩個子集,把多分類問題則變成了關於\(c_1\)和\(c_2,c_3,\ldots,c_k\)的二分類問題,而後對含有多個類別的子集再次使用OvR方法,直至沒法分類爲止。一般這種方法稱爲OvR(One-vs-Rest)。
假設一個數據集\(D\)有\(c_1,c_2,\ldots,c_k\)共\(k\)個類別,則能夠先把\(c_1,c_2,\ldots,c_i, \quad i<k\)當作一個類別,把\(c_i,c_{i+1},\ldots,c_k\)當作另一個類別,即把\(D\)分爲兩個子集,多分類問題則變成了關於\(c_1,c_2,\ldots,c_i\)和\(c_i,c_{i+1},\ldots,c_k\)的二分類問題,而後對兩個子集再次使用MvM方法,直至沒法分類爲止。一般這種方法稱爲MvM(Many-vs-Many)。
若是每次只選擇兩個個類別進行分類的話,則該方法稱爲OvO(One-vs-One),通常狀況下首先考慮使用OvO。
詳見《Softmax迴歸》
有\(m\)個實例\(n\)維特徵的數據集
\[ T=\{(x_1,y_1),(x_2,y_2),\cdots,(x_m,y_m)\} \]
其中\(x_i\)是實例的特徵向量即\(({x_i}^{(1)},{x_i}^{(2)},\cdots,{x_i}^{(n)})\)。
\(\omega\)和二元邏輯迴歸模型。
邏輯迴歸引入時說到邏輯迴歸必定程度上也是基於感知機演化而來,在替換sigmoid函數的同時,將sigmoid函數獲得的值轉換爲機率的形式,進而能夠最大化似然函數獲得最優\(w^*\),這也是邏輯迴歸的巧妙之處,可是二者仍是換湯不換藥,都是基於特徵的線性模型分類。
因爲感知機、線性迴歸和邏輯迴歸都和線性模型有必定的關係,所以放在一塊兒講,下面將會將一個單獨的算法,它從理論上而言是最簡單易懂的一個算法,即k近鄰算法。