大家好,今儿和大家聊一个分类算法模型,逻辑回归~
很常听到的一句话:逻辑回归是一种用于分类问题的机器学习算法,尽管名字中有“回归”,它实际上是用来处理“是或否”、“对或错”这样的二分类问题。
这里给大家一个很简单的解释:
假设你是一位老师,想根据学生的上课表现来预测他是否能通过考试。你的观察包括学生的出勤率、作业完成情况等。你想知道,如果这个学生出勤率高,作业也都做得好,通过考试的概率有多大?
逻辑回归的工作方式是,先收集这些特征(比如出勤率、作业完成情况),然后它会根据这些特征计算出每个学生通过考试的概率。这个概率是一个0到1之间的数,接近1表示很有可能通过,接近0表示不太可能通过。
具体步骤
1. 数据收集:你先拿到一些学生的数据,比如:
小明出勤率90%,作业完成80%,他通过了考试(标签=1) 小红出勤率60%,作业完成50%,她没通过考试(标签=0) 小张出勤率80%,作业完成60%,他通过了考试(标签=1)
2. 拟合模型:逻辑回归根据这些数据建立一个公式,用来预测新学生是否能通过考试。这个公式会根据出勤率、作业完成情况等因素,输出一个介于0到1之间的数。
3. 预测:有了公式后,假设来了一个新学生,小李,他的出勤率是85%,作业完成率是70%。模型会根据公式计算出一个值,比如说0.8,这个0.8代表小李有80%的概率通过考试。通常我们会设置一个阈值,比如0.5,意思是当预测概率大于0.5时,就 认为这个学生能通过考试。
小例子
假设我们有这样的公式:
如果小李的出勤率是85%(0.85),作业完成率是70%(0.70),代入公式:
这个公式经过计算后,可能得出小李通过考试的概率是0.78,说明他有78%的概率能通过考试。
逻辑回归把我们关心的问题转换为概率问题。它根据一些因素(特征)来估计某件事情(如通过考试)的可能性。虽然它名字里有“回归”,但它真正的目的是分类,帮我们区分“会发生”还是“不会发生”的情况。
这个算法的好处是它简单、容易解释,适合用来处理二分类问题,比如:
邮件是垃圾邮件还是正常邮件? 病人是健康还是生病? 学生能通过考试还是不能通过?
逻辑回归的本质就是帮你找到一条“分界线”,把“是”和“否”的情况分开。
要推导逻辑回归的公式,并通过代码实现复杂案例,我们可以一步步来,首先是公式推导。
逻辑回归的公式推导
逻辑回归的核心是将线性回归的结果转化为概率。概率的范围是0到1,而线性回归的结果可能是任意实数,因此我们需要一个函数将线性回归的输出转换为0到1之间的概率值,这个函数就是sigmoid函数。
1. 线性模型:
其中 是偏置项, 是对应特征 的系数。
2. Sigmoid函数:
这个函数将线性模型的输出转化为一个介于0到1之间的值,即概率。
3. 逻辑回归模型:
4. 最大似然估计:
逻辑回归的目标是找到合适的参数 ,使得模型在给定数据集上表现最佳。这是通过最大化似然函数实现的。似然函数表示给定参数下,数据的概率是多少。
对于单个样本 的似然函数为:
对整个数据集,似然函数为:
我们通常最大化的是对数似然函数,这样更容易处理:
通过对这个对数似然函数求导,可以得到各个参数的更新规则,从而逐步优化参数。
案例代码
现在我们将基于上面的推导来构建一个案例。使用虚拟数据集,通过梯度下降来实现逻辑回归,且生成4个及以上的图形进行数据分析。
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
# 生成虚拟数据集
np.random.seed(42)
num_samples = 10000
X1 = np.random.normal(0, 1, num_samples)
X2 = np.random.normal(0, 1, num_samples)
# 假设两个特征之间有一定的相关性
X = np.column_stack((X1, X2))
# 定义真实的权重和偏置
true_weights = np.array([2, -3])
bias = 1.5
# 生成真实的标签 y,使用 sigmoid 函数
Z = np.dot(X, true_weights) + bias
y_true = (1 / (1 + np.exp(-Z)) > 0.5).astype(int)
# 逻辑回归模型(手动实现梯度下降)
def sigmoid(z):
return 1 / (1 + np.exp(-z))
def logistic_regression(X, y, learning_rate=0.01, iterations=10000):
m, n = X.shape
weights = np.zeros(n)
bias = 0
losses = []
for i in range(iterations):
# 计算模型预测
Z = np.dot(X, weights) + bias
y_pred = sigmoid(Z)
# 计算损失(交叉熵损失)
loss = -np.mean(y * np.log(y_pred) + (1 - y) * np.log(1 - y_pred))
losses.append(loss)
# 计算梯度
dw = (1 / m) * np.dot(X.T, (y_pred - y))
db = (1 / m) * np.sum(y_pred - y)
# 更新参数
weights -= learning_rate * dw
bias -= learning_rate * db
return weights, bias, losses
# 训练模型
weights, bias, losses = logistic_regression(X, y_true)
# 生成预测概率
Z_pred = np.dot(X, weights) + bias
y_pred = sigmoid(Z_pred)
# 图形1:交叉熵损失随迭代次数变化
plt.figure(figsize=(10, 6))
plt.plot(losses, color='red', linewidth=2)
plt.title('Loss Curve (Cross-Entropy Loss vs Iterations)', fontsize=16)
plt.xlabel('Iterations', fontsize=14)
plt.ylabel('Loss', fontsize=14)
plt.grid(True)
plt.show()
# 图形2:散点图显示不同类别数据分布
plt.figure(figsize=(10, 6))
plt.scatter(X[:, 0], X[:, 1], c=y_true, cmap='coolwarm', s=50, alpha=0.7, edgecolors='k')
plt.title('Scatter Plot of Data (with True Labels)', fontsize=16)
plt.xlabel('Feature X1', fontsize=14)
plt.ylabel('Feature X2', fontsize=14)
plt.grid(True)
plt.show()
# 图形3:Sigmoid函数图形化显示概率输出
X_values = np.linspace(-6, 6, 100)
plt.figure(figsize=(10, 6))
plt.plot(X_values, sigmoid(X_values), color='blue', linewidth=2)
plt.title('Sigmoid Function', fontsize=16)
plt.xlabel('Input Value (z)', fontsize=14)
plt.ylabel('Probability (sigmoid(z))', fontsize=14)
plt.grid(True)
plt.show()
# 图形4:预测概率与实际标签对比的直方图
plt.figure(figsize=(10, 6))
sns.histplot(y_pred[y_true == 1], color='green', kde=True, label='True Positive', binwidth=0.05)
sns.histplot(y_pred[y_true == 0], color='orange', kde=True, label='True Negative', binwidth=0.05)
plt.title('Histogram of Predicted Probabilities', fontsize=16)
plt.xlabel('Predicted Probability', fontsize=14)
plt.ylabel('Count', fontsize=14)
plt.legend()
plt.grid(True)
plt.show()
1. 数据生成:我们生成了两列随机特征 和 ,通过设定真实的权重 , ,以及偏置 ,用sigmoid函数生成一个二分类的标签集 。
2. 逻辑回归模型:手动实现了梯度下降,计算损失并不断更新参数。这里的损失函数是交叉熵损失,常用于二分类问题。
图1:显示模型训练过程中,损失如何随着迭代次数减少。
图2:展示数据的分布,颜色区分了真实标签(即目标变量 )。
图3:展示Sigmoid函数的形状,直观显示其如何将输入映射到0到1之间的概率。
图4:展示预测的概率值分布,分别绘制真实为1和真实为0的样本的预测概率分布。
整个的步骤,这样可以通过手动的方式实现逻辑回归,训练和可视化结果,避免依赖现成的库。