📅  最后修改于: 2023-12-03 15:36:36.375000             🧑  作者: Mango
本文将介绍如何在 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 回归的步骤:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
我们使用一个虚构的鸢尾花数据集来进行演示。该数据集包含了 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
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$ 表示模型参数向量。
我们使用梯度下降算法来训练模型。在每一次迭代中,我们都计算一次损失函数和梯度,并使用梯度更新模型参数。
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
我们使用测试集来评估模型的性能。预测标签的方法是将 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.