目录
一、引言
在当今数据驱动的时代,机器学习技术已经渗透到我们生活的方方面面,从在线购物推荐、社交媒体内容过滤,到医疗诊断、金融风险评估,无不体现着机器学习的强大力量。在这些应用场景中,分类问题尤为常见,如判断邮件是否为垃圾邮件、预测用户是否会点击某个广告等。逻辑回归(Logistic Regression)作为一种经典的分类算法,因其简单高效、易于实现和解释性强等特点,在机器学习领域占据了重要地位。
逻辑回归,尽管名字中带有“回归”二字,但实际上它是一种用于解决二分类问题的统计学习方法。它通过计算样本属于某个类别的概率来进行分类,具有明确的概率解释性,使得模型的结果更易于理解和应用。此外,逻辑回归还具有计算速度快、对数据和场景的适应能力较强等优点,因此在很多实际问题中得到了广泛应用。
二、逻辑回归
1. 定义逻辑回归
逻辑回归是一种广义的线性回归分析模型,用于解决二分类问题。它通过建立预测函数(也称为决策函数)来预测因变量(通常为二分类的类别标签)与自变量(特征)之间的关系。逻辑回归的输出是一个介于0和1之间的概率值,表示样本属于某个类别的可能性。
在逻辑回归中,我们使用Sigmoid函数(也称为逻辑函数)将线性回归模型的输出映射到0和1之间,从而得到一个概率值。Sigmoid函数具有连续、可导、单调递增等特性,能够很好地满足逻辑回归的需求。
2. 逻辑回归的假设
逻辑回归基于以下假设:
- 样本数据是线性可分的,即存在一个超平面能够将不同类别的样本分开。
- 因变量是二分类的,即每个样本只属于两个类别中的一个。
- 样本数据满足独立同分布假设,即每个样本都是独立生成的,且服从相同的概率分布。
三、 逻辑回归的数学原理
逻辑回归的数学原理主要涉及到预测函数、损失函数和优化方法三个方面。
- 预测函数:逻辑回归的预测函数通常采用Sigmoid函数,将线性回归模型的输出映射到0和1之间。预测函数的形式为:,其中是模型参数(权重和偏置项),(x)是输入特征向量。图像如下图所示:
- 损失函数:逻辑回归的损失函数通常采用交叉熵损失函数(Cross-Entropy Loss),用于衡量模型预测结果与实际标签之间的差异。损失函数的形式为:,其中(m)是样本数量,(y^{(i)})是第(i)个样本的实际标签,是模型对第(i)个样本的预测概率。
- 优化方法:逻辑回归的优化方法通常采用梯度下降算法(Gradient Descent),通过迭代更新模型参数来最小化损失函数。在每次迭代中,根据损失函数对模型参数的梯度来更新参数值,直到达到收敛条件或达到最大迭代次数。公式:weights = weights - learning_rate * gradient
-
逻辑回归的优化也可以使用梯度上升(Gradient Ascent)方法,尽管在实际应用中,梯度下降(Gradient Descent)更为常见。这是因为逻辑回归的损失函数(通常是交叉熵损失)是一个凸函数,对于凸函数来说,梯度下降可以确保找到全局最优解。然而,从数学原理上讲,梯度上升同样可以用来优化逻辑回归。
梯度上升与梯度下降的主要区别在于它们的搜索方向是相反的。梯度下降沿着损失函数的负梯度方向进行搜索,以找到使损失函数最小的参数值;而梯度上升则沿着损失函数的正梯度方向进行搜索,以找到使损失函数最大的参数值。但是,在逻辑回归中,我们通常希望最小化损失函数,因此我们需要对梯度上升进行一些调整。
具体来说,如果我们使用梯度上升来优化逻辑回归,我们可以将参数的更新公式改为:
weights = weights + learning_rate * gradient
其中,
weights
是模型的权重参数,learning_rate
是学习率,gradient
是损失函数关于权重的梯度。这样,参数就会沿着损失函数的正梯度方向进行更新,但由于我们在前面加了一个负号,所以实际上参数是朝着使损失函数减小的方向移动的。
四、 逻辑回归的优缺点
逻辑回归作为一种经典的分类算法,具有其独特的优点和局限性。
- 优点:
- 速度快:逻辑回归的计算效率较高,能够在较短时间内处理大量数据。
- 易于理解和实现:逻辑回归的模型结构相对简单,易于理解和实现。
- 概率解释性:逻辑回归的输出是一个概率值,能够直接表示样本属于某个类别的可能性。
- 缺点:
- 对非线性关系建模能力有限:逻辑回归主要适用于线性可分的问题,对于非线性关系建模能力有限。
- 对数据分布敏感:逻辑回归对数据分布假设较为敏感,如果数据不满足独立同分布假设,可能会影响模型的性能。
- 容易过拟合:当特征数量较多或特征之间存在冗余时,逻辑回归容易过拟合。为了避免过拟合,通常需要采用正则化等技术进行处理。
五、代码实战:脱单预测
1.数据集准备
前五个属性 1代表高水平,0反之;标签 1 代表交往,0代表不交往
Sample | 颜值 | 身材 | 性格 | 收入 | 学历 | 是否交往 |
1 | 1 | 0 | 1 | 1 | 1 | 1 |
2 | 1 | 1 | 0 | 0 | 0 | 0 |
3 | 1 | 1 | 1 | 1 | 1 | 1 |
4 | 1 | 0 | 1 | 0 | 1 | 0 |
5 | 1 | 1 | 0 | 1 | 0 | 0 |
6 | 0 | 1 | 0 | 1 | 1 | 0 |
7 | 1 | 1 | 0 | 0 | 0 | 0 |
8 | 1 | 0 | 1 | 1 | 1 | 1 |
9 | 0 | 0 | 1 | 1 | 1 | 0 |
10 | 1 | 1 | 1 | 1 | 1 | 1 |
11 | 1 | 0 | 1 | 0 | 0 | 0 |
12 | 0 | 0 | 1 | 1 | 1 | 0 |
13 | 1 | 1 | 1 | 1 | 1 | 1 |
14 | 1 | 0 | 1 | 1 | 1 | 1 |
15 | 1 | 1 | 1 | 1 | 1 | 1 |
2.定义sigmoid函数、损失函数、梯度函数:
# 定义sigmoid函数
def sigmoid(z):
return 1 / (1 + np.exp(-z))
# 定义损失函数(交叉熵损失)
def compute_loss(X, y, weights):
num_samples, num_features = X.shape
linear_output = np.dot(X, weights)
y_pred_prob = sigmoid(linear_output)
loss = -np.sum(y * np.log(y_pred_prob) + (1 - y) * np.log(1 - y_pred_prob)) / num_samples
return loss
# 定义梯度函数
def compute_gradient(X, y, weights):
num_samples, num_features = X.shape
linear_output = np.dot(X, weights)
y_pred_prob = sigmoid(linear_output)
gradient = np.dot(X.T, (y_pred_prob - y)) / num_samples
return gradient
3.训练逻辑回归模型
def train_logistic_regression(X, y, learning_rate=0.01, epochs=1000):
num_samples, num_features = X.shape
# 添加偏置项(如果X中没有的话)
X = np.insert(X, 0, 1, axis=1)
num_features_with_bias = num_features + 1 # 加上偏置项
# 初始化权重,包括偏置项
weights = np.zeros(num_features_with_bias)
for epoch in range(epochs):
gradient = compute_gradient(X, y, weights)
weights -= learning_rate * gradient
# 打印损失(可选)
if epoch % 100 == 0:
loss = compute_loss(X, y, weights)
print(f"Epoch {epoch}, Loss: {loss}")
return weights
结果(包含偏置值):
Weights: [-0.64974562 0.4926435 -0.29477575 0.59364466 -0.09071893 0.66445537]
4.根据训练好的模型进行预测
def predict(X, weights):
linear_output = np.dot(X, weights)
y_pred_prob = sigmoid(linear_output)
# 使用0.5作为阈值,大于0.5预测为1(交往),否则为0(不交往)
y_pred = np.where(y_pred_prob >= 0.5, 1, 0)
return y_pred
# 测试集,
testdata = np.array([[1,1, 1, 0, 1, 1]])
# 预测测试集的结果
y_pred = predict(testdata, weights)
print("Predicted label for testdata:", y_pred[0]) # 输出预测标签
结果:
Predicted label for testdata: 1
所以[1,1,0,1,1]测试集的预测结果为1,即交往。
5.完整代码
import numpy as np
import matplotlib.pyplot as plt
def sigmoid(z):
return 1 / (1 + np.exp(-z))
# 定义sigmoid函数
def sigmoid(z):
return 1 / (1 + np.exp(-z))
# 定义损失函数(交叉熵损失)
def compute_loss(X, y, weights):
num_samples, num_features = X.shape
linear_output = np.dot(X, weights)
y_pred_prob = sigmoid(linear_output)
loss = -np.sum(y * np.log(y_pred_prob) + (1 - y) * np.log(1 - y_pred_prob)) / num_samples
return loss
# 定义梯度函数
def compute_gradient(X, y, weights):
num_samples, num_features = X.shape
linear_output = np.dot(X, weights)
y_pred_prob = sigmoid(linear_output)
gradient = np.dot(X.T, (y_pred_prob - y)) / num_samples
return gradient
# 定义逻辑回归训练函数
def train_logistic_regression(X, y, learning_rate=0.01, epochs=1000):
num_samples, num_features = X.shape
# 添加偏置项
X = np.insert(X, 0, 1, axis=1)
num_features_with_bias = num_features + 1 # 加上偏置项
# 初始化权重,包括偏置项
weights = np.zeros(num_features_with_bias)
for epoch in range(epochs):
gradient = compute_gradient(X, y, weights)
weights -= learning_rate * gradient
# 打印损失(可选)
if epoch % 100 == 0:
loss = compute_loss(X, y, weights)
print(f"Epoch {epoch}, Loss: {loss}")
return weights
# 数据集
dataset = np.array([
[1, 0, 1, 1, 1],
[1, 1, 0, 0, 0],
[1, 1, 1, 1, 1],
[1, 0, 1, 0, 1],
[1, 1, 0, 1, 0],
[0, 1, 0, 1, 1],
[1, 1, 0, 0, 0],
[1, 0, 1, 1, 1],
[0, 0, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 0, 1, 0, 0],
[0, 0, 1, 1, 1],
[1, 1, 1, 0, 1],
[1, 0, 1, 1, 1],
[1, 1, 1, 1, 1]
])
# 标签(转换为0和1)
labels = np.array(
['交往', '不交往', '交往', '交往', '不交往', '不交往', '不交往', '交往', '不交往', '交往', '不交往', '不交往',
'交往', '交往', '交往'])
y = np.where(labels == '交往', 1, 0) # 转换为数值型标签
# 训练逻辑回归模型
weights = train_logistic_regression(dataset, y)
print("Weights:", weights)
# 预测函数
def predict(X, weights):
linear_output = np.dot(X, weights)
y_pred_prob = sigmoid(linear_output)
# 使用0.5作为阈值,大于0.5预测为1(交往),否则为0(不交往)
y_pred = np.where(y_pred_prob >= 0.5, 1, 0)
return y_pred
# 训练逻辑回归模型
weights = train_logistic_regression(dataset, y)
print("Weights:", weights)
# 测试集
testdata = np.array([[1,1, 1, 0, 1, 1]])
# 预测测试集的结果
y_pred = predict(testdata, weights)
print("Predicted label for testdata:", y_pred[0]) # 输出预测标签
六、总结
逻辑回归是一种简单而有效的分类算法,在实际应用中具有广泛的应用。通过构建逻辑回归模型,我们可以对数据进行二分类预测,并应用在医疗诊断、金融风控、推荐系统等领域。逻辑回归的实现可以借助Python等编程语言和机器学习库,快速搭建和部署算法。
希望本文能够帮助您更好地理解逻辑回归算法,并在实际项目中应用相关知识。