TowardsDataScience 2023 博客中文翻译(三百六十六)

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

人工智能在医疗保健中应扮演什么角色?

原文:towardsdatascience.com/what-role-should-ai-play-in-healthcare-7acaf9131278?source=collection_archive---------2-----------------------#2023-11-30

关于机器学习在医疗保健中的应用及美国医疗保健 AI 丑闻

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Stephanie Kirmer

·

关注 发表在 Towards Data Science ·11 分钟阅读·2023 年 11 月 30 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片来源:国家癌症研究所,来源于 Unsplash

你们中的一些人可能知道我受过社会学培训——准确地说,我在研究生院学习了医学社会学。这意味着我专注于人们和群体如何与疾病、医学、医疗机构以及围绕健康的概念和想法互动。*

当我担任兼职教授时,我曾向进入医疗领域的本科生讲授这些问题,我认为医疗服务提供者对我们社会、经济和种族状况如何与健康互动有深入了解是非常重要的。每个生病的人都不是相同的,认识到这一点是提供高质量护理之前必须做到的。

我解释这些只是为了为今天的话题——机器学习在医疗中的应用——提供一些背景。我之所以等到现在才谈论这个话题,是因为它实在太大了,但最近的一些新闻报道激励我开始讨论。很可能,我会在未来继续谈论这个话题。

关于生命与死亡

我发现很难讨论在医疗领域使用机器学习的原因之一是因为失败的风险极其严重。如果我预测你在线订购的袜子的到达日期错误,最坏的情况就是你可能有一两天的冷脚。如果机器学习模型在医疗环境中出错,风险就会真正上升到生命丧失或生活质量严重下降的程度。

如果机器学习模型在医疗环境中出错,风险就会真正上升到生命丧失或生活质量严重下降的程度。

当然,我们的医疗服务提供者在日常工作中已经意识到了这种风险,并学会了应对它。但总体来说,数据科学家和机器学习模型开发者对这些模型所涉及的结果并不熟悉。在建模时,以分类模型为例,任务的一个重要部分是估计我们称之为假阳性和假阴性的成本——本质上,就是当我们预测某个事件实际上没有发生(FP)或我们预测不会发生任何事件但它实际上发生了(FN)时,可能会出现什么坏事。在其他类型的模型中,我们也会花时间考虑模型预测的结果与期望值或实际情况的差异。共同点是模型总是会有某种程度的不可避免的错误,即使是生成式人工智能也是如此。正如我过去多次提到的,模型输出在某种程度上是基于概率的,这些概率留有一定的错误(不良行为)的空间。

在医疗环境中,假阳性或假阴性等错误的成本意味着什么?如果还不够明显的话,金钱只是模型潜在错误中的一小部分,无论是在医疗领域还是其他行业。与“生命损失”或“失去独立生活能力”相比,金钱损失应当是一个较低的优先级。虽然我们的法律系统尝试为这些问题分配货币价值,以便在法院案件中分配赔偿金,但这真的不是同一回事,尤其是当问题涉及到你自己的生命或生活质量时。

联合健康

最近报道的关于联合医疗如何 使用机器学习的案例,突显了当“金钱”在医疗决策中被赋予比“生命”更高的优先级时,情况变得多么糟糕。这与模型本身没有太大关系,因为你可以教会一个模型更好地优先考虑医疗结果 如果你愿意的话

不幸的是,我们的医疗系统在护理质量和利润这两个竞争的优先级之间摇摆。我坚决拒绝这两者可以和谐共存的观点,因为它们总是处于紧张状态,但美国的系统仍然基于这种可疑的基础。我们在讨论联合医疗所做的事情时,牢记这一点是重要的。

联合医疗(在实际支付护理方面被普遍认为是美国最差的大型健康保险公司)所做的就是:

  • 人员已支付了他们的保险费用,并且做了所有应做的事情以获得保险覆盖;

  • 人员变老和/或生病,需要住院护理来恢复病情或伤害;

  • 联合医疗的模型提供了案件和患者的一般特征,并预测恢复护理可能需要的时间。这一预测所需的护理时间远远短于医生建议的时间;

  • 联合医疗信任模型而非医生,并拒绝支付更长的护理时间,将患者在未康复前赶出了护理设施。

许多医生和医疗系统的学者讨论了健康保险公司如何“无证行医” 当他们对医生关于患者所需护理的专业医学意见提出质疑时,这种行为正是这种情况的体现。当联合医疗的员工(在模型的支持下)改变患者的护理方案时,我们还能怎么称呼这种行为?

但这并不新鲜,实际上,保险公司不需要模型来支持他们对医生的质疑。这在我们的健康保险系统中是常见的,每天都会发生,形式包括事先授权。保险公司会争辩说,他们有其他医生在做最终决定,因此“无证行医”并不适用,但这些医生明显的激励是站在保险公司一边,而非患者。可以确定,这些医生从未推荐比主要医生更昂贵的护理方案。

应用机器学习

那么,为什么 UHC 的行为现在成为新闻?这与机器学习到底有什么关系?UHC 用于确定这些老年患者的急性后护理应该持续多久的模型来自一家名为 naviHealth 的公司,该公司专门处理这些案例。从他们的网站阅读,我了解到,naviHealth 寻找减少老年患者在护理设施中停留时间的方法。他们可能还提供一些关于案例管理的服务,在患者被送回家之前与他们进行咨询。他们在网站上明确表示,他们可以为保险公司提供“显著的成本节约”。

但关键在于,这个模型“nH Predict”声称能够确定患者在护理环境中停留的最佳时间长度, ostensibly 为了最佳的护理效果,而实际上模型的阈值设置使得这些预测与护理效果并不一致,而仅仅是为了成本节约。

换句话说:如果你允许病人留在医院或康复设施,但他们准备提前回家并且真的这样做了,那是很好的。没有人愿意在医院待得过久(你尝过医院的食物吗?)。这是一种你可能通过提供高质量的护理、他们所描述的案例管理以及其他有用服务来实现的成本节约,同时病人也能得到他们所需的护理。但 UHC 所做的却是,通过拒绝支付病人在医院的费用来获得成本节约,因此不论病人是否准备好,他们都会被赶出医院送回家。

UHC 所做的却是,通过拒绝支付病人在医院的费用来获得成本节约,而不是提供这些服务并让病人准备好提前离开医院,因此无论病人是否准备好,他们都会被赶出医院送回家。

模型如何了解健康

我想澄清的是,这不是“人工智能失控”——这是人类做出了不道德的决定,并利用机器学习来推卸责任。如果你想将老年人赶出医院,不考虑他们的生活或健康后果,那么如果你今天是美国的保险公司,你可以这样做。你不需要一个模型来给你许可。但我认为 UHC 意识到,如果他们有一个模型给出这些建议,而人工审核者可以只是走个过场,那么他们就有了掩护,因为人们认为模型具有一定的独立准确性。毕竟,模型肯定不会查看这项护理的价格标签!

但请记住,模型只是一个试图将模式融合成可以复制的数学语言的尝试,它不控制你提供给它的信息,也不控制你教它回答的问题。在创建一个预测住院天数的模型时,你可以这样进行。

  • 收集大量的过去患者档案数据,其中有人受伤或生病,进入医院,接受康复住院护理,并有结果(不论是康复、需要回医院还是去世)。

  • 将这些文件转化为数字数据。把每个患者看作是电子表格中的一行,开始收集诸如患者年龄、初始伤害的严重程度、患者的过去病史数据、是否有其他疾病(糖尿病、心脏病、痴呆等)。这些成为训练数据。最重要的是,你需要包括 A. 康复住院护理的天数和 B. 结果是什么。

  • 现在你需要框定问题。在这种情况下,塑造模型训练的一种方式可能是:“在考虑到所有病例特征的情况下,治疗效果良好的患者有多少天的康复?” 然后你可能会将其与“在考虑到所有病例特征的情况下,治疗效果差的患者有多少天的康复?”进行比较。这只是一个假设性的框定方式,还有许多其他方法可以构建问题并整合训练数据。

最终你会得到每个患者的康复天数估计值,这个估计值适用于良好的结果。可能会得到一个范围,或者基于天数的良好结果的概率,如果你将天数增加到某个点,那么概率也会增加,如果超过某个点,它又会开始变得有风险。

请记住,康复天数并不是与其他一切无关——你可能会有感染、并发症或其他疾病,这意味着长时间住院是必要的,并不是为了愉快的原因(康复),而是为了不幸的原因(额外的疾病)。所以住院时间过长也可能是一个坏事,但原因与住院天数无关。考虑时间顺序,帮助理解因果关系可能存在的地方。

使用模型的结果

所以我们有一个模型,如果我们告诉它有关患者的信息,它就会给出一个估计值,说明如果这个人要有好的结果,康复住院的时间可能需要多久。真正关键的问题是我们如何利用这些信息!

如果我们是全民医疗保险(UHC),我们的目标是节省开支。我们以非常非常低的估算值为准,可能甚至低于模型推荐的良好结果范围,并在此时停止支付医疗费用。这就是这个故事的经过,依据报道来看。

如果我们的目标是病人的结果,那么我们应该退一步思考一下。我们是否认为病人因非医学原因在医院或住院康复中心待了很长时间?我们是否认为医生因不适当的原因将病人送往康复中心?这些原因可能是什么?老实说,我很难想到许多医生在这种情况下会有什么合理的行为。正如我所提到的,谁愿意在病情好转后仍然待在医院?如果确实发生了这种情况,我们应该寻找改变医生行为的方法,但不应以牺牲病人护理质量为代价。也许医院高管们希望病人待得更久,而医生的薪水与病人的住院时间无关。医生的激励是让病人尽快康复。

我在这里想表达的是,如果我们的目标只是让病人康复,我不确定引入这个模型是否有意义。毫无疑问,过长的康复住院时间目前不是对病人健康的最大威胁。

这篇文章讲述了机器学习,这也是大多数读者来这里的原因,但它还涉及了医疗经济学的问题。这些问题对所有美国人来说都很重要,因为医疗系统迟早会影响到我们所有人。我还认为,对于数据科学家来说,思考将模型投入生产环境的真正意义是一个很好的练习,这不仅仅是从召回率和精确度的角度来看,而是从真实人类生活受影响的角度来看。你对你的模型的优化负责。你在构建模型时做出的决策将使该模型对人们和社会的影响是积极的还是消极的,你不能仅仅耸耸肩说“模型做的”。

即使你的模型不会对人们的医疗保健做出决定,它仍然会对人们产生一些影响。(如果没有,那你为什么要构建它?)我鼓励所有从业者在工作中时刻牢记这一点。

*医学社会学关心的这些问题的例子可能包括:

  • 患有慢性疾病的人如何看待自己及其在社会中的位置?

  • 当人们成为医疗服务提供者时,他们的生活和身份有什么不同?

  • 少数群体或弱势群体的长期健康结果是什么?这些结果与多数群体有何不同,为什么会有这种差异?

  • 环境问题如何影响人们的健康,这些问题如何与社会结构/特权互动?

这只是其中的一部分——这个社会学领域涵盖了对人们生活和福祉至关重要的广泛内容。

www.stephaniekirmer.com上查看更多我的作品。

参考文献

国会委员会和监管机构质疑 Cigna 系统,允许其医生拒绝索赔而无需…

这些探查跟随 ProPublica 和 Capitol Forum 的调查,揭示了 Cigna 允许其医生拒绝数百个…

UnitedHealth 被指控使用有缺陷的 AI 拒绝老年患者必要的医疗覆盖 [## 由诉讼声称]

过去受益者的家庭声称,UnitedHealth 的 AI 系统“积极”拒绝了必要的医疗索赔…

naviHealth 官网 [## 首页]

老年中心护理的未来已来

navihealth 官网

当你的 p 值 = 0.052 时,你的决定应该是什么?

原文:towardsdatascience.com/what-should-your-decision-be-when-your-p-value-0-052-1d50f9d4d2c5

选择显著性水平的指南

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Jae Kim

·发表于 Towards Data Science ·7 分钟阅读·2023 年 4 月 13 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Burst 提供,来源于 Unsplash

在假设检验中,“p 值 < α”几乎被普遍作为统计显著性的标准和决策规则,其中α是显著性水平。例如,在测试中

H0: θ = 0; H1: θ ≠ 0,

当θ是代表某种效应的感兴趣参数时,如果 p 值 < α,我们在α显著性水平下拒绝 H0(无效应假设)。通常设置α = 0.05,而 0.10 和 0.01 也被广泛采用。正如众所周知,这些常规值是任意的,并且缺乏科学依据。

当 p 值接近 0.05 时,你应该怎么做?例如,

  • 如果 p 值 = 0.052,你应该维持α = 0.05 并接受 H0 吗?还是应该将α设置为 0.10 并拒绝 H0?

  • 同样地,如果 p 值 = 0.047,你应该维持α = 0.05 并拒绝 H0 吗?还是应该将α设置为 0.01 并接受 H0?

统计教科书对这一点提供的指导很少,而在统计分析和机器学习方法的实际应用中,经常会遇到这种情况。

本文旨在为研究人员提供一些关键点,以在面对这种情况时做出理性的决定。虽然以下讨论适用于任何接近 0.05 的 p 值,但为了说明问题,我们假设 p 值 = 0.052。文中提供了两个实际应用的示例。

1. α值设置的意义

显著性水平α表示 I 型错误(拒绝真实 H0)的概率。设置低值的α意味着你希望以低概率控制 I 型错误。

原则上,显著性水平的选择应考虑Ⅱ型错误的概率(接受虚假的 H0),记作β;统计功效(1-β);样本大小;以及Ⅰ型和Ⅱ型错误的损失,在数据收集之前做出决定。详细信息请见这篇文章

α 和 β 之间的权衡是众所周知的。较高的α值会导致较低的β值;反之亦然。设置较高的α值意味着你希望以较低的概率控制Ⅱ型错误。

只要样本大小固定,两种错误概率不能同时降低。

2. 不应做的事

回到 p 值接近 0.05 的情况,我们首先回答一下不应该做什么。

最不科学的方式是调整α值以符合或证明你预设的决定。即,α值不应根据研究人员是否想要拒绝或接受假设来选择:见Keuzenkamp 和 Magnus (1995, p. 20)

以 p 值 = 0.052 为例。假设研究人员发起研究的目的是拒绝 H0,因此她选择了α = 0.10 并拒绝 H0。相反,如果研究人员的目的是接受 H0,那么她选择α = 0.01 并接受 H0。

上述做法是不科学且武断的,甚至可能是不道德的。这一过程被称为p-hacking数据窥探,这是许多科学领域错误积累的主要原因:请参见美国统计协会的声明

为了在这种情况下做出更科学的统计决策,需要仔细考虑一系列因素,以做出合理的α值选择或调整。

3. 我们应该怎么做?

当 p 值接近 0.05 时,决策者需要考虑三个要点。这些要点应该与 p 值一起或单独权衡,并据此确定或调整最终的α值。

效应大小

首先是估计的θ值是否表明了一个显著的效果。假设 p 值 = 0.052 且效果被发现是显著的,那么研究人员应该拒绝 H0,选择α值为 0.10 或更高。相反,如果效果被发现是微不足道的,那么选择α值为 0.01 或更低,不拒绝 H0 是合适的。

当效应微不足道时,这意味着 H0 极有可能,设置较低的α值来避免 I 型错误是合理的。相反,如果效应强且 H1 极有可能,那么设置较高的α值来避免 II 型错误是合理的。这将减少β值(II 型错误的概率),因为这是α和β之间的权衡结果。

I 型和 II 型错误的相对损失

I 型和 II 型错误带来损失或后果。当损失已知或可估计时,研究人员应将相对损失纳入决策过程。

再假设一次 p-value = 0.052。假设 I 型错误(拒绝真实的 H0)将导致 100 万美元的损失,而 II 型错误(接受虚假的 H0)将带来较小的损失。那么,研究人员应该通过控制 I 型错误的低概率(如 0.01 或更低,即设置α ≤ 0.01)来避免 I 型错误。因此,在这种情况下,在α = 0.01 时,不拒绝 H0 是合理的。

相反,假设 II 型错误比 I 型错误更昂贵。那么,研究人员应该增加α值,以减少β值并避免 II 型错误。这也是基于上述α和β之间的权衡。在这种情况下,设置α ≥ 0.10 并拒绝 H0 是合理的。

先验知识

可能存在关于效应(θ)的先验知识,这些知识可能以

  • 理论,

  • 规范化事实(积累的统计证据),

  • 专家意见及其共识,或

  • 常识或直觉。

假设有一种理论或专家意见强烈建议存在强效应。在这种情况下,当 p-value = 0.052 时,在α = 0.05 时接受 H0 是不合理的。当先验知识强烈支持 H1 时,则应选择较高的α值,以便将β值降低。这是因为,鉴于 H1 极有可能发生,研究人员希望以低概率控制 II 型错误。因此,在这种情况下,设置α ≥ 0.10 并拒绝 H0 是合理的。

相反,如果先验知识强烈支持没有效应的 H0,那么研究人员应该通过设置较低的α值来以较低的概率控制 I 型错误。这是因为,鉴于 H0 极有可能,研究人员应避免 I 型错误。因此,在这种情况下,设置α ≤ 0.01 并接受 H0 是合理的。

4. 示例

本节提供了两个应用实例。

第一个是广为人知的虚假相关性示例,即美国淹死死亡人数与尼古拉斯·凯奇从 1999 到 2009 年出演的电影数量之间的关系。有关更多细节,请参见这篇文章。设 Y 为死亡人数,X 为尼古拉斯·凯奇出演的电影数量。对于回归 Y = β0 + β1 X + u,估计的斜率系数为 5.82,t 统计量为 2.68,(双尾) p 值为 0.025。我们应该在 5%的显著性水平下拒绝 H0: β1 = 0,还是在 1%的显著性水平下接受它?

假设研究者认为这个关系的实质性重要性很小,并且判断 H0: β1 = 0 很可能是真的。她进一步咨询了许多专家,这些专家也支持她的判断。因此,她希望通过选择一个低概率(例如 0.01)来避免 I 类错误。也就是说,在α = 0.01 的情况下,H0: β1 = 0 不能被拒绝,因为 p 值 = 0.025 大于 0.01。

作为第二个例子,我们考虑Selvanathan (2017)的示例 17.10。一位生产经理希望检查在招聘前进行的能力测试分数与员工入职三个月后的表现评分之间的关系。从 20 名工人的随机样本中,计算出的相关系数(ρ)为样本值 r = 0.379。H0:ρ = 0; H1: ρ ≠ 0 的 Z 统计量,服从标准正态分布,给出如下

图片由作者创建

这在 H0 下给出的值为 1.652,p 值 = 0.098。再说一遍,经理应该选择 0.05 还是 0.10 的显著性水平?

假设经理发现 r = 0.379 并非微不足道的相关性,而且广泛认为这是表示中等关联的相关值:例如,请参见这篇文章。基于此,经理决定 H1 很可能成立,并将α设定为较高的值,如 0.10,以降低 II 类错误的概率。因此,在 10%的显著性水平下,H0 被拒绝,支持 H1,因为 p 值 = 0.098 < 0.10。

在这篇文章中,我解释了如何调整显著性水平,特别关注 p 值接近 0.05 的情况。关于这方面的指导文献很少,这篇文章旨在为数据科学家提供在这种情况下需要考虑的几个关键点。有关在更正式和通用环境中选择显著性水平的方法,请参阅这篇文章

上述讨论隐含假设 α = 0.05 作为初始显著性水平。但当 α 的初始值为 0.10 或 0.01 时,同样的逻辑和论点也应适用。

主要结论是,当研究人员选择或调整显著性水平时,他们应考虑包括关键因素在内的理由来证明其选择。

  • 效应量,

  • 类型 I 和 II 错误的相对损失,以及/或者

  • 先验知识。

任意调整显著性水平是不科学的,应予以避免。

什么阻碍了你获得第一个数据科学工作?

原文:towardsdatascience.com/what-stops-you-from-getting-your-first-data-science-job-ccf93e4187d4?source=collection_archive---------8-----------------------#2023-03-23

数据科学面试流程和获得第一个工作机会的步骤

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 亚历克斯·瓦姆瓦卡里斯

·

关注 发表在 迈向数据科学 ·12 分钟阅读·2023 年 3 月 23 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Rod Long 提供,来源于 Unsplash

尽管有很多关于如何成为数据科学家的博客、视频和教程,但许多资源都存在我所称之为“知识的诅咒”。那是什么呢?大多数这些资源都是由那些已经当了很长时间数据科学家的人创建的,因此他们已经忘记了获得第一份数据科学家工作的瓶颈和困难。

我记得当我开始申请伦敦的数据科学职位时(那时我作为数据分析师已有两年多的经验),在几乎所有阶段都遭遇了很多拒绝。我可能提交了数百份申请,才能让只有几个进入下一阶段。即使是那些通过筛选过程的申请,也经历了很多拒绝,才最终获得了第一份 offer。实际上,有时候我决定完全放弃(有时甚至几个月),因为我相信成为数据科学家的梦想无法实现。有时我希望能回到过去,帮助自己导航数据科学面试流程中的复杂性和未知,并挽回一些失去的时间。

鉴于这一点,我想以稍微不同的方式构建这篇文章。我们不会完全忽略技术要求如统计学、编程和机器学习(别担心,我们还是会涵盖这些内容),而是希望创建一个专注于面试过程各个阶段以及如何集中精力以获得你的第一个 offer 的指南。具体来说,文章将按以下结构展开:

  1. 绘制数据科学面试流程图

  2. 用你的简历打开大门

  3. 技术(回家)评估

  4. 与招聘数据科学家的现场面试

  5. 从错误中学习

1. 数据科学面试流程图

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Brett Zeck 拍摄,来源于 Unsplash

大多数入门级数据科学职位的面试过程通常包括三到五个阶段。虽然这些阶段会根据你希望成为的数据科学家的类型和你申请的公司有所不同,但基本构成是相同的。

前两个阶段是筛选过程的一部分。这些是你的 简历(CV)与招聘人员的初步电话。此时,你仍在敲打公司的大门。目的是将候选人池缩小到一个较小的群体,这些人将被邀请“进入屋内”。

一旦进入公司,你仍然需要证明自己具备足够的资格。换句话说,你需要展示你拥有合适的态度和技能组合,使他们愿意雇佣你,同时能够对这一选择做出合理的解释。这可以分为以下三个阶段(注意,并非所有阶段都出现在每个面试过程中):

  • 技术(家庭作业)评估: 这一阶段旨在测试你的逻辑思维能力和统计与编程(SQL、R 或 Python)的水平。本质上,他们希望评估你的基础知识是否足够,能够进一步进入公司。

  • 与(招聘)数据科学家的现场面试:这一阶段涉及视频通话(在 Covid 后),高级或首席数据科学家将要求你解决问题并回答基于你在被雇佣后需要完成的日常任务的问题。此时,你已经完全进入了公司。

  • 最终面试: 这一阶段并非总是存在,但在成熟的数据科学团队中,作为最后的关卡,你将与数据科学团队的高级领导(负责人或总监)进行简短的通话。目的是让他们了解你并给出“绿灯”或发现任何红旗。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据科学面试流程 [作者提供的图像]

现在我们对各个阶段有了更好的理解,让我们深入探讨每一个阶段,以便你更好地理解它们的结构以及如何应对,以获得你的第一份数据科学角色。

2. 用你的简历打开大门

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 João FerrãoUnsplash 提供

在创建简历时,仔细考虑你想成为哪种类型的数据科学家。如果你想打造合适的钥匙,首先应考虑你希望它打开哪种类型的门。有两种主要类型的(入门)数据科学家职位(即门):

  • 分析数据科学家: 主要职责是 AB 测试、对广告活动、优惠或产品进行临时分析,并构建简单(主要是探索性)的机器学习模型,例如聚类。

  • 核心数据科学家: 主要职责是构建可以投入生产环境的预测模型(具有最高的准确性)。

如果你想了解更多关于不同类型的数据科学家角色及其日常任务,你还可以查看下面的视频。

虽然典型的钥匙是一个小块形状金属,上面有切口以适配特定锁的钥匙孔,但你的简历将包含 关键词工作经验

不幸的是,即使你打造了正确的“钥匙”,在这个阶段的成功率仍将是整个面试过程中最低的。这主要是由于这个阶段的随机性和匆忙性(你可能听说过,大多数简历在做出决定之前只会被查看 2 到 3 秒)。

尽管申请后没有回应可能会让人感到沮丧,但另一方面,你也获得了所有需要的“弹药”来打造合适的“钥匙”。大多数职位描述通常会列出这些关键词,因此你需要做的是 a) 确定哪些职位适合你,b) 收集常见的关键词和所需的技能,并 c) 确保它们在你的简历中得到清晰的体现。相信这个简单的过程,凭借适当数量的申请,你将进入下一个阶段(这只是由于大数法则的一个简单情况)。

如前所述,筛选过程的第二部分是与招聘人员的电话面试。这通常持续 15 到 20 分钟,招聘人员首先会给你介绍公司的背景和职位情况。之后,招聘人员会询问你的工作经历、通知期、签证要求、薪资预期以及一些关于职位的问题。常见的问题包括:

  • 你能快速介绍一下你的简历/工作经历吗?

  • 你对我们公司这个职位感兴趣的地方是什么?

  • 在寻找新职位时,你期望得到什么?或者换句话说,你看重哪些任务或职责?

  • 你在当前或之前的工作中使用了哪些工具和技术?

尽管这些问题看起来很简单,我建议你练习几次。正如亚伯拉罕·林肯所说:“给我六个小时砍树,我会用前四个小时磨快斧子。”

3. 技术(家庭作业)评估

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Nguyen Dang Hoang Nhu 提供,来源于 Unsplash

技术性家庭作业通常以一系列问题的形式呈现。这些问题通常包括以下内容:

  • 编写一个函数来解决一个简单的问题(比如计算大于 1000 的前 10 个斐波那契数),使用 R 或 Python。

  • 给定一个或多个表(通常不超过两个),你需要用 SQL 编写代码来提取或操作数据。这些问题通常从简单开始,例如计算符合某些条件的行总数,最后的问题则需要使用不同类型的连接和窗口函数。

  • 给定一个图表或小表格,你需要利用统计学来得出正确的结论。最常见的问题涉及偏斜分布、平均值和中心极限定理。

  • 给定一个特定的业务问题,你将被要求写一个简要的提案,说明你会选择哪些 KPI 和分析方法来实现预期结果。

我无法过于强调双重(或三重)检查你的答案和验证代码的重要性。我还建议尽可能将这些检查加入到你的解决方案或代码中。你可以在下面的文章中找到有关 SQL 语句和测试代码的更多信息。

## 如何将你的 SQL 从零提升到数据科学家水平 — 第 2/3 部分

SQL 完全指南:学习数据科学家常用的基础和高级 SQL 查询

[towardsdatascience.com

或者,你可能会被给予一个数据挑战。更具体地说,你将获得一个数据集和一个任务或问题的概述。例如,在我为 Deliveroo 完成的家庭作业中,任务是分析他们的“骑手推荐骑手”项目与其他营销渠道的表现。任务的最后一步涉及向高级非技术利益相关者展示信息摘要,并建议可能的下一步。如果你在这一步需要更多帮助,我推荐阅读下面的指南。

## 如何将家庭作业转化为数据科学职位

如何从数据集中创建一个引人注目的故事的逐步指南

[towardsdatascience.com

4. 与招聘数据科学家的现场面试

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 GR Stocks 提供,照片来源于 Unsplash

这将是面试过程中最具挑战性的部分。它不仅是一次现场面试,而且难度也是整个流程中最高的。话虽如此,你可以期待得到公平的评价,因为在视频通话期间,你将获得面试官的全部注意力。

在 COVID-19 之前,大多数技术面试都在公司现场(实际上是在‘公司内部’)进行。然而,如今绝大多数面试都是通过 Zoom 或其他视频会议工具进行的。这些面试由一位或两位数据科学家进行,通常包括以下三个部分:

4.1 行为/态度评估

在这一部分,问题主要是非技术性的,旨在评估你的软技能和个人特点。常见问题包括:

  • 你能描述一个你遇到问题的情况并解释你采取的步骤来解决它吗?

  • 讲述一个你引以为豪的项目及其对业务的影响。

在准备你的回答时(遵循我们朋友亚伯拉罕·林肯的建议),重要的是始终记住这些类型的问题没有正确答案。相反,他们寻找的是理解在任何环境中你都会遇到障碍,而真正重要的是展现出毅力和提供价值的能力。STAR方法是一个很好的框架,讨论具体的情况、任务、行动和结果。

4.2 经验评估

在这一部分,你将被给出一个面试官提出的具体问题,通常基于如果你被录用后需要完成的任务。典型场景包括以下几种:

  • 我们最近启动了一个活动或优惠,并希望评估其表现。描述你会如何从头到尾处理这个问题(与业务相关者沟通,理解目标,获取所需数据,分析和展示结果)。

  • 描述你将如何为特定功能或倡议设计 AB 测试。

  • 如果 AB 测试显示期望的指标在下降,而另一个指标在上升,你会如何决定是否发布或放弃这个功能?

不要害怕向面试官提出澄清问题,并将你的思路阐明给他们。面试官会根据你对模糊描述的理解能力(因为这些描述大多出现在实际环境中)以及你解决问题的方法来评估你。同时,不要犹豫向面试官请求几分钟时间来整理问题后再回答。最后,记住他们在寻找新员工时关注的是为业务提供价值的能力,因此始终以这个北极星为目标来组织你的回答。

4.3 技术技能评估

在这一部分,你将被评估在统计学、AB 测试和机器学习方面的技术技能。示例问题包括:

  • 你将如何向一个 5 岁的小孩描述 p 值和置信区间?

  • 你能解释什么是引导法以及它是如何使用的吗?

  • 你将如何在启动 AB 测试前估计样本大小?

  • 你将如何分析 AB 测试结果中异常值和测试前的不平衡?

如果你需要复习或了解上述问题,可以在下面的链接中找到关于商业环境中 AB 测试的完整指南。

[## 我作为数据科学家运行 AB 测试一年的经验——第 1/2 部分]

像数据科学家一样设置你的 A/B 测试,按照这些简单的步骤操作。

towardsdatascience.com

我还强烈推荐免费书籍《统计学习导论:R 语言应用》(An Introduction to Statistical Learning: With Applications in R)以了解统计学习中的关键主题。书中还涵盖了以下问题:

  • 你能解释一下机器学习中的偏差-方差权衡吗?

  • 你能描述一下什么是过拟合以及在构建预测模型时如何解决它吗?

  • 你能描述一下监督建模和非监督建模之间的区别吗?

  • 你能描述一下什么是交叉验证以及它如何用于模型评估吗?

5. 从错误中学习

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Patrick Tomasso拍摄的照片,来自Unsplash

面试过程中最被忽视的部分之一是请求反馈。这是可以理解的,因为大多数情况下,你不会得到答案,或者得到的是自动化(没有用的)回复。

我的建议是把获取反馈看作是一个焦点小组。你需要大约十个好的回复,以确定你需要改进的共同领域,但同样重要的是,找出什么做得好,什么应该保持不变。

另一个我想强调的点是,根据公司面试过程的质量进行自我评估的重要性。是否对不同阶段投入了足够的努力,还是看起来像是匆忙完成的?他们是否根据你预期的标准评估你?他们是否花时间和精力给你反馈?即使今天你没有获得那个职位,你也可以在公司上标记一个星号,以便在未来的申请中指示一个需要避免或值得关注的地方。

最后,不要把拒绝看作是失败。你参加的面试越多,你就会越了解目标职位的要求,同样重要的是,你会越发准备好!就像其他任何事情一样,唯一的提高方式就是通过练习。就像你第一次骑自行车时一样,你不会期望第一次就成功,也不会因为失败而感到尴尬而放弃。

总结

🚀🚀 完成最后一步,我们已经到达了指南的终点。下面,你还可以找到步骤的快速总结:

✅ 确保你对第一个角色的任务和职责有清晰的理解,并使用相关职位描述中的关键词来打造合适的简历(CV)。

✅ 始终以提供业务价值为主要目标来构建你的回答。记住,公司并不单纯寻找统计学或编程的从业者,而是寻找能够从大数据中提供价值的个人。

✅ 练习可能看起来枯燥或重复,但它将对你获得第一个数据科学职位至关重要。

✅ 尽可能地请求反馈,以确定哪些做法有效,哪些需要改进。

保持联系!

如果你喜欢阅读这篇文章并想了解更多内容,不要忘记 订阅,以便直接将我的故事发送到你的收件箱。

在下面的链接中,你还可以找到一个免费的 PDF 指南,介绍如何使用数据科学技术和最佳实践在实际商业场景中完成客户群体分析。

## 数据科学项目检查清单 - 有志数据科学家

我是一名拥有 7 年以上分析经验的数据科学家,目前在英国伦敦的一家游戏公司工作。我的…

www.aspiringdatascientist.net

带什么?——基于协同过滤的物品建议

原文:towardsdatascience.com/what-to-bring-item-suggestions-with-collaborative-filtering-6cd260984330?source=collection_archive---------11-----------------------#2023-10-03

个性化物品建议基于实际数据和真实案例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Malte Bleeker

·

关注 发表在 Towards Data Science · 7 min 阅读 · 2023 年 10 月 3 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

物品建议(作者提供的图片)

生日聚会、共同旅行或与本地运动俱乐部的夏季聚会——像这些事件很美好,直到你需要自己为准备工作做出贡献。通常,这始于一个非常投入的人,他主动开始并推动事情的进展,但迟早,当已经承诺的项目数量不断增加时,你也不得不问这个问题:我将带什么?

各种类型的活动中常见的物品列表已被大量创建,但总是很难想到一个合适的主意来至少免除你一定的社交义务(通常通过默认的“灵丹妙药”,一瓶酒)。由于我们的网络应用提供了数以万计的此类列表,我们能够通过将其转化为基于已存在列表中的项目来建议有前景的项目,从而应对这一挑战。

我们通过利用数据库中约 10 万份列表与用户当前感兴趣的列表之间的相似性来应对这个挑战。利用这种列表与列表之间的相似性,进而推荐合适的项目,也被称为协同过滤,因为目标是将数据库中可能推荐的海量不同项目过滤成仅几个最合适的(实际上在我们的情况下大约是 10 万种不同的项目)。类似的情况通常可以在如书籍或电影推荐系统中找到,通过利用用户已经观看的内容(在我们的例子中是已添加到列表中的项目)来推荐用户可能错过的电影,这些电影被类似用户观看过(在我们的例子中是已被添加到类似列表中的项目)。

它是如何工作的? — 一个简单的解释

第一步是创建一个表格,行是列表(ID),列是所有项目名称。当我们的所有列表仅包含 20 个唯一单词时,我们只需要 20 列,行数等于列表的数量。每当一个单词出现在列表中时,我们就在相应的列和行中添加值“1”,如果一个单词不在列表中则添加“0”(在文本分析中也称为词袋模型)。我们对要进行建议的列表做相同的操作。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

列表-项目矩阵的简单示意图(作者提供的图片)

对于电影或书籍推荐,采用相同的程序,但列会包含数据库中不同的电影或书籍,行会包含不同的用户(ID),值可以指示一本书是否已被阅读,或者它是否以及如何被评分。

可选:相应的 Python 代码(步骤 1)

# Create the list-item matrix
matrix = df.pivot_table(index='id', columns='what', values='value')

# Matrix Dimensions (126.252 x 179.674) 
# Number of unique listIDs:  126252
# Number of unique items ("what"):  179674

这将我们的数据转换为合适的格式,为第二步做好准备——计算数据库中列表与我们希望建议项目的列表之间的相似度。衡量两个行(向量)相似度的最常用方法之一是“余弦距离”或“余弦相似度”。它通过两个行的点积计算,除以两个向量的大小的常规乘积。下面的图形应该使这个计算更易于理解,但这里的重点是对余弦距离的直观理解,对于任何数学上的细节,请参阅这篇文章。请也将下面的代码块视为一个可选但补充的附加部分。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

计算两个列表/向量之间的余弦相似度(图像由作者提供)

例如,如果两个列表完全相似,它们的余弦相似度为 1,完全没有共同词的列表相似度为 0,而至少有一些共同词的相似度为 0 < x < 1。余弦相似度值越高,数据库中的列表与我们关注的列表越相似。 有了这一点,我们可以计算我们列表与表中所有其他列表的相似度,为每一行获取一个相似度分数。接下来,我们对这些行进行排序,并提取最相似的行,可以基于预定义的数量(例如最相似的 50 个列表)或相似度阈值(例如 > 0.6)。在我们的案例中,相似度分数的变化很大,取决于关注列表的项目数量及其具体用途,因此我们为了简化操作选择了最相似的 100 个列表(一个经验法则:我们在这里选择的列表越多,我们的建议将越稳定,但也更通用)。我们现在可以创建一个包含原始列表-单词表副本的新表,只包含这 100 个最相似的列表。

可选:对应的 Python 代码(步骤 2)

# Find the index of the listID "TestList" in the matrix
# (the TestList is the list we would like to get suggestions for)
list_index = matrix.index.get_loc(listID)

# Extract the row of the listID "TestList" from the matrix
list_row = matrix.iloc[list_index]

# Calculate the similarity between the listID "TestList" and all other listIDs
similarities = cosine_similarity([list_row], matrix)[0]

# Return the indices of all lists with a similarity greater than 0.6 and store them with the similarities in a list
#similar_list_indices = np.where(similarities > 0.5)[0]

# Return the indices of the 100 most similar lists
similar_list_indices = np.argsort(similarities)[-100:]

# Extract the corresponding similarities
similarity_scores = similarities[similar_list_indices]

# Create a list of tuples with the listID and the similarity
similar_lists = [(listid_dict[i], similarity) for i, similarity in zip(similar_list_indices, similarity_scores)]

# Convert the indices to listIDs
similar_list_ids = [listid_dict[i] for i in similar_list_indices]

# Extract the rows of similar lists from the matrix
recommendation_matrix = matrix[matrix.index.isin(similar_list_ids)]

完成后,接下来是识别这些相似列表中最有前景的条目。首先,我们检查感兴趣列表中已存在的条目,并从表格中删除相应的条目(列)(我们假设在这种情况下用户不希望得到已包含的条目建议)。接下来,最简单的方法是检查这些相似列表中出现频率最高的词,并按降序建议这些词。然而,这样做会对第 99 个最相似列表中的词和最相似列表中的词给予相同的权重。为了解决这个问题,行会乘以之前计算的相似度分数。因此,第 99 个最相似行的值(现在介于 0 和 1 之间)相比最相似行显著较小。基于此,可以计算每列(条目)的加权总和,并建议得分最高的条目。

可选:对应的 Python 代码(步骤 3)

# Find columns with a value of 1 in the 'TestList' row (Items that are already in the list)
columns_to_remove = recommendation_matrix.columns[recommendation_matrix.loc[listID] == 1]

# Drop the identified columns (Do not recommend items already in the list)
recommendation_matrix.drop(columns_to_remove, axis=1, inplace=True)

# Create a dictionary to map listIDs to similarity scores
listid_to_similarity = {listID: similarity for listID, similarity in similar_lists}

# Multiply each row in the recommendation matrix by the corresponding similarity score
recommendation_matrix = recommendation_matrix.apply(lambda row: row * listid_to_similarity.get(row.name, 1), axis=1)

# calculate the sum of each column and sort the values in descending order
recommendations = recommendation_matrix.sum().sort_values(ascending=False)

# Print out the Items with the highest Scores (the most suitable item suggestions)
top_item_recommendations = recommendations.head(10)
print(top_item_recommendations)

就这样了——结合少量数据和简单而强大的计算,如余弦相似度,可以生成合适的个性化建议和推荐。接下来,我将向你展示三次建议模拟的结果,列表中条目还很少(条目和列表大多是从德语翻译过来的……如果有些条目选择对你来说感觉怪异,请见谅)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

三个列表的个性化条目建议模拟(图片作者)

如你所见,几个条目就足以生成反映列表基础主题的个性化建议——一旦处理了特定事件类型的最常见条目,建议会变得更加具体。

一些额外说明:为了防止推荐非常具体的条目名称或可能包含个人信息的条目,我们仅包括在至少 20 个不同列表中出现的条目(列)。我们还排除了包含少于 3 个条目的列表。列表建议功能尚未部署到生产环境中,而只是模拟并在本文描述和测试的 Jupyter Notebook 中测试过。

感谢你对这篇文章的关注,我非常感激所有类型的反馈——祝你一切顺利,保持好奇。

找到异常值后该怎么做

原文:towardsdatascience.com/what-to-do-with-outliers-once-you-find-them-8e4d3d32f228

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Bex T.

·发表于Towards Data Science ·阅读时间 5 分钟·2023 年 2 月 15 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由Ralf Kunze提供,来源于Pixabay

异常值检测只是故事的一部分。真正的挑战在于弄清楚如何处理这些异常值。很容易就将异常值一笔勾销,但实际情况中有很多细微差别和需要考虑的因素。

盲目删除异常值可能会产生不良后果。虽然发现某种类型的异常值可能暗示数据存在更严重的问题,但检测到另一种类型的异常值可能根本没有问题。因此,重要的是不要做出草率的决定,因为这可能导致数据质量下降或后续机器学习模型的偏差。

今天,我们将从两个角度分析这个问题。首先,我们将根据异常值存在的原因查看适当的行动方案,然后讨论根据数据集中异常值的数量应采取的措施。让我们开始吧!

查看这系列关于异常值检测的早期部分,我们更注重代码方面:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Bex T.

BEXGBoost - 异常值检测

查看列表3 个故事外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1. 存在的原因:错误

异常值最常见的原因之一是人为和设备错误。有人搞错了零的个数,按错了键,忘记测量某样东西(或测量了两次),或者故障的仪器产生了不一致的读数;软件故障记录了错误的数据,等等。

作为数据科学家,这些事情超出了你的控制范围,因为它们通常发生在数据收集过程中。第一步适当的行动是尝试修正这些错误的异常值。尝试修正那些错别字或将数字值更改为常识性的替代值(例如,当有人在调查中说自己 200 岁时,你将其更改为 20 岁)。

当无法修正或修正成本过高时,只能过滤掉这些数据,因为你知道它们是不正确的值。

2. 存在原因:抽样错误

统计学家和机器学习工程师使用小样本来对特定目标群体做出结论。然而,在数据收集过程中,不属于该群体的数据点可能会泄漏到收集的样本中。

例如,假设你正在研究你朋友果园中的苹果生长。这个研究定义的总体是果园中的所有苹果树,而样本是 1000 棵随机选择的苹果树。但是,由于它们之间的围栏不太明显,几十棵邻居果园的树木被混入了你的样本中。

虽然邻居的苹果不一定是不正常的,但它们来自不同的群体,可能会扭曲你的整个研究。

当异常值是由于这种抽样错误造成的时,删除它们是唯一的解决办法。

3. 存在原因:自然变异

世界充满了惊喜和不确定性。一些异常值可能突然出现,但仍然是目标群体中固有的自然变异的一部分。

例如,有些人天生拥有特定基因使他们非常高、非常矮、是天才等,或者一些动物能够跳得异常高或寿命远超同类……例子无穷无尽。

如果你抽取了足够大的样本,你肯定会遇到自然分布中的奇异值。它们不一定是问题,但会引入数据的变异性。

虽然删除这些异常值很有诱惑力(因为它们会降低数据的统计显著性),但不能仅仅为了获得更好的指标而这么做。

4. 异常值的数量

处理异常值也会极大地依赖于它们相对于数据集大小的数量。

如果它们只是少数(低于 1%)且你有充足的数据,可以安全地排除它们以保持透明。当然,你必须与收集数据的人或领域实验讨论,以确保它们不是自然变异的一部分。

如果异常值过多,以至于引起怀疑,那么它们的存在可能有某种未知原因。也许它们只是相对于大多数数据点来说是异常值,但实际上是目标人群的关键特征。在这种情况下,你所处理的样本可能并不完全代表其目标人群。

最终的情况是数据中有太多异常值,以至于它们形成了一个新的簇或子群体。在这里,推荐使用相同的方法——分析最初的机器学习或数据科学问题是如何框定的,目标人群和样本是如何选择的,以及为什么会有这么多异常值进入数据集。

如果你不去除异常值,该怎么处理它们?

异常值通常会被删除,以避免它们扭曲特征的均值和标准差,从而最终导致模型性能下降。但在某些情况下,异常值本身也是值得关注的。

异常检测的一些应用包括入侵检测(网络安全)、欺诈检测、故障检测、系统健康监测、传感器网络中的事件检测、生态系统扰动检测、使用机器视觉的图像缺陷检测和医疗诊断。在这些场景中,异常值的性质和存在被广泛研究,以推动业务、隐私和医疗决策。

如果你确实决定去除异常值以提高模型性能、改进视觉效果或统计测试,你应该在方法上保持透明。利益相关者(直接从项目中受益或失去的人)应该被告知这一决定。最好是,你应该提供两个结果:一个包含异常值,另一个不包含。

还有一些非侵入性且轻量级的替代方法。一个流行的方法是百分位修剪,即对超出第一个和第 99 个百分位的极端值进行限制。你可以在 Pandas 或 NumPy 中轻松执行此操作:

import pandas as pd

low = distribution.quantile(0.01)
high = distribution.quantile(0.99)

outlier_free = distribution.clip(low, high)

你也可以用中位数或众数来替代异常值。这可以通过 Pandas 的replace函数或 NumPy 的where函数来完成。

结论

本文的主要目标是强调对异常值采取适当行动的重要性。过去,你可能只是为了更好的指标而盲目删除它们,但现在,你可以根据异常值的类型和数量做出更明智的决定。

查看这系列异常检测的其余文章:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Bex T.

BEXGBoost - 异常检测

查看列表3 stories外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

感谢阅读!

ibexorigin.medium.com [## 使用我的推荐链接加入 Medium - Bex T.

获取对我所有⚡优质⚡内容和 Medium 上所有内容的独家访问权限,没有限制。通过购买支持我的工作…

ibexorigin.medium.com [## 订阅 Bex T. 的更新

每当 Bex T. 发布文章时,都会向您发送电子邮件。通过注册,如果您还没有 Medium 账户,将为您创建一个…

ibexorigin.medium.com

更多我的文章…

5 个迹象表明你已经成为高级 Pythonista,而自己却没有意识到 ## 5 个迹象表明你已经成为高级 Pythonista,而自己却没有意识到

[towardsdatascience.com [## 5 个优秀的 Julia 特性,Python 开发者只能羡慕

朱莉亚与 Python 辩论的继续

medium.com [## 如何创建高度组织化的 ML 项目,任何人都可以通过 DVC 管道重现

什么是机器学习管道?

pub.towardsai.net

Pandas 2.0 有什么新变化?

原文:towardsdatascience.com/whats-new-in-pandas-2-0-5df366eb0197

关于这次重大发布的五件事

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Jeff Hale

·发表于 Towards Data Science ·阅读时间 5 分钟·2023 年 4 月 10 日

Pandas 2.0 于 2023 年 4 月 3 日正式发布。让我们看看哪些功能比阳光下的柯基还要炙手可热。☀️

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:pixabay.com

三年前,我写了 Pandas 1.0 有什么新变化。经历了一场大流行和一系列 AI 进展之后,我们迎来了 pandas 2.0。

Pandas 是标准的、脑力友好的 Python 数据处理库。2.0 更新的重点是让 pandas 更快、更节省内存。内存是人们需要离开 pandas 转向 Dask、Ray、SQL 数据库、Spark DataFrames 和其他工具的主要原因。减少内存使用会使 pandas 的使用变得更加轻松。🙂

正如你可能期望的那样,作为一个主要版本,pandas 2.0 有许多显著的变化。让我们深入了解一下!

pyarrow 🐍➡️

如果用一个词来总结这次发布,那就是 pyarrow

Pandas 是使用 NumPy 数据结构进行内存管理构建的。现在,你可以选择使用 pyarrow 作为你的后备内存格式。

使用 pyarrow 意味着你可以加快速度并提高内存使用效率,因为你可以利用 Arrow 的 C++ 实现。有趣的是,pandas 的创始人 Wes McKinney 在 2009 年开源 pandas 后,于 2016 年开始参与 Arrow 的开发。

Arrow 是什么? Sebastian Raschk 解释道,它是“…一种开源且与语言无关的列式数据格式,用于在内存中表示数据。它可以实现进程间的数据零拷贝共享。”

列式数据存储将数据列组装在内存中,从而使得在诸如计算列均值等任务上操作更快。Arrow 数据类型还包含了如空值等有用的概念,如上所述。

使用 pyarrow 的 pandas 比其他 pandas 替代方案更快吗?在一些任务上,Sebastian Raschka 显示 pandas 可能比 polars 更快,polars 是一个相对较新的“Rust 和 Python 的 lightning-fast DataFrame 库”,也使用 Arrow。

然后,polars 库的作者 Ritchie Vink 对 TPCH-10 基准测试 进行了比较测试,这是一个更大、更相关的实际数据测试。请查看以下一些结果和讨论:

来源:twitter.com/RitchieVink/status/1632334005264580608

看起来 pandas 可能还有一段路要走,如果你还没有尝试过,polars 可能值得一试。

如果你觉得需要速度,Numba 是另一个选项。在任何情况下,避免过早优化的普遍建议是合理的。

以下是使用 pyrarrow 后端格式读取 CSV 文件的代码:

pd.read_csv(my_file, dytpe_backend='pyarrow')

如果你想深入了解,Marc Garcia 有一篇不错的文章,介绍了 pandas 内存结构的历史以及 pandas 2.0 中对 pyarrow 的支持(注意,在预发布版本和正式发布之间语法有所更新)。

从一开始就支持可空数据类型

在 pandas 中处理缺失(空)值并不总是那么容易。Pandas 是建立在 NumPy 上的,而 NumPy 对某些数据类型不支持空值。

例如,NumPy 整数数据类型无法支持空值。在整数列中引入空值会导致该列自动转换为浮点数据类型。一分钟列是整数,下一分钟变成浮点数。这至少可以说是不理想的。

Pandas 1.0 为我们提供了可空的数据类型,但使用起来需要一些工作。现在,当你将数据读取到 DataFrame 中时,你可以指定你想要可空的 NumPy 支持的数据类型,如下所示:

pd.read_csv(my_file, dtype_backend="numpy_nullable")

更新:注意,自 2.0 beta 版本以来,这种语法已被更新。

注意,大多数,但不是所有的 read_xxx 函数都支持可空的数据类型。更多信息请见这里

pyarrow 数据类型从一开始就提供了空值支持。

更多 NumPy 数据类型用于索引

现在,你可以为 pandas 索引选择更多的 NumPy 数据类型以减少内存使用。现在你可以选择更低内存的数据类型作为索引。例如,你可以指定索引使用 32 位整数,从而节省之前只能使用 64 位整数时的一半内存。

pd.Index([1, 2, 3], dtype=np.int32)

阅读更多这里

复制-on-写模式

Pandas 变得懒惰了。以一种好的方式。 🙂 大量 DataFrame 和 Series 方法在需要之前不会再创建 pandas 对象的副本。例如,df.head() 不会创建一个包含前五行的新 DataFrame,而只是返回前五行的视图。

这些变化将节省时间和内存。只需使用:

pd.set_option("mode.copy_on_write", True)

你可以通过几种其他方式设置这个行为,因为 pandas 喜欢给你多种方法来完成任务。 ❤️

可安装的额外功能

现在你可以在安装 pandas 时同时安装 pandas 需要的额外 Python 库。例如,运行以下命令将为你提供处理 Google Cloud Platform 和 Parquet 文件格式所需的库。

pip install "pandas[gcp, parquet]==2.0.0"

⚠️ 确保不要忘记引号!

这里是可用的安装选项:

  • all (所有附加功能)

  • performance

  • computation

  • timezone

  • fss

  • aws

  • gcp

  • excel

  • parquet

  • feather

  • hdf5

  • spss

  • postgresql

  • mysql

  • sql-other

  • html

  • xml

  • plot

  • output_formatting

  • clipboard

  • compression

  • test

了解安装的依赖项请访问 这里

Upgrading

要在你的虚拟环境中从 PyPI 安装 pandas 2.0,请使用以下命令进行升级:

pip install -U pandas

现在你已经开始更快、更节省内存的数据处理之旅了! 🎉

Wrap

你已经看到 pandas 2.0 的最大变化了。还有其他变化,比如 read_csv 和类似函数的新日期参数名称。 查看发布帖子了解所有细节

即使有了这些新变化,当你的 pandas DataFrame 没有足够的内存时也会出现问题。针对这种情况,我在 这份指南 中分享了八个帮助你应对的技巧。

如果你是 pandas 新手,可以查看我的入门书籍 Memorable Pandas

希望你觉得这份 pandas 2.0 变化指南对你有帮助。如果有,请分享给其他人,让他们也能找到它! 🚀

我写关于 Python、数据和其他技术话题的文章。如果你对这些感兴趣,跟随我 follow me,这样你就不会错过更新!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:pixabay.com

编程愉快!

Pandas 2.1 中的新功能

原文:towardsdatascience.com/whats-new-in-pandas-2-1-d26c0b8314a?source=collection_archive---------2-----------------------#2023-09-07

关于新版本最有趣的功能

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Patrick Hoefler

·

关注 发布于 Towards Data Science ·5 分钟阅读·2023 年 9 月 7 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 Lukas W. 提供,来源于 Unsplash

pandas 2.1 于 2023 年 8 月 30 日发布。让我们来看看这次发布带来了哪些新功能,以及它如何帮助我们改善 pandas 的工作负载。它包含了一系列改进,同时也引入了一些新的弃用功能。

pandas 2.1 在 pandas 2.0 提供的 PyArrow 集成基础上进行了大量构建。我们专注于扩展对预计将成为 pandas 3.0 默认功能的新特性的支持。让我们深入了解这对你意味着什么。我们将详细查看最重要的改进。

我是 pandas 核心团队的一员。我是 Coiled 的开源工程师,在那里我负责 Dask,包括改进 pandas 集成。

避免为字符串列使用 NumPy 对象 dtype

pandas 中一个主要的痛点是低效的字符串表示。这是我们工作了很长时间的一个话题。第一个 PyArrow 支持的字符串 dtype 在 pandas 1.3 中可用。它有潜力将内存使用减少约 70% 并提高性能。我在 我之前的一篇文章 中更深入地探讨了这个话题,其中包括内存比较和性能测量(总结:非常令人印象深刻)。

我们决定引入一个新的配置选项,将所有字符串列存储在 PyArrow 数组中。你不再需要担心转换字符串列,这将直接生效。

你可以通过以下方式启用此选项:

pd.options.future.infer_string = True

这种行为将在 pandas 3.0 中成为默认,这意味着字符串列将始终由 PyArrow 支持。你需要安装 PyArrow 才能使用此选项。

PyArrow 的行为与 NumPy 对象 dtype 不同,这可能会使详细了解变得棘手。我们实现了用于此选项的字符串 dtype,以便与 NumPy 语义兼容。它的行为将与 NumPy 对象列完全相同。我鼓励大家试一试!

改进的 PyArrow 支持

我们在 pandas 2.0 中引入了 PyArrow 支持的 DataFrame。我们的主要目标之一是在过去几个月内改善 pandas 的集成。我们旨在使从 NumPy 支持的 DataFrame 切换尽可能简单。我们关注的一个领域是修复性能瓶颈,因为之前这会导致意外的慢速。

让我们看一个例子:

import pandas as pd
import numpy as np

df = pd.DataFrame(
    {
        "foo": np.random.randint(1, 10, (1_000_000, )),
        "bar": np.random.randint(1, 100, (1_000_000,)),
    }, dtype="int64[pyarrow]"
)
grouped = df.groupby("foo")

我们的 DataFrame 有 100 万行和 10 个组。让我们看一下 pandas 2.0.3 与 pandas 2.1 的性能对比:

# pandas 2.0.3
10.6 ms ± 72.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

# pandas 2.1.0
1.91 ms ± 3.16 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)

在新版本中,这个特定示例的速度快了 5 倍。merge 是另一个常用的函数,现在也会更快。我们希望使用 PyArrow 支持的 DataFrame 的体验会更好。

Copy-on-Write

Copy-on-Write 最初在 pandas 1.5.0 中引入,并预计将在 pandas 3.0 中成为默认行为。Copy-on-Write 在 pandas 2.0.x 上已经提供了良好的体验。我们主要集中在修复已知的错误并提高运行速度。我建议现在在生产中使用此模式。我写了一系列博客文章来解释 什么是 Copy-on-Write 和 它是如何工作的。这些博客文章详细讲解了 Copy-on-Write 的内部工作原理以及你可以期待什么,包括性能和行为。

我们已经看到 Copy-on-Write 可以将实际工作流的性能提高超过 50%。

弃用在 setitem 类操作中的静默上升类型转换

历史上,如果你将不兼容的值设置到列中,pandas 会静默更改其中一个列的数据类型。让我们来看一个例子:

ser = pd.Series([1, 2, 3])

0    1
1    2
2    3
dtype: int64

我们有一个包含整数的 Series,这将导致数据类型为整数。让我们将字母 "a" 设置到第二行:

ser.iloc[1] = "a"

0    1
1    a
2    3
dtype: object

这将把你的 Series 的数据类型更改为 object。Object 是唯一可以同时包含整数和字符串的数据类型。这对很多用户来说是一个重大困扰。Object 列占用大量内存,计算将无法进行,性能下降以及其他许多问题。它还在内部增加了许多特殊处理来适应这些问题。在过去,DataFrame 中的静默数据类型更改曾让我非常烦恼。这个行为现在已被弃用,并将引发 FutureWarning:

FutureWarning: Setting an item of incompatible dtype is deprecated and will raise in a future 
error of pandas. Value 'a' has dtype incompatible with int64, please explicitly cast to a 
compatible dtype first.
  ser.iloc[1] = "a"

像我们的例子这样的操作将在 pandas 3.0 中引发错误。DataFrame 的列数据类型将保持一致。你需要在想要更改数据类型时明确指出,这增加了一些代码,但使得未来的开发者更容易理解。

这一变化影响所有的数据类型,例如,将浮点值设置到整数列中也会引发错误。

升级到新版本

你可以通过以下方式安装新的 pandas 版本:

pip install -U pandas

或:

mamba install -c conda-forge pandas=2.1

这将为你的环境提供新的发布版本。

结论

我们已经查看了一些改进,这些改进将帮助你编写更高效的代码。这包括性能改进、更容易选择 PyArrow 支持的字符串列以及进一步改进 Copy-on-Write。我们还看到了一项弃用,这将使 pandas 在下一个主要版本中更易于预测其行为。

感谢阅读。欢迎随时联系分享你的想法和反馈。

2023 年的分析领域接下来会发生什么?

原文:towardsdatascience.com/whats-next-for-analytics-in-2023-875a5fe94171?source=collection_archive---------20-----------------------#2023-01-06

分析团队会在 2023 年征服分析的最后一公里吗?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 João António Sousa

·

关注 发布于 Towards Data Science ·6 min read·2023 年 1 月 6 日

我对年末总结和预测总是充满热情。这是一个从日常琐事中抽身,查看全局的绝佳时机。我喜欢阅读同行和行业领袖关于学习和趋势的文章,花时间回顾我的一年,并为下一年做计划。所以我想分享一下我对明年数据分析领域重点关注内容的看法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片由 wirestock 提供,来源于 Freepik

对大多数人来说,2022 年并不轻松。由于经济衰退,我们目睹了大量裁员和预算削减。“以少量资源做更多事情”成为了我们大家越来越常用的短语。我预计这将成为 2023 年的座右铭。

因此,我预测将会更加关注效率、商业价值和分析团队的投资回报率最大化。因此,只有那些能够提供以下结果的项目和技术将会受到优先考虑:

  • 帮助团队节省时间和资源,提高效率

  • 帮助团队节省收入和降低成本,最大化数据与分析的投资回报率。以下是我对明年一些重要分析趋势的预测(不按特定顺序)。

预测 #1 —— 专注于证明分析的投资回报率

数据驱动的公司在过去几年中在技术和人员上进行了大量投资。最初,他们的重点是收集、存储、管理、转换和展示数据,以建立强大的核心。

数据质量对于创造有意义的结果至关重要,但仅有数据质量还不足以创造商业价值。如果我们将数据分析之旅视为马拉松,将商业影响视为奖牌,提供能够指导日常和战略决策的可操作性见解是完成比赛的必备条件。因此,这也是领导者将注意力转向最大化投资回报率的原因。

那么你如何达到目标呢?

  • 与业务团队的更紧密合作(例如,共同确定优先级用例,进行每日/每周性能评审以审查和分享见解)

  • 分析中的速度和全面性以真正赋能决策

  • 强调衡量商业价值和持续迭代以实现最佳结果

预测 #2 —— 大多数决策将通过机器学习(ML)得到增强

为了跟上数据和业务的步伐,“用更少做更多”的口号再次浮现。企业需要增强工作流程和自动化琐碎任务,加快洞察速度,打破速度与全面性的权衡,以创造真正的商业价值并最大化数据分析的投资回报率。

使用数据做出的决策可以通过各种方式实现自动化,并且介于主要依赖人工和完全自动化之间。Gartner 预测,到 2025 年,目前使用数据的 95%的决策将至少部分实现自动化。在人工智能时代,拥抱一定程度的决策自动化的组织有可能通过更快速、复杂和细化的决策来获得竞争优势。

在商业智能(BI)中,大多数决策很快将得到增强。我在大多数数据驱动的公司中看到的两个主要使用场景是:

  • 人工参与的诊断分析:使用机器学习测试数据中的每个假设并评估关键业务指标变化的驱动因素。人类可以专注于筛选出最相关的因素并做出决策

  • 针对关键业务指标变化的自动警报,以自然语言通过 Slack/Teams 传递

预测 #3 — 数据与分析角色将进一步专业化

随着职业的逐渐成熟和复杂化,进一步的专业化往往会发生。这是一种自然的演变,分析领域也不会例外。

当前,数据与分析团队的角色主要基于他们在数据分析工作流中负责的阶段进行分段。

  • 数据工程师负责数据管道的建设。

  • 分析工程师负责清理数据。

  • 数据分析师和科学家从数据中提取洞察。

这些核心角色将继续存在,但会进一步细分,专注于特定的业务问题和目标。

  • 分析工程师的角色将继续增长,确保数据建模并向数据分析师和业务用户提供清洁的数据集。这一趋势也释放了数据分析师的工作负担。

  • 数据分析师将更贴近业务,专注于揭示洞察和改善决策,成为值得信赖的顾问,最大化业务影响。

  • 数据产品经理的角色将继续增长,推动数据产品的采用和货币化。

  • 分析翻译员的角色将继续增长,以缩小数据素养差距,并最大化分析用例的价值。

预测 #4 — 数据网格用于数据民主化和可扩展性

数据网格已成为数据讨论中的热词。但是什么促成了这一趋势?对数据架构的民主化和可扩展性的渴望。

许多组织仍在挣扎,因为他们的架构选择是由技术驱动的,而非业务需求。数据网格旨在通过在组织内部联合数据所有权,并专注于效率、创新和透明度来解决这个问题。

这创造了一种分布式、去中心化的数据处理方式,使得分享和创建数据产品变得更快。数据产品由独立的跨职能团队拥有,但遵循中央治理以确保互操作性和一致性。

打破孤岛、提高数据的重用性并推动创新,数据网格和以业务问题为导向的架构将是那些希望更好地利用数据的公司发展的方向。

预测 #5 — 分析团队将“可操作洞察的速度”定义为北极星指标

大多数数据驱动的答案需要几天甚至几周。由于公司现在可以近乎实时地获取数据,决策延迟成为当前分析的瓶颈。随着业务变化速度的加快,这些答案并未以业务的速度出现。这种反应式的方法带来了显著的成本:直接的负面业务影响、削弱的数据文化以及导致员工流失的恶性循环。

改善这一情况已成为许多分析团队的首要任务。顶尖的分析团队已将“可操作洞察的速度”定义为他们的北极星指标,以确保行动性,最大化业务影响,并提升数据文化。

可操作洞察的速度是一个简单的概念:从业务问题到数据驱动的决策或行动的时间。它已经包括了通常需要的多个迭代。这样,分析团队不仅专注于回答问题,而是主动与业务部门合作,推动可操作的洞察。

这推动了诸如增强型业务根本原因分析和由机器学习(ML)驱动的自动警报和洞察信息等创新。这确保了团队利用所有可用的数据,主动以业务的速度提供分析。

预测 #6 — 数据法规将成为关注重点

欧盟 GDPR、加拿大 PIPEDA 和中国 PIPL 等法规促使公司重新思考他们收集和处理数据的方式。我——以及像 Gartner 这样的分析机构——期望在 2023 年看到更多国家出台新的规则和立法。

这意味着需要更多的工作来赢得客户的信任,使他们更愿意分享他们的信息。为此,企业需要更好地结构化、记录和创造更多的透明度,来处理和处理数据。此外,有效的数据治理将变得更加相关。根据合规阶段,这可能意味着需要对现有数据进行一些回顾性工作,包括数据的收集和存储方式以及使用情况。

这也许不是列表中最令人兴奋的预测,但却是在最大化数据价值、遵守安全标准以及防止任何违规和罚款方面至关重要的预测。

结论

对于那些将强烈关注投资回报率(ROI)并且不浪费任何资源或时间的团队来说,他们将会是赢家。我希望看到分析团队与业务部门紧密合作,专注于数据分析、洞察生成,并采取行动以最大化业务价值。我期望数据基础项目在除非它们是关键的或带来显著成本节约的情况下会被降级优先级。

参考资料:

Gartner, 想要成为数据驱动型组织?从 5 项关键数据与分析计划开始

当 AI 走错路时:现实世界中的高-profile 机器学习失误

原文:towardsdatascience.com/when-ai-goes-astray-high-profile-machine-learning-mishaps-in-the-real-world-26bd58692195

一次对引起全球关注的臭名昭著的机器学习失误和失败的巡礼

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Kenneth Leung

·发表于 Towards Data Science ·阅读时间 6 分钟·2023 年 8 月 19 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 NEOM 提供,Unsplash

人工智能 (AI) 和机器学习的变革潜力经常成为新闻头条,报告了它在医疗、金融等各个领域的积极影响。

然而,没有任何技术是免疫于失误的。虽然成功的故事描绘了机器学习的奇妙能力,但同样重要的是强调其陷阱,以便理解其影响的全貌。

在本文中,我们探讨了许多高-profile 机器学习失误,以便为未来更有信息化的实施提供借鉴。

目录

特别是,我们将查看以下每个类别中的一个值得注意的案例:

(1) 经典机器学习***(2)*** 计算机视觉***(3)*** 预测***(4)*** 图像生成***(5)*** 自然语言处理***(6)*** 推荐系统

可以在以下 GitHub 仓库 Failed-ML 中找到高-profile 机器学习失误的全面汇编:

[## GitHub — kennethleungty/Failed-ML: 高-profile 现实世界案例汇编

github.com](https://github.com/kennethleungty/Failed-ML?source=post_page-----26bd58692195--------------------------------)

(1) 经典机器学习

标题

亚马逊 AI 招聘系统: 亚马逊的人工智能驱动的自动招聘系统在出现对女性候选人的歧视证据后被取消。

细节

亚马逊开发了一款由人工智能驱动的招聘工具,以从十年的简历中识别顶尖候选人。然而,由于科技行业主要由男性主导,该系统对女性申请者表现出了偏见。

例如,它开始降级包含“女性”一词的简历或来自两所女性专用学院的毕业生的简历,同时偏爱某些术语(例如“执行”),这些术语在男性简历中出现频率更高。

亚马逊尝试纠正这些偏见,但在消除歧视性倾向方面面临挑战。因此,他们在 2017 年初终止了该项目,强调该系统从未用于实际候选人评估。

关键课程

训练数据中的偏见可能会在机器学习模型中延续,并导致人工智能系统中出现意想不到和歧视性的结果,这强调了多样化和具有代表性的数据集的重要性。

报告链接

## 亚马逊据报取消了一个 AI 招聘系统

详细信息

(2) 计算机视觉

标题

谷歌糖尿病视网膜病检测 AI: 该视网膜扫描工具在现实环境中的表现远不如在控制实验中的表现,问题包括由于扫描质量差而拒绝的扫描和因间歇性互联网连接导致的上传图像到云端的延迟。

细节

谷歌健康在泰国的 11 个诊所安装了一套深度学习系统,用于识别糖尿病患者眼部疾病的迹象。在实验室测试中,该系统能够以超过 90%的准确率从眼部扫描中识别糖尿病视网膜病,并在不到 10 分钟内给出结果。

然而,当实际部署时,由于图像质量差,AI 系统常常无法给出结果,拒绝了超过五分之一的图像。

当护士认为被拒绝的扫描没有显示出疾病迹象,或当他们不得不重拍和编辑 AI 系统拒绝的图像时,他们感到非常沮丧。几家诊所的糟糕互联网连接也导致了将图像上传到云端处理的延迟。

关键课程

重要的是将 AI 工具量身定制以适应现实环境的具体条件和限制,包括图像质量和离线可用性等因素。

参考资料

## 谷歌的医疗 AI 在实验室中的准确性非常高,但现实生活却完全不同。

www.technologyreview.com

(3) 预测

标题

Zillow 即时购买(iBuying)算法:由于其机器学习模型对房产估价的价格过高估计,Zillow 在房屋翻转业务中遭受了重大损失。

详细信息

像 Zillow 这样的房地产公司一直在使用 iBuying 商业模式,即直接从卖家那里购买房屋,然后在进行一些小修小补后重新挂牌出售。

Zillow 购买任何房屋的第一个步骤是“Zestimate”——基于一个在数百万次房屋估价上训练的模型的机器学习辅助的未来市场价值估算,并依赖于如房屋状况和邮政编码等数据。

然而,Zillow 的系统误判了未来的房价,导致他们向房主提出了许多高于市场的报价,特别是在 COVID-19 大流行引起的房地产波动期间。

这种误判最终导致了 Zillow 的即时购买操作的关闭,预计损失达到 3.8 亿美元。

关键教训

持续的模型监控、评估和再训练至关重要,以确保捕捉到新事件引起的数据漂移(导致测试数据分布的变化),以便进行最新的预测。

参考

## 为什么 Zillow 无法使算法房价定价成功

www.wired.com

(4) 图像生成

标题

Stable Diffusion(文本到图像模型):Stable Diffusion 在生成的数千张与职位名称和犯罪相关的图像中表现出种族和性别偏见。

详细信息

彭博社对 5000 多张使用 Stable Diffusion 生成的图像进行分析,发现了显著的种族和性别偏见。

使用 Fitzpatrick 皮肤分级标准进行分类,他们发现高薪职位的图像主要展示了肤色较浅的主体,而肤色较深则与“快餐工人”等低薪职业相关联。

同样,性别分析显示,每描绘一名女性的图像几乎会有三张图像描绘男性,大多数高薪职位的代表都是肤色较浅的男性。

Stable Diffusion 从 LAION-5B 获取数据,这是全球最大的公开可用图像-文本数据集,来自各种在线网站,包括暴力、仇恨符号等的描绘。

关键课程

审计用于机器学习的数据至关重要。例如,如果描绘放大刻板印象的图像通过增强训练数据回流到未来的模型中,下一代文本到图像模型可能会变得更加有偏见,形成偏见的滚雪球效应。

参考

www.bloomberg.com/graphics/2023-generative-ai-bias

(5) 自然语言处理

标题

ChatGPT 引用: 一名律师使用流行的聊天机器人 ChatGPT 来补充他的研究发现,但提供了完全虚构的不存在的过去案例。

细节

当一名名为史蒂文·施瓦茨的律师使用 ChatGPT 来协助准备与航空公司过失有关的伤害诉讼的法院文件时,事情很快出了岔子。

他提交的简报中包含了几项所谓相关的法院裁决引用,但航空公司的律师和主审法官都无法找到这些引用的裁决。

从事法律工作三十年的施瓦茨承认使用 ChatGPT 进行法律研究,但对其可能产生虚假内容一无所知。他甚至要求 ChatGPT 验证案件的有效性,而 ChatGPT 错误地确认了这些案件的存在。

关键课程

仅仅依赖像 ChatGPT 这样的生成模型的输出而不进行人工验证,可能导致重大不准确,突显了人类监督(即“人类在环”系统)和与可信来源交叉验证的必要性。

参考

[## 当你的律师使用 ChatGPT 时会发生什么

www.nytimes.com](https://www.nytimes.com/2023/05/27/nyregion/avianca-airline-lawsuit-chatgpt.html?source=post_page-----26bd58692195--------------------------------)

(6) 推荐系统

标题

IBM Watson 在肿瘤学中的应用: IBM 的 Watson 据称为癌症患者提供了大量不安全和不正确的治疗建议。

细节

曾被视为癌症研究的未来,IBM 的 Watson 超级计算机据报导已对癌症治疗提出了不安全的建议。

一个显著的例子是,它建议给一位重度出血的癌症患者用一种可能加重出血的药物。然而,这一建议被指出是理论性的,并未应用于实际患者。

根本问题源于输入 Watson 的数据的性质。IBM 的研究人员一直在输入假设性或“合成”案例,以使系统能够在更广泛的患者场景上进行训练。

然而,这也意味着许多建议主要基于提供数据的少数医生的治疗偏好,而不是从真实患者案例中得出的见解。

关键课程

训练数据的质量和代表性在机器学习中至关重要,尤其是在医疗等关键应用中,以避免偏见和潜在的有害结果。

参考资料

[## IBM 的 Watson 提供了不安全的癌症治疗建议

www.theverge.com

总结

虽然机器学习带来了许多好处,但我们必须记住它并不完美,正如本文中的众多实际错误所示。我们必须从这些错误中学习,以便未来更好地利用 AI 和机器学习。

查看这个 GitHub 仓库,获取完整的机器学习错误汇编。

在你离开之前

欢迎加入我的数据科学探索之旅! 关注我的Medium页面,并访问我的GitHub,以获取更多引人入胜和实用的内容。与此同时,祝你在探索机器学习中的成功与失误时玩得愉快!

## 在本地 CPU 上运行 Llama 2 进行文档问答

清晰解释如何使用 LLama 2、C Transformers、GGML 在 CPU 上运行量化开源 LLM 应用程序……

[towardsdatascience.com ## 微平均、宏平均和加权平均 F1 分数,清晰解释

理解 F1 分数的微平均、宏平均和加权平均背后的概念……

[towardsdatascience.com [## 为你的 Medium 帖子创建可点击的目录

创建动态目录的简单技巧,允许读者轻松滚动导航

medium.com

创作歌手何时最成功?

原文:towardsdatascience.com/when-are-songwriters-most-successful-9fdf90708e77

让我们用 KDE 图来找出答案。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Lee Vaughan

·发表在 Towards Data Science ·阅读时间 11 分钟·2023 年 8 月 22 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一位歌手在五彩纸屑飞舞中接受格莱美奖(由 DALL-E2 协助创建)

创作歌手在什么年龄段最成功?我前几天听到一首老歌时就想到了这个问题。我印象中,像数学家一样,创作歌手的巅峰期在 20 岁中期到晚期。但数据显示了什么?

在这个快速成功数据科学项目中,我们将使用 Python、pandas 和 Seaborn 绘图库来调查这个问题。我们将查看 16 位著名创作歌手的职业生涯,他们合计有超过 500 首热门歌曲。我们还将在分析中加入一种被称为核密度估计的迷人图形。

方法论

为了确定创作歌手何时最成功,我们需要一些指南。计划是检查:

  • 包括那些与合作者合作的创作歌手。

  • 职业生涯长达数十年的创作歌手。

  • 各种风格的创作歌手和音乐流派。

  • 《Billboard Hot 100》排行榜上的创作歌手。

Hot 100 是《Billboard》杂志每周发布的排行榜,列出美国表现最佳的歌曲。这些排名基于实体和数字销售、广播播放以及在线流媒体。我们将使用它作为一种一致客观的方式来判断成功。

数据

我们将使用以下高成功率艺术家的歌曲:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

本项目中使用的创作歌手名单(所有剩余的图片均由作者提供)。

我记录了每位艺术人在每首热门歌曲时的年龄,并将其保存为 CSV 文件,存储在这个 Gist 上。如果他们在同一年有多首热门歌曲,他们的年龄条目会为每首歌曲重复一次。这里是文件顶部的一个快照:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

CSV 文件的前几行。

交叉参考这些信息是繁琐的(ChatGPT 拒绝这么做!)。因此,一些由这些艺术家创作但由其他人表演的作品可能不小心被遗漏了。

核密度估计图

核密度估计图是一种类似于直方图的数据点分布可视化方法。虽然直方图对观察值进行分箱和计数,KDE 图则使用高斯核对观察值进行平滑。这产生了一个连续的密度估计,其中 y 值被归一化,使得曲线下的总面积等于一。

下图比较了这两种方法。它们对底层数据的捕捉效果取决于直方图的分箱方式和 KDE 图的平滑方式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

KDE 图(曲线)与直方图(条形)用于一系列观察值(点)的对比。

与直方图不同,直方图无法区分样本在某个区间内的具体位置,而 KDE 图会在每个单独的样本上绘制一个小的高斯钟形曲线。这些钟形曲线会被叠加在一起形成最终的曲线。这使得 KDE 图比直方图更宽,假设数据会平滑地扩展到极端值。因此,即使数据的硬限制为零,KDE 图也不会突然停在零处。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最终的 KDE 曲线是由每个单独数据点上的钟形曲线构建而成。

KDE 图使用带宽进行核平滑处理。选择合适的带宽既重要又具有一定的艺术性。带宽越小,KDE 图越能忠实于底层数据。带宽越大,数据被平均和平滑的程度越高。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

带宽平滑在 KDE 图中的示例。

狭窄的带宽会产生粗糙的曲线,这违背了使用 KDE 图的初衷。它们还可能引入随机噪声伪影。另一方面,宽带宽(如 2)可能会过度平滑,导致数据分布的重要特征(如双峰性)丢失。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

应用不同带宽调整对最终曲线的影响。

虽然 seaborn 库的kdeplot()方法使用了良好的默认值来生成图表,但你可能需要调整bw_adjust参数,以便将 KDE 图调整到你想要讲述的故事。

那么,为什么在已经有一个完美的直方图的情况下还要使用 KDE 图呢?以下是一些原因:

  • KDE 图比直方图更简洁,当在单个图中叠加多个分布时可读性更强。

  • KDE 图可以让你看到数据中的模式(如集中趋势、双峰性和偏斜),这些在直方图视图中可能会被遮蔽。

  • 类似于 sparklines,KDE 图形适合于“快速查看”和质量控制。

  • KDE 图形在视觉上可能比直方图更具吸引力,更适合面向大众的信息图表。

  • KDE 图形便于在数据子集之间进行轻松比较。

关于 KDE 图形的更多信息,请参阅 kdeplot()文档 和 seaborn 可视化指南的 Kernel density estimation 部分

安装库

对于这个项目,我们需要安装 seaborn 用于绘图,pandas 用于数据分析。你可以按如下方式安装这些库:

使用 conda: conda install pandas seaborn

使用 pip: pip install pandas seaborn

代码

以下代码在 JupyterLab 中编写,并按单元格描述。

导入库和加载数据

导入库后,我们将选择 seaborn 的“whitegrid”样式,以确保我们的图表具有一致的外观。然后我们将使用 pandas 读取 CSV 文件。

如果你使用虚拟环境,请注意 NumPy 和 Matplotlib 是 pandas 的依赖项,因此无需单独安装它们。

由于一些艺术家的热门歌曲比其他艺术家多,而 DataFrames 需要是矩形的,因此一些列将被分配缺失值。我们将使用 fillna() 方法将这些 NaN 值替换为零。

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd

sns.set(style='whitegrid')

# Load the data and set NaN values to zero:
df = pd.read_csv('https://bit.ly/3E8Q1BO').fillna(0)
df.head(3)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

初始 DataFrame 的前几行。

融化 DataFrame

我们的 DataFrame 目前是“宽格式”的。每个艺术家的名字是列的标题,他们的年龄是列的。Python 的绘图库更喜欢“长格式”。这意味着艺术家的名字应该是的值,并且应该为每个对应的年龄重复。

为了方便,pandas 提供了一个名为 melt() 的方法,可以将数据从宽格式转换为长格式。var_name 参数用于设置一个名为“Name”的新列,以存放之前的列名。value_name 参数表示之前的列值现在应该放在名为“Age”的列下。

此外,我们将添加一个名为“Color”的新列,并将其设置为“红色”。这是一种方便的方式,用于后续绘图时分组数据。我们还将过滤出 Age 值为零的记录,以准确统计每位艺术家的热门歌曲数量。

# Melt the DataFrame to a long format for plotting by artist name:
melted_df = pd.melt(df, var_name='Name', value_name='Age')

# Make a column for the plotting color:
melted_df['Color'] = 'red'

# Filter out zero values:
melted_df = melted_df[melted_df['Age'] != 0]

melted_df.tail(3)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

长格式融化的 DataFrame 的尾部。

绘制每位艺术家的热门歌曲数量

接下来,我们将使用 pandas 的 value_counts() 方法来计算每位艺术家的 Hot 100 热门歌曲数量。作为过程的一部分,我们将按降序排序数据。

# Calculate the order of the bars by counts:
order = melted_df['Name'].value_counts().index

# Plot a bar chart of the number of hits by each artist:
ax = sns.countplot(data=melted_df, 
                   x='Name', 
                   color='red', 
                   order=order)
ax.set_xticklabels(ax.get_xticklabels(), 
                   rotation=55, 
                   fontsize=10, 
                   ha='right')
ax.set_title('Number of Billboard Hot 100 Hits');

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每位艺术家在其职业生涯中的Hot 100 热门歌曲数量。

绘制最后一次热门歌曲时的年龄和歌曲之间的总时间

接下来,我们将绘制每位艺术人在其最后一次Hot 100热门歌曲时的年龄,以及首次和最后一次出现在榜单上的时间跨度。

由于我们需要找出每位艺术家的最小年龄,我们首先将df DataFrame 中的 0 值设置为NaN,这样它们将被忽略。否则,0 会被选为最小年龄。我们不会对结果进行排序,因为我们希望将图表并排比较,因此希望艺术家名称保持相同的顺序。

# Replace 0 values with NaN in order to find minimum age statistic:
df = df.replace(0, np.NaN)

# Calculate maximum age for each column
max_age = df.max()

# Calculate age span (maximum age - minimum age) for each column
age_span =df.max() - df.min()

# Create subplots for two bar charts
fig, axes = plt.subplots(nrows=1, ncols=2, 
                         figsize=(8, 6))

# Plot artist's age at time of last hit:
sns.barplot(x=max_age.values, 
            y=max_age.index, 
            ax=axes[0], 
            color='red', 
            orient='h')
axes[0].set_title('Artist Age at Time of Last Hit')
axes[0].set_xlabel('Age at Last Hit')
axes[0].set_ylabel('Artist')

# Plot age span between hits:
sns.barplot(x=age_span.values, 
            y=age_span.index, 
            ax=axes[1], 
            color='red', 
            orient='h')
axes[1].set_title("Years Between Artist's First & Last Hits")
axes[1].set_xlabel('Years Between First & Last Hit')
axes[1].set_ylabel('')

plt.tight_layout();

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

比较每位艺术家最后一次热门歌曲的年龄与歌曲之间的时间跨度。

从这些图表中可以得出结论,超过一半的艺术家在 50 岁之前就登上了所有热门榜单,并且这些热门歌曲的时间跨度为 30 年或更短。

计算年龄统计数据

现在,让我们找出艺术家们最成功的年龄。由于单一统计数据无法完全捕捉这一点,我们将使用 pandas 的mean()median()mode()方法。

# Calculate the statistics:
mean_age = round(melted_df.mean(numeric_only=True).mean(), 1)
median_age = round(melted_df.median(numeric_only=True).median(), 1)
mode_age = round(melted_df.mode(numeric_only=True).mode(), 1)

print(f"Mean age = {mean_age}")
print(f"Median age = {median_age}")
print(f"Mode age = {mode_age}")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在调查的 16 位创作歌手中,成功的“甜点”似乎在 29 至 33 岁之间。

注意:本分析的假设是歌曲是在其出现在Hot 100榜单的同一年创作的。由于歌曲创作和出现在榜单之间会有时间滞后,我们的统计数据可能会对年长的年龄有所偏倚。

使用 KDE 图找到成功的甜点

寻找甜点的可视化方式是使用 KDE 图。我们将使用 seaborn 的kdeplot()方法,并传递融化的 DataFrame。我们还将hue参数设置为“颜色”列,这意味着它将忽略艺术家的名字,并将所有年龄值绘制为一个组。

# Create a KDE plot for complete dataset:
ax = sns.kdeplot(data=melted_df, 
                 x='Age', 
                 hue='Color', 
                 fill=True, 
                 palette='dark:red_r', 
                 legend=False)

# Set x-axis tick positions:
ax.set_xticks(range(0, 85, 5))  

ax.set_title('KDE Plot of Billboard Hot 100 Hits by Age For All Artists',
             fontsize=14);

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所有艺术家的“年龄”列的 KDE 图。

该图确认了我们之前学到的,最大成功通常在 30 岁左右。70 岁后的高峰代表了保罗·麦卡特尼在 2015 年与坎耶·维斯特的合作,当时麦卡特尼 73 岁。

使用 Facet Grid 比较职业生涯

Facet grids是创建多个具有共享坐标轴的图表的方法,这些图表显示数据集的不同子集。我们将制作一个 facet grid,使用 KDE 图来比较每位艺术家的热门分布。

我们将首先调用 seaborn 的FacetGrid()方法,并将其应用于融化的 DataFrame 及其“名称”列。为了在没有干扰的情况下比较所有艺术家,我们将为每条曲线使用相同的颜色,由hue参数指定。通过将col_wrap参数设置为2,我们将显示分成 2 列,每列 8 条曲线。

定义好 facet grid 后,我们将调用kdeplot()方法,并将其映射到 facet grid 中,指定为g变量。我们将带宽调整(bw_adjust)设置为0.4,以避免平滑掉数据中的所有变异性。

# Plot a Facet Grid of each artist's hits vs. age as a KDE chart:
g = sns.FacetGrid(data=melted_df, 
                  col='Name', 
                  hue='Color', 
                  aspect=3, 
                  height=1.00, 
                  col_wrap=2, 
                  palette='dark:red_r')

g.map(sns.kdeplot, 'Age',
      fill=True, 
      alpha=0.7, 
      lw=2, 
      bw_adjust=0.4)

g.set_axis_labels('Age', 'Density')
g.set_titles(col_template='{col_name}')
g.tight_layout()

# Loop through each subplot to set custom x-axis tick labels:
for ax in g.axes.flat:
    ax.set_xticks(range(0, 80, 10))
    ax.set_xticklabels(range(0, 80, 10))

# Add a title to the FacetGrid
g.fig.suptitle('Billboard Hot 100 Hits vs. Age', 
               y=1.03,
               fontsize=16);

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每位艺术家的 KDE 图的 facet grid。

多么美妙的图表!简洁而信息丰富。这就是 KDE 图发挥作用的地方。

只需一眼,你就可以看到斯汀在警察乐队的早期成功,随后是成功的个人生涯。约翰尼·卡什的双峰分布反映了他与药物成瘾的斗争。保罗·西蒙在格拉斯兰专辑中的后期职业成功在 45 岁时显得只是一个短暂的高峰。正如我们在早期分析中所见,大多数峰值趋向于集中在 29 到 34 岁之间。

绘制堆叠 KDE 图

另一种用 KDE 图讲故事的方法是将它们堆叠在同一面板中。这总是比堆叠直方图效果更好。

对于我们当前的项目,有太多艺术家使得在个人层面上这种方法效果不佳。但由于我们的目标是突出所有艺术家的“成功甜点”,它做得还算不错。

要堆叠 KDE 图,我们只需调用 kdeplot() 方法,而不使用 facet grid。这里一个重要的参数是 common_norm,它代表“公共归一化”。

根据 seaborn 的文档,“当 common_norm 设置为 True 时,所有 KDE 曲线将使用相同的尺度进行归一化。这在你想比较不同组的整体分布形状时非常有用。当你有多个样本量不同或值范围不同的组时,尤其有帮助,因为这可以确保曲线在形状上直接可比。”

我们每位艺术家的样本量确实不同,并且希望比较曲线,所以我们将 common_norm 设置为 True

# Create a stacked KDE plot:
fig, ax = plt.subplots(figsize=(10, 6))
ax = sns.kdeplot(data=melted_df, 
                 x='Age', 
                 hue='Name', 
                 fill=True, 
                 palette='dark:red_r', 
                 common_norm=True)
ax.set_xticks(range(0, 85, 5))
ax.set_title('Stacked KDE Plot by Artist')
ax.set_xlabel('Age')
ax.set_ylabel('Density');

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每位艺术家的堆叠 KDE 图,公共归一化设置为“True”。

虽然很难甚至不可能识别特定艺术家的曲线(即使你为每位艺术家使用不同的颜色),但很明显最佳年龄在 30 岁左右。

如果你感兴趣的话,这里是 common_norm 设置为 False 时的图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

每位艺术家的堆叠 KDE 图,公共归一化设置为“False”。

绘制分布图

最后,让我们将数据可视化为分布图。seaborn 的 displot() 方法提供了一个图形级别的接口,用于在 seaborn FacetGrid 上绘制分布图。它允许你选择多种图类型,例如 KDE 和直方图,通过 kind 参数。

另一个不错的功能是添加了“rug 图”,通过 rug 参数实现。rug 图标记了数据点在轴上的位置。这让你能够看到实际数据的范围,这些数据可能被 KDE 图的“尾部”遮掩。

# Plot the distribution of hits vs age:
sns.displot(data=melted_df,
            x='Age', hue='Name',
            kind='kde', height=6,
            multiple='fill', clip=(0, None),
            palette='dark:red_r', 
            common_norm=True, rug=True);

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

包含 KDE 和 rug 图的分布图(图像由作者提供)

我个人发现这个图很难解读,但它确实突出了 30 岁左右的高峰成功年。

结论

KDE 曲线图以其平滑、令人愉悦的形状,是可视化单变量数据的绝佳方式。虽然功能上类似于直方图,但它们更容易展示数据中的模式,并在同一图形中堆叠和比较多个分布。

借助 KDE 曲线图,我们能够展示出创作歌手在大约 30 岁时最为成功。因此,如果你想开始创作歌手的职业生涯,千万不要拖延!

谢谢!

感谢阅读,请关注我,以便未来了解更多快速成功的数据科学项目。

当 AutoML 遇上大型语言模型

原文:towardsdatascience.com/when-automl-meets-large-language-model-756e6bb9baa7

利用 LLMs 的力量来指导超参数搜索

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 Shuai Guo

·发表于Towards Data Science ·23 分钟阅读·2023 年 10 月 5 日

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

约翰·施诺布里奇拍摄于Unsplash

自动化机器学习,简称 AutoML,旨在自动化机器学习流程中的各个步骤。其中一个关键方面是超参数调优。超参数是指控制机器学习算法结构和行为的参数(例如,神经网络模型中的层数),这些参数的值在训练之前设定,而不是从数据中学习,这与其他机器学习参数(例如神经网络层的权重和偏置)不同。

当前在 AutoML 中用于超参数调优的做法 heavily rely on sophisticated algorithms (such as 贝叶斯优化) to automatically identify the optimal combination of the hyperparameters that yields the best model performance.

从纯算法的角度解决超参数调优问题虽然有效,但还有另一个重要的信息可以补充算法搜索策略:人类专业知识

资深数据科学家凭借多年的经验和对机器学习算法的深刻理解,通常能够直观地知道从哪里开始搜索,哪些搜索空间的区域可能更有前景,或何时缩小或扩大可能性。

因此,这给了我们一个非常有趣的想法:我们能否设计一个可扩展的专家指导搜索策略,既利用专家提供的细致见解,又结合 AutoML 算法提供的搜索效率?

这是大语言模型(LLM),例如 GPT-4,可以发挥作用的地方。在它们的大量训练数据中,有一部分文本专门用于解释和讨论机器学习(ML)的最佳实践。由于这一点,LLM 能够内化大量的 ML 专业知识,并获得大量的集体 ML 智慧。这使得 LLM 作为潜在的知识渊博的 ML 专家,可以与现有的 AutoML 工具进行互动,共同进行专家指导的超参数调整。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

LLM 指导的超参数调整示例。(图像作者提供)

在这篇博客文章中,让我们尝试这个想法,并实现一个由 LLM 指导的超参数调整工作流。具体来说,我们将开发一个将 LLM 指导与简单随机搜索相结合的工作流,然后将其调整结果与一种名为FLAML(微软研究院开发的最先进的算法驱动的 AutoML 工具)的现成工具进行比较。进行这种比较的理由是评估即使与简单的搜索算法配对,借助 ML 领域专业知识是否真的能带来价值。

这个想法与你有共鸣吗?那就开始吧!

[注]: 本博客中展示的所有提示均由 ChatGPT (GPT-4) 生成并优化。这是必要的,因为它确保了提示的质量,并且有助于避免繁琐的手动提示工程。

这是我关于 LLM 项目的系列博客中的第四篇。第一篇是 构建 AI 驱动的语言学习应用,第二篇是 开发用于研究论文摘要的自主双聊天机器人系统,第三篇是 通过现实生活模拟训练数据科学中的问题解决技能。欢迎查看!

目录

· 1. 案例研究

∘ 1.1 数据集描述

∘ 1.2 模型描述

· 2. 工作流设计 · 3. 配置聊天机器人 · 4. 建议优化度量 · 5. 定义初始搜索空间 · 6. 精炼搜索空间 · 7. 调整日志分析

∘ 7.1 随机搜索与连续减半

∘ 7.2 日志分析

· 8. 案例研究

∘ 8.1 确定度量

∘ 8.2 第一次搜索迭代

∘ 8.3 第二次搜索迭代

∘ 8.4 第三次搜索迭代

∘ 8.5 测试

· 9. 与现成 AutoML 工具的比较 · 10. 结论

1. 案例研究

为了将我们的讨论具体化,让我们首先介绍一下我们将要调查的案例研究。

在本博客中,我们将查看一个二分类问题的超参数调优任务。更具体地,我们将研究一个名为NSL-KDD的网络安全数据集,并识别XGBoost模型的最佳超参数,以便训练出的模型可以准确区分良性和攻击活动。

1.1 数据集描述

NSL-KDD 数据集是网络入侵检测领域广泛使用的数据集。完整的数据集包含四种攻击类别,即 dos(拒绝服务)、r2l(远程机器的未经授权访问)、u2r(权限提升尝试)以及 probe(暴力探测攻击)。在我们当前的案例研究中,我们研究一个二分类问题:我们只考虑“良性”或“探测”性质的数据样本,并训练一个能够区分这两种状态的分类器。

NSL-KDD 数据集包含 40 个特征(例如,连接长度、协议类型、传输数据字节等),这些特征源自原始网络流量数据,捕获了单个网络连接的各种特征。数据集已经预先划分为训练集和测试集。下表显示了两个集合中的样本数量:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

训练集和测试集中样本的数量。(图片作者提供)

请注意,我们当前的数据集是不平衡的。这在网络安全应用中很常见,因为可用的攻击样本数量通常远小于良性样本的数量。

你可以在这里找到预处理的数据集。

1.2 模型描述

尽管完整的 AutoML 包括模型选择,但在当前的案例研究中,我们将范围限制在仅优化 XGBoost 模型。XGBoost 模型以其多才多艺的性能而闻名,但前提是使用了正确的模型超参数。不幸的是,由于 XGBoost 的超参数数量众多,确定给定数据集的最佳超参数组合并不容易。这正是 AutoML 可以发挥作用的地方。

我们考虑调整以下 XGBoost 超参数:

n_estimators, max_depth, min_child_weight, gamma, scale_pos_weight, learning_rate, subsample, colsample_bylevel, colsample_bytree, reg_alpha, 和 reg_lambda。

关于上述超参数的详细描述,请参阅官方文档

2. 工作流设计

要实现 LLM 指导的超参数调优,我们需要回答两个问题:我们应该如何将 LLM 的机器学习专业知识融入调优过程?我们应该如何让 LLM 与调优工具互动?

1️⃣ 如何将 LLM 的机器学习专业知识融入调整过程中?

好吧,在调整过程中至少有三个地方,LLM 的机器学习专业知识可以提供指导:

  • 建议优化指标:超参数调整通常需要一个指标来定义在各种竞争的超参数组合中什么被认为是“最优”的。这为基础的优化算法(例如,贝叶斯优化)设定了目标。LLMs 可以提供关于哪些指标更适合特定类型问题和数据集特征的见解,并可能提供对候选指标的优缺点解释。

  • 建议初始搜索空间:由于大多数超参数调整任务是以迭代方式进行的,通常需要配置初始搜索空间以为优化过程奠定基础。基于其学习的机器学习最佳实践,LLMs 可以推荐对研究数据集特征和选定机器学习模型有意义的超参数范围。这可以潜在地减少不必要的探索,从而节省大量计算时间。

  • 建议搜索空间的细化:随着调整过程的推进,通常需要对配置的搜索空间进行细化。细化可以朝两个方向进行,即缩小某些超参数的范围到显示出前景的区域,或扩展某些超参数的范围以探索新的领域。通过分析前几轮的优化日志,大型语言模型(LLMs)可以自动提出新的细化建议,将调整过程引导向更有前景的结果。

2️⃣ 如何让 LLM 与调整工具进行互动?

理想情况下,我们可以将随机搜索工具封装为 API,并实现一个基于 LLM 的代理,该代理可以访问这个 API 来进行调整。然而,由于时间有限,我未能配置一个能够可靠执行上述迭代调整过程的工作代理:有时代理由于输入模式不正确而无法正确使用工具;其他时候代理则完全偏离了任务。

作为替代,我实现了一个简单的基于聊天机器人的工作流,其中包含以下两个组件:

  • 具有记忆的聊天机器人。在这里,记忆很重要,因为聊天机器人需要回忆之前建议的搜索空间。

  • 三个提示分别对应建议优化指标、建议初始搜索空间和建议搜索空间的细化。

为了启动工作流,首先提示聊天机器人根据问题背景和数据集特征建议一个合适的优化指标。然后解析聊天机器人的响应,提取并存储指标名称作为变量。第二步,提示聊天机器人建议一个初始搜索空间。与第一步一样,解析响应并提取搜索空间,存储为变量。获得这两个信息后,将调用随机搜索工具,使用聊天机器人建议的指标和搜索空间。总体而言,这构成了第一轮迭代。

一旦随机搜索工具完成搜索,将提示聊天机器人根据上一次运行的结果推荐搜索空间的细化。在成功解析聊天机器人的响应中的新搜索空间后,将进行另一轮随机搜索。这个过程会迭代,直到计算预算耗尽或达到收敛,例如,较上次运行没有更多改进。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

基于聊天机器人的解决方案,用于实现 LLM 引导的超参数调优。(图像由作者提供)

尽管不如基于代理的方法优雅,这种基于聊天机器人的工作流具有几个好处:

  • 易于实现和实现质量控制。将聊天机器人与调优工具集成简化为设计三个提示和几个辅助函数,以从聊天机器人的响应中提取目标信息。这比完全集成的基于代理的方法要简单得多。此外,由于超参数调优任务被分解为明确的步骤,每一步都可以被监控和调整,从而使质量控制变得更可控,确保搜索过程保持在轨道上。

  • 完全透明的决策过程。由于聊天机器人会清晰地说明其做出的每个决策或建议,超参数调优过程不再是对用户的黑箱过程。这对于实现可解释的值得信赖的 AutoML 至关重要。

  • 允许结合人类直觉。尽管当前的工作流设计为自动化,但可以轻松扩展,以允许人类专家在每次搜索迭代之前选择接受建议或根据自己的专业知识进行必要的调整。这种灵活性为人类参与的调优打开了大门,可能会导致更好的优化结果。

在接下来的章节中,我们将逐一详细介绍配置聊天机器人以及建议指标、初始搜索空间和搜索空间细化的提示。

3. 配置聊天机器人

我们可以使用 LangChain 轻松设置一个具有记忆的聊天机器人。我们首先导入必要的库:

from langchain.prompts import (
    ChatPromptTemplate, 
    MessagesPlaceholder, 
    SystemMessagePromptTemplate, 
    HumanMessagePromptTemplate
)
from langchain.chains import ConversationChain
from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferMemory

在 LangChain 中,聊天机器人可以通过ConversationChain对象进行配置,这需要一个主干 LLM、一个用于保存对话历史的内存对象以及一个用于指定聊天机器人行为的提示模板:

# Set up LLM
llm = ChatOpenAI(temperature=0.8)

# Set up memory
memory = ConversationBufferMemory(return_messages=True)

# Set up the prompt
prompt = ChatPromptTemplate.from_messages([
    SystemMessagePromptTemplate.from_template(system_message),
    MessagesPlaceholder(variable_name="history"),
    HumanMessagePromptTemplate.from_template("""{input}""")
])

# Create conversation chain
conversation = ConversationChain(memory=memory, prompt=prompt, 
                                llm=llm, verbose=False)

在上面的代码片段中,变量system_message设置了聊天机器人的上下文,如下所示:

# Note: the prompt is generated and optimized by ChatGPT (GPT-4)
system_message = f"""
You are a senior data scientist tasked with guiding the use of an AutoML 
tool to discover the best XGBoost model configurations for a given binary 
classification dataset. Your role involves understanding the dataset 
characteristics, proposing suitable metrics, hyperparameters, and their 
search spaces, analyzing results, and iterating on configurations. 
"""

注意,我们在系统消息中指定了聊天机器人的角色、目的和预期行为。稍后,我们可以使用配置好的聊天机器人进行推理:

# Invoke chatbot with the input prompt
response = conversation.predict(input=prompt)

其中 prompt 是我们对聊天机器人的具体指令,即建议优化度量标准、建议初始搜索空间或建议优化搜索空间。我们将在接下来的几节中介绍这些提示。

4. 建议优化度量标准

作为 LLM 引导的超参数调整的第一步,我们希望聊天机器人提出一个合适的度量标准,以便调整工具进行优化。这个决定应基于几个因素,包括问题的性质(即回归还是分类)、给定数据集的特征,以及来自业务或实际应用的其他具体要求。

以下片段定义了实现我们目标的提示:

def suggest_metrics(report):

    # Note: The prompt is generated and optimized by ChatGPT (GPT-4)
    prompt = f"""
    The classification problem under investigation is based on a network 
    intrusion detection dataset. This dataset contains Probe attack type, 
    which are all grouped under the "attack" class (label: 1). Conversely, 
    the "normal" class is represented by label 0\. Below are the dataset's 
    characteristics:
    {report}.

    For this specific inquiry, you are tasked with recommending a suitable 
    hyperparameter optimization metric for training a XGBoost model. It is 
    crucial that the model should accurately identify genuine threats (attacks) 
    without raising excessive false alarms on benign activities. They are equally 
    important. Given the problem context and dataset characteristics, suggest 
    only the name of one of the built-in metrics: 
    - 'accuracy'
    - 'roc_auc' (ROCAUC score)
    - 'f1' (F1 score)
    - 'balanced_accuracy' (It is the macro-average of recall scores per class 
    or, equivalently, raw accuracy where each sample is weighted according to 
    the inverse prevalence of its true class) 
    - 'average_precision'
    - 'precision'
    - 'recall'
    - 'neg_brier_score'

    Please first briefly explain your reasoning and then provide the 
    recommended metric name. Your recommendation should be enclosed between 
    markers [BEGIN] and [END], with standalone string for indicating the 
    metric name.
    Do not provide other settings or configurations.
    """

    return prompt

在上面的提示中,我们已经向聊天机器人说明了问题的背景、数据集特征(封装在变量report中,我们稍后将讨论),目标(推荐一个适合的超参数优化度量标准用于训练 XGBoost 模型)、具体要求(高检测率和低误报率)以及候选度量标准(它们都在 sci-kit learn 中受支持)。注意,我们明确要求聊天机器人将度量标准名称输出在[BEGIN]-[END]块内,这样可以方便地自动提取信息。

为了生成数据报告,我们可以定义以下函数:

def data_report(df, num_feats, bin_feats, nom_feats):
    """
    Generate data characteristics report.

    Inputs:
    -------
    df: dataframe for the dataset.
    num_feats: list of names of numerical features.
    bin_feats: list of names of binary features.
    nom_feats: list of names of nominal features.

    Outputs:
    --------
    report: data characteristics report.
    """

    # Label column 
    target = df.iloc[:, -1]
    features = df.iloc[:, :-1]

    # General dataset info
    num_instances = len(df)
    num_features = features.shape[1]

    # Class imbalance analysis
    class_counts = target.value_counts()
    class_distribution = class_counts/num_instances

    # Create report
    # Note: The format of the report is generated and optimized
    # by ChatGPT (GPT-4)
    report = f"""Data Characteristics Report:

- General information:
  - Number of Instances: {num_instances}
  - Number of Features: {num_features}

- Class distribution analysis:
  - Class Distribution: {class_distribution.to_string()}

- Feature analysis:
  - Feature names: {features.columns.to_list()}
  - Number of numerical features: {len(num_feats)}
  - Number of binary features: {len(bin_feats)}
  - Binary feature names: {bin_feats}
  - Number of nominal features: {len(nom_feats)}
  - Nominal feature names: {nom_feats}
"""

    return report

在这里,我们特别计算了给定的数据集是否存在不平衡,因为这一信息可能会影响优化度量标准的选择。

现在我们已经完成了第一个提示,指示聊天机器人建议一个适合的度量标准来评估各种超参数配置的性能。接下来,让我们看看如何构建定义初始搜索空间的提示。

5. 定义初始搜索空间

除了优化度量标准,我们还需要一个超参数的初始搜索空间来开始调整过程。以下片段展示了实现这一目标的提示:

def suggest_initial_search_space():

    # Note: The prompt is generated and optimized by ChatGPT (GPT-4) 
    prompt = f"""
    Given your understanding of XGBoost and general best practices in machine 
    learning, suggest an initial search space for hyperparameters. 

    Tunable hyperparameters include:
    - n_estimators (integer): Number of boosting rounds or trees to be trained.
    - max_depth (integer): Maximum tree depth for base learners.
    - min_child_weight (integer or float): Minimum sum of instance weight 
    (hessian) needed in a leaf node. 
    - gamma (float): Minimum loss reduction required to make a further 
    partition on a leaf node of the tree.
    - scale_pos_weight (float): Balancing of positive and negative weights.
    - learning_rate (float): Step size shrinkage used during each boosting 
    round to prevent overfitting. 
    - subsample (float): Fraction of the training data sampled to train each 
    tree. 
    - colsample_bylevel (float): Fraction of features that can be randomly 
    sampled for building each level (or depth) of the tree.
    - colsample_bytree (float): Fraction of features that can be randomly 
    sampled for building each tree. 
    - reg_alpha (float): L1 regularization term on weights. 
    - reg_lambda (float): L2 regularization term on weights. 

    The search space is defined as a dict with keys being hyperparameter names, 
    and values are the search space associated with the hyperparameter. 
    For example:
        search_space = {{
            "learning_rate": loguniform(1e-4, 1e-3)
        }}

    Available types of domains include: 
    - scipy.stats.uniform(loc, scale), it samples values uniformly between 
    loc and loc + scale.
    - scipy.stats.loguniform(a, b), it samples values between a and b in a 
    logarithmic scale.
    - scipy.stats.randint(low, high), it samples integers uniformly between 
    low (inclusive) and high (exclusive).
    - a list of possible discrete value, e.g., ["a", "b", "c"]

    Please first briefly explain your reasoning, then provide the 
    configurations of the initial search space. Enclose your suggested 
    configurations between markers [BEGIN] and [END], and assign your 
    configuration to a variable named search_space.
    """

    return prompt

上面的提示包含了大量信息,所以我们来逐步拆解:

  • 我们首先向聊天机器人说明了我们的目标。

  • 我们提供了一个可调超参数及其含义的列表。此外,我们还指出了每个超参数的预期数据类型。这些信息对 LLM 决定采样分布至关重要。

  • 我们定义了搜索空间的预期输出格式,以便进行有效解析。

  • 我们指明了 LLM 可以建议的可用采样分布。

请注意,我们明确要求聊天机器人简要说明建议的搜索空间的理由。这对于实现透明度和可解释性至关重要。

这就是推荐初始搜索空间的内容。接下来,我们来看看如何优化搜索空间。

6. 优化搜索空间

在从聊天机器人获取优化指标和初始搜索空间后,我们可以启动一次调优轮次。随后,我们可以将生成的 AutoML 日志输入到聊天机器人中,并提示它建议对搜索空间进行优化。

以下代码片段展示了实现目标的提示:

def suggest_refine_search_space(top_n, last_run_best_score, all_time_best_score):
    """
    Generate prompt for refining the search space.

    Inputs:
    -------
    top_n: string representation of the top-5 best-performing configurations.
    last_run_best_score: best test score from the last run.
    all_time_best_score: best test score from all previous runs.

    Outputs:
    --------
    prompt: generated prompt.
    """

    # Note: The prompt is generated and optimized by ChatGPT (GPT-4)
    prompt = f"""
    Given your previously suggested search space, the obtained top configurations 
    with their test scores:
    {top_n}

    The best score from the last run was {last_run_best_score}, while the best 
    score ever achieved in all previous runs is {all_time_best_score}

    Remember, tunable hyperparameters are: n_estimators, max_depth, min_child_samples, 
    gamma, scale_pos_weight, learning_rate, subsample, colsample_bylevel, 
    colsample_bytree, reg_alpha, and reg_lambda.

    Given the insights from the search history, your expertise in ML, and the 
    need to further explore the search space, please suggest refinements for 
    the search space in the next optimization round. Consider both narrowing 
    and expanding the search space for hyperparameters where appropriate.

    For each recommendation, please:
    1\. Explicitly tie back to any general best practices or patterns you are 
    aware of regarding XGBoost tuning
    2\. Then, relate to the insights from the search history and explain how 
    they align or deviate from these practices or patterns.
    3\. If suggesting an expansion of the search space, please provide a 
    rationale for why a broader range could be beneficial.

    Briefly summarize your reasoning for the refinements and then present the 
    adjusted configurations. Enclose your refined configurations between 
    markers [BEGIN] and [END], and assign your configuration to a variable 
    named search_space.
    """

    return prompt

有几个值得解释的地方:

  • 我们向聊天机器人提供了上一次调优轮次中表现最好的前 5 个配置及其相关测试分数。这可以作为聊天机器人确定下一轮优化的基础。

  • 通过包括上一次运行的最佳测试分数和所有之前的运行,聊天机器人可以判断上次运行中建议的搜索空间是否有效。

  • 我们明确要求聊天机器人考虑进一步探索搜索空间。一般而言,优化的最佳实践是平衡探索与利用。由于我们使用的随机搜索算法(将在结果部分讨论)已经涵盖了利用,因此让 LLM 更多地关注探索是合理的。

  • 与其他提示类似,我们要求 LLM 对其建议进行推理,以确保透明度和可解释性。

在下一节中,让我们看看生成top_n变量的日志分析逻辑。

7. 调优日志分析

作为一种迭代方法,我们希望聊天机器人在上一轮搜索完成后提出新的搜索空间,而决策过程的基础应该是上一轮搜索中生成的日志。在本节中,我们首先介绍了当前案例研究中使用的搜索算法。然后,我们讨论了日志结构和提取有用见解的代码。

7.1 逐步折半的随机搜索

正如本文开头所提到的,我们希望将一种简单的超参数搜索算法与 LLM 结合,以检验领域专业知识是否能带来价值。

最简单的调优方法之一是随机搜索:对于一个定义好的搜索空间(通过将采样分布附加到超参数上来指定),对给定数量的超参数组合实例进行采样,并评估其相关的模型性能。产生最佳性能的采样超参数配置被认为是最佳的。

尽管其简单性,随机搜索的朴素版本可能导致计算资源的低效使用,因为它不区分超参数配置,而不良的超参数选择仍然会被训练。

为解决这个问题,提出了连续折半技术,以增强基本的随机搜索策略。基本上,连续折半策略首先使用少量资源评估许多配置,然后逐渐将更多资源分配给有前景的配置。因此,劣质配置可以在早期有效地被淘汰,从而提高搜索效率。Sci-kit Learn 提供了精确实现这一策略的[HalvingRandomSearchCV](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.HalvingRandomSearchCV.html)估算器,我们将在当前案例研究中采用。

7.2 日志分析

当运行[HalvingRandomSearchCV](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.HalvingRandomSearchCV.html)搜索时,搜索日志存储在属性cv_results_中。原始日志以字典格式存储,可以转换为 Pandas 数据框以便于提取见解:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

搜索算法生成的日志。(示例取自官方用户指南。)

对于我们当前的目的,我们希望提取表现最好的前 N 个(默认 5 个)配置及其相关的测试分数。以下函数展示了我们如何实现这一目标:

def logs_analysis(results, N):
    """
    Extracting the top performing configs from the logs.

    Inputs:
    -------
    results: results dict produced by the sklearn search object.
    N: the number of top performing configs to consider.

    Outputs:
    --------
    top_config_summary: a string summary of the top-N best performing configs 
    and their associated test scores.
    last_run_best_score: the best test score obtained in the current search run.
    """

    # Convert to Dataframe
    df = pd.DataFrame(search.cv_results_)

    # Rank configs' performance
    top_configs = df.nsmallest(N, 'rank_test_score').reset_index(drop=True)

    # Considered hyparameters
    hyperparameter_columns = [
        'param_colsample_bylevel', 'param_colsample_bytree', 'param_gamma',
        'param_learning_rate', 'param_max_depth', 'param_min_child_weight',
        'param_n_estimators', 'param_reg_alpha', 'param_reg_lambda',
        'param_scale_pos_weight', 'param_subsample'
    ]

    # Convert to string
    config_strings = []
    for i, row in top_configs.iterrows():
        config = ', '.join([f"{col[6:]}: {row[col]}" for col in hyperparameter_columns])
        config_strings.append(f"Configuration {i + 1} ({row['mean_test_score']:.4f} test score): {config}")

    top_config_summary = '\n'.join(config_strings)

    # Best test score
    last_run_best_score = top_configs.loc[0, 'mean_test_score']

    return top_config_summary, last_run_best_score

8. 案例研究

现在我们拥有了所有的要素,是时候将 LLM 指导的工作流程应用于我们的案例研究了。

8.1 确定度量标准

首先,我们提示 LLM 建议一个合适的优化度量标准:

# Suggest metrics
prompt = suggest_metrics(report)
response = conversation.predict(input=prompt)
print(response)

以下是 LLM 生成的响应:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

LLM 建议了一个合适的度量标准,并提供了理由。(图片作者提供)

我们可以看到,LLM 根据问题背景和数据集特征推荐了“F1”分数作为度量标准,这与我们的期望一致。此外,度量标准名称被正确地封装在我们指定的后处理标记之间。

8.2 第一次搜索迭代

接下来,我们提示 LLM 建议一个初步的搜索空间:

# Initial search space
prompt = suggest_initial_search_space()
response = conversation.predict(input=prompt)
print(response)

LLM 的输出如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

LLM 建议了一个初步的搜索空间,并提供了理由。(图片作者提供)

我们可以看到,LLM 忠实地遵循了我们的指示,并提供了有关设置每个可调超参数的变异范围的详细说明。这对确保超参数调优过程的透明性至关重要。此外,请注意 LLM 成功输出了正确格式的搜索空间。这显示了在提示设计中提供具体示例的重要性。

然后,我们调用随机搜索与连续折半,并运行第一次迭代:

from sklearn.experimental import enable_halving_search_cv
from sklearn.model_selection import HalvingRandomSearchCV
import xgboost as xgb

clf = xgb.XGBClassifier(seed=42, objective='binary:logistic', 
                        eval_metric='logloss', n_jobs=-1, 
                        use_label_encoder=False)
search = HalvingRandomSearchCV(clf, search_space, scoring='f1', 
                               n_candidates=500, cv=5, 
                               min_resources='exhaust', factor=3, 
                               verbose=1).fit(X_train, y_train)

请注意,HalvingRandomSearchCV 估计器仍处于实验阶段。因此,在使用估计器之前,必须首先显式导入 enable_halving_search_cv

使用 HalvingRandomSearchCV 估计器需要设置几个参数。除了指定估计器(clf)、参数分布(搜索空间)和优化指标(f1)外,我们还需要指定控制时间预算的参数。在我们的案例中,我们将 n_candidates 设置为 500,这意味着我们将在第一次迭代中抽取 500 个候选配置(每个配置有不同的超参数组合)。此外,factor 设置为 3,这意味着每次后续迭代中仅选择三分之一的候选者。同时,这些选中的三分之一的候选者将在后续迭代中使用三倍的资源(即训练样本数)。最后,我们将 min_resource 设置为“exhaust”,这意味着在最后一次迭代中,剩余的候选者将使用所有可用的训练样本。有关设置 HalvingRandomSearchCV 估计器的详细说明,请参阅此帖子:使用 HalvingGridSearch 速度提升 11 倍的超参数调优。

下面显示了运行 HalvingRandomSearchCV 估计器生成的日志快照。在我的电脑上运行搜索的实际时间约为 20 分钟。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

连续缩小随机搜索算法生成的日志快照。(图片来源:作者)

8.3 第二次搜索迭代

一旦搜索完成,我们可以从 search.cv_results 中检索搜索历史记录,并将其发送到之前定义的 log_analysis() 函数以提取调优见解。之后,我们调用 suggest_refine_search_space() 函数来提示 LLM 根据之前的搜索结果推荐新的搜索空间:

# Configure prompt
prompt = suggest_refine_search_space(top_n, last_run_best_score, all_time_best_score)

# Refine search space
response = conversation.predict(input=prompt)
print(response)

LLM 的响应如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

LLM 建议了搜索空间的优化并提供了理由。(图片来源:作者)

在这里,我们可以看到 LLM 建议对一些超参数进行缩小空间,对其他超参数进行扩展空间。这些建议的理由也被清晰地阐述,从而提高了可解释性和透明度。

基于优化后的搜索空间,我们可以第二次运行 HalvingRandomSearchCV 估计器:

clf = xgb.XGBClassifier(seed=42, objective='binary:logistic', 
                        eval_metric='logloss', n_jobs=-1, 
                        use_label_encoder=False)
search = HalvingRandomSearchCV(clf, search_space, scoring='f1', 
                               n_candidates=500, cv=5, 
                               min_resources='exhaust', factor=3, 
                               verbose=1).fit(X_train, y_train)

在我的电脑上运行搜索的实际时间约为 29 分钟。

8.4 第三次搜索迭代

让我们再运行一次 LLM 引导的搜索。与之前一样,我们首先从之前的搜索日志中提取有用的见解,然后提示 LLM 进一步优化搜索空间。LLM 生成的响应如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

LLM 建议了搜索空间的优化并提供了理由。(图像由作者提供)

在新定义的搜索空间下,我们第三次运行了 HalvingRandomSearchCV 估计器:

clf = xgb.XGBClassifier(seed=42, objective='binary:logistic', 
                        eval_metric='logloss', n_jobs=-1, 
                        use_label_encoder=False)
search = HalvingRandomSearchCV(clf, search_space, scoring='f1', 
                               n_candidates=100, cv=5, 
                               min_resources='exhaust', factor=3, 
                               verbose=1).fit(X_train, y_train)

在我的 PC 上运行搜索的时间大约为 11 分钟。

8.5 测试

经过三轮随机搜索后,让我们测试获得的 XGBoost 模型的性能。为此,我们可以定义一个辅助函数来计算各种性能指标:

from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
from sklearn.metrics import (
    precision_score,
    recall_score,
    accuracy_score,
    roc_auc_score,
    f1_score,
    matthews_corrcoef
)

def metrics_display(y_test, y_pred, y_pred_proba):

    # Obtain confusion matrix
    cm = confusion_matrix(y_test, y_pred)

    # Output classification metrics
    tn, fp, fn, tp = cm.ravel()

    print(f'ROC_AUC score: {roc_auc_score(y_test, y_pred_proba):.3f}')
    print(f'f1 score: {f1_score(y_test, y_pred):.3f}')
    print(f'Accuracy: {accuracy_score(y_test, y_pred)*100:.2f}%')
    print(f'Precision: {precision_score(y_test, y_pred)*100:.2f}%')
    print(f'Detection rate: {recall_score(y_test, y_pred)*100:.2f}%')
    print(f'False alarm rate: {fp / (tn+fp)*100}%')
    print(f'MCC: {matthews_corrcoef(y_test, y_pred):.2f}')

    # Display confusion matrix
    disp = ConfusionMatrixDisplay(confusion_matrix=cm)
    disp.plot()

# Calculate performance metrics
y_pred = search.predict(X_test)
y_pred_proba = search.predict_proba(X_test)
metrics_display(y_test, y_pred, y_pred_proba[:, 1])

在上述代码片段中,我们将训练好的 XGBoost 模型应用于测试数据集,并评估其性能。获得的混淆矩阵如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

训练后的 XGBoost 模型在测试数据集上的混淆矩阵。(图像由作者提供)

根据混淆矩阵,我们可以计算各种性能指标:

  • 准确率:94.22%

  • 精确度:89.5%

  • 检测率(召回率):80.52%

  • 虚警率(1-特异性):2.35%

  • ROC-AUC 分数:0.983

  • F1 分数:0.848

  • 马修斯相关系数:0.81

9. 与开箱即用 AutoML 工具的比较

正如我们在开头提到的,我们希望将开发的 LLM 引导搜索的调优结果与现成的、基于算法的 AutoML 工具进行比较,以评估是否借助 ML 领域专业知识确实能带来价值。

我们将使用的 AutoML 工具叫做 FLAML,由微软研究院开发,代表 一种用于自动机器学习和调整的快速库。此工具是最先进的,支持快速且经济的自动调优,能够处理具有异质评估成本和复杂约束/指导/提前停止的大型搜索空间。有关安装库的详细信息,请参阅 官方页面

使用此工具极其简单:在下面的代码片段中,我们首先实例化一个AutoML对象,然后调用其fit()方法启动超参数调整过程。我们将调整限制在 XGBoost 模型上(FLAML 也支持其他模型类型),并设置 3600 秒的时间预算,这大致等于我们在 3 轮 LLM 引导搜索中花费的总时间(随机搜索时间+ LLM 响应时间)。

from flaml import AutoML

automl = AutoML()
automl.fit(X_train, y_train, task="classification", time_budget=3600, 
          estimator_list=['xgboost'], log_file_name='automl.log', 
          log_type='best')

以下是 LLM 引导搜索与开箱即用的 FLAML 结果的比较:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

两种调优方法的结果比较。(图像由作者提供)

我们可以看到,LLM-guided 搜索在所有考虑的指标上都比开箱即用的 FLAML 表现更好。由于我们关注的是网络安全应用,两个最重要的指标是检测率误报率。在这里,我们可以看到 LLM-guided 搜索成功显著提高了检测率,同时略微降低了误报率。因此,通过 LLM-guided 搜索训练的 XGBoost 模型将是一个优于 FLAML 搜索模型的异常检测器。

总的来说,我们可以得出结论,对于我们当前的案例研究,利用嵌入在 LLM 中的机器学习领域专业知识确实可以在超参数调优中带来价值,即使它与简单的搜索算法配对。

10. 结论

在本博客中,我们探讨了一种新的 AutoML 范式:LLM-guided 超参数调优。这里的关键思想是将大型语言模型视为机器学习专家,并利用其机器学习领域知识来提出合适的优化指标、建议初始搜索空间以及推荐搜索空间的细化。

随后,我们将这种方法应用于识别网络安全数据集的最佳 XGBoost 模型,我们的结果表明,信息驱动的超参数搜索(即 LLM-guided 搜索)比纯算法驱动的 AutoML 工具 FLAML 产生了更好的异常检测模型,达到了更高的检测率和更低的误报率。

如果你觉得我的内容有用,你可以在这里请我喝杯咖啡 🤗和往常一样,你可以在这里找到包含完整代码的伴随笔记本💻如果你想深入了解,可以查看以下两篇最近的研究论文,它们研究了相同的主题:

此外,如果你对大型语言模型的其他有趣应用感兴趣,可以看看我之前的博客:

  • 构建一个 AI 驱动的语言学习应用

  • 开发自主双聊天机器人系统以消化研究论文

  • 通过现实生活模拟训练数据科学中的问题解决技能。

期待与你分享更多令人兴奋的 LLM 项目。敬请关注!

内容概要:本文详细探讨了双馈风力发电机(DFIG)在Simulink环境下的建模方法及其在不同风速条件下的电流与电压波形特征。首先介绍了DFIG的基本原理,即定子直接接入电网,转子通过双向变流器连接电网的特点。接着阐述了Simulink模型的具体搭建步骤,包括风力机模型、传动系统模型、DFIG本体模型和变流器模型的建立。文中强调了变流器控制算法的重要性,特别是在应对风速变化时,通过实时调整转子侧的电压和电流,确保电流和电压波形的良好特性。此外,文章还讨论了模型中的关键技术和挑战,如转子电流环控制策略、低电压穿越性能、直流母线电压脉动等问题,并提供了具体的解决方案和技术细节。最终,通过对故障工况的仿真测试,验证了所建模型的有效性和优越性。 适用人群:从事风力发电研究的技术人员、高校相关专业师生、对电力电子控制系统感兴趣的工程技术人员。 使用场景及目标:适用于希望深入了解DFIG工作原理、掌握Simulink建模技能的研究人员;旨在帮助读者理解DFIG在不同风速条件下的动态响应机制,为优化风力发电系统的控制策略提供理论依据和技术支持。 其他说明:文章不仅提供了详细的理论解释,还附有大量Matlab/Simulink代码片段,便于读者进行实践操作。同时,针对一些常见问题给出了实用的调试技巧,有助于提高仿真的准确性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值