数据准备阶段基本术语及应用
1. 机器学习流程
图1-1 获取模型流程图
模型训练就是将算法应用于训练集进行运算并获取模型参数的过程。为了构建模型,我们需要进行如下步骤:
(1) 数据准备
在数据准备阶段,需要根据数据的大小或模型的复杂程度将数据集划分为训练集和测试集或训练集、验证集和测试集。
(2) 训练:将训练集输入到选定的算法中进行运算以获取算法最佳超参数,即得到模型。
1)选定算法,比如分类算法,回归算法或者聚类算法;
2)在训练集上训练模型,获取临时模型和训练集预测结果;
3)在验证集上运行临时模型,获得验证集预测结果;
4)参考训练集或验证集预测结果,改进模型;
5)反复迭代 2)-4)步,直至满足停止条件。
(3) 测试: 将测试集输入模型中,得到预测结果,然后将预测结果与预期结果按模型质量评价指标进行比较,最后根据指标结果来衡量当前模型的质量。
2. 数据准备阶段术语
2.1 数据术语
表1-1 鸢尾花部分数据
sepal length | sepal width | petal length | petal width | class |
---|---|---|---|---|
5.1 | 3.5 | 1.4 | 0.2 | Iris-setosa |
4.9 | 3.0 | 1.4 | 0.2 | Iris-setosa |
4.7 | 3.2 | 1.3 | 0.2 | Iris-setosa |
4.6 | 3.1 | 1.5 | 0.2 | Iris-setosa |
5.0 | 3.6 | 1.4 | 0.2 | Iris-setosa |
5.4 | 3.9 | 1.7 | 0.4 | Iris-setosa |
4.6 | 3.4 | 1.4 | 0.2 | Iris-setosa |
鸢尾花数据集是经典的机器学习示例数据集,它包含了关于鸢尾花的样本数据,每个样本都具有一些特征,同时被分为不同的类别,具体如表1-1所示。以下是该数据集中的三个主要概念:
- 特征(属性):特征是描述每个数据样本的各个方面的属性或测量值。在鸢尾花数据集中,每个样本有四个特征,它们分别是:
1) 花萼长度(sepal length)
2) 花萼宽度(sepal width)
3) 花瓣长度(petal length)
4) 花瓣宽度(petal width)
这些特征值用来描述每朵鸢尾花的大小和形态等信息。 - 类别:类别是我们希望模型能够预测的输出。在鸢尾花数据集中,有三个类别,分别代表了三个不同的鸢尾花物种:
1) 山鸢尾(Iris setosa)
2) 变色鸢尾(Iris versicolor)
3) 维吉尼亚鸢尾(Iris virginica) - 样例(记录或示例或实例):
每个样例代表了一个具体的鸢尾花实例,包括其四个特征的测量值以及它所属的类别。样例是数据集中的每一行记录。例如:
1) 花萼长度:5.1
2) 花萼宽度:3.5
3) 花瓣长度:1.4
4) 花瓣宽度:0.2
5) 类别:山鸢尾
图2-1 数据指示
从上图可以看出,除标题行以外,一行代表一个记录或示例或样例,其提供了模型用于学习和预测的信息;除类别列以外,一列代表一个特征或属性,其定义了模型的学习任务。2.2 数据集术语
当训练模型时,通常需要将数据分为不同的集合,如训练集、验证集和测试集,以便对模型进行训练、调优和评估。下面逐一介绍这些数据集的作用:
- 训练集
训练集是获取临时模型的数据集合。在训练阶段,算法使用训练集中的样本来学习数据中的关系,即模型。 - 验证集
只有面临大数据或者复杂模型时,才会划分验证集。验证集主要用于模型改进。在每轮训练之后,模型可以在验证集上进行评估,以了解模型质量。通过观察验证集上的性能,可以调整模型的超参数(如学习率、正则化强度等),以找到能够在验证集上达到最佳性能的参数组合。验证集的目的是避免在模型训练过程中对测试集的过度拟合,从而确保模型在未知数据上的泛化能力。 - 测试集
测试集用于最终评估模型的性能。一旦模型在训练和验证集上进行了多次调优,并且已达到了令人满意的性能水平,就可以使用测试集来验证这一点。测试集的评估结果可以反映模型的泛化能力,即模型对新数据的适应能力,从而帮助你判断模型是否达到了预期的性能水平。
2.3 划分经验
一般而言,这三种数据集均是从同一份标注数据中随机选取的。三者的比例是训练集:验证集:测试集=8:1:1,也可以是训练集:验证集:测试集:7:1:2。如果数据量不大,模型相对简单时,可划分为训练集:测试集=8:2或者训练集:测试集=7:3[1]。
2.4 模型评价指标
2.4.1 分类模型评估指标
-
准确率
准确率 = 预测正确的样本数目 预测样本数目 (2-1) 准确率 = \frac{预测正确的样本数目}{预测样本数目} \tag{2-1} 准确率=预测样本数目预测正确的样本数目(2-1)
例如,假设真实标签为 { 0 , 0 , 1 , 1 , 1 } \{0, 0, 1, 1, 1\} {0,0,1,1,1},预测标签为 { 1 , 0 , 1 , 1 , 1 } \{1,0,1,1,1\} {1,0,1,1,1},则准确率为 0.8 0.8 0.8。将准确率作为模型评估函数的时候会存在很多问题,特别是样本不均衡的情况。例如,有 1000 1000 1000个样本, 990 990 990个负样本, 10 10 10个正样本。假设模型预测的样本一直为负样本,则模型的准确率为 0.99 0.99 0.99。综上所述,在样本不均衡的情况下,准确率无法如实反映模型效果。 -
查准率(精确率)和查全率(召回率)
在介绍查准率和查全率之前,先引入 混淆矩阵的概念。对于二分类问题而言,预测值有两种情况,真实值有两种情况,所以组合起来一共有四种情况。这四种情况经过排列组合形成如下的混淆矩阵。表2-1 混淆矩阵 混淆矩阵 真实标签 正样本 负样本 预测样本 正样本 TP FP 负样本 FN TN 其中, T T T 和 F F F 为 T r u e True True 和 F a l s e False False,表示预测结果是否准确。 P P P 和 N N N 为 P o s i t i v e Positive Positive 和 N e g a t i v e Negative Negative,表示预测为正样本和负样本。根据混淆矩阵,查全率和查准率的公式定义如下:
1)查准率(精确率)是指真正的正样本与被分类器预测为正类的概率。
P = T P T P + F P (2-2) P=\frac{TP}{TP + FP} \tag{2-2} P=TP+FPTP(2-2)
2)查全率(召回率)是指正样本被预测为正样本的概率。
R = T P T P + F N (2-3) R=\frac{TP}{TP + FN} \tag{2-3} R=TP+FNTP(2-3)
案例 1 假设有 1000 1000 1000个样本, 990 990 990个正样本, 10 10 10个负样本。模型预测的全部是正样本,则查全率为 1 1 1,而查准率为 0.99 0.99 0.99。当全部预测为负样本时,则查准率 0 0 0,而查全率为 0 0 0。案例 2 假设有 1000 1000 1000个样本, 990 990 990个负样本, 10 10 10个正样本。模型预测的全部时正样本, 则查全率为 1 1 1,而查准率为 0.01 0.01 0.01。当全部预测为负样本时,则查准率为 0 0 0,而查全率为 0 0 0。
-
F 1 F_1 F1指标
根据案例 2 2 2 可知,查准率和查全率是一对矛盾的量。这时候我们就希望有一个函数能调和查准率和查全率,而 F 1 F_1 F1 指标就是查准率和查全率的调和平均数,计算公式定义如下:
F 1 = 1 1 2 P + 1 2 R = 2 P R P + R (2-4) \begin{align} F_1 &= \frac{1}{\frac{1}{2P} + \frac{1}{2R}} \\ &=\frac{2PR}{P+R} \end{align} \tag{2-4} F1=2P1+2R11=P+R2PR(2-4)
根据调和平均数的性质可知,当 P P P 与 R R R 越接近时, F 1 F_1 F1越大。 -
F β F_{\beta} Fβ指标
有时候我们希望查准率高点;有时候我们希望查全率高点。为了根据偏好来调整查全率和查准率对评估函数的影响,于是引入 F β F_{\beta} Fβ 指标,计算公式定义如下:
F β = 1 1 ( 1 + β 2 ) P + β 2 ( 1 + β 2 ) R = ( 1 + β 2 ) P R β 2 P + R (2-5) \begin{align} F_{\beta} &= \frac{1}{\frac{1}{(1 + \beta^2)P} + \frac{\beta^2}{(1 + \beta^2)R}} \\ &= \frac{(1 + \beta^2)PR}{\beta^2P+R} \end{align} \tag{2-5} Fβ=(1+β2)P1+(1+β2)Rβ21=β2P+R(1+β2)PR(2-5)
其中,当 β = R P > 1 \beta=\frac{R}{P}>1 β=PR>1时,查全率高;当 β = R P < 1 \beta=\frac{R}{P}<1 β=PR<1时,查准率高;当 β = R P = 1 \beta=\frac{R}{P}=1 β=PR=1时, F 1 F_1 F1 与 F β F_{\beta} Fβ 等价。下面对 β \beta β 进行简单推导:
F ( P , R ) = 1 α P + 1 − α R (2-6) \begin{align} F(P, R) = \frac{1}{\frac{\alpha}{P} + \frac{1-\alpha}{R}} \end{align} \tag{2-6} F(P,R)=Pα+R1−α1(2-6)
对 P P P 求偏导:
∂ F ∂ P = α R 2 ( ( 1 − α ) P + α R ) 2 (2-6) \frac{\partial{F}}{\partial{P}} = \frac{\alpha{R^2}}{((1-\alpha)P + \alpha{R})^2} \tag{2-6} ∂P∂F=((1−α)P+αR)2αR2(2-6)
对 R R R 求偏导:
∂ F ∂ R = ( 1 − α ) P 2 ( ( 1 − α ) P + α R ) 2 (2-7) \frac{\partial{F}}{\partial{R}} = \frac{(1-\alpha){P^2}}{((1-\alpha)P + \alpha{R})^2} \tag{2-7} ∂R∂F=((1−α)P+αR)2(1−α)P2(2-7)
假设 F F F 在 R R R和 F F F 在 P P P 的变化率上相等,则
R 2 P 2 = 1 − α α \frac{R^2}{P^2} = \frac{1-\alpha}{\alpha} P2R2=α1−α
β = R P = 1 − α α \beta = \frac{R}{P} = \sqrt{\frac{1-\alpha}{\alpha}} β=PR=α1−α
3. 测试结果及分析
3.1 训练集和测试集划分代码
# python版本
def split_train_test(
*arrays,
train_ratio=None,
test_ratio=None,
shuffle=False,
random_state=None
):
""" Split arrays into random train and test subsets.
Parameters
----------
*arrays: numpy arrays
origin datasets
train_ratio: float, default=None
train ratio
test_ratio: float, default=None
test ratio
shuffle: bool, default=False
shuffle
random_state: int, default=None
random state
Returns
-------
tuple
Tuple containing training datasets and testing datasets
"""
n_array = len(arrays)
if n_array < 1:
raise ValueError("At least one array required as input!")
if train_ratio is None and test_ratio is None:
raise ValueError("Either provide train_ratio or test_ratio!")
if train_ratio is not None:
split_ratio = train_ratio
else:
split_ratio = 1.0 - test_ratio
num_samples = len(arrays[0])
num_train = int(split_ratio * num_samples)
if shuffle:
if random_state is not None:
np.random.seed(random_state)
idx = np.arange(num_samples)
np.random.shuffle(idx)
idx_train = idx[:num_train]
idx_test = idx[num_train:]
else:
idx_train = np.arange(num_train)
idx_test = np.arange(num_train, num_samples)
train_datasets = tuple(array[idx_train] for array in arrays)
test_datasets = tuple(array[idx_test] for array in arrays)
return *train_datasets, *test_datasets
3.2 测试代码和结果
if __name__ == "__main__":
df = pd.read_csv("./breast_cancer/processed_data/breast_cancer.csv", header=None) # 加载乳腺癌数据
data = np.array(df) # 转化数据类型
X = data[:, :-1]
y = data[:, -1]
X_train, y_train, X_test, y_test = split_train_test(X, y, train_ratio=0.7)
pass
图2-2 乳腺癌数据集划分结果
3.3 分析结果
上述代码已实现将数据集划分为训练集和测试集、洗牌等功能,针对验证集划分,目前只支持先划分训练集,然后在训练集中继续划分的方法。直接方法暂未实现。
4. 参考文献
[1] 李烨. 机器学习极简入门[M]. 北京: 人民邮电出版社, 2021:26-29.
[2] 卡卡罗特. Enlighten AI · 机器学习[M]. LeetBook, 2023.