TowardsDataScience-博客中文翻译-2019-三-
TowardsDataScience 博客中文翻译 2019(三)
原文:TowardsDataScience Blog
协议:CC BY-NC-SA 4.0
我的数据之路
原文:https://towardsdatascience.com/a-bit-about-me-7b8b46bbf022?source=collection_archive---------20-----------------------
大家好,我是 Jack,我是他们数据科学团队中一名投资经理的替代数据侦察员,我对所有数据/ML/techy 方面的东西都充满热情。
This is me, looking decidedly data-sciency, beard included.
话虽如此,这对我来说还是相当新鲜的,因为当我加入目前的团队时,我才真正开始了解这方面的事情。
关于我的前数据热
我在达勒姆大学(Durham)主修土木工程,2015 年毕业,一直以来,我都更喜欢数学方面的东西,而不是工程方面。
我从大学一毕业就攻读了 IMC(投资管理证书),并设法在新兴市场股票投资部门找到了一份工作,担任基金管理助理。虽然这给了我积极基金管理过程中的良好基础,以及学* CFA 资格(特许金融分析师)的能力,但我很快意识到实施基金经理交易,监控基金的现金流等。不适合我,所以我开始找别的地方。
幸运的是,新兴市场股票部门正对着一群自称数据科学家的年轻“书呆子”(这个词是一种喜爱,绝对不是一种侮辱)。通过与团队中几个人的小互动,我开始了解一些他们的工作——利用数据帮助基金经理/分析师做出更好的投资决策。起初,我认为这是一种不会持续很久的时尚,但我对这个行业研究得越多,我就越意识到这些人说得有道理——这无疑是这个行业的发展方向。
然后我决定这是适合我的地方,所以开始尝试与团队中的一些人一起喝咖啡,以 a)更多地了解他们,b)看看他们是否有任何职位空缺……经过几次交谈,我发现他们确实有一个空缺,作为一名数据侦察员。
我以前从未听说过数据侦察兵,也不知道这是否是一个真正的工作角色——听起来有点像这样:
Image: Cognizant
但是我还是决定去尝试一下,因为它听起来确实很有趣。
然后我参加了一个预面试,我必须承认这是我一生中最奇怪的经历之一。我被邀请去一家酒吧“聊天”,聊我自己和团队,以及我的工作角色,所以我立刻认为这是一次相当普通的聊天——我谈论我的简历、我学*的动力、我对工作的兴趣,然后他们谈论团队、工作并回答任何问题等。我手里拿着啤酒,在接下来的一个半小时里经历了一系列的思想实验,这些实验被精心制作成类似于团队每天所做的工作。不打算说谎,这让我有点吃惊——我不*惯在这种情况下被激烈地询问我的统计学和数据分析知识。
我获准去申请,经过四次面试和一次案例研究后,我得到了这份工作。这是 2017 年 1 月。
数据热来袭
我现在是一名经验丰富的“数据侦察员”,我在面试过程中了解到,他负责寻找新的、有趣的数据集,我们的团队可以用这些数据集来产生投资见解。在过去的几年里,我肯定参加了成百上千的会议,这些公司声称能够提供几乎任何数据,从中国的石油储量到撒哈拉以南非洲的降雨量。这些会议让我对外面的大量数据大开眼界,我现在坚信这是投资管理/对冲基金行业的前进方向。
编程;编排
换个话题,我一直知道我会对编程感兴趣,但是从来没有真正地 a)费心去学*或者 b)设法克服进入环境设置过程这一重要障碍。我在大学里学过一点,主要是 C 语言,但由于我非常忙碌的工程学生时间表的性质,我只学到了足够做我导师设定的项目。
在基金管理助理的工作中,我曾与 VBA 打过交道,构建了几个宏来帮助自动化办公桌工作的各个部分,但对 Excel 随机冻结、关闭以及通常不以非常文明的方式行事的能力,我一直感到沮丧。
然而,当我第一次发现 Python 时,我就被迷住了。它似乎比 C 语言简单得多——一切似乎都有意义,也比 VBA 强大得多。如果你想画点什么,你可以导入一个库,然后输入。plot()"位于要绘制的数据集的末尾。如果您想要加载一个 csv 数据集,您可以导入一个包并键入”。read_csv()”。这是一个完全的游戏变化,至少对我来说。
我开始参与回答我们的分析师/基金经理的一些要求,这些要求需要基本的编码,通常是结合使用 youtube 上由sendex(【https://www.youtube.com/user/sentdex】T2)提供的教程和之前编写的代码。这些通常涉及网络抓取各种指标(价格,日期,数量等)。)来自各个站点。虽然大多数人认为这相当枯燥乏味,但我认为这是我学*数据获取和数据清理基础知识的好方法,因为来自网站的数据很少是干净的。
正是 Python 的这一发现重新点燃了我对学*/构建事物的热情,这种热情最初将我推向了土木工程的道路——我想我也在做同样的事情,但构建虚拟的事物而不是物理结构。
然后我进入了更难的网络抓取——使用 Chrome 中的开发者面板拦截网络流量,使用 selenium 抓取涉及 javascript 的网站。这提高了我对包装的熟练程度,如美丽的 Soup,熊猫,Numpy 和 Requests,还有 Selenium。2018 年 9 月,在通过 CFA 期末考试后,我决定更进一步,报名参加一位同事向我推荐的大会兼职数据科学课程。
该课程包含四个主题,包括设置(anaconda、git、基本命令行等。)、python 基础、统计学和机器学*,以及一个将在 10 周内完成的项目。我学到了很多东西,特别是在机器学*领域,我之前对它知之甚少,并在 Tinder data 上制作了一个我非常自豪的项目(你可以在这里看到相关报道:https://medium . com/@ jackcballinger/my-friends-give-me-their-Tinder-data-7 fcd 2621 c 140)。
自从课程结束后,我觉得有必要一直有某种项目,以避免变得焦躁不安。迄今为止,这些措施包括:
- 完成火绒项目的撰写
- 用 AWS/flask/html/css/javascript 从零开始建立自己的网站,这些我都没有任何经验
- 为我的银行交易构建一个简单的随机森林分类器来监控支出
- 类似的东西,但看我的净资产(包括一个人所有的各种账户),以及使用晨星数据复制投资业绩
- 构建一个right move/zoopla scraper来监控特定搜索标准内的公寓,目的是对数据进行各种分析,例如价格如何根据与特定车站的距离而变化
我计划在接下来的几周写下这些,但是如果任何人对有趣的项目有任何其他想法,请让我知道!
自动语音识别简史
原文:https://towardsdatascience.com/a-brief-history-of-asr-automatic-speech-recognition-95de6c014187?source=collection_archive---------9-----------------------
这一刻已经到来很久了。语音识别背后的技术已经发展了半个多世纪,经历了几个充满希望和失望的时期。那么是什么改变了 ASR 在商业应用中的可行性呢?早在我们听说 Siri 之前,这些系统究竟能完成什么?
语音识别的故事是关于不同方法的应用和原始技术的发展,尽管两者有着千丝万缕的联系。在几十年的时间里,研究人员会设想出无数种剖析语言的方法:通过声音、通过结构——以及通过统计。
早期
人类对识别和合成语音的兴趣可以追溯到几百年前(至少!)——但直到 20 世纪中叶,我们的祖先才建造出可识别的 ASR。
1961 年 — IBM 鞋盒
在最早的项目中,有一个名为 Audrey 的“数字识别器”,是贝尔实验室的研究人员在 1952 年发明的。奥黛丽可以通过寻找被称为共振峰的音频指纹来识别口头数字,共振峰是声音的精华。
20 世纪 60 年代,IBM 开发了 Shoebox——一个可以识别数字和算术命令,如“加”和“总数”的系统。更好的是,Shoebox 可以将数学问题传递给加法机,由加法机计算并打印出答案。
与此同时,日本的研究人员建造了能够识别元音等语音成分的硬件;其他系统可以评估语音的结构,以找出一个单词的结尾。英国大学学院的一个小组通过分析音素(一种语言的离散声音)可以识别 4 个元音和 9 个辅音。
但是,尽管该领域正在逐步向前发展,但前进的道路并不一定清晰。然后:灾难。
【1969 年 10 月——美国声学学会杂志
刺骨的寒冷
转折点出现在约翰·r·皮尔斯 1969 年写的一封信中。
皮尔斯早已成为国际知名的工程师;在其他成就中,他创造了晶体管这个词,并帮助发射了第一颗通信卫星 Echo I。到 1969 年,他已经是贝尔实验室的一名主管,该实验室在语音识别的开发方面进行了大量投资。
在《美国声学学会杂志》上发表的一封公开信中,皮尔斯表达了他的担忧。皮尔斯引用了二战和史泼尼克人造卫星后“繁荣”的资金环境,以及缺乏问责制,告诫该领域缺乏科学严谨性,声称有太多的野生实验正在进行:
“我们都相信语言科学是可能的,尽管在这个领域里像科学家一样行事的人和看起来像科学的结果很少。”皮尔斯,1969 年
皮尔斯说到做到,他资助了贝尔的 ASR 项目,直到 1971 年他辞职后才恢复。
进展仍在继续
令人欣慰的是,其他地方有更多的乐观情绪。20 世纪 70 年代初,美国国防部高级研究计划局(ARPA)资助了一项名为语音理解研究的五年计划。这导致了几个新的 ASR 系统的诞生,其中最成功的是卡耐基梅隆大学的哈佩,到 1976 年,它可以识别 1000 多个单词。
与此同时,IBM 和美国电话电报公司贝尔实验室的努力将这项技术推向了可能的商业应用。IBM 在办公室通信的背景下优先考虑语音转录,而贝尔关注的是“命令和控制”场景:我们今天知道的语音拨号和自动电话树的前身。
尽管有了这些进步,到 20 世纪 70 年代末,除了高度特定的用例之外,ASR 离可行还有很长的路要走。
这也让我头疼。
80 年代:马科夫和更多
一个关键的转折点出现在 20 世纪 80 年代中期隐马尔可夫模型 (HMMs)的普及。这种方法代表了“从基于模板和光谱距离测量的简单模式识别方法到语音处理的统计方法”的重大转变,这转化为准确性的飞跃。
自 20 世纪 60 年代末以来,语音识别系统的很大一部分改进归功于这种统计方法的强大功能,以及实现 hmm 所需的计算机技术的进步。
HMMs 席卷了整个行业——但它们并非一夜成名。Jim Baker 在 20 世纪 70 年代早期在 CMU 首次将它们应用于语音识别,而 Leonard E. Baum 在 60 年代已经描述了模型本身。直到 1980 年,杰克·弗格森在国防分析研究所做了一系列富有启发性的讲座,这项技术才开始更广泛地传播。
HMMs 的成功验证了 IBM 沃森研究中心(Watson Research Center)的弗雷德里克·耶利内克(Frederick Jelinek)的工作,他自 20 世纪 70 年代初以来一直主张使用统计模型来解释语音,而不是试图让计算机模仿人类消化语言的方式:通过意义、句法和语法(当时的常用方法)。正如耶利内克后来所说:“飞机不会拍打翅膀。”
这些数据驱动的方法也促进了与行业协作和责任相关的进步,就像个人的灵光乍现一样。随着统计模型越来越受欢迎,ASR 领域开始围绕一套测试进行合并,这将提供一个标准化的基准来进行比较。共享数据集的发布进一步鼓励了这一点:研究人员可以使用大型数据集来训练和测试他们的模型。
换句话说:最终,有了一种(不完美的)方法来衡量和比较成功。
【1990 年 11 月,信息世界
消费者可用性—90 年代
不管是好是坏,20 世纪 90 年代以我们今天认可的形式向消费者介绍了自动语音识别。Dragon Dictate 于 1990 年推出,售价高达 9000 美元,宣传一本 80000 字的词典和自然语言处理等功能(见上文信息世界文章)。
这些工具很费时(文章声称并非如此,但 Dragon 因提示用户“训练”听写软件适应自己的声音而出名)。它要求用户用生硬的方式说话:Dragon 最初一分钟只能识别 30-40 个单词;人们说话的速度通常比这快四倍。
但它的运作足够好,让 Dragon 成长为一家拥有数百名员工、客户涵盖医疗保健、法律等领域的企业。到 1997 年,该公司推出了 Dragon NaturallySpeaking,它能以更流畅的速度捕捉单词,售价 150 美元,价格低得多。
即便如此,抱怨声可能和高兴的尖叫一样多:就今天消费者对 ASR 的怀疑程度而言,一些功劳应该归于这些早期产品的过度热情的营销。但是,如果没有行业先驱詹姆斯和詹妮特·贝克(他们在 1982 年创建了龙系统公司)的努力,ASR 的产品化可能需要更长的时间。
【1993 年 11 月, IEEE 通信杂志
语音识别何去何从——续集
在 J.R. Pierce 的论文发表 25 年后,IEEE 发表了题为语音识别何去何从:下一个 25 Years⁵ 的后续文章,作者是贝尔实验室(Pierce 工作的同一家机构)的两名资深员工。
后一篇文章调查了大约 1993 年该论文发表时的行业状况——并作为对原文悲观主义的一种反驳。其要点包括:
- 皮尔斯信中的关键问题是他的假设,为了让语音识别变得有用,计算机需要理解单词的意思。鉴于当时的技术,这是完全不可行的。
- 从某种意义上来说,皮尔斯是对的:到 1993 年,计算机对语言的理解还很贫乏——到了 2018 年,它们仍然不擅长辨别意思。
- 皮尔斯的错误在于他没有预见到语音识别的无数用途,即使计算机不知道单词的实际意思。
《T2 向何处去》续集以一个预测结尾,预测了 1993 年以后 ASR 将走向何方。这一部分用厚颜无耻的模糊限制语表达(“我们自信地预测,这八个预测中至少有一个会被证明是不正确的”)——但它仍然很有趣。在他们的八个预测中:
- 到 2000 年,更多的人将通过语音对话获得远程信息,而不是通过在计算机键盘上键入命令来访问远程数据库
- “人们将学会改变他们的讲话*惯以使用语音识别设备,就像他们改变讲话行为以在应答机上留言一样。即使他们将学*如何使用这项技术,人们还是会抱怨语音识别器。”
黑马
在本系列的下一期文章中,我们将探索自动语音识别的最新发展和当前状态。剧透:神经网络扮演了主角。
但是神经网络实际上和这里描述的大多数方法一样古老——它们是在 20 世纪 50 年代引入的!直到现代时代的计算能力(以及更大的数据集)才改变了这一局面。
但是我们太超前了。关注媒体、推特或脸书上的描述,继续关注我们下一篇关于自动语音识别的文章。
Juang & Rabiner 的时间线
这篇文章最初发表在 Descript 上。
统计学简史
原文:https://towardsdatascience.com/a-brief-history-of-statistics-36cfdac9439f?source=collection_archive---------18-----------------------
第 1 部分—上升—从正态分布到回归。
十九世纪中叶,科学发现使人类达到了顶峰,一股乐观主义的浪潮席卷了欧洲,带来了新的可能性。我们学会支配自然的所有法则似乎只是时间问题。我们在物理、生物、天文学等方面取得了巨大进步。这证明了过度乐观的合理性。似乎如果我们有好的测量方法,我们就可以描述和预测任何事情。不用说,实证主义者错了,但是让我们假装不知道,继续我们的故事。
确定性世界还是随机世界?统计学的兴起。
Galton Board is a machine that tries to demonstrate that different distributions converge to the normal distribution. We call this curious fact the central limit theorem.
更早一点,在十八世纪,当对行星的位置进行一些测量时,有一些轻微的偏差。我们预计这颗行星会在一个位置上,但它稍微在“错误的位置”这种现象有两种可能的解释。要么模型是错误的,要么我们收集这些数据的设备不够好/灵敏。模型看起来相当不错,所以应该是仪器的问题,所以他们开始生产更精确的设备。在分析这些小偏差时,他们注意到他总是遵循某种分布。拉普拉斯将他的一整卷天文学预测仅仅用于处理误差。今天我们知道它是正态分布。
高尔顿盒是一台试图证明不同分布收敛于正态分布的机器。我们称这个奇怪的事实为中心极限定理。
因此,我们开始提高设备的质量,正如预期的那样,误差减少了,这鼓励我们创造越来越好的设备,但随着设备变得越来越精确,一些奇怪的事情开始发生,取而代之的是误差。减少,
开始增加!当时的科学家开始想知道为什么,答案是我们的世界不是确定性的,而是随机的,也就是说,事件具有内在的随机特征!即使我们有最好的数据收集,并知道自然的完美模型,但它也不能保证一个好的预测,因为有我们无法控制的随机因素。
Image from https://www.youtube.com/watch?v=cfJ-VvptSQs
平均值
我们需要新的技术来应对这个新世界,于是就有了我们所知的统计学,一种理解随机世界的工具。例如,在具有随机特征的测量的情况下,我们应该使用某种中心性的测量,例如平均值:
Translating: We add all the observations and divide by the quantity.
方差和标准差
我们统计历史的下一步是查尔斯·达尔文家族的一员,不那么有名,但对历史非常重要,他的表弟弗朗西斯·高尔顿。在许多领域都是天才,高尔顿首先是一个杰出的观察者,也是最早注意到分布的另一个重要特征的人之一,这就是分布的形式,也就是说,虽然平均值传递了中心性的概念,但分布表明了数据的分布程度。远离平均值,因此有了方差和标准差的概念:
Translating: Average and see how far each observation is from the average. If they are always far away, a high dispersion, we have a high variance.
另一个表亲,现在方差是标准差,它基本上是第一个的平方根,其优势是在相同的数据单位中进行解释。图片我们有一个高度表,平均值为 180 厘米,方差为 400 厘米。这个 400 厘米很难解释,
所以我们求根,得出 20 厘米的标准差(20 厘米* 20 厘米= 400 厘米),这意味着人们平均上下变化 20 厘米。
协方差、相关性和平均回归。
高尔顿超越了,远远超越了。他建立了一个实验室来收集和绘制各种人类特征,并为此付出了巨大的努力。一个有趣的观察是,天文测量中的相同误差分布已经在其他几次发现,如身高或前臂大小。但他在这里主要是因为他注意到了当时一个非常好奇和创新的特点。首先,当父母的平均身高过高时,他们的孩子会高于平均身高,当父母的平均身高过低时,他们的孩子也会略低于平均身高。
Galton on Regression — 9000 families and 6 years analyzing
到目前为止没什么新鲜的,即使没有数据,每个人都有这种不信任。但他意识到还有第二种行为,这些孩子,来自高或矮的父母,几乎没有他们的父母一样高或一样矮,似乎有一种力量将他们孩子的身高拉回到平均水平,这种力量我们称之为回归均值。否则,再过几代,我们就会出现一边是巨人,一边是侏儒的种群,而我们显然没有观察到他们。
Example comparing height distribution between sex.
有鉴于此,高尔顿创造了这个术语,后来他的知识继承人皮尔森对其进行了完善,皮尔森命名了一种相关性和技术书籍的出版商。我们都知道的公式是:
Covariance, nothing more than the variation between two different variables. That is, how they disperse the average together. Note that the formula is the same, var = (xi-x) (xi-x) and cov = (xi-x) (yi-y), and so var (x) = cov (x, x)
这有一个相当简单的解释。当 X 和 Y 高于平均值时,我们将添加一个大的正数(负负),如果两者都低于平均值,我们也添加一个正数(正正)。如果这个和是一个很大的数,我们说 X 和 Y 是紧密关联的,否则是差关联的。名字只会让学*变得困难,但今天我们称之为协方差。
Original dataset used by Galton
像方差一样,协方差也很难解释。就像我们把方差归一化为标准差一样,这样更容易理解。Pearson 对协方差做了同样的处理,在这种情况下,我们用原始协方差除以 X 和 Y 的标准偏差,结果神奇地落在-1 和+ 1 之间:
Translating: The correlation between X and Y is nothing more than a normalization of Covariance. A correlation is perfect when it is close to both extremes (-1 and 1) and the variables are uncorrelated when the correlation is close to zero.
现在的解释是,相关性越强,使儿童身高回归预期平均身高的“引力”就越强。弱相关性表明这些变量没有密切关联。这个关于十九世纪和二十世纪之交的简单想法彻底改变了所有现代科学。很难找到任何不受这些发现影响的地区。从农业到医学,再到社会科学,每一门现代科学都使用同一种语言:统计学。
本文并不是对统计学历史的可靠描述,这里描述的许多发现都有以前的合著者,为了简化和便于理解这个主题,这些合著者被省略了。
查看我们的其他帖子:
- 统计简史;
- 为数据科学家推荐书籍、课程和电影。
- 数据科学 的范围是什么;
- 解释机器学*。
训练数据的简要历史
原文:https://towardsdatascience.com/a-brief-history-of-training-data-9c513fc95b3e?source=collection_archive---------26-----------------------
我的一个老朋友,Aman Naimat,最*举办了一次会议,聚集了一些有着共同经历的人:技术领域的领导者,他们为现实世界的用例提供了有用的机器学*模型。如今,符合这一特征的人少得惊人。
尽管如今机器学*备受关注,但在科技公司担任领导角色的人中,很少有人拥有构建机器学*模型的技术技能和已经构建了对现实世界应用的成功至关重要的机器学*系统。
参加会议的人来自非常不同的行业:自动驾驶汽车、营销、金融、硬件、住宿、媒体、安全等。尽管有各种各样的行业,但每个人都有一些共同点,其中一个是训练数据:每个人都像重视算法一样重视数据,以获得成功。我主持了一个关于训练数据的讲座和分组会议,这激发了我写这篇文章。
A brief history of training data
四分之一世纪的训练数据
在训练数据的历史中有一些有趣的循环。20 世纪 90 年代,在机器学*统治人工智能之前,程序员根据模型的行为,硬编码规则来提高系统的性能。当机器学*在* 20 年后占据主导地位时,我们回到了类似的人在回路系统,但由非专家的人类注释者基于模型行为创建训练数据。
在这 20 年的中间,从 20 世纪 90 年代到 2010 年代,机器学*的前景受到获得标记训练数据的高昂费用的限制。这导致了学术界对在相对少量的规范数据集上测试不同算法的关注。这是一个至今没有太大变化的学术焦点。
2000 年代末,从亚马逊的机械土耳其人(Mechanical Turk)开始,现收现付的培训数据选项的兴起改变了人们看待培训数据创建的方式。当时学术界有一场小运动,主动学*作为一种选择正确数据进行人类标注的策略而兴起。
但 2000 年代末最大的变化发生在工业界,而不是学术界。从这个时候开始,训练数据和算法对于每个人建立真实世界的机器学*模型来说都是同等重要的。
在 2010 年早期到中期,又有一个重复周期。当时渴求数据的神经模型需要大量的训练数据,这对于大多数用例来说又是极其昂贵的。这导致了神经方法最初在行业中的缓慢采用,只有少数计算机视觉用例例外,在这些用例中,精确度的变化足够大,以至于创造了新的用例。
今天,自适应神经模型和迁移学*的进步意味着较小的数据集足以在机器学*的重点应用中获得最先进的性能。
创建培训数据
Training data questions today
我们在许多不同的用例中以相似的方式制定训练数据的策略。我们需要多少数据?谁是注释数据的合适人选,我们如何评估注释质量?我们能否绕过用合成数据或预训练模型支付训练数据?在算法方面,我们如何快速调整模型以适应新的标记数据,以及我们如何解释模型的不确定性以帮助对正确的未标记数据进行采样以供人类审查?
就像算法的方法在过去 20 年里发生了巨大的变化一样,创建良好训练数据的方法也是如此。很高兴在会议上分享了许多这些,因为它们不像机器学*界的算法那样被广泛讨论。
AI 多样性如何应用于训练数据?
今天最大的公开问题是:AI 多样性如何应用于训练数据?
在歧视系统:人工智能中的性别、种族和权力中, Myers West、Whittaker、Crawford 讨论了在创造人工智能的人群中多样化代表的重要性。他们的重点是算法和创建机器学*模型的人。
继续他们的论点,在机器学*的训练数据方面可能会有更大的差异。专注于算法的技术极大地让富人的生活变得更加轻松。如果你是一名程序员,那么只要你创建的模型被部署,它就有可能为你的收入做出贡献。然而,训练以数据为中心的技术不成比例地从不太富裕的人身上榨取价值。如果你为同一个模型创建训练数据,你很可能会为你的时间获得一次报酬,而在你的数据上构建算法的人将继续受益。
当 20 世纪 90 年代创造算法的人同时也是创造数据(或规则)的人时,我们必须同等重视这两种贡献。我希望这也是一个循环,这样我们就能回到一个更公平的系统,公平地补偿人们在训练数据中创造的价值。
罗伯特·芒罗
2019 年 7 月 2 日
中心极限定理简介
原文:https://towardsdatascience.com/a-brief-intro-to-the-central-limit-theorem-ccbd2b661b32?source=collection_archive---------26-----------------------
他们说你不可能成为一名数据科学家,如果你不知道…
根据维基百科。
在概率论中,中心极限定理 ( CLT )确立了,在某些情况下,当个独立随机变量相加时,它们的正常归一化和趋向于一个正态分布(非正式的一个“钟形曲线”),即使原始变量本身不是正态分布。
翻译:如果从总体中抽取足够多的样本,这些样本的均值将接*正态分布。
酷的是,这适用于(几乎)任何分布的人群。让我们举一些例子来证明这一点。
生成随机数据
生成 300 个 0 到 50 之间的随机数。
import matplotlib.pyplot as plt
import randomX = []for i in range(0,300):
v = random.randint(0,50)
X.append(v)
画出来,这样我们就能看到数据的形状。
plt.rcParams.update({'figure.figsize':(7,5), 'figure.dpi':100})
plt.hist(X, bins = 50)
Definitely not a normal distribution
取样并计算平均值
现在取 10,000 个样本,样本大小为 5,计算每个样本的平均值,并绘制平均值的频率。
import numpy as npmeans = []for i in range(0,10000):
sample = []
for ii in range(0,5):
v = random.choice(X)
sample.append(v)
mean = np.mean(sample)
means.append(mean)
绘制分布图
画出每个样本平均值的频率。
看起来有点像正态分布。很酷吧。
现在让我们把样本量从 5 个增加到 30 个。
更像是正态分布。
尽管原始人口根本不遵循正态分布,这种情况还是发生了。
我生成的数据是随机的。但是几乎任何分布,连续的或离散的,贝塔的,伽马的或均匀的,都能达到完全相同的效果。
为什么这很重要
如果足够多样本的平均值接*正态分布,我们可以“假装”样本本身的分布也是正态的。在给定一个样本的情况下,对整体人口做出推断时会感觉更舒服。
以上是我的理解,但我不是统计学家。所以我想向大众展示一下。为什么中心极限定理对统计学和机器学*如此重要?
几种常见统计检验简介
原文:https://towardsdatascience.com/a-brief-introduction-of-some-common-statistical-tests-5f2963014641?source=collection_archive---------8-----------------------
统计测试是理解数据集、执行特征工程和特征选择的重要工具。本博客将简要介绍一些常见的统计测试,它们的作用以及何时使用。
测试类型:
- 相关性:检查变量之间的关联。
- 均值比较:检查变量均值之间的差异。
- 回归:检查一个变量是否能预测另一个变量的变化。
- 非参数检验:当数据不符合参数检验的假设时使用的检验。
开始前的几个概念:
- :零假设,两个总体(变量)之间没有变化,例如,如果两个变量具有相同的分布。
- Hₐ :两个总体(变量)不相等。
- p 值 :如果 p 值 小于规定的显著性水平 α (通常为 0.05),差异显著,拒绝零假设。**
- H₀ 被拒绝:两个变量不是来自同一个分布。
相关性
1。皮尔逊相关性
皮尔逊相关系数是两个变量 X 和 Y 之间线性相关的度量,可以计算为:
Pearson’s correlation coefficient
其中 cov 为协方差 σ 为标准差。
皮尔逊相关系数是介于-1 和 1 之间的值,其中-1 是完全负相关,1 是完全正相关,0 是不相关。
2。斯皮尔曼关联
Spearman 相关性是两个变量之间等级相关性的非参数度量,它评估两个变量之间的单调关系(是否线性)。它可用于连续和离散序数变量,计算公式如下:
Spearman’s correlation coefficient
其中 rg 是 X 和 Y 的排名变量,因此 Spearman 相关系数就是两个排名变量之间的 Pearson 相关系数。与皮尔逊相关系数相同,-1 表示完全负相关,1 表示完全正相关,0 表示不相关。
3。卡方
卡方检验检查分类变量的分布是否彼此不同,非常小的卡方检验统计量意味着两个分类变量之间有关系,而非常大的卡方检验统计量意味着没有关系。卡方检验统计量的计算方法如下:
Chi-square test statistic
在哪里
- 是观察次数如果键入 i 。
- N 是观察的总数。
- =是类型 i 的期望(理论)计数,由零假设断言类型 i 在总体中的分数是【pᵢ。**
- n 是表中单元格的个数。
p 值可以通过卡方检验统计和自由度计算得出,通常为$p<0.05$ is significant and the null hypothesis can be rejected.
平均值比较
1。配对 T 检验
配对 t 检验比较两个不同时间或两种不同条件下相同变量的两个平均值。换句话说,这里的零假设是真实的均值差为零。
它只能比较正态分布的连续结果中两个(且只有两个)相关(成对)单位的平均值。
T 统计量T43T可以计算为:
- 1.计算每对中两个观察值之间的差异 dᵢ=yᵢ−xᵢ 。
- 2.计算平均差值 d̅ 。
- 3.计算平均差值的标准误差【se(d̅】:
standard error of the mean difference
其中 n 为样本量。
- 4.计算 T 由:
t-statistic
在零假设下, T 遵循一个 t 分布 与n1的自由度。
- 5.从 学生的 t 分布中获取 p 值使用 T 和自由度根据值表确定是否拒绝零假设。
2。独立 T 检验
这类似于配对 t 检验,除了这里的两个变量应该是独立的和同分布的。
3。ANOVA —方差分析
ANOVA 检验比较三个或更多变量之间的平均值,当只有两个变量时,它相当于独立 T 检验。然而,如果我们对每两个变量进行 t 检验,它将对结果的误差率产生复合影响。
这里的零假设是所有变量具有相同的样本均值。拒绝零假设告诉我们至少有两个变量有不同的含义,但我们不知道是哪一个。因此,需要进行更多的测试来缩小哪些变量的均值不同。
F 统计量 可以计算为:
- 1.计算组间变异性的平方和 SS_between** 😗*
其中 n 为样本量, x̅ 为均值, x̅_G 为大均值为所有变量均值的均值。 k 是样本平均数。
2.计算组间变异性的均方值 MS_between** 😗*
3.计算组内变异性的平方和 SS_within** 😗*
其中是第一个变量的第 i 个值。
4.计算组间变异性的均方值 MS_between** 😗*
其中 N 是样本量的总和。
5.计算F-统计量** 😗*
6.根据参考表使用 F 和显著性水平(通常为 0.05)确定是否拒绝零假设。
回归
简单回归测试一个变量的变化如何预测结果变量的变化,而多重回归测试两个或更多变量组合的变化如何预测结果变量的变化。
非参数化
1。Wilcoxon 秩和检验
检验两个独立变量的平均值之间的差异。Wilcoxon 秩和检验统计量 U 可计算如下:
- 1.给数字变量分配等级。
- 2.计算两个变量的秩和(【r₁】,)。**
- 3.计算 U₁ 和 U₂ :
****
其中 n₁ , n₂ 为两个变量的样本量。
Wilcoxon 秩和检验统计量是 U₁ 和 U₂ 中的较小者。
- 4.根据曼-惠特尼 U 表中的临界值,使用样本大小和显著性水平(通常为 0.05)找到合适的临界值。
5.如果小于临界值,则拒绝 H₀ 。
好的教程可以在这里找到。
2。Wilcoxon 符号等级测试
检验两个相关变量的均值之间的差异,当样本量较小且变量不呈正态分布时,它可以作为配对 t 检验的替代方法。它假设变量是成对的,并且来自同一个总体。
更具体地说,这里的假设是:
- H₀ :线对之间的差值在零附*呈对称分布。
- Hₐ :线对之间的差异不遵循零附*的对称分布。
Wilconxon 符号秩检验统计量可计算如下:
- 1.对于 i=1,…,N ,计算 |X₂,ᵢ - X₁,ᵢ| 和sgn(x₂,ᵢ-x₁,ᵢ),其中 sgn 为符号函数。
- 2.排除与|x₂,ᵢ-x₁,ᵢ|=0的配对。设 Nᵣ 为缩减后的样本量。
- 3.将剩余的 Nᵣ 对从最小绝对差到最大绝对差依次排列,|x₂,ᵢ—。
- 4.对配对进行排序,从非零绝对差值最小的配对开始,数值为 1。平局的等级等于他们所跨越等级的平均值。让 Rᵢ 表示军衔。
- 5.计算检验统计量 W :
Wilcoxon Sign-Rank test statistic
- 6.根据参考表,使用样本大小和显著性水平(通常为 0.05)找到合适的临界值。
- 7.如果 W 小于临界值,则拒绝。
结论
使用哪种统计检验以及何时使用取决于数据的性质(连续或分类、相关或独立、配对或不配对等)以及您有兴趣探索的关系。感谢阅读!
使用 Python 进行变化点检测的简介
原文:https://towardsdatascience.com/a-brief-introduction-to-change-point-detection-using-python-d9bcb5299aa7?source=collection_archive---------18-----------------------
我的很多工作都大量涉及时间序列分析。我使用的一个很棒但不太为人所知的算法是变化点检测。
变点检测(或 CPD)检测时间序列趋势的突然变化(即时间序列瞬时速度的变化),这可以通过人眼轻松识别,但使用传统的统计方法很难精确定位。CPD 适用于一系列行业,包括金融、制造质量控制、能源、医疗诊断和人类活动分析。
CPD 非常适合以下使用案例:
- 检测时间序列中的异常序列/状态
- 检测时间序列中唯一状态的平均速度
- 实时检测时间序列状态的突变
我发现 CPD 在自动识别和去除时间序列中的异常序列时特别有用,如下所示:
Change point detection using the Python ruptures package: We can identify anomalous data sequences that need to be removed from the time series
如果我试图确定系统中的速率变化,这也很好,使我可以专注于类似序列的平均速率:
Change Point Detection in R using the PELT Algorithm: We can split up average velocity of a time series across phases using CPD
本文提供了关于变化点检测的简单易懂的背景知识,以及用 Python 实现的实用包(包括示例代码!).
算法背景
CPD 有两种不同的类别——离线和在线。在本节中,我将对这两者进行简要概述。
离线变化点检测
当不使用实时流数据时,变化点检测方法是“离线”的,并且需要完整的时间序列来进行统计分析。因为离线方法分析整个时间序列,它们通常更准确。离线变化点检测的一些特征如下(1):
- 所有数据同时被接收和处理
- 所有的变化都是感兴趣的,而不仅仅是序列中最*的变化
在线变点检测
与离线变化点检测相比,在线变化点检测用于实时流时间序列,通常用于持续监控或即时异常检测(1)。在线 CPD 在单个数据点可用时对其进行处理,目的是在它们发生时立即检测到状态变化(2)。在线变化点检测有几个特征:
- 快速“即时”处理,以便快速评估时间序列趋势的变化
- 仅评估时间序列中最*的变化,而不是以前的变化
用于变化点检测的 Python 包
r 有一个优秀的包用于变点检测,叫做 changepoint 。该软件包允许用户使用多种搜索方法对时间序列进行变点分析。不幸的是,没有与 R 的 changepoint 包直接对应的 Python。然而,还有其他几个包提供了变化点检测,可通过 Python 获得:
- 破坏了包,这是一个用于执行离线变化点检测的 Python 库
- 使用一个 R 到 Python 的接口 rpy2 包将 R changepoint 包调用到 Python 中
- changefinder 包,一个用于在线变更点检测的 Python 库
在这三个选项中,我发现选项#1 和#3 最容易实现,因为它们不需要在 Python 环境中下载和配置 R 和 rpy2。R changepoint 包的功能是迄今为止最健壮的,但是配置它很耗时。因此,这不是这篇文章的重点。
如果您对使用 rpy2 通过 Python 调用 R changepoint 包的深入背景感兴趣,请查看 Steven Reitsma 的本教程 】。
让我们进一步探讨选项 1 和选项 3。
破裂包装
Charles Truong 改编了 R changepoint 包的破裂包。它特别关注离线变点检测,在这里对整个序列进行分析。在所有 Python changepoint 选项中,它是最好的文档。我们可以使用基本的 pip 安装命令来安装它:
pip install ruptures
该软件包提供了多种搜索方法(二进制分割、毛皮、基于窗口的变化检测、动态编程等)。),以及多种成本函数。在本教程中,我们特别关注搜索方法。
搜索方法背景
本节简要介绍了 surfaces 包中可用的一些搜索方法,包括二进制分割、PELT、基于窗口的变化检测和动态编程。
修剪精确线性时间(毛皮)搜索方法:毛皮方法是一种精确的方法,并且通常产生快速且一致的结果。它通过最小化成本来检测变化点(4)。该算法的计算成本为 O(n),其中 n 是数据点的数量(4)。更多关于毛皮方法的信息,请查看这篇论文。
动态规划搜索法:这是一种精确法,计算量相当大,为 O(Qn),其中 Q 为最大变化点数,n 为数据点数(4)。有关动态编程搜索方法的更多信息,请查看本文。
二分分割搜索法:这种方法可以说是文献中最成立的(4)。二进制分割是一种*似方法,其有效计算成本为 O (n log n),其中 n 是数据点的数量(4)。该算法通过对整个序列反复应用单个改变点方法来确定是否存在分裂。如果检测到分裂,则序列分裂成两个子序列(5)。然后将相同的过程应用于两个子序列,等等(5)。欲了解更多关于二进制分割的信息,请查看本文。
基于窗口的搜索方法:这是一种比较简单的*似搜索方法。基于窗口的搜索方法“计算随信号 y 移动的两个相邻窗口之间的差异”(6)。当两个窗口非常不相似时,两个值之间会出现很大的差异,这指示了一个变化点(6)。在生成差异曲线时,该算法在序列中定位最佳变化点索引(6)。有关基于窗口的搜索方法的更多信息,请查看本文。
代码示例
在下面的代码中,我们使用上面描述的搜索方法来执行变化点检测。我们使用每日 WTI 石油价格的时间序列,从 2014 年到现在,通过能源信息管理局(EIA)的 API 提取(参见本教程了解更多关于使用 EIA API 提取数据的信息):
def retrieve_time_series(api, series_ID):
"""
Return the time series dataframe,
based on API and unique Series ID
api: API that we're connected to
series_ID: string. Name of the series that we want
to pull from the EIA API
"""
#Retrieve Data By Series ID
series_search = api.data_by_series(series=series_ID)
##Create a pandas dataframe from the retrieved time series
df = pd.DataFrame(series_search)
return df """
Execution in main block
"""#Create EIA API using your specific API key
api_key = 'YOUR API KEY HERE'
api = eia.API(api_key)
#Pull the oil WTI price data
series_ID='PET.RWTC.D'
price_df=retrieve_time_series(api, series_ID)
price_df.reset_index(level=0, inplace=True)
#Rename the columns for easier analysis
price_df.rename(columns={'index':'Date',
price_df.columns[1]:'WTI_Price'},
inplace=True)
#Format the 'Date' column
price_df['Date']=price_df['Date'].astype(str).str[:-3]
#Convert the Date column into a date object
price_df['Date']=pd.to_datetime(price_df['Date'], format='%Y %m%d')
#Subset to only include data going back to 2014
price_df=price_df[(price_df['Date']>='2014-01-01')]#Convert the time series values to a numpy 1D array
points=np.array(price_df['WTI_Price'])
#RUPTURES PACKAGE
#Changepoint detection with the Pelt search method
model="rbf"
algo = rpt.Pelt(model=model).fit(points)
result = algo.predict(pen=10)
rpt.display(points, result, figsize=(10, 6))
plt.title('Change Point Detection: Pelt Search Method')
plt.show()
#Changepoint detection with the Binary Segmentation search method
model = "l2"
algo = rpt.Binseg(model=model).fit(points)
my_bkps = algo.predict(n_bkps=10)
# show results
rpt.show.display(points, my_bkps, figsize=(10, 6))
plt.title('Change Point Detection: Binary Segmentation Search Method')
plt.show()
#Changepoint detection with window-based search method
model = "l2"
algo = rpt.Window(width=40, model=model).fit(points)
my_bkps = algo.predict(n_bkps=10)
rpt.show.display(points, my_bkps, figsize=(10, 6))
plt.title('Change Point Detection: Window-Based Search Method')
plt.show()
#Changepoint detection with dynamic programming search method
model = "l1"
algo = rpt.Dynp(model=model, min_size=3, jump=5).fit(points)
my_bkps = algo.predict(n_bkps=10)
rpt.show.display(points, my_bkps, figsize=(10, 6))
plt.title('Change Point Detection: Dynamic Programming Search Method')
plt.show()
Snapshot of the WTI Oil Price Time Series, pulled via the EIA API
Change Point Detection with Pelt Search Method, WTI Oil Price Time Series, 2014-Present
Change Point Detection with Binary Segmentation Search Method, WTI Oil Price Time Series, 2014-Present
Change Point Detection with Window-Based Search Method, WTI Oil Price Time Series, 2014-Present
Change Point Detection with Dynamic Programming Search Method, WTI Oil Price Time Series, 2014-Present
如上图所示,序列中检测到的变化点因使用的搜索方法而异。最佳搜索方法取决于您在对时间序列进行子集化时最重视的内容。PELT 和动态规划方法都是精确(与*似相反)方法,因此它们通常更精确。
changefinder 包
changefinder 包专门用于在线变化点检测。为了执行变点检测,该包使用 SDAR 建模,或顺序贴现自回归时间序列建模。SDAR 就像它听起来的那样——它是自回归(AR)模型的扩展,其中序列中较旧的数据点被“贴现”,即不如序列中较新的值重要。因为最*的数据在 SDAR 模型中权重更大,所以 SDAR 非常适合在线变化点检测,这种检测侧重于检测序列中最*的变化。
自回归建模(AR)是时间序列建模最流行的形式之一,其中当前值是根据序列中以前的值预测的(3)。有关 SDAR 模型(以及多元标准差模型)的更多信息,请查看本文。
代码示例
现在我们已经有了 changefinder 包的一些初始背景,让我们用它来执行在线变更点检测。
对于本例,我们将使用 random()和 numpy()包自动生成数据:
#Create a synthetic data set to test against
points=np.concatenate([np.random.rand(100)+5,
np.random.rand(100)+10,
np.random.rand(100)+5])
生成一些合成数据后,我们通过 ChangeFinder 函数运行这些数据,并根据 SDAR 为每个数据点生成一个异常值:
#CHANGEFINDER PACKAGE
f, (ax1, ax2) = plt.subplots(2, 1)
f.subplots_adjust(hspace=0.4)
ax1.plot(points)
ax1.set_title("data point")
#Initiate changefinder function
cf = changefinder.ChangeFinder()
scores = [cf.update(p) for p in points]
ax2.plot(scores)
ax2.set_title("anomaly score")
plt.show()
ChangeFinder Results: Top graph represents the synthetic data, and bottom graph represents corresponding anomaly scores
在上面的图像中,异常分数在时间 100 和时间 200 达到峰值,这对应于时间序列中发生巨大变化的点。为异常分数设置一个最小阈值,其中任何高于某个阈值的分数都对应于序列中的一个变化点,这是识别序列中单个变化点的最佳方法。
我对变化点检测的简要介绍到此结束。要访问我在本教程中使用的代码,请查看我的 Github repo 。
一如既往的感谢阅读!
查看我的其他数据科学文章和教程:
[## 用最大似然法预测向电网售电的最佳时间
随着新技术在可再生能源和能源存储行业的兴起,有许多新的机会…
techrando.com](https://techrando.com/2019/07/30/using-ml-to-predict-the-best-time-to-sell-electricity-back-to-the-grid/) [## 使用 Python 分析电价时间序列数据:时间序列分解和价格…
欢迎来到科技兰多博客!在今天的帖子中,我将使用能源信息管理局的 API…
techrando.com](https://techrando.com/2019/07/19/analyzing-electricity-price-time-series-data-using-python-time-series-decomposition-and-price-forecasting-using-a-vector-autoregression-var-model/)
来源
- 基利克,丽贝卡。2017.最佳变点检测算法介绍。http://members . cbio . mines-Paris tech . fr/~ thocking/change-tutorial/RK-cptworkshop . html
- Aminikhanghahi,Samaneh 和 Cook,Diane。2017 年 5 月。时间序列突变点检测方法综述。https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5464762/#R7
- 法蒂玛·萨伊德;努尔、达尔菲亚纳;国王,罗伯特。2012.利用 SDVAR 算法检测向量自回归模型的变点。https://pdfs . semantic scholar . org/c56d/4 adad 7 ed 3 f 504015 BC 6 BBC 663 e 21 e 55 f 174 b . pdf
- Wambui,Gachomo Dorcas 吉丘希·安东尼·怀蒂图;安东尼·万何亚。2015 年 12 月。多变点检测中修剪精确线性时间(PELT)检验的功效。https://pdfs . semantic scholar . org/a7bc/09 B7 a 73 DC 96 be 7 cf 844978014 ad 13 cf 0475 a . pdf?_ ga = 2.100775582238-1351705
- 克里斯蒂安·罗尔贝克。使用二元分割和最优分割检测方差变化。https://www.lancaster.ac.uk/pg/rohrbeck/ResearchTopicI.pdf
- 查尔斯·张;劳伦特·奥德雷;尼古拉·瓦亚提斯。2019 年 1 月。离线变点检测方法的选择性审查。https://arxiv.org/pdf/1801.00718.pdfT21
原载于 2019 年 8 月 14 日https://techrando.com。
计算神经科学简介第一部分
原文:https://towardsdatascience.com/a-brief-introduction-to-computational-neuroscience-part-1-42171791f613?source=collection_archive---------6-----------------------
人脑的直觉和建模
1.0 简介
计算神经科学是唯一可以帮助你理解,你如何在大脑中思考和处理信息的领域。即使在你完成这句话的时候,你的大脑中也会发生大量的动作,这些动作可以通过对神经元的研究来解码。计算神经科学的最终目标是解释大脑中如何使用电信号和化学信号来表示和处理信息。它解释了神经元计算的生物物理机制、神经回路的计算机模拟和学*模型。
在你开始阅读这篇文章之前,你的大脑(你)可能会有一些想法,为什么我们需要阅读这篇文章?我们能从中学到什么?还是这个内容会让我知道,大脑在各种情况下是如何反应和解决问题的?是啊!所有的数学,排列,化学方程式都发生在我们自己的大脑里。本文分为三个部分。在文章的第一部分,我们简要介绍了计算神经科学,包括神经元的作用,神经元的解剖结构和可以解释大脑功能的模型,即所谓的大脑模型。
现在,让我们看看通过理解或学*大脑,我们能得到什么。在过去的几年里,我们已经看到了神经网络的进步,这些进步完全是受“计算神经科学”的启发。在神经网络/计算机视觉的几个领域中使用的算法或模型是通过对神经科学的理论理解而得到的。我们所知道的是,我们的大脑快速、聪明,它们从环境中接受输入,发生一些化学反应/融合,最后,它们给我们答案或输出。通过阅读,你将了解我们大脑内部程序的执行情况。我们开始吧!
这是 Lex Friedman 最*发布的推文。他在麻省理工学院担任研究科学家。
人脑真是不可思议。这里可以看到大脑中 3%的神经元和 0.0001%的突触,构成了大脑丘脑皮层系统的一部分。通过 DigiCortex 引擎实现可视化。
2.0 神经科学
背景
“计算神经科学”一词是由 Eric L. Schwartz 在一次会议上提出的,该会议对一个领域进行了回顾,在此之前,该领域有多种名称,如神经建模、大脑理论和神经网络。后来,Hubel & Wiesel 在初级视觉皮层(第一皮层区域)发现了跨视网膜神经元的工作。这将在第 3 节中解释。此外,随着计算能力的提高,大多数计算神经科学家在分析不同的数据和合成生物现象的新模型方面与实验学家密切合作。
理论神经科学
神经科学包括从分子和细胞研究到人类心理物理学和心理学的方法。计算神经科学的目的是描述大脑中如何使用电信号和化学信号来解释和处理信息。这一意图并不新鲜,但在过去十年里发生了很大变化。由于神经科学的进步,现在对大脑有了更多的了解,更多的计算能力可用于执行神经系统的现实模拟,新的见解正在从对大型神经元网络的简化模型的研究中得出。
了解大脑是一项挑战,吸引了越来越多来自不同学科的科学家。虽然在过去的几十年里,在细胞和分子水平上对大脑的结构有了大量的发现,但我们仍然不明白神经系统是如何使我们能够看、听、学*、记忆和计划某些行为的。但是有许多领域依赖于计算神经科学,下面列出了一些,
- 深度学*、人工智能和机器学*
- 人类心理学
- 医学科学
- 心理模型
- 计算解剖学
- 信息论
3.0 Hubel 和 Wiesel 实验
这个实验似乎是已经发现的神经元洞察力的先兆。为深入探索计算神经科学奠定了基础。让我们看看这里面是什么。
David Hubel 和 Torsten Wiesel 教授在 20 世纪 50 年代进行了实验,他们记录了猫在移动强光时视网膜上的神经元活动。在实验进行的过程中,他们记录了一些令人兴奋的观察结果
- 神经元只在某些情况下被激发,但并不总是如此。
- 神经元的活动根据光线的方向和位置而变化。
(不要担心神经元术语,我们将在以下主题中探索所有术语。)连接视网膜和大脑的细胞中记录的电信号和化学信号被转换成声音信号。然后播放这些声音信号,结果是“啪”的一声!“砰!”爆裂声。这些不是连续的,而是仅在神经元激活时播放。此后,它对神经元如何提取视网膜投射的信息建立了基本的理解,然后清楚地解释了视觉皮层神经元(存在于大脑中的初级视觉皮层 V1 中)如何形成图像。
4.0 神经细胞、神经元的解剖学和电个性
因此,为了清楚地了解大脑是如何工作的,以及我们如何能够感知我们周围的世界,让我们看看大脑的主要部分,即神经元。这些是人脑的计算单元。
大脑可以被分解成称为神经元的独立的离散部分。有许多可能的神经元形状,例如,在视觉皮层,神经元是锥体,在小脑,它们被称为浦肯野细胞。
神经元的结构
神经元由三个主要部分组成,即体细胞、树突和轴突。胞体是细胞体。树突是神经元的输入端,而轴突是输出端。因此,树突接收来自相邻神经元轴突的输入。这些输入产生了兴奋性突触后电位(EPSP) ,当从几个其他神经元的组合中提取时,它提供了动作电位或尖峰。只有当输入达到某个阈值时,这种尖峰才会发生。
Structure of neuron (src)
窥视内部
有趣的是,神经元可以被定义为“带电液体的漏袋”那么,突然之间,化学物质是如何出现的呢?这是一件我们很多人都没有意识到的重要事情。神经元完全处理化学物质,化学反应驱动所有的棘波和突触。我们的大脑中确实有钠离子、氯离子、钾离子等。很迷人,不是吗?****
神经元的内容物被包裹在脂质双层中,简单来说脂质就是“脂肪”。这种双层对于带电离子是不可渗透的,例如 Na+,K+,Cl-等。那么,这些化学物质是如何在神经元之间移动的呢?为了回答这个问题,让我们深入研究离子通道。
离子通道
离子通道允许这些离子的传递,即进出神经元。这导致在神经元的内部和外部之间存在电势差,内部电势相对于外部为-70mv。
Membrane potential (src)
我们在外部有 Na+,Cl-,而 K+,有机阴离子-存在于神经元内部。反之亦然,但在这种情况下,离子浓度较低,如下图所示。
Types of ions found in neurons (src)
那么,电位怎么总是-70mv 呢?这是通过将离子泵入和泵出神经元来维持的,即通过排出 Na+并允许 K+进入。离子通道仅允许特定的神经元通过,并可分为三种门控通道,
- 电压门控 —通道打开的概率取决于膜电压。
- 化学门控——与化学物质结合导致通道打开。
- 机械门控 —压力或拉伸影响通道打开/关闭。
Ionic passage across the neuron membrane (src)
神经元信号
神经元信号传递是通过信号传递在神经元之间发生的相互作用。上面讨论的门控通道允许神经元发出信号,让我们看看如何,
- 首先,来自其他神经元的输入激活化学门控通道,即打开通道,这导致局部膜电位的变化。
- 接下来,这导致电压门控通道的打开/关闭,从而导致去极化(电压的正变化)和超极化(电压的负变化)。复极是细胞回到实际电位的地方。
- 足够强的去极化将导致尖峰或动作电位。
- 这确实打开了 Na+通道(电压门控),随后 Na+快速流入(从外向内),驱使更多的通道打开,直到它们失活。
- 当 Na+通道开始缓慢失活时,K+流出(从内向外)恢复膜电位或 K+通道打开,从而减少尖峰。这就是复极。
- 此后,随着 K+通道保持开放并继续让正离子离开神经元,细胞变得更负。这被称为超极化。
- 随着钾通道关闭,钠钾泵再次恢复静息状态。
- 棘波产生后,沿着轴突传播。
- 沿着轴突,Na+通道首先开放,导致动作电位上升,随后 Na+通道关闭,K+通道开放,导致动作电位下降。
从图形上看,这是膜电位随时间变化的记录方式,
Membrane potential during an action potential (src)
速度
信号沿着轴突传播得非常快,主要有两个原因;尺寸和髓鞘。这是一种绝缘物质,不允许离子通过。
Anatomy of neuron (src)
在上述神经元中描绘的 Ranvier 的节点是存在于轴突周围髓鞘包裹之间的空间。在外周神经系统中,髓磷脂存在于施万细胞膜中。在中枢神经系统中,少突胶质细胞负责绝缘。
周围神经系统是由大脑和脊髓以外的神经和神经节组成的。中枢神经系统由大脑和脊髓组成。
当动作电位穿过轴突时,有可能会丢失,所以髓鞘的存在保护了它。
Myelinated vs Unmyelinated Axon (src)
髓鞘降低了其覆盖区域的神经元的电容。因此,神经元会产生大量需要平衡的激动的负离子。因此,它们扩散到膜的末端,希望找到正离子。然后正离子靠*它们,让它们平静下来。这反过来导致在外面形成正离子薄层,在里面形成负离子薄层。当髓鞘包裹在轴突周围时,在轴突的髓鞘包裹部分积累的负离子较少,从那时起,它们将不能容易地接*正离子。这意味着,当动作电位快速通过时,被保护的区域更容易去极化(电压的正变化),因为需要抵消的负离子更少。
ranvier 的节点具有这些正门控电压通道,其中正离子形成群集,因为它们是未覆盖的区域。所以,轴突中的负离子想要到达兰维尔的节点来平衡自己。这种动作电位的传播看起来像一个信号从一个节点跳到另一个节点,称为“跳跃传导”。
这也解释了尖峰的形状,它在一定程度上增加,然后减少。
5.0 理解大脑
既然我们已经看到了神经元的结构以及它们如何通过发送信号和产生化学物质来进行计算,现在是时候将一组神经元分组来了解大脑了。理解大脑总是一个棘手的问题,有时我们无法预测人/大脑在一些场景下会如何反应,尽管他们沉迷于日常活动。它们根据不断触发的动作,在神经元内部存储了大量信息。所以这里的问题是,我们需要如何解读这些信息?有三种理解大脑的计算模型,它们解释了三个问题:“什么、如何和为什么”。这些模型分别被命名为描述性模型、机械论模型和解释模型。现在让我们简单讨论一下这些,
描述性模型:这个模型回答了问题“什么是神经元对外界刺激的反应?”他们回顾了大量的实验数据,从而描述了神经元和神经回路的功能。这些模型可能松散地基于生物物理学、解剖学和生理学的发现,但它们的主要目的是描述现象,而不是解释现象。
描述性模型的两个主要属性是,
- 它们定性地定义了如何通过神经编码来描述场景或数据。
- 它们还定义了我们如何通过神经解码技术从神经元中提取信息。
机械模型:另一方面,机械模型解决了“神经系统如何通过已知的解剖学、生理学和电路运作”的问题。这种模型通常在不同层次的描述性模型之间形成一座桥梁。
机械模型的两个主要特性是,
- 我们如何在计算机上模拟单个神经元的行为?
- 我们如何模拟神经元网络?
****解释性模型:这些模型使用计算和信息论原理来探索神经系统功能各方面的行为和认知意义,解决“为什么神经系统像它们那样运作”的问题。
解释模型的两个主要属性是,
- 为什么大脑以这样的方式运作?
- 它们背后的计算原理是什么?
感谢阅读。本文作者是萨姆希塔·阿拉和维哈尔·鞍马。
敬请关注我们即将到来的部分,“大脑的编码和解码”。✨
参考资料: HubelAndWeisel ,学计算神经科学, KhanAcademy 。
深度学*中的隐私简介
原文:https://towardsdatascience.com/a-brief-introduction-to-privacy-in-deep-learning-24e0f3eab3da?source=collection_archive---------25-----------------------
成功的最先进的深度学*技术需要大量集中的训练数据,或者保存在一台机器或一个位置的数据。尽管深度学*在大量任务中表现出前所未有的准确性和成功,但集中式训练数据的普遍使用限制了深度学*在暴露数据不会带来隐私风险的领域中的适用性。这导致医疗保健等一些领域从深度学*中受益有限。
众所周知,要从深度学*模型中获得最佳结果,训练数据集必须更大,种类更多。学*的数据越多,结果就越好。缺乏对更大数据集和多样性的访问的模型通常会受到过度拟合和不良最终结果的影响。
在医学领域,深度学*已被证明有可能挽救生命,对该领域的发展至关重要。医疗机构携带的高度隐私和敏感信息带来了问题。由于高隐私期望和法规,数据不能合法地与其他机构共享。然后,每个机构被迫只根据他们可用的数据训练模型:他们自己的病人数据,而不是来自其他机构的数据。这导致模型产生的结果无法概括,并且在呈现新数据时表现不佳。
联合学*
联邦学*算法的目标是在大量不同参与设备之间保存的数据上训练一个模型,这些设备称为客户端。如前所述,训练深度学*模型需要将数据与模型本身一起存储在本地。换句话说,训练数据被带到深度学*模型中。联合学*旨在将模型引入训练数据。
该模型将使用大量的客户端。训练数据仍将被本地存储在每个设备上,但是每个设备将下载模型,对它们的本地数据执行计算,产生模型的小更新,然后更新模型并将其发送回中央服务器。这使得每个客户端能够在本地存储其数据的同时对全局模型训练做出贡献。每个客户端将只向全局模型发回一个更新,然后在全局模型中与其他客户端的更新进行平均。
推荐阅读:
- 联合学*:提高沟通效率的策略
安全多方计算
安全多方计算(MPC)旨在允许多方对其输入数据执行计算,同时确保数据保密且最终结果准确。
想象有五个朋友坐在一张桌子旁。他们想知道他们中谁的工资最高,但是他们五个人都不想让别人知道他们自己的工资,除非他们的工资最高。解决这个问题的一个简单方法是引入一个可信任的第三方,五个朋友中的每一个都可以告诉这个第三方他们的工资,第三方将宣布谁的工资最高,而不会给出任何其他人的工资信息。不幸的是,这样一个值得信任的第三方很难得到。因此,MPC 的目标是用一个仍能确保数据隐私的加密协议来取代这个需要的可信任的第三方。
MPC 是机器学*和深度学*中一个不断发展的密码学领域。以下是一些其他资源和推荐读物:
- 用于隐私保护数据挖掘的安全多方计算
- 多方计算在实践中有用吗?
差异隐私
如果分析数据的算法的输出不能用于确定在执行计算的原始数据集中是否使用了个人数据,则该算法可被定义为差分私有算法。差异隐私的目标是通过让计算运行在不完全依赖个人信息的数据上来降低个人信息被泄露的风险。
这是通过向数据集添加足够的噪声来影响数据,从而无法确定个人的具体细节。为了确保每个人的匿名级别相同,随着数据集规模的减小,会添加更多的噪声。随着数据集的增长,需要使用更少的噪声来实现每个人相同的隐私。
例如,对于包含来自两个人的信息的数据集,每个人占数据集的 50%。将需要添加更大量的噪声来确保两个人的数据都是保密的。一个有一百万人的数据集将使每个人占数据集的 0.000001%。因此,需要更少的噪声来掩盖个体的数据。
推荐阅读:
- 垂直分区数据库上的隐私保护数据挖掘
- 差分隐私
- 在保护隐私的同时泄露信息
监督学*简介
原文:https://towardsdatascience.com/a-brief-introduction-to-supervised-learning-54a3e3932590?source=collection_archive---------2-----------------------
监督学*是当今机器学*最常见的分支。通常,新的机器学*实践者将从监督学*算法开始他们的旅程。因此,这三篇文章系列的第一篇将是关于监督学*的。
监督机器学*算法被设计成通过例子来学*。“受监督的”学*这个名称源于这样一种想法,即训练这种类型的算法就像让一个老师监督整个过程。
当训练监督学*算法时,训练数据将由与正确输出配对的输入组成。在训练期间,算法将在数据中搜索与期望输出相关的模式。训练后,监督学*算法将接受新的未知输入,并根据之前的训练数据确定新输入将被分类为哪个标签。监督学*模型的目标是为新出现的输入数据预测正确的标签。在其最基本的形式下,监督学*算法可以简单地写成:
其中 Y 是由映射函数确定的预测输出,该映射函数将类别分配给输入值 x 。用于将输入特征连接到预测输出的函数是由机器学*模型在训练期间创建的。
监督学*可以分为两个子类别:分类和回归。
分类
在训练过程中,将为分类算法提供具有指定类别的数据点。分类算法的工作是获取一个输入值,并根据提供的训练数据为其指定一个类别或种类。
最常见的分类示例是确定电子邮件是否是垃圾邮件。有两个类别可供选择(垃圾邮件或非垃圾邮件),这个问题被称为二元分类问题。该算法将获得带有垃圾邮件和非垃圾邮件的训练数据。该模型将在数据中找到与任一类相关的特征,并创建前面提到的映射函数: Y=f(x) 。然后,当收到一封看不见的电子邮件时,该模型将使用该函数来确定该电子邮件是否是垃圾邮件。
分类问题可以用大量的算法来解决。选择使用哪种算法取决于数据和情况。以下是一些流行的分类算法:
- 线性分类器
- 支持向量机
- 决策树
- k-最*邻
- 随机森林
回归
回归是一个预测性的统计过程,其中模型试图找到因变量和自变量之间的重要关系。回归算法的目标是预测连续的数字,如销售额、收入和考试分数。基本线性回归方程可以写成这样:
其中 x[i] 是数据的特征,其中 w[i] 和 b 是在训练期间开发的参数。对于数据中只有一个要素的简单线性回归模型,公式如下所示:
其中 w 是斜率, x 是单一特征, b 是 y 轴截距。熟悉吗?对于像这样的简单回归问题,模型预测由最佳拟合线表示。对于使用两个特征的模型,将使用平面。最后,对于使用两个以上特征的模型,将使用超平面。
假设我们想根据学生在考试的那一周学*了多少小时来确定他们的考试成绩。假设用最佳拟合线绘制的数据如下所示:
学*时间(自变量)和学生的最终考试成绩(因变量)之间有明显的正相关关系。当给定新的输入时,可以通过数据点绘制最佳拟合线来显示模型预测。比方说,我们想知道一个学生学*五个小时会有多好。我们可以根据其他学生的表现,使用最佳拟合线来预测考试分数。
有许多不同类型的回归算法。下面列出了三种最常见的方法:
- 线性回归
- 逻辑回归
- 多项式回归
简单回归示例
首先,我们将导入所需的库,然后创建一个输出不断增加的随机数据集。
然后,我们可以将最佳拟合线与所有数据点一起放在图上。
然后我们将打印出回归模型的斜率和截距。
**print**("Slope: ", reg**.**coef_[0])
**print**("Intercept:", reg**.**intercept_)
输出:
Slope: 65.54726684409927
Intercept: -1.8464500230055103
中学的时候我们都学过一条直线的方程是 y = mx + b 。我们现在可以创建一个名为“predict”的函数,它将把斜率( w )乘以新的输入( x )。该函数也将使用截距( b )返回一个输出值。创建函数后,我们可以预测当 x = 3 和 x = -1.5 时的输出值。
Predict y For 3: 194.7953505092923
Predict y For -1.5: -100.16735028915441
现在让我们用最佳拟合线来绘制原始数据点。然后,我们可以添加我们预测的新点(红色)。不出所料,它们落在最佳拟合线上。
结论
监督学*是机器学*的最简单的子类别,是许多机器学*从业者对机器学*的介绍。监督学*是最常用的机器学*形式,并已被证明是许多领域的优秀工具。这篇文章是三部分系列文章的第一部分。第二部分将涵盖无监督学*。
关于数据科学及其能为您的企业带来什么的简要介绍
原文:https://towardsdatascience.com/a-brief-primer-on-data-science-and-what-it-can-do-for-your-business-cc723f3d911c?source=collection_archive---------24-----------------------
随着互联网上所有数据的出现,出现了一个新的研究领域,称为数据科学,这是旧的商业分析的副产品,但带有机器学*的扭曲。这不是一个新概念,但十年前,拥有一个与开发人员合作的数据科学团队并不常见。现在,数据科学团队是一组开发人员中有益的一部分。这对您的开发团队来说是一个昂贵的额外工作,所以这里简单解释一下数据科学过程以及数据模型能为您做什么。
什么是数据科学?
数据科学的简单定义是,它是分析信息和预测结果的研究。预测主要是使用机器学*进行的,但仅仅一个模型就可能需要数月的数据提取、清理、编码和部署。
与使用基本算法的标准应用程序相比,数据科学需要更大的数据存储库。你不能用几十个存储的记录来准确地分析数据。你需要数百万条记录来建立和测试一个模型。数据科学家与任何组织合作的第一步是收集和清理数据。您可能听说过“大数据”,甚至可能在您当前的应用中使用该技术。大数据是非结构化的,但它非常适合数据科学。
非结构化数据技术获取尽可能多的记录,并将它们存储在 MongoDB 等数据库中。这些数据可以是任何东西,但是作为一个例子,考虑一个网站和它的每个页面。爬行器在网站上查找页面,并将其文本、图像和链接存储在非结构化记录中。只要您使用支持非结构化格式的数据库,您就可以抓取整个网站并获取其数据,而不必担心在抓取时结构化数据。
下一步是清理数据,这可能是数据科学中最繁琐的部分。大多数科学家清理数据并将其加载到 CSV 文件中,CSV 文件是以逗号分隔的值列表。这些文件很容易导入到另一个数据库或代码中,并且任何操作系统都支持它们。
收集完数据,就该搞清楚它的功能了。数据科学家首先分析他拥有的数据,并提出一个问题。例如,也许你想知道什么产品更有可能吸引顾客。您可以从您的电子商务商店获取数据,并使用以前的客户订单来确定哪些产品最受欢迎,哪些产品在假期可能会受欢迎,以提高您的销售并专注于营销工作。数据科学模型可以为你回答这个问题,并使用机器学*进行预测,以促进你的销售。
建造模型
在数据科学家和业务部门确定要回答的问题后,就该构建模型了。模型是代表问题“答案”的代码单元。答案通常用图表表示,以便公众更容易消费和理解信息。视觉效果通常是导入到项目中的库的一部分,但是数据科学家必须确保将数据转换为图形的分析是准确的。
通常选择两种主要编程语言中的一种来创建模型。r 是数学和统计的语言,所以如果你的科学家有数学教育背景的话,r 是可能的选择。更多人了解 Python,Python 适合其他开发项目,更受数据科学家欢迎。大学教授 Python,由于它在编程界的广泛使用,您可能会发现它更容易实现,学*曲线更短。
数据科学家带着问题创建模型。以电子商务为例,它是这样工作的:数据科学家将检查数据,并将其设置为行和列,以导入 Python 代码,然后 Python 代码计算并显示为图形。图形可以是任意数量的绘图、图表,甚至是可视化工具,如 Excel 或 PowerPoint。视觉输出用于向企业提供信息,以便他们签署结果。一旦分析被证明是准确的,数据科学家就可以进入下一步,即创建模型。
该模型的基础是逻辑代码,它获取存储在 CSV 文件中的数据,并通过数据科学家的算法运行这些数据。这些算法可以是开源的,也可以是科学家定制的。开发人员深入分析以更好地理解必须部署什么并不罕见。
虽然每个模型都是不同的,但是你可以把它们想象成一个代表问题答案的代码模块。业务部门提出问题,数据科学家以模型的形式开发解决方案。
模型部署
整个数据科学工作流程中最困难的部分之一是部署模型。科学家必须与开发人员合作,将模型(用 R 或 Python 编写)转换成本地应用程序的语言,可以是任何语言,如 C#、JavaScript、PHP 或 VB。开发人员可能不是分析专家,这取决于科学家以一种使开发人员易于转换的方式来解释模型。
从统计上来说,大多数模型甚至从未应用过。开发人员在没有完全理解代码做什么的情况下,不愿意将机器学*代码部署到应用程序中,但企业有必要利用每个模型。
金融行业是机器学*模块和本地应用的一个很好的例子。当你去百货商店找收银员要赊账时,你给了她一些关于你自己的信息,却没有讲述你的生活故事。仅从你的社会安全号码、姓名和出生日期,一种算法就可以决定是否给你信用。这些财务决策是使用数据科学模型做出的。
模型回答的问题是:“你是一个值得信赖的信用候选人吗,你的数据历史表明你会还钱吗?”你知道对信贷申请的回应要么是要么不是。由数据科学家编写的数据模型做出这一决定,他们使用机器学*在数百万条记录中挑选模式。
将数据科学整合到业务代码中
建立一个新的数据团队成本很高,需要时间,而且开发人员需要一个学*曲线。好处远远大于坏处,你可以与项目经理和代理机构合作来帮助你开始。
如果您想将您的业务分析提升到一个新的水平,向您当前的 IT 团队添加一名数据科学家是一个不错的选择。您的开发人员将学*新的技能,您的企业将赚更多的钱,并且您可以利用最新的代码设计和数据库存储技术。
幻灭优化的简单入门
原文:https://towardsdatascience.com/a-brief-primer-on-optimization-to-unlock-the-universe-7d5c72af59e1?source=collection_archive---------25-----------------------
Photo by Luca Bravo on Unsplash
人工智能、机器学*和运筹学之间有什么共同点?优化,优化,优化…
你有没有想过所有这些疯狂的深度学*算法和机器学*论文的背后是什么?核心是优化,即拟合参数以最小化或最大化某个目标函数。在这篇文章中,我将给出一个关于优化和各种子类别的简要概述。在进一步阅读之前只要记住一件事,针对人工智能和机器学*爱好者:
实际上,我还要写一份免责声明:
这里没有高等数学,只有纯粹的直觉。
首先,让我们明确一件重要的事情,什么是优化。大多数情况下,我们需要学*某种参数θ,以便最小化目标函数。具体来说,我们写如下:
所以有某种函数, L 我们称之为目标函数。我们想把它最小化。现在,我们不会对如何实际最小化它感兴趣,但是我们将在优化类型之间进行高层次的区分。
- 我们有无约束最优化。这基本上意味着我们可以最小化/最大化目标函数,而不用考虑其他任何事情,这使得问题变得简单了一些。
- 另一方面,有约束优化在这种情况下,我们有一组特定的约束。这些规则规定了我们可以使用什么样的参数 θ 进行最小化。
现在我们知道了什么是约束优化,什么是无约束优化。让我们转向最低限度的问题。显然,各种优化都与寻找某种最大值的最小值有关。正确的措辞应该是极端。关键在于搜索是局部极值还是全局极值。
- 局部极值更容易找到,我们可以只看一下一阶和二阶条件来检查某个东西是否是局部最小值或最大值。一阶意味着检查目标函数的一阶导数是否等于 0,并检查我们是否具有正曲率或负曲率(二阶导数)。
- 全局极值,则有点奸计。找到全局最小值或最大值并确认它们是全局的真的很难!然而,在某些情况下,函数有很好的性质,比如凸性,我们可以说我们的算法肯定会收敛到全局最小值。虽然很吸引人,但实际上这种情况很少发生,我们无法保证全局最小值/最大值。
在这个超级简单的 2D 例子中,我们看到了一个全局最小值和一个局部最小值。如果我们进行基于梯度的优化,我们通常会对参数进行如下更新:
所以我们在时间步 t 有一些参数,它们在时间步 t+1 结束。更新是神秘的 η 乘以向量p的简单加法。这些方法中的整个研究基本上关注于为更新方向(向量 p )和步长参数 η定义良好的值。
你可以想象一下,如果算法的步长和方向都不够好的话,想要走到全局最小值是相当困难的。一开始就有好的方向是什么意思?嗯,这意味着我们的参数更新的方向向量 p 与梯度向量形成一个小于或等于 90 度的角度 α (对正在优化的函数性质的一些细节取模),如下图所示:
实际上是一个不好的方向,显然与我之前说的相反。当角度大于 90 度时。也许这对你来说听起来不太直观,但是想象一下下面的情况:
将它直接放在函数的上下文中,您可以查看下图并了解其效果:
你走反了方向!显然你不会达到当地的最低值。但是方向不是唯一要担心的…
是的……步长非常重要,选择时也很重要。为了说明这一点,请看下图:
Big step in the wrong direction = missing the minimum.
我们在优化中迈出了太大的一步,因此我们错过了函数的实际最小值。为了进一步说明这一点,请看下图:
如果在我们用向量 p 进行更新的点处,步长是相同的,那么我们将被卡住。因此,所有这些学*率的调整,适应性时刻等等——都是为了避免这种情况。
区分不同优化方法的另一个因素是目标函数的性质。你可能已经假设目标函数只是一个简单的连续函数。但事实未必如此,如果是随机的呢?
- 确定性优化关注相对“正常”的函数。它们是正常的,因为它们不会在随机过程中发生变化。
- 在随机(随机)的情况下,基础函数可能会在未来发生变化,因此我们只能处理期望值并最小化我们估计的不确定性。
约束优化是一个有点高级的话题,所以让我们来谈谈无约束优化和不同的可能方法。显然,一篇博客文章不足以涵盖所有的优化方法。但是我们可以有把握地说,大多数约束优化方法本质上是基于无约束方法的。无约束方法可以分为以下几大类:
- 线搜索法是更常用的方法。这是你古老的梯度下降法。本质上,这些方法试图确定方向和步长,以基于关于目标函数的信息来更新参数。
- 信赖域方法只不过是线搜索方法,但它们在某一点周围对与原始函数相似的模型函数进行线搜索,并根据模型函数与原始目标函数相比的良好程度来限制参数的移动。
优化文献很广泛,但我可以理解每个人都想跳入机器学*和人工智能。就我个人而言,我发现深入挖掘所有这些方法来理解所有这些方法的基本原理是非常有用的,这些方法被反复使用。
我希望这篇文章有助于揭示这些优化器在更高层次上实际做了什么。一旦你摆脱了那些让整个事情看起来过于“复杂”的丑陋等式,这些概念就相对容易掌握了。实际上,一些关于梯度优化器的同样复杂的论文在他们的证明中有著名的错误,但是直觉上这些方法是相当简单的。(不会指名道姓,可能会在后面的文章中涉及:)。
感谢您的关注!
Apache Hadoop 小结:大数据问题的解决方案和来自 Google 的提示
原文:https://towardsdatascience.com/a-brief-summary-of-apache-hadoop-a-solution-of-big-data-problem-and-hint-comes-from-google-95fd63b83623?source=collection_archive---------3-----------------------
欢迎来到大数据和 Hadoop 简介,我们将在这里讨论 Apache Hadoop 以及大数据带来的问题。Apache Hadoop 如何帮助解决所有这些问题,然后我们将讨论 Apache Hadoop 框架及其工作原理。
关于大数据
据估计,全球约 90%的数据是在过去两年中创建的。此外,80%的数据是非结构化的,或者以各种各样的结构存在,这很难分析。
现在,你知道产生的数据量了。虽然如此大量的数据带来了巨大的挑战,但更大的挑战是这些数据没有安排好的格式。它有图像,线流记录,视频,传感器记录,GPS 跟踪细节。简而言之,它是非结构化数据。传统系统在处理结构化数据方面很有用(也很有限),但它们无法管理如此大量的非结构化数据。
有人可能会问,为什么还要关心存储和处理这些数据呢?出于什么目的?答案是,无论我们在哪个领域工作,我们都需要这些数据来做出更明智、更有计算力的决策。商业预测并不是一件新鲜事。过去也编制过,但数据很少。在竞争中遥遥领先,企业必须使用这些数据,然后做出更明智的决策。这些决策从猜测消费者的偏好到提前预防欺诈活动。每个领域的专业人士可能会找到他们分析这些数据的原因。
The four V’s of Big data(IBM big data club)
大数据系统的特征
当您需要确定您需要在后续项目中使用任何大数据系统时,请查看您的应用程序将构建的数据,并尝试观察这些特性。这几个点在大数据行业被称为 4 V。
卷
量绝对是大数据的一部分。互联网-移动周期带来了大量的社交媒体更新、来自工具的传感器数据和电子商务的爆发,这意味着所有行业都被数据淹没,如果你知道如何处理数据,这些数据会有惊人的价值。
品种
SQL 表中收集的结构化数据已经成为历史。如今,产生的 90%的数据是“非结构化的”,以各种形状和形式出现——从地理空间数据到可以调查内容和思想的推文,再到照片和视频等视觉数据。
那么,它总是以结构化形式出现,还是以非结构化或半结构化形式出现?
速度
每天每分钟,全球用户在 Youtube 上上传 200 小时的视频,发送 30 万条推文,携带超过 2 亿封电子邮件。随着网速越来越快,这个数字还在增长。
那么,您的数据和速度的未来如何?
大实话
这适用于营销人员可用数据的不确定性。这也可以称为数据流的可变性,它是可变的,使组织很难快速和更恰当地做出响应。
Google 如何解决大数据问题?
这个问题首先引起了谷歌的兴趣,因为他们的搜索引擎数据随着互联网行业的革命而爆炸。很难找到任何证据证明它的互联网产业。他们利用并行处理理论巧妙地解决了这个难题。他们设计了一种叫做 MapReduce 的算法。该算法将任务分成小块,并将这些小块分配给通过网络连接的许多计算机,并将所有事件集合起来形成最后的事件数据集。
Google.com
当你明白 I/O 是数据处理中成本最高的操作时,这看起来是合乎逻辑的。传统上,数据库系统将数据存储在一台机器中,当您需要数据时,您可以以 SQL 查询的形式向它们发送一些命令。这些系统从存储中获取数据,将其放入本地存储区,进行处理,然后发送回给你。这是您可以用有限的控制数据和有限的处理能力来做的真正的事情。
但是当你看到大数据时,你不能在一台机器上收集所有的数据。你必须把它保存到多台电脑中(可能是数千台设备)。当您需要运行查询时,由于高 I/O 成本,您不能将数据聚集到一个位置。所以 MapReduce 算法做什么;它处理您对所有节点的查询,每个节点都有数据,然后汇总最终结果并返回给您。
它带来了两个显著的改进,即非常低的 I/O 成本,因为数据移动是最小的;因为您的作业并行运行在多个机器上,变成更小的数据集。
Apache Hadoop ( hadoop.apache.org)
Hadoop 简介
Hadoop 支持利用大数据提供的机会,克服遇到的挑战。
什么是 Hadoop?
Hadoop 是一个开源的、基于 Java 的编程框架,在分布式计算环境中继续处理大型数据集。它基于谷歌文件系统或 GFS。
为什么选择 Hadoop?
Hadoop 在包含数 Pb 信息的数千个节点的分布式系统上运行的应用程序很少。它有一个分布式文件系统,称为 Hadoop 分布式文件系统或 HDFS,可以在节点之间快速传输数据。
Hadoop 框架
Hadoop Framework
Hadoop 分布式文件系统(Hadoop HDFS):
它为 Hadoop 提供一个存储层。它适用于分布式存储和处理,即当数据被存储时,它首先被分配&然后继续。
HDFS 提供命令行界面与 Hadoop 交互。它提供对文件系统数据的流访问。所以,它包括文件权限和认证。那么,这里存储数据的是在 HDFS 存储数据的 HBase。
HBase:
它有助于在 HDFS 存储数据。它是一个 NoSQL 数据库或非关系数据库。HBase 主要用于需要对大数据进行随机、实时读/写访问的情况。它支持大量数据和高吞吐量。在 HBase 中,一个表可以有数千列。
因此,到目前为止我们已经讨论了数据如何分发&存储,如何理解这些数据如何被摄取&传输到 HDFS。Sqoop 做到了。
Sqoop:
Sqoop 是一个设计用来在 Hadoop 和 NoSQL 之间传输数据的工具。它可以将 Oracle 和 MySQL 等关系数据库中的数据导入 HDFS,并将 HDFS 的数据导出到关系数据库。
如果想摄取流数据、传感器数据或日志文件等数据,那么可以使用 Flume。
Flume:
Flume 分布式服务,用于摄取流数据。所以,分布式数据收集事件数据&把它传送到 HDFS。它非常适合来自多个系统的事件数据。
数据在 HDFS 中传输后,它进行处理,其中一个处理数据的框架是 SPARK。
SPARK:
一个开源的集群计算框架。它提供了比 MapReduce 快 100 倍的性能。与基于双态磁盘的 MapReduce 相比,对于具有内存原语的少数应用程序。Spark 在 Hadoop 集群中运行&在 HDFS 处理数据它也支持多种多样的工作负载。
Spark 有以下主要部件:
Spark Major components
Hadoop MapReduce:
是另一个处理数据的框架。最初的 Hadoop 处理引擎主要基于 JAVA。基于 Map 和 Reduce 编程模型。许多工具,如蜂巢,猪建立在地图上减少模型。它是广泛的&成熟的容错框架。它是最常用的框架。
数据处理之后,就是开源的数据流系统 Pig 做的分析。
猪:
它是一个开源的数据流系统。它主要用于分析。它将 pig 脚本转换为 Map-Reduce 代码,使生产者不必编写 Map-Reduce 代码。像 filter & join 这样在 Map-Reduce 中很难执行的特殊查询可以使用 Pig 有效地完成。这是编写 Map-Reduce 代码的替代方法。
也可以练* Impala 分析数据。
Impala:
它是一个运行在 Hadoop 集群上的高性能 SQL 引擎。它是交互式分析的理想选择。它的延迟非常低,可以用毫秒来衡量。
支持 SQL 的一种方言(Impala SQL)。Impala 支持续集的方言。因此,HDFS 的数据被模拟成一个数据库表。还可以使用 Hive 实现数据分析。
Hive:
它是 Hadoop 上面的一个抽象盖。和黑斑羚很像。但是,它更适合数据处理和 ETL(提取、转换和加载)操作。Impala 优先用于即席查询,hive 使用 Map-Reduce 执行查询。然而,用户不需要在低级 Map-Reduce 中编写任何代码。Hive 适用于结构化数据。在对数据进行检查之后,用户就可以访问支持数据搜索的内容了,这可以使用 clutter is Search Cloudera 来完成。
cloud era Search:
这是一款接*实时的访问产品,它使非技术用户能够搜索和浏览存储在 Hadoop 和 HBase 中的数据,或将数据摄取到其中。在 Cloudera 中,用户不需要 SQL 或编程技能就可以使用 Cloudera search,因为它提供了一个简单的全文搜索界面。这是一个完全混合的数据处理平台。
Cloudera search 提供灵活、可扩展且强大的存储系统,并结合了包括 Hadoop 在内的 CD8 或 Cloudera 发行版。这排除了跨基础架构移动大型数据集来处理业务任务的需要。MapReduce、Pig、Hive 和 Sqoop 等 Hadoop 作业都有工作流。
oo zie:
oo zie 是一种工作流或协调方法,可以用来管理 Hadoop 作业。Oozie 应用程序生命周期如图所示。
Oozie lifecycle ( Simpliearn.com)
在工作流的开始和结束处发生了多个操作。
Hue:
Hue 是 Haddop 用户体验的缩写。它是一个开源的 web 接口,用于使用 Hadoop 分析数据。您可以使用 Hue 执行以下操作。
1。上传和浏览数据
2。在 Hive 和 Impala
3 中查询一个表。运行 Spark 和 Pig 作业
4。工作流搜索数据。
Hue 让 Hadoop 变得易于使用。它还为 hive、impala、MySQL、Oracle、Postgre SQL、Spark SQL 和 Solar SQL 提供了编辑器。
现在,我们将讨论所有这些组件如何协同工作来处理大数据。
大数据处理有四个阶段。
Four stages of Big data processing ( blog.cloudera.com/blog)
第一阶段获取,从各种资源(如关系数据库系统或本地文件)获取数据或将其传输到 Hadoop。正如我们前面讨论的,sqoop 将数据从我们的 RDMS(关系数据库)转移到 HDFS。
鉴于水槽转移事件数据。第二阶段是加工。在这个阶段,数据被存储和处理。我们前面讨论过,信息存储在分布式文件系统 HDFS 和 NoSQL 分布式数据库中。Spark 和 MapReduce 执行数据处理。
第三阶段是分析;这里的数据由处理框架如 Pig、Hive & Impala 解释。Pig 使用 Map 和 Reduce 转换数据,然后解释它。Hive 还基于映射和 Reduce 编程,更适合结构化数据。
第四阶段是访问,通过 Hue 和 Cloudera search 等工具执行。在此阶段,用户可以访问已分析的数据。Hue 是探索数据的网络界面。
现在,您已经了解了 Hadoop 框架的所有基础知识,可以继续努力,成为数据工程师专家。但我会继续写关于 Hadoop 和其他机器学*主题的文章。如果你喜欢随时了解最新消息,你可以关注我或者 LinkedIn。你也可以看看我的基于从网上导入的数据的系列。我在这个系列中谈到的一切都是基本的。
* [## 一些你不知道的数据文件如果你只是一个数据科学的初学者,导入数据文件…
如果你是数据科学领域的新手,那么你必须努力学*数据科学概念。现在…
towardsdatascience.com](/something-you-dont-know-about-data-file-if-you-just-a-starter-in-data-science-import-data-file-e2e007a154c4) [## 忘记 API 用漂亮的汤做 Python 抓取,从 web 导入数据文件:第 2 部分
API 并不都是为你准备的,但是美丽的汤会永远伴随着你。
towardsdatascience.com](/forget-apis-do-python-scraping-using-beautiful-soup-import-data-file-from-the-web-part-2-27af5d666246)
参考:
- https://data-flair.training/blogs/hadoop-tutorial/
- https://www . simpli learn . com/introduction-to-big-data-and-Hadoop-tutorial
- 【https://howtodoinjava.com/hadoop/hadoop-big-data-tutorial/
- https://www . academia . edu/8243093/Solving _ Big _ Data _ Problems _ Using _ Hadoop _ and _ MapReduce
- https://hub . packtpub . com/how-Google-MapReduce-works-big-data-projects/*
熊猫之旅
原文:https://towardsdatascience.com/a-brief-tour-of-pandas-9f10a8ce490a?source=collection_archive---------35-----------------------
Photo by Diana Silaraja on Pexels
Pandas 是一个用于处理数据的 python 库。在这篇文章中,我们将回顾我作为数据科学家最常用的一些 pandas 方法。
首先让我们导入熊猫库:
import pandas as pd
- 读取数据
我通常对熊猫做的第一件事就是把数据读入所谓的熊猫数据帧。我们将使用来自 Kaggle 的奥斯丁动物中心收容所结果数据。如果我们想在。csv 文件我们可以做到以下几点:
df = pd.read_csv("aac_shelter_outcomes.csv")
我们也可以使用。头()和。tail()方法分别查看第一行和最后五行数据:
print(df.head())
print(df.tail())
我们还可以查看列名:
print(df.columns)
这对于包含大量列的数据集尤其有用。
2.清理资料用。dropna()和。菲尔娜()
在真实数据中,我们经常需要处理数据列中缺失的值。使用 pandas,我们可以通过执行以下操作快速了解数据有多稀疏:
print(df.isnull().sum())
如果数据中有缺失值,我们可以使用。dropna()方法删除这些值。这可以就地完成,我们可以返回一个值,我们可以将它存储在一个新的变量中。要将缺少的值放到适当的位置:
df.dropna(inplace=True)
这里 df 变量已经被修改了。或者,我们可以:
df = df.dropna()
我们可以在删除丢失的值之前和之后检查数据帧的长度:
print("Length Before:", len(df))
df.dropna(inplace=True)
print("Length After:", len(df))
类似地,如果您想要填充数据帧中缺失的值,我们假设在适当的位置用零填充:
df.fillna(0, inplace=True)
或者:
df = df.fillna(0)
因为我们在这里输入缺失值,所以数据帧的长度不应改变:
print("Length Before:", len(df))
df.fillna(0, inplace=True)
print("Length After:", len(df))
3.过滤数据
我们可以很容易地根据列值过滤数据帧。例如,如果我们想要阉割的雌性獒混种狗,我们可以写:
df = df[df['breed'== 'Mastiff Mix']]
df = df[df['sex_upon_outcome'] == 'Spayed Female']
print(df.head())
我们也可以很容易地处理时间戳。pandas 将大多数时间值处理为字符串,因此我们需要将感兴趣的日期转换为 datetime 对象:
df['date_of_birth'] = pd.to_datetime(df['date_of_birth'])
我们还可以从日期时间值中提取周、月和年的值:
df['week_of_birth'] = df['date_of_birth'].dt.week
df['month_of_birth'] = df['date_of_birth'].dt.month
df['year_of_birth'] = df['date_of_birth'].dt.year
print(df.head())
然后,我们可以根据周、月或年过滤数据框架。例如,我们可以提取第一个月的数据:
df = df[df['month_of_birth'] == 1]
print(df.head())
我们可以看到,由于我们删除了一些数据,指数也被修改。我们可以使用 reset_index 来解决这个问题:
df = df[df['month_of_birth'] == 1].reset_index()
print(df.head())
我们也可以重新定义指数:
df = df.set_index('month_of_birth')
print(df.head())
4.选择行和列
我们可以利用。iloc()来选择索引。要选择数据集中的第一个、第二个和最后一个索引:
print(df.head())
print("---------------------First---------------------")
print(df.iloc[0])
print("---------------------Second---------------------")
print(df.iloc[1])
print("---------------------Last---------------------")
print(df.iloc[-1])
你可以用。特定列的 loc():
print("---------------------First---------------------")
print(df.loc[0, 'breed'])
print("---------------------Second---------------------")
print(df.loc[1, 'breed'])
我们也可以在一列中选择多行:
print("---------------------First---------------------")
print(df.loc[0:3, 'breed'])
print("---------------------Second---------------------")
print(df.loc[3:6, 'breed'])
5.汇总数据&生成统计数据
另一个有用的方法是。可用于聚合数据的 groupby()方法。假设我们想知道数据集中某一年每种类型的品种的数量:
df = df.groupby(['year_of_birth', 'breed'])['breed'].count()
print(df.head())
假设我们需要每个品种的平均出生周数:
df = df.groupby('breed')['week_of_birth'].mean()
print(df.head())
我们可以使用 sum()、std()、max()和 min()等方法进行类似的聚合。
6.写入文件
最后,如果我们对数据帧做了足够的修改,我们会想把它保存到一个单独的文件中。to_csv():
df.to_csv("new_name_of_file.csv")
我希望这有所帮助。这篇文章的代码可以在 GitHub 上找到。
祝你好运,享受你的熊猫之旅!
用于教授机器学*的纸牌游戏
原文:https://towardsdatascience.com/a-card-game-for-teaching-machine-learning-547611fb69d9?source=collection_archive---------38-----------------------
解释监督学*、非监督学*和强化学*
Image www.pexels.com
由于人工智能和机器学*在我们的社会中越来越重要,关于它们的知识是一般知识的重要组成部分。这也给科学家和教育工作者提出了一个问题,如何教授这个主题和重要的基本概念。如下文所述,已经有向小学生教授这些内容的方法:
[## 向小学生解释人工智能
最*,有人请我给五六年级的小学生(即年龄…
towardsdatascience.com](/explaining-ai-to-primary-school-kids-9d875d23ec1e)
它背后的技术,尤其是数学基础,并不是每个人都喜欢的。因此,需要新的知识转移方法。
我为我的学生开发了一个纸牌游戏,帮助他们理解机器学*的重要原理。我想在本文中简单介绍一下。该游戏旨在展示“监督学*”、“非监督学*”和“强化学*”的原理。学生们以一种有趣的方式发现最重要的想法,并对机器学*程序的功能发展出一种感觉。
这套扑克牌由 32 张印有独立图案的牌组成。每张扑克牌代表一个数据集。
无监督学*
学生被分成 4 人一组,每个游戏组收到以下 16 张扑克牌:
Cards without labels / Image by the author
任务是将卡片分成 4 组,学生们认为它们属于同一个组。然后他们必须描述哪些特征被用来区分。
可以根据以下特征来区分纸牌:
-线条的粗细
-线条颜色的不透明度
数据的所有其他特征,如颜色、行数、精确定位等。对区分没有贡献。
这些卡片组具有以下特征:
-A 组:4 毫米线宽,50%不透明度
-B 组:4 毫米线宽,100%不透明度
-C 组:6 毫米线宽,100%不透明度
-D 组:6 毫米线宽,50%不透明度
任务是教导机器学*算法学*特征的正确特征和特性是重要的。将数据表示为特征值是至关重要的。它还展示了无监督学*(聚类)是如何工作的。
监督学*
第二个任务是解释卡片上能看到什么。然而,这需要额外的信息。这是以 16 张附加卡片的形式给出的,除了图案之外,还注明了卡片上可以看到的内容。有 4 个不同的“对象”可以查看:
“A”、“B”、“C”和“D”:
Cards with labels / Image by the author
因此,学生的任务是分配任务 1 的 4 组中的哪一组属于哪一类物体。额外的卡片代表一个带标签的数据集,这项任务阐明了监督学*的原理。
强化学*
第三个任务是以不同的方式找出哪些对象属于比其他对象“更强”的特定类。没有“标签数据集”形式的数据显示与此类的关联。对象的这种特殊属性必须由学生纯粹从游戏行为中获得。
游戏的规则如下:
-一组 4 个玩家中的 2 个在不告知其他两个的情况下,将 4 个类别中的一个固定为特殊类别(“川普”)。
-任务的目标是其他两名玩家在游戏的下一阶段找出哪些牌属于“王牌类别”。
-打出带有标记的 16 张牌。这些牌被分成 4 张牌,每张牌有 4 张。
-4 名玩家每人在一轮中将一张牌放在桌上。拥有竖线数量最多的牌的玩家赢得这一轮,并获得所有 4 张牌。除非其中一张牌属于“王牌”类别,否则它赢。(这个可以由 2 位选手来判断。)
-如果回合中王牌类别的牌较多,则线条最多的王牌获胜。
-如果几个有相同线数的玩家赢了,则牌被分开。
从几轮比赛的结果来看,肯定是试图认清“川普”的属性。
基本思路来源于卡牌游戏"Watten"(https://en . Wikipedia . org/wiki/Watten _(card _ game)))
在这个游戏中练*的以卡片(物体)为王牌的学*形式,是一种强化学*的形式。在每一轮之后,给出一个玩家的理论,哪个类别是该轮结果的王牌或者被丢弃。
通过这 3 项任务,可以借助卡片展示机器学*的不同变体。通过有趣的方法和学生自己的实验,理解得到了促进,障碍被消除了。
卡的 PDF 文件可在此下载打印:
http://www . stoeckl . ai/WP-content/uploads/2019/12/ml cards _ part 1 . pdf
http://www . stoeckl . ai/WP-content/uploads/2019/12/ml cards _ part 2 . pdf
核能案例:用低碳能源架起通往可再生能源的桥梁
原文:https://towardsdatascience.com/a-case-for-nuclear-bridging-the-route-to-renewables-with-low-carbon-energy-f0ad069a37ce?source=collection_archive---------5-----------------------
循证政策比你或你的感觉更重要——第三部分
他们说破解偏见比破解原子更难。如果所说的偏见是关于分裂原子,这句格言就更正确了。在全球范围内,只有 38% 的人赞成核能,甚至低于出于某种原因支持煤炭发电的 48%。相比之下,可再生能源的支持率高达 97%(太阳能)和 93%(风能)。绿色很酷(至少作为一个概念)。尽管几乎所有国家的能源组合都与这些公开宣称的偏好相去甚远,但可再生能源得到了大量补贴,因此正在崛起,与煤炭、石油或天然气等污染能源展开竞争,并逐渐取代它们。他们应该这样做。然而,由于某种原因,核能经常被包括在所述肮脏能源中。这不仅导致了低支持率,也为从能源组合中彻底去除核能铺平了道路。如果你关心环境,那是你现在最不应该做的事情。
核能是一种高效&低碳能源
分裂一个原子,如核反应堆中最常用的同位素铀-235,会释放出巨大的能量,这些能量可以以电能的形式加以利用。在美国,* 100 个剩余的核反应堆仍然提供了该国约 20%的电力输出。比这个数字更重要的是,与将核能与煤 T15 气混为一谈的企图相反,提供的能源是清洁低碳能源。事实上,核能仍然占美国所有低碳能源的一半以上,因为所采用的核链式反应本身不会导致二氧化碳排放。
A) 2017 US energy mix (consumption) in percent. B) Relative proportion of low-carbon energy sources for the 2017 US energy mix (consumption). Source
还有更多支持核能的理由。铀具有极高的能量密度,其需求量远低于煤或天然气。因此,铀的开采足迹与破坏和污染景观的巨大煤矿或者将石油泄漏到珍贵生态区的沉没油轮相比是微不足道的。核能发电厂需要的钢材和混凝土仅仅是太阳能或风能产生的相同能量的一小部分。作为一个推论,核能占用的空间/土地也比可再生能源少得多(事实上比可再生能源少几百倍)。但这不是一场核能与可再生能源的战争。如果有什么不同的话,可再生能源和核能应该是团队成员,在一个仍然被碳基能源生产牢牢控制的世界里,这两个纯洁的典范。因为,至少在美国,核能和可再生能源加在一起还不到总发电量的三分之一,其余都来自煤炭、石油和天然气。
由于大众观点&错误的意图,核能目前正在撤退
因此,鉴于之前关于煤炭和天然气在我们的能源组合中占主导地位的说法,你可能会认为公民、活动家和政府的首要任务是以牺牲煤炭、石油和天然气为代价来扩大可再生能源。然而令人惊讶的是,环保主义者的愤怒至少在很大程度上也是针对核能的。尽管活动家们宣称气候变化是一种生存风险(我当然会认同),但他们愿意牺牲核能形式的低碳能源生产。因为这是经常发生的事情。由于人们不会神奇地开始使用更少的能源,一旦核反应堆“退役”,它产生的能源现在必须以另一种方式产生。不幸的是,这种方式几乎总是发生在天然气利用的增加,而不是可再生能源的增加,从而增加了二氧化碳的排放。
2012 年加州圣奥诺弗雷核电站关闭事件很好地证明了这一点。通常情况下,这种关闭增加了来自天然气的能源比例,据 T2 估计,这些额外的排放相当于 T4 增加了 200 万辆汽车。这种普遍影响是如此强烈,以至于在全球范围内,尽管可再生能源的发展势不可挡,但从 90 年代到 2014 年,低碳电力的份额下降了几个百分点。至少在很大程度上,这是由于在环保团体的要求下,许多国家关闭了核电站。别误会我的意思。我不赞成建造更多的核电站(至少不赞成目前的核电站形式)。我只是说,如果我们真的关心排放和环境,我们就不应该关闭现有的工厂。可再生能源替代的顺序应该是煤→天然气→核能。目前,我们基本上走的是相反的方向。
假设你不关心环境,只关心你的电费。有一些反对核能的经济论据,其中包括对核电厂所代表的巨大长期投资(每台几十亿美元)的抨击。一座发电厂的建设需要数年时间,并且经常受到延误的困扰。然后,一旦它最终运行,一个核反应堆基本上是永久发电。这对于提供高度可变能量的可再生能源来说不是很好(例如太阳能,它只在白天提供能量,或者水力发电,它受到干旱的影响),并且需要一个灵活的对等物,可以在停机期间进行补偿。这是天然气取代核能的一个原因,因为它天生灵活,适应可再生能源的节奏。此外,由于新的压裂技术,不幸的是真的很便宜。
我们可以很容易地绕过关于长期投资的第一个论点,重申这场辩论不是关于建设新的核电站,而是尽可能长时间地保留剩余的核电站。关于核能发电缺乏灵活性的第二个论点可以通过两点来解决。首先,像安装在瑞士 Goesgen 工厂的这样的技术允许对核反应堆输出进行高达 50%的调节(每分钟 30 兆瓦),从而大大增加了核电的灵活性。第二,开发高效电池来储存能量不仅有助于核能保持竞争力,还能缓解可再生能源的不确定性。最后,关于成本因素,我们必须记住可再生能源获得的令人难以置信的补贴,这是它们相对较低的电力成本的原因。因此,如果有真正的去碳化的政治意愿,人们可以设想对核能进行某种程度的补贴,以抑制煤和天然气的使用。
核能比你想象的要安全得多
当然,在讨论核能时,我们必须面对这个问题:安全。环保主义者经常引用安全问题作为论据,这也是为什么那些将气候变化视为生存危机的活动人士矛盾地将核电站视为生存威胁的原因之一。这里最根本的错误当然是将核能等同于核弹。虽然后者肯定能够夷平整个城市,并通过致命的辐射使周围的大片地区无法居住,但核电站不能也不会这样做。首先,让我们观察一下,在 30 多个国家的核反应堆累积的大约 17 000 个反应堆年中,总共发生了三起重大反应堆事故。
在其中的两起事故中,三里岛和福岛第一核电站,没有一个人死于直接辐射,而有一个人死于癌症。相反,想想最初导致福岛第一核电站反应堆熔毁的海啸在造成的* 16 000 人死亡。历史上最严重的反应堆事故,1986 年切尔诺贝利反应堆熔毁,直接导致 31 人死亡,15 人(直到 2011 年)死于随后的癌症。最常见的辐射引发的癌症,甲状腺癌,幸运的是,如果早期诊断,是可以治疗的(当然,对已知辐射暴露的地区进行严格筛查)。相比之下,每年有多达 1 00 万人死于与煤炭相关的空气污染(加上每年死于煤矿的许多人)。事实上,每一种能源生产方式的每太瓦时死亡率都比核能高,除了水力发电(如果你好奇,人们在安装太阳能电池板时会从屋顶掉下来死去,从而推高了死亡率)。
Safety of energy sources in deaths per terawatt hour (globally, 2011). One terawatt hour is equivalent to one trillion watts. Source
核反应堆熔化时不可能像炸弹一样爆炸。熔毁期间向外界释放的辐射也因剩余的反应堆结构而大幅降低。想想福岛第一核电站的三重熔毁,它未能对继续在现场工作以减轻损害的 200 多名助手造成致命影响。政府研究发现,目前的核反应堆设计可以承受一架加满燃料的波音 767–400迎面相撞,这不仅证明了核反应堆的坚固性,也摒弃了核反应堆是恐怖分子生存威胁或目标的陈腐观点。事实上,几乎没有任何民用建筑比核反应堆防护得更好。
最后,我愿意承认储存核废料是一个问题,尤其是考虑到它保持放射性的时间。然而,有办法解决这个问题。一个步骤是利用核弹头作为反应堆的燃料。除了令人满意的核武库的减少,这通过使用已经放射性的“军事废物”作为输入减少了放射性足迹。另一种在此过程中获得更多能源而不产生更多核废料的方法是核回收,其中你使用一种反应堆的核废料为另一种反应堆提供动力,从相同数量的材料中提取更多的能量。最后但同样重要的是,未来使用钍而不是铀运行的反应堆也将改善这种情况。钍的含量比铀-235 多 500 倍,钍反应堆在运行中会更安全,其核废料的放射性只有传统核废料的千分之一。
核能是一种低碳能源,但却像“肮脏”能源一样受到监管。核能是我们目前拥有的最安全的能源之一,然而它却受到监管,就好像它是最危险的能源之一。这里有一个共同的主题。围绕核能的争论主要是由意识形态而非证据推动的。然而,我们正在输掉这场战斗。越来越多的核电站关闭,不再建造新的反应堆。三里岛在 1979 年经受住了灾难,现在面临着被廉价天然气挤出市场。廉价的天然气将继续加剧气候变化对我们所有人和我们的孩子的可怕影响。如果你不喜欢核能,没关系。也许有一天,我们可以关闭最后一个反应堆,用可再生能源取而代之。但这次不是今天。如果你关心我们的气候环境,你应该关心核能以及替代它的东西。
做对的机会:拥抱自动化决策
原文:https://towardsdatascience.com/a-chance-to-get-it-right-embracing-automated-decision-making-48229904b443?source=collection_archive---------39-----------------------
franki chamak for unsplash
用 ADM 减少偏差
几十年来,我们带着一种无可奈何的无奈目睹了不平衡的权力、财富、种族和性别动态扭曲了我们最基本的权利:自由、追求幸福、工作,甚至是我们头顶上的屋顶。经济差距、种族偏见和性别歧视如此根深蒂固,我们常常忘记看清它们的本质:源于几个世纪的不平等、种族主义和厌女症的系统性偏见决策的结果。
因此……在训练我们人类思维的“数据集”中积累了多年的错误数据。
上周在柏林举行的人工智能峰会上,伦理是一个热门话题。现在,自动化决策(ADM ),或者至少是对它的半知半解,无处不在,对有偏见的数据和歧视性决策的担忧十分猖獗。
是时候了!
政客们正在质疑预测性警务的公平性。伦理机构要求对雇佣算法进行问责。为计算信用分数而输入训练集的数据正在被剖析,以寻找偏见的痕迹。
本质上,既然机器正在做出错误的决定,我们就要奋起反抗。
这里的最终目标——为所有人的利益作出公正的决定——是最崇高的事业。但似乎我们对 ADM 的期望取代了我们对自己的期望,以及我们人类做出公正决定的能力,或者说缺乏这种能力。
这显然没有错!没有人希望机器延续我们人类的弱点。尤其是当两倍、三倍、四倍——质疑数据和决策的准确性和公平性可能意味着正确和不正确的医疗诊断、错误和合理的监禁以及适合我们特定体型的最好和最差牛仔裤之间的差异。好吧…划掉最后一个。
而且,如果我们对完美算法的厚望是由于新发现的不愿对非法监禁、雇佣歧视、偏袒和裙带关系视而不见的结果,那就更好了!健康的怀疑是一种受欢迎的批评和监管形式,如果它确实能防止我们偏离非歧视性(自动化)决策的正确道路。
但最*,对 ADM 的非理性焦虑表明了对人工超级智能和奇点的好莱坞先驱的天真信仰。反对 ADM 的声音越来越大,越来越无知,越来越具有煽动性,这似乎是因为害怕将我们最独特和最具决定性的人类能力,即思考和判断的能力交给机器。考虑到我们在运用这些技能时相对糟糕的记录,这有点荒谬…
如果你从这篇文章中只带走一件事,请让它成为这样:算法做出的任何有偏见和歧视性的自动化决策都是我们自己糟糕的决策能力的直接反映。
不要射杀信使!
有无数的机构、基金会和工作论文致力于道德 AI 和 ADM 的主题。他们阐述了问责制、可追溯性、补救和整体公平的重要性。它们阐明了多样化的团队和庞大的(无错误的)数据集将如何帮助我们做出公正的决策。这很有道理!我们的观点越多,数据越有代表性,判断或评估不公平的可能性就越小。当然,自动化决策和我们一样有缺陷。
因此,与其坚持认为它们是问题所在,不如承认我们确实是问题所在。承认我们历史上不可靠的决策性能可能是自动化决策正确的唯一方式。历史会重演。至少在模拟世界里是这样。在数字世界并非如此。机器与我们相比有一个明显的优势,那就是它们不会注定不断重复错误。他们比我们更好地学*和记忆。
如果训练得当,自动化决策可能会把我们从固有的偏见中拯救出来!
要跟踪关于伦理 ADM 和机器学*的讨论,请查看 WEF 的工作论文 如何防止机器学*中的歧视性结果 。
一个中国人对中国房间的看法
原文:https://towardsdatascience.com/a-chinese-speakers-take-on-the-chinese-room-88a0558b2cc8?source=collection_archive---------5-----------------------
触发预警:无聊指数 9/10。这不是一篇关于激动人心的技术突破的文章,相反,这是一篇人工智能哲学论文,提炼了 40 年之久的中国房间思想实验——如果按照最初的设计工作,智能交流的人将无法理解他们所读或写的东西……
背景
1980 年,在加州大学伯克利分校(我在那里获得数据科学硕士学位)任教的 John Searle 先生发表了著名的中文房间思想实验。
塞尔先生是一位哲学家,他并没有自称是人工智能研究者。然而,中文教室是一个非常有影响力的哲学思想实验,它影响了人工智能研究,尤其是在 NLP 中,也是争论最激烈的实验之一。
此外,塞尔先生“一句中文都不会说”,这是思维实验的关键组成部分之一——它需要是实验者不理解的语言。
有点耐人寻味的是,到目前为止,没有多少说中文的人工智能研究人员加入这场辩论…
中国人的房间
中文房间思维实验的一个过于简洁的描述说如果你有一本完整的规则书,关于什么问题符号序列应该用什么答案符号序列来回答,你可能最终会遇到这样一个人,他不理解那些符号的含义,但却能对用那种语言提出的问题做出“看似”连贯的反应。(不懂中文的人将遵循中文回答规则书,从封闭房间的窗户提供对书面问题的回答;对于房间外的一个说中文的人来说,这和一个真正的说中文的人没什么区别。)
直到这一部分,这是一个僵化的见解。合理的结论是能够产生看似明智的反应可能不足以表明实际上普遍聪明。(Searly 先生演讲中的 StrongAI,或者更广泛的 AI 圈子中的 AGI)
作为一名哲学家,塞尔先生进一步争辩说,这个思想实验意味着一个执行计算机的程序不可能有思想或意识。
虽然最初的思维实验需要一个不懂中文的人被锁在房间里进行实验,以提出一个观点,但作为一个在人工智能相关领域获得学位并会说中文的人,我将重新开始这个讨论,因为自从这个思维实验在* 40 年前首次发表以来,人工智能领域已经经历了巨大的进步…
一位中国演讲者
我在中国北京长大,那里的官方语言是普通话。但是我的祖母只会说广东话,这是一种在中国以外更为人所知的中国方言。粤语是我的“第二语言”。虽然写了下来,但它们 99%是一样的,说一种语言的人很难理解另一种语言。
在去中学学*英语之前,我的想法和塞尔先生一样——学*另一种语言只是学*每个单词的(符号)映射,然后我们可以把新单词(或单词的新发音)放在一起,形成句子、段落和讲话。因为我就是这样学粤语的,所以对我来说,这个假设显然是“被证实了”的。
塞尔先生的思想实验将按照他的设想在字面上完成,略有不同——我可以在一个房间里,使用发音规则口述一个用粤语对我说的句子,写下它们,并写下答案,然后我使用发音规则读出它,本质上,我不会认识或理解粤语,但我将能够通过发音规则书与讲粤语的人交流。
此时,目光敏锐的可能会提出异议:“等等,在你的例子中,你已经理解了书面语言,一旦你写下来,你就理解了,在塞尔先生的中文教室里,他也不理解书面语言。”**
答对了。你猜对了。
B 能够处理“我不理解的符号”以产生有意义的反应,需要超出规则书的相当高的智力水平,我很快就会发现…
学*真正的外语
对于天真无邪的 11 岁的我来说,学*英语的前几个单词“效果很好”。一旦我超越了“桌子”、“椅子”和一个“人”,我就开始质疑老师的胜任能力——“你为什么把它弄得这么复杂,神奇的绘图本在哪里?”
不久,我意识到“嗯……”学*另一种语言不仅仅是用新的符号替换我的词汇,或者用新的规则替换我的句法。我需要学*一整套惯例,句子的构成远非“遵循严格的规则”——它们更像是模式而非逻辑。
事实上,有一个词是由以汉语为母语的英语学*者创造的——“中式英语”。它指的是中国人使用英语单词,但中国人的逻辑和惯例来表达自己。或多或少有点像“遵循规则书来处理新符号”。(还有法国式英语、德国式英语等……)
现在人们普遍认为,学*另一种语言的最好方法是让自己“沉浸”在这种新的语言中,除了词汇和正式语法之外,通过使用它的所有模式和“软规则”来学*。
那么学粤语和学英语有什么区别呢?对于一个说普通话的人来说,粤语的“思维方式”和普通话非常相似——毕竟,它们是同一种语言,只是方言不同(发音、一些短语和一些表达)。这意味着代理人(在这种情况下是我)实际上(几乎)拥有处理新符号所需的所有智能(通过我的第一语言普通话学*),而且粤语和普通话之间确实存在严格的映射规则——然而,这推翻了塞尔先生关于被锁在房间里的人“对中文一无所知”的说法事实上,被关在房间里的人几乎知道所有关于汉语的事情,除了有严格翻译规则的发音。
学*英语是不同的,实际上有一些使用我以前从未练*过的英语语言的智慧,并且采用这样的语言智慧不仅仅是“学*规则”——新的模式,新的抽象方法被获得。
A common joke Chinese speakers tell is “中国队大胜美国队” and “中国队大败美国队” actually both mean the Chinese team beat the Americans — yet, “胜” means winning, and “败” means losing. The logic is in the case of “losing”, it meant “causing… to lose”, if you want it to mean the Chinese team is lost, it needs to be said as “中国队大败于美国队” (败于* means “lost to”).*
实际上,我不能把上面的话直接翻译成英语,没有一种英语表达方式能捕捉到这两种表达方式的语义,并保持这种微妙的*乎幽默的差异是可以理解的。同样,我也不能用中国人的思维方式处理所有的英文符号…
难以捉摸的规则手册
所以,我通过说中文和英文学到的一件事是,要能够处理另一种语言,实际上需要相当高的智力水平!按照简单的“逻辑”规则,我连连贯的英语都说不出来——更不用说聪明地回答英语问题了。
不仅我从未得到过我梦寐以求的学*另一种语言(英语)的规则手册,而且用任何一种语言回答所有问题的规则手册都巧妙地回避了发明(也许永远不会)。
人工智能在过去 40 年中取得的进步之一是研究人员开始承认纯粹基于逻辑的表达不是人类语言的超集——已经证明一阶逻辑是自然语言的子集。意义,我们将无法用一种正式的表达方式来表达一种语言所能传达的所有意义。
换一种说法(一种更哲学的说法),人类的所有智能能否外化为信息存储,独立于信息处理代理?有没有可能有人“转储”了所有人类的智能(不仅仅是知识,而是智能处理所有人类问题所需的全部内容),并保留了所有的智能,以供机械机器(图灵完整机器)进行后期处理?
我们其实离这个问题说“不”越来越*了。
所有智能都可以被记录在静态存储器中,然后只需要进行逻辑处理,就可以像完全智能一样“表现”出来,这种假设被广泛认为是不可行的。人类的智能不能仅仅用公理(可以存储并视为真理的东西)和逻辑推理来完全描述。这主要得益于中国房间实验后几十年人工智能研究的进步。
将所有人类智能外化到信息存储设备的可行性是中文房间思维实验的第一个次要过时点——假设的“完整的中文规则书”不存在。
所以如果中文房间能通过图灵测试,那么肯定有比规则书和房间里藏着的非中文说话者和更多的东西。**
如果我童年时梦想有这样一本简单的规则手册,学*和使用第二语言可能就不会那么痛苦了,但令 10 岁的我沮丧的是,我们从未能够创造出这样一本规则手册。我们在这一领域做的研究越多,我们就越不相信一个纯粹的“规则手册”(或表达的正式语法模型)足以完全表达人类的智慧,实际上,由于能够说中文和英文,我不太确定“你怎么说”和“你说什么”可以完全分开…
语法与语义
塞尔先生选择汉语(与英语相比)作为他的思维实验目标是好的,因为这两种语言的差异足以研究“不同形式的智力表达”。事实上,我很幸运地学会了这两种语言,这帮助我明白了用两种不同的语言表达自己实际上是如何扩展我的智力范围的。重叠不是 100%。(相比之下,如果一个说马德林语的人被锁在一个粤语房间里,思维实验不会揭示太多关于句法和语义理解之间关系的洞察力)。
自 1980 年以来,句法结构和语义问题已被广泛研究(再次,部分归功于塞尔先生的贡献)。
句法“规则”指导如何构造句子(正式)。
语义决定句子所承载和传达的是什么意思(内容)。
塞尔先生认为程序只能从语法上处理,而不能从语义上处理,因此不会产生思维。到目前为止,他看起来基本上是正确的。**
正如塞尔先生所料,时至今日,计算机翻译主要通过句法处理来实现它们的“魔力”。虽然他们这些天做得很好(即谷歌翻译和微软翻译),但我们双语者(尤其是 NLP 研究人员)经常玩递归翻译的游戏——将一个句子从英语翻译成中文,然后将译文翻译回来,结果往往令人捧腹。
像 XLNet、BERT 和较老的 Word2Vec 这样的现代技术(几乎)只在语法上受过训练——至少在设计上是这样。它被输入了数十亿个句子来学*如何分析句子结构。嵌入允许 NLP“理解”语言组件的构造——通过像 SQUAD 这样的训练集,我们可以让 NLP 系统回答 90%以上的自然语言问题——因为它学会了如何提取“问题是什么”和“答案在哪里”。
在这一点上,非常接*于塞尔先生所描述的,我们将自然语言(即英语)输入到 NLP 系统,它将句子编码成向量,我们实际上不太理解为什么或这些向量意味着什么(稍后将详细介绍)。
如果系统可以访问“一个完整的图书馆”(塞尔先生的中文房间里的“故事”),它实际上可以通过首先寻找“相关”段落(主要是搜索工作),然后解析段落以提取答案(主要是语法处理工作),来试图找到“问题”的“最佳答案”。神经元的权重集合充当“规则书”。
至此,NLP 系统实际上对问题和答案都没有直接的理解。它只“理解”上下文(主要是符号搜索)和语法结构(至少我们大多数人是这么认为的)。那和塞尔先生的中文房间设置非常相似,(把中文换成英文,把锁在房间里的假想的人换成伯特,把规则书换成预先训练好的模型)…
嵌入
尽管有两个不便之处:1) XLNet 仍然不能通过图灵测试;2)嵌入虽然对人类来说难以理解,但并不像塞尔先生要求的那样完全“不可理解”。
我们知道前面提到的成就并不完全基于“规则书”,而是使用的关键技术是“嵌入”,这是从简单的一键编码的一次飞跃,这是塞尔先生在创建中文房间思想实验时直观使用的。
嵌入出现在 2003 年左右,直到 2010 年后才开始流行,距离塞尔首次发表思想实验已经过去了* 30 年。它试图从“一字一维”的一热编码中降维,因此可以认为是“压缩”信息空间的方法之一。
第一,XLNet 和 BERT 虽然令人印象深刻,但仍然无法通过图灵测试。(图灵测试不是单轮测试,它是一个统计,系统需要通过 70%的测试才能和人类没有区别,所以那些一次性的炫耀并不被认为是真正通过了臭名昭著的测试。)
从一个说中文的人的角度来看,这并不奇怪。学*像英语这样完全不同的语言,句法规则和语义规则在两种语言之间没有严格的映射。这意味着在一种语言中被认为是语法上的规则可以有语义上的含义。(稍后将详细介绍)
随着 NLP 的飞速发展,越来越多的人怀疑一个纯粹的语法处理系统是否能通过图灵测试。从嵌入进度的方向(仍然无法通过图灵测试),开始模糊语法和语义的边界。
这导致了第二点,虽然我们不太理解嵌入结果向量,但是一些东西被广泛接受:嵌入“保留”了一些语言含义(语义),例如,具有相似含义的单词在欧几里得空间中更接*。此外,相似关系的词对之间的欧几里德距离非常相似。例如,与单词对(男人、女人)相比,单词对(国王、王后)之间的欧几里德距离非常相似。虽然这可能是从句法处理的统计模型中“学*”出来的,但将“国王对王后类似于男人对女人”的知识归类为纯粹的句法知识是没有说服力的。似乎至少在某种程度上,嵌入捕捉到了语言的一些语义特征。
这意味着无论是谁被锁在房间里处理这些嵌入,一个人或一个程序,都不能声称他们不知道这种语言,因为当他们看到两个接*的嵌入时,他们知道它们的意思会很接*。
这意味着嵌入并不是塞尔先生在他最初的中国房间里想象的“曲线”,它不应该带有房间里的人理解的语义。这有可能使中文房间设置无效——这要求被锁在房间里的穷人对中文完全一无所知。包埋似乎不符合实验设置的这一部分。
这进一步增加了人们的怀疑,即一个通过图灵测试的计算机系统可能不仅仅是通过语法处理(形式表达)来完成测试的…
模式识别
关于学*一门新语言,我学到的一件主要事情是,有许多“模式”要“总结”,而不是“抽象规则”要遵循。
在计算机科学中,模式识别在过去几十年中主要作为工程来研究,然而,它也有一些哲学上的重要性。
与此讨论相关的一个特定主题是,模式识别不仅仅是纯句法的。虽然规则可以表示为模式,但一些模式(尤其是人类语言中的模式)是非正式的(不是 100%刚性的规则)这一事实具有重要的意义——模式识别系统识别的内容不能纯粹用“形式表达式”来解释。
随着现代机器学*的进步,模式识别更多的是统计而不是形式。基于统计的模式识别仍然属于塞尔先生要求的“形式语法”描述吗?
一方面,人们可能会认为这是可能的,因为所有的“处理”都是由图灵完整机器完成的——在一天结束时,这些是“海量”的加法和乘法。
另一方面,人们可以争辩说,破坏汉语空间思维实验的统计性质不足以涵盖语义,塞尔先生曾用汉语空间思维实验来证明正式的句法处理语言。
虽然机器学*的早期阶段看起来足够无辜,只是形式处理(句法),但深度学*,尽管理论上仍然使用“相同”的机器学*机制,却能够识别比这复杂几个数量级的模式——有时我们怀疑它是否正在拾取模式的模式。
模式识别还只是海量逻辑运算的集合吗?或者它引入了一种不同类型的“智能能力”?
在人类中,我们通常认为模式识别是与逻辑处理不同智能活动。我们经常发现两者都是执行典型的日常任务所需要的。
从外语学*的角度来看,我们一直认为学*另一种语言,我们需要更多的模式识别而不是逻辑计算。
此外,大量面向统计的处理让人们想起了量子物理学。这是一个有趣的类比,就像量子物理学和经典物理学之间没有已知的明确界限,粒子越小,它表现出量子行为(统计模型)的趋势就越高,物体越大,就越少,但我们没有一个硬限制来分隔两个世界,是 1000 个原子吗?10 万,或者 100 万…
多复杂才算复杂?
我们谈到了“数不清的乘法和加法”,这引出了一个有趣的哲学问题,多复杂才算复杂到把一个东西等同于“许多许多公理的集合”?
音乐只是音符的集合,还是有更多的含义?
经典物理对象仅仅是原子的集合吗,为什么它们的行为不同于它们的任何一个夸克?
现代语言嵌入可能是相当复杂的计算,模拟类似于人类大脑神经元的工作方式——当达到某个阈值时,各层“神经元”会激发,但触发器(或触发器的权重)经过训练,以便各层“神经元”的组合会“最佳”激发,以匹配给定的训练数据。这个过程涉及到非常高维的矩阵计算,大多数人只能“理解其分解的标量计算”,我们很难想象这种矩阵运算的直觉解释。
仅仅因为我们可以分解这个过程的每一个步骤,我们就可以忽略更高层次的“意义”吗?我们怎么知道人类的意识不仅仅是“无意义的量子活动”的集合?
如果技术发展到我们可以实时监控每个大脑神经元对某个特定想法的放电的水平,我们的想法还会是想法吗,或者这一切都变成了“只是电子放电”?(在这个话题上要非常小心,研究人员已经可以利用深度学*将一些脑电波转化为文字,或者假肢的动作)
还有一个更令人不寒而栗的假设——就像量子物理学中,量子粒子在被观测时会“坍缩”。如果在每一个神经元层面(甚至每一个粒子层面)观察,人类的思维是否也会“塌缩”到只有电子?
那么,我们的意识是量子物理之上更高层次的现象吗?为什么量子效应会随着物体质量的增加而减小?量子物理的统计特征对这些差异有重要意义吗?
现代语言模型是统计模型。统计方面一直很吸引人,人类对统计的直觉并不完美。海森堡测不准原理,或者类似的东西,会适用于这种深度学*方法吗?复杂的、不精确的大量计算仍然是“仅仅是计算”吗,或者通过这些计算,更高层次的意义产生了吗?
在阅读理解测试中,我们通常期望有“正确的答案”。这意味着我们可能拥有“存在于人类大脑之外的外部化答案。”
但是在像写作这样的生成性任务中,我们发现非常有趣的是,这些任务广泛地涉及到随机数。GAN 正在使用一种“进化”模型,它从随机生成的内容开始,并通过“对手网络”传递它,然后告诉生成网络它在哪里看起来“错误”。然后,生成器网络将获取该信息,保持它做对的,并改变它做错的,并重复该过程,直到对手网络无法从真实参考中辨别出该代。
这太类似于一个迷你模拟进化,生成网络充当“迭代器”,每次迭代产生有限变化的东西;对手网络的功能有点像自然选择,反馈告诉生成网络什么应该保留,什么应该改变,就像基因在自然选择中所做的一样。所以每一次迭代可以被认为是一个“世代”——双关语。
许多“计算机创造的艺术品”包括识字都是这样产生的,这进一步突出了这类任务的非语法和不确定部分…
意识、好奇心和欲望
塞尔先生试图用中文房间思想实验提出的一个关键论点是,机械规则(程序)结合静态信息存储(没有处理能力的规则书)不能产生意识。
这个定理看起来还是不错的。许多研究者怀疑意识只是逻辑和公理。
我们知道 AI 可以拥有基本水平的“自我意识”,至少在物理层面(即机器人)和“将自我与环境区分开来”层面(即计算机病毒)。虽然我们不认为这些是意识,但它们经常构成意识证据的一部分。
可以实现更高层次的意识,如生存本能——寻找“主机”(它可以运行的地方)的程序已经存在,添加“优先级”,如确保计算能力,或者电力实际上并不需要比我们已经拥有的更多的智能——尽管病毒和特洛伊木马的能力还不够智能,但基本的“生存”技能和“决心”正在出现。
更常见的意识水平“知道我在思考”会很有趣——这是一种意识到思想本身存在的“状态”——我们需要这种意识才能将人工智能视为普遍智能吗?
这种意识水平是非常独特的,并没有被完全理解,这可能与人类的好奇心有关。
如果超级智能只有一个最大的障碍,我会认为是好奇心。令人着迷的是,人类会想“为什么我会想到这个”。对这一“基本”问题的回答令人困惑。
人类似乎有这种发现新知识的冲动和快乐,甚至不惜付出超出生存需要的代价。也许通过进化,那些费心获取更多信息的个体更清楚地知道“这蘑菇有毒”并避免食用它?也许获得更多的信息增加了生存的可能性,所以那些乐于发现更多信息的人获得了早期优势?
好吧,好奇害死猫……然而在人类的情况下,也许一两个人的牺牲提供了所需的信息,增加了群体中其他人的生存机会,也就是说,一个吃了毒蘑菇的人可能会让群体中的其他人免于死亡?
如果是这样的话,为什么人工智能需要那种冲动,它甚至有益于(人工智能和人类)吗?毕竟 AI 是创造,不是出于(纯粹的)进化。
塞尔先生提到的另一个方面是“意向性”,他认为欲望是生物心理的一种状态。对此,我是分裂的。我认为没有足够的证据得出这样或那样的结论。需求某物的“主动性”可以是独立的欲望,但也可以是来源于单一“来源”的“需要”——生存的需要。任何有助于大多数物种生存的统计数据都可以在它们的基因中被“编码”为“欲望”。而这些欲望的“目的”只会增加宿主的生存机会。人们可以认为好奇心是生存的欲望之一。
尽管存在人类欲望的机制,但人工智能的“类欲望”意向性仍可能有可行的来源,例如,寻求电力的人工智能机器人可能会表现出类似于“更喜欢靠*墙壁插座”或“争夺充电器”的行为,它甚至可能会发展出“懒惰”来节省能源(当前的省电模式是人类编程的,而不是人工智能自己的“主动”)。
我们对人工智能研究得越多,我们就越怀疑单一来源(即生存)衍生多个“欲望”是产生类似人类行为的一种可能方式,即使它与人类意识的机制不同…
语言、写作和智力
当我第一次开始学*说普通话时,没有人费心告诉我“这是语法,这是词汇……”(好吧,反正我会太“天真”而无法理解它们)。
我在学校的时候,汉语语法是作为“规则”来教的,没有人质疑,“这些规则是为了构建恰当的语言,还是为了正确地表达思想”。在某种程度上,这可能是因为与英语(和大多数印欧语言)相比,汉语的本质更“流畅”或更富于表现力,其结构没有那么僵硬。
例如,汉语是没有性别的,甚至“她”这个词也是“输入”到汉语中的(有趣的事实:在汉语中,他,她,它,都发音相同,他们只在写下来时有所不同)。汉语也不紧张。如果你想说昨天发生的事情,…好吧,就说“昨天”,否则,如果你现在“做”某事,你明天仍然“做”某事,你昨天“做”它——那个动作的单词不会因为你执行它的时间而改变。事实上,每个动词只是一个动词,没有“形式”,汉语也不区分单复数。
当我开始学*英语时,大多数文本框都是关于句法、语法和词汇的。对于一个说中文的人来说,有些规则似乎太死板了,比如时态、冠词。
然而,很快我就会明白“语法规则不像物理定律,它们通常是粗糙的,可能在 70%的情况下都适用。”
那不是很方便嘛!
但是这两种语言的比较也带来了一个问题,句法和语义的完全分离可能吗?在中文中,实际上比在英文中更难将它们分开,语法可以根据表达的需要进行转换。在“中国队击败美国队”的例子中,确切的句法结构实际上并不清楚,直到读者考虑到表达的意思。在“赢”的形式下,它是主动语态,在“输”的形式下,它实际上是被动语态。句法受到要表达的意思的影响。
这种“不那么重要”的语言差异早就被语言学者所知,但它有一个重要的新含义——英语语言的嵌入更类似于压缩英语的结构吗?或者它可能像汉语一样模糊(或移动)了句法和语义之间的界限?证据开始指向后者。
塞尔先生在中文教室使用的另一个有趣的功能是,他将处理书面中文。到目前为止,fMRI(主动脑成像)证明阅读和听力并不完全激活相同的大脑区域。
我们多少同意书写(或者更准确地说是符号化)允许信息和知识存在于我们的大脑之外,存储在“非智能”媒介中。这引发了一个疑问——书面语言是否涵盖了所有的智力?还是写作本身在智力上带有某种额外的意义?
在讨论的范围内,处理书面语言对智力水平有影响吗?
延伸一下,语言是思想的媒介,还是思想的表达?
我曾经想知道“人们是如何思考的?他们是不是用一种共同的语言来思考,只是自动翻译成口语?”如果人类的思想可以独立于语言而存在,那么,语言只是智慧的一种表现。但是,如果人类的思想“植根于”语言,那么,语言可能在智力中发挥更重要的作用。
这个问题的部分答案没多久我就想起来了。从我学英语的第二年开始,我开始训练自己用英语思考,至少对于相关的话题。我知道人们可以用不同的语言思考,有趣的是,语言之间并没有 100%的重叠。
学*像汉语和英语这样不同的两种语言,对我来说,这些问题的答案是复杂的。似乎有些人类的思想可以独立于语言而存在。有些可能不需要语言,比如视觉艺术,有些可能超越了语言——我们都有想说些什么却找不到合适的词来表达的时候。
似乎我们的一些想法是基于语言的。当我用英语思考时,我发现有些东西很容易理解,但很难翻译成中文——有研究证实,双语者会根据他们使用的思维语言在不同的“思维模式”之间切换。
大多数研究人员都同意,语言可以用来表达思想和观点,这些思想和观点在不同的人类个体中是“普遍可理解的”。“普遍可理解”的部分是指语言是“客观化的思想”,所以它可以在聪明的个体之间传递吗?或者是“最大公约数”?
也许人类的思想可以“投射”到语言中,这可能会捕捉到人类智能可以处理的很大一部分(但不是全部)意义。这可能就像语言嵌入了人类的思想。不同的语言可能就像不同的嵌入设置,它“保留”了大量的含义,但在一个低维空间中表示它…
人工通用智能可能吗?
如果有人把我锁在一个房间里,用我不知道的语言使用规则书通过图灵测试,我需要的不仅仅是规则书——要么我需要自己学*语言并智能地处理符号,要么依靠规则书以外的一些隐藏的东西的帮助。
40 年前,房间里被允许通过图灵测试的“东西”是非常模糊的,但我们似乎在这一部分取得了一点点进展——人工智能系统正在获得语义意义,这正是中国 Roome 思维实验旨在展示“不可能”的东西。
最*的深度学*进展引起了人们的怀疑,即一个以统计方式处理信息的系统可能会在超出正式语法描述的水平上处理这种信息。虽然它们仍然在图灵完整系统上运行,但处理的复杂性、使用的训练数据量以及随机性成分扩展了塞尔先生最初的中文房间思想实验中的“正式”概念。
人工智能的这些进步意味着句法处理与语义完全分离的“纯”中文教室的设置越来越不可能成为未来。
就像中文和英文之间的区别一样,NLP 中使用的表示不是一阶逻辑中的公理。现代自然语言处理正在获取这些单词的一些语义。虽然尚未“完全理解”人类语言,但人工智能似乎正在朝着这个方向前进。
除了 NLP,我们知道自动驾驶汽车可以“识别”红灯,并会停下来。使用计算机视觉操纵物体的机械臂也是可行的。
实际上,将“红色”这个词与红光的视觉联系起来,现在已经是非常成熟的技术了。嗯,不止如此。我们可以结合视觉自动编码器来训练一个模型,将红光与电影中这种项目的视觉联系起来。
结合各种感觉输入流及其编码器的多感觉模式识别和协调是人工智能中非常有趣的研究领域。似乎人工智能正在超越语法处理阶段。
虽然塞尔先生断言人类意识是人脑的生物特征是正确的,但人工智能必须具有同样的意识吗?是否存在与人类机制不同的其他形式的意识?
我相信这是可能的。
知识分子中有一种倾向,认为人类的智力有几分神圣。如果某样东西可以被完全解释,那它就不是智能。我曾经写过我们想要一笔勾销我们所谓的“只是计算”或者“只是逻辑运算”的愿望。
经典睡前故事:神经网络的灰姑娘
原文:https://towardsdatascience.com/a-classic-bedtime-story-cinderella-of-neural-networks-fa9a3414286f?source=collection_archive---------31-----------------------
“人工智能冬天”的最后阶段
一个竞赛,ImageNet,连同一个嘈杂的算法,随机梯度下降,是如何改变 AI 的命运的?
Picture from The Elders Scroll | Skyrim
20 世纪 80 年代初,人工智能(AI)的冬天即将到来,这是一段人工智能研究资金和兴趣减少的时期,后来被称为“AI 冬天”!
在这个持续到 2000 年代中期的寒冷时期,由于对该领域失去了兴趣,几乎没有关于神经网络的研究论文发表。原因很简单:没有针对传统算法的有效算法。
当 Geoffrey Hinton,你可以称他为深度学*的教父,和他的团队在 2012 年一个名为 ImageNet 的著名物体识别比赛中提交他们的研究时,AI 的悲惨遭遇发生了巨大的变化。“ImageNet 2012 事件绝对是引发当今人工智能大爆炸的原因”clari fai 首席执行官马修·泽勒(Matthew Schmidt)说道。
Picture Source: ImageNet
在 Geoffrey 的工作之前,算法下的物体识别研究的准确性非常差,分类错误率超过 25%,而人眼表现的错误率大约为 5%。但是,随着 Geoffrey 的团队完美地实现了神经网络,他们成功地将错误率大幅降低了 40%以上!!按照他的步骤,深度学*已经被如此强烈地使用,以至于仅两年后算法产生的错误率比人眼低得多!!目前,在对象和语音识别领域,几乎所有的研究都是由深度学*的子领域 AI 进行的。
我还应该提到,在从“人工智能冬天”时期进入辉煌的“伟大的人工智能觉醒”时期时,人工智能从 GPU(小心,而不是 CPU)计算的改进中获得了实质性的支持,这要感谢英伟达,以及海量数据集的可用性,这要感谢我们所有人每天创建超过 2.5 万亿(10 ⁸)字节的数据。
让我们把注意力转回深度学*的主干算法。众所周知,算法试图通过最小化误差函数(通常称为成本函数)来优化问题。高效的算法在纳秒内完成,而其他算法可能需要运行数小时。
机器学*算法需要有效的优化技术来解决凸问题或非凸问题。最小化误差在凸函数中表现得最好,因为无论你的起点在哪里,你总会找到全局极小点!这就是为什么我们喜欢 SVM(支持向量机)或其他线性函数,因为他们有凸损失函数,你保证找到全局最小值!!
但是,在现实生活中,优化函数通常是丑陋的。他们生活在非凸空间中,非凸空间由许多局部最小值(“谷”)和最大值(“山”)组成。神经网络也不例外,甚至更糟!
“Visualizing the Loss Landscape of Neural Nets”, Hao Li et al., 2018
神经网络有 1000 多个局部最小值,所以你肯定会陷入其中,永远找不到全局最小值!(告诉我你是否不同意左边的图表,它只显示了一个非凸函数的一小部分。)取决于您的“初始化”点在哪里,您将总是以不同的局部最小值结束(这个问题通常通过随机初始化来处理,或者可能添加一些高斯噪声)。没有人真正喜欢神经网络的原因是,在缺乏负担得起的算法的情况下,它的高度复杂性。
在寻求合理的局部最小值时,研究人员首先使用了积极的方法,如梯度下降或更快的*似牛顿或*似海森方法(随着数据大小和维度的增加,凸优化方法受到不利影响。例如,基于 Hessian 的方法可以最佳地处理凸优化问题,但不能扩大规模,因此需要*似法[Martens et al .,2012]。这些方法是如此完美的寻找最小值,以至于它们可以立即找到“最*的”洞。虽然这听起来很完美,但实际上并不是!-最*的洞不太可能有理想的最小值,您需要寻找更远的地方。
此外,即使你设法看得更远,你也需要寻找宽阔的山谷,而不是狭窄的深度。使用训练数据时发现的深孔在使用测试数据时可能没有那么深。然而,在训练和测试数据集下都可能存在宽谷。
哪种算法能够避开最*的洞并在宽广的山谷空间中停留?这正是 SGD 的实际能力!(尽管人们花了很长时间才发现这一点)。谁会想到,曾经被贴上低效和冗余标签的算法,最终会成为几乎所有深度学*模型的关键优化工具?太棒了。
picture source : https://wikidocs.net/3413
这是怎么发生的?“随机”梯度下降(SGD)方法是如何作为一种非常有效的技术来训练深度神经网络的,在数据集大小上具有线性计算复杂性,给定其非常嘈杂和随机的性质?
与梯度下降法(GD)相比,SGD 的噪声很大,因为 GD 使用整个数据集来计算其路径(梯度),而 SGD 仅使用一个示例,即每次迭代随机选择的批量大小为 1 的示例;因此,它遵循一条随机的路径,但最终是朝着正确的方向。随机性意味着它不会收敛到最*的洞,而只会停留在大的山谷中!这是很多其他算法不具备的素质!
嗯,在我们的童话故事中,在车轮弯曲之前,和故事结束之前,我应该告诉你,我们的主要人物,SGD,由于学*率(步长)有两个主要的限制:如果你选择它太大,那么学*轨迹导致可怕的情况;如果选得太小,它的收敛需要很长时间。所以,明智的选择合适的步长。您可以使用 SGD 的几种变体之一,如 Momentum、Averaging、隐式更新(ISGD)、AdaGrad、Adam 等。或者听听我的建议,开始时迈大步,当它开始来回跳跃时,开始降低你的学*速度,即迈小步。就是这样!
现在桥修好了,我的故事也结束了。
Python 的分类问题——网站报价转换
原文:https://towardsdatascience.com/a-classification-problem-with-python-homesite-quote-conversion-15174bca09b8?source=collection_archive---------26-----------------------
通过 Scikit-Learn 了解 Python 中的分类方法
领先的房屋保险提供商 Homesite 目前还没有一个动态转换率模型来让他们相信报价会导致购买。他们使用客户和销售活动信息的匿名数据库,包括财产和保险信息,要求我们预测哪些客户将购买给定的报价。准确预测转换率将有助于 Homesite 更好地了解提议的价格变化的影响,并保持理想的客户群组合。
数据描述
该数据集代表了对从 Homesite 购买保单感兴趣的大量客户的活动。每个 报价号 对应一个潜在客户, 报价转换 _ 标志 表示该客户是否购买了保单。所提供的特征是匿名的,并且提供了潜在客户和策略的丰富表示。它们包括特定的覆盖范围信息、销售信息、个人信息、财产信息和地理信息。我们的任务是预测测试集中每个 QuoteNumber 的 QuoteConversion_Flag。
我们先看数据,看看这个数据。
训练数据集 : 训练一个模型的子集。
测试数据集 : 测试已训练模型的子集。
trainfile = r'RevisedHomesiteTrain.csv'
train_data = pd.read_csv(trainfile)testfile = r'RevisedHomesiteTest.csv'
test_data = pd.read_csv(testfile)print(train_data.shape)
print(train_data.head())print(test_data.shape)
print(test_data.head())
Figure 1
我们复制不包括目标的训练数据,并将训练数据和测试数据分开。然后,我们只选择目标列。
trainData_Copy = train_data.drop('QuoteNumber', axis=1).iloc[:, :-1].copy()
testData_Copy = test_data.drop('QuoteNumber', axis=1).iloc[:, :-1].copy()X_train = trainData_Copy
X_test = testData_Copy
y_train = train_data["QuoteConversion_Flag"]y_train = train_data.iloc[:, -1]
y_test = test_data.iloc[:, -1]
从 训练数据集 创建验证数据集
from sklearn.model_selection import train_test_split
X_train1, X_val, y_train1, y_val = train_test_split(X_train, y_train, test_size = 0.2)
模型
决策图表
决策树是一种决策支持工具,它使用树状图形或决策模型及其可能的结果,包括偶然事件结果、资源成本和效用。这是显示只包含条件控制语句的算法的一种方式。决策树分类器通过基于不同的标准将数据集分解成越来越小的子集来工作。将使用不同的分类标准来划分数据集,每次划分的示例数量都会减少。
from sklearn.tree import DecisionTreeClassifierclf = DecisionTreeClassifier()
clf.fit(X_train1, y_train1)
clf_predict = clf.predict(X_val)
决策树分类器的 Kaggle 得分:0.94499
随机森林
随机森林是一种集成学*方法,它在数据子集上拟合多个决策树,并对结果进行平均。
Random Forest
from sklearn.ensemble import RandomForestClassifierrfc = RandomForestClassifier()
rfc.fit(X_train, y_train)
rfc_predict = rfc.predict(X_test)
随机森林分类器的 Kaggle 得分:0.91963
k-最*邻
k-最*邻通过检查从某个测试示例到某个训练示例的已知值的距离来操作。给出训练点和测试点之间最小距离的数据点组/类是被选择的类。
K-Nearest Neighbors
from sklearn.neighbors import KNeighborsClassifierknc = KNeighborsClassifier()
knc.fit(X_train, y_train)
knc_predict = knc.predict(X_test)
K-最*邻分类器的 Kaggle 得分:0.60289
神经网络
神经网络是一种机器学*算法,涉及拟合许多用于表示与突触激活功能相连的神经元的隐藏层。这些基本上使用一个非常简化的大脑模型来建模和预测数据。
Neural Networks
from sklearn.neural_network import MLPClassifiermlp = MLPClassifier()
mlp.fit(X_train, y_train)
mlp_predict = mlp.predict(X_test)
神经网络分类器的 Kaggle 得分:0.86759
梯度推进
梯度提升分类器是一组机器学*算法,将许多弱学*模型结合在一起,创建一个强预测模型。决策树通常在做梯度提升时使用。
from sklearn.ensemble import GradientBoostingClassifierabc = GradientBoostingClassifier()
abc.fit(X_train, y_train)
abc_predict = abc.predict(X_test)
神经网络分类器的 Kaggle 得分:0.95882
比较
基于我创建的模型,首先我们可以认识到梯度提升分类器得到最高的 Kaggle 得分。此外,梯度推进模型因其在分类复杂数据集方面的有效性而变得越来越受欢迎,最*已被用于赢得许多 Kaggle 数据科学竞赛。
结论
总之,我们使用 Scikit Learn 的不同分类方法(决策树、随机森林、K-最*邻、神经网络和梯度推进)来预测客户购买报价保险计划的概率,并专注于预测准确性。目的是学*一个可以最大化预测精度的模型,比较不同的算法,选择性能最好的一个。
创建这篇文章的源代码可以在这里找到。
关于我
非常感谢您阅读我的文章!大家好,我是雪莉,目前在亚利桑那州立大学攻读商业分析硕士学位。如果您有任何问题,请随时联系我!
Email me at ***kchen122@asu.edu***and feel free to connect me on [**LinkedIn**](https://www.linkedin.com/in/kuanyinchen-shirley/)!
对人工智能更清洁的监管方法?
原文:https://towardsdatascience.com/a-cleaner-regulatory-approach-to-ai-7bfa6ec3124d?source=collection_archive---------25-----------------------
Screenshot of Michael Kratsios at the HAI fall conference October 2019
美国首席技术官 Michael Kratsios 与人工智能监管
斯坦福大学以人为中心的人工智能研究所(Institute for Human-Centered Artificial Intelligence at Stanford University)提出了一项我认为非常棒而且必须受到称赞的倡议,那就是分享他们关于人工智能伦理、政策和治理的秋季会议的全部视频。这两个长视频,每个都持续几个小时,对于任何对这一领域感兴趣的人或地球上领先的人工智能研究机构之一正在进行的讨论来说,都是一个重要的贡献。与 Michael Kratsios 的讨论从会议的第二天开始。它来自第二天的早期录像,所以应该不难找到。然而,如果你想知道这两天还发生了什么,你可以浏览一下这个公开议程。
值得注意的是,川普政府在填补其技术政策机构的职位方面动作缓慢。在 职位空缺两年多 后,Kratsios 于 8 月份被确认为 CTO。然而,他已经作为美国总统的副助理工作了一段时间。
迈克尔·克拉特西奥斯是谁?
迈克尔在大会上的介绍如下,所以我再重复一遍:
“美国首席技术官迈克尔·克拉特西奥斯。迈克尔于 2019 年 8 月被美国参议院一致确认担任 CTO。他只是美国第四个担任这个角色的人。作为美国首席技术官,迈克尔在非常广泛的技术挑战组合中担任总统的首席顾问,这些挑战包括量子计算、5G 和农村宽带、自动驾驶汽车、商用无人机、STEM 教育、先进制造以及人工智能。在成为首席技术官之前,Michael 在管理的早期阶段担任副首席技术官。在进入政府之前,他是泰尔资本公司的负责人,并担任企业家投资者彼得·泰尔的办公室主任。他毕业于普林斯顿大学,获得了政治学学位。”
他正在斯坦福网络政策中心参加由全球数字政策孵化器执行董事艾琳·多纳霍 主持的讨论。她专注于制定全球数字政策,以应对人权、安全和治理方面的挑战。在斯坦福之前,她是奥巴马政府时期美国驻联合国人权理事会的第一任大使。她还担任过人权观察组织的全球事务主任。她在许多组织的董事会任职,包括国家民主基金会和世界经济论坛人权理事会。
人工智能创新的自由市场方法
我们可以把迈克尔的观点总结如下。监管需要有针对性和部门针对性。他提到了美国保持领先地位的自由市场创新方法:
“我对这个世界的看法是,有些技术是天生免费的,有些技术是天生被囚禁的。”—Michael Kratsios2019 年 10 月 29 日 HAI 秋季大会。
降低与投资相关的监管风险。他在问如何创造一个特别适合军事技术的环境。迈克尔管理着一个庞大的投资组合,他通过召集人的角色制定高层次的战略和指令来确定投资的优先顺序。
迈克尔看到了“本质上是企业家”的机会,因此招聘需要时间来寻找个人投资组合经理。他们招募技术专家来推动政策。根据迈克尔的说法,他三分之一的时间花在政策上;第三是会见利益相关者;第三是对外宣传(他认为这是他与海合作的一部分)。
对他来说,从奥巴马政府到特朗普政府,政策制定一直在延续。潜在政策影响。R&D 基础研究人工智能战略计划。他们通过行政命令建立并启动了一项国家战略。
清洁法规
在某个时候,迈克尔提到了创建更清洁的法规的想法。我清楚地意识到,要制定对企业更有利的法规。他没有使用“放松管制”这个词,然而,这似乎是他在技术监管方法中暗指的。
“放松管制 是减少或取消政府在特定行业的权力,通常是为了在行业内创造更多的竞争而颁布的。”
因为没有所谓的干净监管。通过提及这一点,我认为他可能指的是公平和权宜的概念,能够在人工智能领域实施解决方案。
结合自由市场方法,他似乎代表着“让大型科技公司更容易”为美国经济或保卫国家等共同项目做出贡献。他提到亚马逊和苹果的无人机测试必须在国外完成,他一直想把它带回美国。
海、国家技术与美国价值观
迈克尔在谈到他与海的关系时说:“对我们来说,这是让像你们这样的聪明人与我们所有机构的监管者沟通,这样我们就可以制定一套聪明的规则。”
主持人:艾琳·多纳霍提出了数字威权主义的问题。迈克尔回答道:
“如果美国能够继续成为人工智能领域的领导者,我们就能确保我们所珍视的价值观将成为全球发展的基础。”
因此,展示美中之间的对立关系对迈克尔来说很重要,也反映了当前的特朗普政府。他们希望通过一个充满活力的由私人和公共资金资助 R&D 的私营部门来推动科学发现。他提到,这与他们的‘对手’正在做的事情不同,而不是一个集中的计划。
美国首席技术官支持经合组织的人工智能原则
Michael Kratsios 谈了很多关于去 T2 经合组织的事情,并支持他们的原则。这在我看来不可思议,因为它为更多关注以地球为中心的人工智能方法打开了大门。《经合组织人工智能原则》中的第一条原则是:
人工智能应该通过推动包容性增长、可持续发展和福祉来造福人类和地球。
在当前的美国执行战略中,没有与此原则非常相似,这意味着这可能被用作推动新解决方案或改变美国重点的论据(尽管我认为这将是一场艰苦的斗争)。
向迈克尔提问
当然,我不能涵盖迈克尔演讲的每一点,这也是我做一个简短总结的部分原因。不过,他回答了几个问题,我记下了这些问题,并将尝试进行沟通。
公共数据云
HAI 的领导人之一 John Etchemendy 谈到了一种公共云,这种云向公共利益研究人员提供免费访问。约翰提到的这种可能性为许多可能的应用和可能的误解打开了大门,因为“公共利益”在美国是一种非常务实的方法。公私伙伴关系很好,但在美国,似乎很多时候公共利益几乎可以直接转化为私人利益。迈克尔主要来自彼得·泰尔的私人背景,帕兰蒂尔(彼得拥有的)已经获得了几份新的国防合同。
人工智能与移民政策
问:你与移民政策的关系?
答:美国创新的一大支柱是移民。我们相信 T2 的择优创新体系。政治上具有挑战性,需要国会的支持,需要努力达成共识。改进或走向基于成绩的制度。它需要两个独立的彩票,切换彩票的顺序。获得高等学位的人有更好的机会来这里学*。
在回答这个问题时,迈克尔回避了关于移民和海关执法局(ICE)以及大型科技公司抗议活动的讨论。然而,他说这是与“山上的伙伴”的挑战,所以他的优先事项可能不同,尽管他必须完成一项任务。
创新和价值观
问:美国在人工智能领域的领导地位会给社会带来一定的损失,为了保持美国在人工智能领域的领导地位,个人应该承担什么样的损失?
答:我们在美国是幸运的……其他选择太可怕了,我们需要对我们所有人都珍视的价值观进行互动,以便在未来实施。
投资高级人工智能和 R&D
[费-李非]:上游问题和管道问题,与 STEM 教育有关,无论我们在先进的 R&D 投资多少,我们都需要人才管道。本届政府在推动 STEM 教育方面做了哪些努力?最大的问题之一是在人才管道中缺乏代表性。我们对缺乏代表性做了精彩的介绍。本届政府如何与国会合作,考虑投资于多样性和包容性?
答:美国通过了一项关于 STEM 教育的五年计划。我们政府中的许多机构,将这些组织在一起推动干细胞研究。其中一个支柱正是我们正在谈论的事情,如何推动代表性不足的少数群体进入 STEM 领域。在此基础上,我们希望进行更多的合作,我们可以将您与人们联系起来。联邦政府可以在推动议程方面发挥作用,但大部分工作是在州和地方层面完成的。我们如何建立这些并提供帮助。
基础设施和数据管理基础
问:我们没有现代化的数字基础设施。有一个研究云提到(提到电子爱沙尼亚),你如何提供数据集?
答:党派色彩最少的问题之一是政府技术基础设施的现代化。第一个统计数据是,每位员工每年的 it 服务总成本约为 40,000 英镑,而私人 IT 为 4,000 英镑。我们可以更好地使用这些钱。像美国数字服务这样的项目,从硅谷引进有才华的工程师;另一个项目是总统创新研究员项目。PIF 项目,人们能够进入政府,在那里他们能够努力工作。我们有 25 个以上的代理机构,没有理由一次又一次地重复做同样的事情。我们正处于在政府卓越中心推出人工智能的早期阶段。
保护民主选举
问:作为首席技术官,你个人在哪些具体举措上花费了时间和预算支持来保护民主选举?
答:那是 DHS,一个与州政府密切合作的人,州-地方的努力。在某种程度上,我可以帮你联系国家安全委员会。
迈克尔是首席技术官,但他并不负责保护选举或选举舞弊。可以说,在他们的科技战略中,美国更关心的是国防而不是内部民主。正如喜剧演员约翰·奥利弗在《上周今夜秀》的一集节目中所说,数字投票并非没有问题,而且往往已经过时。
更多跨部门和跨学科的工作
问:越来越多的人认识到,要在规范和创新方面取得成功,学术界和工业界必须合作。HAI 项目很好地反映了这一趋势。对技术挑战和规范的社会挑战有头脑。跨部门和跨专业的工作。
答:最大的反映之一是 R&D 人工智能战略计划,这是涵盖这些伦理问题的八大支柱之一,我们不应将其视为简单的技术问题,而是一个更大的社会科学问题。当我们每季度就人工智能、跨机构合作进行高层讨论时。最大的表现是监管指引备忘录。
分手建议
问:对于想参与人工智能技术政策的人,你有什么临别建议?
答:做公共服务很重要,我得到了一个机会,我们生活在迄今为止世界上最伟大的国家。自由和权力,很多人没有,我们有一个非常特别的国家。我们有令人惊叹的国家实验室,如果我们继续培养这种环境,我们就能推动这里的变化。我很乐意和你谈谈,让这成为现实。
美国科技政策的最新动向
除了会议,我们可以考虑迈克尔·克拉特西奥斯的招聘。根据 NextGov 在 2019 年 11 月 21 日写的文章,有两个变化需要考虑:
- Lynne Parker 博士和 Winter Casey 将在科学和技术政策办公室内晋升。在他们之前的角色中,帕克领导了政府的国家人工智能战略的发展,凯西与盟友一起在技术问题上建立共识。他们现在都是美国副首席技术官。
- 埃里克·伯格将加入 OSTP,担任电信和网络安全助理总监。他负责电信和网络安全产品组合。执行与美国使用无线电频谱、通信网络和网络安全相关的联盟建设、协调和政策工作。
结论
似乎很明显,美国高层战略将继续支持技术领域的自由市场做法,这将严重依赖大型技术公司的意见。由于管理人员和政府官员来自私营部门,特别是来自投资、风险投资和“创业”型企业,因此不难看出他们在技术方面的现有关系将对美国的这些新合作努力产生何种影响。迈克尔正在采取措施加强美国技术相关政策的发展,我们将不得不看看这将把我们带到哪里,因为根据许多消息来源,美国目前是人工智能领域的领先国家。
这里是#500daysofAI,您正在阅读的是第 188 条。500 天来,我每天都写一篇关于人工智能或与之相关的新文章。
西班牙铁路客运定价研究
原文:https://towardsdatascience.com/a-closer-look-into-the-spanish-railway-passenger-transportation-pricing-581c19fe67dc?source=collection_archive---------36-----------------------
介绍
作为一个在离家 400 公里的西班牙城市生活和工作的人,我发现往返旅行最方便的方式是坐火车。作为一个经常使用的用户,我已经对购买门票时的定价模式感到困惑,有时会沿着相同的级别移动,而另一些则超出了最常见的级别。
所以这个疑问促使我提出了以下问题:
“火车票价格真的会随时间变化吗”?
如果是这样,
“有没有购买它们的最佳时机?”
数据
在这个项目中,只考虑了 Renfe 的长距离路线。
该数据集最初来源于由 thegurus.tech 提供的 Renfe scraping 程序,其中每天循环检查几次离开列车的采样路线的价格。
特别是价格被查的车次,时间跨度在 3 个月左右,从 2019 年 4 月 12 日到 2019 年 7 月 7 日。
数据来源:【https://thegurus.tech/posts/2019/05/renfe-idea/
数据争论
在花了一些时间了解数据之后,自然的下一步是清理原始数据,并以一种为分析做好准备的方式对其进行转换,从而为揭示主要问题做好准备。它的代码可以在我的这个项目的 Github repo 中找到。
进一步说,清理和转换任务包括创建新的列,比如路线、出发日期、出发时间、在给定日期和给定时间出发的特定列车的标识符,或者出发前的天数;将格式更改为列,以便能够对其进行计算和进一步转换,方法是减少一些分类变量的类别,如火车类型或机票等级,删除不需要的列或决定如何处理无效行(具有空值)。
结果
本节介绍的所有图和结果的代码也可以在这里找到。
所有路线一起
在这个图表上有一些有趣的东西可以评论。一方面,它回答了主要问题。
1)我们可以看到,价格确实会随着时间的推移而变化,不仅如此,我们还可以看到,随着离店日期的临*,价格明显呈上升趋势。
2)一旦我们承认确实存在相关的变化,是否存在购买门票的最佳时机?嗯,从汇总图中,我们可以看到,最佳购买时机是在机票开始销售时,无论如何,在 50 到 60 天之间。
另一方面,它允许我们确定 3 个主要阶段。首先,在出发前的 42 到 60 天之间,我们可以找到价格的较低范围,然后在出发前的 42 到 13 天期间,价格的变化非常低,总共在 6%-7%左右。最后,还有票价逐日上涨的阶段。
让我们按数据集路径来分解它。
高需求路线中的价格机票演变
马德里-巴塞罗那往返路线被选为高要求路线的范例。它有一个类似的模式,我们观察到的考虑所有可用的路线在一起。我们看到,在机票发售后,接*出发前 50 天,价格会有所下降。同样,我们可以确定 3 个阶段,首先是出发前的 40 到 60 天,价格范围较低,然后是出发前的 40 到 12 天,价格变化非常低,约为 6%-7%。最后是票价逐日上涨的阶段。
非高需求路线中的票价演变
这一次,Renfe 设定了一个初始价格,但由于该价格没有满足需求,价格开始下跌,直到在离开前 40-50 天触及最低点。然后价格演变波动性大得多,随着出发日的临*,价格不断上涨和下跌,但始终遵循上涨趋势。
我们在之前的图中看到的中间阶段,价格几乎在*一个月内保持不变,这里没有重复。
我要强调的最后一点是,价格变化范围远低于高需求路线。
所有数据集路线价格演变的画布
我们还可以根据出行/火车特征来分解价格演变。
星期效应
我们可以看到,无论火车在一周中的哪一天出发,价格演变模式都非常相似,但是,我们看到,星期五和星期天的车票平均比其余时间出发的火车更贵。周一火车票是火车接*发车阶段价格上涨最多的。周六则相反,价格上涨最不明显。
出发时间效应
我们之前在箱线图中看到,在按发车时间窗口分解的价格中确实有轻微的差异,我们可以看到晚上发车的列车比其他发车时间窗口中的列车观察到的价格更便宜,我们还大胆地说,这可能是因为晚上发车的列车通常比其他列车有更多的需求,因此,从 Renfe 设定的更高的价格不会像其他列车一样,因较低的初始需求而下降。
上图支持了这一理论。事实上,晚班火车的最低价格恰好在出发前一个月左右,从而导致不同的最佳购买时刻。
票类效应
一般来说,这两种类型的机票都适用,所以我要强调的是,因为我们知道经济舱机票最先售完,这就解释了为什么当出发日期临*(“最后阶段”)时价格上涨如此平稳。相反,因此,头等舱在起飞前的最后几天更受欢迎,这就是为什么与经济舱机票相比,头等舱的价格上涨更为强劲。
检查是否有任何定价日内差异
一旦评估了日内价格模式,让我们把焦点放在日内价格演变模式上,看看它们是否也存在。
线不断交织和重叠,似乎在告诉我们,每窗口的日内价格乘以离出发的天数没有区别。特别是,唯一突出的一点是晚间价格向图表下限的下降(离出发还有几天甚至几天)。放大看,有可能看到滴滴属于同一天出发。
因此,为了检查我们是否需要考虑这种下降的相关性,我们首先需要知道一般进行的价格检查的次数,以及每个出发窗口时间进行的次数,以便排除潜在的依赖性影响。
我们可以看到价格检查几乎以相同的比例昼夜不停地进行。让我们看看当放大到最后一天,也就是下降发生的时候,这是否成立。
比例不再成立。这意味着,对于出发当天进行的价格检查,这些价格检查是以不平衡的方式进行的;特别是,我们可以看到,晚间价格检查的数量远远低于其他窗口时段。
因此,基本上,由于差价如此之大,在晚上和出发的同一天检查价格的少数火车,可能完全是平均来说更便宜的特定类型。简而言之,没有相关的日内价格差异。
结论
随着出发日期的临*,我们发现了相同组合的火车-日期-时间-路线的相关价格变动。
特别是,对于高需求航线,最佳购买时间是出发前 50-60 天。对于非高需求航线,最佳时刻可以在出发前 40 到 50 天之间找到。当火车在晚上出发时,最佳时刻是出发前 30 天。
在任何情况下,如果由于任何原因不能提前足够的时间购买机票,也不必担心,因为在出发前 12 天之前,价格几乎没有变化(平均只有 6-7%)。
但是,过了这个门槛,车票会一天比一天贵,因为离站日一直接*火车离站的那一天。
最后,我们没有在人民币汇率定价系统中发现任何日内模式。因此,按出发日期分组,人们不会在意在一天中的任何特定时刻购买。
一枚硬币、一些吸烟者和数据分析中的隐私
原文:https://towardsdatascience.com/a-coin-some-smokers-and-privacy-in-data-analysis-1339b83ede74?source=collection_archive---------30-----------------------
Photo by Carlos Muza on Unsplash
我们将继续探索学*隐私保护数据分析技术,这次将更深入地挖掘差异隐私的基础。
在上一篇文章中,我向您介绍了差分隐私的概念,以及它为什么会让您在数据匿名化方面占上风。
我强烈建议你在进一步阅读之前检查一下那篇文章,以便更好地理解我们的学*范围。
[## X 先生,网飞,和数据分析中的隐私
世界各地的隐私监管机构都在关注数据隐私,这给像我们这样的分析师留下了什么空间…
towardsdatascience.com](/mr-x-netflix-and-privacy-in-data-analysis-f59227d50f45)
所以我们现在知道,差分隐私有助于我们在数据库中保存个人的隐私信息,并防止数据泄露。在正式介绍它是如何做到这一点之前,让我们做一个真实世界的项目,以更好地理解潜在的想法。
Photo by Helloquence on Unsplash
假设你是一名数据分析师,你的任务是找出与吸烟*惯最相关的关键因素,因为你没有继续使用的数据集,所以你决定在你家附*的公园进行一次公开调查。你决定去问人们是否吸烟以及其他一些问题。然而,由于吸烟不是一个很好的*惯,在公共场合透露吸烟会给一个人带来问题,一些人不太愿意谈论它,或者我们可以说,这是一种人们希望对自己保密的信息,这样它就不会泄露到其他地方。但这肯定对你没有帮助,所以为了鼓励人们参与你的研究,你决定给他们一个正确回答的选项。
人们可以选择正确答案的想法起初听起来很琐碎,因为你是在故意告诉人们说谎。如果你想一想,你就会明白,你现在拥有的不是一个包含一大堆敏感信息的数据库,而是一个注入了一些噪声的数据库,这就是差分隐私的工作方式。
形式化差异隐私:
差分隐私通过进程提供隐私;特别是它会引入随机性。
此时你应该想到的三个最重要的问题是-
- 噪声注入数据如何保持有用?
- 我们如何引入随机性?
- 还有,什么时候加随机性?
在这篇文章中,我们将学*一个重要的算法来添加噪声到我们的数据,我们将回答上述问题。
Photo by Paul Wong on Unsplash
随机回答:
随机化回答可能是在数据中引入所需噪声的最简单方法。它为你的研究参与者提供了故意撒谎的便利。
研究参与者被告知报告他们是否拥有财产 P,如下所示:
- 抛硬币。
- 如果是反面,那就如实回答。
- 如果是正面,抛第二枚硬币,正面回答“是”,反面回答“否”。
“隐私”来自于对任何结果的似是而非的否认。这让参与者有机会自己给数据添加噪声。
Photo by Icons8 team on Unsplash
“是”答案的预期数量是不具有属性 P 的参与者数量的 1/4 倍,加上具有属性 P 的参与者数量的 3/4。因此,如果 P 是具有属性 P 的参与者的真实分数,则“是”答案的预期数量是(1/4)(1p)+(3/4)P =(1/4)+P/2。因此,我们可以将 p 估计为回答“是”的分数的两倍减去 1/2,即 2((1/4)+p/2)-1/2。
因此,如果在调查结束时,你发现 60%的人吸烟,你实际上有 2(60%) - 50% = 70%的人吸烟。
随机化在这里是必不可少的,最重要的是因为它非常符合差分隐私的定义,无论关于一个人的其他数据集是什么,没有对手能够知道一个人是否吸烟,即使在获得访问数据之后。
但即使在这一切之后,如果我们有一个对我们数据库的查询,可能会泄漏其中的私人信息,我们会说我们的隐私受到了损害。因此,如果我们从数据库中删除一个人,并且查询的输出发生变化,我们可以说这个人的私人信息被泄露了。事实上,查询输出中的这种变化在数据隐私方面非常重要,因此它有一个特定的身份,即 ℓ1-敏感性或简单敏感性。
Formal definition of sensitivity
因此,基本上,敏感度是一个数据库和一个并行数据库的查询输出的变化,每个数据库都有一个人被删除。因此,如果我们的调查中有 10 个人,我们可以根据这些数据创建 10 个并行数据库,每个数据库中少一个人。我们也知道查询只是一个函数,因此数据库 x 和它的并行数据库 y 之间的ℓ1-敏感度本质上如下所示。
ℓ1-灵敏度= max∨f(x)f(y)∨
较大的敏感度值表示查询对数据库中的变化高度敏感,因此更有可能危及隐私。
现在我们准备介绍差分隐私的数学定义:
Formal definition of differential privacy
不要担心这乍一看很吓人,我们将在下面揭开它的神秘面纱。
展开差分隐私的正式定义;
差分隐私的定义表明,类似“硬币投掷算法”的随机化算法将在数据库及其并行数据库上生成相似的结果,这些数据库本质上是相似的数据库。因此,我们可以确立这样一个事实,即引入随机性可以保护我们数据中的隐私。
但是如果我在数据中引入了过多的随机性,比如说我完全翻转了数据库中的条目,这难道不会影响我的分析结果吗?因此,需要了解的一件重要事情是:应该添加多少噪声。如果你还记得上一篇文章,你应该知道,如果我们试图维护我们的隐私,我们会失去我们的准确性。
ε(ε)只不过是应该引入多少噪声的度量,因此它是控制隐私和准确性之间权衡的参数。它是控制隐私保证强度的核心参数,因此也是可以私下回答的查询数量和可达到的准确性。(贾斯汀·许等。艾尔。)
δ (delta) 是这里的另一个参数,它给出了ε不保持其值的概率的度量。
因此,该公式表明,对于任何随机化算法 M ,在数据库 x 上输出 s (s ∈ S)的概率至多是在任何并行数据库 y 上输出 s 的概率的 exp^ε 倍。如果该算法符合这个标准,我们可以称之为ε-δ差分私有算法。
这就是我们如何理解差别隐私背后的公式。
我们刚刚了解到的叫做局部差分隐私关于何时添加噪声,我们将在下一篇文章中了解更多。
总结:
因此,我们了解了如何对我们的数据执行差分隐私,并学*了基本的数学知识。然而,很多问题仍然没有答案,比如我们应该选择ε和δ的什么值,我们将在接下来的文章中尝试理解这些问题。这篇文章是我将要写的关于数据分析中的隐私的系列文章中的第二篇。
在下一篇文章中,我们将了解更多关于差分隐私的算法。
敬请关注。暂时快乐学*。
PS。这是我关于媒体的第二篇文章,所以欢迎任何反馈和建议。
资源:
- https://www.cis.upenn.edu/~aaroth/Papers/privacybook.pdf
- http://www.cis.upenn.edu/~ahae/papers/epsilon-csf2014.pdf
A/B 测试学*资源集:新手到高手
原文:https://towardsdatascience.com/a-collection-of-a-b-testing-learning-resources-newbie-to-master-6bab1e0d7845?source=collection_archive---------12-----------------------
Source: https://vwo.com/ab-testing/
就像 20 世纪制药公司如何通过临床试验测试药物有效性一样,现代软件公司严重依赖测试和学*文化来构建成功的产品[1]。根据您作为分析师、数据科学家、产品经理、营销人员甚至设计师的角色,获取日常工作所需的相关 A/B 测试知识至关重要。
然而,尽管它在工业中有广泛的应用,如何启动 A/B 测试在学校里很少被教授,对于这个领域的大多数新人来说,他们不得不花大量的时间研究实验的细节。因此,为了使这一过程不那么耗时,本文编制了一个简短的在线学*资源、博客和最新研究论文列表,它们可以最好地帮助你达到所需的实验掌握水平。
本文分为 5 节,每节内的每个主题/子主题最多包含 1 至 2 个资源,这样你不会因为阅读过多而感到不知所措。此处将分别涵盖的所有不同部分和主题的快速总结:
- 第一部分:测试的价值和“为什么”
- 第二节:统计和基本的“如何”
- 第三部分:行业应用和高级“如何”
- 第四部分:高级统计:顺序测试
- 第五部分:端到端实验平台
❤特别感谢 Iris、Joe 和 Jonas 的灵感、知识分享和对以下资源的贡献!❤
还请注意,本文主要关注 A/B 测试材料,而不是 A/N 或 A/B/n 测试等。如果你想看到其他类型测试的类似资源共享,请留下评论!
第一部分:测试的价值和“原因”
在我们谈论其他事情之前,为什么我们需要运行 A/B 测试?下面的两个资源解释了运行 A/B 测试需要什么,它的目标是什么,以及它如何帮助现代数字软件和产品开发。
作为一句话的总结,A/B 测试建立因果关系。
[## A/B 测试:如何做好
简而言之,当需要建立网站和应用程序时,太多的公司做决定-从新…
hbr.org](https://hbr.org/2017/09/the-surprising-power-of-online-experiments) [## A/B 测试
A/B 测试(也称为桶测试或分割测试)是一个随机实验,有两个变量,A 和 B。它…
en.wikipedia.org](https://en.wikipedia.org/wiki/A/B_testing)
第二部分:统计和基本“方法”
既然我们已经清楚了价值和“为什么”,接下来的主题是关于支持每个测试背后的决策的统计数据,以及从头开始启用测试的过程。
这包括回答以下问题:
- 我们要测试什么,使用什么指标?
- 如何在测试前估计样本量并选择置信度和功效水平(参考消息 这里是 Adobe Target 的样本量计算器的链接 )?
- 如何拆分测试受众?
- 使用什么统计检验来计算显著性水平(假设这里考虑的是传统的 t 检验)?
- 测试要进行多久?
- 如何解读结果并据此做出决策?
对于那些对典型的测试是如何完成的感到好奇的初学者,我在这里强烈推荐两个资源。
Udacity 的 A/B 测试课程是刚开始学* A/B 测试的人必看的课程。它涵盖了假设、设计和分析测试的端到端过程,以及从业者应该注意的一些陷阱。推荐给任何直接使用 A/B 测试的人。
[## A/B 测试| Udacity
本课程将涵盖 A/B 测试的设计和分析,也称为分裂测试,这是在线实验…
www.udacity.com](https://www.udacity.com/course/ab-testing--ud257)
如果你没有时间看讲座,我发现这个课程总结很有参考价值&快速查找。
[## Udacity A/B 测试课程总结
最*我在 Udacity 上完成了 Google 的 A/B 测试课程。该课程已被极力推荐给…
towardsdatascience.com](/a-summary-of-udacity-a-b-testing-course-9ecc32dedbb1)
此外,著名的网络受控实验:调查和实践指南 论文[2]揭示了从微软运行的网络实验中获得的经验教训,微软是最早的在线实验平台之一。一个伟大的阅读来了解价值,潜在的统计数据,和实践的网络实验(特别是。与 A/B 测试相关的材料的第 3 部分—参见下面的截图)。
(Screenshot) Controlled experiments on the web: survey and practical guide. Section 3.2.
第三部分:行业应用和高级“如何”
现在是时候学*如何在行业中严格应用测试概念,以及在实验设计讨论中经常出现的术语。
新奇效果
当引入测试体验时,有经验的用户在短期和长期会有什么不同的反应?这种差异如何给结果带来偏差?【2】中的“首因效应和新奇效应”(3.6 限制,#3)一节总结了这个问题,并提供了一个通用的解决方案。
网络效果
对于在社交媒体网站上运行的测试,由于用户交互的性质,用户分配变得棘手。下面这篇由 OkCupid 发表的文章详细描述了这个问题和可行的解决方案。
** [## 社交网络中 A/B 测试的陷阱
我经常被要求在 OkCupid 上帮助运行 A/B 测试,以衡量一个新功能或设计变更会产生什么样的影响…
tech.okcupid.com](https://tech.okcupid.com/the-pitfalls-of-a-b-testing-in-social-networks/)
多重比较问题
[## 你如何对许多变体,比如说 20 个或者更多的变体进行 A/B 测试?
回答(3 之 1):不应该。从 WiderFunnel 的这篇博客文章中摘录的答案变化越多,见解就越深刻…
www.quora.com](https://www.quora.com/How-would-you-run-an-A-B-test-for-many-variants-say-20-or-more)
测试审计(如 A/A 测试)
在第一次设置新的启动界面或新的测试软件后,验证测试管道(数据收集、用户分配、行为跟踪)很重要;否则,如果没有彻底调查,无效的结果不仅浪费时间,而且容易导致错误的业务决策。 " 在 Web 上运行受控实验时要避免的七个陷阱 " 论文[3]中的第 8 节给出了验证测试管道的方法的综合列表,包括在线/离线 A/A 测试、仪器等。).
与工程展示阶段相结合的 A/B 测试
在实践中,产品展示通常会经历一个简化的工程过程,称为“分阶段展示”,其最后一步是正式的功能发布。安全速度:使用受控展示大规模软件部署实用指南论文[4]介绍了一种将分阶段展示与 A/B 测试(受控展示(狗粮、内部、内部人员和生产)相集成的混合方法。**
第四部分:高级统计:顺序测试
到目前为止,我们假设使用传统的 t 检验(也称为固定范围检验)进行假设检验。2015 年,Optimizely 发表了一篇博文,解释了他们为什么将底层统计引擎改为顺序测试(本质上是基于贝叶斯统计)。根据他们的测试数据,顺序测试“可以在不牺牲速度的情况下,将错误声明输赢变化的几率从 30%降低到 5%”。虽然没有像 t-test 那样在行业中广泛采用,但顺序测试提供了一种启动在线实验的新方法,它需要更少的输入(例如,没有最小可检测效应),并且可能用更少的样本更快地得出结论。
** [## 互联网时代的统计学:Optimizely 新统计引擎背后的故事
经典的统计技术,如 t 检验,是优化行业的基石,帮助公司作出…
blog.optimizely.com](https://blog.optimizely.com/2015/01/20/statistics-for-the-internet-age-the-story-behind-optimizelys-new-stats-engine/)
鉴于顺序测试是一个新概念,我们还没有找到很多关于这个主题的学*资源。下面的 Udemy 讲座“Python 中的贝叶斯机器学*:A/B 测试”虽然技术含量很高,但却是为数不多的使用贝叶斯统计进行 A/B 测试的资源之一。推荐给铁杆数据科学家。
[## Python 中的贝叶斯机器学*:A/B 测试
这个课程是关于 A/B 测试的。A/B 测试无处不在。营销、零售、新闻源、在线广告…
www.udemy.com](https://www.udemy.com/bayesian-machine-learning-in-python-ab-testing/)
第五部分:端到端实验平台
对于同时运行大量实验(100 个,有时 1000 个测试)的公司来说,构建一个能够大规模规划、启动和分析 A/B 测试的实验平台至关重要。然而,这项工作通常超出了一个数据科学家的工作范围,需要工程投资和产品购买来证明其长期价值。如果你有类似的使用案例,下面是一些关于科技公司如何在内部建立自己的实验平台的快速阅读:
[## 扩展 Airbnb 的实验平台
在 Airbnb,我们在用户体验和产品功能上不断迭代。这可能包括对…的更改
medium.com](https://medium.com/airbnb-engineering/https-medium-com-jonathan-parks-scaling-erf-23fd17c91166) [## 用优步工程构建智能实验平台
由分阶段部署和智能分析工具组成,优步工程的实验平台能够…
eng.uber.com](https://eng.uber.com/experimentation-platform/) [## facebook/Ax
Ax 是一个可访问的通用平台,用于理解、管理、部署和自动化自适应…
github.com](https://github.com/facebook/Ax) [## 这都是关于测试的
网飞实验平台
medium.com](https://medium.com/netflix-techblog/its-all-a-bout-testing-the-netflix-experimentation-platform-4e1ca458c15)
感谢您的阅读!评论、反馈、问题、你想贡献的额外资源、异议等。这里欢迎大家:)
关注我 关于 Medium.com 科技&商业相关话题的定期博客,以及👏🏻 👏 👏🏽非常感谢
论文参考文献
[1]关于 A/B 测试的复*https://hbr.org/2017/06/a-refresher-on-ab-testing
[2] Ron Kohavi 等,“网络上的受控实验:调查和实践指南”。
[3] Thomas Crook 等人,“在网上进行受控实验时要避免的七个陷阱”。
[4]夏彤等人,“安全速度:使用受控展示的大规模软件部署实用指南”。****
每个自然语言处理(NLP)从业者必须知道的资源集合
原文:https://towardsdatascience.com/a-collection-of-must-known-pre-requisite-resources-for-every-natural-language-processing-nlp-a18df7e2e027?source=collection_archive---------17-----------------------
一个你绝不会错过的终极指南!!
嘿,你是一个想进入自然语言处理世界的新手,还是一个对网络上的大量信息感到困惑并且不知道从哪里开始的普通自然语言处理实践者?放松,我也一样,直到我决定花大量的时间在一个地方收集所有需要的资源。
经过去年以来从多种来源的彻底阅读,这里是我编译的最好的学*资源版本,可以帮助任何人开始他们进入 NLP 迷人世界的旅程。有各种各样的任务属于更广泛的自然语言处理领域,如机器翻译、问答、文本摘要、对话系统、语音识别等。然而,要在这些领域中的任何一个领域工作,基本的必备知识是相同的,我将在这篇博客中简要讨论。(注意:如果任何链接已经过期,请在评论区告诉我。 )
简单说一下免责声明关于内容:
1。我将要讨论的内容大部分属于现代的自然语言处理,而不是经典的自然语言处理技术。
2。任何人都不可能去翻遍所有可用的资源。我已经尽了最大的努力。
3。我假设读者对至少相当数量的关于机器学*(ML)和深度学*(DL)算法的知识感到满意。
4。对于我将要涉及的所有主题,我主要引用了博客或视频方面的最佳资源。读者可以很容易地找到每个单独主题的研究论文。我觉得上面提到的博客足以让任何人充分理解各自的主题。
下面是我通往 NLP 世界的路线图: 1。单词嵌入— Word2Vec,GloVe,FastText
2。语言模型& RNN
3。上下文单词嵌入— ELMo
4。NLP 中的迁移学*— ULMFiT
5。句子嵌入
6。Seq2Seq &注意机构
7。变形金刚
8。OpenAI GPT &伯特
9。GPT-2,XLNet
10。总结
我们来简单总结一下以上 10 个话题:
1。单词嵌入— Word2Vec、GloVe、FastText
当我们开始学* NLP 时,首先想到的是我们如何将单词表示成数字,以便任何 ML 或 DL 算法都可以应用于它。这就是矢量/嵌入这个词发挥作用的地方。顾名思义,这里的目的是将任何给定的单词作为输入,并输出一个表征该单词的有意义的向量表示。基于诸如 Word2Vec、GloVe、FastText 之类的底层技术,存在不同的方法来获得这种表示
Word2Vec:
从这个话题开始,我建议读者在 YouTube 上免费观看斯坦福 CS224N: NLP 与深度学*| Winter 2019 的讲座 1 和 2。
&list = ploromvodv 4 rohcuxmzknm 7j 3 fvwbby 42 z&index = 1
这两个讲座形成了一个关于语义词表示的坚实背景。除此之外,您还将了解 Word2Vec 和 GloVe model 工作中涉及的详细数学知识。一旦你对此感到满意,我将向你推荐一些我认为对这个话题最有用的博客。在这些博客中,你可以找到一些帮助你更好理解的例子和图像。
http://mccormickml . com/2016/04/19/word 2 vec-tutorial-the-skip-gram-model/
http://mccormickml . com/2017/01/11/word 2 vec-tutorial-part-2-negative-sampling/
http://jalammar.github.io/illustrated-word2vec/
我希望这些阅读足以让你对 Word2Vec 有一个坚实的理解。让我们继续前进。
手套:
在斯坦福深度学*自然语言处理(2017 年冬季)的第 3 讲中,GloVe 得到了更好的解释
https://www.youtube.com/watch?v=ASn7ExxLZws
除此之外,下面的博客可以帮助你清楚地了解这个话题及其背后的数学原理。
【slide share id = 229369562&doc = paperpassedgloveglobalvectorsforwordrepresentationexplained-200228052056&type = d】
【slide share id = 229369559&doc = emnlpwhatisloveparti-towardsdatascience-200228052054&type = d】
【slide share id = 229369555&doc = emnlpwhatislovepartii-towardsdatascience-200228052050&type = d】
【slide share id = 229369551&doc = emnlpwhatislovepartiii-towardsdatascience-200228052047&type = d】
我希望你到目前为止已经理解了 GloVe 是如何利用全局统计信息而不是 Word2Vec 来优化一个完全不同的目标的。
快速文本:
FastText 是由脸书研究团队创建的一个库,用于高效学*单词表示和句子分类。它支持类似于 Word2Vec 的训练 CBOW 或 Skip Gram 模型,但它对单词的 n-gram 表示进行操作。通过这样做,它有助于通过利用字符级信息找到罕见单词的向量表示。
请参考以下链接,以便更好地理解:
https://towardsdatascience . com/fast text-under-the-hood-11 EFC 57 B2 B3https://arxiv.org/pdf/1607.04606v1.pdfhttps://arxiv.org/pdf/1607.01759.pdf
如果您已经完成了上面提到的要点,那么您现在至少对单词嵌入方法有了更深的理解。是时候进入 NLP 的主干了——语言模型。
2.语言模型(LM)和 RNN
语言模型是我们日常使用的东西。一个这样的场景发生在用手机、Gmail 或 LinkedIn 发短信的时候。LM 为您提供了您希望进一步键入的最有可能的建议。简单地说,LM 就是预测下一个单词是什么的任务。我关于语言模型是自然语言处理的支柱的论点是因为所有当前的迁移学*模型都依赖于语言模型作为基础任务。在你即将到来的旅程中,你会进一步了解这些。但在此之前,我们先来看看了解 LM 的资源。
像往常一样,我的第一个建议是浏览斯坦福大学关于这个特定主题的精彩讲座。CS224N 的第 6 讲很好地涵盖了这个话题。它让你一瞥 LM 在神经网络之前是如何发展的,以及神经网络基本上 RNN 给它带来了什么优势。另外,如果你想重温一下关于 RNNs 的知识,请参考第 7 课。
https://www.youtube.com/watch?v=iWea12EAu6U&list = ploromvodv 4 rohcuxmzknm 7j 3 fvwbby 42 z&index = 6
https://www.youtube.com/watch?v=QEw0qEa0E50&list = ploromvodv 4 rohcuxmzknm 7j 3 fvwbby 42 z&index = 7
另外,如果你觉得对 RNNs 的内部运作不太了解,你可以去参加我在 Udemy 上学的一门很棒的课程
深度学*:高级 NLP 和 RNNs
https://www.udemy.com/course/deep-learning-advanced-nlp/
这是我在网上大量的在线课程中发现的最有用的课程之一。在本课程中,您可以通过展开 rnn、将其转换为双向等方式来理解 rnn 的工作原理。此外,你可以学*在 Keras 中对这些模型进行编码——这是最简单的深度学*框架之一。
3。上下文单词嵌入— ELMo
猜猜什么单词嵌入又回来了!!等等,有一个术语叫“语境”,它不同于我们之前研究过的方法。好吧,那我们为什么不把这个话题和第一个话题放在一起研究。嗯,只是因为我们需要 LM 的知识来理解这个题目。是的,正如我之前提到的,在我们的旅程中,我们遇到了 LM 的第一个应用。相信我到最后,你会同意我把 LM 授予 NLP 的中坚力量。说够了,让我们进入我们当前的主题——上下文单词嵌入
来自语言模型的嵌入(ELMo)使用 LM 来获得单个单词的嵌入。到目前为止,我们对任何输入单词都只有一个嵌入,比如说银行。现在假设我有两个不同的句子——我去银行取钱,站在河边。在这两个句子中,单词 bank 的意思完全不同,因此它们肯定有不同的向量表示。这就是语境嵌入的目的。ELMo 是一种基于多层双向 LSTM 模型的方法,用于获得上下文单词嵌入。请浏览以下博客来了解它们。
https://mlexplained . com/2018/06/15/paper-parsed-deep-contextized word-representations-explained/https://www . slide share . net/shuntaroy/a-review-of-deep-contexternalized-word-representations-Peters-2018
希望以上两个资源足以帮助你更好的了解 ELMo。是时候向前迈进了…
4.自然语言处理中的迁移学*— ULMFiT
在过去的一年里,迁移学*彻底改变了自然语言处理领域。大多数当前正在开发的算法都利用了这种技术。在对计算机视觉领域做出重大贡献之后,迁移学*终于让 NLP 从业者欢欣鼓舞。
用于文本分类的通用语言模型微调(ULMFiT)就是这样一种方法,应该归功于这种奇妙的变化。
ULMFiT 引入了多种方法来有效利用模型在预训练期间学*到的大量内容——不仅仅是嵌入,也不仅仅是
情境化嵌入。ULMFiT 引入了一个语言模型和一个过程,以便针对各种任务有效地微调该语言模型。
最后,预训练和微调概念开始在 NLP 领域显示其魔力。ULMFiT 论文还介绍了不同的技术,如区别微调和倾斜三角形学*率,这些技术有助于改进迁移学*方法的使用方式。
准备探索这些令人兴奋的术语,然后保持冷静,参考以下博客:
http://NLP . fast . ai/class ification/2018/05/15/introducing-ulm fit . htmlhttps://ahmedhanibrahim . WordPress . com/2019/07/01/a-study-on-cove-context 2 vec-elmo-ulm fit-and-Bert/
现在,你一定很熟悉乌尔菲特了。我们旅程的下一步是句子嵌入。
5.句子嵌入
学*了足够多的单词嵌入。句子呢?我们能获得类似于一个词的句子的某种表示吗?一种非常幼稚但强大的基线方法是平均句子的单词向量(所谓的单词袋方法)。除此之外,可以有基于无监督、有监督和多任务学*设置的不同方法。
无监督的方案学*句子嵌入作为学*的副产品,以预测连贯的连续句子。这里的主要优势是,你可以获得大量无人监管的数据,因为互联网上充满了文本类型的东西。跳过思维向量和快速思维向量是在无监督环境中开发的两种成功的方法。
另一方面,监督学*需要为给定任务标注的标签数据集。完成这项任务让你学会一个好的句子嵌入。脸书研究小组的 InferSent 就是这样一个有趣的方法。现在,为了解决无监督嵌入和有监督嵌入之间的冲突,多任务学*机制应运而生。多任务学*的几个建议已经发表,如 MILA/MSR 的通用句子表示,谷歌的通用句子编码器等。
兴奋的来到这个世界。探索&探索提到的链接:
https://medium . com/hugging face/universal-word-sentence-embeddings-ce 48 DDC 8 fc 3ahttps://ai . Google blog . com/2018/05/advances-in-semantic-textual-similarity . html
6.Seq2Seq &注意机制
已经学*了 RNN 模型的变体,并且对单词和句子嵌入有了很好的理解,现在是时候前进到一个令人兴奋的 NLP 架构,称为序列 2 序列模型(Seq2Seq)。这种体系结构用于各种 NLP 任务,如神经机器翻译、文本摘要、会话系统、图像字幕等。序列到序列模型是一种模型,它采用一个项目序列(单词、字母、图像特征等)并输出另一个项目序列。理解这些模型的最好方法是借助可视化,这是我想向你推荐的我最喜欢的 NLP 作者的博客之一。他不是别人,正是杰伊·阿拉姆马。相信我,你会喜欢浏览他的每一个博客。他用来解释这些术语的努力是杰出的。点击下面的链接进入这个美丽的世界。
http://jalammar . github . io/visualizing-neural-machine-translation-mechanics-of-seq 2 seq-models-with-attention/
我想我确实需要向你进一步解释 Seq2Seq,因为到现在为止,你一定很熟悉它。然而,现在我想再次向您推荐斯坦福讲座,以了解有关统计和神经机器翻译的更多信息。了解 Seq2Seq 将有助于你流畅地进行这些讲座。此外,注意力是最重要的话题之一,在那里详细讨论。此外,您还将了解用于评估 NMT 模型的波束搜索解码& BLEU 度量。
敬请参考 CS224N 讲座—8
https://www.youtube.com/watch?v=XXtpJxZBa2c&list = ploromvodv 4 rohcuxmzknm 7j 3 fvwbby 42 z&index = 8
7.变形金刚(电影名)
该是野兽——变形金刚的时候了。虽然 LSTM 模型是革命性的 NLP 行业,它是变压器,开发出了开箱即用,作为 RNN 模型的改进替代品。
Transformer 是一个使用注意力来提高这些模型训练速度的模型。
转换器有助于并行化。论文中提出的变形金刚就是你所需要的全部注意力。由于并行化的性质,它将我们从 RNN 模型中涉及的重复连接中解放出来。它不仅有助于减少训练时间,而且在各种 NLP 任务上有很大的提高。它类似于 Seq2Seq 架构,但它只依赖于注意力机制及其变体。再说一次,理解这个话题的最佳博客是 Jay Alammar 的博客。事实上,如前所述,您可以关注他的所有博客来了解这些先进的 NLP 技术。
http://jalammar.github.io/illustrated-transformer/
除此之外,如果你想从实现的角度理解这篇论文,那么请参考哈佛大学 NLP 小组的这篇精彩的博客。
https://nlp.seas.harvard.edu/2018/04/03/attention.html
如果你已经成功理解了以上两篇博客,那么给自己一个大拇指吧!!相信我,这不是一件容易的事。
现在让我们探索一下研究人员是如何利用这种更新的架构来构建像伯特、GPT-2 等这样的艺术模型的。
8.开放 GPT &伯特公司
迁移学*又回来了,但现在当然是用变形金刚。很简单,如下:利用变压器解码器的堆栈来建立一个新的模型称为 GPT 或利用编码器部分的变压器来建立一个惊人的模型称为伯特。相信我,即使你是 NLP 领域的新手,并且在过去的一年里一直在听 NLP 流行语,伯特和 GPT 也是这个列表中的佼佼者。
生成性预训练(GPT)的目标与 ULMFit 相似,即在 NLP 中应用迁移学*。但是有一个主要的区别。是的,你说对了——用变形金刚代替 LSTM。除此之外,在培训目标上也有一些不同,你可以通过下面提到的博客来了解。总而言之,GPT 的总体思想是训练用于语言建模任务的变换器解码器,也称为预训练。一旦它被预先训练,我们就可以开始使用它来完成下游任务。可以有许多输入转换来处理各种这样的任务。
NLP 最火的词来了——BERT。
主要目标是建立一个基于 transformer 的模型,它的语言模型既取决于左上下文,也取决于右上下文。这是 GPT 的局限性,因为 GPT 只训练了一个正向语言模型。现在,为了实现双向调节的目标,BERT 使用了变压器的编码器部分。为了在计算注意力分数时看不到未来的单词,它使用了一种叫做掩蔽的特殊技术。根据这篇论文的作者,这种掩蔽技术是这篇论文的最大贡献。除了处理多个句子之间关系的掩蔽目标之外,预训练过程还包括一个额外的任务:给定两个句子(A 和 B),B 是否可能是 A 后面的句子?
好吧,如果你对上面的一些术语感到有负担,并且想要对它们有更深入的了解,放松就好。所有这些术语在下面的博客中都有很好的解释:
http://jalammar . github . io/a-visual-guide-to-using-BERT-for-the-first-time/https://mlexplained . com/2019/01/07/paper
9.GPT-2,XLNet
GPT-2 只不过是 GPT 的继任者,参数是它的 10 倍以上,训练数据量也是它的 10 倍以上。由于担心该技术的恶意应用,作者最初没有发布更大的训练模型,这成为一个有争议的话题。
XLNet 是广义自回归模型。它在 20 个任务上超过了 BERT,通常是大幅度超过。这是自然语言处理中迁移学*的新方法。为了更广泛地了解 GPT-2 和 XLNet,请参考以下博客。
https://openai.com/blog/better-language-models/https://towardsdatascience . com/openai-GPT-2-理解-语言-生成-通过-可视化-8252 f683 B2 F8**
10 摘要
最后,您已经按照我们提议的计划完成了学* NLP 先决条件的整个过程。向你致敬!!!由于大量的研究人员积极从事这一领域的工作,模型不断被涉及。因此,几乎每个月,你都会看到一篇新的论文,它超越了之前的技术水平。因此,在这个快速变化的世界中前进的唯一方法是通过定期浏览研究论文和这些信息丰富的博客来了解最新知识。
如果你想回忆整个旅程,可以浏览一下下面提到的博客。
https://lilian Weng . github . io/lil-log/2019/01/31/generalized-language-models . html
在这里,我还列出了一些我认为在学* NLP 领域的新主题时最有用的最佳博客:
【https://medium.com/huggingface】http://jalammar.github.io/https://ruder.io/https://mlexplained.com/
我希望我的资源对读者有所帮助。如前所述,任何人都不可能涵盖所有主题。建议总是受欢迎的,引用一些更好的博客或我错过的重要话题。我希望任何对这些先决条件了如指掌的人都能胜任任何 NLP 任务。到那时,干杯, 尽情享受!!!
一个常见的数据科学错误:通过操纵模型输入进行预测/推荐
原文:https://towardsdatascience.com/a-common-data-science-mistake-prediction-recommendation-by-manipulating-model-inputs-f7eac2d12a84?source=collection_archive---------16-----------------------
“我们训练了一个高性能的机器学*模型。然而,这并不奏效,在实践中也没有用。”这句话我听过好几次,每次都急于找出原因。一个模型在实践中失败可能有不同的原因。由于这些问题通常不会在数据科学课程中解决,因此在本文中,我将解决设计和部署机器学*模型时的一个常见错误。
在本文的其余部分,首先,我将讨论导致机器学*模型误用的相关性和因果性之间的混淆。我将用一个例子来说明这个讨论。之后,显示了模型的输入和输出之间的不同可能性。最后,我提供一些建议来避免这个错误。
相关性而非因果关系
将相关性误认为因果关系会导致错误的结果。混淆相关性和因果关系的一个例子是对魔鬼经济学的分析,伊利诺伊州给学生发了书,因为分析显示,家里有书与高分直接相关。然而,现实是,父母通常买书的房子有一个令人愉快的学*环境。进一步的分析显示,那些家里有几本书的学生在学业上表现更好,即使他们从未读过这些书。事实上,获得更高的分数并不是书本的结果,而是环境的结果。
回到我们的主题,在您开发一个模型之后,您不能操作输入参数(特征)来查看对输出的影响。原因是输入要素可能是输出的结果,而不一定是输出的原因。高性能机器学*模型告诉你的是,输入和输出之间存在相关性。您无法调整输入以获得所需的输出,然后根据调整后的输入提供建议。
例子
这里有一个例子,我们开发了一个回归模型,但该模型提供了一个错误的预测/建议。假设我们有室外温度和室内温度。我们可以开发一个线性回归模型,根据室内温度来估算室外温度。
T(外)= C1T(内)+C2*
其中 C1 和 C2 是从数据中导出的常系数。假设该模型具有非常高的性能(例如,超过 99%)。
通过使用该模型,我们发现如果室内温度增加 5C,室外温度将增加 10C。我们能为房间买一个加热器并提高室内温度来享受温暖的一天吗??!!当然不是。原因是内部温度是结果,而不是原因。当数据科学家操纵模型的输入(例如内部温度)以获得期望的输出(例如外部温度)时,也会发生同样的事情。基于操纵输入的建议在实践中通常是无用的。
投入产出关系
现在,让我们看看当特征之一 A 和输出 B 之间存在相关性时的不同情况。下图显示了不同的情况。
Case 1: A causes B. Manipulating A affects B in the real world.
Case 2: B causes A. Manipulating A does not affect B in the real world.
Case 3: A causes B and B causes A. Manipulating A affects B but it is not a direct effect.
Case 4: A and B are consequences of a common cause C. Manipulating A does not affect B.
很明显,在情况 2、3 和 4 中,模型的输出对于 A 的操纵值与我们在现实世界中看到的不同。应该注意的是,即使在情况 1 中,输出也可能不同,因为 A 可能与模型的其他输入具有某种相关性。这意味着当 A 的值改变时,其他输入也会改变。因此,仅更改其中一个输入要素并研究其效果是不正确的。
如何避免?
首先,要意识到这个问题。你应该知道,通过操纵输入,你无法预测输出。记住这一点会影响你如何设计模型,如何选择未来。
第二,如果你想设计一个预测模型,你需要有历史数据来告诉你的模型改变输入的影响。通过快照,您无法预测如果输入发生变化会发生什么。在这种情况下,您可以根据历史数据来定型模型。在我们的示例中,当我们想要查看室内温度对室外温度的影响时,我们需要一些样本,包括室内温度的变化及其对室外温度的影响(例如,1 小时后)。在这种情况下,模型了解到室内温度对室外温度没有影响。
第三,利用你的领域知识或与专家交谈,看看你的预测/推荐结果是否有意义。这不仅可以避免这个错误,还可以避免其他逻辑错误。例如,您的编码中可能有一些您没有意识到的错误。感觉检查可以帮助您从总体上验证模型。
结论
设计机器学*模型是一项棘手的任务。尽管模型在训练数据上有很高的性能,但在实践中可能不起作用。在本文中,我讨论了机器学*模型的误用,它导致预测在现实世界中不起作用。其他原因可能是过度拟合、重复样本和无偏数据。利用你的领域知识或与一些专家交谈,看看你的预测/推荐结果是否有意义,这总是好的。
如果您有任何问题或意见,请在下面留下您的反馈,或者您可以随时通过 LinkedIn 联系我。
NER 大学和 NER 大学使用美国所有城市名的比较
原文:https://towardsdatascience.com/a-comparison-between-spacy-ner-stanford-ner-using-all-us-city-names-c4b6a547290?source=collection_archive---------13-----------------------
Sugarloaf Mountain, Rio De Janeiro, Brazil, using Kodak Ektar film.
最*,我不得不使用命名实体进行概念验证,直接选项显然是 NLTK、斯坦福 NER & Spacy。我记得读过几篇比较和的文章,前者给了空间优势,后者给了斯坦福优势。看到没有一个明确的案例,我决定做自己的测试。在 Zencity.io ,我们的域名是 govtech,我们的 POC 用例是识别尽可能多的美国城市名称。这个想法很简单,加载所有美国城市名称,看看哪个算法可以识别更多的“位置”。显然,我们可以在其他类别中识别姓名,如个人或组织,但这不是重点。请记住,这些分类器是用于完整的句子,而不是单独的实体,但是,这是一个很好的方式来测试,在一个干净和可控的方式,有多少被识别。一个包含所有相关文件的官方项目可以在下面的 Github 库中找到。
美国城市名称
我找到了一个带有美国城市名的 CSV 文件,里面有 63211 个城市,城镇等。
Several US cities, taken out of the CSV file.
空间
下一步是加载 spacy 并检查 Spacy 是否将每个城市别名识别为地理政治实体(GPE)。GPE 是西班牙人说它是一个已知的国家、城市或州的方式。下面的代码显示了如何做到这一点。其他命名实体可在文档中找到。
斯坦福的 NER
下一步是使用 NLTK 对斯坦福的 NER (SNER)的实现。我们从加载相关的库开始,指向斯坦福 NER 代码和模型文件,我们系统地检查 NER 标记者是否能识别所有的城市名称作为“位置”。对于第一个测试,使用旧的 API,我决定使用基本的 3 类模型,包括位置、人员和组织。为此,您可以使用下面的代码。
对于第二个测试,我使用了新的 API,正如克里斯多佛·曼宁所建议的。但是,我不知道算法中使用的默认模型是什么。
结果
A comparison of Spacy & Stanford’s NER
结论
令人惊讶的是,大多数评论都声称这两种观点各有一点优势。在我们的领域中,优势显然很大,我们可以使用旧 API 识别*两倍数量的实体,使用新 API 识别类似数量的实体,但是,我没有检查结果是否是两个相同的城市名称集。使用旧 API 的测试花费了 24 小时,使用新 API 的测试花费了 85 分钟,这是通过将预测发送到本地服务器而不是使用命令行运行预测所实现的运行时间的巨大差异。然而,似乎 Spacy 仍然胜过 NLTK 的斯坦福 NER。执行 63K 分类需要 Spacy~7 分钟,而 NLTK 大约需要 85 分钟。
Spacy 很有趣,使用起来很快,如果你不介意性能上的巨大差距,那么我会推荐将它用于生产目的,而不是 NLTK 对斯坦福大学 NER 的实现。
感谢塞缪尔·杰弗罗金、约夫·塔尔米、纳塔内尔·大卫多维茨的校对和评论。
Ori Cohen 拥有计算机科学博士学位,专注于机器学*。他领导着 Zencity.io 的数据科学团队,试图积极影响市民的生活。
线性回归中收缩法和选择法的比较
原文:https://towardsdatascience.com/a-comparison-of-shrinkage-and-selection-methods-for-linear-regression-ee4dd3a71f16?source=collection_archive---------8-----------------------
详细介绍 7 种流行的收缩和选择方法。
在本文中,我们将研究线性回归中子集选择和收缩的七种流行方法。在介绍了证明需要这种方法的主题之后,我们将逐一查看每种方法,包括数学属性和 Python 应用程序。
本文基于优秀的 Hastie,t .,Tibshirani,r .,& Friedman,J. H. (2009)的一章。统计学*的要素:数据挖掘、推理和预测。第二版。纽约:斯普林格。一些技术细节可能会被直接转述或引用。
为什么收缩或子集,这意味着什么?
在线性回归上下文中,子集化意味着从可用变量中选择一个子集包含在模型中,从而降低其维数。另一方面,收缩意味着减小系数估计值的大小(将它们向零收缩)。注意,如果一个系数收缩到零,相应的变量就会从模型中消失。因此,这种情况也可以被视为一种子集化。
收缩和选择旨在改进简单的线性回归。它需要改进有两个主要原因:
- 预测精度:线性回归估计往往偏差小,方差大。降低模型的复杂性(需要估计的参数的数量)可以减少方差,但代价是引入更多的偏差。如果我们能找到总误差最小的最佳点,那么由偏差加上方差产生的误差最小,我们就能改进模型的预测。
- 模型的可解释性:预测因素太多,人类很难掌握变量之间的所有关系。在某些情况下,我们愿意确定影响最大的变量的一个小子集,从而牺牲一些细节以获得全局。
设置和数据加载
在直接跳到方法本身之前,让我们先看看我们将要分析的数据集。它来自 Stamey 等人(1989)的一项研究,该研究调查了不同临床测量对前列腺特异性抗原(PSA)水平的影响。任务是基于一组临床和人口统计学变量来识别前列腺癌的风险因素。这些数据,连同一些变量的描述,可以在哈斯蒂等人的网站“统计学*的要素”教科书的数据部分找到。
我们将从导入本文中使用的模块开始,加载数据,并将其分成训练集和测试集,分别保存目标和特性。然后,我们将讨论每种收缩和选择方法,使其适合训练数据,并使用测试集来检查它在新数据上预测 PSA 水平的能力。
线性回归
让我们从简单的线性回归开始,这将构成我们的基准。它将目标变量 y 建模为 p 预测值或特征 X 的线性组合:
该模型具有 p + 2 个参数,这些参数必须从训练数据中估计:
- p 以β系数为特征,每个变量一个,表示它们对目标的影响;
- 一个截距参数,在上面表示为β0,这是在所有 x 都为零的情况下的预测。没有必要将它包含在模型中,事实上在某些情况下,它应该被删除(例如,如果一个人想要包含表示分类变量级别的全套虚拟变量),但一般来说,它给了模型更多的灵活性,正如您将在下一段中看到的;
- 高斯误差项的一个方差参数。
这些参数通常使用普通最小二乘法(OLS)来估计。OLS 最小化残差平方和,由下式给出
图形化地思考这个最小化标准是有帮助的。由于只有一个预测器 X ,我们处于由该预测器和目标形成的 2D 空间中。在此设置中,模型符合在 X-Y 空间中最接*所有数据点的直线,其接*度为所有数据点垂直距离的平方之和——见下面的左图。如果有两个预测值,X1 和 X2,空间增长到 3D,现在模型适合最接* 3D 空间中所有点的平面-参见下面的右面板。有了两个以上的特征,平面就变成了有点抽象的超平面,但思想还是一样的。这些可视化还有助于了解截距如何为模型提供更大的灵活性:如果包含截距,它允许直线或平面不穿过空间的原点。
Source: adapted from The Elements of Statistical Learning by Hastie et al. [1].
上述最小化问题有一个解析解,β参数可计算如下
在 X 矩阵中包含一列 1 允许我们在上面的公式中表示β-hat 向量的截距部分。“β”上方的“帽子”表示它是基于训练数据的估计值。
偏差-方差权衡
在统计学中,要考虑估计量的两个关键特征:偏差和方差。偏差是真实总体参数和预期估计量之间的差异。它测量估计的不准确性。另一方面,方差衡量的是它们之间的差异。
Source: kdnuggets.com
显然,如果偏差和方差过大,它们都会损害模型的预测性能。然而,线性回归倾向于遭受方差,同时具有较低的偏差。如果模型中有许多预测特征,或者如果它们彼此高度相关,情况尤其如此。这就是子集化和规范化的作用。它们允许以引入一些偏差为代价减少方差,最终减少模型的总误差。
在详细讨论这些方法之前,让我们对前列腺数据进行线性回归,并检查其样本外平均预测误差(MAE)。
最佳子集回归
为线性回归选择变量子集的一个简单方法是尝试所有可能的组合,并选择一个最小化某个标准的组合。这就是最佳子集回归的目标。对于每个 k ∈ {1,2,…,p},其中 p 是可用特征的总数,它挑选大小为 k 的子集,该子集给出最小的残差平方和。然而,平方和不能用作确定 k 本身的标准,因为它必然随着 k 而减少:模型中包含的变量越多,其残差就越小。但这并不能保证更好的预测性能。这就是为什么应该使用另一个标准来选择最终的模型。对于侧重于预测的模型,测试数据上的错误(可能是交叉验证的)是常见的选择。
由于最佳子集回归没有在任何 Python 包中实现,我们必须手动循环遍历 k 和所有大小为 k 的子集。下面的代码块完成了这项工作。
里脊回归
最佳子集回归的一个缺点是,它不能告诉我们从模型中排除的变量对响应变量的影响。岭回归为变量的硬选择提供了一种替代方法,将变量分为包含在模型中的变量和排除在模型外的变量。相反,它惩罚系数,使它们向零收缩。不完全是零,因为这将意味着从模型中排除,而是在零的方向上,这可以被视为以连续的方式降低模型的复杂性,同时保持模型中的所有变量。
在岭回归中,线性回归损失函数以这样的方式增加,不仅最小化残差平方和,而且惩罚参数估计的大小:
解决这个最小化问题得到βs 的解析公式:
其中 I 表示单位矩阵。罚项λ是要选择的超参数:其值越大,系数越向零收缩。从上面的公式中可以看出,当λ变为零时,加性罚消失,并且β-岭变得与来自线性回归的β-OLS 相同。另一方面,当λ增长到无穷大时,β-ridge 接*于零:通过足够高的惩罚,系数可以任意收缩到接*于零。
但是,这种收缩真的会像承诺的那样以引入一些偏差为代价来减少模型的方差吗?是的,从岭回归估计的偏差和方差的公式中可以清楚地看出:随着λ增加,偏差也增加,而方差下降!
现在,如何选择λ的最佳值?运行交叉验证,尝试一组不同的值,并选择一个最小化测试数据交叉验证错误的值。幸运的是,Python 的 scikit-learn 可以为我们做到这一点。
套索
Lasso,或最小绝对收缩和选择运算符,在精神上与岭回归非常相似。它还为损失函数添加了非零系数的惩罚,但与脊回归惩罚系数的平方和(所谓的 L2 惩罚)不同,LASSO 惩罚系数的绝对值之和(L1 惩罚)。因此,对于λ的高值,许多系数在 LASSO 下精确归零,这在岭回归中是从来没有的。
它们之间的另一个重要区别是它们如何处理要素之间的多重共线性问题。在岭回归中,相关变量的系数往往是相似的,而在 LASSO 中,其中一个变量通常为零,另一个变量被赋予整个影响。因此,如果有许多大约相同值的大参数,即当大多数预测因子真正影响反应时,岭回归预计会更好地工作。另一方面,当有少量重要参数且其他参数接*于零时,即只有少数几个预测值实际影响响应时,LASSO 预计会出现在顶部。
然而,实际上,人们并不知道这些参数的真实值。因此,岭回归和 LASSO 之间的选择可以基于样本外预测误差。另一种选择是将这两种方法结合起来——参见下一节!
LASSO 的损失函数如下所示:
与岭回归不同,这种最小化问题无法解析求解。幸运的是,有数值算法能够处理它。
弹性网
弹性网最早出现是由于对 LASSO 的批评,其变量选择可能过于依赖数据,因此不稳定。它的解决方案是结合岭回归和套索的惩罚,以获得两全其美。弹性网旨在最小化包含 L1 和 L2 惩罚的损失函数:
其中α是岭回归(当它为零时)和套索(当它为一时)之间的混合参数。最好的α可以通过 scikit-learn 基于交叉验证的超参数调整来选择。
最小角度回归
到目前为止,我们已经讨论了一个子集方法,最佳子集回归,和三个收缩方法:岭回归,套索,以及它们的组合,弹性网。本节专门介绍一种介于子集化和收缩之间的方法:最小角度回归(LAR)。该算法从零模型开始,所有系数等于零,然后迭代工作,在每一步将一个变量的系数移向其最小二乘值。
更具体地说,LAR 从识别与响应最相关的变量开始。然后,它将该变量的系数不断向其最小二乘值移动,从而降低其与演变残差的相关性。一旦另一个变量在与残差的相关性方面“赶上”,这个过程就暂停了。然后,第二个变量加入活动集,即具有非零系数的变量集,并且它们的系数以保持它们的相关性捆绑和递减的方式一起移动。这个过程一直持续到所有变量都在模型中,并在完全最小二乘拟合时结束。“最小角度回归”这个名称来自于该算法的几何解释,在该算法中,给定步骤的新拟合方向与已经具有非零系数的每个要素形成最小角度。
下面的代码块将 LAR 应用于前列腺数据。
主成分回归
我们已经讨论了选择变量(子集)和降低它们的系数(收缩)的方法。本文中介绍的最后两种方法采用了稍微不同的方法:它们将原始要素的输入空间压缩到一个更低维的空间中。主要是,他们使用 X 来创建一小组新特征 Z ,它们是 X 的线性组合,然后在回归模型中使用它们。
这两种方法中的第一种是主成分回归。它应用主成分分析,这是一种允许获得一组新特征的方法,这些新特征彼此不相关,并且具有高方差(以便它们可以解释目标的方差),然后在简单的线性回归中使用它们作为特征。这使得它类似于岭回归,因为两者都在原始特征的主成分空间上操作(对于岭回归的基于 PCA 的推导,参见本文底部来源中的[1])。不同之处在于,PCR 丢弃了信息量最少的成分,而岭回归只是将它们收缩得更强。
要保留的组件数量可以视为一个超参数,并通过交叉验证进行调整,如下面的代码块所示。
偏最小二乘法
本文讨论的最后一种方法是偏最小二乘法(PLS)。与主成分回归相似,它也使用原始特征的一小组线性组合。区别在于这些组合是如何构造的。主成分回归仅使用 X 自身来创建衍生特征 Z ,而偏最小二乘法额外使用目标 y 。因此,在构建 Z 时,PLS 寻找具有高方差(因为这些可以解释目标中的方差)和与目标高度相关的方向。这与仅关注高方差的主成分方法形成对比。
在该算法的保护下,第一个新特征 z1 被创建为所有特征 X 的线性组合,其中每个 X 被其与目标 y 的内积加权。然后, y 在 z1 上回归,给出 PLS β系数。最后,所有的 X 相对于 z1 正交化。然后,对于 z2 该过程重新开始,并且继续进行,直到在 Z 中获得期望数量的组件。像往常一样,这个数字可以通过交叉验证来选择。
可以看出,尽管 PLS 根据需要缩小了 Z 中的低方差分量,但它有时会放大高方差分量,这在某些情况下可能会导致更高的预测误差。这似乎是我们前列腺数据的情况:PLS 在所有讨论的方法中表现最差。
总结和结论
由于许多可能相关的要素,线性模型在预测准确性和模型的可解释性方面会因模型参数的巨大差异而失败。这可以通过减小方差来缓解,但这只能以引入一些偏差为代价。然而,找到最佳偏差-方差权衡可以优化模型的性能。
允许实现这一点的两大类方法是子集化和收缩。前者选择变量的子集,而后者将模型的系数向零收缩。这两种方法都降低了模型的复杂性,从而降低了参数方差。
本文讨论了几种子集化和收缩方法:
- 最佳子集回归迭代所有可能的特征组合,以选择最佳组合;
- 岭回归惩罚系数的平方值(L2 惩罚),迫使它们变小;
- 套索惩罚系数的绝对值(L1 惩罚),可以强制其中一些正好为零;
- 弹力网结合了 L1 和 L2 的点球,独享山脊和套索的精华;
- 最小角度回归介于子集化和收缩之间:它迭代工作,在每一步添加一个特征的“某个部分”;
- 主成分回归执行 PCA 以将原始特征压缩成新特征的小子集,然后使用那些作为预测器;
- 偏最小二乘法也将原始特征总结为新特征的一个更小的子集,但与 PCR 不同,它也利用目标来构建它们。
如果您运行上面的代码块,您将从前列腺数据的应用中看到,这些方法中的大多数在预测准确性方面表现相似。前 5 种方法的误差范围在 0.467 和 0.517 之间,优于最小二乘法的误差 0.523。最后两个,PCR 和 PLS,表现更差,可能是因为数据中没有那么多特征,因此降维的收益有限。
感谢阅读!我希望你已经学到了对你的项目有益的东西🚀
如果你喜欢这篇文章,试试我的另一篇文章。不能选择?从这些中选择一个:
[## 增强你对助推的把握
揭秘著名的竞赛获奖算法。
towardsdatascience.com](/boost-your-grasp-on-boosting-acf239694b1) [## 线性分类器:综述
本文讨论了四个流行的线性函数的数学性质和 Python 的实际应用
towardsdatascience.com](/linear-classifiers-an-overview-e121135bd3bb) [## 插补的不确定性
你在预测中考虑到它了吗?
towardsdatascience.com](/uncertainty-from-imputation-8dbb34a19612)
来源
- Hastie,Tibshirani,r .,,j . h . Friedman(2009 年)。统计学*的要素:数据挖掘、推理和预测。第二版。纽约:斯普林格。
- https://www . data camp . com/community/tutorials/tutorial-ridge-lasso-elastic-net
一个完整的数据科学团队需要的不仅仅是数据科学家
原文:https://towardsdatascience.com/a-complete-data-science-team-requires-more-than-just-data-scientists-195cdbbca538?source=collection_archive---------30-----------------------
Photo by Perry Grone on Unsplash
对于一个完整的数据科学团队来说,没有一个角色是最重要的,但有些角色比其他角色更容易让人想到。
这篇文章最初是在 TechHQ 上 发表 。增加了插图。
从初创公司到企业,从金融到医疗保健等行业的各种组织都在实现人工智能(AI)的好处。
事实上,根据 Gartner的数据,14%的全球首席信息官已经部署了人工智能,到 2020 年,48%的首席信息官将部署人工智能。然而,建立成功承担这些人工智能项目的必要团队比简单地雇佣数据科学家更复杂。
然而,许多组织在这种误解下运作。许多人没有看到,建立和执行成功、道德和有洞察力的人工智能解决方案需要一个全面的数据科学团队,而不仅仅是几个理想主义的数据科学家可以完成所有工作。
Photo by jeshoots.com on Unsplash
为了让人工智能提供商业价值,组织需要确定正确的业务用例。来自人工智能的预测性见解需要通过数据故事变得可消费,对人类行为的更深入理解对于正确的决策至关重要。
除了引入感知的“核心角色”,数据科学团队可能没有意识到他们需要数据翻译、 数据故事讲述者 甚至行为心理学家这样的角色来实现这些目标。
基本角色
在创建完整的数据科学团队时,没有一个角色比另一个角色更重要,这是有争议的。然而,有些角色会比其他角色更早浮现在脑海中。公司热衷于招聘的第一批职位之一是数据科学家,他们通常使用统计学和机器学*(ML)来分析和识别预测性见解。
沿着人工智能之旅前进的组织也将确定他们对可视化设计师的需求,该设计师应该具有信息设计和 UX 技能,以将数据洞察的视觉智能层带入生活。
机器学*(ML)工程师也在数据科学团队中发挥着关键作用,因为他们将 ML 模型打包成端到端的应用程序。他们利用深厚的编程技能和对数据处理的精通来实现整个工作流程的自动化。
Photo by Mitchell Luo on Unsplash
…团队没有意识到他们丢失了什么
除了数据科学团队中这些众所周知的角色之外,还有一些不为人知的角色,但也同样重要。公司应该认识到数据科学翻译的重要性。
他们通过识别可以通过数据解决的最有影响力的项目和业务挑战,充当业务用户和数据科学工程师之间的桥梁。事实上,麦肯锡 估计 到 2026 年,仅美国对翻译的需求就可能达到两到四百万。
引入行为心理学家可以帮助数据科学团队将模式解释为可操作的见解,从而推动决策并提供商业价值。行为心理学家了解人们行为的原因,并可以通过洞察购买决策或客户流失来帮助数据科学家。
例如,寻求预测服务器故障的公司只需查看过去的内存使用水平和服务器负载方面的性能。然而,将真实的人投入到混合中,数据驱动的方法需要由人的维度来补充。
Photo by Jesse Orrico on Unsplash
一家希望预测员工流失率的公司需要了解的不仅仅是员工的历史或表现。在这里,社会科学家将提供对人口统计、个人偏好、职业阶段和过去情绪反应等因素的见解,以提高预测的准确性。
最后,任何想要有效沟通数据洞察的背景和叙述的成长中的数据科学团队都需要一个数据故事讲述者。数据故事讲述者所做的不仅仅是创建可视化仪表板:他们从数据洞察中精心制作吸引人的叙述,即使是最不专业的团队成员也能理解。
数据故事讲述者的工作是帮助非数据科学家团队成员和高管通过迷人的数据故事理解见解,并帮助他们将其转化为业务决策。
事实上,谷歌首席经济学家甚至在十年前就准确预测了这些角色在数据科学团队中的重要性,当时 他说 “获取数据的能力——能够理解它、处理它、从中提取价值、可视化它、交流它——这将是未来几十年非常重要的技能。”
“获取数据的能力——能够理解它、处理它、从中提取价值、可视化它、交流它——将是未来几十年非常重要的技能。”—哈尔·瓦里安
建立一个全面的数据科学团队比许多组织意识到的要困难得多。随着他们向数据最终成为文化的环境发展,组织会发现对这些角色的需求越来越大。
然而,随着 技术技能危机 的持续,渴望沿着数据之旅前进并雇佣必要人才的团队的努力仍将受到阻碍。一旦这种技能差距被填补,组织就可以全速前进,采用人工智能,并收获它的许多回报。与此同时,准备好争夺人才和专业知识对于保持竞争优势至关重要。
想了解更多关于如何在数据科学领域取得成功的信息吗?以下是每个数据科学团队必须计划的 5 个核心&关键技能 。想要在公共场合展示你对数据的热情?这篇文章告诉你从哪里开始。****
文本数据的完整探索性数据分析和可视化
原文:https://towardsdatascience.com/a-complete-exploratory-data-analysis-and-visualization-for-text-data-29fb1b96fb6a?source=collection_archive---------3-----------------------
Photo credit: Pixabay
如何将可视化和自然语言处理结合起来,以一种直观的方式产生洞察力
可视化表示文本文档的内容是文本挖掘领域最重要的任务之一。作为一名数据科学家或 NLP 专家,我们不仅从不同的方面和不同的细节层次探索文档的内容,而且我们还总结单个文档,显示单词和主题,检测事件,并创建故事情节。
然而,在可视化非结构化(文本)数据和结构化数据之间存在一些差距。例如,许多文本可视化不直接表示文本,它们表示语言模型的输出(字数、字符长度、单词序列等)。).
在本帖中,我们将使用女装电子商务评论数据集,并使用 Plotly 的 Python 绘图库和散景可视化库,尽可能多地探索和可视化。我们不仅要探索文本数据,还要可视化数字和分类特征。我们开始吧!
数据
df = pd.read_csv('Womens Clothing E-Commerce Reviews.csv')
table 1
在对数据进行简单检查后,我们发现需要进行一系列的数据预处理。
- 删除“标题”功能。
- 删除缺少“审查文本”的行。
- 清理“审阅文本”列。
- 使用 TextBlob 计算情绪极性,该极性位于[-1,1]范围内,其中 1 表示积极情绪,-1 表示消极情绪。
- 为评论的长度创建新的特征。
- 为评论的字数创建新功能。
text_preprocessing.py
为了预览情感极性得分是否有效,我们随机选择了 5 条情感极性得分最高的评论(1):
print('5 random reviews with the highest positive sentiment polarity: \n')
cl = df.loc[df.polarity == 1, ['Review Text']].sample(5).values
for c in cl:
print(c[0])
Figure 1
然后随机选择 5 条最中性情感极性得分(零)的评论:
print('5 random reviews with the most neutral sentiment(zero) polarity: \n')
cl = df.loc[df.polarity == 0, ['Review Text']].sample(5).values
for c in cl:
print(c[0])
Figure 2
只有 2 篇评论的负面情绪极性得分最高:
print('2 reviews with the most negative polarity: \n')
cl = df.loc[df.polarity == -0.97500000000000009, ['Review Text']].sample(2).values
for c in cl:
print(c[0])
Figure 3
成功了!
Plotly 单变量可视化
单变量或单变量可视化是最简单的可视化类型,它仅由对单个特征或属性的观察组成。单变量可视化包括直方图、条形图和折线图。
评论情绪极性得分分布
df['polarity'].iplot(
kind='hist',
bins=50,
xTitle='polarity',
linecolor='black',
yTitle='count',
title='Sentiment Polarity Distribution')
Figure 4
绝大多数情感极性得分都大于零,这意味着它们中的大多数都非常积极。
评论等级的分布
df['Rating'].iplot(
kind='hist',
xTitle='rating',
linecolor='black',
yTitle='count',
title='Review Rating Distribution')
Figure 5
评级与极性得分一致,也就是说,大多数评级在 4 或 5 的范围内相当高。
审稿人年龄分布
df['Age'].iplot(
kind='hist',
bins=50,
xTitle='age',
linecolor='black',
yTitle='count',
title='Reviewers Age Distribution')
Figure 6
大多数评论者年龄在 30 到 40 岁之间。
分发检查文本长度
df['review_len'].iplot(
kind='hist',
bins=100,
xTitle='review length',
linecolor='black',
yTitle='count',
title='Review Text Length Distribution')
Figure 7
评论字数的分布
df['word_count'].iplot(
kind='hist',
bins=100,
xTitle='word count',
linecolor='black',
yTitle='count',
title='Review Text Word Count Distribution')
Figure 8
有相当多的人喜欢留下长篇评论。
对于分类特征,我们简单地使用条形图来表示频率。
分裂的分布
df.groupby('Division Name').count()['Clothing ID'].iplot(kind='bar', yTitle='Count', linecolor='black', opacity=0.8,
title='Bar chart of Division Name', xTitle='Division Name')
Figure 9
一般分部的评论数最多,Initmates 分部的评论数最少。
部门分布
df.groupby('Department Name').count()['Clothing ID'].sort_values(ascending=False).iplot(kind='bar', yTitle='Count', linecolor='black', opacity=0.8,
title='Bar chart of Department Name', xTitle='Department Name')
Figure 10
说到部门,Tops 部门的评论最多,Trend 部门的评论最少。
阶级的分布
df.groupby('Class Name').count()['Clothing ID'].sort_values(ascending=False).iplot(kind='bar', yTitle='Count', linecolor='black', opacity=0.8,
title='Bar chart of Class Name', xTitle='Class Name')
Figure 11
现在我们来看“评论文本”特征,在探索这个特征之前,我们需要提取 N-Gram 特征。N-gram用于描述作为观察点的词的数量,例如,unigram 表示单词,bigram 表示双词短语,trigram 表示三词短语。为了做到这一点,我们使用了 scikit-learn 的 [CountVectorizer](https://scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html)
函数。
首先,比较去掉停用词前后的 unigrams 会很有趣。
移除停用词前的顶级单字分布
top_unigram.py
Figure 12
去除停用词后的顶级单字分布
top_unigram_no_stopwords.py
Figure 13
第二,我们想比较去除停用词前后的二元模型。
去除停用词前的顶级二元模型分布
top_bigram.py
Figure 14
去除停用词后的顶级二元模型分布
top_bigram_no_stopwords.py
Figure 15
最后,我们比较去除停用词前后的三元模型。
去除停用词前的顶级三元组分布
top_trigram.py
Figure 16
去除停用词后的顶三元模型分布
top_trigram_no_stopwords.py
Figure 17
【词性标注】是给每个词分配词性的过程,如名词、动词、形容词等
我们使用一个简单的Text blobAPI 来深入到我们的数据集中的“查看文本”特征的位置,并可视化这些标签。
评论语料库顶级词性标签分布
POS.py
Figure 18
箱线图用于比较电子商务商店的每个部门或分部的情感极性得分、评级、评论文本长度。
这些部门对情绪极性有什么看法
department_polarity.py
Figure 19
除了趋势部门之外,所有六个部门都获得了最高的情绪极性得分,而 Tops 部门收集了最低的情绪极性得分。而趋势部极性得分中值最低。如果你记得的话,潮流系的评论数量最少。这解释了为什么它不像其他部门那样有各种各样的分数分布。
各部门对评级有什么看法
rating_division.py
Figure 20
除了趋势部,其他部门的中值都是 5 分。总的来说,在这个评论数据集中,评分很高,情绪也很积极。
按部门审查长度
length_department.py
Figure 21
Tops 和 immune 部门的审查长度中位数相对低于其他部门。
用 Plotly 实现二元可视化
二元可视化是一种一次包含两个特征的可视化。它描述了两个特征之间的关联或关系。
推荐的情感极性得分分布
polarity_recommendation.py
Figure 22
显然,具有较高极性分数的评论更有可能被推荐。
按建议的评级分布
rating_recommendation.py
Figure 23
推荐的评论比不推荐的评论有更高的评级。
按建议分配审查长度
review_length_recommend.py
Figure 24
推荐评论往往比非推荐评论更长。
情感极性与评分的 2D 密度联合图
sentiment_polarity_rating.py
Figure 24
2D 密度年龄与情感极性交汇图
age_polarity.py
Figure 25
很少有人非常积极或非常消极。给予中性到正面评价的人更有可能是 30 多岁。这些年龄的人可能更活跃。
寻找特征术语及其关联
有时,我们希望分析不同类别使用的单词,并输出一些显著的术语关联。我们将使用分散文本和空间库来完成这些。
首先,我们需要将数据框架转换成一个分散文本语料库。要查找部门名称的差异,请将category_col
参数设置为'Department Names'
,并使用Review Text
列中的查看,通过设置text
列参数进行分析。最后,向nlp
参数传递一个空间模型,并调用build()
来构建语料库。
以下是区别评论文本和一般英语语料库的术语。
*corpus = st.CorpusFromPandas(df, category_col='Department Name', text_col='Review Text', nlp=nlp).build()
print(list(corpus.get_scaled_f_scores_vs_background().index[:10]))*
Figure 26
以下是审查文本中与 Tops 部门最相关的术语:
*term_freq_df = corpus.get_term_freq_df()
term_freq_df['Tops Score'] = corpus.get_scaled_f_scores('Tops')
pprint(list(term_freq_df.sort_values(by='Tops Score', ascending=False).index[:10]))*
Figure 27
以下是与服装部门联系最紧密的术语:
*term_freq_df['Dresses Score'] = corpus.get_scaled_f_scores('Dresses')
pprint(list(term_freq_df.sort_values(by='Dresses Score', ascending=False).index[:10]))*
Figure 28
主题建模评论文本
最后,我们希望探索这个数据集的主题建模算法,看看它是否会提供任何好处,以及是否适合我们正在为我们的评论文本功能所做的工作。
我们将在主题建模中试验潜在语义分析(LSA)技术。
- 将我们的文档术语矩阵从评论文本生成为一个包含 TF-IDF 特性的矩阵。
- LSA 模型用 TF-IDF 得分替换文档术语矩阵中的原始计数。
- 使用截断奇异值分解对文档术语矩阵进行降维。
- 因为部门的数量是 6,所以我们设置
n_topics=6
。 - 取该主题矩阵中每个评论文本的
argmax
,将给出数据中每个评论文本的预测主题。然后我们可以将这些分类成每个主题的数量。 - 为了更好的理解每个题目,我们会找到每个题目中出现频率最高的三个词。
topic_model_LSA.py
Figure 29
*top_3_words = get_top_n_words(3, lsa_keys, document_term_matrix, tfidf_vectorizer)
labels = ['Topic {}: \n'.format(i) + top_3_words[i] for i in lsa_categories]fig, ax = plt.subplots(figsize=(16,8))
ax.bar(lsa_categories, lsa_counts);
ax.set_xticks(lsa_categories);
ax.set_xticklabels(labels);
ax.set_ylabel('Number of review text');
ax.set_title('LSA topic counts');
plt.show();*
Figure 30
通过查看每个主题中最常用的词,我们有一种感觉,我们可能无法在主题类别之间达到任何程度的分离。换句话说,我们不能使用主题建模技术按部门分离评论文本。
主题建模技术有许多重要的局限性。首先,“主题”这个术语有些模糊,到目前为止,很明显主题模型不会为我们的数据产生高度细微的文本分类。
此外,我们可以观察到绝大多数的复*文本都被归类到第一个主题(主题 0)。LSA 主题建模的 t-SNE 可视化效果不会很好。
所有的代码都可以在 Jupyter 笔记本上找到。代码和交互式可视化可以在的 NBC viewer上查看。
周一快乐!
使用 Python 的交互式地理地图完整指南
原文:https://towardsdatascience.com/a-complete-guide-to-an-interactive-geographical-map-using-python-f4c5197e23e0?source=collection_archive---------2-----------------------
有没有想过这些美丽的地理地图是如何制作的?我们的数据世界收集了大量关于健康、人口增长、教育、文化、暴力、政治权力、技术和我们关心的几个方面的交互式数据可视化。这些可视化帮助我们理解过去几十年世界是如何以及为什么发生变化的。我对这些丰富的信息很感兴趣,并激发了我更深入的探索。
一次快速的谷歌搜索让我找到了 choropleth 地图。地图显示与数据变量相关的彩色、阴影或图案化的划分的地理区域。地理区域可能覆盖整个世界,或者一个国家,州,甚至一个县。有许多工具和软件包可以使用 Python 制作独立的或静态的地图。然而,创建一个动态地图有点棘手,这正是我们将在这个博客中学*的内容。在这个循序渐进的指南中,我们将使用 Python 库和包在 肥胖成人的比例(1975-2016 年) 上重新创建一个交互式全球合唱团地图-熊猫、地球熊猫和 Bokeh 。
在第一部分,我们将创建一个静态地图,然后在代码的基础上引入交互性。
把密码给我
整个代码也可以在我的github.com找到。
下载和安装
要渲染世界地图,我们需要一个带有世界坐标的 shapefile。 Natural Earth 是一个公共领域地图数据集,提供各种分辨率的地理空间数据。对于我们的目的来说,1–110m 小规模数据已经足够好了。点击绿色按钮 下载国家 4.1.0 版 下载 shape 文件夹。接下来,进入我们的数据世界,点击图表上的数据选项卡,下载定义为肥胖的成年人份额. csv。或者,也可以从我的 github 库下载文件。安装 Geopandas 和 Bokeh。
探索熊猫和地理熊猫数据框
导入 geopandas。Geopandas 可以使用返回地理数据框架对象的read_file
命令读取几乎任何基于矢量的空间数据格式,包括 ESRI shapefile。shapefile 由许多列组成,其中只有 3 列是我们感兴趣的。为了便于参考,对列进行了重命名。
import geopandas as gpdshapefile = 'data/countries_110m/ne_110m_admin_0_countries.shp'*#Read shapefile using Geopandas* gdf = gpd.read_file(shapefile)[['ADMIN', 'ADM0_A3', 'geometry']]*#Rename columns.*
gdf.columns = ['country', 'country_code', 'geometry']
gdf.head()
Geopandas GeoDataFrame
我们可以删除“南极洲”这一行,因为它在我们的地图上不必要地占据了很大的空间,在我们当前的分析中也不需要。
print(gdf[gdf['country'] == 'Antarctica'])#*Drop row corresponding to 'Antarctica'* gdf = gdf.drop(gdf.index[159])
接下来,我们进口熊猫并阅读。csv 文件。
import pandas as pddatafile = 'data/obesity.csv'*#Read csv file using pandas*
df = pd.read_csv(datafile, names = ['entity', 'code', 'year', 'per_cent_obesity'], skiprows = 1)df.head()
Pandas DataFrame
df.info()
df[df['code'].isnull()
Investigating missing values in df
调查熊猫数据框架显示苏丹缺失值。我们的数据跨度从 1975 年到 2016 年;而苏丹在 2011 年 7 月分裂成两个国家。这导致了新分裂国家的 3 个字母的 ISO 代码的变化。为了简单起见,让我们忽略苏丹缺失的数据。
2016 年静态 choropleth 地图
让我们首先创建一个表示 2016 年成人肥胖比例的静态地图。这需要从 df 中过滤 2016 年的数据。然后,可以将生成的数据框架 df_2016 合并到地理数据框架 gdf 中。
*#Filter data for year 2016.*
df_2016 = df[df['year'] == 2016]*#Merge dataframes gdf and df_2016.*
merged = gdf.merge(df_2016, left_on = 'country_code', right_on = 'code')
合并后的文件是一个 GeoDataframe 对象,可以使用 geopandas 模块进行渲染。然而,由于我们想加入数据可视化的交互性,我们将使用散景库。散景使用 GeoJSON 格式,用 JSON 表示地理要素。GeoJSON 将点、线和多边形(在散景中称为面片)描述为要素的集合。因此,我们将合并后的文件转换为 GeoJSON 格式。
import json#*Read data to json.*
merged_json = json.loads(merged.to_json())#*Convert to String like object.*
json_data = json.dumps(merged_json)
我们现在准备使用散景渲染我们的 choropleth 地图。导入所需的模块。代码是内联描述的。
from bokeh.io import output_notebook, show, output_file
from bokeh.plotting import figure
from bokeh.models import GeoJSONDataSource, LinearColorMapper, ColorBar
from bokeh.palettes import brewer*#Input GeoJSON source that contains features for plotting.*
geosource = GeoJSONDataSource(geojson = json_data)*#Define a sequential multi-hue color palette.*
palette = brewer['YlGnBu'][8]*#Reverse color order so that dark blue is highest obesity.*
palette = palette[::-1]*#Instantiate LinearColorMapper that linearly maps numbers in a range, into a sequence of colors.*
color_mapper = LinearColorMapper(palette = palette, low = 0, high = 40)*#Define custom tick labels for color bar.*
tick_labels = {'0': '0%', '5': '5%', '10':'10%', '15':'15%', '20':'20%', '25':'25%', '30':'30%','35':'35%', '40': '>40%'}*#Create color bar.*
color_bar = ColorBar(color_mapper=color_mapper, label_standoff=8,width = 500, height = 20,
border_line_color=None,location = (0,0), orientation = 'horizontal', major_label_overrides = tick_labels)*#Create figure object.*
p = figure(title = 'Share of adults who are obese, 2016', plot_height = 600 , plot_width = 950, toolbar_location = None)
p.xgrid.grid_line_color = None
p.ygrid.grid_line_color = None*#Add patch renderer to figure.*
p.patches('xs','ys', source = geosource,fill_color = {'field' :'per_cent_obesity', 'transform' : color_mapper},
line_color = 'black', line_width = 0.25, fill_alpha = 1)*#Specify figure layout.*
p.add_layout(color_bar, 'below')*#Display figure inline in Jupyter Notebook.*
output_notebook()*#Display figure.*
show(p)
酷!我们的 choropleth 地图已经生成。你可能在这张地图上发现了一个问题。非洲大陆看起来支离破碎;那是因为苏丹、南苏丹、索马里兰不见了。还有,格陵兰在世界地图上不见了。没有画出这些国家的原因是我们的中缺少一个或多个对应于这些国家的值。csv 文件,因此,数据帧 df。让我们解决这个问题,因为它会让一些人反感,这是理所当然的!
更正缺失的国家
我们可以确保缺失的国家被绘制在地图上,并用浅灰色填充,表示缺失的数据。这需要在我们之前的代码中进行一些编辑。
为了保留合并数据框中缺失的国家,我们执行了左合并/左外连接。因此,地理数据框架 gdf 中的每个国家都会保留在合并的数据框架中,即使熊猫数据框架 df 中缺少相应的行。
df_2016 = df[df['year'] == 2016]*#Perform left merge to preserve every row in gdf.*
merged = gdf.merge(df_yr, left_on = 'country_code', right_on = 'code', how = 'left')
这导致了下图。
Choropleth map for year 2016 (after left merge)
所以现在我们在地图上看到了之前缺失的国家,但是还有一个问题。新添加的国家按照我们的颜色映射器中的定义进行颜色编码,表示肥胖率在 0–5%的范围内。这具有误导性,因为实际上这些数据是缺失的。理想情况下,我们希望这些国家以中性色显示,如浅灰色,表示缺少数据。我们如何才能做到这一点?
左合并导致在合并的数据帧中为右数据帧中相应的缺失值添加 NaN 值(df_2016)。当我们将这个合并的数据帧转换成 GeoJSON 格式时,问题就出现了,因为 NaN 不是一个有效的 JSON 对象。为了避免这种情况,我们将把合并数据帧中的所有 NaN 值替换为字符串“No data”。
df_2016 = df[df['year'] == 2016]*#Perform left merge to preserve every row in gdf.*
merged = gdf.merge(df_2016, left_on = 'country_code', right_on = 'code', how = 'left')*#Replace NaN values to string 'No data'.*
merged.fillna('No data', inplace = True)
我们还将十六进制代码输入到带有“无数据”的颜色代码国家,作为颜色映射器的参数。
*#Instantiate LinearColorMapper that maps numbers in a range linearly into a sequence of colors. Input nan_color.*color_mapper = LinearColorMapper(palette = palette, low = 0, high = 40, nan_color = '#d9d9d9')
Choropleth map for year 2016 (after left merge and replacing NaNs)
太好了!我对我们 2016 年的 choropleth 地图很满意。是时候增加一些互动性了。
在我们的可视化中增加交互性使用户能够提取他们感兴趣的信息。我们的目标是创建一个动态地图,根据 1975-2016 年间选择的年份更新数据。我们还将添加一个悬停工具,允许用户只需将鼠标悬停在特定国家/地区上方即可查看详细信息。
Bokeh 提供了大量的小部件和工具,使得创建丰富的交互式可视化变得非常简单。我们将定义一些函数,并重用为创建静态地图而编写的大部分代码。代码是内联描述的。
from bokeh.io import curdoc, output_notebook
from bokeh.models import Slider, HoverTool
from bokeh.layouts import widgetbox, row, column*#Define function that returns json_data for year selected by user.*
def json_data(selectedYear):
yr = selectedYear
df_yr = df[df['year'] == yr]
merged = gdf.merge(df_yr, left_on = 'country_code', right_on = 'code', how = 'left')
merged.fillna('No data', inplace = True)
merged_json = json.loads(merged.to_json())
json_data = json.dumps(merged_json)
return json_data*#Input GeoJSON source that contains features for plotting.*
geosource = GeoJSONDataSource(geojson = json_data(2016))*#Define a sequential multi-hue color palette.*
palette = brewer['YlGnBu'][8]*#Reverse color order so that dark blue is highest obesity.*
palette = palette[::-1]*#Instantiate LinearColorMapper that linearly maps numbers in a range, into a sequence of colors. Input nan_color.*
color_mapper = LinearColorMapper(palette = palette, low = 0, high = 40, nan_color = '#d9d9d9')*#Define custom tick labels for color bar.*
tick_labels = {'0': '0%', '5': '5%', '10':'10%', '15':'15%', '20':'20%', '25':'25%', '30':'30%','35':'35%', '40': '>40%'}*#Add hover tool*
hover = HoverTool(tooltips = [ ('Country/region','[@country](http://twitter.com/country)'),('% obesity', '@per_cent_obesity')])*#Create color bar.*
color_bar = ColorBar(color_mapper=color_mapper, label_standoff=8,width = 500, height = 20,
border_line_color=None,location = (0,0), orientation = 'horizontal', major_label_overrides = tick_labels)*#Create figure object.*
p = figure(title = 'Share of adults who are obese, 2016', plot_height = 600 , plot_width = 950, toolbar_location = None, tools = [hover])
p.xgrid.grid_line_color = None
p.ygrid.grid_line_color = None*#Add patch renderer to figure.*
p.patches('xs','ys', source = geosource,fill_color = {'field' :'per_cent_obesity', 'transform' : color_mapper},
line_color = 'black', line_width = 0.25, fill_alpha = 1)*#Specify layout*
p.add_layout(color_bar, 'below')*# Define the callback function: update_plot*def update_plot(attr, old, new):
yr = slider.value
new_data = json_data(yr)
geosource.geojson = new_data
p.title.text = 'Share of adults who are obese, %d' %yr
*# Make a slider object: slider*
slider = Slider(title = 'Year',start = 1975, end = 2016, step = 1, value = 2016)
slider.on_change('value', update_plot)*# Make a column layout of widgetbox(slider) and plot, and add it to the current document*
layout = column(p,widgetbox(slider))
curdoc().add_root(layout)*#Display plot inline in Jupyter notebook*
output_notebook()*#Display plot*
show(layout)
厉害!我们已经成功地为肥胖的成年人重新创建了交互式 choropleth 地图。请注意,当您更改 Jupyter 笔记本中的滑块值时,图不会更新。要以交互模式查看此应用程序,您需要设置一个本地散景服务器。在当前目录下打开命令行窗口,执行bokeh serve --show filename.ipynb
命令。
Setting up local Bokeh server
单击提示的链接,在浏览器中打开应用程序。我已经插入了一个简短的剪辑,显示了互动模式的应用程序。
World obesity Interactive Choropleth map
在数据中的我们的世界的原始地图上有一些很酷的特征,我无法合并;就像悬停时高亮显示一个国家,悬停在颜色栏上的某个部分时高亮显示所有国家一样。我也搞不清楚与颜色条并列的“无数据”的“浅灰色”段的显示。如果您对我们如何进一步增强应用程序的交互性有任何意见或建议,我很乐意倾听!
KPI 仪表板完整指南
原文:https://towardsdatascience.com/a-complete-guide-to-kpi-dashboard-1cf22484a6eb?source=collection_archive---------21-----------------------
1.为什么我们需要 KPI 仪表板?
你有没有开车时不看仪表盘,不检查油位、温度、速度表或任何指示器的经历?对一些人来说,他们甚至检查他们的轮胎、侧镜和危险灯。仅仅开车而不检查仪表板意味着你将自己暴露在更高的风险水平中。如果您的业务不使用 KPI 仪表板,情况也是如此。
就像驾驶汽车一样,管理企业也需要企业所有者了解他/她的关键数据,以便做出更好的商业决策。在不知道数据的情况下,仅仅根据情绪或他/她的直觉做出决定。
今天,让我们从简单的 KPI 仪表板开始,以便更好地了解您的业务。我相信您能够看到了解您的业务关键成果领域中的关键数据的好处。
2.KPI 仪表板的类型
KPI 仪表板有多种类型。一个公司几乎所有的岗位都有 KPI 要求。但是不同岗位的 KPI 规则不一样,无法统一管理。此时,KPI 仪表盘可以轻松解决管理困境,查看不同岗位的 KPI 完成情况。
以下是一些简单的例子:
#营销:
特定销售线索来源的销售线索数量
渠道合作伙伴数量
营销活动的数量
Marketing dashboard made with FineReport
#销售:
转化率
商业交易的价值
已登记销售额
Sales dashboard made with FineReport
#操作:
交付的产品数量
交付产品的价值
退回/拒绝的产品数量
收到的投诉数量
KPI dashboard made with Tableau
#财经:
每月开具的发票数量
每月开具发票的平均值
每月收到的付款额
每月支付的金额
Finance dashboard made with FineReport
#HR:
培训天数
休年假的次数
接受的 MC 数
HR dashboard made with FineReport
因此,在扩展到更详细、更大的业务范围之前,先从一个简单的 KPI 仪表板开始。它将帮助您更好地了解关键业务的运营。
3.制作 KPI 仪表板的技巧
为了制作 KPI 仪表板,您需要选择一个易于使用的数据可视化工具。每种工具都有其优点和缺点。你可以阅读这篇文章2019 年你不能错过的 9 款数据可视化工具 了解一下哪些工具适合你。
这里我以可视化工具 FineReport 为例,向大家展示制作 KPI 仪表盘的基本步骤。FineReport 对没有技术基础的人比较友好。您可以通过简单的拖放操作创建各种图表。
- 首先,我们准备 KPI 的数据,并将其导入到 FineReport Designer 中。FineReport 可以连接各种数据库。
- 设计布局。布局的目的是合理呈现关键绩效指标和数据。有主次指标。一级指标反映的是核心业务,二级指标用于进一步细化,所以在设计布局时赋予了不同的权重。以下是常见布局的示例。
Made with FineReport
- 使用条件格式和公式显示图标。FineReport 支持自定义公式来确定数据是否符合标准。例如,我们可以通过 KPI 公式计算每个员工的 KPI 值。大于规定值为优秀,否则为不合格。
- 选择图表类型。关键指标确定后,我们需要确定指标的分析维度。我们常见的分析方法有类比、趋势、分布、构成等。不同的分析方法有不同的图表类型。
- 添加动态效果。动态效果使 KPI 仪表板更具吸引力。但是我们需要注意动态设计的比例,避免过多的动态。KPI 仪表板的常见动态效果如下。
Made with FineReport
Made with FineReport
关于制作 KPI 仪表盘更详细的教程,可以参考本文 制作销售仪表盘的一步一步指南 。
结论
KPI dashboard 可以通过各种指标的可视化展示,帮助业务人员做出更好的决策。无论是流程管理还是指标查询,KPI 仪表盘都会大大提高效率,减少不必要的沟通时间。
您可能也会对…感兴趣
新手如何打造一个很棒的仪表盘?
KPI 仪表板的前 7 种图表类型
让你的数据报告脱颖而出的指南
2019 年 6 大数据分析工具
初学者财务报表分析指南
学* R 的完全指南
原文:https://towardsdatascience.com/a-complete-guide-to-learn-r-29e691c61d1?source=collection_archive---------6-----------------------
r 编程技术是一种开源编程语言。还有,R 编程语言是最新的尖端工具。r 基础是最热的趋势。此外,R 命令行界面(C.L.I)由一个提示符组成,通常是>字符。
R 的历史
约翰·钱伯斯和他的同事在贝尔实验室开发了 R。基本上,R 编程语言是 S 编程语言的实现。还结合了受 Scheme 启发的词法范围语义。虽然,R 部分是以两位 R 编程语言作者的名字命名的。此外,该项目始于 1992 年,1995 年发布了初始版本,2000 年发布了稳定的测试版本。
安装 R 编程语言& R Studio
在本 R 教程中,我们将介绍 R 编程和 R Studio 的安装:
为了在你的系统上运行 R 编程语言和 R Studio,我们必须按照同样的顺序遵循三个基本步骤。
- r 安装
- R Studio 的安装
- 安装 R 包。
a.如何安装 R 编程语言?
对于我们使用的操作系统,我们必须遵循以下步骤:
- 对于 Mac
首先,我们必须下载适当版本的。pkg 文件形成以下链接。
进一步,打开下载的。pkg 文件并安装 r。
- 对于 Linux
对于安装了 Apt-get 的 Ubuntu,在终端中执行 sudo apt-get install r-base。
- 对于 Windows
从下面的链接下载 R 的二进制安装文件。
打开下载的。exe 文件并安装 r。
b.如何安装 R Studio?
为您的操作系统选择合适的安装程序文件。然后,下载并运行它来安装 R-studio。
c.如何安装 R 包?
如果我们需要使用 R studio,我们需要安装一个特定的包。此外,请遵循以下说明:
润 R 工作室
然后,我们需要单击右下部分的 packages 选项卡。完成后,点击安装。因此,对话框将会出现。
在安装包对话框中,写下你要安装包的包名字段。然后单击安装。这将安装您搜索的软件包。要么根据您的包文本给出匹配包的列表。
这样,R Studio 的安装过程。
为什么要用 R 编程语言?
在这篇 R 教程中,以下几点描述了学* R 编程的原因。
- 我们使用 R 编程作为机器学*,统计和数据分析的主要工具。对象、函数和包很容易由 r .创建,因为它在任何地方都可以使用。此外,它是独立于平台和免费的。因此,任何人都可以在任何组织中安装它,而无需购买许可证。此外,它可以应用于所有操作系统。
- r 编程语言不仅仅是一个统计包。另外,R 允许我们与其他语言(C,C++)集成。因此,您可以轻松地与许多数据源和统计包进行交互。因此,R 编程语言拥有一个庞大且不断增长的用户群体。
r 代表商业
r 最适合商业,因为它是开源的。此外,它对可视化也很有帮助。此外,与早期的工具相比,R 编程语言有更多的功能。还有,公司正在使用 R 编程作为他们的平台,并招募训练有素的 R 用户。
R 编程语言的特点
以下是一些 R 特性:
a.R 程序设计语言的统计特征
- 基本统计学:均值,方差,中位数。
- 静态图形:基本绘图,图形地图。
- 概率分布:贝塔,二项式。
b.R 的编程特点
- 分布式程序设计
- r 包
R 为什么受欢迎?
- 如今,R 编程语言被认为是世界上流行的分析工具。此外,一些用户的估计范围从 25 万到超过 200 万。
- 基本上,R 编程语言再次成为大多数调查的首选。因为 R 拥有比任何其他工具都多的博客、讨论组和电子邮件列表,包括 SAS 编程。
R 编程语言中的工作角色
基本上,R 工作不仅仅是由 IT 公司提供的。尽管所有类型的公司都在高薪招聘 R 候选人,包括-
- 金融公司
- 零售组织
- 银行
- 医疗保健组织等。
基本上,正如我们所知,初创企业对研发工作有巨大的需求。此外,公司有几个不同职位的 R 职位空缺,如:
- r 数据科学家
- 数据科学家(IT)
- 分析师经理
- 高级数据分析师
- 商业分析员
- 分析顾问
使用 R 编程语言的公司
r 已经成为全世界数据科学家和统计学家的首选工具。此外,为了预测产品的价格等,公司正在使用分析。下面列出了一些使用 R 的公司:
- TechCrunch
- 谷歌
- 脸谱网
- Genpact
- 堆
- Orbitz
- ANZ
- 《纽约时报》
- 托马斯·库克
- 埃森哲
- Wipro
- 浏览器名
- 诺华公司
- 默克公司
“R 慢慢赢得了很多大企业的心”。 顶级公司为什么用 R
R 统计语言的工作机会
基本上,被行业重视的技能表现出缺乏理解。r 编程语言是一种工具,人可以在工具中训练。然而,在统计学、数据挖掘和数据分析等方面培训人才是困难的。所以印度的研发专家有非常好的工作机会。
r 职业
很明显!r 是最好的选择,因为它的趋势如此之大。此外,R 编程语言正被各地的大公司和小公司所使用。它也用于非 It 领域、政府和非政府公司。
R 编程的未来范围
未来的范围是非常光明的。因为 R 编程语言是当今的趋势。此外,对于那些不熟悉 R 编程语言的人来说,学*起来也很简单。
而且 R 编程最*的平均工资是最好的所以你可以想想以后会达到多高。
R 工作的来源
您可以在以下工作门户网站查看各种 R 技术工作:
- naukri.com
- indeed.com
- 商务化人际关系网
r 应用
- 基本上,R 是最流行的语言。因此,许多数据分析师和研究程序员使用它。因此,R 被用作金融的基本工具。
- 基本上,R 被许多定量分析师用作其编程工具。因此,R 有助于数据导入和清理。
- 我们用 R 代表数据科学。它给了我们各种各样的统计数据。此外,R 提供了统计计算和设计的环境。R 认为这是 s 的另一种执行方式。
R 的优点和缺点
a.R 编程语言的优势
- 基本上,R 是最全面的统计分析包。因为新技术和新想法往往首先出现在研发领域。
- 基本上,R 编程语言是开源软件。因此任何人都可以使用和改变它。
- 因为 R 编程语言是开源的。因此,我们可以在任何地方、任何时间运行 R,甚至在许可的条件下出售它。
- 基本上 R 编程语言对于 GNU/Linux 和微软 Windows 都是不错的。另外,R 编程是跨平台的,可以在许多操作系统上运行。
- 在 R 中,任何人都可以提供错误修复、代码增强和新的包。
b.R 编程语言的缺点
- 在 R 编程语言中,一些包的质量并不完美。
- 在 R 基本上,没有人抱怨如果一些东西不工作。
- 基本上,R 是许多人投入自己的时间开发的软件应用程序。
- 虽然,R 命令很少考虑内存管理。所以 R 编程语言会消耗所有可用内存。
最佳 R 书
以下是学* R 编程语言的最佳书籍。
a .加勒特·格罗勒蒙德的 R 编程手册
一般来说,如果你是 R 的新手,那么这是最适合你的书。因为这本书的语言非常简单易懂,例子也很容易复制。
诺曼·马特洛夫的《R 编程的艺术》
基本上,这本书讲述了如何做软件开发。从基本类型和数据结构到高级主题。也不需要统计学知识。此外,你的编程技能可以从业余爱好者到专业人士。
c . Trevor Hastie 和 Rob Tibshirani 编写的《统计学*及其在 R 中的应用》一书
即使你没有 R 的知识,这本书也是最好的。因为它有助于从理论和实践上理解许多重要的课题。
比如——机器学*和统计技术。
d . Mark P . j . van der Loo 为 R 统计计算学* R studio
基本上,这本书是为 R 开发人员和分析师设计的。此外,仅适用于那些希望使用 RStudio 功能进行 R 统计开发的人。因此,人们可以创建和管理统计分析项目,生成报告和图形。
妮娜·祖梅尔著《实用数据科学》
基本上,在本书中,作者只关注数据科学方法及其在现实世界中的应用。
哈德利·威克姆的《高级 R》
基本上,这本书是关于 R 语言是如何在三大分析工具之间创造差异的——R vs SAS vs SPSS。
哈雷·威克姆的通用汽车包装
基本上,这本书是为寻求编写自己的 R 包的高级 R 程序员而写的。因为作者已经写了关于 R 包的文档。此外,还解释了 R 包的组件,包括单元测试和简介。
希望你喜欢我们的解释。
结论
我希望这个博客能帮助你以一种非常先进的方式学*。此外,如果你对 R 教程有任何疑问,欢迎在评论区提问。
主成分分析完全指南—机器学*中的 PCA
原文:https://towardsdatascience.com/a-complete-guide-to-principal-component-analysis-pca-in-machine-learning-664f34fc3e5a?source=collection_archive---------1-----------------------
使用 python 和示例逐步解释 PCA
主成分分析(PCA)是一种广泛用于大型数据集降维的技术。减少组件或特征的数量会损失一些准确性,另一方面,它会使大型数据集更简单,更容易探索和可视化。此外,它降低了模型的计算复杂度,使得机器学*算法运行更快。为了获得不太复杂和降维的数据集,牺牲了多少精度,这一直是一个问题,也是有争议的。我们对此没有固定的答案,但是在选择最终的组件时,我们会尽量保持最大的差异。
在本文中,我们将讨论使用 PCA 实现降维的一步一步的方法,然后我还将展示我们如何使用 python 库来实现这一切。
PCA 中涉及的步骤
- 将数据标准化。(均值=0,方差= 1)
- 计算维度的协方差矩阵。
- 从协方差矩阵中获得特征向量和特征值(我们也可以使用相关矩阵或者甚至单值分解,然而在这篇文章中我们将关注协方差矩阵)。
- 对特征值进行降序排序,选择 k 个最大特征值对应的前 k 个特征向量(k 将成为新特征子空间的维数 k≤d,d 为原维数)。
- 从选择的 k 个特征向量中构造投影矩阵 W。
- 通过 W 变换原始数据集 X,得到新的 k 维特征子空间 y。
让我们导入一些需要的库和 Iris 数据集,我将用它们来详细解释每一点。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import standardScaler
%matplotlib inlinedf = pd.read_csv( filepath_or_buffer='https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data', header=None, sep=',') df.columns=['sepal_len', 'sepal_wid', 'petal_len', 'petal_wid', 'class'] print(df.isnull().values.any()) df.dropna(how="all", inplace=True) # drops the empty line at file-end #if inplace = False then we have to assign back to dataframe as it is a copy #df = df.some_operation(inplace=False) #No need to assign back to dataframe when inplace = True #df.some_operation(inplace=True) #Print Last five rows. df.tail()
将 y 数组中的类列值和 X 数组变量中的独立特征的其余值分开,如下所示。
X = df.iloc[:,0:4].values
y = df.iloc[:,4].values
Iris 数据集现在以 150×4 矩阵的形式存储,其中列是不同的特征,每行代表一个单独的花样本。每个样本行 x 可以被描绘成一个四维向量,正如我们在上面 x 输出值的屏幕截图中看到的那样。
现在让我们详细了解每一点。
1.标准化
当有不同的尺度用于特征值的测量时,建议进行标准化,以使所有特征空间的均值= 0,方差= 1。
在执行 PCA 之前非常需要标准化的原因是 PCA 对方差非常敏感。也就是说,如果要素的等级(范围)之间存在较大差异,那么等级较大的要素将优于等级较小的要素。
例如,范围在 0 到 100 之间的特征将优先于范围在 0 到 1 之间的特征,这将导致有偏差的结果。因此,将数据转换到相同的比例可以避免这个问题。这就是我们使用标准化来获得平均值为 0、方差为 1 的特征的地方。
下面是计算要素标准化值的公式:
在本文中,我使用的是 Iris 数据集。尽管 Iris 数据集中的所有特征都是以厘米为单位进行测量的,但我仍然会继续将数据转换到单位尺度上(均值=0,方差=1),这是许多机器学*算法实现最佳性能的一个要求。此外,它将帮助我们理解这个过程是如何工作的。
from sklearn.preprocessing import StandardScaler
X_std = StandardScaler().fit_transform(X)
在下面的输出截图中,您可以看到所有的 X_std 值都在-1 到+1 的范围内进行了标准化。
2.特征分解—计算特征向量和特征值
协方差(或相关)矩阵的特征向量和特征值代表 PCA 的“核心”:
- 特征向量(主分量)决定了新特征空间的方向,特征值决定了它们的大小。
- 换句话说,特征值解释了数据沿新特征轴的变化。这意味着相应的特征值告诉我们,新的变换特征中包含了多少方差。
- 为了得到特征值和特征向量,我们需要计算协方差矩阵。所以下一步我们来计算一下。
2.1 协方差矩阵
PCA 的经典方法是对协方差矩阵σ执行特征分解,它是一个 d×d 矩阵,其中每个元素表示两个特征之间的协方差。注意,d 是数据集的原始维数。在 Iris 数据集中,我们有 4 个特征,因此协方差矩阵的数量级为 4×4。
#mean_vec = np.mean(X_std, axis=0)
#cov_mat = (X_std - mean_vec).T.dot((X_std - mean_vec)) / (X_std.shape[0]-1)
#print('Covariance matrix \n%s' %cov_mat)
print('Covariance matrix \n')
cov_mat= np.cov(X_std, rowvar=False)
cov_mat
2.2 从协方差矩阵计算特征向量和特征值
在这里,如果我们知道线性代数的概念,以及如何计算矩阵的特征向量和特征值,那么这将对理解下面的概念非常有帮助。因此,通读线性代数的一些基本概念,以便更深入地理解一切是如何工作的,这是明智的。
这里,我使用 numpy 数组来计算标准化特征空间值的特征向量和特征值,如下所示:
cov_mat = np.cov(X_std.T)
eig_vals, eig_vecs = np.linalg.eig(cov_mat)
print('Eigenvectors \n%s' %eig_vecs)
print('\nEigenvalues \n%s' %eig_vals)
2.3 特征向量验证
我们知道,特征向量中每个值的平方和是 1。让我们看看它是否成立,这意味着我们已经正确计算了特征向量。
sq_eig=[] for i in eig_vecs: sq_eig.append(i**2)
print(sq_eig)
sum(sq_eig)
print("sum of squares of each values in an eigen vector is \n", 0.27287211+ 0.13862096+0.51986524+ 0.06864169)
for ev in eig_vecs: np.testing.assert_array_almost_equal(1.0, np.linalg.norm(ev))
3.选择主成分
- PCA 的典型目标是通过将原始特征空间投影到更小的子空间来降低原始特征空间的维数,其中特征向量将形成轴。
- 然而,特征向量仅定义新轴的方向,因为它们都具有相同的单位长度 1。
那么现在问题来了,如何选择新的一组主成分。背后的规则是,我们按降序对特征值进行排序,然后选择关于前 k 个特征值的前 k 个特征。
这里的想法是,通过选择前 k 个,我们决定对应于这 k 个特征空间的方差足以描述数据集。通过丢失那些未被选择的特征的剩余方差,不会损失太多的精度,或者我们可以因为忽略方差而损失太多的精度。
所以这是我们必须根据给定的问题集和商业案例做出的决定。没有完美的规则来决定它。
现在,让我们通过以下步骤找出主要组件:
3.1 特征值排序
为了决定在不丢失太多信息的情况下可以丢弃哪个(哪些)特征向量来构建低维子空间,我们需要检查相应的特征值:
- 具有最低特征值的特征向量承载关于数据分布的最少信息;那些是可以放弃的。
- 为此,通常的方法是从最高到最低排列特征值,以选择顶部的 k 个特征向量。
#Make a list of (eigenvalue, eigenvector) tuples
eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:,i])
for i in range(len(eig_vals))]
print(type(eig_pairs))
#Sort the (eigenvalue, eigenvector) tuples from high to low eig_pairs.sort()
eig_pairs.reverse()
print("\n",eig_pairs)
#Visually confirm that the list is correctly sorted by decreasing eigenvalues
print('\n\n\nEigenvalues in descending order:')
for i in eig_pairs:
print(i[0])
3.2 解释差异
- 对特征对排序后,下一个问题是“我们要为新的特征子空间选择多少个主成分?”
- 一个有用的度量是所谓的“解释方差”,它可以从特征值计算出来。
- 解释方差告诉我们有多少信息(方差)可以归因于每个主成分。
tot = sum(eig_vals)
print("\n",tot)
var_exp = [(i / tot)*100 for i in sorted(eig_vals, reverse=True)] print("\n\n1\. Variance Explained\n",var_exp)
cum_var_exp = np.cumsum(var_exp)
print("\n\n2\. Cumulative Variance Explained\n",cum_var_exp) print("\n\n3\. Percentage of variance the first two principal components each contain\n ",var_exp[0:2])
print("\n\n4\. Percentage of variance the first two principal components together contain\n",sum(var_exp[0:2]))
4.从选择的 k 个特征向量中构造投影矩阵 W
- 投影矩阵将被用于将虹膜数据变换到新的特征子空间上,或者我们说新变换的数据集具有降低的维度。
- 它是我们连接的前 k 个特征向量的矩阵。
这里,我们通过选择具有最高特征值的“前 2 个”特征向量来构造我们的 d×k 维特征向量矩阵 w,将 4 维特征空间减少到 2 维特征子空间
print(eig_pairs[0][1])
print(eig_pairs[1][1])
matrix_w = np.hstack((eig_pairs[0][1].reshape(4,1), eig_pairs[1][1].reshape(4,1)))
#hstack: Stacks arrays in sequence horizontally (column wise). print('Matrix W:\n', matrix_w)
5.投影到新的特征空间
在最后一步中,我们将使用 4×2 维投影矩阵 W,通过公式 Y=X×W 将样本变换到新的子空间上,其中输出矩阵 Y 将是变换后样本的 150×2 矩阵。
Y = X_std.dot(matrix_w)
principalDf = pd.DataFrame(data = Y , columns = ['principal component 1', 'principal component 2'])
principalDf.head()
现在,让我们结合我们在文章开始时分离的目标类变量。
finalDf = pd.concat([principalDf,pd.DataFrame(y,columns = ['species'])], axis = 1)
finalDf.head()
可视化 2D 投影
使用 PCA 投影到 2d 来可视化整个数据集。你应该用不同的颜色或形状画出不同的班级。班级之间应该很好地分开。
fig = plt.figure(figsize = (8,5))
ax = fig.add_subplot(1,1,1)
ax.set_xlabel('Principal Component 1', fontsize = 15) ax.set_ylabel('Principal Component 2', fontsize = 15) ax.set_title('2 Component PCA', fontsize = 20)
targets = ['Iris-setosa', 'Iris-versicolor', 'Iris-virginica'] colors = ['r', 'g', 'b']
for target, color in zip(targets,colors):
indicesToKeep = finalDf['species'] == target ax.scatter(finalDf.loc[indicesToKeep, 'principal component 1'] , finalDf.loc[indicesToKeep, 'principal component 2'] , c = color , s = 50) ax.legend(targets) ax.grid()
使用 Python 库直接计算主成分
或者,python 中有直接库,可以直接计算主成分,而不需要进行上述所有计算。上述步骤是为了让您了解一切是如何工作的。
pca = PCA(n_components=2)
# Here we can also give the percentage as a paramter to the PCA function as pca = PCA(.95). .95 means that we want to include 95% of the variance. Hence PCA will return the no of components which describe 95% of the variance. However we know from above computation that 2 components are enough so we have passed the 2 components.principalComponents = pca.fit_transform(X_std)
principalDf = pd.DataFrame(data = principalComponents , columns = ['principal component 1', 'principal component 2'])principalDf.head(5) # prints the top 5 rows
finalDf = pd.concat([principalDf, finalDf[['species']]], axis = 1) finalDf.head(5)
前两个主成分总共包含 95.80%的信息。第一主成分包含方差的 72.77%,第二主成分包含方差的 23.03%。第三和第四个主成分包含数据集方差的其余部分。
这就是主成分分析的全部内容。在我的下一篇帖子中,我将写 PCA 如何加速机器学*算法,并在有和没有 PCA 的情况下进行比较分析。
希望它已经让您很好地理解了 PCA 背后的概念。请在下面的评论区分享你的想法。您也可以使用联系人链接联系我。
原载于 2019 年 7 月 11 日【http://ashutoshtripathi.com】。
机器学*中决策树和 SVM 的完整视图
原文:https://towardsdatascience.com/a-complete-view-of-decision-trees-and-svm-in-machine-learning-f9f3d19a337b?source=collection_archive---------8-----------------------
在机器学*中,基于树的技术和支持向量机(SVM)是建立预测模型的常用工具。给定它们的理论,决策树和 SVM 可以直观地理解为对不同的组(标签)进行分类。然而,它们肯定是解决回归问题的强大工具,然而许多人忽略了这一事实。因此,在这篇博文中,我试图解释这些概念,并通过回归问题的例子展示这些算法如何用于分类和回归问题。
基于树的方法
基于树的方法已经成为许多行业中最受欢迎的技术,并有成功的预测案例。这些方法被认为是非参数化的,对数据的分布和真实模型的结构不做任何假设。它们需要较少的数据清理,并且在一定程度上不受离群值和多重共线性的影响。
最简单的方法是决策树,它可以用于回归和分类问题,并提供一个有用和简单的解释工具。
A simple decision tree to predict house prices in Chicago, IL
分类树和回归树的根本区别在于目标变量的数据类型。当我们的目标变量是一组离散的值时,我们有一个分类树。同时,回归树的目标变量是连续值。在分类问题中,我们的叶子是类别标签,而在回归问题中,我们的叶子是目标变量的连续值的箱。落入相同条柱的所有观测值具有相同的预测值。所以有人可能会想:这似乎不对,因为我们对每个观察值都有不同的值。这绝对没问题。即使使用线性回归方法,您也是在估计响应变量的预期平均值。您也可以将这种方法想象为 kNN 回归,将您的域划分为不同的区域,并拟合常数函数来逼*这些区域。理论上,你可以让你的树增长到有 N 个预测值箱(对于 N 个观察值),但是你的模型会过度拟合数据(偏差-方差权衡)。因此,没有人会这样做。
在 R 中,函数会自动识别回归或分类问题。同时,您需要在流行的 Python sklearn 包中选择分类器或回归器。
那么,我们如何种植一棵树呢?假设我们的数据有 p 个输入和一个对每个 N 个观察值的响应。
构建回归树:
- 考虑所有数据点,然后选择分裂变量 j 和分裂点 s 。
- 根据 j 和 s 定义 R₁和 R₂两个地区。
3.求求解的分裂变量 j 和分裂点 s
对于任何选择 j 和 s ,我们可以通过找到
对于每一个分裂变量,都有可能找到最佳的一对( j , s )。
4.找到最佳分割后,将数据分割成 2 个区域,并在这 2 个区域中的每个区域上重复分割过程。
5.对所有结果区域重复此过程。
显然,我们需要调整树的大小,以便使用我们的数据来控制模型的复杂性。一种简单的方法是仅当由于分裂而导致的平方和的减少超过某些阈值时才分裂树节点。然而,更好的策略是生长一棵大树,并在达到某个最小节点大小时停止分裂过程。使用成本复杂度修剪来修剪这棵大树。成本复杂性标准定义如下,其中 T ⊂ T₀是通过修剪大树 T₀.获得的任何树节点 m 表示区域 Rm,并且|T|是 T 中的终端节点的数量
cost complexity criterion
思路:为每个α寻找子树 T,使成本复杂度最小化。α的大值→较小的树 t。
构建分类树:唯一不同的是分裂节点和修剪树的标准。这里,我们将节点 m 中的类别 k 观测值的比例定义如下。
然后我们可以将节点 m 中的观测值归类到类 k 中,这是节点 m 中的多数类(相当于 𝝆mk 的最大值)。可以使用不同的节点杂质度量 Qm(T ):
虽然所有三个衡量标准是相似的,交叉熵和基尼指数是可区分的,因此更容易进行数值优化。此外,这两种方法对节点概率的变化比误分类误差更敏感。因此,它们往往被用来种树。为了指导成本复杂性修剪,错误分类率是优选的。
然而,像决策树这样简单的模型往往没有很好的预测能力。更复杂的方法,如随机森林和 boosting,通常会产生更好的结果,尽管在可解释性和预测准确性之间存在权衡。
随机森林包括在自举训练集上建立许多决策树。构建决策树时,在每个考虑的分裂中,从全套 p 个预测值中随机选择 m 个预测值。分割只能使用那些 m 选择的预测器中的一个。这种打包方法很好地克服了在拆分中只选择几个强有力的候选人的问题。它消除了树的相关性,使平均树的结果更加稳定。
XGBoost 代表极端梯度增强,实施梯度增强技术,但针对速度和性能进行了优化。boosting 思想涉及到按顺序生长树,这意味着每棵树都是基于先前生长的树的信息构建的。然而,与传统的 boosting 方法相比,XGBoost 在更新树和残差时会在 boosting 方程中应用更多的惩罚,同时利用硬件结构来加快计算时间。因此,它被认为是所有基于树的模型中最好的模型。然而,这种解读更难捕捉。
Project multiple trees of XGBoost model into one tree
支持向量机(SVM)
SVM 的思想是通过在特征空间的大的变换版本中构造线性边界来找到非线性边界。
简单来说,你在一个 x-y 平面上有 2 个类别,它们的点相互重叠,你找不到一条直线可以完美地将它们分开。然而,当你旋转包含我们的数据的平面从不同的角度看时,你可能会发现一个可以将它们分开的超平面。例如,您可以在特征空间中再添加一个维度。
建设 SVM 的关键:
- 我们定义我们的超平面为 Xβ = 0。
- 我们可能需要转换我们的数据(例如基本展开),并且转换通常使用核函数。我们可以用线性核、多项式核、径向基核或神经网络核来转化我们的问题。
- 选择一个使平面和分类组之间的余量(距离) M 最大化的超平面。直观上,我们对远离分割线平面的点比对靠*分割线平面的点更有把握。通过最大化距离,我们还可以捕捉当在整个数据集中有接*平面的点而在训练集中没有时的情况。因此,我们最大化了正确分类的机会。
- 由于完全分离的机会很低,我们需要一些“松弛”的边缘,允许一些点在边缘的错误一侧。我们将松弛变量定义为 ξ
5.然后修改约束条件:
第一个选项以距边距的实际距离度量重叠,而第二个选项以相对距离度量重叠。第一个选择导致非凸优化问题,但第二个选择是凸优化问题。因此,我们倾向于使用第二种选择。第二个约束中的值ξ表示 Xβ的预测位于其边缘错误一侧的比例量。这个误分类容限的调整参数称为“成本”参数 C 。较大的 C 值给出了较低的余量,显示了原始特征空间中过拟合的摆动边界。相反,C 的小值导致原始特征空间中更大的余量或更平滑的边界。
6.在 SVM 算法(R 或 Python)中需要指定的另一个参数是 Gamma 。它定义了单个训练示例可以在多大程度上影响分隔线的计算。低 Gamma 值意味着也可以考虑远处的点,而高 Gamma 值意味着只考虑可能分隔线附*的点。
SVM 还可以用于回归问题,称为支持向量回归。这种方法与 SVM 分类法非常相似,只是有一些细微的差别。在支持向量回归中,我们引入了一个新的术语,即“ ϵ-insensitive ”误差测度。定义如下,其中 r 为剩余值。
我们在这里尝试做的是找到一个函数 f(x,ω),使得我们的大多数训练点都落在ϵ-insensitive 区域内。我们不在乎误差,只要它们小于ϵ.ϵ的值会影响用于构建回归函数的支持向量的数量。我们还有松弛变量ξ来衡量训练样本在ϵ-insensitive 区域之外的偏差,称为软边际。然后,问题被公式化为最小化函数:
那么哪个更好呢?这是使用我的团队的芝加哥房屋数据集运行不同模型的结果。
参考:
Hastie,Tibshirani,r .,& j . h . Friedman(2017 年)。统计学*的要素:数据挖掘、推理和预测。美国纽约州纽约市:斯普林格。
支持向量机回归。http://kernelsvm.tripod.com/
使用 Python 进行图像处理和计算机视觉的综合实用指南:第 1 部分(简介)
原文:https://towardsdatascience.com/a-comprehensive-and-practical-guide-to-image-processing-and-computer-vision-using-python-part-1-4d8283c6d6eb?source=collection_archive---------7-----------------------
介绍
当今的世界是数据驱动的世界,图像是其中的重要组成部分。
每天都有超过 2.5 万亿字节的数据被创建,而且这个数字还会继续增长。据估计,到 2020 年,地球上每个人每秒将产生 170 万字节的数据。
——【https://www.domo.com/solution/data-never-sleeps-6
这些数据中大约 55–60%是图像/视频数据。但是,生成的数据是原始数据。这些数据必须经过预处理。根据需要,这些图像必须经过分析、处理和操作才能投入使用。所以来了,图片中的图像处理和计算机视觉。
完成本指南后,您将能够:-
- 基本的图像处理。
- 处理后的 I/O 图像和视频。
- 执行仿射、形态学、分段、霍夫变换等技术。
- 一些人脸检测和物体检测(Yayyyy!!\ (•◡•) / )
- 还有更多…
先决条件
T 他的这篇文章是我的一点微薄之力,希望通过一种实用的或动手的方法让人们对这些领域感兴趣。我们所需要的是 Python 和 OpenCV 安装(进一步讨论)在您的本地台式机/笔记本电脑或您在云上运行的 VM 实例上!!
- 如果你是 Linux 或 Mac 用户,不要担心你的 machine(Hushhhhh(˘▾˘)).上已经有 Python 了但是如果你是 Windows 用户,在这里从下载 Python。在安装过程中,不要忘记在$PATH 中添加 Python。
这篇文章是针对那些已经很好地掌握了 Python,但可能仍然从图像处理和 OpenCV 开始的人。
关于 OpenCV 的一点信息
penCV(开源计算机视觉)是一个广泛用于计算机视觉和机器学*任务的库。OpenCV 最初的实现是在 C++中。与 C/C++相比,Python 速度较慢,但另一方面,它可以很容易地用这些语言进行扩展。这个特性允许我们用 C++创建计算密集型代码,但用 Python 创建包装器,这样它们就可以作为 Python 模块使用。 OpenCV-Python 是 OpenCV 的 Python 实现。这个库是跨平台的,可以在开源 BSD 许可下使用。OpenCV 支持多种编程语言、操作系统和硬件。Python,Java,MATLAB/Octave 都有绑定。从 3.4 版本开始, OpenCV.js 就是 OpenCV 库的 JavaScript 绑定。
另外,OpenCV 需要一些先决条件,如 NumPy 和 Matplotlib ,通过使用以下命令安装它们:
python -m pip install --user numpy scipy matplotlib ipython jupyter pandas sympy nose
对于 Linux 用户来说,这肯定是可行的:
sudo pip3 install opencv-python
更多说明此处。
抱歉,我没有 Mac(⌣̩̩́_⌣̩̩̀)并且讨厌在 Windows(︶︿︶).使用 Python
如果导入时没有错误,那么就可以开始了。准备好了吗?让我们从深水区潜水吧!
什么是图像处理或计算机视觉,它做什么?
图像处理(通常称为数字图像处理)和计算机视觉是计算机科学中有大量算法处理图像或视频以获取某种信息的领域。图像处理处理图像到图像的转换,即处理的输入和输出都是图像,而计算机视觉是一个跨学科领域,处理如何使计算机理解或从数字图像或视频中获得高层次的见解或信息。下面的地图可以直观地理解上面所说的内容!
图像处理算法接收图像或视频作为输入,对其进行处理,处理的结果仍然是图像或视频。但是,计算机视觉算法接收图像或视频,对其进行处理,并从中构建明确而有意义的描述。
什么是图像?
图像可以定义为二维函数, f(x,y) ,其中 x 和 y 为空间(平面)坐标,任意一对坐标 (x,y) 处的 f 的幅值称为图像在该点的亮度或灰度。当(x,y)和 f 的振幅都是有限的离散值时,我们称该图像为数字图像。
拉斐尔·冈萨雷斯和理查德·伍兹
什么是视频?
视频的基本定义就是沿着时间轴堆叠的图像。视频可以通过纵横比、帧速率、隔行扫描与逐行扫描、颜色模型、压缩方法等来表征。
Courtesy of http://www.ctralie.com/Research/SlidingWindowVideo-SOCG2016/slidingvideo.html
考虑到视频 M 的切片,X[n]是第一帧,X[n+M-1]是最后一帧,Y[n]是将所有这些叠加起来形成整个视频的切片(部分)的向量。
图像处理和输入输出
O penCV 支持很多图像和视频格式的 I/O,首先让我们了解一下视频分析的几个范例。就像今天的相机记录一样,记录(视频)归结为以 30-60 FPS(每秒帧数)显示的帧,其中帧是图像。因此,图像处理和视频分析在很大程度上使用相同的方法
对于cv2.imread()
,支持以下格式:
- Windows 位图— 。bmp,。将饵在水面轻轻地上下拉动
- JPEG 文件— 。jpeg,。jpg,*。jpe
- JPEG 2000 文件— *.jp2
- 便携式网络显卡— *。png
- 便携式图像格式-。pbm,。pgm,*。百万分率
- 太阳栅格— 。高级,。肾素血管紧张素系统
- TIFF 文件— 。tiff,。标签图像文件格式。
对于cv2.VideoCapture()
,AVI 文件——*。avi 格式得到了全面的支持,因为 AVI 似乎是唯一一种具有良好的跨平台支持的格式。更多信息请参见此处的。
以下是 OpenCV 中图像和视频 I/O 的一些示例:
(Left)Code for reading & displaying the read image. (Right) Close the displayed image on a keypress
(Left) Load an existing video and play it. (Right) Record a video from your webcam and save to the disk after you press ‘q’
上面可以看到,图像的类型是 Numpy 的' ndarray '(n 维数组),下面我们来看看一些图像操作(数组操作)和一些没有使用 OpenCV 的核心模块。
1.获取基本的图像属性
import cv2img = cv2.imread('test1.jpeg')print("The properties of the image are:")
print("Shape:" + str(img.shape))
print("Total no. of pixels:" + str(img.size))
print("Data type of image:" + str(img.dtype))
Output for the code above.
2.访问和修改图像像素
访问单个像素的灰度/强度:
import cv2
import numpy as npm = cv2.imread("test1.jpeg")height,width,depth = np.shape(m)y = 1 # y coordinate(across height)
x = 1 # x coordinate(across width)print("Value at (1, 1, 0) = " + str(m[y][x][0])) # This will print the pixel value at given coordinates at depth zero(blue)print("Value at (1, 1, 1) = " + str(m[y][x][1])) # This will print the pixel value at given coordinates at depth one(green)print("Value at (1, 1, 2) = " + str(m[y][x][2])) # This will print the pixel value at given coordinates at depth two(red)
Output for the above code
要简单地迭代图像中的所有像素,我们可以使用:
import cv2
import numpy as npm = cv2.imread("test1.jpeg")height, width, depth= np.shape(m)# iterate over the entire image.
for y in range(0, height):
for x in range(0, width):
print(m[y][x])
看,这会在你的终端里打印出很多数字!!
要修改像素值:
import cv2
import numpy as npm = cv2.imread("test1.jpeg")height, width ,depth = np.shape(m)for py in range(0, height):
for px in range(0, width):
m[py][px][0] = 0cv2.imshow('matrix', m)
cv2.imwrite('output2.png', m)
cv2.waitKey(0)
cv2.destroyAllWindows()
(Left) Original image. Others are manipulated by making all pixels of certain channels = 0.
3.分割图像通道
通常, RGB 图像有一个 24 位‘色深’数据,即三个 8 位通道的 RGB 数据。这些通道只不过是蓝色、绿色和红色,强度等级从 0 到 255。可以使用cv2.split()
在 OpenCV 中分割图像,但是这种方法计算量很大,因此我们选择使用 Numpy 索引,因为它更有效,如果可能的话应该使用。
使用cv2.split()
方法进行分割非常简单:
b,g,r = cv2.split(img)
在 OpenCV 中,通道的顺序是 BGR 而不是 RGB 。
使用索引拆分:
import cv2
import numpy as npm = cv2.imread("test1.jpeg")blue = m[:, :, 0]
green = m[:, :, 1]
red = m[:, :, 2]
要了解更多的索引和拼接,请参考本。
在本文的下一部分,我们将在 OpenCV 中用相关的代码介绍图像处理技术。
本教程中使用的所有代码都可以在下面的资源库中找到。
[## pranav 6670/OpenCV-示例
中等物品的 OpenCV 代码。
github.com](https://github.com/pranav6670/OpenCV-examples/tree/master/Part 1)
Keras 相关神经网络综合指南
原文:https://towardsdatascience.com/a-comprehensive-guide-to-correlational-neural-network-with-keras-3f7886028e4a?source=collection_archive---------13-----------------------
从理论到实施
(本博客的改进在 这里 )
人类和许多其他动物一样有五种基本感觉:视觉、听觉、味觉、嗅觉和触觉。我们还有额外的感觉,比如平衡感和加速度感,时间感等等。人类大脑每时每刻都在处理来自所有这些来源的信息,每一种感官都影响着我们的决策过程。在任何交谈中,嘴唇的运动、面部表情以及声带发出的声音都有助于我们完全理解说话者所说的话的含义。我们甚至可以只通过看嘴唇的运动而不发出任何声音来理解单词。这种视觉信息不仅是补充性的,而且是必要的。这首先在麦克古克效应(麦古克&麦克唐纳,1976)中得到例证,其中带有有声 /ba/ 的视觉 /ga/ 被大多数受试者感知为 /da/ 。由于我们希望我们的机器学*模型达到人类水平的性能,因此也有必要使它们能够使用来自各种来源的数据。
在机器学*中,来自不同异构源的这些类型的数据被称为多模态数据。例如用于语音识别的音频和视频信息。很难在训练中直接使用这些多模态数据,因为它们可能具有不同的维度和数据类型。如此多的注意力放在学*这些多模态数据的通用表示上。学*这种多视图数据的通用表示将有助于一些下游应用程序。例如,学*视频及其音频的通用表示可以帮助为该视频生成比仅使用音频生成更准确的字幕。但是你如何学*这种常见的表示法呢?
An abstract view of CorrNet. It tires to learn a common representation of both views of data and tries to reconstruct both the view from that encoded representation.
相关神经网络是学*常见表示的方法之一。其架构几乎与传统的单视图深度自动编码器相同。但是它为每种数据形式包含一个编码器-解码器对。
让我们考虑一个两视图输入,Z =【Ia,Iv】,其中 Ia 和 Iv 是音频和视频等数据的两个不同视图。在下图中,显示了一个包含这些数据的 CorrNet 的简单架构。
Example of CorrNet with bimodal data Z = [Ia, Iv] where Ia and Iv are two different views of data like (audio and video )
其中编码器和解码器都是单层的。 H 是编码表示。Ha= f(Wa)。Ia+b)是编码表示 Ia。 f() 是任意非线性(sigmoid,tanh 等。).同样的情况还有Hv=f(Wa。I a +b)。双峰数据的常见表示法 Z 给出为:
H =f(Wa。I* a + Wv。Iv + b)。***
在解码器部分,模型试图通过I ' a=g(W ' a . H+b’)和I ' v = g(W ' VH+b’)从普通表示 H 中重构输入**
在训练期间,基于三个损失计算梯度:
I)最小化自重构误差,即最小化从Ia Iv 从 Iv 重构IaIaIa和Iv的误差。
ii)最小化交叉重建误差,即最小化从Ia到 Iv 和从 Ia 到 Iv 的重建误差。
iii)最大化两个视图的隐藏表示之间的相关性,即最大化 Ha 和 Hv 之间的相关性。
总损耗可以写成
这里, Lr() 表示重建损失,可以是“均方误差”或“平均绝对误差”。我们的目标是尽量减少这种损失。当我们想要增加相关性时,从损耗中减去相关性,即相关性越高,损耗越低。
履行
整个实现可以分为三个部分:模型建立、设置损失函数和训练。
在模型构建阶段,我们必须创建自动编码架构。首先,我们必须包含所有必需的包。
*from **keras** import **Model**
from **keras.layers import Input,Dense,concatenate,Add**
from **keras** import backend as **K,activationsfrom tensorflow**
import **Tensor** as Tfrom **keras.engine.topology**
import **Layer**
import numpy as **np***
然后我们必须创建 CorrNet 架构。为简单起见,它有一个单层的编码器和解码器。
*class **ZeroPadding**(Layer):
def **__init__**(self, **kwargs):
super(ZeroPadding, self).__init__(**kwargs) def **call**(self, x, mask=None):
return K.zeros_like(x)
def **get_output_shape_for**(self, input_shape):
return input_shape#inputDimx,inputDimy are the dimentions two input modalities. And #hdim_deep is the dimentions of shared representation( *kept as #global veriable*) inpx = **Input**(**shape**=(inputDimx,))
inpy = **Input**(**shape**=(inputDimx,))
***#Encoder***
hl = **Dense**(hdim_deep,**activation**='relu')(inpx) hr = **Dense**(hdim_deep,**activation**='relu')(inpy) h = Add()([hl,hr]) ***#Common representation/Encoded representation******#decoder***recx = **Dense**(inputDimx,activation='relu')(h) recy = **Dense**(inputDimy,activation='relu')(h)**CorrNet** = **Model**( [inpx,inpy],[recx,recy,h])
**CorrNet**.summary()'''we have to create a separate model for training this **CorrNet**
As during training we have to take gradient from 3 different loss function and which can not be obtained from signle input.If you look closely to the loss function, we will see it has different input parameter'''[recx0,recy0,h1] = **CorrNet**( [inpx, inpy])
[recx1,recy1,h1] = **CorrNet**( [inpx, ZeroPadding()(inpy)])[recx2,recy2,h2] = **CorrNet**( [ZeroPadding()(inpx), inpy ])
H= **concatenate**([h1,h2])
**model** = Model( [inpx,inpy],[recx0,recx1,recx2,recy0,recy1,recy2,H])*
现在我们必须为我们的模型写出相关损失函数。
***Lambda** = 0.01
#by convention error function need to have two argument, but in #correlation loss we do not need any argument. Loss is computed #competely based on correlation of two hidden representation. For #this a '**fake**' argument is used.def ***correlationLoss***(*fake*,H):
y1 = H[:,:hdim_deep]
y2 = H[:,hdim_deep:]
y1_mean = K.mean(y1, axis=0)
y1_centered = y1 - y1_mean
y2_mean = K.mean(y2, axis=0)
y2_centered = y2 - y2_mean
corr_nr = K.sum(y1_centered * y2_centered, axis=0)
corr_dr1 = K.sqrt(K.sum(y1_centered * y1_centered, axis=0) + 1e-8)
corr_dr2 = K.sqrt(K.sum(y2_centered * y2_centered, axis=0) + 1e-8)
corr_dr = corr_dr1 * corr_dr2
corr = corr_nr / corr_dr
**return** K.sum(corr) * Lambda
def ***square_loss***(y_true, y_pred):
error = ls.mean_squared_error(y_true,y_pred)
**return** error*
现在我们必须编译模型并进行训练
*model.**compile**(**loss**=[*square_loss,square_loss,square_loss, square_loss,square_loss,square_loss,correlationLoss*],**optimizer**="adam")
model.**summary**()
'''
Suppose you have already prepared your data and kept one moadlity data in Ia(e.g. Audio) and another in Iv( e.g. Video).To be used by this model Audios and videos must be converted into 1D tensor.
'''model.**fit**([Ia,Iv],[Ia,Ia,Ia,Iv,Iv,Iv,*np.ones((Ia.shape[0],Ia.shape[1]))*],nb_epoch=100)'''
***np.ones((Ia.shape[0],Ia.shape[1]))*** is fake tensor that will be passed to ***correlationLoss*** function but will have no use
'''
using this model we can generate Ia to Iv.For example, from video Iv we can generate corresponding audio Ia
np.zeros(Ia.shape) gives tensors of 0 of dimestions same as output tensor ***audio*** '''
**audio**,_,_ = **CorrNet.**predict([np.zeros(Ia.shape),Iv])*
经过训练后,该模型学*到的公共表示可以用于不同的预测任务。例如,使用 CorrNet 学*的常见表示可以用于:跨语言文档分类或音译等价检测。各种研究发现,使用公共表示可以提高性能。它也可以用于数据生成。例如,在某个数据集中,您有 10000 个音频剪辑和相应的视频,5000 个音频剪辑和 5000 个视频。在这种情况下,我们可以用 10000 个音频和视频训练一个 CorrNet,并可以用来为音频生成缺失的视频,反之亦然。
列表理解综合指南
原文:https://towardsdatascience.com/a-comprehensive-guide-to-list-comprehensions-f15bae4fd0c3?source=collection_archive---------22-----------------------
老实说,你的特征工程技能可能没有达到你想要的水平,你不知道该怎么办。很长一段时间(比我愿意承认的时间长)以来,我一直在使用分散在多行上的各种熊猫操作,只是为了执行简单的操作——比如将一列的一部分提取到另一列中——而实际上大多数事情可以在一行代码中完成。
Photo by Marius Niveri on Unsplash
列举理解就是这样做的一种方式。如果我想卖给你一些东西,现在是时候告诉你它们是如何简单和直观,它们是(在花了几天时间与它们晃来晃去)但对于初学者来说,它们可能看起来令人生畏。
本文将尝试用尽可能简单的语言解释列表理解,并展示它们在数据科学中的用例。现在我废话连篇也没什么意思了,让我们直入主题吧。
介绍泰坦尼克号数据集
我敢肯定,你知道著名的泰坦尼克号数据集,并可能使用它之前的某个时候。即使你还没有,也没什么好担心的,只要从这个 URL 下载,然后用 Python 导入就可以了。这是你应该有的:
牛逼。
先说简单的。
用例 1:将“性别”转换为 0 和 1
这可能是列表理解的最简单的用例。这个想法就是你要做如下的转换:
- 公 - > 0
- 女 - > 1
现在尝试在没有列表理解的情况下这样做。我知道这并不困难,但是看看这个漂亮的一行程序:
现在干净了。但是这很可能不是你阅读这篇文章的原因——你想看更高级的东西。
用例 2:从“名称”列提取标题
现在,这个稍微高级一点。你看到 名称 栏了吗?注意它是如何在第一个逗号后加上这个标题(像先生、小姐等)并在点号后结束的?
提取起来很简单。首先,你在逗号处分开字符串,并抓取右边的所有内容,然后在点处分开,并抓取左边的所有内容:
爽。我知道,但是你可以更进一步。让我们看看怎么做。
用例 3:将“年龄”分成 3 组
直到最*我才知道在一个列表理解中可以使用多个 if 语句。你可以这样做,但是你越深入,你的代码最终看起来就越乱。
想法是将 年龄 列分成 3 组:
下面 _20 - >年龄< 20
20 _ 到 _50 - > 20 <年龄< 50
以上 _50 - >年龄> 50
这可以在一行代码中完成。让我们看看如何:
首先你在做两组(低于 _20 和 20 _ 到 _50 ),然后再把第二组进一步分成两组(20 _ 到 _50 和高于 _50 )。这个特殊的例子并不复杂,但是如果您试图在这个列表理解中添加另一个 if 语句,就会变得混乱。
在你离开之前
列表理解很棒,这是毋庸置疑的。作为数据科学家,您应该尽可能地利用它们,用更少的代码行完成更多的工作。
获取一些数据集,并尝试在清理和准备过程中加以利用。你永远不会回头。
我想听听你的看法,你是如何在一行代码中实现复杂的逻辑的?让我知道。
喜欢这篇文章吗?成为 中等会员 继续无限制学*。如果你使用下面的链接,我会收到你的一部分会员费,不需要你额外付费。
[## 通过我的推荐链接加入 Medium-Dario rade ci
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
medium.com](https://medium.com/@radecicdario/membership)
深度学*中不同类型卷积的综合介绍
原文:https://towardsdatascience.com/a-comprehensive-introduction-to-different-types-of-convolutions-in-deep-learning-669281e58215?source=collection_archive---------2-----------------------
通过可视化实现对卷积的直观理解
如果你听说过深度学*中不同类型的卷积(例如,2D / 3D / 1x1 /转置/扩张(阿特鲁)/空间可分/深度可分/展平/分组/洗牌分组卷积),并对它们的实际含义感到困惑,本文旨在帮助你理解它们实际上是如何工作的。
在这篇文章中,我总结了深度学*中常用的几种卷积类型,并尝试以每个人都可以理解的方式解释它们。除了这篇文章,还有其他人关于这个主题的几篇好文章。请检查它们(在参考中列出)。
希望这篇文章能帮助你建立直觉,并为你的学*/研究提供有用的参考。请随时留下评论和建议。谢谢,请享用!😃
这篇文章的内容包括:
- 卷积与互相关
- 深度学*中的卷积(单通道版本,多通道版本)
- 3D 卷积
- 1 x 1 卷积
- 卷积运算
- 转置卷积(去卷积、棋盘伪影)
- 扩张卷积(阿特鲁卷积)
- 可分离卷积(空间可分离卷积,深度方向卷积)
- 平坦卷积
- 分组卷积
- 混洗分组卷积
- 逐点分组卷积
1。卷积与互相关
卷积是信号处理、图像处理和其他工程/科学领域中广泛使用的技术。在深度学*中,一种模型架构——卷积神经网络(CNN)就是以这种技术命名的。但是深度学*中的卷积本质上是信号/图像处理中的互相关。这两种操作有细微的区别。
无需深究细节,区别就在这里。在信号/图像处理中,卷积被定义为:
它被定义为两个函数的乘积在一个被反转和移位后的积分。下面的可视化演示了这个想法。
Convolution in signal processing. The filter g is reversed, and then slides along the horizontal axis. For every position, we calculate the area of the intersection between f and reversed g. The intersection area is the convolution value at that specific position. Image is adopted and edited from this link.
这里,函数 g 是滤波器。它是反过来的,然后沿着横轴滑动。对于每一个位置,我们计算 f 和反转的 g 之间的相交面积。该相交面积就是该特定位置的卷积值。
另一方面,互相关被称为两个函数的滑动点积或滑动内积。互相关中的滤波器不反转。直接滑过函数 f, f 和 g 的交集面积就是互相关。下图展示了相关性和互相关性之间的差异。
Difference between convolution and cross-correlation in signal processing. Image is adopted and edited from Wikipedia.
在深度学*中,卷积中的过滤器是不可逆的。严格来说是互相关。我们本质上执行元素级的乘法和加法。但在深度学*中只称之为卷积是约定俗成的。这很好,因为滤波器的权重是在训练期间学*的。如果上例中的反函数 g 是正确的函数,则在训练后,学*到的滤波器将看起来像反函数 g。因此,不需要像在真实卷积中那样在训练前首先反转滤波器。
2.深度学*中的卷积
做卷积的目的是从输入中提取有用的特征。在图像处理中,有很多种不同的滤波器可供卷积选择。每种类型的滤波器都有助于从输入图像中提取不同的方面或特征,例如水平/垂直/对角边缘。类似地,在卷积神经网络中,使用滤波器通过卷积提取不同的特征,滤波器的权重在训练期间自动学*。所有这些提取的特征然后被“组合”以做出决定。
做卷积有几个优点,比如权重共享和平移不变性。卷积还考虑了像素的空间关系。这些可能非常有帮助,尤其是在许多计算机视觉任务中,因为这些任务通常涉及识别某些组件与其他组件具有特定空间关系的对象(例如,狗的身体通常链接到头部、四条腿和尾巴)。
2.1.卷积:单通道版本
Convolution for a single channel. Image is adopted from this link.
在深度学*中,卷积是元素级的乘法和加法。对于只有一个通道的图像,卷积如下图所示。这里的滤波器是一个 3 x 3 矩阵,元素为[[0,1,2],[2,2,0],[0,1,2]]。滤波器滑过输入端。在每一个位置,它都在做元素级的乘法和加法。每个滑动位置以一个数字结束。最终输出是一个 3×3 的矩阵。(请注意,在此示例中,步幅= 1,填充= 0。这些概念将在下面的算术一节中描述。
2.2.卷积:多通道版本
在许多应用中,我们处理的是多通道图像。一个典型的例子是 RGB 图像。每个 RGB 通道强调原始图像的不同方面,如下图所示。
Different channels emphasize different aspects of the raw image. The image was taken at Yuanyang, Yunnan, China.
多通道数据的另一个例子是卷积神经网络中的层。卷积网络层通常由多个信道组成(通常有数百个信道)。每个通道描述前一层的不同方面。我们如何在不同深度的层之间进行过渡?我们如何将一个深度为 n 的图层转换为下一个深度为 m 的图层?
在描述这个过程之前,我们想澄清几个术语:层、通道、特征图、过滤器和内核。从层次的角度来看,层和过滤器的概念在同一层次,通道和内核在下面一个层次。频道和功能图是一回事。一个图层可以有多个通道(或要素地图):如果输入是 RGB 图像,则输入图层有 3 个通道。“通道”通常用于描述“层”的结构。类似地,“内核”用于描述“过滤器”的结构。
Difference between “layer” (“filter”) and “channel” (“kernel”).
过滤器和内核之间的区别有点棘手。有时,它们可以互换使用,这可能会造成混淆。从本质上讲,这两个术语有微妙的区别。“内核”指的是权重的 2D 阵列。术语“过滤器”是指堆叠在一起的多个内核的 3D 结构。对于 2D 滤波器,滤波器与内核相同。但是对于 3D 过滤器和深度学*中的大多数卷积来说,过滤器是内核的集合。每个内核都是独一无二的,强调输入通道的不同方面。
有了这些概念,多声道卷积如下。每个核被应用到前一层的输入通道上,以生成一个输出通道。这是一个基于内核的过程。我们对所有内核重复这样的过程,以生成多个通道。然后,这些通道相加在一起,形成一个单一的输出通道。下面的插图将使这个过程更加清晰。
这里的输入层是一个 5×5×3 的矩阵,有 3 个通道。该滤波器是一个 3×3×3 的矩阵。首先,滤波器中的每个内核分别应用于输入层的三个通道。执行三次卷积,得到大小为 3×3 的 3 个通道。
The first step of 2D convolution for multi-channels: each of the kernels in the filter are applied to three channels in the input layer, separately. The image is adopted from this link.
然后将这三个通道相加(逐元素相加)形成一个单通道(3×3×1)。该通道是使用过滤器(3 x 3 x 3 矩阵)对输入层(5 x 5 x 3 矩阵)进行卷积的结果。
The second step of 2D convolution for multi-channels: then these three channels are summed together (element-wise addition) to form one single channel. The image is adopted from this link.
等效地,我们可以认为这个过程是通过输入层滑动 3D 过滤器矩阵。请注意,输入层和过滤器具有相同的深度(通道号=内核号)。3D 过滤器仅在图像的两个方向上移动,高度&宽度(这就是为什么这种操作被称为 2D 卷积,尽管 3D 过滤器被用于处理 3D 体积数据)。在每个滑动位置,我们执行逐元素的乘法和加法,得到一个数字。在下面所示的示例中,在水平方向的 5 个位置和垂直方向的 5 个位置执行滑动。总的来说,我们得到一个单一的输出通道。
Another way to think about 2D convolution: thinking of the process as sliding a 3D filter matrix through the input layer. Notice that the input layer and the filter have the same depth (channel number = kernel number). The 3D filter moves only in 2-direction, height & width of the image (That’s why such operation is called as 2D convolution although a 3D filter is used to process 3D volumetric data). The output is a one-layer matrix.
现在我们可以看到如何在不同深度的层之间进行过渡。假设输入层有 Din 通道,我们希望输出层有 Dout 通道。我们需要做的只是将 Dout 滤镜应用到输入层。每个过滤器都有 Din 内核。每个滤波器提供一个输出通道。应用 Dout 滤波器后,我们有了 Dout 通道,然后它们可以堆叠在一起形成输出层。
Standard 2D convolution. Mapping one layer with depth Din to another layer with depth Dout, by using Dout filters.
3.3D 卷积
在上一节的最后一幅图中,我们看到我们实际上是在对 3D 体积执行卷积。但通常情况下,我们仍然把这种操作称为深度学*中的 2D 卷积。这是对 3D 体积数据的 2D 卷积。过滤器深度与输入层深度相同。3D 滤镜仅在 2 个方向上移动(图像的高度&宽度)。这种操作的输出是 2D 图像(只有一个通道)。
自然有 3D 卷积。它们是 2D 卷积的推广。在 3D 卷积中,滤波器深度小于输入层深度(内核尺寸<通道尺寸)。因此,3D 滤镜可以在所有 3 个方向(图像的高度、宽度和通道)上移动。在每个位置,逐元素的乘法和加法提供一个数。由于过滤器在 3D 空间中滑动,输出数字也在 3D 空间中排列。然后,输出是 3D 数据。
In 3D convolution, a 3D filter can move in all 3-direction (height, width, channel of the image). At each position, the element-wise multiplication and addition provide one number. Since the filter slides through a 3D space, the output numbers are arranged in a 3D space as well. The output is then a 3D data.
类似于编码 2D 域中对象的空间关系的 2D 卷积,3D 卷积可以描述 3D 空间中对象的空间关系。这种 3D 关系对于一些应用是重要的,例如在生物医学成像的 3D 分割/重建中,例如 CT 和 MRI,其中诸如血管的对象在 3D 空间中蜿蜒。
4.1 x 1 卷积
由于我们在前面的 3D 卷积部分讨论了深度操作,让我们看看另一个有趣的操作,1 x 1 卷积。
你可能想知道为什么这很有帮助。我们是否只是将一个数乘以输入层中的每个数?是也不是。对于只有一个通道的层来说,这个操作很简单。在那里,我们将每个元素乘以一个数。
如果输入层有多个通道,事情就变得有趣了。下图说明了 1 x 1 卷积如何适用于尺寸为 H x W x D 的输入图层。使用 1 x 1 x D 的过滤器进行 1 x 1 卷积后,输出通道的尺寸为 H x W x 1。如果我们应用 N 个这样的 1×1 卷积,然后将结果连接在一起,我们可以得到一个尺寸为 H×W×N 的输出层。
1 x 1 convolution, where the filter size is 1 x 1 x D.
最初,1×1 卷积是在网络中的网络论文中提出的。随后,它们在谷歌盗梦空间的论文 中被大量使用。.)1 x 1 卷积的几个优点是:
- 有效计算的降维
- 高效的低维嵌入或特征池
- 卷积后再次应用非线性
上图中可以观察到前两个优势。在 1×1 卷积之后,我们显著地减少了深度方向的维度。假设原始输入有 200 个通道,1×1 卷积会将这些通道(特征)嵌入到单个通道中。第三个优点是在 1×1 卷积之后,可以添加诸如 ReLU 的非线性激活。非线性允许网络学*更复杂的函数。
这些优势在谷歌的初始文件中被描述为:
“上述模块的一个大问题是,至少在这种天真的形式中,在具有大量滤波器的卷积层上,即使是适度数量的 5×5 卷积也可能非常昂贵。
这导致了所提出的架构的第二个想法:在计算需求增加太多的地方明智地应用维度缩减和投影。这是基于嵌入的成功:即使低维嵌入也可能包含大量关于相对大的图像块的信息…也就是说,在昂贵的 3×3 和 5×5 卷积之前,使用 1×1 卷积来计算缩减。除了用作还原,它们还包括整流线性激活的使用,这使它们具有双重用途。"
关于 1 x 1 卷积的一个有趣的观点来自 Yann LeCun,“在卷积网中,没有“全连接层”这样的东西。只有具有 1x1 卷积核和完整连接表的卷积层。”
5.卷积运算
我们现在知道如何处理卷积中的深度。让我们继续讨论如何处理其他两个方向(高度和宽度)的卷积,以及重要的卷积运算。
以下是一些术语:
- 内核大小:上一节讨论了内核。内核大小定义了卷积的视场。
- Stride:它定义了在图像中滑动时内核的步长。Stride 为 1 意味着内核逐个像素地滑过图像。步幅为 2 意味着内核通过每步移动 2 个像素(即跳过 1 个像素)来滑过图像。我们可以使用步幅(> = 2)对图像进行下采样。
- 填充:填充定义了如何处理图像的边框。填充卷积(Tensorflow 中的“相同”填充)将通过在输入边界周围填充 0(如有必要)来保持空间输出维度等于输入图像。另一方面,无填充卷积(Tensorflow 中的“有效”填充)只对输入图像的像素执行卷积,而不在输入边界周围添加 0。输出尺寸小于输入尺寸。
下图描述了一个 2D 卷积,使用的核大小为 3,步长为 1,填充为 1。
有一篇关于详细算术的优秀文章(深度学*卷积算术指南)。.)关于内核大小、步幅和填充的不同组合的详细描述和示例,可以参考它。这里我只是总结了最一般情况下的结果。
对于大小为 I、内核大小为 k、填充为 p、跨距为 s 的输入图像,卷积的输出图像大小为 o:
6.转置卷积(去卷积)
对于许多应用和网络架构,我们通常希望进行与正常卷积方向相反的变换,即我们希望执行上采样。一些例子包括生成高分辨率图像和将低维特征映射到高维空间,例如在自动编码器或语义分割中。(在后面的例子中,语义分割首先在编码器中提取特征图,然后在解码器中恢复原始图像大小,以便它可以对原始图像中的每个像素进行分类。)
传统上,可以通过应用插值方案或手动创建规则来实现上采样。另一方面,诸如神经网络之类的现代架构倾向于让网络本身自动学*适当的转换,而无需人工干预。为此,我们可以使用转置卷积。
在文献中,转置卷积也称为反卷积,或分数步长卷积。然而,值得注意的是,“反卷积”这个名称不太合适,因为转置卷积不是信号/图像处理中定义的真正的反卷积。从技术上讲,信号处理中的反卷积是卷积运算的逆运算。这里的情况并非如此。正因为如此,一些作者强烈反对将转置卷积称为反卷积。人们称之为反卷积主要是因为简单。稍后,我们将看到为什么称这样的运算为转置卷积是自然的和更恰当的。
用直接卷积实现转置卷积总是可能的。对于下图中的示例,我们使用单位步长对填充有 2 x 2 零边界的 2 x 2 输入应用了 3 x 3 内核的转置卷积。上采样输出的大小为 4×4。
Up-sampling a 2 x 2 input to a 4 x 4 output. Image is adopted from this link.
有趣的是,通过应用花哨的填充和步幅,可以将相同的 2 x 2 输入图像映射到不同的图像大小。下面,转置卷积应用于相同的 2×2 输入(在输入之间插入 1 个零),使用单位步长用 2×2 零边界填充。现在输出的大小是 5 x 5。
Up-sampling a 2 x 2 input to a 5 x 5 output. Image is adopted from this link.
在上面的例子中观察转置卷积可以帮助我们建立一些直觉。但是要推广它的应用,看看它是如何在计算机中通过矩阵乘法实现的是有益的。从那里,我们也可以看到为什么“转置卷积”是一个合适的名称。
在卷积中,让我们定义 C 为我们的内核,大为输入图像,小为卷积的输出图像。在卷积(矩阵乘法)之后,我们将大图像下采样成小输出图像。矩阵乘法中卷积的实现如下 C x 大=小。
下面的例子说明了这种操作是如何工作的。它将输入展平为 16 x 1 矩阵,并将内核转换为稀疏矩阵(4 x 16)。然后在稀疏矩阵和展平的输入之间应用矩阵乘法。之后,生成的矩阵(4 x 1)被转换回 2 x 2 输出。
Matrix multiplication for convolution: from a Large input image (4 x 4) to a Small output image (2 x 2).
现在,如果我们将方程两边的矩阵 CT 的转置相乘,利用矩阵与其转置矩阵相乘得到一个单位矩阵的性质,那么我们有如下公式 CT x Small = Large,如下图所示。
Matrix multiplication for convolution: from a Small input image (2 x 2) to a Large output image (4 x 4).
正如您在这里看到的,我们从小图像到大图像执行上采样。这是我们想要实现的目标。而现在,你也可以看到“转置卷积”这个名字的由来了。
转置卷积的一般算法可以从这篇优秀的文章(《深度学*卷积算法指南》)中的关系 13 和关系 14 中找到。
6.1.棋盘文物。
人们在使用转置卷积时观察到的一个令人不快的行为是所谓的棋盘伪影。
A few examples of checkerboard artifacts. Images are adopted from this paper.
论文“去卷积和棋盘状伪像”对这种行为有很好的描述。请查看这篇文章了解更多细节。在这里,我只是总结几个重点。
棋盘状伪像是转置卷积的“不均匀重叠”造成的。这种重叠在某些地方比其他地方更具隐喻性。
下图中,最上面的层是输入层,最下面的层是转置卷积后的输出层。在转置卷积期间,小尺寸的层被映射到大尺寸的层。
在示例(a)中,跨距为 1,文件大小为 2。如红色轮廓所示,输入上的第一个像素映射到输出上的第一个和第二个像素。如绿色轮廓所示,输入中的第二个像素映射到输出中的第二个和第三个像素。输出端的第二像素接收来自输入端的第一和第二像素的信息。总的来说,输出中间部分的像素从输入接收相同数量的信息。这里存在一个内核重叠区域。在示例(b)中,随着滤波器大小增加到 3,接收最多信息的中心部分缩小。但这可能没什么大不了的,因为重叠仍然是均匀的。输出的中心部分的像素从输入接收相同数量的信息。
The image is adopted and modified from the paper (link).
现在对于下面的例子,我们改变步幅= 2。在示例(a)中,滤波器大小= 2,输出上的所有像素从输入接收相同数量的信息。它们都从输入端的单个像素接收信息。这里没有转置卷积的重叠。
The image is adopted and modified from the paper (link).
如果我们将示例(b)中的滤波器大小更改为 4,均匀重叠的区域会缩小。但是,仍然可以使用输出的中心部分作为有效输出,其中每个像素从输入接收相同数量的信息。
然而,如果我们将示例(c)和(d)中的过滤器大小更改为 3 和 5,事情就变得有趣了。对于这两种情况,输出中的每个像素与其相邻像素相比接收的信息量不同。人们无法在输出上找到连续且均匀重叠的区域。
当滤波器大小不能被步幅整除时,转置卷积有不均匀的重叠。这种“不均匀的重叠”使一些地方的颜料比其他地方多,因此产生了棋盘效果。事实上,不均匀重叠的区域在二维上更为极端。在那里,两个图案相乘,不均匀性得到平方。
应用转置卷积时,有两种方法可以减少这种伪像。首先,确保使用除以步幅的文件管理器大小,避免重叠问题。其次,可以使用跨距= 1 的转置卷积,这有助于减少棋盘效应。然而,正如在许多最*的模型中所看到的,工件仍然会泄漏。
论文进一步提出了一个更好的上采样方法:首先调整图像大小(使用最*邻插值或双线性插值),然后做一个卷积层。通过这样做,作者避免了棋盘效应。您可能想在您的应用程序中尝试一下。
7.扩张卷积(阿特鲁卷积)
在的论文 ( 链接)和论文《利用扩张卷积进行多尺度上下文聚合》(链接)中介绍了扩张卷积。
这是标准的离散卷积:
The standard convolution.
扩张卷积如下:
当 l = 1 时,扩展卷积成为标准卷积。
The dilated convolution.
直观地说,膨胀卷积通过在内核元素之间插入空格来“膨胀”内核。这个额外的参数 l(膨胀率)表示我们想要将内核加宽多少。实现可能会有所不同,但是通常会在内核元素之间插入 l-1 个空格。下图显示了当 l = 1,2,和 4 时的内核大小。
Receptive field for the dilated convolution. We essentially observe a large receptive field without adding additional costs.
在图像中,3 x 3 红点表示卷积后,输出图像为 3 x 3 像素。尽管所有三个扩张的卷积提供了具有相同维度的输出,但是由模型观察到的感受野是显著不同的。l = 1的感受野为 3×3。对于 l =2 是 7 x 7。对于 l = 3 ,感受野增加到 15 x 15。有趣的是,与这些操作相关的参数数量基本相同。我们在不增加额外成本的情况下“观察”了一大片感受野。正因为如此,在不增加内核大小的情况下,使用扩展卷积来廉价地增加输出单元的感受野,这在多个扩展卷积一个接一个堆叠时尤其有效。
作者在论文“通过膨胀卷积进行多尺度上下文聚合”中建立了一个由多层膨胀卷积组成的网络,其中膨胀速率 l 在每层都呈指数级增加。结果,有效感受野呈指数增长,而参数的数量仅随层数线性增长!
本文中的扩展卷积用于在不损失分辨率的情况下系统地聚合多尺度上下文信息。该论文表明,所提出的模块增加了当时(2016 年)最先进的语义分割系统的准确性。请查看报纸以获取更多信息。
8.可分卷积
可分离卷积用于一些神经网络架构,例如 MobileNet ( Link )。可以在空间上(空间上可分离的卷积)或深度上(深度上可分离的卷积)执行可分离的卷积。
8.1.空间可分卷积
空间可分离卷积对图像的 2D 空间维度,即高度和宽度进行操作。从概念上讲,空间可分离卷积将一个卷积分解成两个独立的运算。对于下面所示的例子,Sobel 核(其为 3×3 核)被分成 3×1 和 1×3 核。
A Sobel kernel can be divided into a 3 x 1 and a 1 x 3 kernel.
在卷积中,3x3 核直接与图像进行卷积。在空间可分离卷积中,3×1 核首先与图像卷积。然后应用 1×3 内核。在进行相同的操作时,这将需要 6 个而不是 9 个参数。
此外,在空间可分离卷积中比卷积需要更少的矩阵乘法。对于一个具体的例子,在具有 3×3 内核(步幅=1,填充=0)的 5×5 图像上的卷积需要在水平方向的 3 个位置(以及垂直方向的 3 个位置)扫描内核。总共有 9 个位置,如下图中的点所示。在每个位置,应用 9 个逐元素乘法。总的来说,那是 9 x 9 = 81 次乘法。
Standard convolution with 1 channel.
另一方面,对于空间可分离卷积,我们首先在 5×5 图像上应用 3×1 滤波器。我们在水平方向的 5 个位置和垂直方向的 3 个位置扫描这样的内核。总共有 5 x 3=15 个位置,在下图中用圆点表示。在每个位置,应用 3 个元素式乘法。也就是15×3 = 45次乘法。我们现在得到了一个 3 x 5 的矩阵。这个矩阵现在与 1×3 核进行卷积,该核在 3 个水平位置和 3 个垂直位置扫描矩阵。对于这 9 个位置中的每一个,应用 3 个元素式乘法。这一步需要 9 x 3=27 次乘法。因此,总的来说,空间可分离卷积需要 45 + 27 = 72 次乘法,这比卷积少。
Spatially separable convolution with 1 channel.
让我们稍微概括一下上面的例子。假设我们现在对一个具有 m×m 内核的 N×N 图像应用卷积,跨距=1,填充=0。传统卷积需要 (N-2) x (N-2) x m x m 次乘法。空间可分离卷积需要N×x(N-2)x m+(N-2)x(N-2)x m =(2N-2)x(N-2)x m乘法。空间可分离卷积和标准卷积之间的计算成本比是
对于图像大小 N 大于过滤器大小(N >> m)的层,该比率变为 2 / m。这意味着在这种渐*情况下(N >> m),空间可分离卷积的计算成本是 3×3 过滤器的标准卷积的 2/3。对于 5 x 5 的滤镜,它是 2/5;对于 7 x 7 的滤镜,它是 2 / 7,依此类推。
虽然空间可分离卷积节省了成本,但它很少用于深度学*。一个主要原因是,不是所有的内核都可以分成两个更小的内核。如果我们用空间上可分离的卷积代替所有传统的卷积,我们就限制了自己在训练期间搜索所有可能的核。训练结果可能不是最佳的。
8.2.深度可分卷积
现在,让我们继续讨论深度可分卷积,这在深度学*中更常用(例如在 MobileNet 和exception)。深度方向可分离卷积由两个步骤组成:深度方向卷积和 1×1 卷积。
在描述这些步骤之前,有必要回顾一下我们在前面章节中讨论过的 2D 卷积和 1 x 1 卷积。让我们快速回顾一下标准 2D 卷积。举个具体的例子,假设输入层的大小是 7 x 7 x 3(高 x 宽 x 通道),滤镜的大小是 3 x 3 x 3。在用一个滤波器进行 2D 卷积之后,输出层的大小是 5×5×1(只有一个通道)。
Standard 2D convolution to create output with 1 layer, using 1 filter.
通常,在两个神经网络层之间应用多个滤波器。假设我们这里有 128 个过滤器。在应用这 128 个 2D 卷积后,我们有 128 个 5×5×1 的输出图。然后,我们将这些地图堆叠成 5 x 5 x 128 大小的单一图层。通过这样做,我们将输入层(7 x 7 x 3)转换为输出层(5 x 5 x 128)。空间维度,即高度和宽度缩小,而深度扩大。
Standard 2D convolution to create output with 128 layer, using 128 filters.
现在用深度方向可分的卷积,让我们看看我们如何实现同样的变换。
首先,我们将深度方向卷积应用于输入层。在 2D 卷积中,我们不是使用 3×3×3 大小的单个滤波器,而是分别使用 3 个内核。每个过滤器的尺寸为 3 x 3 x 1。每个内核与输入层的 1 个通道进行卷积(仅 1 个通道,不是所有通道!).每个这样卷积提供一个大小为 5×5×1 的图。然后,我们将这些地图堆叠在一起,创建一个 5 x 5 x 3 的图像。在此之后,我们得到大小为 5 x 5 x 3 的输出。我们现在缩小了空间维度,但是深度还是和以前一样。
Depthwise separable convolution — first step: Instead of using a single filter of size 3 x 3 x 3 in 2D convolution, we used 3 kernels, separately. Each filter has size 3 x 3 x 1. Each kernel convolves with 1 channel of the input layer (1 channel only, not all channels!). Each of such convolution provides a map of size 5 x 5 x 1. We then stack these maps together to create a 5 x 5 x 3 image. After this, we have the output with size 5 x 5 x 3.
作为深度方向可分离卷积的第二步,为了扩展深度,我们应用核大小为 1x1x3 的 1x1 卷积。将 5×5×3 的输入图像与每个 1×1×3 的内核进行卷积提供了大小为 5×5×1 的地图。
因此,在应用 128 个 1x1 卷积后,我们可以得到一个大小为 5×5×128 的层。
Depthwise separable convolution — second step: apply multiple 1 x 1 convolutions to modify depth.
通过这两个步骤,深度方向可分离卷积也将输入层(7×7×3)变换成输出层(5×5×128)。
深度方向可分离卷积的整个过程如下图所示。
The overall process of depthwise separable convolution.
那么,做深度可分卷积有什么好处呢?效率!与 2D 卷积相比,深度方向可分卷积需要更少的运算。
让我们回忆一下 2D 卷积例子的计算成本。有 128 个 3x3x3 内核移动 5x5 次。也就是 128 x 3 x 3 x 3 x 5 x 5 = 86,400 次乘法。
可分卷积怎么样?在第一个深度方向卷积步骤中,有 3 个 3x3x1 内核移动 5x5 次。即 3x3x3x1x5x5 = 675 次乘法。在 1×1 卷积的第二步中,有 128 个 1×1×3 核移动 5×5 次。也就是 128 x 1 x 1 x 3 x 5 x 5 = 9,600 次乘法。因此,总的来说,深度方向可分离卷积需要 675 + 9600 = 10,275 次乘法。这只是 2D 卷积成本的 12%!
那么,对于任意大小的图像,如果我们应用深度方向可分离卷积,可以节省多少时间呢?让我们稍微概括一下上面的例子。现在,对于大小为 H x W x D 的输入图像,我们想对大小为 h x h x D 的 Nc 个核进行 2D 卷积(步幅=1,填充=0),其中 H 是偶数。这将输入层(H x W x D)转换为输出层(H-h+1 x W-h+1 x Nc)。所需的总乘法是
Nc x h x h x D x (H-h+1) x (W-h+1)
另一方面,对于相同的变换,深度方向可分离卷积所需的乘法为
D x H x H x 1 x(H-H+1)x(W-H+1)+Nc x 1 x 1 x D x(H-H+1)x(W-H+1)=(H x H+Nc)x D x(H-H+1)x(W-H+1)
深度方向可分离卷积和 2D 卷积之间的乘法比现在是:
对于大多数现代架构来说,输出层具有许多通道是很常见的,例如,即使没有几千个通道,也有几百个通道。对于这样的层(Nc >> h ),上述表达式减少到 1 / h / h。这意味着对于这个渐*表达式,如果使用 3×3 滤波器,2D 卷积比深度方向可分离卷积花费 9 倍多的乘法。对于 5×5 滤波器,2D 卷积花费 25 倍以上的乘法。
使用深度方向可分卷积有什么缺点吗?当然有。深度方向可分离卷积减少了卷积中的参数数量。因此,对于小模型,如果 2D 卷积被深度方向可分离的卷积代替,则模型容量会显著降低。结果,该模型可能变得次优。但是,如果使用得当,深度方向可分卷积可以在不显著损害模型性能的情况下提高效率。
9.扁平盘旋
平坦卷积在论文前馈加速的平坦卷积神经网络中介绍。直观地说,这个想法是应用过滤器分离。我们不是应用一个标准卷积滤波器将输入层映射到输出层,而是将这个标准滤波器分成 3 个 1D 滤波器。这种想法类似于上述空间可分离卷积中的想法,其中空间滤波器由两个秩 1 滤波器*似。
The image is adopted from the paper.
应该注意到,如果标准卷积滤波器是秩 1 滤波器,这种滤波器总是可以被分成三个 1D 滤波器的叉积。但是这是一个强条件,并且标准滤波器的固有秩在实践中高于 1。正如在的论文中指出的,“随着分类问题难度的增加,需要更多数量的主导组件来解决问题……深度网络中的学*过滤器具有分布的特征值,将分离直接应用于过滤器会导致显著的信息丢失。”
为了缓解这种问题,论文限制感受野中的连接,以便模型可以在训练时学* 1D 分离滤波器。该论文声称,通过用由在 3D 空间中所有方向上的连续 1D 滤波器序列组成的扁平网络进行训练,提供了与标准卷积网络相当的性能,并且由于学*参数的显著减少而具有少得多的计算成本。
10.分组卷积
2012 年 AlexNet 论文(链接)中介绍了分组卷积。实现它的主要原因是允许在两个具有有限内存(每个 GPU 1.5 GB 内存)的 GPU 上进行网络训练。下面的 AlexNet 显示了在大多数层的两个单独的卷积路径。它在两个 GPU 之间进行模型并行化(当然,如果有更多的 GPU 可用,也可以进行多 GPU 并行化)。
This image is adopted from the AlexNet paper.
这里我们描述分组卷积是如何工作的。首先,传统的 2D 卷积遵循以下步骤。在此示例中,通过应用 128 个滤镜(每个滤镜的大小为 3 x 3 x 3),大小为(7 x 7 x 3)的输入图层被转换为大小为(5 x 5 x 128)的输出图层。或者在一般情况下,大小为(Hin x Win x Din)的输入层通过应用 Dout 内核(每个都是大小为 h x w x Din)转换为大小为(Hout x Wout x Dout)的输出层。
Standard 2D convolution.
在分组卷积中,滤波器被分成不同的组。每组负责一定深度的常规 2D 卷积。下面的例子可以更清楚地说明这一点。
Grouped convolution with 2 filter groups.
以上是具有两个滤波器组的分组卷积的图示。在每个滤波器组中,每个滤波器的深度只有名义 2D 卷积的一半。它们的深度是 Din / 2。每个滤波器组包含 Dout /2 滤波器。第一个滤波器组(红色)与输入层的前半部分([:,:,0:Din/2])卷积,而第二个滤波器组(蓝色)与输入层的后半部分([:,:,Din/2:Din])卷积。因此,每个滤波器组都会创建 Dout/2 通道。总体而言,两组创建 2 个 Dout/2 = Dout 通道。然后,我们将这些通道与 Dout 通道堆叠在输出层。
10.1.分组卷积与深度卷积
你可能已经观察到分组卷积和深度方向可分离卷积中使用的深度方向卷积之间的一些联系和区别。如果滤波器组的数量与输入层通道的数量相同,则每个滤波器的深度为 Din / Din = 1。这与深度方向卷积中的滤波器深度相同。
另一方面,每个滤波器组现在都包含 Dout / Din 滤波器。总的来说,输出层的深度为 Dout。这与深度方向卷积不同,深度方向卷积不改变层深度。在深度方向可分离卷积中,层深度随后被扩展 1×1 卷积。
做分组卷积有几个好处。
第一个优势是高效的培训。由于卷积分为几个路径,每个路径可以由不同的 GPU 单独处理。该过程允许以并行方式在多个 GPU 上进行模型训练。与用一个 GPU 训练所有东西相比,多 GPU 上的这种模型并行化允许每步将更多的图像送入网络。模型并行化被认为比数据并行化更好。后者将数据集分成几批,然后我们对每一批进行训练。然而,当批量变得太小时,我们本质上是在做随机而不是批量梯度下降。这将导致收敛速度变慢,有时收敛效果更差。
分组卷积对于训练非常深的神经网络变得很重要,如下所示的结果
The image is adopted from the ResNeXt paper.
第二个优点是模型更高效,即模型参数随着滤波器组数量的增加而减少。在前面的示例中,滤波器在标称 2D 卷积中具有 h x w x Din x Dout 参数。具有两个滤波器组的分组卷积中的滤波器有(h x w x Din/2 x Dout/2) x 2 个参数。参数的数量减少了一半。
第三个优势有点让人惊讶。分组卷积可以提供比标称 2D 卷积更好的模型。这是另一个奇妙的博客(链接)解释了这一点。这里简单总结一下。
原因链接到稀疏过滤器关系。下图是相邻图层滤镜之间的相关性。关系稀疏。
The correlation matrix between filters of adjacent layers in a Network-in-Network model trained on CIFAR10. Pairs of highly correlated filters are brighter, while lower correlated filters are darker. The image is adopted from this article.
分组卷积的相关图怎么样?
The correlations between filters of adjacent layers in a Network-in-Network model trained on CIFAR10, when trained with 1, 2, 4, 8 and 16 filter groups. The image is adopted from this article.
上图是使用 1、2、4、8 和 16 个过滤器组训练模型时,相邻图层过滤器之间的相关性。文章提出了一个推理(链接):“滤波器组的作用是在信道维度上用块对角结构化稀疏性来学*……在具有滤波器组的网络中,以更结构化的方式学*具有高相关性的滤波器。实际上,不必学*的过滤器关系是长参数化的。以这种显著的方式减少网络中的参数数量,不容易过度拟合,因此类似正则化的效果允许优化器学*更准确、更有效的深度网络。”
AlexNet conv1 filter separation: as noted by the authors, filter groups appear to structure learned filters into two distinct groups, black-and-white and color filters. The image is adopted from the AlexNet paper.
此外,每个过滤器组学*数据的唯一表示。正如 AlexNet 的作者所注意到的,滤镜组似乎将*得的滤镜分为两个不同的组,黑白滤镜和彩色滤镜。
11.混洗分组卷积
混洗分组卷积是在 Magvii Inc (Face++)的 ShuffleNet 中引入的。ShuffleNet 是一种计算高效的卷积架构,专门为计算能力非常有限(例如 10–150m flops)的移动设备而设计。
混洗分组卷积背后的思想与分组卷积(用于 MobileNet 和 ResNeXt 中)和深度方向可分离卷积(用于exception中)背后的思想相联系。
总的来说,混洗分组卷积包括分组卷积和信道混洗。
在分组卷积部分,我们知道滤波器被分成不同的组。每组负责一定深度的常规 2D 卷积。总操作量显著减少。例如,在下图中,我们有 3 个过滤器组。第一个滤波器组与输入层中的红色部分卷积。类似地,第二和第三滤波器组与输入中的绿色和蓝色部分卷积。每个滤波器组中的内核深度仅为输入层中总通道数的 1/3。在该示例中,在第一分组卷积 GConv1 之后,输入层被映射到中间特征图。然后,通过第二个分组卷积 GConv2 将该特征图映射到输出层。
分组卷积在计算上是高效的。但问题是每个滤波器组只处理从前一层的固定部分传下来的信息。例如,在上图中,第一个滤波器组(红色)仅处理从输入通道的前 1/3 向下传递的信息。蓝色滤镜组(蓝色)仅处理从输入通道的最后 1/3 传递下来的信息。因此,每个过滤器组只限于学*几个特定的特征。这种特性阻碍了通道组之间的信息流,并在训练期间削弱了表示。为了克服这个问题,我们应用了信道混洗。
信道混洗的想法是我们想要混合来自不同滤波器组的信息。在下图中,我们使用 3 个滤波器组应用第一个分组卷积 GConv1 后得到了特征图。在将该特征图馈入第二分组卷积之前,我们首先将每个组中的通道分成几个子组。我们把这些小组混合起来。
Channel shuffle.
在这样的混洗之后,我们照常继续执行第二分组卷积 GConv2。但现在,由于混洗层中的信息已经混合,我们实际上是用特征地图层(或输入层)中的不同子组来填充 GConv2 中的每个组。因此,我们允许渠道组之间的信息流动,并加强了代表性。
12.逐点分组卷积
ShuffleNet 论文( link )也介绍了逐点分组卷积。通常对于分组卷积,例如在 MobileNet ( 链接或 ResNeXt ( 链接)中,分组运算在 3×3 空间卷积上执行,而不是在 1×1 卷积上执行。
shuffleNet 的论文认为 1×1 卷积在计算上也是昂贵的。它还建议对 1×1 卷积应用群卷积。逐点分组卷积,顾名思义,执行 1 x 1 卷积的分组运算。操作与分组卷积相同,只有一处修改,即在 1x1 滤波器而不是 NxN 滤波器(N>1)上执行。
在 ShuffleNet 论文中,作者利用了我们所学的三种卷积:(1)混洗分组卷积;(2)逐点分组卷积;以及(3)深度方向可分离卷积。这种架构设计在保持精度的同时显著降低了计算成本。例如,ShuffleNet 和 AlexNet 的分类误差在实际移动设备上是相当的。然而,计算成本已经从 AlexNet 的 720 MFLOPs 大幅降低到 ShuffleNet 的 40–140m flops。凭借相对较小的计算成本和良好的模型性能,ShuffleNet 在移动设备的卷积神经网络领域获得了广泛应用。
感谢您阅读文章。请随时在下面留下问题和评论。
参考
博客和文章
- “深度学*中不同类型卷积的介绍”(链接)
- “回顾:膨胀网络—膨胀卷积(语义分割)”(链接)
- “ShuffleNet:用于移动设备的极其高效的卷积神经网络”( Link )
- “可分离卷积”可分离卷积的基本介绍
- 盗梦空间网络“盗梦空间网络版本简单指南”(链接)
- 《滤波器组教程(分组卷积)》(链接)
- “卷积算术动画”(链接)
- “转置卷积上采样”(链接)
- “直观理解用于深度学*的卷积”(链接)
报纸
- 网络中的网络(链接
- 通过扩张卷积进行多尺度上下文聚合(链接
- 具有深度卷积网络和全连接 CRF(链接)的语义图像分割
- ShuffleNet:一个用于移动设备的极其高效的卷积神经网络( Link )
- 深度学*卷积算法指南(链接)
- 用回旋更深入(链接)
- 重新思考计算机视觉的初始架构
- 前馈加速的扁平卷积神经网络(链接
- 例外:具有深度可分卷积的深度学*(链接)
- MobileNets:用于移动视觉应用的高效卷积神经网络( Link )
- 反卷积和棋盘格工件(链接)
- ResNeXt:深度神经网络的聚合残差变换( Link
方便的 R 包的完整列表
原文:https://towardsdatascience.com/a-comprehensive-list-of-handy-r-packages-e85dad294b3d?source=collection_archive---------9-----------------------
我发现对工作和生活非常有用的东西
对于数据科学/机器学*,Python 和 R 哪个更优越,这是一个公开的争论。尽管它古怪,不太真实,但普遍认为缓慢,R 在探索性数据分析(EDA)方面真的很出色,在数据争论,可视化,仪表板,统计包的无数选择(和错误)方面——所以我总是发现它有助于双重运用 R 和 Python,特别是使用 reticulate 和 rpy 提高互操作性。在过去几个月的大部分时间里,我都在使用 R,而我的 python、Java 和 javascript 技能则处于休眠状态。 CRAN taskviews 是一个搜索 R 包的很棒的起点,但是我猜我在过去几年中使用的包的列表可能对社区有益。这也是我记录过去学*的一个很好的动机。这就是我要说的——我会试着做些更新。它相当长,所以在强行安装所有东西之前,最好先尝试那些与你的主题相关的东西。然而,有一个观察表明,买了很多书的人几乎不读任何一本书。
所以事不宜迟:
数据争论
- tidyverse :我相信这个现在应该和 R 捆绑在一起了。实际上,如果你不是用它来争论数据,你可能做错了什么(或者你是超级老派)。它附带了一堆丰富的工具,如 dplyr (transform,filter,aggregate),tidyr(长/宽表转换), purrr (函数式编程包),tibble(增压数据帧)等。
- 看门人 :一个伟大的数据清理工具,与 tidyverse 配合得很好。
- sep lyr:dplyr 的一个好用的配套包,增加了一些快捷方式比如分组汇总功能。你可能总是实现自己,但这里是懒人的选择。
- 数据结构:R 中缺少的是现成的数据结构,比如 hashset 和 hashmap。放心,总有一包适合它。
形象化
-
ggplot2 :您应该使用的绘图包,句号。Python 也有一个 plotnine 绑定。有时,您可能会问自己,为什么需要 10 行代码来生成线图,而您可能只需在 excel 中打开文件并生成一个线图,其他时候,您会感激您可以编写任何内容,而无需将头撞向屏幕。如果你是新手,学*曲线肯定是陡峭的,但非常值得投资。
-
DataExplorer :一个易于使用的包,用于生成数据诊断的 ggplot-verse 图,如缺失数据/特征等。我使用一些快捷函数来快速验证数据。
-
ggrepel :这是 geom_text 的替代物,如果你有大量的标签并且不希望所有的文本重叠。运行大型数据集可能需要很长时间,但结果在视觉上会更令人愉快。
-
ggfortify :各种统计模型的诊断/可视化图。
-
sjPlot :附带一系列用于统计建模的简洁诊断图。我特别喜欢它建立在 ggplot 之上,这样你可以很容易地调整外观和感觉,以与其他 ggplot-verse 情节保持一致。jtools / interplot 包含了一些很好的绘制交互效果的函数。 ggdistribute 包含绘制后验分布的函数。
-
coefplot :自动绘制模型系数的置信区间。
-
:又一个带 ggplot2 的牛逼系数绘图包。
-
gghighlight :如果您有多个时间序列,并且希望突出显示其中几个,而将其余的保留在背景中,这将非常有用。
-
stargazer :从可以插入文稿的数据框生成 html / latex 表格。每当我希望表格风格更加经典时,我就用它来为谷歌文档生成表格。否则我就用 sjPlot。还有。
-
ggthemes , ggsci ,gg pubr,gg alt,hrbr themes:各种期刊的出版主题和颜色模板。你甚至可以得到 xkcd 风格的剧情。extra font允许你在绘图中使用自定义字体。
-
:信息图并不总是数据展示的最佳选择,但可能对不太懂数据/技术的受众有所帮助。这里是的一篇博客文章和一些例子。****
-
corrplot :一站式绘制各种表示中的各种相关性。
-
冲积 ,gg 冲积 , 河流地块 : ggplot 包生成 Sankey 流程图。假设你的流不会像面条一样缠绕在一起,它们有时对可视化复杂的流很有用。
-
pheatmap,gg dendro:包来绘制热图。
-
点阵 , plotrix ,gp lots,plottly:各种不在 ggplot 宇宙中的绘图函数。
-
ggmap , mapview , 传单 , sp :打包生成地理空间可视化功能。
-
, gridExtra :这些包很好地将多个 ggplots 拼接在一起。我个人更喜欢拼凑,因为语法更自然,更 gg-ish。
-
分类器图 :包含分类器的各种整洁诊断图。
-
ggstatsplot :自动统计绘图的新软件包。
-
inspectdf :一个非常好的探索分类变量的函数。
-
效果 :一个非常好的演示模型效果的包。
-
:更漂亮的基本绘图包,可直接更换
-
ggPMX :基于“ggplot”的工具,便于 NLME 模型的诊断绘图
-
ggchicklet :有趣又实用的水平堆叠条包
-
点密度 :密度图+散点图
-
WVPlots :一些常用的 ggplots
自然语言处理
- formattable :提供一套很好的函数的包,便于格式化,如数字、百分比等。
- 比例 :一个新的 R 包来辅助/美化 ggplot 比例,这是一个相当烦人和乏味的调整。我依靠这个库来生成对数刻度线(示例链接)。
- stringr , stringi :一套不错的字符串操作函数。R 中的字符串处理一般不太愉快,这些都是好救的。
- :KEA(关键短语提取)的一个 R 接口,这是其他更全面的 NLP 包如 topicmodels 的好伙伴库。
- udpipe :可训练的标记化管道。
- string ist,fuzzywuzzyR:模糊/*似字符串匹配和字符串距离函数。
- fuzzyjoin :一个 n 有趣的概念——这是对 dply join 方法的扩展,为表添加了模糊连接函数。可能很方便,但要小心使用,因为行为可能是不可预测的。
- topicmodels :一个高性能的主题建模包。
- formatR :如果没有使用内置自动格式化功能的 IDE,可以批量格式化多个 R 源代码。
- lintr:代码林挺为 R 源。
- 感知分析 :这是一个类似于 python 的 Vader 的包,如果你想用多种方法进行快速的情感分析。
统计学*
- modelr :精简的建模接口,将几种常用的建模框架规范化。
- broom :非常方便的包,可以将建模对象转换成更易消费的数据帧,用于批量报告、持久化或可视化。
- 【fmsb】**【Mcomp】:这是一本书的配套包医疗卫生数据分析使用 R 的做法。这本书大约有 10 年的历史了,但是一些数据对于尝试各种统计/ ML 方法是有用的。Mcomp 包含了一些时间序列数据。****
- Hmisc ,rcompanion,e 1071:优秀的各种统计分析的实用程序包,如样本大小/幂计算、计算伪 R、各种统计检验等。
- 素食主义者:生态学家的统计方法。
- fit.models :这个包类似于 caret ,它规范了各种参数/非参数模型拟合和比较的接口。
- OEM:apakage 开发出来专门处理大高数据(小 p,很大 N,一个例子就是 kaggle Talking Data )回归问题。
- BeSS : Abest 子集选择算法,可与标准的基于 AIC / BIC 的模型选择程序一起使用。
- quantreg :打包分位数回归函数。
- lavaan:潜变量分析与结构方程建模链接。
- lme4 :这个软件包非常适合线性和广义混合效果模型。
- 提升 :提升建模以优化特定治疗的 ROI,但识别目标的最佳子集[ 链接 ]。
- arm :使用回归和多级/层次模型的数据分析一书的配套。包含分层建模的简便方法。
- 平滑 :曲线平滑和时间序列预测。
- :极值/长尾值统计包,:极值模型的对数似然调整****
- MixtureInf :最大似然估计(MLE)方法。
- SGB :单纯广义贝塔回归
- pln 模型 : 泊松对数正态模型
- :带不等式约束的多项式模型的贝叶斯推断
- rms :这是回归建模策略书的配套包,提供了一系列回归分析的方法。
- emmeans :最小平方边际均值。
- 共图 :计数变形型号
- 【easy stats】:库使统计分析变得容易
- 参数 :提取参数超级简单的包
偶然推理
- MatchIt :一个很棒的倾向评分匹配包。它有一些怪癖,从结果中提取数据可能不是很直观。
- causal impact:Google 用于快速估算的包,通常这是我第一次尝试分析任何因果推断分析。
- 因果关系 :偶然的推论。我还没有详细检查这个包,它看起来很有希望。
- 比较因果网络 : T his 是因果网络的脱字符号,一个接入许多因果网络框架的统一接口。**
- rdd :这个包包含了回归不连续分析所需要的一切。
- 中介 :为因果中介分析开发的 Apackage。优步有一个关于此类分析的精彩博客。这个框架可以估计在没有提出的介体存在的情况下的平均治疗效果 w &。
元分析
- meta , metafor :基本 meta 分析的启动包,如拟合二元/连续结果的固定/随机效应模型。
- forest model,meta viz:meta/metafor 内置的森林绘图函数还没有升级到 ggplot universe。这些包做了改头换面,生成的图可以用 ggplot 函数更新,如改变标题,与其他图缝合等。我写了一个更好的森林绘图函数,我将在另一篇博文中分享。
- vcov :提取方差-协方差矩阵的快速方法。这可以在许多情况下使用,但对于多变量荟萃分析来说却很方便。
- bayesmeta , CPBayes , bmeta :当然会有 Bayes 的同行进行 meta 分析。我还没有详细检查这些,但随着我对贝叶斯推理的深入研究,我可能会做更多的工作。
- netmeta :网络元分析的一个包。网络荟萃分析是一种结合多项研究并推断从未直接比较过的各组间治疗效果的方法。
假设检验
-
diptest :多模态/混合分布的 dip 测试。
-
normtest :包含许多方便的正态性、偏度、峰度等测试,使用蒙特卡罗模拟,是对base::Shapiro . test:Shapiro-维尔克正态性测试的一个很好的补充。
-
seqtest ,SPRT,LD bounds,GS design:这些是用于顺序测试的包——使用各种方法计算界限。我计划写一个关于这个主题领域的综合性博客。
-
lmtest :线性回归模型的假设检验。
-
mhtboot :多重假设检验修正。
-
wBoot :作为假设检验替代方案的 Bootstrap 方法。
-
币 :排列测试框架。
-
重采样 : 重采样方法,可以和很多假设检验框架一起使用。
-
二项式 :提供额外的二项式置信区间,因为标准估计可能不适用于罕见事件、异质 p 等。
-
DescTools :懒人进行描述性统计的工具。
-
容差 : 换一种方式思考假设检验——给定 alpha 和恢复百分比,我们可以从特定概率分布中恢复的数据的下限和上限是什么?这个包对所有的普通发行版都有效。
-
WRS2 :稳健统计建模/测试方法集合;
-
bayesAB :你要用的贝叶斯假设检验包。这是由弗兰克·波特曼开发的一个很棒的软件包。
-
rstanarm:贝叶斯应用回归建模——可用于建模框架中的贝叶斯假设检验。
-
霍特林 :霍特林 T 检验的一个包。
-
BayesFactor :计算常见实验设计的 Bayes 因子。
-
推断 :反向推断包方式。
-
pvaluefunctions :创建置信分布和 p 值函数
-
蒙特。Carlo.se :蒙特卡洛标准误差
-
bamlss :贝叶斯可加模型或位置、比例、形状
-
BayesPostEst :用 MCMC 估计贝叶斯回归模型后的贝叶斯后估计量
功率分析
- **:功率分析的基本功能。从其他 3 个参数中计算出样本大小、功率、效果大小、α中的任意一个。******
- 样本大小 :类似于 pwr ,但也可以计算非参数 Wilcoxon 检验的样本大小。
- power analysis:一个更老的软件包也可以做到这一点。
- simr :使用基于仿真的方法进行功率分析
- effsize ,compute . es:非常方便的计算各种效果大小度量的包(Cohen d 等。).
因素/调查分析
- 调查 :名字很不言自明。
- SDaA :取样、设计、分析
- 因子分析 : 多变量因子分析,用多重对应分析(MCA)
- ade4 :生态数据分析/环境科学/调查方法。
- Ca , homals :各种对应分析方法。
时间序列分析
- seewave :声音分析包,也提供 SAX 转换
- 先知 :脸书的时间序列分析包,包括预测和变点检测。也有 Python 版本。
- 插补 : 专门为时间序列数据设计的插补方法。
- anytime ,time date,lubridate, hms :我们都知道时间格式转换是一种普遍的痛苦。这些包裹是用来营救的。
- fma :你可以玩的时间序列数据集。
- :生存/时间序列数据的回归模型
- 预测:ts/线性模型的预测函数。
- TSA :通用时间序列分析随书时间序列分析在 R 中的应用**
- astsa :应用统计时间序列分析。
- 光谱。 方法 :时间序列数据的频谱分解
- pracma :实用的数字数学函数。
- 变点 , cpm :变点/异常检测方法。
- bcp , ecp :变化点检测的贝叶斯/非参数方法。
- TSClust ,dtwclust:为时间序列数据聚类开发的具体方法。
- 异常化 :自动检测时间序列数据中的异常
生存分析
- 生存 :生存分析工具包。包含一切你需要开始,如考克斯风险模型。
稳健统计
- robust , robustbase :克服单变量/多维异常值并生成更稳定的模型/估计的稳健方法。
异常检测
- Twitter/anomaly detection:这个包已经很多年没有更新了,但是看起来还在工作。我将欢迎关于异常检测方法的建议。
特征工程/选择
- 预测 :分类变量转换工具。
- Boruta :基于重要性度量排列的特征选择方法。
- MXM :贝叶斯网络的特征选择方法。
- fscaret :从插入符号中自动选择特征。
- :使用集成方法的特征选择。
- one_hot , onehot :分类变量 onehot 编码的便捷快捷方式。
- 选择增强 :选择增强进行特性选择。
- 手电筒 :探索黑体算法特性包
距离度量
- proxy :距离函数可以分散在许多具有各种函数签名的 R 包中,这使得它很难热插拔。这个软件包标准化了距离定义,使得定义任何自定义距离函数变得很方便。
- parallelDist :在非常大的数据集(> 5000 行)上计算距离矩阵在本地机器上非常耗时;该软件包允许并行计算距离,这可以大大减少计算时间,测试速度提升高达 20 倍。
- philentropy :概率函数之间的相似距离。
- 【wCorr】权重 :相关性等加权统计。
- 距离 :可用于 ML / stat 建模的各种距离度量。
- 高尔 :高尔记录间的距离,常用于混合数字/分类回答的调查分析。
降维
- Rtsne ,tsne:T-SNE 实现在 r
- g models:fast . pr comp:PCA 的快速版本。
- umap :带教程此处,降维方法论。
- smacof :多维缩放的综合包,是对 MASS::isoMDS 的一个很好的补充
- largeViz :降维的大数据可视化。
- 【RDRToolbox】:降维 w/ isomap 和 LLE,框架统一。
无监督学*/聚类
- 麦克卢斯特 :使用高斯混合的基于模型的聚类方法。它会根据最大似然自动决定最佳的聚类数。这里有一个入门教程。
- fastcluster :一种用大规模性能提升取代内置层次集群的方法。对数千个数据点进行聚类只需不到几秒钟的时间。
- flash cluster:快速层次聚类的另一种实现。
- :包非负矩阵分解。这是一种非常有用的技术,可以找到较小矩阵的压缩版本,这些矩阵可以相乘以逼*源矩阵,同时保持所有值为正(可加)。常用于聚类/图像处理。[ 自然论文 ]
- 聚类 ,FPC, 线索 :一套聚类分析和验证的方法。****
- pvclust :使用 bootstrap 估计层次聚类中的不确定性,搜索最优割。
- fastICA :独立成分分析(ICA)的快速方法。一篇好的 Quora 帖子解释了 PCA 和 ICA 的区别。
- EMCluster :基于模型的聚类 w/有限混合高斯分布。简而言之,它假设数据是从多元高斯分布生成的,并尝试使用 EM 算法来估计最佳聚类数和聚类成员数。
- 线索 ,clusterSim:自动聚类方法,识别聚类数,用诊断图。
- :针对稀疏数据的稳健 K 均值聚类算法。
- 树形扩展 :高级树状图绘制方法。
- factoextra
- 【NbClust:一个非常好的包,可以确定集群的最佳数量——可以同时提供大约 30 个指标。
- clValid :计算各种集群质量指标,如 Dunn index 。
- 聚类倾向 :霍普金聚类倾向——你可以对任何数据集应用聚类算法,但这并不意味着结果有意义。具体来说,数据需要包含某种聚类结构,霍普金指数是一个很好的测量置换测试。
- dbscan :基于密度的聚类方法[ wiki ],也许能够解决传统的基于距离的方法失效的问题。
- cluMix:对混合数据类型的主题进行聚类,可以使用高尔距离计算距离。或者,您可以使用 gower 来计算距离,然后提供给首选的聚类算法。
- apcluster :相似传播聚类——与标签传播类似,通过相似度网络传递亲*度。
- :均值分割、不确定性评估和聚类验证
- 频谱 :快速频谱聚类算法
半监督学*
- SSL , RSSL :这些包提供了使用部分标记数据的半监督学*方法。
监督学*(通用机器学*)/深度学*
- caret :相当于 scikit learn 的 R:特征处理、训练/测试分割、交叉验证、模型性能度量……你说得出的。
- mlbench : ML 基准数据集和函数。
- xgboost :众所周知的 Kaggle 获胜算法。事实上,这几乎是高性能生产级别车型的普遍选择。快速、易于使用、易于部署。
- modelr
- 配方 :设计矩阵辅助包。
- mlr :类似于 caret,这是一个通用的模型训练框架。
- h2o , mltools :分布式机器学*框架,有社区版和包含 AutoML 实现的商业版。
- R studio/Keras:Keras 在 R 中的实现,go 深度学*!
- speedglm:GLM 库的更快版本。
- iml :可解释的机器学*:书
- tidy models:tidy models:tidy verse 风格的机器学*/统计建模包的集合。
- SHAPforxgboost:shap 值诊断 xgboost
阶级不平衡
-
smote family:类不平衡问题的综合过采样方法。
-
upclass :最*由 CRAN 存档,这是另一个合成少数样本的包。
图形分析
- I graph:R 最全面的图形库——汇总统计、距离、社区结构、聚类、可视化布局算法——应有尽有!一定有。
- qgraph :包含图形数据的各种方法,即。
- 网络:igraph 的配套包
- 一个基于 tidyverse 的可视化包
- 图形:基于网络的图形即
- 可视化网络的一些方法
- 网络 D3: 基于 D3 的网络
最佳化
- BB :求解大型线性和非线性方程组。非常快捷方便。
归罪
- VIM :缺失值的可视化和插补。瑞士刀包装。
- 小鼠 , 阿米莉亚 :多变量插补方法。这个想法是借用尽可能多的邻居数据来提高插补精度。**
- missForest :基于模型的方法之一——我们可以使用缺失值作为响应变量,并用其余变量拟合模型,从而进行插补。
- mi , mitools :一些较老的包,用于缺失值插补。
模拟
- 随机化器 :临床试验的随机化。
- 蒙特卡洛 :名字解释了一下,蒙特卡洛模拟的一个包。
生物信息学
- paircompviz:一个用于可视化多重测试比较的生物导体包。
- MSA:DNA/RNA/蛋白质序列比对的多重序列比对程序。可以为定制序列类型的数据重新定义转移矩阵。
- 生物字符串 : 生物字符串的高效库,可扩展为自定义字符集。
数据集
- 性别 :根据英文名猜测性别,产生概率**
- 婴儿姓名 :美国历年人口普查数据中的婴儿姓名。当我试图给我的女儿取名时,我用这个包来理解随时间变化的名字流行度
- gcookbook :这个包包含了本书 R 图形 Cookbook 的数据;我发现它对测试可视化工具很有用,而且它有一些现成的实用功能。
- wbstats:该软件包提供了对世界银行数据的程序化访问,如国内生产总值、收入、犯罪率、教育、人口统计等不同地理粒度的数据
- 【wdi】:易于使用的世界银行数据
开发者工具
- :这个包可以用来调试管道 (% > %) 功能
- validate :这个包自带了一套丰富的函数来验证函数参数,可以用在 plumber 等 web 服务的后端
仪表板/互动界面
- R/Shiny :我不是 Shiny 的忠实粉丝,但它是 Tableu 的一个方便的替代品,用于创建快速交互式数据可视化仪表板。
- html widgets:shiny 的好伙伴,提供许多交互式工具来可视化表格/时间序列/地理空间数据
- dygraphs :最好的时序数据交互可视化软件包之一;您可以同时绘制多个系列并修饰各种注释
- 【DataTables(DT):一个简单的包装器,用于将 R 数据帧转换成具有排序和过滤功能的交互式数据表
- 传单 :可视化地理空间数据的最佳软件包,尽管我发现集成到 Jupyter 笔记本中可能相当笨拙
- golem :健壮闪亮的应用框架
并行计算
- foreach :可以说是 for 循环的健壮得多的版本,用( %dopar%) 语法支持几个并行处理框架。我发现它的性能不如来自 parallel 的MC apply,但我喜欢它的错误处理和灵活性。
- mclapply :如果输出可以压缩到列表/数组中,现在我的 Go-to 函数用于单框并行化。
- parallel,snow :在 MC apply/foreach 中可以使用各种并行后端。
超正析象管(Image Orthicon)
- readr :如果你还在用内置的 read.csv …不要。这个软件包是如此优越,易于使用。不能没有。
- readxl :即使我不记得上一次处理 Excel 文件的情形(现在所有的东西都是 Google Sheets),知道有某种方法可以直接从 Excel 中读取也很棒,尤其是当那个文件包含多个工作表时。
- jsonlite :不需要解释,你需要某种方法来解析 JSON
- xml2 :虽然 xml 已经成为过去,但知道它仍然受到支持让我安心。
- rDrop :直接从 Dropbox 中方便地读取文件。
实用程序/Web 服务
- pryr :窥探 R 对象和函数的方法。
- devtools :开发者工具如果你是 R 开发的话。
- 水管工 , httr :设置 http 服务和发送 http 请求的包。
- glue :一个非常方便的工具,可以格式化带有多个变量的字符串(相当于 python 的 string.format),我发现它对于生成 SQL 或调试消息非常方便
- 备忘录:LRU 缓存的一个很棒的实现,与 http 服务(比如水管工)一起工作很棒
- 网状 :允许 R 直接访问 python 库和对象,如果你是双持!
- 【roxy gen 2】:从内嵌注释生成 R 文档。
- test that:R 的单元测试包
- 编织者 , 记账 :从 R 降价创建 HTML 报表。
- :应收账款管理系统。
- IRdisplay :用于显示 R 内核 Jupyter 中的图像/文本
其他资源
- 自动化探索性数据分析:这个 github repo 列出了许多加快数据探索过程的工具。
一个全面的最先进的图像识别教程
原文:https://towardsdatascience.com/a-comprehensive-state-of-the-art-image-recognition-tutorial-c34c544d0b4?source=collection_archive---------17-----------------------
从基础开始,使用 fastai 和 PyTorch 的快速多类图像识别
Photo by Matt Noble on Unsplash
本教程改编自 Fastai DL 2019 课程,有我的许多补充和澄清。希望对你有帮助。
通过本教程,您将能够在您选择的任何图像数据集上构建和训练图像识别器,并对底层模型架构和训练过程有很好的理解。
本教程涵盖:
1。数据提取
2。数据可视化
3。模型训练:CNN,ResNets,迁移学*
4。结果解读
5。冻结&解冻模型层
6。微调:Learning rate finder,One Cycle Policy
本教程对于任何新的深度学*实践者,任何想简单地使用 CNN 和 ResNets 刷新图像分类基础知识的人,或者任何没有使用过 fastai 库并想尝试一下的人都是一个很好的介绍。
本教程的笔记本也可以在这里找到。
要运行笔记本,只需用 Google Colab 这里 打开即可。这个笔记本是独立的,没有错误,所以你可以直接运行它。
一旦进入 Colab,确保更改以下内容以启用 GPU 后端,
运行时- >更改运行时类型- >硬件加速器- > GPU
本教程中的代码得到了简明的解释。任何类、方法等的进一步文档。可在 fastai docs 找到。
让我们开始吧…
设置 IPython 内核和初始化
导入必要的库,
让我们做一些初始化,
bs
是我们的批量,也就是一次要喂给模型的训练图像的数量。模型参数在每次批量迭代后更新。
例如,如果我们有 640 个图像,我们的批量大小是 64;参数将在一个时期内更新 10 次。
如果您碰巧在教程中的某个时间用完了内存,较小的批处理大小会有所帮助。批量大小通常是 2s 的倍数。
用特定值初始化上面的伪随机数发生器使系统稳定,产生可重复的结果。
1.数据析取
我们将使用的数据集是牛津-IIIT Pet 数据集,可以使用 fastai 数据集模块检索。
URLs.PETS
是数据集的 url。它有 12 种猫和 25 种狗。untar_data
将数据文件解压缩并下载到我们的path
中。
get_image_files
获取图像目录下所有文件的路径并存储到fnames
中。来自fnames
的一个实例将如下所示,
PosixPath('/home/jupyter/.fastai/data/oxford-iiit-pet/images/scottish_terrier_119.jpg')
由于每个图像的标签都包含在图像文件名中,我们将使用正则表达式来提取它。正则表达式,通常缩写为 regex ,是描述一定数量文本的模式。我们提取图像标签的模式如下:
最后一步是特定于这个数据集的。例如,如果属于同一个类的图像在同一个文件夹中,我们就不必担心这个问题。
现在让我们创建我们的训练和验证数据集,
ImageDataBunch
从路径path_img
中的图像创建训练数据集 train_ds 和验证数据集 valid_ds 。
from_name_re
使用编译表达式模式pat
后获得的正则表达式从文件名列表fnames
中获取标签。
df_tfms
是动态应用于图像的变换。在这里,图像将被调整到 224x224,居中,裁剪和缩放。这种转换是数据扩充的例子,在计算机视觉中已经被证明是有前途的。这种变换不会改变图像内部的内容,但会改变其像素值以获得更好的模型泛化。
normalize
使用 ImageNet 图像的标准偏差和平均值对数据进行标准化。
2.数据可视化
训练数据样本表示为
(Image (3, 224, 224), Category scottish_terrier)
其中第一个元素表示图像的 3 个 RGB 通道、行和列。第二个元素是图像标签。
该实例的对应图像是,
len(data.train_ds)
和len(data.valid_ds)
输出训练和验证样本数,分别为 5912 和 1478。
data.c
和data.classes
分别输出类的数量和它们的标签。共有 37 个类别,标签如下:
['Abyssinian', 'Bengal', 'Birman', 'Bombay', 'British_Shorthair', 'Egyptian_Mau', 'Maine_Coon', 'Persian', 'Ragdoll', 'Russian_Blue', 'Siamese', 'Sphynx', 'american_bulldog', 'american_pit_bull_terrier', 'basset_hound', 'beagle','boxer', 'chihuahua', 'english_cocker_spaniel', 'english_setter', 'german_shorthaired', 'great_pyrenees', 'havanese', 'japanese_chin', 'keeshond', 'leonberger', 'miniature_pinscher', 'newfoundland', 'pomeranian', 'pug', 'saint_bernard', 'samoyed', 'scottish_terrier', 'shiba_inu', 'staffordshire_bull_terrier', 'wheaten_terrier', 'yorkshire_terrier']
show_batch
显示一批中的几幅图像。
3.模特培训
cnn_learner
使用来自给定架构的预训练模型构建 CNN 学*器。来自预训练模型的学*参数用于初始化我们的模型,允许以高精度更快地收敛。
这里使用的 CNN 架构是 ResNet34 ,它在过去几年中取得了巨大的成功,至今仍被认为是最先进的。
讨论 CNN 和 ResNets 有很大的价值,因为这将有助于我们更好地了解我们在这里的培训过程。我们走吧。😃
CNN 一言以蔽之:
那么首先,什么是卷积神经网络(CNN 或 convNet)?我们可以将 ConvNet 视为将图像体转换为输出体的层列表,输出体可以是类分数,就像本教程中的情况一样。这些层由连接到前几层的其他神经元的神经元组成。为了深入阅读,我强烈推荐斯坦福大学 CS231 班的卷积神经网络。
A typical CNN architecture [Source]
该图展示了典型的 convNet 架构。我们可以将所有 CNN 架构视为不同可微函数(卷积、下采样和仿射变换)的各种组合。上图只有几层,但深网有几十层到几百层。
结果简单来说:
深度网络中一个非常常见的问题是退化问题,其中模型精度达到饱和,然后迅速退化。这是违反直觉的,因为我们期望额外的层应该支持更详细和抽象的表示。这个问题正是 ResNets 要解决的,因为它们可以安全地优化训练更深层次的网络,而不用担心退化问题。
ResNets 解决退化问题的方法是通过引入“身份快捷连接”,通常称为“跳过连接”,跳过一层或多层。跳过连接的输出被添加到堆叠图层的输出中,如下图所示。跳过连接有效地跳过了某些层上的学*过程,使得深层网络在某种程度上也充当浅层网络。
A residual block [Source]
skip 函数创建了所谓的残差块,即图中的 F(x ),这就是残差网(ResNets)名称的由来。传统网络旨在直接学*输出 H(x ),而 ResNets 旨在学*残差 F(x)。使 F(x) = 0 允许网络跳过该子网,因为 H(x) = x。
已经表明,添加这些身份映射允许模型更深入而不降低性能,并且这种网络比简单的堆叠层更容易优化。ResNet 有几种变体,如 ResNet50、ResNet101、ResNet152ResNet 数字表示 ResNet 网络的层数(深度)。
在本教程中,我们使用 ResNet34,它看起来如下:
Architecture and convolutional kernels of ResNet34 [Source]
在该图中,底部的数字表示输入或特征图的大小(高 x 宽),上面的数字表示通道的数量(过滤器的数量)。例如,第一个左边的块代表输入图像(224 x 224 x 3)。图中的每个层包含很少的残差块,这些残差块又包含具有不同可微函数的堆叠层,导致 34 个端到端的层。下面是 ResNet34 架构与类似的简单架构相比的完整底层布局;侧箭头表示身份连接。
A plain 34-layer CNN (left) and a 34-layer ResNet (right) [Source]
只需将models.resnet34
替换为models.resnet50
或任何其他所需的架构,就可以随意尝试任何其他的 ResNets。请记住,增加层数将需要更多的 GPU 内存。
我们上面描述的使用预训练模型并使其适应我们的数据集的方法被称为迁移学*。但是为什么要用迁移学*呢?
转移学*:
深度神经网络有大量的参数,通常在数百万的范围内。在小数据集(小于参数数量的数据集)上训练这样的网络会极大地影响网络的泛化能力,通常会导致过度拟合。所以在实践中,很少用随机权重初始化从零开始训练网络。
预训练模型通常在非常大的数据集上训练,例如包含 120 万个图像和 1000 个类别的 ImageNet。因此,预训练模型将已经学会在其早期层中捕捉通用特征,如曲线、颜色梯度和边缘,这对于大多数其他计算机视觉分类问题可能是相关的和有用的。迁移学*在其他领域也同样有效,比如自然语言处理和语音识别。
现在,通过迁移学*,我们的模型已经在 ImageNet 上进行了预训练,我们只需要使它更具体地针对我们手头数据集的细节。我们有两个选择来做到这一点,我们可以只更新最后层的参数,或者我们可以更新模型的所有层。第一种选择通常被称为特征提取,而第二种被称为微调。在这两种方法中,由于 ImageNet 预训练模型在输出图层中的大小为 1000,因此首先重塑最终图层以使其在我们的数据集中具有相同数量的类是很重要的。
太好了!到目前为止,我们已经讨论了许多核心概念。
让我们继续…
现在让我们在数据集上训练模型,
fit_one_cycle
根据所提供的时期数训练模型,即此处为 4。
时期数表示模型查看整组图像的次数。然而,在每一个时代,同样的图像在我们的数据扩充后会有些许不同。
通常,度量误差会随着每个历元而下降。只要验证集的准确性不断提高,增加历元的数量是一个好主意。然而,大量的历元会导致学*特定的图像而不是一般的类,这是我们想要避免的。
我们刚刚在这里进行的训练就是我们所说的特征提取,因此只有模型头部(最后一层)的参数被更新。接下来我们将尝试微调所有图层。
祝贺你!!!该模型已被成功训练识别狗和猫的品种。
我们以上达到的准确度约为 93.5%
我们能做得更好吗?微调之后再说。
让我们保存当前的模型参数,以防以后需要重新加载。
4.结果解释
现在让我们看看如何正确解释当前的模型结果。
ClassificationInterpretation
提供错误分类图像的可视化。
plot_top_losses
显示最高损失的图像及其:
预测标签/实际标签/损失/实际图像类别的概率
高损失意味着对错误答案的高度信任。绘制顶部损失是可视化和解释分类结果的好方法。
Misclassified images with the highest losses
Classification confusion matrix
在混淆矩阵中,对角线元素表示预测标签等于真实标签的图像的数量,而非对角线元素是被分类器错误标记的图像。
most_confused
简单抓取预测和实际类别最混淆的组合;换句话说,就是那些最容易出错的。我们可以看到它经常把斯塔福德郡斗牛梗误认为美国斗牛梗,它们看起来确实非常相似:)
[('Siamese', 'Birman', 6),
('american_pit_bull_terrier', 'staffordshire_bull_terrier', 5),
('staffordshire_bull_terrier', 'american_pit_bull_terrier', 5),
('Maine_Coon', 'Ragdoll', 4),
('beagle', 'basset_hound', 4),
('chihuahua', 'miniature_pinscher', 3),
('staffordshire_bull_terrier', 'american_bulldog', 3),
('Birman', 'Ragdoll', 2),
('British_Shorthair', 'Russian_Blue', 2),
('Egyptian_Mau', 'Abyssinian', 2),
('Ragdoll', 'Birman', 2),
('american_bulldog', 'staffordshire_bull_terrier', 2),
('boxer', 'american_pit_bull_terrier', 2),
('chihuahua', 'shiba_inu', 2),
('miniature_pinscher', 'american_pit_bull_terrier', 2),
('yorkshire_terrier', 'havanese', 2)]
5.冻结和解冻
默认情况下,在 fastai 中,使用预先训练的模型会冻结前面的层,因此网络只能对最后一层的参数进行更改,正如我们上面所做的那样。冻结第一层并仅训练更深的层可以显著减少大量计算。
我们总是可以通过调用unfreeze
函数,然后调用fit
或fit_one_cycle
来训练网络的所有层。这就是我们所说的微调,因为我们正在调整整个网络的参数。我们开始吧,
现在的精度比以前差了一点。 为什么会这样?
这是因为我们以相同的速度更新所有层的参数,这不是我们所希望的,因为第一层不需要像最后一层那样做太多的改变。控制权重更新量的超参数称为学*率,也称为步长。它根据损失的梯度调整权重,目的是减少损失。例如,在最常见的梯度下降优化器中,权重和学*速率之间的关系如下,
翻译过来就是new_weight = old_weight — lr * gradient
顺便说一下,梯度只是一个向量,它是导数 的多变量推广。
因此,对模型进行微调的更好方法是对较低层和较高层使用不同的学*速率,通常称为差异或区别学*速率。
顺便说一下,我在本教程中交替使用参数和权重。更准确地说,参数是权重和偏差,但我们不要担心这里的微妙之处。但是,注意超参数和参数是不同的;超参数不能在训练中估计。
6.微调
为了找到用于微调模型的最合适的学*率,我们使用了一个学*率查找器,其中学*率逐渐增加,并且在每批之后记录相应的损失。fastai 图书馆在[lr_find](https://docs.fast.ai/callbacks.lr_finder.html#lr_find)
实现了这一点。关于这方面的进一步阅读,请查看由 @GuggerSylvain 撰写的如何找到好的学*率。
让我们加载之前保存的模型并运行lr_find
,
recorder.plot
方法可用于绘制损失与学*率的关系图。当亏损开始发散时,这个图就停止了。
从结果图中,我们一致认为,在损失开始增加并失去控制之前一点,适当的学*率应该是 1e-4 左右或更低。我们将 1e-4 分配给最后一层,1e-6 分配给前面的层。同样,这是因为早期图层已经训练有素,可以捕捉通用要素,不需要太多更新。
如果您对我们之前实验中使用的学*率感到疑惑,因为我们没有明确声明它,它是 0.003,这是库中默认设置的。
在我们用这些有区别的学*率训练我们的模型之前,让我们揭开fit_one_cycle
和fit
方法之间的区别,因为两者都是训练模型的合理选择。这种讨论对于理解培训过程非常有价值,但是请随意跳到微调结果。
fit_one_cycle
vs fit :
简而言之,不同之处在于fit_one_cycle
实现了 Leslie Smith 1cycle 策略,该策略不是使用固定或递减的学*速率来更新网络参数,而是在两个合理的学*速率下限和上限之间振荡。让我们再深入了解一下这对我们的训练有什么帮助。
➯ 训练中的学*率超参数
当调整我们的深度神经网络时,一个好的学*率超参数是至关重要的。高学*率允许网络更快地学*,但是过高的学*率会使模型无法收敛。另一方面,小的学*率会让训练进度非常慢。
Effect of various learning rate on convergence [Source ]
在我们的例子中,我们通过查看不同学*率下记录的损失来估计适当的学*率( lr )。在更新网络参数时,可以使用这个学*率作为固定值;换句话说,相同的学*率将应用于所有的训练迭代。这就是learn.fit(lr)
所做的。一个更好的方法是随着训练的进展改变学*速度。有两种方法可以做到这一点,学*率时间表(基于时间的衰减,步进衰减,指数衰减等)。)或自适应学*率方法(Adagrad、RMSprop、Adam 等)。).有关这方面的更多信息,请查看 CS230 斯坦福课堂笔记参数更新。另一个好资源是@ Sebastian Ruder 的梯度下降优化算法概述。
➯ 一言以蔽之一个周期政策
单周期策略是学*率调度器的一种类型,它允许学*率在合理的最小和最大界限之间振荡。这两个界限的值是什么?上限是我们从学*率查找器中得到的,而下限可以小 10 倍。这种方法的优点是它可以克服局部最小值和鞍点,鞍点是平坦表面上通常具有小梯度的点。1cycle 策略已被证明比其他调度或自适应学*方法更快、更准确。Fastai 在fit_one_cycle
中实现 1cycle 策略,它在内部调用fit
方法和OneCycleScheduler
回调。fastai 1cycle 政策实施的文档可在这里找到。
One cycle length of 1cycle policy [Source]
fastai 实现中 1 周期策略的一个微小修改是在从lr_max
到0.
的第二阶段中包含余弦退火
➯1 周期策略发现
Leslie Smith 首先发现了一种他称之为 循环学*率 (CLR)的方法,在该方法中,他表明 CLR 在计算上并不昂贵,并且它们消除了寻找最佳学*率值的需要,因为最佳学*率将落在最小和最大界限之间。然后,他在那篇论文之后又写了另一篇 《神经网络超参数的训练方法:第 1 部分——学*速率、批量大小、动量和权重衰减 ,其中他强调了各种评论和建议,以加快网络训练,产生最佳结果。其中一个提议是使用只有一个周期的 CLR 来获得最佳和快速的结果,他在另一篇论文超级收敛中详细阐述了这一点。作者将这种方法命名为 1 周期策略。
下图说明了对于 Cifar-10,超收敛方法如何在更少的迭代中达到比典型(分段常数)训练机制更高的精度,两者都使用 56 层残差网络架构。
Super-convergence accuracy test vs a typical training regime with the same architecture on Cifar-10 [Source]
如果你选择不读莱斯利·史密斯的论文,我还是会推荐你读读这篇文章由 @GuggerSylvain 撰写的1 周期政策。
斗牛中的最后一剑
既然我们已经为我们的层选择了区别学*率,我们可以解冻模型并相应地进行训练。
slice 函数将 1e-4 分配给最后一层,将 1e-6 分配给第一层;在这个范围内,中间的层以相等的增量获得学*率。
我们看到精度有所提高,但并不多,所以我们想知道我们是否需要微调模型?
在微调任何模型之前,需要始终考虑两个关键因素:数据集的大小及其与预训练模型的数据集的相似性。查看斯坦福 CS231 笔记关于何时以及如何微调?。在我们的例子中,我们的 Pet 数据集类似于 ImageNet 中的图像,并且相对较小,这就是为什么我们从一开始就实现了高分类精度,而没有微调整个网络。
尽管如此,我们仍然能够提高我们的成绩,学到了很多东西,做得很好:)
下图说明了使用和微调预训练模型的三种可行方法。在本教程中,我们尝试了第一种和第三种策略。在数据集很小但与预训练模型的数据集不同的情况下,或者数据集很大但与预训练模型的数据集相似的情况下,策略 2 也很常见。
Fine-tuning strategies on a pre-trained model
祝贺您,我们已经使用最先进的 CNN 成功地报道了图像分类,并为底层结构和训练过程打下了坚实的基础👌
您已经准备好在自己的数据集上构建图像识别器。如果你还没有,你可以从谷歌图片中抓取图片,组成一个数据集。我做了一个非常短的教程,只为⬇检查一下。
[## 在不到 10 分钟的时间内对数据集进行最先进的图像分类
使用 fastai 和 PyTorch 库进行快速多类图像分类,代码准备就绪
towardsdatascience.com](/https-medium-com-drchemlal-deep-learning-tutorial-1-f94156d79802)
鸣谢:感谢杰瑞米·霍华德和瑞秋托马斯为创作所有 fastai 内容所做的努力。
我希望这篇简短的教程对你有所帮助。请给它一个分享和一些掌声,这样它也可以到达其他人😀欢迎留下任何评论,并通过 Twitter @ SalimChemlal 或 Medium 与我联系,了解更多信息!
"一个被新的经历拉伸的头脑永远不会回到它原来的维度."——小奥利弗·温德尔·霍姆斯
一种不断更新的 k-means 算法
原文:https://towardsdatascience.com/a-continuously-updating-k-means-algorithm-89584ca7ee63?source=collection_archive---------15-----------------------
一种改进的 k-means 模型,可以不断学*新的例子
Photo by JESHOOTS.COM on Unsplash
概述
我们都听说过流行的 k-means 算法,该算法用于在我们的数据中查找聚类,它基本上是基于现有特征对相似的点进行分组。无论如何,我不会用算法的细节来烦你,你们大多数人可能已经很熟悉了。我有兴趣讨论的是 k-means 的扩展版:一个可以不时用新数据更新,变得更加信息丰富的 k-means 模型。比方说,今天我们有一个特定产品公司的用户行为的大约一百万个数据点。我们对我们的数据应用 k-means 算法,并使用肘图得出一些 k 聚类。一个月后,我们获得了额外的 10k 个数据点,其中包含我们希望包含在模型中的用户行为的最新信息。
我们应该对整个数据运行 k-means 吗?请记住,在大规模数据集上运行 k-means 可能需要大量计算。我们正在讨论定期更新模型,以包含定期出现的新数据。聪明的做法是用新信息更新现有模型,我们称之为 delta 模型。
新型号=旧型号+ Delta 型号
这是一种简单而强大的技术,用于在生产级别维护模型。我将详细讨论该算法,但让我们先看看经典的 k-means 算法。
经典 K 均值算法
让我们试着从头开始编写 k-means 算法。以下是实现 k-means 算法的步骤:
- 通过从数据中随机选择 k 个点来初始化被称为质心的 k 个聚类中心。还有一种用于初始化中心的技术叫做 k-means++我们在这里不讨论。
- 计算每个数据点与这些中心的距离,并将它们分配给最*或距离最小的中心。
- 通过取一个聚类中所有点的平均值来重新计算聚类中心。这些可能在数据集中,也可能不在数据集中。
- 计算新中心到旧中心的距离总和,我们称之为误差。检查误差是否大于容许值,并重复步骤 2 和 3,直到误差低于容许值,这意味着算法已经收敛。这将是最终的聚类中心和各自的点。
python 中的实现看起来有点像这样:
改进的 k-means 算法
k-means 类可用于训练模型和对新数据进行预测。现在,让我们看看如何整合新的数据和更新我们的 k 均值模型。
- 计算一个新数据点到所有聚类中心的距离,并找出这些距离中的最小值。
- 检查最小距离是否小于阈值。如果为真,我们将新的数据点分配给相应的集群。然后,更新该聚类的聚类中心。
- 如果为 False,则创建一个新的聚类,并将该新数据点指定为其中心。此外,数据点成为集群的一部分。
- 我们可以用一系列新数据点重复相同的步骤来更新我们的模型。我们的模型现在比以前更好,因为它看到了更多的数据。
我们改进的具有更新功能的 k-means 类的代码可以写成这样:
测试阵列中包含了一个示例。干杯!
适用于 20 个样本的 ConvNet:小波散射
原文:https://towardsdatascience.com/a-convnet-that-works-on-like-20-samples-scatter-wavelets-b2e858f8a385?source=collection_archive---------6-----------------------
Scatter Transform architecture, from J. Bruna and S. Mallat, Invariant Scattering Convolution Networks (2012)
通常在数据受限的情况下,场景理解必须在很少的时间序列观察下进行——无论是音频、视频还是雷达。我们使用一种令人惊讶的被低估的叫做小波散射的技术来做到这一点。
小波散射(或散射变换)生成一个对数据旋转/平移不变且对数据变形稳定的表示。数据中无意义的变化会被丢弃,例如,音频样本会时移不同的量。像分类这样的下游任务的信息被保留。小波散射无需训练,适用于低数据。
它的主要计算是卷积,使其快速并适用于图像和 1D 信号。在本文中,我们主要关注信号。我们将追溯信号处理社区的发现,并将其与现代机器学*概念联系起来。我证明,是的,我们可以在没有 学*、使用 20 个样本的情况下做得很好。使用链接中的 colab 笔记本重新创建本文中的实验和插图。
小波
小波可以像滤波器一样与信号进行卷积。我认为卷积是内积的连续模拟,其中大的激活(通常用 ML 表示)或小波系数是由连续对象之间的相似性引起的。通过将字典中的元素卷积到被检测的信号中,我们获得了局部的空间相关性。
卷积是深度学*出现过程中的一个关键计算——它速度极快。本文使用的小波散射实现只为高效卷积调用深度学*后端!Kymatio 是一个伟大的 Python 包,由热情的研究人员构建,利用 PyTorch 框架实现小波散射。
Real and imaginary components of the Morlet Wavelet from M. Adamczyk et al., Automatic Sleep Spindle Detection and Genetic Influence Estimation Using Continuous Wavelet Transform (2015)
小波散射的基本构件是小波小波小波。这是一个高斯窗口正弦曲线,与哺乳动物的听觉和视觉有很深的联系。通过对由不同频率位置 v 索引的小波 ψᵥ 进行卷积, x 的小波变换就是散射系数的集合
{ x∫ψᵥ}ᵥ
当小波的正弦分量有扩展空间(正弦波“减缓”其振荡)时,它以去相关的尺度分解信号。这有利于揭示信号的频率结构,但要在更长的时间范围内进行。结果是更宽的高斯窗口用时间分辨率换取更高的频率分辨率(这本身就是海森堡测不准原理的结果)。在实践中,使正弦波逐渐变细的高斯窗口的宽度是一个重要参数【m . Cohen 2018】。
小波散射
小波散射的历史背景始于傅立叶变换,即典型的信号处理技术。傅立叶表示的缺点包括它对高频信号变形的不稳定性。对于被高频变形为 x ̃而轻微扰动的信号 x ,它们的频谱图表示看起来不同(large‖FFT(x)-FFT(x̃)‖),即使它们对于人眼来说仍然是相似的信号。这种不稳定性是由于正弦波不能定位频率信息,因为正弦本身具有非定位支持。
November, Golden Gardens credit: u/purebredcrab at reddit.com/r/analog
小波变换通过用一族小波分解信号来解决这一问题,小波具有各种伸缩,其中每个小波都有局部支持(最终变平,就像 Morlet 小波一样)。得到的小波表示定位了信号的高频分量。然而,因为小波算子与平移互换,所以产生的表示变成平移协变——平移信号也会平移其小波系数。*这使得翻译信号之间的比较变得困难,而翻译不变性是分类等任务的关键。我们如何实现信号表示φ(x)是平移不变的,在变形下是稳定的,并且在所有频率下提供良好的结构信息?*
小波散射用一个冗余的 Morlet 小波字典建立一个信号表示φ(x)。虽然信号空间 X 可以是真正的高维空间,但是该变换在信号空间上形成了一个核度量,导致了一个较低维的流形。观看 Stéphane Mallat 讨论可视化的流形解释。
读者可能已经训练了一个神经卷积网络,将图像编码成潜在流形 Z ,其代码/潜在表示用于分类或结构发现——这就是类比中发生的事情。**小波散射对数据集 X 进行编码,其中 X 中的无信息可变性:平移、旋转和缩放——组的动作——在该过程中被丢弃。**
φ【j .布鲁纳和 s .马拉特,2013】转换信号的主要好处是
**φ对信号平移不变。
用 xₜ 表示一个与 x 相同的信号,除了在时间上被转换,则φ(x)=φ(xₜ)。
**φ在信号变形下稳定。
即,φ是对变形连续的 Lipschitz 信号与其变形版本的散射表示之间的差异是线性的。一个变形可以是一些局部的位移/扭曲(或者一个可笑的量的扭曲,如后面的例子所示)。对于 Lipschitz 常数 C > 0 和引起变形以产生 x ̃的位移场τ( u ),**
‖(x)-φ(x̃)‖≤c‖x‖supᵤ|∇τ(u)|****
其中‖x‖=∫x(u)杜、 | 、 u ) | 为全局变形幅度。
**φ不需要学*。
小波散射引入的先验足够好,以至于它的性能经常使得学*变得多余;此外,它还带有可解释的特性和输出。在数据受限的情况下,如果可比较的数据是公开可用的,一个很好的计划是通过一个预训练的模型来传输你的小数据集。但是,在数据集较小且唯一的困难情况下,可以考虑将小波散射作为 ConvNets 和其他模型的初始化。我怀疑“数据约束学*”的未来将是协同预定义过滤器和学*过滤器。
下图说明了变形下的稳定性。 Left 我们对说话者说‘零’的声音应用了散射变换。散射表示由从平均/低通滤波器、1 阶小波和 2 阶小波导出的系数组成。右在施加了用正弦波大部分掩盖了原始信号结构的位移场之后,φ(x̃)几乎不受影响;通过φ变换将变形的影响线性化。
卷积网络散点表示由 0 阶、1 阶、2 阶系数组成,通过不同序列的小波合成产生。合成在一起的多个小波捕获高频结构,例如,二阶系数显示信号内的波干扰(在音乐中听起来是不和谐的)。我们现在简要介绍一下计算是如何完成的(复数模数和均值滤波器在附录中有更详细的解释)。
在第 m 层,将第 n 组预定义小波{ ψᵥ₁,…,ψᵥₙ} }与来自第( m-1 )层的属于前一小波ψᵥᵐ⁻的系数进行卷积。在上图中,第一层与ψᵥ卷积,然后是第二层与ψᵥ卷积,得到一行 2 阶系数。
总的来说,我们将小波序列表示为长度为 m 路径为 p =ψᵥψᵥᴹ).通过卷积然后取复数模|⋅|,表示算子 U[ v₁,v₂,…,vₘ].]的结果有序积对于长度为 2 的路径,
u【v₁,v₂】x= | |x∫ψᵥ₁|∫ψᵥ₂|
为了最终提取如上图中的一行系数,应用一个平均滤波器φ,并将其称为 S[ v₁,v₂,…,vₘ]:
S[ v₁,v₂ ] x = U[ v₁,v₂]x∫φ(u)
从数据 x 开始作为根,该小波树中的根路径集指定φ(x)。实际上,最长为 2 的路径足以从自然发生的数据中提取所有相关的频率信息。因此,与小波变换相比,散射变换的显著特点就是 2 阶系数。
A 3-layer scatter network. Notice to extract any coefficients, we must apply the averaging filter Φ. Diagram from J. Bruna and S. Mallat, Invariant Scattering Convolution Networks (2012)
示例任务让我们对真实数据集应用散布变换。自由口语数字数据集(FSDD) 有来自 4 个说话者的 2000 个记录,每个说话者说一个数字 50 次。经过小波卷积后,我绘制了高维系数的 2D t-SNE 投影。每个点是一个音频样本的散点表示φ(x),按数字类别着色。
Blue points belong to class zero? Red is one? Maybe a legend would have been helpful Lihan…
在时间序列分类任务中,竞争技术包括动态时间弯曲、隐马尔可夫模型以及 LSTMs 和 RNNs 之类的神经模型。让我们看看小波散射是如何表现的,即使是在数据极其有限的情况下。作为预处理,我们对音频样本进行 Z 归一化。然后,音频样本被 0 填充到统一长度,并且大约 20 个音频样本被丢弃,以确保分散表示具有相同的维度。继续不学*的实践,我们使用 3 个最*邻作为分类器。3NN(φ(x))预测第 i 位,如果训练集中最接*φ(x)的至少两个邻居属于第 i 位,或者最接*的邻居是第 i (在三向联系中有这种可能)。
对于 1981 个样本,我们发现的三重分类准确率为 91.5% ,对于一个由 20 个样本组成的训练集、、以及保留集、中的所有其他观测值,我们达到了 49% 。还不错,考虑到我只尝试了 Q 超参数(每个八度音程的小波数)的不同值,并留下了其他转盘。在随附的笔记本中尝试不同的比例参数 J 值。
我完成了激发小波散射。在这一点上,如果你开始自己探索这个技术,我会很高兴,也许从我的数字音频 jupyter 笔记本开始。附录深入探讨了小波散射的关键属性,如当 x 为图像时如何利用φ(x)以及实际考虑因素。
他们说需要一个开发团队来开发一篇中型文章。没有包括爱德华、文森特和迈克尔在内的研究人员和开发人员,这是不可能的。我很高兴有机会在 Paul Bendich 的指导下,与政府机构合作,在 Geometric Data Analytics 上解释和利用这项令人惊叹的技术。
附录
实际上,给定路径 p = ( ψᵥ₁,ψᵥ₂),提取二阶系数还需要复数模数 | ᐧ |和平均滤波器 φ:
s【v₁,v₂】x(u)= | |x∫ψᵥ₁|∫ψᵥ₂|∗φ(u)
夏羽·马拉特解释了前人对小波散射,然后对复模数和平均滤波器的需要。
复数模量是小波散射的秘密武器。| ᐧ |是应用于系数的非线性,使它们 1)对微分同胚稳定,2)在欧几里德度量中稳定 L 。复数模量使得φ(x)lip schitz 关于变形是连续的。从视觉上看,模数形成了系数的上包络。
每当φ被应用于系数|x∫ψᵥ|时,我们接受去除高频分量,以便定位覆盖较低频谱的仓(丢弃|x∫ψᵥ|)的相位。为了保留高频信息,散射变换在通过φ定位其不同的频率仓之前,沿着小波路径 p 进一步传播高频信息。
图像的小波散射2D 小波可以与图像数据进行双向卷积。除了伸缩参数,2D 小波可以旋转。
例如,研究人员发现小波散射在纹理图像分类方面表现出色,其中主要障碍是找到一种“缩放”、平移和旋转不变的表示方法——一旦这些组动作从样本生成过程中被排除,纹理分类就很简单了。小波散射所忽略的正是这些可变性。
参数化小波字典当小波的正弦分量有扩展空间时(正弦波“减缓”其振荡),它以去相关的尺度分解信号。这有利于揭示信号的频率结构,但要在更长的时间范围内进行。结果是更宽的高斯窗口用时间分辨率换取更高的频率分辨率(这本身就是海森堡测不准原理的结果)。在实践中,使正弦波逐渐变细的高斯窗口的宽度是一个重要参数【m . Cohen 2018】。
本文中的小波字典由 J(最大对数标度)和 Q(每个八度音程的小波数)来参数化。通过将小波宽度增加一个 2^J.因子,增加 j 以时间分辨率换取频率分辨率。大的 j 意味着发出更少小波系数的“长”小波,导致更短的小波表示。
对于音频信号,较大的 Q 值(介于 4 和 16 之间)通常是有益的,因为这些信号通常具有很高的振荡性,频率比时间更容易定位— kymatio 教程
对于信号处理从业者来说,散射变换的小波形成了一个非正交的冗余字典。
信号能量保持不变小波卷积的合成保持了信号范数,或者基本上保持了信号能量。这是因为小波变换是一种收缩的可逆算子。在沿路径的每个卷积之后,平均滤波器将原始信号内的能量转换成“系数能量”。对于加州理工学院-101 图像数据库,【j .布鲁纳和 s .马拉特,2013】显示,对于任何 j 值,深度为 3 的网络保存了约 99%的信号能量
大规模使用空间的几个技巧
原文:https://towardsdatascience.com/a-couple-tricks-for-using-spacy-at-scale-54affd8326cf?source=collection_archive---------2-----------------------
Python 包 spaCy 是自然语言处理的一个很好的工具。下面是我在大型数据集上使用它所做的一些事情。
Me processing text on a Spark cluster (artist’s rendition).
编辑:这个帖子现在已经过时了(看看一些评论)。自从我写这篇文章以来,SpaCy 引入了一个 ***pipe***
方法,它做了我在这里所做的事情,只不过它不需要黑客,而且更快。建议大家都用那个方法。
当我正在做的项目需要自然语言处理时,我倾向于首先求助于 SpaCy。Python 还有其他几个 NLP 包,每个包都有自己的优缺点。我通常发现 spaCy 很快,它的约定很容易学*。
我在 Spacy 遇到的一个困难是需要处理大量的小文本。例如,我最*有几十万个不同的标签,每个标签有 1 到 15 个单词,我决定用 word2vec 来比较它们。我对 spaCy 的单词矢量化很满意,但我还需要处理每个字符串,首先删除不相关的单词和词性,对一些标记进行词汇化,等等。花了很长时间。以下是我加快速度的两种方法。
将所有内容作为一个文档处理,然后拆分成多个部分
处理一堆独立记录的直观方法是分别处理它们。我开始遍历每条记录,并对每条记录调用 spaCy 的nlp
。我不知道处理每件事要花多长时间,因为我已经没有耐心了,只是在进程结束前就终止了它。所以我想了想,又读了一些文档,得出了这个结论:
这将所有文本连接成一个字符串,每个原始文本由一些字符序列分隔,这些字符序列不太可能自然出现。我选择了三个管道,每边都有一个空间。然后我给nlp
打了一次电话。处理大约 25,000 条记录只需几秒钟。之后,我可以遍历标记列表,识别特殊的字符序列,并使用它将文档分割成多个部分。这些跨度包含单独的标记,并且具有文档的属性,例如单词向量。
使用火花
这并不像听起来那么简单。根据我的经验,做 NLP 最昂贵的部分是加载语料库。一旦你把所有的东西都装上了,就只需要高效地查找你需要的信息了。如果你正在使用 spaCy 提供的最大的英语语料库,就像我一样,你将面临一些困难来把这些语料库放到你的 Spark 执行器上。
首先,spaCy 使用了与 PySpark 不同的 pickling 库,这导致在试图将语料库包含在用户定义的字段中时出错——无论是作为广播变量还是其他。无论如何,序列化庞大的语料库,然后将它转移到执行器,然后再反序列化,这不一定有意义,因为您可以将它加载到执行器本身。
这提出了一个新问题。加载语料库需要很长时间,所以你想尽量减少需要加载的次数。我发现,在将 Scikit-learn 模型部署到 Pyspark 时,遵循我过去使用的一个实践非常有用:将记录分组到一个相当长的记录列表中,然后调用列表中的一个 UDF。这允许你做一次昂贵的事情,代价是必须连续做一小组相对便宜的事情。
我的意思是:
因此,我将我的 spark 数据框随机分成 20 个部分,将我所有的文本收集到一个列表中。我的 UDF 从 spaCy 加载语料库,然后遍历文本进行处理。
需要注意两件事:
- 我在一个循环中分别处理每个文档。我没有理由要那么做。我可以使用第一个技巧,将所有文档作为一个整体处理,然后拆分成多个部分。这两个技巧并不相互排斥。
- 出于我的目的,我只需要单词向量,所以这就是我返回的全部内容。我不知道 PySpark 是否很难将整个 spaCy 文档或 span 对象从执行者那里移回来。我从来没试过。无论如何,我发现使用 Spark 只获取自己需要的东西是一个好*惯,因为移动东西是很昂贵的。所以如果你只需要单词向量,写一个只返回这些向量的 UDF。如果您只需要命名实体或词类之类的东西,编写一个 UDF 来返回它们。如果您需要所有这些内容,请在 UDF 中将其分离出来,并作为单独的字段返回。
使用这两种方法,处理大量文本对我来说变得更有效率。
证明停机问题的速成教程
原文:https://towardsdatascience.com/a-crash-course-on-proving-the-halting-problem-3579fdcd114?source=collection_archive---------8-----------------------
以非正式的严谨方式解释
A plan for Charles Babbage’s Analytical Engine circa 1840, which would have been a Turing complete mechanical computer had it ever been built. CC BY 4.0
在一堂课上,老师解释了“我”:
《我是围的声音》他说
当学生要求解释他的意思时;大师说“它是你头脑中的一个声音”
“我脑袋里没有声音”学生想,他举起手告诉大师
大师叫住学生,说“刚才说你脑袋里没有声音的声音;是我”
然后学生们就开窍了。
杰夫·贝索斯在推特上宣布:“我将提供 10 亿美元给一个人,他可以编写一个程序,可以测试任何和所有其他可以想象的程序,看看在一些输入下,它们是否在有限的时间后产生正确的输出,或者永远继续运行。”
您立即开始在您的黑暗主题 IDE 中噼啪作响,并迅速着手为项目编写 Python 类结构。但是在你的内心深处,你感到某种不祥的预感,好像来自以太的一些深奥的知识在悄悄地警告你即将到来的徒劳。
正如所证明的,一般来说不可能编写一个程序或算法来确定任何任意的程序或算法(包括它自己)是否在某个任意的输入上停止或者永远继续运行。更有甚者,在所有可能的输入下,更不可能确定所述程序是否会停止或永远运行。在这篇文章中,我们将谈论前一个事实。
为了便于讨论,让我们假设我们的算法是完美的,并且除了暂停之外,将总是产生正确的结果。我们可以把一个通用算法(非正式地)想成类似于一个巨大的查找表(一个函数),它把一些输入 x 映射到它相应的输出 y = f( x ),并且在 100%的时间里都可以预测。然而,与查找表不同,该算法可以由经典编程意义上的决策语句(if,else)、循环和递归组成,因此它是一个具有开始和结束状态的“动态”过程,它在输入 x 上计算一些输出 y 或永远继续运行。上述问题被称为停机问题,由艾伦·图灵于 1936 年著名地证明,根据他发明的算法的正式定义及其相关的计算模型,即现在普遍称为图灵机是不可计算的。事实上,并不是所有的函数都是可计算的,所以我们的算法不同于查找表函数,尽管上面的类比是有用的。
为了理解为什么会出现这种情况,请思考一下,我们将以一种非正式的严谨方式讨论兼容性和停顿问题背后的一些想法。事实上,我们甚至不需要正式定义什么是算法,也不需要像图灵机这样的计算模型。我们只会对一般的可计算性做简单的论证。
从一些定义开始。目前,我们提供给算法或程序的所有输入都是自然数 N 的子集,因此我们的输入由单个整数组成,如 2、3、12、23 或2^82589933 1及其组合(在传递多个参数 x 、 y 、 z 到 f ( x 、 y 的意义上)这个想法就是,我们关心的输入到算法或函数中的唯一输入可以用自然数来编码。
定义 1 :一个函数p(x)= y带 x , y ∈ N 称为部分可计算 (p.c.) 如果有一个算法在定义 y 时停止,但在 y 时不停止(发散)该算法计算出 y 的值或一些相关值。直观上,部分函数 p 是不需要 p 将域 X 的每个元素 x 映射到共域y的元素的函数
部分可计算函数的一个例子是带余数的非负整数除法。下面用 a , b ∈ Z+: 定义
a**b=p(a,b)= {φ(a, b ) = q ,rifb如果 b 为 0,则未定义
在上面,实体 φ 是实际用来计算整数除以余数的结果的算法或过程,也就是函数 p 。我们可以很容易地从小学回忆起,带余数的除法规则定义得很好,适用于所有非负整数 a 和 b ,除了当 b 为 0 时。无余数的正则非负整数除法也是部分函数。
定义 2 :一个函数 f 是全可计算的或者简单的可计算 i f 它被定义在它的输入子集 N 的整个定义域上,并且存在在f的定义域上停止的算法
我们可以用一些技巧使一般的整数除法(没有余数)可计算:
a**b=p(a,b)= {φ(a, b ) = q , r 如果 b 不为 0;南如果 b 为 0 }
注意,如果 b 为 0,我们将 aNaN作为输出,并且我们还升级了算法φ来处理负整数。从技术上讲** 我们的函数是为 a,b ∈ Z 的整个定义域定义的,根据著名数学家乔治·康托的工作,这个定义域的大小与自然数 N 的某个子集的大小相同,或者是可数无穷的。*
*关于技术细节,它是数学和一阶逻辑中证明方法的基础,因为数学中的许多定义都相当精确,所以最好接受它。以后的证明将直接依赖于我们自己创造的定义的技术细节。
定义 3: 对于某个算法 φₖ 一个(输入的)集合叫做可计算可枚举(也就是说,递归可枚举这个术语也很流行)如果它在一个 p.c .函数 p = φₖ 的域内。也就是说,如果所有元素 x 导致 φₖ 停止或导致 φₖ 分叉,而不是两者,则集合 X 在 φₖ 中是 c.e .
可计算可枚举的性质归因于特定的集合和特定的算法。因此,我们可以说整数集合 Z 是整数除余数算法的集合,因为在 Z 中有值导致除余数算法给出未定义的输出(例如 0 和负数)。同样, φₖ 对于某种计算模型来说是唯一的,但是所有具有正确特征但彼此仅略有不同的确定性计算模型在图灵意义上是等价的。因此,我们可以说 φₖ 是计算模型 T. 中所有可能算法集合中的第 k 个算法
定义 4:称为 X 的 N 的子集是可计算的或递归的,如果它有一个可计算的特征函数或指示函数😗*
I( x ) = { 1 如果 x 在 X 中;如果 x 不在 X 中,则为 0
因此,指示器功能必须停止,并在整个域 N 上给出真或假的结果。
既然我们已经建起了操场,是时候去玩一玩了。在证明为什么停机问题是不可计算的之前,让我们先问一个问题:
在一个理发师只给自己不刮胡子的人刮胡子的城镇里,谁会给理发师刮胡子呢?在这个镇上,妻子、单身女子、母亲、孩子和外地人都不能给任何人刮胡子。
如果理发师不刮自己的胡子,那么他必须刮自己的胡子,反之,如果理发师刮自己的胡子,那么根据定义,他就不能刮。这是罗素悖论的一个应用版本,它询问所有集合中不包含自身的那个集合是否存在。罗素悖论是试图在“所有集合的集合”这一概念被从标准集合论的公理中丢弃之前找到这一概念的幼稚想法的直接结果。另一个有趣的逻辑矛盾是著名的第 22 条军规:
申请工作需要工作经验,但是要获得工作经验就需要一份工作。
原来我们可以用这些矛盾来表明某些前提(一个逻辑假设)的反面或复合前提一定是真的,即如果我们已经逻辑地推导出一个矛盾的前提,那么原前提的否定一定是真的。这就是著名的反证法技术。例如,罗素悖论的存在意味着所有集合中的一个集合不可能存在。注意,可计算性理论中的许多重要定理,有点像机器学*中的,是非构造性的。换句话说,这个定理可能假设某个特定事物的存在,或者排除其他事物的存在,但实际上并没有提供这个事物的一个例子,所以这个证明可能是不直观的,完全不可思议的,但这就是可计算性的工作方式。
停机问题的设置导致了一个矛盾;让我们将一个暂停集 H 定义为一组所有程序或算法,它们在一些任意输入时暂停。如果我们只讨论 H 的某些子集,这个证明就不会如此深刻。直觉上,这是一个可以接受的定义——尽管我们很快就会看到这是一个天真的定义。回想一下,在我们的计算模型 T 中,所有 k 索引算法都是唯一的。
定义 5:h:= {(k,x* )使得算法或程序 φₖ 在输入 x 时停止运行***
定理 1: H 不可计算。
证明:
假设 H 是(总)可计算的,那么它一定有一个可计算的指示函数 I( k , x )由 Def。4.如果 H 中的程序停止,该指示灯输出 1,否则输出 0;
I( k , x ) = { 1 如果 φₖ 停在x;0 否则}。
假设我们按如下方式制作一个程序φₘt57】:
φₘ(x):={ 1 如果我( m ,x)= 0;如果 I( m , x ) = 1,则未定义**
函数 φ ₘ的伪代码如下所示:
**def *φ*ₘ():
if I(*φ*ₘ):
while 1:
pass
return 1**
φ ₘ在 H (由于 φ ₘ在某个输入 x 上停止),也是 p.c .(记住,只有指标需要是可计算的总量)。现在观察当我们将指标函数应用于ₘ:时会发生什么
我们想确定 φ ₘ是否在 x. 上停止。如果指示器 I( m ,x)= I(φₘ(x))确定φₘ(x)停止,那么根据 φ ₘ的定义,它一定不会停止如果指示器确定 φ ₘ没有停止, φ ₘ必须停止并返回定义 1。在这种情况下,没有反对递归自引用的规则,因为 H 的定义足够宽泛,可以包含这样的程序。既然我们得出一个矛盾,我们就不能假设 H 是可计算的。 □
显示 H 是 c.e .留给读者作为练*(提示:我们能为 H 建立一个 p.c .指示器函数吗?).
这类似于罗素悖论,因为我们对集合 H 的(幼稚)定义允许这样的 φ ₘ,其中当且仅当 φ ₘ不停止时 φ ₘ停止。在 H 的定义中所有程序的规定就是允许这种矛盾发生的原因。这看起来像是循环推理,从抽象的角度来说就是,但是当我们假设 H 是可计算的时候,我们对 H 的定义承认了这种矛盾。因此,为了保持 H 的一致性,我们必须拒绝它,因为它是可计算的。
课程在现实生活中,如果我们小心避免编写类似于 φ ₘ的程序,那么我们的磕磕绊绊的测试人员可以在真实的程序上实现实际的性能,只是受到时间的限制。停滞问题的影响当然是显著的。可以想象,我们可以构建一个元系统来观察暂停检查器的子系统是否会遇到暂停问题。但是,我们需要多少元系统来覆盖它们下面的系统呢?情况变得像一个无限的套娃。令人着迷的是,人类可以从这些停止检查元系统的无限回归之外意识到这种情况,但也可以随意切换到这些系统的任意级别,并从外部和内部对它们进行推理。事实上,这就是一些人认为的意识的标志性特征。正是这种力量让库尔特·哥德尔、艾伦·图灵、阿隆佐·邱奇等人在 20 世纪 30 年代证明了几个关于逻辑、计算和数学基础的深刻而又相关的定理
如果我们能建立一个确定性的,甚至是基于机器学*的停机测试器,来分析 CPU 指令,以确定一个程序是否正在进行有用的计算,或者是否已经进入了无用的无限循环,这将是一件有趣的事情。如果你喜欢这篇文章,请检查我的其他文章,如果你发现任何明显的错误或逻辑漏洞,请让我知道。
*如果你有风险资本,有兴趣投资这个创意,请联系我。
补遗:
预计到人们会抱怨上面的证明是“手动的”或者太不正式(毕竟,我们大踏步地采用了递归自引用,并且没有很好地定义指示器将如何检查 φ ₘ是否停止),我将在下面给出一个更加严格的证明。
我们将使用图灵机 T 的直观定义作为运行确定性过程的机器,满足以下条件:
- 能够进行循环和条件分支,并且是有状态的
- 能够运行子程序
- 能够复制数据(例如将数据复制到子程序中)
- 能够永远停止或者运行
这台机器 T 将计算函数 I( m , x )如果它是可计算的。缺乏对 T 的精确定义不会过多地妨碍我们对这个证明的理解。
定理 2(定理 1 重述): I( m , x )不可计算。
证明:**再次假设 I( m , x )是可计算的。为了避免怪异的递归自引用,我们做的一件事就是将 φ ₘ的源代码,S( m ) = φ ₘ作为输入提供给 I,即 I( φ ₘ, φ ₘ).在图灵机定义中,程序 φ ₘ和它们对应的源代码只是唯一的、真正大的自然数。从机械上讲,在 H 中给某个程序输入一个非常大的自然数是没有错的,即使这个数字是 φ ₘ本身的唯一“源代码号”。在这种情况下,函数调用自身时没有递归。
现在我们在下面定义一个程序控制函数 h (我们的候选停止检查器):
h(φ):= { 0 if I '(φ,φ)= 0;否则未定义}**
注意我们有一个不同的指示函数 I’。我们对可计算的定义只谈到了可计算指标的存在,它们不需要完全相同,但是它们应该表现相同(一致性)。计算h(φ)的程序在 H. 中,因此我( m , x )将能够检查 h ( φ )是否停止。我们将 h ( φ )的来源馈给 I( m , x ),即 I( h , h )。将 I( h , h )视为我们的第一级暂停元检查器。
当 h ( φ )在某个程序源代码 φ 上运行时,如果 I’(φ, φ )没有暂停,而 I( h,h )返回 1 表示 h 暂停,当 I’(φ时发散根据可计算性的定义,我们不能让程序同时暂停和分叉(考虑一下h(φ)I 的一个子程序( h , h ))。因此 I( m , x )是不可计算的。 □
链接到我的其他文章:
- 张量流和自定义损失函数
- 随机森林
- Softmax 分类
- 气候分析
- 曲棍球骚乱和极端值
一种创造性的特征选择方法
原文:https://towardsdatascience.com/a-creative-approach-towards-feature-selection-b333dd46fe92?source=collection_archive---------31-----------------------
品格如树,名誉如影。影子就是我们对它的看法。这棵树是真的。——亚伯拉罕·林肯
简介
谈到特征工程,特征选择是最重要的事情之一。我们需要减少特征的数量,以便我们可以更好地解释模型,使训练模型的计算压力更小,消除冗余效应,并使模型更好地一般化。在某些情况下,特征选择变得极其重要,否则输入维度空间太大,使得模型难以训练。
执行功能选择的各种方式
有多种方法来执行特征选择。我将使用我自己在实践中使用的方法。
- 卡方检验(分类变量对连续变量)
- 相关矩阵(连续变量与连续变量)
- 领域知识
- 线性正则模型的系数。
- 树方法的特征重要性(最喜欢这个)
我的创作方法
在这里,我提出了我的创造性观点,如何使用以上我最喜欢的方法来进行特征选择,而不是仅仅局限于其中一种。核心思想是结合相关矩阵(每个变量与目标变量比较)、线性正则化模型的系数和各种树方法的特征重要性,使用随机加权平均将它们结合起来。使用随机加权是为了避免对某一种单一方法的固有偏见。所以,最后,我们有了一个最终的特征重要性矩阵,它综合了我最喜欢的特征选择方法。与研究各种方法相比,在我们面前有一个单一的产出数字总是一件好事。
概念证明
为了展示概念证明,我将使用波士顿住房数据集。这是一个回归案例,所有输入变量都是连续的。
- 首先计算整个数据集的相关矩阵。这里只做这个,因为所有变量都是连续的。在有一些分类变量的情况下,我们需要使用卡方统计而不是相关矩阵。
Natural values of linear correlation with respect to target variable
Absolute Linear correlation with respect to the target variable ‘MEDV’
2.选择套索和山脊计算变量系数。
Lasso natural coefficients
Ridge natural coefficients
Normalised and absolute values of lasso coefficients
Normalised and absolute values of ridge coefficients
3.选择 GradientBoostingRegressor、RandomForestRegressor、DecisionTreeRegressor 和 ExtraTreeRegressor 来计算特征重要性。在实践中,在此步骤之前,分类变量的所有转换都应该完成(例如,使用一个热编码或标签编码)。
Decision Tree Feature Importance
Random Forest Feature Importance
Extra Trees Feature Importance
Gradient Boosted Trees Feature Importance
4.使用 numpy 进行随机采样,为每种方法赋予权重,然后取加权平均值。
这里,我们使用了随机权重生成方案,其中,对于任何形式的特征选择机制,我们都不使用 0,并且为了简单起见,值或权重以 0.1 为步长。
5.然后,我们返回合并的结果,可以使用条形图显示。
结论
还有各种其他的特征选择技术,但我提出的这个可以提供一个非常不同的视角,使用一种我最喜欢的特征选择技术的集合来比较特征与目标变量的相关性。你可以摆弄各种参数,让这个想法更有创意。还可以使用具有更具体设置的模型,例如使用树模型对象,根据具体的使用情况,用 n_estimators 或 max_depth 的一些具体值初始化,但这里只是为了展示我使用默认模型对象的想法。
这一思考过程不仅有利于得出最终的一次性特征重要性输出,而且我们可以直观地看到数字和图表,以比较不同方法如何独立执行,然后就输入变量的选择做出明智的决定。
就像爱因斯坦的名言 一样,我相信直觉和灵感。我有时觉得我是对的。我不知道我是。
第三次民主辩论的数据分析
原文:https://towardsdatascience.com/a-data-analysis-of-the-third-democratic-debate-67094c363083?source=collection_archive---------40-----------------------
辩论数据能告诉我们谁赢了吗?
Photo by Kyle Head on Unsplash
在许多方面,政治似乎已经取代棒球成为全国性的消遣。就像体育博客和 ESPN 争论球类运动一样,新闻网站和 CNN 的专家们也沉迷于政治竞选的细枝末节。
本着体育赛事的政治精神,我认为从这个领域再偷一招——体育统计——会很有趣。内特·西尔弗和其他人完善了民意测验专家的艺术,但我希望能更进一步。正如 Sabermetrics 让我们对棒球世界有了新的认识,我希望政治数据可以让我们对政治前景有更好的看法。为此,我分析了上一次民主党辩论的记录,并分析了数据以寻找趋势。这是我的发现。
关注并不总是随着投票而来
就数据而言,新闻报道的一条信息是说话时间。理论上,越受欢迎的候选人应该得到更多的时间,因为观众对他们要说的话更感兴趣。实际上,情况并非如此。
下面是两个对比图。左边是最新早间咨询民意调查的图表。右边是每位候选人在 9 月辩论中的发言字数。
Left — Democratic Polling : Right — Words Spoke during Sept Debate
不出所料,领先的乔·拜登在辩论中获得了最多的字数。然而在他下面,投票和发言时间之间有很大的差异。民调支持率仅为 3%的科里·布克参议员几乎和前副总统说得一样多。当然,大部分都是在辩论接*尾声的时候。尽管如此,它还是说明了当权派候选人是如何在电视上受到优待的。
有趣的是,时间充裕的伯尼·桑德斯在说的单词方面几乎垫底。很明显,他比他的对手说得更慢,用的词更少。我还观察到,他不太愿意超过分配给他的时间,也不需要像其他候选人那样被打断。
最后,不管你怎么看,杨安泽在辩论中被欺骗了。在大多数民意调查中,杨的表现优于奥罗克、布克、卡斯特罗和克洛布查尔。然而,他在电视上只说了少得可怜的 1600 字。这并不奇怪,因为杨经常被主流媒体忽视,以至于他有时会被完全从政治报道中抹去。
好斗能获得播出时间
当比较候选人的发言时间和他们的投票时,观察到的最大差异是朱利安·卡斯特罗。尽管民调支持率只有 1%,他说的话甚至比皮特·布蒂吉格还多。这主要是因为卡斯特罗利用他的演讲时间发动了攻势。
冲突造就了好的电视节目,所以卡斯特罗有足够的机会与乔·拜登辩论。这是有数据证明的。如果只看候选人发言的次数(包括简短的交流),我们会发现卡斯特罗做得非常好。
这一策略是否会提高他的支持率还有待观察,但很明显,继续攻击将会获得更多的播出时间。
沃伦和桑德斯最受观众欢迎
辩论笔录中最能说明问题的一句话是“(掌声)”。如果我们计算每个候选人的掌声次数,我们就能知道谁在现场观众中表现最好。
令人惊讶的是,领先的乔·拜登几乎排在名单的末尾。只有艾米·克洛布查尔(Amy Klobuchar)不太受与会者的欢迎(我预计她很快就会退出)。
伯尼·桑德斯和伊丽莎白·沃伦支持的进步议程最受民主党人欢迎,这或许不足为奇。在描述他们的“全民医保”计划时,两人都获得了积极的观众反应。
科里·布克会讲笑话
另一个值得注意的词是“(笑声)”。让观众发笑是让他们喜欢你的一个简单方法。在这方面,科里·布克做得最好。他在晚上得到了一些很好的笑点,特别是当他自嘲他的纯素食饮食时。
布克作为一名沟通者如此娴熟,而且他如此受媒体喜爱,这一事实表明他可能是这场竞选中的一匹黑马。如果卡玛拉·哈里斯开始下滑,我预计更优雅的布克将取代她的位置,成为一个迷人和可口的中间派候选人。
每个候选人都专注于“人民”
我们可以从这场辩论中收集到的另一个数据是哪些词用得最多。如果去掉“会”、“必须”、“美国人”等无聊的政客词汇,就能统计出每个候选人最常用的词汇。这些术语用下面的单词云表示。
纵观领跑者,无一不是在呼吁“人民”。这个词是最常见的。这些诉求的性质因政治家而异。拜登专注于“事实”和“数字”,表明他试图显得务实。桑德斯和沃伦花更多的时间谈论“医疗保健”、“保险”和“公司”。沃伦从“家庭”的角度谈论个人,而桑德斯从“国家”的角度看待事物。
中间派候选人也对“人民”有吸引力。哈里斯通过她反对“特朗普”,布克通过呼吁“社区”。皮特·布蒂吉格词云的平淡表明他的中心思想是模糊的,难以确定的。
最后,在低层候选人中,我们观察到一些有趣的趋势。奥罗克在提到得克萨斯州和埃尔帕索时大多处于高位。杨想给人们钱,并与私营公司合作解决医疗保健问题。克洛布查尔大概说“我认为”太多,也想“团结”人。最后,卡斯特罗正在努力推动自己的医疗保健“计划”,同时也在攻击其他候选人的计划。
最后的想法
《金钱球》出版后,统计数据开始主导体育评论和分析。同样的事情还没有发生在政治上。大多数专家仍然依靠直觉来描述政治形势,只有当民意调查出来时,他们才会接受现实的检验。有了推特、新闻报道,以及现在的电视辩论,我们有了大量的数据来进行更客观的分析。随着时间的推移,我相信这些工具将会有更好的预测能力。
肯巴-垂怜经“互换”的数据驱动分析
原文:https://towardsdatascience.com/a-data-driven-analysis-of-the-kemba-kyrie-swap-24241f136d29?source=collection_archive---------26-----------------------
使用 Python 的数据科学模块来分解统计数据和高级指标,看看哪个球员更适合波士顿凯尔特人队。
这个 NBA 淡季是整个联盟运动的焰火。仿佛是很久以前,凯里·欧文离开小镇去了布鲁克林和凯文·杜兰特一起打球。不到一年前,垂怜经声称自己热爱波士顿,并将长期留在这里。然而,与其他波斯顿球迷不同的是,我很难将对垂怜经的憎恨藏在心里,因为作为一名球员,我太喜欢他了——这与本文的观点无关。
现在让我们波士顿球迷惊讶的是夏洛特黄蜂队的肯巴·沃克有兴趣来凯尔特人队打球。这很奇怪,因为 1)沃克似乎打算留在黄蜂队,2)波士顿似乎真的是从他想要的比赛目的地冒出来的。我们都知道他在康涅狄格大学做了什么,当他在三月疯狂锦标赛中投篮命中,最终带领哈士奇队赢得男子大学篮球冠军
无论如何,让我们进入这篇文章的主题。让我们试着剖析谁赢得了这场“交换”,谁是更好的球员,以及我们可以期待什么。我们在这里只分析有形的东西,所以我们不能考虑无形的东西,比如化学反应和球员对教练的反应。
在我们真正分解它之前,让我们看看一些基本的统计数据(所有统计数据都来自 basketball-reference.com)。我将使用 Python(尤其是 matplotlib 模块)来生成一些图形。让我们开始吧。
Points Per Game (career)
让我们来看看与控卫位置最相关的数据。传统上和历史上,控球后卫的位置是控制比赛节奏的位置。很自然地,我想到了两个数据:得分和助攻。垂怜经职业生涯 22.2 PPG,肯巴 19.8 PPG。
Assists Per Game (career)
如果我们看看助攻,数据更相似,肯巴是 APG 的 5.5 次,垂怜经是 APG 的 5.7 次。他们职业生涯的平均得分和平均助攻都非常相似。垂怜经是更有天赋的球员,所以我们可以把更高的 PPG 归因于此。虽然垂怜经在职业生涯中受益于更好的队友,但他仍然平均每场比赛只多 0.2 次助攻,这可能表明肯巴可以在球队中服务得更好。即使当垂怜经在凯尔特人,一个可以说更有天赋的球队打球时,他平均只有 6.1 个 APG,只比他在骑士队的平均水平高出 0.6 个 APG,只比他的职业生涯平均水平高出 0.4 个 APG。
既然我们比较了传统控球后卫的标准数据,让我们来看看现代 NBA 中非常重要的东西——三分球。
在我们继续深入之前,值得注意的是,虽然垂怜经和肯巴都打了 8 个赛季——他们都是在 2011 年的选秀中被选中的,分别在第 1 和第 9 选择,肯巴打了 97 场比赛,尽管垂怜经在他参加的所有 508 场比赛中都是首发。让我们来看看三个百分点和总数:
垂怜经和肯巴场均 2.1 3 分。然而,垂怜经的投篮命中率更高,平均每场 5.4 次,而肯巴每场 5.9 次。虽然这看起来不是一个巨大的差异,但实际上肯巴的三分球命中率为 35%,而垂怜经的命中率接* 39%。
总数再次描绘了一幅相似的画面。做出来的 3 个百分点显然和上面一样。肯巴更多的尝试(和失误)可以归因于更多的比赛。然而,话虽如此,肯巴在他职业生涯的 605 场比赛中投进了 1283 个三分球,而克里在 508 场比赛中投进了 1063 个三分球。如果我们假设一切保持线性,让垂怜经打 605 场比赛,他将会投中 1266 个三分球,这在某种程度上是可以比较的。
到目前为止,有两点需要注意——这些数据基本上没有让我们得出更适合的现实结论;也就是说,我们只是看到了两个伟大的控球后卫职业生涯中的平均水平。包含每 36 分钟的统计数据并没有什么意义,因为两位球员都打了首发级别的比赛(肯巴每分钟 34.1 分钟,而垂怜经每分钟 33.8 分钟)。我认为更能说明问题的是最*几个赛季,以及一些更先进的指标。
所以我们来思考一下为什么要看*几季。有几个原因。首先,我们想看看谁更适合波士顿凯尔特人队的整体。这意味着我们只想看看垂怜经的最后两个赛季,并将它们与肯巴的赛季进行比较。我们可以在这个概念上加倍下注,因为肯巴从 2017 赛季开始才成为全明星。无论你是否认为他在那之前应该是全明星球员,这都不会帮助我们,所以让我们深入了解过去两个赛季的统计数据和高级指标。让我们把最基本的东西弄清楚。
PPG,APG 和 3PT%是我们想再看看的。
再一次,这个数据有点不确定,因为在过去的两个赛季中,肯巴场均 23.85 次 PPG,而垂怜经场均 24.1 次 PPG。APG 也是如此,肯巴和垂怜经分别为 5.75 和 6 APG——尽管垂怜经上赛季的确有职业生涯最高的 6.9 APG,这可以归功于更好的队友,我们很快就会看到这一点。
在过去的两个赛季中,垂怜经是一个神奇的三分射手,他的三分命中率为 40.4%,而肯巴只有 37%。垂怜经的能力,尝试和艰难的运球投篮(三分)不能被忽视;联盟中可能没有其他球员更擅长创造自己的投篮机会勒布朗球迷对我的愤怒加剧
值得注意的是,在过去的两个赛季中,肯巴几乎参加了所有可能的比赛,只缺席了两场比赛。肯巴打了 162 场比赛,而垂怜经打了 127 场。肯巴的长寿是一个巨大的加分点,但在肯巴的三个全明星赛季中,黄蜂队都没有进入季后赛。在某种程度上,我们可以再次将这归因于他周围的团队,我们将查看一些高级指标,看看谁更适合。
高级指标
如前所述,在肯巴的每个全明星赛季,夏洛特黄蜂队都没有资格进入季后赛。垂怜经上赛季无疑拥有他职业生涯中最好的配角,但作为一个团队,凯尔特人队只获得了 49-33,低于上一年的表现。黄蜂队以 39 比 43 结束了比赛。为了更好地了解支持强制转换,让我们更深入地了解指标。
在 37 场比赛中一起出场最多的黄蜂队首发阵容是尼克·巴图姆-杰瑞米·兰布-肯巴·沃克-马文·威廉姆斯-科迪·泽勒。这个阵容取得了 19 胜 18 负的战绩,是他们所有首发阵容中最好的胜率(51.4%)。另一方面,波士顿凯尔特人队的首发阵容一起打了 33 场比赛,19 胜 14 负,胜率为 57.6%。这个问题中的阵容是艾尔·霍福德-凯里·欧文-马库斯·莫里斯-马库斯·斯马特-杰森·塔图姆。这可能会让某些人感到震惊,因为 1)我们付给戈登·海沃德很多钱,对他期望很高,2)杰伦·布朗似乎有退步的迹象。如果我们更深入地观察,我们会发现实际上有两个 5 场比赛的首发阵容非常出色。阿隆·贝恩斯-艾尔·霍福德-凯里·欧文-马库斯·斯马特-杰森·塔图姆的阵容以 80%的胜率取得了 4 比 1 的胜利,艾尔·霍福德-马库斯·莫里斯-特里·罗齐尔-马库斯·斯马特-杰森·塔图姆的首发阵容以明显的 100%胜率取得了 5 比 0 的巨大胜利。
艾尔·霍福德、马库斯·莫里斯和阿隆·贝恩斯已经不在队里了。因此,这将对我们如何让肯巴适应凯尔特人产生明显的影响。在我们尝试将这些放在一起之前,让我们看一下 2018-2019 赛季的 win share 相关指标。我们将关注 VORP(价值超过替代球员)。如果我们把一个玩家的 VORP 乘以 2.7,我们得到他们的战争(胜于替换)。由于比例是线性的(2.7 倍),所以在数据可视化方面并不重要,所以让我们看看 2018-2019 赛季的 VORP。
这里我们有凯尔特人队首发阵容的 VORP,他们一起打了 33 场比赛。凯里·欧文拥有最高的 VORP,为 4.7,占 VORP 首发阵容的 41.6%。欧文得益于艾尔·霍福德的帮助,他的得分是 3.4。
如果我们看看黄蜂队的 VORP 图表,我们看到肯巴实际上在整个 VORP 中占了更高的百分比,为 41.9%。肯巴的个人 VORP 是 3.9,但没有一个艾尔·霍福德类型的人来帮助他。整个团队中第二高的 VORP 是尼克·巴图姆,1.7 分。所以很明显,垂怜经确实有更好的配角。
为了更好地了解支持阵容,让我们看看没有肯巴和垂怜经的阵容。
很明显,凯尔特人的队友上赛季比黄蜂的队友打得更好,分别是 17.82 分和 14.58 分。
以我们对凯尔特人阵容的了解,让我们看看如果我们把肯巴放入肯巴-马库斯·斯马特-杰森·塔图姆-杰伦·布朗-伊内斯·坎特的最佳阵容会发生什么。我承认这不会是完美的,因为 1)伊内斯·坎特的 VORP 上赛季不会很好,因为他取代了正在经历职业生涯赛季的努尔基奇(所以我们将使用他职业生涯的平均水平 VORP ), 2)我们不知道首发阵容会是什么,这意味着我们不能真正在杰伦·布朗或戈登·海沃德身上下注。
事实上,杰伦·布朗的 VORP 值为 0.0。海沃德的 VORP 指数实际上是 1.2,这让我感到意外,可能也让所有人感到意外。我们应该期待布朗和海沃德在没有垂怜经的情况下在本赛季向前迈进一步。
我会把前面提到的 more 瓦尔和垂怜经/肯巴的对比放在另一张图上,但这并不能说明什么,因为垂怜经的 VORP 是 4.7,而肯巴是 3.9,所以它只会持续 0.8。
所以这些数字告诉我们,就纯生产而言,凯里·欧文和肯巴·沃克之间并没有巨大的差距。正如我之前提到的,我只考虑了有形资产。我试着不偏不倚,但根据这些数据,凯尔特人队的总胜率比上赛季更好并不是不可能的。老实说,VORP/战争的数据告诉我们,霍福德是更大的损失,因为他上赛季 3.4 的 VORP 远远超过了预计的中锋伊内斯·坎特,他上赛季的 VORP 为 0.6(但职业生涯的 VORP 为 2.1,尽管仍有所下降)。
很明显,这不是一篇完美的文章,也不是对名单和两名球员的分析。我这样做有几个原因:
- 了解篮球运动中的高级指标
- 使用 Python 中的数据分析模块来实现数据可视化
我会很高兴地感谢任何反馈!我知道网上已经有其他工具来做我所做的这种类型的分解,但我这么做只是为了好玩,因为它结合了我最喜欢的两件事:篮球和编码(尤其是 Python)。我完全打算把这样的东西放在一起,可能会看看科怀·伦纳德和保罗·乔治的新阵容。展望未来,我希望:
- 实施机器学*模块来预测最佳阵容
- 从 Basketball-Reference.com 导入 CSV(逗号分隔值)格式的数据,这样我就不用硬编码值了。通过这种方式,我可以创建一个项目,该项目具有对任何球队的任何球员进行分析的类和函数。
- 与前一个项目相反,因为我可以引入一个 CSV,所以我也可以使用 Pandas 模块。
最后,万一垂怜经或肯巴看到这个:这只是一个软件工程师在找乐子,并试图学*。我对你们以及你们为凯尔特人所做的/将要做的一切只有爱。
感谢阅读!
图像来源:
- https://bleacher report . com/articles/2835452-尼克斯-谣言-凯里-欧文-给予强烈考虑-肯巴-沃克-雷达
- https://www . nytimes . com/2011/03/11/sports/ncaabasketball/11 uconn . html
人格模型的数据科学方法
原文:https://towardsdatascience.com/a-data-science-approach-to-personality-models-d3c7e18a377?source=collection_archive---------8-----------------------
1。简介
我个人一直觉得人们在行为方式上的差异很有趣,所以这项研究将让我们对此有更多的了解。我们将洞察一个人的特征如何与他们的性格特征和*惯相关联,甚至能够根据一些人口统计数据进行预测。
特别是,大多数当前的性格测试利用了普遍接受的 5 因素模型,也称为海洋,以组成它的 5 个因素的首字母命名。
对经验的开放。(创新/好奇vs一贯/谨慎)
C .责任心。(高效/有条理与随和/粗心)
[E]外向。(外向/充满活力与孤独/保守)
宜人性。(友好/富有同情心与挑战/冷漠)
神经质。(敏感/紧张与安全/自信)
该模型基本上是一种被该领域专家普遍接受的人格特征分类方法,因为它允许捕捉人与人之间最相关的人格差异。然而,它也是辩论和批评对象。
有人认为,作为一种解释性或预测性理论,五大模型的范围是有限的。也有人认为,五大人格量表只占正常人格特质的 56%。
一个常见的批评是五大人格不能解释所有的人类人格,事实上,一些心理学家不同意这个模型,因为他们觉得它忽略了人格的其他方面。由于这个原因,一些人已经开始把五大心理学称为“陌生人心理学”,因为他们指的是陌生人身上相对容易观察到的特质,而其他更私人化或更依赖于背景的个性方面被排除在外。
鉴于范围限制的批评,也许可以开发一个新的心理测量模型,以找到相关的维度或替代的潜在因素来解释人格的差异。因此,这成为本文的核心,我将在下面的章节中详细解释。
2。数据
这个数据集不是以海洋方法为基础的,它是一个有趣的答案集合,通过个人兴趣、性格特征、生活方式和个人特征,回答了从音乐偏好到恐惧症等一系列不同的问题。它是通过调查收集的,调查对象是 1010 名年龄在 15 至 30 岁之间的欧洲人。顺便提一下,答案中几乎没有缺失值,但是由于样本量足够大,我们可以小心地完全删除这些行。要了解问题列表的更多信息,请参考附录。
抽样单位是按行组织的单个回答。在列中,我们可以找到变量。我分析的重点是,一方面是基本特征,另一方面是个性特征。
基本特征
性别。分类,男,女。
年龄。数值变量,但按照以下标准转换为序数变量:
- 1:15–19 哟
- 2:20–24 哟
- 3:25–30 yo(比其他组多花一年时间,但有意义,因为就受访者而言,该组人数较少)
教育。序数变量。类别如下:
- 1:小学
- 2:中学
- 3:大专学历
- 4:硕士学位和博士学位(我加入了他们两个,因为受访者中很少有博士)
受访者度过大部分童年时光的地方。类别:
- 村庄
- 城市
性格特征
更准确地说,这份名单不仅包括性格特征,还包括对生活的信念和看法,在我看来,这些都可以追溯到性格特征。
它由 54 个问题组成,所有问题都有 1 到 5 级的建议答案,1 表示强烈反对,5 表示强烈同意。实际上有 57 个,但为了简单起见,删除了 3 个,因为它们与其余的性质不同。
其他感兴趣的数据
除了个性数据,还有关于兴趣、音乐偏好、恐惧症和生活方面的问题。
答案的范围也是从 1 到 5。
3.方法学
为了进一步实现我们的目标,即找到人格特质与一个人的特征之间的关系的有价值的见解,先花些时间研究一下人格特质的问题列表是很方便的。在这个意义上,我们说的是一个因素分析。背后的理由是双重的。
首先,我们希望能够在相似的维度上对变量(问题)进行分组,而不损失信息的能力,换句话说,我们希望降维。这很方便的原因是因为向前看,使用几个变量比使用很多变量要方便得多(记住我们在谈论 55 个问题,所以有 55 个变量);尤其是关于将来使用回归技术的前景。因此,简而言之,这就好像我们在为随后的分析筛选变量。
其次,它将允许我们发现潜在的结构,这些结构也许可以建立一种人格测试的替代心理模型。
因此,由于没有创建变量时使用的模型,或者我们可以与之进行比较的任何参考,我们需要探索是否可以找到潜在的相关维度,因此该分析实际上是一种探索性因素分析。
一旦基本原理清楚了,我们该如何进行呢?
首先,对变量之间的相互关系有所了解是有好处的。为此有两个选项,一个是绘制关联热图矩阵,另一个是对所有问题运行 PCA ,以查看它们在前两个维度上的回归,并观察它们如何相互关联。请注意,主成分分析是一种降维方法,但出于此目的,最好利用其他方法。正如我们将在结果部分看到的,两者都是计算出来的。
特别是,使用基于 Ward 最小方差凝聚法的系统聚类绘制了相关可视化。Ward 的聚类遵循在树的每个节点处合并两个聚类的标准,其中它试图最大化新聚类的均值与其他聚类的均值的分离,这相当于最小化新组合的聚类内的离差。r 包 Corrplot 允许我们计算这个。
在此之后,使用的方法是主轴分析。这里的要点是提取因子后的旋转,以不断寻找潜在结构。使用的旋转方法是 varimax 旋转。R 中的 Factanal 包用于计算这一点。
此时出现的一个问题是,我们需要执行多少次旋转?意思是,我们在哪里停止得到因子或维度?
在这里,scree 图就派上了用场。scree 图描绘了变量(问题)相对于因子数的相关矩阵的特征值。在这个问题上,R 中的 Nscree 包帮助了我们。
一旦我们提出了解释原始变量中观察到的大多数差异的少量因素,我们的想法是根据人的特征回归它们,以便对人进行区分或分类。这是通过分类和回归树(CART)完成的。
回归树开发了易于可视化的决策规则,用于根据一些相关变量以某种方式预测分类变量。r 也被用来计算这个,特别是 rpart.plot 包。
这基本上是项目主干中使用的方法。然而,除此之外,我想得到一些其他的见解。特别是,我想分析健康的生活方式。为此,我求助于对应分析。其主要目的是在地图(通常从投影到平面上的多维空间)中直观地描述答案之间的关系——从 1 到 5,1 表示非常不同意,5 表示非常同意,回答以下陈述“我过着非常健康的生活方式”;和类别,在这种情况下,变量是性别、年龄(分组)和教育。
4.结果
在开始之前,可以在附录中找到的原始问题列表也已经用数字给出,以便于可视化,因为 54 个变量一起有时使得有时难以阅读图表。
主成分分析
首先,让我们看一下进入前两个维度的主成分分析。为此,我们需要对数据集应用 PCA,如下面的代码所示。
Thanks to Prof. Michael Greenacre for its PCA customized function
运行代码后,结果如下所示:
在这里,我们可以对变量在前两个维度中的关系有一个粗略的*似。我们可以看到,他们解释的方差约占 16%,这表明我们最好探索并考虑更多的维度。
查看 PCA,例如在维度 2 中,我们可以看到有一组变量,稍后我们将能够更详细地看到它们,它们是非常负相关的(由相反的箭头表示),这些是问题 52、47 和 31,即兴趣或爱好、能量水平和朋友数量,而不是问题 27 和 24,即改变过去(悔恨、忧郁)和孤独。正如我们所看到的,双方都唤起了完全相反的感觉。
相关性热图矩阵
现在让我们更详细地看看问题之间的关系。下面是相关矩阵。
x 和 Y 轴显示了 54 个问题。这种排序已经给出了一些想法和提示,告诉我们在计算因子分析时会发现什么。特别地,矩阵单元中每个正方形的大小和颜色指示了每对之间的皮尔逊相关系数的强度。
此外,我随意突出显示了 9 个矩形,这些矩形显示了相似特征之间的分组。例如,问题 2、3 和 4(从右下角开始的第二个矩形)、“优先处理工作量”、“写笔记”、“工作狂”等概念包含了一个潜在的相似概念,即勤奋,努力工作的动力。(请注意,样本单位是 15 至 30 岁的年轻人,因此在大多数情况下,他们相当于工作的老年人正在学*)。此外,有趣的是,我提到的这个组与问题 25、51(从左上角开始的第三个矩形)、“学校作弊”和“早上起床困难”负相关,这完全说得通。
无论如何,上面的相关性矩阵是一个很好的起点,但是要告诉我们的是调查问题下面的主要潜在因素,是因素分析。
所以让我们开门见山吧。
要素分析
首先,我们定义一个函数来画出我们将要得到的维度和它的参数。
然后,我们调用 factanal 包,使用 varimax 旋转法获得因子。
最后,我们在包含因子的变量上调用之前定义的函数。
阅读以下因子图的方法基本上是关注 X 轴和 Y 轴的极值标签,因为它们是表征或解释每个维度的大部分方差的标签。换句话说,它们代表每个因素最高负荷的变量。
因素 1
Dimension of factor 1 can be read horizontally and the one for factor 2, vertically
同样,每个变量的含义可以在附录中找到。
F1. Positiveness
我称之为积极因素,因为他们与积极的感觉有关,看起来他们是积极的人,感觉快乐,精力充沛,晚上做好梦,对自己和自己的个性有积极的想法。在光谱的另一端,我们发现那些感觉不好的人是因为他们感到孤独(正如我们在前面展示的相关性矩阵中看到的那样,与“生活幸福”和“能量水平”非常负相关),他们经历负面情绪可能是因为他们不积极,如悔恨和愿意改变过去,以及情绪不稳定。
因素 2
F2. Extroversion
第二个因素是外向/内向性格维度的有效测量。那些外向的人发现与新的人一起进入和适应新的环境是容易和令人兴奋的,喜欢认识新的人,有大量的朋友,有许多兴趣和爱好,而且他们也更容易变得自信。自信并不总是容易运用的东西,因为关系的另一部分可能不会很好地接受它,一个内向、更敏感和一般朋友较少的人可能想要避开。另一方面,我们看到内向者的典型特征(内向的春天),当被很多人包围时,他们往往会感到不舒服,所以他们往往不喜欢/害怕公开演讲;他们也倾向于反复思考,因此做决定和回复一封严肃的信需要时间。内向的人也倾向于内省,因此平均来说比外向的人更担心健康,这也是有道理的,毕竟,内向的人比外向的人更能意识到他们内心发生的事情,所以发现健康异常并沉思它们对他们来说比外向的人更有可能发生。
因素三
Dimension for factor 3 can be read vertically
F3 — Diligence
第三个维度是勤奋。正如我们在简要评论 PCA 时提到的,这个因素代表了那些勤奋工作的人,他们可以被认为是有纪律的、勤奋的人,因此也是可靠的。像写笔记和工作狂这样的概念清楚地反映了这一点。其他如优先考虑工作量和提前考虑可能不太明显,但仔细想想,以系统的方式做这件事并不容易,让我们说舒服,所以它显示了一定程度的勤奋和动力,以按时完成任务。另一方面,我们有那些早上起床有困难的人,他们在学校有作弊的倾向,简而言之,这些人通常更懒,也不那么勤奋。
因素 4
Dimension for factor 4 can be read vertically
F4 — Warmth
第四个人格维度是“温暖”,是善良、敏感和诚实的概括。它反映了个性的各个方面,例如,对他人的同情,看到他人痛苦时的痛苦,该给礼物时的慷慨,当一个人感到挣扎时的哭泣,以及享受孩子的陪伴。前两个表示同理心,第三个表示善良,第四个表示不克制表达情感如哭泣的人,所以诚实地反映他们的真实情况和感受;第五宫也显示出温暖,毕竟,小孩子很爱玩,经常微笑,这迫使他们以某种方式回报,所以如果有人有点冷淡、严肃或不想被这种事情困扰,就会倾向于喜欢少一些孩子的陪伴。
在光谱的另一端,我们有那些双面的人,那些喜欢大的危险的狗而不是小的狗的人,和那些容易爱上某人但很快失去兴趣的人。它们看起来似乎是毫无关联的话题,但对我来说并非如此,因为它们描绘了那些倾向于在他们周围筑起一堵墙的人,这样其他人就看不到他们是谁或他们的感受。第一个似乎显而易见,因为他们直截了当地说出来,第二个可能与那些通过想要给人留下强大和危险印象而建起一堵墙的人相匹配,第三个反映了那些在敞开心扉、展示真实自我、在更深层次上同情和联系他人方面有很多困难的人,因此他们很快失去兴趣并不断更换伴侣。
因素五
Dimension for factor 5 can be read vertically
F5 — Superficiality
我把第五个因素称为肤浅,在某种程度上代表了那些把形象和地位看得非常重要的人物,这通常与物质主义、自我中心和浅薄联系在一起。在我看来,第一个变量将个人关系的重点放在了解一个人对他/她可能有多大用处上,这在我看来是自私的,第二个变量与他们对自己身体形象的重视程度有关,第三个变量反映了那些吹嘘自己成就的人。
另一方面,我们有远离物质主义和自私的人格特征,因为第一个问题回答了那些上交丢失物品的人,这些物品虽然有价值,但不是他们的;第二个回答了那些把朋友看得比金钱更重要的人。
到目前为止,我们提出了一些因素,除了有意义之外,它们还解释了变量的值的变化。因此,在这一点上出现的问题是,选择多少因素?
上面的碎石测试对此有所启发。我们可以看到,有 17 个特征值高于 0,这告诉我们,有多达 17 个因素至少可以解释一些方差。10 被认为是因素的最佳数量,然而我尝试了,他们除了没有多大意义之外,几乎不能解释差异。所以,根据我的发现和对特征值曲线上因素数量的直观探索,我们可以看到随着曲线斜率的减小,增加新的因素似乎并不能捕捉和解释大量的方差,所以我决定在 5 个因素处停止。
能够将 54 个问题归结为 5 个维度,并获得所有变量的大部分方差,这似乎很棒。这是因素 1:积极,F2:外向,F3:勤奋,F4:热情,F5:肤浅。
但是在进入分类树之前,还有一个缺口需要填补。
如前所述,这个想法是为了简化变量,我们已经这样做了,但是,我们知道归入因子的变量有相反的符号。如果我们不转换这些因素的组成部分,我们就不能真正反映它的本质。例如,“生活中的快乐”给那些对自己和自己的生活感到非常快乐的人打 5 分,但我们也可以找到“孤独”,它给孤独的最大强度打 5 分,因此如果我们听其自然,一个快乐的人会给“生活中的快乐”打 5 分,给“孤独”打 1 分,所以我们的平均得分是 3 分。然后,一个孤独、消极的人给“生活中的快乐”打 1 分,给“孤独”打 5 分,平均再打 3 分。如果两个完全相反的人,就这种人格特征而言,给维度相同的平均值,我们如何能期望维度在人的特征上正确分类?
似乎很明显,必须进行变革。我所做的是反转“相反”变量的评级,因此转换后的 1 是 5,2 是 4,以此类推。将此应用于所有获得的因素,我们可以计算平均值,并在接下来的分类模型中将其用作解释变量。
回归树
我们在这里要做的是分类并预测一个人属于所分析的特征变量的给定类别的概率,给定他们在树的每一层的最有区别的维度上的分数。
年龄
根据数据部分中确定和解释的群体,我们可以从树的顶部节点看到,最大的受访者群体属于 20 至 24 岁的人。顶部节点(和每个节点)的第二行代表分别属于第一、第二和第三组的预期概率(相当于它们的频率)。
我们可以看到,勤奋维度得分 3.2 更有利于预测 25 至 30 岁的人(从观察到的 9%至 15%)。然后,低于 3.2 的勤奋,低于 3.1 的积极,但高于 4.2 的热情是进一步帮助预测有利于“中年”人的组合(从观察到的 48%到 75%)。最后,更好地预测最年轻者(15-19 岁)的组合是勤奋低于 3.2,积极高于 3.2,肤浅高于或等于 3.9。
因此,总之,该树将“年纪最大”的人归类为受访者中最勤奋的人,最年轻的人归类为最肤浅、最不积极和最不热情的人,而“中年人”归类为最积极的人,然而,如果受访者在积极方面的平均得分低于 3.1,根据该模型,他们将是最热情的人。
童年地点
简而言之,该模型预测最热情和最不肤浅的人在乡村度过了相当长的童年时光。平均热情得分高于 4.2 和肤浅低于 2.7 的组合预测回答者有 63%的概率在农村度过童年。如果我们考虑到它们只占观测值的 29%,那就相当高了。所以根据这些因素和这棵树,城市意味着更少的温暖和更多的肤浅,这似乎很准确。
性别
简而言之,更多的温暖(平均分数为 3.4%)预测有利于女性,从 59%的女性受访者中高达 78%。同样,当试图对人们进行性别分类时,最具歧视性且似乎更相关的因素是温暖因素。平均分数低于 2.7 的人有 80%的可能性是男性(41%的男性回答了调查)。
对应分析
一旦分析了项目的主干,让我们把注意力从人格特征转移到人们的生活方式上。
特别是,其目的是获得一些关于健康的生活方式是如何由性别、年龄和教育等特征决定的直观见解。
对于“我过着非常健康的生活方式”这个问题,人们被要求强烈同意(5)、同意(4)、中立(3)、不同意(2)或强烈不同意(1)。
这里有一些年龄性别和教育的交叉列表。
“ma”和“fa”分别代表男性和女性,而 1、2、3 对应于我们在数据部分解释的最年轻、中年和最年长的人。
性别-年龄
对应分析对我们的目的来说很方便。让我们按性别-年龄来看一看。
在上面的 CA 图中,我们可以看到所包含的维度分别解释了总惯性的 72.4%和 16.2%,对于二维解决方案,总共解释了 88.6%,这似乎是一个非常高的值,表明与剩余维度相关的其余惯性实际上与解释差异无关,因此所使用的二维是解释类别差异的最佳维度。
从地图上我们可以推断出什么?
第一个维度由生活方式总体健康的人与生活方式极端的人之间的对立决定,也就是说,要么生活方式非常健康,要么生活方式总体不健康。
第二个维度似乎把偏离整体利益的符号分开了。
所以,我们可以在第一维的一边观察女性,在另一边观察男性。这意味着总体而言,年轻女性比年轻男性更关注健康的生活方式,观点的可变性似乎比男性更少分散和“两极化”。而对于男性,我们可以看到最年轻的(15-24 岁)和成年人(25-30 岁)之间的明显区别,成年人遵循非常健康的生活方式,而年轻人则相反,特别是年轻男性,他们似乎平均遵循相当不健康的生活方式。
教育
这一次,总惯性的 99.3%由双标图的 2 个维度解释,这证实了这是解释变量间差异的最佳维度数。
特别是,我们可以观察到,与受过高等教育的人相比,受教育程度较低的人的平均生活方式往往不太健康。
无论如何,让我们对此持保留态度,因为由于取样单位的年龄从 15 岁到 30 岁,年龄与研究高度相关。
5.结论
我们应用因子分析得出了有趣的个性维度,这些维度可能无法从遵循海洋方法的标准问卷中捕捉到。从他们身上,我们已经能够看到部分不同的人格因素,这些因素可能是替代人格心理测量模型的基础。在对获得的因素使用回归树之后,我们也能够为不同的基本分类特征找到有趣的分类。
限制可能是导致获得 5 个维度的解释性因素分析应该继续进行验证性因素分析,以便建立具有统计显著性因素的模型。这肯定会是我为这种项目设想的扩展。
6.参考
https://www . ka ggle . com/nowaxsky/visualization-and-prediction-of-shopping-habits/data
https://cran . r-project . org/web/packages/corr plot/corr plot . pdf
https://www.statisticssolutions.com/factor-analysis-2/
https://github . com/rsangole/personalitytracfactoranalysis/blob/master/FA _ Traits。R
https://www.statmethods.net/advstats/factor.html
https://cran . r-project . org/web/packages/nf actors/nf actors . pdf
http://www.milbo.org/rpart-plot/prp.pdf
http://trevorstephens . com/ka ggle-titanic-tutorial/r-part-3-decision-trees/
https://en.wikipedia.org/wiki/Big_Five_personality_traits
[## 什么是内向的人?一个深入的解释——内向的春天
内向和外向出现在一个谱上。这意味着有不同程度的内向。没有人…
introvertspring.com](https://introvertspring.com/what-is-an-introvert/#whatisintrovert)
7.附录
人格特质陈述/问题列表
斯托克霍姆公寓价格的数据科学方法
原文:https://towardsdatascience.com/a-data-science-approach-to-stockholms-apartment-prices-part-1-dcee0212596d?source=collection_archive---------20-----------------------
SE 公寓项目
用 Python 中的 Web 抓取获取和清理数据
项目背景
被认为是世界上价格最高的房地产市场之一,我认为斯德哥尔摩的公寓市场可以作为一个有趣的案例研究,有很多有趣的数据。将大部分数据转化为易于理解的有用见解,并建立一个预测未来公寓房源销售价格的模型。
我还决定确保用一个数据科学家处理这个问题的方式来处理这个问题,处理一些现实情况下会出现的头痛和挑战。这意味着我想挑战自己,将可用的数据转换成可以实际使用的干净数据。
注意:通常这个角色包括提出一个对业务有益的具体目标。但是在这种情况下,我选择了一种非常通用的方法,我还不知道我可能在寻找什么样的模式。
“数据科学家是能够获取、筛选、探索、建模、和解释数据、融合黑客技术、统计学和机器学*的人。数据科学家不仅擅长处理数据,还将数据本身视为一流产品。— 希拉里·梅森 ,快进实验室创始人。
在这里阅读这个项目的下一部分:
用机器学*把数据变成洞察和预测器。
所有源代码都在这里:
https://github . com/gustaf VH/Apartment-ML-Predictor-Stockholm _-with-web scraper-and-Data-Insights
项目目标
1.收集在线可用的真实生活数据,并能够收集、清理和过滤这些数据成一个高质量和高数量的数据集。这次没有干净的 Kaggle-datasets 的捷径。
2.根据收集到的数据,制作一个机器学*模型,该模型基于相关的 f 特征,如大小、房间数量和位置,以可行的准确度对其销售价格做出准确的猜测,从而实际上被认为是有用的。
3.将我收集的所有数据转化为洞察力,希望能教会我一些关于斯德哥尔摩房地产市场的令人惊讶或有用的东西。
使用的特殊工具
- Python :整个项目都是用 Python 编写的,因为它对这个领域的库有很大的支持
- Selenium(Python):流行的在 Chrome 中执行网页抓取程序的端到端测试软件。
- 熊猫&Numpy:Python 库为易于使用的数据结构和数据分析工具。
- [Yelp API](# https://www.yelp.com/developers/documentation/v3/business_search):API 接收附*的兴趣点以及基于地址的坐标。
- Seaborn&Matplotlib:Python 的数据可视化库旨在直观地展示我们的结果。
获取良好和丰富的数据。
为了开始这个项目,我需要好的数据。从这个意义上说,好的数据意味着它主要满足两个要求,质量和数量。就质量而言,重要的是我们的数据具有不同的属性(特征),这些属性与我想要了解和预测的内容相关。如果我想预测一套公寓的销售价格,好的特征将是,例如,公寓的大小,它的位置,房间数量,何时售出等等。
我可以在 Hemnet 上找到所有这些数据,这是一个瑞典的公寓列表网站,所以我决定使用这些数据。
关于网络抓取非常重要: 就我而言,我绝不会将此作为商业产品或用于任何金钱利益,但始终尊重其他人或公司的数据,并确保您总是仔细检查适用于网络抓取的内容,以免侵犯版权。
Demo of how my Selenium Web Scraper works by automatically controlling an instance of Chrome.
简而言之,Web Scraper 的工作原理是打开 Chrome 浏览器窗口,导航到 Hemnets Stockholm 列表,获取该页面上的所有公寓列表,然后导航到下一页,重复这个过程。
我遇到并幸运解决的一些问题:
- Hemnet 将每个搜索查询的列表限制为 50 页。我以此为契机,在公寓大小之间获得了均匀分布的数据。我将我的搜集工作分成 20 个查询部分,每个部分对应于一个特定的公寓大小,然后我告诉搜集者为我搜集。为了前任。一部分是面积在 20 至 25 平方米之间的所有公寓。这导致我得到:
每页 50 个列表 50 页 20 段= 50,0 00 个列表** 现在我也有了比以前更好的数据传播,结果非常好!
segments = [20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 250]*for* i in range(0, (len(segments)-1)):
driver = initCrawler(segments[i], segments[i+1])apDataNew = getRowsFromHnet(driver, 50)
apData = apData.append(apDataNew, *ignore_index*=True)
- 谷歌广告横幅。这些都很棘手,因为它们的类是动态的,当我试图点击“下一页”按钮时会导致 Scraper 误点击。不幸的是,这导致 Scraper 在我的例程中多次获得相同的页面,因为它有时没有正确地点击下一页按钮。正因为如此,在删除重复的条目后,我最终得到了 15 000 个条目,而不是 50 000 个。然而,我没有深究这个问题,因为幸运的是,15 000 仍然是足够继续下去的数据。
- iframe 中的隐私策略弹出窗口。每次都弹出来,因为我们处于匿名模式,需要点击。原来它是在一个 iframe 中实现的,这使事情变得复杂,但是用 Seleniums 窗口管理工具解决了。
在 Yelp 的帮助下,为我们的数据添加特征。
在 Yelps API 的帮助下,我们可以得到很多基于某个位置的细节信息。例如,通过发送地址,我们可以获得该位置的坐标(纬度和经度)。这非常有用,因为我们现在可以将基于字符串的地址,如“Hamngatan 1”转换成更可量化的东西,如两个数字。这将使位置成为一个可用的功能,以后创造的可能性,几何比较公寓的位置。
此外,我们还接收兴趣点功能,以添加到我们的公寓数据集。这被定义为 Yelps 认为值得列出的地方的数量,这些地方在公寓的 2 公里以内。你可能会问,这有什么关系?它之所以相关,是因为它可以表明你的公寓位于市中心的位置,这可能会反映在销售价格中。因此,添加这个特性可能有助于我们以后在模型中的准确性。
response = yelp_api.search_query(*location*=adress, *radius*=2000, *limit*=1)*return* (latitude, longitude, pointsOfInterestsNearby)
清理、擦洗和过滤数据
这是我认为我学到的将问题应用到现实世界的最多的部分,因为数据从来没有像你希望的那样被很好地格式化和干净,这次也不例外。首先,我开始清理数据并重新格式化:
- 改变日期顺序并制作数值。我使用 python 字典结构将月份转换成数值。
*# 6 december 2019 --> 20191206* df.Date = [apartment.split(' ')[2] + (apartment.split(' ')[1]) + (apartment.split(' ')[0]).replace('december', '12')
- 将除地址和经纪人之外的所有特征都变成数字(浮点数)。
- 削减销售价格。从“Slutpris 6 250 000 kr”转换为“6 250 000”。
- 删除错误获取的坐标。Yelp API 确实在一些情况下认为一个地址在瑞典完全不同的地方,并返回这些坐标。这可能会扭曲数据,因此如果一个公寓的坐标明显超出斯德哥尔摩的范围,整行都会被删除。
df = df.loc[17.6 < df['Longitude'] < 18.3]
df = df.loc[59.2 < df['Latitude'] < 59.45]
- 添加新的组合功能 PricePerKvm。由于奖金与公寓的面积密切相关,直接比较不同面积公寓的价格并不能显示价格有多合理。为了直接比较奖品,我创建了一个名为(PricePerKvm)的新功能,即价格除以平方米。
请击鼓:我们的最终数据集
经过大量的清理、擦洗和过滤,我们最终得到了一个包含 14 171 套公寓房源的数据集,这些房源具有 9 种不同的特征。
[Sample of 5 out of 14 171 entries]
在这一部分中,我了解到数据科学项目中的大部分时间将包括收集和清理数据,因为从时间上来说,这一部分几乎占了整个项目时间的 80%。现实生活中的数据很少按照你想要的方式进行清理、过滤或结构化。它也不总是统一的,所以对于下一个项目我想接受将不同类型的数据集结合成一个的挑战。
当谈到这个数据集时,它应该是我们下一部分的足够数据— 建立一个预测性的机器学*模型,并将数据转化为见解!
在这里阅读这个项目的下一个故事:
用机器学*把数据变成洞察和预测器。
所有源代码均可在此获得:
https://github . com/gustaf VH/Apartment-ML-Predictor-Stockholm _-with-web scraper-and-Data-Insights
斯托克霍姆公寓价格的数据科学方法
原文:https://towardsdatascience.com/a-data-science-approach-to-stockholms-apartment-prices-part-2-13e51772b528?source=collection_archive---------22-----------------------
SE 公寓项目
通过机器学*将数据转化为洞察和预测
这个故事的目标和上一个故事的摘要。
在之前的故事中,我们探索了如何获取和清理数据。虽然清理和过滤的时间比预期的要长,但我们最终得到了一个非常干净的数据集。为了唤起你的记忆,我们现在把这个作为我们的数据集:
Sample of 5 out of 14 171 apartment listings with 9 different features.
拆分数据进行验证。
我们的数据集中大约有 14 000 个条目,这对训练我们的 ML 模型非常有用。训练我们的模型,需要大量的数据,所谓的训练 数据。但是为了检查我们模型的性能,我们还需要数据,即所谓的验证数据。在这里,平衡很重要,因为如果我们的训练数据太少,我们的模型将无法在足够的数据上进行训练并且不准确。另一方面,如果我们没有足够的验证数据,我们就不能确定我们的模型在以后测试时的准确性。注意:我们也可以使用交叉验证,但是因为我们有大量的数据,收益会很小。
出于这些原因,我选择对数据进行 3/4 分割,这意味着 75%的行用于训练,25%用于验证。
建立机器学*模型。
训练我的机器学*(ML)模型的第一步是考虑我应该包括的特征,这也很重要。根据直觉和以前对公寓的了解,我决定选择:‘日期’、大小、【附*位置】、【房间】、【纬度】、 和‘经度’。 选择要包含和排除的正确特性对于我们模型的性能非常重要,所以我们稍后将返回来对此进行调整。但是让我们从这个开始,看看我们最终会怎样。
如何建模
这个问题将是一个回归任务,很可能会过度拟合。因此我最终决定使用一个 随机森林树 。因为它是一种集合方法(一种使用不同评估平均值的方法),所以它可以很好地对抗过度拟合,并且通常在很少调整其超参数的情况下产生非常好的结果。
因为它是一个决策树模型,我们也不需要标准化数据来避免某些特性比其他特性更优先。
现在,我们用训练数据训练模型,并对照验证数据进行测试。
I wrote a function that calculates the accuracy in Mean Absolute Error or Mean Absolute Error Percentage. Follow the links if you want to learn more but the short story for both measurements is that the closer to 0, the better.
嗯,不完全是一个伟大的公寓价格预测。这意味着我们的模型的预测将会平均偏离24%或者超过 1 000 亿 SEK。我们肯定可以改进这一点。那么我们如何优化这一点呢?
特征工程和优化
我绘制了特征的相关性,以发现使用我们训练的模型及其特征最好包括哪些特征。
feat_importances = pd.Series(trainedModel.feature_importances_, *index*=trainFeatures.columns)
feat_importances.nlargest(numOfFeatures).plot(*kind*='barh')
Which feature that has the biggest impact on the price. The higher the value, the bigger the impact. This means Size affects the pricing the most.
我最终决定选择: 【大小】【邻*点】【纬度】 和 【经度】 因为它们对价格的影响最大,你可以在这里的图表中看到。
我遗漏了租金,因为在这种情况下,我们知道租金但不知道价格,反之亦然,似乎没有必要包括在内。
我在这个实例中使用了大量的优化,但这超出了本文的范围。然而,经过这些优化后,我们最终获得了以下性能:
Shows how close the predictions were to actual pricing (in SEK). X-Axis: What the prediction model predicted the price would be. Y-Axis: Actual Price for the apartment. Each dot represents one apartment listing and the red line is the linear fit of all predictions.
更好的是,我们的模型可以预测销售价格,平均为 390,000 SEK 或实际价格的 8.4 %。
这里需要注意是,对于这种精确度,我们只使用 4 个特征:‘大小’,‘邻*点’,‘纬度’,和‘经度’,来获得这种精确度。因为附*的点、纬度和经度都来自地址,我们实际上只需要两个特征。这为什么让人印象深刻?这意味着我们的模型只需要公寓大小和地址就可以达到 91.6%的准确率。
我们为什么不干脆赋予模型所有的特性呢? 多多益善吧?不,这样做通常会导致过度拟合——其中模型学*训练数据太好,意味着噪声和离群值也包括在其预测中,而不是学*一个通用公式,这正是我们要寻找的。
结论:将数据转化为见解。
在这一点上,我们有干净和有组织的数据和预测销售价格的 ML 模型。最后,我想总结一下这项研究给了我们哪些有益的启示。
先说实际数据。这是我们所有数据行的汇总。它显示了所有 9 个特征数据的平均值、标准偏差、最大值和最小值。
Summary of 14 171 rows of data.
假设从 Hemnet 获得的数据代表了斯德哥尔摩的公寓市场,我们可以得出结论:斯德哥尔摩公寓的:
- 中间价是 390 万 SEK。
- 租金中位数是 2 800 SEK。
- 房间数量的中位数是 2。
此外,我们可以比较所有功能之间的关系(它们的相关性),以了解每个功能如何相互影响,而不仅仅是价格。
Shows how much each feature is dependent on each other. For example, the Size is entirely dependent on itself, so its value is 1 (green). The lower (red, -1) or higher (green, 1) the value, the more dependency.
从这个图表中,我们可以看到一些并不令人惊讶的事情,房间很大程度上取决于大小。但我们也可以总结出一些我们之前可能不知道的关于斯德哥尔摩公寓的事情:
- 经度很大程度上取决于附*的兴趣点。含义:附*好玩的地方(餐馆、酒吧、学校等)的数量。根据 Yelp) 这很有趣,取决于你是住在西斯德哥尔摩还是东斯德哥尔摩,东斯德哥尔摩有更多附*的景点。
- PricePerKvm 对经度的依赖程度是纬度的两倍。意思是如果你住在东斯德哥尔摩,你的公寓可能会更贵。
当然,还有很多需要建立的联系,但这些是我个人最喜欢的。
最后,我想再次回到这个关联图,它显示了每个特性对价格的影响程度。
Which feature that has the biggest impact on the price. The higher the value, the bigger the impact. This means Size affects the pricing the most.
我发现最令人惊讶的一点是,房间数量对价格的影响是如此之小。含义:
- 无论是多一间房还是两间房,一套公寓的价格都没有太大差别。在这种情况下,最重要的是平方米的大小。
我们还可以从该图中得出结论,大小、邻*点、纬度和经度是对价格影响最大的特征。其中三个完全取决于位置。含义:
- 位置决定一切并将极大地影响定价。
为了展示斯德哥尔摩的价格变化,我决定直观地展示一下。
Shows the geographical positions of the most expensive apartments. X-Axis: Latitude, Y-Axis: Longitude, Z-Axis: Sales Price / Square Meters (SalePricePerKvm)
如你所见,模式确实存在。如你所见,最高点(黄色)位于 stermalm 的中部。
本案例研究的主要收获
对于斯德哥尔摩的公寓:
- 中间价390 万 SEK。
- 租金中位数是 2 800 SEK。
- 房间数的中位数是 2。
- 附*有趣的地方(餐馆、酒吧、学校等)的数量。根据 Yelp) 的说法,这些都很有趣,这取决于你是住在斯德哥尔摩西部还是东部,那里的东部有更多有趣的地方。
- 如果你住在东斯德哥尔摩,你的公寓很可能会更贵。****
- 一套公寓的定价是没有明显的不同** 不管它有一个额外的房间还是两个房间,如果它不增加更多的平方米。**
在这里阅读之前的故事:
用 Web 抓取获取和清理数据。
所有源代码均可在此获得:
https://github . com/gustaf VH/Apartment-ML-Predictor-Stockholm _-with-web scraper-and-Data-Insights
Python 数据科学案例研究:Mercari 价格预测
原文:https://towardsdatascience.com/a-data-science-case-study-with-python-mercari-price-prediction-4e852d95654?source=collection_archive---------6-----------------------
Photo by Myriam Jessier on Unsplash
学*数据科学最有效的方法是解决与数据科学相关的问题。阅读、倾听和记笔记是有价值的,但是一旦你解决了一个问题,概念就会从抽象固化成你有信心使用的工具。通常,一个完整周期的数据科学项目包括以下阶段:
- 数据收集和争论
- 数据分析和建模
- 沟通和部署
在本案例研究中,我们将介绍工作流程中的分析、建模和沟通部分。解决数据科学问题的一般步骤如下:
- 理解问题和数据
- 数据探索/数据清理
- 特征工程/特征选择
- 建立绩效指标
- 模型评估和选择
- 模型优化
- 得出结论并记录工作
那些不熟悉数据科学领域和 Python 编程语言的人仍然可以继续阅读这篇文章,因为它将提供关于如何处理和解决这类问题的高级概述。
虽然博客中包含了一些代码片段,但是完整的代码你可以看看这个 Jupyter 笔记本。
问题定义
Mercari 是日本最大的社区购物应用程序,人们可以在这里出售和购买不同品牌的各种全新和二手产品,从毛衣到智能手机。现在,Mercari 希望向卖家建议正确的价格,但这很难,因为他们的卖家可以在 Mercari 的市场上放置任何东西或任何一捆东西。
因此,我们的目标是建立一个模型,自动向卖家建议正确的产品价格。我们获得了每种产品的以下信息:
train_id —产品的 id
名称—产品的标题
item_condition_id —卖方提供的产品的状况
类别名称—产品的类别
品牌名称—产品的品牌名称
运费—如果运费由卖方支付,则为 1;如果运费由买方支付,则为 0
item_description —产品的完整描述
价格—产品的销售价格(这是我们将预测的目标变量)
这类问题属于监督回归机器学*的范畴:
- 监督:我们可以访问特征和目标,我们的目标是训练一个可以学*两者之间映射的模型。
- 回归:目标变量价格是一个连续变量。
探索性数据分析
EDA 是一个开放式的过程,在这个过程中,我们计算统计数据并制作图表,以发现数据中的趋势、异常、模式或关系。简而言之,EDA 的目标是学*我们的数据能告诉我们什么。它通常从高层次的概述开始,然后随着我们发现数据中感兴趣的部分,缩小到特定的领域。这些发现本身可能是有趣的,或者它们可以用于通知我们的建模选择,例如通过帮助我们决定使用哪些功能。在匆忙进入机器学*阶段时,一些数据科学家要么完全跳过探索过程,要么做一个非常敷衍的工作,但实际上 EDA 是解决数据科学相关问题的最关键步骤之一。
数据集可以从 Kaggle 下载。为了验证结果,我们只需要“train.tsv”数据文件。所以让我们开始吧!
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
我们将把数据分别按 80%和 20%的比例分成训练集和测试集。作为惯例,我们将仅对训练数据集进行 EDA。
In:
data = pd.read_csv('train.tsv', sep='\t')train, test = train_test_split(data, test_size=0.2)
print(train.shape, test.shape)Out:
(1186028, 8) (296507, 8)
在训练数据中有大约 118 万个数据点/行,在测试数据中有 29.6 万个数据点/行。8 是两组中的列/特征的数量。特性和变量在这里的意思是一样的,所以它们在博客中可以互换使用。
#this command displays first few rows of the data set
train.head()
检查缺少的值
处理真实世界数据时的一个常见问题是缺少值。这些可能由于许多原因而出现,并且必须在我们训练机器学*模型之前填充或移除。首先,让我们了解一下每一列中有多少缺失值。
“brand_name”功能有 42%的缺失值。处理缺失值时通常考虑的一些方法有:
- 删除缺少值的记录。
- 如果缺失值的数量高于某个阈值,比如 50%,则移除特征本身。
- 将“缺失值”视为相应特征本身的另一个类别。
在这个项目中,我们将采用第三种方法。
现在我们将开始逐一分析特性。我们将首先检查目标变量价格,然后开始单独分析预测变量,并查看它如何与价格变量相互作用。
价格
让我们检查价格变量的分布,并浏览一些基本的统计数据。
train['price'].plot.hist(bins=50, figsize=(10,5), edgecolor='white',range=[0,500])
plt.xlabel('Price', fontsize=15)
plt.ylabel('Frequency', fontsize=15)
plt.tick_params(labelsize=15)
plt.title('Price Distribution - Training Set', fontsize=17)
plt.show()
train['price'].describe()
- 价格变量的分布与上述统计数据一致,即分布是右偏的。
- 这些商品的中间价格是 17 美元。
- 75%的商品价格低于 29 美元。
- 数据中一个商品的最高价格是 2009 美元。
运费
In:
train['shipping'].value_counts(normalize=True)*100Out:
0 55.267667
1 44.732333
Name: shipping, dtype: float64
55.26%的商品运费由买家支付。让我们看看运输功能与价格的关系。
如果卖家支付运费,产品的中值价格为 14.0 美元,而如果买家支付运费,产品的中值价格为 20.0 美元。
通常,当我们在网上购买产品时,我们需要支付低于一定价格的产品的运费或送货费。但是这里的趋势有点相反,因为卖家支付运费的项目的中值价格低于买家支付运费的项目的中值价格。
项目条件
“项目条件标识”有五个唯一值,范围从 1 到 5。数字越低,物品的状况越好。
In:
train['item_condition_id'].value_counts(normalize=True, sort=False)*100Out:
1 43.194511
2 25.323264
3 29.166934
4 2.153153
5 0.162138
Name: item_condition_id, dtype: float64
43%的项目条件 ID 为 1,而只有 0.16%的项目条件 ID 为 5。让我们看看这个特性与价格的关系。为了比较和可视化分类变量和数值变量之间的关系,箱线图非常有用。下面的代码用于绘制箱线图。
#for easier visualization, we are considering the prices from range of 0-100
price_100 = train[train['price']<100]fig, ax = plt.subplots(figsize=(20,7.5))
sns.boxplot(x='item_condition_id', y='price', data=price_100, ax=ax)
plt.xlabel('Item Condition', fontsize=15)
plt.ylabel('Price', fontsize=15)
plt.xticks(fontsize=15)
plt.yticks(fontsize=15)
plt.show()
虽然比例较低,但是与具有更好条件的项目相比,项目条件 ID 为 5 的项目具有更高的中值价格。
在仔细检查了一些数据后,其中项目条件 ID 被给定为 5,大多数具有这种条件的产品,尤其是电子产品被出售,因为它们的零件本身可以被证明是有价值的。这很好地解释了中值价格较高的原因。
产品类别
“类别名称”中有 1268 个独特的类别
(train['category_name'].value_counts(normalize=True)*100).head(6)Out:
Women/Athletic Apparel/Pants, Tights, Leggings 4.060365
Women/Tops & Blouses/T-Shirts 3.134841 Beauty/Makeup/Face 2.321684 Beauty/Makeup/Lips 2.025398 Electronics/Video Games & Consoles/Games 1.798039 Beauty/Makeup/Eyes 1.720390 Name: category_name, dtype: float64
正如我们所看到的,对于每个项目,有三组由“/”分隔的类别。类别根据全面性从上到下排列。因此,我们可以将类别分成三个不同的列。这三个类别将表示主要类别、第一子类别和第二子类别。拆分时,缺少的值将用字符串“类别未知”填充。
作为常见的预处理实践,我们将把所有文本分类值转换成小写。通过下面的例子,这样做的原因将会很清楚:
假设数据中有两行,属于这两行的产品是 iPhone,对应于第一个条目的品牌名称是“Apple ”,第二个条目的品牌名称是“APPLE”。因此,当我们特征化数据以应用机器学*模型时,我们将应用的任何特征化技术都将考虑“苹果”和“苹果”具有两种不同的值,尽管它们意味着相同的东西。因此,为了让我们的模型认为这两个值是相同的,我们将把所有文本分类值转换为小写。实际上,“苹果”和“苹果”将变成“苹果”和“苹果”。
拆分类别后,我们有 11 个唯一的主类别,114 个唯一的第一子类别,863 个唯一的第二子类别。
主要类别
让我们看看哪一个主要类别在数据中的产品数量最多,并看看主要类别如何根据各自产品的中值价格进行排列。
最多的产品,即全部产品的 44.8%属于“女性”类,其次是“美容”类产品,约占全部产品的 14%,而最少的 1.7%的产品属于“运动和户外”类。
最高中值价格为 21 美元,属于“男士”类别,其次是“女士”类别,中值价格为 19 美元,而“手工”类别的最低中值价格为 12 美元。
第一子类别
由于有 114 个独特的子类别,很难将它们全部可视化。因此,我们将看看前 10 个最受欢迎的子类别,以及根据其各自项目的中值价格排序的前 10 个和后 10 个子类别。
最受欢迎的子类别是“运动服装”,这与之前的观察一致,即最受欢迎的主要类别是“女性”,而“运动服装”属于“女性”和“男性”两个类别。9%的产品属于运动服装类。
从商品的中间价格来看,“电脑&平板电脑”子类别的商品具有最高的中间价格,中间价格为 40 美元。
子类别“纸制品”中的商品的最低中间价格为 6 美元。“纸制品”属于“手工制品”一类。这也证实了之前的观察,即“手工”类别的商品在所有主要类别中具有最低的中值价格。
商标名称
数据中有 4535 个独特品牌。让我们来看看十大最受欢迎的品牌。
Nike 和 Pink 是最受欢迎的两个品牌,数据中 12.6%的产品属于这两个品牌。
当我们检查缺失值时,“品牌名称”功能有 42.7%的缺失值。因此,为了解决这个问题,我们将使用字符串“品牌不可用”来估算缺失的值。
train[’brand_name’] = train[’brand_name’].fillna(’brand_unavailable’)
因为有 42%的价值缺失,所以当给定或不给定特定产品的品牌名称时,观察价格是否会受到影响将是有趣的。为此,我们将创建一个名为“品牌名称已给定”的新功能,其中值“是”和“否”表示品牌名称是否已给定。让我们来了解一下!
看了箱线图后,虽然有很多重叠,但我们可以说,给出品牌和不给出品牌时,价格有相当大的差异。当给出品牌名称时,产品的中间价格是 20 美元,当没有给出品牌名称时,中间价格是 14 美元。简而言之,这个特性将有助于 ML 模型从中映射某种模式。
项目说明
“item_description”功能属于非结构化文本数据类别。对于这种类型的数据,预处理步骤将包括以下操作:
- 将所有单词转换成小写。
- 删除常用词,如“或”、“和”、“是”、“the”、“was”等。我们删除它们是因为这些种类的单词将会以很高的比例出现在数据中,而 ML 模型将无法从中生成任何有意义的模式。这些词被称为“停用词”。
- 删除特殊字符,如“&”、“@”、“!”, '?'等等。
对于可视化,可视化文本数据最有效的方法之一是绘制“单词云”。我们将在下面的词云中看到,当价格上涨时,物品描述中的词是如何比较的。为了检查这一点,我们将根据价格从低到高对数据进行排序,然后将数据分成四个相等的部分。通过这样做,第一季度将有价格最低的产品,因此第四季度将有价格最高的产品。
First Quarter
Second Quarter
Third Quarter
Fourth Quarter
所有的四个字云几乎都是一模一样的。像“全新”、“从未使用过”、“状况良好”、“大小”、“中等”等词。无论价格如何,在大多数产品中都被频繁使用。这表明销售者大部分时间都试图在产品描述部分为他们的产品说好话,这样他们就不会有太多的麻烦来快速卖掉产品。
在第一个词云中有一个有趣的事情是“描述尚未”这几个词。在快速浏览数据后,有些条目中没有给出描述,只有“还没有描述”几个字,有 5.57%的行有这样的字。就像我们对“brand_name”功能所做的那样,我们将验证产品的价格是否会受到描述的影响。
与“brand_name”功能不同,这里没有太大的区别。给出描述时和不给出描述时的产品中值价格几乎相同。给出描述时,产品价格的第 75 个百分位值比未给出描述时的产品价格的第 75 个百分位值多 5 美元。
特征工程和选择
我们将选择用于建模的特征是‘品牌名称’,‘品牌名称给定’,‘项目描述标识’,‘发货’,‘主类别’,‘子类别 1’,‘子类别 2’和‘项目描述’。
一键编码
机器学*模型只能从我们提供的数据中学*,因此确保数据包含我们任务的所有相关信息至关重要。我们刚才分析的所有上述特征将用于制作模型。但 ML 模型无法区分“耐克”和“三星”品牌,也无法区分“化妆品”和“玩具”类别,也无法区分任何分类特征。所以为了解决这个问题,我们需要将我们的分类值转换成数值。我们可以通过‘一键编码’我们的分类值来做到这一点。通过下面的例子,“一键编码”的概念将变得清晰。
假设我们有一个名为“颜色”的特征,这个特征有三个唯一的值:红色、蓝色和绿色。通过对该颜色特征应用“一键编码”,将生成三列,每列代表三种颜色,二进制值 1 或 0 表示该颜色是否出现在特定的行/观察中。
One Hot Encoding (Source)
借助 Python 中的 Scikit-Learn 库,我们可以对分类数据实现“一键编码”。此外,当我们应用 OHE 时,我们需要将其应用于与列车数据相关的测试数据,以避免数据泄漏。例如,如果测试数据中有另一种颜色“黄色”,而这种颜色在列车数据中不存在,那么为了避免数据泄漏,我们将在对测试数据应用 OHE 时忽略“黄色”,因为测试数据应该总是被视为“不可见的”。
一袋单词
现在开始将“item_description”特征表示成数值,我们将应用名为“单词包”的技术。这种技术与“一键编码”相同
在这项技术中,我们将构建一个包含数据集中所有唯一单词的词汇表,并为词汇表中的每个单词关联一个唯一的列。然后,每个句子都被表示为一个列表,其长度与我们的词汇表中不同单词的数量一样长。在列表的每一栏,我们标记出给定单词在句子中出现的次数。这被称为“单词袋”模型,因为它是一种完全忽略句子中单词顺序的表示。通过下面给出的图像,解释将变得清楚。
Representing sentences as a Bag of Words. Sentences on the left, representation on the right. Each index in the vectors represent one particular word (Source)
评估指标
通常,均方根误差(RMSE)度量用于回归任务。但是,由于价格遵循长尾分布(50%的产品低于 17 美元),为了使低价产品的误差比高价产品的误差更相关,此问题的适当度量标准是均方根对数误差(RMSLE)。因此,我们将对价格目标变量应用对数转换,以使此假设可用于模型训练。下图给出了 RMSLE 的公式以及每个变量的含义。
建立基线
开始建模前的最后一步是建立一个简单的基线。这基本上是一个猜测,我们可以根据它来比较我们的结果。如果机器学*模型没有击败这个猜测,那么我们可能不得不得出结论,机器学*对于这项任务来说是不可接受的,或者我们可能需要尝试一种不同的方法。
对于回归问题,合理的原始基线应该是:对于测试集中的所有示例,相应的价格预测将是训练集中所有示例的价格变量的平均值。这为任何车型设定了相对较低的超越门槛。因此,让我们将对数转换应用于基线模型并对其进行评估。
#split the target variable and the predictor variables
x_train, x_test = train.drop(['price'], axis=1), test.drop(['price'], axis=1)
y_train, y_test = train['price'], test['price']#log transformation
y_train_log = np.log1p(y_train)
y_test_log = np.log1p(y_test)#for baseline prediction
y_train_mean = y_train_log.mean()from sklearn.metrics import mean_squared_error
def rmsle(y_test, y_pred):
result = (np.sqrt(((y_test-y_pred)**2).mean())).round(4)
return result
baseline_result = rmsle(y_test_log,y_train_mean)
print(baseline_result)**0.7497**
为了让我们说机器学*算法表现良好,从 ML 模型获得的误差应该小于基线误差,即 0.7497。
模型选择和超参数调整
有大量的机器学*模型可供选择,决定从哪里开始可能会令人生畏。其中一种方法是尝试几种算法,看看哪一种效果最好!机器学*仍然是一个主要由实验结果而不是理论结果驱动的领域,不可能提前知道哪个模型会做得最好。
我们将评估涵盖复杂性范围的四种不同模型:
- 线性回归
- 支持向量回归
- 决策树回归
- 极端梯度推进回归(XGBoost)
对于上面的每个模型,我们可以通过调整它们各自的超参数来优化它。模型超参数最好被认为是机器学*算法的设置,由数据科学家在训练前设置。例如随机森林中的树木数量或 K-最*邻算法中使用的邻居数量。
模型参数是模型在训练期间学*的内容,例如线性回归中的权重。
控制超参数通过改变模型中欠拟合和过拟合之间的平衡来影响模型性能。欠拟合是指我们的模型不够复杂无法学*从特征到目标的映射。一个欠拟合模型有高偏差,我们可以通过使我们的模型更复杂来纠正它。
过拟合是我们的模型本质上记忆训练数据的时候。过度拟合模型具有高方差,我们可以通过正则化来限制模型的复杂度,从而对其进行校正。欠拟合和过拟合模型都不能很好地概括测试数据。
选择正确的超参数的问题是,对于每个机器学*问题,最佳集合都是不同的!因此,找到最佳设置的唯一方法是在每个新数据集上尝试多种设置。
我们将应用的特定超参数调整技术是带有 K 倍交叉验证的随机搜索:
- 随机搜索指的是我们将用来选择超参数的技术。我们定义一个网格,然后随机抽样不同的组合,并执行 K-fold CV,而不是网格搜索,在网格搜索中,我们穷尽地尝试每一个组合。随机搜索的性能几乎和网格搜索一样好,但运行时间大大减少。
- K-Fold CV 是将给定的数据集分成 K 个部分/折叠,其中每个折叠在某个点被用作测试集。让我们以 5 重交叉验证(K=5)为例。这里,数据集被分成 5 个部分。在第一次迭代中,第一次折叠用于测试模型,其余的用于训练模型。在第二次迭代中,第二个折叠用作测试集,而其余折叠用作训练集。重复该过程,直到 5 个折叠中的每个折叠都被用作测试组。对于特定的超参数组合,来自所有五次迭代的测试误差被平均。随机搜索 CV 完成后,平均测试误差最小的超参数组合被选为最优超参数组合。然后,该组合将用于预测测试数据中示例的价格。
K-Fold Cross Validation with K = 5 (Source)
在 Scikit-Learn 中实现机器学*模型
我们将使用 Python 中的 Scikit-Learn 库进行建模。一旦您知道如何在 Scikit-Learn 中制作一个模型,您就可以快速实现各种算法。我们可以举例说明模型创建、训练(使用。适合)和测试(使用。预测)与决策树回归以及随机搜索 CV:
from sklearn.tree import DecisionTreeRegressor
from sklearn.model_selection import RandomizedSearchCV# Create the model to use for hyperparameter tuning
DT = DecisionTreeRegressor(random_state=42)# Minimum number of samples to split a node
min_samples_split = [25,50,75,100,200]# Maximum depth of each tree
max_depth = [5,10,20,30,50]# Define the grid of hyperparameters to search
params = {'max_depth':max_depth, 'min_samples_split':min_samples_split}# Set up the random search with 4-fold cross validation
RS_DT = RandomizedSearchCV(DT, params, scoring='neg_mean_squared_error', cv=4, n_jobs=-1, random_state=42)# Fit on the training data
RS_DT.fit(x_train_final, y_train_log)# this will return the hyperparameters with lowest CV error
RS_DT.best_params_**Out:
{'max_depth':30, 'min_samples_split':50}**
现在我们将使用上述超参数来评估模型在测试集上的性能。
# Create the model with the optimal hyperparameters
DT = DecisionTreeRegressor(max_depth=30, min_samples_split=50, random_state=42)# Fit the model on the training data
DT.fit(x_train_final, y_train_log)# Make predictions on the test data
y_pred_dt = DT.predict(x_test_final)# Evaluate the model
dt_error = rmsle(y_test_log, y_pred_dt)
print(dt_error)**Out:
0.582**
决策树模型的 RMSLE 为 0.582,比基线模型结果低 22.3%。显然,机器学*适用于我们的问题,因为在基线上有显著的改进!其余选定的 ML 型号也遵循相同的程序。让我们看看其他模型在测试集上的表现如何。
线性回归模型给出了测试集上最低的 RMSLE。这表明更简单的 ML 模型也可以完成这项工作,它们不应该被低估。
此外,两种线性模型(线性回归和支持向量回归)都比两种非线性模型(决策树和 XGBoost 回归)表现得更好。
结论
在本文中,我们完成了一个数据科学案例研究,其中我们理解了问题陈述,进行了探索性数据分析、特征转换并最终选择了 ML 模型,进行了随机搜索和超参数调整,并在测试集上对它们进行了评估并比较了结果。
机器学*往往是一个迭代而非线性的过程。我希望这个案例研究至少给了你一个关于数据科学和机器学*相关问题通常是如何处理和解决的高层次概述。
帮助我写这篇博客的参考资料:
- https://towards data science . com/a-complete-machine-learning-walk-through-in-python-part-one-c 62152 f 39420
- https://towards data science . com/a-complete-machine-learning-project-walk-through-in-python-part-two-300 f1 f 8147 e 2
- https://towards data science . com/machine-learning-for-retail-price-suggestion-with-python-64531 e 64186d
- https://medium . com/unstructured/how-I-lost-a-silver-medal-in-kaggles-mercari-price-suggestion-challenge-using-CNN-and-tensor flow-4013660 fcded
感谢您的阅读!
数据科学作品集比简历更有价值
原文:https://towardsdatascience.com/a-data-science-portfolio-is-more-valuable-than-a-resume-2d031d6ce518?source=collection_archive---------11-----------------------
考察 3 个投资组合构建平台:Github、LinkedIn 和 Medium
Image be Benjamin O. Tayo
数据科学是一个实用的领域。实践技能非常重要,尤其是当你有兴趣作为一名实践数据科学家在学术界之外工作时。
在学术界,你需要更多的理论和研究技能。虽然深入了解数据科学的理论基础很重要,但作为一名实践数据科学家,实践经验非常重要,展示您实践技能的一种方式是通过构建一个非常棒的投资组合。有兴趣雇用你的公司肯定会向你索要投资组合,因为这证明了你在基础数据科学概念方面的优势。
虽然数据科学简历很重要,但数据科学投资组合比简历更有价值。本文将讨论可用于投资组合构建的 3 个重要平台。
在深入探讨构建良好的数据科学组合这一主题之前,让我们首先讨论数据科学组合为何重要的 5 个原因。
数据科学产品组合之所以重要的 5 个原因
- 投资组合有助于展示您的数据科学技能。
- 投资组合使您能够与其他数据科学专业人员和该领域的领导者建立联系。
- 投资组合有利于记账。您可以使用它来记录已完成的项目,包括数据集、代码和示例输出文件。这样,如果你不得不在一个类似的项目上工作,你总是可以使用已经写好的代码,只需要很小的修改。
- 通过建立投资组合并与其他数据科学专业人士和领导者建立联系,您可以接触到该领域的技术变化。由于技术的进步,数据科学是一个不断变化的领域。为了跟上该领域的最新变化和发展,加入数据科学专业人士网络非常重要。
- 作品集增加了你找到工作的机会——我已经从 LinkedIn 获得了很多机会,比如招聘人员联系我寻找数据科学方面的工作机会。
现在,我们来讨论创建数据科学产品组合的 3 个重要平台。
构建数据科学组合的平台
1.开源代码库
Github 是一个非常有用的平台,可以展示你的数据科学项目。这个平台使您能够与其他数据科学家或数据科学爱好者共享您的代码。有兴趣雇佣你的雇主会检查你的 github 作品集,评估你完成的一些项目。所以在 github 上建立一个非常强大和专业的投资组合对你来说很重要。
要建立 github 投资组合,首先要做的就是创建一个 github 账户。创建帐户后,您可以继续编辑您的个人资料。编辑您的个人资料时,添加简短的个人简介和专业的个人资料图片是个不错的主意。你可以在这里找到一个 github 概要的例子:。
现在让我们假设您已经完成了一个重要的数据科学项目,并且您想要为您的项目创建一个 github 存储库。
****创建存储库的技巧:确保你为你的存储库选择了一个合适的标题。然后附上一个自述文件,提供项目的概要。然后,您可以上传您的项目文件,包括数据集、jupyter 笔记本和样本输出。
下面是一个机器学*项目的 Github 知识库的例子:
****储存库名称:bot 13956/ML _ Model _ for _ Predicting _ Ships _ Crew _ Size
****资源库 URL:https://github . com/bot 13956/ML _ Model _ for _ Predicting _ Ships _ Crew _ Size
自述文件:
**ML_Model_for_Predicting_Ships_Crew_Size**Author: Benjamin O. TayoDate: 4/8/2019We build a simple model using the cruise_ship_info.csv data set for predicting a ship's crew size. This project is organized as follows: (a) data proprocessing and variable selection; (b) basic regression model; (c) hyper-parameters tuning; and (d) techniques for dimensionality reduction.**cruise_ship_info.csv**: dataset used for model building.**Ship_Crew_Size_ML_Model.ipynb**: the jupyter notebook containing code.
2.商务化人际关系网
LinkedIn 是一个非常强大的平台,可以展示你的技能,并与其他数据科学专业人士和组织建立联系。LinkedIn 现在是发布数据科学工作和招聘数据科学家最著名的平台之一。实际上,我已经通过 LinkedIn 获得了 2 次数据科学面试。
确保您的个人资料始终是最新的。列出你的数据科学技能,以及你的经历,包括你已经完成的项目。列出奖项和荣誉也是值得的。你还想让招聘人员知道你正在积极寻找工作。此外,在 LinkedIn 上,您可以关注数据科学的影响者和出版物,如数据科学的****和人工智能的。这些公司发布关于各种主题的有趣数据科学文章的更新,包括机器学*、深度学*和人工智能。********
从这里找到我在 LinkedIn 上的帖子的例子:https://www . LinkedIn . com/in/Benjamin-o-tayo-ph-d-a 2717511/detail/recent-activity/shares/
3.中等
Medium 现在被认为是投资组合构建和网络发展最快的平台之一。如果你有兴趣使用这个平台来建立投资组合,第一步是创建一个中型账户。您可以创建一个免费帐户或会员帐户。对于免费帐户,每月实际访问的会员文章数量是有限制的。会员账户需要 5 美元或 50 美元/年的月订阅费。从这里了解更多关于成为中等会员的信息:【https://medium.com/membership】。
创建帐户后,您可以继续创建个人资料。确保附上一张职业照片和一份简短的简历。下面是一个中等配置文件的例子:https://medium.com/@benjaminobi。
在 medium 上,与其他数据科学专业人士交流的一个好方法是成为一名追随者。您还可以关注专注于数据科学的特定媒体出版物。排名前两位的数据科学出版物是面向数据科学的和面向人工智能的。****
提升你的媒体作品的最好方法之一就是成为一名媒体作家。
为什么要考虑在 Medium 上写数据科学文章?
写中型文章有 5 个主要优势:
- 它为您提供了展示数据科学知识和技能的途径。
- 它激励你从事具有挑战性的数据科学项目,从而提高你的数据科学技能。
- 它使你能够提高你的沟通技巧。这是有用的,因为它使你能够以一种普通大众能够理解的方式传达信息。
- 每一篇发表在 medium 上的文章都被认为是知识产权,所以你可以在简历中添加一篇 Medium 文章。
- 你可以从你的文章中赚钱。通过 媒介合作伙伴计划 ,任何在媒介上发表文章的人都可以获得赚钱的资格。
如果您有兴趣成为一名数据科学媒体作者,这里有一些资源可以帮助您入门:
在介质上写数据科学博客的初学者指南
为您的数据科学文章选择合适的精选图片
总之,我们已经讨论了可用于构建数据科学产品组合的 3 个重要平台。投资组合是您展示技能和与其他数据科学专业人员交流的一种非常重要的方式。一份好的作品集不仅能帮助你跟上该领域的最新发展,还能帮助你在潜在的招聘者面前提高知名度。
数据科学项目周期
原文:https://towardsdatascience.com/a-data-science-project-cycle-af5a1cdef14f?source=collection_archive---------28-----------------------
如何更多地关注问题,而不是工具
Photo by Katie Rodriguez on Unsplash
作为组织中的一名数据科学家,您经常会发现自己处于以下几种情况:
- 你有一个数据集,你想提取一些有用的信息
- 你有一个业务问题,你想找到一个数据驱动的解决方案
第一种情况实际上是一种常见的情况,基本上,这意味着在您的数据科学之旅中,将您所学的所有内容作为探索性数据分析(EDA)的一部分。在本文中,我将解释如何处理第二种情况。
假设你在你的组织中已经呆了足够长的时间,知道它的业务实践和它产生的所有类型的数据。在这个过程中,你已经形成了一个假设,你想要验证这个假设。或者,也许你的经理/首席执行官/首席技术官正在请求你帮助找到他们遇到困难的问题的答案。如果你有足够的经验,你可能会知道你的下一步,但新手往往很难将他们的思维引向正确的方向。这是一种算法的方式来思考问题,直到找到解决方案。
Data science project cycle ( @DataEnthus)
问题是
在第一步,你有一个疑问或问题。如果它很大,如果需要的话,你可以把它分成小块。例如,如果问题是关于预测未来 10 年的销售增长,你可以把它分成几个部分,比如历史销售额是多少?目前的销售趋势如何?市场需求趋势如何?竞争对手表现如何?等等。
你从不同的来源收集尽可能多的信息,从不同的角度理解问题。你首先缩小大图,然后放大与问题相关的具体信息。在这个阶段,你真的从许多不同的角度开始了解手头的问题。这部分类似于学术研究项目中的文献综述。你应该花大量的时间来构思这个问题。
该过程
第二步,不,你不是在想用什么模型/工具/可视化技术;还没有。你正在思考一个方法过程,它将引导你回答你的问题。您可以列出一个数据集列表,确定在哪里可以找到它们,还可以列出一个可能有用的工具列表。即使您还没有对数据/工具的细节做出最终决定,在头脑中或在纸上有一个整体过程也会有很大帮助,即使它会随着后来的额外信息而改变。这种方法有点类似于在学术环境中,你在实际执行研究之前写下你的研究提案;随着你进一步研究手头的问题,事情往往会发生变化。
工具
在第 3 步中,现在您正在考虑哪些工具可以帮助回答这个问题。如果这是一个预测问题,你会想基于时间序列的模型是否有用?还是反而是线性回归问题?需要 GIS 技术吗?有没有好的 R 或者 Python 的包?
一旦您探索了所有可用的选项并决定了一组特定的工具,您现在就可以开始搜寻数据了。您需要的数据可以是一个数百万行的数据集,也可以是一百个数据点,这取决于您的问题和您选择的模型。
你找到所选模型所需的数据了吗?如果是,你就可以去适应你的模型了。但是如果你没有所有需要的输入,你应该在这里停下来,回到第二步的方法过程。也许还有其他不需要时间序列数据的工具/方法?一个不需要很多参数或者大数据集的系统动态模型怎么样?
答案
你已经把你的大问题分成了几个小部分,并单独回答了它们。总的来说,你解决了你开始的那个大问题了吗?如果是的话,恭喜你。如果没有,请返回步骤 2。
沟通是解决问题过程中很重要的一部分。你需要能够说服你的听众(产品经理/同事/外部听众)为什么你的解决方案有意义吗?您还需要对与提议的解决方案相关的不确定性和警告以及您在此过程中所做的假设保持透明。
底线
总之,成为一名科学家意味着要经历一个探索/发现的过程。我们经常被我们所知道的工具/模型以及如何用数据来拟合它们所困扰。正如我们所见,选择正确的工具是解决问题过程的一小部分。总是先有问题,后有工具。
数据科学公共服务公告
原文:https://towardsdatascience.com/a-data-science-public-service-announcement-fe81fbe6dc3f?source=collection_archive---------4-----------------------
(Source)
开源数据科学工具需要你的帮助。幸运的是,现在比以往任何时候都更容易做出贡献——以下是提供帮助的方法
生命中最美好的东西都是免费的:朋友、pandas
、家人、numpy
、睡眠、jupyter notebooks
、欢笑、python
。严肃地说,令人难以置信的是,数据科学的最佳工具可以免费获得,而且不是由一个拥有无限资源的公司创造的,而是由一个个人社区创造的,其中大多数人无偿从事这些项目。你可以支付860 美元/年购买 Matlab (外加额外费用以获得更多库),或者你可以免费下载 Python 和任何库,不用花一分钱就能获得更好的软件和更好的客户支持(以栈溢出和 GitHub 问题的形式)。
自由和开源软件(FOSS) 运动——你可以自由使用、共享、复制和以任何方式改进软件——极大地改善了公司和个人使用的数字工具,同时将许多领域(包括数据科学)的准入门槛降低到接*于零。对于我们这些在过去几十年中长大的人来说,这是我们唯一知道的模式:软件当然是免费的!然而,我们每天依赖的开源工具现在面临着严重的可持续性问题。
在这篇文章中,我们将探讨自由/开源软件面临的问题,更好的是,你可以采取许多步骤(有些步骤只需 30 秒)来确保你最喜爱的数据科学工具保持免费,并且比付费工具更好。虽然存在一个真正的问题,但我们所有人也有许多解决办法。(本文所依据的信息来自“道路和桥梁:我们数字基础设施背后看不见的劳动”以及 NumFocus 网站。)
为什么开源数据科学工具需要帮助
想想熊猫图书馆这个神奇的工具。截至 2019 年 2 月 20 日,《熊猫》已被 PyPi 下载超过 8000 万次(详细分析 PyPi 下载在此)。根据 libraries.io 的说法,在至少有 25000 个 GitHub 库依赖于 Pandas,至少有 100 个不同的包需要这个库。栈溢出所有问题中有* 1.8%是关于熊猫的(5 倍于整个 Matlab 语言的问题数量)。
Analysis of Stack Overflow Tags. You can do your own exploration here.
发展和维护熊猫的工作是由一个相对较小的群体完成的。据 openhub.net 介绍,自从韦斯·麦金尼在 2009 年启动项目以来,熊猫知识库只有 1400 名贡献者,他们总共编写了 294000 行代码。这代表了惊人的 78 年开发者的努力,价值至少 780 万美元。尽管他们的劳动很有价值,但几乎每一个贡献者都是完全免费工作的,他们都渴望构建伟大的数据科学工具。
然而,要维护和更新熊猫,需要的不仅仅是兼职贡献者。根据 NumFocus (稍后将详细介绍该组织), Pandas 需要 10 名全职付费开发人员来实现其目标,包括致力于 1.0 版本的发布。目前,这个由数千万人和数千家公司使用的库有 1 个按 20%时间付费的核心开发人员、1 个按 10%时间付费的核心开发人员和 8 个按 0%时间付费的核心开发人员。
From NumFocus (Some of these stats are a little old).
在其他开源数据科学库中也存在类似的问题:matplotlib 需要 14 名全职付费开发人员——目前有 2 名 10%付费时间的开发人员 numpy 需要 12 名——有 2 名 100%付费时间的开发人员(多亏了一笔拨款)。这种付费开发者时间的缺乏损害了开源库:尽管业界广泛依赖,但 Pandas 尚未发布 1.0 版本(被认为是稳定版本),只能以与其获得的资金水平成比例的速度发布。
维护和改进开源软件这样的共享资源的挑战在“公地悲剧”中有所体现:许多人利用免费工具,但很少有人回报。没有适当的支持,公地悲剧的最终结果是资源的枯竭和最终的损失。开源软件——不仅仅是在数据科学领域——正越来越多地遇到可持续性问题,因为越来越多的人采用这些工具而不给予回报。
扩大采用是好事——没有人主张关闭自由/开源软件工具——但这意味着生产者与消费者的比率继续下降到不可持续的水平。在开源时代的开始,许多用户也帮助构建工具,但现在,由于个人电脑的令人难以置信的采用,更多的人可以使用这种软件,这给真正构成我们数字基础设施的工具带来了压力。
A quote from Noah Kantrowitz, Python developer and member of the PSF.
在过去的几年里,我们已经开始看到构成我们数字基础设施的开源软件的崩溃(见道路和桥梁报道)。OpenSSL 是一套被 2/3 的 web 服务器使用的加密工具,多年来一直由一名全职开发人员提供支持。70%的网络依赖于一个人的工作,这一事实并没有激励任何人或任何公司捐款,直到 2014 年发现“heartbleed”漏洞,将注意力集中在该项目上,并导致急需的捐款。目前,OpenSSL 有足够 4 名全职员工工作 3 年的资金。如果没有另一个重大问题,这种资助的持续性是不确定的。
作为另一个例子, [bash,一种安装在 70%的互联网连接设备上的 Unix shell 和命令语言](http://Bash - GNU Project - Free Software Foundation https://www.gnu.org/software/bash/)(包括每一台 Linux 和 MacOS 机器),自 1992 年以来一直由一个人维护,Chet Ramey,他在凯斯西储大学工作。同样,这似乎没有困扰任何人,直到 2014 年 bash 中发现了“shell shock”漏洞,引起了急需的媒体关注。
幸运的是,在撰写本文时,我们还没有看到开源数据科学工具中的同等问题。尽管如此,采取行动的时间并不是在灾难发生后,而是尽早阻止灾难发生,防止损失。如果我们想避免真正的公地悲剧,那么我们需要采取行动,把我们心爱的工具放在稳定的基础上。是时候从开源工具的单纯消费者转变为支持者和/或生产者了!
解决方案
任何时候你提出一个问题,你都应该在法律上有义务提出一个解决方案,最好是一个读者可以立即接受的方案。在支持开源数据科学工具的情况下,无论您的技术专长或财务状况如何,都有大量的选项可供您选择。在这里,我们将经历三个阶段:
- 报告问题
- 解决问题和撰写文档
- 通过像 NumFocus 这样的组织进行小额捐赠(这需要30 秒)。
第一种,也许是最简单的帮助方式,是报告问题,这样项目开发人员就知道该修复什么。莱纳斯定律说“如果有足够多的眼球,所有的bug都是肤浅的”这意味着如果一个项目有足够多的用户,所有的问题最终都会被发现。报告问题很有价值,但需要以有效的方式进行。确保您的问题尚未解决(首先搜索类似问题),提供重现问题所需的准确代码,并根据要求提供后续信息。此外,尊重项目开发人员:开源贡献者没有义务解决你所有的问题,所以友善点,尽你所能给他们帮助。
如果你有点不确定该不该问,这里有一些在 GitHub 上提交问题的小技巧,还有如何问一个关于堆栈溢出的好问题。除了改进开源库之外,这两项技能(提交问题/提问)将帮助你个人成为一名数据科学家,因为如果你使用一个库足够长的时间,你最终会遇到一个别人从未遇到过的问题。当你遇到新问题时,你必须知道如何提问或如何自己解决问题。
这一点让我们想到了第二种贡献方式:解决开源库的突出问题和需求。GitHub 是一个很棒的合作平台,它让你很容易找到你可以贡献的地方。你所需要做的就是去你最喜欢的图书馆的仓库,选择问题,并在你觉得舒服的地方寻找。
这甚至不需要高水平的技术专业知识。GitHub 上有超过 2800 个关于熊猫的公开问题,其中 227 个被标记为“好的第一期”。这些问题中的许多都与文档有关,这意味着您不需要编写代码!这些贡献是一个让你接触开源工作的好地方,也可以帮助你建立一个档案,向雇主展示你对数据科学的承诺(请不要只是为你的档案做象征性的贡献,而是对一个项目做出承诺)。
开源的精神是每个问题都应该被视为一个机会:如果你看到一个问题,没有什么可以阻止你为自己和数百万其他人改善图书馆做出贡献。
如果这两个选项都不吸引你,或者你想提供更多的帮助,你可以为开源项目提供财政支持。现在,你可能会说我的捐赠永远不会有所作为,但由于这些项目中的大多数获得的金额极低(2017 年熊猫获得 3000 美元,Numpy 获得 1300 美元),即使是小额捐赠也可以发挥很大作用。此外,来自许多个人的许多小额捐款加起来:如果每个阅读我的文章的人在一个典型的月中只给开源 1 美元,那将超过 50 万美元来支持我们的数据科学工具!
说到捐赠,有时可能有太多的选择,所以我只给你一个专注于数据科学的选择,NumFocus。该慈善机构的既定目标是“为开源科学数据堆栈中的项目提供一个稳定、独立和专业的家园。”NumFocus 支持开源项目,如numpy
、pandas
、matplotlib
、project jupyter
、ipython
、pymc3
、pytables
、等。向 NumFocus 捐款很简单:点击图片,30 秒内你就成为支持会员。
Click this image and make a difference!
就我个人而言,我每月向 NumFocus 捐赠 2 美元。这是一个很小的数目——以普遍的价值衡量,还不到一个月一杯咖啡——但我很高兴知道我在为我所热爱的图书馆做一点点贡献。成为永久会员也很棒,因为我甚至不需要记得捐款——我只需注册一次,然后自动捐款,每个月都会收到 NumFocus 的感谢邮件。
如果数据科学不是你的领域,或者你想为其他项目做贡献,这里有一些支持开源的组织:
- Python 软件基础
- 阿帕奇软件基金会
- 软件自由保护协会
(你可以在这里看到一个更大的列表。)同样,我认为重要的是不要不知所措,所以只需选择一两个,自动化您的支持,然后您甚至不必考虑它。
最好的自动化让我们不用任何有意识的努力就能让世界变得更好!
如果你想更进一步,让你的公司也成为开源软件的一员。如果我的经验是任何迹象,那么你的公司将很高兴投资这些工具,如果你在你的工作中依赖他们。几周前,我在《熊猫》中遇到了一个奇怪的 bug,我在 Stack Overflow 和然后是 GitHub 上发布了这个 bug,在那里它加入了 2800 个其他关于熊猫的公开问题。不久之后,我收到一条评论,将我引向问题的可能来源,8000 行文件中的第 7400 行,形成了 pandas 中数据帧的基础,并被告知欢迎一个拉请求。
不幸的是,我对熊猫的专业技能和知识远没有达到我想去搞乱图书馆内部的水平。因此,我觉得我需要做些什么来帮助他们,于是我向我公司的首席技术官( Cortex Building Intel )询问公司是否愿意每月向 NumFocus 捐款。幸运的是,我们的 CTO 意识到了支持我们日常使用的技术的价值,并乐于提供帮助。
我分享这个故事不是因为我是一个典范,而是因为它表明有多种方式来支持开源。当我脱离我的技术联盟时,我转向另一种方式来有所作为。我还没有天真到认为我一个人的行动就能缓解这个问题,但是如果有足够多的人行动起来,我们就能改善这些工具的可持续性。
尽管认为砸钱就能解决问题有点过于简单,但更多的付费开发时间确实有所帮助。熊猫有一个在 1.0 版本发布前要达到的目标列表,而及时完成这些目标的唯一方法是用资金支持付费开发者。
Pandas road map (if they get more donations!)
为了使它更有效,你应该这样表达你的信息:支持开源工具是对你公司未来的投资。免费和开源技术让许多初创企业得以起步,现在已经成为许多公司甚至整个互联网的技术核心。现在的捐赠将确保开源继续提升技术领域,加强我们的基础设施,并为我们提供最好的数据科学工具。
最后的想法
支持开源不仅仅是拥有有效的免费工具,而是成为更大社区的一部分。解决公地悲剧最有效的方法是培养一种社区意识。让人们感觉他们属于一个共享的团体,他们将努力确保所有成员的资源得到维护。当你开始做出贡献时,你会感受到一种更强烈的团体意识(这是我们这个世界严重缺乏的东西),并且知道你在帮助自己和他人。
此外,如果你做出了任何形式的贡献,我完全允许你在你所有的社交媒体渠道上夸耀。有些活动——献血、在食物银行做志愿者——天生对世界有益,我永远不会厌倦看到关于它们的帖子。当你向开源捐款的时候,站在你个人的山顶大声喊出来。如果你捐得比我多(是的,这是一个挑战),那么让我知道,我会很高兴听到。如果有人说你讨厌,不要理会他们:你让世界变得更好,而他们不是。开源数据科学社区只会不断发展,所以让我们努力为我们都使用的工具提供一个可持续的基础。
提醒一下,游戏计划如下:
- 提交质量问题,尽最大努力帮助解决这些问题。
- 去你最喜欢的开源图书馆,挑一个问题(应该有一些标明“好的第一个问题”)并尝试解决它
- 如果你有能力,向 NumFocus 或其他开源组织进行持续捐赠。
- 如果你的公司依赖于开源工具,和某人谈谈如何维持公司对开源软件的支持
- 在任何你想的地方张贴你的捐款。
- 通过对话和写作说服他人也这样做。
一如既往,我欢迎反馈和建设性的批评。你可以在推特上找到我。
阿克巴和伯巴尔时代的一个数据科学问题
原文:https://towardsdatascience.com/a-data-science-question-in-the-times-of-akbar-and-birbal-7e3f1128fe16?source=collection_archive---------22-----------------------
一个著名的印度故事,在那些在印度长大的人中特别受欢迎,是阿克巴-比尔巴的故事,伟大的莫卧儿皇帝阿克巴提出了一个看似不可能回答的问题——“我们王国里有多少只乌鸦?”。
伯巴尔,机智聪明的阿克巴皇帝的大臣,用一个随机数字反驳,当被要求证明其准确性时,以他典型的无与伦比的方式回应,逻辑是阿克巴不可能验证的,因为如果数字不准确,那是由于鸟类的迁徙本性!
统计估计问题
然而,我认为这是数据科学中一个完全有效的估计问题,也是一个值得问一群数据科学家(如果不是部长的话)的问题(如果我可以做一个观察的话,他们似乎从来没有对科学有足够的理解!).当然,由于所有的乌鸦看起来都一样或难以区分,这似乎是一个相当困难的问题。
An adjacent problem: Estimating the number of cars in a city
邻*的问题
但在我们讨论乌鸦之前,让我们讨论一个稍微相邻的问题——我们如何估计一个城市(如果不是王国)的汽车数量。当然,我们现在拥有的优势是,不像乌鸦,汽车被分配了注册号码,并且在大多数城市或多或少以升序排列。在这一点上,值得思考的一个有趣的问题是——拥有这样的注册号会让您的任务变得容易吗?
这是一个至少在面试中经常问产品经理的问题——答案围绕着一系列关于人口统计、城市条件等的猜测,导致最终的“猜测”。
然而,我意识到这个问题有一个优雅的统计解决方案,因此对于数据科学家的采访来说,这也是一个有趣的问题。当我写下数学证明(我们一会儿就会看到)时,我的一个朋友向我指出了一个令人难以置信的事实,这种技术实际上在* 70 年前的二战中被盟军用来估计德国人一直在制造的坦克数量,并将其命名为 德国坦克问题 !
德国坦克问题
By Bundesarchiv, Bild 101I-218–0504–36 / Dieck / CC-BY-SA 3.0, CC BY-SA 3.0 de, https://commons.wikimedia.org/w/index.php?curid=5476517
盟军正利用缴获的坦克进行估算。他们得到的估计是每月生产 270 辆坦克,后来德国战后的记录显示实际数字是 276 辆!所以,事不宜迟,让我们开始吧!
估算一个城市的汽车数量!
这里有几个我们需要做的假设——假设汽车的注册号码是按顺序分配的,没有漏洞。此外,在像印度这样的国家,区号是注册号码的一部分——所以在这种情况下,让我们把重点放在估计特定区号内的汽车的问题上。此外,当有字母作为注册号的一部分时,应该不难将它们转换成数字形式,以便注册号真正是一个数字!
在上述假设/条件下,可以对城市中的一些汽车(比如说 n 辆)进行采样,并根据看到的最大注册数量得出一个估计值。
现在让我们来推导一下这个估计值是什么样子的——需要回忆一下你的高中数学,以防你感到数学上的挑战。当然,如果你愿意,请直接跳到这个公式。
估计值的推导
假设 M 是从“n”个样本中看到的最大注册数。假设 N 是汽车总数或实际分配的最大登记数量。
理想情况下,我们希望 M 尽可能接* n。
也就是说,我们希望 m 大于𝑡∗𝑁,其中 0 t 更接*于 1)
也就是说,所有的车都是按照注册号顺序从第一辆 t * N 开始的样品。
上面的等式可以用来表示随机变量 M 的 CDF 函数:
M 的预期值可推导如下:
在这种情况下,
因为我们知道 M 可以取 0 到 n 之间的值。此外,我想澄清一下,这实际上是一个离散随机变量,尽管出于计算目的,我将其建模为连续随机变量。
对于正随机变量,
同样的推导参见链接。
换句话说,N 可以估计为:
那看起来一点也不差!
举个例子,如果你通过看 1000 辆车来估算 M,M 预计是实际值的 99.9%!
回到乌鸦队!
现在我们已经有了一个合理的统计方法来解决这个问题,当汽车被编号时,问题就出现了,在没有编号的乌鸦的情况下能做什么!好消息是,估计任何物种的数量都是目前研究得很好的课题,并且有技术可以解决这个看似困难的问题。
有两种估算鸟类种群的方法。一种是进行点计数,即计算从一个点可以看到的鸟类,然后跨区域进行推断。另一种方法是从样线计数,事实上,如果记录了斑点鸟的距离信息,它可以用来绘制该地区特定鸟类的密度图。
标记并重新捕获
另一种方法是称为标记和重新捕获的技术。生物学家(或者数据科学家!)标记该物种的一些鸟类,并让它们进入环境。经过足够长的时间后,发现该物种,并计算有标记和无标记鸟类的数量。样本中有标记鸟类与无标记鸟类的比例使他们能够推断出无标记物种的数量,并得到种群的总体估计。对于那些好奇的人来说,乌鸦等鸟类的标记技术可能是喷射荧光染料,这种染料可以粘在鸟类身上。
假设 K 只乌鸦被做了标记。假设乌鸦被重新捕获。
在重新捕获的鸟中,假设有 k 只被标记。
我们如何确定该地区乌鸦的总数 N?
让我们首先理解这里起作用的条件分布。
P(k | N) =假设总共有 N 只鸟,k 只标记的鸟被重新捕获的概率。
概率分布
这原来是一个超几何分布。超几何分布的平均值是
如果我们进行了足够的观察,k 是样本的平均值,那么 N 可以估计为:
这意味着,如果你标记了 100 只乌鸦,并且在你随后的观察中,你看到平均有 2%的乌鸦有标记,那么有标记的乌鸦与无标记的乌鸦的比率可以估计为 1:50,从而给我们一个 5000 只乌鸦的乌鸦种群估计!
请注意,在上述两个问题(乌鸦和汽车)中,出于理解的目的,我使用了所谓的频率主义方法,因为对于这个问题,这是一种更简单但合理的方法,尽管有足够多的情况表明频率主义方法是一种谬误。
参考
[## 如何估算一个城市的汽车数量?
我在产品经理面试中遇到过这个问题,答案围绕着一系列…
medium.com](https://medium.com/@vinodh.ravindranath/how-to-estimate-the-number-of-cars-in-a-city-dd40432f12d2) [## 人口规模、密度和分布
如果您看到此消息,这意味着我们在网站上加载外部资源时遇到了问题。如果你是…
www.khanacademy.org](https://www.khanacademy.org/science/high-school-biology/hs-ecology/hs-population-ecology/a/population-size-density-and-dispersal) [## 鸟类普查技术:数乌鸦(和其他鸟类!)为什么数鸟?描述性研究=…
为什么数鸟?(续)评估栖息地需求=询问“鸟类在……中的密度是更高还是更低?”
slideplayer.com](https://slideplayer.com/slide/4490242/) [## 对话:标记和重新捕获
乔利斯的方法也应该提到。是的,这里应该描述一下 cormack jolly seber 方法。这是极端的…
en.wikipedia.org](https://en.wikipedia.org/wiki/Talk:Mark_and_recapture#Statistical_treatment)
这篇文章最初出现在印度分析杂志上。
启动项目的数据科学工作流画布
原文:https://towardsdatascience.com/a-data-science-workflow-canvas-to-kickstart-your-projects-db62556be4d0?source=collection_archive---------10-----------------------
Photo Credit: https://www.wocintechchat.com/
使用本指南帮助您完成数据科学项目。
从自己的错误和最佳实践中学*,我设计了一个 数据科学工作流画布 ***** 来帮助他人实现自己的数据科学项目。这张画布可以帮助你先确定目标的优先顺序,然后再努力实现它们。你可以这样想:不是按照食谱中的步骤来做一顿预定的饭,而是首先想象这顿饭看起来和尝起来是什么样子,然后你开始制定食谱。在从事数据科学项目时,您通常没有一套指令来实现预定的结果。相反,你必须确定结果和实现这些结果的步骤。这个数据科学工作流画布的设计考虑到了这一过程。在这里,我将带您了解如何使用这个画布,并且我将分享我如何在自己的项目中实现这个画布的例子。
Data Science Workflow Canvas.
下载数据科学工作流画布 。
如何使用数据科学工作流画布
第一步:确定你的问题陈述
你想解决什么问题?这个问题解决了什么更大的问题?这一部分帮助你解决项目的“为什么”。
第二步:陈述你的预期结果/预测
是的,你不会知道你的成果是什么,直到你完成了你的项目,但你至少应该有一个你认为它们应该是什么样子的想法。识别潜在的预测变量(X
)和/或目标变量(y
)。
步骤 3:确定您的数据源
您的数据来自哪里?数据是否足够?你真的能使用它吗?有时候,你可能有现成的数据集,或者你可能需要收集数据。
第四步:选择你的模型
根据你对这些问题的回答选择你的模型:你的结果是离散的还是连续的?您是否有标记或未标记的数据集?你关心离群值吗?您希望如何解释您的结果?根据您的项目,问题列表会有所不同。
步骤 5:确定模型评估指标
确定相应的模型评估指标来解释您的结果。每个模型都有自己的一套评估指标。
步骤 6:创建数据准备计划
为了运行您的模型并实现您的结果,您需要对您的数据做什么?数据准备包括数据清理、特征选择、特征工程、探索性数据分析等等。
将这一切结合在一起
一旦你在画布上完成了你的想法的头脑风暴,是时候把它们都集中起来,激活你的项目了!将项目投入使用时,请参考画布“激活”部分中列出的顺序。
数据科学工作流画布示例#1
下面是我在 WNBA 机器学*项目中如何实现数据科学工作流画布的一个例子。阅读关于这个项目的文章或者参考这个画布跟随 GitHub 库。
Data Science Workflow Canvas for the WNBA Clustering project.
数据科学工作流画布示例#2
这是我在假新闻检测器项目中如何实现数据科学工作流画布的另一个例子。阅读关于这个项目的文章或者参考这个画布跟随 GitHub 库。
Data Science Workflow Canvas for the fake news detector project.
结论
要很好地实施这个数据科学工作流画布,请记住以下三点:
- 不要害怕犯错误。用这块画布作为头脑风暴你最初想法的空间,然后回来完善你的过程。保留有用的,去掉无用的。
- 专注于你想完成的事情。即使你最初的目标改变了,也要专注于你想要完成的事情。不管你需要多长时间回顾和更新你的目标,只要专注于它们。
- 数据科学是一个非线性的迭代过程。实现数据科学项目没有正确或线性的方法。你可以使用这个画布作为资源来帮助你开始一个项目,但是如果你开发另一个更适合你的过程也没关系。
祝您的数据科学项目好运,愿画布与您同在!
*数据科学工作流画布中的内容灵感来自我在大会期间所做的笔记 数据科学沉浸式 。画布的结构灵感来自 商业模式画布 。
Jasmine Vasandani 是一名数据科学家、战略家和研究员。你可以在这里了解她的更多:www.jasminev.co/
数据科学方法
原文:https://towardsdatascience.com/a-data-scientific-method-80caa190dbd4?source=collection_archive---------7-----------------------
如何对数据科学采取务实和目标驱动的方法
数据科学的主要目的很简单:从数据中提取价值是。这个价值在不同的环境中可能有不同的形式——但是,通常,它以 更好的决策 的形式出现。
Data Science Should Ensure that Data Results in Better Decisions (CREDIT: Author on Canva)
随着我们越来越深入地探索 21 世纪,数据在我们决策中扮演的角色变得越来越重要。这是因为可用数据的绝对体积增长,以及我们可以用来存储、处理和分析数据的工具的改进。
然而,从更宏观的角度来看,数据科学领域仍处于起步阶段。这是一个出现在其他几个学科交叉领域的领域——仅举几个例子,如统计学、商业智能和计算机科学。随着这些领域的迅猛发展,数据科学也是如此。
因此,重要的是要清楚地制定一种方法,从数据中做出更好的决策,以便它可以有系统地应用于新的问题;当然,这个过程可能会以“向黑暗中开枪”开始——但你至少希望你的射击随着时间的推移变得更加准确;您希望您的过程随着每个项目而改进。
在 高斯工程 我们做了许多项目,明确的目标是从数据中提取价值;这篇文章将尝试记录我们的一些经验,并为数据科学制定一个流程;我们方法的灵感来源于久经考验的科学方法…
科学方法
自 18 世纪以来,科学方法是自然科学领域的一个特征;它由一系列系统化的步骤组成,这些步骤的最终目的是验证或拒绝一个陈述(假设)。
The Phases of the Scientific Method (CREDIT: Author on Canva)
步骤大概是这样的:
1. 观察 →进行观察
2. 提问 →提问观察,收集信息
3. 假设 →形成假设——试图解释观察结果的陈述,根据这个假设做出一些预测
4. 测试→ 使用可重复的实验来测试假设(和预测)
5. 结论→ 分析结果并得出结论,从而接受或拒绝假设
6. 重做 →实验要复制足够的次数,以保证观察值/结果与理论不矛盾。
举个例子,想象你刚从学校或工作回到家;你打开卧室的灯,什么也没发生!我们怎样才能用科学方法来确定这个问题呢?
The Scientific Method Applied to Everyday Life (CREDIT: Author on Canva)
科学是增进理解的方法论;而科学方法可以被看作是 一种迭代的方法来规范进行实验的过程,这样所有的实验都可能产生更有价值、更可靠的结果——因此,更好的理解。
同样,我们希望数据科学有一个标准化的方法;也就是说,一种优先获得与分析目标相关的信息的方法。
“如果它与实验不符,那就错了。这句简单的话就是科学的关键理查德·p·费曼
数据科学方法
The Gaussian Data Scientific Method (CREDIT: Author on Canva)
在我们的组织 高斯工程 中,我们找到了一种方法,我们觉得这种方法对我们的项目很有效。像科学方法一样,它由 6 个阶段组成:
1. 识别
2. 了解
3. 流程
4. 分析
5.**缔结缔结缔结**
6. 沟通
这些阶段将得到更详细的解释,我将列出我们在每个阶段使用的一些工具/方法(我们的团队用 Python 编程,并使用各种开源工具,所以请原谅我在这方面的偏见)。
识别
“识别”阶段涉及数据科学项目目标的制定;它也可以被称为“计划”阶段。
我们发现,通过分析所讨论的数据集,非常清楚地了解我们试图实现的目标是非常有帮助的。借用 PAS 55 实物资产管理标准中的一个术语,我们试图确保我们的团队对项目的总体目标有一个清晰的视线。
在这个阶段,我们会问这样的问题:
- 根据这些数据需要做出什么决定?
- 我们希望回答什么问题?
- 对于答案,我们会对什么样的自信水平感到满意?
- 我们能阐明与这些问题相关的假设吗?它们是什么?
- 我们有多少时间进行探索?
- 利益相关者希望从这些数据中做出什么决定?
- 理想的结果是什么样的?
- 我们如何导出并展示最终结果?
对“识别”阶段有用的工具/方法:**
- 研讨会/头脑风暴会议
- 制定一个指定的空间将相关的文档和调查结果放在一起(SharePoint网站、Dropbox文件夹等)。)
- 松弛 或 微软团队 (数字协作平台)
- 特雷罗 或 阿萨纳 (帮助项目管理的应用)
了解
这个“理解”阶段就是对数据本身有一个 的总体感觉 。
在你开始迷失在细节中之前;深入各种数据源;在各个领域上进行筛选,在‘增值工作’和‘分析麻痹’之间走着细微的界限,有用的 保证你的团队对有什么 有更大的画面理解。我们在花了大量时间为我们的项目目标建立了一个视线之后才这样做——以便在下一阶段让它们在我们的脑海中保持新鲜。
在这个阶段,我们会问这样的问题:
- 数据的大小是多少?
- 一共有多少档?
- 数据在多大程度上来源于不同的来源?
- 自动导出还是手动电子表格?
- 数据是否有一致的格式(日期、位置等)。)?
- 整体数据质量如何?就数据质量的 6 个维度而言?
- 需要什么样的清洁水平?
- 各个字段是什么意思?
- 有哪些领域存在偏见问题?
Our Take on the Six Dimensions of Data Quality (CREDIT: Author on Canva)
了解数据的各个方面,例如数据的总体大小,可以帮助您决定如何进行分析;对于较小的数据,您可能希望使用 Python、Jupyter 和 Pandas 或 R;对于较大的数据,您最好将它移动到一个带索引的 SQL 数据库中(对于较大的数据,Hadoop 和/或 Apache Spark 成为选项)。
这个阶段特别有趣的是,如果你对自己的目标有一个清晰的视线,那么,随着你对数据 有了更好的理解,你就可以确定哪些方面对分析 最重要;这些是你可以首先投入大部分精力的领域。这在有严格时间限制的项目中尤其有用。
一些对“理解”阶段有用的工具/方法:**
- 研讨会/头脑风暴会议
- Python
- Jupyter 笔记本 (允许共享包含实时代码、公式和可视化的文档)
- Numpy 和 熊猫 (Python 库)
- Matplotlib和Seaborn(可以帮助查看缺失数据的 Python 可视化库)**
- (一种面向统计的编程语言)
Using Python to Visualize Missing Data with a Heatmap (Yellow is indicative of Missing Data) (CREDIT: Author on Jupyter Notebook)
Code Snippet for Heatmap (‘df’ stands for ‘DataFrame ‘— a Pandas data structure)
(以上热图是用随机数据生成的)
流程
这个“处理”阶段是关于 让您的数据进入一种准备好进行分析的状态 。
我想到了“清洁”、“争吵”和“争吵”这些词。
这里给你一个有用的现象是帕累托原则——或“80/20 法则”:
“对于许多事件来说,大约 80%的结果来自 20%的原因”——维尔弗雷多·帕累托
The Pareto Principle or 80/20 Rule (CREDIT: Author on Canva)
“流程”阶段通常会占用最多的时间;根据帕累托原则,重要的是优先考虑你投入最多时间的数据的哪些方面;你想先把注意力集中在你认为最重要的事情上,只有在必要和有时间的情况下才回到次要的领域。
在此阶段,我们可以执行以下任何或所有操作:
- 将所有数据组合成一个单一的索引数据库(我们使用PostgreSQL)**
- 识别并删除与确定的项目目标无关的数据
- 识别并删除重复项
- 确保重要数据的格式(日期、时间、地点)一致
- 删除明显与现实不符的数据,这些异常值不太可能是真实数据
- 修复结构错误(错别字、大小写不一致)
- 处理丢失的数据(nan 和 null——通过丢弃或插值,取决于具体情况)
这个阶段的目的实际上是让你在分析阶段的生活变得更容易;处理数据通常需要很长时间,可能是相对乏味的工作,但结果是值得努力的。
一些对'流程'阶段有用的工具/方法:**
- MySQL ,SQLite或PostgreSQL
- 巨蟒
- Numpy 和 熊猫 (Python 库)
- Matplotlib和Seaborn(可以帮助查看缺失数据的 Python 可视化库)
- NLTK (自然语言处理工具包——另一个 Python 库)
分析
这一阶段涉及数据的实际分析;它是对数据进行检查、探索和建模的过程——以 发现以前未知的 模式和关系。
在数据价值链中,这一阶段(以及前一阶段)是数据本身增加最重要价值的地方。这是将数据转换成(潜在的)可用信息的转换阶段。
在这一阶段,您可能希望快速可视化您的数据,尝试确定不同字段之间的特定关系。您可能想要探索不同位置或不同时间的字段差异。
理想情况下,在 识别 阶段,你会提出几个关于你想从这些数据中得到什么的问题,甚至可能会陈述几个假设——这是你实施模型来确认或拒绝这些假设的阶段。
在此阶段,我们可以执行以下任何一项操作:
- 如果有基于时间的数据,探索某些领域是否存在长期趋势——通常使用基于时间的可视化软件,如 超集 或 格拉法纳
- 如果有基于位置的数据,按区域探索某些字段的关系—通常使用制图软件,如 传单 JS ,以及空间查询(我们使用PostgreSQL与PostGIS)**
- 探索不同领域之间的相关性(r 值)
- 使用自然语言处理方法(如单词袋模型)对文本进行分类
- 实施各种机器学*技术,以识别多个变量/领域之间的趋势——回归分析可能很有用
- 如果有许多变量/字段,可以使用降维技术(如主成分分析)将其减少到保留大部分信息的较小变量子集
- 深度学*和神经网络有很大的潜力,特别是对于更大的结构化数据集(尽管我们还没有充分利用这一点)
分析阶段实际上是橡胶碰到路面的阶段;这也说明了数据科学更性感的一面。
Visualizing the Distribution of Two Variables Using Seaborn’s Jointplot (CREDIT: Author on Jupyter Notebook)
Code Snippet for Jointplot
一些对“分析”阶段有用的工具/方法:**
(注意,我们将可视化工具留到最后一节)
- mySQL ,SQLite或PostgreSQL(对于查询,包括空间查询—对于 SQLite,参见SpatiaLite)
- JetBrains data grip(py charm IDE)
- (一个探索和发布数据的工具)****
- Jupyter 笔记本 (允许共享包含实时代码、方程式和可视化的文档)
- SciPy(Python 高级计算库)
- 【NumPy】熊猫 (Python 数据分析/操纵库)
- Scikit-Learn(Python 机器学*库)
- 张量流 (Python 机器学*库一般用于深度学*和神经网络)
- Keras (用于神经网络快速实验的 Python 库)
缔结缔结缔结**
这个阶段关注的是从阶段的分析结果中得出可靠的、有价值的结论。在这个阶段,你可以清楚地回答你的问题;在这个阶段,你可以证明或者否定你的假设。在这个阶段,你还可以利用你的结论,产生可操作的项目,以帮助实现目标(如果合适的话)。
我们通常旨在创建一个从分析中得出的结论或“发现”列表,以及一个基于这些发现的后续建议行动列表。列出行动时应该考虑到你的目标受众:他们想简洁地知道 发现了什么 和 他们可以用/关于它做什么 。
在此阶段,我们可能会执行以下任何一项或全部操作:
- 交叉检查调查结果和原始问题(“识别”阶段),并确定我们已经回答了什么
- 拒绝或接受“识别”阶段的各种假设
- 对结论/调查结果进行优先排序,哪些结论/调查结果对利益相关方最重要——哪些最重要?
- 尝试将结论编织成某种形式的故事
- 确定跟进问题
- 确定行动将产生最有价值结果的高度优先领域(帕累托原则)
- 根据结论制定建议和/或行动(特别是在高度优先领域)
一些对“总结”阶段有用的工具/方法:**
- 研讨会/集思广益会议
- 微软办公软件(Excel、PowerPoint、Word)
- 【80/20 法则】
传达
可以说,数据科学方法中最重要的步骤是“交流”阶段;在这个阶段,你 确保你的客户/观众/利益相关者理解你从他们的数据中得出的结论 。
还应该以这样一种方式向他们展示这些,以便他们能够采取行动——因此,如果你不建议采取行动,那么应该展示结论,以便激发他们采取行动的想法。
在这个阶段,您将自己的发现和结论打包成美观、易于理解的可视化、演示、报告和/或应用程序。
A Geographic Visualization Using Apache Superset (CREDIT: Apache Superset)
在此阶段,我们可能会执行以下任何一项操作:
- 如果有基于时间的数据,使用像 【格拉法纳】 或 超集 这样的软件包创建性感的时间序列可视化
- 如果有空间数据,使用 传单 JS ,Plotly或 超集 等软件包创建性感的地图可视化**
- 使用D3 . js,Matplotlib或 Seaborn 创建统计图**
- 将各种可视化嵌入仪表板,并确保它们是可共享的/可移植的(无论是托管的还是作为应用程序构建的)——超集 是在组织内实现这一点的绝佳方式
- 使用D3 . js或 开发交互式可视化**
- 使用 Angular、Vue.js 或 React(或只是普通的 JavaScript)等 web 技术开发交互式应用程序或 spa(单页应用程序!)—使用 PostgreSQL 的 Psycopg2 等库将这些链接到数据上
一些对“沟通”阶段有用的工具/方法:**
- (针对时间序列)****
- Apache 超集 (探索与可视化平台;允许创建可共享的仪表板;非常适合各种数据源,包括 SQL 数据库)
- Matplotlib , Seaborn ,Bokeh(Python 可视化库—Seaborn更多的是为了统计可视化,是建立在Matplotlib)
- D3.js (一个直接将 HTML 链接到数据的 JavaScript 库,允许漂亮的、交互式的和高度可定制的浏览器内可视化)
- leaflet . js(一个用于创建交互式地图的 JavaScript 库)
- Plotly ,Altair,以及Pygal(Python 库用于交互式可视化)
- Jinja 2(Python,HTML 模板库——类似 Django 模板)
- psycopg 2(PostgreSQL 驱动通过 Python 方便数据库连接)
- vue . js和React*(SPA 库/JavaScript 框架)*****
- 微软办公软件(Excel、Word 和 PowerPoint)——用于报告
信息应导致行动
现在,就像到目前为止所陈述的那样,通过这个过程是非常好的;毕竟,它应该会产生一些声音信息。不过,要实现这些数据的任何好处,应该对从中获得的信息做些什么!
像科学方法一样,我们的方法是一个迭代的过程,应该包含行动…
所以,稍微修改一下我们的图表:
The Data Scientific Method with Feedback and Action Loop (CREDIT: Author on Canva)
通常我们也会经历这六个阶段,在我们再次重复之前没有时间采取行动。我们可能会交流发现,立即引发进一步的问题,然后我们可能会陷入另一个循环。然而,从长远来看,行动是使整个工作变得有价值的关键。
在我们的组织中,每个新的数据科学项目都由几个这样的周期组成。交流结果往往会引发新的讨论,并为探索开辟新的问题和途径;如果我们的结论导致产生有利结果的行动?我们知道我们正在做正确的事情。
“没有数据,你只是另一个有观点的人。”爱德华·戴明
本文原文, 点击此处 。感谢 杜 为数据科学方法整理原始步骤( 查看 GitHub 账号 )
一个数据科学家至少应该了解这么多 Python OOP
原文:https://towardsdatascience.com/a-data-scientist-should-know-at-least-this-much-python-oop-d63f37eaac4d?source=collection_archive---------11-----------------------
© s72677466/Adobe Stock
数据科学家处理数据,并使用建模技术来检测异常、进行财务预测、对医学图像进行分类等。这些数据虽然不会神奇地到达数据科学家的计算机;它通过管道与各种数据源连接,如实时金融系统、实时传感器数据、医疗成像设备等。这些管道由软件工程师创建,通常利用面向对象编程(OOP)的概念。数据科学家是最了解管道中流过什么的人,因此,他们将参与代码评审,与其他软件工程师交流,检查系统架构等。要成为任何团队的职能成员,一个人必须说团队的语言,在这种情况下,OOP。
此外,OOP 知识对数据科学工作本身也有帮助。例如,我们知道,数据科学家工作中最耗时的任务之一是数据清理,即删除对手头的数据科学任务无用的数据。坐在代码评审中,仔细检查系统架构,可以揭示数据流路径,在那里数据出来更干净。这可以为我们的数据科学家节省时间和精力。关于 OOP 是否应该成为数据科学家技能的一个组成部分,一直有一些争论。在其他地方,有人认为面向对象编程减少了编码开销,并为数据科学任务系统提供了健壮性【2】。
我认为数据科学家至少应该掌握 OOP 的主要概念:封装、继承、多态和对象关联。 Python OOP 是我个人比较想在面试时测试的技能。那么,我们该怎么做呢?就像一张图片胜过千言万语,一个程序胜过一百个问题。如果你在网上搜索 OOP 面试问题,酒店预订管理系统的类设计经常会出现。下面是我的测试:为一个小酒店的预订管理系统(RMS)设计类,在这个系统中,你使用了封装的概念,并且至少使用了一次继承、多态和对象关联的概念。这篇文章的其余部分描述了我们这个小练*的解决方案。
解决方案:希腊米克诺斯岛精品度假村预订管理系统的设计
© 2mmedia/Adobe Stock
为了让这成为一次有趣的学*经历,让我们为希腊米克诺斯岛一家出租别墅的精品度假村的客户经理设计课程。度假村出租四栋标准别墅和两栋贵宾别墅。贵宾别墅更大,配有私人游艇。所有别墅都配有私人助理。
我们将使用以下类对系统建模: villa、vipvilla、guest、reservation、resort。
数据封装
类必须保护最重要的资产,我们的数据。另一方面,他们必须通过使用 get/set 访问功能向外界公开某些数据来提高透明度和协同作用。这个面向对象的概念将渗透到我们例子中所有类的设计中,每个类都将被设计成包含数据,并且只包含与现实世界中的类特征相关的数据。
其中特权最少的一类是别墅,从这个意义上来说它封装了最少的数据(别墅的名字和别墅私人助理的名字)。它还提供了一些信息功能,包括私人助理的待命时间,别墅清洁和更换钥匙的日期。此外,它还具有打印留在每位新客人房间的礼物标签的功能:
Class guest 封装了客人的以下属性:名和姓、房间中的成人数量和儿童数量。它提供了对客人姓氏的访问功能和对客人对象的打印功能。
遗传和多态性
Class v ipVilla 提供了实现类继承和多态的例子。正如我们在下面看到的,该类继承自类 villa ,并且它重新定义了基类方法 setPersonalAssistant() 。哪个方法被调用,由 Python 使用方法解析顺序进行解析。
对象关联
度假胜地提供了这方面的例子。方法 setGuest() 和 setReservation() 分别接受类型为 guest 和 reservation 的对象。在封装方面,类 resort 封装了以下属性:包含(标准)别墅名称的列表、包含 VIP 别墅名称的列表、客人列表、预订列表和预订 ID 列表。
我们最后的类是 reservation ,它封装了预订的以下属性:预订别墅的名称、入住日期、退房日期、预订 ID、预订类的打印功能。
github 上有完整的代码和一个测试模块:https://github . com/theomitsa/python/blob/master/mykonos 2 . ipynb
数据科学家的视觉音频比较方法
原文:https://towardsdatascience.com/a-data-scientists-approach-to-visual-audio-comparison-fa15a5d3dcef?source=collection_archive---------5-----------------------
Beatles 1965 “Help” album art
在本文中,我演示了一些我创建的自定义方法,以直观地比较多个音频文件的频域。这些工具在许多情况下都很有用。对于这里的音乐爱好者来说,我们可以使用这些工具来检查同一首歌的不同版本之间的差异(我在本文中演示了这一点)。或者你可能在音频录制/编辑行业工作。这些可以用来查看您自己的主设备在过程的各个阶段是如何变化的,甚至可以可视化空间中麦克风放置的效果。
基本上,如果你有两个音频文件,这些工具可以让你看到它们之间的区别!
如果你有兴趣使用你在这里看到的一些代码,去看看这个项目的 github repo 。
项目和演示
我正在为这个项目使用 python,我使用一个名为 Librosa 的包和一个名为 FFT ( 快速傅立叶变换 ) 的过程从我的音频文件中提取频率数据。如果你有兴趣学*更多关于 libroso 的知识,以及它如何帮助你在 python 中处理音频,这里有一些很棒的文档。
一切都是围绕我为这个项目设计的两个自定义类构建的。一个处理音频处理,另一个帮助产生比较可视化。
这些工具可以比较任何两个音频文件。但是我认为它们真正的亮点在于展示了相对相似的文件之间的差异。正因为如此,我在甲壳虫乐队的歌曲《昨天的 T12》的一个原始版本和两个重制版本中演示了它们的使用。你可以听下面每个版本的录音。
1965 年原版:
2009 年重制:
2015 年复赛:
在继续阅读之前,我鼓励你听几秒钟,看看你是否能听出一些不同之处。你能具体定义这些差异吗?如果没有,希望这个分析能帮助你看到和理解音频是如何从一个版本变化到另一个版本的。
我们开始吧!
加载数据
将音频数据放入 Librosa 实际上非常简单,但是分析和频率转换可能需要一点代码。为了获得最佳的分析结果,我们需要知道每个文件的采样率,如果文件之间的采样率匹配也是最好的。这里,它们都是 44.1 kHz(相当标准的采样速率)。
我的AudioAnalyzer
类负责将音频转换成 librosa 并将其转换到频域。同样,如果您有兴趣查看所有这些的完整代码,请查看我的项目库。
Initialize the AudioAnalyzer instances
input_sr 代表输入采样率,每个文件设置为 44100。我们还将 fft_size 设置为 44100。FFT 基本上是一种获取时域数据并创建特定数量的仓来放置频率信息的方法。为了使 FFT 大小与采样速率相匹配,我们使每个频段正好为 1 Hz。如果你有兴趣阅读更多关于 FFT 的内容,请查看本页。
在幕后,我们加载音频,通过 FFT 处理,然后平均每个频段的幅度,以获得每个文件的单一频谱。
AudioAnalyzer 类已经可以为我们生成一个简单的声谱图。
plotting individual spectrums
从代码中可以看出,我已经指定了最小和最大频率。这只是为了让我们能够聚焦于一个特定的范围,在这个范围内,我们将能够更清楚地看到一切。此外,请注意,在下图中,每个谱图的 y 轴(振幅)都被缩放到 0 到 1 之间。当比较这些光谱图时,把所有的东西放在同一个尺度上是有帮助的。
从这些图表中,你可能会认为它们看起来很相似。那是因为他们有。像这样并排比较频域是相当困难的(这也是我写这篇文章的原因!).幸运的是,我有另一个类可以帮助我们更好地可视化和比较差异。
比较音频
我用另一个类SpectrumCompare
处理两个音频文件之间的比较。这个类接受我们之前创建的两个AudioAnalyzer
实例,并在后台运行一些计算来帮助我们比较它们。
让我们来看看。
Initializing SpectrumCompare class
就这么简单!我们现在可以在我们的orig_to_09
实例上调用一些不同的绘图方法来比较原始的 1965 年版本和重新制作的 2009 年版本。
首先,让我们绘制这两个文件的光谱图。
Plot basic spectrum group
有了这个视觉,比较这两个版本的频谱就容易多了。
快速浏览一下,似乎重新灌制的版本在所有频率上都有更高的振幅。但是振幅的差异在所有范围内都是一致的吗?如果不是,更大的差异在哪里?幸运的是,SpectrumCompare
可以帮助我们回答这些问题!
Plot full spectrum group with threshold
通过在plot_spectrum_group
中传递一些其他的参数,我们可以看到振幅在不同的频率区间是如何变化的。这里的绿线显示缩放幅度的差异,红线是阈值。当绿线位于红线上方时,意味着重制版本在该频率仓中具有更高的振幅。当它在下面时(在这个特殊的例子中我们看不到),这意味着原始信号在那个频率上有更高的振幅。
注意:将
AudioAnalyzer
实例添加到SpectrumCompare
初始化的顺序将决定红线的哪一侧意味着哪个频谱的幅度更大。中的第一个得到下半部分,第二个得到上半部分。有关更多信息,请参见项目报告。
我们可以证实我们最后的观察结果,即重新灌制的版本在标绘的光谱范围内往往具有更大的振幅。我们甚至可以看到许多峰值形成的位置,以及它们在大约 700 Hz 后开始变平的位置。
虽然这张图肯定让我们更直观地了解了这种比较,但我认为它可以简化一点,仍然给出相同的一般信息。为此,我们可以使用SpectrumCompare.plot_spectrum_heatmap
方法。
Alternative heatmap plot
太好了!现在,这看起来更令人愉快,并且提供了所有相同的信息。我们的红色和绿色线条已被热图背景所取代。通过这张热图,我们可以看到有几个特别的热点。如果我们想让我们的分析更精确一点,我们可以使用frange
参数来放大特定的范围。在这里,看起来大多数热点出现在 100-500 赫兹之间(对于许多男性声乐和器乐来说,这是一个相当丰富的范围)。
Heatmap from 20–500 Hz
在这个更*的范围内,我们可以看到,在 180 Hz 左右的某个地方,有一个非常重要的热点,表明重新录制的版本在该频率下具有更高的幅度。该音域对应于 F3 左右,这是一个舒适的男声音域,正好在吉他音域的中间。这也恰好是这首歌的关键(F 大调)。此外,随着频率越来越接* 500 Hz,我们可以看到这些热点开始消退。
因此,我们可以从这一视觉分析中得出一个结论,即重新灌制的版本似乎强调了从 180 Hz 到 500 Hz 的范围。这些热点是相对包含的,我们没有看到任何特别广泛的区域,其中振幅在重制中得到显著提升。因此,这些微妙的变化可能会反映出对主要声乐和器乐线条的更多强调。
简单介绍一下这个过程之后,让我们看看这些不同版本之间的其他一些比较。
接下来,我们来对比一下 1965 年的原版和 2015 年的复刻版。
Comparison of original to 2015 remaster
先说这个对比和上一个的相似之处。从频谱组图中,我们可以再次看到,在重新灌制版本中,所有标绘频率的振幅普遍增加。然而,如果我们观察 100–400Hz 范围,频率的增加似乎更广泛一些。也就是说,它不仅仅集中在几个峰值周围,而是在整个范围内更加分散。
为了证实这一点,我们可以看看我们的热图。果然,我们看到 180 Hz 范围以下有一些更宽的热点。此外,90 Hz 和 110 Hz 附*的热点在我看来似乎更亮一些。这似乎表明,除了强调中间音域,2015 年的这张专辑还增加了一些低音。
但要真正测试这一点,让我们比较两个重制版。
Comparison of 2009 and 2015 remasters
这些结果并不明显,这本身就是一个有趣的观察。基本上,当谈到改变情商时,这两位大师做出了很多相同的美学选择。
在我们的光谱组图中,我们的绿线主要围绕红线。由于 2015 年版本是我们的SpectrumCompare
类的第二个输入,红线上方的绿色意味着 2015 年的 remaster 在这些频率下具有更高的振幅。有一些地方,它下降到阈值以下,这意味着 2009 年的版本有更大的幅度,但只有少数这样的情况。
特别有趣的是,我们可以在 100–200Hz 之间的 2015 版本中看到一些更大的振幅。正如我所怀疑的那样,2015 年的 remaster 似乎有一些低音增强。
通过查看我们的热图可以确认这一点。这里,我将范围限制在 20–200Hz,这样我们就可以看到这个较低范围的细节。虽然热点不是非常明显,但我们肯定可以在 180 Hz 以下看到它们。因此,我们可以确信,2015 年版确实有一些 2009 年版没有的低音增强。
TL;速度三角形定位法(dead reckoning)
如果你跳过了所有冗长的部分,只是浏览了一下图表,这就是结论。两个重新灌制的版本似乎都比 1965 年的原版声音更大,并且彼此相对相似。特别是,翻唱者强调了歌曲的主要声乐和乐器范围(180-500Hz 之间),2015 年的版本也增加了一些低音增强。
考虑到这一点,你可能想回去再听一遍这三个版本,看看你是否能听到这些特征。此外,看看你是否喜欢其中一个。我个人认为,2009 年的重新灌制很好地平衡了旋律的重点和整体清晰度。
同样,请随意查看我的 github 库,并在其他音频上尝试代码。
我希望你喜欢这个视频音频比较的简短探索。感谢阅读!
一位数据科学家从数独到 Kaggle 的旅程
原文:https://towardsdatascience.com/a-data-scientists-journey-from-sudoku-to-kaggle-120876b7fa33?source=collection_archive---------6-----------------------
与 Rohan Rao 的对话:数据科学家、Kaggle 特级大师、印度数独卫冕冠军
Rohan(4th from L)along with other winners of the Brands Brain International Challenge’2019
如果你把足够多的聪明人聚集在一个地方,好事就会发生。埃里克·赫斯曼
成为 H2O.ai 一员的额外好处之一是,你可以和这个星球上最聪明的人一起工作。在这里,你可以和有丰富经验和专业知识的人*距离接触。这里的一组专家是 Kaggle 特级大师 ,他们一次又一次地证明了自己在数据科学领域的实力和专业知识。
我有机会与我的同事 Rohan Rao 互动,他是一位 Kaggle 特级大师,也是 7 次全国数独冠军,我想将对话分享给社区。通过这次谈话,你将有机会了解他的旅程、灵感和成就。你还将了解是什么激励他去竞争,是什么让他保持动力。
奥汉·拉奥,在 Kaggle 上的名字是 Vopani,他身兼数职。除了是一名四重 Kaggle 特级大师 和 H2O.ai 的数据科学家之外,他还是一名出色的数独和解谜专家,被广泛认为是印度最好的数独解谜专家。
他是数独和拼图的 15 次全国冠军,是第一个排名世界前 10 的印度人,也是唯一一个在 2018 年和 2019 年亚洲锦标赛上登上领奖台(前 3 名)的印度人。他最*赢得了最新一届的全国数独锦标赛,还在今年 7 月曼谷举行的著名的 Brands Brain 国际挑战赛中获得了第二名。
[## Rohan Rao -维基百科
Rohan Rao 是一个印度数独和解谜者,被广泛认为是印度最好的数独解谜者。他是 15 次…
en.wikipedia.org](https://en.wikipedia.org/wiki/Rohan_Rao)
以下是我与 Rohan 对话的摘录:
- 你是第一个进入数独世界前 10 名的印度人?最初是什么激励你开始玩数独?
Another podium finish — Winner of National Sudoku Championship’2019
罗汉: 我从小就对逻辑、数字、模式、运动着迷。2005 年,在孟买的一场比赛前一天,我学会了解数独,最终我赢得了 U-16 组别的比赛。那是我的转折点,出于兴趣和爱好,我开始积极地追求它。
作为一个天生的问题解决者,我认为数独是一个需要解决的问题。通过消除和输入数字的逻辑路径最终得到解决方案,总是给我一种成就感和幸福感。
多年来的练*、准备、勤奋和努力使我赢得了各种国内和国际冠军。这让我有机会代表我的国家参加这项运动,并帮助我实现了成为第一个进入世界前 10 名和亚洲前 3 名的印度人的目标。
- 你是如何对数据科学产生兴趣的?擅长解谜在其中有作用吗?
Rohan:完成应用统计学硕士学位后,我一直在寻找可以应用统计学解决现实问题的领域。我发现数据科学(DS)是一个令人兴奋的工作领域,它使用了大量的数学和统计学。幸运的是,我在 2013 年获得了我在一家机器学*(ML)咨询公司的第一份工作,在那里我开始了我的职业生涯。
数独和 ML 一开始是独立的兴趣和工作领域。虽然最初很难跟上两者,但逐渐发现了两者重叠的一些领域。
数独教会我思考、制定策略和计划解决一个给定的问题。它帮助我建立了精神上的耐力、速度,以及找到脱颖而出的解决方案的关键要素的能力。
另一方面,ML 教会了我如何巧妙地将理论见解和想法结合到实际的动手解决方案中。它让我体会到分析的重要性,多维度的洞察力,以及将解决方案优化到边缘的概念。
- 成为 Kaggle 特级大师是一项令人印象深刻的壮举,需要极大的毅力和努力。你和 Kaggle 的幽会是如何开始的,是什么让你在你的大师之旅中一直保持动力?
Rohan’s Kaggle Profile
罗汉: 我很幸运在我工作的最初几年有一位伟大的导师,他让我接触了 Kaggle,并与我密切合作。然后,我的竞争精神、渴望和取得成功的动力占据了我的心头,这是我整个旅程中不变的动力。
成为 Kaggle 特级大师无疑是我职业生涯中的一个决定性时刻,这涉及到一些个人牺牲以及来自家人和朋友的大量支持。
- 就数据科学而言,您最喜欢的资源是什么?你更喜欢哪种编程语言?
罗汉: Kaggle、Google、Stackoverflow 会是我的前三名,一点也不奇怪。根据问题陈述的不同,有许多有用的 Github 库和开源库/包都可以为构建解决方案增加价值。
我从 R 开始,它仍然是我首选的 DS 语言。随后我学*了 Python 和 Scala,过去几年我一直在使用 Scala 构建生产就绪的解决方案。
- 很多人,尤其是新手,被 Kaggle 弄得不知所措?对于他们应该如何对待数据科学竞赛,有什么建议吗?
Rohan:ka ggle 已经变得浩如烟海,拥有大量有用的信息、代码、想法、讨论和解决方案。由于可用内容的庞大和深度,一开始可能会有点让人不知所措。
我的建议是开辟一条道路,根据目标,确定小任务,花时间完成它们。在最初阶段,最好完全专注于一项比赛。人们可以从探索内核开始,并参与比赛的讨论。接下来可以参加不同类型的比赛,一个接一个地获得最大的曝光率。
- 作为 H2O.ai 的一名数据科学家,你的角色是什么?你在哪个具体领域工作?
Rohan:作为 H2O.ai 的 Kaggle 特级大师,我的职责主要是开发 H2O 的产品,如无人驾驶 ai,以帮助我们的客户为各种行业的广泛用例构建机器学*解决方案,包括金融科技、制造、零售、医疗保健和营销。我专攻推荐引擎、信用风险建模、数字支付生态系统和优化数字营销活动。
Makers gonna Make
挑战是双重的:为可扩展的机器学*解决方案建立一个行业无关的平台,以及通过与数据或模型或领域专业知识有关的各种方法实现智能,并能够将一切结合到端到端的打包产品中。
- 你通过 Kaggle 学到的最好的东西有哪些是你在 H2O.ai 的专业工作中应用到的?
罗汉:ka ggle 上的问题种类繁多,各有各的处理数据、建立模型、优化解决方案的方式。对我来说,最重要的学*是理解数据集,然后设计数据科学解决方案框架的能力。
我自动化了机器学*工作流的许多组件,以提高我在 Kaggle 比赛中的效率。我现在使用其中的许多模块来增强 H2O.ai 的产品,如无人驾驶 AI 用于构建跨各种行业的机器学*解决方案,以便在更广泛的生态系统中可用。
- 总的来说,最*有很多关于 ML 和 AI 的炒作。你对此有什么想法?
Rohan:理解人工智能正在跨行业取得巨大突破,并在围绕其构建的产品和应用中拥有光明的未来是至关重要的。同样重要的是要认识到,几乎所有的创新解决方案都极其难以开发,并且是经过多年研究开发出来的,而不仅仅是魔术。
随着时间的推移,它将逐渐成为我们生活中不可或缺的一部分,有望解决世界上的许多问题,它将变得更容易理解、构建和分享。
- 你希望在 ML 的哪些特定领域或问题上运用你的专长?
Rohan:利用数据和 ML 预测全球范围内的犯罪是我最感兴趣的领域之一,它可以在世界上产生重大的积极影响。
- 对刚刚开始或希望开始数据科学之旅的数据科学有志者有什么建议?
Rohan:DS 正在成为一把巨大的保护伞,拥有许多令人兴奋的工作和项目,涉及各种行业。许多有抱负的人会被信息的内容和深度所困扰。
我给其他人的建议是,确定一个适合他们技能的领域,然后朝着这个方向努力解决问题。在任何 ds 工作中亲自动手是必不可少的,因为只有这样,一个人才能理解个人资料的所有细节。作为全职贡献者,作为公司/团队的一部分参与 DS 项目也是更好的选择,因为这样可以暴露 DS 项目的整个工作流程。
这需要大量的努力、时间、耐心和牺牲。记住这一点将有助于你更好地准备快节奏的 DS 社区,并增加你成功的机会,同时享受这个过程中的工作和旅程。
成功从来都不容易。这往往是一条充满艰难险阻的艰难之路。耐心、毅力和实践是构成成功支柱的三大美德。大师不是一天出来的。相反,他们日复一日、年复一年地不懈努力来实现他们的目标。希望这次谈话也能启发和激励你朝着你渴望的人生目标努力。
将分类变量编码成数字的数据科学家工具包
原文:https://towardsdatascience.com/a-data-scientists-toolkit-to-encode-categorical-variables-to-numeric-d17ad9fae03f?source=collection_archive---------13-----------------------
将分类变量编码成数字变量是数据科学家日常工作的一部分。我一直想为需要编码分类变量的读者写下一些提示。本文中的技巧在我的专业工作中经常使用。我希望本文能够帮助您进行任何额外的转换,以增强您的模型性能。以下是一些技巧:
(A)一个热编码
(B)均值编码(目标编码)
(C)证据的份量
(D)留一编码
顺序编码
(F)散列编码:
因为您可能会为新的变量制作数据可视化展示,所以值得看一看我关于数据可视化的系列文章,包括“ Pandas-Bokeh 使令人惊叹的交互式绘图变得容易”、“使用 Seaborn 使美丽的绘图变得容易”、“用 Plotly 实现强大的绘图”和“用 Plotly 创建美丽的地理地图”。我在数据可视化文章中的目标是帮助您轻松地和熟练地制作数据可视化展示和见解。如果您想采用所有这些数据可视化代码或使您的工作更加熟练,请查看它们。我写过关于各种数据科学主题的文章。为了方便使用,你可以将我的总结文章“数据人学*之路——培养你的技能,推动你的职业发展”加入书签,其中列出了所有文章的链接。
[## 通过我的推荐链接加入 Medium-Chris Kuo/data man 博士
阅读 Chris Kuo/data man 博士的每一个故事。你的会员费直接支持郭怡广/戴塔曼博士和其他…
dataman-ai.medium.com](https://dataman-ai.medium.com/membership)
(A)一键编码
哑编码和一热编码是一回事;前一个术语来自统计学,后一个术语来自电气工程(电子学)。让我解释一下细微的区别。因为回归模型只能接受数字变量,统计学早就通过将一个 n 值的分类变量转换成 n-1 虚拟变量解决了这个问题。为什么 n-1 ?这是为了避免多重共线性的问题(稍后解释)。一键编码将 n 个值的分类变量转换为 n 个虚拟变量。所有创建的变量都有值 1 和 0。然而,今天的软件允许您创建所有的虚拟变量,并让您决定删除哪个虚拟变量,以防止多重共线性问题。
有许多 Python 模块处理一键编码。在这里,我提出了得到 _ 大熊猫的假人和 OneHotEncoder 的分类 _ 编码器。您可以通过pip install category_encoders
安装模块encode_category
。为了向您展示一个真实的案例,我使用 Kaggle 的数据集家庭信用违约风险来演示编码方法。有 18 个类别加上变量“职业类型”的缺失(NaN),如下所示。
(A.1)获取 _ 虚拟
使用pd.get_dummies(df['OCCPATION_TYPE'],dummy_na=True)
创建虚拟变量。然后,我将虚拟变量追加回数据中。结果变成:
给你的提示:
- 删除一个级别以避免回归中的多重共线性:请注意,我删除了虚拟的“劳动者”。我为什么放弃它?如果您正在运行回归模型,则需要删除与其他变量显示多重共线性的变量。但是,如果您正在运行任何基于树的算法,则不需要删除该变量。你可以在我的文章“避免这些致命的建模错误,这些错误可能会让你失去职业生涯”中找到更多的解释。
- 选择可信计数的级别作为基础级别:为什么我删除了“劳动者”而没有删除其他类别?原因是的可信度。在回归中,分类变量的删除值成为其他值将引用的基础级别。如果下降值的计数太少,就不好作为其他级别参考的基准级别。例如,假设你有一个变量“state”,按字母顺序排列的第一个状态是只有三个观测值的“AK”。R 等很多语言都是以首字母级别作为参考级别,所以“AK”就成了参考级别。但是,它在您当前的数据集中只有三个观测值!如果重复相同的数据绘制过程,可能会少于三次观察。更好和更常见的做法是设置最频繁的级别或具有足够数量的观察值的级别。
- 不要忘记丢失的值:注意我使用了
dummy_na=True
。如果你不把 NAs 明确作为虚拟变量,你可能会忘记它,它将成为你回归的参考水平。如果 NAs 的数量碰巧很少,您将遇到如上所述的可信度问题。还可以看看我的帖子"避免这些致命的建模错误,这些错误可能会让你失去职业生涯"如果一个连续变量有" NA "," 0 ","-99 "或"-999 "该怎么办"。
(a . 2)OneHotEncoder of Category _ encoder
我指定handle_unknown='indicator'
来创建未知的类别“OCCUPATION_TYPE_nan ”,它是缺失值的类别。
独热编码或哑编码的缺点是,如果一个分类变量有许多类别,它会创建一个非常大的稀疏矩阵。例如,如果您对美国的 41,700+邮政编码使用 one-hot 编码来转换变量“Zip_code ”,您将得到一个巨大的矩阵。你的模型会变得非常低效,容易过度拟合。我们有更好的方法吗?是的。我们来看看下面的技巧。
(B)均值编码(或称目标编码)
目标编码只是将每个类别替换为具有该类别的样本的平均目标值。下面的代码将一个类别的平均值分配给一个类别的观察值。
给你的提示:
- 目标编码可能会受到过度拟合的严重困扰,因为它使用了有关目标的信息,称为目标泄漏。
- 为了克服这个问题,您可以向新变量添加微小的随机值,以便不要过于精确地适应训练数据。你可能会问多小才算小?下面的代码生成从 0 到上限值的噪声,上限值是目标平均值的一部分(=0.3)(您可以将前十个记录与上面的记录进行比较)。这个分数
cntrl
控制随机值的大小。你如何确定这个分数?在建模过程中,您会尝试不同的值。您应该确定一个值,使您的测试数据达到最佳性能。 - 使用模型预测新记录时,不需要向新变量添加随机值。
(C)证据权重(WOE)编码
证据权重(WOE)是在信用风险建模中广泛使用的技术,或称为违约概率建模(这种模型预测申请人偿还贷款的能力)。
这种转换的目标是获得与目标变量相关的分类类别之间的最大差异。它计算每个分类类别中响应者和非响应者的数量,然后为每个分类类别分配一个数值。在这种转换中,目标变量的信息已经被利用。当一个分类变量包含许多类别时,WOE 是一个不错的选择。WOE 变换可以扩展到连续因变量。由于其有价值的应用,我在(B.1)和(B.2)中描述了两个场景。
(B.1)带有二进制目标变量的 WOE
在违约概率模型中,目标值不是好就是坏(违约)。所以在这里,我只是采用流行的 WOE 公式,它仍然使用“好”或“坏”的术语,如下所示:
在 Kaggle 的这个数据集家庭信用违约风险中,目标变量“target”有两个值:“1”表示客户无法偿还贷款(贷款违约,或不良贷款),“0”表示客户可以偿还贷款(良好贷款)。
下面我写一个简短的 Python 函数来计算 WOE。首先,我创建了一个“NoData”类别,以确保缺失值被算作一个类别。对于每个类别,我计算记录总数和“好”记录的数量。然后,我得出“好”和“坏”记录的百分比。WOE 值是“好”和“坏”百分比之间的奇数比。
图(1)显示了变量“职业类型”的权重系数。请注意,它是按升序排列的。
Figure (1)
我将每个类别的 WOE 值追加回原始数据。前十个记录打印在图(2)中。
因为 WOE 转换使用 X 和 Y,所以知道您仅使用训练数据来生成图(1)中的 WOE 表是很重要的。然后将该表追加到训练数据中。您还将把 WOE 表附加到测试数据中。
您也可以使用模块 category_encoders 的函数WOEEncoder()
来计算 WOE。下面是如何执行 WOE 转换。您会发现无论使用 my 函数还是WOEEncoder()
,图(2)中的 WOE 值都是相同的。
Figure (2)
如果目标是连续变量呢?你可以将预测因子分成 10 或 20 等份,然后计算相应的权重。
给你的提示:
- 特别适合逻辑回归:逻辑回归拟合预测因子的线性回归方程,预测 logit 转换二元 Goods/Bads 目标变量。Logit 转换就是概率的对数。因此,通过在逻辑回归中使用 WOE 转换的预测因子,预测因子被编码为相同的 WOE 等级,并且线性逻辑回归方程中的参数可以直接比较。
- 记住为缺失值创建“NoData”值
- 与目标的单调关系:在目标变量和 WOE 转换变量之间。关于具有单位相关性的响应的对数几率,WoE 变换是严格线性的。
- 没有必要限制或限制离群值:给定分类类别,离群值将落入分类类别。每个箱的 WOE 值是好的到坏的分布,对异常值的关注消失了。
- 您应该只使用您的训练数据来创建图(1)中的 WOE 值。您不应该为测试数据单独创建 WOE 值。
(B.2)连续目标变量的故障树
假设现在目标变量是数据中的总收入,我们想在“职业 _ 类型”上回归总收入。因为目标变量是连续的,我们将把 WOE 公式修改为:
我们的连续目标 WOE Python 函数变成:
Figure (3)
图(3)显示了连续变量的 WOE。当我将 WOE 值追加回原始数据时,前五条记录具有以下值:
(D)留一(LOO)编码
不要混淆留一法(LOO)编码和留一法交叉验证(LOOCV)。LOOCV 是一种模型验证技术,用于评估您的机器学*模型将如何推广到独立的数据集。
正如(C)中所讨论的,目标泄漏——使用关于目标的信息,会导致严重的过拟合问题。泄漏是如何发生的?这是因为目标与数据中的预测值在同一行。当您导出平均值或其他统计数据时,该行被包括在内,目标值被泄露。为了克服这样的挑战,留一编码产生相同分类级别的所有行的目标平均值,不包括行本身。它将行本身的目标值排除在外—因此得名留一(Leave-One-Out)。这避免了直接的目标泄漏。
我将首先使用 category_encoders 中的 leave-one-out 函数向您展示这有多容易。然后我写下我的函数,向你展示它是如何产生的。
Figure (4)
下面的“我的函数”首先按类别获取计数和总和统计信息,然后将统计信息追加到数据中。现在关键的步骤是第 12 行,它减去该行本身的目标值以获得平均值。
Figure (5)
图(5)中的留一分数与图(4)中的分数相同。
(E)序数编码
序号编码使用附加信息将类别变量转换为数值。教育水平就是一个很好的例子,如图 6 所示。它可以用一个标签(EDU_1)来编码,也可以用完成这个级别的年数来编码。类别编码器模块使您能够做到这一点。
Figure (6)
给你的提示:
- 数字差异很重要。所以你需要考虑数字是否有意义,你的解读是否一致。
(F)哈希编码
如果使用一键编码来转换高基数分类变量(比如邮政编码),最终将得到一个巨大的稀疏矩阵。稀疏矩阵效率极低,并且会导致模型不稳定。哈希编码可能是更好的解决方案。散列编码在 Kaggle 竞赛的讨论中变得流行起来。它类似于一键编码,但是投影到的维数要少得多。哈希编码使用哈希函数将 N 级转换为 M ≤ N 列。
它是如何工作的?让我用图(H)来告诉你细节。首先,通过 MD5 散列函数将每个分类值转换成十六进制值。MD5 算法是一种广泛使用的哈希函数。你可以用这个 MD5 哈希生成器来玩。第二,十六进制值被转换成十进制值,你可以通过这个十六进制到十进制转换器来模拟。然后十进制值除以列长度(下面的代码示例使用 4)得到余数。你可以用这个长除法计算器得到余数。最后,余数指示打开或关闭哪一列(1 或 0)。请注意,您无法通过反向查找来确定输入是什么。所以哈希不是可逆的。
Figure (7): Hashing Encoding Process
模块 category_encoders 可以很容易地完成散列编码。下面显示了代码。我设置了n_components=4
,所以结果有四列。默认值为 n_components=8。如果您将 n_components 设置为与级别数相同,哈希编码将成为一次性编码。
分配给每列的分类级别是什么?我对每一列执行 value_counts()操作,并在下面显示结果。Col_0 只有一个值“NoData”,Col_1 有七个级别,依此类推。这种编码逻辑由图(7)中的过程决定。这个编码过程将一些层次折叠成相同的结果,称为碰撞。尽管丢失了一些信息,但有趣的是,除非有大量重叠,否则冲突不会显著影响性能。
给你的提示:
- 哈希编码的缺点是缺乏良好的业务解释。为什么“经理”、“司机”、“人事”都去同一个组?
- 这个过程可能很耗时。
- 如果您想要一个更易解释的结果,您可以手动分组分类级别。
其他一些编码技术,如 CatBoost 编码、多项式编码、求和编码或 James-Stein 编码,在此不做介绍。是因为以上的技巧对于我的大部分专业工作来说已经足够了,或者说未覆盖的技巧是技巧的一些变种。鼓励读者查看类别编码器以获取更多参考信息。
[## 通过我的推荐链接加入 Medium-Chris Kuo/data man 博士
阅读 Chris Kuo/data man 博士的每一个故事。你的会员费直接支持郭怡广/戴塔曼博士和其他…
dataman-ai.medium.com](https://dataman-ai.medium.com/membership)
数据可视化冒险
原文:https://towardsdatascience.com/a-data-visualization-adventure-55876196f7f8?source=collection_archive---------11-----------------------
从原始数据到数据第一名
数据可视化是艺术还是科学?条形图和折线图的清晰度是否总是胜过不寻常和/或美丽的数据?
这些是数据 viz 社区中一些两极分化的问题。你们中的一些人大声尖叫“科学!清晰!”而另一些人会快乐地死在艺术山上。
data viz 社区中的这一裂痕使得数据可视化同时受到喜爱和厌恶成为可能。例如,我的饥饿游戏图片获得了 87%的高票,获得了一个令人敬畏的原创内容奖,同时在评论区被烤得很糟糕。谢谢 Reddit。
这种爱恨交织的情况很常见。第二个例子,在的一篇博客文章中,布莱恩·皮尔斯反驳了比尔·盖茨为《连线》杂志选择的一个形象化的观点。在这篇文章中,他解释了为什么清晰更有优势。
Bill Gates Choice
Bryan Pierce’s Remix
谁在这里?我们应该专注于简单明了——还是应该专注于复杂美观?
在分享我的数据可视化项目时,这是一个我不断回到的问题。
除了详述这一困境,我还将介绍其他项目亮点,例如:
- 数据集的起源和饥饿游戏可视化思想
- 我如何使用 Python 将一个 25GB 的文件转换成 Tableau 可以使用的文件
- 我的数据可视化流程
- 在 Reddit 上被烤的娱乐价值
- 整合反馈以获得最终版本
第一部分:我如何想出数据和饥饿游戏可视化的想法
这一切都始于一个学校项目。这个项目的目标是讲述一个可视化的故事。我们可以选择任何我们想要的数据集。
我在 Tableau 上有着丰富的工作经验,我可以说我已经融入了这个社区。至少足够了解#改头换面星期一。对于一年中的所有 52 周,Eva Murray 或 Andy Kriebel 都会发布一组数据,并对其进行改造。你能猜出他们在哪天分享它吗?
这对于有抱负的数据科学家和想从事数据工作的人来说是非常好的。这对于那些想快速找到学校项目数据集的懒人来说也很棒。
就在本周,他们从西雅图公共图书馆开源数据库中分析了詹姆斯·帕特森的结账记录。因为这个文件有 3400 多万行,重 25 千兆字节#改头换面星期一先把范围缩小到只有一个作者。这样,公众可以很容易地使用它。
我认为这将是一个有趣的数据集,因为它可以追溯到 2005 年,包含书籍和 DVD 的借阅。
下一步是找出我想问数据什么问题。我的第一个想法是看看《哈利·波特》,看看图书借阅、电影上映日期和 DVD 借阅之间的关系。
然而,第一本书是在 1997 年出版的,所以我无法了解全貌。我最终转向了其他流行的书籍电影系列。
也许是暮光之城!?!?我很难拒绝。我最终选择了饥饿游戏。
第二部分:我如何使用 Python 从一个 25GB 的文件获取 Tableau 可以使用的内容
现在,我的文档中有一个 25,417,394 KB (~25 GB)的文件。尝试将它原样插入 Tableau 可能不是一个好主意。
我喜欢 Python。为 Tableau 准备数据只需几个步骤。
- 应用一些逻辑将行标记为饥饿游戏
- 想办法一次只读入一小块数据——文件太大了,会很快锁住你的电脑
- 只保留与饥饿游戏系列有关的结帐
之前的数据:
Now that’s what I call Christmas and Indiana Jones in just a 5 row sample
处理数据的代码:
The last cell is where the magic happens — just processing 50,000 rows at a time
数据后:
Catching Fire CD?!?! Hmmm…
新文件只有 17,000 KB (.017 GB)。好多了。
第三部分:我的数据可视化流程
在数据科学中,没有比数据可供分析更好的时刻了。
这个话题我觉得没有争论。尽管数据工程同样重要,也是需要推动的第一张多米诺骨牌——但只有怪人喜欢数据准备。
我们对数据可能告诉我们的东西有自己的想法。这是一个激动人心的时刻,我们将发现我们是对还是错。
我的假设正确吗?我的预测器能预测目标变量吗?我的想法有价值吗?或者所有这些努力都是浪费时间?
现在数据准备已经结束,我们将很快能够回答我们的任何问题。
Iteration 1 (made with Tableau)
我做的第一个图表是折线图。这张图表的好处是你可以清楚地看到每月有多少退房。
图书借阅量在第一张 DVD 发行前达到顶峰,但之后图书借阅量就再也没有上升过。
Iteration 2 (made with Tableau)
因为我最感兴趣的是将饥饿游戏的结帐总数可视化,所以我切换到了显示 DVD +图书结帐的面积图。
我也开始关注格式化,清除图表垃圾,减少墨迹。例如,不需要年轴标签,因为它已经很清楚了,我们有一个仅基于年值的时间序列线图。
我认为一个重要的考虑因素可能是电影在影院上映的时间。
如果这个项目是一个商业设置,其中决策和清晰度是最重要的。我可能会就此打住。
然而,我知道我想发布到 DataIsBeautiful。所以我需要继续努力,让一些东西看起来更有趣。
Iteration 3 (made with Tableau)
所以最后,我们在这里…从清晰走向美丽。我们为什么要这么做?因为我们的目标和目标受众。
人们想看新的、有趣的、令人兴奋的东西。所以我用了面积图的表亲,水流图。
在将我的 viz 发布到 DataIsBeautiful 之前,我知道我会因为违反了至少两个数据可视化最佳实践而受到一些负面评论。以下是我做的一些淘气的事情和我的理由:
- 没有 Y 轴
我希望用户更多地关注书籍和 DVD 之间的相对关系,而不是原始的结帐数量。
2.这个图的镜像本质是多余的,你只需要上半部分就可以了
这是真的,它违背了爱德华·塔夫特的数据可视化原则,只有墨水可以增加更多的洞察力(数据与墨水的比率)。然而,人们也发现,人们喜欢对称的东西。在这种情况下,我觉得对称可以使数据更令人难忘。
第四部分:Reddit 上被烤的娱乐价值
建立一个所有人都珍惜的数据可视化并不容易。人们对颜色选择等基本事物有不同的偏好。我很确定不可能让每个人都开心。
想要证据吗?发布一个 viz 到 DataIsBeautiful,拿些爆米花,看混乱展开。读了一些评论后,我甚至很难记起这是 87%的高票。
烧烤
乐观的
邱
第五部分:整合反馈以获得最终版本
发布到 Reddit 不仅仅是娱乐。有些人会给你一些有用的建议,甚至重新编辑你的帖子。我的帖子被重新混合,我添加了他们的贡献来制作我的最终版本:
Iteration 4 (made with Tableau)
最后一个假设可能是,在期待第一部电影时,图书借阅量激增。在连续上映的电影中,没有类似的图书高峰。也许是因为任何一个因为电影而倾向于阅读书籍的人已经这样做了。
此外,你会注意到,学舌鸟 DVD 奇怪地有两个尖峰。它作为两个不同的部分在不同的日期发布。
最终想法:
你不可能造出对每个人都漂亮的东西。颜色选择有最佳实践。然而,即使这些也不能让你达到 100%的快乐率。87%的竖起大拇指可能就相当不错了。
你不可能做出每个人都清楚的东西。然而,你的目标应该是让尽可能多的人理解你的观点。
我本可以更好地最大化清晰度。然而,如果我没有做出这些选择,我的帖子还会被投票排在第一吗?
在我看来,数据可视化更接*艺术。科学大多是由它建立的规则来定义的。数据可视化由不太可靠的最佳实践指导。科学不在乎你的感受和反应。而数据可视化完全是为了迎合其受众。
有时候,清晰更重要。想象一家医院使用数据可视化来做出关键决策。这与试图制作一个有趣的数据并发布到 Reddit 上是完全不同的目标。
数据可视化可以从测试和学*中受益。获得反馈是非常宝贵的。更好的办法是运行一个随机的 A 组和 B 组,你可以让每个组接触不同的版本,只改变一件事。如果目标是决策,看看他们会做出什么决定。如果目标是吸引人们,问他们更喜欢哪一个。
圣杯是清晰而美丽的。这两件事不一定要互斥。虽然要做到这两点并不容易。当时间有限时,关注你的目标和目标受众。
班加罗尔 Tensorflow 路演的一天
原文:https://towardsdatascience.com/a-day-at-tensorflow-roadshow-bangalore-8e2f96dea661?source=collection_archive---------34-----------------------
活动期间共享的所有信息的摘要。
我有幸参加了谷歌在班加罗尔举办的 Tensorflow 路演,直接看到了 Tensorflow 2.0 的所有最新进展,并与社区中一些最酷的人建立了联系。去年我没有得到确认,但我很高兴这次我有机会目睹这一事件,我决定分享事件过程中发生的所有事情。
总共有 16 场会谈,我想简单介绍一下所有的信息
Source :- https://hackernoon.com/everything-you-need-to-know-about-tensorflow-2-0-b0856960c074
主题演讲:ML 的今天和明天
简要概述了哪些发展使深度学*得以快速发展
- 与以前相比,现在可以获得更多的培训数据。开放数据集,如谷歌的 OpenImages 数据集,包含大约900 万张图片
- 计算能力呈指数增长。单个 TPU 可以提供 45 万亿次浮点运算的计算能力,并且可以堆叠其中的 64 个达到高达 100 万亿次浮点运算
- 深度学*领域的大量研究导致了与 7 年前相比,今天可以实现的许多改进。例如 RNN 必须按顺序训练,这导致训练花费了大量时间。随着 transformer 架构的出现,我们现在可以并行训练,并且能够获得更好的结果,更好地利用计算资源,花费更少的时间。类似地,如果你看到 NLP 部分,随着 BERT 及其变体架构、XLNET 和 T21 等的出现,在过去的 1-2 年里已经有了巨大的进步。
展示了 Tensorflow 在现实世界中的几个应用
- 峰会拥有 27000 GPU 的世界上最快的超级计算机使用 Tensorflow 进行极端天气预测
- 总部位于智利的初创公司 Notco 使用 Tensorflow 和深度学*来寻找使食物成为人类所需的所有东西,并试图使用健康的物品提供相同的体验。
- 印度主要的初创公司都在使用 Tensorflow。 Sharechat 利用深度学*发现用户偏好。 Dunzo 利用深度学*来估算需求。 Nobroker 利用深度学*来理解所有的房子数据。
- IITD 的学生开发了一款安卓应用程序,利用照片来判断的空气质量。他们使用了 Tensorflow Lite ,这样所有的计算都在设备上进行,不需要服务器,这样即使没有互联网连接,应用程序也能工作。
TensorFlow 2.0 更新
- Keras api :-通过将 Keras 直接集成到 tensorflow 中,该 api 变得更加简单。
- 会话死亡 :- Tensorflow 2.0 带来了急切执行,因此不再有会话。现在不需要运行会话来检查张量内部的值,直接打印张量就可以给出它的值
- Python 代码到 tensorflow graph :-现在任何用 Python 写的代码都可以通过使用 tf.function decorator 转换成 tensorflow graph。将代码转换为图形的用途是现在可以利用硬件,如 GPU
- 访问低级操作 :-低级操作仍然可以使用 tf.raw_ops 进行访问
- 移除 tf.contrib :- tf.contrib 现已移除,少量导入代码移至核心 api
- 分配策略 :-提供了许多在 GPU 之间分配工作负载的选项
- Tensorboard 升级 :- Tensorboard 现在支持 colab 和剖析神经网络性能
- 向后兼容 :-使用 tf.compat 仍然支持 tensor flow 1 . x。TF _ upgrade _ v2 脚本可用于将代码从 1.0 升级到 2.0
- 数据集和教程 :-增加了许多新的数据集和教程
- 单一模型序列化 :-单一存储模型可以部署在多个平台上
Source :- https://medium.com/tensorflow/whats-coming-in-tensorflow-2-0-d3663832e9b8
TF 文本
支持 tensorflow 内置的预处理和标记化
支持不规则张量,因为文本的张量大小不需要恒定
讨论了不同类型的记号赋予器,如空白记号赋予器、unicode 记号赋予器和单词块记号赋予器
内置了对词汇的支持,但支持所有语言是一项艰巨的任务。词块词汇生成用于减少词汇
TF Lite
TF Lite 用于在移动设备和嵌入式设备上部署设备模型。由于延迟、网络连接和隐私原因,设备上的人工智能非常重要。
TF Lite 可以在 Android、IOS、树莓、微控制器等平台上运行。
Source :- https://ai.googleblog.com/2017/10/portrait-mode-on-pixel-2-and-pixel-2-xl.html
谷歌的人像模式使用设备上的人工智能
边缘设备上的模型性能可以通过以下三种方法来提高
- 量化 :-将 32 位缩减为 8 位。许多硬件加速器,如 GPU,在 uint8 上表现更好
- 修剪:通过移除神经网络中未使用的连接/权重
- 硬件加速器 :-现在在 GPU、Edge TPU、DSP 等加速器的支持下,CPU 可以获得更好的性能
在 TF 2.0 中委托用于移动需要使用加速器(如 GPU)加速的任务。
Tensorflow Select 作为桥梁支持 Tensorflow Lite 中不受支持的操作,尽管未经优化。TF Lite 允许开发人员通过删除不必要的操作来减少二进制文件的大小。
除了手机,代码还可以在其他嵌入式设备上运行,如 Raspberry、微控制器等。不需要任何改变。
未来工作 :-
- 改进转换器,使代码在边缘设备上工作
- 更好的错误处理诊断
- 控制流支持
- 稳定运行时绑定
- 前后处理支持库
- 微控制器将增加更多运算。改进的转换和测试工具。支持 Arduino
[## TensorFlow Lite
在移动和物联网设备上部署机器学*模型 TensorFlow Lite 是一个开源的深度学*框架,适用于…
www.tensorflow.org](https://www.tensorflow.org/lite)
TF 分销战略
只需几行代码,轻松简单地支持在 GPU 上分配训练负载。支持以下策略
- MirroredStrategy :-通过在每个 GPU 中镜像相同的过程,支持在多个 GPU 上进行训练
- MultiWorkerMirroredStrategy:-适用于跨机器培训。类似于镜像策略,将工作负载分布到每台机器和每台机器中的每个 GPU
- 参数服务器策略 :-支持参数服务器
- t 策略 :-与上述策略类似,但用于 TPU 而非 GPU
tf.data input pipeline 可与任何分发策略无缝协作
[## 使用 TensorFlow | TensorFlow Core 进行分布式训练
tf.distribute.Strategy 是一个 TensorFlow API,用于在多个 GPU、多台机器或 TPU 之间分发训练…
www.tensorflow.org](https://www.tensorflow.org/guide/distributed_training)
张量流 Javascript
Tensorflow Javascript 可以在浏览器或 Node.js 中运行
TF JS 支持运行现有模型的推理,重新训练现有模型或从头开始用 Javascript 编写模型
不需要安装任何东西,TFJS 默认运行。所有数据都保存在客户端,因此具有隐私保护性。
没有服务器端调用,一切都在浏览器上运行。使用 WEBGL 获得计算所需的所有数学运算,而不是从头开始。
代码可以在笔记本电脑、手机以及 Javascript 运行的任何地方运行
TFJS 用 Node.js 运行,python 中用 Tensorflow 训练的模型可以直接用在 Javascript 中。
用于数据处理的 TFJS api 现已推出。
现在增加了反应原生支持。
参与 Tensorflow
要想参与 Tensorflow,探索 ML 学院活动正在印度各地举行。有兴趣的同学可以志愿。
Tensorflow 用户组出现在班加罗尔和其他地方,供感兴趣的人使用。
也可以加入 Tensorflow 的任何特殊兴趣小组。
可以对 Tensorflow RFC 的建议或问题进行评论
模型优化和量化
模型优化可以在两天内完成,先训练后优化或者边训练边优化。
Source :- https://medium.com/tensorflow/tensorflow-model-optimization-toolkit-post-training-integer-quantization-b4964a1ea9ba
量化 :-精度从 float32 降低到 float16。它提高了性能,减小了模型大小,但却是一种有损变换。
后期训练量化 :-训练并保存模型,使用 TF Lite 转换器转换。可以在转换过程中指定优化选项。但是有更多的损失,因为优化是在训练之后进行的
可以使用混合优化仅量化权重,或者可以通过发送代表性数据集来执行权重+激活的完整整数量化。
量化感知训练 :-在训练期间应用优化,使得网络感知到优化的发生,因此与上面相比可以执行得更好。在这种情况下,优化应用于正向训练,就像它在推理过程中是如何完成的一样。由于现在网络正被训练在它将在推理中看到的那种权重上,它可以更好地优化以在约束内实现好的结果。
更多细节在下面的链接
[## 张量流模型优化
TensorFlow 模型优化工具包是一套工具,用于优化 ML 模型的部署和执行…
www.tensorflow.org](https://www.tensorflow.org/model_optimization)
张量流扩展
Tensorflow Extended(TFX)帮助您建立完整的端到端机器学*管道。TFX 与元数据存储集成。这有助于跟踪多个实验,比较结果和模型性能等。
支持使用 Tensorflow 数据可视化(TFDV)进行数据可视化
支持预处理,如使用张量流变换进行标记化
Tensorflow 服务于版本控制并支持多种模型。
提供了一个管道示例,演示如何处理芝加哥 Cab 数据集。
[## TFX 开发者教程| TensorFlow
本教程旨在介绍 TensorFlow Extended (TFX)并帮助您学*创建自己的机器学*…
www.tensorflow.org](https://www.tensorflow.org/tfx/tutorials/tfx/airflow_workshop)
Tensorflow 的 Swift
与 python 相比,Swift 的优势在于它速度快,并且它可以直接与 C 和 Python 进行互操作。跨平台,易学易用,开源。支持差分编程。
显示 swift 的演示和 colab 代码。fast.ai 针对 Swift 深度学*的新课程发布。
[## fast.ai 拥抱 Swift 进行深度学*
杰里米的笔记:如果你想加入旧金山大学的下一个深度学*课程,讨论…
www.fast.ai](https://www.fast.ai/2019/03/06/fastai-swift/)
结论:-
总的来说,这是令人兴奋和增长见识的一天。我可以学到很多我以前没有听说过的东西,并了解所有最新的发展。我期待着未来会发生什么。
数据科学家的一天
原文:https://towardsdatascience.com/a-day-in-the-life-of-a-data-scientist-eb63cdd71edb?source=collection_archive---------15-----------------------
有些人可能想知道,数据科学家的一天是怎样的?这是我作为数据科学家的一天。我还应该说明,我的部分职责与管理相关,因此这些职责占用了我实际从事数据科学的时间,但数据科学部分仍然是我最喜欢的部分。
启动
我到办公室后做的第一件事就是喝杯咖啡。这并不意味着有一个社交活动,而是在我的咖啡机预热的时候有片刻的停顿,然后我计划我要做什么。我有一个任务和后续步骤的列表,按天排序,按优先级排序。这让我不会偶然忘记。有时候事情做不完,有时候,我不得不决定无限期地搁置一项任务,这样我就能保持专注。上周显示的是模糊的任务,但是任务的数量是真实的。
然后,我开始工作。这听起来很简单,但是我的思路可以一上午都是散乱的。我并不总是从最重要的事情开始,但是我会从一些事情开始着手。有时候是读一些新闻文章或者开始一个兼职项目。这有助于我集中注意力,进入状态。
开销
我的一天通常被人们的来访打断。这些都是很好的干扰,因为牢固的关系会在关键时刻带来高效的团队合作。我把它们视为对未来的投资。
我不会一心多用;我能有效地进行单个任务和上下文切换。
然后就是开会。我不惜一切代价避免开会。我更喜欢半小时的会议,议程紧凑,只邀请需要的人。会议是我效率最低的时间,因为即使我试图在会上工作,我的注意力也会分散。当我专注于一项任务时,我工作得更好。我不擅长多任务处理,但我知道如何有效地切换任务。
单一任务专注并不是一件坏事。每个人都喜欢多任务处理的想法,但是说实话,我们一次只能做一件事。一心多用就是一边拍脑袋一边揉肚子。任务切换正在改变我正在做的单个任务,有时非常迅速。
最后是数据!
我必须管理我的数据来自哪里,所以通常是从上一个任务的下一步开始的。在我的例子中,数据必须被安排收集,发送到数据库,然后通过我们的管道进行处理。最快两天就能搞定。对我来说,没有太多的工作,但这是一个团队的努力。
数据科学是一项团队工作。
最后,我得到了数据,并为重复的任务编写了脚本,例如本地提取数据、准备数据以及生成所需的图形和表格。结果是,我实际上花了大约 10 分钟来查看数据并确定下一步措施。
最*,我的许多数据都围绕着深度网络学*,并试图通过系统的试错来理解它们是如何工作的。不过,通常我会花几周,有时几个月的时间来获取足够的数据,以了解某个功能或问题,而我花在查看数据上的时间实在是太少了。我认为关键不仅仅是准备,而是训练,这样我只需要很短的时间来理解数据。
对于长期数据任务,我会查看数据。我研究数据。我制作了不同的有趣的图表,看看我是否能够将数据形象化,以便对正在发生的事情有一个清晰的理解。这些任务通常是更长的,有时几分钟,有时几天,有时几周。
休息
我工作日的一个重要组成部分是从工作中休息一下。我想理清思路,这样我就能以不同的方式思考,或者获得新的视角。这给了我在旧数据中发现错误或提出新问题的最佳机会。我的休息时间通常是喝咖啡的休息时间,我经常和我的工作朋友或陌生人一起喝咖啡,因为我在工作中投资网络。
淋浴是我想出最多点子的地方。当你洗澡的时候,除了洗和思考,你不会做太多别的事情。我已经想出了新的想法,在精神上遍历代码以找到 bug,并以一般的方式清理了我的头脑。
深夜
因为我的工作很有弹性,而且从研究生院开始就是如此,所以我倾向于白天少工作几个小时,晚上再补上。作为一名经理,我晚上更多的工作是回复电子邮件,但通常情况下,一周有几次,我发现自己在深夜当家里的每个人都睡着了的时候处理一些数据。我发现有一次或几次两个小时没有被任何人或任何电子邮件打扰,我已经能够赶上(或者甚至提前)我想去的地方。
第二天的前一天晚上也是我回顾我的任务清单的时候,这样我就可以寻找我错过的事情,应该优先处理的事情,以及我本周不会去做的事情。然后到了早上,我就准备跑步了。
如果你愿意,可以在 Twitter 和 YouTube 上关注我,我会在那里发布不同机器上的浓缩咖啡视频和浓缩咖啡相关的东西。你也可以在 LinkedIn 上找到我。
我的进一步阅读:
咖啡数据表
断续浓缩咖啡:提升浓缩咖啡
30 多岁开始学开车
不训练如何跑马拉松
管理敌对的经理
乐高:毁灭的故事
崩溃!石头穿过我的窗户
工匠咖啡价格过高
被盗浓缩咖啡机的故事
美国十年气象灾害:危害、暴露和脆弱性
原文:https://towardsdatascience.com/a-decade-of-u-s-weather-disasters-hazards-exposure-and-vulnerability-7eeef46b3699?source=collection_archive---------27-----------------------
在过去的四十年里,美国面临了 241 次自然灾害事件,这些事件被称为“十亿美元”事件,每次事件的成本都大于或等于 10 亿美元( NCEI,2019 )。关于这些灾害,一个令人担忧的事实是,随着时间的推移,它们的频率越来越高,随之而来的是生命损失以及对基础设施和农业的经济破坏。作为世界银行和 Mapbox 发起的#VizRisk 挑战的一部分,我决定制作一张美国天气灾害的互动地图,让人们和组织看到各种灾害的发生和破坏。我展示的数据来自风暴事件数据库,这是美国国家海洋和大气管理局(NOAA)国家气象局的产品。
A static image of the interactive map
呈现灾害风险数据的一个挑战是维度,空间(跨地理)和时间(跨时间)维度使得很难以有意义和可理解的方式总结数据。因为我显示灾难数据的目的是帮助您理解,所以我必须做出几个关于数据减少的决定。
首先,我决定不呈现每年的数据点,而是呈现 2005 年至 2016 年所有年份的总和。第二,在我的数据中有多达 48 个独特的事件,所以我决定只呈现最令人担忧的事件。我在确定 10 个最具破坏性和 10 个最常发生的事件的基础上,仅列出 13 个独特的灾难事件(两个列表中有些事件重叠)。我不改变空间维度。
Top 10 table for selecting 13 unique disaster events
作为最终输出,您可以在下拉列表中选择一场灾难,并检查其损失价值(以百万美元计)或检查其在美国各州的发生频率。
我是如何构建我的交互式地图的?
为了构建我的交互式地图,我主要依赖 Mapbox 的底图、ap I 和图形库;GitHub 用于文件版本控制和托管网站;数据争论的 Stata 和 NOAA 网站获取灾害数据。生成交互式地图的代码完全可以通过我的 GitHub 帐户获得,所以在本文中我不会过多地讨论它的细节。
最初,我用 Mapbox 创建了一个帐户,这样我就可以获得自己的 Mapbox API 令牌,因为它是使 Mapbox javascript 元素正常工作所必需的。我还获得了底图图层的令牌,这是一个“浅色”图层。
Access tokens
我选择了 light 图层,因为它为 choropleth 美国地图图层提供了一个很好的背景。
Choropleth map over a light basemap layer
一旦我有了一个浅色底图图层,我希望添加三个交互功能。首先是美国的 choropleth 地图,其次是根据下拉菜单中选择的灾难类型更新的 choropleth 地图。第三,用户可以通过在地图上自由移动鼠标指针来读取州名及其数据值。简而言之,我能够从 Mapbox 中学*两个例子并创建自己的地图。第一个例子结合了多个 Choropleth 映射。第二个例子提供了可视化数据元素的指南(使用鼠标指针)。别忘了,我在网页的右侧添加了填充来解释我的地图等。为了这个,我效仿了拉法·古铁雷斯的范例代码。我还要感谢来自 Mapbox 团队的 Deven Diliberto 和 Madison Draper,他们在我工作的不同阶段通过电子邮件提供了支持。
Interactive features of the map
创建一个 GitHub 账户并托管一个网站是一次很酷的冒险。我不知道 GitHub 能在多大程度上简化与代码相关的工作。我可以和其他初学 GitHubbers 的人分享两个关键的经验。为了能够在您的 index.html 中调用 JSON 或 GEOJSON 文件格式,请通过单击“Raw”按钮获得正确的链接。
The Raw button
如果你想上传一张图片到 GitHub 并在你的网页上重复使用,请在你的 GitHub 中创建一个文件夹(例如,“images”文件夹),然后在你的 index.html 中调用正确的文件路径。
灾难数据争论是我工作中最耗时的部分。这也是最关键的部分。值得庆幸的是,我已经在普渡大学攻读博士学位时研究过这些数据。数据清理和分析部分花了我整整两个月的时间,因为这些数据的范围相当大。我使用 Stata 进行所有的数据工作,但后来我不得不使用 convertcsv 网站将汇总的数据转换为 JSON 文件格式。
就这样了,伙计们!如果你需要的话,你可以用我的完全可用的代码来工作。如果您有任何问题,也可以通过 LinkedIn 联系我。我希望你喜欢这个互动地图,至少找出受灾最频繁、损失最大的州。
对数据质量的深入探究
原文:https://towardsdatascience.com/a-deep-dive-into-data-quality-c1d1ee576046?source=collection_archive---------8-----------------------
简介:
数据质量通常被视为处理数据的乏味组成部分。具有讽刺意味的是,通常是这个组件占据了我们大部分的时间。数据质量很可能是数据管道中最重要的组成部分,因为如果您的数据缺乏可信度和可靠性,从数据中生成的仪表板和分析将毫无用处。
数据质量面临的挑战是,没有清晰简单的公式来确定数据是否正确。就像一个没有淡水来源的池塘,数据会很快变得停滞不前。今天正确的数据,一个月后可能就不正确了。幸运的是,在验证数据质量时,有一些基本的技术和方法可以广泛应用。数据质量的一般主题是发现不满足特定需求的离群值和违反业务假设的记录集。
攻略:
在处理移动数据时,可以将数据分为三个独立的层:ETL 层、业务层和报告层。ETL 层包含源系统和目标系统之间的数据接收和数据移动的代码(例如,从应用程序数据库到数据仓库)。业务层位于原始数据和最终数据模型之间。最后,报告层包含仪表板,业务用户可以从中查看和交互。在接下来的部分中,我们将介绍适用于每个数据层的技术。
下面的例子是用 Postgres SQL 做的。我将使用两个表,一个点击表和一个视图表。点击表表示关于点击网页上的链接的用户的数据。“视图”表表示访问过网页的用户的相关数据。
ETL 层中的数据质量:
数据管道的第一层是 ETL 层。这一层的数据质量检查通常是相似的,与业务需求和不同的行业无关。这里的目标是检查以确保数据在从源系统移动到目标系统时不会丢失或降级。我们检查诸如行计数的差异(显示数据被错误地添加或丢失)、部分加载的数据集(通常有很高的空计数)和重复的记录。
使用 SQL 的示例:
行数
WITH
source_count as (Select count(*) as total_count from source) ,target_count as (Select count(*) as total_count from target)SELECT
CASE WHEN
(select total_count from source_count) = (select total_count from target_count)
THEN True
ELSE False
END as valid_row_count
FROM
pipe_table_1
在上面的例子中,我们正在寻找一个场景,其中来自源和目标的计数不匹配。在大多数情况下,两个表中的行数应该保持一致。这是为了确保表之间发生的转换不会意外地更改行数。例如,应用程序上的用户数量应该与应用程序数据库和数据仓库相匹配。也存在行数预计会改变的情况。在这种情况下,目标应该是验证计数是否在预期范围内。另外,需要注意的是,这里使用了 通用表表达式 来保持 SQL 语句的可读性。
加入验证
WITH join_count AS ( SELECT count(*) AS view_count FROM views LEFT JOIN clicks ON clicks.view_id = views.id)SELECTCASE
WHEN (SELECT view_count FROM join_count) = count(1)
THEN True
ELSE False
END AS valid_joinFROMviews;
在上面的例子中,我们正在检查以确保左连接后的表的行数与原始表的行数相同。这是为了确保在任一表上都没有重复的键(这通常可以由数据库强制执行,但在使用派生表或视图时则不行)。同样,该约束并不总是正确的,因为某些连接预计会导致连接记录中的行增加或减少,在这种情况下,有必要了解值的预期范围。
Image from Trifacta
业务层的数据质量:
数据管道的下一层是业务逻辑层。通常,在将原始/部分转换的数据加载到数据仓库中的临时区域后,会应用该层中的数据质量检查。在通过这些检查并检查到无效行之前,您不希望将数据加载到最终目的地。这里的目标是确保不违反基本的业务理解,并且数据具有业务意义。
这些业务质量检查还充当辅助检查或安全措施,以确保数据已经从 ETL 层正确地引入到数据库中(因为在 ETL 层中验证每个数据质量度量可能是广泛的和不切实际的)。
业务层检查通常包括验证数值度量是否在业务需求定义的有效范围内。
SELECT
count(*),
yearFROM views aJOIN date b on a.date _id = b.date_idGROUP BY 1,2HAVING count(*) > [EXPECTED_RANGE];--------------------------------------------------------SELECT
count(*),
year,
monthFROM Views aJOIN date b on a.date _id = b.date_idGROUP BY 1 2,3HAVING count(*) > [EXPECTED_RANGE];
一种技术是观察给定度量或测量在不同时间段的变化。在本例中,我们查看不同年份以及不同月份的视图。
我们正试图识别用户浏览量的突然意外上升或下降。区分预期变化和意外变化也是必要的。在我们的例子中,我们关注的是电子商务网站的眼球,也称为用户视图。一个预期的趋势是,在假期期间,观看次数会增加。
—验证视图数量应始终大于点击数量
SELECT CASE WHEN count(a.num_view) >= count(b.num_clicks)
THEN True
ELSE False
END as click_validationFROMviews aLEFT JOIN clicks b ON b.click_id = a.click_id
另一种常见的业务验证是检查值是否遵循特定的边界或特定的业务规则。在我们的例子中,查看页面的用户数量应该总是大于或等于点击链接的用户数量(因为在首先查看页面之前不能点击链接)。由于这些检查严重依赖于业务约束,因此确保业务规则和假设在代码和/或元数据存储库中得到适当记录也很重要。
报告层的数据质量:
报告层是数据管道的最后一层。这是最终用户与您的数据进行交互的层。然而,仅仅因为这一层通常是管道的末端,并不意味着数据工程师和数据分析师不应该利用报告层来确保数据质量。
一个简单的技巧是绘制不同时间段(年、月、日)的数据点,并直观地检查异常值。直观地捕捉数据质量错误是很常见的,在验证检查中可能不容易捕捉到。
Sample Dashboard
报告层的另一个优秀用例是创建数据质量仪表板。您可以将多个数据质量检查结合在一起,并在将数据发送给主管/业务用户之前,每天将这些指标/图表发送给您。
结论:
基本上,数据质量验证应该尽可能自动化。验证应该嵌入到数据管道代码中,但是要以一种允许毫不费力地改变它的方式。根据数据和验证的重要程度,您可能希望管道完全失败,或者标记问题,将记录移动到单独的拒绝区域,或者继续处理。
有一些工具,如 Trifacta,将有助于简化和自动化这些数据质量检查。现有的 ETL 工具,比如 Informatica,可能也已经内置了数据质量检查特性。然而,理解如何从头实现数据质量仍然很重要,以确保您实现的数据质量检查是有意义的。
在设计数据管道时,数据质量应该是一个对开发工作产生重大影响的驱动因素。数据工程师应该对他们的数据有一定的熟悉程度,以便能够改进和调试数据质量问题。值得注意的是,数据质量不应该是单个团队或个人的责任。在我看来,对工程师来说,像熟悉他们正在处理的数据一样熟悉代码是至关重要的。
本文概述了数据质量、监控数据质量的技术以及积极使用数据质量的策略。如前所述,数据质量是数据系统的重要组成部分。投入时间和资源来处理数据质量非常重要!数据质量应该和单元测试对于软件开发一样重要。
对 H2O 汽车的深入探究
原文:https://towardsdatascience.com/a-deep-dive-into-h2os-automl-4b1fe51d3f3e?source=collection_archive---------6-----------------------
H2O 汽车公司的自动机器学*概述
过去几年,对机器学*系统的需求激增。这主要是由于机器学*技术在广泛应用中的成功。AutoML 通过让来自不同背景的人使用机器学*模型来解决复杂的场景,从根本上改变了今天基于 ML 的解决方案的面貌。然而,即使有明确的迹象表明机器学*可以促进某些业务,今天许多公司仍在努力部署 ML 模型。
这是因为该行业缺乏经验丰富的数据科学家。在某种程度上,对机器学*专家的需求已经超过了供应。其次,大量的机器学*步骤需要的经验多于知识,尤其是在决定训练哪些模型以及如何评估它们的时候。如今,这种差距非常明显,人们正在努力解决这些问题。自动机器学*可能是这些障碍的答案,在本文中,我们将深入了解如何实现这一点。
自动机器学*:AutoML
自动化机器学* ( AutoML )是将机器学*应用于现实世界问题的端到端过程自动化的过程。AutoML 倾向于自动化 ML 管道中的最大数量的步骤——用最少的人力——而不损害模型的性能。
Aspects of Automated Machine Learning
自动化机器学*可以被认为是标准的机器学*过程,其中涉及一些步骤的自动化。AutoML 非常广泛地包括:
- 自动化数据准备的某些部分,如插补、标准化、特征选择等。
- 能够自动生成各种模型,如随机网格搜索、贝叶斯超参数优化等。
- 从所有生成的模型中获取最佳模型,这些模型大多数情况下是集成的,例如集成选择、堆叠等。
H2O 的自动机器学*
是一个完全开源的、分布式内存中的机器学*平台,具有线性可扩展性。H2O 支持最广泛使用的统计&机器学*算法,包括梯度增强机器、广义线性模型、深度学*等等。
Features of H2O
H2O 还拥有业界领先的 AutoML 功能(在 H2O ≥3.14 版本中可用),该功能可以自动构建大量模型,从而在数据科学家没有任何先验知识或工作的情况下找到“最佳”模型。H2O AutoML 可用于自动化机器学*工作流,包括在用户指定的时间限制内自动训练和调整许多模型。
H2O AutoML 的一些重要特征是:
- 尖端 ML 算法的开源、分布式(多核+多节点)实现。
- 高性能 Java 中核心算法的可用性。包括 R,Python,Scala,web GUI 中的 API。
- 将模型作为纯 Java 代码轻松部署到生产环境中。
- 无缝地在 Hadoop、Spark、AWS、您的笔记本电脑等上工作。
是给谁的?
H2O 的 AutoML 对新手和高级用户来说都是有用的工具。它提供了一个简单的包装函数,可以执行大量与建模相关的任务,这些任务通常需要许多行代码。这实质上释放了时间来关注数据科学管道的其他方面,如数据预处理、特征工程和模型部署。
AutoML 接口
H2O AutoML 有一个 R 和 Python 接口以及一个叫做 Flow 的 web GUI。H2O AutoML 界面设计为具有尽可能少的参数,因此用户所需要做的就是指向他们的数据集,识别响应列,并可选地指定时间约束或对训练的总模型数的限制。
H2O AutoML is available in R, Python, and a web GUI.
安装
H2O 提供了一个可以从 CRAN 安装的 R 包和一个可以从 PyPI 安装的 Python 包。在本文中,我们将只使用 Python 实现。此外,您可能想要查看文档以了解完整的细节。
依赖关系:
pip install requests
pip install tabulate
pip install "colorama>=0.3.8"
pip install future
- 使用 pip 安装
pip install h2o
每个新的 python 会话都从初始化 Python 客户端和 H2O 集群之间的连接开始。
H2O 汽车功能
H2O 的 AutoML 配备了以下功能:
- 必要的数据预处理功能(与所有 H2O 算法一样)。
- 训练一个 随机网格 的算法如 GBMs、DNNs、GLMs 等。使用精心选择的超参数空间。
- 单个模型使用交叉验证进行调整。
- 两个 层叠合奏 受训。一个集成包含所有模型(针对模型性能进行优化),另一个集成仅提供每个算法类/家族中性能最佳的模型(针对生产使用进行优化)。
- 返回所有型号的排序后的“排行榜”。
- 所有型号都可以轻松出口到生产。
个案研究
使用机器学*预测库存管理中的材料延期交货
Image by marcin049 from Pixabay
对于案例研究,我们将使用一个 产品延期交货 数据集。这里的目标是在给定许多产品指标(如当前库存、运输时间、需求预测和以前的销售)的情况下,预测产品是否会处于延期交货状态。这是一个经典的二元分类问题。可以从这里访问数据集。
参考
R. B .森蒂斯峰、E. P .阿吉亚尔和 l .戈利亚特,“使用机器学*预测库存管理中的材料缺货”,第四届 IEEE 拉丁美洲计算智能大会,秘鲁阿雷基帕,2017 年。
方法学
这个机器问题的基本概要如下。
- 开始 H2O
我们从导入的 h2o Python 模块和H2OAutoML
类开始。然后,初始化本地 H2O 集群。
import h2o
from h2o.automl import H2OAutoML
h2o.init(max_mem_size='16G')
这是一个本地的 H2O 集群。在执行单元时,一些信息将以表格的形式显示在屏幕上,其中包括节点数量、总内存、Python 版本等..此外,h2o.init()
确保没有 H2O 的先前实例正在运行。
默认情况下,H2O 实例使用所有的内核和大约 25%的系统内存。但是,如果您希望为它分配固定的内存块,您可以在 init 函数中指定它。
- 将数据加载到 H2O
让我们从本地 CSV 文件导入数据。该命令与pandas.read_csv
非常相似,数据以H2 of frame的形式存储在内存中。
data_path = "https://github.com/h2oai/h2o-tutorials/raw/master/h2o-world-2017/automl/data/product_backorders.csv"# Load data into H2O
df = h2o.import_file(data_path)
让我们来看一部分数据。
df.head()
A sample of the dataset
print(f'Size of training set: **{df.shape[0]}** rows and **{df.shape[1]}** columns')
-------------------------------------------------------------
Size of training set: 19053 rows and 23 columns
- 将数据集分为训练数据集和测试数据集
splits = df.split_frame(ratios=[0.8],seed=1)
train = splits[0]
test = splits[1]
- 指定响应和预测变量
接下来,让我们确定响应列** n,并将列名保存为 y。响应列名为“ went_on_backorder ,表示产品是否延期交货(二进制响应)。我们还将删除sku
列,因为它是一个唯一的标识符,不应该包含在预测列集中,预测列存储在一个名为 x 的列表中。**
y = "went_on_backorder"
x = df.columns
x.remove(y)
x.remove("sku")
- 运行 AutoML
运行 AutoML,120 秒后停止。max_runtime_secs
参数提供了一种按时间限制 AutoML 运行的方法。
aml = H2OAutoML(max_runtime_secs=120, seed=1)
aml.train(x=x,y=y, training_frame=train)
所需停止参数
有两种停止策略(基于时间或模型数量),必须指定其中一种。如果设置了这两个选项,AutoML 运行将在达到其中一个限制时立即停止。
- max _ runtime _ secs:此参数控制 AutoML 在训练最终堆叠集合模型之前最多运行多长时间。默认为 3600 秒(1 小时)。
- max_models :指定 AutoML 运行中要构建的模型的最大数量,不包括堆叠整体模型。默认为
NULL/None
。
还有几个可选参数可以设置,例如:
nfolds、balance_classes、class_sampling_factors、max_after_balance_size、max_runtime_secs_per_model、stopping_metric 等。你可以在文档中读到更多关于它们的内容。
排行榜
接下来,我们可以查看 AutoML 排行榜。AutoML 对象包括在该过程中训练的模型的“排行榜”,包括 5 重交叉验证的模型性能(默认)。
每个机器学*任务的默认性能指标(二元分类、多类分类、回归)在内部指定,排行榜将按该指标排序。
lb = aml.leaderboard
lb.head()
排行榜显示了 AutoML 构建的前 10 个模型及其参数。最佳模型是一个堆叠集合(放置在顶部),并存储为aml.leader.
系综探索
为了理解集合是如何工作的,让我们看一看堆叠集合“所有模型”模型的内部。“所有模型”集合是 AutoML 运行中所有单个模型的集合。这通常是排行榜上表现最好的型号。
*# Get model ids for all models in the AutoML Leaderboard*
model_ids = list(aml.leaderboard['model_id'].as_data_frame().iloc[:,0])*# Get the "All Models" Stacked Ensemble model*
se = h2o.get_model([mid for mid **in** model_ids if "StackedEnsemble_AllModels" **in** mid][0])*# Get the Stacked Ensemble metalearner model*
metalearner = h2o.get_model(se.metalearner()['name'])
检查集合中 metalearner(合并器)算法的可变重要性。这向我们展示了每个基础学*者对整体的贡献。
%matplotlib inline
metalearner.std_coef_plot()
Plotting the base learner contributions to the ensemble.
使用 Leader 模型预测
pred = aml.predict(test)
pred.head()
拯救领袖模式
您还可以保存并下载您的模型,并将其用于部署到生产环境中。
h2o.save_model(aml.leader, path="./product_backorders_model_bin")
结论
从本质上来说,AutoML 的目的是自动化重复的任务,如管道创建和超参数调整,以便数据科学家可以将更多的时间花在手头的业务问题上。AutoML 还旨在让每一个人都能使用这项技术,而不是少数人。AutoML 和数据科学家可以协同工作来加速 ML 过程,以便可以利用机器学*的真正有效性。
原发表于 H2O.ai
对深度学*的深刻直觉
原文:https://towardsdatascience.com/a-deep-intuition-to-deep-learning-8f7220cd6579?source=collection_archive---------26-----------------------
想知道深度学*为什么有效?这是背后的直觉。
这个博客的灵感完全来自 IIT 马德拉斯的米特什·哈普拉教授的讲座。这是相当长的,如果你想浏览只是得到一个要点,请随意跳过感知器,并转移到乙状结肠神经元。
深度学*背后的动机
考虑一个预测用户是否会喜欢特定电影的例子。影响决定的一些因素有——类型、导演、剧本、收视率等等。一般来说,机器学*或深度学*问题的结构是,你有一个要预测的目标变量,以及一组影响目标的因素。因此,有了关于因素和目标的可用历史数据的知识,模型必须预测给定因素的未来目标。
“深度学*是将目标变量作为影响输入特征/变量的函数进行学*的过程。”
事实上,机器学*也做了与上述定义相同的事情。然而,当涉及到现实世界问题的复杂性时,机器学*(ML)的学*能力是有限的。不要责怪 ML,因为它本身并不是“精心制作”来学*这些复杂性的。
深度学*恰恰相反,它是为了从数据中学*复杂的功能而设计的。对于复函数,我的意思是在特征和目标之间的关系中存在的非线性。让我们看看为什么一个神经网络有足够的能力在我们进行的过程中学*这些复杂性。
感知器——神经网络的基本元素
神经网络由大量连接在一起作为网络的感知器组成。感知器是一种二进制分类算法,它学*分隔两个类的线。感知器的基本原理如下—
- 如果输入/特征的“加权”和大于 0,则预测类别 1,否则预测类别 0。下面显示的是一个感知器,它将连续值特征作为输入,并给出二进制输出。
A perceptron where x denotes input features and w denotes weights
Definition of perceptron
- 请从上图中注意,我们的感知器在 x*w 方程中还包含了一个常数项(用红色标注),叫做“偏差”。
- 使用训练数据,在我们知道类别标签的情况下,学*每个特征的“权重”。
- 权重通过构造目标函数来学*,例如-(y * x * w)。如果你观察,只有当 y 和 xw 的符号相同时,这个函数才会> 0。即仅当函数 xw 正确预测目标时。我们需要找到能给出最多正确预测的“w”向量。
- 现在应该很清楚,目标函数应该是所有点的 yxw 之和的负数,我们需要最小化它。既然我们有了目标函数,随机梯度下降将用于学*权重向量。
我将把感知器留在那里,如果你对此有粗略的想法,这很好。你需要知道,如果输入的加权和大于 0,那么感知器“触发”(预测类 1),否则它“不触发”(预测类 0)。
现在,考虑引言中的电影例子。假设我们只有一个特征——评论家评分,来决定我们是否喜欢一部电影,还假设这个特征的权重是 1,偏差是-0.5。如果评论家评分是 0.49,感知器将预测 0,如果评论家评分是 0.51,感知器将预测 1。
Example of a harsh judgment
现实世界中人的大脑是这样工作的吗?不。这就是为什么我们有“乙状结肠神经元”。
乙状结肠神经元
以下是感知器决策边界和 sigmoid 边界的可视化表示。
Sigmoid 比感知器更平滑,不那么刺耳,更自然。它由下面的等式给出。
Sigmoid function
sigmoid 函数的输出范围在 0 和 1 之间。这是一种相当合理的分类方法,因为你可以把它看作概率值。现在,我们有足够的知识来深入研究深度学*为什么有效。
深度学*为什么有效?
回想一下,我们正试图将目标变量作为输入变量的函数来学*。我来介绍一些术语。
- 目标变量—“y”
- 输入特征向量“x”
- “x”和“y”的真实关系——“f(x)”
1989 年,一个被称为“普遍逼*定理”的非常强大的定理被一位科学家发表并向世界证明。这个定理如下
“具有单个隐藏层的多层神经元网络可用于以任何期望的精度逼*任何连续函数”
换句话说,对于一个真实的函数 f(x),有一个神经网络存在,它有一个任意数量神经元的隐藏层,其输出“g(x)”是这样的|f(x)-g(x)|
为什么我们会关心这个定理呢?因为我们的首要目标是知道一个神经元网络是否可以学*任意函数 f(x)。例如,让我们以下面的函数为例。
True function we want our network to learn
你能想出一个自然的方法来*似这个函数吗?可以说,它可以*似为一系列矩形塔状杆,如下所示。
approximation of the true function
那么,如果我们可以学*这些矩形条中的每一个,并将它们全部相加,我们不就可以逼*真实函数了吗?每个条的高度不同,否则它们都是矩形条。视觉示例如下所示。
Sum of rectangular bars can approximate true function
所以,我们的工作现在缩小到学*每一个酒吧/塔。下面的图像代表了我们对这些塔的神经网络的想法。
Sum of towers = approximation of true function
关于神经网络的酷想法是,通过使用 sigmoid 神经元,可以学*如上所示的单个造塔者。怎么会????在探索如何之前,我们需要知道 sigmoid 的两个性质。
- sigmoid 函数中“S”曲线的斜率受“w”向量的影响,权重越高,斜率越陡。
- x 轴上 s 形曲线的位置受偏置项的影响。
如果以上两个 sigmoids 相减会怎么样?是的,你猜对了——我们将得到矩形条别名塔函数。
Tower function
万岁!!因此,现在证明了我们可以使用 sigmoid 神经元构建塔函数——塔函数的高度和形状受权重和偏差的影响。这个定理可以用数学方法投影到多个维度,尽管在上面的图表中,我们只可视化了一个输入维度。
神经网络体系结构的最后一瞥
根据上述定理和证明,我们看到许多层相连的乙状结肠神经元可以为我们带来神奇的效果。针对特定问题要调整的参数是层数和每层的神经元数量。最后,一个简单的前馈神经网络如下所示。
Feed forward neural network
- 前馈神经网络是如上所示的神经元的堆叠。
- 第一个红色图层是输入图层-x1、x2 和 x3 是构成单个数据点的三个要素。
- 所有蓝色神经元层称为隐藏层,绿色层称为输出层。
- 在每一个神经元中,计算是这样进行的—
g(偏差+(权重*对神经元的输入))
- “g”函数可以是任何函数——sigmoid、tanh、relu 等。这称为激活函数,它会在网络中引入非线性。
- 最终的绿色输出层由和类一样多的神经元组成。如果我有两个目标类,那么最后我会有两个神经元。
- 使用 sigmoid 函数作为最后一层中的激活函数是有意义的,因为它给出了范围从 0 到 1 的值,这些值可以被解释为概率。
- 一旦我们学会了正确的权重和偏好,我们就完成了。
学*正确的权重和偏差的动机是什么?你可能已经猜到了,这是目标函数。我们总是被目标函数所驱使,目标函数是我们需要最小化的损失函数,以便学*真实函数的*似。
最常用的损失函数是均方误差。
Loss function
因此,我们想要找到权重和偏差,使得上述损失函数最小化。我们知道真正的标签,我们也知道我们网络的结果是权重和偏差的函数。因此,我们应该能够通过使用上述公式来测量损失,并对我们的权重进行迭代修正。这个想法是,我们从随机权重和偏差开始,通过测量每一步的损失来迭代地修正它们。我们怎么做呢?对于这个问题,随机梯度下降很方便。我强烈推荐你阅读我之前关于 SGD 的博客,以充分理解它在这里的作用。我们遍历损失函数,找到权重和偏差,使得损失函数最小化。这个过程在神经网络中被称为“反向传播”。是的,有了这个,我们就理解了神经网络为什么以及如何能够解决我们许多复杂的问题。
结论
虽然这是一篇冗长的博客,但我希望这有助于正确看待深度学*的某些奥秘。我仍然会建议你继续看你选择的大学的著名神经网络讲座。我个人推荐 Mitesh Khapra 教授的讲座,他在讲座中讲述了神经网络中一切事物背后的直觉。我已经尽力从他的演讲中总结出基本的概念。如果有什么不太清楚的,请在评论中告诉我,我会继续编辑博客,直到它有凝聚力。
对剩余学*的深入探究
原文:https://towardsdatascience.com/a-deeper-dive-into-residual-learning-d92e0aaa8b32?source=collection_archive---------21-----------------------
探索在剩余学*领域取得的最显著的进步
A traditional convolution network (Image: Courtesy of PACKT Publication)
在计算机视觉领域,深度学*随着 DCNNs 或深度卷积神经网络的引入而取得了长足的进步。随着强大 GPU 的出现,深度网络正在成为常态。但是,这些网络都存在 消失梯度 的问题。为了克服这一点,何等人在 2015 年引入了 残差学* 的概念,其中作者使用 残差单元 作为网络的积木块。在这篇文章中,我们仔细研究了前面提到的剩余单元以及它到目前为止所经历的修改。
在他们的论文中,何等人讨论了用大量堆叠网络训练网络的问题,其中网络停止训练,并且随着网络深度的增加,其精度随着训练损失的增加而饱和。这种困境并不像许多人认为的那样是过度拟合的结果。相反,这是因为误差的梯度在 反向传播 期间变得几乎为零,从而在通过 SGD(随机梯度下降)过程训练网络时阻碍了训练。
让我们假设一个如上所示的传统卷积网络,两层之间的正向传播可以定义为:
这里, x(l) 和 x(l+1) 是卷积层 l 的输入和输出特征。卷积运算由 F 定义,并且 k 是偏置项。最后,激活操作由 f 表示。现在,我们可以将项 x(l+1) 写成:
上面,我们认为 G 是函数 F 和 f 的组合。我们可以递归地将层 L 的输出定义为:
现在,在反向传播期间,较深层的误差梯度 L 被传播到较浅层,这样,在每个较浅层获得的梯度变得越来越小,直到它完全消失。对所述问题的解决方案由何等人提出,通过引入如下所示的。
Fig. 1: Original residual unit proposed by K. He et al.
在何等人提出的网络的情况下,剩余单元 l 的输入和输出可以表示为:
上式中 h(x(l)) 表示恒等式映射, F 表示 剩余函数 ,因此可以写成 h(x(l)) = x(l) 。这定义了 ResNet 架构的基础。下面给出了上述剩余单元的 Keras 实现:
在上面的实现中,我们没有给出 ResNet 架构中使用的剩余单元的精确实现。当处理非常深的架构时,使用这种类型的剩余架构的优点是错误有一条 捷径 可以通过。使用这些剩余单元构建的基本模型如下所示:
对此类剩余单元的改进由何等人于 2016 年在文章《深度剩余网络中的恒等映射中提出,作者认为 f 是一个 恒等函数, 则 x(l+1) = y(l) 。因此,上面的等式变成:
现在,如果我们考虑一个由剩余单元堆叠而成的深度网络,那么深度单元 L 的输出可以表示为深度单元 l :
因此,对于任何较深的单元 L,,我们有在 L 之前的较浅单元的剩余函数加上较浅单元 l 本身缩放到特定级别,即某个标量λ的总和。这与 平面网络 (其中不存在身份映射)相反,其中在层 L 的特征输出是如前所述的一系列矩阵向量乘积。上述等式可以简化为:
如前所述,在反向传播期间,在单元 L 获得的误差梯度被传递到单元 L-1 上,单元L-1又将其接收到的误差梯度传递到单元 L-2 上。残差单元的上述变化具有一些独特的反向传播特性,如下所示:
上面我们看到了从一个较浅的单元 l 获得的误差梯度。对于具有非常深的结构的网络,λ对于避免误差梯度的消失是至关重要的。正如我们在上面的等式中看到的,如果 L 非常大并且 λ > 1 ,那么误差梯度变得指数级大,否则如果 λ < 1 那么误差变得无穷小。因此, λ=1 是最优选择。
现在,正如已经提到的,当且仅当在上面的等式中 x(l+1) = y(l) 时,这个等式才有效。因此,我们必须考虑剩余分支中的层是完全预激活的。下面,我们看到作者提出的完全预激活。**
对于每个变体的性能的完整细节,我强烈建议跟进何等人的原始文章“中的身份映射”。下面显示了所提出的剩余单元的完全预激活变体的一个 Keras 实现。****
我强烈建议在处理更深层次的网络时使用剩余学*。一个好的做法是在训练时记录网络饱和时的损耗。如果在向现有网络添加新层时观察到损耗急剧增加和精度下降,这可能是由 消失梯度 现象引起的。
感谢您阅读这篇文章。请给出您的反馈,并随时跟进我的问题,我很乐意帮忙!
对 NSL-KDD 数据集的深入研究
原文:https://towardsdatascience.com/a-deeper-dive-into-the-nsl-kdd-data-set-15c753364657?source=collection_archive---------3-----------------------
您是否曾经想过,您的计算机/网络如何能够避免感染来自互联网的恶意软件和不良流量输入?它之所以能检测得这么好,是因为有适当的系统来保护您的计算机或网络中保存的有价值的信息。这些检测恶意流量输入的系统被称为入侵检测系统(IDS),并接受互联网流量记录数据的训练。最常见的数据集是 NSL-KDD,是现代互联网流量的基准。
NSL-KDD 的数据集并不是第一个。KDD 杯是一场国际性的知识发现和数据挖掘工具竞赛。1999 年,举办了这项比赛,目的是收集交通记录。竞赛任务是建立一个网络入侵检测器,一个能够区分“坏”连接(称为入侵或攻击)和“好”正常连接的预测模型。作为这场比赛的结果,大量的互联网流量记录被收集并捆绑到一个名为“KDD 99”的数据集,并由此产生了 NSL-KDD 数据集,作为新不伦瑞克大学 KDD 99 的修订和清理版本。
该数据集由四个子数据集组成:KDDTest+,KDDTest-21,KDDTrain+,KDDTrain+_ 20 %,尽管 KDDTest-21 和 KDD train+_ 20%是 KDD train+和 KDDTest+的子集。从现在开始,KDDTrain+将被称为 Train,KDDTest+将被称为 Test。KDDTest-21 是测试的子集,没有最困难的交通记录(得分为 21),KDDTrain+20Percent 是 Train 的子集,其记录数占整个训练数据集的 20%。也就是说,KDDTest-21 和 KDD train+ 20%中存在的流量记录已经分别在测试和训练中,并且不是任何一个数据集中的新记录。
这些数据集包含简单入侵检测网络看到的互联网流量的记录,是真实入侵检测系统遇到的流量的幻影,只留下其存在的痕迹。数据集每条记录包含 43 个特征,其中 41 个特征指的是流量输入本身,最后两个是标签(是正常还是攻击)和分数(流量输入本身的严重性)。
在数据集内存在 4 种不同的攻击类别:拒绝服务(DoS)、探测、用户到根(U2R)和远程到本地(R2L)。每个攻击的简要描述如下:
- DoS 是一种试图切断进出目标系统的流量的攻击。IDS 被异常流量淹没,系统无法处理,于是关闭以保护自己。这将阻止正常流量访问网络。这方面的一个例子可能是一家在线零售商在大减价的一天收到大量在线订单,由于网络无法处理所有请求,它将关闭,阻止付费客户购买任何东西。这是数据集中最常见的攻击。
- 探测或监视是一种试图从网络获取信息的攻击。这里的目标是像小偷一样窃取重要信息,无论是客户的个人信息还是银行信息。
- U2R 是一种攻击,它从普通用户帐户开始,试图以超级用户(root)的身份访问系统或网络。攻击者试图利用系统中的漏洞来获得根用户权限/访问权。
- R2L 是一种试图获得远程机器本地访问权限的攻击。攻击者无法在本地访问系统/网络,并试图“侵入”网络。
从上面的描述中可以注意到,DoS 的行为与其他三种攻击不同,在其他三种攻击中,DoS 试图关闭系统以完全阻止通信流,而其他三种攻击则试图悄悄渗透系统而不被发现。
下表显示了数据集中存在的每个攻击的不同子类的细分:
虽然这些攻击存在于数据集中,但分布严重倾斜。记录分布的细目见下表。从本质上讲,每个数据集中超过一半的记录都是正常流量,U2R 和 R2L 的分布非常低。虽然这一数字很低,但这是现代互联网流量攻击分布的准确表示,其中最常见的攻击是 DoS,U2R 和 R2L 很少出现。
流量记录中的特征提供了与 IDS 输入的流量相遇有关的信息,并且可以分为四类:内在的、内容的、基于主机的和基于时间的。以下是不同类别功能的描述:
- 内在特征可以从分组的报头中导出,而无需查看有效载荷本身,并且保存关于分组的基本信息。此类别包含功能 1–9。
- 内容特征保存关于原始分组的信息,因为它们是以多个片段而不是一个片段发送的。有了这些信息,系统就可以访问有效负载。此类别包含功能 10–22。
- 基于时间的功能保存对两秒钟窗口内的流量输入的分析,并包含诸如它尝试与同一主机建立多少连接之类的信息。这些特征主要是计数和速率,而不是关于流量输入内容的信息。此类别包含功能 23–31。
- 基于主机的功能类似于基于时间的功能,只是它不是在 2 秒的窗口内进行分析,而是在一系列连接上进行分析(在 x 数量的连接上向同一主机发出了多少请求)。这些功能旨在应对持续时间超过两秒钟的攻击。此类别包含功能 32–41。
该数据集中的特征类型可分为 4 种类型:
- 4 分类(特征:2,3,4,42)
- 6 二进制(功能:7,12,14,20,21,22)
- 23 个独立的(功能:8、9、15、23–41、43)
- 10 连续(功能:1,5,6,10,11,13,16,17,18,19)
下表列出了分类特征的可能值。有 3 个可能的协议类型值、60 个可能的服务值和 11 个可能的标志值。
不像协议类型和服务的值是自明的(这些值描述了连接),标志不是很好理解。标志功能描述连接的状态,以及是否出现标志。标志中的每个值代表一个连接的状态,每个值的解释见下表。
在谷歌电子表格这里可以看到每个功能的描述和数据集的分类。
深入了解下降算法
原文:https://towardsdatascience.com/a-deeper-look-at-descent-algorithms-13340b82db49?source=collection_archive---------21-----------------------
不同下降算法的概述和比较
Photo by Katerina Kerdi on Unsplash
理解本文的核心要求
- 线性代数
- 多变量微积分
- 凸函数的基本思想
众所周知,优化是机器学*中最重要的因素之一。因此,我们感兴趣的是找到一种在合理的时间内优化函数的算法。今天最常用的算法之一是梯度下降。今天我们就来看看其他的优化算法,对它们有一个理论上的了解。
本文将讨论的核心算法有:
- 牛顿方法
- 最陡下降
- 梯度下降
你可以从教材凸优化:第三部分中了解更多关于这些算法的知识。在本文中,我们将主要关注二次/多项式函数
对我们的功能所做的假设
我们总是假设我们所处理的函数及其导数是连续的(即 f ∈ C )。在牛顿法的情况下,我们还需要假设二阶导数是连续的。(即 f ∈ C )。我们做的最后一个假设是,我们试图最小化的函数是凸的。因此,如果我们的算法收敛到一个点(通常称为局部最小值),那么我们保证它是一个全局优化器。
牛顿方法
单变量函数的算法
x_n = starting point
x_n1 = x_n - (f'(x_n)/f''(x_n))
while (f(x_n) != f(x_n1)):
x_n = x_n1
x_n1 = x_n - (f'(x_n)/f''(x_n))
牛顿方法背后的思想是被最小化的函数 f 由二次函数局部逼*。然后我们找到那个二次函数的精确最小值,并把下一个点设为那个。然后我们重复这个过程。
多元函数的情况
到目前为止,看起来牛顿的方法是一个可靠的候选方法。但通常情况下,我们不会处理很多单变量函数。大多数时候,我们将需要优化有很多参数的函数(例如,ℝn).函数这是多变量情况下的算法:
假设 x∈ ℝn,我们有:
x_n = starting_point
x_n1 = x_n - inverse(hessian_matrix) (gradient(x_n))while (f(x_n) != f(x_n1)):
x_n = x_n1
x_n1 = x_n - inverse(hessian_matrix) (gradient(x_n))
其中gradient(x_n)
是在x_n
的梯度向量,hessian_matrix
是一个 n×n hessian 对称矩阵,其元素由在x_n
的二阶导数组成。
众所周知,求一个矩阵的逆矩阵代价很高(**O(n)**),因此这种方法并不常用。
梯度下降
这是迄今为止机器学*和其他*似优化中使用的最流行的优化方法。这是一种算法,涉及到在每次迭代中在梯度方向上迈出一步。它还包括一个常数α,它决定了每次迭代中要采取的步长。算法是这样的:
*alpha = small_constant
x_n = starting_point
x_n1 = x_n - alpha * gradient(x_n)while (f(x_n) != f(x_n1)): # May take a long time to converge
x_n = x_n1
x_n1 = x_n - alpha * gradient(x_n)*
这里,alpha 是一个值,你必须在每次迭代中选择它来更新x_n
(这被称为超参数)。我们将分析我们选择的α值
如果我们为 alpha 选择一个大的值,我们将会超出优化点。其实选的太大就可以发散。
Gradient Descent after 10 iterations with an alpha value that is too large.
另一方面,如果我们选择α很小,那么将需要很多次迭代才能收敛到最优值。随着越来越接*最佳值,梯度趋于零。因此,如果你的阿尔法值太小,那么它可能会永远收敛到最小点。
Gradient Descent after 10 iterations with an alpha value that is too small.
因此,如你所见,你有责任为α选择一个好的常数。然而,如果您选择了一个好的 alpha,那么您可以在每次迭代中节省很多时间
Gradient Descent after 10 iterations with an alpha value that is good enough.
最陡下降
最速下降非常类似于梯度下降,只是它更严格,因为每次迭代中采取的步骤都保证是最佳步骤。算法是这样工作的:
*x_n = starting_point
alpha_k = get_optimizer(f(x_n - alpha * gradient(x_n)))
x_n1 = x_n - alpha_n * gradient(x_n)while (f(x_n) != f(x_n1)):
x_n = x_n1
alpha_k = get_optimizer(f(x_n - alpha * gradient(x_n)))
x_n1 = x_n - alpha_n * gradient(x_n)*
其中x_n
和x_n1
是ℝn 的输入向量,gradient
是 f 在x_n
处的梯度,alpha_k
为:
因此,在优化我们的原始函数时,我们需要在每次迭代中优化一个内部函数。好消息是,这个函数是一个单变量函数,这意味着它并不复杂(例如,我们可以在这里使用牛顿法)。然而,在大多数情况下,在每一步都优化这样一个函数确实有点昂贵。
二次函数的一个特例
考虑平方误差损失函数:
其中 I 为单位矩阵 y=Qw+b
为简单起见,我们只考虑寻找权重 w 的最优值(假设 b 为常数)。通过代入 y 并简化一切,我们得到如下结果:
回头看一下 g(α) ,我们知道如果我们在 αk 取梯度,由于是极小值,所以应该是 0。利用这一点,我们有以下优势:
简化上面的混乱,代入两点处的 f 的梯度,我们得到αk 如下
现在,在二次函数的情况下,我们有了αk 的具体值。
二次函数的收敛性分析
以ℝ的二次函数为例,最速下降通常会在不到十步的时间内非常接*最优值。
Steepest descent in 2 dimensions after 4 iterations.
在上图中,请注意方向的变化在每次迭代中都是垂直的。经过 3 到 4 次迭代后,我们注意到导数的变化几乎可以忽略不计。
为什么不用最速下降法?
那么为什么这种算法不经常使用呢?很明显,它不再需要超参数来调整,并且保证收敛到局部最小值。这里的问题是,在每次迭代中,我们需要优化 alpha_k,考虑到我们必须在每一步都这样做,这有点昂贵。
例如,在二次函数的情况下,我们必须在每次迭代中计算多个矩阵乘法和向量点积。相比之下,梯度下降,在每一步,我们只需要计算导数,并更新新的价值,这是更便宜的方式。最速下降法在非二次函数的情况下也很难推广,在这种情况下,α_ k 可能没有具体值
梯度下降法和最速下降法的比较
我们将对梯度下降和最速下降进行比较,并分析它们的时间复杂度。首先,我们将对两种算法的时间进行比较。我们将创建一个二次函数 f:ℝ ⁰⁰⁰→ℝ (涉及一个 2000×2000 的矩阵)。然后,我们将优化函数,并将迭代次数限制为 1000 次。然后,我们将比较两种算法所用的时间以及 x_n 值与优化器的接*程度。
让我们先来看看最速下降:
*0 Diff: 117727672.56583363 alpha value: 8.032725864804974e-06
100 Diff: 9264.791000127792 alpha value: 1.0176428564615889e-05
200 Diff: 1641.154644548893 alpha value: 1.0236993350903281e-05
300 Diff: 590.5089467763901 alpha value: 1.0254560482036439e-05
400 Diff: 279.2355946302414 alpha value: 1.0263893422517941e-05
500 Diff: 155.43169915676117 alpha value: 1.0270028681773919e-05
600 Diff: 96.61812579631805 alpha value: 1.0274280663010468e-05
700 Diff: 64.87719237804413 alpha value: 1.027728512597358e-05
800 Diff: 46.03102707862854 alpha value: 1.0279461929697766e-05
900 Diff: 34.00975978374481 alpha value: 1.0281092917213468e-05
Optimizer found with x = [-1.68825261 5.31853629 -3.45322318 ... 1.59365232 -2.85114689 5.04026352] and f(x)=-511573479.5792374 in 1000 iterations
Total time taken: 1min 28s*
这是渐变下降的输出,alpha = 0.000001
*0 Diff: 26206321.312622845 alpha value: 1e-06
100 Diff: 112613.38076114655 alpha value: 1e-06
200 Diff: 21639.659786581993 alpha value: 1e-06
300 Diff: 7891.810685873032 alpha value: 1e-06
400 Diff: 3793.90934664011 alpha value: 1e-06
500 Diff: 2143.767760157585 alpha value: 1e-06
600 Diff: 1348.4947955012321 alpha value: 1e-06
700 Diff: 914.9099299907684 alpha value: 1e-06
800 Diff: 655.9336211681366 alpha value: 1e-06
900 Diff: 490.05882585048676 alpha value: 1e-06
Optimizer found with x = [-1.80862488 4.66644055 -3.08228401 ... 2.46891076 -2.57581774 5.34672724] and f(x)=-511336392.26658595 in 1000 iterations
Total time taken: 1min 16s*
正如你所看到的,梯度下降往往更快,虽然不是很多(几秒或几分钟)。但更重要的是,虽然α的值没有被选为梯度下降中的最佳参数,但最速下降比梯度下降采取的步骤要好得多。在上例中,第 900 个梯度下降的 f(xprev) 和 f(xcurr) 之差为 450。这种差异在最陡下降中很早就过去了(大约在迭代 300 和 400 之间)。
因此,如果我们只考虑最速下降的 300 次迭代,我们得到如下结果:
*0 Diff: 118618752.30065191 alpha value: 8.569151292666038e-06
100 Diff: 8281.239207088947 alpha value: 1.1021416896567156e-05
200 Diff: 1463.1741587519646 alpha value: 1.1087402059869253e-05
300 Diff: 526.3014997839928 alpha value: 1.1106776689082503e-05 Optimizer found with x = [-1.33362899 5.89337889 -3.31827817 ... 1.77032789 -2.86779156 4.56444743] and f(x)=-511526291.3367646 in 400 iterations
Time taken: 35.8s*
因此,最陡下降实际上更快。这只是表明,如果你想接*最优,你真的需要每次迭代更少的步骤。事实上,如果您的目标是逼*最优值,那么最速下降法只需 10 步就能生成更接*最优值的小维函数,而梯度下降法需要 1000 步!
这里有一个例子,我们有一个来自ℝ ⁰→ℝ.的二次函数 10 步,最陡下降产生f(x) = -62434.18
。1000 步内,梯度下降生成f(x) = -61596.84
。在短短 10 步中,最速下降降低到一个f-比 1000 步中的梯度下降值还低!
请记住,上面的工作真的很好,只是因为我们正在处理二次函数。一般来说,每次迭代都很难找到αk 的值。优化 g(α)并不总是让你找到αk 的具体值,通常我们倾向于使用迭代算法来最小化这样的函数。在这种情况下,事情变得繁琐,比梯度下降慢得多。这就是为什么最速下降不那么受欢迎。
结论
总之,我们学*了三种算法:
牛顿方法
牛顿的方法提供了一个函数的二次*似,并在每一步进行优化。最大的缺点是,它涉及到对多变量情况下的矩阵求逆(当处理具有许多特征的向量时,这可能是昂贵的)
梯度下降
梯度下降是最常见的优化算法。它非常快,因为每一步最昂贵的事情就是计算导数。然而,它确实涉及到“猜测”或“调整”一个告诉你每一步应该走多远的超参数。
最陡下降
最速下降算法是在给定函数梯度向量的情况下找到最佳步长的算法。唯一的问题是,它涉及到在每次迭代中优化一个函数,这通常是昂贵的。在二次函数的情况下,最速下降通常表现良好,尽管它确实涉及每步大量的矩阵计算。
这篇文章的笔记本版本可以在这里找到
神经网络基于梯度学*的深入研究
原文:https://towardsdatascience.com/a-deeper-look-into-gradient-based-learning-for-neural-networks-ad7a35b17b93?source=collection_archive---------13-----------------------
http://ruder.io/content/images/2016/09/saddle_point_evaluation_optimizers.gif
在深度学*中,我们试图逼*输入和输出之间的函数的方法是,首先随机初始化网络的参数,然后通过最小化损失函数来逐步更新它们以找到这些参数的正确配置,该损失函数在大多数情况下本质上是非凸的(许多局部最小值而不是单个全局最小值),因此训练神经网络是一个不确定的组合优化问题,因为我们不能保证当达到时收敛点是全局最小值或误差表面上的鞍点。
一大堆算法被提出来处理这种情况,其中流行的有 SGD,momentum based,NAG,RMSprop 和 ADAM。它们都是经典梯度下降算法的一些变体,而结合了 RMSprop 和 momentum 的 ADAM 被认为是当前的技术水平。
1.梯度下降更新规则
考虑网络的所有权重和偏差被展开并堆叠到某个高维向量空间中的单个向量θ中,并且与之相关联的损失是ϑ(θ).θ的方向或大小的任何变化都会给我们一个新的ϑ(θ).值
在训练网络时,在每个时期,我们的目标是找到另一个向量∏θ,使得新的损失ϑ(θ+∏θ小于先前的损失ϑ(θ,因此在每个时期,目标是找到∏θ,使得以下不等式成立:
ϑ(θ + ∆θ) — ϑ(θ) < 0
在我们继续寻找∏θ之前,让我们快速回顾一下泰勒级数,它指出任何非多项式函数都可以精确地*似为多项式项的无穷和,
(x) = c0 + c1 x + c2 x + c3 x +。。。。
要满足的唯一条件是 LHS 和 RHS 的一阶、二阶和所有高阶导数应该完全匹配,并且(x)应该是一个无限可微的函数。
cos(θ)在θ= 0°时,我们能否写成 cos(θ) = 1- 1/2 θ为二阶泰勒*似。因为我们只使用前三项(c1= 1,c2 = 0,c3 = 1/2)而不是所有的无限多项式项,所以这种*似只在θ接* 0°时才有效。
https://bespokeblog.files.wordpress.com/2011/07/sintay.png
通常,x 处的泰勒级数是以下幂级数
对于一个小的 x,λ(x)≈λ(x+∏x)。
对于多元函数ф(x ),就像损耗ϑ(θ和ϑ(θ+∈θ),它依赖于向量θ和θ+∈θ,下面是一阶泰勒*似
这是(x+∏x)的二阶泰勒*似
取损失函数的一阶泰勒*似
ϑ(θ+∏θ)=ϑ(θ)+∏θ∇ϑ(θ)
ϑ(θ+∏θ)—ϑ(θ)=∏θ∇ϑ(θ)
我们知道,为了使损失函数最小化,每一步的损失都应该小于前一步,并且这个不等式(ϑ(θ+∏θ)-ϑ(θ)< 0) should hold, and thus from the first order Taylor approximation implies that the dot product ∆θ ∇ϑ(θ) < 0.
因为点 B (A B cos(ϕ))只能在它们之间的角度大于 90 度时为负,当∏θ与损失梯度的方向相反时,在任何时期损失的最大减少都是可能的
这给了我们众所周知的梯度下降更新规则
θ := θ — ∇ϑ(θ)
因为我们使用的是损失函数的一阶泰勒*似,它只在θ的邻*区域有效,所以∏θ必须小是一个必要条件。所以我们乘以η << 0 with ∆θ in our update rule.
θ := θ — η ∇ƒ(θ)
In practice, larger η also causes overshooting in machine learning and is termed as the learning rate and is a hyper parameter.
Limitations
One of the limitations of Vanilla Gradient Descent is that in the region of gentle slopes, computed gradients are very small resulting in a very slow convergence. One may simply increase the value of η but it may violate the assumption of first order Taylor approximation of loss function, also larger learning rate may cause overshooting.
Another point to consider is that near the minima loss functions are slightly ellipsoidal and gradients in these regions from the first order Taylor approximation of loss function are almost orthogonal to the true direction of convergence, causing a zig-zag path and a slow convergence.
Although it is not very clear, but second order Taylor approximation may solve this problem. but calculation of ∇ ²ƒ(θ) (Hessian) is computationally very expensive. There are some proposed implicit ways of using hessian by setting the learning rate η as 1/ β, where β is the dominant eigenvalue of the hessian. 点击此处阅读更多关于这个提议的解决方案。
2.利用动力学*
为了解决梯度下降算法收敛速度慢的问题,一种方法是在前面步骤中计算的梯度的指数加权平均方向上更新θ。
动量 _t = γ *动量 _t -1 + η ∇ϑ(θ_t)
θ_t+1 := θ_t -动量 _t
其中∇ϑ(θ_t)表示在步骤 t 计算的梯度
momentum _ 0 = 0
momentum _ 1 = momentum _ 0+η∇ϑ(θ_1)= η∇ϑ(θ_1)
momentum _ 2 = momentum _ 1+η∇ϑ(θ_2)=γη∇ϑ(θ_1)+η∇ϑ(θ_2)
momentum _ 3 = momentum _ 2+η∇ϑ(θ_3)
=>γη∇ϑ(θ_1)+γη∇ϑ(θ_2)+η∏ϑ(θ_ 3)
设置γ << 1 insures that the higher power of γ causes decay in the gradients computed in previous steps and maximum weight is given to the last step.
动量会导致快速收敛,即使在梯度下降需要大量时间收敛的缓坡区域也是如此。
限制
虽然动量导致比梯度下降相对更快的收敛,但是它通常超过目标并导致在最小值附*振荡。
A pendulum oscillating around minima because of momentum
3.内斯特罗夫加速梯度下降法
NAG 是基于动量梯度下降算法的简单改进。正如我们已经讨论过的,在动量项中,我们也考虑了具有误差面梯度的更新规则中的历史动量向量。
- 初始化动量= 0
- 还包括动量项的更新步骤
θ_t+1 = θ_t - - 将当前梯度加入动量
动量=动量+ η * ∇ϑ(θ_t)
想象在步骤= t,我们在误差面上的点 A。在 A 点计算的梯度会把我们带到 B 点,动量会把我们带到 C 点,两者都会把我们带到 d 点。
在这种情况下,动量本身是超调的,在 A 点计算的梯度甚至加入其中,导致更大的超调。
NAG 说,不是计算 A 点的梯度并把它们加到从 A 点到 D 点着陆的动量中,而是应该计算 C 点(前瞻点)的梯度并把它加到从 A 点到 D '点着陆的动量中,因此与动量相比减少了最小值附*的振荡。
- 初始化动量= 0
- 计算前瞻点
look_ahead = θ_t +动量 - 用在 look_ahead 点计算的梯度更新 nag
θ_ t+1 =θ_ t—{γ动量+ η∇ϑ(θ_look_ahead)} - 将前瞻处的梯度加入动量
动量=动量+ η*∇ϑ(θ_look_ahead)
4.Adagrad 和 RMSprop 用于自适应学*速率
到目前为止,我们一直在寻找更好的算法来更快地通过小梯度误差表面。训练大型神经网络的另一个问题是许多特征的不均匀稀疏性。想象与产生激活 h(w.x + b)的特征 x1 相关联的权重 w1,并且应用 L2 损失来训练网络。在大多数情况下,如果 x1 为零,则相对于 w1 的损耗梯度将非常小。
∂ϑ/∂w1 =(h(w . x+b)—y)* h’(w . x+b)* x1。(乘以 x1)
深度神经网络中不同特征的稀疏性的这种不平衡导致所计算的梯度值的显著变化,从而导致与稀疏特征相比,非稀疏特征的权重的更大更新。
NPTEL NOC-IITM, Deep Learning CS7015
在上图中,与 w 相关的特征非常稀疏,这导致了上图中所示的收敛路径。
Adagrad 的主要思想是根据特征的稀疏性将自适应学*速率分配给不同的权重,与具有较小梯度的权重相比,具有较大梯度的权重被分配较小的学*速率。
这可以简单地通过累积先前的梯度并从中划分学*率来实现。
其中,ϵ是一个超参数,通常设置为 1e-6
,这是自适应梯度更新规则(Adagrad) ,由于某些原因,它在分母中没有平方根时将不起作用,对此没有明确的答案。
v 是累积梯度的更新向量,通过这种方式,我们可以根据特征的稀疏性调整学*率。
NPTEL NOC-IITM, Deep Learning CS7015
在上图中,绿色曲线代表阿达格拉德采取的收敛路径。它比 momentum 或 NAG 路径更短,在稀疏情况下速度更快,但可能不会收敛。
原因是如果 v_t 的值对于不稀疏的特征来说非常大,我们只是在多次迭代中杀死梯度。
RMSprop
对于自适应学*速率,我们希望将η除以每个权重的累积梯度的平方根,但是我们不希望梯度的“过度累积”用于不太稀疏的特征,以防止步长的消失。
一个可能的解决方案是取梯度平方的指数加权平均值(就像动量一样),而不是简单地相加。
v_t = β * v_t + (∇ w_t)并将β设置在 0 到 1 之间(β的默认设置是 0.9 或 0.95)
似乎累加梯度平方的加权平均的“分量”而不是整个梯度可以产生更好的结果。
v_t = β * v_t + (1 — β) * (∇ w_t)其中,通过乘以 1 — β,我们仅在 v_t 中累加梯度平方的一个分量作为加权平均值
如果我们用上面的等式代替 Adagrad 的累加步骤,那就变成 RMSprop(通过梯度的加权均方根的延拓来调整学*速率)。
下图显示了 RMSprop 采用的收敛路径。
NPTEL NOC-IITM, Deep Learning CS7015
亚当·乐观主义者——结合一切,获得当前的艺术状态
- Venilla 梯度下降
重复直到收敛:
。。。θ = θ — η * ∇θ .。。。。㈠ - 基于动量的梯度下降
初始化 m = 0
重复直到收敛:
。。。m = γ * m + η * ∇θ。。。。。(二)
。。。θ = θ — m。。。。㈣ - 具有自适应学*的 RMSprop 更新规则
初始化 v = 0
重复直到收敛:
。。。v = β * v + (1 — β) * (∇θ)。。。。。
(五)。。。θ = θ — {η / √(v + ϵ)} * ∇θ。。。。。㈥
在 ADAM 中,关键思想是结合动量和 RMSprop,即在没有η的情况下计算等式(ii)中的 m,并用等式(vi)中的∇θ代替 m。
这使它成为适应性的时刻
初始化 m = 0,v = 0
重复直到收敛:
。。。m = β1 * m + (1 — β1) * ∇θ。。。。。(七)
。。。v = β2 * v + (1 — β2) * (∇θ)。。。。。(八)
。。。θ = θ — {η / √(v + ϵ)} * m。。。。㈨
这是 ADAM 的更新规则。人们应该注意到等式(vii)与等式(ii)完全相同。γ被重命名为β1,并且我们通过对自适应学*速率应用 RMSprop 的相同逻辑,仅累积梯度(1-β1)的一部分。
亚当的一般设置为β1 = 0.9,β2 = 0.999,η = 0.01,ϵ = 1e — 6
ADAM 中的偏差校正
Adam 的上述更新规则适用于批量梯度下降。但在小批量梯度和随机梯度下降中,上述更新规则是不正确的。背后的原因是,在小批量梯度下降和 SGD 中计算的梯度不是真正的梯度,因为我们没有使用整个训练数据来计算它们,因此在每个小批量中计算的梯度存在随机变化,并且可能指向冲突的方向。
为了解决这个问题,应该将小批量或 SGD 中计算的梯度视为具有某种概率分布的随机变量,因此矩(m 和 v)应该等于该概率分布的期望值。
要保持的条件是𝔼[m] = 𝔼[∇θ]
但是,
m0 = 0
m1 =β1 * m0+(1—β1)* ∇θ_1=(1—β1)∇θ_1
m2 =β1 * m1+(1—β1)* ∇θ_2 =
=>β1 {β1 * m0+(1—β1)* ∇θ_1}+(1—β1)* ∇θ_2
=>β1(1—β1)* ∇θ_1+(1—β1)* ∇θ_2
m3 =β1(1—β1)* ∇θ_1+β1(1—β1)* ∇θ_2+(1—β1)* ∇θ_3
一般情况下,
mt = ∑ β1^(t-i) * {( 1 — β1) * ∇θ_i}。。。。。I 从 1 开始到 t
=>mt =(1—β1)∑β1^(t-i) ∇θ_i
=>𝔼[mt]= 𝔼[(1—β1)∑β1^(t-i) ∇θ_i]
=>𝔼[mt]=𝔼[∇θ]{(1—β1)∑β1^(t-i)}
=>𝔼[mt]=𝔼[∇θ](1—β1^t)
但是因为我们想让𝔼[m 等于梯度概率分布的期望值(𝔼[∇θ),我们必须通过除以(1-β1^t).)来修正 m
m' = m / (1 — β1^t)
v' = v / (1 — β2^t)。。。。(相同逻辑适用于 v)
以下是带有偏差修正的 ADAM 更新规则
ADAM 是训练神经网络的当前技术状态,并且被认为是过去四年来训练深度神经网络的首选。虽然其他算法特别是带有一些权重衰减策略的 RMSprop 工作得和 ADAM 一样好。人们可以将 RMSprop 比喻为汽车中的手动变速器,而 ADAM 是自动变速器。
ADAM 广泛用于所有的计算机视觉工作,并在几乎所有流行的卷积神经网络架构上产生了非常好的结果,包括非常深的网络,如 Resent 50。
新发现
最*有一些研究论文表明,ADAM 在某些情况下不会产生好的结果。另外,在这个领域有一些有趣的新研究。
- 循环学*率:https://arxiv.org/abs/1506.01186
- 亚当·W(解耦重量衰减):https://arxiv.org/abs/1711.05101
最*在 2019 年,谷歌大脑的研究人员提出了分层自适应矩优化器(LAMB)算法来训练他们的流行语言模型 BERT。
早些时候,用亚当 W 训练伯特需要 3 天,但兰姆只用了 76 分钟。下面是https://arxiv.org/pdf/1904.00962.pdf的论文,供进一步参考。😃
马来西亚汽车产业的深层透视
原文:https://towardsdatascience.com/a-deeper-look-into-malaysia-vehicles-industry-c114fda97d36?source=collection_archive---------10-----------------------
用可视化数据讲故事
交通拥堵被认为是马来西亚的一个主要问题,尤其是在马来西亚首都吉隆坡。所以,我从小到大都有一个疑问,为什么吉隆坡经常发生堵车?
是因为路况吗?也许吧…但是我想可能有一个更大的因素导致了这个问题。正如我们所知,在解决任何问题之前,理解全局应该是首要任务。因此,今天我会给你一些汽车市场的概述,在接下来的文章中,我会更深入地寻找答案。
如果你喜欢我的故事,请跟我来,我会尽力制作更好的内容。
事不宜迟,我们开始吧!
乘用车
乘用车(PV)包括乘用车(PC)、厢式车(WV)、多用途车(MPV)以及四轮驱动/运动型多用途车(4x4/SUV)。
根据马来西亚汽车协会(MAA)2019 年上半年关于光伏汽车前 20 大品牌的报告,Perodua 约占行业总量(TIV)的 45.2%,而本田和宝腾各占 16%左右。因此,你可以注意到前三大品牌已经占据了 77.7%的市场份额。
https://www.motomalaysia.com/category/best-car-under-rm50k-malaysia/?orderby=Price_Code&order=ASC
上面的截图显示了你能在马来西亚找到的最便宜的 4 辆车。Perodua 拥有马来西亚光伏汽车最大市场份额的原因之一是它提供了最便宜的汽车。
根据马来西亚雇主联合会 2018 年的研究,如果你是持有荣誉学位的应届毕业生,平均工资只有每月 2169 令吉。
假设你的工资是平均水平,你想买一辆 Perodua Axia。你需要付 10%的定金。现在,假设你的汽车贷款的利率是 4%,还款年是 5 年。所以,你每月需要支付大约 413 令吉,这已经占你工资的 19%了。在这个场景中,你可以看到,作为一名应届毕业生,买得起最便宜的汽车确实是一个巨大的负担。
总之,马来西亚汽车行业最实惠的价格可能是抢占市场份额的重要因素之一。
商用车辆
而对于商用车(CV),包括平板货车(PV)、皮卡(PU)、卡车、原动机(PM)和公共汽车。
根据马来西亚汽车协会(MAA)发布的报告,五十铃马来西亚有限公司连续第五年保持 2018 年全国首选 CV 品牌的首位。
尽管五十铃获得了全国最受欢迎的商用车徽章,但丰田仍有 Hilux 保持其在 CV 领域的最高市场份额地位,在排名前 20 的品牌中占 37.3%。
供求
上面的快照显示了马来西亚汽车市场的总销量和生产量。很明显,在 2018 年 6 月到 2018 年 8 月之间有一个峰值,我用红框突出显示了这个峰值。
如果你知道 MalaMalaysia 的 ss,这实际上是因为马来西亚总理 Tun Mahathir 重新引入销售和服务税(SST)并将商品和服务税(GST)标准税率设定为 0%的行动。
正如马来西亚人所知,12 月可以说是购买汽车的最佳月份之一,因为更多的公司提供年终销售,但从我在这里的观察来看,Tun Mahathir 的行动效果已经超过了季节性的影响。
最后的想法
我感谢你耐心阅读到最后,我希望这可以是你对马来西亚汽车市场的一个很好的介绍。
如果你对我收集的代码或数据集感兴趣,请在下面评论,我会清理代码并发送给你。
关于作者
Low 魏宏是 Shopee 的数据科学家。他的经验更多地涉及抓取网站,创建数据管道,以及实施机器学*模型来解决业务问题。
他提供爬行服务,可以为你提供你需要的准确和干净的数据。你可以访问 这个网站 查看他的作品集,也可以联系他获取抓取服务。
你可以在 LinkedIn 和 Medium 上和他联系。
阿帕奇气流资源的权威汇编
原文:https://towardsdatascience.com/a-definitive-compilation-of-apache-airflow-resources-82bc4980c154?source=collection_archive---------12-----------------------
又名一个新的数据工程师的阅读清单,开始工作在一个生产水平的 Apache 气流架构。
官方资源
- 气流文件
- 气流 GitHub 回购
- 气流维基首页
- 气流社区松弛通道
- 气流鸣叫
- 气流 JIRA
简介/概述
- 《气流:一个工作流管理平台》Maxime Beauchemin(Apache air flow 的创造者)。Airbnb 工程和数据科学。2015 年 6 月。
- ‘阿帕奇’气流渐渐壮大!’作者 Sid Anand(Paypal 首席数据工程师。提交人& PMC 成员阿帕奇气流)。中等。2019 年 1 月。
- “了解 Apache Airflow 的关键概念”,Dustin stans bury(Quizlet 数据科学家)。中等(~ 1.8k +1 的值)。2017 年 5 月。
- Airflow 101:如何开始使用 Airflow 实现数据管道自动化,作者 Sriram Baskaran(数据工程洞察数据科学项目总监)。中等(~ 1.2k +1 的值)。2018 年十月。
- [视频]'air flow 的最佳实践-工作流的开源平台&时间表,Maxime Beauchemin(Apache air flow 的创建者)。
- [视频] ' 使用 Python 和 Airflow(和 Spark)的现代 ETL-ing'作者 Tamara Mendt(hello fresh 的数据工程师)。PyConDE 2017。
- [视频] ' 气流实用介绍'作者马特·戴维斯(Clover 的数据平台工程)。PyData SF 2016。
- [视频] ' 利用 Apache Airflow 用 Python 代码开发优雅的工作流' Michael Karzynski(英特尔技术主管)。欧洲 Python 大会。2017 年 7 月。
- 【视频】’我是如何学会时间旅行的,或者说,数据流水线和气流调度,劳拉·洛伦茨(Data & SWE at Industry Dive)。PyData DC 2016。
行业中的气流
- “大规模管理优步的数据工作流”Alex Kira。优步数据工程。2019 年 2 月。
- Samuel Ngahane 和 Devin Goodsell 在 Twitter 上用工作流制作 ML。推特工程。2018 年 6 月。
- 艾斯·海德里的《潘多拉星球上的阿帕奇气流》。潘多拉工程公司。2018 年 3 月。
- 在 Lyft 运行阿帕奇气流,作者、Andrew Stahlman 和 Junda Yang。Lyft 工程。2018 年 12 月
- 为什么罗宾汉使用气流,Vineet Goel 著。罗宾汉工程公司。2017 年 5 月。
- 数据工程师、数据分析师和数据科学家之间的合作,Germain Tangus(daily motion 高级数据工程师)。每日运动工程。2019 年 5 月。
- Sift 如何使用 Apache Airflow 训练数千个模型’Duy Tran 著。筛工程。2018 年 3 月。
- 气流、元数据工程和世界上最大的民主国家的数据平台,Vinayak Mehta 著。Socialcops 工程。2018 年 8 月。
- 阿帕奇气流数据流量控制,尼古拉斯·戈尔·巴黎水(leboncoin 数据工程师)。leboncoin 工程博客。2019 年 1 月。
- “气流第二部分:经验教训(在 snap travel)”Nehil Jain 著。SnapTravel 工程。2018 年 6 月。
- 使用 Apache Airflow 在公共部门创建数据基础设施,作者 Varun Adibhatla 和 Laurel Brunk。天文学家 io . 2017 年 10 月。
- WePay上的气流。我们付钱。2016 年 7 月。
气流分布式部署
- Apache air flow 如何在芹菜工人身上分配工作,Hugo Lime(数据科学家,Sicara AI 和大数据)。希卡拉工程公司。2019 年 4 月。
- 关于如何构建气流服务器/集群的指南,作者 Tianlon Song(Zillow 的高级软件工程师、机器学*&大数据)。2016 年十月。
测试
- 数据的地狱:WB Advanced Analytics 的 7 圈数据测试地狱与气流。2018 年 1 月。
- 气流第 1 部分中的测试—由 Chandu Kavar 在介质(~1k +1)上进行的 DAG 验证测试、DAG 定义测试和单元测试。2018 年 8 月。
附加阅读
- 杰西卡·拉夫林的《我们都在错误地使用气流以及如何纠正它》。蓝芯工程。2018 年 8 月。
这些是我用来理解气流和与之相关的数据架构框架的资源。随着我继续工作并找到更多有用的资源,我应该更新这篇文章。请随意对这个列表提出补充建议。
关于气流资源的超详尽汇编,请查看 Jakob Homan(Lyft 数据软件工程师)的“Awesome Apache air flow GitHub Repo”。气流委员和 PMC 委员)。
携带数据分析的演示(丹佛 EDA 犯罪)
原文:https://towardsdatascience.com/a-demonstration-of-carrying-data-analysis-crimes-in-denver-eda-5e852bc75bee?source=collection_archive---------13-----------------------
这是我第二次演示使用 Python 进行数据分析。我之前的文章是关于纽约市 Airbnb 开放数据的。请看看,并给我你的意见和想法,让我可以不断改进。
[## 携带数据分析演示(纽约市 Airbnb 开放数据)
在本文中,我将使用 Pythons 进行数据分析,并记录下在此过程中的每一个发现和想法
towardsdatascience.com](/a-demonstration-of-carrying-data-analysis-new-york-city-airbnb-open-data-a02d0ce8292d)
这次我将分析“丹佛 EDA 中的犯罪”。可以通过以下链接从 Kaggle 下载数据:
[## 丹佛犯罪数据
下载数千个项目的开放数据集+在一个平台上共享项目。探索热门话题,如政府…
www.kaggle.com](https://www.kaggle.com/paultimothymooney/denver-crime-data)
Photo by Eric Donzella on Unsplash
下载文件中有两个 csv 文件,一个是包含数据集的“crime . CSV”;另一个是“进攻 _ 代码. csv ”,它将进攻代码解码成各种描述。第一步,我将在 crime.csv 上工作。
同样,在导入数据集之后,我喜欢先打印一些记录,然后获取数据集的基本信息。
data = pd.read_csv('crime.csv')
data.head()
data.info()
data.head()
data.info()
如 info()所示,有些变量缺少一些值。
data.isnull.().sum()
所以 LAST_OCCURRENCE_DATE 丢失了太多贵重物品。所以没必要留着。对于 INCIDENT_ADDRESS,由于有 GEO_LON 和 GEO_LAT,我将直接使用它们,因此我也将删除 INCIDENT_ADDRESS。我不知道 GEO_X 和 GEO_Y 是什么,但我相信它们也是用来定位的。所以我不会留着它们。对于 GEO_LON 和 GEO_LAT,我将保留那些丢失的记录,因为其他变量是有价值的。
data.drop(['INCIDENT_ID','INCIDENT_ADDRESS'],axis=1,inplace=True)
接下来是一些与进攻类型相关的栏目;“冒犯 _ 代码”、“冒犯 _ 代码 _ 扩展”、“冒犯 _ 类型 _ID”、“冒犯 _ 类别 _ID”。“冒犯 _ 代码”和“冒犯 _ 代码 _ 扩展”为数字格式;“进攻类型标识”和“进攻类别标识”是字符串格式。现在它可以导入另一个 csv 文件。
data_codes = pd.read_csv('offense_codes.csv')
data_codes.head()
data__codes.info()
data_codes.head()
data_codes.info()
data_codes 中没有缺失值。
除了数据中的这四列,data_codes 中还有一些列。因此,最好先将它们结合起来,以获得更详细的信息。
但首先我会检查“crime.csv”中的现有信息是否与“offense _ codes.csv”相同
data_temp = data.merge(right=data_codes,how='left', left_on =['OFFENSE_CODE','OFFENSE_CODE_EXTENSION'],right_on=['OFFENSE_CODE','OFFENSE_CODE_EXTENSION'])(data_temp['OFFENSE_TYPE_ID_x']==data_temp['OFFENSE_TYPE_ID_y']).all()(data_temp['OFFENSE_CATEGORY_ID_x']==data_temp['OFFENSE_CATEGORY_ID_y']).all()(data_temp['IS_CRIME_x']==data_temp['IS_CRIME_y']).all()(data_temp['IS_TRAFFIC_x']==data_temp['IS_TRAFFIC_y']).all()
所以所有结果都是真的。这意味着“crime.csv”中的那些现有列在与“offense _ codes.csv”合并后是相同的。所以我们只需要保留从“进攻 _ 代码. csv”中获得的新列。
data = data_temp.loc[:,~data_temp.columns.str.endswith('_y')]
data.columns = data.columns.str.replace('_x', '')
由于只执行了左连接,因此有必要再次检查连接后是否有任何缺失值。
data.isnull().sum()
很好,连接后没有丢失值。所以不需要保留“进攻 _ 代码”和“进攻 _ 代码 _ 扩展”。让我们移除它们
data.drop(['OFFENSE_CODE','OFFENSE_CODE_EXTENSION'],axis=1,inplace=True)
现在进入下一步。
有两列存储日期信息,“首次发生日期”和“报告日期”。但是,回到 data.info(),它们只存储为字符串。所以最好把它们的格式改成 datetime 格式。
data['FIRST_OCCURRENCE_DATE'] = pd.to_datetime(data['FIRST_OCCURRENCE_DATE'], infer_datetime_format=True)
data['REPORTED_DATE'] = pd.to_datetime(data['REPORTED_DATE'], infer_datetime_format=True)
我们开始吧。
我正在处理的数据集涵盖了从 2004 年 1 月 2 日到 2019 年 9 月 26 日。显然,数据集在不断更新,所以如果你的结果与我的不同,不要担心。
第一次分析:最常见的犯罪
data.groupby('OFFENSE_CATEGORY_NAME').agg({'INCIDENT_ID':'count'}).sort_values(by='INCIDENT_ID',ascending=False)
最常见的类别是“交通事故”。幸运的是,“谋杀”是最少发生的一个。
data[data['OFFENSE_CATEGORY_NAME']=='Traffic Accident'].groupby('OFFENSE_TYPE_NAME').agg({'INCIDENT_ID':'count'}).sort_values(by='INCIDENT_ID',ascending=False)
在“交通事故”中,普通交通事故最多,约占总“交通事故”的三分之二。第二种是肇事逃逸。
如果你想知道每个犯罪类别的前五种犯罪类型,你可以使用下面一行代码:
data.groupby(['OFFENSE_CATEGORY_NAME','OFFENSE_TYPE_NAME']).agg({'INCIDENT_ID':'count'}).groupby(['OFFENSE_CATEGORY_NAME']).head().sort_values(by=['OFFENSE_CATEGORY_NAME','INCIDENT_ID'],ascending = [True,False])
基本上,你首先执行一个分组,并得到每个进攻类别类型组合的计数。然后使用进攻类型执行另一个 groupby,并使用 head()获得前五种进攻类型。最后,通过排序呈现结果。
那么接下来的分析就是要找出每起犯罪哪个时间段报案比较常见。为此,第一步是创建一个新列来存储“FIRST_OCCURRENCE_DATE”的小时
data['FIRST_OCCURRENCE_HOUR'] = data['FIRST_OCCURRENCE_DATE'].dt.hour
然后绘制频率图。
sns.countplot(data=data,x='FIRST_OCCURRENCE_HOUR')
plt.title('Frequency of crime by hour')
plt.show()
所以大多数报道的犯罪都发生在白天。我相信那些罪行只是小罪。
data[data['FIRST_OCCURRENCE_HOUR'].isin([15,16,17,18])].groupby(['FIRST_OCCURRENCE_HOUR','OFFENSE_CATEGORY_NAME']).agg({'INCIDENT_ID':'count'}).groupby(['FIRST_OCCURRENCE_HOUR']).head().sort_values(by=['FIRST_OCCURRENCE_HOUR','INCIDENT_ID'],ascending = [True,False])
但是总的来说,轻罪比重罪多得多,仅仅比较绝对数字是没有意义的。因此,最好进行升力分析。
升力分析是一种常见但有用的分析。它首先用于数据挖掘,但现在它在许多领域都有应用。更多信息,维基百科和 kdnuggets 可以帮助你。
[## Lift(数据挖掘)
在数据挖掘和关联规则学*中,提升是目标模型(关联规则)性能的度量
en.wikipedia.org](https://en.wikipedia.org/wiki/Lift_(data_mining)) [## 提升分析——数据科学家的秘密武器——KD nuggets
作者安迪·高施米特,阿卡努。每当我阅读关于数据科学的文章时,我都觉得有一些重要的方面…
www.kdnuggets.com](https://www.kdnuggets.com/2016/03/lift-analysis-data-scientist-secret-weapon.html)
基本上,提升分析是计算某一事件在特定情况下发生的概率是高还是低。例如,电梯分析可以判断午夜谋杀是否更频繁。然后我们计算午夜发生谋杀的概率和全天的概率然后得到比率。
摘自维基百科,“如果某个规则的提升值为 1,这意味着前因和后果出现的概率是相互独立的”
在这里,前因是午夜,后果是谋杀。
所以我定义“午夜”是从晚上 10 点到凌晨 4 点。然后下一步是计算全天和午夜期间的谋杀概率。
murder_ttl_count = data[data['OFFENSE_CATEGORY_NAME']=='Murder']['INCIDENT_ID'].count()
ttl_count = data['INCIDENT_ID'].count()
murder_midnight_count = data[(data['OFFENSE_CATEGORY_NAME']=='Murder')&((data['FIRST_OCCURRENCE_HOUR']>=22)| (data['FIRST_OCCURRENCE_HOUR']<=4))]['INCIDENT_ID'].count()
midnight_count= data[(data['FIRST_OCCURRENCE_HOUR']>=22)| (data['FIRST_OCCURRENCE_HOUR']<=4)]['INCIDENT_ID'].count()lift = (murder_midnight_count / midnight_count) / (murder_ttl_count/ttl_count)
print("Average probability of having murder during the whole day : {:1.6f}".format((murder_ttl_count/ttl_count)))
print("Probability of having murder during the midnight : {:1.6f}".format((murder_midnight_count / midnight_count)))
print("The lift is : {:1.6f}".format(lift))Average probability of having murder during the whole day : 0.000604
Probability of having murder during the midnight : 0.001190
The lift is : 1.969831
由于电梯大于 1,谋杀在午夜比平均水平更频繁。您可以对其他类别进行类似的计算,找出每种犯罪类型的流行时间段。
下一步是查看任何报道谋杀的热门地点。和上次一样,我将使用 follow 来可视化数据。
data_murder = data[data['OFFENSE_CATEGORY_NAME']=='Murder']
denver_map = folium.Map(location=[39.7, -104.9],zoom_start =11)
data_loc= data_murder[['GEO_LAT','GEO_LON']].values
data_loc =data_loc.tolist()
hm = plugins.HeatMap(data_loc)
hm.add_to(denver_map)
denver_map
大多数谋杀发生在丹佛的北部和西北部。
本次分析到此为止。欢迎分享你的想法和评论,这样我可以继续改进。请随意分享并鼓掌支持我。
以下是 GitHub 上完整代码的链接:
https://github.com/wyfok/Crimes_in_Denver_EDA
携带数据分析演示(纽约市 Airbnb 开放数据)
原文:https://towardsdatascience.com/a-demonstration-of-carrying-data-analysis-new-york-city-airbnb-open-data-a02d0ce8292d?source=collection_archive---------15-----------------------
在本文中,我将使用 Python 执行数据分析,并记录分析过程中的每个发现和想法。用真实数据练*不仅可以帮助我在分析不同数据时有更多的经验,还可以帮助我在与他人的作品进行比较时发现更多的技术和技能。
Photo by Oliver Niblett on Unsplash
本文使用的数据集是来自 Kaggle 的“纽约市 Airbnb 开放数据”。下面是下载链接https://www . ka ggle . com/dgomonov/new-York-city-Airbnb-open-data
导入模块和 csv 文件后,通常我的第一步是浏览数据集。这一步包括研究整个数据集的格式、所有变量的类型、检查和清理数据集。
data = pd.read_csv('AB_NYC_2019.csv')
data.info()class 'pandas.core.frame.DataFrame'>
RangeIndex: 48895 entries, 0 to 48894
Data columns (total 16 columns):
id 48895 non-null int64
name 48879 non-null object
host_id 48895 non-null int64
host_name 48874 non-null object
neighbourhood_group 48895 non-null object
neighbourhood 48895 non-null object
latitude 48895 non-null float64
longitude 48895 non-null float64
room_type 48895 non-null object
price 48895 non-null int64
minimum_nights 48895 non-null int64
number_of_reviews 48895 non-null int64
last_review 38843 non-null object
reviews_per_month 38843 non-null float64
calculated_host_listings_count 48895 non-null int64
availability_365 48895 non-null int64
dtypes: float64(3), int64(7), object(6)
memory usage: 6.0+ MB
所以总共有 16 列,有些列有缺失值。
data.isnull().sum()id 0
name 16
host_id 0
host_name 21
neighbourhood_group 0
neighbourhood 0
latitude 0
longitude 0
room_type 0
price 0
minimum_nights 0
number_of_reviews 0
last_review 10052
reviews_per_month 10052
calculated_host_listings_count 0
availability_365 0
dtype: int64
在数据集中,last_review 和 reviews_per_month 都有超过 10k 的缺失值。它们也有相同数量的缺失值。根据缺失值的名称和数量,我怀疑这两列是相关的,因此缺失值的数量相同。
(data['last_review'].isnull()==data['reviews_per_month'].isnull()).all()True
所以应该一起处理。
此时,我不知道如何处理“last_review”列中缺少的值,因为这通常显示一个日期字符串,指示上次审查的日期。所以此时此刻,我会先把它放在一边。
但是,对于 reviews_per_month 中缺失的值,我会将它们赋为零。
data.loc[data['reviews_per_month'].isnull(),'reviews_per_month']=0
其余缺少值的列是 name 和 host_name。但是,我觉得无论从名字还是 host_name 都没有任何预测力。因此,我将直接从数据集中删除,而不是处理丢失的值。
有两列,id 和 host_id,表示 Airbnb 的房子和主人。检查后,id 在数据集中是唯一的,但 host_id 不是。因此,可以删除 id,但不能删除 host_id。此外,如果房源数量和价格之间存在任何关系,这也是有意义的。因此将保留 host_id。
下一步是使用
data.describe()
使用 describe()可以帮助我理解每个变量的可能值的范围。我可以知道值的分布。此外,从数据集中发现任何不现实的记录也是可能的。
例如在这个数据集中,有一些异常。第一个是存在“价格”= 0 的记录,这是不现实的,因为这意味着不需要支付住宿费用。所以这些记录应该被删除。
第二个是“minimum_nights”最高 1250 我认为不现实(这还是 Airbnb 还是只是另一个租房合同?).我把阈值定为 365 天。“minimum_nights”大于 365 的任何记录也将被删除。
清理后的数据集:
data.info()<class 'pandas.core.frame.DataFrame'>
RangeIndex: 48870 entries, 0 to 48869
Data columns (total 12 columns):
host_id 48870 non-null int64
neighbourhood_group 48870 non-null object
neighbourhood 48870 non-null object
latitude 48870 non-null float64
longitude 48870 non-null float64
room_type 48870 non-null object
price 48870 non-null int64
minimum_nights 48870 non-null int64
number_of_reviews 48870 non-null int64
reviews_per_month 48870 non-null float64
calculated_host_listings_count 48870 non-null int64
availability_365 48870 non-null int64
dtypes: float64(3), int64(6), object(3)
memory usage: 4.5+ MB
48870 行和 12 列
现在我可以看看数据集了。一次一列
第一个是邻里群体
set(data['neighbourhood_group']){'Bronx', 'Brooklyn', 'Manhattan', 'Queens', 'Staten Island'}data.groupby('neighbourhood_group')['price'].describe()
该表很容易显示每个邻域组和所有邻域组的价格分布。Airbnb 的数量不是偶数。大多数 Airbnb 的房子要么在曼哈顿,要么在布鲁克林。不过这两个区域也是五个区域中价格最高的。一个可能的原因是,因为这些地区的需求很高,导致更多的主人出租他们的房间或公寓。
为了更准确地显示价格,考虑到房型,我们进行了进一步的细分。
data.pivot_table(index='neighbourhood_group',columns='room_type',values='price',aggfunc='mean')
一般来说,你可以在布鲁克林租到一个单间,但在曼哈顿你甚至租不起一个合住的房间。
接下来是 Airbnb 的位置。众所周知,曼哈顿和布鲁克林有更多的 Airbnb。这里我用一张热图来呈现。
ny_map = folium.Map(location=[40.7, -74],zoom_start =10)
data_loc= data[['latitude','longitude']].values
data_loc =data_loc.tolist()
hm = plugins.HeatMap(data_loc)
hm.add_to(ny_map)
ny_map
曼哈顿和布鲁克林有一大片红色区域。
是时候进一步细分各个小区了。
for gp in set(data['neighbourhood_group']): print(data.loc[data['neighbourhood_group']==gp,].groupby(['neighbour hood_group','neighbourhood']).agg({'price':['count','mean']}).sort_values(by=('price', 'mean'),ascending=False).head())
print()
上表显示了每组中前 5 名最昂贵的社区。除了 Staten Island 在某些邻居中只有 1 条记录是 top 5 neighbors 之外,其他邻居都有足够的记录来正确表示每个地区的平均价格。布朗克斯的河谷镇和曼哈顿一样贵。
下一个要研究的变量是“最低夜数”。第一个变量是按“邻居组”细分的
data.groupby('neighbourhood_group')['minimum_nights'].describe()
由于所有“minimum_nights”大于 365 的记录都已被删除,因此最大值仅为 365。如图所示,超过 25%的 Airbnb place 只需要 1 晚,超过一半的 Airbnb place 只需要 2 或 3 晚,这符合 Airbnb 服务的最初原则,即短期住宿。
现在我们可以转到下一个变量,视图。我会使用每月评论数而不是评论数,因为这样可以消除 Airbnb 上持续时间列表的影响。
for gp in set(data['neighbourhood_group']):
print(gp)
print(data[data['neighbourhood_group']==gp] ['price','reviews_per_month']].corr())
print()
显然,价格和每月的评论数量之间没有关系。
相反,几乎所有的房子每个月都只有很少的评论。
分析到此结束。希望您喜欢,并请与我分享您的评论,以便我可以不断改进,并在未来使用 Python 演示更多的数据分析。下次见。
完整的代码可以在https://github.com/wyfok/New_York_City_Airbnb_Open_Data找到
数据科学的设计思维模式
原文:https://towardsdatascience.com/a-design-thinking-mindset-for-data-science-f94f1e27f90?source=collection_archive---------1-----------------------
改编自为德克萨斯大学 capstone 撰写的一篇研究论文。
摘要
自年以来,数据科学在技术研究和商业战略中受到了关注;然而,数据科学研究过程本身有机会增加研究和改进。通过本文中描述的研究方法,我们相信有可能将设计思维应用到数据科学过程中,以努力形式化和改进研究项目过程。因此,本文将集中讨论这一理论的三个核心领域。首先是数据科学研究过程的背景,以及数据科学家面临的常见陷阱。第二篇文章解释了设计思维原则如何应用于数据科学。第三个是基于上述发现提出的数据科学研究项目的新流程。本文最后将分析对数据科学个人和团队的影响,并对未来研究提出建议,以验证提议的框架。
关键词:数据科学,研究过程,设计思维应用
简介
数据科学可以说是本世纪最受欢迎的工作之一;然而,这份工作的特点仍然不确定( HBR )。大学项目中缺乏正式培训,角色要求不明确,以及职位的广泛性导致了如何成为一名优秀的数据科学家的模糊性,以及对那些能够做所有事情的人的偶像崇拜——俗称“独角兽”。
数据科学领域的学术进步传统上集中在新的统计分析技术、机器学*模型和神经网络的开发上。对过程本身的研究很少,最突出的是 1997 年提出的 KDD 过程 —数据库中知识发现的框架。除了过时和缺乏对当今数据科学研究过程中常见挑战的答案之外,KDD 框架还主要关注过程中的数据挖掘步骤,而没有将其深度扩展到整个研究过程。
过程研究在其他领域相当流行;最值得注意的是在设计领域——这个职业已经发展出了大量关于如何用设计师的思维解决问题的文献。研究人员和杰出的设计师分享了设计工作中使用的核心方法和推理模式,从而使术语“设计思维”及其相关实践在企业和机构中得以普及。此外,设计思维的许多方法和原则具有广泛的适用性,已经应用于教育、医疗和写作研究等领域。
数据科学家的角色缺乏正式性,缺乏现有的文献,以及与设计研究领域的跨学科重叠,这些都鼓励了对整个数据科学过程的进一步研究。因此,本文旨在确定数据科学研究过程中的常见陷阱,并通过强调与数据科学研究过程相关的设计思维的优势,提出一个使用设计思维的原则和过程解决数据科学问题的新框架。本文还将解释用于得出这些结论的方法,解释潜在的影响,并确定未来的研究机会。
方法论
本文的数据是通过专业的第一手经验以及对行业研究和学术文献的全面回顾和分析收集的。以下提供了所用方法的总结,参考资料中列出了更详细的来源:
- 使用谷歌学术和搜索词(如设计思维过程、设计思维应用、数据科学过程、数据科学挑战、研究错误和数据科学研究)对设计思维和数据科学主题的已发表论文进行系统综述
- 对斯坦福 D 学院、IDEO、跳板和奥赖利等知名机构的主题专家发表的博客和内容进行评论
- 回顾热门书籍中的概念,主题包括设计改变、数据分析风格的要素、和用数据讲故事
- 在尝试解决数据科学研究过程的常见缺点时,考虑了设计思维之外的其他过程框架。其中考虑的是精益和敏捷框架。最终,设计思维被选中,因为它直接应用于一般的研究过程,而不是其他更类似于开发过程的框架。
数据科学研究过程概述
对于本文来说,首先要区分数据科学问题和数据科学研究项目。前者被定义为一个定义明确的问题或一组问题,提供这些问题的目的是为了快速得出答案。相比之下,数据科学研究项目包含更大的努力,其中目标和答案是同时开发的。这两者可以根据完成所需的时间长短来分类——一个问题可以很快得到回答,而一个项目则需要一段较长的时间才能完成。另一个区别在于任务的模糊性:一个问题仅仅是;而一个项目通常开始时比较模糊,因此会导致许多挑战。以下部分详细介绍了完成数据科学项目的流程以及相关的常见缺陷。
陷害问题
在任何研究过程中,通过提出问题,陈述自己的假设,并发展一种战略方法来回答所提出的问题是很常见的。按照这种思路,通常在进行研究时会考虑到可用数据的局限性,而不是从战略问题或方向入手;然而,大数据的兴起从根本上改变了人们进行此类研究的方式。随着可用的数据数量、质量和种类的增加,有效地消除了利用数据的限制开始研究过程的需要,构建数据科学项目的方法并没有发展。这在缺乏经验的数据科学家中变得最麻烦,他们通常从什么数据可用的心态开始,努力发现有意义的见解,而不是从什么问题最有战略价值来集中他们的研究。
获取数据
数据科学研究过程的后续步骤——收集、清理和准备数据——的重要性经常被忽视。数据完整性是研究领域的一个大问题,它始于对数据来源的全面了解。如果没有对数据源的全面理解,就很难清楚地说明结果的可归纳性和准确性、任何发现的影响或为受众开发的模型的理论基础。
探索数据
数据探索,也称为数据挖掘,是从大型数据集中发现有价值见解的过程,通常借助于高级统计分析和可视化。除了表面水平的技术,如运行变量的描述性统计和检查相关性,过程中的这一点可能会难倒数据科学家,因为他们不知道对数据提出什么问题。要在这一步取得成功,需要对研究问题有丰富的知识,并有创造力从初步探索转向有价值的见解。
进行深入分析
一旦研究完数据,流程通常会转向进一步的深入分析或模型构建,这取决于项目的范围。在这一点上,当数据科学家全神贯注于项目,以至于看不到最终目标,或者陷入兔子洞,或者产生对项目的利益相关者来说不是立即可操作的或有价值的结果时,就会出现常见的失败。
传达结果
与任何研究一样,数据科学研究项目的最后一步是将研究结果传达给相关的利益相关方。在这一点上,数据科学家或研究团队需要传达基于他们的发现应该采取的行动,方法是将他们打包到报告或演示文稿中,并与能够实施相关见解的团队共享这些发现。理想情况下,所有的研究项目最终都会对一个企业有更深入的了解,如果不是直接的行动,以证明投入时间进行研究是值得的;然而,这种情况并不常见。
总之,以上对数据科学流程的描述揭示了一个挑战的总体主题:构建和提出正确的数据问题,并为相关利益相关方产生可操作的结果。
提议的思维模式:数据科学研究过程的设计思维
正确地构建问题,并确保过程产生可操作的结果,这一挑战也是设计思维过程所要解决的。一套核心原则的定义和一个高级流程的创建,使得如何在设计者中解决这些问题变得清晰。通过综合设计思维的优势和数据科学研究中发现的不足,以下部分提出了数据科学研究的原则和流程改进:
核心指导原则
- 同理心:在一开始就定义相关的利益相关者,并在整个过程中记住他们,包括进行主题专家访谈,经常收集非正式的反馈,以及创建一个专门包装的最终产品来满足利益相关者的需求。
- 通过原型进行理解:研究人员对问题空间的理解可以受益于预先绘制假设的复杂分析或模型,以便在投入大量精力开发完整的解决方案之前掌握范围并测试可能的解决方案。此外,快速原型法被证明可以在更短的时间内获得与非约束原型法相似的结果。
- 积极而有目的的反馈:经常有目的地从技术和非技术利益相关者那里收集信息,有助于加深对问题的理解,并集思广益找到解决方案。
- 描述之上的图表:分析、模型和发现的交流可能会变得复杂。帮助非技术观众理解流程;让它可视化。
- 借鉴他人的想法:从内部和外部寻找已经完成的工作,以及如何在此基础上再接再厉。由于缺乏知识共享,团队经常遭受重复工作的困扰,数据科学工作也不例外。
- 拥抱创造力和非线性之旅:如果一个研究人员没有探索很多选项,他们就没有足够的发散。抱着数量胜于质量的心态进行头脑风暴,为以后的发现提供了更多的选择。
新流程
构思
如前所述,成功的数据科学项目始于战略问题和研究领域的选择。设计思维将战略选择过程描述为平衡技术可行性、合意性和商业可行性。这种思维模式迫使设计解决方案结合业务和技术方面来考虑解决方案的人的因素,这是一个经常被忽视的领域。下面提出了一个类似的文氏图,用于选择数据科学研究领域,以帮助增加数据科学项目的成功机会:技术可行性、业务影响和数据可用性的交集。
Demonstrating the Three Aspects of Data Science
构思阶段的另一个重要方面是问题的框架和范围,包括确定假设、重要问题和研究目标。在设计思维中,由于设计师通常不是主题专家,设计师几乎从项目被分配的第二秒钟就开始进行主要和次要的研究,以发展对问题空间的理解。通常在这些早期阶段,设计师会惊喜地收集到比预期更深入的见解。即使设计者或研究人员没有明确要求,一个简单的问题,要求被引导通过过程可能阐明痛苦和问题。
数据科学家可以应用相同的技术来帮助自己熟悉感兴趣的领域,了解利益相关者,并发现有助于构建其研究流程的见解。应用这种思维方式可能看起来像是数据科学研究项目的开始阶段,包括大量的前期研究。要执行的活动示例包括:
- 与其他业务单位和团队的信息访谈
- 用图表表示过程和概念来测试理解
- 在适用的情况下,访问用户证明和支持票证
探索性分析
进入一个项目的探索阶段会显得杂乱无章,很难提出想法,并导致创意枯竭。设计思维通过创建流程图和框架来组织关键知识,确定进一步关注的领域,并将决策传达给外部利益相关方,从而进入设计流程的这一阶段。设计思维中使用的探索性工具的例子包括 原样旅程图和客户旅程 。类似的工具,或者简单地描绘出研究领域的概念,可以帮助数据科学家在探索阶段组织和策划他们的下一步。
分析技术中的头脑风暴和创造力也是探索阶段的关键部分。正如本文前面所述,当数据科学家无法想出新的分析问题来尝试发现一个有趣的领域进行进一步研究时,他们会感到沮丧。数据科学方法可以借鉴设计思维中的一个重要理论,即在项目的早期阶段,数量重于数量。不要从一开始就限制想法,而是从写出 100 个可以由数据构成的潜在问题或疑问开始,不管这些问题或疑问有多荒谬或无用,然后将这些想法捆绑到主题中,并根据容易程度和潜在影响对它们进行优先排序。
建模、原型制作和深入分析
设计思维过程受益于快速迭代和来自相关利益相关者的有针对性的反馈,允许在选择过程中考虑更大范围的可能解决方案。这种策略旨在避免个人偏见,以及在更好的想法出现时选择第一个想法。数据科学过程可以从类似的策略中受益,以帮助增加创造力和考虑的选项,同时避免基于尝试的第一个想法来确定解决方案。
从相关利益相关者那里收集反馈也有利于沟通和认同。例如,设计师不仅将反馈作为收集潜在解决方案输入的方法,还用于学*如何最佳定位解决方案并与特定受众分享发现。类似地,数据科学家经常努力确保项目结果与利益相关者相关,如果相关,如何传达。因此,在建模和创建更深入的分析的整个过程中,频繁和有意的反馈可以改善这些弱点。
展示调查结果和模型
大多数研究过程收集了大量的数据和见解,这些数据和见解通常不仅仅是与受众相关和有价值的。因此,结果往往需要提炼出真正重要的东西。设计思维通过在故事中构建见解和建议的解决方案来实现这一步,旨在带领观众了解为什么最终结果很重要,这些结果是如何实现的,以及如何解决这些问题。
数据科学研究通常不会以一个精心制作的故事结束,因此为观众创造引人入胜的材料可能具有挑战性。通过借用设计思维中的讲故事原则,有以下几点建议:
- 关注解释性分析而不是探索性分析:解释性分析首先提出一个重要的发现或建议,然后解释实现这个发现或建议的过程。那些仅仅是有趣而没有用的发现会被保存下来用于项目的深入描述,或者根本不包含在内。
- 有目的地使用想象:开始想象,写下需要沟通的内容,然后准确地创造出来。通常更容易的是创建一组图表和图形,然后围绕所创建的内容获取见解和构思一个故事。这导致不太引人注目的可视化。而是从目的入手。
- 将过程记录为一次旅程:分享得出结论的步骤有助于听众对最终建议有更深的理解,并激发行动。利用研究之旅建立可信度,并获得重要利益相关者的认同。
潜在影响
本文开头讨论了对“独角兽数据科学家”的期望和寻找,他们在数据科学的技术、业务战略和沟通方面表现出色。此外,对与数据科学相关的技术培训的关注使许多人缺乏战略和沟通技能。
提议的数据科学设计思维模式有可能在流程的其他方面帮助有技术头脑的人,包括框定问题,通过创造性方法扩展构思,在牢记最终目标的情况下执行探索性分析,收集关于原型的反馈以保持利益相关者的参与,以及将最终结果打包成令人信服的故事。此外,随着数据科学的技术组件随着 Watson 等基于人工智能的数据分析产品越来越多地走向自动化,数据科学工作的这些确定的方面将变得越来越重要,因为它们本质上是以人为中心的,更难以自动化。
结论
现有文献展示了设计思维过程的好处,并强调了数据科学过程中面临的失败和挑战。通过综合两个学科的研究,人们可以得出结论,数据科学学科可以从应用成熟的设计思维方法中受益。数据科学流程受益最大的两个特定领域是对数据提出正确的问题,以及产生可操作的结果。
首先,数据科学家可以运用同理心和原型来确保他们有正确的框架,并对数据提出正确的问题。在整个构思阶段,数据科学家可以进行信息访谈,以更深入地了解他们试图解决的问题,同时培养对最终用户的同情心。数据科学家可以使用分析和模型的原型来加深对数据的理解,了解解决方案的可行性,并收集关于其结论对利益相关者的有用性的信息。
其次,数据科学家可以通过寻求对调查结果和调查结果的沟通方式的积极反馈来提高其结果的可操作性。通过收集项目中技术和非技术利益相关者的意见,数据科学家可以检查他们是否在项目中产生有用的结果,而不是等到最后才展示他们的发现。在项目结束时,当数据科学家正在评估传达其发现的最佳沟通方式时,反馈也是有益的。
随着数据分析和机器学*领域的不断发展,数据科学研究过程将变得越来越重要。正如在研究中所看到的,很明显,在已知的挑战和围绕该过程的支持研究之间存在差距。通过综合其他学科的知识,本文提出了一个框架,该框架可以改善上述挑战,并定义下一个数据科学研究流程范式。
未来研究
本文旨在作为执行数据科学研究项目的新流程框架的起点。可以进行研究,以评估将设计思维原则应用于数据科学研究问题的有效性,并通过更正式的流程建议来构建基线想法。此外,研究可以侧重于衡量数据科学团队对业务的影响,以帮助量化流程改进的重要性,并帮助比较多个流程。这项研究的重点不是量化“快速和肮脏”分析与全面研究项目之间的权衡,因为它关系到决策和战略的质量。衡量研究类型之间的影响和权衡的挑战在于如何定义成功。因此,进一步研究的合适起点可能是定义一些关键性能指标,以帮助量化数据科学工作。
推荐进一步阅读和本文的主要启示
- 因设计而改变,蒂姆·布朗
- 用数据讲故事,科尔·克纳弗利克
- 数据分析风格的要素,杰弗里·韭菜
可视化文本数据集的设计者指南
原文:https://towardsdatascience.com/a-designers-guide-to-visualize-a-text-dataset-1d534756e914?source=collection_archive---------12-----------------------
The Office — Season 5, Episode 17 — Golden Ticket
数据可视化
用 Python 和 R 创建数据驱动的可视化
在本文中,我探索了一种使用 Python 和 R 代码可视化文本数据集的方法。作为一名用户体验和信息设计师,我想提高我的技术技能。我通过结合我的“兴趣”和挑选一个不寻常但有趣的数据集来实现这个目标。
经过一番寻找,我在布丁旁边的看到了这个精彩的互动 dataviz 项目 【办公室】五图对话。这个项目是一个很好的开始参考,它也给我指出了一个我可以想象的可怕的数据集。这个数据集本质上是《办公室》每一集所有台词的集合。
太好了!我找到了数据,现在我终于可以开始了!
第一步
首先,我决定根据我的技术能力和我希望学*的技能为这个项目设定一些目标和限制。
我需要知道我自己的项目的原因。
我当初为什么要启动这个项目?我希望学到什么?我想完成什么?
我这个项目的目标是:
- 使可视化代码足够简单,并且能够创建有趣的模式。
- 使用现有的 python 知识。
- 学* R studio 中的图形渲染。
- 培养非数字数据的设计思维。
- 全职工作的同时管理兼职项目。
第二步
接下来,为了指导我的设计,我开始思考这个可视化的目标。我的方法是开始问一些可以探究的问题。
我们的目标不是回答所有的问题,而是用它们来集思广益可视化的概念和想法。
例如,一些问题是
- 每个角色的心路历程是怎样的?
- 每个角色的屏幕时间是多少?
- 所有的角色之间是如何互动的?
- 每一集都有哪些主角?
第三步
基于现有的数据和我的目标,我想出了一些想法和可行的解决方案。我的想法围绕着表示从基于文本的数据集导出的数值。
在开始编码之前,我决定勾勒出我的最终设计。这被证明是一个有用的工件,用于计算数学和逻辑。
在这里,我以非线性方式可视化了一个线性对话。
一集中所说的每一段对话都被表示为一个线段。为了传达对话的连续性,所有的线段都要相互连接。然而,它们以直角连接,即在一个线段的末端,下一个线段开始,但是具有 90°的枢轴。
如设计所示,我用以下方式编码数据-
- 对话(说出的单词数)→线段的长度
- 字符→颜色
非线性数据可视化的美妙之处在于,
真的真的真的真的(!)长文本可以包含在有限的空间内。
第四步
我需要将这个数据集转换成一个更加明确的结构,以便能够对它做一些有用的事情。现在,我的想法是使用 python 来清理数据,并使用 R 将其呈现为可视化形式。
python 程序的输出成为 R 程序的输入。
那么,我期望 python 程序的输出是什么呢?
一个 CSV 文件,可以导入到 R studio 中,它包含关于每个线段的坐标及其颜色的信息。
我从一个随机的插曲开始- 办公室奥林匹克!
(也恰好是我的最爱之一!)
我开始从网站上复制对话框并粘贴到一个中。txt 文件。我想也可以编写 python 代码来从网站上收集必要的数据。数据清理包括删除不是对话框的文本。在这个网站上,一集的故事情节,即每个角色的行为都被放在方括号中,并从整体文本中删除。
下一个任务是,计算数学。正如设计建议的那样,我根据说对话的角色和它的长度,为每个线段计算颜色和坐标。
步骤五
执行完这段 python 代码后,我有了必要的输入。我使用 python 程序生成的 CSV 文件,通过 R studio 绘制了基于线的数据可视化。尽管它是一小段相对简单的代码,但编写它是对**ggplot2**
库的一次有用的学*经历。
瞧啊。就是这么做的。
最后的结果
在 Illustrator 中做了一些修改后,下面是这个项目的一些输出。我为不同的图案修补了颜色。
The Office — Season 2, Episode 3 — Office Olympics
The Office — Season 1
The Office — Some of my favorite cold opens
最终意见
我可以假设这可能不是你读过的最精彩或最复杂的东西。然而,我真的希望这是你今天遇到的最有趣的事情之一。
在这篇文章中,我想鼓励你,
- 从小做起,然后迭代。你不必总是去追求一个“惊人”的想法。最好创建一些有多个微小失败循环的东西。
- 思考盒子的外面和里面。
你并不总是需要新的解决方案。通常,创新的解决方案是用新的方式做同样的事情。 - 投身于你舒适区之外的项目。
接受挑战,以适应不舒服。
最后,如果您正在寻找与数据可视化相关的灵感,这里有一些项目可以帮助您开始:
[## 少年派的艺术
探索隐藏在π中的艺术
www.visualcinnamon.com](https://www.visualcinnamon.com/portfolio/the-art-in-pi) [## 文学星座
文学星座是一系列海报,旨在类似星座地图,但不是基于…
www.c82.net](https://www.c82.net/blog/?id=73)
看看我的另一个项目,在那里我创建了手绘可视化来表示数据。
[## 数据在艺术里!
利用颜色、形状和涂鸦来理解软数据和小数据
towardsdatascience.com](/the-data-is-in-the-art-b97cf2ceda7c)
对贝叶斯规则的不同看法
原文:https://towardsdatascience.com/a-different-take-on-bayes-rule-e303c1d7d5f6?source=collection_archive---------23-----------------------
从机器学*和增量学*的角度,对术语“后验”、“先验”和“可能性”有更多的直觉。
Bayes Rule — θ refers to the model, D refers to a data point
本文的目标
大多数阅读本文的人都看过贝叶斯规则中每个概率分布的演示。大多数阅读这篇文章的人已经正式了解了术语“后验”、“先验”和“可能性”。如果没有,那更好!
我认为将贝叶斯规则视为增量学*规则对许多人来说是一个新的视角。此外,我相信这个观点会给更好的直觉,为什么我们使用术语“后”和“前”。最后,我认为这个观点有助于解释为什么我不认为贝叶斯统计比频率主义统计导致任何更多的归纳偏差。
注释
在深入研究贝叶斯规则本身之前,首先重要的是就符号达成一致。 θ 指的是我们的模型。一个模型可以通过一个类和一组参数来识别。例如,我们的模型类可以是高斯分布。这个模型的参数是均值和方差。
另一个示例模型类是具有一个隐藏层和 256 个节点的神经网络。该模型的参数是与网络的每个节点相关联的权重。
D 指一组数据点。在上面的例子中 D 是一组标量值。
Theta is the set of parameters mu and sigma-squared referring to the mean and variance respectively.
术语
老实说,我讨厌行话。我知道当双方共享一个共同的词汇时,它允许更快和更精确的交流,但我发现过度依赖行话会导致忘记信息密集术语的含义。也就是说,让我们进入一些行话!
Posterior distribution
在后面的
给定数据的模型的概率。在贝叶斯世界中,我们不是在处理一个单一的实例化模型。我们处理模型上的概率分布。这个分布表示“根据我观察到的数据,我认为你的模型为 θ 的概率是 22%。”我们可以用许多不同的模型来查询这个分布,以询问每个模型给出观测数据的可能性有多大,或者我们可以询问这个分布最可能的模型是什么。
Prior distribution
在先的;在前的
一个模型的概率。贝叶斯概率最有争议的部分之一是包含先验分布。用机器学*的术语来说,你可以认为这是正则化的一种形式。先验允许你指定一个特定模型的概率,不管你观察的是什么数据。这让你可以说“我知道男性的平均身高不超过 8 英尺,给做出这种说法的模型分配零概率。”
Likelihood
可能性
如果这些数据是使用我的模型生成的,那么观察到这些数据的概率有多大?这种可能性让我们可以问,如果世界按照我们的模型运行,会发生什么。我们会看到这些特殊的样本吗?
想象一下,我们使用一个模型,这个模型说一个随机的人有 99%的可能性非常富有。然后,我从世界各地随机抽取一组人作为样本,问“根据我的世界模型,我画出这组人的概率是多少?”因为大多数人并不非常富有,在集合中,远少于 99%的人会非常富有。这种模式的可能性相当低。
增量学*
将贝叶斯规则视为增量学*规则的第一步是识别后验和先验之间的关系。通过天真地分析单词——忽略等式本身——人们可能会猜测先有先验,后有后验。让我们在等式中加入时间指数来使这一点更加清楚。
回忆条件概率的一个性质也很有用。当随机事件以非随机事件为条件时,随机事件的概率不变。
如果 A 是随机事件而 B 不是,那么当以 B 为条件时 A 发生的概率不变。
利用这个特性,我们可以对贝叶斯规则方程进行最后的修改。
The only thing that changed was the prior probability distribution.
我们的先验分布现在是以我们以前观察到的数据为条件的。这是对先验的合法更改,因为过去的数据不再是随机的。
为了理解为什么过去的数据不是随机的,想象你在时间步 t-1 上。你刚刚收到一个数据样本,你想知道你收到那个特定数据点的可能性有多大。这是因为你的数据是随机抽取的。你相应地改变你的模型,向前迈出一步。在时间步长 t 上,您在 t-1 上使用的样本会突然改变吗?没有。那个样本永远定格在历史里;它不再是一个随机变量。
Top — The posterior written as a function of the prior. Bottom — Stochastic Gradient Descent.
这样写贝叶斯规则,可以看出后验和先验的关系。在接收到一个数据点后,我们可以从模型的先前估计转向新的估计,即后验估计。我写的随机梯度下降更新规则是为了比较。在从之前的权重中减去一步后,我们计算出新的权重估计值 W 。
起点
贝叶斯统计的一个很有争议的点是先验分布的选择。当将贝叶斯规则视为增量学*规则时,我们可以很容易地看到,这并不是贝叶斯统计所独有的。任何增量学*规则必须选择一个起点,一组初始的权重或参数。贝叶斯法则也不例外。
我指出这一点只是因为在线学*社区似乎对贝叶斯统计有特殊的看法。有许多反对贝叶斯统计的论点(也有许多赞成!),但我认为归纳偏差论点并不是一个有效的例子。
结论
采用贝叶斯规则的增量学*观点可以理解与之相关的术语的选择。理解这个观点也打开了更深入理解贝叶斯推断和贝叶斯优化的大门。
在 Spark 上部署 Python 模型的不同方式
原文:https://towardsdatascience.com/a-different-way-to-deploy-a-python-model-over-spark-2da4d625f73e?source=collection_archive---------15-----------------------
将预测方法与 Python 类的其余部分分开,然后在 Scala 中实现
Instead of using the whole thing, just take the pieces you need.
前阵子,我写了一篇关于如何在 Spark 上部署 Python 模型的帖子。方法大致如下:
- 根据全部数据的样本在 Python 中训练模型。
- 将测试数据收集到任意大小的组中——大约 500,000 条记录对我来说似乎很好。
- 广播训练好的模型,然后使用用户定义的函数对每组记录整体调用模型的
predict
方法,而不是对每条单独的记录(如果对未分组的数据帧调用 UDF,Spark 就会这样做)。
该方法利用了支持 scikit-learn 的支持 numpy 的优化,并减少了您必须经历序列化和反序列化模型对象的昂贵过程的次数。
我最*采用了一种不同的方式在 Spark 上部署 Python 模型,不需要对大量数据进行分组和分解。我仍然在 Python 中对全部数据的样本进行模型训练,但是我将调用 predict 方法所需的一切存储在一个 JSON 文件中,然后该文件可以被调用到一个可以实现 predict 方法的 Scala 函数中。
例如,以 sci kit-learnRandomForestRegressor为例。predict
方法是一堆个体决策树的predict
方法结果的平均值,但是方法本身的实现根本不使用树结构。它将所有内容编码成一系列列表。
以下代码创建了一个纯 Python 函数,该函数将精确再现经过训练的 RandomForestRegressor 的预测:
看一下tree_template
字符串。我们从五个列表开始——每个列表都有树中的节点。features
列表中的唯一值与模型训练所依据的特征一样多。我们从列表的第一个值开始—索引 0。如果索引 0 处的值是,比如说,3,那么我们取出模型被训练所基于的第三个特征的值。然后我们从thresholds
列表中取出索引零值。如果所选特征的值小于或等于相应阈值的值,那么我们查看children_left
列表的零索引值。否则,我们查看children_right
列表的零索引值。不管怎样,这个值就是我们的新索引,然后我们重新开始这个过程。我们一直这样做,直到子列表中的值成为“您已经到达了树的末尾”的占位符。在 scikit-learn 中,这个占位符的默认值是-2。此时,无论您当前在哪个索引上,您都可以从values
列表中查找该索引的值。那是你的预测。
所以,是的,这是一个很大的数据量——拥有几十个特征的决策树回归器通常有大约 100,000 个节点。但是导航树以获得预测的逻辑非常简单。因此,您所要做的就是创建一个包含每棵树的列表的函数,以及从一个索引跳到另一个索引的逻辑。然后取一组特征,从每棵树上得到预测值,并取平均值。那是你的随机森林。
很容易将所有这些信息转储到 JSON。下面的函数就是这样做的。它只需要一个经过训练的 RandomForestRegressor 对象、按照训练中使用的顺序排列的特性列表,以及一个将 JSON 文件转储到的文件路径。
单棵树的输出如下所示:
下一段代码来自我的同事 Sam Hendley,他已经忘记了比我所知道的更多的 Scala 知识。它从 JSON 文件中读入树信息,实现每棵树的预测逻辑,然后对整个森林进行平均。
在 Scala 中实现预测避免了对函数的 Python 表示进行序列化和反序列化的过程——一切都可以直接在 JVM 上完成。随机森林是这里最复杂的用例之一。在任何产生系数的模型中,将预测函数转换成 JSON 和 Scala 甚至更容易。
神圣的机会
原文:https://towardsdatascience.com/a-divine-chance-eb36d865027d?source=collection_archive---------48-----------------------
我在数据领域的第一份工作的期望与现实
Photo taken on a recent hike to Mission Peak
自从我开始攻读商业分析硕士学位以来,我唯一的职业目标就是获得一份工作,在这份工作中,我可以应用我的技能,做出成绩,并拓宽我在数据科学方面的知识。5 月份从硕士项目毕业后,我很快参加了旧金山一个非常有名的数据科学训练营。毕业后的第二天就开始找工作了。
在我继续说下去之前,这篇文章不是关于我的求职,那将是一篇完全不同的文章,但这更多的是关于我在我的专业职位的前两个月观察到的。经过一场涉及无数编码挑战、数据集、无数自动拒绝邮件(有些甚至在夜里 2:00)等的严格求职,上帝保佑我在旧金山湾区一家知名公司的人工智能部门找到了一个数据工程师的职位。刚从一个硕士项目毕业时,我在人工智能团队中期待的是现成的数据集(csv ),它们大声疾呼“请在我身上应用一个模型,并获得最佳预测或分类分数!”。基本上是一场卡格尔比赛。事实绝对不是这样,事后看来,我离真相已经不远了。
人工智能团队是一个新团队,作为数据工程师的第一项任务是促进数据。通俗地说,“没有现成的数据,你的工作是收集所有可用的非结构化信息,给出结构并组织起来”。我花了相当长时间学*的有价值的机器学* scikit-learn 模型突然退居二线。
如今,在一位杰出导师及其 rockstars 团队的帮助和指导下,我已经完成了两个月的工作,创建了自动组织和构建数据的脚本,促进了数据流和连续数据流入数据湖,还创建了几个有用的仪表板可视化工具来分析实时输入的原始数据。最初的几个月教会了我比硕士课程和训练营加起来还要多的东西。
我知道我在这里仅仅触及了表面,但我写这篇文章的原因是为了强调我们所有有志于成为数据专业人士的人都需要灵活地学*和做更多的事情。这正是这份工作教给我的东西,也绝对是我职业发展的绝佳机会。
一种狗检测器和品种分类器
原文:https://towardsdatascience.com/a-dog-detector-and-breed-classifier-4feb99e1f852?source=collection_archive---------6-----------------------
在像物理学这样的领域,事情变得越来越难,以至于除非用高度简化的术语,否则很难理解前沿发生了什么。然而,在计算机科学中,尤其是人工智能,世界各地的人们经过 70 多年慢慢积累起来的知识仍然是非常直观的。事实上,由于高级编程语言、框架和重视以易于访问的格式共享知识的社区,进入这个领域变得越来越容易了!
在这篇博文中,我们将做一些十年前不可能的事情,但像我这样的学生现在可以用几行 Python 代码完成;建立一个系统,可以识别照片中是人还是狗,并告诉我们它是什么品种(或者最像!).
你可以在我的 Github 找到代码。
探测人和狗
有几种方法可以解决图像分类问题。在这篇博文中,我们将使用卷积神经网络来确定狗的品种。在此之前,我们将使用 Viola-Jones haar 级联分类器方法来检测照片中是否包含人脸。
CNN 现在得到了最多的关注,但是你以前肯定见过 Viola-Jones 方法。每当你打开相机,它就会在人脸周围画出方框。诺丁汉大学的迈克·庞德做了一个很棒的视频讲解,可以在这里观看。简而言之,我们找出哪些过滤器最擅长区分人脸和非人脸。最佳滤波器应用于图像的每个区域。如果一个区域通过,它将在下一个过滤器上被测试。对大约 6000 个其他过滤器重复这一过程,如果一个区域通过了所有这些过滤器,我们就断定它包含一张脸。
报纸上还有很多其他的东西。例如,作者开发了一种简单而聪明的方法来有效地计算图像中某个区域的像素值。我们所需要做的就是从一个名为 OpenCV 的库中下载这些预先训练好的滤镜,并通过它们运行我们的照片。
import cv2def face_detector(img_path):
img = cv2.imread(img_path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray)
return len(faces) > 0
就这样,它计算出图像中有多少张人脸!
不幸的是,OpenCV 的好人们没有为我们建立一些好的 haar 过滤器。相反,我们将使用 ImageNet,这是一个由 1400 万张图片组成的数据集,分为 2 万个类别。在过去十年中,它一直是领先的计算机视觉基准之一。我们将使用一个较小版本的 ImageNet,包含 1000 个类别,其中类别 151–268 是狗的品种。
我们可以使用一个名为 Resnet 的预训练 CNN,我们可以从 Keras 的网站上下载(稍后会有更多关于 Keras 的内容)。
from keras.applications.resnet50 import ResNet50ResNet50_model_ = ResNet50(weights='imagenet')
我们需要做一些预处理,以便模型可以对我们的图像做出预测:
from keras.preprocessing import image
from tqdm import tqdmdef path_to_tensor(img_path):
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
return np.expand_dims(x, axis=0)def paths_to_tensor(img_paths):
list_of_tensors = [path_to_tensor(img_path) for img_path in tqdm(img_paths)]
return np.vstack(list_of_tensors)
现在,我们可以看到模型做出的预测是否符合某个犬种类别:
from keras.applications.resnet50 import preprocess_input, decode_predictionsdef ResNet50_predict_labels(img_path):
img = preprocess_input(path_to_tensor(img_path))
return np.argmax(ResNet50_model_.predict(img))def dog_detector(img_path):
prediction = ResNet50_predict_labels(img_path)
return ((prediction <= 268) & (prediction >= 151))
最后,当我在 100 张样本图像上测试检测器时,人脸和狗的检测器没有任何假阴性。狗探测器也没有任何误报!
Our human face detector results
Our dog detector results
决定狗的品种
所以我们可以说在这幅画中有某种狗或人。但我本可以做到的。我能说出 117 个不同品种的区别吗?可能不能。让我们看看是否可以用机器学*来区分。
是时候破解 Keras 库了。像 Tensorflow、Pytorch、Theano 或 CNTK 这样的框架为我们执行机器学*操作。Keras 是一个建立在这些之上的库,所以我们可以用一种更简洁易读的方式编写代码。
以下是我们在 Keras 对 CNN 的定义:
model = Sequential()model.add(Conv2D(32, (3, 3), input_shape = (224, 224, 3), use_bias=False))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Dropout(0.2))model.add(Conv2D(64, (2,2), use_bias=False))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size = (2,2)))
model.add(Dropout(0.2))model.add(Conv2D(128, (2,2), use_bias=False))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Dropout(0.2))model.add(Flatten())model.add(Dense(512, use_bias=False))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.2))model.add(Dense(256, use_bias=False))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(Dropout(0.2))model.add(Dense(len(dog_names), activation='softmax'))model.summary()
这是怎么回事?我们有 3 个卷积层,后面是 3 个全连接层。这最后一层有一个 softmax 激活函数,这意味着我们的输出将是一个有 1000 个值的概率分布,我们使用的 ImageNet-1000 数据库中的每个可能结果都有一个值。
接下来我们将定义优化器和损失函数。这一行有许多术语,所以我将试着解释一下。
- SGD 或随机梯度下降是最好的比喻,滚下一座山。如果你找到了下去的路,继续走。如果没有,请尝试不同的方向。请记住,在多维数学世界中,不仅仅只有 3 个维度可供选择。当你在某个方向达到局部最小值时,你就会知道,因为你所在的曲线的梯度会变小。这些都是在引擎盖下为我们处理的。
- lr 是我们的学*率。给定一条新信息,我们应该在多大程度上改变模型?小比率意味着缓慢的训练,但大比率意味着我们可能会跳过最佳解决方案到山谷的另一边。最佳解决方案是使用…
- 衰减意味着我们开始时学*率很高,当我们接*山/谷底部时,学*率随着每个时期而降低。
- clipnorm 用于裁剪渐变,这样它们就不会变得过大或过浅,这会使渐变下降变得困难。 clipnorm 如果发生这种情况,剪辑值,但也缩放梯度,所以我们没有剪辑一些而不是其他的
- 涅斯捷罗夫动量是我们向前看了一步后计算的梯度。这有助于我们更快地训练。
- 分类 _ 交叉熵是损失函数。这意味着我们正在判断模型的性能,以及我们需要在多大程度上调整它,这取决于我们在检查结果后收到了多少新信息。如果我确定我见过一只金毛寻回犬,并且我是对的,那么就没有多少新的信息被创造出来。如果我不确定,那么已经创造了一些。如果我确定它不是金毛寻回犬,但它确实是,那么大量的信息就产生了。
- 准确性是我们将监控的指标。它就像罐头上说的那样。它为多类分类问题计算所有预测的平均准确率。换句话说,有多少狗被正确分类。
sgd = SGD(lr=0.01, clipnorm=1, decay=1e-6,
momentum = 0.9, nesterov=True)model.compile(optimizer=sgd, loss='categorical_crossentropy',
metrics=['accuracy'])
然后我们就好训练了!
checkpointer = ModelCheckpoint(
filepath='saved_models/weights.best.from_scratch.hdf5',
verbose=1, save_best_only=True)model.fit(train_tensors, train_targets,
validation_data=(valid_tensors, valid_targets), epochs=5,
batch_size=20, callbacks=[checkpointer], verbose=1)
如果我们运行 6 个时期,会发生以下情况:
The training and validation losses as our model trained
培训损失随着我们的培训而改善,但验证损失看起来将趋于平缓。这意味着如果我们长时间训练它,我们的模型将开始过度拟合。
在测试集上,该模型正确预测了它看到的 3.7%的狗的品种。这比随机猜测要好 4 倍,但仍有相当大的改进空间。
迁移学*
进入迁移学*。我们可以采取一个预训练的模型,就像我们对探测器所做的那样,并在它的末端添加我们自己的层来为我们做出预测。我们将使用的模型是 Resnet50,已经由微软的研究人员在更大的机器上进行了训练,时间超过了我所能获得的时间。
我们可以下载权重,将它们存储在本地,然后像这样解包特性:
bottleneck_features = np.load(
'bottleneck_features/DogResnet50Data.npz'
)
train_Resnet50 = bottleneck_features['train']
valid_Resnet50 = bottleneck_features['valid']
test_Resnet50 = bottleneck_features['test']
使用 Keras 很容易获得 Resnet50 并在它的末尾添加我们自己的层。同样,我们希望我们的输出是每个品种的概率分布
Resnet50_model = Sequential()
Resnet50_model.add(
GlobalAveragePooling2D(input_shape=train_Resnet50.shape[1:])
)
Resnet50_model.add(Dense(133, activation='softmax'))
之后就和以前一样了
Resnet50_model.compile(
loss='categorical_crossentropy',
optimizer=sgd,
metrics=['accuracy']
)checkpointer = ModelCheckpoint(
filepath='saved_models/weights.best.Resnet50.hdf5',
verbose=1,
save_best_only=True
)resnet50_hist = Resnet50_model.fit(
train_Resnet50,
train_targets,
validation_data=(valid_Resnet50, valid_targets),
epochs=20,
batch_size=56,
callbacks=[checkpointer],
verbose=1
)
这种模式有多好?在测试集上,它正确预测了 84%的品种!这比我和我的疯狗家庭得到的要多得多。
尝试一下
将我们的人类和狗检测器与品种预测器结合起来,让我们在一些照片上尝试一下。
Correct! Not even the Barbour jacket confuses it
Correct! Ironically, my it’s my dog who is overfitting in this photo (those ducks are plastic!)
Wrong, this is actually a Border Collie.
But he does look like an Australian Shepherd
Silky Terrier, who knew?
It’s got a bit confused by Pongo…
然而,如果我们仔细观察模型的预测,我们可以看到达尔马提是第二名,所以不算太坏。
bottleneck_feature = extract_Resnet50(path_to_tensor('images/pongo.png'))
predicted_vector = Resnet50_model.predict(bottleneck_feature)top_predictions = np.argpartition(predicted_vector.flatten(), -4)[-4:]
for i in top_predictions:
print(dog_names[i])
Well you can’t win them all!
潜在的改进
我们在这里可以做更多的事情。世界上最好的模型在有更多可能类别的 ImageNet 版本上获得了比我更好的测试精度。我们可以通过租用多个 GPU、获取更多带标签的图像等来获得一些改进,但这基本上归结为花钱,在概念上不是很有趣。
我们可以改进这个模型的一个方法是使用数据扩充。例如,通过翻转、移动、旋转、变暗、变亮、添加噪声和许多其他可能的操作,我们可以人为地增加模型可以暴露的图像的数量。我在这个项目中试验了数据扩充,结果令人失望。有可能通过一些参数调整和更长时间的训练,我会看到一些改善。
我们可以改变 CNN 本身。有可能更多的层,更多的特征,不同的损失函数,学*率和其他各种变化会使它表现得更好。深度学*的很大一部分是对模型进行修改,只有在它确实改善了事情的情况下才进行学*。如果我有更多的 GPU 时间,我可能会尝试使用网格搜索在一夜之间系统地实验不同的超参数。
结论
在本帖中,我们有:
- 从 ImageNet 加载并预处理图像。
- 加载了一些预训练的 haar 级联分类器,以便使用 Viola Jones 方法检测人脸。
- 加载了一个预先训练好的 CNN 来探测狗。
- 从头开始编写和训练了一个 CNN 来对狗的品种进行分类。这在测试集上成功了 3.7%,这听起来很低,但比机会好 4 倍。
- 使用迁移学*从根本上改善了 CNN 的性能,使其在测试集上的准确率达到 84%。
- 用我自己的几张照片测试了这个模型。
- 讨论了未来改进模型的方法。
也许你在这篇文章中学到了一些东西。我从写作中学到了很多。如果你发现了一个错误,或者认为有些东西可以更好地措辞,让我知道,我会更新它!
Happy Coding!
ML 和敏捷注定的联姻
原文:https://towardsdatascience.com/a-doomed-marriage-of-ml-and-agile-b91b95b37e35?source=collection_archive---------28-----------------------
如何不对 ML 项目应用敏捷
Photo by photo-nic.co.uk nic on Unsplash
TLDR :在一个 ML 项目中过分使用敏捷和塞巴斯蒂安的话的三个错误。我认为在 ML 项目中什么是敏捷的,什么是不敏捷的。
免责声明 :这篇文章没有得到我工作的任何公司或我提到的任何工具或服务的支持或赞助。我交替使用人工智能、数据科学和 ML 这三个术语。
喜欢读什么? 跟我上 中LinkedIn,或者Twitter。还有,作为一名数据科学家,要不要学*商业思维和沟通技巧?查看我的《* 用机器学*影响 》指南。*
一份供词
现在是 2016 年 11 月 3 日晚上 11 点 35 分。我坐在多伦多市中心海湾街的一间会议室里。我盯着街道那头空荡荡的办公室的地板。我房间的灯暗了下来。我的手机亮了。我收到了三份通知。
//10 小时后的执行演示。
//打电话给杰斯。在 12 小时内发送最终的婚礼后勤细节。
//去机场。18 小时后飞往香港参加我们的婚礼。
“Fck… Fck。Fck!”*
我敲了敲键盘;笔记本电脑已打开;弹出了一个号码。还是不行。我该如何解释预期转化率下降 35%的原因?
我拿起电话打给西蒙,他是我的同事,会在演示中支持我:“让我们计划一下损失控制。”
“喂,你在想我们的婚礼吗?”我可爱的妻子杰斯问道。
我突然回到现在。现在是 2019 年 11 月 5 日。我坦白。不,我不是在想我们的婚礼,而是结婚纪念日快乐!我永远不会忘记这个日子。
该死的,塞巴斯蒂安
我喜欢关于 ML 的成功故事。但是,让我们面对现实:大多数 ML 项目都失败了。很多项目失败是因为我们试图用 ML 解决错误的问题;有些失败是因为我们没有足够重视最后一英里问题和工程和组织问题。有几个失败了,因为我们觉得数据科学很无聊并且不再关心。剩下的和我告白里的那个一样,都是因为项目管理不善而失败的。
如果我要从这次经历中吸取一个教训,那就是:不要过度敏捷。这一切都是从巴斯蒂安·特龙的一张图开始的。
这是我最喜欢的 ML 工作流程图,部分原因是 Sebastian 拥有最好的手写效果,是用电脑写字板写的(真的)。但是,这里有一个重要的细微差别。
Sebastian Thrun, Udacity — Introduction to Data Science, the Best Online Course!
我的无知,细微差别,以及发生了什么
首先,我必须承认我自己的无知。我是一个天真的敏捷方法论的拥护者,因为瀑布是如此的老派和无趣。像我一样,你们中的许多人可能听说过敏捷:迭代允许我们快速学*、测试和失败。(此外,我们通过节省撰写技术规范的论文来减少砍伐树木,这些技术规范没有人阅读,而且在早期项目中可能是错误的)。**
细微差别。不应有箭头指向问题和评估(绿色和红色文本)阶段。敏捷的迭代原则不应该应用*到我们定义核心问题和评估度量的阶段。*
核心问题必须尽早清楚地阐明。然后,必须立即想出子问题(参见假设驱动的问题解决方法)。他们帮助 1)识别好的特性想法并推动探索性分析,2)计划时间表,以及 3)决定每个敏捷 Sprint 应该关注什么。必须根据核心问题仔细选择评估指标。我在我的指南中详细讨论了这个过程。
那么,发生了什么?未能认识到自己的无知和 ML 工作流程中的细微差别导致了 3 个致命错误。
错误#1: 我们中途更改了目标变量,因为对核心业务问题的定义有误。这导致了数据泄露破坏了我们的模型性能。我们不得不对大约 35%的代码库进行重新编码,并花费大约 2 周的时间重新尝试不同的数据转换和模型架构。那是一场噩梦。
错误#2: 我们优先考虑低影响特征,因为我们的子问题没有经过深思熟虑。嗯,其中一些功能是创新的,但回想起来并没有用。这浪费了宝贵的开发时间,而这在有时间限制的咨询环境中是极其重要的。
错误#3 : 我们改变了评估指标。我们必须重新设计我们的模型架构,并重新运行超参数搜索。这需要新的测试用例。我们不得不手动运行许多回归测试。
所有这些错误都反映在客户体验、团队士气和时间表上。最终,他们导致了我婚礼前的一个非常紧张的夜晚。
变得更聪明
好吧。说句公道话。我确实断章取义了塞巴斯蒂安的建议。他是曼梯·里最好的老师(对不起,吴恩达)。
Sebastian 的工作流程主要是为以实验为中心的 ML 项目而设计的(例如 BI 或洞察发现)。对于像我们这样的以工程为重点的 ML 项目(例如,全栈 ML 系统),工作流程应该基于软件工程和产品管理的最佳实践进行优化。
以下是我对什么是敏捷或者不是敏捷的看法。这对于有时间限制的咨询或内部原型项目尤为重要。没有十全十美的方法,所以不要走得太远,要聪明地运用。
敏捷能力:
- 数据特征的发展
- 模型架构的开发
- 面向用户的用户界面的设计和开发(例如仪表板、网络用户界面等)。)
- 设计开发 CICD 测试用例
不灵活:
- 如果最终消费者是人,用户体验;如果最终消费者是系统,集成模式和协议
- 核心、子问题和主要功能想法列表的定义
- 目标变量的定义(不惜一切代价避免改变。但是如果业务需求发生变化,锁定 CICD 管道非常有助于捕捉数据或软件错误。)
- 评估指标
- 管道:数据到模型和 CICD 与 DVC
- 基础设施:集成模式、服务层、关键数据库和硬件平台
到目前为止效果还不错。一如既往地欢迎任何反馈。
根据对这篇文章的反应,我可能会跟进如何使用瀑布和敏捷来计划一个 ML 项目的工作计划图和需求示例。
请在 Medium 、 LinkedIn 或 Twitter 上关注我。如果你喜欢这篇文章,请分享,这样其他人就可以加入对话。
正如你所看到的,能够清晰地表达核心问题并得出分析、特征想法和模型选择对项目的成功至关重要。我整合了我在 影响力与 ML 迷你课程中提供给学生和从业者的研讨会材料。希望你觉得有用。
喜欢你读的书吗?你可能也会喜欢我这些受欢迎的文章:
* [## 最有用的 ML 工具 2020
每个懒惰的全栈数据科学家都应该使用的 5 套工具
towardsdatascience.com](/the-most-useful-ml-tools-2020-e41b54061c58) [## 被遗忘的算法
用 Streamlit 探索蒙特卡罗模拟
towardsdatascience.com](/how-to-design-monte-carlo-simulation-138e9214910a) [## 越狱
我们应该如何设计推荐系统
towardsdatascience.com](/how-to-design-search-engines-24e9e2e7b7d0) [## 12 小时 ML 挑战
如何使用 Streamlit 和 DevOps 工具构建和部署 ML 应用程序
towardsdatascience.com](/build-full-stack-ml-12-hours-50c310fedd51) [## 数据科学很无聊
我如何应对部署机器学*的无聊日子
towardsdatascience.com](/data-science-is-boring-1d43473e353e) [## 抵御另一个人工智能冬天的最后一道防线
数字,五个战术解决方案,和一个快速调查
towardsdatascience.com](/the-last-defense-against-another-ai-winter-c589b48c561) [## 人工智能的最后一英里问题
许多数据科学家没有充分考虑的一件事是
towardsdatascience.com](/fixing-the-last-mile-problems-of-deploying-ai-systems-in-the-real-world-4f1aab0ea10) [## 我们创造了一个懒惰的人工智能
如何为现实世界设计和实现强化学*
towardsdatascience.com](/we-created-a-lazy-ai-5cea59a2a749)*
Google Coral 开发板上的一种 FaceNet 风格的面部识别方法
原文:https://towardsdatascience.com/a-facenet-style-approach-to-facial-recognition-dc0944efe8d1?source=collection_archive---------6-----------------------
介绍
在这篇博文中,我们介绍了面部识别的主题,并描述了我们对之前博文中介绍的问题的解决方法。
当决定实现面部识别时,首先想到的是 FaceNet。FaceNet 是一个人脸识别管道,它学*从人脸到多维空间中一个位置的映射,其中点之间的距离直接对应于人脸相似性的度量。
以下摘自 FaceNet 的论文给出了其主要概念的概述:
“[……]我们致力于从图像 x 到特征空间的嵌入 f(x),使得独立于成像条件,相同身份的所有人脸之间的平方距离很小,而来自不同身份的一对人脸图像之间的平方距离很大。
这允许一个身份的面孔生活在一个流形上,同时仍然加强了与其他身份的距离和区分度。”
FaceNet 的 TensorFlow 实现目前在 GitHub 上可用。
基于之前在 FaceNet 上的工作,我们的解决方案分为三个阶段:
1.预处理 —一种用于获取一组图像并将其全部转换为统一格式的方法——在我们的例子中,是一个仅包含人脸的正方形图像。当使用边缘 TPU 时,由于我们的计算资源有限,因此统一数据集有助于减少训练时的方差。
2。嵌入 —这是一个过程,是 FaceNet 工作方式的基础,它在多维空间中学*人脸的表示,其中距离对应于人脸相似性的度量。
3。分类 —使用嵌入过程给出的信息来分离不同人脸的最后一步。
我们还想实现的另一个功能是重量印记。权重印记是一种将训练过程分为两步的方法,第一步在大型数据集上训练整个模型,第二步仅在新数据上训练最后一层,同时利用前一步中获得的知识。重量印记允许在设备上进行学*,只需要很少的样本图像。它可以学*从未见过的人脸的内在属性,并将这些属性与它从已知数据集学*到的属性进行比较。
我们解决方案的架构
鉴于我们前面描述的三个阶段,我们为我们的具体实现构建了一个架构,并考虑了在 Edge TPU 上实现它的实用性。
该架构将使用以下方法:
1.使用对齐脚本进行预处理;
2。训练深度 Mobilenet 模型以识别人脸,然后在表示嵌入的层将其分割;
3。附加单层分类模型并使用权重印记来训练它。
对准
训练和推理过程的第一步都是对齐图像。这将总是发生在除了 Edge TPU 之外的机器上,因为 Edge TPU 环境不支持所需的库。我们目前正在运行来自 Facenet GitHub 库的 align_dataset_mtcnn.py 脚本。
通过执行脚本,我们可以指定面部缩略图的大小,并对齐它们。
这一步对于确保数据集中的一致性非常重要。如果没有这种一致性,模型将不得不学*对同一张脸的图像之间存在不必要差异的数据集进行分类。一个强大到足以做到这一点的模型对于第一次尝试在 TPU 边缘实现某些东西来说可能太复杂了。
在我们的例子中,为了处理图像,我们必须在服务器上运行脚本,因为本地机器需要大量的时间。
执行的命令是:
for N in {1..20}; do \
python3 src/align/align_dataset_mtcnn.py \
—image_size 182 \
—margin 44 \
—random_order \
—gpu_memory_fraction 0.05 \
& done
在一台 20 核服务器上,我们花了大约 30 分钟来对齐包含数十万张图像的 CASIA Webface 数据集。相比之下,我们预计在 MacBook Pro 上运行类似的脚本至少需要 2.5 小时。
把...嵌入
与对齐相反,嵌入和分类旨在在边缘 TPU 上运行。
嵌入模型是卷积层的串联,它寻找特征并将它们映射到多维空间。为了获得我们的嵌入层,我们从 MobileNet 模型的预训练版本开始——我将在下一篇文章中详细介绍——并重新训练它。值得注意的是,我们使用了整个模型,这意味着它既创建了嵌入,也对它们进行了分类。然而,该模型随后被分割,因此我们可以使用其输出(嵌入)作为单一层分类模型的输入。
为了进行训练,我们使用了mobilenet _ v1 _ L2 norm _ train . py脚本,该脚本将 TFRecord 格式的数据集和检查点作为输入,这些都是预训练模型提供的。
然后,我们必须保存模型的一个 GraphDef *并冻结图形。我们通过训练时创建的新检查点实现了这一点。重要的是,与我们之前描述的面网分类器相比,我们还去除了 L2 范数算子,因为它不受边缘 TPU 的支持。
为了冻结图表,我们使用了 Tensorflow 工具 freeze_graph ,这是一个简单的程序,只需要训练后的检查点。通过使用转换图工具,将冻结图作为输入,该模型去除了 L2 范数算子。
*更多关于 Tensorflow 中图形对象的信息可以在这里找到。
分类
对于分类,我们必须将模型分成两部分——嵌入提取器和分类层——然后将它们重新连接起来。
这种分离的原因是,如前所述,我们计划使用嵌入作为单层分类模型的输入。这一步确保了我们能够使用权重印记,这意味着该模型将能够在有限的数据集(大约 5 到 10 张图像)上训练(在 TPU 边缘),以识别一张从未见过的脸。
为了实现这一点,我们首先使用 tflite_convert 将整个冻结的图形转换为一个 TFLite 文件,它接受 GraphDef 文件并输出一个 tflite 文件。
由于 tflite_convert 不支持,我们随后使用 toco 创建了基础图作为其自己的文件。tflite 文件作为输入。
由此,我们有了与分类层完全分离的嵌入提取器。然后,我们使用 toco 创建头部图,然后使用 Edge TPU 编译器编译基础图。
最后一步是使用谷歌的 join_tflite_models 工具重新连接编译好的基础图和头部图。
摘要
我们从分析 FaceNet 论文开始,提出了面部识别系统的三步计划:预处理、嵌入和分类。
为了进行预处理,我们使用了服务器上的 FaceNet git 存储库中的一个脚本。然后,我们在我们选择的数据集上重新训练了一个预训练模型,并冻结了它的图形。最后,我们将模型分为一个基础(嵌入)和一个头(分类)以允许我们稍后进行权重印记。然后,我们应该有一个在我们选择的数据集上训练的工作编译模型。
MixMatch 的 fastai/Pytorch 实现
原文:https://towardsdatascience.com/a-fastai-pytorch-implementation-of-mixmatch-314bb30d0f99?source=collection_archive---------20-----------------------
在这篇文章中,我将讨论和实现“MixMatch:半监督学*的整体方法;由贝特洛,卡利尼,古德菲勒,奥立佛,帕伯诺和拉斐尔[1]。MixMatch 于 2019 年 5 月发布,是一种半监督学*算法,其性能明显优于以前的方法。这篇博客来自加州州立大学东湾分校 Ehsan Kamalinejad 博士的机器学*研究小组的讨论。
MixMatch 的改进有多大?当在具有 250 个标记图像的 CIFAR10 上训练时,MixMatch 在错误率(11.08%对 36.03%;作为比较,在所有 50k 个图像上完全监督的情况具有 4.13%的误差率)。[1]这些远远不是增量结果,该技术显示出显著改善半监督学*状态的潜力。
半监督学*在很大程度上是一场反对过度适应的战斗;当标记集很小时,不需要非常大的神经网络来记忆整个训练集。几乎所有半监督方法背后的一般思想是利用未标记数据作为有标记数据训练的正则化器。对于各种半监督学*方法的概述,请参见 Sebastian Ruder 的这篇博客文章。不同的技术采用不同形式的正则化,MixMatch 论文将它们分为三组:熵最小化、一致性正则化和一般正则化。由于所有三种形式的正则化都被证明是有效的,MixMatch 算法包含了每种形式的特征。
MixMatch 是对*年来出现的几种技术的组合和改进,包括:刻薄老师[2]、虚拟对抗训练[3]和 Mixup [4]。在高层次上,MixMatch 的思想是使用来自模型的预测来标记未标记的数据,然后以多种形式应用大量正则化。第一种是执行几次数据扩充,并对标签预测取平均值。这些预测然后被“锐化”以减少它们的熵。最后,在标记和未标记的集合上执行混合。
Diagram of MixMatch — Image taken from original paper [1]
我这篇文章的目标是那些熟悉 Pytorch 的人,但不一定是 fastai。这篇文章的 Jupyter 笔记本版本包含了重现所有结果所需的全部代码,参见这个资源库。
法斯泰
在进入本文之前,我将简要介绍一下 fastai 。Fastai 是一个基于 Pytorch 的库,它使得编写机器学*应用程序变得更加容易和简单。Fast.ai 还提供了一个非常棒的在线课程,涵盖了 fastai 和深度学*。与纯 Pytorch 相比,fastai 大大减少了生成最先进的神经网络所需的样板代码的数量。这里我们将使用 fastai 的数据管道和训练循环特性。
Imports
成分
让我们首先描述组装 MixMatch 所需的各个部分,然后在最后将它们放在一起形成完整的算法。根据本文,我们将使用 CIFAR10 并随机选择 500 张图像作为标记的训练集。标准的 10000 图像测试装置用于所有精度测量。
数据扩充
数据增强是一种广泛使用的一致性正则化技术,其最大的成功(到目前为止)是在计算机视觉领域。这个想法是在保留语义标签的同时改变输入数据。对于图像,常见的放大包括旋转、裁剪、缩放、增亮等。—不改变图像基本内容的所有变换。MixMatch 通过多次执行增强来产生多个新图像,从而更进一步。然后对这些图像上的模型预测进行平均,以产生未标记数据的目标。这使得预测比使用单一图像更加稳健。作者发现仅仅两次增加就足以看到这种好处。
Fastai 有一个高效的转换系统,我们将在数据上加以利用。然而,由于它被设计为每个图像只产生一个增强,而我们需要几个,我们将从修改默认的 LabelList 开始,以发出多个增强。
Multiple Augmentation
Fastai 的数据块 api 允许灵活地加载、标记和整理几乎任何形式的数据。然而,它没有一种方法来获取一个文件夹的子集和另一个文件夹的整体,而这是这里所需要的。因此,我们将对 ImageList 类进行子类化,并添加一个自定义方法。我们将使用不带参数的 fastai 的get_transforms
方法来使用默认的图像转换;它们是围绕中心 y 轴翻转、旋转 10 度、缩放、光照变化和扭曲。Fastai 的变换系统在应用时会自动随机化每个变换的确切参数。
混合
Mixup
Mixup 首先由张、西塞、多芬和洛佩兹-帕兹[4]在 2018 年提出,属于一般或传统正则化的范畴。Mixup 不是将单个图像传递给模型,而是在两个独立的训练图像之间执行线性插值,然后将其传递给模型。使用与图像相同的λ系数,图像的一个热编码标签也被内插。该系数是从贝塔分布中随机抽取的,由阿尔法参数化。通常,α需要根据数据集进行调整。当α值较小时,贝塔分布的大部分权重在尾部,接* 0 或 1。随着α的增加,分布变得均匀,然后在 0.5 左右逐渐达到峰值。因此,α可以被视为控制混合的强度;较小的值只会导致少量的混合,而较大的值偏向于最大混合(50/50)。在极端情况下,α=0 导致完全没有混合,当α→∞,β接*以 0.5 为中心的狄拉克δ分布。作者建议从 0.75 开始,如下图所示,大部分重量仍然在尾部。本文对原方法做了一处修改,即把λ设为 max(λ,1-λ);这使混音偏向原始图像。
Beta Distribution
Mixup
磨刀
Sharpen
作者使用上述方程作为熵最小化的一种形式,增强了模型对未标记数据的预测。如果温度 T 这个相对简单的步骤,不涉及任何学*参数,对算法来说非常重要。在一项烧蚀研究中,该论文报告称,当移除锐化步骤(将 T 设置为 1)时,精度降低了 16%以上。
Sharpening random distribution
半监督学*中熵最小化背后的思想是分类器的决策边界不应穿过数据空间的高密度区域。如果是这种情况,边界会将非常接*的数据分开。此外,微小的扰动会导致预测的巨大变化。由于决策边界附*的预测更不确定,熵最小化寻求使模型对其预测更有信心,从而使边界远离数据。虽然其他方法[3]将熵项添加到损失中,但是 MixMatch 通过上面的等式直接降低了未标记目标的熵。
作为这种技术的一个例子,让我们尝试一个比 CIFAR-MNIST 更简单、更容易可视化的分类问题。我们仍然将 500 个随机样本作为带标签的训练集,而将其余的样本作为无标签的训练集。完整的图像用于训练,但我们也将使用 tSNE 将每个图像缩减为二维图像进行可视化。按照 MixMatch 关于未标记数据的相同方法,以半监督方式进行训练,我们将使用模型本身来生成伪标签。该模型仅由两个卷积层和一个线性头部组成。没有使用混淆或数据扩充,所以我们可以隔离熵最小化的影响。损失函数在很大程度上也与 MixMatch 相同,对标记数据使用交叉熵,对未标记数据使用均方误差(有关其背后的原理,请参见下面的损失部分)。上面的图像是在没有使用锐化的情况下训练的,而在下面的图像中,伪标签是用 T =0.5 锐化的。分别对十个时期进行训练,非锐化模型的测试准确率为 80.1%,锐化模型的准确率为 90.7%。在下图中,颜色对应于预测的类,标记大小与预测置信度成反比(标记越小越有把握)。如标记大小所示,非锐化模型有很多不确定性,尤其是在聚类的边缘周围,而锐化模型在其预测中更有信心。
The effect of sharpening on the semi-supervised training of MNIST. Images in MNIST were reduced to two dimensions using tSNE. Colors correspond to predicted class, and marker size is inversely proportional to prediction confidence (smaller markers are more confident). The upper image depicts training with T=1, and the lower image with T=0.5.
MixMatch 算法
现在所有的部分都准备好了,完整的算法就可以实现了。下面是单个训练迭代的步骤:
- 提供一批带标签的数据和一批无标签的数据
- 扩充标记的批次以产生新的训练批次。
- 将未标记批次中的每个图像放大 K 倍,以产生总共批次大小* K 个新的未标记样本。
- 对于未标记批次中的每个原始图像,将 K 个扩充版本传递给模型。对增强的模型预测进行平均,以产生增强图像的单个伪标签。
- 锐化伪标签。
- 扩充的标记数据集及其标签形成集合 x。扩充的未标记数据及其(预测的)标签形成集合 u。
- 将集合 U 和 X 连接成集合 w。
- 通过对集合 X 和|X|应用混合来形成集合 X。
- 通过对集合 U 和步骤 8 中未使用的 W 中的示例应用混合来形成集合 U′。
然后将集合 X '(标记的混合)和 U '(未标记的混合)传递给模型,并使用相应的混合标签计算损失。
模型
我们将使用 28 层的宽 resnet 模型,生长因子为 2,以匹配纸张。我们将使用 fastai 包含的 WRN 实现,并与本文中使用的架构相匹配。
失败
有了数据和模型,我们现在将实现训练所需的最后一部分——损失函数。损失函数是两项的总和,即标记损失和未标记损失。标记损失使用标准交叉熵;然而,未标记的损失函数是 l2 损失。这是因为 l2 损失对非常不正确的预测不太敏感。交叉熵损失是无界的,并且随着模型的正确类别的预测概率趋向于零,交叉熵趋向于无穷大。然而,对于 l2 损失,由于我们正在处理概率,最坏的情况是当目标为 1 时模型预测为 0,反之亦然;这导致损失 1。由于未标记的目标来自模型本身,该算法不想过于严厉地惩罚不正确的预测。参数λ ( l
在代码中,因为λ是保留的)控制这两项之间的平衡。
我们将通过在第一个 3000 次迭代(大约 10 个时期)中线性增加未标记损失的权重来稍微偏离本文。在应用这个 rampup 之前,训练模型有困难;我们发现,在早期,精确度增长非常缓慢。由于训练开始时预测的标签本质上是随机的,所以延迟未标记损失的应用是有意义的。当未标记损失的权重变得显著时,模型应该做出相当好的预测。
培养
在培训之前,让我们回顾一下已经介绍过的超参数。
Hyperparameters
该论文的作者声称,T 和 K 应该在大多数数据集上相对恒定,而α和λ需要在每个数据集上进行调整。我们将使用与论文的官方实现相同的超参数值。
一个实现细节:该论文提到,它不是学*速率退火,而是用训练模型参数的指数移动平均值来更新第二个模型。这是另一种形式的正则化,但对算法来说并不重要。对于那些感兴趣的人来说,存储库中有使用 EMA 模型进行培训的代码。然而,在学*速率调度上没有明显的好处,为了简单起见,我们将放弃 EMA,使用 fastai 的单周期策略的实现来调度学*和动量速率。
我们将使用 fastai 的回调系统来编写一个处理大多数 MixMatch 步骤的方法。这个方法从有标签和无标签的集合中分批获取,得到预测的标签,然后执行混合。
fastai Learner
对象包含数据加载器和模型,负责执行训练循环。它也有很多效用函数,如学*率发现和预测解释。该实现中的时期是通过整个未标记数据集的一次。
Learner
结果
作为参考,这些测试是在一个有 16 个 CPU 和一个 P100 GPU 的谷歌计算引擎虚拟机上运行的。第一步是建立一些基线,以便可以比较 MixMatch 的性能。首先,我们将使用所有 50k 训练图像尝试完全监督的情况。接下来,我们将只对 500 个带标签的图像进行训练,没有非监督的组件。最后,我们将使用上一节定义的学*器,用 MixMatch 进行训练。这些跑步的全部细节可以在邮报的资料库的笔记本中找到。
Results
结论
MixMatch 显然拥有令人印象深刻的性能,但缺点是额外的培训时间成本。与完全监督的情况相比,训练 MixMatch 需要大约 2.5 倍的时间。其中一些可能是由于实现中的低效率,但是生成多个增强然后获得标签的模型预测具有显著的成本,尤其是在一个 GPU 的情况下。我们使用官方的 Tensorflow 实现进行比较,并验证 MixMatch 需要很长时间才能完全收敛;超过 12 个小时的训练导致的错误率比论文中报道的要高几个百分点。在 P100 装置上需要将* 36 个小时的训练才能完全匹配他们的结果。然而,几个小时的训练将实现绝大多数的准确度提高,最后的百分之几花费了总训练时间的大部分。
虽然增强和锐化非常有益,但这篇论文的烧蚀研究表明,从误差角度来看,最重要的一个因素是混淆。这也是为什么它如此有效的最神秘的部分——为什么在图像之间的预测中实施线性会有助于模型?当然,它减少了训练数据的记忆,但数据扩充也是如此,在这种情况下效果不尽相同。甚至最初的 MixUp 论文也只提供了关于其功效的非正式论证;根据该论文:
“我们认为,这种线性行为减少了在训练样本之外进行预测时不必要的振荡。此外,从奥卡姆剃刀的角度来看,线性是一个很好的归纳偏差,因为它是最简单的可能行为之一”[4]
其他研究扩展了这一思想,例如通过混合中间状态而不是输入[6],或者使用神经网络而不是β函数来产生混合系数5。然而,我无法找到一个坚实的理论依据;这是另一种属于“它只是工作”类别的技术。很难进行生物学类比——人类很难通过将一个概念与一个不相关的概念混合来学*它。
MixMatch 是一种非常有前途的方法,适用于计算机视觉以外的领域。看到它被进一步理解和应用将会很有趣。
参考
[1]:贝特洛、大卫、尼古拉斯·卡里尼、伊恩·古德菲勒、尼古拉斯·帕伯诺、阿维塔尔·奥利弗和科林·拉斐尔。" MixMatch:半监督学*的整体方法."ArXiv:1905.02249 [Cs,Stat],2019 年 5 月 6 日。http://arxiv.org/abs/1905.02249。
[2]:塔尔瓦伊宁、安蒂、哈里瓦尔波拉。"平均教师是更好的榜样:加权平均一致性目标提高了半监督深度学*的结果."ArXiv:1703.01780 [Cs,Stat],2017 年 3 月 6 日。http://arxiv.org/abs/1703.01780。
[3]:宫藤,Takeru,前田信一,小山正德,石井信。"虚拟对抗训练:监督和半监督学*的正则化方法."ArXiv:1704.03976 [Cs,Stat],2017 年 4 月 12 日。【http://arxiv.org/abs/1704.03976】T4。
[4]:张、、穆斯塔法·西塞、扬恩·多芬和·帕斯。"混淆:超越经验风险最小化."ArXiv:1710.09412 [Cs,Stat],2017 年 10 月 25 日。http://arxiv.org/abs/1710.09412。
[6]:维尔马、维卡斯、阿历克斯·兰姆、克里斯多夫·贝克汉姆、阿米尔·纳杰菲、约安尼斯·米特利亚格卡斯、亚伦·库维尔、戴维·洛佩斯-帕兹、约舒阿·本吉奥。“流形混合:通过插值隐藏状态实现更好的表示”,2018 年 6 月 13 日。https://arxiv.org/abs/1806.05236v7。
关于软件工程现状的几点看法
原文:https://towardsdatascience.com/a-few-points-on-the-state-of-software-engineering-9256c98fac4b?source=collection_archive---------14-----------------------
在这篇短文中,我对当代软件工程实践的挑战进行了简短的讨论,确定了其当前状态的一些潜在原因。在随后的文章中,我将介绍和讨论主流范例用来最小化软件复杂性的策略。这里的观察主要来自我自己的实地经验。因此,这里进行的审查不能说是详尽无遗的。强烈建议被激发进一步研究这个主题的读者去研究参考文献中提到的作品。
Monet’s Rouen Cathedral (cropped). It reminds me of Concepts, Techniques, and Model of Computer Programming.
毫不奇怪,软件工程包含大量的认知努力。要获得软件的所有方面并拿出一个成品,需要跨学科的努力:从需求分析到规范,到设计,到编码,到测试,到评估,以及维护。软件工程使用计算机科学来设计和分析算法,使用工程工具来构建基础设施,使用管理技术来定义权衡、风险、监督人员和监控进度。E. E .小大卫指出[1]:
很少有人认识到今天如此著名的高科技本质上是一种数学技术。
与一些人愿意相信的相反,软件工程不仅仅是写代码。然而,学*软件工程的一种方法是学*编程,这是本文的主要兴趣所在。根据 Brooks 的说法,编程的本质是连锁概念的构建和表示:算法、数据结构、功能以及它们之间的关系[2],而对 Dijkstra 来说,它是“组织复杂性的艺术”【3】。这两种观点相互补充,因为在大多数情况下,软件系统的元素以非线性方式相互作用,整体的复杂性增加得更快。正因为如此,在大多数情况下,对程序正确性的推理,无论是正式的还是非正式的,从非平凡到几乎不可能。尽管如此,证明程序具有所需属性的能力是程序员的基本职责之一。
在这种情况下,一个大型软件系统的复杂性经常超出任何一个人的理解和控制。由此而来的是对高效沟通的需求。为了能够协调许多专业人员的项目开发,不仅要掌握复杂社会系统的内部运作,还要组织个人之间的有效知识转移,因为缺乏这种能力可能会导致对需求的误解和丧失远见。Dijkstra 指出:“磨练你自己的智力是不够的(那将和你一起进入坟墓),你必须教别人如何磨练他们的智力” [4]。不幸的是,目前的教育体系似乎不能满足对熟练软件开发人员的极高需求。J. C. Adams 注意到“需要高级计算技能的公司发现对稀缺资源——拥有这些技能的人——的激烈竞争” 5。软件工程的短缺不仅仅是缺乏任何个人,而是缺乏有经验的专业人员。
然而,我们必须记住,编程只是在 20 世纪 80 年代初才作为一种职业出现的。因此,它相对较新且不成熟,许多软件公司和从业者缺乏对该技术的深刻理解。用 Dijkstra 的话来说,许多急需的工具都需要打磨。现有技术的优势、局限性和需求是可疑的。这同样适用于软件范例、技术,特别是设计用来代表计算机编程当前趋势的语言。在过去的 20 年里,数十种不同的语言被引进和抛弃。根据我的经验,许多主流工具,比如 JavaScript,几乎都有严重缺陷的名声。
这门学科的年轻也反映在它的科学研究上。尽管研究团体很活跃,但是到目前为止,他们还不能准确地整理出许多关于软件工程的基本概念。例如,Baragry 指出,尽管从 20 世纪 50 年代就开始讨论软件体系结构,但是只有 Shaw 1989 年的大型系统需要更高层次的抽象【6】,以及 Perry 和 Wolf 随后的论文软件体系结构研究的基础【7】,为软件体系结构作为一个主要研究领域的出现奠定了基础。即使是 Garlan 和 Shaw 给出的最广泛使用的定义,也没有被社区普遍接受[8]。
人们必须记住,尽管编程的技术和科学取得了令人难以置信的成果,但它们都非常年轻,并且在这种特性和所生产的软件质量之间存在着明显的相关性。要了解这一点,可以考察一下编程劳动的成果。
行业状况
软件业的兴起时期是一个艰难的时期。尽管它带来了二十世纪最伟大的工程成就之一——阿波罗制导系统,但它却被臭名昭著的质量问题所困扰[9]。许多预算超支(如 OS/360)、财产损失(跨西伯利亚天然气管道爆炸)甚至重伤和死亡(臭名昭著的 Therac-25 事件)导致了 1968/1969 年软件危机的认定。许多软件问题导致北约科学会议确定软件不可靠、不可维护、交付延迟且超出预算[10]。1972 年,Dijkstra 指出了同样的问题[11]。
最*的失败
虽然自 20 世纪 60 年代以来,软件工程已经走过了漫长的道路,但尚不清楚这场危机是否已经完全消退。不幸的是,*代史上不乏悲惨的软件故障。1991 年,一枚弹道导弹袭击了美国驻沙特阿拉伯的军营,造成 28 人死亡,96 人受伤。1997 年,一个车载地面高度预警系统是造成 228 人死亡的韩国空难的部分原因[13]。2018 年,优步的一辆自动驾驶汽车的软件计算错误导致一名行人死亡[14]。最后,在狮航波音 737 Max 8 喷气式飞机于 2018 年坠入爪哇海,造成 189 名乘客和机组人员死亡后,联邦航空管理局向波音 737 Max 8 和 9 飞机的运营商发出紧急通知,警告说有故障的“迎角”传感器读数“可能导致机组人员难以控制飞机。”坠机事件的调查人员将飞机飞行控制系统的故障描述为小故障。132 天后,埃塞俄比亚航空公司的波音 737 飞机在亚的斯亚贝巴郊外坠毁,157 人遇难。
鉴于航空航天事故数量惊人,N. G. Leveson 警告说,紧密耦合的系统极其复杂,它们之间的相互作用失调[16]:
本文调查的所有事故都显示了系统事故的某些方面。交互的复杂性和紧耦合导致系统事故。软件允许我们构建复杂程度和耦合度超出我们控制能力的系统;事实上,我们正在构建的系统中,组件之间的交互(通常由软件控制)无法全部被计划、理解、预期或防范。
斯坦迪什报告及其批评
1994 年,独立的国际 IT 研究组织 Standish Group 发表了臭名昭著的 Chaos 报告,报告显示了令人震惊的 16%的软件项目成功率。2004 年,29%的项目成功,53%受到质疑,18%失败。在两个最初的报告中,项目的成功是基于它是否“在合理的估计时间内,保持在预算内,并且包含大量估计的特性和功能”完成的在 2015 年,结果是相似的,29%的项目成功,52%被认为有挑战,19%失败,其中项目的成功是基于它是否“在合理的估计时间内解决,保持在预算内,并交付客户和用户满意,而不管最初的范围”[17]。
Standish 最初和最*的数据经常被认为是软件业失败的证据。然而,多年来,提出了许多反对意见,质疑斯坦迪什的方法。许多人认为斯坦迪什的数字是“不可靠,不一定反映现实”【18】【19】【20】。
埃尔·埃马姆等人指出[21]:
尽管有各种关于软件项目失败率的行业报告,但实际数字仍然不确定。研究人员在 2005 年和 2007 年对全球 IT 部门进行了网络调查。结果表明,软件危机可能被夸大了,大多数软件项目都交付了。然而,对于一个应用学科来说,总的项目失败率,包括被取消的和已完成的但表现不佳的项目,仍然是很高的。
软件工艺
不管实际情况如何,随着技术的进步,新的劳动力进入市场,关于危机的争论逐渐平息。从作者的个人经验来看,软件产品的质量似乎在整个行业中分布得很不均匀,在具体的努力领域之间有显著的差异。这与没有既定做法的新兴市场的不同质量标准、不同水平的期望和所生产软件的重要性以及财务利润优先于责任有关。毫不奇怪,在工艺不被关注的市场上,软件的低质量更容易被忽视。
为了应对对行业未来日益增长的担忧,《敏捷宣言》(Agile manifesto)的合著者、《坚实的原则》(SOLID principles)以及工匠精神运动的支持者罗伯特·c·马丁(Robert C. Martin)向程序员们提出了一个誓言(类似于《日内瓦宣言》(Declaration of Geneva),要求“捍卫和维护职业的荣誉”。那些宣誓成为程序员的人,除了其他人之外,还应该发誓“无所畏惧,坚持不懈地抓住每一个机会改进代码”【22】。
行业人口统计
当讨论这个行业的弊病时,人们必须记住当前的行业劳动力是多么年轻。自 20 世纪 80 年代以来,软件工程才成为一个普遍的职业。罗伯特·c·马丁推测,到 1980 年,以前来自工程、科学或数学等领域的高技能个人(通常在三四十岁)被数百万刚刚毕业的年轻人所取代[23]。在那之前,程序员是训练有素的专业人士,他们受雇于其他工作职能部门,通常更老更成熟,不需要太多的管理。在某种程度上,这场革命是由家庭和商业计算的出现促成的。Martin 接着说,粗略地说,程序员人数每五年翻一番(或者说过去是这样),这意味着,在任何时候,一半的程序员只有不到五年的经验。不管这个观察多么正确,一个不可否认的事实是,现在,一般的程序员都很年轻。
2018 年,致力于编程的热门问答网站 StackOverflow 进行了一项 30 分钟的调查,覆盖了全球超过 10 万名开发者[24]。调查的主题从人工智能到编码伦理。结果显示,在专业开发人员中:
- 30.1%的人参加 0-2 年的专业课程,27.4%的人参加 3-5 年的专业课程,14.6%的人参加 6-8 年的专业课程。换句话说,72.1%的职业受访者拥有 0 至 8 年的经验;
- 46.1%拥有学士学位,22.6%拥有硕士学位,在本科专业中,只有 63.7%的学位是计算机科学、计算机工程或软件工程;
- 26.1%小于 25 岁,49.2%在 25 至 34 岁之间。
总之,StackOverflow 的发现似乎支持马丁关于计算机编程行业永远缺乏经验的说法。马丁还指出,由于教育系统无法弥补行业的高速增长,年轻人注定会一次又一次地重复同样的错误。一些程序员将这种现象称为业界的十年失忆【26】。
摘要
正在进行的辩论似乎难以解决,而且可能永远如此。无论如何,重要的是不要自满。Moseley 和 Marks 认为复杂性是当今软件绝大多数问题的根源[25]:
不可靠性、延迟交付、缺乏安全性——通常甚至是大规模系统中的低性能都可以被认为是源于不可管理的复杂性。复杂性作为这些其他问题的主要原因的主要地位仅仅来自于这样一个事实,即能够理解一个系统是避免所有这些问题的先决条件,当然,复杂性摧毁的正是这一点。
在他的经典论文 No Silver Bullet 中,Brooks 指出软件的复杂性是一个基本属性[2]。由此,我们可以得出结论,软件系统中的大部分复杂性是必不可少的。Moseley 和 Marks 不同意这种观点,他们指出软件系统中的大部分复杂性实际上是偶然的,并且是可以消除的[25]。具体来说,他们认为复杂性的主要来源是对主流语言中状态的错误处理。
我们将在以后的文章中研究这个想法。在此之前,敬请关注,感谢您的阅读。
如果您有任何反馈(尤其是批评性的),请评论或给我发电子邮件至 iwoherka@gmail.com。
参考
- W.洛杉矶.弗里德曼。解决现实世界问题的课程。工业和应用数学学会,第一版,1987 年。
- F.软件工程的无银弹本质和事故。计算机,20(4):10–19,1987 年 4 月。
- E.迪克斯特拉,奥达尔和 c .霍尔。结构化程序设计笔记。数据处理中的 APIC 研究,8,1972。
- E.w .迪杰斯特拉。我对计算科学的希望(ewd709)。《第四届国际软件工程会议论文集》, ICSE '79,第 442-448 页,美国新泽西州皮斯卡塔韦,1979 年。IEEE 出版社。
- 计算机是当今最安全的职业选择。https://cacm.acm.org/blogs/blog-cacm/ 180053-计算机是最安全的职业选择-今天/全文。访问时间:2019–03–30。
- 米(meter 的缩写))肖。更大规模的系统需要更高层次的抽象。《第五届软件规范和设计国际研讨会论文集》, IWSSD '89,第 143-146 页,美国纽约州纽约市,1989 年。ACM。
- D.e .佩里和 A. L .沃尔夫。软件体系结构研究基础。SIGSOFT Softw。英语。注释,17(4):40–52,1992 年 10 月。
- J.巴拉格雷和 k .里德。为什么定义软件架构如此困难?《第五届亚太软件工程会议论文集》, APSEC '98,第 28 页,美国 DC 华盛顿州,1998 年。IEEE 计算机学会。
- 页(page 的缩写)诺尔和 b .兰德尔,编辑。软件工程:由北约科学委员会主办的会议报告,德国加米施,1968 年 10 月 7-11 日,布鲁塞尔,北约科学事务处。1969.
- 页(page 的缩写)诺尔和 b .兰德尔,编辑。软件工程:由北约科学委员会主办的会议报告,德国加米施,1968 年 10 月 7-11 日,布鲁塞尔,北约科学事务处。1969.
- E.w .迪杰斯特拉。谦逊的程序员。Commun。美国计算机学会,15(10):859–866,1972 年 10 月。
- R-17 vs 爱国者:四舍五入的问题。https://www.viva64.com/en/b/0445/.访问时间:2019–03–30。
- 疲劳和失误被指在关岛坠机。https://www.nytimes.com/1999/11/03/us/疲劳和错误被引用于关岛坠机事件. html .访问时间:2019–03–30。
- 报道:软件 bug 导致优步自动驾驶撞车死亡。【https://arstechnica.com/tech-policy/】T22018/05/report-软件-bug-导致死亡-无人驾驶-撞车/。访问时间:2019–03-30。
- 当一个软件故障导致一架客机坠毁时,一些棘手的问题被提了出来。https://www.viva64.com/en/b/0445/。访问时间:2019–03–30。
- 名词(noun 的缩写)g .莱韦森。软件在航天器事故中的作用。宇宙飞船和火箭杂志,41(4):564–575,2004。
- 南团体。混沌报告:2015,2015
- R.格拉斯。斯坦迪什报告:它真的描述了一场软件危机吗?Commun。美国计算机学会,2006 年 8 月,49:15–16。
- 米(meter 的缩写))乔根森和 k .莫洛肯-奥斯特瓦尔德。软件成本超支有多大?对 1994 年混沌报告的评论。Inf。Softw。技术。,48(4):297–301,2006 年 4 月
- C.伊夫琳斯。混沌报告数字的起伏。IEEE 软件,27(1):30–36,2010 年 1 月。
- K.埃马姆和克鲁。it 软件项目失败的重复调查。IEEE Softw。,25(5):84–90,2008 年 9 月。
- 程序员的誓言。https://blog . clean coder . com/uncle-bob/2015/11/18/the programmerswear。 html。访问时间:2019–03–30。
- 编程的未来。https://www.youtube.com/watch?v=ecIWPzGEbFc.访问时间:2019–03–30。
- 堆栈溢出—开发者调查结果:2018 年。https://insights.stackoverflow.com/survey/2018/.访问时间:2019–03–30。
- B.莫斯利和 p .马克斯。从沥青坑里出来。2006 年软件实践进步(SPA)课程。
- 功能极客——第一集——罗伯特·c·马丁。https://www . functional geekery . com/episode-1-Robert-c-Martin/
构建闪亮应用程序时需要注意的几件事
原文:https://towardsdatascience.com/a-few-things-to-take-care-of-while-building-shiny-apps-888e4676090b?source=collection_archive---------24-----------------------
构建 RShiny 应用程序时克服障碍和节省时间的简化技术
自从 2011 年末 RStudio 的发展以来,Rshiny 已经被广泛用于构建仪表板和应用程序,这些仪表板和应用程序具有 web 上的后端 R 支持和部署。现在,通过专用的包将 CSS 和JavaScript功能嵌入 Rshiny 应用程序是可能的,其目的是提高交互性并提供动态界面。我已经开发和部署 Rshiny 应用程序 3 年多了,所以通过这篇博客,我将分享一些障碍以及如何在开发产品时用简单的技巧克服它们。
首先,让我简单介绍一下初级/中级优秀程序员在设计应用程序时可能会遇到的障碍。
1.花在设计上的时间
美学是最重要的,正如人们所说的那样——“许多难以设计的东西证明很容易实现”——塞缪尔·约翰逊。
虽然 ShinyDashboard 和 ShinyDashboardPlus 提供了设计 Dashboard 的模板,但在提供动态 UI 方面,它们往往有所欠缺。例如,引导模式在使用 shinydashboard 页面时失败。为了克服这个问题,需要使用引导页面设计一个仪表板,但是这样你就失去了设计的机会,因为你需要从头开始重新构建它,而且这需要大量的研究,这几乎占用了总时间的 30- 40 %。对于一个刚刚开始使用 RShiny 设计应用程序的初学者来说,可能会觉得它很慢。
2.没有时间进行测试——再次构建和测试
虽然看起来应用程序运行良好,但在演示中你的应用程序突然下毛毛雨,这表明控制台上有一个错误。此错误可能是由于不合逻辑的数据操作或子集操作导致的,这些操作返回了零个条目,并且有时它没有指出错误发生的位置。当您修复代码并使工具再次运行时,您会看到一些之前没有注意到的错误。这也发生在我身上。
原因是我们过多地参与了逻辑与设计的集成,以至于我们几乎没有足够的带宽来适当地处理错误。
3。随机应变…适应…克服挑战
假设您为仪表板中的一个页面编写了一个逻辑,并将其展示给客户。突然,你的客户要求对它进行细微的改变,这可能需要你改变现有工具的反应,你发现自己很痛苦。当你正在设计的工具有多个模块,而你/你的客户从来没有想到这个即将到来的逻辑会被证明是有价值的时候,这种情况经常发生。它为你的工作增加了价值,但是要花费大量的时间重新回到前面。
解释完挑战后,现在让我们来关注如何应对它们。
1.始终遵循 SDLC { 软件开发生命周期 }
构建 RShiny 应用程序是一个项目,每个项目都有阶段。虽然我们大多数人都知道 SDLC,但是我们很少打算实现它。大部分时间花在设计上,没有时间测试和集成。
Easy way to understand SDLC | Dignitas Digital
拥有预定义的 SDLC 不仅有助于软件开发,还有助于跟踪我们在每个阶段投入了多少时间。
这是我在开始这个项目之前使用的一种方法:
- 设计线框:总是设计一个线框,它只不过是一个网页的布局,展示什么样的界面元素将存在于关键页面上。你可以使用任何工具,甚至可以在普通纸上设计。手里有线框将帮助你确定需要什么成分来开发页面,因此反过来,在实现美学方面将节省大量时间。
2。截止日期和工作量分配
虽然构建闪亮的应用程序在开始时似乎很容易,但将后端与前端集成起来需要付出很多努力。如果您正在设置部署的截止日期,请确保:
—牢记要解决的测试案例。
—设计时,确保检查元素以调整浏览器本身的宽度和高度。 示例 :通过手动微调,确定合适的框宽或高度。
Changing Aesthetics on the fly in Rshiny app.
—将代码分离到模块中,并在页面数量增加时相应地分配带宽。例如,一个页面的前端代码和后端代码将作为单独的 R 脚本保存,这些脚本将在服务器中使用 source 命令导入。所以,如果你有一个团队在开发这个应用程序,每个人都可以用来创建一个单独的模块,这个模块可以在以后集成。关于它的更多信息在这里 提到
—如果有大量数据需要与后端集成,尝试将代码分成三个部分,即。全球。r,服务器。r 和 UI。r,这里是全局。r 将只包含初始数据获取和数据清理操作。
—如果您的数据导入和清理需要很长时间,请尝试在运行 global 后存储初始工作空间环境。r 作为工作空间图像(. RData ),这样以后导入它所花的时间就会减少,节省下来的时间可以用来增强 UI。
3.快速获取有用的资源
在设计闪亮的应用程序时,许多概念将成为新的搅拌机。因此,在短时间内找到合适的资源将证明是有益的。除了寻找解决堆栈溢出的方法,这里还有一些我在 RShiny 上工作时期待的资源**
- https://www.showmeshiny.com 的是一个很棒的网站,有一个闪亮的应用程序库,提供源代码和现场演示供参考。如果你是一个希望在设计线框之前看一些模板的人,这是你探索的正确地方。
- ***【https://deanattali.com/blog/advanced-shiny-tips/ ***
- https://github.com/grabear/awesome-rshiny
- https://github.com/FrissAnalytics/shinyJsTutorials
- 探索CRAN——在 shiny 中,有许多正在开发的包可以简化 UI 的开发,您可以找到许多为此做出贡献的包。
- 在 GitHub 上询问——**如果你没有得到你想要的,试着在 GitHub 上找到这个问题,如果没有的话,把它贴在相关的库问题里,这样作者可以试着解决它。例如,与JavaScript*相关的问题可以放在 shinyjs 存储库问题中。*****
Asking Questions on GitHub
结束注释
因此,在了解了建议的漏洞并将其应用到您的 RShiny 项目之后,我希望它能帮助您节省大量的时间。
接下来,我将分享一些 R 技巧和 Rshiny 功能,它们将帮助你平稳高效地构建 RShiny 应用。
进入科技行业前你应该知道的几件事
原文:https://towardsdatascience.com/a-few-things-you-should-know-before-going-into-tech-aebc77c4f6cf?source=collection_archive---------31-----------------------
对最*科技发展趋势的快速总结
Median Salary in Tech in the US (2018), based on Operating System used
很少有行业像科技这样随着新趋势而蓬勃发展。每年都有新的框架、编程语言和技术颠覆这个行业的核心。科技无疑是当今最有趣、最赚钱的工作领域之一。
一个新人在找这个领域的工作的同时,肯定要对这个行业的实际趋势和需要的技能做一些研究。无论一个人是对最新技术感兴趣,还是仅仅想要一份高薪的技术工作,知道什么是热门,什么不是很重要。
本文根据 Stackoverflow 进行的问卷调查提供了一些有趣的见解。调查问卷可追溯至 2013 年和 2018 年,包含约 20,000 条(干净的)观察结果。为了确保结果的可比性,数据集只关注美国市场和全职工作岗位。这几年间的问卷结构发生了显著变化,但经过广泛的数据清理,仍然可以得出有趣的结论。我们将在下面的段落中讨论它们。
- Python 热,PHP 不热
上面两张图表显示了 2013 年和 2018 年编程语言的相对受欢迎程度*。由于不同年份之间 Stackoverflow 问卷结构的变化,上述两个图并不完全可比。但是,有些趋势还是很明显的。
在常见的“前端-后端-数据库”工具箱(Java、C、Javascript、SQL)后面,唯一一种相对份额在这些年来有所增加的语言是 Python。另一方面,C#和 PHP 正在失去它们在编程语言组合中的份额和地位。这并不奇怪,因为 Pythons 的功能和库在过去的几年里显著增加了。在以前没有使用 Python 的领域,例如前端开发,python 正成为开发人员的首选工具。
2。大数据意味着更多的数据管理员
上面的图表显示了技术工作在不同职业/职位中的分布情况。在两次问卷调查过程中,一些职位名称发生了变化,这可能会导致模糊的结论。然而,数据库管理员的角色保持不变,其在技术领域的份额在 5 年间从 2%跃升至 5%。这种变化的确令人印象深刻,但也是直觉的。
最新技术允许科技公司存储海量数据,并利用这些数据获得有价值的见解。维护和结构化数据变得越来越重要,数据库管理员的角色也随之变得越来越重要。
3。经验很重要
Feature Table explaining the Salary in US (2018)
Stackoverflow 问卷还询问了受访者的工资。我试图利用 2018 年的数据,找出哪些特征最能解释工资。使用的模型是随机森林分类,其中工资被分成 50K、100K、150K 箱。虽然分类结果很差(测试集的加权 F1 分数为 51%),但特征重要性结果很有趣。重要的是,这些结果与其他几个模型(线性回归、随机森林分类)的相同结果非常吻合。
从上面的特征表中我们可以看到,最能解释工资的因素是“编码年数”。看来,较早进入该行业并获得经验的受访者可以期待更高的薪水。
Median Salary in US in Tech for different levels of Experience
还有最后两点。
从特性表和本文开头的柱状图中,我们注意到开发人员在哪个操作系统中工作很重要。Unix 开发人员有望获得大约 12 万美元的最高年薪。
了解替代编程语言似乎是有利可图的。虽然 Java,C,Javascript 等。是最受欢迎的语言,使用 Hack、Scala 和其他“特殊用途”语言的专业人士可以期望赚得更多。
Median Salary across programming languages in US (2018)
结论
在这篇文章中,我们回顾了科技行业的一些变化趋势,并试图揭示解释该领域薪资的一些特征。使用的数据是 Stackoverflow 年度问卷数据。
总而言之:
1- Python 越来越受欢迎,而 PHP 和 C#却落后了
2-需要数据库管理员
3-经验是导致高薪的最重要的特征。然而,精通“专用”编程语言和在不太传统的操作系统如 BSD/Unix 和 MacOs 中工作也能带来高收入。
这篇文章后面的完整代码可以在这里找到,问卷数据在这里。
*调查问卷的参与者回答了他们精通哪种编程语言(通常不止一种)。这里的流行度是一种编程语言在所有回答中的相对出现率。
有几次,我打碎了熊猫
原文:https://towardsdatascience.com/a-few-times-i-managed-to-broke-pandas-d3604d43708c?source=collection_archive---------26-----------------------
这里有一个场景。我希望其他人能从我这里的错误中受益。
W 当我将大部分工作从 Stata 转移到熊猫时,我遇到了一些障碍。好吧,我承认。我写了一些糟糕的代码。这是我做错的一个例子。
Image credit: Author. “Broken Pandas.” Image Credit: “Via Design Pickle” — More on attributions.
重复的列名
其他统计语言更严格地防止重复的列名。然而,熊猫可以被欺骗允许重复的列名。
如果您计划将数据集转换为另一种统计语言,重复的列名是一个问题。它们也是一个问题,因为它会在 Python 中导致意想不到的、有时难以调试的问题。
公平地说,复制这一点并不容易,下面的代码展示了如何复制:
How I broke Pandas. Image Credit: “Author’s Screen Capture” — More on attributions.
上述数据框的用例是一个作者列表,他们被分配写两个主题中的一个。因此,主题列是分类变量或因子变量。
所以,到目前为止,没有错误。直到您尝试将选项标签映射到'topic'
下的选项值,这是操作分类或因子变量时的常见操作。
Error that occurs when a Pandas data frame has more than one identically named columns. Image Credit: “Author’s Screen Capture” — More on attributions.
检查列名唯一性的一个快速方法是评估'len(df.columns) == len(set(df.columns))
。如果语句评估为False
,这表明您可能有重复的列名。
愚蠢的错误。很容易解决。
How I fixed the data frame that I managed to break above. Image Credit: “Author’s Screen Capture” — More on attributions.
[## 加入我的介绍链接媒体-亚当罗斯纳尔逊
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
adamrossnelson.medium.com](https://adamrossnelson.medium.com/membership)
感谢阅读
把你的想法和主意发给我。你可以写信只是为了说声嗨。如果你真的需要告诉我是怎么错的,我期待着尽快和你聊天。推特:@ adamrossnelson| LinkedIn:亚当·罗斯·纳尔逊 |脸书:亚当·罗斯·纳尔逊。
手腕轻轻一弹:定义下一代人机交互
原文:https://towardsdatascience.com/a-flick-of-the-wrist-defining-the-next-generation-of-human-computer-interaction-7c8f962bd014?source=collection_archive---------13-----------------------
以下是我在 2019 年 1 月在 TedX Goldey Beacom 上的一次演讲的书面版本。他们拍了下来,你可以在这里观看!
多年来,我们一直被魔法的概念所迷惑。有人认为,只要挥一挥魔杖,打个响指,或者说一些特殊的话,就可以在瞬间彻底改变他们周围的世界,这种想法在历史上一直占据着人们的头脑。
任何足够先进的技术都和魔法没什么区别。
—亚瑟·C·克拉克爵士
现在,我们生活在一个在屏幕上操控人类全部知识的世界里,屏幕仅仅比信用卡大一点。我敢打赌,这个房间里的每个人口袋里都有一个设备,它的计算能力比我们用来把人送上太空的技术还要强。相对于人类历史的其余部分,这一切都发生在眨眼之间。即使在我的有生之年,也很难夸大我们已经走了多远。
St. Peter’s Square in 2005 via NBC
St. Peter’s Square in 2013 via NBC
随着扩展现实、机器学*和其他新兴技术的出现,我们与计算机以及彼此之间的工作方式将在未来几年内发生巨大变化。我们越来越能够不仅感知三维的数字世界,还能与它们互动并被它们看到。这本质上就是人机交互领域正在发展的东西。
今天,我将向您展示一些正在推动技术边界的 HCI 研究项目。我邀请你展望未来,看看它们将如何从根本上改变我们与计算机、信息以及彼此之间的互动方式。
但首先,花点时间和我一起做梦。今天是 20XX 年,星期二。
想象一下,一个孩子第一次上化学课。还记得学分子几何吗?原子排列成各种三维形状,像四面体和三棱锥?你必须把它们画在纸上,只用一支铅笔和一把尺子来想象这些构成我们世界基本组成部分的抽象形状。
或者,也许你更幸运一点,参加了一个活动,像我在高中时那样安排橡皮泥和牙签。他们真的很悲伤,萎靡不振。
相反,20XX 的孩子们玩全息图,在太空中徒手构建八面体和跷跷板。他们可以直观地操纵原子键,玩数字表示,就像我们在原子水平上理解事物一样。
想象一下,你正在远足,看到了壮丽的山景。受到它们的美丽的启发,你拿出了你的素描本,但你并没有自己身上所有的颜料。但这没关系,当你画出细细的摇摆不定的线条时,它就在你眼前变成了一幅如画的风景画。
你下班回到家,投入到一个游戏中,这个游戏基本上把你带入了母体。作为孤胆英雄,你独自站在一个充满敌意的世界里。你被特工包围,用整个身体慢动作躲避子弹。
现在,你想告诉我所有这些听起来很疯狂,需要我们没有的技术,对吗?但事实证明,“20XX”其实是 2018 年。这些是我们去年做的一些事情。
化学申请是卡内基梅隆大学的项目学生。
Project Pupil Chemistry Demo via Yujin Ariza
那幅画?由备忘录 Akten 提出的申请。
Learning to See via Memo Akten
慢镜头射手?超级热门的,你现在就可以去虚拟现实街机玩。
via Super Hot VR Trailer
那么,这些东西到底是什么?我们如何做到这一点?
对于外行人来说,XR 是一个总括术语,用来描述真实和虚拟对象协同交互的连续统一体。这包括像虚拟现实这样的技术,在虚拟现实中,你的整个环境是数字的,增强现实中,你将平面图像叠加到现实世界中,以及两者之间的任何维度。
Leap Motion Mirrorworlds Concept Video
也许你玩过原始的增强现实系统,比如口袋妖怪 Go …
或者有幸尝试过像 Beat Saber 这样的虚拟现实系统卖家。
Beat Saber via LIV and SwanVR
XR 技术的一个共同点是它们使用计算机来塑造你的感知。XR 作为一个光谱可以把你放在一个全新的和不同的环境中,或者简单地给现实世界添加信息。
机器学*本质上是使用特定的算法来教计算机如何解决问题。它被用于各种应用,从掌握围棋 …
…到为自动驾驶汽车的大脑提供动力,
…以从少量线条中生成猫。
via pix2cats
我画了最后一个,他大概是。
使用机器学*通过计算机的眼睛看世界有很多令人兴奋的工作。
我们能够让人工智能展示世界的一部分。我们可以向他们展示我们的身体,我们的绘画,物体如何相互作用,看他们想出什么,并利用这些来塑造我们的感知。机器学*能够理解现实中的大量信息,而 XR 将帮助我们更清楚地看到这些信息。
All watched over by machines of loving grace: Deep-dream edition (2015) via Memo Akten
我觉得一些最令人兴奋的发展是通过开源和公共资助的研究项目实现的。
OpenPose 是卡耐基梅隆大学的一个研究项目,它使用机器学*来检测单个图像中的身体。
它已经被用作其他工作的主干,包括帮助你将整个身体放入虚拟现实的研究项目
Deep Learning for VR/AR: Body Tracking with Intel RealSense Technology
…帮助你(或者至少是你的视频)表演复杂的芭蕾舞。
Everybody Dance Now via Caroline Chan
Pix2Pix 是伯克利的一个项目,它使用神经网络根据训练数据生成图像。
Pix2Pix via a Affinelayer
它被进一步混合到应用程序中,使你的网络摄像头变成鲜花
Learning to See: Gloomy Sunday
…或者将威尔明顿天际线的照片变成模仿范·高的华丽画作。
via Deep Dream Generator
Project North Star 是一款增强现实耳机,你可以在世界任何地方进行 3D 打印。有一个社区正在围绕这些耳机的采购和制造成长,我认为随着它变得更容易获得,我们将会看到一些有趣的应用。
这些都是开源的,所以任何人都可以利用他们的成果,在此基础上开发各种应用程序。
“他们”包括我。
Me in my North Star via UDaily
我目前正在建造自己的北极星。我在特拉华大学能够 3D 打印的一些部分,其他部分来自项目周围突然出现的社区成员。这大部分发生在 UD 的夏季学者计划中,在那里我花了 10 周时间学* XR 开发的基础知识。学期开始后,我将这一经历转化为一个本科生研究项目,专注于让跨学科的学生一起开发 XR 应用程序。
就在上周,我去了麻省理工学院媒体实验室的黑客马拉松 Reality Virtually 。我和其他 400 多名开发人员、艺术家、设计师和程序员一起开发 XR 应用程序。
The University of Delaware Human-Computer Interaction at Reality Virtually. Right to left: Zhang Guo, Dr. Roghayeh Barmaki, Alina Christenbury, Yan-Ming Chiou
黑客马拉松所有项目的一个规则是,它们必须是开源的,这样世界上的任何人都可以利用它们创造出新的有趣的应用程序。我们一起制作了不到 100 个 XR 项目,包括物理治疗和无障碍工具,还有游戏和互动艺术。我的团队在不到 5 天的时间里制作了一个虚拟现实逃生室,我的顾问巴马基博士的物理治疗项目获得了“最佳虚拟现实应用”。
Escape the Witch’s Grotto
在我看来,这项技术真正融合在了镜像世界的概念中。
Illustration by Anna Mill
这项技术将帮助将你周围的物理空间转换到另一个平行维度,而不是离开你的物理空间。椅子变成了山,墙壁变成了日落,“地板是熔岩”从一个简单的儿童游戏变成了一种发自内心的体验。您可以像与物理对象交互一样与数字对象交互,并且与物理对象的交互效果更好。你的环境可以向你展示它是如何工作的,就像物品向你展示如何使用它们一样。一把吉他可以教你如何弹奏它自己,告诉你如何最好地握住它来弹奏特定的和弦。或者物体可以完全改变,比如桌子变成触摸屏,铅笔变成魔杖。
是时候将话题从 AR 系统应该是什么样子转移到 AR 体验应该是什么感觉上了。大卫·霍尔茨
问题不再是“我们如何让这个工作?”而是“这应该是什么感觉?”我们正处在历史的某个点上,被认为是“魔法”的东西是真实的。就在这里,就是现在。所以,我留给你们这个:
你会用它做什么?
为了准备这个,我读了很多很多的东西,以便为这个演讲创造一个稍微有点像叙事的东西。我尽了最大努力保存来源,其中大部分都链接到 throughout,但请随意查看来源以获得完整列表。这篇文章也可以在我的网站 alinac.me 上找到。
我也有邮件列表!如果你想偶尔收到我在 alinac.me/subscribe的邮件,请注册
管理模型风险的框架
原文:https://towardsdatascience.com/a-framework-for-model-risk-5953dedbe112?source=collection_archive---------31-----------------------
Photo by Dakota Roos on Unsplash
*年来,银行在使用定量分析和模型方面面临监管压力。因此,法规正在到位,以确保模型得到有效管理,从而降低模型风险。
美联储将模型风险定义为[1]:
基于不正确或误用的模型输出和报告的决策的潜在不利后果。模型风险可能导致财务损失、糟糕的业务和战略决策,或者损害银行组织的声誉
以银行监管为起点,我们将定义一个可用于任何机器学*部署的框架,以量化和最小化模型风险。
我们的模型风险可以分解为 4 个关键轴[2,3]:
- 模型定义
- 模型治理
- 模型验证
- 模型监控
Model Risk Framework
模型定义
建立一个拥有明确所有者的模型清单,定义组织内运行的每个机器学*模型的目标、假设和限制
第一步是建立一个在生产中运行的机器学*模型的清单,以及它们如何相互交互。通过创建模型清单,您将能够找出哪些模型由于潜在的级联故障而具有最大的内在风险。
您的清单的目标不应该是创建技术文档,而是给涉众一个模型做什么和它的限制是什么的高层次概述
它应包括:
- 型号名称和描述
- 开发阶段(已实施使用、开发中或*期退役)
- 高等级风险评估
- 模型目标
- 模型假设
- 型号限制
评估模型重要性有助于定义与每个模型相关的高级风险。通过根据容量、使用环境和财务影响分解每个模型,您可以为每个模型分配一个风险分数[4]。例如,很少使用的模型不会像影响关键业务决策的模型那样带来很大的风险。
其中一个风险是,随着时间的推移,该模型清单会过时,为了避免这种情况,您应该指定一个人明确负责确保该文档保持最新。这并不意味着这个人应该编写所有的文档,而是他们应该跟进模型所有者,以确保他们的模型文档是最新的。
模型治理
指定负责开发、实施和使用模型的模型所有者。他们的部分职责是与高级管理层合作,为新模型的部署制定签署政策。
考虑模型治理的良好开端是定义:
- 模型所有者:模型所有者负责确保模型得到适当的开发、实现和使用。
- 模型开发人员:模型开发人员在模型所有者的领导下创建并实现机器学*模型。
- 模型用户:模型用户可以是企业内部的,也可以是外部的。对于这两种情况,清楚地确定他们的需求和期望是很重要的。他们还应该参与模型开发,并可以帮助验证模型的假设。
明确地定义不同的涉众将会使分配角色和职责变得更加容易,这在模型发展和团队变化的时候尤其重要。
良好的模型治理也是关于跟踪模型的初始开发以及它如何随着时间的推移而变化。通过记录模型开发过程,即使所有者发生变化,您也能够更快地迭代。
再现性很重要,但还不够,你的文档还应该解释为什么选择一种方法而不是另一种方法,以及探索的死胡同。
在开发模型治理策略时,最后一个好的实践是定义在部署新模型之前需要什么样的管理签署。鉴于机器学*模型可能产生的影响,定义谁负责签署新模型的部署非常重要。管理层签核可以基于每个模型,也可以基于验证指标自动进行。
模型验证
定义一个外部或内部的验证过程,以确保模型按预期执行,并在部署之前进行记录。
一旦开发了模型,就需要在部署之前对其进行验证。可以通过两种方式进行验证:
1.外部验证:由外部审计师或独立方
2 执行。内部验证:验证由同一个团队或部门执行
虽然一些监管机构要求外部验证,但对于大多数不受监管的行业,您可能会在内部验证您的模型。为了最小化确认偏差,验证过程应该在模型开发人员很少或没有输入的情况下进行。这也将有助于识别模型开发过程的文档中的潜在差距。
为了使内部验证有效,应该根据模型用户的输入提前定义验证指标和阈值。验证不应仅限于简单地评估性能指标,还应包括对方法的审查,以确定尚未考虑的模型偏差或边缘情况。验证者还应该检查用于构建模型的代码,并确保它的版本是正确的。
模型监控
使用与传统 IT 系统类似的流程,定义流程来检测和解决潜在问题。
在前面的章节中,我们已经定义了流程,以确保关键的利益相关者意识到正在开发的模型中的内在风险,并确保它们是可重复的和可迭代的。
即使有好模型治理,使用机器学*模型也有风险。这些风险可以细分为:
- 依赖关系的变化
- 数据质量问题
- 您正在建模的过程中的变化——通常被称为概念漂移
处理模型风险意味着制定一个计划来检测和修复这些潜在的问题。做到这一点的一种方法是实施与传统 IT 系统类似的监控策略,但使用针对机器学*系统的指标。
我以前写过一些您应该监控的核心指标:部署后的模型生命周期
Example Monitoring Dashboard — Stakion
结论
模型风险对于任何部署机器学*模型的组织来说都是一个现实,但也是经常被忽视的东西。
建立具有明确定义的模型目标、假设和限制的准确模型清单是最小化模型风险的第一步。定义模型开发、验证和签署的过程也将确保只有你满意的模型才开始被使用。最后,一旦部署了模型,您应该有一个监控策略来跟踪模型依赖性、数据质量和概念漂移。
参考:
- [1] 欧洲议会和理事会指令 2013/36/EU
- [2] 压力测试模型管理 —英格兰银行
- [3] PRA 的模型风险管理的 4 个关键原则
运行数据科学项目的框架
原文:https://towardsdatascience.com/a-framework-for-running-data-science-projects-fd37b26a4389?source=collection_archive---------25-----------------------
Seattle photo by Luca Micheli & Boston photo by Osman Rana on Unsplash
开始一个数据科学项目
对于从数据领域起步的人来说,从零开始建立一个项目似乎有点令人生畏。这可能很有诱惑力,只是把你所知道的一切都投入进去,看看什么会有效,但事实上(和其他事情一样),耐心最终会有回报的。这就是为什么数据科学家开发了各种旨在帮助管理数据项目和提供结构的框架。这些框架中的大多数都遵循类似的步骤,这些步骤将在本文中概述。
为了给出一个真实的例子,我将参考我一直在做的一个项目,比较西雅图和波士顿的 Airbnb 数据,试图提取有用的商业见解。遵循本文中的步骤将会给你一个开始的地方,并有希望让你专注于底层数据。
了解你的目标(主题理解)
在执行任何任务之前,重要的是要知道分析的目标是什么,或者你要解决什么问题。这似乎是显而易见的,但是你会惊讶于很多次有人会要求你做一些没有明确目标的事情。首先,你应该问为什么要执行任务,找出利益相关者的目标,理解关键绩效指标(KPI)。在整个项目中记住这些事情是很重要的,这样你就不会忽略什么是重要的。
Airbnb conference photo by Teemu Paananen on Unsplash
在我的案例中,使用 Airbnb 数据的目的是根据各种因素(例如位置、便利设施或大小)向用户推荐一个挂牌价格。这个商业案例很简单;价格更好的用户不会低估他们的财产而导致收入损失,也不会高估他们的预订损失。为了让我在项目过程中保持专注,我想出了一些简短的商业目标,以便在实现最终目标的过程中回答:
- Airbnb 两个市场的价格会随季节变化吗?
- Airbnb 的哪些房源变量会对价格产生最大影响?
- 我能根据市场、设施和季节性预测价格吗?
将一项任务分解成业务问题、小目标或里程碑有助于保持专注,确保实现核心业务目标。
数据理解
现在是时候尝试一下,看看你有什么可用的数据。一个很好的起点是考虑你可能需要哪些数据点来实现你的目标,以及这个目标如何与你当前的数据保持一致。在 Airbnb 项目中,我需要我的因变量:我想要预测的价格。为了创建我的模型,我还需要我的独立变量,例如评论分数、位置、客人数量和设施。
An example of a Pandas DataFrame during the Data Understanding step
接下来,检查数据的质量是很好的。我这样做是通过寻找 NaN 的,简单的错误,并检查以确保所有的数据集可以合并。这最后一点听起来微不足道,但如果我的因变量和自变量有不同的标识符,数据将是无用的。最后,在这一点上创建最初的可视化将有助于对数据的整体理解。
Initial analysis | Distribution of Airbnb prices
上面的直方图显示了 Airbnb 各个市场的价格差异。与波士顿相比,西雅图的平均价格较低,差价较小。这表明项目后期可能需要考虑地区差异。它显示,波士顿的平均房价将远远高于西雅图的房价。
在数据中翻箱倒柜之后,你可能会发现几个结果中的一个:你已经有了执行分析所需的一切,需要更多的数据,或者项目不可行,因为所需的数据不可用。
数据准备
现在我们已经有了所有需要的数据,是时候将它处理成所有分析和建模所需的格式了。这通常是流程中最耗时的部分(60–80%的时间),并且随着数据需求的发展,可能会与任何分析/建模交织在一起。
Python photo by Chris Ried on Unsplash
首先要做的是对数据进行一些清理。这可能包括处理 NaN、格式化日期、合并文件、剥离字符串、编辑价格等等。在 Airbnb 项目的这一点上,我为清理和合并我的数据做了一些基本的功能。我强烈建议这样做,因为您可以将它们添加到一个包中,并在整个项目中多次使用它们。
Example from a basic cleaning function used on the Airbnb dataset
下一部分将取决于项目最终想要达到的目标。在进行更多清理之前,我做了一些基本分析,以了解更多关于 Airbnb 的数据。对于许多项目,将需要一些更高级的处理,尤其是执行机器学*(ML)任务。例如,对分类变量进行编码,对基于文本的数据运行 NLP(自然语言处理),或者执行 PCA(主成分分析)来降低维数。任何建模之前的最后一步是在训练和测试数据集之间分割数据,因为这允许您保留一些数据用于模型调整和评估。
系统模型化
这是大多数博客文章、研究论文和面向客户的演示会关注的部分。然而,如果你幸运的话,它最多会占用你 10-20%的时间。在这一部分,我们创建机器学*模型,有洞察力的可视化或执行投影。
在我的项目中,我做了一些分析,试图解决我的第一个商业问题:Airbnb 两个市场的价格是否随季节变化?
Seasonal trends | Seattle & Boston
季节性趋势变得相当令人惊讶,因为这两个市场全年的变化程度相似。它们在年初都有一个季节性低点,在 8 月份左右有一个高点。这种季节性变化可用于调整最终的 ML 模型,以获得全年价格的更好预测。
在上面的分析之后,我继续讨论 Airbnb 数据集的核心建模问题。为此,我进行了回归分析,根据因变量来预测上市价格。使用的回归模型是一种被称为随机森林的集合方法(这种方法的细节可以在这里找到)。模型训练如下所示:
Parameterisation of the Random Forests ML model
当优化任何形式的建模时,确保用可靠的性能指标来验证测试是很重要的。这些将根据业务案例而有所不同。在我的回归分析中,我使用了 MAE(平均绝对误差),因为它不会像 RMSE(均方根误差)等其他方法那样对较大的误差进行加权。这对于预测 Airbnb 价格很有用,因为我们更喜欢一个更通用的模型,即使一些离群值被预测错了。
Performance metrics for model parameterisation showing RMSE and MAE
模型制作和优化后,在部署任何东西之前,都需要检查、测试和评估。
估价
评估您的模型/分析是该过程中最重要的步骤之一。这是为了评估模型或见解在多大程度上可以推广到新的数据集。该过程的第一步是使用建模前搁置的测试数据,以确保模型在参数化过程中不会过度拟合。
我的模型评估的另一个重要部分是查看每个变量如何影响模型预测。这被称为功能重要性,有助于回答我的第二个商业问题:Airbnb 的哪些房源变量将对价格产生最大影响?
Feature importance of the Random Forests model
从上面的图来看,影响价格的最重要的特征是(如你所料)房产大小指标,如卧室、浴室和客人。驱动该模型的令人惊讶的特征是,该物业是否有急救箱或一氧化碳探测器;这些可能是价格较低的房产正在提升其舒适度的一个指标。执行特征重要性的另一个关键要点是,一些变量对模型有负面影响,因此应该在建模前移除。
评估建模效果的最后一步是将该过程应用于另一个市场,并观察结果的对比。对我来说,这有助于回答整个商业问题:我能根据市场、变量和季节性预测价格吗?
Actual Airbnb prices against the predicted prices
上面的结果显示了 Airbnb 的实际价格和预测价格。这条线代表完美的预测,从这条线到每个点的距离就是预测的误差。总的来说,模型很好地预测了总体趋势,除了异常值属性。这些异常值可能预订率低,或者有其他原因导致价格与趋势不符(例如 Airbnb 的质量)。总的来说,该模型可以很好地预测价格,为用户提供建议,从而实现核心业务目标。
通过查看您的模型验证指标和 KPI,您可以最终决定您是否成功实现了您的业务目标。
成果和部署
最后,是时候将你创造的一切付诸实践了。这可能是为外部流程部署一个模型(想想网飞推荐引擎),或者根据分析得出的见解调整内部流程。对于 Airbnb 项目,这将需要根据用户提供的便利设施在托管页面上执行价格建议。
Just sit back and relax! Photo by Ali Yahya on Unsplash
如果你认为项目到此结束,那你就大错特错了,在现实世界中,一旦你部署了一个项目,就会有无穷无尽的改进、更新和错误修复要处理。就结论而言,你能做的最好的事情就是希望你在所有的迭代之间得到一个新的项目来集中你的注意力!
完成流程
总之,在任何项目中要经历的主要步骤是:
- 主题理解(上下文和业务案例)
- 数据理解(收集和初步分析)
- 数据处理(准备、清理、擦洗和争论)
- 建模(建模、分析、探索和验证)
- 评估(解释、优化和评估)
- 部署(实施、改进和迭代)
上面的框架很大程度上遵循了 CRISP-DM 流程,并添加了来自其他框架的额外注释。这在很大程度上被视为执行数据科学项目的行业标准,应该为运行任何数据项目提供坚实的基础。
传统数据科学框架
这篇文章从 CRISP-DM 之外的一些数据框架中获得了灵感。这里有几个例子,如果你想谷歌一下或者进一步研究的话:
- CRISP-DM(数据挖掘的跨行业标准流程)
- KDD(数据库中的知识发现)
- OSMEN(获取、擦洗、探索、建模、解释)
- 数据科学生命周期
关于我
目前,我是 ASO Co(一家应用营销公司)的数据科学家。有关该项目的任何进一步信息或查看我在分析中的表现,请在下面找到我的各种社交平台的链接:
GitHub:https://github.com/WarwickR92/Airbnb-Market-Analysis
领英:https://www.linkedin.com/in/warwick-rommelrath-a7b4575a/
这个项目中的所有数据都是通过 Kaggle 上的 Airbnb 提供的,并与我的 Udacity 数据科学家 Nanodegree 一起使用。
跨团队分发数据项目的框架
原文:https://towardsdatascience.com/a-framework-to-distribute-data-projects-across-teams-15e2b9f9662?source=collection_archive---------21-----------------------
Photo by Ansgar Scheffold on Unsplash
介绍
当您开始一个新项目或加入一个新团队时,您将经历一系列步骤来设置您的本地环境,并准备好共享您的项目。在这篇文章中,我总结了我实现这个目标的步骤。这是我一直遵循的框架,也是我在团队中实施的框架。这是我多年经验中最有效的方法。希望能对你以后的项目有所帮助。
我假设您的团队选择的开发工具如下:
- 源代码是用 Python 写的。
- Pycharm 是构建项目的 IDE。
- 探索性分析在 Jupyter 笔记本上完成。
- Gitlab 是你的 Git 库平台。
在这篇文章中,我将简要介绍 python 虚拟环境以及如何创建它们。然后,我将解释如何将它们添加为本地 Jupyter 安装的内核。之后,我将定义启动一个项目或使用 Pycharm 从 GitLab 克隆它的步骤。最后,我将描述编写项目依赖项并将其打包的最佳方式。
Python 虚拟环境
python 的虚拟环境是 Python 应用、机器学*和数据科学项目的关键。
虚拟环境是一种工具,它通过使用特定版本的库接口为项目和系统中的其他安装创建一个隔离的环境,来帮助将项目的依赖项与它们分开。
关于详细的介绍和说明,你可以阅读 python 官方文档中的虚拟环境和包的介绍。
因此,我们采取的第一步是用指定版本的 Python 创建一个虚拟环境,并将其作为项目的解释器。
如何创建虚拟环境?
我使用“ conda ”,但是你也可以使用 python 的模块“ venv ”,这两个工具都会创建一个“环境”来隔离软件包安装。
要使用 conda 创建一个新的虚拟 env,请确保您的计算机中已经安装了它,并且 Conda 可执行文件的路径已经添加到您的系统路径中,这样您就可以从命令行访问命令- conda 。
$ conda -V
conda 4.7.12
如果您可以运行前面的命令并看到安装的版本,那么您可以继续。现在我将用 Python 3.5 创建一个名为“py35-ygroup”的虚拟环境。
$ conda create --no-default-packages -n py35-ygroup python=3.5
...
Proceed ([y]/n)? y
...
Preparing transaction: done
Verifying transaction: done
Executing transaction: done
#
# To activate this environment, use
#
# $ conda activate py35-ygroup
#
# To deactivate an active environment, use
#
# $ conda deactivate
就这样,您已经有了一个干净的 python 安装,可以使用了。我将把它作为一个内核添加到一个现有的本地 Jupyter 服务器上,以防你使用 Jupyter 笔记本,然后我将在我们的 IDE 中把它设置为项目的解释器。
将环境添加到 Jupyter 笔记本中
Jupyter 笔记本自动从您的系统中提供 IPython 内核。然而,我想在新环境中使用内核,所以我需要手动注册它。
$ source activate py35-ygroup
# you will see the name of the venv
(py35-ygroup) $ conda install ipykernel
(py35-ygroup) $ python -m ipykernel install --user --name py35-ygroup --display-name "Python3.5 (YGroup)"
如果你有一个 Jupyter 服务器运行,你可以刷新用户界面,当你创建一个新的笔记本时,你应该可以看到环境。
下一步是在 PyCharm 中设置项目和环境。有两种可能的情况:
- 开始一个新项目
- 从 Gitlab 克隆项目
开始一个新项目
在 PyCharm 中,使用现有环境创建新项目非常简单,一旦打开初始窗口,您将看到选项:
- +新建项目→项目解释器→现有解释器。
现在,您可以从之前创建的 env 中选择 Python 可执行文件,默认情况下,它应该位于 conda env 的文件夹中(或者 Anaconda,如果您通过它安装了 conda),对于我:"/Anaconda 3/envs/py35-ygroup/bin/Python "
adding a virtual environment as the project’s interpreter — PyCharm
现在,您可以开始在您已经创建的环境中工作了。在环境中安装软件包可以通过 conda 或 pip 使用 IDE 中的终端或您系统中的终端(Windows 的 CMD 或 macOS 用户的终端)来完成。确保在安装库之前已经激活了虚拟环境,否则你会将它们安装在你的根或系统 python 中。
注意:不幸的是,当 conda 和 pip 一起使用来创建环境时,可能会出现问题…在 conda 环境中通过 pip 执行安装之前,请确保您阅读了本指南:[在 Conda 环境中使用 Pip](https://www.anaconda.com/using-pip-in-a-conda-environment/),如果您在运行代码时遇到任何问题,这将有助于您了解/修复您已安装的库。
总结和共享您的项目
将库添加到项目中之后,您可以创建包含在另一台机器(比如您同事的计算机)中重新创建环境的信息的 requirements.txt 或 requirements.yaml 文件。您必须将此文件添加到项目的根目录中;从终端导航到根目录,并运行以下命令:
(py35-ygroup) $ conda env export > requirements.yml
现在您可以保存项目并通过 Git 共享它。我将在下一节讨论在虚拟环境中安装库。
从 Gitlab 克隆项目
在这一部分中,我假设您在 Gitlab 中有一个存储库来托管您的项目,在这种情况下,您可以使用 SSH 或通过 Gitlab.com 的用户/密码验证来克隆项目。我将讨论前一个,但是出于安全原因,最好还是选择第一个选项。这是一个相当快的步骤,作为一个附加说明,你可以随意命名项目,它不一定需要与你的项目在回购中的名称相同,但要使路径不被使用
您需要获得 PyCharm 连接到 Gitlab 所需的插件。转到 IDE 插件并下载以下插件:
- GitLab 集成
- GitLab 项目
安装了它们之后,你应该能够从 IDE 的启动窗口中检查 VS 的项目,点击“git”并提供你的用户名和密码。
Check out from Version Control — PyCharm
您克隆的默认分支应该是主分支。此时,您可以从 IDE 的左下角(或通过终端)更改、签出或创建新的分支,这里重要的部分是现在在本地运行项目。为此,您需要从安装在虚拟环境中的 requirements.txt 或 YAML 文件中获取所有需求,让我们将新创建的虚拟环境定义为项目解释器,然后获取需求。
按照“ 开始一个新项目 的初始指令,得到虚拟 env 作为项目的解释器。完成后,您可以从 IDE 中打开终端并开始安装依赖项。
安装需求
要重新创建虚拟环境,请导航到项目的根目录,需求文件就在那里,然后运行:
(py35-ygroup) $ conda env update --file requirements.yml
在这种情况下,存储库有一个 requirements.txt 文件,您可以使用 pip 安装依赖项,而不是运行您可以运行的前面的命令:
(py35-ygroup) $ pip install -r requirements.txt
此时,您已经准备好继续开发,直到项目准备好被共享,一旦完成,您应该更新需求文件并将变更推送到存储库。
结论
这篇文章中描述的基本步骤将使您和您的团队更容易共享项目,并且在处理分析或数据项目时也是一个很好的实践。至此,您已经学*了如何创建一个新的虚拟环境,如何使用 PyCharm 从 GitLab 克隆一个现有的项目,以及如何通过安装需求文件中包含的库来重新创建虚拟环境。
我希望这篇文章能帮助你下次进入一个新的项目,如果你有任何问题或意见,请在评论区分享,反馈总是受到欢迎:)
全栈数据科学项目
原文:https://towardsdatascience.com/a-full-stack-data-science-project-part-1-9f73a997dc4d?source=collection_archive---------5-----------------------
Photo by Chris Ried on Unsplash
我涉足数据科学已经有一段时间了——我会从 Kaggle 下载一个数据集,启动一个内核,进行探索性分析,数据清理,使用 sklearn 或 fast.ai 建立一个基线机器学*模型或神经网络,结果只是被工作分散了注意力,暂时失去了兴趣,后来又对不同的比赛或数据集重复相同的过程。
在与一些从业的数据专业人士交谈后,我逐渐意识到,虽然 Kaggle 极具竞争力,并为世界上一些顶级数据科学家的同行提供了无与伦比的学*机会,但 Kaggle 数据集始于数据科学生命周期的中间某个地方——数据收集、解释、清理、屏蔽(去标识)这些平凡但最重要的步骤都已经完成。我想建立一个数据科学项目,整合生命周期的所有方面——数据收集、清理、分析和模型构建。我还希望它能成为我学*数据科学和神经网络不同方面的平台。从而开始寻找一个“好”的数据集。
在一次与工作相关的旅行中,我在机场的一家书店浏览,我想知道是否可以围绕与书籍相关的数据建立一个数据科学项目。从一本书的导语中可以收集到什么信息?还是它的封面?当我仔细考虑这个想法时,我意识到关于一本书的其他信息,如评分、评论、描述等。进行一些实验可能也是有价值的。目标是获得从头构建模型的经验。
我将尝试遵循数据科学项目的标准工作流程,如下图所示。
经过一番研究后,我决定使用 Goodreads 作为我的数据集的来源,因为他们的书籍页面上的信息量非常全面,而且基本上是标准格式。我决定“收集”以下信息:
- 标题
- 描述
- 作者
- 版本
- 格式
- 国际标准图书编号
- 页数
- 评级
- 评级数量
- 评论数量
- 体裁
- 书籍封面图像
我举了一个 Goodreads 的书籍网页的例子,下面标注了各种信息。
An annotated image of a Goodreads page, highlighting the fields that will be extracted
在下一节中,我们将详细了解数据收集中涉及的步骤。
1.数据收集
因为我们的目标是为大量的书籍建立一个数据集合,所以我从查看这里的可用书籍列表开始。“有史以来最好的书”列表中有超过 50000 本书,我决定用它作为我的培训数据来源。为了使数据收集更容易,我将这个过程分为三个部分:
1.1 URL 集合
第一步是通过抓取图书列表来收集单个图书页面的 URL:
An example of a book “list” to be scraped.
Python 中用来从网页中收集静态数据的最流行和易用的包之一是 BeautifulSoup 。它以 Pythonic 的方式提供了对页面中各种 HTML 元素的访问。如果页面内容是使用 JavaScript 动态生成的,那么 Selenium 将是更好的选择,尽管速度较慢。幸运的是,我们分析所需的所有内容在 Goodreads 网页上都是静态的。
BeautifulSoup 包中最流行和最强大的两个方法是 find 和 find_all。只要我们可以使用标签和类来识别元素,我们就可以使用这两种方法从网页中提取几乎任何信息。我从 web 页面收集数据的方法是开始“检查”包含数据的元素,找出它在 HTML 格式中的结构。例如,在上面显示的列表中,右键单击“动物庄园”标题,然后单击“检查”,显示页面上的图书数据以表格的形式排列,并且在表格数据标签中可用,< td >:
<td width=”100%” valign=”top”>
<a class=”bookTitle” itemprop=”url” href=”/book/show/7613.Animal_Farm”>
<span itemprop=”name”>Animal Farm</span>
</a>
因此,通过访问表的每一个行中的标记,我们可以使用几行代码提取 URL:
1.2 数据收集
现在我们已经在 books.csv 文件中收集了 URL,下一步是收集文件中每本书的数据。这将是一个漫长的过程,因为抓取每本书的网页数据会耗费大量时间。我们还应该记住,服务器不应该因为我们的请求而过载,所以我们应该在请求 web 服务器之间留出足够的时间。
与 URL 收集不同,数据收集过程中的每个数据元素在 HTML 网页中都有不同的声明方式。因此,对于每个元素,我们需要弄清楚它是如何构造的,要访问哪个标签和类,以及如何提取数据用于我们的分析。我没有一个一个地遍历这些元素,而是在下表中给出了用于访问它们的 HTML 元素和一个例子。
Data attributes from the book web page and their corresponding HTML tags
用于提取这些数据的代码可在这里获得。
1.3 图像收集
下一步是收集书皮。这相对容易,因为我们已经收集了图书封面的图片 URLs 所需要的只是简单地下载它们。下面是我用 wget 包做同样事情的代码:
我也按照这些步骤收集了 2018 年最佳书籍的数据,这些数据可以在这里的列表中找到。我用这个作为我的测试数据集,来评估我在有史以来最好的书籍上收集的数据上训练的任何模型。
需要注意的一些最佳实践:
- 始终确保在向服务器请求之间留出足够的时间,以避免过载和被踢出局
- 每隔几次迭代就保存您的工作
- 并非所有数据元素在所有网页上都可用,因此在代码中包含检查以解决相同的问题
为了便于加载和使用这两个数据集,我已经将它们上传到 Kaggle。你可以在这里找到他们这里和这里。另外,用于数据收集的代码在 GitHub 上,这里是。
在下一节中,我们可以在开始进行特定的分类或预测任务之前,研究数据以了解不同的特征。
2.数据探索
探索这些数据的笔记本可以在 GitHub 这里找到。
不管您正在执行的数据分析是什么,也不管您认为自己对数据的了解程度如何,在开始进行特定的预测或分类任务之前,查看数据并了解各种特征始终是一个好主意。让我们先来看看我们收集的数据:
The first 10 rows of the training dataset (Best books ever, from Goodreads)
从数据集的初始视图来看,有几件事很突出:
- 英语不是唯一的语言——数据集中还有其他语言,这需要探索
- 一本书可以属于多个流派
让我们先来看看流派。
2.1 流派
我们应该记住,Goodreads 网站上的体裁是由用户提供的,而不是作者或出版商给出的该书的“官方”体裁。这可能导致多种类型的重复或琐碎。让我们先来看看每本书的流派数量分布。
我们可以看到,书籍的平均数量在 5 到 6 本左右,分布有点右偏。下一个问题:有多少独特的流派,哪些是最常出现的?
数据集中有多达 866 个独特的流派!我认为这是因为它们是由用户提供的,并且许多流派可能会重复拼写错误。不管怎样,让我们看看数据集中的热门流派:
即使在前 50 名的榜单中,似乎也有相当长的流派尾巴。有趣的是,与小说(约 26K)相比,非小说类书籍的数量相当低(约 7.5K)。这些类型中的大多数都属于小说类(幻想、浪漫、青少年和不同类型的小说,如科学、历史、女性、现实等)。书的封面反映了一本书被标记的类型吗?让我们检查一下。
2.2 书籍封面
我随机抽取了一些书籍封面样本,并检查了它们所标注的类型:
据我所知,仅仅从书的封面来分类一本书的类型是很困难的。当然,在某些情况下,我们可能知道作者以前的作品(例如斯蒂芬·金的《恐怖片》),并且可以猜测其类型,但是孤立的书籍封面似乎不能提供足够的信息来确定类型。
经过进一步的研究,我发现这是一篇研究论文的主题,题为“通过封面来判断一本书”,可在此处获得。该论文的作者在他们的任务中确实取得了一些成功,但是指出:
许多书的封面图像具有很少的视觉特征或模糊的特征,导致许多不正确的预测。在揭示 CNN 发现的一些设计规则时,我们发现书籍也可能有误导性的封面。此外,因为书籍可以是多种体裁的一部分,CNN 在榜首的表现很差。
了解到目前为止我们收集的关于书籍封面的信息,它们可能不会成为我们分析的一部分。让我们继续讨论下一个参数:语言。
2.3 语言
我们对数据集的初步了解告诉我们,我们的列表中包含了一些非英语书籍。让我们看看数据集中所有可用的不同语言。
langdetect 包帮助找出一段给定文本的语言。这对于通过使用图书的描述(代码如下)来确定数据集中可用的图书的不同语言非常有用:
绘制每种语言的图书数量,我们可以看到几乎 90%的图书是英文的:
出于我们的分析目的,我们可以删除对应于非英语书的记录。然而,出于好奇,让我们检查一下数据集中非英语书籍的数量:
相当多的欧洲语言出现在这个列表中。我也对这里有相当多的印度语言这一事实感兴趣。来自印度钦奈,我想知道哪些泰米尔书籍是有史以来最好的书籍的一部分:
Ponniyin Selvan ,被认为是有史以来最伟大的泰米尔小说,出现在这个名单上!很高兴知道:)
后续步骤
探索这些数据帮助我们认识到,试图从书籍封面预测流派可能不是一个很有成效的练*(我也可能是错的!).我会试着用这本书的描述来预测流派。这可能是一个相当琐碎的任务,但它肯定会有助于理解如何从头构建一个递归神经网络,并为其准备数据。关于流派另一个需要注意的点是,独特流派的大量存在使得它成为一个非常难以预测的目标参数。通过对数据进行相应的预处理,将一本书分类为小说或非小说是有意义的。我将在接下来的小节中介绍这些步骤。
3.数据清理
尽管 Goodreads 上可用的数据在很大程度上是结构化和格式化的,但数据集仍有一些问题需要解决。因为我们分析的感兴趣的数据是书的描述和相关的类型,这些是我遇到的问题:
- 有些唱片没有任何流派
- 一些记录没有有效的描述
- 一些唱片的标签类型列表中既没有“小说”也没有“非小说”
- 正如我们前面看到的,一些记录有非英语的描述
- 一些图书描述有不可打印的字符和格式问题
发现这些问题需要反复试验,尤其是格式问题,需要仔细检查描述本身。尽管如此,我还是为上面提到的每个步骤编写了助手函数,并通过训练和测试数据集运行它们:
似乎有相当数量的唱片被丢弃了,因为它们被贴上了既非小说也非非小说的标签。当我检查这些记录时,我发现要么是因为用户没有给它们加标签,标签就不见了,要么是因为它们属于中性类别,比如诗歌等等。
4.数据预处理
既然我们已经处理了数据中尽可能多的问题,我们应该准备好将数据输入到模型中。实现这一点的第一步是确保所有输入模型的数据都是相同的格式和长度。自然,所有书籍的描述都有不同的长度。我们如何确定输入神经网络模型的描述的最佳长度?
4.1 剪辑和填充
我将假设,如果我们能够在一定长度(即字数)内容纳至少 80%的图书描述,那么我们的模型应该表现得相当好。为了确定这个长度,让我们绘制一个训练数据集中描述长度的累积直方图:
如果你将鼠标悬停在上图中的条柱上,你可以观察到大约 80%的记录字数在 207 字以下。让我们把最大阈值字数定为 200。这是什么意思?这意味着对于描述少于 200 个单词的记录,我们将用空值填充它们,而对于描述多于 200 个单词的记录,我们将对它们进行裁剪,只包含前 200 个单词。除了最大阈值,我们还需要一个最小阈值来确保描述至少有几个词来实际预测流派。
4.2 标记化
与递归神经网络相关的标记化是指将事物序列(无论是字符还是单词)转换为整数序列的过程。这仅仅意味着,对于我们跨训练和测试数据集的描述语料库中的每个单词,我们分配一个整数,我们将称之为“令牌”。因此,神经网络的输入将是代表形成描述的单词的符号序列。
Keras ,由Fran ois Chollet开发的令人敬畏的深度学*库,有一个预定义的方法来标记序列。然而,我想自己构建标记化器只是为了好玩。标记化的第一步是建立描述中所有可用单词的词汇表。一旦这个词汇表可用,分配标记就是一个简单的任务,即引用词汇表中单词的索引。在标记化的过程中,我们还可以进行之前看到的裁剪和填充。关于填充,有几点需要注意:
- 因为我们将使用整数零进行填充,所以在词汇表中不要给这个令牌分配任何单词是很重要的。
- 递归神经网络将从左到右阅读令牌序列,并输出一个预测,判断该书是小说还是非小说。这些标记的内存被一个接一个地传递给最终的标记,因此,对序列进行预填充而不是后填充是很重要的。这意味着零添加在令牌序列之前,而不是之后。存在后填充可能更有效的情况,例如在双向网络中。
下面给出了我用来将描述标记成固定长度的整数序列的代码。
4.3 训练和验证数据集
虽然创建训练和验证集是一个相当标准的过程,但当数据集不平衡时,即目标变量的分布不均匀时,我们应该确保训练-验证分裂是分层的。这确保了目标变量的分布在训练和验证数据集中得到保留。
5.模型开发
下一步是建立一个递归神经网络来处理符号化的描述,并将它们分类为小说或非小说。为此,我使用 Keras 库构建了一个顺序模型。Keras 是目前可用于神经网络开发的最佳 API 之一,尤其以其用户友好性和易于理解的结构而闻名。
我在顺序模型中使用的层如下(按此顺序):
5.1 嵌入
在我们进入嵌入层的细节之前,让我们看看为什么它在这种情况下是有用的。我们前面看到,我们构建了描述中所有可用单词的词汇表,并将描述转换为标记序列(整数)。现在,这些整数不能以原始形式传递给神经网络,因为这些整数的大小实际上没有任何意义。例如,对应于令牌 1 的单词是“gremlin ”,而令牌 2 的单词是“collaborated”。这并不意味着“合作”是“小淘气”的两倍。那么,我们该怎么处理呢?
这种变量称为分类变量,通常通过一键编码传递到机器学*模型中。例如,如果我们的词汇表中有 5 个单词,我们将它们标记如下:
[outbound, hearse, select, dogged, rowboats][1, 2, 3, 4, 5]
其中出站对应 1,灵车对应 2,以此类推。这种标记化表示的独热编码版本应该是:
outbound: [1, 0, 0, 0, 0]hearse: [0, 1, 0, 0, 0]select: [0, 0, 1, 0, 0]dogged: [0, 0, 0, 1, 0]rowboats: [0, 0, 0, 0, 1]
因此,每个单词都由一个向量来表示,向量的长度是词汇表中单词的总数。如果类别的数量很少,这种分类变量的表示很有效。在我们的例子中,类别的数量实际上是我们的词汇中独特单词的数量,超过 90000 个。如果我在数据集中的每条记录中有 200 个单词,这意味着我的数据集变成了一个 n90000200 张量,其中 n 是记录的总数。当有太多类别时,独热编码的另一个问题是表示变得太稀疏,即,与矩阵中的 1 相比,有太多的 0。一些算法可能不能很好地处理稀疏表示。因此,我们需要一种替代的方式来表示我们的输入。这就是嵌入的用武之地。
简单地说,嵌入层“学*”每个输入类别的固定长度数字表示。嵌入向量的长度可以由用户决定。一般来说,更长的嵌入能够学*更复杂的表示。在我们上面看到的例子中,假设我们训练长度为 10 的嵌入层,训练后得到的嵌入向量可能如下所示:
因此,如果我们训练一个长度为 200 的嵌入层来表示我们的词汇,该层有效地将输入的维数从 n90000200 减少到 n200200。这使得计算变得容易得多,我们的表现也更加密集。
5.2 叠 LSTM
我们模型的下一层是递归神经网络的核心——LSTM(长短期记忆)层。简而言之,无论序列有多长,LSTM 层通常都会保留记忆。它能记住多少是基于输入序列和目标变量之间的关系来学*的。在我们的例子中,我们将长度为 200 的序列传递给 LSTM 层。在序列中的每个字处,LSTM 层产生一个输出状态,该输出状态被传递到下一个字,并且如果需要的话,可选地产生一个隐藏状态,该隐藏状态被传递到另一个 LSTM 层。起初我发现 LSTM 的概念非常复杂,但是克里斯多夫·奥拉的这篇文章很好地解释了这个概念:
[## 了解 LSTM 网络——colah 的博客
这些循环使得循环神经网络看起来有点神秘。然而,如果你想得更多一点,事实证明…
colah.github.io](http://colah.github.io/posts/2015-08-Understanding-LSTMs/)
在我们的例子中,我使用了一个两层 LSTM,其中第一层产生一个隐藏状态序列,该序列被传递到第二层。
5.3 完全连接
全连接(也称为“密集”)层获取 LSTM 层的输出,并通过 sigmoid 激活将输入压缩为 0 到 1 之间的数字,将其映射到单个目标变量。
为了更好地理解,下面给出了网络架构的直观表示:
下面给出了创建顺序模型的代码。
Keras 给出的模型摘要:
6.模型评估
最后一步是训练我们的模型,根据验证集进行评估,并用我们的测试数据集进行测试。该模式能够在具有 2 个时期的训练的验证集上实现超过 90%的准确度,并且在测试数据集上实现大约 95%的准确度。
Train on 23393 samples, validate on 5848 samples
Epoch 1/2 23393/23393 [==============================] — 162s 7ms/step — loss: 0.3532 — acc: 0.8542 — val_loss: 0.3033 — val_acc: 0.9020
Epoch 2/2 23393/23393 [==============================] — 160s 7ms/step — loss: 0.1660 — acc: 0.9393 — val_loss: 0.2347 — val_acc: 0.9152
657/657 [==============================] — 13s 19ms/step
[0.14756220990516913, 0.9482496194824962]
结论
所有用于数据收集、探索和模型开发的代码都可以在 GitHub 上找到,网址是:
[## meet naren/Goodreads-图书-分析
根据简介或描述将一本书分类为小说或非小说的数据科学项目…
github.com](https://github.com/meetnaren/Goodreads-book-analysis)
我还尝试在 PyTorch 这里复制模型开发。PyTorch 可以更好地控制数据如何进入网络,并允许我们定义构成网络转发的操作。对于像本文中描述的简单序列模型,Keras 是一个很好的选择。
一个全职 ML 角色,100 万博客浏览量,10k 播客下载量:一个社区教授 ML 工程师
原文:https://towardsdatascience.com/a-full-time-ml-role-1-million-blog-views-10k-podcast-downloads-a-community-taught-ml-engineer-96f99b91c5ee?source=collection_archive---------14-----------------------
快速回顾一个社区教授 ML 工程师的旅程。
里程碑和全职工作
2019 年 10 月 15 日标志着一个特殊的里程碑,实际上是相当多的里程碑。所以我考虑以博客的形式分享它,在一个出版物上,这是我所有帖子的家:)(注意:这最初是在 HackerNoon 上发布的)
网络社区对我太好了,这些博客帖子成了我和那些我通过 slack 小组认识的了不起的人庆祝任何或大或小的成就的一种方式:KaggleNoobs,ODS。AI、TWiMLAI、数据科学网、fast.ai 论坛甚至 Twitter 以及分享我的失败,未经过滤,尽管用手挠我的后脑勺,但这个令人惊叹的社区仍然对我太好了,即使在我失败了我最大的一次梦想面试时。
因此,如果我不分享我最终在“人工智能”领域的领导者之一获得了一个惊人的全职机会,这将是很不礼貌的。公司肯定不需要介绍了,这里就略过赞了。
在我写这篇文章的时候,我将开始在 H2O.ai 做一名全职的机器学*工程师和 AI 内容创作者。尽管全职工作是我一直向往的,但我还是很难接受这个事实。另外,鉴于我的博客帖子以及柴时间播客所取得的一些其他里程碑式的成就,我真的很兴奋,也非常感谢 ML 在线社区,它一直对我非常热情和友好。
我想这篇文章也可以让我快速回顾一下我的旅程,正如你可能知道的,我一直乐于通过这篇博客公开记录我的失败和成功,目的是留下一个公开的旅程记录,这样任何和我处于类似情况的人都可以从这些文章中受益,不会重复我的错误。
里程碑之前的旅程:)
旅程
在我的前一篇标志着几个里程碑的帖子中,我已经与谷歌人工智能驻地的分享了我的拒绝,但甚至在那之前,当我去互联网上寻找更多有趣的想法和“最新”的大学学*主题时,我的旅程才真正开始。我想,要么我可以抱怨大学教学大纲太过时,与行业不同步,要么我可以出去搞清楚这个行业实际上是什么,什么是“机器学*”,什么是“模型”。你可以想象这个列表。
我参加了网上课程,在我还在上大学的时候就参加了相当多的网上课程。然后在 9 月 29 日。我从地球的另一边收到了这封邮件,我记得我在凌晨 4 点读了它(是的,我醒得很早,然后我做的第一件事就是有时读邮件)
这一直是我最亲爱的“证书”有趣的事实,在“柴时间数据科学”工作室:
这是现存的唯一一份装裱好的打印件。虽然我不确定它是否会出现在那里的 RGB 娱乐中。
这让我进入了另一个探索周期,因为杰里米是我遇到的最好的教授。我结束了花大量时间“观看”课程的生活。回想起来,这些钱应该花在编码和“训练大量模型”上(杰里米的顶级建议,来自 Lex Fridman 的《神奇的人工智能》播客)
与此同时,我鼓起勇气访问了 kaggle dot com(我想强调一下 dot,听起来更好,不是吗?)有一两次,我确信我应该投资一台“DL 笔记本电脑”(因为我还在上大学,所以不可能买盒子)。这本身就导致了论坛上一长串的讨论和我终于在 2018 年底开始使用 Kaggle。此外,我需要一大笔钱来买笔记本电脑,所以我又开始上网,因为我还有一年的大学时间,我不能在大学期间做“工作”。我的“自由职业者”/合同工就是这样开始的。
新年伊始,我收到了一封来自谷歌的邮件,让我大吃一惊。我进入了人工智能住院医师面试的最后一轮,然后被拒绝了。当这封信送达时,我已经勾掉了我的几个“2019 年决心”。
- 成为 Kaggle 专家
- 创建一个好的 Kaggle 内核
- 每周写一篇博客:)
- 实现一些文件。
所以我决定花些时间在社区里,心中没有最终目标。我真的想回馈社区,因为我已经大学毕业,我有时间和许多了不起的人交谈,并通过 slack 提供帮助,主持学*小组甚至研讨会。
第一份“远程工作”,社区活动
到了四月底,我有了一次惊人的求职面试经历。
我通过他们的社区工作认识了一个了不起的人: Aakash N S 发布了他们公司的一个职位。于是我 pinged 了他们,有了最酷的面试体验。一个 45 分钟的视频电话,而不是一个关于责任和我的长期目标的友好讨论。下一个电话是入职电话。
等等,让我理解一下。
我提到那个 fast.ai 社区就是这个意思,真的很神奇。由两位 fast.ai 研究员( Aakash N S 和 Siddhant Ujjain )创建的一家公司在另一个城市遇到了另一位 fast.ai 研究员,经过一场小讨论后,他们邀请他在同一个团队工作。多牛逼啊!
该公司名为 Jovian.ml,真正建立在几个 fast.ai 哲学之上,这确实是一个天然的契合点,但创始团队的社区努力和 kaggle 的目标确实与我和整个董事会相呼应。因此,团队让我远程兼职工作,这样我也可以在 Kaggle 和社区工作上分配时间。
我最自豪的时刻之一是为印度最大的社区之一:数据科学网络做出了贡献,并组织了印度最大的 KaggleDaysMeetup 之一。
博客
fast.ai 最令人惊讶的一个方面是强调将博客作为投资组合或项目建设练*。整个社区甚至杰瑞米·霍华德本人都非常强调博客,这就是我开始写博客的原因。
有一次,我邀请了我的几个朋友: Dominic Monn 和 Tuatini GODARD 采访他们的旅程,因为他们两人在回答我的愚蠢问题时给了我很大的帮助,他们的旅程对我很有启发。这些采访很受社区欢迎,所以接下来我来到了一个十字路口:
要么我继续尝试技术文章,解释 CNN、LSTM、Transformer 等概念。或者真正专注于分享这些采访,因为我觉得这是社区中真正缺失的。所以我选择把创建教程和帖子的工作留给比我更聪明更有智慧的人,比如“4 分钟 PyTorch 基础知识”,并接触了大量我真正钦佩的“机器学*英雄”。
我仍然不相信是怎么回事,但这导致了 25 次博客采访。
尽管这很可怕,因为我正稍微远离分享工程和代码遍历,这是对我的期望,对于我渴望的数据科学和 ML 的角色,但我仍然坚持采访系列。
现在我已经毕业,找到了更多的带宽,我决定重新开始这个系列,但这次是以播客的形式:视频、音频和博客格式。
我想澄清一点,我从来没有将这些帖子货币化,我也从来没有打算这样做,我也没有期望柴时间数据科学播客是一个“商业”,它对我来说是一个新的媒介,作为一个媒介(太元了,不是吗?)通过 3 种不同的格式分享这些故事,以真正允许社区所有选项来消费这些“我的机器学*英雄”的惊人故事
柴时间数据科学播客
再次与播客,我在一个有趣的十字路口,我选择发布视频,音频采访,处理编辑(最费力的任务),采访和发布。
因为我真的很喜欢这些面试,所以我选择通过终止一些自由职业者的合同/协议来腾出时间,并决定在几个月内放弃 90%的收入,专注于让这些令人惊叹的旅程变得更容易实现。我真的很感谢木星的团队,让我继续播客,同时也在为“木星”工作。事实上,Aakash 还好心地设置了一个 Zoom 账户,通过这个账户进行采访。没有这一点,就不会有第一批采访或电话。
我真的很享受这个过程,现在能够和我的 ML 英雄们聊上一两个小时。播客电话真的是我做过的最好的活动之一。尽管这也让我在 Kaggle 竞赛和练*更多编码之间做了一个权衡,但我还是设法每天挤出几个小时来练*编码。我想我真的坚持了蒂姆·德特默给应届毕业生的建议:“你有时间。放轻松,享受过程,享受学*。总有一天,你的任务会变得重复,所以慢慢来,理解你的激情。我真的很高兴我做到了:)
里程碑
我真的想分享三个里程碑,几个我从未真正期望会发生的点:
我的博客点击量达到了 100 万次。
对,100 万!想象一下,开始一个在线课程建议的活动,一个在线社区教你的活动,然后能够与这么多人分享!
我非常感谢 Hackernoon 热情地接受了我的所有采访和所有帖子,也感谢 David(Hackernoon 的首席执行官)在我试验性帖子的最初几天给了我很多反馈。
我不会分享任何写博客的建议,而是分享我用过的最好的一个。
这是我每篇文章的指导方针。
我也非常感谢每一个阅读我的帖子的人,特别是那些“机器学*英雄”,他们友好地与一个刚刚开始旅程的新手分享了他们的旅程。
10k 播客下载
柴时间数据科学上线 1.5 个月后下载量达到 10k!我不是一个播客,也不是一个好的统计人员,但这对我来说是一个巨大的数字,我真的很高兴播客作为一种媒体达到了很多观众,并分享了这些伟大的故事,建议。我希望继续保持我带来的疯狂的发布时间表。
另一个疯狂的事实,柴时间数据科学,在写作的时候,已经流过 80 个国家。什么!?
我真的很喜欢互联网(或者只是它上面的 ML 社区:)
Fast.ai
我把旅途中最精彩的部分留到了最后一节。😃
在我上面提到的所有统计数据中,这可能是我最自豪的一个,甚至可能超过我的 Kaggle 等级(也许)(尽管我想完全指出,所有的 Kaggle“奖牌”或“等级”都是由于我在一个团队中有机会遇到和工作令人惊讶的 kagglers,所以如果没有我有机会与之合作的令人惊讶的人,我完全不可能实现它们。我不是一个聪明的 kaggler,我也不会假装聪明,但我绝对相信 Kaggle 是一个很好的学*平台,也是数据科学的真正家园,我认为我不能再强调这一点了)
亲爱的 fast.ai 团队:杰瑞米·霍华德、瑞秋·托马斯和西尔万·古格,还有 fast.ai 一家,(这是一个我喜欢称之为家庭的在线社区)。自学或社区教育的一个方面是,我的教育只能和社区的资源和建议一样好。
在我之前的帖子中,我并没有很不幸地真正感谢 fast.ai 团队,但最终得到了一份梦寐以求的工作,这是我做梦都不敢想的(又太元了?)我想我终于可以把我的成就归功于 fast.ai 课程、图书馆和社区了。
我学到的很多东西:在 kaggle 上竞争、博客、软件工程和深度学*,甚至是一些小事情,比如如何阅读论文、如何筛选数学方程,不要迷失在希腊语中,而是找出代码。我能够做的这些事情,在某种程度上或者更大程度上,都要归功于我通过 fast.ai 体验获得的曝光率。我承认我可能不是最好的学生,因为我还没有完成 swift for TF 课程,尽管我已经在 swift 上写了几篇博文,我还没有观看 V2 演练,所以我可能不是 fast.ai 全球课堂上最真诚的学生。然而,我真的真的很感谢杰瑞米·霍华德、瑞秋·托马斯、西尔万·古格和所有我在论坛上认识的了不起的人。
我还想指出的是,像 Kaggle 这样的东西在课程中被轻描淡写地强调了,所以它不是我提到的所有上述要点的必经之路,你可能还需要做功课。但正如他们所说,核能是由铀产生的,而不是发生的副产品,我认为 fast.ai 是这种连锁反应的铀,如果你正确地遵循,你可能会获得惊人的结果!😃
然而,如果我没有加入 KaggleNoobs 社区、DSNet、ODS,这对我来说是不可能的。AI 和 TWiMLAI 也是。所有这些对我来说都是一个惊人的学*点,尽管我没有参与太多的对话或最新的论文讨论,因为我已经承诺了播客的发布时间表。然而,我真的很感激这些社区和他们中的每个人对我的欢迎。(同样,我是通过 fast.ai 论坛发现这些的:)
最后,我要提到,当我说“在线或社区或自学”(我更喜欢这三个词之外的社区教育)时,我确实遵循并追求了传统的 CS 本科学位,我所有的在线学*都是从那里开始的。但是,我对机器学*世界的了解(非常少)真正归功于在线资源。我只从事我真正喜欢教学大纲的大学课程,并真正浏览了其他课程,我不知道为什么,但我确实获得了“IET 奖”,正如他们所说,“这是由大学提供给他们最优秀的学生的”。我给大学里任何人的唯一建议是,追随你的激情,不要害怕寻求帮助,无论是在线还是离线。
我在机器学*旅程中的下一个角色和下一部分
从页面https://www.h2o.ai/team
我非常幸运,也非常兴奋能够在 H2O.AI 开始全职担任“机器学*工程师和人工智能内容创作者”。
这绝不是将我归类为专家,该公司本身就是许多令人惊叹的 kagglers 和世界顶级数据科学家的家园,我对我旅程的下一部分感到非常兴奋,并准备了解更多。
多亏了互联网, fast.ai 和在线 ML 社区定义了我的道路,并特别感谢我的父母,他们同意了这个完全疯狂的计划,甚至在播客最初增长缓慢时支持了我,或帮助我开始使用我的第一个 GPU,甚至在我选择退出大学校园实*时更早,因为他们大多数人都是全栈角色,我真的想转而 Kaggle(对任何竞争数据都没有经验 科学竞赛)并花时间学*在线课程,尽管这个计划听起来很疯狂(我的父母支付了我的大学费用,甚至是我追求的在线课程),但我的父母一直是最支持的。 我的母亲更是如此,她总是忍受着一个儿子,他经常在一个房间里呆上几天,在一个产生高电气噪音的 GPU 环境中喝下数不尽的茶。
我将继续通过 Hackernoon(和 Medium)的博客分享我的旅程,不加过滤,定期发布。感谢所有和我一起经历这个奇妙旅程的人。
你可以在推特上找到我@ bhutanisanyam 1
订阅我的时事通讯,获取深度学*和计算机视觉阅读的每周精选列表
10 分钟内一个功能齐全的聊天机器人
原文:https://towardsdatascience.com/a-fully-functional-chatbot-in-10-mins-8ecd69dff789?source=collection_archive---------23-----------------------
聊天机器人很酷,没有什么比在 10 分钟内制作一个聊天机器人更令人满意的了。我们也对最佳实践感到非常兴奋。因此,尽管这篇文章是针对第一次构建聊天机器人的人,但即使是有经验的开发人员也会带回家一些好东西。就这样,让我们以菜谱的方式进行构建…
Sanbot King Kong for hospitality By QIHAN Technology — Own, CC0, https://en.wikipedia.org/w/index.php?curid=55094935
— — — — 如何制作聊天机器人 — — —
先决条件:
你肯定需要一个烤箱,在这种情况下,这是你的 Azure 订阅(https://azure.microsoft.com/en-us/free/)
配料:
- 写 Python 代码的地方。我正在使用 Visual Studio 代码(https://code.visualstudio.com/)看看 Visual Studio 安装和入门的评论部分。
2.Azure 中的 QnA Maker 服务
3.Azure Bot 服务版本 4
说明:
步骤 1: 让我们为 python 设置虚拟环境。python 虚拟环境只是一个自包含目录,其中包含特定版本的 python 安装和项目/程序/模块所需的相关库。
Python Virtual Env set up in VS Code
命令:
来自项目根文件夹
mkdir 虚拟 _ 环境
光盘。\虚拟环境\
python -m venv 聊天机器人 _env
set-execution policy-Scope Process-execution policy Bypass(特定于 Windows 的命令)
。\ chatbot _ env \脚本\激活
第二步:接下来,我们需要建立 QnA Maker 服务。QnA Maker 是一个基于云的 API 服务,在您的数据上创建一个对话、问答层[1]。
QnA Maker 使您能够根据半结构化内容(如常见问题解答(FAQ)URL、产品手册、支持文档和自定义问答)创建知识库(KB)。QnA Maker 服务通过将用户的自然语言问题与知识库中 QnA 的最佳答案进行匹配,来回答用户的自然语言问题。逐步指南可参考以下文件:
[## 设置 QnA Maker 服务— QnA Maker — Azure 认知服务
在创建任何 QnA Maker 知识库之前,您必须首先在 Azure 中设置 QnA Maker 服务。任何人有…
docs.microsoft.com](https://docs.microsoft.com/en-us/azure/cognitive-services/QnAMaker/how-to/set-up-qnamaker-service-azure)
create a QnA Maker service from Azure Portal
提示:为这个项目创建一个资源组[2],并将与本练*相关的所有内容放入其中,这样您就可以从资源组管理与这个项目相关的所有内容。
您还可以使用 azure 资源管理器模板(JSON 格式的)[3]来自动化部署。
部署完成后,您将能够看到 Azure 为您创建所需的资源。平台即服务不是很有魅力吗?
QnA Maker Deployment Summary from Azure Portal
第三步:现在我们需要建立知识库。QnA Maker 知识库[4]由一组问题/答案(QnA)对和与每个 QnA 对相关联的可选元数据组成。
关键知识库概念:
问题:问题包含最能代表用户查询的文本。
答案:答案是当用户查询与相关问题匹配时返回的响应。
元数据:元数据是与 QnA 对相关联的标记,表示为键值对。元数据标签用于过滤 QnA 对,并限制执行查询匹配的集合。
您可以根据自己的内容(如常见问题解答或产品手册)创建 QnA Maker 知识库(KB)。
在这里,我将使用 https://azure.microsoft.com/en-us/free/free-account-faq/的来构建一个聊天机器人。
使用您的 Azure 凭据登录qnamaker . ai门户,然后按照下面文档中的逐步指导进行操作:
[## 创建、培训和发布知识库— QnA Maker — Azure 认知服务
您可以根据自己的内容(如常见问题解答或产品手册)创建 QnA Maker 知识库(KB)。QnA 制造商…
docs.microsoft.com](https://docs.microsoft.com/en-us/azure/cognitive-services/QnAMaker/quickstarts/create-publish-knowledge-base)
QnAMaker.ai portal
QnAMaker.ai portal create knowledge base step 1
QnAMaker.ai portal create knowledge base step 1_1
QnAMaker.ai portal create knowledge base step 1_2
QnAMaker.ai portal create knowledge base step 1_3
我们有一个包含 101 个 QnA 对的初始知识库,需要保存和训练。当然,我们可以修改和调整它,使它更酷。
QnAMaker.ai portal create knowledge base step 2
QnAMaker.ai portal create knowledge base step 2_1-> Save and Train
一旦我们完成了培训,就该测试QnA 制造商了。
QnAMaker.ai portal create knowledge base step 3_1-> Test
我们还可以检查测试响应,选择最佳答案或添加备选措辞进行微调。
QnAMaker.ai portal create knowledge base step 3_2-> Inspect Test results
现在是时候发布知识库了。您需要从门户网站中点击“发布”选项卡。
当您发布知识库时,知识库的问题和答案内容会从测试索引移动到 Azure search 中的生产索引。
QnAMaker.ai portal create knowledge base step 4_1-> Publish
QnAMaker.ai portal create knowledge base step 4_2-> Publish wait for completion
QnAMaker.ai portal create knowledge base step 4_3-> Service deployed/published
在我们继续创建聊天机器人之前,让我们接下来以编程方式调用 qnamaker。
Python 程序调用并测试 qnamaker。代码出现在这里:https://github.com/RajdeepBiswas/Ten_Minute_ChatBot_Python,解释和设置过程起草如下,作为主要文章步骤的一部分。
第 4 步:密钥、密码和秘密不能在众目睽睽之下…让我们建立一个配置文件来保存我们的 python 项目的秘密和密钥。
我们将从 qnamaker.ai 服务发布页面的 curl 部分获取值。
Get the config values from QnAMaker.ai portal
根据上面的值设置 config.py 文件。不要忘记放置 init。py 使配置文件可调用😊
config.py file to store the secrets
init.py file to make the config referable
现在,我们已经做好了配置准备。
提示:不要忘记将 config.py 包含到。gitignore 如果你想把代码放到 github 里。
文件可在以下位置找到:
[## RajdeepBiswas/Ten _ Minute _ ChatBot _ Python
在 GitHub 上创建一个账号,为 RajdeepBiswas/Ten _ Minute _ ChatBot _ Python 开发做贡献。
github.com](https://github.com/RajdeepBiswas/Ten_Minute_ChatBot_Python/tree/master/secret_keys)
第五步:现在我们需要编写客户端 python 程序。这里用到的程序可以在 github 中找到:https://github . com/RajdeepBiswas/Ten _ Minute _ ChatBot _ Python/blob/master/call _ qna . py
Call QnA maker from python code
第六步:终于到了创建聊天机器人的时候了……哇呜!!!
在 QnAMaker.ai 门户的服务部署页面点击创建聊天机器人。这一步将把您重定向到 Azure 门户,您需要在那里创建 Bot 服务。
Create bot from QnAMaker.ai portal
Azure portal create bot service
如果存在资源提供者注册错误,可以通过多种方式解决。
这里,我在 Azure cli 中使用了以下命令:
az 提供者注册—微软命名空间。僵尸服务
create bot error resolution
有关更多信息,请参考:https://docs . Microsoft . com/en-us/azure/azure-resource-manager/resource-manager-register-provider-errors
然后刷新 Azure 门户页面以创建聊天机器人:
Azure portal create bot service
点击“创建”后,将会有一个自动验证步骤,然后将会部署您的资源。
Bot service deployment
Bot service deployed
部署完成后,转到 azure portal 中的 webapp bot。
Web App Bot
现在,让我们在网络聊天中测试我们的机器人:
Test in Web Chat
奖励环节:你可以把你的机器人连接到不同的频道。
通道是机器人和通信应用程序之间的连接。您可以配置一个 bot 来连接到您希望它可用的频道。通过 Azure 门户配置的 bot 框架服务将您的 bot 连接到这些通道,并促进您的 Bot 和用户之间的通信。你可以连接到许多流行的服务,如 Cortana,Facebook Messenger,Kik,Skype,脸书,丨t丨e丨l丨e丨g丨r丨a丨m丨s丨,Twilio,Slack 以及其他一些服务。网络聊天频道是为您预先配置的。更多信息可以在这里找到:https://docs . Microsoft . com/en-us/azure/bot-service/bot-service-manage-channels?view=azure-bot-service-4.0
Connect bot to channels
如果你已经成功地做到了这一步,我肯定会认为你未来探索人工智能机器人开发的旅程将会更有收获,更顺利。请让我知道你的任何问题或意见。
参考文献
[1]
“QnAMaker”,2019 年 4 月 4 日。【在线】。可用:https://docs . Microsoft . com/en-us/azure/cognitive-services/qna maker/overview/overview。
[2]
“资源组”,[在线]。可用:https://docs . Microsoft . com/en-us/azure/azure-resource-manager/resource-group-overview # resource-groups。
[3]
“模板-部署”,[在线]。可用:https://docs . Microsoft . com/en-us/azure/azure-resource-manager/resource-group-overview # template-deployment。
[4]
“知识库”,2019 年 6 月 4 日。【在线】。可用:https://docs . Microsoft . com/en-us/azure/cognitive-services/qna maker/concepts/knowledge-base。
东京铁路系统外国人指南
原文:https://towardsdatascience.com/a-gaijins-guide-to-the-tokyo-train-system-ce64fe0d1148?source=collection_archive---------13-----------------------
Every day, millions of Japanese use public trains to commute in and around Tokyo. With the 2020 Olympics right around the corner, this number is expected to increase significantly with the sudden influx of millions of international spectators. What can data about Tokyo’s public transportation tell us about the world’s most efficient and complex system? And can we find ways to improve the system such that it can operate just as efficiently at much higher capacities?
东京地铁系统是一个物流奇迹。东京这座城市大约有 1400 万人口,是一个繁忙的国际商业中心,是许多年轻日本工人的目的地,也是 2020 年奥运会的举办地,因此它很少睡觉。有这么多的人试图在城市里移动,一个高效的公共交通系统是至关重要的。东京创造了,可以说是世界上最好的(也是最广泛的)。以铁路为主要交通工具,东京发展了一个庞大的系统,由独立拥有和运营的铁路线和汽车组成的互联网络组成,能够每天运送大约 2000 万乘客。
面对如此惊人的庞大数字,我认为分析东京最受欢迎的运营商之一东武铁路公司会很有意思。数据是通过东京公共交通 API 的开放数据挑战获得的,这篇文章的全面分析可以在我的 GitHub 页面找到。虽然分析的数据只是整体运营的一小部分,但它确实揭示了日本铁路行业的真实规模,以及我们外国人如何更有效地利用火车为我们的旅游服务。
列车容积
最初,数据被清理是为了显示一天中有多少列车在东武线上运行。重要的是要记住,不是所有的列车都是一样的,所以列车的类型是作为一个额外的维度添加到分析中的。下图显示了日本铁路每天运行的数百万辆列车,不仅强调了总数,还强调了类列车的数量。
这张图表告诉我们的是,在早上 7-9 点和下午 5-7 点之间,火车的总数达到了每天的最高水平。这是有道理的,因为这些窗口是在早晚高峰期间,数百万日本上班族和女性上下班的时候。此外,半特快列车只在早高峰运行,直到晚高峰前才再次启动。这表明它们的目的是在高峰时段帮助人们涌入东京附*的车站。
晚上 8 点到 10 点的高峰也很有趣,因为它凸显了一种日本文化现象。日本员工应该在老板离开后离开,一旦他们离开办公室,同事们应该聚在一起喝酒和吃饭。典型的日本工薪族通常要到晚上 10 点以后才回家(关于日本的工作文化是否与该国不断下降的出生率有任何关联,有很多猜测,但那是另一个时间的讨论)。
上图还显示了三种火车构成了日常运输的主体:慢车、快车和半快车。就百分比而言,这 3 个系列可以细分如下:
在这里,我们可以清楚地看到,慢车和快车处理大约 85%的全天交通,而半快车主要用于高峰时间。作为一个外国人,如果你想在这个城市四处走走,你最好的选择是乘坐慢车或快车。
另一个有趣的点是进站和出站列车之间的差异。虽然火车在东京只有两种移动方式(进或出),但一天中的时间和火车移动的方向之间可能有关系。按照一天中的时间绘制进站和出站列车的数量,以产生以下视觉效果:
同样,我们在图中看到峰值出现在上午 7–9 点和下午 5–7 点。但是,如果仔细观察,您会发现早高峰期间进站列车略多于出站列车。晚高峰的情况正好相反。这实际上是非常直观的,因为大多数人从其他地方来到东京工作,工作一结束就离开。晚上 8-10 点的峰值也说明了上述文化点。然而,这种涌入在一定程度上也是因为年轻人来到这个城市享受东京的夜生活。
就百分比而言,上图可以表示如下:
这个图表的有趣之处在于,它澄清了一个事实,由于上面提到的原因,一天中进站的列车比出站的列车多。
车站音量
既然对列车容量有了概念,下一个合乎逻辑的步骤就是看看这些列车到底要去哪里。东武铁路连接 158 个车站;然而,只有那些接收 20,000 或更多进站列车的列车才包括在分析中。这个数字被选为阈值,因为接收较少的站的数量变化如此之大,以至于我们无法洞察哪些站是最繁忙的(因为图表会变得过于混乱)。
我们可以清楚地看到,东武动物园站是网络中最繁忙的。然而,这并不意味着所有的乘客都对看到奇异的动物感到兴奋。事实上,造成这种差异的原因是东武动物园实际上是东武铁路线上的最后一站。这意味着东武站用于换乘其他铁路,本质上充当了经由东武线进出东京的枢纽。
线路音量
最后的分析是为了确定哪些铁路线是最繁忙的。进站和出站列车是根据特定的东武铁路线计算的。
这张图说明了大江线、堀里线和东京晴空塔线构成了东武铁路系统的绝大部分。所有其他线路都是东京内更具体地点的分支。作为一名游客,你去任何地方的最佳选择就是使用这三条线路中的一条。
结论
东京公共铁路运营庞大而复杂。在这篇文章中,我只概述了一条具体的铁路。实际上,还有 29 家运营商运营着总共 108 条独立线路,连接东京境内总共 882 个火车站。由于网络的设计,实际上不可能获得所有城市的列车数据用于分析目的;然而,我们仍然可以从整个画面的一小部分中收集一些重要的见解。作为游客,我们应该预料到早晚高峰时车站会非常拥挤。我们还应该预料到,如果我们决定在晚上进入东京而不是离开(早上正好相反),我们的旅行将不会那么拥挤。此外,帕累托法则适用于铁路线——你的大部分运输可以在运营商的一小部分线路上完成。最后,火车路线上的最后一站通常是最繁忙的,因为许多人正在换乘火车在全国各地旅行。
文字游戏:矢量化、标记和情感分析
原文:https://towardsdatascience.com/a-game-of-words-vectorization-tagging-and-sentiment-analysis-c78ff9a07e42?source=collection_archive---------9-----------------------
用自然语言处理分析《权力的游戏》第一册中的单词
Image from simisi1 from Pixabay
完全披露:我没有看过《权力的游戏》,但我希望通过分析文本来了解更多。如果你想了解更多关于基本文本处理的背景知识,你可以阅读我的其他文章。所有 5 本书的文本都可以在 Kaggle 上找到。在本文中,我将使用清理后的文本来解释以下概念:
- 矢量化:单词袋、TF-IDF 和 Skip-Thought 矢量
- 矢量化后
- 词性标注
- 命名实体识别(NER)
- 组块和叮当声
- 情感分析
- 其他 NLP 包
矢量化
目前,我有一个词条列表,但是我如何以一种机器能够理解的方式来组织它们呢?我将探索几个向量化方法,它们将单词列表转化为可用于不同机器学*方法的数字数组。这样做时,确保从文本中删除停用词和其他不必要的词是很重要的,这样创建的数组/向量系统将只有重要的维度可以建模。
一种方法叫做单词包,它定义了文本中包含的唯一单词的字典,然后找到文本中每个单词的计数。例如,如果我要从 A Game of Thrones 中收集一个独特的单词列表,然后按章节将整个列表拆分成单词,我将得到一个每行有一章、每个单词的计数跨列的数组。这种方法的缺点是它不能保持单词的顺序([坠落,死亡]和[坠落,爱]有非常不同的意思),而且它不能捕捉单词的任何实际意思。此外,如果我们将文本按章节划分,包含更多单词的章节会无意中被赋予更大的权重,因为它们在整个行中有很高的计数。然而,这仍然是查看术语分布的好方法,并且如果您想要查看某个特定单词出现了多少次,这是很有用的。这是一个在《权力的游戏》文本上的实现,按章节划分:
from sklearn.feature_extraction.text import CountVectorizerbow = CountVectorizer()
BOW = bow.fit_transform(page_lemm)
bagOFwords = pd.DataFrame(BOW.toarray())
bagOFwords.columns = bow.get_feature_names()
在这个例子中,page_lemm
是长度为 572(页数)的列表,每个元素是该页上的一串单词。CountVectorizer()
函数自动对所有字符串中的单词进行标记和计数。在使用上面的代码之前,我做了一些后台的停用词和词条去除,你可以在我的 github 上看到。这段代码创建了一个 dataframe,其中每一行对应于书中的一章,每一列对应于文本中的一个单词。框架的主体包含每章每个单词的计数。
另一种解决单词袋问题的方法叫做 TF-IDF,或者术语频率-逆文档频率。TF-IDF 与前面的方法类似,只是每行每列中的值是根据文档中的术语数量和单词的相对稀有程度来调整的。词频等于一个词在文档中出现的次数除以文档中的总字数。逆文档频率计算语料库中所有文档中的稀有单词的权重,其中稀有单词具有高 IDF 分数,并且出现在语料库中所有文档中的单词具有接*零的 IDF。这使得那些可能有很多意思的词,即使很少,在最后的分析中仍然有影响力。这么想吧——是知道‘手’这个词在一本书的所有章节中都有使用会更好,还是知道‘死亡’只在其中 10 章出现会更有影响?TF 和 IDF 相乘得到最终的 TF-IDF 分数。在中可以找到这个过程的一步一步。Python 中的 scikit-learn 包(sklearn
)有一个函数TfidfVectorizer()
,它将为您计算 TF-IDF 值,如下所示:
from sklearn.feature_extraction.text import TfidfVectorizervectorizer = TfidfVectorizer()
got_tfidf = vectorizer.fit_transform(page_lemm)
tfidf = pd.DataFrame(got_tfidf.toarray())
tfidf.columns = vectorizer.get_feature_names()
如您所见,这两种方法的代码非常相似,采用相同的输入,但在 dataframe 中给出不同的内容。计算 TF-IDF 分数,而不是每个单词的计数。这里是根据平均单词数的前 10 个单词和根据平均 TF-IDF 分数的前 10 个单词的比较。有一些重叠,但是 TF-IDF 给出的字符名称的平均分比单词袋高。我强调了这两种方法之间不重叠的地方。
跳跃思维 矢量是另一种矢量化方法,它使用神经网络中的迁移学*来预测句子的环境。迁移学*的概念是,机器可以将它从一项任务中“学到的”知识应用到另一项任务中。这是几乎所有机器学*技术背后的思想,因为我们试图让机器以比人类学*更快、更可量化的速度学*。特别是对于文本处理,其想法是一种算法建立一个神经网络,从数千本不同的书籍中学*,并找出句子结构,主题和一般模式。然后,这种算法可以应用于尚未阅读的书籍,它可以预测或模拟文本中的情感或主题。你可以在这里阅读更多关于这种方法以及它与 TF-IDF 的比较。
另一种严重依赖神经网络的矢量化方法是 word2vec ,它计算两个单词之间的余弦相似度,并在空间中绘制单词,以便将相似的单词分组在一起。你可以在这里阅读这个方法的一个简洁的实现。
矢量化后
现在你有了一个数字数组,接下来呢?使用单词包,您可以执行逻辑回归或其他分类算法来显示数组中哪些文档(行)最相似。当试图查看两篇文章在主题上是否相关时,这是很有帮助的。skip think Vectors 和 Word2Vec 都是基于文本内的含义来聚类单词,这是一种叫做单词嵌入的方法。这项技术很重要,因为它保留了单词之间的关系。尤其是在处理评论文本数据(任何带有数字评级的文本评论)时,这些技术可以产生关于消费者的感受和想法的有价值的见解。由于权力的游戏没有默认的分类值,我没有办法验证模型,我将在下面解释分析文本的替代方法。
位置标记
词性标注 (POS)是使用上下文线索将词性分配给列表中的每个单词。这很有用,因为同一个词有不同的词性,可能有两种完全不同的意思。例如,如果你有两个句子['一架飞机可以飞'和'房间里有一只苍蝇'],正确定义'飞'和'飞'是很重要的,以便确定这两个句子是如何相关的(也就是根本没有)。按词性标注单词可以让你进行组块和分块,这将在后面解释。一个重要的注意事项是,词性标注应该在标记化之后和移除任何单词之前立即进行,以便保留句子结构,并且更明显地知道单词属于哪种词性。一种方法是使用nltk.pos_tag()
:
import nltkdocument = ' '.join(got1[8:10])
def preprocess(sent):
sent = nltk.word_tokenize(sent)
sent = **nltk.pos_tag**(sent)
return sentsent = preprocess(document)
print(document)
print(sent)
【他说“死了就是死了”。“我们和死人没关系。”,’“他们死了吗?”罗伊斯轻声问道。“我们有什么证据?”]
[,…(' ','
'),('我们',' PRP '),('有',' VBP '),('无',' DT '),('商',' NN ',('有',' IN '),(' the ',' DT ',('死',' JJ ',('.', '.')、(“' '”、“' '”、…]
这是上面创建的一个片段,你可以看到形容词被表示为“JJ”,名词被表示为“NN”,等等。该信息将在以后分块时使用。
命名实体识别
有时,进一步定义特殊单词的词性会很有帮助,尤其是在尝试处理关于时事的文章时。除了名词之外,“伦敦”、“巴黎”、“莫斯科”和“悉尼”都是有特定含义的地点。同样的道理也适用于人名、组织名、时间名、金钱名、百分比名和日期名等等。这个过程在文本分析中很重要,因为它是理解文本块的一种方式。通常,要对文本应用 NER,必须先执行标记化和词性标注。nltk 包有两个内置的 NER 方法,这两个方法都在本文中有很好的解释。
执行 NER 并能够可视化和排序结果的另一个有用方法是通过 spaCy 包。一个很好的演练可以在找到。我使用这种方法研究了 get 文本,得到了一些有趣的结果:
import spacy
from collections import Counter
import en_core_web_sm
nlp = en_core_web_sm.load()
from pprint import pprintdoc = nlp(document3)
pprint([(X.text, X.label_) for X in doc.ents])
('乔治·r·r·马丁','人'),
('威玛·罗伊斯爵士','人'),
('五十','红衣主教'),
('威尔','人'),
('罗伊斯','人'),
('八日','日期'),
('九日','红衣主教'),
('威玛·罗伊斯','人', ('加雷斯','人'),
('加雷斯','组织'),【组织】。
在上面的代码中,document3
是一个字符串中的一个权力的游戏的全文。这个包可以有效地发现和分类所有类型的实体。在 Gared 的一些例子上有点混乱(在某一点上它把他归类为 PERSON,另一个归类为 ORG,后来又归类为 WORK_OF_ART)。然而,总的来说,这比单纯的词性标注更能洞察文本的内容。下面是每种实体类型的匹配数和找到的顶级实体。不出所料,文中有很多名字。
labels = [x.label_ for x in doc.ents]
items = [x.text for x in doc.ents]print(Counter(labels))
print(Counter(items).most_common(5))
计数器({ '红衣主教':340,'日期':169,' FAC': 34,' GPE': 195,'法律':2,' LOC': 24,'金钱':1,' NORP': 32,'序数':88,' ORG': 386, '人':2307 ,'产品':35,'数量':23,'时间':86,' WORK_OF_ART': 77})
(乔恩’、259)、( 奈德’、247)、( 艾莉亚’、145)、( 罗伯特’、132)、(
分块和分块
组块和分块是从文本中提取有意义短语的两种方法。它们结合了词性标注和正则表达式来生成与所请求的短语结构相匹配的文本片段。组块的一个实现是找到提供不同名词描述的短语,称为名词短语组块。名词短语块的形式通常由决定/所有格、形容词、可能的动词和名词组成。如果你发现你的组块中有你不想要的部分,或者你宁愿在特定的位置拆分文本,一个简单的方法就是通过 chinking 。这定义了在分块时应该移除或分割的小块(称为缝隙)。我不打算在这篇文章中探索 chinking,但可以在这里找到一个教程。
使用 NLTK 进行特定类型分块的最简单方法是使用nltk.RegexpParser(r‘<><><>’)
。这允许您指定您的名词短语公式,并且非常容易解释。每个< >引用一个单词的词性进行匹配,正常的正则表达式语法适用于每个< >。这非常类似于nltk.Text().findall(r’<><><>’)
的概念,但是只是用了 POS 而不是实际的单词。在创建要解析的正则表达式字符串时需要注意的几件事是,词性缩写(NN =名词,JJ =形容词,PRP =介词,等等。)可能因软件包而异,有时最好从更具体的开始,然后扩大搜索范围。如果你现在非常迷茫,可以在这里找到这个概念的。此外,在此之前温*一下句子结构和词性可能是个好主意,这样你就能完全理解组块分析的结果。下面是一个应用于掘地工具的示例:
document2 = ' '.join(got1[100:300])
big_sent = preprocess(document2) # POS tagging wordspattern = 'NP: {<DT>?<JJ>*<NN.?>+}'
cp = nltk.RegexpParser(pattern)
cs = cp.parse(big_sent)
print(cs)
(……,( NP 暮光/NNP )深化/VBD。/.( NP The/DT 万里无云/NN sky/NN )转身/VBD ( NP a/DT 深/JJ 紫/NN ),/,(NP The/DT color/NN)of/IN(NP an/DT 老/JJ 青
这是一个非常类似于 NER 的想法,因为你可以将 NN 或 NNP(名词或专有名词)组合在一起以找到物体的全名。此外,匹配的模式可以是词类的任意组合,这在查找特定种类的短语时非常有用。但是,如果词性标注不正确,您将无法找到您要查找的短语类型。我在这里只寻找名词短语,但是在我的 github 代码中包含了更多类型的组块。
情绪分析
情感分析是计算机如何将目前为止所涉及的一切结合起来,并想出一种方法来传达一篇文章的整体主旨。它将句子、段落或文本的另一个子集中的单词与字典中的单词列表进行比较,并根据句子中单个单词的分类来计算情感得分。这主要用于分析评论、文章或其他观点,但我今天将把它应用于 GOT。我主要感兴趣的是看这本书的整体基调是积极的还是消极的,以及这种基调在各章之间的变化。进行情感分析有两种方法:你可以在以前分类的文本上训练和测试一个模型,然后用它来预测同一类型的新文本是正面还是负面,或者你可以简单地使用内置于函数中的现有词典来分析和报告正面或负面得分。下面是后者的一个例子或者是《权力的游戏第一页的一些句子:
from nltk.sentiment.vader import SentimentIntensityAnalyzer
nltk.download('vader_lexicon')sid = **SentimentIntensityAnalyzer**()
for sentence in sentences:
print(sentence)
ss = sid.polarity_scores(sentence)
for k in sorted(ss):
print('{0}: {1}, '.format(k, ss[k]), end='')
print()
……“死人让你害怕吗?”
compound:-0.7717,neg: 0.691,neu: 0.309,pos: 0.0,
威玛·罗伊斯爵士带着刚刚的一丝微笑问道。
复合:0.3612,neg: 0.0,neu: 0.783,pos: 0.217,
Gared 未上钩。
复合:0.0,neg: 0.0,neu: 1.0,pos: 0.0,…
因为这是在分析一本书的文本,而不是评论的文本,所以很多句子将会有一个中性的复合得分(0)。然而,这完全符合我的目的,因为我只是在寻找这本书的语言随着时间推移的一般趋势。但是当提到死亡的时候,一个负分被应用,这仍然是一件好事。
TextBlob 是另一个有用的可以进行情感分析的包。一旦你把你的文本转换成一个 TextBlob 对象(textblob.textBlob()
),它就具有对纯文本进行标记化、词汇化、标签化的功能,并生成一个 WordNet,它可以量化单词之间的相似性。这个包有很多不同的文本对象,允许非常酷的转换,在这里解释。甚至有一个correct()
功能会尝试纠正拼写错误。在本文中,我不打算深入讨论其中的大部分,因为我正在尝试分析一本书,它通常应该具有正确的拼写和语法,然而,当处理特别混乱的文本数据时,这些工具中的许多将是有用的。下面是 TextBlob 在权力的游戏第一页的情绪分析版本:
from textblob import TextBlob
def detect_polarity(text):
return TextBlob(text).sentiment
for sentence in sentences:
print(sentence)
print(detect_polarity(sentence))
“死人让你害怕吗?”
情绪(polarity =-0.2,主观性=0.4)
威玛·罗伊斯爵士带着刚才那一丝微笑问道。
情绪(极性=0.3,主观性=0.1)
加雷斯没有上钩。
情绪(极性=0.0,主观性=0.0)
nltk 和 textblob 的情感评分之间有相似性,但是 nltk 版本有更多的可变性,因为它是一个复合评分。或者,textblob 情感具有主观性得分,这有助于判断句子可以被分类的准确程度。下面是每种方法的页面情感分布。总的来说,Textblob 给出了更高的情感评级,而 nltk 与分数的差异更大。
如果你试图从社交媒体文本或表情符号中收集情绪,VADER 情绪分析是一个专门为这项任务设计的工具。它内置了俚语(lol,omg,nah,meh 等。)甚至能看懂表情符号。如何使用它的一个很好的演练可以在这里找到。此外,如果 Python 不是您进行文本分析的首选语言,那么在不同的语言/软件中还有其他方法来进行情感分析,这里的将对此进行解释。
其他 NLP 包
在本文中,我只解释了nltk
、textblob
、vaderSentiment
、spacy
和sklearn
包的功能,但是根据您试图完成的任务,它们有许多优点和缺点。其他一些可能更适合你的任务是多语种和 Genism。 Polyglot 以具有分析大量语言的能力而闻名(根据任务支持 16–196 种)。 Genism 主要用于对文本的无监督学*任务,并且需要用不同的包进行任何预处理。你可以在这里找到所有这些信息的图表。
结论
我从撰写本文中学到的一个关键点是,完成一项任务至少有三种方法,而确定最佳选择取决于您使用的数据类型。有时候你会优先考虑计算时间,而其他时候你会需要一个可以很好地进行无监督学*的包。文本处理是一门迷人的科学,我迫不及待地想看看它在未来几年里将我们引向何方。在本文中,我介绍了矢量化以及它如何确定文本之间的相似性,标记允许将意义附加到单词上,以及情感分析,它可以大致判断文本的积极或消极程度。我从《权力的游戏》中收集了很多见解,比如有很多死亡,先生是一个常见的头衔,拼写为 Ser,龙的例子没有我被引导相信的那么多。不过,我现在可能被说服去看书了!我希望你喜欢这篇文章!
我的代码副本,有更多的例子和解释,可以在 github 上找到!请随意获取和使用代码。
我的另一篇文章《文本预处理来了》可以在这里找到!
假设检验的一般指南
原文:https://towardsdatascience.com/a-general-guidance-of-hypothesis-testing-7cab119ca999?source=collection_archive---------17-----------------------
对 P 值、I 型误差、II 型误差、统计功效的温和解释
假设检验作为一种重要的统计技术,广泛应用于各种商业案例的 A/B 检验中,同时也给许多人带来了困惑。本文旨在总结假设检验的几个关键要素的概念,以及它们如何影响检验结果。
故事从假设开始。当我们想知道一个总体的任何特征,如分布形式、感兴趣的参数(均值、方差等)时。),我们对它做一个假设,叫做人口假设。然后,我们从总体中抽取样本,并测试样本结果在给定的假设下是否有意义。
例如,您的经理不知何故知道公司网站上所有用户的平均点击率为 0.06(总体点击率的平均值),而您对此表示怀疑,并认为点击率应该更高。如何检验你或你的经理是否会赢?假设检验所做的是首先提出一个假设,即假设 CTR μ = 6%,然后随机抽取大量用户的样本数据,并从中计算 CTR 的均值(样本的 CTR 均值)。根据对样本的观察,决定是否拒绝你的假设。于是就出现了零假设和替代假设。
零假设:μ = 6%
替代假设:μ > 6%
假设样本量足够大是有效的,你发现 CTR 的均值是 7.5%。你能不能直接告诉你老板,真实的 CTR 是 7.5%?基于样本的 1.5%的差异是否足以让你做出这个决定?概率总能帮助解决不确定性。希望您能提供这样的答案:如果零假设为真,即 CTR 的均值等于 6%,那么从样本中看到 CTR 的均值等于或大于 7.5%的概率为 1%。百分之一的概率是很少发生的。因此,拒绝零假设是合理的。这正是 P 值所解释的。
" P 值是在零假设下获得与观察到的结果一样或更极端的结果的概率."
P 值= P(μ ≥ 7.5% |零假设成立)
让我们看看下面两种情况下 P 值的可视化。
黑线代表零假设的分布,蓝线代表样本均值的分布。粉色区域是如上所述的 P 值。第一种情况是这两种分布彼此远离,P 值很低,为 0.01。表示看到样本均值分布均值等于或大于 7.5%的概率为 1%,假设总体真实均值等于 6%的零假设为真。这是非常罕见的,但这是我们观察到的,所以我们声明假设是不正确的。类似地,第二种情况,P 值等于 30%,意味着有 30%的概率看到样本分布的均值等于或大于 7.5%,这是一个相当高的概率,所以我们不能拒绝零假设。这就是为什么当 P 值很小时,拒绝零假设。
另一方面,不管零假设是否为真,也不管你是否应该拒绝零假设,它们的组合都可以表示为概率。这就是假设检验的美妙之处。查看可视化的更多细节:
假设在这种情况下,P 值(*似粉色三角形包含的区域)足够小,等于 0.05。那么α,β和 1- β的意义是什么呢?
α是I 型误差,是假设假设为真,错误拒绝零假设的概率。也算是你能容忍的 P 值的最大值。设置好α的值后,你会有一个相应的显著性水平。例如,当α = 5%时,显著性水平为 95%。
α = P(拒绝零假设|零假设为真)
β是第二类错误,是假设无效,拒绝无效假设失败的概率。
β = P(拒绝零假设失败|零假设为假)
1-β是统计功效,是在假设无效的情况下,正确拒绝无效假设的概率。
1-β = P(拒绝零假设|零假设为假)
下表总结了四种情况:
这让我想起了我们通常用于分类问题的混淆矩阵。α其实是假阳性,β是假阴性,1-β是真阳性,1-α是真阴性。见下图。
显然,我们希望最小化 FP 和 FN,最大化 TP,但正如上面所示的分布图,随着α减小,β增大,统计功效减小。所以它们之间总是有一个权衡,我们不能只优化一个单一的指标。当你试图平衡召回率和精确度时,这与混淆矩阵的逻辑完全相同。影响α和β的因素有几个,如样本大小、分布范围、假设和观察之间的差异等。统计功效的标准选择是 80%,α是 5%。
本文从概念上提供了假设检验的顶级摘要以及一些重要的度量标准。在分布和要测量的度量标准的选择方面,还有许多其他的计算细节和要求。继续潜水!
分类的生成方法
原文:https://towardsdatascience.com/a-generative-approach-to-classification-17a0b5876729?source=collection_archive---------7-----------------------
简单的解释
Image by Prashant Sharma from Pixabay
每当有人谈到生成性分类模型和区分性分类模型时,我总是感到困惑。
我读了一遍又一遍,但不知何故,它避开了我。
所以我想到了写一篇关于它的帖子来提高我的理解。
这篇文章是关于理解生成模型以及它们与判别模型的区别。
最后,我们将自己创建一个简单的生成模型。
区别性与生成性分类器
问题陈述: 有了一些输入数据,X
我们要把数据分类到标签里y
。
生成模型学*联合概率分布p(x,y)
,而判别模型学*条件概率分布p(y|x)
那么真的,有什么区别?他们看起来几乎一样。
假设我们有一个小样本数据:
(x,y) : [(0,1), (1,0), (1,0), (1, 1)]
那么p(x,y)
就是
而p(y|x)
是
如你所见,他们模拟了不同的概率。
判别分布p(y|x)
可以直接用于将示例x
分类到类别y
。判别分类模型的一个例子是逻辑回归,其中我们尝试对 P(y|X)建模。
Logistic Regression
生成算法模型p(x,y)
。一个例子是朴素贝叶斯模型,在该模型中,我们尝试对 P(X,y)建模,然后使用贝叶斯方程进行预测。
生成分类背后的中心思想
- 用概率分布分别拟合每个类别。
- 对一个新的点进行分类,找出它最有可能来自哪个分布。
还不明白的也不要着急。你一定会在这篇文章结束时得到它。
一个小例子
让我们使用虹膜数据集。
对于我们的简单示例,我们将使用单个 x 变量 SepalLength 和我们的目标变量 Species。
让我们看看不同物种的萼片长度的分布。为此我使用了 plotly_express 。
import plotly_express as px
px.histogram(iris, x = 'SepalLengthCm',color = 'Species',nbins=20)
要创建创成式模型,我们需要找出两组值:
1.个别类别的概率:
获得单个类的概率是相当简单的——例如,我们的数据集中的实例数,即 seta 除以数据集中的案例总数。
0.3333333333333333 0.3333333333333333 0.3333333333333333
虹膜数据集非常平衡。
2.每类 x 的概率分布:
这里我们拟合了 X 上的概率分布。我们假设 X 数据是正态分布的。因此,我们可以找到这三个分布的样本均值和方差(因为我们有三个类别)
在上图中,我用三个物种的样本均值和方差为每个物种拟合了三个正态分布。
那么,我们如何用这个来预测呢?
假设我们得到一个新的例子,SepalLength = 7 cm。
因为我们看到最大概率出现在 virginica,我们预测 x=7 的 Virginica,也是基于该图;这看起来是非常正确的选择。
您也可以使用代码获取值。
Setosa 3.062104211904799e-08
Versicolor 0.029478757465669376
**Virginica 0.16881724812694823**
这一切都很好。但是我们什么时候处理过单一变量呢?
让我们把例子扩展到两个变量。这一次让我们也使用 PetalLength。
px.scatter(iris, 'SepalLengthCm', 'PetalLengthCm',color = 'Species')
那么在这种情况下我们该如何进行呢?
第一次我们在单个 x 上拟合正态分布,这次我们将拟合双变量正态分布。
这是它的样子:
现在,其余的计算保持不变。
在上面的方程中,只有法线被二元法线代替。如你所见,通过使用二元正态分布,我们得到了更好的分类分离。
作为对多变量(多于 2 个)这种情况的扩展,我们可以使用多元正态分布。
结论
生成型模型擅长生成数据。但与此同时,创建这样的模型来捕捉数据的底层分布是极其困难的。
生成建模涉及许多假设,因此,这些模型在分类设置中的表现不如判别模型。在上面的例子中,我们还假设分布是正态的,这可能是不正确的,因此可能会引起偏差。
但是理解它们是如何工作的仍然是有帮助的。一类这样的模型被称为生成对抗网络,它对于生成新图像非常有用,也非常有趣。
这里的是包含所有代码和可视化效果的内核。
如果你想了解更多关于生成模型和机器学*的知识,我推荐圣地亚哥大学的这门机器学*基础课程。上面的帖子大体上是从来自 SanDiego 的 MicroMasters 课程的内容中得到启发的,我目前正在努力构建我的数据科学学*。
谢谢你的阅读。将来我也会写更多初学者友好的帖子。在 媒体 关注我,或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系到我。
Python 决策树的简明指南
原文:https://towardsdatascience.com/a-gentle-guide-into-decision-trees-with-python-cbfc76deb748?source=collection_archive---------14-----------------------
决策树算法是一种监督学*模型,用于用一系列训练变量预测因变量。决策树算法可用于分类和回归目的。
在这个特别的项目中,我将用一个离散随机变量的分类来说明它。
决策树可以回答的一些问题。
- 贷款申请人是否应该被接受?这是基于他/她的历史和其他措施。
- 哪种药物最适合特定的病人。
- 癌细胞是良性的还是恶性的?
- 电子邮件是否是垃圾邮件?
以及现实生活中更多的场景。
理解决策树算法。
决策树是使用递归分区将数据分为两组或更多组来构建的。
现实生活的例子。
假设我们有随着时间的推移进行癌症筛查的患者的数据。基于来自筛选练*的测试,筛选的细胞被分类为良性和恶性。基于该数据,可以建立决策树模型,以比医生更好地为未来的患者以最高的准确度预测这些病例。
决策树从具有最高预测能力、较少杂质和较低熵的变量开始,逐个变量分割数据变量。
该方法的主要目的是最小化杂质和每个节点。节点的杂质通过节点中数据的的熵来计算。
熵
熵是信息量的无序或简单地说是数据的随机性或不确定性。
数据集的熵取决于节点的随机性。应当注意,熵越低,分布越不均匀,节点越纯。如果样本完全同质,则熵完全为零,如果样本被等分,则熵为 1。
参考上述数据,假设一个节点具有 7 个恶性和 1 个良性,而另一个节点具有 3 个恶性和 5 个良性,前者与后者相比具有低熵。
这是熵的数学计算方法:
最佳树的选择取决于分裂后具有最高信息增益的节点。
信息增益
这是拆分后可以增加确定性水平的信息。计算如下。
这个过程继续构建一个基本的决策树。下面是 python 中的一步一步的过程。
用 Python 实现。
导入库
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
数据摄取
loan_data = pd.read_csv(“loan_data.csv”)
loan_data.info()
loan_data.describe()
loan_data.sample(5)
探索性数据分析。
这是一个简短的 EDA,因为该项目旨在决策树插图。
plt.figure(figsize=(10,6))
loan_data[loan_data[‘credit.policy’]==1][‘fico’].hist(alpha=0.5,color=’blue’,
bins=30,label=’Credit.Policy=1')
loan_data[loan_data[‘credit.policy’]==0][‘fico’].hist(alpha=0.5,color=’red’,
bins=30,label=’Credit.Policy=0')
plt.legend()
plt.xlabel(‘FICO’)
设置数据。
我这里的数据有一些我必须驯服的分类变量,因为如果格式不正确,模型算法可能无法很好地处理这些数据。
categorical_var = [‘purpose’]
loan_data2 = pd.get_dummies(data= loan_data,columns=categorical_var,drop_first=True)
loan_data2.columns
列车测试分离
from sklearn.model_selection import train_test_split
X = loan_data2.drop('not.fully.paid',axis = 1)
y = loan_data2['not.fully.paid']
X_trainset, X_testset, y_trainset, y_testset = train_test_split(X, y, test_size=0.30, random_state=2)
训练决策树模型
from sklearn.tree import DecisionTreeClassifier
loanTree = DecisionTreeClassifier(criterion="entropy", max_depth = 4)
loanTree
loanTree.fit(X_trainset,y_trainset)
模型评估
predLoan = loanTree.predict(X_testset)
from sklearn.metrics import confusion_matrix,classification_report,precision_score
print(classification_report(y_testset,predLoan))
这产生了 78%的准确度水平
让我们来看看混淆矩阵的可视化
sns.heatmap(confusion_matrix(y_testset,predLoan),cmap=”viridis”,lw = 2,annot=True,cbar=False)
决策树模型产生了 78%的准确性,这是令人印象深刻的,因为没有进行任何功能工程,甚至没有调整参数来改进模型。
通过应用随机森林分类器算法也可以提高精度,该算法比简单决策树更好。在另一个内核上有更多的内容。
决策树的可视化
from IPython.display import Image
from sklearn.externals.six import StringIO
from sklearn.tree import export_graphviz
import pydotfeatures = list(X.columns)
# features
dot_data = StringIO()
export_graphviz(loanTree, out_file=dot_data,feature_names=features,filled=True,rounded=True)graph = pydot.graph_from_dot_data(dot_data.getvalue())
Image(graph[0].create_png())
欢迎所有意见、建议和任何改进!
请在此处查看上面的代码。在我的 Github 库中。
干杯!
配对交易中强化学*的温和实现
原文:https://towardsdatascience.com/a-gentle-implementation-of-reinforcement-learning-in-pairs-trading-6cdf8533bced?source=collection_archive---------3-----------------------
tensor flow 中结构化编程的一个例子
Source: Pexels
这涵盖了基于 1 分钟股市数据的协整配对交易中从概念到 RL 实现的主题。对于这里的强化学*,我们使用 N 臂 bandit 方法。代码是可扩展的,因此如果你遵循这种风格,你可以将任何策略、数据 API 或机器学*算法插入到工具中。
Left-to-Right: Code Structure, Sample Price Relationship, Testing Profits
外卖 :
1。具有数据获取实用程序
2 的可扩展基础设施。python 代码构造的组合技术
3。跨越编码、计量经济学和强化学*主题的一般概念和理论
[## wai-I/Pair-交易-强化-学*
在 GitHub 上创建一个帐户,为 wai-I/Pair-Trading-Reinforcement-Learning 的发展做出贡献。
github.com](https://github.com/wai-i/Pair-Trading-Reinforcement-Learning)
第 1 部分:理论之前的数据
1.1 数据来源— Tiingo
ti Ingo是一个金融研究平台,提供包括新闻、基本面、价格等数据。我们可以通过其 REST IEX API 提取当天的股票市场数据,该 API 从 IEX 交易所检索 TOPS 数据(书籍顶部、最后销售数据和顶部买价和卖价报价)。
例如,只需在浏览器中粘贴以下链接:
*https://api.tiingo.com/iex/aapl/prices?startDate=2019-01-02&endDate=2019-01-02&resampleFreq=5min&token=ef79e455ba9b04c3df719407e34f05e1b051b4d6*
您将获得一份 JSON 格式的 AAPL 截至 2019 年 1 月 2 日的历史 5 分钟盘中价格列表:
*[{"date":"2019-01-02T14:30:00.000Z","open":154.74,"high":155.52,"low":154.58,"close":154.76},{"date":"2019-01-02T14:35:00.000Z","open":154.8,"high":155.0,"low":154.31,"close":154.645},{"date":"2019-01-02T14:40:00.000Z","open":154.67,"high":154.94,"low":154.25,"close":1...*
为了自动完成这项任务,我们需要能够在特定的历史窗口内获得一系列股票的标准化日内数据的函数。
限制
- 历史数据频率高达 1 分钟
- 对于每种股票的每个请求,检索的样本的最大数量是不一致的,也就是说,即使您指定了 365 天的窗口,您也只能获得几天的数据
- 每天的样品数量并不一致(例如,它也可能在市场开放时间后给你价格)
- 不够快(可能只是我的问题)
解决方案
- 一次获取 1 个日期的 1 只股票
- 通过固定数量的观察值截断样本,即假设每个日期有 391 个 1 分钟的价格
- 异步输入输出
Pandas 还提供相关工具不仅从 Tiingo 提取数据,也从其他数据提供商提取数据,但似乎他们只提取日常数据。
请注意,根据您的订阅和相应的请求限制,API 数据是免费的。但是,在使用代码时,您应该注意用法,避免挑战限制。
1.2 实施
首先,你需要一个 Tiingo API 令牌。只需注册一个账户,你就会在这里找到你的代币。
这些是位于代码内数据/API.py 中的主要函数:
- 我们需要一个函数,它可以为我们提供检索特定股票[股票代码、日期[目标日期、频率[频率]的当天数据的 url,假定您的令牌[令牌 T13 是有效的。您可以想象我们可以动态地调用这个函数来逐个日期地检索数据,这样我们就可以在一系列读取中轻松地标准化格式。
2.Pandas read_json 允许我们将获取的 json 数据读入一个系列或数据帧。我们可以在类中包装它:
3.上述函数在 Data/API.py 中的 Tiingo 类下定义。该代码将基于关键输入重复提取:开始日期、结束日期、目标属性(即“日期”和“收盘”)以及股票列表,并输出组合数据帧
异步输入/输出
上面的实现受到限制并且很慢。每次当我们开始获取数据时,程序将打开 API 连接,从服务器请求数据,并在关闭连接之前等待它的响应。在所有的进程重复之后,直到最后的 url 被获取。
我们来看看和 AsyncIO 的区别有多大。以下代码获取 GOOG 和 FB 在 2018 年 1 月 1 日至 2018 年 1 月 31 日之间的 1 分钟价格。每个日期 391 个样本,总共约 15,600 次观察。所有设置都在配置字典中配置,但我们暂时忽略它。
下面的结果表明,使用 AsyncIO 比普通的获取快 17 倍。
Speed comparison between normal and asynchronous fetching
根据 python 文档:
asyncio 是一个使用 async/await 语法编写并发代码的库。
asyncio 被用作多个 Python 异步框架的基础,这些框架提供了高性能的网络和 web 服务器、数据库连接库、分布式任务队列等。
与并行编程不同,AsyncIO 是单线程的。一个简单的想法是,它在一个组织任务分布的单事件处理程序中管道化分配的任务,以便多个任务可以在其他任务空闲时开始运行。
为了说明这个概念,让我们来看一个官方示例:
Source: https://python.readthedocs.io/fr/latest/library/asyncio-task.html
上面的关键字 async def 将相应的函数定义为一个协程,它可以暂停或恢复执行。每当一个任务在关键字下等待时,进程控制被传递回事件控制器(循环),事件控制器为另一个任务分配并启动进程。简单来说,就是不浪费等待时间。**
在我们的代码中也有类似的东西。 _fetch_hist_async 将创建一个事件循环来控制 fetch_data_async 的进程,该进程是获取当天价格的底层任务。当遇到 await 时,控制返回到触发另一个获取请求的事件循环,即使前一个尚未完成。
1.3 数据存储
理想情况下,我们应该建立一个数据库来存储价格。为了简单起见,让我们把价格存进去。目录下的 csv 统计/价格:
第 3 部分:配对交易——概念和分析
让我们跳过第 2 部分,它涵盖了枯燥的代码和结构,并做一些分析。但是我仍然建议你去读完这篇文章,如果你感兴趣的话,先对骨骼有个概念。
3.1 配对交易
配对交易是一种市场中性策略。如 Gatev 等人(2006 年)所述:
“配对交易的概念非常简单。找出两只历史上价格变动一致的股票。当它们之间的价差扩大时,做空赢家,买入输家。如果历史重演,价格就会趋同,套利者就会获利。”
它将战略总结为两个阶段:
- 在制定阶段,我们衡量股票之间的价格关系,并在范围内确定股票对。
- 在随后的交易期间,将根据预定义的规则监控和交易该关系。
简单地说,它利用均值回复价差交易。问题是,我们如何估计或验证股票对之间的价格动态?
Krauss (2017)将成对交易策略中的常用方法归纳为五类:距离方法、协整方法、时间序列方法、随机控制方法以及其他方法,如机器学*、主成分分析和 copula。本文将展示经典的 Engle 和 Granger (1987)协整方法在配对交易的强化学*算法组合中的应用。
这里的想法与时间序列分析中一个叫做平稳性的概念有关。它通常被称为金融时间序列中的弱形式(或协方差)平稳性,其标准如下:
- 随机变量 x 的期望值,即**E[x(t)]**,与时间 t 无关
- 方差**Var(x(t)**是一个与时间无关的正的有限常数
- 协方差 **Cov( x ( t ),x(s)**是有限的,与时差 t-s 有关,但既不是也不是 s**
通常情况下,x(t)被视为对数价格回报(或差异),而非价格水平。如果一个时间序列在一阶差分后变得平稳,则称之为一阶积分 I(1) 。
尽管股票价格也可能是均值回复的,但它们很少振荡,即由于持续的经济驱动因素和市场活动的混合影响,它们是趋势性的和非平稳的(随机游走)。所以可能有人会从定向投注中获利,但这不是我们关注的重点。
我们实际上想要的是找到一对价格差异或价差持续稳定(且协整)的股票。
3.2 分析(参见 EXAMPLE/Analysis.py)
我提取了 21 只美股从 2018–01–01 到 2018–07–30 的 1 分钟价格。所有价格都保存在 STATICS/PRICE in 中。csv 格式。让我们取时间序列的前 70%做一些分析。
皮尔森相关性
Pearson correlations across 21 stock prices
这里我们计算价格(不是回报)相关性。相关性最高的是 PEP 、 PG 、 JNJ 和 KO 。从经济角度来说,他们应该分为两对: JNJ-PG 和 KO-PEP 。请注意,高相关性并不一定意味着协整。请参见下面的详细信息。
边际分配
如果我们研究他们的边际分布,线性关系应该有所认识。我们还可以找到一些可能有用的集群,但暂时让我们避免进一步的数据挖掘,这不是我们的主要关注点。
****
Marginal distributions of JNJ-PG and KO-PEP intraday prices
价格图表
让我们创建一个函数来绘制样本期的价格和价差。在样本开始时,价格重新以 1 为基础。注意,第二个子图将描述由对称交易阈值(th)和止损(stop)指定的交易范围:
JNJ-PG price pairing
KO-PEP price pairing
协整检验
以下代码计算协整检验的 p 值,零假设为无协整。所以如果 p 值小,观察到协整关系的概率应该相对高。
请注意,下面的测试是针对整个时间序列的。在培训期间,我们应该根据选择的样本进行测试和交易。
下面的结果表明,即使他们的相关性是可比的,找到一个协整关系的概率是非常不同的。
有时我们可以找到一个相关但不协整的价格关系。例如,如果两只股票价格随着时间的推移一起上涨,它们就是正相关的。然而,如果这两只股票以不同的速度上涨,价差将保持增长,而不是在均衡点振荡,因此是非平稳的。
让我用一个实验来说明这一点。下面的代码通过 几何布朗运动 和 乔莱斯基分解 模拟了两个高度相关的股票价格,每个包含 1000 个样本。
如您所见,尽管相关性很高,但 p 值非常大。
让我们画出这些时间序列:
Prices and spread of correlated GBM prices
底部子图所示的价差是趋势性的,而不是均值回复性的。
3.3 协整
Engle 和 Granger (1987)定义了两步识别法:
- 协整时间序列的元素应该具有相同的积分顺序
- 它们的线性组合应该产生具有较低积分阶的变量
在我们的情况下,当一个以上的 I(1) 非平稳和外生变量(因此它们在理论上是相互独立的)完全相互抵消时,在随机趋势成分中存在协整,从而给出平稳的线性组合和长期均衡。更具体地说,两个 I(1) 对数股价x(1, t )** 和 x (2, t ) 如果存在一个协整系数 b 则进行协整,给出一个平稳的时间序列 y ( t )**
其中 a 简单来说就是一个常数,y(t)就是我们的目标交易价差。
显然,我们可以简单地使用普通的最小二乘法(OLS)方法,通过回归×套期保值比率 (1, t )** 对 x (2, t ) 来估计利差和系数 b 。最初的想法是基于格兰杰表示定理,并以误差修正模型(ECM)的形式表示。然而,基于股票(1987)中的一个叫做超一致性的想法,由于更快地收敛到真实的回归系数,OLS 估计量更容易实现,并且预计在估计协整关系时具有更好的性能。**
3.4 协整检验
检验协整的最常见方法是通过使用迪基富勒(DF)** 或增广迪基富勒(ADF) 单位根检验来检查上述回归的残差是否平稳。**
单位根和迪基-富勒(DF)检验
****单位根是随机过程的一个特征。考虑一个阶为 1 的自回归过程(一个 AR(1) 过程):
*e(t*)是白噪声而 0 < c ≤ 1 。如果过程是非平稳的,也不是完全随机的,那么假设值 c 等于 1 (即方程的根是 1,因此过程是 I(1) )。例如,这可能意味着今天的价格等于昨天的价格加上一个随机值。
Dickey 和 Fuller (1979)表明,这种情况下的统计量不符合 T2 分布,因此检验是不一致的。为了解决这个问题,我们可以将上述模型改为:
并检验 ( c -1)=0 的零假设。这就是所谓的迪基-富勒测试。我们也可以添加一个截距或趋势项,并根据假设检验其系数等于零的零假设。
增强迪基-富勒(ADF)试验
如果我们把自回归过程展开成一个 p 的顺序(即 AR( p ) ):
然后我们可以用这个公式应用增强的迪基-富勒检验:
并检验以下的零假设:
3.5 实施
在第 2.3 节中,我们已经看到了策略类 EGCointegration ,其实现与上面的解释一致。注意,这里的测试是基于stats models . TSA . stat tools . coint的,在用于单元根测试的同一个库中还有另一个函数stats models . TSA . stat tools . ad fuller。不同的是:
- coint 是有效的恩格尔-格兰杰两步协整检验。它用 I(1)测试估计的协整对(2 个时间序列输入)的残差,而
- adfuller 测试单变量过程的单位根(1 个时间序列输入)
在大多数情况下,这两个测试应该产生相同的结论,但是 coint 对于我们的实现来说更加直观。
第四部分:强化学*的思想
我从这个系列中受益匪浅,在代码开发过程中汲取了一些想法。肯定推荐。
4.1 一般概念
强化学*的基础由两个主要部分组成:代理和环境。环境由具有预定义状态空间的不同状态来表示,而代理学*确定在动作空间之外执行什么动作的策略。在完全强化学*问题中,智能体的学*周期可以归纳为以下几个阶段:
- 对环境状态进行观察
- 根据现有策略执行相应的操作
- 根据所执行的行动获得相应的奖励
- 更新策略
Source: Reinforcement Learning: An Introduction, Sutton, R., Barto A.
举个例子,想象一只小狗(代理人)正在学*如何对主人的命令(环境)做出反应。它是只知道如何执行以下动作的懒狗:
- 答:坐下
- b 站
- c .无所事事
为了训练小狗,他的主人定期给他一套命令(状态),包括“坐”、“站”和“跳”。如果他反应正确,他的主人会给他一些狗粮(奖励)。
开始时,小狗并不真正理解他的主人想要什么,也就是说,他不知道(政策)如何将命令正确地“映射”到期望的动作。然而,偶尔他可以以正确的方式做出反应并获得奖励,并逐渐建立他们之间的联系(更新政策)。
经过多次尝试,他终于知道,每当他听到“坐”或“站”这个词时,他都应该“坐”。但是不管他的主人让他跳多少次,他都不知道该怎么办。在这种情况下,他几次试图坐着或站着,但都没有得到任何回报。
最终小狗选择 c .对于“jump”命令什么都不做是因为与其他动作相比,这个选项耗费的精力要少得多(所以负面奖励也少)。
强化学* vs .监督学*
在监督学*中,算法从指令中学*。每个实例都有一个要比较的估计目标,以便计算差异的成本,并且通过迭代最小化成本来更新算法,因此该过程在某种程度上是由目标输出“指示”的,它告诉什么是正确的结果。
然而,在强化学*中,通过评估来学*策略。样本中没有这样的绝对目标可以比较。代理只能通过不断评估反馈来学*,也就是说,它不断选择一个动作并评估相应的回报,以便调整策略,保留最理想的结果。所以工艺流程要复杂得多。当我们在交易中应用强化学*时,我们需要问自己代理人到底在学*做什么,并且在定义元素时要小心,特别是状态和动作空间。
4.2 基本强化学*问题
N 武装匪徒
Illustration of n-armed bandit problem
****问题:上图中,有一个双臂吃角子老丨虎丨机。为了使我们的回报最大化,拉哪只胳膊最好?
****答:右臂自拉的预期回报大于左臂的。
但是机器如何学*解决这个难题呢?
从 RL 的角度来看,这是 RL 问题中最简单的设置,上面的任务可以总结为以下空间:
- ****状态空间:无
- ****动作空间:【左】或【右】
- 奖励 : [1]或[0]
在训练过程中,RL 算法将重复上述任务(拉手臂)并评估所获得的回报,并递归地更新其策略。最终,通过评估政策权重,它应该能够给出一个结论,即哪只手臂是最好的拉。在这篇文章中可以看到更好的解释。
上下文强盗
上下文土匪问题是 n 臂土匪的扩展。如上图所示,假设吃角子老丨虎丨机不是只有 1 台而是 3 台,我们需要考虑对于特定的机器(状态)来说,拉哪个手臂最好。现在设置变成了:
- ****状态空间:【机器 A】、【机器 B】、【机器 C】
- ****动作空间:【左】或【右】
- 奖励 : [1]或[0]
4.3 实施
我们到底希望机器学会执行什么?遵循对于每一对时间序列的思想,它通过选择历史窗口、交易窗口、交易阈值和止损[动作]的最佳组合,学*最大化预期交易利润[报酬]。
换句话说,我们将其公式化为一个 N 武装土匪问题(无状态):
- ****状态空间:【无】(由虚拟状态确定—交易成本)
- ****动作空间:【历史窗口】、【交易窗口】、【交易阈值】、【止损】、【信心水平】
- ****奖励:【平均回报】
第 5 部分:将所有东西放在一起
现在我们可以走了。下面是的实现:
- 加载相关配置和价格数据
- 将它们标准化并分成训练集和测试集
- 创建状态空间和动作空间
- 创建和构建网络
- 创建学*对象并进行培训
- 从学*对象中提取记录并执行测试分析
S 设置
对 : JNJ-PG
数据周期:2018–01–01 至 2018–07–30
频率 : 1 分钟
状态:无(设置为固定交易成本 0.1%)
动作 :
—一、历史窗口:60 至 600 分钟,60 分钟步长
—交易窗口:120 到 1200 分钟,120 分钟一步
—三。交易门槛:(+/-)1 到 5,价格步长为 1
— iv。止损:(+/-)1 到 2 在交易阈值之上,价格步长为 0.5
—五、信心水平:90%或 95%
获利回吐水平 : 0
报酬:平均回报(如果是协整,否则设置为交易成本)
交易数量 : 1 个买卖信号的价差
校准价格:标准化
【T33
试运行后,我发现玻尔兹曼探索的概率输出可以达到 1。为了减轻异常高回报的影响,平均回报上限为 10 英镑。
配置
config_train.yml
步骤 1 和 2:加载相关的配置和价格数据,将它们标准化并分成训练集和测试集
步骤 3:创建状态空间和动作空间
步骤 4:创建和构建网络
步骤 5:创建学*对象并进行培训
步骤 6:从学*对象中提取记录,并执行测试分析
从培训结果来看,尽管有上限,平均奖励仍为正:
Positive expected reward in training
Distribution of training reward
以下测试使用从训练结果中获得的最佳操作,在每分钟进行交易,不包括最大可能的历史窗口和交易窗口:
****
No. of trades (pair) [LHS] and PnL [RHS] across testing samples (1-minute, 2018–5–29 to 2018–7–30)
或者,我们也可以使用滑索和 Pyfolio 进行更复杂的回溯测试。
虽然结果看起来很有希望,但在现实世界中,情况会因许多因素而变得复杂,如买卖价差、执行延迟、保证金、利息、零股等。然而,我们在这里的目的是给出一个例子,说明如何将各种技术结合起来,开发一个具有结构化机器学*组件的系统化交易工具。我希望这是一个愉快的页面给你。
回到第 2 部分:代码设计
Illustration of the code structure
2.1 配置
执行由配置(字典)管理。这个组件允许我们封装大量的执行并整理代码。它也可以用作附加参数的载体。
例如,在上一节中, API 的实例化。Tiingo 将配置作为输入,将其设置为一个属性。当它调用底层函数时,将从配置中提取输入参数,如开始日期、结束日期、令牌、每天的样本数量和数据频率。
config_data.yml for data fetching
目前只实现了一个配置。理想情况下,我们应该为不同的组件实现多种配置。
使用 PyYAML 包,代码可以识别T5 的字段。yaml /** 。 yml 文件并自动转换格式:**
***-空字段:加载到 **None
- True/False** :加载到布尔字段 True 或 **False
- 1.0** :加载到 float **1.0
- 1** :加载到 integer **1
- string** :加载到‘string’
-【1,2,3】【T32***
*****Folder:
Folder A:** Math Notes
**Folder B:** [Memo, Magazines]***
该包可以识别缩进并将其加载到字典中:
***{'Folder A': 'Math Notes', 'Folder B': ['Memo', 'Magazines']}***
检查 UTIL/FileIO.py 的读写功能:
2.2 数据 API
对于这一点,我们已经讨论了主要细节,所以我将跳过这一点。如果你想添加另一个 API,我建议你简单地创建另一个类,使用与类 Tiingo 中的 fetch 相同的接口。
2.3 战略
在中。/STRATEGY* 每个模块包含一个策略类别,每个策略应该由一个类表示。该类继承自一个抽象基类,该抽象基类要求它实现以下内容:***
- process() :由机器学*脚本在训练或测试时调用
- 奖励:定义 RL 奖励(即交易利润)的属性
- 记录:训练期间要存储的任何其他属性
在这个包中,我们可以找到一个策略类 EGCointegration ,它在实例化期间接受价格数据 x 和 y 以及其他参数。当底层函数需要样本数据集时,它们将调用 get_sample 函数从其数据属性中执行采样。
EGCointegration class in ./Strategy/Cointegration.py
在训练阶段,在每次迭代中,我们需要校准 p 值和系数,以决定是否以及如何触发配对交易。这些执行嵌入在同一个类中。当调用进程时,对象将自动从其数据属性执行采样并运行校准。基于校准的结果,该功能将获得奖励和记录,并将其设置为相应的属性。**
参见第三部分中关于协整及其测试的更多内容。**
Key functions for calibration in EGCointegration
2.4 基本构建模块、处理器和 ML 算法
这些组件高度集成,不仅由配置管理,而且由控制整个高度自动化的 ML 流程的定制代理管理。许多 ML 算法是硬编码的。这意味着如果需要微调逻辑,就必须修改代码,这有点不方便。在这里,虽然设计有点复杂,如果你能理解的风格,你将能够以任何方式扩展它。
最*,谷歌发布了一个名为 TF-Agents 的强化学*(RL)开源库。请随意检查这个出来。一些概念是相似的,但是我们代码的主要焦点是自动化,所以如果你想构建一个新的,你可以使用它作为基础。
2.4.1 基本构建模块
- 代理人
Agent class in Basic.py
它是 ML 中运行和控制流程的主体。在 RL 中,它有另一层含义:一般来说,它是接收环境状态并相应地决定采取什么行动的组件。代理类应该由机器学*类继承。它应该由一个网络对象和一个配置字典启动。主要功能包括:**
***- 对接:附加网络输入输出层
- assign_network :给代理对象分配新网络并连接
- set_session :设置 tensor flow
-get _ counter:从 config 中提取参数并获取一个 StepCounter 对象的字典用于循环或增量如变概率
-save _ model/restore _ modelckpt 文件 - 流程:训练或测试要实现的抽象方法***
- 网络
构建张量流神经网络的一种典型方式是这样的,其中的层和每个层中的参数都是硬编码的:
或者,我们也可以构建一个重复上述过程的函数,牺牲设置层参数的灵活性。
如果你想建立一个 ML 系统或一些带有 GUI 的东西,在保留自动化的同时,灵活地定制每一层的细节(即层类型、层输入、层参数),这里有一个建议:
Network and TFLayer in Basics.py
左边的两个函数在类网络下。**
- build_layers :它将一个字典 layer_dict 作为输入,通过依次添加从 TFLayer 类中选择的层来构建网络,如右侧所示。只要正确定义了每层的参数,就可以递归调用该函数,在当前网络中现有的最终层之上添加层。每个层都被设置为网络对象的属性,因此它们的名称必须是唯一的。**
- add_layer_duplicates :与 build_layers 类似,它接受一个 layer_dict 作为输入,并需要一个 n_copy 的输入,该输入指定在现有网络之上应该添加多少个由 layer_dict 规定的层的副本。通过连接副本中的图层名称和图层编号,将为复制的图层创建新名称。
例如:
创建网络的步骤:
- 发起一个网络对象。这必须由第一个输入层实例化,在本例中是 tf.placeholder。
- 基于 layer_dict1 构建网络。它指定了两个层:一个是实际上具有 5 个输出的 tf.one_hot 的 'one_hot' 层,另一个是具有 10 个输出的 TF . contrib . layers . fully _ connected 的 'coint1' 层。TF . contrib . layers . fully _ connected 的输入参数由关键字‘layer _ para’定义。**
- 通过添加 layer_dict2 规定的层的副本来扩展网络。具有 10 个输出的层‘coin T2’被添加到当前网络 3 次。**
因此,网络对象 N 现在总共应该有 6 个属性。它们中的每一个都是具有预定义属性的层:
由于网络的构建是基于层字典的,如果这种字典的生成是流线型的,那么自动化就开始起作用,并且我们不再需要在每次构建新的东西时对网络进行硬编码。
- 空间
基本上它指的是一个样本空间物体。它将一个 list 字典作为输入,并通过对 list 元素进行完全组合来创建样本空间。例如,对于以下示例空间:
***space_dict = {'dice': [1, 2, 3, 4, 5, 6],
'coin': ['H', 'T']}
S = Space.states_dict***
S 包含骰子和硬币的所有组合,共 12 个元素。它包含必要的函数,可将样本从字典转换为单个索引、索引列表或 one_hot 数组,反之亦然,以适应 TensorFlow 中不同类型的输入或输出载体。**
- 计步器
在训练期间,一些参数是递增的,例如 for 循环中的当前步长,或者学*速率被设置为可变的。我们甚至可能希望在实际步骤被触发之前添加一个缓冲区(即,学*速率在 100 次循环之后开始下降)。我们可以用一个计数器来执行上述操作,而不是在脚本中硬编码。该计数器还具有缓冲预训练步骤的能力。例如,实际计数值仅在 100 个缓冲步骤之后才开始改变。
2.4.2 处理器
一个处理器类应该将一个代理对象作为初始化的输入。当进程被调用时,它将从代理对象中提取相关参数,包括附加的配置字典,并将任何输出附加到作为代理属性的数据字典。我们实际上可以创建另一个对象来携带这些属性,但是为了简单起见,我们不要在这里重载这个结构。**
- 状态空间和动作空间
两者都继承父类空间,用于生成状态样本或动作样本。基于配置中指定的 方法 ,它们可以以不同的形式(即索引/一个热点/字典)或不同的方式(有/无探索)输出样本,用于不同的目的,如网络训练,或作为策略对象中 过程 函数的输入。**
StateSpace and ActionSpace in PROCESSOR/MachineLearning.py
- 奖励引擎
它采用一个包含进程方法的引擎对象。在我们的例子中,它将是一个 EGCointegration 对象。
RewardEngine class
- 探索
这篇文章很好的介绍了强化学*中的探索方法。该对象的目的是探索可能的操作。所选择的方法将向代理对象中的数据载体返回动作索引。当调用 ActionSpace 中的进程函数时,就实现了探索。
- 经验缓冲
这利用了这篇文章中的体验回放实现。目的是在训练过程中存储样本和结果,并从缓冲区重新采样,以允许代理从历史中重新学*。
- 记录器
最后但同样重要的是,我创建了一个记录器类,它可以用来跟踪存储在代理对象内部的数据字典中的记录。我们可以通过在配置文件的recorder data field字段中指定键名来选择我们希望它存储的字段:
****RecorderDataField:** [NETWORK_ACTION, ENGINE_REWARD]**
Recorder class
2.4.3 毫升算法
有了上面描述的组件,我们可以定制任何采用这些构建块的类,并创建一个运行过程。这是唯一需要为不同目的定制的部分,但对于类似的情况,逻辑仍然是相当标准化的。
例如,在这个项目中,我创建了一个上下文强盗类,它实际上可以执行 N 臂强盗或者上下文强盗运行,取决于状态的数量。如果我们想对 N 臂土匪问题运行它,我们可以只指定一个具有单一固定状态(虚拟)的状态空间。
ContextualBandit class in MAIN/Reinforcement.py
- init :初始化对象并继承父方法和属性。TensorFlow 机器学*属性也在这里定义。之后上面描述的所有处理器都会被组合实例化,以对象本身作为输入实参(【agent】)。
- update_network :从数据字典中提取样本,更新张量流层和网络。
- ****缓冲:如果配置中有指定,将样本存储在 ExperienceBuffer 对象中。
- create_sample_list :为经验缓冲创建样本。
- ****流程:控制培训或测试流程的主要程序。需要一个 tf。Session()并根据代理启动的 StepCounter 对象中的值执行循环。
放弃
这篇文章和相关的代码和内容纯粹是信息性的,所提供的任何信息都不构成对任何特定人的任何安全、交易或投资策略的任何建议。本文中描述的实施可能会有风险,市场状况可能会不稳定,并与上述时期不同。所有交易策略和工具的实施均由用户自担风险。
文献学
[1] Dickey,D. A .,Fuller,W. A .,具有单位根的自回归时间序列估计量的分布(1979),美国统计协会杂志。74(366): 427–431.
[2] Engle,R.F .,Granger,C.W.J .,《协整和误差修正:表示、估计和检验》(1987),计量经济学55(2):251–276
[3] Gatev,e .、Goetzmann,W.N .和 Rouwenhorst,K.G .,《配对交易:相对价值套利规则的表现》(2006 年),《金融研究评论》19(3):797–827
[4] Granger,C.W .,时间序列数据的一些性质及其在计量经济模型规范中的应用(1981),经济学杂志16(1):121–130
5 Johansen,s .,协整向量的统计分析(1988),《经济动态与控制杂志》12(2–3):231–254
[6] Krauss,c .,统计套利对交易策略:回顾与展望(2017),经济学调查杂志31(2):513–545
[7] Stock,J.H .,协整向量的最小二乘估计的渐*性质(1987),计量经济学55:277–302。
[8]萨顿,R.S .,巴尔托,A.G,《强化学*:导论》( 1998),麻省理工学院出版社,第二版
算法公平性的温和介绍
原文:https://towardsdatascience.com/a-gentle-introduction-to-algorithmic-fairness-46c825bdaf5d?source=collection_archive---------30-----------------------
算法公平问题的温和介绍:一些美国历史,法律动机,和四个带有反证的定义。
历史
在美国,借贷中的公平问题由来已久。
例如,划红线:
1935 年,联邦住房贷款银行委员会要求住房所有者贷款公司调查 239 个城市,并绘制“住宅安全地图”,以显示每个被调查城市的房地产投资安全水平。在地图上,“D 型”社区用红色标出,被认为是抵押贷款支持风险最高的地区..
’20 世纪 60 年代,社会学家约翰·麦克奈特创造了“红线”一词,用来描述银行基于社区人口统计数据而避开投资领域的歧视性做法。在红线的全盛时期,最常受到歧视的地区是市中心的黑人社区……'
划红线显然是不公平的,因为投资的决定不是基于个人房主偿还贷款的能力,而是基于位置;这个基础系统地拒绝贷款给一个种族群体,黑人。事实上,1988 年在《亚特兰大宪法日报》上发表的普利策奖系列文章第一部分表明,位置比收入更重要:“T10 在收入相同的稳定社区中(在亚特兰大市区),每 1000 户家庭中,白人社区总是获得最多的银行贷款。融合的社区得到的总是较少。黑人社区——包括市长的社区——收到的总是最少。
1968 年《公平住房法案》和 1977 年《社区再投资法案》就是为了打击住房和贷款中的这类不公平行为而通过的。
最*,在 2018 年,WUNC 报告称北卡罗来纳州一些城市的黑人和拉丁美洲人被拒绝的抵押贷款利率高于白人:
贷方和他们的贸易组织不否认他们拒绝有色人种的比率远远高于白人。但他们坚持认为,这种差异可以用该行业竭力隐瞒的两个因素来解释:潜在借款人的信用记录和整体债务收入比。他们特别指出三位数的信用评分——银行用来确定借款人是否有可能偿还贷款——在贷款决策中尤为重要。"
WUNC 的例子提出了一个有趣的观点:通过一个指标(按人口统计的贷款利率)看起来不公平是可能的,但通过另一个指标(根据信用历史和债务收入比判断的支付能力)看起来不公平是不可能的。衡量公平是复杂的。在这种情况下,我们无法判断贷款行为是否公平,因为我们无法获得这些特定群体的信用历史和债务收入比数据,来评估贷款人对差异的解释。
2007 年,美国联邦储备委员会(FRB) 报告了关于信用评分及其对信贷可用性和可负担性的影响。他们得出结论信用历史评分模型中包含的信用特征并不能代表种族,尽管不同的人口统计群体平均而言有着显著不同的信用评分,并且“对于给定的信用评分,不同的人口统计群体的信用结果——包括贷款绩效、可用性和可负担性的衡量指标——也是不同的。”该 FRB 研究支持贷方的主张,即信用评分可能解释抵押拒绝率的差异(因为人口统计群体具有不同的信用评分),同时也指出不同群体的信用结果不同。
这公平不公平?
定义公平
随着机器学*(ML)的普及,人们对 ML 中的公平、问责和透明越来越感兴趣(例如 fat* 会议和 fatml 研讨会)。
一些研究人员说,公平不是一个统计学概念,没有任何统计数据能够完全捕捉到它。有许多统计定义,人们试图联系(如果不是定义)公平。
首先,这里有两个在许多关于公平的讨论中出现的法律概念:
- 不同的待遇 :“根据《美国民权法案》第七章,由于受保护的特征(如种族或性别)而对某人的不平等行为。”如果目的是拒绝黑人贷款,红线就是完全不同的待遇。
- 三教九流冲击 :“惯例..这对具有受保护特征的一组人的不利影响比对另一组人的不利影响更大,即使规则适用..在形式上是中立的。”(“完全不同的影响原则在具有里程碑意义的美国最高法院格里戈斯诉杜克电力公司案(1971)中正式确立。1955 年,杜克电力公司制定了一项政策,规定雇员必须有高中文凭才能被考虑晋升,这大大限制了黑人雇员的资格。法院发现这一要求与工作表现几乎没有关系,因此认为它具有不合理的——也是非法的——完全不同的影响。”【corb 2018】)
[Lipt2017]指出这些是差异的法律概念,并为应用于机器学*分类器的奇偶技术概念创建了相应的术语:
- 处理奇偶校验:分类器应该对给定的受保护特征不敏感。在[Corb2018]中也被称为反分类,或“通过无意识的公平”
- 影响均等:在不同的群体中,做出肯定决定的人的比例应该是均等的。这也叫人口统计奇偶性,统计奇偶性,或者被保护阶层与分数的独立性[Fair2018]。
有大量关于算法公平性的文献。从[Corb2018]开始,又多了两个定义:
- 分类奇偶校验:某个给定的分类错误度量在由受保护属性定义的组之间是相等的。[Hard2016]称此为均等机会如果测量值为真阳性率,以及均等几率如果有两个均等测量值,即真阳性率和假阳性率。
- 校准:以风险分值为条件,结果独立于受保护属性。也就是现实符合风险评分。例如,预计有 20%违约几率的所有贷款中,约有 20%实际上违约了。
研究界对公平的理想统计定义缺乏共识。事实上,同时实现多个公平概念是不可能的结果([Klei2016] [Chou2017])。正如我们之前提到的,一些研究人员认为公平不是一个统计概念。
没有完美的定义
上面描述的每个统计定义都有反例。
待遇平等不公平地忽略了真正的差异。[Corb2018]描述了 COMPAS 评分用于预测累犯(某人如果出狱是否会犯罪)的案例。在控制了 COMPAS 评分和其他因素后,女性复发的可能性降低了。因此,在这个预测中忽略性可能会不公平地惩罚女性。请注意,平等信贷机会法案从法律上规定了待遇平等:“债权人在某些情况下可能会向你索要【受保护的阶级信息,如种族】,但在决定是否给你信贷或设定信贷条款时,他们可能不会使用这些信息。“因此,[Corb2018]暗示这种不公平是法律规定的。
影响均等并不能确保公平(人们反对配额),而且会削弱模型的准确性,损害模型对社会的效用。[Hard2016]在其导言中讨论了这个问题(使用术语“人口均等”)。
Corbett 等人[Corb2018]详细论述了分类奇偶性自然被违反:“当暴力累犯的基本比率在不同群体之间不同时,真实的风险分布也必然不同——无论在预测中使用了哪些特征,这种差异都将持续存在。
他们还认为,校准不足以防止不公平。他们假设的例子是,一家银行只根据邮政编码内的违约率发放贷款,而忽略了收入等其他属性。假设(1)在邮政编码范围内,白人和黑人申请者有相似的违约率;(2)黑人申请者居住在违约率相对较高的邮政编码区。那么,该银行的计划将会不公平地惩罚信誉良好的黑人申请者,但仍然是经过校准的。
结论
总之,可能的公平没有单一的衡量标准。我们对四个统计定义进行了旋风式的考察,其中两个由历史驱动,两个最*由机器学*驱动,并总结了每个定义的反驳意见。
这也意味着自动决定一个算法是否公平具有挑战性。开源公平测量包通过提供许多不同的测量方法来反映这一点。
然而,这并不意味着我们应该忽略统计数据。他们可以给我们一个主意,我们是否应该更仔细地看。精神食粮。我们应该好好喂养我们的大脑,因为它最有可能做出最后的决定。
(注意:这个问题是有争议的。我们的目的是以富有成效、尊重的方式加入对话。我们欢迎任何形式的反馈。)
感谢 克里希纳拉姆扎克·利普顿卢克·梅里克阿米特·卡帕 ,以及 克里希纳·加德 的反馈**
参考
- 亚历山德拉·乔尔德乔娃。"具有不同影响的公平预测:对累犯预测工具偏差的研究."大数据 5,第 2 期(2017 年 6 月 1 日):153–63。https://doi.org/10.1089/big.2016.0047。
- 科比特-戴维斯、萨姆和沙拉德-戈埃尔。"公平的测量和错误测量:公平机器学*的评论."ArXiv:1808.00023 [Cs],2018 年 7 月 31 日。http://arxiv.org/abs/1808.00023。
- [Fair2018]“公平与机器学*。”2019 年 4 月 9 日接入。https://fairmlbook.org/。
- [哈德 2016]哈特、莫里茨、埃里克·普莱斯和内森·斯雷布罗。"监督学*中的机会均等."ArXiv:1610.02413 [Cs],2016 年 10 月 7 日。http://arxiv.org/abs/1610.02413。
- [Klei2016]克莱恩伯格、乔恩、森迪尔·穆莱纳坦和马尼什·拉格哈万。"公平确定风险分值的内在权衡."ArXiv:1609.05807 [Cs,Stat],2016 年 9 月 19 日。http://arxiv.org/abs/1609.05807。
- 利普顿、扎卡里·c、亚历山德拉·乔尔德乔娃和朱利安·麦考利。"减轻 ML 的影响差异需要治疗差异吗?"ArXiv:1711.07076 [Cs,Stat],2017 年 11 月 19 日。【http://arxiv.org/abs/1711.07076】T42。
原载于 2019 年 4 月 23 日https://blog . fiddler . ai。**
阿帕奇箭与阿帕奇火花和熊猫的温柔介绍
原文:https://towardsdatascience.com/a-gentle-introduction-to-apache-arrow-with-apache-spark-and-pandas-bb19ffe0ddae?source=collection_archive---------1-----------------------
这一次我将尝试解释如何将 Apache Arrow 与 Apache Spark 和 Python 结合使用。首先,让我分享一些关于这个开源项目的基本概念。
[Apache Arrow]
Apache Arrow 是内存数据的跨语言开发平台。它为平面和层次数据指定了一种标准化的独立于语言的列内存格式,为现代硬件上的高效分析操作而组织。[ 阿帕奇箭头页
简而言之,它促进了许多组件之间的通信,例如,用 Python (pandas)读取 parquet 文件并转换为 Spark 数据帧、 Falcon 数据可视化或 Cassandra 而不用担心转换。
Overview Apache Arrow [Julien Le Dem, Spark Summit 2017]
一个好问题是问数据在内存中是什么样子的?Apache Arrow 利用列缓冲区来减少 IO 并提高分析处理性能。
Columnar In-memory [Apache Arrow page]
在我们的例子中,我们将使用 pyarrow 库来执行一些基本代码并检查一些特性。为了安装,我们有两个选项使用 conda 或 pip 命令*。
conda install -c conda-forge pyarrowpip install pyarrow
*建议在 Python 3 环境中使用 conda。
Apache Arrow with Pandas(本地文件系统)
将 Pandas 数据帧转换为 Apache 箭头表
import numpy as np
import pandas as pd
import pyarrow as pa
df = pd.DataFrame({'one': [20, np.nan, 2.5],'two': ['january', 'february', 'march'],'three': [True, False, True]},index=list('abc'))
table = pa.Table.from_pandas(df)
Pyarrow 表到熊猫数据框
df_new = table.to_pandas()
读取 CSV
from pyarrow import csv
fn = ‘data/demo.csv’
table = csv.read_csv(fn)
df = table.to_pandas()
从 Apache 编写拼花文件箭头
import pyarrow.parquet as pq
pq.write_table(table, 'example.parquet')
阅读拼花文件
table2 = pq.read_table(‘example.parquet’)
table2
从拼花文件中读取一些列
table2 = pq.read_table('example.parquet', columns=['one', 'three'])
从分区数据集读取
dataset = pq.ParquetDataset(‘dataset_name_directory/’)
table = dataset.read()
table
将拼花文件转换成熊猫数据帧
pdf = pq.read_pandas('example.parquet', columns=['two']).to_pandas()
pdf
避开熊猫指数
table = pa.Table.from_pandas(df, preserve_index=False)
pq.write_table(table, 'example_noindex.parquet')
t = pq.read_table('example_noindex.parquet')
t.to_pandas()
检查元数据
parquet_file = pq.ParquetFile(‘example.parquet’)
parquet_file.metadata
参见数据模式
parquet_file.schema
时间戳
记住熊猫使用纳秒,所以为了兼容你可以用毫秒截断。
pq.write_table(table, where, coerce_timestamps='ms')
pq.write_table(table, where, coerce_timestamps='ms', allow_truncated_timestamps=True)
压缩
默认情况下,Apache arrow 使用 snappy 压缩(不那么压缩,但更容易访问),尽管也允许使用其他编解码器。
pq.write_table(table, where, compression='snappy')
pq.write_table(table, where, compression='gzip')
pq.write_table(table, where, compression='brotli')
pq.write_table(table, where, compression='none')
此外,可以在一个表中使用多种压缩
pq.write_table(table, ‘example_diffcompr.parquet’, compression={b’one’: ‘snappy’, b’two’: ‘gzip’})
写一个分区拼花表
df = pd.DataFrame({‘one’: [1, 2.5, 3],
‘two’: [‘Peru’, ‘Brasil’, ‘Canada’],
‘three’: [True, False, True]},
index=list(‘abc’))
table = pa.Table.from_pandas(df)
pq.write_to_dataset(table, root_path=’dataset_name’,partition_cols=[‘one’, ‘two’])
- 兼容性说明:如果您使用 pq.write_to_dataset 创建一个将由 HIVE 使用的表,则分区列值必须与您正在运行的 HIVE 版本的允许字符集兼容。
带 HDFS(远程文件系统)的 Apache Arrow】
Apache Arrow 附带了与 Hadoop 文件系统的基于 c++(T3)的接口的绑定。这意味着我们可以从 HDFS 读取或下载所有文件,并直接用 Python 解释。
连接
主机是 namenode,端口通常是 RPC 或 WEBHDFS 更多的参数像用户,kerberos 票证是允许的。强烈建议阅读所需的环境变量。
import pyarrow as pa
host = '1970.x.x.x'
port = 8022
fs = pa.hdfs.connect(host, port)
- 可选,如果您的连接是在数据或边缘节点可能使用的前端
fs = pa.hdfs.connect()
将拼花文件写入 HDFS
pq.write_to_dataset(table, root_path=’dataset_name’, partition_cols=[‘one’, ‘two’], filesystem=fs)
从 HDFS 读取 CSV
import pandas as pd
from pyarrow import csv
import pyarrow as pa
fs = pa.hdfs.connect()
with fs.open(‘iris.csv’, ‘rb’) as f:
df = pd.read_csv(f, nrows = 10)
df.head()
Reading CSV from HDFS
从 HDFS 读取拼花文件
从 HDFS 读取拼花文件有两种形式
使用熊猫和 Pyarrow 引擎
import pandas as pd
pdIris = pd.read_parquet(‘hdfs:///iris/part-00000–27c8e2d3-fcc9–47ff-8fd1–6ef0b079f30e-c000.snappy.parquet’, engine=’pyarrow’)
pdTrain.head()
Pyarrow .拼花地板
import pyarrow.parquet as pq
path = ‘hdfs:///iris/part-00000–71c8h2d3-fcc9–47ff-8fd1–6ef0b079f30e-c000.snappy.parquet’
table = pq.read_table(path)
table.schema
df = table.to_pandas()
df.head()
其他文件扩展名
因为我们可以存储任何类型的文件(SAS、STATA、Excel、JSON 或 objects),所以大多数文件都很容易被 Python 解释。为了实现这一点,我们将使用 open 函数返回一个缓冲区对象,许多 pandas 函数如 read_sas 、 read_json 可以接收这个对象作为输入,而不是一个字符串 URL。
斯堪的纳维亚航空公司
import pandas as pd
import pyarrow as pa
fs = pa.hdfs.connect()
with fs.open(‘/datalake/airplane.sas7bdat’, ‘rb’) as f:
sas_df = pd.read_sas(f, format='sas7bdat')
sas_df.head()
擅长
import pandas as pd
import pyarrow as pa
fs = pa.hdfs.connect()
with fs.open(‘/datalake/airplane.xlsx’, ‘rb’) as f:
g.download('airplane.xlsx')
ex_df = pd.read_excel('airplane.xlsx')
JSON
import pandas as pd
import pyarrow as pa
fs = pa.hdfs.connect()
with fs.open(‘/datalake/airplane.json’, ‘rb’) as f:
g.download('airplane.json')
js_df = pd.read_json('airplane.json')
从 HDFS 下载文件
如果我们只是需要下载文件,Pyarrow 为我们提供了下载功能,将文件保存在本地。
import pandas as pd
import pyarrow as pa
fs = pa.hdfs.connect()
with fs.open(‘/datalake/airplane.cs’, ‘rb’) as f:
g.download('airplane.cs')
上传文件到 HDFS
如果我们只是需要下载文件,Pyarrow 为我们提供了下载功能,将文件保存在本地。
import pyarrow as pa
fs = pa.hdfs.connect()
with open(‘settings.xml’) as f:
pa.hdfs.HadoopFileSystem.upload(fs, ‘/datalake/settings.xml’, f)
阿帕奇箭带阿帕奇火花
Apache Arrow 从版本 2.3 开始与 Spark 集成,存在关于优化时间、避免序列化和反序列化过程以及与其他库集成的良好演示,如来自 Holden Karau 的关于在 Spark 上加速 Tensorflow Apache Arrow 的演示。
还有其他有用的文章,比如由 Brian Cutler 发表的文章,以及 Spark 的官方文档中非常好的例子
Apache Arrow 的一些有趣用法是:
- 加速从 Pandas 数据帧到 Spark 数据帧的上转换
- 加速从 Spark 数据帧到 Pandas 数据帧的上转换
- 使用熊猫 UDF(又名矢量化 UDF)
- 使用 Apache Spark 优化 R
第三项将是下一篇文章的一部分,因为这是一个非常有趣的话题,以便在不损失性能的情况下扩展 Pandas 和 Spark 之间的集成,对于第四项,我建议您阅读文章(发表于 2019 年!)去了解更多。
让我们先测试熊猫和 Spark 之间的转换,不做任何修改,然后允许 Arrow。
from pyspark.sql import SparkSession
warehouseLocation = “/antonio”
spark = SparkSession\
.builder.appName(“demoMedium”)\
.config(“spark.sql.warehouse.dir”, warehouseLocation)\
.enableHiveSupport()\
.getOrCreate()#Create test Spark DataFrame
from pyspark.sql.functions import rand
df = spark.range(1 << 22).toDF(“id”).withColumn(“x”, rand())
df.printSchema()#Benchmark time
%time pdf = df.toPandas()
spark.conf.set(“spark.sql.execution.arrow.enabled”, “true”)
%time pdf = df.toPandas()
pdf.describe()
在结果中使用箭头来减少时间转换显然更方便。
Optimizing transformation from Spark Data Frame to Pandas
如果我们需要测试相反的情况(熊猫引发 df ),我们也能及时看到优化。
%time df = spark.createDataFrame(pdf)
spark.conf.set("spark.sql.execution.arrow.enabled", "false")
%time df = spark.createDataFrame(pdf)
df.describe().show()
总之
这篇文章的目的是发现和理解 Apache Arrow,以及它如何与 Apache Spark 和 Pandas 一起工作,我还建议你查看它的官方页面,以了解更多关于其他可能的集成,如 CUDA 或 C++,如果你想更深入地了解 Apache Spark,我认为 Spark:权威指南是一本很好的书。
PS 如果你有任何问题,或者想要澄清一些事情,你可以在 Twitter 和 LinkedIn 找到我。我最*发表了 一篇关于 Apache Druid 的温和介绍,这是一个新的 Apache 项目,非常适合分析数十亿行。
[## Google 云平台中 Apache Druid 的温和介绍
使得分析数十亿行变得容易
towardsdatascience.com](/a-gentle-introduction-to-apache-druid-in-google-cloud-platform-c1e087c87bf1)
Google 云平台中 Apache Druid 的温和介绍
原文:https://towardsdatascience.com/a-gentle-introduction-to-apache-druid-in-google-cloud-platform-c1e087c87bf1?source=collection_archive---------13-----------------------
使得分析数十亿行变得容易
Druid UI
概念和目的
为了对阿帕奇德鲁伊有一个清晰的理解,我将参考官方文档中的内容:
Apache Druid(孵化)是一个实时分析数据库,旨在对大型数据集进行快速切片分析(【OLAP】【查询】)。Druid 最常被用作支持实时接收、快速查询性能和高正常运行时间非常重要的用例的数据库。
Druid Logo [Meetup Group Photo Album]
在我的 Druid 简历中,我们不仅可以批量分析数十亿行,还可以实时分析,因为它与不同的技术有许多集成,如 Kafka、云存储、S3、Hive、HDFS、DataSketches、Redis 等。
德鲁伊最有趣的特征是:
- 云原生,轻松实现水平扩展
- 支持 SQL 分析数据
- API REST 支持查询或上传数据
在 GCP 测试 Druid 的目的是需要一种工具,可以批量上传数百万行(面向事件),然后使用传统的数据可视化工具进行分析,如 Tableau 或 Qlik,将 Druid 作为主要的处理引擎,所以因为我不知道服务器的正确数量,所以必须使用灵活的环境,如 GCP,并从最简单的部署开始。
一般建筑
对于一个生产集群,Druid 主要由 6 个进程组成:协调器、霸王、代理、历史、中间管理器和路由器,其中建议组织成 3 种类型的服务器:主服务器、查询服务器和数据服务器。根据需要,这些服务器可能不止一台。
主人
由协调者和支配者组成。
管理数据接收和可用性:它负责启动新的接收作业,并协调“数据服务器”上数据的可用性
查询
由路由器和代理组成。
提供用户和客户端应用程序交互的端点,将查询路由到数据服务器或其他查询服务器[ Druid 文档
数据
由中层管理者和历史管理者组成。
执行摄取作业并存储可查询的数据[ Druid 文档
其他组件
除了三个服务器和六个服务之外,Druid 还需要一个元数据存储,深度存储对于理解 Druid 读取数据的来源以及负责与所有组件通信也很重要。
元数据存储
基本上用于存储关于系统的元数据(审计、数据源模式、任务等。).对于实验环境,建议使用 Derby ,尽管对于生产目的,MySQL 或 PostgreSQL 是最佳选择。
Derby for a non-production cluster [Apache Derby website]
深度存储
Druid 为接收的数据使用单独的存储,这意味着该过程与存储分离,使其成为一种容错技术。一些深度存储技术有云存储、亚马逊 S3、HDFS、Redis 等。
Google Cloud Storage Logo [DataKitchen]
数据摄取
Druid 中的所有数据都被组织成 段、,这些数据文件通常每个都有几百万行。在 Druid 中加载数据被称为摄取或索引 ,包括从源系统读取数据并基于该数据创建数据段。[ 德鲁伊文献 ]
德鲁伊完全支持批处理和流式摄取,支持的一些技术有 Apache Kafka、Kinesis、云存储和本地存储。
Druid support Streaming sources like Apache Kafka [Kafka Website]
动物园管理员
德鲁伊使用 Zookeeper 来整合所有的服务。对于实验,你可以使用德鲁伊自带的 Zookeeper,而对于生产来说,必须单独安装它,一个好的做法是为 Zk 准备一个自己的服务器。
ZooKeeper is the coordinator for all the Druid services [Wikipedia]
初始图
考虑到所有组件,我们可以创建一个代表生产集群 Google 云平台的架构图。
GCP Diagram
建立在 GCP 的基础上
对于本文,我将使用 Druid 独立服务器,Apache Derby 作为深度存储,云存储作为元数据服务器。虽然它包含了所有的特性,所以我们没有遗漏任何东西。
德鲁伊单服务器
我们将按照文档中的建议将 Druid 部署为 IAS,好的配置是 4CPU/16GB RAM。您可以使用 UI 或通过 Cloud Shell 提交来创建计算实例。
#Using Cloud Shellgcloud beta compute --project=[PROJECT-ID] instances create instance-druid --zone=us-central1-a --machine-type=n1-standard-4 --subnet=default --network-tier=PREMIUM --maintenance-policy=MIGRATE --service-account=[SERVICE-ACCOUNT] --scopes=https://www.googleapis.com/auth/devstorage.read_write,https://www.googleapis.com/auth/logging.write,https://www.googleapis.com/auth/monitoring.write,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly,https://www.googleapis.com/auth/trace.append --image=debian-9-stretch-v20191014 --image-project=debian-cloud --boot-disk-size=15GB --boot-disk-type=pd-standard --boot-disk-device-name=instance-druid --reservation-affinity=any
重要:默认情况下,您的权限/范围到devstorage (google cloud storage)
是read_only
您需要更改为read_write
。
安装德鲁伊
我们使用 SSH 连接到实例,并遵循以下步骤:
- 下载的最新版本,在当时,是 0.16
- 解压缩文件
wget [https://www-eu.apache.org/dist/incubator/druid/0.16.0-incubating/apache-druid-0.16.0-incubating-bin.tar.gz](https://www-eu.apache.org/dist/incubator/druid/0.16.0-incubating/apache-druid-0.16.0-incubating-bin.tar.gz)
tar -xzf apache-druid-0.16.0-incubating-bin.tar.gz
cd apache-druid-0.16.0-incubating
注意:有趣的是,我们下载了与安装生产集群的人相同的 Druid 版本和相同的文件,没有version lite.
这意味着我们可以在以后将其作为主节点、数据节点或查询节点重用。
- 下载动物园管理员
curl https://archive.apache.org/dist/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz -o zookeeper-3.4.14.tar.gz
tar -xzf zookeeper-3.4.14.tar.gz
mv zookeeper-3.4.14 zk
- 浏览文件
如果你这样做了ls conf/druid/cluster
,你将会找到对应于数据服务器、主服务器和查询服务器的文件。在这种情况下,我们可以欣赏 Druid 的模块化,例如,如果您想将此安装用作数据服务器,您只需运行相应的.sh
文件,不需要更改任何内容,这同样适用于 Query 和 Master。
Production folders
在我们的例子中,我们将启动micro-quickstart
Differents size for Druid single-server
正如我们注意到的,这个微型快速入门提供了所有的服务
Druid services included in the single-server
- 安装 Java8 和 Perl
sudo apt-get install openjdk-8-jdk
sudo apt-get install libmodule-install-perl
- 创建一个 SSH 隧道:Druid 默认使用端口 8888,所以使用云 Shell 你可以建立一个到它的隧道或者有可能建立一个防火墙规则来打开这个端口。
#${PROJECT} is your GCP project ID
#${ZONE} is the zone of your VMs in this case us-central1-a
gcloud compute ssh ${HOSTNAME} \
--project=${PROJECT} --zone=${ZONE} -- \
-4 -N -L 8081:${HOSTNAME}:8888
- 快跑!(在另一个云壳里)
./bin/start-micro-quickstart
Druid running
- 德鲁伊界面工作!
Druid landing page
深度存储
正如我提到的,默认情况下,深度存储是本地的,因此在这种情况下,我们将修改为指向云存储。
- 停止德鲁伊服务器(Ctrl+c)
_ _common . runtime . properties 这个文件非常重要它包含:
- 德鲁伊扩展
druid.extensions.loadList=["druid-google-extensions", “druid-hdfs-storage”, “druid-kafka-indexing-service”, “druid-datasketches”]
- 动物园管理员 ip
druid.zk.service.host=localhost
druid.zk.paths.base=/druid
- 元数据的引用
druid.metadata.storage.type=derby
druid.metadata.storage.connector.connectURI=jdbc:derby://localhost:1527/var/druid/metadata.db;create=true
druid.metadata.storage.connector.host=localhost
druid.metadata.storage.connector.port=1527
- 深层存储的引用。
druid.storage.type=local
druid.storage.storageDirectory=var/druid/segments
此外,您可以在生产中为所有类型的服务器找到相同的文件。
我们来修改一下:
vi conf/druid/single-server/micro-quickstart/_common/common.runtime.properties
添加德鲁伊扩展druid-google-extensions
注释引用本地,并添加对谷歌云存储的引用
# For Google Cloud Storage
druid.storage.type=goole
druid.google.bucket=[BUCKET-NAME]
druid.google.prefix=[FOLDER-PATH]
退出并保存:wq
元数据
Druid 在使用 MySQL 或 Postgres 时有更好的性能。在这个机会中,我们将启动一个云 SQL 实例并连接到我们的服务器。
注意:在防火墙规则中允许 Druid IP 和 Cloud SQL IP 的入口/出口。
我们再修改一下:
vi conf/druid/single-server/micro-quickstart/_common/common.runtime.properties
- 注释所有对 Derby 的引用,并添加 MySQL 的凭证
druid.metadata.storage.type=mysql
druid.metadata.storage.connector.connectURI=jdbc:mysql://druiddb:3306/druid
druid.metadata.storage.connector.user=.[USER]
druid.metadata.storage.connector.password=[PASSWORD]
- 再次启动我们的服务器
./bin/start-micro-quickstart
基本摄入
Druid 允许 as 上传来自不同来源的数据,将这些数据组织成段(保存在深层存储和 MySQL 的元数据中),我们可以在那里查询并开始分析数据。可以通过四种方式摄取数据:
- 使用 Druid UI(数据加载器)
Data Loader
- JSON 任务
- 命令行
- API Rest
出于我们的目的,我们可以从图形选项开始,并使用可用的快速入门数据。
- 选择加载数据,然后选择本地数据
- 相应地完成基本目录和文件过滤
quickstart/tutorial/
wikiticker-2015-09-12-sampled.json.gz
Uploading data using Druid UI
- 按下 next(建议仔细阅读)并在配置模式步骤中停止,这里我们可以看到在 Pase 时间步骤中添加的_ _ 时间列。这个列很重要,因为 Druid 有基于时间的分区。此外,我们可以观察用于汇总的查询粒度字段,保持不变。
Query granularity
- 在最后一步,我们看到 JSON 已经完成了所有的配置,并准备好提交,这将生成一个任务。
JSON with all the configurations
- 有可能看到运行任务生成
Task running
- 成功!
Success
查询数据
用户可以通过 SQL 处理数据,也可以使用 REST API。
Querying data
推荐
- For exploration 建议保留本文中描述的体系结构,因为以后可以将数据迁移到更大的集群中。
- 尝试测试所有的 SQL 函数并注意其优势,例如,再次运行相同的查询,您可以看到时间的显著减少,这是因为 Druid 缓存。
- 如果您有自己的数据,可以上传(CSV 或 JSON)到
apache-druid-0.16.0-incubating/quickstart/tutorial/
- 在上图中,您可以看到一些列,如“sum_added”、“sum_deleted”和“sum_delta”。这些列是在上传期间创建的,您可以省略或添加其他的聚合列。
- 如果您想要更好的性能,建议您在创建虚拟机时选择 SSD 存储。
后续步骤
在德鲁伊中存在许多需要测试的特性,我希望在下一篇文章中介绍。
- 用户管理(角色、身份验证和授权)
- 使用 REST API 上传和查询数据
- 查找
- 连接到数据可视化工具
- 数据和查询服务器的水平扩展
- 上传大数据源的调优
- 查询和并发支持调优
- 其他扩展如 Apache Data Sketchs 或 Redis
- 将数据和元数据迁移到另一个 Druid 集群
- 升级集群
- 摄取流数据
如果您想更进一步部署生产集群,请查看文章表单 Jesús Méndez Galvez 此处。
PS 如果你有任何问题,或者想要澄清一些事情,你可以在 Twitter 和 LinkedIn 上找到我。如果你想了解阿帕奇 Arrow 和阿帕奇 Spark 我有一篇文章对阿帕奇 Arrow 与阿帕奇 Spark 和 Pandas 有一些例子。
[## 阿帕奇箭与阿帕奇火花和熊猫的温柔介绍
这一次我将尝试解释如何将 Apache Arrow 与 Apache Spark 和 Python 结合使用。首先…
towardsdatascience.com](/a-gentle-introduction-to-apache-arrow-with-apache-spark-and-pandas-bb19ffe0ddae)
客户细分的简明介绍
原文:https://towardsdatascience.com/a-gentle-introduction-to-customer-segmentation-375fb4346a33?source=collection_archive---------21-----------------------
使用 K-Means 聚类来理解营销响应
Photo by Nick Karvounis on Unsplash
概观
我这篇文章的目的是要表明,你并不总是需要超级复杂和精密的机器学*模型来从你的数据中获得有意义的见解。
对于这个迷你项目,我使用流行的 K-Means 聚类 算法,根据客户对一系列营销活动的反应对他们进行细分。这种技术相对容易实现,但它允许我从我的数据中收集大量信息,并挖掘我的客户群中有趣的行为模式。
什么是市场细分?
市场细分 是指根据共同的属性、兴趣和行为将现有和/或潜在客户的消费市场划分为多个群体(或细分市场)的过程。
基本概念是,拥有共同特征的消费者更有可能以相似的方式对营销传播做出回应,这样公司就可以以更相关、更有效的方式接触每个群体。
什么是 K-Means 聚类?
K-Means 聚类是 无监督学* 建模家族的一部分,这是一套用于在尚未标记、分类或归类的数据中寻找模式的技术。由于这种方法不要求有一个聚类目标,它可以在客户细分的探索阶段有很大的帮助。
基本思想是,分配到一个组的客户尽可能相似,而属于不同组的客户尽可能不相似。每个聚类由其centre
表示,对应于分配给该聚类的元素的平均值。
为了说明这个原理,假设你有一组像下图中那样的元素,并想把它们分成 3 个簇
K-Means 将为您做的是将它们分组在每个簇的中间或centre
,这里用“X”的表示,以最小化每个元素到其centre
的距离的方式
那么这如何帮助你更好地了解你的客户?嗯,在这种情况下,你可以利用他们的行为(具体来说,他们选择或不选择哪种优惠)作为一种方式,将他们与想法相似的客户分组。现在,您可以研究每一组,发掘趋势和模式,并用它们来塑造未来的产品。
稍微技术性一点的说明,重要的是要提到有许多 K-Means 算法可用( Hartigan-Wong 、 Lloyd 、 MacQueen 等等),但它们都有相同的基本概念:每个元素都被分配到一个聚类中,从而使到centre
的欧几里德距离的平方和最小化——这个过程也被称为使总数最小化
加载包
**library**(tidyverse)
**library**(lubridate)
**library**(knitr)
**library**(readxl)
**library**(broom)
**library**(umap)
**library**(ggrepel)
数据
数据集来自约翰·福尔曼的书数据智能。它包含虚构葡萄酒零售商的促销数据,包括 32 次促销的详细信息(包括葡萄酒品种、最低购买量、折扣百分比和原产国)以及 100 名客户及其响应的促销的列表。
offers_tbl <- **read_excel**('../00_data/WineKMC.xlsx',
sheet = 'OfferInformation')offers_tbl <- offers_tbl %>%
**set_names**(**c**('offer', 'campaign',
'varietal', 'min_qty_kg',
'disc_pct','origin','past_peak')
)**head**(offers_tbl)## # A tibble: 6 x 7
## offer campaign varietal min_qty_kg disc_pct origin past_peak
## <dbl> <chr> <chr> <dbl> <dbl> <chr> <chr>
## 1 1 January Malbec 72 56 France FALSE
## 2 2 January Pinot Noir 72 17 France FALSE
## 3 3 February Espumante 144 32 Oregon TRUE
## 4 4 February Champagne 72 48 France TRUE
## 5 5 February Cabernet~ 144 44 New Zeala~ TRUE
## 6 6 March Prosecco 144 86 Chile FALSEtransac_tbl <- **read_excel**('../00_data/WineKMC.xlsx',
sheet = 'Transactions')transac_tbl <- transac_tbl %>%
**set_names**(**c**('customer', 'offer')
)**head**(transac_tbl)## # A tibble: 6 x 2
## customer offer
## <chr> <dbl>
## 1 Smith 2
## 2 Smith 24
## 3 Johnson 17
## 4 Johnson 24
## 5 Johnson 26
## 6 Williams 18
数据需要被转换成一个User-Item format
(又名客户-产品矩阵),顶部是客户,下方是报价。单元格中填充了 0 的和 1 的,其中 1 的表示客户是否对特定报价做出了回应。
这种矩阵也被称为二进制评级矩阵和不需要标准化。
wine_tbl <- transac_tbl %>%
**left_join**(offers_tbl) %>%
**mutate**(value = 1) %>%
**spread**(customer,value, fill = 0) **head**(wine_tbl)## # A tibble: 6 x 107
## offer campaign varietal min_qty_kg disc_pct origin past_peak
## <dbl> <chr> <chr> <dbl> <dbl> <chr> <chr>
## 1 1 January Malbec 72 56 France FALSE
## 2 2 January Pinot Noir 72 17 France FALSE
## 3 3 February Espumante 144 32 Oregon TRUE
## 4 4 February Champagne 72 48 France TRUE
## 5 5 February Cabernern~ 144 44 New Zea~ TRUE
## 6 6 March Prosecco 144 86 Chile FALSE
## # ... with 100 more variables: Adams <dbl>, Allen <dbl>, Anderson <dbl>, Bailey <dbl>, Baker <dbl>, Barnes <dbl>, ...
对客户进行聚类
K-Means 算法附带了 stats 包,这是 R 中的核心系统库之一,使用起来相当简单。我只需要将几个参数传递给 kmeans() 函数。
user_item_tbl <- wine_tbl[,8:107]**set.seed**(196)
kmeans_obj <- user_item_tbl %>%
**kmeans**(centers = 5, # number of clusters
nstart = 100, # number of random sets to be chosen
iter.max = 50) # max number of iterations allowed
我可以用broom
包中的glance()
快速检查模型,它提供了模型级统计数据的摘要
**glance**(kmeans_obj) %>% **glimpse**()## Observations: 1
## Variables: 4
## $ totss <dbl> 283.1875
## $ tot.withinss <dbl> 189.7255
## $ betweenss <dbl> 93.46201
## $ iter <int> 3
真正需要关注的一个指标是总的类内平方和(或tot.withinss
),因为类的最佳数量是最小化tot.withinss
的数量。
所以我想为不同数量的集群拟合 k-means 模型,看看在哪里tot.withinss
达到最小值。
首先,我为一定数量的centers
(本例中为 4)构建一个函数,并检查它是否在glance()
上工作。
kmeans_map <- **function**(centers = 4) {
user_item_tbl %>%
**kmeans**(centers = centers,
nstart = 100,
iter.max = 50)
}4 %>% **kmeans_map**() %>% **glance**()## # A tibble: 1 x 4
## totss tot.withinss betweenss iter
## <dbl> <dbl> <dbl> <int>
## 1 283\. 203\. 80.0 2
然后,我创建了一个嵌套 tibble ,这是一种在数据框中“嵌套”列的方式。
嵌套数据框的伟大之处在于,您可以在其中放置任何您想要的东西:列表、模型、数据框、绘图等!
kmeans_map_tbl <- **tibble**(centers = 1:15) %>%
# create column with centres **mutate**(k_means = centers %>%
**map**(kmeans_map)) %>%
# iterate `kmeans_map` row-wise to
# gather kmeans models for each centre **mutate**(glance = k_means %>%
**map**(glance))
# apply `glance()` row-wise to gather
# each model’s summary metrics kmeans_map_tbl %>% **glimpse**()## Observations: 15
## Variables: 3
## $ centers <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, ...
## $ k_means <list> [<1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ...
## $ glance <list> [<tbl_df[1 x 4]>, <tbl_df[1 x 4]>, ...
最后,我可以构建一个scree plot
,并在图上寻找“肘部”,即额外集群的数量趋于稳定的地方。在这种情况下, 5 似乎是一个最佳数字,因为 6 的tot.withinss
下降不如前一个明显。
kmeans_map_tbl %>%
**unnest**(glance) %>% *# unnest the glance column*
**select**(centers,
tot.withinss) %>% *# select centers and tot.withinss*
**ggplot**(**aes**(x = centers, y = tot.withinss)) +
**geom_line**(colour = 'grey30', size = .8) +
**geom_point**(colour = 'green4', size = 3) +
**geom_label_repel**(**aes**(label = centers),
colour = 'grey30') +
**theme_light**() +
**labs**(title = 'Scree Plot')
将片段可视化
现在我已经确定了集群的最佳数量,我想把它们可视化。为此,我使用了(均匀流形逼*和投影),这是一种维度缩减技术,可以以类似于 主成分分析 和 t-SNE 的方式用于聚类可视化。
首先,我创建一个 umap 对象,取出layout
参数(包含可用于可视化数据集的坐标),将其格式更改为 tibble,并从wine_tbl
中附加offer
列。
umap_obj <- user_item_tbl %>% **umap**()
umap_tbl <- umap_obj$layout %>%
**as_tibble**() %>% *# change to a tibble*
**set_names**(**c**('x', 'y')) %>% *# remane columns*
**bind_cols**(wine_tbl %>% **select**(offer)) *# attach offer reference*
然后,我从嵌套表中pluck
出第 5 个 kmeans 模型,将 cluster 参数从kmeans
函数附加到输出,并将 offer 和 cluster 加入 umap_tbl。
umap_kmeans_5_tbl <- kmeans_map_tbl %>%
**pull**(k_means) %>%
**pluck**(5) %>% *# pluck element 5*
broom::**augment**(wine_tbl) %>% *# attach .cluster to the tibble*
**select**(offer, .cluster) %>%
**left_join**(umap_tbl,
by = 'offer') *# join umap_tbl by offer*
最后,我可以看到星团的 UMAP 投影。plotly
增加了一些很好的交互性,让图表变得栩栩如生!
umap_kmeans_5_tbl %>%
**mutate**(label_text = **str_glue**('Offer: {offer}
Cluster: {.cluster}')) %>%
**ggplot**(**aes**(x,y, colour = .cluster)) +
**geom_point**() +
**geom_label_repel**(**aes**(label = label_text), size = 3) +
**theme_light**() +
**labs**(title = 'UMAP 2D Projections of K-Means Clusters',
caption = "") +
**theme**(legend.position = 'none')
评估集群
现在我们终于可以更仔细地观察单个聚类,看看 K-Means 识别出了什么。
但是,让我们首先将所有信息放在一个数据框中。
cluster_trends_tbl <- wine_tbl %>%
**left_join**(umap_kmeans_5_tbl) %>%
**arrange**(.cluster) %>%
**select**(.cluster, offer:past_peak)
群组 1 和 2
集群 1 中的顾客购买大量的起泡酒(香槟和普罗塞克),而第二细分市场中的顾客喜欢购买不同品种的少量。
cluster_trends_tbl %>%
**filter**(.cluster ==1 | .cluster ==2) %>%
**count**(.cluster, varietal, origin, min_qty_kg, disc_pct) %>%
**select**(-n)## # A tibble: 9 x 5
## .cluster varietal origin min_qty_kg disc_pct
## <fct> <chr> <chr> <dbl> <dbl>
## 1 1 Champagne France 72 48
## 2 1 Champagne New Zealand 72 88
## 3 1 Prosecco Chile 144 86
## 4 2 Espumante Oregon 6 50
## 5 2 Espumante South Africa 6 45
## 6 2 Malbec France 6 54
## 7 2 Merlot Chile 6 43
## 8 2 Pinot Grigio France 6 87
## 9 2 Prosecco Australia 6 40
群组 3 和 4
当谈到葡萄酒时,这些群体中的顾客有非常特殊的口味:那些在第三部分的顾客偏爱黑皮诺,而第四组的顾客只购买大量的法国香槟。
cluster_trends_tbl %>%
**filter**(.cluster ==3 | .cluster ==4 ) %>%
**group_by**() %>%
**count**(.cluster, varietal, origin, min_qty_kg, disc_pct) %>%
**select**(-n)## # A tibble: 6 x 5
## .cluster varietal origin min_qty_kg disc_pct
## <fct> <chr> <chr> <dbl> <dbl>
## 1 3 Pinot Noir Australia 144 83
## 2 3 Pinot Noir France 72 17
## 3 3 Pinot Noir Germany 12 47
## 4 3 Pinot Noir Italy 6 34
## 5 4 Champagne France 72 63
## 6 4 Champagne France 72 89
第 5 组
****第五部分更难分类,因为它包含许多不同的属性。唯一明显的趋势是,这一细分市场的顾客选择了所有可用的赤霞珠葡萄酒。
cluster_trends_tbl %>%
**filter**(.cluster ==5 ) %>%
**count**(.cluster, varietal, origin, min_qty_kg, disc_pct) %>%
**select**(-n)## # A tibble: 17 x 5
## .cluster varietal origin min_qty_kg disc_pct
## <fct> <chr> <chr> <dbl> <dbl>
## 1 5 Cabernet Sauvignon France 12 56
## 2 5 Cabernet Sauvignon Germany 72 45
## 3 5 Cabernet Sauvignon Italy 72 82
## 4 5 Cabernet Sauvignon Italy 144 19
## 5 5 Cabernet Sauvignon New Zealand 144 44
## 6 5 Cabernet Sauvignon Oregon 72 59
## 7 5 Champagne California 12 50
## 8 5 Champagne France 72 85
## 9 5 Champagne Germany 12 66
## 10 5 Chardonnay Chile 144 57
## 11 5 Chardonnay South Africa 144 39
## 12 5 Espumante Oregon 144 32
## 13 5 Malbec France 72 56
## 14 5 Merlot California 72 88
## 15 5 Merlot Chile 72 64
## 16 5 Prosecco Australia 72 83
## 17 5 Prosecco California 72 52
最后的想法
虽然它不会给你所有的答案,聚类是一个强大的探索性练*,它可以帮助你揭示你的消费者群的模式,尤其是当你有一个全新的市场要探索,并且之前没有任何关于它的知识。
这很容易实现,甚至在像我在这里使用的小数据集上,你也可以在你的客户群中挖掘出有趣的行为模式。
我们不费吹灰之力就了解到,我们的一些顾客喜欢某些种类的葡萄酒,而另一些顾客则喜欢买高买低。这些信息可以用来针对那些更倾向于做出回应的客户,定制你的定价策略和营销活动。此外,客户细分允许更有效地分配营销资源,并最大限度地增加交叉销售和追加销售机会。
还可以通过叠加客户的人口统计(年龄、种族、宗教、性别、家庭规模、种族、收入、教育水平)地理(他们生活和工作的地方)心理(社会阶层、生活方式和个性特征)等信息来丰富细分,但这些都超出了这个小型项目的范围。
代码库
完整的 R 代码可以在我的 GitHub 档案中找到
参考
- 有关客户细分潜力的更广泛观点
- 对于某些 k-means 缺点的批判
- 贝恩&公司的客户细分
原载于 2019 年 5 月 25 日https://diegousei . io。**
Dash 开发的温和介绍
原文:https://towardsdatascience.com/a-gentle-introduction-to-dash-development-and-deployment-f8b91990d3bd?source=collection_archive---------9-----------------------
构建交互式可视化并将其部署到 Heroku 的有效工作流
你是一个饱受 D3 羡慕的 Python 程序员吗?
第一步:垂涎于 D3 画廊的性感&互动剧情
第二步:从 Javascript
的陡峭学*曲线上掉下来第三步:回到制作平庸的 seaborn 剧情
有更好的办法!
A Dash interactive visualization in <150 lines of Python code, deployed to Heroku from this GitHub repo
进入 Dash ,这是一个用纯 Python 构建交互式 web 可视化的简单而强大的框架。因为它是建立在 D3 之上的,所以你得到了你渴望的美感(这里有一些社区的例子)。Dash 有一篇优秀的介绍文章,和一篇示范性的教程,它将教你在 1-2 小时内制作一个交互式可视化。我想澄清一下,我不是在写 Dash 的教程(说真的,他们的很棒),也不是在争论 Dash 与 Altair 或 Bokeh 的优点(我会把这个留给专家和他们的机智决策树)。
那么我为什么要写 Dash 开发的教程呢?在用户指南的彻底性中丢失的是一个通用工作流的简明图片——构建和部署交互式可视化。如果你对 git 特性分支、Heroku 或虚拟环境有点模糊,很容易被本教程简单的可视化所迷惑。在您探测堆栈溢出的深度之前,这里有一个有效的工作流,它帮助我构建了多个仪表板(示例)并避免了常见的陷阱。我使用以下工作流程开发了 GitHub 教程及以上 Heroku app 。
Sample workflow
项目设置
同样,本教程是关于构建非平凡的 Dash 应用程序和部署到 Heroku ,所以我们必须使用版本控制和 GitHub。为了便于进入,我在教程 repo 中做了一个样板分支。
注:你可能熟悉cookiecutter,一个项目设置的自动化工具。Plotly 提供了一个 dash 组件样板 ,并且至少有一个 dash app 样板 。我的是一个轻量级版本,对于本教程来说已经足够了。
Github tutorial boilerplate branch
除了琐碎的破折号app
,我还包含了 Heroku 部署所需的文件。这些文件在 Heroku 的 Python 快速入门中有很好的记录。简而言之,Procfile
、runtime
和setup
告诉远程 Heroku 服务器如何运行你的应用,requirements
列出了用于构建你的应用的虚拟环境的 Python 包(及其具体版本)。
步骤 1: 创建自己的 Git 资源库
步骤 2 :克隆或下载教程的样板文件分支,手动将这些文件添加到您的 Git 资源库中(这比分叉整个 Git 资源库要干净)。
第三步:创建你的虚拟环境。我使用的是一个由pip
作为包管理器的conda
环境。打开一个终端,运行conda create -n dash_tutorial pip
。(将pip
添加到您的环境中使得稍后通过pip freeze
跟踪包变得更加容易)。注意我的runtime
用的是 Python 3.7.2。
第四步:安装你的软件包。首先,确保您在您的环境中:对于 Windows,运行activate dash_tutorial
。如果你只是按照教程来做,你可以通过运行
(env_name) C:/path/to/dash_tutorial> pip install -r requirements.txt
来复制我的环境(激活环境并在你的 git repo 中)【如果你正在为你自己的应用程序使用样板文件(而不是使用 cookiecutter 模板),你需要一个包含最新版本包的环境。你可以pip install
最新的 Dash 库,以及pip install jupyter pandas
和任何其他你打算用于你的应用的库。在这一点上,你可能会感到沮丧,因为我答应了一个“温和的”介绍,然后让你承担环境管理的重担。然而,环境勤奋对于使 Heroku 部署顺利进行至关重要(实际上,对于任何重要的 Python 开发都是如此)。如果你真的愿意,你可以在处理 Heroku 部署之前构建完整的 Dash app
,但是根据我的经验,Heroku 部署对于初学者来说很棘手,在你构建一个你无法部署的复杂应用之前,用一个玩具应用来调试部署更容易。
部署到 Heroku
第五步:本地运行 app。
(env_name) C:/path/to/dash_tutorial> python app.py
这将启动一个本地服务器,您可以通过浏览器导航到 http://127.0.0.1:8050/ 来访问该服务器。您应该会看到类似这样的内容
Boilerplate app running on local server
第六步:创建你的 Heroku app
如果你没有 Heroku 账号,参考他们的 Python 快速入门快速安装配置。否则,通过heroku create my-app-name
创建一个 Heroku 应用程序(注意,应用程序名称必须是唯一的,所以你不能使用例如dash-tutorial
) 步骤 7: 部署到 Heroku
运行git push heroku master
如果你没有得到错误,访问你的应用程序,其 url 由https://my-dash-name.herokuapp.com/
组成如果一切顺利,你应该看到与你的本地服务器完全相同的输出。
Boilerplate app running on Heroku
开发您的 Dash 应用程序(有趣的部分)
至此,你已经有了一个坚实的应用程序开发框架。参考前面的工作流程图,您现在将使用以下步骤在 git 分支上开发应用程序特性(我用字母标记了这些步骤,以表示独立的循环流程)。我将展示来自教程 repo 的特性分支的例子:第一个创建了散点图,第二个添加了 choropleth 图。
创建一个 git 分支。
在回购教程中,我运行git checkout -b scatterplot
创建一个分支,我将在其中添加第一个交互式散点图。
B)添加特性 常见的工作流程是在自己喜欢的文本编辑器或 IDE 中编写代码,然后启动本地服务器。下面是交互式散点图的精简代码,摘自第一个功能分支的[app.py](https://github.com/zwrankin/dash_tutorial/blob/scatterplot/app.py)
(显示在上面的应用程序中)。我通常从简单的例子开始复制粘贴代码,比如 Dash 教程的散点图(它解释了layout
和callbacks
)。
对于小的调整,您可以使用 Dash 的自动加载器迭代地编写代码并查看更新。下面,我启动本地服务器,然后通过向 choropleth 地图添加autocolorscale=False
参数来更改 colorscale,并立即看到更新后的地图。
Tweaking Plotly code and seeing autoreloader update local app
对于某些任务,比如数据管理,我发现在将代码添加到app.py
之前,在 Jupyter 笔记本上写代码是值得的。
Data munging is easier in Jupyter than Dash’s autoreloader
我发现在 Jupyter 笔记本上开发 Plotly 代码并没有特别大的帮助。这需要一些额外的设置步骤,Dash autoreloader 为调试提供了不错的堆栈跟踪。如果你想在笔记本上运行 Plotly,你需要导入特殊的工具,如下:
A few extra steps to use Plotly in Jupyter notebook
C)从功能分支 推送至 Heroku 一旦您对运行在 http://127.0.0.1:8050/ 上的应用版本感到满意,就该重新部署了。您可以将您的分支合并到 master,然后将 master 推送到 Heroku,但是我发现在将它合并到 master 之前从我的特性分支进行部署更令人欣慰。这是通过git push heroku branchname:master
完成的。
E)推送并合并您的特性分支 如果您的部署进展顺利,推送您的分支:
git push --set-upstream origin branchname
转到 GitHub,创建一个 pull 请求(PR),然后合并您的 PR。在合并 PR 之后,最好的做法可能是git push heroku master
,但是如果你有干净的特性分支工作流,你可以从特性分支部署。
冲洗并重复
继续开发功能分支,并重新部署到 Heroku。
解决纷争
我的应用可以在本地运行,但不能在 Heroku 上运行 1)仔细检查你的环境。确保您的requirements.txt
是最新的(运行pip freeze > requirements.txt
并确保提交任何更新)。
2) Heroku 有一些回购结构要求。例如,确保你的[Procfile](https://devcenter.heroku.com/articles/procfile)
在你的应用程序的根目录下。有时候,你的本地设备和 Heroku 的操作系统之间的差异会产生严重的错误。比如我写了一个在 Windows 本地运行的 app,用pd.read_csv('data.csv')
读取data.CSV
。它成功地部署到 Heroku,但是不能在 Heroku 的 Unix 系统上运行,与FileNotFoundError: 'data.csv' does not exist
中断。
后续步骤
Dash 允许你用纯 Python 制作强大的可视化应用。除了 Heroku 部署所需的文件,本教程的app.py
模块包括所有数据转换、绘图和应用布局代码。很可能这对你的目的来说已经足够了。随着你的应用程序的开发,你可能需要将你的代码重构为多个模块,例如:
-将数据转换、调色板等重构为独立的模块,这样你的app.py
模块就可以专注于应用程序本身。
-用你自己的 CSS 设计你的应用
-用React.js
编写你自己的组件
探索性数据分析的简明介绍
原文:https://towardsdatascience.com/a-gentle-introduction-to-exploratory-data-analysis-f11d843b8184?source=collection_archive---------2-----------------------
包括:漂亮的图画,一个漫游卡格尔例子和许多挑战
粉色汗衫,染红头发,镀灰胡子,不穿鞋,约翰列侬眼镜。真是个人物。想象一下他会有怎样的故事。他停好车,走进咖啡馆。
这家咖啡馆是当地人的最爱。但是椅子不太舒服。所以我会尽量简短(剧透:我说的简短是指与你实际花在 EDA 上的时间相比的简短)。
当我第一次在 Max Kelsen 公司做机器学*工程师的时候,我从来没有听说过 EDA。有一堆我从来没听说过的缩写。
我后来知道 EDA 代表探索性数据分析。
这是你第一次遇到数据集时要做的事情。但这不是一次性的过程。
过去几周,我一直在做一个机器学*项目。一切都很顺利。我用少量数据训练了一个模型。结果相当不错。
是时候加快步伐,添加更多数据了。我照做了。然后就断了。
我填满了我正在使用的云计算机的内存。我又试了一次。同样的问题。
某处出现了内存泄漏。我错过了一些东西。什么变了?
更多数据。
也许我获取的下一个数据样本与第一个有所不同。确实如此。有一个异常值。一个样本的购买量是平均值的 68 倍(100)。
回到我的代码。它对异常值并不稳健。它将异常值应用于其余的样本,并用零填充它们。
不是有 1000 万个长度为 100 的样本,而是都有 6800 个长度。大部分数据都是零。
我改了密码。重新运行模型,开始训练。内存泄漏已被修补。
暂停。
穿粉色汗衫的人走了过来。他告诉我他的名字叫约翰尼。
他继续说道。
女孩们因我没打招呼而责骂我。
“你赢不了,”我说。
“太对了,”他说。
我们笑了。这里的女孩真的很好。常客会被取笑。约翰尼是常客。他告诉我他在家里有自己的农场。他的脚趾甲被涂成粉色和黄色,交替着,粉色,黄色,粉色,黄色。
强尼走了。
回去吧。
发生了什么事?为什么 EDA 的故事中断了?
除了向你介绍约翰尼的传奇,我想举一个例子来说明你是如何认为前方的路是清晰的,但实际上,有一个弯路。
EDA 是一个很大的弯路。没有真正结构化的方法来做这件事。这是一个反复的过程。
EDA 为什么?
当我开始学*机器学*和数据科学时,大部分(全部)都是通过在线课程。我用它们创造了我自己的人工智能硕士学位。他们都提供了优秀的课程和优秀的数据集。
这些数据集非常出色,因为它们可以立即与机器学*算法一起使用。
你可以下载数据,选择你的算法,调用.fit()
函数,将数据传递给它,突然之间,损失值开始下降,你会得到一个精度指标。魔法。
这就是我大部分学*的过程。然后我找了一份机器学*工程师的工作。我想,终于,我可以把我学到的东西应用到现实世界的问题中了。
路障。
客户把数据发给了我们。我看了看。这是搞什么鬼?
单词、时间戳、更多单词、缺少数据的行、列、很多列。数字在哪里?
我该如何处理这些数据?我问 Athon。
他说,你必须做一些特征工程,对分类变量进行编码,我会给你一个链接。
我去找了我的数字导师。谷歌。什么是特征工程?
再次谷歌。什么是分类变量?
Athon 给发了链接。我打开了。
就在那里。我必须穿过的下一座桥。埃达。
在运行机器学*模型之前,您需要进行探索性数据分析来了解更多信息。
你为数据创建自己的心理模型,这样当你运行机器学*模型进行预测时,你将能够识别它们是否是谎言。
我没有回答你所有关于 EDA 的问题,而是设计了这篇文章来激发你的好奇心。让你思考你可以问数据集的问题。
你从哪里开始?
你如何探索山脉?
你直接走到顶端吗?
沿着基地试着找到最佳路径怎么样?
这取决于你想要达到的目标。如果你想到达顶峰,最好尽快开始攀登。但花些时间寻找最佳路线也可能是好的。
探索数据也是一样。你想解决什么问题?或者更好,你想证明什么假设是错的?
你可以花一整天来讨论这些。但是最好从简单的开始,证明它是错的,并根据需要增加复杂性。
示例时间。
首次提交 Kaggle
你一直在网上学*数据科学和机器学*。你听说过卡格尔。你已经读过一些文章,说在他们的问题上练*你的技能是多么有价值。
路障。
尽管你听说过卡格尔的种种优点。您尚未提交。
你决定是时候参加自己的比赛了。
你在 Kaggle 网站上。您可以转到“从这里开始”部分。有一个包含泰坦尼克号乘客信息的数据集。你下载它并加载一个 Jupyter 笔记本。
你是做什么的?
你想解决什么问题?
我能根据其他乘客的数据预测泰坦尼克号上乘客的存活率吗?
这似乎是一个很好的指路明灯。
EDA 清单
如果一份清单足够好,可供飞行员在每次飞行中使用,那么它也足够好,可供数据科学家在每个数据集上使用。
EDA 清单
1.你试图解决什么问题(或证明什么问题是错的)?
2。你有什么样的数据,如何对待不同的类型?
3。数据中缺失了什么,如何处理?
4。离群值在哪里,为什么要关心它们?
5。如何添加、更改或删除功能以充分利用您的数据?
我们将逐一讲解。
**Response opportunity:** What would you add to the list?
你想解决什么问题?
我在副标题中加了一个 s。忽略它。从一个开始。不要担心,随着你的发展,会有更多的事情发生。
对于我们的泰坦尼克号数据集示例,它是:
我们能根据其他乘客的数据预测泰坦尼克号上的幸存者吗?
太多的问题会让你的思维空间变得混乱。人类不擅长同时计算多个事物。我们会把它留给机器。
Sometimes a model isn’t required to make a prediction.
Before we go further, if you’re reading this on a computer, I encourage you to [**open this Juypter Notebook**](http://bit.ly/yourfirstkagglesubmission) and try to connect the dots with topics in this post. If you’re reading on a phone, don’t fear, the notebook isn’t going away. I’ve written this article in a way you shouldn’t *need* the notebook but if you’re like me, you learn best seeing things in practice.
你有什么样的数据,如何看待不同类型?
您已经导入了泰坦尼克号训练数据集。
我们去看看。
training.head()
.head() shows the top five rows of a dataframe. The rows you’re seeing are from the Kaggle Titanic Training Dataset.
一列接一列,有:数字,数字,数字,单词,单词,数字,数字,数字,字母和数字,数字,字母和数字和 NaNs,字母。类似于强尼的脚趾甲。
让我们将特征(列)分成三个框,数字、分类和不确定。
Columns of different information are often referred to as features. When you hear a data scientist talk about different features, they’re probably talking about different columns in a dataframe.
在数字桶中,我们有:PassengerId
、Survived
、Pclass
、Age
、SibSp
、Parch
和Fare
。
分类桶包含Sex
和Embarked
。
而在不确定中我们有Name
、Ticket
和Cabin
。
现在,我们已经将这些列分解到单独的桶中,让我们检查每一个。
数字桶
还记得我们的问题吗?
我们能根据其他乘客的数据预测泰坦尼克号上的幸存者吗?
由此,你能找出我们要预测的是哪一列吗?
We’re trying to predict the green column using data from the other columns.
Survived
栏。因为它是我们试图预测的列,我们将把它从数值桶中取出来,暂时不考虑它。
还剩下什么?
PassengerId
、Pclass
、Age
、SibSp
、Parch
和Fare
。
想一想。如果你试图预测泰坦尼克号上是否有人幸存,你认为他们独特的PassengerId
真的会对你的事业有帮助吗?
大概不会。所以我们暂时也将这个专栏放在一边。EDA 并不总是必须用代码来完成,你可以从你的世界模型开始,然后用代码来看看它是否正确。
Pclass
、SibSp
、Parch
怎么样?
这些都是数字,但它们有所不同。你能捡起来吗?
Pclass
、SibSp
和Parch
到底是什么意思?也许我们应该在这么快建立模型之前多读些文档。
谷歌。Kaggle 泰坦尼克号数据集。
找到了。
Pclass
是车票等级,1 =一等,2 =二等,3 =三等。SibSp
是乘客在飞机上的兄弟姐妹的数量。并且Parch
是某人在船上的父母的数量。
这些信息很容易找到。但是如果你有一个从未见过的数据集呢?如果一个房地产经纪人想要帮助预测他们城市的房价。你查看他们的数据,发现一堆你不理解的栏目。
你给客户发邮件。
Tnum
是什么意思?
他们回应。Tnum
是一个物业的卫生间数量。
很高兴知道。
当你处理一个新的数据集时,你并不总是像 Kaggle 提供的那样有关于它的可用信息。这是你想要寻求中小企业知识的地方。
另一个缩写。太好了。
SME 代表主题专家。如果您正在从事一个处理房地产数据的项目,EDA 的一部分可能涉及到与房地产经纪人交谈和向他们提问。这不仅可以节省您的时间,还会影响您将来对数据的提问。
既然泰坦尼克号上已经没有人活着了(安息吧,米莉维娜·迪恩,最后的幸存者),我们将不得不成为我们自己的中小企业。
Pclass
、SibSp
和Parch
还有一些独特之处。尽管它们都是数字,但它们也是类别。
为什么
这样想吧。如果你能在头脑中很容易地将数据组合在一起,那么它就有可能是一个类别的一部分。
Pclass
列可以标记为第一、第二和第三列,其含义与 1、2 和 3 相同。
还记得机器学*算法有多喜欢数字吗?由于Pclass
、SibSp
和Parch
都已经是数字形式,我们就让它们保持原样。Age
也是如此。
唷。这并不难。
分类桶
在我们的分类桶中,我们有Sex
和Embarked
。
这些是分类变量,因为你可以把女性乘客和男性乘客分开。或者说从 s 出发的人走上 C 的人。
为了训练机器学*模型,我们需要一种将这些转换成数字的方法。
你会怎么做?
还记得Pclass
吗?第一次= 1,第二次= 2,第三次= 3。
对于Sex
和Embarked
,你会怎么做?
也许你可以为Sex
做些类似的事情。女性= 1,男性= 2。
至于Embarked
,S = 1,C = 2。
我们可以使用sklearn
库中的[.LabelEncoder()](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html)
函数来改变这些。
training.embarked.apply(LabelEncoder().fit_transform)
Wait? Why does C = 0 and S = 2 now? Where’s 1? Hint: There’s an extra category, Q, this takes the number 1. See the data description page on Kaggle for more.
我们在将分类数据转换成所有数字方面取得了一些进展,但是其他列呢?
**Challenge:** Now you know Pclass could easily be a categorical variable, how would you turn Age into a categorical variable?
不确定桶
剩下Name
、Ticket
、Cabin
。
如果你在泰坦尼克号上,你认为你的名字会影响你的生还几率吗?
不太可能。但是你还能从一个人的名字中提取出什么信息呢?
如果你给每个人一个数字,根据他们的头衔是先生,夫人还是小姐。?
您可以创建另一个名为 Title 的列。这一栏,先生= 1,太太= 2,小姐的。= 3.
您所做的是在现有特征的基础上创建一个新特征。这被称为特征工程。
将标题转换成数字是一个相对容易创建的特性。根据你所拥有的数据,特征工程可以变得任意奢侈。
这个新特性会对模型产生怎样的影响?这是你必须调查的事情。
现在,我们不会担心Name
列做出预测。
那Ticket
呢?
前几个例子看起来根本不太一致。还有什么?
training.Ticket.head(15)
The first 15 entries of the Ticket column.
这些也不是很一致。但是再想想。你认为票号能提供更多关于某人是否幸存的信息吗?
也许如果票号与这个人乘坐的舱位等级有关,它会有影响,但是我们已经在Pclass
中有了这个信息。
为了节省时间,我们暂时忽略Ticket
列。
你第一次在数据集上进行 EDA 的目的不仅仅是提出更多关于数据的问题,而是用尽可能少的信息建立一个模型,这样你就有了一个工作的基线。
现在,我们拿小屋怎么办?
你知道,因为我已经看过数据了,我的蜘蛛感官告诉我这是下一部分的完美例子。
**Challenge:** I’ve only listed a couple examples of numerical and categorical data here. Are there any other types of data? How do they differ to these?
数据中缺失了什么,如何处理?
missingno.matrix(train, figsize = (30,10))
The missingno library is a great quick way to quickly and visually check for holes in your data, it detects where NaN values (or no values) appear and highlights them. White lines indicate missing values.
Cabin
栏看起来像约翰尼的鞋子。不在那里。Age
中也有相当多的缺失值。
在没有数据的情况下,你如何预测呢?
我也不知道。
那么,在处理缺失数据时,我们有什么选择呢?
最快最简单的方法是删除每一行缺少的值。或者完全移除Cabin
和Age
柱。
但是这里有一个问题。机器学*模型喜欢更多的数据。删除大量数据可能会降低我们的模型预测乘客是否幸存的能力。
下一步是什么?
输入值。换句话说,用从其他数据计算出的值来填充缺失的数据。
您将如何为Age
列执行此操作?
When we called .head() the Age column had no missing values. But when we look at the whole column, there are plenty of holes.
你能用平均年龄来填补缺失值吗?
这种价值填充是有缺点的。假设您总共有 1000 行,其中 500 行缺少值。您决定用平均年龄 36 来填充 500 个缺失的行。
会发生什么?
随着年龄的增长,你的数据变得堆积如山。这将如何影响对 36 岁人群的预测?或者其他年龄?
也许对于每个缺少年龄值的人,您可以在数据集中找到其他相似的人,并使用他们的年龄。但是这很耗时,也有缺点。
还有更高级的方法来填充本文范围之外的缺失数据。应该注意的是,没有完美的方法来填充缺失值。
如果Age
栏中的缺失值是泄漏的排水管,则Cabin
栏是破裂的堤坝。无可救药。对于你的第一个模型,Cabin
是你应该忽略的一个特性。
**Challenge:** The Embarked column has a couple of missing values. How would you deal with these? Is the amount low enough to remove them?
异常值在哪里,为什么您应该关注它们?
“你查过发行情况了吗,”Athon 问。
我用了第一组数据,但没有用第二组数据……”
它击中了我。
就在那里。其余的数据被加工以匹配异常值。
如果您查看数据集中唯一值的出现次数,您会发现最常见的模式之一是齐夫定律。看起来是这样的。
Zipf’s law: The highest occurring variable will have double the number of occurrences of the second highest occurring variable, triple the amount of the third and so on.
记住 Zipf 定律有助于思考异常值(不经常出现的接*尾部末端的值是潜在的异常值)。
对于每个数据集,异常值的定义是不同的。作为一个通用的经验法则,你可以认为任何偏离平均值超过 3 个标准差的数据都是异常值。
You could use a general rule to consider anything more than three standard deviations away from the mean as an outlier.
或者换个角度。
Outliers from the perspective of an (x, y) plot.
如何发现异常值?
分销。分销。分销。分销。四次就够了(我在这里努力提醒自己)。
在您第一次通过 EDA 时,您应该检查每个特性的分布情况。
分布图将有助于表示不同数据值的分布。更重要的是,有助于识别潜在的异常值。
train.Age.plot.hist()
Histogram plot of the Age column in the training dataset. Are there any outliers here? Would you remove any age values or keep them all?
为什么要关心离群值呢?
在数据集中保留异常值可能会导致模型过度拟合(过于精确)。移除所有的异常值可能会导致你的模型过于一般化(它不会在任何异常的情况下做得很好)。和往常一样,最好反复试验,找到处理异常值的最佳方法。
**Challenge:** Other than figuring out outliers with the general rule of thumb above, are there any other ways you could identify outliers? If you’re confused about a certain data point, is there someone you could talk to? Hint: the acronym contains the letters M E S.
利用特征工程从数据中获取更多信息
泰坦尼克号数据集只有 10 个特征。但是如果你的数据集有数百个呢?还是几千?或者更多?这并不罕见。
在您的探索性数据分析过程中,一旦您开始形成一种理解,您对分布有了一个概念,您发现了一些异常值并处理了它们,下一个最大的时间块将花费在特征工程上。
特征工程可以分为三类:添加、删除和更改。
泰坦尼克号的数据集开始时状态很好。到目前为止,我们只需要改变一些特性就可以实现数值化。
然而,野外的数据是不同的。
假设您正在解决一个问题,试图预测一家大型连锁超市全年香蕉库存需求的变化。
您的数据集包含库存水平和以前采购订单的历史记录。你可以很好地对这些进行建模,但你会发现一年中有几次股票水平发生不合理的变化。通过您的研究,您发现在一年一度的全国庆祝活动“香蕉周”期间,香蕉的库存水平直线下降。这是有道理的。为了跟上庆祝活动,人们买更多的香蕉。
为了补偿香蕉周并帮助模型了解它何时发生,您可以向数据集中添加一个包含香蕉周或不包含香蕉周的列。
# We know Week 2 is a banana week so we can set it using np.where()df["Banana Week"] = np.where(df["Week Number"] == 2, 1, 0)
A simple example of adding a binary feature to dictate whether a week was banana week or not.
添加这样的功能可能并不简单。您可能会发现添加要素没有任何作用,因为您添加的信息已经隐藏在数据中。与过去几年一样,香蕉周期间的采购订单已经高于其他周。
移除功能怎么办?
我们在泰坦尼克号数据集上也做到了这一点。我们删除了Cabin
列,因为在我们运行模型之前,它丢失了太多的值。
但是,如果您已经使用剩下的特性运行了一个模型,该怎么办呢?
这就是功能贡献的用武之地。特征贡献是一种计算每个特征对模型影响程度的方法。
An example of a feature contribution graph using Sex, Pclass, Parch, Fare, Embarked and SibSp features to predict who would survive on the Titanic. If you’ve seen the movie, why does this graph make sense? If you haven’t, think about it anyway. Hint: ‘Save the women and children!’
为什么这些信息会有帮助?
知道一个特征对模型的贡献有多大可以给你指明下一步特征工程的方向。
在我们的泰坦尼克号例子中,我们可以看到Sex
和Pclass
的贡献是最高的。你认为这是为什么?
如果你有 10 个以上的功能会怎样?100 怎么样?你也可以做同样的事情。制作一个图表,显示 100 个不同特征的特征贡献。
“哦,我以前见过这个,”
齐夫定律又回来了。顶部特征比底部特征的贡献大得多。
Zipf’s law at play with different features and their contribution to a model.
看到这一点,您可能会决定削减贡献较小的功能,改进贡献较大的功能。
你为什么要这么做?
移除要素会降低数据的维度。这意味着您的模型需要进行更少的连接来找出拟合数据的最佳方式。
您可能会发现移除要素意味着您的模型可以在更少的数据和更少的时间内获得相同(或更好)的结果。
就像 Johnny 是我所在咖啡馆的常客一样,特征工程是每个数据科学项目的常规部分。
**Challenge:** What are other methods of feature engineering? Can you combine two features? What are the benefits of this?
构建您的第一个模型
最后。我们已经完成了一系列步骤,为运行一些模型准备好数据。
如果你和我一样,当你开始学*数据科学时,这是你最先学*的部分。上面所有的东西都已经被别人做过了。你所要做的就是在上面放一个模型。
我们的泰坦尼克号数据集很小。因此,我们可以在它上面运行大量的模型,以找出哪一个是最好的。
注意我是怎么在副标题里放一个(s)的,你可以注意这一个。
Cross-validation accuracy scores from a number of different models I tried using to predict whether a passenger would survive or not.
在我们的小型 Titanic 数据集上运行多个模型是没问题的。但是对于较大的数据集可能不是最好的。
一旦你对不同的数据集进行了一些实践,你就会开始发现什么样的模型通常效果最好。例如,大多数最*的 Kaggle 比赛都是通过不同梯度提升树算法的集合(组合)赢得的。
一旦你建立了几个模型并找出了最好的,你就可以开始通过超参数调整来优化最好的一个。把超参数调谐想象成在烹饪你最喜欢的菜肴时调节烤箱上的转盘。开箱后,烤箱上的预设设置工作得很好,但根据经验,你会发现降低温度和提高风扇速度会带来更美味的结果。
机器学*算法也是一样。他们中的许多人开箱即用。但是只要稍微调整一下它们的参数,它们就能工作得更好。
但无论如何,如果没有足够的数据准备,即使是最好的机器学*算法也不会产生一个伟大的模型。
EDA 和建模是一个重复的循环。
The EDA circle of life.
最后的挑战(和一些课外活动)
我离开了咖啡馆。我的屁股很痛。
在这篇文章的开始,我说过我会保持简短。你知道结果如何。它将与您的 EDA 迭代相同。当你认为你完成了。还有更多。
我们以 Titanic Kaggle 数据集为例,介绍了一个不完整的 ed a 清单。
1.你想解决什么问题(或者证明什么问题是错的)?
从最简单的假设开始。根据需要增加复杂性。
2.你有什么样的数据?
你的数据是数字的,分类的还是其他的?你如何处理每一种?
3.数据中缺失了什么,你如何处理?
为什么数据丢失了?丢失数据本身就是一个信号。你永远无法用和原来一样好的东西来代替它,但是你可以试试。
4.离群值在哪里,为什么要关注它们?
分销。分销。分销。总结三遍就够了。数据中的异常值在哪里?你需要它们吗?还是它们正在破坏你的模型?
5.如何添加、更改或删除功能以充分利用您的数据?
默认的经验法则是数据越多越好。遵循这一点通常会很有效。但是有什么东西你可以去掉得到同样的结果吗?从简单开始。少而精。
GitHub 上的笔记本中有我们在这里讨论的所有内容的例子(以及更多),YouTube 上有我一步一步浏览笔记本的视频(编码从 5:05 开始)。
**FINAL BOSS CHALLENGE:** If you’ve never entered a Kaggle competition before, and want to practice EDA, now’s your chance. Take the [notebook I’ve created](http://bit.ly/yourfirstkagglesubmission), rewrite it from top to bottom and improve on my result.**Extra-curriculum bonus:** [Daniel Formoso's notebook](https://github.com/dformoso/sklearn-classification/blob/master/Data%20Science%20Workbook%20-%20Census%20Income%20Dataset.ipynb) is one of the best resources you’ll find for an extensive look at EDA on a Census Income Dataset. After you’ve completed the Titanic EDA, this is a great next step to check out.
如果你认为这篇文章遗漏了什么,请在下面留言或者给我发个短信。
不然你可以在 Twitter 、 LinkedIn 和 YouTube 上找我。
GA2Ms 的温和介绍,白盒模型
原文:https://towardsdatascience.com/a-gentle-introduction-to-ga2ms-a-white-box-model-d05d13c6ca00?source=collection_archive---------24-----------------------
这篇文章温和地介绍了一个叫做 GA2M 的白盒机器学*模型。
我们将走过:
- 什么是白盒模型,您为什么想要白盒模型?
- 一个经典的白盒模型:逻辑回归
- 什么是 GAM,你为什么想要 GAM?
- GA2M 是什么,您为什么想要它?
- 什么时候应该选择 GAM,GA2M,还是别的?
所有这些机器学*模型的目的是对人类指定的目标做出预测。想一个模型,可以预测贷款违约,或在照片中出现某人的脸。
简而言之:广义加性模型(GAM)是一个白盒模型,比逻辑回归更灵活,但仍然可以解释。GA2M 是一个带有交互项的 GAM,这使得它更加灵活,但是解释更加复杂。gam 和 GA2Ms 是工具箱中一个有趣的附加物,以不适合每种数据为代价进行解释。一张图:
关于这一切意味着什么的更多信息,请继续阅读。
白盒模型
术语“白盒来自软件工程。它意味着你可以看到软件的内部结构,相比之下,它是一个“黑匣子”,你不能看到它的内部结构。根据这个定义,如果你能看到权重(图片来源),一个神经网络可以是一个白盒模型:
然而,人们所说的“白盒”实际上是指他们能够理解的东西。白盒模型是一种人们可以看到其内部并对其进行推理的模型。这是主观的,但大多数人会同意上面显示的权重没有给我们提供关于模型如何工作的信息,因为我们可以有效地描述它,或预测模型在未来会做什么。
将上面的图片与这张关于肺炎死亡风险的图片进行比较[1]:
这不是一个完整的模型。相反,它是一个特征(年龄)对风险分值的影响。绿线为误差线(100 轮装袋中的 1 个标准差)。它们中间的红线是最好的估计。在论文中,他们观察到:
- 直到 50 岁左右,风险评分一直持平。这里的风险评分为负,意味着死亡风险低于数据集中的平均值。
- 风险评分在 65 分急剧上升。这可能是因为退休。将来,收集关于退休的数据可能会很有趣。
- 误差线在 66-85 岁之间最窄。也许这是数据最多的地方。
- 风险评分再次上升至 85。误差线也再次变宽。也许这一跳不是真的。
- 风险分值降至 100 以上。这可能是因为缺乏数据,或者其他原因。在论文中,他们提出,人们可能希望“修复”模型的这一区域,通过改变它来预测 85-100 岁的水平,而不是下降。这个修正是使用领域知识(“85 岁以后肺炎的风险可能不会下降”)来解决可能的模型工件。
- 66 到 85 之间的风险得分相对较低。
所有这些都来自一个模型特征的一个图表。有一些事实,比如图表的形状,以及对图表为什么会那样的推测。这些事实有助于理解这些数据。这种推测无法通过任何工具来回答,但可能有助于建议进一步的行动,如收集新的特征(比如退休)或新的实例(比如年龄低于 50 岁或高于 100 岁的点),或新的分析(比如仔细查看年龄在 85-86 岁左右的数据实例以找出差异)。
这些并不是模型会做的模拟。这些是模型本身的内部因素,所以图表准确地描述了年龄对风险评分的确切影响。这个模型还有 55 个其他组件,但是每个组件都可以被检查和推理。
这就是白盒模型的力量。
这个例子也说明了危险。通过看到一切,我们可能认为我们理解了一切,并胡乱猜测或不恰当地“修复”。一如既往,我们必须运用判断力来正确使用数据。
总之:制作一个白盒模型来
- 了解你的模型,不是从模拟或*似,而是实际的内部
- 改善你的模型,给你方向追求的想法
- “修复”你的模型,即,让它与你的直觉或领域知识保持一致
最后一种可能性:法规规定您需要完整地描述您的模型。在这种情况下,有人类可读的内部参考可能是有用的。
以下是一些白盒和黑盒模型的示例:
白盒模型
- 逻辑回归
- GAMs
- GA2Ms
- 决策树(短树和少树)
黑盒模型
- 神经网络(包括深度学*)
- 助推树木和随机森林(许多树木)
- 支持向量机
现在,我们来看三种特定的白盒模型。
经典:逻辑回归
逻辑回归发展于 19 世纪初,20 世纪初重新普及。它已经存在很长时间了,原因有很多。它解决了一个常见的问题(预测事件的概率),并且是可解释的。让我们探索一下这意味着什么。下面是定义该模型的逻辑方程式:
在这个模型方程中有三种类型的变量:
- p 是我们预测的事件的概率。例如,拖欠贷款
- x 是特征。例如,贷款金额。
- 𝛽's(贝塔)是我们用计算机拟合的系数。
betas 适合整个数据集一次。对于数据集中的每个实例,x 是不同的。p 表示数据集行为的集合:任何数据集实例要么发生了(1),要么没有发生(0),但是在集合中,我们希望右侧和左侧尽可能接*。
“log(p/(1-p))”是对数几率,也称为“概率的 logit”。几率是(事件发生的概率)/(事件不会发生的概率),或者 p/(1-p)。然后,我们应用自然对数将取值范围为 0 到 1 的 p 转换为适用于线性模型的范围从-∞到+∞的量。
这个模型是线性的,但是对于对数概率来说。也就是说,右边是一个线性方程,但它适合于对数赔率,而不是事件的概率。
该模型可解释如下:在𝛽i,xi 的单位增长是对数优势增长。
例如,假设我们正在预测贷款违约的概率,我们的模型有一个贷款金额特征 x1 的特征系数𝛽1=0.15。这意味着在默认情况下,该特征的单位增加对应于 0.15 的对数赔率增加。我们可以取自然指数得到比值比,exp(0.15)=1.1618。这意味着:
在这个模型中,在其他因素不变的情况下,贷款金额每增加一个单位(比如说 1000 美元),贷款违约的几率就会增加 16%。
当人们说逻辑回归是可解释的时,这种说法就是他们的意思。
总结一下为什么逻辑回归是一个白盒模型:
- 输入响应项(𝛽i*xi 项)可以相互独立地解释
- 术语以可解释的单位表示:系数(β)以对数概率为单位。
那么,除了友好、古老的逻辑回归模型,我们为什么还要使用其他模型呢?
嗯,如果特征和对数概率没有线性关系,这个模型就不太适合。我总是想尝试用一条线来拟合一条抛物线:
No line fits a curve.
如果你有非线性数据(黑色抛物线),线性拟合(蓝色虚线)永远不会很好。没有一条线符合这条曲线。
广义可加模型
广义加性模型 (GAMs)由 Hastie 和 Tibshirani 于 20 世纪 90 年代开发。(参见他们的书第九章“统计学*的要素”。)下面是定义该模型的等式:
这个方程非常类似于逻辑回归。它具有相同的三种类型的元素:
- E(Y)是数据集行为的集合,就像上面等式中的“p”。其实很可能是一个事件的概率,同 p。
- g(。)是一个链接函数,就像上面的逻辑方程式中的 logit(或 log odds)。
- fi(xi)是每个数据集实例特征 x1,…,xm 的术语。
最大的不同是,现在我们有一个函数 fi(xi ),而不是一个特征的线性项𝛽i*xi。在他们的书中,Hastie 和 Tibshirani 指定了一个像三次样条一样的“平滑”函数。Lou 等人[2]研究了 fi 的其他功能,他们称之为“形状功能”
GAM 还具有白盒特性:
- 输入响应项(f(xi)项)可以相互独立地解释
- 这些术语是以可解释的单位表示的。对于 logit 链接函数,这些是对数概率。
现在,一个项,而不是一个常数(β),是一个函数,所以不是用数字来报告对数几率,我们用一个图表来形象化它。事实上,上图中按年龄划分的肺炎死亡风险是 GAM 中的一项(形状函数)。
那我们为什么要用 GAM 以外的东西呢?它已经是灵活的和可解释的了。和之前一样的原因:可能不够准确。特别是,我们已经假设每个特征响应可以用它自己的函数建模,与其他的无关。
但是如果特征之间有交互作用呢?一些黑盒模型(提升树、神经网络)可以对交互项进行建模。让我们通过一个白盒模型来看看:GA2Ms。
具有交互条款的 gam(GA2Ms)
Lou 等人在 2013 年对 GA2Ms 进行了研究[3]。作者用字母“gee ay two em”来发音,但在室内我们称它们为“互动游戏”,因为它更容易发音。下面是模型方程:
这个方程与上一节的 GAM 方程非常相似,只是它增加了可以同时考虑两个特征变量的函数,即相互作用项。
微软刚刚发布了一个用 python 实现 GA 2Ms 的库 InterpretML 。在图书馆里,他们称之为“可解释的助推机器”
Lou 等人说,这些仍然是白盒模型,因为相互作用项的“形状函数”是热图。这两个特征是沿 X 和 Y 轴的,中间的颜色表示函数响应。下面是一个来自微软图书馆的例子,适合预测的贷款违约,这个数据集来自 lending club 的贷款表现:
对于此示例图:
- 右上角是最红的。这意味着,当 dti(债务收入比)和 FICO _ range _ midpoint(FICO 信用评分)都很高时,违约概率上升最多。
- 左边的条纹也是红色的,但在底部附*变成蓝色。这意味着非常低的 dti 通常是不好的,除非 fico_range_midpoint 也很低。
这个特殊的热图很难解释。这可能只是没有单一特征项的交互作用效应。因此,在高 dti 和高 fico 的情况下,整体违约概率可能并不更高,而只是高于他们自己预测的任何一种主要影响。为了进一步研究,我们可以看看边界附*的一些例子。但是,对于这篇博文,我们将跳过深潜。
在实践中,这个库适合所有的单特征函数,然后是 N 个交互项,其中你选择 N 个。选择 N 个并不容易。如果交互项增加了足够的准确性,值得花额外的复杂性盯着热图来解释它们,那么交互项是值得的。这是根据你的业务情况做出的判断。
什么时候应该用 GAMs 或者 GA2Ms?
要执行机器学*,首先挑选一个目标。然后选择一种最能利用您的数据来实现目标的技术。有成千上万本书和数百万篇论文是关于那个主题的。但是,考虑 GA2Ms 如何适应可能的模型技术,这里有一个大大简化的方法:它们在从可解释性到建模特性交互的范围内。
- 如果游戏足够精确,就使用游戏。它给出了白盒模型的优点:带有可解释单元的可分离项。
- 如果 GA2Ms 明显比 gam 更准确,就使用 GA2Ms,特别是如果您从您的领域知识中相信存在真实的功能交互,但它们并不太复杂。这也给出了白盒模型的优势,用更多的精力去解读。
- 如果您不太了解数据,可以尝试 boosted trees (xgboost 或 lightgbm ),因为它对数据中的异常非常健壮。这些是黑盒模型。
- 当特征彼此高度交互时,比如图像中的像素或音频中的上下文,你可能很需要神经网络或其他可以捕捉复杂交互的东西。这些都是深深的黑匣子。
在所有情况下,您可能都需要特定领域的数据预处理,比如对图像求平方,或者标准化特征(减去平均值并除以标准偏差)。那是另一天的话题。
现在希望我们开始的图表更有意义。
在 Fiddler Labs ,我们帮助你解释你的人工智能。请发邮件至 info@fiddler.ai 联系我们。
参考
- 卡鲁阿纳、里奇、尹露、约翰内斯·盖尔克、保罗·科赫、马克·斯特姆和小糯米·艾尔哈达德。"医疗保健的可理解模型:预测肺炎风险和住院 30 天再入院."第 21 届 ACM SIGKDD 知识发现和数据挖掘国际会议论文集,1721–1730。KDD 15 年的。美国纽约州纽约市:美国计算机学会,2015 年。【https://doi.org/10.1145/2783258.2788613】T4。
- 卢、尹、里奇·卡鲁阿纳和约翰内斯·戈尔克。"可理解的分类和回归模型."第 18 届 ACM SIGKDD 知识发现和数据挖掘国际会议论文集,150–158。12 年的 KDD。美国纽约州纽约市:美国计算机学会,2012 年。https://doi.org/10.1145/2339530.2339556。
- 娄、尹、里奇·卡鲁阿纳、贾尔斯·胡克和约翰内斯·戈尔克。具有成对交互的精确可理解模型,2017。https://www . Microsoft . com/en-us/research/publication/accurate-understand-models-pairwise-interactions/。
原载于 2019 年 6 月 3 日https://blog . fiddler . ai。
通过线性回归对梯度下降的温和介绍
原文:https://towardsdatascience.com/a-gentle-introduction-to-gradient-descent-thru-linear-regression-fb0fc86482a3?source=collection_archive---------26-----------------------
Génesis | © Sebastião Salgado
为了对我们周围的现实的错综复杂的本质有所了解,为了理解事件或主题之间的潜在关系,或者甚至为了评估特定现象对任意事件的影响,我们必须将现实旋绕到信息维度中,试图利用我们人类的抽象来以某种方式把握我们周围实际事物的本质。
在本文中,我们将简要分析一个简单的统计工具,该工具允许我们根据一组观察值、评估我们如何利用一组变量来适当地生成一个模型,该模型将通过推断变量关系和相互影响来预测或预报行为。这个统计工具叫做线性回归。
为了帮助最小化与预测模型相关的误差,优化它以更好地代表现实,我们还将简要展示梯度下降优化算法的简单应用。
本文假设只有基本的代数和微积分知识,因为这两个主题都很简单,但却代表了现代统计学和机器学*的两个基础学科。
方案
让我们考虑一个简单的例子,从 StackOverflow 的“2018 年开发者工资”文章中抽取一些值。下面我们可以看到一个代表平均工资点的小数字,以及随着开发人员经验的增加,德国的平均工资点是如何变化的:
Figure 1) Median yearly salaries for developers, in thousands of euros, by experience in Germany (2018)
基于上述数据点,我们希望开发一个简单的模型函数,使我们能够预测在任何给定的经验时间点工资如何演变。
线性回归
然后,线性函数可以由简单的表达式定义:
常数 m 代表函数线的斜率,常数 b 通常称为截距。下面的一些例子展示了 (m,b) 的不同值:
Figure 2) Three examples of slopes and intercepts for a linear function
在上面的例子中,我们可以看到,改变 m 会影响结果值的斜率,也会影响截距 b ,它会在穿过 x = 0 时修改函数值。
在我们当前的方案中,由于工资的变化实际上并不是由线性级数表示的,然而,查看图 1 中的数据形状,通过在积分级数中拟合一条线来*似预测的最终工资是可以接受的,其方式为:
最后,我们的模型将试图通过某种方式调整 m 和 b ,将自己表示为逼*我们的参数薪水和经验的演变的线,例如,它将允许我们获得类似如下的结果:
Figure 3) Possible linear model used to predict the median salaries
对于代表我们参数之间关系的基本模型的“线性”表示,我们可以称之为线性回归。
我们错误的代价
既然我们已经确定了我们将使用什么形状来生成我们的模型,那么我们必须试着弄清楚【m,b】的值是什么,它们将更好地描述我们的数据预测模型的发展。
但是我们如何选择 m 和 b 的值来生成我们要寻找的线呢?一种方法是计算我们的模型生成的值和我们现有的实际数据之间的误差。
仅用于表示目的的简单方法可以是:
- 我们知道,一个拥有大约10 年左右经验*的开发人员挣得大约72K欧元的年薪* (1)****
- 从示例斜率和截距 (m,b) = (3,35) 开始
一个样本误差函数,对于这个 10 年经验的特定数据点 (x=10) ,我们的误差 E 为:
对于我们现有的所有样本数据点,我们可以计算误差,该误差考虑了我们的预测和真实值之间的所有误差之和,从而得到如下函数:
使用:
- n 是我们数据集的总样本
- y 为具体观察的实际薪资值
- x 是我们要为 y 预测的经验年数
对于每个观察值与其组均值之间的平方差之和,这将代表我们的误差函数(或成本函数,我们将每个观察值与其组均值之间的平方差之和命名为 : 平方差之和(SSE)。在统计学中,这个均方差对于评估我们的预测值相对于真实观测值的“质量”非常有用。**
但是我们如何继续寻找 m 和 b 的合适值呢?一种直观的方法可能是,因为我们现在能够计算一个误差函数,找到最小化该函数的一对 (m,b) 。如果是这样的话,我们就可以清楚地表明,我们的预测产生的误差最小,因此更接*现实。**
然后,让我们为 (m,b) 选择两个随机值,计算成本函数,然后改变这些值,以试图找到我们的误差函数的最小值。让我们首先考虑(m,b) = (3,0),我们的数据点来自图 1,我们得到下面的图形结果:
Figure 4) Initial prediction and errors for (m, b) = (3, 0)
从上图我们可以看出:
- 绿点代表我们的工资观察数据值****
- 蓝线是我们的预测模型* ( y = 3 年经验+ 0 )**
- 红色虚线表示当前参数 (m,b) 的错误****
对于这组特定的截距和斜率,现在让我们计算现有观测值的累积成本:
现在让我们将斜率值固定为 3,但是将截距增加到 20, (m,b) = (3,20) 。我们将获得以下表示:
Figure 5) Prediction iteration 1, and errors for (m, b) = (3, 20)
与 相关的成本 E = 232.5 。我们可以清楚地看到,通过更新我们的截距,我们已经改善了我们的预测,因为误差大幅下降。现在让我们针对不同的截距值绘制多种场景:
Figure 6) Computing the errors by varying the value of the intercept
从上图可以看出,随着截距值 b 的增加,我们还可以观察到成本函数的变化。在这个具体的例子中,用 (m,b) = (3,30) 确定粉红色线是我们观察值的更准确预测,因为它也具有更低的成本值。
通过绘制通过改变截距值获得的误差成本函数的变化,我们得到了下图:**
Figure 7) Evolution of the cost function when changing the intercept value
我们可以清楚地看到,当改变 b 的值时,考虑到我们的误差函数是凸的,我们能够找到一个局部最小值,它将代表我们的预测模型的最小误差。在上面这个简单的演示中,可以清楚地说明使我们的误差最小的截距 b 在【30,40】之间。不幸的是,用预先定义的步骤简单地迭代,以找到这个最小值是非常昂贵和耗时的。
但是我们怎样才能更巧妙的计算出我们的成本函数的最小值呢?然后我们将使用梯度下降算法。**
梯度下降
梯度下降是一种迭代优化算法,允许我们找到特定函数的局部最小值。
解释这种算法背后的逻辑的一个很好的例子,也是文献中反复出现的,是盲人登山家的例子。让我们想象一下,一个盲人登山运动员想用最少的步骤爬到山顶:**
Figure 9) Sequence of steps a smart blind alpinist would take to climb a mountain
由于登山运动员是盲人,他将评估他当前位置的倾向,以便选择他下一步应该采取的幅度:
- 如果他当前位置的山(坡)的倾斜度很高,他可以安全地迈出一大步(例如我们可以注意到从第一步到第二步的过渡)**
- 当坡度越来越小时,当他到达山顶时,他知道他需要迈更小的步子,以便接*精确的最高点(当登山运动员越来越接*山顶时,从第 6 步到第 7 步,他更加小心如何增加他的位置)**
- 对于正坡,他需要继续向上到达顶部
- 对于负斜率,他正在下降,所以他需要回到顶部
给定点处“山”的斜率则由该函数在特定点处的导数给出:
Figure 10) Slope of the function at a given point
因此,通过计算我们的“山函数”在某一点的导数,我们就可以推断出为了适当地达到我们的局部最小值,我们将需要的步骤的性质。通过达到接* 0 的斜率(顶部的黄色斜率,与山起点的蓝色斜率值相比)。
通过将登山挑战从到达山顶切换到实际到达谷底,理解对于该函数的凸形版本同样有效也是微不足道的:
Figure 11) Iterative finding of our local minimum for a convex function (or a valley in this alpine example)
回到我们的研究案例,考虑到我们想要正确估计使成本最小化的斜率和截距的值,我们可以使用这个概念来最小化凸函数,它实际上是我们的成本函数。
为了简单起见,让我们首先通过保持斜率固定在 m = 3 来预测截距的实际值。我们的成本函数是:
现在我们知道了这条曲线的方程,我们可以对它求导,并确定它在截距的任意值处的斜率。**
现在让我们使用链式法则,根据截距计算成本函数的导数:
现在我们已经正确地计算了导数,我们现在可以使用梯度下降来寻找我们的成本函数在哪里有它的局部最小值。
通过找到导数(斜率)为 dE(b)/db = 0 的位置来计算这个特定的最小值确实是微不足道的。然而,这在许多计算问题中是不可能的。因此,我们将应用梯度下降,从最初的猜测开始,了解这个最小值的性质。当我们无法计算导数时,这种多功能性实际上使得这种优化算法在许多情况下如此有用,例如现代机器学*问题。
学*正确的价值观
现在我们有了导数函数,让我们首先计算截距 b 的随机值的斜率,例如:
由此我们知道,当截距为 0 时,在我们的成本函数上,该点切线的斜率为 -69 。一旦我们接*函数的最小值,这个斜率也将接* 0。
从我们在阿尔卑斯山的例子中,我们明白了我们应该采取的步骤的大小应该在某种程度上与给定点的斜率有关。这具有的目标,即当斜率较高且我们远离最小值时给出“较大”的步长,而当我们越来越接*零斜率时给出“较小”的步长。**
当我们迭代地进行这个过程时,只需要我们采用上面描述的具有实际所需步长的图像,并在每次迭代中调整它们。我们将使用这个常数来实际调整步长,我们称之为学*速率。考虑到这一点,我们可以定义以下表达式,以在每次迭代中生成和调整我们的步长:**
假设学*率为 0.2,我们将获得以下步长:**
考虑到我们的新步长,我们可以安全地将下一次迭代截距计算为实际步长:**
因此,对于我们的第一次迭代,我们有:
对于这个新的截距值,我们可以看到误差函数的斜率由下式给出:
随着斜率越来越接* 0,我们就可以理解,仅仅通过进行第一次迭代,我们实际上就越来越接*最佳值。通过重新查看图 6,我们确实可以推断,通过将截距从 0 增加到更大的值,我们确实可以减少估计值和实际观测值之间的残余误差。
通过几次迭代,我们得到:
*****Step Size(2)** = -41.4 * 0.2 = -8.28
**b(2)** = 13.8 - (-8.28) = 22.08
**dE(22.08)/db** = -24.8**Step Size(3)** = -24.8 * 0.2 = -4.96
**b(3)** = 22.08 - (-4.96) = 27.04
**dE(27.04)/db** = -14.8**Step Size(4)** = -14.8 * 0.2 = -2.96
**b(4)/db** = 27.04 - (-2.96)= 30
**dE(30)/db** = -9***
我们可以从这 3 次迭代中验证以下内容:
- 每走一步,我们都在接*一个更小的绝对斜率
- 当我们接* 0°斜率时,我们通过保持相同的学*速率来做更小的步骤
从视觉上我们可以看到,每一次迭代,我们都离数据集的预测线越来越*,实际上步长越来越小:
Figure 13) Applying the iteration values from the gradient descent for the intercept
为了适当地停止迭代,对于某个可接受的值,应该:
- 决定每次迭代的最小步长,例如,如果步长小于 0.001,则停止
- 当我们达到一定的迭代次数时停止
通过应用这些规则,我们可以验证算法在几次迭代后停止:
*****[+] Iteration 5:****Step Size** = -0.592
**b =** 30.592
**dE/db** = -7.8160000000000025**[+] Iteration 6:****Step Size** = -0.1184
**b = ** 30.7104
**dE/db** = -7.579200000000007*(...)***[+] Iteration 9:****Step Size** = -0.0009472000000000001
**b =** 30.7397632
**dE/db** = -7.5204736000000025***
以截距 b = 30.7397632 稳定。当绘制时,我们得到:
Figure 14) Using the stabilized predicted value given for a fixed slope to our intercept
通过这种方法,我们可以验证,通过渐进迭代(以基于学*洞穴的适应步长的速度),我们确实可以接*误差成本函数的最小化,如所绘制的,获得进化的非常接*的模型表示。这是通过简单地预测一个参数,截距来实现的。在接下来的部分,我们将试图理解这两个变量的模型的演变。
进入新的维度
既然我们已经了解了如何为我们的模型估计截距值,现在让我们向一维之外移动一步,并将梯度下降应用于截距和斜率。**
首先,如前一节所述,我们将使用链式法则,根据截距,计算成本函数的导数:**
现在,我们可以根据斜率继续寻找误差函数的偏导数:
对于偏导数的集合,对于这个函数的所有维度,我们称之为梯度:****
然后,我们将使用这个梯度,如在前面的部分,然后找到我们的误差函数的局部最小值。这就是称这个算法为梯度下降的原因。**
为了做到这一点,我们需要推断我们在上一节中为 intersect 所做的事情,以实际预测这两个值,并调整它们自己的相互依赖性。就这样暴露出来:
- 当我们现在接*两个变量时,这个问题可能再次类似于爬山,但是具有额外的复杂性。你需要调整双脚在墙上运动的速度,但也需要调整一个独特的手握动作的速度。因此,保持相同的学*速率,我们需要调整两个步长,一个用于斜率,另一个用于交点:**
- 使用新的步长,我们可以在每次迭代 n 中获得两个变量的当前预测:
- 然后,我们将再次计算梯度(即两个变量的导数,带有更新的值):
- 重复整个过程,直到我们达到迭代过程的选定极限。我们将继续使用步长限制。
为了实现这个小算法,我们还需要调整所有的初始值。还应该确定一个适当的停止值限制。以我们的例子为例,让我们决定:
- 初始相交为*b = 30*******
- 初始斜率为 m = 3
- 我们的学*率将会是 0.001
- 当学*率达到 0.00001 时,我们将停止
这可以用这个简单的 python 脚本来表示:
运行这个简单的脚本,我们获得以下输出:
然后获得我们两个变量的下列预测值:
- 坡度(米)= 2.5101
- 相交(b) = 40.5478
将这些值应用于包含误差传播的先前图,我们得到以下结果:
Figure 15) Using the stabilized predicted value, based on the computed slope and intercept, compared with the initial value
从上图中我们可以看到,我们的(线性)预测现在更接*于预测模型数据,然后我们可以使用我们的新模型来实际推断这两个参数之间的关系。
结论
我们可以通过使用线性回归来尝试对一组参数的自然关系做出初步预测,甚至获得一个简单的进化模型。在本文中,我们尝试使用这种简单的数值方法来清楚地展示梯度下降算法的基本功能,以及我们如何通过尝试最小化收敛误差函数来实现预测的迭代优化。
尽管它所拥有的概念可能会在概念和数学上表现得非常简单,但它们是深度学*和神经网络的基础之一。
图形神经网络的简单介绍(基础、深走和 GraphSage)
原文:https://towardsdatascience.com/a-gentle-introduction-to-graph-neural-network-basics-deepwalk-and-graphsage-db5d540d50b3?source=collection_archive---------0-----------------------
Image from Pexels
最*,图神经网络(GNN)在各个领域越来越受欢迎,包括社会网络、知识图、推荐系统,甚至生命科学。GNN 在建模图中节点之间的依赖性方面的能力使得与图分析相关的研究领域取得突破。本文旨在介绍图神经网络的基础知识和两个更高级的算法,DeepWalk 和 GraphSage。
图表
在我们进入 GNN 之前,让我们先了解一下什么是图。在计算机科学中,图是由顶点和边两部分组成的数据结构。一个图 G 可以由它包含的顶点 V 和边 E 的集合很好地描述。
边可以是有向的,也可以是无向的,这取决于顶点之间是否存在方向依赖。
A Directed Graph (wiki)
顶点通常被称为节点。在本文中,这两个术语可以互换。
图形神经网络
图形神经网络是一种直接作用于图形结构的神经网络。GNN 的一个典型应用是节点分类。本质上,图中的每个节点都与一个标签相关联,我们希望在没有事实的情况下预测节点的标签。本节将举例说明论文中所描述的算法,它是 GNN 的第一个提议,因而通常被视为 GNN 的原创。
在节点分类问题设置中,每个节点 v 通过其特征 x_v 来表征,并且与地面事实标签 t_v. 相关联。给定部分标记的图 G ,目标是利用这些标记的节点来预测未标记的标签。它学*用包含其邻域信息的 d 维向量(状态) h_v 来表示每个节点。具体来说,
https://arxiv.org/pdf/1812.08434
其中 x_co[v] 表示与 v 连接的边的特征,h_ne[v] 表示 v 的相邻节点的嵌入, x_ne[v] 表示v的相邻节点的特征,函数 f 是将这些输入投影到 d 维空间的转移函数。由于我们正在寻找 h_v 的唯一解,我们可以应用 Banach 不动点定理并将上述方程重写为迭代更新过程。这种操作通常被称为消息传递或邻域聚合。
https://arxiv.org/pdf/1812.08434
h 和 X 分别表示所有 h 和 X 的连接。
通过将状态 h_v 以及特征 x_v 传递给输出函数 g 来计算 GNN 的输出
https://arxiv.org/pdf/1812.08434
这里的 f 和 g 都可以解释为前馈全连接神经网络。L1 损耗可以直接用公式表示如下:
https://arxiv.org/pdf/1812.08434
这可以通过梯度下降来优化。
然而,本文指出 GNN 的这一原始提案有三个主要局限性:
- 如果放松“不动点”的假设,就有可能利用多层感知器来学*更稳定的表示,并消除迭代更新过程。这是因为,在最初的提议中,不同的迭代使用转移函数 f 的相同参数,而 MLP 的不同层中的不同参数允许分层特征提取。
- 它不能处理边信息(例如,知识图中的不同边可以指示节点之间的不同关系)
- 不动点会阻碍节点分布的多样化,因此可能不适合学*表示节点。
已经提出了 GNN 的几种变体来解决上述问题。然而,他们没有被涵盖,因为他们不是这篇文章的重点。
深度行走
DeepWalk 是第一个提出以无监督方式学*的节点嵌入的算法。就训练过程而言,它非常类似于单词嵌入。其动机是图中节点和语料库中单词的分布都遵循如下图所示的幂定律:
http://www.perozzi.net/publications/14_kdd_deepwalk.pdf
该算法包含两个步骤:
- 对图中的节点执行随机行走以生成节点序列
- 运行 skip-gram,根据步骤 1 中生成的节点序列学*每个节点的嵌入
在随机游走的每个时间步,从前一个节点的邻居均匀地采样下一个节点。然后,每个序列被截断成长度为 2|w| + 1 的子序列,其中 w 表示跳跃图中的窗口大小。如果你不熟悉 skip-gram,我之前的博客文章将向你简要介绍它是如何工作的。
本文采用层次化的 softmax 来解决 softmax 由于节点数量巨大而导致的计算量大的问题。为了计算每个单独输出元素的 softmax 值,我们必须计算所有元素 k 的所有 e^xk
The definition of Softmax
因此,对于原始的 softmax,计算时间是 O(|V|) ,其中 V 表示图中的顶点集。
分层 softmax 利用二叉树来处理这个问题。在这个二叉树中,所有的叶子(上图中的 v1,v2,… v8)都是图中的顶点。在每个内部节点中,有一个二元分类器来决定选择哪条路径。为了计算给定顶点 v_k 的概率,简单地计算沿着从根节点到叶子 v_k 的路径的每个子路径的概率。由于每个节点的子节点的概率总和为 1,所以所有顶点的概率总和等于 1 的性质在分层 softmax 中仍然成立。元素的计算时间现在减少到了 O(log|V|) ,因为二叉树的最长路径由 O(log(n)) 限定,其中 n 是叶子的数量。
Hierarchical Softmax (http://www.perozzi.net/publications/14_kdd_deepwalk.pdf)
在对 DeepWalk GNN 进行训练之后,该模型已经学*了每个节点的良好表示,如下图所示。不同的颜色表示输入图中不同的标签。我们可以看到,在输出图(二维嵌入)中,具有相同标签的节点聚集在一起,而大多数具有不同标签的节点被适当分离。
http://www.perozzi.net/publications/14_kdd_deepwalk.pdf
然而,DeepWalk 的主要问题是它缺乏泛化能力。每当一个新的节点进来,它必须重新训练模型,以便表示这个节点(转导)。因此,这种 GNN 不适用于图中节点不断变化的动态图。
图表法
GraphSage 提供了一个解决上述问题的方案,以一种归纳的方式学*每个节点的嵌入。具体来说,每个节点由其邻域的聚合来表示。因此,即使一个在训练期间看不见的新节点出现在图中,它仍然可以由它的相邻节点适当地表示。下面显示了 GraphSage 的算法。
https://www-cs-faculty.stanford.edu/people/jure/pubs/graphsage-nips17.pdf
外环表示更新迭代的次数,而 h^k_v 表示在更新迭代 k 时节点 v 的潜在向量。在每次更新迭代中, h^k_v 基于聚合函数、前一次迭代中 v 和 v 的邻域的潜在向量以及权重矩阵 W^k 进行更新。论文提出了三个聚合函数:
1。平均聚合器:
均值聚合器取一个节点及其所有邻域的潜在向量的平均值。
https://www-cs-faculty.stanford.edu/people/jure/pubs/graphsage-nips17.pdf
与原来的等式相比,它删除了上面伪代码中第 5 行的串联操作。这种操作可以被看作是一种“跳过连接”,这在本文的后面部分被证明可以极大地提高模型的性能。
2。LSTM 聚合器:
由于图中的节点没有任何顺序,它们通过置换这些节点来随机分配顺序。
3。汇集聚合器:
该操作符对相邻集执行元素池功能。下面显示了最大池的一个示例:
https://www-cs-faculty.stanford.edu/people/jure/pubs/graphsage-nips17.pdf
,可以用均值池或任何其他对称池函数来代替。指出池式聚合器性能最好,而平均池式和最大池式聚合器性能相*。本文使用 max-pooling 作为默认的聚合函数。
损失函数定义如下:
https://www-cs-faculty.stanford.edu/people/jure/pubs/graphsage-nips17.pdf
其中 u 和 v 在定长随机游走中同现,而 v_n 为不与 u 同现的负样本。这种损失函数鼓励距离较*的节点具有相似的嵌入,而距离较远的节点在投影空间中被分离。通过这种方法,节点将获得越来越多的关于其邻居的信息。
GraphSage 允许通过聚集其附*的节点来为看不见的节点生成可表示的嵌入。它允许将节点嵌入应用于涉及动态图的领域,其中图的结构是不断变化的。例如,Pinterest 采用了 GraphSage 的扩展版本 PinSage ,作为其内容发现系统的核心。
结论
您已经学*了图形神经网络、DeepWalk 和 GraphSage 的基础知识。GNN 在建模复杂图形结构方面的能力确实令人惊讶。鉴于其有效性,我相信,在不久的将来,GNN 将在人工智能的发展中发挥重要作用。如果你喜欢我的文章,别忘了在 Medium 和 Twitter 上关注我,在那里我经常分享 AI、ML 和 DL 的最先进的发展。
物联网/GPS 轨迹聚类和地理空间聚类简介
原文:https://towardsdatascience.com/a-gentle-introduction-to-iot-gps-trajectory-clustering-and-geospatial-clustering-daba8da8c41e?source=collection_archive---------13-----------------------
当谈到开发增值主张时,物联网、互联设备和地理空间数据都是热门话题。在这篇文章中,我将温和地介绍应用于 GPS 轨迹的无监督学*技术。
数据来自微软亚洲研究院,包含 2007 年 4 月至 2012 年 8 月间 182 名用户和 17621 次旅行的数据。数据大多是密集的,每 1 到 5 秒记录一次经度和纬度。
数据准备和清理
现在让我们来看看数据文件本身。嗯。plt '格式,一个我没见过的格式,不过还是用文本编辑打开吧。
好极了,看起来熊猫 read_csv 函数可以很好地与。plt 文件格式,附带的关于数据结构的文档看起来很准确。
import pandas as pdcolnames = ['lat','long', 'null', 'alt' ,'DateTime','Date','Time']df = pd.read_csv('20090724005608.plt', skiprows=6, names = colnames)
将时间序列放在一个数据框中很好,但是我们需要将每个数据框转换成具有多个特征的单个观察值。这样做将格式化数据,以便加载到聚类分析算法中。让我们合计速度、加速度和加加速度的第 10、25、50、75、90 和平均值。为此,我们将编写几个 python 函数来应用于每个文件。
def add_feat(df_input):
"""
This function takes in raw lat long time series from the microsoft geolife data.Preprocessing notes: skip the first six lines before doing pandas read csv , expecting columns in ['lat','long', 'null', 'alt' ,'DateTime','Date','Time']Requres: pandas imported as pd
from vincenty import vincenty
Adds:
speed
acceleration
jerk
bearing rate
distance travelled
"""
df = df_input
# add some initial shifts
df['lat_shift'] = df.lat.shift(-1)
df['long_shift'] = df.long.shift(-1)
df['time_shift'] = df.DateTime.shift(-1)
# add speed
def speed(x):
try:
s = vincenty((x[-3],x[-2]),(x[0],x[1]), miles = True) / ((x[-1]-x[4]) * 24)
except:
s= np.nan
return s
df['speed_mph'] = df.apply(speed,axis =1)
df['speed_shift'] = df.speed_mph.shift(-1)
# add acceleration
def accel(x):
try:
a = (x[-1] - x[-2]) / ((x[9] - x[4]) *24*60*60)
except:
a = np.nan
return a
df['acceleration'] = df.apply(accel, axis =1)
df['acceleration_shift'] = df.acceleration.shift(-1)
# add jerk
def jerk(x):
try:
j = (x[-1] - x[-2]) / ((x[9] - x[4]) *24*60*60)
except:
j = np.nan
return a
df['jerk'] = df.apply(accel, axis =1)
df['jerk_shift'] = df.jerk.shift(-1)
# add y for bearing calculator
def y(x):
try:
yy = np.sin((x[8] - x[0]) * np.pi/180) *np.cos( x[7]* np.pi/180)
except:
yy= np.nan
return yy
df['y'] = df.apply(y, axis =1)
# add x for bearing calculator
def x(x):
try:
xx = np.cos(x[0] * np.pi/180) *np.sin(x[7]* np.pi/180) - np.sin(x[0]* np.pi/180) * np.cos(x[7]* np.pi/180)*np.cos((x[8]-x[1])* np.pi/180)
except:
xx = np.nan
return xx
df['x'] = df.apply(x,axis =1)
# calculate bearing
def bearing(x):
try:
b = np.arctan2(x[-2],x[-1])*180/np.pi
except:
b = np.nan
return b
df['bearing'] = df.apply(bearing,axis=1)df['brearing_shift'] = df.bearing.shift(-1)
# calculate bearing rate (rate of change of direction)
def bearing_rate(x):
try:
br = abs(x[-1]-x[-2])
except:
br = np.nan
return br
df['bearing_rate'] = df.apply(bearing_rate,axis=1)
# calculate distance travelled
def distance(x):
try:
dist = vincenty((x[7],x[8]),(x[0],x[1]), miles = True)
except:
dist= np.nan
return dist
df['distance'] = df.apply(distance,axis = 1)
df.drop(df.tail(4).index,inplace=True)
return dfdef list_df_summary(input_df):
'''
Converts output from add_feat function into an observation for machine learning
'''
names = ['speed_10','speed_25','speed_50','speed_75','speed_90','speed_ave',
'accel_10','accel_25','accel_50','accel_75','accel_90','accel_ave',
'jerk_10','jerk_25','jerk_50','jerk_75','jerk_90','jerk_ave',
'bearingRate_10','bearingRate_25','bearingRate_50','bearingRate_75','bearingRate_90','bearingRate_ave',
'distance_traveled','time_traveled' ,'last_lat','last_long','start_lat','start_long'
]
values = list()
#speed
values.append(input_df.quantile(.10)[8])
values.append(input_df.quantile(.25)[8])
values.append(input_df.quantile(.50)[8])
values.append(input_df.quantile(.75)[8])
values.append(input_df.quantile(.90)[8])
values.append(input_df.mean()[8])
#accel
values.append(input_df.quantile(.10)[10])
values.append(input_df.quantile(.25)[10])
values.append(input_df.quantile(.50)[10])
values.append(input_df.quantile(.75)[10])
values.append(input_df.quantile(.90)[10])
values.append(input_df.mean()[10])
#jerk
values.append(input_df.quantile(.10)[12])
values.append(input_df.quantile(.25)[12])
values.append(input_df.quantile(.50)[12])
values.append(input_df.quantile(.75)[12])
values.append(input_df.quantile(.90)[12])
values.append(input_df.mean()[12])
#bearing
values.append(input_df.quantile(.10)[18])
values.append(input_df.quantile(.25)[18])
values.append(input_df.quantile(.50)[18])
values.append(input_df.quantile(.75)[18])
values.append(input_df.quantile(.90)[18])
values.append(input_df.mean()[18])
#distance travelled
values.append(input_df.distance.sum())
#time travelled
values.append((input_df.iloc[-1,4] - input_df.iloc[0,4])*24*60)
#lat long
values.append(input_df.iloc[-1,0])
values.append(input_df.iloc[-1,1])
values.append(input_df.iloc[0,0])
values.append(input_df.iloc[0,1])
return pd.DataFrame([values],columns=names)
为了遍历文件目录,我使用了一个名为 glob 的包。下面的代码完成了为每个。GeoLife 目录中的 plt 文件。然后通过运行 for 循环。plt 列出并应用前面的函数让我们为机器学*做好准备!
plts = []
for folder in glob('Geolife Trajectories 1.3/Data/*/Trajectory'):
for file in glob(folder +'/*.plt'):
plts.append(file)large_df = []
for i, file in enumerate(plts):
print( int(i*100 / len(plts)))
try:
large_df.append(list_df_summary(add_feat(pd.read_csv(file, skiprows=6,names=colnames))))
except:
print('error at: ' + file)
df = pd.concat(large_df)
对于我的例子,我将使用 modeling_df 特性的一个子集来创建集群。不是每个特征都有有用的信息(阅读更多关于维度的诅咒)。这是一个迭代的过程,你可以尝试不同的子集来开发不同的集群。最初,我查看每个特征的分布,猜测它是否对无监督学*算法有价值。
GPS 轨迹聚类
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
import seaborn as sns
from collections import Counter## Remove longer trips
df_local_all_feat=df[(df.time_traveled < 300) & (df.distance_traveled < 100)& (df.speed_90<75)]## Select Features with unique distributions
df_local = df_local_all_feat[['speed_90','speed_ave','accel_75','speed_50','accel_ave','distance_traveled','time_traveled']]## Scale Data for KMeans
X = StandardScaler()
X = X.fit_transform(df_local)#################################
### PERFORM KMeans CLUSTERING ###
#################################Sum_of_squared_distances = []
scores = []
cluster_count = []
K= range(2,15,1)
for i in K:
km = KMeans(n_clusters=i)
km.fit(X)
pred =km.predict(X)
Sum_of_squared_distances.append(km.inertia_)
scores.append(silhouette_score(X, pred))
cluster_count.append(i)
print(Counter(pred))
print(str(silhouette_score(X, pred)) + ' clusters:' +str(i))
print('------')########################################
### Elbow plot with silhouette score ###
########################################sns.set_context('talk')
sns.lineplot(cluster_count,scores)
plt.xlabel('Cluster Count')
plt.ylabel('Silhouette Score')
plt.title('Elbow Method For Optimal Cluster Count')
plt.show()
The elbow plot is telling us to investigate either 6 or 7 clusters.
df_local_all_feat['cluster'] = KMeans(n_clusters=7).fit_predict(X)
Trajectory Clusters
聚类 4,5 包含很少数量的观察值,因此不包括在此分析中。
让我们看看最终目的地和轨迹簇。
Tsinghua University, Trajectory Cluster
看看清华大学,我们可以看到大量的集群 0 和 1。
Tencent Office, Trajectory Cluster
看看腾讯的办公室,我们可以开始看到更多的地铁乘坐,集群 5 和 6。
看一下当地的购物区,地铁/火车出行较少,但火车出行通常距离更长(大小是行驶的总距离)。
目标地理空间聚类
上面部分的放大图可以在下面找到。我们已经确定了 3 个一般的兴趣点,现在是时候将它们聚集在一起了。
Tsinghua University on top, shopping center on lower left, and Tencent on lower right
看起来我们需要一种算法,既能结合距离和接*度,又能排除噪音。听起来 DB 扫描将是这个应用程序的算法。
from sklearn.cluster import DBSCAN# pull out the only the location metrics
df_cluster = df_local_all_feat[['Last Lat', 'Last Long']]X = StandardScaler()
X = X.fit_transform(df_cluster)scores = []
EP =[]
number =[]
eps= [.08,.10,.15,.20,.25,.30,.40,.50,.60]
size= [200,250,300]
for ep in eps:
for siz in size:
db = DBSCAN(eps=ep, min_samples=siz)
pred = db.fit_predict(X)
print('ep:'+ str(ep) + ' size:'+ str(siz))
print(Counter(pred))
try:
scores.append(silhouette_score(X, pred))
except:
scores.append(np.nan)
EP.append(ep)
number.append(siz)
变量 eps 和 size 将允许您为您的应用网格搜索适当的超参数。最后,我选择了下面的价值观。
db = DBSCAN(eps= 0.37, min_samples = 250)
结合两种聚类算法
通过结合两种聚类算法,我们可以基于兴趣点过滤特定的行程,以确定人们来自哪里以及到达所述兴趣点所使用的交通方式。
对于清华大学,我们可以看到人们通常从附*短途旅行。
对于购物区,我们可以看到人们的出行距离更远,并且大多使用交通模式 0。
对于腾讯办公室来说,人们从最远的地方出发。然而,从附*通勤的人通常选择交通模式 0,而从更远通勤的人选择交通模式 6。
结论
使用各种无监督学*算法,我们能够确定人们如何前往特定位置,如何限制兴趣点,以及人们来自哪里。
通过调整,在数据收集架构中,根据出行距离和交通方式等因素来确定人们在一个地点的居住方式将会很有意义。
机器学*的简明介绍
原文:https://towardsdatascience.com/a-gentle-introduction-to-machine-learning-599210ec34ad?source=collection_archive---------19-----------------------
内部 AI
任何足够先进的技术都和魔法没什么区别
欢迎光临!这篇文章是我第一次尝试稍微深入一点像机器学*这样的高级主题。我写这篇文章有两个原因。首先,我发现这个主题非常有趣,如果你对机器学*感兴趣,但不知道从哪里开始,那么这篇文章是给你的。其次,这篇文章是我综合我的学*并与机器学*爱好者分享我的知识的一种方式。
我希望你有一些“概率论”的基础知识,以便跟上。由于机器学*是一个非常广泛的话题,我希望您喜欢阅读,因此本文将主要关注:
- 揭秘什么是机器学*?
- 学*方法
- 监督和非监督学*
- 回归、分类和聚类概述
- 数据集的两个实例。
- 免费资源,了解更多信息
So、什么是机器学*&我们为什么需要它?
任何足够先进的技术都和魔法没什么区别
—亚瑟·C·克拉克
我们知道人类从过去的经验中学*,机器遵循人类给出的指令。
W 如果人类可以从过去的数据中训练机器,做人类能做的事情,会怎么样?
好吧,那就是机器学*,我们来深究一下。
这个世界充满了数据,大量的数据——图片、音乐、文本、视频、电子表格。机器学*是人工智能的科学和分支,其中计算机根据数据进行训练以执行特定任务,而不是通过显式编程。
传统软件开发 VS 机器学*
在传统的软件开发方法中,输入和算法是已知的,你编写一个函数来产生一个输出。
- 输入数据
- 通过对算法应用逻辑来设计算法
- 产生输出
然而,在机器学*方法中,你知道输入和期望输出,但不知道给出输出的算法。
- 给出一组输入数据
- 给出一组期望的输出数据
- 通过神经网络 (将在另一篇文章中介绍)你得到预测期望输出的算法。
机器学*的一些应用
公司使用机器学*算法来优化他们产品的结果。
- 当你在网飞的时候,你怎么知道你想看哪部电影?网飞使用机器学*提出建议。
- 当你使用信用卡进行购买时,上面有欺诈保护,这就是机器学*。
- 机器学*的其他应用包括语音识别、语言翻译、自动驾驶汽车和许多其他应用。
学*是如何发生的?
在机器学*的大多数应用:重点不在于建立模型(“理解底层过程”),而在于预测。
就像人类从经验中学*一样,机器学*也是一样,你给他们大量的例子(数据),他们就开始弄明白发生了什么。我们人类进行归纳推理而不是演绎推理。让我们回顾一下这两个概念,因为它们在机器学*中非常重要。
归纳(具体→一般)是根据我们有限的经验,从具体的例子中归纳出结论,这里的结论可能并不总是 100%准确。
- 我们每天都观察日出。
- 所以我们预测太阳明天也会升起。
- 因此,我们预测明天太阳还会升起。
演绎(一般→具体)是从一般陈述中得出具体结论的过程。这里的结论是事实。
- 所有的人都会死。
- 威廉是个男人。
- 因此,威廉是凡人。
重要的是要记住,任何学*的系统都有“归纳偏差”或先验知识,机器学*旨在自动化“归纳推理”的过程。机器学*这种多样性的一个显著例子就是监督学*和非监督学*的分离,这里我就不说强化学*了。
监督学*
在监督学*中,考虑到输入和输出之间存在某种关系,我们得到了一个带标签的数据集,并且已经知道我们的正确输出应该是什么样子。自动驾驶汽车就是监督学*的一个例子。监督问题分为“回归”和“分类”问题。
在一个“回归”问题中,我们试图预测具有连续结果的事物。例如,给定一个人的照片,我们必须根据给定的照片来预测他们的年龄。
在“分类问题中,我们试图预测具有离散输出的结果。例如,给定一个患有肿瘤的患者,我们必须预测肿瘤是恶性的还是良性的。
机器学*的 5 个步骤
为了设计机器学*算法,需要遵循以下 5 个主要步骤:
- 输入,又称功能 : x
- 输出,也称为标签 : y
- 目标函数: f: x → y (未知)
- 采集数据 (x1,y1),(x2,y2),…。,(xn,yn)
- 假设: h: x → y
让我们看两个既有分类又有回归的监督学*的例子,以便更深入地理解。
例 1:分类
假设我们在大学的招生办公室工作,我们的工作是接受或拒绝一个学生。为了做出决定,我们需要一些学生的意见,对吗?让我们看看:他们的成绩和最后一年的考试分数。
我们在尝试根据以往收集的数据来预测,学生 C 是否会被录取?为了形象化,我们可以把它画在图上。
Udacity’s course “Intro to Deep Learning with PyTorch”
在上图中,我们首先用一条线将好的和坏的数据分开。这条线将成为我们的模型。蓝点代表被录取的学生的数据点,红点代表根据他们的考试分数和成绩被拒绝的学生的数据点。看这个图表,我们可以看到,线上的学生被录取,而线下的学生被拒绝。你可能会想,线上有几个红点,线下有几个蓝点,是的,你是对的,模型犯了几个错误,这就是为什么它是概率而不是 100%确定的。所以可以肯定的是,如果一个分数超过了分数线,那么这个学生就被录取了。成绩(6)和考试分数(7)的学生 C 在分数线以上,因此我们可以有把握地认为学生 C 最有可能被录取。这是一个分类问题,因为输出是离散的(接受,拒绝)。
示例 2:回归(小高级)
我们举一个 房价预测的例子。 你的朋友拥有一栋 750 平方英尺的房子,他想卖掉房子,想知道能卖多少钱。你知道机器学*,因此你可以用你的机器学*知识和技能帮助他预测价格。我们来看看怎么做。
我们的目标是,给定一个训练集,学*一个函数 h: X → Y ,使得 h(x)是 Y 的相应值的“良好”预测器。出于历史原因,这个函数 h 被称为假设。假设接受输入并给出一个估计值,所以它从 x → y 映射。
我们可以使用一条“线性线(下方图片中的粉色线)来拟合数据集,基于此,看起来他可能可以以 15 万美元的价格出售它。然而,可能有比线性更好的学*算法。除了将直线拟合到数据中,我们也许可以尝试将“二次”拟合到这个函数中(下图中的蓝线)。然后,通过对它进行预测,看起来他可能可以以 20 万美元的价格出售它。现在的问题是选择我们应该使用哪一个?挑选中没有公平可言,哪个给我们的朋友的价格最好。这是一个回归问题,因为答案可以是连续的。**
Andrew Ng’s Machine Learning course on Coursera
无监督学*
在无监督学*中,我们很少或根本不知道我们的结果应该是什么样的。因此,目的是发现数据中隐藏的结构。理解无监督学*的核心思想是“聚类”。
聚类:取 50 个不同的人集合,想办法自动把这些人分组。也许你想把他们分成男性和女性,因此你可以决定如何去做。你也许可以根据面部毛发、肤色、衣着等来划分他们。最后,你可以说你是 27 个男性和 23 个女性。
关键术语
- 特性:模型的输入
- 示例:用于训练的输入/输出对
- 标签:模型的输出
- 层:神经网络中连接在一起的节点的集合
- 模型:你的神经网络的表示
总结
- 任何学*的系统都有“归纳偏差”或“先验知识”。
- 机器学*旨在自动化“归纳推理”的过程
- 我们需要知道我们在寻找什么(归纳偏差)
- 由于机器学*是一种归纳参考的形式,我们永远无法对结果充满信心。
- 在机器学*的大部分应用中,重点与其说是建立模型,不如说是预测。
这篇文章只是对机器学*领域的浅尝辄止,还有更多的内容,并且有大量的在线资源可以用来增强你的知识。下面我提供了 5 个我个人认为非常有用的资源。
一些免费的有用资源,了解更多:
- 谷歌的人工智能冒险
- Udacity 的机器学*课程
- 机器学*变得有趣&有趣
- 加州理工学院的机器学*课程
- 吴恩达 Coursera 课程
这篇文章是我第一次尝试深入像机器学*这样的复杂话题。我会写更多的文章来讨论机器学*背后的数学。我希望我做了一个体面的解释工作,你觉得这篇文章很有见地。
保持好奇和不断学*:)
最大似然估计和最大后验估计简介
原文:https://towardsdatascience.com/a-gentle-introduction-to-maximum-likelihood-estimation-and-maximum-a-posteriori-estimation-d7c318f9d22d?source=collection_archive---------1-----------------------
以足球为例获得最大似然法和地图的直觉
Photo by Mitch Rosen on Unsplash
最大似然估计(MLE)和最大后验估计(MAP)是估计统计模型参数的方法。
尽管这些方法背后有一点高等数学,但 MLE 和 MAP 的思想非常简单,直观易懂。在这篇文章中,我将解释什么是 MLE 和 MAP,重点是方法的直觉以及背后的数学。
例子:利物浦足球俱乐部在下个赛季赢得比赛的概率
2018-19 赛季,利物浦 FC 在英超 38 场比赛中赢了 30 场。有了这些数据,我们想猜测下赛季利物浦赢得比赛的概率。
这里最简单的猜测是 30/38 = 79% ,这是基于数据的最佳猜测。这实际上是用 MLE 方法估计的。
然后,假设我们知道利物浦在过去几个赛季的胜率在 50%左右。你认为我们最好的猜测还是 79%吗?考虑到先前的知识以及本赛季的数据,我认为 50%到 79%之间的某个值会更现实。这是用图法估算的。
我相信上面的想法很简单。但是为了更精确的理解,我将在下面的部分中阐述 MLE 和 MAP 的数学细节。
模型和参数
在讨论每种方法之前,让我先澄清一下这个例子中的模型和参数,因为 MLE 和 MAP 是估计统计模型的参数的方法。
在这个例子中,我们简化为利物浦在所有赛季的所有比赛中只有一个获胜概率(姑且称之为 θ ),而不考虑每场比赛的独特性和真实足球比赛的任何复杂因素。换句话说,我们假设利物浦的每场比赛都是伯努利试验,获胜概率为 θ 。
有了这个假设,我们就可以描述对于任意给定数量的 k 和 n ( k≤n ),利物浦在 n 场比赛中赢 k 次的概率。更准确的说,我们假设利物浦的胜数服从参数为 θ 的二项分布。给定获胜概率 θ ,利物浦在 n 场比赛中赢 k 次的概率公式如下。
这种简化(仅使用单个参数 θ 来描述概率,而不考虑现实世界的复杂性)是该示例的统计建模,并且 θ 是待估计的参数。
从下一节开始,我们用 MLE 和 MAP 来估计这个 θ 。
最大似然估计
在上一节中,我们得到了对于给定的 θ ,利物浦在 n 场比赛中赢 k 次的概率公式。
由于我们有本赛季的观测数据,即38 场比赛中的 30 场胜利(姑且称此数据为 D ),我们可以计算出P(D |θ)——对于给定的 θ ,观测到此数据 D 的概率。让我们以 θ=0.1 和 θ=0.7 为例计算 P(D|θ) 。
当利物浦获胜概率 θ = 0.1 时,观察到这个数据D(38 场比赛 30 胜)的概率如下。
P(D |θ)= 0.000000000000000000211。所以,如果利物浦的获胜概率 θ 实际上是 0.1 ,这个数据D(38 场比赛 30 胜)是极不可能被观测到的。那如果 θ = 0.7 呢?
远高于之前的。所以如果利物浦的获胜概率 θ 为 0.7,这个数据 D 比 θ = 0.1 时更容易被观察到。
基于这种比较,考虑到实际观测数据 D ,我们可以说 θ 更有可能是 0.7 而不是 0.1 。
这里,我们一直在计算对于每个 θ 观察到 D 的概率,但同时,我们也可以说,我们一直在根据观察到的数据检查 θ 的每个值的可能性。正因为如此, P(D|θ) 也被认为是 θ 的可能性。这里的下一个问题是,最大化可能性 P(D|θ) 的 θ 的精确值是什么?没错,这就是最大似然估计!
最大化似然性的 θ 的值可以通过使似然函数对 θ 求导并将其设置为零来获得。
解决这个, θ = 0,1 或者 k/n 。由于当 θ= 0 或 1 时似然性为零,因此 θ 的值使似然性最大化为 k/n 。
本例中,用 MLE 估计时, θ 的估计值为 30/38 = 78.9% 。
最大后验估计
当你有足够的数据时,MLE 是强大的。然而,当观察到的数据量很小时,这种方法效果不好。例如,如果利物浦只有 2 场比赛,他们赢了这 2 场比赛,那么 MLE 估计的 θ 的值是 2/2 = 1 。意思是估计说利物浦赢 100% ,这是不切实际的估计。地图可以帮助处理这个问题。
假设我们事先知道利物浦过去几个赛季的胜率在 50%左右。
然后,没有这个赛季的数据,我们已经对 θ 的潜在价值有了一些概念。(仅)基于先验知识, θ 的值最有可能是 0.5 ,不太可能是 0 或 1 。换句话说, θ=0.5 的概率高于 θ=0 或 1 。称之为先验概率 P(θ),如果我们将它形象化,它将如下。
Figure 1. A visualisation of P(θ) expressing the example prior knowledge
然后,有了本赛季的观察数据D(38 场比赛中 30 胜),我们可以更新这个仅基于先验知识的 P(θ) 。给定 D 的 θ 的更新概率表示为 P(θ|D) ,称为后验概率。
现在,考虑到我们的先验知识和观测数据,我们想知道 θ 的最佳猜测。这意味着最大化 P(θ|D) 并且这是 MAP 估计。
这里的问题是,如何计算 P(θ|D) ?到目前为止,在本文中,我们检查了计算 P(D|θ) 的方法,但还没有看到计算 P(θ|D) 的方法。为此,我们需要使用下面的贝叶斯定理。
本文不深入讨论贝叶斯定理,但有了这个定理,我们可以利用似然 P(D|θ) 和先验概率 P(θ) 计算后验概率 P(θ|D) 。
等式中有 P(D) ,但 P(D) 与 θ 的值无关。由于我们只对寻找最大化 P(θ|D) 的 θ 感兴趣,我们可以在最大化中忽略 P(D) 。
上面的等式意味着关于 θ 的后验概率 P(θ|D) 的最大化等于关于 θ 的似然 P(D|θ) 和先验概率 P(θ) 的乘积的最大化。
我们在本节的前面讨论了 P(θ) 的含义,但是我们还没有进入公式。本质上,我们可以用任何一个将概率分布描述为 P(θ) 的公式来很好地表达我们的先验知识。然而,为了计算的简单性,使用对应于可能性的概率分布的特定概率分布。叫做共轭先验分布。
在这个例子中,可能性 P(D|θ) 遵循二项式分布。由于二项分布的共轭先验是贝塔分布,所以我们这里用贝塔分布来表示 P(θ) 。贝塔分布描述如下。
其中, α 和 β 称为超参数,无法通过数据确定。相反,我们主观地设置它们是为了更好地表达我们的先验知识。例如,下图是不同值的 α 和 β 的贝塔分布的可视化。你可以看到左上角的图是我们在上面的例子中使用的图(表示 θ=0.5 是基于先验知识的最可能的值),右上角的图也表示相同的先验知识,但这是为相信过去几个赛季的结果很好地反映了利物浦的真实能力的人准备的。
Figure 2. Visualisations of Beta distribution with different values of α and β
这里有一个关于右下图的说明:当 α=1 和 β=1 时,意味着我们对 θ 没有任何先验知识。在这种情况下,估计将与 MLE 的估计完全相同。
所以,现在我们有了所有的组件来计算 P(D|θ)P(θ) 以使其最大化。
与 MLE 一样,我们可以通过对这个函数求关于 θ 的导数,并将其设置为零,从而使 θ 最大化。
通过解决这个问题,我们得到以下结果。
在这个例子中,假设我们用 α=10 和 β=10 ,那么θ=(30+10–1)/(38+10+10–2)= 39/56 = 69.6%
结论
从上面的例子可以看出,MLE 和 MAP 复杂的数学方程背后的思想出奇的简单。我在本文中使用了二项分布作为例子,但是 MLE 和 MAP 也适用于其他统计模型。希望这篇文章能帮助你理解 MLE 和 MAP。
自然语言处理入门
原文:https://towardsdatascience.com/a-gentle-introduction-to-natural-language-processing-e716ed3c0863?source=collection_archive---------4-----------------------
介绍自然语言处理和对文本数据的情感分析。
Image Source
人类通过某种形式的语言进行交流,无论是文本还是语音。现在要让计算机和人类互动,计算机需要理解人类使用的自然语言。自然语言处理就是让计算机学*、处理和操作自然语言。
在这篇博客中,我们将看看在自然语言处理任务中使用的一些常见做法。并且在电影评论上建立简单的情感分析模型,以预测给定评论是正面的还是负面的。
什么是自然语言处理(NLP)?
NLP 是人工智能的一个分支,它处理分析、理解和生成人类自然使用的语言,以便使用自然人类语言而不是计算机语言在书面和口头上下文中与计算机交互。
自然语言处理的应用
- 机器翻译(谷歌翻译)
- 自然语言生成
- 网络搜索
- 垃圾邮件过滤器
- 情感分析
- 聊天机器人
…以及更多
数据清理:
在数据清理过程中,我们从原始数据中移除特殊字符、符号、标点符号、HTML 标签<>等,这些数据不包含模型要学*的信息,这些只是我们数据中的噪声。
这个过程还取决于问题陈述,比如从原始文本中删除什么。例如,如果问题包含来自经济或商业世界的文本,那么像$或其他货币符号这样的符号可能包含一些我们不想丢失的隐藏信息。但大多数情况下我们会移除它们。
数据预处理:
数据预处理是一种数据挖掘技术,包括将原始数据转换成可理解的格式。
小写:
让所有文本都变成小写是最简单也是最有效的文本预处理形式之一。
Image Source
符号化:
记号化是将文本文档分解成称为记号的单个单词的过程。
如上所述,句子被分解成单词(记号)。自然语言工具包(NLTK)是一个流行的开源库,广泛用于 NLP 任务。对于这个博客,我们将使用 nltk 进行所有的文本预处理步骤。
您可以使用 pip 下载 nltk 库:
*!pip install nltk*
停止单词删除:
停用词是在文本文档中不提供太多信息的常用词。像‘the’,‘is’,‘a’这样的词价值较小,会给文本数据增加干扰。
NLTK 中有一个内置的停用词列表,我们可以用它从文本文档中删除停用词。然而,这不是每个问题的标准停用词表,我们也可以根据领域定义自己的停用词表。
NLTK 有一个预定义的停用词列表。我们可以从这个列表中添加或删除停用词,或者根据具体任务来使用它们。
词干:
词干化是将一个单词缩减为其词干/词根的过程。它将单词(如“help”、“helping”、“helped”、“helped”)的词形变化减少到词根形式(如“help”)。它从单词中去掉词缀,只留下词干。
Image Source
词干可能是也可能不是语言中的有效词。例如,movi 是 movie 的词根,emot 是 emotion 的词根。
词汇化:
词汇化与词干化的作用相同,将单词转换为其词根形式,但有一点不同,即在这种情况下,词根属于语言中的有效单词。例如,在词干的情况下,单词 caring 将映射到“care”而不是“car”。
WordNet 是英语中有效单词的数据库。NLTK 的 WordNetLemmatizer()使用来自 WordNet 的有效单词。
N-grams:
Image Source
N-grams 是多个单词一起使用的组合,N=1 的 N-grams 称为 unigrams。类似地,也可以使用二元模型(N=2)、三元模型(N=3)等等。
当我们希望保留文档中的序列信息时,可以使用 n 元语法,比如给定的单词后面可能跟什么单词。单字不包含任何序列信息,因为每个单词都是独立的。
文本数据矢量化:
将文本转换为数字的过程称为文本数据矢量化。现在,在文本预处理之后,我们需要用数字表示文本数据,也就是说,用数字对数据进行编码,以便算法进一步使用。
包话(鞠躬):
这是最简单的文本矢量化技术之一。BOW 背后的直觉是,如果两个句子包含一组相似的单词,就说它们是相似的。
考虑这两句话:
Image Source
在 NLP 任务中,每个文本句子被称为一个文档,这些文档的集合被称为文本语料库。
BOW 在语料库(数据中所有标记的集合)中构建了一个包含 d 个唯一单词的字典。例如,上图中的语料库由 S1 和 S2 的单词组合而成。
现在,我们可以想象创建一个表,其中的列是语料库中唯一的单词集,每行对应一个句子(文档)。如果这个单词出现在句子中,我们把它的值设置为 1,否则我们把它设置为 0。
Image Source
这将创建一个矩阵 dxn ,其中 d 是语料库中唯一标记的总数,而 n 等于文档的数量。在上面的例子中,矩阵的形状为 11x2。
TF-IDF:
Image Source
它代表词频(TF)-逆文档频率。
词频:
词频定义了在文档中找到某个单词的概率。现在假设我们想找出在文档 dj 中找到单词 wi 的概率是多少。
词频( wi , dj ) =
wi 出现在 dj 中的次数/ 在 dj 中的总字数
逆文档频率:
IDF 背后的直觉是,如果一个单词出现在所有文档中,它就没有多大用处。它定义了单词在整个语料库中的独特性。
IDF(wi,Dc) = log(N/ni)
这里, Dc =语料库中的所有文档,
N =文件总数,
ni =包含 word ( wi )的文档。
如果 wi 在语料库中更频繁,则 IDF 值减少。
如果 wi 不频繁,这意味着 ni 减少,因此 IDF 值增加。
TF( 作业指导书、DJ)*IDF(作业指导书、 Dc )
TF-IDF 是 TF 和 IDF 值的乘积。它给予在文档中出现较多而在语料库中出现较少的单词更大的权重。
情感分析:IMDB 电影评论
Image Source
关于
该数据集包含来自 IMDB 网站的 50,000 条评论,正面和负面评论的数量相等。任务是预测给定评论(文本)的极性(积极或消极)。
我使用 Deepnote 在 IMDB 数据集上做数据分析,它的设置简单快捷,并且提供了很好的协作工具。我最喜欢的是从多个数据源即插即用的能力。如果你是新手,正在开始你的数据科学之旅,我强烈建议你去看看。这里是这个项目的笔记本。
1.数据的加载和浏览
IMDB 数据集可以从这里下载。
数据集概述:
正面评价标为 1,负面标为 0。
样本正面评论:
样品差评:
2.数据预处理
这里,我们在一个方法中完成了数据清理和预处理的所有步骤,如上所述。我们使用词干化而不是词干化,因为在测试两者的结果时,词干化给出的结果比词干化稍好。
词干化或词干化或两者的使用取决于问题,所以我们应该尝试看看哪种方法对给定的任务最有效。
通过对所有评论应用 data_preprocessing(),在 dataframe 中添加一个新列 preprocessed _ review。
3.向量化文本(评论)
将数据集分为训练和测试(70–30):
我们正在使用 sklearn 的 train_test_split 将数据拆分为训练和测试。这里我们使用参数分层,在训练和测试中有相等比例的类。
低头
这里我们使用了 min _ df = 10T5,因为我们只需要那些在整个语料库中出现至少 10 次的单词。
TF-IDF
4.构建 ML 分类器
带评论 BOW 编码的朴素贝叶斯
带 BOW 的朴素贝叶斯给出了 84.6%的准确率。用 TF-IDF 试试吧。
带有 TF-IDF 编码评论的朴素贝叶斯
TF-IDF 给出了比 BOW 稍好的结果(85.3%)。现在让我们用一个简单的线性模型,逻辑回归,来试试 TF-IDF。
对 TF-IDF 编码的评论进行逻辑回归
使用 TFIDF 编码的评论的逻辑回归给出了比朴素贝叶斯更好的结果,准确率为 88.0%。
绘制混淆矩阵为我们提供了关于有多少数据点被模型正确和错误分类的信息。
在 7500 个负面评论中,6515 个被正确分类为负面,985 个被错误分类为正面。在 7500 个正面评论中,6696 个被正确分类为正面,804 个被错误分类为负面。
摘要
我们已经学*了一些基本的 NLP 任务,并为电影评论的情感分析建立了简单的 ML 模型。通过深度学*模型尝试单词嵌入,可以实现进一步的改进。
感谢您的阅读。完整的代码可以在这里找到。
参考资料:
[## 处理文本数据(使用 Python)的终极指南——面向数据科学家和工程师
引言实现任何水平的人工智能所需的最大突破之一是拥有…
www.analyticsvidhya.com](https://www.analyticsvidhya.com/blog/2018/02/the-different-methods-deal-text-data-predictive-python/) [## 关于自然语言处理和机器学*的文本预处理
数据科学家卡维塔·加内桑。根据最*的一些谈话,我意识到文本预处理是一个严重的…
www.kdnuggets.com](https://www.kdnuggets.com/2019/04/text-preprocessing-nlp-machine-learning.html)
推荐系统简介
原文:https://towardsdatascience.com/a-gentle-introduction-to-recommendation-systems-eaddcbde07ce?source=collection_archive---------16-----------------------
基于内容的过滤、协同过滤及实际应用
推荐系统简介
如果你正在阅读关于推荐系统的文章,你肯定已经知道我们将要讨论的内容,所以也许你可以跳过这一章。但是如果你是被封面图片所吸引,或者如果你想知道更多关于推荐系统在过去几年是如何出现和成长的,那么请继续关注这篇文章的这一部分。
让我们回到过去,试着想象一下:这是周五晚上,你想租一盘你最*的大片的录像带。你和你的女朋友去那里,已经在讨论你要租哪部电影了。也许是喜剧?或者一部动作片?一场雷雨即将来临,这给恐怖电影或惊悚片带来了完美的气氛。
当你在思考的时候,你的女朋友告诉你:“你在网上搜索过什么好的推荐吗?”。不幸的是,在你工作的时候,互联网一整天都是关闭的,不管怎样,你仍然试图让自己在万维网上到处都是那些晦涩难懂的东西。
你终于到了,但是经过*一个小时的考虑,你还是不知道该选什么。你已经看过所有受欢迎的电影,商店的首要部分全是废话。你不想吹毛求疵,但就是没什么好的。你的女朋友问桌子后面的大片伙伴,但他对电影的了解似乎比你爷爷少,而且他真的不喜欢孩子。天色已晚,你筋疲力尽,长话短说,你决定租一部你已经看过的老电影。保持它的健全和安全比你周五晚上的计划要好得多。
这个例子似乎很老了,但是在生活的很多方面,人们都在以相似的方式做决定。我可以向你保证,我爷爷想给自己买书的时候不会用谷歌。然而,对年轻人来说幸运的是,今天的决策在许多情况下更安全(我不知道我是否敢说更容易,或更快),因为在谷歌上简单的搜索会给我们几十甚至几百条评论。然而,在线零售商想让你呆在他们的网站里。他们不希望你走出他们的网页,搜索一些评论,这些评论可能会引导你去另一家零售商那里购买你正在寻找的小玩意。甚至,因为无法解决或找到您想要的东西而暂停购买。
在这种背景下,推荐系统作为一种维护网站或应用程序内部受众的方式出现了。因此,首先,重要的是要明白,它是厌倦了失去客户的商家的工具。当然,这样做的结果是,商家试图用好的推荐来让他们的客户满意,否则,这个工具根本不会起作用。所以最终,对零售商和顾客来说,这是一个双赢的局面。
通常,推荐系统会利用我们之前的活动为我们提出具体的建议。现在,如果我们是第一次访问电子商务,它不会知道我们的任何事情,那么它怎么能给出合理的建议呢?最基本的解决方案是推荐最畅销的产品,一些最新版本,如果我们谈论的是电影或书籍,可能是经典系列,或者我们甚至可以推荐能给企业带来最大利润的产品。然而,构建智能推荐系统有可能提高销售和业务绩效,因此公司正在超越这些经典技术,构建更好、更强大的推荐系统。
构建推荐系统时的挑战
当我们试图向用户推荐商品时,我们面临着一些根本性的挑战:
- 数据稀疏性:有很多产品可以推荐给很多用户,而且一个用户不太可能试用很大一部分产品。相反,许多用户可能只需要几样东西,但很多人只需要几样。
- 冷启动:我们需要能够向那些我们只有很少数据(如果有的话)的用户提供建议。
- 准确但多样的预测:我们希望给出有用的推荐,即它们符合用户的偏好,但也希望推荐对用户来说包含一些新奇的东西。
- 评估:评估很困难,可能因算法而异。
- 可扩展性:即使有数百万的用户和项目需要我们仔细分析,我们也需要能够当场给出建议。
- 用户界面:用户想知道为什么会收到特别的推荐。
- 易受攻击性:我们不希望我们的推荐系统被滥用于推广或禁止特定项目。
- 时间分辨力:品味和喜好不会随时间保持不变。
面对这一切,我们会定期谈论用户和物品。在大多数情况下,我们会为每一对可能的用户和项目预测一个特定的评级。如果用户已经给出了一些评分,我们可以将其与我们的预测进行比较:
设计我们的推荐系统
基本上有两种方法:
- 基于内容的过滤
这个替代方案推荐类似于每个特定用户过去已经喜欢的产品。就拿推荐一本书来说,如果用户喜欢《哈利·波特与魔法石》这本书,但没有给《哈利·波特与被诅咒的孩子》排名,我们可以推荐后者。
基于内容的过滤使用特定的相似性度量。相似性度量仅仅是获得用户或项目的向量之间的距离的度量。它本身是一个非常广泛的数学概念,所以我们不打算在本文中更多地讨论它(不过我可能会在将来写更多关于它的内容,所以请保持关注)。但是,例如,我们可以使用余弦相似性来度量项目向量之间的距离,按降序排列它们,然后使用以下方法之一向任何给定用户推荐项目:
- Top-n 方法:推荐前 n 部电影的地方。在这种情况下,该数字通常由企业定义
- 分级方法:设定一个阈值,将高于该阈值的所有电影推荐给用户
这种技术的最大问题是,它将总是限于用户过去购买或排序的相同类型的项目。因此,以我们的书籍为例,如果用户以前从未购买过与商业相关的书籍,它就不会推荐这一类别的书籍。
- 协同过滤
文章的这一部分主要基于来自 Analytics Vidhya 的内容,因为那里几乎所有的内容都得到了完美的解释,我不想重新发明轮子:)
说到这里,为了理解这个算法,让我们继续我们关于书籍的例子:假设我喜欢以下书籍:《盲人刺客》和《莫斯科的绅士》。我的朋友马蒂亚斯也喜欢《盲人刺客》和《莫斯科绅士》,但也喜欢《小龙虾歌唱的地方》。似乎马蒂亚斯和我有相同的兴趣。所以你可能会肯定我也喜欢《小龙虾歌唱的地方》,尽管我没有读过。这正是协同过滤背后的逻辑,唯一的例外是你可以在他们之间比较用户,或者比较项目。让我们看看每种方法是如何工作的:
- 用户-用户协同过滤
这个例子和我们刚才提到的例子一模一样。如果用户 A 喜欢或购买与用户 B 相同的物品,那么我们可以推荐用户 A 喜欢但用户 B 还不喜欢的物品。反之亦然。我们将通过使用相似性度量来比较两个用户对所有排序/购买/喜欢的项目的向量,从而找到它们之间的相似性:
预测 Pu,I 由下式给出:
其中:
- Pu,I 是一个项的预测
- Rv,I 是用户 v 对电影 I 的评价
- 苏,v 是用户之间的相似度
在我们的图书例子中,这似乎很容易,但是现在想象一下,你和你的亚马逊有成千上万的用户和评级。思考计算问题?嗯,你说得对:这种情况下这个算法很重。为了解决这个问题,公司使用邻居逻辑,只选择固定数量的用户进行预测,而不是使用所有的用户。我们可以通过几种方式做到这一点:
然而,该算法相当耗时,因为它涉及计算每个用户的相似性,然后计算每个相似性得分的预测。处理这个问题的一种方式是仅选择几个用户(邻居)而不是所有用户来进行预测,即,不是对所有相似性值进行预测,而是仅选择几个相似性值。有几种选择邻居的方法:
- 选择一个阈值相似性,并选择高于该值的所有用户
- 随机选择用户
- 安排 desc 的邻居。排序他们的相似性值并选择前 N 个用户
- 使用聚类选择邻居
在选择查看 k 个最相似用户的情况下,预测等式将被转换成如下:
这里𝑁𝑘𝑖(𝑢)表示与评价项目𝑖.的用户𝑢最相似的𝑘用户
作为一个例子,让我们以用户相似性(例如相关相似性)为例,我们将考虑用户 1 的两个最*邻居:
- 项目-项目协同过滤
在该算法中,我们计算每对项目之间的相似性:
在这种情况下,算法会再次向我推荐《小龙虾歌唱的地方》,但这只是因为马蒂亚斯、维多利亚和我,我们三个人都喜欢《盲刺客》,而《小龙虾歌唱的地方》是马蒂亚斯和维多利亚都喜欢的唯一一本书。因此,在这种情况下,我们不采用“用户-邻居”评级的加权和,而是采用“项目-邻居”评级的加权和。预测结果由下式给出:
使用协作过滤器
最后,为了应用我们刚刚看到的一些概念,我们将重新访问非常受欢迎的 movielens 数据集(在我的 GitHub 帐户中可用),应用来自 Analytics Vidhya 的技术和来自我的大会沉浸式课程的一些其他技术,使用相同的数据集:
movielens 数据集包含不同的表:
- 用户表:包含年龄、性别、职业和邮政编码等信息
- 项目表:包含电影标题、上映日期、类型、IMBd URL 等等
- 评级表:这是我们将要使用的。
让我们看看最后一个:
现在我们知道了所有这些,让我们一步一步来得到我们的预测:
首先,我们需要创建一个用户-项目矩阵,用于计算用户和项目之间的相似性:
n_users = ratings.user_id.unique().shape[0]
n_items = ratings.movie_id.unique().shape[0]
现在,我们将创建一个充满零的矩阵,然后我们将遍历评级中的每一行,用评级填充用户行和电影列:
data_matrix = np.zeros((n_users, n_items))
**for** line **in** ratings.itertuples():
data_matrix[line[1]-1, line[2]-1] = line[3]
现在,我们将计算相似度。根据定义,规则余弦相似性反映了方向的差异,而不是位置的差异。因此,它没有考虑用户评分的差异。经调整的余弦相似性通过减去平均评级来抵消这一缺点。因此,我们将创建一个函数来查找调整后的余弦相似度:
**from** **scipy** **import** spatial**def** adjusted_cos_distance_matrix(size, matrix, row_column):
distances = np.zeros((size,size))
**if** row_column == 0:
M_u = matrix.mean(axis=1)
m_sub = matrix - M_u[:,**None**]
**if** row_column == 1:
M_u = matrix.T.mean(axis=1)
m_sub = matrix.T - M_u[:,**None**]
**for** first **in** range(0,size):
**for** sec **in** range(0,size):
distance = spatial.distance.cosine(m_sub[first],m_sub[sec])
distances[first,sec] = distance
**return** distances
现在,让我们找出用户和项目的相似性:
user_similarity = adjusted_cos_distance_matrix(n_users,data_matrix,0)
item_similarity = adjusted_cos_distance_matrix(n_items,data_matrix,1)
最后,让我们做个预测:
def predict(ratings, similarity, type='user'):
if type == 'user':
mean_user_rating = ratings.mean(axis=1)
ratings_diff = (ratings - mean_user_rating[:, np.newaxis])
pred = mean_user_rating[:, np.newaxis] + similarity.dot(ratings_diff) / np.array([np.abs(similarity).sum(axis=1)]).T
elif type == 'item':
pred = ratings.dot(similarity) / np.array([np.abs(similarity).sum(axis=1)])
return pred
如您所见,我们使用了 np.newaxis,因此 mean_user_rating 与 ratings 具有相同的格式。点击了解更多关于 np.newaxis 的信息。
user_prediction = predict(data_matrix, user_similarity, type='user')
item_prediction = predict(data_matrix, item_similarity, type='item')
让我们检查一下预测矩阵的形状:
最后,除了创建推荐系统之外,让我们使用之前创建的预测创建一个函数。它会找到用户没有评级的电影(因此没有看过),并根据我们的预测给我们排名前 5 的电影。
**def** finding_movies_for_user(user, ratings, preds):
recos = {'movie_id': [],'rating': []}
user_array = preds[user]
orig_rat = ratings[user]
**for** each **in** range(0,len(orig_rat)):
**if** orig_rat[each] == 0:
recos['movie_id'].append(each+1)
recos['rating'].append(user_array[each])
recos_df = pd.DataFrame(recos)
final_recos_df = pd.merge(recos_df, items[['movie_id','movie_title']],
how='left', on='movie_id')
**return** final_recos_df.sort_values(by='rating',ascending=**False**).head(5)
让我们用一个随机用户来测试一下。
哇,太神奇了!我们已经设法为任何给定的用户获得了我们的第一批推荐。当然,推荐系统是一个非常广泛的话题,我们还可以谈论更多:相似性度量、性能评估、更复杂的获取推荐的技术等等!我可能会在未来写更多关于这方面的内容,但同时,请随意查看我的 GitHub 账户,那里有一些不错的项目,包括带有 movielens 数据集的完整推荐系统项目:)
顺便说一句,如果你对推荐系统感兴趣,可以看看我上一篇关于使用奇异值分解改进你的推荐系统的文章,以及我的作者简介中的更多内容。如果你喜欢这篇文章,别忘了关注我,如果你想直接在你的电子邮件上收到我的最新文章,只需订阅我的时事通讯:)
干杯。
写委婉介绍的委婉介绍
原文:https://towardsdatascience.com/a-gentle-introduction-to-writing-gentle-introductions-d87c69268362?source=collection_archive---------29-----------------------
Source
如果你给你的文章起了别的标题,人们怎么知道你写的是关于数学的呢?
你是谁?你,对一些听起来很可怕的事情很了解,却想让人们知道这个事情!你的动机当然不是想让人们知道你知道这件事——当然不是。你的动机肯定不是展示那些软技能,那些你在 LinkedIn 网络上认可的沟通技能。不。你希望世界有一个容易获得的资源来学*中心极限定理,或者稀疏矩阵,或者神经网络,或者神经网络,或者神经网络,甚至神经网络!
Source
你必须强调这个概念是如何可接*的,不要介意这个概念的完整推导是某人花了五年时间写博士论文的主题。不,作为一个受人尊敬的媒介传播者,你可以将这个想法提炼为一段估计为“6 分钟阅读”的文字。亲爱的作家,不要担心,如果你的主题对于一篇六分钟的中型文章来说确实太复杂了。这就是范围和背景假设的辉煌写作手段发挥作用的地方。例如,如果你试图通过梯度下降来解释反向传播,这是一个完全公平的假设,即阅读你的帖子的机器学*爱好者具有足够好的多变量微积分背景,能够通过将链规则应用于你的网络的权重、偏差和激活的梯度来理解你在做什么,因为它们与你的通用示例损失函数相关。如果他们没有这方面的背景,那么这就“超出了”你的文章的范围——不需要再想了!
哦,有帮助的、知识渊博的作家,不要担心在这一点上你的数学密集、充满隐喻的文章不再是“温和的介绍”。更改你的标题不符合任何人的利益,所以你对支持向量机松弛变量的温和介绍将经受住中等出版物编辑的严格编辑。想想看:你的标题对技术和非技术读者有广泛的吸引力,你的材料符合出版物的使命,增加的流量同样遵循出版物的使命。“流量增加了!”你暗自思忖,对宣传你的作品的潜在点击诱饵的指控感到震惊,“这个骗子如何证明这是真正的点击诱饵?”亲爱的有用的作者,使用下面关于机器学*和数据科学的中型文章的调查,我们可以看到明确的证据,一旦短语“温和的介绍”出现在你的标题中,鼓掌的中位数和平均数都会飙升。
Some Examination of Clap Totals in “Gentle Introductions” vs All Other Medium Data Science Posts DATA
记住所有这些,不要考虑改变你的标题,当然不要偏离成功的媒体文章公式,无论你做什么,不要试图将你自己从众多知识渊博的数据科学作家中区分出来,旨在帮助所有“有抱负的数据科学家”。你的工作太重要了,以前肯定没有人写过。
可视化的另一个阶段:对 Dash 做出反应
原文:https://towardsdatascience.com/a-gentle-invitation-to-interactive-visualization-with-dash-a200427ccce9?source=collection_archive---------7-----------------------
一个温柔的邀请
Dash 是一个开源的 python 库,它使我们能够用 Plotly 创建 web 应用程序。使用简单的反应式装饰器,如下拉菜单、滑动条和降价文本数据,可以很容易地构建交互式可视化。我们甚至可以使用回调函数根据输入数据更新图表,所有这些功能都可以直接使用,不需要 Javascript 或 HTML。Plotly 是一个非常强大的工具,它使我们能够以一种方便的方式制作一个信息丰富且有效的情节,Dash 可以被视为展示令人敬畏的可视化的舞台。
今天我将向你展示如何用 Plotly 创建一个仪表板。我们将制作一个时间序列线图,并添加一个下拉菜单和一个与该图交互的滑动条。有关于如何使用这个库的很好的文档,但是我发现一开始可能很难阅读示例代码并使用它们。因此,这可能是一个善良的桥梁,让你了解如何使用破折号与 Plotly。
装置
要构建一个仪表板,我们需要安装如下一些包。
pip install plotly==2.5.1
pip install dash==0.21.0
pip install dash-core-components==0.22.1
pip install dash-html-components==0.10.0
pip install dash-renderer==0.12.1
正如我上面所说,dash-core-components
不仅允许我们构建图形,还允许我们构建下拉列表和文本框,这样我们就可以相应地更新组件。dash-html-components
使我们能够在 Python 中使用 HTML & CSS。它帮助我们在仪表板上放置 HTML 组件,如 Div、H1 和 H2。
如果这是你第一次使用破折号和 HTML 语法,它可能有点复杂和难以阅读。因此,我建议您将以下脚本作为 Dash 的基本指南。从现在开始,我们要做的是一步一步地填写这个。
首先,我们导入库。您可以根据需要添加其他库。然后我们通过调用 Dash 类来初始化 Dash。这就像在我们的桌子上放一块空白的白板,我们所做的就是在这块板上构建更多的应用程序。
**# Step 1\. Launch the application**
app = dash.Dash()**# Step 2\. Import the dataset**
df = pd.read_csv('finance-charts-apple.csv')
现在让我们从熊猫的 CSV 文件中提取一些材料。我们要使用的数据集是苹果公司的股票价格数据,这里的。
仪表板上的简单散点图
关于 Plotly 本身的细节我就不多说了,但是如果有必要的话你可以从这个视频中找到一个关于 Plotly 的很好的教程。在这一系列的视频中,你还可以学*如何制作 3D 绘图或 Choropleth 地图。这里我们将绘制一个显示股票价格波动的线图。
******# Step 3\. Create a plotly figure**
trace_1 = go.Scatter(x = st.Date, y = st['AAPL.High'],
name = 'AAPL HIGH',
line = dict(width = 2,
color = 'rgb(229, 151, 50)'))layout = go.Layout(title = 'Time Series Plot',
hovermode = 'closest')fig = go.Figure(data = [trace_1], layout = layout)****
现在,该是dash-html-components
出场的时候了。我们先放一个除法,然后把图形放进去。id
正在给这个组件命名,这样我们就可以用它的名字来称呼它。以后你就明白这是干什么用的了。然后,我们在步骤 6 中创建一个运行的服务器。如果我们设置调试模式等于真,我们可以很容易地改变和更新应用程序,而服务器正在运行。
******# Step 4\. Create a Dash layout**
app.layout = html.Div([
** dcc.Graph(id = 'plot', figure = fig)**
])**# Step 6\. Add the server clause**
if __name__ == '__main__':
app.run_server(debug = True)****
我们用 app.py 的名字保存这个脚本,在终端上导入(或者 anaconda 提示)。请注意,工作目录应该与您保存文件的位置相同。
**C:\Users\jjone\Dash> **python app.py****
如果没有打字错误或语法错误,您将看到本地主机地址。你可以复制并粘贴它,也可以在一个新的网页标签上输入 localhost:8050 。
添加页眉和段落
我们也可以有额外的组件,如把文本数据就像 HTML。你可以在 这里找到 有哪些元素。让我们在页面上放一个简单的标题和一段文字。
****# Step 4\. Create a Dash layout**
app.layout = html.Div([
** # adding a header and a paragraph
html.Div([
html.H1("This is my first dashboard"),
html.P("Learning Dash is so interesting!!")
],
** style = {'padding' : '50px' ,
'backgroundColor' : '#3aaab2'}),# adding a plot
dcc.Graph(id = 'plot', figure = fig)
])**
在图表的顶部,我将再添加一个部分,并在其中添加一个标题和一个段落。我们有两个主要组件,html.Div
里面的html.Div
和dcc.Graph.
,还有两个附加组件,头(html.H1
)和段(html.P
)。我们可以用style
属性改变组件的边距或背景色。它应该以支持 CSS 属性的字典格式来指定。
请特别注意括号的开始和结束位置。理解每个部分的段落范围是很重要的。由于有太多的括号和方括号,一开始可能会令人困惑。而且很容易犯语法错误。
将步骤 4 中的代码放入我们的模板中,看看结果。如果服务器没有关闭,我们可以通过按 F5 来检查结果。
现在,我希望您了解什么是 dash 组件和 HTML 组件。如何将多个组件放在一起,以及如何将它们放在一起。
下拉式
这次让我们试着在仪表板上做一个下拉菜单。我们要做另一个图,根据给定的选项改变它的 y 轴。通过 仪表板组件 的文档,我们可以把Dropdown
整理如下。
如您所见,这些选项应该是字典格式的。在我们的例子中,选项将是只有连续变量的列,从第 2 列到第 10 列。有了列表理解,我们可以只用一行就做出选项字典。
**features = st.columns[1:-1]
opts = [{'label' : i, 'value' : i} for i in features]**
现在,我们将下拉组件放在绘图的底部,而不是 HTML 组件。先看一下粗体字,因为其他的只是为了修饰两大应用。value
是下拉列表的默认值。
****# Step 4\. Create a Dash layout**
app.layout = html.Div([
# adding a plot
dcc.Graph(id = 'plot', figure = fig), **# dropdown**
**html.P([
html.Label("Choose a feature"),
dcc.Dropdown(id = 'opt',
options = opts,
value = opts[0])
],** style = {'width': '400px',
'fontSize' : '20px',
'padding-left' : '100px',
'display': 'inline-block'}**)**
])**
正如我们之前所做的,我们可以在模板的第 4 步替换这段代码,并检查结果。
使用回调连接到图形
为了根据下拉列表的选择更新图表,我们需要在输入数据(下拉列表)和输出数据(图表)之间建立一个连接。这将通过在步骤 5 中添加一个回调函数来完成。
****# Step 5\. Add callback functions**
[**@app**](http://twitter.com/app)**.callback(**Output('plot', 'figure'),
[Input('opt', 'value')]**)****
你记得我们给每个组件赋予了什么id
吗? 剧情 和 opt。 因此我们可以如上图用它们的名字来称呼它们。我们从名为 opt 的选项中获取输入数据,并将输出给名为 plot 的线图。
****def** update_figure(**X**):
trace_2 = go.Scatter(x = st.Date, **y = st[X],**
** name = X,**
line = dict(width = 2,
color = 'rgb(106, 181, 135)'))
fig = go.Figure(data = **[trace_1, trace_2]**, layout = layout)
**return** fig**
因此,我们获取输入数据,然后通过创建更新函数返回我们想要的输出。这里我们的输入数据是什么?这是从下拉列表中选择的特征变量的名称,我们将它作为第二个线图的 y 轴。由于trace_1
没有什么可改变的,我们可以简单地将trace_2
添加到数据表中。现在,如果我们将这段代码放到第 5 步,并重新运行 app.py ,结果将如下所示。
在我们进入下一部分之前,我想简单谈一下回调。因为这是编写任何应用程序时最常用的函数之一。简单来说, 一个回调是一个在得到真正的执行命令之后再执行的函数,通常是为了更新。回调函数在得到命令后不能正常工作。这些人都是那种。它们将在其他命令行被执行后执行它们的工作,我们 调用 它们 返回 再次执行真正的命令。****
看看我们的update_figure()
是怎么运作的。这个函数不是在我们导入这个应用程序之后,而是当我们通过“回调”给它实际的输入信号时,才开始工作这就是回调函数。你在不理解的情况下使用它是完全没问题的,但是我希望你在这里得到粗略的想法。你还可以从 这篇文章 中找到更多细节。
范围滑块
最后,让我们尝试一个范围滑块。我们将在图中添加一个年范围滑块,它非常类似于下拉菜单。让我们先查看一下 dash 组件的文档。
我想这时候你很容易就明白了。这里的重点是如何做一个标记字典。由于日期周期从(2015 年 2 月 17 日 ) 开始到(2017 年 2 月 17 日),我想在周期之间添加 7 个标记,如下所示。**
****st['Date'] = pd.to_datetime(st.Date)
dates = ['2015-02-17', '2015-05-17', '2015-08-17', '2015-11-17',
'2016-02-17', '2016-05-17', '2016-08-17', '2016-11-17',
'2017-02-17']date_mark = {i : dates[i] for i in range(0, 9)}****
现在,我们可以简单地将范围滑块放在下拉位置。这次我把它命名为 滑块 。min
和max
是滑块的最小值和最大值,value
是滑块的默认设置。同样,所有其他部分都在设计 CSS 样式的 HTML 组件。
******# Step 4\. Create a Dash layout**
app.layout = html.Div([
# adding a plot
dcc.Graph(id = 'plot', figure = fig), **# range slider
html.P([
html.Label("Time Period"),
dcc.RangeSlider(id = 'slider',
marks = date_mark,
min = 0,
max = 8,
value = [3, 4])
],** style = {'width' : '80%',
'fontSize' : '20px',
'padding-left' : '100px',
'display': 'inline-block'}**)**
])****
做好滑块后,下一步会做什么?把它和剧情联系起来!我们将再次从 滑块 获取输入数据,并将输出返回到 图 。但是这一次,这里有个小技巧。您是否注意到滑块的默认值是一个包含两个值的列表?请再次检查上面的代码框。**value = [3, 4]**
与下拉组件不同,范围滑块在一个列表中接受两个值。因此,当我们从滑块中获取输入数据时,会有两个值,即起始值和结束值(**X[0]**
、**X[1]**
)
******# Step 5\. Add callback functions**
[@app](http://twitter.com/app).callback(Output('plot', 'figure'),
[Input('slider', 'value')])
**def** update_figure**(X):**
**st2 = st[(st.Date > dates[X[0]]) & (st.Date < dates[X[1]])]**
trace_1 = go.Scatter(x = st2.Date, y = st2['AAPL.High'],
name = 'AAPL HIGH',
line = dict(width = 2,
color = 'rgb(229, 151, 50)'))
fig = go.Figure(data = [trace_1], layout = layout)
** return** fig****
现在我们将过滤数据,并用给定的周期更新图形。如果你再次重新加载网页,你会看到与我相同的结果。
把这些都集中起来!
我想到目前为止我们已经谈了很多了。从放图到添加回调。现在我们为什么不把它们都放在一起?我建议你一步一步地阅读下面的脚本。您可以在第 4 步中组合图形、下拉菜单和滑块的所有组件,就像替换和更改模块一样。
你准备好看看我们的第一个仪表板是什么样子了吗?😃😃🙌🙌嘣!!
干得好!你喜欢制作仪表板吗?我希望现在您能够轻松阅读和理解其他 Dash 代码示例。Dash 提供了这样一个不错的指南 所以你可以随意探索自己的网站。你也可以通过 Plotly 查看 Dash 中的其他内容。
****** [## 🌟引入破折号🌟
用纯 Python 创建反应式 Web 应用程序
medium.com](https://medium.com/@plotlygraphs/introducing-dash-5ecf7191b503)
部署
到目前为止,我们的应用程序本地托管在您的机器上。为了让其他人也能使用它,我们需要将它部署在 web 上。有两个选择可以选择,App 授权和部署到 Heroku。第一种要求我们安装[dash-auth](https://github.com/plotly/dash-auth)
包,有两种不同类型的认证,HTTP Basic Auth 或 Plotly OAuth。可以按照 这个教程 。
另一种方式是通过使用 Heroku、AWS、Google 云平台等托管平台。Heroku 是最简单的部署方式,你可以按照这个教程。其他平台和 Heroku 一样。
除了下拉菜单,我们还可以添加其他组件,如文本区或上传数据。我建议你去了解一下有什么样的仪表板部件。您还可以添加任意数量的 HTML 组件,并使用 CSS 属性以更奇特的方式设计您的电路板。如果你需要学*一些 HTML & CSS 的基础知识,可以从 这个视频 中找到很棒的教程。
感谢您的阅读,希望您对这篇文章感兴趣。如果有什么需要改正的地方,请和我们分享你的见解。我总是乐于交谈,所以请在下面留下评论,分享你的想法。我还在 LinkedIn 上分享有趣和有用的资源,所以请随时关注并联系我。下次我会带着另一个有趣的故事回来的!******
竞争数据科学一瞥:计算机视觉的最佳实践
原文:https://towardsdatascience.com/a-glance-into-competitive-data-science-the-best-practices-for-computer-vision-2c77c5d98d19?source=collection_archive---------16-----------------------
几种技术如何显著提高计算机视觉模型的性能…
简介
S 由于 2019 年 Freesound Audio Tagging 比赛即将结束,我决定写一篇关于构建健壮的计算机视觉模型的最佳实践和技术的文章,这是我在第一次研究比赛中学到的。此外,这是我把我的想法写在纸上的一种方式,以便对我所使用的技术有一个结构化和清晰的概述:那些工作良好的技术,以及那些没有在我的测试分数中产生显著提高的技术。
作为 Fast.ai 课程的学生,我仍然处于学*旅程的最开始,因此一些评论或技术对于最有经验的人来说可能是显而易见的。
像往常一样,我强烈鼓励你纠正我,如果你不明白或者不清楚,可以问我关于某一点的精确信息,并在评论区添加一些评论!
我从这场比赛中得到的最重要的教训是,建立稳健的模型是一个经验过程。竞争有助于培养直觉,知道什么可行,什么不可行。
给你一点背景,比赛是关于标记(分类)声音(猫,瀑布,乐器…)。我们得到了两个数据集:一个是有清晰可闻声音的精选数据集(4970 个条目),另一个是有声音和一些背景噪音的嘈杂数据集(20000 多个条目)。请注意,每个数据条目都有多个标签。两个数据集都被标记了。竞赛的主要挑战(由绝大多数参与者确定)是正确使用有噪声的数据集来提高精选数据的性能。
我们根据一个定制的指标进行评估:标签加权的标签排名平均精度也缩写为 lwlrap 。为了给出一个尺度,前 1%的人获得了 0.76 的 lwlrap 分数,而铜牌(大约前 12%)以 0.695 或更高的分数被授予。我在第一阶段的最终分数是 0.686,这使我进入了前 15%。
快速傅立叶变换和 melspectrograms:如何将声音输入 CNN?
从文章开始,你可能会觉得我同时谈论计算机视觉和声音很奇怪。事实上,声音是由多个样本组成的基于时间的信号。起初,我们可能认为可以通过应用 1D 卷积将声音输入到 CNN 或 LSTM 的模型中。然而,这两种技术都没有产生令人信服的结果,可能是由于将原始信号输入到模型中导致了信息的丢失。馈送原始信号会导致信息(即频率、相位、幅度)的显著损失。经过一些实验,两个模型都没有产生超过 0.5 的 lwlrap。相当失望…
作为音频分类的经验法则,我们通常将声音转换成更全面的 2D 表示(图像),然后输入 CNN。这种表示可以是 MFCC、色度、CQT 变换,但通常是梅尔频谱图。
Mel-spectogram of a signal plotted with Matplotlib
为了理解 mel 谱图是如何产生的,我们首先需要理解傅立叶变换对信号的影响。快速傅立叶变换(具有比原始版本 o(n2) 更低复杂度 o(nlogn) 的修改算法)将声音信号从其原始时域转换成频域中的表示。
然后我们应用一系列变换,最终得到 mel 谱图表示。
为了执行这一系列的计算,你可以直接使用 librosa 库,该库具有各种功能来执行音频特征分析。
附加阅读:
- 如何在 Python 中把声音转换成图像(Daisukelab 的一个内核):https://www . ka ggle . com/Daisukelab/creating-fat 2019-预处理-数据
- 一套用于音频特征分析的笔记本:https://musicinformationretrieval.com/
- Python 中的 librosa 库介绍:https://towardsdatascience . com/audio-classification-using-fastai-and-on-the-fly-frequency-transforms-4 dbe1 b 540 f 89
Mixup:在计算机视觉中实现艺术效果的必备工具
简单地说,Mixup 是一种数据扩充技术,它根据两个现有数据条目之间的线性关系创建新的数据条目。我们可以用这个公式来总结。γ是代表图像的张量,而λ是权重。
相同的变换应用于目标:
它只不过是两个现有数据样本的加权平均值。例如,我们可以选择λ = 0.7。如果γ1 代表狗,γ2 代表猫,new 将代表介于狗和猫之间的东西,比猫离狗更*。如果你查看与 new 相关的图像,它可能对你没有太大意义,但对计算机来说,它显然看到了一只狗,因此增加了狗的图像数据集。
Representation of a new data sample using Mixup (credits: Fast.ai)
如您所见,通过从其他现有数据创建新数据,它可以作为一种强大的数据扩充技术。当你不得不处理阶级不平衡时,这是特别有用的。在这次比赛中就是这种情况(有些品牌出现的次数很少,而其他品牌出现的次数很多)。这个技巧帮助我打破了 0.6 lwlrap 的障碍,在排行榜上从 0.57 上升到 0.65(结合下面列出的其他技巧)。
附加阅读:
- Mixup 原创研究论文:【https://arxiv.org/abs/1710.09412
- 关于 Mixup 的 Fast.ai 文档:【https://docs.fast.ai/callbacks.mixup.html
训练时间增加(TTA):在排行榜中排名
训练时间增强(TTA)是一种在推理过程中使用的数据增强技术。TTA 的结果是通过计算标准预测和应用数据扩充技术后对数据集所做预测的加权平均值而获得的。不出所料,这个等式看起来与 Mixup 非常相似:
默认情况下,在 fast.ai 中,beta 系数设置为 0.4。
注意,在 Fast.ai 中,TTA 计算对数概率(因此是负数)。要从对数概率转换到“标准”概率(介于 0 和 1 之间),只需计算概率的指数。
您可能面临的唯一问题是模型计算预测需要多长时间。特别是如果您的模型的执行有严格的时间限制,TTA 可能不是一个好的选择。
至于比赛,它让我从排行榜上的 0.57 跳到了 0.65。
迁移、半监督学*和伪标记
迁移学*包括用数据集预先训练你的模型,然后用最接*你想要预测的数据集训练它。这是一种允许更快训练和更稳定地收敛到损失最优值的技术。无论是计算机视觉还是基于 ULMFiT 模型和 BERT 的 NLP,它现在都是业界的标准。
对于这场比赛,我选择首先在嘈杂的数据集上预先训练我的模型,最终在精选的数据集上训练我的模型。在我的本地机器上,我的 lwlrap 从 0.81 跳到 0.83。让我们回想一下,比赛不允许预先训练的模型。
我尝试的第二种技术是半监督学*。如果您有大量未标记的数据,这将非常有用。它有助于模型映射数据分布,并允许更快的收敛。
你最好花一周时间来标记额外的数据,而不是试图创建一个模型来完美地利用未标记的数据。
我选择了一种特殊类型的半监督学*:伪标记噪声数据。在这个比赛中,我们有大量的噪音数据。我没有使用现有的标签,而是在精选的数据上训练了一个模型,然后使用这个模型来标记我的噪音数据。最终,通过将筛选的数据与新标记的噪声数据相结合,我重新训练了我的模型。尽管由于精确的数据分布和有噪声的数据分布之间的太大差异,它没有显著地提高性能,但是在集合模型中,性能提高了。
我可能会总结说,你最好花一周的时间来标记额外的数据,而不是试图创建一个模型来完美地利用未标记的数据。当你有大量的备用数据时,半监督学*技术通常是合适的。
补充阅读:
- 伪标签综合讲解:https://www . analyticsvidhya . com/blog/2017/09/pseudo-labeling-semi-supervised-learning-technique/
K-Fold 交叉验证和 bootstrap 聚集:在推理过程中获得更稳定的结果
由于 K-Fold CV 在 fast.ai 课程中并没有特别突出,虽然是业界标配,但我并没有真正用过。让我快速回忆一下 K 折叠验证的定义:这是一种技术,通过这种技术,数据集被分成 K 个折叠,模型在 K-1 个折叠上被训练,并在剩余的折叠上被验证。显然,由于每个模型都有不同的验证集,所以会生成 K 个模型。这导致更准确和一致的性能评估。
A 5-fold cross-validation scheme
但是除了作为一种验证技术之外,K-Fold CV 还可以在一个集合模型中使用(对它的花哨说法是 bootstrap aggregating )。这个词隐藏了相当直接和简单的技术,例如,你计算你的 K 倍所有预测的平均值。这种集成技术通常会产生更好的性能,因为整个模型的方差大大减少了。
集合技术:进入前 5%的关键
我的上一段介绍了竞争数据科学的一个关键概念,广义地说是创建更精确的模型的概念:集成的概念。简而言之,集成是一种将几个模型放在一起以获得预测稳定性和精确度的技术。
为了实现一个高性能的集合模型,你需要检查所有模型之间的相关性。相关性越低越好。为此,您需要计算皮尔逊相关系数:
其中 σ 是统计数列的标准差, cov(X,Y) 是统计数列 X 和 Y 的协方差。
通过结合一个简单的基线模型和一个迁移学*模型以及一个伪标签模型,我获得了排行榜上的最高分:0.686。
说清楚一点,统计数列 X 和 Y 是你的模型的预测。对于您创建的每个模型,您可以计算彼此之间的皮尔逊相关系数,并丢弃高度相关的模型。
在这个竞赛中,X 和 Y 将是包含属于每个数据样本的 80 个类别之一的概率的矩阵。
至于比赛,组合技术显然给了我接*铜牌的机会。通过结合一个简单的基线模型和一个迁移学*模型以及一个伪标签模型,我获得了排行榜上的最高分:0.686。
补充阅读:
- 集成技术综合指南,从平均到叠加概括:https://mlwave.com/kaggle-ensembling-guide/
从这里去哪里?
现在是时候对我的表现采取批评的观点了。因为我没有赢得奖牌,所以有很多事情我可以改进。我会强迫自己去思考那些我本可以用不同的方式去做的事情,或者除了我已经做的事情之外。
了解你的数据
可能我最严重的错误在于太急于建立一个模型,而不是首先试图理解数据分布和噪声数据集中的噪声种类。它会让我更好地理解预测标签的难度,并阅读更多相关的研究论文,以消除或减弱轨道上的噪声。
阅读研究论文
这是一个提醒,而不是一个真正的批评家。我发现资本阅读研究论文是如何应用技术,导致最先进的结果。随着人工智能的民主化,得益于 fast.ai 课程等 MOOC(再次感谢杰瑞米·霍华德、雷切尔·托马斯和项目背后的出色团队),越来越多的人可以获得强大的机器学*工具,使他们更接*最先进的结果。阅读研究论文并能够实现所描述的一些技术是一种无价的额外津贴,因为它使你从竞争中脱颖而出。很少有人愿意花时间去阅读它,更少有人去实现一种技术。
我为自己设定的一个主要目标是对 Fast.ai 及其底层框架 PyTorch 足够熟悉,以实现并将我自己的代码片段集成到库中。例如,我偶然发现了这篇研究论文https://arxiv.org/abs/1905.02249,它看起来非常有效,因为据说 MixMatch 可以将错误率降低 4 倍。然而,经过多次尝试,我还不能实现它。
使用更多数据通道?
我们之前已经讨论过 mel 光谱图以及它们是如何产生的。但是可以创建其他音频表示,即色度、梅尔频率倒谱系数(MFCC)、常数 Q 变换等等。所有这些表示强调音频信号的不同方面:一个可能探索振幅,而另一个可能探索相位或频率。例如,我无法建立一个足够准确的模型来从阶段中学*。我坚信这是比赛的关键,因为它给光谱模型增加了更多的信息。
更复杂的集成技术:加权平均、堆叠概括?
当使用集合技术时,我没有以复杂的方式组合我的模型。我只是计算了我所有预测的平均值。我本可以通过选择适当的权重来微调我的模型,从而为我的预测创建一个加权平均值。
我甚至可以尝试使用一个神经网络,它将来自不同模型的所有预测作为输入,并试图检测不同预测之间的非线性模式。一个挑战是数据限制。我们在精选的数据集中只有 4970 个数据样本,删除 1000 个数据样本会适得其反,因为 4970 已经是一个很低的数字了。
我没有尝试在嘈杂的数据集上训练我的模型,因为这个分布离测试集太远了。
结论
因为文章已经很长了,所以我的结论会很简短(如果你还在的话,恭喜你,谢谢你)。我从这场比赛中得到的最重要的教训是,建立稳健的模型是一个经验过程。你尝试,你失败,你思考,你改正。为了变得擅长,你必须尝试很多事情。竞争有助于培养直觉,知道什么可行,什么不可行。
我希望你喜欢这篇文章。同样,如果我在某些方面有错,请不要犹豫地纠正我,或者在评论区分享你对比赛的想法。
看看我的另一篇博文:https://medium . com/@ pabtennis/how-to-create-a-neural-network-from-scratch-in-python-math-code-FD 874168 e955
https://www.kaggle.com/rftexas
一瞥新披露的亚马逊欺诈探测器
原文:https://towardsdatascience.com/a-glimpse-of-newly-revealed-amazon-fraud-detector-c8c989501a5d?source=collection_archive---------19-----------------------
几天前,在亚马逊网络服务(AWS) re:Invent 2019 上,亚马逊宣布了其检测交易异常的完全托管服务亚马逊欺诈检测器(Amazon Fraud Detector)。这项服务目前处于预览阶段,当我的预览应用程序被批准后,我迫不及待地尝试了一些欺诈检测样本。
亚马逊欺诈检测器最棒的一点是,你不需要任何人工智能专业知识来构建欺诈检测模型。只需获取一些历史数据,亚马逊欺诈检测器就会使用这些数据来自动训练、测试和部署定制的欺诈检测模型。
要开始,我总是推荐官方文档,这是一个很好的起点。您可以通过本文末尾提供的参考链接来了解更多关于 Amazon Fraud Detector 的信息。
对于那些仍在急切等待预览的人来说,本文将简要介绍该服务,并介绍构建欺诈检测模型和运行欺诈预测测试的步骤。
我使用了一些从 https://mockaroo.com/生成的假数据,这是一个很好的生成真实数据的工具。还可以使用开源的 faker . js(https://github.com/marak/Faker.js/)库,在 Node.js 和浏览器中生成海量的虚假数据。
准备好数据集后,将 csv 文件上传到 S3 存储桶,控制台将为您提供创建或选择现有 IAM 角色来访问培训数据集的选项。
Defining data location
亚马逊欺诈检测器模型模板提供了三种模板选项,其中“在线欺诈洞察”模型目前可用。其他两个模型模板,即用于识别受损账户的账户接管和用于捕获欺诈交易的交易欺诈,正在未来发布的路线图中。
在线欺诈洞察模型模板需要下图所示的输入来创建模型。我们需要确保我们的数据集包括电子邮件、时间戳、IP 和欺诈标签字段。
下一步,我们需要配置我们的模型,以确保输入正确地映射到选定的变量。
第三步,也是最后一步,允许我们查看模型细节,最后单击以创建和训练我们的模型。该模型在部署之前需要一些时间来训练。在这种情况下,为具有 20,000 行的数据集定型大约需要 20 分钟。
一旦培训成功,我们就可以部署这一特定版本的模型来配合我们的检测机使用。在下图中,我们看到了模型性能和一个表格表示,以帮助我们确定在编写评估事件的规则时应该使用哪个模型阈值。
一旦我们成功部署了欺诈检测模型,我们将在本次动手演示的第二部分创建一个检测器。创建检测器有五个简单的步骤,首先是为我们的检测器定义一个名称。
在第二步,添加我们在本演示的第一部分中创建的模型。
在此之后,我们可以添加规则来解释我们的亚马逊欺诈检测器模型的分数。这里,我们将需要提供规则表达式和一个结果,该结果将是欺诈预测的结果,如果在评估期间规则匹配,则返回该结果。
我们可以在下图中看到一个样本规则表达式。
一旦我们创建了规则,我们就可以定义执行规则的顺序,这些规则将影响最终的欺诈预测结果。在这种情况下,我们将“高欺诈风险”规则移到了第一个位置。
在最后一步,我们可以查看规则,最后,继续创建检测器。
一旦我们的检测器被创建,我们可以使用一些样本事件数据来测试我们的检测器的逻辑。正如我们在下图中看到的,测试的结果是“审查”,模型得分为 688。因此,我们的模型现在已经准备好了,我们可以将其用于实时欺诈检测。
结论
凭借 AWS 和 Amazon.com 20 年的欺诈检测专业知识,在数毫秒内自动识别潜在的欺诈活动,亚马逊欺诈检测器抽象出了复杂的机器学*,以提供一个简单易用的界面,供每个人使用。目前,虽然此服务仅限于少数模型模板,并且仅在 AWS 美国东部(N. Virginia)地区提供,但我们可以预计,随着欺诈管理需求的不断增长,此服务将会增长。
参考
https://aws.amazon.com/fraud-detector/
https://docs . AWS . Amazon . com/fraud detector/latest/ug/what-is-fraud detector . html
张量流一瞥
原文:https://towardsdatascience.com/a-glimpse-of-tensorflow-bd9c6c06ab73?source=collection_archive---------18-----------------------
TensorFlow 是 Google 的一个流行的开源软件库。最初它是由谷歌大脑团队开发的,供谷歌内部使用。随着 AI 研究社区变得越来越协作,TensorFlow 在 Apache 2.0 开源许可下发布。
张量流的详细研究可能需要几个月的时间。但是对它的力量的一瞥提供了一个很好的动力去钻研它。考虑到这一点,这篇博客着眼于分类模型的实现。
分类是我们在人工智能工作中经常遇到的问题之一。通常,我们有一组输入,这些输入必须分类到不同的类别中。我们可以使用 TensorFlow 为这项任务训练一个模型。下面,我们将逐步介绍一个这样的实现的每个步骤。
导入模块
重要的事情先来!TensorFlow 是一个外部库,需要导入到脚本中,我们才能使用它。
除了 TensorFlow,我们通常还会导入一些其他的库,让我们的生活更加简单。Keras 是 TensorFlow 的一部分。它帮助我们非常容易地开发高阶模型。我们可以单独使用 TensorFlow 来创建模型。然而,Keras 简化了我们的工作。
NumPy 是任何机器学*任务中的默认导入。没有它我们无法生存。几乎所有的数据操作都需要 NumPy。
另一个重要的模块是 matplotlib。这是非常重要的,我们可视化的可用数据,以获得隐藏在其中的感觉。任何数量的算法分析都不能给我们仅仅通过图形形式查看数据所得到的东西。
TensorFlow 在版本上经历了一些变化。概念没有变,但是一些方法变了。检查我们使用的版本是一个很好的做法。如果我们有问题,我们可以查看特定版本的帮助。由于版本冲突,许多开发人员都面临这个问题,所以在论坛上搜索特定版本的问题要简单得多。
以下代码基于版本 1.12.0
MNIST 数据集
为了分享基本思想的简要介绍,我们可以研究一个简单问题的实现。MINST(改进的国家标准和技术研究所)给出了从 0 到 9 的手写数字的良好数据集。我们可以利用这一点来训练神经网络,并建立一个可以读取和解码手写数字的模型。
这个问题通常被称为深度学*的“Hello World”。当然,我们需要更多来开发“真正的”应用程序。这很好的给你介绍了题目。当然,TensorFlow 还有更多的功能。如果你对详细的研究感兴趣,你可以参加在线课程。
加载数据
第一步是加载可用数据。TensorFlow 为我们提供了一套很好的测试数据集,可以用来学*和测试。MINST 数据集也在这些数据库中提供。因此,在这种情况下,获取训练和测试数据的工作非常简单。在现实生活问题中,积累、清理和加载这样的数据是工作的主要部分。这里我们只用一行代码就完成了。
这给了我们四个张量——train _ images、train_labels、test_images 和 test_labels。load_data()方法本身负责将可用数据分成训练集和测试集。在现实生活问题中,我们必须自己解决这个问题。但是,对于示例代码,我们可以使用 TensorFlow 数据集的可用方法。
检查数据
作为一种最佳实践,应该总是看一眼可用的数据。
我们知道我们正在解决一个图像分类问题。所以让我们试着看看这些图像是什么样子的。
在这个阶段,我们可以做很多事情。但是对于像这样已经清理过的数据来说,这没有什么意义。
数据净化
下一步是改变可用数据,使其更适合训练模型。
图像数据自然是二维的。这对于查看图形来说可能非常好。但是,为了训练神经网络,我们需要一维记录。这需要“扁平化”数据。Keras 为我们提供了简化模型中数据的简单方法。但是对于一般的预处理,最好是立即将其展平。TensorFlow 也提供了这一功能。
我们的标签是用数字 0-9 来表示的。但是,作为神经网络的输出,这些值没有数字序列。也就是 1 小于 9。但是当我们阅读图像时,这种关系一点也不重要。这些输出之间的数字关系只是偶然的。对于应用程序,它们只是 10 个不同的标签。它们是分类输出。
为此,我们需要将这些标签映射到 10 个不同的由 1 和 0 组成的独立数组中。我们需要将每个标签映射到一个由 10 个二进制数组成的数组中——0 代表所有的值,1 代表特定的值。例如,1 将被映射到[0,1,0,0,0,0,0,0,0,0];8 会映射到[0,0,0,0,0,0,0,0,1,0]等等。这就是所谓的“分类”输出。
另一个非常重要的任务是将数据标准化。激活函数— relu 或 sigmoid 或 tanh..当这些数字小于 1 时,它们都可以最佳地工作。这在任何神经网络中都是重要的一步。错过这一步对模型效率有非常不好的影响。
这是训练神经网络中非常简单但重要的一步。同样,如果是一些原始数据,我们将需要更多的清理工作。但是这个已经被 Keras 消毒了。
数据扩充
我们拥有的资源总是少于我们所需要的。数据也不例外。为了取得越来越好的结果,我们需要比我们现有的更多的东西。我们可以从现有的资源中生成更多的数据——利用我们对数据的了解。例如,我们知道,如果整个图像向两边移动一个像素,数字不会改变。
因此,输入集合中的每个图像可以通过在每一侧移动一个像素来生成另外四个图像。这些图像在我们看来几乎没有变化。但是对于神经网络模型来说,它是一个新的输入集。这个简单的信息可以给我们 5 倍的数据。就这么办吧。
如果你不能理解上面的代码,不要担心。有关使用 NumPy 数组的详细信息,请参考 NumPy 博客。
本质上,这段代码只是删除了图像一侧的单元格,并在另一侧插入了 0。它从训练数据中每个图像的所有四个边进行计算,然后将其附加到名为 augmented_images 的新数组中。除此之外,它还构建了 augmented_lables 数组。
现在,我们可以使用 augmented_images 和 augmented_labels 代替 train_images 和 train_labels 来训练我们的模型。但是,等一下。如果我们仔细想想,数据就不再是随机的了。我们有一个巨大的数据块,图像在中心,后面是一个巨大的数据块,图像在每个方向上移动。这样的数据并不能创造出好的模型。我们需要通过很好地重组数据来改善这一点。
但这并不那么简单。现在,我们有一组图像和一组标签。我们必须洗牌。但是,通信不应该丢失。洗牌后,5 的图像应该指向标签 5!
NumPy 确实为我们提供了一种优雅的方式。
本质上,我们将两者结合成一个单一的实体,然后以图像和标签一起移动的方式对其进行洗牌。
训练模型
一切就绪后,我们现在可以开始训练模型了。我们从创建一个 Keras 序列模型开始。我们可以在下面的博客中查看不同类型模型的详细信息。让我们给这个模型添加三层。Keras 允许我们添加许多层。但是对于这样的问题,3 层就足够了。
784 的输入形状由输入数据中每个实体的大小定义。我们每个人有 784 张照片。这就是我们开始的地方。输出大小必须是 10,因为我们有 10 种可能的结果。典型的网络在最后一层具有 softmax 激活,在内部隐藏层具有 relu。
每层的大小只是基于判断的估计。我们可以通过实践、经验和对神经网络工作原理的理解来发展这种判断。您可以尝试使用这些工具,看看它们对模型效率的影响。
接下来,我们使用可用的数据来编译和训练模型。
编译器的参数——loss = " categorial _ cross entropy "和 optimizer = TF . train . adamoptimizer()可能看起来模糊不清。你可以查看一下深度学*上的博客,以便更好地理解它们。
方法 model.fit()使用我们拥有的数据完成训练模型的实际工作。
这会生成一个输出:
我们可以看到,随着每次迭代,损耗减少,精度提高。请注意,输出可能不总是精确匹配,这是因为随机播放和训练的随机性。但趋势应该差不多。
评估模型
现在我们有了一个训练好的模型,我们需要评估它有多好。第一个简单的步骤是使用 TensorFlow 自己的评估方法进行检查。
那很好。考虑到我们拥有的数据量,这是一个很好的精确度。但是,这个测试是不够的。非常高的精度也意味着过度拟合。所以一定要用测试数据来核对。
人们可以注意到,测试数据的准确性稍低。这意味着轻微的过度拟合。但这还不算太糟。所以我们暂时可以接受。在真实的例子中,根据需要,可以尝试调整模型形状和其他超参数以获得更好的结果。
抽样
这可能不会给我们所需要的所有信心。我们可以手动检查一些样本,看看我们的模型表现如何。
首先,为所有测试图像创建预测。现在,预测是一个包含测试集中所有图像输出的数组。
我们可以看到,这个集合中的每个元素都是一个 10 个元素的数组,它显示了输入图像属于给定标签的概率。当我们检查预测集中的第 0 个元素时,我们可以看到除了元素 7 之外,所有元素的概率都很低,几乎为 1。因此,对于图像 0,人们会预测 7。
现在让我们看看测试图像是什么样子的。在此之前,我们需要重塑图像数组(还记得我们为构建模型制作了一个一维数组吗?现在让我们检查第 0 个元素
这确实是 7!
只有一个正确答案肯定不足以验证模型的准确性。但是,此时我们可以检查的一点是预测[0]数组中的值。元素 7 中的值远远大于其他值。这意味着,模型对结果是绝对确定的。毫无疑问是因为两个类似的结果。这是一个好模型的重要特征。
Kaggle 座头鲸识别挑战的金牌解决方案综述
原文:https://towardsdatascience.com/a-gold-winning-solution-review-of-kaggle-humpback-whale-identification-challenge-53b0e3ba1e84?source=collection_archive---------14-----------------------
对最引人注目的方法的广泛而简单的回顾
Photo by Sandra Seitamaa on Unsplash
最*,我的团队参加了在 Kaggle 举办的座头鲸识别挑战赛。我们赢得了一枚金牌,并在排行榜上(在 2131 支队伍中)名列第十。
在这篇博文中,我将总结我们解决方案的主要思想,并简要概述其他团队使用的有趣且吸引人的方法。
问题描述
主要目标是确定,给定的这张鲸侥幸的照片是属于 5004 种已知鲸鱼个体中的一种,还是一种以前从未观察到的新鲸鱼。
Example of 9 photos of the same whale from the training data
这场竞赛令人困惑的一面是巨大的阶级不平衡。对于 2000 多个班级,只有一个训练样本,这使得很难使用开箱即用的分类方法。更重要的是,对鲸鱼是否是新品种进行分类是比赛的重要组成部分,这被证明是相当重要的。
Class Imbalance, from kernel by
Tomasz Bartczak
比赛的衡量标准是 mAP@5 (平均精度为 5),这允许我们为每张测试图像提交多达 5 个预测。我们在私有测试集上的最高成绩是 0.959 mAP@5。
萨纳科耶乌,普莱斯科夫,沙克雷💪
该团队由海德堡大学博士生弗拉迪斯拉夫·沙克雷(我)阿奇奥姆·萨纳科耶乌和 Kaggle Top-5 特级大师帕维尔·普莱斯科夫组成。
为了加快实验速度,我们在比赛中途加入了 Artsiom,Pavel 在团队合并截止日期前一周加入了我们。
验证和初始设置
在这场比赛的几个月前,同一场比赛的游乐场版本在 Kaggle 上举办,但是,正如比赛主办方提到的,真实(非游乐场)版本的特点是更多的数据和更干净的标签。我们决定以多种方式利用之前比赛的知识和数据:
- 利用之前比赛的数据,我们使用图像哈希收集了【2000 多个验证样本。后来,当我们验证我们的套装时,这被证明是至关重要的。
- 我们从训练数据集中删除了 new_whale 类,因为它的元素之间不共享任何逻辑图像特性。
- 有些图像根本没有对齐。幸运的是,有一个公开可用的预先训练的边界框模型,用于操场竞赛的获胜解决方案。我们用它来检测鲸鱼爪周围的精确边界框,并相应地裁剪图像。
- 由于图像的颜色不同,所有数据在训练前都被转换为灰度。
方法 1:连体网络(Vladislav)
我们的第一个架构是一个暹罗网络,有许多分支架构和客户损耗,由许多卷积层和密集层组成。我们使用的分支架构包括:
- ResNet-18,ResNet-34,Resnet-50
- SE-ResNeXt-50
- 马丁·皮奥特公开分享的类 ResNet自定义分支
我们使用硬负以及硬正挖掘,通过每 4 个时期对分数矩阵求解线性分配问题。为了简化训练过程,在矩阵中加入了少量的随机化。
采用渐进式学*,分辨率策略 229 x229->384 x384->512 x512。也就是说,我们首先在 229x229 图像上训练我们的网络,几乎没有正则化,学*率更大。收敛后,我们重置学*率并增加正则化,从而在更高分辨率(例如 384x484)的图像上再次训练网络。
此外,由于数据的性质,使用了大量的增强,包括随机亮度、高斯噪声、随机裁剪和随机模糊。
此外,我们追求智能翻转增强策略,这大大有助于创建更多的训练数据。具体来说,对于属于同一鲸鱼X, Y
的每对训练图像,我们多创建了一对训练图像flip(X), flip(Y)
。另一方面,对于每一对不同的鲸鱼,我们又创造了三个例子flip(X), Y
、Y, flip(X)
和flip(X), flip(Y)
。
An example showing that random flips strategy does not work with a pair of same-whale photos. Notice how the lower photos become different when we flip one of the images since we care about fluke orientation.
使用 Adam optimizer 对模型进行优化,初始学*率为 1e-4,在平稳状态下减少了 5 倍。批量大小被设置为 64。
模型的来源写在 Keras 上。在单个 2080Ti 上训练约 400-600 个历元的模型需要 2-3 天(取决于图像分辨率)。
拥有 ResNet-50 的表现最好的单一模型得分 0.929 磅。
方法 2:度量学*(Artsiom)
我们使用的另一种方法是利用利润损失的度量学*。我们使用了许多 ImageNet 预训练的主干架构,包括:
- ResNet-50,ResNet-101,ResNet-152
- DenseNet-121、DenseNet-169
网络主要使用 448×448-> 672×672 策略逐步训练。
我们使用 Adam 优化器,在 100 个时期后将学*率降低 10 倍。我们还在整个培训中使用了 96 的批量大小。
最有趣的部分是什么让我们立即获得了 2%的提升。这是一种度量学*方法,由 Sanakoyeu,Tschernezki 等人开发,并在 2019 年 CVPR 上发表。它所做的是每隔n
个时期就将训练数据和嵌入层分成k
个簇。在建立了训练组块和学*者之间的双射之后,该模型在累积分支网络的梯度的同时单独训练它们。你可以在这篇论文发表的时候在这里查看它和代码。
“分而治之,嵌入度量学*空间”,Artsiom Sanakoyeu,Vadim Tschernezki,Uta Büchler,bjrn Ommer,CVPR,2019 年
由于巨大的阶级不平衡,大量的增强被使用,其中包括随机翻转,旋转,缩放,模糊,照明,对比度,饱和度变化。在推断期间,计算查询特征向量和训练图库特征向量之间的点积,并且选择具有最高点积值的类作为前 1 个预测。另一个有助于解决类别不平衡的技巧是对属于相同鲸鱼 id 的训练图像的特征向量进行平均。
这些模型是使用 PyTorch 实现的,在一台 Titan Xp 上训练需要 2-4 天(取决于图像分辨率)。值得一提的是,采用 DenseNet-169 主干的性能最佳的单一型号的得分为 0.931 磅。
方法 3:特征分类(Artsiom)
当我和 Artsiom 联手时,我们做的第一件事就是使用从我们所有模型中提取的特征训练分类模型,并连接在一起(当然是在应用 PCA 之后)。
分类头由两个致密层组成,中间有脱落物。该模型训练非常快,因为我们使用预先计算的特征。
这种方法让我们获得了 0.924 磅,并带来了更多的整体多样性。
方法 4:新的鲸鱼分类(Pavel)
这场比赛最复杂的部分之一是正确地对新鲸鱼进行分类(因为大约 30%的图像属于新鲸鱼类)。
处理这个问题的流行策略是使用一个简单的阈值。也就是说,如果给定图像 X 属于某个已知的鲸类的最大概率小于阈值,则它被分类为新鲸类。然而,我们认为可能有更好的办法来解决这个问题。
对于每个表现最好的模型和集合,我们取其前 4 个预测,按降序排列。然后,对于每隔一个模型,我们取它们在所选的 4 个类别中的概率。目的是根据这些特征来预测鲸鱼是否是新的。
Pavel 创建了一个非常强大的对数回归、SVM、几个 k-NN 模型和 LightGBM 的混合体。在交叉验证中,所有数据的组合为我们提供了 0.9655 的 ROC-AUC,并增加了 2%的 LB 分数。
组装
从我们的模型中构建整体绝对不是一件容易的事。事实是,我的模型的输出是一个非标准化概率矩阵(从 0 到 1),而 Artsiom 提供的输出矩阵由欧几里德距离组成(因此范围从 0 到无穷大)。
我们尝试了多种方法将 Artsiom 的矩阵转换为概率,其中包括:
- 类 t-SNE 变换:
- Softmax
- 通过应用功能
1 / (1 + distances)
简单地反转范围 - 许多其他函数来反转矩阵的范围
不幸的是,前两种方法根本不起作用,虽然大多数情况下使用任意函数将范围裁剪为[0,1],但结果大致相同。我们最终选择了这个函数,在验证集上选择了一个具有最高 mAP@5 的函数。
令人惊讶的是,最好的一个是1 / (1 + log(1 + log(1 + distances)))
。
其他团队使用的方法
基于 SIFT 的
我想概述一个解决方案,在我看来,它是最漂亮的解决方案之一,同时也是不寻常的。
现在是 Kaggle 特级大师(排名 12)的 David 在私人 LB 排名第四,并在 Kaggle 讨论论坛上以帖子的形式分享了他的解决方案。
他处理全分辨率图像,使用传统的关键点匹配技术,利用 SIFT 和 ROOTSIFT。为了处理假阳性,大卫训练了一个 U-Net 从背景中分割出鲸鱼。有趣的是,他使用 smart 后处理给只有一个训练示例的类更多的机会进入前 1 预测。
我们也想过尝试基于 SIFT 的方法,但我们确信它的性能肯定比顶级的神经网络差。
在我看来,我们永远不应该被深度学*的力量所蒙蔽,低估传统方法的能力。
纯分类
由 Dmytro Mishkin 、 Anastasiia Mishchuk 和 Igor Krashenyi 组成的团队 Pure Magic thanks radek (第 7 名)采用了一种结合了度量学*(三重缺失)和分类的方法,正如 Dmytro 在他的帖子中所描述的那样。
在长时间训练分类模型时,他们尝试使用中心损失来减少过拟合,并在应用 softmax 之前使用温度缩放。在使用的众多主干架构中,最好的是 SE-ResNeXt-50,它能够达到 0.955 LB。
他们的解决方案远不止这些,我强烈建议你参考最初的帖子。
圆脸,圆脸
正如 Ivan Sosin 在帖子中提到的(他的团队 BratanNet 在这次比赛中获得第 9 名),他们使用了 CosFace 和 ArcFace 方法。来自原帖:
其中,Cosface 和 Arcface 作为新发现的人脸识别任务的 SOTA 脱颖而出。主要思想是在余弦相似性空间中使相同类的例子彼此靠*,并拉开不同的类。用 cosface 或 arcface 训练一般是分类,所以最后损失的是交叉熵。
当使用像 InceptionV3 或 SE-ResNeXt-50 这样的较大主干时,他们注意到过度拟合,因此他们转向像 ResNet-34、BN-Inception 和 DenseNet-121 这样的较轻网络。
该团队还使用了精心挑选的增强功能和众多网络修改技术,如 CoordConv 和 GapNet 。
他们的方法中特别有趣的是他们处理new _ whales . From the original post 的方式:
从一开始,我们就意识到有必要对新的鲸鱼做些什么,以便将它们纳入训练过程。简单的解决方法是给每条新鲸鱼分配一个概率,每类概率等于 1/5004。在加权抽样技术的帮助下,它给了我们一些帮助。但后来我们意识到,我们可以使用 softmax 预测来自训练集合的新鲸鱼。所以我们想出了蒸馏。我们选择蒸馏而不是伪标签,因为新鲸被认为具有与火车标签不同的标签。尽管这可能不是真的。
为了进一步提高模型能力,我们将带有伪标签的测试图像添加到训练数据集中。最终,我们的单个模型可以通过快照组装达到 0.958 。不幸的是,以这种方式训练的 ensembling 并没有带来任何分数的提高。也许是因为伪标签和蒸馏导致的品种减少。
最后的想法
Final Standings
令人惊讶的是,尽管私有测试集贡献了所有测试数据集的* 80%,但最终几乎没有任何改变。我相信竞赛主持人很好地提供了一个非常有趣的问题,以及干净和经过处理的数据。
这是我参加的第一次 Kaggle 比赛,它确实证明了 Kaggle 比赛是多么有趣、吸引人、激励和教育人。我想祝贺那些由于这次比赛而成为专家、大师和特级大师的人们。我还要感谢 ODS.ai 社区令人惊叹的讨论和支持。
最后,我想再次特别感谢我的团队成员 Artsiom Sanakoyeu 和 Pavel Pleskov 给了我一次难忘的 Kaggle 比赛经历。
一个研究生对统计学的看法
原文:https://towardsdatascience.com/a-graduate-students-perspective-on-statistics-5cb6ca643689?source=collection_archive---------21-----------------------
为什么统计学是一个普遍令人困惑的领域?
当我遇见一个新的人,不可避免的问题被问到,“那么,你是做什么的?”,我回答说我是一名统计学的博士生,对此的回答大多是这样的:
“统计?!我在大学时有一门必修的统计学课,它非常令人困惑。”
仅仅是这种事件的发生频率就让我开始思考为什么统计数据如此普遍地令人困惑。对我来说,答案很复杂,根源在于将确定性事件(如我们所见)转化为随机过程(如统计学所见)的实现。我试图在下面解开这些复杂性。
从点跳到云
在微积分之前,数学教育的标准轨迹通常会终止,我们生活在一个由点、线、曲线等组成的世界里。—数量通过确定性关系交织在一起的形状。我知道速度=距离/时间,所以如果我们需要在 45 分钟内到达 60 公里外的某个地方,那么我知道我必须以 80 公里/小时的速度行驶,这些函数关系是确定性的。
但是一上统计学课,我们就步入了一个随机的世界。我们不再在一组已知的关系中工作,而是在推断产生我们所看到的观察的未知机制。
例如,我们等一辆公共汽车,考虑到它过去的可靠性,我们试图预测它今天是否会准时到达。随机性有很多来源——交通灯的同步、路上其他司机的礼貌、天气状况——这些因素导致不同的到达时间。
因此,统计学隐含地处理概率 云、而不是点数。紧密概率云(“公共汽车每 10 1 分钟来一次”)表示我们非常确定公共汽车几乎总是接*其预定时间。分散的云(“公共汽车每 10 分钟来一趟”)表示到达时间的广泛可变性。如果我们只是没有观察到足够的信息来确定其长期模式(也许我们只等了两次公交车),或者我们的观察非常分散(有时会早 10 分钟,但有时会晚 20 分钟),这种情况就可能发生。
实际上,从来没有人明确告诉我,我正在离开一个由线条组成的世界,走向一个由云组成的世界,但我相信这是进入统计世界的一个基本困难。一个主要的结果是我们不再处理等效值(例如,y = x+3),而是处理范围和概率(例如,玫瑰是红色的,紫罗兰是蓝色的……但是我有玫瑰还是紫罗兰呢?
通常,统计问题集会提出一个问题,问题的开头是:
“假设 X 是分布的…”
在这些情况下,随机变量 X 的理论行为被告知我们,我们得出关于我们可能观察到的其实现的结论,这些实现用小写字母 X 表示。给定关于 X 的不同假设集,我们可以得出关于其行为的不同属性,如下所示:
考虑到这一点,你可能会认为统计学中的一个重要工具是一个“排序帽”,给定一组经验数据,测试它们是否最接*正态、泊松等。这样,我们就知道从我们的数据中可以得到哪组属性。
然而这样的工具相当稀少!有一个 Kolmogorov-Smirnov 测试,它测试两个分布的相似性,但只是在我的一堂本科统计学课上顺便提到过。 QQ 图作为两个重叠直方图的改进形式,直观地比较经验分布的分位数与其假定的理论分布是否匹配。直到研究生院,我才知道像核密度估计这样的方法可以用来估计非标准密度函数。
致力于将观察到的数据集与其潜在属性联系起来的统计推断领域,倾向于假设数据的分布,并简单地提供估计其参数的方法。精确的发行版本身对结果属性的影响是否像缺少工具所暗示的那样小?
自我反驳的一个尝试在于中心极限定理。我们经常对手段的行为感兴趣(平均,公交车会准时来吗?),中心极限定理说独立随机变量之和趋于正态分布。由于均值包含一个和,那么所有关于正态分布的导数都可以应用于独立随机变量实现的均值。
另一个回答是,人们越来越重视半参数和非参数方法,这种方法很少(或没有)作出分布假设。然而,正如应该合理预期的,这些方法的灵活性和适用性的增加可能是以降低功率为代价的。
那么数据科学家呢?
当我们意识到数据科学家必须做出确定性决策时,担心我们的随机性模型的准确性可能显得没有意义。正因为如此,简单地比较两个数字的大小,或者并排绘制直方图,可能就足以确定获胜的决策。统计学在一个不确定的世界中运作,但数据科学家在一个必须以二元方式做出决策的世界中运作。是或不是。
实际上,随机性——通常以 p 值的形式——只是告诉我们如何确定我们的决定,但永远不会改变我们决定的方向。考虑到这一点,不确定性程度的精确量化真的重要吗?如果我们选择将我们的数据建模为一种分布而不是另一种分布,那实际上会改变什么吗?
我对统计的保留意见
你经常听到人们把追求博士描述为“越来越了解越来越少”。但这不是我迄今为止对我的博士工作的评价——我当然会继续学*统计学的基础知识(比如斯坦的悖论!).
鉴于上述讨论,我更关心的是:
(1)如何将我们对理论统计的理解贯彻到现实世界中。这样做似乎需要一种能力来验证假设的程度,这是一个似乎还不发达的统计学领域。
(2)在一个确定性的世界里,如此谨慎地对待随机性的有用性。如果使用统计学来对公共政策、药物、网站设计等做出具体的选择。,随机性在哪些方面发挥了重要作用?
我的想法一直在发展,我衷心欢迎下面的评论、不同意见或反馈。
致谢
非常感谢高子冲、菲利普·莫里茨、阿维·费勒、特里萨·格伯特和佐伊·弗农与我一起阅读和提炼这些观点。
Much thanks to Zi Chong Kao, Philipp Moritz, Avi Feller, Theresa Gebert, and Zoe Vernon for reading and refining these ideas with me.
图形数据库案例研究:中国*语连锁店
原文:https://towardsdatascience.com/a-graph-db-case-study-chinese-idioms-2b8969afdea8?source=collection_archive---------37-----------------------
用 20 行 Python 构建一个 Neo4J 图形数据库应用程序
与关系数据库相比,图数据库有许多优点:快速查询、灵活模式、高效存储等。但时至今日仍未得到充分利用。困难之一是与其他语言的互操作性,官方文档提供的例子很少。本文试图填补这个空白,提供了一个只有 20 行 python 代码的案例研究。
中华*语链球赛
这是一个帮助小学生学*成语的经典教育游戏。一名学生坐在圆桌旁,随机拿出一个中国*语(一个由 4 个汉字组成的中国*语)。下一个学生必须快速说出另一个*语,其第一个字符与给定的*语的最后一个字符相匹配。当有人被卡住时,他必须唱首歌或跳支舞。
现在有了 graph DB 的知识,小学生可以不用再担心输了比赛,不得不在全班面前表演了!
图形设计
The graph structure is as simple as you can imagine. We have one types of node and one types of directed edge. It’s tempting to create a node for each idiom, because an idiom is an entity, just like a user, a movie, a product. If an edge exists between two nodes, we just create an edge. For example, there is an edge pointing from 坚定不移 to 移花接木, because the character 移 connects the two idioms.
Naive design
具有关系数据库背景的人可能会自然而然地想到这种设计,因为边只是连接操作中的一个匹配。对吗?不幸的是,这个看似无害的设计结果却不切实际。我们必须彻底搜索所有的边,并且一次添加一个边,导致二次时间复杂度。
通过巧妙的建模,我们可以做得更好。如果我们将*语嵌入到边中,而不是节点中,会怎么样?设位于*语开头或结尾的每个字符都是一个节点。设每条*语是一条有向边,从一个*语的最后一个字符(源节点)指向另一个*语的开始字符(目的节点)。原来这个设计是花费线性时间来构建的!
Improved design
履行
有了好的设计,实现就变得简单了。你需要安装 Neo4J 桌面服务器,和 py2neo 库。
pip install pandas py2neo
接下来,启动 Neo4J 服务器(参见指令,加载数据集。
现在我们可以查询结果了!让我们编写一个助手函数,让您定义初始*语、路径长度和行限制。
我们去查询数据库吧!不出所料,速度没有让人失望。为了在关系数据库中获得相同的结果,您需要自连接*语表五次。猜猜需要多长时间?(费用是 N⁵)
摘要
这个例子展示了我们如何利用图数据库的优势来显著地加速特定的任务,即使这些任务主要是用另一种语言编写的(在这个例子中是 Python)。
然而,阅读这篇文章并不能保证你可以在任何任务中运用同样的策略。为了做到这一点,需要牢固掌握密码语言。
延伸阅读
下面的博客涵盖了与 AB 测试相关的主题,以及对本文中提到的关键概念的更深入的回顾。
- 可视化贝塔分布和贝叶斯更新[ 链接
- 理解置信区间[ 链接
- A/B 测试的威力[ 环节
- 超越 A/B 测试:多臂强盗实验[ 链接 ]
- 你知道可信区间[ 链接吗
源代码、数据集、结果都在我的 GitHub 资源库 中。
一个巨大的公共健康阴谋?
原文:https://towardsdatascience.com/a-great-public-health-conspiracy-73f7ac6fb4e0?source=collection_archive---------13-----------------------
(Source)
科学、医学和政府在改善公众健康方面的合作。真人秀第五集。
2013 年 1 月,安大略省温莎市的市议会做出了一个奇怪的选择。以 8 比 3 的投票结果,他们实施了一项计划,将该镇儿童的蛀牙率提高了 50%以上。这些议员实施了什么邪恶的行为?每年举办多次万圣节?让糖果公司做学校午餐?不,他们做了更灾难性的事情:他们故意选择忽视堆积如山的医疗建议,屈服于公众的歇斯底里,取消上个世纪最伟大的公共卫生成就之一、公共用水加氟。
自 1945 年以来,向公共供水中添加矿物质氟化物以防止蛀牙已经成为一种普遍的做法。全世界大约有 4 亿人饮用添加了氟化物的水,包括至少 66%的美国人口。数以千计的研究发现水氟化是有益且无风险的,其中疾病控制和预防中心得出结论:氟化物在预防和控制龋齿方面既安全又有效 ( 龋齿是龋齿/蛀牙的医学术语)。尽管如此,加拿大一个小镇的政府认为他们比整个医学界都了解。
6 年后,儿童龋齿增加了 51%,低收入家庭需要牙科保健财政支持的人数增加了 300%,该镇儿童遭受了无尽的痛苦,温莎委员会在 2018 年 12 月的一次会议上不情愿地撤销了其决定。会上,5 位牙科专家作证,根据所有医学证据,全力支持水氟化。另一方面,20 名公民——没有医学学位——基于毫无根据的恐惧和一种信念表示反对,认为政府不应该“治疗”公众,即使药物阻止儿童去医院。幸运的是,到了最后,理智和民意调查显示 80%的市民希望水的氟化占了上风,而温莎将再次享受到好处。
这个故事立即引起了我的注意,因为它有着耐人寻味的元素:一项伟大的医学成就被阴谋论者毁掉了,人们拒绝承认大量的证据,最后,科学战胜了迷信。此外,它说明了为什么现实项目,努力用数据减少对世界的误解是重要的:只有通过检查数据,我们才能找出哪些政策是有效的,然后——即使作为个体公民——为它们的实施而运动。在科学、医学和我们的世界观方面保持正确不仅仅是为了虚荣,而是为了确保我们为社会做出最好的决定。
在现实项目的第五集中,我们将深入探究公共用水氟化的证据。虽然前几集关注的是大规模的想法,但这一集更私人:它涉及到你和你家人的健康。我们需要知道事实,因为虽然我们最初可能会嘲笑阴谋论者,但只有当他们开始侵蚀对政府的信任,并随之降低社会福祉时,这才是有趣的。也许我们天生倾向于寻找疯狂的理论(你点击这个是因为标题中的“阴谋”,对吗?)但事实往往更令人惊讶,因为公共用水加氟的数据证明了这一点。
公共用水加氟的事实
对于任何健康话题,尤其是引起争议的话题,我们必须小心我们从哪里获得数据。即使是同行评议期刊上的研究也会有偏见——有意或无意。因此,审查医学证据的最佳实践是查看荟萃分析,即评估数十或数百项研究结果的审查。英国慈善机构 Cochrane Organization 成立的目的是为了对医学文献进行系统综述,并为公众利益提出客观建议。我们将依靠他们对公共水氟化的荟萃分析,以及来自澳大利亚国家健康和医学研究委员会(NHMRC )的一项分析。为了进行经济分析,我们将使用来自“社区水氟化的经济评估”的数据。
这些来源都不是引人入胜的读物,但是当涉及到健康时,依赖娱乐(即新闻)作为事实的来源是灾难性的。阅读实际证据是困难的,但这是不被特殊利益集团愚弄的唯一方法。维基百科的文章可以是一个很好的起点,但是我们应该始终坚持引用。在这里,我将总结相关的部分,但是如果你持怀疑态度,我鼓励你阅读文章。
公共饮水加氟能减少蛀牙吗?
让我们从一个简单的问题开始:水氟化能预防蛀牙和蛀牙吗?明确的答案是:是的,至少在儿童中是这样。根据 Cochrane review(基于 107 项研究),公共水氟化减少了乳牙 35%的蛀牙和恒牙 26%的蛀牙。其他荟萃分析也发现了类似的结果。来自 NHMRC 的报告发现,在所有研究中,风险降低了 9%到 35%。同一篇综述发现,需要治疗(NNT)以预防蛀牙的人数在 3-14 人之间。NNT 值为 3 意味着每 3 个人接受氟化水,就有 1 个人不会因此患上龋齿。
NHMRC 审查的相关调查结果见下图。龋齿是蛀牙的学名(和细菌产生的酸造成的蛀牙是一回事)。风险差和 NNT 是两个最有用的栏目。在所有回顾的研究中,公共供水的氟化降低了蛀牙的风险。
Table 11 from NHMRC review on the efficacy and safety of fluoridation.
Cochrane review 小心翼翼地指出,没有足够的研究证实水的氟化作用可以降低成人龋齿的发病率。然而,疾病控制和预防中心(CDC) 引用了至少一项研究,表明成年人的蛀牙减少了 20-40 %,这表明益处可能会持续一生。重要的是,既要承认我们已有的证据——饮水氟化改善了儿童的牙齿健康——又要承认在得出结论之前我们还需要更多的研究。
潜在的副作用是什么?
医学干预的效果不是唯一的关键因素:不需要有有害的副作用,或者至少好处必须大于不利的结果。因此,第二个问题是:氟化有副作用吗?反对水氟化的人列举了一系列副作用(包括癌症和低智商),但是,在一项又一项的研究中,医学证据指出只有一种很少发生:牙齿轻度变色。这种情况被称为氟斑牙,纯粹是美学意义上的,它只会影响牙齿的外观。其他新闻,喝咖啡和茶也会染牙!
任何由阴谋论者鼓吹的声称发现了负面影响的研究都检验了远远超过任何社区水氟化计划所要求的剂量(百万分之 0.7 份)。这意味着公共饮水加氟唯一可能的副作用是轻微的色斑,就像你可能从过量的茶中得到的一样。所以,归根结底是你重视什么:如果你想让你的牙齿腐烂,但看起来无可挑剔,停止喝含氟水(和茶)!对于我们这些不喜欢牙痛和蛀牙的人来说,轻微变色的风险完全值得氟化物的好处。
如果你不相信我,也许美国牙科协会(ADA)的以下声明可以动摇你:“[ADA]毫无保留地支持社区供水的氟化,认为这是安全、有效和必要的,可以防止蛀牙”。提醒你一下,美国糖尿病协会认为 T2 会因为加氟水而失去 T3,因为这导致了患者的减少。也许是唯一从这种情况中获益的人?一名当地牙医,由于水氟化的停止,他的预约一直持续到 2020 年。
经济学
有效的治疗是一回事,但在实施之前对社区来说最重要的问题可能是:值得吗?我们无法对预防的人类痛苦定价,但我们可以将氟化的成本与减少的蛀牙治疗成本进行比较。在审查“社区水氟化的经济评估”中,对不同人口规模的 6 项不同研究进行了检查,发现每人每年的水氟化成本从 0.24 美元到 4.85 美元不等,取决于社区规模(人口越多意味着人均成本越低)。将这些数字放在背景中,每人每年提供的平均福利从 5.49 美元到 93.19 美元不等。
并排比较成本和收益,社区水氟化每投资 1 美元可获得 135 美元。在每项研究中,收益都超过了成本,如下表所示:
Cost to benefit ratios of water fluoridation from 6 studies (Source)
有趣的是,成本收益比通常随着社区规模的增加而增加。这是有道理的:基础设施是最昂贵的部分,氟化物本身相对便宜。因此,同一供水系统服务的人越多,人均成本就越低。
我们希望我们的退休基金能够带来正回报,我们也应该从公共卫生干预中获得同样的回报。你可以做得比把你的钱投入公共水氟化更糟糕:它不仅减少了你社区的儿童的痛苦,而且还可以获得 135 倍的投资回报!任何选择在水中加氟的社区不仅能改善其公民的牙齿健康,还能带来社会利益。
可供选择的事物
有没有其他方法可以在不往水里放氟化物的情况下获得同样的好处?答案是肯定的:牛奶和盐都可以加氟,最常见的替代品是局部选择,包括凝胶和牙膏。现在美国大约 90%的牙膏都含有氟化物。更重要的是,牙膏中的浓度几乎是水氟化物的 1000 倍( 1000+ ppm,相比之下,水的浓度为 0.7 ppm)。对于那些担心氟化对健康有潜在影响的人来说,明确的解决办法不是避免饮用自来水,而是停止刷牙。
其他氟化物来源的流行可能是为什么在过去的几十年里,公共水的氟化作用已经下降。在 20 世纪 50 年代和 60 年代进行的初步研究发现,当引入氟化物时,龋齿减少了 50–70%。然而,正如我们在上面所了解到的,提出的证据表明了一个更加适度的减少,大约 20-35%。这是一个好消息,因为美国的整体蛀牙率下降,含氟和非含氟社区之间的牙齿健康差距缩小。然而,应该注意的是,在社会经济水平较低的地区,含氟牙膏和替代来源的获取受到限制,而这些地区恰恰是最需要含氟牙膏的地方。疾控中心总结得很好:
水氟化对社会经济地位低的社区尤其有益。这些社区的龋齿负担不成比例,并且比高收入社区更难获得牙齿保健服务和其他氟化物来源……尽管有其他含氟产品,但水氟化仍然是向大多数社区的所有成员提供氟化物的最公平和最具成本效益的方法,无论年龄、教育程度或收入水平如何。
与替代品相比,公共水氟化最好的部分是它不会基于财富进行歧视。与每人每年花费 100 美元的氟化物凝胶相比,它也便宜得多。反对公共用水加氟的人普遍认为,所有其他选择都意味着不再需要加氟。然而,如果是这样的话,那如何解释温莎市在短短几年内蛀牙率的快速上升呢?虽然这只是一个轶事,但是其他研究已经发现一旦停止水的氟化会有类似的不良影响。是的,有替代品,但它们要求人们能够负担得起,并知道他们应该使用它们。在公共用水中加入氟化物,覆盖所有的基地,并接触到那些最脆弱的人,这要有效得多。
为什么推迟?
鉴于上述证据:氟化物是预防蛀牙的有效、安全和最便宜的选择,尤其是对儿童而言,很难想象有人会反对这一措施。尽管如此,还是有反对水氟化的呼声,通常来自那些反对任何形式的政府干预的人。 Rational Wiki 有一个很棒的页面,揭穿了许多反对水氟化的不合逻辑的论点,但是在这里我只提到两个。
1.世界卫生组织反对氟化
的确,世卫组织已经发布了关于从饮用水中去除氟化物的出版物。然而,世卫组织并没有谈论受控的公共水氟化,而只是过度的自然氟化。这只适用于世界上很少一部分人,他们生活在氟化物自然供应量极高的地区。任何东西在极端的量下都是危险的,包括许多维生素,将这些地方与公共水氟化相比较是错误的逻辑。在美国,用于给公共用水加氟的百万分之 0.7 远低于国家资源委员会认为安全的百万分之 4。
事实上,世卫组织是水氟化最坚定的支持者之一,明确声明:“在可能的情况下,水供应的氟化是预防龋齿的最有效的公共卫生措施。”引用水氟化减少健康不平等的能力,世卫组织提倡尽可能采用这种干预措施。用一个有限的例子来代表所有情况是阴谋论者的经典策略。它代表了一种过度概括的谬误,是两种完全不同情况的比较。
2.消费者应该对水的氟化有选择权
这可能是反对水加氟的最常见的论点,并以多种形式出现:政府不应该对其公民用药,消费者没有接受加氟的选择,我们应该能够过上没有暴政的生活。关于选择的论点可以分为几个层次。鉴于政府——至少在反对势力强大的美国——是由人民选举产生的,你确实可以选择水的氟化。如果你不喜欢它,没有什么可以阻止你竞选公职来改变事情。此外,你可以选择只喝瓶装水,瓶装水可能含氟,也可能不含氟(因为美国食品和药物管理局对瓶装水的监管有些松懈)。
此外,儿童是水氟化的最大受益者,他们不能投票,因此没有任何选择。如果事情真的由人民决定,那么每个人都会有平等的发言权。此外,政府还为公共安全做了很多其他事情,比如在冬天犁地和管理药品。我们是否应该选择在积雪覆盖的高速公路上行驶,或者给我们的孩子药物,其中可能含有公司想要的任何东西(在药物受到监管之前,它往往杀死的人比它帮助的人多)。当涉及到公众的安全时,我们通常没有真正的选择,鉴于我们对非理性、有害行为的偏好,这是一件好事。
水氟化的批评者并不多,他们只是倾向于大声疾呼。在温莎,有五分之四的居民支持水的氟化处理,少数敢于直言的人造成了大部分的损失。同样, 1998 年盖洛普民意测验发现,美国 70%的受访者赞成这种做法,这表明一小部分人应对反对派负责。问题似乎不在于公众舆论,而在于谁的声音最大。当人们相信(错误地)他们受到了政府的伤害时,他们更有可能说出来,而不是当他们知道他们得到了帮助时,这就产生了更有说服力的新闻。
我将以一个生动的故事来结束这一节。当芬兰城市库奥皮奥在 1992 年停止水的氟化时,他们在宣布停止之前一个月实施了这一改变,没有告诉公众。这意味着公众在不知情的情况下饮用了整整一个月的无氟水。研究人员利用这一补偿来调查居民与水氟化有关的症状,甚至是水的味道。研究结果显示,居民们不知道水的氟化作用已经提前停止:他们报告说,即使在氟化作用停止后,水的症状或味道也没有变化。
只有当居民们被告知他们不再饮用氟化水时,他们才奇迹般地报告症状减轻,并说他们能注意到味道的变化。换句话说,整个效果都在他们的头脑中。这些研究的作者很好地总结道:“这些症状的流行似乎与接触氟化水的心理影响有关,而不是身体影响。”那些认为氟化是一种消极行为的人最有可能报告说,一旦他们知道氟化已经停止,他们会感觉更好(但当氟化实际发生时,他们没有注意到任何变化)。人类的思维非常善于证明非理性的信念,公共用水加氟是有害的这一概念不得不被列为最不合逻辑的理论之一。不管人们反对水氟化的动机是什么,有一件事是清楚的:他们自己没有检查数据,也没有批判性地思考证据。
结论
水氟化的故事是一个关于药物如何发挥作用的经典故事:它被深入研究,并在被证明安全有效后,在美国全国范围内实施。虽然我开始写的那篇文章可能会让你质疑人类的未来,但我认为这个故事是积极的。重要的教训是,科学和医学最终取得了胜利。温莎再次获得了氟化水,镇上的孩子们(可能还有成年人)将体验到这种解脱。值得指出的是,真理不是靠叫嚣对方而赢得的,而是靠提出明确的证据。问题不是缺乏公众对有益措施的支持,而是反对的声音太大了。套用一句的名言,迷信要想获胜,唯一需要做的就是让科学安静地坐在一旁。
现在你知道了事实:水氟化显然对健康有益,没有副作用,并且是防止蛀牙的最具成本效益的方法——你准备好利用这些信息继续让世界变得更美好。如果人类倾向于寻找耸人听闻的东西,那么就把水的氟化说成是耸人听闻的。这是一个由科学、医学和政府在最大规模上实施的计划,实际上已经成功地改善了公共卫生,同时带来了利润。
一如既往,我欢迎反馈和建设性的批评。我可以通过推特 @koehrsen_will 联系到。
对图像数据集进行重复数据删除的绝佳方式
原文:https://towardsdatascience.com/a-great-tool-for-image-datasets-cb249663ca45?source=collection_archive---------18-----------------------
生产中的命令行工具。
就手工劳动的时间而言,为 ML 管道准备数据通常要花费大部分时间。此外,构建或扩展数据库通常要花费天文数字的时间、子任务和对细节的关注。后者让我找到了一个很棒的命令行工具,用于清除重复和*似重复的内容,尤其是在与 iTerm2 (或 iTerm )一起使用时——即 imgdupes 。
注意,这里的目的是介绍 imgdupes。有关规范、算法、选项等的技术细节,请参阅参考资料(或者继续关注有关细节的未来文章)。
问题陈述:消除映像集的重复
我在构建面部图像数据库时的情况如下:一个包含多个目录的目录,每个子目录包含相应类的图像。这是 ML 任务中的一个常见场景,因为许多著名的数据集都遵循这样的约定:为了方便和作为显式标签,通过目录将类样本分开。因此,我在清理人脸数据,并在命名的子目录中识别人脸。
知道有几个副本和*似副本(例如,相邻的视频帧),并且这对我要解决的问题没有好处,我需要一种算法或工具来找到副本。准确地说,我需要一个工具来发现、显示并提示删除所有重复的图像。我很幸运地发现了一个非常棒的基于 python 的命令行工具 imgdupes。
先决条件
在所需的 python 环境中安装 imgdupes (即,参见 Github 获取说明)(例如,参见 Gergely Szerovay 的博客了解 conda 环境)。
如果 iTerm2 是您的 shell 提示符的选择,我会建议大多数开发人员使用它,因为它提供了许多简洁的特性、可调的设置和需要时的附加组件。iTerm 本身可以组成一系列博客,如果特定的博客还不存在的话(例如,克洛维斯的(@阿尔贝 l) 博客)。
IMGDUPES:简单来说
直接借用作者的 Github 页面,这里有一张 gif 演示 imgdupes 的用法。
https://github.com/knjcode/imgdupes/blob/master/video_capture.gif
该工具出色地允许用户找到重复项,然后甚至直接在 iTerm 中并排显示这一对。此外,可选参数允许每个实例提示用户保留一个、多个重复图像,或者不保留任何重复图像。
一个小问题(根据我的用例)
首先,与在子目录中搜索相比,从根文件夹中搜索时需要更多的比较。换句话说,如果我确信在任何子目录中都不存在重叠,则不希望从根目录使用,原因如下:
- 许多(数百万和数百万)不必要的比较。
- 很多误报源于不同的身份。这占了大多数。如下面的截图所示,这四组重复项都是假的,但都来自不同的目录(参见下图中图像下方的路径)。
最初使用的代码片段:
Screenshot running imgdupes from root directories.
这有两个问题:(1)如果手动筛选,会浪费太多时间;(2)删除了太多不应该删除的面(标志 -dN ,其中 -d 提示保留或删除, -N 首先选择并删除其余部分,无需用户输入)。
简单修复
让我们从命令行直接切换到每个单独的目录,运行 imgdupes,切换回根目录,然后重复。从命令行运行以下命令:
Notice the progress bar appearing when imgdupes is run from a different subdirectory.
只需添加 -N if,以仅保留每组的第一幅图像,从而无需额外输入即可运行——如果从根递归运行,这种方法将删除许多许多独特的人脸。
默认情况下,列表的顺序由文件大小设置(降序)。对于我的情况,大约 95%的第一张图片是首选。然而,这里有几个例子;事实并非如此。
The second image might be the preferred image to keep.
为此,您可以通过每次提示手动选择一组重复项。然而,这可能很耗时,我就遇到过这种情况。所以我首先运行显示,然后滚动以确保所有看起来都很好(即,手动处理首选人脸不是第一个的实例),然后再次运行删除。尽管如此,这完全取决于开发人员和项目/数据的需求。最后,我先查看了一下(即带有 -d 标志)……只是为了确定一下。然后,我运行以下程序对映像集进行重复数据消除:
最后
imgdupes 是一个很棒的命令行工具,它提供了一个实用的界面来查找、查看和清理重复的图像。技术细节在他们的 Github 上(也许还有未来的博客:)。
总而言之,与 iTerm 的集成令人振奋。这是我最喜欢的部分——事实上,基于 python 的控制台工具还可以从这里完成的 iTerm 集成中受益。
请分享任何可以借用这个想法或想到的任何其他想法的额外工具的想法或想法。
接触
网
领英