【机器学习】1.逻辑回归
逻辑回归(Logistic Regression)全解析
逻辑回归是机器学习中经典的分类算法(虽名为“回归”,实则用于分类),核心是将线性回归的连续输出映射到[0,1]区间,以此表示样本属于某一类的概率。本文从基础原理、核心方法、语法格式、实战案例四个维度系统梳理。
一、核心基础:逻辑回归的数学原理
1.1 从线性回归到Sigmoid函数
线性回归的输出是连续值:z=wTx+bz = w^T x + bz=wTx+b(www为权重,bbb为偏置,xxx为特征)。
逻辑回归通过Sigmoid函数将zzz映射到(0,1),得到分类概率:
σ(z)=11+e−z\sigma(z) = \frac{1}{1 + e^{-z}}σ(z)=1+e−z1
- 当σ(z)≥0.5\sigma(z) \geq 0.5σ(z)≥0.5时,预测为正类(Y=1Y=1Y=1);
- 当σ(z)<0.5\sigma(z) < 0.5σ(z)<0.5时,预测为负类(Y=0Y=0Y=0)。
1.2 对数几率(Log Odds)
对Sigmoid函数变形可得:
ln(P(Y=1∣X)1−P(Y=1∣X))=wTx+b\ln\left(\frac{P(Y=1|X)}{1-P(Y=1|X)}\right) = w^T x + bln(1−P(Y=1∣X)P(Y=1∣X))=wTx+b
左侧称为“对数几率”(Odds的对数),表示“正类概率/负类概率”的对数,逻辑回归本质是对数几率的线性模型。
1.3 损失函数:对数似然损失(交叉熵损失)
逻辑回归不适用平方损失(非凸函数,梯度下降易陷入局部最优),采用对数似然损失(Log-Likelihood Loss):
L(w,b)=−1N∑i=1N[yiln(y^i)+(1−yi)ln(1−y^i)]L(w,b) = -\frac{1}{N}\sum_{i=1}^N \left[ y_i \ln(\hat{y}_i) + (1-y_i) \ln(1-\hat{y}_i) \right]L(w,b)=−N1i=1∑N[yiln(y^i)+(1−yi)ln(1−y^i)]
- yiy_iyi:真实标签(0/1);
- y^i\hat{y}_iy^i:预测概率(Sigmoid输出);
- 损失越小,模型预测越准。
1.4 优化方法
通过最小化损失函数求解最优www和bbb,常用优化器:
- 梯度下降(GD):批量梯度下降(BGD)、随机梯度下降(SGD)、小批量梯度下降(MBGD);
- 牛顿法/拟牛顿法:收敛速度更快(sklearn默认用拟牛顿法
lbfgs); - 共轭梯度:适用于高维数据。
二、逻辑回归的核心方法分类
逻辑回归的变体主要围绕“分类任务类型”“正则化”“数据平衡”三大维度展开,以下是核心方法总结:
| 方法类型 | 适用场景 | 核心思想 | 关键特点 |
|---|---|---|---|
| 二分类逻辑回归 | 二分类任务(如:是否患病、是否违约) | 直接用Sigmoid函数输出正类概率,0.5为阈值分类 | 基础款,计算高效 |
| 多分类逻辑回归(OVR) | 多分类任务(如:鸢尾花3类) | One-vs-Rest:为每个类别训练一个二分类器,预测时取概率最大的类别 | 简单易实现,适合类别数少的场景 |
| 多分类逻辑回归(OVO) | 多分类任务(如:手写数字10类) | One-vs-One:为每两个类别训练一个二分类器,预测时投票选胜出类别 | 精度高,计算量随类别数平方增长 |
| L1正则化逻辑回归 | 特征维度高、需特征选择 | 损失函数加L1惩罚项:L+α∑wiL + \alpha \sum w_iL+α∑wi | 生成稀疏权重,自动筛选特征 |
| L2正则化逻辑回归 | 解决过拟合(权重过大) | 损失函数加L2惩罚项:L+α∑wi2L + \alpha \sum w_i^2L+α∑wi2 | 权重平滑,避免单特征主导 |
| ElasticNet正则化 | 兼顾特征选择与权重平滑 | 损失函数加L1+L2惩罚项:L+α(ρ∑wi+(1−ρ)∑wi2)L + \alpha(\rho\sum w_i + (1-\rho)\sum w_i^2)L+α(ρ∑wi+(1−ρ)∑wi2) | 结合L1/L2优点 |
| 加权逻辑回归 | 不平衡数据集(如:欺诈检测) | 为不同类别设置权重(class_weight),平衡少数类的损失贡献 | 提升少数类预测精度 |
三、逻辑回归的语法格式(Python + Scikit-learn)
Scikit-learn是实现逻辑回归的主流工具,核心API为sklearn.linear_model.LogisticRegression。
3.1 核心参数说明
| 参数名 | 作用 | 常用取值 |
|---|---|---|
penalty | 正则化类型 | ‘l1’/‘l2’/‘elasticnet’/‘none’ |
C | 正则化强度的倒数(C越小,正则化越强) | 0.01/0.1/1/10/100 |
solver | 优化器 | ‘lbfgs’(默认)/‘sgd’/‘liblinear’/‘newton-cg’ |
multi_class | 多分类策略 | ‘ovr’(OVR)/‘multinomial’(OVO)/‘auto’ |
class_weight | 类别权重 | ‘balanced’(自动平衡)/{0:0.1, 1:0.9}(自定义)/None |
l1_ratio | ElasticNet中L1占比(仅penalty='elasticnet'时生效) | 0~1(如0.5) |
max_iter | 最大迭代次数 | 100(默认)/500/1000 |
random_state | 随机种子(保证结果可复现) | 42/0等 |
3.2 基础语法流程
# 步骤1:导入库
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
# 步骤2:数据预处理(特征缩放+划分训练/测试集)
# 特征缩放:逻辑回归对特征尺度敏感,需标准化(均值0,方差1)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X) # X为特征矩阵
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
# 步骤3:定义模型
model = LogisticRegression(
penalty='l2', # 正则化类型
C=1.0, # 正则化强度倒数
solver='lbfgs', # 优化器
multi_class='auto', # 多分类策略
class_weight=None, # 类别权重
max_iter=100, # 最大迭代次数
random_state=42
)
# 步骤4:训练模型
model.fit(X_train, y_train)
# 步骤5:预测
y_pred = model.predict(X_test) # 预测类别(0/1/...)
y_pred_proba = model.predict_proba(X_test) # 预测每个类别的概率
# 步骤6:模型评估
print("准确率:", accuracy_score(y_test, y_pred))
print("混淆矩阵:\n", confusion_matrix(y_test, y_pred))
print("分类报告:\n", classification_report(y_test, y_pred))
# 步骤7:查看模型参数
print("权重w:", model.coef_)
print("偏置b:", model.intercept_)
四、实战案例:覆盖所有核心方法
案例1:基础二分类逻辑回归(泰坦尼克生存预测)
数据背景
泰坦尼克数据集包含乘客的年龄、性别、舱位等特征,目标是预测乘客是否存活(存活=1,死亡=0)。
完整代码
# 1. 加载数据
import seaborn as sns
df = sns.load_dataset('titanic')
# 2. 数据清洗与特征工程
# 缺失值处理
df['age'].fillna(df['age'].median(), inplace=True)
df['embarked'].fillna(df['embarked'].mode()[0], inplace=True)
df.drop('deck', axis=1, inplace=True)
# 类别特征编码
df = pd.get_dummies(df, columns=['sex', 'embarked', 'pclass'], drop_first=True)
# 选择特征和标签
X = df[['age', 'sibsp', 'parch', 'fare', 'sex_male', 'embarked_Q', 'embarked_S', 'pclass_2', 'pclass_3']]
y = df['survived']
# 3. 数据预处理
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
# 4. 定义并训练二分类逻辑回归模型
model = LogisticRegression(penalty='l2', C=1.0, solver='lbfgs', random_state=42)
model.fit(X_train, y_train)
# 5. 评估
y_pred = model.predict(X_test)
print("二分类准确率:", accuracy_score(y_test, y_pred))
print("混淆矩阵:\n", confusion_matrix(y_test, y_pred))
# 输出示例:
# 二分类准确率: 0.8100558659217877
# 混淆矩阵:
# [[90 15]
# [19 55]]
案例2:多分类逻辑回归(鸢尾花分类)
数据背景
鸢尾花数据集包含3类鸢尾花(setosa、versicolor、virginica),4个特征,目标是多分类。
完整代码
# 1. 加载数据
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data
y = iris.target # 0/1/2对应3类鸢尾花
# 2. 预处理
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)
# 3. 多分类逻辑回归(OVR策略)
model_ovr = LogisticRegression(
penalty='l2',
multi_class='ovr', # OVR策略
solver='lbfgs',
random_state=42
)
model_ovr.fit(X_train, y_train)
# 4. 评估
y_pred_ovr = model_ovr.predict(X_test)
print("多分类(OVR)准确率:", accuracy_score(y_test, y_pred_ovr))
print("分类报告:\n", classification_report(y_test, y_pred_ovr))
# 5. 对比OVO策略(multi_class='multinomial')
model_ovo = LogisticRegression(
penalty='l2',
multi_class='multinomial', # OVO策略
solver='lbfgs',
random_state=42
)
model_ovo.fit(X_train, y_train)
y_pred_ovo = model_ovo.predict(X_test)
print("多分类(OVO)准确率:", accuracy_score(y_test, y_pred_ovo))
# 输出示例:
# 多分类(OVR)准确率: 1.0
# 多分类(OVO)准确率: 1.0(鸢尾花数据简单,两者效果一致)
案例3:正则化逻辑回归(解决过拟合)
背景
模拟高维数据,对比L1、L2、ElasticNet正则化的效果,验证L1的特征选择能力。
完整代码
# 1. 生成模拟高维数据(易过拟合)
from sklearn.datasets import make_classification
X, y = make_classification(
n_samples=1000, n_features=50, n_informative=5, # 仅5个特征有效
n_redundant=45, random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 2. 无正则化(易过拟合)
model_none = LogisticRegression(penalty='none', solver='lbfgs', random_state=42)
model_none.fit(X_train, y_train)
print("无正则化训练集准确率:", model_none.score(X_train, y_train))
print("无正则化测试集准确率:", model_none.score(X_test, y_test))
# 3. L2正则化(缓解过拟合)
model_l2 = LogisticRegression(penalty='l2', C=0.1, solver='lbfgs', random_state=42)
model_l2.fit(X_train, y_train)
print("L2正则化训练集准确率:", model_l2.score(X_train, y_train))
print("L2正则化测试集准确率:", model_l2.score(X_test, y_test))
# 4. L1正则化(特征选择)
model_l1 = LogisticRegression(penalty='l1', C=0.1, solver='liblinear', random_state=42)
model_l1.fit(X_train, y_train)
print("L1正则化非零权重数:", np.sum(model_l1.coef_ != 0)) # 仅保留有效特征
print("L1正则化测试集准确率:", model_l1.score(X_test, y_test))
# 5. ElasticNet正则化
model_elastic = LogisticRegression(
penalty='elasticnet', C=0.1, l1_ratio=0.5, solver='saga', random_state=42
)
model_elastic.fit(X_train, y_train)
print("ElasticNet测试集准确率:", model_elastic.score(X_test, y_test))
# 输出示例:
# 无正则化训练集准确率: 1.0(过拟合)
# 无正则化测试集准确率: 0.85
# L2正则化训练集准确率: 0.92
# L2正则化测试集准确率: 0.88
# L1正则化非零权重数: 5(仅保留5个有效特征)
# L1正则化测试集准确率: 0.89
# ElasticNet测试集准确率: 0.885
案例4:加权逻辑回归(不平衡数据)
背景
模拟欺诈检测数据(正类=欺诈,占比5%),对比普通逻辑回归和加权逻辑回归的效果。
完整代码
# 1. 生成不平衡数据
X, y = make_classification(
n_samples=10000, n_features=20, n_informative=5,
weights=[0.95, 0.05], # 负类95%,正类5%
random_state=42
)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 2. 普通逻辑回归(偏向多数类)
model_normal = LogisticRegression(random_state=42)
model_normal.fit(X_train, y_train)
y_pred_normal = model_normal.predict(X_test)
print("普通逻辑回归(不平衡数据):")
print("准确率:", accuracy_score(y_test, y_pred_normal))
print("分类报告:\n", classification_report(y_test, y_pred_normal))
# 3. 加权逻辑回归(class_weight='balanced')
model_weighted = LogisticRegression(class_weight='balanced', random_state=42)
model_weighted.fit(X_train, y_train)
y_pred_weighted = model_weighted.predict(X_test)
print("加权逻辑回归(不平衡数据):")
print("准确率:", accuracy_score(y_test, y_pred_weighted))
print("分类报告:\n", classification_report(y_test, y_pred_weighted))
# 输出示例(核心对比):
# 普通逻辑回归:正类召回率(recall)仅0.2左右(漏检多)
# 加权逻辑回归:正类召回率提升至0.8左右(少数类预测更准)
五、总结与注意事项
5.1 核心总结
- 逻辑回归是线性分类算法,适合处理线性可分的分类问题,可扩展到多分类;
- 正则化是逻辑回归的核心调优手段:L1用于特征选择,L2用于缓解过拟合,ElasticNet兼顾两者;
- 不平衡数据需用加权逻辑回归(
class_weight='balanced'); - 特征缩放(标准化)是逻辑回归的必要步骤(优化器对特征尺度敏感)。
5.2 注意事项
- 逻辑回归假设特征与对数几率线性相关,非线性问题需先做特征工程(如多项式特征);
- 多分类任务中,OVO精度更高但计算量大,OVR更高效;
- 优化器选择:
lbfgs适合中小数据集,sgd适合大数据集,liblinear支持L1正则化。
通过以上梳理,你可系统掌握逻辑回归的原理、方法和实战,后续可结合网格搜索(GridSearchCV)调优参数,进一步提升模型效果。
更多推荐
所有评论(0)