柚子快報激活碼778899分享:【機(jī)器學(xué)習(xí)筆記4】邏輯回歸模型
柚子快報激活碼778899分享:【機(jī)器學(xué)習(xí)筆記4】邏輯回歸模型
目錄
什么是邏輯回歸?
Sigmoid函數(shù)
決策邊界
邏輯回歸的損失函數(shù)
為什么平方誤差模型不可行?
對數(shù)損失函數(shù)
單個樣例損失:
整體損失函數(shù)
梯度下降算法
補(bǔ)充:F1-score評價指標(biāo)
F1-Score簡介
相關(guān)概念
F-Score
示例及代碼:
問題描述:
數(shù)據(jù)預(yù)處理
特征縮放(Z-score標(biāo)準(zhǔn)化)
實現(xiàn)邏輯回歸
sigmoid函數(shù)
損失函數(shù)
梯度計算函數(shù)(求偏導(dǎo))
梯度迭代函數(shù)
訓(xùn)練數(shù)據(jù)集,繪制擬合決策邊界
模型預(yù)測和評價
補(bǔ)充:現(xiàn)在將特征集擴(kuò)大到所有
補(bǔ)充:使用sklearn完成邏輯回歸
請確保你已學(xué)會了前幾個線性回歸的內(nèi)容。之前涉及的相關(guān)概念在此文章不會再提及。
什么是邏輯回歸?
邏輯回歸是一種廣義的線性回歸模型,主要用于解決二分類問題。所謂二分類問題,就是比如判斷一個郵件是否是垃圾郵件、根據(jù)某些特征判斷腫瘤是否為惡性腫瘤等問題,我們可以將是/否表示為1/0。簡單的二分類數(shù)據(jù)圖如下:
(注:左圖為只有一個特征的數(shù)據(jù)模擬圖,右圖為有兩個特征的數(shù)據(jù)模擬圖。)
以僅有一個特征的二分類(左圖)為例,如果我們模擬傳統(tǒng)線性回歸,并選擇0.5作為閾值:當(dāng)時我們認(rèn)為它是種類1,當(dāng)時,我們認(rèn)為它是種類0,那么可以得到以下圖像:
?但是,當(dāng)我們再加一些數(shù)據(jù),它就會模擬成這樣:
很明顯能看出,這樣的預(yù)測并不準(zhǔn)確。
所以當(dāng)對二分類問題進(jìn)行回歸分析時,采用傳統(tǒng)的線性回歸函數(shù)進(jìn)行擬合并不是一個好的方案。于是我們將使用另一種函數(shù)——Sigmoid函數(shù)。
Sigmoid函數(shù)
Sigmoid函數(shù)又稱為Logistic函數(shù)(邏輯函數(shù)),Sigmoid函數(shù)輸出值在(0,1)之間,而且可以解決離群點(diǎn)對擬合線性回歸的影響,Sigmoid函數(shù)在諸多領(lǐng)域都有涉及,這里不再拓展。
Sigmoid函數(shù)表達(dá)式:
函數(shù)圖像:
現(xiàn)在使用sigmoid函數(shù)擬合上面的例子,當(dāng)時,我們認(rèn)為它屬于種類1,當(dāng)時,我們認(rèn)為它屬于種類0,于是可以得到下面的圖像:
(注:橙色的線為決策邊界,后面會詳細(xì)解釋。)
很明顯看出該函數(shù)擬合的很好。
決策邊界
上面提到,我們使用sigmoid函數(shù)進(jìn)行預(yù)測時,當(dāng),我們認(rèn)為是種類1,當(dāng)時,我們認(rèn)為是種類0。那么,什么時候等于0.5呢?觀察sigmoid函數(shù)的圖像,當(dāng)z等于0時,。所以我們令,決策邊界即。
以上述右圖為例(即以有兩個特征的二分類為例),決策邊界最終求出的函數(shù)為。當(dāng),屬于種類1;當(dāng),屬于種類0。決策邊界圖像為:
可以看到?jīng)Q策邊界將兩個不同的種類分開了。
又比如,當(dāng)為更復(fù)雜的多項式時,可以畫出以下圖像:
邏輯回歸的損失函數(shù)
為什么平方誤差模型不可行?
在之前的線性回歸中,我們使用平方誤差作為我們的代價函數(shù)(損失函數(shù)):
其中,(i)為樣例序號。
那時,平方誤差代價函數(shù)可以平滑下降直到一個最低點(diǎn)。
下圖是一元一次線性回歸的代價函數(shù)圖像:
但是邏輯回歸的函數(shù)為,其中,。
如果再使用平方誤差作為代價函數(shù),它的圖像將會是凹凸不平的:
?這意味著梯度下降算法很可能無法找到最低點(diǎn),會卡在某個極小值點(diǎn)。
?為了解決這個問題,我們將使用另一種模型作為我們的代價函數(shù):
對數(shù)損失函數(shù)
為什么使用對數(shù)損失函數(shù)作為邏輯回歸的損失函數(shù)而不使用其他函數(shù)?
使用對數(shù)損失函數(shù)作為邏輯回歸的損失函數(shù)是由極大似然估計推導(dǎo)所得,這里不進(jìn)行拓展。
單個樣例損失:
其中,
解釋一下含義:
當(dāng)真實值為1時,圖像為:
可以看出,在真實值y為1的情況下:當(dāng)預(yù)測值接近1時,計算出的損失很??;而當(dāng)接近0時,計算出的損失很大很大。換成人話,就是比如說某人真實情況是“很胖”,但是預(yù)測出的卻是“很廋”,這時預(yù)測值和真實值的差距就很大很大。
同理,當(dāng)真實值為0時,圖像為:
?在真實值y為0的情況下:當(dāng)預(yù)測值接近0時,計算出的損失很??;而當(dāng)接近0時,計算出的損失很大很大。
化簡,可得
整體損失函數(shù)
上式求和即可得:
公式:
讓我們用這個新的代價函數(shù)模擬一下最開始左圖的代價函數(shù)模型:
?現(xiàn)在這個圖像很適合使用梯度下降算法來找到它的最低點(diǎn)。
梯度下降算法
步驟與線性回歸相同,同時進(jìn)行以下直到收斂:
其中,
這兩個偏導(dǎo)求出來的公式和線性回歸的幾乎長得一樣,但是并不代表他們一樣。
這里
求導(dǎo)過程請參考文章:邏輯回歸梯度下降法
現(xiàn)在只需要利用該算法求得即可。?
關(guān)于多分類問題:
softmax多分類現(xiàn)已更新。
【機(jī)器學(xué)習(xí)筆記13】softmax多分類模型【上篇】完整流程與詳細(xì)公式推導(dǎo)_Twilight Sparkle.的博客-CSDN博客?【機(jī)器學(xué)習(xí)筆記14】softmax多分類模型【下篇】從零開始自己實現(xiàn)softmax多分類器(含具體代碼與示例數(shù)據(jù)集)_Twilight Sparkle.的博客-CSDN博客
補(bǔ)充:F1-score評價指標(biāo)
關(guān)于
混淆矩陣與F1-score詳解現(xiàn)已更新。詳細(xì)介紹請見文章:
【機(jī)器學(xué)習(xí)筆記15】多分類混淆矩陣、F1-score指標(biāo)詳解與代碼實現(xiàn)(含數(shù)據(jù))_Twilight Sparkle.的博客-CSDN博客
F1-Score簡介
F1分?jǐn)?shù)(F1 Score),是統(tǒng)計學(xué)中用來衡量二分類模型精確度的一種指標(biāo)。它同時兼顧了分類模型的精確率和召回率。F1分?jǐn)?shù)可以看作是模型精確率和召回率的一種加權(quán)平均,它的最大值是1,最小值是0。
相關(guān)概念
下面先介紹幾個概念:
TP(rue Positive):正樣本被判定為正樣本 FP(False Positive):負(fù)樣本被判定為正樣本 TN(True Negative):負(fù)樣本被判定為負(fù)樣本 FN(False Negative):正樣本被判定為負(fù)樣本
精確度/查準(zhǔn)率:指分類器預(yù)測為正例中正樣本所占比重:
召回率/查全率:指預(yù)測為正例占總正例比重:
F-Score算法將同時使用以上兩個公式,此外,介紹另一種常用的準(zhǔn)確率概念:
準(zhǔn)確率,指分類器判斷正確的占總樣本的比重:
F-Score
具體來源等等就不拓展了,有興趣可以自查。
F-Score是可以綜合考慮精確度(Precision)和召回率(Recall)的調(diào)和值,公式如下:
當(dāng)時,被稱為F1-Score或F1-Measure。此時精確度和召回率權(quán)重相同。
當(dāng)我們認(rèn)為精確度更重要,調(diào)整;
當(dāng)我們認(rèn)為召回率更重要,調(diào)整。
示例及代碼:
數(shù)據(jù)來源:Pumpkin Seeds Dataset | Kaggle
問題描述:
現(xiàn)在有兩類南瓜種子(CERCEVELIK, URGUP_SIVRISI)以及它們的一些特征:
@ATTRIBUTE Area ? ?INTEGER @ATTRIBUTE Perimeter ? ?REAL @ATTRIBUTE Major_Axis_Length ? ?REAL @ATTRIBUTE Minor_Axis_Length ? ?REAL @ATTRIBUTE Convex_Area ? ?INTEGER @ATTRIBUTE Equiv_Diameter ? ?REAL @ATTRIBUTE Eccentricity ? ?REAL @ATTRIBUTE Solidity ? ?REAL @ATTRIBUTE Extent ? ?REAL @ATTRIBUTE Roundness ? ?REAL @ATTRIBUTE Aspect_Ration ? ?REAL @ATTRIBUTE Compactness ? ?REAL
現(xiàn)在請根據(jù)已知數(shù)據(jù)集對這兩類南瓜種子進(jìn)行(邏輯回歸)分類并判斷準(zhǔn)確率。
代碼說明:會使用sklearn進(jìn)行數(shù)據(jù)分割以及評價模型(F1-score),邏輯回歸部分全部自主實現(xiàn)。
?所需要的包
import pandas as pd
import numpy as np
import math,copy
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
數(shù)據(jù)預(yù)處理
為了可視化,這里只選擇其中兩個特征作為特征集(Major_Axis_Length、Minor_Axis_Length)。
導(dǎo)入和提取數(shù)據(jù)、拆分訓(xùn)練集和數(shù)據(jù)集:
# 導(dǎo)入數(shù)據(jù)
data = pd.read_excel(r'.\Pumpkin_Seeds_Dataset\Pumpkin_Seeds_Dataset.xlsx',0)
df = pd.DataFrame(data)
# 轉(zhuǎn)換數(shù)據(jù)
color = []
label = []
for i in df['Class']:
if i == '?er?evelik':
label.append(0)
elif i == 'ürgüp Sivrisi':
label.append(1)
# 提取所需數(shù)據(jù)
x_1 = np.array(df['Major_Axis_Length']).reshape(-1,1)
x_2 = np.array(df['Minor_Axis_Length']).reshape(-1, 1)
X_features = np.c_[x_1,x_2]
Y_target = np.array(label)
# 拆分訓(xùn)練集和測試集
X_train,X_test,y_train,y_test = train_test_split(X_features,Y_target,train_size=0.5,random_state=45)
特征縮放(Z-score標(biāo)準(zhǔn)化)
注意:特征縮放一定要用對地方,應(yīng)該在拆分完訓(xùn)練集和測試集后,僅對訓(xùn)練集使用,不應(yīng)該把訓(xùn)練集和測試集放在一起標(biāo)準(zhǔn)化,對測試集的操作應(yīng)該是在對訓(xùn)練集標(biāo)準(zhǔn)化后,使用通過訓(xùn)練集標(biāo)準(zhǔn)化時計算得到的平均值、方差等進(jìn)行標(biāo)準(zhǔn)化。
這里使用Z-score標(biāo)準(zhǔn)化進(jìn)行特征縮放。
# Z-score標(biāo)準(zhǔn)化
def Zscore(X):
'''x是(m,n)的矩陣,m為樣本個數(shù),n為特征數(shù)目'''
# 找每列(特征)均值
mu = np.mean(X,axis=0)
# 找每列(特征)標(biāo)準(zhǔn)差
sigma = np.std(X,axis=0)
X_norm = (X - mu) / sigma
return X_norm,mu,sigma
# 標(biāo)準(zhǔn)化特征集
X_train,mu,sigma = Zscore(X_train)
# 繪制訓(xùn)練集
for i in y_train:
if i == 1:
color.append("blue")
else:
color.append("orange")
plt.scatter(X_train[:,0],X_train[:,1],color = color)
plt.xlabel('Major_Axis_Length')
plt.ylabel('Minor_Axis_Length')
plt.show()
?標(biāo)準(zhǔn)化后的訓(xùn)練集:
?注:橘色為?er?evelik種類,藍(lán)色為ürgüp Sivrisi種類。
實現(xiàn)邏輯回歸
sigmoid函數(shù)
公式:
def sigmoid(z):
'''
:param z: 標(biāo)量
:return: 標(biāo)量
'''
g = 1 / (1 + np.exp(-z))
return g
損失函數(shù)
公式:
# 邏輯回歸損失函數(shù)
def compute_cost_logistic(X, y, w, b):
'''
:param X: 特征集,矩陣
:param y: 目標(biāo)值,列表
:param w: 向量
:param b: 標(biāo)量
:return: 對數(shù)損失值,標(biāo)量
'''
m = X.shape[0]
cost = 0.0
for i in range(m):
z_i = np.dot(X[i],w)+b
g_wb_i = sigmoid(z_i)
cost += -y[i]*np.log(g_wb_i) - (1-y[i])*np.log(1-g_wb_i)
cost = cost/m
return cost
梯度計算函數(shù)(求偏導(dǎo))
公式:
其中,
def compute_gradient_logistic(X, y, w, b):
'''
:param X: 特征集,矩陣
:param y: 目標(biāo)值,列表
:param w: 向量
:param b: 標(biāo)量
:return:
dj_dw: 對數(shù)損失函數(shù)對向量w的偏導(dǎo)
dj_db: 對數(shù)損失函數(shù)對b的偏導(dǎo)
'''
m,n = X.shape
dj_dw = np.zeros((n,))
dj_db = 0.0
for i in range(m):
g_wb_x = sigmoid(np.dot(X[i],w)+b)
dj_db = dj_db + g_wb_x - y[i]
for j in range(n):
dj_dw[j] = dj_dw[j] + (g_wb_x - y[i])*X[i,j]
dj_dw = dj_dw/m
dj_db = dj_db/m
return dj_dw,dj_db
梯度迭代函數(shù)
公式:重復(fù)以下直到收斂
def logistic_regression(X_train,y_train,alpha,num_iters):
'''
:param X_train: 特征集,矩陣
:param y_train: 目標(biāo)值,列表
:param alpha: 學(xué)習(xí)率,標(biāo)量
:param num_iters: 訓(xùn)練次數(shù),標(biāo)量
:return:
w: 訓(xùn)練得出的w,向量
b: 訓(xùn)練得出的b,標(biāo)量
'''
m,n = X_train.shape
init_w = np.zeros((n,)) # n個特征,所以w有n個
init_b = 0
w = copy.deepcopy(init_w)
b = init_b
for i in range(num_iters):
if i%100 == 0:
print(i)
dj_dw,dj_db = compute_gradient_logistic(X_train,y_train,w,b)
w = w - alpha*dj_dw
b = b - alpha*dj_db
return w,b
訓(xùn)練數(shù)據(jù)集,繪制擬合決策邊界
model_w,model_b = logistic_regression(X_train,y_train,alpha=0.4,num_iters=10000)
x_line = np.c_[np.arange(-4,4,0.1).reshape(-1,1),np.arange(-4,4,0.1).reshape(-1,1)]
print(model_w)
y_line = np.dot(x_line,model_w)+model_b
plt.plot(x_line,y_line,label = 'Predicted Value')
plt.show()
這是當(dāng)訓(xùn)練次數(shù)為10000時得出的決策邊界:
模型預(yù)測和評價
算出后,代入,閾值為0.5。大于等于0.5為1類,小于0.5為0類。
注意預(yù)測之前要先將特征測試集標(biāo)準(zhǔn)化。
這里使用F1-Score(F1分?jǐn)?shù))進(jìn)行評價。
# 模型預(yù)測
def model_predict(X,w,b):
'''
:param X: 測試集
:param w: 向量
:param b: 標(biāo)量
:return: 預(yù)測值(列表)
'''
y = []
for i in X:
if sigmoid(np.dot(i,w)+b) >= 0.5:
y.append(1)
else:
y.append(0)
return y
# 模型預(yù)測
X_test = (X_test - mu) / sigma
y_predict = model_predict(X_test,model_w,model_b)
f1_score = f1_score(y_test,y_predict,average='binary')
print(f"F1分?jǐn)?shù)為:{round(f1_score,2)}")
?結(jié)果:
補(bǔ)充:現(xiàn)在將特征集擴(kuò)大到所有
直接上結(jié)果:
稍微比原來準(zhǔn)確了一丟丟。
補(bǔ)充:使用sklearn完成邏輯回歸
前面講了一大堆,實際上sklearn幾行代碼搞定~
淚目
還是剛才那個數(shù)據(jù)(擴(kuò)大到所有特征后的),直接上代碼!
import pandas as pd
import numpy as np
import math,copy
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import f1_score
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
data = pd.read_excel(r'.\Pumpkin_Seeds_Dataset\Pumpkin_Seeds_Dataset.xlsx', 0)
df = pd.DataFrame(data)
label = []
for i in df['Class']:
if i == '?er?evelik':
label.append(0)
elif i == 'ürgüp Sivrisi':
label.append(1)
X_features_bk = np.array(df)
X_features = X_features_bk[:,:-1]
X_features = np.float32(X_features)
Y_target = np.array(label)
# 拆分訓(xùn)練集和測試集
X_train,X_test,y_train,y_test = train_test_split(X_features,Y_target,train_size=0.5,random_state=45)
# 使用sklearn進(jìn)行Z-score標(biāo)準(zhǔn)化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train) # 標(biāo)準(zhǔn)化訓(xùn)練集X
# 繪制訓(xùn)練集
color = []
for i in y_train:
if i == 1:
color.append("blue")
else:
color.append("orange")
plt.scatter(X_train[:, 2], X_train[:, 3], color=color)
plt.xlabel('Major_Axis_Length')
plt.ylabel('Minor_Axis_Length')
plt.show()
# 訓(xùn)練邏輯回歸模型
lr_model = LogisticRegression()
lr_model.fit(X_train,y_train)
# 標(biāo)準(zhǔn)化測試集x
# 只有訓(xùn)練集才fit_transform,測試集是transform,原因上面自己寫代碼的時候說過了
X_test = scaler.transform(X_test)
# 預(yù)測
y_pred = lr_model.predict(X_test)
# F1-Score評估
f1_score = f1_score(y_test,y_pred,average='binary')
print(f"F1分?jǐn)?shù)為:{round(f1_score,2)}")
?中間我們拿出之前那兩列來畫了下圖,這個圖是同樣的隨機(jī)種子,采用sklearn的Z-score標(biāo)準(zhǔn)化后得出的圖像:
對比我們之前自己處理的數(shù)據(jù),只能說,完全一致好吧。
然后來看看結(jié)果:
甚至比我們自己寫的差了這么一丟丟。導(dǎo)致這個的原因是它的學(xué)習(xí)率和訓(xùn)練次數(shù)和我們選的不一樣,不過計算速度比我們快很多,我估計它訓(xùn)練次數(shù)選的比較少。如果我們調(diào)整自己的參數(shù),也可以達(dá)到同樣的效果!
柚子快報激活碼778899分享:【機(jī)器學(xué)習(xí)筆記4】邏輯回歸模型
參考閱讀
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。