机器学习——逻辑回归

一、逻辑回归概念点

逻辑回归 (Logistic Regression)是一种广泛使用的统计分析方法和机器学习算法,主要用于处理二分类问题(即因变量为二元类别,如0和1、是和否等)。尽管名字中有"回归"二字,但它实际上是一种分类算法,而不是回归分析方法

1.1 逻辑回归优缺点

1.优点

  • 简单易懂:逻辑回归模型结构简单,易于理解和实现
  • 可解释性强:模型参数(权重)具有明确的统计意义,可以解释各个特征对结果的影响
  • 计算效率高:逻辑回归算法计算速度快,适合大规模数据集
  • 适用于二分类问题:逻辑回归是处理二分类问题的标准方法之一

2.缺点

  • 对非线性关系建模能力有限:逻辑回归假设特征与目标变量之间是线性关系,对非线性关系建模能力有限
  • 对异常值敏感:逻辑回归对异常值较为敏感,可能会影响模型的准确性
  • 需要特征缩放:逻辑回归对特征的尺度敏感,通常需要对特征进行标准化或归一化处理
  • 不适合多分类问题:虽然可以通过一对多或一对一的方法扩展到多分类问题,但不如其他算法(如决策树、随机森林等)直接

1.2 逻辑回归原理

逻辑回归的核心是使用Sigmoid 函数 (也称为逻辑函数)将线性回归的输出映射到0和1之间,表示事件发生的概率

Sigmoid 函数的公式为:

其中,z是线性回归的输出,即

逻辑回归的目标是找到一组权重 w ,使得模型对训练数据的预测尽可能准确。这通常通过最大化似然函数 来实现,等价于最小化损失函数(如交叉熵损失)

1.3 逻辑回归执行步骤

1.3.1 数据准备

  • 收集数据:收集包含特征和目标变量的数据集
  • 数据清洗:处理缺失值、异常值等
  • 特征选择:选择对目标变量有影响的特征
  • 数据分割:将数据集分为训练集和测试集

1.3.2 特征工程

  • 特征缩放:对特征进行标准化或归一化处理,以提高模型的收敛速度和准确性
  • 特征编码:对分类特征进行编码

1.3.3 模型训练

  • 初始化参数:随机初始化模型参数(权重)
  • 选择优化算法:如梯度下降法
  • 迭代优化:通过迭代优化算法更新模型参数,直到收敛或达到最大迭代次数

1.3.4 模型评估

  • 使用测试集评估模型性能,常用的评估指标包括准确率、精确率、召回率、F1分数等
  • 交叉验证:使用交叉验证方法评估模型的泛化能力

1.3.5 模型优化

  • 参数调优:通过网格搜索或随机搜索等方法调整模型参数。
  • 特征选择:使用特征选择方法(如递归特征消除、L1正则化等)选择最佳特征

二、Python代码实现逻辑回归

2.1 数据分析

在给出的数据中,前两列是特征值分别作为X轴和Y轴,第三列是类别标签

-0.017612 14.053064 0

-1.395634 4.662541 1

-0.752157 6.538620 0

-1.322371 7.152853 0

0.423363 11.054677 0

0.406704 7.067335 1

0.667394 12.741452 0

-2.460150 6.866805 1

0.569411 9.548755 0

-0.026632 10.427743 0

0.850433 6.920334 1

1.347183 13.175500 0

1.176813 3.167020 1

-1.781871 9.097953 0

-0.566606 5.749003 1

0.931635 1.589505 1

-0.024205 6.151823 1

-0.036453 2.690988 1

-0.196949 0.444165 1

1.014459 5.754399 1

1.985298 3.230619 1

-1.693453 -0.557540 1

-0.576525 11.778922 0

-0.346811 -1.678730 1

-2.124484 2.672471 1

1.217916 9.597015 0

-0.733928 9.098687 0

-3.642001 -1.618087 1

0.315985 3.523953 1

1.416614 9.619232 0

-0.386323 3.989286 1

0.556921 8.294984 1

1.224863 11.587360 0

-1.347803 -2.406051 1

1.196604 4.951851 1

0.275221 9.543647 0

0.470575 9.332488 0

-1.889567 9.542662 0

-1.527893 12.150579 0

-1.185247 11.309318 0

-0.445678 3.297303 1

1.042222 6.105155 1

-0.618787 10.320986 0

1.152083 0.548467 1

0.828534 2.676045 1

-1.237728 10.549033 0

-0.683565 -2.166125 1

0.229456 5.921938 1

-0.959885 11.555336 0

0.492911 10.993324 0

0.184992 8.721488 0

-0.355715 10.325976 0

-0.397822 8.058397 0

0.824839 13.730343 0

1.507278 5.027866 1

0.099671 6.835839 1

-0.344008 10.717485 0

1.785928 7.718645 1

-0.918801 11.560217 0

-0.364009 4.747300 1

-0.841722 4.119083 1

0.490426 1.960539 1

-0.007194 9.075792 0

0.356107 12.447863 0

0.342578 12.281162 0

-0.810823 -1.466018 1

2.530777 6.476801 1

1.296683 11.607559 0

0.475487 12.040035 0

-0.783277 11.009725 0

0.074798 11.023650 0

-1.337472 0.468339 1

-0.102781 13.763651 0

-0.147324 2.874846 1

0.518389 9.887035 0

1.015399 7.571882 0

-1.658086 -0.027255 1

1.319944 2.171228 1

2.056216 5.019981 1

-0.851633 4.375691 1

-1.510047 6.061992 0

-1.076637 -3.181888 1

1.821096 10.283990 0

3.010150 8.401766 1

-1.099458 1.688274 1

-0.834872 -1.733869 1

-0.846637 3.849075 1

1.400102 12.628781 0

1.752842 5.468166 1

0.078557 0.059736 1

0.089392 -0.715300 1

1.825662 12.693808 0

0.197445 9.744638 0

0.126117 0.922311 1

-0.679797 1.220530 1

0.677983 2.556666 1

0.761349 10.693862 0

-2.168791 0.143632 1

1.388610 9.341997 0

0.317029 14.739025 0

2.2 代码展示

2.2.1 导入相关库

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

2.2.2 数据预处理

python 复制代码
path = '文件名.txt'

def loaddataset():
    testset = [[-3.141592, 2.343434], [7.12121, 3.232323], [-1.222222, 3.2323232], [2.794747, -4.67890]]
    datamat = []
    labelmat = []
    fr = open(path)
    for line in fr.readlines():
        linearr = line.strip().split()
        datamat.append([1.0, float(linearr[0]), float(linearr[1])])
        labelmat.append(int(linearr[2]))
    return datamat, labelmat, testset

代码解析:

1.定义了一个变量 path,对包含数据集的文本文件的路径和文件名进行存储

2.定义函数loaddataset(),将数据集从文件中加载出来

3.定义了一个 testset 的列表,其中包含了测试数据集。每个子列表代表一个测试样本,包含两个

特征值

4.初始化两个空列表,datamat 用于存储训练数据的特征,labelmat 用于存储训练数据的标签

5.打开文件,逐行读取文件中的内容并将数据存储到datamat列表和labelmat列表中

6.返回三个值:datamat(训练数据的特征),labelmat(训练数据的标签),以及 testset(测试数据集)

2.2.3 逻辑回归模型构建

python 复制代码
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

# 测试函数并展示图像
def test_sigmoid():
    nums = np.arange(-10, 10, 0.1)
    sig_values = sigmoid(nums)
    fig, ax = plt.subplots(figsize=(12, 8))
    ax.plot(nums, sig_values, 'g')
    ax.set_xlabel('Input Value')
    ax.set_ylabel('Sigmoid Value')
    ax.set_title('Sigmoid Function')
    plt.grid(True)
    plt.show()

2.2.4 实现模型的梯度上升函数

python 复制代码
# 实现模型的梯度上升函数
def gradascent(datamatin, classlabels, stoptype='bgd'):
    m, n = np.shape(datamatin)  # m为矩阵的行数,n为矩阵的列数
    weights = np.ones((n, 1))  # 权重矩阵(n,1)的列向量
    alpha = 0.001  # 学习率(梯度上升的步长)
    if stoptype == 'bgd':
        datamatrix = np.asmatrix(datamatin)  # 将datamatrix转化为矩阵
        labelmat = np.asmatrix(classlabels).transpose()  # 将labelmat转化为矩阵同时转置
        maxcycles = 500  # 最大迭代次数
        for k in range(maxcycles):  # 梯度上升循环
            h = sigmoid(datamatrix * weights)  # 使用当前权重和输入数据计算每个数据点的预测概率
            error = (labelmat - h)  # 计算预测概率和真实标签的误差
            weights = weights + alpha * datamatrix.transpose() * error
        return weights  # datamatrix.transpose()*error为梯度,再利用梯度*学习率来更新权值
    elif stoptype == 'sgd':
        weights = np.ones((n, 1))  # 初始化权重
        for i in range(m):
            h = sigmoid(np.dot(datamatin[i], weights))  # 使用当前权重和输入数据计算每个数据点的预测概率
            error = classlabels[i] - h  # 计算预测概率和真实标签的误差
            weights = weights + alpha * error * np.array(datamatin[i]).reshape(n, 1)
        return weights

2.2.5 预测测试集,划分类别

python 复制代码
# 预测测试集,划分类别
def classifyVector(testset, weights):
    count = 0
    testset = np.array(testset)
    for sample in testset:
        count += 1  # 用来记录当前的测试集
        z = weights[0] * 1 + weights[1] * sample[0] + weights[2] * sample[1]
        result = sigmoid(z)
        print(f"第{count}个测试集计算的概率结果为:{result}")
        if result > 0.5:
            print(f"第{count}个测试预测类别为1类")
        else:
            print(f"第{count}个预测类别为0类")

2.2.6 绘制决策边界

python 复制代码
# 绘制决策边界
def plotBestFit(weights, dataMat, labelMat):
    dataArr = np.array(dataMat)
    n = np.shape(dataArr)[0]  # 获取数据总数
    xcord1 = []; ycord1 = []  # 存放正样本
    xcord2 = []; ycord2 = []  # 存放负样本
    for i in range(n):  # 依据数据集的标签来对数据进行分类
        if int(labelMat[i]) == 1:  # 数据的标签为1,表示为正样本
            xcord1.append(dataArr[i, 1]); ycord1.append(dataArr[i, 2])
        else:
            xcord2.append(dataArr[i, 1]); ycord2.append(dataArr[i, 2])
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(xcord1, ycord1, s=30, c='b', marker='o')  # 绘制正样本
    ax.scatter(xcord2, ycord2, s=30, c='r', marker='x')  # 绘制负样本
    x = np.arange(-3.0, 3.0, 0.1)
    y = (-weights[0, 0] - weights[1, 0] * x) / weights[2, 0]
    ax.plot(x, y)
    plt.xlabel('X1'); plt.ylabel('X2')
    plt.legend(["1", "0", "decision boundary"])
    plt.show()

2.2.7 主函数执行

python 复制代码
# 主函数
if __name__ == "__main__":
    dataMat, labelMat, testset = loaddataset()  # 加载数据集
    test_sigmoid()
    weights = gradascent(dataMat, labelMat)  # 训练模型并获取最优权值
    print("最优权值:")
    print(weights)
    classifyVector(testset, weights)  # 预测测试集
    plotBestFit(weights, dataMat, labelMat)  # 绘制决策边界

2.3 效果截图

2.3.1 逻辑回归模型展示

2.3.2 最优权值

2.3.3 测试集预测

2.3.4 绘制决策边界

2.4 总结

2.4.1 实验目标

本次实验的目标是通过实现逻辑回归模型,对二分类数据集进行训练和预测,并通过绘制决策边界来直观展示模型的分类效果。实验主要涉及以下内容:

  • 数据加载与预处理
  • 实现逻辑回归模型的训练(梯度上升法)
  • 对测试集进行预测
  • 绘制决策边界并评估模型性能

2.4.2 实验方法

本次实验采用 Python 编程语言,使用 NumPy 和 Matplotlib 等库实现逻辑回归模型。实验步骤如下:

  1. 数据加载与预处理
  • 数据集包含两个特征和一个标签,标签为 0 或 1
  • 数据加载时,每行数据被处理为一个特征向量(添加偏置项 1.0)和对应的标签
  • 数据集被分为训练集和测试集
  1. 模型训练
  • 采用梯度上升法(Gradient Ascent)训练逻辑回归模型
  • 实现了两种梯度上升方法:批量梯度上升,即使用所有数据点计算梯度,更新权重;随机梯度上升,即每次只使用一个数据点计算梯度,更新权重。
  • 学习率设置为 0.001,迭代次数为 500 次(BGD)
  1. 预测与评估
  • 使用训练好的权重对测试集进行预测
  • 预测结果基于 Sigmoid 函数的输出,阈值为 0.5
  • 打印每个测试样本的预测概率和预测类别
  1. 决策边界绘制
  • 根据训练好的权重绘制决策边界
  • 决策边界由公式 确定
  • 数据点根据标签分为两类,分别用蓝色圆圈(正样本)和红色叉号(负样本)表示

2.4.3 实验分析

  1. 模型性能
  • 从决策边界图像可以看出,模型能够较好地分隔两类数据,说明训练效果较好
  • 测试集的预测结果也表明,模型能够准确地对新样本进行分类
  1. 梯度上升法
  • 批量梯度上升法(BGD):计算稳定,但计算量较大,适合小数据集
  • 随机梯度上升法(SGD):计算速度快,但收敛速度可能较慢,适合大数据集

通过实现逻辑回归模型,加深了对逻辑回归算法的理解,包括 Sigmoid 函数、梯度上升法等核心概念,在实验中, 使用 Python 和 NumPy 实现了数据处理、模型训练和可视化,提升了编程能力

相关推荐
碳酸的唐7 分钟前
量子计算模拟:从理论到实践
人工智能·量子计算
kailp1 小时前
云渲染技术解析与渲酷平台深度测评:如何实现高效3D创作?
人工智能·深度学习·3d·渲染·gpu算力
liuyang-neu2 小时前
目标检测 Lite-DETR(2023)详细解读
人工智能·目标检测·计算机视觉
Tech Synapse2 小时前
深度解析3D模型生成器:基于StyleGAN3与PyTorch3D的多风格生成工具开发实战
人工智能·pytorch·深度学习·3d
Qforepost3 小时前
英伟达有意入股 PsiQuantum,释放战略转向量子计算的重要信号
人工智能·量子计算·量子
Blossom.1183 小时前
量子计算在金融科技中的应用前景
大数据·人工智能·安全·机器学习·计算机视觉·金融·量子计算
旺仔溜溜没3 小时前
Autodl训练Faster-RCNN网络(自己的数据集)
人工智能·深度学习·神经网络·cnn
广州华锐视点3 小时前
VR 航天科普,沉浸式体验宇宙奥秘
人工智能·vr
纠结哥_Shrek3 小时前
ollama+open-webui搭建可视化大模型聊天
人工智能·电商·ollama·open-webui
熊猫在哪4 小时前
野火鲁班猫(arrch64架构debian)从零实现用MobileFaceNet算法进行实时人脸识别(一)conda环境搭建
linux·人工智能·python·嵌入式硬件·神经网络·机器学习·边缘计算