机器学习之逻辑回归

文章目录

1.逻辑回归简介

1.1 什么是逻辑回归

逻辑回归(Logistic Regression)是一种用于解决分类问题的统计方法,尤其适用于二分类问题。尽管名称中有"回归",但它主要用于分类任务。

逻辑回归通过将线性回归的输出映射到0,1区间,来表示某个类别的概率。

常用的映射函数是sigmoid函数: f ( x ) = 1 1 + e − x f\left(x\right)=\frac{1}{1+e^{-x}} f(x)=1+e−x1,其导数 f ′ ( x ) = f ( x ) ( 1 − f ( x ) ) f\prime \left(x\right)=f(x)(1-f\left(x\right)) f′(x)=f(x)(1−f(x))

逻辑回归结果可表示为:

P ( y = 1 ∣ x ) = 1 1 + e − ( β 0 + β 1 x 1 + β 2 x 2 + ... + β n x n ) P(y=1\mid \boldsymbol{x})=\frac{1}{1+e^{-\left({\beta }{0}+{\beta }{1}x_{1}+{\beta }{2}x{2}+\ldots +{\beta }{n}x{n}\right)}} P(y=1∣x)=1+e−(β0+β1x1+β2x2+...+βnxn)1

其中 β 0 + β 1 x 1 + β 2 x 2 + ... + β n x n {\beta }{0}+{\beta }{1}x_{1}+{\beta }{2}x{2}+\ldots +{\beta }{n}x{n} β0+β1x1+β2x2+...+βnxn为线性回归输出结果,P(y=1∣x)表示输出为1类的概率。根据逻辑回归结果和阈值来确认最终预测结果,若逻辑回归结果大于阈值则输出为1类,反之输出为0类。

1.2逻辑回归应用场景

  • 信用评分:预测客户是否会违约(违约/不违约)。
  • 欺诈检测:预测某笔交易是否是欺诈行为。
  • 垃圾邮件检测:预测一封邮件是否是垃圾邮件(垃圾邮件/非垃圾邮件)。
  • 广告点击预测:预测用户是否会点击某个广告(点击/不点击)。
  • 图像分类:将图像分类为不同的类别(如猫、狗、鸟等)。
  • 情感分析:将文本分类为正面、负面或中性情感。
  • 产品质量分类:预测产品是否合格。
  • 医学诊断:预测患者是否患有某种疾病(患病/未患病)。
  • 蛋白质功能预测:基于蛋白质序列和结构特征预测其功能类别。

1.3逻辑回归损失函数

逻辑回归的损失函数通常使用对数损失(Log Loss),也称为二元交叉熵损失(Binary Cross-Entropy Loss),用于衡量模型输出的概率分布与真实标签之间的差距。逻辑回归的损失函数来源于最大似然估计(MLE)。

P ( Y | X ; β ) P\left(Y\middle| X;\boldsymbol{\beta }\right) P(Y∣X;β)表示给定输入特征x和模型参数β时,因变量y发生的概率:

似然函数 L ( β ) L\left(\boldsymbol{\beta }\right) L(β)表示已知y的结果,此时模型参数为β的概率:

对于1个样本: L ( β ) = P ( y | x ; β ) = P ( y = 1 | x ; β ) y ( 1 − P ( y = 1 | x ; β ) ) 1 − y L\left(\boldsymbol{\beta }\right)=P\left(y\middle| \boldsymbol{x};\boldsymbol{\beta }\right)={P\left(y=1\middle| \boldsymbol{x};\boldsymbol{\beta }\right)}^{y}{\left(1-P\left(y=1\middle| \boldsymbol{x};\boldsymbol{\beta }\right)\right)}^{1-y} L(β)=P(y∣x;β)=P(y=1∣x;β)y(1−P(y=1∣x;β))1−y

对于 n \mathrm{n} n个样本: L ( β ) = ∏ i = 1 n P ( y i | x i ; β ) = ∏ i = 1 n P ( y i = 1 | x i ; β ) y i ( 1 − P ( y i = 1 | x i ; β ) ) 1 − y i L\left(\boldsymbol{\beta }\right)=\prod_{i=1}^{n} P\left(y_{i}\middle| {\boldsymbol{x}}{\boldsymbol{i}};\boldsymbol{\beta }\right)=\prod{i=1}^{n} {P\left(y_{i}=1\middle| {\boldsymbol{x}}{\boldsymbol{i}};\boldsymbol{\beta }\right)}^{y{i}}{\left(1-P\left(y_{i}=1\middle| {\boldsymbol{x}}{\boldsymbol{i}};\boldsymbol{\beta }\right)\right)}^{1-y{i}} L(β)=∏i=1nP(yi∣xi;β)=∏i=1nP(yi=1∣xi;β)yi(1−P(yi=1∣xi;β))1−yi

1.4API使用

scikit-learn中的LogisticRegression类用于实现逻辑回归。它支持二分类和多分类任务,并提供了多种优化算法和正则化选项。

python 复制代码
# solver: 优化算法
#   lbfgs: 拟牛顿法(默认),仅支持L2正则化
#   newton-cg: 牛顿法,仅支持L2正则化
#   liblinear: 坐标下降法,适用于小数据集,支持L1和L2正则化
#   sag: 随机平均梯度下降,适用于大规模数据集,仅支持L2正则化
#   saga: 改进的随机梯度下降,适用于大规模数据,支持L1、L2和ElasticNet正则化
# penalty: 正则化类型,可选l1、l2和elasticnet
# C: 正则化强度,C越小,正则化强度越大
# class_weight: 类别权重,balanced表示自动平衡类别权重,让模型在训练时更关注少数类,从而减少类别不平衡带来的偏差
model = sklearn.linear_model.LogisticRegression(solver="lbfgs", penalty="l2", C=1, class_weight="balanced")

2.案例:心脏病预测

2.1数据集说明

Heart Disease数据集https://www.kaggle.com/datasets/johnsmith88/heart-disease-dataset。

  • 年龄:连续值

  • 性别:0-女,1-男

  • 胸痛类型:0-典型心绞痛,1-非典型心绞痛,2-非心绞痛,3-无症状

  • 静息血压:连续值,单位mmHg

  • 胆固醇:连续值,单位mg/dl

  • 空腹血糖:1-大于120mg/dl,0-小于等于120mg/dl

  • 静息心电图结果:0-正常,1-ST-T异常,2-可能左心室肥大

  • 最大心率:连续值

  • 运动性心绞痛:1-有,0-无

  • 运动后的ST下降:连续值

  • 峰值ST段的斜率:0-向上,1-水平,2-向下

  • 主血管数量:0到3

  • 地中海贫血:一种先天性贫血,0-正常,1-固定缺陷,2-可逆缺陷

  • 是否患有心脏病:标签,0-否,1-是

2.2特征工程

2.2.1特征转换

数据集中包含多种类型的特征:

  • 类别型特征(需要特殊处理)
  • 胸痛类型:4种分类(名义变量)
  • 静息心电图结果:3种分类(名义变量)
  • 峰值ST段的斜率:3种分类(有序变量)
  • 地中海贫血:4种分类(名义变量)
  • 数值型特征:年龄、静息血压、胆固醇、最大心率、运动后的ST下降、主血管数量
  • 二元特征(保持原样):性别、空腹血糖、运动性心绞痛

对于数值型特征,可以直接进行标准化。

对于类别型特征,直接使用整数编码的类别特征会被算法视为有序数值,导致错误的距离计算(例如:会认为 胸痛类型=1 和 胸痛类型=2 之间的差异比 胸痛类型=1和 胸痛类型=3之间差异更小,而实际上它们都是类别) 。使用 独热编码(One-Hot Encoding)可将类别特征转换为二元向量,消除虚假的顺序关系。

2.2.2避免多重共线性

drop="first"是独热编码中的一个参数,它的核心目的是避免多重共线性(Multicollinearity)。

多重共线性是指特征之间存在高度线性相关关系的现象。例如特征胸痛类型包含4个类别(0、1、2、3),若直接进行独热编码会生成4个新列(胸痛类型_0、胸痛类型_1、胸痛类型_2、胸痛类型_3),此时这4列满足

胸痛类型_0+胸痛类型_1+胸痛类型_2+胸痛类型_3=1

这种完全线性相关关系会导致特征矩阵的列之间存在完美共线性。

当特征矩阵存在多重共线性时,模型参数估计会变得不稳定(矩阵不可逆或接近奇异),导致系数估计值方差增大、模型可解释性下降、过拟合等问题。

在独热编码时设置drop="first",会删除每个类别特征的第1列,从而打破完全共线性。比如特征胸痛类型会生成3列(胸痛类型_1、胸痛类型_2、胸痛类型_3),此时

胸痛类型_1=0,胸痛类型_2=0,胸痛类型_3=0 隐含代表 胸痛类型_0=1

2.3代码实现

python 复制代码
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.linear_model import LogisticRegression

# 加载数据集
heart_disease = pd.read_csv("data/heart_disease.csv")
heart_disease.dropna()

# 划分为训练集与测试集
X = heart_disease.drop("是否患有心脏病", axis=1)  # 特征
y = heart_disease["是否患有心脏病"]  # 标签
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=100)

# 特征工程
# 数值型特征
numerical_features = ["年龄", "静息血压", "胆固醇", "最大心率", "运动后的ST下降", "主血管数量"]
# 类别型特征
categorical_features = ["胸痛类型", "静息心电图结果", "峰值ST段的斜率", "地中海贫血"]
# 二元特征
binary_features = ["性别", "空腹血糖", "运动性心绞痛"]
# 创建列转换器
preprocessor = ColumnTransformer(
    transformers=[
        # 对数值型特征进行标准化
        ("num", StandardScaler(), numerical_features),
        # 对类别型特征进行独热编码,使用drop="first"避免多重共线性
        ("cat", OneHotEncoder(drop="first"), categorical_features),
        # 二元特征不进行处理
        ("binary", "passthrough", binary_features),
    ]
)
# 执行特征转换
x_train = preprocessor.fit_transform(x_train)  # 计算训练集的统计信息并进行转换
x_test = preprocessor.transform(x_test)  # 使用训练集计算的信息对测试集进行转换

# 模型训练
model = LogisticRegression()
model.fit(x_train, y_train)

# 模型评估,计算准确率
model.score(x_test, y_test)

3.多分类任务

逻辑回归通常用于二分类问题,但可以通过一对多(One-vs-Rest,OvR)以及Softmax回归(Multinomial Logistic Regression,多项逻辑回归)来扩展到多分类任务。

3.1一对多(OVR)

1)实现方式

2)优缺点

优点:简单易于实现,适用于类别数量较少的情况。

缺点:每个类别训练1个分类器,当类别数量较多时,训练时间较长。

3)API

python 复制代码
from sklearn.linear_model import LogisticRegression

model = LogisticRegression(multi_class="ovr")

# 或

from sklearn.multiclass import OneVsRestClassifier

model = OneVsRestClassifier(LogisticRegression())

3.2Softmax回归(多项逻辑回归)

1)实现方式

2)优缺点

优点:只训练1个模型,计算高效,分类一致性更好。

缺点:计算Softmax需要对所有类别求指数,计算量较高。

3)API

python 复制代码
from sklearn.linear_model import LogisticRegression

model = LogisticRegression(multi_class="multinomial")

# 对于多分类问题,LogisticRegression会自动使用multinomial,因此multi_class参数可省略

model = LogisticRegression()

4.案例:手写数字识别

4.1数据集说明

Digit Recognizer数据集:https://www.kaggle.com/competitions/digit-recognizer。

文件train.csv中包含手绘数字(从0到9)的灰度图像,每张图像为28×28像素,共784像素。每个像素有一个0到255的值表示该像素的亮度。

文件第1列为标签,之后784列分别为784个像素的亮度值。

第x×28+y个像素表示图像第x行第y列的像素。

4.2逻辑回归实现手写数字识别

python 复制代码
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.linear_model import LogisticRegression

# 加载数据集
digit = pd.read_csv("data/train.csv")
plt.imshow(digit.iloc[10, 1:].values.reshape(28, 28), cmap="gray")
plt.show()
# 划分训练集和测试集
X = digit.drop("label", axis=1)  # 特征
y = digit["label"]  # 标签
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=100)

# 归一化
preprocessor = MinMaxScaler()
x_train = preprocessor.fit_transform(x_train)
x_test = preprocessor.transform(x_test)

# 模型训练
model = LogisticRegression(max_iter=500)
model.fit(x_train, y_train)

# 模型评估
model.score(x_test, y_test)

# 预测
plt.imshow(digit.iloc[123, 1:].values.reshape(28, 28), cmap="gray")
plt.show()
print(model.predict(digit.iloc[123, 1:].values.reshape(1, -1)))
相关推荐
青桔柚子1 小时前
2026 企业 AI 办公工具选型指南:搭建适配业务的 AI 工作体系
人工智能
eBest数字化转型方案1 小时前
快消渠道 AI 落地路线:拍照、数据、决策三阶段的工程逻辑
大数据·人工智能
七牛云行业应用1 小时前
DeepSeek Harness 插件 dsh-zen-remote 教程:手机访问、桌面配对与通知配置
人工智能·ai·智能手机·ai编程
张星河zen1 小时前
英伟达Groq 3 LPX全面量产,AI工厂进入Token拼价时代,重构智能体AI底座
人工智能·大模型·英伟达·groq·推理芯片
ZEB11061 小时前
AI 转型服务商怎么选?五类机构的能力与适用边界
人工智能
数聚天成DeepSData1 小时前
夜间灯光可以代表经济活动吗?先处理年际一致性
人工智能·深度学习·机器学习·数据集·deepsdata
AllData公司负责人1 小时前
AllData搭建AI中台,集成开源项目LabelStudio/CubeStudio,建设数据标注平台/机器学习平台
数据库·人工智能·机器学习·labelstudio·cubestudio
百胜软件@百胜软件1 小时前
百胜软件黄飞:让AI真正走进零售,把不确定性变成“胜券在握”
大数据·人工智能·零售
高洁011 小时前
数字孪生、具身智能、世界模型三者交叉
人工智能·python·深度学习·机器学习