本文主題-邏輯回歸(上部分):
- 邏輯回歸的應(yīng)用背景
- 邏輯回歸的數(shù)學(xué)基礎(chǔ)
- 邏輯回歸的模型與推導(dǎo)
- 邏輯回歸算法推導(dǎo)
- 梯度下降算法
- 邏輯回歸梯度下降算法實現(xiàn)
一. 線性回歸在分類上存在的問題
- 線性回歸的條件
??在上述例子中婶芭,我們看到線性回歸可以做預(yù)測东臀,也可以做分類,一切結(jié)果看起來都是很完美犀农。
??線性回歸模型:
??
??
??
??其中的推導(dǎo)建立在一個假設(shè)之上:服從正態(tài)分布(Gaussian Distribution)
??
??????其中:μ表示期望(均數(shù))惰赋,σ表示標(biāo)準(zhǔn)差赁濒,σ2表示方差
??
??記正態(tài)分布為 户辱,標(biāo)準(zhǔn)正態(tài)分布是
??
??下面可視化正態(tài)分布:
% matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
# 繪圖的坐標(biāo)軸
figure=plt.figure('正態(tài)分布可視化', figsize=(6, 4))
ax = figure.add_axes([0.1, 0.1, 0.8, 0.8], label='正態(tài)分布函數(shù)曲線')
ax.set_xlabel('x值')
ax.set_ylabel('隨機值:y')
# 設(shè)置繪制曲線范圍
ax.set_xlim(left=-10,right=10) # x取值范圍
ax.set_ylim(bottom=0, top=0.5) # 概率在[0, 1) 之間
# x取值范圍
x=np.linspace( -10 ,10, 100, dtype=np.float32 )
# 系數(shù)-方差
sigma=1
# 系數(shù)-均值
mu=0
# 正態(tài)分布常數(shù)系數(shù)
coefficient = 1.0 / ( np.sqrt( 2 * np.pi) * sigma )
# 正態(tài)分布指數(shù)
exponent = -(x-mu)**2/(2*sigma**2)
y=coefficient * np.exp( exponent )
ax.plot(x, y,color='r',label='正態(tài)分布曲線')
ax.legend()
figure.show(warn=False)
??正態(tài)分布函數(shù)(概率密度函數(shù))從正無窮到負(fù)無窮積分的概率為1。即頻率的總和為100%
??隨機正態(tài)分布概率,就是其中一段區(qū)域的積分范嘱。
- 一個不適合使用線性回歸分類的例子
??使用隨機方式構(gòu)造一個數(shù)據(jù)集
% matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
cls1_data = np.random.uniform(low=10000,high=100000,size=50)
cls1_result = np.ones(shape=(50),dtype=np.int32)
cls2_data = np.random.uniform(low=0,high=30000,size=50)
cls2_result = np.zeros(shape=(50),dtype=np.int32)
# 繪制樣本
figure=plt.figure('用于線性回歸的分類樣本', figsize=(6, 4))
ax = figure.add_axes([0.1, 0.1, 0.8, 0.8], label='2類樣本')
ax.set_xlabel('取值區(qū)間')
ax.set_ylabel('分類:0與1')
# 設(shè)置繪制曲線范圍
ax.set_xlim(left=0,right=100000) # x取值范圍
ax.set_ylim(bottom=-0.3, top=1.5) # 概率在[0, 1) 之間
ax.scatter(cls1_data,cls1_result,color='r',marker='.')
ax.scatter(cls2_data,cls2_result,color='b',marker='.')
figure.show(warn=False)
??使用線性回歸分類
# 采用sklearn模塊來實現(xiàn)線性回歸
from sklearn.linear_model import *
import numpy as np
x=np.hstack((cls1_data,cls2_data))
y=np.hstack((cls1_result,cls2_result))
x=x.reshape(-1, 1)
regression=LinearRegression()
# 訓(xùn)練
# 數(shù)據(jù)格式整理
# Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.
# 如果是一維特征,使用reshape處理單特征形狀(-1, 1)列疗,如果只有一個樣本闷堡,形狀reshape(1,-1)
regression.fit(x, y)
# 測試
print('評估:',regression.score(x, y))
# 斜率
print('斜率:',regression.coef_)
# 截距
print('截距:',regression.intercept_ )
# 使用訓(xùn)練數(shù)據(jù)統(tǒng)計分類正確率
pre=regression.predict(x)
print(pre)
cls_a=pre[0:50]
cls_a=cls_a>0.5
a_num=cls_a.sum()
# 第二類:后50
cls_b=pre[50:]
cls_b=cls_b<0.5
b_num=cls_b.sum()
# 統(tǒng)計正確率
a_pct=cls_a.mean()
b_pct=cls_b.mean()
print("A類識別正確數(shù):%d葫隙,識別正確率:%5.2f%%"%(a_num,a_pct*100))
print("B類識別正確數(shù):%d,識別正確率:%5.2f%%"%(b_num,b_pct*100))
# 可視化分類情況
figure=plt.figure('分類情況', figsize=(6, 4))
ax = figure.add_axes([0.1, 0.1, 0.8, 0.8], label='2類樣本')
ax.set_xlabel('取值區(qū)間')
ax.set_ylabel('分類:0與1')
# 設(shè)置繪制曲線范圍
ax.set_xlim(left=0,right=100000) # x取值范圍
ax.set_ylim(bottom=-0.3, top=1.5) # 概率在[0, 1) 之間
ax.scatter(cls1_data,cls1_result,color='r',marker='.')
ax.scatter(cls2_data,cls2_result,color='b',marker='.')
ax.plot(x, regression.predict(x),color='y', label='回歸直線')
ax.legend()
figure.show(warn=False)
評估: 0.555891654577714
斜率: [1.34255212e-05]
截距: 0.01655814267519684
[0.84828292 0.58331511 1.11550652 1.05660159 0.5944528 1.15643254
1.14064579 0.94602928 0.48950987 0.48060621 0.5319122 0.71212052
0.50981994 0.7330047 0.62845884 1.21112727 0.54341076 0.21257363
0.26175963 1.02209569 1.23536988 0.53998925 0.98959512 0.17659679
0.4907314 0.64503974 0.18405636 0.76383753 0.97628677 1.35292452
0.20352834 0.98268824 1.06256155 1.32459732 0.99089918 0.46460692
0.98906349 0.91117129 0.2198635 0.59830641 0.8756055 1.2736329
0.83592414 1.06118727 0.65489012 0.8660766 0.61240252 1.33904091
0.47394198 1.02521 0.05723705 0.37106916 0.33210881 0.33587503
0.19013076 0.24586235 0.36920796 0.14182335 0.37130829 0.25797109
0.2270329 0.27208044 0.15928228 0.1021966 0.17905334 0.22717218
0.0948184 0.13249571 0.38909531 0.05946123 0.35638356 0.1328463
0.0309184 0.41697969 0.08458613 0.11541662 0.08907712 0.02159664
0.273264 0.13543039 0.27976214 0.38864573 0.02586998 0.35168836
0.10483192 0.32039087 0.09642115 0.30624559 0.35838634 0.35280365
0.15571477 0.38641816 0.11186056 0.14146531 0.38562691 0.06455996
0.23412796 0.22797953 0.38572513 0.25240354]
A類識別正確數(shù):39,識別正確率:78.00%
B類識別正確數(shù):50茧跋,識別正確率:100.00%
????明顯的兩類樣本是可分的,使用線性回歸得到的分類效果明顯存在較大誤差棘催。這是因為我們的樣本違背了線性回歸的三個假設(shè):
??????|-自變量與因變量是線性關(guān)系兴蒸;
??????|-自變量與誤差項相互獨立;
??????|-誤差項服從正態(tài)分布细办;
二橙凳、邏輯回歸的數(shù)學(xué)基礎(chǔ)
從分類開始談起
??某個樣本屬于A類還是B類,從結(jié)果上講就是值為0笑撞,還是值為1岛啸。但影響這個分類的是由一些因素決定的。我們從數(shù)學(xué)角度可以使用向量表示這些因素(這些因素就影響某個樣本屬于A類還是B類):
??
??
??其中就是表示一個樣本茴肥,樣本
具有n個影響分類的特征坚踩。如果考慮偏置項,則可以增加一個份量1瓤狐。
??建立分類的邏輯模型
??我們假設(shè)有兩套標(biāo)準(zhǔn)判定樣本所屬的分類瞬铸,使用數(shù)學(xué)函數(shù)表示如下:
????|-??樣本x屬于A的可能性;
????|-??樣本x屬于B的可能性础锐;
??
??這樣我們就可以建立一個分類模型:
??
??
??
??當(dāng)嗓节,則樣本
屬于A類;當(dāng)
皆警,則樣本
屬于B類拦宣;
??
??可以把上述模型表示為:
??
??
分類邏輯模型的概率分析基礎(chǔ)
??
?? 如果假設(shè)與
是線性關(guān)系,同時考慮
的誤差都獨立服從正態(tài)分布,可以把
表示如下:
??
??|-
??|-
??
??其中是服從獨立分布的誤差項鸵隧,可以假設(shè)服從正態(tài)分布绸罗。
??記,則:
??|-
??
??從而分類邏輯模型可以表示如下:
??|-
??其中
??
??
??則樣本X屬于A的概率可以表示為:
??|-
??從正態(tài)分布可以繼續(xù)推導(dǎo):
??|-
??其中是變量
的累積分布函數(shù)掰派;
表示樣本屬于A的概率
probit模型
??上述推導(dǎo)的公式在學(xué)術(shù)上稱為probit模型从诲,建立的回歸模型也稱proit回歸。
??
??
??
??是正態(tài)分布函數(shù)的累積函數(shù)靡羡,上述累積分布函數(shù)系洛,在服從正態(tài)分布的時候比較麻煩,因為正態(tài)分布的累積函數(shù)還沒有解析表達(dá)式能夠表達(dá)略步。 從而其參數(shù)估計非常麻煩描扯,如果需要應(yīng)用,則需要簡化( 做近似處理 )趟薄。
??為了解決正態(tài)分布累積函數(shù)的問題绽诚,正態(tài)分布的累積函數(shù)的計算居然是通過查表的形式提供運算結(jié)果,大家如果想不起杭煎,可以查閱自己的高中數(shù)據(jù)或者大學(xué)數(shù)學(xué)書恩够。正態(tài)分布的近似處理
??正態(tài)分布表示:
??????其中:μ表示期望(均數(shù)),σ表示標(biāo)準(zhǔn)差羡铲,σ2表示方差
??
??記正態(tài)分布為,標(biāo)準(zhǔn)正態(tài)分布是
??
?? 我們可以簡化下正態(tài)分布累積函數(shù)的表示:
??
??因為是線性扑媚,所以只需要考慮標(biāo)準(zhǔn)正態(tài)分布。
??在數(shù)學(xué)上存在一個邏輯分布雷恃,與正態(tài)分布非常相似疆股,邏輯分布與標(biāo)準(zhǔn)正態(tài)分布
??下面使用可視化來認(rèn)識下邏輯分布函數(shù)與正態(tài)分布函數(shù)的近似度。
????|- 正態(tài)分布:
????|- 邏輯分布:
??
??邏輯分布函數(shù)與正態(tài)分布的區(qū)別就在于:邏輯分布有累積函數(shù)倒槐,其累積函數(shù)如下:
????|- 邏輯分布累積函數(shù):
??
??下面是邏輯分布函數(shù)旬痹,正態(tài)分布函數(shù)的比較:
% matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
# 繪圖的坐標(biāo)軸
figure=plt.figure('正態(tài)分布與邏輯分布', figsize=(10, 4))
ax = figure.add_axes([0.1, 0.1, 0.8, 0.8], label='邏輯分布與正態(tài)分布')
ax.set_xlabel('x值')
ax.set_ylabel('y值')
# 設(shè)置繪制曲線范圍
ax.set_xlim(left=-10,right=10) # x取值范圍
ax.set_ylim(bottom=0, top=0.5) # 概率在[0, 1) 之間
# 標(biāo)準(zhǔn)正態(tài)分布函數(shù)--------------------
# x取值范圍
x_n=np.linspace( -10 ,10, 100, dtype=np.float32 )
# 系數(shù)-方差
sigma=1
# 系數(shù)-均值
mu=0
# 正態(tài)分布常數(shù)系數(shù)
coefficient = 1.0 / ( np.sqrt( 2 * np.pi) * sigma )
# 正態(tài)分布指數(shù)
exponent = -(x_n-mu)**2/(2*sigma**2)
y_n=coefficient * np.exp( exponent )
ax.plot(x_n, y_n,color='r',label='正態(tài)分布')
# 邏輯分布函數(shù)--------------------
x_l=np.linspace( -10 ,10, 100, dtype=np.float32 )
y_l=np.exp( -x_l ) / ( 1 + np.exp( -x_l ) )**2
ax.plot(x_l, y_l,color='b',label='邏輯分布')
ax.legend()
figure.show(warn=False)
- 邏輯分布與標(biāo)準(zhǔn)正態(tài)分布的累積函數(shù)
??標(biāo)準(zhǔn)正態(tài)分布沒有累積函數(shù),所以我們采用scipy的積分函數(shù)來繪制导犹。
??使用積分表示正態(tài)分布累積函數(shù)的公式如下:
????|-唱凯,
% matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import scipy.integrate as integrate
# 定義正態(tài)函數(shù),用于積分運算
def normal(t,m,s):
# 系數(shù)-方差
sigma=s
# 系數(shù)-均值
mu=m
# 正態(tài)分布常數(shù)系數(shù)
coefficient = 1.0 / ( np.sqrt( 2 * np.pi) * sigma )
# 正態(tài)分布指數(shù)
exponent = -(t-mu)**2/(2*sigma**2)
re=coefficient * np.exp( exponent )
return re
def cumulative(x):
re=integrate.quad(
normal, # 積分函數(shù)
-np.inf, # 積分下限
x, # 積分上限
args=(0.0, 1.0) # 傳遞給函數(shù)的參數(shù)(除第一個參數(shù)外谎痢,按照順序來)
)
return re[0] #第一個是積分磕昼,第二個是誤差上限
# 繪圖的坐標(biāo)軸
figure=plt.figure('正態(tài)分布與邏輯分布', figsize=(10, 4))
ax = figure.add_axes([0.1, 0.1, 0.8, 0.8], label='邏輯分布與正態(tài)分布')
ax.set_xlabel('x值')
ax.set_ylabel('y值')
# 設(shè)置繪制曲線范圍
ax.set_xlim(left=-10,right=10) # x取值范圍
ax.set_ylim(bottom=-0.1, top=1.1) # 概率在[0, 1) 之間
# 標(biāo)準(zhǔn)正態(tài)分布函數(shù)--------------------
# x取值范圍
x_n=np.linspace( -10 ,10, 100, dtype=np.float32 )
y_n=[cumulative(x) for x in x_n ]
ax.plot(x_n, y_n,color='r',label='正態(tài)分布累積函數(shù)')
# 邏輯分布函數(shù)--------------------
x_l=np.linspace( -10 ,10, 100, dtype=np.float32 )
y_l=1.0 / ( 1 + np.exp( -x_l ) )
ax.plot(x_l, y_l,color='b',label='邏輯分布累積函數(shù)')
ax.legend()
ax.grid(b=True)
figure.show(warn=False)
- 最佳的邏輯分布
??如果邏輯分布參數(shù)做一些調(diào)整,可以最佳接近节猿。下面是最佳邏輯分布累積函數(shù)表示:
????|-
??下面是可視化后的直觀效果票从。
% matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import scipy.integrate as integrate
# 定義正態(tài)函數(shù)漫雕,用于積分運算
def normal(t,m,s):
# 系數(shù)-方差
sigma=s
# 系數(shù)-均值
mu=m
# 正態(tài)分布常數(shù)系數(shù)
coefficient = 1.0 / ( np.sqrt( 2 * np.pi) * sigma )
# 正態(tài)分布指數(shù)
exponent = -(t-mu)**2/(2*sigma**2)
re=coefficient * np.exp( exponent )
return re
def cumulative(x):
re=integrate.quad(
normal, # 積分函數(shù)
-np.inf, # 積分下限
x, # 積分上限
args=(0.0, 1.0) # 傳遞給函數(shù)的參數(shù)(除第一個參數(shù)外,按照順序來)
)
return re[0] #第一個是積分峰鄙,第二個是誤差上限
# 繪圖的坐標(biāo)軸
figure=plt.figure('正態(tài)分布與邏輯分布', figsize=(10, 4))
ax = figure.add_axes([0.1, 0.1, 0.8, 0.8], label='邏輯分布與正態(tài)分布')
ax.set_xlabel('x值')
ax.set_ylabel('y值')
# 設(shè)置繪制曲線范圍
ax.set_xlim(left=-10,right=10) # x取值范圍
ax.set_ylim(bottom=-0.1, top=1.1) # 概率在[0, 1) 之間
# 標(biāo)準(zhǔn)正態(tài)分布函數(shù)--------------------
# x取值范圍
x_n=np.linspace( -10 ,10, 100, dtype=np.float32 )
y_n=[cumulative(x) for x in x_n ]
ax.plot(x_n, y_n,color='r',label='正態(tài)分布累積函數(shù) $F_{\epsilon}(x)=\int_{-\infty}^{x}\dfrac{1}{\sqrt{2\pi}\sigma}exp(-\dfrac{(t-\mu)^2}{2\sigma^2})\mathrmqn5vrub t$')
# 邏輯分布函數(shù)--------------------
x_l=np.linspace( -10 ,10, 100, dtype=np.float32 )
y_l=1.0 / ( 1 + np.exp( -1.702*x_l ) )
ax.plot(x_l, y_l,color='b',label='邏輯分布累積函數(shù) $S(x)=\dfrac{1}{1+e^{-1.702x}}$ ')
ax.legend()
ax.grid(b=True)
figure.show(warn=False)
9.sigmoid函數(shù)
?? 就是鼎鼎大名的sigmoid函數(shù)浸间,該函數(shù)具備許多良好的性質(zhì)。尤其是深度學(xué)習(xí)中的大殺器吟榴!經(jīng)常會用到魁蒜。
??函數(shù)的特點:
????|- 函數(shù)的導(dǎo)數(shù)可以用自身表示:
????|- 連續(xù)處處可微
????|- 值在[0,1)范圍
????|- 單調(diào)遞增
????|- 非線性
????|- 平滑性
????|- 原點附近近似identity(f(x)≈x)或者先線性性。
??函數(shù)的缺點:
????|- 運算量大(后面使用梯度下降算法可以提現(xiàn)出來吩翻,尤其誤差傳遞的時候)
????|- 容易出現(xiàn)梯度消失的情況兜看,從而不利于樣本訓(xùn)練,甚至完不成梯度訓(xùn)練狭瞎。(大家可以從邏輯分布函數(shù)看得出來细移,sigmoid函數(shù)的導(dǎo)數(shù)就是邏輯分布函數(shù),邏輯分布函數(shù)從0開始熊锭,就逐步趨向于0弧轧,容易產(chǎn)生梯度消失)
三、邏輯回歸模型與模型推導(dǎo)
邏輯回歸模型
??從上述邏輯分布與正態(tài)分布的相似性碗殷,可以得到邏輯回歸模型:
??
????|- (1)proit回歸模型:
????|- (2)正態(tài)分布簡寫模型:
??
??在porit回歸模型基礎(chǔ)上精绎,簡單推導(dǎo),可以定義如下模型:
???? |-
????上上述公式就是邏輯回歸模型(省略了具體的推導(dǎo)還有一部分假設(shè))锌妻。發(fā)生比
?? 我們可以定義為發(fā)生比捺典。 然后簡單取自然對數(shù),得到如下公式:
??
??
?? 邏輯回歸是建立在一個假設(shè)之上:事件發(fā)生比實際上是一個線性模型从祝。似然函數(shù)
??邏輯回歸的算法還是要從模型參數(shù)的估計開始。
??從統(tǒng)計來說引谜,數(shù)據(jù)出現(xiàn)的概率越大越好牍陌,這就是最大似然估計法,由于數(shù)據(jù)的取值是離散的0员咽,1毒涧,從而數(shù)據(jù)取值的概率分布函數(shù)可以表示為(這里用到了二項分布概率累積函數(shù)的計算方法):
????|-
??取自然對數(shù):
????|-
??
??考慮所有樣本,而且每個樣本獨立贝室,所以可以對所有樣本形成下面公式:
????|-其中
表示遍歷所有樣本契讲,
表示其中第
個樣本。 ??
??把所有樣本的概率分布函數(shù)展開:
????|-
??替換為概率分布函數(shù):sigmoid函數(shù)滑频,可以得到如下公式:
????|-
??????其中表示sigmoid函數(shù)
捡偏,
表示第
個樣本。
??上述公式就是W的似然函數(shù)峡迷,可以更加明確的按照條件概率方式記為:
????|-參數(shù)估計公式推導(dǎo)
??使用最大似然估計法银伟,可以得到W的參數(shù)估計公式(求對數(shù)):
????|-機器學(xué)習(xí)的損失函數(shù)定義
??由于使似然函數(shù)值最大你虹,相反考慮,定義損失函數(shù)如下:
????
??這樣就使得問題編程求最小值彤避,我們可以定義成邏輯回歸模型的損失函數(shù)傅物。使用算法找到的最小值即可。
四钧舌、邏輯回歸模型定義
決策函數(shù)
??
??
?? 其中是sigmoid函數(shù)
?? 其中是第
個樣本數(shù)據(jù)箭养。
?? 其中是樣本的線性系數(shù)岳锁,也可以理解成樣本特征的重要性加權(quán)。
機器學(xué)習(xí)中的誤差定義
??
??上述公式被稱為交叉熵(Cross Entropy)
??其中
五卒暂、邏輯回歸的算法推導(dǎo)
??邏輯回歸最終還是找到一個W,使得分類誤差最小榨咐,也就是使得損失函數(shù)最小介却,所以邏輯回歸屬于于廣義線性回歸的一種。
??邏輯回歸算法也是找到一個W块茁,使得對所有樣本函數(shù)的值最小齿坷, 由于考慮問題的思路不同,這里的
不再像線性回歸函數(shù)那樣:通過推導(dǎo)直接得到
的求解公式数焊。
??下面我們嘗試使用求導(dǎo)的方式永淌,來推導(dǎo)能否求解&J(W)&的最小值,從而得到W的解佩耳。
??推導(dǎo)前的一個已知知識:sigmoid函數(shù)(也稱S曲線函數(shù))有一個顯著特性就是其導(dǎo)數(shù)可以使用自身表示遂蛀。
????|-
- 求偏導(dǎo)數(shù)
??上述推導(dǎo)基于一個數(shù)學(xué)知識:鏈?zhǔn)角笃珜?dǎo)公式。下面繼續(xù)推導(dǎo):
??上述公式注意最后的推導(dǎo)干厚,我們直接采用了向量求導(dǎo)李滴,直接得到。
??下面對前面幾項做多項式拆分蛮瞄,得到如下公式:
求解W
??按照原來的套路所坯,利用極值求解W,由于其中是一個指數(shù)函數(shù)挂捅,加上求和等線性因素芹助,上述公式按照導(dǎo)數(shù)=0的方式求解非常麻煩,應(yīng)該說無法使用公式推導(dǎo)求的W的值闲先。 下面我們來回顧下状土,數(shù)學(xué)中求極值算法。
從最大似然函數(shù)的推導(dǎo)結(jié)果看問題
??最大似然函數(shù)
????|-均方差(損失函數(shù))
??????|-線性(Closed-Form)
????????|-最小二乘法
??????|-非線性
????????|-梯度下降法
????????|-牛頓迭代法
????????|-擬牛頓法
????????|-坐標(biāo)下降法
????|-交叉熵(損失函數(shù))
??????|-非線性
????????|-梯度下降法
????????|-牛頓迭代法
????????|-擬牛頓法
????????|-坐標(biāo)下降法
??從機器學(xué)習(xí)的角度伺糠,通過建模的模型分析蒙谓,得到一個評估學(xué)習(xí)模型好壞的標(biāo)準(zhǔn)-損失函數(shù),然后建立訓(xùn)練目標(biāo)退盯。
??其中損失函數(shù)一般是損失最小彼乌,為了使得損失函數(shù)最小泻肯,就需要各種算法。
??下面列出在不同模型中常用的損失函數(shù)(后面逐步講解每個損失函數(shù)的來源)
??
??梯度下降法:
????|-全梯度下降法 (FG)
????|-隨機梯度下降算法 (SG)
????|-隨機平均梯度下降算法 (SAG)
????|-小批量梯度下降算法 (mini-bantch)
????|-隨機方差縮減法( SAGA)(STOCHASTIC VARIANCE REDUCTION METHODS)
- 常見的損失誤差:
??|-1. 鉸鏈損失(Hinge Loss):主要用于支持向量機(SVM) 中慰照;
??|-2. 互熵?fù)p失 (Cross Entropy Loss灶挟,Softmax Loss ):用于Logistic 回歸與Softmax 分類中;
??|-3. 平方損失(Square Loss):主要是最小二乘法(OLS)中毒租;
??|-4. 指數(shù)損失(Exponential Loss) :主要用于Adaboost 集成學(xué)習(xí)算法中稚铣;
??|-5. 其他損失(如0-1損失,絕對值損失)
六墅垮、梯度下降算法
- 梯度下降算法的前置條件
??|-梯度下降就是讓一個損失函數(shù)最小惕医,所以梯度下降首先需要一個損失函數(shù)。
??|-梯度下降使得損失函數(shù)最小算色, 必須是因為某個量抬伺,在我們的機器學(xué)習(xí)中, 這個量都是特征()權(quán)重的影響量灾梦; 在線性回歸與邏輯回歸中就是線性系數(shù)
峡钓。
??(1)線性回歸中,損失函數(shù)是:
????|-
??(2)邏輯回歸中若河,損失函數(shù)是:
????|-
??????|-上述公式被稱為交叉熵(Cross Entropy)
??????|-其中
- 梯度下降的數(shù)學(xué)極值與凸優(yōu)化理論
??求最小值能岩,大家第一個想到的就是極值定理。
????|-極大值與極小值就是函數(shù)在其定義域的某些局部區(qū)域所達(dá)到的相對最大值或相對最小值萧福。當(dāng)函數(shù)在其定義域的某一點的值大于該點周圍 任何點的值時拉鹃,稱函數(shù)在該點有極大值; 當(dāng)函數(shù)在其定義域的某一點的值小于該點周圍任何點的值時, 稱函數(shù)在該點有極小值鲫忍。這里的極大和極小只具有局部意義膏燕。
????|-極值點:極值點只能在函數(shù)不可導(dǎo)的點或?qū)?shù)為零的點上取得。
?? ??極值定理
對于一元可微函數(shù)??(??)悟民,它在某點x0有極值的充分必要條件是??(??)在??0的某鄰域上一階可導(dǎo)煌寇,在??0處二階可導(dǎo),且??'(??0)=0逾雄,??' '(??0)≠0,那么:
1)若??' '(??0)<0腻脏,則f在x0取得極大值鸦泳; 2)若??' '(??0)>0,則f在x0取得極小值永品。
求解極值做鹰,直接解?? ' (??0)=0方程,可以得到極值點鼎姐。
??????最值與極值
??????因為極值是局部意義上的钾麸,最值是全局意義上的更振;在算法過程中,容易導(dǎo)致求出的極值在局部最大饭尝,在全局不是最大肯腕。為了保證極值就是最值,需要函數(shù)滿足凸性钥平。
??????凸集
??對于集合
滿足:任給的
,總有
,對于任意的
实撒,我們稱X是凸集。
?? ????凸函數(shù)
??對于一個函數(shù)
涉瘾,滿足:任給的
(
是函數(shù)定義域)知态。總有
,對于任意的
立叛,我們稱
為凸函數(shù)负敏。
??換成幾何描述就是,函數(shù)的幾何圖形中任意兩個點的連線上的點都在函數(shù)的幾何圖形中秘蛇。
- 均方差函數(shù)的可視化
??均方差函數(shù)本身是凸的其做, 如果從權(quán)重考慮,則發(fā)現(xiàn)該函數(shù)在邏輯回歸中是非凸的彤叉。
??從輸出的圖形來看是凸的庶柿。
% matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure('3D可視化',figsize=(8,6))
# 創(chuàng)建3D圖形
# 方式一:
# ax = Axes3D(fig)
# 方式二:
ax = fig.add_subplot(111, projection='3d')
# J(W)對多個樣本繪制
# 年齡
x = np.loadtxt('ex2x.dat')
# 身高
y = np.loadtxt('ex2y.dat')
w = np.arange(-2, 2, 0.02)
b = np.arange(-2, 2, 0.02)
w, b = np.meshgrid(w, b) # x-y 平面的網(wǎng)格
z=0
for i in range(len(x)):
z += ( ( x[i]*w + b - y[i])**2 )
z/=len(x)
# rstride:行之間的跨度 cstride:列之間的跨度
ax.plot_surface(w, b, z, rstride=1, cstride=1, cmap=plt.get_cmap('rainbow'),label='三維拋物面')
# 設(shè)置圖像z軸的顯示范圍,x秽浇、y軸設(shè)置方式相同
#ax.set_xlim(-2,2)
#ax.set_ylim(-2,2)
#ax.set_zlim(0,4)
plt.show()
- 均方差采用S曲線函數(shù)輸出的可視化
??從輸出的圖形來看浮庐,非凸,所以在邏輯回歸的損失函數(shù)柬焕,采用均方差公式訓(xùn)練會存在錯誤收斂的問題审残。
% matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
fig = plt.figure('3D可視化',figsize=(8,6))
# 創(chuàng)建3D圖形
# 方式一:
# ax = Axes3D(fig)
# 方式二:
ax = fig.add_subplot(111, projection='3d')
# J(W)對多個樣本繪制
cls1_data = np.random.uniform(low=0,high=100,size=50)
cls1_result = np.ones(shape=(50),dtype=np.int32)
cls2_data = np.random.uniform(low=0,high=3,size=50)
cls2_result = np.zeros(shape=(50),dtype=np.int32)
x=np.hstack((cls1_data,cls2_data))
y=np.hstack((cls1_result,cls2_result))
w = np.arange(-1, 1, 0.04)
b = np.arange(-1, 1, 0.04)
w, b = np.meshgrid(w, b) # x-y 平面的網(wǎng)格
s=lambda p: 1.0/(1+np.exp(-p))
z=0
for i in range(len(x)):
z += ( ( s(x[i]*w + b) - y[i] )**2 )
z/=len(x)
# rstride:行之間的跨度 cstride:列之間的跨度
ax.plot_surface(w, b, z, rstride=1, cstride=1, cmap=plt.get_cmap('rainbow'),label='三維拋物面')
#等高線繪制(直觀想象3D圖形)
cset = ax.contour(w, b, z, zdir='z', offset=-0.2, cmap=cm.coolwarm)
cset = ax.contour(w, b, z, zdir='x', offset=-1, cmap=cm.coolwarm)
cset = ax.contour(w, b, z, zdir='y', offset=1, cmap=cm.coolwarm)
ax.set_xlim(-1.1,1.1)
ax.set_xlim(-1.1,1.1)
ax.set_zlim(-0.2,0.6)
plt.show()
- 交叉熵函數(shù)的可視化
??
????|-其中
??
??在下面例子中,為了避免計算精度產(chǎn)生的問題斑举,我們對樣本數(shù)據(jù)同比縮小搅轿,限制在0.1之間(一種正則化思維),這樣可以避免數(shù)據(jù)計算溢出的問題(無窮大與無窮小的問題)
?? 從下面可視化效果上富玷,看的出損失函數(shù)是凸的璧坟。實際上從數(shù)學(xué)推理上也可以證明,上面的公式非凸赎懦,這個公式是凸的雀鹃。
% matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
fig = plt.figure('3D可視化',figsize=(8,6))
# 創(chuàng)建3D圖形
# 方式一:
# ax = Axes3D(fig)
# 方式二:
ax = fig.add_subplot(111, projection='3d')
# J(W)對多個樣本繪制
cls1_data = np.random.uniform(low=0.0,high=1.0,size=50)
cls1_result = np.ones(shape=(50),dtype=np.float32)
cls2_data = np.random.uniform(low=0.01,high=0.04,size=50)
cls2_result = np.zeros(shape=(50),dtype=np.float32)
x=np.hstack((cls1_data,cls2_data))
y=np.hstack((cls1_result,cls2_result))
w = np.arange(-1, 1, 0.04,dtype=np.float64)
b = np.arange(-1, 1, 0.04,dtype=np.float64)
w, b = np.meshgrid(w, b) # x-y 平面的網(wǎng)格
s=lambda p: 1.0/(1.0+np.exp(-p))
for i in range(len(x)):
z+=y[i]*np.log(s(x[i]*w+b))+(1.0-y[i])*(np.log(1.0-s(x[i]*w+b)))
z=-z
z/=len(x)
# rstride:行之間的跨度 cstride:列之間的跨度
ax.plot_surface(w, b, z, rstride=1, cstride=1, cmap=plt.get_cmap('rainbow'),label='三維拋物面')
#等高線繪制(直觀想象3D圖形)
cset = ax.contour(w, b, z, zdir='z', offset=0.5, cmap=cm.coolwarm)
cset = ax.contour(w, b, z, zdir='x', offset=-1.1, cmap=cm.coolwarm)
cset = ax.contour(w, b, z, zdir='y', offset=1.1, cmap=cm.coolwarm)
ax.set_xlim(-1.1,1.1)
ax.set_xlim(-1.1,1.1)
ax.set_zlim(0.5,1)
plt.show()
- 交叉熵函數(shù)凸性證明
??為了證明交叉熵函數(shù)是凸的,只需要求二階導(dǎo)數(shù)就可以(這里用到凸優(yōu)定理):
??上面已經(jīng)求出一階導(dǎo)數(shù):
????|-
????|-
????|-
????|-
????|-
????|-??
??由于是半負(fù)定矩陣励两,所以
是凸函數(shù)黎茎,有最小值。
- 最小值梯度下降求解
?? 由于函數(shù)我們從可視化直觀觀察当悔,還是通過數(shù)學(xué)證明傅瞻,都知道是凸函數(shù)踢代,并具有最小值( 注意對似然函數(shù)來講是最大值,我們添加了一個負(fù)號- )嗅骄。 由于難以使用公式符號推導(dǎo)求解胳挎,所以這里采用梯度下降求解。
?? 梯度下降求解的原理
?? ?? |-(1)取一個初始隨機的(這里包含偏置項)掸读;
?? ?? |-(2)根據(jù)邏輯回歸模型的決策函數(shù)計算出預(yù)測值串远;
?? ?? |-(3)如果預(yù)測值與實際值有差異,則調(diào)整的值儿惫;
?? ?? |-(4)調(diào)整值一定要往最小值點方向調(diào)整澡罚;
?? ?? |-(5)n次以后,我們可以認(rèn)為是使得損失函數(shù)最小的穩(wěn)定值肾请。
- 梯度下降的方向與速度
??
?? 梯度下降的方向
????怎么保證調(diào)整的值是往最小值方向調(diào)整的呢留搔? 用下圖的拋物線(凸函數(shù))來充分說明梯度方向的選擇(最小值情況)。
??????|- 為了趨向最小值點铛铁,在最小值左邊應(yīng)該是增加隔显,在最小值右邊應(yīng)該是減少
(W是x軸)
??????|- 如果去的導(dǎo)數(shù)作為
的調(diào)整值,就可以很方便地決定方向饵逐,因為在最小值左邊導(dǎo)數(shù)為負(fù)括眠,載最小值右邊導(dǎo)數(shù)為正。
??????|- 如果取導(dǎo)數(shù)作為調(diào)整值倍权,則最小值左邊減去導(dǎo)數(shù)值(增加)掷豺,最小值右邊加上導(dǎo)數(shù)值(
減少)。
??
?? 梯度下降的速度
????從下圖可以看見薄声,如果的值調(diào)整過大当船,在最值點會擺動很大,導(dǎo)致無法準(zhǔn)確得到最好的
默辨,為了控制在最小值點擺動產(chǎn)生的過擬合德频,可以對調(diào)整值加上一個參數(shù)
來控制。
??????|-參數(shù)越大缩幸,訓(xùn)練速度快壹置,取得的訓(xùn)練值容易過擬合。
??????|-參數(shù)越小表谊,訓(xùn)練速度慢蒸绩,容易取得最好訓(xùn)練值。
% matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure('梯度下降說明',figsize=(8,6))
ax = fig.add_subplot(111,label='梯度下降說明',xlabel='X-軸(W值)',ylabel='Y-軸(損失值:$J(W)$)')
x = np.linspace(-2.0, 2.0, 20)
y = x**2
ax.plot(x, y,label='二次凸曲線',color=(1,0,0,1),marker='.',markersize=10,markerfacecolor=(0,0,1,1),markeredgecolor=(0,0,1,1))
for i in range(9):
ax.arrow(x=x[i],y=y[i],dx=x[i+1]-x[i],dy=y[i+1]-y[i],width=0.02,color=(0,0,0,1) ,head_width=0.1,head_length=0.05)
plt.show()
實現(xiàn)部分铃肯,限于篇幅,請閱讀下部分