超全面讲透一个算法模型,多项逻辑回归 ! !

文摘   2024-09-22 20:26   北京  

大家好,我是小白~

今儿是基础算法的第N天,我们来聊多项逻辑回归~

多项逻辑回归(Multinomial Logistic Regression)是一种用于处理多分类问题的统计模型。它能够处理多个类别的情况,而不仅仅是简单的二分类问题。为了让小白同学更好理解,我将尽量用简单的语言解释,并通过例子来说明。

1. 逻辑回归的基本概念

逻辑回归是一种用于分类的模型,特别是用来预测某个事物属于两种可能情况之一的概率。例如,预测一个人是否会生病(是/否),或者一个邮件是否是垃圾邮件(是/否)。

对于二分类问题,我们会有一个输出变量 ( y ),它只有两个可能的值:0 或 1。逻辑回归的目标是找到一种方法,通过一些输入特征(比如年龄、收入等),来预测 ( y ) 是 0 还是 1 的概率。

2. 多项逻辑回归的概念

多项逻辑回归扩展了普通的逻辑回归,用来处理多个类别的分类问题。比如,不是简单地预测某件事情是 0 或 1,而是预测可能的多个结果。

假设我们有三个类别:A、B 和 C。那么多项逻辑回归的目标是通过输入特征,预测一个物体属于 A、B、C 中哪个类别的概率。

3. 举个例子:水果分类

想象一下,你是一名水果摊主,卖苹果、香蕉和橘子(我们有三个类别)。现在,来了一个顾客买了一个水果,你看不到水果,但可以通过几个特征判断这是什么水果,比如:

  • 重量
  • 颜色
  • 大小

你想通过这些特征来预测顾客买的到底是苹果、香蕉还是橘子,这就是一个多分类问题

输入特征

你通过测量知道:

  • 水果的重量是 150 克
  • 水果的颜色是黄色
  • 水果的大小比较大

输出

你希望用这些特征来预测这个水果是苹果、香蕉还是橘子。

4. 逻辑过程

多项逻辑回归会做的是:

  • 它会根据这些输入特征(重量、颜色、大小)计算出这个水果属于每个类别的概率。
    • 这个水果是苹果的概率:20%
    • 这个水果是香蕉的概率:70%
    • 这个水果是橘子的概率:10%
  • 最终,它会选出概率最大的类别(比如香蕉,概率是 70%),作为预测结果。

5. 多项逻辑回归背后的数学

对于每一个类别(比如苹果、香蕉和橘子),多项逻辑回归会计算每个类别的概率。计算公式和普通的二分类逻辑回归类似,不过会有多个公式,每个类别一个。

公式: 假设有三个类别 A、B 和 C,多项逻辑回归会计算:

  • 物品属于 A 类的概率
  • 物品属于 B 类的概率
  • 物品属于 C 类的概率

这些概率会基于一个输入特征的线性组合(比如权重 * 特征),通过softmax函数来标准化为概率。softmax函数能确保所有的类别概率加起来为 1。

总的来说,多项逻辑回归是一种分类模型,可以通过输入一些特征,来预测一个物体属于多个类别中的哪个类别。比如,在水果分类问题中,通过测量水果的特征(重量、颜色等),多项逻辑回归可以预测它是苹果、香蕉还是橘子。

接下来咱们聊聊多项逻辑回归的公式,最后给大家提供一个完整的案例~

公式推导

假设我们有  个类别(如水果:苹果、香蕉、橘子等),多项逻辑回归的目标是预测每个样本属于  个类别中的一个。

输入变量与输出变量

  • 输入:我们有  个样本,每个样本有  个特征,记为 $ \mathbf{x}i = [x{i1}, x_{i2}, ..., x_{ip}]  i = 1, 2, ..., n $。
  • 输出:输出的类别 ,即每个样本属于  个类别之一。

概率计算

我们希望计算样本 $ \mathbfx}_i  k  P(y_i = k \mathbf{x_i) $。多项逻辑回归使用 softmax 函数来计算这个概率。对于  个类别,公式如下:

其中:

  •  是类别  的权重向量,大小为 
  •  是样本  的特征向量。

目标函数

为了优化模型,我们需要定义损失函数。对于多项逻辑回归,通常使用负对数似然损失函数(cross-entropy loss)。公式为:

其中:

  •  是一个指示函数,当  时取值为 1,否则为 0。
  •  是样本  属于类别  的预测概率。

梯度更新

为了优化这个损失函数,我们可以使用梯度下降。具体的梯度更新规则是:

通过不断更新权重 ,我们最终能找到最优的分类模型。


完整案例

接下来,我们从头实现多项逻辑回归,并生成一些虚拟数据进行分析和可视化。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

# 生成虚拟数据集
np.random.seed(42)

# 样本数
n_samples = 3000
# 特征数
n_features = 2
# 类别数
n_classes = 3

# 生成随机特征和类别
X = np.random.randn(n_samples, n_features)

# 定义真实的权重和偏置,生成目标类别
true_w = np.array([[2-1], [-12], [11]])
true_b = np.array([0.5-0.50])
linear_output = X @ true_w.T + true_b
y = np.argmax(linear_output, axis=1)

# 2. 定义 softmax 函数
def softmax(logits):
    exp_logits = np.exp(logits - np.max(logits, axis=1, keepdims=True))
    return exp_logits / np.sum(exp_logits, axis=1, keepdims=True)

# 3. 初始化模型参数
W = np.random.randn(n_classes, n_features)
b = np.zeros(n_classes)

# 4. 学习率和迭代次数
learning_rate = 0.01
n_iterations = 5000

# 5. 梯度下降训练模型
for iteration in range(n_iterations):
    # 线性部分
    logits = X @ W.T + b
    # 计算 softmax 概率
    probabilities = softmax(logits)
    
    # 损失函数(交叉熵损失)
    loss = -np.mean(np.log(probabilities[np.arange(n_samples), y]))
    
    # 计算梯度
    grad_logits = probabilities
    grad_logits[np.arange(n_samples), y] -= 1
    grad_W = grad_logits.T @ X / n_samples
    grad_b = np.mean(grad_logits, axis=0)
    
    # 更新参数
    W -= learning_rate * grad_W
    b -= learning_rate * grad_b
    
    # 每 1000 次迭代打印损失
    if iteration % 1000 == 0:
        print(f"Iteration {iteration}, Loss: {loss}")

# 6. 可视化分类结果
# 定义颜色映射
cmap = ListedColormap(['#FF6347''#4682B4''#32CD32'])

# 创建一个网格用于分类边界绘制
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.arange(x_min, x_max, 0.01),
                     np.arange(y_min, y_max, 0.01))

# 预测网格点的分类
grid = np.c_[xx.ravel(), yy.ravel()]
logits_grid = grid @ W.T + b
predicted_grid = np.argmax(logits_grid, axis=1)
predicted_grid = predicted_grid.reshape(xx.shape)

# 绘制分类边界
plt.figure(figsize=(108))
plt.contourf(xx, yy, predicted_grid, alpha=0.5, cmap=cmap)

# 绘制原始数据点
scatter = plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', cmap=cmap)

# 添加图例
legend = plt.legend(*scatter.legend_elements(), title="Classes")
plt.title("Multinomial Logistic Regression Decision Boundaries")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.show()

# 7. 绘制其他数据分析图
# 图1: 数据分布散点图
plt.figure(figsize=(86))
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap, edgecolor='k')
plt.title("Data Distribution")
plt.xlabel("Feature 1")
plt.ylabel("Feature 2")
plt.show()

# 图2: 损失函数随迭代次数的变化
plt.figure(figsize=(86))
iterations = np.arange(0, n_iterations, 1000)
loss_values = [iteration for iteration in range(0, n_iterations, 1000)]
plt.plot(iterations, loss_values, color='red', marker='o')
plt.title("Loss Function over Iterations")
plt.xlabel("Iterations")
plt.ylabel("Loss")
plt.grid(True)
plt.show()

# 图3: 各类别概率分布直方图
plt.figure(figsize=(86))
probabilities_sample = softmax(X @ W.T + b)
for i in range(n_classes):
    plt.hist(probabilities_sample[:, i], bins=30, alpha=0.6, label=f"Class {i+1}")
plt.title("Probability Distribution per Class")
plt.xlabel("Probability")
plt.ylabel("Frequency")
plt.legend()
plt.show()

# 图4: 权重变化情况
plt.figure(figsize=(86))
for i in range(n_classes):
    plt.bar(np.arange(n_features), W[i], alpha=0.6, label=f"Class {i+1}")
plt.title("Learned Weights per Class")
plt.xlabel("Features")
plt.ylabel("Weights")
plt.legend()
plt.show()

1. 数据生成:我们生成了 300 个样本,每个样本有两个特征,并为每个样本分配了一个类别(苹果、香蕉、橘子)。

2. 模型训练:我们使用梯度下降算法优化权重  和偏置 

分类决策边界

数据分布

损失函数随迭代次数的变化:

各类别概率分布:

学习到的权重

通过手动实现的多项逻辑回归,我们能够准确预测数据的类别,并通过可视化图表来展示模型的性能。

机器学习和人工智能AI
让我们一起期待 AI 带给我们的每一场变革!推送最新行业内最新最前沿人工智能技术!
 最新文章