机器学习:逻辑回归
一、邏輯回歸介紹
邏輯回歸(Logistic Regression)是機器學習中的一種分類模型,邏輯回歸是一種分類算法,雖然名字中帶有回歸。由于算法的簡單和高效,在實際中應用非常廣泛。
1 邏輯回歸的應用場景
- 廣告點擊率
- 是否為垃圾郵件
- 是否患病
- 金融詐騙
- 虛假賬號
看到上面的例子,我們可以發現其中的特點,那就是都屬于兩個類別之間的判斷。邏輯回歸就是解決二分類問題的利器
2 邏輯回歸的原理
要想掌握邏輯回歸,必須掌握兩點:
- 邏輯回歸中,其輸入值是什么
- 如何判斷邏輯回歸的輸出
2.1 輸入
h(w)=w1x1+w2x2+w3x3.....+bh(w) = w_{1}x_{1} + w_{2}x_{2} + w_{3}x_{3} ..... + b h(w)=w1?x1?+w2?x2?+w3?x3?.....+b
邏輯回歸的輸入就是一個線性回歸的結果。
2.2 激活函數
-
sigmoid函數
g(wT,x)=11+e?h(w)=11+e?h(wTx)g(w^{T}, x) = \frac{1}{1+e^{-h(w)}} = \frac{1}{1+e^{-h(w^{T}x)}} g(wT,x)=1+e?h(w)1?=1+e?h(wTx)1? -
判斷標準
- 回歸的結果輸入到sigmoid函數當中
- 輸出結果:[0, 1]區間中的一個概率值,默認為0.5為閾值
邏輯回歸最終的分類是通過屬于某個類別的概率值來判斷是否屬于某個類別,并且這個類別默認標記為1(正例),另外的一個類別會標記為0(反例)。(方便損失計算)
輸出結果解釋(重要): 假設有兩個類別A,B,并且假設我們的概率值為屬于A(1)這個類別的概率值。現在有一個樣本的輸入到邏輯回歸輸出結果0.55,那么這個概率值超過0.5,意味著我們訓練或者預測的結果就是A(1)類別。那么反之,如果得出結果為0.3那么,訓練或者預測結果就為B(0)類別。
關于邏輯回歸的閾值是可以進行改變的,比如上面舉例中,如果你把閾值設置為0.6,那么輸出的結果0.55,就屬于B類。
在之前,我們用最小二乘法衡量線性回歸的損失
在邏輯回歸中,當預測結果不對的時候,我們該怎么衡量其損失呢?
我們來看下圖(下圖中,設置閾值為0.6)
那么如何去衡量邏輯回歸的預測結果與真實結果的差異呢?
3 損失以及優化
3.1 損失
邏輯回歸的損失,稱之為對數似然損失,公式如下:
- 分開類別:
其中yyy為真實值,hθ(x)h_\theta(x)hθ?(x)為預測值
怎么理解單個的式子呢?這個要根據log的函數圖像來理解
無論何時,我們都希望損失函數值,越小越好
分情況討論,對應的損失函數值:
- 當y=1時,我們希望hθ(x)h_\theta(x)hθ?(x)值越大越好;
- 當y=0時,我們希望hθ(x)h_\theta(x)hθ?(x)值越小越好
- 綜合完整損失函數
接下來我們呢就帶入上面那個例子來計算一遍,就能理解意義了。
我們已經知道,?log(P)-log(P)?log(P), PPP值越大,結果越小,所以我們可以對著這個損失的式子去分析
3.2 優化
同樣使用梯度下降優化算法,去減少損失函數的值。這樣去更新邏輯回歸前面對應算法的權重參數,提升原本屬于1類別的概率,降低原本是0類別的概率。
二、邏輯回歸api介紹
sklearn.linear_model.LogisticRegression(solver='liblinear', penalty=‘l2’, C = 1.0)
- solver可選參數:{‘liblinear’, ‘sag’, ‘saga’,‘newton-cg’, ‘lbfgs’},
- 默認: ‘liblinear’;用于優化問題的算法。
- 對于小數據集來說,“liblinear”是個不錯的選擇,而“sag”和’saga’對于大型數據集會更快。
- 對于多類問題,只有’newton-cg’, ‘sag’, 'saga’和’lbfgs’可以處理多項損失;“liblinear”僅限于“one-versus-rest”分類。
- penalty:正則化的種類
- C:正則化力度
默認將類別數量少的當做正例
LogisticRegression方法相當于 SGDClassifier(loss=“log”, penalty=" "),SGDClassifier實現了一個普通的隨機梯度下降學習。而使用LogisticRegression(實現了SAG)
三、案例:癌癥分類預測-良/惡性乳腺癌腫瘤預測
1 背景介紹
數據介紹
原始數據的下載地址
數據描述:
(1)699條樣本,共11列數據,第一列用語檢索的id,后9列分別是與腫瘤
相關的醫學特征,最后一列表示腫瘤類型的數值。
(2)包含16個缺失值,用”?”標出。
2 案例分析
1.獲取數據 2.基本數據處理 2.1 缺失值處理 2.2 確定特征值,目標值 2.3 分割數據 3.特征工程(標準化) 4.機器學習(邏輯回歸) 5.模型評估3 代碼實現
import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.linear_model import LogisticRegression# 如果導入數據的時候需要網址驗證,就寫以下ssl import ssl ssl._create_default_https_context = ssl._create_unverified_context # 1.獲取數據 names = ['Sample code number', 'Clump Thickness', 'Uniformity of Cell Size', 'Uniformity of Cell Shape','Marginal Adhesion', 'Single Epithelial Cell Size', 'Bare Nuclei', 'Bland Chromatin','Normal Nucleoli', 'Mitoses', 'Class']data = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/breast-cancer-wisconsin/breast-cancer-wisconsin.data",names=names) data.head() # 2.基本數據處理 # 2.1 缺失值處理 data = data.replace(to_replace="?", value=np.NaN) data = data.dropna() # 2.2 確定特征值,目標值 x = data.iloc[:, 1:10] x.head() y = data["Class"] y.head() # 2.3 分割數據 x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=22) # 3.特征工程(標準化) transfer = StandardScaler() x_train = transfer.fit_transform(x_train) x_test = transfer.transform(x_test) # 4.機器學習(邏輯回歸) estimator = LogisticRegression() estimator.fit(x_train, y_train) # 5.模型評估 y_predict = estimator.predict(x_test) y_predict estimator.score(x_test, y_test)在很多分類場景當中我們不一定只關注預測的準確率!!!!!
比如以這個癌癥舉例子!!!我們并不關注預測的準確率,而是關注在所有的樣本當中,癌癥患者有沒有被全部預測(檢測)出來。
四、分類評估方法
1.分類評估方法
1.1 精確率與召回率
1.1.1 混淆矩陣
在分類任務下,預測結果(Predicted Condition)與正確標記(True Condition)之間存在四種不同的組合,構成混淆矩陣(適用于多分類)
1.1.2 精確率(Precision)與召回率(Recall)
- 精確率(查準率):預測結果為正例樣本中真實為正例的比例(了解)
- 召回率(查全率):真實為正例的樣本中預測結果為正例的比例(查得全,對正樣本的區分能力)
1.2 F1-score
還有其他的評估標準,F1-score,反映了模型的穩健型
1.3 分類評估報告api
sklearn.metrics.classification_report(y_true, y_pred, labels=[], target_names=None )
- y_true:真實目標值
- y_pred:估計器預測目標值
- labels:指定類別對應的數字
- target_names:目標類別名稱
- return:每個類別精確率與召回率
假設這樣一個情況,如果99個樣本癌癥,1個樣本非癌癥,不管怎樣我全都預測正例(默認癌癥為正例),準確率就為99%但是這樣效果并不好,這就是樣本不均衡下的評估問題
問題:如何衡量樣本不均衡下的評估?
2 ROC曲線與AUC指標
2.1 TPR與FPR
TPR=TPTP+FNTPR = \frac{TP}{TP + FN}TPR=TP+FNTP?
- 所有真實類別為1的樣本中,預測類別為1的比例
FPR=FPFP+TNFPR = \frac{FP}{FP + TN}FPR=FP+TNFP?
- 所有真實類別為0的樣本中,預測類別為1的比例
2.2 ROC曲線
ROC曲線的橫軸就是FPRate,縱軸就是TPRate,當二者相等時,表示的意義則是:對于不論真實類別是1還是0的樣本,分類器預測為1的概率是相等的,此時AUC為0.5
2.3 AUC指標
- AUC的概率意義是隨機取一對正負樣本,正樣本得分大于負樣本得分的概率
- AUC的范圍在[0, 1]之間,并且越接近1越好,越接近0.5屬于亂猜
- AUC=1,完美分類器,采用這個預測模型時,不管設定什么閾值都能得出完美預測。絕大多數預測的場合,不存在完美分類器。
- 0.5<AUC<1,優于隨機猜測。這個分類器(模型)妥善設定閾值的話,能有預測價值。
2.4 AUC計算API
from sklearn.metrics import roc_auc_scoresklearn.metrics.roc_auc_score(y_true, y_score)
- 計算ROC曲線面積,即AUC值
- y_true:每個樣本的真實類別,必須為0(反例),1(正例)標記
- y_score:預測得分,可以是正類的估計概率、置信值或者分類器方法的返回值
- AUC只能用來評價二分類
- AUC非常適合評價樣本不平衡中的分類器性能
五、ROC曲線的繪制
關于ROC曲線的繪制過程,通過以下舉例進行說明
假設有6次展示記錄,有兩次被點擊了,得到一個展示序列(1:1,2:0,3:1,4:0,5:0,6:0),前面的表示序號,后面的表示點擊(1)或沒有點擊(0)。
然后在這6次展示的時候都通過model算出了點擊的概率序列。
下面看三種情況。
1 曲線繪制
1.1 如果概率的序列是(1:0.9,2:0.7,3:0.8,4:0.6,5:0.5,6:0.4)
與原來的序列一起,得到序列(從概率從高到低排)
| 0.9 | 0.8 | 0.7 | 0.6 | 0.5 | 0.4 |
繪制的步驟是:
1)把概率序列從高到低排序,得到順序(1:0.9,3:0.8,2:0.7,4:0.6,5:0.5,6:0.4);
2)從概率最大開始取一個點作為正類,取到點1,計算得到TPR=0.5,FPR=0.0;
3)從概率最大開始,再取一個點作為正類,取到點3,計算得到TPR=1.0,FPR=0.0;
4)再從最大開始取一個點作為正類,取到點2,計算得到TPR=1.0,FPR=0.25;
5)以此類推,得到6對TPR和FPR。
然后把這6對數據組成6個點(0,0.5),(0,1.0),(0.25,1),(0.5,1),(0.75,1),(1.0,1.0)。
這6個點在二維坐標系中能繪出來。
看看圖中,那個就是ROC曲線。
1.2 如果概率的序列是(1:0.9,2:0.8,3:0.7,4:0.6,5:0.5,6:0.4)
| 0.9 | 0.8 | 0.7 | 0.6 | 0.5 | 0.4 |
繪制的步驟是:
6)把概率序列從高到低排序,得到順序(1:0.9,2:0.8,3:0.7,4:0.6,5:0.5,6:0.4);
7)從概率最大開始取一個點作為正類,取到點1,計算得到TPR=0.5,FPR=0.0;
8)從概率最大開始,再取一個點作為正類,取到點2,計算得到TPR=0.5,FPR=0.25;
9)再從最大開始取一個點作為正類,取到點3,計算得到TPR=1.0,FPR=0.25;
10)以此類推,得到6對TPR和FPR。
然后把這6對數據組成6個點(0,0.5),(0.25,0.5),(0.25,1),(0.5,1),(0.75,1),(1.0,1.0)。
這6個點在二維坐標系中能繪出來。
看看圖中,那個就是ROC曲線。
1.3 如果概率的序列是(1:0.4,2:0.6,3:0.5,4:0.7,5:0.8,6:0.9)
與原來的序列一起,得到序列(從概率從高到低排)
| 0.9 | 0.8 | 0.7 | 0.6 | 0.5 | 0.4 |
繪制的步驟是:
11)把概率序列從高到低排序,得到順序(6:0.9,5:0.8,4:0.7,2:0.6,3:0.5,1:0.4);
12)從概率最大開始取一個點作為正類,取到點6,計算得到TPR=0.0,FPR=0.25;
13)從概率最大開始,再取一個點作為正類,取到點5,計算得到TPR=0.0,FPR=0.5;
14)再從最大開始取一個點作為正類,取到點4,計算得到TPR=0.0,FPR=0.75;
15)以此類推,得到6對TPR和FPR。
然后把這6對數據組成6個點(0.25,0.0),(0.5,0.0),(0.75,0.0),(1.0,0.0),(1.0,0.5),(1.0,1.0)。
這6個點在二維坐標系中能繪出來。
看看圖中,那個就是ROC曲線。
2 意義解釋
如上圖的例子,總共6個點,2個正樣本,4個負樣本,取一個正樣本和一個負樣本的情況總共有8種。
上面的第一種情況,從上往下取,無論怎么取,正樣本的概率總在負樣本之上,所以分對的概率為1,AUC=1。再看那個ROC曲線,它的積分是什么?也是1,ROC曲線的積分與AUC相等。
上面第二種情況,如果取到了樣本2和3,那就分錯了,其他情況都分對了;所以分對的概率是0.875,AUC=0.875。再看那個ROC曲線,它的積分也是0.875,ROC曲線的積分與AUC相等。
上面的第三種情況,無論怎么取,都是分錯的,所以分對的概率是0,AUC=0.0。再看ROC曲線,它的積分也是0.0,ROC曲線的積分與AUC相等。
很牛吧,其實AUC的意思是——Area Under roc Curve,就是ROC曲線的積分,也是ROC曲線下面的面積。
繪制ROC曲線的意義很明顯,不斷地把可能分錯的情況扣除掉,從概率最高往下取的點,每有一個是負樣本,就會導致分錯排在它下面的所有正樣本,所以要把它下面的正樣本數扣除掉(1-TPR,剩下的正樣本的比例)。總的ROC曲線繪制出來了,AUC就定了,分對的概率也能求出來了。
六、補充內容:分類中解決類別不平衡問題
1 類別不平衡數據集基本介紹
在這一節中,我們一起看一下,當遇到數據類別不平衡的時候,我們該如何處理。在Python中,有Imblearn包,它就是為處理數據比例失衡而生的。
- 安裝Imblearn包:pip3 install imbalanced-learn
- 創造數據集
- 查看各個標簽的樣本
- 數據集可視化
可以看出樣本的三個標簽中,1,2的樣本量極少,樣本失衡。下面使用imblearn進行過采樣。
接下來,我們就要基于以上數據,進行相應的處理。
關于類別不平衡的問題,主要有兩種處理方式:
- 過采樣方法
增加數量較少那一類樣本的數量,使得正負樣本比例均衡。 - 欠采樣方法
減少數量較多那一類樣本的數量,使得正負樣本比例均衡。
2 解決類別不平衡數據方法介紹
2.1 過采樣方法
2.1.1 什么是過采樣方法
對訓練集里的少數類進行“過采樣”(oversampling),即增加一些少數類樣本使得正、反例數目接近,然后再進行學習。
2.1.2 隨機過采樣方法
隨機過采樣是在少數類 SminS_{min}Smin? 中隨機選擇一些樣本,然后通過復制所選擇的樣本生成樣本集 EEE ,將它們添加到 SminS_{min}Smin? 中來擴大原始數據集從而得到新的少數類集合 Snew?minS_{new-min}Snew?min? 。新的數據集 Snew?min=Smin+ES_{new-min} = S_{min} + ESnew?min?=Smin?+E 。
通過代碼實現隨機過采樣方法:
# 使用imblearn進行隨機過采樣 from imblearn.over_sampling import RandomOverSampler ros = RandomOverSampler(random_state=0) X_resampled, y_resampled = ros.fit_resample(X, y) #查看結果 Counter(y_resampled)#過采樣后樣本結果 # Counter({2: 4674, 1: 4674, 0: 4674})# 數據集可視化 plt.scatter(X_resampled[:, 0], X_resampled[:, 1], c=y_resampled) plt.show()缺點:
- 對于隨機過采樣,由于需要對少數類樣本進行復制來擴大數據集,造成模型訓練復雜度加大。
- 另一方面也容易造成模型的過擬合問題,因為隨機過采樣是簡單的對初始樣本進行復制采樣,這就使得學習器學得的規則過于具體化,不利于學習器的泛化性能,造成過擬合問題。
為了解決隨機過采樣中造成模型過擬合問題,又能保證實現數據集均衡的目的,出現了過采樣法代表性的算法SMOTE算法。
2.1.3 過采樣代表性算法-SMOTE
SMOTE全稱是Synthetic Minority Oversampling即合成少數類過采樣技術。
SMOTE算法是對隨機過采樣方法的一個改進算法,由于隨機過采樣方法是直接對少數類進行重采用,會使訓練集中有很多重復的樣本,容易造成產生的模型過擬合問題。而SMOTE算法的基本思想是對每個少數類樣本 xix_ixi? ,從它的最近鄰中隨機選擇一個樣本 xi^\hat{x_i}xi?^? ( xi^\hat{x_i}xi?^? 是少數類中的一個樣本),然后在 xix_ixi? 和 xi^\hat{x_i}xi?^? 之間的連線上隨機選擇一點作為新合成的少數類樣本。
SMOTE算法合成新少數類樣本的算法描述如下:
xnew=xi+rand(0,1)×(xi^?xi)x_{new} = x_i + rand(0,1) \times (\hat{x_i}-x_i) xnew?=xi?+rand(0,1)×(xi?^??xi?)
我們用圖文表達的方式,再來描述一下SMOTE算法
4)在少數類樣本 xix_ixi? 和被選中的這個近鄰樣本 xi^\hat{x_i}xi?^? 之間的連線上,隨機找一點。這個點就是人工合成的新的樣本點(綠色正號標出)
SMOTE算法摒棄了隨機過采樣復制樣本的做法,可以防止隨機過采樣中容易過擬合的問題,實踐證明此方法可以提高分類器的性能。
代碼實現:
# SMOTE過采樣 from imblearn.over_sampling import SMOTE X_resampled, y_resampled = SMOTE().fit_resample(X, y) Counter(y_resampled)# 采樣后樣本結果 # [(0, 4674), (1, 4674), (2, 4674)]# 數據集可視化 plt.scatter(X_resampled[:, 0], X_resampled[:, 1], c=y_resampled) plt.show()2.2 欠采樣方法
2.2.1 什么是欠采樣方法
直接對訓練集中多數類樣本進行“欠采樣”(undersampling),即去除一些多數類中的樣本使得正例、反例數目接近,然后再進行學習。
2.2.2 隨機欠采樣方法
隨機欠采樣顧名思義即從多數類 SmajS_{maj}Smaj? 中隨機選擇一些樣樣本組成樣本集 EEE ,然后將樣本集 EEE 從 SmajS_{maj}Smaj? 中移除。新的數據集 Snew?maj=Smaj?ES_{new-maj} = S_{maj} -ESnew?maj?=Smaj??E 。
代碼實現:
# 隨機欠采樣 from imblearn.under_sampling import RandomUnderSampler rus = RandomUnderSampler(random_state=0) X_resampled, y_resampled = rus.fit_resample(X, y) Counter(y_resampled)# 采樣后結果 [(0, 64), (1, 64), (2, 64)]# 數據集可視化 plt.scatter(X_resampled[:, 0], X_resampled[:, 1], c=y_resampled) plt.show()缺點:
- 隨機欠采樣方法通過改變多數類樣本比例以達到修改樣本分布的目的,從而使樣本分布較為均衡,但是這也存在一些問題。對于隨機欠采樣,由于采樣的樣本集合要少于原來的樣本集合,因此會造成一些信息缺失,即將多數類樣本刪除有可能會導致分類器丟失有關多數類的重要信息。
上一篇:機器學習:線性回歸
下一篇:機器學習:決策樹
總結
- 上一篇: WIN8的孩子注意啦——微软黑屏来了!
- 下一篇: Java IDE MyEclipse 使