Python 地理数据科学入门
教程、真实世界项目和练习
World countries GPD 2007 map
这是 Python 地理数据科学入门系列文章的第一篇,该系列文章由三部分组成。您将学习如何用 Python 阅读、操作和分析地理数据。本系列中的文章按顺序排列,第一篇文章奠定基础,第二篇文章介绍中级和高级地理数据科学主题。第三部分涵盖了一个相关的真实世界的项目,总结巩固你的学习。每个教程也有一些简单的练习来帮助你学习和练习。所有代码、数据集和 Google Colab Jupyter 笔记本都可以从本文末尾的链接获得。
在本系列中,我将只关注地理矢量数据。在下一个系列中,我们将学习卫星图像和栅格数据分析。
该系列包含三个部分:
- 地理数据科学导论
- 地理数据处理
- 地理数据科学项目
这是第一部分。在本教程中,我们将学习使用 Geopandas 加载和处理地理数据的基础知识。Geopandas 是 Python 中地理数据科学的主力,它建立在 pandas 和 Numpy 库之上。与 Pandas 数据框架一样,Geopandas 数据结构包含地理数据框架和地理系列。Geopandas 不仅提供了轻松读取和操作地理数据的能力,还可以执行许多基本的地理空间操作,包括其他几何操作、投影和地理分析。您还可以使用 Geopandas 可视化和绘制地图——它为 Matplotlib 库提供了一个高级接口——方法是在 GeodataFrame/GeoSeries 上使用.plot()
方法。
这些是本部分“地理数据科学简介”的学习目标:
- 在 Geopandas 中读写地理数据。
- 投影并设置坐标参考系统(CRS)。
- 可视化地图
1.读取地理数据
在本教程中,我们将主要使用 3 个数据集:
- 国家
- 城市
- 河
地理(矢量)数据有不同的格式(Shapefiles、Geopackage、Geojson 等)。使用 Geopandas 加载大多数地理数据格式非常简单。我们可以使用.read_file().
让我们看一个读取数据的例子。在这种情况下,我们将读取国家数据集。
首先,我们创建了一个变量来保存文件路径,然后我们使用 Geopandas,.read_file()
方法来读取国家数据集。Geopandas 负责几何列,使我们能够执行地理处理任务,例如绘制地图。
开始数据探索的一个好方法是查看前几行、数据的形状以及数据的一般统计信息。这可以通过以下命令来实现。
- 方法返回前 5 行。如果需要,可以调整要返回的行数,例如,
.head(8)
表示数据集中的前 8 行。 .shape()
返回数据的行数和列数.describe()
可用于探索一些基本的统计细节,例如,平均值、标准差和百分位数。
这是前 5 行数据的样子。
countries Geodataframe — first 5 rows
另一个在 Geopandas 中读取数据的例子,这次我们将读取城市数据集。它以 Geojson 文件的形式出现,但我们用来读取国家/地区数据集的技术同样适用于此处。
我们也可以使用.head()
、.shape()
和.describe()
进行同样的探索,以了解这个数据集是关于什么的。一旦我们进行了探索,我们就可以开始绘制地图了。
通过.plot()
功能,在 Geopandas 中绘制地图很容易。由于我们有两个数据集国家和城市数据,我们可以将它们叠加并显示为地图。在这里,我们使用 Matplotlib 设置子情节,并将轴传递给 Geopandas .plot()
函数。
这是输出图。只需两到三行代码,我们就能生成这张漂亮的地图。
Countries and cities of the world map — Change picture
你该做些小运动了。
练习 1.1:读取河流数据
练习 1.2:阅读河流数据集的前 5 行
练习 1.3:可视化河流数据集。
2.坐标系和投影
坐标参考系统表示我们的二维(平面)数据如何与地球上的实际位置相关联。它是将属性保持在各自位置的粘合剂。地理数据框架有。crs 属性,它可以给出数据中使用的原始 CRS。这些坐标很容易变换和投影。但是,要执行投影,必须有相同的 CRS,以便执行地理分析并从分析中获得正确的值。国家、城市和河流有相同的 CRS。让我们检查一下各国的客户登记系统。
这是上面代码{‘init’: ‘epsg:4326’}的输出。EPSG 代表欧洲石油测量组织,是维护空间参考系统的权威机构。代码 4326 指示使用的地理坐标系,在本例中为 1984 年世界大地测量系统(WGS84)。
不同的 CRS 有不同的测量值。有些坐标以十进制度定义,有些则以米定义。在地理数据处理中,将数据从一种格式转换为另一种格式是很常见的。该源对于可视化和比较不同的投影非常有用:
比较墨卡托和罗宾逊的地图投影
map-projections.net](https://map-projections.net/compare.php?p1=mercator-84&p2=robinson&sps=1)
我们将把数据投射到墨卡托。当您远离赤道时,墨卡托投影、经纬度四边形会沿 x 轴和 y 轴拉伸。但首先,让我们看看国家数据集的几何列。
这是上面代码的输出。它只是打印出多边形的纬度和经度。这些坐标现在是十进制度。
0(多边形((117.7036079039552 4.163414542001791…
)1(多边形((117.703603607903955 2 4.163414544 420017…
)2(多边形((-69.6964699994-17.5996
让我们投射这些数据,看看变化。在本例中,我们投影到 EPSG:3395,这是广泛使用的墨卡托投影。
现在我们的几何列数据如下所示:
0(多边形((13102705.69639943 460777.6522179524…
)1(多边形((13102705.696399943 460777.6522179 524…
)2(多边形((-7737727-1963777.
由于投影,几何图形不再以十进制样式点测量,而是以米为单位。更容易理解地图的区别。让我们画出原始国家和预计国家。
Left WGS84 World map. Right World Mercator Projection map
请注意两张地图中 x 和 y 的不同比例。随着我们从赤道到两极越走越远,墨卡托投影扭曲了物体的大小。这就是为什么非洲看起来很小,而格陵兰岛看起来比它的面积大得多。
如果您尝试用未投影的数据覆盖投影的数据,那么您的数据将不会正确对齐。让我们看看我们是否能在投影国家的顶部绘制城市。请记住,我们没有规划城市。
Overlay Projected countries and unprojected cities
如您所见,城市在投影国家数据集中没有正确叠加。他们落在非洲附近,那不是他们该去的地方。为了正确地对齐它们,我们还需要对国家数据集进行相同的投影,EPSG:3395,这是一个练习。
练习 2.1:将城市数据转换为 EPSG:3395 投影,并在 countries_proj 的顶部绘制城市。
3.写入地理数据
我们可以轻松地将任何新创建的数据保存到本地磁盘。当您希望在其他时间访问该文件而不再次执行相同的操作时,这很有帮助。让我们拯救我们预测的国家。记住我们已经计划好了。Geopandas 有.to_file()
方法。
这将保存您的文件。你可能想下载这个文件,因为我们正在使用 collab,没有用 Google drive 配置它。当您在 Google Colab 中关闭您的会话时,这将被删除。
如果您已经猜到我们还需要保存练习 2.1 中的预测城市,那么您是对的。这是本部分的最后一个练习。
练习 3.1:将在练习 2.1 中创建的投影城市文件保存到一个文件中
结论
在本教程中,我们已经讲述了加载和写入地理数据以及地理坐标系和投影的基础知识。在下一教程中,我们将学习使用 Geopandas 对地理数据进行地理处理和操作。该代码可从以下 GitHub 存储库中获得:
地理数据科学教程系列。在 GitHub 上创建一个帐户,为 shakasom/GDS 的发展做出贡献。
github.com](https://github.com/shakasom/GDS)
您也可以直接从以下链接运行 Google Collaboraty Jupyter 笔记本:
编辑描述
colab.research.google.com](https://colab.research.google.com/github/shakasom/GDS/blob/master/Part1%20-%20Introduction.ipynb)
掌握你的假设检验
关于电源、自举、样本选择和结果分析的教程。
Photo by Vienna Reyes
在本教程中,我们将浏览一个 FIFA '19 球员属性数据集以回答一个简单的问题:哪个国家出产更好的足球运动员?英格兰或西班牙。
本教程将涵盖哪些内容:
- 清理和设置数据
- 定义无效假设和替代假设,并确定α
- 功率和样本大小,以及自举
- 计算 T 值
- 计算 P 值
- 评估测试并得出结论
在我们开始之前,我想包括一个小备忘单,里面有一些与假设检验相关的常用术语和概念。当我阅读那些期望你已经了解你的主题的所有东西的教程时,这总是让我有点恼火…因为如果你知道,你可能就不需要教程了。
迷你测试小抄
P 值:
当研究问题的零假设(H 0)为真时, P 值或计算概率是发现观察到的或更极端的结果的概率——“极端”的定义取决于假设如何被检验
- 当试图决定是否拒绝你的零假设时,p 值真的很有用。
Z 值(Z 分数):
“从技术上来说,一个 z - 分数是参考人群(一个已知值已被记录的人群,就像 CDC 编制的这些关于人的体重的图表)的平均值的标准偏差数。A z - 得分为 1 比平均值高 1 个标准差。”
T 值:
t - 值测量相对于样本数据变化的差异大小。
类型错误:
在统计假设检验中,一个型 I 错误是拒绝一个真的零假设(也称为“假阳性”发现或结论),而一个型 II 错误是拒绝一个假的零假设的失败(也称为“假阴性”发现或结论)。
理论
这一节希望有助于澄清围绕假设检验的一些困惑。T 检验有两种类型:单尾和双尾。
单尾:
- 单尾检验要求样本之间的差异在特定方向上。例如,如果我们想测试一个新的电子邮件营销策略。如果我们原来的策略有 30%的成功率,我们想看看我们的新策略是否更好,这意味着它的成功率高于 30%,我们将不得不使用单尾测试。
双尾:
- 双尾检验要求样本之间的差异在任一方向。
- 当您想要找出两个样本平均值之间是否存在统计差异时使用。这与单尾检验不同,因为我们不关心差异是高还是低。
- 非常适合我们在这个例子中所做的比较。
当执行双尾检验时,有一些事情需要考虑。
- 有没有两类可以比较?
例如:最初,我想比较重量和速度。但是为了进行假设检验,您需要为这些属性中的每一个属性建立一个类别。体重和速度与类别(即团队或国家)没有任何联系,因此很难对它们进行统计测试,而如果你想用这些模型建立线性回归将会非常容易。
2.两个数据集必须是独立的
为了收集有意义的数据,这两个数据集必须相互独立,这就是为什么重量和速度不起作用的原因,因为速度与重量成线性关系。
因此,对于这个例子,我们将使用基于两个独立数据集的双尾假设检验,希望找到每个国家生产的球员质量的统计差异。
既然我们已经想好了如何从概念上接近我们的测试,那么是时候实际制作东西了!
假设检验的步骤:
- 收集数据:
首要任务是收集有用的数据。对于这个例子,我使用的是来自视频游戏 *FIFA 19 的玩家属性数据。*数据需要被清理和组织,以便您以后在执行假设检验时可以方便地访问它。我使用 python、pandas、Numpy 和 Sci-kit learn 来执行这些测试。为了在 Jupyter 笔记本中使用这些工具,您必须导入它们。
import pandas as pd
import numpy as np
import seaborn as sns
import scipy
import matplotlib.pyplot as plt
from scipy import stats
from statsmodels.stats.power import TTestIndPower
根据我最初的问题,我知道我需要来自英格兰和西班牙球员的包含总体属性的数据。
注意:选择英格兰和西班牙是因为数据集中有大量来自这两个国家的球员。
fifa_df['Nationality'].value_counts().head()England 1662
Germany 1198
Spain 1072
Argentina 937
France 914
在下面的代码中,我使用 FIFA 19 数据创建了一个 DataFrame 然后将它们分成 Numpy 数组,我可以用它们来执行我的假设测试。
fifa_df = pd.read_csv('data 2.csv')fifa_df = fifa_df.drop(['Photo', 'Flag', 'Club Logo'], axis =1)overall_df= fifa_df[['Overall', 'Nationality']].dropna()finishing_df = fifa_df[['Finishing', 'Nationality']].dropna() #Selects Overall From English Born Players
overall_eng = overall_df[overall_df['Nationality'].str.contains("England")==True]#Selects Overall From Spanish Born Players
overall_spa = overall_df[overall_df['Nationality'].str.contains("Spain")==True]
我上面创建的是熊猫系列,包含了所有分别出生在英格兰和西班牙的玩家的核心。为了让我们的生活更轻松,让我们把这些系列变成 Numpy 数组。Numpy 数组非常通用,Numpy 库有大量有用的函数。
#Englishenglish_ov_df = overall_eng['Overall']
english_overall = np.array(english_ov_df)
english_overall#Spanishspanish_ov_df = overall_spa['Overall']
spanish_overall = np.array(spanish_ov_df)
spanish_overall
完美!因此,现在我们已经将我们的数据浓缩成一些东西,我们可以将它们输入到下面将要创建的函数中
2。定义无效假设和替代假设。
创建假设检验时,您需要定义一个空假设和替代假设。我喜欢这么想。
空:第一个数据集的 表示 与第二个数据集的 表示 相比没有任何统计差异。
Alt:第一个数据集的 表示 与第二个数据集的 表示 相比,确实有统计学差异。
那么我们应该如何写这个例子呢?
零:在英格兰出生的球员和在西班牙出生的球员在整体技能上没有统计学差异。
Alt:一个出生在英格兰的球员和一个出生在西班牙的球员在整体技能上有统计学上的差异。
Alpha :定义为。 *05。*通常,当运行双尾测试时,选择α值 0.05 作为误差的标准度量。如果你看下面的图表,两个尾端是阿尔法值。
Alpha = .05, but since it’s two-tailed- the alpha is split in half
3。功率、尺寸和自举
抽样是假设检验的主要部分。抽样背后的哲学很简单;利用真实人口实际上是不可能的(这将花费太多的时间和金钱),因此为了得出结论,我们必须从人口中取样,并得出结论,这些发现代表了整个人口。为了找到本例中的样本大小,我们将找到效果大小,我们可以用它来找到我们测试的功效。然后,power 将给出我们必须收集的样本的最小值,以满足约束条件。
from statsmodels.stats.power import TTestIndPower
科恩的 d :在计算幂之前,我们需要求解两个不同国家之间的科恩的 d。科恩的 d 效应大小衡量的是两组球员的 表示 之间的差异(在这种情况下,英格兰球员的整体技能vs 西班牙球员的整体技能)。这让我们对两组之间实际发生了多少变化有了一些了解。Cohen’s d 效应大小的结果用标准差来衡量。在下面的代码中,您可以看到如何使用 python 函数计算 Cohen 的 d。
def calc_cohen_d(group1, group2):
"""Calculate and Define Cohen's d"""# group1: Series or NumPy array
# group2: Series or NumPy array# returns a floating point numberdiff = group1.mean() - group2.mean()n1, n2 = len(group1), len(group2)
var1 = group1.var()
var2 = group2.var()# Calculate the pooled threshold as shown earlier
pooled_var = (n1 * var1 + n2 * var2) / (n1 + n2)
# Calculate Cohen's d statistic
d = diff / np.sqrt(pooled_var)
return d# To use our function, we simply call it using the numpy arrays we created earlier. cohens_d = calc_cohen_d(english_overall, spanish_overall)
abs(cohens_d)0.939861699762249
评估测试的效果分为三个部分:
0.0–0.20 =小影响
0.20–0.50 =中等效果
0.50 + =大效果
科恩的 d 应该总是正的,这也是我们取绝对值的原因
根据我们的计算,我们的测试应该有很大的影响。下一步是通过确定我们的测试能力来计算我们的最小样本量:这也可以通过几行 python 代码来完成,如下所示:
# Define Variables
effect = cohens_d
alpha = 0.05
power = 1
# sample 2 / sample 1
ratio = len(spanish_overall) / len(english_overall)# Perform power analysis
analysis = TTestIndPower()
result = analysis.solve_power(effect, power=power, nobs1=None,ratio=ratio, alpha=alpha)print(f"The minimum sample size: {result}")
print(f"Number of players:{len(spanish_overall)}")The minimum sample size: 500.0
Number of players:1072
我们的能量测试结果很有希望。由于我们有很高的能级,当我们计算它们时,我们能够自信地得出结论。
关于电源的简短说明:
- 功效用于确定测试出现 II 型错误的可能性。
- 功效越高,测试出现第二类错误的几率越低,反之亦然。
- 功率值介于 0 和 1 之间
- 功率低于 0.80 的测试通常被认为太低。
该函数的输出告诉我们,为了获得 1.0 的功率水平,我们只需要使用 500 个样本。幸运的是,我们有 1072 个,有很多可以玩!
所以我们最终得到了样本量。我们对 采样 了解多少?
- 它应该是随机的,以确保它能代表总体。
- 我们的数据应该服从正态分布
- 我们的价值观应该相互独立。
但是如果不是或者我们不确定呢?如果我们不确定,有一个非常有用的工具叫做 bootstrapping。自举模拟新的数据收集,我的意思是它从**原始样本中随机抽取替换的新样本,**计算平均值并创建现在可以用于运行测试的新数据。
这是因为假设您的原始样本已经代表了 人口 。所以只要你从原始样本中取样,它就应该模仿收集新的 真实 数据的动作,这些数据代表 总体 。比方说,你有一个完整的 cookie(群体),然后你掰下那个 cookie 的一半(原始样本)。然后从原始样本中分离出 2 个较小的片段(引导样本)。bootstrapping 背后的想法是(bootstrap samples)只是原始样本的一部分,尝起来就像原始 cookie 被分开之前的味道。下面的代码向您展示了如何做到这一点。
sample_means_overall_eng = []
for _ in range(1000):
sample_mean = np.random.choice(english_overall,size=500).mean()
sample_means_overall_eng.append(sample_mean)
len(sample_means_overall_eng)sample_means_overall_french = []
for _ in range(1000):
sample_mean = np.random.choice(english_overall,size=500).mean()
sample_means_overall_french.append(sample_mean)
len(sample_means_overall_french)
基本上,我们使用我们计算的样本大小(500)并根据随机抽样创建了 1000 个新样本。这在概念上就像我们去英格兰和西班牙,从每个国家的另外 1000 名玩家那里收集数据一样。
到了第四步,我们终于开始发现这些工作是否真的重要了!
4。计算 T 值(长距离):
这是看起来很吓人的 T-Stat(T 值)公式。
This is ugly…. so we broke it up into formulas!
这太难看了…所以我们把它分解成更小更简单的公式!
def calc_variance(sample):
'''Computes the variance a list of values'''
sample_mean = np.mean(sample)
return sum([(i - sample_mean)**2 for i in sample])
上面的公式计算 Numpy 数组中的方差。
def calc_sample_variance(sample1, sample2):
'''Computes the pooled variance 2 lists of values, using the calc_variance function'''
n_1, n_2 = len(sample1), len(sample2)
var1, var2 = calc_variance(sample1), calc_variance(sample2)
return (var1 + var2) / ((n_1 + n_2) - 2)
此公式计算两个样本平均值的混合方差。
def calc_twosample_tstatistic(expr, ctrl):
'''Computes the 2-sample T-stat of 2 lists of values, using the calc_sample_variance function'''
expr_mean, ctrl_mean = np.mean(expr), np.mean(ctrl)
n_e, n_c = len(expr), len(ctrl)
samp_var = calc_sample_variance(expr,ctrl)
t = (expr_mean - ctrl_mean) / np.sqrt(samp_var * ((1/n_e)+(1/n_c)))
return t
这是泰姬陵。这个函数使用上面定义的两个函数来计算 T-Stat。
t_stat = calc_twosample_tstatistic(sample_means_overall_eng, sample_means_overall_spanish)t_stat-480.6580710651087
5。计算 T-Stat 和 P-Value(最简单的方法):
为了计算我们的 P 值并再次检查 T-Stat,我们将使用另一个导入的库。这个公式接受我们的两个样本均值,这两个均值与我们使用自举方法创建的数组相同,并输出一个 T 值和一个 P 值。
stats.ttest_ind(sample_means_overall_eng,
sample_means_overall_spanish)Ttest_indResult(statistic=-480.6580710651088, pvalue=0.0)
如您所见,T-Stat 与我们之前计算的完全相同!这是一个非常好的健全性检查,公式也给了我们一个 P 值。
6。评估我们的 P 值
当我们想要接受或拒绝我们的零假设时,我们想要参考我们的 p 值。在本教程的前面,我们将 alpha 定义为. 05。这意味着我们期望假设我们的零假设是正确的,我们的测试在 95%的情况下是正确的,而另外 5%是不正确的,因为随机机会。由于这是一个我们上面定义的 双尾检验 ,我们就把 alpha 误差一分为二,放在我们分布的两边。这意味着我们要寻找的 p 值是 0.025,也就是 2.5%。如果我们的 p 值小于或等于我们的预期误差,那么我们将拒绝我们的零假设。
这背后的逻辑有点反直觉。p 值是我们得到超出 95%置信区间的随机结果的可能性。如果 p 值小于我们的 alpha,这意味着超出 95%的结果不太可能是随机的,这意味着它是显著的,不应该作为错误被忽略。然而,如果 p 值高于我们的α值,这意味着在我们的 95%区间之外的结果很可能是随机的,所以我们不应该惊慌失措,也不会拒绝(也就是保持)我们的零假设。
结论:
对于我们的例子,由于我们的 p 值为零,这意味着我们将接受我们的替代假设,并得出结论,英格兰或西班牙球员的整体技能存在差异。
根据 FIFA 球员 19 数据集显示,西班牙球员明显优于英国球员。所以,如果你想成为一名职业足球运动员,或者你想让你的孩子成为下一个莱昂内尔·梅西,也许西班牙是你应该训练他们的地方。
一些旁注:
效应大小对功效/样本大小:效应大小和功效有负的线性关系。Power 帮助您确定样品的尺寸,以满足其要求。根据您的能力,您需要的样本数量将根据效果大小而变化。例如,如果您有一个大的效果尺寸,那么为了满足您的功率要求所需的样本数将会更少。就像上面的例子一样,如果我取 0.90 的幂而不是 1,那么最小样本量应该是 30 左右。这是因为两个样本平均值的效应大小非常接近于 1。
p 值与效应大小:评估假设检验的结果时,p 值是一个有用的工具。效应大小可以预测 p 值的结果。如果影响大小非常大,就像我们的测试中一样,那么有理由认为两个样本组的平均值之间存在显著的统计学差异。如果存在统计学上的显著差异,那么 p 值将非常接近于零,这意味着您将拒绝零假设。因此,您应该记住,如果您运行一个效应大小在 0.6 到 1.0 之间的测试,并且 p 值高于您的 alpha 值,您可能需要重新检查您的测试并确保没有出现错误。(我知道这一点,因为我在编写本教程时犯了这个错误)
Bootstrapping: Bootstrapping 并不总是必要的,事实上,它是一种被采用的方法,因为计算机几乎可以瞬间创建新数据。如果您有大量正态分布的数据,那么您不必进行引导。Bootstrapping 是一种在数据有限且可能无法完美分布时使用的工具。
我希望这篇教程有所帮助。我介绍了一些不同的策略,这些策略对于假设检验来说并不完全必要,但是我认为介绍更复杂的想法会有所帮助。如果你对代码感到好奇,想看看我的回购,它的链接 在这里 **!**在 LinkedIn 上联系我!
还有,查一个我参与的 近期项目 。我们用足球数据按联赛得出了主场优势、阵型优化、球队属性的一些结论!
参考文献:
p 值定义:https://www.statsdirect.com/help/basics/p_values.htm
z 值定义:https://www . statistics show to . data science central . com/probability-and-statistics/z-score/
实力:https://www.statisticsteacher.org/2017/09/15/what-is-power/
类型错误:https://en.wikipedia.org/wiki/Type_I_and_type_II_errors
掌握数据科学和实现职业转型的 5 大常见问题
Photo by Johannes Andersson
最近,我一直在指导弗吉尼亚一所历史悠久的学校的商业分析硕士项目的应届毕业生。具有讽刺意味的是,尽管分析技能的需求很高,但残酷的现实是,这些学生发现即使在获得分析硕士学位后,也很难获得面试和工作。
这并不是说他们在从哪里获得分析技能方面做出了错误的选择——该计划涵盖了很多分析领域,并在计划结束时提供了与真实客户、真实项目的实践经验。
挑战在于掌握工作转换的复杂性,就像他们掌握了商业分析一样。从本质上来说,找工作就像营销——不是每个收到传单的人都会打电话接受邀请。但是有一些方法可以提高几率,下面是方法。
1.求职有一个漏斗。我曾经和想要成为分析专家的人聊过,他们申请了 5 份、10 份甚至 20 份工作,当他们没有得到一次面试机会时,他们会感到失望。我提醒他们,“不是你没有得到面试机会,而是你还没有得到的面试机会!”5 份、10 份、20 份甚至 50 份工作申请都不足以填满漏斗的顶端;不足以获得 20 次面试和一两个工作机会。
我对职业转换客户的经验法则是申请大约 180 份“目标”工作。如果他们没有获得 20 次面试机会,那么他们可能会得出结论,他们的简历有问题,但之前没有。如果他们完成了 20 次面试,却没有得到一两个机会,那么他们可以得出结论,他们在面试中做错了什么,但之前没有。当然,所有这些假设都已经满足:他们在Aryng analytics aptitude assessment中获得了 16 分或更高的分数,完成了核心课程,完成了客户项目(客户对此很满意),缩小了他们的目标工作概况,并根据他们的每个目标概况定制了简历。这些数字可能看起来更好,这取决于你所在地区、行业和经验水平等的需求。当然,如果你在公司内部调动或者通过你的关系网,你的漏斗会看起来更好。
2.锁定目标会增加你的胜算。不要盲目申请 180 的工作。相反,确定你的梦想轮廓。你的梦的轮廓是你从哪里来的函数。如果你在职业生涯的大部分时间里都是一家能源公司的项目工程师,那么在一家能源公司的工程、IT 或战略部门寻找一份分析工作将是你的最佳选择。
LinkedIn 工作和其他工作网站允许你根据这些和其他许多标准来筛选职位。筛选之后,寻找那些让你兴奋到迫不及待去申请并开始工作的工作。结果:你的目标梦的轮廓。从那里,寻找类似的工作。
要增加您的职务库,您可以通过删除一些早期标准来创建更多优先级较低的职务。例如,搜索能源行业的任何分析工作或石油和天然气等相关行业的工程分析工作。
3.定制简历不是可有可无的。在我咨询的几乎 100%的案例中,我都建议职业转型专家从头开始写简历。你的目标是做一份 8 秒钟的简历——一份经过 8 秒钟审核后就可以进入“是”堆的简历。你将如何做到这一点?我的书《把握你的分析职业转型》将为你提供指导,但简而言之,你要讲述一个引人注目的故事,讲述一位分析师在具有影响力的项目中展现出分析才能和分析技能的故事。你可以利用你的客户项目和课程项目以及你以前的工作经验来完成。一旦你有了一份主简历,一定要为你的每一份目标工作量身定制。
4.随着技能的提高,你不需要学习所有的工具和技术。分析更多的是一种心态,而不是学习如何使用工具或掌握每一项技术。一旦你知道了一个类别中的一个工具,你就可以很容易地申请到要求涉及同一类别中另一个工具的工作。例如,如果您知道如何使用 R 来操作数据和构建预测模型,那么如果您使用 SAS enterprise miner,只需几天时间就可以学会 SAS base 中的正确语法,从而达到相同或更短的持续时间。技术也是如此。学习最常用的数据科学技术,其余的可以在项目需要时随时掌握。在商业中,最常用的商业分析方法是聚合和关联分析。最常见的高级/预测技术包括逻辑回归、线性回归、决策树和 k 均值聚类。我会在我的书’每一个好决策的背后’'的第三章和第六章分别谈论更多的方法和工具。
5.预计需要 9-12 个月的时间来提高技能和过渡。虽然我看到我的一些客户在 4 个月内就完成了转型,但这并不是大多数专业人士的真实写照。在职业转型专家开始申请工作之前,我的 Aryng 项目有 80 个小时的课程工作和两个月的客户项目,假设他们同时在工作目标和简历方面工作。我们的项目是最快、最快速、最适合工作的项目,但是大多数人仍然需要 9-12 个月来完成他们的过渡。大多数其他项目没有这么快,所以给自己一些时间来享受这个旅程。这不会一蹴而就。
如果你有更多的问题,需要我的个人指导,请点击这里的阿林分析能力评估,开始评估你的分析能力。
使用免费 GPU 在 Google Colaboratory 上掌握快速梯度提升
On the photo NVIDIA K80 GPU, https://www.nvidia.com/ru-ru/data-center/tesla-k80/
决策树上的梯度推进 (GBDT)是一个最先进的机器学习工具,用于处理异构或结构化数据。处理数据时,完美算法的选择在很大程度上取决于数据的类型。对于同类数据,如图像、声音或文本,最佳解决方案是神经网络。对于结构化数据,例如信用评分、推荐或任何其他表格数据,最佳解决方案是 GBDT。
正因如此, Kaggle 比赛的大量获奖方案都是基于 GBDT。GBDT 也大量用于不同的推荐系统、搜索引擎和许多金融机构。
许多人认为 GBDT 无法通过 GPU 有效加速,但事实并非如此。在这篇文章中,我解释了如何使用 GPU 加速 GBDT。
对于 GBDT 实现,我将使用 CatBoost 。CatBoost 以其分类特性支持和高效的 GPU 实现而闻名。它不仅适用于分类数据,而且适用于任何数据,在许多情况下,它的性能优于其他 GBDT 图书馆。
该库是为领先的俄罗斯科技公司 Yandex 的生产需求开发的,后来大约一年半前在 Apache 2 许可下开源。
我的演示的测试环境将是 Google 联合实验室 。这是一个免费访问 GPU 运行时的机器学习研究工具。这是一个 Jupyter 笔记本电脑环境,不需要设置即可使用。
谷歌合作实验室免费提供相当老的 GPU——一个大约 11GB 内存的特斯拉 K80 GPU。随着新的 GPU,速度的提高将更加显著。但即使使用这种旧的 GPU,你也会看到令人印象深刻的速度差异。
下面你会发现在 Colab 中设置 CatBoost 的几个简单步骤,下载数据集,在 CPU 和 GPU 上训练模型,以及比较执行时间。
创建笔记本
导航到协同实验室并创建一个新的 Python 3 笔记本。
将 GPU 设置为硬件加速器
选择 GPU 作为硬件加速器有两个简单的步骤:
第一步。导航到“运行时”菜单并选择“更改运行时类型”
第二步。选择“GPU”作为硬件加速器。
导入 CatBoost
下一步是在环境中导入 CatBoost。大多数库都可以通过简单的快速安装在 Colaboratyro 中!pip 安装命令。
请注意,每次启动新的 Colab 会话时,都需要重新导入库。
!pip 安装 catboost
从 pypi 安装的 CatBoost 库支持 GPU,因此您可以直接使用它。要让它在你的机器上工作,你只需要安装一个 NVIDIA 驱动程序,其他一切都可以开箱即用。对于 Windows 来说也是如此,这使得想要在 GPU 上训练模型的 Windows 用户更加容易。
下载并准备数据集
是时候编码了!配置好环境后,下一步是下载和准备数据集。对于 GPU 训练来说,数据集越大,加速就越大。对一千个样本或更少的数据集使用 GPU 训练没有太大意义,但从大约 10,000 个样本开始,你将获得很好的加速。
我们需要一个大型数据集来展示 GPU 在 GBDT 任务中的能力。我们将使用 Epsilon ,它有 50 万个样本和 2000 个特征,包含在 catboost.datasets 中
下面的代码下载数据集大约需要 10-15 分钟。请耐心等待。
CPU 培训
为了消除关于 GBDT 在 GPU 上没有表现出大的速度增益的神话,我想比较一下 GBDT 在 CPU 和 GPU 上的训练时间。先说 CPU。下面的代码创建一个模型,对其进行训练,并测量训练的执行时间。它使用默认参数,因为它们在许多情况下提供了相当好的基线。
我们将首先训练我们所有的模型 100 次迭代(因为在 CPU 上训练它需要很长时间)。
运行此代码后,您可以将其更改为默认值 1000 或更多次迭代,以获得更好的质量结果。
CatBoost 将需要大约 15 分钟在 CPU 上训练 100 次迭代。
在 CPU 上拟合模型的时间:877 秒
关于 GPU 的培训
所有以前的代码执行都是在 CPU 上完成的。现在该用 GPU 了!
要启用 GPU 训练,您需要使用 task_type=‘GPU’ 参数。
让我们在 GPU 上重新运行实验,看看结果会是什么时间。
如果 Colab 会给你显示“GPU 内存使用接近极限”的警告,按“忽略”即可。
在 GPU 上适应模型的时间:199 秒
GPU 比 CPU 加速:4.41 倍
如你所见,GPU 比 CPU 快 4 倍。它只需要 3-4 分钟,而 CPU 需要 14-15 分钟来适应模型。此外,学习过程仅需 30 秒,而不是 12 分钟。
当我们训练 100 次迭代时,瓶颈是预处理而不是训练本身。但是对于在大型数据集上获得最佳质量所必需的数千次迭代来说,这个瓶颈将是不可见的。你可以尝试在 CPU 和 GPU 上训练 5000 次迭代,再比较一次。
密码
上面所有的代码你都可以在 CatBoost 仓库找到,作为谷歌合作实验室的 教程 。
摘要
- GBDT 训练在 GPU 上完美运行。
- CatBoost 是一个超快速的 GBDT 实现,具有 GPU 开箱即用的支持。
- Google Colaboratory 是一个有免费 GPU 支持的有用工具。
进一步阅读
[1] V .埃尔绍夫, CatBoost 使用 GPU 在决策树上实现快速梯度提升,NVIDIA 博客文章
[2] CatBoost GitHub
[3] R. Mitchell,梯度增强,决策树和 XGBoost 与 CUDA ,NVIDIA 博客文章
[4] LightGBM GPU 教程
使用 Selenium 和 Python 掌握 web 抓取艺术(第 1/2 部分)
Selenium 是与网站进行高级交互的强大工具:登录、点击…让我们用它来抓取网页
Using Selenium to do web scraping requires a specific strategy to access the data you seek
或者 90%的网站,你不需要硒。事实上,简单的请求和美丽组合组合就能完成任务。我写了一篇关于如何做到这一点的文章。
但是如果网站要求你在访问它的内容之前登录呢?如果您想要抓取的页面没有特定的 url,而您需要点击按钮并触发 javascript 操作才能到达正确的页面,该怎么办?
这就是本文的目标:在不简单抓取的网站上实现网页抓取。
安装 Selenium
Selenium 模拟 web 浏览器。实际上,你不仅可以模仿 Chrome,还可以模仿 Firefox、Safari 和 Edge。你需要在这里安装需要的组件。在本文的其余部分,我将使用 Chrome 模拟器。
使用以下内容安装 Python 包:
pip安装硒
用 Python 运行 Selenium
好了,现在让我们打开一个 Jupyter 笔记本,尝试运行以下代码:
从硒导入 webdriver
浏览器= webdriver。chrome(executable _ path = '/usr/local/bin/chrome driver ')
browser . get(URL = " https://www . Facebook . com ")
Selenium opens a new Chrome window and goes to facebook.com
请注意,*'/usr/local/bin/chrome driver '*可能会为您而改变,无论您是在 Mac、PC 等设备上。
让我们登录:
browser . find _ element _ by _ XPath(“//input[@ type = ’ email ']”)。send _ keys(‘your _ email _ address _ here’)
browser . find _ element _ by _ XPath(“//input[@ type = ’ password ']”)。send _ keys(‘your _ password _ here’)
browser . find _ element _ by _ id(" log in button ")。单击()
这应该很好!如果弹出窗口出现,您可以在以后使用以下命令禁用它。
替换
浏览器= webdriver。chrome(executable _ path = '/usr/local/bin/chrome driver ')
与以下内容
选项=网络驱动程序。chrome options()
option . add _ experimental _ option(" prefs ",{ " profile . default _ content _ setting _ values . notifications ":2 })
browser = web driver。chrome(executable _ path = '/usr/local/bin/chrome driver ',chrome_options=option )
There can be a notification just after you logged in. You can automatically disable pop-ups with Selenium.
结论
硒入门没那么难。棘手的是提前准备好网页抓取方案。在下一篇文章中,我们将关注一个真实的 web 抓取用例,并设计一个具体的方案来实现它。
奖金
几个关于我如何使用 Selenium + Python 的例子
Selenium posting on Facebook
= >我自动在 70 多个脸书小组上发表了关于机器学习的文章。不幸的是,我最近重新运行了代码,发现脸书更新了网站以避免这种行为:/
Selenium filling an online quiz
= >我完成了之前公司的在线培训(约 40 次培训,每次约 120 个不同的问题),并在排行榜上获得第一名
= >我收集了多个网站的在线电影评论(千兆字节的文本数据,真的很酷,可以训练 ML 模型!)
而这只是冰山一角。你还可以做很多其他很酷的事情。
使用 Selenium 和 Python 掌握 web 抓取的艺术[第 2/2 部分]
Selenium 是与网站进行高级交互的强大工具:登录、点击…让我们用它来抓取网页
好吧,让我们做一些简单的事情:收集 Spotify 上所有可用的艺术家。
That’s a robot scrolling through Spotify’s catalog of artists
⚠️Obviously,我需要在这里放一个免责声明⚠️
不要用这种方法倒卖你收集的数据,这些都是公司私有的。特别是,不要转售 Spotify 数据或对其做任何非法的事情。
第二点备注:既然 Spotify 有一个 API ,那么从网站获取数据就有点蠢了。然而,这是一个很好的练习和你通常可以从网络抓取中获得比使用受限 API 更多(但更慢)的东西(虽然不确定 Spotify 是否如此)。
如果您错过了关于 Selenium 和 Python 的第一篇文章,请点击这里:
[## 使用 Selenium 和 Python 掌握 web 抓取艺术(第 1/2 部分)
Selenium 是与网站进行高级交互的强大工具:登录、点击…让我们用它来抓取网页
towardsdatascience.com](/mastering-the-art-of-web-scraping-with-selenium-and-python-part-1-2-90a216199873)
首先,了解网站是如何运作的
Spotify’s page when “a” was typed in the search bar
- 您需要登录才能看到艺术家
- 搜索时不会显示所有艺术家——否则你的浏览器会因加载的大量数据而崩溃……所以你需要发挥创造力,在避免浏览器溢出的同时获得比显示更多的内容
- 你需要以某种方式召集所有的艺术家。同样,这里需要一些创造力
研究 html
打开 Chrome 开发者工具,深入研究 html。艺术家的名字和相关联的 url 位于一个“div”标记中,该标记具有一个等于“Search__content”的类
现在您需要向下滚动,因为只显示了 50 位艺术家。我花了相当多的时间在这里,因为滚动不是在整个窗口,而是在艺术家标签。想法是:取最后一个加载的艺术家并滚动到它。
最后,回顾任务
如前一篇文章所见,登录部分很简单。
正常
搜索部分应该不是最难的:只需在搜索栏中写些东西,然后按回车键。有一个关于搜索完成后向下滚动的问题,以及你需要向下滚动多少次。
~还好好歹
彻底搜索似乎是最棘手的部分。我们不知道我们是否会得到 Spotify 上艺术家的完整列表,没有什么会告诉我们我们已经达到了 Spotify 上艺术家的最大数量。从这个,看起来有 100 万到 100 万 2M 艺术家。
~好吧总之
让我们言归正传。
然后设计你的网页抓取方案
Bot 指南
我们将为我们的网页抓取机器人设定两条准则:
- 它将滚动 4̶0̶ 100 次[ 更新:尝试了 40 次,但得到了太多的重复,搜索后改为 100 次
- 它将在目录中搜索两个字母的所有可能组合
我们可以估计大约 26x26 个搜索,大约 50 个结果/滚动导致
26 x 26 x 50 x 100 = 3 380 000 最大独特艺术家。注意,我们可能会有很多副本。
并行运行
您想要做的另一件事是将流程设置为并行执行。您不希望等待一个 python 脚本来完成所有工作,而是希望有多个 python 脚本来完成这项工作。
在这种情况下,我们可以设置 2̵6̵ 4bots [ 更新:试过 26 我的电脑死机了,还注意到打开 5 个以上窗口后页面停止刷新;我把它改成了 4 个机器人,每个机器人从一个不同的字母开始,第二个字母尝试 26 个字母。例:*机器人 1 会尝试‘aa’,‘ab’,‘AC’,…,‘az’。*注意,26 个[ 4 ] Chrome 会话将运行我的 Mac(我可怜的 Mac…)。不确定 Spotify 是否会自动检测同一个用户的多个活动会话并断开我的连接[ 更新:它不关心多个会话 ]。生活是有风险的,有时候你只能盲目去相信。
实时监控
在创建和运行脚本之前,您还需要实时监控流程的进展情况。我不知道如何做到这一点,但我可以想到看到所有机器人的进度条,他们完成的预期剩余时间,当前收集的艺术家数量…因此,多一个 Python 脚本将进行实时监控。
The Jupyter Notebook is monitoring in real-time the 5 web scraping bots. Note they have really different speed.
The number of artists found gets updated in real-time as well as the number of duplicates
还要估计一下需要的时间。滚动 1 次后,您将等待 1 秒钟加载结果。所以~2 分钟/搜。26 次搜索 x 2 分钟 x 6 次运行(4 个机器人同时运行),因此我可以在最乐观的情况下预计整个网页抓取方案将在 3 小时内完成。
让表演开始吧
1 Python script to search some artists, scroll down and save the list in a txt file
Jupyter Notebook to monitor everything
我不得不承认我没有完成练习。我的电脑声音比机场还大,我知道我有足够的时间完成它,但无论如何,你得到的想法。
在 2 个小时内,我得到了 38174 个独特的艺术家,其中有 AC/DC,克里斯蒂娜·阿奎莱拉,暴力反抗机器,但没有蕾哈娜或阿姆。
掌握数据科学面试循环
2012 年,《哈佛商业评论》宣布数据科学将是 21 世纪最性感的工作。从那以后,围绕数据科学的炒作只增不减。最近的报告显示对数据科学家的需求远远超过供给。
然而,现实是这些工作大部分是为那些已经有经验的人准备的。另一方面,由于供求关系的变化,入门级的数据科学工作竞争非常激烈。数据科学家来自各种背景,从社会科学到传统的计算机科学背景。许多人还将数据科学视为重塑自我的机会,这将导致大量人员涌入,寻求获得他们的第一个角色。
让事情变得更复杂的是,与拥有更标准化面试流程的软件开发职位不同,数据科学面试可能会有巨大的变化。这部分是因为作为一个行业,仍然没有对数据科学家达成一致的定义。Airbnb 认识到了这一点,并决定将他们的数据科学家分成三路:算法、推理和分析。
https://www.linkedin.com/pulse/one-data-science-job-doesnt-fit-all-elena-grewal/
因此,在开始寻找角色之前,确定什么样的数据科学吸引你是很重要的。基于你对此的回答,你所学的内容和你将被问到的问题会有所不同。尽管类型不同,但一般来说,他们会遵循类似的面试循环,尽管问的特定问题可能会有所不同。在这篇文章中,我们将探讨在面试过程的每一步会遇到什么,以及一些技巧和准备方法。如果你在寻找一份可能在面试中出现的数据科学问题清单,你应该考虑阅读这个和这个。
编码挑战
编码挑战可以从简单的 Fizzbuzz 问题到更复杂的问题,例如使用杂乱的数据建立时间序列预测模型。这些挑战将根据问题的复杂程度进行计时(从 30 分钟到一周不等)。挑战可以在诸如 HackerRank 、 CoderByte 等网站上进行,甚至可以在公司内部解决方案上进行。
通常情况下,你会得到书面的测试案例,告诉你是否通过了一个问题。这通常会考虑正确性和复杂性(例如,运行代码需要多长时间)。如果没有提供测试,编写自己的测试是个好主意。面对数据科学编码挑战,你甚至可能会遇到统计方面的选择题,所以一定要问招聘人员你到底要考什么。
当你面临编码挑战时,记住公司并不总是在寻找“正确”的解决方案是很重要的。他们可能还在寻找代码可读性、良好的设计,甚至是特定的最佳解决方案。所以,即使通过了所有的测试案例,你也没有进入面试过程的下一个阶段,不要太在意。
准备:
- Leetcode 上的练习题,既有 SQL 也有传统的数据结构/算法题
- 复习数学和统计题的精彩。
- SQL Zoo 和 Mode Analytics 都提供了各种可以在浏览器中解决的 SQL 练习。
温馨提示:
- 开始编码之前,通读所有问题。这让你的潜意识开始在后台处理问题。
- 先从最难的问题开始,当你遇到困难时,先处理简单的问题,然后再处理较难的问题。
- 首先关注通过所有的测试用例,然后再考虑提高复杂性和可读性。
- 如果你做完了,还剩下几分钟,去喝一杯,试着清醒一下头脑。最后一次通读你的答案,然后提交。
- 没有完成编码挑战也没关系。有时,公司会在一周的时间限制内创造出不合理的乏味的编码挑战,需要 5-10 个小时才能完成。除非你绝望了,否则你可以走开,花时间准备下一次面试。
人力资源屏幕
人力资源筛选将包括行为问题,要求你解释简历的某些部分,你为什么想申请这家公司,以及你可能不得不在工作场所处理特定情况的例子。偶尔你可能会被问到一些简单的技术问题,也许是一个 SQL 或者一个基本的计算机科学理论问题。之后,你们将有几分钟时间提出自己的问题。
请记住,与你交谈的人不太可能是技术人员,所以他们可能对组织的角色或技术方面没有深刻的理解。记住这一点,试着把你的问题集中在公司,这个人在那里的经历,以及逻辑问题上,比如面试循环通常是如何进行的。如果你有他们无法回答的具体问题,你可以随时要求招聘人员将你的问题转给能够回答这些问题的人。
记住,面试是双向的,所以在投入更多时间去面试这家公司之前,找出任何危险信号对你最有利。
准备:
- 阅读角色和公司描述。
- 查找谁将是你的面试对象,并试图找到融洽的领域。也许你们都在某个特定的城市工作,或者在类似的非营利组织做志愿者。
- 在打电话之前仔细阅读你的简历。
温馨提示:
- 带着问题准备好。
- 让你的简历清晰可见。
- 找一个安静的地方接受采访。如果不可能,重新安排面试。
- 在通话的前几分钟,专注于建立融洽的关系。如果招聘人员想花几分钟谈论昨晚的篮球比赛,让他们去吧。
- 不要说你现在或过去公司的坏话。即使你工作的地方很糟糕,它也不会让你受益。
技术呼叫
在面试过程的这一阶段,你将有机会接受团队技术成员的面试。诸如此类的调用通常使用诸如 Coderpad 之类的平台进行,它包括一个代码编辑器以及一种运行代码的方式。偶尔你可能会被要求在谷歌文档中写代码。因此,您应该能够轻松地进行编码,而不需要任何语法突出显示或代码补全。就语言而言,Python 和 SQL 通常是您需要编写的两种语言,但是,这可能会因角色和公司而异。
这个阶段的问题复杂程度不一,从用 windows 函数解决的简单 SQL 问题到涉及动态编程的问题。不管有多难,你都应该在开始编码之前问清楚问题。一旦你对问题和期望有了很好的理解,就从一个强力的解决方案开始,这样你至少有东西可以用了。然而,一定要告诉你的面试官,在考虑优化之前,你首先是在用一种非最优的方式解决这个问题。在你做了一些工作之后,开始优化你的解决方案,让你的代码更具可读性。在整个过程中,用语言描述你的方法是有帮助的,因为面试官可能偶尔会帮你指引正确的方向。
如果你在面试结束时有几分钟时间,利用你正在和团队中的一名技术人员交谈这一事实。询问他们编码标准和过程,团队如何处理工作,以及他们的日常工作是什么样子。
准备:
- 如果你面试的数据科学职位是工程组织的一部分,确保阅读破解编码面试和编程面试要素,因为你可能有一个软件工程师进行技术筛选。
- 抽认卡通常是复习在这个阶段可能出现的机器学习理论的最佳方式。你可以自己制作,也可以花 12 美元购买这套。机器学习备忘单也是很好的复习资源。
- 查看 Glassdoor,了解可能出现的问题类型。
- 研究谁将面试你。拥有博士学位的机器学习工程师对你的面试会和数据分析师不一样。
温馨提示:
- 如果你被困住了,寻求帮助是没问题的。
- 和朋友一起练习模拟技术电话,或者使用像interview . io这样的平台。
- 在开始解决问题之前,不要害怕要求一两分钟来思考问题。一旦你开始了,向面试官介绍你的方法是很重要的。
带回家的项目
“带回家”在数据科学面试环节中越来越受欢迎,因为它们往往与你开始工作后将要做的事情联系得更紧密。它们可以出现在技术筛选之前的第一次人力资源筛选之后,也可以作为现场交付内容。公司可能会测试你处理模糊问题的能力(例如,这里有一个数据集,找到一些见解并向业务利益相关者推销),或者专注于更具体的交付成果(例如,这里有一些数据,建立一个分类器)。
如果可能的话,试着问一些澄清性的问题,以确保你知道他们在测试你什么,你的听众是谁。如果你带回家的观众是商业利益相关者,用技术术语填充你的幻灯片不是一个好主意。相反,把重点放在可行的见解和建议上,把技术术语留给附录。
虽然所有带回家的目标可能不同,但共同点是你将从公司接收数据。所以不管他们让你做什么,第一步总是探索性的数据分析。幸运的是有一些自动化的 EDA 解决方案,比如 SpeedML 。这里你主要想做的是调查数据中的异常。通常情况下,公司会综合生成数据,留下特定的复活节彩蛋供您寻找(例如,客户收入的幂律分布)。
一旦你完成了你的任务,试着从朋友或导师那里得到一些反馈。通常,如果你在一个带回家的项目上工作了足够长的时间,你可能会开始只见树木不见森林,所以从一个不了解你的背景的人那里得到反馈总是好的。
准备:
- 练习带回家的挑战,你可以从 datamasked 购买,或者通过查看这个 Github repo 上没有问题的答案。
- 复习可能对你的工作有帮助的库和工具。例如用于快速数据可视化的 SpeedML 或 Tableau。
温馨提示:
- 一些公司故意提供一个带回家的东西,要求你发邮件给他们以获得额外的信息,所以不要害怕联系!
- 一个好的带回家通常可以抵消现场的任何不良表现。理由是,尽管你不知道如何解决特定的面试问题,但你已经展示了解决他们日常可能遇到的问题的能力。因此,如果在做更多的 Leetcode 问题和润色你的现场演示之间做出选择,关注后者是值得的。
- 确保保存您所做的每个现场挑战。您永远不知道在未来的挑战中什么时候可能需要重用一个组件。
- 只要你陈述出来,就可以做出假设。在这种情况下,信息不对称是必然的,做一个假设比不断地用问题轰炸你的招聘人员要好。
现场
现场面试将由一整天的一系列面试组成,包括午餐面试,这通常是评估你的“文化契合度”。
重要的是要记住,任何让你走到这一步的公司都希望看到你成功。他们已经花了大量的金钱和时间面试候选人,将范围缩小到现场候选人,所以对你的能力要有信心!
确保向招聘人员要一份将要面试你的人的名单,这样你就有机会提前做一些调查。如果你面试的是一位主管,你应该集中精力准备更高层次的问题,比如公司战略和文化。另一方面,如果你面试的是一名软件工程师,他们很可能会让你在白板上写下一个编程问题。如前所述,这个人的背景会影响他们会问的问题类型。
准备:
- 尽可能多地阅读关于这家公司的资料。公司网站、、CrunchBase 、维基百科、最近的新闻文章、盲人、玻璃门,都是收集信息的绝佳资源。
- 和一个朋友进行一些模拟面试,这个朋友可以对你可能表现出的任何言语上的抽搐或回答中的漏洞给予反馈。如果你要在现场做一个带回家的演示,这尤其有用。
- 为常见的行为面试问题准备好故事,比如“说说你自己吧”、“为什么选择这家公司?”“告诉我一次你不得不与一个难相处的同事打交道的经历”。
- 如果你有软件工程师在现场,你很有可能需要温习一下你的数据结构和算法。
温馨提示:
- 不要太认真。这些面试官中的大多数宁愿回到他们的办公桌前做他们被分配的项目。所以,尽你所能让你的面试官有一次愉快的经历。
- 确保修整该部分。如果你去东海岸的一家财富 500 强公司面试,你可能需要比去西海岸的一家初创公司面试时穿得保守得多。
- 利用浴室和休息时间来调整自己。
- 问一些你真正感兴趣的问题。你在面试这家公司,就像他们在面试你一样。
- 现场结束后,给你的招聘人员和招聘经理发一封简短的感谢信。
要约和谈判
对于许多人来说,谈判可能看起来不舒服,尤其是对于那些没有行业经验的人。然而,现实是谈判几乎没有坏处(只要你礼貌对待),还有很多好处。
通常情况下,公司会通过电话通知你他们打算给你一份工作。在这一点上,当场承诺并接受提议可能很有诱惑力。相反,你应该表达你对这份工作的兴奋,并要求他们给你一些时间与你的另一半或朋友讨论。你也可以提前告诉他们你还在面试其他几家公司,你会很快回复他们。有时这些提议有截止日期,然而,这些通常是相当随意的,可以由你的一个简单请求来推动。
你的谈判能力最终取决于多种因素,但最大的因素是选择性。如果你手上有两个很好的报价,谈判会容易得多,因为你可以选择离开。当你在谈判时,有各种各样的杠杆可以利用。三个主要的是你的基本工资、股票期权和签约/搬迁奖金。每个公司都有不同的政策,这意味着一些杠杆可能比其他杠杆更容易拉动。一般来说,签约/调动是最容易谈成的,其次是股票期权,然后是底薪。因此,如果你处于弱势,要求更高的签约/搬迁奖金。然而,如果你处于强势地位,增加基本工资可能对你最有利。原因是,它不仅会在你加薪时起到更高的乘数作用,还会对公司福利产生影响,如 401k 匹配和员工股票购买计划。也就是说,每种情况都是不同的,所以一定要根据需要重新安排谈判的优先顺序。
准备:
- 关于谈判的最佳资源之一是 Haseeb Qureshi 写的一篇文章,详细描述了他如何从新兵训练营毕业生到收到来自谷歌、Airbnb 和许多其他公司的邀请。
温馨提示:
- 如果你不擅长即兴演讲,让招聘人员的电话转到语音信箱可能会有好处,这样你可以在给他们回电之前冷静下来。你不太可能会接到拒绝电话,因为这些通常是通过电子邮件完成的。这意味着当你给他们回电话时,你应该在心里预演当他们告诉你他们想给你一个机会时你会说什么。
- 对公司表现出真正的兴奋。招聘人员可以感觉到候选人只是为了钱,他们可能不太可能在谈判过程中帮助你。
- 总是把事情做得很好!即使你没有接受一家公司的邀请,对招聘人员保持礼貌和坦诚也是很重要的。科技行业可能是一个小得惊人的地方,你的声誉很重要。
- 不要拒绝其他公司或停止面试,直到你得到一份真正的工作。口头提议有被收回的历史,所以不要庆祝,直到你有书面的东西。
记住,面试是一种可以学习的技能,就像其他任何事情一样。希望这篇文章能让你对数据科学面试有所了解。
这个过程也不是完美的,有时你会因为不具备一些晦涩的知识而无法给面试官留下深刻印象。然而,通过反复的坚持和充分的准备,你很快就能找到一份数据科学的工作!
掌握 Google Colab 的功能
在本文中,让我们了解更多关于 Google Colab 的信息,并测试它的特性。
Photo by Hrishikesh Mane on Medium
介绍
什么是 Google Colab 及其用法?
Google Colab 是一个数据科学和机器学习的研究工具。这是一个 Jupyter 笔记本电脑环境,不需要设置即可使用。它是迄今为止最顶级的工具之一,尤其是对于数据科学家来说,因为你不需要手动安装大部分的包和库,只需要通过调用它们直接导入即可。而在普通的 IDE 中,你需要安装库。Jupyter notebook 主要用于代码文档,它通常看起来像一篇博客文章。在过去的两个月里,我一直在使用 Google Colab,它对我来说是最好的工具。在这篇博客中,我会给你们一些掌握 Google Colab 的技巧和窍门。敬请关注,阅读所有要点。这些特性甚至是我一开始也很难实现的,现在我掌握了它们。让我们来看看谷歌 Colab 笔记本的最佳功能。
你可以在这里 访问 Google Colab 。去输入你的第一个程序。
特征
1)运行电池:
要“运行单元格”(单元格是您输入要执行的代码或文本的地方),您可以按“ Ctrl+Enter ”或“ Shift+Enter ”。我个人使用“ Shift+Enter ”是因为当你按下“ Shift+Enter ”时,它会运行那个特定的单元格并自动创建一个新的单元格,这是一个方便的功能,可以快速完成工作。
Using “Ctrl+Enter”
Using “Shift+Enter”
2)上传文件
如果你遵循一些随机的在线教程的步骤,这可能是一个非常痛苦的任务。但我有一个简单的解决方案,这是一个一步到位的过程,你不需要写额外的代码,或执行一些额外的任务,而你只需要手动上传到 Colab。这是做这件事的方法。
下图清楚地表明,您必须右键单击单元格左侧看起来像“ > ”的箭头标记。当你点击它时,你会发现一个有三个选项的标签,你只需要选择“文件”。然后,您可以在“上传选项的帮助下轻松上传您的文件。有一件事你要注意,你应该把文件上传到“ Samples 文件夹之外。给你,你的任务完成了。
Click on the Files tab to upload.
这是你上传文件到 colab 时的样子。
After uploading your file to the Colab.
Colab 中的教程
你知道 Google Colab 不仅用于输入代码,还是学习机器学习、熊猫和神经网络概念的好地方吗?确实可以在 Colab 找到一堆可以提升技能的教程。要找到这些教程,只需点击你左手边的 > ,然后点击“目录”->“更多资源”你就可以在那里找到一堆教程。
You can find many tutorials in Colab.
4)在笔记本中上传图片。
有时候你需要上传图片到笔记本上,只是为了把事情说清楚。当您按照在线教程操作时,添加图像有时会很困难。一个简单的方法,我发现,显然你必须使用一个免费的图像托管网站,以便在笔记本上呈现你的图像。要做到这一点,请使用“ TinyPic ”,这是上传图片的最佳网站,它提供了一系列链接供您选择,如 HTML、Url 等。你也可以上传视频到这个网站。
Choose one of the above links that fit your needs.
一旦你将图片上传到 TinyPic,那么你只需要根据你的要求复制链接,然后粘贴到“文本部分。给你,你的任务完成了。
Paste the link in the Text section
5)使用 Tab 完成代码。
这是 Colab 中最好的特性之一,称为“制表符补全”。制表符补全非常有用,尤其是当您不确定函数的方法时。它显示所有列出的方法,然后您可以选择您需要的方法。为此,您只需按下键盘上的“ Tab 键,就可以看到所有等效方法的完整列表。
Press the Tab key to use this option.
6)直接保存到 GitHub
Google Colab 为您提供了一个将项目保存到 GitHub 资源库的选项,这是一个非常方便的选项。这个选项有助于手动上传你的项目到你的 GitHub,而不是自动保存你的项目到你的库。为此,只需点击屏幕上方的“文件”选项卡,然后点击选项“在 GitHub 中保存一份副本”。
Click on the File Tab to upload to your GitHub
7)将您的项目保存为 PDF
这对我来说是一项痛苦的任务,除非我的教授教我如何去做。因为有时为了提高可读性,您可能需要发送笔记本的 PDF 文档。因为这个 IPYNB 文件是不可读的,除非您有一个解析器。因此,为了保存为 PDF 文档,你只需点击“ Ctrl-P ”,然后点击另存为“ PDF ”。给你,你的任务完成了。我知道这是一个简单的过程,但有时如果你不知道如何去做,这些简单的过程可能会令人头疼。
Press Ctrl-P or Print option.
8)导入库而不安装它们。
Google Colab 给了你一个独特的功能,甚至是最好的 IDE 都没有提供,比如"在没有安装的情况下导入库",你不需要在导入库之前手动安装任何库,你所要做的只是告诉例如 import pandas as pd ,然后你的工作就完成了,那些你必须在命令提示符中键入 pip install pandas 的日子已经一去不复返了,这很恶心。这确实是 Google Colab 最好的功能之一。但是有时你可能想要手动安装一些外部库。
以上是使用 Google Colab 的突出特点或提示,Google Colab 中的一切都是可用的,你只需动动脑筋就能实现它们。此外,我希望阅读这篇博客已经让你更好地了解如何像专业人士一样使用 Google Colab。感谢你们花时间阅读我的博客,请关注更多更新。请在下面的评论区告诉我你对这篇文章的看法。如果你对这篇文章有任何疑问,评论区都是你的。祝你有愉快的一天。
数据科学的数学:效用矩阵上的协同过滤
理解推荐引擎协同过滤模型背后的数学原理
我强烈推荐看看我的另一篇文章,作为推荐引擎的介绍:
它们是什么,它们是如何工作的,以及它们为什么伟大。
towardsdatascience.com](/a-primer-to-recommendation-engines-49bd12ed849f)
概述:什么是协同过滤?
协同过滤是一种使用用户和项目数据的推荐引擎。更具体地说,是个人用户对单个商品的评分。这样,基于来自其他用户的评级来推荐项目,因此,协作。这些数据可以用效用矩阵来表示,其中一个轴是用户,另一个轴是项目。协同过滤推荐引擎的目标是填补效用矩阵中的空白,因为不是每个用户都对每个项目进行了评级,然后输出评级最高的、先前未评级的项目作为推荐。
A simple utility matrix, with 4 users (columns) and 4 items (rows).
填充效用矩阵有三种主要技术:用户-用户、项目-项目和 SVD。我们将使用上面的简单效用矩阵逐一分析,尝试并预测用户 1 对项目 3 的评价。
用户对用户
计算效用矩阵的缺失值有两个主要步骤:
- 计算 U1 和所有其他用户之间的相似度
- 通过对其他用户的 I3 评分取平均值**,计算 U1 对 I3 的评分,根据用户与 U1 的相似度对每个用户的评分进行加权**
在这里,我们快速讨论一下相似性度量。常见的有:euclidean distance
(T1 的一种具体形式)cosine similarity``Pearson correlation``Jaccard index
等。从实验上来看,皮尔逊相关性被证明是最好的。对于这篇文章中的例子,我们将使用余弦相似度。
Left: cosine similarity of U1 to all other users; Right: weighted average of ratings for I3
因此,我们对 U1 和 I3 的预测评级是 4.34!另请注意,不同的相似性度量会给出略微不同的结果。
项目对项目
项目-项目协同过滤与用户-用户非常相似,但不是计算用户之间的相似性,而是计算项目之间的相似性。你想要的最终值是 U1 其他评分的平均值,用 I3 和其他项目的相似度加权。
Left: cosine similarity of I3 to all other items; Right: weighted average of ratings for U1
采用这种逐项计算的方法,我们最终得到的预测值为 3.31——与我们之前的预测值 4.34 大相径庭。
需要注意几件事:
- 当计算相似性时,一些来源说将缺失值视为 0,而一些来源在计算相似性时简单地忽略缺失值的整个行/列。
- 一般来说,由于用户的独特品味,逐项方法更有效。
- 在决定是使用用户-用户还是项目-项目时,您可能要考虑算法的复杂性。如果你有 m 个用户和 n 个项目,那么用户-用户的时间复杂度是 O(m ^ n ),项目-项目的时间复杂度是 O(m n)。如果你有更多的用户,你可能会选择条目,反之亦然。
奇异值分解
我们必须从一点点理论开始,来理解这些概念从何而来。奇异值分解(SVD)是矩阵分解的一种形式。矩阵分解是将一个矩阵分解成(通常是三个)矩阵的乘积。如果你还记得代数的话,当我们把二次方程分解成它们的线性部分(即 x + 2x + 1 = (x+1)(x+1) )时,也是类似的思路。
SVD 是由西蒙·芬克在 2007 年 Netflix 奖竞赛中一举成名的型号。如果你学过线性代数课程,奇异值分解通常是利用矩阵的特征值和特征向量将其分解为三个分量矩阵。Python 库中用于解决推荐引擎的算法名为SVD,但它并不完全分解你的效用矩阵。取而代之的是,它在做 SVD 的逆,并试图使用两个分量矩阵而不是三个分量矩阵来重建你的效用矩阵。如下所示,这两个矩阵可以被解释为项目矩阵和用户矩阵。
Decomposing the utility matrix into an item matrix and a user matrix.
潜在特征指的是所有物品或用户特征的某种抽象。只要你有相同数量的物品和用户的潜在特征,你就可以将矩阵相乘,得到一个与你的效用矩阵维数相同的矩阵。潜在特征的数量是一个可以在模型中调整的超参数。基于矩阵乘法,我们还可以看到,U1 对 I3 的评级值受到项目矩阵的 I3 行和用户矩阵的 U1 列的影响。
因为我们不能分解有缺失值的矩阵,所以我们必须采取另一种方法。这就是机器学习的用武之地。如前所述,我们现在将尝试用我们的项目矩阵和用户矩阵重新创建效用矩阵。这是使用梯度下降的方法完成的:交替最小二乘法。
1.初始化
与所有使用梯度下降的模型一样,您必须从一些初始值开始。我们正在初始化两个分量矩阵。在这个例子中,我已经用全 1 初始化了我们的分量矩阵。
In blue: After initializing the component matrices with 1s, the recreated utility matrix is all 2s. In grey: the original utility matrix for comparison.
2.价值函数
在这个模型中,成本函数是允许我们比较我们原始效用矩阵和我们重新创建的效用矩阵中的相应值的任何度量。这意味着,我正在比较我的原始效用矩阵 4 中的 U1-I1 的评级与我重新创建的矩阵2 中的 U1-I1 的评级,并对矩阵中的所有值进行同样的操作。在这里,我使用均方根误差( RMSE:对每个个体的差值求平方,取平均值,然后求平方根)并在计算 RMSE 时将缺失值视为 0。
3.交替最小二乘法梯度下降
这种梯度下降的工作原理是通过一次改变一个分量矩阵中的一个值来尝试最小化成本函数(RMSE)。让我们从寻找项目矩阵中 I1 的第一个潜在特征的最优值开始。
如上图所示,通过改变这个第一个值(现在表示为未知的 x ,我们更新了我们重新创建的效用矩阵的整个第一行。通过矩阵乘法,这整个第一行变成 x + 1。因为矩阵的其余部分是静态的,我们可以通过第一行最小化我们的成本函数。因此,我们只是最小化那个二次方程,以得到 2.5 的最优 x !
Our RMSE goes down!
用 2.5 替换 x ,我们重新创建的效用矩阵的第一行变成了 3.5,我们的 RMSE 从 1.75 下降到 1.58!这个过程一遍又一遍地重复,直到 RMSE 再也好不起来。需要注意的是,改变项目或用户矩阵中的一个值,会改变重新创建的效用矩阵的整个行或列。这维护了用户和项目之间的关系,这个过程被称为并行化。一遍又一遍地做这个过程(我是用 Python 库 Surprise 做的,我将在另一篇文章中介绍),我们最终得到 1.15 的 RMSE,这就是我们重新创建的效用矩阵的样子:
4.估价
基于此,我们可以猜测 U1 对 I3 的评分是 3.7!在一个更稀疏的矩阵中,每个用户有多个未知的评分,然后你会推荐以前最高的未评分项目。有趣的是,与我们的用户-用户(4.34)和项目-项目(3.31)预测相比,我们的 SVD 值 3.7 介于使用两个不同轴的相似性之间。
在实际操作中,如果有更多的数据,你可以对你的已知评分做一个train-test-split
,然后测量 RMSE 在你的测试集中的实际评分值和它们在模型中的预测值。RMSE 将用于评估模型,不要与在执行此交替最小二乘梯度下降时用作成本函数的 RMSE混淆。RMSE 可以解释为你的预测评级与实际评级的平均偏差,即你的预测平均偏离多少颗星。
我喜欢的资源:
- 推荐系统的矩阵分解技术:https://data jobs . com/data-science-repo/Recommender-Systems-[网飞]。pdf
- 给你推荐:Netflix 奖和哈利南与 Striphas 制作的算法文化:https://journals . sage pub . com/doi/pdf/10.1177/1461444814538646
- 莱斯科维克、拉贾拉曼和乌尔曼对大规模数据集的挖掘:http://infolab.stanford.edu/~ullman/mmds/book.pdf(特别是第 9 章对理解奇异值分解非常有帮助)
- 给惊喜的文档,我用于 SVD 的库:https://surprise.readthedocs.io/en/stable/index.html
“数学人”对数据科学和 STEM 是一种威胁
为什么 STEM 似乎不是所有人都能接触到的,为什么它必须是。
关键要点
- 你质疑所见的能力是你成为一个有价值的社区成员的原因。为了追求清晰,我们需要赞美问题。
- 专家和非专家需要能够质疑科学程序和结果,以防止和纠正不良科学。
- 在像数据科学这样的新领域,这两者都是如此,在这个领域,演示和可视化是传达信息的核心。
当我们小的时候,我们总是被问到这个问题“你是一个数学爱好者吗?”这种对儿童的分类意味着一些人会做数学,而另一些人不会,不管付出多少努力、时间或经验。问题是,我们谈论干细胞领域的这种简单而基本的方式会使重要的研究变得不直观,甚至不可想象。
至关重要的是,关于科学过程的失败和透明度的意义与我们谈论 STEM 领域的方式之间存在差异。我想讨论两个案例,它们以各自的方式至关重要,取决于提出问题、要求答案以及对研究过程和科学应用进行批判性思考的重要性。
从这些案例中吸取的经验教训可以应用于各个研究领域,但在考虑新兴的数据科学领域时具有独特的重要性。当我们面临迷恋数据可视化和时髦词汇的风险时,我们必须更加小心,不要停下来质疑这个过程的每一步。我们对待“失败”和误解的方式对于 STEM 教育、数据的道德使用和跨学科工作具有持久的重要性。
案例 1:拉库尔和格林(2014 年)
Figure 1 from LaCour and Green, 2014.
(这项研究已被广泛报道,所以这里是一个简短的概述。)
迈克尔·拉库尔是 2014 年加州大学洛杉矶分校政治科学系的一名有前途的研究生。他与唐纳德·格林合著了一项令人印象深刻的研究,唐纳德·格林目前是哥伦比亚大学伯吉斯政治学教授。这项研究的问题很简单:有没有可能通过一次对话改变选民对一个有争议问题的看法?拉票员被派出去拜访两个选民的家庭,谈论同性婚姻或回收(一个控制)。一些拉票者会谈论他们在同性群体中认识的人。其他游说者会透露他们是同性恋,并希望结婚。结果令人震惊。选民的想法变了。这是不朽的。拉库尔得到了一份普林斯顿大学助理教授的工作。
发表后不久,两名研究生大卫·布鲁克曼和约书亚·卡拉想要复制和扩展拉库尔和格林的工作。但是他们遇到了一些问题。这项研究在经济上怎么可能是可行的?此外,数据太完美了。2015 年 5 月,唐纳德·格林撤回了这篇文章。
Broockman and Kalla, 2016
但故事并不全是苦涩的。布鲁克曼和卡拉找到了一种方法,实际上正确地进行研究,关于变性恐惧症。他们的研究证明更加严谨。他们公布了他们的数据。他们公布了他们的代码。一切都是透明的。
他们于 2016 年在科学杂志上发表了他们的研究。2017 年,他们和 Jasjeet S. Sekhon 一起发表了他们关于改变这类田间实验设计的工作。这些学者坚持不懈地质疑和批判性地思考进行实验的过程,产生了令人难以置信的工作,不仅对学术界,而且对非学术界都有影响。
插曲:论专长
上面的例子说明,有时即使是专家也可能进行糟糕的科学研究。此外,当糟糕的科学发生时,其他专家有时没有抓住——拉库尔和格林的原始研究发表在科学上!当然,科学有严格的同行评议程序,但即使是专家也会漏掉一些东西。但是数字看起来不错。从所提供的一切来看,这看起来像是很好的科学。此外,人们希望拉库尔的结果是真实的。
同一领域的人需要对解释他们的方法、数据和思维过程负责。质疑事物是如何工作的,事物是如何被书写的,这是推动科学前进的唯一途径。我们必须考虑每一项个人工作能为更大的社区提供什么,以及它将如何影响其他研究人员和科学家。
尽管专家之间的对话对所有 STEM 领域的发展都很重要,但这些讨论似乎离那些认为自己不是技术人员或外行的人很远。专家们努力工作来赢得他们的证书和信誉。但是“专家”的标签也可能成为一个非专家真正应该参与的对话的障碍。布鲁克曼和卡拉能够部分建立在先前的研究基础上,是因为他们处于被尊重和倾听的地位。有时候,非专家的声音会产生真正的、持久的影响。这让我们回到了几十年前医疗保健的一个重要时期。
案例 2:行动起来和 1980 年代的艾滋病行动主义
美国医疗行业的各个方面都充满了争议,从医疗保险到医疗事故。临床试验是医学研究的一个关键部分,因此新药和新疗法可以(安全地)提供给病人。
The New York Times, July 22, 1998, page B1
在 20 世纪 80 年代,艾滋病是一个巨大的、致命的公共问题。医疗行业正在争先恐后地寻找治疗方法,同时遵循他们的方案:长时间的小型临床试验。人们不应该同时参加多个试验,这样结果就不会被污染……但是人们正在死去。他们不知道他们是否服用安慰剂或实际药物。
公开的同性恋群体及其盟友动员了他们的社会资本和金融资本,以一种“非专家”以前没有真正做过的方式介入医疗领域。他们去参加医学会议;他们自学成才。最重要的是,他们与医疗专业人员分享了他们的生活经验。虽然现在患者理解医疗过程似乎很正常,但这在当时并不规范。
这些被认为是该领域之外的人,不可逆转地改变了激进主义和医学研究,尤其是在公共危机时期。他们能够利用自己的“非专家”经验——基本数据——来说,医疗专业人员遗漏了一个非常重要的部分。生命比一部分人精心设计的协议更重要。作为非专家,他们看到了问题,并努力成为解决方案的一部分。
数据科学的含义:“你是一个数学人吗?”
专家和非专家之间清晰的交流是科学探索和进步的核心。但是这个问题,“你是一个数学人吗”掩盖了局外人知识在追求理解非常小众的概念中的重要性。我们不都是这么聊着 STEM 长大的吗?“他们是数学界的人。”“我只是不是一个学数学的人。”
有些人似乎对事物有诀窍。然而,即使像西蒙妮·比尔斯这样的明星运动员也必须在健身房里投入大量时间。一名歌手花费数年时间磨练自己的声音。厨师在厨房工作,完善每一种调料,每一种酱料。
那么,为什么我们坚持告诉人们我们所有人都有一个天生的 STEM 门槛呢?
当我们延续“数学人”和“非数学人”之间的这种划分时,我们就阻止了个人认识到科学是建立在失败和误解之上的。我们允许人们迷恋科学,认为看起来不错,但实际上并不好。
如果布鲁克曼和卡拉没有想过如何进一步推动拉库尔和格林的研究,他们可能永远也不会找到一种方法来使实地实验更加高效和有效。如果行动积极分子没有相信并争取成为医学研究对话的一部分,不清楚艾滋病研究需要多长时间才能赶上。
越来越多的公司现在正在雇用数据科学家,专注于花哨的可视化、大数据和机器学习。在这种环境下,问一个问题,尤其是作为一个非技术人员,会让人觉得你在拿自己的名誉冒险。问一个在这个行业工作了很长时间的人一个问题,会让人感到害怕。我看起来无知吗?我看起来落伍了吗?但这是这些问题最重要的时候。我们不能因为别人的模型或数字有一定的可信度,就认为他们是绝对可靠的。
与以往任何时候相比,不知道事物是如何组合在一起的力量更大。失败可能会产生难以置信的成效和影响。这不同于仅仅敲打键盘直到你的代码工作,或者运行每一个可以想象的测试直到它“工作”——因为从概率上来说,至少有一个测试可能成功。
这是关于系统的提问,对社区贡献的严格忠诚,而不是吹捧任何个人的荣誉,并在别人还没有想到的地方寻找答案。当研究一个技术领域时,如果你的非技术朋友有问题,批判性地思考它们,因为他们可能会发现一些你永远不可能发现的东西。对于那些认为自己不是技术人员或外行,并对某些事情有疑问的人。大声点。你可能会对结果感到惊讶。
参考资料和进一步阅读
- 《行动起来:艾滋病的治疗和外行专家意见》(哈里·柯林斯和特雷弗·平奇,2002 年)
- 《数据科学的再现性危机》(扎克·斯科特 2019 年 5 月 17 日)
- “具有调查结果的现场实验设计:选择更高效、更稳健和更道德设计的框架”(大卫·e·布鲁克曼、约书亚·卡拉和贾斯吉特·s·塞孔,2017 年)
- “持久减少变性恐惧症:上门拉票的现场实验”(大卫·布鲁克曼和约书亚·卡拉 2016)
- 《如何要求医学突破:艾滋病斗争的教训》 (NPR 愤怒的另一面,2019 年 2 月 9 日)
- 《走向可复制性:平衡隐私与出版》(扎克·斯科特 2018 年 5 月 31 日)
- “我们发现了社会科学最大的骗局之一。以下是我们学到的东西。”(大卫·布鲁克曼和约书亚·卡拉 2015 年 7 月 22 日)
- “当接触改变思想:一个传递对同性恋平等支持的实验”(迈克尔·拉库尔和唐纳德·p·格林,2014)
如何进入数据科学——数学还是编码
对于那些仍然在决定数学和编码哪个更重要的人来说
如果我知道机器学习算法的整个数学逻辑,但我不能很好地编码,我有机会进入数据科学领域吗?
如果我只是勉强知道那些机器学习算法背后的数学,但我能很好地编码,我有资格成为一名数据科学家吗?
我希望我在大学毕业前努力进入数据科学时知道这个答案。
我的一些背景,我来自一个数学背景,在大学期间没有学很多编程课程。我在大学学的编程语言包括 R,C++,Matlab。
Matlab 不是开源语言,主要用于研究行业。r 没有 Python 那样的大型社区,尤其是在与数据科学相关的库中。C++ (C 族)仍然是编程的根本,所以如果你正在学习编码,我还是会建议你学习 C 族的语言。
我实习的时候,行业里用的大多是 Python。所以,我还是要靠自己去捡 Python。除此之外,我只学了一门和机器学习的数学相关的课程。
我感到不知所措,因为我不仅要学习数学,同时还要提高我的编码技能。因此,在那个时候,我想知道我应该把更多的精力放在编码上还是放在学习数学上。
数学或编码
我将分享我对当前行业中哪个更受欢迎的观点。
让我问你一个问题。如果你是数据科学的技术负责人,你已经有很多博士为你工作,但想进一步扩大你的团队。你心中有两个候选人,一个编码比较好,一个数学概念比较好,你会倾向于哪个候选人?
这个问题没有对错之分,但从我的观察来看,通常情况下,他们会更喜欢那些在编码方面有更好技能的人。
你可能会想,为什么?
原因很简单,因为大部分数据科学方向的项目,将由博士提供,他们应该更有见识。因此,谁能更快地实现多种方法,谁就能成为最后的赢家。
那么,你可能会问,统计是数据科学的基础,你是在告诉我,为了进入数据科学,只需要学习如何很好地编码?🤔
不,数学在数据科学中仍然非常重要。更好地理解数学的人将会是那些能够提出新想法来改进机器学习模型的人。
目前市场上有大量的机器学习模型。因此,了解在什么样的场景中使用什么样的模型肯定会节省你很多时间。除此之外,当先前表现很好的型号,突然性能下降,你将能够找出可能的原因。
但是,如果您只是想进入数据科学领域,您不需要在数学部分深入研究太多细节。数据科学不仅仅是知道如何推导或求解数学方程。更重要的是,知道如何定义和解决商业问题。
例如,你在一家电子商务公司工作。你有一个自动分类列表的任务。或许,你需要做的第一步是定义问题,也许陈述一个时间表和你需要达到的精确度。下一步,您将思考模型可能面临的一些问题,并且需要澄清。
比方说,如果房源名称和图片属于不同的类别,那么房源应该如何分类?应该按图片分类还是按房源名称分类?
在理解了你的团队同意的标准操作程序(SOP)之后,只有你才能开始这个项目。
回到主题,数据科学高度要求的技能之一是派生 GitHub 代码并在数据集上试用的能力。因此,如果你擅长编码,那么无论编程语言是什么,你都能够测试不同的方法。
例如,您正在使用给定的数据集训练 NER(命名实体识别)模型。让我们想象一下,目前还没有用 Python 写的关于 NER 的代码,唯一可用的代码是用 Java 写的,由斯坦福大学提供。因此,拥有不同编程语言的知识绝对是一个优势,这样你就可以节省用 Python 编写整个代码的时间来训练模型。
另一方面,如果你更多地研究机器学习的数学部分,你会对你应该关注的指标更加敏感,这取决于不同的问题。假设您正在处理一个信用欺诈项目。你应该关注的指标不再是准确性,而是 f1 的分数。因为您的目标是不仅能够识别尽可能多的欺诈案例,而且还能保持准确性。
最后的想法
数学和编码在数据科学中同样重要,但如果你正在考虑在数据科学领域转行或开始职业生涯,我会说编码或编程技能比深入研究各种机器学习模型的数学更重要。
开始做更多真实世界的项目,在面试时能够清晰地陈述和回答问题,一定会增加你进入数据科学的机会。
进入数据科学很难,但是记住不要放弃,继续努力。
你所有的努力很快就会有回报,不管有多难,都要坚持下去。
关于作者
Low 魏宏是 Shopee 的数据科学家。他的经验更多地涉及抓取网站,创建数据管道,以及实施机器学习模型来解决业务问题。
他提供爬行服务,可以为你提供你需要的准确和干净的数据。你可以访问 这个网站 查看他的作品集,也可以联系他获取抓取服务。
线性判别分析是如何得名的?
Photo by Franck V. on Unsplash
尽管是宣传最差的机器学习分类工具之一,但线性判别分析(LDA)在各种设置中可以匹配甚至优于逻辑回归。LDA 经常在机器学习中用于降维,但它也可以有效地用于分类。在本文中,我们将深入研究 LDA 的数学基础分类。
在分类中,我们考虑 K 个类{1,2,3,…,K}和一个输入向量 X。我们将 X 分类为属于使 P(Y=i | X)最大化的类 I。
LDA 分类依赖于贝叶斯定理,该定理规定:
这个公式表明,我们可以将 X 属于每个类的概率与输入在每个类中取值的概率联系起来。为了简单起见,我们假设只有一个输入变量,在这种情况下,X 只是一个数字。
我们可以将 P(X|Y)视为一个概率密度函数,如下图所示,其高度告诉我们输入值为 X 的概率,我们有 K 个图,每个类一个。如果图的高度很大,则获得值 X 的概率很高,如果高度很低,则概率很小。
因为我们希望上述公式易于使用,所以我们选择了一个具有良好数学特性的概率密度函数——由以下等式给出的正态分布:
这是 LDA 的一个关键假设。如果输入变量来自近似正态分布,该技术将更好地工作,并且该近似值越小,性能就越差。
将正态分布代入贝叶斯定理,我们得到
为了简单起见,我们还假设只有 2 个类,所以 i=0 或 1,并且这些类对于 x 共享相同的方差。
我们想找到最大化这个值的类。
看到指数会让我们想到对数,因为对数不会改变集合的排列顺序,所以我们继续简化
这些项中的许多项在不同的类中保持不变,因此无助于确定哪个类具有最大的概率。我们可以把它们去掉,只剩下判别函数
我们可以将 X 分类为产生最大判别函数值的那一类。注意,公式在 X 轴上是线性的,这也是 LDA 这个名字的由来。
现在让我们来看一个简单的例子!
将种子设置为 10(这对可再现性很重要),我们使用 R 从均值为 1、方差为 1 的正态分布中随机生成 10000 个点,我们将其指定为组 1(红色)。我们还从均值为+1、方差为 1 的正态分布中随机生成 10000 个点,我们将其指定为第 2 组(蓝色)。我们希望使用 LDA 将一个输入分类为属于这两个组中的一个。从下图中,我们看到 X=0 很好地将两个组分开。
在这种情况下,每组有 10000 个,因此每个组都有均等的机会获得输入。因此 P(Y=0) = P(Y=1) = 0.5。同样,第 1 组的平均值为-1.002,第 2 组的平均值为 0.996。计算我们得到的标准差的估计值
将这些值代入组 1 的判别函数,我们得到
对于第二组,我们得到
我们可以看到,当 X>0.003 时,X 将被分类为属于第 2 组,否则被分类为属于第 2 组。这非常接近理论上存在于两个这样的正态分布之间的 X>0 的真实截止值。
注意我们可以放宽 K=2 的要求,将 X 设为多维向量,导出类似的判别公式。我们只需要计算鉴别函数 K 次,而不是两次。
如果我们放松 Var(X)在 K 个类中是常数的约束,我们会得到一种稍微不同的技术,称为二次判别分析或 QDA。但这是另一篇文章的主题。
感谢您的阅读,并在下面留下您的意见或问题!
梯度下降背后的数学直觉
梯度下降中更新规则的数学推导——机器学习和深度学习中最流行的优化算法
梯度下降是一种寻找函数最小值的迭代优化算法,最常用于机器学习和深度学习。
介绍
如果你在生活中曾见过或听说过“梯度下降”这个术语,你肯定会遇到下面这个等式:
Gradient Descent - parameter update step
和下图:
Cost vs Weight in Gradient Descent
在上式中,L 是损失函数(或成本函数),而 θ 是成本函数所依赖的任何参数。在神经网络(或深度学习)的情况下,这些是权重( W )和偏差( b )。
目标是找到损失函数的全局最小值。这些参数在训练算法的每次迭代期间被更新,直到我们达到损失函数的最小值。
在深度学习(或神经网络)的背景下,我们根据权重和偏差写出上述等式,如下:
weight and bias update in gradient descent
这是梯度下降优化算法中的基本步骤,在训练的每次迭代期间执行。
我们来数学推导一下这个方程(不要慌!你只需要高中基础微积分就可以做到这一点)。这样做之后,无论何时你遇到参数更新步骤,你都会知道它的起源,并且感觉更有力量!
通用学习算法
让我们首先快速回顾一下一般的学习算法:
general learning algorithm
这里的“直到满意”是一个主观条件,可以是许多停止标准中的一个,如达到阈值损失值或重复某个固定次数等。
参数更新步骤
注意,更新步骤包括添加一些变化δw,δb到 w , b 。我们很快就会发现那些确实是损失的负偏导数 w.r.t w , b 分别是**-𝛿l/𝛿w和 - 𝛿L/𝛿 b 其中 L = f( w , b )。
让我们用数学公式来表达这些:
注意,我们还没有引入学习率α。我们先来了解一下学习率的需求。
需要学习率
我们知道 θ 是向量,δθ也是向量。
让我们考虑这两个向量的和:
vector sum of θ and Δθ
很明显,与单个矢量相比,两个矢量的合成和相当大。这是因为我们迈出了一大步δθ。我们需要在这个方向上迈出一小步,这样向量和就很小。这也很重要,因为如果我们对参数 θ 进行如此大的更新(δθ,我们可能会错过损失函数 l 的全局最小值。因此,我们引入学习率来限制我们对参数 θ 进行更新的大小。
vector sum of θ and αΔθ
注意如何借助学习率α < 1, we limit the amount of update we make to θ 。
现在让我们找出δθ的正确值,它将减少损失值。
在我们继续之前,让我介绍一下著名的泰勒级数,我们将用它来求δw,δb,从而得到δθ
泰勒级数及其在梯度下降中的应用
Taylor series
泰勒级数用于找出距离 x 点δx 处的函数值,已知该函数在该点的导数。
让我们用泰勒级数来求δw 的值。
在这种情况下,函数 f 将是损失函数 L,我们对 L 进行级数展开(w+αδw*)。
我们必须找到一个δw的值,使得 L(w+αδw*)<L(w)。
Taylor series for loss function in terms of w
在这一步,我们可以推断,我们需要第二项为负,新的损失小于旧的损失。
但是 Loss L(θ) 是一个多元函数。它不仅是重量 w 的函数,也是偏差 b 的函数。我们将它们表示为一个向量 θ = [ w , b 。
所以我们需要写下泰勒级数的向量形式来求δθ。
vector form of Taylor series for parameter vector θ
这里∇ L(θ) 代表损耗 w.r.t θ的一阶梯度。 梯度无非是函数 w.r.t 对其每个参数的偏导数的向量。
类似地∇将是一个向量的二阶偏导数等等。
实际上,学习率α非常小(0.001,0.00001 等。),所以α,α,…将非常小,它们对损耗 L 的贡献可以忽略不计。因此它们可以从等式中忽略。最后的等式将变成
updated equation for loss
寻找δθ的最佳值
由于我们希望更新后的损耗L(θ+αδθ)小于之前的损耗 L(θ) ,并且由于损耗是一个正的量,上述等式中的第二项必须是负的。
所以我们需要这样的δ值 θ 所以使得第二项的点积为负,即我们需要
condition for new loss to be negative
我们知道这一点
cosine of angle between 2 vectors is their dot product divided by product of their magnitudes
我们还知道 cos β 位于-1 和 1 之间,即-1 ⩽ cos β ⩽ +1。
因此,
现在我们希望点积尽可能的负(这样损耗可以尽可能的低)
但是从上面的不等式可以看出,它能获得的最大负值是-k。
现在,为了使点积为-k,cos β 必须等于-1。
cos β = -1 对应 β = 180
由于这两个矢量方向相反,从矢量的性质我们知道
最终参数更新步骤
现在,如果我们在通用学习算法的参数更新步骤中替换这些值,它变成
updated parameter update step in learning algorithm
现在,我的朋友,这个等式与我们开始推导的完全相似。
每次使用此规则更新参数(w 和 b)时,训练集的损失将会减少,直到不能再减少,即当斜率(或偏导数)变为 0 时。
Result in decrease of loss due to iterative update steps
多重权重和偏差的梯度下降规则(矢量化符号)
我们已经导出了单个权重和偏差的更新规则。
在现实中,深度神经网络具有许多权重和偏差,它们被表示为矩阵(或张量),因此我们的更新规则也应该被修改,以同时更新网络的所有权重和偏差。
注意,大多数深度学习文本使用符号δ而不是∇来表示方程中的梯度。
gradient descent update rule for deep neural network
结尾部分
这一个就到此为止。希望看完这些,你对梯度下降算法有了更直观的认识。
梯度下降的数学直觉
数学推理可以被看作是两种能力的结合,我们可以称之为直觉和独创性
这是给好奇的人的。每个人都知道梯度下降以及如何将其应用于成本函数的公式:
for j=0 to n
但是在本文中,我们将关注上面公式中突出显示的部分,以理解梯度下降背后的直觉:为什么从θ的每个分量中减去这个因子会引导我们最终达到最佳θ?所以,基本理解“梯度下降是如何工作的?”。
指导步骤:
- 渐变矢量
- 梯度向量代表什么?
- 将梯度向量应用于成本函数
1.渐变向量:
假设我们有一个成本函数 J,它依赖于两个独立变量θ0 和θ1。那么 J 的梯度向量:
∇G= < ∂J ∕ ∂θ0 , ∂J / ∂θ1 >
在哪里,
函数的∂J ∕ ∂θ0=导数保持θ1 不变。
∂J ∕ ∂θ1 =函数 j w r tθ1 保持θ0 不变的导数。
我们来分析一下。假设函数 J 相对于θ0 和θ1 的曲线如下所示:
如果碗形三维图形被平行于 zθ0 平面的一个平面以特定的θ1 值切割,它将产生一个二维抛物线,如下所示:
偏导数∂J ∕ ∂θ0 表示特定θ1 的二维抛物线的切线斜率,反之亦然,∂J ∕ ∂θ1.也是如此特定(θ0,θ1)处的梯度向量是以这些斜率作为其分量的向量。
2.梯度向量代表什么?
在我们得到答案之前,我们需要了解等高线图的概念。如果 J 的上图被平行于θ0θ1 平面的平面在特定的 z=z1 水平上切割,它将产生一个二维圆,使得对于圆上的每个点,函数 J 将给出一个常数 z1 值。许多这样的图在不同的 z 水平给出了多维曲线的等高线图。
slicing at z=25
Contour Plot of J(θ0 ,θ1)
在等高线图中,梯度向量垂直于水平面,并始终指向更高的水平面,即指向 j 值更高的水平面。这种行为有其逻辑原因,但这需要另一篇关于多变量微积分概念的文章。
3.将梯度向量应用于成本函数
因为我们需要找到使 J 值最小的θ0 和θ1 的值,所以我们在与梯度向量相反的方向上移动与梯度向量的大小成比例的距离(因为它是到下一个水平表面的垂直距离,所以它是到下一个水平表面的最短距离)。
假设我们在 A 点,坐标θ0=a,θ1=b,水平面 z=4。我们想移动到下一个更低水平的表面,比如 z=3。我们有带方向和大小的梯度向量来引导我们到这个较低水平表面 z=3 处的新的点(θ0’,θ1’)。因此通过简单的向量数学,
θ0’= a+(-∂j∕∂θ0)= a-∂j∕∂θ0
θ1’ = b + (-∂J ∕ ∂θ1) = b - ∂J ∕ ∂θ1
这是我们开始用的梯度下降公式。重复该过程,直到收敛,即,直到我们到达最低水平表面。Alpha 是学习率乘以梯度向量,以减少达到最低级别表面所需的步骤数。
如你所见,最终的汇聚点很大程度上取决于初始点。
我希望你有直觉。当你被一个又一个的公式轰炸时,这似乎有点令人不知所措。但是,每件事背后都有一个数学推导的逻辑。你只需要好奇。
数学编程——数据科学进步的关键习惯
我们展示了如何通过模拟飞镖的随机投掷来近似计算圆周率的值。这是建立数学编程习惯的一小步,而数学编程应该是初露头角的数据科学家必备的一项关键技能。
注意
这个故事也被列为 KDnuggets 平台上点击率最高的故事之一。
介绍
数学编程 的精髓在于你建立了一种习惯,将数学概念编码起来,尤其是那些涉及到一系列计算任务的系统化的概念。
这种编程习惯对于从事分析和数据科学的职业非常有用,因为人们每天都要遇到各种各样的数字模式并理解它们。数学编程的能力有助于快速数字分析的快速原型化,这通常是建立数据模型的第一步。
几个例子
那么,我所说的数学规划是什么意思呢?不是已经在各种 Python 库中内置和优化了一堆数学函数吗,比如 NumPy 和 SciPy ?
是的,但这不应该阻止你从头开始编写各种数值计算任务,并养成数学编程的习惯。
这里有一些随机的例子,
- 通过蒙特卡罗实验计算圆周率——模拟随机向棋盘投掷飞镖
- 构建一个包含所有处理复数的方法的函数或类(Python 已经有了这样一个模块,但是你能模仿它吗?)
- 给定每只股票的方差,通过模拟多种经济情景,计算投资组合的平均回报率
- 模拟并绘制随机行走事件
- 模拟两个球的碰撞,并根据随机的起点和方向计算其轨迹
如您所见,这些示例可以非常有趣,并且接近真实生活场景。因此,这种技术也带来了为离散或随机模拟编写代码的能力。
当你在网上浏览一些数学性质或概念时,你是否有一种冲动,想用你最喜欢的编程语言编写一段简单的代码来快速测试这个概念?
如果是,那么恭喜你!你有数学编程的根深蒂固的习惯,这将带你在追求令人满意的数据科学职业生涯中走得更远。
为什么数学编程是数据科学的关键技能?
数据科学的实践需要与数字和数字分析建立极其友好的关系。然而,这并不意味着要记忆复杂的公式和方程式。
发现数字模式的能力,以及通过编写简单代码快速检验想法的能力,对一名初露头角的数据科学家大有裨益。
这类似于电子工程师亲自操作实验室设备和自动化脚本,运行这些设备来捕捉电信号中的隐藏模式。
或者,想想一位年轻的生物学家,她擅长在载玻片上制作细胞横截面样本,并在显微镜下快速运行自动化测试,以收集数据来测试她的想法。
重点是,虽然整个数据科学企业可能由许多不同的组件组成,如数据争论、文本处理、文件处理、数据库处理、机器学习和统计建模、可视化、演示等。—对想法的快速实验通常只需要扎实的数学编程能力。
很难准确指出发展数学编程技能所需的所有必要元素,但是一些常见的元素是,
- 模块化编程的习惯,
- 对各种随机化技术的清晰认识
- 能够阅读和理解线性代数、微积分和离散数学的基本主题,
- 熟悉基本的描述性和推断性统计,
- 关于离散和连续优化方法(如线性规划)的初步想法
- 基本熟练掌握核心数字库和函数所选择的语言,其中数据科学家想要测试她的想法
您可以参考这篇文章,它讨论了在数据科学的基本动手数学中应该学习什么。
成为更好的数据科学家需要掌握的关键主题
towardsdatascience.com](/essential-math-for-data-science-why-and-how-e88271367fbd)
在本文中,我们将通过讨论一个非常简单的例子来说明数学编程,这个例子使用向棋盘投掷随机飞镖的蒙特卡罗方法来计算圆周率的近似值。
通过投掷(许多)飞镖来计算圆周率
这是一种通过模拟向棋盘投掷飞镖的随机过程来计算圆周率值的有趣方法。它不使用任何复杂的数学分析或公式,而是试图从纯物理(但 随机 )过程的仿真中计算圆周率的近似值。
这种技术属于蒙特卡罗方法的范畴,其基本概念是模拟随机过程,当重复大量次数时,会产生一些感兴趣的数学量的近似值。
想象一个正方形的镖靶。
然后,里面画了一个圆的镖靶接触到它的所有边。
然后,你朝它扔飞镖。随机。这意味着有些落在圈里,有些落在圈外。但是假设没有飞镖落在棋盘之外。
在投掷飞镖游戏结束时,你计算落在圆圈内的飞镖占投掷的飞镖总数的百分比。将这个数字乘以 4。
结果数字应该是圆周率。或者,如果你投了很多飞镖,这是一个很接近的近似值。
有什么想法?
这个想法非常简单。如果你投出大量的飞镖,那么一个飞镖落在圆内的概率正好是圆的面积与方板的面积之比。在基础数学的帮助下,你可以证明这个比例是π/4。所以,要得到圆周率,你只需要把这个数乘以 4。
这里的关键是模拟投掷许多飞镖,以便使(落在圆圈内的飞镖的)分数等于概率,这一断言仅在这一随机事件的大量试验的限度内有效。这来自大数定律或概率的频率主义定义。
Python 代码
在我的 Github repo 中给出了一个 Jupyter 笔记本,展示了 Python 代码。请随意复制或叉。步骤很简单。
首先,创建一个函数来模拟飞镖的随机投掷。
然后,编写一个函数,根据给定的落点坐标,确定一个飞镖是否落在圆内,
最后,写一个函数,模拟大量的飞镖投掷,从累积结果中计算出圆周率的值。
但是规划不能就此停止。我们必须测试近似值有多好,以及它如何随着随机投掷的次数而变化。与任何蒙特卡洛实验一样,我们希望随着实验次数的增加,近似值会变得更好。
这是数据科学和分析的核心。仅仅编写一个打印出预期输出并停止在那里的函数是不够的。必要的编程可能已经完成,但科学实验不会在没有进一步探索和测试假设的情况下就此停止。
我们可以看到大量的随机投掷可以重复几次来计算一个平均值,得到一个更好的近似值。
简单的代码,丰富的思想
这项技术背后的理论和代码看起来非常简单。然而,在这个简单练习的表象背后,隐藏着一些非常有趣的想法。
函数式编程方法:技术的描述可以用一个整体代码块来编码。然而,我们展示了任务应该如何被划分成模拟真实人类行为的简单功能
- 扔飞镖,
- 检查镖的落点坐标并确定它是否落在圆圈内,
- 重复这个过程任意次
为大型程序编写高质量的代码,使用这种 模块化编程 风格是有指导意义的。
突现行为:在这段代码中,没有使用任何涉及圆周率或圆的性质的公式。不知何故,圆周率的值出现在集体行动中,集体行动是向一块木板随机投掷一串飞镖,然后计算一个分数。这是 涌现行为 的一个例子,其中一个数学模式通过它们之间的相互作用从一组大量重复的同类实验中涌现出来。
频率主义者对概率的定义:概率的定义有两大类,两个激烈对立的阵营——频率主义者和贝叶斯主义者。作为一个频率主义者,很容易将概率定义为一个事件的频率(作为随机试验总数的一部分)。在这个编码练习中,我们可以看到这种特殊的概率概念是如何从大量重复的随机试验中产生的。
随机模拟 : 飞镖的核心功能在其核心使用了一个随机生成器。现在,计算机生成的随机数并不是真正的随机,但出于所有实际目的,它可以被假设为一。在这个编程练习中,我们使用了 Python 的random
模块中的统一随机生成器函数。这种随机化方法的使用是随机模拟的核心,它是数据科学实践中使用的一种强有力的方法。
通过重复模拟和可视化来测试断言:通常,在数据科学中,我们会处理随机过程和概率模型,这些都必须基于大量的模拟/实验来测试。因此,当务之急是以渐进的方式思考,并以统计上合理的方式测试数据模型或科学论断的有效性。
摘要(也是对读者的挑战)
我们展示了培养数学规划的习惯意味着什么。本质上,它是从编程的角度来思考,以测试您在头脑中开发的数学属性或数据模式。这个简单的习惯可以帮助未来的数据科学家发展良好的实践。
用简单的几何恒等式、随机模拟的概念和概率的频率主义定义演示了一个例子。
如果你想寻求更多的挑战,
可以通过模拟一个随机行走事件来计算圆周率吗?
如果你想叉这个趣味练习的代码, 请叉这个回购 。
如果您有任何问题或想法要分享,请联系作者在tirthajyoti【AT】Gmail . com。另外,你可以查看作者的 GitHub 资源库中其他有趣的 Python、R 或 MATLAB 代码片段和机器学习资源。如果你像我一样对机器学习/数据科学充满热情,请随时在 LinkedIn 上添加我或在 Twitter 上关注我。
[## Tirthajyoti Sarkar - Sr .首席工程师-半导体、人工智能、机器学习- ON…
佐治亚理工学院理学硕士- MS,分析这一 MS 计划传授理论和实践…
www.linkedin.com](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/)
数据科学数学
你是否被寻找资源来理解数据科学和机器学习背后的数学所淹没?我们掩护你。
动机
学习数据科学或机器学习的理论背景可能是一次令人畏惧的经历,因为它涉及多个数学领域和一长串在线资源。
在这篇文章中,我的目标是建议一些资源来建立必要的数学背景,以便开始并运行数据科学实践/研究工作。这些建议源自我自己在数据科学领域的经验,以及对社区建议的最新资源的跟进。
然而,假设你是机器学习的初学者,并希望在该行业找到一份工作。在这种情况下,我不建议在开始实际工作之前学习所有的数学知识。你可能会感到气馁,因为你一开始就提出了这个理论?)之前的练习(好玩!)。这种自下而上的方法适得其反。
我的建议是反过来做(自顶向下的方法),学习如何编码,使用 PyData 栈(Pandas,sklearn,Keras 等)。),动手构建真实世界的项目,使用库文档和 YouTube/Medium 教程。然后,你会开始看到更大的画面,注意到你缺乏理论背景,去理解那些算法是如何工作的;那一刻,学数学对你来说就有意义多了!
这是神奇的 fast.ai 团队的一篇文章,支持自上而下的学习方法
不幸的是,这是几个关于深度学习的资源开始的地方——要求学习者跟随…
www.fast.ai](https://www.fast.ai/2016/10/08/teaching-philosophy/)
另一个是 Jason Brownlee 在他的金矿“机器学习大师”博客中写的
像数学、物理、甚至计算机科学这样的技术课题都是采用自下而上的方法来教授的。这个…
machinelearningmastery.com](https://machinelearningmastery.com/youre-wrong-machine-learning-not-hard/)
资源
我会把资源分成三个板块(线性代数、微积分、统计&概率);资源列表没有特定的顺序。资源多样化,包括视频教程、书籍、博客和在线课程。
线性代数
线性代数用于机器学习,以理解算法如何在引擎盖下工作。都是关于向量/矩阵/张量运算;不涉及黑魔法!
- 可汗学院线性代数系列(初学者友好)。
- 编码矩阵教程(和书)。
- 3Blue1Brown 线性代数系列 。
- fast.ai 线性代数 for coders 课程,与现代 ML 工作流程高度关联。
- Coursera 第一门课程机器学习专精的数学。
- 《应用线性代数导论——向量、矩阵和最小二乘》一书。
- 麻省理工线性代数课程,综合性很强。
- 斯坦福 CS229 线性代数复习。
结石
在机器学习中利用微积分来制定用于训练算法以达到其目标的函数,即损失/成本/目标函数。
- 可汗学院微积分系列(初学者友好)。
- 3Blue1Brown 牙石系列。
- Coursera 第二门课程机器学习专业化的数学。
- 深度学习论文需要的矩阵演算。
- MIT 单变量微积分。
- 麻省理工学院多元微积分。
- 斯坦福 CS224n 微分学复习。
统计与概率
两者都用于机器学习和数据科学,以分析和理解数据,发现和推断有价值的见解和隐藏的模式。
- 可汗学院统计与概率系列(初学者友好)。
- 看理论:概率统计的直观介绍。
- 介绍来自 Udacity 的描述性统计。
- 来自 Udacity 的推断统计简介。
- 来自 Coursera 的 R 专门化统计。
- 斯坦福 CS229 概率论复习。
额外材料
- 深度学习书第一部分。
- CMU 数学背景为 ML 课程。
- 机器学习用数学书。
所以,这就是我为了公共利益放弃我精心策划的数学书签文件夹!我希望这有助于您扩展您的机器学习知识,并消除您对发现 sklearn/Keras/pandas import 语句背后发生的事情的恐惧。
我们非常欢迎您通过查看所列资源或添加新的显著资源来投稿。
Matplotlib+ Seaborn + Pandas:统计数据可视化的理想融合
探索性数据分析包括两个基本步骤
- 数据分析(数据预处理、清理和处理)。
- 数据可视化(使用不同类型的图来可视化数据中的关系)。
Pandas 是 python 中最常用的数据分析库。python 中有大量用于数据可视化的库,其中 matplotlib 是最常用的。Matplotlib 提供了对情节的完全控制,使情节定制变得容易,但它缺乏对熊猫的支持。Seaborn 是一个构建在 matplotlib 之上的数据可视化库,与 pandas 紧密集成。
这个职位将负责,
- seaborn 有不同类型的地块。
- 熊猫和 seaborn 的整合如何帮助用最少的代码制作复杂的多维情节?
- 如何在 matplotlib 的帮助下定制使用 seaborn 制作的情节?
谁应该阅读这篇文章?
如果你有 matplotlib 和 pandas 的工作知识,并且想探索 seaborn,这是一个很好的起点。如果你刚刚开始学习 python,我建议在对 matplotlib 和 pandas 有了基本的了解之后再回到这里。
1.Matplotlib
尽管许多任务仅使用 seaborn 函数就可以完成,但理解 matplotlib 的基础知识是必不可少的,原因有两个:
- 在幕后,seaborn 使用 matplotlib 绘制情节。
- 一些定制可能需要直接使用 matplotlib。
下面是 matplotlib 基础知识的快速回顾。下图显示了 matplotlib 的解剖图。
要理解的三个主要类是 图形 、 轴 和 轴
数字
它指的是你看到的整个图形。在同一个图中可以有多个子图(轴)。在上面的例子中,我们在一个图中有四个子图(轴)。
轴线
坐标轴指的是图中的实际点。一个图形可以有多个轴,但给定的轴只能是一个图形的一部分。在上面的例子中,我们把四个轴放在一个 图 中
轴
轴是指特定图中的实际轴(x 轴/y 轴)。
本文中的每个例子都假设所需的模块和数据集已经被加载,如下所示
让我们试着用一个例子来理解 图 和 轴 类
plt.subplots()创建单个 人物 实例,(nrowsncols)轴 实例,并返回创建的 人物 和 轴 实例。在上面的例子中,由于我们已经传递了 nrows=1 和 ncols=1 ,所以它只创建了一个 轴 实例。如果 nrows > 1 或 ncols > 1 ,它会创建一个轴网格,并将它们返回到一个( nrows * ncols) 形 numpy 数组中。*
定制轴类最常用的方法有
这里有一个例子,使用上述一些方法进行一些定制
现在我们已经回顾了 matplotlib 的基础知识,让我们继续学习 seaborn
2.海生的
seaborn 中的每个绘图函数要么是一个 图形级 函数,要么是一个 轴级 函数,了解两者的区别是必不可少的。如前所述,一个图形指的是你看到的整个图形,而 Axes 指的是图形中的一个特定的子图。 轴级 函数绘制到单个 matplotlib 轴上,不影响图形的其余部分。另一方面,一个 图形级 函数控制整个图形。一种思考方式是,一个 人物级 函数可以调用不同的 轴级 函数在不同的轴上绘制不同类型的支线剧情
2.1 轴级功能
以下是 seaborn 中所有轴级函数的详尽列表
要使用任何轴级函数,有两点需要理解
- 向轴级函数提供输入数据的不同方式。
- 指定用于绘图的轴。
2.1.1 向轴级功能提供输入数据的不同方式
有三种不同的方法将数据传递给轴级函数
- 列表、数组或系列
将数据传递给轴级函数的最常见方式是使用列表、数组或序列等可迭代对象
**
2.使用熊猫数据帧和列名。
seaborn 受欢迎的主要原因之一是它能够直接处理熊猫数据帧。在这个传递数据的方法中,列名应该传递给 x 和 y 参数,数据帧应该传递给 数据 参数
**
3.仅传递数据帧
在这种传递数据的方法中,只有 Dataframe 被传递给 data 参数。将使用此方法绘制数据集中的每个数值列。该方法只能用于以下轴级功能
这种传递输入数据的方法的一个具体用例是使用上面提到的任何轴级函数比较数据集中多个数值变量的分布
*sns.boxplot(data=iris)*
2.1.2 指定用于绘图的轴
seaborn 中的每个轴级函数都有一个显式的 ax 参数。传递给 ax 参数的轴将被用于绘图。这在控制哪些轴用于绘图方面提供了很大的灵活性。
例如,假设我们想要查看账单总额和小费之间的关系(使用散点图)以及它们在同一张图中不同轴上的分布(使用箱线图)。
每个轴级函数还会返回绘图所在的轴。如果一个 Axes 已经被传递给 ax 自变量,将返回相同的 Axes 对象。然后,返回的 Axes 对象可用于使用不同方法(如 Axes.set_xlabel()、Axes.set_ylabel()等)的进一步定制
如果没有轴传递给 ax 参数,seaborn 将使用当前(活动)轴进行绘图。
在上面的例子中,即使我们没有明确地将 curr_axes(当前活动的轴)传递给 ax 参数,seaborn 仍然使用它来绘图,因为它是当前活动的轴。
id(curr _ Axes)= = id(scatter _ plot _ Axes)返回 True 表示它们是相同的轴。
如果没有轴被传递给 ax 参数,并且没有当前活动的轴对象,seaborn 创建一个新的轴对象进行绘图,然后返回该轴对象
seaborn 中的轴级函数没有任何控制图形大小的直接参数。但是,由于我们可以指定哪些轴用于绘图,通过在 ax 参数中传递轴,我们可以如下控制图形大小
2.2 图形级功能
在探索多维数据集时,数据可视化最常见的用例之一是在不同的数据子集上绘制同一图表的多个实例。seaborn 中的 图级 函数就是为这个用例量身定制的。一个 图形级 函数可以完全控制整个图形,并且每次调用一个图形级函数时,它都会创建一个新的图形,该图形可以包括多个轴,所有这些都以有意义的方式组织起来。seaborn 中三个最通用的图形级函数是 FacetGrid、PairGrid、JointGrid
2.2.1 面网格
考虑以下用例,我们希望在不同的数据子集上可视化总账单和小费之间的关系(通过散点图)。每个数据子集通过以下变量
1 的值的唯一组合进行分类。日(星期四,Fri 星期六,太阳)
2。吸烟者(不管这个人是不是吸烟者)。性别(男性或女性)
这在 matplotlib 中很容易做到,如下所示
上述代码可以分为三个步骤:
- 为每个数据子集创建一个轴(子图)
- 将数据集划分为子集
- 在每个轴上,使用对应于该轴的数据子集
绘制散点图
步骤 1 可以在 seaborn 中使用 FacetGrid()
完成,步骤 2 和步骤 3 可以使用 FacetGrid.map()完成
使用 FacetGrid,我们可以使用 行 、 列 和 色调 参数创建将数据集分割成三维的轴。
一旦我们创建了 FacetGrid,我们可以使用 FacetGrid.map()在所有轴上绘制相同类型的图,方法是将图的类型作为参数传递。我们还需要传递用于绘图的列的名称。
因此,“Matplotlib 提供了很好的支持来制作具有多个轴的图,但是 seaborn 通过将图的结构与数据集的结构直接链接来构建它”。使用 FacetGrid,我们既不必为每个子集显式创建轴,也不必将数据显式划分为子集。这分别由 FacetGrid()和 FacetGrid.map()在内部完成。
我们可以将不同的轴级函数传递给 FacetGrid.map()。
此外,seaborn 提供了三个图形级函数(高级接口),它们在后台使用 FacetGrid()和 FacetGrid.map()。
1。relplot()
2。catplot()
3。lmplot()
上面的每个图级函数都使用 FacetGrid()创建多个轴,并在 种类 参数中取一个轴级函数,然后在内部传递给 FacetGrid.map()。因此,上述三个函数在可以传递给它们中的每一个的轴级函数方面是不同的。
显式使用 FacetGrid 比直接使用 relplot()、catplot()或 lmplot()等高级接口提供了更多的灵活性;例如,使用 FacetGrid(),我们还可以将自定义函数传递给 FacetGrid.map(),但是对于高级接口,您只能使用 种类 参数中内置的轴级函数。如果不需要这种灵活性,可以直接使用高级接口
上述三个图形级函数以及 FacetGrid 都返回 FacetGrid 的一个实例。使用 FacetGrid 实例,我们可以访问各个轴,然后可以使用这些轴来调整绘图(如添加轴标签、标题等)。此外,与控制 matplotlib 图形的大小相比,控制图形级别函数的大小是不同的。我们可以使用 高度 和 纵横比 参数来设置每个面(子情节)的高度和纵横比,而不是设置整体的图形大小。
更多示例请参考 FacetGrid 。
配对网格
PairGrid 用于绘制数据集中变量之间的成对关系。每个子图显示了一对变量之间的关系。考虑以下用例,我们想要可视化每对变量之间的关系(通过散点图)。这可以在 matplotlib 中轻松完成,如下所示
上面的代码可以分为两步
- 为每对变量创建一个轴
- 在每个轴上,使用对应于该变量对的数据
绘制散点图
步骤 1 可以使用 PairGrid()
完成,步骤 2 可以使用 PairGrid.map()完成。
因此,PairGrid()为每对变量创建轴,PairGrid.map()使用对应于该对变量的数据在每个轴上绘制绘图。我们可以将不同的轴级函数传递给 PairGrid.map()
在对角线轴上绘制散点图是没有意义的。可以在对角线轴上绘制一种图形,在非对角线轴上绘制另一种图形。
还可以在上三角轴、对角轴和下三角轴上绘制不同种类的图。
如果您不需要 PairGrid()的所有灵活性,Seaborn 还提供了一个高级接口 pairplot()来绘制变量的成对关系。它在后台使用 PairGrid()和 PairGrid.map()。
*sns.pairplot(data=iris)*
PairGrid()和 PairPlot()都返回 PairGrid()的一个实例。使用 PairGrid()实例,我们可以访问各个轴,然后可以使用这些轴来调整绘图,如添加轴标签、标题等
更多示例请参考对网格
接缝网格
当我们想要在同一个图中绘制双变量分布和边际分布时,使用 JointGrid。两个变量的联合分布可以使用 散点图//regplot 或 kdeplot 可视化。变量的边际分布可以通过 直方图 和/或 kde 图可视化。 用于关节分布的轴级函数必须传递给 JointGrid.plot_joint()。用于边际分布的轴级函数必须传递给 JointGrid.plot_marginals()
如果你不需要 JointGrid()的所有灵活性,seaborn 还提供了一个高级接口 jointplot() 来绘制双变量分布和边际分布。它在后台使用 JointGrid()和 JointGrid.plot_joint()。
JointGrid()和 jointplot()都返回 JointGrid()的一个实例。使用 JointGrid()实例,我们可以访问单个轴,然后可以使用这些轴来调整绘图,如添加标签、标题等
更多例子请参考接合栅格
摘要
将 seaborn 与 pandas 整合在一起,有助于用最少的代码制作复杂的多维情节。seaborn 中的每个绘图函数要么是一个 轴级 函数,要么是一个 图形级 函数。 一个轴级 函数绘制到单个 matplotlib 轴上,不影响图形的其余部分。另一方面, 图形级 功能控制整个图形。她的是轴级和图形级函数的快速总结
轴级别
数字级
欢迎提供使本文更好的建议/技巧。感谢阅读!!!
Matplotlib 教程:学习 Python 强大的绘图库的基础知识
什么是 Matplotlib
为了进行必要的统计推断,有必要可视化您的数据,Matplotlib 是 Python 用户的一个解决方案。对于那些使用 Python 和 NumPy 的人来说,这是一个非常强大的绘图库。Matplotib 最常用的模块是 Pyplot,它提供了一个类似 MATLAB 的接口,但它使用 Python,并且是开源的。
安装 Matplotlib
要在本地计算机上安装 Matplotlib,请打开 Python 命令提示符并输入以下命令:
python -m pip install -U pip
python -m pip install -U matplotlib
我假设你希望涉足数据科学和机器学习的世界,因此我建议你从这里下载 anaconda 包发行版。它安装了 python,Jupyter notebook 和其他重要的 python 库,包括 Matplotlib,Numpy,Pandas,scikit-learn。Anaconda 支持 Windows、MacOS 和 Linux。要快速开始使用 Matplotlib 而无需在本地机器上安装任何东西,请查看 Google Colab 。它免费提供与你的 Google Drive 账户相关联的云端 Jupyter 笔记本,并且预装了所有重要的软件包。您也可以在 GPU 上运行您的代码,这有助于加快计算速度,尽管我们在本教程中不需要 GPU 计算。要快速开始使用 Google Colab,请查看这篇令人惊叹的文章。
一般概念
Matplotlib 图形可以分为以下几个部分:
图形:是一个完整的图形,可以包含一个或多个轴(图)。你可以把图形想象成一块包含情节的画布。
轴:就是我们一般认为的剧情。一个图形可以包含多个轴。它包含两个或三个轴对象(在 3D 的情况下)。每个轴都有一个标题、一个 x 标签和一个 y 标签。
****轴:它们是像数字线一样的物体,负责生成图形界限。
****艺术家:图上能看到的一切都是艺术家,比如Text
物体、Line2D
物体、collection
物体。大多数艺术家都被绑在斧头上。
Pyplot 入门
Pyplot 是 Matplotlib 的一个模块,它提供了简单的功能来添加绘图元素,如线条、图像、文本等。当前图形中的当前轴。
制作一个简单的情节
import matplotlib.pyplot as plt
import numpy as np
这里我们导入 Matplotlib 的 Pyplot 模块和 Numpy 库,因为我们将要处理的大部分数据都是以数组的形式出现的。
我们将两个数组作为输入参数传递给 Pyplot 的plot()
方法,并使用show()
方法调用所需的绘图。请注意,第一个数组出现在图的 x 轴上,第二个数组出现在 y 轴上。现在我们的第一个图已经准备好了,让我们添加标题,并分别使用方法title()
、xlabel()
和ylabel()
命名 x 轴和 y 轴。
我们还可以使用方法figure()
指定图形的大小,并将值作为行和列长度的元组传递给参数figsize
对于每个 X 和 Y 参数,您还可以以字符串的形式传递可选的第三个参数,该参数指示绘图的颜色和线型。默认格式是 b- ,表示蓝色实线。在下图中,我们使用 go 表示绿色圆圈。同样,我们可以进行许多这样的组合来格式化我们的情节。
我们也可以通过在plot()
方法中传递 X 和 Y 轴的多组参数来绘制多组数据,如图所示。
一个图形中的多个图:
我们可以使用subplot()
方法在一个图形中添加多个图。在下图中,我们使用这种方法来分离两个图形,这两个图形在前面的例子中绘制在相同的轴上。subplot()
方法有三个参数:它们是nrows
、ncols
和index
。它们表示行数、列数和子图的索引号。例如,在我们的例子中,我们想要在一个图中创建两个子图,这样它就在一行两列中出现,因此我们在subplot()
方法中传递参数(1,2,1)
和(1,2,2)
。请注意,我们已经为两个支线剧情分别使用了title()
方法。我们用suptitle()
的方法给图做一个集中的标题。
如果我们希望我们的子图在两行和一列中,我们可以传递参数(2,1,1)
和(2,1,2)
当我们想要很多支线剧情的时候,上面的制作支线剧情的方法就变得有点乏味了。更方便的方法是使用subpltots()
方法。注意两种方法中的的不同。该方法采用两个参数nrows
和ncols
分别作为行数和列数。该方法创建了两个对象:figure
和axes
,我们将它们存储在变量 fig 和 ax 中,这两个变量分别用于更改图形和轴级别的属性。请注意,这些变量名是任意选择的。
用 Pyplot 创建不同类型的图形
1)条形图
条形图是最常见的图形类型之一,用于显示与分类变量相关的数据。Pyplot 提供了一个方法bar()
来制作带参数的条形图:分类变量、它们的值和颜色(如果你想指定的话)。
为了使用方法barh()
制作水平条形图,我们还可以传递一个参数(及其值)xerr
或yerr
(在上述垂直条形图的情况下)来描述数据中的差异,如下所示:
为了创建水平堆叠的条形图,我们使用了两次bar()
方法,并在提到条形图的索引和宽度时传递参数,以便将它们水平堆叠在一起。另外,请注意使用了另外两种方法legend()
来显示图表的图例,以及xticks()
来根据条形的位置标记 x 轴。
类似地,为了将条形图垂直堆叠在一起,我们可以使用参数bottom
并在下面提到我们想要堆叠的条形图作为它的值。
2)饼图
另一种基本类型的图表是饼图,可以使用方法pie()
制作。我们也可以传入参数来定制饼图,以显示阴影、分解一部分、倾斜一个角度,如下所示:
3)直方图
当我们在查看像身高和体重、股票价格、顾客等待时间等本质上连续的数据时,直方图是一种非常常见的图表类型。直方图的数据在其频率范围内绘制。直方图是概率和统计中非常常见的图形,是各种分布(如正态分布、t 分布等)的基础。在下面的例子中,我们生成了一个包含 1000 个条目的随机连续数据,并将其划分为 10 个相等的层,根据其频率进行绘制。我们使用了 NumPy 的random.randn()
方法,该方法生成的数据具有标准正态分布的特性,即均值= 0,标准差= 1,因此直方图看起来像正态分布曲线。
4)散点图和三维绘图
散点图是广泛使用的图形,尤其是在可视化回归问题时非常方便。在下面的例子中,我们输入任意创建的身高和体重数据,并将它们绘制成图表。我们使用xlim()
和ylim()
方法分别设置 X 轴和 Y 轴的极限。
上面的散射也可以三维可视化。为了使用该功能,我们首先导入模块mplot3d
,如下所示:
from mpl_toolkits import mplot3d
一旦模块被导入,通过将关键字projection='3d'
传递给 Pyplot 模块的axes()
方法就创建了一个三维轴。一旦创建了对象实例,我们就将我们的参数高度和重量传递给scatter3D()
方法。
我们还可以创建其他类型的三维图形,如线图、曲面图、线框图、等高线图等。上面的例子以简单的线图的形式如下:这里我们使用方法plot3D()
而不是scatter3D()
摘要
希望这篇文章对你有用。如果你喜欢这篇文章,请表达你的赞赏。在我们结束这篇文章之前,这里列出了所有出现的方法。
- plot(x 轴值,y 轴值)-绘制一个简单的折线图,其中 x 轴值对应 y 轴值
- show()-显示图形
- title(" string ")-按照字符串的指定设置绘图的标题
- xlabel(" string ")-按照字符串的指定设置 x 轴的标签
- y label(" string ")-按照字符串的指定设置 y 轴的标签
- figure()-用于控制一个图形的级别属性
- subplot(nrows,ncols,index)-向当前图形添加一个 subplot
- sup title(" string ")-它为字符串指定的图形添加一个公共标题
- 支线剧情(nrows,ncols,figsize)——一个在单一调用中创建支线剧情的便捷方式。它返回一个图形和轴数的元组。
- set _ title(" string ")-一种轴级方法,用于设置图形中支线剧情的标题
- 条形图(分类变量、值、颜色)-用于创建垂直条形图
- barh(分类变量、值、颜色)-用于创建水平条形图
- 图例(loc)-用于制作图表的图例
- xticks(索引,分类变量)—获取或设置 x 轴的当前刻度位置和标签
- 饼图(数值,分类变量)-用于创建饼图
- hist(值,箱数)-用于创建直方图
- xlim(起始值,结束值)-用于设置 x 轴值的限制
- ylim(起始值,结束值)-用于设置 y 轴值的限制
- 散点图(x 轴值,y 轴值)-绘制 x 轴值与 y 轴值的散点图
- 轴()-将轴添加到当前图形中
- set _ xlabel(" string ")-用于设置指定为字符串的绘图的 x 标签的轴级别方法
- set _ y label(" string ")-用于设置指定为字符串的绘图的 y 标签的轴级别方法
- 散点图 3D(x 轴值,y 轴值)-绘制三维散点图,其中 x 轴值与 y 轴值相对应
- plot3D(x 轴值,y 轴值)-用 x 轴值与 y 轴值绘制三维折线图
在 Excel 中做矩阵乘法的三种方法— fastai 第二部分,第八课
fastai“从基础开始”的第二部分终于出来了。我不记得上一次对 MOOC 这么兴奋是什么时候了。课程一对外发布,我就开始深入挖掘,加深对深度学习和底层概念的理解。
这次我决定听从杰里米和雷切尔的建议,写博客。这篇特别的文章解释了杰里米在第八课中实现的各种矩阵乘法方法。我将使用微软 Excel 进行说明。
所以让我们开始吧!
矩阵乘法
了解 Jeremy 提到的矩阵乘法的一个很好的互动场所是:
从图中可以看出,我们对第二个矩阵进行转置,将元素相乘并相加,得到结果。例如,结果矩阵中的第一项15
来自1*2 + 6*2 + 1*1 = 2 + 12 + 1 = 15
。
虽然这种解释在视觉上令人愉悦,但以我的拙见,很难将其转换为代码。所以还是用 Excel,换一种方式理解矩阵乘法吧!
EXCEL 中的矩阵乘法
考虑大小为4x3
和3x4
的两个矩阵 A 和 B 。
注意:在本文中,我将使用粗体符号 A 和 B 来指代矩阵。使用粗体符号引用向量和矩阵是常见的做法。
Matrices A and B
从我们之前看到的图像中,如果你还记得的话,我们对 B 进行了转置,并将 A 的行与 B 的列相乘,得到了结果矩阵。相反,这次让我们跳过转置这一步,直接将行和列相乘。
因此, A 的第 0 行与 B 的第 0 列逐元素相乘,得到的逐元素乘积相加得到结果矩阵 C 中位置[0][0]
处的第一项。
下面是它在 Excel 中的样子:
C[0][0] = 11 + 105 + 100*9 = 1 + 50 + 900 = 951
类似地,我们通过将 A 的第 0 行和b的第 3 列逐元素相乘得到C[0][3]
。在 excel 中,它看起来像:
C[0][3] = 14 + 108 + 100*12 = 4 + 80 + 1200 = 1284
最后我们按照同样的过程遍历 C 中的每个空盒子,得到最终结果。
C[3][3] = 44 + 408 + 400*12 = 16 + 320 + 4800 = 5136
我们走吧!我们就是这么做矩阵乘法的!那很容易,不是吗?我们现在不仅理解了矩阵乘法,而且还在 Excel 中实现了它!多酷啊。
我个人认为现在你已经准备好处理一些与矩阵乘法相关的规则了(或者简而言之 MatMul ):
- 设
ar,ac
为 A. 中的行数和列数,同样,设br, bc
为 B. 中的行数和列数,那么为了执行矩阵乘法,需要ac == br
。为什么?嗯,正如你在 excel 中看到的,我们将行和列元素相乘,然后将中间乘积相加,得到最终结果。如果维数不匹配,并且一个向量比另一个向量长,我们就不能再进行元素乘法了! - 生成的矩阵的维数将总是
ar,bc
。即行数来自 A ,列数来自 B.
方法 1:使用 3 进行循环
这里有另一个免责声明,在 Excel 中实现矩阵乘法时,我们不仅理解了它,而且还复制了 Jeremy 的第一个使用 3 进行循环的方法。下面是它在代码中的样子:
def matmul1(a,b):
ar,ac = a.shape
br,bc = b.shape
assert ac==br
c = torch.zeros(ar, bc)
for i in range(ar):
for j in range(bc):
for k in range(ac): #or br
c[i,j] += a[i,k]*b[k,j]
return c
希望你现在能更好地理解它。如果没有,这将是一个很好的时机,可以停下来试验一下代码,看看到底发生了什么。我保证,和我们 Excel 版本一样!
好吧,我假设你花了一些时间思考代码,那么,让我们来讨论一下吧!
- 为什么前两个循环在
range(ar)
和range(bc)
?嗯,正如你在规则 2 中所记得的,我们得到的矩阵将会有维度ar,bc
。从 Excel 中我们看到,我们逐个遍历了 C 的每个元素,因此,要遍历ar
行和bc
列,我们需要 2 个用于range(ar)
和range(bc)
中的循环。 - 那么,为什么第三个 FOR 循环在
range(ac) #or br
里呢?从规则-1 中,我们知道ac==br
,所以我们是否将range(ac)
或range(br)
放在第三个循环中并不重要。本质上,这是单个元素相乘并相加的地方。根据我们之前的 Excel 示例,对于C[0][0]
,这是步骤C[0][0] = 1*1 + 10*5 + 100*9 = 1 + 50 + 900 = 951
发生的地方,最后我们将继续下一个框。相乘并相加的项数等于ac or br
。
真的是这样!这是给你的方法 1!这里有一首记住矩阵乘法的歌。(这个我最早是从 fast.ai 上了解到的,原作者不详)
希望现在你已经明白两个矩阵是如何相乘的了。如果没有,这里的是可汗学院的另一个教程。
方法 2:使用逐元素乘法
所以到目前为止,我们一直在解析结果矩阵 **C 中的每个位置,**寻找单个元素的乘积,然后将它们求和。如果你记得的话,类似于,C[0][0] = 1*1 + 10*5 + 100*9 = 1 + 50 + 900 = 951
。当然,肯定有别的办法吧?如果我们不做单个乘积,然后求和,而是一次将向量相乘,得到一个结果向量,然后将结果向量求和,得到最终元素,会怎么样?
m = tensor([1, 2, 3])
n = tensor([10, 10, 10])
m*n>>tensor([10, 20, 30])
到目前为止,我们一直在寻找单个产品10, 20, 30
并将它们组合在一起10 + 20 + 30 = 60
。但是,真的,所有这些都可以替换为:
m = tensor([1, 2, 3])
n = tensor([10, 10, 10])
(m*n).sum()>>tensor(60)
如果您还记得的话,在range(ac) #or br
中最里面的循环是找到单个产品并添加它们。好吧,我们可以替换这个循环来执行向量元素方式的乘积,并在最后放一个.sum()
,PyTorch/NumPy 有能力为我们执行元素方式的运算!
下面是它在 excel 中的样子:
C[0][0] = sum(A[row 0] * B[col 0])
类似地,我们通过将 A 的第 0 行的向量与 B 的第 3 列的向量相乘,并将结果向量相加,得到C[0][3]
。
C[0][3] = sum(A[row 0] * B[col 3])
最后我们按照同样的过程遍历 C 中的每个空盒子,得到最终结果。
C[3][3] = sum(A[row 3] * B[col 3])
注意这和方法-1 有什么不同吗?这一次,我们只是说,要想出类拔萃或 PyTorch,请将 A 的第 0 行与 B 的第 0 列相乘,并对结果向量求和,得到答案。而不是做1*1 + 10*5 + 100*9
。例如:对于C[0][0]
,该方法将 A tensor([1,10,100])
第 0 行的矢量与 B tensor{[1,5,9])
第 0 列的矢量相乘,得到中间积矢量tensor([1,50,900])
,并求和得到C[0][0]
位置的结果为tensor(951)
。
在代码中,它看起来像:
def matmul2(a,b):
ar,ac = a.shape
br,bc = b.shape
assert ac==br
c = torch.zeros(ar,bc)
for i in range(ar):
for j in range(bc):
c[i,j] = (a[i,:]*b[:,j]).sum()
return c
因此,我们只需使用两个 FOR 循环来解析 **C、**的每个位置,并在该位置输入相应的结果。如果i,j
代表 C 中的行和列位置,这看起来像…
i:0,j:0
a:tensor([ 1, 10, 100]),b:tensor([1, 5, 9])
tensor([[951., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
---
i:0,j:1
a:tensor([ 1, 10, 100]),b:tensor([ 2, 6, 10])
tensor([[ 951., 1062., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
---
i:0,j:2
a:tensor([ 1, 10, 100]),b:tensor([ 3, 7, 11])
tensor([[ 951., 1062., 1173., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
---
i:0,j:3
a:tensor([ 1, 10, 100]),b:tensor([ 4, 8, 12])
tensor([[ 951., 1062., 1173., 1284.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
---
i:1,j:0
a:tensor([ 2, 20, 200]),b:tensor([1, 5, 9])
tensor([[ 951., 1062., 1173., 1284.],
[1902., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
等等…直到我们得到完整的矩阵 C 。
tensor([[ 951., 1062., 1173., 1284.],
[1902., 2124., 2346., 2568.],
[2853., 3186., 3519., 3852.],
[3804., 4248., 4692., 5136.]])
方法-3:广播
注意到一个共同的主题了吗?每次都要将每一行 A 与每一列 B 相乘,得到 C 。你注意到重复了吗?我们正在将 A bc
中同一行的向量乘以!我们重复这个过程ar
次!
有没有办法将 A 的行向量与 B 的所有列相乘,得到 **C 中的相应行?**是的,有!进入广播……
注意:我不会解释广播,杰里米在这里做得很好。
相反,让我们看看这段神奇的代码
for i in range(ar):
c[i] = (a[i,:].unsqueeze(-1).expand_as(b)*b).sum(dim=0)
像往常一样,让我们在 Excel 中复制!这会让事情变得非常简单。让我们分步骤做吧。
步骤-1) 选择第一行的 A a[i,:]
。我们选择第 0 行作为示例。
Select row 0 of A
步骤-2) 取其转置 a[i,:].unsqueeze(-1)
Take transpose of row 0 of A
步骤-3) 将柱矩阵展开为 B a[i,:].unsqueeze(-1).expand_as(b)
Expand column matrix as B
步骤-4) 元素乘以 B a[i,:].unsqueeze(-1).expand_as(b)*b
Element wise multiply with B
步骤-5) 沿行求和,得到 C 的第 0 行
Sum along side row dimension to get row 0 of C
每排一个的完整广播过程看起来像这样:
Broadcasting as a whole
我希望现在你能收到的广播!那么,让我们看看它在代码中是什么样子的…
def matmul3(a,b):
ar,ac = a.shape
br,bc = b.shape
assert ac==br
c = torch.zeros(ar,bc)
for i in range(ar):
c[i] = (a[i,:].unsqueeze(-1).expand_as(b)*b).sum(dim=0)
print(f"i:{i}")
print(c)
return c
输出如下所示:
i:0
tensor([[ 951., 1062., 1173., 1284.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
i:1
tensor([[ 951., 1062., 1173., 1284.],
[1902., 2124., 2346., 2568.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]])
i:2
tensor([[ 951., 1062., 1173., 1284.],
[1902., 2124., 2346., 2568.],
[2853., 3186., 3519., 3852.],
[ 0., 0., 0., 0.]])
i:3
tensor([[ 951., 1062., 1173., 1284.],
[1902., 2124., 2346., 2568.],
[2853., 3186., 3519., 3852.],
[3804., 4248., 4692., 5136.]])
这正是我们所期望的,并且与我们的 Excel 版本相同!
仅此而已!我们已经成功地介绍了包括广播在内的三种矩阵乘法方法。
Google sheet 上图可以在 这里找到 。感谢阅读!如果您有任何问题,请随时拨打https://linkedin.com/in/aroraaman/联系我。