基于sklearn的LogisticRegression二分类实践
生活随笔
收集整理的這篇文章主要介紹了
基于sklearn的LogisticRegression二分类实践
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1. 預備知識
- 2. 實踐代碼
- 3. 結果對比
- 3.1 正態分布
- 3.2 均勻分布
- 3.3 修改Pipeline
- 3.3.1 刪除多項式轉換
- 3.3.2 刪除歸一化項
- 3.3.3 刪除多項式轉換&歸一化
- 3.4 總結
- 4. 附
- 4.1 matplotlib.pyplot.contourf
- 4.2 numpy 之 np.r_[a,b], np.c_[a,b]
本文使用 sklearn的邏輯斯諦回歸模型,進行二分類預測,并通過調整各種參數,對預測結果進行對比。
1. 預備知識
邏輯斯諦回歸模型( Logistic Regression,LR)
范數(norm) 幾種范數的簡單介紹
- L0 范數:∣∣X∣∣0=#(i∣xi≠0)||X||_0 = \#(i|x_i\neq 0)∣∣X∣∣0?=#(i∣xi??=0) 向量中非零元素個數,由于它沒有一個好的數學表示,難以應用。
- L1 范數:∣∣X∣∣1=∑i=1n∣xi∣||X||_1 = \sum\limits_{i=1}^n |x_i|∣∣X∣∣1?=i=1∑n?∣xi?∣ 表示非零元素的絕對值之和
- L2 范數:∣∣X∣∣2=∑i=1nxi2||X||_2 = \sqrt{\sum\limits_{i=1}^n {x_i}^2}∣∣X∣∣2?=i=1∑n?xi?2? 表示元素的平方和再開方
機器學習——正則化 (L1與L2范數)
- 一般來說,監督學習可以看做最小化下面的目標函數:
ω?=arg?min?ω∑iL(yi,f(xi;ω))+λΩ(ω)\omega^* = \argmin\limits_\omega \sum\limits_i L(y_i, f(x_i;\omega))+\lambda \Omega(\omega)ω?=ωargmin?i∑?L(yi?,f(xi?;ω))+λΩ(ω) LLL 是損失項(訓練誤差),Ω\OmegaΩ 項是對參數 ω\omegaω 的規則化函數,去約束模型,使之盡量簡單,λ\lambdaλ 為系數,在sklearn的參數中 C=1/λC = 1/\lambdaC=1/λ。 - L1 范數是指向量中各個元素絕對值之和,也叫“稀疏規則算子”(Lasso regularization)
- L1 范數和 L0 范數可以實現稀疏(趨于產生少量特征,其他為0),L1 因具有比 L0 更好的優化求解特性而被廣泛應用。
- L2 范數是指向量各元素的平方和然后求平方根
- L2 范數可以防止過擬合,提升模型的泛化能力(選擇更多的特征,特征都會接近0)。
sklearn中的LogisticRegression模型一文對模型的參數進行了說明
sklearn 中文文檔 https://sklearn.apachecn.org/docs/0.21.3/
2. 實踐代碼
- 生成以y=-x^2+1.5為分類線的數據集
- 為增加模型學習難度,將隨機抽取的10%的數據強行賦值為正類
- 嘗試通過特征的多項式升維、歸一化,然后交給LR模型,訓練一個分類曲線。
- 為了學習到合適的分類曲線,我們嘗試了不同的參數組合
3. 結果對比
3.1 正態分布
當樣本為正態分布時:X = np.random.normal(0, 1, size=(n, 2)) # 正態分布,中心0,標準差1
| 200組數據、seed(520) | ||||||
| 準確率 | 0.9500 | 0.9500 | 0.9167 | 0.9333 | 0.9333 | |
| 200組數據、seed(777) | ||||||
| 準確率 | 0.9333 | 0.9333 | 0.9333 | 0.8833 | 0.9167 | |
| 2000組數據 seed(520) | ||||||
| 準確率 | 0.9333 | 0.9217 | 0.9317 | 0.9233 | 0.9317 | |
| 2000組數據 seed(777) | ||||||
| 準確率 | 0.9117 | 0.8983 | 0.9233 | 0.9067 | 0.9150 |
對比可以發現:
- 對比 1,2 列,數據越密集的區域,越容易學到準確的分類邊界,且容易克服噪聲的影響;
- 隨機種子seed不一樣,產生的樣本集合不同,在假設的分類模型比較接近真實分類界線(y=-x^2+1.5),隨著數據增加,學習到的模型越靠譜;在假設的分類模型比真實分類界限復雜時,在數據密集區域,隨著數據增多,配合上正則化,依然可以學習到更準確的模型。在數據稀釋區域,模型的復雜度很高,且受噪聲數據影響比較大。
- degree的增加,可以產生高階的曲線分界
- 對比 3,4 列,C越大,正則化項作用越小,曲線會越復雜,過擬合會越嚴重
- 對比 4,5 列,可見,l1 正則化下的預測分界曲線可能階數更低(非0參數更少)
- 分類線實質上是拋物線(2階),我們用20階去學習,首先2000組數據不一定充分,其次,由于正態分布數據集中在中心,邊緣區域數據覆蓋很少,所以周圍區域的分類線有時候會奇形怪狀,但中心區域的分類還是比較準確的
3.2 均勻分布
當樣本為均勻分布時:X = np.random.uniform(-4, 4, size=(n, 2)) # 均勻分布,區間[-4,4)
| 200組數據、seed(520) | ||||||
| 準確率 | 0.8500 | 0.8333 | 0.8333 | 0.8000 | 0.8333 | |
| 200組數據、seed(777) | ||||||
| 準確率 | 0.7833 | 0.7333 | 0.7667 | 0.7000 | 0.6667 | |
| 2000組數據 seed(520) | ||||||
| 準確率 | 0.8767 | 0.8750 | 0.9050 | 0.8900 | 0.8767 | |
| 2000組數據 seed(777) | ||||||
| 準確率 | 0.8883 | 0.8883 | 0.9050 | 0.9017 | 0.8950 |
- 由上面2大組實驗(X的分布形式改變),可看出均勻分布下,2000組數據下,各組參數下分類結果均比較好
- 當數據量比較小時,結果易受到seed隨機出來的樣本影響(第1,2行),同時,分類效果也不好
3.3 修改Pipeline
sklearn 的 Pipeline簡介:
- 管道機制實現了對機器學習全部步驟的流式化封裝和管理
- 前幾步是轉換器(Transformer)(如多項式轉換、歸一化等等),最后一步必須是估計器(Estimator)或叫分類器,輸入數據經過轉換器處理,輸出的結果作為下一步的輸入
- pipeline.fit生成預測模型
- pipeline.predict對數據進行預測
上面實踐代碼里Pipeline定義了模型將要做的事情:
- a. 對數據進行 多項式轉換PolynomialFeatures(維度變化)
- b. 歸一化處理StandardScaler(讓異常數據不要對正常數據造成很大影響)
- c. 邏輯斯諦回歸LogisticRegression(預測)
在均勻分布的情況下,刪除a、刪除b、刪除a,b,查看對預測的影響
3.3.1 刪除多項式轉換
| 200組數據、seed(520) | ||||||
| 準確率 | 0.7333 | 0.7333 | 0.7333 | 0.7333 | 0.7333 | |
| 200組數據、seed(777) | ||||||
| 準確率 | 0.6333 | 0.6167 | 0.6333 | 0.6167 | 0.5667 | |
| 2000組數據 seed(520) | ||||||
| 準確率 | 0.6933 | 0.6933 | 0.6933 | 0.6933 | 0.6917 | |
| 2000組數據 seed(777) | ||||||
| 準確率 | 0.6867 | 0.6867 | 0.6867 | 0.6867 | 0.6867 |
- 可以看出在刪除ploy多項式轉換項后,模型維度沒有增加,保持線性
- 預測分類線為一條直線
- 預測準確率也下降很多,不管怎么調參數,效果甚微
3.3.2 刪除歸一化項
| 200組數據、seed(520) | ||||||
| 準確率 | 0.8667 | 0.8667 | 0.8500 | 0.8500 | 0.8500(Warning) | |
| 200組數據、seed(777) | ||||||
| 準確率 | 0.8000 | 0.8000 | 0.7500 | 0.7500 | 0.7176(Warning) | |
| 2000組數據 seed(520) | 沒跑出來 | |||||
| 準確率 | 0.8767 | 0.8783 | 0.7767 | 0.7767 | - | |
| 2000組數據 seed(777) | 沒跑出來 | |||||
| 準確率 | 0.8883 | 0.8917 | 0.8100 | 0.8133 | - |
- 可以看出在2階情況下,沒有歸一化,影響不是很大
- 高階下,沒有歸一化,對結果影響很大(因為噪聲數據下,高階波動相當大,相當于系統不穩定,conditiona number很大)
3.3.3 刪除多項式轉換&歸一化
| 200組數據、seed(520) | ||||||
| 準確率 | 0.7333 | 0.7667 | 0.7333 | 0.7667 | 0.7500 | |
| 200組數據、seed(777) | ||||||
| 準確率 | 0.6167 | 0.6667 | 0.6167 | 0.6667 | 0.6333 | |
| 2000組數據 seed(520) | ||||||
| 準確率 | 0.6933 | 0.6933 | 0.6933 | 0.6933 | 0.6917 | |
| 2000組數據 seed(777) | ||||||
| 準確率 | 0.6850 | 0.6900 | 0.6850 | 0.6900 | 0.6883 |
- 沒有多項式與歸一化后,分類線表現為一條直線(沒有多項式轉換)
- 分類效果也都很差,調參效果很差
3.4 總結
- 訓練數據分布對預測結果有直接影響,數據密集的地方預測較準,數據稀疏的地方,預測不準確(噪聲,模型本身都有影響)
- 特征轉換,有助于預測出更高階的模型
- 歸一化能夠降低噪聲的影響
- 加大數據規模一定程度上能夠抗噪,提高模型準確率,重復區域高密度的數據一定程度以后,對模型預測也就失去了價值
4. 附
4.1 matplotlib.pyplot.contourf
import numpy as np import matplotlib.pyplot as plt# 計算x,y坐標對應的高度值 def f(x, y):return x**2+y<1.5# 生成x,y的數據 n = 256 x = np.linspace(-4, 4, n) y = np.linspace(-4, 4, n) # 把x,y數據生成mesh網格狀的數據,在網格的基礎上添加上高度值 X, Y = np.meshgrid(x, y) # 填充等高線 plt.contourf(X, Y, f(X, Y)) # 顯示圖表 plt.show()畫出 x**2+y = 1.5 的等高線如下
4.2 numpy 之 np.r_[a,b], np.c_[a,b]
np.r_ np.c_ 用法參考下面:>>> a array([[1, 2, 3],[7, 8, 9]]) >>> b array([[4, 5, 6],[1, 2, 3]]) >>> c=np.c_[a,b] >>> c array([[1, 2, 3, 4, 5, 6],[7, 8, 9, 1, 2, 3]]) >>> c=np.r_[a,b] >>> c array([[1, 2, 3],[7, 8, 9],[4, 5, 6],[1, 2, 3]]) >>> c=np.c_[a.ravel(),b.ravel()] # ravel()展平 >>> c array([[1, 4],[2, 5],[3, 6],[7, 1],[8, 2],[9, 3]])總結
以上是生活随笔為你收集整理的基于sklearn的LogisticRegression二分类实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode 421. 数组中两个数
- 下一篇: LeetCode 337. 打家劫舍 I