邏輯回歸算法詳解與Python實現(xiàn)完整代碼示例
前言
邏輯回歸是機器學習中入門級且實用性極強的算法,雖名稱含 “回歸” 二字,實則是解決二分類問題的經(jīng)典模型。其核心優(yōu)勢在于結構簡單、可解釋性強、計算效率高,廣泛應用于信用評估、垃圾郵件識別、疾病診斷等場景。本文將從核心原理、實現(xiàn)步驟、Python 代碼實現(xiàn)、實驗結果分析及常見問題解決等方面,全面講解邏輯回歸算法,幫助初學者快速掌握并落地實踐。
一、邏輯回歸核心知識梳理
1. 算法定位與適用場景
邏輯回歸是基于統(tǒng)計學習的二分類算法,通過 Sigmoid 函數(shù)將線性回歸的連續(xù)輸出映射到 0-1 區(qū)間,以此表示樣本屬于某一類別的概率。適用于:
- 目標變量為二元類別(如 0/1、是 / 否、正 / 負)的場景;
- 數(shù)據(jù)特征與目標變量存在線性相關關系的問題;
- 對模型可解釋性要求較高、需要快速訓練和預測的場景。
2. 核心優(yōu)缺點
| 優(yōu)點 | 缺點 |
|---|---|
| 模型結構簡單,易理解和實現(xiàn) | 僅能建模線性關系,無法處理非線性數(shù)據(jù) |
| 可解釋性強,參數(shù)對應特征重要性 | 對異常值敏感,需提前處理 |
| 計算效率高,訓練和預測速度快 | 原生不支持多分類(需通過 One-vs-Rest 等方式擴展) |
| 無需復雜調參,泛化能力穩(wěn)定 | 需對特征進行標準化 / 歸一化處理 |
3. 核心原理
(1)Sigmoid 函數(shù)
邏輯回歸通過 Sigmoid 函數(shù)實現(xiàn) “連續(xù)輸出→概率映射”,函數(shù)公式如下:

其中z是線性回歸的輸出,即

(w0?為偏置項,w1?−wn?為特征權重,x1?−xn?為樣本特征)。
Sigmoid 函數(shù)的特性:
- 輸出值范圍嚴格在 (0,1) 之間,可直接作為概率解釋;
- 當z=0時,σ(z)=0.5(分類閾值);
- 當z>0時,σ(z)>0.5(預測為正類 1);當z<0時,σ(z)<0.5(預測為負類 0)。
(2)損失函數(shù)與優(yōu)化目標
邏輯回歸的優(yōu)化目標是最大化 “似然函數(shù)”(即讓模型預測結果與真實標簽的匹配概率最高),等價于最小化 “交叉熵損失函數(shù)”,損失函數(shù)公式如下:

其中
是模型對第i個樣本的預測概率,yi?是第i個樣本的真實標簽,m是樣本總數(shù)。
(3)參數(shù)求解方法
采用梯度上升法(因目標是最大化似然函數(shù))求解最優(yōu)權重w,權重更新公式為:
w=w+α⋅∇L(w)
其中α是學習率(控制每次權重更新的步長),∇L(w)是損失函數(shù)的梯度(指引權重更新方向)。
常用的兩種梯度上升實現(xiàn):
- 批量梯度上升(BGD):每次使用全量樣本計算梯度,收斂穩(wěn)定但適用于小數(shù)據(jù)集;
- 隨機梯度上升(SGD):每次使用單個樣本計算梯度,速度快但收斂波動較大,適用于大數(shù)據(jù)集。
4. 算法執(zhí)行步驟
- 數(shù)據(jù)準備:收集數(shù)據(jù)→數(shù)據(jù)清洗(處理缺失值、異常值)→特征選擇→劃分訓練集 / 測試集;
- 特征工程:對特征進行標準化 / 歸一化(消除量綱影響)、類別特征編碼(如 One-Hot);
- 模型訓練:初始化權重→設置學習率和迭代次數(shù)→通過梯度上升法更新權重;
- 模型評估:使用準確率、精確率、召回率、F1-score 等指標評估模型性能,必要時進行交叉驗證;
- 模型優(yōu)化:調整學習率、迭代次數(shù)等超參數(shù),或優(yōu)化特征工程(如添加多項式特征)。
二、Python 完整實現(xiàn)代碼
1. 環(huán)境依賴
需安裝 NumPy(數(shù)值計算)和 Matplotlib(可視化)庫,安裝命令:
pip install numpy matplotlib
2. 完整代碼(兼容 NumPy 2.0+)
import numpy as np
import matplotlib.pyplot as plt
# 1. 加載數(shù)據(jù)集(構造二維特征的二分類數(shù)據(jù),添加偏置項)
def load_dataset():
"""
加載數(shù)據(jù)集,返回特征矩陣、標簽矩陣、測試集
"""
data_mat = [] # 特征矩陣(含偏置項)
label_mat = [] # 標簽矩陣
# 構造訓練數(shù)據(jù)(模擬文章中的數(shù)據(jù)集分布)
fr = [
"3.542485\t1.977398\t0",
"3.018896\t2.556416\t0",
"7.551510\t-1.580030\t1",
"2.114999\t-0.004466\t0",
"8.127113\t1.274372\t1",
"7.108772\t-0.986906\t1",
"2.326297\t0.265213\t0",
"0.207971\t-0.438046\t0",
"6.332009\t0.469543\t1",
"6.172788\t-2.044329\t1",
"3.645780\t3.410627\t0",
"3.125951\t-0.160513\t0",
"2.912122\t-0.206010\t0",
"8.307974\t-0.422311\t1",
"5.286862\t0.660109\t1"
]
for line in fr:
line_arr = line.strip().split('\t')
# 特征:[偏置項1, 特征1, 特征2]
data_mat.append([1.0, float(line_arr[0]), float(line_arr[1])])
label_mat.append(int(line_arr[2]))
# 構造測試集(4個樣本,模擬文章中的測試數(shù)據(jù))
test_set = [
[1.0, 7.635630, 0.215151],
[1.0, 6.383078, -1.012999],
[1.0, 7.192221, -0.130088],
[1.0, 8.348103, 1.071160]
]
return np.asmatrix(data_mat), np.asmatrix(label_mat).transpose(), np.asmatrix(test_set)
# 2. Sigmoid函數(shù)(將線性輸出映射到0-1區(qū)間)
def sigmoid(in_x):
"""
Sigmoid激活函數(shù)
:param in_x: 輸入(線性回歸輸出)
:return: 0-1之間的概率值
"""
return 1.0 / (1 + np.exp(-in_x))
# 3. 批量梯度上升訓練邏輯回歸模型
def grad_ascent(data_mat_in, class_labels):
"""
批量梯度上升法求解最優(yōu)權重
:param data_mat_in: 特征矩陣(m×n)
:param class_labels: 標簽矩陣(m×1)
:return: 最優(yōu)權重矩陣(n×1)
"""
data_matrix = np.asmatrix(data_mat_in)
label_mat = np.asmatrix(class_labels)
m, n = np.shape(data_matrix) # m:樣本數(shù),n:特征數(shù)(含偏置)
alpha = 0.001 # 學習率(與文章一致)
max_cycles = 500 # 迭代次數(shù)(與文章一致)
weights = np.ones((n, 1)) # 初始化權重為1
for k in range(max_cycles):
h = sigmoid(data_matrix * weights) # 預測概率(m×1)
error = (label_mat - h) # 誤差(m×1)
# 梯度上升更新權重:weights = weights + alpha * X.T * (y - h)
weights = weights + alpha * data_matrix.transpose() * error
return weights
# 4. 隨機梯度上升(可選,用于對比)
def stoc_grad_ascent0(data_mat_in, class_labels):
"""
隨機梯度上升法(單樣本更新)
"""
m, n = np.shape(data_mat_in)
alpha = 0.01
weights = np.ones(n) # 一維數(shù)組
for i in range(m):
h = sigmoid(sum(data_mat_in[i] * weights))
error = class_labels[i] - h
weights = weights + alpha * error * data_mat_in[i]
return np.mat(weights).transpose()
# 5. 預測函數(shù)
def classify_vector(in_x, weights):
"""
根據(jù)權重預測類別,并輸出概率
:param in_x: 單個樣本特征(1×n)
:param weights: 最優(yōu)權重(n×1)
:return: 預測概率、預測類別(0/1)
"""
prob = sigmoid(in_x * weights)
label = 1.0 if prob > 0.5 else 0.0
return prob[0, 0], label
# 6. 繪制決策邊界
def plot_best_fit(weights, data_mat, label_mat):
"""
繪制樣本點和邏輯回歸的決策邊界
"""
data_arr = np.array(data_mat)
n = np.shape(data_arr)[0]
xcord1 = []; ycord1 = [] # 類別1的樣本
xcord2 = []; ycord2 = [] # 類別0的樣本
# 區(qū)分兩類樣本
for i in range(n):
if int(label_mat[i]) == 1:
xcord1.append(data_arr[i, 1])
ycord1.append(data_arr[i, 2])
else:
xcord2.append(data_arr[i, 1])
ycord2.append(data_arr[i, 2])
# 繪制散點圖
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xcord1, ycord1, s=30, c='blue', marker='o', label='Class 1')
ax.scatter(xcord2, ycord2, s=30, c='red', marker='x', label='Class 0')
# 計算決策邊界(sigmoid(z)=0.5 → z=0 → w0 + w1x1 + w2x2 = 0 → x2 = (-w0 -w1x1)/w2)
x = np.arange(-1.0, 10.0, 0.1)
y = (-weights[0, 0] - weights[1, 0] * x) / weights[2, 0]
ax.plot(x, y, c='green', label='Decision Boundary')
# 設置坐標軸和圖例
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.legend(loc='upper left')
plt.title('Logistic Regression Decision Boundary')
plt.show()
# 主函數(shù):執(zhí)行邏輯回歸完整流程
if __name__ == "__main__":
# 1. 加載數(shù)據(jù)
data_mat, label_mat, test_set = load_dataset()
print("數(shù)據(jù)集加載完成,訓練樣本數(shù):", np.shape(data_mat)[0])
print("測試樣本數(shù):", np.shape(test_set)[0])
# 2. 測試Sigmoid函數(shù)
print("\nSigmoid函數(shù)測試:sigmoid(0) =", sigmoid(0))
print("sigmoid(2) =", sigmoid(2))
print("sigmoid(-2) =", sigmoid(-2))
# 3. 訓練模型(批量梯度上升)
weights = grad_ascent(data_mat, label_mat)
print("\n批量梯度上升得到的最優(yōu)權重:")
print(weights)
# 可選:隨機梯度上升訓練
# weights_stoc = stoc_grad_ascent0(np.array(data_mat), np.array(label_mat).flatten())
# print("\n隨機梯度上升得到的最優(yōu)權重:")
# print(weights_stoc)
# 4. 測試集預測
print("\n測試集預測結果:")
for i in range(np.shape(test_set)[0]):
prob, label = classify_vector(test_set[i], weights)
print(f"測試樣本{i+1}:預測概率={prob:.4f},預測類別={int(label)}")
# 5. 繪制決策邊界
plot_best_fit(weights, data_mat, label_mat)三、關鍵代碼說明
1. 數(shù)據(jù)加載模塊
- 手動構造了 15 個訓練樣本和 4 個測試樣本,每個樣本包含 2 個特征和 1 個二元標簽;
- 為特征矩陣添加了偏置項 1.0,對應線性回歸中的w0?,確保模型能擬合截距;
- 兼容 NumPy 2.0 + 版本:使用
np.asmatrix替代棄用的np.mat函數(shù)(避免報錯)。
2. 模型訓練模塊
- 批量梯度上升(BGD):每次使用全量訓練數(shù)據(jù)計算梯度,確保收斂穩(wěn)定,適合小數(shù)據(jù)集;
- 隨機梯度上升(SGD):每次僅用 1 個樣本更新權重,訓練速度快,適合大數(shù)據(jù)集;
- 學習率設置為 0.001,迭代次數(shù) 500 次:平衡訓練速度和收斂效果(可根據(jù)實際數(shù)據(jù)調整)。
3. 預測與可視化模塊
- 預測函數(shù)同時輸出概率和類別,便于分析模型置信度;
- 決策邊界推導:基于 Sigmoid 函數(shù)閾值 0.5,將w0?+w1?x1?+w2?x2?=0變形為x2?=(−w0?−w1?x1?)/w2?,直接繪制直線即可。
四、實驗結果與分析
1. 輸出結果
(1)最優(yōu)權重
運行代碼后,批量梯度上升得到的最優(yōu)權重如下(與理論預期一致):

- 偏置項權重w0?=4.124,特征 1 權重w1?=0.480,特征 2 權重w2?=−0.617;
- 權重正負表示特征對類別影響的方向:特征 1 正向影響(權重為正),特征 2 負向影響(權重為負)。
(2)測試集預測結果
4 個測試樣本均被預測為類別 1,預測概率在 0.76~1.0 之間:

(3)繪制決策邊界

總結
到此這篇關于邏輯回歸算法詳解與Python實現(xiàn)完整代碼示例的文章就介紹到這了,更多相關Python邏輯回歸算法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
python 產(chǎn)生token及token驗證的方法
今天小編就為大家分享一篇python 產(chǎn)生token及token驗證的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12

