EduCoder 机器学习 逻辑回归
邏輯回歸是屬于機器學習里面的監督學習,它是以回歸的思想來解決分類問題的一種非常經典的二分類分類器。由于其訓練后的參數有較強的可解釋性,在諸多領域中,邏輯回歸通常用作 baseline 模型,以方便后期更好的挖掘業務相關信息或提升模型性能。
本實訓項目的主要內容是基于 Python 語言搭建出一個能夠識別惡性腫瘤的邏輯回歸模型,并使用 sklearn 中的 LogisticRegression 實現手寫數字識別。
第1關:邏輯回歸核心思想
- 任務描述
- 相關知識
- 什么是邏輯回歸
- sigmoid 函數
- 編程要求
- 測試說明
任務描述
本關任務:根據本節課所學知識完成本關所設置的編程題。
相關知識
為了完成本關任務,你需要掌握:
什么是邏輯回歸;
sigmoid函數。
什么是邏輯回歸
當一看到“回歸”這兩個字,可能會認為邏輯回歸是一種解決回歸問題的算法,然而邏輯回歸是通過回歸的思想來解決二分類問題的算法。
那么問題來了,回歸的算法怎樣解決分類問題呢?其實很簡單,邏輯回歸是將樣本特征和樣本所屬類別的概率聯系在一起,假設現在已經訓練好了一個邏輯回歸的模型為 f(x) ,模型的輸出是樣本 x 的標簽是 1 的概率,則該模型可以表示, p^?=f(x) 。若得到了樣本 x 屬于標簽 1 的概率后,很自然的就能想到當 p^?>0.5 時 x 屬于標簽 1 ,否則屬于標簽 0 。所以就有
y^?={01?p^?<0.5p^?>0.5?
(其中 y^? 為樣本 x 根據模型預測出的標簽結果,標簽 0 和標簽 1 所代表的含義是根據業務決定的,比如在癌細胞識別中可以使 0 代表良性腫瘤, 1 代表惡性腫瘤)。
由于概率是 0 到 1 的實數,所以邏輯回歸若只需要計算出樣本所屬標簽的概率就是一種回歸算法,若需要計算出樣本所屬標簽,則就是一種二分類算法。
那么邏輯回歸中樣本所屬標簽的概率怎樣計算呢?其實和線性回歸有關系,學習了線性回歸的同學肯定知道線性回歸無非就是訓練出一組參數 WT 和 b 來擬合樣本數據,線性回歸的輸出為 y^?=WTx+b 。不過 y^? 的值域是 (?∞,+∞) ,如果能夠將值域為 (?∞,+∞) 的實數轉換成 (0,1) 的概率值的話問題就解決了。要解決這個問題很自然地就能想到將線性回歸的輸出作為輸入,輸入到另一個函數中,這個函數能夠進行轉換工作,假設函數為 σ ,轉換后的概率為 p^? ,則邏輯回歸在預測時可以看成p^?=σ(WTx+b) 。 σ 其實就是接下來要介紹的sigmoid函數。
sigmoid 函數
sigmoid函數的公式為:
σ(t)=1/(1+e?t)
函數圖像如下圖所示:
從sigmoid函數的圖像可以看出當 t 趨近于 ?∞ 時函數值趨近于 0 ,當 t 趨近于 +∞ 時函數值趨近于 1 ??梢妔igmoid函數的值域是 (0,1) ,滿足我們要將 (?∞,+∞) 的實數轉換成 (0,1) 的概率值的需求。因此邏輯回歸在預測時可以看成
p^?=1/(1+e?WTx+b)
編程要求
根據提示,在右側編輯器補充 Python 代碼,實現sigmoid函數。底層代碼會調用您實現的sigmoid函數來進行測試。(提示: numpy.exp()函數可以實現 e 的冪運算)
測試說明
測試用例:
輸入:1
預期輸出:0.73105857863
輸入:-2
預期輸出:0.119202922022
開始你的任務吧,祝你成功!
#encoding=utf8 import numpy as npdef sigmoid(t):'''完成sigmoid函數計算:param t: 負無窮到正無窮的實數:return: 轉換后的概率值:可以考慮使用np.exp()函數'''#********** Begin **********#return 1/(1+np.exp(-1*t))#********** End **********#第2關:邏輯回歸的損失函數
- 任務描述
- 相關知識
- 為什么需要損失函數
- 邏輯回歸的損失函數
- 編程要求
- 測試說明
任務描述
本關任務:根據本節課所學知識完成本關所設置的選擇題。
相關知識
為什么需要損失函數
訓練邏輯回歸模型的過程其實與之前學習的線性回歸一樣,就是去尋找合適的 WT 和 b 使得模型的預測結果與真實結果盡可能一致。所以就需要一個函數能夠衡量模型擬合程度的好壞,也就是說當模型擬合誤差越大的時候,函數值應該比較大,反之應該比較小,這就是損失函數。
邏輯回歸的損失函數
根據上一關中所學習到的知識,我們已經知道了邏輯回歸計算出的樣本所屬類別的概率 p^?=σ(WTx+b) ,樣本所屬列表的判定條件為
y^?={01?p^?<0.5p^?>0.5?
很明顯,在預測樣本屬于哪個類別時取決于算出來的p^?。從另外一個角度來說,假設現在有一個樣本的真實類別為 1 ,模型預測樣本為類別 1 的概率為 0.9 的話,就意味著這個模型認為當前樣本的類別有 90% 的可能性為 1 ,有 10% 的可能性為0。所以從這個角度來看,邏輯回歸的損失函數與 p^? 有關。
當然邏輯回歸的損失函數不僅僅與 p^? 有關,它還與真實類別有關。假設現在有兩種情況,情況A:現在有個樣本的真實類別是 0 ,但是模型預測出來該樣本是類別 1 的概率是 0.7 (也就是說類別 0 的概率為 0.3 );情況B:現在有個樣本的真實類別是 0 ,但是模型預測出來該樣本是類別 1 的概率是 0.6 (也就是說類別 0 的概率為 0.4 );請你思考 2 秒鐘,AB兩種情況哪種情況的誤差更大?很顯然,情況A的誤差更大!因為情況A中模型認為樣本是類別 0 的可能性只有 30% ,而B有 40% 。
假設現在又有兩種情況,情況A:現在有個樣本的真實類別是 0 ,但是模型預測出來該樣本是類別 1 的概率是 0.7 (也就是說類別 0 的概率為 0.3 );情況B:現在有個樣本的真實類別是 1 ,但是模型預測出來該樣本是類別 1 的概率是 0.3 (也就是說類別 0 的概率為 0.7 );請你再思考 2 秒鐘,AB兩種情況哪種情況的誤差更大?很顯然,一樣大!
所以邏輯回歸的損失函數如下,其中 cost 表示損失函數的值, y 表示樣本的真實類別:
cost=?ylog(p^?)?(1?y)log(1?p^?)
這個式子其實很好理解,當樣本的真實類別為 1 時,式子就變成了 cost=?log(p^?)。此時函數圖像如下:
從圖像能看出當樣本的真實類別為1的前提下,p^? 越大,損失函數值就越小。因為 p^? 越大就越說明模型越認為該樣本的類別為 1 。
當樣本的真實類別為 0 時,式子就變成了 cost=?log(1?p^?) 。此時函數圖像如下:
從圖像能看出當樣本的真實類別為 0 的前提下,hatp 越大,損失函數值就越大。因為 p^? 越大就越說明模型越認為該樣本的類別為 1 。
cost=?ylog(p^?)?(1?y)log(1?p^?) 是一個樣本的損失計算公式,但是在一般情況下需要計算的是 m 條樣本數據的平均損失值,所以損失函數的最終形態如下,其中 m 表示數據集中樣本的數量, i 表示數據集中第 i 個樣本:
cost=?m1?sumi=0m?y(i)log(p^?(i))?(1?y(i))log(1?p^?(i))
知道了邏輯回歸的損失函數之后,邏輯回歸的訓練流程就很明顯了,就是尋找一組合適的 WT 和 b ,使得損失值最小。找到這組參數后模型就確定下來了。
編程要求
根據相關知識,按照要求完成右側選擇題任務,包含單選題和多選題。
測試說明
平臺會對你選擇的答案進行判斷,全對則通過測試。
開始你的任務吧,祝你成功!
1、邏輯回歸的損失函數可以寫成如下形式(A)
cost={?log(p^?)?log(1?p^?)?y=1y=0?
A、對
B、錯
2、下列說法正確的是(ACD)
A、損失值能夠衡量模型在訓練數據集上的擬合程度
B、sigmoid函數不可導
C、sigmoid函數的輸入越大,輸出就越大
D、訓練的過程,就是尋找合適的參數使得損失函數值最小的過程
3、sigmoid函數(對數幾率函數)相對于單位階躍函數有哪些好處?(AB)
A、sigmoid函數可微分
B、sigmoid函數處處連續
C、sigmoid函數不是單調的
D、sigmoid函數最多計算二階導
4、邏輯回歸的優點有哪些?(D)
A、需要事先對數據的分布做假設
B、可以得到“類別”的真正的概率預測
C、可以用閉式解求解
D、可以用現有的數值優化算法求解
第3關:梯度下降
- 任務描述
- 相關知識
- 什么是梯度
- 梯度下降算法原理
- 編程要求
- 測試說明
任務描述
本關任務:用 Python 構建梯度下降算法,并求取目標函數最小值。
相關知識
為了完成本關任務,你需要掌握:梯度下降算法。
什么是梯度
梯度:梯度的本意是一個向量,由函數對每個參數的偏導組成,表示某一函數在該點處的方向導數沿著該方向取得最大值,即函數在該點處沿著該方向變化最快,變化率最大。
梯度下降算法原理
算法思想:梯度下降是一種非常通用的優化算法,能夠為大范圍的問題找到最優解。梯度下降的中心思想就是迭代地調整參數從而使損失函數最小化。假設你迷失在山上的迷霧中,你能感覺到的只有你腳下路面的坡度??焖俚竭_山腳的一個策略就是沿著最陡的方向下坡。這就是梯度下降的做法:通過測量參數向量 θ 相關的損失函數的局部梯度,并不斷沿著降低梯度的方向調整,直到梯度降為 0 ,達到最小值。
梯度下降公式如下:
對應到每個權重公式為:
其中 η 為學習率,是 0 到 1 之間的值,是個超參數,需要我們自己來確定大小。
算法原理: 在傳統機器學習中,損失函數通常為凸函數,假設此時只有一個參數,則損失函數對參數的梯度即損失函數對參數的導數。如果剛開始參數初始在最優解的左邊,
很明顯,這個時候損失函數對參數的導數是小于 0 的,而學習率是一個 0 到 1 之間的數,此時按照公式更新參數,初始的參數減去一個小于 0 的數是變大,也就是在坐標軸上往右走,即朝著最優解的方向走。同樣的,如果參數初始在最優解的右邊,
此時按照公式更新,參數將會朝左走,即最優解的方向。所以,不管剛開始參數初始在何位置,按著梯度下降公式不斷更新,參數都會朝著最優解的方向走。 #####梯度下降算法流程
編程要求
根據提示,使用 Python 實現梯度下降算法,并損失函數最小值時對應的參數theta,theta會返回給外部代碼,由外部代碼來判斷theta是否正確。
測試說明
損失函數為:loss=2?(θ?3) 最優參數為:3.0 你的答案跟最優參數的誤差低于0.0001才能通關。
開始你的任務吧,祝你成功!
# -*- coding: utf-8 -*-import numpy as np import warnings warnings.filterwarnings("ignore")def gradient_descent(initial_theta,eta=0.05,n_iters=1000,epslion=1e-8):'''梯度下降:param initial_theta: 參數初始值,類型為float:param eta: 學習率,類型為float:param n_iters: 訓練輪數,類型為int:param epslion: 容忍誤差范圍,類型為float:return: 訓練后得到的參數'''# 請在此添加實現代碼 ##********** Begin *********#theta = initial_thetai_iter = 0while i_iter < n_iters:gradient = 2*(theta-3)last_theta = thetatheta = theta - eta*gradientif(abs(theta-last_theta)<epslion):breaki_iter +=1return theta#********** End **********#第4關:動手實現邏輯回歸 - 癌細胞精準識別
- 任務描述
- 相關知識
- 數據集介紹
- 構建邏輯回歸模型
- 訓練邏輯回歸模型
- 編程要求
- 測試說明
任務描述
本關任務:使用邏輯回歸算法建立一個模型,并通過梯度下降算法進行訓練,得到一個能夠準確對癌細胞進行識別的模型。
相關知識
為了完成本關任務,你需要掌握:
- 邏輯回歸算法流程;
- 邏輯回歸中的梯度下降。
數據集介紹
乳腺癌數據集,其實例數量是 569 ,實例中包括診斷類和屬性,幫助預測的屬性一共 30 個,各屬性包括為 radius 半徑(從中心到邊緣上點的距離的平均值), texture 紋理(灰度值的標準偏差)等等,類包括: WDBC-Malignant 惡性和 WDBC-Benign 良性。用數據集的 80% 作為訓練集,數據集的 20% 作為測試集,訓練集和測試集中都包括特征和類別。其中特征和類別均為數值類型,類別中 0 代表良性, 1 代表惡性。
構建邏輯回歸模型
由數據集可以知道,每一個樣本有 30 個特征和 1 個標簽,而我們要做的事就是通過這 30 個特征來分析細胞是良性還是惡性(其中標簽 y=0 表示是良性, y=1 表示是惡性)。邏輯回歸算法正好是一個二分類模型,我們可以構建一個邏輯回歸模型,來對癌細胞進行識別。模型如下:
z=b+w1?x1?+w2?x2?+...+wn?xn?
y=1+e?z1?
其中 xi?表示第 i 個特征,wi?表示第 i 個特征對應的權重,b表示偏置。 為了方便,我們稍微將模型進行變換:
z=w0?x0?+w1?x1?+w2?x2?+...+wn?xn?
其中x0?等于 1 。
Z=heta.X
heta=(w0?,w1?,...,wn?)
X=(1,x1?,...,xn?)
y=1+e?θ.X1?
我們將一個樣本輸入模型,如果預測值大于等于 0.5 則判定為 1 類別,如果小于 0.5 則判定為 0 類別。
訓練邏輯回歸模型
我們已經知道如何構建一個邏輯回歸模型,但是如何得到一個能正確對癌細胞進行識別的模型呢?通常,我們先將數據輸入到模型,從而得到一個預測值,再將預測值與真實值結合,得到一個損失函數,最后用梯度下降的方法來優化損失函數,從而不斷的更新模型的參數 θ ,最后得到一個能夠正確對良性細胞和癌細胞進行分類的模型。
在上一節中,我們知道要使用梯度下降算法首先要知道損失函數對參數的梯度,即損失函數對每個參數的偏導,求解步驟如下:
loss=?ylna?(1?y)ln(1?a)
?w?loss?=?a?loss?.?z?a?.?w?z?
?a?loss?=?ay??1?a1?y?(?1)=a(1?a)a?y?
?z?a?=(1+e?z)2e?z?=a.(1?a)
?w?z?=x
?w?loss?=(a?y)x
其中a為預測值,y為真實值。 于是,在邏輯回歸中的梯度下降公式如下:
wi?=wi??η(a?y)xi?
訓練流程:
同梯度下降算法流程:請參見上一關卡。
編程要求
根據提示,在右側編輯器Begin-End處補充 Python 代碼,構建一個邏輯回歸模型,并對其進行訓練,最后將得到的邏輯回歸模型對癌細胞進行識別。
測試說明
只需返回預測結果即可,程序內部會檢測您的代碼,預測正確率高于 95% 視為過關。
提示:構建模型時 x0? 是添加在數據的左邊,請根據提示構建模型,且返回theta形狀為(n,),n為特征個數。
開始你的任務吧,祝你成功!
# -*- coding: utf-8 -*-import numpy as np import warnings warnings.filterwarnings("ignore")def sigmoid(x):'''sigmoid函數:param x: 轉換前的輸入:return: 轉換后的概率'''return 1/(1+np.exp(-x))def fit(x,y,eta=1e-3,n_iters=10000):'''訓練邏輯回歸模型:param x: 訓練集特征數據,類型為ndarray:param y: 訓練集標簽,類型為ndarray:param eta: 學習率,類型為float:param n_iters: 訓練輪數,類型為int:return: 模型參數,類型為ndarray'''# 請在此添加實現代碼 ##********** Begin *********#theta = np.zeros(x.shape[1])i_iter = 0while i_iter < n_iters:gradient = (sigmoid(x.dot(theta))-y).dot(x)theta = theta -eta*gradienti_iter += 1return theta#********** End **********#第5關:手寫數字識別
- 任務描述
- 相關知識
- 數據簡介
- LogisticRegression
- 編程要求
- 測試說明
任務描述
本關任務:使用sklearn中的LogisticRegression類完成手寫數字識別任務。
相關知識
為了完成本關任務,你需要掌握如何使用sklearn提供的LogisticRegression類。
數據簡介
本關使用的是手寫數字數據集,該數據集有 1797 個樣本,每個樣本包括 8*8 像素(實際上是一條樣本有 64 個特征,每個像素看成是一個特征,每個特征都是float類型的數值)的圖像和一個 [0, 9] 整數的標簽。比如下圖的標簽是 2 :
sklearn為該數據集提供了接口,若想使用該數據集,代碼如下:
LogisticRegression
LogisticRegression中默認實現了 OVR ,因此LogisticRegression可以實現多分類。LogisticRegression的構造函數中有三個常用的參數可以設置:
solver:{'newton-cg' , 'lbfgs', 'liblinear', 'sag', 'saga'}, 分別為幾種優化算法。默認為liblinear;
C:正則化系數的倒數,默認為 1.0 ,越小代表正則化越強;
max_iter:最大訓練輪數,默認為 100 。
和sklearn中其他分類器一樣,LogisticRegression類中的fit函數用于訓練模型,fit函數有兩個向量輸入:
X:大小為 [樣本數量,特征數量] 的ndarray,存放訓練樣本;
Y:值為整型,大小為 [樣本數量] 的ndarray,存放訓練樣本的分類標簽。
LogisticRegression類中的predict函數用于預測,返回預測標簽,predict函數有一個向量輸入:
- X:大小為[樣本數量,特征數量]的ndarray,存放預測樣本。
LogisticRegression的使用代碼如下:
編程要求
填寫digit_predict(train_sample, train_label, test_sample)函數完成手寫數字識別任務,其中:
train_image:訓練集圖像,類型為ndarray,shape=[-1, 8, 8];
train_label:訓練集標簽,類型為ndarray;
test_image:測試集圖像,類型為ndarray。
測試說明
只需返回預測結果即可,程序內部會檢測您的代碼,預測正確率高于 0.97 視為過關。
開始你的任務吧,祝你成功!
from sklearn.linear_model import LogisticRegressiondef digit_predict(train_image, train_label, test_image):'''實現功能:訓練模型并輸出預測結果:param train_sample: 包含多條訓練樣本的樣本集,類型為ndarray,shape為[-1, 8, 8]:param train_label: 包含多條訓練樣本標簽的標簽集,類型為ndarray:param test_sample: 包含多條測試樣本的測試集,類型為ndarry:return: test_sample對應的預測標簽'''#************* Begin ************#flat_train_image = train_image.reshape((-1, 64))# 訓練集標準化train_min = flat_train_image.min()train_max = flat_train_image.max()flat_train_image = (flat_train_image-train_min)/(train_max-train_min)# 測試集變形flat_test_image = test_image.reshape((-1, 64))# 測試集標準化test_min = flat_test_image.min()test_max = flat_test_image.max()flat_test_image = (flat_test_image - test_min) / (test_max - test_min)# 訓練--預測rf = LogisticRegression(C=4.0)rf.fit(flat_train_image, train_label)return rf.predict(flat_test_image)#************* End **************#總結
以上是生活随笔為你收集整理的EduCoder 机器学习 逻辑回归的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode 879. 盈利计划
- 下一篇: EduCoder 机器学习 决策树