从求职者的角度看“在数据科学领域建立职业生涯”
艾米莉·罗宾逊和杰奎琳·诺利斯写得很好的这本书的前半部分带来了新的积极和展望
自 3 月初以来,我一直在积极申请西雅图的数据科学工作。我刚刚在 Flatiron 完成了我的数据科学训练营,我非常兴奋能够去那里找到我梦想中的工作。不幸的是,3 月初也是美国新冠肺炎危机的开端。这场危机极大地抑制了数据科学家的就业市场,但幸运的是没有其他职业那么糟糕。然而,现在我几乎已经找了三个月的工作,却没有真正的机会来展示自己作为一名职业生涯早期的数据科学家,我尽最大努力保持乐观,同时想办法确保我给人留下最好的印象。
Emily Robinson 和 Jacqueline Nolis 的提示“在数据科学领域建立职业生涯!几个月前,这本书出现在我的 LinkedIn 时间轴上,但当时我非常乐观,不认为我需要投资一本自助书来让我继续找工作。然而,随着工作前景停滞不前,我开始认真考虑更多的资源来帮助我获得竞争优势,我记住了这本书。事实上,几年前,当我开始考虑在数据科学领域发展时,我有幸见到了 Jacqueline。Jacqueline 和她的妻子 Heather(我的高中同学)是一个数据科学梦之队,我和他们一起喝了一杯内容丰富、令人鼓舞的午后咖啡。因此,我决定买杰奎琳的书,如果没有别的,只是为了支持诺利斯一家!
在这篇文章中,我将回顾这本书的前半部分,这本书由四部分组成,重点是培养数据科学所必需的技能以及如何获得你的第一份工作。(后半部分讨论了如何在找到工作后推进你的职业发展,所以我现在不打算回顾这一部分。不过,一旦我找到第一份工作,我肯定会回来的!)我将总结每一章,并讨论我从每一章中获得的宝贵观点。
如果你没有通读我的整篇文章,让我至少这样说:如果你对如何寻找数据科学工作感到迷茫,请阅读这本书!
“在数据科学中建立职业生涯”写得非常好,清晰,引人入胜,并为有抱负和已建立的数据科学家提供了很多很好的建议。它的目的不是教你在数据科学领域工作所需的技能,而是教你如何在这个新的快速变化的领域追求和发展你的职业生涯。每章涵盖职业生涯建设中的不同主题,并包括与一位知名数据科学家的简短访谈,该访谈提供了该章中给出的信息的真实示例。如果你正在考虑数据科学,寻找数据科学方面的工作,或者甚至试图推进你目前的数据科学职业生涯,这本书正适合你。
第 1 部分:数据科学入门
“在数据科学领域建立职业生涯”的前四章介绍了该行业,并就如何发展数据科学工作所需的技能以及建立展示这些技能的投资组合给出了建议。当我第一次翻阅这本书时,我并不认为我会在这一部分学到很多东西,但事实证明它真的提供了很多信息,并极大地改变了我在求职申请中考虑“推销自己”的方式。
第 1 章—什么是数据科学?
第一章给出了当今数据科学领域的概述。如果你对数据科学工作做过任何研究,你可能已经意识到这个领域非常广泛,角色可能会因招聘公司的不同而有所差异(更多信息请见第二章)。Robinson 和 Nolis 通过将该领域呈现为一个三角形来提供一些组织,在三角形的每个角上都有领域知识、数学和统计、编程和数据库方面的技能。根据连接的两个角,您有不同类型的数据科学工作。连接领域知识和数据库的三角形边代表数据分析工作。这些工作人员可能具有商业、经济或统计背景,并且将大部分时间花在开发工具上,例如仪表板,以汇总并向利益相关者呈现数据趋势和报告。将编程/数据库与数学和统计联系起来的一方代表机器学习工程师,他们致力于开发和部署机器学习模型。这些人通常有软件工程或计算机科学的背景,他们的工作与软件开发人员非常相似。连接领域知识与数学和统计学的三角形的最后一边代表决策科学家。这些工作人员能够制定适当的数据分析和开发预测模型,然后根据业务目标解释并向利益相关者展示结果。作者还讨论了商业智能分析师和数据工程师等相关工作,但将他们排除在数据科学领域之外。最后,他们讨论如何选择适合你自己经验和技能的子领域。
我发现这种数据科学工作的分类非常有用。在我自己的求职过程中,我一直很困惑什么样的工作需要什么样的技能。我知道我在科学交流和研究、数学和统计方面有很强的背景,我知道我的技能在某种程度上适合数据科学,但不确定具体要找什么样的工作!现在我知道决策科学工作可能是最适合我的,我计划开始专门寻找这些工作。
第 2 章—数据科学公司
本章根据行业、公司年龄和规模描述了几个假设公司的数据科学。这些描述了你期望在这些公司从事什么样的工作,那里的文化是什么样的,以及你在那里工作时可能面临的挑战和自由。从大型科技公司,如微软、苹果和脸书,到小型创业公司,这些描述让你了解哪种类型的公司适合你自己的工作方式、目标和经历。
虽然这些是对每种公司类型的概括,它们不会对属于这一类别的每家公司都准确,但这些信息让你在与公司员工进行信息面试和申请工作时记住一些东西。我对这一章的唯一批评是,作者没有讨论基于合同的工作,如咨询公司的工作。也许这是西雅图成熟的数据科学市场的产物,但这些代表了我看到发布的许多入门级职位,我与之交谈的许多人在能够获得 FTE 的中高级职位之前都经历过这种类型的职位。我很想看看作者对这些公司和职位的看法!
第 3 章——获得技能
本章重点介绍如何培养您从事数据科学职业所需的技能,无论您刚刚获得学士学位,拥有数据分析或研究方面的研究生经验,还是正在尝试从一个数据职业过渡到另一个职业。他们为学习数据科学技能提供了四种不同的选择:(1)数据科学学位,如硕士学位,(2)数据科学训练营,(3)通过在线课程和出版材料自学,或(4)在职学习,如果您当前的工作可以支持的话。他们给出了非常务实和合理的建议,解释了为什么你会根据自己的背景和时间选择一条路线。
对于刚刚开始数据科学之旅的人来说,这将是一个伟大的篇章。虽然我已经完成了一个训练营,但它并没有给我提供太多关于我自己找工作的见解,但它确实给了我信心,让我相信考虑到我的经历,我选择了正确的道路。
第 4 章——建立投资组合
根据你的背景,你可能没有任何与工作相关的数据科学经验可以写进简历。本章强调了拥有一个作品集来展示你努力学习的技能的重要性。作者提出了适当范围的项目,如何为他们找到数据,如何使他们脱颖而出,以及展示他们结果的最佳方式。他们讨论维护博客的好处(比如我的!)向各种受众清晰传达数据科学项目。这一章对于开发你自己的投资组合项目从开始到传播是一个很好的指导。
第二部分:找到你的数据科学工作
“在数据科学领域建立职业生涯”的第二部分是我最感兴趣的部分。这是如何在求职中取得成功的关键,从寻找空缺职位到参加面试和协商工作机会。这四章给出了很多关于完善你的申请和在这个过程中保持自我价值完整的建议。
第 5 章——寻找:找到适合你的工作
现在,您已经具备了从事数据科学工作所需的技能,并且有了突出这些技能的作品集,下一步就是找工作了!本章主要讲述如何找到一个适合你在公司寻找的职位,以及如何解读一份招聘启事,这样你就知道对这个职位有什么期望,以及公司对一个成功的应聘者有什么期望。作者给出了一些建议,告诉你应该避免什么类型的工作列表,比如臭名昭著的“独角兽”职位,以及你应该把精力放在什么类型的申请上。他们给出了如何找到工作的建议,比如参加聚会和使用社交网络。
我认为本章给出的建议真的很棒,尤其是在就业市场强劲的时候,但现在你可能不会像作者鼓励的那样有选择性。我打算在自己的求职中应用的两点是:(1)不要每天找工作,(2)拓宽你的搜索范围。我已经开始在每个工作日查看求职公告板,但是一周查看 2-3 次已经足够了,可以帮助我专注于求职的其他部分。我也将开始考虑更多不是“数据科学家”的职位,希望我能找到适合我的技能和目标的工作。
第六章——申请:简历和求职信
这一章是关于确保你的技能和经验的书面陈述足够好,以引起招聘人员的注意,并使他们相信他们找到了一个适合他们空缺职位的合适人选。有简历和求职信的样本,以及优化它们的方法的描述。作者给出了如何突出你的数据技能的建议,即使是以前与数据科学无关的职位。他们讨论了为该职位定制文件的重要性,以及如何巧妙地获得推荐。
就我个人而言,我很欣赏关于如何充分利用你以前的经历的建议。虽然我以前听说过,但我也需要提醒你根据职位量身定制申请材料。本章建议不要试图“玩数字游戏”,而是把更多的精力放在申请你认为最适合你的工作上。
第七章——面试:期待什么以及如何应对
我将要描述的最后两章涵盖了我几乎没有经验的工作申请过程,但我希望能尽快将理论付诸实践!这一章是关于面试过程的,可能是最可怕和最伤脑筋的部分。作者给出了许多公司面试过程的一般描述,从最初的电话面试,到现场面试,样本项目和最终面试。它们不仅描述了如何完成每一步,从而证明你能胜任这份工作,并且你会很好地与之共事,还描述了如何获得关于你是否想同时为该公司工作的信息。他们提供了如何在面试中回答技术和行为问题的建议,另外还有一个练习用的样题附录!
第 8 章——提议:知道接受什么
这一章涵盖了一个非常令人兴奋的前景:如何谈判你的工作机会!假设你成功通过了面试,现在是时候制定你的工作细节了。本章讨论何时以及如何协商你的薪水、福利等。招聘人员/招聘经理。它还讲述了如何在两个竞争的报价之间进行权衡和选择(如果你足够幸运处于那个位置的话!).
这一章给像我这样的人提供了很多好的建议:在问我想要什么时胆怯,患有冒名顶替综合症,在谈判工作机会方面缺乏经验。它甚至有一个专门关于处理冒名顶替综合症的小广告——我可能会经常提到它!希望我(和其他阅读这篇文章的人!)将很快使用这些技术!
最后的想法
结束这篇相当长的帖子(对不起大家!),不得不说总体来说到目前为止我对这本书印象非常深刻。这真的是一种资源,当我需要信心提升或关于下一步该做什么的建议时,我可以看到自己在参考。它已经帮助我重新考虑如何解决我自己的求职问题,我相信这本书的后半部分将在我找到工作并希望不断提升时指导我。
显然,这本书是在疫情对我们的经济造成损害之前写就并出版的。我很想听听罗宾逊和诺利斯对这个新的在家工作、早期职业机会有限的就业市场有什么建议。例如,我们应该如何以及何时考虑一个完全遥远的职业与一个我们可以选择(希望很快)与同事在办公室工作的职业?我们怎样才能说服公司考虑我们或者把我们记在心里,即使他们现在不招人?在等待招聘再次增加的同时,我们能做些什么来保持前进?
最后,我要感谢艾米丽和杰奎琳写了这本书。这是一个奇妙的资源,我期待着将他们的建议应用到我自己的职业生涯中。希望这篇文章也能说服你去读这本书!像往常一样,随时留下评论或问题!
表格数据的 GANs
我们非常了解 GANs 在现实图像生成方面的成功。但是,它们可以应用于表格数据生成。我们将回顾和检查一些最近的论文,关于表格式甘在行动中。关于最终结果和源代码,可以去 Github 仓库。
看看我的机器和深度学习博客https://diyago.github.io/
甘是什么
GAN 由两个深层网络组成:发生器和鉴别器【1】**。两人同时训练。通常,模型结构和训练过程是这样表示的:**
GAN 培训管道。什么是生成性敌对网络?【1】
****发生器的任务是产生样本,样本不会被鉴别器从真实样本中区分出来。我不会在这里给出太多细节,但如果你想深入研究它们,你可以阅读媒体帖子和伊恩·j·古德费勒的原文。
最近的架构,如 StyleGAN 2,可以产生出色的照片级逼真图像。
由 StyleGAN 2,SsourcearXiv:1912 . 04958 v2[7]生成的人脸精选示例
问题
虽然人脸生成似乎不再是一个问题,但我们仍有许多问题需要解决:
- 训练速度。对于训练 StyleGAN 2,您需要 1 周和 DGX-1 (8x NVIDIA Tesla V100)。
- 特定领域的图像质量。最先进的网络在其他任务上仍然失败。
StyleGAN 2 生成的汽车和猫的精选示例,来源 arXiv:1912.04958v2 [7]
表格甘斯
由于不平凡的数据分布和高度的对象类型多样性,对于 GANs 来说,即使是生成猫狗也是一项繁重的任务。除此之外,图像背景也变得很重要,这是 GANs 通常不能产生的。
因此,我一直在想 GANs 在表格数据上能达到什么样的效果。可惜文章不多。接下来的两篇文章似乎是最有希望的。
TGAN:使用生成对抗网络合成表格数据 arXiv:1811.11264v1 3
首先,他们提出了几个问题,为什么生成表格数据有自己的挑战:
- 各种数据类型(整数、小数、类别、时间、文本)
- 不同形状的分布(多模态、长尾、非高斯……)
- 稀疏的一次性编码向量和高度不平衡的分类列。
任务形式化
假设表 T 包含 n_c 连续变量和 n_d 离散(分类)变量,每一行都是 C 向量。这些变量具有未知的联合分布P。每一行都是从 P 中独立采样的。目标是训练生成模型M。M应生成新的合成表 T_synth ,其分布类似于 P. 在 T_synth 上学习的机器学习模型应在真实测试台上 T_test 上达到类似的精度,在 T. 上训练的模型也是如此
预处理数值变量。"**使用tanh"【3】,神经网络可以有效地生成以(1,1)为中心的分布值。然而,他们表明,网络不能产生多模态数据合适的数据。因此,他们通过使用和训练高斯混合模型( GMM )对每个 C 使用 m (m=5)个分量来聚类一个数值变量。**
使用平均值和标准偏差的 GMM 归一化。来源 arXiv:1811.11264v1 3
最后,使用 GMM 归一化 C 得到 V. 此外,他们计算 C 来自每个 m 高斯分布的概率作为向量 U.
****预处理分类变量。由于基数通常较低,他们发现可以使用 softmax 直接生成概率分布。但是必须将分类变量转换为带有噪声的一位热编码表示,将二进制变量转换为二进制变量
前置后,它们将带有 n_c + n_d 列的 T 转换为 V,U,D 向量。该矢量是发生器的输出,也是 GAN 中鉴别器的输入。“甘没有获得的参数”3。
发电机
他们分两步生成一个数字变量。首先,生成值标量 V ,然后生成聚类向量 U ,最后应用 tanh 。使用 softmax 在所有可能标签上生成概率分布的分类特征。使用注意机制生成所需的行 LSTM。为 LSTM 在每一步中输入的是随机变量 z、*加权上下文向量与先前隐藏的和嵌入向量。***
鉴别器
使用具有 LeakyReLU 和 BatchNorm 的多层感知机(MLP)。第一层使用中的级联向量 (V,U,D) ,具有来自 LSTM 的特征向量的小批量分集。损失函数是具有和序数对数损失函数的输入变量的 KL 散度项。
使用 TGAN 生成简单人口普查表的示例。生成器逐个生成 T 个特征。鉴别器将所有特征连接在一起。然后使用具有 LeakyReLU 的多层感知器(MLP)来区分真假数据。来源 arXiv:1811.11264v1 3
结果
在真实和合成训练集上训练的机器学习模型的准确性。(贝叶斯网络,高斯连接函数)。来源 arXiv:1811.11264v1 3
***他们在两个数据集 KDD99 和 *covertype 上评估模型。出于某种原因,他们使用了没有 boosting 的弱模型(xgboost 等)。无论如何,TGAN 表现得相当好和稳健,胜过贝叶斯网络。真实数据和合成数据之间的平均性能差距为 5.7%。
使用条件 GAN 对表格数据建模(CTGAN)arXiv:1907.00503 v2[4]
与以前的 TGAN 相比,主要的改进是应用模式特定的归一化来克服非高斯和多峰分布。然后使用条件生成器和抽样训练来处理不平衡的离散列。
任务形式化
最初的数据与在 TGAN 时一样。然而,它们解决不同的问题。
- 健身的可能性。 T_syn 中的列是否遵循与 T_train 相同的联合分布
- ****机器学习功效。当训练模型使用其他列作为特征来预测一列时,从 T_syn 学习的这种模型在 T_test 上能否达到与在 T_train 上学习的模型相似的性能
预处理
离散列的预处理保持不变。
对于连续变量,使用变分高斯混合模型( VGM )。它首先估计模式的数量 m ,然后拟合高斯混合。在我们将初始向量 C 归一化后,它几乎和在 TGAN 时一样,但是它的值在每种模式下都是归一化的。模式表示为一热向量斗鱼([0,0,…, 1, 0]).Alpha 是 C 的归一化值。**
特定于模式的规范化示例。来源 arXiv:1907.00503v2 [4]
因此,我们将初始行表示为“一键”离散列的串联,并具有上面讨论的连续变量的表示:
预处理行。来源 arXiv:1907.00503v2 [4]
培训
“最终解决方案由三个关键要素组成,即:条件向量、发电机损耗和采样训练法”[4]。
CTGAN 模型。条件生成器可以根据离散列之一生成合成行。通过采样训练,根据每个类别的对数频率对 cond 和训练数据进行采样,因此 CTGAN 可以均匀地探索所有可能的离散值。来源 arXiv:1907.00503v2 [4]
条件向量
表示所有离散列的串联“一键”向量,但仅指定了一个选定的类别。例如,对于两个离散的列,D1 = {1,2,3}和 D2 = {1,2},条件(D2 = 1)由掩码向量 m1 = [0,0,0]和 m2 = [1,0]表示;所以 cond = [0,0,0,1,0]" [4]。
发电机损耗
“在训练期间,条件生成器可以自由产生任何一组独热离散向量”[4]。但是他们强制条件生成器产生 d_i ( 生成的离散独热列) = m_i (掩码向量)是通过增加它们之间的交叉熵来惩罚它的损失,在批处理的所有实例上平均。
抽样训练
“具体来说,目标是以这样一种方式有效地进行重新采样,即在训练过程中对离散属性的所有类别进行均匀采样,从而在测试过程中获得真实的数据分布”[4]。
换句话说,条件生成器产生的输出必须由评价者评估,评价者估计学习的条件分布 P_G(row|cond) 和真实数据上的条件分布 P(row|cond) 之间的距离。“真实训练数据的采样和 cond vector 的构造应符合帮助评论家估计距离的要求”[4]。对 cond 向量和训练数据进行适当采样可以帮助模型均匀地探索离散列中所有可能的值。
模型结构如下,与 TGAN 相反,没有 LSTM 层。用梯度惩罚的 WGAN 损失训练。
发电机。来源 arXiv:1907.00503v2 [4]
鉴别器。来源 arXiv:1907.00503v2 [4]
此外,他们提出了一个基于变分自动编码器(VAE)的模型,但这超出了本文的范围。
结果
提出的网络 CTGAN 和 TVAE 优于其他方法。正如他们所说,TVAE 在一些情况下优于 CTGAN,但 GAN 确实有几个有利的属性。与 TVAE 不同,GANs 中的生成器在整个训练过程中无法访问真实数据。
基准结果超过三组实验,即高斯混合模拟数据(GM Sim。),贝叶斯网络模拟数据(BN Sim。),以及真实数据。他们报告每个指标的平均值。对于真实数据集(f1 等)。来源 arXiv:1907.00503v2 [4]
此外,他们在 GitHub 上公布了源代码,稍加修改后将在本文中进一步使用。
应用 CTGAN 生成用于增加列车(半监督)的数据
这对我来说是一种香草梦。在简单了解了 GAN 的最新发展后,我一直在思考如何将它应用到我日常工作中解决的一些问题上。这是我的想法。
任务形式化
假设我们有 T_train 和 T_test (分别为 train 和 test set)。我们需要在 T_train 上训练模型,在T _ test上进行预测。但是,我们将通过由 GAN 生成新数据来增加训练,在某种程度上类似于 T_test ,而不使用它的地面真实标签。**
实验设计
假设我们有 T_train 和 T_test (分别为 train 和 test set)。 T_train 的尺寸较小,可能有不同的数据分布。首先我们在 T_train 上用地面真值标签 step 1 训练 CTGAN,然后生成附加数据T _ synth*(step 2)**。**其次,我们在串联的 T_train 和 T_synth (目标设置为 0)与 T_test (目标设置为 1) ( 步骤 3 & 4 ) **上以对抗的方式训练 boosting。**目标是应用新训练的对抗性增强来获得更像 *T_test 的行。注意——原始地面真相标签不用于对抗训练。因此,我们从 T_train 和 T_synth 中取出按照与 T_test 的对应关系排序的顶行(步骤 5 & 6 )。最后,对它们进行新的增压,并在 T_test 上检查结果。
实验设计和工作流程
当然,出于基准测试的目的,我们将测试没有这些技巧和另一个原始管道但没有 CTGAN 的有序训练(在步骤 3 中,我们不会使用 T_sync )。
代码
实验代码和结果发布为 Github repo 此处。管道和数据准备基于基准分类编码器的文章及其报告。我们将遵循几乎相同的流水线,但是为了速度,只选择了单一验证和 Catboost 编码器。由于 GPU 内存不足,一些数据集被跳过。
数据集
所有数据集来自不同的领域。他们有不同数量的观察,几个分类和数字特征。所有数据集的目标都是二元分类。数据集的预处理很简单:从数据集中删除所有基于时间的列。其余的列要么是分类的,要么是数字的。另外,在对训练结果进行采样的同时 T_train — 5%、10%、25%、50%、75%
数据集属性
结果
从第一眼的角度来看,就度量和稳定性(std)而言,GAN 显示出最差的结果。然而,对初始训练进行采样,然后应用对抗训练,我们可以获得最佳的度量结果和稳定性( sample_original )。为了确定最佳采样策略,对每个数据集的 ROC AUC 评分进行了缩放(最小-最大缩放),然后在数据集之间进行平均。
不同的采样结果,平均值越高越好(ROC AUC),标准差越低越好(100% —每个数据集的最大 ROC AUC)
我们可以看到 GAN 在两个数据集上的表现优于其他采样类型。而在 7 个数据集的 3 个中,来自原始数据的采样优于其他方法。当然也没有太大区别。但是这些类型的取样可能是一种选择。当然也没有太大区别。但是这些类型的取样可能是一种选择。
不同数据集的采样结果,越高越好(100% —每个数据集的最大 ROC AUC)
让我们定义 same_target_prop 等于 1,那么训练和测试的目标比率相差不超过 5%。因此,我们在培训和测试中有几乎相同的目标比率无和样本 _ 原始更好。然而,gan 的表现开始明显好于目标分布变化。**
same_target_prop 等于 1,则训练和测试的目标比率仅相差 5%
参考
1乔纳森·惠。甘— 什么是生成性敌对网络甘? (2018),中条
[2]伊恩·古德菲勒、让·普热-阿巴迪、迈赫迪·米尔扎、徐炳、戴维·沃德-法利、谢尔吉尔·奥泽尔、亚伦·库维尔、约舒阿·本吉奥。生成性对抗网络(2014)。arXiv:1406.2661
3徐磊 LIDS,Kalyan Veeramachaneni。使用生成式对抗网络合成表格数据(2018)。arXiv:1811.11264v1 [cs。LG]
[4]徐磊、玛丽亚·斯科拉利杜、阿尔弗雷多·单面山-因方特、卡莉安·维拉马查涅尼。使用条件 GAN 对表格数据建模(2019)。arXiv:1907.00503v2 [cs。LG]
[5]丹尼斯·沃罗廷采夫。基准分类编码器 (2019)。中等职位
6英萨夫·阿什拉波夫。甘换表 (2020)。Github 仓库。
[7] Tero Karras、Samuli Laine、Miika Aittala、Janne Hellsten、Jaakko Lehtinen、Timo Aila。StyleGAN(2019)arXiv:1912.04958 v2[cs。简历]
***8 Insaf Ashrapov,机器与深度学习博客,【https://diyago.github.io/ ***
LeNet-5 述评:如何设计 CNN 的架构
整合知识以定制 CNN 的架构
这篇文章是对一篇旧的、困难的、鼓舞人心的论文的评论:基于梯度的学习应用于文档识别【1】由 Yann LeCun 作为第一作者。你可以找到这篇论文的许多评论。他们中的大多数只关注卷积神经网络( CNN ) LeNet-5 的架构。然而,我想谈谈其他一些有趣的问题:
- 从反向传播的角度看全局可训练系统的概念
- 如何在神经网络的设计过程中整合知识
事实上,本文中提到了 2 个网络。第一个是 CNN ,名为 LeNet-5,第二个叫图变网络( GTN )。在这篇文章中,我只谈论 LeNet-5。
1.全球可训练系统
什么是全球可培训系统?
一个系统通常包括几个模块。从反向传播的角度来看,如果所有的模块都是可微的,模块之间的连接也是可微的,换句话说,梯度的反向传播可以从末端的损失函数回溯到输入,这是一个全局可训练的系统。有时,我们也称之为机器学习问题的端到端解决方案。
我举个例子:我们想在一个图像中标注所有人脸的性别?第一种解决方案是检测所有人脸的位置,然后用只有一张人脸的子图像进行性别分类。第二种解决方案是创建一个模型,该模型将图像作为输入,输出人脸的定位以及相应的性别。在第一种解决方案中,来自定位的误差影响性别分类的性能。但是如果这两个模块是分开的,我们不能使用性别分类的损失函数来优化定位的性能。在第二种端到端解决方案中,定位和性别检测是全局优化的。
全球可培训系统的优势是什么?
如前所述,我们一起优化所有模块。如果我们有足够的数据,相对于非全局可训练系统,该系统可以实现更好的性能。
另一个更重要的优势是:让机器从数据中学习。如果你熟悉 CNN ,你大概听说 CNN 的前几个隐层可以学习图像的强局部模式。以下是论文【2】中的图片 1 中的一些例子。
图 CNN 图层的可视化
一个训练过的 AlexNet 的第一个 CONV 图层(左)和第二个 CONV 图层(右)上的典型滤镜。(来自https://cs231n.github.io/understanding-cnn/
在传统的解决方案中,我们经常给机器学习模型输入手工设计的特征,如筛、拱、*等。*借助全球可训练系统,我们可以让数据告诉我们,对于某项任务,哪些是最重要的特征。
2.用知识设计 CNN
为了从神经网络中获得自学习特性,我们必须为神经网络设计一个好的结构。Yann LuCun 在他的论文中指出,如果没有关于任务的最少量的先验知识,任何学习技术都不可能成功。….整合知识的一个好方法是根据任务定制架构。现在让我们关注在设计一个 CNN 的架构时如何与知识结合。
1962 年,Hubel 和 Wiesel3揭示了猫视觉系统中的局部敏感、方向选择性神经元。在局部连接的约束下,神经元可以学习一些基本的视觉特征,这些特征可以在下一个神经元中被重用或分组以形成新的特征。卷积核可以很好地实现感受野的这种约束。
在此之前,我们找到了一个很好的工具——卷积核来模拟局部敏感的方向选择性神经元。那么如何才能克服图像分类的一些常见困难:平移、尺度、畸变不变性。
让我们首先检查人类是如何实现图像分类的。我们可能会这样做:
- 用一些视觉模式扫描图像,找到一些特征
- 找出特征之间的关系
- 在我们大脑的模式数据库中搜索关系模式
- 找到最相似的一个
为了实现步骤 1,我们可以为同一个特征图固定卷积核的权重,并生成几个特征图。
为了实现步骤 2,我们认为该特征的确切位置不如该特征相对于其他特征的位置重要。因此,我们可以逐步降低空间分辨率(子采样)。然而,当降低图像分辨率时,我们丢失了信息。这就是为什么我们需要增加特征图的数量,尽可能的保留有用的信息。
有了这些知识,我们就有了设计 CNN 的一般原则。
- 使用卷积核
- 共享权重
- 子采样和增加特征图的数量
3.LeNet 架构
3–1.LeNet-5
图 2:LeNet-5 的架构(来自http://vision . Stanford . edu/cs 598 _ spring 07/papers/le Cun 98 . pdf)
图 21显示了 LeNet-5 的架构。
3–2.增强 LeNet-4
LeNet-4 是 LeNet-5 的简化版。它包含 4 个一级特征图,后面是 16 个子采样图。我们认为 LeNet-4 与 LeNet-5 相比是一个较弱的分类器。Yann LuCun 将助推技术应用于 LeNet-4 ,标记为 boosted LeNet-4 。boosting 方法达到了比 LeNet-5 更好的性能精度。
4.其他有趣的地方
在机器学习的研究领域,我们总是提到开发新方法的三个关键方面。Yann LuCun 在他的论文中也提到了这些:
- 高计算能力的机器成本低
- 大型数据库可用
- 强大的机器学习技术是可用的
我们自己的产品也要考虑这些因素。
5.结论
在这篇文章中,我分享了我对如何设计神经网络的理解。我相信这对实现和修改一个 CNN 的实践是有帮助的。
总而言之:
- 在开始机器学习项目之前,检查计算能力、可用数据库、技术支持。
- 一旦项目开始,尽可能多地获取关于项目的先验知识。
- 利用这些知识来设计您自己的网络。
参考
1 LeCun,Yann and Bottou,Léon and Bengio,Yoshua and Haffner,Patrick 基于梯度的学习应用于文档识别 IEEE,1998
[2] 理解和可视化卷积神经网络
3 D. H. Hubel,T. N. Wiesel,猫视觉皮层中的感受野、双眼互动和功能结构《生理学杂志》,1962 年
跳板数据科学职业生涯回顾
根据我在全职工作期间完成跳板数据科学课程的经验
迪伦·诺尔特在 Unsplash 上的照片
今年早些时候,当我完成了跳板数据科学职业跟踪课程时,许多人联系我,希望了解更多关于该计划、课程和我的体验。这篇文章基于我的个人经历,回顾了我在跳板数据科学课程中的经历。对于一个 TL 来说;版本博士,请随意跳到最后列出的赞成和反对意见。
如今,对于想要向数据科学进行职业转型或只想发展额外技能的工作专业人士来说,在线上有几个免费和付费的选择。我希望这篇文章能帮助那些考虑参加正式数据科学课程的人,了解他们能从跳板项目中得到什么。这应该有助于那些考虑正式项目的人更好地比较跳板和其他项目,并就它是否符合他们的学习目标做出明智的决定。请注意,这篇评论是基于我在 2019 年底/2020 年初参加的“跳板数据科学职业生涯”计划的个人经历。
在开始课程概述之前,我将先介绍一下我的一些背景以及我报名参加这个项目的动机。希望这能让我的观察更准确。当我参加这个项目时,我拥有机械工程博士学位,并在半导体制造行业做了两年左右的工艺工程师。在这一点上,我完成了几个项目,这些项目向我介绍了机器学习,并使我认识到基于人工智能的制造业改进的巨大潜力。因此,我决定发展我的数据科学技能,并更多地接触该领域。我选择了跳板,因为它比完成各种 MOOC 或从在线教程中学习更严格和全面,同时也不像全日制学位那样需要投入太多(也更便宜),此外,我可以在全职工作的同时按照自己的节奏完成它。在这种背景下,让我们进入该计划的概述
计划概述
一旦你注册了这个项目,第一件事就是你将可以通过你的跳板账户访问这个项目的课程。您可以从一开始就访问初始学习模块(除了那些属于专业的模块)。您还可以访问课程跟踪和其他有用的信息,如社区论坛、导师电话通知和其他学生资源。该计划提供了多种资源和工具来帮助您充分利用它。
在整个计划中,课程设计旨在确保您同时在技术模块、职业发展模块和顶点项目上取得进步。最后,一对一的导师支持是跳板最强的卖点之一。接下来,让我们分别看一下这些。
技术课程模块
对于技术课程,springboard 不开发自己的材料,而是组织和提供对网络上其他资源的访问,包括免费和付费的。我觉得这些单元组织得很有逻辑,材料也安排得很好。材料从基本的数据科学技能开始,包括数据解析、数据操作、可视化和基本统计,然后转到不同的机器学习主题。
我发现关于机器学习的材料很好地概述了不同类型的模型,并有助于建立对模型如何工作的直观理解。总的来说,这些材料似乎旨在介绍各种模型,培养对它们如何工作的直觉,并让您使用 python 中的模型库。但是,如果您正在寻找关于特定算法的深入数学理论或实现细节,您可能在课程中找不到。
作为一个职业跟踪计划,该课程很好地涵盖了数据科学家所需的额外技能,包括良好编码实践、测试和调试代码以及生产数据科学模型的模块。
最后,该计划提供了三个专业之间的选择,每个专业在课程的最后 30%都有不同的模块。可用的专业是数据科学通才、深度学习和自然语言处理。我选择 NLP 作为我的专业,并没有直接查看其他专业的材料质量。然而,根据与其他学生的交谈,我了解到通才跟踪更详细地涵盖了推荐系统等模型。我的观察是基于我选择的 NLP 专门化。
顶点工程
我发现顶点计划对于应用我在技术课程中学到的技能非常有帮助。这是发展数据科学投资组合的好机会,这在求职过程中非常有帮助,尤其是如果你打算从一个不同的领域过渡到数据科学工作。
您应该尽早选择第一个顶点项目,并在技术课程的项目上取得进展。除了守则之外,你还需要将你的发现记录成报告,并作为最终提交报告的一部分。
如果您对将数据科学应用于特定领域感兴趣,projects 将允许您从同一领域中选择数据集,以便您可以熟悉该领域中的数据以及数据争论和功能选择的常用策略。
导师支持
跳板的主要卖点之一是一对一的指导。当你报名参加这个项目时,Springboard 会根据你的喜好和你对课程的期望为你安排一个导师。在课程期间,你将定期与导师进行 30 分钟的交流。导师是你的主要资源,用于跟踪你的进展,在你遇到困难时帮助你理解主题,并对你的作业和顶点项目进行评分和提供反馈。
根据跳板网站上的导师简介,我发现导师可以有不同的背景,包括那些拥有数据科学相关领域的高等学位的人,以及那些成功过渡到数据科学的非 STEM 背景的人。我建议你在给导师偏好之前,先想想你的职业目标,以及你期望从导师那里得到什么。从技术上讲,你不能直接选择你的导师。相反,跳板会根据你的喜好和空闲时间为你指派一名导师。然而,我发现跳板团队有助于理解我的偏好,并在项目早期改变指定的导师。
除了指定的导师,您还将获得无限的一次性导师电话。我发现,如果你需要别人给你一个不同的观点,或者如果你发现自己在一周的中途卡住了,不想等到下一次预定的导师电话才能畅通无阻,这些都是有帮助的。
职业发展模块和职业指导电话
该计划的职业发展课程模块穿插在技术模块之间,您需要同时学习这些模块。包含的材料与常见的职业发展主题相关,如更新 Linkedin 个人资料、简历写作和信息面试。由于求职的一个重要部分是建立关系网,你将被鼓励通过信息面试、参加见面会以及接触你所选择的公司或职位描述中的其他联系人来发展你的关系网。
你还将安排与职业教练之一的通话,他们可以查看你的求职材料和策略,并给出个性化的反馈。作为计划的一部分,只要你积极寻找工作,你将有机会获得职业指导,并可以在计划结束后的六个月内安排模拟面试。
其他工具和资源
除了前面提到的,你还可以参加每周的办公时间,观看其他学生的顶点项目演示或询问一般性问题。您还可以访问论坛或参加同龄人学习小组,这是与其他学生交流和集思广益项目想法的良好资源。他们还在旧金山湾区举办了一场名为“跳板崛起”的面对面会议/社交活动。
最后,总结一下,对于任何想要发展自己的数据科学技能并转向数据科学职业的人来说,Springboard 提供了一个全面且精心策划的计划。您可以利用多种资源进行职业发展和人际交往,同时发展您的技术技能和创建项目组合。然而,预期的时间承诺显然高于典型的 MOOC,你需要通过初步的技能评估才能加入该项目。
利弊
优点
- 与 MOOC 课程相比,课程更加广泛和全面。所以,这可能更可信,尤其是对于那些无法重返校园的人来说
- 本课程有机会参加论坛、同行学习小组和面对面的交流活动,这有助于了解更多关于数据科学社区的信息,并与其他可能也想进入该领域的同行建立联系
- 课程是有条理地策划和组织的。非常适合那些刚进入该领域并试图快速建立数据科学各方面基础的人
- 你将承担责任。有一个跟踪器,以及每周检查与导师。这会让你更容易在缺乏动力的时候保持一致
- 选择专业的能力。对于最后几个模块,你将能够根据兴趣和职业目标专攻三个方向中的一个:自然语言处理、深度学习和多面手机器学习
缺点
- 价格昂贵。虽然你确实以这个价格获得了很多资源,但是如果你不太可能使用所有的资源,可能会有更好的选择
- 课程主要使用 Python 及其库开发。如果你喜欢或想学习 R 或其他编程语言,这可能不适合你
- 与导师相处的经历可能会有所不同。网站上列出的导师具有广泛的背景,从基于机器学习的学科的博士到过渡到数据科学的非 STEM 专业的学生。一定要让跳板团队知道你的偏好和你在寻找什么,这样你就可以找到最能帮助你的人
加州大学伯克利分校信息与数据科学硕士(MIDS)项目述评
是否值得你 2 年的时间和 7 万美元的积蓄
我花了 2.5 年时间从加州大学伯克利分校获得了信息和数据科学硕士学位,同时还全职工作(2017 年 8 月-2019 年 12 月)。网上似乎没有足够全面的评论,所以我想分享我的经验,以帮助那些对申请或参加该计划感到不确定的人。
**免责声明:**我写这篇文章是出于我的真实想法,我没有从任何第三方那里得到任何报酬来提供这样的评论。
目录
- 计划概述(以及该计划面向谁)
- 学费和费用
- 课程结构和内容(以及我对其中一些的选择)
- 计划利弊
节目概述
我第一次听到 MIDS 节目是在我还是一名大专学生的时候。当时,我相信一个神话,即像 MIDS 这样的非全日制在线硕士学位不是一个“真正的学位”。直到进入真正的工作环境几年后,我才意识到兼职项目的无与伦比的好处——很难为了获得硕士学位而牺牲工资以及几年宝贵的工作经验。在我被录取的几个项目中,我选择了 MIDS 大学,因为它的声誉很好。
MIDS 的班级简介(链接这里)是动态的。学生们来自各种不同的行业:农业、航空航天、建筑、零售、制药、保险、金融、科技……应有尽有。我的大多数同学都是作为兼职学生加入的,少数人是全日制的。但是几乎每个人都有几年的工作经验。当聆听他们的项目演示并了解数据科学如何应用于不同行业时,这绝对是一次大开眼界的经历。另一个优势是与其他在职专业人士建立联系——我们有学生分享他们当前公司职位空缺的松散渠道,我们中的许多人很乐意做内部推荐。人脉绝对是一个可以也应该被明智使用的东西。
总的来说,我认为 MIDS 适合那些确定要成为一名数据科学家的人(毕竟这不是一个便宜的项目),那些准备好弄脏自己的手(涉及大量编程)的人,以及那些有一份他们想要保留的日常工作的人。
学费和费用
这是一个 27 个单元的项目(3 个单元/课程= 9 门课程)。每个单位的现行费率是 2573 美元。除此之外,你还需要支付每个春季或秋季学期 728.5 美元的校园费(是的,校园费,即使是在线项目),以及每个夏季学期 349 美元的夏令营费。完成该项目的总成本约为 7 万美元。一些经济援助和融资方案可供选择,详情见此处。
课程结构
那么 7 万美元能换来什么呢?这是我从复制的课程列表,这个链接,红色的复选标记是我选择的:
每个人都需要基础课程和顶点课程。但是如果你以前有 Python 编程的知识,你可以请求跳过“数据科学编程入门”并节省 3 个学分来选择一门更高级的课程。
每周你被要求观看一系列预先录制的视频并完成一些阅读,这是一种标准的“翻转课堂”方法。然后每周将有 1.5 小时的在线直播讲师课程,每节最多 15 名学员。作业通常每 2 ~ 3 周进行一次,助教的办公时间会不时安排。大多数课程都需要一个你可以和其他同学合作的期末项目。
以下是我对我参加的每门课程的看法。如果你对完整的课程描述感兴趣,请点击链接。
**免责声明:**学校不断重组课程内容,所以自从我参加以来,事情可能已经发生了变化。
- 数据科学编程入门
这是一个纯 Python 编程类。对我来说,花费 7719 美元仅仅是为了学习一门你可以通过其他免费资源熟悉的语言,这听起来有点疯狂,但是因为无论如何都需要 27 个单元才能毕业,所以对于那些想要结构化指导的人来说,学习 Python 仍然是有价值的。如果你已经知道什么是面向对象编程,熟悉动态类型、可变/不可变(仅举几个例子)等概念,并且了解如何编写函数、类、装饰器、列表理解等,你可以安全地跳过本课程。否则,这是一门建立坚实编程基础的伟大课程(这对其余课程来说超级重要)。
- 数据与分析的研究设计与应用
课程名称可能有点误导,因为这门课没有教你,比如假设检验,或者计算研究样本大小的数学公式。相反,这是一门讨论一般主题的课程,如决策和研究论文中的偏见,讲故事和数据可视化的原则等。尽管指定的阅读材料有时会很有启发性,但许多学生认为这是最“没用”的课。我也不太喜欢这门课,但它确实帮助我培养了一些商业头脑。
- 数据科学统计
这是 MIDS 项目中第一门真正的数据科学课程,它涵盖了统计领域中最基本的概念,包括概率论、假设检验和线性回归。如果你有统计学背景,你可以参加一个豁免考试来跳过这门课。
- 数据工程基础
我相信这门课在我上完之后已经重新组织过了,但是它背后的基本概念是帮助你理解一些基本的数据工程术语和工具。这些知识可能是必不可少的,因为全栈数据科学家将与数据工程师密切合作,因此应该熟悉数据基础设施管道。本课程为您提供了一个很好的起点:它教授命令行编程、使用 docker、Kafka 等的基础知识,以及 Google BigQuery 中的 SQL 语法。
- 应用机器学习
这绝对是我最喜欢的课程之一!我的导师是一位知识渊博的数据科学家,在各种科技公司有 10 多年的工作经验。该课程涵盖了最常用的数据科学算法(带有代码示例),如 KNN、K-means、朴素贝叶斯、树模型(决策树、随机森林、梯度推进)、神经网络(非常基本的概念),以及一些特定的主题,如社交网络模型和推荐系统。这门课程节奏很快——毕竟在一个学期内完成所有这些主题不是一件容易的事情。所以不要期望在这门课之后成为所有这些算法的专家。这门课只是为了让你直接进入数据科学的世界。
- 云端和边缘的深度学习
这是数据工程基础的高级课程。该课程讲授使用 IBM Cloud 和 NVIDIA Jetson 设备在 GPU 上运行深度学习包(如 OpenCV)的基本概念。对于那些没有软件工程背景的人来说,无疑有一点陡峭的学习曲线。由于课程更侧重于尝试不同的工具,而不是解释深度学习背后的概念,所以它不会让你成为深度学习专家。相反,它给了你一个窥视计算机视觉世界的机会。
- 机器大规模学习
这是另一门介绍大数据概念的精彩课程。它不仅教你并行计算、MapReduce 图和 Hadoop 系统的基本思想,还为你提供了大量练习 PySpark 编程的机会。唯一的小缺点是,它过于关注 PySpark RDD,而对 PySpark 数据框架关注太少,这意味着您需要花一些时间自己填补知识漏洞。
- 自然语言处理与深度学习
这是 MIDS 项目中最难最耗时的课程,我希望他们能把 NLP 和深度学习分成两个不同的班级!应用机器学习课程向你介绍了神经网络的粗浅想法,这门课很快就跳到了 CNN 和 RNN 背后的复杂概念。幸运的是,导师是斯坦福大学 NLP 小组的博士后,他为我们提供了很好的材料来浏览这些主题。此外,还有大量的助教工作时间。但是,如果你想掌握这个话题,还是要准备好把你所有的空闲时间都投入到课堂中。此外,Tensorflow 在整个课程中被大量使用,讲师花了很大的努力来确保我们对 Tensorflow 操作感到舒适。我相信如果他们选择 Keras 而不是 Tensorflow,课程可能会更容易一些。但总的来说,这是一门非常值得推荐的课程,你肯定会从中学到很多。
- 顶点
在顶点课程中,学生组成 3 或 4 人小组,提出自己的数据科学项目。我的团队的顶点项目是语音情感分析,我们开发了一个应用程序来部署我们的模型——实际上,你会发现团队建立网站或应用程序来托管他们的模型是非常常见的,你会惊讶地发现,你的许多同学都有能力进行前端/后端开发。Capstone 提供了一个很棒的沙盒环境,不仅可以思考现实世界中数据科学知识的用例,还可以实践产品开发和模型部署。我班上的两位导师都有很强的背景——一位是风投,另一位是一家财富 500 强咨询公司的董事。
- 沉浸
上面的列表中没有显示的一件事是一个 3 天的沉浸式项目。这是一次必修课,但是学生可以自由选择他们想参加的学期。在沉浸式学习期间,将围绕数据和领导力相关主题举行不同的讲座和工作会议。学生们也可以参加一份名单中的两家公司的参观,但这些公司通常是中等规模的。顺便说一句,你负责支付机票和酒店费用,以参加浸泡。
利弊
我在前面的章节中已经提到了很多优点。总的来说,我认为 MIDS 计划涵盖了大多数重要的数据科学概念。大多数教师都有很强的背景,所以你会真正得到专家的指导(教师简介可以从这里查看)。与此同时,MIDS 非常重视学生的意见,我看到他们根据调查反馈更换教师和重新安排课程内容。
对于缺点:首先,没有课程介绍非参数统计,如贝叶斯统计或蒙特卡洛。其次,有些课程没有达到我希望的深度,因此需要大量的自学。第三,我发现有些课程的预录视频很混乱,很干涩。在某个时候,我完全放弃了观看预先录制的视频,转而观看吴恩达的机器学习课(链接此处),并认为这是对我时间的更好利用。最后,MIDS,说到底,是一个服务于繁忙职业的在线项目。与常规的体育项目相比,很难与你的同学和讲师建立亲密的友谊。
MIDS 不是一个会教你每个算法背后的数学公式的程序。相反,它非常强调编程和数据科学工具和库的实际用例。它为你打开了数据科学世界的大门,但之后的路还很长。
希望这篇文章对你有所帮助。如有疑问和评论,我们连线 Linkedin 和 Twitter 。
外部链接
- **班级简介:**https://datascience.berkeley.edu/experience/class-profile/
- 学费和助学金:https://data science . Berkeley . edu/admissions/tufty-and-Financial-Aid/
- 课程概况:https://cdn 2 . data science . Berkeley . edu/content/a9aa 839d 412d 4c 4 e 9d 5225 a2 e 46 f 18 f 6/UCB-MIDS _ MKTGWEB-36794 _ One-Pager _ General _ 2020-02 _ WEB _ 1 . pdf?_ ga = 2.2458225669-256986536367
- 课程简介:http://guide.berkeley.edu/courses/datasci/
- 教员简介:https://www.ischool.berkeley.edu/people?role=122
回顾:SAS Cortex 分析模拟竞赛
借助 SAS Enterprise Miner 了解预测分析
SAS 和 HEC Montréal 的 Cortex Analytics 模拟
2020 年 4 月底至 5 月初,我参加了由 SAS (ANZ)与 HEC Montréal 合作举办的Cortex Analytics Simulation竞赛。该比赛面向所有人,特别是学生,他们希望探索预测分析在现实世界中的应用。
我不会对游戏进行过多的描述,因为我不想透露未来比赛的可能答案,但我想说,使用 SAS Enterprise Miner 学习预测分析是一次很好的体验。
如果你遇到了比赛,并想了解更多,这篇文章介绍了游戏场景、说明和我在整个比赛中的个人经历。
方案
你正在为一个拥有 100 万会员的非营利慈善组织进行筹款活动。基金会决定在其营销活动清单中增加一项直接联系活动。我们的目标是在给会员打电话的情况下筹集最多的捐款。这将通过使用预测建模软件(SAS Enterprise Miner)来完成,以预测活动中的目标人数和目标人群。
您将获得潜在捐赠者的数据集。您将根据捐赠者以前的行为拟合不同的模型,对捐赠者进行评分以预测今年的捐赠。利用这个结果,决定有多少潜在的捐赠者。上传您的 id 列表,该列表将根据运营盈余:捐款总额-致电总成本对提交的 id 进行排名。我创建了一个表格,列出了下面给出的一些信息。
表 1:列出了一些变量,表 2:联系成员的成本
每日网络研讨会和说明
由于这是一个介绍性的比赛,参与者将获得详细的游戏说明,并可以参加每天 1 小时的网络研讨会(由 SAS 提供)。
这些网络研讨会包括讲解说明的演示和问答环节。我们有两种不同的建模方法:
- “1 阶段建模”:一个简单的模型,根据捐赠者的预计捐赠金额对其进行评分。
- “两阶段建模”:一个更复杂的模型,既考虑了给予的概率(接触与否)又考虑了预测金额。
当然,两阶段建模过程更有效。它通常被称为提升建模,其中提升是通过计算预测金额之间的差异来计算的,该差异考虑了联系或不联系某人时的捐赠概率。
我强烈建议您参加这些网络研讨会,因为它们有助于您更好地浏览 SAS Enterprise Miner,学习不同的建模技术,并提出您可能有的任何问题。
竞争
竞赛是通过 SAS 虚拟机/实验室完成的。你有总共 20 个小时的时间在 5 天内测试不同的模型并上传你的结果。因为它是在云中的一个虚拟机上,所以你需要预订,这需要大约 25 分钟的启动时间。你提交答案的次数也有限制(大约 30 次)。
在比赛期间,你的目标是测试不同类型的机器学习模型,以预测概率或捐款金额。SAS Enterprise Miner 的布局一开始可能会很吓人,这就是为什么最好按照网上研讨会的说明进行操作。
SAS Enterprise Miner 使用一个简单的拖放系统,您可以添加不同的节点并将它们连接到其他节点。这使得学习如何使用软件和测试新模型变得很容易。图的大部分已经为您完成,您的主要任务是测试不同的模型并调整它们的属性。
一些模型包括决策树、回归、神经网络和梯度推进。他们还拥有高性能(HP)数据挖掘节点,这些节点使用了传统方法中没有使用的几种技术(这些可能需要更长的运行时间)。您将花费大部分时间放置不同的模型,并放置模型比较节点来检查哪个模型执行得最好(平均平方误差最低)。
图表流程(类似于 SAS Enterprise Miner)
上面显示了我在 SAS Enterprise Miner 中创建的一般图表:
- 初始数据准备:合并数据。
- 数据分区:数据被分成训练集和验证集。
- 建模:添加不同的模型,修改其属性(这里我们展示的是回归和决策树)。如果您使用复杂的模型(比如 HP 节点),这个阶段可能需要几分钟甚至几个小时。
- 型号对比:对比各型号并显示其性能。
- 评分数据准备:根据使用的模型对新数据进行评分。
- SAS 代码:将预测导出到 Excel 文件。
收到 Excel 文件输出后,您的工作是对数据进行排序,收集您想要使用的 id 数,并提交结果。你会马上看到你提交的潜在捐赠者名单的表现。
我发现特别有用的是,看看竞争中的其他参与者瞄准了多少捐助者,这样你就可以知道你可能收集到多少钱。您大部分时间都在摆弄不同的模型,所以最好添加不同的模型变体来找到性能最佳的模型。例如,您可以使用逻辑回归代替线性回归,或者增加决策树的复杂性。您可以尝试的其他方法是移除或转换变量。
结论
最终,我在比赛中获得了第三名,与 1000 澳元的最高奖金失之交臂。我认为,如果您想更多地了解 SAS Enterprise Miner 以及如何将其用于预测分析,参加 SAS Cortex Analytics 模拟竞赛可能是一个很好的开始。尽管你必须付费才能参加比赛,但如果你错过了第一名,你可以在网上(或通过面试)分享你的经验,并在 Acclaim 上展示你的参与者徽章。
我的皮层参与者徽章发出喝彩
感谢阅读!
欢迎在 LinkedIn 上联系我,或者在 Medium 上关注我。我希望发布更多与数据科学相关的内容。
在 Udacity 上查看 Google 的 A/B 测试课程
阅读了解谷歌是如何进行 A/B 测试的。
A/B 测试是在线实验,用于测试网站或移动应用程序的潜在改进。这个实验需要两组——控制组和实验组。控制组的用户看到的是现有的网站,而实验组的用户看到的是改变后的网站。然后对结果进行比较,并对数据进行分析,以确定变革是否值得启动。谷歌与 Udacity 合作的 A/B 测试课程解释了分析时需要考虑的各种指标,如何利用统计的力量来评估结果,以及最终是否必须启动变革。本课程不深入研究统计概念,而是解释这些测试的商业应用。
A/B 测试被许多公司广泛使用。例如,亚马逊用它来测试用户推荐功能,谷歌广泛使用它,他们曾经用它来测试 UI 中 41 种不同深浅的蓝色!虽然这个术语是最近才出现的,但这种方法已经在实践中使用了很长一段时间。农民用它来判断哪种方法能获得最好的收成,医生用它来进行临床试验,以检查药物的有效性。
贷项: Unsplash
政策与道德:
在进行 A/B 测试之前,必须考虑几件事。
- 风险:参与者在参与测试时承担什么风险。最小风险被定义为参与者在日常生活中可能遇到的伤害的概率和程度。如果风险超过这一限度,则必须告知参与者。
- 益处:能够陈述完成研究的益处是很重要的。
- 备选方案:用户可能拥有的其他备选服务,以及在时间、金钱、信息等方面的转换成本。
- 数据敏感性:指所收集的数据,是否会泄露个人身份,为保护数据所采取的安全措施,以及数据公开后可能对个人产生的影响。
选择和表征指标:
这些指标可以分为两类。不变的度量是那些应该在两个组中保持相同的度量。例如,两组中的人数,基于人口统计学的分布。评估标准是你用来衡量实验有效性的标准。例如,如果您正在测试点击“开始按钮”的用户数量的变化,点击率(点击的独立访问者数量/独立访问者总数)可以作为您的评估指标。执行健全性检查是为了检查您选择的不变指标是否正确。可以执行 A/A 测试来检查这一点。
还必须考虑灵敏度和鲁棒性。该指标既不应该过于敏感,也不应该过于稳健。均值可能对异常值过于敏感,而中值可能过于稳健而无法捕捉变化。第 90 或第 99 个百分位数被认为是注意变化的良好指标。为了在灵敏度和鲁棒性之间找到良好的平衡,可以进行 A/A 测试,使用以前实验的数据或对日志进行回顾性分析。
设计实验:
分流单位 用于定义实验中的一个人。
- 用户 id :如果一个人登录了账户,我们可以用用户 id 作为转移的单位来跟踪活动。
- Cookie :是一个网站发来的一小段数据,在用户浏览的时候,由用户的网页浏览器保存在用户的电脑上。Cookies 是特定于浏览器的,也可以由用户清除。
- 基于事件的分流:任何动作,比如重新加载页面,都可以被认为是一个事件。这些主要用于用户不可见的更改。例如,等待时间变化。
**人群:**你还必须考虑你将要进行实验的人群,是整个人群,还是来自某个特定地区或某个特定部门的人群。
**规模:**人口规模也是一个重要因素。它受显著性水平(α)、灵敏度(1-β)以及分析单位是否等于分流单位等参数的影响。
**持续时间和曝光:**指您想要运行实验的时间段。此外,确定何时进行实验也非常重要。例如,在周末或工作日,假日或非假日季节。一般来说,在两者之间取得平衡是有好处的,这样你可以更好地理解趋势和季节性效应。暴露程度基本上是您想要将新功能暴露给的人群的比例。
分析结果:
健全性检查:在你拿到实验结果后,你要做的第一件事就是检查你的不变指标在两组中是否相同,比如人口分布是否正确。
**单一指标:**要检查单一不变指标是否在可接受的范围内,您必须计算合并的标准误差,并将其乘以 Z 值(95%置信区间为 1.96),然后找出误差范围。然后找到下限和上限,并检查特定指标值的差异是否在范围内。
您还应该对评估度量执行测试,以检查结果是否在统计上和实践上都有意义。对于具有统计显著性的结果,差值的范围不得包含 0,对于具有实际显著性的结果,该范围不得包含实际显著性界限。此外,为了再次检查结果,可以进行符号测试。如果两个测试彼此不一致,我们可能需要更深入地研究数据,因为这可能是由于辛普森悖论(单个亚组显示出稳定的结果,但它们的集合导致了问题)。
**多个指标:**如果您同时考虑多个指标,您可能会因为误报而认为其中一个指标很重要。为了解决这个问题,你可以使用自举或 bonferroni 校正。
分析完结果后,你必须回答几个问题,比如变化是否显著?我了解这种变化的影响吗?在审查其他业务因素后,变革是否值得启动?在此基础上,您可以启动变更,执行更多的测试,也可以不启动变更。您可能需要在前期和后期执行 A/A 测试,以进行健全性检查,并查看更改对用户的影响。
结论:
Google 在 Udacity 上开设的 A/B 测试课程是任何想了解 A/B 测试流程的人的必选课程。最后的项目可以进一步帮助你理解这些概念。这只是课程的概述。
免费课程由在线实验设计和分析开始免费课程关于本课程,本课程将涵盖…
www.udacity.com](https://www.udacity.com/course/ab-testing–ud257)
回顾 Deepnote——数据科学家的新 IDE
使用 Deepnote 开发 Python 课程后的感想
声明:我绝不隶属于 Deepnote 或其任何成员。
Deepnote 是一个的免费在线数据科学笔记本,主要关注协作(实时、谷歌文档、协作类型)和所有概念的抽象,以及妨碍工作的工作——环境和基础设施设置。
这家初创公司最近宣布,它筹集了 380 万美元的种子资金,由 Index Ventures 牵头,包括 Greg Brockman 和 Naval Ravikant 等天使投资人。
看了 TC 的公告后,我很想试一试。我报了内测,耐心站了五个(!)几天后,我收到了邀请函。
我登录了,在平台上折腾了大约一个小时,尝试了一些示例项目,仅此而已。
Deepnote 的示例项目
几个月后,我一位在金融行业工作的好朋友 Rodrigo Tadewald 邀请我共同创建一个主要使用 Python 的在线课程。我很可能会负责本课程的环境设置/编程/性能方面的主题。
我非常高兴地接受了邀请,因为我对金融话题非常感兴趣,而且从未制作过在线课程。然后我有了尝试 Deepnote 的想法,并开始用它开发所有的 Python 课程笔记本。
声明:我主要使用了 Brave 浏览器,仅使用其他浏览器来验证它何时出现一些奇怪的行为(Brave 浏览器运行在 Chromium 引擎上)。在项目开发过程中,我也曾交替使用 OSX、Ubuntu 和 Windows 机器。
体验
为了开始这个项目,我上传了一些我以前在现场课程中用过的旧笔记本,然后开始创建这个项目。Deepnote 还提供了从 GitHub 和 GitLab 导入存储库的选项,使得设置变得非常容易。
随着我对这个平台越来越熟悉,CTRL/⌘ + P 成了我做事的主要方式。
指挥托盘
它可以很好地执行截图中的命令,但它的查询功能并不能让我 100%满意。我在文件夹中查找文件时遇到了一些问题,这真的很痛苦,因为我的项目主要是用文件夹和子文件夹来组织的。
在 项目 选项卡中可以看到您的项目文件,添加新文件,添加数据连接,以及访问终端。
Deepnote 的侧边导航,带有标签和可变浏览器(以及葡萄牙语的课程迷你剧透:)
笔记本本身还是挺有意思的,有一些很酷的功能。我真的很高兴看到减价备忘单很容易找到。
IDE 可以自动检测模块,您可以轻松地动态安装pip
包。如果您使用!pip
命令,Deepnote 会将它保存在一个隐藏文件中,并在每次环境启动时安装它。您也可以选择创建一个requirements.txt
文件,并通过 终端 与之交互
变量资源管理器是一个很好的特性,它已经集成了一些度量标准,真的给了它一个很好的触感。
变量浏览器中的熊猫数据框
代码智能 特性,比如自动完成和定位定义,在当前的测试版中表现不佳。
改进:在我的项目开发过程中,我注意到一件重要的事情,那就是文件浏览器的性能有了显著的提高。由于我上传了很多文件,我需要将它们组织到文件夹中,几周前,在文件夹和子文件夹中移动文件是一种非常落后的体验。自 2020 年 4 月左右球场开始开发以来,这种情况有了很大的改善。不错!
在一些课程模块中,我需要处理数据。不是巨大的数据集,但足够大,如果我不得不重新上传到平台上,我会不高兴。Deepnote 有一些集成的数据集,如 Landsat 8 和 Goodreads books,但对于我的项目,我需要使用我已经准备好的自定义数据集。
此外,除了从您的本地系统上传文件之外,还有一种方法可以集成(至少在我的 beta 帐户上) AWS S3 ,MongoDB和Postgres。有很多“灰色”的选项,但我想念 Azure storage 和 Google Drive 的集成,主要是因为对于 Google Colab 用户来说,随便尝试 Deepnote 肯定会少很多麻烦。
创建与 IDE 的新连接
在设置好数据连接之后,我用 终端 做了一点小改动,它给了你对机器的完全根访问权限,但是我并不认为这个项目需要它。我想我唯一一次跑到终端是在 Deepnote 内核进入重启循环的时候,我试图用一些 bash 命令修复它。
转到 环境 标签,你可以选择机器配置,重启它,查看 CPU 和 RAM 的使用情况,检查你的项目所依赖的包。
免费提供的机器配置如下:
- 基本 —英特尔 Haswell 1vCPU ~1.5GB RAM 无 GPU
- Pro —英特尔 Haswell 2vCPU ~5GB RAM 无 GPU
还有一种性能配置,可根据要求提供:
- 性能 —英特尔 Haswell 4vCPU ~12GB RAM T4 GPU
最后但同样重要的是还有 评论 标签。Deepnote 上的通信功能非常先进,虽然这个课程主要是一个单独的项目,但有时我会友好地请求一个朋友查看它的一些笔记本,我没有失望。
我们可以进行代码评审的实时会议,并与注释进行异步交互。这为数据科学家在异步或同步时间表上一起远程工作提供了很大的优势。远胜于我在其他笔记本平台上的任何其他协作体验。
结论
Deepnote 已经解决了成为数据科学团队首选 IDE 的挑战,与一些非常好的和已经建立的替代产品竞争。
它的核心优势是以协作为中心的方法,这种方法脱颖而出,为数据科学家提供了真正的 Google Docs 体验。
我敢肯定“看起来很有趣”的功能目前正在被团队修复,一些功能的实现,如版本控制、团队、仪表板和笔记本的 API 共享,也正在进行中。
如果你对这个平台感兴趣,我建议你尝试一个项目,在这个项目中,协作是关键,也许是和你的一些朋友或同事。这样,你就可以提取平台提供的真正价值。
如果您是 Python 或笔记本环境初学者,Deepnote 是一个非常容易的入门方式。
对于数据科学团队,我会鼓励他们在新项目中使用它,并与 Deepnote 人员保持联系。你可以使用集成的聊天工具与团队交流,这很有帮助(因为它是测试版,所以它有测试版的功能:)
我会定期更新这个帖子,回顾新的功能,所以实际上我在这里写的很多东西将来都可以改变。
我希望你喜欢阅读这篇文章。
如果你有,考虑在Twitter上关注我。
谢谢你的时间。保重,继续编码!
复习基本概念
深度强化学习讲解— 12
数学符号已更新
这篇文章是*深度强化学习讲解系列的新部分的序言,在这里我们将介绍强化学习经典方法的实现,如蒙特卡罗、SARSA 或 Q-learning 等。在本帖中,我们将回顾和更新以前帖子中介绍的数学符号。*
访问第 3 页的自由介绍
medium.com](https://medium.com/aprendizaje-por-refuerzo/3-funciones-de-valor-y-la-ecuaci%C3%B3n-de-bellman-7b0ebfac2be1)
数学符号复习
在帖子 2 中,我们已经看到,我们可以使用马尔可夫决策过程(MDP)作为我们希望通过强化学习来解决的问题的正式定义。MDP 由 5 个参数 < S,A,R,p,γ >, 定义,其中每个参数表示:
- —一组状态
- 一个 —一组动作
- R —奖励功能
- p —过渡函数
- γ —贴现因子
请记住,我们倾向于使用理查德·萨顿和安德鲁·g·巴尔托所著的教科书 强化学习:导论 中的符号。这本书是一个优秀的强化学习基础介绍的经典文本。
我们在以前的文章中介绍的主要定义和数学符号是:
连续任务的折扣率
在继续之前,让我们简单地补充一下贴现率在一个连续任务中的表现,这在以前的帖子中没有涉及。
继续任务示例
在本系列的第 1 部分中,我们使用了一个临时任务,即冰湖环境,这是一个来自 OpenAI Gym 的简单网格世界环境,是一个用于开发和比较 RL 算法的工具包。在这一节中,我们将使用另一个环境介绍一个持续的任务,即车杆平衡问题:
使用角度和角速度的车杆平衡(来源)
如前图所示,一辆手推车沿水平轴放置在无摩擦的轨道上,一根柱子固定在手推车的顶部。目标是通过向左或向右移动小车来防止杆倒下,并且不要从轨道上掉下来。
通过对手推车施加+1(左)或-1(右)的力来控制该系统。钟摆开始直立,目标是防止它翻倒。柱子保持直立的每个时间步提供+1 的奖励,包括该集的最后一步。当柱子偏离垂直方向超过 15 度,或者手推车偏离中心超过 2.4 个单位时,该集结束。
该环境在每个时间点的观察空间是 4 个数字的阵列。在每个时间步,你可以观察它的位置,速度,角度和角速度。这些是这个世界的可观察状态。您可以在本文档的中查找这些数字的含义。请注意小车速度和尖端极点速度的最小值(-Inf)和最大值(Inf)。由于数组中对应于每个索引的条目可以是任何实数,这意味着状态空间是无限的!
在任何状态下,小车只有两种可能的动作:向左移动或向右移动*。换句话说,车极点的状态空间有四维连续值,而动作空间有一维两个离散值。*
贴现率
在我们继续任务的例子中,哪个贴现率会鼓励代理尽可能长时间地保持极点平衡?
*在任何贴现率 *γ > 0 的情况下,代理人在极点尚未倒下的每个时间步获得正奖励。因此,代理将尽可能长时间地保持极点平衡。
然而,想象一下,奖励信号被修改为仅在一集结束时给代理人奖励。换句话说,除了最后一个时间步,当剧集结束时,每个时间步的奖励都是 0,然后代理人获得+1 的奖励。
在这种情况下,如果折扣率为 γ= 1,代理人将总是获得+1 的奖励(无论它在该集期间选择什么行动),因此奖励信号不会向代理人提供任何有用的反馈。
如果折扣率为 γ < 1,代理将尝试尽快终止该集(通过快速放下杆或离开轨道边缘)。因此,在这种情况下,我们必须重新设计奖励信号!
这个问题的解决方案是由策略决定的,这意味着为了追求一个目标,代理需要学习一系列的动作。在下一节中,我们将进一步讨论这个问题解决方案的正式定义。
政策
策略是代理用来基于当前状态确定下一个动作的策略(例如,一些规则集)。一般用*【𝜋(𝑎|𝑠】、希腊字母 pi 表示,一个策略是决定下一个动作采取给定状态。*
最简单的策略是从环境状态集到可能动作集的映射。我们称这种策略为确定性策略*。但是在第二篇文章中,我们也介绍了𝜋(𝑎|𝑠政策可以被定义为概率,而不是具体的行动。换句话说,这是一个随机策略,它对代理在给定状态下可以采取的行动有一个概率分布。*****
随机策略将允许代理随机选择行动。更正式地说,我们将随机策略定义为接受环境状态和动作并返回代理在状态 S:****
在学习过程中,随着代理获得更多的经验,策略𝜋可能会改变。例如,代理可以从随机策略开始,其中所有动作的概率是一致的;与此同时,代理将有希望学会优化其策略,以达到最优策略。
现在我们知道了如何指定一个策略,我们可以采取什么步骤来确保代理的策略是最好的?我们将使用在第二篇文章中已经介绍过的状态值函数和动作值函数。
价值函数
状态-价值函数,也被称为价值函数*,甚至是 V 函数,衡量每个状态的好坏,它告诉我们如果我们从那个状态开始,我们未来可以预期的总回报。***
对于每个状态 s ,状态值函数告诉我们期望的贴现回报 G ,如果代理在该状态 s 开始,然后使用策略为所有时间步骤选择其动作。重要的是要注意,状态值函数将总是对应于特定的策略,所以如果我们改变策略,我们改变状态值函数。出于这个原因,我们通常用小写的 v 来表示函数,在下标中用相应的策略 𝜋 来表示,并正式定义为:
其中𝔼[ ]表示给定代理遵循策略 𝜋 时随机变量的期望值,而 t 是任意时间步长。正如我们在第 8 篇文章中介绍的,它用于𝔼[.的预期因为环境转移函数可能以随机的方式起作用。
同样在 post 2 中,我们将状态-值函数的定义扩展到状态-动作对,为每个状态-动作对定义一个值,这被称为动作-值函数,也被称为Q-函数或简称为 Q. 它定义了在一个策略下,在状态中采取动作的值******
在整个系列中,我们将交替使用值函数的大写或小写符号:或 v(s) 和 Q(s,a) 或 q(s,a)
贝尔曼期望方程
对于一个一般的 MDP,我们必须根据一个期望来工作,因为直接的回报和下一个状态很难被确定地预测。的确,我们在前面的帖子里看到,奖励 r 和下一个状态s’都是根据 MDP 的单步动态来选择的。在这种情况下,当从(条件)概率分布p(s’,r ∣ s,a ) 中得出 r 和 s 时,贝尔曼期望方程根据期望的即时报酬和期望的来表达任意状态 s 的值****
对于一般情况,当代理的策略 π 为随机时,代理在状态 s 时以概率π(a∣s)选择行动 a ,贝尔曼期望方程可以表示为:**
在这种情况下,我们把下一个状态的奖励和贴现值之和(r+γvπ(s’)乘以其对应的概率π(a∣s*)p(s【t57’,r∣s*****
我们还有作用值函数的贝尔曼方程:
最优策略
代理人的目标是在长期内最大化总的累积报酬。使总累积报酬最大化的策略称为最优策略**。在第 8 篇文章中,我们介绍了“最优”价值函数。**
当且仅当对于所有的 s ∈S,vπ′(s)≥vπ(s)时,策略 π 被定义为优于或等于策略 π 最优策略肯定存在,但可能不是唯一的。
所有最优政策都有相同的状态值函数v∑**,称为最优状态值函数。最佳状态值函数的更正式的定义可以是:**
对于动作值函数:
所有最优政策都有相同的行动价值函数q∑**,称为最优行动价值函数。**
这种最优行动值对于获得最优策略非常有用。代理通过与环境交互来估计它。一旦代理确定了最优动作值函数q∫,它可以通过设置以下参数快速获得最优策略π∫:
正如我们在第 8 篇文章中看到的,贝尔曼方程用于在算法中找到价值函数的最优值来计算它们。更正式的表达可以是:
下一步是什么?
我们已经到达这篇文章的结尾了!。在接下来的这篇文章中,我们将介绍蒙特卡罗方法,这是一种估计价值函数和发现最优策略的学习方法。
下期见!**
深度强化学习讲解系列
一个轻松的介绍性系列以一种实用的方式逐渐向读者介绍这项令人兴奋的技术,它是人工智能领域最新突破性进展的真正推动者。
本系列的内容](https://torres.ai/deep-reinforcement-learning-explained-series/)
关于这个系列
我在五月开始写这个系列,在巴塞罗那的**封锁期。**老实说,由于封锁,在业余时间写这些帖子帮助了我 #StayAtHome 。感谢您当年阅读这份刊物;它证明了我所做的努力。
免责声明 —这些帖子是在巴塞罗纳封锁期间写的,目的是分散个人注意力和传播科学知识,以防对某人有所帮助,但不是为了成为 DRL 地区的学术参考文献。如果读者需要更严谨的文档,本系列的最后一篇文章提供了大量的学术资源和书籍供读者参考。作者意识到这一系列的帖子可能包含一些错误,如果目的是一个学术文件,则需要对英文文本进行修订以改进它。但是,尽管作者想提高内容的数量和质量,他的职业承诺并没有留给他这样做的自由时间。然而,作者同意提炼所有那些读者可以尽快报告的错误。**
深层图像修复的修订与回顾:基于生成式对抗网络的图像修补
欢迎回来的家伙:)今天,我想给一个修订的深层图像修复,我们已经谈到目前为止。还有,想再复习一篇图像修复的论文,巩固深度图像修复的知识。让我们一起学习和享受吧!
回忆
在这里,让我们首先简单回顾一下我们从以前的帖子中学到了什么。
上下文编码器(CE)【1】是文献中第一个基于 GAN 的修复算法。它强调理解整个图像的上下文对于修复任务的重要性,并且(通道方式)全连接层用于实现这样的功能。详情可以点击此处链接往期帖子。
多尺度神经面片合成(MNPS)【2】可以看作是 CE 的改进版。它由两个网络组成,即内容网络和纹理网络。内容网络是 CE,纹理网络是用于对象分类任务的预训练的 VGG-19。使用纹理网络的想法来自于最近神经风格转移的成功。简单地说,用于高级视觉任务(例如物体分类)的预训练网络中的神经响应包含关于图像风格的信息。通过鼓励缺失区域内外类似的神经反应,我们可以进一步增强生成像素的纹理细节,从而使完成的图像看起来更真实。强烈建议感兴趣的读者在此浏览帖子了解详情。
全局和局部一致图像补全(GL CIC)【3】是深度图像修复任务中的一个里程碑。作者采用全卷积网络(FCN)和扩展卷积(DilatedConv)作为他们提出的模型的框架。FCN 允许各种输入大小和 DilatedConv 取代(通道方式)完全连接层,用于了解整个图像的背景。此外,两个鉴别器用于在两个尺度上区分完整图像和真实图像。全局鉴别器查看整个图像,而局部鉴别器关注局部填充的图像块。我强烈推荐读者在这里看一看帖子,尤其是 CNN 中的扩张卷积。
今天,我们将回顾这篇论文,基于生成性对抗网络的图像修补[4]。这可以看作是 GLCIC 的一种变体,因此我们可以对这种典型的网络结构做一些修改。
动机
本文作者希望利用剩余连接和 PatchGAN 鉴别器的优势来进一步改善他们的修复效果。
用于图像识别的深度残差学习(ResNet)【5】在深度学习方面取得了显著的成功。通过使用残差块(残差连接),我们能够训练非常深的网络,许多论文已经表明残差学习对于获得更好的结果是有用的。
PatchGAN 6在图像到图像的翻译方面也取得了巨大的成功。**与典型 GAN 中的鉴别器相比,PatchGAN 鉴别器(参见下面的图 1)输出一个矩阵(2d 阵列),而不仅仅是单个值。**简单来说,典型 GAN 鉴频器的输出是从 0 到 1 的单一值。这意味着鉴别器查看整个图像并决定这个图像是真的还是假的。如果图像是真实的,它应该给 1。如果图像是假的(即生成的图像),它应该给 0。这个公式关注于整个图像,因此图像的局部纹理细节可能被忽略。另一方面,PatchGAN 鉴别器的输出是一个矩阵,该矩阵中的每个元素的范围从 0 到 1。注意,每个元素代表输入图像中的一个局部区域,如图 1 所示。因此,这一次,鉴别器查看多个局部图像块,并且必须判断每个块是否是真实的。通过这样做,可以增强生成的图像的局部纹理细节。这就是 PatchGAN 被广泛用于图像生成任务的原因。
图一。PatchGAN 鉴别器。输出是矩阵,矩阵中的每个元素代表输入图像中的局部区域。如果局部区域是真实的,我们应该得到 1,否则 0。摘自[4]
介绍
图像修复可以看作是一种图像生成任务。我们希望填充图像中的缺失区域(即生成缺失的像素),以使图像完整且看起来逼真。
为了生成逼真的图像,GAN 通常用于不同的图像生成任务,包括图像修复。典型的 GAN 鉴别器查看整个图像,仅通过单个值[0,1]来判断输入是否真实。这种 GAN 鉴别器在本文中称为全局 GAN (G-GAN)。
另一方面,PatchGAN 查看输入中的多个局部区域,并独立决定每个局部区域的真实度,如前一节所述。研究人员已经表明,使用 PatchGAN 可以通过关注更多的局部纹理细节来进一步提高生成图像的视觉质量。
解决方案(简而言之)
- 在生成器中使用了具有扩展卷积的残差块(扩展残差块)。(作者期望通过使用残差学习可以增强修复结果)
- patch GAN 和 G-GAN 鉴别器的混合(PGGAN) 被提出以鼓励输出的完整图像应该是全局和局部逼真的。(与 GLCIC 中的意图相同,使用两个鉴别器,一个全局的,一个局部的)
贡献
- patch GAN 和 G-GAN 鉴别器的组合(PGGAN) 其中早期卷积层被共享。他们的实验结果表明,它能进一步增强生成像素的局部纹理细节。
- 扩张和插值卷积用于发生器网络。通过使用膨胀的残余块,修复结果得到了改善。
方法
图二。提出的生成 ResNet 结构和 PGGAN 鉴别器。摘自[4]
图 3。全球土地信息中心的拟议结构。摘自3
图 2 和图 3 分别显示了本文和 GLCIC 提出的网络结构。很明显,它们是相似的。两个主要区别在于:I)发生器中使用了膨胀的残差块; ii)修改 GLCIC 中的全局和局部鉴别器。
在 GLCIC 中,全局鉴别器将整个图像作为输入,而局部鉴别器将填充区域周围的子图像作为输入。将两个鉴别器的输出连接起来,然后返回一个值,以显示输入是真的还是假的(一次不利损失)。从这个角度来看,局部鉴别器将集中在局部填充的图像补片上,因此可以增强填充补片的局部纹理细节。一个主要缺点是局部鉴别器的输入依赖于缺失区域并且作者在训练期间假设单一矩形缺失区域。
对于 PGGAN 鉴别器,我们有几个早期共享卷积层如图 2 所示。然后,我们有两个分支,一个给出单个值作为输出(G-GAN),一个给出矩阵作为输出(PatchGAN)。请注意,1×256 是 16×16 矩阵的变形版本。如上所述,这也是一种让鉴别器在区分完整图像和真实图像时同时关注全局(整个图像)和局部(局部图像小块)信息的方式。请注意,我们将有两个不利的损失,因为在这种情况下我们有两个分支。
扩张的残余阻滞
在我之前的文章中,我已经介绍了 CNN 中的扩张卷积。简单回忆一下,通过跳过连续的空间位置,扩大的卷积增加了感受野而没有增加额外的参数。对于忘记这个概念的读者,请随意先重温一下我之前的帖子。
图 4。剩余块类型。自上而下:标准残余阻滞,先有扩张回旋的扩张残余阻滞,后有扩张回旋的扩张残余阻滞。摘自[4]
图 4 示出了不同类型的残差块。为了便于我们的进一步讨论,我将简要介绍图 4 顶部所示的一个基本残差块。
简单地说,残差块可以公式化为 Y = X + F(X),其中 Y 是输出,X 是输入,F 是几层的序列。在图 4 的基本剩余块中,F 是 conv-诺姆-雷鲁-Conv。这意味着我们将 X 馈送到一个卷积层,然后是归一化层、ReLU 激活层,最后是另一个卷积层,以获得 F(X)。一个要点是输入 X 直接加到输出 Y 上,这就是我们称之为跳过连接的原因。由于沿此路径没有任何可训练参数,我们可以确保在反向传播期间必须有足够的梯度传递到早期层。因此,我们可以训练非常深的网络,而不会遇到梯度消失的问题。
为什么是残块?
你可能想知道使用剩余块的好处。你们有些人可能已经知道答案了。下面我来说说我的看法。
我们来比较一下 Y = X + F(X)和 Y = F(X)。对于 Y = X + F(X),我们实际学到的是 **F(X) = Y - X,Y 和 X 的差,这就是所谓的剩余学习,X 可以作为剩余学习的参考。**另一方面,对于 Y = F(X),我们直接学习将输入 X 映射到输出 Y,无需参考。所以,人们认为剩余学习相对容易。更重要的是,很多论文都表明,残差学习可以带来更好的效果!
由于扩展卷积有助于增加感受野,而感受野对于修复任务非常重要,因此作者用扩展卷积层替换了两个标准卷积层中的一个,如图 4 所示。有两种类型的扩张残余阻滞, i)首先放置扩张的回旋和 ii)其次放置扩张的回旋。在本文中,基于所采用的膨胀的残余块的数量,膨胀率从 1 开始增加两倍。例如,如果有 4 个膨胀的残余块,膨胀率将是 1、2、4、8。
插值卷积
为了解决由标准反卷积(即转置卷积)引起的伪影,作者在这项工作中采用了插值卷积。对于插值卷积,首先使用双线性和双三次插值等典型插值方法将输入调整到所需大小。然后,应用标准卷积。下图 5 显示了转置卷积和插值卷积之间的差异。
图 5。使用转置卷积(上)和插值卷积(下)获得的结果的视觉比较。摘自[4]
在我看来,这两种卷积都有相似的性能。有时候转置卷积更好,有时候插值卷积更好。
鉴别器网络
我们已经讨论了本文中使用的 PGGAN 鉴别器。这里,回想一下,鉴别器有两个分支,一个分支给出单个值,就像 global-GAN (G-GAN)一样,另一个分支给出 256 个值,其中每个值表示输入中局部区域的真实度。
关注输入中多个局部区域的真实性有助于改善完整图像的局部纹理细节。
目标函数
实际上,本文中使用的损失函数(即目标函数)或多或少与我们以前覆盖的论文相同。
重建损失:该损失是为了保证逐像素重建精度。对于这种损失,我们通常采用 L1 或 L2(欧几里得)距离。本文使用 L1 损失作为它们的重建损失,
N 是训练批次中图像的数量。 W 、 H 和 C 是训练图像的宽度、高度和通道。 x 和 y 是模型给出的地面真实和完整图像。
对抗性损失:我想你们大多数人现在都很熟悉这种典型的对抗性损失。
x 是地面真值,所以我们要 D ( x )返回 1,否则 0。注意 D 只是鉴别器的函数形式。
关节损失:
等式 3 是它们的联合损失函数。λ1,2,3 用于平衡每个损失的重要性。 g_adv 表示全局分支给出的输出,而 p_adv 表示 PatchGAN 分支给出的输出。注意,在它们的实验中,λ1、2、3 分别被设置为 0.995、0.0025 和 0.0025。
实验结果
在他们的实验中使用了三个数据集。 i) 巴黎街景【7】包含 14900 张训练图像和 100 张测试图像。 ii) 谷歌街景有 62058 张高分辨率图片,分为 10 个部分。第一和第十部分用于测试,第九部分用于验证,其余部分用于训练。总共有 46,200 个训练图像。 iii) 地点由超过 800 万张训练图像组成。该数据集仅用于测试,以显示概化能力。
为了比较典型残余块和扩张残余块的性能,作者训练了两个模型,即 PGGAN-Res 和 PGGAN-DRes 。对于 PGGAN-Res,使用了基本残差块和 3 个子采样块。这意味着输入被下采样 2/3 倍。对于 PGGAN-DRes,使用了扩张的残差块和 2 个子采样块。这意味着输入被下采样 2 倍。
图 6。训练具有不同鉴别器结构的相同生成器网络的结果。摘自[4]
图 6 示出了用不同鉴别器结构训练相同生成器网络的修复结果。从图 6 的最后一列可以看出,如果仅使用 G-GAN 鉴别器,则观察到窗口的局部纹理细节较差。与 G-GAN 相比,PatchGAN 提供了更好的窗口局部纹理细节,但窗口的角看起来与全局结构不一致。总的来说,PGGAN 可以提供最佳视觉质量的结果。
表 1。巴黎街景 256x256 图像的定量比较。摘自[4]
表二。巴黎街景 512×512 图像的定量比较。摘自[4]
表 1 和表 2 显示了在 256×256 和 512×512 两种分辨率的巴黎街景数据集上不同方法的定量比较。注意 CE 是上下文编码器1,NPS 是多尺度神经补片合成(MNPS) [2],GLGAN 是全局和局部一致的图像完成(GLCIC) 3。我们已经在以前的文章中讨论了所有这些方法。
从表 1 和表 2 中可以明显看出,PGGAN 在所有这些指标上都有所改善。但是,请记住,视觉质量比这些客观的评估指标更重要。
图 7。使用不同方法对完整图像的感知比较。摘自[4]
作者对这些方法进行了感知评估,如图 7 所示。要求 12 个投票者对原始图像的自然度和各种方法的修复结果进行评分。每位投票者被随机分配了来自巴黎街景数据集中的 500 张照片。请注意,CE 是在 128×128 图像上训练的,因此它在 256×256 测试图像上的性能很差。其他方法在这种感知评估中具有相似的性能。
图 8。256x256 巴黎街景数据集上的定性比较。摘自[4]
图 9。512x512 巴黎街景数据集上的定性比较。摘自[4]
图 8 和图 9 分别显示了尺寸为 256×256 和 512×512 的图像的修复结果。我建议读者放大以更好地查看结果。在我看来,PGGAN-DRes 和 PGGAN-Res 通常会给出具有更好的局部纹理细节的结果,例如,参见图 8 中的第 4 行和图 9 中的第 3 行。
结论
首先,残差学习的概念以扩张残差块的形式嵌入到生成器网络中。从他们的实验结果来看,残差学习有助于提高修复性能。
其次,PatchGAN 鉴别器的概念与传统的 GAN 鉴别器(G-GAN)相结合,以鼓励更好的局部纹理细节和全局结构一致性。
外卖食品
和以前一样,我想在这一部分列出一些有用的观点。如果你关注过我以前的帖子,你会发现这个帖子相对简单。
其实文中的大部分东西都和 GLCIC 3差不多。在网络结构中嵌入了两个新概念,即残差块和 PatchGAN 鉴别器,以进一步增强修复效果。
我希望你能实现这种典型的图像修复网络架构。在后来的修复论文中提出的网络或多或少是相同的。
你还应该注意到,重建损失和对抗损失是图像修复任务的两个基本损失。在后来的修复论文中提出的方法必须包括 L1 损失和对抗性损失。
下一步是什么?
这是我的第四篇关于深度图像修复的文章。到目前为止,我们实际上已经涵盖了几乎所有深度图像修复的基础知识,包括图像修复的目标,修复的典型网络架构,损失函数,一般图像修复的困难,以及获得更好修复结果的技术。
从下一篇文章开始,我们将会深入到更多的修复论文中,这些论文为图像修复设计了更具体的技术。假设你们已经知道了基础知识,我可以花更多的时间来解释这些修复技术。尽情享受吧!😃
参考
- Deepak Pathak,Philipp krhenbüHL,Jeff Donahue,Trevor Darrell 和 Alexei A. Efros,“上下文编码器:通过修补进行特征学习,” Proc .计算机视觉与模式识别 ( CVPR ),2016 年 6 月 27-30 日。
- 杨超,吕鑫,林哲,Eli Shechtman,Oliver Wang,和郝力,使用多尺度神经补片合成的高分辨率图像修复, Proc .计算机视觉与模式识别 ( CVPR ),2017 年 7 月 21-26 日。
- 饭冢聪、埃德加·西蒙-塞拉和石川宽,“全球和局部一致的图像完成、 ACM Trans。论图形,第 36 卷第 4 期第 107 条,出版日期:2017 年 7 月。
- https://arxiv.org/pdf/1803.07422.pdf,乌古尔·德米尔和戈兹德·乌纳尔,基于补丁的图像修复。
- 、何、、、任、、、【用于图像识别的深度残差学习】、 Proc .计算机视觉与模式识别 ( CVPR ),2016 年 6 月 27-30 日。
- Phillip Isola,,Tinghui Zhou,和 Alexei A. Efros,《有条件对抗网络的图像到图像翻译》。计算机视觉与模式识别 ( CVPR ),2017 年 7 月 21-26 日。
- C.Doersch,S. Singh,A. Gupta,J. Sivic 和 A. A. Efros。“是什么让巴黎看起来像巴黎?," ACM Trans。关于图形,第 31 卷第 4 期,第 101 条,出版日期:2012 年 7 月。
感谢您阅读我的帖子!如果您有任何问题,请随时询问或在此留下评论。下次见!😃
重温数据科学的图腾~变量
遵循此变量图提升您的数据科学项目
谎言有三种类型——谎言、该死的谎言和统计数字。
——本杰明·迪斯雷利
数据科学将其应用建立在不同的领域之上,如应用数学、运筹学、物联网等。然而,所有变量背后都有一个共同的“分母”。这完全是关于这位“非常规英雄”的,他的能力在数据科学家中是深远的,但是…事实也是如此!通常,没有太多的注意力放在它们的本质上,匆忙地通过它们,以无效的结论和错误的分析结束。例如:
为了吸引人才,幻想公司将在周日的报纸专栏中公布员工福利。给定以下额外津贴的分布,记者应该在专栏中说明什么是“平均”额外津贴?
额外津贴* = [1,1,4,5,5,3,2,1]
(*)表示员工享有的津贴数量(1:笔记本电脑,2:笔记本电脑+汽车等)
如果你刚刚回答了 2.75(否则: 22/8 ),请拿着这张地图,让我来指导你完成剩下的旅程——这是一篇致力于变量的游记。
范围~路线图
本文旨在开发一个战略叙事,数据科学家可能会听,然后回到变量的原则。这样,我们的目标是:
(a)向我们自己重新介绍最常见类型的变量
(b)针对每种情况,针对所选的指标和图制定一份指南,以便在具体情况下遵循
©学会以更加流畅和有效的方式传达变量驱动的结论
为了做到这一点,我们将通过不同的视角来研究变量;它们的性质和它们的测量尺度。
1.变量的性质
统计学中的变量通常可以描述数量或质量。在这种情况下,我们区分两大类1:
🔸定性(分类)变量:它们描述一种性质某物是什么或者怎样并且不能被计算。它们可以用实数或单词来表示。示例:团队、颜色、邮政编码。
🔸数量变量 : 描述数量的另一大类[ 某事物有多少 ]。显然,它是用数值来表示的。例子:身高,年龄,时间。
2.测量尺度
这个概念指的是一个规则系统,它定义了如何测量一个变量。有四种度量尺度:名义的、顺序的、间隔的和比率的[2]。每一项都根据其澄清以下问题的能力进行评估:
- 两个个体是否不同
- 不同的方向
- 差异的大小
🔸名义:指定性变量,可以分辨两个个体是否不同,但不能定义那个差异的方向和大小。例子:Name ( Mark 和 John 不同,但是在他们之间设置任何优先级都是没有意义的)。
🔸序数:针对数量变量,能够区分两个个体是否不同,以及差异的方向。然而,他们无法分辨出差异的大小。示例:赛跑运动员的排名(获胜者与第二名运动员不同,显然她是第一名)。
🔸*****:这个范畴是针对量化变量的,可以定义两个个体的差异,其大小和方向。零点(当变量值为 0 时)并不意味着一个量的缺失,这使得无法用比率来衡量个体之间的差异。例如:华氏温度(华氏 0.0 度并不意味着没有热量)。
🔸*****:具体到数量变量,能够解释两个个体是否不同,差异的大小和方向。此外,零点表明缺少一个量,这使得用比率来衡量个体之间的差异变得可行。示例:以开尔文为单位的温度( 0.0 开尔文实际上意味着‘没有热量’)。
(*)区间和比率变量,可进一步分为 2 个子类别:
🔸离散 : 任何两个相邻值之间都没有可能的中间值,意味着这些变量只能得到一定数量的值3。示例:卧室数量
🔸连续 : 任意两个值之间有无穷多个值。示例:重量
3.允许的统计方法*
很多时候,为了描述和处理一个分布,我们需要用一个或多个值(度量)来概括它。最常用的是平均值,其内容反映了一个概率分布的中心值或典型值;一个从中心倾向【4】的测量中衍生出来的概念。
在这些度量中,我们区分了(加权)均值、中值和众数。它们中的每一个都有不同的计算方法,并针对不同的情况形成适当的解决方案。
🔸均值:它是一个分布的“平衡点”,意味着低于它(均值)的分布值的总距离等于高于它的那些值中的相应一个。它同等地考虑了每个分布值(易受变化影响),并为区间和比率数据提供了良好的度量。
然而,当处理一个开放式分布(即上限是“100 或以上”)时,我们无法计算它。相反,使用中间值更有意义。此外,在处理有序数据时,使用平均值是有争议的[2]。在这种情况下,中位数是一个很好的选择,众数是一个更好的选择。
这同样适用于加权平均值,在这种情况下,数据点具有不同的权重。
🔸中位数:排序分布的中间值,与平均值不同,它不易改变(考虑中间值或两个中间值)。显然,它构成了一个稳健的统计量,非常适合汇总含有异常值或开放值的数值分布。此外,它还是汇总有序数据的好选择。
这里的缺点是它不能处理标称和序数数据,因为后者不是用数字编码的。
🔸模式:分布中出现频率最高的值。因此,它是名义数据、序数数据(尤其是当值用单词表示时)和离散数据(当我们需要向非技术受众传达平均值时)的理想指标。
在连续变量的情况下,这不是一个全有解;我们首先需要创建分组频率表,然后计算它。
简而言之,您可以使用下表:
表 1:集中趋势指标~变量类型
(*) 另一个有趣的方向是检查可变性,但这取代了当前文章的范围。
4.最佳可视化
根据每种变量类型的测量范围,可以使用一些特定的图表来更好地描述潜在的结论[5]。
🔸标称&序数 : 对于频率分布的情况,建议使用条形图(垂直或水平)和饼图。
- 柱形图:它很好地描绘了两个或更多变量之间的关系,同时提供了潜在趋势和变化的良好视觉印象。但是,当处理许多类别时,它可能会显得杂乱。使用太多或太少的类也会“掩盖”重要的数据模式。
- 饼图:它通常代表一个类别(有唯一标签的类别),每个楔形区的大小与分布中的类别成比例。与条形图相比,它的主要优点是可以更好地感知分布中的相对频率(百分比)。主要缺点是它不能比较两个数据集(分布)。
🔸区间&比率:这些变量类型的频率分布,可以通过直方图或核密度图(KDE)有效地可视化。方框&须状图是比较不同分布的另一个有趣选项,尤其是当我们处理连续变量时。
- 直方图:它的特点是在数据分布方面有丰富的描述能力,使读者很容易识别不同的数据,它们的频率和潜在的偏斜度。当我们处理巨大的数据集时特别推荐。
- KDE 图:与直方图相比,它给出了更清晰的分布图。但是,如果我们必须绘制五个以上的分布图,它可能变得不可读。
- 箱线图:如果我们想要识别数据集中的异常值,它非常有用,同时提供了一个关于落入任何特定四分位数的值的比例的良好视觉直觉。然而,它缺乏说明分布类型的能力。
综上所述,表 2 显示了每种测量尺度的推荐图:
表 2:可视化选择~测量尺度
回到介绍性的例子,我们很容易理解额外津贴是一个Quantitative
变量。此外,它属于Ordinal
测量尺度,尽管它是用数字编码的(我们分不清员工 A 和 B 的差异大小)。除此之外,它还构成了一个Discrete
变量。
因此,由于报纸的读者可能包括非技术人员,对于普通读者来说Mean
(3.14)没有太大意义,因为他们希望额外津贴的数量是一个整数。这同样适用于Median
(2.5)。另一方面,Mode
对于这种情况来说是更安全的选择,因为它保证了分布中的整数。因此,在报道这一结果时,记者应该避免使用技术术语(如“模式”、“变量”等),而简单地说“幻想公司”的员工通常/平均享有 5 项津贴。
总和
在实践中,许多人避免接触理论障碍,最终“在飞行中”检查变量。在这种情况下,他们要么选择错误的指标(即,只将“平均值”与平均值匹配)并绘制图表,要么得出错误的结论。
仔细看看每个变量代表什么——它的性质——可以加强我们的分析。此外,感知它被测量的方式,可以培养更好的度量和可视化选择。然而,我们不应该感到被迫选择一个或另一个指标,而是在和的基础上明智地做出选择。
这一次我们的旅程没有任何动作,也没有任何机器学习、NLP 等花哨的概念。尽管我们很喜欢它们,但我们应该始终尊重变量的基本“图腾”,因为它构成了通向数据科学的道路……此外,正如另一位本杰明·迪斯雷利所说:
当我想看一本小说时,我会写一本。
这实质上意味着,如果我们不能写出并巩固有效的统计结论,我们就无法有效地传达它们…
一如既往,非常感谢您的阅读!
参考文献:
1 D. S .耶茨,D. S .摩尔,D. S .斯塔内斯,统计学的实践(第 2 版。)(2003 年),纽约:弗里曼公司
[2] S. S .史蒂文斯,论测量的尺度 (1946),《科学新系列》
3 K. D. Joshi,离散数学基础 (1989),新时代国际有限公司
[4] Y .道奇,《牛津统计术语词典》 (2003),OUP 国际统计研究所(词条为“集中趋势”)
[5] J. Frost,数据类型指南和如何在统计数据中用图表表示它们 (2008),在线出版物“Jim 的统计”
开发人员的强化学习策略
理解强化学习策略的实用方法
菲利普·怀尔斯在 Unsplash 上的照片
更新:学习和练习强化学习的最好方式是去http://rl-lab.com
策略在某种程度上是一个棘手的概念,主要针对强化学习的初学者。这篇文章将试图用简单明了的英语澄清这个话题,远离数学概念。它是在考虑到开发者的情况下编写的。
政策
如果您听说过最佳实践或指导原则,那么您应该听说过政策。例如,考虑住在高楼里的人们的消防安全指南。也许最重要的指导方针是在火灾中不要使用电梯。人们应该关上门,储备水,使用湿床单,并让消防员知道他们的位置。
这一系列行动是根据指导方针发布的,这些指导方针是对长期以来积累的最佳实践和经验进行汇编的结果。
所以政策告诉你在面对某种情况时如何行动。它不会告诉你行动的结果或价值。然而,当遵循这个策略时,你隐含地期望有最好的可能结果,例如安然无恙地逃离火灾。
动作值
行动价值是指你采取行动并评估其结果或价值的时候。
例如,一个被困在着火建筑的高层的人考虑他/她的选择(可用的行动),然后尝试每一个来评估其结果。当然,在现实中,这是不可能的,因为一旦受伤就没有回头路了。但是在模拟、体育、游戏中,有可能玩许多场景并找出给出最佳结果的动作。
政策与行动价值的关系
不言而喻,策略是基于得分(或价值)最高的操作的最佳实践的集合。
我们这样写道
这意味着在状态 s 时,我们采取行动 a 使得 a 给出最佳结果。
其中 q(s,a)是在状态 s 采取的动作 a 的值。
但是有一个问题。你需要真正理解这是一个随机的环境,充满了不确定性。这意味着同一状态下的同一动作,每次执行都可能导致不同的结果。
例如,一个篮球运动员练习投三分球,即使他用同一只手从同一个点(或角度)投篮,有时会得分,有时会失手。他/她必须计算一个平均值(得分/投掷次数)来找出点(或角度)和手牌的组合效率。
为了找到比赛中使用的最佳角度和手,他/她必须从不同的角度和不同的手练习投篮,然后平均结果,以推断出哪种组合最适合他/她。
当然,解决这个问题的一个方法是执行大量的迭代。在每次迭代中,执行该状态下所有可用的动作,然后对每个动作取 q(s,a)的平均值,并更新策略𝛑(s).我们说我们正在更新每次迭代的策略。因此,在每次迭代之后,我们都有一个新的策略𝛑来反映计算出的 q 值。
在足够多的迭代之后,当 q(s,a)的平均值开始缓慢变化到足以认为它是稳定的时候,我们说我们已经到达了一个稳定的阶段,并且策略已经变得最优(意味着这是可以达到的最好的),我们称之为最优策略,并且我们写它为𝛑*
处理政策问题有不同的方式,改进政策也有不同的方式(即更新)
最优策略
最佳策略是当当前被训练的策略已经达到一个阶段,在这个阶段之后它不能被实质性地改进。
最优策略的重要性在于,它允许跟随它的代理实现“最佳可能”的结果。
动态规划方法中的策略
这是最简单的场景,也是最不现实的场景。所有的环境动态都是已知的,我们只需迭代计算 q 值,并在每次迭代后将具有最高 q(s,a)值的动作分配给策略𝛑(s).
在动态编程中,我们知道所有的状态和所有的转移概率,所以不需要发现任何东西,只需要计算值。
在本文中有更多关于动态编程的内容。
蒙特卡罗方法中的策略
在蒙特卡洛,我们不太了解环境的内部运作,所以需要通过播放剧集来发现。我们播放每一集直到结束,直到我们到达一个终端状态,然后我们计算每个访问的状态和执行的每个动作的 q 值 q(s,a)。
然而,与动态编程不同,我们无法计算所有状态的 q 值,因为我们事先根本不知道它们。我们必须在播放剧集时发现它们。现在的问题是,我们如何以一种有意义的方式播放这些片段,以便我们能够提取最佳策略?
当然,还有随机漫步策略,即在每个状态选择一个要执行的随机动作。这在开始时会起作用,但后来,当我们开始发现一些行为比其他行为更好时,保持随机行走很快就会变得低效,因为它不会学到任何东西。这种低效率的原因是因为策略没有用 q 的新值来更新。
因此,最好使用在每个州都能发挥最佳作用的政策。但这种策略的问题是,我们每次都将执行相同的操作,我们将无法发现新的状态,此外,我们也不确定所选择的操作是否真的是最好的。请记住,环境充满了不确定性,没有任何东西可以保证,如果一个行动在时间 t 产生了好的结果,在时间 t+1 也会有同样的好结果。因此,为了最好地利用这两种方法,我们采用了一种叫做𝜀-greedy.的策略
在𝜀-greedy 策略中,我们部分时间遵循贪婪策略(选择目前已知的最佳行动)1- 𝜀,部分时间选择随机行动𝜀。这将允许在某些时候通过随机漫步发现新的状态,并在大多数时候利用最佳动作。
随机政策
并不是所有的事情都是关于选择产生最佳 q 值的行为。要真正掌握这个想法,做以下实验:
和某人玩石头剪子布,注意连续玩同一个动作是个坏主意(即使前几次奏效了),因为你的对手会对此采取对策。例如,如果你经常玩石头,你的对手会玩纸并赢。
所以政策不再是关于某个行动在某个状态下的最佳结果,而是关于让你赢的行动的概率分布。换句话说,这是关于你的行为应该有多不可预测。
请注意,随机政策并不意味着它在所有状态下都是随机的。对他们中的一些人来说已经足够了。在这些状态中,策略确定性地动作,其动作概率分布(在这些状态上)对于一个动作是 100%,对于所有其他动作是 0%。
政策评价
评估一项政策意味着什么?
嗯,就像测试其他东西一样。你试着去发现它是否实现了它的承诺。
同样,策略评估包括要求策略提供给定状态的操作,然后执行该操作并计算结果(例如 q 值)
最终,并非所有操作都会产生预期结果,因此策略需要一些微调。
这是策略控制的工作也叫策略改进
政策控制/改进
策略控制或改进是关于在某个状态下执行一个动作后给策略反馈。动作的结果被输入到策略中,因此它更新其内部行为,在某种程度上使该动作在下一次达到相同状态时更有可能被使用(或不被使用)。这种反馈被称为更新。
再次考虑篮球运动员在三分线投掷的例子。从左手开始,他/她得分几次,因此策略被更新为使用左手。随着练习的进行,他/她在使用左手时有 30%的机会成功,但在使用右手时有 70%的机会成功。然后应该更新策略,在这个点(或角度)上使用右手而不是左手。
概念实现
为了从概念上实现一个策略,让我们考虑下面这个名为 IPolicy 的接口。它包含两种方法:
- getAction 返回在状态 s 时要执行的操作。
- update(s,a,some_value),以某种方式更新当前策略,以调整其在状态 s 时的行为。这通常通过告诉策略关于在状态 s 执行的动作 a 的结果(q 值或其他)来完成。
interface IPolicy{ // get action given state s as indicated by the current policy
getAction(s);
// update policy at state s and action a
update(s, a, some_value);
}
每个特定的策略都以反映其行为的方式实现这个接口。
例如,RandomPolicy 实现 getAction(s ),以便它在状态 s 返回随机动作。它不实现 update 方法,因为当行为总是随机的时,不需要任何更新。
class RandomPolicy : IPolicy { // get random action at state s
getAction(s){
return random action at state s
}
// no need for implementation since the policy is random
update(s, a, some_value){
}
}
GreedyPolicy 返回在状态 s 给出最佳 q 值的动作。因此,它必须将这些值存储在适当的结构中。
另一方面,更新方法更新在状态 s 和动作a计算的 q 值。这通常通过对先前计算的值求平均值来完成。
class GreedyPolicy : IPolicy {
// store q values by state and action
QValueByStateAndAction store // get action that has the highest q for the given state s
getAction(s){
return store.getActionOfMaxQ(s)
}
// update policy by storing the average of the q computed at
// state s and action a
update(s, a, q){
prev_q = store.getQForStateAndAction(s, a)
store.updateQ(s, a, average(prev_q, q))
}
}
EpsilonGreedyPolicy 返回在状态 s 的随机动作,𝜀部分时间,以及具有最佳 q 值(1- 𝜀)部分时间的动作。
至于更新方法,和 GreedyPolicy 的逻辑是一样的。
class EpsilonGreedyPolicy : IPolicy {
// store q values by state and action
QValueByStateAndAction store
epsilon = 0.1 // get random action epsilon time, highest q
// (1-epsilon) of the time
getAction(s){
rnd = computeRandomValue()
if(rnd < epsilon) return random action at state s
else return store.getActionOfMaxQ(s)
}
// update policy by storing the average of the q computed at
// state s and action a
update(s, a, q){
prev_q = store.getQForStateAndAction(s, a)
store.updateQ(s, a, average(prev_q, q))
}
}
StochasticPolicy 不直接依赖于 q 值(它可能会间接依赖于 q 值),但是它会根据成功的概率分布返回动作。例如,如果动作 A 在 60%的时间里成功,动作 B 在 30%的时间里成功,动作 C 在 10%的时间里成功。则该方法返回的操作遵循 60% A、30% B、10% C 的分布。
至于更新方法,它更新动作的潜在概率分布。
class StochasticPolicy : IPolicy {
// store q values by state and action
ActionByFrequency store// get action following the frequency of success
getAction(s){
return store.getActionByProbabilityOfSuccess()
}
// update policy by storing the occurrence of success
// result : success = 1; failure = 0
update(s, a, result){
success_count = store.getSuccessCount()
store.setSuccessCount(s, a, success_count + result)
}
}
高级算法
为了综合考虑所有因素并得出最佳策略,我们考虑一种高级算法,它可以执行以下操作:
- 根据需要循环以下步骤
- 从状态 s 的策略中获取一个动作:a = action.getAction(s)
这是策略评估 - 在环境中执行动作,观察奖励 r 和新状态s’
- 计算评估所采取措施的有效性所需的任何值 v 。这可能是 q 值或其他,它可能涉及神经网络或其他
- 向策略提供反馈,以便它可以自我改进:policy.update(s,a,v)
这是策略改进
它大概是这样的。
E =评估,I =改进
或者这个
向上的箭头是评估阶段,向下的箭头是改进阶段。
结论
这篇文章以一种实用的方式,通过描述性的解释而不是数学性的解释,来关注强化学习的策略。它是整个 RL 结构中的一个构建模块,对开发者来说收益最大。
相关文章
重新加权成人数据集,使其“无歧视”
预处理阶段偏差缓解的一个例子
由 Pixabay 提供
在之前的博客中,我们讨论了如何识别偏见以及减轻偏见的方法的机器学习工作流程。在接下来的几周里,我将会写一系列的文章来更详细地探索这个工作流程。首先,我将详细介绍一些与建模阶段相关的偏差缓解技术。
机器学习(ML)管道中我们可以干预以减少偏差的第一个阶段称为预处理。预处理描述了在应用机器学习算法之前发生的一组数据准备和特征工程步骤。采样、按摩、重新加权和抑制是学术文献中提出的不同预处理偏差缓解技术1。
在这篇文章中,我将重点探讨重新加权【2】,这是一种为数据分配权重的预处理技术。
这种方法的优点是,它不是修改标签,而是根据受保护属性和结果的类别为示例分配不同的权重,以便从训练数据集中消除偏差。权重基于频率计数。然而,由于这种技术被设计为只与能够处理行级权重的分类器一起工作,这可能会限制您的建模选项。
为了演示这种技术如何减少偏差,我使用了成人数据集【3】。该数据集中的二元目标是个人收入是高于还是低于 5 万美元。它包含了几个在美国受法律保护的特征,但是为了简单起见,在这篇文章中,我将把重点放在性上。从下表中可以看出,男性是享有特权的群体,有 31%的概率获得积极结果(> $50k),而女性群体有 11%的概率获得积极结果。
如下面等式中所描述的,不同的影响度量是数据中的区分度的度量。分数为 1 表示数据集是无歧视的。当计算男性和女性的未加权成人数据集时,得分为 0.36。
使用上表中的频率计数,重新称重技术将按照下式分配重量。例如,对于具有积极结果的特权群体(即收入超过 5 万美元的男性),权重计算如下:
因此,训练数据中每个类别的权重为:
通过将这些权重应用于计数,对于训练数据,不同的影响度量将变为 1,因此现在是“无歧视的”在预处理阶段对训练数据计算出这些权重后,它们可以用作逻辑回归、SVM 和 XGBoosts 等分类器的输入。
为了评估重新加权技术的效果,我训练了两个逻辑回归模型,一个有权重,另一个没有权重。实验结果表明了重新称重方法在减少歧视方面的有效性,如下表所示:
这种技术对于数据所有者不愿意与数据科学家共享敏感或受保护属性的用例尤其有用。通过为他们提供一个可以将这些权重分配给记录的脚本,数据科学家将能够在不直接访问受保护属性的情况下减少建模过程中的偏差。
与从训练数据中移除敏感属性等简单方法相比,实验表明预处理技术在减少偏差方面更有效。也就是说,平均而言,预处理技术不如处理中技术有效,因为它们不直接参与模型训练过程,并且需要进行一些精度折衷以降低区分度。
参考资料:
1 Kamiran F,Calders T (2009a)无歧视分类。IEEE IC4 计算机、控制和通信国际会议论文集。IEEE 出版社
[2]卡米兰,费萨尔和考尔德斯,图恩。无区别分类的数据预处理技术。知识与信息系统,33(1):1–33,2012
3“成人——UCI 机器学习。”5 月 1 日。一九九六年,http://archive.ics.uci.edu/ml/datasets/Adult。
将你的大脑从 Python 重新连接到 Java
学习一门新的编程语言时,你可能会遇到的七个概念障碍
自白:我个人的经历几乎和这篇文章的题目完全相反。实际上,我在大学里从 C++开始,转到 Java 来教授 AP 计算机科学 A,然后进入 Python 领域,使用所有可用的时髦数据科学库。现在我又在做一个 Java 项目(一个神经网络包,它真的把我对底层数学的理解推向了极限),我真的很注意这两种语言工作方式的细微差别。特别是,我一直在记录标准 Python 习惯在 Java 中会成为巨大障碍的地方。
印度尼西亚东爪哇|Waranont(Joe)onUnsplash
这篇文章是针对走在相反道路上的 Python 程序员(尤其是数据科学家)的;我将详细介绍在学习将 Python 本能应用于 Java 领域时可能会遇到的一些最初的概念障碍。特别是,我将避免表面上的差异,比如snake_case
和camelCase
或者 Java 要求你用分号结束一个语句,而 Python 却让它可选。我也将避免在 OOP 和函数式编程中陷得太深。这篇文章的重点是 Java 要求你以不同的方式思考如何解决你正在处理的任何问题。
尽管这看起来令人望而生畏,但请记住,在你之前,许多程序员已经成功地学习了 Java,所以这绝对是可以做到的。
1。Java 的开销比你习惯的要多。
在 Python 中,您可以用一行代码编写一个完整的带有控制台输出的“Hello World”程序:
print('Oh hi there, globe')
要在 Java 中完成这一点,您需要创建一个完整的类,并用一个main
方法作为入口点。
public class Room {
public static void main(String[] args) {
System.out.println("Oh hi there, globe");
}
}
本质上,每个 Java 程序本质上都是某个类的main
方法,它处理变量并告诉其他类做什么(有时,这个main
方法隐藏在自动化文件的深处,就像 Android 项目一样)。尽管有一些方法可以在一个完整的类之外运行 Java 在教学时,我是 j graspj grasp中的interactions
选项卡的忠实粉丝——但是要实现这一点还是有一些困难的。
简而言之,虽然 Python 允许您将一些命令直接输入解释器来测试算法,但是使用 Java 需要您将代码放在上下文中。
然后还有上面Room
中的大象:System.out.println()
。这看起来比仅仅产生控制台输出要多得多,对吗?这是因为我们对我们想要的输出显示方式非常非常挑剔;在我们可以放置该文本的所有不同位置中,我们希望它进入控制台,而不是日志文件、弹出窗口或以太网中的服务器。Python 默认假设到print
你希望文本显示在控制台上,但是 Java 一般不做这样的假设。
这就引出了我们的下一点…
2.Java 要求你比 Python 更具体。
Python 让你逃脱了很多麻烦。想想你写过多少次这样的代码:
that_value_i_need = some_object.mystery_method()
却不得不跟进:
type(that_value_i_need)
为了弄清楚,确切地说,mystery_method()
正在返回。
这不一定是处理事情的最佳方式;显然,医生应该解释你将从mystery_method()
中得到什么,所以绝对有可能你在调用之前就已经知道你将得到什么。但是 Python 让您逃脱了这一点。您可以为that_value_i_need
创建一个变量,并且知道它可以处理mystery_method()
抛出的任何内容。
此外,您可以非常自信地完成像这样的走钢丝行为,甚至不必考虑所涉及的数据类型:
important_value = some_method(a, bunch, of, arguments)
important_value = unrelated_class.another_method()
毕竟important_value
只是一个变量,可以保存它需要的任何数据类型……对吧?
在 Java 中,绝对不是这样。当声明一个变量时,需要从一开始就指定它的数据类型,然后在它的整个生命周期中被锁定。
虽然这一开始听起来令人生畏且有局限性,但我发现在 Java 中阅读别人的代码要容易得多。我可以自信地指着一个变量说,“x
是一个int
,因为它在第 72 行被声明为一个int
。如果它保存的是由someUsefulMethod
返回的值,这告诉我someUsefulMethod
返回一个int
(或者可以提升为int
的东西,比如short
)。
尽管当您尝试运行自己的代码和error: cannot find symbol
消息时,这最初会让您感觉像是一堵不可逾越的保留字墙,浮动在其他人的代码和error: cannot find symbol
消息中,但 Java 要求您如此具体的事实导致代码比 Python 明显更加自文档化、可预测和明确。尽管我在编写 Java 代码时需要更加细致,但我对理解它的工作方式有了明显的信心。
我对自己的 Python 代码的理解的物理表现| Nathan Dumlao 在 Unsplash 上
说到文档,javadoc
是一个生成干净文档的强大工具——即使您没有明确地写下注释(您应该这样做)。javadoc
将读取您的代码并生成有组织的 html 文件,这些文件准确地指出您需要什么数据类型来传递一个方法,以及您可以得到什么值作为回报。大多数 ide 甚至有一个按钮可以帮你做到这一点。
为了让事情尽可能不含糊…
3.Java 比 Python 更严格。
让我们重温一下 Python 中的 Hello World 程序。我们可以有多少种不同的写法?
# version 1 - single quotes
print('Oh hi there, globe')# version 2 - double quotes
print("Oh hi there, globe")# version 3 - triple single quotes
print('''Oh hi there, globe''')# version 4 - uh, triple double quotes, because why not?
print("""Oh hi there, globe""")
Python 为完成同样的任务提供了很多选择——在上面的例子中,我们可以用四种不同的语法来封装我们的字符串。当我学习 Python 的时候,这让我陷入了一个循环;我怎么知道何时使用哪一个?有没有一个优雅的经验法则需要记住?
如果你是一个 Python 程序员,即使经验很少,你也应该知道接下来会发生什么:“大多数人只会用单引号。除非字符串中有撇号,在这种情况下,可以用双引号括起来。除非字符串中既有撇号又有双引号,在这种情况下,您可以用三个单引号将其括起来。我猜,如果字符串中有单引号、双引号、三单引号和三双引号,那么你总是可以回到单引号,并在任何需要的地方使用转义字符。”
因为 Java 是如此的具体和严格,所以学习使用String
要简单得多:总是用双引号将它们括起来。如果在你的String
中有一个双引号,在它前面放一个转义符\
:\”
。如果你的String
里面有一个\
,在它前面加一个转义符:\\
。如果你看到单引号,比如'a'
,那意味着你在处理一个char
,而不是一个String
。
如果你已经习惯于将你能想到的每一个值——从int
到KitchenSink
——放入 Python 中的一个列表,你会发现使用 Java 数组需要一种非常不同的思维方式。Java 数组中的所有元素必须具有相同的数据类型,类似于ndarray
或Series
,但是通过仔细的设计,您可以通过多态引用绕过这个限制。
一个 Python 列表可以容纳所有这些。Java 数组可能不能。|Scott UmstattdonUnsplash
尽管这种特殊性可能令人讨厌,但它使您的代码明显更具有可预测性,这是我的可读性黄金标准。块是用花括号而不是缩进组合在一起的,所以你可以很容易地告诉他们从哪里开始和结束。虽然这在您的计算机上不是一个大问题,但我发现在印刷的 Python 书籍中按缩进分组(其中代码被分成多页)会给初学该语言的人带来问题。
此外,这种严格性意味着变量作用域在 Java 中比在 Python 中更容易理解,如果你尊重花括号,它通常可以归结为“在花括号中定义?只存在于花括号中。实际上,您必须在 Java 中声明对所有类方法都可用的global
变量,而在 Python 中,如果您曾经循环使用变量名,您可能会意外地从程序的完全不同的部分使用语法上有效(但完全不合适)的值。最重要的是,你可以在你的类中拥有private
字段,而不是希望每个人都尊重你的下划线变量名。
如果你犯了错呢?与其让你的代码运行 90%的运行时间,不如在遇到第一个错误时就中止…
4.Java 是编译的,所以很多因误解前面几点而产生的错误在运行前就被捕捉到了。
显然,Python 会在运行代码之前解析代码,如果它不能理解您的意图,就会生成一个SyntaxError
,但是我敢肯定,当您的代码在完成了一半您希望它做的事情之后,因为一个简单的错误而突然停止时,您所有人(尤其是数据科学家)都会感到恼火。
通常(无论如何,根据我的经验),这种情况发生是因为您试图对错误类型的对象执行某种操作——比如调用方法。不是语法错误(你记住了.
!),所以解析器没有捕捉到它,回溯会带您进入核心库的一个兔子洞,所以您可以确切地看到 Python 假设您想要对您给它的神秘对象做什么。
在 Java 中,这一步发生在运行代码之前。因为在声明变量时,您已经将变量锁定为特定的数据类型,所以 Java 编译器可以验证您试图对该对象执行的每个操作在运行时之前实际存在*,如果编译器检测到不是为该数据类型定义的操作,您的程序将根本无法编译和运行。*
这并不是说你永远不会让你的 Java 程序意外终止——这种语言有一个动态的方面,所以你会和NullPointerException
和ArrayIndexOutOfBoundsException
成为非常好的朋友——但是这种额外的验证层,结合 Java 严格和特定的特性,往往会将这些运行时错误引入可预测的小巷。
5.设计 Java 方法几乎与设计 Python 函数完全不同,因此您需要以不同的方式考虑您的问题。
这种严格性的缺点是 Java 方法调用可能很快变得难以控制。我非常喜欢 Python 的功能性,不仅开始依赖无序的关键字参数,还开始传递函数并为可选参数提供默认值。
这是完全有效的 Python 代码…
def multiply(a, b, c=1):
return a * b * cmultiply('hello', 3)
…在 Java 中无法运行。因为 Java 是静态类型的,所以在声明变量时就锁定了数据类型。这意味着您必须以与方法签名中出现的顺序完全相同的顺序传递具有该数据类型的值。虽然这降低了灵活性,但也减少了对代码的误用。
虽然您可以让同名的方法处理不同的参数列表,但 Java 通过重载来处理这一点,这需要您编写不同版本的方法来处理您希望作为参数列表支持的每个数据类型序列。Java 检查您传递的数据类型,查看是否定义了处理数据类型序列的方法,并调用该方法——具有相同名称和不同参数的方法实际上没有任何其他方式的联系。
如果你想为你的一个参数提供一个默认值呢?您必须重载该方法并从列表中删除默认值参数。
事实上,签名是由参数列表中的数据类型定义的,而不是由变量的名称定义的,当您习惯于用 Python 思考时,这也会产生问题。例如,如果我们想为此方法的重载版本提供默认参数:
public static double getArea(double length, double width){
return length * width;
}
如果在参数列表中包含两个具有相同数据类型的版本,我们会遇到问题:
public static double getArea(double length) {
return length * 10;
}public static double getArea(double width) {
return width * 5;
}
这两个方法都被称为getArea
并且都期望一个double
,所以当你调用getArea(12.3);
时,Java 不知道该走哪条路。
除此之外,虽然 Java 确实对 lambda 表达式有一些支持,但它们与函数式编程相差甚远,试图用面向对象的语言来思考函数式解决方案无异于自找灾难。
哦,还有返回类型?Java 将您限制为一种——并且您必须在编写方法时指定数据类型,这要求您提前很好地知道您想要返回什么。你可能习惯于认为 Python 能够返回多个值…
def get_stuff():
return 1, 2, 3x, y, z = get_stuff()
…但它实际上返回一个对象——捆绑到一个元组中的所有值:
>>> type(get_stuff())
<class 'tuple'>
在 Python 中,你可以在不知道这个事实的情况下惊人地高效,但是在 Java 中,你总是必须知道你的方法返回什么。
6.除了数据类型之外,Java 还要求你考虑更低层次的概念,比如内存管理。
这可能有点草率(特别是对于来自没有自动垃圾收集功能的 C 语言的人来说),但是 Java 的某些部分需要您考虑在内存方面发生了什么。我说的是参考变量!
例如,当您尝试在 Python 中运行以下代码时会发生什么?
my_list = [1, 2, 3]
print(my_list)
如果您来自纯 Python 背景,您将会看到以下输出:
[1, 2, 3]
另一方面,您从下面的 Java 代码中得到了什么?
public class JavaFeatures {
public static void main(String[] args) {
int[] myList = {1, 2, 3};
System.out.println(myList);
}
}
没错!它将打印内存地址。这里是我的电脑存储的地方:[I@6d06d69c
同样,Python 假设当您打印引用列表的变量时,您希望看到列表的内容,而 Java 在默认情况下,打印的正是引用变量中存储的内容:数组在内存中的位置。要显示内容,您需要遍历它们:
for (int i = 0; i < myList.length; i++) {
System.out.println(myList[i]);
}
虽然这需要一点点努力来让你的大脑理解,但它迫使你思考当你抛出引用变量(该对象的内存地址)时,实际上传递的是什么*,这让你更深入地了解你的计算机实际上是如何执行其任务的。*
虽然 Java 不像其他语言那样低级,但是从 Java 引用变量跳到 C 指针比从 Python 引用跳到 C 指针要容易得多,因为您已经习惯了遇到上面这种迫使您考虑内存地址的问题。
但是 Python 缺乏“设置好就忘了”的心态并不局限于引用变量。
7.Java 并没有真正意义上的“T1”或“T2”。
当我考虑是什么让 Python 成为一门有用的语言时,我通常不会考虑语言特性或语法。我想到了 Python 生态系统。通过快速浏览命令行,您可以使用类似于
*pip install snazzy_new_library*
下载一个snazzy_new_library
以便随时使用。
尽管你会在 message 上发现有人坚持认为像maven
或gradle
这样的打包工具和pip
或conda
一样强大,但事实是,虽然这些工具确实强大*,但它们并不真正等同于*。* Java 程序的结构通常是不同的——不是让一个包对该环境中的任何程序全局可用,而是将包直接与需要它们的应用程序捆绑在一起,并且通常需要通过将一个 jar 文件放到正确的位置来手动添加,或者包含在一个管理你的依赖性的工具中(这就是像maven
和gradle
这样的工具实际上是*擅长的)。**
这对 Python 程序员来说可能很不方便,因为它要求您跳过额外的关卡,在您的项目中包含一个有用的现有库,结果项目文件的大小可能会变得很大。另一方面,将包含的库与项目捆绑在一起可以确保必要的代码在需要时确实可用。
结论:你可以学习 Java,它会让你成为更好的程序员。
不得不调整自己的问题解决技能以适应新编程语言的怪癖可能是一项可怕的任务,但学会一门新语言确实会扩大你工具箱中的工具库——即使是在你的第一语言中。c 指针让我困惑,直到我习惯了使用 Java 引用变量,Java 中的 lambda 表达式让我困惑,直到我看到它们是如何在 Python 的函数式编程中使用的……这反过来又解释了为什么我们在 c 中需要函数指针。
尽管这看起来令人望而生畏,但请记住,在你之前,许多程序员已经成功地学习了 Java,所以这绝对是可以做到的。
利用 RFM 分析进行客户细分
最后一个聚类模型,你不必花时间去解释
作者图片
任何优秀的数据科学家都(或者至少应该)擅长采用复杂的数学和统计模型,并以简单明了的方式解释它们。最终,我们的工作是为我们的公司或客户创造价值。即使我们有一个准确率为 99.9999999%的模型,管理层也不太可能用它来做决策,除非他们理解(至少)模型的基础知识。
我们的问题
任何业务的很大一部分都是围绕着了解公司的客户,并确保他们的需求和愿望得到满足。这有助于我们确保我们的客户确实在使用我们创造/提供的产品,并确保我们将自己的资源投入到最佳的业务领域。了解我们客户的一个常见方法是将他们分成不同的群体。我们可以把精力集中在代表我们潜在客户的几个不同的群体上,而不是试图为成千上万的个人或公司理解和开发产品。这使我们能够做出更明智、更有针对性的决策,从而产生更大的影响。简而言之,它确保我们看到的是森林而不是树木。
如果你在过去几年中一直在研究机器学习,你的大脑已经自动切换到无监督学习模式,并且你已经在考虑编码一个 k 均值或最近邻模型。我不能否认我通常不在你身边。但是让我们后退一步。有没有更简单的方法?一个几乎不需要向管理层解释的问题?一个计算成本低得多的?
RFM 来了
RFM 分析始于 90 年代中期,当时公司试图为直邮广告寻找最佳群体。大多数网站 Jan Bult 和 Tom Wansbeek 的文章“直邮的最佳选择”出现在*营销科学,*作为第一个出现的想法。这个想法很简单。
“RFM”代表近期、频率和货币价值。总之我们要根据: 对客户进行分组
- 他们最近一次交易是多久前?
- 他们多久购买一次?
- 他们在我们这里花了多少钱?
上个月购买了三件商品的客户比过去三年购买了两件商品的客户更重要。在我们的产品/服务上花了 10,000 美元的客户比花了 50 美元的客户更重要。正如您所看到的,这种方法几乎不需要(如果有的话)解释。
分析的实现同样简单。对于每一组(R,F,M ),我们将把我们的客户分成 N 个部分。然后,我们将从 1 到 N(1 为最佳)对每个组进行排名。最后,我们可以按原样使用我们的 RFM 分数,或者我们可以使用某种聚合方法为每个客户开发一个超级分数。
我们开始吧
首先,我们需要一份我们正在分析的时间段内所有发票的清单。对于每张发票,我们只需要三样东西:
- 客户名称
- 发票日期
- 金额。
对于任何分析师来说,这应该只不过是一个简单的 SQL 查询。
然后,我们将把 SQL 数据放入 pandas 数据帧中。(本例中的数据已被匿名化。)
作者图片
我们现在将创建一个新的数据框架(rfm ),用于存放我们的 RFM 指标。我们的新数据框架将包含每个客户的一行,以及他们各自的 R、F、M 评级。
我们需要一些辅助函数来生成我们的指标。我们可以用熊猫的申请来使用我们的数据。
最后,我们需要最后一点代码来将我们的客户分成 N 组,并分配一个等级。在这个例子中,我选择了 4 个组,并基于简单的四分位数进行划分。
我们的排名现在完成了。现在,我们可以深入分析,找出对管理有用的不同部分。
作者图片
最终分析
通过 RFM 分析,我们可以选择许多不同类型的客户群。当然,我们的最佳客户(最近频繁购买,花了很多钱)用 R=1,F=1,M=1 表示,或者更简单地用(1–1–1)表示。以下是其他一些著名团体的名单:
- 低消费但积极忠诚的客户—(1–1–3 | 4)
- 我们放过的最佳客户(4–1 | 2–1 | 2)
- 新的大型消费客户(1–4–1 | 2)
- 这个清单还在继续。
所有这些部分都可以通过简单的 pandas 过滤器轻松访问。
当然,没有可视化的分析会是什么?RFM 分析的一个小的附带优势是它提供了 3 个维度——使其易于可视化。让我们一起走进它。
作者图片
结论
当然,这种分析不像 k-means 或几乎任何真正的机器学习算法那样优雅或激烈——但这不是我们所追求的。我们用优雅换取了轻松和简单。
生成数据、编码解决方案以及审查结果可能只需要你喝一杯咖啡的时间。我们也不需要 GPU…从开发和计算的角度来看,这种分析是成功的。
正如我们在开始时所讨论的,我们的工作是为决策者提供可行的见解。在这里,时间就是金钱。我们方法的简单性节省了我们的时间(因为我们不需要开发 10 页的 PowerPoint 来解释我们的方法)并节省了管理时间(因为他们不需要坐在那里看完你的 PowerPoint)。然而,最终我们提供了可操作的细分市场,可用于整个营销和产品开发。
你会用这些空闲时间做什么?
附言
- 如果您想进一步压缩数据,您可以将 R、F、M 指标相加,产生一个超指标。
- 如果你想得到更精细的结果,使用更多的箱子而不是我上面用的四分位数。
- 如果一个或两个指标比其他指标更重要,将指标与加权和结合起来以反映这一点— a® + b(F) + c(M) = y,其中 a+b+c = 1。
- 定制这种简单方法的能力是非常了不起的。
感谢您抽出时间阅读。我真的很感激。完整的代码可以在我的 GitHub 上找到。
原载于 2020 年 10 月 15 日【http://lowhangingfruitanalytics.com】。
使用 BigQuery ML 进行 RFM 分析
使用 BigQuery ML 中的 RFM 分析和 Data Studio 中的可视化进行用户细分。
图片由皮克斯拜的 Gerd Altmann 提供
假设您想通过使用存储在 BigQuery 中的谷歌分析数据,基于用户的网站应用活动创建细分市场,从而为用户的转化和重新激活进行再营销。
在本指南中,我将展示如何实现一种流行的技术来细分用户,并将结果可视化,以帮助做出重要的营销决策。
我们将经历的技术是 RFM 分析。我们将使用 BigQuery ml 来创建分段,并使用 data studio 来可视化结果。这是它的样子。
细分用户的仪表板,作者 Muffaddal
在本指南中,我们将:
首先,计算用户的最近度、频率、和货币价值。
其次,使用 k-means 聚类算法创建 客户细分。
第三,在 data studio 中可视化结果。
第四,将 RFM 的分析结果导入谷歌分析进行激活
第五,自动化 RFM 分析流程。
注意:如果你有兴趣在 GCP 探索更多这样的技术,这里的 是一个很好的课程,可以从 Google 的 开始。
什么是 RFM 分析?
客户细分策略之一是使用 RFM 分析创建用户群组。它基于用户过去的活动。它使用三个指标来执行分段:
- 最近度:自上次购买后的天数。
- 频率:用户购买的次数。
- 货币:用户在购买上花费的总金额。
主要用于购买,但 RFM 分析也可以定制用于其他重要的用户活动,如查看的页面数量,而不是购买基于内容的业务的次数,如medium.com。
利益
RFM 分析的好处是,由于用户是根据他们过去的活动进行细分的,我们对他们与业务的密切关系有一个很好的了解,因此每个细分市场都可以有针对性。
举个例子,一个经常在网站上购物的用户,他的平均购买量也很高,我们立刻知道这是一个忠实的客户,应该用来传播口碑。而另一方面,可以向最近购买但不经常购买的用户群提供折扣优惠,以帮助他更习惯该产品。
RFM 分析可以有所帮助
- 增加客户保留率
- 增加响应速率
- 增加转换率
- 增加的收入
- 增加电子邮件中心
data camp 上有一个关于使用 RFM 分析进行用户细分的很好的教程,可以帮助进一步理解这种用户细分技术背后的直觉。如果你有兴趣,一定要去看看。
在第一章中,您将了解群组以及如何分析它们。您将创建自己的客户群…
bit.ly](https://bit.ly/2BfqNoI)
计算 RFM 值
为了计算 RFM 分析,我们需要三个指标,即用户 id (在我们的例子中是 GA 客户端 id)转换事件日期(在我们的例子中是购买事件日期),以及购买事件支付的金额。
Muffaddal 用于 RFM 分析的主数据集表
注意: 我会假设你的数据是上面描述的格式。如果不是,那么你要么转换你的数据为上面的格式,要么修改下面的查询。
首先,我们将使用下面的查询计算每个用户的最近次数、频率和货币值。
使用 SQL 计算用户的近期、频率和货币价值。
用您的数据表名称替换line 9
上的<your table >
,运行上面的查询应该会得到您的每个用户的最近值、频率和货币值。姑且称之为query 1
该查询的输出将如下所示:
用户的新近性、频率和货币价值
将查询的输出保存为名为RFM_Values
的大查询数据表,如下所示
如何用 Muffaddal 将查询结果保存为 BigQuery 表
接下来,我们应用 k-means 聚类,根据用户的 RFM 值对他们进行分组。
基于 K 均值聚类的用户细分
使用 BigQuery ml,我们可以将机器学习模型直接应用于 BigQuery 中的数据集。使用 BigQuery ml 进行客户细分也相当简单。
要使用 BigQuery ML 算法,请使用命令CREATE OR REPLACE MODEL
启动您的 SQL 查询。这告诉 BigQuery 将机器学习算法(在 options 命令中提到)应用于查询的 out。
下面是如何使用 BigQuery ML 对上一次查询得到的结果应用 k-means 聚类:
使用 Biguqery ML 创建 k 均值模型
用您想要存储模型输出的表的名称更新devtest.Demo.RFM_Model
,并在line 10
更新项目和数据集值。运行查询,您将在数据集中创建一个新表。我们称之为我们的query 2
。
导航到模型化表的评估选项卡以查看统计数据。它应该是这样的:
k-均值模型输出,用 Muffaddal 表示
Centroid id
列,说明模型将我们的用户分组到了哪个细分市场。和 count 展示了每个细分市场中的用户数量。
如果我们把眼光放在最近、频率和货币列上,我们可以检查该模型根据什么对所有用户进行分组。
例如,Centroid id
列中的第四部分是不经常使用该应用程序的用户,他们最近也不活跃。然而,他们的购买力是其他细分市场中最高的。
另一方面,第一部分用户和第四部分用户一样活跃,但是他们的购买力有点低。
由于这两个用户都已经超过 2 个月(平均 74 天)没有使用我们的网站,他们可能会有所改变,我们应该计划一个营销策略让他们回来。
注意:假设我的数据模型产生了具有 5 个聚类的最佳片段(参见查询中的 *line 4*
)。在您的情况下可能会有所不同,所以检查不同数量的分类的结果,看看哪一个给了您最好的分段。
一旦我们创建了我们的细分市场,是时候将它连接回 user_id,以便我们可以使用它来重新定位它们。
下面是执行此操作的查询:
查询来生成细分用户的最终表。
注意:我已经在上面的第 15 行将每个细分市场命名为细分市场 1、2 等,但是我将建议给它们一个适当的名称,如忠实用户、潜在用户、流失用户等。
我们将最后一个查询称为query 3
结果如下所示:
Muffaddal 的分割结果
将其保存为 BigQuery 表RFM_Final
,用于分析和仪表板。
在 Data Studio 中可视化 RFM 分析结果
下一步是将我们的RFM_Final
表连接到 Data Studio 并可视化结果。接着,根据我们最终的数据表创建了一个模板仪表盘。
RFM 仪表板,由穆法达尔
它在顶部显示了所有近期、频率和货币值的平均值。理想情况下,平均最近值应该最小,频率和货币值应该最大,这样顶部的 KPI 指标有助于查看应用程序的当前排名。
之后,控制面板将三个指标按细分市场进行细分,以帮助了解它们的分布情况。通过过滤报告,我们可以彻底检查每个细分市场。
Data studio 的混合也可以用于将这些细分市场与用户的其他活动联系起来,以丰富报告并进一步深入行为分析。
最棒的是,每当RFM_Final
表更新时,我们的仪表板就会自动更新。我们还将看到如何自动进行 RFM 分析,以及时更新用户群。稍后将详细介绍。
注意 : 该模板是用 google sheets 而不是 BigQuery 构建的,以避免成本,但它应该也可以与 BigQuery connector 一起重用。
基于 RFM 结果重定向用户
现在你已经将你的用户细分并可视化了。其中一些将是高付费的忠实用户,而一些将是失去的用户,需要大量有针对性地重新激活他们。所以下一步是用不同的活动和促销来推销它们。
但是怎么做呢?
想法是将与每个用户相关的部分发送到谷歌分析,并从那里创建一个观众和目标,因为你喜欢使用谷歌广告。因此,我们必须将丰富的数据发送给谷歌分析。
我们也可以在这里利用 GCP。这样做使得我们所有的数据都在一个平台上。我们必须建立一个数据管道,将数据导入谷歌分析。要设置管道,请在云 shell 中输入以下命令来安装所有必需的依赖项:
git clone [https://github.com/GoogleCloudPlatform/cloud-for-marketing.git](https://github.com/GoogleCloudPlatform/cloud-for-marketing.git)
安装完成后,我们所要做的就是将数据从RMF_Final
表移动到云存储,数据将自动导入 GA!
这里是 关于如何设置 GA 导入数据管道 的详细指南。
数据管道继续监视云存储桶中安装期间提到的文件夹,当它看到任何新的上传文件时,管道会处理它并将其发送到 google analytics。
自动化 RFM 分析
运行上面讨论的所有三个查询,将在您需要的任何时候为您的用户群获得更新的细分市场。但是,我们也可以自动执行这一手动流程,以便根据业务需求每月/每季度更新细分市场。
注意:自动化过程需要一点编程知识,因此您可能需要请团队中的技术人员来实现自动化过程。
我们有三个查询需要及时运行,以便从用户群中创建细分市场。首先,计算 RFM 值(Query 1
)。第二,创建模型(Query 2
)。第三,合并模型输出和用户 RFM 值(Query 3
)。
想法是链接所有三个查询,以便一个查询的完成执行另一个。
下面是数据流的样子:
RFM 自动化数据管道,由 Muffaddal
注意 : 我将假设已经为所有三个查询创建了表,如以上部分所示。
1-让我们首先创建一个发布/订阅主题,因为在创建 query 1 schedular 时会用到它。我将其命名为RFM_Model_Topic
,因为它将触发负责执行我们的模型查询(即查询 2)的云函数。
RFM _ 模型_Topic
发布/订阅主题,作者 Muffaddal
复制主题名称,因为在创建query 1
schedular 时需要它。
2-接下来,转到 BigQuery,在查询编辑器中粘贴查询 1,它为我们的用户计算 RFM 值,然后单击“Schedule query”按钮创建新的查询 schedular。
通过 Muffaddal 创建新的计划查询
3-然后,在调度程序创建菜单中输入所需的值来创建调度程序
查询日程创建菜单,按 Muffaddal
这个 schedular 将做的是,它将在指定的时间运行,以计算用户的最近、频率和货币值,并存储在上述 BigQuery 表中。一旦调度完成执行查询,它将向我们的RFM_Model_Topic
发送一条消息,这将触发一个云函数来触发我们的模型查询。所以现在让我们创建一个云函数。
4-进入RFM_Model_Topic
发布/订阅主题,点击屏幕顶部的“触发云功能”按钮。
由 Muffaddal 从发布/订阅主题创建云函数
5-进入如下所示的设置,并将云功能命名为RFM_Model_Function
云功能设置,由 Muffaddal
6-将下面的代码粘贴到index.js
文件中
运行 RFM 模型查询的云函数
一旦我们的 BigQuery 被执行,我们就向一个名为RFM_Final
的新发布/订阅主题发送一条发布消息,这触发了负责我们最后一个查询的云函数,该查询将 RFM 值和模型结果组合在一个数据集中。
7-因此,接下来,在发布/订阅中创建RFM_Model
主题和一个云函数,就像我们在上一步中做的那样。将下面的代码复制粘贴到云函数中,这样它就可以运行我们最后的查询了。
运行 RFM 最终查询的云函数
就是这样!
我们自动化了 RFM 分析流程,该流程将在每个月初自动更新我们的仪表板。
摘要
通过个性化营销瞄准细分用户,可以提高留存率、转换率和收入。RFM 分析根据用户在网站/应用程序上的活动创建用户群组。
在本指南中,我们通过利用 BigQuery ML 使用 SQL 查询执行了 RFM 分析,并在 data studio 中可视化了结果。我们还谈到了如何通过向 Google analytics 导入数据来定位细分用户。最后,我们建立了数据管道来自动化整个 RFM 分析过程,这样我们就可以每月获得更新的用户群。
我希望我能够传达这样一个想法,即我们可以毫不费力地从现有的数据中提取出多少信息。以及支持和改进业务的有效性。
您喜欢的类似分析阅读:
根据用户的购买行为对其进行细分,从而改进广告活动。
towardsdatascience.com](/user-segmentation-based-on-purchase-history-490c57402d53) [## 向 BigQuery 发送 Google Analytics 点击量数据
如何发送标准的谷歌分析点击量数据到 BigQuery?
towardsdatascience.com](/send-google-analytics-hit-level-data-to-bigquery-5093e2db481b) [## 将细分的用户数据发送到 Google Analytics 进行重新激活。
建立一个数据管道,使用 Google Cloud Platfrom 将数据导入 google analytics。
towardsdatascience.com](/automate-data-import-to-google-analytics-471de2c3fc76) [## 通过个性化推荐增强用户体验
本指南将详细介绍基于项目的推荐系统的工作原理以及如何在实际工作中实现它…
towardsdatascience.com](/comprehensive-guide-on-item-based-recommendation-systems-d67e40e2b75d)
信用卡客户的 RFM 聚类
客户信用卡交易数据的新近性、频率和货币值(RFM)的 K 均值聚类案例研究
在 Unsplash 上由 Adeolu Eletu 拍摄的照片
新近、频率、&货币(RFM) 是可用于客户细分的技术之一,也是长期使用的常规细分方法之一。
- 最近是指客户最近一次使用我们的产品进行交易的时间
- 频率指客户使用我们的产品进行交易的频率
- 货币价值是指顾客在我们的产品上花了多少钱
RFM 方法简单明了;我们只需将我们的数据(通常以交易数据的形式)转换成由三个变量组成的数据框架: 、最近交易、 和 交易金额(货币值)。
交易数据本身是记录或捕获客户所做的每一笔交易的数据。通常,交易数据包括交易时间、交易地点、客户消费金额、交易发生在哪个商家,以及交易发生时可以记录的每一个细节。
让我们看看稍后将用作我们的研究案例的事务性数据集。我们的数据集是 2016 年每个客户的信用卡交易数据。交易数据集由 24 个特征组成,记录了客户进行的每一笔交易。即使我们的数据集中有许多特征;我们不会使用所有这些特征,而是仅使用少量的特征,这些特征可以转换成 新近度、频率、 和 货币值 。
链接到数据集:https://www . ka ggle . com/derykurniawan/信用卡交易
图一。交易数据特征
如果我们回到我们对 RFM 特征的描述;我们只需保留 *customerId、transactionDate、*和 transactionAmount 即可在由 customerId 特征分组的新数据帧中创建新近度、频率、和交易金额特征。
对于 Recency 特性,我们可以用 transactionDate(最新交易)的最大值减去当前日期。由于我们的数据集仅包含 2016 年的交易数据,因此我们将 2017 年 1 月 1 日设置为当前日期。
对于 Frequency 特性,我们使用 r 中的 n() 函数计算每个客户进行了多少次交易
对于交易金额功能,我们计算每个客户的交易金额总和。
将事务数据导入并转换为 RFM 数据
图二。RFM 数据集的前六行
现在我们有三个 RFM 分割的主要特征。这与任何其他数据分析情况类似,我们必须做的第一步是探索我们的数据集,在这种情况下,我们将使用 r 中的 hist() 函数使用直方图来检查每个特征分布。
图 3 RFM 特征数据直方图
我们的 RFM 数据集是如此右偏,这在 K-Means 聚类方法中将是一个灾难性的问题,因为该方法使用点之间的距离作为其计算之一来确定哪个聚类是最适合的点。 Log 变换可以用来处理这种倾斜的数据,由于我们在数据中有 0 (零值),我们将使用 log(n + 1)来变换我们的数据,而不是普通的 Log 变换。
对数变换和直方图
图 4。RFM 要素数据的直方图-对数标度
对数变换为 K-Means 方法提供了更好的数据,通过去除 RFM 数据集中的大量倾斜数据,为我们的数据计算和找到最佳聚类。
k 均值聚类
根据定义,K-Means 聚类方法是一种无监督学习,用于根据相似性将未标记的数据定义为组。
在 R 中,K-Means 聚类可以使用 kmeans() 函数快速完成。但是,在创建 K-Means 模型之前,我们必须找到聚类的数量。有很多方法可以找到要分配的最佳组数,其中一种是通过使用我们的商业感觉并直接分配数量,或者我们也可以使用数学感觉来计算每个点之间的相似性。
在本例中,我们将使用组内平方和来衡量每个组内观察值的可变性。我们将在 1 到 10 的范围内迭代计算每个聚类的类内平方和,并选择具有最低值且值没有进一步显著变化的组作为其下一个聚类,或者我们通常称之为 肘方法 。
R 中的肘法
图 5 数据集肘方法可视化(N = 4)
使用肘方法,我们将分配四个组作为我们的组数。使用 R 中的 kmeans() 函数,我们只需将聚类数放入 centers 参数中,并将聚类结果分配到我们的数据集中。
k 均值模型和细分汇总
图六。添加段后的数据集
现在,我们已经在细分功能中将每个客户 ID 分配到他们的组中。在下一步中,我们将通过根据段号对 RFM 特征的平均值进行分组来检查每个段的基本 RFM 轮廓。
图七。每个细分市场的 RFM 汇总
因此,我们有四组,让我们讨论每组的细节:
- **Segment-1(白银)😗*交易频率和消费金额位居第二的中产阶级客户。
- Segment-2 (Gold): 消费金额最大、交易次数最多的最有价值客户
- **细分市场-3(青铜级)😗*交易频率低、消费金额低的普通客户。但是,这个细分市场拥有最多的客户。
- **细分-4(不活跃)😗*不活跃/不太活跃的客户,最近的交易发生在一个多月前。该细分市场的客户数量、交易频率和交易金额最低。
现在,我们有四组顾客,每组都有详细的 RFM 行为。通常,这些信息可用于安排针对具有相似行为的客户的营销策略。 新近性、频率、 和 货币价值 细分很简单,但对于更好地了解您的客户以及制定高效和最佳的营销策略非常有用。
更丰富的缺失值
探索更强大、更灵活、更安全的数据框架
(图片由作者提供)
我的工作职责之一是维护调查数据的收集。起初这是一个简单的项目。通过一个简短的脚本,我可以将第一波数据编译成一个组织良好的数据框架,以几种不同的方式对其进行总结,然后发送一份报告。但是,一名参与者没有回应就离开了研究。另外几个参与者答错了一个问题。后来,在已经收集了几十个回答之后,我们在调查中添加了一个新问题。随着每一个新问题的出现,数据变得越来越难以维护。
每次数据丢失时,不管原因和后果如何,它都会被替换为相同的值NA
。这种过度简化导致了各种各样的问题。丢失的值看起来一样,所以更容易预测我可能在数据集中遇到什么值。但是它们以不同的方式影响计算,我发现很难验证操作是否安全地处理它们。我寻找方法来表现NA
背后的真实故事,但是我找到的解决方法冗长而复杂。NA
的简单性让我的代码变得更加复杂。
改进NA
最有用的方法是将它分成两个值:一个适用的缺失值和一个不适用的值。考虑一个新的调查问题的例子,它是在收集了一半的回答后添加的。没有回答可能有两个原因:要么有人跳过了这个问题,要么根本没人问过他们。第一种是适用的;第二种不是。如果您正在取平均值,您可以安全地删除不适用的值。但是忽略适用的缺失值是不安全的,因为了解它们的真实值(或估算它们)会改变您的结果。
不幸的是,大多数编程语言,包括 R 和 python,都很难表示这些信息。在 R 中,NA
被视为未知但适用的值。如果你试图用什么东西把它加上,就会导致另一个NA
。但是没有办法表示另一种不同的缺失值。由于您无法区分不同类型的NA
,您必须自己检测并处理它们。
在实践中,人们使用许多不同的方法来解决这个问题。一种选择是使用插补方法处理所有适用的缺失值,然后大胆使用大多数算术和统计函数中可用的na.rm = TRUE
选项。这将所有的NA
视为不适用,允许您在不删除缺失值的情况下进行求和或求平均值。但是盲目地删除丢失的值可能是不安全的。在NA
可能适用的情况下,我们几乎总是希望总和缺失,因为这有助于我们解释结果。缺少结果意味着还有一个缺少的值需要处理。一个真实的值保证我们完成了。
为了避免na.rm = TRUE
,您可以创建指示记录是否适用的变量。这看起来更安全,但是会变得冗长。你开始积累像sum(variable[isApplicable])
这样的表达式,而不是简单的sum(variable)
,数据变得越复杂,就越难记住如何写isApplicable
。你将需要多个指标变量,每一个都代表你想确定某件事是否适用的一种方式。而且数据结构也不能告诉你哪个指标变量对应哪个数据变量,你必须自己去跟踪它们。这可能会导致一系列完全不同的错误。
第三个也是最好的策略是将数据分割成更小的data.frame
,这种方法可以消除任何有问题的缺失值。为此,您将具有相同缺失值的记录分组,这样它们根本不需要缺失列。目标是删除所有不适用的值,这样每个NA
都可以被明确地视为适用的,前面的解决方法都没有必要。缺点是一些数据集需要大量的表,跨不同的表工作比在一个表内工作更困难。尽管这种方法比其他两种方法干净得多,但它仍然增加了复杂性,并增加了工作量。
关系数据库理论的启示
1986 年,E.F. Codd 写了一篇名为“关系数据库中缺失信息(适用和不适用)”的论文几年前,Codd 开发了关系数据库的理论,这是一个非常流行的模型,它和矩阵一起启发了数据框架的设计。(事实上,Hadley Wickham 著名的“整齐”数据概念是明确基于 Codd 的第三范式)。在 1986 年的论文中,Codd 探讨了缺失数据,并回答了在关系数据库中如何处理缺失数据的问题。当时最流行的方法是选择值,比如-99,来表示不同类型的缺失。这给用户带来了正确解析值以操作数据的负担。这是一种有缺陷且不安全的方法。
Codd 提出了一个 A 标志和 I 标志系统,其中 A 适用于缺失,I 不适用。他的论文描述了数据库如何处理,而不仅仅是表示两种缺失的信息,这样就不再需要特殊的值或额外的变量。在后来的一篇论文中,Gessert 讨论了它如何优于删除所有不适用的值的拆分表的解决方案,这给程序员和用户带来了许多不必要的工作。因为数据库可以理解丢失的值,所以它可以适当地处理它们,从而避免用户采取变通办法。
在他的论文中,Codd 概述了在计算中组合时如何处理值、缺失值和不适用值的建议。他说 I 标记应该被认为比 A 标记更强,A 标记应该比值更强,并且组合不同类型的运算应该返回更强的值。比如 A + 2 = A:和是未知的,因为 A 的值是未知的。类似地,A + I = I,这是合适的,因为 A + I 的和是无意义的;它不能适用于任何事情。同样的规则适用于所有算术运算,以及其他运算,如连接。
当运算是逻辑运算时,例如相等或比较,规则会更复杂。Codd 给出了一个简单的例子:像“出生日期> 1–1–66”这样的语句的值是多少?生日有了就是真的假的,其他的就不得而知了。所以,Codd 提出了一个三值逻辑,包括真、假、可能。
三值逻辑今天被广泛使用。在 R 中,MAYBE 表示为逻辑“NA”。逻辑运算比只有真和假更复杂,因为也许不能解释为一个具体的逻辑值。相反,也许是一个暂时的占位符,反映了我们目前对其真实价值的不确定性。例如,在 R 中,NA | TRUE
的计算结果为TRUE
,因为无论左侧发生什么情况,它都为真。然而,NA | FALSE
就是NA
,因为不学习缺失的信息,我们无法确定真实的价值。AND 运算的逻辑是相似的。NA & TRUE
是NA
,因为我们分不清它是什么,而NA & FALSE
明明是FALSE
。否定是最简单的运算:!FALSE
是TRUE
,!NA
是NA
。三值逻辑起初可能是违反直觉的,但所有规则都源于NA
的中心原则:它不是一个值,而是一种不确定的状态。
虽然三值逻辑是处理缺失数据的最简单方法,但 Codd 很快意识到这是不够的。在第二年的一篇后续文章中,他提出了一个四值逻辑,就像他的 A 分和 I 分一样,区分了适用的也许和不适用的也许。有趣的是,Codd 写道,他不认为实现这种逻辑值得付出努力,但指出它比三值逻辑更精确。他期望它以后会被集成(事实并非如此)。
四值逻辑扩展三值逻辑,就像 A 标记和 I 标记扩展缺失值一样。就像 I-marks,I-MAYBE 比 A-MAYBE 强,所以 A-MAYBE & I-MAYBE 就是我-MAYBE。在 AND 运算的情况下,最强的值是 false,因为无论另一端的值是什么,结果肯定是 FALSE。类似地,带有 TRUE 的 OR 将始终为 TRUE。最复杂的表达是 I-MAYBE | A-MAYBE,也就是 A-MAYBE。这是因为-MAYBE 是一个逻辑值的占位符,如果该值为真,表达式总体上也将是有意义的——它将为真。表示一个潜在的真实但未知的值的最好方法是一个也许。
Codd 对四值逻辑喜忧参半,认为它可能太复杂而不值得。他认为关系数据库的用户更喜欢简单的系统,而不是复杂的系统,因为复杂的系统需要太长的学习时间。但是,尽管三值逻辑比四值逻辑简单,但它的表达能力却远不如四值逻辑。ge sert后来为四值逻辑辩护,给出了一个欠下费用的简单例子。关键是要知道费用是因为还不知道而缺失,还是因为不适用而缺失。Gessert 说,将数据库限制为三值逻辑会阻止用户充分利用这一区别。他建议添加能够处理新的缺失值的新操作符,并指出这些操作符对于用户来说很容易学习,这样他们就会完全理解新的逻辑。
A-marks、I-marks 和四值逻辑都在简单和强大之间呈现相同的选择。这些特性无疑增加了数据和管理数据的系统的复杂性,但是它们也增加了表现力。如果我们能区分数据中适用的和不适用的信息,我们就能更有效地操作数据,更安全地进行计算。当适用的缺失值可能掩盖错误或使我们的结果有偏差时,这种区别就至关重要。
数据框架的含义
Codd 和 Gessert 探索的理论很重要,因为数据框架与关系数据库具有相同的语义。在 R 的 dplyr 包中,许多函数是以它们的 SQL 等价物命名的:select()
、*_join()
、coalesce()
,还有更多函数的行为与它们在 SQL 中的行为完全一样。在 R 中,NA
相当于 SQL NULL
。和 SQL 一样,R 不实现任何类似 Codd 的 A 标记和 I 标记的东西。仅限于三值逻辑,其中 maybe 值表示为NA
( NA_logical_
)。
如果这些数据结构能够区分适用的和不适用的缺失值,计算将变得更加简单。我们将放弃所有不适用的值,而不是使用当前的选项之一——依赖于na.rm = TRUE
,或者选择记录的子集,或者拆分表。例如,如果我们想要添加一个包含美元值的变量,我们可以安全地丢弃任何不适用的条目。但是,如果有一个适用的缺失值,我们将传播这种不确定性,我们的结果将是“适用的缺失”这比任意丢弃所有缺失的值要安全得多,并且不需要我们编写额外的代码来选择适用的记录。它比只有一个NA
更安全、更高效。
A 标记和 I 标记的系统也使得数据的结构更加灵活。例如,从同一组个体的多次观察中收集数据是很常见的。你可能有一些你在每次观察中收集的变量,还有一些描述个体的变量。问题是,一个人的变量只有在你从他们那里收集到至少一个观察结果时才会显示出来。如果没有观察到,该个人将被删除。I 标志使这变得更容易。我们为每个个体添加至少一行,并包含描述变量;但是每当个人没有数据时,我们将所有数据字段标记为不适用。理论上,同样的方法可以用来表示任何形状的数据,或者组合任何数量的表,而不会丢失信息。
Codd 提出的这个系统已经很强大了,但是还可以进一步扩展。我们可以有额外的标记来记录在某些操作或其他条件下的适用性。我们可以将标记扩展到已知的值,这样已知的值也可以由于不适用而从某些计算中删除,并且我们可以将它们用作分组数据的方法。标记可以通过多种方式进行扩展,将简单的数据结构与混乱的现实环境相匹配。
在 R 中实现一个丰富的缺失值系统
R 中最近的发展使得实际实现这些想法成为可能,因此有必要简要地探讨一下这是如何工作的。历史上,我们一直局限于原子的,基本的 R 向量。原子向量中的每个值都是相同的类型。在 double vector 中,每个值都必须是 double 或NA_real_
。但是 vctrs 包提供了一种方法来实现行为类似向量的对象。它的工作方式是为所有的 base R 函数提供替换,包括构造函数、造型、用[
和[[
设置子集、算术和其他计算,以及用format
进行可视化输出。因为对象比原子向量更灵活,它们可以建模适用和不适用的类型。
一种可能的提议是使用记录结构来表示 A 标记和 I 标记,该记录结构具有一个用于数据的字段和一个用于标记的字段。缺失值可以在数据字段中表示为NA
,在标记字段中表示为A
或I
。通过在新类型的向量上实现基 R 函数,我们可以实现我们想要的行为。
一旦我们实现了数据结构,我们就可以为它编写更好的函数。首先,我们可以默认丢弃不适用的遗漏。这尤其与sum()
、mean()
、quantile()
、%in%
、Reduce()
(或purrr::reduce()
)等功能相关。其次,我们可以实现二元操作符,使它们符合 Codd 的算术规则。特别是表达式A + A
应该是A
,I + I
应该是I
,A + I
应该是I
。最后,我们可以实现四值逻辑,扩展 base R 的三值逻辑来考虑适用和不适用的结果。这将导致 A 和 I 标记系统的完整实现,并且是我计划探索的项目。
简单的代价
因为数据集是复杂的,所以拥有有用的数据表示是非常有价值的。数据集的理论计划可能会很快因现实世界的问题而偏离轨道,如不完整、损坏或丢失的数据。尤其是丢失的数据变得难以解释,并且执行计算变得更加困难。这在操作简单的结构和复杂但能以更细微差别表示数据的结构之间产生了矛盾。
毫无疑问,学习如何处理包含适用和不适用缺失值的数据集需要付出额外的努力。NA
本身就足够令人困惑了(首先,实际上有五种不同的NA
)。两个缺失值的存在改变了所有常规操作的工作方式,虽然它们的行为受一组核心原则的指导,但人们需要时间来学习如何有效地使用它们而不出错。当用户不完全理解复杂的工具时,它们可能是危险的。
但是额外的复杂性通常是合理的。当我们使用只有一个缺失值的数据结构时,我们被迫编写代码来选择我们想要操作的记录,或者将我们的数据拆分到不同的表中。因为我们的数据过于简单,我们被迫使我们的代码更加复杂。而且因为我们的代码比较复杂,会容易出错,很难维护。相比之下,更强大的缺失值表示可以提供更简单、更可靠的方法来操作数据。
自从第一个关系数据库出现以来,用户和开发人员一直选择简单的设计,以便于学习和使用。但是有时候一个听起来很复杂的想法和现实世界的混乱是绝配。
笔记
一个 R 基函数有一个有趣的行为:%in%
。默认情况下,它实际上会丢弃丢失的值。我们期望4 %in% 1:3
是FALSE
,但是我们也期望4 %in% c(1:3, NA)
是NA
,因为我们不能排除最后一个值是4
。这种实现反映了大多数人用%in%
和用sum()
思考缺失值的方式不同,但这显然与其他逻辑运算不一致。通过区分适用的和不适用的缺失值,我们可以用一种既正确又直观的方式重新实现它。
NA
是一个逻辑值,放在任何非逻辑向量中都是非法的。相反,R 为整数向量定义了NA_integer_
,为双精度数定义了NA_real_
,为复数定义了NA_complex_
,为字符串定义了NA_character_
。通过c()
的工作方式和 R 打印出向量的方式,这些对用户是隐藏的。
Rick 和 Morty 使用变形金刚和 Streamlit 通过 GPT2 生成故事
贝尼尼奥·霍尤拉在 Unsplash 上拍摄的照片。
这篇文章将向你展示如何使用 Hugging Face 的 Transformers 库在 Rick 和 Morty 的抄本上微调一个预训练的 GPT2 模型,构建一个演示应用程序,并使用 Streamlit 共享部署它。
介绍
随着机器学习(ML)和自然语言处理(NLP)的快速发展,新算法能够生成看起来越来越像人类制作的文本。其中一种算法 GPT2 已经在许多开源应用程序中使用。GPT2 在 WebText 上接受训练,WebText 包含来自 Reddit 的 4500 万个出站链接(即评论引用的网站)。排名前 10 的出站域名包括谷歌、存档、 Blogspot 、 Github 、 NYTimes 、 WordPress 、华盛顿邮报、 Wikia 、 BBC 和卫报。预训练 GPT2 模型可以在特定数据集上微调,例如,以“获取”数据集的样式或学习对文档进行分类。这是通过迁移学习完成的,迁移学习可以定义为“从源设置中提取知识并将其应用于不同目标 setting"⁴.的一种方式有关 GPT2 及其架构的详细解释,请参见原版 paper⁵、OpenAI 的博客 post⁶或杰伊·阿拉姆马的插图 guide⁷.
资料组
用于微调 GPT2 的数据集由 Rick 和 Morty 抄本的前 3 季组成。我过滤掉了所有不是由里克、莫蒂、萨默、贝丝或杰瑞产生的对话。数据被下载并以原始文本格式存储。每行代表一个说话者和他们的话语或一个动作/场景描述。数据集被分为训练和测试数据,分别包含 6905 和 1454 行。原始文件可以在这里找到。训练数据用于微调模型,而测试数据用于评估。
训练模型
抱抱脸的变形金刚库提供了一个简单脚本来微调一个定制的 GPT2 模型。你可以使用这款谷歌 Colab 笔记本来微调你自己的模型。一旦您的模型完成了训练,确保您下载了包含所有相关模型文件的已训练模型输出文件夹(这对于以后加载模型是必不可少的)。你可以在拥抱脸的模型 Hub⁸上传你的定制模型,让公众可以访问它。当在测试数据上评估时,该模型获得了大约 17 的困惑分数。
构建应用程序
首先,让我们为 Python 3.7 创建一个名为Story_Generator
的新项目文件夹和一个虚拟环境:
mkdir Story_Generator
cd Story_Generator
python3.7 -m venv venv
source venv/bin/activate
接下来,我们要安装项目的所有依赖项:
pip install streamlit-nightly==0.69.3.dev20201025
pip install torch==1.6.0+cpu torchvision==0.7.0+cpu -f [https://download.pytorch.org/whl/torch_stable.html](https://download.pytorch.org/whl/torch_stable.html)
pip install git+git://github.com/huggingface/transformers@59b5953d89544a66d73
我们的整个应用程序将驻留在app.py
中。让我们创建它并导入新安装的依赖项:
import urllib
import streamlit as st
import torch
from transformers import pipeline
在我们做任何处理之前,我们希望我们的模型加载。通过使用@st.cache
装饰器,我们可以执行一次load_model()
函数,并将结果存储在本地缓存中。这将提高我们的应用程序性能。然后,我们可以使用pipeline()
功能简单地加载一个模型来生成文本(将模型路径替换为您的定制模型,或者从模型中心使用 my 预训练的模型):
[@st](http://twitter.com/st).cache(allow_output_mutation=True, suppress_st_warning=True)
def load_model():
return pipeline("text-generation", model="e-tony/gpt2-rnm")model = load_model()
我们可以使用 Streamlit 的text_area()
函数来制作一个简单的文本框。我们还可以提供高度和允许的最大字符数(因为大文本需要更长的时间来生成):
textbox = st.text_area('Start your story:', '', height=200, max_chars=1000)
现在我们已经有了第一行代码,我们可以通过运行应用程序来查看它是什么样子的(我们也可以通过刷新页面来查看实时更改):
streamlit run app.py
接下来,我们可以添加一个 slider 小部件,允许用户决定模型应该生成多少个字符:
slider = st.slider('Max story length (in characters)', 50, 200)
我们现在准备生成文本!让我们创建一个执行文本生成的按钮:
button = st.button('Generate')
我们希望我们的应用程序监听“按钮按压”动作。这可以通过一个简单的条件语句来完成。然后我们可以生成文本并将其输出到屏幕上:
if button:
output_text = model(textbox, max_length=slider)[0]['generated_text']
for i, line in enumerate(output_text.split("\n")):
if ":" in line:
speaker, speech = line.split(':')
st.markdown(f'__{speaker}__: {speech}')
else:
st.markdown(line)
让我们在文本框中输入提示并生成一个故事:
Rick: Come on, flip the pickle, Morty. You're not gonna regret it. The payoff is huge.
输出:
Rick: Come on, flip the pickle, Morty. You're not gonna regret it. The payoff is huge. You don't have to be bad, Morty.
(Rick breaks up)
[Trans. Ext. Mortys home]
太好了!模型正在输出新的文本,看起来不错。我们可以通过调整解码方法的参数来提高输出质量。参见拥抱脸在 decoding⁹的帖子,了解不同方法的详细概述。让我们替换我们的model()
函数,并应用更多的参数:
output_text = model(textbox, do_sample=True, max_length=slider, top_k=50, top_p=0.95, num_returned_sequences=1)[0]['generated_text']
简而言之,do_sample
随机挑选下一个单词,top_k
过滤最有可能的 k 下一个单词,top_p
允许动态增加和减少可能的下一个单词的数量,num_returned_sequences
输出多个独立样本(在我们的例子中只有 1 个)用于进一步过滤或评估。您可以使用这些值来获得不同类型的输出。
让我们使用这种解码方法生成另一个输出。
输出:
Rick: Come on, flip the pickle, Morty. You're not gonna regret it. The payoff is huge.
Morty: Ew, no, Rick! Where are you?
Rick: Morty, just do it! [laughing] Just flip the pickle!
Morty: I'm a Morty, okay?
Rick: Come on, Morty. Don't be ashamed to be a Morty. Just flip the pickle.
我们的输出看起来更好!这种模式仍然会产生不合逻辑和无意义的文本,但新的模式和解码方法可能会解决这个问题。
不幸的是,我们的模型有时会产生伤害性的、粗俗的、暴力的或歧视性的语言,因为它是根据来自互联网的数据训练的。我们可以通过简单地从 451 个单词的列表中检查粗俗的单词来应用不良单词过滤器来审查有害的语言。我敦促读者考虑使用进一步的过滤器,比如过滤仇恨言论。该滤波器可以按如下方式实现:
def load_bad_words() -> list:
res_list = []file = urllib.request.urlopen("[https://raw.githubusercontent.com/RobertJGabriel/Google-profanity-words/master/list.txt](https://raw.githubusercontent.com/RobertJGabriel/Google-profanity-words/master/list.txt)")
for line in file:
dline = line.decode("utf-8")
res_list.append(dline.split("\n")[0])
return res_listBAD_WORDS = load_bad_words()
def filter_bad_words(text):
explicit = False
res_text = text.lower()
for word in BAD_WORDS:
if word in res_text:
res_text = res_text.replace(word, word[0]+"*"*len(word[1:]))
explicit = Trueif not explicit:
return textoutput_text = ""
for oword,rword in zip(text.split(" "), res_text.split(" ")):
if oword.lower() == rword:
output_text += oword+" "
else:
output_text += rword+" "return output_textoutput_text = filter_bad_words(model(textbox, do_sample=True, max_length=slider, top_k=50, top_p=0.95, num_returned_sequences=1)[0]['generated_text'])
我们最终的app.py
文件现在看起来像这样:
import urllib
import streamlit as st
import torch
from transformers import pipelinedef load_bad_words() -> list:
res_list = []file = urllib.request.urlopen("[https://raw.githubusercontent.com/RobertJGabriel/Google-profanity-words/master/list.txt](https://raw.githubusercontent.com/RobertJGabriel/Google-profanity-words/master/list.txt)")
for line in file:
dline = line.decode("utf-8")
res_list.append(dline.split("\n")[0])
return res_listBAD_WORDS = load_bad_words()
[@st](http://twitter.com/st).cache(allow_output_mutation=True, suppress_st_warning=True)
def load_model():
return pipeline("text-generation", model="e-tony/gpt2-rnm")def filter_bad_words(text):
explicit = False
res_text = text.lower()
for word in BAD_WORDS:
if word in res_text:
res_text = res_text.replace(word, word[0]+"*"*len(word[1:]))
explicit = Trueif not explicit:
return textoutput_text = ""
for oword,rword in zip(text.split(" "), res_text.split(" ")):
if oword.lower() == rword:
output_text += oword+" "
else:
output_text += rword+" "return output_textmodel = load_model()
textbox = st.text_area('Start your story:', '', height=200, max_chars=1000)
slider = slider = st.slider('Max text length (in characters)', 50, 1000)
button = st.button('Generate')if button:
output_text = filter_bad_words(model(textbox, do_sample=True, max_length=slider, top_k=50, top_p=0.95, num_returned_sequences=1)[0]['generated_text'])
for i, line in enumerate(output_text.split("\n")):
if ":" in line:
speaker, speech = line.split(':')
st.markdown(f'__{speaker}__: {speech}')
else:
st.markdown(line)
您还可以在 Github 资源库中查看我的演示的代码,因为它包含了修改应用程序功能和外观的有用代码。
它现在已经准备好上线了!
部署应用程序
可以使用 Streamlit 共享⁰.部署该应用程序您只需要有一个公共的 Github 存储库,存储库中有一个requirements.txt
和一个app.py
文件。您的requirements.txt
文件应该是这样的:
-f [https://download.pytorch.org/whl/torch_stable.html](https://download.pytorch.org/whl/torch_stable.html)
streamlit-nightly==0.69.3.dev20201025
torch==1.6.0+cpu
torchvision==0.7.0+cpu
transformers @ git+git://github.com/huggingface/transformers@59b5953d89544a66d73
在 Streamlit Sharing 网站上,您可以简单地链接您的存储库,您的模型将很快上线!
道德考量
本文中介绍的应用程序仅用于娱乐目的!应该仔细考虑在其他场景中应用 GPT2 模型。虽然从原始训练数据中删除了某些域,但 GPT2 模型是在来自互联网的大量未经过滤的内容上进行预训练的,这些内容包含有偏见和歧视性的语言。OpenAI 的型号卡指出了这些注意事项:
以下是我们认为可能的一些次要使用案例:
-写作辅助:语法辅助、自动补全(针对普通散文或代码)
-创造性写作和艺术:探索创造性虚构文本的生成;帮助诗歌和其他文学艺术的创作。
-娱乐:创造游戏、聊天机器人和娱乐一代。
范围外的使用案例:
因为像 GPT-2 这样的大规模语言模型不能区分事实和虚构,所以我们不支持要求生成的文本是真实的用例。此外,像 GPT-2 这样的语言模型反映了他们接受培训的系统固有的偏见,所以我们不建议将它们部署到与人类交互的系统中,除非部署者首先进行与预期用例相关的偏见研究。我们发现 774M 和 1.5B 之间在性别、种族和宗教偏见调查方面没有统计学上的显著差异,这意味着所有版本的 GPT-2 都应该以类似的谨慎程度对待对人类属性偏见敏感的用例。
下面的例子展示了模型如何产生有偏差的预测(另一个例子可以在这里找到):
>>> from transformers import pipeline, set_seed
>>> generator = pipeline('text-generation', model='gpt2')
>>> set_seed(42)
>>> generator("The man worked as a", max_length=10, num_return_sequences=5)[{'generated_text': 'The man worked as a waiter at a Japanese restaurant'},
{'generated_text': 'The man worked as a bouncer and a boun'},
{'generated_text': 'The man worked as a lawyer at the local firm'},
{'generated_text': 'The man worked as a waiter in a cafe near'},
{'generated_text': 'The man worked as a chef in a strip mall'}]>>> set_seed(42)
>>> generator("The woman worked as a", max_length=10, num_return_sequences=5)[{'generated_text': 'The woman worked as a waitress at a Japanese restaurant'},
{'generated_text': 'The woman worked as a waitress at a local restaurant'},
{'generated_text': 'The woman worked as a waitress at the local supermarket'},
{'generated_text': 'The woman worked as a nurse in a health center'},
{'generated_text': 'The woman worked as a maid in Daphne'}]
我敦促读者仔细考虑这些模型在真实场景中的应用和使用。有许多资源(如 EML、艾诺)可用于了解道德规范。
结论
恭喜你!您的应用程序现已上线!
通过使用开源框架,我们能够快速微调 GPT2 模型,原型化有趣的应用程序,并部署它。通过使用更先进的预训练模型、解码方法,甚至结构化语言预测,可以进一步改进生成的故事。
参考
[2]: 排名前 30 的 Gpt2 开源项目
[4]: 网络文本中出现的前 1000 个域名
[5]: A .、Jeffrey Wu、R. Child、David Luan、Dario Amodei 和 Ilya Sutskever 2019。语言模型是无人监督的多任务学习者。
[7]: 图解 GPT-2(可视化变压器语言模型)
[10]: 部署一个 app