机器学习——逻辑回归

目录

一、逻辑回归

1.1、模型原理

1.2、损失函数

 二、实例

2.1、定义sigmoid函数

2.2、数据集

2.3、梯度上升算法

2.4、预测函数

2.5、绘画函数

三、代码

运行结果:

四、总结

优点:

缺点:


一、逻辑回归

逻辑回归是一种广义的线性回归分析模型,用于解决二分类或多分类问题。逻辑回归模型,尽管名字中包含“回归”二字,实际上是一种分类方法,特别是用于处理二分类问题。它通过将线性回归的结果通过某种函数映射到(0,1)区间内,从而进行概率的预测和分类决策。逻辑回归在许多领域都有广泛应用,如医疗领域中疾病自动诊断、金融领域中的信用评分以及市场分析等。

1.1、模型原理

  • 线性回归与逻辑函数:逻辑回归的基础是线性回归模型,其核心在于引入了逻辑函数(Sigmoid函数),该函数能将任意实数值映射到(0,1)区间内,输出可以被理解为某一事件发生的概率。
  • 参数求解:逻辑回归通常采用极大似然估计来求解模型参数,即找到使观测数据出现概率最大的参数值。在实际应用中,常通过引入对数变换简化计算过程,并利用梯度下降法等优化算法进行求解。

1.2、损失函数

  • 交叉熵损失函数:逻辑回归通常使用交叉熵损失函数来度量模型预测值与真实标签之间的差异。交叉熵在处理概率分布时表现良好,特别适用于逻辑回归这类输出为概率的模型。
  • 损失函数的选择理由:与均方误差损失相比,交叉熵损失函数在处理概率预测上更为合理,尤其是在处理稀疏数据时能提供更好的性能表现。

 二、实例

我这个代码是通过使用逻辑回归来实现影片的二分类问题

2.1、定义sigmoid函数

sigmoid函数的取值范围为[0,1],通过Sigmoid函数,逻辑回归能够将任意实数值的线性组合输出映射到(0,1)区间内,这个区间正好对应于概率值的范围。这种映射使得模型的输出可以被解释为属于某一类的概率,即输出值越接近1,表示样本属于正类的可能性越高;输出值越接近0,表示样本属于负类的可能性越高。我们可以以0.5为分界在以下为负类,以上为正类

公式:\sigma(z) = \frac{1}{1 + e^{-z}}

def sigmoid(z):
    return 1 / (1 + np.exp(-z))

2.2、数据集

我是手动输入数据集,也可以通过读取文本来实现数据输入

def createDataSet():
    group = np.array([[20, 101], [2, 102], [100, 1], [5, 110], [110, 10],
                      [30, 102], [100, 20], [50, 110], [110, 50], [20, 105],
                      [90, 30], [70, 105], [120, 40], [80, 100], [10, 90],
                      [40, 5], [60, 90], [100, 60], [20, 50], [10, 100],
                      [105, 25], [55, 95], [115, 45], [5, 85], [15, 95],
                      [35, 15], [30, 65], [125, 55], [55, 80], [5, 95],
                      [106, 15], [58, 85], [112, 48], [58, 88], [18, 88],
                      [38, 18], [35, 68], [128, 60], [78, 85], [8, 98],
                      [107, 22], [60, 80], [114, 52], [72, 82], [82, 12],
                      [12, 42], [72, 40], [65, 122], [95, 72], [1, 108]])
    labels = ['爱情片', '爱情片', '动作片', '爱情片', '动作片',
              '爱情片', '动作片', '爱情片', '动作片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '动作片',
              '爱情片', '动作片', '爱情片', '动作片', '爱情片']
    return group, labels  # 返回数据集的特征和标签

2.3、梯度上升算法

梯度上升算法,通常用于寻找目标函数的最大值。它是一种迭代优化算法,其核心思想是在每次迭代中更新变量以使目标函数值增大,直到达到最大值点或满足一定的停止条件

梯度上升算法需要注意以下几点:

  1. 选择合适的初始值和学习率,这些参数对算法的性能有很大影响。
  2. 对于大规模数据集,可以考虑使用随机梯度上升算法来提高计算效率。
  3. 需要监控算法的收敛情况,适时调整学习率或停止条件以避免过拟合。

 

函数接收四个参数:特征矩阵X、目标向量y、学习率和迭代次数。函数首先获取特征矩阵的行数和列数,然后随机初始化权重向量。接下来,通过迭代更新权重,计算线性组合、Sigmoid函数值、预测误差、权重的梯度,并根据梯度上升法更新权重。最后返回学习得到的权重向量w。

# 梯度上升优化参数
def optimize(X, y, learning_rate, num_iterations):
    m, n = X.shape  # 获取特征矩阵的行数和列数
    w = np.random.rand(n, 1)  # 随机初始化权重向量
    for i in range(num_iterations):  # 迭代更新权重
        z = np.dot(X, w)  # 计算线性组合
        A = sigmoid(z)  # 计算Sigmoid函数值,即预测值
        dz = A - y  # 计算预测误差
        dw = 1/m * np.dot(X.T, dz)  # 计算权重的梯度
        w = w - learning_rate * dw  # 根据梯度上升法更新权重
    return w  # 返回学习得到的权重向量w

2.4、预测函数

它接受两个参数:XwX是一个二维数组,表示输入数据;w是一个一维数组,表示权重。函数首先计算Xw的点积,然后将结果传递给sigmoid函数。sigmoid函数将输入值映射到0和1之间。最后,函数返回一个与A形状相同的数组,其中大于0.5的元素被转换为1,小于等于0.5的元素被转换为0。

def predict(X, w):
    z = np.dot(X, w)
    A = sigmoid(z)
    return (A > 0.5).astype(int)

2.5、绘画函数

这段代码是用来绘制决策边界的。首先,它使用散点图分别绘制了类别1和类别0的数据点。然后,计算了决策边界的斜率和截距,并使用plt.plot()函数绘制了红色的决策边界线。最后,设置了坐标轴标签、标题和图例,并显示了图形。

# 绘制决策边界
plt.scatter(X[y.flatten() == 1, 1], X[y.flatten() == 1, 2], label='Class 1', marker='o')
plt.scatter(X[y.flatten() == 0, 1], X[y.flatten() == 0, 2], label='Class 0', marker='x')
x_values = [np.min(X[:, 1]), np.max(X[:, 1])]
y_values = - (w[0] + w[1]*x_values) / w[2]  # 直线方程:w0*x0 + w1*x1 + w2*x2 = 0
plt.plot(x_values, y_values, color='r', label='Decision Line')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('Decision Line for Logistic Regression using Gradient Ascent')
plt.legend()
plt.show()

三、代码

import numpy as np
import matplotlib.pyplot as plt

# 定义sigmoid函数
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

# 梯度上升优化参数
def optimize(X, y, learning_rate, num_iterations):
    m, n = X.shape  # 获取特征矩阵的行数和列数
    w = np.random.rand(n, 1)  # 随机初始化权重向量
    for i in range(num_iterations):  # 迭代更新权重
        z = np.dot(X, w)  # 计算线性组合
        A = sigmoid(z)  # 计算Sigmoid函数值,即预测值
        dz = A - y  # 计算预测误差
        dw = 1/m * np.dot(X.T, dz)  # 计算权重的梯度
        w = w - learning_rate * dw  # 根据梯度上升法更新权重
    return w  # 返回学习得到的权重向量w

# 预测函数
def predict(X, w):
    z = np.dot(X, w)
    A = sigmoid(z)
    return (A > 0.5).astype(int)

# 自定义数据集
def createDataSet():
    group = np.array([[20, 101], [2, 102], [100, 1], [5, 110], [110, 10],
                      [30, 102], [100, 20], [50, 110], [110, 50], [20, 105],
                      [90, 30], [70, 105], [120, 40], [80, 100], [10, 90],
                      [40, 5], [60, 90], [100, 60], [20, 50], [10, 100],
                      [105, 25], [55, 95], [115, 45], [5, 85], [15, 95],
                      [35, 15], [30, 65], [125, 55], [55, 80], [5, 95],
                      [106, 15], [58, 85], [112, 48], [58, 88], [18, 88],
                      [38, 18], [35, 68], [128, 60], [78, 85], [8, 98],
                      [107, 22], [60, 80], [114, 52], [72, 82], [82, 12],
                      [12, 42], [72, 40], [65, 122], [95, 72], [1, 108]])
    labels = ['爱情片', '爱情片', '动作片', '爱情片', '动作片',
              '爱情片', '动作片', '爱情片', '动作片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '爱情片',
              '动作片', '爱情片', '动作片', '爱情片', '动作片',
              '爱情片', '动作片', '爱情片', '动作片', '爱情片']
    return group, labels  # 返回数据集的特征和标签

# 获取自定义数据集
X, labels = createDataSet()
y = np.array([1 if label == '爱情片' else 0 for label in labels]).reshape(-1, 1)

# 数据预处理
X = (X - np.mean(X, axis=0)) / np.std(X, axis=0)

# 添加偏置项
X = np.insert(X, 0, 1, axis=1)

# 训练模型
w = optimize(X, y, learning_rate=0.01, num_iterations=1000)

# 进行预测
predictions_subset = predict(X[:5, :], w)
# 显示前五个样本的特征向量,并在每个特征向量后加上其预测结果和实际结果
for i in range(5):
    print("Feature vector:", X[i, 1:], "Predicted result:", predictions_subset[i], "Actual result:", y[i])

# 绘制决策边界
plt.scatter(X[y.flatten() == 1, 1], X[y.flatten() == 1, 2], label='Class 1', marker='o')
plt.scatter(X[y.flatten() == 0, 1], X[y.flatten() == 0, 2], label='Class 0', marker='x')
x_values = [np.min(X[:, 1]), np.max(X[:, 1])]
y_values = - (w[0] + w[1]*x_values) / w[2]  # 直线方程:w0*x0 + w1*x1 + w2*x2 = 0
plt.plot(x_values, y_values, color='r', label='Decision Line')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.title('Decision Line for Logistic Regression using Gradient Ascent')
plt.legend()
plt.show()

运行结果:

这是经过数据预处理过后显示出的电影分类图,中间那条线表示了与测试在线的下方则表示与0是同一类,在上方则与1是同一类

这是预测集的结果

四、总结

优点:

  1. 易于理解和实现
    • 逻辑回归模型基于线性回归,并通过引入Sigmoid函数将线性回归的输出映射到0和1之间,使得结果可以被解释为概率。这种模型结构简单清晰,不仅便于初学者理解,也方便了数据的预处理和模型的后续调整。
    • 由于算法简单,逻辑回归在计算上非常高效。这使得它在处理大规模数据集时依然能够保持较快的训练速度,适合用于快速原型开发和实时预测需求。
  2. 输出具有概率意义
    • 逻辑回归的输出是介于0和1之间的概率值,这表示属于某一类的可能性。这种概率输出对于需要量化风险或置信度的应用场景(如医疗诊断或信用评分)尤为重要。
    • 输出的概率形式还便于进行结果的解释和交流,尤其是在需要向非技术背景的利益相关者解释模型预测时。

缺点:

  1. 高维数据处理能力不足
    • 虽然逻辑回归可以处理多特征数据,但在特征数量非常多时,尤其是特征之间存在复杂的非线性关系时,逻辑回归的性能会受到影响。这是因为其基于线性假设,难以捕捉复杂模式。
    • 在实际应用中,可能需要进行特征选择或降维来提高逻辑回归的效果。
  2. 受多重共线性影响较大
    • 如果数据集中的特征之间存在高度相关性或多重共线性,逻辑回归的性能可能会下降。这是因为模型可能难以区分这些特征对目标变量的具体贡献,导致模型不稳定或难以解释。
  3. 对数据不平衡敏感
    • 当面对不平衡的数据时,即某些类的样本数量远多于其他类,逻辑回归可能无法准确地学习到少数类的决策边界。这通常需要通过采样策略或调整算法来解决。
  4. 准确率存在局限性
    • 尽管逻辑回归在某些任务中表现良好,但在一些复杂问题上,特别是涉及非线性关系和多分类问题的场合,它的准确率可能不如更复杂的模型如随机森林或神经网络。
  • 29
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值