机器学习——Logistic回归

目录

一、理论介绍

1、线性模型

2、从线性到逻辑回归

3、最小二乘法

4、逻辑回归的参数估计

5、对数线性回归

二、代码实现

1、准备数据,使用乳腺癌数据集

2、实现Logistic回归模型

3、训练和测试模型

4、可视化结果:

完整代码:

 运行结果:

 三、总结


一、理论介绍
1、线性模型

        线性模型是一种假设输入变量(自变量)和输出变量(因变量)之间存在线性关系的模型。在最简单的形式中,线性模型可以表示为一个等式,其中输出变量( y )是输入变量( x1, x2, ..., xn )的加权和,再加上一个常数项(也称为截距项)( \beta_0 )。数学上,这可以表达为: 

[ y = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + ... + \beta_n x_n + \epsilon ]

        在回归分析中,线性模型用于预测连续的输出变量。例如,在房价预测问题中,我们可能会使用房屋的面积、位置、房龄等作为输入变量来预测房屋的价格。线性回归模型会尝试找到最佳的参数值(( \beta )系数),使得模型预测的价格与实际价格之间的差异最小。 

        线性回归模型通常用于连续值预测问题。但是,当我们处理分类问题时,输出变量是离散的标签值,而不是连续的数值。这时,我们需要引入逻辑回归(Logistic Regression)

2、从线性到逻辑回归

        逻辑回归是一种广泛应用于分类问题的统计方法,尤其是二分类问题。尽管它的名字中含有“回归”二字,但逻辑回归实际上是一种分类模型而不是回归模型。它通过使用逻辑函数将线性回归的输出映射到0和1之间,从而预测一个事件发生的概率。 

        为了解决线性模型在分类问题中的局限性,我们引入了逻辑函数,也称为Sigmoid函数。Sigmoid函数的公式为:

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

其中,( z )是线性模型的输出,即(z = \beta_0 + \beta_1 x_1 + ... + \beta_n x_n )。Sigmoid函数将任意实数值映射到( (0, 1) )区间内,这使得它可以被解释为概率值。

        Sigmoid函数的特点是它在( z=0 )附近变化很快,在( z )远离0时趋于平缓,并且始终保持在0和1之间。这意味着即使线性模型的输出非常大或非常小,经过Sigmoid函数转换后也能保证预测的概率值在合理的范围内。

        总结来说,Sigmoid函数允许我们将线性模型的输出转换为概率值,从而适用于处理二分类问题。这种结合了线性模型和Sigmoid函数的模型就是逻辑回归模型。

3、最小二乘法

        最小二乘法是一种数学优化技术,它通过最小化误差的平方和来寻找数据的最佳函数匹配。在统计学中,这种方法常用于拟合线性回归模型。

        假设我们有一组观测数据点,并想要找到一个线性函数来近似这些数据。最小二乘法的目标是确定线性模型的参数(( \beta )系数),使得所有数据点和线性函数预测值之间的差异(即残差)的平方和最小。数学上,如果我们的数据集由( n )个观测值组成,每个观测值包含一个输入变量( xi )和一个输出变量( yi ),最小二乘法将寻找参数( \beta )以最小化以下目标函数:

[ J(\beta) = \sum_{i=1}^{n} (y_i - (\beta_0 + \beta_1 x_{i1} + ... + \beta_m x_{im}))^2 ]  

其中,( J(\beta)是损失函数,也称为代价函数或目标函数,( m )是输入变量的数量。

4、逻辑回归的参数估计

        虽然最小二乘法在线性回归中非常有效,但它并不适合逻辑回归。这是因为逻辑回归处理的是分类问题,其输出是概率值,而最小二乘法试图直接最小化输出值和目标值之间的差异。由于逻辑回归的输出是通过Sigmoid函数转换的,这会导致模型的误差项不再是正态分布,且残差不满足独立同分布的假设,因此最小二乘法不再是最佳选择。

        在逻辑回归中,通常使用极大似然估计(MLE)来估计模型参数。MLE的目标是找到一组参数,使得给定这组参数时,观测到的样本数据出现的概率最大。对于逻辑回归,我们定义似然函数为观测数据在模型参数下的概率,然后寻找能够最大化这个似然函数的参数。

在逻辑回归中,似然函数可以写成:

[ L(\beta) = \prod_{i=1}^{n} P(y_i | x_i; \beta) ] 

其中,( pi )是第( i )个样本属于正类的概率,( yi )是实际的类别标签(通常编码为1表示正类,0表示负类)。我们通常对似然函数取对数,得到对数似然函数,这样做的好处是将乘积转换为加和,便于计算:

[ \log L(\beta) = \sum_{i=1}^{n} [y_i \log(p_i) + (1 - y_i) \log(1 - p_i)] ] 

        提到极大似然估计就离不开梯度下降。梯度下降是一种用于优化问题的迭代方法,它的核心思想是:从一个初始参数值开始,逐步调整参数以沿着损失函数的负梯度方向(即下降最快的方向)移动,直到找到损失函数的最小值。在逻辑回归的极大似然估计中,我们使用梯度下降来最大化对数似然函数。

5、对数线性回归

        对数几率函数,也称为logit函数,是逻辑回归中使用的一个核心函数,它将概率值( p )映射到实数域。对于事件发生的概率( p ),对数几率是指事件发生概率与不发生概率的比值的自然对数,数学上表示为:

[ \text{logit}(p) = \ln\left(\frac{p}{1-p}\right) ]

其中,( p )是事件发生的概率,( \frac{p}{1-p} )被称为几率(odds),即事件发生与不发生的概率比。当( p )增加时,几率和对数几率都会增加;当( p )为0.5时,几率为1,对数几率为0。

如何从线性回归模型转换为对数线性回归模型?

        在线性回归模型中,我们预测的是一个连续的输出变量( y ),而在对数线性回归模型中,我们关注的是一个二元事件发生的对数几率。为了从线性回归模型转换为对数线性模型,我们做以下变换:

  • 首先,我们定义( y )为事件发生的对数几率,而不是事件本身的发生概率。
  • 然后,我们将线性回归模型的输出通过logit函数转换,即设置( y = \text{logit}(p) )。
  • 接着,我们将线性模型的等式代入上述关系中,得到:

\ln\left(\frac{p}{1-p}\right) = \beta_0 + \beta_1 x_1 + ... + \beta_n x_n

        通过这种方式,我们将原本的线性模型转换为对数线性模型,适用于分类问题,特别是二元分类问题。 

6、决策边界

        逻辑回归通过决策边界来进行分类。决策边界是输入空间中的一个超平面,它将不同类别的数据点分开。在逻辑回归中,决策边界是由所有满足以下条件的点组成的集合:

[ \beta_0 + \beta_1 x_1 + ... + \beta_n x_n = 0 ]

当线性组合的结果大于0时,模型预测正类(通常编码为1);当小于0时,预测负类(通常编码为0)。因此,决策边界实际上是模型输出概率为0.5的地方,即事件发生的几率与不发生的几率相等。

        不同的参数值( \beta )会影响决策边界的位置和形状。例如,在二维空间中,如果我们有两个特征( x_1 )和( x_2 ),那么决策边界可以表示为直线:

[ \beta_0 + \beta_1 x_1 + \beta_2 x_2 = 0 ] 

        通过调整这些参数,我们可以使决策边界更好地拟合训练数据,从而提高模型在分类任务上的性能。

二、代码实现
1、准备数据,使用乳腺癌数据集
# 加载乳腺癌数据集
breast_cancer = datasets.load_breast_cancer()
X = breast_cancer.data[:, :2]  # 为了可视化,只取前两个特征
y = breast_cancer.target

# 数据标准化
scaler = StandardScaler()
X = scaler.fit_transform(X)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
2、实现Logistic回归模型
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

def loss(h, y):
    return (-y * np.log(h) - (1 - y) * np.log(1 - h)).mean()

def gradient_descent(X, h, y):
    return np.dot(X.T, (h - y)) / y.shape[0]

def fit(X, y, num_iterations=10000, lr=0.01):
    X = np.insert(X, 0, 1, axis=1)  # 添加偏置项
    theta = np.zeros(X.shape[1])
    
    for i in range(num_iterations):
        z = np.dot(X, theta)
        h = sigmoid(z)
        grad = gradient_descent(X, h, y)
        theta -= lr * grad
        
        if(i % 1000 == 0):
            z = np.dot(X, theta)
            h = sigmoid(z)
            print(f'loss: {loss(h, y)} \t')
    
    return theta

定义了Logistic回归模型所需的几个关键函数:

  • sigmoid函数是Logistic回归中使用的激活函数,它将输入映射到(0,1)区间,表示概率。
  • loss函数计算了当前模型参数下的交叉熵损失,这是Logistic回归中常用的损失函数。
  • gradient_descent函数根据当前预测和实际标签计算损失函数的梯度,这是参数更新的方向。
  • fit函数初始化参数theta,并迭代地执行梯度下降算法来更新这些参数。每1000次迭代,它会打印出当前的损失,帮助监控训练过程。
3、训练和测试模型
theta = fit(X_train, y_train)
def predict(X, theta):
    X = np.insert(X, 0, 1, axis=1)
    probabilities = sigmoid(np.dot(X, theta))
    return [1 if x >= 0.5 else 0 for x in probabilities]

y_pred = predict(X_test, theta)

# 计算准确率
accuracy = np.mean(y_pred == y_test)
print(f'Accuracy: {accuracy}')
4、可视化结果:

定义了plot_decision_boundary函数,用于绘制数据点和模型的决策边界。它首先创建一个散点图来显示不同类别的数据点,然后使用plt.contourf函数根据模型参数theta绘制决策边界。最后,调用此函数来显示图形。 

完整代码:
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# 1. 准备数据
# 加载乳腺癌数据集
breast_cancer = datasets.load_breast_cancer()
X = breast_cancer.data[:, :2]  # 为了可视化,只取前两个特征
y = breast_cancer.target

# 数据标准化
scaler = StandardScaler()
X = scaler.fit_transform(X)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 2. 实现Logistic回归模型
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

def loss(h, y):
    return (-y * np.log(h) - (1 - y) * np.log(1 - h)).mean()

def gradient_descent(X, h, y):
    return np.dot(X.T, (h - y)) / y.shape[0]

def fit(X, y, num_iterations=10000, lr=0.01):
    X = np.insert(X, 0, 1, axis=1)  # 添加偏置项
    theta = np.zeros(X.shape[1])
    
    for i in range(num_iterations):
        z = np.dot(X, theta)
        h = sigmoid(z)
        grad = gradient_descent(X, h, y)
        theta -= lr * grad
        
        if(i % 1000 == 0):
            z = np.dot(X, theta)
            h = sigmoid(z)
            print(f'loss: {loss(h, y)} \t')
    
    return theta

# 3. 训练模型
theta = fit(X_train, y_train)

# 4. 测试模型
def predict(X, theta):
    X = np.insert(X, 0, 1, axis=1)
    probabilities = sigmoid(np.dot(X, theta))
    return [1 if x >= 0.5 else 0 for x in probabilities]

y_pred = predict(X_test, theta)

# 计算准确率
accuracy = np.mean(y_pred == y_test)
print(f'Accuracy: {accuracy}')

# 5. 可视化结果
def plot_decision_boundary(X, y, theta):
    plt.figure(figsize=(10, 6))
    plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], color='b', label='0')
    plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], color='r', label='1')
    plt.legend()
    
    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100), np.linspace(y_min, y_max, 100))
    Z = predict(np.c_[xx.ravel(), yy.ravel()], theta)
    Z = np.array(Z).reshape(xx.shape)
    plt.contourf(xx, yy, Z, alpha=0.2)
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    plt.title("Decision Boundary")
    plt.xlabel('Feature 1')
    plt.ylabel('Feature 2')
    plt.show()

# 绘制决策边界
plot_decision_boundary(X, y, theta)
 运行结果:

        可以看出随着迭代次数的增加,损失函数值逐渐减小,说明模型在学习过程中不断改进,预测结果越来越接近真实标签,表明了模型通过梯度下降算法成功地减少了预测误差。初始损失值为0.6914,这是在模型参数刚初始化时的损失值。由于此时的权重theta都是0,模型只能进行随机猜测,因此损失较高。

        这个准确率已经较好,但还有可能通过调整模型参数(如学习率、迭代次数)、增加特征数量或使用更复杂的模型来进一步提高准确率。

 三、总结

        Logistic回归模型能够有效地处理二分类问题,并且可以通过梯度下降算法来训练模型参数。在本例中,只使用了乳腺癌数据集的前两个特征来训练模型,这主要是为了可视化方便。在实际应用中,使用更多的特征可能会提供更多信息,有助于提升模型性能。

         总之逻辑回归是一种简单而强大的机器学习算法,可以应用于各种二分类问题,理解其背后的数学原理和手动实现过程对于深入理解算法的工作原理是非常有价值的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值