机器学习:逻辑回归实验

一、逻辑回归算法简介

        逻辑回归算法是一种用于解决二分类问题的统计方法,它通过拟合一个逻辑函数(通常是Sigmoid函数)来预测某个事件发生的概率。逻辑回归虽然名字中包含“回归”,但实际上它是一种分类方法,特别是用于处理二分类问题,即结果只有两种可能的情况。

二、算法原理

2.1 线性回归

        线性回归模型是一种用于预测连续变量的统计方法,它通过构建一个线性方程来拟合数据点。这个线性方程可以表示为:

f(x)=w^{T}*x+b

其中,w和b都是通过学习得到的,最常用的方法就是最小二乘法。在线性回归中,最小二乘法就是试图找到一条直线,使得所有样本到直线上的欧氏距离之和最小。我们只需要将函数E_{w,b}=\sum_{i=1}^{m}(y_{i}-wx_{i}-b)^{2}求导并令导数为0即可求解出w和b的最优解。

2.2 sigmoid函数

        Sigmoid函数是一种在生物学、统计学及深度学习中广泛使用的激活函数,以其能够将输入映射到0和1之间的概率值而闻名。Sigmoid函数的基本形式为 S(x)=\frac{1}{1+e^{-x}}​。这个表达式说明Sigmoid函数接收任意实数作为输入,输出则被限制在0到1之间。这种特性使得Sigmoid函数非常适合用于表示概率,或者在任何需要将变量压缩到0和1区间的场景中使用。其函数图像如下图所示:

2.3 逻辑回归具体算法

        逻辑回归模型是统计学中用于解决分类问题的一种方法,特别是在因变量(目标变量)是二元的情况下。该模型源自线性回归,并通过引入Sigmoid函数来实现将预测值转化为概率。

对于线性回归中,f(x)=w^{T}*x+b ,这里f(x)的范围为[ − ∞ , + ∞ ],说明通过线性回归中我们可以求得任意的一个值。对于逻辑回归来说就是概率,这个概率取值需要在区间[0,1]内,所以我们将线性回归进行修改:p=\sigma (w^{T}x+b)此时,我们希望概率p的取值仅在区间[0,1]内。通常我们使用Sigmoid函数表示 。我们将线性回归问题转化为:
p=\sigma (w^{T}x+b)=\frac{1}{1+e^{-w^{T}x+b}}

f=1, p>=0.5;f=0, p<0.5

所以,我们现在需要做的就是找到给定样本集的最优的参数w和b。

2.4 损失函数

        逻辑回归中使用的损失函数是交叉熵损失函数,它衡量的是真实标签与预测标签之间的差距。交叉熵损失越小,模型的预测越准确。它的公式为:

L=−(ylog(p)+(1−y)log(1−p))

其中 y 是真实标签,p 是模型预测为正类的概率。在逻辑回归中,对于一个样本集,我们需要将所有的损失函数加起来得到

J(w)=-\frac{1}{m}\sum_{i=1}^{m}y_{i}log(p_{i})+(1-y_{i})log(1-p_{i})

其中,

p_{i}=\frac{1}{1+e^{-w^{T}+b}}

为了方便计算,重新定义

p_{i}=\frac{1}{1+e^{-w^{T}x^{b}}}

J(w)=-\frac{1}{m}\sum_{i=1}^{m}y_{i}log(\sigma(wx_{i}^{b}))+(1-y_{i})log(1-\sigma (wx_{i}^{b}))

所以,对于逻辑回归问题,我们就是要找到最优的w和b,使得损失函数J(w)最小,在这里,我们使用梯度下降法来求解。

2.5 梯度下降法

        为了最小化损失函数,逻辑回归通常采用梯度下降法来优化模型参数。该方法通过迭代更新参数,使得损失函数逐渐减小,直至收敛到一个局部最小值。

梯度下降算法分为下面几步

  • 初始化权重w
  • 进行若干轮训练
    • 计算预测值
    • 使用激活函数将预测值压缩到(0,1)中
    • 计算损失值:这里采用了每隔100轮输出一次损失的方法
    • 更新权重
  • 保存训练结果

2.6 线性回归与逻辑回归的区别

        尽管逻辑回归与线性回归在形式上类似,但它们解决的问题类型和输出类型不同。线性回归用于预测连续值,是解决回归问题,而逻辑回归用于预测离散的概率值,是解决分类问题。

三、实验及实验结果分析

3.1 数据集

        本次实验的数据集如下:

-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

前两列是属性列,也是我们需要输入的数据,最后一列是分类label。

3.2 实验代码

# 导入numpy库
from numpy import *
import matplotlib.pyplot as plt

# 定义数据集的文件名
filename = 'D:\ML\data\logistic_text.txt'

# 定义函数用于加载数据集
def loadDataSet():
    # 创建空列表用于存储数据和标签
    data = []
    label = []
    # 打开文件
    fr = open(filename)
    # 逐行读取文件内容
    for line in fr.readlines():
        # 去除空白符并按空格切分每一行
        lineArray = line.strip().split()
        # 将数据添加到data列表中,确保第一个元素为1.0(偏置项)
        data.append([1.0, float(lineArray[0]), float(lineArray[1])])
        # 将标签转换为整数并添加到label列表中
        label.append(int(lineArray[2]))
    # 返回数据和标签
    return data, label

# 定义sigmoid函数,用于逻辑回归模型
def sigmoid(X):
    # 计算sigmoid值
    return 1.0 / (1 + exp(-X))

# 设置学习率
alpha = 0.001

# 定义函数用于计算梯度
def gradient(weights, data, label):
    # 将数据转换为矩阵形式
    dataMatrix = mat(data)
    # 将标签转换为矩阵形式,并进行转置
    classLabels = mat(label).transpose()
    # 计算预测值
    h = sigmoid(dataMatrix * weights)
    # 计算误差
    error = (classLabels - h)
    # 计算梯度
    q = -dataMatrix.transpose() * error
    # 返回梯度
    return q

# 定义梯度下降算法函数
def gradient_Accent(data, label):
    # 获取数据的形状
    m, n = shape(data)
    # 初始化权重向量
    weights = ones((n, 1))
    # 初始化梯度
    q = gradient(weights, data, label)
    # 当梯度的绝对值大于阈值时,继续迭代更新权重
    while not all(absolute(q) <= 2e-5):
        weights = weights - alpha * q
        q = gradient(weights, data, label)
    # 返回最终的权重向量
    return weights

# 定义函数用于绘制最终分类结果的图形
def plotBestFit(weights):
    # 加载数据和标签
    dataMat, labelMat = loadDataSet()
    # 将数据转换为数组形式
    dataArr = array(dataMat)
    # 获取数据的数量
    n = shape(dataArr)[0]
    # 分别存储类别1和类别0的数据点坐标
    xcord1 = []; ycord1 = []
    xcord2 = []; ycord2 = []
    # 根据标签将数据点分配到不同的列表中
    for i in range(n):
        if int(labelMat[i]) == 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)
    # 绘制类别1的数据点(红色圆圈)
    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
    # 绘制类别0的数据点(绿色圆圈)
    ax.scatter(xcord2, ycord2, s=30, c='green')
    # 创建一个从-3到3的等差数列,用于绘制决策边界
    x = arange(-3.0, 3.0, 0.1)
    # 计算对应的y值
    y = (-weights[0] - weights[1] * x) / weights[2]
    # 在图上绘制决策边界(蓝色线)
    ax.plot(x, y)
    # 设置x轴和y轴的标签
    plt.xlabel('X1')
    plt.ylabel('X2')
    # 显示图形
    plt.show()

# 定义主函数
def main():
    # 加载数据和标签
    dataMat, labelMat = loadDataSet()
    # 使用梯度下降算法训练模型并获取权重向量
    weights = gradient_Accent(dataMat, labelMat).getA()
    # 调用函数绘制最终分类结果的图形
    plotBestFit(weights)

# 如果当前脚本是主程序,则执行main函数
if __name__ == '__main__':
    main()

3.3 实验结果及分析

        

        由上图可知,本次实验的实验结果很好,只错分了3个点。

四、总结

        综上所述,逻辑回归模型通过引入Sigmoid函数,将线性回归的输出转化为概率值,从而实现对二元分类问题的预测。其算法简单且有效,广泛应用于医学、生物统计学、市场营销等领域。尽管面临一些挑战,如对异常值的敏感性和对数据集的特定要求,但通过适当的数据处理和模型调优,逻辑回归仍然是一个非常有力的工具。在未来,随着机器学习和数据科学的发展,逻辑回归及其变种将继续在解决实际问题中发挥重要作用。

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值