自然语言理解简史
照片由 Unsplash 上的 @allecgomes 拍摄
人工智能中自然语言处理的一个子课题
在探索自然语言处理时,我偶然发现了术语自然语言理解。这让我对语言有了更多的思考,不仅仅是处理过程,还有意义。
黄色的花是什么意思?
当然,它可以简单地表示一朵黄色的花,作为一个物体。
它可以是你所爱的人最喜欢的花,让你想起婚礼的那一天,一段珍贵的回忆或悲伤,这取决于具体情况。
也许你总是带黄色的花去你祖母的坟墓。
在墨西哥,黄色的花金盏花象征着死亡。墨西哥的庆祝活动以金盏花鲜艳的黄色和橙色为特色。
照片由 @albrb 拍摄
黄色的花可以代表开悟,这就是为什么它在印度经文中被广泛用来代表佛陀和毗湿奴。
在法国,黄色的花代表嫉妒。
随着时间的推移,意思是一样的吗?
在维多利亚时代的英国,黄色的花被用来象征单恋。维多利亚时代的人用花就像我们用表情符号一样。
说到表情符号——这个看起来很无辜。
🍆
它在网上最常用来代表阴茎。
当汗液滴表情符号旁边时,表示射精。
我们从开花到射精有点快。
无论是口语、文本还是符号,语言中的意义和语境都不是那么容易的。
什么是自然语言理解?
如果意义是如此的困难,那么将这种意义变成一个自动的过程似乎是一个挑战。
在这篇文章中,我探索了术语自然语言理解,主要从维基百科的文章开始,并通过一些我感兴趣的其他来源进一步阐述。
“自然语言理解 ( NLU )或自然语言解释 ( NLI )是人工智能中自然语言处理的一个子课题,处理机器阅读理解。”
以这种方式,它处理一些相当困难和复杂的事情。
如果在人工智能(AI)领域内操作,它可以被认为是一个人工智能难题。什么是 理解 ?
“理解是一个与抽象或物理对象(如人、情况或信息)相关的心理过程,通过这一过程,一个人能够思考它并使用概念来充分处理该对象。理解是知者和理解对象之间的关系。”
理解可以自动化吗?
照片由 @heathermount 拍摄
这个过程可以被充分描述以复制它或者使用人工语言(编程/代码)来更好地理解它吗?
如果这两个问题的答案都是肯定的,那么你可能对自然语言理解有些兴趣。
然而,这些问题可能不相关,你可能只是想从自然语言的角度来探索它——人类说话、发短信或交流。
如果你曾经学过一种不同于你母语的语言,你可能在某种程度上理解句子可以表达相同的意思,也可以表达不同的意思,而且有不同的社会背景,这些句子表达不同的意思。
语言具有社会性和动态性,它是不断变化的,而不是一成不变的。
Insight 可以应用于自动推理、机器翻译、问答、新闻收集、文本分类、语音激活、存档和大规模内容分析。
自然语言理解的历史
可能有许多方法来讲述自然语言理解的历史,但是如果我们从你在维基百科上能读到的东西来看,它是从学生程序开始的。
1964 年学生丹尼尔·鲍勃为他在麻省理工学院的博士论文写的。
学生使用基于规则的系统进行逻辑推理。
这些规则由软件开发人员预先编程,能够解析自然语言。
这被认为是计算机理解自然语言的最早尝试之一。
在此之前,约翰·麦卡锡在 1955 年创造了人工智能这个术语。
丹尼尔·鲍勃的论文题目是 计算机问题解决系统的自然语言输入 。
事实上,这份出版物可以在 ResearchGate 上找到。
Daniel Bobrow 题为计算机问题解决系统的自然语言输入的论文截图
它展示了计算机如何理解简单的自然语言输入来解决代数问题。
1965 年,一年后,麻省理工学院的约瑟夫·韦岑鲍姆写了《伊莉莎》。
伊莱扎是一个互动程序,用英语就任何话题进行对话,最受欢迎的是心理治疗。
与伊莱扎聊天机器人的对话。权利:公共领域。
创作者将程序视为一种展现人机交流肤浅性的方法。
然而,令他惊讶的是,许多人把类似人类的感觉归功于计算机程序,包括他的秘书。
伊莱扎的工作是通过简单的分析和把关键词替换成固定短语。
伊莱扎作为一个玩具项目获得了惊人的人气。
尽管如此,它仍可被视为 2020 年商业系统的早期范例。
1969 斯坦福大学的 Roger Schank 为自然语言理解引入了概念依赖理论。
该模型使用以下基本表示性标记:
- 现实世界的物体,每个都有一些属性。
- 现实世界的动作,每个都有属性
- 次
- 位置
一组概念转换然后作用于这个表示。
如何使意义独立于输入中使用的单词?
1970 ,William A. Woods 引入了扩充转换网络(ATN)来表示自然语言输入。
这些网络称为一组*‘有限状态自动机’*。
可以在现代社会的许多设备中观察到状态机的行为,这些设备根据它们所呈现的事件序列执行预定的动作序列。
这与相位结构规则形成对比。阶段结构规则用于将自然语言句子分解成其组成部分,也称为’句法类别’,包括词汇类别(词类)和短语类别
有限状态自动机被递归调用。
“一个有限自动机可以被看作一个只有有限内存量的程序。一个递归自动机就像一个可以使用递归 ( 递归地调用过程和)的程序,但是在它的变量空间中又超过了有限的内存量。[ 递归自动机 ]
1971 年,特里·维诺格拉德在麻省理工学院完成了他的博士论文《SHRDLU》。
这个程序可以在一个受限的儿童积木世界中理解简单的英语句子,以指导机械臂移动物品。
斯坦福 HCI 发布的原始屏幕显示。
这一成功的演示为该领域的继续研究提供了巨大的动力。
维诺格拉德出版了他的书《作为认知过程的语言的 T2》。
这本书可能是有史以来第一部在计算机帮助下对自然语言处理的思想史进行全面、权威和原则性的描述【书评
让这个故事更加有趣的是维诺格拉德后来建议的那个人。
拉里·佩奇是谷歌的创始人之一,特里·维诺格拉德是他的顾问。
20 世纪 70 年代和 80 年代,SRI International 的自然语言处理小组继续进行该领域的研究和开发。
“SRI 国际(SRI)是一个美国非营利性科学研究机构和组织,总部设在加利福尼亚州门洛帕克。斯坦福大学的董事们于 1946 年建立了斯坦福研究所,作为支持该地区经济发展的创新中心。该组织成立时名为斯坦福研究所。斯坦福国际研究所于 1970 年正式脱离斯坦福大学,并于 1977 年更名为斯坦福国际研究所。
1982 ,另外 Gary Hendrix 成立了赛门铁克公司,最初是一家为个人电脑上的数据库查询开发自然语言界面的公司。
然而,赛门铁克改变了方向。
1983 ,Michael Dyer 在耶鲁开发了 BORIS 系统,该系统与 Roger Schank 和 W. G. Lehnert 的工作有相似之处。
在 20 世纪 80 年代和 2010 年之间的几十年里,进步变得更加模糊,这仍然是我需要了解更多的一段时间。至少在自然语言理解方面(NLU)。就 NLP 而言,总体而言,确实取得了进展。
1980 年随着用于语言处理的机器学习算法的引入,自然语言处理发生了一场革命。
计算能力稳步增长,乔姆斯基语言学理论的主导地位逐渐减弱(例如,乔姆斯基语言学理论的理论基础阻碍了语料库语言学的发展,而语料库语言学是语言处理机器学习方法的基础)。
乔姆斯基发展了一套文法的形式理论,其中转换不仅操纵表面字串,也操纵与它们相关的剖析树,使得转换文法成为一套树状自动机系统
最早使用的机器学习算法,如决策树,产生了类似于现有手写规则的硬 if-then 规则系统。
→ 统计模型最近受到了更多的关注,它基于将实值权重附加到组成输入数据的特征来做出软概率决策。
在维基百科的“自然语言处理的历史”页面上有一个最新软件的列表。这可以追溯到 1954 年 T2 的乔治城实验。然而,我选择展示 20 世纪 80 年代到 20 世纪 10 年代。
并非所有这些系统都专注于自然语言理解。
近几十年来,我们看到了其他系统的崛起,如 IBM Watson。
2011 年,沃森计算机系统参加了危险边缘的比赛!对阵冠军布拉德·鲁特和肯·詹宁斯。
一方面,这是一个有趣的进步,另一方面,人们还在争论这样的系统到底有多“理解”**例如根据约翰·塞尔的说法,沃森甚至没有理解这些问题。
认知科学家、帕托姆理论的发明者约翰·鲍尔支持这一评估。
从最近的语音助手可以注意到,如 Siri、亚马逊(Alexa)和谷歌(Nest)这些并不总是理解你。不得不说更近了,现在的人都在用设备对话。
数以亿计的人正在与盒子或智能手机交谈,这些设备在某种程度上可以理解你。
在未来的岁月里,看看我们如何理解或解释语言肯定会很有趣。现在是 2020 年,我们正在接近理解人类如何交流。我们也更接近于理解如何让设备以一种人类可以理解并进行对话的方式进行交流。
我希望你觉得这篇文章很有趣,并且让你对自然语言理解更感兴趣。
当我们理解这个世界的时候,它一定会在某个地方发生变化。虽然我们在任何时候都可能只有有限的理解,但创建一张地图并看看它通向哪里肯定是有趣的。
这可能会导致一些误解。
机器能被编程理解你吗?
照片由 @kristapsungurs 拍摄
这是#500daysofAI,您正在阅读第 425 篇文章。500 天来,我每天都在写一篇关于或与人工智能相关的新文章。
ggvis 简介
例谈图形的语法
Grammar of Graphics是 Leland Wilkinson 在图形领域数十年工作和研究的成果,它为 R 图形库提供了哲学基础,如 ggplot2、ggvis 和 Julia 图形库,如牛虻。虽然,还有其他库可以为您提供真正令人惊叹的图形,但这些包的不同之处在于,它们基于 Wilkinson 所做的研究,该研究试图将图形视为一种语言,并将其分解为单独的组件,就像任何其他语言将其组件分解为主语、动词、宾语等。
威尔金森在 20 世纪 70 年代早期写了一个以其全面的图形而闻名的统计软件包,后来他在 90 年代中期把它卖给了 SPSS。在 SPSS 工作的时候,他写了他的突破性的研究,不久前提到过。他的研究对计算机科学中的图形哲学产生了重大影响。由 Winston Chang 和 Hadley Wickham 维护的Rgg plot 2 中最著名的绘图软件包,其基本原理来自于图形语法。另一个这样的软件包是 ggvis。我们会谈到后者。
由 Jason Coudriet 在 Unsplash 上拍摄的照片
为什么是 ggvis 而不是 ggplot2?
《T21》本身就是一个了不起的包。ggvis 没有从中拿走任何东西,相反,它只是前者的扩展,具有构建 HTML 图形的能力。因为 ggvis 图形是 HTML,所以它们可以用在一个漂亮的 web 应用程序、R markdown 报告中,也可以和 JavaScript 一起使用。一会儿我们会弄清楚其中一些意味着什么。
资源
关于 ggvis 的文档可以在这里找到,还有一个关于数据营的非常好的教程。如需更多信息,您可以访问 ggvis 上的 RStudio 的博客,以及一份关于 图形 语法的简明摘要。本帖的主要目的是探究和理解 ggvis 的语法和句法*。*
$ religiongdp <- read.table("/Users/kovid.rathee/Downloads/ReligionGDP.csv", header=TRUE, sep=",")
$ religiongdp %>% ggvis (~GDP, ~Religiosity) %>% layer_points()
我们首先要了解的是从 马格里特 包中取出的管道操作符 % > % 。这就像壳管操作器的工作一样。
从第一张图片本身来看,这种模式很明显。越是宗教化的国家,越不繁荣(从 GDP、幸福等方面来看)。这里不算,因为我们没有数据)他们是。不过,也有一些例外。但是,我们也可以从数据中看到这一点。为什么要创建图表?因为图表很容易理解。他们讲述完整的故事,而不是一篇十页的文章。他们让我们预测未来——或者至少他们应该让我们预测未来。
religiongdp %>% compute_smooth(GDP ~ Religiosity) %>% ggvis (~pred_, ~resp_) %>% layer_lines(stroke := "darkblue", strokeWidth := 3, strokeDash := 5)
religiongdp %>% compute_smooth(GDP ~ Religiosity) %>% ggvis (~pred_, ~resp_) %>% layer_points(fill := "darkblue", size = 0.5)
回归和趋势线
用一条有点像的线来绘制原始数据。我们可以认为是一条回归线。数据集中的特征不足以进行适当的分类从而猜测一个国家或一个州的 GDP 应该是多少。除了宗教信仰,还有很多更重要的东西,比如人口,政府形式等等。但是,即使从这张图表中,我们也可以粗略地确定 GDP 和宗教信仰之间存在负相关关系——尽管有两个主要的例外,科威特和美国。我们可以称他们为离群值。
虽然橙色趋势线是数据的一个相当不错的表示,但如果我们在这里谈论做出预测,基于不同算法的分类,如 KNearestNeighbour 等。可能需要。这个想法是将所谓的离群值也放入算法运行其原因后将创建的许多类中的一个。
请注意重现右上角的设置按钮。当你点击那个按钮时,它会为你提供一个选项来下载一个 svg 文件或者一个 png 文件。
你想要什么?可缩放矢量图形或便携式网络图形。阅读一些关于什么时候使用哪个的信息。
交互式图表
ggvis 也有别于 ggplot2 ,因为它具有类似*输入滑块的交互功能。*互动性是 *ggvis 的主要成就之一。*它的工作方式与在 Tableau 或 Qlikview 环境中的工作方式相同,但是,当您使用这些库编写自己的代码时,您将对这些图形的渲染方式有更多的控制和更清晰的理解。这里有一个例子:
religiongdp %>% ggvis (~GDP, ~Religiosity) %>% layer_points(fill := "darkblue", size := input_slider (5,15,value=1)) %>% layer_smooths(stroke:="orange", span = input_slider (5,15,value=1))
带有滑块输入的图形。制作了一个非常好的交互式图表,可以嵌入到应用程序中。
iris %>% ggvis(~Sepal.Length,~Sepal.Width,fill=~Species) %>% layer_smooths(span = 2, stroke := “darkred”, strokeDash := 6) %>% layer_smooths(span = 1, stroke := “darkblue”) %>% layer_smooths(span = 0.5, stroke := “orange”)
只需使用%>%运算符,就可以用不同的格式在图上定义不同的线。这让生活变得简单多了。
iris %>% ggvis(~Sepal.Length,~Sepal.Width,fill=~Species) %>% layer_points() %>% add_axis ("x",title="Sepal Length",properties=axis_props(axis=list(stroke="darkblue"),grid=list(stroke="brown",strokeDash=3),ticks=list(stroke="orange",strokeWidth=2),labels=list(angle=45, align="left", fontSize=12)))
著名 Iris 数据集的基本点状图。在这种情况下,我们可以通过颜色来识别花的种类,位置代表了叶子的尺寸——长度和宽度。
iris %>% ggvis (~Sepal.Length,~Sepal.Width) %>% mutate(Sepal.Length = Sepal.Length * 1.5) %>% layer_points(fill=~Species,size=~Petal.Width) %>% add_axis(“x”,title=”Sepal Length”,orient=”top”) %>% add_axis(“y”,title=”Sepal Width”,orient=”right”) %>% add_legend(c(“size”,”fill”),title=”Petal Width”))
在这里,我们试图添加另一个变量到图中。花瓣宽度——除了能够绘制萼片尺寸和通过颜色识别物种,我们还可以通过一个点的强度/大小来表示花瓣宽度。
iris %>% ggvis(x=~Sepal.Length,y=~Petal.Length,fill=~Species) %>% layer_points(opacity=~Sepal.Width) %>% layer_model_predictions(model="lm",stroke:="green",opacity=3)
使用图层模型预测的线性拟合线。有很多预定义的模型可以用来绘图。线性拟合线在这里没有什么意义。但如果是这样的话,它应该是这样的。
iris %>% ggvis(x=~Sepal.Length,y=~Petal.Length,fill=~Species) %>% layer_points(opacity=~Sepal.Width) %>% layer_model_predictions(model="loess",stroke:="green",opacity=3)
可能,不正确的例子使不透明度成为萼片宽度的函数。但这对于可视化变量的强度、严重性和大小非常有用——这些变量无法绘制在 x-y 平面上。
结论
ggvis 是一个很棒的包,它提供了对 ggplot2 的升级,具有许多新时代的功能,如交互式绘图和创建 HTML 绘图的能力,使这些绘图能够嵌入到闪亮的应用程序中等等。威尔金森的工作极大地影响了绘图语言中的话语——这是日常工作,同时进行数据分析、商业智能、机器学习等。
Go-Explore 简介
如何打败最难的雅达利游戏
介绍
这些天我们在机器学习社区看到的是一场真正的军备竞赛:每个月,每个星期研究人员都发表新的论文,声称在数据集上产生最先进的(SOTA)结果。总的来说,我对机器学习的很多领域都感兴趣,所以我真的很难跟上新论文的潮流。在这方面,有一个网站给了我很大的帮助,那就是 paperswithcode ,它展示了对无数不同数据集的 SOTA 模型的全面概述。竞争极其激烈的领域之一是经典的雅达利游戏。就在今年,来自谷歌的研究人员提出了一种新方法来实现两个众所周知的困难游戏陷阱和蒙特祖马的复仇的超人性能。下面是他们是如何做到的。
为什么强化学习很难
首先,我们需要两个来理解为什么特别是这两场比赛如此艰难。强化学习的整个思想是代理人通过从环境中收集奖励来学习。代理人会尝试一系列的行动,并选择能产生最高综合回报的行动组合。最佳环境有非常密集的奖励,所以代理人立即得到反馈,它的行动有多好。这方面的一个例子是吃豆人,那里的迷宫充满了收集的硬币。如果奖励太少,就会出现问题。那么代理缺乏反馈来改进他的行动。根据谷歌的论文,那些稀疏的奖励引发的两个主要问题是脱离和出轨
超脱
为了解决奖励稀少的问题,人们提出了内在奖励的概念。在这里,奖励被人为地均匀分布在整个环境中,以鼓励代理人去探索。
说明超脱的最简单的方法是通过一个简单的图片。请看图 1。这里的 im 是绿色的,分布在两个迷宫中。
图 1:拆卸图【1】
代理从中间开始,首先探索左侧的迷宫。大多数强化学习算法的行为是随机的,所以在某个时间点,代理可能会决定开始探索正确的迷宫。现在的问题是在左边的迷宫中还有一些部分没有被探索,因此仍然有奖励,但是代理不太可能收集它们。原因是强化学习中的另一个问题叫做灾难性遗忘。当一个代理探索一个新的区域时,它会覆盖它过去的经验,因此它访问某个区域的时间越长,情况就越糟。
出轨
为了理解这个问题,我们需要稍微了解一下强化学习算法。在许多环境中,在探索和开发之间存在冲突,即代理人可以采取一条已经众所周知的路径,在这条路径上保证有好的回报(开发),或者执行新的行动,希望这会导致更高的回报,但有接受更低回报的风险(探索)。为了应对这种冲突,许多算法采用了某种ɛ-greedy 策略。这意味着,在大多数情况下,代理将执行尽其所知最佳的动作(利用),但在某些概率下,它将执行随机动作(探索)。这可能会有问题。想象一个智能体想要达到某个状态,而这个状态只有通过一系列动作的组合才能达到。代理甚至不太可能达到这种状态,因为在这个过程中,它将执行许多不同的动作,偏离了实际所需的路径。
去探索
谷歌的研究人员已经开发出一种方法来解决分离和出轨。它包括两个不同的阶段,即探索阶段和强健阶段。
第一阶段:探索
这个阶段没有使用任何神经网络或其他机器学习算法,而是完全基于随机(可能是半指导)探索。在这里,作者介绍了细胞的概念。单元格是实际游戏帧的缩小和灰度图像(图 2)。
图 2:从帧到单元格【1】
这里的主要目标是找到感兴趣的细胞。那些是什么?有趣的细胞,以前没有发现,并在那里的代理收集了高奖励,以达到目的。每当发现新的单元时,四个值被添加到单元档案中:
- 这个细胞的完整轨迹
- 该牢房的环境状况
- 该轨迹实现的总回报
- 这个轨迹的长度
如果遇到已经在档案中的细胞,则相应的条目被更新,以防它“更好”,即更高的总回报或更短的轨迹。
在每次迭代中,该算法执行以下操作:
- Go: 使用试探法选择一个“好的”单元格,然后前往该单元格。试探可能选择具有最高总回报、最少访问等的单元。
- **探索:**执行随机动作,从这个有希望的细胞中寻找新的细胞。同样:这是随机的,没有政策或网络来选择一个动作。
这两个步骤有助于防止脱轨和脱离。我们建立了一个状态以及如何到达那里的档案,所以好的状态不会丢失(防止分离)。第一步,我们直接去国家,没有政策,因此没有随机行动。出轨也因此得以避免。
第二阶段:强健
第一阶段做了一个巨大的隐含假设:我们的环境是决定性的。为了从我们的档案中“转到”某个单元,我们需要能够重置环境,并确保我们存储的一系列操作确实会导致我们想要的“好”单元。这在电脑游戏中很容易实现,尤其是在简单的 Atari 游戏中,因为在这里相同的动作总是会导致相同的结果。但是当然,人们也想在现实世界中使用强化方法,这通常很难确定。这就是我们需要这个第二阶段的目的:使我们通过随机探索发现的良好结果细胞的轨迹对噪声和非确定性更加鲁棒。
为此,本文使用了所谓的向后算法。图中,我们有一系列单元格 c(1),c(2),…,c(n-1),c(n),我们在探索阶段发现这些单元格非常好,现在想做得更健壮。在第一步中,我们将我们的环境设置为 c(n-1 ),并训练一个强化算法来执行达到 c(n)所必需的动作。如果这个算法找到了一条轨迹,与我们随机找到的相比,它得到了相同或更高的回报,我们就返回到 c(n-2),并试图从那里到达 c(n)。这是一个不断重复的过程,直到我们找到一个好的策略,找到一系列从 c(1)(开始状态)到 c(n)(结束状态)的动作。
如上所述,Atari 游戏是确定性的,但我们希望使我们的策略对非确定性更加鲁棒。那么,该怎么办呢?在我们的环境中引入噪声有两种相对简单的方法:
- 没有操作:雅达利游戏有一个内置的计时器,它可以确定某些危险是否存在,或者危险和敌人在哪里。因此,如果我们在游戏开始时等待随机数量的帧,世界将总是处于稍微不同的状态。
- 粘性动作:人类玩得不完美。他们的反应需要一些时间,所以他们有时按下按钮的时间比他们应该按的时间要长。强化算法通过粘性动作来模拟这一点,即根据算法的策略,随机执行动作的时间比应该执行的时间稍长。
结果
使用 Go-Explore 方法获得的结果是杰出的:不仅比任何其他强化算法执行得更好,而且它们还在超人的水平上运行(图 3)。
图 3:Go-探索蒙特祖马的复仇与其他方法的性能对比【1】
来源
[1] A. Ecoffet,J. Huizinga,J. Lehman,K. O. Stanley 和 J. Clune: Go-Explore:一种解决难探索问题的新方法 (2020)
新冠肺炎数据来源简评
一些流行的新冠肺炎数据源的利与弊
作为一名数据科学家,我一直在寻找分析疫情冠状病毒的“最佳”数据源。不幸的是,周围有这么多不同的来源,每一个都有点不同。以下是截至 2020 年 3 月 26 日的简短回顾。我将介绍以下数据源的优点和缺点,以便您可以选择最适合您需求的数据源:
更新 2020–03–30:世界计量、美国事实、和纽约时报在#5 丁香元之后讨论。
简而言之,如果不需要 API,那么 1Point3Acres 的数据和可视化最好。
如果你确实需要一个 API,那么 【约翰霍普金斯】 的数据,连同**COVID 跟踪项目 的信息,为测试提供了一个很好的起点。**
以下是详细内容。
1.3 亩:
如果您正在寻找美国新冠肺炎数据,并且您不需要 API,那么就不要再找了。这是最好的网站。
优势:
- 有关于确认和死亡人数的县级详细信息。这是我找到的唯一包含此信息的数据源。
- 来自许多其他来源的综合信息。比如测试数据(来自https://covidtracking.com/)、各种来源的新闻、来自 YouTube 的相关视频等。
- 非常可靠和高质量的数据,甚至美国疾病控制和预防中心每天都使用它的数据。
- 非常好的视觉效果。便于读者选择自己感兴趣的状态。和其他国家对比也毫不费力。而《赛车》条形图(使用花枝作为后端)也很有信息量,在其他网站很少见到。
****
缺点:
- 没有公共 API。如果您想以编程方式使用他们的数据,那么您需要联系他们。
- 关注美国和加拿大。如果你的主要兴趣在其他地方,那么这不是你的来源。
约翰霍普金斯 CSSE (系统科学与工程中心)
如果您正在寻找全球数据,这是要去的数据源。自冠状病毒流行早期以来,它就被广泛引用。
优势:
- 涵盖世界各地的数据封面。
- 2020 年 3 月 22 日及之后的数据包含美国的县级数据。
- 数据在 GitHub 中公开,并在世界各地积极开发和使用。这样你就可以轻松地自己玩了。事实上,大多数其他数据源都是建立在这个数据集之上的。例如,您可以通过以下方式获取 2020 年 3 月 25 日的每日报告 CSV:
缺点:
- 2020 年 3 月 22 日之后的美国县级信息。考虑到美国已于 2020 年 3 月 13 日宣布全国进入紧急状态,这并不理想。纽约时报数据源(本文后面会提到)有自 2020 年 1 月 21 日以来的县级信息。
- 仪表板 GUI 的信息量小于 1Point3Acres。除了地图,您只能看到确诊病例和每日增加病例的时间序列图。您无法比较不同的区域,无法查看对数比例的图,等等。
COVID 跟踪项目
如果您只需要美国的数据,并且您需要一个 API,那么这就是要去的数据源。
这是一个独特的数据源,因为它不仅包含已确认/死亡人数,还包含美国的测试数据,即阳性和阴性结果、待定测试和测试总人数。这些信息非常有价值,因为它揭示了许多尚未“确认”的“实际”患者人数的信息。这些测试数据也被 1Point3Acres 用在他们的网站上。
优势:
- 包含测试数据
- API (Google sheet、CSV、JSON、download 和 API 端点)公开可用,并且非常容易使用。例如,您可以通过以下方式获取每日 JSON 和 CSV:
缺点:
- 没有县级数据
- 没有全局数据
ka ggle 新型冠状病毒数据集
如果您想要构建医疗细节的统计数据,这是首选的数据源。
优势:
- 使用约翰霍普金斯大学 CSSE 分校的数据作为主要的底层数据源
- 有几千个病例的医学细节,如症状、旅行史、慢性病等。它还可以通过谷歌电子表格格式获得。
弱点:
- 与约翰霍普金斯大学的数据基本相同。在 2020 年 3 月 22 日之前没有县数据,也没有测试数据。
Ding Xiang Yuan (丁香园)
如果你正在为中国寻找最好的数据,这是可以去的数据源。这是公众可以获得的最早的数据来源。自 2020 年 1 月冠状病毒爆发以来,它已被广泛使用。
优势:
- 包含中国最早和最详细的(市级)数据
缺点:
- 没有公共 API。但是,你可以在 GitHub 中找到网络爬虫,它从丁象元获取数据。比如艾萨克·林的时间序列数据仓库。这也是我在这篇媒体文章中为自己的 GitHub 项目分析中国疫情数据时使用的数据源。
- 网站上的可视化是原始的。没有适当的组织,所有的图都挤在一起,并且没有可用的对数比例图。
- 全球数据只有国家总数,没有细分到各州。
更新 2020 年 3 月 30 日:
世界计量表
总的来说,我更喜欢约翰·霍普金斯大学 CSSE 分校。在 Worldometers 没有提供太多的信息,但在约翰霍普金斯 CSSE 大学没有。查看该网站的唯一原因是它将已确认的数量分为轻度和严重/危急。然而,该网站没有说明这种分裂的来源或方法,因此很难判断他们有多可信。
美国事实
一般来说,我更喜欢 1Point3Acres 而不是 USAFacts。两个网站都提供县级信息。但是 1Point3Acres 具有更好的可视化效果,如对数标度图、州级图、赛车条形图等。此外,1Point3Acre 可以轻松地将数字与其他国家进行比较,而 USAFacts 则不能。
然而,尽管 USAFacts 没有任何 API,但它确实提供了县一级确诊和死亡人数的下载链接:
死亡:https://usafactsstatic . blob . core . windows . net/public/data/新冠肺炎/covid_deaths_usafacts.csv
纽约时报数据集
纽约时报从 2020 年 3 月 27 日开始在 GitHub 上发布他们的数据集。如果您正在寻找美国的县级数据集,这是一个不错的去处。然而,据我所知,他们的县级数字加起来并不完全是州总数。另外,纽约时报的数据有点延迟,你可能要等到第二天才能得到更新的每日数据。
还有,他们没有测试数据,也没有国际数据。所以如果你需要这些信息,你需要从其他地方合并。
最后的话
我见过的大多数其他数据源都是从这些数据源中的一个或多个派生出来的。如果你看到任何其他好的数据来源,请不要犹豫,给我留下评论。谢了。
承认
我要感谢我的朋友 David Tian,他是一名机器学习工程师,他对本文提出了宝贵的建议。看看他有趣的自驾 DeepPiCar 博客。
朴素贝叶斯分类及其实现的简短教程
朴素贝叶斯从计数开始,然后转向概率
图片来源:Unsplash
朴素贝叶斯分类是数据挖掘或机器学习中最简单和最流行的算法之一(被 CRC Press Reference [1]列为十大流行算法)。朴素贝叶斯分类的基本思想非常简单。
(如果你觉得视频格式更适合你,可以跳这里你也可以去笔记本。)
基本直觉:
比方说,我们有两类书。一类是体育,一类是机器学习。我统计了“匹配”(属性 1)和“算法”(属性 2)这两个词的出现频率。让我们假设,我从这两个类别各有 6 本书,这 6 本书的字数如下图所示。
图 1:书籍中的字数
我们清楚地看到,“算法”这个词更多地出现在机器学习的书籍中,“比赛”这个词更多地出现在体育运动中。有了这些知识,假设我有一本书,它的类别是未知的。我知道属性 1 的值是 2,属性 2 的值是 10,我们可以说这本书属于体育类。
基本上,我们想要找出哪一个类别更有可能,给定属性 1 和属性 2 的值。
图 2:根据数量查找图书的类别
从计数到概率:
这种基于计数的方法适用于少量类别和少量单词。使用条件概率可以更好地遵循同样的直觉。
图 3:条件概率(图片来源:作者)
有一个例子可以更好地理解条件概率
让我们假设
事件 A:面值为奇数|事件 B:面值小于 4
P(A) = 3/6(有利情况 1,3,5 总情况 1,2,3,4,5,6)类似地 P(B)也是 3/6(有利情况 1,2,3 总情况 1,2,3,4,5,6)。条件概率的一个例子是,给定一个小于 4 的奇数(A)的概率是多少(B)。为了找到这一点,我们首先找到事件 A 和 B 的交集,然后除以情况 B 中的案例数。更正式地说,这由以下等式给出
图 4:条件概率(图片来源:作者)
P(A|B)是条件概率,读作给定 B 的概率。这个等式构成了中心原则。现在让我们再回到我们的图书类别问题,我们想更正式地找到图书的类别。
条件概率到朴素贝叶斯分类器
让我们使用下面的符号 Book=ML 是事件 A,book=Sports 是事件 B,“属性 1 = 2,属性 2 = 10”是事件 C。事件 C 是一个联合事件,我们一会儿就会谈到这一点。
因此问题变成这样,我们计算 P(A|C)和 P(B|C)。假设第一个值为 0.01,第二个值为 0.05。那么我们的结论将是这本书属于第二类。这是一个贝叶斯分类器,朴素贝叶斯假设属性是独立的。因此:
P(属性 1 = 2,属性 2 = 10) = P(属性 1 = 2) * P(属性= 10)。我们把这些条件分别称为 x1 和 x2。
图 5:用条件概率寻找类(图片来源:作者)
因此,使用可能性和先验,我们计算后验概率。然后,我们假设属性是独立的,因此可能性扩展为
图 6:扩展条件概率
上面的等式显示了两个属性,但是,可以扩展到更多。因此,对于我们的特定场景,等式变为如下。它仅在 Book='ML '中显示,在 Book ='Sports '中也会类似地显示。
图 7:书籍的朴素贝叶斯方程示例(图片来源:
实施:
让我们使用著名的朴素贝叶斯流感数据集,并导入它,你可以改变路径。你可以从这里下载数据。
导入数据:
图 8:流感数据集
nbflu=pd.read_csv('/kaggle/input/naivebayes.csv')
数据编码:
我们将列存储在不同的变量中,并对它们进行相同的编码
**# Collecting the Variables**
x1= nbflu.iloc[:,0]
x2= nbflu.iloc[:,1]
x3= nbflu.iloc[:,2]
x4= nbflu.iloc[:,3]
y=nbflu.iloc[:,4]# **Encoding the categorical variables**
le = preprocessing.LabelEncoder()
x1= le.fit_transform(x1)
x2= le.fit_transform(x2)
x3= le.fit_transform(x3)
x4= le.fit_transform(x4)
y=le.fit_transform(y)**# Getting the Encoded in Data Frame**
X = pd.DataFrame(list(zip(x1,x2,x3,x4)))
模型拟合:
在这一步中,我们将首先训练模型,然后为患者进行预测
model = CategoricalNB()
*# Train the model using the training sets*
model.fit(X,y)
*#Predict Output*
*#['Y','N','Mild','Y']*
predicted = model.predict([[1,0,0,1]])
print("Predicted Value:",model.predict([[1,0,0,1]]))
print(model.predict_proba([[1,0,0,1]]))
输出:
Predicted Value: [1]
[[0.30509228 0.69490772]]
输出表明不流感的概率是 0.31,流感的概率是 0.69,因此结论是流感。
结论:
朴素贝叶斯作为基线分类器工作得非常好,它速度快,可以处理较少数量的训练样本,可以处理有噪声的数据。挑战之一是它假设属性是独立的。
参考:
[1]吴 X,库马尔 V,编者。数据挖掘的十大算法。CRC 出版社;2009 年 4 月 9 日。
[2]https://towards data science . com/all-about-naive-Bayes-8e 13 cef 044 cf
一种构建推荐系统的简单方法
利用惊喜包在 Python 中构建协同过滤推荐器
具有协同过滤的示例推荐系统。莫莉·里伯斯金图片。
要理解推荐系统的力量,最简单的方法就是关注网飞,他最先进的推荐系统让我们在电视机前呆上几个小时。然而,推荐人是极其多样化的,他们在交叉销售产品、确定具有相似技能的员工候选人以及寻找会对促销信息做出回应的客户方面发挥着作用。这些例子仅仅触及了如何使用推荐系统的表面。
尽管推荐器可能非常复杂,但有两种简单的方法可以作为一个良好的起点。
- 基于内容的过滤:使用项目特征来推荐与用户以前喜欢或交互过的项目相似的项目。潘多拉的音乐基因组项目识别每首歌曲的音乐属性,并利用这些信息找到相似的歌曲并做出推荐。
- 协同过滤:根据相似用户对每个项目的评价来确定用户喜欢的项目。网飞通过确定相似用户观看的内容来识别用户喜欢的节目和电影。
这篇文章将重点介绍使用巴西电子商务公司 Olist 发布的销售交易数据开发一个协同过滤推荐系统。
入门指南
为了构建推荐器,我们将使用 Surprise ,一个为协同过滤而构建的 Python scikit 包。
第一步是加载我们需要的包和数据集。数据集由 8 个表组成,但是出于演示的目的,我已经连接了表并隔离了我们需要的列。完整代码在这里。
#Import packages **import** pandas **as** pd
**import** matplotlib.pyplot **as** plt
**import** seaborn **as** sns**from** surprise **import** NormalPredictor, Reader, Dataset, accuracy, SVD, SVDpp, KNNBasic, CoClustering, SlopeOne**from** surprise.model_selection **import** cross_validate, KFold, GridSearchCV, train_test_split#import dataset
olist_data = pd.read_csv('olist_data.csv')
正如现实世界的数据经常发生的那样,这个数据集不是为创建协作推荐系统而完美构建的。这里的一个大挑战是,几乎 90%的用户都是第一次购买,这意味着我们没有他们以前的评分来确定喜欢的产品。相反,我们将把数据集分为重复用户和首次用户,并且只把重复用户输入到协作过滤模型中。对于第一次购买的顾客,我们仍然可以提供推荐,但它们会更加通用,侧重于商品的受欢迎程度和用户的位置。
**def** repeat_and_first_time(data): repeaters = data.groupby('customer_unique_id').filter(**lambda** x: len(x) > 1)
first_timers = data.groupby('customer_unique_id').filter(**lambda** x: len(x) == 1)
**return** repeaters, first_timers
利用惊喜
为了利用 surprise 内置的用户评级矩阵转换,我们需要提供一个包含用户 id 列、项目 id 列和评级列的数据框架。
**def** create_user_ratings_df(data):
df = data.groupby(['customer_unique_id','product_id'])['review_score'].agg(['mean']).reset_index()
df = df.rename({'mean':'estimator', 'product_id':'productId'}, axis=1)
**return** dfuser_ratings_df = create_user_ratings_df(repeater_data)user_ratings_df.head()
用户评级矩阵示例。莫莉·里伯斯金图片。
从这里开始,Surprise 将帮助我们生成一个用户评级矩阵,其中每个用户 id 是一行,公司提供的每个产品是一列。这将产生与创建熊猫数据透视表相同的效果。我们将用 80/20 分区将数据帧分成训练集和测试集。
**def** surprise_df(data):
scale = (data.estimator.min(), data.estimator.max())
reader = Reader(rating_scale=scale)
df = Dataset.load_from_df(data[['customer_unique_id',
'productId',
'estimator']], reader)
**return** dfuser_ratings_matrix = surprise_df(user_ratings_df)train_set, test_set = train_test_split(user_ratings_matrix, test_size=0.2, random_state=19)
惊喜提供了 11 种不同的预测算法,包括各种 KNN 和维数缩减技术,如奇异值分解和 NMF。在本次演示中,我们将测试一些最常见的技术。
使用 5 重验证,我们将比较以下模型的结果。
- NormalPredictor:根据假定为正态的训练集分布预测随机评级的基线模型。
- 奇异值分解:一种矩阵分解技术,作为网飞奖的一部分由西蒙·芬克推广。
- KNNBasic:利用余弦相似性(或用户确定的距离度量)来执行 KNN。
- 协同聚类:一种算法,以类似于 k-means 的方法为聚类分配点数。
有两种方法可以评估模型性能。定性地说,你可以观察一个给定的用户,考虑到他们喜欢的其他产品,确定这个推荐是否有意义。例如,如果有人喜欢恐怖电影,不喜欢浪漫喜剧,《闪灵》相对于真爱会是一个不错的推荐。对于这个数据集,我们没有每个产品的信息,只有一个产品 id,所以我们将使用一个定量的测量方法,均方根误差。这两种方法的结合是理想的,尽管定量测量在生产中更现实。
kf = KFold(n_splits=5, shuffle=**True**, random_state=19)**def** model_framework(train_data): #store the rmse values for each fold in the k-fold loop
normp_rmse, svd_rmse, knn_rmse, co_rmse, slope_rmse = [],[],[], [],[]
**for** trainset, testset **in** kf.split(train_data):
*#baseline*
normp = NormalPredictor()
normp.fit(trainset)
normp_pred = normp.test(testset)
normp_rmse.append(accuracy.rmse(normp_pred,verbose=**False**))
*#svd*
svd = SVD(n_factors=30, n_epochs=50,biased=**True**, lr_all=0.005, reg_all=0.4, verbose=**False**)
svd.fit(trainset)
svd_pred = svd.test(testset)
svd_rmse.append(accuracy.rmse(svd_pred,verbose=**False**))
*#knn*
knn = KNNBasic(k=40,sim_options={'name': 'cosine', 'user_based': **False**}, verbose=**False**)
knn.fit(trainset)
knn_pred = knn.test(testset)
knn_rmse.append(accuracy.rmse(knn_pred,verbose=**False**))
*#co_clustering*
co = CoClustering(n_cltr_u=3,n_cltr_i=3,n_epochs=20)
co.fit(trainset)
co_pred = co.test(testset)
co_rmse.append(accuracy.rmse(co_pred,verbose=**False**))
mean_rmses = [np.mean(normp_rmse),
np.mean(svd_rmse),
np.mean(knn_rmse),
np.mean(co_rmse),
np.mean(slope_rmse)]
model_names = ['baseline','svd','knn','coclustering','slopeone']
compare_df = pd.DataFrame(mean_rmses, columns=['RMSE'], index=model_names)
**return** compare_dfcomparison_df = model_framework(train_set)
comparison_df.head()
莫莉·里伯斯金图片。
基于以上所述,我们确定 SVD 具有最低的 rmse,并且是我们将继续调整的模型。
模型调整:惊奇的网格搜索
这个令人惊讶的包提供了一个使用 GridSearchCV 调整参数的选项。我们将为 GridSearchCV 提供一个参数字典,并计算和比较每个参数组合的 rmse。
**def** gridsearch(data, model, param_grid):
param_grid = param_grid
gs = GridSearchCV(model, param_grid, measures=['rmse'], cv=5)
gs.fit(data)
new_params = gs.best_params['rmse']
best_score = gs.best_score['rmse']
print("Best score:", best_score)
print("Best params:", new_params)
**return** new_params, best_scoresvd_param_grid = {'n_factors': [25, 50,100],
'n_epochs': [20,30,50],
'lr_all': [0.002,0.005,0.01],
'reg_all':[0.02,0.1, 0.4]}
svd_params, svd_score = gridsearch(train_set, SVD, svd_param_grid)
从该搜索中,我们得到一个输出,告诉我们获得的最佳分数(最低 rmse)是 1.27,它是使用参数{‘n_factors’: 25,’ n_epochs’: 50,’ lr_all’: 0.01,’ reg_all’: 0.1}产生的。
最终模型和指标
利用上面的参数,我们然后在没有交叉验证的完整训练集上运行该模型,并根据测试集获得准确度分数。
**def** final_model(train_set, test_set):
params = {'n_factors': 10, 'n_epochs': 50, 'lr_all': 0.01,
'reg_all': 0.1}
svdpp = SVDpp(n_factors=params['n_factors'],
n_epochs=params['n_epochs'],
lr_all=params['lr_all'],
reg_all=params['reg_all'])
svdpp.fit(train_set)
predictions = svdpp.test(test_set)
rmse = accuracy.rmse(predictions,verbose=**False**)
**return** predictions, rmse
final_predictions, model_rmse = final_model(train_set, test_set)
的。测试属性输出预测,其中包含用户 id、项目 id、用户实际评级、模型估计评级以及可能做出预测的指示器。除了查看来自最终训练模型的 model_rmse 输出,我们还将查看所有预测的绝对误差分布。为此,我们将把预测输出打包到一个数据帧中,并添加一个列来指示每个预测的错误。然后,我们将通过绘制误差直方图来可视化结果。
results = pd.DataFrame(final_predictions, columns=['userid', 'item_id', 'user_rating', 'model_est', 'details'])
results['err'] = abs(results.model_est - results.user_rating)
在下面的图中,我们看到,尽管完整数据集的误差为 1.0,但当用户给产品的评分高于 3 时,模型做出了更好的预测,误差仅为 0.8。相比之下,当用户给产品打 3 分或 3 分以下的分数时,误差明显更高,为 1.5 分。这是一个很好的结果,因为为了提供好的推荐,我们更关心准确预测用户喜欢并评分高于 3 的产品。
比较整体模型误差与等级> 3 和等级≤3 的误差的图。莫莉·里伯斯金图片。
然后,可以使用转储模块对模型进行打包,转储模块是 Pickle 的包装器。对于这个例子,协同过滤推荐只是整个系统的一部分。它根据每个地理区域的总体畅销产品和最佳表现者进行推荐。
附加注释
为了熟悉这个过程,Surprise 有一些很好的内置数据集,文档详细解释了不同的交叉验证方法、相似性度量和预测算法。
目前,Surprise 还不能处理隐式评级、执行内容过滤或生成混合推荐。然而,对于初学者来说,Surprise 是一个简单直接的协作过滤包。
你可以在 github 上找到这个例子的所有代码。
Python 中的简单突破交易策略
对客观的系统突破策略进行编码和回溯测试
注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
我刚刚出版了一本新书《Python 中的新技术指标》。它对复杂的交易策略进行了更完整的描述和补充,Github 页面致力于不断更新代码。如果你对此感兴趣,请随时访问下面的链接,或者如果你喜欢购买 PDF 版本,你可以在 Linkedin 上联系我。
亚马逊网站:交易策略之书(9798532885707): Kaabar,Sofien:书籍
www.amazon.com](https://www.amazon.com/gp/product/B09919GQ22/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B09919GQ22&linkCode=as2&tag=sofien-20&linkId=bc5df3f6ab0f3af2df79641c56b949ba)*
交易分为许多不同的策略,依赖于趋势跟踪、均值回归、波动性或其他因素。成功的策略依赖于当前的市场状态,例如,当市场趋势强劲时,均值回归策略往往会失败,因此我们必须相应地调整我们的市场方法。下面是一个突破策略,它使用了一个叫做唐奇安通道的指标。基本的想法是让区间尽可能客观(即可以衡量),然后在突破时交易(即趋势的开始)。因此,本文的目的是看这个指标是否能增加我们整个交易系统的价值。它能提供好的信号吗?这些触发因素值得认真对待吗?
唐奇安海峡
理查德·唐奇安创造了这个简单而伟大的指标,用来识别突破和反转。就像布林线一样,它的使用方式也差不多。我们的目标是通过超越或突破任何障碍来客观地确定区间出场。它的形成方法是首先计算最近 n 个周期高点的最大值和最近 n 个周期低点的最小值,然后计算它们的平均值。这给了我们三个小节:唐奇安高频带、低频带和中频带。下面是数学公式,随后是用于 OHLC 数据结构的 Python 代码。
*def donchian(Data, low, high, where_up, where_down, median, period):
for i in range(len(Data)):
try:
Data[i, where_up] = max(Data[i - period:i + 1, 1])
except ValueError:
pass
for i in range(len(Data)):
try:
Data[i, where_down] = min(Data[i - period:i + 1, 2])
except ValueError:
pass
for i in range(len(Data)):
try:
Data[i, median] = (Data[i, where_up] + Data[i, where_down]) / 2
except ValueError:
passdonchian(Data, 2, 1, 4, 5, 6, 20)'''
plt.plot(Data[-500:, 3], color = 'black')
plt.plot(Data[-500:, 4])
plt.plot(Data[-500:, 5])
plt.plot(Data[-500:, 6])
plt.grid()'''*
从视觉上看,唐奇安通道似乎包围了价格,这是可以理解的,因为它考虑了当前的极端情况,因此市场永远不会位于通道之外。
欧元兑美元 H3 时间框架和 20 期唐奇安通道。
制定战略
唐奇安海峡的基本战略是突围战略。它直观而清晰,下面是规则:
- 当市场超过最后一个上升通道时买入。
- 每当市场突破最后一个较低通道时,卖出(做空)。
*def donchian_signals(Data, onwhat, donch_up, donch_down):
for i in range(len(Data)):
if Data[i, where_close] > Data[i - 1, donch_up]:
Data[i, 6] = 1
elif Data[i, where_close] < Data[i - 1, donch_down]:
Data[i, 7] = -1
return Data# Note: The onwhat variable is the closing price*
我们选择最后的唐奇安水平,因为我们想知道我们什么时候打破我们最后的高点或低点。请记住,该公式考虑了当前的最高价和最低价,因此当前价格永远不会突破它们。
回测选择的条件更多的是长期突破,因为我们使用的是 60 天的日线图。这意味着,如果市场超过了过去 60 天的上唐奇安通道,那么我们买入趋势。我在下面的三个测试货币对中加入了一个简单的 100 点的止损单。我选择了三个主要的货币对作为这个策略的代理,它们是欧元兑美元,美元兑瑞士法郎和 GBPUSD。下面的图表显示了三个后验测试的信号图。
欧元兑美元、美元兑瑞郎和 GBPUSD 的信号图。绿色箭头表示买入订单,而红色箭头表示卖出订单。
出于比较的原因,在 10,000 美元的手数中,每笔交易 0.5 点后的净值曲线。初始余额为 1000 美元,因此杠杆比率为 1:100。
遵循唐奇安策略的权益曲线。
如果你也对更多的技术指标和使用 Python 创建策略感兴趣,那么我关于技术指标的畅销书可能会让你感兴趣:
亚马逊网站:Python 中的新技术指标:9798711128861: Kaabar,Sofien 先生:书籍
www.amazon.com](https://www.amazon.com/gp/product/B08WZL1PNL/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B08WZL1PNL&linkCode=as2&tag=sofien-20&linkId=e3cb9716bb6a07cf6c8b9fb585412b07)
显然,它需要一些改进,唐奇安通道应该有另一个指标,以确认信号或增加波动因素,稳定结果。
唐奇安突围战略的绩效表。*
这里还可以采用另一种策略。它依赖于中间波段。我们可以尝试使用与上述相同的回溯测试条件来开发基于它们的策略。从上面的介绍中我们知道,中间波段只是上下波段的平均值,因此它可以与布林线的移动平均值相比较。如果你有兴趣了解更多关于布林线的信息,你可以查看这篇文章,我提供了更多的回溯测试:
* [## 使用 RSI 和布林线创建交易策略。使用 Python 的新想法。
绝大多数交易者使用著名的相对强弱指数来帮助他们做决定,虽然它…
medium.com](https://medium.com/swlh/creating-a-trading-strategy-using-the-rsi-the-bollinger-bands-new-ideas-using-python-4115e1fdfbba)
因此,中间波段策略的规则是:
- 当市场超过中间波段时买入。
- 每当市场突破中间波段时,卖出(做空)。
欧元兑美元日时间框架与唐奇安 60 天中间带。
def donchian_signals_middle(Data, onwhat, donch_middle, buy, sell):
for i in range(len(Data)):
if Data[i, onwhat] > Data[i, donch_middle] and Data[i - 1, onwhat] < \
Data[i, donch_middle]:
Data[i, buy] = 1
elif Data[i, onwhat] < Data[i, donch_middle] and Data[i - 1, onwhat] > \
Data[i, donch_middle]:
Data[i, sell] = -1# Note: The buy and sell variables are the triggers (equivalent to column 6 and 7 in the first strategy code)
第二种策略的信号图如下:
欧元兑美元、美元兑瑞郎和 GBPUSD 的信号图。绿色箭头表示买入订单,而红色箭头表示卖出订单。
股权曲线就没那么令人印象深刻了。
遵循唐奇安中带策略的权益曲线。
东中带突破策略表现表。
结论
虽然第一个策略显示了一些潜力,但第二个策略未能给人留下深刻印象。很明显,唐奇安通道还有很多事情要做,但是很高兴知道我们可以尝试量化范围和交易突破。
https://pix abay . com/illustrations/entrepreneur-idea-competence-vision-4313671/*
ROC 曲线改变了我们看待分类问题的方式
没有一种机器学习算法能最好地解决所有问题
接收器工作特性(ROC) 曲线是一条概率曲线,它说明了我们的二元分类在基于真阳性率和假阳性率进行分类时有多好。
曲线下面积(AUC) 是一个范围从 0 到 1 的指标。它是(ROC)曲线下的面积。
ROC 曲线和 AUC 的示例。资料来源:Huy Bui
动机
为什么理解 ROC 曲线和 AUC 对数据科学家很重要?为了回答这个问题,我们来看看下面的乳腺癌数据集:
from sklearn.datasets import load_breast_cancer
import pandas as pddata=load_breast_cancer()
columns=data.feature_names
X=pd.DataFrame(data.data, columns=columns)
y=pd.DataFrame(data.target, columns=['Target'])
df=pd.concat([y,X],axis=1)
乳腺癌数据集:591 个观察和 30 个特征。资料来源:Huy Bui
当处理分类问题时,应该考虑准确性的折衷。如果医院使用这些数据来检测乳腺癌,模型应该强调从患者身上检测癌症的能力。该模型还需要小心翼翼地将可能被错误标记为癌症的健康患者的数量降至最低,因为癌症治疗的副作用可能会很严重。
该数据集的目标是恶性(1)和良性(0)。让我们看看下面的直方图:
良性和恶性的分布。资料来源:Huy Bui
通常,对于这种类型的问题,数据集更加不平衡。根据美国乳腺癌统计数据,12%的美国女性在其一生中将发展为浸润性乳腺癌。然而,这只是出于教育目的,我们可以忽略数据集的现实方面。
如上所述,我们需要在召回和假阳性率之间找到一个好的平衡。你可能会问为什么是假阳性率而不是精确度。提醒一下:
**回忆:**也叫真阳性率(TPR)。TPR 是正确的癌症预测与癌症病例总数之间的比率。从数学上来说, TPR=TP/(TP+FN) 其中 FN 是那些被错误归类为良性的。
精度:所有正确癌症与预测癌症总数之比。精度 = TP/(TP+FP)
假阳性率: FPR=FP / (TN+FP)
根据数学公式,我们可以看出精度和 FPR 之间的区别。Precision 关注模型检测癌症的能力。相反,FPR 关注的是癌症检测的失败率。如果你想了解更多,这里有一个关于精确召回(PR)和 FPR 召回(ROC)的长时间讨论。
简而言之,只有当正面类比负面类有趣得多,并且正面/负面比率很小(严重不平衡)时,我们才应该使用精确回忆。然而,在这种情况下,良性肿瘤约占恶性肿瘤的 4/7,这表明数据只是轻度不平衡。正如我们上面讨论的,错误分类的癌症可能会导致不良后果。因此,在这里使用 ROC 曲线是合理的。
注意:精确召回的方法与 ROC 曲线非常相似,你可以在这里找到它的文档。
受试者工作特征曲线
我们将要使用的模型是逻辑回归。通常,当我们进行分类时,输出已经被某个阈值四舍五入。ROC 曲线使用不同的阈值来绘制 TPR-FPR 之间的关系。因为我们想要研究 TPR、FPR 和阈值之间的关系,所以让我们在舍入之前先看看逻辑回归输出。
from sklearn.linear_model import LogisticRegressionlogreg = LogisticRegression(fit_intercept=False, C=1e12, solver='liblinear')
logreg.fit(X, y.values.flatten())
prediction=logreg.decision_function(X) #Values before the ouput#Define positive and negative
cancer_index=y[y.Target==1].index
no_cancer_index=y[y.Target==0].index
cancer_prob=prediction[cancer_index]
no_cancer_prob=prediction[no_cancer_index]#Histogram
n_bins = 20
fig, axs = plt.subplots(1, 2, sharey=True, tight_layout=True)
axs[0].hist(cancer_prob, bins=n_bins)
axs[1].hist(no_cancer_prob, bins=n_bins)
plt.show()
在做出边界决定之前,评估良性和恶性之间的频率。资料来源:Huy Bui
如果我们使用核密度估计将这两个直方图放在一起,并截断一些异常值,我们会获得一个漂亮的图形:
两类决策边界
蓝线是决策边界。它将图表分为 4 个部分:
- 纯绿色:无癌症(真阴性)
- 纯红色:癌症(真阳性)
- 左侧混合:有癌症,但被检测为无癌症(假阳性)
- 右混合:没有癌症,但被检测为患有癌症(假阴性)
注意,一个好的二进制分类模型将最小化混合区域。因此,在获得一个好的模型后,研究 ROC 曲线将告诉我们我们的模型是否在 TPR 和 FPR 之间做了很好的平衡。下面我们来看看 ROC 曲线:
from sklearn.metrics import roc_curve, auc# Normalize the Data
X = X.apply(lambda x : (x - x.min()) /(x.max() - x.min()),axis=0)
X_train, X_test, y_train, y_test = train_test_split(X, y.values.flatten(), random_state=0)y_score = logreg.fit(X_train, y_train).decision_function(X_test)
fpr, tpr, thresholds = roc_curve(y_test, y_score)def ROC_curve(fpr,tpr):
# Seaborn's beautiful styling
sns.set_style('darkgrid', {'axes.facecolor': '0.9'})print('AUC: {}'.format(auc(fpr, tpr)))
plt.figure(figsize=(10, 8))
lw = 2
plt.plot(fpr, tpr, color='darkorange',
lw=lw, label='ROC curve')
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.yticks([i/20.0 for i in range(21)])
plt.xticks([i/20.0 for i in range(21)])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic (ROC) Curve')
plt.legend(loc='lower right')
plt.show()
ROC_curve(fpr,tpr)
物流回归 ROC 曲线。资料来源:Huy Bui
模型中的虚线是随机选择(概率 50%)。因为有两类,这条线的斜率处处都是 1,因此我们得到单位正方形的对角线。注意这条线下的面积(AUC)是 0.5。
橙色线是 ROC 曲线。它位于虚线上方,表明我们的准确性优于随机选择。通过增加阈值的数值,越来越多的观察结果属于癌症类别。所以 TP 趋近于 1,FN 趋近于 0。这使得 TPR 趋近于 1 。类似地,增加阈值将导致 FP 接近 1,TN 接近 0。这会使 FPR 趋近于 1。因此,我们得出结论,FPR、TPR 和阈值彼此成正比。ROC 曲线仅显示了 2 轴 FPR 和 TPR,但是现在我们知道阈值是产生该图的混杂变量。
再看一下图表。AUC 评分为 0.96,接近完美。我们还想看看 ROC 曲线,看看在图中的哪个点我们有 FPR 和 TPR 的完美组合。例如,如果我们将当前模型调整为具有 97%的 TPR,则 FPR 大约为 6%。如果我们将 FPR 降低到 5%,那么 TPR 只有 82%。所有调整模型的不同方法都是不同领域的不同主题。
结论
我们可以使用 ROC 分析来选择基于成本背景或类别分布的可能的最优模型。ROC 分析也非常类似于诊断决策的成本/收益分析。这是一个伟大的工具,每个数据科学家都应该评估他们的分类器性能。
你可以从我的库中找到这个博客的完整代码。
请在下面留下任何评论、问题或建议。感谢您的阅读!
Python 中一个简单的遗传算法
用遗传算法优化员工计划
染色体是遗传学的重要元素。国家癌症研究所在 Unsplash 上拍摄的照片。
遗传算法
遗传算法是模拟自然选择过程的优化算法。他们没有使用“数学技巧”,而是简单地复制了一个我们知道行得通的逻辑。
遗传算法中的自然选择
这种自然选择的过程是建立在适者生存的基础上的:自然界中让最优秀的个体(动物、植物或其他)生存下来的过程。那些最适合的个体然后互相交配,产生新的一代。自然也以基因突变的形式增加了一点随机性。
新一代是好的和坏的个体的混合体,但是在这里,好的个体会生存下来,然后交配,然后产生新一代。
结果是一代又一代的持续改进。
人员规划的遗传算法
员工规划是优化研究的一个主题,在许多公司都会出现。一旦一家公司有了很多员工,就很难找到既能满足业务需求又能遵守某些约束的计划。在其他现有的解决方案中,遗传算法是解决这个问题的一种优化方法。
Python 实现
在之前的一篇文章中,我已经向展示了如何使用 Python 中的 DEAP 库来实现开箱即用的遗传算法。在这篇文章中,我将更详细地说明如何理解遗传算法的不同部分。
下面的代码是遗传算法的生产代码的简化版本。它是为了更好地理解示例而优化的,而不是为了速度和可重用性。它包含应用于示例数据的每个列出的步骤。
6 步遗传算法代码演练
遗传算法的步骤:
- 如何为遗传算法编码数据?
- 如何评价遗传算法的解?
- 如何为遗传算法编码交配(交叉)?
- 如何为遗传算法编码突变?
- 如何定义遗传算法的选择?
- 如何定义遗传算法的迭代和停止?
步骤 1——如何为遗传算法编码数据?
输入数据—两种类型的规划
在这段代码中,我们将使用两种不同形状的相同人员计划。
第一类规划——每名员工
为每个员工的遗传算法(类型 1 规划)编码数据。作者配图。
第一个形状将是员工的员工计划,详细的看法。这个每周总计划是一个包含每天列表的列表(在我们的例子中是 5 天)。每个每日列表包含一个班次列表(在我们的例子中,员工有 11 个班次)。每个班次都是一个员工 id(从 0 到 11,仅供参考)、开始时间(0 到 24 点之间)和班次持续时间(0 到 10 小时之间)的列表。
我们的员工需要这种类型的计划来了解他们何时工作。
类型 2 计划—每小时总计
遗传算法的编码数据-类型 2 规划-每小时总数。作者配图。
第二种类型的计划是每小时配备的员工总数。店主将使用该计划来决定该计划是否符合商店的估计需求。
步骤 2——如何评估遗传算法的解?
为了评估一个小时制员工计划,我们需要定义一个目标情境。定义这个目标不是优化的一部分:这将是另一个项目的问题。
定义遗传算法的评估——定义目标情况。作者配图。
我们确实需要定义如何评估提议的计划和目标计划之间的差异。这将基于小时计划,通过合计过多的员工小时总数和缺少的员工小时数来完成。这将是一个我们需要最小化的成本函数。
定义遗传算法的评估——定义成本函数。作者配图。
我们可以为人员过多或不足添加权重,但在本例中,我让它们的权重相等。
步骤 3-如何为遗传算法编码交配(交叉)?
遗传算法中有两个关键步骤:交配(也称为交叉或重组)和变异。
在交配阶段,新的一代是由亲代个体的后代形成的,就像在自然选择中一样。
为了将这一点应用到我们的例子中,考虑到以后,我们将生成许多不太好的员工计划,并试图将最好的计划结合在一起。因此,我们需要定义一种方法来“混合”两个人(员工计划)。
在本例中,我决定将代码编写如下:
- 从人群中随机选择一个妈妈
- 从人群中随机选择一个爸爸
- 创建一个与父节点大小相同的子节点,但随机填充 0 和 1。
- 孩子有 1 的位置,我们从他父亲那里得到数据,孩子有 0 的位置,我们从他母亲那里得到数据。
- 我们对每个孩子重复这个过程(孩子的数量等于人口数量)
为遗传算法定义交叉。作者配图。
这是一种方法,还有许多其他可能的方法。为了使遗传算法工作,组合码中具有随机性是很重要的。当然,组合必须符合您在步骤 1 中选择的数据结构。
步骤 4——如何为遗传算法编码突变?
遗传算法的第二个重要步骤是变异。它包括给新一代增加一个完全随机的变化。这种随机变化允许向不再存在的群体添加新值。
例如,考虑这样一种情况,其中算法已经进行了几次迭代,并且由于选择和组合过程中的随机性,它已经取消选择了上午 10 点之前的所有开始时间。如果没有突变,算法将永远无法得到这个值,尽管它可能在以后实际上给出一个更好的解决方案。
随机插入(非常少量的)新值有助于算法摆脱这种情况。
为遗传算法定义变异。作者配图。
它在这里被编码为用 0 和 10 之间的随机值替换一个班次的持续时间或开始时间。如果我们指定一个 n_mutations 值,这可以重复。
步骤 5——如何定义遗传算法的选择?
选择过程非常简单:
- 首先,选择所有可行的解决方案:去掉那些员工工作时间超过 10 小时的方案。
为遗传算法定义选择—可行性。作者配图。
- 然后,将评估函数应用到每个个体(即每个员工规划)并选择最佳个体。所选个体的数量在代码中保持可变。
定义遗传算法的选择——成本。作者配图。
步骤 6——如何定义遗传算法的迭代和停止?
代码的最后一部分是将所有前面的构建块添加到一个迭代的整体代码中。
为遗传算法定义迭代*。作者配图。*
优化参数调整
为了使遗传算法完美地工作,选择正确的参数是很重要的:世代大小、n 次突变和 n 次最佳在这方面很重要。
调整这三者可以找到最佳组合,使两者:
- 收敛到一个解决方案(而不是在没有改进的情况下随意转向)
- 避免陷入局部最优
如果调整后你的算法仍然停滞不前,另一个改进的方向是调整交配和变异函数,看看会发生什么。
因为这篇文章的目标是从头开始开发一个简单实用的遗传算法,所以我不会详细讨论如何找到那些最佳参数:那需要另一篇文章。
感谢您的阅读。不要犹豫,继续关注更多!
一个简单的梯度增强树解释
梯度推进树的简单介绍。
介绍
几年前,Kaggle 的官方博客“没有自由的预感”发布了一篇 Kaggle 大师本·戈尔曼(Ben Gorman)解释渐变增强的文章。文章发表后不久,我在博客上评论了这篇文章。快进到大约一年后,我正在为我的博客查看我的谷歌分析账户,我注意到我的评论得到了很多点击。在进一步的检查中,我发现原来的“没有自由的预感”文章被删除了,因此解释了为什么我的文章得到了这么多的点击(即人们在寻找原来的文章)。鉴于这些新信息,我更新了我的文章,并向人们介绍了我在 GitHub 上的一些工作,这些工作可能会有所帮助。有趣的是,我从来没有喜欢过卡格尔的原创文章。我有一些想法来真正削减脂肪和解释核心概念,这正是这篇文章!我希望这篇文章对那些刚刚开始理解梯度推进树的人有用。
在 Unsplash 上由 Belinda Fewings 拍摄的照片
最简短的解释
在梯度推进树中,我们不断地在我们的模型误差上构建决策树,并且我们使用这些误差预测来修正\更新我们的原始模型预测。
更详细的简短解释
我们建立一个决策树。这个模型对于每个数据点都有一个误差。如果我们可以在这些错误的基础上建立另一个决策树,并使用我们预测的错误来修改我们原来的预测,会怎么样?我们可以!我们可以根据错误建立另一个决策树,并使用这些预测来修改我们最初的预测。我们可以继续这个过程,直到我们决定停止!
更详细的简短解释+可视化
注意:以下图片并非来自 Jupyter 或 Python 或任何实数,我们的可视化只是在 Microsoft Paint 中创建的草图。
首先,我们有一些数据。
由作者在 Microsoft Paint 中创建
因此,我们想用 X 来预测 Y。在此之前,可以通过取 Y 的平均值来推导出一个简单的 Y 模型(所以先忽略 X),我们可以在未来的所有情况下用它来预测 Y。
由作者在 Microsoft Paint 中创建
这种模式似乎在某些方面做得不错,而在其他方面做得很差。因此,每个数据点都有一个错误,下面用红色表示。
由作者在 Microsoft Paint 中创建
如果我们可以建立一个误差模型,这样我们就可以在未来修正我们的误差(因为我们手头没有因变量)。嗯,我们可以!
由作者在 Microsoft Paint 中创建
上面我们看到了 X 的残差图,我们可以使用 X 来帮助预测第一个模型的残差。这个模型说我们想要增加 X 低端的值,减少所有其他的值。我们可以用这些预测来更新我们原来的预测!
由作者在 Microsoft Paint 中创建
所以我们采用了最初的预测,并用第二个模型的预测误差对它们进行了修正。
我们可以一遍又一遍地继续这个过程。实际上,我们通常使用“学习率”来只取误差\误差更新的一小部分。当我们多次运行(包括学习率)时,我们可能会得到如下结果。
由作者在 Microsoft Paint 中创建
就是这样!
你可以看到这个算法是如何得到它的名字的,它的灵感来源于梯度下降。
技术细节和演示
要了解更多技术细节,以及使用 Python 的演示,您可以点击这里查看我在 GitHub 上的分类示例。
概括起来
- 梯度推进树只是根据我们的模型误差不断构建决策树的过程,我们使用这些预测来修改\更新我们的原始模型预测。
- 关于使用数据和代码的演示,你可以点击这里查看我在 GitHub 上的分类示例。
感谢阅读!!😄
数据科学 A/B 测试简单指南
数据科学家最重要的统计方法之一
图片由我、Terence Shin 和 Freepik 创建
查看我的文章’ 假设检验尽可能简单的解释 '如果你还不知道什么是假设检验的话先!
A/B 测试是数据科学和整个技术世界中最重要的概念之一,因为它是对任何假设做出结论的最有效的方法之一。理解什么是 A/B 测试以及它通常是如何工作的很重要。
目录
什么是 A/B 测试?
从最简单的意义上来说,A/B 测试是对两个变量进行的实验,根据给定的度量标准来看哪一个表现更好。通常,两个消费者群体接触同一事物的两个不同版本,以查看会话、点击率和/或转化率等指标是否有显著差异。
以上面的图片为例,我们可以将我们的客户群随机分成两组,一个控制组和一个变异组。然后,我们可以用一个红色的网站横幅来展示我们的变体组,看看我们是否会获得显著的转化率增加。需要注意的是,在执行 A/B 测试时,所有其他变量都需要保持不变。
更专业地说,A/B 测试是一种统计和双样本假设测试。统计假设检验是一种将样本数据集与总体数据进行比较的方法。双样本假设检验是确定两个样本之间的差异是否具有统计显著性的方法。
为什么知道很重要?
了解什么是 A/B 测试及其工作原理非常重要,因为这是量化产品变化或营销策略变化的最佳方法。在一个数据驱动的世界里,这一点变得越来越重要,因为商业决策需要事实和数字的支持。
如何进行标准的 A/B 测试
1.阐明你的假设
在进行 A/B 测试之前,您需要陈述您的零假设和替代假设:
零假设是指样本观察结果纯属偶然。从 A/B 检验的角度来看,零假设表明对照组和变异组之间没有差异。
替代假设是指样本观察值受到一些非随机原因的影响。从 A/B 测试的角度来看,另一种假设认为对照组和变异组之间存在差异。
当开发您的空假设和替代假设时,建议您遵循 PICOT 格式。皮科特代表:
- 人群:参与实验的一群人
- I 干预:指研究中的新变体
- C 比较:指的是你计划用来与你的干预措施进行比较的参照群体
- O utcome:表示您计划测量的结果
- ime:指体验的持续时间(收集数据的时间和时间)
实施例:“与对照干预相比,干预 A 将改善在 3 个月时具有临床焦虑水平的癌症患者的焦虑(通过 HADS 焦虑子量表中相对于基线的平均变化来测量)。”
它是否遵循 PICOT 标准?
- 人群:具有临床焦虑水平的癌症患者
- 干预:干预 A
- 对比:对照干预
- 结果:通过 HADS 焦虑分量表中基线的平均变化来衡量焦虑的改善
- 时间:与对照干预相比的第 3 个月。
是的,确实如此——因此,这是一个强假设检验的例子。
2.创建您的对照组和测试组
一旦你确定了你的无效假设和替代假设,下一步就是创建你的控制和测试(变量)组。在这一步中,有两个重要的概念需要考虑,随机抽样和样本大小。
随机抽样
随机抽样是一种技术,在这种技术中,群体中的每个样本都有均等的机会被选中。随机抽样在假设检验中很重要,因为它消除了抽样偏差,而消除偏差也很重要,因为你希望你的 A/B 检验结果能代表整个群体,而不是样本本身。
样本量 在进行 A/B 测试之前,确定测试的最小样本量是非常重要的,这样你就可以消除覆盖偏差,即由于采样太少而产生的偏差。有很多在线计算器可以用来计算这三个输入的样本量,但是如果你想了解背后的数学原理,请点击链接!
3.进行测试,比较结果,拒绝或不拒绝零假设
一旦你进行了实验并收集了数据,你想确定你的控制组和变异组之间的差异是否有统计学意义。确定这一点有几个步骤:
- 首先,你要设置你的 alpha ,犯类型 1 错误的概率。通常,alpha 设置为 5%或 0.05
- 接下来,您希望通过首先使用上述公式计算 t 统计量来确定概率值(p 值)。
- 最后,将 p 值与 alpha 值进行比较。如果 p 值大于 alpha,不要拒绝 null!
如果这对你没有意义,我会花时间在这里 学习更多关于假设检验的知识 !
更多类似的文章,请看 https://blog.datatron.com/的
感谢阅读!
如果你喜欢我的工作,想要支持我,请在我的电子邮件列表这里注册!
参考
A/B 测试(也称为桶测试或分割测试)是一个随机实验,有两个变量,A 和 B。它…
en.wikipedia.org](https://en.wikipedia.org/wiki/A/B_testing)
Python 中 A/B 测试的简单指南
可视化和模拟数据
桌子上的两个苹果 由保罗·塞尚、公有领域
A/B 测试是一项至关重要的数据科学技能。它通常用于测试网站 A 与网站 B 或*药物 A 与药物 B、*的有效性,或者具有相同主要动机的一个想法的任何两个变体,无论是销售、药物疗效还是客户保留。这是容易产生额外混乱的统计概念之一,因为假设检验本身就需要理解正态分布、z 值、p 值和零假设的仔细构建。对于 A/B 测试,我们有两个样本要处理。然而,A/B 测试本质上仍然只是假设测试!本指南将是简单的单样本假设检验到双样本假设检验或 A/B 检验的基本演练。
简单的单样本假设检验
让我们考虑苹果农民的领域和苹果大小。我们知道,在历史上,一组特定果园中的红苹果平均宽度为 3.5 英寸,标准偏差为 0.2 英寸。因此:
总体均值和标准差
但是农民麦金托什声称他的果园里有一种特殊的新型红苹果,比其他农民的苹果格外美味,而且个头也更大。分别构建零假设和替代假设,或𝐻0 和 H1:
显著性水平为 5%
α选择 5%的显著性水平,这是单样本假设检验的标准显著性水平,也是统计学家和研究人员之间有点随意的约定。假设我们从农民麦金托什的果园里取了 40 个苹果样本,每个苹果平均 4 英寸,样本标准偏差为 0.5:
我们现在有了进行测试所需的一切。为了刷新任何假设检验背后的逻辑,看一下下面获得检验统计量的等式:
这个想法是我们取 x-bar,这是我们的样本均值,找到它与总体的差异意味着样本可能来自。在这种情况下,是 3.5,然后除以标准误差,得到我们的测试统计量:
提醒一下,测试统计是一个指标,表明假设零假设为真,我们有多大可能完全随机获得这个样本。标准正态表,或者 z-score 表,可以用来求正态曲线下对应的面积,就是偶然得到那个结果的概率。在 Python 中,scipy.stats
是一组非常有用的内置函数,用于此目的,scipy.stats.norm.cdf
和scipy.stats.norm.sf
分别给出了测试统计数据在正态分布下的面积。在这种情况下,6.32 是一个非常高的检验统计量,相当于偶然获得这些苹果大小的概率极低:
因为我们的 alpha 被设置为 0.05,所以我们可以使用st.norm.isf(.05)
来确定临界值,如果我们的测试统计超过了这个临界值,我们就可以拒绝零假设。在这种情况下,临界值计算为1.64
,这是一个常见且可识别的数字,因为在正态假设下,它总是α为 0.05 的临界值。我们的测试统计值是 6.32,这远远超过了临界值,所以我们可以安全地拒绝零假设,并说农民麦金托什肯定生产大于平均水平的苹果。
用模拟数据进行 A/B 测试
现在我们已经完成了单样本假设检验的过程,让我们看一些模拟数据来感受一下双样本检验,记住 A/B 检验在一天结束时仍然是检验一个零假设和一个替代假设。Jupyter 笔记本和数据可以在我的 Github 上找到,我鼓励您亲自实际运行一些函数,以便获得数据的实际感受,即使您只是改变随机种子来见证采样是如何变化的。
这是一千个随机生成的正态分布的点,使用sklearn.datasets.make_gaussian_quantiles.
创建,我们称之为我们的总体:
pop, ignore_classes = make_gaussian_quantiles(n_samples=1000, n_features = 2, cov=1, n_classes=1, random_state=0)plt.figure(figsize=(15,10))
plt.scatter(pop[:,0], pop[:,1], s=5, color='cornflowerblue')
plt.show()
为了简单起见,让我们将测试的范围限制在 x 轴上。这意味着这些可视化可以在一个数字线上,但是二维可以让我们更容易地可视化随机样本的分布。
现在让我们从这个群体中随机抽取两个 30 人的样本:
rand1 = np.random.choice(range(1000), 30, replace=False)
rand2 = np.random.choice(range(1000), 30, replace=False)sample1_x = pop[:,0][rand1]
sample2_x = pop[:,0][rand2]
我们的第一个样本平均值(红色)是-.23,样本标准偏差是 0 . 93,第二个样本平均值(绿色)是-.13,样本标准偏差是 0 . 99。因为我们知道真实的总体均值和标准差(因为最初的一千个点是从正态分布生成的)是 μ =0 和 σ =1.0,所以我们可以有把握地说这些样本很好地代表了总体。但是他们的代表性如何呢?看起来两种手段都有点低于真品。在这一点上,我们会产生怀疑,说**也许这些样本完全来自不同的人群?**这个问题就是 A/B 测试试图回答的。
就像单样本假设检验一样,我们有一个两个样本的检验统计公式。尽管它看起来要复杂得多,但它仍然只是零假设和替代假设之间的差异除以标准误差:
两个样本的检验统计公式
本质上,即使我们处理两个样本,我们仍然假设两个样本都来自正态分布,因此在两个样本测试的零假设下,我们假设样本均值之间的差异为零。这有效地将两个样本的检验简化为一个单一样本的假设检验。挑选显著性水平(alpha)和寻找临界值的过程几乎是相同的。
以下代码片段演示了一个用于 A/B 测试的 Python 函数,其中包含一个用于设置不同 alphas 的选项:
def ab_test(sample_A, sample_B, alpha=.05):
mean_A = np.mean(sample_A)
mean_B = np.mean(sample_B)
std_A = np.std(sample_A)
std_B = np.std(sample_B)
standard_error = np.sqrt((std_A**2)/len(sample_A) + (std_B**2)/len(sample_B))
difference = mean_A - mean_B
test_statistic = difference/standard_error
crit = st.norm.ppf(p_value/2)*-1
reject_status = 'Reject Null Hypothesis' if crit < test_statistic else 'Fail to Reject Null Hypothesis'
return 'Test Statistic: ', test_statistic, 'Critical Value: ', crit, reject_status
让我们看看,我们获得这些样本平均值(我们知道它们的差值应该为零)的可能性有多大,这完全是因为偶然:
我们对这两个样本的检验统计量非常接近于零,这是应该的,所以显然我们拒绝零假设,因为这两个样本的均值都应该是零。
然而,让我们不断地创建随机样本,直到我们通过将α设置为. 0001 而获得两个非常不可能的样本,这将允许我们拒绝零假设:
需要 26,193 次随机抽样才能产生足够的样本均值来拒绝零假设!由于仅有一对随机样本的纯粹偶然性,这种情况发生的可能性是 0.002%。让我们想象一下这些例子:
我们可以看到大部分红点在零的右边,大部分绿点在左边,然而我们获得这两个样本纯属偶然(经过 26193 个做作样本)!
这里的要点是,对于真实数据,我们不知道两个样本是否来自不同的人群,我们必须依靠 A/B 测试来告诉我们样本是否真的足够不同,从而可以自信地对他们的人群做出断言。
对于测试不同网站版本或药物功效的公司来说,这是至关重要的信息,并且具有更高的显著性水平,如. 05,实际上**获得允许我们基于纯粹的机会错误地拒绝零假设的样本是相对常见的(也称为 I 型错误)。**因此,通常会引入修正,如 Bonferroni 的修正,以减少因参数空间增加而产生的误差,这被称为多重比较问题或别处查看效应。
和往常一样,在对数据做出强有力的声明之前,了解数据的里里外外是很重要的,即使在运用统计测试和执行 A/B 测试时也是如此,因为虚假但明显的统计显著性在许多领域都很普遍,并且很容易获得看似不可能的样本数据,即使在上面的例子中花费了人为的努力(即使将这个 Jupyter 笔记本中的随机种子改为 42,由于“运气”,我们也可以获得两个样本均值,这两个均值允许我们在 0001 的α水平上拒绝零假设*。试试看。)*
自己处理数据确实有助于理解测试背后的统计直觉,尤其是 A/B 测试,因为有这么多移动的部分。但是所有的假设检验实际上都是同样的程序。所以生成一些数据,自己试试,感谢阅读!
卷积神经网络的简单指南
卷积神经网络揭秘没有任何花哨的技术术语!
识别人和物体的卷积神经网络(来源)
汽车可以识别路标。脸书知道你最好朋友的名字。可以用脸解锁手机。这都是由魔法完成的。
我只是在开玩笑,这里没有魔法,只是简单的,古老的数学。但是严肃地说,我刚才提到的所有东西都是 卷积神经网络的例子。
但是在深入研究卷积网络的代码之前,让我们先了解一下什么是卷积神经网络(CNN)以及它是如何工作的。
第 0 部分:什么是 CNN?为什么要用?
那么,我们为什么要使用 CNN 而不是另一种类型的神经网络,比如多层感知器?这是因为 CNN 能够提取图像的特征,而像多层感知器(MLP)或递归神经网络(RNN)这样的算法不具备这种能力。
卷积神经网络的架构如下所示:
卷积神经网络的架构
我们应该从中注意到一些事情。网络从 2 个卷积和最大池层*、开始,接着是 2 个全连接*层,以一个输出层结束。卷积+最大池图层是识别影像(提取要素)的位置,完全连接图层是将影像分类到预定义类别的位置。
第 1 部分:图像识别
卷积神经网络中的第一部分过滤图像以从图像中提取特征,然后它汇集提取的特征以减少数据的大小,最后添加激活函数,使得网络是非线性函数。这可以归结为卷积 + 汇集+激活层。
盘旋
过滤器是从图像中提取特征的矩阵(这是学习发生的地方)。滤波器值和图像像素值之间的点积形成卷积层。
过滤张量是一个权重矩阵。每当网络执行反向传播时,滤波器矩阵中的值被更新。然而,滤波器矩阵的维数由程序员明确确定。
将滤波器张量与图像的像素值张量相乘。(来源)
在 CNN 中,有许多不同的过滤器来提取图像中的各种特征。随着我们在网络中前进,从图像中提取的特征变得越来越具体。让我们以停车标志为例。
由于第一层中的过滤器用于检测易于识别的特征,因此这可能是停车标志的八角形形状。第二层中的过滤器将用于检测更具体的内容,如文本“停止”。第三层中的过滤器可以用来检测更具体的东西,如“STOP”中的字母“S”。
在 Keras(tensor flow中的深度学习框架)中,第一个卷积层的代码如下所示:
注意:我不会太深入地讲述代码是如何工作的,但我会简单谈谈架构。
所以在这里,我的卷积层是 16 X 16 X 3,一个 5 X 5 的过滤器。程序员必须明确定义滤波器的维数,但滤波器中的值是网络自学的。
联营
在图像通过第一个过滤器后,它将继续到池层。池层减小了过滤层的大小,这使我们可以更快地训练模型。此外,它通过丢弃滤波器张量中不需要的值来防止过拟合。
一种流行的汇集方法被称为最大汇集。这与滤波过程相同,但这次我们取最大值,而不是点积。看看下面的动画:
最大池层的动画
鲁热
现在,我们要增加数学。Re-Lu(校正线性单元)是神经网络中常用的激活函数。激活函数用于向神经网络添加非线性。这使得我们能够解决比我们的网络只是一个线性函数更复杂的问题。如果我们的网络中从来没有激活函数,它将是一个简单的线性回归算法。
Re-Lu 激活功能(源)
Re-Lu 激活函数是一个只有当值大于零时才返回值的函数,有助于减少训练时间。
第 2 部分:图像分类
既然卷积层已经提取了图像的所有特征,那么是时候对图像进行分类了。
在完全连接的层中,每个神经元都与它之前和之后的层中的所有其他神经元共享连接。这就是为什么它被称为“完全连接”层。下面是它们的样子:
CNN 中的全连接层(来源)
变平
在将我们复杂的输入输入到一个密集(全连接)层之前,我们必须展平张量(我们的输入)。扁平化就是把多维输入张量变成一维输入张量。例如,假设最后的卷积层输出一个(28,28,3)张量。展平此输出将为下一层提供(2352,1)的输入。2352 来自于乘以 28 X 28 X 3,这是前面输出张量的维数。
展平汇集张量的例子(来源)。
这意味着图像中总共有 2352 个像素。扁平化允许我们分析每一个像素,因为现在,图像中的每一个像素都有自己的神经元。
拒绝传统社会的人
输入展平后,它会穿过密集层。密集层完成了它的任务,然后就在我们到达最后一个密集层之前,我们做了一件叫做辍学的事情。放弃神经元是将一些输出神经元随机设置为零,只是为了加快训练和反向传播过程,并防止过度拟合我们的网络。
第 3 部分:训练网络
你刚刚学会如何建立一个 CNN,但一个未经训练的网络有什么用!要掌握 CNN 的艺术,你也必须知道如何训练他们。在本文中,我将讨论 CNN 中使用的损失函数和优化器。
损失函数
简而言之,损失函数是一种计算数据精确度的方法。任何优化问题(任何神经网络)的目标都是最小化代价函数。
有各种类型的损失函数。在 CNN 的,使用的损失函数是交叉熵。交叉熵计算概率分布(可以是向量、矩阵、张量等)之间的差异。)和标签的概率分布。
在我们的例子中(在 CNN 中),数据用向量表示。交叉熵损失计算标签向量(y)中每个元素与网络输出向量(X)之间的差值,然后将所有这些值相加,得出网络的总损失。
交叉熵损失的可视化(来源:Udacity
那里陈述的公式包括一些非常密集的数学符号,所以如果你想在数学上更深入,我建议你去下面的链接。然而,你不需要精通数学来写 CNN(特别是在像 Keras 或 Pytorch 这样的框架中,因为你只需要写*“loss = cross _ entropy*”,Keras/Pytorch 会处理剩下的)。
最佳化
机器学习中的优化是找到将返回最低成本(损失)的最佳权重/偏差。优化器就是一种能做到这一点的算法。在 CNN(和大多数其他深度神经网络)中,我们使用 Adam 优化器。
如果你真的有兴趣学习更多关于 Adam 优化器的知识,戴上你的统计学和微积分头盔,点击下面的链接。
Adam 是一种自适应学习率优化算法,专为训练深度神经…
towardsdatascience.com](/adam-latest-trends-in-deep-learning-optimization-6be9a291375c)
像以前一样,您不需要理解优化器如何工作背后的本质数学。在 Keras 中,使用 Adam 优化器仅仅是一行代码( optimizer=“Adam”)
这是一个总结!
厉害!你现在知道了 CNN 的基本知识,所以现在你应该选择一个你真正热爱的 CNN 项目,这样你就可以去应用你刚刚学到的东西。同时,看看下面这个很棒的教程,在那里我学会了如何写一个路标分类器!
在本教程中,您将学习如何训练自己的交通标志分类器/识别器能够获得 95%以上的…
www.pyimagesearch.com](https://www.pyimagesearch.com/2019/11/04/traffic-sign-classification-with-keras-and-deep-learning/)
关键要点
总结一下这一切:
- CNN 是一种深度神经网络,通常用于图像数据和复杂的分类问题。
- CNN 的架构涉及各种类型的层,包括:卷积、最大池化、密集、丢弃。
- 卷积层通过将过滤矩阵与图像张量相乘,从图像中提取特征信息,创建图像的过滤层。这是所有学习发生的地方
- 然后,合并过滤层(过滤层的大小减小)。这是通过最大池完成的。
- 在图像通过几个卷积+最大池层后,它得到展平并进入密集层。
- 在致密层完成它的工作后,一些神经元被随机丢弃以防止过度拟合。
- 我们使用 Adam 优化器和交叉熵损失来训练我们的模型。
现在是时候建立你自己的 CNN 了!
了解你的神经网络和激活的简单指南。
分析哪个功能似乎合适
生物神经网络一览。
为了更好地理解激活函数的意图和目的,让我们分析一下我们自身的一个等效模型——神经元(首先是神经网络的灵感)。一个生物神经网络简单来说就是由一个细胞 体,树突(来自神经元的输入)和轴突(输出到其他神经元)。一个有用的术语是突触,它来自一个神经元与另一个神经元通信的接触点。树突上覆盖着由其他神经元轴突末端形成的突触。来自所有树突的突触在细胞体中累积,细胞体根据累积跨越的阈值(类似于各种激活功能)确定细胞的状态激活/未激活。然后这些突触穿过轴突,到达沿途交流的其他神经元。
神经元的简单解剖
人工神经网络
人工神经网络确实保持了其生物学等效物的完整性,尽管多了一些术语。
重量
偏差
神经元的处理过程
输出=σ(权重*输入)+偏差
这遵循线性方程y = MX+c其中权重对应于“m ”,偏差对应于“c”
重量(瓦特)
权重,通常是突触权重,代表一个神经元对另一个神经元的强度,使整体连接更强。
偏见
作为截距,偏差项使网络符合实际情况,而不是理想情况。如果缺少偏差项,训练点将只通过原点,这是一个太简单的分析。一个网络往往是更强大的偏差项,因为它是开放的,以新的方式考虑和拟合。此外,它还决定了激活功能生效的时间点。
选择您的激活功能
现在,我们已经对生物神经网络和人工神经网络进行了基本的比较,我们将看看各种激活函数,并检查它们的优点和局限性。
每个激活函数取一个值,并对其执行数学运算。
1.乙状结肠的
乙状结肠的
- 它接受一个实数值,并将其压缩到范围[0,1]内
- 其数学形式:σ(x)= 1/(1+e x)
但是,由于以下限制,它很少实现:
- 乙状结肠饱和,从而消除梯度 当激活在 1,0 达到饱和时,梯度减小到零。
因此,在反向传播期间,该零梯度与梯度输出相乘,产生一个非常小的数字,阻碍信号流过权重和输入。 - 非零中心输出 如果进入神经元的数据总是正的,则反向传播期间的权重将产生全正或全负的梯度。这导致梯度更新中不期望的行为。
2。Tanh
双曲正切
虽然与 sigmoid 函数相似,但 tanh 函数解决了它的一个限制:非零中心输出。
- tanh(x)= 2σ(2x)1
- 它将一个实数值压缩到[-1,1]范围内
局限性:
- 它在与它的乙状结肠对应物相同的线上饱和。
3.热卢
热卢
- f(x)=max(0,x)
- 随机梯度的收敛速度大约加快了 6 倍。
- 它将激活矩阵的阈值设置为零,并且由于没有指数或缺少指数,所以成本较低。
- 随着 x 的增加,不存在饱和。
- 然而,它提出了“垂死的 ReLU”问题的局限性。
当零处的梯度为零时(当 x <为 0 时),一个垂死的 ReLU 对任何输入产生相同的输出。梯度学习不会改变权重。 - 这是由于
-一个非常高的学习率
-一个大的负偏差
4。泄漏的 ReLU
泄漏的 ReLU 和 PReLU
泄漏的 ReLU 试图解决垂死的 ReLU 问题的局限性。
- 当 x < 0.
例如 y = 0.01x 时,泄漏 ReLU 具有小的负斜率 - 参数 ReLU ( PReLU)是泄漏 ReLU 的变体,其中斜率被视为要调整的参数。α代表斜率参数。y =α x
- 因此,由于负值斜率的存在,它确实会对相应的输入产生一个输出,从而产生变化。
- 然而,泄漏的 ReLU 并不总是一致的。
所以,问题。我应该选择哪个激活功能?
避免使用 sigmoid 函数。您可以选择 ReLU 或泄漏 ReLU(作为 ReLU 函数的替代)。不过,要监控你的学习速度。
你可以给 Tanh 一个机会,但是它可能产生比 ReLU 更差的结果。
资源
[## 用于视觉识别的 CS231n 卷积神经网络
斯坦福 CS231n 课程材料和笔记:视觉识别的卷积神经网络。
cs231n.github.ioo](http://cs231n.github.io/) [## ReLU -人类的机器学习- TinyMind
TL;DR: ReLU 代表整流线性单位,是一种激活函数。数学上定义为 y…
www.tinymind.com](https://www.tinymind.com/learn/terms/relu) [## 人与机器:人工神经网络和生物神经网络的比较
学习能力被认为是智慧生命的标志之一。机器学习现在有能力学习和…
news.sophos.com](https://news.sophos.com/en-us/2017/09/21/man-vs-machine-comparing-artificial-and-biological-neural-networks/)
面向数据科学家的面向对象编程简单指南
如何轻松阅读复杂的 Python 包?
作为一名数据科学家,您可能不会像开发人员那样每天都编写面向对象(OO)代码。在您的整个职业生涯中,您可能永远都不需要编写 OO 代码!然而,在不知不觉中,您每天都在通过使用包和框架与面向对象编程(OOP)进行交互。关键的数据科学库,如 pandas、numpy 和 scikit-learn 都严重依赖 OOP。
看看这些库的源代码,它们充满了类、方法、属性等等。你可能还想知道为什么你需要声明一个回归模型(例如)作为一个类的实例,然后运行一个 fit 方法来训练你的机器学习模型。
如果你是一个非常好奇的人,你可能想阅读和理解一个很酷的机器学习包的源代码。理解 OOP 可以帮助你轻松做到这一点。如果有一天你想写一个 Python 包或者框架,这些知识将是极其有价值的。
在这篇文章中,我将解释一些主要的 OOP 原则来帮助你开始。
*Edit 2022:你也可以在我的 Youtube 频道上观看下面这篇整篇文章的视频版本,我在其中更详细地描述了 OOP 概念。
首先,我们为什么需要 OOP?
如果我们不知道 OOP 能解决什么样的问题,我们就无法理解和欣赏它。
我们大多数人害怕意大利面条式的代码,因为它太混乱了,难以阅读和维护。但是意大利面代码是如何创建的呢?
意大利面条代码。来源:作者。
看看这个代码结构。希望你看着眼熟:)。我们可以看到 5 个不同的函数相互调用,还有一堆全局变量被一个或多个函数访问和使用。想象一下这个结构扩展几倍,事情会变得非常混乱,难以理解。OOP 通过两个原则解决了这个问题:封装和抽象。
包装
OOP 将变量和函数从我们上面的意大利面条式结构中组合在一起,形成称为“对象”的实体。对象内部的变量称为属性/特性,函数称为方法。把属性想象成一个物体的特征(比如一只猫有蓝色的眼睛)。另一方面,方法本质上是一个对象做事情的能力(比如一只猫知道怎么抓老鼠,会说“喵”)。
对象通过引用彼此的属性和调用彼此的方法进行交互。
封装使得代码更容易复制和维护。如果我们想将一个对象复制成 10 个对象,我们只需复制整个对象,而不是复制对象中的每个变量和函数。
抽象
当我们不希望其他对象访问和修改一个对象的属性时,我们对其他对象隐藏这些属性。理想情况下,只有一个对象的基本元素通过该对象的接口对其他对象可用。
这就是所谓的“抽象”。我们的手机是抽象的例子。它们的界面只为我们提供了使用它们的相关手柄,但芯片和存储卡等东西对我们来说是隐藏的。
Python 中的 OOP
在 Python 中,类用作创建对象的代码模板。这类似于 JavaScript 中的构造函数。
使用类的构造函数创建对象。这个对象将被称为类的instance
。在 Python 中,我们以下列方式创建实例:
Instance = class(arguments)
让我们看下面一个类的例子:
类的例子。来源:作者
一个类中的函数不能直接访问该类的属性,就像我们通常认为的“全局变量”一样。相反,我们需要使用self
关键字来访问类的属性。这也类似于 JavaScript。在 Python 中,self
关键字总是放在第一个参数中。
要实例化该类,我们只需调用:
>>> MySuperCuteCat = SuperCuteCat()
你也可能经常在 Python 类中看到 __init__
方法。这个方法只是用来初始化一个类的几个属性。
我希望这篇文章能让你对 OOP 有一个更清晰的认识,并帮助你作为一名数据科学家更好地理解 Python 包和框架。如果你有兴趣学习更多关于面向对象的知识,这个页面可能会很有趣。
感谢您的阅读!享受学习。
一个简单的指标添加到您的交易系统
提出一个简单的指标概念,应该包含在你的交易框架中
注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语 。
金融研究是一个无穷无尽的令人兴奋的领域,有许多“**找到了”**和“**哦,不!”**瞬间。我们总是在寻找那个一直有效并让我们晚上睡得好的黄金策略,但是我们经常会遇到“哦,不!”瞬间。这很正常,我们是在大海捞针,针是一个体面的策略,而大海捞针是想法的无限可能性。
刚刚在 Python 中 新技术指标成功后出了新书。它对复杂的交易策略进行了更完整的描述和补充,Github 页面致力于不断更新代码。如果你对此感兴趣,请随时访问下面的链接,或者如果你喜欢购买 PDF 版本,你可以在 Linkedin 上联系我。
亚马逊网站:交易策略之书(9798532885707): Kaabar,Sofien:书籍
www.amazon.com](https://www.amazon.com/gp/product/B09919GQ22/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B09919GQ22&linkCode=as2&tag=sofien-20&linkId=bc5df3f6ab0f3af2df79641c56b949ba)
有时候,简单是成功的关键。我们不需要几十个技术指标到处发出信号,到头来却发现自己成了净输家。我们必须了解关于技术指标的两件事:
- 它们是价格衍生的。这意味着他们取价格,分解价格,了解一些特征。因此,他们不是向前看,而是向后看。我们希望这种落后的关系在未来继续下去。例如,如果我们看到 RSI 出现背离,我们希望它会像往常一样导致价格衰竭。这种背离并没有窥视未来,它只是一个简单的数学观察。
- 他们不太可能独自提供成功的策略。如果是这样的话,那么为什么我们不都是依靠随机指标上的超买/超卖区成为百万富翁呢?交易比这复杂得多,需要更全面的方法来发现有利可图的交易。
考虑到这一点,我们应该把指标看作是我们信念的小帮手。例如,当我们发现足够的信息告诉我们做多(购买)一项资产时,我们可以检查技术指标,看看它们是否证实了这一点。我们还应该检查当前的市场状态,以了解指标是否会提供良好的信号。这意味着当我们处于趋势市场时,我们不应该使用均值回复指标。下图显示了原因。这是 RSI 在上升趋势市场中给出的卖出信号。请注意蓝色矩形内的价格趋势,很明显,信号的质量很差。
RSI 信号图——欧元兑美元每日时间框架。(图片作者)
现在,我们可以试着从一个很简单的想法中找到一个简单的指标,那就是归一化。标准化的好消息是,买卖条件已经列出来了,而且很直观,因此,我们要做的就是找到一个合适的周期(如 RSI 中的 14 默认周期)。我们将看到如何在不偏离指标的情况下找到这个周期。
规范化的概念
这个伟大的技术允许我们捕捉 0 和 1 之间的值(或者 0 和 100,如果我们想乘以 100 的话)。这个概念围绕着从当前值中减去某个回望周期中的最小值,再除以同一回望周期中的最大值减去最小值(在命名器中相同)。
(图片作者)
我们可以尝试用 python 编写这个公式。以下函数对给定的 OHLC 类型的时间序列进行归一化处理:
def normalizer(Data, lookback, onwhat, where):
for i in range(len(Data)):
try:
Data[i, where] = (Data[i, onwhat] - min(Data[i - lookback + 1:i + 1, onwhat])) / (max(Data[i - lookback + 1:i + 1, onwhat]) - min(Data[i - lookback + 1:i + 1, onwhat]))
except ValueError:
pass
Data[:, where] = Data[:, where] * 100return Data# The **onwhat** variable is what to normalize and the **where** variable is where to print the normalized values, i.e. which colum.
如果我们将该函数应用于欧元兑美元每日时间框架的收盘价,并有 50 个回望期(也就是说,该函数将查看最后 50 个值,并从中选择最小值和最大值),我们将得到下图。
欧元兑美元每日时间框架及其标准化值。(图片作者)
现在,如果我们形成一个简单的策略,当归一化值等于 0 时买入,当归一化值等于 100 时做空,我们得到下图。这些信号似乎确实捕捉到了一些顶部和底部。就其本身而言,这是一个良好的开端,因为选择 50 是完全随意的。为简单起见,我们可以称归一化值:归一化指数(NI) 。
如果你也对更多的技术指标和使用 Python 创建策略感兴趣,那么我关于技术指标的畅销书可能会让你感兴趣:
亚马逊网站:Python 中的新技术指标:9798711128861: Kaabar,Sofien 先生:书籍
www.amazon.com](https://www.amazon.com/gp/product/B08WZL1PNL/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=B08WZL1PNL&linkCode=as2&tag=sofien-20&linkId=e3cb9716bb6a07cf6c8b9fb585412b07)
欧元兑美元遵循 50 天标准化指标的信号图。(图片作者)
然而,我们希望从这种奇妙的技术(即规范化)中提取尽可能多的价值。怎么会?基本想法是这样的:
我们不想说 20 天周期比 50 天周期更适合标准化,因此我们可以形成一个全标准化指数(ANI ),它使用从 2 到 100 的回顾周期,并相应地对它们进行加权。这样,我们将有一个加权的标准化指数,它考虑了广泛的回望期。
如果 10 天期标准化指数显示值为 40,那么它在全标准化指数中的真实值为 40 / 100 = 0.40。因此,我们将拥有一个由 100 个规范化索引器组成的介于 0 和 100 之间的索引。
用 Pythonic 语言来说,我们将有以下创建全规范化索引(ANI)的循环语句,请记住,我们仍然处于 OHLC 数据结构中(第 0 列表示开放,第 1 列表示高,第 2 列表示低,第 3 列表示关闭):
# Starting from column 4 (i.e. the first Normalized Index)
b = 4# Looping and adding 1 so that the correct column will be populated
for a in range(2, 102):
Asset1 = normalizer(Asset1, a, 3, b)
b = b + 1# Formatting
normalized_values = Asset1[:, 4:104]# Calculating the ANI
all_normalizer = np.sum(normalized_values, axis=1) / 100# Reshaping
all_normalizer = np.reshape(all_normalizer, (-1, 1))
Asset1 = deleter(Asset1, 4, 110)# Concatenating the OHLC Data with the ANI
Asset1 = np.concatenate((Asset1, all_normalizer), axis = 1)
Asset1 = adder(Asset1, 10)
Asset1 = Asset1[102:,]
让我们看看我们的新指标是什么样的。剧透警报,看起来像个指示器。顺便说一句,如果你喜欢通过 Python 研究和回测策略,那么我写的这本书可能会让你感兴趣, 《回测之书:客观交易:回测和揭秘交易策略 。
与 ANI 的欧元兑美元每日时间框架。(图片作者)
因此,上述指标是一百个标准化索引器的平均值,给我们的信号似乎稍微好一点(我们总是可以优化它)。让我们检查下面的信号图。
ANI 之后的欧元兑美元信号图。(图片作者)
我们可以在 ANI 上添加我们的触觉,因为信号有点稀少。加个 8 日均线怎么样?这可以根据均线何时穿过 ANI 给我们一些信号。下图说明了前一点,我们有更多的信号,移动平均线做得很好,平滑了 ANI。
与 ANI 和 8 日均线的欧元兑美元每日时间框架。(图片作者)
如果您对另一个标准化指标感兴趣,请查看我写的这篇文章:
[## 标准化的布林线指标。另一种交易范围的方式。Python 中的回溯测试。
深入挖掘并修改布林线。
medium.com](https://medium.com/@kaabar.sofien/the-normalized-bollinger-indicator-another-way-to-trade-the-range-back-testing-in-python-db22c111cdde)
结论
这个指标有什么用?嗯,衡量动量是交易中的一个关键概念,标准化指数通过使用纯粹的收盘价数据完美地做到了这一点。如果随机振荡器使用稍微修改的归一化版本,那么后者可以帮助我们看到纯粹的收盘动量。如果你想取消一步棋,你可以向 ANI 确认你的观点。
经验法则是,如果 ANI 的读数高于 95,那么它支持你的看跌观点,如果 ANI 的读数低于 5,那么它支持你的看涨观点。我们可以使用 ANI 的另一个方法是它的移动平均线交叉。当然,8 期 MA 是个人选择,如果更适合你可以选择另一期。
图片由皮克斯拜的 Gerd Altmann 提供
Python 正则表达式的简单介绍
我们将通过一些在 Python 中使用 Regex ( 正则表达式 )的基本例子,展示这个框架如何用于强大的文本处理。
图片来源: Pixabay(免费商业使用)
介绍
文本挖掘是当今数据科学的一个热门话题。文本数据的数量、种类和复杂性正以惊人的速度增长。
根据本文,2019 年全球文本分析市场价值为 54.6 亿美元,预计到 2025 年将达到 148.4 亿美元。
正则表达式用于 识别 一个模式是否存在于一个给定的字符序列(字符串)中,也用于 定位 该模式在文本语料库中的位置。它们有助于操纵文本数据,这通常是涉及文本分析的数据科学项目的先决条件。
因此,对于初露头角的数据科学家来说,对于未来的项目和分析任务来说,初步了解这个强大的工具非常重要。
在 Python 中,有一个名为 re 的内置模块,需要导入该模块才能使用 Regex。
**import re**
这是官方文档页面 的 起点。
在这篇简短的回顾中,我们将通过 Python 中的一些实际例子,介绍正则表达式在简单文本处理中的基本用法。
“匹配”方法
我们使用**match**
方法来检查一个模式是否匹配一个字符串/序列。它区分大小写。
一个``compile`d 程序
我们可以使用**compile**
创建一个正则表达式程序并使用内置方法,而不是重复代码。
因此,编译后的程序返回特殊对象,如**match**
对象。但是如果它们不匹配,它将返回**None**
,这意味着我们仍然可以运行我们的条件循环!
位置匹配
我们可以很容易地使用match
对象中的附加参数来检查字符串模式的位置匹配。
上面,我们注意到一旦我们用模式thon
创建了一个程序prog
,我们就可以用不同的字符串多次使用它。
另外,请注意,pos
参数用于指示应该在哪里查找匹配。对于最后两个代码片段,我们改变了起始位置,得到了不同的匹配结果。虽然字符串是相同的。
一个简单的用例
让我们看一个用例。我们想知道列表中有多少单词的最后三个字母是 ing。
“搜索”方法
为了解决上面的问题,我们可以使用一个简单的字符串方法。
regex 有什么强大的地方?
答案是它可以匹配非常复杂的模式。但是要看这么高级的例子,我们先来探讨一下**search**
的方法。
注意,match
方法如何返回None
(因为我们没有在文本中指定模式的正确起始位置),但是search
方法找到匹配的位置(通过扫描文本)。
自然,我们可以使用由search
返回的match
对象的span()
方法来定位匹配模式的位置。
findall
和` finditer '方法
search
功能强大,但也仅限于查找文本中第一个出现的匹配。要发现一个长文本中的所有匹配,我们可以使用findall
和finditer
方法。
findall
方法返回一个带有匹配模式的列表。你可以通过统计条目的数量来了解被搜索的条目在文本中出现的频率。
finditer
方法产生一个迭代器。我们可以使用它来查看更多信息,如下所示。
通配符匹配(使用单个字符)
现在,我们轻轻地进入 Regex 闪耀的竞技场。正则表达式最常见的用法与“通配符匹配”或“模糊匹配”有关。这是你没有完整的模式,但它的一部分,你仍然想找到在一个给定的文本中,类似的东西出现。
这里有各种各样的例子。这里我们还将对由search
返回的对象应用group()
方法,以返回匹配的字符串。
单点单字符匹配
点.
匹配除换行符以外的任何单个字符。
小写\w 匹配任何单个字母、数字或下划线
DOT 仅限于字母字符,所以我们需要用其他工具来扩展曲目。
(\W 或大写 W)匹配没有包含\w 的任何内容
除了字母、数字和下划线之外,还有其他符号。我们用\W 来捕捉它们。
用空白字符匹配模式
\s(小写 s)匹配单个空白字符,如空格、换行符、制表符、回车符。当然,这是用来搜索一个有空白的模式,比如一对单词。
\d 匹配数字 0-9
这里有一个例子。
这是一个实际应用的例子。假设,我们有一篇描述一些学生在一次测试中的分数的文章。分数范围为 10-99,即两位数。其中一个分数被错打成了 3 位数(Romie 得了 72,却被打成了 721)。下面的简单代码片段使用\d 通配符匹配来捕获它。
字符串的开头
^(caret)匹配字符串开头的模式(但不匹配其他任何位置)。
字符串的结尾
$(美元符号)匹配字符串末尾的模式。下面是一个实际的例子,我们只对苹果的专利信息感兴趣,而忽略其他公司。我们检查文本末尾的“Apple ”,只有当它匹配时,我们才使用前面显示的数字匹配代码取出专利号。
通配符匹配(有多个字符)
现在,我们可以转到更复杂的多字符通配符匹配,这让我们拥有更大的能力和灵活性。
匹配 0 次或更多次重复
*****
匹配前面正则表达式的 0 次或多次重复。
匹配 1 次或多次重复
**+**
使产生的 re 匹配前面 RE 的一次或多次重复。
精确匹配 0 或 1 次重复
**?**
使结果 RE 精确匹配前一个 RE 的 0 或 1 次重复。
控制匹配的重复次数
**{m}**
精确地指定了**m**
RE 要匹配的副本。较少的匹配导致不匹配并返回**None.**
**{m,n}**
精确指定**m**
到**n**
的副本 RE 来匹配。省略**m**
指定下限为零,省略**n**
指定上限无穷大。
**{m,n}?**
指定**m**
到**n**
RE 的副本以非贪婪方式进行匹配。
匹配字符集
**[x,y,z]**
匹配 x、y 或 z。
集合中的字符范围
在集合中可以匹配一系列字符。这是使用最广泛的正则表达式技术之一。我们用**-**
来表示距离。例如,a-z
或A-Z
将匹配a
和z
或A
和Z
之间的任何内容,即整个英文字母表。
让我们假设,我们想要提取一个电子邮件 id。我们放入一个模式,用字母字符+ @ + .com 匹配正则表达式,但是它不能捕获一个包含一些数字的电子邮件 id。
因此,我们稍微扩展了一下正则表达式。但是我们只提取带有域名的电子邮件 id。’ com '。因此,它无法捕捉其他领域的电子邮件。
这很容易扩展,但巧妙的电子邮件操作可能会阻止用这样的正则表达式提取。
通过 OR-ing 结合正则表达式的功能
像任何其他好的可计算对象一样,Regex 支持布尔运算来扩展它的范围和能力。单个正则表达式模式的 OR 运算特别有趣。
例如,如果我们想查找包含区号“312”的电话号码,下面的代码无法从第二个字符串中提取出区号。
我们可以如下创建正则表达式对象的组合来扩展功能,
一个组合的例子
现在,我们展示一个使用findall()
从文本中提取有效电话号码的例子,以及我们到目前为止学到的多字符匹配技巧。
请注意,区号为 312 的有效电话号码是 312-xxx-xxxx 或 312.xxx.xxxx。
拆分方法
最后,我们讨论一种方法,它可以创造性地用于从不规则的语料库中提取有意义的文本。下面显示了一个简单的例子,我们用打乱了一个常规句子的外部字符构建了一个正则表达式模式,并使用**split()**
方法从句子中去掉这些字符。
摘要
我们回顾了使用 Python 定义正则表达式对象和搜索模式的要点,以及如何使用它们从文本语料库中提取模式。
Regex 是一个庞大的主题,它本身几乎就是一种小型编程语言。鼓励读者,尤其是那些对文本分析感兴趣的读者,从其他权威来源更多地探索这个主题。这里有一些链接,
你是那种因为正则表达式看起来像外语而远离它的人吗?我在……
medium.com](https://medium.com/free-code-camp/regular-expressions-demystified-regex-isnt-as-hard-as-it-looks-617b55cf787)
对于 JavaScript 爱好者来说,
正则表达式不是外来语言。在这里学习 JavaScript 中 Regex 的基础知识。
codeburst.io](https://codeburst.io/an-introduction-to-regular-expressions-regex-in-javascript-1d3559e7ac9a)
十大最需要的正则表达式,现成的,
十大最常用(也是最需要的)正则表达式
medium.com](https://medium.com/factory-mind/regex-cookbook-most-wanted-regex-aa721558c3c1)
A lso,你可以查看作者的 GitHub 知识库获取机器学习和数据科学方面的代码、思想和资源。如果你和我一样,对人工智能/机器学习/数据科学充满热情,请随时在 LinkedIn 上添加我或在 Twitter 上关注我。
[## Tirthajyoti Sarkar - Sr .首席工程师-半导体、人工智能、机器学习- ON…
通过写作使数据科学/ML 概念易于理解:https://medium.com/@tirthajyoti 开源和有趣…
www.linkedin.com](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/)
使用开源工具过渡到网络安全的简单介绍。
网络安全——胡安·卡西尼的艺术作品
现在是 2020 年 2 月,我已经看到多篇文章预测,由于缺乏信息安全方面的人才,大规模的末日正在向我们走来。有些是危言耸听吗?大概吧。但现实是,大多数行业都在向科技发展,而科技带来了网络威胁。因此,传统的 IT 部门不得不适应并开始将网络安全放在首位。随着 IR35 的变化将于 2020 年 4 月生效(尽管它从 2000 年就已经存在了),雇佣承包商来保护你的安全将不再那么容易。这对 IT 部门意味着什么?对一些部门来说,这意味着招聘人才,无论是内部招聘还是着眼于当前市场?由于英国退出欧盟即将对英国移民体系进行改革,这可能会变得更加困难。然而,对于那些希望进入这个行业的人来说,这为进入一个需求巨大的行业提供了机会。
因此,让我们假设你已经在技术领域工作,并想将流转换为网络,你从哪里开始呢!
网络安全的角色那么多,知道自己的兴趣在哪里是一个很好的开始。解决这个问题的一个好方法是开始消费网络内容,可以是播客、书籍、YouTube,甚至是媒体阅读。 你 觉得什么有趣?如果你来自数据科学背景,并且热爱数据,那么网络安全🤝数据科学=一个豆荚里的两颗豌豆。这辈子,你要热爱你做的事情,当你热爱你做的事情的时候,感觉就不像工作了,对吧?你越喜欢你所做的事情,你就会变得越好奇,并且会走得更远。在网络安全领域,求知欲是必需的这可能是从同一所学院毕业、成绩相同的候选人之间的区别。
让我们从一些你需要的工具开始,⚒️
虚拟机将是你最好的朋友。这不仅是一个比建造你的实验室更环保的解决方案,而且它提供了一个复制*(在某种程度上,这是由你的家用机器有多强大决定的)*场景的机会,对于那些不习惯命令行的人来说也是一个机会。
VirtualBox 是大多数人用来部署虚拟机的最常见的开源虚拟化工具。一种常见的做法是部署一台易受攻击的机器(让我们说一台具有已知漏洞的邮件服务器),然后部署另一台带有 Kali Linux 或 Parrot OS 的虚拟机,设置网络设置以确保它们可以通信,然后继续利用漏洞。
我应该试用什么操作系统?
Kali 通常是最推荐的网络安全操作系统,尤其是如果你正在进行渗透测试的话。然而,Kali 也是一把拥有许多工具的瑞士军刀,所以对于第一次使用的人来说,它可能会令人生畏,令人困惑,而且处理起来太多了。那么,你该如何应对呢?
熟能生巧!
好的,让我们假设您是一名 DBA,已经与数据库打交道很长时间了,但现在想转换立场,加入我们的 infosec。你知道数据库,但从未使用过 Kali,所以学习它的最好方法是用 MongoDB 构建一个 VM,并安装一个你知道有漏洞的版本。识别网络安全漏洞的标准被称为“常见漏洞和暴露”( CVE s)。例如,搜索 MongoDB 会返回 36 个 CVE,这些 CVE 现在都将被打补丁。但是,例如,如果您在虚拟机上下载并安装了一个没有为CVE-2015–7882打补丁的 MongoDB 版本,该版本由于对版本 3.0.0 到 3.0.6 的 LDAP 身份验证处理不当而允许未经身份验证的客户端获得未经授权的访问,那么您就可以练习使用类似 Metasploit 或其他数据库破解工具。这种方法背后的原理是让你使用 Kali 中的一些工具包,切换数据库和工具,并学习渗透测试的基础知识。人们常说进攻是最好的防御方式。这也适用,尤其是在网络安全领域。如果你不知道它是如何被攻击的,你就不能保护它,对吗?
但是网络安全不仅仅是渗透测试信不信由你!
这里是我最喜欢的虚拟机之一。这是一个完整的安全套件,可以用来加强您的家庭防御。这可能是开始使用你的数据作为学习手段的好方法。介绍安全洋葱!
Security Onion 是一个免费的开源 Linux 发行版,用于入侵检测、企业安全监控和日志管理。它包括 Elasticsearch、Logstash、Kibana、Snort、Suricata、Bro、Wazuh、Sguil、Squert、CyberChef、NetworkMiner 和许多其他安全工具。
这里提到了许多工具,让我们来分解一下:
- ELK Stack—Elastic Stack 由 Elasticsearch、Kibana 和 Logstash 组成,像 Voltron 一样,它们结合在一起共同工作,形成一个伟大的 SIEM 工具,Logstash 摄取&处理日志,Elasticsearch 存储和解析,Kibana 显示它们以供分析。
麋鹿栈还包括 Beats!——承蒙弹力
- SNORT —是一款免费开源的网络入侵检测系统和入侵防御系统。由 Martin Roesch 于 1998 年创建,能够进行实时流量分析和数据包记录。
那么 SNORT 是如何工作的呢?
让我们以CVE-2017–0144-Windows SMB 远程代码执行漏洞为例,也称为永恒之蓝,它是 2017wanna cry 流行病的催化剂。SNORT 允许您在网络上设置规则,以阻止任何利用此漏洞的企图。例如,WannaCry 已知会与某个 sinkhole 进行通信,并检查某个 URL 是否是活动的,因为这是一个已知的指标,您网络中显示此行为的任何机器都很可能会受到危害,因此拥有检测和阻止此行为的规则将是一个很好的防御策略。数据科学家将喜欢使用 SNORT 规则和它生成的数据,结合 Kibana,您将能够构建图表并结合机器学习来预测&分析趋势。
通过 Kibana 发出 SNORT 警报——由 sý nesis 提供
- BRO —现在叫 Zeek,但知道的人不多。但是 BRO 是一个网络分析框架,与典型的 IDS 有很大的不同。
- Wazuh —是一款开源的企业级安全监控解决方案,用于威胁检测、完整性监控、事件响应和合规性。
- Sguil 是由网络安全分析师为网络安全分析师打造的。Sguil 的主要组件是一个直观的 GUI,它提供对实时事件、会话数据和原始数据包捕获的访问。Sguil 促进了网络安全监控和事件驱动分析的实践。
- Squert —是一个 web 应用程序,用于查询和查看存储在 Sguil 数据库中的事件数据(通常是 IDS 警报数据)。Squert 是一个可视化工具,它试图通过使用元数据、时间序列表示以及加权和逻辑分组的结果集来为事件提供额外的上下文。希望这些观点能引发一些问题,否则这些问题可能不会被提出。
网络安全🤝良好的图形用户界面——由 Squert 项目提供。
从远处看,看到所有这些工具并思考我不知道自己在做什么可能会令人生畏,但控制你的环境,查看教程并努力解决任务和漏洞是一种很好的学习方式。每当我在 Kali 上执行任何活动时,我总是确保我在监控会话,然后返回并试图通过日志重放它。通过查看每个分析工具发生了什么,它帮助我在日常工作中识别和记住我以前见过的行为。
Windows 事件日志是实践中一个很好的例子。用户登录时会发生什么?如果通过 LDAP 服务器或 VPN 登录,哪些日志与登录相关联?能够看到成功的登录,并将它们与系统尝试的日志进行比较,有助于形成您对基础架构环境的理解。
推荐购买!
阅读团队现场手册— 本·克拉克写的一本书,我一直把它放在办公桌上!
我总是把这本书放在身边,尤其是当命令行不是你的强项或者你正在使用 Windows CMD 并且需要复习常用命令的时候。绝对值得 4.94!这里可以买到!
想学笔考,但是没时间搭建环境?
在家学习是许多领域发展的关键,但在网络安全领域,这也是发现新人才和专业化的关键。但不是每个人都有时间或资源来建立他们的家庭实验室。这就是像 Hack The Box 这样的工具出现的原因。Hack The Box 由哈里斯·皮拉里诺斯(Haris Pylarinos)创建,提供了一个测试和提升渗透技能的在线平台。随着材料的不断变化,你现在可以在 YouTube 上找到有人如何侵入一个退休系统的视频。你只能找到退役系统的视频,顺便说一句,这是为了确保每个人都有公平的机会尝试新系统,并能在排行榜上排名。有趣的是,要获得一个账户,你必须黑进去。
是的,要得到你的邀请码,你必须黑进去。享受挑战吧!——承蒙 HTB
如果你正在进入网络安全领域,并且意识到有很多东西需要学习,一个好的记忆方法是开始写关于它的文章。了解如何安装一个新的 GoPhish 钓鱼服务器?写一篇关于它的博客。你面临的问题,别人肯定会遇到,你的叙述甚至可能比我经常发现的文档更好。我会一直关注 Medium 来理解一个新工具,因为经常有人写我可能没有考虑过的替代方案,或者推荐优秀的内容来帮助学习。
延伸阅读:
- 这篇文章是我在 2017 年写的一篇关于我如何获得我在网络安全领域的第一份工作的文章的更新版本。
- 安全洋葱文档
- 学习 Elasticsearch —本指南涵盖 6.3 版之前的 Elastic
- 如何在 AWS 上部署安全洋葱作者 Iain Dickson
斯蒂芬·查彭达玛