2D 直方图与 Plotly
如何用 plotly 创建更多信息量的直方图?
Plotly Python (plotly.py)是基于 plotly javascript (plotly.js)构建的开源绘图库。我喜欢 plotly.py 的一点是,它提供了一个高级 API ( plotly express )和一个低级 API ( graph objects )来创建可视化。使用 plotly express,我们可以用很少的代码行创建一个动态的、信息丰富的图。另一方面,我们需要用图形对象编写更多的代码,但是对我们创建的内容有更多的控制权。
在本帖中,我们将使用 plotly express 创建 2D 直方图,也称为密度图。
直方图是数据分析中常用的图表,用于概括数据的分布。在直方图中,数字或分类数据的分布以条形显示。每个条形代表一个值范围或类别,条形的高度与落入该范围的值的数量成比例。
让我们首先创建 1D 直方图,然后升级到 2D 直方图(或密度图)。我们将使用著名的泰坦尼克号生存数据集,该数据集在 Kaggle 上这里可用。
我们从将数据读入熊猫数据帧开始:
import numpy as np
import pandas as pddf = pd.read_csv("/content/titanic_train.csv")print(df.shape)
df.head()
我只使用包含 891 名乘客数据的训练数据集。我们首先在“年龄”和“费用”列上创建直方图。
#import plotly express
import plotly.express as pxfig = px.histogram(df, x="Age",
title="Histogram of Age",
width=800, height=500)fig.show()
我们的年龄范围很广,但大多在 20 至 30 岁之间。让我们看看“Fare”列的分布情况。
票价一栏有一些极值。出于演示目的,我将删除票价大于 100 的行。这些行约占整个数据集的 6%。
len(df[df.Fare > 100]) / len(df)
0.05948372615039282df = df[df.Fare < 100]
我们现在可以绘制“票价”列的直方图。
len(df[df.Fare > 100]) / len(df)
0.05948372615039282df = df[df.Fare < 100]
大多数票价都不到 20 英镑,当我们涨到 100 英镑时,数字就会减少。
是时候引入 2D 直方图了,它结合了 x 轴和 y 轴上的 2 个不同的直方图。因此,我们能够可视化重叠或并发的密度。
len(df[df.Fare > 100]) / len(df)
0.05948372615039282df = df[df.Fare < 100]
它看起来像是一个散点图,带有区域,而不是显示单个点。我们有一个划分票价-年龄组合的网格。plotly 的交互式绘图允许您查看每个分区代表的范围以及这些区域中的点数。黄色分区包含最多的乘客。随着颜色变暗,落入隔板的乘客数量减少。
我们还可以使用边缘参数来可视化构成该密度图的直方图。
fig = px.density_heatmap(df, x="Age", y="Fare",
title="Density Map of Age and Fare",
marginal_x="histogram",
marginal_y="histogram",
width=800, height=500)fig.show()
除了密度图之外,我们还可以看到年龄和费用直方图。
你可能已经知道,泰坦尼克号生存数据集的目的是根据数据集中给出的数据来预测一名乘客是否幸存。特征(阶级、年龄、性别、费用……)被用作独立变量来预测目标(幸存)变量。在实现机器学习模型之前,我们可以使用数据可视化来了解某些特征是否会影响存活率。
让我们使用 facet_col 参数来区分基于“幸存”列的“年龄”和“费用”的密度图。
fig = px.density_heatmap(df, x="Age", y="Fare",
title="Density Map of Age and Fare Based on Survival",
facet_col="Survived")fig.show()
密度图看起来相似,但我们可以得出结论,位于左侧图中的黄色区域会降低存活的机会。对于这两个网格,非幸存乘客与幸存乘客的比率(183/66)高于整个数据集中的相同比率(535/303)。
df.Survived.value_counts()0 535
1 303 Name: Survived, dtype: int64
我们已经用 plotly 覆盖了 2D 直方图(密度图)。当然,这只是这个神奇的图书馆的一小部分功能。我们可以使用 plotly 动态创建许多其他绘图类型。它的语法也很容易理解。在接下来的帖子中,我会尝试涵盖更复杂的情节。你也可以查看 plotly 文档,我认为它有很多不同的例子。就像任何其他主题一样,熟悉 plotly 的最好方法就是实践。因此,我建议创造大量的情节来提高你的技能。
感谢您的阅读。如果您有任何反馈,请告诉我。
分析了 Glassdoor 上的 2K 以上数据分析师工作
工作列表数据集的探索性数据分析。
马库斯·温克勒在 Unsplash 上的照片
我们生活在数据时代。越来越多的企业意识到从数据中创造价值的潜力。技术进步为收集和分析数据提供了高效的工具,这进一步推动了企业对数据科学和分析的投资。因此,我们比以往更多地在各种平台上看到像数据分析师、数据科学家、机器学习工程师这样的工作清单。
我最近在 kaggle 上偶然发现了一个数据分析师职位列表的数据集,它包含了来自 glassdoor 网站的 2253 个职位的详细信息。我想研究这个数据集,以深入了解工作的细节。使用数据分析工具也是一个很好的实践。
我们将在整个帖子中练习的技能:
- 熊猫的数据清理和分析
- 使用 NLTK 的基本自然语言处理(NLP)技术
- 用 matplotlib 和 seaborn 实现数据可视化
让我们从导入库开始。
#Data analysis
import numpy as np
import pandas as pd#NLP
import nltk
nltk.download("popular")#Data visualization
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('darkgrid')
%matplotlib inline
我们现在可以把数据读入熊猫的数据框。
df = pd.read_csv("/content/DataAnalyst.csv")
print(df.shape)
df.columns
有 2253 个工作列表,上面有关于工作和公司的各种细节。
职位描述
工作描述栏包含一个描述工作细节的长文本,以及对申请人的技能要求。为了获得一个大概的了解,我们可以阅读所有的职位描述,这绝对不是以数据分析为导向的方法。另一种更可取的方法是应用自然语言处理(NLP)技术来推断一些见解。我将使用 NLTK 库提供的工具,但是有许多文本预处理库也有相同的工具。
一种方法是统计每个单词的出现次数,以检查最常见的单词。我们首先将“job description”列转换成一个长文本文件,然后将其标记化。标记化简单地说就是将文本分割成更小的单元,比如单词。
from nltk.tokenize import word_tokenize
text = ''.join(df['Job Description'])
words = word_tokenize(text)
我们使用了 NLTK 的 word_tokenize 模块。在进一步发展之前,我们需要解决一些问题。第一个是降低所有字母。否则,“数据”和“数据”将被作为不同的词来处理。像“a”、“the”、“we”这样的词对我们的分析没有用,所以我们需要将它们从标记化列表中删除。最后,标点符号需要被删除,这样它们就不会被算作单词。
#lowercase letters
words = [word.lower() for word in words]#Remove punctuation and stopwords
punc = [',','.',';','-','"','!','--','?', '."',"'",':',')','(',"'s"]from nltk.corpus import stopwords
stop_words = stopwords.words('english')words_filtered = [word for word in words if word not in (stop_words + punc)]
我们使用列表理解来过滤初始的标记化列表。NLTK 的 FreqDist 函数提供了显示每个单词出现次数的频率分布。
fdist = nltk.FreqDist(words_filtered)
让我们检查一下最常见的单词:
fdist.most_common(20)
最常见的词是“数据”(令人惊讶!).“经验”一词紧随其后,因为企业通常会具体说明他们希望应聘者具备的经验。除了一些例外,这些词更像是一般的工作描述词。
我们可以使用 fdist 对象访问特定单词的出现次数。
fdist['software']
1160
“软件”这个词被写了 1160 次。让我们为数据分析师工作创建一个常见编程语言/技能的列表,并检查它们的频率。
common = ['sql', 'python', 'r', 'hadoop','java', 'javascript', 'c', 'c++']dict_a = {}
for i in common:
dict_a[i] = fdist[i]plt.figure(figsize=(10,6))
plt.title("Common words in job descriptions", fontsize=14)
ax = sns.barplot(x=list(dict_a.keys()), y=list(dict_a.values()))
ax.tick_params(labelsize=12)
不出所料,SQL 是第一名。SQL 的频率几乎是每个作业列表 1 个。SQL 之后是 python 和 R。如果这些是“数据科学家”的工作,我们会看到 python 和 R 比 SQL 更常见。这让我们了解了数据分析师和数据科学家之间的区别。
检查经常一起出现的单词通常会提供更多信息。例如,bigram 意味着标记化列表中的两个相邻元素。这可以扩展到任何 n 值的 n 元语法。让我们使用 NLTK 的二元语法和频率分布函数创建一个频率分布。
bigrams_list = list(nltk.bigrams(words_filtered))
fdist2 = nltk.FreqDist(bigrams_list)fdist2.most_common(20)
这个元组列表让我们对工作描述有了更多的了解。
薪资估算
Glassdoor 提供了一个薪资估算的区间。
它也不是用于分析的理想格式。让我们先把它转换成一个漂亮干净的数字格式。最简单的方法似乎是以字符 2 和 3 为下限,7 和 8 为上限。但是,我们不能这样做,因为有些工资是 6 位数(如 123K)。另一种选择是先用熊猫的剥离方法将拆分为“-”字符的上下限,然后修剪掉“$”和“K”。“薪金估计”列中只有一个值缺失,用“-1”表示。我将首先用最常见的值替换该值。
df['Salary Estimate'].replace('-1', '$42K-$76K (Glassdoor est.)', inplace=True)lower = df['Salary Estimate'].str.split('-').str[0]
upper = df['Salary Estimate'].str.split('-').str[1]
让我们从较低的开始,因为它更简单。我们只需要去掉右边的“K”和左边的“$”。
lower = lower.str.rstrip('K')
lower = lower.str.lstrip('$')
对于 upper,我们首先取前 5 个字符(考虑$121K),然后将其剥离为 lower。
upper = upper.str[:5]
upper = upper.str.rstrip()
upper = upper.str.rstrip('K')
upper = upper.str.lstrip('$')
您可能已经注意到有一个额外的 rstrip。这是因为我们采用了前 5 个字符,这导致一些值在末尾有一个空格(例如$47K)。我们现在可以通过取上下限的平均值来创建一个新的列。
upper = upper.astype('float64')
lower = lower.astype('float64')
avg = ((upper + lower) / 2)*1000
df['Avg_Salary'] = avg
我们现在有了一个清晰的数字格式的平均值。让我们首先检查所有工作列表的平均估计工资。
df['Avg_Salary'].mean()
72117
总体平均约为 7.2 万美元。位置可能会影响平均工资。位置包含城市和州。我认为最好比较各州的情况,以便有一个更概括的概念。这是“位置”栏:
我们可以使用 pandas 字符串操作轻松创建一个“state”列。
df['State'] = df['Location'].str.split(',').str[1]
Groupby 函数可以用来查看不同州的平均工资。我希望看到平均工资和列表的数量,所以我将对 groupby 应用“agg([“mean “,” count”]),而不是只应用“mean”。
df[['Avg_Salary','State']].groupby('State').agg(['mean','count']).sort_values(by=('Avg_Salary','counts'), ascending=False)[:10]
结果根据计数进行排序。加州拥有最多的工作列表和最高的平均工资。德克萨斯州有很多工作,但平均工资相对低于其他顶级州。
公司部门
数据集还包含有关公司和行业的信息。我们先来看看哪些部门的数据分析师岗位最多。
df['Sector'].value_counts()[:10]
“-1”表示缺少值。有各种各样的部门显示了数据分析师的工作是如何分布的。任何领域的企业都可以从数据中创造价值。
薪酬最高的行业是“会计和法律”,但平均工资也非常接近。
高薪工作对数据分析师的需求很大。比工作数量更重要的是,这些工作来自许多不同的行业和部门。这有力地表明了数据分析对企业的重要性。我认为,对数据分析师和科学家的需求将长期存在。
感谢您的阅读。如果您有任何反馈,请告诉我。
三,二,一,…人工智能起飞!
是的,你没看错。AI 已经爆炸了。
经过几十年的缓慢燃烧,人工智能已经孵化成为世界上主要科技公司整个议程的 P1。
*为什么?*相当简单,需要。面对不断生成和消耗的数据,人类需要一种能够学习并适应我们的新工具。那基本就是 AI 了。
我们以前认为不可能或科幻小说,今天正变得必要和高度期待的一些。技术领导者正在竞相开发人工智能解决方案,通过增加和增强人类智能为他们提供竞争优势。但是,如果我们停下来想一想,这个领域的所有进步都是基于同一个等式:
大数据+ GPU 增强+深度学习
是的,我的朋友,我们有新的人工智能可口可乐配方。
我称之为“基本方程式”。
如果你想了解更多,请访问oscargarciaramos.com
然而,正如我在我的文章 【小数据的反叛】 中所说,我们有很大的机会展望未来,并发展我们的“基本方程”,利用小数据,更全面和有效的深度学习模型,新的硬件和无监督学习使用中的深度进步。
作为显著变量的深层推理
很明显,深度学习在人工智能等式中变得越来越重要,当我们提到语音、视觉或自然语言处理的一些上下文时( **)“嘿,Siri,我能帮你吗?”T31)。
然而,深度学习尚未展示其在辅助机器推理方面的全部能力,这是许多人工智能原型和解决方案所需的能力。深度学习已经帮助我们解决了定义明确的问题,例如,我们希望对数据进行分类。然而,下一步我们必须超越分类或感知,而是推理和理解。
目前,这些系统还没有常识。 推理 帮助我们处理广泛的认知任务,包括可能的上下文变化或意外事件。人类知道,如果他们把水放在玻璃杯里,除非杯子破了,否则水不会漏。机器是怎么知道的?
那是玩阴的……
是的,我们确实已经达到了这样的程度,在标记了自由文本段落之后,我们能够将自然语言句子转换成逻辑公式。我们需要采取的下一步将是使用推理机制,以最少的努力来工作和理解这些公式。
我们如何变得更高效,进化出下一波深度学习?
小数据
是的,你是对的。小数据。
多少次我们听到“领域内没有足够的数据来馈入深度学习模型”或“数据集既不好也不相关,不足以训练模型”。我们都知道神经网络需要大量的数据来学习某项任务。然而,我们通常没有时间找到如此大量的高质量数据或资源来训练这些数据,从而导致项目时间、人工智能系统的训练、测试和改进出现偏差。
研究人员正在花费大量时间研究用更少的数据训练系统的新方法,这些方法即使规模很小,也比大量数据要好。
无监督学习
正如我们已经看到的, 监督学习 需要标记数据的繁重任务,这有时会非常令人沮丧,导致资源成本并在系统中引入偏差,因为这是一项“人工”任务。
然而,大多数人工智能远见者声称,纯粹的 无监督学习 是深度学习的圣杯,距离我们现在的位置以及能够在人工智能解决方案和模型训练的开发中实现它还很远。
当然,在不久的将来,我们将把自己定位在有监督和无监督学习之间。
我的朋友,还没有完全失去。
目前还有其他方法仍然需要监督,但它们正在帮助我们更深入地探索深度学习应用的世界:
- 强化学习 ,或者说是一个系统做得好就奖励,做得不好就惩罚的方式,随着他们的学习。
- 迁移学习 ,或者说如何将一个训练好的模型外推至一个完全新的问题。
- 主动学习 ,系统只有在需要的时候才需要新的标注数据(计算机标注 vs .人类)。
最后但同样重要的是,…
效率和硬件
大多数人工智能和分析部门专注于开发需要更小架构和更快运行的模型。
*为什么?*虽然 GPU 在训练和性能上有了质的飞跃,但仍然不够。为了训练一个模型,你仍然需要足够的计算能力和资源,首先是训练它,其次是维护它,这会降低创新和应用程序的性能。
硬件是不可能自己进化,克服计算复杂度的。算法模型增强和硬件开发之间必须存在共生关系。
*"Simulating Human thinking shouldn't be a matter of money".*
那么,接下来呢?
“鸟扇动翅膀飞行,但为了让人类飞行,我们必须发明一种不同的飞行方式——一种自然界中没有的飞行方式”。在人工智能的例子中,也会发生类似的事情。我们必须发明生物学上不存在的新型思维。
因此,这种智能并没有取代人的思维,而是增强了它”。
欢迎留下评论或分享这篇文章。跟随 我 未来的岗位。
如果你想了解更多,你可以通过oscargarciaramos.com找到我
数据科学家的 3 种先进熊猫方法
内部 AI
Pandas 是数据科学家和机器学习专业人员可以使用的一把瑞士刀。3 种用于现实项目的先进而强大的方法
照片由锡德·巴拉钱德朗和赛基兰·阿纳加尼在 Unsplash 拍摄
在我看来,Pandas 和 NumPy library 一起节省了数百小时的编程时间,是数据科学家和机器学习专业人员的宝贵工具。
如果没有很好地掌握这两个库,要成为一名优秀的数据科学家或机器学习专家几乎是不可能的。
大多数情况下,可用的原始数据只有很少的空白值,格式不正确,或者分散在几个不同的源中,带有一个主键。在这篇文章中,我将讨论三种先进的 pandas 数据准备和辩论技术,它们将有助于为机器学习算法输入设置正确的数据格式。
让我们从一个四列三行的简单样本数据帧开始。
import pandas as pddf1 = pd.DataFrame(
[["Keras", "2015", "Python","Yes"],
["CNTK", "2016", "C++","Yes"],
["PlaidML", "2017", "Python, C++, OpenCL","No"]],
index=[1, 2, 3],
columns = ["Software", "Intial Release",
"Written In","CUDA Support" ])print(df1)
样本数据帧具有三种不同的属性,即初始版本、写入和 CUDA 对三个机器学习库的支持。
数据帧 df1 —上述代码的输出
我们可以看到,机器学习库名称是其中一列,库的不同属性在各个列中。
让我们想象一下,机器学习算法期望不同格式的相同信息。它期望库的所有属性在一列中,各自的值在另一列中。
我们可以使用“”函数将数据帧从当前格式转置为期望的排列。
在 id_vars 参数中指定了原始数据帧中的列,这些列与单独的列保持相同的排列。
*df2=df1.melt(id_vars=["Software"],var_name='Characteristics')
print(df2)*
在 id_vars 参数中指定了原始数据帧中的列,这些列与单独的列保持相同的排列。原始数据帧中的所有剩余属性都填充在“特征”列下,并且在相应的列中具有值。
df1 上“熔化”功能后的数据帧 df2 上述代码的输出
许多时候,收集的原始数据是将所有属性排列在一列中,在相应的列中提到值。机器学习算法要求输入数据的每个属性值都在单独的列中。我们可以使用 Pandas 中的“”pivot*”方法将数据转换成所需的格式。*
*df3=df2.pivot(index="Software",columns="Characteristics",
values="value")print(df3)*
本质上,“融”和“枢”是互补的功能。“Melt”转换一列中的所有属性和相应列中的值,而“pivot”转换一列中的属性和另一列中的值。
数据帧 df2 上的 Pivot 函数—上述代码的输出
有时,我们的原始数据分散在几个文件中,我们需要将它整合到一个数据集中。为了简单起见,首先,我们将考虑单个数据集中的数据点已经在正确的行序列中的情况。
在新的数据帧 df4 中,为机器学习库声明了另外两个属性。
*df4 = pd.DataFrame(
[["François Chollet", "MIT license"],
["Microsoft Research", "MIT license"],
["Vertex.AI,Intel", "AGPL"]],
index=[1, 2,3],columns = ["Creator", "License"])print(df4)*
我们可以使用" concat" 函数 将这个新的数据帧与原始数据帧连接起来。
*df5=pd.concat([df1,df4],axis=1)
print(df5)*
级联的数据帧 df1 和 df4 的输出在一个数据帧 df5 中具有原始的三个属性和两个新属性
数据帧 df1 和 df4 的连接—上述代码的输出
在现实生活中,单个数据集中的大多数时间数据点不在同一行序列中,并且有一个公共键(标识符)链接数据集中的数据点。
我们有一个数据帧 df6 来存储机器学习库的“创建者”和“许可”值。“软件”是该数据帧和原始数据帧 df1 之间的共同属性。
*df6 = pd.DataFrame(
[["CNTK","Microsoft Research", "MIT license"],
["Keras","François Chollet", "MIT license"],
["PlaidML","Vertex.AI,Intel", "AGPL"]],
index=[1, 2,3],
columns = ["Software","Creator", "License"])print(df6)*
我们可以看到数据帧 df6 的行序列与原始数据帧 df1 不同。在 df6 中,首先存储“CNTK”库的属性,而在数据帧 df1 中,首先提到值“Keras”。
数据帧 df1 和 df6 —上述代码的输出
在这种情况下,我们需要合并分布在几个数据集中的原始数据,并且各个数据集中的值不在相同的行序列中,我们可以使用“ merge ”函数将数据合并到一个数据帧中。
*combined=df1.merge(df6,on="Software")
print(combined)*
在 merge 函数的“on”参数中提到了用于从不同数据集中识别正确对应值的公共键(唯一标识符)。
上述代码的输出—基于唯一标识符“软件”的合并数据帧 df1 和 df6
重述
在这篇文章中,我们学到了三个先进的熊猫功能是相当得心应手的数据准备。
Melt:将属性/特征分离到一列中,并将值分离到相应的列中
透视:将一列中的属性/功能拆分到单独的一列中
Concat:沿行或列连接数据帧。
Merge:跨不同行序列中的数据帧和值合并具有唯一标识符的数据帧。
结论
熊猫可以帮助为机器学习算法准备正确格式的原始数据。本文中讨论的 Pandas 函数如“melt”、“concat”、“merge”和“pivot”可以用一行代码转换数据集,否则将需要许多嵌套循环和条件语句。在我看来,专业和业余数据科学家之间的区别不在于对奇异算法或超级优化超参数技术的了解。对 Pandas、NumPy 和 Matplotlib 的深入了解使一些人进入了专业联盟,并使他们能够以更干净的代码和更高的性能更快地获得结果。
你可以在 5 用熊猫进行数据预处理的强大可视化中学习用熊猫进行数据可视化。
此外,像专业数据科学家一样学习探索性数据分析(EDA)高级可视化。
Edtech 的 3 个人工智能创业想法利用了因新冠肺炎而兴起的在线直播课程
Edtech 中使用最先进的计算机视觉和自然语言处理的创业想法。
图片来自 Pixabay 并由 AiArtist Chrome 插件风格化(由我构建)
在 K-12 (幼儿园到 12 年级)领域的在线辅导并不新鲜。有独角兽像 元辅道 (k-12 教育) [VIPKid](https://equalocean.com/education/20191008-vipkid-raises-an-undisclosed-amount-of-financing-from-tencent) (英语学习)基于中国在线视频辅导。有 韦丹图 在印就是迎合在线辅导。新加坡有几个小球员,比如泰诺比,在同一个场地发球。
由于新冠肺炎带来的在线课程的增加,许多初创公司都报告了更高的注册人数,其中一些公司最近从投资者那里拿到了巨额支票。投资者有 FOMO (害怕错过),因此,一旦他们感觉到某些行业将会上涨,他们就会尽快行动。
今天,我们将在在线视频辅导/课程中看到一些创意,它们有可能变成新的创业,迎合崛起。
创业思路 1:利用计算机视觉进行视频直播课堂中的注意力分散检测。
图片来自 Pixabay
在一堂正常的课中,有一位老师正在监督学生们是否在注意。但是在直播视频课堂上,老师不可能专注于每个学生的视频反馈。
因此,使用计算机视觉算法从视频馈送中自动识别注意力分散的学生并通知老师的过程至关重要。然后,老师可以向所有注意力分散的学生发出警告或轻触按钮发出轻柔的“乒”声。
在视频流中识别注意力分散还没有得到很好的研究,但是由于自动驾驶汽车的增加,在识别注意力分散的司机方面已经做了相当多的研究。一些研究直接适用于或经过微小修改后适用于班级中学生的注意力分散检测。
您还可以从视频流中检测出打哈欠和疲劳来识别不活跃的听众。
注意力分散检测算法的几个要点:
创业想法 2:自动评估(MCQs,对/错,填空)来减轻老师的工作量。
图片来自我们的创业推介资料
随着在线课程的兴起,老师们面临着一个新的挑战,即准备演示和幻灯片以使课堂更有吸引力。传统上,大多数老师仍然使用黑板来教学。但是有了在线轮班,他们有额外的工作量来准备演示文稿。
减轻他们工作负担的一个方法是将评估创建部分自动化。您可以使用最先进的自然语言处理算法来理解任何文本(章节)识别重要概念,根据内容自动创建评估(MCQs,是非题,填空题)。
我自己的关于评估自动化的研究的几点提示:
您还可以使用自然语言处理(NLP)来检测在线直播聊天中的欺凌或识别不清楚的概念 / 话题中提到的等。然后老师可以快速复习再解释不清楚的概念或者静音欺负人等等
创业理念 3:根据学习目标自动创建内容。
图片来自我们创业公司的技术平台
对于课程设计者和内容作者,一个主要的挑战是基于某些学习目标创建内容。
学习目标是学生完成一门课程后的预期目标。在上图中,我们可以看到我们如何使用 AI 来生成一个新章节关于**“尼罗河”**开始与学习目标 1) 了解尼罗河的重要性和 2) 了解埃及文明。
我们可以通过从给出的学习目标中生成初始文本和图像来自动化这个过程。课程设计者可以进一步编辑并最终确定内容。使用 NLP 中最先进的条件文本生成模型(2等)和图像生成模型(甘 s)实现这一点不再是不可能的。有了足够的数据和研究,我们可以建立一个强大的基线。
该领域研究的几个指针:
快乐学习!
使用自然语言处理的问题生成——教程
我推出了一个非常有趣的 Udemy 课程,名为“使用 NLP 生成问题”,扩展了这篇博文中讨论的一些技术。如果你想看一看,这里是链接。
祝 NLP 探索愉快,如果你喜欢它的内容,请随时在 Twitter 上找到我。
3 Python 中数据科学与软件工程的算法面试问题
熟悉常见的算法问题,为下一次面试做好准备
我上一次数据科学面试 90%都是 python 算法问题。
虽然你应该准备好解释一个 p 值,你也应该准备好回答传统的软件工程问题。
算法问题是一种可以学习的技能,公司用它来淘汰没有准备好的候选人。
下面是 3 个常见的算法问题和答案,在难度谱的容易端。
问题 1:检查两个字符串是否是字谜
变位词是通过重新排列另一个字符串中的字符而创建的字符串。
说明:
- 给定两个字符串,
s1
和s2
,如果它们互为变位词,则返回True
。 - 必须使用所有字符。
代码:
把这个复制到本地的一个代码编辑器里,写一个函数解决这个问题。
def anagram(s1, s2):
#
# your code here
#
检查您的答案:
运行此程序以确认您的功能按预期运行。
assert anagram('word', 'wodr')
assert not anagram('dog', 'dogg')
assert anagram('racecar', 'carrace')
解决方案:
这是一个解决方案,但不是唯一的解决方案。
def anagram(s1, s2):
c1 = {}
c2 = {}
def count_chars(s):
h = {}
for char in s:
if char in h:
h[char] += 1
else:
h[char] = 1
return hreturn count_chars(s1) == count_chars(s2)
上面,我们用每个字符串中的字符数创建了字典,然后比较字典的相等性。
时间复杂度是 O(n) ,因为字符串迭代和字典查找依赖于输入字符串的长度。
问题 2:找出添加到句子中的单词
说明:
- 给定一个句子,
sent1
,以及带有附加词的同一个句子,sent2
,返回附加词。 - 每一句话,
s1
,至少会有 1 个单词。
代码:
def extra_word(sent1, sent2):
#
# your code here
#
检查您的答案:
assert extra_word('This is a dog', 'This is a fast dog') == 'fast'
assert extra_word('answer', 'The answer') == 'The'
assert extra_word('Can you solve algorithm questions', 'Can you solve hard algorithm questions') == 'hard'
解决方案:
def extra_word(sent1, sent2):
words = {}
for word in sent1.split(' '):
if word in words:
words[word] += 1
else:
words[word] = 1
for word in sent2.split(' '):
if word in words:
words[word] -= 1
else:
return word
上面,我们通过字典统计了第一句话的单词。然后从同一本字典中减去第二句话中的单词。不在字典中的单词是要返回的单词。
时间复杂度是 O(n) 因为我们对每个句子迭代一次。
问题 3:嘶嘶的嗡嗡声
这是经典的 fizzbuzz 面试问题。
说明:
- 给定
n
,返回从1
到n
的每个整数的值列表。 - 如果一个数能被 3 整除,则返回
'Fizz'
代替它。 - 如果这个数能被 5 整除,则返回
'Buzz'
代替它。 - 如果数字能被 3 和 5 整除,则返回
'FizzBuzz'
代替它。
代码:
def fizzbuzz(n):
#
# your code here
#
检查您的答案:
output = fizzbuzz(1000)assert output[8] == 'Fizz'
assert output[99] == 'Buzz'
assert output[198] == 199
assert output[510] == 511
assert output[998] == 'Fizz'
解决办法
def fizzbuzz(n):
answer = []
for i in range(1,n+1):
if i % 3 == 0 and i % 5 == 0:
answer.append("FizzBuzz")
elif i % 3 == 0:
answer.append("Fizz")
elif i % 5 == 0:
answer.append("Buzz")
else:
answer.append(i)
return answer
上面,我们创建了一个给定值列表n
。然后遍历每个值,并将值 Fizz、Buzz 或 FizzBuzz 添加到列表中。
时间复杂度是 O(n) 因为我们遍历列表一次。
结论
您是否对每周 5 个算法问题和答案的系列感兴趣?请在评论中告诉我。
至于算法问题,这些都很简单,并且都可以在 O(n)时间复杂度内解决。但是如果你不熟悉这类问题,最好从基础开始。
在可预见的未来,算法问题将成为数据科学和软件工程面试的一部分。掌握这项技能的最好方法是每周做几道题。这样,如果你需要申请新的工作,你就可以随时准备好。
构建推荐系统的 3 种方法
Python 推荐系统入门
毫无疑问,推荐系统是在各种平台上增强用户体验的最明显的方式之一,也是将机器学习引入公司的一种方式。因此,许多公司一直在采用“为你推荐”的口号,这一口号已被亚马逊、网飞和 Youtube 等公司推广开来,它们通过实施自己版本的推荐来满足客户需求。
在讨论各种实现方法之前,我们首先将推荐系统定义为一种在将信息呈现给人类用户之前从信息流中丢弃冗余或无用信息的方法,或者更具体地说,它是一种信息过滤系统的子类,旨在预测用户对某个项目的“评级”或“偏好”(来源:维基百科)。
有了这些知识,我们可以开始研究解决这个问题的一些方法了——关于这篇文章中生成的完整代码,请访问 my Github 。
permalink dissolve GitHub 是超过 5000 万开发人员的家园,他们一起工作来托管和审查代码,管理…
github.com](https://github.com/kurtispykes/recommender_system/blob/master/notebooks/02_kpy_ideas.ipynb)
在下面的演示中,我们将使用 MovieLens 100k 数据集。
协同过滤
约翰·施诺布里奇在 Unsplash 上拍摄的照片
协同过滤是推荐引擎最流行的实现之一,它基于这样的假设,即过去达成一致的人将来也会达成一致,因此他们会像过去一样喜欢相似种类的项目。
协同过滤的一个例子可以是,一个朋友和我过去喜欢相同范围的书,并且他/她接着喜欢我没有读过的书,但是因为我们过去同意并且他/她喜欢我没有读过的新书,所以很可能我也会喜欢那本书,所以那本书会被推荐给我。该逻辑描述了所谓的基于用户的协同过滤。
从前面的例子来看,不是仅仅关注我的朋友喜欢什么,我们可以决定关注以前喜欢的项目的范围,并确保基于过去喜欢的项目之间的相似性向我推荐新的项目,其中相似性是通过使用项目的评级来计算的——“喜欢这个项目的用户也喜欢”。这种算法背后的逻辑被称为基于项目的协同过滤。
总之,这两种方法都属于协作过滤的范畴,即基于记忆的方法。让我们看一个 Python 中基于内存的方法的例子。
import numpy as np
import pandas as pd
from sklearn.metrics import mean_squared_error, pairwise# creating n x m matrix where n is user_id and m is item_id
user_ratings = pd.pivot_table(rating, index="user_id", columns="item_id", values="rating").fillna(0)# user and item counts
n_users = len(user_ratings.index)
n_items = len(user_ratings.columns)**print**(f"Users: {n_users}\nItems: {n_items}")
user_ratings.head()Users: 943
Items: 1682
现在我们有了所需格式的数据,我将随机生成一个训练和测试集,我们可以用它来测试我们的方法做得有多好。
# [https://www.ethanrosenthal.com/2015/11/02/intro-to-collaborative-filtering/](https://www.ethanrosenthal.com/2015/11/02/intro-to-collaborative-filtering/) def train_test_split(data: np.array, n_users: int, n_items:int):
# create a empty array of shape n x m for test
test = np.zeros((n_users, n_items))
train = data.copy()
# for each user, we generate a random sample of 5 from movies they've watched
for user in range(n_users):
random_sample = np.random.choice(data[user, :].nonzero()[0],
size=5,
replace=False)
# set the train to zero to represent no rating and the test will be the original rating
train[user, random_sample] = 0\.
test[user, random_sample] = data[user, random_sample]
return train, testtrain, test = train_test_split(data=user_ratings.to_numpy(), n_users=n_users, n_items=n_items)
构建协同过滤系统的第一步是计算用户(基于用户)或项目(基于项目)之间的相似性。
user_similarity = pairwise.cosine_similarity(train + 1e-9)
item_similarity = pairwise.cosine_similarity(train.T + 1e-9)**print**(user_similarity.shape, item_similarity.shape)(943, 943) (1682, 1682)
下一步是预测数据中未包含的评级。一旦我们做出了预测,我们就可以将我们的结果与实际测试数据进行比较,以评估我们模型的质量——评估指标超出了本教程的范围。
# predict user ratings not included in data
user_preds = user_similarity.dot(train) / np.array([np.abs(user_similarity).sum(axis=1)]).T# # get the nonzero elements
nonzero_test = test[test.nonzero()]
nonzero_user_preds = user_preds[test.nonzero()]user_rating_preds = mean_squared_error(nonzero_test, nonzero_user_preds)
**print**(f"UBCF Mean Squared Error: {user_rating_preds}")UBCF Mean Squared Error: 8.250006012927786
上面的代码是一个基于用户的协同过滤的例子。我们还可以进行基于项目的协同过滤。
# predict item ratings not included in data
item_preds = train.dot(item_similarity) / np.array([np.abs(item_similarity).sum(axis=1)])# get the nonzero elements
nonzero_item_preds = item_preds[test.nonzero()]item_rating_preds = mean_squared_error(nonzero_test, nonzero_item_preds)
**print**(f"IBCF Mean Squared Error: {item_rating_preds}")IBCF Mean Squared Error: 11.361431844412557
我们的算法不是很好,但希望你能明白其中的要点!
我们现在知道基于协作的方法可能被分类为基于内存的,我们已经在上面看到了它的 Python 实现。我们可以对协同过滤方法进行分类的另一种方式是基于模型的方法。
在这种方法中,使用不同的数据挖掘、机器学习算法来开发模型,以预测用户对未评级项目的评级(来源:维基百科)。
基于内容的过滤
另一种向用户推荐有用信息的流行方式是通过基于内容的过滤。这种技术基于项目的描述和用户偏好的简档。它最适合于这样的情况:已知一个项目的信息,但不知道用户的很多信息。因此,基于内容的过滤方法将推荐视为用户特定的分类问题。
基于内容的过滤的一个例子可以通过使用电影推荐场景来解释。想象一下,我们已经建立了一个相当新的网站,我们目前没有太多的用户信息,但我们确实有关于我们积压的电影的细节。我们要做的是获取电影的元数据/特征,如类型、演员、导演、电影长度等,并使用它们作为输入来预测用户是否喜欢一部电影。
上面的场景也暗示了我们有一个偏好的用户配置文件。这些数据可以通过用户询问来收集,这意味着用户可以设置他或她的过滤偏好,或者通过记录用户行为作为一种隐含的方法来收集。
注意:您也可以使用混合方法来获得最佳数据收集策略。
让我们看看如何在 Python 中做到这一点…
# merge data so we know the features of each movie
movies = pd.merge(item, rating, right_on="item_id", left_on="movie_id")# create a pivot table
movies_pivot = pd.pivot_table(movies, index="user_id", columns="movie_title", values="rating")# Transpose only so it fit's in the screen
movies_pivot.T.head()
# avg ratings and rating counts
avg_rating = movies.groupby("movie_title")["rating"].mean()
num_ratings = movies.groupby("movie_title")["rating"].count()# getting counts and average ratings
ratings_counts = pd.DataFrame({"avg_rating": avg_rating,
"num_of_ratings": num_ratings})# joining the new values to movie data
full_movie_data = pd.merge(movies, ratings_counts, left_on="movie_title", right_index=True)# [https://towardsdatascience.com/recommender-system-in-python-part-2-content-based-system-693a0e4bb306](/recommender-system-in-python-part-2-content-based-system-693a0e4bb306)def get_similar_movies(full_movie_data: pd.DataFrame,
movie_matrix: pd.DataFrame,
movie_title: str,
min_num_of_ratings: int = 100,
n_recommendations: int = 5
):
"""
Get similar movies based on correlation with other movies
"""
# get most correlated movies
similar_movies = movie_matrix.corrwith(movie_matrix[movie_title])
# converting to a dataframe and dropping NaN's
similar_corr_df = pd.DataFrame({"correlation":similar_movies})
similar_corr_df.dropna(inplace=True)
# store the oringinal dataframe
orig = full_movie_data.copy()
# merge with correlated dataframe but only keep specified columns
corr_with_movie = pd.merge(left=similar_corr_df,
right=orig,
on="movie_title")[
["movie_title", "correlation", "avg_rating", "num_of_ratings"]].drop_duplicates().reset_index(drop=True)
# filter movies with less than min_num_of_ratings
result = corr_with_movie[corr_with_movie['num_of_ratings'] > min_num_of_ratings].sort_values(
by='correlation',
ascending=False)
return result.iloc[1:, :].head()# test function on Toy Story
get_similar_movies(full_movie_data, movies_pivot, "Toy Story (1995)")
混合推荐系统
混合系统在现实世界中更为常见,因为组合来自不同方法的组件可以克服各种传统缺点;在这个例子中,我们更具体地讨论来自协作过滤和基于内容的过滤的混合组件。
由郑 KY,帕克 DH,李 JH (2004) [1]的论文陈述“为了有效,推荐系统必须很好地处理两个基本问题。第一,稀疏评级问题;与需要预测的评级数量相比,已经获得的评级数量非常小。因此,从少量示例中有效生成是重要的。当用户数量很少时,这个问题在系统的启动阶段尤其严重。第二,第一流的问题;除非用户以前对某个项目进行过评级,否则无法推荐该项目。
这种方法可以显著改善推荐系统的预测。
作为给读者的任务,建立你自己的混合推荐系统!(完成后与我分享)
[1]荣凯。,朴 DH。李·JH。(2004) 混合协同过滤和基于内容过滤的改进推荐系统。载于:Bubak M .、van Albada G.D .、Sloot P.M.A .、Dongarra J .(编辑)计算科学-ICCS,2004 年。ICCS 2004。计算机科学讲义,第 3036 卷。斯普林格,柏林,海德堡。【https://doi.org/10.1007/978-3-540-24685-5_37
包裹
在这篇文章中,我们介绍了三种实用的推荐系统方法,以及如何使用 Python 实现其中的两种(协同过滤和基于内容的推荐)。我知道我没有深入研究算法背后的理论或性能指标来评估它们,但如果你想更深入地了解这些专长,那么我强烈推荐 Youtube 上的吴恩达推荐系统播放列表。
让我们继续 LinkedIn 上的对话…
[## Kurtis Pykes -人工智能作家-走向数据科学| LinkedIn
在世界上最大的职业社区 LinkedIn 上查看 Kurtis Pykes 的个人资料。Kurtis 有两个工作列在他们的…
www.linkedin.com](https://www.linkedin.com/in/kurtispykes/)
3 种看待自己作为 ML 从业者的方式
听众、艺术家还是作曲家?
T 他的想法我第一次是在这本书里看到的这里,但是我觉得它太好了,你们都得读一读。
显然,并不是所有的 ML 从业者都是生而平等的,至少有几种不同的类型。下面,我们将会看到一分为三,类似于人们与音乐的三种互动。
听众们
来源: Pixabay
机器学习开源软件、在线课程和基于云的工具的浪潮让新来者不必担心 ML 管道的细节。
在 ML 的世界里,现成工具的可用性是一件好事,也是一件坏事。这是因为,虽然没有经验的用户可以很容易和容易地从机器学习中受益,但可以肯定的是,他们中的一些人并不真正知道他们在做什么,也不理解。因此,对他们的数据/模型得出错误的结论是很常见的。
这些被称为监听器,因为就像在音乐的情况下,用户能够选择不同类型的算法,辨别它们之间的表面差异,并从它们的使用中受益。
艺术家们
来源: Pixabay
与听众相比,艺术家有足够的勇气将不同的方法和分析插入到管道中。对于这一类人来说,非常重要的是他们掌握所用工具背后的数学知识的程度。他们并没有真正深入到所用方法的各个方面,但是他们很好地理解了背后的机制,以及需要调整什么来提高他们模型的性能。
这些人被称为艺术家,因为就像小提琴歌手一样,高技能的练习者可以将他们的乐器带入生活并激发观众,他们可以在他们的 ML 练习中增加一些趣味。
作曲家们
来源: Pixabay
大师们来了。
可以边听边玩。你可以拉小提琴,而且会拉得很好。但可能创造自己的音乐作品并不是一件容易的事情。ML 从业者也一样。
的创造者:
属于作曲家的范畴。他们不仅喜欢“听音乐”,完美地“演奏”音乐,而且还“创作”了杰作。
很有可能,你现在可能不是一个作曲家,但是只要有纪律和热情,你可以做到。
最后的想法
这是一本小册子,应该如此对待。如果你热爱你所做的事情,并且你的工作提供了价值,你是哪种类型的 ML 从业者并不重要。
如果你喜欢我的作品,可以考虑看看我的其他帖子:
还是不是?
towardsdatascience.com](/why-do-we-use-0-05-8cd43a39edfa) [## 标准偏差与标准误差
[警告这太容易了] -包含简短的示例 R 代码
towardsdatascience.com](/standard-deviation-vs-standard-error-5210e3bc9c04)
直到下次,继续学习。
Python 中股票市场分析的 3 个基本步骤
用 Python 分析特斯拉股票,计算交易指标,绘制 OHLC 图表。包括一个带有代码示例的 Jupyter 笔记本。
克里斯·利维拉尼在 Unsplash 上的照片
我最近开始阅读斯坦·温斯坦的《在牛市和熊市中获利的秘密。在他的书中,Stan 揭示了他成功的投资时机选择方法,以产生持续盈利的结果。
许多投资者说“这是你需要阅读的唯一一本投资书籍”
斯坦·温斯坦是专业的股票市场技术分析师。1987 年,他利用自己的图表阅读技巧,预测了股票市场 31%的崩盘,由此一举成名。
我其他关于这个话题的文章:
我用 Python 写的关于股票市场分析的文章的精选列表。
romanorac.medium.com](https://romanorac.medium.com/stock-market-analysis-in-python-b71bf50151d9)
这里有几个你可能感兴趣的链接:
- [Complete your Python analyses 10x faster with Mito](https://trymito.io/) [Product]- [Free skill tests for Data Scientists & ML Engineers](https://aigents.co/skills) [Test]- [All New Self-Driving Car Engineer Nanodegree](https://imp.i115008.net/c/2402645/1116216/11298)[Course]
你愿意多看一些这样的文章吗?如果是这样,你可以点击上面的任何链接来支持我。其中一些是附属链接,但你不需要购买任何东西。
介绍
这是 Python 中股票市场分析系列的第一篇文章,在这篇文章中,我将尝试描述和实现在股票市场中获利的成功技术。
让我们从基础开始。在本文中,您将了解到:
- 用 Python 获取股票数据的最简单方法
- 什么是交易指标,如何计算
- 如何用 OHLC 图表绘制股票数据
注意,我不是专业投资者,我不对你的损失负责。这是教育内容。
马特·邓肯在 Unsplash 上拍摄的照片
1.获取股票数据
用 Python 下载股票历史数据最简单的方法是用 yfinance 包。要安装该软件包,只需运行:
pip install yfinance
使用 yfinance 将 Tesla (TSLA)的每日股票价格下载到熊猫数据框架中非常简单:
df = yf.download("TSLA", start="2018-11-01", end="2020-10-18", interval="1d")df.head()
特斯拉股票的每日价格
yfinance 下载函数有很多参数:
- 您可以使用 1m、2m、5m、15m、30m、60m、90m、1h、1d、5d、1wk、1mo、3mo,而不是将间隔设置为 1d。
- 您可以在一个列表或字符串中定义多个 tickers:“间谍 AAPL MSFT”。
- 您可以使用“ytd”来下载从今天起一年内的数据,而不是开始和结束日期。其他有效期间包括 1d、5d、1mo、3mo、6mo、1y、2y、5y、10y、ytd、max。
- 详见y 金融。
yfinance 还有许多其他有用的函数,比如股息函数。假设我们想列出美国电话电报公司(T)的股息。
t = yf.Ticker("T")t.dividends
t.dividends.plot(figsize=(14, 7))
美国电话电报公司股息增长
2.计算交易指标
交易指标是数学计算,在价格图表上绘制成线条,可以帮助交易者识别市场中的某些信号和趋势。
TA-LIB
TA-LIB 是 Python 中技术分析使用最多的库之一。
要使用它,首先需要安装 TA-LIB 依赖项:
# Mac OS X
brew install ta-lib# see [https://github.com/mrjbq7/ta-lib](https://github.com/mrjbq7/ta-lib) for other platforms
然后需要安装 python API:
pip install TA-Lib
移动平均数
移动平均线(MA)用于确定当前价格趋势的方向,不受短期价格上涨的影响。
MA 指标结合了特定时间范围内的股价点,并除以数据点的数量,得出一条趋势线。
让我们计算 TSLA 收盘价的 20 天(短期)和 200 天(长期)MA(我们可以用熊猫直接计算 MA):
df.loc[:, 'ma20'] = df.Close.rolling(20).mean()
df.loc[:, 'ma200'] = df.Close.rolling(200).mean()
短期和长期移动平均线的特斯拉价格
为什么均线很重要?
交易者观察短期均线与长期均线的交叉,作为趋势变化的可能指标,以进入多头和空头头寸。
斯坦·温斯坦认为:要想买入一只股票,价格必须在短期 MA 以上。
RSI——相对强度指数
相对强弱指数(RSI)是技术分析中使用的一种动量指标,用于衡量最近价格变化的幅度,以评估股票或其他资产价格的超买或超卖情况。
RSI 显示为一个振荡器(在两个极端之间移动的线形图),读数可以从 0 到 100。它通常用于 14 天的时间段。
相对强弱和相对强弱指数一样吗?
如果你正在阅读斯坦·温斯坦的《在牛市和熊市中获利的秘密》,斯坦提到了相对强度,但不要把它和 RSI 混淆。
相对强弱表明一只股票相对于另一只股票、指数或基准的价值,而相对强弱表明一只股票相对于同一只股票近期表现的表现。
让我们计算 TSLA 的相对强度
import talibdf.loc[:, "rsi"] = talib.RSI(df.Close, 14)
现在,让我们绘制 RSI 图,30 表示超卖,70 表示超买:
import matplotlib.pyplot as pltfig, ax = plt.subplots(1, 2, figsize=(21, 7))ax0 = df[["rsi"]].plot(ax=ax[0])
ax0.axhline(30, color="black")
ax0.axhline(70, color="black")df[["Close"]].plot(ax=ax[1])
14 天 RSI 左边是特斯拉收盘价,右边是特斯拉收盘价。
RSI ≥70 的资产通常被认为超买,而 RSI ≤ 30 的资产通常被认为超卖:
- 超买信号表明资产价格可能会回调。
- 超卖信号可能意味着短期下跌即将成熟,资产可能会反弹。
在上图中,我们可以观察到 TSLA 价格随着 RSI 的变化而变化的模式。当超买(RSI ≥70)时,价格处于修正阶段,反之亦然。
3.绘制股票数据
在这一节中,我们将看到如何绘制 OHLC 图,这是一种我们在交易平台上常见的开盘价、最高价、最低价和收盘价的图表。
我们将使用 Plotly 库来制作 OHLC 海图。要安装它:
pip install plotly
如果您使用的是 JupyterLab,您还需要安装一个 Plotly 扩展,以便 JupyterLab 可以呈现 Plotly 图表:
jupyter labextension install jupyterlab-plotly
为了用 Plotly 绘制 OHLC,我们只需要在正确的投入上设定价格。
import plotly.graph_objects as gofig = go.Figure(
data=go.Ohlc(
x=df.index,
open=df["Open"],
high=df["High"],
low=df["Low"],
close=df["Close"],
)
)
fig.show()
特斯拉股价的 OHLC 图表
在你走之前
像往常一样,你可以下载这个 Jupyter 笔记本在你的机器上尝试例子。
在推特上关注我,在那里我定期发关于数据科学和机器学习的推特。
照片由Courtney hedge在 Unsplash 上拍摄
AWS 开发者认证对机器学习工程师的 3 个好处
对我如何选择该认证及其主要优势的详细回顾
Joshua Hoehne 在 Unsplash 上拍摄的照片
如果你正在处理数据,并且你正在考虑参加你的第一个 AWS 认证,你可能想知道 哪一个是适合你的。
这对我来说是一个很难的选择,因为在 AWS 有 12 种可能的认证。经过一番研究,我选择了 AWS 开发者助理认证。但这并不容易。
这就是为什么我想分享我的故事。我希望这篇文章能对 AWS 开发者认证如何帮助获得一些新知识有所帮助——特别是如果你是一名机器学习工程师。
我希望在这篇文章结束时,你会更有信心回答 AWS 开发者认证是否适合你这个问题。
AWS 认证:选择正确的认证
正如我今天早些时候提到的,在 AWS 中有 12 种可能的认证。他们分为四个级别:基础、助理、专业和专业。
[## AWS 认证-验证 AWS 云技能-获得 AWS 认证
AWS 认证验证云专业知识,帮助专业人员突出按需技能和组织构建…
aws.amazon.com](https://aws.amazon.com/certification/)
如果您正在讨论数据,那么 AWS 中有两个认证可能会引起您的兴趣。数据分析专业和机器学习专业。但是……总有但是。对吗?
AWS 为数据分析专业推荐至少 5 年数据分析技术经验和 2 年 AWS 实际操作经验。
另一方面,对于机器学习专业,AWS 建议1-2 年在 AWS 云上开发、架构或运行 ML/深度学习工作负载的经验。
所以,如果你不符合建议的要求,你应该考虑开始另一个 AWS 认证。
不要误会,这是不,你不能去的专业。我只是说,如果你想在从事专业工作之前学习一些东西,你可以从其他地方开始。
有些人建议从其他认证开始,而不是从专业开始。特别是,他们建议从助理级别开始。
[## 我希望有人告诉我如何获得 AWS 认证:自学的技巧和诀窍
一年多来,我每天都和 AWS 一起工作,这时我的脑海中出现了追求 AWS 认证的想法。为什么…
medium.com](https://medium.com/@brunoamaroalmeida/what-i-wish-someone-had-told-me-about-pursuing-an-aws-certification-tips-tricks-for-self-study-a9244462a1a1)
虽然你可以从基础级别开始,通过云从业者认证,但许多人不推荐它,因为他们声称它面向想要熟悉 AWS 技术的非技术人员。
“在过去的一年里,AWS 推出了可以说是他们向 AWS 合作伙伴网络 (APN)中的非技术专业人员提供的最佳计划之一**:AWS 认证云从业者认证。该计划对那些从事销售或营销工作的人来说尤其有价值,它不提供任何用于销售或营销 AWS 的高科技产品或服务。相反,它提供了一个学习途径和一个认证,旨在为个人提供必要的知识和技能,以有效地展示对 AWS 云的整体理解。”—煤火小组**
[## AWS 认证云从业者:对非技术角色的专业人员的宝贵认证
在过去的一年里,AWS 推出了可以说是他们向非技术人员提供的最好的项目之一…
www.coalfire.com](https://www.coalfire.com/the-coalfire-blog/may-2018/aws-certified-cloud-practitioner-certification)
尽管如此,如果你是 AWS 的初学者,并且想从头开始学习,云从业者认证还是很有帮助的。
AWS 助理级别认证
有三种可能的认证,你可以考虑在准水平。
这是一份来自云专家的帖子的迷你简历,其中提到了三种可能的认证:
- **解决方案架构师:**这一部分关注如何使用架构最佳实践在 AWS 云中构建和部署系统——参见参考资料,如 AWS 良好架构的框架。
- SysOps: 对于任何在 AWS 上运行东西的人来说,这是一个“T2”。这个考试在 CloudWatch 上进行得相当深入。通过这一认证会让您更好地了解 AWS 架构中的实际情况。”
- **开发人员:**这一期侧重于从较低层面理解 AWS 服务是如何工作的。它侧重于通过遵循 AWS 的最佳实践来测试您使用和连接服务的能力。
所以你在考虑获得 AWS 认证。太好了!云计算技能需求巨大,无论…
acloudguru.com](https://acloudguru.com/blog/engineering/which-aws-certification-should-i-take)
在这一点上,我会鼓励你考虑哪一个认证最吸引你。对我来说,是 AWS 开发者认证。由于我的角色,这是最适合我的。
动机
有一次,我在训练一个机器学习模型,我遇到了一些与模型部署相关的问题。特别是,我不知道怎么做或者怎么消费。
我曾经工作过的公司的首席技术官当时告诉我一件让我记忆犹新的事情:
"我希望您能够部署自己的模型。我不希望你培训他们,把他们留在你的电脑里,因为你不知道如何把他们投入生产… ”
如果你读了那句话,那会让你想起 AWS 开发者认证可能是你的第一步。
AWS 开发人员认证—助理:内容和优势
如果你是机器学习工程师,这个认证可以帮助你解决一些问题。
**但是首先要知道,这个认证的重点不是机器学习工程。**但是,我相信如果您了解一些 AWS 服务及其最佳实践,有些事情会变得更容易
考试内容分为 5 个领域:
- 部署:检查的 22%
- 安全性:占考试的 26%
- 带 AWS 服务的开发:占考试的 30%
- 重构:占考试的 10%
- 监控和故障排除:12%
这些领域中的每一个都可以帮助您获得关于 AWS 的丰富知识。特别是,我在这个认证中发现了三个主要的好处可以帮助你这个机器学习工程师…
机器学习工程师的优势
1.了解如何部署和使用机器学习模型
我们都知道部署和使用机器学习模型并不容易。它有许多挑战,并不是所有的人都训练有素。
假设您需要部署一个模型来处理一些照片。假设你要对照片中的东西进行分类,*例如,*是否有狗。
首先,您必须部署模型。那你就要消耗掉它。为此,您需要读取图像,对其进行处理,进行分类,然后保存结果以供进一步分析。
这就是 AWS 开发者认证可以帮助你的地方!该认证将让您了解更多关于 AWS 服务开发的知识。
如果你仔细观察,部署和消费机器学习模型遵循软件开发的生命周期。因此,更多地了解它会给你一些你现在可能缺少的工具。
例如,您将学习如何使用一些 AWS 服务,如 AWS Lambda、ECS、Dynamo、SNS、SQS 等等。另外,你会学到很多关于无服务器的方法和一些关于 AWS 开发的最佳实践。
2.了解 CI/CD 管道
一旦将机器学习模型部署到生产中,还会出现其他问题。
例如,您可能希望自动执行其重新培训过程,或者在重新培训后自动执行其部署。
我知道,你可能会想*“等一下。DevOps 团队就是这么干的!”你可能是对的。他们可以帮助你做到这一点。*
但是,我相信如果你对 CI/CD 了解得更多一点,DevOps 团队会感谢你的。如果你了解这个过程,你可以学习 CI/CD 的一些最佳实践,这对整个团队都有好处!
例如,您将学习如何使用一些 AWS 服务,如 AWS CodeCommit、CodeBuild、CodeDeploy、CodePipeline、X-ray、Cloudwatch 等。
3.学习 AWS 基础知识
相信我。你需要学习 AWS 的基础知识。我们不知道的事情太多了…
我记得有一次我刚开始用 AWS 的时候,我在写一个 Lambda。任务很简单。lambda 将对数据进行红移,进行一些处理,并查询一个端点。但是,lambda 超时了。花了整整一个下午才弄清楚超时与 VPC 配置有关。
你明白了吗?学习基本面很重要!不要像早期版本的我。
您将在认证中学习的一些基础知识与 IAM、VPCs、互联网网关、NAT 网关、安全组等服务相关。
认证考试准备
经过三个月的学习,我通过了我的 AWS 开发者认证。
我通过参加 Linux Academy (现已被一位云专家收购)的 AWS 认证开发者课程来准备考试。
[## 在线课程| 2020 年 AWS 认证开发人员助理|云专家
我们使用 cookies 来确保您在我们的网站上获得最佳体验。如果您同意我们使用 cookies,请…
咕噜咕噜](https://acloud.guru/learn/aws-certified-developer-associate?opt_id=oeu1597066625814r0.02678598007629196&_ga=2.78320412.90951335.1603291362-108285620.1597066626)
2020 年 8 月更新]:所有问题都已重新编写,添加了详细的解释,并基于…添加了新问题
www.udemy.com](https://www.udemy.com/course/aws-certified-developer-associate-practice-tests-dva-c01/)
如果你不想学习 Linux Academy 的课程,我会鼓励你购买模拟考试测试。他们真的很有帮助。我敢说,没有他们,我不会通过认证考试。
结论
我知道这是一篇很长的文章。但我试图向您展示我是如何做出决定的,以及我在认证中发现的好处。
希望这些信息有助于回答 AWS 开发者认证是否适合你的问题。
感谢阅读到最后。
下期帖子再见!
如果你想随时更新我的作品, 请加入我的 简讯 ! 我会努力为你提供信息和资源,让你成为更好的数据从业者!
2020 年及以后成功程序员的 3 本书
托马斯叶
尤其是对于那些渴望成为下一个科技巨星的应届毕业生来说
众所周知领导者是读者,这一点在科技行业确实适用,就像在其他任何地方一样。然而,这篇文章并不是要向你宣扬阅读对于成功人生的必要性。
毕竟,通过打开这一页,你自愿决定用你生命中的 10 分钟来学习阅读好书,所以我将继续下去,假设你是“领导者就是读者”教条的坚定信徒,并直奔主题。
在今天这个信息丰富的时代,考虑任何话题,你都会发现一个巨大的可用资源聚宝盆来研究。一旦你决定要学习某样东西,你很快就会发现自己面临选择的暴政:“既然外面有那么多,我应该从哪里开始?”
这是我能帮忙的地方。假设你对软件开发的艺术和如何推动自己更上一层楼感兴趣,让我向你介绍我个人最喜欢的 3 个主题。不是令人畏惧的 25 个把你吓跑,而是仅仅 3 个,因为这足够让你开始了。
对于每本书,让我给你一个内容的简要总结,解释这本书的教训如何直接适用于我们的技术狂经济的现状,以及这方面的知识如何转化为对你的竞争对手的优势。
除了让我成为一个更有效的程序员(和一个更好的人),这些书还帮助我理解了教育、技术和商业,以及这些是如何在人类对创新的不懈追求中联系在一起的。我真诚地相信他们也能为你做同样的事情。因此,事不宜迟,让我们从**第一册)**开始吧。
第 1 册)——>斯科特·盖洛韦著
你有没有想过脸书的巨额财政收入是从哪里来的?或者说,苹果公司是如何以与三星手机几乎相同的质量收取如此高的溢价的?好吧,读读这本书,你就不会再有疑问了。
《四个 T1》是一次深入亚马逊、苹果、脸书和谷歌这四大科技巨头内部运作的令人大开眼界的旅行。读完之后,你会理解并真正欣赏当一个人将丰富的数据与能够从中提取有价值信息的智能算法相结合时所释放的巨大力量。
一旦得到认可,你将不再对脸书的市场估值高达数千亿美元感到困惑,尽管它“只是一个社交网络”,似乎没做什么。剧透,它确实很多在引擎盖下。
我发现这本书后面的章节特别有用,作者为进入这个行业的年轻人提供了一些建议,告诉他们如何利用四大巨头创造的经济,让自己走向成功。
换句话说,如果你想在今天由脸书、亚马逊、谷歌和苹果主导的就业市场中蓬勃发展,你可以把这本书看作是在商业、营销、教育和技术的交叉点上导航这个复杂景观的实用指南。
太好了,看完书 1)你就会熟悉“大科技”游戏的规则,准备征服世界。也就是说,获准在四个大联盟中的一个参加比赛并不容易,尤其是对新手来说。
幸运的是,第二本书是以技术面试的形式让你通过那些可怕的看门人,并通过获得你的第一份梦想工作来帮助你启动你的技术职业生涯。
第二册)——>破解编码访谈作者格利·拉克曼·麦克道尔
这本书已经成为计算机科学专业大学生的圣经,他们希望在一家高端科技公司获得实习和第一份全职工作,同样是亚马逊、苹果、脸书、谷歌,但这一次这份名单被微软和 Palantir 扩大了。为了接下来几段的目的,让我们把这 6 家公司的集合称为“六”。
****第一册)和第二册)构建其内容的基础假设(到 2020 年末成立)有三重:
- 在六家公司中的一家工作是最近的科技毕业生非常渴望的
- 在六家公司中的一家找工作竞争非常激烈,因此也很难
- 六家公司的招聘流程都非常相似
假设 1 在第一册)中有详细介绍。现在,书 2) 关心的是点 2 和点 3。更准确地说,它的目的是让年轻、有抱负、有抱负的技术超级明星做好准备,在与六个中的一个的技术面试中脱颖而出,从而获得他们梦想中的工作。****
这些公司的面试是出了名的技术性,非常注重应聘者解决问题和编写代码的能力。这本书的结构尊重这种现状,分为两部分。
第一部分(软技能部分)是关于工作的非技术性方面,比如你应该穿什么,可以问什么问题,如何进行有效的电梯推销,以及如何谈论你过去的经历以引起面试官的兴趣。
它还包含了一系列严格的不要做的事情,不管你有多有才华,这些事情都会立刻让你关门大吉。一定要把这些记在某个地方,不惜一切代价避免它们。
本书的其余部分(即超过 80%的部分)是所谓的技术部分,是在六个中的一个的真实世界面试中候选人遇到的问题样本的集合,并附有描述性的解决方案。
您可能没有时间浏览作者在技术部分中介绍的数百个技术示例。不要担心,我也没有。但是我建议详细研究这本书的第一部分,然后解决每个技术部分的几个问题。
信不信由你,许多准备从头开始背诵散列图实现的精明工程师经常被简单的查询弄得措手不及,比如:“那么,托马斯,告诉我一点关于你自己的情况”。我自己也去过,这一点也不好玩!第一部分 Book 2) 是特别设计的,这样你就不会像我一样结束,所以不要跳过它。
最后,即使你不打算为六个中的一个工作,通读这本书并学习搞定工作面试的艺术(技术和非技术方面)很可能会被证明是你一生中最有价值的投资之一。
那是因为在我们这个时代,面试已经成为事实上的找工作的标准。如果你已经准备好参加第六次、第十九次(即的面试,这是最难的面试之一),你应该已经做好准备,可以顺利通过世界上几乎任何其他工作的面试。
安德鲁·亨特和戴维·托马斯的《实用程序员》
很好,读完第 1)和第 2)本书,你就知道科技游戏大概是什么样子了,你也知道如何在谷歌和 Facebooks of the world 和其他酷孩子一起玩了。
现在你可能会问自己:一旦我进入大联盟,我该如何让自己脱颖而出?是什么让克里斯蒂亚诺·罗纳尔多在科技界与当地球员区分开来?
简短的回答是努力工作和经验。现在有办法解决了。然而,你可以通过专门的学习和比你级别高的优秀员工的指导来加速你的提升。
想象一下那些高级工程师,他们在职业生涯中不得不面对的所有陷阱,以及他们从这些陷阱中学到的无数教训。正是这种来之不易的智慧让他们在工作中如此出色。如果把它写在某个地方,让年轻一代学习并应用到他们的实践中,而不是用他们自己的血汗和眼泪来支付,这不是很好吗?
****好消息!第三册)(务实的程序员)正是这样,一个技巧、窍门和习惯的汇编,有效的程序员使用它们来编写干净、设计良好的代码,满足业务期限并交付尖端软件,同时为他们的工作赢得信用以及同事工程师和关键业务利益相关者的信任。
事实是,软件工程不是短跑,而是马拉松。作为一名程序员,要爬上成功的阶梯,你需要生产高质量的工作,而且你需要经常生产,在稳定和一致的基础上。
**作为**第三册)如何帮助你成为软件工程顶尖高手的一个例子,请看下面这本书里我经常使用的 3 个我最喜欢的技巧,我可以很容易地证明它们的采用使我在我所做的事情上变得更好(当然,书中还有许多其他可爱的技巧)
- 学习如何估计你的工作(说:“任务 X 将花费我 N 天时间。”而不是:“我不知道完成 X 需要多长时间…”)
- 自动化重复性任务(通常使用 shell 脚本)
- 不要请求允许(宁愿以后请求原谅……)
有趣的事实:技巧 3 是我在亚马逊的现任越级经理最喜欢给团队新成员的一条智慧。我想知道他是不是也是从这本书里得到的…
以我自己为例,当我刚从大学毕业就被推进一家美国公司而引发认知失调时,我读了一些书。当时,我认为作为一名程序员,我会花大部分时间写代码。我大错特错了…
当我准备艰难地学习时,软件工程是一门非常复杂的学科,它给从业者带来了定义模糊的问题、紧迫的期限和不断要求的客户。
要想成功,除了编码,你还需要掌握更多的技能。这是因为编写代码只是您将要交付的端到端解决方案的一部分,而且实际上是相对较小的一部分。
幸运的是, Book 3) 可以为你提供一种实用主义哲学,这种哲学寻求在保持代码纯净和保持业务运行之间找到正确的平衡。
有了实用的精神操作系统,你不仅可以避免因构建重要软件时的模糊性和压力而导致的精神错乱,还可以让自己在这个不断要求和令人兴奋的领域获得成功。
感谢您阅读我的文章
正在寻找一位导师来帮助你在科技世界茁壮成长?
订阅我的 邮箱列表 !
托马斯·叶
体操运动员、数学家和软件工程师
随时与我联系 LinkedIn :
资源
选择的暴政->https://www . scientific American . com/article/the-暴政的选择/****
领导是读者->https://www . PDA . org/PDA-Europe/news-archive/full-story/2017/03/06/4-原因-领导-是读者
斯科特·盖洛威著->-https://www . Amazon . com/Four-Hidden-Amazon-脸书-Google/dp/0525501223
安德鲁·亨特和戴维·托马斯的《务实的程序员》->https://www . Amazon . com/practical-Programmer-joyneman-Master/DP/020161622 x
破解编码采访盖尔·拉克曼·麦克道尔->https://www . Amazon . com/Cracking-Coding-Interview-Gayle-McDowell/DP/0984782850
每个数据科学家都应该知道的 3 个条件
图示条件方差(图片由作者提供)
条件期望、条件概率和条件方差:回归建模者的实践见解
条件期望
随机变量的条件期望是我们期望它取的值,条件是它所依赖的另一个变量取一个特定值。
**如果这听起来很拗口,不要绝望。**我们将很快进入这个概念的“啊哈”时刻。为了帮助我们的探索,我们将使用泊松分布的随机变量 Y 作为我们的主角。
所以设 Y 为平均发生率 λ 的泊松分布离散随机变量。
的 P 概率 M 屁股 F 油膏看起来如下。( PMF 只是离散随机变量的概率分布的另一个名称):
泊松(λ=20)随机变量的 PMF
【Y】的期望值,记为()【T47),是以下各项的乘积之和:**
- Y 在其范围【0,∞】、和内的每一个值,
- 其对应的概率P(Y= Y),摘自其 PMF。换句话说,如下:
离散随机变量的期望值(图片由作者提供)
**关于期望值的事情是,如果你把你的钱押在 Y 的任何一个值上,E(Y)是你应该押的。
在 Y 是泊松(λ) 分布的情况下,可以证明 E(Y) 就是单纯的 λ 。在上图所示的样本分布中,E(Y)= 20。**
**如果 Y 是一个连续值的随机变量,如正态分布的随机变量,E(Y)计算如下:
无条件期待连续的 Y (图片由作者)
其中 f(y) 是Y的 P 概率 D 密度F*function(PDF)*【a,b】是其区间 。
那么关于这个期望的条件是什么呢?在这种情况下,什么都不是,因为 Y ,按照我们的定义,是一个独立变量,即它的值不依赖于任何其他变量的值。
我们现在介绍另一个主角:变量 X 。有了图中的 X ,我们可以考虑 Y 依赖于 X 的情况,即 Y 是 X: 的某个函数
Y= f(X)。**
**一个简单的例子 f(。)是 Y 和 X 之间的线性关系:
**=β0+β1 * X
其中 β0 为截距 β1 为直线的斜率。
让我们扮演一下上帝。我们将声称知道 Y 和 X. 之间的真实关系如下(但是不要让你头脑中的回归建模者知道这个真实关系!):
Y= 20+10**** X*****
下面是 Y 对 X 的剧情:
Y= 20+10*** X***(图片由作者)***
等等,但是 Y 不是一个随机变量吗?因此,对于 X 的每个值,我们会期望占据一个或多个由***【Y】的概率分布(PDF 或 PMF)控制的随机值。Y 的这种随机行为导致了下面这种图,Y对 X而不是我们之前看到的非常整齐的图:*******
一个更现实的 Y 对 x 的曲线被假设为泊松分布的随机变量。(图片由作者)**
再次回忆一下,在我们的例子中,我们假设 Y 是泊松(λ) 分布。原来泊松分布的 PMF 的参数 λ 在我们之前看到的 Y 对 X 的整齐直线图和上图所示的对 X 的涂抹图之间形成了结缔组织。具体来说, λ 是 X 的如下线性函数:****
λ(X)= 20+10* X******
但正如我们在文章开头所指出的,一个泊松(λ) 分布随机变量的期望值即E(Y),就是的简单λ。因此,对于 的某个值 X :**
E(Y|X)=λ(X),从而:
E(Y|X)= 20+10* X******
符号E(Y|X)是对XY的*条件期望,条件是 X 取一个特定值*******
比如在 Y 对 X 的整齐直线图中,当X****= 6时,**
E(Y|X= 6)= 20+10 * 6 = 80。
所以现在我们可以说,当 X =6, Y 是一个均值 λ 为 80 的泊松分布随机变量。
我们可以对 X 的每一个值进行类似的计算,得到X****= X对应的条件期望Y这样做让我们“叠加”两个 Y 对 X 图,如下所示。橙色点是 Y 的泊松分布样本的条件平均值,由蓝色点表示。**
E( Y | X )叠加在 Y (图片由作者提供)
一般来说,如果 Y 是一个随机变量,并且与**【X】具有线性关系,我们可以将这种关系表示如下:**
E(Y | X= X**)=β0+β1*X
其中 E(Y | X= X**)称为以 X 取值为条件的 Y 的期望值******
条件期望,又称 Y 对的条件均值,也可以简写为E(Y|X)。****
现在是关于条件概率分布的部分:
我们将看到 解释变量 X 如何通过参数 λ: 进入泊松分布 Y 的 PMF
到目前为止,我们已经看到:
E(Y | X= X**)=λ(X= X)=β0+β1*****X
我们还知道, Y 的 PMF 由下式给出:
PMF 的泊松(λ) (图片由作者)
在上面的等式中,用β0+β1X替换 λ ,或者确实用任何其他函数f(X)X,就宾果! Y 取特定值 y 的概率现在突然依赖于×取特定值 x 。请参见下面更新的 PMF 公式:*****
泊松的条件 PMF(λ(X))(图片由作者)
换句话说, Y 的 PMF 现在已经转化为一个 条件概率分布函数 。这不是很棒吗?
Y 可以有任何一种概率分布,离散的、连续的或混合的。同样, Y 可以通过任何一种关系 f(.)介于 Y 和 X 之间。因此,对于Y 为离散随机变量的情况,我们可以将Y对 X 的条件期望写成如下:
离散随机变量的条件期望(图片由作者提供)
其中P(Y= Y _ I |X= X)是条件概率 质量 函数的 Y 。
如果 Y 是一个连续的随机变量,我们可以把它的条件期望写成:
连续随机变量的条件期望(图片由作者提供)
其中f(Y= Y _ I |X= X)是条件概率 密度 函数Y。**
条件概率分布和条件期望在回归模型的规范中占有突出的位置。我们将在线性回归的上下文中看到两者之间的联系。
条件期望和回归建模
假设给我们一个(y,x)元组的随机样本,该样本取自前面图中所示的总体值:
(y,x)值的随机样本(图片由作者提供)
还假设您已决定将线性回归模型拟合到此样本,目标是从 x 预测 Y。在您的模型被训练(即拟合)到样本后,模型的回归方程可指定如下:
【Y _(预测)=+β1 _(拟合)X*
其中 β0_(拟合) 和 β1_(拟合) 为拟合模型的系数。现在让我们跳过安装步骤。下图显示了上述样本图的拟合模型。我已经叠加了 Y , E(Y|X) 的条件期望,对于 X 的每个值:
样本 Y,E(Y|X)和拟合的模型(图片由作者提供)
从图中可以看出,拟合的模型并没有完全通过 Y 的条件期望。每种情况下都有少量的误差。让我们算出这个误差为 X =8 :
***When ***X***=8:
We know *E(****Y****|****X****)* because we are playing God and we know the exact equation between ***Y*** and ***X****:
E(****Y****|****X****=8)* = 20+10*8 = 100Our model cannot God, so at best it can only estimate *E(****Y****|****X****)***:
*Y_predicted****|****X****=8* = 22.034 + 9.458 * 8 = 97.698Thus the **residual error *ϵ*** for ***X****=8* is 100 - 97.698 = 2.302***
这样,我们也可以找到所有其他值 X 的残差。
我们现在可以使用这些剩余误差项,根据拟合模型的系数来表达 Y 的条件期望。这种关系为×****= 8看起来是这样的:**
E(Y|X= 8)= 100 = 22.034+9.458 * 8+2.302
或者总的来说,我们有:
e(y|x)=【β0 _(拟合)*+**【β1 _(拟合)X + ϵ
换句话说:
E(Y|X) = Y_(预测)+ ϵ
其中 ϵ 是回归模型的误差,又称模型的残差。
一般来说,对于“表现良好”的模型,当您在越来越大的样本量上训练您的模型时,会发生以下有趣的事情:
- ***在我们的示例中,拟合模型的系数: *β0_(拟合)和 β1_(拟合)开始接近真实值(在我们的示例中,分别为 20 和 10)。
- 拟合模型的预测( Y_predicted )开始逼近Yon,即 E(Y|X【T97)
- 模型的剩余误差开始趋近于零。
条件方差
方差是对数据偏离均值的简单衡量。
数学上,样本的方差 s (或总体的 σ )是样本(或总体)值与样本(或总体)均值之差的平方和。
样本的方差(图片由作者提供)
下面的情节说明了 无条件 方差s(Y)和 有条件 方差s(Y|X= X:**
无条件和有条件方差(图片由作者提供)
样本(或总体)的无条件方差考虑了样本(或总体)中的所有值,而有条件方差只关注与给定值**【X相对应的Y 值的子集。**
在我们的示例中,我们将样本的条件方差s(Y|X= X)定义为给定 X 值的 Y 的方差。因此记法为s(Y|**
条件方差和回归建模
与条件期望一样,条件方差在回归建模领域占有特殊的位置,其位置如下:
建立回归模型(或任何统计模型)的主要原因是试图“解释”因变量的可变性。实现这个目标的一个方法是在你的模型中包含相关的解释变量 X 。条件方差为您提供了一种解释回归变量对减少 Y 方差的帮助(即解释)程度的方法。
如果你发现一个解释变量的存在不能解释太多的差异,它可以从模型中删除。
为了说明这个概念,让我们再来看一下上面的图,它显示了中的无条件方差和有条件方差
样本的总体方差为 870.59。但是,如果您要将 X 固定为 6,那么只需知道 X 为 6 就可以将方差降低到只有 25!下表列出了 Y 中x 的剩余值的条件方差,将每个值与 Y 的总体无条件方差进行比较,即 870.59:**
不同 X 值的条件方差(图片由作者提供)
就是这样!这就是条件概率,条件期望和条件方差的全部内容。您可以看到这三个概念在回归建模中扮演了多么有用和重要的角色。
快乐造型!
感谢阅读!我写关于数据科学的主题。如果您喜欢这篇文章,请 关注我 接收关于数据科学、时间序列分析和预测主题的文章、指南和编程建议。
视觉三维重建
来源:卡琳·科列夫和丹尼尔·克雷默斯的论文《通过凸松弛进行连续比率优化并应用于多视角三维重建》。
整整一年前,在我开始写这篇文章之前,我看了特斯拉人工智能总监 Andrej Karapathy 的一次演讲,他向世界展示了特斯拉汽车如何使用挂在车上的摄像头感知深度,以便以 3D 方式重建周围环境并实时做出决策,一切(除了安全方面的前雷达)都是通过视觉进行计算的。那个演示让我大吃一惊!
当然,我知道通过相机可以实现环境的三维重建,但我的思维模式是,当我们拥有像激光雷达、雷达等这样高精度的传感器时,为什么有人会冒险使用普通相机呢?这能以少得多的计算量给我们一个准确的三维环境展示?我开始研究(试图理解)与深度感知和视觉三维重建相关的论文,并得出结论,我们人类从来没有从我们的头部发出光线来感知深度和周围的环境,我们很聪明,只用我们的两只眼睛就能意识到我们的周围环境,从开车或骑自行车去上班,或者在世界上最危险的赛道上以 230 英里/小时的速度驾驶一级方程式赛车,我们从来不需要激光在微秒内做出决定。我们周围的世界是由我们自己构建的,我们是有视觉的生物,所以正如埃隆所说,'一旦我们解决了视觉问题,这些昂贵的传感器将变得毫无意义。
在视觉深度感知领域正在进行大量的研究,特别是随着机器学习和深度学习的进步,我们现在能够仅以高精度从视觉计算深度。因此,在我们开始学习概念和实现这些技术之前,让我们看看这项技术目前处于什么阶段,以及它的应用是什么。
机器人视觉:
ZED 相机的环境感知
为自动驾驶创建高清地图:
深度感知与深度学习
SfM(运动结构)和 SLAM(同步定位和映射)是主要技术之一,它们利用了我将在本教程中向您介绍的概念。
LSD-SLAM 的演示
既然我们已经有了足够的灵感来学习,我将开始教程。所以首先我要教你理解幕后发生的事情所需的基本概念,然后用 C++中的 OpenCV 库应用它们。你可能会问,为什么我要用 C++实现这些概念,而用 python 实现会容易得多,这是有原因的。第一个原因是 python 的速度不够快,无法实时实现这些概念,第二个原因是,与 python 不同,使用 C++会要求我们理解概念,没有它就无法实现。
在本教程中,我们将编写两个程序,一个是获取场景的深度图,另一个是获取场景的点云,都使用立体视觉。
在我们进入编码部分之前,理解相机几何的概念是很重要的,这是我现在要教你的。
相机型号
自从摄影开始以来,用来产生图像的过程就没有改变过。来自被观察场景的光被相机通过前光圈(镜头)捕获,前光圈将光发射到位于相机镜头后面的图像平面上。该过程如下图所示:
由上图可知, do 是镜头到被观察物体的距离, di 是镜头到像面的距离。并且 f 将因此成为透镜的焦距。根据下面所示的所谓“薄透镜方程”,这些描述的量之间具有关系:
现在让我们来看看现实世界中的三维物体是如何被投影到二维平面(照片)上的。让我们理解这一点的最好方法是看看相机是如何工作的。
相机可以被看作是将三维世界映射成二维图像的功能。让我们以最简单的相机模型为例,那就是针孔相机模型,人类历史上最古老的摄影机制。下面是针孔摄像机的工作示意图:
从这个图表中我们可以得出:
在这里,很自然地,物体形成的图像的尺寸与物体离摄像机的距离成反比。并且位于位置(X,Y,Z)的 3d 场景点将被投影到(X,Y)处的图像平面上,其中(X,y) = (fX/Z,fY/Z)。其中 Z 坐标指的是点的深度,这是在前面的图像中完成的。整个摄像机配置和符号可以用一个简单的矩阵来描述,该矩阵使用齐次坐标 系统。
当摄像机生成世界的投影图像时,射影几何被用作现实世界中物体几何、旋转和变换的代数表示。
齐次坐标是射影几何中使用的坐标系统。即使我们可以在欧几里得空间中表示真实世界中的对象(或三维空间中的任何点)的位置,但是必须执行的任何变换或旋转都必须在齐次坐标空间中执行,然后再返回。让我们看看使用齐次坐标的优点:
- 涉及齐次坐标的公式通常比笛卡尔坐标中的要简单。
- 无穷远处的点可以用有限坐标来表示。
- 单个矩阵可以代表相机和世界之间可能发生的所有可能的保护性转换。
在齐次坐标空间中,二维点由 3 个向量表示,三维点由 4 个向量表示。
在上面的等式中,第一个带有 f 符号的矩阵称为内禀参数矩阵(或俗称内禀矩阵)。这里的固有矩阵现在只包含焦距( f ),我们将在本教程之前研究这个矩阵的更多参数。
带有 r 和 t 符号的第二个矩阵称为非本征参数矩阵(或通常称为非本征矩阵)。该矩阵中的元素表示相机的旋转和平移参数(即相机在现实世界中的位置和放置方式)。
因此,这些内在和外在矩阵一起可以给出图像中的(X,Y)点和现实世界中的(X,Y,Z)点之间的关系。这就是三维场景点如何根据给定的相机内部和外部参数投影到二维平面上。
现在我们已经获得了足够多的关于射影几何和相机模型的知识,是时候向你介绍计算机视觉几何中最重要的元素之一了,基础矩阵。
基础矩阵
现在我们知道了三维世界中的一个点是如何被投影到相机的像平面上的。我们将研究显示同一场景的两幅图像之间的投影关系。当这两个摄像机被一条刚性基线分开时,我们使用术语**立体视觉。**假设两个针孔摄像机观察一个给定的场景点,共享相同的基线,如下图所示:
从上图可以看出,世界点 X 在图像平面上的位置 x 处有图像,现在这个 x 可以位于三维空间中这条线上的任何位置。这意味着如果我们想在另一幅图像中找到同一点 x ,我们需要沿着这条线在第二幅图像上的投影进行搜索。
这条从 x 画出的假想线被称为 x 的极线。这条极线带来了一个基本的约束,即在另一个视图中,给定点的匹配必须位于这条线上。意思是,如果你想从第二张图片中的第一张图片中找到 x ,你得沿着第二张图片中 x 的极线去寻找。这些核线可以描述两个视图之间的几何特征。这里需要注意的一点是,所有的极线总是通过一个点。这个点对应于一个摄像机中心到另一个摄像机中心的投影,这个点被称为极线。
我们可以将基础矩阵 F 视为将一个视图中的二维图像点映射到另一个图像视图中的核线的矩阵。图像对之间的基本矩阵可以通过求解一组方程来估计,该组方程涉及两幅图像之间的一定数量的已知匹配点。这种匹配的最小数量是 7,最佳数量是 8。然后,对于一幅图像中的一个点,基本矩阵给出了在另一个视图中应该找到其对应点的直线的方程。
如果一个点(x,y)的一个点对应的点是(x ',y '),两个像平面之间的基本矩阵是 F,那么在齐次坐标下我们必须有下面的方程。
这个等式表达了两个对应点之间的关系,称为极线约束。
使用 RANSAC 匹配好的图像点
当两个相机观察同一个场景时,它们看到的是相同的物体,但视角不同。C++和 Python 中都有 OpenCV 之类的库,它们为我们提供了特征检测器,这些检测器可以用图像中的描述符为我们找到某些点,它们认为这些点对于图像是唯一的,如果给定同一场景的另一幅图像,就可以找到这些点。然而,实际上不可能保证通过比较检测到的特征点的描述符(如 SIFT、ORB 等)在两幅图像之间获得匹配集。)会准确真实。这就是为什么引入了基于 **RANSAC(随机抽样一致性)**策略的基本矩阵估计方法。
RANSAC 背后的想法是从一组给定的数据点中随机选择一些数据点,并仅使用这些数据点进行估计。所选择的点的数量应该是估计数学实体所需的最小点的数量,在我们的基础矩阵的情况下是八个匹配。一旦从这八个随机匹配中估计出基础矩阵,匹配集中的所有其他匹配就根据我们讨论的极线约束进行测试。这些匹配形成了所计算的基础矩阵的支持集。
支持集越大,计算出的矩阵是正确矩阵的概率就越高。并且如果随机选择的匹配之一是不正确的匹配,那么计算的基础矩阵也将是不正确的,并且它的支持集将被认为是小的。这个过程重复多次,最后,具有最大支持集的矩阵将被保留为最可能的矩阵。
从立体图像计算深度图
人类进化成为有两只眼睛的物种的原因是我们能够感知深度。当我们在一台机器中以类似的方式组织相机时,这被称为立体视觉。立体视觉系统通常由两个并排的摄像机组成,观察同一个场景,下图显示了具有理想配置的立体装备的设置,完美对齐。
在上图所示的理想相机配置下,相机仅通过水平平移分开,因此所有的核线都是水平的。这意味着对应的点具有相同的 y 坐标,并且搜索减少到一维线。当摄像机被这样的纯水平平移分开时,第二个摄像机的投影方程将变成:
通过查看下图,这个等式会更有意义,这是数码相机的一般情况:
其中 (uo,vo) 点是经过镜头主点的直线穿过像面的像素位置。这里我们得到一个关系式:
这里,术语*(x-x’)*被称为视差, Z 当然是深度。为了从立体对中计算深度图,必须计算每个像素的视差。
但是在实际世界中,获得这样的理想配置是非常困难的。即使我们精确地放置摄像机,它们也不可避免地会包含一些额外的过渡和旋转组件。
幸运的是,可以通过使用鲁棒的匹配算法来校正这些图像以产生所需的水平对线,该算法利用基础矩阵来执行校正。
现在让我们从获得下面立体图像的基本矩阵开始:
立体图像对
你可以点击这里从我的 GitHub 库下载上面的图片。在开始编写本教程中的代码之前,请确保您的计算机上已经构建了 opencv 和 opencv-contrib 库。如果还没有安装,我建议你在 Ubuntu 上访问这个链接来安装它们。
我们来编码吧!
#include <opencv2/opencv.hpp>
#include "opencv2/xfeatures2d.hpp"using namespace std;
using namespace cv;int main(){
cv::Mat img1, img2;img1 = cv::imread("imR.png",cv::IMREAD_GRAYSCALE);
img2 = cv::imread("imL.png",cv::IMREAD_GRAYSCALE);
我们做的第一件事是包含了 opencv 和 opencv-contrib 中所需的库,这是我在开始本节之前要求您构建的。在 main() 函数中,我们已经初始化了 cv:Mat 数据类型的两个变量,这是 opencv 库的成员函数, Mat 数据类型可以通过动态分配内存来保存任何大小的向量,尤其是图像。然后使用 cv::imread() 我们将这两幅图像导入到mat数据类型的 img1 和 img2 中。cv::im read _ gray参数将图像作为灰度导入。
// Define keypoints vector
std::vector<cv::KeyPoint> keypoints1, keypoints2;// Define feature detector
cv::Ptr<cv::Feature2D> ptrFeature2D = cv::xfeatures2d::SIFT::create(74);// Keypoint detection
ptrFeature2D->detect(img1,keypoints1);
ptrFeature2D->detect(img2,keypoints2);// Extract the descriptor
cv::Mat descriptors1;
cv::Mat descriptors2;ptrFeature2D->compute(img1,keypoints1,descriptors1);
ptrFeature2D->compute(img2,keypoints2,descriptors2);
这里我们利用 opencv 的 SIFT 特征检测器从图像中提取所需的特征点。如果你想更多地了解这些特征检测器是如何工作的,请访问这个链接。我们上面获得的描述符描述了提取的每个点,该描述用于在另一幅图像中找到它。
// Construction of the matcher
cv::BFMatcher matcher(cv::NORM_L2);// Match the two image descriptors
std::vector<cv::DMatch> outputMatches;
matcher.match(descriptors1,descriptors2, outputMatches);
BFMatcher 获取第一组中一个特征的描述符,并使用某种阈值距离计算将其与第二组中的所有其他特征进行匹配,然后返回最接近的特征。我们将 BFMatches 返回的所有匹配存储在*vector<cv::d match>*类型的输出匹配变量中。
// Convert keypoints into Point2f
std::vector<cv::Point2f> points1, points2;
for (std::vector<cv::DMatch>::const_iterator it= outputMatches.begin(); it!= outputMatches.end(); ++it) { // Get the position of left keypoints
points1.push_back(keypoints1[it->queryIdx].pt);
// Get the position of right keypoints
points2.push_back(keypoints2[it->trainIdx].pt);
}
首先需要将获取的关键点转换成 cv::Point2f 类型,以便与 cv::findFundamentalMat 一起使用,我们将利用该函数使用我们提取的这些特征点来计算基础矩阵。两个合成向量点 1 和点 2 包含两幅图像中对应的点坐标。
std::vector<uchar> inliers(points1.size(),0);
cv::Mat fundamental= cv::findFundamentalMat(
points1,points2, // matching points
inliers, // match status (inlier or outlier)
cv::FM_RANSAC, // RANSAC method
1.0, // distance to epipolar line
0.98); // confidence probabilitycout<<fundamental; //include this for seeing fundamental matrix
最后,我们调用了 cv::findFundamentalMat。
// Compute homographic rectification
cv::Mat h1, h2;
cv::stereoRectifyUncalibrated(points1, points2, fundamental,
img1.size(), h1, h2);
// Rectify the images through warping
cv::Mat rectified1;
cv::warpPerspective(img1, rectified1, h1, img1.size());
cv::Mat rectified2;
cv::warpPerspective(img2, rectified2, h2, img1.size());
正如我之前在教程中向您解释的那样,在现实世界中很难获得没有任何误差的理想摄像机配置,因此 opencv 提供了一个纠正功能,该功能应用单应变换将每个摄像机的图像平面投影到一个完全对齐的虚拟平面上。这种变换是从一组匹配点和基本矩阵中计算出来的。
// Compute disparity
cv::Mat disparity;
cv::Ptr<cv::StereoMatcher> pStereo = cv::StereoSGBM::create(0, 32,5);
pStereo->compute(rectified1, rectified2, disparity);cv::imwrite("disparity.jpg", disparity);
最后,我们计算了视差图。从下图来看,较暗的像素代表离相机较近的物体,较亮的像素代表离相机较远的物体。你在输出视差图中看到的白色像素噪声可以用一些滤镜去除,我不会在本教程中介绍。
既然我们已经成功地从给定的立体对中获得了深度图。现在,让我们尝试使用 opencv 的 3D-Viz 工具将获得的二维图像点重新投影到三维空间,该工具将帮助我们绘制三维点云。
但是这一次,我们将使用本质矩阵来投影这些点,而不是从给定的图像点估计基础矩阵。
本质矩阵
本质矩阵可被视为基本矩阵,但用于校准的相机。我们也可以称之为基础矩阵的专门化,其中矩阵是使用校准的相机计算的,这意味着我们必须首先获得关于我们在世界上的相机的知识。
因此,为了估计本质矩阵,我们首先需要相机的固有矩阵(代表给定相机的光学中心和焦距的矩阵)。让我们看看下面的等式:
这里从第一个矩阵开始, fx 和 fy 代表相机的焦距, (uo,vo) 是主点。这是内在矩阵,我们的目标是估计它。
这个寻找不同摄像机参数的过程被称为摄像机校准。显然,我们可以使用摄像机制造商提供的规格,但是对于我们将要进行的 3d 重建等任务,这些规格不够精确。因此,我们将执行我们自己的摄像机校准。
这个想法是向摄像机显示一组场景点,我们知道这些点在现实世界中的实际三维位置,然后观察这些点在获得的图像平面上的投影位置。利用足够数量的 3-D 点和相关的 2-D 图像点,我们可以从投影方程中提取精确的摄像机参数。
做到这一点的一种方法是从不同的视点拍摄世界上一组具有已知三维位置的三维点的若干图像。我们将利用 opencv 的校准方法,其中一种方法将棋盘的图像作为输入,并返回给我们所有的角。我们可以自由地假设电路板位于 Z=0,X 和 Y 轴与网格对齐。在下一节中,我们将看看 OpenCV 的这些校准函数是如何工作的。
三维场景重建
让我们首先创建三个函数,我们将在主函数中使用它们。这三个功能是
- addchesboardpoints()//返回给定棋盘图像的角点
- calibrate() //从提取的点返回固有矩阵
- triangulate()//返回重建点的三维坐标
#include "CameraCalibrator.h"#include <opencv2/opencv.hpp>
#include "opencv2/xfeatures2d.hpp"using namespace std;
using namespace cv;std::vector<cv::Mat> rvecs, tvecs;// Open chessboard images and extract corner points
int CameraCalibrator::addChessboardPoints(
const std::vector<std::string>& filelist,
cv::Size & boardSize) {// the points on the chessboard
std::vector<cv::Point2f> imageCorners;
std::vector<cv::Point3f> objectCorners;// 3D Scene Points:
// Initialize the chessboard corners
// in the chessboard reference frame
// The corners are at 3D location (X,Y,Z)= (i,j,0)
for (int i=0; i<boardSize.height; i++) {
for (int j=0; j<boardSize.width; j++) {objectCorners.push_back(cv::Point3f(i, j, 0.0f));
}
}// 2D Image points:
cv::Mat image; // to contain chessboard image
int successes = 0;
// for all viewpoints
for (int i=0; i<filelist.size(); i++) {// Open the image
image = cv::imread(filelist[i],0);// Get the chessboard corners
bool found = cv::findChessboardCorners(
image, boardSize, imageCorners);// Get subpixel accuracy on the corners
cv::cornerSubPix(image, imageCorners,
cv::Size(5,5),
cv::Size(-1,-1),
cv::TermCriteria(cv::TermCriteria::MAX_ITER +
cv::TermCriteria::EPS,
30, // max number of iterations
0.1)); // min accuracy// If we have a good board, add it to our data
if (imageCorners.size() == boardSize.area()) {// Add image and scene points from one view
addPoints(imageCorners, objectCorners);
successes++;
}//Draw the corners
cv::drawChessboardCorners(image, boardSize, imageCorners, found);
cv::imshow("Corners on Chessboard", image);
cv::waitKey(100);
}return successes;
}
在上面的代码中,你可以看到我们包含了一个头文件“CameraCalibrator.h”,它将包含这个文件的所有函数声明和变量初始化。你可以通过访问这个链接在我的 Github 下载这个头文件以及本教程中的所有其他文件。
我们的函数使用 opencv 的*findchesboardcorners()*函数,该函数将图像位置数组(该数组必须包含每个棋盘图像的位置)和棋盘大小(您应该输入水平和垂直方向上棋盘中存在的角的数量)作为输入参数,并返回包含角位置的向量。
double CameraCalibrator::calibrate(cv::Size &imageSize)
{
// undistorter must be reinitialized
mustInitUndistort= true;// start calibration
return
calibrateCamera(objectPoints, // the 3D points
imagePoints, // the image points
imageSize, // image size
cameraMatrix, // output camera matrix
distCoeffs, // output distortion matrix
rvecs, tvecs, // Rs, Ts
flag); // set options}
在这个函数中,我们使用了 calibrateCamera() 函数,该函数获取上面获得的三维点和图像点,并返回给我们固有矩阵、旋转向量(描述相机相对于场景点的旋转)和平移矩阵(描述相机相对于场景点的位置)。
cv::Vec3d CameraCalibrator::triangulate(const cv::Mat &p1, const cv::Mat &p2, const cv::Vec2d &u1, const cv::Vec2d &u2) {// system of equations assuming image=[u,v] and X=[x,y,z,1]
// from u(p3.X)= p1.X and v(p3.X)=p2.X
cv::Matx43d A(u1(0)*p1.at<double>(2, 0) - p1.at<double>(0, 0),
u1(0)*p1.at<double>(2, 1) - p1.at<double>(0, 1),
u1(0)*p1.at<double>(2, 2) - p1.at<double>(0, 2),
u1(1)*p1.at<double>(2, 0) - p1.at<double>(1, 0),
u1(1)*p1.at<double>(2, 1) - p1.at<double>(1, 1),
u1(1)*p1.at<double>(2, 2) - p1.at<double>(1, 2),
u2(0)*p2.at<double>(2, 0) - p2.at<double>(0, 0),
u2(0)*p2.at<double>(2, 1) - p2.at<double>(0, 1),
u2(0)*p2.at<double>(2, 2) - p2.at<double>(0, 2),
u2(1)*p2.at<double>(2, 0) - p2.at<double>(1, 0),
u2(1)*p2.at<double>(2, 1) - p2.at<double>(1, 1),
u2(1)*p2.at<double>(2, 2) - p2.at<double>(1, 2));cv::Matx41d B(p1.at<double>(0, 3) - u1(0)*p1.at<double>(2,3),
p1.at<double>(1, 3) - u1(1)*p1.at<double>(2,3),
p2.at<double>(0, 3) - u2(0)*p2.at<double>(2,3),
p2.at<double>(1, 3) - u2(1)*p2.at<double>(2,3));// X contains the 3D coordinate of the reconstructed point
cv::Vec3d X;
// solve AX=B
cv::solve(A, B, X, cv::DECOMP_SVD);
return X;
}
上述函数采用投影矩阵和归一化的图像点,这些点可以通过使用上一个函数的固有矩阵获得,并返回上述点的三维坐标。
下面是从立体对三维重建的完整代码。这个代码需要至少 25 到 30 个棋盘图像,这些图像来自你拍摄立体像对的同一台相机。为了首先在您的 PC 上运行这段代码,克隆我的 GitHub repo,用您自己的立体对替换立体对,用您自己的数组替换棋盘图像位置数组,然后编译。我上传了一个棋盘图片的例子给你参考,你需要拍摄大约 30 个这样的图片并在代码中提及。
int main(){cout<<"compiled"<<endl;const std::vector<std::string> files = {"boards/1.jpg"......};
cv::Size board_size(7,7);CameraCalibrator cal;
cal.addChessboardPoints(files, board_size);cv::Mat img = cv::imread("boards/1.jpg");cv::Size img_size = img.size();
cal.calibrate(img_size);
cout<<cameraMatrix<<endl;cv::Mat image1 = cv::imread("imR.png");
cv::Mat image2 = cv::imread("imL.png");// vector of keypoints and descriptors
std::vector<cv::KeyPoint> keypoints1;
std::vector<cv::KeyPoint> keypoints2;
cv::Mat descriptors1, descriptors2;// Construction of the SIFT feature detector
cv::Ptr<cv::Feature2D> ptrFeature2D = cv::xfeatures2d::SIFT::create(10000);// Detection of the SIFT features and associated descriptors
ptrFeature2D->detectAndCompute(image1, cv::noArray(), keypoints1, descriptors1);
ptrFeature2D->detectAndCompute(image2, cv::noArray(), keypoints2, descriptors2);// Match the two image descriptors
// Construction of the matcher with crosscheck
cv::BFMatcher matcher(cv::NORM_L2, true);
std::vector<cv::DMatch> matches;
matcher.match(descriptors1, descriptors2, matches);cv::Mat matchImage;cv::namedWindow("img1");
cv::drawMatches(image1, keypoints1, image2, keypoints2, matches, matchImage, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
cv::imwrite("matches.jpg", matchImage);// Convert keypoints into Point2f
std::vector<cv::Point2f> points1, points2;for (std::vector<cv::DMatch>::const_iterator it = matches.begin(); it != matches.end(); ++it) {
// Get the position of left keypoints
float x = keypoints1[it->queryIdx].pt.x;
float y = keypoints1[it->queryIdx].pt.y;
points1.push_back(cv::Point2f(x, y));
// Get the position of right keypoints
x = keypoints2[it->trainIdx].pt.x;
y = keypoints2[it->trainIdx].pt.y;
points2.push_back(cv::Point2f(x, y));
}// Find the essential between image 1 and image 2
cv::Mat inliers;
cv::Mat essential = cv::findEssentialMat(points1, points2, cameraMatrix, cv::RANSAC, 0.9, 1.0, inliers);cout<<essential<<endl;// recover relative camera pose from essential matrix
cv::Mat rotation, translation;
cv::recoverPose(essential, points1, points2, cameraMatrix, rotation, translation, inliers);
cout<<rotation<<endl;
cout<<translation<<endl;// compose projection matrix from R,T
cv::Mat projection2(3, 4, CV_64F); // the 3x4 projection matrix
rotation.copyTo(projection2(cv::Rect(0, 0, 3, 3)));
translation.copyTo(projection2.colRange(3, 4));
// compose generic projection matrix
cv::Mat projection1(3, 4, CV_64F, 0.); // the 3x4 projection matrix
cv::Mat diag(cv::Mat::eye(3, 3, CV_64F));
diag.copyTo(projection1(cv::Rect(0, 0, 3, 3)));
// to contain the inliers
std::vector<cv::Vec2d> inlierPts1;
std::vector<cv::Vec2d> inlierPts2;
// create inliers input point vector for triangulation
int j(0);
for (int i = 0; i < inliers.rows; i++) {
if (inliers.at<uchar>(i)) {
inlierPts1.push_back(cv::Vec2d(points1[i].x, points1[i].y));
inlierPts2.push_back(cv::Vec2d(points2[i].x, points2[i].y));
}
}
// undistort and normalize the image points
std::vector<cv::Vec2d> points1u;
cv::undistortPoints(inlierPts1, points1u, cameraMatrix, distCoeffs);
std::vector<cv::Vec2d> points2u;
cv::undistortPoints(inlierPts2, points2u, cameraMatrix, distCoeffs);// Triangulation
std::vector<cv::Vec3d> points3D;
cal.triangulate(projection1, projection2, points1u, points2u, points3D);cout<<"3D points :"<<points3D.size()<<endl;viz::Viz3d window; //creating a Viz window//Displaying the Coordinate Origin (0,0,0)
window.showWidget("coordinate", viz::WCoordinateSystem());window.setBackgroundColor(cv::viz::Color::black());//Displaying the 3D points in green
window.showWidget("points", viz::WCloud(points3D, viz::Color::green()));
window.spin();
}
我知道 medium 的代码显示很混乱,特别是对于 C++,因此甚至代码看起来也很混乱,所以我建议你去我的 GitHub 了解上面的代码。
对我来说,给定对的输出如下所示,可以通过调整特征检测器及其类型来改进。
任何对深入学习这些概念感兴趣的人,我会推荐下面这本书,我认为它是计算机视觉几何学的圣经。也是本教程的参考书。
计算机视觉中的多视图几何第二版——作者理查德·哈特利和安德鲁·齐泽曼。
如果你有任何问题,请在评论区告诉我。
谢谢你。
不到 5 分钟的 3 个深度学习算法—第 1 部分(前馈模型)
图片由来自 Pixabay 的 Thomas Breher 拍摄
如果你认为机器学习是你没有勇气与之交谈的暗恋对象,深度学习就是你暗恋对象的父亲!由于硬件的前所未有的进步和研究人员对更好更大模型的渴望,深度学习日益变得令人生畏和难以捉摸。每天涌现的研究越多,你应该掌握的基础知识水平就越高。所以,对于那些犹豫是否直接投入到深度学习的阴暗和俗气的好处中的人,我希望这篇文章能增强你的信心。本文不会讨论这些模型的任何数学问题,但会为您提供概念上的强化,让您在血淋淋的数学过程中走得更远。
全连接网络
你能找到的最简单的深层网络。它通常有一个输入层,一个输出层和可选的中间多个隐藏层。让下面的类比来解释。
类比:弗兰肯斯坦的实验室
想象你是科学怪人实验室的助手,那里充满了古怪的设备。弗兰肯斯坦刚刚要求你使用下面的仪器,用蓝色、红色、黑色和黄色的颜料来制作紫色、深橙色和绿色。当你把颜料倒在顶部时,根据管子开口的宽度,颜料会流到下面的一系列球上。有一种机制可以改变管子的大小。
管子的结构。线条的粗细表示管的厚度。你可以把虚线想象成非常小(或者不存在)的管子
这类似于 FCN 的工作原理。你给它输入,即特征向量(例如花的各种属性)(例子中的油漆桶),然后你预测结果(例如花的种类)(例子中的混合颜色)。预测结果是一系列的数学计算(包括矩阵乘法、加法等。).您可能已经意识到该设备已经被配置为最佳配置。达到最佳设置被称为训练/优化一个模型,它涉及输入特征向量、预测标签和真实标签(在示例中调整管宽度)。它也不需要仅仅是输入层和输出层。你也可以有中间层(即隐藏层)。这是 FCN 真正的样子。(了解更多:这里)
一种 FCN,用于在给定一些花卉属性的情况下预测正确的花卉种类。
应用程序
- 结构化数据的简单分类任务,例如根据房屋属性预测房价
自动编码器
自动编码器是一种全连接网络,不同之处仅在于它们的使用方式。它们从一个输入开始,就像 FCNs 一样,将其映射到一个更小的隐藏表示(称为编码),最后重建原始输入(称为解码)。
类比:回到科学怪人的实验室
假设你和你的朋友有两个以上的小工具,并决定玩他们。您将它们组合起来,以便它们共享输出。现在看起来像下面。请注意,底部的管配置是顶部的镜像。
你和你朋友发明的小玩意。你把颜色倒在顶部和底部,你会得到相同的颜色。
你可以从顶部倒颜色,让它们在中间混合。那么一个可以分离不同颜色的“神奇粒子分离器”就会让颜色分离到原来的颜色。你甚至可以在顶部倒一种随机的颜色,让这个流形在底部找出随机的颜色。
这就是自动编码器中发生的情况。它接受一个输入(本例中为 paint),计算一个较小的潜在表示(本例中为混合颜色),最后导出原始输入(本例中为底部的颜色)。这是在真正的自动编码器中的样子。(了解更多:自动编码器)
自动编码器在现实生活中是什么样子的。它接受一些输入(例如图像像素),将其转换为较小的表示形式,然后重建原始输入。
应用程序
- 恢复损坏的图像-您可以训练自动编码器通过输入损坏的图像并要求模型预测原始图像来恢复图像(类似于识别倒在顶部的随机颜色)。
- 图像/数据聚类-您可以使用学习到的较小潜在表示作为数据的特征表示代理,从而对数据进行聚类
卷积神经网络
啊!计算机视觉的征服者。CNN 非常擅长处理图像。CNN 由卷积层、全连接层和可选的汇集层组成。CNN 接收具有高度、宽度和通道(例如 RGB —红绿蓝)的图像。
类比:博物馆抢劫!
有一个令人讨厌的逃犯正试图闯入博物馆偷一颗钻石。他走进博物馆计划抢劫。他把地板分成一个 5x5 的格子。然后,他从一个牢房走到另一个牢房,每行从左到右。然后他会查看四个相邻的单元格(即他所在的一个单元格、右边的单元格、上面的单元格和右上角的单元格)。如果他在视野中看到一些障碍物/艺术品,他会在正上方的天花板上射出一个绿色的夜光标记,如果钻石在这 4 个单元中的一个,他会射出一个红色的夜光标记。如果他站在地板上的每个细胞都这样做,他会有下面的计划。有了这个,他可以在晚上偷偷溜进来,即使在漆黑一片的时候也能准确地知道去哪里!
强盗将如何绘制博物馆的地图。你可以看到,在他偷偷摸摸的小冒险结束时,他得到了两张特征地图,可以帮助他在地板上导航,而不会触发任何警报。
这就是 CNN 的卷积层所做的。它移动一个内核(强盗想要映射的东西),这个内核一次只看到图像的一小部分,覆盖在图像上(就像强盗去所有的单元格)。并且在每个位置,它将输出一些值(例如,障碍物是否存在)。这一过程导致了要素地图的开发,这些地图提供了有用的宏观分析信息。最后,将 FCN 连接到最后一个卷积层,因为任何分类/回归任务都需要 FCN。这是典型的 CNN 的样子。(了解更多:卷积神经网络)。
一个真正的 CNN。它接收图像并使用卷积层生成多个特征图。可选地,网络具有池化图层,这从本质上减少了要素地图的宽度和高度(有助于减少模型的参数计数),最后还有一个完全连接的网络,允许您进行分类/回归。
应用程序
- 图像分类—识别图像中存在的对象的类别
- 对象检测—识别图像中的所有对象及其位置
结论
我们看了三种算法:全连接网络(FCNs)、自动编码器和卷积神经网络(CNN)。以下是主要的几点。
- FCN 接受输入特征向量并预测正确的输出类别
- 自动编码器接收输入,将其转换为较小的表示形式,并重建原始输出
- CNN 接收一幅图像,通过一系列卷积/池层发送,最后通过 FCN,预测图像中存在的正确对象类别。
想在深度网络和 TensorFlow 上做得更好?
检查我在这个课题上的工作。
[2] (视频课程)Python 中的机器翻译 — DataCamp
[3] (书)TensorFlow 中的自然语言处理 1 — Packt
新的!加入我的新 YouTube 频道
如果你渴望看到我关于各种机器学习/深度学习主题的视频,请确保加入 DeepLearningHero 。
其他文章
不到 5 分钟的 3 种深度学习算法—第 2 部分(深度序列模型)
在的上一篇文章中,我们研究了处理非时间序列数据的模型。是时候把我们的注意力转向其他模型了。这里我们将讨论深度序列模型。它们主要用于处理/预测时间序列数据。
链接到第 1 部分,以防你错过。
简单递归神经网络/Elman 网络
简单的递归神经网络(也称为 RNNs)对于时间序列问题就像 CNN 对于计算机视觉一样。在时间序列问题中,您向模型提供一个值序列,并要求它预测该序列的下一个 n 值。rnn 遍历序列的每个值,同时建立它所看到的记忆,这有助于它预测未来会是什么样子。(了解更多关于 RNNs【1】【2】)
类比:新改进的秘密列车
我小时候玩过这个游戏,你可能知道它的另一个名字。孩子们被要求站成一排,你对排在队伍中的第一个孩子耳语一个随机单词。这个孩子应该在这个单词上加上一个合适的单词,然后小声告诉下一个孩子,等等。当信息到达最后一个孩子时,你应该有一个由孩子的想象力酝酿的令人兴奋的故事。
输入简单的 RNNs!这就是 RNN 的症结所在。它在时间 t — x(t) (来自最后一个孩子的新单词)和从时间 t-1 — h(t-1) (消息的先前单词)开始的状态作为输入,并产生输出— y(t) (先前的消息+来自最后一个孩子的新单词+您的新单词)。
一旦训练了一个 RNN,你就可以(但一般不会)永远保持预测,因为对时间 t 的预测(即 y(t) )在 t+1 成为输入(即 y(t)=x(t+1) )。这是 RNN 在现实世界中的样子。
RNN 如何解决情感分析问题。它从一个单词到另一个单词,同时产生一个状态(红球)。最后,有一个完全连接的网络(FCN),它采用最后一个状态并产生一个标签(正/负/中性)。
应用程序
- 时间序列预测(例如天气/销售预测)
- 情感分析——给定一个电影/产品评论(一系列单词),预测它是负面/正面/中性的。
- 语言建模——给定故事的一部分,想象故事的其余部分/ 从描述中生成代码
长短期记忆网络
LSTM 是 RNN 镇最酷的新成员。LSTM 是一个比 RNNs 更复杂的野兽,能够记住比 RNNs 更长的事情。LSTMs 还会遍历序列的每个值,同时建立它所看到的内容的记忆,这有助于它预测未来会是什么样子。但是记得 RNNs 只有一个状态(代表记忆)吗?LSTMs 有两种状态(一种长期状态和一种短期状态),因此得名 LSTMs。(了解更多: LSTMs )
类比:快餐连锁店
所有这些解释都让我饿了!所以让我们去一家快餐连锁店。这是一个字面上的连锁,因为如果你点了一顿饭,一家店做汉堡,另一家做薯条,等等。在这个快餐店里,你去了第一家店,说了下面的话。
我需要一个汉堡,里面有烤老虎面包和烤鸡。
有一个人接受订单(绿色),并将信息发送给红色的人,假设他烤了面包。与蓝人交流时,他可以放下敬酒的部分,说:
一个汉堡,有老虎面包和烤鸡
(我们仍然需要烤的部分,因为下一家商店基于此决定酱料)。然后你开车到下一个商店说,
加上切达干酪,大薯条,我穿了一件绿色 t 恤
现在,绿色的人知道他的 t 恤颜色是完全不相关的,并放弃了这一部分。该商店还从上一个商店的红色和蓝色中获取信息。接下来他们会加入调味汁,准备薯条。第二家商店中的红色人员将持有大部分订单说明,以备我们稍后需要(如果客户投诉)。但他只会说,
一个汉堡和大薯条
蓝色的人,因为这是他工作所需要的。最后,您从第二个商店的输出终端获得订单。
快餐连锁店。有三个人;绿色(输入)、红色(单元状态)和蓝色(输出状态)。它们还可以从您提供的输入中丢弃某些信息,以及在内部处理它们时丢弃信息。
LSTMs 与这个链条的运作方式相差不远。在给定的时间 t,
- 输入 x(t)(本例中的客户),
- 输出状态 h(t-1)(来自先前商店的蓝色人)和
- a 细胞状态 c(t-1)(前一家店的红人)。
并产生,
- 一个输出状态 h(t)(这个商店里的蓝色人)和
- a 细胞状态 c(t)(本店红人)
但是,LSTM 没有对这些元素进行直接计算,而是有一个门控机制,可以用来决定允许这些元素传递多少信息。例如,记得当顾客说“我在第二家商店穿了一件绿色 t 恤”时发生了什么,绿色的人(输入门)丢弃了该信息,因为它对订单不重要。另一个例子是,当红色的人在第一家商店扔掉了面包烘烤的部分。LSTM 的牢房里有许多扇门。即,
- 输入门(绿色的人)——丢弃输入中无用的信息。
- 遗忘之门(红人的一部分)——丢弃在之前的细胞状态中无用的信息
- 一个输出门(蓝色人的一部分)——丢弃单元状态中无用的信息,生成输出状态
如您所见,交互是复杂的。但是最重要的是,
LSTM 保持两种状态(输出-短期状态和单元状态-长期状态),并在计算最终和中期输出时使用门控来丢弃信息。
这是 LSTM 的样子。
现实世界中的 LSTM。你可以看到这是一个复杂的连接迷宫。因此,不要试图理解它们在这一点上是如何连接的。了解所涉及的各种实体。红色虚线球表示由 LSTM 单元计算的中间输出
应用程序
- 与 RNNs 相同
门控循环单元
唷!我离开的时候,LSTMs 真的花了不少时间。GRU 是 LSTMs 的继承者,它简化了 LSTMs 未来的机制,而没有过多地损害性能。(了解更多:格鲁什【1】【2】)
类比:快餐连锁店 v2.0
不是作为一个美食评论家,但我们之前看到的快餐连锁店看起来相当低效。有没有办法让它更有效率?这里有一个方法。
新的改良快餐连锁店。我们不再有红色的人。这将导致更少的延误,并有助于更快地获得您的货物。
- 去掉红色的人(细胞状态)。现在长时记忆和短时记忆都由绿人管理(输出状态)。
- 只有一个输入门和一个输出门(即没有遗忘门)
你可以把 GRU 看作是简单的 RNN 和 LSTMs 之间的一个中间者。这是 GRU 的样子。
现实世界中的 GRU。虽然不像 LSTMs 那么复杂,但还是有点难以下咽。因此,不要试图理解它们在这一点上是如何连接的。了解所涉及的各种实体。红色虚线球表示由 GRU 单元计算的中间输出。
应用:
- 与 RNNs 相同
结论
我们看了简单的 rnn、LSTMs 和 gru。以下是主要的几点。
- 简单 RNNs——从一个时间步到另一个时间步的简单模型,同时在每一步生成一个输出状态(无门控机制)
- LSTMs —相当复杂。有两种状态;单元状态(长期)和输出状态(短期)。它还有一个门控机制来控制流经模型的信息量。
- GRUs——RNNs 和 LSTMs 的折衷。只有一个输出状态,但仍有门控机制。
接下来将包括深度学习中最热门的话题;变形金刚。
如果你喜欢我分享的关于数据科学和机器学习的故事,考虑成为会员吧!
作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…
thushv89.medium.com](https://thushv89.medium.com/membership)
想在深度网络和 TensorFlow 上做得更好?
检查我在这个课题上的工作。
[2] (视频课程)Python 中的机器翻译 — DataCamp
[3] (书)TensorFlow 中的自然语言处理 1 — Packt
新的!加入我的新 YouTube 频道
如果你渴望看到我关于各种机器学习/深度学习主题的视频,请确保加入 DeepLearningHero 。
以前的文章
第 1 部分:前馈模型