为谷歌铺路!
我从许多数据科学访谈中学到的经验
Photo by Paweł Czerwiński on Unsplash
有一个时候你应该换一份工作,不管这个文化有多牛逼,这个公司有多神奇,那就是你停止成长的时候。
当我的时间到了,我采访了东西海岸的许多组织。从金融机构到科技巨头,从纽约和华盛顿特区到西雅图和旧金山,我乐于接受新的冒险。与此同时,在每一步和每一次面试结束时,我都在思考,作为一名候选人,我和面试团队本可以做得更好。
你将要读到的并不是如何找到下一份工作的路线图,而更像是我对整个过程的回忆。
我要讲的大部分内容已经在 LinkedIn 上发表了。我知道很多人已经在经历或即将开始我几个月前刚走完的路,我希望我关于寻找合适的公司、处理拒绝、准备面试等的笔记。让他们的旅程比我的更精彩。
以下是我讨论的主题列表:
- 这不是容易但它是值得它。
- 求职与网上约会
- 我评价一个职位的标准!
- 你如何帮助公司找到你?
- 终极面试技巧:忘记解决方案,建立系统!
- 成为数据科学家的技能:我的看法
- 我准备技术面试的系统
- 非技术性面试技巧
- 致我所有经历拒绝的朋友们!
- 排斥后处方
- 想被录用吗?努力提高你的技能!想要升职吗?学习机构知识!
- 给面试官:在候选人的舒适区见他们!
不容易但是值得它!
招聘人员的电子邮件、介绍电话、技术问题、周末项目、现场参观、拒绝信、谈判等等似乎是一个永无止境的过程;一个我反复重复的循环。
这个过程令人筋疲力尽,但最后,至少对我来说,是值得的,值得努力。我学到了很多东西,坦率地说,在这个过程中,我成为了一名更好的数据科学家。采访不同行业、不同规模和不同地点的公司,讨论他们想要雇佣你的各种令人兴奋的问题,是令人大开眼界的。每次面试都让我对需求、挑战和期望有了更好的认识,从而帮助我为下一次面试做准备。
求职 vs 网恋!
在我看来
找工作很像网上约会;单身的人很多,但匹配的人太少。你的工作不是和第一个和你约会的人结婚,而是找到一个有共同兴趣和长远前景的人。
我评价一个职位的标准!
你挑选未来组织的标准是什么?品牌、地点、薪酬待遇、工作描述、你将参与的项目,甚至是津贴和福利以及弹性工作时间;哪个因素最重要?如果你在不同的公司有多种选择,你会选择什么,为什么?以下是我的观点:
- 很少有人能对你的生活质量产生长期影响:你的生活伴侣、你的顾问、经理和你的同事。确保你明智地选择它们,这能让你的生活更加有趣和充实!
说到事业,我从来不后悔优先考虑人而不是项目/公司/大学。他们可以成就或毁灭你和你的未来;他们可以鼓励/阻止你前进的每一步;它们会成为你个人或职业成长的主要力量,或者成为你实现目标的主要障碍。
我的下一次职业生涯也不例外。试图找到合适的团队加入是当务之急。 - 职责
通过与招聘团队的交谈,我想知道我是否对这个角色和职责感兴趣。有一次我面试了一家票务领域的公司,那里的整个团队都对体育赛事充满热情。对于不喜欢运动的我来说,这显然不是一个正确的选择。
不要仅仅依赖职位描述,因为它只会给你一个关于这个角色的想法。尤其是对于那些在招聘数据科学家方面经验不足的公司来说,工作描述中的要求对于他们招聘的职位来说可能不是必需的。 - 成长机会
未来的公司是否鼓励学习/提高技能并为其提供工具?如果我想转岗,我能在同一个组织中找到新的职业机会吗?我能很容易地找到并联系到导师吗? - 职业道路
我所考虑的职位与我未来 3-5 年的目标有多一致。我用这个原则拒绝了几个在经济上有意义但与我的长期目标不一致的提议。 - 薪酬方案
现在很重要,将来也永远重要。但不是最重要的因素。金钱和财务健康是努力工作和影响力的结果,如果你找到一个鼓励学习、支持成长和奖励努力工作的组织,你就不用担心其他的了!
如何帮助公司找到你?
考虑以下事实:
- 2019 年 5 月开业 730 万,
- 由于科技的发展,任何人只需点击一下鼠标就可以申请任何职位,
- 然而,63%的招聘人员认为人才短缺是他们最大的问题。
这就是为什么你需要成为自己的倡导者&帮助公司将信号从噪音中分离出来。事实是,没有人比你更了解你的目标和抱负,在你的简历上列出一系列的技能和项目是不公平的。
如果你想增加被合适的职位和合适的公司聘用的机会,这里有一些方法可以尝试:
- 你的 LinkedIn 个人资料就像你的储蓄账户。即使你睡着了,它也对你有效。保持更新,使用正确的关键词,让访问者容易找到你的相关信息。记住,87%的招聘人员使用 LinkedIn 来检查候选人。
- 你的关系网
他们是你的关系网,这是有原因的。一个引荐可以让你的机会增加 5 倍,所以给他们发信息,恭敬地请求引荐、指导、建议等。每个连接尝试两次后停止。你有更重要的事情要做。 - 冷邮件:
我是这样做的:在 LinkedIn 上找到&申请合适的职位。如果招聘人员列在工作页面上,我会给他们发一条消息(评论中的示例)。
我用来发冷邮件的一封信的样本:
你好[…],
在阅读[…]的职位描述时,我发现我目前的职责和职位描述有很大的重叠。请允许我详细说明:
在过去的几年里,我
—在[…]、
工作过—在[…]、
—定义和衡量产品指标、
—熟悉[…]
—训练有素的机器学习模型、
—准备[…]分析、
—与业务团队广泛合作、
—构建分析仪表板。
我申请了这个职位[工作 ID 在这里],我希望你能考虑我的申请。
最佳
你的名字,
目前的头衔
终极面试技巧:忘掉解决方案,建立系统!
秘诀是要意识到,在大多数面试中,应聘者和面试官寻求的是两种不同的东西:当应聘者专注于解决方案时,面试官寻求的是系统。前者依赖于技术能力,而后者是关于你建立的展示它们的过程。
这个系统是一个循序渐进的过程,你用它来帮助面试官理解你评估和解决问题的方法,并传达你的想法和观点。她感兴趣的不仅仅是正确的答案!如果解决方案是故事,你的系统就是你如何讲述你的故事,它是你知识深度和你沟通能力的最好证明。
作为一个例子,我讨论我的系统来回答一个技术问题,比如一个 SQL 问题:
- 重复这个问题,以及你应该向面试官传达什么,以确保你们双方达成共识。
- 要求一两分钟,考虑解决方案。这不仅给你时间整理你的想法,也给面试官留下了一个积极的印象:你说话之前先思考!
- 向面试官解释你的策略并检查你的假设。比如“假设数据中有缺失值或重复值安全吗”?
- 让面试官参与进来:编写尽可能易读的代码,并在每一步解释你在做什么。
- 检查您的解决方案,并提供如何改进的建议。
- 求反馈!在许多情况下,反馈帮助我改进了代码。有时,它会引发围绕其他可能的问题解决方案的有趣对话。
成为数据科学家的技能:我的观点!
我过去常常问我应该获得什么技能,我应该知道多少才能过渡到数据科学的职业生涯。而且大多数时候答案都不够好!
把你想如何学习它们留给你,以下是我的看法:
- SQL
如果你习惯使用窗口函数,你就可以开始了! - 统计学
你可以计算置信区间,设计实验,解释 p 值。你熟悉方差分析,并且理解线性回归背后的假设。 - Python
编写简单的代码来处理字符串,理解 Numpy 库,变得足够好,可以用 Pandas 处理大型数据集,用 Matplotlib 可视化结果。 - 机器学习
你很好地理解了基础知识:从偏差-方差权衡,参数和非参数算法之间的差异,分类与回归模型,到过采样和欠采样方法,等等。你了解传统算法是如何工作的:从线性回归和 SVM 到集成方法。你至少精通两种算法,如逻辑回归和随机森林。您了解评估您的模型的不同指标,以及如何针对您的问题选择正确的指标。
我准备技术面试的系统
- 20 分钟
我阅读了职位描述,强调了关键点,并思考了我的经历是如何关联的。这看起来可能不是技术问题,但是这部分给出了技术问题的背景。 - 30 分钟
通过与招聘人员的初步交谈,我试图弄清楚我应该期待哪种类型的技术面试。 - 30 分钟
我在网上搜索公司,如果可能的话,搜索他们正在招聘的部门,思考他们正在努力解决的项目和问题。如果对这个领域不熟悉,我会花几分钟研究这个领域。 - 10-15 分钟
我在 LinkedIn 上查看了面试官(如果有的话),以了解她的专业知识。有趣的是,出于某种原因,我越少这样做,或者基本上我越不在乎谁面试我,我在实际面试中做得越好。 - 45–60 分钟
我在 Glassdoor 和其他一些网站上查看了该公司的面试问题。如果是电话面试,我只复习了电话面试问题之类的。 - 60–120 分钟
根据面试情况,我复习了我的 SQL/Python/统计学/机器学习笔记(我会在不久的将来分享)。
面试非技术性提示
- 表现得像个话题专家,而不是求职者!
把面试当成一次谈话,把面试官当成你的同事。将问题与你过去的经历联系起来,讲一个故事,让面试官参与进来,问她这样的问题:你/你的公司会如何处理这种情况? - 我意识到下班后的晚上对我来说更好。自己想办法。
- 你很有可能和许多面试官一样合格。谦虚但自信。
- 如果你在技术上做好了准备(假设你的技能符合工作要求),数据科学面试很容易!你练习得越多,准备得越充分。
- 不要担心被拒绝:你几乎总是会有第二次机会(过一段时间),同时,还有许多其他伟大的公司。
- 你已经被告知无数次了,但是请记住,你还要面试公司代表。一些你现在没有问或没有注意到的事情,以后会成为一个大问题。
- 把对你最关心的公司的面试留到最后,这样你就有足够的时间从过去的错误中学习和改正。
致我所有遭遇拒绝的朋友
我感受到你的痛苦和沮丧!几周前我经历了同样的过程,我被许多公司拒绝了。面对挫折时,我们通常会责怪自己不够好。然而,至少对我认识的大多数人来说,这与事实相差甚远。通过多次采访(有一段时间似乎没完没了),我意识到我最大的挫败感来自两个公司群体:
- 那些以前没有雇佣数据科学家经验的公司(通常是中小型公司)。在这里你可能会看到最不准确的职位描述,以及一些无关紧要的问题。
- 那些拥有数据科学团队但没有良好的招聘流程的公司。在这里,你可能需要根据面试你的人和面试官正在做的/感兴趣的项目来回答一些非常专业的问题。
不要为你无法控制的事情责备自己!相反,从每一次面试中学习,继续前进,为下一次面试做好准备。有很多公司需要你的才华、激情和努力。你获得的经验越多,你就能更好地应对任何情况。
拒绝处方后
- 你做得很好,但是面试官没有理解你!
- 这些问题令人困惑。它们不是面试类型的问题。
- 我没有得到足够的解释或时间。
- 你不应该被拒绝!
- 等等
你在以上所有方面都是绝对正确的。但仅限于被拒后的前半个小时!前 30 分钟过后,在忘记面试的内容和你表现中可能存在的缺陷之前,从你构思问题的方式、你处理 SQL 问题的方式或者对公司/产品不够熟悉,仔细想想哪里出了问题!把它写下来,确保你处理好它。事实是,在面试中有很多事情可能会搞砸,但没关系!不可以的是两次犯同样的错误!你只是没有时间做这些…
外面有很多很棒的公司,所以如果你搞砸了面试,不要担心!
在早期,我搞砸了一些科技巨头的几次面试,让我陷入绝望。我担心,如果这种情况继续下去,我会失去很多好的选择,并可能不得不在某个对我的职业生涯没有帮助的地方结束。与此同时,我已经在一家大公司找到了一份工作,和一群了不起的人一起工作,在任何情况下我都不想换工作。
一些事情帮助我克服了这种恐惧。例如,在 LinkedIn 上简单地搜索一下,就会发现无数来自伟大但鲜为人知的组织的机会,这些组织拥有有趣的、有时甚至是颠覆性的技术,我们许多人从未听说过。事实是,这个世界并不局限于脸书或谷歌。事实上,有一些超乎你想象的公司拥有健康的文化和支持团队,愿意帮助你成长并成为最好的你。
把你的重要决定,包括承担一个新的角色,建立在你的希望而不是恐惧之上:如果你正在寻找并且还没有找到合适的组织,不要放弃。继续找!
想被录用吗?努力提高你的技能!
想要升职?学习机构知识!
领域知识和机构知识:当我过去的公司的 CEO 鼓励我将拒绝交易作为我加入团队后的第一个项目时,我很失望!刚出学术界,我就希望有一个复杂的项目,比如建立最好的机器学习模型。取而代之的是,我被分配去计算所有交易中被拒绝的比率,以此来简化它。我不知道的是,我的任务即使不是最重要的,也是支付行业最重要的问题之一。
我缺少的不是技术技能。从技术上讲,我可以做任何类型的分析。在 3 个不同的科学领域发表了 14 篇论文,涉及从宇宙学到非线性光学和计算生物化学的各种高要求主题,赢得了多个研究奖项,并在大约一年的时间里致力于我的数据科学技能,我已经准备好做任何事情来展示我的技术能力;要发光!缺失的部分不是数学和统计。这是领域知识和商业头脑!
除了技术能力之外,数据科学家还需要开发其他技能,以便能够识别影响业务的项目,并赋予利益相关者权力,使他们优先于任何其他类型的工作。要达到这一点,即培养商业头脑,两者的共存是必要的;领域知识和机构知识!
领域知识帮助你理解你所在行业的主要概念。另一方面,机构知识关注的是你工作的公司:它的愿景、竞争优势、运营和创收方式、优先事项、历史和未来计划等等。
支付行业的领域知识专家可能会将欺诈和拒绝交易识别为非常重要的问题。机构知识有助于专家根据哪个更符合公司的愿景进行选择。
与你所在领域的专家、你公司的人交谈,订阅时事通讯,阅读公司文件,所有这些都可以帮助你拓展你的领域和机构知识。
仔细听对话,记住名字,掌握反复提到和重复的重要概念。耐心点!
好消息是:我已经意识到,虽然我们是因为技术技能而被聘用的,但让我们不可替代的是制度和领域知识。用一个有更好技术技能的人来替换一个人通常并不困难,但是替换一个对这个领域和她工作的机构非常了解的人就非常困难了。因此,在短期内,你的竞争优势是你的技术技能;从长远来看,你的领域和机构的知识成为一个!
在候选人的舒适区会见他们!
我认为,如果你想看到应聘者的最佳状态,就在他们的舒适区对他们进行评估:这是给面试官的一个建议!
在面试过程中,无论是电话面试还是现场面试,候选人的大脑都在同时处理无数不同的事情。在这种情况下,如果你的判断仅仅基于他们理解与新角色相关的问题和挑战的能力,那么你就没有充分发挥他们的能力来评估他们。
相反,我建议面试的一部分应该专注于进入候选人的舒适区,通过询问关于他们过去工作的详细问题来挑战他们。这确实应该超越通常在面试开始时进行的简短介绍。
这将有助于对候选人的认知和技术能力、他们的思维过程和解决问题的方法、他们如何应对挑战以及他们如何向你展示这些挑战建立一个更全面的了解。
虽然这需要有经验的面试官,但它让面试过程变得公平,并有助于组织吸引可能更适合该职位的申请人。
用 numpy 解释 PCA 和 SVD
主成分分析和奇异值分解到底有什么关系,如何用 numpy 实现?
主成分分析和奇异值分解是探索性数据分析和机器学习中常用的降维方法。它们都是经典的线性降维方法,试图在原始高维数据矩阵中找到特征的线性组合,以构建数据集的有意义的表示。当涉及到降低维度时,它们受到不同领域的青睐:生物学家经常使用 PCA 来分析和可视化来自群体遗传学、转录组学、蛋白质组学和微生物组的数据集中的源差异。与此同时,奇异值分解,尤其是其简化的截断奇异值分解,在自然语言处理领域更受欢迎,以实现对庞大而稀疏的词频矩阵的表示。
人们可以发现从 PCA 和 SVD 得到的表示在某些数据中是相似的。实际上,PCA 和 SVD 是密切相关的。在这篇文章中,我将使用一些线性代数和几行 numpy 代码来说明它们之间的关系。
0.线性代数复习者
让我们首先快速回顾一下线性代数的一些基础知识,因为 PCA 和 SVD 都涉及一些矩阵分解。
- 矩阵转置:重新索引一个二维矩阵 A 来切换行和列索引,有效地用 a_{ji} 替换它的所有元素 a_{ij} 。转置的符号是矩阵上上标的⊤或 ’ 。在 numpy 中,可以调用。T 或。transpose()NP . ndarray 对象的方法来转置一个矩阵。
- 点积与矩阵乘法:两个矩阵A*(n×m)B【m×p】的乘积*=AB两个矩阵可以相乘 n×p. 合成矩阵 C 中的元素 c_{ij} 计算如下:**
Elements in the product matrix of two matrices are the dot products of the corresponding row vectors and column vectors
你可能会意识到,乘积矩阵 C 中的元素分别是矩阵 A 和 B 中对应的行向量和列向量的点积。
- 矩阵求逆:只有方阵才能求逆,一个矩阵a***(n×n)与其逆的乘积a^**(-1)是一个单位矩阵 I ,其中对角线上的元素是 1,其他地方的元素都是 0*
- *共轭转置:定义为共轭矩阵的转置。通常用上标 a 或 H (埃尔米特语)表示。共轭矩阵是通过取原始矩阵中所有元素的复共轭而获得的矩阵:
Conjugate transpose
回想一下复数,一个数由一个实部和一个虚部组成。例如, a + i b 是一个复数,其中 i 是等于-1 的平方根的虚数单位。 a + i b 的复共轭为 a - i b. 由于我们处理的大部分数据集都是实数的矩阵,所以矩阵的共轭转置等价于普通的转置。
- 酉矩阵:定义为共轭转置也是其逆矩阵的方阵。对于酉矩阵,我们有它的转置等于它的逆:
Unitary matrix, where the conjugate transpose equates the matrix inverse
- 协方差矩阵:协方差量化两个随机变量 X 和 Y 之间的联合变异性,计算如下:
Covariance
**协方差矩阵 C 是来自数据矩阵 X (n 个样本× m 个特征)的特征的两两协方差的方阵。从协方差的定义观察,如果两个随机变量都以 0 为中心,则随机变量的期望变成 0 的,协方差可以计算为两个特征向量 x 和 y 的点积。因此,所有要素都居中的数据矩阵的协方差矩阵可计算如下:
Covariance matrix of a 0-centered matrix X
好的,这带来了一些大学线性代数的美好回忆。现在我们来认识一下这个帖子的主角们。
1.主成分分析
PCA 旨在寻找线性不相关的正交轴,这些轴也称为主分量(PC)在 m 维空间中,以将数据点投影到这些 PC 上。第一台 PC 捕获数据中的最大差异。让我们通过将 PCA 拟合到二维数据矩阵上来直观地理解它,二维数据矩阵可以方便地用二维散点图来表示:
Making sense of PCA by fitting on a 2-D dataset (source)
因为所有的 PC 都是相互正交的,所以我们可以使用二维空间中的一对垂直线作为这两个 PC。为了让第一台电脑捕捉到最大的方差,我们旋转了一对电脑,使其中一台电脑与数据点的分布最佳对齐。接下来,可以将所有数据点投影到 PCs 上,它们的投影(PC1 上的红点)本质上是数据集的最终降维表示。Viola,我们刚刚将矩阵从二维减少到一维,同时保留了最大的方差!
PCs 可以通过协方差矩阵 C 的特征分解来确定。毕竟特征分解的几何意义就是通过旋转为 C 找到特征向量的新坐标系。
Eigendecomposition of the covariance matrix C
在上式中,协方差矩阵C***(m×m)分解为一个特征向量矩阵W**(m×m)和一个对角矩阵 m 特征值λ*。特征向量,即 W 中的列向量,实际上就是我们要寻找的 PC。然后,我们可以使用矩阵乘法将数据投影到 PC 空间。出于降维的目的,我们可以将数据点投影到第一个 k 个PC 上作为数据的表示:**
Project data onto the first k PCs
PCA 可以非常容易地实现,因为 numpy 是执行特征分解的关键函数( np.linalg.eig )已经内置:
2.德拉贡诺夫狙击步枪(Snayperskaya Vinyovka Dragunov 的缩写)
*SVD 是实矩阵和复矩阵的另一种分解方法。它将一个矩阵分解成两个酉矩阵( U , V )和一个奇异值的矩形对角矩阵(σ)的乘积:
Illustration of SVD, modified from source.
在大多数情况下,我们处理的是实矩阵 X ,得到的酉矩阵V也将是实矩阵。因此, U 的共轭转置就是简单的正则转置。
SVD 也已经在 numpy 中实现为 np.linalg.svd 。要使用 SVD 转换数据:
3.主成分分析和奇异值分解的关系
PCA 和 SVD 是密切相关的方法,并且都可以应用于分解任何矩形矩阵。我们可以通过对协方差矩阵 C 进行奇异值分解来研究它们的关系:
从上面的推导中,我们注意到结果与 C 的特征值分解形式相同,我们可以很容易地看出奇异值(【σ***)与特征值(λ)之间的关系:***
Relationship between eigenvalue and singular values
要使用 numpy 确认这一点:
那么这意味着什么呢?这表明我们实际上可以使用 SVD 来执行 PCA,反之亦然。事实上,PCA 的大多数实现实际上使用在遮光罩下执行 SVD,而不是对协方差矩阵进行特征分解,因为 SVD 可以更有效,并且能够处理稀疏矩阵。此外,还有简化形式的奇异值分解,计算起来更加经济。
在下一篇文章中,我将深入研究不同 SVD 解算器和实现的复杂性,包括 numpy、scipy 和新开发的自动签名库谷歌 JAX 。
参考资料:
主成分分析:特征向量和特征值
每当你在处理数据的时候,你总是会面对相对的特征。后者是我们在描述数据时考虑的变量。也就是说,如果你正在收集一些关于米兰房屋的数据,典型的特征可能是位置、尺寸、楼层等等。
然而,经常发生的情况是,你的数据提供给你许多功能,有时是数百个…但是你需要全部吗?好吧,记住简约法则,我们宁愿处理一个只有很少特征的数据集:训练起来会容易得多,也快得多。另一方面,我们不希望在删除某些功能时丢失重要信息。
我们如何处理简单性和信息量之间的权衡呢?这个问题的答案是主成分分析(PCA)的结果。
主成分是由初始变量的线性组合构成的新变量。这些组合是以这样的方式完成的,即这些新变量是不相关的,并且初始变量中的大部分信息被存储到第一分量中。因此,这个想法是, k 维数据给你 k 主成分,但是 PCA 试图把最大可能的信息放在第一个主成分中,这样,如果你想减少数据集的维数,你可以把你的分析集中在前几个成分上,而不会遭受信息损失的巨大损失。
在这种分析中,度量信息量的是方差,并且主成分可以在几何上被视为高维数据的方向,其捕捉最大数量的方差并将其投影到较小维度的子空间,同时保留大部分信息。因此,第一主成分占最大可能的方差;第二个分量将直观地说明第二大方差(在一个条件下:它必须与第一个主分量不相关)等等。
为了更深入地理解 PCA,我们需要引入一些进一步的概念。
协方差矩阵
让我们考虑一个场景,其中我们只有两个特征,x 和 y。我们可以在 2D 图中表示我们的数据如下:
现在,我们可以计算所谓的协方差矩阵:它是一个对称的, dxd 矩阵(其中 d 是特征的数量,因此在这种情况下 d =2 ),其中存储了每个特征的方差和交叉特征协方差:
因为 Cov(x,y)等于 Cov(y,x),所以如前所述,矩阵是对称的,并且特征的方差位于主对角线上。
协方差矩阵可以根据数据的形状采用不同的值。让我们检查一些场景:
当两个特征正相关时,协方差大于零,否则,它具有负值。此外,如果没有证据表明它们之间存在相关性,则协方差等于零。
如您所见,协方差矩阵定义了数据的分布(方差)和方向(协方差)。这个矩阵还可以分配两个元素:一个代表向量和一个表示其大小的数。向量将指向数据的较大分布的方向,数字将等于该方向的分布(方差)。这两个元素分别是特征向量和特征值。让我们想象一下:
绿色的方向是特征向量,它有一个对应的值,叫做特征值,特征值描述了它的大小。让我们更详细地看看它是如何工作的。
特征向量和特征值
为了更好地理解这些概念,让我们考虑下面的情况。我们被提供了二维向量 v1,v2,…,vn。然后,如果我们将线性变换 T(一个 2x2 矩阵)应用于我们的向量,我们将获得新的向量,称为 b1,b2,…,bn。
但是,其中的一些(更具体地说,与特征的数量一样多)有一个非常有趣的特性:确实,一旦应用了变换 T,它们会改变长度,但不会改变方向。这些向量称为特征向量,代表特征向量倍数的标量称为特征值。
因此,每个特征向量都有一个对应的特征值。现在,如果我们考虑我们的矩阵σ,并将所有相应的特征向量收集到矩阵 V 中(其中,作为特征向量的列数将等于σ的行数),我们将获得如下结果:
其中 L 是存储所有特征值(与特征向量一样多)的向量。如果我们考虑两个特征(x 和 y)的例子,我们将获得以下结果:
然后,如果我们按照特征值降序排列我们的特征向量,我们将得到第一特征向量占数据中最大的分布,第二特征向量占第二大的分布,等等(在描述新空间的所有这些新方向是独立的,因此彼此正交的条件下)。
现在,如果我们想降低数据集的维度,我们应该怎么做呢?假设我们从 5 个特性开始,我们想要处理 2 个特性。因此,程序如下:
- 计算σ矩阵我们的数据,这将是 5x5
- 计算特征向量矩阵和相应的特征值
- 按降序排列我们的特征向量
- 构建所谓的投影矩阵 W,其中将存储我们想要保留的 k 个特征向量(在本例中,2 是我们想要处理的特征的数量)。因此,在我们的例子中,我们的 W 将是一个 5x2 矩阵(通常,它是一个 dxk 矩阵,其中d=原始特征的数量,k=期望特征的数量)。
- 通过投影矩阵 W 变换原始数据,原始数据可以表示为矩阵 X(其中,n=观察值的数量,而d=特征的数量),从而获得新的数据集或矩阵 Y,其将为 nxk 。
这个新的,转换后的空间 Y 的两列,是我们用来代替原始变量的主要成分。如上所述,它们被构造成存储尽可能多的信息。
PCA 广泛用于机器学习任务:事实上,为了使我们的算法有效,训练过程必须尽可能快,但这并不意味着我们可以在没有特定标准的情况下降低维度,从而有丢失相关信息的风险。
PCA 不是特征选择
它实际上是做什么的,什么时候可以用,什么时候不能用。
几乎没有数据科学家会要求更少的数据,但是维数灾难使得必须采取一些措施来管理数据集中的许多变量。主成分分析(PCA)是一种非常有用的工具,但关于 PCA 有一些常见的误解和/或错误,妨碍了初级数据科学家正确应用它。
PCA 是数据从一个坐标系到另一个坐标系的旋转。新数据科学家犯的一个常见错误是将 PCA 应用于非连续变量。虽然在技术上可以对离散变量或作为热编码变量之一的分类变量使用 PCA,但您不应该这样做。简单地说,如果你的变量不属于一个坐标平面,那么就不要对它们应用 PCA。应用后,在我们的新坐标系中,第一维具有最大的方差,然后第二维具有最大的剩余方差,依此类推。
在相对较小的数据集上,前几个组件可以解释数据集中几乎所有的差异。我见过其他数据科学家错误地认为,这意味着最后几个组件可以忽略不计,前几个组件才是最重要的特性。PCA 是特征选择的有效方法的唯一途径是,如果最重要的变量恰好是那些变化最大的变量。然而,这通常不是真的。作为一个例子,假设您想要对一个 NFL 球队进入季后赛的概率进行建模。NFL 球队的胜利数(0 到 16)比球队的总冲刺码(以千计)更有助于预测进入季后赛的概率,但 PCA 会选择冲刺码作为第一部分的最大贡献者。
有应用 PCA 的好时机。假设我们对调查标准普尔 500 股票的波动性感兴趣。我们可以将 PCA 应用于一个有 500 列(每家公司一列)和 1000 行(每只股票在过去 1000 天的收盘价)的数据集。价格变化大的股票对第一部分的贡献最大。一旦你完成了主成分分析,你现在就有了不相关的变量,它们是旧变量的线性组合。理想情况下,前几个成分可以解释标准普尔 500 中几乎所有的差异。处理这几个变量要比处理 500 个变量(每个公司一个)容易得多。这是一个很好的应用程序,因为每只股票都有相同的标度,也就是说,它们都用美元表示价格。知道什么时候可以,什么时候不可以应用 PCA,对于使用它是必不可少的!
PCA vs TSNE——El clásico
PCA vs TSNE——这场比赛让我们所有人都兴奋不已
Photo by Hermes Rivera on Unsplash
皇家马德里对巴塞罗那的比赛总是让我们兴奋不已。两支球队都很棒,但都有不同的比赛风格。在数据科学领域,我们有自己的 El clásico——PCA vs TSNE。两者都是流行的降维技术。两者都有自己的风格。
有足够多的关于主成分分析和 TSNE 的文献从数学的角度或者从视觉化的角度探讨了两者的区别。在这个故事中,我想用一种数据故事讲述的方法来展示两者的区别。我将举两个例子,一个是电信客户数据集,另一个是漫威复仇者数据集。激动。然后继续读下去
示例 1 —电信数据集的降维
电信公司收集了大量客户信息。客户数据集信息量很大。这里显示了一个这样的样本数据集
Sample Telco dataset
该数据集具有大约 20 个字段,这些字段具有各种信息,例如客户人口统计、订购的服务以及计费费用。它是分类字段和数值字段的混合。
现在让我们在这个数据集上应用两种技术 PCA 和 TSNE,并比较结果
步骤 1 —比较输出
使用这两种技术将维数减少到 2 维的结果如下所示
PCA vs TSNE — comparing the output
看着这些观想,我们可以做一些观察。PCA 形成了两个集群。TSNE 已经形成了三个集群,并且有一些数据点从集群中分离出来。
因此,只要比较两种算法的输出,就会发现一些重要的差异。那么这意味着什么呢?让我们在下一步回答这个问题
步骤 2 —解释集群
为了理解这种差异,我们必须首先解释集群的含义。出于解释的目的,下面给出了每个集群的名称。在 PCA 端,簇的名称是 Cluster0 和 Cluster1。在 t-SNE 端,集群的名称为集群 0、集群 1 和集群 2
Giving some cluster names
一个简单快捷的解释星团的方法是使用雷达图,如图所示。雷达图显示了每个聚类的重要特征(或列)的平均值
Radar chart to interpret cluster
我们观察到
- 对于 PCA,每月费用是集群之间的最大区别
- 对 TSNE 来说,老年人这一特征是集群之间的最大区别
让我们用一些颜色来验证这些观察。我们可以使用月费给 PCA 可视化中的点着色。类似地,用老年公民给 TSNE 观想中的点上色
这证实了我们已经观察到的雷达图。在 PCA 侧,低月费的集群是清楚可识别的。在 TSNE 一侧,一群老年人清晰可见
步骤 3——理解差异
那么,为什么 PCA 选择月费作为主要的差异化领域之一呢?原因是 PCA 是一种数学方法,它试图基于最高方差尽可能地分离点。月费是客户支付的金额,因客户而异
所以 PCA 本质上是通过 分离 点****基于最高变化场。
TSNE 选择了老年人作为重点区分领域之一。原因是 TSNE 是一种概率方法,它试图根据两个接近的点来自相同人口分布的概率来尽可能接近地对点进行分组。因此,一般来说,在现实生活中,老年人也可以被认为是一种类型人群,且他们很有可能表现出消费电信服务的类似行为
所以 TSNE 基本上是通过 分组 点 尽可能接近点的特征
现在,让我们探索另一个基于漫威字符的数据集,并更深入地了解 PCA 和 TSNE 的内部工作
示例 2-漫威字符数据集的降维
漫威给了我们一些很棒的超级英雄电影。幸运的是,它还提供了一个有趣的数据集,这样数据科学家就可以玩了。此处显示了该数据集中的一个样本
Marvel comic character data sample
这个数据集大约有 185 个字段。相当多的领域,你需要一些超级武器来理解这些大量的领域。幸运的是,在主成分分析和 TSNE 方面,我们拥有超级武器,可以进行一些很酷的降维
这里显示的是两种降维技术的输出。
我们可以观察到在 PCA 中有一个可见的簇,而在 TSNE 中没有形成簇。TSNE 没有任何集群的原因是因为所有的超级英雄都是非常不同的,并且没有相似的超级英雄的潜在群体。超级英雄是独一无二的。没有钢铁侠 100 的人口。只有一个铁人。
所以一个超级英雄和另一个超级英雄很接近的可能性很小。用数据科学术语来说,数据非常稀疏。当数据非常稀疏时,TSNE 不会形成任何聚类
为了解释 PCA 聚类,我们可以通过功率来给点着色,功率是变化最大的场。对 TSNE 来说,因为没有星团形成,所以给点着色没有意义。分析 TSNE 输出的唯一方法是用漫威角色的名字标记一些点,以便做出一些解释
在 PCA 输出中,我们看到该簇具有中低功率的字符。随着我们越走越远,角色的力量越来越大。
在 TSNE,没有群集,但我们可以分析一些字符之间的密切程度。我们可以看到洛基和灭霸很接近。这可能是因为它们在数据集中代表了一种邪恶的对齐方式。同样,冬季士兵和美国队长也很接近。这是因为他们有相似的军队背景和相似的性格。火箭浣熊和黑豹也是如此,它们具有相似的动物特征和力量
基于这个数据集,我们可以做一个更重要的观察
只有当人口分布中有足够的点时(意味着当数据不稀疏时),TSNE 才会形成聚类。然而,点的接近度可以用来观察两点之间的相似性
我的朋友们,这是用两个数据故事对两种降维技术的简单解释。总结一下
- PCA 基本上是通过尽可能地分离点来工作的
- TSNE 基本上是通过将点尽可能靠近地分组来工作的
- 只有当数据不稀疏时,TSNE 才会形成簇
这两种技术都有自己的风格,在不同的情况下都很有用
所以现在正如你所理解的不同,这不是一个对另一个。都是很棒的技术,都有自己的风格。
Photo by Jonathan Tomas on Unsplash
额外资源
网站(全球资讯网的主机站)
你可以访问我的网站进行零编码分析。https://experiencedatascience.com
请订阅每当我发布一个新的故事时,请及时通知我。
** [## 每当 Pranay Dave 发表文章时,您都会收到电子邮件。
每当 Pranay Dave 发表文章时,您都会收到电子邮件。通过注册,您将创建一个中型帐户,如果您还没有…
pranay-dave9.medium.com](https://pranay-dave9.medium.com/subscribe)
你也可以通过我的推荐链接加入 Medium。
[## 通过我的推荐链接加入 Medium—Pranay Dave
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
pranay-dave9.medium.com](https://pranay-dave9.medium.com/membership)
https://www.youtube.com/c/DataScienceDemonstrated 的 YouTube 频道
这里是我的 Youtube 频道
的链接**
PDF 不是概率。
x 处的概率密度可以大于 1,但是它怎么能积分为 1 呢?
众所周知,概率的最大值是 1 。
但对于某些 PDF(如指数分布的 pdf,下图),当 λ= 1.5 和 𝒙 = 0 时,概率密度为 1.5 ,明显大于 1 !
From Wikipedia: The PDF of Exponential Distribution
1.一个 PDF 的值怎么可能大于 1,概率仍然积分为 1?
即使 PDF f(x) 取大于 1 的值,如果它所积分的区域小于 1 ,它加起来只能是 1 。让我们举一个最简单的 PDF 的例子——定义域**【0,0.5】上定义的均匀分布。均匀分布的 PDF 为 1/(b-a) ,在整个中恒定为 2。**
The PDF of uniform distribution
总概率就是图 f(x) ,
下的总面积也就是 2 * 0.5 = 1 。
如你所见,即使 PDF 大于 1 ,因为它在小于 1 的域上积分,所以它可以累加到 1 。
2.概率密度函数和概率的区别
PDF f(x)不是概率吗?
否。因为 f(x)可以大于 1 。
(PDF 中的“PD”代表“概率密度”,不是概率。)
f(𝒙) 只是 PDF 图在 X = 𝒙 处的高度。(你是否混淆了 𝐗 vs 𝒙 的符号?点击这里查看。)
整个“PDF =概率”的误解是因为我们习惯了“ PMF =概率”的概念,事实上,这是正确的。但是,一个 PDF 和一个 PMF 不是一回事,也不应该和一个 PMF 做同样的解读,因为离散随机变量和连续随机变量的定义是不一样的。
对于离散随机变量,我们在单点查找 PMF 的值以找到它的概率 P(𝐗=𝒙) (例如还记得我们如何将插入泊松 PMF 吗? )
对于连续的随机变量,我们在某个区间上对一个 PDF 进行积分,求其 X 落在那个区间的概率。
**f(x) ≠ P(X = 𝒙)*** **f(x): PDF for a continuous r.v.** * **P(X = x) : PMF for a discrete r.v.**
当然,都很好。然而,你可能想知道…
为什么我们必须整合 PDF?
我们能不能像处理 PMF 值一样,只对 PDF 值求和?
不会。因为,对于连续随机变量,𝐗取任意特定值𝒙的概率为 0。
3.为什么连续随机变量在每一点的概率为零?
我们来看前面的例子——均匀分布在【0,0.5】。****
x=1 时的概率密度为 2。但是为什么 x=1 时的概率为零呢?****
要回答上面的问题,我们需要先回答下面的问题:
【0,0.5】中我们总共有多少个实数?
****无限∞。(数学上彻底一点,不可数无穷。)
0.1 , 0.01 , 0.001 , 0.0001 ,…可以在最小的小数前面一直插入 0。
**因此,**一个连续的随机变量有无限#的可能取值,即使定义域很小且固定。假设【0,0.5】中每个值的概率密度取一个极小的值,例如 000000001。尽管如此,无限(不可数)多个值的总和将达到无穷大,不管它们的值有多小。
那么,为了使概率之和为 1 ,单点的概率应该是 1/∞ ,也就是 0 。
嗯,这也说不通。如果你加上无穷多个零,你仍然会得到零。总概率加起来应该是 1,而不是 0。
问题是,我们不能对连续变量使用离散 PMF(一个值有一个匹配概率)的概念。我们不能像对离散变量那样定义连续变量的概率。
4.那我们怎么从概率密度 f(x)计算概率呢?
我们将借用“积分”的思想。
如果 X 正好在点𝒙的概率为零,那么围绕点 𝒙 的一个极小的区间呢?说,【𝒙,𝒙+d𝒙】?假设 d𝒙 是 0.00000000001。
那么 X 落在【𝒙,𝒙+d𝒙】的概率就是 f(𝒙) 夹在【𝒙,𝒙+d𝒙】中间的曲线下的面积。
如果 d𝒙 无限小,这个近似值对p(𝐗=𝒙来说就足够好了。
**f(𝒙)d𝒙** : The probability of **X** in **[𝒙, 𝒙+d𝒙]**.
**f(𝒙)**: Probability density.
**d𝒙** : Interval length.
需要注意一些事情:
1.如果你看一下 PDF 和 PMF 的定义,它实际上只是把离散情况下的求和(PMF)变成了连续情况下的积分(PDF)。
2.为什么我们使用术语【密度】【质量】*?*
这类似于物理学中的质量密度——将密度积分得到质量。如果你把一个质量想成一个概率,我们就对一个概率密度进行积分得到一个概率(质量)。
3.𝒙点的概率密度意味着什么?
意思是𝒙附近单位长度( d 𝒙)有多少概率集中,或者𝒙.附近概率有多密集
4.我们需要修正维基百科上的指数分布图。Y 轴的水平 P(X) 听起来像是概率。我们需要把它改成 f(x) 或者“概率密度”。
Wikipedia: The PDF of Exponential Distribution
你可能喜欢的其他直观的文章:
何时使用泊松分布?
towardsdatascience.com](/poisson-distribution-intuition-and-derivation-1059aeab90d) [## 指数分布直觉
它的派生词和例子
medium.com](https://medium.com/@aerinykim/what-is-exponential-distribution-7bdd08590e2a)**
使用 Python 处理 PDF
Photo by James Harrison on Unsplash
介绍
作为一种语法相对简单的高级解释语言,Python 对于那些没有编程经验的人来说是完美的。流行的 Python 库被很好地集成在一起,提供了处理像 Pdf 这样的非结构化数据源的解决方案,并且可以用来使它更加合理和有用。
PDF 是最重要和使用最广泛的数字媒体之一。用于提交和交换文档。pdf 包含有用的信息、链接和按钮、表单域、音频、视频和业务逻辑。
1-为什么使用 Python 处理 PDF
如你所知,PDF 处理属于文本分析。
大多数文本分析库或框架都是仅用 Python 设计的。这为文本分析提供了杠杆作用。还有一点,你永远无法在现有的机器学习或自然语言处理框架中直接处理 pdf。除非他们为此提供一个明确的接口,否则我们必须首先将 pdf 转换成文本。
2-用于 PDF 处理的 Python 库
作为一名数据科学家,你可能不会拘泥于数据格式。
pdf 是一个很好的数据源,大多数组织只发布 pdf 格式的数据。
随着 AI 的成长,我们需要更多的数据进行预测和分类;因此,忽略 pdf 作为数据源可能是一个错误。实际上,PDF 处理有点困难,但是我们可以利用下面的 API 来简化它。
在这一节中,我们将发现顶级 Python PDF 库:
PDFMiner 是一个从 PDF 文档中提取信息的工具。与其他 PDF 相关工具不同,它完全专注于获取和分析文本数据。PDFMiner 允许用户获得文本在页面上的确切位置,以及其他信息,如字体或线条。它包括一个 PDF 转换器,可以将 PDF 文件转换为其他文本格式(如 HTML)。它有一个可扩展的 PDF 解析器,可以用于文本分析之外的其他目的。
PyPDF2 是一个纯 python 的 PDF 库,能够拆分、合并、裁剪和转换 PDF 文件的页面。它还可以向 PDF 文件添加自定义数据、查看选项和密码。它可以从 pdf 中检索文本和元数据,还可以将整个文件合并在一起。
pdfrw 是一个 Python 库和实用程序,用于读取和写入 PDF 文件:
- 版本 0.4 已经过测试,可以在 Python 2.6、2.7、3.3、3.4、3.5 和 3.6 上运行
- 操作包括子集化、合并、旋转、修改元数据等。
- 最快的纯 Python PDF 解析器
- 多年来一直被印刷商用于印前生产
- 可与 rst2pdf 一起使用,忠实地再现矢量图像
- 可以单独使用,也可以与 report lab 结合使用,以便在新的 pdf 中重用现有的 pdf
- 特许的
石板
Slate 是一个 Python 包,它简化了从 PDF 文件中提取文本的过程。这取决于 PDFMiner 包。
3-设置环境
**第一步:**从【Python.org】中选择要安装的 Python 版本。
****第二步:下载 Python 可执行安装程序。
****第三步:运行可执行安装程序。
步骤 4: 验证 Python 是否安装在 Windows 上。
步骤 5: 验证是否安装了 Pip。
****第六步:将 Python 路径添加到环境变量中(可选)。
步骤 7 :为你的 IDE 安装 Python 扩展。
我在 visual studio 代码中使用 Python 3.7。有关如何设置环境和选择 Python inter inter ter 来开始用 VS 代码编码的更多信息,请查看 VS 代码文档中的Python 入门。****
第 7 步:现在你可以用你的 IDE 执行 python 脚本了。
步骤 8 :安装 pdfminer.six
**pip install pdfminer.six**
第 9 步:安装 PyPDF2
**pip install PyPDF2**
搞定了。现在,你可以开始用 python 处理 pdf 文档了。
4-多个大型 Pdf 文档文本提取解决方案
pdf 文本提取解决方案基于三个主要步骤:
- 将 PDF 文档分割成一组文档(逐页分割)
- 处理分割文档并提取文本。
步骤 1:设置烧瓶应用端口和前缀:
**import datetime
import numpy as np
import json
def myconverter(o):
if isinstance(o, datetime.datetime):
return o.__str__()
if isinstance(o, np.bool_):
return o.__str__()
def writeToJSONFile(filepath, data):
with open(filepath, 'w') as file:
json.dump(data, file, default=myconverter, indent=4)
ports = {
"data_extraction": 5000
}
PREFIX = "/api"**
第二步:分割 PDF 文档:
该脚本包括:
- 从上传文件夹中收集 Pdf 文件
- 逐页分割 Pdf 文件
- 将分割的 pdf 页面保存到输出文件夹
**import os
from PyPDF2 import PdfFileReader, PdfFileWriter
def splitting(upload_folder, split_folder):
'''Do collect PDF files, split pages and save them
'''
entries = os.listdir(upload_folder)
path = os.path.abspath(split_folder)
for entry in entries:
uploaded_file = os.path.join(upload_folder, entry)
output_file_folder = os.path.join(path, entry)
if not os.path.isdir(output_file_folder):
os.mkdir(output_file_folder)
pdf = PdfFileReader(uploaded_file, strict=False)
for page in range(pdf.getNumPages()):
pdf_writer = PdfFileWriter()
pdf_writer.addPage(pdf.getPage(page))
output_filename = \
os.path.join(output_file_folder, f'{page+1}.pdf')
with open(output_filename, 'wb') as out:
pdf_writer.write(out)**
第三步:从 PDF 文档中提取文本:
该脚本包括:
- 收集分割的 PDF 页面。
- 将文本文件提取并保存到输出目录
**import os
from io import StringIO
import re
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
def pdf_to_text(path):
'''Extract text from pdf documents
'''
manager = PDFResourceManager()
retstr = StringIO()
layout = LAParams(all_texts=False, detect_vertical=True)
device = TextConverter(manager, retstr, laparams=layout)
interpreter = PDFPageInterpreter(manager, device)
with open(path, 'rb') as filepath:
for page in PDFPage.get_pages(filepath, check_extractable=True):
interpreter.process_page(page)
text = retstr.getvalue()
device.close()
retstr.close()
return text
def extraction(split_path, text_path):
'''Extract and save text files to output dir
'''
# entries names
entries = os.listdir(split_path)
# repeat the process for each entry
for entry in entries:
# define a custom list cotain entries files paths
custom_list = os.listdir(os.path.join(split_path, entry))
# list must be sorted
custom_list.sort(key=lambda f: int(re.sub(r'\D', '', f)))
# repeat the process for each file path
for file_path in custom_list:
text_output = pdf_to_text(
os.path.join(split_path, entry, file_path))
# save text file of each entry
with open(os.path.join(text_path, f"{entry}.txt"),
"a",
encoding="utf-8") as text_file:
text_file.write(text_output)**
步骤 4:提取相关实用程序的烧瓶包装: (分离和提取烧瓶 API)
**'''Flask wrapping of the extraction related utilities
'''
import os
from flask import Flask, request, jsonify
from werkzeug.utils import secure_filename
from global_common import ports
from global_common import PREFIX
from extraction import extraction
from splitting import splitting
app = Flask(__name__)
port = int(os.environ.get("PORT", ports["data_extraction"]))
path = os.getcwd()
# Project directories defined As follow:
# -data_dir-: data .
data = os.path.join(path, 'data')
if not os.path.isdir(data):
os.mkdir(data)
# -upload_dir-: contain files uploaded.
uploads = os.path.join(data, 'uploads')
if not os.path.isdir(uploads):
os.mkdir(uploads)
# -preparation_dir-: contain processed & prepared files.
prepare = os.path.join(data, 'files_preparation')
if not os.path.isdir(prepare):
os.mkdir(prepare)
# -output_dir-: contain generated text files.
outputs = os.path.join(data, 'outputs')
if not os.path.isdir(outputs):
os.mkdir(outputs)
# Verify and validate files extensions...
ALLOWED_EXTENSIONS = set(['.pdf'])
def allowed_file(filename):
'''Assess if the file extension is in the allowed listdir
'''
lowercase_extension = os.path.splitext(filename)[1].lower()
return lowercase_extension in ALLOWED_EXTENSIONS
@app.route(PREFIX + '/upload', methods=['POST'])
def upload():
'''Upload files to process
'''
if request.method != 'POST':
resp = jsonify({'message': 'Operation not supported'})
resp.status_code = 500
return resp
# check if the post request has the file part
if 'files[]' not in request.files:
resp = jsonify({'message': 'No file part in the request'})
resp.status_code = 500
return resp
files = request.files.getlist('files[]')
errors = {}
success = False
# check if file allowed or not allowed.
for file in files:
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
file.save(os.path.join(uploads, filename))
success = True
else:
errors[file.filename] = 'File type is not allowed'
if success and errors:
errors['message'] = 'File(s) successfully uploaded'
resp = jsonify(errors)
resp.status_code = 404
return resp
if success:
resp = jsonify({'message': 'Files successfully uploaded'})
resp.status_code = 200
return resp
resp = jsonify(errors)
resp.status_code = 404
return resp
@app.route(PREFIX + '/extraction', methods=['POST'])
def extract_function():
'''Do extract data from files
'''
if request.method == 'POST': # check request method
if not os.listdir(uploads): # if uploads dir is empty return -> error
resp = jsonify({'message': 'Files not found'})
resp.status_code = 500
return resp
try:
# splitting : split docs into single pages.
splitting(uploads, prepare)
# extraction: extract text from pages.
extraction(prepare, outputs)
resp = jsonify({'message': 'Files successfully extracted '})
resp.status_code = 200
return resp
except:
resp = jsonify({'message': 'error occurs while extraction'})
resp.status_code = 404
return resp
else:
resp = jsonify({'message': 'Operation not supported'})
resp.status_code = 500
return resp
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=port)**
第五步:编写 Dockerfile 文件
**FROM python:3.7
COPY . /app/
WORKDIR /app
RUN pip install -r requirements.txt
ENTRYPOINT ["python3"]
CMD ["app.py"]**
第六步: 编写 App(编写 Docker-Compose 文件)
**version: '3'
services:
web:
build: '.'
ports:
- '5000:5000'**
步骤 7:测试烧瓶应用程序(上传&提取)
另外,我在的 pdf-text extractGitHub 项目中附上了 postman 集合。
**curl -X POST [http://127.0.0.1:5000/api/upload](http://127.0.0.1:5000/api/upload)
curl -X POST [http://127.0.0.1:5000/api/upload](http://127.0.0.1:5000/api/upload) --form 'files[]=@"toto.pdf"' --form 'files[]=@"toto2.pdf"'
curl -X POST [http://127.0.0.1:5000/api/extraction](http://127.0.0.1:5000/api/extraction)**
GitHub 上有完整版的 Extraction。
请通过查看
分叉 和 主演 资源库是支持项目的最佳方式。
**** [## ahmedkhemiri 95/pdf-text extract
Python 多 PDF 文档文本提取— Python 3.7 作为一名数据科学家,你可能不会拘泥于数据格式。PDFs
github.com](https://github.com/ahmedkhemiri95/PDFs-TextExtract)****
如果你对我的文章有任何反馈、评论或有趣的见解,请随时通过我的 LinkedIn 社交媒体频道联系我
你可以在 Github 上关注我:【https://github.com/ahmedkhemiri95】T22
**** [## Ahmed Khemiri -微软认证培训师-微软| LinkedIn
在世界上最大的职业社区 LinkedIn 上查看 Ahmed Khemiri 的个人资料。艾哈迈德有 3 个工作列在他们的…
www.linkedin.com](https://www.linkedin.com/in/ahmed-khemiri-b33400134/)****
预测不可靠的调峰。
神经网络调峰:第三部分
一个 19 世纪的物理方程如何能让电力公司节约超过 60%
与 合作研究开放建模框架 。
这是关于神经网络调峰的三部分系列文章中的第三部分。考虑一下另外两个:
电力分销商可以通过降低高峰需求费用来节省数十万美元。一些…
www.brownanalytics.com](https://www.brownanalytics.com/energy_forecasting)
即使是预测能源消耗的最佳模型也不足以捕捉大部分调峰的可能价值。当一个预测只有 3%的误差时,结果是损失一半的可能节省并不罕见。考虑最小的误差如何显著影响这些电力公司预期的调峰成本节约(此处测试):
考虑到这一点,在考虑第二天的负载预测的不确定性时,考虑公用事业公司应该部署哪种调度策略是很重要的。谢天谢地,我们可以用一个等式来为这种不确定性做打算,对冲我们的赌注,并重新获得一些在不完美预测中损失的价值。
设置
3D 热量方程如下所示。3Blue1Brown 的对该主题的介绍启发了这种方法。就我们的目的而言,您只需要知道热量方程是一个方便的函数,可以在曲线下的面积保持不变的情况下展平曲线。我们希望在使用所有可用资源的同时分散我们的派遣。
Left: The 3D heat equation, where T is temperature, alpha is some constant and t is time. Right: How the heat equation affects a curve. Source: 3Blue1Brown
考虑对明天负荷曲线的预测。我们知道,一般来说,3%的平均绝对误差是正确的。我们不能将所有鸡蛋放在一个篮子里(即,将我们所有的电池调度放在一个小时内)。我们根据预测的负载来计算理想的存储调度,然后将热量方程应用到附近的时间。这确保了最小的预测误差不会导致储蓄的显著下降。
下面是转化为 python 的热量方程及其对存储调度的影响:
其他详细信息
电力公司可能犯的最大错误是试图在错误的时间给电池充电。在我测试过的众多型号中,中午充电的电池持续增加本月的峰值(T2)。由于这个原因,最好总是安全地玩,并且总是在消耗处于绝对低的时候充电。从我收集的信息来看,这种保险策略只损失了大约 1-2%的最佳可能价值,而且非常值得,至少在预测软件变得更好之前是如此。
为了做出调度决策,我们使用线性编程 python 包puLP
。软件包的细节可以在这里找到——它对任何类型的运筹学都非常有用。我们陈述了一个目标函数,如“最小化最大负载”,同时提供了电池的限制。
结果呢
我测试了从 2002 年到 2018 年,热量等式将如何影响德克萨斯州八个 ERCOT 地区的收入。为了模拟预测精度,我添加了一个噪声的正态分布,在负载周围有 3%的标准偏差。我假设我们有 700 千瓦的存储,每小时最多可以调度 500 千瓦。功能和测试可以在本 jupyter 笔记本中找到。
重要的是要澄清,测试是在每天的峰值上执行的,以收集更大的样本。我依赖的假设是月峰值和日峰值之间没有显著差异。
Percent of optimal value obtained if heat equation is applied with given values in the COAST region of ERCOT.
上面的热图显示了应用不同的 alpha 值和时间步长时获得的最佳值的百分比。在 ERCOT 的沿海地区,如果热量方程不适用,公用事业公司将收集 28%的最佳调峰值。如果适当地应用热量方程,它们捕获 46%的最优值。德克萨斯州每个地区的结果如下表所示。应用这个扩展公式可以帮助每个地区。这一公式将增加 20%到 64%的储蓄。
此外,最大化节约的常数对于每个地区来说都是相对相似的,这表明这些常数随着时间的推移是相对稳定的,并且是可推广的,尽管自然地,每个公用事业公司在应用它们之前都必须进行独立的分析。
对德克萨斯州 NCENT 地区的快速分析显示,即使有 99%的准确率,应用热量方程仍然可以提高储蓄。在我们的预测能力达到随机效应所允许的完美程度之前,应该应用并完善考虑到我们不确定性的优化公式。
疑问?更正?数据科学笑话?联系我或者在 我的网站 上看到更多好玩的项目。
皮尔逊相关系数解释。
我开始意识到,对于可以在数据集上执行的不同类型的关联,存在许多困惑。让我先从皮尔逊相关系数开始,澄清一下这个问题。
什么是相关性?
相关性是一种双变量分析,衡量两个变量之间的关联强度和关系方向。就关系的强度而言,相关系数的值在+1 和-1 之间变化。值为 1 表示两个变量之间的完美关联程度。随着相关系数值趋向于 0,两个变量之间的关系将变弱。关系的方向由系数的符号表示;加号表示正相关,减号表示负相关。
通常,在统计学中,我们衡量四种类型的相关性:
- 皮尔逊相关
- 肯德尔等级相关
- 斯皮尔曼相关
- 点双列相关。
皮尔逊相关系数
如题所示,我们将只讨论皮尔逊相关系数。我会尽量简短,但内容丰富,这样你就可以自己动手了。皮尔逊相关系数是对两个变量之间线性关联强度的度量,用 r 表示。您会遇到皮尔逊 r 相关
皮尔逊相关回答的问题
- 年龄和身高有统计学上的显著关系吗?
- 温度和冰淇淋销量有关系吗?
- 工作满意度、生产率和收入之间有关系吗?
- 哪两个变量在年龄、身高、体重、家庭规模和家庭收入之间有最强的相关性?
假设
1.对于皮尔逊 r 相关性,两个变量都应该是正态分布。即正态分布描述了变量的值是如何分布的。这有时被称为“钟形曲线”或“高斯曲线”。一个简单的方法是使用夏皮罗-维尔克检验分别确定每个变量的正态性。
Normal Distribution
2.应该有没有明显的异常值。我们都知道异常值是什么,但我们不知道异常值对皮尔逊相关系数 r 的影响。皮尔逊相关系数 r 对异常值非常敏感,这会对最佳拟合线和皮尔逊相关系数产生非常大的影响。这意味着-在分析中包含异常值会导致误导性结果。
Outliers
3.每个变量应该是连续的,即间隔或比率,例如体重、时间、身高、年龄等。如果一个或两个变量在测量中是有序的,那么可以进行 Spearman 相关。
4.这两个变量有一个线性关系。散点图将帮助您判断变量之间是否存在线性关系。如果数据点是直线(而不是曲线),则数据满足线性假设。如果您拥有的数据不是线性相关的,您可能需要运行非参数。
Linear and non-Linear Relationships
5.这个观测值是**成对观测值。**也就是说,对于自变量的每一次观测,必然有因变量的相应观测。例如,如果你在计算年龄和体重之间的关系。如果有 12 个体重的观察值,你应该有 12 个年龄的观察值。即没有空白。
6.同质性。我把最好的留到了最后。hard 很难发音,但概念很简单。同方差描述了一种情况,其中误差项(即自变量和因变量之间关系中的“噪声”或随机扰动)在自变量的所有值上都是相同的。散点图使得检查这一点变得容易。如果这些点位于最佳拟合线的两侧,那么数据是同方差的。另外,同异方差的反义词是异方差(违反同异方差),当误差项的大小在自变量的值之间不同时,就会出现异方差。
Homoscedasticity
Heteroscedasticity
您还可以查看:
Pebble 的前数据主管谈论进军数据科学的策略
苏珊·霍尔科姆目睹了一切。
2014 年,她加入了世界上第一家智能手表公司 Pebble,成为他们第一位专注于数据的员工。她将继续领导他们的整个数据科学工作,并面临艰巨的挑战,即如何处理一种在此之前几乎没有人遇到过的数据。
苏珊也是一个有天赋的社交高手:如果你不知道如何接触合适的人,你不可能从一个物理学研究生辍学成为硅谷最热门的创业公司之一的数据主管。
我们与 Susan 坐下来讨论了成就伟大数据科学事业的技能(和个性),以及她为那些希望在数据科学领域引起招聘经理注意的人提供的屡试不爽的建议。请点击这里查看,别忘了在 Twitter 上关注她,地址为 @h0lc0mb !
额外收获:一定要去看看苏珊的网站:datasciencecareermap.com
请听下面的对话:
基于 RetinaNet 的航空图像行人检测
用数据做很酷的事情!
介绍
航空图像中的目标检测是一个具有挑战性和有趣的问题。随着无人机成本的降低,产生的航空数据量激增。拥有能够从航空数据中提取有价值信息的模型将非常有用。 Retina Net 是最著名的单阶段探测器,在这篇博客中,我想在来自斯坦福无人机数据集的行人和骑车人的航拍图像上测试它。请参见下面的示例图像。这是一个具有挑战性的问题,因为大多数物体只有几个像素宽,一些物体被遮挡,阴影中的物体更难检测。我读过几个关于空中图像或汽车/飞机上的物体检测的博客,但是只有几个关于空中行人检测的链接,这是特别具有挑战性的。
Aerial Images from Stanford drone dataset — Pedestrians in pink and Bikers in red
视网膜网
RetinaNet 是一款单级检测器,使用特征金字塔网络(FPN)和焦点损失进行训练。特征金字塔网络是这篇论文中介绍的一种多尺度物体检测结构。它通过自上而下的路径和横向连接将低分辨率、语义强的特征与高分辨率、语义弱的特征结合起来。最终结果是,它在网络的多个级别上产生不同比例的特征图,这有助于分类器和回归器网络。
焦点损失被设计成解决具有不平衡的单阶段对象检测问题,其中存在非常大量的可能背景类别,而只有少数前景类别。这导致训练效率低下,因为大多数位置是没有贡献有用信号的容易否定的,并且大量的这些否定例子淹没了训练并降低了模型性能。焦点损失基于交叉熵损失,如下所示,通过调整伽马参数,我们可以减少分类良好的示例的损失贡献。
Focal Loss Explanation
在这篇博客中,我想谈谈如何在 Keras 上训练一个 RetinaNet 模型。我没有对 RetinaNet 背后的理论做出足够的评价。我用这个链接来了解这个模型,并强烈推荐它。我的第一个训练模型在空中探测物体方面表现很好,如下图所示。我还在我的 Github 链接上开源了代码。
Retina Net on Aerial Images of pedestrians and bikers
斯坦福无人机数据集
斯坦福无人机数据是无人机在斯坦福校园上空收集的航拍图像的海量数据集。该数据集是理想的对象检测和跟踪问题。它包含大约 60 个空中视频。对于每个视频,我们有 6 个类的边界框坐标——“行人”、“骑车人”、“滑板者”、“手推车”、“汽车”和“公共汽车”。行人和骑车人的数据集非常丰富,这两个类别覆盖了大约 85%-95%的注释。
在斯坦福无人机数据集上训练 Keras 的 RetinaNet
为了训练视网膜网络,我在 Keras 中使用了这个实现。它有很好的文档记录,并且工作时没有错误。非常感谢 Fizyr 开源他们的实现!
我遵循的主要步骤是:
- 从庞大的斯坦福无人机数据集中选择图像样本来构建模型。我拍摄了大约 2200 张训练图像和 30,000 多个公告,并保留了大约 1000 张图像进行验证。我已经把我的图像数据集放在 google drive 这里给任何有兴趣跳过这一步的人。
- 生成 Retina Net 所需格式的注释。Retina Net 要求所有注释都采用格式。
path/to/image.jpg,x1,y1,x2,y2,class_name
我将斯坦福注释转换成这种格式,我的训练和验证注释被上传到我的 Github 。
- 调整锚点大小:Retina 网的默认锚点大小为 32、64、128、256、512。这些锚的大小对大多数物体来说都很好,但是因为我们是在航拍图像上工作,一些物体可能小于 32。这个回购协议提供了一个方便的工具来检查现有的锚是否足够。在下图中,绿色的注释被现有的锚点覆盖,红色的注释被忽略。可以看出,即使对于最小的锚尺寸,很大一部分注释也太小了。
Retina Net with default anchors
所以我调整了锚,去掉了最大的 512 号锚,代之以一个 16 号的小锚。这导致了显著的改进,如下所示:
After adding a small anchor
- 有了这些,我们准备开始训练。我保留了大多数其他默认参数,包括 Resnet50 主干,并通过以下方式开始训练:
keras_retinanet/bin/train.py --weights snapshots/resnet50_coco_best_v2.1.0.h5 --config config.ini csv train_annotations.csv labels.csv --val-annotations val_annotations.csv
这里的重量是可可重量,可用于跳跃开始训练。用于训练和验证的注释是输入数据,config.ini 具有更新的锚大小。所有文件也在我的 Github repo 上。
就是这样!模型训练起来很慢,我连夜训练。我通过在测试集上检查平均精度(MAP) 来测试训练模型的准确性。从下面可以看出,第一个经过训练的模型具有非常好的 0.63 的 MAP。在从空中容易看到的汽车和公共汽车类上,性能尤其好。骑自行车的人级别的地图很低,因为这经常被行人混淆。我目前正致力于进一步提高自行车手职业的准确性。
Biker: 0.4862
Car:0.9363
Bus: 0.7892
Pedestrian: 0.7059
Weighted: 0.6376
结论
Retina Net 是一个使用特征金字塔网络的强大模型。它能够在非常具有挑战性的数据集上检测空中的物体,其中物体尺寸非常小。我花了半天时间训练了一个视网膜网络。经过训练的模型的第一个版本具有相当好的性能。我仍然在探索如何进一步适应视网膜网络架构,以在空中检测中具有更高的准确性。这将在我的下一篇博客中讨论。
我希望你喜欢这个博客,并尝试自己训练模型。
我有自己的深度学习咨询公司,喜欢研究有趣的问题。我已经帮助许多初创公司部署了基于人工智能的创新解决方案。在 http://deeplearninganalytics.org/的入住我们的酒店。
你也可以在https://medium.com/@priya.dwivedi看到我的其他作品
如果你有一个我们可以合作的项目,请通过我的网站或 info@deeplearninganalytics.org 联系我
参考
基于非最大抑制算法的行人检测
检测路上行人的完整管道
Photo by David Marcu on Unsplash
被困在付费墙后面?点击这里阅读完整故事与我的朋友链接!
行人检测仍然是计算机科学中尚未解决的问题。虽然已经研究了许多目标检测算法,如 YOLO、SSD、RCNN、快速 R-CNN 和更快 R-CNN,并取得了巨大的成功,但是拥挤场景中的行人检测仍然是一个公开的挑战。
近年来,在人的密度高的真实世界场景中,即机场、火车站、商场等,迫切需要行人检测。尽管已经取得了很大的进步,但是在这些场景中检测行人仍然是困难的,这由现有技术方法的显著性能下降所证明。在这篇文章中,我将介绍一种被称为非最大抑制的高效可扩展算法,用于解决拥挤场景中的行人/人物检测。
应用程序
- **自动驾驶汽车。**识别道路场景中的行人
- 安全。限制某些人进入某些地方
- **零售。**分析超市内顾客的行为
- **时尚。**识别特定品牌和穿着它们的人
数据
我从 这里 下载了测试用的图片。然后,我将图像压缩到 300*200 的大小,并使用这些图像作为这个项目的测试图像。
非最大抑制
结合支持向量机(SVM)** 的定向梯度历史(HOG)** 对于检测图像中的对象已经相当成功,但是这些算法的问题是它们检测图像中对象周围的多个边界框。因此,它们不适用于我们在拥挤的道路上检测行人的情况。这就是非最大抑制(NMS)来拯救更好地细化检测器给出的边界框的地方。在该算法中,我们提出了额外的惩罚来产生更紧凑的包围盒,从而变得对 NMS 阈值不太敏感。对于具有贪婪 NMS 的管道下的人群,理想的解决方案是设置高阈值以保留高度重叠的对象,并为所有实例预测非常紧凑的检测框以减少误报。
环境和工具
- sci kit-学习
- sci kit-图像
- numpy
- opencv
代码在哪里?
事不宜迟,让我们从代码开始吧。github 上的完整项目可以在这里找到。
我从计算我们的算法检测到的两个边界框之间的重叠区域开始。
然后我定义了一个函数,将包围盒矩形和阈值因子作为输入。我还按照右下角坐标值的降序排列了所有的边界框。之后,我将所有不在重叠区域 0.5 倍范围内的盒子附加到另一个盒子上。
加载所有需要的库的时间。
然后我创建了一个函数,将所有边界框的四个端点坐标添加到一个空列表中。
之后,我为图像定位创建了一些解析器参数,缩小它,可视化它,并对它应用阈值。
然后是算法的核心部分。我使用了一个 pickle 文件,它是在数千张有行人和没有行人的图像上训练后生成的。此外,我将图像转换为灰度,并在其上应用了步长。
之后,我创建了一个脚本来查找和定位所有在 nms 函数定义的阈值内的边界框,如上所示。请注意,下面的脚本乍一看可能有点吓人,但它只是简单的数学。
最后,我写了一些行来显示应用 NMS 前后的图像,并保存了我得到的输出图像。
评估行人检测模型
对象检测问题中的每个图像可能具有不同类别的不同对象。因此,在图像分类问题中使用的标准精度度量不能直接应用于此。这就是 mAP(平均精度)发挥作用的地方。
地面实况; 真值(机器学习)
对于任何算法,总是在与真实数据的比较中评估指标。我们只知道训练、验证和测试数据集的基本事实信息。
对于对象检测问题,基础事实包括图像、图像中对象的类别以及图像中每个对象的真实边界框。
Sample Example
计算地图
让我们说,原始图像和地面真相注释是我们在上面看到的。训练和验证数据以相同的方式对所有图像进行注释。该模型将返回大量预测,但其中大多数预测的相关置信度非常低,因此我们只考虑高于某个报告置信度的预测。我们通过我们的模型运行原始图像,这是在置信度阈值化之后对象检测算法返回的结果。
我们首先需要知道来判断这些检测中每一个的正确性。告诉我们给定边界框的正确性的度量是并集上的交集。
计算欠条
交集/并集是预测框和基础事实框的交集和并集之间的比率。
结果
Input Image
Output Image
结论
虽然像 Mask R-CNN 这样的算法已经突破了边界,并被认为是最先进的实例分割算法,但像行人检测这样的问题仍然提出了许多公开的挑战。如果图像包含聚集在一个位置的许多人,非最大抑制算法仍然失败。这个项目远未结束。事实上,它提出的问题比它回答的问题还多。无人驾驶汽车的未来在很大程度上取决于高效的行人检测算法。
参考资料/进一步阅读
追踪行人的完整管道。
medium.com](https://medium.com/@abhinav.sagar/pedestrian-tracking-in-real-time-using-yolov3-33439125efdf) [## 自适应 NMS:改进人群中的行人检测
人群中的行人检测是一个非常具有挑战性的问题。本文通过一种新颖的非最大值方法来解决这个问题
arxiv.org](http://arxiv.org/abs/1904.03629) [## Python - PyImageSearch 中对象检测的非最大抑制
康涅狄格州很冷。非常冷。有时候早上起床都很难。老实说,如果没有…
www.pyimagesearch.com](https://www.pyimagesearch.com/2014/11/17/non-maximum-suppression-object-detection-python/)
在你走之前
相应的源代码可以在这里找到。
使用非最大抑制的行人检测。行人检测仍然是计算机领域尚未解决的问题…
github.com](https://github.com/abhinavsagar/Pedestrian-detection)
联系人
如果你想了解我最新的文章和项目,请关注我的媒体。以下是我的一些联系人详细信息:
快乐阅读,快乐学习,快乐编码。
惩罚均值:调整异常值的新方法?
在处理真实世界的数据时,知道如何处理异常值是一个标准,例如,这篇文章涵盖了检测异常值的统计和机器学习方法。一旦我们知道数据中有异常值,我们可以做以下两件事之一:
- 扔掉它们。
- 使他们正规化。
在接下来的部分中,我们将简要介绍两篇学术文章,介绍用于异常值正则化的离散函数,但是如果值为正,我们也定义一种正则化它们的新方法。我们所理解的离散函数是,给定一个变量 x ,它只能从给定的集合ω中取值,其中每个元素都是相互“分离”的。
1.L-1 范数误差函数稳健性和异常值正则化
这篇由丁宏强和蒋波撰写的文章的动机是使用线性函数来拟合数据。假设你在一个二维空间中有( x , y )个真实数据,如图 1。其中拟合值(红线)由 f、 表示
Figure 1. The blue points represent observed data, the red line represents a linear fitted model and the dashed line a δ threshold.
那么我们说,如果理论预测值 f 与真实值 y 之差大于 δ,那么这个数据点就是异常值。 换言之,
Figure 2
符号函数在哪里
Figure 3. The sign function
并且 δ 是具有将观察值 y 拉回红色虚线的效果的公差参数,而与距离平均值有多远无关。
2.矢量数据的异常正则化与 L21 范数稳健性
由同一作者在第一篇文章的一个月后写的这篇文章是上述技术的矢量化方法。在这种情况下,我们将真正的观察点移动一些单位远离观察点*【f】,*** 如图 4 所示。**
Figure 4
等同于之前,我们现在在边界处有 y (由图 1 中的虚线表示)。我们在图 4 中看到,通过归一化向量,拉回是有保证的。
总的来说,这些技术结合了期望极限值 、δ 、前沿的信息。现在我们将看到一种不同的方法来整合某个阈值之间的实值*【y】*,但是如果您想深入了解该函数的等效连续表示,请查阅论文。
3.惩罚平均值
如果我们假设我们的数据是正态分布的(至少 30 个观察值),传统的规则是丢弃一个观察值 x ,如果它离平均值有两个标准偏差。惩罚均值不仅调整上述数据,而且当 x 偏离均值一个标准偏差时也调整。正如我们在图 5 中看到的。
Figure 5
在第一种情况下,我们注意到 2σ/(x-μ) 小于 1,因此 x 被拉回一个标准差和两个标准差之间,稍后我们将看到理论上的证明。而在第二种情况下,将σ移到第二项的分母后,我们注意到
Figure 6
由于1<(x-μ)/σ<2的事实,这对于确保满足不等式μ<x<μ+σ具有巨大的效果。现在,让我们看看当观察值位于中值μ的左侧时会发生什么,正则化函数发生变化,因为现在我们正在搜索大于 1 的参数γ,使得 x 向右移动。
Figure 7
例如,当 x < μ - 2σ 时,我们有那个*(μ-x)/2σ>1***,因此新的值 x 将大于它本身。对于理论上的证明,我们将在下一节正式证明。**
4.区间对齐
现在我们要确定正则化后 x 的值。这一部分是技术性的,所以你可以跳过它,但它是有用的尝试肌肉大脑(只是代数!).
案例一。x < μ-2σ
After some algebra, we arrive at
Figure 8
where, we notice that
案例二。μ-2σ<x<μ-σ
基于这样一个事实
Figure 9
我们采用的方法是在最后一个不等式中限制横向极限。关于上限,我们执行以下操作。
Figure 10
对于下限,我们再次注意到 1 > σ / (μ-x) ,有了这个我们就有了那个
Figure 11
然后将所有术语组合在一起,间隔为
Figure 12
案例三。x+σ < x < x + 2σ
The initial inequality is
Figure 13
whereas before we’re trying to find upper and lower bounds. First, we notice that
Figure 14
To find an upper bound for this value, we’re going to do some algebra with the denominator. We should arrive at
Figure 15
Concerning the other bound in Figure 13, the algebra is analogous, but we would use a different trick as follows (where we have factorized some terms in the denominator x + σ + σ²/(x-μ))
Figure 16
where the last inequality is satisfied only if x > σ((2σ/μ)-1)。 考虑到最后一个操作,我们得出的区间是
Figure 17
案例 4。x > x + 2σ
现在,我们将正式证明我们之前说过的,即 x 取比 x + 2σ 小的值。证据如下
Figure 18.
注意到(2σ)/(x-μ)<1**,我们得出结论x 满足这样一个事实,即将取值到 x + 2σ 的左边。****
5.结论
我发现这两篇论文的一个不方便之处是阈值δ决定正则化值的位置。如果理论上找不到δ的最佳值,这可能会导致主观操纵数据。此外,如果假设数据中的噪声是高斯噪声,那么其中的 5%将采用固定值μ + δ或μ-δ。
在罚平均中,我们发现 x-(σ /(μ-x))并不总是正的,所以取绝对值来代替是方便的,但是预期的效果或使观察规律化并不令人满意。一般来说,这种方法对于位于μ右边的值更有效,因为对于 x < μ,如果值足够小,正则化根本无效,正如我们在第四节中所展示的。
最后,我们还没有涵盖可以应用这种正则化的实际案例,这可能是第二部分。
参考
【丁与江,2017】c .丁与 b .江。L-1 范数误差函数稳健性和异常值正则化。arXiv:1705.09954v1,2017。
【丁与江,2017】c .丁与 b .江。向量数据的异常正则化和 L21 范数稳健性。arXiv:1706.06409,2017。
分类惩罚回归
Image by Jill Wellington from Pixabay
在之前的中,我们研究了使用 JMP 的套索和弹性网正则化方法。这些模型是为了预测连续变量而构建的,所以这次我们将研究分类变量。更具体地说,这是一个二分法变量,它决定了葡萄酒的质量是“好”还是“坏”。我们将使用普通和惩罚逻辑回归构建几个模型,包括套索和弹性网技术的基本和自适应形式,最后我们将使用我们的“最佳”模型基于新数据进行预测。
我们将采用与之前研究略有不同的模型分析方法。在创建单个分类模型时研究它们的统计数据给我们的信息非常少,所以我们将保存每个新创建的模型的预测。这些预测将在以后进行比较,以确定每个模型的准确性和其他统计数据。
在这项研究中,我们将看看在 2009 年的一项研究中影响人类专家如何对葡萄酒质量进行排名的一些因素。参与者用 1-10 的等级给一些葡萄酒打分,并记录下每个样品的各个方面。出于本研究的目的,4 分或更低的评级被视为“差”,而 5 分或更高的评级被视为“好”这给了我们一个二元反应变量,每种酒要么是好的,要么是坏的。该数据集中总共包括 12 个预测值,如酸度、柠檬酸、残糖、酒精含量和颜色。
第一步是准备将这个数据集输入到我们的模型中。我们再次使用了 60/20/20 的培训/验证/测试划分。然而,因为这是横截面数据,JMP 的验证列工具将观察值分配给每个名称,以确保随机性。大约 3,900 个观察值用于训练每个模型,而 1,300 个观察值用于验证和测试每个模型。然后,我们创建了一个包含所有变量的基本逻辑回归模型。这有助于稍后提供一个基线,以查看使用所有预测变量的模型与其他更专业的模型相比表现如何。
基本和自适应套索方法
在最初的分析之后,我们开始寻找广义回归,以追求更准确的预测模型。广义回归在必要时对某些变量施加惩罚,以减少它们对模型的影响。我们从套索开始,用基本方法和自适应方法创建了预测模型。套索法使用了 12 个预测变量中的 8 个,减少了密度、pH 值、硫酸盐和总二氧化硫对模型的影响。自适应套索采取了不同的方法,仅使用 7 个预测变量。pH 值、硫酸盐和二氧化硫总量的影响再次减弱。
Adaptive Lasso Variable Estimates
基本和自适应弹性网格方法
下一组模型使用弹性网络方法,再次使用基础和适应性方法。弹性网模型确定 12 个变量中有 9 个对模型很重要。总二氧化硫、pH 值和硫酸盐水平再次降低。我们已经可以预计,最终的模型可能不会使用这 3 个变量,这表明它们对葡萄酒的质量等级影响很小。使用自适应弹性网显示了类似的结果,同时也排除了柠檬酸和氯化物。使用新的弹性网络模型,我们创建了两组新的预测,并保存每组预测,以便与 lasso 和普通逻辑回归模型进行比较。
Parameter Estimates for Adaptive Elastic Net Model
模型比较
保存了 5 组预测后,我们现在可以比较模型的准确性,看看某个特定的方法是否更好。正如我们在下面看到的,每个模型似乎都有一个相对较低的 R 平方值。然而,这个问题不同于以往的研究,我们的反应变量是如何分类的。在这项研究中,我们的响应变量是分类变量,而不是与实际值有可测量距离的数值。换句话说,预测和真实值之间不可能有距离,因为每个预测不是好就是坏。因此,R 平方值提供的信息非常少,因此我们需要查看其他度量来比较模型。更具体地说,我们想要观察错误分类率和 ROC 曲线下的面积。
错误分类率给出了预测出错频率的估计值。我们希望将这一比率降至最低,以减少对葡萄酒质量进行错误分类的机会。另一个指标,ROC 曲线下面积(或 AUC)理想地尽可能高。
ROC 曲线绘制了模型对 1 减去其特异性的灵敏度。这有助于表明我们的模型的真阳性率(模型正确猜测好酒的能力)是如何受模型的假阳性率(劣质酒被归类为好酒的频率)影响的。计算该图下的面积,并将其用作模型准确性的另一种度量。一个完全准确的模型的 AUC 为 1.0,表明其预测 100%正确。我们希望找到一个具有最高可能 AUC 的模型,这与更高的模型准确性相关。
Comparison of Classification Model Predictions
我们可以在上面的模型比较中看到 R 平方值有多低。由于我们的响应变量的性质,很难从这些值中提取任何有意义的数据,因此我们可以安全地忽略这些测量。相反,如上所述,我们将在测试数据集上比较每个模型的误分类率和 AUC。我们可以看到自适应套索和弹性网模型的错误分类率最低,相差很小,因此我们将这两个模型视为最佳模型。自适应套索的 AUC 为 0.7862,而自适应弹性网的 AUC 为 0.7861。因为这两个值非常接近,所以有理由认为这两个值中的任何一个都最适合我们的数据。为了这项研究,我们将使用适应性套索作为我们的最佳选择。
这里需要注意的一点是,每个型号的值非常相似。我们模型的错误分类率是 0.039 或 0.040,AUC 也在一个很小的范围内。这是因为在我们的数据集中只有几个变量和大量的观察值。在有限的变量池中,每个模型的构建方式几乎没有什么差异,因此预计模型会具有相似的精度。
Variable Use in Adaptive Lasso Model
在上图中,我们可以看到在自适应套索模型中选择使用的变量。正如所料,pH 值、硫酸盐和总二氧化硫在模型中的权重为 0。柠檬酸和氯化物也被认为是多余的或不需要的,所以它们的值被缩小到 0。挥发性酸度、颜色和残糖似乎对葡萄酒等级有很大的影响。挥发性酸度的负系数约为-5.54,表明与葡萄酒等级呈负相关。换句话说,随着酸度的增加,被归类为“好”的概率会降低。残糖有相反的关系,糖含量的增加往往会增加一个好的评级的机会。酒色[红白]在自适应套索模型中也有正系数。这表明红葡萄酒比白葡萄酒更有可能被评为好酒。
Variable Importance on Model
我们可以更进一步,研究每个变量在我们的预测模型中的重要性。在上图中,残糖似乎是葡萄酒质量分类的最大因素。约 47%的预测受残糖水平影响,41%受密度影响,34%的分类受挥发性酸度影响。基于我们的发现,有理由假设含糖量较高、密度较低的葡萄酒更有可能被归类为好酒。
对新数据的预测
我们还可以使用我们的模型来预测新酒的分类。假设新酒有以下数据,我们可以预测它会被归类为好还是坏:
固定酸度=8.9
挥发酸度= .90
柠檬酸=.35
pH=3.20
残糖=4.8
氯化物=.09
游离二氧化硫=4
总二氧化硫=40
密度=.99
硫酸盐=.65
酒精=9.0
颜色=红色
我们知道我们选择的自适应套索模型只使用了 7 个变量。将这些值输入到我们的模型中提供了 0.9516 的概率。因此,我们可以估计这种特殊的葡萄酒被归类为“好”的概率约为 95%。
这项研究的数据可以在我的GitHub(wine quality study . jmp)上找到。
JMP 的惩罚回归
Image by Kevin Schneider from Pixabay
这个简短的研究使用惩罚回归来预测银价,基于一些金融指标。惩罚逻辑回归或正则化是一种逻辑模型,它惩罚或减少某些变量的影响。当数据集有大量变量,但对哪些变量在回归模型中特别有用几乎没有指导时,使用正则化技术。为了避免模型过度拟合数据,正则化技术会施加一个惩罚来减少一些变量的影响,而不会直接将它们从方程中删除。这理想地给了我们一个模型,表明哪些变量对预测值的影响比其他变量更大。建立惩罚回归模型有许多方法,但这项研究将着眼于套索和弹性网方法。对于软件,我们将使用 JMP,它有一些有用的内置工具在需要时调整我们的模型。
该数据集包括描述汇率、利率和股票市场的 90 个不同变量的信息。我们只对描述基本变量的回报和滞后回报值的 60 个子集感兴趣。我们使用不同的方法建立了多个模型,以确定哪一个模型可以根据全球指标提供最准确的白银价格预测。套索和弹性网方法是我们的主要焦点,既是一种基本形式,也是一种适应性技术。我们还使用柯西分布建立了一个模型,以理想地忽略异常值的影响,并在标准化数据集上提供更准确的预测。
我们首先使用所有潜在变量建立一个标准的最小二乘模型。数据集被分割成 60/20/20 的部分,以创建训练、验证和测试数据集(这种分组也用于剩余的模型构建)。基本的标准最小二乘模型使用所有 60 个感兴趣的变量。这有助于在假设所有变量对银的预测值有显著影响的情况下提供基线。它还通过研究每个变量在这个天真模型中的影响,让我们预览了哪些变量更有可能出现在我们的最终模型中。
“套索”技术
套索技术能够将变量的大小减少到绝对 0,有效地消除它们对预测模型的影响。在寻找最佳拟合模型的过程中,我们同时使用了基础和自适应套索方法。我们的第一个模型,使用基础套索方法,在测试集上产生了大约 0.365 的 R 平方值。虽然不是一个过高的值,36.5%是一个相对有用的模型。0.0189 的 RMSE 也表明这是一个好模型。我们还可以看到,该模型的 lambda 值为 0.06。当λ较小时,该模型类似于最小二乘估计。然而,随着它的增加,变量值接近或达到 0。在这个模型中,λ相对较小,表明变量不需要太多的正则化。
Basic Lasso Model Results
套索和弹性网的自适应版本试图在变量对响应变量有实际影响时减少对变量的惩罚。自适应模型应该提供类似于那些你在模型中发现的对响应变量有实际影响的变量的估计。不同之处在于,适应性模型仍然使用所有变量,只是惩罚无用的变量,使其影响可以忽略不计。
使用自适应套索方法构建一个新模型提供了一个稍微不同的结果。我们的 R 平方值下降到 0.302,而 RMSE 上升到 0.02。套索和弹性网的自适应版本试图在变量对响应有实际影响时减少对变量的惩罚。我们可以在仅为 0.011 的新λ值中看到这一点的证据。该模型在识别应该具有零系数的预测因子时变得更加可靠,同时减少了对某些变量施加的惩罚。
Adaptive Lasso Method Results
弹性网格法
弹性网格法的最大优点之一是它结合了套索法和岭法的技术,套索法基于系数值的总和进行惩罚,岭法基于系数值的平方和进行惩罚。简而言之,弹性网方法基于相关性形成变量组。然后,当它找到一个强预测值时,它会将整个相关组包含在模型中。这在理想情况下避免了仅仅因为变量相关就忽略变量而丢失信息,但是仍然会施加惩罚以减少某些变量可能产生的影响。我们创建了两个模型,一个使用基本方法,另一个使用自适应方法,来研究与套索方法的区别。
Standard Elastic Net Method
标准弹性网模型在测试集上给出了 0.365 的 R 平方值,这非常接近套索模型。RMSE 几乎是相同的,以及我们的 lambda 惩罚这个模型。这表明,当使用弹性网格方法时,由套索模型选择和惩罚的变量被给予相同的处理。使用这种技术的自适应方法给出了与自适应套索模型相似的结果。我们在测试集上收到了一个 R 平方为 0.301、RMSE 为 0.021 的模型,它模拟了自适应套索模型的结果。λ值再次变小,仅为 0.011,表明在某些变量上更加宽松。
Adaptive Elastic Net
使用柯西分布
Adaptive Lasso Method Using Cauchy Distribution
我们还想尝试使用柯西分布建立一个模型。简而言之,柯西分布有助于消除主要异常值的偏差。理论上,这有助于创建更可靠的模型,因为极值对总体分布的影响较小。我们使用自适应套索技术和柯西分布建立了一个模型。这计算出 0.408 的广义 R 平方值和 5.347 的显著λ损失。这表明使用柯西的模型对不太重要的变量有更多的限制。
模型比较
建立了 6 个模型后,我们最终可以比较结果,以确定最适合我们的数据。将预测值放入一个比较模型中会稍微改变值,但是我们仍然能够从发现中做出一些决定。我们可以看到,基本的套索和弹性网方法似乎对测试数据具有最高的准确性,R 平方值约为 0.408。最差的模型是我们的标准最小二乘模型,它在测试数据集上几乎没有可靠性。我们的套索和弹性网模型的 RASE 约为 0.0189,AAE 是另一个理想的低值,仅为 0.0149。因此,我们可以假设弹性网或套索方法将给出我们的最佳拟合模型。因为弹性网稍微好一点,我们将使用这种方法进行最终分析。
Comparison of Models
调查的结果
回到我们的基本弹性网络模型,我们可以看到 7 个变量对 RSLV 的预测值有可测量的影响。一些变量涉及国际汇率;RFXF、RFXA、RFXC、RFXS 和 LRFXY 都表明相关国家的货币价值对白银价格有影响。虽然不是特定于一个国家,RTIP 是计算通货膨胀的措施。作为双金属标准之一,难怪如此多的货币因素对预测白银的价值有影响。
Variable Selection via Elastic Net Method
在下图中,我们可以看到按对模型的重要性列出的变量。RFXF,瑞士法郎的价值,解释了超过 35%的预测模型。指示石油价格的 RUSO 通常不会与白银的价值联系在一起。然而,令人惊讶的是,它在这个模型中占了 20.5%。材料行业指数 RXLB 仅排在第三位,约为 18.6%。由于白银在电子产品和其他制成品中的重要性,有理由预计材料指数将是这种金属价值的高度预测指标。
Variable Importance in Elastic Net Model
这项研究中使用的数据集可以在GitHub(silverweekly study . jmp)上找到。
潘德雷肯四:多智能体强化学习与命运大秩序
Three initial characters left to right Jeanne d’arc alter (Jalter), Ishtar, Artoria Pendragon
多代理强化学习在一个定制的游戏环境中训练 4 个代理,并让他们玩手机游戏命运大令
Github 回购此处
一年多前,我在《走向数据科学》上发表了我的第一个系列博客帖子,我亲切地称之为项目潘德雷肯,讲述了我如何建立一个强化学习(RL)环境,成功培训 RL 代理,并为制作了一个 API,允许他们提取信息并向手机游戏《命运大令》(FGO)发送命令。这篇文章将讲述我是如何重新选择这个项目并训练 4 个 RL 代理一起玩这个游戏的。
我为 FGO 建造机器人的一个主要动机是,游戏要求玩家多次通关,以便为事件、关卡角色、技能等收集所需的材料。我说的多次是指 5 分钟 40-50 次,这种情况并不少见。所以能够让一个机器人为我执行这些重复的任务是非常好的。
命运大订单快速汇总
FGO 是一个游戏,你选择 1 到 6 个角色,并使用该团队通过各级战斗,直到所有的敌人或团队被击败。在任何给定的时间点,你可以有 3 个角色在场上,他们每个人都有 3 种能力。这些能力可以是攻击增益,治疗法术等。
Initial combat screen showing three characters with their 3 abilities below their portraits
在 FGO 战斗的主要机制是,战斗是通过从你的牌组中抽取 5 张牌中的 3 张牌来完成的。我之前的 FGO 机器人 pendragon alter 专注于以有效的方式挑选这些卡片。
example of 5 cards being dealt for a round of combat
每种类型的卡都有自己的属性,以不同的组合使用它们有不同的好处。例如,玩三张相同颜色的牌会在基础牌的基础上增加额外的奖励。奖金的性质取决于卡的类型。艺术卡(蓝色)充能强大的终极能力,巴斯特卡(红色)造成额外伤害,快速卡(绿色)创造致命一击的可能性,双倍伤害。我试着解释对这篇文章很重要的游戏机制,但是你也可以看看上一篇文章,更详细地了解组成 FGO 的其他卡片机制。
自从训练了那些最初的捡卡 RL 代理,我没有做太多的工作来增加额外的功能来改善我的机器人或提高他们的游戏水平。然而最近我很受鼓舞去改进它们,因为在过去的一年里 RL 发生了很多有趣的事情。
example round of combat from Pendragon Four where bot 2 plays a skill while bots 1 and 3 choose to pass. The card bot picks cards from the dealt hand. All actions are sent through a custom API to do the combat actions.
启发训练另一轮命运大令机器人
对我来说,看到 OpenAI 和 Deepmind 等研究小组的进展以及他们在将强化学习应用于游戏方面的成功真的很令人兴奋,这些游戏包括 Dota 2 (OpenAI Five)和 Starcraft 2 (Alphastar),它们都达到了极高的游戏水平。虽然他们确实有缺点,但我仍然觉得令人印象深刻。最初,我发现最令人兴奋的是 Alphastar,因为我是星际争霸 2 的长期玩家。然而,通读 OpenAI Five 文献激励我致力于更多的强化学习,目标是对我的 FGO 机器人采取额外的步骤。
当我为 FGO 制作我最初的 RL 代理时,我专注于有效地挑选卡片。这使得我的机器人可以清除大量的游戏内容,但这意味着我没有使用我上面提到的个人角色能力。这些能力非常强大,可以帮助人类玩家更快地成功通关,并清除更难的内容。所以我的想法是,如果我能把能力的使用结合到我的机器人中,这将是有益的。我不确定最好的方法是什么…我陷入了困境,直到我通读了 OpenAI 发布的帖子,这些帖子说明了他们如何训练 5 个独立的机器人,并让它们一起工作来玩。
进入正题
试图让一个代理人处理所有三个角色会造成混乱的行动空间,所以为每个角色训练一个代理人的想法帮助我在心理上简化了它,至少让我考虑开始解决这个问题。虽然我说这帮助我澄清了我头脑中的问题,但它也让我非常认真地考虑在一个我从未做过的环境中同时训练 3 个或者 4 个 RL 代理。
我的想法是有 3 个代理人(三个角色各一个),他们的行动空间是他们可以使用的法术加上一个允许他们通过的节点(行动空间大小为 4)。然后增加一名代理人来挑选卡片。如果我能训练这 4 个代理人合作,那么我很可能能够制造一个 FGO 机器人,它可以清除更难的内容,或者至少比我以前版本的机器人更快地清除内容。
考虑到这个最终目标……完成这个目标需要什么?对我以前的游戏环境做了很多升级,以前的游戏环境只是为了选卡而设计的。
- 初始约束
- 代表字符:
- 环境升级
- 建筑代理
All three bots opt to pass on round 2 turn 3. One of the main things the bots had to learn was when to pass vs when to play skills since they are only allowed to use a skill once per game.
初始约束
虽然我希望能够训练我的机器人在一个完美的 FGO 再造中,拥有所有的角色,技能,敌人等等,但对我来说,建造所有这些是不可行的。即使对于 OpenAI 和 Deepmind 这样的团队来说,看到他们限制游戏的哪些方面以及随着他们构建更复杂的代理,这一列表如何随着时间的推移而变化也总是很有趣。
对于这个版本的多代理 FGO 机器人,我有一些值得注意的限制。
- 我目前只有 3 个角色可用,我用它来进行初始训练和测试。
- 技能可以用,但是每局只能用一次。我没有增加冷却机制来允许机器人多次使用它们。
- 机器人被训练成按照一定的顺序战斗。在培训中,我将代理放在位置 1、2 或 3(视觉上是从左到右),这构成了团队组成的顺序。在未来,我的想法是在地点 1 和 2 放置支援型角色,地点 3 保留给伤害处理角色,这样地点 1 和 2 可以学习支援角色 3。我将在团队合作部分详细讨论这一点。
- 崇高幻象(NPs):是 FGO 中人物拥有的强大终极能力,通常会造成大量伤害。NP 在使用前必须充电到 100%,这在“NP 量表”中进行跟踪。我没有选择何时使用它的机器人。相反,在训练中,我让他们一充电就使用他们的 NPs。
- 机器人必须前后作战:它们不能选择目标,所以它们按照从前到后的顺序与敌人作战。这将使机器人玩某些关卡更加困难,因为更强的敌人通常被放在后面,人类玩家会选择他们并首先集中火力打倒他们,而不是首先杀死他们前面的敌人。
好了,现在让我们开始吧!
Sample turn where 2 bots (Jalter and Ishtar) decide to play skills, one (Artoria) passes and and card bot selects combat cards
代表字符
因为这个项目的主要目标之一是为每个角色添加单独的代理人,让他们作为一个团队一起通关…我首先需要解决的事情之一是如何表现每个角色。这是我去年制作最初的机器人时想做的事情,但当时我是一名非常弱的软件工程师,所以我把它推迟到了以后的日期,我想现在是时候了。
我所做的是设置了一个名为[HeroicSpirit](https://github.com/sugi-chan/multiagent_pendragon/blob/hal_way_to_policy_gradient/fgo_environment/heroic_spirt.py#L72)
的通用类,它包含了代理的神经网络以及获取动作、训练/更新网络、跟踪技能和三个角色技能本身的方法。这个通用类为管理和维护我在游戏中的角色设置了框架,然后我为我想要训练的每个特定角色创建了HeroicSpirit
子类。
在大多数情况下,每个子类只需要调整新角色的特性。这将是像角色特定的技能和能力,而簿记功能在主HeroicSpirit
类中保持。如果我只是添加通用特性,这有助于最小化我需要更改/更新的代码量。
例如,当我开始编写原型代码时,我没有意识到要跟踪主动能力、每个角色当前的伤害调整值,并将这些能力的效果映射到他们应该针对的角色上需要付出多少努力,所以我不得不在HeroicSpirit
上添加许多功能,这在三个地方进行更新会很烦人。
目前我有三个HeroicSpirit
的子类,分别代表三个角色,他们的能力我已经编程出来了JAlter
、Ishtar
、ArtoriaSaber
。对于我之前提到的每个角色来说,他们的技能在游戏效果中的表现是不同的,这是我必须要考虑的。目前,我用一个字典来表示技能,这个字典跟踪各种各样的值,这些值依赖于技能。例如Ishtar
的第一个技能是战斗导向的全队伤害提升,用下面的字典来表示:
{‘name’: ‘sk1_’+self.spot+’_’+self.name+’_manifestation_of_beauty’, ‘target’: [‘hero1’,’hero2',’hero3'],
‘hp_boost’: 0,
‘np_boost’: .00,
‘critical_boost’: .00,
‘critical_star_boost’: .0,
‘dmg_boost’: (‘all’, .2),
‘duration’: 3}
所以对于每一个技能,我都会追踪它的名字,目标,以及各种效果,比如生命值提升,终极充能(np_boost),暴伤提升,暴星提升,伤害提升,持续时间。大多数技能只会对其中的几个领域产生影响,因此对于这个技能来说'dmg_boost': ('all', .2)
意味着 20%的伤害提升会应用到团队中由target
领域['hero1','hero2','hero3']
上的点所代表的每个人身上。'duration': 3
表示技能持续 3 回合。
另一方面,Ishtar
的第二个技能侧重于充能她的终极能力,而不是直接战斗。
{'name': 'sk2_'+self.spot+'_'+self.name+'_gleaming_brilliant_crown', 'target': [self.spot],
'hp_boost': 0,
'np_boost': 50,
'critical_boost': .00,
'critical_star_boost': .0,
'dmg_boost': ('all', .0),
'duration': 1}
因此,虽然所有相同的类别都在技能词典中被追踪,但这个法术只针对Ishtar
她自己,所以目标指向团队中 Ishtar 所在的任何位置,并且没有伤害提升。相反,伊师塔获得她终极能力的 50%充电。这个能力也只能持续一个回合。
我以三个字符开始,因为这是我想尝试并立即开始的最低限度。我之所以从这些角色开始,是因为他们都是以伤害为导向的角色,他们的能力是以战斗为导向的。在这个初始阶段,这有助于我简化我必须建立的东西的数量。未来的工作将是添加支持角色,这些角色的能力通常针对其他团队成员,对于清除游戏中较难的内容至关重要。
这些角色类建立了角色能做什么的框架,一般来说,我们将如何跟踪他们在做什么,所以现在我们必须为他们建立一个游戏环境。
环境升级
为了升级游戏环境,我不得不做很多事情来处理额外的复杂性,比如让每个角色同时激活,追踪 buff 和他们的效果,应用 buff 来修改他们的伤害输出。旧环境大约 400 行代码,新环境大约 1200 行代码。很多只是增加了新的功能来跟踪游戏的各个方面。
这种环境的基本结构是每场游戏由 3 轮战斗组成(反映 FGO 游戏水平),每一轮都变得更加困难,因此第三轮比第一轮要困难得多。在这种环境下,我通过增加机器人必须面对的对手的生命值和伤害来做到这一点。目前我还没有花时间去打造复杂的对手,但这是我将来可能会做的事情。
在我的HeroicSpirit
类中,我有根据环境计算的奖励来采取行动和训练代理的功能。因此,在这个环境中,我需要能够处理这些输出,并将它们应用到游戏本身,并准备好将累积的奖励反馈给机器人。这归结为每个角色的几个步骤。
对于三个字符中的每一个:
- 生成他们的游戏状态和动作。我现在使用的游戏状态是回合数,回合数,一个活跃 buffs 的二进制列表(长度 9)和一个已经使用技能的二进制列表(长度 9)
- 如果他们在那回合没有选择
pass
,那么我就获取那个技能,解析它,将那个技能的效果添加到角色的活动效果列表中。我通过将每个角色拥有的技能存储在一个“爱好者字典”中来追踪它们。因此,如果一个角色施放了一个影响团队中每个人的技能,那么每个角色都会将该技能添加到他们的“buff dictionary”中,以便在计算伤害时可以应用这些修正值。 - 做簿记来记录技能已经被使用,这样机器人就不会试图在冷却时间重复使用技能。
一旦所有的角色都走了,我会检查每个“buff 字典”中的所有 buff,并将每个角色 buff 中的相关修改应用到他们的伤害或其他战斗统计中。一旦这样做了,我就移除不再激活的 buffs,即duration = 0
。在该回合的 buffs 被应用后,我会在游戏中选择战斗部分,如果相关的话,会应用机器人的效果。例如,如果一个角色有一个 20%的伤害缓冲,并且他的卡被选中,那么该卡的伤害将会增加 20%,以此类推。
Bot 1 and bot 3 (Jalter and Artoria) cast skills while bot 2 (Ishtar) passes
构建代理:奖励和无效移动
在我以前做过的 RL 项目中,我使用了深度 Q 学习器,并试图让它在任何给定的游戏状态下所有的动作都有效。然而,在这个项目中,我改用了策略梯度法,并允许无效的移动。这两件事都增加了我代码的复杂性,因为我以前从未实现过这些东西,但我认为它们值得升级。
政策梯度
深度 Q 学习者是代理人,他们的行为每一轮都会得到奖励,他们在任何给定的状态下都在有效地寻找最高的奖励。这是一个很好的方法,但对我来说,它经常需要游戏不同部分的工程奖励,我觉得我必须把我的意志/游戏风格强加给机器人。我仍然用我的拣卡机器人做这件事,它是我和三个角色代理一起训练的。解决这个问题的另一种方法是收集代理的所有动作和游戏状态,一旦游戏结束,就根据输赢之类的东西给小组分配奖励。这就是政策梯度方法的本质(正如我现在所理解的,我可能很容易就错了)。
起初,这似乎是一个有趣的想法,因为即使在亏损的情况下,也可能有好的和合理的举动,但它们将受到负面的惩罚。这是真的!但希望是,如果这确实是一个好的举措,那么随着时间的推移,它将有一个净积极的回报,代理人将学会在某些情况下做得更多。安德烈·卡帕西的 Pong to Pixel 博客在这个话题上非常出色!
目前,我没有对政策梯度使用纯+1 或-1 风格的奖励。如果他们使用了技能,我会在某些回合中使用修正值来尝试和激励技能的使用。对于游戏的大部分来说,机器人只是pass
,这是有道理的,因为它们只有 3 个技能,我只允许使用一次,但游戏可能会持续 10-15 轮。所以他们倾向于习惯于在没有区别奖励的情况下度过大部分时间。
无效移动
接下来要考虑的重要事情是如何处理无效的移动。在这个游戏例子中,无效的移动是已经使用过的技能,现在处于冷却期,如果机器人试图在游戏中选择它,它实际上不会做任何事情。在过去,我通过设定游戏状态来避免这个问题,在游戏状态中,所有的移动在任何给定的时间都是有效的。这里的权衡是行动空间变得比考虑有效移动时要大得多。
例如,在我的拣卡机器人中,动作空间是 60,这代表了你可以从 5 张卡片中挑出 3 张卡片的每一种方式,其中顺序很重要。我这样做是因为虽然 60 的动作空间很大,但所有 60 个动作都是有效的。另一方面,如果我考虑到无效的选择,那么我可以有少至 3 个动作(每种牌类型一个),并让它通过查看它尚未挑选的牌来选择玩哪手牌。
我之所以一直避免这样做,是因为我真的不确定最好的方法是什么/怎么做。当深入研究如何解释无效移动时,我遇到了一个非常有用的堆栈溢出帖子。
“忽略无效动作就好了。”-堆栈溢出
好酷!听起来很简单…
我最后做的是,在训练期间,一旦技能冷却,我会将技能节点的输出抑制到一个较低的数值(数组-1 中最低的数值)。该输出阵列的抑制版本被反馈到网络中作为网络的目标。机器人的游戏状态中也会跟踪哪些技能已经被使用。这里的希望是,机器人将了解它不能选择一个以前使用过的技能。
我认为奖励和无效移动是建造这些机器人的机械部分,所以现在我只需要弄清楚一些更哲学的东西。我要怎么做才能让机器人作为一个团队一起玩?团队合作对一堆神经网络来说意味着什么?
如何教会一个机器人团队合作?
我之前提到过,在阅读了 OpenAI 在过去一年左右的时间里所做的工作后,我受到了启发,试图制作我的下一个 FGO 机器人系列。对我来说,最有趣的部分之一是这个想法,他们可以训练单个的机器人,并让它们作为合作团队一起玩。OpenAI 有一个团队合作参数,可以在 0 到 1 之间调整,较高的值表明机器人应该重视团队奖励而不是最大化自己的奖励。
这让我开始思考如何融入团队合作,或者至少是某种形式的沟通。虽然我考虑过使用另一个总体网络来管理团队合作,但我实际上最终采用了一个非常简单的想法,即让机器人在每个回合都按设定的顺序运行,并且在每个机器人运行后,我修改游戏状态以显示它们采取了什么行动。这里的希望是,机器人将能够根据早期机器人的行动做出更明智的决定。
对于我当前的机器人/环境,游戏状态由两个长度为 9 的数组(每个角色 3 个点)以及回合数和回合数表示。两个长度为 9 的数组是跟踪 3 个机器人动作的数组。第一个数组表示该回合中哪些技能有效,第二个数组表示哪些技能已经施放。在新游戏第一轮的第一回合,这两个数字都是 0。下面是游戏第 1 轮第 1 回合的游戏状态示例。
game_state_og = [Round 1] + [Turn 1] + [0,0,0,0,0,0,0,0,0] + [0,0,0,0,0,0,0,0,0]
这个原始的游戏状态是第一个角色在游戏的第一回合看到的。看到这个阵法后,他们选择使用他们的第一个技能。游戏状态被修改,使得每个数组的第一个元素被设置为 1,因为角色 1 使用了他们的第一个技能,并且该第一个技能当前是活动的。
Character_1_action = skill_1
game_state_1 = [Round 1] + [Turn 1] + [1,0,0,0,0,0,0,0,0] + [1,0,0,0,0,0,0,0,0]
然后我们将这个new_gamestate1
作为输入提供给第二个字符。所以第二个角色可以看到角色 1 使用了一个技能,而且是主动的。基于这些知识,它可以决定是否也要使用一个技能。假设角色 1 使用了技能,角色 2 也跟着使用了技能 3。新的游戏状态如下。
Character_2_action = skill_3
game_state_2 = [Round 1] + [Turn 1] +[1,0,0,0,0,1,0,0,0] + [1,0,0,0,0,1,0,0,0]
角色 1 状态的游戏状态被修改,然后传递给角色 3。
Character_3_action = skill_2
gamestate_3 = [Round 1] + [Turn 1] +[1,0,0,0,0,1,0,1,0] + [1,0,0,0,0,1,0,1,0]
所以角色 3 处于做决定的最佳位置,因为它可以在花费任何技能之前看到角色 1 和 2 做什么,并且它可以与其他两个机器人一起行动。
我希望这种团队合作的框架将允许机器人一起工作,这将出现在游戏中的一种方式是机器人联合使用多种技能。现在我打算把这个特性叫做“ 技能弹幕 ”。
“技能屏障”
在 FGO,很多技能的强大之处在于你可以将它们与其他角色的技能结合使用。将不同的效果叠加在一起,玩家可以放大不同角色的效果,从而大幅增加团队的伤害输出。
目前,我已经训练了代理人来处理这些角色,这意味着他们在放大伤害,但是游戏中最强的伤害增益通常来自于“支持”角色。辅助角色造成的伤害更少,所以他们带来的直接火力比伤害交易者类型的角色要少。他们通过带来强大的技能来弥补这一点,这些技能可以决定一场艰难比赛的成败。
我的想法是在地点 1 和地点 2 放置辅助角色,在地点 3 放置主要伤害处理者。所以当伤害处理者看到两个支持角色已经施放了他们的 buffs,那么角色 3 也会使用一个技能来进一步增加他们的伤害。
下面是三个代理技能弹幕的例子。
skill barrage example. Round 1 Turn 2, all three bots use skills one after another.
培养
我将在这里写一些关于训练模型的一般笔记,但很快会添加一个关于这个主题的更详细的帖子(这篇文章太长了,大多数人都不想看)。
我用 Tensorflow 后端在 Keras 中构建了所有 4 个代理,并在单个 2080 TI GPU 上训练它们。对于那些在 GPU 上使用 Tensorflow 的人来说,Tensorflow 会将所有可用的 GPU 内存分配给任何加载用于训练的模型。在这个管道的以前版本中,我不能同时运行多个 Tensorflow 机器人,这使得内存分配很困难。
最后,我用在网上找到的一段代码绕过了这个管道。基本上,它的作用是将模型可以分配给自己的 GPU 空间限制在某个百分比。我在这里训练的模型实际上非常小,所以我将其限制在我的 GPU 内存的 20%。
# extra imports to set GPU options
import tensorflow as tf
from keras import backend as k
###################################
# TensorFlow wizardry
config = tf.ConfigProto()
# Don't pre-allocate memory; allocate as-needed
config.gpu_options.allow_growth = True
# Only allow a total of 20% the GPU memory to be allocated
config.gpu_options.per_process_gpu_memory_fraction = 0.2
# Create a session with the above options specified.
k.tensorflow_backend.set_session(tf.Session(config=config))
因为我在训练的 4 款车型中的每一款,实际上在我的 2080 TI 上我都进行了多次训练。
经过一些修补,我制作了一个足够硬的游戏环境,可以进行像样的训练,我的第一个版本太硬了,机器人总是输,没有得到多少积极的回报。一旦我把它调到一个合适的水平,我看到 4 个机器人的随机猜测胜率约为 38%,在大约 20-30K 的游戏后会达到 72%左右的峰值。在做了一些额外的工作和大量的实验后,我的成功率达到了 84%左右。
我将在另一篇文章中介绍有趣的细节,因为我已经在这篇文章中写了很长时间了。
Two turns of bots passing while skills are available to play. As I mentioned before, one of the things the bots had to learn to do is pass rather than just use all their skills immediately
结果
一旦完成,我必须更新我以前构建的 API,以允许新的 4 bot 版本点击能力,并从游戏中获得所需的信息。我在我的第一篇 pendragon 帖子中展示了很多最初的框架。
主要思想是,当一个机器人选择使用一个技能时,我记录下技能按钮的位置,并可以使用 python 将鼠标发送到该位置并单击。一旦就位,我就可以开始运行机器人来对抗实际的 FGO 任务,我对结果感到惊喜。
他们相对快速地完成任务,对于一个与他们的环境结构相似的普通任务,他们需要 7-8 次才能完成。相比之下,我认为一个人可以在 5-8 回合内通过这个特定的团队。
关于 bot 行为的一些初步想法:
1\. The bots tend to use most skills early in round 1 and 2
这是我个人认为次优的行为,因为第一轮和第二轮通常比第三轮容易得多。然而,对于机器人来说,未来是不确定的,他们希望确保自己能活到第三轮。
这些机器人以政策梯度的方式接受训练,根据输赢给予奖励。因此,虽然他们可能有很好的机会很快清除第三轮,如果他们保存更多的技能。机器人需要确保它们能活到那个时候。如果他们保存了所有技能,他们甚至可能撑不到第三轮,或者可能在途中受到太多伤害。因此,尽早使用技能并为第三轮保留一些技能似乎是他们使用的更稳定的策略。这让他们可以进入游戏的后期,至少有机会获胜。
2\. The bots do perform skill barrages where 2–3 bots are firing skills together
目前,机器人确实像我希望的那样成功地使用了技能屏障,其中 2-3 个经常一起使用技能。然而,这些技能可能不会一起超级好。例如,一个机器人可能会使用一个技能来增加他们的致命一击伤害,而其他机器人可以搭配其他技能来增加致命一击伤害,他们会做一些事情,如充电自己的 NP 能力或类似的事情。这些技能没有任何真正的协同作用,但机器人一起使用它们。
这可能意味着机器人需要更多的时间来探索游戏环境,或者我所建立的环境对它们来说还不够艰难,不需要那种程度的通信。他们从来没有看到他们的能力做了什么,他们只是看到了来自环境的奖励,基于他们使用后是赢是输。
3\. Bots do still save some skills for the round 3 late game
因此,虽然我抱怨机器人玩 sub 优化,并在早期使用技能,但他们也倾向于在游戏后期保留一些能力。我认为这是机器人意识到清除任务的第一部分是重要的,清除高生命值使他们更有可能获胜。如果他们想赢得一个好的机会,他们仍然需要为最后的战斗保存一些能力。这是一个很好的长期规划,我希望机器人能够学习。
Bot 1 (Jalter) saved a skill for late game which helps to boost the team’s damage in the final round which can often have stronger/harder to kill enemies
结束语
为了达到这一点,训练和部署这些机器人来玩游戏命运大令花了我大约一个月的工作和大量的失败/实验。我的大多数帖子都是基于其他人已经完成的项目,通常可以找到一些松散的文档或建议来遵循。这一次我大部分时间都在忙着解决问题,并经常因为我的不同想法而惹恼我的朋友。
从技术上来说,我以前的机器人可以播放很多 FGO 的内容,我想用机器人来玩。但是,一旦我找到了一种看似合理的方法,我就很难抗拒试图构建远远超过它的机器人的诱惑。我对数据科学有点上瘾,但这并不是一件坏事。
展望未来,我对这个项目有很多目标:
- 为游戏添加支持
- 使用某种多代理框架清除最终游戏内容
- 让潘德雷肯四号被接受为会议演讲/论文,这样我就可以做一个关于视频游戏的技术演讲了。(一个会做梦的男孩)
人们不信任人工智能。我们需要改变这种情况。
The issue of mistrust in AI systems was a major theme at IBM’s annual customer and developer conference, THINK, this year. Image via Ron Poznansky.
在过去的一周里,我有幸参加了 IBM 的年度客户和开发者大会 THINK 并在会上发言,此次大会吸引了 25,000 多名与会者来到旧金山。当然,在一篇简单的博客文章中总结如此规模的事件几乎是不可能的——但我想分享一些在我参加的对话和会议中让我印象深刻的关键观点。尤其是其中一个主题,是我在 THINK 时关注的焦点,那就是我们对人工智能系统的信任问题。
说白了,大部分人都不信任 AI——至少,还没到把它投入生产的程度。经济学人2018 年进行的一项研究发现,94%的企业高管认为采用人工智能对解决战略挑战很重要;然而,麻省理工学院斯隆管理评论在 2018 年发现,只有 18%的组织是真正的人工智能“先驱”,已经在他们的产品和流程中广泛采用了人工智能。这种差距说明了我们在人工智能社区中面临的一个非常现实的可用性问题:人们想要我们的技术,但它在目前的状态下并没有为他们工作。我认为缺乏对谎言的信任是这个问题的主要原因之一。
人们现在还不信任人工智能工具有一些很好的理由。首先,偏见是一个热点问题。最近的 高调的 事件理所当然地获得了媒体的大量关注,帮助让机器学习偏见的概念家喻户晓。组织有理由对实施最终可能产生种族主义、性别歧视或其他偏见的系统犹豫不决。
事情是这样的:人工智能在设计上是有偏见的。正如 Forrester 首席分析师 Brandon Purcell 在我们关于人工智能公平性和可解释性的思考小组讨论中雄辩地指出的那样,机器学习模型被称为“鉴别器”是有原因的。有故意的、必要的偏见——例如,在问答系统中,同行评议的论文比维基百科的文章权重更大——还有无意的、有害的偏见——建立一个无法识别有色人种的面部识别模型。但“不良偏差”是算法决策系统中难以解决的问题,部分原因是我们尚未能从人类决策系统中消除它。我们生活在一个有偏见的世界,充满了有偏见的数据,这些数据会训练出有偏见的模型。
The author (right), Brandon Purcell of Forrester Research (middle), and Rohan Vaidyanathan of IBM (left) discuss AI fairness and explainability at THINK 2019.
除了偏见问题,另一个阻碍信任的关键话题是可解释性——或者说缺乏可解释性。有很多讨论,特别是在 GDPR 生效之后,在理解一个给定的模型如何得出一个个体决策的背景下,关于可解释性的讨论。这种类型的可解释性在更复杂的机器学习系统中很难实现,这些系统采用了“黑盒”技术,如神经网络或 XGBoost 模型。
从监管和伦理的角度来看,这种可解释性是非常重要的。然而,我认为,还有另一个可解释的元素对于建立人工智能模型的信任同样重要,那就是理解人工智能系统影响的能力——能够将模型输出与有形结果联系起来。对机器学习模型进行审计跟踪,对于了解这些模型在一段时间内的表现至关重要。如果没有能力审计他们的模型的功能(并确保一致的利益,或知道在性能下降的情况下何时进行纠正),许多组织将会犹豫是否真正信任任何人工智能系统。
Image via giphy.
在 THINK 上反复出现的人工智能采用的最后一个挑战是许多组织面临的技能差距。在 IBM 的一项 2018 年研究中,63%的受访者认为缺乏技术技能是人工智能实施的障碍。通过我自己与客户的交谈,我了解到大多数组织要么没有专门的数据科学团队,要么他们有一个过度扩展的非常小的团队。据德勤称,根据目前的供需情况,到 2024 年,美国预计将面临 25 万名数据科学家的短缺。
对于没有专用资源的公司,业务负责人最终负责人工智能项目。没有工具来帮助他们理解这些系统实际上是如何工作的,他们很难将实验从实验室带入生产。难怪麻省理工斯隆管理评论的 2018 年研究报告发现,大多数组织——82%的受访者——未能在试点或概念验证项目之外采用人工智能。
所以,人们不信任人工智能——我认为我们作为技术专家的首要任务应该是尽快改变这种情况。有几个原因可以解释为什么对人工智能系统缺乏信任让我如此困扰。首先,我不断回到麻省理工学院斯隆管理学院的研究。在有家公司在大规模采用人工智能方面取得了飞跃——18%的组织被归类为“先驱”这些公司拥有强大的数据科学团队,他们有资源来构建自己的解决方案,以克服我上面提到的三个障碍。在人工智能的帮助下,这些公司将主宰市场。我坚信健康竞争作为客户和员工利益保障的重要性。因此,我想帮助尽可能多的公司跟上变化的潮流。我想确保各种各样的企业能够使用少数大公司已经在利用的相同工具。如果我们不帮助小家伙们信任 AI,他们将被市场整个吞噬。
其次,我担心如果我们不能成功地建立值得广泛信任的模型和系统,我们将永远无法实现 AI 的全部积极潜力(当然;你可以称我为技术理想主义者。我相信人工智能的真正承诺是创造公平的竞争环境——打破数百年来主导市场的规模经济。但是,如果大多数人和组织都不想参与,竞争环境就不可能是公平的。
后面的怀疑论者会很快指出,技术的民主化也产生了许多不好的结果——我意识到,当涉及到广泛采用时,并不全是美好的事情。但我认为,如果我们保持技术的封闭和不透明,坏人造成巨大伤害的风险会更高。如果我们不为每个人提供他们需要的工具来理解人工智能系统,就何时何地使用这些系统做出明智的决定,我们将为那些怀有恶意的人留下更多的空间来利用人们的缺乏理解。
那么我们如何解决 AI 缺乏信任这个迫切的问题呢?它从解决不信任的根源开始。我在 THINK 采访过的人有一些想法。为了解决偏见问题,旨在扩展训练数据以消除盲点的数据集,如人脸数据集中的多样性,是一个良好的开端。像 AI Fairness 360 这样的工具有助于数据科学家识别他们模型中的偏差。检查和缓解来自像算法正义联盟这样的团体的专业知识对于让这些工具有效工作是必不可少的。
The Diversity in Faces dataset includes 10 facial coding methods, offering a jumping off point for researchers working on facial recognition models. Image via IBM Research.
提高人工智能系统易读性的技术也是必须的——我工作的产品 Watson OpenScale 就专注于这个问题。我们特别需要为非技术或半技术受众设计的工具,这些工具以企业主可以理解的语言为人工智能模型带来透明度。智能监管将是推动这些领域工作的关键。欧盟的 GDPR 和即将到来的加州 CCPA 已经要求“算法决策”系统具有更高水平的可解释性。围绕系统中允许的偏差水平的法规可能会推动技术专家开发新的方法来确保人工智能系统的公平性。
对人工智能系统缺乏信任是我们迫切需要解决的更大问题的症状。我们今天拥有的狭义人工智能的技术能力正在迅速发展,比我们管理它们所带来的风险的能力快得多。研究人员已经在开发一些模型,他们担心被恶意使用而不愿分享这些模型。如果人工智能社区今天不把我们的努力集中在解决这项技术的问题上,明天就会有人为我们解决这些问题——以极端的、限制创新的法规的形式,或者,在我看来更糟糕的是,公众对人工智能完全失去信心和否认。
好消息是,我们正在像 THINK 这样的行业活动中讨论人工智能中的不信任问题。在过去的一年中,我看到技术社区围绕偏见、可解释性和易读性等挑战团结起来,这让我充满希望。我希望鼓励技术和非技术利益相关者更广泛地参与这些讨论。这将需要一个村庄来建立每个人都可以信任的人工智能系统。
像你这样的人喜欢这样的东西
推荐引擎的问题是
奥纳坦·海特害怕说出任何道德上模棱两可或伦理上微妙的话。对于商业伦理和道德心理学教授来说,这是一个荒谬的职位。然而,在海德特任教的纽约大学商学院,学生和管理人员已经联合起来,为那些在课堂上遇到政治挑战、道德复杂或其他冒犯性材料的学生开设了一条帮助热线。保证匿名。虽然帮助热线旨在成为一股向善的力量——一个随时为那些在高等学术机构的橡胶路面环境中道德和政治观点受到挑战的学生提供压力的阀门——但这不是撒玛利亚人。电话接线员不是在鼓励听众或志愿者成为朋友,他们是强大的管理者,在 NYU 学术人员的集体头上悬着达摩克利斯。
这条求助热线是海特过去几年一直在研究的一长串社会公正现象中最近的一个。利用他的社会科学工具包和他的道德万花筒,海特试图理解:为什么十几岁的女孩自杀人数创纪录,为什么学生团体如此强烈地反对一些客座演讲人的观点,以至于他们拒绝让其他学生听到他们的观点,为什么他的同事因无意冒犯而被解雇,等等。
正如任何称职的社会科学家一样,海特对这些现象有一套理论。他认为,自 90 年代初以来,西方父母一直处于一种歇斯底里的状态。海特认为,对新思想的过度敏感,对官方认可的保护国的需要,以及自残的可怕北行轨迹,都是反脆弱父母教育的结果。根据 Haidt 的说法,90 年代儿童诱拐率的缓慢攀升跨越了父母与子女比率的下降斜率,这些指标在一个临界点相遇,这是翻转父母养育方式的完美支点。孩子们突然每时每刻都受到监督,生怕装着鸡蛋的篮子会发生什么可怕的事情。
这种长期的泡沫包裹无疑解释了其中一些现象的情感力量。但是根除无人监管的游戏是党派和思想过敏的学院的唯一先决条件吗?难道不应该有其他非父母的力量来塑造孩子的原则和观点吗?
过去,父母们不得不编造出斗鸡眼的诡计来劝阻孩子们不要看电视(这种情况在晚间新闻开始时出现,让孩子们眯着眼,同时带着关切的目光)。现在,对于一个核心家庭来说,如果没有在无聊、紧张、沉默、非喜剧性的蒙太奇、对话等时刻出现的间隙屏幕,共同观看一部电影似乎是不可能的。这种变化的原因是什么?
不可否认,早期的电视是一个吸引注意力的怪物,但它必须变戏法。广播网络按照精心安排的收视率/广告优化轮流运行——从卡通片到肥皂剧,再到新闻和商业节目,带着一个运转良好的美国中产阶级家庭的圆滑。
从 90 年代中期开始,各种各样的设备要么被发明出来,要么价格降低到足以普及互联网接入。台式电脑、笔记本电脑、上网本、智能手机、平板电脑。随着每一代设备的相继出现,家庭关注被打破。挑战现有者的新媒体公司不再需要担心平衡代际娱乐的旋转盘子,而是可以为用户优化——特定屏幕的单一、不可减少的所有者。而且,通过正确的技术组合,他们可以建立一个电视网络的内容供一个人欣赏,他们可以大规模地这样做*。*
但是,一个新生的互联网创业公司如何找到足够多的关于你的信息来代表你建立一个电视网络呢?外推。
对于经常使用现代网络的人来说,你在网站上的几乎每一个动作都会被记录下来,这并不奇怪。浏览量、点击量、点赞数和评论数被制成表格,储存在巨大的数据中心。然而,可能让你震惊的是,利用这些表面事件来获得进一步的细节。你的收入等级、社会地位、婚姻状况、年龄、种族和性别都在统计上相差很远。从这里开始,从数学上很容易找到那些最像你的用户。每一个数据都是高维空间中的一个坐标,每个人都是一个点。你的观看偏好和购买偏好是它们之间距离的假象。
你想看什么,什么会让你参与的问题,可以简化为你和你邻居的内容历史的集合运算。
海特遇到的学生很可能被溺爱,但这不仅仅是父母的错。社会已经将其社会化的责任让给了互联网,却没有意识到每个人的网络都是他们自己的,远非详尽的、隔离的、令人麻醉的熟悉。
普遍的个性化但持续强化已有原则的预期结果会是什么,尤其是当这种个性化在我们的成长阶段开始的时候?
互联网的支持者声称,它的主要好处之一是任何人都有能力为个人表达和创造力构建一个载体,但相反的能力呢?有能力为自己构建一个无底的消费渠道,在这个渠道中,我们的价值观不会受到审视?
这种经验框架不需要那些有抑郁倾向的人在他们的个人互联网上遇到不断增加的负面情绪吗?互联网听起来不像是抑郁发作所表明的认知治疗的完美对立面吗?
部落主义难道不是支配我们醒着的大部分时间里看什么和读什么的数学运算的自然结果吗?未来的几代人将会停留在不妥协的青少年意识形态中,还是我们会找到另一种交流方式?一个统一与和谐的世界,一个超越病毒传播的世界,一个让我们面对自古以来智人就在思考的难题的世界?
垃圾进,垃圾出。
原载于 2019 年 8 月 9 日【https://carldawson.co.uk】*。*
使用深度学习进行人物跟踪
用数据做很酷的事情!
简介
目标跟踪是计算机视觉的一个重要领域。它包括跟踪一个物体的过程,这个物体可以是一个人,一个球或者一辆汽车。对于人物跟踪,我们将从一帧中所有可能的检测开始,并给他们一个 ID。在随后的画面中,我们试图延续一个人的身份。如果这个人离开了相框,那么这个 ID 就会被删除。如果一个新的人出现,他们就用一个新的 ID 开始。
这是一项困难的任务,因为人们可能看起来很相似,导致模型切换 id,人们可能被遮挡,例如当行人或玩家隐藏在其他人后面时,或者物体可能消失并在后面的帧中重新出现。
深度学习让我们在跟踪方面有了惊人的表现。请看下面来自多目标跟踪( MOT 数据集)测试集的视频的深度排序算法的结果。
Pedestrain Tracking through Deep Sort
跟踪的基础
让我们首先回顾跟踪的基础知识。假设我们有帧中所有对象的边界框信息。在现实世界的应用中,我们需要提前进行包围盒检测,因此跟踪器需要与检测器相结合。但是现在让我们假设我们只在跟踪上工作。给定第 1 帧中 ID 的 bbox 信息,我们如何在后续帧中分配 ID?
- 基于质心的 id 分配——最简单的形式是,我们可以通过查看边界框的质心来分配 ID。我们通过计算第 1 帧中每个边界框的质心来做到这一点。在第 2 帧中,我们查看新的质心,根据与先前质心的距离,我们可以通过查看相对距离来指定 id。基本的假设是帧到帧的质心只会移动一点点。只要形心彼此隔开,这种简单的方法就能很好地工作。可以想象,当人们彼此靠近时,这种方法会失败,因为它可能会切换 id
- 卡尔曼滤波器 —卡尔曼滤波器是对简单的基于质心的跟踪的改进。这个博客很好地解释了卡尔曼滤波器。卡尔曼滤波器允许我们根据物体的位置和速度来模拟跟踪,并预测它可能在哪里。它用高斯模型模拟未来的位置和速度。当它接收到一个新的读数时,它可以使用概率将测量值分配给它的预测值,并自我更新。它内存小,运行速度快。由于它同时使用了运动的位置和速度,因此比基于质心的跟踪具有更好的结果。
Kalman Filter — Prediction and Measurement Update
深度排序算法
我喜欢深度排序算法。太直观了。在所有上述数学中,我们人类在跟踪中一直使用的一个基本要素是对边界框的视觉理解。我们不仅根据距离、速度,还根据那个人的长相来追踪。深度排序允许我们通过计算每个边界框的深度特征并使用深度特征之间的相似性来添加该特征,从而也将该特征纳入跟踪逻辑。
我们如何计算深层特征?
本文使用在数百万幅人类图像上训练的模型,并为每个包围盒提取 128 维向量,该向量应该捕获该包围盒的关键特征。使用深度特征可以使该模型在人们遮挡或非常靠近的情况下更好地跟踪,如下图所示。
Tracking with Deep Sort
总的来说,我们的实验表明深度排序算法工作得非常好,但它也有一些限制:
- 如果边界框太大,过多的背景被“捕获”在特征中,降低了算法的有效性
- 如果人们穿着相似就像体育运动中发生的那样,会导致相似的特征和身份转换
结论
跟踪是计算机视觉中的一个重要问题,有着广泛的应用。深度排序算法非常强大,运行速度很快,对于许多情况来说是一个很好的起点。他们的回购写得非常好,很容易尝试。我鼓励你拿出他们的代码来试一试。
我有自己的深度学习咨询公司,喜欢研究有趣的问题。我已经帮助许多初创公司部署了基于人工智能的创新解决方案。请到 http://deeplearninganalytics.org/的来看看我们吧。
你也可以在https://medium.com/@priya.dwivedi看到我的其他作品
如果你有一个我们可以合作的项目,请通过我的网站或 info@deeplearninganalytics.org 联系我
参考
用机器学习跟踪人
检测客户习惯,跟踪他们的活动
Photo by sydney Rae on Unsplash
你的窗户有效地吸引人吗?对于购物者来说,你的商品有多少是容易买到的?如果你是一个心胸开阔的小杂货店老板,或者如果你是一家服装店的视觉采购员,你需要知道这些是人工智能可以帮助回答的典型问题。零售商不仅采用人工智能解决方案来改善客户体验,还直接增加了他们的业务。这样,一个恰当的问题可以是:一家特定的商店将户外人流转化了多少?
需要同时评估营销效果和总服务成本之间的完美权衡,以影响消费者行为并实现成本优化。在这种情况下,人工智能解决方案似乎代表了一种高价值的可能性。
在这篇文章中,我制作了一个有趣的应用程序,旨在跟踪商店里的人,并关注他们的历史活动,以检测他们的行为。随着机器学习和计算机视觉技术的实际发展,我们手中有大量强大的工具来完成像这样的任务,并且表现出色……你不需要重新发明轮子,你需要知道如何使用轮子来让你的汽车变得更好。
数据集
对于这个特殊的挑战,我们不需要带有标记数据的数据集,也就是说,我们使用已经在类似领域中专门化的预训练模型。我们的能力是正确地使它们适应我们感兴趣的情况。人物检测是计算机视觉中的一个经典应用领域,许多模型被训练来区分这个标准类别,取得了很高的性能。
我们只需要找到有意义的数据来测试我们的方法。我想找到显示固定商店布局内购物者活动的视频格式的数据。安全摄像头视频非常适合这个目的!它们是网络上容易获得的资源,反映了我们需要一个“老大哥”来监视店内的一切。我在 YouTube 上找到了我们实验的合适人选,并把它们下载到了我的电脑上。
这些视频是一个离散的质量,并没有那么沉重(平均 3 分钟),所以他们对我们来说是完美的!
Shop Layouts extracted from videos. These videos are available on YouTube. From left: Video1 (1 minute), Video2 (6 minutes), Video3 (3 minutes)
模型
为了完成我们的任务,我选择了 ImageAI 库 。这个开源项目使每个人都能够轻松地将最先进的人工智能功能集成到我们新的和现有的应用程序和系统中。通过几行代码,您可以访问一系列用于图像预测和对象检测的最先进的机器学习算法。所有的脏活(预处理、模型查询、输出结果……)都已经为我们做好了,并且活在幕后。
那么,我们的工作已经完成了吗?幸运的是,还没有…附加值是由我们构建的智能工作流直接提供的,它能够回答我们臭名昭著的问题。
工作流程
我们有 mp4 格式的原始视频;作为我们行动计划的第一步,我们必须将视频转换成图像。这很容易,只需从原始视频中以固定的给定频率采样帧即可实现。在 python 中:
def extract_frames(video_path, fr=12):
frames = []
cap = cv2.VideoCapture(video_path)
total_frames = cap.get(cv2.CAP_PROP_FRAME_COUNT)
id_frame = 0
while id_frame<=total_frames:
cap.set(1, id_frame)
success, frame = cap.read()
if type(frame) != type(None):
frames.append(frame)
id_frame+=fr
return frames
我将频率速率(fr)固定为 12:即,如果给定视频的频率为每秒 30 帧,我们每秒收集一帧,这是跟踪人的一个很好的近似值。
第二阶段,我们初始化所有的 ImageAI 工具。只有几行,我们可以访问非常强大的预训练对象检测模型。
detector = ObjectDetection()
detector.setModelTypeAsTinyYOLOv3()
detector.setModelPath("yolo-tiny.h5")
detector.loadModel()
custom_objects = detector.CustomObjects(person=True)
我选择了微小的 YOLO 来进行对象检测(很容易从 h5 格式的 ImageAI 文档页面下载),因为它允许在性能和速度之间进行很好的权衡。这个网络运行良好,所有的工作流程能够在不到一秒的时间内处理一帧图像!
有趣的部分来了。我们必须将我们收集的数据(来自视频的图像)转化为对我们有用的东西:它同时易于理解,并且包含有价值的信息。完美的选择是热图表示,它允许我们赋予我们从人员检测任务中存储的信息以价值。如果还不清楚,让我来画…
由于 ImageAI 的强大功能,这可以通过一种非常优雅的方式实现:它们的检测器返回检测到的对象以及相关的边界框坐标作为输出。对于人来说,我们只提取盒子的底部,以提供一个可解释的重叠信息和商店的平面图。有了这些容易获得的结果,我们可以构建一个以热图表示形式的频率图(在右侧与商店地图重叠)和一个路径掩码(在左侧)。为了给予进一步的可解释性,我们排除了帧的底部部分:这些区域受到“错误检测”的影响,即我们的模型太聪明了,并且识别出人也具有破坏热图计算的半个身体。
这些结果告诉我们购买者遵循的路线以及他们会在哪里停留更长时间。
“最热区域”是人们更加关注的地方。在最长的视频中(我最近处理的两个),这些区域立刻就清晰了!现在想象一下,如果有更多的视频资料供我们使用,我们能够检测到多少客户行为?
摘要
在这篇文章中,我制作了一个计算机视觉解决方案来跟踪商店里的人。人物检测是机器学习中的一项综合性任务,因此我们试图将这一知识(具有相对较高的性能)应用于不同的领域。给定一个显示正常购物程序的视频,我们能够检测购物者的行为和路径。这些是每个零售商的黄金信息,以便以不同的方式改善他们的业务:商品展览,商店布局,员工效率,库存水平等等。
保持联系: Linkedin
愚人节 2019:感知驱动的数据可视化
利用最强大的心理学技术探索 OKCupid 数据以加速分析
本文为 2019 年愚人节恶作剧。既然庆祝活动已经结束,请滚动到文章末尾的真实课程部分,进行一分钟真正的学习。
进化赋予了人类一些非凡的能力,从直立行走到操作重型机械,再到高效的在线择偶。
人类已经进化出快速处理人脸的能力,你可以使用感知驱动技术来加速你的分析。
其中最令人印象深刻的是我们感知面部结构和表情微小变化的能力,因此数据科学家已经开始利用我们与生俱来的超能力来获得更快、更强大的数据分析。
进化驱动的数据分析
准备好被令人难以置信的新分析技术震撼吧!
切尔诺夫的脸以优雅和清晰而著称,通过利用人类最擅长的面部识别来传达信息。
Chernoff faces 背后的核心思想是,每个面部特征都将映射到数据的一个属性。更大的耳朵意味着什么,微笑、眼睛大小、鼻子形状等等也是如此。我希望你看到它的运行会很兴奋!
让我们用 OKCupid 数据来看一个现实生活中的择偶例子。
数据处理
我首先下载了一个数据集,里面有近 60K 个泄露的 OKCupid 个人资料,你可以在这里找到来跟进。真实世界的数据通常是杂乱的,在对您的数据科学目标有用之前,需要进行大量的预处理,这也是事实。例如,他们有大量认真的和 100%可靠的自我介绍文章,所以我做了一点快速过滤,把我的数据集浓缩成与我相关的东西。我用了 R 我发现最有用的函数是 grepl() 。
首先,因为我住在纽约,所以我过滤掉了 17 个我附近的资料。接下来,我清理了数据,以显示我最在意的特征。例如,我是水瓶座,占星学上的相处显然很重要,同样重要的还有对猫的热爱和在进行灵魂对话的意愿。
在第一个预处理步骤之后,我的数据集看起来是这样的:
下一步是将字符串转换成数字,这样 Chernoff face 代码就能正常运行。这是我将从 R 的 aplpack 包中提交到 faces() 函数中的内容:
下一步,魔术!
露出的面孔
现在我们的数据集已经准备好了,让我们运行我们的 Chernoff faces 可视化!哒哒。
下面是如何阅读的简便指南。这难道不令人惊讶的优雅和如此迅速地看到到底发生了什么吗?比如最大的脸是最高最老的人,而微笑者会给我唱甜甜的 C++ 十四行诗。很容易在一瞬间看到这一切。人脑真是不可思议!
数据隐私问题
不幸的是,通过认知机器深度学习所有这些面孔,我们正在侵犯 OKCupid 用户的隐私。如果你仔细观察并记住这些图像,你也许能从人群中挑选出他们。小心那个!在向你的老板展示这些强有力的图像之前,确保你通过在一个不相关的数据集上重新运行代码来重新匿名化你的结果。
日期和约会
切尔诺夫脸?!你真的应该检查出版日期,尤其是在四月初的时候。当这位顽固的统计学家提到占星术时,我希望你已经开始怀疑了,并且在我说到去匿名化的废话时,你已经确定了。
我爱你,无论是哪个恶作剧者转发给你的。❤
真正的教训
我总是被切尔诺夫的面孔逗乐(并渴望找个借口与你分享一些我最喜欢的分析琐事),尽管我从未真正见过他们在野外发挥作用。尽管这篇文章是为了搞笑,但也有一些真正的教训要吸取:
- 期望花时间清理数据。 虽然最终的可视化只需要击几个键就可以实现,但我的大部分工作是准备要使用的数据集,你应该会在自己的 数据科学 冒险中看到这一点。
- 数据可视化不仅仅是 直方图 。当谈到如何呈现数据时,有很大的创造性空间,尽管并不是所有的东西都会在一个易于初学者使用的包中实现。虽然你可以通过 R 只使用单一的函数 faces(数据)来获得 Chernoff faces,但是如果你觉得有创意并且愿意在图形方面付出努力,那么天空就是极限。如果你追求最深刻的自我表达,你可能需要像 C++这样的东西。
- 与我相关的东西可能与你无关。我可能关心爱猫,你可能关心别的。分析只对其预期的目的有用,所以如果你继承了别人的数据集或报告,要小心。可能对你没用,或者更糟,误导。
- 没有正确的方法来呈现数据 ,但是考虑 viz 质量的一种方法是理解速度。这些面孔不能有效地将信息传递到你的大脑中——你可能不得不去查阅桌子来弄清楚你在看什么。当你为现实做分析时,这是你想要避免的。
- 切尔诺夫的面孔在被发明 的时候听起来才华横溢,同样的道理,“认知”这个和那个在今天听起来才华横溢。不是所有让你内心深处的诗人发痒的东西都是好主意……当论点诉诸进化论和人类大脑时,要格外警惕逻辑的跳跃。不要忘了在你把神奇的东西运用到你的业务中之前,先测试一下 数学。
如果你想试着自己创造这些面孔,这里有一个教程。如果你更喜欢读我的一篇关于数据可视化的直白的文章,试试这篇文章。
Chernoff face visualization explained on Wikipedia.
感谢阅读!人工智能课程怎么样?
如果你在这里玩得开心,并且你正在寻找一个为初学者和专家设计的有趣的应用人工智能课程,这里有一个我为你制作的娱乐课程:
Enjoy the entire course playlist here: bit.ly/machinefriend
喜欢作者?与凯西·科兹尔科夫联系
让我们做朋友吧!你可以在 Twitter 、 YouTube 、 Substack 和 LinkedIn 上找到我。有兴趣让我在你的活动上发言吗?使用表格联系。
线性分类的感知器算法
了解感知器算法是如何工作的,以及它们背后的直觉。
基本感知器算法是由参考文献 1 在 20 世纪 50 年代末首次提出的。这是一个用于监督学习的二元线性分类器。二元线性分类器背后的思想可以描述如下。
其中 x 为特征向量, θ 为权重向量, θ 为偏差。符号函数用于区分x 是正(+1)还是负(-1)标签。存在用不同标签分离数据的决策边界,这发生在
决策边界将超平面分成两个区域。在θ⋅x+θ₀>,的区域,数据将被标记为正,在 θ⋅ x + θ ₀ <的区域,数据将被标记为负。如果一个给定数据中的所有实例都是线性可分的**,则对于每第 i 个数据点,存在一个 θ 和一个 θ ₀,使得 y⁽ⁱ⁾(θ⋅x⁽ⁱ⁾+θ*)【t100,其中 y⊙***
图 1 用二维情况说明了上述概念,其中x=[x₁x₂]ᵀ、θ=[θ₁θ₂】和 θ ₀是偏移标量。请注意,边距边界与正则化相关,以防止数据过度拟合,这超出了这里讨论的范围。**
Figure 1. The concepts of binary linear classifier with the 2-D case.
感知器
找到决策边界的一种方法是使用感知器算法。只有当决策边界错误分类数据点时,感知器算法才会更新 θ 和 θ ₀。算法的伪代码描述如下。
**# Perceptron Algorithm**# initialize θ and θ₀ with 0*
θ = 0 (vector)
θ₀ = 0 (scalar)*# totally T epoches to iterate*
for t = 1 .. T do
* # totally m data points*
for i = 1 .. m do
*# misclassify data points*
if y⁽ⁱ⁾(θ ⋅ x⁽ⁱ⁾ + θ₀) ≦ 0
then
θ = θ + y⁽ⁱ⁾ ⋅ x⁽ⁱ⁾
θ₀ = θ₀ + y⁽ⁱ⁾return θ, θ₀*
感知器算法遍历所有带标签的数据点,并相应地更新 θ 和 θ ₀。更新规则背后的直觉是将 y⁽ⁱ⁾(θ⋅x⁽ⁱ⁾+θ₀)推得更接近一个正值,如果 yθ≡xθ≦**
感知器收敛
构成感知器算法所犯错误数量界限的因素是数据点的最大范数和正负数据点之间的最大差值。感知器收敛定理已在参考文献 2 中得到证明。给定一组通过原点可线性分离的数据点, θ 的初始化不会影响感知器算法最终收敛的能力。
迭代次数 k 具有有限值意味着一旦数据点通过原点是线性可分的,无论 θ 的初始值是什么,感知器算法最终都会收敛。这些概念也代表了 θ ₀.的存在
然而,一旦数据点是线性不可分的,这种感知器算法可能会遇到收敛问题。有两种感知器算法变体被引入来处理这些问题。一个是平均感知器算法,一个是 pegasos 算法。
平均感知器
与感知器算法类似,平均感知器算法使用相同的规则来更新参数。然而, θ 和 θ ₀的最终返回值取每次迭代中 θ 和 θ ₀的所有值的平均值。算法的伪代码描述如下。
***# Average Perceptron Algorithm**# initialize θ, θ₀, sum_θ, sum_θ₀, and counter with 0*
θ = 0 (vector)
θ₀ = 0 (scalar)
sum_θ = 0 (vector)
sum_θ₀ = 0 (scalar)
counter = 0*# totally T epoches to iterate*
for t = 1 .. T do
*# totally m data points *
for i = 1 .. m do
*# misclassify data points *
if y⁽ⁱ⁾(θ ⋅ x⁽ⁱ⁾ + θ₀) ≦ 0
then
θ = θ + y⁽ⁱ⁾ ⋅ x⁽ⁱ⁾
θ₀ = θ₀ + y⁽ⁱ⁾ sum_θ = sum_θ + θ
sum_θ₀ = sum_θ₀ + θ₀
counter = counter + 1return (sum_θ/counter), (sum_θ₀/counter)**
佩加索斯
pegasos 算法具有超参数 λ ,为要调整的模型提供了更大的灵活性。无论数据点是否分类错误,都会更新 θ 。详情见参考文件 3。算法的伪代码描述如下。
***# Pegasos Algorithm**# initialize θ, θ₀, and counter with 0*
θ = 0 (vector)
θ₀ = 0 (scalar)
counter = 0*# totally T epoches to iterate*
for t = 1 .. T do
* # totally m data points *
for i = 1 .. m do
counter = counter + 1
η = 1/√counter
if y⁽ⁱ⁾(θ⋅x⁽ⁱ⁾ + θ₀) ≦ 1
then
θ = (1 - ηλ)θ + ηy⁽ⁱ⁾⋅x⁽ⁱ⁾
θ₀ = θ₀ + ηy⁽ⁱ⁾
else
then
θ = (1 - ηλ)θ
θ₀ = θ₀return θ, θ₀**
可视化感知器算法
图二。通过不同的感知器算法可视化决策边界的更新。请注意,给定的数据是线性不可分的,因此感知器算法绘制的决策边界会发散。平均感知器算法和 pegasos 算法都很快达到收敛。pegasos 算法的 λ 在这里使用 0.2。
Figure 2. Updating the decision boundaries by the different perceptron algorithms. May take time to load.
示例代码
在 Jupyter 笔记本上写的感知器算法的样本代码可以在这里找到。你可以自己处理数据和超参数,看看不同的感知器算法表现如何。
参考
[1]
F.罗森布拉特,“感知机:大脑中信息存储和组织的概率模型”,《心理评论》,1958 年。土井: 10.1037/h0042519**
[2]
米(meter 的缩写))Mohri 和 A. Rostamizadeh,“感知机错误界限”, arxiv ,2013 年。https://arxiv.org/pdf/1305.0208.pdf
[3]
南 S.-Shwartz、Y. Singer、N. Srebro 和 A. Cotter,“Pegasos:SVM 初始估计次梯度求解器”,数学规划,2010 年。doi:10.1007/s 10107–010–0420–4