全文共13000余字,预计阅读时间约30~60分钟 | 满满干货,建议收藏!
一、前言
逻辑回归(Logistic Regression)是一种常用的分类方法,在机器学习和统计学中被广泛使用。尽管名字中包含“回归”,但实际上它是一种分类方法,主要用于二分类问题,同时也推广到了解决多分类问题。它通过拟合一个逻辑函数(或称为Sigmoid函数),将自变量和因变量之间的线性关系转换为概率。
逻辑回归模型的输出是一个概率值,通常,我们会设定一个阈值,当模型输出的概率大于这个阈值时,我们将样本判定为正类,否则判定为负类。
二、逻辑回归的理论基础
逻辑回归是一种统计建模方法,是广义线性模型(Generalized Linear Models,GLM)的一种特殊形式,它使用对数几率函数(logit function)作为链接函数,将特征和目标变量之间的关系建模为概率。该模型不仅能够处理二分类问题,还能很好地处理多分类问题。
在求解逻辑回归模型参数时,一般采用极大似然估计(Maximum Likelihood Estimate)方法,这个方法通过最大化似然函数(也就是观测到的数据的概率)来估计模型参数。除了极大似然估计,也可以使用KL散度来求解模型参数,这两种方法都是在寻找最佳的模型参数,使得模型对训练数据的预测尽可能接近实际观察到的结果,我们在后面会分别介绍这两种方法。
逻辑回归的这一建模思路不仅使模型在统计上具有较好的解释性,同时也让模型具有良好的预测能力,使其在许多实际应用中都得到了广泛的使用。
2.1 广义线性模型
2.1.1 线性回归
我们先从线性回归开始回顾。如果你还不了解线性回归,建议先看一下这篇文章:
线性回归是最基本的预测模型之一。它假设目标变量(或响应变量)和输入特征(或预测变量)之间存在线性关系:
y = w 0 + w 1 x 1 + w 2 x 2 + . . . + w n x n + b y = w_0 + w_1x_1 + w_2x_2 + ... + w_nx_n + b y=w0+w1x1+w2x2+...+wnxn+b
或者等价的向量表示:
y = w T ⋅ x + b y = w^T \cdot x + b y=wT⋅x+b
这里, w 1 , w 2 , . . . , w n w_1, w_2, ..., w_n w1,w2,...,wn 是模型参数, b b b 是偏置项。
对于向量表示来说, w T w^T wT表示权重向量的转置, x x x是特征向量。 w T ⋅ x w^T·x wT⋅x表示的是权重向量和特征向量的点积,其结果就是每个特征和对应权重的乘积之和,和第一种写法一样。这种写法更为简洁,尤其在特征数量很多的情况下。
线性回归的目标是找到最佳的 w
和 b
,使得预测的 y
尽可能接近真实的 y
。
然而,线性回归的一个主要限制是它假设目标变量和输入特征之间的关系是线性的。
这里的“线性”,是相对于模型参数 w
而言的,即使y
和x
的关系在数学形式上为非线性(例如多项式,指数,对数等),只要这种关系可以写成参数w
的线性组合形式,我们仍然可以使用线性回归模型。但是,当w
和x
之间的关系是非线性的,我们就需要更灵活的模型来处理这种情况。
此外,线性回归假设模型的误差项服从正态分布,而在现实中,目标变量可能不遵循这个假设,或者目标变量可能不是连续的(例如分类问题)。为了处理这些情况,就需要引入更为广泛的模型框架 —— 广义线性模型(GLM)。
广义线性模型不仅可以处理目标变量和输入特征之间非线性的关系,还可以处理目标变量不符合正态分布的情况。
2.1.2 正态分布与指数族分布
正态分布:也称为高斯分布,是一种在数学、物理和工程等领域都非常重要的概率分布。正态分布的概率密度函数是一个钟形曲线,其形状由两个参数决定,即平均值(或期望)μ和方差σ²。在正态分布的曲线下,观测值接近平均值的概率最高。
指数族分布:指数族分布是一大类概率分布,它包括许多常见的分布,如正态分布、二项分布、泊松分布、伽马分布等。这些分布被称为指数族,是因为它们的概率密度函数(或概率质量函数,对于离散分布)可以写成一个特定形式的指数函数。指数族分布在统计学中有许多重要的性质,使得它们在建模和推断中非常有用。
我们先使用numpy和matplotlib库来生成和展示这两种分布的曲线:
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
# 正态分布
mu, sigma = 0, 1 # mean and standard deviation
s = np.random.normal(mu, sigma, 1000)
count, bins, ignored = plt.hist(s, 30, density=True)
plt.plot(bins, 1/(sigma * np.sqrt(2 * np.pi)) *
np.exp( - (bins - mu)**2 / (2 * sigma**2) ), linewidth=2, color='r')
plt.title('Normal Distribution')
plt.show()
# 指数分布
lam = 1.0 # rate lambda
s = np.random.exponential(lam, 1000)
count, bins, ignored = plt.hist(s, 30, density=True)
plt.plot(bins, lam*np.exp(-lam*bins), linewidth=2, color='r')
plt.title('Exponential Distribution')
plt.show()
这个代码首先生成正态分布和指数分布的随机样本,然后创建了一个直方图,并在直方图上方绘制了相应的理论密度函数。红线是理论的概率密度函数。
在经典的线性回归模型中,我们假设误差项(也就是实际观测值与由模型预测的值之间的差)遵循正态分布。这个假设有助于我们进行参数估计(如最小二乘法),并进行各种统计检验和构建置信区间。正态分布假设使得线性回归模型的解析解可以容易地通过闭式公式得到,且在某些情况下,这个解是最优的。
逻辑回归是广义线性模型(GLM)的一种,GLM的框架允许我们对目标变量的分布做出更一般的假设。在逻辑回归中,我们假设响应变量遵循二项分布(这是指数族分布的一种),并且我们使用了对数几率链接函数,这使得我们可以在[0, 1]区间内建模概率。这种方式使得逻辑回归可以用于分类任务。
2.1.3 广义线性模型定义
广义线性模型(GLM)是线性回归的一种扩展,它扩展了常规线性回归模型,以处理目标变量不符合正态分布的情况,提供了更多的灵活性。
GLM的核心思想是,允许目标变量服从指数族分布,而不仅仅是正态分布,同时通过一个链接函数将响应变量和预测变量连接起来,而不是直接的线性关系。
在GLM中,我们有:
g ( y ) = w 1 x 1 + w 2 x 2 + . . . + w n x n + b g(y) = w_1x_1 + w_2x_2 + ... + w_nx_n + b g(y)=w1x1+w2x2+...+wnxn+b
等价于向量形式:
g ( y ) = w T ⋅ x + b g(y) = w^T \cdot x + b g(y)=wT⋅x+b
这里, g ( ) g() g()是链接函数, w 1 , w 2 , . . . , w n w_1, w_2, ..., w_n w1,w2,...,wn是模型参数, b b b是偏置项。
通过选择不同的分布和链接函数,GLM可以表示很多不同的统计模型。例如,当我们选择二项分布和对数几率链接函数时,我们就得到了逻辑回归模型;当我们选择泊松分布和对数链接函数时,我们就得到了泊松回归模型。这就引出了我们的主题:逻辑回归。
2.2 从对数几率理解逻辑回归
2.2.1 对数几率过程
逻辑回归的基本原理和推导过程我们先从对数几率(log-odds)或 logit 函数的角度来理解,这也是 “Logistic Regression” 名称的来源。那我们就需要先了解下面的这些过程。
对于二分类问题,如果某个事件发生的概率为 p p p,那么该事件不发生的概率为 1 − p 1-p 1−p。该事件的几率定义为发生概率与不发生概率的比值,即
o d d s ( p ) = p ( 1 − p ) odds(p) = \frac{p}{(1-p)} odds(p)=(1−p)p
取这个几率的对数,我们得到的就是对数几率(log-odds),也就是logit函数。对数几率的范围是全实数域,从负无穷到正无穷,这是其主要优点。
当我们选择二项分布和对数几率链接函数时,我们就得到了逻辑回归,写为以下的对数几率形式:
对数几率(log-odds)中的"log"通常指的是自然对数(即以e为底的对数,也就是"ln")。在数学和统计学中,当我们只说"log"时,通常默认是指自然对数。所以,在许多文献和教材中,对数几率函数通常被写作ln[p/(1-p)]。
ln ( p 1 − p ) = w T ⋅ x + b \ln \left(\frac{p}{1-p}\right) = w^T \cdot x + b ln(1−pp)=wT⋅x+b
即我们的线性预测器等于样本的对数几率。对上面的等式进行变换,我们可以解出 p p p,也就是样本属于正类的概率:
p = e w T ⋅ x + b 1 + e w T ⋅ x + b p = \frac{e^{w^T \cdot x + b}}{1+e^{w^T \cdot x + b}} p=1+ewT⋅x+bewT⋅x+b
这就是逻辑回归的模型形式,它预测的是样本属于正类的概率。我们可以看到,虽然最初建立的是线性预测器,但是经过逻辑函数的映射,我们得到的预测值是在0到1之间的概率,通过对数几率,逻辑回归模型能够将线性回归模型的结果转化为一个预测类别的概率,这使得逻辑回归在处理分类问题上非常实用。
2.2.2 逻辑回归标准形式的推导
首先,我们从对数几率公式开始:
ln ( p 1 − p ) = w T ⋅ x + b \ln \left(\frac{p}{1-p}\right) = w^T \cdot x + b ln(1−pp)=wT⋅x+b
我们设 w T ⋅ x + b = x w^T \cdot x + b = x wT⋅x+b=x,于是我们有:
ln ( p 1 − p ) = x \ln \left(\frac{p}{1-p}\right) = x ln(1−pp)=x
然后对等式两边同时用 e e e 指数化,我们有:
p 1 − p = e x \frac{p}{1-p} = e^x 1−pp=ex
我们可以变形得到:
p = e x ( 1 − p ) p = e^x(1-p) p=ex(1−p)
然后我们将等式左边的所有 p p p 提取出来:
p ( 1 + e x ) = e x p (1 + e^x) = e^x p(1+ex)=ex
最后,我们解出 p p p:
p = e x 1 + e x p = \frac{e^x}{1 + e^x} p=1+exex
最后,我们把 zx替换回 w T ⋅ x + b w^T \cdot x + b wT⋅x+b,即得:
p = 1 1 + e − ( w T ⋅ x + b ) p = \frac{1}{1 + e^{-(w^T \cdot x + b)}} p=1+e−(wT⋅x+b)1
即:
y = 1 1 + e − ( w T ⋅ x + b ) y = \frac{1}{1 + e^{-(w^T \cdot x + b)}} y=1+e−(wT⋅x+b)1
这个等式就是逻辑回归的标准形式,其中 y y y表示样本属于正类的概率。
三. 逻辑函数(Sigmoid 函数)
3.1 逻辑回归标准形式与Sigmoid函数的关系
逻辑回归的标准形式实际上是sigmoid函数的一个特定形式。sigmoid函数是一种在生物学、人工神经网络和机器学习中广泛使用的S形函数,其公式为:
f ( x ) = 1 1 + e − x f(x) = \frac{1}{1+e^{-x}} f(x)=1+e−x1
在逻辑回归中,我们将线性预测器 w T ⋅ x + b w^T \cdot x + b wT⋅x+b 的结果通过sigmoid函数进行转换,得到的输出是一个介于0和1之间的概率值。这个值可以被解释为样本属于正类的概率。
所以,逻辑回归的标准形式实际上就是将线性预测器的结果输入到sigmoid函数中,并输出一个概率值。这就是逻辑回归与sigmoid函数的关系。
3.2 逻辑函数的一阶导数推导
我们首先知道,sigmoid函数的定义为:
f ( x ) = 1 1 + e − x f(x) = \frac{1}{1+e^{-x}} f(x)=1+e−x1
我们对其进行微分,首先考虑到它的形式可以写为:
f ( x ) = ( 1 + e − x ) − 1 f(x) = (1+e^{-x})^{-1} f(x)=(1+e−x)−1
这样就变成了一个更标准的链式法则的形式。接下来我们将这个函数看作是两个函数的复合,即
g ( x ) = 1 + e − x g(x) = 1+e^{-x} g(x)=1+e−x
f ( g ) = g − 1 f(g) = g^{-1} f(g)=g−1
根据链式法则,我们有
f ′ ( x ) = f ′ ( g ( x ) ) ⋅ g ′ ( x ) f'(x) = f'(g(x)) \cdot g'(x) f′(x)=f′(g(x))⋅g′(x)
对于上面的两个函数,它们的导数分别为
g ′ ( x ) = − e − x g'(x) = -e^{-x} g′(x)=−e−x
f ′ ( g ) = − g − 2 = − ( 1 + e − x ) − 2 f'(g) = -g^{-2} = - (1+e^{-x})^{-2} f′(g)=−g−2=−(1+e−x)−2
所以,按照链式法则,我们可以得到:
f ′ ( x ) = f ′ ( g ( x ) ) ⋅ g ′ ( x ) = − ( 1 + e − x ) − 2 ⋅ − e − x = e − x ( 1 + e − x ) 2 f'(x) = f'(g(x)) \cdot g'(x) = - (1+e^{-x})^{-2} \cdot -e^{-x} = \frac{e^{-x}}{(1+e^{-x})^{2}} f′(x)=f′(g(x))⋅g′(x)=−(1+e−x)−2⋅−e−x=(1+e−x)2e−x
接下来,我们将其化简,为了化简,我们首先将上下都乘以 e x e^{x} ex,这样得到
f ′ ( x ) = 1 ( e x + 1 ) 2 f'(x) = \frac{1}{(e^{x}+1)^{2}} f′(x)=(ex+1)21
然后,我们将其进一步简化,我们知道:
f ( x ) = e x e x + 1 f(x) = \frac{e^{x}}{e^{x}+1} f(x)=ex+1ex
这意味着,我们可以将上面的公式的分子替换为 f ( x ) f(x) f(x),于是得到:
f ′ ( x ) = f ( x ) ⋅ 1 e x + 1 f'(x) = f(x) \cdot \frac{1}{e^{x} + 1} f′(x)=f(x)⋅ex+11
然后我们注意到 1 e x + 1 \frac{1}{e^{x} + 1} ex+11 就是 1 − f ( x ) 1 - f(x) 1−f(x),于是,我们就得到:
f ′ ( x ) = f ( x ) ⋅ ( 1 − f ( x ) ) f'(x) = f(x) \cdot (1 - f(x)) f′(x)=f(x)⋅(1−f(x))
这就是sigmoid函数的一阶导数。
3.3 逻辑函数的图像
我们生成一些数据并使用Matplotlib库绘制Sigmoid函数及其导数的图像。然后,我将解释该图像的主要特性。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 定义sigmoid函数和其一阶导数
def sigmoid(x):
return 1 / (1 + np.exp(x))
def sigmoid_derivative(x):
return sigmoid(x) * (1 - sigmoid(x))
# 生成数据
x = np.linspace(-10, 10, 100)
y_sigmoid = sigmoid(x)
y_derivative = sigmoid_derivative(x)
# 生成数据框
data = pd.DataFrame({
'x': x,
'sigmoid': y_sigmoid,
'derivative': y_derivative
})
# 绘制sigmoid函数和其导数的图像
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.plot(data['x'], data['sigmoid'], label='sigmoid')
plt.title('Sigmoid function')
plt.xlabel('x')
plt.ylabel('sigmoid(x)')
plt.grid(True)
plt.subplot(1, 2, 2)
plt.plot(data['x'], data['derivative'], label='derivative', color='red')
plt.title('Derivative of the sigmoid function')
plt.xlabel('x')
plt.ylabel('sigmoid\'(x)')
plt.grid(True)
plt.tight_layout()
plt.show()
从图中,我们可以观察到以下特性:
- Sigmoid函数:这个函数能够将输入的任何实值映射到(0, 1)区间内。这一性质使得sigmoid函数在分类问题中非常有用,因为我们可以将其输出解释为属于某个类别的概率。
- Sigmoid函数的导数:这个函数在z=0处取得最大值0.25,而当z远离0时,导数值逐渐趋近于0。这说明,当输入值远离0时,sigmoid函数变化越来越慢。这就是所谓的“梯度饱和”问题
- 导数与原函数的关系:我们可以看到,sigmoid函数的导数可以表示为原函数的形式:sigmoid’(x) = sigmoid(x) * (1 - sigmoid(x))。这一性质在计算梯度时非常有用,因为我们已经计算出了sigmoid(x),所以可以直接复用,而不需要再计算一次exp(-x)。
3.4 逻辑函数的性质
根据上一节的描述,我们可以得到逻辑函数的一些重要性质:
-
取值范围:逻辑函数的输出始终在0到1之间。这使得逻辑函数的输出可以被解释为概率,非常适合于处理分类问题。
-
单调性:逻辑函数是单调递增的。也就是说,
x
的值越大,f(x)
的值越大;x
的值越小,f(x)
的值越小。 -
形状:逻辑函数的形状类似于 “S”。在
x
的值非常大或非常小的时候,f(x)
的值分别趋近于1和0。在x=0
的时候,f(x)=0.5
。 -
导数:逻辑函数的导数可以用函数自身表示,即:
f'(x) = f(x) * (1 - f(x))
。这个性质使得逻辑回归的参数更新(如梯度下降法)在计算上非常便利。
这些性质使得逻辑函数非常适合于逻辑回归模型。在逻辑回归模型中,我们假设特征和对数几率(log-odds)之间存在线性关系,然后通过逻辑函数将对数几率转换回概率。这样,我们就可以得到一个输出范围在0到1之间,可以被解释为概率的预测模型,非常适合于处理分类问题。
3.5 线性回归与逻辑回归可视化对比
我们创建一些模拟数据并使用线性回归和逻辑回归对其进行拟合。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression, LogisticRegression
# 创建模拟数据
np.random.seed(0)
n = 100 # 数据点数量
x = np.linspace(0, 10, n)
y = np.where(x + np.random.normal(0, 1, n) > 5, 1, 0) # 添加一些噪声
# 转换为 DataFrame
data = pd.DataFrame({'x': x, 'y': y})
# 线性回归
lr = LinearRegression()
lr.fit(data[['x']], data['y'])
# 逻辑回归
logr = LogisticRegression(solver='lbfgs')
logr.fit(data[['x']], data['y'])
# 创建图表
plt.figure(figsize=(10, 6))
# 绘制原始数据
plt.scatter(data['x'], data['y'], alpha=0.5, label='Data')
# 绘制线性回归的预测结果
plt.plot(data['x'], lr.predict(data[['x']]), label='Linear Regression')
# 绘制逻辑回归的预测结果
plt.plot(data['x'], logr.predict_proba(data[['x']])[:,1], label='Logistic Regression')
# 添加图例和标题
plt.legend()
plt.title('Linear Regression vs Logistic Regression')
# 显示图表
plt.show()
这个数据集包含一个连续的特征 x
和一个二元的目标变量 y
。我们为 x
添加了一些正态分布的噪声,然后用一个阈值(在这个例子中是5)来决定 y
的值。因此,我们的目标是尝试预测给定 x
的情况下 y
的值。
在这个图形中,横坐标代表特征 x
,纵坐标代表目标变量 y
。我们可以看到目标变量 y
只有两个值:0 或 1。这是一个典型的二元分类问题。
散点代表我们的原始数据。而两条线则是我们利用线性回归和逻辑回归得到的模型的预测结果。
线性回归的预测结果是一条直线,预测值可以在负无穷到正无穷的范围内取值。这在预测连续变量,如房价、销售额等问题时非常合适。然而,对于分类问题(目标变量只能取有限个离散值的问题),线性回归可能会预测出一些不合理的结果。例如,在这个图形中,线性回归的预测值在一些地方小于0或大于1,这对于我们的目标变量来说是不可能的。
逻辑回归的预测结果是一条形状类似于"S"的曲线,预测值始终在0到1之间。这个值可以被解释为属于正类(y=1
)的概率。在特征 x
较小的时候,预测的概率接近于0,而在特征 x
较大的时候,预测的概率接近于1。这符合我们对分类问题的预期,因此逻辑回归更适合于处理这类问题。
虽然线性回归和逻辑回归都可以用于预测,但是它们各自适合于处理不同类型的问题:线性回归适合于预测连续变量,而逻辑回归适合于预测分类变量。
四、模拟实现逻辑回归计算过程
我们使用以下代码,创建一组数据集:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# 设置随机数种子以保证结果可复现
np.random.seed(109)
# 生成第一类点(比如标签为0)
num_samples = 5
x0 = np.random.normal(2, 1, (num_samples, 2)) # 平均值为2,标准差为1的正态分布
y0 = np.zeros(num_samples) # 标签为0
# 生成第二类点(比如标签为1)
x1 = np.random.normal(4, 1, (num_samples, 2)) # 平均值为4,标准差为1的正态分布
y1 = np.ones(num_samples) # 标签为1
# 合并两类点
X = np.concatenate((x0, x1))
Y = np.concatenate((y0, y1))
# 创建 DataFrame
df = pd.DataFrame(np.concatenate((X, Y.reshape(-1, 1)), axis=1), columns=['x1', 'x2', 'y'])
# 打印 DataFrame
print(df)
# 绘制图像
plt.figure(figsize=(4, 2))
plt.scatter(X[:, 0], X[:, 1], c=Y)
plt.xlabel('x1')
plt.ylabel('x2')
plt.show()
这段代码的主要目标是创建并可视化一个二维的二分类数据集。
首先,通过正态分布生成了两类点,并分别标记为 0 和 1。接着,将这两类点以及对应的标签合并成完整的数据集,并存储在一个 pandas DataFrame 中。最后,通过 matplotlib 生成一个散点图,可视化了这两类点的分布,其中点的颜色对应其标签。我们来看一下输出和散点图
使用以下逻辑回归模型公式来预测输出值 y ^ \hat{y} y^:
y ^ = 1 1 + e − ( w 0 + w 1 x 1 + w 2 x 2 ) \hat y = \frac{1}{1 + e^{-(w_0 + w_1x_1 + w_2x_2)}} y^=1+e−(w0+w1x1+w2x2)1
其中, y ^ \hat{y} y^ 是我们模型预测的概率输出,即y的概率。而 w 0 , w 1 , w 2 w_0, w_1, w_2 w0,w1,w2 是我们模型的参数,需要通过训练数据来学习。为了找到最佳的模型参数,我们通常使用梯度下降算法来最小化逻辑回归的损失函数(如交叉熵损失),这两方面的内容我会在下一篇中讲到,此处我先给出这三个参数值: w 0 = − 5.91 w_0 = -5.91 w0=−5.91, w 1 = 1.43 w_1 = 1.43 w1=1.43, w 2 = 0.46 w_2 = 0.46 w2=0.46
这意味着模型的形式为:
y ^ = 1 1 + e − ( − 5.91 + 1.43 x 1 + 0.46 x 2 ) \hat y = \frac{1}{1 + e^{-(-5.91 + 1.43x_1 + 0.46x_2)}} y^=1+e−(−5.91+1.43x1+0.46x2)1
我们使用代码进行计算:
w0 = -5.91
w1 = 1.17
w2 = 0.46
# 计算z值
z = w0 + w1 * df["x1"] + w2 * df["x2"]
# 将z值代入sigmoid函数得到预测概率
y_hat = 1 / (1 + np.exp(-z))
# 打印出每个样本的预测概率
for i in range(len(y_hat)):
print(f"样本{i+1}的预测概率是:{y_hat[i]:.4f}")
计算概率输出如下:
所以我们更新一下目前的数据情况:
样本 | x1 | x2 | y | 预测概率 |
---|---|---|---|---|
1 | 1.812265 | 4.440637 | 0.0 | 0.1484 |
2 | 1.059092 | 2.613912 | 0.0 | 0.0302 |
3 | 2.735627 | 2.972918 | 0.0 | 0.2072 |
4 | 2.259195 | 1.925925 | 0.0 | 0.0846 |
5 | 1.822312 | 1.161256 | 0.0 | 0.0376 |
6 | 3.843713 | 3.658238 | 1.0 | 0.5671 |
7 | 4.818730 | 3.907386 | 1.0 | 0.8213 |
8 | 4.508081 | 2.245778 | 1.0 | 0.5981 |
9 | 3.635182 | 3.969081 | 1.0 | 0.5421 |
10 | 3.873856 | 4.299181 | 1.0 | 0.6457 |
逻辑回归的输出是(0,1)之间的连续型数值,也就是上面表格中的预测概率这一列,我们需要确定一个"阈值",将其转化为二分类的类别判别结果,一般"阈值"取0.5,即:
y ^ = { 0 , 预测概率 < 0.5 1 , 预测概率 ≥ 0.5 \begin{equation} \hat y=\left\{ \begin{aligned} 0, 预测概率<0.5 \\ 1, 预测概率≥0.5 \end{aligned} \right. \end{equation} y^={0,预测概率<0.51,预测概率≥0.5
我们继续使用代码来实现这个过程,并进行绘图
import matplotlib.pyplot as plt
import numpy as np
# 设置阈值
threshold = 0.5
# 根据阈值进行分类
y_hat = (y_hat >= threshold).astype(int)
# 创建一个画布,宽度为14,高度为6
fig, axes = plt.subplots(1, 2, figsize=(14, 6))
# 在左侧的图中绘制真实的标签情况
axes[0].scatter(df['x1'][df['y'] == 0], df['x2'][df['y'] == 0], color='blue', label='Label 0')
axes[0].scatter(df['x1'][df['y'] == 1], df['x2'][df['y'] == 1], color='red', label='Label 1')
axes[0].set_title('Actual Labels')
axes[0].legend()
# 在右侧的图中绘制预测的标签情况
axes[1].scatter(df['x1'][y_hat == 0], df['x2'][y_hat == 0], color='blue', label='Predicted Label 0')
axes[1].scatter(df['x1'][y_hat == 1], df['x2'][y_hat == 1], color='red', label='Predicted Label 1')
axes[1].set_title('Predicted Labels')
axes[1].legend()
# 显示图像
plt.show()
这两个图像是逻辑回归模型的真实值与预测值的散点图。
左图显示了样本的真实类别。蓝色的点代表类别0,红色的点代表类别1。可以看到,两类样本在x1和x2的分布上有一定的区别,这是我们应用逻辑回归模型进行分类的基础。
右图显示了模型的预测结果。同样的,蓝色的点代表预测为类别0,红色的点代表预测为类别1。通过比较左右两图,你可以看到预测结果大致上和真实情况是一致的。这说明模型在这组数据上的表现是良好的。
五、结语
总结一下逻辑回归的建模过程:
在逻辑回归中,我们不仅预测出一个类别标签(0或1),而且还预测出样本属于每个类别的概率,这种概率的预测是通过逻辑函数(Sigmoid)函数来实现的,具体的:
数学上,逻辑回归模型首先计算出一个线性函数的值,即:
z = w 0 + w 1 x 1 + w 2 x 2 + . . . + w n x n + b z = w_0 + w_1x_1 + w_2x_2 + ... + w_nx_n + b z=w0+w1x1+w2x2+...+wnxn+b
然后,这个线性函数的值 z z z被带入到sigmoid函数中,得到预测概率 y ^ \hat y y^:
y ^ = 1 1 + e − z \hat y = \frac{1}{1 + e^{-z}} y^=1+e−z1
这个预测概率 y ^ \hat y y^即为样本被预测为类别1的概率,它的值在(0,1)之间。
最后,我们可以设定一个阈值(一般是0.5),如果 y ^ \hat y y^ 大于等于这个值,那么我们就预测这个样本为类别1,否则预测为类别0。这就是我们上述实现的过程。
在上述的模拟数据中,我直接给出了 w 0 w_0 w0, w 1 w_1 w1, w 2 w_2 w2的值,实际上这些模型参数的值是通过机器学习算法从数据中学习得到的,逻辑回归模型通常使用梯度下降(Gradient Descent)或其他优化算法来找到能够使损失函数最小的参数值。损失函数的选择通常为交叉熵损失(Cross-Entropy Loss),接下来的文章将会有参数估计和梯度下降的详细解读,届时我们就能够很好的理解如何得到最优的超参数以完成完整的逻辑回归建模。
最后,感谢您阅读这篇文章!如果您觉得有所收获,别忘了点赞、收藏并关注我,这是我持续创作的动力。您有任何问题或建议,都可以在评论区留言,我会尽力回答并接受您的反馈。如果您希望了解某个特定主题,也欢迎告诉我,我会乐于创作与之相关的文章。谢谢您的支持,期待与您共同成长!
期待与您在未来的学习中共同成长。