如何解释 Logistic 回归中分类变量的比值比
参考类别说明及选择正确的类别

逻辑回归是一个非常流行的机器学习模型,一直是许多文章和博客的焦点。虽然有一些使用相对简单的数据的精彩例子,但我很难找到一篇使用分类变量作为特征的综合文章。
为什么每个变量的一个类别在统计输出中被省略?我如何解释回归系数,即“对数优势比”,一个特定类别的变量?
我将通过涵盖以下主题来揭开这一神秘面纱:
虚拟变量概述
什么是参考类别,如何选择一个
如何解释虚拟变量的比值比
我将使用 Python 和 statsmodels 包(有很好的统计输出)以及一个开源的自行车旅行数据集,该数据集包含纽约市的城市自行车数据和大量派生的分类变量。从行程持续时间特性中,我生成了一个布尔目标变量,表示自行车行程是否超过 20 分钟,我已经武断地决定这是一次“长”行程。我们将研究哪些分类特征会显著增加或减少自行车旅行超过 20 分钟的几率。
我们开始吧!
处理分类数据—你好虚拟变量
数据变量可以是连续的(介于理论最小值和最大值之间的测量值,如年龄、体重)或分类的/离散的(固定值或分类,如工作日、性别)。分类数据不能直接用于机器学习算法,因此需要进行预处理。
分类变量可以转换成数字的虚拟变量,这是一种更好的格式。这是数据被转置的地方,因此每个类别由一组二进制特征表示,指示该类别在每行数据中的存在与否。两种流行的方法是熊猫 get_dummies() 和 s cikit-learn 的 OneHotEncoder() 。在这篇文章中,我将重点介绍 pd.get_dummies 方法。
为了避免多重共线性(变量之间的相关性),大多数模型都要求从数据中删除一个哑变量。这是如何工作的?因为每行至少有一个特性类别的值(假设您已经处理了丢失的值!),如果特性的每个虚拟变量都是 0,那么默认情况下,最后一个类别必须是 1。因此,可以删除一个虚拟变量。
那么我们如何删除一个虚拟变量呢?
“drop _ first”参数可能不是你的朋友
我学会了在使用 pd.get_dummies()创建虚拟变量时总是使用“drop_first=True”参数。这是在线学习平台涵盖的概念之一,但似乎从未深入到你使用它时实际发生的细节。
我注意到我不能选择哪个类别被删除。默认情况下,它总是删除按字母顺序排列的类别。这违背了所有的数据科学逻辑——当然,类别很重要,而且肯定有一些数据驱动的逻辑来挑选哪一个没有通过最终筛选?
让我们来回答第一个问题。为什么删除类别很重要?
参考类别
被丢弃的类别被称为引用类别。当您解释您的模型的结果时,该类别将与所有其他类别进行比较。
考虑到这一点,有必要通过将逻辑回归模型与您的数据相拟合来回想您试图回答的问题。在我们的例子中,一次自行车旅行是否会超过 20 分钟,你想确定事件发生的几率是多少?相对于其他类别,例如一周中的某一天,您是否对特定类别的效果感兴趣?(后面更有解读!)
因此,参考类别应该是允许更容易解释的类别,也是您最关心的类别。从数学上来说,这可能是在您的数据中具有最大代表性的类别,即代表“标准”的类别。同样,它也可能是在您的数据中意外出现的类别。
可视化你的数据可以帮助你做出决定。要素类别的频率或百分比的简单条形图有助于了解它们在数据中的分布情况。它还会揭示你可能想要研究的任何有趣或意想不到的模式。
现在让我们考虑一下我们的纽约自行车旅行数据。我已经从每次自行车旅行的开始时间中获得了额外的特征;“工作日”,七个类别代表一周中的某一天,“日类型”表示旅行发生在工作日还是周末。对于那些骑自行车观光的人来说,你可能会认为周末(周六和周日)是骑自行车旅行时间较长的日子。事实上,我们下面的探索性可视化显示,周六的自行车旅行超过 20 分钟的比例似乎略高。

图片由作者提供,在 matplotlib 中创建。
如果您的研究问题旨在解决一周中的某一天对自行车旅行超过 20 分钟是否有影响,您可以将参考类别设置为“周末”,以证实您的怀疑,即工作日自行车旅行超过 20 分钟的几率明显高于周末超过 20 分钟的几率。或者,您可以将您的参考类别设置为一周中的某一天,以评估相对于您选择作为参考类别的那一天,其他日子对赔率的影响。
其他一些挑选参考类别的策略可以在这里找到。
手动选择正确的参考类别
因此,我们认为,有能力选择作为参考的类别是非常重要的。那么,我们如何绕过讨厌的默认 drop_first 参数,选择我们自己的参数呢?
幸运的是,你可以使用一些工具来选择合适的丢弃方式。以下代码显示了一个快速示例函数,用于确定数据集中具有最高值计数的类别,然后从数据中删除这些类别,并将它们用作引用类别。使用相同的方法,您可以修改函数来选择拥有数据集中最常见属性以外的属性的类别,以用作引用。
作者代码
太好了,现在我们有了最常见类别的列表。现在我们可以把这些从虚拟变量的数据框架中去掉。
作者代码
太好了!现在我们已经用虚拟变量准备好了数据,我们知道哪些是参考类别。我们准备运行逻辑回归!
到赔率比
我已经略微谈到了对比值比的解释,但是让我们再深入一点。在我们将逻辑回归模型拟合到我们的数据之后,查看 statsmodels 的输出是有帮助的。

statsmodel 逻辑回归输出,图片由作者提供。
在这里,您可以看到左侧列出的所有特性,包括虚拟变量(省略了参考类别!)及其相应的统计数据。让我们分别关注第一列和第四列中的系数(coef)和 P 值(P>|z)。
该系数代表的对数优势比。由于这篇文章有一个很棒的解释,我不会在这里赘述,但它值得做一个高层次的总结。
几率是某件事情发生的概率超过它没有发生的概率,记为(p/(1-p ))。如果自行车旅行超过 20 分钟的概率是 25%,那么这个概率是 0.25/(1-. 25)= 0.33。所以在 100 次自行车旅行中,有 33 次会超过 20 分钟。
比值比是两个比值之间的比率或比较,以观察它们在不同情况或条件下如何变化。特征的比值比是条件 1 中自行车旅行超过 20 分钟的比值,与条件 2 中自行车旅行超过 20 分钟的比值。
正的比值比表明该事件更有可能发生,而负的比值比表明该事件不太可能发生。
注意,系数是对数比值比。对数优势比的“对数”部分就是优势比的对数,因为逻辑回归使用对数函数来解决回归问题。仅仅使用比值比要容易得多,所以我们必须取对数比值比的指数 (np.exp())来得到比值比。
对于分类特征或预测因素,比值比比较每个预测因素类别相对于参考类别的事件发生几率,假设所有其他变量保持不变。
好了,理论完成后,让我们来看几个例子,看看这在实践中是如何工作的。
注意。我们的引用类别是每个特性中最常见的,在我们的例子中是:
- [user _ type]=‘订户’(另一个选项是‘客户’,我假设是指付费乘车的非订户)
- 【性别】=‘男性’
- 【日类型】=‘工作日’
- 【30 岁以下】=‘30 岁以上’
- 【工作日】=‘星期三’
如果所有其他变量保持不变,给定优势比 exp(1.66) = 5.28 ,如果您是客户,则乘车超过 20 分钟的几率是订户的 5 倍。(也许他们是在充分利用他们的车,因为他们不是固定的付费用户!)
如果所有其他变量都不变,给定 exp(0.32) = 1.37 的比值比,如果你是女性,那么骑行超过 20 分钟的几率比男性高 37%。
如果所有其他变量都保持不变,给定优势比 exp(-0.07) = 0.92 ,如果你的年龄在 30 岁以下,那么骑行超过 20 分钟的几率比 30 岁以上的人低 8%。
在工作日或周末,如果所有其他变量保持不变,超过 20 分钟的乘车几率几乎不变,给定的几率比为 exp(0.002) = 1.003 。
所以,我们有它!我希望这有助于解释更多关于在逻辑回归中使用分类特征的问题,并且 1)你应该关心你使用的参考类别,2)你有选择的权力,3)对于分类变量来说,优势比并不是很难把握。
你可以在我的 GitHub 库这里看到我的全部代码。感谢阅读:)
如何面试正在面试你数据工作的公司
利用面试最后 5 分钟的指导方针

1。背景——面试不是单向的选择
开始一份新工作既令人兴奋又让人害怕。在我之前的博客里,我讲过一个 4 步法在面试中谈你的项目 。对于许多寻找新角色的人来说,开始新角色就像买了一个“神秘盒子”——在你打开盒子之前,你不知道里面是什么。尤其是对于像数据科学家、数据工程和数据分析师这样的数据工作来说,“典型的工作日”可能会有很大的不同——对于同一行业甚至同一公司的角色来说。即使你有相同的头衔,你使用的工具,需要的技能,以及项目使用的数据种类也因团队而异。因此,了解你需要什么和你的工作是至关重要的。
我怀疑没有人会喜欢惊讶地发现新工作与他们想象的相去甚远,尤其是以一种不受欢迎的方式。许多人努力准备在面试中展示自己最好的一面,以给公司留下深刻印象,但许多经验不足的候选人通常会忽略一点:评估和面试公司,而不仅仅是让公司评估你。
2.什么时候?
现在我们知道我们想在面试中更多地了解这个职位,下一个问题是我们什么时候可以对公司进行面试?通常,在面试中,最后 5-10 分钟是被面试者向面试官提问的时间。很高兴能得到我们需要的关于新工作的答案。如果你认为这个时间不够或者没有机会完成这一步,我建议你提出来,要求一些时间来完成你的采访部分。
3.谁啊。
大多数人可能认为未来的经理是提问的最佳人选,但我不建议你在考虑面试人员时有这样的限制。每个人都有自己的角色和观点,但每个人都可能因为自己的立场而有所偏颇。因此,你应该学会根据受访者的角色问什么问题。在讨论什么是好问题之前,我们先来了解一下面试官的角色是如何决定你的问题内容的:

作者图片
人力资源(部)
人力资源筛选通常是大多数数据工作的第一次面试。对话通常是关于一些一般性的问题,比如你目前的工作状况、签证状况、换工作的动机、面试过程等等。我建议你问更多关于面试过程的细节问题,而不是公司文化。我不是说你不应该“面试”人力资源,我的意思是问人力资源关于公司文化不如弄清楚你会有什么样的面试以及如何准备面试,因为在对话中与人力资源的时间有限。
未来经理
没有好经理的支持,很难有成功的职业生涯。然而,在一些面试中(新毕业生或普通员工),你可能没有机会和你未来的经理交谈——事实是,在这次面试中,你可能不知道谁会是你的经理。
对于直接招聘过程,经理可能是决定你的报价的最重要的人。他/她是最能帮助你在新角色中成长的人。所以,在面试中,他/她是一个很好的资源来了解团队的大范围,以及对你工作的期望。你需要确保你能接受他的管理风格,以便将来共事。
未来的同事
同一个团队的同事可能是你在工作中互动最多的人。他们通常已经在团队中呆了一段时间,熟悉团队的运作方式,以及你的新角色的日常生活。你想从他们那里了解的是球队的氛围和文化。
未来的商业伙伴
他们通常会在“小组面试”阶段与你交谈。他们的角色可能是您的 LOB 合作伙伴(业务线)、内部客户、产品经理、项目经理等。他们的工作会受到你的影响,但他们不一定和你在同一个团队,也不一定了解 data/ML。因为他们依靠你的工作来完成他们的工作,他们会对你的表现有所期待。
其他面试官
在你的新工作中,你很少或永远不会再与面试官共事,这种情况并不少见。这些人可以是你团队之外的其他员工、另一个姐妹团队的经理或部门主管。虽然你们两个都知道你们以后不会有太多的互动,但我仍然认为它们是了解这个部门或公司本身的很好的资源。
总之,我鼓励你向每一个面试你的人提出有价值的问题,无论是你未来的老板、同事、商业伙伴,还是另一个团队中永远不会在新工作中与你共事的人。
4.怎么会?
接下来要讨论的重要事情是什么问题好问。虽然每个人在工作中可能会有不同的衡量标准,但我建议从以下几个方面来评估这份工作:

作者图片
4.1 技术要求
如上所述,根据角色的不同,实际工作可能会有很大的不同。如果面试官在面试中没有提到这些问题,你可能会问这些问题:
- 这个角色最大的挑战是什么?
问谁?
询问未来的经理和同事,因为他们可能会提供不同的观点。你也可以问问未来的商业伙伴。
问这个问题我们想学什么?对于经理来说,这个答案表明了他/她对你工作的期望——他/她需要员工好好处理的领域。对于未来的同事,他们的回答代表了这份工作的潜在痛点,从中你可以预测什么可能会让你生气。例如,如果他们的答案是“为 ML 模型获取干净的数据”。那么你知道伟大的数据清理技能对于这份工作是必要的。
如果这份工作需要你和商业伙伴密切合作,你可以问他们这个问题。与经理类似,他们会对经常合作的人设定期望。
- 常用的工具有哪些?更具体地说,是什么编程语言(例如 Python R,SAS)。他们使用什么云服务(例如 Google cloud 或 AWS)?什么样的数据库/数据湖(如雪花、Qubole)?
问谁?
未来的同事。如果你不能从未来的同事那里得到答案,你也可以问未来的经理。
我们通过问这些问题想了解什么?职位描述通常会列出理想候选人的技能。但有时描述要么太笼统,要么列出 100 项技能。确认所需的技能永远不会有坏处,而且知道你目前的技能组合是否能满足这些技能也很关键。此外,问这个问题可以帮助你找出缺少什么,这样你就可以在新工作的第一天开始改进。
4.2 工作程序
你想确定你会喜欢新工作的工作节奏,这样你就会对日常生活有所了解。以下是一些可以问的好问题:
- 这部作品中有多少与人的互动?
问谁?
未来的经理、同事和商业伙伴。
我们问这个问题是想了解什么?
数据工作需要与他人频繁互动。有些角色可能需要与客户、商业伙伴和同事等不同的人进行多次会面,因此您只有有限的时间来专注于开发 ML 模型或数据产品。在某些角色中,您可能会与来自不同背景的技术人员合作(例如,数据科学家与数据工程师一起工作),其他角色需要与非技术人员一起工作,以提供业务见解或数据产品。也有可能你独自工作,只向你的经理汇报。问这个问题可以帮助你了解你每天/每周的例行工作,看看你是否喜欢这种工作方式。当面试官是你未来的同事时,你也可以问一个相关的问题,比如“典型的一天是什么样的?”
- 那里的工作生活平衡如何?
问谁?
未来的同事和其他不在你团队中的员工。
我们问这个问题是想了解什么?
不管你是喜欢保持忙碌,还是想要一些时间享受生活,你都应该经常问这个问题。这是一个比问“下班后我们多久需要工作一次”更好的问题。
4.3 行政信息
许多人忽略了它,但它很重要。世界每天都在变化。即使你是团队中最好的员工,也不要期望永远呆在原地。公司重组、领导层变动、政策调整……这些都会对员工个人产生巨大影响。保持警惕,做好准备,甚至在踏进公司之前。
- 团队结构是什么样的?
问谁?
未来的经理和同事。
我们问这个问题是想了解什么?
这个团队是新成立的吗,你会是那里的第一个数据科学家吗?这个团队的扩大是因为更多的资金随着许多激动人心的新项目而来吗?还是团队在招人,因为最近有几个人走了?是的,团队的结构很重要,你可以想象在一个新的团队和一个成熟的团队中工作是非常不同的。
你可能还想了解这个团队中的其他人。例如,对于一个中级数据科学家角色,我建议你询问团队中是否有其他 d。有为数据模型做管道工作的数据工程师吗?是每个人都有技术背景的数据科学团队,还是你将是团队中唯一支持所有其他非技术人员的 DS?
为什么会有这些问题?我认为它们与你的职业目标高度相关。当我还是一名初级员工时,我想在一个有高级 DS 的团队中工作,我可以向他们学习。我想在一个成熟的团队中工作,那里的人有经验,知道做事的最佳方式。每个人都有不同的职业目标,所以要确保新工作能适合你的需求。
- 团队坐在公司的什么位置?
问谁?
未来的经理,可能是同事和商业伙伴。
问这个问题我们想学什么?
我们问这个问题是想看看这个团队是一个**“成本中心”还是一个**“利润中心”。成本中心,也称为收入中心,是公司内部的一个小组或部门,其职能有助于业务运营,但不直接产生收入。利润中心是公司中直接产生收入和利润的部门。
与数据相关的角色可以位于成本中心或收入中心。一些公司依靠 ML 或其他数据产品以各种方式产生利润,因此创造这些产品的团队是这些公司的核心。此外,一些公司建立他们的人工智能或人工智能部门来支持他们的核心业务。换句话说,这些公司用传统的方式经营他们的业务,ML 是好东西,但不是必需的。我并不是不鼓励你在成本中心工作,但我认为如果你想减少因一些不可预测的情况而被解雇的可能性,在成本中心工作的风险要比在利润中心高。
4.4 自我发展
- 公司提供了哪些增长机会?
问谁?
未来的经理和同事。
我们问这个问题是想了解什么?我认为在评估这份工作时,了解未来的发展机会是很重要的。工作不仅仅是用工作来换取金钱;这也是为了积累经验和成长。尤其是因为数据工作需要终生学习,30 年后我们不太可能在工作中使用同样的工具和技术。我建议你问问团队或公司是否提供在线学习平台,如 LinkedIn learning 或 DataCamp,以及他们是否鼓励员工参加研讨会和会议。如果你打算获得另一个学位,你也可以问问他们是否有学费资助。
5.请尽量避免问这些问题
- 关于金钱和利益的问题。
无论你多么急切地想知道薪水,不要在面试中讨论,尤其是和未来的经理。你可以在人力资源筛选时讨论这个问题,也可以在得到工作机会后再和经理讨论。
- 我在面试中搞砸了吗?
我明白当你认为自己没有展现出最好的一面时,你可能会感觉很糟糕,但尽量不要在面试的最后 5 分钟问这个问题。面试官有他们的判断,你可能认为你搞砸了,但也许你比其他候选人做得更好。或者面试官问你一些具有挑战性的问题来测试你如何应对高压。不要表现出你对得到这份工作没有信心,永远不要!
总结——也是关于你的!
对大多数人来说,找到你的下一份理想工作从来都不是小菜一碟。请记住,工作是一个双向选择,不仅仅是公司找到它需要的东西,还包括找到一个你乐意工作、学习、成长和成为更好的自己的地方!
感谢您的阅读,我希望这篇博客对您的数据求职有所帮助, 这里还有一篇关于数据面试的博客,您可能会对 感兴趣。我希望你能得到一个好的报价。祝你好运!
💖喜欢这个故事吗?请随时订阅 DS 和 ML 粉丝的邮件列表,并成为媒介会员!🤩
这篇博客最初发表在我的个人网站上。
参考
【1】https://www . indeed . com/career-advice/career-development/profit-center-vs-cost-center
如何凭直觉发现检察官的谬误(并进行更好的假设检验)
面向商业领域的数据科学家和分析师

被告与犯罪现场发现的 DNA 匹配的可能性只有百万分之一。所以被告是有罪的。听起来还好吗?不是的!
仅仅基于这一证据,被告很有可能是无辜的,这是不直观但非常有启发性的检察官谬误所描述的逻辑陷阱。
当我们理解了这一点,我们就开始在广告、媒体和人们的日常决策中处处看到它。它也是正确解释 p 值的一个常见困难的基础,对此获得更好的直觉会使我们如何在商业环境中进行假设检验变得更加清晰。
再举一个例子。您因严重疾病进行的医学测试呈阳性。当你回忆起测试的准确率为 95%时,你感到一阵恐慌。然而,你真正的机会可能比这大得多——也许你真的有 10%的机会。这怎么可能呢?
学习目标
本文的第一个目标是对检察官的谬误作一个总体介绍,并用通俗易懂的语言解释它,针对使其难以直观理解的原因。如果你没有遇到过它或者对它的概念不清楚,那么无论你走哪条路,它都是一个很好的生活工具,我希望你会像我一样发现学习它的乐趣。
文章的第二部分将探讨在使用假设检验时,检察官的谬误如何在 p 值的解释中发挥作用,并针对执业数据专业人员。如果你很难解释为什么 p 值不是你的零假设为假的概率,而是你得到的结果与给定零假设时观察到的结果一样极端的概率,这是值得理解的——继续读下去。
理解检察官的谬误
附件 A
所以被告与犯罪现场的 DNA 匹配的几率是百万分之一。这是一个高度准确的 DNA 测试,已经有一个阳性匹配。然而,无论这一证据看起来多么令人信服,仅凭这一点并不能证明被告有罪。不是因为这个概率中还有少量的不确定性(从来没有绝对的确定性),而是因为给出无罪证据的概率和给出无罪证据的概率不一样。
为了理解这意味着什么,让我们首先假设我们正在一个 1000 万人口的城市中寻找罪犯(加上一个罪犯)。而且有 100%的把握,真正的罪犯的 DNA 会与犯罪现场的 DNA 相匹配。
把这些数字放在一个表格里,我们得到这个:

作者图片
现在,我们被告知,只有百万分之一的机会,一个无辜的人会得到 DNA 匹配。因此,如果我们要测试这个城市所有的 1000 万人,我们希望其中有 10 人匹配。
将此添加到表格中:

作者图片
现在看看所有无辜的人,他们的 DNA 都符合这个场景。事实上,无罪匹配的数量比正确有罪匹配的数量多十倍!这是 10 次假阳性对 1 次真阳性。
用百分比表示,那么整个城市给出证据的有罪概率是 1 / (1 + 10) = 9.1%。仅根据这一 DNA 证据,现在看起来被告有 1–9.1% = 90.9%的无罪几率,这与检察官最初声称的 0.0001%的无罪几率形成了鲜明对比。

作者图片
最初声明的含义是,由于只有百万分之一的无辜者会与 DNA 匹配,而被告与 DNA 匹配,他们有罪的概率是 1–0.000001,这几乎是必然的。但是这种逻辑是有缺陷的,尤其是当概率适用的人群很大的时候;我们从数据中得出的结论可能会像这个例子一样发生戏剧性的转变。DNA 匹配无罪的概率不能与 DNA 匹配无罪的概率相混淆。
那是不是说我们在刑事审判中对 DNA 证据无能为力?我们可以,但这里的关键是要明白,需要有其他理由相信被告有罪。如果我们仅仅依靠 DNA 匹配,我们就会暴露在虚假的匹配面前,但是如果我们已经对某人有了其他的怀疑,那么这个额外的证据将是非常令人信服的。我们还可以使用 DNA 来缩小嫌疑人的范围,以帮助集中调查(根据对金州杀手的追捕),但这不是决定性的,这与我们将在第二部分探讨的假设检验中使用 p 值有重要的相似之处。
这里值得一提的是,检察官谬论的一个延伸是辩护人谬论,其中错误地认为,一项指控被告有罪的证据应该被放弃,因为它可以与许多其他证据相匹配。这被用于 OJ Simpson 的审判中,辩护律师认为,与 OJ 匹配的现场血液样本(400 分之一的匹配率)也可以与洛杉矶数以千计的其他人匹配,因此不是有用的证据。这是对检察官谬论的曲解,证据是有用的,因为它是与其他证据一起考虑的,尽管它本身并不具有决定性。
附件 B
这是你一直害怕的消息。您很健康,但已接受了一种罕见疾病的筛查,您接受的“95%准确率”测试呈阳性。你感到麻木。但是你应该吗?
在这里,我们首先遇到“准确性”意味着什么的问题,在医学测试中,术语和 特异性 用于定义准确性的两个不同方面:
- 敏感度:患病者被正确识别为患病的可能性(真实阳性率)
- 特异性:未患病者被正确识别为未患病的可能性(真实阴性率)
对于本例,我们将假设 95%的准确度适用于灵敏度和特异性*。我们假设这种疾病会影响 1/1000 的人口。*
因此,在 1000 万人口中,我们预计会有 10,000 人患有这种疾病。把这些数字放在一个表格里,我们就有了这幅图:

作者图片
另一种可能更直观的表达方式是使用决策树:

作者图片
有了这些数字,假设你刚刚进行了阳性测试(并且没有其他理由相信你患有这种疾病),你患有这种疾病的几率为 9500/(9500+499500)= 1.87%。
即使这种疾病在人群中流行了 10 倍,在得到阳性检测后,你患这种疾病的可能性也只有 16.1%。最重要的是,将测试的特异性提高到 99%,你的几率仍然是 49%。(在澳大利亚,COVID 家用快速抗原检测试剂盒必须经过认证,灵敏度为> 80%,特异性为> 98%)。
最初的 95%的“准确性”测量没有给你足够的关于患该疾病的实际概率的信息,因为你错过了关于该疾病在人群中的流行率的信息,因此错过了你患该疾病的先前可能性。
如果您患有某种疾病,那么您获得阳性检测结果的概率(95%)与您在检测结果中患有该疾病的概率是不同的,为了对您患该疾病的可能性做出任何判断,您首先需要知道您患该疾病的可能性有多大,而不管检测结果如何(ABC 使用真实世界 COVID 情景的精彩评论此处)。
先验概率和随着新信息(如 COVID 测试结果)的出现而更新概率的想法在贝叶斯框架中被正式化,著名的贝叶斯公式为我们刚刚通过列联表说明的内容提供了一条捷径。这是改天的话题。
检察官的谬误是如何进入假设检验的
从这一点来说,我假设你有一些假设检验的背景知识,并有一些概念的工作知识,如检验统计,零假设和 p 值。这个可能是下一个去的好地方,如果你不感兴趣的话。
本节的重点将是对 p 值有一个更好的直觉,特别是 p 值是而不是零假设为真的概率;p 值 0.05 是而不是零假设为真的概率为 5%,或者替代假设为真的概率为 95%。更确切地说,这是得到观察到的结果的概率(或者更极端的情况),假设零假设*,这种差异很难凭直觉理解,更不用说在现实世界中组织测试时帮助他人理解了。*
有关系吗?
首先,这种措辞上的差异真的有关系吗?实际上,这不是一回事吗?事实并非如此,原因来自于同样的区分,这些区分使得检察官的谬论成为一个陷阱,并带来严重的实际后果。
不理解这种差异的危险在于,我们可能会从我们的测试结果中得出毫无根据的结论,就像检察官对被告的无辜提出错误的主张一样。
具体来说,当我们认为可以:
- 在多个区段重复测试,直到我们的 p 值低于 0.05
- 将我们最初的测试结果分成几个子集,并指出任何 p 值低于 0.05 的结果都是有意义的
附件 C
想象一下,你是一家超市,在你的网站上测试可口可乐的广告,并把你的在线客户分成两部分,在 A/B 测试中,一半看到广告,另一半看不到。您仔细计算了所需的样本量,并让数据累积起来,但在测试结束时,您失望地发现两组之间的可乐销售没有显著差异。
但是,你想,如果它引起了某些客户群体的共鸣呢?所以你去探索不同的细目分类,并开始注意到各处 p < 0.05 的结果:住在纽卡斯尔的顾客,倾向于价值产品的退休者,购买大量奶酪的人…
营销人员变得兴奋起来。也许我们在这里有所发现。是的,纽卡斯尔的人们会对可口可乐的广告反应良好,这是有道理的,因为我们目前正在那里的市中心做一个大型广告牌广告,它已经在顾客的脑海中浮现了。让我们加倍努力,继续在网上锁定这个群体。
这是一种错误的推理,类似于检察官从人群中随机挑选人,直到出现阳性 DNA 匹配,并声称有罪,尽管实际可能性为 9.1%。事实上,似乎有证据支持这个(广告牌)是确认偏差;如果我们去寻找正当理由,我们经常会找到,但仅仅因为事后看来它们是合理的,并不意味着它们是相关的。注意不要后理性化。
为了解开这个问题,我们将再次使用列联表。再次从我们的第一个例子的数字,阴影部分基本上是什么 p 值代表。

作者图片
但是我们真正感兴趣的是:

作者图片
那么为什么我们不能只测量这个呢?原因很简单,当我们进行假设检验时,我们没有办法测量底部“有罪”框的数量。我们所能做的最好的事情就是通过收集样本数据来填写最上面一行,然后做出一个推论。
如果我们确实观察到了与 p 值为 0.05 的广告的“显著”差异,那么将此转换为我们的可口可乐广告 A/B 测试示例,我们可能会得到如下结果:

作者图片
这与双重否定相混淆,但最上面一行是说,如果可口可乐的广告真的对销售没有影响,我们只能获得 100 次中的 5 次(或者更极端)销售结果。考虑到无效假设,这是一个非常令人惊讶的结果。
但关键的是,这并没有说可口可乐的广告是否真的对销售有影响(在替代假设下的真实效果)。为了获得一个位置,我们需要在左下角的框中输入一个数字,这不是我们可以通过 A/B 测试或任何其他方式收集的数据。
为了帮助我们理解为什么 0.05 便士的价值与可口可乐广告的效果没有直接关系,让我们试着输入一些假设的数字。
这里能放什么?先说‘1’吧。这是一个任意的数字,只对上面的方框中的“5”有意义,但我们遵循的逻辑与我们在前面的例子中用来说明检察官谬误的逻辑相同。

作者图片
所以现在,尽管 p 值为 0.05,我们得到可口可乐广告产生差异的概率仅为 1 / (1+5) = 17%。
现在让我们试着输入一个更大的数字;比如说 45 英尺。这给了我们一个概率,广告产生了 45 / (45+5) = 90%的差异。同样的 p 值,我们可以从数据中得出两个截然相反的结论。

作者图片
但是,抛出这些没有基于真实、可测量数据的假设数字有什么意义呢?这是这次讨论的关键,也是在现实世界中更好地实践假设检验的关键。你在这里输入的数字代表你之前对假设的信心。
数字越高,你的信心越高。我们通过在这里插入不同的数字来证明,p 值 0.05 和我们假设为真的概率没有关系。如果测试一开始就是一次登月,即使有有利的 p 值,你仍然有理由持怀疑态度。先前的定罪在假设检验中很重要。
如前所述,贝叶斯思维模型提供了一种数学处理这种先验信念的方法,但是 p 值和置信区间的频率主义模型是当今商业世界中 A/B 测试的事实标准,这种推理中的陷阱经常被忽视。p 值不能取代人类推理的需要,我们必须从假设中的一些先验信念开始,测试结果和 p 值才是有用的。如果这变得不直观,回想一下检察官的例子。
把所有的放在一起
- p 值并不能说明假设是否成立。不要纯粹根据测试是否通过了某个 p 值阈值来下结论。
- p 值是观察到结果的概率或更极端的情况,假设为零假设。这不同于给定证据的零假设的概率。检察官的谬论说明了为什么这种区分很重要。
- A/B 测试的 p 值有助于验证我们的假设,如果我们首先有充分的理由相信它的话。
- 不要去寻找有吸引力的 p 值,并根据它们进行逆向推理。如果您发现某个细分市场的 p 值出乎意料地低,最好的办法是使用特定于该细分市场的新测试来验证它。
在商业决策中使用 p 值
当在商业世界中用 p 值进行假设检验时,要清楚它们的正确用法,并准备好解释它,但不要觉得你需要强烈反对 p 值的每一次滥用才能成为一个好的顾问。
我们在需要快速做出决策且数据不完善的环境中工作,因此,如果决策者需要根据不可靠的数据不时凭直觉做出决策,请不要犹豫;毕竟,自信是等式的一部分。
因此,即使在你知道正确的做法是重新运行测试的情况下,如果这样做的成本超过了继续决策的成本,那么它可能没有很好的实际意义。明确你的立场,但没有必要在每个决定上都力求严谨。
进一步阅读
统计艺术将 p 值描述为“弱证据”(即决策中的一个因素,但远非唯一因素),并就我们如何在其他证据之上构建强有力的案例提供了一些很好的评论。
例如,在法庭上,不同的证据可以被逐项列出,每个证据被赋予不同的可能性比率(如果被告有罪,证据的概率/如果被告无罪,证据的概率),有可能将它们相乘,以量化案件的实力,尽管英国法院没有这样做,因为这是陪审团的作用。
关于回答问题和声称发现和从经验中学习贝叶斯方法的章节充满了像这样的伟大的现实世界的例子和权衡证据的不同思想流派。
我还从系列讲座中获得了一些灵感,称之为扯淡,特别是关于“ P 值和检察官的谬误”的讲座。
如何在笔记本上与汉密尔顿迭代
原文:https://towardsdatascience.com/how-to-iterate-with-hamilton-in-a-notebook-8ec0f85851ed
对于那些不知道的人来说, Hamilton 是一个通用的微框架,用于指定数据流,例如指定 Pandas 转换。它帮助你构建你的代码库,并改进你的代码,例如,你总是用 Hamilton 编写单元可测试转换代码。它通过引入一种范式来做到这一点,在这种范式中,函数必须以自以为是的、声明性的方式来编写。参见这篇 TDS 帖子获取更广泛的介绍。
使用 Hamilton 的一个开发含义是,它迫使您从一开始就将 python 函数组织成模块。如果在笔记本中迭代是您的开发方式,那么在笔记本环境中使用 Hamilton 似乎很困难。在本帖中,我将解释如何在笔记本上舒适地迭代汉密尔顿 DAG。
步骤 1 —安装 Jupyter & Hamilton
我假设您已经设置了这个步骤。但是以防万一你没有:
pip install notebook
pip install sf-hamilton
然后,要启动笔记本服务器,应该是:
jupyter notebook
步骤 2—设置文件
- 启动你的 Jupyter 笔记本。
- 转到您希望笔记本和 Hamilton 功能模块所在的目录。
- 创建一个或多个 python 文件。通过“新建>文本文件”来完成。它将打开一个“文件”编辑器视图。给文件命名并给它一个
.py扩展名。保存之后,您会看到 jupyter 现在提供了 python 语法高亮显示。保持此选项卡打开,以便您可以翻回到它来编辑此文件。 - 启动将在另一个浏览器选项卡中使用的笔记本。
步骤 3——迭代的基本过程
概括地说,您将在选项卡之间来回切换。您将向汉密尔顿函数 python 模块中添加函数,然后将该模块导入/重新导入到笔记本中以获得更改。然后,您将像往常一样使用 Hamilton 来运行和执行事物,并使用笔记本来执行您使用笔记本执行的所有标准事物。
让我们看一个例子。
这是我添加到我们的哈密尔顿函数模块的一个函数。我将模块命名为some_functions.py(显然选择一个更适合您情况的名称)。
import pandas as pddef avg_3wk_spend(spend: pd.Series) -> pd.Series:
"""Rolling 3 week average spend."""
print("foo") # will use this to prove it reloaded!
return spend.rolling(3).mean()
下面是我在笔记本上设置的内容,以便能够使用 Hamilton 并导入该模块:
单元格 1:这只是导入了我们需要的基本东西。
import importlibimport pandas as pdfrom hamilton import driver
单元格 2:导入您的汉密尔顿功能模块
# import your hamilton function module(s) here
import some_functions
单元格 3:每当你对some_functions.py做出更改并保存时,运行这个单元格
# use this to reload the module after making changes to it.
importlib.reload(some_functions)
这样做的目的是重新加载模块,从而确保代码是最新的,以供您使用。
单元格 4:使用汉密尔顿
config = {}
dr = driver.Driver(config, some_functions)
input_data = {'spend': pd.Series([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])}
df = dr.execute(['avg_3wk_spend'], inputs=input_data)
运行该单元后,您应该会看到作为输出打印的foo。
好的,现在让我们说我们正在迭代我们的哈密尔顿函数。在另一个浏览器选项卡中,转到您的 Hamilton 功能模块(本例中为some_functions.py),将print("foo")更改为其他内容,例如print("foo-bar").保存文件——它看起来应该是这样的:
def avg_3wk_spend(spend: pd.Series) -> pd.Series:
"""Rolling 3 week average spend."""
print("foo-bar")
return spend.rolling(3).mean()
回到笔记本,重新运行单元 3 和单元 4。您现在应该会看到一个不同的输出,例如foo-bar。
恭喜你!你刚刚用 Jupyter 笔记本成功迭代了 Hamilton!
总结一下,在我看来事情是这样结束的:
- 下面是我的
some_functions.py文件的样子:

作者图片
- 我的笔记本看起来是这样的:

作者图片
帮助:我正在使用谷歌 Colab,我不能做到以上几点
自从1.8.0发布以来,你现在可以用你的驱动程序内联定义函数来构建 DAG。我们强烈建议只有在绝对必要的时候才使用这种方法——用这种方法构建代码非常容易。
例如,假设我们想要添加一个函数来计算avg_3wk_spend的对数,而不是将其添加到some_functions.py,我们可以直接在笔记本中执行以下步骤:
# Step 1 - define function
import numpy as npdef log_avg_3wk_spend(avg_3wk_spend: pd.Series) -> pd.Series:
“””Simple function taking the logarithm of spend over signups.”””
return np.log(avg_3wk_spend)
然后我们必须创建一个“临时 python 模块”来存放它。我们通过导入ad_hoc_utils然后调用create_temporary_module函数,传入我们想要的函数,并为我们正在创建的模块提供一个名称。
# Step 2 - create a temporary module to house all notebook functions
from hamilton import ad_hoc_utils
temp_module = ad_hoc_utils.create_temporary_module(
log_avg_3wk_spend, module_name='function_example')
现在,您可以像对待 python 模块一样对待temp_module,并将其传递给驱动程序,像平常一样使用 Hamilton:
# Step 3 - add the module to the driver and continue as usual
dr = driver.Driver(config, some_functions, temp_module)
df = dr.execute(['avg_3wk_spend', 'log_avg_3wk_spend'], inputs=input_data)
这种方法的注意事项:
使用“临时 python 模块”不会通过在 Spark 上使用 Ray、Dask 或 Pandas 来实现计算的缩放。所以我们建议只将这种方法用于开发目的。
提示:你可以直接导入函数
将 Hamilton 函数放入一个模块的好处是,在另一个上下文中重用它非常容易。例如另一个笔记本,或者直接。
例如,很容易直接使用笔记本中的功能,就像这样:
some_functions.avg_3wk_spend(pd.Series([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
它调用我们在some_functions.py模块中定义的avg_3wk_spend函数。
提示:您可以使用 ipython magic 来自动加载代码
并排打开 Python 模块和 Jupyter 笔记本,然后将% auto reload ipython magic添加到笔记本以自动重新加载单元格:
from hamilton.driver import Driver
# load extension
%load_ext autoreload
# configure autoreload to only affect specified files
%autoreload 1
# import & specify my_module to be reloaded
# i.e. this is the data transformation module that I have open in other tab
%aimport my_module
hamilton_driver = Driver({}, my_module)
hamilton_driver.execute(['desired_output1', 'desired_output2'])
然后,您将遵循以下流程:
- 在 open python 模块中编写数据转换
- 在笔记本中,实例化一个 Hamilton 驱动程序,并用一小部分数据测试 DAG。
- 由于%autoreload,每次执行 Hamilton DAG 时,都会使用最新的更改重新导入模块。这种方法防止了无序的笔记本执行,并且函数总是驻留在干净的地方。py 文件。
鸣谢: Thierry Jean 的博客文章提供了这最后一个技巧。
最后
感谢你阅读这篇文章。我们很乐意帮助您成功使用汉密尔顿。欢迎在我们的 github 知识库中留下问题/评论(我们也很喜欢⭐️!),或者加入我们的 slack 服务器寻求帮助,或者提供建议/改进。
如何用 GitHub Pages 和 Jekyll 启动你的个人网站
一个完整的一步一步的指南,自动化繁重的工作,让您专注于内容

建立自己的网站是脱颖而出的好方法,也是在网上建立个人品牌的好方法。在这篇文章中,我将分享一个逐步建立和启动一个看起来干净、专业且易于维护的网站的指南。您将学习如何:
- 使用静态站点生成器 Jekyll 在本地构建您的站点,
- 在网站托管服务 GitHub Pages 上托管您的网站,
- 将您的站点连接到您选择的自定义域,并
- 添加动态内容,例如来自您的 Twitter 订阅源的内容。
最重要的是,有了这个设置,你可以在简单的 Markdown 中完成所有的内容创建,而 Jekyll 则负责将你的文字转换成 html。(关于演示,请查看我自己的网站这里。)
让我们开始吧。
1.安装 Jekyll
Jekyll 是一个将 markdown 文件转换成 html 的 Ruby 应用程序。为了使用 Jekyll,你首先需要安装 Ruby。在苹果电脑上,你可以用自制软件做到这一点:
brew install chruby ruby-install xz
ruby-install ruby
从技术上来说,你刚才做的是先安装chruby,它只是一个简单的小 shell 脚本,然后用chruby安装最新版本的ruby。现在运行以下命令来配置您的环境(最好将这些行添加到您的。巴沙尔或者。zshrc):
source /opt/homebrew/opt/chruby/share/chruby/chruby.sh
source /opt/homebrew/opt/chruby/share/chruby/auto.sh
chruby ruby-3.1.2
现在你可以在你的 shell 中使用 Ruby 的包管理器gem。执行以下命令:
gem install Jekyll
去安装哲基尔。就是这样!
👉不是 Mac 用户?Jekyll 也可以安装在 Windows、Ubuntu 或其他 Linux 系统上。查看此处的说明。
2 .建立一个新的 git repo 并在本地构建您的站点
首先,你需要在 GitHub 上创建一个账户,如果你还没有的话。然后,您创建一个新的 repo,它可以命名为“site”,并将其克隆到您的本地计算机上:
git clone git@github.com:<your username>/site.git
在site目录中,你现在可以运行:
jekyll new --skip-bundle . --force
这初始化了一个新的 Jekyll 项目,并创建了一堆文件,您将使用这些文件来创建您的网站,最重要的是:
Gemfile包含执行 Jekyll 所需的 gem 依赖关系,- 是 Jekyll 配置,它决定了你的站点的外观
index.md是你网站的首页。这是您添加第一个内容的地方。
接下来,您需要对代码做以下两个小的更改:
- 在
Gemfile里面,注释掉了这一行:
#gem "jekyll", "~> 4.2.2"
改为添加这一行:
gem "github-pages", "~> 227", group: :jekyll_plugins
👉这条线到底是做什么的?这告诉您的 Ruby 编译器,不要直接用 Jekyll 构建站点,而应该用 GitHub Pages Ruby gem 来构建,它拥有在 GitHub Pages 中运行 Jekyll 的所有依赖项。
2.在_congig.yml里面,注释掉这两行:
#baseurl: ""
#url: ""
这是因为 Github 页面会在构建过程中自动设置这些 URL。
最后,跑
bundle install
这将在本地构建 html 网站,使用来自Gemfile的依赖项、_config.yml中的 Jekyll 配置和目录中 Markdown 文件的内容。
3.在本地测试你的站点
运行以下命令:
bundle exec jekyll serve
这将输出一个本地 URL。将此粘贴到您的浏览器中以预览网站。如果您得到错误消息“无法加载这样的文件— webrick”,只需运行bundle add webrick; bundle install。这将 webrick 包(一个 HTTP 服务器工具包)的依赖性添加到了 Gemfile 中。
每次您保存对 markdown 文件的更改时,Jekyll 都会自动更新网站,您只需刷新浏览器即可查看更改。
👉不想记住这个命令?只需运行
echo 'bundle exec jekyll serve' > dryrun.sh。现在你可以简单地运行bash dryrun.sh来测试你的站点
4.部署站点
提交所有本地更改并将它们推送到 github:
git add .
git commit -m 'first commit'
git push origin master
在您的 GitHub repo 页面上,请访问:
Settings → Code and automation → Pages → Build and deployment → Deploy from branch
并选择要部署的分支(如主)。现在,GitHub 将运行自己版本的 Jekyll 来构建和部署您的站点。如果您使用site作为回购的名称,您的网站现在将托管在:
https://www.<your username>.github.io/site
每次您向存储库中推送新内容时,这些内容都会在几分钟内自动部署到生产环境中。
👉想要立即强制重建一个站点吗?单击“已部署”链接,然后单击“重新运行所有作业”。
5.添加自定义域
自定义域名更短,更容易让人记住,这可以为您的网站带来更多流量。以下是添加自定义域的方法:
- 去https://domains.google.com查看你想要的域名是否可用。如果有,就购买。它应该花费你大约一个月一美元左右。
- 在 google 域上,在 DNS 设置下,您需要添加两条记录,一条
A记录和一条CNAME记录。在 A 记录中,列出这 4 个 IP 地址(指向 GitHub 的服务器):
185.199.108.153
185.199.109.153
185.199.110.153
185.199.111.153
- 在《CNAME 记录》中,简单地写着
<your username>.github.io。
现在,在 GitHub 上,进入设置→页面→自定义域,添加你的自定义域,点击“保存”。您的 Google 域名现在已连接到您的 GitHub 页面。
👉设置正确的 DNS 配置可能有点棘手。需要故障排除帮助吗?点击查看特伦特杨的帖子。
6.内容,内容,内容

我自己网站上的 Twitter 小部件演示
一旦你的网站建立并运行,就有无限的可能性来添加更多的内容。以下是一些想法:
- 添加一个 Twitter 小部件,列出您最近的推文。只需将这段代码添加到您的
index.md中:
<a class="twitter-timeline" href="https://twitter.com/elonmusk?ref_src=twsrc%5Etfw">Tweets by elonmusk</a> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
(当然,你会想把 *elonmusk* 换成你自己的 Twitter 句柄。)
- 从 Gumroad 添加您的电子书或课程。在 Gumroad 上,转到您网站上想要嵌入的产品,然后导航到共享→嵌入→模态叠加,简单地将代码复制粘贴到您的
index.md。下面是它在我的网站上的样子。 - 添加一个小部件,显示您的最近的博客文章的提要。
- 使用 Jekyll 帖子把你的网站变成一个个人博客。
最后,一个好的实践是使用分支来开发你的站点:当添加一个新的特性时,在一个单独的分支中完成。然后,在 GitHub 上,可以尝试从新的分支部署站点。如果新特性破坏了您的站点,您可以快速将部署分支回滚到master。
快乐创作!
📫 订阅 把我的下一篇文章直接发到你的收件箱。
💪 成为中等会员 并解锁无限权限。
🐦关注我上 中 、LinkedIn、Twitter。
如何以正确的方式学习复杂的话题
原文:https://towardsdatascience.com/how-to-learn-complex-topics-the-right-way-97ca39c4db3e
在最近的一次 Q & A 中,高级数据科学家安尼·马杜尔卡观察到“有大量内容适合初学者,也有大量内容适合研究人员,但对于中级专家来说,这些内容显得分散而杂乱。”我们牢记这一点。本周,我们将重点介绍一系列最近发表的帖子,这些帖子在解决高级和小众主题方面做得特别好,同时保持可访问性。它们非常适合那些有一定经验的从业者——他们希望拓宽自己的技能和知识。
我们开始吧!(如果你想听更多阿尼对 ML 职业挑战和其他话题的见解,请查看他的完整采访。)
- 优化问题,以及如何解决 。Hennie de Harder 的最新文章是一篇清晰而全面的优化指南,对于在工业界和学术界工作的数据科学家来说,这是一个至关重要的领域。Hennie 包括简单的例子(以及解决方案和代码片段),使有时棘手的主题变得易于管理。
- **更多优化问题!(非线性的那种。)**这是另一个完整的初级读本,包括一个完整的 Python 实现,涵盖了基于梯度的线搜索优化算法。
- 处理数据库,蟒道 **。**当您想到“数据库”时,首先想到的语言通常是 SQL。不满足于现状, Marlene Mhangami 想要找到一种更 Python 友好的方式来与多个数据库引擎进行交互,于是登陆了开源的 Ibis 项目。玛琳的全面介绍将帮助其他蟒蛇迈出它们与朱鹭的第一步(以及第二步和第三步)。

- 充分利用图和网络 **。**如果你很想了解应用于图形的中心性度量和划分技术, Angel Das 的新解释器是一个很好的起点——它涵盖了深入社交网络分析和谱聚类之前的一些必要基础知识。
- SHAP 价值观一站式指南 。阅读时间约为 80 分钟, Reza Bagheri 的《SHAP 价值观介绍》与其说是一篇博客文章,不如说是一个你在学习过程中可以多次查阅的资源。它深入 SHAP 图书馆的引擎盖下,展示了它是如何工作的,以及它如何应用于机器学习项目。
无论是现在,明天,还是下一次你有一个安静的时刻,我们希望你选择探索我们最近发表的其他几篇优秀文章。我们认为你不会后悔的。
- Raveena Jayadev 以一种的新眼光看待经典的 MNIST 数据集,从空间的角度接近它。
- 追踪心情 1000 天能学到什么?胡安·德·迪奥斯·桑托斯正是这么做的,并带回了一些非常有趣的见解。
- 在 TDS 播客上, Jeremie Harris 欢迎 Beena Ammanath 讨论公司可以做些什么来建立可靠和值得信赖的人工智能系统。
- 约翰娜·阿佩尔带领我们对人工胚胎发生进行了一次引人入胜的尝试:试图从遗传密码中创造出复杂的神经结构。
- 最后,对于求职者来说, Emma Ding 凭借其深厚的行业经验指导读者选择正确的数据科学职位。
如果你喜欢 TDS,欣赏我们作者的作品,可以考虑成为的媒体会员——它不仅支持作者,还为你的阅读乐趣打开我们的全部文章档案。
直到下一个变量,
TDS 编辑
如果想完成目标,如何学习数据科学
我向你展示如何从头开始规划你的旅程,这样你就有希望释放你的潜力

目录
我喜欢定期更新自己的建议,告诉自己如何从零开始学习数据科学。数据领域变化很快,随着我自身知识的增长,我认为重新评估我推荐的方法很重要。
自从我之前努力传授这种智慧以来,我对学习数据科学的建议已经发生了变化。在这篇文章中,我给你我最新的方法,告诉你我将如何学习这个领域,并从中获得乐趣。作为免责声明,我不认为学习数据科学有一种“正确”的方法。不同的事情适合不同的人,你自己的尝试对你在任何职业中的成功都是不可或缺的。请务必阅读到最后,因为我回答了我在这个话题上最常被问到的问题:学习数据科学需要多长时间?
如果您喜欢视频格式,请点击此处观看:
学数据科学有可能吗?
首先,我想揭穿你可以“学习数据科学”的想法这意味着数据科学是一门静态学科,可以完整地学习。无论好坏,数据科学都在不断发展壮大。我不知道任何一个人,包括我自己,有可能了解整个领域。学习数据科学是一个旅程,而不是目的地,带着这种心态来学习可以让这个过程变得更加愉快。我看到很多学生被这个领域的巨大所淹没。如果你的目标是学习整个领域,这将是完全压倒性的。另一方面,如果你专注于一次只学一点点,并在头脑中有具体的小目标的情况下增长你的知识,这就变得容易管理了。
从哪里开始学习
话虽如此,让我们直接进入我想改变我以前的方法。回想起来,我对最开始的建议是非常模糊的。我通常会说类似“学习足够的 Python 和统计学来开始项目。”虽然这是个不错的建议,但这一次我想深入了解你应该如何开始这个学习过程。

作者图片
真正的第一步是了解该领域的组成部分,并为自己制定一个学习计划来导航旅程。如果我们没有任何明确的方向就跳进海里开始游泳,我们真的很容易累坏,可能会放弃。另一方面,如果我们有一张地图和一个明确的目标,我们至少知道我们正在进入什么。在做任何其他事情之前,您需要为您的数据科学学习创建此地图。真正酷的部分是,通过创建这个地图,你还会学到很多关于数据科学领域的知识。

作者图片
如何创建学习地图
那么,我该如何创建地图呢?有两种方法可以做到这一点,这两种方法在高空作业的水平上有所不同。最简单的方法是参加一个为你准备的在线课程或证书。这就是在线课程的巨大好处:它们可以为你规划出完整的学习路径,所以你只需要跟着走就行了。另一方面,它们要花钱。如果你愿意花时间为自己创建这个路线图,所有的信息都是免费的。明确一点,这里没有对错。不管你是否决定付钱给一个组织,做对你来说值得的事情。如果课程是你的速度,我在下面的附录中有 365 DataScience 的折扣代码;如果没有,我已经包含了一些链接到我最喜欢的免费资源。
下一个方法是查看多个在线课程、大学课程和其他资源,并大致了解它们是如何规划道路的。大多数付费课程让你了解课程的结构。然后,您可以基于您在那里看到的类和概念制定自己的路线图。通过这样做,您还可以感觉到该领域需要什么技能和技术。有趣的是,你可以看到什么是最有趣的,最吸引你的,并据此调整你的路线图。这对以后真的很重要。
我的学习地图会是什么样子?
好了,让我们为自己设定一个学习计划。我鼓励你在这里做你自己的研究,并根据你的兴趣和能力进行调整。
如果我为自己制定一个学习计划,我几乎肯定会从学习 Python 开始。编码语言允许你构建东西。如果你能建造东西,你几乎可以把你正在做的任何东西应用到实际问题中。我认为学习编程就像构建我的工具集一样。我可以赤手空拳搭建一个棚子,但是用锤子和电钻要容易得多。Python 是我的动力工具。我个人几乎总是觉得,与数学相比,编程是阻碍我提高学习速度的原因。需要说明的是,数学非常重要,我个人不会首先关注它。
对于编程,我会确保自己对变量、循环和函数等基础知识有扎实的理解。我也会非常专注于学习如何使用像 pandas 这样的导入库。事实上,我建议尽可能多的浏览熊猫文档。在我看来,为数据科学编码并不是真正的编码。你更多地利用其他人为特定目的而构建的工具。例如,我认为对熊猫的深刻理解会比对纯 Python 的非凡理解更好地服务于大多数数据科学家。我在下面的附录中包含了一些学习 Python 的免费和付费资源。另外,如果你对我学习编码的方法感兴趣,看看我写的这篇关于这个问题的文章。
在您开始项目之前…
以前,我会告诉你在此之后立即开始项目。在这篇文章中,我会为大多数人推荐一个额外的步骤。我收到了大量的反馈,说大多数人在学习了这些基本技能后,不知道从哪里开始做项目。有一个很好的解决方法。看看别人的项目。你可以去 Kaggle 看看其他人做过的项目。你可以看到他们所有的代码和他们留下的关于他们思维过程的评论。对我来说,这绝对是一座金矿。你可以坐在前排观看杰出的数据科学家如何解决问题。我肯定不聪明,但这里有一个我走过泰坦尼克号数据集的视频:
当开始做项目时,它们不一定是原创的。你可以像其他人一样进行完全相同的分析,仍然可以学到一些东西。一个典型的学习会议可能就是你在屏幕的一半上有别人的项目,然后一行一行地输入,在屏幕的另一半上运行。当你这样做的时候,你可以改变参数,尝试不同的视觉效果,看看它是如何工作的。很明显,你不应该把这项工作的功劳据为己有,也不应该把它作为自己的作品发表,但是你绝对可以通过这种方式从中学习。许多人认为他们用这种方法学不到任何东西,但我个人就是这么做的,这是最近让我走得最远的一件事。
当你浏览这些不同的练习册时。您将不可避免地开始看到您不熟悉的不同工具、算法和技术。你应该记下这些,并研究它们是什么。
统计???
好了,现在你开始熟悉这个过程了。我建议开始熟悉一些您将使用的统计数据和算法。你需要对统计学有一个坚实的基础理解(例如,集中趋势,概率论等。)、线性代数和微积分(你可能会等一会儿再看这个)。开始了解分类、回归和聚类算法之间的区别,并开始思考可以用这些算法解决的问题类型。有没有你看到的可以应用这些算法的数据集?你有没有可以在这些类别中找到答案的问题?
项目困扰
这就是项目成为我学习的主要焦点的地方。我会做尽可能多的项目。我会用我自己的数据,用我能找到的任何数据,在 Kaggle 上做。在下面的附录中,我添加了一些数据科学项目的视频播放列表。
我的数据教授朋友说,学习数据科学的最好方法是做数据科学,我非常同意。项目是你做真正的数据科学的第一个地方。早些时候,我提到反思数据科学的哪些部分让你感到兴奋非常重要。这就是它发挥关键作用的地方。在早期阶段,你应该把你的项目集中在你感兴趣的事情上。对一个项目来说,你能做的最重要的事情就是在这个项目上取得进展。如果你对这个话题或你正在使用的技术足够兴奋,你就尽可能地增加了你学到更多东西的机会。
如何有效地利用项目
在学习了 Python 的基础知识并做了一些项目之后,世界真的是你的了。我建议多做一些专注于技能的项目,这些技能与你自己的旅程相关。比如在大多数公司,SQL 真的很重要。如果你的目标是找一份工作,那就非常值得去做。我没有从 SQL 开始,因为我认为与 Python 相比,它非常容易学习,如果你能学习 Python,你应该能很快学会 SQL。如果你对图像分析着迷,你可能应该将你的学习和项目导向深度学习或其他一些技术。
正如你所知道的,在某个时间点之后,你真的需要调整你的计划来适应你的确切兴趣和能力。你可能不想听到这些,但这是你需要为自己做的事情。

作者图片
这就是事情的全部。如果我想在这之后学习一项新的技能或技术,我会仔细阅读并尝试尽快应用。你的项目和工作成为你过去如何使用许多算法或技术的参考。
随着您的成长,您的迭代循环变得更加紧密,您希望将更多的精力放在良好的学习习惯上。我创建了#66DaysOfData 来帮助在这个过程中保持好习惯。欢迎你随时加入这个项目,我在附录中留下了一些关于它的链接。
这需要多长时间?
你们中的大多数人可能想知道:这个过程需要多长时间?这是一个非常困难的问题。说实话,我认为你可以在短短 3 个月内很好地了解基础知识并做项目。不过,大多数人可能需要 6 个月左右的时间。我真的不建议太专注于需要多长时间。这是一个终身学习的过程,所以只要掌握了知识,3 个月,6 个月,1 年,甚至 5 年都不重要。
关于目标的重要说明
我想结束的一件事是目标的概念。当你创建路线图时,开始思考你的学习目标。你想学习什么概念,想做什么分析?大多数人学习数据科学不应该只是为了了解材料,而应该是你想要使用这些技能来实现的东西。当你学习的时候记住这些事情,但是不要害怕做出相应的调整。如果你一开始对这个领域知之甚少,你怎么可能设定准确的目标呢?随着你在这个领域的不断成长,你的目标设定、你的项目和你的学习必须不断发展。我看到很多人感到失望,当他们真的不知道他们实际上开始要做什么的时候,他们没有完成他们开始要做的事情。
这可能是一些额外的工作,但我建议再次阅读这篇文章,思考你的学习计划。在下面分享你的计划和目标,这样我们就可以互相问责了!
如果您喜欢这篇文章,请记得在 Medium 上关注我以获取更多类似内容,并注册我的简讯以获取我的内容创作和数据科学行业其他学习资源的每周更新!此外,考虑通过注册会员来支持我和成千上万的其他作家。
非常感谢您的阅读,祝您在数据科学之旅中好运!
附录
学习数据科学的资源:
- (付费)365 数据科学(年优惠 57%;这是一个附属链接):【https://365datascience.pxf.io/P0jbBY】T4
- (免费)https://kaggle.com/
- 【https://www.freecodecamp.org/】
学习编程的资源:
- (付费)365 数据科学(年优惠 57%;这是一个附属链接):【https://365datascience.pxf.io/P0jbBY】T4
- (免费)https://www.learnpython.org/
- https://www.youtube.com/redirect?event=video_description&redir_token=QUFFLUhqbFBFa1FJbGtab3g3cXlWVWxvbXdNcFhBLVRNd3xBQ3Jtc0tsVVlUOC1MUUdta3ZnTzRUOGt5QU0xSjY0Z1k1UHVXb3hHM25BVHFGT25RN0Qya3lDNjI3ZXNXRTZ4Znh4MnFMb0xBRzhRU2lHOXNzU1hObnprNll3M0o4Y1RlS2dRRUl1QXdsWFhldzhiSWtiWHRrVQ&q=https%3A%2F%2Fwww.python.org%2Fabout%2Fgettingstarted%2F(免费)
熊猫文献:https://pandas.pydata.org/docs/
数据科学项目播放列表:
- 数据科学项目初学者播放列表:https://www.youtube.com/watch?v=sq5Tn…
- 数据科学项目播放列表:https://www.youtube.com/watch?v=pPfw2…
# 66 days ofdata:【https://www.youtube.com/watch?v=qV_Al…】T4
如何学习来自多个领域的不平衡数据
多领域长尾识别、非平衡领域推广及超越(ECCV 2022)
给大家介绍一下我们的新工作,已经被 ECCV 2022 接受: 关于多领域长尾识别、不平衡领域泛化和超越 。顾名思义,这项工作的问题是,当存在来自多个域的数据,并且每个域都可能存在(潜在不同的)数据不平衡时,如何学习一个健壮的模型。现有的处理不平衡数据/长尾分布的方法只针对单域,即数据来源于同一个域;然而,自然数据可能来自 不同的域,其中一个域中的少数类可能有来自其他域的大量实例。有效地利用来自不同领域的数据可能会提高所有领域的长尾学习的性能。本文推广了传统不平衡分类问题的范式,将其从单域推广到多域。
我们首先提出 领域类可迁移性图 ,量化了数据不平衡情况下不同领域类对之间的可迁移性。在这个图中,每个节点指的是一个域类对,每个边指的是嵌入空间中两个域类对之间的距离。我们证明了可迁移性图决定了跨领域不平衡学习的性能。受此启发,我们设计了 BoDA ,一个理论上跟踪可转移性统计量上限的损失函数,以提高模型性能。我们构建了五个新的多域不平衡数据集,并对大约 20 个算法进行了比较。代码、数据和模型已经在 GitHub 上开源:https://github.com/YyzHarry/multi-domain-imbalance。
背景和动机
现实世界中的数据经常表现出标签不平衡,而不是在类之间均匀的标签分布,事实上,数据本质上是不平衡的:少数类包含大量实例,而许多其他类只有少量实例。为了处理这种现象,已经提出了许多解决数据不平衡的方法。更详细的回顾可以在我的上一篇文章中找到。
但是,现有的不平衡数据学习的解决方案主要考虑的是单域的情况,即所有样本来自同一数据分布。然而,在现实中,同一任务的数据可能来自不同的域。例如,下图显示了 Terra Incognita,这是一个为野生动物识别&分类收集的真实数据集。左图是在不同地点设立的相机陷阱,以及捕捉到的野生动物样本;右图显示了(部分)不同摄像机位置获得的具体数据分布及其拍摄效果。我们可以清楚地看到,即使是同样的野生动物分类任务,不同相机的参数、拍摄背景、光照强度等。 与 完全不同;即不同相机陷阱之间存在一个畴隙。而且由于有些动物只出现在特定的位置,这进一步导致了对于一个摄像机(域)的数据不平衡,甚至存在对于某些类别的 无数据 (比如位置 100 对于类别 0 和 1 几乎没有数据)。然而,由于不同摄像机捕获的标签分布通常差异很大,这也意味着其他属性域可能具有这些类别中的许多样本-例如,位置 46 具有更多类别 1 数据。这表明我们可以利用多域数据来解决 各域 内部固有的数据不平衡。

未知领域数据集。即使是同样的野生动物分类任务,参数、拍摄背景、光照强度等。不同相机的拍摄效果可能完全不同。每个相同的摄像机获得的数据也是极不平衡的;再者,不同相机拍摄到的标签分布也大相径庭,不匹配。但它也说明了我们可以利用多域数据来解决每个域中固有的数据不平衡。(图片由作者提供)
同样,在其他实际应用中也会出现类似的情况。例如,在视觉识别问题中,来自“照片图像的少数类可以用来自“草图图像的潜在丰富样本来补充。同样,在自动驾驶中,“真实生活中的少数事故类别可以通过“模拟中产生的事故来丰富。此外,在医学诊断中,来自不同人群的数据可以相互增强,来自一个机构的少数群体样本可以用来自其他机构的实例来丰富。在上面的例子中,不同的数据类型充当不同的域,这样的多域数据可以用来解决每个域中固有的数据不平衡。
因此,在本工作中,我们将多域长尾识别(MDLT) 问题公式化为从多域不平衡数据中学习,每个域都有其自己的不平衡标签分布,并推广到在 所有域类对 上平衡的测试集。MDLT 的目标是从多个不同领域的不平衡数据中学习,解决标签不平衡*、域转移和跨域的不同标签分布,并推广到所有域的整个类别集。*

多域长尾识别(MDLT)从多域不平衡数据中学习,解决跨域的标签不平衡、域移位和发散标签分布,并推广到所有域类对。(图片由作者提供)
多领域不平衡学习的挑战
然而,我们注意到,MDLT 带来了不同于其单一领域对手的新挑战。
(I) 首先,每个域的 标签分布很可能与其他域的 不同。例如,在上面的 gif 图中,“照片”和“漫画”域名呈现出不平衡的标签分布;然而,“漫画”中的“马”类比“照片”中的样本要多得多。除了域内数据不平衡之外,这还带来了跨域的不同标签分布的挑战*。*
**(二)二、多域数据内在涉及。简单地将不同的领域作为一个整体来对待,并应用传统的数据不平衡方法不太可能产生最好的结果,因为领域差距可以任意大。
(III) 第三,MDLT 自然地激发了 内的和 域间的——即概括为域内缺失类(gif 图右部),以及没有训练数据的 新域 ,其中后一种情况通常表示为域概括(DG) 。******
综上所述,与传统的单领域不平衡分类相比,MDLT 面临着新的困难和挑战。那么,应该怎么做多领域不平衡学习呢?在接下来的两节中,我们将从整体建模、激励示例、观察到的现象、理论推导,到最终损失函数的设计,逐步分析这个问题,并最终在 MDLT 任务上提高模型性能。
领域类可转移图
这里我们首先提出一组定义来模拟 MDLT 问题。我们认为,与单领域不平衡学习相反,在单领域不平衡学习中,人们关心的基本单元是 T21,在 MDLT,基本单元自然地转化为领域类对。
那么当我们从“领域类对”入手,就可以衡量它们之间的可转移性(相似性),可转移性定义为嵌入空间中不同领域类对之间的距离:

(图片由作者提供)
直观上,两个领域类对之间的 可转移性 是它们的学习表示之间的平均距离,表征它们在特征空间中的接近程度。默认选择 d 作为欧氏距离,但也可以表示( d,c )的高阶统计量。例如,马氏距离使用协方差。那么,基于可转移性,我们可以进一步定义 可转移性图:****

(图片由作者提供)
在可转移性图中,每个节点表示一个领域类对,每个边表示嵌入空间中两个领域类对之间的距离(即可转移性)。此外,我们可以使用多维标度(MDS)在 2D 空间中可视化该图。**

可转移性图的总体框架。(a)为所有域类对计算分布统计,由此我们生成完整的可转移性矩阵。(b) MDS 用于将图形投影到 2D 空间中进行可视化。©我们定义了(α,β,γ)可转移性统计量来进一步描述整个可转移性图。(图片由作者提供)
具体来说,如上面的图(a)(b)所示,对于每个域类对,我们可以计算特征统计(均值、协方差等)。)属于这个域类对的所有数据。然后对于不同的域类对,我们进一步计算对之间的可转移性,从中生成一个完整的可转移性图,用矩阵表示(图 a)。然后,我们可以使用多维标度(MDS)在 2D 平面上可视化这种相似性。在图 b 中,我们可以看到不同的域用不同的颜色标记,每个点代表一个域类对,它的大小代表包含的数据量,数字代表具体的类别;而它们之间的距离可以看作是可转移性。很明显,我们希望同号(也就是同一个类别)的域类对靠得更近,而不同类别的域类对离得更远。这种关系可以进一步抽象为三种可转移性统计量:异域同类 ( α )、异类同域 ( β )、以及异类异域 ( γ ):**

(图片由作者提供)
到目前为止,我们已经对 MDLT 进行了建模和数学定义。接下来,我们将进一步探讨可转移性(统计数据)和最终 MDLT 性能之间的关系。
在 MDLT,什么是好的代表?
分散的标签分布妨碍了可转移的特征
MDLT 必须处理跨域标签分布之间的差异。为了理解这个问题的含义,我们从一个例子开始。
激励范例。我们构建了数字-MLT ,一个双域玩具 MDLT 数据集,它结合了两个数字数据集:MNIST-M 和 SVHN。任务是 10 类数字分类。我们手动改变每个域类对的样本数量,以模拟不同的标签分布,并针对每种情况使用经验风险最小化(ERM)来训练普通的 ResNet-18。我们保持所有测试集的平衡和一致。结果揭示了有趣的观察。当跨域的每个域的标签分布是平衡的和相同的时,尽管存在域间隙,但这并不禁止模型学习高准确度(90.5%)的区别特征,如图 a 所示。如果标签分布是不平衡的但相同的*,如图 b 所示,ERM 仍然能够在两个域中对齐相似的类,其中多数类(例如类 9)在可转移性方面比少数类(例如类 9)更接近相比之下,当标签都是跨域的不平衡和不匹配时,如图 c 所示,学习到的特征是 不再可转移 ,导致跨域的间隙和最差的准确度。这是因为跨域的发散标签分布产生了不期望的捷径;该模型可以通过简单地分离两个域来最小化分类损失。***

当数字的标号比例变化时,可转移性图形的演变模式——MLT。(a)两个域的标签分布是平衡且相同的。(b)两个域的标签分布不平衡但相同。两个域的标签分布是不平衡和发散的。(图片由作者提供)
可转移的特征是可取的。结果表明,需要可转移特征跨( d,c )对,尤其是出现不平衡时。特别地,跨域的同一类之间的可转移性链接应该大于域内或跨域的不同类之间的可转移性链接。这可以通过( α,β,γ )可转移性统计来捕获,如下所示。**
可迁移性统计特征概括
激励的例子。同样,我们使用具有不同标签分布的数字-MLT 。我们考虑三种不平衡类型来组成不同的标签配置:(1) 统一(即平衡标签),(2) 前向-LT ,其中标签在类 id 上呈现长尾,以及(3) 后向-LT ,其中标签相对于类 id 是反向长尾。对于每种配置,我们用不同的超参数训练 20 个 ERM 模型。然后,我们计算每个模型的( α,β,γ )统计量,并绘制其相对于(β+γ)——α的分类精度。

(β+γ)α数量与不同数字标签配置测试准确度之间的对应关系-MLT。每个图表示两个域的特定标记分布(例如,( a)对域 1 采用“统一”,对域 2 采用“统一”)。每个点对应一个使用不同超参数的 ERM 训练模型。(图片由作者提供)
它揭示了多个有趣的发现:(1)α,β,γ 统计数据表征了一个模特在 MDLT 的表现。特别是,(β+γ)α量在整个范围和每种标签配置中与测试性能表现出非常强的相关性。 (2) 数据不平衡增加了学习较少可转移特征的风险。然而,随着标签变得不平衡(图 b、c)和进一步发散(图 d、e),模型学习不可转移特征(即较低的(β+γ)——α)的机会增加,导致性能大幅下降。
限制可转移性统计的损失
我们利用上述发现来设计一个特别适合 MDLT 的新损失函数。我们将首先引入损失函数,然后证明它最小化( α,β,γ )统计量的上界。我们从一个简单的损失开始,这个损失是由公制学习目标激发的。我们将这种损失称为 L_{DA},因为它旨在实现域类分布对齐,即跨域对齐同一类的特征:

(图片由作者提供)
直观上,这种损失解决了 标签发散 ,因为共享同一类的( d,c )对将被拉近,反之亦然。也与( α,β,γ )统计有关,因为分子代表 正 跨域对 ( α ),分母代表 负 跨类对 ( β,γ )。
但是,并没有解决标签不平衡的问题。注意( α,β,γ )是以方式定义的,与每个( d,c )的样本数无关。然而,给定一个不平衡的数据集,大多数样本将来自多数域类对,这将主导损失并导致少数对被忽略。****
平衡域级分布比对。为了解决( d,c )对之间的数据不平衡,我们将损耗修改为 BoDA 损耗:

(图片由作者提供)
BoDA 通过因子 1/N_{d,c} 缩放原始的 d ,该因子是域类对中的样本数( d,c )。因此,它通过引入一个平衡的 距离度量来抵消不平衡的域类对的影响。对于博达,我们有以下定理:

(图片由作者提供)
请参考我们的论文了解证明细节。定理 1 具有以下有趣的含义:
- BoDA 上界( α,β,γ )以期望的形式统计,自然转化为更好的性能 。通过最小化 BoDA,我们保证一个 低 α (吸引相同阶层)和 高、γ (分开不同阶层),这是在 MDLT 推广的必要条件。**
- 常数因子对应于各成分对可转移性图形 的贡献大小。放大 exp( ) 的论点,我们观察到目标与α(β 1/| D |+γ(| D | 1)/| D |)*成正比。根据定义 3,我们注意到 α 总结了相同类别的数据相似性,而后一个表达式使用 β 和 γ 的加权平均值总结了不同类别的数据相似性**,其中它们的权重与关联域的数量成比例。*******
针对数据不平衡的校准导致更好的传输
BoDA 的工作原理是鼓励 特征跨 域转移相似的类,也就是说,如果( d,c 和(d′,c )在不同的域中引用同一个类,那么我们希望将它们的特征互相转移。但是、少数领域类对自然会有更差的特征估计,这是由于数据稀缺、以及强迫其他对转移给它们会损害学习。因此,当在嵌入空间中拉近两个域类对时,我们希望少数的(d,c )转移到多数的中,而不是相反。****
这里有很多细节,我就直接跳过了。在我们的论文中给出了详细的激励示例和解释。结论是通过给 BoDA 增加一个校准项,可以通过两个域类对的**相对样本大小来控制转移度😗*****

(图片由作者提供)
基准 MDLT 数据集和实验
为了支持多领域不平衡学习方法的实际评估,并促进未来的研究,我们从现有的多领域数据集筛选了五个 MDLT 基准:

(图片由作者提供)
此外,我们选择了 ~20 种算法,涵盖了多领域学习、分布式鲁棒优化、不变特征学习、元学习、不平衡学习等多个类别。作为基线比较,以及每个算法的优化超参数。这样的过程确保了比较是最佳对最佳的,并且超参数对于所有算法都是优化的。**
在评估期间,我们报告跨域的平均**准确度;我们还报告了域上最差的**精度,并将所有域类对进一步划分为多射(超过 100 个训练样本的对)、中射(20∾100 个训练样本的对)、少射(20 个训练样本以下的对)和零射(没有训练数据的对),并报告结果******
实验:由于实验很多,这里只展示有代表性的结果(所有结果请参考论文)。首先,BoDA 在所有数据集上始终保持最佳平均准确度**。它还在大多数情况下实现了最佳 最坏精度。此外,在某些数据集上(例如,OfficeHome-MLT),MDL 方法表现更好(例如,CORAL),而在其他数据集上(例如,TerraInc-MLT),不平衡方法实现更高的增益(例如,CRT);然而,不考虑数据集,BoDA 优于所有方法,突出了其对于 MDLT 任务的有效性。最后,与 ERM 相比,BoDA 略微提高了平均和多次拍摄的性能,而大大提高了中镜头、少镜头和零镜头对的性能。******

(图片由作者提供)
理解博达的分析:我们对博达进行进一步分析。我们绘制了通过 BoDA 学习的可迁移性图,并在不同的跨域标签分布下与 ERM 进行了比较。从下图可以看出,博达学习了一个更平衡的特征空间来区分不同的类别。当标签分布平衡和相同时,ERM 和博达都能学习到好的特性;当标签开始不平衡 (b,c),甚至不匹配跨域(d,e)时,ERM 学习到的可迁移性图中有一个明显的域缺口;相比之下,博达总能学习到一个平衡的和对齐的特征空间。因此,更好的学习特征转化为更好的精度(9.5%的绝对精度增益)。****

(图片由作者提供)
超越 MDLT:不平衡的领域泛化
领域泛化(DG)是指从多个领域学习,并泛化到看不见的领域。由于学习域的标签分布自然不同,甚至可能在每个域中存在类别不平衡,我们研究 BoDA 是否可以提高 DG 的性能。请注意,我们为 MDLT 调整的所有数据集都是 DG 的标准基准,这证实了数据不平衡是 DG 中的固有问题,但被过去的工作忽略了。

(图片由作者提供)
我们按照标准的 DG 评估测试 BoDA。上表揭示了以下发现:首先, BoDA 单独使用可以在五个数据集中的四个上改善当前的 SOTA,并实现显著的平均性能增益。此外,将与当前的 SOTA 相结合,博达在所有数据集上进一步显著提高了结果,表明标签不平衡与现有的 DG 特定算法正交。最后,与 MDLT 相似,增益取决于数据集内不平衡的严重程度 TerraInc 显示出跨域的最严重的标注不平衡,而 BoDA 在这方面的增益最高。这些有趣的结果揭示了标签不平衡如何影响分布外泛化,并强调了整合标签不平衡对于实际 DG 算法设计的重要性。
结束语
作为本文的总结,我们提出了(1)一个称为多域长尾识别(MDLT)的新任务,( 2)一个新的理论上保证损失函数 BoDA 来建模和改进 MDLT,以及(3)五个新基准来促进未来对多域不平衡数据的研究。此外,我们发现标签不平衡影响分布外泛化,实际和稳健的 DG 算法设计也需要纳入标签不平衡的重要性。最后,我附上了几个与本文相关的链接;感谢阅读!
代号:https://github.com/YyzHarry/multi-domain-imbalance
项目页面:http://mdlt.csail.mit.edu/
如何轻松学习新的编程语言
原文:https://towardsdatascience.com/how-to-learn-new-programming-languages-easily-1e6e29d3898a
学习任何新的编程语言——例如 Python、Java 和 Go

阿诺·弗朗西斯卡在 Unsplash 上的照片
经历了在大学学习编程语言,通过各种电子学习平台,并在极少的指导下投入到研究生项目中(包括教授自己开发的超级利基“编码语言”),我注意到不同编程语言的共同之处。
如果你已经知道至少一种编程语言,那么对比其他语言会让你更容易掌握。如果你没有——希望这篇文章将“学习如何编码”的抽象概念分解成更小的基本块。
这篇文章将涉及不同类型的编程语言,如何接近一种(新的)编程语言,编程语言的基本组成部分,以及最后如何设置您的笔记本电脑并运行代码!这些都将用 Python、Java 和 Go 中的例子来解释。
目录
声明式与命令式编程范例
了解编程范式的类型可以让我们知道编程语言的用途,以及代码是如何组织和执行的。
有两种编程范例——声明式和命令式。
声明式编程范例的子集包括函数式、数学式、逻辑式和反应式编程。它试图执行操作,但不控制操作如何发生或操作的执行顺序。
命令式编程范例的子集包括过程式和面向对象的编程。它试图控制操作发生的顺序。
由于 Go 是一种过程化编程语言(我们后面会看到这是什么意思),所以它是命令式编程。而 Python 和 Java 是多范式语言,这意味着它们根据您的编程需求支持声明式和命令式编程范式。
编译语言与解释语言
理解代码执行的幕后发生了什么
编译语言和解释语言的区别在于代码是如何执行的。
Go 是编译型语言,Python 是解释型语言,而 Java 是编译和解释并重;它首先被编译成中间形式,然后由解释器解释。
在我们运行代码的最后一节,我们将看到运行编译语言与运行解释语言有什么不同。
定义和描述编程语言还有其他方法,但我发现了解编程范式和代码如何执行就足以让我充分了解编程语言。
还有其他类型的比较,下面的列表并不详尽,
- 弱类型与强类型 :弱类型允许数据类型之间的隐式转换,而强类型不允许
- 静态与动态类型 :静态类型在编译时执行类型检查,而动态类型在运行时执行类型检查
- 高级vs .低级 语言:高级语言面向用户,低级语言面向机器
- 通用vs .特定领域 语言:通用语言可以解决多个领域的问题,而特定领域语言是专门为解决一个领域的问题而创建的
现在,让我们深入了解编程语言的基本组成部分!

打印和注释
任何编程语言的第一行代码
您可能熟悉术语print("Hello World"),打印很重要,因为它不仅跟踪您正在执行的操作,而且有助于调试代码错误,例如打印中间变量以检查它们是否有错。
另一方面,注释对代码没有任何作用,但是允许你在代码中添加注释来解释代码在做什么。这有助于您和他人更好地理解代码。
下面是用 Python、Java 和 Go 注释和打印的代码片段。

图 Python、Java 和 Go 中的注释和打印——作者图片
关于打印和注释的更多主题:
- 注释的类型,即行内注释与块注释
- 打印不同的数据类型(见下一节)
- (Python)使用 f 字符串打印
数据类型
任何编程语言的支柱
数据类型是任何编程语言的支柱,因为每个变量和对象都是一种数据类型。不同的数据类型可以执行不同的操作,并且有不同的方式与它们交互。例如,您可以从一组数字中获取最大值,但不能从单个数字中获取最大值。
有三种不同的数据类型—简单、复杂和用户定义的。简单数据类型代表单个值,比如描述数字或文本的变量。复杂数据类型由多种现有的数据类型组成,比如一个数字序列或者将一个数字映射到一个单词(例如,在电话簿中)。某些编程语言支持用户定义的数据类型,您可以在其中创建自己的数据结构。

图 2a: Python 数据类型—作者图片
在 Python 中,上图是所有数据类型的列表,并提供了示例。由于 Python 是一种弱类型语言,我们可以将它赋给一个变量,而不用定义它的类型。举个例子,

图 2b:用 Python 实例化变量——作者图片

图 3a: Java 数据类型——作者图片
Java 是一种强类型语言;当初始化一个新变量时,必须指定变量的类型,有时甚至是变量的大小。

图 3b:用 Java 实例化变量——作者图片

图 4a: Go 数据类型—按作者分类的图片
与 Java 类似,Go 是一种强类型语言,但是 Go 不需要显式地指定变量类型。Go 在如何创建新变量方面也有所不同;它定义了所有以关键字var开始的变量。或者,为了避免使用关键字var,可以使用数学表达式:=。下面是一些如何在 Go 中实例化变量的例子,

图 4b:用 Go-Image 按作者实例化变量
除了知道不同的数据类型之外,区分数据类型是可变的还是不可变的(如果它的值在创建后可以改变)或者它们是否被索引以知道何时选择每种数据类型是很重要的。一开始,接触多种数据类型可能会令人望而生畏。我发现将我关于数据类型的笔记组织成三个不同的部分是有益的——构造新变量、查询变量和转换变量。
关于数据类型的更多主题:
- 【构造加载外部文件,即从 JSON 文件初始化字典
- 【构造】简单数据类型之间的转换,如十进制到整数,日期到字符串
- [ Query 从复杂或用户定义的数据类型中检索项目
- [ 转换 ]将项目前置或附加到复杂数据类型
- [ 转换 ]替换可变数据类型中的项目
- [ 转换 ]排序或反转复杂的数据类型,如列表、字典
- [ 转换字符串操作,即改变大小写、提取字符或子串、删除前导或尾随空格、拆分字符串
条件句和循环
基于条件控制代码流,或者重复一个代码,直到满足条件
了解了数据类型并实例化了一些变量之后,很自然地想要控制代码流或者修改变量(或者变量中的每一项)。为了控制代码流,我们可以只在满足某些条件的情况下执行一组指令,并相应地指导代码流。为了修改变量中的每一项,我们通过变量迭代,这可以使用循环来完成。
有一些常见的条件和循环,注意不是所有的编程语言都支持下面列出的所有类型的条件和循环,
- If-else 条件:执行一个任务 如果 满足一个条件, else 执行另一个任务或者什么都不做
- 切换情况:在一种情况下执行一项任务,在另一种情况下执行另一项任务。这类似于 if-else 语句,只是条件的计算结果是一个值而不是布尔值(真或假)
- For 循环:执行任务 for 复变量中的每一项
- While loop:在 一个条件满足时执行一个任务 (当心无限循环!)

图 Python、Java 和 Go 中的条件句——作者图片
关于条件句的更多主题:
- 不同数据类型的数学条件或更复杂的条件检查
- 为复杂数据类型实现 for 循环,即迭代列表
- 创建一个变量范围并为其实现一个循环
- 使用枚举器并为其实现一个循环
函数和类
对一系列操作进行分组,并重用它们
函数和类是最常见的代码,因为函数式编程使用函数,而面向对象编程使用类。
对于任何函数,都需要指明输入的名称。对于某些(更严格的)编程语言,还需要提供输入和预期输出的数据类型。作为面向对象的编程,类将几个相关的函数结合在一起。类内的函数被称为类 方法 。

图 Python 中的函数和类——作者图片
在 Python 中,函数用关键字def定义(第 1 行),输出用关键字return返回(第 4 行)。不需要指定输出的数据类型。

图 Java 中的类——作者图片
Java 里是面向对象编程,文件名必须跟在类名后面;类别MyClass必须包含在MyClass.java中。如果文件被执行,只有main功能(第 6 行)会运行。
在定义一个类方法时,需要定义输入和输出变量的数据类型,并且有一个可见性修饰符(private/public/protected)和其他隐式参数(static/final)的概念,这将不在本文中讨论。

图 8:Go 中的类——按作者分类的图片
在 Go 中,类似于 Java,也是面向对象编程但是对文件名没有限制。执行该文件时,只会运行main功能(第 10 行)。
由于在执行.go文件时只运行main函数,所以函数通常被顺序地缝合在一起,形成过程。因此,正如本文开头提到的,Go 遵循过程化编程范式。
关于函数和类的更多主题:
- 类方法与类对象
- 类中的构造函数、析构函数
- (Python)类方法与静态方法
- (Java)可见性修饰符和其他隐式参数
- 继承:将一个类扩展到另一个类
- 断言:确保满足条件
- 异常处理:控制出现错误时会发生什么
进口
使用内置包、外部包或其他文件中的代码
单个文件中的代码可能无法涵盖您需要的所有内容,您将需要依赖于包或文件中的现有代码,这些代码由他人或您自己编写,通过导入它们来实现。
有三种类型的导入—从内置包、外部包或其他文件导入。导入在代码开始时完成,因为您需要在使用它们之前导入包。
从内置包和外部包导入遵循相同的过程,只是需要额外的步骤来安装外部包。

图 9:在 Python 中导入——按作者分类的图片
在 Python 中,常用pip或conda安装程序。外部包可以在终端上用命令pip install package-name或conda install package-name安装,用上面的例子导入。

图 10:用 Java 导入——作者图片
在 Java 中,通过在各自的 Maven 或 Gradle 文件中添加包的详细信息,可以用 Maven 或 Gradle 安装外部包。上面显示了一些用 Java 执行导入的例子。

图 11:在 Go 中导入—按作者排序的图像
在 Go 中,可以在命令行用go get package-name安装外部包。同一文件夹中的所有代码都属于同一个包,因此不需要导入。但是,您需要用上面的例子导入内置或外部的包。
设置和运行代码
学习理论后迈出第一步
终于,你准备好开始编码和运行一些代码了!
*要进行设置,您需要下载编程语言本身,本文末尾提供了链接。你还需要下载一个 **IDE(集成开发环境)*来运行代码。你可以把 IDE 看作是一个运行代码的漂亮界面,否则你就需要使用命令行界面,这对初学者来说并不友好。一些 IDE 可以运行多种编程语言,所以你只需要下载一个 IDE。
就个人而言,我不喜欢将我的 IDE 与多种编程语言混合在一起。这是我的设计,
- Python: PyCharm(重载),Sublime Text(轻量级)
- Java: IntelliJ 理念
- Go: Visual Studio 代码,终端
要运行代码,可以在 IDE 上(推荐)或通过命令行界面运行代码。

图 12:在 PyCharm 中运行 Python 作者图片
要运行 Python 代码,您可以点击 Ctrl-Enter 或 Ctrl-B 按钮,或者将其复制并粘贴到 Python 控制台——这取决于您的 IDE。

图 13:在 IntelliJ IDEA 中运行 Java 作者图片
要运行 Java 代码,您需要先构建代码,以便在运行它们之前将.java文件编译成.class文件。这个额外的步骤是因为 Java 既是编译语言又是解释语言,正如前面的章节所解释的。

图 14:在 Visual Studio 代码中运行 Go——作者图片
要运行 Go 代码,您可以使用命令行界面并运行go run file-name.go来编译和执行代码。
或者,如果您只想在没有任何安装的情况下玩玩,您可以使用在线 IDE。
在本文的最后有 Python、Java 和 Go 的在线 IDE 的链接。虽然在线 ide 很方便,但是它们不能执行复杂的任务,比如安装和导入某些外部包,或者在多个文件中编写代码。
恭喜你,你现在知道如何学习编程语言了,从理解编程语言的类型和组成编程语言的基本组件,到如何设置和运行代码。希望通过 Python、Java 和 Go 的例子,您可以看到编码语法和约定之间的相似之处和(一些)不同之处——一旦我们找到相似之处,学习其他语言就更容易了!不要担心混淆语法,是的,它会发生,谢天谢地,好的 ide 可以在你运行代码之前发现并反映这些错误。
要掌握一门编程语言,最好是每天通过做一个简单的任务或项目来练习。
最后,除了经常练习编程语言,我认为编码是一种“思维方式”。例如,给定一个大项目,适当地组织你的代码而不是从上到下顺序运行它或者硬编码组件是很重要的。幸运的是,这种“思维方式”可以通过遵循编码最佳实践来加以利用(您可以将其视为一组推荐的规则)。遵循编码最佳实践可以使您的代码更加优雅、模块化和易于理解。有需求的话可以出续集;)
*💔-tips-for-writing-clean-codes-beyond-coding-best-practices-c53b04120c3> *
相关链接
计算机编程语言
- 安装:https://www.python.org/downloads/
- *教程:【https://docs.python.org/3/tutorial/ *
- *在线 IDE:【https://www.online-python.com/ *
Java 语言(一种计算机语言,尤用于创建网站)
- 安装:https://www.oracle.com/java/technologies/downloads/
- 教程:https://www.w3schools.com/java/
- 在线 IDE:https://www.jdoodle.com/online-java-compiler/
去
- 安装:https://go.dev/doc/install
- 教程:https://go.dev/doc/tutorial/getting-started
- 在线 IDE:https://go.dev/play/
如何用 5 种简单的方法提升你的熊猫技能
原文:https://towardsdatascience.com/how-to-level-up-your-pandas-skills-in-5-easy-ways-223208ce18cc
用熊猫提升你的数据科学技能的 5 种方法

Pandas 是一个用于数据科学的强大而通用的 Python 库。在学习如何将 Python 用于数据科学应用时,它通常是您最先遇到的库之一。它可以用来加载数据,可视化数据和操作数据,以适应您正在进行的项目的目标。
然而,许多人没有超越如何使用库的基础,并且没有利用一些更高级和有趣的特性。
在这篇文章中,我们将介绍 5 个你以前可能没有遇到过的特性,这些特性将使你在使用这个库时更有效率。
加载库和数据
对于本文中使用的所有示例,我们将使用的数据是作为 Xeek 和 FORCE 2020 (Bormann 等人,2020) 举办的机器学习竞赛的一部分的测井数据的子集。该数据在此处https://zenodo.org/record/4351156#.Y4iZHC-l0eY公开,并根据 挪威政府数据公开许可证(NLOD) 2.0 获得许可。
然而,这里显示的所有方法和示例都可以应用于加载到 pandas 中的任何数据集。
首先,我们首先需要导入 pandas 库,为了方便起见,通常简称为pd 。
然后,我们将使用read_csv()函数将 csv 文件读入数据帧。
import pandas as pd
df = pd.read_csv('data/Xeek_train_subset_clean.csv')
df
当我们查看数据帧时,我们可以看到有 12 列数据混合了文本和数值。

来自 Xeek Force 2020 机器学习竞赛的测井数据的数据帧。图片由作者提供。
现在已经完成了,我们现在可以继续 5 种方法来提高你与熊猫的数据科学技能。
更改默认熊猫绘图库
在进行探索性数据分析时,我们通常希望快速绘制出我们的数据。你可以使用 matplotlib 构建一个情节,然而,我们可以使用 pandas 通过几行代码来完成。
一旦你加载了数据,你就可以调用 dataframe,然后调用.plot方法。
例如,如果我们采用 GR 列并绘制直方图,如下所示:
df.GR.plot(kind='hist', bins=30)
这将返回以下图:

熊猫使用的伽玛射线直方图。plot()函数。图片由作者提供。
返回的图像非常简单,缺乏交互性。
从 pandas 版本 0.25 可以改变使用哪个绘图库。例如,代替 matplotlib,你可以为 plotly 切换这个。 Plotly 允许以高效的方式生成非常强大的交互式数据可视化。
有关如何使用 Plotly 生成另一种类型的散点图的更多信息,您可能有兴趣浏览我以前的文章:
要更改当前实例的默认绘图库,您需要更改 pandas 的plotting.backend选项。
pd.options.plotting.backend = "plotly"
一旦你完成了,你就可以像以前一样调用相同的代码
df.GR.plot(kind='hist', bins=30)
生成的绘图现在是交互式的,并在探索数据集时提供了更好的用户体验。

将 pandas 后端绘图选项更改为 plotly 后的伽马射线直方图。图片由作者提供。
您还可以使用其他类型的图,包括散点图,方法是稍微修改一下代码,如下所示:
df.plot(kind='scatter', x='NPHI', y='RHOB', color='GR')
当执行上面的代码时,您会得到下面的图:

改变熊猫后端绘图选项后创建的交互式散点图。图片由作者提供。
链接操作
将多个方法链接或连接在一起是一种长期实践的编程技术,可以提高代码的可读性。
它是在一行中一个接一个地调用对象上的方法的过程,而不是分别对对象应用这些方法。这有助于您流程的多个阶段。
例如,如果要加载数据,请将列更改为小写,然后删除缺失值(nan ),可以这样做:
df = pd.read_csv('data/Xeek_train_subset_clean.csv')
df = df.rename(columns=str.lower)
df = df.dropna()
然而,更有效的方法是像这样链接操作:
df = pd.read_csv('data/Xeek_train_subset_clean.csv').rename(columns=str.lower).dropna()
有时这一行可能会变得很长,所以您可能希望通过将它分成多行来提高可读性。
如本堆栈溢出问题所示,这可以使用行继续符(\)来完成。
df = pd.read_csv('data/Xeek_train_subset_clean.csv')\
.rename(columns=str.lower)\
.dropna()
或者使用圆括号,就像另一个 StackOverflow 问题中建议的那样,这样就不需要换行字符了。
df = (pd.read_csv('data/Xeek_train_subset_clean.csv')
.rename(columns=str.lower)
.dropna())
查询()
我们在处理数据时经常做的一项常见任务是基于单个或多个条件对数据进行过滤。您可以使用以下代码来实现这一点:
df[df.GR > 100]
然而,使用 熊猫查询 函数会产生一段可读性更好的代码,尤其是当事情变得稍微复杂一些的时候。
例如,如果要查找 GR(伽马射线)列包含值大于 100 的所有行,可以像这样调用查询方法:
df.query("GR > 100")
它返回下面的 dataframe 对象。

使用 pandas 查询方法过滤伽马射线大于 100 API 的行后的 Dataframe。图片由作者提供。
如果您想要组合多个条件,也可以使用逻辑。
df.query("GR > 100 and GR < 110")
它返回一个更小的数据帧,只有 7,763 行

使用 pandas 查询方法过滤伽马射线大于 100 API 但小于 110 API 的行后的数据帧。图片由作者提供。
如果你想寻找一个特定的字符串值,比如这个数据集中的无水石膏,你需要修改我们的查询方法,把几个方法连接在一起。
df.query("LITH.str.contains('Anhydrite')")
这将返回其中 LITH 列包含单词 Anhydrite 的任何行

使用 pandas 查询方法过滤 LITH 包含硬石膏的行后的 Dataframe。图片由作者提供。
如果字符串包含特殊字符,例如我们的数据帧中的井列包含反斜杠和破折号,也可以使用这种方法:
df.query("WELL.str.contains('15/9-13') and GROUP.str.contains('ZECHSTEIN GP.')")

使用 pandas 查询方法筛选组中包含 Zechstein Gp 的行后的 Dataframe。井名是 15/9–13。图片由作者提供。
eval()
Python 中的 eval()方法是一个强大的工具,可以对同一数据帧中的列计算任意 Python 表达式。
这意味着您可以通过提供字符串表达式从数据帧中提取列并执行算术计算。
例如,您可以从 GR 列中减去值 100:
df.eval('GR-100')
它返回

结果用 eval 方法进行简单计算后。图片由作者提供。
如果您想将这个计算放在一个新的列中,您需要调用pd.eval并传递目标数据帧后面的表达式。
pd.eval('GR_TEST = df.GR - 100', target=df)

使用 pd.eval 添加基于简单表达式的新列后的 Dataframe。图片由作者提供。
岩石物理学中的常见计算是计算地层中粘土的体积。要进行这种计算,您只需扩展以下表达式:
pd.eval('CLAYVOL = ((df.GR - 20)/(200-10))', target=df)
这会创建一个名为CLAYVOL的新列

使用 pd.eval 方法根据伽马射线柱计算粘土体积后的数据帧。图片由作者提供。
如果您正在进行适当的岩石物理分析,您将需要考虑基于多个地层或深度范围的选定参数。上面举例说明了进行计算的一种快速方法。
地图()
如果我们需要匹配某个对象(如字典)中的值,或者用另一个值替换数据帧中的值,我们可以使用 映射功能 。
此函数只能应用于数据框架中的单个列或 Pandas 系列。
使用这个数据示例,我们可以创建一个新列,其中包含基于文本字符串的数字代码。这可以通过使用另一个数据帧或字典来实现。
如果使用字典作为参考,您首先需要创建一个或加载一个。这个例子使用了一个快速创建的简单例子。
lith_dict = {'Shale':1,
'Sandstone':2,
'Sandstone/Shale':3,
'Limestone':4,
'Tuff':5,
'Marl':6,
'Anhydrite':7,
'Dolomite':8,
'Chalk':9,
'Coal':10,
'Halite':11}
接下来,您将创建一个新列,例如,LITH_CODE。
然后调用 LITH 列并应用.map函数,它包含上面创建的字典。
df['LITH_CODE'] = df['LITH'].map(lith_dict)
当您调用 dataframe 时,您现在有了一个新列,该列的岩性代码映射到正确的岩性。

Dataframe 在使用 map 函数后,根据 string 的内容创建一个新的岩性代码列。图片由作者提供。
摘要
Pandas 是一个令人难以置信的图书馆,允许用户以非常直观的方式可视化、转换和分析数据。本文介绍了一些鲜为人知的特性和方法,如果您刚刚开始数据科学之旅,其中许多可能对您来说是新的。了解这些将有助于您利用熊猫的力量来提高您的数据分析技能。
感谢阅读。在你走之前,你一定要订阅我的内容,把我的文章放到你的收件箱里。 你可以在这里做!或者,您可以 注册我的简讯 免费获取更多内容,直接发送到您的收件箱。
其次,你可以通过注册成为会员来获得完整的媒介体验,并支持我和成千上万的其他作家。每月只需花费你 5 美元,你就可以接触到所有精彩的媒体文章,也有机会通过写作赚钱。如果你用 我的链接 , 报名,你直接用你的一部分费用支持我,不会多花你多少钱。如果你这样做了,非常感谢你的支持!
参考
博尔曼,彼得,奥桑德,彼得,迪里布,法哈德,曼拉尔,投降,&迪辛顿,彼得。(2020).机器学习竞赛 FORCE 2020 井测井和岩相数据集[数据集]。芝诺多。https://doi.org/10.5281/zenodo.4351156
如何升级你的终端游戏
原文:https://towardsdatascience.com/how-to-level-up-your-terminal-game-db7b44e31e65
提高效率的 6 个命令行实用程序

作者图片
对于许多新开发人员来说,使用终端或命令行可能会显得低效甚至过时。然而, shell 是任何开发人员可用的最有用的工具之一。在这篇文章中,我将向你展示六个有用的工具来升级你的终端游戏!
***Table of Contents*****1\. xclip
2\. croc
3\. zoxide
4\. htop
5\. entr
6\. fzf**
1.复制/粘贴
当我说“复制/粘贴”时,您可能会立即想到 Ctrl-C 和 Ctrl-V,但是您知道吗,您还可以使用命令行以编程方式将数据复制/粘贴到系统的剪贴板,而无需使用任何键盘快捷键。
如果您使用的是基于 Linux 的操作系统(或 Windows 上的 WSL),您可以使用 xclip 实用程序从命令行与剪贴板进行交互。你可以使用你系统的包管理器来安装 xclip(比如 Ubuntu 上的apt,或者 Arch 上的pacman)。
运行xclip -o将会显示你剪贴板的当前内容,你可以把它导入另一个程序,重定向到一个文件,等等。
同时,通过管道将文本输入到命令xclip中会导致文本被复制到您的剪贴板中。(旁注:xclip 旨在与 X11 窗口系统一起使用。如果你用的是 Wayland,你应该安装wl-clipboard,它提供wl-copy和wl-paste。
如果你在 MacOS 上,你可以使用相应的pbcopy和pbpaste命令来代替。在 Windows 上,如果您没有使用 WSL,您可以使用clip.exe(对应于copy)和/或 Powershell 命令Get-Clipboard和Set-Clipboard。
无论您使用什么操作系统,我都建议您在 shell 配置文件中使用别名复制/粘贴命令,如下例所示。如果您正在使用 bash,您可能希望将您的别名添加到~/.bashrc(或者对于 zsh,添加到~/.zshrc)。您可以通过运行echo $SHELL来检查您当前使用的是什么 shell。
# Example copy/paste alias for Linux
alias paste='xclip -o'
alias copy='xclip -c'# Example copy/paste alias for MacOS
alias paste=pbpaste
alias copy=pbcopy
现在,您可以运行如下命令:
paste > file # paste clipboard into a file
cat file | copy # copy file contents to clipboard
paste | croc send # send clipboard contents using croc
2.鳄鱼
Croc 是一个有用的跨平台工具,可以在两台计算机之间安全地传输数据(比如文件或文本)。不用再发送 zip 文件或者摆弄 Dropbox——如果你需要发送文件给某人,在大多数情况下,croc 更简单(可能)更快。
唯一的要求是发送方和接收方的系统上都安装了 croc。Croc 可能可以从您最喜欢的包管理器获得——更具体的安装说明可以在项目的 github 页面上找到。
以下是 Croc 的使用示例:
$ croc send file.dat
Sending 'file.dat' (0 B)
Code is: <code-phrase>
在第二台计算机上,键入croc <code-phrase>将提示您接受传输的数据,如下所示:
Accept 'file.dat' (0 B)? (Y/n)
使用 croc 发送文本同样简单——您可以通过管道将文本输入到 croc 中,也可以手动键入文本,如下所示:
$ echo "Hello from croc!" | croc send
# or
$ croc send --text "Hello from croc!"
如果这还不够,croc 允许支持多种加密/哈希算法、可恢复传输和代理!在我看来,croc 是一个非常有用的工具,可以放在你的工具箱里。
3.佐西德
Zoxide 与我之前提到的其他工具有所不同。它旨在通过帮助您更快地遍历文件系统来改善命令行体验。
Zoxide 允许你进入一个目录而不用给出完整的路径。相反,Zoxide 会考虑你过去的历史,并根据你提供的名字来判断你想去哪里。本质上,佐希德只是一个“更聪明的”cd。
Zoxide 支持所有主要的 shells,并且可能从您最喜欢的包管理器中获得。你可以在它的 Github 页面上找到安装说明和更高级的使用技巧。
这里有一个如何使用 Zoxide 的例子。注意:Zoxide 提供了命令z,但是由于肌肉记忆,我更喜欢别名它而不是cd。
$ z /opt/local/lib # changes your directory like normal
$ z ~ # jumps to home directory like normal
$ z lib # will automatically jump /opt/local/lib
$ z .. # go up one directory
$ z l # may also jump to /opt/local/lib
使用 Zoxide 时,运行z <something>会根据 Zoxide 的匹配算法将目录更改为排名最高的选择。Zoxide 既考虑了一个目录被访问的频率,也考虑了它上次被访问的时间。
比如多次进入目录/opt/local/lib,就会增加它的“分数”。现在,如果你从你的主目录运行z lib,Zoxide 会直接把你带到/opt/local/lib。事实上,你甚至不需要完全输入lib。Zoxide 使用模糊字符串匹配,所以即使运行z l也能把你带到正确的地方。
我个人认为 Zoxide 很有用,因为它允许我跳转到不同项目的目录,而不必记住它们在我系统中的确切位置。只要我知道一个目录的名称(或者它的前 3 个字符),我就可以到达那里。
4.htop
Htop 是终端的资源监视器和进程管理器。
Htop 可以使用你最喜欢的软件包管理器来安装。最新版本和源代码可以在它的 Github 上找到。

来自https://htop.dev/screenshots.html的 htop 官方截图
下面是 htop 允许您做的事情的快速列表:
- 查看每个内核的 CPU 负载、内存使用情况(包括交换)、正常运行时间等
- 显示哪些进程使用了最高数量的 CPU/内存
- 按名称或 PID 搜索流程
- 用你选择的中断终止进程(比如 SIGINT,SIGKILL,SIGTERM 等)
Htop 同时支持键盘和鼠标——如果你不需要的话,就不必学习快捷键。此外,通过树形视图,您可以看到哪些进程是其他进程的子进程,这非常有趣。我主要使用 htop 来监控系统负载和杀死行为不当的进程(在我自己的系统和远程服务器上)。
5.引入线
Entr 是一个实用程序,允许您在每次文件更改时重新运行命令。这允许您用一个简单的终端命令实现自己的 ad-hoc 实时重载服务器。Entr 应该可以从你最喜欢的包管理器中获得(或者如果你想手动安装它,请看它的主页这里)。
使用 entr 的方法是在标准输入中提供一个文件名列表,以及每当这些文件之一发生变化时运行的命令。举例来说,假设我们有一个简单的 Python 项目,我们想在源代码发生变化时重新运行该程序。
这可以用一行代码来完成:
$ find . -name *.py | entr python main.py
如上所述,find命令用于生成当前目录中扩展名为py的所有文件的列表,然后该列表通过管道传输到entr,每当检测到其中一个文件发生变化时,它就会重新运行main.py。
如果我们需要更复杂的行为,我们可以简单地添加一个 Makefile 并告诉 entr 要构建哪个目标。例如,给定一个假设的 C 项目,我们可能希望运行下面的代码,让 Make 处理重新编译 C 文件的复杂性。
$ find src/ | entr make
Entr 还允许您在命令中使用已更改文件的名称。例如,运行ls | entr echo /_将监控当前目录中的每个文件,并在检测到变化时打印出文件的路径。
如果你想了解更多关于 entr 的知识,可以查看主页[这里](https://ls *.rb | entr -r ruby main.rb)。您将找到更多的例子,以及特殊命令行标志的文档。
6.fzf
我将用一个伟大的交互式实用程序来结束这篇文章。Fzf 是一个模糊查找器,允许您从列表中交互式地选择一个选项。它还具有很好的外壳集成和可配置性。
Fzf 可以从几乎所有的包管理器中获得,但是你也可以用 git 安装它(指令在这里)。
默认情况下,运行fzf将为位于当前目录或其子目录中的每个文件显示一个交互式选择器(相当于find .)。这本身就很有用——如果你想交互式地选择一个文件进行编辑,只需运行vim $(fzf)。通过输入搜索词,可以缩小 fzf 提供的选择范围。然后,你可以按<回车>来选择选项。

使用 fzf 选择要编辑的文件
您可以使用 fzf 从任何列表中选择一个项目。使用 fzf,您可以轻松地编写 shell 脚本,以交互方式检查 git 提交、选择要终止的进程、选择要安装的包等。可能性是无穷的,你可以在网上找到很多有用的脚本。
下面显示了来自 fzf 示例 wiki 的fcoc脚本。

使用 fzf 检验 git 提交
更不用说,fzf 还有许多更高级的特性,比如命令的 shell 完成、预览窗口、vim/tmux 集成等等。关于这些信息,我建议通读该项目的 Github。
Git 仓库
https://github.com/schollz/croc https://github.com/ajeetdsouza/zoxide https://github.com/htop-dev/htop https://github.com/eradman/entr https://github.com/junegunn/fzf
结论
不要小看终端!命令行是一些最简单但最有用的工具的家园!
如何利用零方数据获得更深刻的见解
原文:https://towardsdatascience.com/how-to-leverage-zero-party-data-for-greater-insights-f4de0e2801d6
用一个简单的 Python 演示。

在 Unsplash 上拍摄的 ThisisEngineering RAEng
第三方数据是推动现代营销和分析的最重要的燃料。它是来自公司外部的数据,无论是来自客户、供应商还是其他来源。
这对于清楚地了解您的业务表现以及如何改进非常重要。无论你何时访问一个应用程序,从跟踪 cookies 到社交媒体登录,这些数据通常都会在后台自动收集。
但在当今数据驱动的世界中,另一种类型的数据变得越来越重要:零方数据。零方数据由 Forrester Research 创造,是客户“有意和主动与品牌分享”的数据
在本文中,我们将讨论为什么零方数据很重要,并通过 Python 中的一个示例演示如何使用它来提高机器学习模型的准确性。
为什么零方数据很重要
“数据是新的石油”这句老生常谈的话今天仍然适用。你拥有的数据越多,你就能更好地洞察你的业务和客户。零方数据是一个有价值的信息来源。
零方数据的优势之一是它总是最新的。它总是最新的,因为客户自愿与您共享它。这与第三方数据形成对比,如果不定期更新,第三方数据可能会过时(甚至被欺诈性地收集)。
零派对数据的另一个优势是它更加个人化和相关。因为客户是自愿分享的,所以更有可能与他们的兴趣和需求相关。这与第三方数据形成对比,第三方数据可能与您的客户不太相关,甚至无关。
数量与机器学习的准确性相关
不仅如此,你有越多的数据来推动机器学习算法,它们就能更好地工作。虽然这种并不总是的情况,但今天最先进的模型,从 OpenAI 的 GPT-3 到悟道 2.0,都依赖于惊人的数据量。
机器学习对企业越来越重要,因为它可以帮助你自动化客户细分和线索评分等任务。
但重要的不仅仅是数量。数据的质量也很重要。这是零方数据的亮点,因为它比第三方数据更有可能是高质量的。
如何获得零方数据
现在你知道了为什么零方数据如此重要,那么你该如何着手获取它呢?这里有一些建议。
向你的顾客索要。
获得零方数据的最好方法之一就是直接向你的客户索要。您可以通过多种方式做到这一点,例如通过调查或要求他们与您分享联系信息。
传统的方式是通过弹窗“询问”,甚至是隐性的批准进行用户追踪。虽然第三方数据收集工具运行从脸书像素到 Hotjar 到 Mixpanel 的色域,但零方数据收集是较新的。有了 involve.me 这样的工具,就可以通过小测验、调查、计算器等形式获得零方数据。
为分享提供奖励。
另一种获得零方数据的方法是提供激励让客户与你分享。这可以是折扣、奖励或其他特别优惠的形式。
实用指南:用零方数据构建预测模型
既然您已经理解了零方数据的重要性,那么您实际上如何将它合并到您的预测建模中呢?让我们看一个 Python 中的简单例子,比较和对比使用零方数据和传统数据的结果。
我们将使用银行客户调查—定期存款营销数据集,这是一个 UCI ML 数据集,包含银行电话营销数据,如年龄、工作、婚姻状况、教育、余额、住房和个人贷款状况。目标是预测客户是否会认购定期存款。
第一步是导入必要的库。
import pandas as pd
import numpy as np
import sklearn
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import MinMaxScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
现在,让我们导入数据集。
df = pd.read_csv('bank_customer_survey.csv')
由于我们的数据集充满了非数值,让我们对其进行编码。
df['y'] = df['y'].astype(int)
df = df.apply(LabelEncoder().fit_transform)
首先,我们将使用通用的、预先包含的第三方数据构建一个模型。
X = df # our input data
y = pd.DataFrame(X.pop(‘y’))X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
scaler = MinMaxScaler()X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
logreg = LogisticRegression()logreg.fit(X_train, y_train)print(‘Accuracy of Logistic regression classifier on training set: {:.2f}’.format(logreg.score(X_train, y_train)))
print(‘Accuracy of Logistic regression classifier on test set: {:.2f}’.format(logreg.score(X_test, y_test)))
我们得到以下输出:
Accuracy of Logistic regression classifier on training set: 0.89
Accuracy of Logistic regression classifier on test set: 0.89
换句话说,我们可以使用逻辑回归分类器以 89%的准确率预测客户是否会订阅定期存款。
现在,在添加了一些零方数据之后,是时候构建相同的模型了。出于演示目的,我制作了一个综合专栏,向客户提出一个调查问题,并给出一个自愿回答(零方数据的示例):
“未来 5 年要不要买房?”
我们可以伪随机地将我们的合成列添加到数据框架中,其中“是”的答案与购买定期存款相关联,这在现实世界的数据中可能会发生。
dfNo = df[df['y']==0]
dfYes = df[df['y']==1]lstYes = [0,1,1,1,1]
dfYes[“Do you want to buy a house in the next 5 years?”] = np.random.choice(lstYes, size=len(dfYes))lstNo = [0,0,0,0,1]
dfNo[“Do you want to buy a house in the next 5 years?”] = np.random.choice(lstNo, size=len(dfNo))dfZeroPartyData = dfNo.append(dfYes)
现在,让我们重建我们的模型。
X = dfZeroPartyData # our input data
y = pd.DataFrame(X.pop(‘y’))X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
scaler = MinMaxScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)logreg = LogisticRegression()
logreg.fit(X_train, y_train)print(‘Accuracy of Logistic regression classifier on training set: {:.2f}’.format(logreg.score(X_train, y_train)))
print(‘Accuracy of Logistic regression classifier on test set: {:.2f}’.format(logreg.score(X_test, y_test)))
我们得到以下输出:
Accuracy of Logistic regression classifier on training set: 0.92
Accuracy of Logistic regression classifier on test set: 0.92
换句话说,我们使用逻辑回归分类器以 92%的准确率预测了客户是否会订阅定期存款。通过添加零方数据,我们将准确率提高了 3%。鉴于数据生成的随机性,您可能会得到不同的结果。
当然,这只是一个使用合成数据的演示示例,但这些好处每天都在现实世界中实现,企业使用零方数据或客户有意和主动与品牌分享的数据来建立更好的模型。
代码
请参见这个 Google Colab 文件获取完整代码,并在评论中随意提出任何问题!
发现数据失真
原文:https://towardsdatascience.com/how-to-lie-with-data-c58df403bdce

艾萨克·史密斯在 Unsplash 上拍摄的照片
批判性评估图表和数字的演练
介绍
数据分析团队的目标是帮助他们的组织基于数据和见解做出业务决策。
经过几个月的艰苦工作,通过稳健设计的数据管道收集了跨多个部门的组织数据,然后小心翼翼地将它们存储在精心设计的数据库中,您的数据分析师现在终于可以分析它们了,希望发现的任何见解都可以促使管理层做出一些突破性的决策,并帮助组织实现其业务目标。
反正就是这个愿景。
然而,我们(数据分析师)想要传达的和他们(观众)最终得到的是两回事。
有时,这种错位可能是有意的。但更多的时候,它们是偶然的。
这篇文章旨在成为一系列文章中的第一篇,这些文章强调了一个人在展示数据时可能“误导”他人的方式(无论是无意的还是其他的),以及受众在解释数据时可以做得更好的方式(通过意识到这是如何做到的)。
这背后的大部分灵感来自丹尼尔·J·莱维汀的作品,他的书《谎言实地指南》[1]中,作者通过大量的数据误报案例以及如何做到这一点。这本书,以及我在研究这个主题时发现的许多其他后续资源,构成了本文和后续文章中将要分享的内容的基础。
现在,我们将把重点放在人们可以摆弄图表的最明显的方式上——它的轴。
玩斧子
我想不言而喻,当一个人拿到图表时,他首先应该看的是坐标轴和图例。
轴为用户将数据点与值相关联提供了重要的参考信息,尤其是当数据点没有在图表中直接标记时。— [4]
在这一节中,我们将探讨一些技术,这些技术可以用来误导他人如何通过摆弄轴来解释数据。
1。未标记图表/坐标轴
如前所述,如果没有任何标签或轴,读者将很难联想或比较呈现的图表。
为了开始我们对数据虚假陈述的研究,考虑下面一个假设的公司— ACME 的例子:

ACME 的市场份额(图片由作者提供)
在上图中,我们可以看到,与市场上的其他公司相比,ACME 拥有 56%的最大市场份额。
但是差别到底有多大呢?
标签的缺失——在本例中是 Y 轴——使得读者无法理解 ACME 相对于其竞争对手的优势有多大。
2.截断轴
如前所述,Y 轴通常用来显示事物在 X 轴上变化的幅度(通常是时间,或者一些类别)。
然而,为了额外强调 Y 轴上的增加或减少(例如,目的可能是强调在某人的领导下事情有了多大的改善),可以选择通过截断 Y 轴来改变它们(即。通过移除一部分 Y 值直到与我们相关的点)。
考虑下面的图表。


两张图表都显示了不同时间段的销售数字。然而,左边的更讨人喜欢。(图片由作者提供)
这两个图表都是使用相同的数据集创建的,其中绘制了一家公司在 2008 年至 2013 年期间的销售数据。
然而,左边的这个看起来更讨人喜欢——因为随着时间的推移,它显示出一条漂亮的上升曲线。与此同时,右边的图表显示,随着时间的推移,没有发生太大的变化——基本上没有任何进展。
怎么会这样呢?
不同之处在于 Y 轴的设置方式。放大的那个(通过截断 Y 轴)放大了 2.299B 到 2.300B 之间的值,因此从一个不经意的观察者的角度来看,随着时间的推移,改进似乎是显著的。
右边的图表从 0 开始,到 2.5 亿结束,因为对于这种规模的企业(即数十亿)——以每年 10,000 件的增量进行销售可能是我们不想宣扬的事情。然而——这是实际上需要发送给管理层的信息。
那么我们需要总是确保我们看到的任何图表的 Y 轴都固定在 0 吗?
在[7]中,塞思·朗认为这要视情况而定。根据具体情况,微小的差异实际上可能会产生重大影响,并且可能需要数据分析师在 Y 轴上放大,以便向受众清楚地表明,随着时间的推移,情况确实发生了变化。
考虑下面的例子,我们有两个图表描述了一个虚构国家的隔夜政策利率(OPR)。左边的是 Y 轴被截断,而右边的是 Y 轴从 0 开始。


一个虚构国家的隔夜政策利率。左边的图表截断了 Y 轴。右边的图表有一个完整的 Y 轴。(图片由作者提供)
在这种情况下,利率值的微小差异可能会转化为每月贷款/融资付款的巨大差异,我们可以清楚地看到左侧的图表更受欢迎,因为它清晰地展示了利率随时间的差异(与右侧相反)。
3.轴中数据的不连续性
在我们之前的例子中,我们展示了我们可以通过有选择地放大销售数字的 Y 轴来误导观众,以强调我们试图强调的价值。

通过使用不连续的 Y 轴,对销售收入进行另一种尝试。(图片由作者提供)
现在,让我们使用前面示例中的相同销售数据。从前面的教训中,我们知道一个更有说服力的图表应该从 Y 轴的 0 开始。
然而,我们上面的新图表没有在 Y 轴上使用相同的刻度,而是在刻度中引入了一个不连续点,在 2.3B 标记开始的每个刻度处使用 5000,而不是在每个刻度处表示 100 米。
通过这样做,我们现在能够(向不经意的观察者)证明我们的销售数字随着时间呈指数增长。
真是厚颜无耻。
4.双 Y 轴
双 Y 轴本质上是一种在同一图表上绘制两组观察值的绘图技术。这种技术的危险在于,如果分析师为了证明一个观点而调整轴线(或者让它完全消失),它可能会误导观众。
让我们考虑一个例子。现在是 2017 年,假设我们需要根据即将到来的 2018 年业务计划的预测销售收入来证明我们的营销费用。


(左):营销支出似乎高于收入。(右图):收入似乎高于营销支出。(图片由作者提供)
在上面的图表中,我们现有的困境描绘在左边;我们的预计营销支出远远高于我们的预计收入。当描绘在同一个 Y 轴上时,可以立即看出差异。事情看起来对我们不太有利。
在右图中,我们引入了另一个 Y 轴来表示我们的收入数字。这样,我们的收入数字终于出现在我们的营销支出之上。我们的商业计划现在“看起来”比以前更加坚实。
一个更极端的、真实的例子,关于人们如何试图逃避玩双 Y 轴可以参考[8],其中代表 Jason Chaffetz 试图指出,计划生育(一个非政府组织)在 7 年期间增加了堕胎数量,减少了癌症筛查和预防服务。最初的图表似乎支持他的观点,如果不是因为数字线本身不应该交叉,如果绘制在相同的 Y 轴上的话。
不过,返回到双 Y 轴——在构建图表时,这种技术本身并不令人不快(在某些情况下,它确实有它的用途)。然而,在应用它时,需要注意不要误导观众。
5.累积的
现在是 2018 年底(在我们的假设故事中),我们未能达到我们的收入目标。我们的经理完全无视我们的收入数字,安排了一次市场简报会,我们将在会上向市场分析师和投资者简要介绍公司今年的表现。
让我们试着深入挖掘我们的月销售收入。

我公司 2018 年月度营收。(图片由作者提供)
以上表明,我们在 2018 年上半年一直做得相对较好,但自 2018 年 8 月以来走下坡路。对我们产品的需求急剧下降,而且没有回升的迹象,这肯定会吓坏市场、投资者和我们未来的客户。
我们如何描绘一幅更积极的画面,并改变叙事?
输入累积图。

月收入累积图。(图片由作者提供)
虽然上图仍然显示收入增长率在下降,但对于普通观众来说,我们的销售收入确实在增加。总而言之,积极的一面!
事实上,这种方法正是苹果公司[2]在 2013 年的演示中使用过的。在那次演讲中,蒂姆·库克展示了一段时间内 iPhone 的累计销量——从一个不经意的观察者的角度来看,这似乎表明苹果一切都很顺利。然而,分析每个季度的数据显示了一个不同的故事,iPhone 的销售在过去几个季度实际上一直停滞不前。
摘要
在本文中,我们通过几个例子说明了如何通过摆弄图表的坐标轴来歪曲数据。
我们涵盖了:
- 未标记图表/坐标轴
- 截断轴
- 轴中数据的不连续性
- 双 Y 轴
- 累积的
有些技术非常明显,很容易被发现。其他的(如双 Y 轴)对于未受过训练的人和不习惯定期阅读图表的人来说可能需要一段时间才能理解。
这篇文章背后的想法,如果还不明显的话,就是不鼓励数据失实。更确切地说,写这篇文章是希望我们能更好地了解数据和图表是如何适应演讲者的叙述的。
请记住,误传往往是偶然的。虽然有时,他们可能是故意的。
理解了这一点,我们就能更好地解读任何对我们有利的图表。希望我们现在能更好地质疑我们在图表中看到的东西,而不是图表中实际显示的东西。
参考
[1]https://www . Amazon . com/Field-Guide-Lies-Critical-Information/DP/1524702528
[2]https://www . tech junkie . com/Tim-cook-trying-prove-needness-chart/
[3]https://www . calling bullshit . org/tools/tools _ missinging _ axes . html
[4]https://xd gov . github . io/data-design-standards/components/axes
[6]https://www.heap.io/blog/how-to-lie-with-data-visualization
[8]https://www . vox . com/2015/9/29/9417845/planned-parenthood-terrible-chart
绝对初学者如何用 Python 做数据库连接
连接 MS SQL Server、MySQL、Oracle 和许多其他数据库的 3 个步骤(+示例)

连接时间(图片由马库斯·乌尔本斯在 Unsplash 上拍摄)
使用 Python,我们可以自动编写和执行 SQL。但是要做到这一点,我们需要 Python 能够与数据库通信。在本文中,我们将重点关注使用名为pyodbc的包,通过 ODBC 协议与关系数据库进行通信。阅读完本文后,你将能够在你的 Python 应用程序中编写和执行 SQL。我们来编码吧!
在开始之前…
让我们定义一下这篇文章的范围。
Postgres 用户?
有许多数据库符合 ODBC 和 pyodbc,在本文中我们将使用 MS SQL。如果您正在使用 PostgreSQL,那么请查看下面的文章,了解更优化的方法。
生成 SQL 查询
本文重点介绍如何使用 pyodbc 创建与数据库的连接。然后可以使用这个连接来执行 SQL。有些数据库使用不同的语法:
- MS SQL Server
SELECT TOP 1 colname FROM tablename LIMIT 10 - PostgreSQLT2
。
这意味着您必须为特定的数据库编写 SQL 语句。
有一种与数据库无关的方法,可以用更 Pythonic 化的方式定义查询,然后针对某个数据库进行编译。这将为那个数据库生成特定的 SQL,这样您就不会受限于您当前使用的数据库的特定内容。这意味着,如果你将来决定从 MySQL 转换到 Postgres,你不必修改你的代码。
我正在写这篇文章,所以请务必关注我!
关于 pyodbc 和 odbc 协议
关于我们正在使用的软件包及其工作原理的一些背景知识。Pyodbc 是一个允许您与(关系)数据库通信的包。它使用的开放式数据库通信的协议。这个协议定义了客户端(就像您的 Python 脚本)和数据库如何通信。
您可以将这种通信协议与 HTTP 协议进行比较,HTTP 协议有助于计算机之间通过 internet 进行通信:客户端知道如何请求资源,服务器知道如何响应,客户端知道响应是什么样的,因此它们可以使用这些信息。同样,客户端可以使用 ODBC 协议与数据库通信。
连接到数据库—代码部分
我们将经历几个简单的步骤。我们需要使用我们的凭证来创建一个连接字符串。用那根线我们可以建立联系。在连接上,您可以创建一个我们将用来执行查询的游标。首先做一些准备:
准备:依赖性
首先,让我们创建一个虚拟环境,并安装我们唯一的依赖项。
pip install pyodbc
第一步。收集我们的凭证
这是我们检索数据库凭证的地方。在下面的例子中,我们尽可能以最安全的方式处理我们的凭证:我们从环境中加载它们,这样我们的应用程序就可以访问它们,而无需将它们硬编码到我们的脚本中。
import pyodbc
driver: str = 'ODBC Driver 17 for SQL Server'
username = os.environ.get("SQLSERVER_USER")
password = os.environ.get("SQLSERVER_PASS")
host = os.environ.get("SQLSERVER_HOST")
port = os.environ.get("SQLSERVER_PORT")
database = os.environ.get("SQLSERVER_DB")
通过学习如何应用下面文章中的env files来防止您的密码泄露:
第二步。创建连接字符串
Pyodbc 需要一个包含我们的凭据的格式化字符串来连接到数据库。在下面的例子中,我们使用 f 字符串来创建连接字符串,同时保持代码的整洁。
password = "}}".join(password.split("}"))
constring = f"DRIVER={driver};" \
f"SERVER={host};" \
f"DATABASE={database};" \
f"UID={username};" \
f"PWD={{{password}}};" \
f"port={port};"
修复密码…
password发生了一些诡异的事情。首先,我们将密码中的所有}花括号折叠起来,然后我们再次用花括号将它括起来。这是因为密码可能包含一些奇怪的字符,例如/\{};。用花括号把它们括起来可以避免所有的错误。我们不希望我们的密码中的任何花括号被转义,所以我们将它们加倍,以便“避免转义”。
有点奇怪,但这显然是它的工作方式。还要注意,这不仅适用于密码,也适用于任何参数,所以如果您的用户名包含特殊字符,您也可以使用这种技术。
产生的连接字符串如下所示(注意,my_}password现在被正确地翻译成了{my_}}password})。
DRIVER=ODBC Driver 17 for SQL Server;SERVER=my_host;DATABASE=my_database;UID=my_username;PWD={my_}}password};port=my_port;
第三步。连接
这是最简单的部分,我们将创建一个连接(通常每个应用程序有一个连接)。然后我们在连接上创建一个光标。游标用于迭代查询产生的结果集。处理完结果集后,关闭光标。
cnxn:pyodbc.Connection = pyodbc.connect(constring)cursor:pyodbc.Cursor = cnxn.cursor()
try:
cursor.execute("SELECT @@VERSION")
print(cursor.fetchone())
except Exception as e:
print(f"Connection could not be established: {e}")
finally:
cursor.close()
接下来,我们可以使用光标执行一些 SQL,在本例中,我们打印出 SQL Server 数据库的版本。如果有任何失败,我们打印出错误,并且在任何情况下,我们关闭我们的光标。
有一种更短、更好的方法可以做到这一点:
with cnxn.cursor() as cursor:
try:
cursor.execute("SELECT @@VERSION")
print(cursor.fetchone())
except Exception as e:
print(f"Connection could not be established: {e}")
使用上下文管理器(with部分)会使光标自动关闭。此外,它将提交(您必须commit插入;看下面的例子)你在try块中执行的任何东西。如果它检测到错误,它将回滚所有查询。请注意,这仅适用于使用autocommit=False(默认设置)创建连接的情况。
额外收获:示例查询
这里有一些示例查询可以帮助您。
查询 1:选择记录
使用cursor.fetchone()检索单个行。
with cnxn.cursor() as cursor:
cursor.execute("SELECT * FROM INFORMATION_SCHEMA.TABLES")
for row in cursor.fetchall():
print(row)
查询 2:选择记录;转换为字典列表,其中每个字典为一行
with cnxn.cursor() as cursor:
cursor.execute("SELECT * FROM INFORMATION_SCHEMA.TABLES")
colnames = [col[0] for col in cursor.description]
coltypes = [col[1] for col in cursor.description]
for rowvalues in cursor.fetchall():
# convert types
rowvalues = [coltypes[i](rowvalues[i]) for i in range(len(coltypes))]
# make dicts from the colnames and rowvalues
row = dict(zip(colnames, rowvalues))
print(row)
查询 3:常规插入
因为我们在上下文管理器块中(即with),所以如果没有错误发生,执行将被提交。光标也会自动关闭。
with cnxn.cursor() as cursor:
cursor.execute("INSERT INTO med.mytable (name, age) VALUES (?,?)", "mike", 32)
[## SQL —在一条语句中插入、删除和更新:用 MERGE 同步表
towardsdatascience.com](/sql-insert-delete-and-update-in-one-statement-sync-your-tables-with-merge-14814215d32c)
查询 4:回滚插入
前两个被插入,然后#3 失败,所以#1 和# 2 再次回滚。数据库里不会有 a 先生,b 先生,c 先生的踪迹。
with cnxn.cursor() as cursor:
cursor.execute("INSERT INTO med.mytable (name, age) VALUES (?,?)", "mr. a", 44)
cursor.execute("INSERT INTO med.mytable (name, age) VALUES (?,?)", "mr. b", 33)
cursor.execute("INSERT INTO med.mytable (name, age) VALUES (?,?)", "mr. c", 55, "toomany")
查询 5:超快速插入
上面的插入将一次插入一行。使用下面的选项,我们可以为多行创建一条语句,从而大大提高插入速度。
with cnxn.cursor() as cursor:
cursor.fast_executemany = True
SQL = "INSERT INTO med.mytable (name, age) VALUES (?,?)"
values = [
('mr. y', 21),
('mr. x', 98)
]
cursor.executemany(SQL, values)
阅读下面的文章,了解fast_executemany的内部工作原理。
重要的
为了防止 SQL 注入攻击,一定要清理放入 SQL 语句中的变量,尤其是在允许用户输入语句的情况下。这一点被 这部 XKCD 著名漫画 诠释得很漂亮。
后续步骤
现在您的脚本可以连接到数据库了,您可以开始编写 SQL 了。比如你可以用 5 行代码 做一个 API。通过这种方式,您可以为用户提供对数据库的受控访问,定义用户可以请求哪些信息。
请务必查看 此链接 以获得许多有用查询的详细概述。最后,下面的文章详细介绍了如何实现数据库迁移。这使得以编程方式设计和版本控制数据库成为可能。
结论
我希望已经阐明了如何用 pyodbc 连接到您的数据库,并使用它来执行一些 SQL。我希望一切都像我希望的那样清楚,但如果不是这样,请让我知道我能做些什么来进一步澄清。与此同时,请查看我的关于各种编程相关主题的其他文章:
- 面向绝对初学者的 cy thon——通过简单的两步将代码速度提高 30 倍
- Python 为什么这么慢,如何加速
- Git 绝对初学者:借助视频游戏理解 Git
- Docker 对于绝对初学者——Docker 是什么以及如何使用它(+例子)
- 绝对初学者的虚拟环境——什么是虚拟环境,如何创建虚拟环境(+示例
- 创建并发布你自己的 Python 包
- 用 FastAPI 用 5 行代码创建一个快速自动记录、可维护且易于使用的 Python API
编码快乐!
—迈克
附注:喜欢我正在做的事吗? 跟我来!
898

被折叠的 条评论
为什么被折叠?



