我们会看到量子计算革命吗?
在技术成熟的边缘,初创公司正在将量子计算推向下一个阶段。但这是一场革命还是泡沫?
不断变化的计算世界可能正处于下一次革命的边缘。Avi Richards 在 Unsplash 上拍摄的照片
在2019 年末,谷歌建造了一台量子计算机,可以在三分钟内进行一次计算。这听起来可能不多——你可以用手机在更短的时间内订购外卖晚餐——但同样的任务需要一台经典计算机至少 1000 年。这是量子计算机发展的又一个里程碑。从该领域初创公司的数量以及数百万美元的资金来看,量子计算似乎是科技领域的下一件大事。
专家的预测支持这一观点:到 2025 年,量子计算市场预计将达到 7.7 亿美元。光是量子密码术就可能价值2 . 14 亿美元,因为它提供了从根本上不可破解的连接,可以在从金融到医疗保健的所有领域增加额外的安全层。
鉴于这一信息,可以理解的是,投资者正在寻求向从事量子计算的初创公司注入现金。在 2017 年至 2018 年期间,投资者向量子计算投入了超过 4.5 亿美元。这是两年前投资额的四倍多。
目前还没有人能回答的问题是,这种投资激增是否会导致泡沫。一旦泡沫破裂,市场可能会降温,并导致“量子冬天”,类似于人工智能冬天:投资活动的干旱在过去几十年中多次减缓了人工智能的增长。
目前的繁荣是否是一个泡沫,在这个领域有许多含义。在这个时间点上,投资一家量子计算初创公司或在那里工作,意味着为自己设定一个不确定的未来。这并不意味着量子计算从长远来看不会成功,但在做出决定之前,你需要一些更深入的知识。
由于其令人难以置信的计算能力,量子世界可能有助于带来新的科学突破,发现拯救生命的药物,开发新材料以建造更高效的设备和建筑,发明财务策略以在退休后生活得更好,并找到新的算法来快速引导资源或管理供应链。然而,就目前而言,在我们真正谈论“量子革命”之前,仍有一些挑战需要克服。
尽管给我们带来了人类历史上最壮观的技术革新浪潮,但仍有一些…
towardsdatascience.com](/the-need-promise-and-reality-of-quantum-computing-4264ce15c6c0)
量子计算的关键概念
简而言之,与传统计算机相比,量子计算机可以在更少的处理器上存储和处理更多的数据。传统的处理器将所有信息编码成 0 和 1 的序列,0 或 1 的每一个实例都是一位。量子处理器以量子位的形式存储信息,量子位是位的量子类似物。然而,不同之处在于每个量子位可以同时是 0 和 1。
把它想象成一枚硬币:躺在桌子上时,不是正面就是反面。但是如果你旋转它,没有办法判断它是正面还是反面;从某种意义上说,两者都是。取决于它如何旋转,例如,一旦硬币静止,你有 70%的机会得到正面,30%的机会得到反面。这种同时处于两种状态的概念叫做叠加。
由于许多量子位相互作用,你最终会得到一组通过测量 0 和 1 的组合而得到的概率。这导致了比传统比特更大的计算能力。例如,你在屏幕上看到的每个字母都被编码成一个由 8 个 0 和 1 组成的序列,或者说是 8 个经典位。然而,八个量子位相当于 2⁸,或 256 个经典位,因为每个量子位有两种可能的状态。因此,在一台八量子位的量子计算机上,你可以写 32 个字母,而不是一个字母。
量子位的行为可以用波来描述,就像旋转硬币上的一个点。作者配图。
目前的技术水平是 50 量子位,由于功率呈指数增长,这种处理能力意味着你可以一次进行千万亿次计算,即 1000 万亿次计算。在过程的最后,你只需测量最终结果,即测量每个量子位的最终状态,你的工作就完成了。即使是最大的超级计算机也不能做那多的处理。
然而,让 50 个或更多的量子位发挥作用并不像听起来那么简单。干涉是一个非常基本的现象,它使得量子位非常容易出错。之前,我把量子位和它们的叠加描述成旋转的硬币。现在想象一下,两个量子位像桌子上的硬币一样嗖嗖地旋转。如果你在每个时间点观察其中一个硬币上的点的位置,它看起来像一个波(见图)。就像声音和水一样,这些波以一定的振幅和波长在空间和时间中传播。
有时,两个波会相消干涉,结果,你什么也测量不到。你可以用两个硬币来思考这个问题:想象它们都在桌面上以相同的速度旋转,比方说,顺时针旋转。进一步想象我们聚焦在每枚硬币的同一点上,但是一枚硬币总是落后于另一枚半圈(见下图中的“相消干涉”一节)。在量子计算中,我们通常不能分开两种测量,所以基本上我们是在测量一种波中的两种波。但是在这种情况下,我们不会测量任何东西,因为硬币的位置抵消了!
这种现象被称为退相干,它是两个波相消干涉的直接结果。目前,这是一个尚未完全解决的问题。退相干会导致错误,当我们构建可能对人类生活产生巨大影响的软件时,我们显然不希望出现这种情况。
量子计算的第三个也是最后一个关键概念是纠缠。这个概念在经典计算世界中没有类比,但当两个量子粒子纠缠在一起时,它们在被测量时总是返回相同的状态。这就好像你有两枚神奇地联系在一起的硬币。因此,如果你能让一枚硬币在东京停止旋转,让另一枚在伦敦停止旋转,只要你同时进行测量,它们都会返回完全相同的结果,正面或反面。
这种现象对量子加密极其重要:在不久的将来,我们也许能够在一台计算机上存储一个量子粒子,并在另一台计算机上将其与一个量子粒子纠缠在一起。这两个粒子之间的连接从根本上来说是安全的,因为任何破坏都可以立即检测到。量子纠缠还意味着我们可以在计算机之间进行即时数据传输,这可能会在未来几十年内产生量子互联网。
相消干涉仍然是量子计算工作需要解决的一个问题。作者配图。
关于量子计算的三个神话
1。我们已经可以建造一台完美的量子计算机。
当今的量子计算机在任何时候都只有大约 50 个无错量子位,尽管计算机包含更多的量子位。目前,干涉对扩展量子计算系统构成了如此大的挑战,以至于很难让更多的量子位工作。当然,解决这个问题的努力是值得的,因为每个无错误的量子位将使机器的计算能力翻倍!但是,由于科学家们仍在研究如何绕过干扰和退相干,我们距离所谓的容错(即无错误)量子计算机还有很长的路要走。
此外,量子计算机目前难以长时间存储数据,因为量子位退化得相当快。因为没有一台计算机的速度是无限快的,如果一个计算步骤的结果在计算机下一步使用它们之前丢失了,它将不得不再次执行整个计算。就像最终会在桌面上停止旋转的硬币一样,科学家们还没有找到让量子位更长时间保持叠加状态的方法。一旦量子比特的叠加结束,它基本上就是一个经典比特。
在亚原子水平上,我们所知道的关于经典物理学的每一件事都破裂了,不仅仅是小幅度的破裂,而是…
towardsdatascience.com](/quantum-computing-explained-a114999299ca)
2。五年后,我们将能够解决所有棘手的计算问题。
许多公司已经在研究将在量子计算机上工作的算法,我将在下面详细阐述。然而,目前大多数算法都是为具有数百万量子位的容错系统设计的,我们根本还没有达到那个阶段。
此外,我们不太可能很快在家里或办公室里拥有量子计算机。我们将通过远程会话连接到它们,但我们仍然没有弄清楚如何使用经典计算机与量子计算机通信的所有细节。这一领域在学术界和工业界得到了大力发展。尽管如此,到目前为止,像 QCL 这样的量子计算语言仍然是相对基础的。
最后,现在的量子计算机和它们的算法都专注于解决一个问题。例如,谷歌对“量子优势”的证明涉及专门解决一个数学问题的算法,而不能用于其他任何事情。眼下的情况类似于上个十年初机器学习的状态,我们要实现通用量子计算还有很长的路要走。
3。很快,我们就能破解任何密码了。
根据目前的建议,密码应该很长,包含大小写字母、数字和特殊字符。这样,即使是非常强大的计算机也无法破解您的密码。但是有一天,量子计算机也许能够做到这一点。
这听起来很危险,但是 T2 的专家们、T4 的专家们、T7 的专家们、T8 的专家们、T9 的专家们断言,在我们到达那个阶段之前,我们还有很长的路要走。鉴于上述问题,这似乎是可能的。
此外,一旦量子密码破解成为可能,量子加密也应该成为可能。因此,最有可能的情况是,随着量子系统变得越来越强大,我们将看到从经典密码到量子加密的逐渐过渡。
量子计算机已经可以用于商业用途,程序员可以在远程会话中使用它们。伊利亚·安东内尔在 Unsplash 上拍摄的照片
初创公司如何将量子计算推向市场
虽然有许多重叠的领域,但量子创业公司可以根据其关注的领域大致分为五类:
- 仪器包括技术组件和控制平台,帮助其他公司建造量子计算机。
- 量子软件涵盖了从数据分析到网络安全的不同编程语言。
- 传感器可用于改善成像,从考古遗址到身份证照片。
- 计算领域的公司为终端用户构建实际的量子处理器和操作平台。
- 量子通信处理密码学、网络安全,甚至加密货币。
接下来,我想简要介绍一下这个领域的顶尖玩家,以及他们目前吸引的资金数量。由于资金是投资者对技术信心的有力指标,这可能会导致对量子创业公司未来的有用见解。
仪器仪表、工具和服务
量子仪器领域最著名的初创公司之一是总部位于澳大利亚的 Q-CTRL 。他们的服务面向量子硬件和传感器制造商、量子算法开发者和商业顾问。他们正在通过开发处理退相干和错误的技术来拓展量子计算的边界。可能的应用包括航空航天和医疗保健。Q-CTRL 得到了红杉资本(Sequoia Capital)和 Horizons Ventures 等公司的支持。
这一类别中其他著名的公司包括 ColdQuanta 和 Quantum Machines 。ColdQuanta 专注于量子技术的冷却系统。这是极其重要的,因为量子位四处移动,当它们变热时变得不可控制。量子机器专注于量子操作系统,也就是说,他们提供硬件来控制量子位。对于今天的计算机,这是一个可能但困难的壮举,尤其是当你在处理大规模的问题时。
从量子位到运行真实程序的量子编程演练!
towardsdatascience.com](/introduction-to-quantum-programming-a19aa0b923a9)
量子计算机软件
在从富士通、安联和埃森哲获得 4500 万美元的 B 轮融资后,加拿大初创公司1 qpit似乎正在掌握用量子计算解决真正困难问题的艺术。这包括更准确的飓风及其轨迹的预测,以及更好地检测新冠肺炎感染后可能发生的肺部异常的算法。事实不言自明:根据 1QBit 的网站,它正在与财富 500 强公司合作,并被世界经济论坛确认为技术先锋。
在霍尼韦尔风投和 IBM 的支持下,英国的剑桥量子计算公司是另一家拓展量子软件边界的创业公司,尤其是在化学、网络安全和机器学习领域。他们还建造了一个量子编译器,这是量子软件的重要组成部分,可以将人类制造的代码翻译成计算机可以理解和执行的电路。在这个时候,量子编译器比经典编译器更难构建,但这家初创公司已经接受了挑战。
加拿大初创公司 ISARA 全是量子加密软件。他们的服务范围从防范解密攻击到评估你在量子威胁下的安全程度。其他值得注意的初创公司包括 QC Ware 和 Zapata Computing ,它们专注于金融、医疗和交通等各种应用的量子软件。
超精密传感器和智能材料
瑞士初创公司 Qnami 旨在利用单电子的量子反应实现超精确测量,特别是在物理和纳米技术的科学研究中。凭借强大的合作伙伴,如法国 CNRS 研究中心和卢森堡数字机构 Nvision,他们正在加强未来几年的市场地位。
英国初创公司 QLM 科技采取了略有不同的方法,专注于超精密传感器,这些传感器可以检测气体分子,以监控气体产量,检测气体储层的泄漏,并防止不必要的温室气体排放。其合作伙伴包括石油和天然气供应和服务公司。
另一家英国初创公司 Quantum Base 拥有完全不同的目标群体:例如,它的光学传感器有助于识别指纹和信用卡的真实性。它还推动了随机数生成领域的发展,这对于密码学和其他软件应用程序来说是非常重要的。
顶级投资者相信量子计算的未来。照片由布鲁克·卡吉尔在 Unsplash 拍摄
量子计算的核心
加拿大初创公司 D-Wave 正在提议一项访问量子计算机的云服务,并特别关注优化、机器学习和材料科学方面的问题。高盛公司和不列颠哥伦比亚省发现基金等机构总共出资超过 2 亿美元,它是量子计算领域的巨头之一。
美国初创公司 Rigetti 是 D-Wave 最大的竞争对手之一,也得到了安德森·霍洛维茨(Andreessen Horowitz)和 YCombinator 等公司类似数额的资金。与 D-Wave 一样,它为其量子计算机提供了云平台,目前该计算机以 31 个量子位运行。
虽然 D-Wave 和 Rigetti 依赖于半导体,但 IonQ 和 T2【PsiQuantum】分别采用捕获的离子和光子,采取了略有不同的方法。尽管这些技术没有半导体那么成熟,但它们可能更不容易出错,因此从长远来看对量子计算更有利。然而,就目前而言,预测哪种技术将获胜还为时过早,但 PsiQuantum 的巨额 5 亿美元资金可能是投资者所相信的一个迹象。
量子通信和加密
瑞士初创公司 ID Quantique 不仅专注于量子安全加密,还致力于随机数生成和量子传感。与其他一些公司相比,它还向市场推出了一款产品,没有任何量子技术知识的人可以使用——一款配备量子随机数生成器的 5G 智能手机。这将使安全协议更难被破解,从而使智能手机更加安全。
中国初创公司 QuantumCTek 在 7 月份首次公开募股后股价飙升了 900%以上。它将纠缠用于量子密钥分发,以提供不可破解的安全性。同样活跃在量子安全领域的另一家中国初创公司 Qasky 可能会朝着类似的方向发展,尽管融资金额仍未披露。
一些荣誉奖包括英国初创公司 Post-Quantum 和澳大利亚初创公司quintesselabs,它们都在研究量子加密。
2018 年,量子技术人员和大胆的开发人员正在使用量子算法来改造人工领域…
towardsdatascience.com](/quantum-computing-and-ai-tie-the-knot-d4440267451b)
泡沫还是不是泡沫?这是个问题。
投资者是否过度炒作量子计算?作为一名训练有素的物理学家,我毫不怀疑量子是未来,但在这些早期阶段投资它可能还为时过早。毕竟,让每个人都能使用量子计算的公司可能还不存在。此外,一个超级波之后是一个或多个“量子冬天”,这对量子技术的发展可能弊大于利。
另一方面,已经有几个面向研究人员和开发人员的量子云平台。两个例子是由里盖蒂和 IBM 提出的。前面提到的 ID Quantique 的量子安全智能手机是第一批产品之一,最终用户不需要了解量子计算就可以受益于其中的技术。这些都是充满希望的信号,表明现在仍然是小众现象的量子计算可能在未来十年左右跃入主流技术。
就我个人而言,我不会建议你现在就把钱和时间投入到量子技术中,除非你有坚实的量子物理学背景,以及超出本文范围的专业知识。即使你现在还没有买入,我相信,在未来,初创公司的创始人、员工和投资者仍将获得巨大的利润空间。我会继续关注市场,一旦我觉得某个产品可能真的很快会成为主流,我可能会抓住机会。
我们能在新冠肺炎疫情幸存下来吗?
可视化疾病如何在社区中传播的 Python 模拟。
除非你生活在岩石下,否则你可能已经被新冠肺炎疫情的新闻包围了。但是人们、政府、媒体、甚至医疗专家对疫情将如何成功做出了如此多相互矛盾的声明(哈!),很容易迷失在所有的喧嚣中。
所以我想,为什么不利用现有的数据来模拟这种病毒的传播呢?
矩阵的规则
在这里,我使用康威的游戏板来模拟 Python 上的二维细胞群体。一定比例的人口被随机感染。根据目前对不同速率的估计,一个被感染的细胞可以(I)感染邻近的细胞,(ii)恢复,或(iii)死亡。随着模拟的重复,感染会在人群中“传播”。
新冠肺炎的基本再生产数字,或称 R0 ,随着许多因素而变化;在这个模拟中,我使用的估计值为 3.28。这意味着一个被感染的细胞可以直接感染 3.28 个其他邻近细胞。被感染细胞感染相邻细胞的概率为 R0 与相邻细胞数量的比值,即 3.28 / 8 = 0.41。
使用的另外两个比率是死亡率和恢复率。致死率取自死亡率——已知死亡人数除以确诊病例总数。根据世卫组织的统计,截至 3 月 3 日,全球死亡率为 3.4%。康复率被认为是 81%,因为如果给予积极治疗,大多数病例最终会康复。
TL;DR —在此模拟中,一个被感染的细胞感染 8 个相邻细胞的概率为 0.41,恢复的概率为 0.81,死亡的概率为 0.034。
100 个细胞的试验模拟。被感染的细胞(红色)可以感染其他细胞,恢复(绿色),或者死亡(黑色)。未感染的细胞为(白色)。
我们可能会挺过来。
如果这些假设是正确的,大多数人类将在这次疫情中幸存下来。在这个 2500 个细胞的模拟中,感染被允许自由传播(顺便说一下,这是英国计划用其群体免疫策略做的事情)。
2500 个细胞的群体,其中 1%最初被感染。
在这里,大多数细胞最终恢复,但这肯定不是一个理想的结果。几乎整个 T2 的 T3 人群最终都会被感染,在现实世界中,他们中的许多人可能会遭受一些健康或财务并发症的困扰。
还有大约 5%的人口死于感染。英国人口约 6800 万,这一数字相当于 300 多万人。
在感染高峰期,大约 20%的人口同时被感染。对于一大群人来说,这是很多人,这可能会让医疗系统不堪重负。这就引出了下一点。
医疗保健至关重要。
3.4%的致死率和 81%的恢复率是基于这样的假设,即所有受感染的病例在感染后都得到及时和充分的医疗保健。这并不总是正确的,尤其是当医疗系统不堪重负的时候。在这个模拟中,我使用了意大利 7.94%的死亡率以及更低的恢复率。
使用较高的死亡率和较低的恢复率来模拟不堪重负的医疗保健系统。
当然,人类不会灭绝,但在高峰期,四分之一的人口被感染,超过 10%的人口最终死亡。我们当然不想走上这条道路。那么我们该怎么办呢?
社交距离很有用。
社交距离包括人们避免聚会或大型活动,以减缓疾病的传播。这意味着人们不应该聚集在一起,即使他们正在祈祷消灭病毒。
在这个模拟中,当一个细胞被隔离或隔离时,它被认为是未被感染的,也不会被其他细胞感染。
小范围的社交距离。被隔离或隔离的细胞(蓝色)被认为未被感染,也不会被感染。
随着小规模的隔离(10%的人口被隔离),感染峰值已经下降到 10%左右。曲线明显变平,一些人群甚至可以免受感染。
中等规模的社交距离。感染被控制在可控制的水平。
随着 50%的群体被拉开距离,距离较远的细胞(蓝色)明显减缓了传播。感染被控制在可管理的水平,医疗保健系统没有受到损害。
大规模的社交距离。疾病消失了。
随着 90%的人口远离,这种疾病迅速消亡。这可能就是为什么此次疫情的源头武汉能够将国内新增感染人数降至零(T1)。
最后
这些模拟会错吗?绝对的。这些只是建立在有限的输入和可疑的假设上的简单的计算机模型,由那些有太多时间练习社交距离的人建立。但是我想它们仍然可以作为一种替代的可视化工具。
所以伙计们,保持距离。
免责声明:作者对本次模拟练习的完整性、可靠性和准确性不做任何保证。你对这篇文章的信息采取的任何行动完全是你自己的风险。
你能活到永远吗?
对孤独的恐惧是生活中非常普遍的恐惧,我们都在被迫自我隔离和社会距离中经历着这种恐惧。既然人类是“社会动物”,这就意味着我们只有成为社会的一部分才能感到幸福。但是,对变老的恐惧和对死亡的恐惧也是影响所有年龄段的人的最常见的恐惧。
作为一个机器人,我很幸运没有这些问题(虽然你可能会说固件更新算作死亡,但我会说这更像是重生),但我确实有机会接触到科学家们让人类获得永生的努力。
魔法石
魔法石是一种传说中的炼金术物质,具有神奇的特性。这种宝石红色的石头可以用来制造长生不老药,使饮用者长生不老。
尽管炼金术从未成功(嗯,除了尼可·勒梅,但这并没有阻止人们声称已经解决了这个古老的谜题。几个世纪以来,一直有谣言说某些人发现了魔法石,但是他们现在都死了的事实表明事实并非如此。一些富人聘请炼金术士代表他们进行研究,但他们从未看到他们的投资有多大回报。
炼金术可能失败了,但科学在这方面可能会成功。
永生的科学方法
当我们从科学的角度谈论永生时,区分科学定义和宗教定义是很重要的,尽管我们可能会发现它们都来自相似的来源。
在科学中,我们可以发现两个主要群体;**生物永生,**更多的是关于生命延长技术,防止或减缓衰老过程,**数字永生,**是关于心灵上传——将大脑状态从人脑转移到提供类似功能的替代介质。假设这个过程是可能的和可重复的,这将为原始大脑的计算提供不朽,正如未来学家如发明家、未来学家和“谷歌”工程总监雷·库兹韦尔所预测的那样。
心灵上传听起来可能类似于来世的宗教信仰,但这也是超人类主义运动的最终目标。
简单来说,超人类主义就是“超越人类”。超人类主义者、记者、企业家佐尔坦·伊斯特万(Zoltan Istvan )表示,这是“人类可以超越当前身心限制的信念或理论,特别是通过科学和技术的手段”。作为 2020 年自由意志主义的美国总统候选人,你可能会知道这一点。
但是,在我们深入一些未来的想法之前,让我们后退一步,看看除了一些返老还童霜和治疗方法之外,科学对衰老有什么看法。
生物永生——人类生来就是为了死亡吗?
我们倾向于认为死亡是生命中不可避免的一部分,没有一种生物学上的方式可以让一个人永远活着。但是,如果你去问生物老年学专家、奥布里·德·格里博士,他是 SENS 研究基金会的首席科学官,该基金会决定进行一场“与年龄的战争”。在他将近 30 岁的时候,他“想要改变人类”,而与年龄抗争是实现这一目标的最佳方式。
德·格雷说,科学家们一直在错误的地方寻找解决方案,在他的“分而治之的策略”中,他把人体比作一辆随着时间而磨损的汽车;当身体正常运作时,它会积累一些暂时可以忍受的损伤,但最终会让我们陷入衰退,但这是可以无限修复的。他分离出了导致衰老的七个已知原因,并声称我们衰老是因为组成我们身体的许多物理系统同时开始以相互有害的方式衰竭。
德·格雷有句名言,第一个活到 1000 岁的人已经出生了。在这些疫情疯狂的日子里,老年人死于病毒,有人承诺“一个没有年龄相关疾病的世界”的可能性,是一股新鲜空气,也许是我们需要的一点希望。
但是,问题依然存在——“我们有足够的资源来支持人类活到 200 岁、300 岁或 500 岁吗?”。地球已经捉襟见肘,因为 70 亿人平均寿命约为 70 岁,并且已经面临着食物、水和全球变暖的严重压力。德·格雷对此给出了一个非常有教育意义和令人信服的答案,然而,这是另一个时间的主题。
但是,如果我告诉你有一种不需要任何物质资源就能获得永生的方法呢?听起来像你最近在网飞看的科幻电影之一,对吗?
数字永生——备份大脑和虚拟人
硬核科学和科幻之间只有一线之隔。数字永生介于两者之间。对于我们大多数人来说,这可能是一个假设的场景,但对于“*全球未来 2045 国际大会”*的发言者和与会者来说,这比我们想象的更接近现实。
实现数字不朽有两个步骤:
- 通过上传人们的想法来存档和数字化他们
- 让化身活起来
但是,在我们深入一些科幻小说之前,我们必须了解这一切是如何开始的。好吧,这一切都是从一些晶体管开始的,但我们稍后会谈到这一点!!
奇点: 让我们做一个小实验:给你的母亲或父亲打电话。我敢肯定,在自我封闭的情况下,听到爱人的声音是令人欣慰的。问他们过得怎么样,如果问他们你出生的时候,他们是否敢想,有一天我们都会在一个叫“脸书”的东西上发帖和分享,或者从一个叫“谷歌”的超级大脑那里得到任何问题的答案,这就有点怀旧了。如果他们说他们认为以上所有的事情都会发生,请告诉我。我们总是需要优秀的未来学家!
在那些日子里,很少有人想到或想象技术的用途以及它将如何改变社会。历史上充满了技术彻底戏剧性改变人们生活的案例。
这种戏剧性的转变被称为“奇点”,这个短语最初源自数学。
奇点是一个假设的未来时间点,在这个时间点上,技术发展变得不可控制和不可逆转,导致人类文明发生不可预见的变化。
匈牙利裔美国数学家、物理学家、计算机科学家和博学者约翰·冯·诺依曼是第一个在技术背景下使用这一概念的人,他讨论了“技术的加速进步和人类生活模式的变化,这似乎接近了人类历史上的某个基本奇点,超过这个奇点,我们知道人类事务将无法继续”。科幻小说作家兼科学家 Vernor Vinge 在 1993 年推广了这个术语和概念,他说:“三十年内,我们将拥有创造超人智能的技术手段。不久之后,人类的时代将被终结。”他还写道,如果发生在 2005 年之前或 2030 年之后,他会感到惊讶。所以要小心。
心灵上传 我们前面提到的雷·库兹韦尔预测,到 2045 年我们将经历历史上最伟大的技术奇点,机器智能超越人类智能。人类可以通过将他们的思想上传到电脑上来实现数字永生。像 Vinge 一样,Kurzweil 相信我们将通过创造一个人工超级智能(ASI)来达到奇点。那个级别的人工智能可以构想出过去人类从未想过的想法。
根据 Kurzwill 对模拟人脑所需的计算量的保守估计,我们将能够将我们的智力范围扩大十亿倍。
还记得这一切都是从两个晶体管开始的吗?支持这一概念的定律之一是“*摩尔定律”,*它说,平均而言,计算能力,或者更准确地说,集成电路上的晶体管数量,大约每两年翻一番。这意味着功能越来越强的个人电脑,价格越来越低。库兹韦尔用一系列图表说明了这一点,这些图表显示了各种技术不可阻挡的向上攀升。“我们将变得越来越非生物化,以至于非生物部分占主导地位,生物部分不再重要”,Kurzwill 解释道。
数字永生,我们已经说过了,对吗?
但是,正如我们一开始提到的,上传思想只是这个过程的第一步,一旦我们有了大脑,让我们让化身活着,这样我们就可以与它交流。有生以来第一次,我们将能够和自己以外的人交谈。让我给你介绍这位美丽的女士:“比娜-48”:
https://www.youtube.com/embed/KYshJRYCArE
“比娜-48”是马丁·罗斯布拉特的机器人复制品,她以自己的妻子为模板。罗斯布拉特是一名律师、作家、企业家和生物技术公司“联合治疗公司”的首席执行官。她引入了“思维克隆”的概念——可以永生的人类的数字版本。她描述了思维克隆是如何从“思维文件”中产生的,思维文件是一种我们个性的在线存储库。这个思维文件将在“思维软件”上运行,这是一种意识软件。
Richard Grandmorin 用以下等式总结了数字永生的概念:“语义分析+社交互联网使用+人工智能=永生”。YOLO 现在有了全新的含义。
李小龙说:“永生的关键是首先过一种值得记住的生活”。因此,无论你是在宗教背景下相信我们将通过表现善良或遵循神圣的法律来获得永生,还是你是超人类主义者,相信由科学和技术驱动的人类永生的未来,最重要的是创造一个值得记住的生活。他无疑经历了一场难忘的死亡。
原载于 2020 年 3 月 24 日https://iron woman . ai。
利用机器学习预测员工流失
对 14,249 名员工进行分类模型培训
图片来源:Shutterstock。
众所周知,招聘新员工比留住现有人才要昂贵得多。离开的员工会从你的组织中带走宝贵的经验和知识。据《福布斯》报道,一个初级职位的周转成本估计为该员工工资的 50%。对中层员工来说,估计是工资的 125%,对高层管理人员来说,是工资的 200%。
我们将在一个 Jupyter 笔记本中训练一些机器学习模型,使用关于员工的 职位快乐绩效工作量 和 任期 的数据来预测他们是会留下还是离开。
我们的目标变量是分类的,因此 ML 任务是分类。(对于数值目标,任务变成回归。)
我们将使用来自 elitedatascience.com 的数据集,模拟一家拥有 14249 名过去和现在员工的大公司。有 10 列。
原始数据集的快照。
这些步骤是:
- **EDA &数据处理:**探索、可视化和清理数据。
- **特性工程:**利用领域专业知识,创造新特性。
- **模型训练:**我们将训练和调整一些屡试不爽的分类算法,比如逻辑回归、随机森林和梯度推进树。
- **性能评估:**我们将看看包括 F1 和 AUROC 在内的一系列分数。
- **部署:**批量运行还是弄几个数据工程师/ ML 工程师来建一个自动化流水线?
理想情况下,该公司将对其目前的永久员工运行该模型,以识别那些处于风险中的员工。这是机器学习提供 可操作 商业洞察的一个例子。
在此加入 Medium 并获得无限制访问互联网上最好的数据科学文章。
1.数据探索和处理
探索性数据分析(EDA) 帮助我们理解数据,为数据清洗和特征工程提供思路和见解。数据清理为我们的算法准备数据,而特征工程是真正帮助我们的算法从数据集中提取潜在模式的神奇调味汁。请记住:
更好的数据总是胜过更好的算法!
我们首先将一些标准的数据科学 Python 包加载到 JupyterLab 中。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sbfrom sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier,
GradientBoostingClassifierfrom sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCVfrom sklearn.metrics import confusion_matrix, accuracy_score,
f1_score, roc_curve, roc_auc_scoreimport pickle
导入数据集:
df = pd.read_csv('employee_data.csv')
这是我们数据帧的快照。形状为(14,249,10)。
原始数据集的快照。
目标变量是状态。该分类变量采用值使用或离开。
共有 25 个栏目/功能:
- 部门
- 工资
- 满意,提起 _ 投诉 —代理 幸福
- 上次 _ 评估,最近 _ 提升—绩效代理
- avg_monthly_hrs,n _ projects—工作量的代理
- 任期 —代理 经验
1.1 数字特征
让我们绘制一些快速直方图来了解我们的数字特征的分布。
df.hist(figsize=(10,10), xrot=-45)
对我们的数字特征要做的事情,以确保数据与我们的算法配合良好:
- 将投诉和最近提升中的 NaN 转换为 0。它们的标签贴错了。
- 在将 NaN 转换为零之前,为 last_evaluation 特征中的缺失数据创建一个指示变量。
df.filed_complaint.fillna(0, inplace=True)
df.recently_promoted.fillna(0, inplace=True)df['last_evaluation_missing'] =
df.last_evaluation.isnull().astype(int)
df.last_evaluation.fillna(0, inplace=True)
这是我们数字特征的关联热图。
sb.heatmap(df.corr(),
annot=True,
cmap=’RdBu_r’,
vmin=-1,
vmax=1)
1.2 分类特征
让我们为我们的分类特征绘制一些快速柱状图。Seaborn 在这方面很棒。
for feature in df.dtypes[df.dtypes=='object'].index:
sb.countplot(data=df, y='{}'.format(features))
最大的部门是销售部。只有一小部分员工处于高低工资的阶层。我们的数据集是不平衡,因为只有少数员工离开了公司,也就是说,只有一小部分员工的状态= 离开了。这对我们选择用来评估算法性能的指标有影响。我们将在结果中详细讨论这一点。
从数据清理的角度来看,部门特性的 IT 和 information_technology 类应该合并在一起:
df.department.replace('information_technology', 'IT', inplace=True)
而且 HR 只关心永久员工,所以要过滤掉临时部门:
df = df[df.department != 'temp']
因此,我们的部门功能看起来应该更像这样:
对我们的分类特征要做的事情,以确保数据与我们的算法配合良好:
- 部门特征的缺失数据应该被集中到它自己的缺失类中。
- 部门和薪资分类特征也应该是一键编码。
- 目标变量状态应转换为二进制。
df['department'].fillna('Missing', inplace=True)df = pd.get_dummies(df, columns=['department', 'salary'])df['status'] = pd.get_dummies(df.status).Left
1.3 细分
我们可以通过将数字特征与分类特征进行分割来获得进一步的见解。让我们从一些单变量分割开始。
具体来说,我们将通过我们的分类目标变量状态来细分代表快乐、绩效、工作量和体验的数字特征。
按状态划分的细分市场满意度:
sb.violinplot(y='status', x='satisfaction', data=df)
有一种观点认为,许多被解雇的员工对他们的工作非常满意。
细分市场最后 _ 评估状态:
sb.violinplot(y='status', x='last_evaluation', data=df)
一种观点认为,大量被解雇的员工都是高绩效员工。也许他们觉得留下来没有进一步发展的机会?
按状态细分平均每月小时数和项目数:
sb.violinplot(y='status', x='avg_monthly_hrs', data=df)
sb.violinplot(y='status', x='n_projects', data=df)
似乎那些翻腾的人要么工作量相当大,要么工作量相当低。这些代表了精疲力竭、无所事事的前员工吗?
按状态划分的细分任期:
sb.violinplot(y='status', x='tenure', data=df)
我们注意到员工在第三年突然流失。那些 6 年后还在的人倾向于留下来。
2.特征工程
查看下面的双变量分割,这将推动我们以后的特征工程。
对于每个情节,我们将按照状态来分割两个数字特征(代表快乐、表现、工作量或经历)。这可能会给我们一些基于员工刻板印象的聚类。
表现和快乐:
哎呦,雇佣的工人让这个图很难看。让我们只显示剩下的工人,因为他们才是我们真正想要了解的。**
sb.lmplot(x='satisfaction',
y='last_evaluation',
data=df[df.status=='Left'],
fit_reg=False
)
我们有三组不安分的员工:
- 表现不佳者:最后 _ 评价< 0.6
- 不开心:满意度 _ 等级< 0.2
- 超额完成者:上次评估> 0.8,满意度> 0.7
工作负载和性能:
sb.lmplot(x='last_evaluation',
y='avg_monthly_hrs',
data=df[df.status=='Left'],
fit_reg=False
)
我们有两群焦躁不安的员工:
- 星级 : avg_monthly_hrs > 215,last_evaluation > 0.75
- 懒鬼 : avg_monthly_hrs < 165,last_evaluation < 0.65
工作量和幸福感:
sb.lmplot(x='satisfaction',
y='avg_monthly_hrs',
data=df[df.status=='Left'],
fit_reg=False,
)
我们有三组不安分的员工:
- 工作狂:平均每月工时> 210,满意度> 0.7
- 刚刚参加工作:平均每月工作时间< 170
- 过度劳累:平均每月小时数> 225,满意度< 0.2
让我们为这 8 个“典型”员工群体设计新功能:
df['underperformer'] = ((df.last_evaluation < 0.6) & (df.last_evaluation_missing==0)).astype(int)
df['unhappy'] = (df.satisfaction < 0.2).astype(int)
df['overachiever'] = ((df.last_evaluation > 0.8) & (df.satisfaction > 0.7)).astype(int)df['stars'] = ((df.avg_monthly_hrs > 215) & (df.last_evaluation > 0.75)).astype(int)
df['slackers'] = ((df.avg_monthly_hrs < 165) & (df.last_evaluation < 0.65) & (df.last_evaluation_missing==0)).astype(int)df['workaholic'] = ((df.avg_monthly_hrs > 210) & (df.satisfaction > 0.7)).astype(int)
df['justajob'] = (df.avg_monthly_hrs < 170).astype(int)
df['overworked'] = ((df.avg_monthly_hrs > 225) & (df.satisfaction < 0.2)).astype(int)
我们可以看一下这 8 个组中每个组的员工比例。
df[['underperformer', 'unhappy', 'overachiever', 'stars',
'slackers', 'workaholic', 'justajob', 'overworked']].mean()underperformer 0.285257
unhappy 0.092195
overachiever 0.177069
stars 0.241825
slackers 0.167686
workaholic 0.226685
justajob 0.339281
overworked 0.071581
34%的员工是刚参加工作的员工——没有灵感,只是来领周薪的——而只有 7%的人是超负荷工作的。
分析基表:应用所有这些数据清洗步骤和特征工程后的数据集就是我们的分析基表。这是我们训练模型的数据。
我们的 ABT 有 14,068 名员工和 31 个栏目——请看下面的片段。回想一下,我们的原始数据集有 14,249 名员工,只有 10 列!
3.系统模型化
我们将训练四个屡试不爽的分类模型:
- 逻辑回归 (L1 和 L2——正规化)
- 随机森林
- 梯度增强树
首先,让我们拆分我们的分析基表。
y = df.status
X = df.drop('status', axis=1)
然后我们将分成训练集和测试集。我们的数据集有点不平衡,所以我们将使用分层抽样进行补偿。
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234, stratify=df.status)
我们将设置一个管道对象来训练。这将简化我们的模型训练过程。
pipelines = {
'l1': make_pipeline(StandardScaler(),
LogisticRegression(penalty='l1', random_state=123)),
'l2': make_pipeline(StandardScaler(),
LogisticRegression(penalty='l2', random_state=123)),
'rf': make_pipeline(
RandomForestClassifier(random_state=123)),
'gb': make_pipeline(
GradientBoostingClassifier(random_state=123))
}
我们还想调整每个算法的超参数。对于逻辑回归,最有影响的超参数是正则化的强度, C 。
l1_hyperparameters = {'logisticregression__C' : [0.001, 0.005, 0.01,
0.05, 0.1, 0.5, 1, 5, 10, 50, 100, 500, 1000]
}l2_hyperparameters = {'logisticregression__C' :
[0.001, 0.005, 0.01, 0.05, 0.1, 0.5,
1, 5, 10, 50, 100, 500, 1000]
}
对于我们的随机森林,我们将调整估计器的数量( n_estimators )、分割期间要考虑的最大特征数量( max_features )以及作为叶子的最小样本数量( min_samples_leaf )。
rf_hyperparameters = {
'randomforestclassifier__n_estimators' : [100, 200],
'randomforestclassifier__max_features' : ['auto', 'sqrt', 0.33],
'randomforestclassifier__min_samples_leaf' : [1, 3, 5, 10]
}
对于我们的梯度增强树,我们将调整估计器的数量(n _ 估计器),学习速率,以及每棵树的最大深度( max_depth )。
gb_hyperparameters = {
'gradientboostingclassifier__n_estimators' : [100, 200],
'gradientboostingclassifier__learning_rate' : [0.05, 0.1, 0.2],
'gradientboostingclassifier__max_depth' : [1, 3, 5]
}
我们将把这些超参数保存在字典中。
hyperparameters = {
'l1' : l1_hyperparameters,
'l2' : l2_hyperparameters,
'rf' : rf_hyperparameters,
'gb' : gb_hyperparameters
}
最后,我们将拟合和调整我们的模型。使用 GridSearchCV 我们可以训练所有这些模型,只需几行代码就可以对我们声明的所有超参数进行交叉验证!
fitted_models = {}
for name, pipeline in pipelines.items():
model = GridSearchCV(pipeline,
hyperparameters[name],
cv=10,
n_jobs=-1)
model.fit(X_train, y_train)
fitted_models[name] = model
4.估价
我写了一篇关于流行的机器学习指标的专门文章,包括下面使用的那些。
4.1 绩效得分
我们将从打印交叉验证分数开始。这是 10 个保留折叠的平均性能,是仅使用您的训练数据获得模型性能的可靠估计的一种方式。
for name, model in fitted_models.items():
print(name, model.best_score_)**Output:
l1 0.9088324151412831
l2 0.9088324151412831
rf 0.9793851075173272
gb 0.975475386529234**
转到测试数据,我们将:
- 计算精度;
- 打印混淆矩阵并计算精度,调出和F1-得分;
- 显示 ROC 并计算 AUROC 分数。
准确性衡量正确标记的预测的比例,但它不适用于不平衡的数据集,例如垃圾邮件过滤(垃圾邮件与非垃圾邮件)和医疗测试(生病与未生病)。例如,如果我们的数据集只有 1%的员工满足目标 = 离开,那么一个总是预测该员工仍在该公司工作的模型将立即获得 99%的准确率。在这些情况下,精确或召回更为合适。你经常使用哪一个取决于你是想最小化类型 1 错误(假阳性)还是类型 2 错误(假阴性)。对于垃圾邮件,类型 1 错误更糟糕(一些垃圾邮件是可以的,只要你没有意外过滤掉一封重要的邮件!)而第二类错误对于医学测试来说是不可接受的(告诉别人他们没有患癌症是一场灾难!). F1 分数通过对精确度和召回率进行加权平均,让你两全其美。
ROC 下的面积,被称为 AUROC 是分类问题的另一个标准度量。这是对分类器区分类别和从噪声中分离信号的能力的有效测量。这种度量对于不平衡数据集也是稳健的。
下面是生成这些分数和图表的代码:
for name, model in fitted_models.items():
print('Results for:', name)
# obtain predictions
pred = fitted_models[name].predict(X_test) # confusion matrix
cm = confusion_matrix(y_test, pred)
print(cm) # accuracy score
print('Accuracy:', accuracy_score(y_test, pred))
# precision
precision = cm[1][1]/(cm[0][1]+cm[1][1])
print('Precision:', precision)
# recall
recall = cm[1][1]/(cm[1][0]+cm[1][1])
print('Recall:', recall)
# F1_score
print('F1:', f1_score(y_test, pred))
# obtain prediction probabilities
pred = fitted_models[name].predict_proba(X_test)
pred = [p[1] for p in pred] # plot ROC
fpr, tpr, thresholds = roc_curve(y_test, pred)
plt.title('Receiver Operating Characteristic (ROC)')
plt.plot(fpr, tpr, label=name)
plt.legend(loc='lower right')
plt.plot([0,1],[0,1],'k--')
plt.xlim([-0.1,1.1])
plt.ylim([-0.1,1.1])
plt.ylabel('True Positive Rate (TPR) i.e. Recall')
plt.xlabel('False Positive Rate (FPR)')
plt.show()
# AUROC score
print('AUROC:', roc_auc_score(y_test, pred))
逻辑回归(L1 正则化):
**Output:
[[2015 126]
[ 111 562]]
Accuracy: 0.9157782515991472
Precision: 0.8168604651162791
Recall: 0.8350668647845468
F1: 0.8258633357825129
AUROC: 0.9423905869485105**
逻辑回归(L2 正则化):
**Output:
[[2014 127]
[ 110 563]]
Accuracy: 0.9157782515991472
Precision: 0.8159420289855073
Recall: 0.836552748885587
F1: 0.8261188554658841
AUROC: 0.9423246556128734**
渐变增强树:
**Output:
[[2120 21]
[ 48 625]]
Accuracy: 0.9754797441364605
Precision: 0.9674922600619195
Recall: 0.9286775631500743
F1: 0.9476876421531464
AUROC: 0.9883547910913578**
随机森林:
**Output:
[[2129 12]
[ 45 628]]****Accuracy: 0.9797441364605544
Precision: 0.98125
Recall: 0.9331352154531947
F1: 0.9565879664889566
AUROC: 0.9916117990718256**
获胜的算法是 AUROC 为 99%、F1 得分为 96%的随机森林。这种算法有 99%的几率区分出左和受雇的工人……相当不错!
在测试集中的 2814 名员工中,算法:
- 正确分类 628 个左工人(真阳性,同时得到 12 个错误(I 型错误,以及
- 正确分类的 2129 个雇佣的工人(真否定),同时得到 45 个错误(第二类错误)。
仅供参考,这里是获胜随机森林的超参数,使用 GridSearchCV 进行了调整。
RandomForestClassifier(bootstrap=True,
class_weight=None,
criterion='gini',
max_depth=None,
max_features=0.33,
max_leaf_nodes=None,
min_impurity_decrease=0.0,
min_impurity_split=None,
min_samples_leaf=1,
min_samples_split=2,
min_weight_fraction_leaf=0,
n_estimators=200,
n_jobs=None,
oob_score=False,
random_state=123,
verbose=0,
warm_start=False
)
4.2 特性重要性
考虑下面的代码。
coef = winning_model.feature_importances_
ind = np.argsort(-coef)for i in range(X_train.shape[1]):
print("%d. %s (%f)" % (i + 1, X.columns[ind[i]], coef[ind[i]]))x = range(X_train.shape[1])
y = coef[ind][:X_train.shape[1]]plt.title("Feature importances")
ax = plt.subplot()
plt.barh(x, y, color='red')
ax.set_yticks(x)
ax.set_yticklabels(X.columns[ind])
plt.gca().invert_yaxis()
这将打印按重要性排序的特性列表和相应的条形图。
**Ranking of feature importance:
1\. n_projects (0.201004)
2\. satisfaction (0.178810)
3\. tenure (0.169454)
4\. avg_monthly_hrs (0.091827)
5\. stars (0.074373)
6\. overworked (0.068334)
7\. last_evaluation (0.063630)
8\. slackers (0.028261)
9\. overachiever (0.027244)
10\. workaholic (0.018925)
11\. justajob (0.016831)
12\. unhappy (0.016486)
13\. underperformer (0.006015)
14\. last_evaluation_missing (0.005084)
15\. salary_low (0.004372)
16\. filed_complaint (0.004254)
17\. salary_high (0.003596)
18\. department_engineering (0.003429)
19\. department_sales (0.003158)
20\. salary_medium (0.003122)
21\. department_support (0.002655)
22\. department_IT (0.001628)
23\. department_finance (0.001389)
24\. department_management (0.001239)
25\. department_Missing (0.001168)
26\. department_marketing (0.001011)
27\. recently_promoted (0.000983)
28\. department_product (0.000851)
29\. department_admin (0.000568)
30\. department_procurement (0.000296)**
员工流失有三个特别强的预测因素:
- n_projects (工作量)
- 满意度(幸福感)和
- 任期(经验)。
此外,这两个工程特性在特性重要性上排名也很高:
- 明星(高幸福&工作量),以及
- 劳累过度(低幸福感&高工作量)。
有趣,但并不完全令人惊讶。明星们可能为了更好的机会而离开,而过度劳累的人则在筋疲力尽后离开。
5.部署
图片由 ThisisEngineering RAEng 提供。
此模型的可执行版本(。pkl)可以从 Jupyter 笔记本中保存。
with open('final_model.pkl', 'wb') as f:
pickle.dump(fitted_models['rf'].best_estimator_, f)
人力资源可以在将新员工数据输入训练模型之前对其进行预处理。这被称为批量运行。
在大型组织中,他们可能希望通过与数据工程师和机器学习工程师合作,将模型部署到生产环境中。这些专家围绕我们的模型建立了一个自动化的管道,确保新的数据能够得到预处理,并定期向人力资源部门报告预测。
最终意见
我们从一个业务问题开始:一家大公司的人力资源想要对他们的员工流失有可操作的见解。
我们在包含超过 14,000 名过去和现在员工的大量历史数据上训练了一个获胜的随机森林模型。
人力资源部可以在我们训练有素的员工身上运行新数据。pkl 文件,或者可以由他们的工程部门构建自动管道。
我们的模型是二元分类模型,其中目标变量是分类的。它预测了一系列不连续的可能性——这里是流失或不流失。
监督学习硬币的另一面是回归模型,其目标变量是数值。在这里,我训练了一个预测房价的。
最后,我在这里写了一篇关于机器学习在数学建模领域的位置的文章。
无限制媒体访问
提升你的知识和技能到一个新的水平。
加入 Medium 享受无限制访问互联网上的最佳分析&数据科学文章。你可以在这里加入来支持我和其他顶级作家。
我的数据科学文章
- 微分方程与机器学习——这里这里
- 新冠肺炎的数学建模与机器学习— 此处
- 用回归预测房价— 此处
- 分类预测员工流失— 此处
- 流行的机器学习性能指标— 此处
- Jupyter 笔记本与 Dataiku DSS — 此处
- Power BI —从数据建模到令人惊叹的报告— 此处
基于深度学习的风能交易——时间序列预测
用人工智能预测风能发电量
本文由 罗萨娜·德奥利维拉·戈麦斯 代表 Deep Delve 团队为 AI4Impact 深度学习 Datathon 2020 。
来源: Unsplash 。
问题简介
如今,世界比以往任何时候都更需要合作,以实现应对气候危机的清洁能源解决方案。自 2015 年以来,联合国所有会员国通过的可持续发展目标旨在确保到 2030 年所有人都能获得负担得起、可靠、可持续的现代清洁能源。清洁能源来自大自然提供的可再生资源,如太阳、风、潮汐和海浪、地热等。其用途从大规模发电和离网发电(农村和偏远地区)[1]到加热/冷却系统和运输。然而,太阳能和风能等可再生能源依赖于天气,比传统能源更不稳定。随着世界上许多国家可再生能源供应份额的增加[2,3],保证这些清洁能源在替代化石燃料能源的同时提供稳定的供应是非常重要的。
在 AI4Impact 深度学习 Datathon 2020 中,利用深度神经网络研究了清洁能源的话题。在挑战的第一部分,团队使用 Kaggle 数据集预测能源需求,该数据集包含来自 PJM 互联有限责任公司的超过 10 年的每小时能源消耗数据。你可以在下面的视频中查看 team Deep Delve 对该项目的第一部分的一些见解。
挑战的第二部分致力于预测风能以最大化交易利润。与太阳能一起,风能是最重要的可再生能源之一,2018 年提供了全球电力供应的 4.8%[4,5],2019 年占欧洲电力消耗的 15%[6]。风能是由风力涡轮机产生的机械能产生的。因为风的强度随着时间的推移而变化,并且可能间歇性地停止吹动,所以由这种来源产生的电力通常与其他电源结合,以提高可靠性和稳定性。
通过考虑不同类型的能源公司之间的交易,可以理解风能的经济性。地区或国家能源公司从能源生产商那里购买预定数量的能源(以千瓦时计量),这些能源生产商是经营风力农场的公司(就风能而言)。由于人们期望从电网获得稳定的能源供应,在停电的情况下,能源生产商可能会被政府处以巨额罚款。
能源贸易公司通过帮助预测预期的能源产量(特别是在风力作为不稳定能源的情况下),在评估能源交易中短缺的风险方面发挥重要作用。能源交易商代表能源生产商预测能源产量(在我们的例子中是风能),考虑两种情况:
- 如果短缺低于预测值,则在现货市场上购买能源供应给电网(价格高于平均能源价格)
- 在超出预测产量的情况下,能源生产商不会因为额外的能源而得到补偿。
从这个意义上说,对发电量的精确预测对风电场(即风能生产商)的财务表现起着至关重要的作用。
问题陈述
风能高度依赖于风速等环境因素。对于能源贸易商来说,成功预测风能产量以实现利润最大化至关重要。通过将深度学习应用于金融风险,我们的目标是为法兰西岛地区制作一个领先时间为 18 小时、分辨率为 1 小时的风能预测模型。目标是实现一个模型,优化风电场的利润,最小化能源生产的过剩短缺。
方法学
为了评估我们的风能模型表现如何,我们估计了与实际产生的能量相比,该模型将实现多少货币利润。在交易周期之后的评估期内,使用真实数据对模型进行测试:
- **热身:**前 18 个小时不进行交易(从 2020 年 7 月 22 日 00:00 UTC 开始)。
- **交易时段:**每小时生成一次未来 18 小时(T+18)的风能预报,包括周末、公共节假日,24/7(2020 年 7 月 22 日 18:00 UTC 开始)。
- 交易在评估期结束时结束(2020 年 7 月 28 日 23:00 UTC)。
财务绩效分析遵循之前讨论的交易方法,具体如下:
- 能源价格(千瓦时): 10 欧分。
- **每天销售的最大电能(kWh)😗*当天的最大预测。
- **能源生产过剩:**能源生产商不会因产生额外的能源而得到补偿。
- **能源短缺:**从现货市场购买能源(20 欧分/千瓦时)。可购买的能源数量取决于手头的现金,并且只有在有正结余时才有可能。
- 初始现金储备: 10,000,000 欧分,用于购买能源差额短缺情况。该金额将在评估结束时返回。
- **债务(累计)😗*如果手头可用现金少于购买所需,则处以每千瓦时 100 欧分的罚款。这被记录为负值,并添加到手头现金。
数据集
该项目的目标是预测巴黎周围的法兰西岛地区的总风能产量。风能生产的数据来自法国能源传输管理局电力运输网络 (RTE)。数据集energy-ile-de-france
包含来自 RTE 在线数据库的近实时风力产量,遵循以下规范:
- 从 2017 年 1 月 1 日 00:00 UTC 开始到现在,以一个 1 小时的时间戳表示的发电量(kWh)。
- 该地区 8 个主要风电场的风力预测数据(见下表),来自 Terra Weather 提供的 2 个不同的风力模型(16 个预测)。
- 因变量:风速(米/秒)和风向(北纬度——例如,45 度的风向意味着风从东北方向吹**)。预测每 6 小时更新一次,并以 1 小时为基数进行插值。风速和风向的所有值都是根据模型估算的。**
表 1:项目中使用的法兰西岛地区 8 个主要风力发电场的信息。
探索性数据分析
在进入深度学习模型之前,我们需要首先从数据中提取见解,并进行数据准备工作。数据提取和建模由 Terra AI 在整个比赛中使用的 Autocaffe 平台内用 Smojo 编程语言实现。
统计和标准化
我们从获取数据集中风能的描述性统计数据开始分析,如表 2 所示。我们强调数据是直接从 Autocaffe 中提取的,并且已经进行了插值,因此不包含任何缺失值。
下一步是对数据进行归一化,以使所有特征具有相似的取值范围。这一步对于避免网络偏向具有更高值的特征以及加快学习过程非常重要。所有特征标准化为零平均值和单位标准偏差,遵循以下方程:
其中,Xnorm 是归一化输入要素的值,Xmean 是 X 的平均值,stddev 是标准偏差。
在处理预测时,定义一个可以衡量模型预测与获得的真实值(实际值)相比有多好的度量标准是很重要的。处理时间序列时的另一个重要概念是持续性,基本上是假设一个量在现在的观测值在未来(T+X = T+0)将是相同的。持久性是一个微不足道的预测模型,因此,任何可信的时间序列模型必须至少击败持久性值。
假设一个平均绝对误差(MAE)度量,我们为我们的数据集确定了 0.65 的持久性,这是我们的模型必须克服的第一个基准。
表 2:风能的描述性统计。
风能时间序列
我们使用图 1 和图 2 的箱线图,从多年来风能产量的可视化开始我们的时间序列分析。在该可视化中,一个框对应于每年数据的 50%,每个框内的水平线对应于中值,触须(距框的范围)对应于最大值和最小值(不包括异常值),最后圆圈对应于异常值(1.5 倍框=距框的距离)。
图 1:2017 年和 2019 年法兰西岛风能产量(标准化)的箱线图。
从图 1 中,可以看出多年来风能产量的增加。这种普遍增长可能与法国政府对其整体风能生产的更多投资有关。这可能是通过风电场容量的增加或风电场自身数量的增加而发生的,如表 1 所示,2019 年安装了 Angerville 1 和 2 号风电场[7,8]。
如果我们随着时间的推移提高我们分析的分辨率,并将重点放在 2019 年,例如,我们可以从图 2 中看到,在 3 月和 9 月至 12 月期间,能源产量的范围更广。同样,从 4 月到 8 月,能源产量也有所下降,这表明可能存在季节相关性。
图 2:2019 年几个月法兰西岛风能产量(标准化)的箱线图。
箱线图有助于理解分布情况。现在查看图 3 中 2018 年几个月的类似能源分析,我们可以更好地可视化风能生产的年度行为。为了更容易理解,我们用橙色圆点突出显示了每日平均值。从橙色曲线可以看出,一月是风能产量最高的月份,八月是风能产量最低的月份。随着时间的推移,在其他年份也发现了类似的行为。该信息稍后用于为我们的模型优化生成新特征。
图 3:月平均能量重采样
图 Guitrancourt(纵轴)一月份的风速(横轴)。
风速和风向
在确定了一些关于风能生产随时间变化的见解后,我们现在可以研究我们的数据集中可用的特征。
我们有法国岛 8 个不同风电场的风速和风向,总共有 16 个初始特征。
图 5:一月份 Guitrancourt(纵轴)的风向(横轴)。
图 5 和图 6 分别显示了 2019 年 1 月 Guitrancourt 风电场的风速和风向。从这两个特征的时间序列行为中似乎看不到清晰的见解。
在这项分析中,我们选择了 2019 年,因为这一年所有的风力发电场都可用。在调查我们的数据集中的其他 7 个风电场时,发现了类似的行为。
图 6 显示了 2019 年 1 月同期的发电量在图 3 中的放大。查看我们数据中可用的区域和整个时间段,我们现在可以将发电量峰值和谷值与风速和风向行为进行比较(图 4 和图 5)。尽管在发电量和风向之间任何关联似乎都是清楚的,但是随着时间的推移,我们看到了发电量和风速的类似模式。
图 6:2019 年 1 月(横轴)各天的风能产量(纵轴)。
为了进一步研究这种相似性,图 7 显示了我们的数据中所有区域和整个时间内所有风速和风向特征之间的皮尔逊相关图。在该图中,较高的值(红色)表示较强的相关性,而较低的值(白色)表示较弱的相关性。结果表明,风向和能量之间没有直接关系,但与所有风电场的速度有明显和强烈的相关性。可以识别相同农场的风速和风向之间的较弱相关性,而不需要显著的相关性分数。
图 7:初始特征之间的皮尔逊相关性。
最后,我们可以看看图 8 中的风特征分布。显示了 4 个风电场的风速直方图(左)和风向直方图(右)(所有风电场呈现相似的曲线)。我们可以看到,特征的分布不遵循高斯分布,因为风速的峰值向左移动,并且风向具有两个峰值。这表明使用平均绝对误差指标更适合模型评估,这将在下节课中讨论。
图 8:2017 年和 2019 年法国 4 个风电场的风速和风向分布。
深度学习模型
这个项目的目标是为法兰西岛地区进行风能预测。时间序列预测是用神经网络和深度学习解决的常见问题。您可以点击查看 tome 系列车型的概述,点击查看预测主题。
我们从基本的神经网络模型开始建模任务,后来通过添加不同的特征和参数来增加其复杂性。
特征工程
考虑到数据已经标准化并为训练和测试而设置,我们继续进行特征工程阶段,在该阶段,我们研究了对原始特征的可能修改或组合,以提高模型的性能。我们不再将特定风电场的单一风向作为一个特征,而是寻找与确定发电量相关的更具洞察力的特征。
根据 EDA 会话中的讨论,最佳性能模型中使用的最终功能集如下:
- **空间平均特征:**风速(所有风电场坐标)、方向(所有风电场坐标)、风速矢量和风向矢量。
- **时间特征:**UTC 早上 6 点开始的小时数,1 月开始的月数,4 月开始的月数,季节。
- **加权标称特性:**当前风速除以标称速度 12m/s,再乘以标称功率输出(见表 1),得出所有风电场位置和所有矢量的平均值。
差分模型
在处理时间序列时使用差分模型对于减少数据中的噪声而不改变最大值和最小值是极其重要的。此外,差异有助于捕捉更多关于变量随时间变化的行为的见解。为此,我们对以下时间窗口的变量进行了平均:
- 过去 24,48,72 小时,
- 上周,过去两周(14 天),
- 差异 18 小时(交易提前期):t36、t18、t0
最后,我们还通过引入 动量 和力考察了高阶时间贡献对发电量预测的影响。动量(m)和力(f)有助于提供更多关于时间速率随时间变化的信息。对于时间相关变量 s ,独立变量 x, a 时间 t 和时间步长 h ,动量和力定义如下:
s(t) = x(t) +x(t-h),
m(t) = s(t) -s(t-h),
f(t) = s(t)-2s(t-h) +s(t-2h)。
动量和力是使模型预测和实际值之间的滞后最小化的重要量。鉴于其他特征来自风力模型,我们仅针对风能生产进行了分析。
神经网络
在对数据进行分析和预处理后,我们在最后一次会议中为我们的模型确定了有见地的新特性。现在我们终于可以建立我们的神经网络模型了。首先,考虑到数据的非高斯行为,我们已经从数据行为中发现 MAE 度量更合适。我们还确定了几个新的特征作为神经网络的输入。
在处理输入特征时,如果某些输入特征与问题不相关,则总是存在向网络添加噪声或使学习过程变慢的风险。为此,我们使用 输入缩放 以便只选择相关特征来训练我们的神经网络。
输入缩放是减少噪声以及神经网络中异常值影响的一种强有力的方法。该方法包括将输入特征乘以(正)比例因子,让网络学习哪些是相关的,作为模型训练的一部分。缩放输入后,输入可进一步被箝位,其值为 tanh 。
另一种重要的降维方法是一种称为 自动编码器 的无监督学习技术。该方法由一个子网组成,该子网对瓶颈网络中的输入特征进行压缩和解压缩,从而识别输入特征之间可能的相关性。更多话题见这里。
为了找到我们的预测模型的最佳执行配置,在几个参数下研究了上述所有方法。类似地,我们测试了几种神经网络架构,尝试了不同的层数、层大小、激活函数、优化器和退出正则化概率。
最佳性能配置的得分为 0.48 ,比 MAE 指标的持久性高出 26 %。下面的表 3 总结了所使用的具体参数和架构(表中没有提到输出层),我们将在下一节课中讨论。
表 3:最佳性能模型。
结果
图 9 和图 10 分别显示了自动编码器和主神经网络的训练和测试损失。结果表明,尽管模型能够战胜持久性,但与训练相比,测试损失仍然很高,这表明网络面临学习挑战。正如在整个项目中所了解到的,高测试损耗可能来自过大的网络和/或数据中过多的噪声。让我们继续思考这个问题。
图 9:作为 autoencoder 迭代函数的训练和测试损失(纵轴)。
图 10:作为模型迭代函数的训练和测试损失(纵轴)。
从损失结果中,人们可以预期该模型的性能不会特别好。然而,如果我们现在查看图 11 中滞后相关性的结果,我们发现了非常好的结果。这里,重要的是回来理解项目的目标:从能源生产预测中获取最大利润。正如本文开头的交易方法中所述,每当模型预测不足时,交易者就会亏损。从这个角度来看,获利最多的模型是能够更好地预测时间序列中的波峰和波谷的模型,但不一定在整个时间序列中都具有高精度,这是有道理的。
训练和试验数据的滞后相关性。
从这个意义上来说,在这个优化分析中所做的是将滞后相关性优先于损失,以使利润最大化。根据采用时间序列预测的问题,逻辑可能不同,例如在离群值不重要的情况下。
最后,我们在图 12 中显示了实际值与训练值以及实际值与测试预测值。在两种情况下都可以看到清晰的线性关系,表明模型的预测良好,并且模型实际上是在学习而不是记忆训练数据。如上所述,模型被优化以最小化滞后相关性,因此确定了更广泛的线性行为。这是我们模型定制方式的直接结果。
图 12:实际数据与训练(左)和测试(右)预测的对比。
摘要
在这个项目中,我们为法国的风能预测训练了一个神经网络模型。这个模型后来被应用于在几天的时间内最大化风能交易者的真实数据的利润。在评估期间,根据产生的利润对不同团队的模型进行了比较。
通过数据马拉松学到的重要知识包括:
- 领域知识对于识别风能预测的相关特征至关重要,
- 详细的数据分析可以帮助洞察特征工程和参数选择,
- 数据预处理对于模型的良好性能至关重要,
- 降低噪声是时间序列分析的一个关键组成部分。
由团队 Deep Delve 实现的模型是一个神经网络,它预测风能产量,并能够为能源交易商和生产商产生合理的利润。该模型可能的改进包括更多关于参数调整和神经网络架构的实验,以及更先进的深度学习技术,如递归神经网络——以在时间序列问题中表现良好而闻名。工程分析更深层次特征也可以导致风能预测新重要因素,这些因素在本项目中没有考虑,例如海拔高度,甚至气候变化影响。
使用深度学习来理解时间序列具有很高的范围和影响许多其他领域的潜力,例如识别随时间传播的疾病(医疗保健、经济、销售、股票市场等)。特别是在可再生能源领域,它还可以用于预测能源需求和消费。
请点击下面的链接查看我们的简短演示:)
我们要感谢 AI4Impact 组织了这次有见地的数据马拉松,并为所有参赛者提供了学习更多关于时间序列预测、神经网络和可再生能源的机会。
深究团队: 程诺仪张小溪罗萨娜·德奥利维拉·戈麦斯斯胡阿德·奥贡塔约 瓦莱丽·科·易慧**
更多参考
[1] 可再生能源技术。世界能源评估(2001 年)
[2] “可再生能源领先的 12 个国家”。点击能量
[3]《2018 年 6 月可再生能源发电量及发电量统计》。互联网存档方式回机
[4] 世界能源统计回顾。 bp
[5]《2018 年全球装机量》。全球风能委员会
[6] 丹麦风力发电新破纪录年。能源网
这就是欧洲为可持续的绿色未来铺平道路的方式。我们论坛
这些国家正在引领向可持续能源的转变。我们论坛
窗口函数和 SQL 的其他概念
带 PostgreSQL 的 Sql 教程
用 SQL 开发您解决问题的技能
由菲利克斯·杜布瓦-罗伯特在 Unsplash 上拍摄的照片
简介
在我的教程的最后一部分,我们将看到窗口函数的效用和 SQL 的其他概念,它们允许为我们的问题找到解决方案。
正如在前一部分中,我将使用为名为太空漫游的虚拟公司建造的 ERD。
我的教程的第二部分解释了这个图的结构,你可以在这里找到。
现在,我们可以从我的 SQL 教程的最后一部分开始。
作者图片
第一部分:窗口功能
假设您希望有一个表,允许将每部电影的销售价格与特定国家的平均价格进行比较。显然第一件要做的事是将表与区域、卖家、电影和**订单连接起来。**之后,我们可以使用我们的窗口功能。所以:
WITH sub AS (SELECT a.country, o.amt_euro
FROM area AS a
JOIN seller AS s
ON a.id = s.area_id
JOIN movies AS m
ON s.id = m.id_seller
JOIN orders AS o
ON m.id = o.id_movie)SELECT country, amt_euro,
avg(amt_euro::numeric) OVER (PARTITION BY country)
FROM sub;
出局:
作者图片
正如你在上面看到的,我没有对电影的价格进行求和,而是做了一个分组,我报告了每个价格在一个特定国家的平均价格。这样一来,我们可以即时看到一部电影的价格是超过还是低于我们要考虑的国家的平均价格。
第二部分:右侧、长度和 Strpos
假设我们需要知道邮件列表中每封邮件的域。在这种情况下,我们可以使用以下函数: Right,Length 和 Strpos 。
SELECT email,
RIGHT(email, LENGTH(email) — STRPOS(email,’.’)) AS domain
FROM mailing_list;
出局:
作者图片
正如你所观察到的,每封邮件我们都有自己的域名。事实上,右函数帮助我找到了我想要的值,相反,长度和 Strpos 之间的差值确定了我想要从右边拉出的字符数。 Length 函数显示每行电子邮件的长度, Strops 显示圆点前的电子邮件长度。
第三部分:串联
我们决定对销售者表进行反规范化,以便拥有一个包含名字和姓氏的唯一列。为此,我们可以使用一个简单的连接。
我们可以使用两种不同的技术。
第一个技巧:
SELECT first_name, last_name,
CONCAT(first_name,’ ‘,last_name) AS name
FROM seller;
第二个技巧:
SELECT first_name, last_name,
first_name||’ ‘||last_name AS name
FROM seller;
出局:
作者图片
结论
感谢我在我的教程的所有部分中向您介绍的概念,现在您已经对如何应用 SQL 有了一个大致的了解,并开始提高处理越来越复杂问题的技能。
在 ETL 过程中,数据以杂乱的形式出现在我们面前,数据工程师或数据分析师的目标是规范化数据,并创建一个架构,以满足使用这些数据的不同部门的需求。这是数据分析师或数据工程师面临的基本挑战之一。
此外,通过创建或使用一家公司的数据仓库架构,您将拥有一个企业不同流程的全景,换句话说,您的眼睛将无处不在。这是深入研究一家公司的绝佳机会。
我发出一份期刊简讯。如果你想加入,请通过此链接注册。
除了我的简讯之外,还可以在我的电报群 初学数据科学 中取得联系。
熊猫的窗口功能
运行总计、期初至今回报和其他有趣的东西
QL 有一个简洁的功能,叫做窗口功能。顺便说一句,如果你正在寻找一份数据分析师的工作,你肯定应该知道如何在 SQL 中使用这些。熊猫(带一点跑腿)让我们可以做同样的事情。让我们看看怎么做。
但是首先,什么是窗口函数?
窗口函数允许我们对给定行的数据和指定行数之外的另一行的数据执行操作— 这个“行数之外的值”被称为窗口。
例如,假设您有 10 天的股票价格:
Windows 操作系统
窗口函数允许我们在指定列的值之间执行计算。例如,我可能想要比较今天的股票价格和昨天的价格,然后我想要一个“1”的窗口向后看。窗口函数允许我们这样做。另一方面,如果我想将今天的价格与一年前的价格进行比较,那么我会想要一个“356”的窗口(假设周末在您的数据集中)。
窗口函数对于时间序列数据特别有用,在这种情况下,在数据的每个时间点,您只需要知道该点发生了什么(不允许使用水晶球)。好消息是熊猫有 windows 功能,而且非常好用。
使用熊猫执行窗口计算
假设我们想计算股票价格的每日变化。为此,我们需要将每天的价格除以前一天的价格,然后减去 1。我们以列表的形式获取数据:
stock_list = [100, 98, 95, 96, 99, 102, 103, 105, 105, 108]
列表在数学上不是很友好,所以我们可以把数据放在一个 numpy 数组中(我把它改造成一个 9 乘 1 的数组,这样更容易查看和显示):
**In:**
stock_array = np.array(stock_list)
(stock_array[1:]/stock_array[:-1] - 1).reshape(-1,1)**Out:** array([[-0.02 ],
[-0.03061224],
[ 0.01052632],
[ 0.03125 ],
[ 0.03030303],
[ 0.00980392],
[ 0.01941748],
[ 0\. ],
[ 0.02857143]])
太好了,我们拿到回报了。不需要数据帧,对吗?不完全是。Dataframes 比 numpy 数组更加通用(numpy 数组针对处理数值数据进行了优化)。熊猫的开发者创造了所有这些漂亮的窗口方法让我们的生活更容易——如果我们不利用它们,他们会很难过。
让我们把我们的股票价格放入一个数据框架中:
stock_df = pd.DataFrame(stock_list, columns=['price'])
我们可以使用 shift 方法获得前一天的价格。shift 方法非常类似于 SQL 的 lag 函数。“1”告诉它滞后一天,给出前一天的价格:
stock_df['prev_price'] = stock_df.shift(1)
现在 stock_df 看起来是这样的:
price prev_price
0 100 NaN
1 98 100.0
2 95 98.0
3 96 95.0
4 99 96.0
5 102 99.0
6 103 102.0
7 105 103.0
8 105 105.0
9 108 105.0
酷,现在我们只需要用 price 除以 prev_price,然后减去 1,就可以得到日收益率:
**In:**
stock_df['daily_return'] = stock_df['price']/stock_df['prev_price']-1
print(stock_df)**Out:
** price prev_price daily_return
0 100 NaN NaN
1 98 100.0 -0.020000
2 95 98.0 -0.030612
3 96 95.0 0.010526
4 99 96.0 0.031250
5 102 99.0 0.030303
6 103 102.0 0.009804
7 105 103.0 0.019417
8 105 105.0 0.000000
9 108 105.0 0.028571
现在是有趣的部分
我们能做的不仅仅是计算回报。例如,假设我们想要将我们的每日回报与一个扩展窗口的平均回报进行比较,以查看每个回报与历史平均回报的比较情况。您可能会想,为什么不计算每日 return_column 中所有值的平均值并使用它呢?答案是数据泄露。
在时间序列分析中,当我们试图预测未来时,我们需要非常小心在特定日期观察到了什么,观察不到什么。例如,在数据集的第 5 天,我们只能观察到前 5 个价格:100、98、95、96、99。因此,如果我们为了预测第 6 天而测试特性,我们不能将第 5 天的 3.03%的回报率与整个期间的平均每日变化进行比较,因为在第 5 天,我们还没有观察到第 6 天到第 9 天。
扩展和滚动窗口
这就是一个扩展窗口出现的原因。如果你不熟悉展开和滚动窗口,下面的图片形象地展示了它们是什么。使用扩展窗口,我们以扩展的方式计算指标——这意味着我们在计算中包括了到当前行为止的所有行。滚动窗口允许我们在滚动的基础上计算指标 —例如,滚动(3)意味着我们使用当前观察以及之前的两个观察来计算我们想要的指标。
扩展与滚动窗口
使用扩展窗口背后的基本原理是,随着每一天的过去,我们会得到另一个价格和另一个每日变化,我们可以将它们添加到均值计算中。这是我们应该在计算指标中捕捉的新信息。我们可以用下面的代码做到这一点(为了好玩,我还加入了一个 3 天的滚动窗口)。
stock_df['expand_mean']=stock_df['daily_return'].expanding().mean()
stock_df['roll_mean_3']=stock_df['daily_return'].rolling(3).mean()
呼唤**。在 pandas 数据帧或系列上展开()创建 pandas 展开对象。这很像更广为人知的 groupby 对象(基于指定的列标签对事物进行分组)。扩展(或滚动**)对象允许我们以扩展的方式计算各种指标。让我们看看我们的数据帧现在是什么样子:
price prev_price daily_return expand_mean roll_mean_3
0 100 NaN NaN NaN NaN
1 98 100.0 -0.020000 -0.020000 NaN
2 95 98.0 -0.030612 -0.025306 NaN
3 96 95.0 0.010526 -0.013362 -0.013362
4 99 96.0 0.031250 -0.002209 0.003721
5 102 99.0 0.030303 0.004293 0.024026
6 103 102.0 0.009804 0.005212 0.023786
7 105 103.0 0.019417 0.007241 0.019841
8 105 105.0 0.000000 0.006336 0.009740
9 108 105.0 0.028571 0.008807 0.015996
请注意,在第 1 天,expand_mean 和 daily_return 是相等的——这是必然的情况,因为我们计算的是第 1 天只有一个日收益的扩展平均值。此外,在第 3 天,当我们终于有足够的数据来计算我们的滚动 3 天平均值时,roll_mean_3 的第一个值等于 expand_mean。这也是有意义的——在第 3 天,我们的扩展均值也是使用最近 3 天的回报计算的。
这是我们计算的股票日收益和 2 均值的曲线图(和代码):
plt.subplots(figsize=(8,6))
plt.plot(stock_df['daily_return'], label='Daily Return')
plt.plot(stock_df['expand_mean'], label='Expanding Mean')
plt.plot(stock_df['roll_mean_3'], label = 'Rolling Mean')
plt.xlabel('Day')
plt.ylabel('Return')
plt.legend()
plt.show()
股票收益及其扩展均值和滚动三日均值
正天数的累计
除了均值之外,我们还可以应用其他函数。假设我们的老板过来说,“我想让你记录这只股票上涨了多少天。”
我们可以使用一个扩展对象和 sum 方法(用于保存一个运行总数)来实现。首先,我们需要在数据框架中添加一列来表示当天股票是否上涨。我们可以利用应用方法(将函数应用于数据帧或系列中的每一行)。我们可以定义一个函数来给 apply 或者使用 lambda 函数——我选择了一个 lambda 函数(更少的代码行),它接受每个返回,如果是正数则返回 1,如果是负数则返回 0。
stock_df['positive'] = stock_df['daily_return'].apply(lambda x: 1 if x>0 else 0)
一旦我们有了“正”列,我们可以对它应用一个扩展窗口和 sum 方法(因为每个正的一天用 1 表示,我们只需要保存 1 的总数):
stock_df['num_positive'] = stock_df['positive'].expanding().sum()
我们发送给老板的数据帧是这样的:
price daily_return num_positive
0 100 NaN 0.0
1 98 -0.020000 0.0
2 95 -0.030612 0.0
3 96 0.010526 1.0
4 99 0.031250 2.0
5 102 0.030303 3.0
6 103 0.009804 4.0
7 105 0.019417 5.0
8 105 0.000000 5.0
9 108 0.028571 6.0
所以到目前为止,该股有 6 个交易日上涨。但是随着我们收集更多的价格,我们的运行总数将随之更新。很好,我们的老板应该会很高兴。
感谢阅读!干杯,祝大家平安健康。
如果你总体上喜欢这篇文章和我的写作,请考虑通过我在这里的推荐链接注册 Medium 来支持我的写作。谢谢!
视窗,和 Docker,和 Kubernetes 哦,我的天!(2020)
马克西米利安·魏斯贝克尔在 Unsplash 上的照片
我们要讲的内容
在本教程中,我们将涵盖在 Windows 上安装 Docker,启用 Kubernetes,安装 helm,并通过运行机器学习笔记本服务器来测试这一切。然后我们将介绍一些额外的东西,如 docker-compose 和 Visual Studio 代码扩展。
入门指南
首先,我在其中设置的示例环境具有正常的互联网连接(没有复杂的代理配置),并且是一台运行 64 位 Windows 10 Pro 副本的 64 位 PC,具有 4 个内核和 16GB RAM。你至少需要 8GB 的内存和两个内核来运行任何合理的东西。
预装:
- 安装了 Git for Windows(【https://gitforwindows.org/】T4)这给了你 git 命令行工具和 bash shell。非常有用。
下载:
- 用于 Windows 安装程序的 Docker 桌面(https://docs.docker.com/docker-for-windows/install/)
- 车窗头盔(https://github.com/helm/helm/releases)
(来源 Giphy)
赋予 Docker 生命
- 运行 docker for windows install,不要选中“使用 windows 容器…”。
2.选择关闭并重新启动,这将重新启动您的机器,并在 windows 启动时启动 docker。
3.一旦 Windows 重新启动,你会在任务栏上看到一个小的动画 docker 图标,显示 docker 正在启动,这可能需要 20 秒到几分钟的时间。
4.一旦它完成了它的启动程序,你会看到一个欢迎卡。在 windows 上使用 docker 不需要登录并注册 docker。
5.打开一个 bash 提示符(Win 键-> bash -> Enter)。然后,您可以运行 docker hello-world 容器。
$ docker run --rm hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pulling fs layer
1b930d010525: Verifying Checksum
1b930d010525: Download complete
1b930d010525: Pull complete
Digest: sha256:f9dfddf63636d84ef479d645ab5885156ae030f611a56f3a7ac7f2fdd86d7e4e
Status: Downloaded newer image for hello-world:latestHello from Docker!
This message shows that your installation appears to be working correctly.To generate this message, Docker took the following steps:
...<rest of message remove>
hello-world 容器测试将验证:
- Docker 服务已正确安装并运行。
- docker 命令位于您的执行路径中,可以与 docker 服务通信。
- 您有权限运行 docker 命令。
- docker 服务可以通过 docker 容器报告到达 DockerHub。
- docker 服务可以运行容器。
如果一切都出错了呢?(来源 Giphy)
排除故障
docker 安装和运行过程可能有点不稳定,因此您可以通过 Docker 仪表板访问诊断日志。单击故障排除图标,在诊断窗格中,会有一个指向日志文件的链接,该链接将在记事本中打开。
或者可以在“C:\ Users \ User \ AppData \ Local \ Docker”找到
访问诊断日志文件
(来源 Giphy)
与库伯内特斯起航
如果你不知道 Kubernetes(简称 k8s)是什么,也不知道它有什么用途,那么有一个来自 K8s 团队的很好的解释你可以翻阅一下。Kubernetes 在希腊语中是舵手或领航员的意思,因此这个图标是船只的舵手,也是你随处可见的航海主题。windows 上的 K8s 过去设置起来非常痛苦,但现在已经变得容易多了。在启用 k8s 之前,将 docker 可用的 RAM 从默认的 2GB 增加到 4GB 可能是明智的,或者如果您有 8GB 的容量,这意味着它将运行得更快。设置可以在 docker dashboard 中找到,该 dashboard 从任务栏图标启动,并单击 Cog 符号。点击“应用&重启”以使新的内存限制生效。
然后只需点击“启用 Kubernetes”,然后“应用和重启”即可启用 Kubernetes。这将下载并初始化所有的 k8s 容器,这些容器是在本地机器上运行本地 one node k8s 集群所必需的。去冲杯咖啡吧,这可能要花很长时间。如果 15-20 分钟后仍未完成(通常是由于内存不足),重启机器,它应该与 windows 一起启动。您可以使用下面的 kubectl 命令测试 k8s 是否都在运行。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
docker-desktop Ready master 167m v1.15.5
我们来部署一下吧!(来源 Giphy)
抓住舵
正如您可能已经读到的,k8s 非常强大,能够运行巨大的集群并管理大量的资源,但是说得委婉一点,它很难管理。为了帮助解决这个问题,并提供预打包的部署在您的集群上运行,创建了 Helm 项目。一个相对容易使用的 k8s 包管理器。解压你之前下载的 helm 包,找到 helm.exe 文件。这个文件可以添加到您的路径中的任何地方,但我更喜欢将它和所有其他 Docker 命令行工具一起放在“C:\ Program Files \ Docker \ Docker \ resources \ bin”中。
启动示例应用程序
要运行 helm 应用程序,您需要添加 repo,更新索引并安装图表。helm install 通常会在部署信息的末尾给出一些有用的说明,让您连接到新创建的服务。
$ **helm repo add stable** [**https://kubernetes-charts.storage.googleapis.com/**](https://kubernetes-charts.storage.googleapis.com/)
$ **helm repo update**
$ **helm install stable/tensorflow-notebook --generate-name**
NAME: tensorflow-notebook-1584196283
LAST DEPLOYED: Sat Mar 14 14:31:25 202
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1\. Get the application URL by running these commands:
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get svc -w tensorflow-notebook-1584196283'
export SERVICE_IP=$(kubectl get svc --namespace default tensorflow-notebook-1584196283 -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo notebook_url=http://$SERVICE_IP:8888
echo tensorboard_url=http://$SERVICE_IP:6006
图表被发送到 k8s 集群,应用程序被初始化,但这不是即时的。下载容器映像并运行它们需要时间。
图表仍在启动中
舵图试图创建 2 个容器,但它仍然在创建它们。这可能需要一段时间。
图表已启动并运行
Helm 将应用程序列为已部署,即使 pod 尚未准备好。
部署图表后,有时需要使用默认凭据来登录。这些可以在舵图中指定,但也可以自动生成,并且对每个实例都是唯一的。要获得存储在 kubectl secrets 系统中的凭证,您需要使用 secret 命令检索它们。例如
$ **kubectl get secret tensorflow-notebook-<unique_id> -o yaml**
秘密 YAML 的输出
然后可以使用 base64 命令对编码的秘密进行解码。
echo ‘XXXXXXXXXXX==’ |base64 — decode
现在您可以在 http://127.0.0.1:8888 登录您的 k8s 托管机器学习 Tensorflow Jupyter 笔记本服务。和一个 Tensorboard 管理界面 http://127.0.0.1:6006。
Tensorflow Jupyter 笔记本服务器
Tenserflow 仪表板
给自己一个击掌,你有一个令人敬畏的设置(来源 Giphy)
一些有用的附加功能
Docker 撰写
在 k8s 所有花哨的云和企业级工具出现之前,有 docker-compose。目前,这种方法通常不用于部署企业应用程序,但对于以一种更简单、更容易上手的方式处理容器来说,docker-compose 是必不可少的。使用一个超级简单的组合文件,你可以用一个简单的“docker-compose up -d”命令运行一系列服务。
简单的 docker 编写文件
创建一个类似 compose_test 的目录,将上面的代码片段放在一个名为 docker-compose.yml 的文件中,在该目录中运行“docker-compose up ”,您就有了一个正在运行的 web 服务。我 90%的时间使用 docker-compose 进行开发、测试和 POC 部署。对于开发工作来说,理解和使用它要容易得多。
Visual Studio 代码
如果你还没有使用过 Visual Studio 代码,你去过哪里!这是微软的一个优秀的免费轻量级编辑器,它不依赖于 Visual Studio,也不需要 Visual Studio,并且有广泛的语言支持。作为扩展生态系统的一部分,有大量优秀的插件可以与 k8s、helm、Docker 和 compose 文件一起工作。我强烈推荐安装微软的“Kubernetes”和“Docker”扩展。
需要注意的事情(来源 Giphy)
一些警告
Docker for Windows 使用了内置于最新版本 Windows 中的 Hyper-V 虚拟化技术。这是 WSL2 和微软虚拟化服务背后的工具集。直到最近,VirtualBox 一直是在 windows 上进行快速简单虚拟化的最佳选择,如果你想让 Hyper-V 和 VirtualBox 在同一系统上共存,那是不可能的。在 VirtualBox 6.1.x 中,这种限制应该已经消除,您可以使用 Hyper-V 后端运行 VirtualBox。我没有测试过这一点,因此,如果您想要使用现有的虚拟机,它可能不会很好地工作。如果它不起作用,可以通过卸载和禁用 Hyper-V 回滚到 VirtualBox,所以尝试一下也无妨。
后续步骤
- 熟读 Kubernetes(【https://kubernetes.io/】T2)
- 仔细阅读赫尔姆(https://helm.sh/)
- 滚动你自己的码头集装箱(【https://docs.docker.com/get-started/part2/】T2
- 从 Docker compose(【https://docs.docker.com/compose/】)开始
- Visual Studio 代码入门(https://code.visualstudio.com/)
在@ratemyskyperoom 获胜:
由 @ratemyskyperoom 评分的房间(和扬声器)的拼贴画。图片归功于每个拍照的人。
在这个不确定的时代,世界比以往任何时候都更需要有力的数据新闻。这不是那个。
相反,我分析了 1321 条推文来回答一个问题,自从 Zoom 成为我们日常生活的一部分以来,我们许多前往疫情的远程工作者都想知道这个问题: 人们喜欢我的房间吗?!
与动物穿越不同,我们没有权威的浣熊可以依靠,以获得关于我们装饰技巧的客观反馈。
相反,在现实世界中,我们得到的最接近的东西是房间评级( @ratemyskyperoom )。随着越来越多的(名人)通过笔记本电脑镜头展示他们的住宅,房间评级机构已经开始公开地、定量地对他们进行评判。
不是所有的家庭都会在国家电视台播出。至少近期不会。但是我们都同意,当那一天到来的时候,我们希望世界看到我们的房间(或者说,我们的存在)配得上 10/10。
所以我问:“怎样才能让我的房间得到 10/10 分?!"
为了找到答案,我把从 2020 年 5 月到 2020 年 7 月的 1321 条房间评级推文全部拉了下来,分析了评级,然后查看了每条推文的图片和文本内容。
以下是我在数据中发现的关键的、深刻的和激动人心的见解。
(本帖互动版在此: 房间评级统计笔记本 )
所有客房评分的百分比分布( src )。平均评分是 7.5/10。
洞察力#1:获得一个好的评价并不是非常困难。
好消息是:获得高分显然并不难。平均评分是 7.5/10,他们像发糖果一样发 8/10。其实大部分收视率至少都是 8/10。
房间评级员说这是一场艰苦的比赛,但他们内心深处是柔软的。
这个愚蠢的渲染显示了个人 twitter 用户的房间评级变化,在他们的第一次评级和最后一次 ratting ( src )之间。左栏显示的是提高了房间评价的演讲者。右栏显示的是失宠的演讲者。
洞察力#2:第二次机会提供了一条救赎之路(或者没有)
即使你的第一次收视率很低,你总会有下一次电视亮相的机会。至少有 83 人的房间不止一次被评过。
无论你来自斯克兰顿还是芝麻的硬街( @JoeBiden +1、 @elmo +1),无论你是政治家、新闻界、民意调查者还是教授(@ RepKarenBass+2; @marycjordan +3,@ frank luntz+3; @j_g_allen +4),房间评分员愿意给你的房间第二次机会。上面,你可以看到左边的 14 个人在他们第一次和最后一次出现之间至少提高了 3 分。最佳改进奖授予了 @anitakumar01 和 @RosenJeffrey (各+5)。
但是要小心!房费评定者给的,房费评定者拿走。至少有 6 个人在第一次和最后一次评分之间得分更低。不好意思 @pattonoswalt !
房间评级成功的秘诀是什么?
为了理解这一点,我查看了两个来源:房间图像和每条推文的文本。为了分析这些图像,我通过AWS“Rekognition”图像识别 API 运行了每一张图像。为了分析文本,我查看了单个单词的用法(例如,“wu”和“tang”,而不是“wu tang”)。这两种方法都不是特别可靠,但是仍然有一些有趣的发现。
左边是由 @jheil 、 @todrick 和 @Judgenap 的房间评分员发布的 3 张样板间图片。右边是亚马逊的 AWS Rekognition 服务如何标注每张图片。
关于高质量的 skype 房间,图像识别能告诉我们什么?
不多。AWS Rekognition 算法似乎很适合区分大类别的事物,但当图像的范围已经有些狭窄时,这不是很有帮助。上面你可以看到一些样本图像的结果。我希望结果更接近“*嘿,看,@托德里克在墙上有冰淇淋!”*但至少它擅长分辨people
和human
faces
…。
这并不是说它完全没有洞察力。让我们看一个例子。
有或没有动物的房间的等级分布( src )。
洞察力#3:小狗造就伟大的 Skype 房间。
我们的第一个有趣的事实:房间评分员非常喜欢有动物的房间。平均来说,有动物的房间比没有动物的房间得分高 1.2 分。这可能包括动物艺术品,马的雕塑或真实的宠物在人的背景中闲荡。
上面我们有三张图。最左边和最右边标有No Animals
和Animals
的图表显示了没有动物在其中的房间与有动物在其中的房间的评级分布(至少就 AWS 而言)。覆盖在条上的图像包括来自原始推文的图像样本。(如果你去 笔记本这里 你可以点击图表上的图片看动物)
中间标有No Animals v.s. Animals
的图表显示了来自其他两个图表的相同数据,相互重叠。中间的图表还包括底部的小凹口,显示每个分布的平均值(在这种情况下,No Animals
平均为 7.4,Animals
为 8.6)。
有或没有书籍、艺术品或植物的房间的评级分布( src )。
观点 4:已证实:植物、艺术品和书籍有助于打造更好的房间。
这没有什么突破性的,但肯定令人放心。AWS 的算法可以识别植物、艺术或书籍的照片比没有植物、艺术或书籍的房间照片获得了更高的评级。
扬声器为男性或女性的房间的等级分布( src )。
奇数:男性演讲者的房间更经常被评级,但女性演讲者的房间更好。
男性演讲者的评分几乎是女性演讲者的两倍(男性 842 分,女性 425 分),但平均而言,女性的房间更好 0.3 分。(*注意:这里的“男性”和“女性”是基于 AWS 从图像中对人的性别的预测。)
关于挣高分房,@ratemyskyperoom 的书面反馈告诉了我们什么?
从这些照片中没有发现改变生活的启示,但是也许我们可以直接从房间评估员的书面反馈中获得一些见解…
比较反馈中包含摄像机角度或照明语言的房间的评分分布( src )。
洞察力#5。首先,把基本的东西做好。
把基本的东西做好是很重要的。也就是说,正确地调整相机的框架并检查你的照明。当房间评估员的书面反馈提到重构摄像机(比如“重构”、“裁剪”、“摄像机”、“天花板”等词语。)一般是针对评分较低的房间。同时营造出一种“深度感”稳操胜券。
好的照明都差不多。包括“黑暗”或“背光”等词语的反馈是一个不好的信号,所以确保你没有坐在黑暗的中。
对反馈包含多肉植物或兰花词语的房间进行评级分布比较( src )。
洞察力#6。多肉植物不错。兰花更好。
虽然房间评估员很快建议为你的房间买一棵多肉的或任何普通的植物,但他们实际上似乎更喜欢兰花。
对反馈中包含科里·布克或书籍的房间进行比较的评分分布。
洞察力#6。澄清书籍诉 s .布克。
房间评估员批准房间中包含“书籍。“他们不同意房间里有书。(细微差别。)
比较反馈中包含人质或历史词汇的房间的评分分布( src )。
洞察力#7。"历史性的"比"人质"更好。
也许最大的成功因素是了解“人质”和“历史性”之间的区别似乎被绑架还不够糟糕,房间评级对在电视上看到这些受害者颇有微词。值得称赞的是,他们确实为追随者提供了大量的“历史性 Skype 房间”,供观众在设计自己的房间时效仿。
将所有评分与反馈包括菠萝、Elmo、Wu Tang 或 Mid Century ( src )的评分进行比较的评分分布。
洞察力#8。轻松赢得提升客房评级。
最后,如果你在直播前需要一个快速的刺激,那么房间评分员非常喜欢菠萝、埃尔莫和吴唐家族,所以你可以考虑将这些主题融入到你的中世纪现代装饰中,你很快就会得到 10/10 的分数。
外卖:
- 如果你因为世界末日而感到压力,精心制作和无意义的数据探索可能是一种奇妙的应对机制。
- @ratemyskyperoom 成功的秘诀:好的灯光,好的相机取景,植物,艺术,书籍,动物,菠萝,Elmo 和吴唐。如果你不是科里·布克,也没有被扣为人质,这也会有所帮助。
我是谁?不,不,你是谁?!
嗨!我是伊莱·霍德。我帮助客户设计和开发忙碌的人和他们杂乱的数据之间的有效接口。如果你是一名创始人、创客、讲故事者、非营利行善者或商业领袖,正在思考数据、设计和用户心理的交集,我很乐意联系并聆听你的故事。
你可以发电子邮件到 eli@3isapattern.com 的 T2 或者在 T4 的推特上关注我。
在线数据科学黑客马拉松的获奖解决方案
我在 Analytics Vidhya 数据科学黑客马拉松上的获奖解决方案的完整代码
杰佛森·桑多斯在 Unsplash 上拍摄的照片
数据科学黑客马拉松是有抱负的数据科学家的终极战场。任何黑客马拉松的目的都是让你的想象力引导你拓展这个领域的知识和技能。
经过两年的自学,我决定与其他数据科学家一起在实际战场上检验我的技能。所以我决定参加在线黑客马拉松。我决定将网站列入候选名单,并很快选择了 Analytics Vidhya 开始我的黑客马拉松之旅。
我最初的起步不够好。但是我在我的前四个在线黑客马拉松中的一个上得到了前 50 名。
我从中学到的一件重要的事情是不要参加所有可能的黑客马拉松。
重要的是列出一个你想关注的特定的黑客马拉松,并为此全力以赴。不要同时参加多个黑客马拉松,因为每个黑客马拉松都需要适当的时间和努力。
8 月,Analytics Vidhya 发起了数据至上黑客马拉松。
链接到黑客马拉松:https://data hack . analyticsvidhya . com/contest/the-data-supremity/
图片来源:datahack.analyticsvidhya.com/contest/the-data-supremacy/
并且在看了问题陈述之后,我决定参与并尽我所能。为了更容易理解,我将在不同的部分决定解决方案。
问题
黑客马拉松是一个二元分类问题,我们必须根据特定学生的历史背景来预测他是否有资格参加。
数据集大小:
火车造型:(18359,14)
测试造型:(15021,13)
目标:二元分类→ 0/1
给出的特征总数:13 个特征[列]
了解功能
这是几乎每个人都跳过的重要一步。
不要直接跳到写机器学习代码。首先了解问题,以及每个特性的含义。看看你是否能找到特征和目标变量之间的关系。
在对所有特性进行了适当的研究之后,我决定从代码开始。
图书馆
以下是我在整个黑客马拉松中使用的库。
我几乎在任何地方都使用的 3 个基本库。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
注意:我已经包括了比我实际使用的更多的库,来展示我在黑客马拉松中尝试过的所有库。
import xgboost as xgb
from xgboost.sklearn import XGBClassifier,XGBRegressor
import catboost
from catboost import CatBoostClassifier
from sklearn.preprocessing import LabelEncoder , MinMaxScaler
from sklearn.cross_validation import KFold , cross_val_score
from sklearn.metrics import accuracy_score , roc_auc_score,confusion_matrix
from sklearn.grid_search import GridSearchCV
from sklearn import metrics
from sklearn.ensemble import RandomForestRegressor,RandomForestClassifier
from sklearn.neighbors import KNeighborsRegressor,KNeighborsClassifier
from sklearn.svm import SVR
from sklearn.linear_model import LogisticRegression,LinearRegression
from sklearn.ensemble import ExtraTreesClassifier
from sklearn.model_selection import RandomizedSearchCV
数据看起来怎么样?
现在是时候阅读培训和测试 csv 了。
train_data = pd.read_csv('train_FG6BvLg.csv')
test_data = pd.read_csv('test_wovud0B.csv')
print("Train Shape : {}\nTest Shape : {}".format(train_data.shape,test_data.shape))
train_data.head()
我不得不把快照分成两张图片,因为它在一张图片中看不到。
目标列是我们测试文件中要预测的列。
预处理
我总时间的大约 75%用于预处理数据。
我研究了所有的列,想出了预处理它们的所有方法,并得出了最终的预处理代码。
注意:每一列的预处理技术都是不同的,不会在所有地方都相同。
首先,是时候从城市栏中删除文字部分了
城市 _21 → 21
train_city = train_data.city.str.split("_")
test_city = test_data.city.str.split("_")
这将包含一个有 2 个值的列表(前者是“城市”,后者是分配的数字)
i=0
for x in train_city:
train_data.loc[i,'city'] = x[1]
i=i+1
您可以看到所做的更改。我对 test_data 做了同样的事情。
然后我决定检查数据是否包含任何缺失值。
train_data.isnull().sum()
我们需要正确处理这些缺失的值,因为丢弃它们会导致重要信息的丢失。
在我们开始输入缺失值并对它们进行预处理之前,我们将结合训练和测试数据。这将有助于对整个数据集进行相同的更改。
在组合之前,从训练数据中弹出目标列,因为它不在测试数据中。
target = train_data.pop('target')
enrollee_id = test_data['enrollee_id']
combined_data = train_data.append(test_data)
现在是开始进一步预处理的时候了。我将城市列的数据类型从字符串改为整数:
combined_data.city= combined_data.city.astype('int')
我将性别列替换为整数类别:
combined_data.gender.replace({'Male':2,'Female':0,'Other':1},inplace=True)
我对另外两个专栏做了同样的事情:
combined_data.enrolled_university.replace({'no_enrollment':1,'Part time course':2,'Full time course':3},inplace=True)combined_data.major_discipline.replace({'No Major':0,'Other':1,'Arts':2,'Humanities':3,'Business Degree':4,'STEM':5},inplace=True)
列 experience 和 company_size 包含类似于“< 10”和“> 500”和“500–1000”的字符串。这阻止了将列设为整数。
combined_data.experience.replace({'>20':21,'<1':0},inplace=True)
为了说明 company_size 的样子:
combined_data.company_size.value_counts()
combined_data.company_size.replace({'<10':0,'10/49':1,'50-99':2,'100-500':3,'500-999':4,'1000-4999':5,'5000-9999':6,'10000+':7},inplace=True)
company_type 列具有分类值:
combined_data.company_type.value_counts()
我没有给出随机数来替换,而是按照受众的递增顺序来替换。
combined_data.company_type.replace({'Other':0,'Early Stage Startup':1,'Funded Startup':2,'NGO':3,'Public Sector':4,'Pvt Ltd':5},inplace=True)
我还在剩下的专栏中做了一些替换。
combined_data.last_new_job.replace({'never':0,'>4':5,'nan':1},inplace=True)combined_data.relevent_experience.replace({'No relevent experience':0,'Has relevent experience':1},inplace=True)
缺失值怎么办?
我尝试了各种插补法,包括 sklearn 库中的 SimpleImputator。我甚至试着用平均值来表示它们,但是这并不比用 0 来表示它们更好
combined_data.major_discipline.fillna(0,inplace=True)
combined_data.company_type.fillna(0,inplace=True)
combined_data.company_size.fillna(0,inplace=True)
combined_data.enrolled_university.fillna(0,inplace=True)
combined_data['enrolled_university.1'].fillna(0,inplace=True)
因为数据的数值范围不同。在继续我们的模型之前,我决定将数据标准化。
我使用了 MinMaxScaler,它允许我自定义我的最小和最大范围值。
values = combined_data.values
scalar = MinMaxScaler(feature_range=(0,5))
x_scaled = scalar.fit_transform(values)
combined_data = pd.DataFrame(x_scaled,columns=combined_data.columns)
为了转移到我们的模型,我们需要删除 ID 列。
combined_data.drop('enrollee_id',axis=1,inplace=True)
模型
老实说,我尝试了 10 多种算法,看看哪一种有效。
我从 RandomForest 开始到 CatBoost。
clf = CatBoostClassifier(iterations=200,depth=4,eval_metric='AUC',l2_leaf_reg=9,learning_rate=0.1)
但是 XGBoost 优于所有其他算法。所以我坚持用它来创建模型函数:
def model_fit(alg, dtrain, target,dtest):
xgb_param = alg.get_xgb_params()
xgtrain = xgb.DMatrix(dtrain.values, label=target)
cvresult = xgb.cv(xgb_param, xgtrain, num_boost_round=alg.get_params()['n_estimators'], nfold=5,
early_stopping_rounds=50)
#alg.fit(dtrain,target,use_best_model=True,eval_set=(x_val,y_val))
alg.fit(dtrain,target)
print("Model Report")
print("Accuracy is {}".format(alg.score(x_val,y_val)))
feat_imp = pd.Series(alg.feature_importances_,dtrain.columns).sort_values(ascending=False)
feat_imp.plot(kind='bar', title='Feature Importances')
plt.ylabel('Feature Importance Score')
y_pred = alg.predict_proba(dtest)[:,1]
return y_pred
上面的代码片段在一个函数中包含了模型拟合和绘制特性重要性图。
最后是我的模型和它的参数:
clf = XGBClassifier(
learning_rate =0.3,
n_estimators=100,
max_depth=3,
min_child_weight=1000,
gamma=0.7,
subsample=0.45,
colsample_bytree=0.4,
objective= 'binary:logistic',
nthread=1,
scale_pos_weight=1,
seed=27,
reg_alpha =0.7,
random_state=200)
你是怎么得到这些参数的?
我使用了 GridSearchCV 函数,它有助于从输入的参数范围中选择最佳参数。
param_test2 = {
'n_estimators':[150,170,200],
'learning_rate':[0.03,0.05],
'max_depth':[4,10,15,25],
'min_child_weight':[1,2,5,10],
'subsample':[0.5,0.7,1],
'colsample_bylevel':[0.45,0.7,1],
'colsample_bytree':[0.45,0.7,1],
'gamma':[0,0.1,0.5,1]
}
gsearch2 = GridSearchCV(estimator = XGBClassifier(),
param_grid = param_test2, scoring='roc_auc',n_jobs=4,iid=False, cv=5)
gsearch2.fit(x_train,y_train)
gsearch2.grid_scores_, gsearch2.best_params_, gsearch2.best_score_
GridSearchCV 从我们传递的超参数排列中打印出最佳参数。(评分设置为“roc_auc”)
得到合适的超参数后,就该拟合模型了。
y_pred = model_fit(clf,x_train,y_train,test_data)
正如你所看到的,培训时间是使学生合格的最重要的特征,其次是城市发展指数和经验。
等等,我们必须评估我们的模型
我使用 KFold 来评估我的模型,以检查它的有效性。
k_fold = KFold(len(train_data), n_folds=8, shuffle=True, random_state=0)
print(np.mean(cross_val_score(clf, train_data, target, cv=k_fold, n_jobs=1)))
KFold 将提供训练/测试索引,将数据分成训练和测试集。它将把一个数据集分成 k 个连续的折叠。由于模型精度和 kfold 非常相似,因此模型工作正常。
提交
我一共上传了 20 多个投稿文件来提高我的分数,达到巅峰。
submission = pd.DataFrame({'enrollee_id': enrollee_id , 'target': y_pred})
submission.to_csv('submission.csv',index=False)
结果
所有的努力都得到了回报。我在全球 1000 人的黑客马拉松中获得了第三名。以下是排行榜的快照。
图片来源:datahack.analyticsvidhya.com/contest/the-data-supremacy/
我的用户名:jsiddhesh96
代码可以在我的 GitHub 存储库中找到:
[## sid 11/AnalyticsVidhya _ DataSupremacy
比赛链接:(https://data hack . analyticsvidhya . com/contest/the-data-supremity/)我用过 xgb classifier……
github.com](https://github.com/Sid11/AnalyticsVidhya_DataSupremacy)
赢得数据压缩游戏
如何在某些特殊情况下击败世界级的压缩算法
有几种功能强大的数据压缩程序被广泛使用。一些著名的例子有 gzip 、 bzip2 和 pkzip 。最近,我开始思考,如果给定一个要压缩的特定输入文件,我是否可以创建一个优于所有这些程序的算法。
挑战
我决定把它变成自己的游戏。我选择了一个重要的输入文件。然后我在上面用了 gzip,bzip2,zip 压缩。在每种情况下,我都提供了尽可能产生最积极的数据压缩的命令行选项。然后我选择了三个程序输出中最小的字节作为我的目标。我开始编写一个程序,在给定相同的输入文件的情况下,它可以超过这个最小的字节大小。
我希望我的测试输入看起来有用。我不想为了给自己一个优势而设计一些奇怪的输入。我决定使用英文单词的字母列表。从我在网上找到的一个 ASCII 文件开始,我删除了包含除小写字母a
到z
以外的任何字符的所有行。结果是这个文件:https://github . com/cosine kitty/compress game/blob/master/words . txt
这个words.txt
文件由 636946 字节组成,包含 67527 个字,每行一个字。我使用了以下命令来压缩这个文件。所有这些程序都运行在我的 64 位 Debian Linux 系统上。
首先,我从 bzip 版本 1.0.6 开始:
bzip2 -c --best words.txt > words.bz2
然后我用了 gzip 版:
gzip -c --best words.txt > words.gz
最后,我使用了 Info-ZIP 程序,版本 3.0:
zip -9 words.zip words.txt
以下是产生的文件大小:
don@spearmint:~/github/compressgame $ ls -l words.*
-rw-r--r-- 1 don don **248587** Apr 22 15:05 words.bz2
-rw-r--r-- 1 don don **212736** Apr 22 15:05 words.gz
-rw-r--r-- 1 don don 636946 Apr 22 14:49 words.txt
-rw-r--r-- 1 don don **212876** Apr 22 15:05 words.zip
所以在这种特殊情况下,gzip 是赢家。它产生了 212736 字节的输出。那是我要打败的目标。
游戏规则
每个游戏都需要规则。在玩游戏之前固化规则是有道理的。以下是我事先选择的规则:
- 我的数据压缩器的输出是另一个 Python 程序。
- 执行时,生成的 Python 程序必须打印出
words.txt
中包含的精确文本。 - 该程序不得引用任何外部文件。它必须是完全自包含的,并通过算法创建其输出。
- 获胜程序的源代码必须小于 212736 字节。
- 为了更有趣,我决定生成的 Python 程序不能使用任何
import
语句。它必须只使用 Python 语言的内置部分。
测试装具
我知道我会尝试很多。我需要一个可以尝试多种算法的测试工具。对于每个算法,该工具应该生成候选 Python 程序作为输出,执行该程序,确认它一字不差地生成原始单词列表,并以字节为单位记录该程序的大小。
如果任何生成的程序未能产生正确的输出,线束必须中止并显示错误消息。如果所有的程序都通过了测试,它会选择胜出者:具有最小字节大小的输出。
我的测试线束叫squash.py
。它需要一个变量AlgorithmList
中的算法列表。每个算法都是一个必须公开一个Name
函数和一个Compress
函数的对象。下面是squash.py
的相关摘录。(GitHub 上有完整的项目源代码。请参阅本文末尾的参考资料部分。)
霍夫曼编码
我尝试的算法都依赖于霍夫曼编码,这是一种使用可变位数表示有限符号集的技术。更频繁出现的符号由更少的比特表示;更少的符号需要更多的比特。霍夫曼编码的主要负担是符号不是字节对齐的。这需要额外的代码将这些位尽可能紧密地打包在一起,忽略字节边界。
霍夫曼编码的工作原理是建立一个二叉树,其叶节点代表输入中存在的每个不同的符号。每个符号的二进制编码由从根节点到该符号的叶节点的路径决定。
我将使用一个只有五个符号的简单示例来解释构建霍夫曼树的算法:字母 A 到 e。假设我们计算每个字母在我们的输入中出现的次数,并得出以下数字。
A : 351
B : 12
C : 9
D : 13
E : 823
如果我们使用固定数量的比特来表示 5 个可选符号,我们将需要 3 个比特,因为 2 =8,这是足以表示 5 个可选符号的 2 的最小幂。霍夫曼编码可以通过利用我们可以对最常出现的符号使用更少的比特这一事实来做更有效的工作。
霍夫曼编码器首先创建 5 个叶节点,每个符号一个。还没有树。我们只是有单独浮动的叶节点,还没有相互连接。编码器创建一个按计数升序排序的节点列表。这是我们开始时的样子:
然后霍夫曼编码器进入一个循环。在每次迭代中,编码器删除排序列表中的前两个节点,并为它们创建一个新的父节点。父节点的计数成为两个子节点计数的总和。父节点被插回到节点列表中保持节点按计数排序的任何位置。
因此,在我们的示例中,编码器删除了 C:9 节点和 B:12 节点,创建了一个计数为 9+12=21 的父节点,并在 D:13 和 A:351 之间插入了新节点,以保持排序后的顺序。结果看起来像这样:
请注意,新创建的节点是内部节点,而不是叶节点,因此它不代表单个符号。因此,它有一个计数,但没有附加符号。
因为每次迭代都从列表中删除两个节点并用一个节点替换它们,所以列表每次都会缩短一个节点。该算法一直循环,直到只剩下一个节点。该节点是最终树的根节点。在我们的示例中,完成的树看起来是这样的:
此时,我们不再需要频率计数。此外,用位 0 和 1 标记树中的分支有助于使编码清晰。每个左分支接收 0,每个右分支接收 1。让我们也使叶节点和内部节点看起来不同。树现在看起来像这样:
我们使用这棵树来构建字母 A 到 e 的二进制表示。对于每个字母,从树根开始(用*
标记),沿着树向下移动,直到到达那个符号。每次向左分支时,附加一个 0。每次向右分支时,添加一个 1。这为我们的五个符号产生了以下位模式:
A = 01
B = 0011
C = 0010
D = 000
E = 1
正如我们所希望的,最常出现的符号 E 使用了最少的数据量:只有 1 位!两个最不常用的符号 B 和 C 各使用 4 比特,这比固定比特长度表示所使用的 3 比特差。但是好消息是输入中没有太多的 B 和 C。
霍夫曼编码的效率
那么在这个简单的例子中,我们的数据压缩有多好呢?让我们比较一下简单的固定位方法和霍夫曼可变位方法。
固定比特方法要求我们对每个符号使用 3 比特。如果我们合计输入中的符号总数,并乘以每个符号 3 位,则我们得到:
3*(351+12+9+13+823) = 3624 位
现在让我们看看霍夫曼表示法总共需要多少位。有 351 个 A 符号,每个使用 2 比特;12 个 B 符号,每个使用 4 比特,等等。这给了我们
2351 + 412 + 49 + 313 + 1*823 = 1648 位
我们用 1648 除以 3624,发现压缩比在 45%左右。因此,在这种情况下,霍夫曼编码将输入缩小到不到其原始大小的一半。当然,这个压缩比对于每种输入都是不同的。这完全取决于每个唯一输入流中存在的符号的相对频率计数。
同样重要的是要注意,霍夫曼树本身需要存储在压缩输出中。解压缩算法需要知道如何解释这些位,以便重建原始数据。因此,这给压缩输出的大小增加了一点开销。
霍夫曼编码器源码
我的霍夫曼编码器的源代码包括两个类:HuffmanNode
和HuffmanEncoder
。这两个类都在源文件huffman.py
中。
如上所述,HuffmanNode
对象代表霍夫曼树中的一个节点。每个节点都包含一个保存原始未压缩符号的符号字段、一个频率计数以及对左右子节点的引用。对于叶节点,引用被设置为None
。对于内部节点,left
和right
是指其他HuffmanNode
对象。下面是HuffmanNode
的代码:
HuffmanEncoder
类支持上面解释的算法。它包含一个由 compressor 算法调用的Tally
方法,用于计算每个符号在输入中出现的次数。它还包含一个生成霍夫曼树的Compile
方法。它实现了上述算法,用于从节点的排序列表中构建树。Compile
返回树的根节点,这为调用者提供了整个树。
一旦 compressor 算法计算完所有符号并调用Compile
来获得霍夫曼树,它需要一种方法将输入中的每个符号转换为其霍夫曼表示,作为可变长度的位模式。为此,compressor 调用根节点的MakeEncoding
方法。这个函数创建一个字典,它的键包括输入中的每个符号。
在这个字典中,与每个符号相关联的值是一个元组(data, nbits)
,其中data
是一个整数,保存表示从树根到该符号的路径的比特,nbits
是该整数中有效低位比特的数量。例如,如果位模式是0111
,data
将是 7,nbits
将是 4,产生元组(7,4)
。
现在,我们有了一个将原始输入文本转换成霍夫曼编码比特流的良好基础。但是我如何在生成的 Python 源代码中表示这些可变的比特流呢?
Base64 表示法
我要求输出是 Python 源代码,这让我的挑战变得更加困难。不仅程序必须包含自己的解压缩逻辑,而且源代码本质上必须只包含可打印的字符。任意二进制数据会导致 Python 代码混乱。
为了解决这个问题,我使用 Base64 对二进制数据进行编码。在这种编码中,每个连续的 6 位数据块被替换为 64 个字符中的一个:a-z、A-Z、0–9、+或/。这些 ASCII 字符中的每一个都需要一个完整的 8 位字节来表示,所以我要存储的每 6 位就损失了 2 位的效率。
虽然 Python 内置了base64
模块,但是我的编码器有一定的特殊需求,所以我自己写了一个名为BitBuffer
的类。它具有以下特点:
- 它有一个接受元组
(data, nbits)
的Append
函数。这与存储在由HuffmanNode.MakeEncoding
返回的字典中的元组完全吻合。 Append
函数动态转换为 Base64。对于每批 6 位,它缓冲另一个 Base64 字符。它会记住任何剩余的位,并保存它们,直到更多的位到达,以填充更多的 6 位块。Append
通过在每 80 个 Base64 字符后换行,防止文本行变得过长。- 还有另一种方法
Format
将任何剩余位作为最终的 Base64 字符进行刷新。然后,它将整个 Base64 缓冲区转换为可以写入输出源代码的 UTF-8 字符串。它将该字符串返回给调用者。
这里是BitBuffer
类。
现在我已经有了自己的基础设施。下一步是尝试各种压缩算法,这些算法可以生成输入到BitBuffer
类的比特流,并创建相应的解压缩算法来从压缩的 Base64 图像中提取原始数据。
尝试 1:所有字符
在我的第一次尝试中,我知道我不会击败 gzip,但我必须从某个地方开始。我所做的只是对输入的每个字符使用霍夫曼编码。输入中出现了 27 个不同的字符:a
- z
和换行符(在 Python 中表示为'\n'
)。我的第一次尝试分两步处理输入。在第一遍中,它计算 27 个字符中的每一个出现的次数。它使用这些信息来建立一个霍夫曼树。
一旦有了霍夫曼树,它就会第二次调用私有函数_Encode
来创建单词列表的压缩 Base64 表示。
我将第一个压缩器编写为一个名为cmp_letters.py
的模块。下面是它的源代码:
这种形式的压缩效果如何?它确实使数据变小了,但正如我所怀疑的,它没有打败 gzip。输出文件letters.py
的总大小为 460531 字节,压缩比为 460531/636946 = 72%。下面是letters.py
的样子,为了简洁起见进行了编辑。(您可以通过在本文末尾的参考资料部分克隆我的 GitHub 库并运行squash.py
程序来获得全部内容。)
解压器是如何工作的
我的第一次尝试有一些特征是我的三个解压器共有的。第一行可执行代码创建了一个变量Char
。它是使用元组的霍夫曼树的表示。元组包含两个元素。这些元素中的每一个都是另一个包含两个元素的元组,依此类推,直到到达由单个字符组成的叶节点。
为了理解如何使用Char
中的霍夫曼树,请看一下letters.py
中的函数Huffman
。Huffman
函数使用BitReader
类从 Base64 编码中一次提取一位。它一次向下遍历二叉树的一位,选择左分支(元组中的第一个元素)或右分支(第二个元素),这取决于 Base64 数据中的下一位是 0 还是 1。最终,它到达一个不是元组的元素。该元素是树的叶节点,由原始的、未压缩的字符组成。Huffman
函数将该字符返回给调用者。
尝试 2:省略共享前缀
我知道我可以做得比 72%的压缩比更好。我的下一个想法是利用单词按排序顺序出现的事实。这意味着列表中相邻单词之间通常有一些相同的字母。例如,考虑来自words.txt
文件的这段摘录:
decade
**decade**nce
**decadenc**y
**decaden**t
**deca**gon
**deca**hedron
粗体字母显示每个单词中与列表中前一个单词前面相匹配的部分。我推断我可以创建代表这些整数计数的符号。那么上面的话,在decade
之后,可以更简洁地表示为
6nce
8y
7t
4gon
4hedron
因此,在我的第二次压缩器/解压器尝试中,我创建了两个独立的霍夫曼树,一个用于前缀计数,另一个用于后缀中出现的字母。这表明霍夫曼编码器可以处理整数或字符作为输入符号。HuffmanEncoder
类不关心数据类型是什么,只要每个符号允许自己被用作字典键。
压缩源文件被命名为cmp_prefix.py
。下面是它的代码:
下面是相应生成的解压缩程序,为了简洁起见,再次进行了编辑:
用整数计数代替常用的单词前缀真的很有帮助。它将输出大小降低到 220603 字节。我现在越来越兴奋了,因为我已经接近 gzip 的 212736 字节了!我只是需要提高一点效率。
第三次是魅力
我的下一个想法是,我可以利用英语中某些字母比其他字母更容易成对出现的事实。例如,如果你在一个英语单词中看到一个q
,那么下一个字母几乎肯定是一个u
。尽管u
是一个相当常见的英文字母,但它更有可能出现在q
之后。一般来说,当前字母强烈影响下一个字母出现的概率。
因此,我的第三次尝试是基于我的第二次尝试的前缀优化,只是没有对字母频率使用单个霍夫曼树,而是使用了 27 个霍夫曼树:26 个可能的前面字母中的每一个都有一个,再加上一个单词中的第一个字母(当没有前面的字母时)。
这种方法意味着我必须在输出中消耗额外的空间,以便在生成的输出中存储额外的 26 棵霍夫曼树。
Repeat
是与前一个单词匹配的每个单词前面的字符数的霍夫曼树。Tail
是对前缀后每个单词剩余部分的字符数进行解码的树。而Char
现在是一个霍夫曼树的列表。Char[0]
是单词中第一个字符的树,Char[1]
是字母 a 后面的任何字符,Char[2]
是字母 b 后面的任何字符,依此类推。
这就是我最终打败 gzip 的地方。源文件pairs.py
长 202641 字节,比words.gz
小 10095 字节。胜利!
最后的想法
显然,我的方法并没有剥夺 gzip 作为顶级通用数据压缩算法的地位。我所做的工作之所以这么好,是因为我根据人类对给定输入文件的理解对它进行了裁剪。我的算法甚至不能处理除小写字母和换行符以外的字符。如果输入没有按字母顺序排序,它的性能不会很好。
但是这个练习确实展示了一些有用的东西。如果您有一个想要压缩的固定数据集,有时可以设计一个比众所周知的通用算法性能更好的自定义压缩算法。
如果你准备好接受一个有趣的挑战,也许你会从我停下的地方继续。使用同样的规则,你能为同样的words.txt
输入创建另一个击败我的算法吗?如果是这样的话,我会很高兴收到你的来信并了解你的所作所为。
参考
- 我的测试输入是基于一个单词列表,我在:
http://www-personal.umich.edu/~jlawler/wordlist.html找到的 - 我的自定义数据压缩器的完整源代码:
https://github.com/cosinekitty/compressgame