文章目錄
- 一、邏輯回歸:從線性回歸到二分類的跨越
- 1.1 邏輯回歸簡介
- 1.2 Sigmoid函數:概率映射的數學本質
- 1.3 參數 w w w 和 b b b 對Sigmoid的調控
- 1.4 從線性回歸到分類
- 1.5 決策邊界:從概率到類別(結合圖3、圖4)
- 二、似然函數與交叉熵損失:從概率建模到參數優化的數學橋梁
- 2.1 似然函數:基于伯努利分布的聯合概率建模
- 2.2 對數似然:從連乘到連加的數學變換
- 2.3 交叉熵損失:從最大化到最小化的目標轉換
- 2.4 等價性證明:最大化似然 ≡ 最小化交叉熵
- 三、sklearn 實現邏輯回歸:從 API 到實戰應用
- 3.1 sklearn邏輯回歸API詳解
- 3.2 模型訓練與預測流程
- 3.3程序代碼
一、邏輯回歸:從線性回歸到二分類的跨越
1.1 邏輯回歸簡介
邏輯回歸(Logistic Regression)是機器學習中解決二分類問題的經典算法,盡管名稱中包含"回歸",但它本質上是一種分類方法。其核心思想是通過將線性回歸的輸出映射到(0,1)概率區間,從而實現分類預測。具體來說:
- 利用線性模型 f ( x ) = w T x + b f(x) = w^T x + b f(x)=wTx+b 計算特征的線性組合
- 通過Sigmoid函數將線性輸出轉換為概率值 P ( y = 1 ∣ x ) P(y=1|x) P(y=1∣x)
- 設置概率閾值(如0.5)將概率轉換為類別標簽
邏輯回歸廣泛應用于醫學診斷、金融風控、廣告點擊率預估等場景,其優勢在于模型簡單、可解釋性強,且在小規模數據上表現優異。
-
f ( x ) = w T x + b f(x) = w^T x + b f(x)=wTx+b 的數學推導
線性模型 f ( x ) = w T x + b f(x) = w^T x + b f(x)=wTx+b 的推導源于概率論中的伯努利分布和對數幾率變換:
-
什么是伯努利分布?
伯努利分布是描述二元隨機變量(只有兩種可能結果)的最基本概率分布。在二分類問題中,樣本標簽 y ∈ { 0 , 1 } y \in \{0,1\} y∈{0,1} 正好滿足:- 結果互斥:每個樣本只能屬于一個類別
- 概率完備: P ( y = 1 ) + P ( y = 0 ) = 1 P(y=1) + P(y=0) = 1 P(y=1)+P(y=0)=1
- 形式簡潔:單參數 p p p 完全定義整個分布
與經典概率分布(如正態分布)相比,伯努利分布:
- 直接建模離散的二分類結果
- 完美匹配分類問題的概率特性
- 數學形式簡單且可解釋性強
- 伯努利分布 vs 經典概率求法
-
經典概率求法(頻率學派)
在傳統概率計算中,我們通過統計事件發生的頻率來估計概率:
p = 正類樣本數 總樣本數 p = \frac{\text{正類樣本數}}{\text{總樣本數}} p=總樣本數正類樣本數?示例:
拋硬幣10次,出現正面7次,則正面概率:
p = 7 10 = 0.7 p = \frac{7}{10} = 0.7 p=107?=0.7 -
伯努利分布的本質
伯努利分布 P ( y ) = p y ( 1 ? p ) 1 ? y P(y) = p^y(1-p)^{1-y} P(y)=py(1?p)1?y 是經典概率的數學抽象:
- 當 y = 1 y=1 y=1 (正類): P ( 1 ) = p 1 ( 1 ? p ) 0 = p P(1) = p^1(1-p)^0 = p P(1)=p1(1?p)0=p
- 當 y = 0 y=0 y=0 (負類): P ( 0 ) = p 0 ( 1 ? p ) 1 = 1 ? p P(0) = p^0(1-p)^1 = 1-p P(0)=p0(1?p)1=1?p
-
關鍵聯系:
經典概率 k n \frac{k}{n} nk? 正是伯努利分布在 n n n 次獨立試驗中正類出現次數 k k k 的期望值:
E [ y ] = p = k n E[y] = p = \frac{k}{n} E[y]=p=nk? -
對比分析
特性 | 經典概率求法 | 伯努利分布 |
---|---|---|
表達形式 | 統計比值 k n \frac{k}{n} nk? | 參數化概率模型 p y ( 1 ? p ) 1 ? y p^y(1-p)^{1-y} py(1?p)1?y |
計算基礎 | 依賴具體觀測數據 | 基于概率參數 p p p |
預測能力 | 只能描述已觀測數據 | 可預測未知樣本概率 |
數學處理 | 難以建立特征-概率的映射 | 可連接特征與概率(如 p = σ ( w T x + b ) p=\sigma(w^Tx+b) p=σ(wTx+b)) |
- 實際應用示例
假設醫學檢測:
- 100人中20人陽性 → 經典概率: p = 20 / 100 = 0.2 p=20/100=0.2 p=20/100=0.2
- 伯努利分布建模:
- P ( y = 1 ) = 0.2 P(y=1)=0.2 P(y=1)=0.2
- P ( y = 0 ) = 0.8 P(y=0)=0.8 P(y=0)=0.8
- 對新患者 x x x,可通過 p = σ ( w T x + b ) p=\sigma(w^Tx+b) p=σ(wTx+b) 預測患病概率
核心優勢:伯努利分布將離散的頻率統計轉化為連續的概率模型,為建立特征與概率的數學關系奠定了基礎,這是經典概率比無法實現的。
-
繼續 f ( x ) = w T x + b f(x) = w^T x + b f(x)=wTx+b 的數學推導
對于二分類問題, y y y 服從伯努利分布:
P ( y ∣ x ) = p y ( 1 ? p ) 1 ? y P(y|x) = p^y(1-p)^{1-y} P(y∣x)=py(1?p)1?y
其中 p = P ( y = 1 ∣ x ) p = P(y=1|x) p=P(y=1∣x) 是樣本屬于正類的概率。 -
對數幾率變換
為建立 p p p 與特征 x x x 的關系,定義對數幾率:
logit ( p ) = ln ? ( p 1 ? p ) \text{logit}(p) = \ln \left( \frac{p}{1-p} \right) logit(p)=ln(1?pp?)- 該變換將概率 p ∈ [ 0 , 1 ] p \in [0,1] p∈[0,1] 映射到實數域 ( ? ∞ , + ∞ ) (-\infty, +\infty) (?∞,+∞)
-
關鍵假設
邏輯回歸的核心假設是:對數幾率與特征呈線性關系
ln ? ( p 1 ? p ) = w T x + b \ln \left( \frac{p}{1-p} \right) = w^T x + b ln(1?pp?)=wTx+b -
代數求解
通過代數變換求解 p p p:
p 1 ? p = e w T x + b p = ( 1 ? p ) e w T x + b p ( 1 + e w T x + b ) = e w T x + b p = e w T x + b 1 + e w T x + b = 1 1 + e ? ( w T x + b ) \begin{align*} \frac{p}{1-p} &= e^{w^T x + b} \\ p &= (1-p)e^{w^T x + b} \\ p(1 + e^{w^T x + b}) &= e^{w^T x + b} \\ p &= \frac{e^{w^T x + b}}{1 + e^{w^T x + b}} \\ &= \frac{1}{1 + e^{-(w^T x + b)}} \end{align*} 1?pp?pp(1+ewTx+b)p?=ewTx+b=(1?p)ewTx+b=ewTx+b=1+ewTx+bewTx+b?=1+e?(wTx+b)1?? -
最終形式
得到線性模型與Sigmoid函數的組合:
P ( y = 1 ∣ x ) = σ ( w T x + b ) = 1 1 + e ? ( w T x + b ) P(y=1|x) = \sigma(w^T x + b) = \frac{1}{1 + e^{-(w^T x + b)}} P(y=1∣x)=σ(wTx+b)=1+e?(wTx+b)1?
其中:- w w w:權重向量,表示各特征的重要性
- b b b:偏置項,表示決策邊界的偏移
- w T x = ∑ i = 1 n w i x i w^T x = \sum_{i=1}^n w_i x_i wTx=∑i=1n?wi?xi?:特征線性組合
-
關鍵數學關系
概念 | 數學表達式 | 取值范圍 | 解釋 |
---|---|---|---|
原始概率 | $p = P(y=1 | x)$ | [ 0 , 1 ] [0, 1] [0,1] |
幾率 | p 1 ? p \frac{p}{1-p} 1?pp? | [ 0 , + ∞ ) [0, +\infty) [0,+∞) | 正負類概率比 |
對數幾率 | ln ? ( p 1 ? p ) \ln\left(\frac{p}{1-p}\right) ln(1?pp?) | ( ? ∞ , + ∞ ) (-\infty, +\infty) (?∞,+∞) | 幾率的自然對數 |
線性模型 | w T x + b w^T x + b wTx+b | ( ? ∞ , + ∞ ) (-\infty, +\infty) (?∞,+∞) | 特征線性組合 |
1.2 Sigmoid函數:概率映射的數學本質
-
函數定義與幾何意義
Sigmoid函數是邏輯回歸的核心,其數學表達式為:
σ ( z ) = 1 1 + e ? z \sigma(z) = \frac{1}{1 + e^{-z}} σ(z)=1+e?z1?- 符號解析:
- z z z:線性組合結果(為 z = w T x + b z = w^T x + b z=wTx+b);
- e e e:自然對數底數(≈2.71828),負責將線性輸出映射到指數空間。
圖 1 圖1 圖1
從 Sigmoid函數曲線(圖1) 可見:
- 當 z → + ∞ z \to +\infty z→+∞ 時, e ? z → 0 e^{-z} \to 0 e?z→0, σ ( z ) → 1 \sigma(z) \to 1 σ(z)→1(正類概率趨近1);
- 當 z → ? ∞ z \to -\infty z→?∞ 時, e ? z → + ∞ e^{-z} \to +\infty e?z→+∞, σ ( z ) → 0 \sigma(z) \to 0 σ(z)→0(正類概率趨近0);
- 當 z = 0 z=0 z=0 時, σ ( z ) = 0.5 \sigma(z)=0.5 σ(z)=0.5,是二分類的天然決策閾值( σ ( z ) ≥ 0.5 \sigma(z) \geq 0.5 σ(z)≥0.5 預測為正類,反之為負類)。
- 符號解析:
1.3 參數 w w w 和 b b b 對Sigmoid的調控
圖 2 圖2 圖2
-
權重 w w w 的影響
w w w 控制Sigmoid曲線的陡峭程度(對 z z z 變化的敏感程度):
- ∣ w ∣ |w| ∣w∣ 越大,曲線越陡峭(如 w = 5 w=5 w=5 時, z z z 微小變化即可讓 σ ( z ) \sigma(z) σ(z) 從0躍升至1);
- ∣ w ∣ |w| ∣w∣ 越小,曲線越平緩(如 w = 0.5 w=0.5 w=0.5 時, z z z 需大幅變化才會改變 σ ( z ) \sigma(z) σ(z))。
-
偏置 b b b 的影響
b b b 控制Sigmoid曲線的左右平移(決策閾值的位置):
- b > 0 b>0 b>0 時,曲線左移(更小的 z z z 就能讓 σ ( z ) = 0.5 \sigma(z)=0.5 σ(z)=0.5);
- b < 0 b<0 b<0 時,曲線右移(更大的 z z z 才能讓 σ ( z ) = 0.5 \sigma(z)=0.5 σ(z)=0.5)。
-
權重符號的影響
w w w 的正負決定Sigmoid曲線的傾斜方向:
- w > 0 w>0 w>0 時, σ ( z ) \sigma(z) σ(z) 隨 z z z 增大而遞增(正相關);
- w < 0 w<0 w<0 時, σ ( z ) \sigma(z) σ(z) 隨 z z z 增大而遞減(負相關),需通過 b b b 調整決策邏輯。
1.4 從線性回歸到分類
-
線性組合: z = w T x + b z = w^T x + b z=wTx+b
邏輯回歸首先計算 線性組合 z z z,繼承線性回歸的形式:
z = w 1 x 1 + w 2 x 2 + ? + w n x n + b z = w_1 x_1 + w_2 x_2 + \dots + w_n x_n + b z=w1?x1?+w2?x2?+?+wn?xn?+b- 符號解析:
- w = [ w 1 , w 2 , … , w n ] T w = [w_1, w_2, \dots, w_n]^T w=[w1?,w2?,…,wn?]T:權重向量,每個 w i w_i wi? 表示特征 x i x_i xi? 的“重要性”;
- x = [ x 1 , x 2 , … , x n ] T x = [x_1, x_2, \dots, x_n]^T x=[x1?,x2?,…,xn?]T:樣本的特征向量( n n n 為特征維度);
- b b b:偏置項,代表“基準概率”(所有 x i = 0 x_i=0 xi?=0 時的 z z z 值)。
- 符號解析:
圖 3 圖3 圖3
-
概率映射: P ( y = 1 ∣ x ) = σ ( z ) P(y=1|x) = \sigma(z) P(y=1∣x)=σ(z)(結合圖3)
通過Sigmoid函數,線性組合 z z z 被映射為 正類概率:
P ( y = 1 ∣ x ; w , b ) = σ ( w T x + b ) P(y=1|x; w, b) = \sigma(w^T x + b) P(y=1∣x;w,b)=σ(wTx+b)
負類概率為:
P ( y = 0 ∣ x ; w , b ) = 1 ? σ ( w T x + b ) P(y=0|x; w, b) = 1 - \sigma(w^T x + b) P(y=0∣x;w,b)=1?σ(wTx+b)合并表達式(全概率公式):
P ( y ∣ x ; w , b ) = [ σ ( w T x + b ) ] y ? [ 1 ? σ ( w T x + b ) ] 1 ? y P(y|x; w, b) = \left[\sigma(w^T x + b)\right]^y \cdot \left[1 - \sigma(w^T x + b)\right]^{1-y} P(y∣x;w,b)=[σ(wTx+b)]y?[1?σ(wTx+b)]1?y- 當 y = 1 y=1 y=1 時,公式退化為 σ ( w T x + b ) \sigma(w^T x + b) σ(wTx+b)(僅保留正類概率);
- 當 y = 0 y=0 y=0 時,公式退化為 1 ? σ ( w T x + b ) 1 - \sigma(w^T x + b) 1?σ(wTx+b)(僅保留負類概率)。
圖 3 圖3 圖3
圖 4 圖4 圖4
1.5 決策邊界:從概率到類別(結合圖3、圖4)
當 σ ( z ) ≥ 0.5 \sigma(z) \geq 0.5 σ(z)≥0.5 時,預測 y = 1 y=1 y=1;否則預測 y = 0 y=0 y=0。此時決策邊界滿足:
w T x + b = 0 w^T x + b = 0 wTx+b=0
- 一維特征(圖3):決策邊界是 x x x 的具體值(如 x = 0.67 x=0.67 x=0.67);
- 二維特征(圖4):決策邊界是直線(如 w 1 x 1 + w 2 x 2 + b = 0 w_1 x_1 + w_2 x_2 + b = 0 w1?x1?+w2?x2?+b=0);
- 高維特征:決策邊界擴展為超平面,分割特征空間為兩個區域。
繪圖代碼:
import numpy as np # 導入NumPy庫,用于數值計算
import matplotlib.pyplot as plt # 導入Matplotlib繪圖庫
from matplotlib.colors import ListedColormap # 導入顏色映射工具
from mpl_toolkits.mplot3d import Axes3D # 導入3D繪圖工具# 設置中文字體,確保圖表能正確顯示中文
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False # 定義Sigmoid函數,數學公式為σ(z) = 1/(1+e^(-z))
def sigmoid(z):return 1 / (1 + np.exp(-z))# 1. 繪制Sigmoid函數的基本曲線
def plot_sigmoid():z = np.linspace(-10, 10, 1000) # 生成-10到10之間的1000個等距點作為輸入sigma_z = sigmoid(z) # 計算Sigmoid函數值plt.figure(figsize=(10, 6)) # 創建10x6英寸的畫布plt.plot(z, sigma_z, linewidth=2.5) # 繪制Sigmoid曲線,線寬2.5plt.axhline(y=0.5, color='r', linestyle='--', alpha=0.5) # 添加y=0.5的紅色虛線plt.axvline(x=0, color='gray', linestyle='--', alpha=0.5) # 添加x=0的灰色虛線plt.title('Sigmoid函數曲線', fontsize=15) # 設置標題plt.xlabel('z 值 (線性組合結果)', fontsize=12) # 設置x軸標簽plt.ylabel('σ(z) 值 (概率值)', fontsize=12) # 設置y軸標簽plt.grid(True, alpha=0.3) # 添加網格線,透明度0.3# 填充z≥0區域(藍色)和z<0區域(紅色),突出概率大于/小于0.5的部分plt.fill_between(z, sigma_z, 0.5, where=(z >= 0), color='lightblue', alpha=0.3)plt.fill_between(z, sigma_z, 0.5, where=(z < 0), color='lightcoral', alpha=0.3)# 添加文本注釋,說明概率大于/小于0.5的區域plt.text(3, 0.85, 'σ(z) > 0.5', fontsize=12)plt.text(-3, 0.15, 'σ(z) < 0.5', fontsize=12)plt.tight_layout() # 自動調整布局plt.savefig('sigmoid_function.png', dpi=300) # 保存圖片plt.show() # 顯示圖表# 2. 繪制不同參數對Sigmoid函數的影響對比
def plot_sigmoid_with_different_params():z = np.linspace(-10, 10, 1000) # 生成輸入數據plt.figure(figsize=(12, 8)) # 創建12x8英寸的畫布# 第一個子圖:不同權重w對Sigmoid的影響plt.subplot(2, 2, 1)for w in [0.5, 1, 2, 5]: # 遍歷不同的權重值plt.plot(z, sigmoid(w * z), label=f'w={w}') # 繪制不同w的曲線plt.title('不同權重 w 的影響', fontsize=13) # 設置標題plt.xlabel('z', fontsize=10) # 設置坐標軸標簽plt.ylabel('σ(z)', fontsize=10)plt.legend() # 顯示圖例plt.grid(True, alpha=0.3) # 添加網格# 第二個子圖:不同偏置b對Sigmoid的影響plt.subplot(2, 2, 2)for b in [-2, -1, 0, 1, 2]: # 遍歷不同的偏置值plt.plot(z, sigmoid(z + b), label=f'b={b}') # 繪制不同b的曲線plt.title('不同偏置 b 的影響', fontsize=13)plt.xlabel('z', fontsize=10)plt.ylabel('σ(z)', fontsize=10)plt.legend()plt.grid(True, alpha=0.3)# 第三個子圖:不同參數組合(w,b)的影響plt.subplot(2, 2, 3)params = [(1, 0), (2, 0), (1, -2), (2, 2)] # 參數組合列表for w, b in params: # 遍歷參數組合plt.plot(z, sigmoid(w * z + b), label=f'w={w}, b={b}') # 繪制曲線plt.title('不同參數組合的影響', fontsize=13)plt.xlabel('z', fontsize=10)plt.ylabel('σ(z)', fontsize=10)plt.legend()plt.grid(True, alpha=0.3)# 第四個子圖:權重符號對Sigmoid的影響plt.subplot(2, 2, 4)for w in [1, -1, 2, -2]: # 遍歷正負權重plt.plot(z, sigmoid(w * z), label=f'w={w}') # 繪制曲線plt.title('權重符號的影響', fontsize=13)plt.xlabel('z', fontsize=10)plt.ylabel('σ(z)', fontsize=10)plt.legend()plt.grid(True, alpha=0.3)plt.tight_layout() # 調整布局plt.savefig('sigmoid_params_comparison.png', dpi=300) # 保存圖片plt.show() # 顯示圖表# 3. 繪制邏輯回歸從線性組合到概率映射的完整過程
def plot_logistic_probability_mapping():np.random.seed(42) # 設置隨機種子,確保結果可復現x = np.linspace(-5, 5, 100) # 生成輸入特征xw = 1.5 # 權重b = -1 # 偏置z = w * x + b # 線性組合z = wx + bprob = sigmoid(z) # 計算屬于正類的概率# 根據概率生成分類標簽(概率>0.5為正類1,否則為負類0)y = (prob > 0.5).astype(int)# 添加噪聲模擬真實數據noise = np.random.normal(0, 0.2, 100) # 生成均值0、標準差0.2的噪聲x_noise = x + noise # 帶噪聲的特征prob_noise = sigmoid(w * x_noise + b) # 帶噪聲的概率y_noise = (prob_noise > 0.5).astype(int) # 帶噪聲的標簽plt.figure(figsize=(12, 10)) # 創建畫布# 第一子圖:線性回歸結果z = wx + bplt.subplot(2, 2, 1)# 繪制帶噪聲的數據點,顏色根據標簽區分plt.scatter(x_noise, z, c=y_noise, cmap=ListedColormap(['#FF9999', '#99CCFF']),edgecolors='k', alpha=0.7)plt.plot(x, z, 'r-', linewidth=2) # 繪制線性回歸直線plt.axhline(y=0, color='gray', linestyle='--', alpha=0.5) # 添加y=0的虛線plt.title('線性回歸結果 (z = wx + b)', fontsize=13)plt.xlabel('輸入特征 x', fontsize=10)plt.ylabel('線性組合結果 z', fontsize=10)plt.grid(True, alpha=0.3)# 第二子圖:Sigmoid函數映射過程plt.subplot(2, 2, 2)# 繪制z到概率的映射關系,點顏色根據標簽區分plt.scatter(z, prob_noise, c=y_noise, cmap=ListedColormap(['#FF9999', '#99CCFF']),edgecolors='k', alpha=0.7)plt.plot(z, prob, 'g-', linewidth=2) # 繪制Sigmoid曲線plt.axhline(y=0.5, color='r', linestyle='--', alpha=0.5) # 添加y=0.5虛線plt.axvline(x=0, color='gray', linestyle='--', alpha=0.5) # 添加x=0虛線plt.title('Sigmoid函數映射', fontsize=13)plt.xlabel('線性組合結果 z', fontsize=10)plt.ylabel('概率值 P(y=1|x)', fontsize=10)plt.grid(True, alpha=0.3)# 第三子圖:邏輯回歸的最終分類結果plt.subplot(2, 2, 3)# 繪制特征x與預測概率的關系,點顏色根據標簽區分plt.scatter(x_noise, y_noise, c=y_noise, cmap=ListedColormap(['#FF9999', '#99CCFF']),edgecolors='k', alpha=0.7, s=50)plt.plot(x, prob, 'g-', linewidth=2) # 繪制概率曲線plt.axhline(y=0.5, color='r', linestyle='--', alpha=0.5) # 添加決策閾值線plt.title('邏輯回歸分類結果', fontsize=13)plt.xlabel('輸入特征 x', fontsize=10)plt.ylabel('預測概率 P(y=1|x)', fontsize=10)plt.grid(True, alpha=0.3)# 第四子圖:邏輯回歸的決策邊界plt.subplot(2, 2, 4)# 繪制特征x與標簽y的關系,點顏色根據標簽區分plt.scatter(x_noise, y_noise, c=y_noise, cmap=ListedColormap(['#FF9999', '#99CCFF']),edgecolors='k', alpha=0.7, s=50)plt.axhline(y=0.5, color='r', linestyle='--', alpha=0.5) # 添加概率閾值線decision_boundary = -b / w # 計算決策邊界x值plt.axvline(x=decision_boundary, color='blue', linestyle='-', alpha=0.7) # 繪制決策邊界# 填充決策邊界兩側的區域,區分分類結果plt.fill_between(x, 0, 1, where=(x > decision_boundary), color='#99CCFF', alpha=0.2)plt.fill_between(x, 0, 1, where=(x <= decision_boundary), color='#FF9999', alpha=0.2)plt.title(f'決策邊界 (x = {decision_boundary:.2f})', fontsize=13)plt.xlabel('輸入特征 x', fontsize=10)plt.ylabel('類別標簽 y', fontsize=10)plt.grid(True, alpha=0.3)plt.tight_layout() # 調整布局plt.savefig('logistic_regression_mapping.png', dpi=300) # 保存圖片plt.show() # 顯示圖表# 4. 繪制二維特征空間中的邏輯回歸決策面
def plot_3d_decision_boundary():np.random.seed(42) # 設置隨機種子x1 = np.linspace(-5, 5, 50) # 生成特征x1x2 = np.linspace(-5, 5, 50) # 生成特征x2x1, x2 = np.meshgrid(x1, x2) # 生成二維網格點w1, w2, b = 1, 2, -3 # 設置權重和偏置# 計算線性組合z = w1x1 + w2x2 + b和對應的概率z = w1 * x1 + w2 * x2 + bprob = sigmoid(z)fig = plt.figure(figsize=(12, 10)) # 創建畫布# 第一子圖:3D決策面ax1 = fig.add_subplot(221, projection='3d') # 創建3D子圖# 繪制3D曲面,顏色映射為viridis,透明度0.8surf = ax1.plot_surface(x1, x2, prob, cmap='viridis', alpha=0.8)# 在3D曲面上繪制z=0.5的等高線(決策邊界)ax1.contour(x1, x2, prob, levels=[0.5], colors='r', linestyles='dashed', linewidths=2)ax1.set_title('邏輯回歸決策面', fontsize=13) # 設置標題ax1.set_xlabel('特征 x1', fontsize=10) # 設置坐標軸標簽ax1.set_ylabel('特征 x2', fontsize=10)ax1.set_zlabel('P(y=1|x1,x2)', fontsize=10)ax1.view_init(elev=30, azim=45) # 設置3D視圖角度fig.colorbar(surf, ax=ax1, shrink=0.5, aspect=5) # 添加顏色條# 第二子圖:決策邊界等高線圖ax2 = fig.add_subplot(222) # 創建子圖# 繪制概率的填充等高線圖,20個層級,顏色映射viridiscontour = ax2.contourf(x1, x2, prob, levels=20, cmap='viridis', alpha=0.8)# 繪制概率=0.5的等高線(決策邊界)ax2.contour(x1, x2, prob, levels=[0.5], colors='r', linestyles='dashed', linewidths=2)ax2.set_title('決策邊界等高線圖', fontsize=13)ax2.set_xlabel('特征 x1', fontsize=10)ax2.set_ylabel('特征 x2', fontsize=10)fig.colorbar(contour, ax=ax2, shrink=0.5, aspect=5) # 添加顏色條# 生成隨機樣本點n_samples = 100 # 樣本數量x1_samples = np.random.uniform(-5, 5, n_samples) # 隨機生成x1x2_samples = np.random.uniform(-5, 5, n_samples) # 隨機生成x2z_samples = w1 * x1_samples + w2 * x2_samples + b # 計算線性組合prob_samples = sigmoid(z_samples) # 計算概率y_samples = (prob_samples > 0.5).astype(int) # 生成標簽# 第三子圖:帶樣本點的決策邊界ax3 = fig.add_subplot(223) # 創建子圖# 繪制概率的填充等高線圖contour = ax3.contourf(x1, x2, prob, levels=20, cmap='viridis', alpha=0.6)# 繪制決策邊界ax3.contour(x1, x2, prob, levels=[0.5], colors='r', linestyles='dashed', linewidths=2)# 繪制樣本點,顏色根據標簽區分scatter = ax3.scatter(x1_samples, x2_samples, c=y_samples,cmap=ListedColormap(['#FF9999', '#99CCFF']),edgecolors='k', alpha=0.8, s=50)ax3.set_title('帶樣本點的決策邊界', fontsize=13)ax3.set_xlabel('特征 x1', fontsize=10)ax3.set_ylabel('特征 x2', fontsize=10)# 添加類別圖例legend1 = ax3.legend(*scatter.legend_elements(), title="類別")ax3.add_artist(legend1)fig.colorbar(contour, ax=ax3, shrink=0.5, aspect=5) # 添加顏色條# 第四子圖:概率分布熱圖ax4 = fig.add_subplot(224) # 創建子圖# 繪制概率熱圖,設置范圍和顏色映射im = ax4.imshow(prob, extent=[-5, 5, -5, 5], origin='lower',cmap='viridis', aspect='auto')# 繪制決策邊界ax4.contour(x1, x2, prob, levels=[0.5], colors='r', linestyles='dashed', linewidths=2)ax4.set_title('概率分布熱圖', fontsize=13)ax4.set_xlabel('特征 x1', fontsize=10)ax4.set_ylabel('特征 x2', fontsize=10)fig.colorbar(im, ax=ax4, shrink=0.5, aspect=5) # 添加顏色條plt.tight_layout() # 調整布局plt.savefig('3d_decision_boundary.png', dpi=300) # 保存圖片plt.show() # 顯示圖表# 5. 繪制邏輯回歸的對數損失函數
def plot_logistic_loss():# 定義對數損失函數def log_loss(y_true, y_pred):epsilon = 1e-15 # 防止對數計算中出現0或1,導致數值溢出y_pred = np.clip(y_pred, epsilon, 1 - epsilon) # 限制預測概率范圍# 對數損失公式:- [y_true*log(y_pred) + (1-y_true)*log(1-y_pred)]return -(y_true * np.log(y_pred) + (1 - y_true) * np.log(1 - y_pred))y_pred = np.linspace(0.01, 0.99, 100) # 生成0.01到0.99的100個預測概率值plt.figure(figsize=(10, 6)) # 創建畫布# 繪制真實標簽為1時的損失曲線plt.plot(y_pred, log_loss(1, y_pred), label='y=1 (正類)')# 繪制真實標簽為0時的損失曲線plt.plot(y_pred, log_loss(0, y_pred), label='y=0 (負類)')plt.title('邏輯回歸的對數損失函數', fontsize=15) # 設置標題plt.xlabel('預測概率 P(y=1|x)', fontsize=12) # 設置坐標軸標簽plt.ylabel('損失值', fontsize=12)plt.grid(True, alpha=0.3) # 添加網格plt.legend(fontsize=12) # 顯示圖例# 添加注釋,說明預測正確和錯誤時的損失情況plt.annotate('預測正確時損失小', xy=(0.95, log_loss(1, 0.95)), xytext=(0.7, 0.5),arrowprops=dict(facecolor='black', shrink=0.05, width=1.5, headwidth=8))plt.annotate('預測錯誤時損失大', xy=(0.05, log_loss(1, 0.05)), xytext=(0.3, 3),arrowprops=dict(facecolor='black', shrink=0.05, width=1.5, headwidth=8))plt.tight_layout() # 調整布局plt.savefig('logistic_loss_function.png', dpi=300) # 保存圖片plt.show() # 顯示圖表# 主程序:依次調用所有繪圖函數
if __name__ == "__main__":plot_sigmoid() # 繪制Sigmoid函數基本曲線plot_sigmoid_with_different_params() # 繪制不同參數的Sigmoid對比plot_logistic_probability_mapping() # 繪制邏輯回歸概率映射plot_3d_decision_boundary() # 繪制二維特征的決策面plot_logistic_loss() # 繪制對數損失函數
二、似然函數與交叉熵損失:從概率建模到參數優化的數學橋梁
2.1 似然函數:基于伯努利分布的聯合概率建模
過渡銜接:在通過伯努利分布與對數幾率變換建立特征-概率映射后,如何求解最優參數 ( w , b ) (w, b) (w,b)?這需要從樣本的聯合概率分布出發,構建優化目標函數。
在邏輯回歸中,樣本標簽 y i y_i yi? 服從伯努利分布,單個樣本的概率為:
P ( y i ∣ x i ; w , b ) = [ σ ( w T x i + b ) ] y i [ 1 ? σ ( w T x i + b ) ] 1 ? y i P(y_i|x_i; w, b) = \left[\sigma(w^T x_i + b)\right]^{y_i} \left[1 - \sigma(w^T x_i + b)\right]^{1-y_i} P(yi?∣xi?;w,b)=[σ(wTxi?+b)]yi?[1?σ(wTxi?+b)]1?yi?
若 m m m 個樣本獨立同分布,則聯合似然函數為所有樣本概率的乘積:
L ( w , b ) = ∏ i = 1 m P ( y i ∣ x i ; w , b ) = ∏ i = 1 m [ σ ( z i ) ] y i [ 1 ? σ ( z i ) ] 1 ? y i L(w, b) = \prod_{i=1}^{m} P(y_i|x_i; w, b) = \prod_{i=1}^{m} \left[\sigma(z_i)\right]^{y_i} \left[1 - \sigma(z_i)\right]^{1-y_i} L(w,b)=i=1∏m?P(yi?∣xi?;w,b)=i=1∏m?[σ(zi?)]yi?[1?σ(zi?)]1?yi?
- 符號說明:
- z i = w T x i + b z_i = w^T x_i + b zi?=wTxi?+b;
- y i ∈ { 0 , 1 } y_i \in \{0, 1\} yi?∈{0,1} 為第 i i i 個樣本的真實標簽;
- ∏ \prod ∏ 為連乘符號,體現獨立事件聯合概率的計算邏輯。
核心目標:尋找參數 ( w , b ) (w, b) (w,b) 使得 L ( w , b ) L(w, b) L(w,b) 最大,即讓觀測數據出現的概率最大化(與1.4節伯努利分布的概率建模邏輯連貫)。
2.2 對數似然:從連乘到連加的數學變換
直接優化連乘式計算復雜,利用對數函數性質 ln ? ( ∏ f i ) = ∑ ln ? ( f i ) \ln(\prod f_i) = \sum \ln(f_i) ln(∏fi?)=∑ln(fi?) 轉換為對數似然函數:
ln ? L ( w , b ) = ∑ i = 1 m [ y i ln ? σ ( z i ) + ( 1 ? y i ) ln ? ( 1 ? σ ( z i ) ) ] \ln L(w, b) = \sum_{i=1}^{m} \left[ y_i \ln \sigma(z_i) + (1-y_i) \ln (1 - \sigma(z_i)) \right] lnL(w,b)=i=1∑m?[yi?lnσ(zi?)+(1?yi?)ln(1?σ(zi?))]
- 詳細推導步驟:
- 對似然函數取自然對數: ln ? L ( w , b ) = ln ? ( ∏ i = 1 m P ( y i ∣ x i ) ) \ln L(w, b) = \ln \left( \prod_{i=1}^{m} P(y_i|x_i) \right) lnL(w,b)=ln(∏i=1m?P(yi?∣xi?)),其中 P ( y i ∣ x i ) P(y_i|x_i) P(yi?∣xi?) 為單個樣本概率;
- 利用對數乘法性質展開: ln ? L ( w , b ) = ∑ i = 1 m ln ? P ( y i ∣ x i ) \ln L(w, b) = \sum_{i=1}^{m} \ln P(y_i|x_i) lnL(w,b)=∑i=1m?lnP(yi?∣xi?);
- 代入伯努利分布概率表達式:
ln ? P ( y i ∣ x i ) = ln ? { [ σ ( z i ) ] y i [ 1 ? σ ( z i ) ] 1 ? y i } = y i ln ? σ ( z i ) + ( 1 ? y i ) ln ? ( 1 ? σ ( z i ) ) \ln P(y_i|x_i) = \ln \left\{ \left[\sigma(z_i)\right]^{y_i} \left[1 - \sigma(z_i)\right]^{1-y_i} \right\} = y_i \ln \sigma(z_i) + (1-y_i) \ln (1 - \sigma(z_i)) lnP(yi?∣xi?)=ln{[σ(zi?)]yi?[1?σ(zi?)]1?yi?}=yi?lnσ(zi?)+(1?yi?)ln(1?σ(zi?))。
2.3 交叉熵損失:從最大化到最小化的目標轉換
為將“最大化對數似然”轉化為機器學習中常見的損失函數最小化問題,定義:
L o s s ( w , b ) = ? ln ? L ( w , b ) = ? ∑ i = 1 m [ y i ln ? σ ( z i ) + ( 1 ? y i ) ln ? ( 1 ? σ ( z i ) ) ] Loss(w, b) = -\ln L(w, b) = -\sum_{i=1}^{m} \left[ y_i \ln \sigma(z_i) + (1-y_i) \ln (1 - \sigma(z_i)) \right] Loss(w,b)=?lnL(w,b)=?i=1∑m?[yi?lnσ(zi?)+(1?yi?)ln(1?σ(zi?))]
-
信息論視角:
交叉熵 H ( y , y ^ ) = ? ∑ i = 1 m [ y i ln ? y ^ i + ( 1 ? y i ) ln ? ( 1 ? y ^ i ) ] H(y, \hat{y}) = -\sum_{i=1}^{m} \left[ y_i \ln \hat{y}_i + (1-y_i) \ln (1 - \hat{y}_i) \right] H(y,y^?)=?∑i=1m?[yi?lny^?i?+(1?yi?)ln(1?y^?i?)] 衡量真實分布 y y y 與預測分布 y ^ \hat{y} y^? 的差異,當 y ^ i = σ ( z i ) \hat{y}_i = \sigma(z_i) y^?i?=σ(zi?) 時, L o s s Loss Loss 即為交叉熵,直接量化1.4節中“概率映射準確性”的損失。
- 幾何意義:
- 當預測概率 σ ( z i ) \sigma(z_i) σ(zi?) 與真實標簽 y i y_i yi? 一致時(如 y i = 1 y_i=1 yi?=1 且 σ ( z i ) → 1 \sigma(z_i)\to1 σ(zi?)→1), L o s s → 0 Loss \to 0 Loss→0;
- 當預測相反時(如 y i = 1 y_i=1 yi?=1 且 σ ( z i ) → 0 \sigma(z_i)\to0 σ(zi?)→0)。
2.4 等價性證明:最大化似然 ≡ 最小化交叉熵
從數學變換看:
arg ? max ? w , b L ( w , b ) ? arg ? max ? w , b ln ? L ( w , b ) ? arg ? min ? w , b L o s s ( w , b ) \arg\max_{w,b} L(w,b) \quad \Leftrightarrow \quad \arg\max_{w,b} \ln L(w,b) \quad \Leftrightarrow \quad \arg\min_{w,b} Loss(w,b) argw,bmax?L(w,b)?argw,bmax?lnL(w,b)?argw,bmin?Loss(w,b)
三者本質是同一優化問題的不同表達,核心是 對數函數的單調性 和 極值方向的反轉(取負號)。
三、sklearn 實現邏輯回歸:從 API 到實戰應用
- sklearn的介紹和安裝:網頁鏈接
3.1 sklearn邏輯回歸API詳解
核心類與參數說明
from sklearn.linear_model import LogisticRegression
-
主要參數:
-
solver:優化算法選擇
liblinear
:適用于小數據集,支持L1/L2正則化sag/saga
:適用于大數據集,支持增量學習lbfgs
:擬牛頓法,收斂速度快,默認選項
-
penalty:正則化類型
l1
:L1正則化(Lasso),可產生稀疏解l2
:L2正則化(Ridge),默認選項,防止過擬合
-
C:正則化強度的倒數,值越小懲罰越嚴厲,默認值為1.0
-
class_weight:類別不平衡處理
balanced
:自動調整權重,適用于正負樣本比例懸殊場景- 字典形式:如
{0:1, 1:10}
表示正類權重為負類的10倍
-
3.2 模型訓練與預測流程
數據集:電信客戶流失數據集
官方數據集下載地址:下載鏈接
百度網盤下載地址:下載鏈接 提取碼: pujh
將數據集導入項目根目錄即可
-
工具準備:導入核心庫
pandas
處理表格數據(讀文件、列操作),numpy 支持數值計算;
matplotlib+seaborn
畫圖表(看數據分布、模型結果);
sklearn
模塊分工:train_test_split
分訓練 / 測試集,MinMaxScaler
歸一化特征,LogisticRegression
建模型,classification_report/roc_auc_score
評估效果。
中文字體設置:解決圖表中文亂碼、負號異常問題,讓結果更直觀。 -
數據加載與初檢
pd.read_csv('churn.csv')
讀數據,info()
看 列名、數據類型、缺失值(本案例無缺失,簡化處理)。 -
數據預處理:讓模型 “讀懂” 數據
獨熱編碼(get_dummies
):把 “性別”“合同類型” 等字符串轉成 0/1 數值(模型只能處理數值),drop_first=True
避免 多重共線性(如 “性別” 只留 “男” 列,女則為 0)。
列重命名:把編碼后的機器名(如gender_Male
)改成中文(如 性別),方便分析。
拆分特征與目標:data_x
存客戶屬性 / 服務 / 費用(特征),data_y 存 “是否流失”(目標)。 -
可視化:發現數據規律
用sns.countplot
畫 流失分布,發現 未流失客戶遠多于流失客戶(數據不平衡)→ 后續評估需重點看 流失類的召回率(別漏判流失客戶)。 -
數據分割:訓練 vs 測試
train_test_split
按 8:2 拆分,random_state=44
固定隨機種子(結果可復現)。 -
特征工程:歸一化
MinMaxScaler
把特征縮到 [0,1] 范圍(如 “月費” 10→100、“總費用” 100→1000,縮放后統一尺度)。
訓練集fit_transform
(先學規則再轉換),測試集transform
(復用規則,避免 “作弊”)→ 邏輯回歸對特征尺度敏感,歸一化加速模型收斂。 -
模型訓練:邏輯回歸
LogisticRegression(max_iter=1000)
:設最大迭代次數 1000(避免默認次數不足導致不收斂),用訓練集 fit 學規律(特征→流失的關系)。
歸一化的介紹:網頁鏈接 -
運行效果
精確率:0.8020
AUC得分:0.8331
分類報告:precision recall f1-score supportFalse 0.84 0.91 0.87 1027 True 0.68 0.52 0.59 382 accuracy 0.80 1409 macro avg 0.76 0.71 0.73 1409 weighted avg 0.79 0.80 0.79 1409
3.3程序代碼
分類任務的評估方法和根據評估指標進行優化:網頁鏈接
import pandas as pd # 導入Pandas庫用于數據處理
import numpy as np # 導入NumPy庫用于數值計算
import matplotlib.pyplot as plt # 導入Matplotlib用于數據可視化
import seaborn as sns # 導入Seaborn用于高級數據可視化
from sklearn.preprocessing import MinMaxScaler # 導入特征縮放工具
from sklearn.linear_model import LogisticRegression # 導入邏輯回歸模型
from sklearn.metrics import classification_report, roc_auc_score # 導入評估指標
from sklearn.model_selection import train_test_split # 導入數據分割工具# 設置中文字體支持
plt.rcParams['font.sans-serif'] = ['SimHei'] # 設置中文字體,確保中文能正常顯示
plt.rcParams['axes.unicode_minus'] = False # 確保負號能正常顯示# 1.加載數據
base_data = pd.read_csv('churn.csv') # 從CSV文件讀取數據
print("數據基本信息:")
base_data.info() # 查看數據的基本信息,包括列名、數據類型和缺失值情況# 2.數據預處理
# 2.1 將字符串轉變成數值(獨熱編碼),并重命名列
data = pd.get_dummies(base_data, drop_first=True) # 將分類特征轉換為數值特征,使用drop_first避免多重共線性
data.rename(columns={'gender_Male': '性別', 'Partner_att': '配偶狀態', 'Dependents_att': '受撫養人狀態','landline': '固定電話','internet_att': '互聯網服務', 'internet_other': '其他互聯網服務', 'StreamingTV': '電視流媒體服務','StreamingMovies': '電影流媒體服務','Contract_Month': '月付合同', 'Contract_1YR': '一年期合同', 'PaymentBank': '銀行支付','PaymentCreditcard': '信用卡支付','PaymentElectronic': '電子支付', 'MonthlyCharges': '月費', 'TotalCharges': '總費用'},inplace=True # 原地修改列名
)# 2.2 數據分割(特征集和目標集)
data['客戶流失'] = data['Churn_Yes'] # 創建目標變量列
data.drop(['Churn_Yes'], axis=1, inplace=True) # 刪除原始目標變量列
data_x = data.iloc[:, :-1] # 提取特征集(所有列除了最后一列)
data_y = data.iloc[:, -1] # 提取目標集(最后一列)# 2.3 數據展示 - 添加可視化:客戶流失分布情況
plt.figure(figsize=(10, 6)) # 設置圖表大小
sns.countplot(x='客戶流失', data=data) # 繪制客戶流失分布柱狀圖
plt.title('客戶流失分布情況') # 設置圖表標題
plt.savefig('churn_distribution.png') # 保存圖表為圖片
plt.show() # 顯示圖表# 3.數據分割:將數據分為訓練集和測試集
x_train, x_test, y_train, y_test = train_test_split(data_x, data_y, test_size=0.2, random_state=44 # 測試集占比20%,設置隨機種子確保結果可復現
)# 4.特征工程:使用Min-Max縮放對特征進行歸一化
ss = MinMaxScaler() # 初始化MinMaxScaler
nx_train = ss.fit_transform(x_train) # 對訓練集進行縮放并學習縮放參數
nx_test = ss.transform(x_test) # 使用訓練集學習的參數對測試集進行縮放# 5.模型創建與訓練
lr = LogisticRegression(max_iter=1000) # 初始化邏輯回歸模型,設置最大迭代次數為1000
lr.fit(nx_train, y_train) # 使用訓練數據訓練模型# 6.模型預測
pred_y = lr.predict(nx_test) # 預測測試集的分類標簽
pred_proba = lr.predict_proba(nx_test)[:, 1] # 獲取測試集樣本屬于正類的概率# 7.模型評估
print(f"\n精確率:{lr.score(nx_test, y_test):.4f}") # 計算并打印模型準確率
print(f"AUC得分:{roc_auc_score(y_test, pred_proba):.4f}") # 計算并打印AUC值
print("\n分類報告:")
print(classification_report(y_test, pred_y)) # 打印分類報告,包含精確率、召回率、F1分數等指標# 8.特征重要性分析
plt.figure(figsize=(12, 8)) # 設置圖表大小
# 創建特征重要性DataFrame,使用系數的絕對值作為重要性指標
importance = pd.DataFrame({'特征': data_x.columns,'重要性': np.abs(lr.coef_[0]) # 獲取邏輯回歸模型的系數絕對值
}).sort_values('重要性', ascending=False) # 按重要性降序排序# 只展示前10個重要特征
sns.barplot(x='重要性', y='特征', data=importance.head(10)) # 繪制特征重要性條形圖
plt.title('Top 10特征重要性') # 設置圖表標題
plt.tight_layout() # 自動調整布局
plt.savefig('feature_importance.png') # 保存圖表
plt.show() # 顯示圖表