精读《设计机器学习系统》-ch04: 训练数据

Search for a command to run...

No comments yet. Be the first to comment.
C++程序设计兼谈对象模型-导读 conversion function, 转换函数 class Fraction { public: Fraction(int num, int den=1) : m_numerator(num), m_denominator(den){}; operator double() const { return 1.0 * m_numerator / m_denominator; } private: int m_n...

头文件与类声明 Classes 两个分类 Class without pointer member(s): complex Class with pointer member(s): string 也可以分为 Object-Based vs Object Oriented 构造函数 inline函数 函数如果在 class 内定义完成,则自动成为 inline 候选人. 也可以在class 外部定义,方法需要增加inline 关键字。 constructor(ctor, 构造函数) ...

类型限制了一个变量可以接受的有效值的集合,对数据可以进行的操作,数据的意义。 空类型(The empty type) 根据类型的定义,类型定义了可以接受的有效值集合,那么这个集合有没有可能为空?答案是有可能的,TypeScirpt 的 never 就是这种类型。 需要注意的是,空类型不同与 void, 后者是有效值集合当中只有一个值,但这个值没有任何意义。而空类型的有效值集合本身是空的。 使用场景 控制流分析 在函数调用时,标志一个函数不会返回任何值: 在调用过程中抛出异常、死循环或者程序崩溃...

这一章大部分内容和DDIA很相似,作者也说 “If you’re already familiar with data systems, you might want to move directly to Chapter 4 to learn more about how to sample and generate labels to create training data. If you want to learn more about data engineering from a...

不同于 Chapter03 从系统的角度来处理数据,这一章从数据科学的视角来处理数据。这章的标题是“training Data”,而非“training dataset”,因为 数据集(dataset) 意味着有限(finite)和固定(stationary), 而现实生产环境中的 数据(data) 通常是 无限 并且 不固定 的。
抽样方法在 ML 项目的生命周期中无处不在,在这一节中,我们使用生成训练数据作为例子。
那为什么需要抽样?直接使用全部数据不可以吗?
首先,在现实世界中,并不是所有数据都可以被访问,模型训练只能使用部分数据集。 其次,处理你能够访问到的所有数据是不现实的,需要大量的时间和资源。好的抽样方法可以帮助你以更低的成本和更快的时间来完成任务。
理解不同的抽样方法,可以帮助我们避免潜在的抽样偏差(biases), 也可以帮助我们提升抽样的速度。
抽样方式主要分为两类: 非概率抽样(nonprobability sampling) 和 随机抽样(random sampling)
非概率抽样,人如其名,选择数据不基于任何概率标准,有以下几类:
任意抽样(Convenience sampling) 选择可以用的数据就好。这种方法很受环境,因为方便。
滚雪球抽样(Snowball sampling) 未来的样本是根据现有的样本来选择的。例如,要在没有问Twitter数据库的情况下抓取合法的Twitter账户,你先从少量的账户开始,然后抓取他们关注的所有账户,以此类推。
判断抽样(Judgment sampling) 专家决定包括哪些样本。
配额抽样(Quota sampling) 根据某些数据分段的配额来选择样本,不需要任何随机化。举个例子: 在做调查时,你可能希望每个年龄组有100个结果:30岁以下,30至60岁之间,60岁以上,而不考虑实际年龄分布。
通过非概率抽样选择的样本,并不能有代表性的反应真实世界的数据分布,它们充满了由于选择造成的偏差。然而,处于成本和便捷性的考虑,非概率性抽样在某些场景下依旧被采用。以下是具体的应用例子。
语言模型 的训练通常不是用代表所有可能文本的数据,而是用容易收集到的数据--维基百科、Common Crawl、Reddit。
很多 情感分析 模型基于 IMBD 和 Amazon 评论,但这些评论并不能代表那些不能上网的人或不愿意把评论放在网上的人。
训练 自动驾驶,最初的自动驾驶数据是从亚利桑那州的凤凰城(因为其法规宽松),以及加利福尼亚州的湾区(因为许多制造自动驾驶汽车的公司都在这里)。 但这两个地方都阳光明媚。当2016年,自动驾驶业务在阴雨天较多的Kirkland, Washington 测试时,对于阴雨天气下的自动驾驶,效果并不好。
总体(statistical population)中的所有样本都有均等的机会被选择。
优点: 容易实现
缺点: 对于某些稀少的种类,很难被选择。
为了避免简单随机抽样的缺点,我们将总体数据划分到不同的群体中,对于群体单独进行选择。无论哪个群里多么稀少,都保证可以被选择。
针对每一个样本都会被赋予一个权重,来决定被选择的可能性。
优点: 可以得到领域知识的加成。当你知道哪部分数据可以为模型带来更好的效果时,可以增加这部分数据的被选择的机会。
当你拥有的数据与真实数据相比来自不同的分布时,这也有助于处理这种情况。 在 python 中的 random 就可以帮助我们实现这一点。
# Choose two items from the list such that 1, 2, 3, 4 each has
# 20% chance of being selected, while 100 and 1000 each have only 10% chance. import random
random.choices(population=[1, 2, 3, 4, 100, 1000], weights=[0.2, 0.2, 0.2, 0.2, 0.1, 0.1],k=2)
# This is equivalent to the following
random.choices(population=[1, 1, 2, 2, 3, 3, 4, 4, 100, 1000],k=2)
在ML中还有一个和加权抽样(weighted sampling)相似的概念: 样本权重(ample weights)。加权抽样是用来选择样本来训练你的模型,而样本权重是用来给训练样本分配 "权重 "或 "重要性"。权重较高的样本对损失函数的影响更大。改变样本权重可以大大改变你的模型的决策边界。如下图

蓄水池抽样用来处理流式数据,在生产环境中经常会用到。
假设你想从源源不断的推文中选取特定数量 k 个, 来分析和训练模型,但你不知道推文的数量,也无法保存所有推文在内存中。但你要确保:
所有推文都有 同样的可能性 被选择。
可以 在任何时间停止 抽样,并且所有推文被抽样的可能性相同。
蓄水池抽样就是可以解决这一类问题的 在线算法。 使用了一个代表蓄水池的数组,共有三步:
选择最初的k个样本进入蓄水池.
对于后面的第n个样本,生成一个随机数i, 1 <= i <= n.
如果 1 <= i <= k, 那么则替换第i个元素。否则,就什么也不做。 可以证明, 每个在蓄水池中的样本,都有k/n的概率被选中。

对应的有一道 leetcode 382
在大规模集群下,有对应的 Parallel Streaming Random Sampling
重要性抽样是最重要的抽样方法之一,不仅仅是在ML中。它允许我们在只能获得另一个分布的情况下从一个分布中取样。
ML模型的优劣很大程度上取决用于训练的标注数据的数量和质量。
在生产环境中,获得手工标注的标签是非常困难的,有以下几个原因:
手工标注数据的成本很高,尤其是在需要领域知识的情况下。比方说需要为X光胸片做标注,需要寻找专业的医生的帮助,并且他们的时间是非常有限和昂贵的。
手动标注数据对数据隐私构成了威胁。
手动标注数据很慢。例如,在语音上准确转录语音语料可能需要比语料时间长400倍的时间。缓慢的标注会导致缓慢的迭代速度,使你的模型对不断变化的环境和要求的适应性降低。
通常,为了标注足够多的数据,公司会使用多个来源的数据,并且依靠拥有不同层次经验的注释者。这样就会造成一个问题: 这些不同的数据源和注释者也有不同的准确性。
要求的领域专业知识水平越高,注释分歧的可能性就越大。
为了尽量减少注释者之间的分歧,首先要有一个明确的问题定义。其次,你需要将该定义纳入注释者的培训中,以确保所有注释者都能理解这些规则。
跟踪你的每个数据样本的来源以及它的标签是一个很好的做法,这种技术被称为 数据脉络(Data lineage) 。数据脉络有助于你在数据中标明潜在的偏差,并调试你的模型。