diff --git a/Practice/Dataset.md b/Practice/Dataset.md index a057cfb..54006e8 100644 --- a/Practice/Dataset.md +++ b/Practice/Dataset.md @@ -4,12 +4,44 @@ ![ML](https://img.shields.io/badge/LH-Machine%20Learning-red) ![NLP](https://img.shields.io/badge/LH-Natural%20Language%20Processing-red) +## 从数据概念开始讲起 + +我们认为能学习数据都符合一定的假设,在统计学上认为则是数据遵循一定概率分布。例如可乐一定遵循一定概率分布,其概率分布可以理解为从可乐厂生产。可乐厂生产的每一瓶可乐(样本)可能都不同,我们可以认为每一份样本(可乐)都遵从一个可乐厂生产的概率分布。而每一瓶可乐(样本)都是从可乐厂生产(采样)出来的。而机器学习的目标是学会这个概率分布。我们将遵从一定的概率分布记作 $\sim$ ,$x$ 数据遵循 $P$ 概率分布则会被写作 $x \sim P$。机器学习做的另一个假设则为数据集是遵循最终概率分布的,即 $\mathcal{D} \sim P$​。 + +如果我们称呼用于直接训练模型的数据点称呼为**训练集(training set,$\mathcal{D}_\text{train}$)**。而我们期望模型通过学习现有观测数据(训练集),并尝试去在未见过的数据达到最好的性能。因此我们需要一个模型从未见过的数据用于评估模型性能。我们称这个数据集为**测试集(testing set,$\mathcal{D}_\text{test}$​​)**。当然,我们一定不能让模型看到测试集,换句话说不能有泄露(Leakage)。 + +> **如果看见测试集会怎么样?** +> 让我们考虑一个学习的例子。上课老师总是在通过各种各样的题目让你学会知识(可以理解为在训练集上训练),平时测验尝试评估你学会知识没(通过测试集测试)。对于高中来说,我们期望在最终的高考取得好成绩,即我们通过平时的学习能够解决没见过的题目。对于类似的,通过先验经验以达到解决未见过的问题被称为**泛化(Generalisation)**。我们期望学生拥有最高的泛化性能。 +> +> 但是如果每次平时测验,你都做过原题(训练了测试集),那么对于最终的平时测试,你可能次次满分,相对应的,测试集上的测试指标非常高。但是对于现实问题的泛化性能,我们不得而知。 + +那通过训练集和测试集,我们究竟在拟合什么呢?可能最直觉的答案是我们在拟合训练集整体的概率分布,这是没错的。但是如果考虑一个现实情况,如果我们把数据集分割为训练集和测试集,那么显然训练集,测试集和最终概率分布都可能会有轻微不一样: +$$ +\mathcal{D} = \mathcal{D}_\text{train} \cup \mathcal{D}_\text{test} +\\ +\mathcal{D} \sim P +\qquad \mathcal{D}_\text{train} +\sim P_\text{train}\qquad +\mathcal{D}_\text{test} \sim P_\text{test}\\ + +P \approx P_\text{test} \approx P_\text{train} +$$ +考虑我们最终是以测试集指标作为评估标准,那么我们也可以认为,我们其实期望模型最终拟合测试集所对应的概率分布。 + ## 分割数据集 -在实践中,我们通常不会将所有数据点都用于训练模型,而根据模型训练的不同阶段,将数据集划分为训练集(training set,$\mathcal{D}_\text{train}$)、验证集(validation set,$\mathcal{D}_\text{valid}$,也称开发集,dev set)和测试集(testing set,$\mathcal{D}_\text{test}$)。 +在实践中,我们通常不会将所有数据点都用于训练模型,而根据模型训练的不同阶段,将数据集划分为**训练集(training set,$\mathcal{D}_\text{train}$)**、**验证集(validation set,$\mathcal{D}_\text{valid}$,也称开发集,dev set)**和**测试集(testing set,$\mathcal{D}_\text{test}$​)**。 + +> **为什么要有验证集?** +> +> 如果一个模型拥有很多超参数,即机器学习并不能自动学习的参数,那么我们通常需要手动调整以确定最优值,我们称呼这个过程为超参数调优 Hyperparameter Tuning。而我们依赖什么数据集进行调整呢? +> +> 如果我们直接在 $\mathcal{D}_\text{test}$ 上进行调整,那我们其实在变相给模型透露了最终用于验证的数据集特征:我们期望其在测试集取最低的损失,意味着我们其实本质上在让模型去拟合测试集的概率分布,这里的问题是我们的模型可能会只学习了测试集的分布,而学不会整体情况,从而导致在未见过的数据性能低下,即泛化性能并没有预期的好。 ![](./img/split.png) + + 训练集用于训练模型,验证集通常用于查看新数据的状态和用于调整模型的超参数,测试集用于评估模型的性能。在划分数据集时,我们通常会将数据集的大部分数据用于训练集,只有一小部分数据用于验证集与测试集。 常见的划分比例是 70% 的数据用于训练集,10% 的数据集用于验证集,20% 的数据用于测试集。 @@ -51,4 +83,5 @@ K 折交叉验证是将训练集 $\mathcal{D}_\text{train}$ 划分为 $K$ 个大 ### 留一法 Leave-One-Out Cross Validation -留一法是 K 折交叉验证的特例,即 $K=N$,其中 $N$ 是训练集 $\mathcal{D}_\text{train}$ 的大小。留一法的缺点是计算量大,但是由于每次只有一个样本作为验证集,因此留一法的结果是最准确的。 \ No newline at end of file +留一法是 K 折交叉验证的特例,即 $K=N$,其中 $N$ 是训练集 $\mathcal{D}_\text{train}$ 的大小。留一法的缺点是计算量大,但是由于每次只有一个样本作为验证集,因此留一法的结果是最准确的。 +