数据驱动的企业如何进行场景规划
有已知的已知。这些是我们知道自己知道的事情。有已知的未知。也就是说,有些事情,我们知道我们不知道。但也有不为人知的未知。有些事情我们不知道我们不知道。 拉姆斯
情景规划是 20 世纪 50 年代开发的一种规划技术,用于帮助军方更好地应对意外变化。在情景规划之前,许多军事规划都是以类似于影响分析技术的方式进行的,假设未来与现在非常相似。相比之下,情景规划迫使你分析许多可能的未来,这些未来可能与现在非常不同。
场景规划会因业务而异,因为您需要考虑的未来场景取决于您的业务。本周我们将介绍情景规划的基本框架,这样你就可以将它应用到你自己的需求中。具体来说,我们将涵盖:
让我们从确定将形成我们需要考虑的未来的驱动趋势开始吧!
离群值 **监控您的业务数据,并在发生意外变化时通知您。**我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。 今天安排试玩。
- Outlier 是 Strata+Hadoop World 2017 观众奖得主。
场景规划:识别驱动趋势
在你开始构建未来的场景之前,你需要确定可能塑造这些未来的力量。这些力量很大程度上取决于你的业务类型,但通常可以分为社会,技术,经济,环境和政治趋势,这就是所谓的陡峭。例如,如果你是一家电子公司,你的未来可能会受到进口关税(政治)、运输成本(经济)、制造成本(技术)、回收法规(环境)和客户认知(社会)的影响。让我们通过几个简单的步骤来识别你所有的驾驶趋势。
第一步。集思广益,找出你的企业可能存在的所有驱动趋势。这可能会是一个非常大的列表,所以寻找相似之处和可能包含许多不同趋势的更大趋势。理想的情况是,你希望汇集一个合理的主要趋势列表,而没有太多的重复。
第二步。即使在整合之后,您的业务也可能有大量潜在的驱动趋势。下一步是对这些趋势进行分类,并找出最重要的趋势来塑造你的场景。为此,我们将从两个不同的方面对每位驱动因素进行评估:
- 影响:这个驱动因素对未来的潜在影响有多大?
- 不确定性:你能多好地预测这个驱动因素在未来会发生什么?
回到我们的电子公司,构建产品的组件成本具有较低的不确定性(不太可能在没有警告的情况下改变),但具有较高的影响(影响您的利润)。同时,竞争性的产品发布具有很高的不确定性(你不知道你的竞争对手在计划什么)和很高的影响(可能会降低销量)。影响和不确定性是定性的衡量标准,因此您应该决定自己的评分标准。无论你用什么标准,确保你对每个司机的相对评分是一致的。
第三步。评分后,您现在可以根据潜在驾驶员的两个得分将他们分为三类:
- 次要因素是对塑造你的未来影响较小、不太重要的驱动因素。
- 总体趋势是重要的驱动因素,但也很容易理解和预测。
- 关键的不确定性是很难预测其未来的重要驱动因素。
显然,关键的不确定性是最重要的,也是你应该用来构建你的场景的!次要因素和总体趋势将成为你从关键不确定性中构建的情景的背景。接下来,我们将讨论如何做到这一点。
方案规划:选择方案
在您确定了业务的驱动趋势(昨天的那些关键不确定性)之后,是时候选择值得研究的场景了。如果你只是简单地选择你最感兴趣的场景或者你已经知道的场景,那么整个场景规划的过程就是一种浪费!为了使情景规划有效,你需要面对可能的不愉快或未知的未来。
幸运的是,你已经确定的关键不确定性将为你塑造你的场景。例如,给定任意两个不确定性,您可以使用它们可能的结果(积极或消极)构建场景:
如果没有例子,这可能很难想象,所以让我们用一个例子!假设我们是一家电子公司,在中国生产产品,主要在美国销售。通过我们的流程,我们发现最大的关键不确定性是竞争性价格变化和进口关税变化。每种情况都有两种可能的结果:
然后,我们可以根据这两个关键的不确定性构建四种情景:
每个场景都有很大的不同,对每个场景进行分析将有助于深入了解这些以前不确定的业务领域。这是一个简单的例子,只使用了你的两个关键不确定性来创建场景,但是你可能会有两个以上的不确定性。您可以通过组合成对的不确定性(重复这个简单的过程)或者将两个以上的不确定性组合成一个更复杂的矩阵来构建更多的场景。无论哪种方式,您都应该有一个有趣的场景集合来分析。
如果你有太多的场景需要在有限的时间内考虑,按照可能性对它们进行排序会很有帮助,这样你就可以在极不可能的场景上花费更少的时间。例如,如果你的一个场景依赖于心灵运输的发明,你可以跳过这一个,因为你可能不会很快看到心灵运输的发明。
接下来,我们将介绍分析这些场景的不同方法,因为您已经掌握了这些方法!
一旦你确定了你的场景,以及产生这些场景的关键不确定性,是时候模拟这些场景,看看它们会如何发展。这里的目标不是完美地预测场景的未来,而是充分地探索它,以便您可以使用获得的知识做出更好的决策。你可以通过思考场景中的一连串事件以及它们在未来可能会如何发展来做到这一点。
你的模拟将依赖于你的业务经验、你能收集到的关于总体趋势和关键不确定性的任何数据以及外部建议。许多公司会聘请顾问来帮助他们进行场景规划,以确保他们避免在这个阶段引入偏见。如果你真的希望你的利润增加,你可能会无意中添加到你的模拟偏差,显示利润增加。
与任何模拟一样,最重要的部分是您建立的规则。运行良好的模拟具有以下规则:
- …反映公司潜在的战略选择。如果你的公司位于加州,搬迁是不可能的,你应该避免考虑搬迁到其他国家。
- …不受制于你当前的战略。情景规划的发展是为了攻击“官方未来”的想法,即简单地将今天延伸到明天。你需要愿意改变现状,考虑彻底的改变。
- …足够严格以提供一个结果。生活非常复杂,有很多因素,这就是为什么很难预测下周会发生什么。你需要限制你的模拟中的因素,否则你真的不能取得很大进展。
当你发现自己在考虑以前没有考虑到的选项和因素时,你就会知道你的模拟在起作用。请记住,情景模拟的目标不是最终结果,而是过程和它迫使你思考业务的不同方式。
接下来我们将介绍如何模拟真正复杂的场景,包括许多不同的竞争者或组织相互作用:战争游戏!
方案规划:高级方案
有些场景太复杂,不能简单地在白板上思考,因为要考虑的因素太多了。例如,如果您的场景涉及与三个或四个竞争对手的竞争性价格战,则很难理解每个参与者对每个变化的反应。这些可能是需要理解的最重要的场景;你如何管理复杂性?
正如我前面提到的,情景规划最初源于军事规划技术。军方预测未来的一个非常有效的方法是运行战争游戏(模拟),让团队在模拟的战斗中相互竞争,以观察不同部队之间的事态发展。战争游戏运行良好,因为每个团队只需要担心他们的利益和资源,给他们清晰的决策和更有效的整体模拟。这是一个有效的工具,您可以部署它来理解这些高度复杂的多方场景。而且很好玩!
最简单的部分是把你的人分成小组,在你的场景中每一方一个小组。困难的部分是建立模拟的规则(正如我们昨天所讨论的),以便它以一种对决策有用的方式进行。这与我们之前模拟的场景没有太大的不同,不同的是在你的战争游戏中每个团队可能有不同的规则。例如,一个大的竞争对手可能比一个小的竞争对手更灵活地调整他们的价格和利润(由于大量的现金流)。你为每个团队设计的规则越好,你的模拟结果就越好。
轮换你的团队总是一个好主意,这样每个人都有机会从不同的角度看问题。如果你定期重复这个过程,这是很容易的,这也将帮助你的团队提高他们的模拟技能。
延伸阅读:我在这里只触及了场景规划的皮毛!如果你想了解更多关于场景规划的知识,并看到更多详细的例子,我推荐莱比锡管理研究生院发表的关于场景规划的的优秀论文。
离群值 **监控您的业务数据,并在发生意外变化时通知您。**我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。 今天安排演示。
- Outlier 是 Strata+Hadoop World 2017 观众奖得主。
数据驱动型公司如何构建客户角色
“与人打交道可能是你面临的最大问题,尤其是在商界。”——卡耐基
客户角色通过识别共同的特征和行为来帮助你理解你的客户。
不是所有的客户都是一样的,这就是为什么我们首先需要数据!如果你的生意成功,你将拥有大量的客户,每个人都有不同的需求和兴趣,这使得你很难理解你的客户到底想要什么。你如何为数百个不同的客户建立营销策略和计划?
客户人物角色通过识别大群客户共有的共同特征和创建简单的档案,使得处理如此多样化的客户群变得更加容易。这些人物角色是代表大部分客户的客户档案,将使您的决策更容易,因为相对于数百个单独的客户,根据已知的人物角色测试给定的策略更容易。
例如,如果您在线销售桌子,并且有大量居住在加利福尼亚的女性客户,您可以创建一个名为 Beth 的热爱家具的加利福尼亚妇女的角色。Beth 不是一个真实的人,但是她的角色与你的许多现有客户有着共同的特征,因此 Beth 可以用来代表他们的利益。当你考虑产品变化和营销活动时,你可以通过 Beth 的视角来看待它们,并考虑她作为你客户的代理人可能会如何回应。
你如何建立你的客户角色,你如何知道他们代表你的客户?本周我们将介绍一些技巧,包括:
- 第 2 部分— 寻找特征(群体重采样)
- 第 3 部分— 构建人物角色(人群分类)
- 第 4 部分— 测试人物角色
- 第 5 部分— 利用人物角色做决策
首先,我们将从一个简单的方法开始,确定哪些角色已经存在于您的客户数据中。
离群值 **监控您的业务数据,并在发生意外变化时通知您。**我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。 今天安排试玩。
- Outlier 是 Strata+Hadoop World 2017 观众奖得主。
客户角色:寻找特征
创建人物角色很容易,你只需要收集描述大部分用户的一系列特征,并把它们组合成一个人物角色。识别这些大片段并提取它们的特征是真正的挑战。
如果你把你的客户想象成一大群复杂的人,这个任务可能会令人生畏。然而,你需要做的只是找到一些特征,有效地将你的客户分成几个主要群体。要做到这一点,你可以一次从一个角度看你的客户。
比如让我们考虑一下我们网上表公司的客户群。我们的客户遍布全国各地,代表了许多年龄组和人口统计数据。让我们看看它们是如何分布在几个常见维度上的:
在这种情况下,购买量分布相当均匀,因此没有明显的客户集中。因此,这对于我们的任何角色来说都不是一个好的特征。
购买总数有一个有趣的钟形曲线形状,表明购买总数向中心集中,但它未能将我们的客户划分成任何逻辑组。相反,看起来我们的客户在一系列购买中表现得像一个单一的、大的部分。
Breaking customers into groups based on effective traits
年龄让我们第一次清楚地看到有效的特质,两个明显的年龄组彼此分开。这使得年龄成为创建人物角色的理想特征,因为这里出现了两种明显的人物角色:年轻人和老年人。
正如你所看到的,通过不同的维度来观察客户的分布,可以很容易地识别出清晰的界限,这表明这是构建人物角色的一个很好的选择。您正在寻找的维度将在您的客户中创建清晰的分离,并允许您用单一维度有效地捕获大型群体。
接下来,我们将讨论如何将这些候选特征组合成人物角色!
客户角色:构建角色
我们刚刚讨论了如何通过维度来查看客户的分布,从而为我们的人物角色确定候选特征。现在我们只需要将它们放在一起,组成人物角色!
不幸的是,你可能有一长串的特征,因为你的客户会自然地分成几十个组。虽然我们欢迎你创建几十个人物角色,但通常只有少数几个是最有用的。为了处理这种复杂性,我们将通过使用总人数来对可能的角色进行分类。
例如,让我们假设我们为我们的在线家具公司确定了 3 个特征,每个特征都有 2 个明确的细分:年龄(年轻人和老年人)、桌子大小(小和大)和购买频率(一次性和每月)。即使这个简单的模型有三个特征(每个有两个部分),也能产生 8 个不同的角色!
这太多了,所以让我们通过查看属于每个候选人角色的客户总数来减少数量。当我们这样做时,事情就变得清楚多了:
如你所见,结合我们的特征实际上减少了我们大部分潜在的人物角色到我们人口中很小的一部分。只有“年轻的、小的、一次性的”和“老的、小的、每月的”代表了足够多的客户,值得创建人物角色。
请注意,这两个人物角色并没有涵盖我们所有的客户,只是很大一部分。你的人物角色永远不会覆盖 100%的用户,因为需要的人物角色数量是不切实际的。然而,在使用你的人物角色时,请记住这一点,因为有许多客户不在此列。
你会发现使用人口作为过滤器是从几十个潜在人物角色中筛选出几个的非常有效的方法。有了这些,明天我们将讨论如何验证你的人物角色是否真正代表了你的客户,或者你的客户只是代表了你的人物角色。
客户角色:测试角色
既然我们已经集合了一组人物角色,我们需要做最后的检查,确保组成我们的人物角色的特征是有用的。特征可以是两种形式之一:
- 描述性。这些特征抓住了客户行为方式的某些方面,并有助于预测未来的行为。
- 衍生。这些特征是客户行为的结果,很可能是你的产品如何运作或者客户如何看待你的公司的产物。
区别是很重要的,因为由衍生特征组成的人物角色是没有用的,因为它们不会帮助你理解变化会如何影响你的客户。你的人物角色应该只由描述性特征组成,但是你如何确定呢?
为了说明这个困难,让我们回顾一下另一篇关于集群的文章中的一个特征:桌子大小。请记住,我们发现了两个客户角色:(1)一次性购买小桌子的年轻人,以及(2)每月购买小桌子的老年人。有人每个月都会买桌子,这应该会让你感到奇怪吧!为什么会发生这种情况?
- 他们可能代表一个更大的组织或社区购买桌子,所以他们并不是真正为自己购买,幕后有一个你永远看不到的顾客。
- 他们可能会在你的网站上购买桌子,然后在其他地方转售,因为你的价格低于他们在其他地方可以买到的价格。
选项#1 是描述性的,因为购买一张桌子的频率表明了一组特定的客户需求,这意味着向您购买时有一组特定的决策标准。选项#2 是派生的,因为它仅仅是你的桌子价格的结果,没有真正的决策标准。根据哪个原因是正确的,这种特征的分类会有所不同,所以你需要调查所有的原因来确定。
理解为什么一个特征存在对于正确分类它是至关重要的。做到这一点的唯一可靠方法是在每个角色中与客户交谈,更好地了解他们的需求。好消息是,你不必在每个人物角色中与几个人交谈,就能确定你已经捕捉到了代表他们的描述性特征。
接下来,我们将讨论如何利用我们收集的这些人物角色做出决策!
客户角色:使用角色
有了我们的客户角色,是时候使用它们来做一些决定了!
正如我在开始时提到的,客户角色作为大部分客户的替身是很有用的。你可以用它们来评估客户眼中的许多不同决策。例如,如果你是…
- …考虑增加新功能。你的角色会在意吗?对他们的效用是什么?他们将如何看待这种效用?他们是否有时间使用更多的功能,或者他们已经尽可能多的花时间和你在一起了?
- **…考虑新的品牌信息。**它将如何脱颖而出?他们还收到了哪些信息,这些信息与其他信息相比会有什么不同?有没有办法用一种直接吸引他们的语言来说话?
- ……考虑新市场。你的人物角色在新市场中存在吗?你需要接触全新类型的客户,还是以新的方式接触相同的人物角色?
大多数公司会更进一步,使用他们的人物角色来组织客户焦点小组,这些小组是符合给定人物角色的简单的客户小组。通过按人物角色收集客户,您可以从真实客户那里获得关于即将到来的变化的实时相关反馈,反馈的方式应该是有针对性的和一致的。从人物角色中建立的客户焦点小组远远优于一般的客户小组,在那里你会得到许多相互冲突的利益和观点。
无论你如何使用你的人物角色,确保你公司的每个人都知道他们是什么,并把他们作为决策的参考点。如果你这样做了,你会发现你的团队做出了更好、更一致的以客户为中心的决策。
回顾:顾客角色是一种简单的方法,可以确保你在做每一个决定时都考虑到顾客。通过创建几个典型客户类型的简介,你可以更容易地从客户的角度看问题。
离群值 **监控您的业务数据,并在发生意外变化时通知您。**我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。 今天安排试玩。
- Outlier 是 Strata+Hadoop World 2017 观众奖得主。
数据科学如何实现早期癌症诊断
在这篇文章中,我提出了一个使用两步法的癌症早期检测的解决方案。第一步是使用霰弹枪法,如质谱法,利用常规检查样品收集尽可能多的化学信息;第二步是建立一种可靠的方法来筛选化学信息,并标记可疑的癌症样本以供进一步测试。开发了一个网络应用程序,以促进癌症预测和发现用于癌症诊断的指纹化学物质。
癌症的早期发现和治疗对于提高癌症患者的生存率和生活质量至关重要。根据英国癌症研究的数据,对于女性和男性最常见的癌症乳腺癌和前列腺癌,如果在 I 期/之前诊断,五年存活率几乎是 100%,而在 IV 期存活率显著下降到不到 30%!
Figure. 5-Year Survival Rate for Breast Cancer at Different Stages
Figure. 5-Year Survival Rate for Prostate Cancer at Different Stages
目前,癌症通常是在患者出现呕吐和头晕等症状后才被诊断出来。然而,在大多数情况下,症状只有在晚期才明显,即使症状出现,病人和医生也不会首先怀疑癌症。因此,最好是找到一种可靠的方法,使用常规体检样本(,例如,血液样本)来检查癌症,并且甚至在症状出现之前就“标记”可疑的癌症样本以进行进一步的测试。
早期癌症检测的两步法
第一步。猎枪法
质谱提供了一种经济、快速的解决方案,可从唾液、血液或其他样本中收集尽可能多的化学信息,已被制药公司广泛应用于药物筛选和测试。
一般来说,质谱通过化学物质的重量或质量来区分化学物质,即使化学物质的浓度很低,质谱也具有很高的灵敏度。此外,质谱分析通常使用微小的样品(毫克),需要几分钟才能完成,并且可以很容易地与机器人样品制备技术结合,这是高通量化学筛选和测试的理想方法。
然而,太多的信息意味着很难找到哪个肿块是癌症诊断的决定性因素,即使是有经验的专业人员。通常的做法是,人们根据有限数量的已知癌症决定化学物质(或标准)来预测癌症,这将由于样本差异而导致大量的错误分类。
Figure. Typical mass spectra of ovarian cancer samples and ovarian control samples
第二步。受数据科学启发的频谱分析
在人们的印象中,数据科学和机器学习更多的是与高科技行业相关,比如图像处理、语音处理、人工智能,但它们与频谱分析有什么关系呢?换句话说,如何将现实世界的癌症早期诊断问题转化为机器学习问题来解决?让我们在下面几节中演示这种“转换”。
数据收集
首先,让我们收集一些质谱数据。我正在调查的数据可以从国家癌症研究所 (NCI)公开获得。在这里,我主要关注两种癌症:卵巢癌和前列腺癌。对于卵巢癌,我采用了两组,一组由机器人准备,另一组按照标准协议手工准备。对于前列腺癌,所有样品都是按照标准方案手工制备的。每组都有癌症组和对照组(健康组)。大约 20%的癌症样品处于 I 期,而其余 80%的癌症样品处于 II、III 和 IV 期。
Figure. Mass spectra samples collected for cancer prediction
这种情况下的数据争论是将单个质谱结合到光谱矩阵,每行代表单个样品,每列代表单个 M/Z。所有样品都标记为癌症为 1,非癌症为-1。
Figure. Mass spectra matrix after combining individual mass spectrum
数据可视化
那么我们的数据是什么样的呢?他们可以很容易地被分为癌症或非癌症群体吗?现在,我们面对的数据集的特征(不同的质量)明显大于样本(质谱的数量)。这对于所有光谱数据都是常见的,通过实验收集大量样本相对困难,但通过光谱分析获得大量特征或数据点却相当容易。由于我们数据的高维数(> 9000 个特征),不可能直接查看我们的数据。相反,我们可以将我们的数据“投影”到 2D 空间,并将其可视化。主成分分析为我们提供了很好的工具来做到这一点,在这里我们可以很容易地看到和知道我们的数据。在这里,我们使用前两个主成分绘制了数据分布图。
Figure. Comparison of cancer and non-cancer group in three groups. Purple plots represent the non-cancer group, while yellow plots represent the cancer group. From left to right: robotic prepared ovarian samples, hand-prepared ovarian samples, and prostate samples
我们可以看到,对于机器人制备的卵巢样本和前列腺样本,癌症和非癌症样本可以合理地分离,而对于手工制备的卵巢样本,癌症和非癌症样本在很大程度上重叠,无法仅使用前两个主成分进行分离(与机器人制备的卵巢组和前列腺组相比,更难预测癌症/非癌症)。
特征选择
我们知道我们的光谱数据是高维数据。事实上,高维数据不仅带来了高维的诅咒,还带来了相关和噪声特征,这可能导致我们的模型过拟合数据或难以收敛。因此,在应用机器学习算法之前,我们需要选择重要的特征。
决策树是一种自然的特征选择方法。树分裂基于基尼不纯的最大增益,因此树总是向着更重要的特征分裂。随机森林算法是一种集成方法,对每次分裂使用树打包和随机特征选择。在这里,我使用随机森林来选择最重要的特征。我将阈值设置为 95 %,这意味着我预计最重要的特征可以解释数据集 95%以上的差异。
Figure. Explained Variance vs. Number of Features rendered by Random Forest.
值得注意的是,在 9,200 个特征(M/Z)中,仅使用 40 个特征(总特征的 0.43%)就可以解释前列腺样本 95%以上的差异,52 个特征(总特征的 0.58%)将解释机器人制备的卵巢样本 95%以上的差异,而手工制备的卵巢样本需要 86 个特征(总特征的 0.93%)。特征选择将显著减少噪声和冗余特征。
选择的特征有意义吗?
是的,这意味着指纹肿块可以确定癌症
【T4查看我的 github 了解更多详情@第 4.4 节
对于机器人制备的卵巢样本,200 到 1000 之间的指纹质量数为 25,确定卵巢癌的癌症的一个关键代谢物 (分子量 472) **在我们用于卵巢预测的重要质量列表中。**换句话说,我开发了一种工具,用于选择可能用于癌症诊断的指纹分子,这对新发现代谢和致癌化学物质具有重要价值。在这种情况下,研究人员可以只关注 52 个预测卵巢癌的分子,或者 40 个预测前列腺癌的分子,而不是关注所有 9300 个可能的分子,这将大大提高研发效率并节省成本。
癌症预测模型
使用选择的特征,我应用了支持向量机(SVM)随机森林(RF)K 最近邻 (KNN)和集成方法,通过投票进行癌症预测。模型参数通过网格搜索交叉验证进行调整。基于预测准确性、AUC 评分和 F1 评分比较模型性能。
Figure. Comparison of model performance on robotic-prepared ovarian samples, hand-prepared ovarian samples, and prostate samples
值得注意的是,对于卵巢癌和前列腺癌的预测,所有机器学习模型都表现良好。对于机器人准备的卵巢数据,随机森林和 SVM 可以达到 100%的准确性,1.0 的 AUC 和 1.0 的 F1 评分,使它们成为预测的完美模型;对于手工准备的卵巢数据,SVM 和系综方法表现相似,达到 95%的准确性,0.95 的 AUC 和 0.96 的 F1 评分;对于前列腺数据,SVM、随机森林和集成方法可以实现高达 98%的准确性、0.98 的 AUC 和 0.98 的 F1 分数。然而,我们不应该对我们的模型过于自信,因为我们的结果是基于小规模的样本,我们将需要更大的数据来优化我们的模型和测试模型的性能。我们的模型还必须灵活,这意味着它们应该能够处理质谱中出现比平时更多噪音的情况(例如,仪器误差和样品制备过程中引入的杂质)。
我们可以看到 SVM 和集成模型在预测准确性、AUC 和 F1 评分方面相似,但是哪一个对于癌症的早期确定更好呢?
让我们回到这项工作的目标。我们将对疑似癌症样本进行“危险标记”以进行进一步检测,因此敏感性是我们首要关注的问题。换句话说,如果有癌症,我们的模型应该尽可能地预测癌症。这类似于机场的安全检查,警报被调整为对所有金属物体敏感,甚至对钥匙和手机也是如此。
如果我们看一下下面显示的混淆矩阵,它显示了当有癌症时有多少样本没有被预测为癌症(假阴性结果),我们希望尽可能少地出现假阴性结果。这里,1 代表癌症,而-1 代表非癌症。可以容易地看出,SVM 模型在所有三组中呈现 0 假阴性结果,使得 SVM 是比集合模型更好的预测卵巢癌和前列腺癌的模型。
Figure. Comparison of Confusion Matrix between SVM and Ensemble models
如果样本不小心混在一起,我们能知道它属于哪一组吗?
经常会有人把样本搞混的情况,尤其是处理大量样本的时候。在这里,我提供了一个如何使用机器学习工具将未知样本分配到组中的解决方案。在这个数据集中,我们有六个单独的组。我们必须使用多分类来决定样本属于哪一组。通过比较三种模型(SVM、随机森林和 KNN),我们得出结论,SVM 在这种多分类中表现最佳,准确率高达 93%。进一步证明,我们的模型可以根据性别(高达 97%的准确率)以及机器人准备和手工准备(高达 100%的准确率)来分离样本。
我们能否开发一个应用程序,只需上传一个质谱文件,它就会提供预测结果?
是的。为了实现这个目标,我开发了一个名为癌症诊断 1.0 的应用程序
在这里,我开发了一个基于 Dash 的 web app ,你只需上传一个质谱文件,癌症诊断结果就会立即显示出来。该应用程序已通过 Heroku 部署。
- 上传文件
- 质谱将通过热图和曲线图显示,您可以选择质量范围
- 它显示所有训练样本中新样本的可视化,并通过四个模型预测概率。您可以选择不同的分类标准:全部、性别或准备
- 如果您选择一个特定的组(此处为机器人准备的卵巢组),它会显示该组中训练样本内新样本的可视化,并通过四个模型预测癌症/非癌症的概率
- 它还将显示特定组(此处为机器人准备的卵巢组)内的指纹质量,您可以选择质量范围来显示感兴趣的指纹质量
结论
- SVM 被选为预测卵巢癌和前列腺癌的最佳模型,准确率高(95-100%),假阴性率为零,非常适合“标记”疑似癌症样本
- 确定了决定卵巢癌的指纹分子之一,这被文献报道所证实
- 开发了一个癌症诊断应用程序,以提供快速的癌症预测结果以及用于癌症诊断的指纹分子列表
建议
- 在癌症筛查的常规检查中,患者应该要求进行质谱检测
- 医生应该建议患者在常规体检时做质谱测试
- 保险公司应该支付质谱测试费用,作为一种预防性测试,以鼓励人们进行常规癌症筛查
数据科学如何帮助营销
This post is the updated version of a piece I wrote last year, How Data is Fueling Marketing
数据科学正在迅速改变营销。具体来说,情境营销正在兴起。情境营销不同于传统营销。顾名思义,这种营销策略完全是关于背景。我们不再对观察和预测人们如何进行简单的有意识决策感兴趣。相反,通过这种类型的营销,我们试图观察个人在购买某种产品、预订旅行或浏览在线目录时的习惯。
I updated the content after the talk I gave at the SXSWi 2016 in Austin, Texas
习惯模式塑造了我们每天大约 45%的选择。通过情境营销,我们不仅可以发现和了解某人是谁,还可以了解他们的地理位置,他们在不同的地区和时间点正在做什么,以及他们接下来最有可能做什么。更准确地说,利用今天可用的数据,我们可以观察个人的年龄、性别、过去的行为、设备使用、位置、天气条件、一天中的时间和购买历史以及其他相关因素。这有助于我们在正确的时间传递正确的信息,并识别正确的趋势。我们观察和评估深层背景特征的能力改变了一切。
大公司已经在战略性地使用情境营销。例如,在线预订公司 Orbitz 向 Mac 用户显示价格更高的酒店!另一方面,Travelocity 为移动购物者提供 5%的折扣。众所周知,美国航空公司会在你购物时提高机票价格,以制造一种紧迫感。购物零售商 Target 已经开发了一款“怀孕探测器,它基本上是通过观察访问其网站的女性的购物和浏览历史/cookie 来挖掘数据,从而进入你的子宫。
这是怎么回事?营销人员知道怀孕是一个非常有利可图的时间段。通过观察成千上万不同的产品购买,数据科学家能够确定 25 种最显著的产品,这些产品对“怀孕预测”得分有显著影响。该分析模型有助于预测个人在特定时间段和小机会窗口内的购物行为。然后,Target 会在孕妇可能搜索和购买其产品的特定怀孕阶段发送优惠券。
计时是如何工作的?举个例子:化妆水是一种广泛使用的,每个人都广泛购买的,不仅仅是孕妇。然而,据观察,孕妇在第二个三个月开始时会购买更多的无味乳液。
数据科学不仅非常好地补充了传统营销,它还在我们眼前改变了传统营销。数据科学的一个重要方面是,它通过输入和输出来改善情境营销。诸如年龄、性别、收入、位置、搜索历史、购买历史、一天中的时间等输入。这些输入产生相关的输出,这些输出可以改变你的服务/产品的游戏规则,例如:你需要使用什么渠道来锁定你的客户,你的产品的正确价格和折扣,客户在一年中的特定时间对什么特定产品感兴趣,等等。
关于数据科学如何驱动环境,我最喜欢的一个例子是 Stitchfix 。在刚刚于 6 月 1 日发布的玛丽·米克尔互联网趋势报告中,Stitchfix 在微观数据驱动的参与度、满意度、数据收集和个性化方面领先。Stitchfix 正在将类似网飞和 Spotify 的内容发现应用于时尚,为每位顾客提供差异化的体验。Stitchfix 有一个融合了艺术和科学的数据驱动的入职流程。他们收集顾客偏好、风格和活动的数据点。设计师使用 Pinterest 板和访问算法来帮助改善产品选择。下面的幻灯片描述了 Stitchfix 如何利用数据科学不仅驱动上下文,而且作为其整个产品的基础。
Get the full report at Kleiner Perkins
Nestle Purina 在数据科学方面也取得了成功,不仅利用它来个性化客户信息,还个性化客户宠物!雀巢普瑞纳,近年来,已经建立了一个目标,为宠物主人提供量身定制的营养计划,为他们喜爱的宠物。作为全球第二大宠物食品公司,data science 通过文章索引、文章结构聚类以及推荐算法的使用,帮助 Purina 推出了许多针对客户的广告。
所有这些例子听起来都很棒。但问题出现了,我们如何在数据科学的支持下实际实现和实施情境营销?
确定你的战略无论你的品牌是什么,舒适的鞋子、驾驶汽车的乐趣、快餐配送、难忘的经历都会强化这种价值。与此同时,开始思考什么样的输入对改进你的产品最有益,以及你希望产生的输出。
为顾客旅程提供便利想办法解决顾客购买前、购买中和购买后的旅程问题。关注客户体验和参与度。
内容仍然是王道在互动过程中,你提供的每一条内容都必须基于你从过去的互动中收集的数据,不仅针对客户,而且针对特定的时刻。
与您的 IT 部门合作引入正确的工具来执行自动化和项目。
今天,我们作为营销人员可以获得大量的数据。你必须愿意去挖掘它。搜索、移动设备使用、内容浏览和社交媒体活动揭示了客户一生的旅程。重新定义活动的目的,邀请你的客户不仅购买你的产品或服务,还要与你建立深厚的关系。
这只是冰山一角。如果您有更多问题,请在 Twitter 上联系我。
在 Slideshare 上查看这篇文章的演示文稿。
数据科学如何实现更好的决策
良好的决策是公司和机构高效运行和克服不可预见障碍的关键。在数据科学公司的帮助下,决策者现在能够通过形成和过滤他们的组织收集的数据,做出比过去更明智的选择。通过使用这些数据,他们能够对未来做出预测,例如,如果他们决定将他们的组织带到一个全新的方向,或者他们将如何在金融灾难后重建自己,等等。
然而,应该提到的是,仅有数据科学并不总是足够的。正如 InData 实验室的 Irina Peregud,解释:“数据科学家分析数据以发现洞见,但告诉他们要寻找什么是产品经理和商业领袖的工作。”从本质上来说,企业领导人和政府机构负责人需要在派出数据科学团队尝试解决问题之前,知道问题是什么。数据科学家能够挖掘大量信息,但这些信息毫无价值,除非他们由了解他们工作环境的人领导,即具有行业经验的领导者。在数据科学家能够理论化实现目标的方法之前,需要明确设定目标。
自动化
构建自动响应系统通常被视为许多寻求投资数据科学的企业领导者的最终目标。当收集和利用正确的数据时,许多小的决策可以很容易地自动化。例如,许多发放贷款的银行多年来一直使用信用评分系统来预测其客户的“信用价值”,然而,现在,在数据科学的帮助下,他们能够以更高的准确度做到这一点,这减轻了员工的一些决策过程,降低了如果客户“不值得”就无法获得贷款回报的可能性,同时也加快了这一过程。
最重要的是,数据科学还能够帮助自动化更复杂的决策过程,能够提供许多可靠的方向供选择,并以数据作为这些可能性的证据。使用数据科学,有可能预测尚未做出的决策的影响。这种例子有很多,但最著名的可能是那些濒临倒闭的公司,他们相信数据科学,并根据数据告诉他们会起作用的东西重塑公司,从而得救了,如 Dunkin’ Donuts 和 Timberland 。前者投资于忠诚度系统,后者投资于识别其理想客户。拥有支持此类重大决策的数据,可以让决策者对他们正在做的事情更有信心,并在财务和心理上对该想法进行更多投资。
医疗保险
医疗保健是另一个领域,数据科学已证明对各种行业的决策非常有益。显然,提供充分的治疗是第一要务。许多医疗保健提供商现在正在转向循证医学,当与数据科学结合使用时,医生可以通过在做出治疗决定之前访问更大的资源池来为患者提供更个性化的体验。
健康和人寿保险是从数据科学中受益匪浅的其他医疗保健领域。与上述银行根据“信用价值”评分发放贷款的方式类似,健康和人寿保险公司也可以制定“健康”评分。要得出这样的分数,需要从大量地方收集数据,包括社交媒体、金融交易甚至身体传感器。这在整个保险行业也可以看到。事实上,正如 Datafloq 解释的那样:“保险公司依赖于通过为每个客户调整保单来增加客户数量”。通过使用数据科学,保险公司能够为客户和保险公司提供更加个性化的保险方案。这使得决策过程变得更加容易,因为这不再是保险公司对客户说“是”或“否”的问题,而是询问对双方都适用的条款。
更顺畅的操作
数据科学也为那些旨在提高运营标准的人所熟知。通过将数据科学应用于运营程序,决策者能够更有效地实施变革,并通过反复试验更密切地监控变革是否成功。这种方法可以应用于雇佣和解雇员工,通过收集和测量数据来看谁最适合这份工作,以及测量绩效目标来看谁真正应该得到提升。最重要的是,它有助于雇主了解哪里真正需要工作,哪里可以裁员。
威廉·爱德华·戴明曾经说过:“我们相信上帝。所有其他人都必须带数据。”虽然他在 24 年前就去世了,但他的话现在比当初说的时候更有道理。在数据科学的帮助下,决策者——无论他们身处哪个行业——都可以做出比以往更加精确的选择。或者,在某些情况下,通过自动化来消除整个决策过程。
通过充分利用数据科学的潜力,所有行业的顶级决策者不仅可以做出更明智的决策,还可以对未来做出更清晰的预测。凭借这一优势,他们能够稳定那些一直没有清晰愿景的企业,拯救那些濒临倒闭的企业。
然而,应该再次提到的是,只有当决策者知道有一个问题需要解决,并且能够给他们领导下的数据科学家以目标时,数据科学才是一种优势。一旦目标确立,数据科学家就可以施展他们的魔法,并理论化如何修正它。数据科学本身并不是决策的优势,数据科学结合良好的领导力才是优势。
数据科学如何带来更好的决策
本周美国、欧洲和中东的新闻生动地提醒人们理性决策的谬误。无论我们阅读的是商业、经济还是社会方面的书籍,每天似乎都会带来明显糟糕的决策。杰克·曾格和约瑟夫·福克曼概述了决策者失败的几个原因,包括疏忽、缺乏预见性、优柔寡断和孤立。【我】。假新闻、伪造的事实和被操纵的观点是糟糕决策的原因还是结果?【ii】最重要的是,为了我们的组织、我们的客户和我们的职业,我们可以做些什么来提高我们的决策技能?
我们生活在一个数据经常被误认为事实的时间和空间里。*做出更好的决策,而不是处理数据,是改善管理的最终基准。*我们目前每天大约产生 2.5 万亿字节的数据——过去两年的数据量超过了人类历史上的数据量。克劳斯·施瓦布认为,我们已经进入了第四次工业革命,在这场革命中,价值是由我们捕捉和分析这些海量数据的能力来定义的。迄今为止,很少有证据表明这场革命带来了比过去更好的决策。数据科学旨在将数据转化为有效的行动,以应对基本的组织挑战。
改善决策需要什么?在决策科学中,我们了解到有效管理的主要挑战是对我们做出决策的环境的复杂性、模糊性和不确定性的认识。在认知科学中,我们被告知,我们的先入之见和偏见扭曲了我们看待问题的方式,也限制了我们提出创新解决方案的能力。在管理学院,我们被训练认识到当今现实世界问题的复杂性,无视“一个最好的方法”的逻辑。最后,在商业中,我们意识到罪魁祸首不仅仅是我们自己的决定,还常常是我们周围的人。
什么是更好的决定?根据大卫·斯诺登关于理性决策的研究,我们认为好的、更好的和伟大的决策之间有着明显的区别。在确定性决策环境中,好的决策是可能的,在确定性决策环境中,可以通过检查手头的数据找到正确的答案。不幸的是,大多数商业决策是在随机环境中做出的,在这种环境中,无法从可用数据中推断出正确的决策——通过减少不确定性的原因,更好的决策仍然是可能的。最后,我们所指的伟大决策是那些背景、挑战和解决方案允许我们重新审视决策过程本身性质的决策。
虽然机器学习目前作为一种神秘的灵丹妙药被推销给管理层,但它只不过是一种用于探索我们所面临问题的本质的技术工具。监督学习代表了一种特定类型的解决问题的方法,在这种方法中,我们知道答案就在数据中,挑战在于推导出它。无监督学习概括了一种没有唯一正确答案的挑战,但我们相信研究数据将使我们能够归纳出潜在反应的模式。半监督学习代表了第三种方法,其中我们知道答案,但我们正试图校准决策过程,以产生更可靠的结果。在所有情况下,信息技术为我们提供了一面思考我们周围挑战的镜子。
数据科学研究如何帮助我们成为更好的决策者?业务分析是一个四步流程,旨在帮助人们在其工作环境中做出更好的决策。首先,我们需要扫描环境(物理环境和数字环境),以了解我们试图解决的问题的本质。第二步是探索我们必须处理的数据的质量。第三步是应用正确的方法来探索数据,并针对我们试图解决的问题类型制定解决方案。最后,我们需要将数据转化为故事,激励我们的团队和社区采取适当的行动。数据科学与其说是理论,不如说是实践,将这些决策基础整合到我们的工作方式中。
数据科学实践是商业分析研究所的核心和灵魂。2018 年 白暑期项目 将探索利用数据科学提高管理决策的关键任务技能。我们独特的夏季会议将为来自美国和加拿大、欧洲和亚洲的四十多名参与者提供对使用分析实践的坚实理解——如何评估手头的数据,如何将适当的方法应用于特定类型的个人和专业挑战,以及如何将数据转化为集体行动。
Lee Schlenker 是商业分析和数字化转型教授,也是 http://baieurope.com 商业分析研究所的负责人。他的 LinkedIn 个人资料可以在www.linkedin.com/in/leeschlenker.查看,你可以在https://twitter.com/DSign4Analytics的 Twitter 上关注我们
【I】曾格尔,j .和福克曼 J. (2014)。导致可怕决定的 9 个习惯。哈佛商业评论[在线]
【ii】Schlenker,L. (2017),更好的决策对你来说意味着什么?,中等
【iii】屈臣氏营销,(2017)2017 年十大关键营销趋势
【iv】施瓦布,K. (2017)。第四次工业革命。第一版。兰登书屋公司。
Snowdon,d .和 Kurtz,C.F. (2003),复杂世界中的意义构建,IBM 系统杂志
数据科学家如何让医生相信人工智能有效
当我在医学院的时候,我被教导对一个病人说的四个最重要的词是*‘你没有癌症’*。我相信你会同意,这一声明对于正确行事至关重要。为了作出这一声明,观察者必须尽可能地确信这一声明在当时确实是正确的(癌症已经被证明是不存在的)。在统计学术语中,这种说法被称为真正的否定。可惜医学不是非黑即白的,医生也有可能搞错。这种情况并不经常发生(嗯,比我们希望的要多,但还不足以让每个人都放弃),但一旦发生,结果对患者来说可能是灾难性的。
当人工智能系统进行诊断或报告发现时,确保新技术也是准确的,或者至少像人类一样准确是很重要的。这是通过临床验证过程完成的,其目的是评估系统的“准确性”。我们当然不希望 AI 开始错误地告诉人们,他们比人类更容易患癌症或不患癌症!在这篇文章中,我将回顾在临床环境中为 AI 开发者报告准确性的最相关的指标。
准确性到底是什么?
“准确性”不是一个已定义的科学统计术语,但它本质上包含了指数测试(被测试的系统)表现如何的概念,通常与另一个预先存在的系统相比较,在人工智能的背景下,该系统通常是人类医生。“准确性”可以使用替代测量来评估,例如可靠性、灵敏度、精确度和误差率,等等。
指标测试的“准确性”最好通过与黄金标准的无误差测试进行比较来衡量。然而,在医学诊断领域(或其他领域,如放射学或病理学发现),往往没有无错误的黄金标准。因此,应该使用建立“基础事实”的最佳方法,即临床参考标准(CRS)。CRS 可以定义为“一组合格医生的一致意见”,或者更简单地说是“一名合格医生的专家意见”。CRS 的全部意义在于尽可能接近一个完美的系统。在进行临床验证时,CRS 的定义非常重要,因为它会影响任何统计检验的方法、分析和结果。我经常看到发表的关于人工智能系统准确性的文献,相比之下只有一两个医生,这可能还不够。(但是,占用几百个医生的时间,大概是不合理的,所以尽你所能吧!)
有几种统计方法来衡量“准确性”。然而,必须指出的是,大多数统计测试旨在评估二元分类(给定的疾病、条件或生理测量)中仅一个目标条件的测试的“准确性”,而不是大量变量。
或者,测试间比较(kappa 一致性、一致性、可靠性)可用于评估“准确性”,尤其是在缺乏具体定义的目标条件的情况下。然而,这些测试只是衡量 AI 和人类之间的一致程度,并不能反映‘准确性’。不一致并不能告诉你两个测试哪个更好,只能说明他们不一致。因此,我将在本文中忽略这些比较测试。
最后,任何对“诊断准确性”的方法学评估都应尽可能消除偏见,适用于具体情况,透明,并有适当的依据。出于这个原因,产生了报告“诊断准确性”的国际标准,这是一个同行评审的框架,使研究人员能够充分记录和合理化他们的研究和发现。
测量二元分类的“准确度”
在结果是二分的环境中(二元;存在或不存在),没有不确定的结果,可以使用统计二元分类器。
通过将指数测试与黄金标准进行比较,可以创建一个简单的 2x2 表格,称为混淆矩阵或列联表。
Standard confusion matrix
基于真/假正/负的计算可以提供“准确性”的替代测量。
一般来说,系统越“精确”,出现的真阳性和真阴性就越多,假阳性和假阴性就越少。
两个世界碰撞
在报告诊断“准确性”时,医学和数据科学指标之间有相当大的重叠。在临床领域,使用的主要指标是真实柱比率——真实阳性率和真实阴性率(灵敏度和特异性)。在数据科学中,最常报告的指标是真阳性率,即阳性预测值(PPV)和真阳性率(TPR),分别称为精确度和召回率。
传统上,非医疗部门的人工智能系统仅根据精确度和召回率进行评级。这是因为在将模型应用于非临床问题(例如,为文档或信息检索而设计的系统)时,真正的负面因素可能并不重要。然而,当将人工智能应用于医疗情况时,真正的负面因素必须包括在你的统计分析中。
精度
精确度(绿色单元格)是对阳性结果与相关性的度量,也称为阳性预测值(PPV)。
其计算方法如下:
精度= TP / (TP + FP)
Precision
当黄金标准完全没有误差时,精确度是一种有用的“准确度”衡量标准。然而,当金本位制可能出现错误时,必须小心谨慎。这是因为指数测试实际上可能更“准确”(例如,人工智能比人类医生更好*),但因为它只是与 CRS 进行比较,指数测试产生的任何真阳性都可能被错误地归类为假阳性,从而人为地降低了报告的精确度。医生的一致意见是有癌症,而实际上没有。人工智能系统正确地说没有癌症。在这种情况下,AI 系统是正确的,但因为我们只是将结果与医生的不正确共识意见进行比较,所以 AI 系统的精度受到了负面影响)。*
召回/灵敏度
回忆(红细胞)是对正确阳性结果的比例的测量,也被称为真阳性率,或灵敏度。
其计算方法如下:
召回= TP / (TP + FN)
Recall
只有当黄金标准是无误差的,召回/灵敏度才能真正有用,因为它假设黄金标准的所有阳性结果确实是阳性的。如果一个人是不正确的,一个诊断实际上是一个真正的否定,那么报告召回将被人为地减少。
值得注意的是,精确度和召回率/灵敏度都没有考虑真正的负面因素,因此不能提供“准确性”的完整描述。出于这个原因,传统的数据科学的精确度和召回率指标不足以在临床环境中评估准确性。记住——“你没有癌症”是一个真正的否定,无论是精确度还是召回率都不能告诉我们任何关于人工智能系统是否能做出这种声明的事情。
特异性
特异性(黄色细胞)是对正确阴性结果的比例的测量,也称为真阴性率。
其计算方法如下:
特异性= TN / (TN + FP)
Specificity
真正的阴性率在诊断测试中至关重要,因为它是衡量指标测试正确否定诊断的频率。这在临床上很重要,因为排除诊断对所需的分类/进一步调查/治疗水平有很大影响,更不用说假阴性对患者的情绪影响了。
然而,只有当金标准产生真阴性时,才能测量真阴性率,而医生在做出临床诊断决定时往往不会这样做。想象一下,医生的鉴别诊断列表必须包括所有可能的阴性诊断,或者放射学报告必须包括所有可能的阴性发现——这几乎是不可能的!在实践中,可以假设,如果医生没有而不是将一个诊断包括在鉴别诊断中,则所有其他可能的诊断都被自动排除。
阴性预测值
阴性预测值(NPV,蓝色单元格)衡量的是与阴性结果的相关性。
其计算方法如下:
NPV = TN / (FN + TN)
Negative predictive value
至于真负率,只有金本位产生真负才能算出来。
具有高 NPV、特异性和敏感性的人工智能系统很可能被批准用于临床。
组合二元分类
ROC 曲线
为每个诊断临界值绘制 1-特异性和敏感性对给出了接收器操作特征曲线(ROC 曲线)。
左上角的曲线越高,诊断测试就越“准确”。
曲线下面积(AUC)给出了诊断测试的区分能力的单一数字指标。
Arbitrary AUC cut-off meanings
当比较两种不同的诊断试验时,AUC 通常比对照金标准比较指数试验更有用,因为它不提供关于试验在裁定或排除诊断或发现方面有多好的信息。还需要进行统计显著性计算(p 值),以便将结果放入上下文中。(我甚至不打算触及支持和反对 p 值的论点!).
如果两条 ROC 曲线不相交,那么一种方法优于另一种方法,因为它在各方面都优于另一种方法。如果两条曲线相交,那么这表明存在一个平衡点,在这个平衡点上,对于某项任务,一个系统比另一个系统好,在这个平衡点之上,另一个系统更好。例如,人工智能系统可能比人类更具体,但人类可能更敏感。这可能表现为两条曲线在两个系统执行两个指标的点上相交。
有趣的是,与完美的黄金标准相比,人工智能系统永远不会有更好的 AUC。这是因为不可能在完美的金本位上有所改进。你所能期望的最好结果是同等的。幸运的是人工智能开发者,但不是病人,人类容易出错!
F1 得分
精确度和召回率的加权平均值(紫色单元)被称为 F1 分数,是机器学习中分类系统的常用度量。
其计算方法如下:
F1 得分= 2x((精确度 x 召回率)/(精确度+召回率))
然而,重要的是,这个分数没有考虑真正的否定(TN)。人工授精系统的阴性率对于确定(诊断“遗漏”率)很重要,因此也应尝试报告特异性和/或 NPV。
可能性和诊断优势比
为了涵盖阳性率和阴性率,需要一个包含检测概率和误报概率的综合单一指标。假阳性是“假警报”,假阴性是“假再确认”。
阳性似然比(LR+ = TPR / FPR)是检测的概率,高 LR+值是包括诊断的良好指标。
负似然比(LR- = FNR / TNR)是虚警的概率,低 LR 值是排除诊断的良好指标。
这两个比率(包括所有 4 个粉红色细胞)可以结合起来形成诊断比值比(DOR ),它是一项测试诊断准确性的量度。
其计算方法如下:
DOR = LR+ / LR- = (TPR/FPR) / (FNR/TNR)
DOR 的优势在于它不依赖于潜在的患病率,是一个不需要统计学意义的单一指标,具有 95%置信区间的简单计算,并且得到医学认可。
效力
测试的有效性可能最接近于“准确性”的定义,因为它是所有情况下指数测试的正确输出比例的度量。
其计算方法如下:
有效性= (TP + TN) / (TP + TN + FP + FN)
然而,有效性受潜在患病率的影响很大,这使得它成为一个较差的统计测试。例如,给定一组灵敏度和特异性,人群中高患病率的疾病比低患病率的疾病更有可能被指数测试诊断出来。因此,成效从不作为单一指标报告,而总是与 PPV 和 NPV 等其他指标一起报告。在测试人工智能系统的情况下,当计算有效性时,极高的流行率可能是一个问题,因为测试的每个案例都有一个诊断。
总结
不符合严格方法标准的研究通常会高估或低估测试性能的指标,因为它们限制了研究结果的适用性。人工智能开发人员可以使用几种统计方法,每种方法都有自己的优点和缺点。在临床环境中验证人工智能系统时,重要的是要考虑是否会报告真正的阴性结果,因为这将影响可以应用哪些统计测试。目前,医生的鉴别诊断、报告或发现不包括所有可能的阴性结果(这将过于详尽),因此必须假设被排除的诊断/发现是阴性的。但是,由于错误/疲劳/知识偏差,这可能会错误地将排除的诊断/发现计算为阴性,从而导致一些错误的结果。相反,如果没有真正的阴性结果,只能推断出精确度、召回率和 F1 值,这不能提供医学相关阴性诊断/发现和遗漏方面的完整情况。
最后的信息是,没有 100%正确的方法来报告人工智能系统在临床环境中的准确性,因为每个人都有自己的怪癖!我的建议是报告 ROC 曲线、AUC 和 DOR——这样你就可以用医学家理解的统计语言涵盖阳性率和阴性率的所有方面。令人欣慰的是,ROC 曲线在机器学习界越来越受欢迎,所以对于那些将你的技能应用于医疗问题的人来说,你将能够让你遇到的医生理解你的结果。
参考文献:
【http://www.stard-statement.org/ 号
*【http://bmjopen.bmj.com/content/6/11/e012799 *
http://www.ifcc.org/ifccfiles/docs/190404200805.pdf
http://gim.unmc.edu/dxtests/roc3.htm
诊断检查的范围从从病人的病史和体检中获得的体征和症状到…
www.biochemia-medica.com](http://www.biochemia-medica.com/content/selecting-and-interpreting-diagnostic-tests)*
如果你和我一样对人工智能在医学成像领域的未来感到兴奋,并想讨论这些想法,请联系我们。我在推特@drhughharvey
如果你喜欢这篇文章,点击推荐并分享它会很有帮助。
关于作者:
哈维博士是一名委员会认证的放射科医生和临床学者,在英国国民医疗服务体系和欧洲领先的癌症研究机构 ICR 接受过培训,并两次获得年度科学作家奖。他曾在 Babylon Health 工作,领导监管事务团队,在人工智能支持的分诊服务中获得了世界第一的 CE 标记,现在是顾问放射科医生,皇家放射学家学会信息学委员会成员,以及人工智能初创公司的顾问,包括 Kheiron Medical。
DBSCAN 如何工作,为什么要使用它?
Scikit Learn — Plot Cluster Comparison
首先,这是我在 medium 上的第一个故事,如果我做错了什么,我很抱歉。其次,我的英语不是很流利,那么我可能会犯很多错误,对此我也很抱歉。
简单解释一下我为什么用英语写这篇文章:首先,我需要提高我的英语技能。那么,什么比用英语写课文更好呢?第二,我认为英语文本会比葡萄牙语(我的母语)文本更受欢迎。
我认为当我们尝试去做,犯错误并从中吸取教训的时候,我们就学到了新的东西。
“经验只是我们给自己的错误起的名字.”(奥斯卡·王尔德)
好了,开始说 DBSCAN 吧。
带噪声应用的基于密度的空间聚类(DBSCAN) 是一种众所周知的数据聚类算法,常用于数据挖掘和机器学习。
基于一组点(让我们在图中举例说明的二维空间中思考),DBSCAN 根据距离度量(通常是欧几里德距离)和最小点数将彼此靠近的点分组在一起。它还将低密度区域中的点标记为异常值。
参数:
DBSCAN 算法基本上需要两个参数:
eps :指定点之间应该有多近才能被认为是聚类的一部分。这意味着如果两点之间的距离小于或等于该值(eps),则这些点被视为邻居。
minPoints :形成密集区域的最小点数。例如,如果我们将 minPoints 参数设置为 5,那么我们至少需要 5 个点来形成密集区域。
参数估计:
参数估计是每个数据挖掘任务都面临的问题。为了选择好的参数,我们需要了解它们是如何使用的,并且至少对将要使用的数据集有一个基本的了解。
eps :如果选择的 eps 值太小,很大一部分数据将不会被聚类。它将被视为异常值,因为不满足创建密集区域的点数。另一方面,如果选择的值太高,聚类将合并,大多数对象将在同一个聚类中。eps 应该根据数据集的距离来选择(我们可以使用 k-距离图来找到它),但一般来说,较小的 eps 值是更可取的。
minPoints :作为一般规则,最小 minPoints 可以从数据集中的多个维度(D)中导出,因为 minPoints ≥ D + 1。对于有噪声的数据集,较大的值通常更好,并将形成更重要的聚类。minPoints 的最小值必须是 3,但是数据集越大,应该选择的 minPoints 值就越大。
你可以在这里找到更多关于参数估计的信息。
为什么要用 DBSCAN?
DBSCAN 算法应该用于查找数据中的关联和结构,这些关联和结构很难手动找到,但对于查找模式和预测趋势可能是相关的和有用的。
聚类方法通常用于生物学、医学、社会科学、考古学、市场营销、字符识别、管理系统等领域。
让我们考虑一下 DBSCAN 的实际应用。假设我们有一个电子商务,我们想通过向客户推荐相关产品来提高销售额。我们不知道客户到底在寻找什么,但根据数据集,我们可以预测并向特定客户推荐相关产品。我们可以将 DBSCAN 应用于我们的数据集(基于电子商务数据库),并根据用户购买的产品找到聚类。使用此聚类,我们可以发现客户之间的相似之处,例如,客户 A 购买了 1 支笔、1 本书和 1 把剪刀,客户 B 购买了 1 本书和 1 把剪刀,然后我们可以向客户 B 推荐 1 支笔。这只是使用 DBSCAN 的一个小示例,但它可以用于多个领域的许多应用程序。
如何才能轻松实现?
正如我已经写的(提示:不要相信我写的所有东西)DBSCAN 是一个众所周知的算法,因此,您不需要担心自己实现它。您可以使用互联网上可以找到的一个库/包。下面是一个可以找到 DBSCAN 实现的链接列表: Matlab、 R、 R、 Python、 Python 。
我还开发了一个应用程序(葡萄牙语),以教学的方式解释 DBSCAN 如何工作。该应用程序是用 C++编写的,你可以在 Github 上找到它。
参考资料:
1996 年 8 月,北京大学出版社出版。一种基于密度的发现带噪声的大型空间数据库中聚类的算法。在 Kdd (第 96 卷,№34,第 226–231 页)中。
https://en.wikipedia.org/wiki/DBSCAN
应该有多‘深’才称得上深度学习?
深度学习现在无处不在。它是 AI 的前沿,每个人似乎都在追求它。
当我们第一次试图理解深度学习的概念时,通常会出现一个问题,
“机器学习模型需要有多深才能被认为是深度学习模型?”
这听起来可能是一个合理的问题。毕竟,在深度学习中,我们正在使用更深更复杂的模型。
事实证明,我们问了一个错误的问题。我们需要从一个不同的角度来看待深度学习,看看为什么。
让我们来看几个深度学习的定义。
“机器学习中的一个子领域,它基于学习多级表示的算法,以便对数据之间的复杂关系进行建模。因此,较高级别的功能和概念是根据较低级别的功能和概念定义的,这样的功能层次结构被称为深度架构”——深度学习:方法和应用。
“概念的层次结构允许计算机通过用简单的概念构建复杂的概念来学习它们。如果我们画一个图表来显示这些概念是如何建立在彼此之上的,那么这个图表是很深的,有许多层。为此,我们将这种方法称为人工智能深度学习。”—深度学习。麻省理工学院出版社,伊恩·古德菲勒,约舒阿·本吉奥,亚伦·库维尔。
这些谈到了一个叫做分层特征学习的概念。为了理解它,让我们后退一步,看看深度学习模型是如何工作的。
让我们以卷积神经网络为例。
卷积神经网络是深度学习的一个主要例子。他们受到了视觉皮层(大脑中处理视觉输入的区域)中神经元排列方式的启发。这里,并不是所有的神经元都与来自视野的所有输入相连。相反,视野是由相互部分重叠的神经元群(称为感受野)组成的。
卷积神经网络(CNN)以类似的方式工作。它们使用数学卷积算子(近似于感受野的工作方式)处理输入的重叠块。
A Convolutional Neural Network
典型 CNN 的第一卷积层使用一组卷积滤波器来从输入图像中识别一组低级特征。这些识别的低级特征然后被汇集(来自汇集层)并作为输入提供给下一个卷积层,该卷积层使用另一组卷积滤波器从先前识别的低级特征中识别一组高级特征。这对于几个层继续进行,其中每个卷积层使用来自前一层的输入来识别比前一层更高级别的特征。最后,最后一个卷积层的输出被传递给一组完全连接的层,用于最终分类。
本质上,CNN 的卷积滤波器试图首先识别较低级别的特征,并使用这些识别的特征通过多个步骤逐渐识别较高级别的特征。
这就是我们前面讲的分层特征学习,是深度学习的关键,也是它与传统机器学习算法的区别所在。
Hierarchical Feature Learning
深度学习模型(如卷积神经网络)不会试图一次理解整个问题。
即,它不像传统算法试图做的那样,试图一次掌握输入的所有特征。
它所做的是逐段查看输入,并从中导出较低级别的模式/特征。然后,它使用这些较低级别的特征来逐步识别更高级别的特征,通过许多层,分等级地。
这使得深度学习模型能够通过从简单模式逐步建立复杂模式来学习复杂模式。这也允许深度学习模型更好地理解世界,它们不仅“看到”特征,还看到这些特征是如何建立的层次结构。
当然,必须分层次地学习特征意味着模型中必须有许多层。这意味着这样的模型将是“深”的。
这让我们回到了最初的问题:这并不是说我们将深度模型称为深度学习。那就是,为了实现分层学习,模型需要是深度的。深度是实现分层特征学习的副产品。
分层特征学习允许深度学习模型不像传统机器学习模型那样具有“性能高原”。
The (lack of) Plateau in Performance in Deep Learning
那么,我们如何鉴别一个模型是深度学习模型还是现在?
简单来说,如果模型使用分层特征学习——首先识别较低级别的特征,然后在此基础上识别较高级别的特征(例如,通过使用卷积滤波器)——那么它就是深度学习模型。如果不是,那么无论你的模型有多少层,它都不被认为是深度学习模型。
这意味着具有 100 个全连接层(并且只有全连接层)的神经网络不会是深度学习模型,但具有少量卷积层的网络会是。
如果你想了解更多关于深度学习的知识,可以在亚马逊查阅我的书:Build Deeper:Deep Learning 初学者指南 。
原载于 2017 年 9 月 5 日 www.codesofinterest.com。
牙科诊所如何解决取消预约的问题
牙科医学的学生在学校学习口腔卫生和牙科的各个方面,但有一点他们没有让你做好准备,那就是你会因为预约取消的瘟疫而浪费多少空闲时间。
事实证明,大约 20%的牙科预约在最后一刻被取消。在一些诊所,这个数字可能高达 50%,特别是当考虑到没有出现时。其中至少 75%仍未填补,这相当于该行业每年损失约 114 亿美元的收入。
当我们检查这种患者行为背后的原因时,我们可以看到许多患者在提前两到四周预约时取消预约——任何超过四周的预约被取消的风险都要高得多。
这是合乎逻辑的,因为大多数人的时间表主要是由他们不可预测的老板决定的,他们的孩子忘记告诉他们即将举行的家长会或在学校太早到来的最后期限等等。
取消的另一个预测因素是保险类型,它与社会经济地位密切相关。来自有公共保险的低收入家庭的病人是臭名昭著的失约者。处罚和一些战术服务的引入,如旨在提醒患者预约的灯塔 360 和解决方案 Reach ,在一定程度上改变了这种行为。然而,他们设法减少了失约,但没有取消,因为以前可能失约的人现在只需提前一两天取消。
这些行为上的变化,虽然为这些公司提供了成功的声称,但对该行业仍然是无益的,因为这些被取消的任命仍然在很大程度上是空缺的。
一家总部位于波士顿的健康科技初创公司对这个行业之谜提出了一个罕见的新观点。EarlierCare 的目标是通过应用机器学习算法来研究预订模式和取消约会的行为,从而减少取消,接近零。该数据将允许牙科诊所看到其最频繁取消的时间段的热图,并被给予关于如何修改其时间表中这些红色区域的可用性以尽可能减少它们的建议。
除了采用人工智能, EarlierCare 还旨在通过创建一个平台来减少取消预约的情况,该平台将通过一个应用程序向现有患者和新患者群“转售”这些新开放的位置。
然后,患者可以标记出他们最想看牙医的日期和时间,从而创建一个个性化的提醒日历,在取消预约后突然有空的时候通知他们。这为患者和诊所创造了双赢的局面,因为患者现在可以获得更方便的预约,他们也更确定自己能遵守。诊所的空缺职位会自动从现有数据库和外部早期护理患者库中填补。
无论机器学习发展到什么程度,不确定性都会存在。但通过研究我们的行为,我们可以利用习惯的力量,最终通过看似随机的万亿字节数据,帮助解决几十年的老问题。
费德勒是如何击败纳达尔的
对费达尔游戏玩法的深入探究
对于那些生活在岩石下的人来说,今年 1 月 29 日早些时候,费德勒和纳达尔之间的澳大利亚网球公开赛决赛在墨尔本举行。费德勒在史诗般的五盘比赛中胜出6–4 3–6 6–1 3–6 6–3,这是为电影编写的完美跷跷板!两位球员在整个比赛中都表现出了令人难以置信的毅力,特别是因为他们都在长期受伤后复出。对罗杰和拉法来说,这标志着一个非凡游戏赛季的开始,对我来说,有很多数据需要分析!
我一直想对费德尔的竞争做一次真正的深度挖掘,澳大利亚公开赛决赛似乎是一个不错的起点。多亏了令人难以置信的图表项目,世界可以对最近的大部分比赛进行逐镜头分析。对我们这样的网球爱好者来说绝对是金牌;)
在这篇博客中,我们将会看到拉法糟糕的正手击球,罗杰漂亮的反手回击以及这之间的一切。他们在球场上的发球有多好,身体发球对罗杰有效吗,拉法是从哪里完成长途拉力赛的?罗杰的反手击球被讨论了很多,他是打得很深,还是打在底线上?谁控制了反弹,谁处理压力更好,等等!
拍摄制作
让我们看看他们的投篮——意料之中的正手触地球和反手触地球领先,其次是反手削球和其他击球。
有趣的是,拉法比罗杰打更多的正手球,而罗杰比拉法打更多的反手球——很可能是纳达尔掩盖他的反手球的结果。很快会有更多的消息:)
按拉力赛长度计算的胜率
纳达尔的一个著名策略是延长反弹,迫使对手失误。这对罗杰不利吗?
左边是罗杰·费德勒通过致胜和诱导强迫失误赢得的分数(来自纳达尔),右边是拉法。纳达尔的策略看起来肯定是有效的(6 杆后明显增加),强迫失误让他比胜利者获得更多的分数!在费德勒这边,他的获胜者是在一个不同的联盟,在 6 次出手后为他赢得了超过 30%的分数。
谁主宰了!
分数显示这场比赛打得很好,两局轮流进行。然而,我想看看双方球员在比赛中的统治力,比赛分数是一个很容易衡量的变量。
优势得分:我没有深入研究拉力赛长度(一分有多难!),只看在那个特定游戏中赢得的积分份额。假设罗杰以 40 比 15 赢得了比赛——罗杰的统治力得分是 0.8,而拉法的统治力得分是 0.2。
一个有趣的统计数据——罗杰在发球比赛中的平均统治力为 0.71,而纳达尔为 0.66。费德勒的发球稍微轻松了一点!
这是两个球员每场比赛的优势分数,由于发球的变化,会出现预期的曲折。看看第 6-8 场比赛,罗杰在第一盘击败了纳达尔,第 11-14 场比赛,纳达尔连续 4 场比赛!最后,在第五盘,罗杰最初被打破(勉强),但他回来赢得了最后 4 场比赛的小跑!
发球
作为玩家游戏性的最重要因素之一,你的发球决定了接下来的对打风格!我已经分析了他们的发球策略,他们是否在寻找更短的反弹,以及他们的第一次和第二次发球有多不同。
显然罗杰有更好的一发(22%的一发得分率!),但是拉法在第二次发球时挡住了它(用那一脚!).
发球方向——发球方向分为三大类,“宽”、“身体”和“T”。看看他们在平分(左边)和分庭(右边)的百分比。
x 轴是发球的自然顺序,deuce_wide 在最左边,ad_wide 在最右边。
重要的是要记住,罗杰打右手,而拉法打左手,以了解模式。而罗杰在 Deuce T 和 Ad Wide 打反手,拉法在 Deuce T 和 Ad T 打反手,罗杰投篮 60%发球给拉法的反手,拉法投篮 50%以上给罗杰的反手。该模式几乎是对称的两个平分和广告法院!
还要注意罗杰几乎从不在身体上发球,但是拉法在 30%的时候都在这样做——有意思!它有分红吗?
服务器在 3 分或以下赢得的分数百分比
对于纳达尔来说,向身体发球并不是一个很大的优势(在短分上)——这几乎类似于在平分场上向反手发球,以及在 Ad 场上最糟糕的方向。对于费德勒来说,所有方向的短分都几乎相等!
现在让我们把注意力转移到他们发球得分的进程上——发球方需要多长时间才能结束得分?
正如我们前面看到的,罗杰的第一次发球非常有效!由于拉法的二次发球胜率更高,我本以为这些反弹会持续更短时间——两者完全相等!每秒 5.3 次拉力赛——这可能是纳达尔用他的触地击球指挥拉力赛的结果。我们再深入一点,好吗?
左边的图表示第一次发球得分与对打得分的百分比,右边的图表示第二次发球得分。一个非常有趣的之字形图案是可见的,因为当球在他的球场上时,两个球员都占上风!根据我们之前的观察,拉斐尔在第二次发球时领先,而罗杰在第一次发球时也领先。
第一次发球的稳步下降表明,得分越长,对他不利的可能性就越大——如果这是一次强有力的发球,得分应该更早结束,对打仍然存在的事实表明回球者占了上风!
接发球
足够的服务,让我们得到一些好的回报!我们将会看到在回球时打了哪些球,从哪些位置以及回球的深度。
根据报道,费德勒在反手回击方面占据上风,而拉法在正手回击方面略微领先罗杰。不要看太多的切片和芯片回报,数量太少,没有任何洞察力。
我们已经看到了纳达尔令人惊讶的高身发球,让我们看看费德勒如何反应!
罗杰·费德勒几乎 50%的身体发球胜利——难以置信!拉法,请发球出界!纳达尔在身体上也有 50%的胜率,但他们总共只占 6 次发球(对洞察力来说微不足道)。
好的回报通常是快速深度的,这使服务器处于惊讶状态。弱小的矮个子通常很容易被派出,这就是为什么两个球员都更喜欢发球而不是对手的反手。
图中显示的是费德勒(左)和纳达尔(右)的短回和深回的百分比。费德勒在所有击球中都有更深的回球,尤其是正手击球!很明显,拉法应该在回报上下功夫,这将是费德勒发球 3 分高比例的一个重要因素。
触地击球
发球发了,接发球发了,我们还是要得分,对吗?让我们关注一下两位选手的击球方向——费德勒更多的直拍,纳达尔更多的正手?
蓝条代表斜线球、中线球、底线球、内外球的正手击球百分比。费德勒在左,纳达尔在右
我对两位球员如此高的斜线球命中率感到惊讶!正如所料,当球打在中间时,反手击球的比例较高,这表明反手击球的风险较低。另一个非常令人惊讶的数据是——相比纳达尔的 27 次(12%),罗杰打出了 42 次内翻正手(20%)。你可能永远也猜不到这一点,让我们看看这些内外颠倒是否能有效地完成这一点?
为了计算最后一击的有效性,我考虑了三个因素——如果这一击是致胜的或者导致了对手的被迫失误(在接下来的一击中),则为+1,如果这一击被证明是非被迫失误,则为-1。因此,如果拉法打了 5 次反手得分,其中 2 次是致胜球,2 次是罗杰的诱导失误,1 次是拉法的非受迫性失误,他的反手得分将是(2+2–1)/5 = 0.6
让我们剖析一下上面的情节,它给了我们很多启示!
- 罗杰的正手斜线球还可以,但是拉法的失误有点多
- 中路的正手一点也不漂亮,尤其是拉法(6 次非受迫性失误,1 次致胜)。
- 嗯,拉法的正手下网一如既往的完美(香蕉射谁了?).罗杰因为他的非受迫性失误受到了很多处罚,显示了他的表现有多不稳定!
- 从内外来看,罗杰可能命中更多,但在这方面没有人能击败纳达尔!
- 反手向下-中间也不好看。基本不要中间击球!
- 费德勒的反手直拍再次显示了他的连胜(4 次胜利,2 次受迫性失误和 3 次非受迫性失误)
在最后的镜头中有更多的视觉效果
Forehand Finishing Shots
Backhand Finishing Shots
两张饼状图都显示了费德勒非受迫性失误的优势,也显示了纳达尔是如何从受迫性失误中获得异常高的分数的!
网玩
随着费德勒近年来在网球比赛中大获全胜,纳达尔成为一名底线球员,这几乎是一个机会!
一个有趣的统计数据是,当费德勒决定上网时,反弹是多么短暂。我完全可以想象费德勒发球,上前截击,然后纳达尔将球打入网内——4 次对打!
我告诉过你!
压力点
现在我们知道费德勒的比赛有多冒险了,他是如何在第五盘坚持住的,尤其是在休息的时候!我试图理解压力点,我的定义是当发球方在发球时落后一分以上(例如 0-30 或 15-40),或者当他落后一个破发点(40-AD)时,就称为“压力点”。
这是压力点的图表。
Pressure points and Pressure points saved, Federer on left, Nadal on right
通过之字形曲线可以看到设定的优势,两条曲线之间的差距变成了失去的关键破发点!在第一盘,罗杰没有面对一个压力点,这与纳达尔在第四盘的情况类似。第五盘非常有趣——尽管在一个压力点上输了,但费德勒反击了,让纳达尔承受了巨大的压力(13 分!).最终,罗杰在最后 4 场比赛中连胜,夺得冠军:)
结论
- 罗杰打出了更多的致胜球和更多的非受迫性失误。五花肉的游戏性!
- 罗杰的发球比拉法更有统治力(0.71 比 0.66)
- 罗杰的第一次发球更有效,他发球得分率高
- 拉法有一个更强的二次发球,在比赛中一直表现得更好。
- 两名球员都在对方的背后发球,拉法在罗杰的身体上发了相当多的球。
- 为身体服务对拉法来说没有用——失去了 50%的分数
- 两位球员都有很高的斜线球命中率,罗杰比拉法更多的内外球。令人惊讶!
- 拉法在所有射门类型上都有更好的得分——罗杰犯了太多的错误。
- 罗杰打了一场非凡的落网球,在离网 4.5 个回合内完成了比赛。
- 直到第五盘,两位选手对压力点的处理几乎是一样的。罗杰全力以赴,最后一盘拉法连得 13 分,最终他屈服了!
总而言之,这个分析是更多分析的起点——我很想看看这几年来两位球员是如何处理最后一击、发球方向和压力点的!
2008 年温布尔登网球公开赛应该讲述一个不同的故事,对吧?;)
我们如何在一小时内构建图书推荐系统第二部分— k 近邻和矩阵分解
在的上一篇文章中,我们看到了如何使用简单的相关技术,根据图书用户的评分记录,在他们之间建立一个相似性的衡量标准。在本帖中,我们将展示如何使用这些相似性度量向读者提出建议。
基于 k 近邻的协同过滤
kNN 是一种机器学习算法,可以根据常见的书籍评级来找到相似用户的聚类,并使用前 k 个最近邻居的平均评级进行预测。例如,我们首先在矩阵中显示评级,矩阵中每个项目(书籍)占一行,每个用户占一列,如下所示:
然后,我们找到具有最相似的用户参与度向量的 k 个项目。在这种情况下,项目 id 5 的最近邻居= [7,4,8,…]。现在让我们将 kNN 实现到我们的图书推荐系统中。
数据
我们使用上次使用的相同的图书数据:它由三个表组成:ratings、books info 和 users info。我从这里下载了这三张表。
评分信息
用户信息
图书信息
为了确保统计上的显著性,我们将只看流行书籍
为了找出哪些书受欢迎,我们需要结合书籍数据和评分数据。
然后,我们按书名分组,并为总评分创建一个新列。
我们现在将评分数据与总评分计数数据相结合,这正好给了我们过滤掉不太出名的书所需的数据。
让我们来看看总评分的统计数据:
中值书只被评价过一次。让我们看看分布的顶端:
大约 1%的书获得了 50 或更多的评分。因为我们的数据中有如此多的书,我们将把它限制到前 1%,这将为我们提供 2713 本独特的书。
仅过滤美国和加拿大的用户
为了提高计算速度,并避免遇到“内存错误”问题,我将把我们的用户数据限制在美国和加拿大。然后将用户数据与评级数据和总评级计数数据相结合。
实现 kNN
我们将表格转换为 2D 矩阵,并用零填充缺失的值(因为我们将计算评级向量之间的距离)。然后,我们将矩阵数据帧的值(等级)转换成一个稀疏矩阵,以便进行更有效的计算。
寻找最近的邻居
我们使用带有 sklearn.neighbors. 的无监督算法我们用来计算最近邻的算法是“brute”,我们指定“metric=cosine”这样算法就会计算评分向量之间的余弦相似度。最后,我们拟合模型。
测试我们的模型并提出一些建议:
在这一步中,kNN 算法测量距离以确定实例的“接近度”。然后,它通过查找最近的邻居对实例进行分类,并在邻居中挑选最受欢迎的类。
完美!《绿色一英里》系列书籍绝对值得推荐,一本接一本。
使用矩阵分解的协同过滤
Source: ohAI
矩阵分解只是一个玩弄矩阵的数学工具。矩阵分解技术通常更有效,因为它们允许用户发现用户和项目(书籍)之间交互的潜在(隐藏)特征。
我们使用奇异值分解(SVD)——一种矩阵分解模型来识别潜在因素。
与 kNN 类似,我们将美加用户评级表转换为 2D 矩阵(这里称为效用矩阵),并用零填充缺失值。
然后我们转置这个效用矩阵,这样书名变成了行,用户标识变成了列。在使用 TruncatedSVD 对其进行分解后,我们将其拟合到模型中进行降维。这种压缩发生在数据帧的列上,因为我们必须保留书名。我们选择 n_components = 12 作为 12 个潜在变量,您可以看到,我们的数据维度已经从 40017 X 2442 显著减少到 2442 X 12。
我们为最终矩阵中的每个图书对计算皮尔逊相关系数。为了与 kNN 的结果进行比较,我们选择了同一本书“绿色里程:科菲的手(绿色里程系列)”,以找到与它具有高相关系数(在 0.9 和 1.0 之间)的书籍。
你有它!
不算太寒酸!我们的系统可以打败亚马逊的,你说呢?看标题截图!
参考:音乐推荐
我们如何在一小时内建立图书推荐系统第一部分——基础
几乎每个人都有过这样的网上体验:网站为了未来的销售或持续的流量而提供个性化的推荐。亚马逊告诉你“买了这个商品的顾客也买了”,Udemy 告诉你“看过这个课程的学生也看过”。2009 年,网飞向一个开发团队颁发了 100 万美元的奖金,奖励其将公司推荐系统的准确率提高了 10%的算法。
如今,构建推荐系统需要分析、机器学习和软件工程方面的专业知识,学习新的技能和工具既困难又耗时。在这篇文章中,我们将从头开始,讲述 Python 中的一些基本技术和实现。在以后的文章中,我们将介绍更复杂的方法,如基于内容的过滤和基于协作的过滤。
所以,如果你想从头开始学习如何构建推荐系统,那就开始吧。
数据
Book-Crossings 是由蔡-尼古拉斯·齐格勒编制的图书评分数据集。它包含 90,000 个用户对 270,000 本书的 110 万个评级。等级从 1 到 10。
该数据由三个表组成:评级、图书信息和用户信息。我从这里下载了这三张表。
import pandas as pd
import numpy as np
import matplotlib.pyplot as pltbooks = pd.read_csv('BX-Books.csv', sep=';', error_bad_lines=False, encoding="latin-1")
books.columns = ['ISBN', 'bookTitle', 'bookAuthor', 'yearOfPublication', 'publisher', 'imageUrlS', 'imageUrlM', 'imageUrlL']
users = pd.read_csv('BX-Users.csv', sep=';', error_bad_lines=False, encoding="latin-1")
users.columns = ['userID', 'Location', 'Age']
ratings = pd.read_csv('BX-Book-Ratings.csv', sep=';', error_bad_lines=False, encoding="latin-1")
ratings.columns = ['userID', 'ISBN', 'bookRating']
评级数据
评级数据集提供了用户对图书的评级列表。它包括 1,149,780 条记录和 3 个字段:userID、ISBN 和图书评级。
收视率分布
收视率分布很不均匀,绝大多数收视率都是 0。
书籍数据
图书数据集提供了图书的详细信息。它包括 271,360 条记录和 8 个字段:ISBN、书名、图书作者、出版商等。
用户数据
该数据集提供用户人口统计信息。它包括 278,858 条记录和 3 个字段:用户 id、位置和年龄。
年龄分布
最活跃的用户是那些 20-30 岁的人。
基于评级计数的建议
ISBN 为“0971880107”的书获得了最多的评分。我们来看看是什么书,前 5 都有哪些书。
在这个数据集中获得最多评分的书是里奇·沙佩罗的《野性的阿尼姆斯》。这五本书有一个共同点,那就是它们都是小说。这位推荐者认为小说很受欢迎,可能会获得更高的收视率。而如果有人喜欢《可爱的骨头:一部小说》,我们大概也应该向他(或她)推荐《野阿尼姆斯》。
基于相关性的建议
我们使用皮尔逊相关系数来衡量两个变量之间的线性相关性,在我们的例子中,两本书的评级。
首先,我们需要找出平均评分,以及每本书获得的评分数。
观察结果:
在这个数据集中,获得最多评价的书根本没有得到很高的评价。因此,如果我们使用基于评分的推荐,我们肯定会犯错误。所以,我们需要一个更好的系统。
为确保统计显著性,评级低于 200 的用户和评级低于 100 的图书被排除在外。
评级矩阵
我们将评级表转换成 2D 矩阵。这个矩阵将是稀疏的,因为不是每个用户都对每本书进行评级。
让我们来看看哪些书与排名第二的书《可爱的骨头:一部小说》相关。
引用维基百科的话:“这是一个十几岁的女孩在被强奸和谋杀后,在她的个人天堂看着她的家人和朋友努力继续他们的生活,同时她接受了自己的死亡”。
我们获得了图书的 ISBNs,但是我们需要找出书名,看看它们是否有意义。
让我们从上面高度相关的列表中选择三本书来考察:《保姆日记:一部小说》、《飞行员的妻子:一部小说》和《心在哪里》。
《保姆日记》讽刺了曼哈顿上层社会在照看孩子的人眼中的形象。
《可爱的骨头》的作者是同一个人,《飞行员的妻子》是 Shreve 非正式三部曲中的第三部小说,故事发生在新罕布什尔州海岸的一座大型海滨别墅里,这里曾是一座修道院。
《心在何处》详细描述了美国低收入家庭和寄养儿童的苦难。
这三本书听起来会与《可爱的骨头》高度相关。看来我们的关联推荐系统正在发挥作用。
摘要
在这篇文章中,我们学习了如何设计简单的推荐系统,你可以在一个小时内实现并测试它。这篇博文的 Jupyter 笔记本版本可以在这里找到。如果你想了解更多,Xavier Amatriain 的讲座是一个很好的起点。
在未来的帖子中,我们将介绍更复杂的方法,如基于内容的过滤、k-最近邻、协作过滤,以及如何提供推荐和如何测试推荐系统。在此之前,享受推荐!
我的训练和测试数据有多相似?
了解机器学习模型可能失败的场景
他们总是说不要拿苹果和橘子比较。但是如果我们比较一种苹果和橘子的混合物和另一种苹果和橘子的混合物,但是分布是不同的呢?还能比吗?你会怎么做?
在现实世界的大多数情况下,你会遇到后者。
这在数据科学中经常发生。在开发机器学习模型时,我们遇到了这样一种情况,我们的模型在训练数据上表现很好,但在测试数据上却无法达到同样的性能。
我这里指的不是过度适应。即使我选择了基于交叉验证的最佳模型,但它在测试数据上的表现仍然很差,测试数据中仍有一些我们没有捕捉到的固有模式。
想象一下这样一种情况,我正试图模拟顾客的购物行为。现在,如果我的训练和测试数据如下所示,那么您可以清楚地看到这里的问题。
与测试相比,该模型将针对平均年龄较低的客户进行培训。这个模型从未见过像测试数据中那样的年龄模式。如果年龄是你的模型中的一个重要特征,那么它在测试中就不会有好的表现。
在这篇文章中,我将谈论如何识别这个问题,以及我们如何解决它的一些原始想法。
协变量移位
我们可以更正式地定义这种情况。协变量是指我们模型中的预测变量。协变量移位是指预测变量在训练和测试数据中具有不同**特征(分布)**的情况。
在有许多变量的现实世界问题中,协变量的变化很难发现。在这篇文章中,我试图讨论一种方法来识别这一点,以及如何解释这种训练和测试之间的转换。
基本思路
如果存在协变量偏移,那么在混合训练和测试时,我们仍然能够以良好的准确性对每个数据点的来源(无论是来自测试还是训练)进行分类。
我们来了解一下原因。考虑上面的例子,其中年龄是测试和训练之间的漂移特征。如果我们采用类似随机森林的分类器,并尝试将行分类为测试和训练,年龄将成为分割数据时非常重要的特征。
实施
现在,让我们尝试将这个想法应用到真实的数据集上。我用的是这次 kaggle 比赛的数据集:https://www . ka ggle . com/c/Porto-seguro-safe-driver-prediction/data
第一步:数据预处理
我们必须首先清理我们的数据,估算所有缺失值,并对所有分类变量进行标签编码。对于这个数据集,不需要这一步,所以我跳过了这一步
#loading test and train data
train = pd.read_csv(‘train.csv’,low_memory=True)
test = pd.read_csv(‘test.csv’,low_memory=True)
Step2: 表示产地来源
我们必须在训练和测试数据中添加一个特征**‘is _ train’**。该特性的值对于测试为 0,对于序列为 1。
*#adding a column to identify whether a row comes from train or not
test[‘is_train’] = 0
train[‘is_train’] = 1*
第三步: 训考结合
然后我们必须把两个数据集结合起来。此外,由于训练数据具有测试中不存在的原始“目标”变量,我们也必须删除该变量。
***注意:*对于您的问题,“目标”将被您的原始问题的因变量的名称所替代
*#combining test and train data
df_combine = pd.concat([train, test], axis=0, ignore_index=True)
#dropping ‘target’ column as it is not present in the test
df_combine = df_combine.drop(‘target’, axis =1)y = df_combine['is_train'].values #labels
x = df_combine.drop('is_train', axis=1).values #covariates or our independent variablestst, trn = test.values, train.values*
第四步: 构建并测试一个分类器
出于分类的目的,我使用随机森林分类器来预测组合数据集中每一行的标签。您也可以使用任何其他分类器。
*m = RandomForestClassifier(n_jobs=-1, max_depth=5, min_samples_leaf = 5)
predictions = np.zeros(y.shape) #creating an empty prediction array*
我们使用分层的 4 倍,以确保每个类别的百分比得到保留,并且我们一次覆盖全部数据。对于每一行,分类器将计算它属于训练的概率。
*skf = SKF(n_splits=20, shuffle=True, random_state=100)
for fold, (train_idx, test_idx) in enumerate(skf.split(x, y)):
X_train, X_test = x[train_idx], x[test_idx]
y_train, y_test = y[train_idx], y[test_idx]
m.fit(X_train, y_train)
probs = m.predict_proba(X_test)[:, 1] #calculating the probability
predictions[test_idx] = probs*
第五步: 解释结果
我们将输出我们的分类器的 ROC-AUC 度量,作为对该数据有多少协变量偏移的估计。
如果分类器能够以良好的准确性将行分类到训练和测试中,我们的 AUC 得分应该在较高的一侧(大于 0.8)。这意味着训练和测试之间的强协变量转移。
*print(‘ROC-AUC for train and test distributions:’, AUC(y, predictions))# ROC-AUC for train and test distributions: 0.49944573868*
AUC 值为 0.49 意味着没有明显的协变量变化。这意味着大多数观察值来自不特定于测试或训练的特征空间。
由于这个数据集取自 Kaggle,所以这个结果是意料之中的。因为在这种竞争中,数据集是经过精心策划的,以确保这种变化不存在。
在我们开始建模之前,可以对任何数据科学问题重复这一过程,以检查协变量的变化。
超越
在这一点上,我们要么观察协变量转移,要么不观察。那么,我们可以做些什么来提高测试数据的性能呢??
- 漂移特征的丢弃
- 使用密度比估计的重要性权重
漂移特征的丢弃:
***注:*此方法适用于你见证协变量移位的情况。
- 从我们在上一节中构建的随机森林分类器对象中提取特征重要性
- 顶部的特征是那些正在漂移并导致转变的特征
- 从顶部的功能中,一次放下一个变量,构建您的模型并检查其性能。收集所有不会降低性能的特性
- 现在,在构建最终模型时,删除所有这些功能
Bucketing of features
我们的想法是移除红色桶中的要素
使用密度比估计的重要性权重
***注:*无论是否存在协变量移位,该方法都适用。
让我们来看看我们在上一节中计算的预测。对于每个观察值,该预测告诉我们根据我们的分类器它属于训练数据的概率。
*predictions[:10]
----output-----array([ 0.34593171])*
因此,对于第一行,我们的分类器认为它属于概率为. 34 的训练数据。我们姑且称之为 P(火车)。或者我们也可以说它有 0.66 的概率来自测试数据。我们姑且称之为 P(测试)。魔术是这样的:
对于每一行训练数据,我们计算一个系数 w = P(测试)/P(训练)。
这个 w 告诉我们训练数据的观察值与我们的测试数据有多接近。下面是笑点:
我们可以在我们的任何分类器中使用这个 w 作为样本权重,以增加这些看起来与我们的测试数据相似的观察值的权重。直觉上,这是有意义的,因为我们的模型将更侧重于从观察中捕捉模式,这似乎类似于我们的测试。
这些重量可以使用下面的代码来计算。
*plt.figure(figsize=(20,5))
predictions_train = predictions[len(tst):] #filtering the actual training rows
weights = (1./predictions_train) — 1\.
weights /= np.mean(weights) # Normalizing the weightsplt.xlabel(‘Computed sample weight’)
plt.ylabel(‘# Samples’)
sns.distplot(weights, kde=False)*
您可以传递在模型拟合方法中计算的权重,如下所示:
*m = RandomForestClassifier(n_jobs=-1,max_depth=5)m.fit(X_train, y_train, ***sample_weight=weights***)*
Weights distribution for the training observations
以上情节中需要注意的一些事情:
- 观察值的权重越高,与测试数据越相似
- 几乎 70%的训练样本具有接近 1 的样本权重,因此来自对训练或测试高密度区域不是非常特定的特征空间。这与我们计算的 AUC 值一致
结束注释
我希望现在你对协变量转换有了更好的理解,你可以如何识别它并有效地对待它。
参考
[1] Shimodaira,H. (2000 年)。通过加权对数似然函数改进协变量移位下的预测推断。统计规划与推论杂志,90,227–244。
【2】比克尔,S. 等 (2009)。协变量移位下的鉴别学习。机器学习研究杂志,10,2137–2155
https://github.com/erlendd/covariate-shift-adaption
[4]所用数据集的链接:https://www . ka ggle . com/c/Porto-seguro-safe-driver-prediction/data
数据科学家如何提出正确的问题?
我喜欢提问。而且,多年来,这份爱让我不仅能很好地提问,还能问出正确的问题。
通过在大学里学习古希腊语和拉丁语,我非常熟悉一些最好的魔鬼拥护者:苏格拉底、亚里士多德和柏拉图;在获得图书馆和信息科学硕士学位的同时,我开始应用批判性思维大师的学术研究框架,如玛西娅·贝茨和布伦达·德文;现在,在熨斗学院的数据科学沉浸式课程中,我开始学习数据科学的提问方式。
那么,对于一个数据科学家来说,问正确的问题是什么样的呢?
如果你花几秒钟在谷歌上搜索“问正确的问题数据”,你会检索到几十个“问这几个问题,你不会出错”的想法。这些妙趣横生的文章更有可能用下图这样的图表来修饰:
Image from Piyanka Jain‘s piece “3 Key Analytics Questions to Ask Your Big Data” (2012).
这些图片通常概述的步骤大致如下:1)就衡量成功的关键绩效指标达成一致(上文 Jain 的衡量框架),2)定义这些关键绩效指标(上文 Jain 的投资组合分析),以及 3)确定利益相关方(上文 Jain 的客户分析)。一旦你做到这一切,瞧!你拥有一切你需要的东西来精心制作一个值得数据驱动的探索的真诚问题。
虽然回答上述问题应该是任何数据驱动的分析的一部分,但简单地回答这些问题似乎不符合数据科学家在“做”数据科学时所做的事情。那么,我们带来了什么额外的东西呢(当然,除了我们对微积分、线性代数、统计学、概率和编程的惊人理解之外)?
嗯,在这个领域呆了整整两个星期之后,我觉得有资格说,数据科学提问方式的独特力量来自于……等等……科学!
(不,我不是说数据科学家整天站在实验室里,在显微镜下看着比特和字节。我的意思是,数据科学家通过使用传统上与生命科学相关的技术来质疑他们的世界。)
对一些人来说,这似乎是显而易见的——科学实际上是专业的名称——但在写这篇文章之前,它对我来说仍然有点模糊。
为了提醒我们自己“科学”意味着什么,让我们回到五年级和科学方法。科学方法的第一步(或者第二步,如果你把观察算作第一步的话)是提问。
回到五年级,在提出一个问题后,我们被教导形成一个假设,然后检验这个假设,最后分析我们的结果。但是我们很少被鼓励在观察数据和得出结论之间徘徊(另外,我们为什么要这样做?最酷的部分是证明醋和小苏打混合会使东西爆炸。
但是,我们在五年级时掩盖的同一个极限空间,我们可以根据某种基于数据的反馈循环一次又一次调整我们的问题的空间,似乎就是制造数据科学特殊调味酱的地方。
如果我们深入一些数据科学教育学,我们可以看到科学方法与乔·布利茨坦和汉斯·彼得·菲斯特所说的“数据科学过程”之间的相似之处:
https://insidebigdata.com/2014/11/12/ask-data-scientist-data-science-process/
你会很快发现科学方法和数据科学过程非常非常相似。
(如果你想要一个更性感的版本,请查看微软的数据科学生命周期,并用“问一个问题”替换商业理解。)
而且,与探索最相关的是,他们都强调迭代(Bircher 的科学方法图及其“快速迭代”调用,以及 Blitzstein & Pfister 的不断旋转的箭头)。这些过程中的“科学”似乎体现在一个我们应该反复重复的问题-测试-分析循环中。通过重复这些步骤,数据科学家能够精心设计正确的问题。
这些正确的问题被脸书数据科学家 Brandon Rohrer 称为“尖锐的”在“如何做数据科学”中,他写道:
在选择你的问题时,想象你正在接近一个神谕,它可以告诉你宇宙中的任何事情,只要答案是一个数字或一个名字。这是一个恶作剧的神谕,它的回答将尽可能含糊不清,令人困惑。你想用一个无懈可击的问题来确定它,以至于先知不得不告诉你你想知道的。糟糕问题的例子有“我的数据能告诉我关于我的业务的什么?”,“我该怎么办?”或者“我如何增加利润?”这些为无用的答案留下了回旋的空间。相比之下,对于“第三季度我会在蒙特利尔卖出多少台 Q 型小玩意?”这样的问题,答案很明确或者“我车队中的哪辆车会先出故障?”是无法避免的。
当然,因为我们是在这里做科学研究,Rohrer 的文章以命令式的**“然后重新开始”结束。**
数据科学教育家 Raj Bandyopadhyay 在“数据科学过程:一个数据科学家每天实际做什么”中同样强调了提问的迭代过程是真正的数据科学分析的第一步:
你一开始会问很多问题。。。一旦你对这个领域有了一个合理的理解,你应该问更多有针对性的问题,以准确理解你的客户想要你解决的问题。。。答对了!你现在可以看到问题中的数据科学。。。[和]。。。你可以把它框起来。。。请求进入数据科学问题。。。【还有一次】。。。你有一些具体的问题,你可以回到销售副总裁那里,向她展示你的问题。
…等等,直到你到达的问题。
总之,虽然为数据分析提供一个按数字绘制的解决方案的思考片段对于调整业务目标和让你的老板高兴是有用的,但要知道数据科学远不止这些。
数据科学是关于科学的!科学是关于反复提问的,很少能被包装成一个可转移的“做这个,然后做那个”的包。这就是为什么数据科学家拥有我们出了名的高薪,并且是值得这些薪水和尊敬的神奇科技独角兽——我们是批判性思维、商业敏锐度和硬技能的结合体。
爱因斯坦知道发生了什么,他说
如果我有一个小时来解决一个问题,而我的生命取决于它,我会利用前 55 分钟来确定要问的适当问题,因为一旦我知道了适当的问题,我就可以在不到 5 分钟的时间内解决问题。
如果我有一个小时来解决一个问题,我可能会分配至少 10 分钟来阅读栈溢出,但是嘿,爱因斯坦不得不利用他所拥有的。
温哥华人对(取消)拥挤收费有什么看法?一种社交媒体文本挖掘方法。
温哥华是世界上许多考虑移动定价策略的城市之一,希望以此减少交通拥堵,促进公平,支持交通投资。成立了一个移动定价独立委员会,对在温哥华市引入去拥堵收费的可行性进行研究并提出建议,以实现这些目标。
几周前,我在委员会的脸书官方网页上浏览对其中一个帖子的评论——“是时候了,Metro Vancouver*”——这两条评论引起了我的注意:*
在同一周,我有机会参加了由新威斯敏斯特市组织的小组讨论,会上发表了不同的意见。许多与会者认为移动定价是减少拥堵的灵丹妙药,而其他人则严重关注公平、公正和可负担性。在脸书和推特的官方页面上,我也观察到了一个类似的趋势,这让我很好奇——温哥华人对拥堵费有什么看法?
我的假设是:这是一种消极的感觉。显而易见先生——嘿,我听到了!不要认为我的话是理所当然的。正如 w .爱德华兹·戴明曾经说过的:我们信赖上帝;所有其他人带来的数据。因此,让我们获取数据,进行一些分析,并对这一假设进行测试。**
正如你将在几分钟后看到的,我的分析得出结论,虽然关于这个有争议的话题确实有复杂的感情,但负面的情绪占主导地位。这是一种自然的反应:没有人愿意为他们曾经“免费”拥有的东西付费(许多纳税人认为这不是真正的免费)。这适用于任何形式的移动定价,尤其是在像美丽的温哥华这样的昂贵城市,以及我们目前支付的所有税收(包括汽油税)之外。也许这个一般观察的(唯一)例外是当人们看到引入新收费的价值时。不幸的是,真正的价值可能我们很多人都不清楚。****
在我们看结果之前,我想指出一个重要的注意事项。这种分析所感受到的表达出来的情绪可能不能用它们的真实程度来表示。只有通过精心设计的实验,从的代表性样本中收集数据,才能对感兴趣的量进行准确的估计。在这一分析中,来自用户在脸书官方帖子上互动的数据只被使用了*。诚然,这个样本不能被认为是一个代表性的样本,但尽管如此,它提供了一个镜头来回答这个有趣的问题。***
在接下来的两节中,我将解释数据是如何收集和分析的。分析在R
中完成,源代码可在 Github 上获得。
数据
数据收集自 2017 年 10 月下旬至 2018 年 3 月中旬委员会的官方脸书页面。这一时期涵盖了是时候了项目的整个公众参与阶段。**
我使用了Rfacebook
包——它提供了一个到脸书 API 的接口——来获取页面内容。数据分 3 步查询。首先我查询了帖子,然后是评论,最后是评论回复。帖子数据集包括发布的消息和类型(状态、照片、视频等。),喜欢的次数和反应(喜欢,难过,生气等。)、份额数量、时间戳和 ID。评论和评论回复数据集的结构几乎相同。两个数据集都包括发表的评论、赞数、时间戳和 ID。
分析
为了测量用户的印象,我们将从两个方面分析这些数据:一个是通过用户对每个帖子做出反应的显式情绪(对帖子的分析)。另一种是通过使用文本挖掘技术的情感分析(评论分析)。我将在下面的小节中详细讨论这两种方法。
一、职位分析
为了将事情放入 perceptive 并了解页面的活跃程度,让我们看看每月的帖子数量:
下图显示了每月的参与度。我不是社交媒体专家(甚至不是一个非常活跃的用户!),但是,我理解“参与度”一词在营销和广告领域可能有不同的含义。在这个分析中,我将参与度定义为“用户每月的总活动量”,包括喜欢、反应、评论和分享的数量。
理想情况下,敬业度计算为一个比率或加权平均值,其中不同类型的敬业度根据其重要性进行加权。例如,一个帖子的分享应该比一个评论或类似的东西更重要。然而,就我有限的知识而言,没有明确的方法来量化这一点。因此,我决定简单地将不同类型的约定放在一起。也就是说,可能有一些重复计算(同一个人可能喜欢、分享和评论同一篇帖子),这在下图中没有考虑到。由于我无法访问只有页面所有者或管理员才能访问的“洞察”数据(如帖子的总点击量或浏览量),因此限制重复计算和/或计算更有意义的比率是不可行的。
回到正题:看起来二月是参与度最高的月份。接下来,我们来看看帖子反应的分布情况:
特别感兴趣的,点赞数和愤怒情绪。总的来说,喜欢的情绪多于愤怒的情绪。以下是在参与阶段每个月的平均反应数,即喜欢和愤怒反应数的趋势:
在参与活动的早期阶段,没有太多的愤怒反应,然而,这一数字在 2 月份达到了最高水平。有意思!看起来二月份的帖子收到了最多的喜欢和愤怒情绪!
让我们看看最受欢迎的帖子是什么?
**We’re studying Distance-Based Charges: charging per kilometre driven within a given boundary, varying by time and location. We’re exploring ways this type of charge could work in Metro Vancouver to figure out whether this approach would reduce congestion, improve fairness, and support transportation investment in our growing region. We want to hear your thoughts when online engagement opens on February 26!**
收到最多愤怒反应的帖子是什么?
**We’re studying Distance-Based Charges: charging per kilometre driven within a given boundary, varying by time and location. We’re exploring ways this type of charge could work in Metro Vancouver to figure out whether this approach would reduce congestion, improve fairness, and support transportation investment in our growing region. We want to hear your thoughts when online engagement opens on February 26!**
不,这不是一个错误!同样的帖子获得了最高数量的喜欢和愤怒的反应。在不同的拥挤收费方法(警戒线收费、过路费等)中。),看起来“基于距离的收费”是页面上讨论的最有争议的方法。有道理,对吧?
在我们进入下一部分之前,让我们将反应分为积极(喜欢和爱)和消极(生气、悲伤、哈哈和哇)情绪。我把哈哈和哇的反应归类为负面情绪,因为在这种情况下,它们分别与讽刺和震惊联系在一起。
耶!
抓紧…我们不要太兴奋太快。评论中仍然隐藏着大量我们尚未看到的信息。下一节重点分析评论和评论回复。
二。评论分析
根据所选的分析单位,有许多可能的方法来分析文本数据。一种方法是将分析单位定义为单词。另一种方法是将其定义为文本块(一句或多句)。后一种方法更现实,但也更复杂。
在我们深入分析之前,值得注意的是,我将评论和评论回复合并在一个数据集中。我还删除了页面管理员的所有评论,以便分析只关注用户的评论。在文本挖掘分析中,去除“停用词”和数字是很典型的,我也是这样做的。
现在,让我们来看看评论中最常用的词语:
“拥堵”这个词没有进入前五名!“税”是使用最多的词,其次是“人”——嗯,“税务人”只是提醒一下,以防你想知道:“不”是一个停用词,从正在分析的词包中删除。
这里是评论中使用的漂亮的彩色单词云——颜色和大小表示每个组的排名:
接下来,我们将讨论从用户评论中挖掘情感的两种方法:作为单词和作为评论。
二世。a .情感分析—字数
在我们看了词频之后,现在让我们来看看这些词背后潜在的情感。这个过程通常被称为意见挖掘或情感分析。为了做到这一点,我们需要知道每个单词的相关情绪。幸运的是,有字典可以用来评估超过 27,000 个单词的相关意见或情绪。****
在这个分析中,我使用了三个通用词汇:AFINN
、bing
和nrc
——这三个都是tidytext
R
包的一部分。值得注意的是,这些词典是基于单字(即单个单词)。单字方法不考虑单词组合,如“不高兴”或“非常悲伤”。在某些文本中(如小说),这可能不是一个问题。然而,对于预期会出现否定和讽刺的情况,比如在社交媒体文本中,基于词汇的方法可能不会返回最准确的结果。尽管如此,它们仍然可以用来获得评论中情感内容的总体感觉。
让我们来看看基于三种词汇的结果是如何比较的:
Word Sentiments using nrc lexicon
Word Sentiments using bing lexicon
Word Sentiments using AFINN lexicon
看起来,bing
和AFINN
词汇的结果更加一致——负面情绪的词汇更多。另一方面,将nrc
词典中的不同情绪分为积极情绪和消极情绪(类似于我们之前对帖子反应所做的)会导致两组之间的单词份额几乎相等。鉴于我前面提到的这种方法的局限性,我不想在这些结果上多费口舌。相反,让我们看看如何将评论作为一个文本单元而不是一个词来进行情感分析。
二。b .情感分析—评论
在本节中,我们的目标是为每条评论分配一个情感分数,同时将评论视为一个文本单元,而不是单个单词。几年前,这不是一个简单的问题。然而,多亏了谷歌,这现在变得更加可行和容易实现。
谷歌云平台的最新更新提供了强大的机器学习 API,这些 API 运行在复杂的深度学习模型背后,这些模型是多年来利用谷歌源源不断的数据和巨大的计算能力开发的。这些工具和服务使用户更容易在指尖驾驭机器学习的力量。自然语言处理(NLP) API 也不例外。我使用了[googleLanguageR](https://cran.rstudio.com/web/packages/googleLanguageR)
包来访问 NLP API。为了能够访问这个 API,必须首先获得一个密钥。查看谷歌文档获取快速入门指南。建立一个软件开发帐户,除了 300 美元的注册积分之外,还提供每月一定限额(NLP API 为 5000)的免费访问。
NLP API 提供不同的服务。出于本文的目的,我将只关注情绪分析。分析的重点是识别给定文本中的主流情感观点。根据谷歌的文档,情感是由数值score
和magnitude
来表示的。score
的范围在-1 和 1 之间,表示总体情绪是消极的还是积极的。与score
不同的是,magnitude
没有规格化。然而,它是一个正整数,表示情绪的强度(消极或积极),通常与文本的长度相关(文本越长,magnitude
越高)。
为了验证 API 结果,我评估了一堆注释和它们的赋值
scores
。结果相当不错。正如人们所料,API 背后的模型并不完美,但我多次惊讶于其对潜在情绪的捕捉。请记住,社交媒体文本通常是低质量的文本,包括拼写错误、表情符号和缩略语。我还注意到,非常短的评论经常得到零或接近零的scores
。这可能表明,如果模型是不确定的,它会分配一个低的score
——这是需要记住的。
下面是用户评论的score
分布:
如你所见,负面评论比较多。然而,有很多零或接近零的评论score
。我们应该如何处理这些问题?
总的来说,score
和magnitude
指标可用于测量四种情绪水平,即:积极、消极、中性和混合情绪。例如,零或接近零的文本score
可能被解释为低情绪或混合情绪的文本。低情绪文本是一个中立的观点,而混合情绪文本是一个积极和消极情绪相互抵消的文本。谷歌建议用magnitude
来区分两者。具有低score
和低magnitude
的文本应归类为中性文本,而混合文本将具有低score
和高magnitude
。低和高的定义相当宽松;这在很大程度上取决于分析的背景。基于score
的分布,并通过检查个人评论,我发现,平均而言,score
在-0.2 和 0.2 之间的文本既不明显是负面的,也不明显是正面的。类似地,通过查看magnitude
低score
评论的分布(在-0.2 和 0.2 的范围内),0.5 似乎是定义低/高magnitude
的合理界限。
如果你还记得,根据明确的反应(例如,喜欢,愤怒的情绪),我们发现关于“基于距离的收费”的帖子是同时收到最多喜欢和愤怒情绪的帖子。你猜怎么着?结果发现,同一篇帖子收到的正面和负面评论最多(基于四个定义的情绪水平)。这是对情感分析结果的很好的验证。
我们来看看用户评论中情绪的四个层次的分布情况:
这并不奇怪。我们从score
分布中得知,负面评论会更多。但是,正如你所看到的,也有相对较高比例的低情绪评论被分为中性和混合情绪评论。
现在让我们考虑一下看待这个问题的另一种方式。如果你是脸书用户,你可能知道评论和评论回复也可以被用户喜欢。让我们考虑这个假设的例子,对于一个给定的帖子,有两条评论:一条负面评论获得 10 个赞,一条正面评论获得 15 个赞。如果我们忽略喜欢的数量,我们会得出结论,该帖子被感知的比例为 50/50。然而,与一个负面评论和 10 个喜欢(11 个负面印象)相比,得出帖子被正面看待的结论可能更现实,因为有一个正面评论和 15 个喜欢(16 个正面印象)。下图显示了基于他们收到的评论和相关赞数的分布情况。
这种方法是一种改进,但并不完美。同一个人可以任意多次评论一篇文章,也可以喜欢自己的评论。此外,更有可能的是,一个写了负面(或正面)评论的人也会喜欢同一帖子上的其他负面(或正面)评论。因为我们不知道对帖子(或评论)发表评论和/或喜欢评论(或评论回复)的用户的 id,所以我们在解释这些结果时必须小心——它们不代表用户的百分比。然而,有人可能会争辩说,这些影响可能会相互抵消,不应该对结果产生太大影响。不幸的是,我们没有更多的数据来确认。
最后,为了把事情放在一起,让我们把我们从用户对每个帖子的反应的显性情绪和我们从他们的评论中提取的隐性情绪结合起来。与我们之前所做的类似,我将喜欢和爱的反应的数量添加到正面评论及其相关喜欢的数量中,将愤怒、悲伤、哇和哈哈的反应的数量添加到负面评论及其相关喜欢的数量中。下面是情绪水平的总体分布:
哒哒!该图总结了分析。它结合了我们从帖子和评论分析中学到的见解。这也证实了我最初的假设——负面情绪占主导地位。好消息是,现在我们对情绪水平的分布有了更好的认识。中性和混合感觉占整体分布的 40%左右。与强烈反对的人相比,不确定引入移动定价的人可能更容易改变看法。这可以通过解决他们关心的问题并帮助他们理解问题的复杂性和欣赏提议的解决方案来实现。第一步是确定这些评论和相关的意见/关注点——这种类型的分析有助于实现这一点。
TL;博士;医生
在这篇文章中,我们使用文本挖掘技术来分析社交媒体源。特别是,从独立移动定价委员会的官方脸书网页收集数据。我们探索了几种分析公开可用数据的方法,并提出了一种了解用户情绪水平的方法。这是数据科学和机器学习如何从半非结构化数据中提供有价值的见解的一个例子。
交通拥堵和移动定价是影响每个人日常生活的争议话题。个人不太可能意识到向他们曾经免费拥有的东西收费的价值。这解释了为什么就需求管理这样一个复杂的概念教育公众不是一件容易的事情。我们发现,虽然用户表达了许多中性和混合的情绪,但负面情绪占主导地位。这样的反应是意料之中的。这一分析帮助我们理解了不同情绪水平的分布,这对制定公众参与策略非常有用。
谢谢你的来访!我希望你喜欢阅读这篇文章,我很想听到你的反馈。欢迎在评论中给我留言。
在这个帖子中表达的观点和看法完全是我的。用于进行分析的数据和信息都是公开的,不包含任何敏感和/或个人信息。代码可在这里获得,但是,数据集不符合 API 服务提供商的条款和条件。您可以通过按照代码中提供的步骤获取数据来重现结果。探索愉快!
我们如何在网上自动找到每天的好交易?
使用 R 进行基本的 web 内容抓取,以自动化枯燥的任务
背景
正如这里所定义的那样,“数据科学家比任何软件工程师都更擅长统计,比任何统计学家都更擅长软件工程。”因此,这篇博客文章重点关注 web 内容废弃的实践,这是数据科学家在结构化数据库之外获取信息的一项基本技能,当 API 不可用时。
当在网上寻找好的交易时,我们经常去一些电子商务网站查看我们想要的商品的价格。过了一段时间,这就变成了一项乏味的任务。受 程序员预订飞机指南 的启发,Zeke 在 Node 中编写了一个脚本来自动完成寻找廉价机票的过程,我们想在好的 MacBook 交易中复制他的方法,使用 r
目标
目的是当 MacBook 价格跌至某个点以下时,可以收到自动电子邮件提醒。
方法
- 从电子商务网站上删除产品信息
我们需要首先加载网站的 html 结构,以便检索我们需要的信息。我们将使用的 R 包是 rvest 。
library(rvest)
library(XML)#save html of URL
url <- "[http://www.rakuten.com.tw/category/4945/?p=1&l-id=tw_pagen_1](http://www.rakuten.com.tw/category/4945/?p=1&l-id=tw_pagen_1)"
保存 URL html 后,我们需要通过检查页面源代码来找到我们需要的信息部分。我们将搜索价格以导航到产品相关信息,如下所示。
Screenshot of the page source
我们注意到产品相关信息在
下,因此我们将只提取这一部分。
product <- url %>%
read_html() %>%
html_nodes(".b-content")
一个优秀的 Chrome 插件叫做 SelectorGadget 可以在这里下载。这个工具可以让我们直观地选择我们想要的具体内容。
当我们选择产品名称时,内容将以绿色突出显示,如下所示。该工具还猜测我们还需要其他产品名称,因此它会用黄色突出显示其他产品名称。对于我们不需要的任何内容,我们可以单击它,它将被删除(颜色将变为红色)。
我们发现可以使用提取产品名称。产品名称,如页面底部所示。
name <- product %>%
html_nodes(".product-name") %>%
html_text()
接下来,我们将重复这个过程来查找价格并以数字格式保存它。
price <- product %>%
html_nodes(".b-underline .b-text-prime") %>%
html_text() %>%
gsub(",","",.) %>%
as.numeric()
完成后,我们可以将名称和价格保存在一个数据帧中。
all <- data.frame(name, price,stringsAsFactors = FALSE)
我们还需要删除多个页面来提取所有信息。
for (i in 1:10){
starturl <- "[http://www.rakuten.com.tw/category/4945/?p=](http://www.rakuten.com.tw/category/4945/?p=)"
nexturl <- "&l-id=tw_pagen_"
url <- paste(starturl,i,nexturl,i,sep="")product <- url %>%
read_html() %>%
html_nodes(".b-content")name <- product %>%
html_nodes(".product-name") %>%
html_text()price <- product %>%
html_nodes(".b-underline .b-text-prime") %>%
html_text() %>%
gsub(",","",.) %>%
as.numeric()mydata <- data.frame(name, price,stringsAsFactors = FALSE)
all <- rbind(all,mydata)
}all<-all[!duplicated(all),]
最终结果以 dataframe 格式存储在下面。
Screenshot of the scrapped prices on MacBooks
2。创建发送电子邮件提醒的规则
接下来,我们将设置接收电子邮件提醒的规则。假设我们只希望收到价格在新台币 25,000 元到新台币 30,000 元之间的产品的警报。
alert <- all[all$price>25000&all$price<=30000,]
接下来,如果至少有一个警报,我们将使用 mailR 包发送电子邮件,如下所示。
if (nrow(alert) >=1){write.table(alert,"alert.txt",fileEncoding = "UTF-8")send.mail(from = "[jchen6912@gmail.com](mailto:jchen6912@gmail.com)",
to = c("[jchen6912@gmail.com](mailto:jchen6912@gmail.com)"),
subject = "Mac Deal Alert",
body <- "alert.txt",
smtp = list(host.name = "smtp.gmail.com", port = 465, user.name = "[jchen6912@gmail.com](mailto:jchen6912@gmail.com)", passwd = "xxxxxxxx", ssl = TRUE),
encoding = "utf-8",
authenticate = TRUE,
send = TRUE)
}
Screenshot of the automatic email alert received
3。通过定期安排任务来自动化流程
这可以通过 taskscheduleR 包来完成,但是目前只在 Windows 中可用。点击此处了解更多详情。我们可以安排 Rscript 以所需的频率运行,并相应地接收自动警报。
Screenshot of the UI in taskscheduleR
这总结了关于如何为静态内容的网站删除内容的简短博客,然而,动态网站更复杂,可能需要额外的代码来模拟真实的浏览行为,如会员登录和表单提交。或者,类似的任务也可以用 Python 中的 scrapy 和 BeautifulSoup 来执行。
r 代码
library(rvest)
library(XML)
library(taskscheduleR)
library(mailR)setwd("~/Desktop/deals")url <- "[http://www.rakuten.com.tw/category/4945/?p=1&l-id=tw_pagen_1](http://www.rakuten.com.tw/category/4945/?p=1&l-id=tw_pagen_1)"
product <- url %>%
read_html() %>%
html_nodes(".b-content")name <- product %>%
html_nodes(".product-name") %>%
html_text()price <- product %>%
html_nodes(".b-underline .b-text-prime") %>%
html_text() %>%
gsub(",","",.) %>%
as.numeric()all <- data.frame(name, price,stringsAsFactors = FALSE)for (i in 1:10){
starturl <- "[http://www.rakuten.com.tw/category/4945/?p=](http://www.rakuten.com.tw/category/4945/?p=)"
nexturl <- "&l-id=tw_pagen_"
url <- paste(starturl,i,nexturl,i,sep="")product <- url %>%
read_html() %>%
html_nodes(".b-content")name <- product %>%
html_nodes(".product-name") %>%
html_text()price <- product %>%
html_nodes(".b-underline .b-text-prime") %>%
html_text() %>%
gsub(",","",.) %>%
as.numeric()mydata <- data.frame(name, price,stringsAsFactors = FALSE)
all <- rbind(all,mydata)
}all<-all[!duplicated(all),]alert <- all[all$price>25000&all$price<=30000,]if (nrow(alert) >=1){write.table(alert,"alert.txt",fileEncoding = "UTF-8")send.mail(from = "[jchen6912@gmail.com](mailto:jchen6912@gmail.com)",
to = c("[jchen6912@gmail.com](mailto:jchen6912@gmail.com)"),
subject = "Mac Deal Alert",
body <- "alert.txt",
smtp = list(host.name = "smtp.gmail.com", port = 465, user.name = "[jchen6912@gmail.com](mailto:jchen6912@gmail.com)", passwd = "xxxxxxxx", ssl = TRUE),
encoding = "utf-8",
authenticate = TRUE,
send = TRUE)
}
问有什么问题、意见或顾虑吗?
jchen6912@gmail.com
我们如何教会一台机器自己编程?—整洁的学习。
在这篇文章中,我将尝试解释一种叫做通过扩充拓扑进化神经网络(NEAT)的机器学习方法。
简介:
我喜欢学习。打开一本书或一篇论文,谈论一个我还没有遇到的话题,并试图理解它,这真的很令人兴奋。有些人喜欢在空闲时间解决纵横字谜、数独或谜语来刺激他们的意识——我喜欢阅读论文并尝试实现所提出的算法。因为我喜欢学习,但遗憾的是,我无法学到我真正想学的所有东西,所以我对学习如何让计算机为我学习并向我提供有趣的信息特别感兴趣,这些信息可能会最大限度地提高我的学习效率。这些算法有助于构建复杂的信息,是“专家系统”领域的一部分。因此,我们的目标是“创造”一个“专家”,当你需要做决定的时候,你可以向他咨询。让我们从高层次上来看一个模型,它有助于创建那些被称为 NEAT 的“专家”。本文将介绍这个概念。在以后的文章中,我可能会分享实现示例。
什么是整洁?
Neat 代表“通过增强拓扑结构的神经网络”,并描述了自学习机器的算法概念,这些概念是由进化过程中的基因修改激发的。
生活本身绝对是迷人的。每当我观察自然时,我倾向于在所有生物中看到一个共同的特性,那就是信息。信息似乎是繁衍的核心传承。大自然能够优化过去 37 亿年传递的信息,创造了许多共存的不同物种。查尔斯·达尔文的适者生存的概念启发了我们对某些物种进化而其他物种灭绝的理解。进化计算机科学家的目标是通过模仿自然进化来构建寻求解决复杂问题的系统。
基因复制(或染色体复制或基因扩增)是产生新基因的主要机制
en.wikipedia.org](https://en.wikipedia.org/wiki/Gene_duplication)
描述 NEAT 如何工作的最简单的方法是通过一个例子。如果你必须设计一个专家系统,让它以最优的方式为你玩游戏,那么相关的因素是什么?
**首先,**定义“玩家”被允许执行的所有潜在动作是很重要的。例如,超级马里奥能够跳跃、蹲下、向左、向右行走、扭动身体、快速奔跑等等。如果我们将一台机器连接到这些变量,并允许它执行这些变量,它将有可能做一些事情。
**其次,**给电脑定义一个目标很重要。NEAT 的工作原理有一个概念,叫做“健身得分”。健康分数是一个奖励成功的数学函数。在像马里奥这样的游戏中,体能分数是玩家向终点线前进的程度。健身分数函数中可以包含更多的变量,如收集的硬币、击败的敌人或完成比赛的总时间。
**第三,**定义进化的规则很重要。NEAT 允许节点的突变,节点之间的新连接,以及最适合的神经网络遗传到新的后代中。此外,NEAT 确保不同种类的“物种”可以共存,直到它们被允许相互竞争产生新的更健康的后代。为了确保最适合的物种生存下来,已经尝试过的网络不会在未来重复自己,并且现有的网络会优化自己,NEAT 为每个基因添加了一个创新编号,作为历史标记。
上图显示了通过添加连接的变异和通过添加节点的变异。在图中的上例中,从 2 到 4 的连接被禁用,而从 3 到 5 的新连接被创建。在下面的节点突变示例中,可以看到从 2 到 4 的连接是如何被禁用的,以及新节点 6 是如何被引入的,以及它是如何生成从 3 到 6 和从 6 到 4 的两个新连接的。
上图显示了进化是如何发生的。Parent 1 和 Parent 2 在节点和连接上确实有相似的结构,但是它们也有区别。现在,机器使用二进制逻辑来包含节点/连接或删除它。基本的决定机制是基于真与真是真,真与假是假,假与假是假。以这种方式,后代确保继承的信息是关于适应度分数的有希望的有效性,同时在后代中考虑新的进化节点和/或连接,并且禁用的父节点保持禁用。匹配基因是随机遗传的,而分离基因(那些中间不匹配的基因)和多余基因(那些最终不匹配的基因)是从更适合的亲本遗传的。在这种情况下,假设适合度相等,因此不相交和多余的基因也是随机遗传的。被禁用的基因可能会在未来几代中再次启用:如果父母中的任何一方禁用了某个遗传基因,该基因就有可能被禁用。”[斯坦利,Miikkulainen,109 页,整洁]
现在一切都或多或少清楚了,NEAT 可以通过迭代和进化新的神经网络来完成游戏,以达到最佳的健身分数。我强烈推荐阅读这篇论文,它写得非常好,只需要一点谷歌搜索的努力,初学者就能理解。但是如果你想有一个快速速成班,你也可以在 youtube 上观看这个精彩的视频:
NEAT 通过将复杂的问题分成可以优化的更小的问题来解决复杂的问题。可以为许多不同的单独任务开发 NEAT 代理,然后联合起来解决更复杂的问题。一个例子可以是使用 NEAT 创建新的药房,首先布局所有可以使用的原子,其次定义一个适应度函数,使模拟理解奖励系统,最后定义进化规则。另一个 NEAT 可用于选择生产新设计的药物的制造技术。一旦这两个系统结合在一起,针对成本效率优化的新适应度函数可以为新设计的药房创建最佳生产方法。这在理论上听起来很棒,但显然是一项非常复杂的任务,需要花费大量精力进行研发。
这是论文:
我们如何“训练”神经网络?
一.导言
这是我计划的关于用于机器学习特别是神经网络“训练”的优化算法系列的第 1 部分。在这篇文章中,我将介绍梯度下降(GD)及其小变化。在未来,我计划写一些其他流行的算法,如:
我会在写完之后把链接放在上面。
今天我将从简单介绍神经网络开始,这足以理解我将要谈到的概念。我将解释什么是损失函数,以及它对“训练”神经网络或任何其他机器学习模型的意义。我并不声称我的解释是对神经网络的全面、深入的介绍,事实上,我希望你已经熟悉了这些概念。如果你想更好地理解神经网络中正在发生的事情,我在文章末尾提供了一个学习资源列表。
我会解释几年前在 kaggle 举行的狗和猫比赛的例子。在比赛中,我们面临的任务是识别一张图片上出现的是一只狗还是一只猫。
二。让我们定义一个神经网络
人工神经网络(ANN)的灵感来自于你大脑中实际发生的事情。虽然这些类比相当松散,但人工神经网络与它们的生物“父母”有几个相似之处。它们由一定数量的神经元组成。让我们来看看单个神经元。
Single Perceptron.
我们将考虑一个由弗兰克·罗森布拉特在 1957 年提出的最简单的神经元模型的一点修改版本,称为“感知器”。我做的所有修改都是为了简单,因为我不打算对神经网络进行深入解释。我只是想让你对正在发生的事情有一个直觉。
那么什么是神经元呢?这是一个数学函数。它接受几个数字作为输入(想要多少就有多少)。我上面画的神经元接受两个数字作为输入。我们将每个输入数字表示为 xₖ ,其中 k 代表输入的索引。对于每个输入 xₖ 神经元分配另一个数字 wₖ 。由这些数字 wₖ 组成的向量称为权重向量。这些权重使得每个神经元独一无二。它们在测试期间是固定的,但在训练期间,我们将改变这些数字,以便“调整”我们的网络。稍后我会在帖子中谈到这一点。如我上面所说,神经元是一种功能。但这是什么功能呢?它是权重和输入的线性组合,上面有某种非线性函数。让我进一步解释一下。我们来看第一部分——线性部分。
Linear combination of weight and inputs.
上面的公式就是我说的线性组合。我们将获取输入,将它们乘以相应的权重,然后将所有内容相加。结果是一个数字。最后一部分——是在其上应用某种非线性函数。今天使用的最流行的非线性实际上比称为整流线性单元( ReLU )的线性函数更简单。公式如下:
Rectified Linear Unit formula.
如果我们的数字大于零,那么我们就照原样取那个数字,如果它小于零,那么我们就取零。这种非线性函数应用于神经元中的顶部线性函数称为激活函数。我们必须有某种非线性函数的原因将在后面变得明显。总而言之,神经元是一种功能,它接受一些固定数量的输入,并输出一个单一的数字——它的激活。我们对于上面被淹没的神经元的最终公式是:
Neuron that takes two numbers as input.
稍微超前一点,如果我们以狗和猫为例,我们将把我们的图像作为输入传递给神经元。你可能会想,当我把神经元定义为函数时,我们怎么传递图像。你应该记得,我们在计算机中存储图像的方式是把它表示成一个数字阵列,每个数字表示一个给定像素的亮度。因此,将它传递给神经元的方法是采用 2D 阵列(或彩色图像的 3D 阵列),将其展平成一行以获得 1D 向量,并将所有这些数字传递给神经元。不幸的是,这使得我们的网络依赖于图像大小,我们只能处理网络定义的给定大小的图像。现代神经网络已经找到了解决这个问题的方法,但是现在我们将有这个限制。
是时候定义一个神经网络了。神经网络也是一个数学函数。它是由一堆相互连接的神经元定义的。当我说连接时,我的意思是一个神经元的输出被用作其他神经元的输入。让我们看看一个非常简单的神经网络,希望它能让我们更清楚。
Simple neural network.
上面定义网络有 5 个神经元。正如你所看到的,这些神经元堆叠在 3 个完全连接的层中,也就是说,一层中的每个神经元都连接到下一层中的每个神经元。一个网络有多少层,每层有多少个神经元以及它们是如何连接的——所有这些选择定义了网络的架构。第一层由两个神经元组成,称为输入层。这一层中神经元实际上不是我前面描述的神经元,从某种意义上说,它们不执行任何计算。它们只是用来表示网络的输入。对非线性的需求来自于我们将神经元连接在一起的事实,以及线性函数之上的线性函数本身就是线性函数的事实。所以,如果没有在每个神经元中应用非线性函数,神经网络将是线性函数,从而不会比单个神经元更强大。最后要注意的是,我们通常需要一个介于 0 和 1 之间的数字作为神经网络的输出,所以我们把它当作一个概率。例如,在狗和猫的对比中,我们可以把接近零的数字当作猫,把接近一的数字当作狗。为此,我们将对最后一个神经元应用不同的激活函数。我们将使用一个乙状结肠激活。关于这个函数,你只需要知道它返回一个从 0 到 1 的数字,这正是我们想要的。说了这么多,我们准备定义一个与我上面画的网络相对应的函数:
Function, defining out neural network. Superscript of w denoted to the index of the neuron. Subscript of w denotes the index of input.
因此,我们有某种函数,它接受一些数字,输出另一个介于 0 和 1 之间的数字。实际上,这个函数有什么公式并不重要,重要的是我们有复杂的非线性函数,它由一些权重参数化,在某种意义上,我们可以通过改变权重来改变函数。
三。损失函数
在我开始讨论训练之前,唯一需要定义的是一个损失函数。损失函数是一个告诉我们,我们的神经网络对于某项任务有多好的函数。直观的方法是,取每个训练示例,通过网络得到数字,从我们想要得到的实际数字中减去它,然后平方它(因为负数和正数一样糟糕)。
其中,y 代表我们希望从网络中获得的数字,y 代表我们通过网络传递示例实际获得的数字,I 代表训练示例的索引。让我们再次以狗对猫为例。我们有一个关于狗和猫的图片的数据集,如果是狗就标记为 1,如果是猫就标记为 0。这个标签对应于 y——当我们把图像传递给网络时,它是我们想从网络获得的数字。为了计算损失函数,我们将检查数据集中的每个训练示例,为该示例计算 y ,然后计算上面定义的函数。如果损失函数很大,那么我们的网络就不能很好地运行,我们希望损失函数越小越好。我们可以重写这个公式,将 y 改为我们网络的实际函数,以更深入地了解损失函数和神经网络的联系。
四。培养
当我们从神经网络开始时,我们随机初始化我们的权重。显然不会给你很好的结果。在训练的过程中,我们希望从性能差的神经网络开始,以高精度的网络结束。就损失函数而言,我们希望我们的损失函数在训练结束时更低。改进网络是可能的,因为我们可以通过调整权重来改变它的功能。我们希望找到另一个比最初的函数性能更好的函数。
训练的问题等价于最小化损失函数的问题。为什么要把损失最小化而不是最大化?原来损失是更容易优化的函数。
有很多优化函数的算法。这些算法可以基于梯度,也可以不基于梯度,因为它们不仅使用函数提供的信息,还使用函数的梯度。一种最简单的基于梯度的算法——我将在本文中讨论——被称为随机梯度下降。让我们看看它是如何工作的。
首先,我们需要记住什么是对某个变量的导数。让我们取一些简单的函数 f(x) = x 。如果我们还记得高中时的微积分规则,它的导数是 x 的每一个值,这告诉了我们什么?导数是当我们朝正方向迈出无限小的一步时,函数变化的速度。从数学上讲,它可以写成如下形式:
这意味着:我们的函数改变了多少(左边的项)大约等于这个函数对某个变量的导数 x 乘以我们改变了那个变量多少。当我们的步长无限小时,这个近似值是精确的,这是导数的一个非常重要的概念。回到我们的简单函数 *f(x) = x,*我们说过,我们的导数是 1,这意味着,如果在正方向上采取一些步骤ε,函数输出将改变 1 乘以我们的步骤ε,也就是ε。很容易检查出这是规则。这甚至不是一个近似值,这是准确的。为什么?因为我们的导数对于每个 x. 的值都是一样的,这对于大多数函数来说是不成立的。让我们来看一个稍微复杂一点的函数 f(x) = x .
y = x²
从微积分的规则中我们知道,函数的导数是 2x。很容易检查出,如果我们从某个值 x 开始,进行某个步长ε,那么我们的函数改变了多少,并不完全等于上面给出的公式。
现在,梯度是偏导数的向量,其元素包含关于函数依赖的变量的导数。对于我们到目前为止考虑的简单函数,这个向量只包含一个元素,因为我们只使用了一个输入的函数。对于更复杂的函数(如我们的损失函数),梯度将包含我们想要的每个变量的导数。
我们如何利用导数提供给我们的信息来最小化某个函数呢?让我们回到我们的函数 f(x) = x . 显然,那个函数的最小值在点 x = 0 ,但是计算机怎么会知道呢?假设,我们从某个随机值 x 开始,这个值是 2。 x = 2 中函数的导数等于 4。这意味着我们正向移动一步,我们的函数将成比例地变为 4。所以会增加。相反,我们想最小化我们的功能,所以我们可以向相反的方向迈出一步,负的,以确保我们的功能会减少,至少一点点。我们能走多远?这是个坏消息。我们的导数只能保证,如果迈出无限小的一步,函数就会减小。我们不能这么做。一般来说,你需要用某种超参数来控制你的步长。这个超参数被称为学习率,我稍后会谈到它。现在让我们看看如果我们从点 *x = -2 开始会发生什么。*导数现在等于-4,这意味着,如果向正方向迈出一小步,我们的函数将成比例地变为-4,因此它将减小。这正是我们想要的。
注意到这里的一个模式了吗?当 x > 0 时,我们的导数大于零,我们需要往负方向走,当 x < 0 时,导数小于零,我们需要往正方向走。我们总是需要向导数的反方向前进一步。让我们把同样的想法应用于梯度。梯度是指向空间某个方向的向量。它实际上指向函数增长最快的方向。因为我们想最小化我们的函数,我们将向梯度的相反方向迈出一步。让我们应用我们的想法。在神经网络中,我们认为输入 *x、*和输出 y 是固定的数字。我们要对其求导的变量是权重 w,,因为这些是我们想要改变的值,以改善我们的网络。如果我们计算损失函数相对于我们的权重的梯度,并且在梯度的相反方向上采取小的步骤,我们的损失将逐渐减少,直到它收敛到某个局部最小值。这种算法被称为梯度下降。在梯度下降的每次迭代中更新权重的规则如下:
For each weight subtract the derivative with respect to it, multiplied by learning rate.
上面符号中的 lr 表示学习速率。它是用来控制我们在每次迭代中走多远。这是训练神经网络时需要调整的最重要的超参数。如果你选择学习太大的东西,那么你会迈出太大的步伐,并且会“跳过”最小值。这意味着你的算法会有分歧。如果你选择的学习率太小,可能会花太多时间收敛到局部极小值。人们已经开发了一些非常好的技术来寻找最佳的学习速度,但是这已经超出了这篇文章的范围。其中一些在我的另一篇文章“提高我们工作的方式和学习率”中有所描述。
不幸的是,我们不能真正应用这种算法来训练神经网络,原因在于我们的损失函数公式。
从我们上面的定义可以看出,我们的公式是总和的平均值。从微积分我们知道,和导数就是导数的和。因此,为了计算损失的导数,我们需要检查数据集的每个例子。在梯度下降的每一次迭代中都这样做是非常低效的,因为算法的每一次迭代都只是通过一些小的步骤来改善我们的损失。为了解决这个问题,有另一种算法,称为小批量梯度下降。更新权重的规则保持不变,但我们不会计算精确的导数。相反,我们将对数据集的某个小批量进行导数近似,并使用该导数来更新权重。小批量不能保证在最佳方向采取措施。其实通常不会。对于梯度下降法,如果选择足够小的学习率,每次迭代的损失一定会减少。对于小批量来说,这不是真的。你的损失会随着时间的推移而减少,但它会波动,并且更加“嘈杂”。
用于估计导数的批量大小是你必须选择的另一个超参数。通常,您想要尽可能大的批量,因为您的内存可以处理。但是我很少看到有人使用大于 100 的批量。
批量等于 1 的小批量梯度下降的极端版本称为随机梯度下降。在现代文献中,当人们说随机梯度下降(SGD)时,他们实际上指的是小批量梯度下降。大多数深度学习框架会让你选择 SGD 的批量大小。
这就是梯度下降及其变化。最近,越来越多的人开始使用更先进的算法。大部分是基于梯度的,实际上是基于 SGD 稍加修改。我也打算写这些。
七。反向传播
关于基于梯度的算法,唯一要说的是我们如何计算梯度。最快速的计算方法是解析地找到每个神经网络结构的导数。我想,就神经网络而言,我不应该说这是一个疯狂的想法。我们上面为一个非常简单的神经网络定义的公式很难找到所有的导数,而且我们只有 6 个参数。现代建筑有数百万个。
第二种方法,实际上也是最容易实现的方法,是用微积分中的公式来近似求导:
虽然它非常容易实现,但这样做的计算代价太大。
计算导数的最后一种方法叫做反向传播,这种方法很好地平衡了计算难度和计算代价。讨论这个算法超出了这篇文章的范围,但是如果你想了解更多,可以去这篇文章的最后一部分,在那里我列出了学习神经网络的资源。
不及物动词为什么会起作用?
当我第一次了解神经网络及其工作原理时,我理解所有的方程,但我不太确定它们为什么工作。这个想法,我们可以采取一些功能,然后采取一些导数,并最终与算法,可以区分狗和猫的图像似乎有点超现实主义对我来说。为什么我不能给你一个真正好的直觉,为什么神经网络工作得这么好,有一些方面你应该注意。
- 我们用神经网络解决的任何问题都必须用某种数学方式来表达。对于狗和猫是这样的:我们需要找到一个函数,它从一幅图像中提取所有的数字,并输出它是一只狗的概率。你可以这样定义任何分类问题。
- 可能还不清楚,为什么有这样一个函数可以在给定的图像上区分狗和猫。这里的想法是,只要你有一些带有输入和标签的数据集,总会有一个函数在给定的数据集上工作得很好。问题是这个函数将会非常复杂。神经网络来帮忙了。有一个“通用逼近定理”,它说只有一个隐藏层的神经网络可以尽可能好地逼近任何函数。现在,还不清楚为什么,即使我们找到了这个函数的近似值,它也会在新的数据集上工作得一样好,神经网络在训练中没有看到这个数据集。这被称为泛化问题,是一个开放的研究问题。研究表明,SGD 具有“自我概括”效应。但是我们仍然没有真正理解这个问题。
七。从哪里了解更多信息
在学习神经网络时,我发现了一些非常有用的资源:
- fast.ai 课程提供了两门优秀的程序员实用深度学习课程,以及一门精彩的计算线性代数课程。这是尽快开始编写神经网络代码的好地方,同时随着课程的深入,学习更多的神经网络理论。
- neuralnetworksanddeeplearning.com 的书是一本很棒的关于基础的在线书籍。神经网络背后的理论。作者用一种非常好的方式解释了你需要知道的数学。他还提供并解释了在不使用任何深度学习框架的情况下从头实现神经网络的代码。
- 吴恩达关于深度学习的课程coursera 上的课程也很棒,可以学习更多关于神经网络的知识,从非常简单的网络开始,到卷积网络等等!
- 3Blue1Brown youtube 频道有一些很棒的视频可以帮助你理解深度学习和线性代数。它们提供了很好的可视化和非常直观的方式来思考数学和神经网络。
- 关于视觉识别的卷积神经网络的 Stanford CS231n 课程是了解更多深度学习特别是 CNN 的好地方。
怎么把物理教给机器学习模型?
混合分析:结合两个世界的精华
在我的其他帖子中,我已经涉及了一些主题,如:用于异常检测和状态监控的机器学习、机器学习如何用于生产优化,以及如何避免机器学习用于时间序列预测的常见陷阱。
但你知道吗,你也可以结合机器学习和基于物理的建模?在这里,我将描述它是如何实现的,以及我们如何向机器学习模型“教授物理”。
机器学习与基于物理的建模
作为一名物理学家,我喜欢制作数学模型来描述我们周围的世界。有了关于当前情况的足够信息,一个制作精良的基于物理学的模型使我们能够理解复杂的过程并预测未来的事件。这种模型已经在我们的现代社会中广泛应用于非常不同的过程,例如预测大型太空火箭的轨道或纳米大小物体的行为,这些都是现代电子学的核心。
做出预测的能力也是机器学习(ML)的重要应用之一。一个常见的关键问题是如何在基于物理的模型和数据驱动的 ML 模型之间进行选择。答案取决于你想解决什么问题。在这种情况下,主要有两类问题:
1)我们没有关于该系统的直接理论知识,但是我们有关于它如何表现的大量实验数据。
例如,如果你对一个系统的行为没有直接的了解,你就不能用数学模型来描述它并做出准确的预测。
幸运的是,并没有失去一切。如果你有很多示例结果,你可以使用基于 ML 的模型。给定足够多的示例结果(训练数据),ML 模型应该能够学习关于系统的信息(输入变量)和您想要预测的结果(输出变量)之间的任何潜在模式。
这方面的一个例子是预测一个城市的房价。如果你有足够的同一地区类似房屋销售价格的例子,你应该能够对待售房屋的价格做出合理的预测。
2)我们对系统有很好的理解,并且我们也能够用数学方法描述它。
如果一个问题可以用基于物理的模型很好地描述,这种方法通常会是一个好的解决方案。
这并不意味着机器学习对于任何可以使用基于物理的建模来描述的问题都是无用的。相反,在混合建模方案中结合物理和机器学习是一个非常令人兴奋的前景。如此激动人心,事实上,它正在被深入研究。与我的工作相关,我最近一直在深入研究机器学习和基于物理的建模之间的交集。
混合分析:结合机器学习和基于物理的建模
即使一个系统,至少在原则上,可以用基于物理的模型来描述,这并不意味着机器学习方法不起作用。ML 模型从经验中学习的能力意味着它们也可以学习物理:给定足够多的物理系统如何表现的例子,ML 模型可以学习这种行为并做出准确的预测。
这种通过经验而不是通过数学方程来学习物理的能力对我们很多人来说都很熟悉,尽管我们可能没有意识到这一点:例如,如果你曾经踢足球,你可能会试图做出完美的射门。为了做到这一点,你必须准确预测球的路径。这是一个有点复杂的物理问题,包括几个变量,比如你踢球的力,你的脚的角度,球的重量,空气阻力,草地的摩擦力,等等。
然而,当一名足球运动员踢球时,这并不是他在几分之一秒内完成的复杂物理计算的结果。相反,他从经验中学到了正确的动作,并获得了完美击球的直觉。
( 插画作者:越轨艺术 )
原则上,ML 模型(或算法)从经验中学习的事实类似于人类学习的方式。一类称为人工神经网络的 ML 模型是受大脑如何处理信息和从经验中学习启发的计算系统。
这种从经验中学习的能力也启发了我和我的同事尝试向 ML 模型教授物理学:我们通过向模型展示输入变量和正确解的例子来训练模型,而不是使用数学方程。
当我们已经有基于物理的模型时,为什么还要使用机器学习?
一个重要的问题是,当我们有一个基于物理的模型能够描述正在讨论的系统时,我们为什么要实施基于 ML 的方法。
其中一个关键方面是模型的计算成本:我们可能能够使用基于物理的模型来详细描述系统。但是,解决这个模型可能是复杂和耗时的。因此,如果我们的目标是一个可以根据实时数据进行实时预测的模型,基于物理学的方法可能会失败。
在这种情况下,更简单的基于 ML 的模型可能是一种选择。ML 模型的计算复杂度主要在训练阶段可见。一旦模型完成训练,对新数据进行预测就很简单了。这就是结合机器学习和基于物理的建模的混合方法变得非常有趣的地方。
通过混合建模方案的虚拟流量计量
例如,我们已经考虑将这种方法用于油井虚拟流量计量的特定任务,如下图所示。几个传感器可以提供油井井下 P_dh、T_dh 以及油井节流器上游 P_uc、T_uc 和下游 P_dc、T_dc 的温度和压力测量值。我们想要解决的问题是油、气和水的流量如何依赖于这些测量值:即描述多相流率的函数:
Q_o,Q_g,Q_w = F(P_dh,P_uc,P_dc,T_dh,T_uc,T_dc,Pos_Choke)
这是一个复杂的建模任务,但使用最先进的模拟器工具,我们可以做到这一点,具有高度的准确性。
该模型捕捉了来自生产井的油、气和水的多相流的热力学和流体动力学。利用这一点,我们可以为 ML 模型生成大量模拟训练数据,并将它们与来自物理井的真实数据相结合。
这种方法的优点是,我们可以离线执行所有计算要求高的部分,快速实时预测不是问题。通过从基于物理的模型生成大量训练数据,我们可以向 ML 模型传授问题的物理原理。
经过训练的 ML 模型可以仅使用来自物理井的传感器测量值,即压力和温度,来同时预测油、气和水的流量。更重要的是,它可以在几分之一秒内做出这些预测,使其成为运行生产井实时数据的理想应用。
这种方法允许我们为生产设施上的所有油井实施虚拟多相流量计。毫无疑问,它将成为监控和生产优化的一个非常有价值的工具。
你认为还有哪些领域会受益于机器学习?
在未来,我相信机器学习将会被用在比我们今天所能想象的更多的地方。你认为它会对各个行业产生什么影响?我很想在下面的评论中听到你的想法。
如果你有兴趣了解更多与人工智能/机器学习和数据科学相关的主题,你也可以看看我写的其他一些文章。你可以在我的中型作者简介中找到它们,你可以在这里找到。
而且,如果你想成为一个媒体会员,免费访问平台上的所有资料,你也可以使用下面我的推荐链接。(注意:如果您使用此链接注册,我也会收到一部分会员费)
[## 通过我的推荐链接加入媒体- Vegard Flovik
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@vflovik/membership)
更多来自 Vegard Flovik 媒体:
- 蒙特卡洛方法简介
- 从物理学到数据科学的转变
- 什么是图论,你为什么要关心它?
- 用于图像分类的深度迁移学习
- 构建一个能读懂你思想的人工智能
- 机器学习:从炒作到现实应用
- 人工智能和大数据隐藏的风险
- 用于供应链管理的人工智能:预测分析和需求预测
- 如何(不)使用机器学习进行时间序列预测:避免陷阱
- 如何使用机器学习进行异常检测和状态监控
- 如何利用机器学习进行生产优化:利用数据提高绩效
- 我们能使用纳米级磁铁建立人工大脑网络吗?
人工智能研讨会——从宣传到现实应用
如何训练一个人脸检测模型?
由于我最近一直在探索 MTCNN 模式(在这里了解更多信息)所以我决定试着训练它。即使只是从概念上考虑,训练 MTCNN 模型也是一个挑战。这是一个级联卷积网络,这意味着它由 3 个独立的神经网络组成,不能一起训练。我决定从训练第一网络 P-Net 开始。
P-Net 是传统的 12-Net:它以 12x12 像素的图像作为输入,并输出一个矩阵结果,告诉您是否存在人脸——如果存在,则显示每个人脸的边界框和面部标志的坐标。因此,我必须从创建一个仅由 12x12 像素图像组成的数据集开始。
开发这个模型的团队使用宽脸数据集来训练边界框坐标,使用 CelebA 数据集来训练面部标志。为了简单起见,我从只训练边界框坐标开始。
宽脸数据集包括具有不同情况下的人的 393,703 张脸的 32,203 张图像。这些图像被分成训练集、验证集和测试集。在训练集下,图像根据场合进行了划分:
Image 1: Folders of different images
每个文件夹里都有数百张照片,有成千上万张面孔:
Image 2: Inside a folder
然而,所有这些照片都明显大于 12x12 像素。我不得不将它们裁剪成多个 12x12 的正方形,其中一些包含人脸,一些不包含。
我考虑简单地创建一个 12x12 的内核,它在每张图片上移动,并且每移动 2 个像素复制其中的图片。然而,这将给我留下数百万张照片,其中大多数不包含人脸。为了确保更好的训练过程,我希望大约 50%的训练照片包含人脸。此外,面可以具有不同的尺寸。我需要不同大小的脸的图像。
这是我决定要做的:首先,我将加载照片,去掉任何有一张以上脸的照片,因为这些照片只会使裁剪过程更加复杂。
然后,我将为每张照片创建 4 个不同比例的副本,这样我就有一个副本,照片中的人脸高 12 像素,一个高 11 像素,一个高 10 像素,一个高 9 像素。
小于 9x9 像素的人脸太小,无法识别。为了说明我的观点,这里有一张年轻的贾斯汀比伯的 9x9 像素的脸:
Image 3: 9x9 Justin Bieber // Source
对于每个缩放后的副本,我会尽可能多地裁剪 12x12 像素的图像。例如,在这张 12x11 像素的贾斯汀比伯图像中,我可以裁剪两张包含他的脸的图像。
使用更小的比例,我可以裁剪更多的 12x12 的图像。对于每张裁剪后的图像,我需要将边界框坐标转换为 0 到 1 之间的值,其中图像的左上角是(0,0),右下角是(1,1)。这使得处理计算以及将图像和边界框缩放回原始大小变得更加容易。
Image 4: Converting bounding box coordinates // Source
最后,我将边界框坐标保存到一个. txt 文件中。我运行了几次,发现每张脸产生了大约 60 个裁剪过的图像。我需要做的就是再创建 60 张没有人脸的裁剪过的图片。
生成负面(无脸)图像比生成正面(有脸)图像更容易。类似地,我创建了每张图片的多个缩放副本,正面分别为 12、11、10 和 9 像素高,然后我随机绘制了 12×12 像素的方框。如果那个盒子碰巧落在边界框内,我就画另一个。如果该框没有与边界框重叠,我就裁剪了图像的这一部分。
最后,我生成了大约 5000 张正面图像和 5000 张负面图像。这足以做一个非常简单的短期训练。
训练变得简单多了。使用原始文件中的代码,我构建了 P-Net。然后,我读入正负图像,以及边界框坐标集,每个都作为一个数组。我给了每个负像的边界框坐标[0,0,0,0]。
然后,我用一个索引将这些图像混在一起:因为我首先加载的是正图像,所以所有的正图像都在数组的开头。如果我不洗牌的话,前几批训练数据都是正像。
最后,我定义了一个交叉熵损失函数:每个包围盒坐标和概率的误差平方。
我跑了一圈训练。大约 30 个时期后,我达到了大约 80%的准确率……考虑到我的数据集中只有 10000 张图片,这已经不错了。
保存我的权重后,我将它们加载回完整的 MTCNN 文件,并用我新训练的 P-Net 进行了测试。就像以前一样,它仍然可以准确地识别人脸,并在人脸周围画出边框。MTCNN 模型的一个巨大优势是,即使 P-Net 精度下降,R-Net 和 O-Net 仍然可以设法细化边界框边缘。
我没有再次经历为 RNet 和 ONet 处理数据的繁琐过程,而是在 Github 上找到了这个 MTCNN 模型,其中包括该模型的培训文件。该模型类似地仅用宽脸数据集训练边界框坐标(而不是面部标志)。
Image 5: Intersection over Union
正如我所做的那样,这个模型在训练过程之前裁剪了每个图像(P-Net 为 12×12 像素,R-Net 为 24×24 像素,O-Net 为 48×48 像素)。与我的简单算法不同,这个团队根据 IoU (交集超过并集,即 12x12 图像和边界框之间的相交面积除以 12x12 图像和边界框的总面积)将图像分类为正面或负面,并包括一个单独的“部分”面类别。
创建单独的“部分面部”类别允许网络学习部分覆盖的面部。这样,即使你戴着墨镜,或者把半边脸转开,网络仍然可以识别你的脸。
此外,对于 R-Net 和 O-Net 培训,他们利用了硬样本挖掘。即使经过训练,P-Net 也不是完美的;它仍然会将一些没有人脸的图像识别为正面(有人脸)图像。这些图像被称为假阳性。由于 R-Net 的工作是细化包围盒边缘,减少误报,因此在训练 P-Net 之后,我们可以将 P-Net 的误报包含在 R-Net 的训练数据中。这样可以帮助 R-Net 针对 P-Net 的弱点,提高准确率。这个过程被称为硬样品开采。类似地,他们也在 O-Net 训练中应用硬样本挖掘。
这个模型的另一个有趣的方面是他们的损失函数。他们没有为人脸检测和边界框坐标定义一个损失函数,而是分别定义了一个损失函数。在训练过程中,他们在每个反向传播步骤中在两个损失函数之间来回切换。我以前从未见过这样定义的损失函数——我一直认为定义一个包罗万象的损失函数会更简单。不知道这样来回切换是否提高了训练精度?
训练这个模型花了 3 天时间。大型数据集使得训练和生成硬样本成为一个缓慢的过程。另外,我第一次训练的时候 GPU 就用完了内存,迫使我重新训练 R-Net 和 O-Net(又花了一天)。
我以前没有研究过这个,但是分配 GPU 内存是训练过程的另一个重要部分。在每个培训计划结束时,他们会记录他们想要使用多少 GPU 内存,以及他们是否允许增长。如果是,如果需要的话,程序可以请求更多的内存。如果没有,程序将在程序开始时分配内存,并且在整个训练过程中不会使用超过指定的内存。这使得进程更慢,但降低了 GPU 耗尽内存的风险。
点击此处下载 MTCNN 论文和资源:
- 受训模特 Github 下载:【https://github.com/ipazc/mtcnn
- 可训练模型 Github 下载:https://github.com/wangbm/MTCNN-Tensorflow
- 调研文章:http://arxiv.org/abs/1604.02878
- 我的 PNet 培训代码:https://github.com/reinaw1012/pnet-training
Docker 如何帮助您成为更高效的数据科学家
作者:哈默尔·侯赛因
在过去的 5 年里,我听到了很多关于码头集装箱的传言。似乎我所有的软件工程朋友都在用它们开发应用程序。我想弄清楚这项技术如何能让我更有效,但我发现在线教程要么太详细:阐述我作为数据科学家永远不会使用的功能,要么太肤浅:没有给我足够的信息来帮助我了解如何快速有效地使用 Docker。
我写了这个快速入门,所以你不必解析所有的信息,而是可以学习你需要知道的东西来快速入门
编辑 2020 年 8 月 24 日 : 本文写于 2017 年。大部分仍然是正确的,我已经注释了事情发生变化的几个地方。我仍然鼓励你阅读这篇文章。当你完成后,你可能也会喜欢我最近在 Docker 上做的这些 详细笔记。
Docker 是什么?
您可以将 Docker 视为轻量级虚拟机,其中包含运行应用程序所需的一切。docker 容器可以捕获系统状态的快照,以便其他人可以快速重建您的计算环境。对于本教程,这就是你需要知道的全部,但是更多细节你可以点击这里。
为什么要用 docker?
- 可再现性:作为一名专业的数据科学家,你的工作具有可再现性真的很重要。再现性不仅有助于同行评审,还能确保您构建的模型、应用程序或分析能够顺利运行,从而使您的交付成果更加健壮,经得起时间的考验。例如,如果您在 python 中构建了一个模型,仅仅运行 pip-freeze 并将结果 requirements.txt 文件发送给您的同事通常是不够的,因为这只会封装 python 特定的依赖关系,而通常存在于 python 之外的依赖关系,如操作系统、编译器、驱动程序、配置文件或代码成功运行所需的其他数据。即使您可以只共享 python 依赖项,但是将所有内容包装在 Docker 容器中可以减轻其他人重新创建您的环境的负担,并使您的工作更容易访问。
- 计算环境的可移植性:作为一名数据科学家,尤其是在机器学习领域,能够快速改变计算环境会极大地影响你的工作效率。数据科学工作通常从原型制作、探索和研究开始,这些工作不一定马上需要专门的计算资源。这项工作通常在笔记本电脑或个人电脑上进行。然而,经常会出现不同的计算资源会大大加快您的工作流程的情况,例如,一台具有更多 CPU 的机器或一个用于深度学习等事情的更强大的 GPU。我看到许多数据科学家将自己限制在本地计算环境中,因为他们认为在远程机器上重新创建本地环境会有摩擦。Docker 负责移植您的环境(所有的库、文件等)。)非常容易。快速移植您的计算环境也是 Kaggle 竞争中的一个巨大竞争优势,因为您可以以经济高效的方式利用 AWS 上的宝贵计算资源。最后,创建 docker 文件允许您移植许多您喜欢的本地环境的东西——比如 bash 别名或 vim 插件。
- 增强您的工程能力:熟悉 Docker 可以让您将模型或分析部署为应用程序(例如,作为可以提供预测服务的 REST API 端点),让其他人可以访问您的工作。此外,作为数据科学工作流的一部分,您可能需要与之交互的其他应用程序可能存在于 Docker 容器中,如数据库或其他应用程序。
码头术语
在我们开始之前,熟悉 Docker 术语很有帮助:
- 图像:是你想要构建的蓝图。例如:Ubuntu + TensorFlow,带有 Nvidia 驱动程序和运行的 Jupyter 服务器。
- 容器:是你赋予生命的图像的实例。您可以运行同一映像的多个副本。掌握图像和容器之间的区别非常重要,因为这对新来者来说是一个常见的混淆来源。如果图像和容器之间的区别不清楚,停下来再读一遍。
- Dockerfile :创建图像的方法。Docker 文件包含特殊的 Docker 语法。从官方文档来看:
Dockerfile
是一个文本文档,它包含用户可以在命令行上调用的所有命令来组合一个图像。 - 提交:和 git 一样,Docker 容器提供版本控制。通过提交更改,您可以随时将 docker 容器的状态保存为新的图像。
- DockerHub / Image Registry :人们可以发布公共(或私人)docker 图片以促进协作和共享的地方。
- 层:对已有图像的修改,由 docker 文件中的指令表示。图层按顺序应用于基础图像,以创建最终图像。
我将在这篇文章的其余部分使用这个术语,所以如果你迷路了,请参考这个列表!这些术语很容易混淆,尤其是图像和容器之间——所以在阅读时要保持警惕!
安装 Docker
你可以免费下载并安装 Docker 社区版。你可以在这里按照的指示。
创建您的第一个 Docker 图像
在创建 docker 容器之前,创建一个定义图像的 docker 文件是很有用的。让我们慢慢浏览下面的文档。你可以在本教程 附带的 Github repo 上找到这个文件 。
语句中的
FROM ubuntu:16.04
来自语句的封装了 Docker 最神奇的部分。该语句指定了要在其上构建的基础映像。在用 FROM 指定一个基本映像后, Docker 将在您的本地环境中查找一个名为 ubuntu:16.04 的映像,如果在本地找不到,它将搜索您指定的 Docker 注册表,默认为 DockerHub 。这种分层机制很方便,因为你经常想在 Ubuntu 这样的操作系统上安装你的程序。不用担心如何从头开始安装 Ubuntu,你可以简单地在官方的 Ubuntu 映像上构建!Dockerhub 上托管着各种各样的 Docker 映像,包括那些不仅仅提供操作系统的映像,例如,如果您想要一个已经安装了 Anaconda 的容器,您可以在官方的 anaconda docker 映像之上构建一个容器。最重要的是,您还可以随时发布您构建的图像,即使该图像是通过在另一个图像上分层而创建的!可能性是无限的。****
在这个例子中,我们指定我们的基本映像是 ubuntu:16.04 ,它将寻找一个名为 ubuntu 的 DockerHub repo。冒号-16.04 后面的镜像名称部分是标签,它允许您指定想要安装的基本镜像版本。如果你导航到 Ubuntu DockerHub repo ,你会注意到不同版本的 Ubuntu 对应不同的标签:
Screenshot of the official Ubuntu DockerHub repo as of December 2017.
比如在本文撰写之时, ubuntu:16.04 、 ubuntu:xenial-20171201 、 ubuntu:xenial 、 ubuntu:latest 都是指 Ubuntu 16.04 版本,都是同一个镜像的别名。此外,该存储库中提供的链接将您链接到用于构建每个版本的映像的相应 docker 文件。你不会总是在 DockerHub 库上找到 DockerHub 文件,因为维护者可以选择包含他们如何制作映像的 DockerHub 文件。我个人发现看几个这样的 Dockerfiles 对更好地理解 Dockerfiles 很有用(但是等你看完这个教程再说吧!)
有一个标签值得特别一提,那就是:最新的标签。如果您没有在您的 FROM 语句中指定一个标签,这个标签指定了您将默认拉取的内容。例如,如果您的 FROM 语句如下所示:
FROM ubuntu
那么你最终只会得到 ubuntu:16.04 的图像。为什么?—如果仔细看上面的截图,您会看到:latest 标签与 16.04 相关联
关于 Docker 图片的最后一点:当从 DockerHub 中提取随机的 Docker 图片时,运用明智的判断。恶意行为者创建的 Docker 图像可能包含恶意软件。
标签声明
该语句向图像添加元数据,并且是完全可选的。我添加这个是为了让其他人知道应该联系谁来处理这个映像,也是为了让我可以搜索我的 docker 容器,特别是当服务器上有很多容器同时运行的时候。
LABEL maintainer="Hamel Husain <youremail>"
ENV 语句
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
这允许您更改环境变量,而且非常简单。你可以在这里阅读更多关于这个的内容。
运行语句
这通常是完成你想要建立一个 Docker 形象的主要手段。您可以运行任意 shell 命令,如 apt-get 和 pip install 来安装您想要的包和依赖项。
RUN apt-get update --fix-missing && apt-get install -y wget bzip2
build-essential \
ca-certificates \
git-core \
...
在本例中,我安装了一些我喜欢的实用程序,比如 curl、htop、byobu,然后安装了 anaconda,接着安装了基本 anaconda 安装中没有的其他库(向上滚动到完整的 other 文件以查看所有的 RUN 语句)。
在 RUN 语句之后的命令与 Docker 无关,而是普通的 linux 命令,如果您自己安装这些包,您将会运行这些命令,所以如果您不熟悉这些包或 linux 命令,也不用担心。另外,作为进一步的建议——当我第一次开始学习 docker 时,我查看了 Github 或 DockerHub 上的其他 docker 文件,并将我想要的相关部分复制并粘贴到我的 docker 文件中。
您可能会注意到 RUN 语句的格式。为了可读性,每个库或包都整齐地缩进并按字母顺序排列。这是 Dockerfiles 的一个普遍惯例,所以我建议你采用它,因为它会简化协作。
EXPOSE 语句
如果您试图公开一个端口——例如,如果您从容器内部为一个 jupyter 笔记本或某种 web 服务提供服务,这个语句会很有帮助。Docker 的文档很好地解释了 EXPOSE 语句:
EXPOSE
指令实际上并不发布端口。它在构建映像的人和运行容器的人之间起到一种文档的作用,说明打算发布哪些端口。要在运行容器时实际发布端口,使用docker run
上的-p
标志发布并映射一个或多个端口,或者使用-P
标志发布所有公开的端口并将它们映射到高阶端口。
卷报表
VOLUME /ds
这个语句允许你在 docker 容器和主机之间共享数据。VOLUME 语句允许您挂载外部挂载的卷。主机目录仅在容器运行时声明(因为您可能在不同的计算机上运行该容器),而不是在定义映像时。现在,您只需在 docker 容器中指定想要与主机容器共享的文件夹的名称。*
来自 docker 用户指南:
*** 主机目录是在容器运行时声明的:主机目录(挂载点)本质上是依赖于主机的。这是为了保持图像的可移植性。因为不能保证给定的主机目录在所有主机上都可用。因此,您不能从 docker 文件中挂载主机目录。
*VOLUME*
指令不支持指定*host-dir*
参数。创建或运行容器时,必须指定挂载点。**
此外,这些卷意味着在容器的文件系统之外持久存储数据,如果您正在处理大量数据,并且不希望 docker 映像膨胀,这通常是有用的。保存 docker 映像时,此卷目录中的任何数据都不会保存为映像的一部分,但是容器中此目录之外的数据将被保存。
WORKDIR 语句
WORKDIR /ds
该语句设置工作目录,以防您想要在另一个命令中引用没有绝对路径的特定文件。例如,docker 文件中的最后一条语句是
CMD [“./run_jupyter.sh”]
假设工作目录是/ds
ADD 语句
编辑 2020 年 8 月 24 日:您现在应该使用 COPY 语句而不是 ADD 语句。在这里阅读更多。****
*ADD run_jupyter.sh /ds/run_jupyter.sh*
该命令允许您在 docker 容器运行时将文件从主机复制到 docker 容器中。我用它来执行 bash 脚本并将有用的东西导入容器,比如。bashrc 文件。
请注意这里没有完全指定主机容器的路径,因为主机路径是相对于运行容器时指定的上下文目录的(这将在后面讨论)。**
当我运行这个容器的时候,碰巧我会将文件 run_jupyter.sh 放在上下文目录的根目录下,所以这就是为什么在源文件前面没有路径。
从用户指南中:
ADD <src>... <dest>
ADD
指令从<src>
复制新文件、目录或远程文件 URL,并将它们添加到路径<dest>
处的镜像文件系统中。
CMD 声明
Docker 容器的设计理念是,它们是短暂的,只停留足够长的时间来完成你想要运行的应用程序。然而,对于数据科学来说,我们经常希望让这些容器保持运行,即使其中没有任何活动的东西在运行。许多人通过简单地运行 bash shell(除非您杀死它,否则它不会终止)来实现这一点。
*CMD [“./run_jupyter.sh”]*
在上面的命令中,我运行一个 shell 脚本来实例化一个 Jupyter 笔记本服务器。但是,如果您没有任何想要运行的特定应用程序,但是您希望容器在不退出的情况下运行,那么您可以使用下面的命令来运行 bash shell:
*CMD ["/bin/bash"]*
这是可行的,因为 bash shell 在您退出之前不会终止,因此容器保持启动和运行。
从用户指南中:
一条
Dockerfile
中只能有一条CMD
指令。如果您列出了多个CMD
,那么只有最后一个CMD
会生效。****
**CMD**
的主要用途是为正在执行的容器提供默认值。这些默认值可以包括一个可执行文件,也可以省略该可执行文件,在这种情况下,您还必须指定一条ENTRYPOINT
指令。
建立你的码头工人形象
唷,这是关于 Dockerfiles 的大量信息。别担心,从这里开始,其他事情都相当简单。现在我们已经以 docker 文件的形式创建了我们的食谱,是时候构建一个图像了。您可以通过以下命令完成此操作:
Also available on Github
这将构建一个 docker 映像(不是容器,如果你不记得区别是什么,请阅读本文开头的术语!),您可以在以后运行它。
从您的 Docker 映像创建并运行一个容器
现在,您已经准备好让所有这些魔法发挥作用了。我们可以通过执行以下命令来启动此环境:
Also available on Github
在您运行这个之后,您的容器将启动并运行!jupyter 服务器将启动运行,因为
***CMD [“./run_jupyter.sh”]***
*Dockerfile 文件末尾的命令。现在,您应该能够在它所服务的端口上访问您的 jupyter 笔记本了——在本例中,应该可以使用密码*教程从 http://localhost:7745/ 访问它。如果你远程运行这个 docker 容器,你必须设置本地端口转发以便你可以从你的浏览器访问 jupyter 服务器。
与容器交互
一旦您的容器启动并运行,这些命令将会派上用场:
- 将新的终端会话附加到容器。如果您需要安装一些软件或使用 shell,这很有用。
- 将容器的状态保存为新图像。即使您从一个包含所有想要安装的库的 over 文件开始,随着时间的推移,您可能会通过交互地添加更多的库和包来显著地改变容器的状态。将容器的状态保存为图像是很有用的,您可以稍后共享或在其上分层。您可以通过使用 docker commit CLI 命令来实现这一点:
***docker commit <container_name> new_image_name:tag_name(optional)***
例如,如果我想将名为 container1 的容器的状态保存为名为 hamelsmu/tutorial:v2 的图像,我只需运行以下命令:
***docker commit container_1 hamelsmu/tutorial:v2***
你可能想知道为什么 hamelsmu/ 在图像名称的前面——这只是为了让[稍后更容易将这个容器推送到 DockerHub](http://n order to push a repository to the Docker Hub, you need to name your local image using your Docker Hub username, and the repository name that you created) ,因为 hamelsmu 是我的 DockerHub 用户名(稍后将详细介绍)。如果你在工作中使用 Docker,很可能有一个内部私有的 Docker repo,你可以把你的 Docker 图片放到里面。
- 列出运行容器。当我忘记了当前正在运行的容器的名称时,我经常使用这个方法。
***docker ps -a -f status=running***
如果您在没有 status=running 标志的情况下运行上面的命令,那么您将看到系统上所有容器的列表(即使它们不再运行)。这对于追踪旧容器很有用。
- 列出您保存在本地的所有图像。
***docker images***
- ****将您的图像推送到 DockerHub(或另一个注册表)。如果你想和别人分享你的作品,或者方便地在云中保存图片,这是很有用的。注意,这样做时不要分享任何私人信息(DockerHub 上也有私人回购)。
首先创建一个 DockerHub 存储库,并适当地命名您的映像,如这里所描述的。这将包括运行命令 docker login 首先连接到你在 DockerHub 或其他注册表上的帐户。例如,要将一个图像推送到这个容器,我首先必须将我的本地图像命名为 hamelsmu/tutorial(我可以选择任何标记名)例如,CLI 命令:
***docker push hamelsmu/tutorial:v2***
将上述 docker 图像推送到标签为 v2 的该储存库。应该注意的是,如果你公开你的图片,其他人可以简单地在你的图片上叠加图层,就像我们在本教程中给 ubuntu 图片添加图层一样。这对其他寻求复制或扩展你的研究的人来说是非常有用的。****
现在你有超能力了
现在您已经知道如何操作 Docker,您可以执行以下任务:
- 与同事和朋友分享可重复的研究。
- 通过根据需要将您的代码临时迁移到更大的计算环境中,在不破产的情况下赢得 Kaggle 竞赛。
- 在您的笔记本电脑上的 docker 容器中本地构建原型,然后毫不费力地将相同的计算无缝地转移到服务器,同时随身携带许多您喜欢的本地环境的东西(您的别名、vim 插件、bash 脚本、定制提示等)。
- 使用 Nvidia-Docker 快速实例化在 GPU 计算机上运行 Tensorflow、Pytorch 或其他深度学习库所需的所有依赖关系(如果你从头开始做这件事,这可能会很痛苦)。更多信息见下面的奖金部分。
- 将您的模型作为应用程序发布,例如作为一个 rest api,它从 docker 容器中提供预测服务。当您的应用程序被 docker 化时,它可以根据需要被任意多次复制。
延伸阅读
我们只是触及了 Docker 的皮毛,您还可以做更多的事情。我把重点放在了 Docker 的一些领域,我认为作为一名数据科学家,您会经常遇到这些领域,希望能给你足够的信心开始使用它。以下是一些对我的 Docker 之旅有帮助的资源:
- 2020 年 8 月 24 日编辑:以下是我最近在 Docker 上做的一些更详细的笔记。
- 有用的停靠命令
- 更有用的 Docker 命令
- 文档参考
- 如何在 DockerHub 上创建并推送存储库
奖金:英伟达-Docker
我最初学习 Docker 的最初动机是在单个 GPU 上构建深度学习模型的原型,并在我需要更多马力时将计算转移到 AWS。我也在快速学习这门优秀的课程。人工智能由杰瑞米·霍华德开发,并希望与他人分享原型。
然而,要正确封装所有依赖项,如 Nvidia GPUs 的驱动程序,您需要使用 Nvidia-Docker 而不是 Docker。这比使用普通的 Docker 需要更多的工作,但是一旦你理解了 Docker,这就很简单了。
我已经将我的 Nvidia-Docker 设置放在这个报告中,并将它作为读者的练习。