前言
用于分类的线性模型是指决策边界是特征向量 的线性函数的模型,存在几个重要的线性分类模型,包括线性判别分析(linear discriminant analysis)、逻辑回归(logistic regression)、感知机( percetron )和线性支持向量机(linear support vector machines);然而,在这里只讨论逻辑回归(logistic regression)模型
下面讨论的模型的理论方面有两个目的:
- 更好地理解每个模型的工作原理
- 更好地理解在 scikit-learn 实现每个模型中使用的一些重要参数
Logistic Regression
LDA中决策边界的线性性是对类条件密度的高斯假设的直接结果。另一种实现线性决策边界的方法是假设后验概率 的某种单调变换是线性的。在这方面,一个众所周知的变换被称为 函数。特别地,如果 ,那么
式中 函数内部的比率称为赔率( 函数的另一个名称是 )。例如,如果在一个二进制分类问题中,从一个类得到观察结果的概率是 ,那么从该类得到观察结果的概率是
让我们考虑一个函数,即 函数 :
使 用
作为
的参数导致 :
这意味着逻辑 是 函数的逆函数。在 Logit模型中,假设后验的 是 的线性函数,也就是说:
在 中分别用 和 代替 和 ,产生:
它总是介于0和1之间(因为后面是一个概率)。此外,由于 ,于是得到:
由 和 得到:
基于Logit模型的分类器是通过在 中设置 得到,既:
同时可以进一步写为:
相当于:
如上所示,由决策边界定义的二进制分类器的 Logit模型是线性的,因此,这是一个线性分类器。剩下的就是估计未知的参数 和 ,并在公式中替换它们,以便有一个正常运行的分类器
估计 Logit模型中未知参数的一个常见方法是,将给定观测值作为 和 的函数时,观测到标签的对数可能性最大化。让 表示未知参数的 维列向量。假设有独立的数据,此时可以写为:
其中 , 遵循公式中指定的紧凑形式,而 在 中表明这个概率确实是未知参数的函数,这种最大化方法是一种被称为最大似然估计的一个示例,因为我们试图通过最大化观察到的标签的( )似然来估计 (模型参数)的值,通过将上述对数似然函数乘以 -1,得到由 表示的损失函数(也称为误差函数) ,也就将上述最大化问题转换为最小化,也就是说:
由于其与交叉熵函数的相似性,被称为交叉熵损失(也称为对数损失)。证明了 关于 (即 Hessian 矩阵)的二阶导数是正定的。这意味着 是具有唯一极小值的 的凸函数。因此,设置 相对于 到零的导数应该导致最小值; 然而,由于这些方程是非线性的,不存在闭式解,需要依靠迭代优化方法来估计参数 和 。通过这些方法之一估计 和 ,并在公式中替换它们,结果得到以下分类器:
尽管在文献中使用损失函数 时,标签常常是0和1,但假设标签是 ,则有一个更紧凑的形式来写逻辑回归的损失函数,首先要注意的是,类似于前文中的后验的紧凑表示,可以表示为:
利用这个后验的紧凑表示,可以把 写成如下紧致形式,其中
强调对不同形式的 使用的 等价于使用 。因此,这些标记类的选择并不影响 和 以及相应分类器的估计
关于 Logit模型,一个重要而且相当令人困惑的观点是,它的主要用途是分类,而不是回归。根据定义,试图近似和估计数字的后验概率,这并不奇怪,它被称为 Logit模型,但是,在效用方面,我们几乎总是感兴趣,将这些后验概率进行比较,以便将给定的观察结果与其中一个类别或等效的形式进行分类)进行分类。因此,它有时被称为
多元分类
进行二分类时,我们假设 是特征向量的线性函数,然后使用 来引入二分类 ,在多分类的情况下,我们假设:
因为后验概率加起来是1,我们可以得到 类的后验概率:
利用这些形式的后验概率,我们可以将损失函数扩展到多类,然后使用一些迭代优化方法来估计模型的参数(既 和 ),然后使用前文中的判别式获得分类器
正则化
在实际应用中,考虑前文中指出的损失函数的惩罚形式通常是有帮助的; 也就是说,使用一个损失函数来约束 中系数的大小(即惩罚可能的大系数以得到较小系数)。试图正则化或缩减估计系数,这种方法被称为正则化或缩减。缩减有多种形式。一种常见的方法是最小化:
其中 被称为 的 范数,由 给出,而 是一个调节参数,它表示估计参数时损失项和正则化项的相对重要性,当 , 惩罚项对最小化没有影响,然而当 , 向量 中的系数收缩为0,这意味着更高的 ,我们期望的正规化程度越低,进而意味着对训练数据的拟合效果越强,在模型选择阶段,通常对 的最佳选择进行估计(例如,调整 )。因为这里使用的是 的 范数,所以最小化 被称为 正则化,使用这个目标函数训练的 Logit模型被称为 惩罚 Logit模型(也被称为 ),还有其它有用的缩减方法,如 正则化和弹性网络正则化。Logit模型的 正则化是通过最小化来实现的:
其中 是 的范数,另一方面弹性网络正则化是通过同时最小化 正则化和 正则化来实现的:
其中, 是另一个调整参数,它在 正则化和 正则化之间创建了一种折中。特别是当
时,
减小到 正则化的情形,而当v =0时, 减小到 正则化的情形
Scikit-learn 实现
逻辑回归分类器是通过 sklearn.linear_model 模块中的 LogisticRegression 类实现的,默认情况下,scikit-learn 实现使用 正则化,其超参数 的默认值为 1.0。然而,可以通过设置 'penalty' 和 的值来更改这些选择。penalty 参数的可能选项包括 ' '、' '和 'elasticnet'。当 'penalty' 设置为 'elasticnet' 时,还应该通过将 LogisticRegression 中的 ' _ratio'的值 ν设置为区间 [0,1] 中的某个值,并且还需要将 solver 的默认值从 'lbfgs'(截至 scikit-learn 版本 1.1.2)更改为 'saga',因为 'saga' 支持 'elasticnet' 正则化。如果想要 正则化,则可以使用 'liblinear' 求解器(也支持 正则化)
More on solver
有许多优化算法可以在实际 中 用来求解上述损失函数的最 小化,以估计未知参数。 这些方法包括:
- "最速下降方向(Steepest Descent Direction)" 指的是在优化问题中使用的一种迭代方法,它的目标是在搜索空间中找到一个能够使目标函数值下降最快的方向。该方向通常与梯度的方向相反
- 牛顿方法(例如,迭代加权最小二乘法)具有较快的收敛速度(通常是二次的),但需要计算目标函数的 Hessian 矩阵,这本身是计算昂贵且容易出错的
- 拟牛顿法是一类具有超线性收敛速度(比线性更快)的方法,通过避免显式计算 Hessian 矩阵,甚至可以在 Hessian 矩阵非正定的情况下使用。它们利用了梯度变化提供了关于沿搜索方向的 Hessian 矩阵的信息这一事实
案列
,
在这个案例中,希望训练一个具有 正则化(LRR)的 Logit模型,使用两个特征: 萼片宽度和花瓣长度对鸢尾花进行分类
import numpy as np
arrays = np.load('data/iris_train_scaled.npz')
X_train = arrays['X']
y_train = arrays['y']
arrays = np.load('data/iris_test_scaled.npz')
X_test = arrays['X']
y_test = arrays['y']
print('X shape = {}'.format(X_train.shape) + '\ny shape = {}'.format(y_train.shape))
print('X shape = {}'.format(X_test.shape) + '\ny shape = {}'.format(y_test.shape))
为了说明的目的,这里只使用数据的第二和第三个特征(萼片宽度和花瓣长度)来开发和测试分类器
X_train = X_train[:,[1,2]]
X_test = X_test[:,[1,2]]
X_train.shape
接下来使用 正则化来绘制 Logit模型的判定边界
%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.linear_model import LogisticRegression as LRR
import numpy as np
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
# 设置颜色和颜色映射
color = ('aquamarine', 'bisque', 'lightgrey')
cmap = ListedColormap(color)
# 计算坐标范围
mins = X_train.min(axis=0) - 0.1
maxs = X_train.max(axis=0) + 0.1
x = np.arange(mins[0], maxs[0], 0.01)
y = np.arange(mins[1], maxs[1], 0.01)
X, Y = np.meshgrid(x, y)
coordinates = np.array([X.ravel(), Y.ravel()]).T
# 创建图形和轴
fig, axs = plt.subplots(1, 2, figsize=(6, 2), dpi=150)
fig.tight_layout()
# 不同的正则化参数值
C_val = [0.01, 100]
# 循环绘制图形
for ax, C in zip(axs.ravel(), C_val):
# 创建逻辑回归模型
lrr = LRR(C=C)
lrr.fit(X_train, y_train)
# 预测决策区域
Z = lrr.predict(coordinates)
Z = Z.reshape(X.shape)
# 绘制决策区域和轮廓线
ax.tick_params(axis='both', labelsize=6)
ax.set_title('逻辑回归决策区域: C=' + str(C), fontsize=8)
ax.pcolormesh(X, Y, Z, cmap=cmap, shading='nearest')
ax.contour(X, Y, Z, colors='black', linewidths=0.5)
# 绘制训练数据点
ax.plot(X_train[y_train == 0, 0], X_train[y_train == 0, 1], 'g.', markersize=4)
ax.plot(X_train[y_train == 1, 0], X_train[y_train == 1, 1], 'r.', markersize=4)
ax.plot(X_train[y_train == 2, 0], X_train[y_train == 2, 1], 'k.', markersize=4)
# 设置轴标签
if (C == C_val[0]):
ax.set_ylabel('花瓣长度(归一化)', fontsize=7)
ax.set_xlabel('花萼宽度(归一化)', fontsize=7)
# 打印准确率
print('正则化参数 C={} 在训练数据上的准确率为 {:.3f}'.format(C, lrr.score(X_train, y_train)))
print('正则化参数 C={} 在测试数据上的准确率为 {:.3f}'.format(C, lrr.score(X_test, y_test)))
正如前文所说,较大的 值表示较少的正则化,模型对数据的拟合更强。这可以从图中的右图清晰看出,在这里观察到数据确实可以被两条线很好地分离。然而,较小的 值意味着更多的正则化,如图中左图所示。这也可以从在训练数据上估计的准确度中看出。虽然 C = 100 可以以 95% 的准确度分离训练数据,但 C = 0.01 的模型导致了 81.7% 的复原准确度。在这里,C = 100 在测试数据上展现出更高的准确度;然而,并不总是如此:
- 并不是说 的高值总是比低值好,反之亦然
- 较大的训练精度并不一定导致较大的测试精度。如果模型过分拟合训练数据,它可以显示一个高的重置精度,但在测试数据执行较差
如果你对类似于这样的文章感兴趣。
欢迎关注、点赞、转发~
regularizations. In particular, when
ν
= 1 , (6.47) reduces to that of
l 1
regularization, and when
ν
= 0 , (6.47) reduces to that of
l 2
regularizatio
