📜  使用Python从零开始实现 Logistic 回归(1)

📅  最后修改于: 2023-12-03 15:36:36.375000             🧑  作者: Mango

使用Python从零开始实现 Logistic 回归

本文将介绍如何在 Python 中从零开始实现 Logistic 回归。Logistic 回归是一种用于分类问题的算法,它可以根据已有数据建立一个模型,然后用这个模型对新数据进行分类。Logistic 回归最常被用于二分类问题,即将数据分为两类。

算法原理

Logistic 回归的算法原理基于 Sigmoid 函数。Sigmoid 函数是一个 S 形曲线函数,它能够将任何数值映射到一个介于 0 和 1 之间的值。在 Logistic 回归中,我们将 Sigmoid 函数的输出解释为样本属于正类的概率。

Logistic 回归的模型通常用以下公式表示:

$$h_{\theta}(x) = \frac{1}{1 + e^{-\theta^{T}x}}$$

其中,$x$ 表示输入特征向量,$\theta$ 表示模型参数,$h_{\theta}(x)$ 表示模型的预测输出。

模型训练的过程就是寻找一组最优的模型参数 $\theta$,使得模型的预测输出与实际标签之间的误差最小化。最小化误差的一种常见方法是最小二乘法,但是 Logistic 回归中的目标函数不是凸函数,无法使用最小二乘法求解最优解。因此,我们使用了梯度下降算法来进行参数优化。

梯度下降算法的过程就是不断地迭代更新参数,直到误差降到最小。每次迭代中,我们利用训练数据计算误差函数的梯度,然后沿着梯度的反方向更新参数,从而使得误差函数降低。最终,算法会收敛到一个局部最优解,该解通常能够达到很好的分类效果。

实现步骤

以下是使用 Python 从零开始实现 Logistic 回归的步骤:

1. 导入必要的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
2. 载入数据集,并进行预处理

我们使用一个虚构的鸢尾花数据集来进行演示。该数据集包含了 3 种不同品种的鸢尾花,每个样本有 4 个特征。我们将数据集分为训练集和测试集,并进行归一化处理。

# 载入数据集
data = pd.read_csv('iris.csv')
# 将标签列转换为数值列
data['species'] = pd.Categorical(data['species']).codes
# 划分数据集为训练集和测试集
mask = np.random.rand(len(data)) < 0.8
train_data = data[mask]
test_data = data[~mask]
# 归一化处理
train_mean = train_data.mean()
train_std = train_data.std()
train_data = (train_data - train_mean) / train_std
test_data = (test_data - train_mean) / train_std
3. 定义 Sigmoid 函数和损失函数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def loss(X, y, theta):
    h = sigmoid(X.dot(theta))
    J = -(y * np.log(h) + (1 - y) * np.log(1 - h)).mean()
    grad = ((h - y) * X).mean(axis=0)
    return J, grad

其中,$X$ 表示输入数据矩阵,$y$ 表示实际标签向量,$\theta$ 表示模型参数向量。

4. 训练模型

我们使用梯度下降算法来训练模型。在每一次迭代中,我们都计算一次损失函数和梯度,并使用梯度更新模型参数。

def train(X, y, learning_rate, num_epochs):
    theta = np.zeros(X.shape[1])
    losses = []
    for i in range(num_epochs):
        J, grad = loss(X, y, theta)
        theta -= learning_rate * grad
        losses.append(J)
        if i % 100 == 0:
            print(f'Epoch {i}, loss = {J:.6f}')
    return theta, losses
5. 测试模型

我们使用测试集来评估模型的性能。预测标签的方法是将 Sigmoid 函数的输出大于等于 0.5 的样本预测为正类,小于 0.5 的样本预测为负类。

def predict(X, theta):
    h = sigmoid(X.dot(theta))
    y_pred = (h >= 0.5).astype(int)
    return y_pred

theta, losses = train(train_data.iloc[:, :-1].values, train_data.iloc[:, -1].values, 0.1, 1000)
y_pred = predict(test_data.iloc[:, :-1].values, theta)
test_acc = (y_pred == test_data.iloc[:, -1].values).mean()
print(f'Test accuracy = {test_acc:.4f}')
结论

Logistic 回归是一个简单而有效的分类算法。在本文中,我们演示了如何使用 Python 从零开始实现 Logistic 回归,并且使用一个虚构的鸢尾花数据集来测试我们的实现。使用训练集训练的模型在测试集上达到了 96.0% 的准确率,表明我们的实现是正确且有效的。

参考文献

[1] 李航. 统计学习方法[M]. 清华大学出版社, 2012. [2] Ng A. Machine Learning Coursera Class Notes (Stanford)[EB/OL]. (2014-12-21). https://see.stanford.edu/materials/aimlcs229/cs229-notes1.pdf.