逻辑回归算法

一、引言

逻辑回归(Logistic Regression)是一种用于解决二分类问题的统计学习方法。它通过对数据进行建模,预测因变量(通常为二元分类)与自变量之间的关系。虽然名为“回归”,但逻辑回归实际上是一种分类算法,它使用了Sigmoid函数将线性回归的输出值映射到0和1之间,从而表示属于某个类别的概率。

二、逻辑回归原理

2.1 逻辑函数(Sigmoid Function)

逻辑回归的模型是基于线性回归的,但不同于线性回归直接输出预测值,逻辑回归使用Sigmoid函数将线性回归的输出值转化为一个概率值。Sigmoid函数表达式如下:

                                ​​​​​​​        ​​​​​​​        ​​​​​​​        \sigma(z) = \frac{1}{1 + e^{-z}}

其中,z=θTx 是线性回归的预测值,θ 是参数向量,x 是输入特征向量。

通过Sigmoid函数,逻辑回归的输出值被压缩在0到1之间,可以解释为属于正类的概率。当输出值大于0.5时,通常认为该样本属于正类;反之,则认为属于负类。

2.2 损失函数(Loss Function)

逻辑回归的损失函数通常使用交叉熵损失(Cross Entropy Loss),其表达式如下:

L = -\frac{1}{N} \sum_{i=1}^{N} [y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i)]​​​​​​​

其中,m 是样本数量,y(i) 是第 i 个样本的真实标签(0或1),hθ​(x(i)) 是逻辑回归模型对第 i 个样本的预测概率。

2.3 参数优化(Parameter Optimization)

为了找到使损失函数最小的参数 θ,我们可以使用梯度下降法(Gradient Descent)来迭代更新参数。梯度下降法的迭代公式如下:

\theta_{j} := \theta_{j} - \alpha \frac{\partial}{\partial \theta_{j}} J(\theta)
 

其中,α 是学习率,控制参数更新的步长;\frac{\partial}{\partial \theta_{j}}J(\theta)是损失函数对参数 θj​ 的偏导数。

三、逻辑回归实现框架

3.1 数据准备

首先,我们需要准备用于训练的数据集。数据集通常包括特征矩阵 X 和标签向量 y。特征矩阵 X 的每一行代表一个样本,每一列代表一个特征;标签向量 y 的每个元素代表对应样本的真实标签。

# 设置随机种子以获得可重复的结果
np.random.seed(0)

# 生成特征数据X,这里假设有两个特征,样本数为100
num_samples = 100
num_features = 2
X = np.random.rand(num_samples, num_features) * 10  # 乘以10以增加特征值的范围

# 假设一个线性决策边界,例如 w0*x1 + w1*x2 + b = 0,其中 w0=2, w1=-1, b=0
true_w0, true_w1, true_b = 2, -1, 0
Y_probabilities = sigmoid(np.dot(X, np.array([[true_w0], [true_w1]])) + true_b)

# 将概率转换为标签(例如,如果概率大于0.5,则标签为1,否则为0)
Y = (Y_probabilities > 0.5).astype(int)

# 确保Y是列向量
Y = Y.reshape(Y.shape[0], 1)

3.2 初始化参数

在训练模型之前,我们需要初始化参数 θ。通常,我们可以将参数初始化为零向量或小的随机值。

def initialize_with_zeros(dim):
    w = np.zeros((dim, 1))
    b = 0
    return w, b
# 初始化参数
dim = X.shape[1]
w, b = initialize_with_zeros(dim)

3.3 迭代训练

在训练过程中,我们使用梯度下降算法或其他优化算法来迭代更新参数。在每一轮迭代中,我们首先计算当前参数下模型对训练数据的预测概率,然后计算损失函数对参数的偏导数,并使用偏导数来更新参数。迭代过程通常持续到损失函数收敛或达到预设的最大迭代次数。

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

# 前向传播
def forward_propagation(X, w, b):
    z = np.dot(X, w) + b
    A = sigmoid(z)
    return A, z


# 计算损失
def compute_cost(A, Y):
    m = len(Y)
    cost = -1 / m * np.sum(Y * np.log(A) + (1 - Y) * np.log(1 - A))
    return cost


# 反向传播
def backward_propagation(X, Y, A, z):
    m = len(Y)
    dz = A - Y
    dw = (1 / m) * np.dot(X.T, dz)
    db = (1 / m) * np.sum(dz)
    return dw, db


# 更新参数
def update_parameters(w, b, dw, db, learning_rate):
    w = w - learning_rate * dw  
    b = b - learning_rate * db
    return w, b


# 梯度下降法
def gradient_descent(X, Y, w, b, num_iterations, learning_rate):
    costs = []
    for i in range(num_iterations):
        A, z = forward_propagation(X, w, b)
        cost = compute_cost(A, Y)
        dw, db = backward_propagation(X, Y, A, z)
        w, b = update_parameters(w, b, dw, db, learning_rate)
        if i % 100 == 0:
            costs.append(cost)
    return w, b, costs
# 选择学习率和迭代次数
learning_rate = 0.01
num_iterations = 1000

# 梯度下降法
w, b, costs = gradient_descent(X, Y, w, b, num_iterations, learning_rate)

3.4 模型评估

训练完成后,我们可以使用测试数据集来评估模型的性能。常见的评估指标包括准确率、精确率、召回率和F1分数等。

3.5 可视化结果

最后,我们可以使用可视化工具(如matplotlib)来绘制决策边界和数据点,以便直观地了解模型的分类效果。

# 绘制数据点和决策边界
plt.scatter(X[:, 0], X[:, 1], c=Y.flatten(), cmap='viridis')
plt.xlabel('feature1')
plt.ylabel('feature2') 
x_values = np.linspace(0, 5, 100)
y_values = (-w[0] * x_values - b) / w[1]
plt.plot(x_values, y_values, 'k', label='Decision Boundary')
plt.legend()
plt.show()

# 绘制损失函数随迭代次数的变化
plt.plot(costs)
plt.xlabel('Iterations')
plt.ylabel('Cost')
plt.title('Cost over iterations')
plt.show()

四、完整代码与结果

代码:

import numpy as np
import matplotlib.pyplot as plt

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


# 初始化参数
def initialize_with_zeros(dim):
    w = np.zeros((dim, 1))
    b = 0
    return w, b


# 前向传播
def forward_propagation(X, w, b):
    z = np.dot(X, w) + b
    A = sigmoid(z)
    return A, z


# 计算损失
def compute_cost(A, Y):
    m = len(Y)
    cost = -1 / m * np.sum(Y * np.log(A) + (1 - Y) * np.log(1 - A))
    return cost


# 反向传播
def backward_propagation(X, Y, A, z):
    m = len(Y)
    dz = A - Y
    dw = (1 / m) * np.dot(X.T, dz)
    db = (1 / m) * np.sum(dz)
    return dw, db


# 更新参数
def update_parameters(w, b, dw, db, learning_rate):
    w = w - learning_rate * dw  
    b = b - learning_rate * db
    return w, b


# 梯度下降法
def gradient_descent(X, Y, w, b, num_iterations, learning_rate):
    costs = []
    for i in range(num_iterations):
        A, z = forward_propagation(X, w, b)
        cost = compute_cost(A, Y)
        dw, db = backward_propagation(X, Y, A, z)
        w, b = update_parameters(w, b, dw, db, learning_rate)
        if i % 100 == 0:
            costs.append(cost)
    return w, b, costs


# 设置随机种子以获得可重复的结果
np.random.seed(0)

# 生成特征数据X,这里假设有两个特征,样本数为100
num_samples = 100
num_features = 2
X = np.random.rand(num_samples, num_features) * 10  # 乘以10以增加特征值的范围

# 假设一个线性决策边界,例如 w0*x1 + w1*x2 + b = 0,其中 w0=2, w1=-1, b=0
true_w0, true_w1, true_b = 2, -1, 0
Y_probabilities = sigmoid(np.dot(X, np.array([[true_w0], [true_w1]])) + true_b)

# 将概率转换为标签(例如,如果概率大于0.5,则标签为1,否则为0)
Y = (Y_probabilities > 0.5).astype(int)

# 确保Y是列向量
Y = Y.reshape(Y.shape[0], 1)

# 初始化参数
dim = X.shape[1]
w, b = initialize_with_zeros(dim)

# 选择学习率和迭代次数
learning_rate = 0.01
num_iterations = 1000

# 梯度下降法
w, b, costs = gradient_descent(X, Y, w, b, num_iterations, learning_rate)

# 输出训练后的参数
print("w = ", w)
print("b = ", b)


# 绘制数据点和决策边界
plt.scatter(X[:, 0], X[:, 1], c=Y.flatten(), cmap='viridis')
plt.xlabel('feature1')
plt.ylabel('feature2')
x_values = np.linspace(0, 5, 100)
y_values = (-w[0] * x_values - b) / w[1]
plt.plot(x_values, y_values, 'k', label='Decision Boundary')
plt.legend()
plt.show()

# 绘制损失函数随迭代次数的变化
plt.plot(costs)
plt.xlabel('Iterations')
plt.ylabel('Cost')
plt.title('Cost over iterations')
plt.show()

结果展示:

w =  [[ 1.37582861]
 [-0.70120125]]
b =  0.1028612131796778

数据集可视化: 

 

损失函数迭代次数的变化:

五、总结

逻辑回归是一种简单但强大的分类算法,它适用于二分类问题,并且可以通过扩展来处理多分类问题(如使用softmax函数)。在逻辑回归中,我们使用了Sigmoid函数将线性回归的输出转换为概率值,并使用交叉熵损失函数来衡量预测值和真实值之间的差异。通过梯度下降法优化损失函数,我们可以找到使损失最小的参数,从而得到最终的分类模型。

六、分析

逻辑回归和线性回归虽然名字相似,但它们在许多方面存在显著的差异。

不同点

  1. 模型输出
    • 线性回归:预测输出是连续的数值。
    • 逻辑回归:预测输出是二分类或多分类的概率,通常用于分类问题。
  2. 函数形式
    • 线性回归:使用线性函数(如 (y = ax + b))来拟合数据。
    • 逻辑回归:虽然名字中有“回归”,但实际上它使用逻辑函数(如Sigmoid函数)将线性函数的输出转换为概率值。
  3. 损失函数
    • 线性回归:通常使用均方误差(Mean Squared Error, MSE)作为损失函数。
    • 逻辑回归:使用交叉熵(Cross-Entropy)或对数似然损失(Log-Likelihood Loss)作为损失函数。
  4. 假设条件
    • 线性回归:要求因变量与自变量之间存在线性关系,且误差项服从正态分布。
    • 逻辑回归:要求样本数据服从伯努利分布(二分类)或多项分布(多分类)。

优点:

  • 简单易懂:模型简单,易于理解和实现。
  • 计算效率高:计算代价不高,速度快。
  • 解释性强:可以输出每个特征对结果的影响程度(权重)。

缺点:

  • 假设性强:对数据分布有一定的假设条件,如果数据不满足这些条件,可能导致模型效果不佳。
  • 对非线性问题处理不佳:对于非线性问题,逻辑回归可能无法很好地拟合数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值