使用 Ubuntu 18.04 设置深度学习工作站的权威指南
DL 钻机
CUDA,CuDNN,Python,Pytorch,Tensorflow,RAPIDS
Lambda 和其他供应商提供预建的深度学习工作站,配备新的安培 RTX 3090、3080 和 3070 GPU——但如果你有兴趣构建自己的工作站,请继续阅读。
创建自己的工作站至少是我的一个梦想。我知道这个过程,但不知何故,我从来没有去过。
但这次我不得不这么做。因此,我找了一些空闲时间,在 NVIDIA 的帮助下创建了一个深度学习平台,他们非常有帮助。在这方面,特别感谢乔希·帕特森和迈克尔·库帕。
现在,每当我从安装角度创建整个深度学习设置时,我都会面临类似的挑战。这就像是带着各种各样的依赖和错误在兜圈子。这一次,我也不得不在整个配置没有错误的情况下尝试很多东西。
所以这一次,在我自己的系统中安装所有需求和它们的依赖关系时,我特意记录了所有的东西。
这篇帖子是关于设置你自己的 Linux Ubuntu 18.04 系统,用于深度学习,拥有你可能需要的一切。
如果首选预建的深度学习系统,我可以推荐工作站和服务器的 Exxact 的 line 。
我假设你已经安装了新的 Ubuntu 18.04。我从 2017 年的斯拉夫·伊万诺夫的精彩帖子中获得了关于创建深度学习盒子的灵感。从设置的角度来看,你可以将它称为同一篇文章的 2020 版本,但从那时起许多事情都发生了变化,并且有许多关于 Tensorflow 和 Pytorch 不支持的特定 CUDA 版本的警告。
启动
由 Serghei Trofimov 在 Unsplash 上拍摄
在对我们的安装做任何事情之前,我们需要将我们的 Linux 系统更新到最新的包。我们可以简单地通过使用:
sudo apt-get update
sudo apt-get --assume-yes upgrade
sudo apt-get --assume-yes install tmux build-essential gcc g++ make binutils
sudo apt-get --assume-yes install software-properties-common
sudo apt-get --assume-yes install git
该过程
现在我们已经做好了一切准备,我们要安装以下四样东西:
- GPU 驱动程序:为什么你的电脑不支持高图形分辨率?或者你的显卡如何与你的 python 接口对话?
- CUDA :提供访问 GPU 指令集和并行计算单元的层。简单地说,它允许我们为 GPU 编写代码
- CuDNN :为深度学习网络提供原语的库
- Pytorch、Tensorflow 和 Rapids :编码深度神经网络的高级 API
1.GPU 驱动程序
第一步是添加最新的 NVIDIA 驱动程序。18.04 版本可以选择 GPU 产品类型,Linux 64 bit,下载类型为“Linux 长寿命”。
点击搜索将带您进入下载页面:
您可以从这里下载驱动程序文件NVIDIA-Linux-x86_64–440.44.run
并使用以下命令运行它:
chmod +x NVIDIA-Linux-x86_64–440.44.run
sudo sh NVIDIA-Linux-x86_64–440.44.run
对于您来说,该文件可能会有不同的名称,这取决于最新的版本。
2.库达
我们现在需要安装 CUDA 工具包。不知何故,Pytorch 和 Tensorflow 仍然不支持 CUDA toolkit 10.2,所以我们将使用两者都支持的 CUDA Toolkit 10.1。
此外,CUDA 10.1 产品页面上的命令对我不起作用,我最终使用的命令是:
sudo apt-key adv --fetch-keys [http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub](http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub) && echo "deb [https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64](https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64) /" | sudo tee /etc/apt/sources.list.d/cuda.listsudo apt-get update && sudo apt-get -o Dpkg::Options::="--force-overwrite" install cuda-10-1 cuda-drivers
下一步是创建 LD_LIBRARY_PATH,并将安装 CUDA 的路径附加到 PATH 变量中。只需在您的终端上运行以下命令。
echo 'export PATH=/usr/local/cuda-10.1/bin${PATH:+:${PATH}}' >> ~/.bashrc && echo 'export LD_LIBRARY_PATH=/usr/local/cuda-10.1/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}' >> ~/.bashrc && source ~/.bashrc && sudo ldconfig
之后,可以使用以下命令检查 CUDA 是否安装正确:
nvcc --version
如你所见,CUDA 版本是我们想要的 10.1。另外,检查您是否可以使用该命令:
nvidia-smi
对我来说,当我第一次使用它时,它显示了一个错误,但是一个简单的重启就解决了这个问题。我的两个 NVIDIA 显卡都光彩照人。不用担心显示屏上说支持的 CUDA 版本是 10.2。我也被弄糊涂了,但这只是nvidia-smi
中显示的图形驱动程序支持的最高 CUDA 版本。
3.CuDNN
如果我们不打算训练神经网络,那么所有这些库有什么用?CuDNN 提供了深度学习的各种原语,后来被 PyTorch/TensorFlow 使用。
但是我们首先需要得到一个开发者帐号来安装 CuDNN。一旦你填写了注册表格,你会看到下面的屏幕。选择适合您的 CUDA 版本的 cuDNN 版本。对我来说,CUDA 版本是 10.1,所以我选择第二个。
选择合适的 CuDNN 版本后,屏幕会展开:
对于我的用例,我需要为 Ubuntu 18.04 下载三个文件:
[cuDNN Runtime Library for Ubuntu18.04 (Deb)](https://developer.nvidia.com/compute/machine-learning/cudnn/secure/7.6.5.32/Production/10.1_20191031/Ubuntu18_04-x64/libcudnn7_7.6.5.32-1%2Bcuda10.1_amd64.deb)[cuDNN Developer Library for Ubuntu18.04 (Deb)](https://developer.nvidia.com/compute/machine-learning/cudnn/secure/7.6.5.32/Production/10.1_20191031/Ubuntu18_04-x64/libcudnn7-dev_7.6.5.32-1%2Bcuda10.1_amd64.deb)[cuDNN Code Samples and User Guide for Ubuntu18.04 (Deb)](https://developer.nvidia.com/compute/machine-learning/cudnn/secure/7.6.5.32/Production/10.1_20191031/Ubuntu18_04-x64/libcudnn7-doc_7.6.5.32-1%2Bcuda10.1_amd64.deb)
下载这些文件后,您可以使用这些命令进行安装。如果未来发生任何变化,您还可以看到确切的命令:
# Install the runtime library:
sudo dpkg -i libcudnn7_7.6.5.32-1+cuda10.1_amd64.deb#Install the developer library:
sudo dpkg -i libcudnn7-dev_7.6.5.32-1+cuda10.1_amd64.deb#Install the code samples and cuDNN User Guide(Optional):
sudo dpkg -i libcudnn7-doc_7.6.5.32-1+cuda10.1_amd64.deb
4.蟒蛇,Pytorch,张量流和急流
最后,我们到达了症结所在。我们将安装大部分时间都要使用的软件。
我们需要在虚拟环境中安装 Python。我已经下载了 python3,因为它是目前最稳定的版本,是时候和 Python 2.7 说再见了。当它持续的时候,它是伟大的。我们还将安装 Pytorch 和 Tensorflow。在适用的特定任务中,我更喜欢他们两个。
你可以去 anaconda 发行版页面下载这个包。
下载后,您只需运行 shell 脚本:
sudo sh Anaconda3-2019.10-Linux-x86_64.sh
您还需要在您的 shell 上运行这些命令,将一些命令添加到您的~/.bashrc
文件中,并使用最新的库版本更新 conda 发行版。
cat >> ~/.bashrc << 'EOF'
export PATH=$HOME/anaconda3/bin:${PATH}
EOFsource .bashrc
conda upgrade -y --all
下一步是为你的深度学习追求创造一个新的环境,或者使用一个现有的环境。我使用以下工具创建了一个新的 Conda 环境:
conda create --name py37
这里,py37 是我们为这个新的 conda 环境提供的名称。您可以使用以下方式激活 conda 环境:
conda activate py37
您现在应该能够看到类似这样的内容:
请注意终端中命令开头的 py37
我们现在可以使用 pip 或 conda 将所有需要的包添加到这个环境中。正如我已经提到的,从 pytorch 网站看到的最新版本 1.3 还不能用于 CUDA 10.2,所以我们很幸运有了 CUDA 10.1。此外,我们需要将 TensorFlow 的版本指定为 2.1.0,因为这个版本是使用 10.1 CUDA 构建的。
我还安装了 RAPIDS,这是一个将各种数据科学工作负载转移到 GPU 的库。为什么 GPU 只用于深度学习而不用于数据处理?您可以从 rapids 发布选择器中获得安装 rapids 的命令:
sudo apt install python3-pipconda install -c rapidsai -c nvidia -c conda-forge -c defaults rapids=0.11 python=3.7 cudatoolkit=10.1pip install torchvision
由于 PyTorch 安装会干扰 TensorFlow,所以我在另一个环境中安装了 TensorFlow。
conda create --name tf
conda activate tf
pip install --upgrade tensorflow
现在,我们可以通过在 TF 和 Pytorch 各自的环境中使用以下命令来检查它们的安装是否正确:
# Should print True
python3 -c "import tensorflow as tf; print(tf.test.is_gpu_available())"# should print cuda
python3 -c "import torch; print(torch.device('cuda' if torch.cuda.is_available() else 'cpu'))"
如果安装显示 TensorFlow 出现一些错误,或者 GPU 测试失败,您可能需要在bashrc
文件的末尾添加这两行,然后重新启动终端:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/extras/CUPTI/lib64:/usr/local/cuda/lib64export CUDA_HOME=/usr/local/cuda
你可能还想安装jupyter lab
或jupyter notebook
。感谢开发者,这个过程就像在你的终端上运行jupyter lab
或jupyter notebook
一样简单,无论你喜欢哪个。我个人更喜欢没有不必要的杂物的笔记本。
结论
在这篇文章中,我谈到了你将需要毫不费力地在你的深度学习装备中安装的所有软件。
你可能仍然需要一些帮助和面对一些问题,我最好的建议是去看看不同的 NVIDIA 和 Stack Overflow 论坛。
因此,我们已经有了深度学习装备设置,现在是进行一些测试的时候了。在接下来的几篇文章中,我将对 GPU 进行一些基准测试,并尝试编写更多关于各种深度学习库的文章,这些库可以包含在他们的工作流中。敬请关注。
继续学习
如果你想了解更多关于深度学习的知识,这里是一门优秀的课程。您可以免费开始 7 天的免费试用。
谢谢你的阅读。将来我也会写更多初学者友好的帖子。在 媒体 关注我或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter@ mlwhiz联系
此外,一个小小的免责声明——这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意。
影响大小的权威指南
由 Kaboompics 拍摄的照片。com 来自 Pexels
了解如何正确计算和解释 A/B 测试的影响大小!
作为一名数据科学家,在进行某种 A/B 测试时,您很可能会遇到影响大小的问题。一种可能的情况是,公司希望对产品进行更改(无论是网站、移动应用程序等。)而你的任务是确保这种改变在一定程度上会带来更好的 KPI 表现。
这就是假设检验发挥作用的时候了。然而,统计测试只能告知影响存在的可能性。就效果而言,我只是指一种差异——它可以是两个方向上的差异,但也可以是一种假设的更精确的变体,即一个样本实际上比另一个样本更好/更差(根据给定的指标)。为了知道影响有多大,我们需要计算影响大小。
在本文中,我将提供一个关于效果大小的简单理论介绍,然后展示一些如何在 Python 中计算它的实际例子。
理论介绍
从形式上来说,效应大小是我们正在研究的现象的量化大小。如前所述,统计测试得出了观察到一种效应的概率,然而,它们并没有具体说明这种效应实际上有多大。这可能会导致这样的情况:我们检测到统计上的显著影响,但它实际上非常小,对于实际情况(业务)来说,它可以忽略不计,一点也不有趣。
此外,在计划 A/B 测试时,我们希望估计测试的预期持续时间。这与功耗分析的主题有关,我在的另一篇文章中提到过。快速总结一下,为了计算所需的样本量,我们需要指定三件事:显著性水平、检验的功效和效应大小。保持其他两个不变,效应大小越小,就越难以某种确定性来检测它,因此统计检验所需的样本量就越大。
一般来说,可能有数百种不同的效果大小的测量方法,每一种都有一些优点和缺点。在这篇文章中,我将只介绍一些最流行的。在深入研究兔子洞之前,效应大小的度量可以根据它们定义效应的方法分为三类。这些群体是:
- 基于相关性的度量
- 基于差异的指标(例如,平均值之间)
- 分类变量的度量
前两个系列涵盖连续随机变量,而最后一个系列用于分类/二元特征。举一个现实生活中的例子,我们可以将前两个应用于一个指标,如在一个应用程序中花费的时间(以分钟为单位),而第三个系列可以用于转换或保留-以布尔值表示。
我将在下面描述一些效果大小的度量,以及 Python 实现。
Vishwarajsinh Rana 在 Unsplash 上拍摄的照片
Python 中的示例
在这一部分中,我将更详细地描述每个效果大小系列的几个例子,并展示如何使用流行的库在 Python 中计算它们。当然,我们也可以自己编写这些函数,但是我认为没有必要重新发明轮子。
作为第一步,我们需要导入所需的库:
1.相关家族
这个组的名字(也称为“r 族”)来自两个变量之间关联的度量——相关性。到目前为止,最流行的相关性度量是皮尔逊相关系数(皮尔逊的 r )。
在深入研究指标之前,我们将从多元正态分布中生成一些随机的相关变量。它们有不同的含义,因此我们实际上可以检测到一些影响,同时为了简单起见,我们将方差保持为 1。
请记住,我们生成的随机观察越多,它们的分布就越像我们指定的分布。
皮尔森的r
这并不奇怪,因为这个家族的名字就是基于这个标准。皮尔逊相关系数衡量两个实值变量之间的线性关联程度。该度量是无单位的,表示为[-1,1]范围内的数字。为简洁起见,我只描述极端情况的解释:
- 值-1 表示变量之间完全负相关,
- 值 0 表示没有线性关系,
- 值为 1 表示完美的正关系。
由于这通常是最常用的指标之一,因此在 Python 中有许多计算相关系数的方法:
pearsonr
在scipy.stats
中——除了相关系数,我们还接收相关测试的 p 值。引用文档:"p 值大致表示不相关系统产生的数据集的皮尔逊相关性至少与从这些数据集计算出的值一样极端的概率。
stats.pearsonr(x[:,0], x[:,1])
# (0.6023670412294826, 0.0)
numpy.corrcoef
—返回相关矩阵,使用rowvar
指示随机变量的观察值是存储在行中还是列中。
np.corrcoef(x, rowvar=False)
# array([[1\. , 0.60236704],
# [0.60236704, 1\. ]])
pandas
数据帧/系列的corr
方法。pingouin
的corr
函数——默认情况下,它返回皮尔逊的 r 系数(也可以使用其他相关性度量)。与scipy
相反,该函数返回相关性测试的更详细的结果。我们也可以使用检验的单侧变量。
pg.corr(x[:, 0], x[:, 1])
决定系数(R )
在这个家族中,效应大小的第二个度量是决定系数,也称为 R。它说明了自变量解释(可预测)的因变量方差的比例。换句话说,这是一个衡量观察到的结果如何被模型复制的标准。
决定系数有几种定义,然而,对我们来说最相关的是与皮尔逊的 r 相关的定义。当使用包含截距的简单线性回归(有一个因变量)时,决定系数就是皮尔逊的 r 的平方。如果有更多的因变量,R 是多重相关系数的平方。
在上述任何一种情况下,决定系数通常在 0 和 1 之间。但是,如果使用另一个定义,这些值也可能变成负值。由于我们平方相关系数的事实,决定系数不传达任何关于相关方向的信息。
我们可以通过运行简单的线性回归并检查报告值来计算决定系数:
- 使用
pingouin
:
pg.linear_regression(x[:, 0], x[:, 1])
- 使用
statsmodels
:
在这两种情况下,决定系数接近 0.36,这是相关系数(0.6)的平方。
η平方( η )
该系列中最后考虑的度量是 eta 平方。它是一个预测因子在因变量中解释的方差比率,同时控制其他预测因子,这使它类似于 r。
其中 SS 代表平方和。 η 是模型解释的总体方差的有偏估计量,因为它仅估计所考虑样本中的效应大小。这意味着 eta 平方将总是高估实际效应大小,尽管这种偏差随着样本大小的增加而变小。Eta-squared 也有 r 的弱点——每个额外的变量都会自动增加 η 的值。
为了用 Python 计算 eta 的平方,我们可以使用pingouin
库:
pg.compute_effsize(x[:, 0], x[:, 1], eftype='eta-square')
# 0.057968511053166284
此外,该库包含一个名为convert_effsize
的有用函数,它允许我们将 Pearson 的 r 或 Cohen 的 d 测量的效果大小转换为 eta-squared 等。
2.“差异”家庭
第二个家族被称为差异家族,这可能是衡量效应大小的最常用方法——计算样本平均值之间的差异。通常,该差异也通过除以标准偏差(任一或两个群体)来标准化。
实际上,人口数值是未知的,只能通过抽样统计来估计。这就是为什么有多种方法来计算均值之间的差异的影响大小——它们在使用的样本统计方面有所不同。
另一方面,这种估计效应大小的形式类似于计算 t 统计量,不同之处在于标准偏差除以 t 统计量分母中 n 的平方根。与 T21 统计不同,效应大小旨在估计总体水平的值,不受样本大小的影响。
这一族也被称为“ d 族”,以估计效应大小的最常见方法——Cohen 的 d. 命名
在深入研究指标之前,我们先定义两个来自正态分布的随机变量。我们使用不同的均值和标准差来确保变量有足够的差异来获得合理的效应大小。
两个随机变量的分布
科恩的 d
科恩的 d 测量两个变量的均值之间的差异。差异以标准差的数量表示,因此在公式中有除法。科恩的 d 定义为:
其中 s 为合并标准差,S1、S2 为两个独立样本的标准差。
注:一些来源使用不同的集合标准差公式,并且分母中不包括-2。
对效应大小的最常见解释如下:
- 小效果尺寸:d=0.2
- 中等效果尺寸:d=0.5
- 大效果尺寸:d=0.8
Cohen 的 d 经常用于估算 A/B 测试所需的样本量。一般来说,Cohen 的 d 值越低,表明需要更大的样本量,反之亦然。
在 Python 中计算 Cohen 的 d 的最简单方法是使用pingouin
库:
pg.compute_effsize(x, y, eftype='cohen')
# -0.5661743543595718
玻璃’δ’
Glass 的δ与 Cohen 的 d 非常相似,不同之处在于使用了第二个样本(A/B 测试中的对照组)的标准偏差,而不是混合标准偏差。
仅使用对照组的标准差的基本原理是基于这样的事实,即如果我们将多个治疗组与同一对照组进行比较,这样我们将在所有情况下具有共同的标准。
pg.compute_effsize(x, y, eftype='glass')
# -0.6664041092152272
对冲的 g
Cohen 的 d 是总体水平效应大小的有偏估计量,尤其是对于小样本(n < 20)。这就是为什么 Hedge 的 g 通过将 Cohen 的 d 乘以修正系数(基于伽马函数)来进行修正:
pg.compute_effsize(x, y, eftype='hedges')
# -0.5661722311818571
我们可以看到科恩的 d 和对冲的 g 的差别非常小。对于较小的样本量,这种情况会更明显。
3.绝对家族
这一族用于估计分类(以及在一些简单的情况下——二元)随机变量的效应大小。我们通过运行以下代码片段来生成该部分的随机变量:
φ(φ系数)
phi 系数是卡尔·皮尔逊引入的两个二元变量之间关联的度量,与 2x2 列联表的卡方统计相关。在机器学习术语中,列联表基本上与混淆矩阵相同。
当大部分数据落在列联表的对角线上时,两个二元随机变量是正相关的(想想真正的正和真正的负)。相反,当大部分数据脱离对角线时,变量是负相关的(想想假阳性和假阴性)。
事实上,为两个二元变量计算的皮尔逊相关系数( r )会得出 phi 系数(我们将用 Python 来证明)。然而,phi 系数的范围不同于相关系数,尤其是当至少一个变量取两个以上的值时。
此外,在机器学习中,我们看到马修斯相关系数作为评估分类模型性能的一种度量标准越来越受欢迎。事实上,MCC 就是皮尔逊的 phi 系数。
Phi/MCC 考虑了混淆矩阵/列联表的所有元素,这就是为什么它被认为是一个平衡的评估指标,也可以在类别不平衡的情况下使用。
运行代码会产生以下输出:
Phi coefficient: 0.000944
Matthews Correlation: 0.000944
Pearson's r: 0.000944
克莱默 V
cramér’s V 是分类变量之间关联的另一种度量(不限于二元情况)。
其中 k 和 r 代表列数和行数,φ是上面计算的φ系数。
克拉默的 V 取值范围为 0(变量之间没有关联)到 1(完全关联)。请注意,对于 2x2 列联表(两个二元变量)的情况,Cramér 的 V 等于 phi 系数,我们将很快在实践中看到这一点。
对克拉默 V 的大小最常见的解释如下:
- 小效果尺寸:V ≤ 0.2
- 中等效果尺寸:0.2 < V ≤ 0.6
- Large Effect Size: 0.6 < V
Cramer's V: 0.000944
We have indeed obtained the same value as in the case of the phi coefficient.
科恩的 w
Cohen 提出了效应大小的另一种度量,它“随着替代假设指定的分布与代表零假设的分布之间的差异程度而增加”(更多详细信息,请参见[1]第 216 页)。在这种情况下,我们处理的是比例(所有观察值的一部分),而不是之前度量的列联表。
其中:
- p_{0i} —零假设下单元格 i 中的比例,
- p_{1i} —替代假设下单元格 i 中的比例,
- m —细胞数量。
Cohen 的 w 测量的效应大小被认为对于接近 0.1 的值是小的,对于大约 0.3 是中等的,对于大约 0.5 是大的。
Cohen's w: 0.173820
科恩的 h
另一种用于比较两个独立样本比例的方法是科恩的 h ,定义如下:
其中 P1 代表第一个样本中阳性病例的比例。为了评估影响大小的大小,作者提出了与科恩的 d 相同的指示值范围。
Cohen's h: 0.174943
优势比
通过比值比测量的效应大小通过注意到治疗组中事件发生的比值比对照组高/低 X 倍来计算。
Odds Ratio: 1.374506
事件(例如转化)发生的几率在x
组中比在y
组中高约 1.37 倍,这与生成数据时提供的概率一致。
加成:通用语言效果大小
最后一个指标非常有趣,因为——顾名思义——它旨在用每个人都能理解的简单语言来表达效果大小。也不属于上面提到的家庭。作者在[2]中将这一指标描述为:
从一个分布中随机抽取的分数大于从其他分布中抽取的分数的概率。
为了使描述尽可能清楚,我将转述文中提到的例子。假设我们有一个成年男女的身高样本,CLES 是 0.8。这将意味着在 80%随机选择的配对中,男性将高于女性。或者换个说法,10 次相亲中有 8 次,男方会高于女方。
随机生成的高度的分布
结论
在本文中,我介绍了影响大小的不同度量,并展示了如何在 Python 中计算它们。了解这些,或者每个家族至少有一个关键指标,在使用 frequentist 方法计划 A/B 测试时肯定会派上用场。
您可以在我的 GitHub 上找到本文使用的代码。一如既往,我们欢迎任何建设性的反馈。可以在 Twitter 或者评论里联系我。
如果您对本文感兴趣,您可能也会喜欢:
图书馆的快速参观,以及它是如何从老守卫中脱颖而出的
towardsdatascience.com](/the-new-kid-on-the-statistics-in-python-block-pingouin-6b353a1db57c) [## 单尾还是双尾检验,这是个问题
了解统计测试的两种变体之间的区别,以及如何在 Python 中实现它们
towardsdatascience.com](/one-tailed-or-two-tailed-test-that-is-the-question-1283387f631c) [## Python 中的功耗分析简介
了解概念的重要性,如显著性水平、效应大小、统计功效和样本大小
towardsdatascience.com](/introduction-to-power-analysis-in-python-e7b748dfa26)
参考
[1]科恩,J. (2013)。行为科学的统计功效分析。学术出版社。
[2] McGraw,K. O .,& Wong,S. P. (1992 年)。一种常见的语言效应大小统计。心理通报,111 (2),361–365。https://doi.org/10.1037/0033-2909.111.2.361
使用 Azure 将 CSV 文件转换为 Power BI 视觉效果的权威指南
使用 Microsoft Azure 产品将新冠肺炎数据转化为惊人的 Power BI 视觉效果的分步指南。
云、大数据和商业智能是这十年的三个热门词汇。每个人都在谈论他们。每个人都想做。但是没人告诉你怎么做。你如何使用云来处理你的大数据并围绕它构建智能来做出业务决策?
这个问题有多种答案,在本指南中,我们试图使用微软的云解决方案(Azure)和微软的 BI 工具(Power BI)来回答这个问题,以帮助您朝着正确的方向开始。
微软 Azure 是领先的云解决方案提供商之一,提供一套端到端的工具和技术来摄取、分析和消费大量的数据源和数据格式。
注意: Microsoft Azure 是一项付费服务,遵循本文可能会导致您或您的组织承担财务责任。
在继续阅读本文之前,请阅读我们的使用条款:https://dhyanintech . medium . com/disclaimer-disclosure-disclosure-terms-of-use-fb3 BF BD 1e 0e 5
先决条件
- 有效的 Microsoft Azure 订阅
如何获得 Azure 订阅?
[## 立即创建您的 Azure 免费帐户| Microsoft Azure
利用人工智能创造个性化体验构建互联的跨平台体验-为客户互动量身定制…
azure.microsoft.com](https://azure.microsoft.com/en-us/free/)
以一种简单、易于理解和可用的形式表示数据的第一步是识别数据的来源和格式。传统上,数据专业人员专注于提取、转换&加载(ETL) 加载和转换数据。Azure 的出现打开了在无限和前所未有的规模上处理无结构数据的大门。此变更将转换和加载数据转移到提取、加载&转换(ELT) 。基本原理和步骤保持不变;他们只是遵循不同的顺序。Azure 中的数据项目通常包括以下步骤:
- **获取:**确定加载数据的工具、技术和方法
- **准备和培训:**确定转换数据的工具、技术和方法
然后是两个额外的步骤来分析和使用清理后的数据
- **建模和服务:**确定建模和分析数据的工具和方法
- **消费:**确定消费或呈现数据的工具和技术
在这篇文章中,我们将借助一个例子,通过 ELT 的不同阶段,了解在 Azure 中转换和加载数据的整体方法。为了开始我们的旅程,我们将:
- 从 GitHub 获取公开的新冠肺炎数据(来源)
- 借助 Azure Data Factory ( 摄取)将 CSV 文件存储到 Azure Data Lake Storage Gen2
- 将 CSV 文件转换并清理为 Azure Databricks 中的关系数据(准备和培训)
- 将清理后的数据存储在 Azure Synapse Analytics 数据仓库*(建模和服务)*
- 最后,以 Power BI 视觉效果的形式呈现准备好的数据(消耗)
体系结构
下图提供了我们旅程的高度可视化:
典型的现代数据仓库架构(图片由作者提供)
数据流
- 使用 Azure Data Factory 以网页的形式从 GitHub 获取 CSV 数据。
- 将传入的数据作为 CSV 文件保存在 Azure Data Lake 存储中。
- 利用 Azure Databricks 来执行可扩展的分析,并实现清理和转换的数据(或者使用 PolyBase 来清理、转换和直接加载到 Azure Synapse Analytics 数据仓库)。
- 将清理和转换后的数据移动到 Azure Synapse Analytics 数据仓库,以与现有的结构化数据相结合。
- 在 Azure Synapse Analytics 数据仓库的基础上使用 Power BI 构建报告和仪表板,以从数据中获得洞察力。
成分
- Azure Data Factory:一种混合数据集成服务,用于创建、调度和编排 ETL 和 ELT 工作流
- Azure 数据湖存储 :面向非结构化数据、图像、视频、音频、文档等的大规模可扩展且经济高效的存储。
- Azure data bricks:快速、简单、可扩展和协作的基于 Apache Spark 的分析平台
- Azure Synapse Analytics:基于大规模并行处理架构的可扩展弹性云数据仓库,将企业数据仓库和大数据分析结合在一起
- Power BI :一套业务分析工具,提供来自数百个数据源的见解,简化数据准备,并推动即席分析
下一步是设置完成数据项目所需的资源和组件。在典型设置中,数据工程师可能会执行一些常规任务:
- 提供:提供数据平台技术存储数据
- 过程:创建数据处理管道,在不同的数据存储之间移动数据
- 安全:确保数据安全,防止未经授权的访问和网络攻击
- 监控:设置主动和被动监控和警报,以确保解决方案满足所需的性能、可用性和成本限制
- 灾难恢复:确保在发生灾难时能够恢复数据
在本指南中,我们将重点介绍资源调配和处理,因为其他任务超出了我们项目的范围。让我们开始吧。
创建资源组
在 Azure 中,每个资源都属于且仅属于一个资源组。资源组是资源的逻辑分组,以简化管理、访问、成本等。我们的资源组将保存所有我们提供的组件。
[## 管理资源组- Azure 门户- Azure 资源管理器
了解如何通过 Azure 资源管理器使用 Azure 门户来管理您的 Azure 资源组。对于管理 Azure…
docs.microsoft.com](https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/manage-resource-groups-portal#what-is-a-resource-group)
登录 Azure 门户。在左上角选择 +创建资源,搜索资源组,在新*刀片上,*点击创建开始创建过程。在Create a resource groupblade 上,选择您将用于这个项目的订阅,为您的资源组键入一个名称,并从列表中选择一个适当的区域。
刀片指的是 Azure 门户中的窗格。
Azure 门户:搜索资源或服务(图片由作者提供)
Azure 门户:创建资源组(图片由作者提供)
您可以自由选择资源的名称;但是,遵循命名约定是一个好习惯。
组织您的云资产,以支持运营管理和会计要求。定义良好的命名和…
docs.microsoft.com](https://docs.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/naming-and-tagging)
创建 Azure 密钥库
Azure Key Vault 是一款安全存储和访问机密的工具。秘密是您想要严格控制访问的任何东西,比如 API 密钥、密码、访问令牌或证书。
搜索 Key vault 与我们对资源组所做的类似(步骤 1-3 ),并填写所示的设置,将其余部分保留为默认设置,请注意,我们的资源组可在下拉列表中选择。
Azure 门户:创建 Azure 密钥库(图片由作者提供)
创建 Azure 数据工厂
在 Azure 门户搜索数据工厂,填写如图所示的设置;将其余部分保留为默认值。
Azure 门户:创建数据工厂实例(图片由作者提供)
调配 Azure 数据湖存储
在 Azure 门户中搜索存储账号,填写如图所示的设置;将其余部分保留为默认值。这里需要注意的重要一点是 Azure Data Lake Storage Gen2 提供的分层名称空间,它构建在低成本的 Azure blob 存储之上。分层命名空间将对象组织到目录的层次结构中,以增强性能、管理和安全性。
Azure Data Lake Storage Gen2 是一组专用于大数据分析的功能,构建于 Azure Blob 存储之上…
docs.microsoft.com](https://docs.microsoft.com/en-us/azure/storage/blobs/data-lake-storage-introduction)
Azure 门户:提供 Azure 数据湖存储 Gen2(图片由作者提供)
选择工具栏上的通知图标,查看创建进度。部署后,您会收到一个弹出通知。使用它转到新创建的资源。在概述页面,找到容器选项;我们将使用它来制作一个容器,作为存储下载文件的仓库。按照所示步骤创建容器 CSV*-数据存储*。点击打开新容器,选择 **+添加目录,**创建新目录,命名为covid 19-data;这个文件夹将保存我们的文件。
在 Azure 数据湖存储 Gen2 中创建一个容器(图片由作者提供)
创建 Azure Databricks 工作区
在左上角,选择 +创建资源。选择Analytics>Azure data bricks开始创建过程,如图所示填写设置。
Azure 门户:创建一个 Azure Databricks 工作区(图片由作者提供)
在 Azure Synapse Analytics 中创建数据仓库
在左上角,选择 +创建资源。选择数据库> Azure Synapse Analytics(以前的 SQL DW) 开始创建过程,填写如图所示的设置。我们已经在 Azure Synapse Analytics 中成功创建了一个数据仓库。
Azure 门户:创建 Azure Synapse 分析数据仓库(图片由作者提供)
一台服务器,多个数据库
当我们创建第一个 Azure SQL 数据库时,我们也创建了一个 Azure SQL(逻辑)服务器。可以把服务器想象成我们数据库的管理容器。我们可以通过服务器控制登录、防火墙规则和安全策略。我们还可以在服务器中的每个数据库上覆盖这些策略。目前,我们只需要一个数据库。
部署完成后,转到资源,为我们的新数据库打开概述页面。浏览概览页面上的数据库详细信息;我们对服务器名和连接字符串特别感兴趣。我们稍后将需要这些来连接到我们的数据库。
Azure Synapse 分析:概述(图片由作者提供)
设置 Microsoft Power BI
Microsoft Power BI 存在于 Azure 产品之外,有三种不同的定价风格——桌面版、专业版和高级版。桌面版对个人用户是免费的,非常适合我们的锻炼。从 Microsoft store 下载并安装 Power BI Desktop。
Microsoft Power BI Desktop 专为分析师打造。它结合了最先进的互动可视化,与…
www.microsoft.com](https://www.microsoft.com/en-us/download/details.aspx?id=58494)
伙计们,就这样吧。喝杯咖啡,我们将在后续的系列文章中继续讨论各个组件的详细处理步骤。
结论
我们看了新时代的 ETL 过程和数据工程师必须执行的任务。我们提出并讨论了一个数据工程项目,并设置了 Microsoft Azure 组件来构建我们的项目。
后续步骤
跟随我们的后续文章,与我们一起构建您的项目。我们将详细讨论和解释所有组件的处理过程。
- 使用 Azure 数据工厂摄取文件
[## 使用 Azure Data Factory 基于 HTTP 上的 URL 模式增量复制文件
一个创新的 Azure 数据工厂管道,通过 HTTP 从第三方网站增量复制多个文件…
medium.com](https://medium.com/@dhyanintech/using-azure-data-factory-to-incrementally-copy-files-based-on-url-pattern-over-http-569476b625fc)
- 在 Azure 数据块中清理和转换 CSV 文件
[## 在 Azure Databricks 中将模式漂移的 CSV 文件清理并转换为关系数据
使用 PySpark 处理模式漂移文件并将其加载到 Azure Databricks 中的 Azure Synapse Analytics 数据仓库
medium.com](https://medium.com/@dhyanintech/cleansing-and-transforming-schema-drifted-csv-files-into-relational-data-in-azure-databricks-519e82ea84ff)
- 使用 PolyBase 在 Azure Synapse Analytics 中加载数据
[## 使用 PolyBase 将 CSV 数据加载到 Azure Synapse Analytics
使用 PolyBase 将 CSV 数据从 ADLS Gen2 导入 Azure Synapse Analytics 的分步指南
dhyanintech.medium.com](https://dhyanintech.medium.com/loading-csv-data-into-azure-synapse-analytics-by-using-polybase-5ae942ce3059)
- 用 Power BI 建模和呈现数据—无限期推迟
喜欢这个帖子?与 Dhyan 联系
让我们做朋友吧!你可以在 LinkedIn 上找到我或者在 Medium 上加入我。
RShiny 演示——您的下一个基于代码的仪表板解决方案?
建立一个个人支出仪表板应用程序来检查我的财务状况
市场上最好的两个 dashboarding 工具,Tableau 和 Power BI,使用起来完全是一种享受(好吧,也许不是 Power BI……)。然而,在可行的情况下,我总是倾向于使用 r,而不是使用他们争论数据的产品(Prep 和 PowerQuery)。
r 更快,有非常优雅的语法(如果你对 Tidyverse 感兴趣的话),可重复(因为它是代码),并且对它可以完成的各种数据争论任务(包括数据检索)几乎没有限制。
但是 R 也提供了各种各样的表示/报告选项。r 可以通过编程构建 pdf 报告、PowerPoints、Word 文档和网页,所有这些都以图表和表格为特色,这些图表和表格利用了一些最新的 web 可视化库(也可以设置为在预定的基础上自动通过电子邮件发送这些输出)。
这篇文章的主要焦点是 R 的交互式仪表板/应用程序解决方案,通常被称为“闪亮”。
在许多情况下,定制的仪表盘/应用程序(并不闪亮)使用 JavaScript、React 和 D3(我当然不是专业的定制应用程序开发专家),然而,存在许多 R 包作为这些技术的“包装器”,使得从 R 代码生成相同类型的专业输出成为可能。
当然,与这些语言的本地编码者可能产生的东西相比,可能会有一些限制;但是对于一个 R 程序员来说,能够进入下一步并产生一个工作原型(最终可能完全足够)而不是引入一个新专业人员,是相当有价值的。
鉴于目前 R 在一大堆本科科学课程中的受欢迎程度,预计未来几年将会有越来越多崭露头角的 R 开发人员涌入。因此,为了展示 R 在这方面的能力,我制作了一个个人财务应用程序(显示的值是半虚拟的旧交易数据)。
初始输入和交易检查页面
主费用汇总页面
累计费用和收入预测页
如果你想看视频,这里有一个可能比你希望的更详细的演示(但它有一个额外的目的,所以请继续阅读,在最后找出它是什么)。
对于那些经过一些整洁的小技巧的人来说,这里是带有代码的 GitHub repo。是的,有 2000 多行(我喜欢危险的生活)。
此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…
github.com](https://github.com/Tadge-Analytics/Personal-expense-shiny-dashboard)
仅仅因为 R 是开源的,并不意味着这些仪表板项目一定会比使用流行的付费工具便宜。虽然您可能会节省最初的订购费用,但大多数人会意识到,一个专有的拖放式工具能够让您在更少的计费时间内启动并运行。使用一个也可能使过程更容易转移,因为 Tableau 和 Power BI 开发人员比闪亮的开发人员多得多。
然而,当使用代码时,在再现性方面有相当大的优势。例如,如果为多个客户端创建同一个仪表板;有了 R,每当需要更新时,不再需要完全独立的仪表板构建工作和对每个文件的单独编辑。使用(正确的)代码,您只需更改相关的函数(或特定的参数)就可以实现更改。
但是,当然,通过代码获得美学可能会很麻烦(对于最初的尝试来说也是如此)。默认情况下,许多软件包都产生了不错的设计,并且您可以完全控制几乎所有的元素(但这就是问题所在——选项太多了。有时,仅仅通过拖动或简单地从一个漂亮的用户调色板中“挑选”你想要的颜色来调整图表的大小要容易得多。*
对于我的应用程序来说,数据争论非常复杂。虽然这个可以作为一个单独的数据预处理过程来完成,但是争论层和表示层之间的迭代和交织本质意味着将它们放在同一个软件中是理想的。最终结果更加无缝(这也是我想象中的最终用户真正使用产品的唯一方式)。
该应用包括 Tableau / Power BI 用户熟悉的许多功能:
- “点击”过滤器(点击一个图表以过滤另一个图表)
- 点击高亮显示(基本相同,通常在一个图表中,尽管看到虚线下面的灰色条)
- 单击参数更新(出现并被更改的虚线)
- 工具提示(虽然我没有费心整理这些,因为它只是一个 MVP)
还有一些流行的付费工具的功能是闪亮仪表盘中不存在的(据我所知)。例如,将图例浮动在任何位置,并且在工具提示图表中有“”。**
- 通过表示层将“客户端”CSV 直接上传到流程中
- 将有争议的 CSV 摘要下载到 Excel 文件中(包含多个工作表和格式化表格)。这样做是为了让用户可以选择在最熟悉的环境中对他们的交易进行手动分类。
- 利用与 Googlesheets 的连接来存储汇总数据(作为使用 Excel 文件的替代方案),并利用检索和“写回”功能,只需点击一个按钮。这使得用户不必在保存和上传多个 Excel 文件之间进行迭代(它还允许跟踪更改——这非常简洁)。
我闪亮的仪表板能够做的关键事情(在付费工具中不可能做到的)是*😗
这款应用的主要特点是它可以帮助对银行交易进行分类。本质上,随着用户收集更多的关键字,所需的工作(正确识别新交易)大大减少。
第二页是洞察力开始的地方。特别是,主要功能是支出率图表。对我来说,关键的一点是,这让我可以看到我的总体“消耗率”和按特定类别细分的支出率。尤其是我在外出就餐、公共交通和日常不可避免的开支上花了多少钱。
第三页是由用户说明引导的关于费用的推断。在这里,您可以看到每个类别的贡献。
通过 Excel 电子表格(或 Googlesheet),可以:
- 加入尚未发生的预期事件
- 修改那些已经发生的(通过指定正在进行的费率/时间表,规定它们不会再次发生)。
- 限制用于每日消费率计算的历史数据的范围(例如,仅使用我外出就餐的最近 20 笔交易来预测未来,或仅使用自[某个日期]以来的交易)。
最终注释
这个项目是一个经典的案例,一些看起来很简单的东西被发现实际上非常复杂。即使作为一个爱好项目和(广告)博客帖子的组合,它也占用了相当多的额外时间。最后,它被证明是一个无论是用 Tableau 还是 Power BI 都无法真正完成的项目(至少没有那样的凝聚力),所以我想这并不是真正最公平的比较。
对于像这样的应用程序的安全(启用身份验证)、基于网络的交付系统, Shinyapps.io 提供了这项服务,但也有许多自托管选项可用。然而,因为我预计大多数个人和企业都非常不愿意将他们的私人交易数据上传到第三方(即使这是一个相当改进的、安全的在线版本的应用程序)——这就是为什么我一直将该文件作为可以在个人电脑上本地使用的东西。
此外,我已经决定让这个项目开源。希望它的某些部分可能对 R 社区有所帮助。项目本身也可以从他们的推荐/建议中受益,所以请随意使用 Youtube 视频和脚本来检测可能的改进。如果你愿意合作,请随时给我发电子邮件。
原载于 2020 年 1 月 21 日 https://tadge-analytics.com.au。**
迁移学习的一个糟糕例子:VGG 预训练模型在 Keras 中的应用
使用特征提取过程对 Mnist 数字数据进行分类的迁移学习演示
迁移学习是机器学习中最先进的技术之一,已广泛应用于图像分类。在这篇文章中,我将讨论迁移学习,VGG 模型和特征提取。在最后一部分,我将展示一个有趣的迁移学习的例子,其中迁移学习技术在对 MNist 数字数据集进行分类时表现出乎意料地差。
V VGG 小组参加了一年一度的计算机视觉竞赛——ImageNet 大规模视觉识别挑战赛( ILSVRC ),并提交了著名的 VGG 模型,用于参加对象定位(检测来自 200 个类别的图像中的对象)和图像分类任务(1000 个类别的分类)的竞赛。ImageNet 数据集是比赛中使用的主要计算机视觉基准数据集,包括属于 1000 个类别的超过 1400 万张图像。VGG 模型以 92.7%的前 5 名测试准确率超越了其他模型,并在 2014 年 ILSVRC 竞赛中获得了第一名和第二名。
VGG 建筑
VGG 有两种不同的架构:VGG-16 包含 16 层,VGG-19 包含 19 层。在本文中,我们将重点关注 VGG-16,它主要包含三个不同的部分:卷积、池和全连接层——它从两个卷积层开始,然后是池,然后是两个卷积,然后是池,再重复三个卷积,然后是池,最后是三个全连接层。下图显示了 VGG-16 模型的架构。VGG 模型最有趣的部分是模型权重可用于不同的平台(如 Keras ),并可用于进一步的分析——开发模型和应用程序。将模型的权重用于进一步任务的想法引发了迁移学习的想法。
VGG-16 建筑
我们可以运行以下三行代码,用 python 绘制 VGG-16 模型架构:
from keras.applications.vgg16 import VGG16
from keras.utils import plot_model
model = VGG16()
plot_model(model)
迁移学习
我们知道,随着神经网络架构的增加/深化,训练时间呈指数增长。一般来说,用大规模数据集训练一个 3-5 层的神经网络可能需要几个小时/几天。因此,由于模型架构中完全连接的图层/节点的深度和数量,在大规模数据集上从头开始部署 VGG 是一项令人厌倦且计算量巨大的任务。另一个挑战是从零开始构建 VGG 需要相当大的内存空间和带宽,因为 ImageNet 训练的 VGG-16 砝码的大小为 528 MB。然而,我们可以执行转移学习,即,利用权重等知识以及之前训练过的(例如预训练的 VGG)模型的特征,来解决类似的问题,而不是从零开始构建 VGG。例如,如果我们想开发一个二进制图像分类器,那么我们可以使用一个预先训练的模型,它是在像 VGG 这样的大型基准图像数据集上训练的。因此,迁移学习是一种机器学习方法,其中为一项任务开发的模型被重新用作第二项任务的模型的起点。迁移学习通常用于加快训练时间,最终提高模型的性能。在利用迁移学习的同时,我们必须考虑到使用迁移学习的好处并不明显。
什么时候使用迁移学习?
可以阅读深度学习的世界 中的文章 迁移学习的意义,解释什么时候使用迁移学习。
当训练数据不足时,机器学习算法尤其是深度神经网络可能无法正确学习。迁移学习可以在解决这一问题和调整模式以适应新任务方面发挥重要作用。在应用迁移学习时,我们可以寻找一些因素[1]:
- **更高的起点:**有迁移学习的模型初始阶段的表现应该会优于没有迁移学习的模型。
- **更高的斜率:**在源模型的训练阶段,性能斜率或改进率比其他情况下更陡。
- **更高的渐近线:**预训练的应该更平滑地收敛。
为什么要用 VGG 模式进行迁移学习?
假设给定数量的训练样本(图像)不足以构建分类器,在这种情况下,VGG 可以很容易地用于特征提取,因为它是在数百万个图像上训练的。VGG 是在 2014 年推出的,尽管如此,通过 2014 年之后出现的许多最先进的图像分类器,它在一些特定任务上比其他分类器具有更好的准确性。
在这篇文章中,我们将用 VGG 模型展示迁移学习的一个例子,它表明迁移学习方法没有达到标准。在以后的文章中,我们将展示另一个例子,在这个例子中,利用迁移学习方法,模型的性能得到了预期的提高。
在这次演示中,我们使用著名的 MNIST 数字数据集。我们使用仅包含数字 8 和 6 的 MNIST 数据集的一部分。总共有 8200 个样本,每个样本有 784 个特征。我们使用 VGG 预训练的权重为 MNIST 数据集提取特征。
步骤 1 —数据准备
我们将数据集从本地硬盘上传到 Google Colab,并将标签从 8 和 6 转换为 1 和 0。
from google.colab import files
uploaded = files.upload()
从本地驱动器上传数据到 Colab
现在,我们读取数据集。下图显示标签为 8 & 6。在后面的部分中,我们将应用逻辑回归,我们将标签转换为 1 和 0。
数据片段
运行这一行代码将转换标签:
data['label'] = np.where(data['label'] == 8, 1, 0)
转换数据集的标签
步骤 2——从 VGG-16 模型中提取特征
在提取特征之前,只需观察 VGG-16 模型的总结:
VGG-16 模型综述
总之,VGG-16 包含 16 层,其中在展平最后一个卷积层(第一个突出显示)之后,特征的数量是 25,088,并且在最后一层(预测或最终密集层)中,节点的数量是 1000,因为 VGG-16 主要针对 1000 类分类问题进行训练(第二个突出显示)。
出于迁移学习的目的,我们可以使用 VGG 模型从 MNIST 数据集中提取 25088 个特征。红色垂直线显示特征提取的切割。
VGG-16 的特征提取
下面的代码部分将在最后的卷积层之后剪切 VGG 模型:
from keras import models
base_model = VGG16(weights='imagenet')
model_VGG16 = models.Model(inputs=base_model.input, outputs=base_model.get_layer(**'flatten'**).output)
输出:
VGG 模型在去掉最后三层后的总结
利用 VGG-16 模型的特征提取
在使用 VGG 模型从数字数据中提取特征之后,我们用这些特征训练了逻辑回归二元分类器,并执行 10 重交叉验证。同时,我们还对原始的 mnist 数字数据进行了逻辑回归,并进行 10 重交叉验证,以将结果与迁移学习的性能进行比较。
以下两个表显示了对原始数据和从原始数据中提取的特征应用逻辑回归的结果。在没有迁移学习的情况下,即将 LR 应用于原始数字数据实现了大约 98%的准确度,而利用迁移学习特征的模型仅实现了 50%的准确度,这类似于二进制分类问题的随机猜测。总的来说,我们期望随着迁移学习的进行,模型的性能会提高。然而,在这个演示中,我们发现随着迁移学习,模型性能急剧下降。
逻辑回归应用于 Mnist 数字数据的结果
VGG16 性能不佳的可能原因:
- VGG-16 是为 3 通道 RGB 图像训练的,而 Mnist 数字数据是 1 通道灰度
2.通过 VGG-16 高级代表性特征学习的 ImageNet 数据中的背景噪声
3.VGG-16 训练用于 1000 级分类,而对于这个任务,我们使用它进行二进制分类
虽然具有迁移学习的模型在该实验中没有提供有益的结果,但是利用 VGG 的其他层进行特征提取过程或者微调参数可以产生更好的准确性。总之,迁移学习是一种最先进的机器学习技术,可以提高模型的性能。然而,灵活运用迁移学习技术是获得适当优势的必要条件。
阅读默罕默德·马苏姆博士(以及媒体上成千上万的其他作家)的每一个故事。
你的会员费将直接支持和激励穆罕默德·马苏姆和你所阅读的成千上万的其他作家。你还可以在媒体上看到所有的故事—
阅读愉快!
参考:
[1]https://analyticsindiamag . com/transfer-learning-deep-learning-significance/
https://keras.io/guides/transfer_learning/
PyTorch 中使用视觉转换器的实际演示:MNIST 手写数字识别
在本文中,我将给出一个实际操作的示例(带代码),说明如何使用流行的 PyTorch 框架将视觉转换器应用到实际的计算机视觉任务中,该框架是在论文“ 中提出的,一幅图像相当于 16x16 个单词:按比例进行图像识别的转换器 (我在 的另一篇文章 中对此进行了评论)。
视觉转换器的原理图(来自https://openreview.net/pdf?id=YicbFdNTTy)
为此,我们将使用众所周知的 MNIST 数据集 来研究手写数字识别的问题。
使用 Pyplot 生成的 MNIST 手写数字示例
我想马上提供一个警告,只是为了说明这一点。我选择 MNIST 数据集进行这次演示,因为它足够简单,可以在几分钟内,而不是几小时或几天内,在没有任何专门硬件的情况下,从头开始训练模型并用于预测,因此几乎任何有计算机的人都可以做到这一点,并看看它是如何工作的。我没有尝试过优化模型的超参数,我当然也没有用这种方法达到最先进的精确度(目前这个数据集的精确度约为 99.8%)的目标。
事实上,虽然我将展示视觉转换器可以在 MNIST 上获得令人尊敬的 98%以上的准确性,但可以说它不是这项工作的最佳工具。由于该数据集中的每个图像都很小(只有 28x28 像素),并且由单个对象组成,因此应用全局注意力只能具有有限的效用。稍后我可能会写另一篇文章,研究如何在包含更大图像和更多种类的更大数据集上使用该模型。现在,我只想展示它是如何工作的。
在实现方面,我将依赖来自王飞的 这个 开源库的代码,特别是来自 vit_pytorch.py 文件的以下 Vision Transformer (ViT)类:
与任何 PyTorch 神经网络模块类一样,它具有初始化( init )函数,其中定义了所有可训练参数和层,以及转发函数,该函数建立了将这些层组装到整个网络架构中的方式。
为了简洁起见,这里只给出了 ViT 类本身的定义,没有给出依赖类。如果你想在你的电脑上使用这段代码,你需要导入整个vit _ py torch . py文件(这个文件出奇的小,只有一百行左右的代码;我在 GitHub 上给出了我自己的分叉版本的链接,以防将来原始文件发生变化),以及最近版本的 PyTorch (我使用的是 1.6.0)和用于张量操作的 einops 库。
要开始使用 MNIST 数据集,我们需要首先加载它,我们可以这样做(从这一点开始,这篇文章中的所有代码都是我的,尽管其中很多都很标准):
上面代码中的 transform_mnist 转换用于归一化图像数据,使其均值为零,标准差为 1,这有助于神经网络训练。 train_loader 和 test_loader 对象包含已经随机分成批次的 MNIST 图像,以便它们可以方便地输入到训练和验证程序中。
数据集中的每个项目都包含一个带有相应地面实况标签的图像。一旦在数据集的训练部分(60,000 个手写数字图像)上进行训练,我们的转换器的目标将是基于图像来预测测试部分(10,000 个图像)中每个样本的正确标签。
我们将使用以下函数为每个时期训练我们的模型:
该函数对 data_loader 对象中的每个批次进行循环。对于每一批,它计算模型的输出(作为一个 log_softmax )和这个输出的 负对数似然损失 ,然后通过 loss.backward() 计算这个损失关于每个可训练模型参数的梯度,并通过 **optimizer.step()更新参数。**每第 100 批,它提供一份关于训练进度的打印更新,并将当前损失值附加到 loss_history 列表中。
在每个时期的训练之后,我们将能够使用以下函数来查看我们的当前模型在测试集上的表现:
虽然这类似于上面的训练程序,但现在我们不计算任何梯度,而是将模型的输出与地面实况标签进行比较,以计算准确性并更新损失历史。
一旦定义了所有的函数,就该初始化我们的模型并运行训练了。我们将使用以下代码:
在这里,我们用 7x7 的面片大小(对于 28x28 的图像,这意味着 4 x 4 =每个图像 16 个面片)、10 个可能的目标类别(0 到 9)和 1 个颜色通道(因为图像是灰度)来定义我们的视觉转换器模型。
在网络参数方面,我们使用 64 个单元的嵌入维数,6 个变换器块的深度,8 个变换器头,以及输出 MLP 头的隐藏层中的 128 个单元。对于优化器,我们将使用学习率为 0.003 的 Adam(如论文中所示)。我们将对我们的模型进行 25 个时期的训练,并观察结果。
使用上面的超参数值没有特别的理由。我只是选了一些看起来合理的东西。当然有可能优化这些将导致更高的精度和/或更快的收敛。
一旦代码运行了 25 个时期(在一个普通的免费 谷歌实验室 笔记本电脑上,配有一个特斯拉 T4 GPU),它会产生以下输出:
嗯,98.36%的准确率还不算太差。这比人们期望从全连接网络中得到的要好得多(我在那里得到了大约 97.8-97.9%,没有任何技巧),所以注意力层肯定有好处。当然,正如我上面提到的,视觉转换器并不特别适合这项任务,即使是几层的简单卷积网络也可以达到 99%或以上的精度。在优化了超参数之后,这个变压器模型可能会做得更好。
但关键是,它是可行的,而且,正如 论文 中所描述的,当应用于更大、更复杂的问题时,它可以与最好的卷积模型相媲美。希望这篇简短的教程向读者展示了如何在自己的工作中使用它。
揭开形式概念分析(FCA)的神秘面纱
在复杂数据中寻找结构和规则。
结构(图片作者提供)。
这种情况多久发生一次?一个新的数据仓库出现了,或者有人给你指出一个不错的新数据集,从中你可以看到可能有一些有趣的事情要做。然后你看着它,嗯…它是一串数字。你可以运行一些统计数据,并四处打探,但这到底意味着什么呢?
也许形式概念分析 (FCA)能有所帮助。这看起来可能很复杂,但它基于一个相当简单的想法:T2 概念 T3。概念(有点像面向对象编程中的类)表示共享一组属性的一组对象。通常,在 FCA 中,这些属性是二进制的。
例如,假设我们正在查看关于四个国家的数据,这四个国家可大可小,人们可能会在左侧或右侧驾驶。我们可以用下面的二进制矩阵来表示每个国家的属性。
一个非常简单的数据集的形式上下文。
这个矩阵就是所谓的形式背景,我们可以看到这里有意义的概念包括大国的概念,或者说大国在右侧行驶的概念。包含在第一个对象(称为概念的范围中的对象(国家)集合是国家 1、国家 2 和国家 3 、,第二个对象仅包含国家 1 和国家 3。每个概念的意图,即共享的属性集合,对于前者为*【size:big】,对于后者为【size:big,driving:right】*。
有一件事我们需要添加到概念的定义中,这是 FCA 的核心:概念必须是封闭的。这意味着范围中的对象集应该正好是共享意图属性的对象集,和意图中的属性集应该正好是范围中的对象共享的属性集。
从那个定义来看,【大小:大】**【大小:大,驾驶:右】 是封闭的,但是*【大小:小】这个概念不是。的确,只有 country4 有这个属性,但它也有【驾驶:右】。因此,要使其封闭,必须通过范围元素共享的两个属性来定义概念:【size:small,driving:right】。同样适用于【驾驶:左】。这种情况下的封闭概念是【大小:大,行驶:左】*。
现在,寻找封闭的概念当然很有趣,但是让整个事情变得真正强大的是这些概念是由包容自然组织起来的。直觉上,一个概念包含另一个更一般的概念。更正式的说法是,它的意图(属性)包含在对方概念的意图中,它的范围(对象)包含对方概念的范围。基本上,【大小:大】归入【大小:大,驾驶:左】。
这种包含关系是一种偏序,这意味着一个概念可能包含另一个概念,被另一个概念包含,或者都不包含。因此,给定数据集(形式背景)的所有封闭概念都自然地组织在一个层次结构中(一个点阵),从更一般到更具体。
由一个小例子创建的概念格。
当然,对于这样一个小例子,它实际上并没有多大帮助。那么,让我们看看它在一个更重要的例子上做了什么。
乡村的例子,但是真实的
为了得到一个更真实的例子,我使用了 Wikidata 来检索国家列表以及与它们相关的信息(属性)。跳过细节(用于重新创建数据集的所有代码都可以通过 FCA 的基本实现以及在github.com/mdaquin/fca.js的示例获得),数据集包括来自国家/地区的信息,这些国家/地区具有超过 90%的国家/地区共享的属性值,并且具有数值或少于 5 个唯一分类值。对于这些国家,属性值通过以下方式转换为二进制属性:
- 对于分类属性,为每个可能的值创建一个属性,例如驾驶侧:左侧(机器学习从业者称之为 一个热编码 )。
- 对于数字属性,根据 33%和 67%的百分点创建低、中和高值的属性,例如人口:低(一种非常基本的离散化方法)。
结果是 147 个对象(国家)和 33 个二元属性的正式上下文。例如,法国由以下属性表示:
France:[
"area:high",
"population:high",
"mains voltage:medium",
"driving side:right",
"inflation rate:low",
"total fertility rate:low",
"PPP GDP per capita:high",
"life expectancy:high",
"has quality:free country",
"nominal GDP per capita:high",
"nominal GDP:high"
]
看这个正式的上下文感觉有点像看矩阵。一列接一列的 x,感觉有点随机,但也有点不随机:这里面有模式,所以让我们试着找到它们。
正式的上下文看起来都是矩阵。
构建概念格
构建概念格是一项复杂的任务,但是为了这个例子的目的,我使用了一个基本的方法。首先,我通过添加每个对象的意图以及与现有概念的意图的任何交集来构建所有相近的概念。然后我迭代概念来建立包含关系。最后,我用它们的范围填充每个概念。这远远不是最有效的算法(参见这篇文章中更好的算法列表), javascript 也不是最好的语言,但在我的笔记本电脑上,只需要几分钟就可以完成,所以还不算太差。
首先要注意的是,该算法找到了 8,840 个概念。这听起来可能很多,但是这远远没有达到我们用这个数量的属性所能找到的最大概念数量!我想这就是为什么大多数关于 FCA 的教程和例子倾向于只使用非常基本的例子。复杂的不是技术,而是结果。
然而,即使逐个检查所有这些概念是乏味且毫无意义的工作,这里的关键是它们不是作为属性集的列表,而是通过导航结构来探索它们。事实上,从网格的顶部开始(即没有属性作为意图,所有对象作为范围的概念),我们可以将注意力集中在下一个级别,例如低预期寿命的国家(【预期寿命:低】),发现有 20 个次级概念,包括人口也低的国家(其中 14 个)。在第三个层次,我们发现只有 5 个可能的其他概念,除了低预期寿命和人口之外,还有:
- 低名义 GDP,
- 高总和生育率,
- 中等电源电压,
- 低购买力平价人均国内生产总值,或
- 高通货膨胀率
可能有许多其他概念,但只有这五个,而且 FCA 基于封闭的属性集,这意味着这些其他概念根本不存在于数据中。在我们列出的国家中,你不可能预期寿命和人口都很低,也不可能不属于那 5 个类别之一。网格更深入地细分了这组国家,并提供了一种便捷的方式来探索数据集。但是它能做得更多吗?
提取关联规则
除了提供一个(相当庞大的)导航结构之外,一旦构建好,网格还可以用来识别数据中应用的规则。这里简单的直觉是,如果概念 C 的意图包括不在其任何父概念的意图中的属性(即包含概念),那么这些属性暗示了父概念的属性。这也是因为概念是封闭的:如果 C 自己的属性(其正确的意图)可以在没有父属性的情况下出现,那么它们就已经出现在更高的层次上了。
不幸的是,这种情况在我们国家的数据集中没有出现。然而,我们可以看到这种情况何时会发生。一个概念的支撑是其范围内的对象(国家)的数量。比如*【预期寿命:低,人口:低】的支持度是 14,如上图。如果一个概念 C 的支持度几乎与它的一个父概念 D 的支持度相同,那一定意味着 D 的意图的属性几乎隐含了 C 的意图的属性。换句话说,如果 C 具有意图【a,b,C】的支持度为 9,并且包含概念 S 具有意图【a,b】,的支持度为 10,我们可以说,任何具有属性 a 和 b 的对象在 90%的情况下也具有 C。我们有一个关联规则*说明 a 和 b 隐含 c,置信度 90%(支持度 9)。
那个,我们国家数据集有很多。仅关注置信度高于 95%且支持度至少为 25 的规则,我们可以发现例如以下规则:
inflation rate:high,total fertility rate:high -> life expectancy:low s:25 c:0.9615384615384616
其中指出,在 96.1%的置信度下,高通胀率和高生育率的国家预期寿命也低,这适用于我们数据集中的 25 个国家。
结论
FCA 和关联规则提取的应用还有很多,但对我来说,数据集探索和理解是最重要的应用之一。上面的规则和网格的结构可能反映了世界的某种现实,或者可能是数据集构建方式的人工产物。它可能会说明一些国家的情况,或者在数据中显示出一些偏差。无论是哪种情况,在数据过程的可解释性变得越来越重要的时候,一个可以告诉我“这是你的数据所说的东西”或“这是我在你的数据集的一个角落里发现的一个重要模式”的过程,对于理解数据和我们对数据所做的任何事情的结果都是无价的。
注意 U-Net 的详细说明
U-网中的注意门
了解新颖的注意力门,它可以自动聚焦于图像中的目标结构
在这个故事中,我解释了 Oktay 等人写的 Attention U-Net:学习在哪里寻找胰腺中的 Attention U-Net。艾尔。该论文写于 2018 年,提出了一种新颖的注意力门(AG)机制,允许 U-Net 专注于不同大小和形状的目标结构。
概述
- 什么是注意力?
- 为什么 U-Net 需要关注
- 注意力是如何实现的?
- 分析
1.什么是注意力?
在图像分割的背景下,注意力是一种在训练期间仅突出相关激活的方式。这减少了浪费在无关激活上的计算资源,为网络提供了更好的泛化能力。本质上,网络可以“关注”图像的某些部分。
答:努力关注
注意力有两种形式,硬和软。硬注意的工作原理是通过裁剪图像或迭代区域提议来突出相关区域。由于硬注意一次只能选择一个图像的一个区域,所以它有两层含义,它是不可微的,需要强化学习来训练。
由于它是不可微的,这意味着对于图像中的给定区域,网络可以“关注”或不关注,没有中间状态。因此,无法进行标准的反向传播,需要蒙特卡罗采样来计算反向传播各个阶段的精度。考虑到准确性取决于采样的好坏,因此需要其他技术(如强化学习)来使模型有效。
b .软注意
软注意通过对图像的不同部分进行加权来工作。高相关性区域乘以较大的权重,低相关性区域用较小的权重标记。随着模型被训练,更多的焦点被给予具有较高权重的区域。与硬注意不同,这些权重可以应用于图像中的许多小块。
当处理句子中的不同单词时,图像上的软注意力权重的可视化。较亮的区域具有较高的权重。(徐等,2015)
由于软注意的确定性,它仍然是可区分的,可以用标准的反向传播来训练。随着模型被训练,权重也被训练,使得模型在决定关注哪些部分方面变得更好。
强烈关注:
- 一次只挑补丁注意
- 不可微,需要强化学习
软性关注:
- 对图像的不同块进行加权以确定相关性
- 可微分的,可以用反向传播来训练
2.为什么在 U-Net 中需要注意力?
为了理解为什么注意力在 U-Net 中是有益的,我们需要看看所使用的跳跃连接。
灰色箭头表示 U 形网络中使用的长跳线连接。 (Ronneberger 等人,2015)
在扩展路径中的上采样期间,重新创建的空间信息是不精确的。为了解决这个问题,U-Net 使用跳过连接,将来自下采样路径的空间信息与上采样路径相结合。然而,这带来了许多冗余的低级特征提取,因为初始层中的特征表示很差。
在跳过连接处实施的软注意将主动抑制不相关区域中的激活,减少带来的冗余特征的数量。
3.注意力是如何实现的?
Oktay 等人推出的注意门使用的是加性软注意。
a .注意门的故障
顶部:注意门(AG)示意图。底部:AGs 是如何在每个 skip 连接上实现的。
- 注意力门接受两个输入,向量 x 和 g 。
- 向量 g 取自网络的下一个最低层。该矢量具有更小的维度和更好的特征表示,因为它来自网络的更深处。
- 在上面的示例图中,矢量×矢量×矢量的尺寸为 64×64×64(滤镜×高度×宽度),矢量×g×的尺寸为 32×32×32。
- 向量 x 经过步长卷积,其尺寸变为 64×32×32,向量 g 经过 1×1 卷积,其尺寸变为 64×32×32。
- 这两个向量按元素求和。该过程导致对齐的权重变大,而非对齐的权重变得相对较小。
- 合成向量经过 ReLU 激活层和 1x1 卷积,将维度折叠为 1x32x32。
- 这个向量经过一个 sigmoid 层,该层在范围[0,1]之间缩放向量,产生注意系数(权重),其中系数越接近 1 表示越相关的特征。
- 使用三线性插值将关注系数上采样到矢量×矢量 的原始尺寸(64×64)。关注系数被逐元素地乘以原始 x 向量,根据相关性缩放该向量。然后像往常一样在 skip 连接中传递。
Oktay 等人还提出了一种基于网格的门控机制,该机制从上采样路径而不是下采样路径(除了最低层)获取 g 向量,因为该向量已经通过先前的注意门被调节到来自多个尺度的空间信息。
注意系数在 3、6、10 和 150 个时期显现,其中红色突出了较高的注意系数。(Oktay et。阿尔,2018)
如上图所示,随着训练的进行,网络学会聚焦于所需的区域。注意门的可微分性质允许它在反向传播期间被训练,这意味着注意系数在突出相关区域方面变得更好。
b .在 Keras 的实施情况
4.分析
CT-150 数据集上的结果(Oktay 等人,2018 年)
Oktay 等人获得的结果表明,在整体骰子系数得分方面,注意力 U-Net 比普通 U-Net 的表现好得多。虽然注意 U-Net 有更多的参数,但并没有显著增加,推理时间也只是略微延长。
总之,注意门是一种在大量数据集上一致地改进 U-Net 的简单方法,并且在计算成本方面没有显著的开销。
要获得预先实施了注意力、递归和初始层的 U-Net 的完整实施,请检查https://github.com/robinvvinod/unet/。
理解数据库伸缩基础的开发人员指南
如何扩展数据库以承受传入的流量,以及如何降低其潜在性并提高其性能
菲德尔·费尔南多在 Unsplash 上的照片
假设我们有一个服务,用一个数据库服务器处理每月几千个请求,这个服务器处理来自应用服务器的所有读/写请求。
到目前为止,一切都运行良好,但是随着时间的推移,您开始观察到传入流量的峰值,即使尝试了以下方法,您也无法减少延迟和数据库故障:
- 拥有一个拥有大量内存和高性能闪存的数据库。
- 实现了最佳缓存以减少延迟。
- 对数据库查询进行适当的索引和优化。
因此,现在您需要解决您的数据库基础设施,以便它能够承受传入的流量。
让我们看看数据库分片和复制如何提供一个高度可靠和高性能的数据库系统,能够承受数百万的规模。
分身术
数据复制是将相同的数据存储在多个数据库服务器上的过程,可减少延迟、提高读取可伸缩性、简化数据恢复和提高数据可用性。
通常,数据副本存储在单独的硬件组件中,因为如果该硬件崩溃,您不希望副本崩溃。
最常用的复制策略是单领导者复制。
单头复制
在这种复制中,有一个主节点负责所有写入,并处理所有其他节点上的数据复制。
领导节点通常称为主节点,其他从属节点称为从节点。
读取和写入仅在主服务器上启用,从服务器只能处理读取查询。
作者图片— 单头主从复制
现在,要更新从属服务器上的数据,我们可以选择同步复制或 T21 异步复制。这两者各有利弊。
**1。同步复制:**一旦收到确认,它就完成写入并通知客户端。
同步复制的好处
- 它通过确保所有节点都拥有更新的数据来提供数据一致性,因为所有从节点都与主节点同步。
- 如果主节点出现故障,任何从节点都可以轻松成为主节点,而不会丢失任何数据。
同步复制的缺点
- 有时,当主设备等待来自所有从设备的确认时,系统可能是高度潜伏的。
- 如果任何从属服务器不可用或出现故障,则主服务器会阻止所有写入,直到同步副本再次可用。因此导致较低的可用性。
2。异步复制:
这样,即使所有从节点都出现故障,主节点也可以继续进行写入。
异步复制的好处
- 它提供了低延迟,因为主设备不等待从设备上的数据更新。
- 更高的可用性,因为即使任何从节点发生故障,也不会影响主节点。
异步复制的缺点
- 由于复制滞后,可能导致数据不一致。即主设备到从设备的数据复制可能需要很长时间。
因此,如果在主服务器和从服务器上运行相同的查询(并发执行),可能会得到不同的结果。 - 如果异步系统中的主节点发生故障,新指定的主节点可能无法完成前一个主节点的所有写操作。如果先前的主设备重新联机并成为从设备,它将具有冲突的写入。
因此,对数据库的读取规模可以通过复制来实现。
但是怎么加一个写尺度?答案是分片。
分片
比方说,你有一个比萨饼,你不能一个人吃整个,所以你把它切成片,然后打电话给你的朋友。
现在,这些朋友中的每一个都将得到一片比萨饼。你所做的是根据每个朋友的份额有效地划分比萨饼,就像我们可以有多个数据库服务器,它们将承担发送到它的请求的负载。
照片由 mahyar motebassem 在 Unsplash 上拍摄
因此,从技术上讲,我们将在分片中将完整的数据库负载分配给 N 个数据库服务器。
每个传入请求的子集将由一个单独的服务器提供服务。现在,每个分区都位于完全不同的物理机器上,并受具有相同数据库模式的独立数据库实例的控制。
这被称为分片。它也可以称为水平分区,因为分片基本上是跨不同物理机器/节点的水平分区。
分片提供了更高的可用性,减少了读/写数据库延迟,并且可以高效地处理高数据库负载。
在为数据库启用分片时,需要考虑多种因素。需要考虑的两个主要问题如下:
碎片键:
我们需要一些标识符来决定一个特定的请求应该从哪个数据库服务器得到服务。也就是说,应该有一个键,我们应该根据这个键来决定一个请求应该放在哪个碎片上。我们称之为碎片密钥或分区密钥。
一般我们选择表格的任意一列作为 shard_key 。
哈希函数:
哈希是使用数学函数将任意长度的输入转换成固定大小的文本字符串的过程。 这意味着任何文本无论多长都可以转换成数字和字母的数组。
这个用于生成散列值的数学函数被称为散列函数**。**
因此,我们使用散列函数计算 shard_key 的散列值,然后将该散列值映射到 DB 服务器。
在下图中,散列函数将 shard_key (row-id)作为输入,并返回一个值,通过这个值我们可以确定它应该进入哪个 shard。
作者提供的图片- 带有 4 个碎片集群的数据库碎片
现在, NoSQL 像 Mongo DB 这样的数据库为分片提供了一个内置的标准实现。
更多在数据库级别提供分片的数据库是 Cassandra、Hadoop 和 Apache H-Base e.t.c。
而在 MySQL 这样的关系数据库中,没有分片的标准实现。因此,通常的做法是让应用程序级分片用于关系数据库。
由于分片可能产生的问题
1.数据的重新分布:
如果在一个数据库集群中,一个数据库服务器出现故障,或者您正在向集群添加一个新的数据库碎片,那么您可能需要重新分发或重新散列数据。
这种开销直接依赖于我们用来在不同碎片之间分发数据的散列函数。
如果散列函数是一个简单的取模函数,它采用行 id 的取模和个碎片来决定请求应该到达的碎片,那么在这种情况下,它将导致数据的完全重新散列,如下所示:
作者提供的图片- 在添加服务器的情况下重新散列数据
在上图中,我们可以看到 4 个碎片的数据映射基于 id 模 4(碎片数)
12%4 ->第 0 分片
29%4 - >第 1 分片
27%4 - >第 3 分片
对于 5 个分片,数据映射基于 id 模 5(分片数)
12%5 ->第二碎片
29%5 - >第四碎片
27%5 - >第二碎片
因此,我们在这里观察到,当我们向现有的 four shard 集群添加一个 DB shard 时,所有的行都需要重新映射。
这种重新分配通常需要系统停机,这对您的系统来说是有风险的。
如何避免:
- 为了避免这种情况,我们可以使用一种特殊的散列技术,名为 一致散列 ,它通常只需要重新映射
k/N
个键,其中k
是键的数量,N
是数据库服务器的数量(更具体地说,是服务器的初始和最终数量的最大值)。
2.数据非规范化(关系数据库)
对于单个数据库服务器,需要连接的查询可以很容易地完成,但是我们知道在分布式架构中,数据跨越多个区域。因此,驻留在多个区域上的表的连接将需要大量的处理,并且是相当潜在的。
因此,您可能需要进行数据反规范化,以尽可能避免连接。
如何避免:
- 你也可以去 NoSQL 数据库的情况下,你想避免这一点。但是在某些情况下,你可能对关系数据库有一个确切的需求。
- 共享连接: 一般来说,为了避免关系数据库中的连接,我们尝试将同一碎片中的行的 FK 映射放在不同的表中。因此,所有需要连接的行都位于同一个片上。
为了实现这一点,我们选择可以连接的列作为 shard_key 。因此,不同表中具有相同的 shard_key 列值的行将位于同一个 shard 中。
作者图片——共享加入
在上面医院数据库的例子中,我们选择 patient-id 作为分片键。
因此,具有相同患者 id 的不同表格的所有条目将位于相同的碎片中。
3.热点关键问题
对同一分片中的一个或多个特定键的过度访问会导致节点耗尽。
也就是说,大部分请求由一小部分碎片提供服务,而其他碎片在大部分时间保持理想状态。这可能会导致节点故障或过载,从而导致延迟和故障激增。
作者图片- 大多数请求由 shard-1 提供服务
在上图中,我们可以看到大多数请求由 shard-1 提供服务,因此负载很重。而碎片-2 和碎片-3 几乎是理想的。
这可能导致 shard-1 所服务的所有请求的延迟和失败增加。
一个真实的例子是,假设脸书选择用户名作为其用户表的碎片键。所有访问量最大的个人资料,如克里斯蒂亚诺·罗纳尔多的
、Lady Gaga 的和贾斯汀比伯的最终都在同一个碎片中。那么与其他碎片相比,该特定碎片将是请求的热点。
如何避免:
- 为了避免这种情况,我们需要选择碎片键和散列函数,使得整个应用程序负载几乎平均分布在所有数据库碎片中。
结论
分片是以一种巧妙的方式抵御传入流量的绝佳方式。但是你需要确定什么时候是分片的确切需求,因为你可以看到数据分区和分片会带来很多额外的复杂性。
因此,在决定共享数据库之前,您应该考虑其他选项来提高数据库的性能,比如索引或缓存。
但是如果您仍然决定设计一个分布式数据库系统,那么您还必须考虑其他的权衡。
感谢阅读。编码快乐!
WiDS 2020 数据马拉松的另一种方法
使用随机森林分类器对 ICU 中的患者进行分类
虽然今年的 WiDS Datathon 要求数据科学家预测重症监护室中的患者存活率,但我决定对数据集提出一个不同的问题。源于几年前我参加的一个急诊医学课程,我想知道,除了宣布一个病人是否会存活,我们是否可以用存活的概率来相应地对 ICU 中的病人进行分类。
设计
问题的第一步是确定分类级别,并确定分配标签的标准。为此,我利用了 medicinenet 上展示的分类层级,并确定了以下模式。
由 Molly Liebeskind 创建的图像
为了确定幸存的机会,我在一个分类模型中预测该类‘幸存’的概率。虽然 Kaggle 竞赛基于 AUC 分数评估模型,但我在这里又一次偏离了,而是选择了针对回忆进行优化。当标记 ICU 中的患者时,我觉得捕捉所有潜在的高风险患者是最重要的,我愿意牺牲一些精确性。也就是说,我确实确保了 AUC 不会随着我的调整而显著下降。一旦我对模型感到满意,我就使用阈值调整来分配分类标签,以确定存活概率与上述模式一致的患者。
模型
我的目标是创建一个简单的模型,以便它可以在快节奏的医院环境中有效地部署,我自下而上地设计了这个模型。如下所示,使用数据字典,我根据列所属的类别将较大的数据集分成多个表。
由 Molly Liebeskind 创建的图像
从那里,我评估了存活组和未存活组之间哪些特征有显著差异,以及哪里有机会通过特征工程放大信号。当我从每个类别中选择特征时,我测试了将它们添加到两个不同的模型中,逻辑回归和随机森林,并观察了影响。
有了完整的特性集,我对两个模型都进行了调优。通过五重交叉验证,我认为随机森林优于逻辑回归和我测试的总体变化。最终代码可以在这里找到。
输出
为了证明询问数据的力量,我们可以如何对病人进行分类,而不是预测存活率,我创建了一个简单的 Tableau 仪表板,向医生和医院管理人员显示高风险病人在 ICU 的位置,以便他们可以相应地进行规划和资源配置。下面是该工具的简要演示。
板 1:用于管理人员,显示每个分流组中的患者数量、他们所在的位置以及他们从哪里进入 ICU。board 2:For physicians and filters by department in the ICU,显示该部门中每个风险级别的患者,然后提供每个患者的进一步信息以便快速获取。注意:所有患者 ID 都是我出于演示目的随机生成的,并非来自原始数据集。Molly Liebeskind 设计的仪表盘。
持续的挑战
不幸的是,这个模型的最佳特性集包括许多变量,这需要医生和患者的开销。这些特征不仅需要时间、金钱和身体耐力来为每个患者生成,而且输入结果的手动过程会妨碍该工具提供实时益处的能力。由于这只是概念的演示,真正的目标是建立一个模型,在进行医学测试时自动获取数据,并实时协助医生进行分类。
我希望你喜欢 WiDS Datathon 挑战赛的这种不同。请在下面添加任何问题或评论。作为参考,你可以在这里找到的完整代码。
可视化分类结果的不同方式
用不常见的分类图升级你的机器学习报告。
我喜欢好的数据可视化。早在我攻读粒子物理学博士学位的时候,我就被我的同事们构建的直方图和在一个单独的图中积累的信息量惊呆了。
图中的信息
改进现有的可视化方法或从其他研究领域移植方法确实具有挑战性。你必须考虑你的情节中的维度和增加更多维度的方法。一个很好的例子是从箱线图到紫线图再到群集图的路径。这是一个不断增加维度和信息的过程。
给情节添加信息或维度的可能性几乎是无穷无尽的。可以使用不同的标记形状添加类别,像热图中的颜色图可以作为另一个维度,标记的大小可以提供对进一步参数的洞察。
分类器性能图
当谈到机器学习时,有许多方法来绘制分类器的性能。有大量的度量标准来比较不同的评估者,如准确度、精确度、召回率或有用的 MMC。
所有常见的分类指标都是从真阳性、真阴性、假阳性和假阴性事件中计算出来的。最受欢迎的图无疑是 ROC 曲线、PRC、CAP 曲线和混淆矩阵。
我不会深入三条曲线的细节,但是有许多不同的方法来处理混淆矩阵,比如添加热图。
混乱矩阵的 seaborn 热图。
分类镶嵌图
在许多情况下,这可能就足够了,并且很容易获得所有相关的信息,但是对于一个多类的问题,要做到这一点会变得更加困难。
在阅读一些文件时,我偶然发现:
雅各布·雷梅克斯、彼得·j·罗瑟夫、米娅·休伯特。可视化分类结果。arXiv:2007.14495[统计。ML]
从那里到
很友好,迈克尔。"多向列联表的镶嵌显示."美国统计协会杂志,第 89 卷,第 425 号,1994 年,第 190-200 页。JSTOR ,www.jstor.org/stable/2291215.2020 年 8 月 13 日访问。
作者建议使用镶嵌图来绘制离散值。我们可以将这种想法转移到机器学习领域,将预测的类别作为离散值。
在多类环境中,这样的图看起来像下面这样:
具有四个类别的分类结果的镶嵌图。
与经典的混淆矩阵相比,它有几个优点。人们可以容易地看到 y 轴上的预测类别和 x 轴上的每个类别的数量比例。与简单的柱状图最大的不同是柱状图的宽度,它给出了阶级不平衡的概念。
你可以在这里找到这样一个带有混淆矩阵的图的代码:
祝您在绘制下一个分类结果时愉快!
对决策树的探究
马里乌斯·马萨拉尔在 Unsplash 上的照片
决策树是如何工作的?
决策树是一些最常用的机器学习算法。它们用于分类和回归。它们可用于线性和非线性数据,但主要用于非线性数据。顾名思义,决策树是根据数据及其行为做出的一系列决策。它不使用线性分类器或回归器,因此其性能与数据的线性性质无关。Boosting 和 Bagging 算法已经被开发为使用决策树的基本原理的集成模型,该决策树经过一些修改以克服决策树的一些重要缺点并提供更好的结果。使用树模型的另一个最重要的原因是它们非常容易解释。
决策树
决策树可用于分类和回归。虽然原理是相同的,但方法略有不同。决策树使用 CART 算法(分类和回归树)。在这两种情况下,决策都基于任何特性的条件。内部节点表示条件,叶节点表示基于条件的决策。
分类
决策树是基于特定条件的决策的所有可能解决方案的图形表示。
在用于分类的决策树的每个步骤或节点上,我们尝试在特征上形成一个条件,以最大限度地分离数据集中包含的所有标签或类。让我们看看这个想法是如何运作的。
比方说,上面给出的表格是我们的数据集。如果我们尝试分析数据集并基于数据集创建决策树,我们将获得类似下面给出的树
在根节点中,我们首次使用“Feat 2 ≥3”作为分离数据集的条件。我们可以看到,如果答案是假的,我们到达一片叶子,它只有标签为 3 的条目。所以,标签 3 是完全分离的。但是,如果答案是真的,我们到达一个中间节点。在这种情况下,有 3 个条目,其中 2 个属于标签 2,一个属于标签 1。因此,这个结果有杂质,因为有两个标签混合。我们对中间态应用另一个条件,得到纯分离的标签。在叶 2 上,我们仅获得了标签 1 条目,而在叶 3 上,我们仅获得了标签 2 条目。
现在,可能出现的问题是:
- 在数字特征的情况下,例如“feat 2≥3”,我们如何确定决定值?
- 我们如何决定应该使用哪些特性来创建我们的内部条件节点?
- 如何决定首先使用哪个特性,例如,在前面的例子中,我们有特性 1 和特性 2,那么,我们应该使用哪个特性作为根?
随着我们的前进,我们将会看到这些问题的答案。
在我们开始讨论这些答案的细节之前,让我们先来看看在回答这些问题时起主要作用的一些定义。
**熵:**它给出了数据中杂质或随机性的度量。它由下式给出:
熵= — P(类 1) x Log(P(类 1)) — P(类 2) x Log(P(类 2))
其中 P 表示概率。
如果有两个数量相等的类别,类别 1 和类别 2,即类别 1 的条目数量等于类别 2 的条目数量,并且我们随机选择一个条目,则它将以 50%的概率属于任何类别 1 或类别 2。在这种情况下,熵将会很高。
如果某个数据集的所有数据都属于类 1 或类 2,则获得的熵为 0,因为在这种情况下,P(类 1)或 P(类 2)将等于 0。如果 P(class1)=0,那么 P(class2)应该等于 1。因此,很明显,如果数据集中有不纯或混合的类别标签,熵将会很高。
Pr(x==1)
上图显示了标签概率随熵的变化。我们可以看到如果一个标签的概率是 0.5,熵是最大的。
如果数据集中总共有 20 个条目或行,其中 14 个属于标签 1,6 个属于标签 2,则熵将等于:
= — P(标签 1)。log(P(标签 1)) — P(标签 2)。日志(P(标签 2))
=—14/20 . log(14/20)—6/20 . log(6/20)
=0.880
**信息增益:**信息增益是数据集基于属性拆分后熵的减少。构建决策树取决于找到返回最高信息增益的属性。它有助于选择在特定点使用哪个特征或属性来创建决定性的内部节点。
它由下式给出:
信息增益=熵(s) — [(加权平均)x(每个特征的熵)
那么,这实际上是如何操作的呢?
比方说,这是我们的数据集。所以,我们有特性 1 和特性 2,它们应该是我们的根节点。上述决定是基于每个特征提供的信息增益量。所以,让我们检查一下。
首先,我们想要检查基于每个特征的标签的分布,以便深入了解一个特征将提供多少信息增益。
例如对于特征 1,
我们可以看到,如果我们选择条件“特征 1==2”,我们可以成功地将标签 2 从数据集中纯粹地分离出来。
现在,熵(E(s))=—4/10 * log(4/10)—6/10 * log(6/10)= 0.97
对于功能 1:
e(feature _ 1 = = 1)=—3/4 * log(3/4)—1/4 * log(1/4)= 0.81
e(feature _ 1 = = 2)=—3/3 log(3/3)=—1 log 1 = 0
e(feature _ 1 = = 3)=—2/3 * log(2/3)—1/3 * log(1/3)= 0.91
对于功能 1,加权平均值=
4/100.81+3/100+3/10*0.91=0.597
信息增益= 0.97–0.597 = 0.313
同样,让我们对特性 2 做同样的事情:
对于功能 2:
对于功能 2:
e(feature _ 2 = = 1)=—2/3 * log(2/3)—1/3 * log(1/3)= 0.91
e(feature _ 2 = = 2)=—2/3 * log(2/3)—1/3 * log(1/3)= 0.91
e(feature _ 2 = = 3)=—3/4 * log(3/4)—1/4 * log(1/4)= 0.81
对于特性 2,加权平均值=
3/100.91+3/100.91+4/10*0.81=0.87
因此,特征 2 的信息增益= 0.97–0.87 = 0.1
现在,我们发现特征 1 在该点的信息增益大于特征 2。因此,我们将使用特性 1 来形成根节点。
**基尼指数:**基尼指数也是一种衡量杂质的指标,用于使用 CART 机制构建决策树。
它由下式给出:
基尼系数= 1 —(“第一类”的概率)——(第二类”的概率)
让我们看看它的工作情况,
比方说,这是我们在 100 个条目的数据集上的分布。应用于特征 1 的条件给出了上述结论。
叶的基尼系数 1:1-(35/43)—(8/43)= 0.302
叶 2 的基尼系数:1 — (15/57) — (42/57) =0.38
现在,特征 1 的总体基尼系数杂质:
基尼系数的加权平均值:
=43/100* 0.30+ 57/100*38=0.34
同样,我们还计算了其他特征的基尼系数。
需要注意的一点是,如果数据集中的每个条目只属于一个类,即类 1 或类 2,
基尼杂质:1-(1/(0+1) )-(0/(0+1) )=0
因此,我们可以看到,对于一个纯粹的分布,基尼系数是 0。
Gini 杂质指数也可以用于决定应该使用哪个特征来创建条件节点。选择产生较小基尼系数杂质指数的特征,以在该点创建内部条件节点。
我们已经看到了一些概念,为了理解决策树的工作原理,我们需要知道这些概念。我想我们已经找到了第二个和第三个问题的答案,即特征是如何决定的,以及哪个特征被用来形成结论的条件。我们现在需要找到第一个问题的答案,即在连续数字特征的情况下,如何获得用于形成条件的值。
寻找最合适的值来创建条件的过程非常简单。首先,我们基于数值特征以升序方式对数据集进行排序。接下来,我们找到相邻数值对的平均值。
比方说,我们获得了如上所示的平均值。所以,avg_1=(val_1+val_2)/2。接下来,根据我们使用的方法,我们拟合条件中的平均值,以检查哪个提供了最小的基尼系数或哪个提供了最大的信息增益。平均值用作我们为该特征形成的条件中的截止值。
类似地,对于基于离散值或基于类的特征,我们尝试拟合集合中存在的每个值并创建条件。最后,我们选择给出最小基尼系数的值或条件。我们的第一个查询到此结束。
现在,我们已经看到,我们考虑基尼系数或信息增益来决定我们应该考虑哪种情况。在某些情况下,一些特征显示根本没有改进或者没有信息增益,这样的特征从不在决策树中使用。决策树就是这样进行自动特征选择的。
决策树的主要挑战之一是它会导致数据过度拟合。这主要是因为它为训练数据创建了基于条件的方法。所以,它与训练数据非常吻合。现在,对树中的训练数据应用的条件越多,树就长得越深,它就越适合数据。但是在一个点之后,它开始考虑一些特征上的非常小的变化,这给出非常低的信息增益,通常这些点破坏了模型的泛化,并且在测试数据上表现得像异常值。我们可以通过使用信息增益的阈值来限制这些条件,这样,如果条件提供的信息增益小于给定值,我们就不会考虑该条件。这部分地防止了过度拟合,并有助于创建通用模型。
剪枝是一种删除节点以获得最优解和降低复杂度的树的方法。它删除分支或节点,以便创建降低过拟合倾向的子树。一旦我们完成了回归树,我们将讨论这个概念。
回归
要理解回归树的概念,必须对回归和线性回归的概念有一个清晰的认识。如果需要,请随意阅读我关于回归的文章。
让我们考虑两个条件:
在第一个分布中,我们可以看到,我们可以很容易地拟合一条线。所以,在这种情况下,我们可以用线性回归来预测一个值。但是,在第二种分布的情况下,很明显,我们不能用任何特定的直线来拟合分布来预测值,因为分布在不同的范围内表现非常不同。换句话说,在第二种情况下,分布是非线性的。在这种非线性情况下,使用回归树。一个论点是,我们可以对非线性数据使用多项式回归,但有时分布分析和决定多项式相当复杂,因此,决策树的基于条件的方法是首选。
在回归树中,叶子代表一个连续的数值,而分类树通常在叶子上代表布尔值或离散值。
上图展示了回归树的基本结构。当多个特征加入并且特征集的维度增加时,树变得更加复杂和难以分析。
现在,让我们看看如何决定我们应该选择哪个值来创造条件。这与我们在分类树中所做的有点不同。
假设我们有一个由三个特性组成的特性集:特性 1、特性 2 和特性 3。
功能 1 的分布
让我们把上面的图像看作是特性 1 的分布。y 轴具有我们需要拟合回归的值,X 轴具有特征值。因此,我们将图表中显示的值 Val 1、Val 2 等视为构成要素 1 条件的截止值。这些值只是两个对应点的特征 1 值的平均值。现在,让我们看看计算是如何进行的。
现在,让我们考虑上面的图表。这些图不是按比例绘制的,所以 avg_2 不等于 avg_4。当我们将 val_1 视为要素 1 的临界值时,我们将线左侧点的所有 Y 值的平均值视为 avg_1,同样,我们将线右侧所有点的平均值视为 avg_2。因此,对于条件 feature 1>val_1 为真的任何值,树提供 avg_2 作为预测,反之亦然。
接下来,我们计算所有点的平方误差。因此,对于线右侧的任何点,该点的平方误差为(实际值-预测值(即 avg_2)),类似地,对于左侧的任何点,该点的平方误差为(实际值-预测值(即 avg_1))。所以,我们找到所有点的平方误差,然后求和。这叫做误差平方和。比方说,对于值 1,误差平方和是 S_1。
类似地,对于值 4,计算误差平方和为 S_4。我们可以观察到 S_4 会比 S_1 小很多。因此,我们找到所有我们观察的值的误差平方和,作为创建条件的截止值。如果我们绘制它们,我们将获得如下所示的图。
在上图中,我们可以看到特征 1 的 val_4 提供了该点的最小误差平方和。现在,我们已经看到了特定值的截止值是如何确定的。
现在,如果我们有多个特征,如何决定我们应该使用哪个特征来创建节点。为此,我们创建候选人。例如,对于特征 1,val_4 给出最小的误差平方和。因此,它被称为功能 1 的候选。类似地,我们找到特征 2 和特征 3 的候选者。假设特征 2 的候选对应的 SSR 是 S2 _ 3,特征 3 的候选对应的 SSR 是 S3 _ 5。我们将比较 S_4、S_2_3 和 S_3_5,并选择最小值。对应于最小值的特征将被用于创建决定节点。
上述方法被递归地用于创建回归树。至此,我们已经看到了 CART 机制是如何工作的,以及分类树和回归树是如何形成的。现在,简单回顾一下树木中一个非常重要的概念:修剪。
修剪
该方法用于树中以减少过度拟合。这是一个减少树的节点和分支以减少树的深度的过程。
上图显示了修剪的概念是如何工作的。
基本上有两种类型的修剪:
- 预修剪
- 后期修剪
在预修剪中,我们在创建树的过程中设置参数,如“最小样本数”、“最大深度”和“最大叶子数”。所有参数都需要超参数调整,并使用交叉验证和网格搜索方法找到。它将树限制在一定的深度或一定数量的叶子。
后期修剪方法大多是在树已经形成之后进行的。成本复杂性修剪是最常用的后修剪方法。
结论
决策树具有巨大的重要性,因为它们在 bagging 和 boosting 的情况下形成了集成学习模型的基础,bagging 和 boosting 是机器学习领域中最常用的算法。同样,由于其简单的结构和可解释性,决策树被用在一些人类可解释的模型中,如 LIME。
在本文中,我们已经看到了决策树是如何使用 CART 原理工作的。
希望这有所帮助。
元数据中心工具探究
如今,“元数据中心”正在发生一些变化
作者图片
元数据中心(有时也称为元数据搜索和发现工具)似乎是分析领域正在发生的另一种趋势/运动。仅在过去的两年里,我们已经看到许多元数据中心项目被主要的技术公司发布、撰写或开源。其中包括:
- Airbnb 的数据门户
- 网飞的元卡特
- 优步的数据手册
- LinkedIn 的数据中心
- Lyft 的阿蒙森
- Spotify 的 Lexikon
- 以及谷歌云平台的数据目录(虽然我只是把它包括进来,因为它看起来像是对当前市场上元数据中心趋势的回应)。
在这篇文章中,我将快速总结这些产品旨在解决的问题,快速概述每个项目,然后深入研究看起来最有希望的两个项目:LinkedIn 的 Datahub 和 Lyft 的 Amundsen。
什么是元数据中心?
假设您是一家大型公司的数据用户或数据分析师,该公司在全球有许多办公室。您的数据组织分布在这些位置,您在不同的数据仓库和 BI 工具中有数千个表,还有分布在整个公司不同分析阶段的数百个报告、数据集和数据模型。你需要找到你需要的报表,或者你想要的数据集。如果你找不到这些东西,那么你需要找到下一个最好的东西:你需要知道向谁询问,或者向组织中的哪个团队询问。
进入元数据中心。
元数据中心的目标是充当公司内整个数据生态系统的“搜索引擎”。名称中的“元数据”意味着“关于数据的数据”。这包括表模式、列描述、访问记录以及与每个数据库或数据仓库相关联的 SLA 等信息,还包括“哪个团队负责这个数据集”以及“最后一个从这个数据集创建报告的人是谁?”
当然,正如 LinkedIn 数据中心的 Mars Lan 所说:“如果你能通过问你公司的一个人来找到所有东西的位置,那么你肯定不需要这个。”只有当您是一个大型组织,并且您需要跨整个组织扩展数据访问时,元数据中心才变得重要。你会听到像“数据民主化”和“数据可发现性”这样的词被抛来抛去;他们真正指的是随机数据分析师跟上一个非常大的数据生产和数据消费组织的能力。
只有当您是一个大型组织,并且您需要跨整个组织扩展数据访问时,元数据中心才变得重要。
概括地说,我上面提到的所有元数据中心项目都提供了以下内容的某种组合:
- **搜索:**终端用户的搜索界面。
- Discovery: 一个可探索的界面,供用户浏览和导航不同的数据源,并深入到表或行级别。
- **自动化:**一个 API 服务,公开元数据供其他内部数据服务使用。
- **管理:**选择、保存和管理元数据集合的能力。
某些项目,如 Airbnb 的 Dataportal 和 Spotify 的 Lexikon,能够公开用户资料,以便你可以找到最近接触过你感兴趣的数据集的个人或团队。但其他人没有。
这些项目,简单来说
我将按时间顺序浏览这些项目,如果你愿意,我会给你足够的外部链接,让你可以去寻找最初的公告帖子、存储库(如果有的话)和技术讲座。但是,如果您想了解好的部分,我建议您浏览这一部分(特别注意关于 Amundsen 和 Datahub 的部分),然后跳到下一部分,在那里我将比较这两个项目。这两个人似乎是目前社区活动最多的人。
Airbnb 的数据门户,2017 年 5 月 11 日
Airbnb 公布数据门户的博文截图。到目前为止,它不是开源的,也没有任何更新。图片作者。
这个列表中最早的项目是 Airbnb 的 Dataportal。克里斯·威廉姆斯和约翰·博德利在 GraphConnect Europe 2017 的舞台上首次描述了 Dataportal(此处提供幻灯片)。一天后,也就是 2017 年 5 月 12 日,他们发表了一篇博文,描述了这个系统。
Dataportal 跟踪谁在 Airbnb 内生产或消费数据资源。该项目将这些关系建模为 neo4j 中的图表,这意味着他们可以提供一个搜索引擎,使用 Pagerank 算法,将这些关系展现给用户。
Dataportal 从来都不是开源的,有趣的是,它也没有出现在https://airbnb.io/projects/上。从那以后我们再也没有听说过这件事。
网飞的 Metacat,2018 年 6 月 15 日
大约一年后,网飞发表了一篇博文描述他们的元数据系统,命名为 Metacat。这个项目是为了填补网飞数据栈中的一个漏洞而构建的——本质上,他们需要一个元数据服务来介于他们的 Pig ETL 系统和 Hive 之间。
Metacat 系统是网飞数据基础设施中的一个联合服务。它提供了一个统一的 API 来访问网飞内部生态系统中各种数据存储的元数据,但它是根据网飞自己的工具和数据堆栈高度定制的。它看起来没有特别好的可扩展性。
Metacat 的 Github 页面。作者照片。
Metacat 是开源的,正在积极开发中,但似乎不是为外部采用而设计的。截至发稿时,他们的 Github 自述文件包含一个标题为“Documentation”的部分,下面写有“TODO”字样。
优步的数据手册,2018 年 8 月 3 日
优步的数据手册是在网飞的 Metacat 发布后一个月左右在一篇博客文章中公布的。
优步公布数据手册的博客文章——作者照片。
Databook 从 Hive、Vertica、MySQL、Postgres 和 Cassandra 获取元数据,并在一个界面中展示表模式、列描述、来自数据库的样本数据、统计数据、沿袭、新鲜度、SLA 保证和数据所有者等内容。它还允许 Databook 用户在其用户界面中组织和管理这些元数据。在早期阶段,Databook 建立在一个爬虫架构上(也就是说,Databook 将运行爬虫,从各种数据源收集元数据),但随着时间的推移,优步的数据工程团队最终将系统切换到一个建立在 Kafka 之上的系统。他们还从 MySQL 转换到 Cassandra,以便支持多个数据中心,同时不会增加延迟。
Databook 并不是开源的,我们也没有听说过它。据推测,它仍然在优步广泛使用。
Lyft 的阿蒙森,2019 年 8 月 3 日
Lyft 的 Amundsen 是在 2019 年 8 月 3 日宣布的,然后几个月后开源,同年 10 月 31 日。
阿蒙森的书出版后引起了一些轰动。dbt 的 Tristan Handy 写了关于 Amundsen 开源的:
这款产品非常重要,我真的相信在未来五年内,该产品类别将成为数据领域最重要的产品类别。所有东西都需要放入目录中。
阿蒙森的 DNA 中有过去系统的痕迹。与 Dataportal 一样,它允许您在公司内部搜索数据资源,并为它可以访问的每个数据源中的每个表公开一个可发现的界面,一直到行级别。在发布时,创建者还谈到了他们打算如何与 Workday 等工具集成,以便在 Amundsen 的搜索图中显示员工信息,这样您就可以联系到与您感兴趣的数据集有关联的同事。
Lyft 的博客文章宣布阿蒙森。作者照片。
Amundsen 由许多不同的部件组成(来源):
- 元数据服务处理来自前端服务以及其他微服务的元数据请求。默认情况下,持久层是 Neo4j。
- 搜索服务由 Elasticsearch 支持,处理来自前端服务的搜索请求。这个搜索引擎也可以被替代。
- 前端服务是一个 Flask webapp,托管一个 React 前端。这是用户交互的主要界面。
- Databuilder 是一个通用的数据摄取框架,它从各种来源提取元数据。它受 Apachegoblin的启发,作为 ETL 工具将元数据推送到 Amundsen 的元数据服务中。它使用气流作为工作流程工具。
- 最后, Common 是一个库 repo,它保存了阿蒙森所有微服务的公共代码。
在阿蒙森发布的博客文章中,作者注意到发现数据假象的时间已经降低到阿蒙森之前基线的 5%。阿蒙森的社区可能是这里涵盖的所有项目中最大的,并且它今天仍在快速增长。
领英的数据中心,2019 年 8 月 14 日
宣布在阿蒙森之后不到两周,LinkedIn 的数据中心实际上是他们建立元数据中心的第二次尝试。2016 年,LinkedIn 开源了 WhereHow ,这影响了本文提到的其他一些项目。但 Datahub 是从头开始编写的,旨在解决 LinkedIn 在 WhereHow 方面遇到的一些问题。
最有趣的是,Datahub 建立在“基于推送”的架构之上。这意味着必须修改组织中的每个数据服务,以便将元数据推送到数据中心,而不是让数据中心从服务中抓取数据。在实践中,这并不太难做到,因为 Datahub 是建立在 Kafka 流之上的,Kafka 已经在 LinkedIn 中广泛使用(Kafka 是在那里创建的)。
DataHub 的 Github 页面。你可以看到这个项目正在进行中。作者照片。
Datahub 的架构带来了许多有趣的好处。首先,它允许增量摄取(而不是每隔一段时间进行一次抓取或快照)。其次,它允许近乎实时的更新,因为任何推送到数据中心的更改都会立即传递给下游用户。火星兰,创作者之一,笔记(播客;大约在 18:20 左右)这种设置允许您构建使用从 Datahub 发出的 changestream 的应用程序,并且他们已经在 LinkedIn 中广泛地这样做了。
事实上,整集播客值得一听。Lan 谈到了他们在 Datahub 中提出可扩展但通用的数据模型时需要做出的一些权衡(“当人们花 90%的时间讨论如何正确地对元数据建模,然后花 10%的时间实际编码时,你知道你已经成功了。”).它让你感受到工程师们给这个项目带来的丰富经验。
Datahub 在今年二月被开源。稍后会有更多的介绍。
Spotify 的 Lexikon,2020 年 2 月 27 日(尽管建于 2017 年)
Spotify 的 Lexikon 与之前的项目覆盖了大部分相同的领域。Lexikon 的最初版本建于 2017 年,以应对 Spotify 转移到 GCP 和 BigQuery 后数据集的爆炸。
Spotify 公布 Lexicon 的博文。到目前为止,这个项目还没有开源。作者照片。
该项目的最新颖之处在于,它为数据用户提供了算法生成的个性化数据集建议。(如果你仔细想想,这是 Spotify 应该做的事情)。像 Dataportal 一样,Lexikon 提供了一种搜索体验,同时也提供了可能对你正在查看的数据集有所帮助的用户。像 Amundsen 和 Datahub 一样,Lexicon 向您显示表级和列级的统计信息。
Lexikon 不是开源的。
谷歌云的数据目录,2020 年 5 月 1 日
谷歌云的数据目录是一种类似的元数据服务,但它只适用于 GCP 服务,如 BigQuery、Pub/Sub 和云存储文件集。这个想法是,你将数据目录添加到一个现有的 GCP 主持的项目中,打开开关,享受谷歌数据目录的好处。
我只包括这个项目有两个原因。首先,谷歌宣布它已经在 2020 年 5 月 1 日全面上市,就在不久之前。对于外部观察者来说,这似乎是对该领域当前活动的回应,这对整个数据生态系统来说是个好兆头。
其次,谷歌表示,数据目录是建立在从他们的商品数据系统中提取的洞察力之上的,该数据系统过去是(现在是?)作为一种非常有效的数据目录服务在谷歌内部使用了很多年。描述这个系统的论文可以在这里找到。
观看阿蒙森和数据中心
在这组项目中,Amundsen 和 Datahub 似乎是领先者。阿蒙森有一个热闹的社区,一个非常时髦的 网站,以及许多有趣的案例研究:edmunds.com、 ING 和 Square 。其他采用 Amundsen 的公司包括 Workday、Asana 和 iRobot。
Amundsen 在 Datahub 上有一点领先,因为它在去年 10 月开源。社区更大,截至 8 月 11 日,阿蒙森现在是 Linux Foundation 的 AI 基金会孵化项目。更重要的是,你可以在新闻稿中看到项目创建者 Mark Grover 的声明:
“成为 LF AI 基金会的一员是该项目在成为事实上的开源数据发现和元数据引擎的旅程中的一个重要里程碑。看到 Lyft 采用 Amundsen,以及其开源社区的增长,现在已经有超过 750 名成员,真是令人惊讶。我很高兴看到这个项目在 LF AI 基金会的支持下持续增长并取得成功。”
另一方面,Datahub 应该受到重视,因为 LinkedIn 在开源项目方面的记录(他们创建了 Kafka,然后开源了 Kafka,Kafka 现在是云基础设施领域的一个主要项目,Datahub 建立在 Kafka 之上*……用创建者的话说,使扩展它的工作成为一个“解决的问题”)。根据他们的 Github 页面,采用 Datahub 的组织数量也相当可观:其中包括 Expedia、Saxo Bank、TypeForm 和 Experius 等公司。*
这是值得注意的,因为 DataHub 仅在六个月前开源。Mars Lan 和 Pardhu Gunnam 最近在数据工程播客上接受了采访,他们指出,采用的速度和不断增长的社区让他们有些吃惊。兰还认为,他们的方法优于市场上的其他任何方法,因为四年多前在 LinkedIn 内建立 WhereHow 的经验来之不易(应该指出,兰没有参与 WhereHow,但 WhereHow 的使用为 Datahub 的设计提供了)。
结论
当我写这篇文章的时候,距离这些项目公开发布已经一年多了,距离开始采用开源还不到一年,距离它们成熟还有很长的路要走。
鉴于这些项目解决了非常相似的问题,并得到了强大的技术公司的支持,而且大多数项目都选择了开源方法,看看哪些项目会走在前面以及是什么让它们这样做将会很有趣。
推动分类数据的测试
阿克希特·普里耶什
什么是数据的分类分析?
C 分类数据分析是将响应变量分成一组互斥的有序(如信用评分组)或无序(如贷款类型)类别的数据分析。
用更简单的话说
在统计学中,我们使用总体样本进行分析,在该样本中,属于特定组的数据点总数称为频率,因此这种分类数据分析称为频率分析。定量描述一组数据特征的研究称为描述统计学。频率分析是描述统计学的一部分。在统计学中,频率是一个事件发生的次数。频率分析是统计学的一个重要领域,它处理出现的次数(频率)并分析集中趋势、离差、百分位数等的度量。对于这种频率分析,我们有许多统计测试。我们将在本文中讨论一些重要的测试。
卡方检验
这是最常见、最常用和最重要的假设检验之一。一个卡方检验,也被写为T5χ2 检验,是一个统计假设检验,当检验统计量在零假设下为卡方分布时有效执行,特别是皮尔逊卡方检验及其变体。皮尔逊卡方检验用于确定在列联表的一个或多个类别中,预期频率和观察到的频率之间是否存在统计显著性差异。
卡方检验有两种类型**。两者都将卡方统计和分布用于不同的目的:**
卡方拟合优度测试确定样本数据是否与总体匹配。
一个卡方独立性检验比较列联表中的两个变量,看它们是否相关。在更一般的意义上,它测试分类变量的分布是否彼此不同。
- 非常小的卡方检验统计量意味着您的观察数据与您的预期数据非常吻合。换句话说,是有关系的。
- 非常大的卡方检验统计量意味着数据不是非常吻合。换句话说,没有关系。
用简单的话,用简单的例子
卡方检验给出了一个“p”值来帮助我们决定哪一个应该是完美的和首选的蜜月目的地。
举例。阿克希特·普里耶什
性别影响蜜月目的地吗?
如果性别确实影响首选蜜月目的地,我们说他们是依赖。
通过简单的计算,我们可以很容易地找到 p 值。
p 值为 0.101
现在, p < 0.05 是对依赖性的通常测试。
在这种情况下 p 大于 0.05 ,因此我们认为变量是独立的**。**
换句话说,男人和女人可能对泰姬陵和巴黎有不同的偏好,而不是 T21。这只是我们在收集数据时预期的随机差异。
卡方公式。
使用 python 进行卡方检验
t,p = stats.chisquare(dataframe)
费希尔精确试验
从前面的例子中,我们知道卡方检验是近似的,所以我们需要一个精确的检验。对于这个精确的测试,费希尔的精确测试进入了框架。
费希尔精确检验是一种用于列联表分析的统计显著性检验。尽管在实践中,当样本量很小时使用它,但它对所有样本量都有效。
使用 python 导入
stats.fisher_exact
它返回 p 值,用于查找极端值或比观察值更极端的值。
例如,x 是度假目的地海滩或山区,y 是旅游目的地海滩或山区的数量。如果果阿旅游了 5 次,珠穆朗玛峰旅游了 1 次,果阿没有山和 4 个不同的海滩。那么相关的矩阵将是
举例。阿克希特·普里耶什
实际上总和为 1。小于或等于 Pcutoff= 0.0238 的 p 值之和是 0.0476,因为它小于 0.05,所以有效。因此,在这种情况下,在目的地和出现的目的地类型之间将存在统计上显著的关联。
麦克内马试验
在统计学中,麦克内马检验是一种用于成对名义数据的统计检验。它应用于具有二分特征的 2 × 2 列联表,具有匹配的受试者对,以确定行和列的边际频率是否相等。它是以奎因·麦克尼马尔的名字命名的,他在 1947 年引进了它。
在 python 中
从 statsmodels.sandbox.stats.runs 导入 mcnemar
科克伦 Q 检验
在统计学中,在双向随机区组设计的分析中,响应变量只能采用两种可能的结果,Cochran 的 Q 检验是一种非参数统计检验,用于验证 k 处理是否具有相同的效果。它是以科克伦命名的。
在 python 中
从 statsmodels.sandbox.stats.runs 导入 cochrans _ q
**结束注释
本文的重点是收集&演示分类数据测试的概念。这种方法提供了一个自然的框架来处理参数和模型的不确定性,并且已经变得非常流行,特别是在像机器学习这样的领域。然而,它的计算量要大得多,因此通常需要借助现有的工具(如 statsmodels 或 stats)来实现。这也显示了像 Python 这样的自由和开放语言的优势之一,因为它们提供了一种建立在科学界现有工作基础上的方法,并且只需要我们的热情和奉献。**
错误的选择:拯救生命还是拯救经济
生命可以被拯救,但经济总是会受到冠状病毒的沉重打击
编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里 。
周日晚上,川普总统在推特上表示,他不希望解决新冠肺炎问题的方法比问题本身更糟糕。其他人,包括非常严肃的人如埃隆·马斯克和杨安泽,都说对抗病毒的经济损失超过了如果我们选择什么都不做或反应软弱可能导致的死亡。得克萨斯州副州长丹·帕特里克说得更直白,他认为很多祖父母会愿意为他们的孙辈牺牲经济。
这种思维有两种解读方式。一是人们不相信公共卫生专家的说法,即冠状病毒的致命性是季节性流感的十倍,季节性流感在美国每年导致 3-4 万人死亡,即使有疫苗(冠状病毒疫苗可能要到明年的 T32 才能准备好)。另一个解释是,美国老年人的生命没有得到适当的重视,这比专家对病毒危险的估计更有可能是不正确的。
珍惜生命
人们怎么能把这些生命的价值与试图拯救它们的代价相比较呢?人们可能会觉得生命是无价的,但保险公司和政府机构等组织会给人的生命贴上价格标签,以衡量不同的政策决定。以 2020 年的美元计算,美国环保署估计一个人的生命价值为 1050 万美元。这比其他估算生命价值的方法都要高,比如用一个人一生的收入来估算(2020 年价值 280 万美元)。但它抓住了人们在经济贡献之外还有价值的直觉。
利用环境保护局的生命价值和其他一些指标,人们可以比较不同政策选择的成本。我们有按年龄组估计的病毒致命程度,我们知道每个年龄组有多少人。我们还对最终处于严重或危急状态的冠状病毒病例的比例以及每种类型的病例可能花费的费用有所了解。最后,研究人员估计了在人们行为的各种假设下,病毒的致命性。
在没有政策应对措施和很少或没有行为应对措施的情况下,早期最坏情况估计冠状病毒将在美国导致 170 万到 220 万人死亡。然而,这种灾难不太可能在现实中发生。即使政府对这样的疫情无所作为,人们也会改变他们的习惯,许多其他机构如企业和学校也会改变他们的行为来减缓病毒的传播。更有可能的情况是,死亡人数估计在 20 万到 48 万之间,中间值为 34 万,是季节性流感每年死亡人数的十倍。
比较政策成本
下表显示了将所有这些数字放在一起的结果。很难说当前的政策会属于哪种情况。尽管鉴于迄今为止的行动,我们不太可能看到最坏的情况估计,但根据图 1 所示的数据,很明显,美国的反应看起来更像意大利,而不是中国或韩国。我的假设是,目前的政策符合更有可能的 20-48 万人死亡的估计。
更有可能的情况是直接成本占 GDP 的-1.2%到-2.8%。这包括 160 万或更多重症或危重病例的住院费用以及生命价值损失。这还不包括不能因集中资源治疗冠状病毒而造成的影响(在最糟糕的情况下,这一影响会更高)。这些数字也不包括对经济的后续影响。
高盛估计由于公共卫生状况,经济将在 2020 年收缩 3.8%。但总的影响不仅仅是-3.8%,而是这种增长与没有冠状病毒的情况有多么不同。过去五年的平均经济增长率为 2.3%,但在病毒来袭前市场预计会出现衰退。我的方法使用了一个介于平均增长率和 1990 年、2001 年和 2009 年的平均值 0.3%之间的值,结果为 1.3%。总体而言,该病毒的经济影响为 GDP 的-5.1%-3.8%-1.3%。
这个数字应该与更可能发生的情况的直接成本结合起来,以计算我们当前政策的总成本,结果是 GDP 的-6.3%到-7.9%。与最坏的情况相比,这个成本就相形见绌了。无所作为的直接成本(不包括经济状况)估计为 GDP 的-9.8%到-12.7%,远远高于现行政策。
面对威胁,人们会改变行为
然而,说什么都不做就意味着经济将继续沿着同样的增长道路前进是错误的。最糟糕的情况表明,1370-1780 万人将因严重或危急病例而住院。由于对人们产生了如此巨大的影响,从某种意义上来说,一旦佛罗里达的春假孩子因为危及父母和祖父母的安全而受到严厉指责,他们就会停止外出。联邦政府之外的机构会制定政策来保证人们的安全。综合来看,这些措施会减缓经济增长。
即使美国选择什么都不做以避免衰退,其他国家仍然会让关闭他们的大部分经济活动,这将会减缓全球经济,降低美国的增长。我在这里的假设是,在最糟糕的情况下,对美国经济的影响将是一半(-2.6%,而不是-5.1%),导致总成本为 GDP 的-12.4%至 15.2%,远远高于美国迄今为止采取的黯淡应对措施的成本。
如果一个人对生活有不同的价值观,或者认为经济在最坏的情况下会更好,那会怎样?任何人都可以在这里下载电子表格模型,并利用输入来观察影响。这些结果对许多关于最坏情况下经济增长和生命价值的合理假设选择是稳健的。
但是拯救经济需要多少成本呢?
这篇文章的早期反馈正确地指出,目前国会正在辩论的财政刺激方案(约 2 万亿美元)的价格高于当前的政策(占 GDP 的 7.1%,约 1.5 万亿美元)。然而,财政刺激计划旨在让经济恢复活力,目标是让经济比没有刺激时增长得更快。
这意味着刺激的净成本低于其初始价格。例如, TARP 是一项 7 亿美元的计划(实际投资约 4 亿美元),旨在帮助 2008 年金融危机后的最终实现盈利。很难说这项刺激计划的最终成本是多少,但值得指出的是, 2017 年特朗普减税仅在 2018 年就使政府收入减少了大约5000 亿美元。危机过后回到奥巴马时代的收入水平将有助于为当前的刺激买单。
人们不仅仅是经济贡献者
事实是,从来就没有什么也不做的选择。各州命令人们就地避难是一件好事,这不仅仅是因为拯救生命的价值。上面的功利算计,错过了以尊严和尊重待人的价值。这种尊重有助于一个有凝聚力的社会,并支持个人权利。
未来的问题是,特朗普政府和州/地方政府会坚持到底吗?我最担心的是,人们会变得如此担心经济,以至于放松限制和他们自己的个人安全措施,这将导致病毒传播的死灰复燃,就像在台湾看到的那样。鉴于迄今为止的经济损失和许多人对传播病毒的恐惧,放松限制不太可能让经济起死回生。
数据仓库和脚本可以在 这里找到 。
虚假的安全感
或者,当投资公司告诉你他们进行了 1000 次模拟时,你为什么要小心翼翼
所以,几天前,我和我爸爸就如何处理我银行里的一些现金发生了一点小争执。我想用这笔钱来产生比大多数银行提供的可怜的 0.5%的利率更好的利率。我父亲更倾向于把我的钱存放在一个随机的顾问那里,并相信他们会投资,而我更倾向于自己管理这笔钱。由于无法得出结论,我们决定进行一次实验,并决定以 2:1 的比例分割这笔钱,将 2/3 的钱存放在这家新的、受欢迎的投资公司,并将 1/3 的钱留给我投资。
然而,当我开始调查这家公司时,我变得有点警惕——特别是因为他们一直宣传自己是一家“数据驱动”的公司,并拥有所有这些很酷的图形。下面是文章大纲(和 TL;博士)
TL;博士;医生
- 这家公司是新加坡金融公司,拥有数据驱动解决方案和专有系统
- 问题:
a .模拟的不准确性/不可靠性:模拟/模型的准确性取决于其输入的准确性。如果输入一开始就有缺陷,那么运行一个模型 1000 或 1000000 次并不会提高它的预测准确性。因此,他们的 1000 次模拟预测并不令人印象深刻。
b .历史回报+费用:历史回报(公司用于预测)从不具有指示性或提供未来回报的确定性。此外,费用会影响回报率。 - 结论:投资公司做这样的预测没有错,但作为消费者,我们必须意识到,它们并不总是最准确的
公司
该公司标榜自己是一家“总部位于新加坡的 金融科技公司 ,让人们能够掌控自己的财务未来”。我强调了“金融技术公司”部分,因为这是这家公司真正高度推销自己的地方,将这种“先进”的技术方法与传统的财务顾问形成对比。他们的使命声明继续解释说,他们使用“专有系统,在构建个性化解决方案时提供数据驱动的财富建议。”哇——对普通人来说,这一切听起来真的很酷,而且(用新加坡的俗语)很俗气。数据驱动的建议?专有系统?帮我报名吧,宝贝。
当你第一次在他们那里开户时,你可以选择设定一些财务目标。你投入你的初始投资,你的每月供款,以及你的风险承受能力(用最大提取百分比表示)。这就是令人印象深刻的数据奇迹发生的地方。在运行了一些密集的计算后,它吐出了一个预计的投资组合增长图(基于 1000 次 模拟;是的一千)。它看起来是这样的:
很漂亮不是吗?因此,这种所谓的数据驱动方法似乎向潜在投资者传达了这样的信息——嘿!我们使用一些尖端技术来管理您的资金,因此您可以信任我们。但是事情是这样的…真的有那么令人印象深刻吗?让我们找出答案。
问题
模拟的不准确性
首先,运行 1000 次模拟听起来很酷。我的意思是,如果我们尝试 1000 次,它肯定是准确的,对不对?但是让我们回顾一下,想想这意味着什么。运行 1000 次模拟以获得一系列可能性可以被认为是蒙特卡洛模拟**。这被定义为任何“当随机变量的干预存在时,用于预测不同结果的概率的模型”。本质上,它允许您使用重复采样来解释潜在的随机性。**
这真的是一个“先进”的概念吗?当然,这听起来和看起来令人印象深刻,但实际上很容易复制。因此,我创建了一个函数来估计回报,给定预期回报和标准差(这也是模拟的另一个关键问题,我们将在后面讨论)
创建函数后,我运行了一个循环,允许用户输入他们的初始投资、年回报率和标准偏差(根据公司的模拟)。
在我的模拟中,我使用了他们 60/40 投资组合的年回报率和标准差——这是一个保守但面向增长的策略。
how much is your initial investment? 10000
What is the yearly rate of return? 0.0771
What is the standard deviation of return 0.0870
How many years are you investing for? 30
How many times to simulate? 1000
在输入我的设置(遵循给定的回报率)后,我计算了投资组合的第 10 个百分点、中间值和第 75 个百分点(模仿公司模拟给出的结果)
The median return of the portfolio is 71657.24\.
The 10th percentile is 38651.81 and the 75th percentile is 96055.78\. The highest amount is 438889.69, and the lowest is 16925.8.
将我的结果与他们的进行比较(如下图),我必须说这是非常接近的。我的模拟超出了中位数约 7000 美元,但这很可能是因为我没有考虑费用等因素。前 25%的人也超出了大约 6000 美元,但后 10%的人非常相似,只有大约 2000 美元的差异。总的来说,我对这个结果很满意。
在这一点上,你可能会说,“扎克!看到了吗?太准了!这家公司有什么让人不喜欢的地方?”这让我想到了模特的问题。模型的输出完全取决于模型的输入。这似乎是显而易见的,但这正是这些花哨的萨满的问题,告诉你他们运行了 1000 次模拟。我可以运行 1,000,000 次模拟(事实上我确实这么做了),如果我的输入完全错误,它不会增加我的准确性一点。例如,我用不同的输入再次运行这个模型(并模拟 10,000 次)。
我运行这个模型 10,000 次会让它更精确吗?不要!如果我的输入是有缺陷的(在这种情况下,70%的年回报率),我的输出仍然是有缺陷的,不管我运行了多少次模拟。因此,这些东西看起来很好,很花哨,但它们不能成为“准确性”的标志,因为它们严重依赖于输入。这就引出了我的下一个观点…
历史回报+费用
作为一家公司,该公司自 2010 年代末才成立,因此预期回报率来自他们所投资基金的历史回报率。预计回报率,当用图表表示时,看起来像这样:
标准差为 8.7%,这意味着有 68%的机会(一个标准差),你的年回报率将在 6.9%和 8.4%之间。原则上,该公司不“选股”,而是通过买入股票和债券 ETFs 共同基金(并为智能再平衡收取管理费),帮助客户实现多元化。因此,预测的不是公司投资组合的历史回报,而是这些基金历史回报的合并(加权)!我们都知道使用历史回报的问题……正如 David Blanchett(晨星投资管理公司退休研究负责人)指出的那样,使用历史回报来衡量未来回报“隐含了历史事件的重复发生,并且只考虑了有限的数据”。此外,他认为,“蒙特卡洛工具的一个问题是,它们往往能描绘出一幅不切实际的回报图景”,给人一种确定性的假象,而实际上,“确定性要小得多”。
另一个影响回报的潜在因素是费用。我明白每一笔投资都要收费。毕竟,有人要拿的工资来维持公司运转。该公司将其 0.6%的费用(低于 20 万美元的投资组合)与行业平均水平约 2%进行了比较。虽然这个数字肯定更低,但我们必须再次记住,这家公司本身并不是一家投资公司。相反,他们将资金分配到基金中,而基金经理就是投资这些资金的人。这些基金也收取管理费(合计约 0.5%)。
结论
那么,这一切给我们留下了什么?我写这篇文章的意图并不是要败坏这家公司的名声,或者阻止任何人投资这种“数据驱动型”投资公司。相反,通过剖析该公司背后的“奇特”技术,我想提出两个关键点。
- 首先,警惕漂亮的视觉效果和 cheem sounding 的东西。运行 1000 次模拟听起来真的很酷,但你必须记住,一个模型的预测输出只和它的输入一样准确。如果输出不准确,1000 或 100 万次模拟真的不会对模型的准确性产生太大影响。
- 第二,历史回报不能为未来回报提供确定性。我们当然可以用历史回报来估计未来的回报,但我们需要记住,无论图表看起来有多好,都没有确定性。
所以,我没有责怪他们。该公司显然收取较低的费用,而且确实有健全的多样化战略等。但是,作为一个潜在的投资者,请注意,他们作为“优势”呈现的美丽的数据驱动模型是有局限性的。
最初发表于https://zachlim98.github.io/me/。
一个幻想草案秩序彩票使用 R 闪亮
作为 web 应用程序编写的 NBA 风格的彩票系统
迪伦·诺尔特在 Unsplash 上的照片
新冠肺炎影响了体育运动,进而影响了梦幻体育运动。然而,我们的梦幻足球联盟仍然准备好为一个不确定的赛季进行选秀。我们的联盟竞争激烈,为了确保没有人在第一次选秀权时出局,我们实施了 NBA 风格的抽签系统,让每个人都有机会获得梦寐以求的第一次选秀权。在本文中,我将解释如何为我们的梦幻联盟创建一个 web 应用程序来实现 NBA 风格的彩票系统。
NBA 风格彩票(加权彩票)
NBA 在 1990 年采用了加权抽签系统,给战绩最差的球队最好的机会获得状元签。与 NBA 内的加权彩票系统相关联的赔率多年来一直在调整,以减少彩票中最佳球队的第一次整体选秀权的数量,并减少最差球队获得第一次整体选秀权的整体赔率,以防止故意失败。在我们的联盟中,第一次选秀权没有保证的威慑和最后一次选秀权的耻辱目前足以防止任何故意的失败。
我们的系统
2 的幂有一些美丽的东西,我们的系统以 2 的幂增加了赢得第一次选秀权的几率。联赛冠军只有一次机会(0.1%)赢得第一次选秀权。亚军有 2 次机会(0.2%)赢得第一次选秀权。第三名和第四名的赔率分别为 0.4% (4 次机会)和 0.8% (8 次机会)。你看到一种模式出现了吗?这种情况一直持续到我们联盟的最后一名,有 512 次机会或 50%的几率赢得第一次选秀权。
代码
当我们实现这个系统时,我们同时使用了 R 和 python,但是为了本文的目的,我们将只详细描述 R 版本。*** 注意:R 和 python 会有不同的结果,因为两者之间的随机数生成器不同。*** 为了实现我们的系统,我们创建了长度为 N 的联盟成员姓名列表,N(机会的数量)由他们的位置决定。
## Create Member Lists of Length N by Finish Position
first <- "Mack"
second <- rep("Colin", 2**1)
third <- rep("Frank", 2**2)
...
last_place <- rep("Matt", 2**9)
为了简洁起见,上面的代码被截断了,但是,一旦我们有了不同大小的列表,我们就将列表名称汇集在一起并随机抽样。这就是设定种子发挥作用的地方,我们使用年份作为设定种子以获得可重复性。最后,在随机抽样之后,我们通过使用 unique 命令返回成员名称的第一次出现来返回选择顺序。
## Establish set.seed
year <- 2020
set.seed(year)## Pool and randomly sample
pool <- c(first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, last_place)sampled_pool <- sample(pool)## Get unique output
pick_selection_order <- unique(shuffled_pool)
让联盟中的每个人都可以使用它
为了增加程序的透明度,我们使用 R Shiny 创建了一个 web 应用程序。运行应用程序的代码可以在我的 GitHub 上找到。在本地运行应用程序需要闪亮的包。由于输入被列为选项,web 应用程序目前只适用于我们的联盟。为了使它对你的联盟来说是独一无二的(如果你有 10 名球员),只需在应用程序中的每个位置改变列表。
selectInput("last", h5("Select the Loser"),
choices = c("Mack", "Fish", "Todd", "Colin", "Andrew",
"Jake", "Frank", "Matt","Cody", "Jim"))
在Fantasy _ Draft _ Order**可以通过 shinyapps.io 访问 web 应用。**下面是应用程序的截图。
[## 草稿订单生成器
我们梦幻联盟的梦幻选秀订购工具 glickman.shinyapps.io](https://glickman.shinyapps.io/Fantasy_Draft_Order/)
马特是最后一名,以第三顺位结束比赛。坏运气和糟糕的幻想足球。
我们专员的智慧
敬我们英明的专员!
虽然该应用程序由专员运行并在联盟范围内得到验证,但有些人对他们的选秀位置(第二或第三)不满意,因为他们希望在我们的 snake 选秀格式中接近第 9 或第 10 顺位。专员改变了草稿选择生成器的目的,不是定义草稿中的位置,而是选择选择位置的顺序。例如,在上面的排序中,吉姆可以选择第一轮的第一个选择或其他任何地方。作为第二人选,我可以选择任何职位,除了那些已经被我上面的人选中的职位。在过去的 4 年里,这个系统已经被 10 个极具竞争力的梦幻足球运动员接受来组织我们的选秀位置。它具有随机性和可控性。
感谢阅读
一如既往地感谢您的阅读。我叫科迪·格利克曼,可以在 LinkedIn 上找到我。R Shiny 应用程序的代码可以在我的 GitHub 上找到。如果有赛季的话,祝你好运!
附加文章
一步一步的教程,让你自己的美丽的图像
towardsdatascience.com](/creating-photo-mosaics-using-python-49100e87efc) [## 使用 Dash 和 SQL 快速浏览圣诞歌曲
使用 SQL 数据库创建 Dash 仪表板的简单项目
towardsdatascience.com](/dashing-through-christmas-songs-using-dash-and-sql-34ef2eb4d0cb) [## 使用 GitHub 创建漂亮的静态网页
查找模板和为静态网页创建表单的位置
towardsdatascience.com](/building-a-beautiful-static-webpage-using-github-f0f92c6e1f02)
Python 中使用自然启发算法的快速超参数调整
Bat 算法与网格搜索的性能比较
受自然启发的算法非常强大,通常用于解决 NP 难问题(如旅行推销员问题)或其他计算量大的任务。它们也被称为优化算法。受自然启发的算法试图找到问题的最佳解决方案,然而并不保证会找到最佳解决方案。
超参数调整通常使用网格搜索或随机搜索来完成。网格搜索的问题在于它非常昂贵,因为它尝试了所有可能的参数组合。随机搜索会尝试一定数量的随机参数组合。它不太可能找到参数的最佳组合,但是,它比网格搜索要快得多。
蝙蝠的回声定位是蝙蝠算法的基础部分(杨新社 2010)。照片由 Igam Ogam 在 Unsplash 上拍摄
接下来是自然启发算法。它们比网格搜索更快,并且有可能找到最佳解决方案——超参数的最佳组合。然而,算法与算法之间的结果会有所不同(有许多受自然启发的算法,例如:蝙蝠算法、萤火虫算法……),这些算法也有自己的参数,这些参数控制它们如何搜索解决方案。如果您知道这些算法是如何工作的,您可能希望设置这些参数来改进搜索过程。
使用自然启发的算法开始超参数调谐
如果您在您的机器学习项目中使用 Scikit-Learn ,您可以使用一个名为 Sklearn 自然启发算法 的 python 库,它将允许您使用自然启发算法进行超参数调整。我们将在本教程中使用这个库,通过 pip 安装它。
pip install sklearn-nature-inspired-algorithms
假设我们想要优化我们的随机森林分类器的参数。
from sklearn.ensemble import RandomForestClassifierclf = RandomForestClassifier(random_state=42)
现在我们需要定义我们将尝试的参数集,用法类似于 scikit-learn 的 GridSearchCV 。这组参数总共有 216 种不同的组合。
param_grid = {
'n_estimators': range(10, 80, 20),
'max_depth': [2, 4, 6, 8, 10, 20],
'min_samples_split': range(2, 8, 2),
'max_features': ["auto", "sqrt", "log2"]
}
此外,我们需要一个数据集。我们将使用 make_classification 人工创建一个。
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classificationX, y = make_classification(n_samples=1000, n_features=10, class_sep=0.8, n_classes=2)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)print(f'train size - {len(X_train)}\ntest size - {len(X_test)}')
**现在我们可以使用自然启发的算法进行超参数调整。**我们正在使用 Bat 算法进行优化。我们将训练 25 个个体的种群规模,如果算法在 10 代内找不到更好的解决方案,我们将停止该算法。我们将这样做 5 次,并将使用 5 倍交叉验证。要了解关于 NatureInspiredSearchCV 参数的更多信息,请参考其 文档 ,您也可以使用 Bat 算法之外的其他算法。
from sklearn_nature_inspired_algorithms.model_selection import NatureInspiredSearchCVnia_search = NatureInspiredSearchCV(
clf,
param_grid,
cv=5,
verbose=1,
algorithm='ba',
population_size=25,
max_n_gen=100,
max_stagnating_gen=10,
runs=5,
scoring='f1_macro',
random_state=42,
)
nia_search.fit(X_train, y_train)
花费了一些时间,大约 1 分钟(GridSearch 大约需要 2 分钟,参数网格越大,差异越大)。现在,您可以用找到的最佳参数来拟合您的模型。最佳参数存储在*nia _ search . best _ params _*中。
from sklearn.metrics import classification_reportclf = RandomForestClassifier(**nia_search.best_params_, random_state=42)
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
print(classification_report(y_test, y_pred, digits=4))
现在,您已经使用受自然启发的算法选择的最佳参数成功训练了模型。这是完整的例子。
我还做了一个 GridSearchCV 和 NatureInspiredSearchCV 的比较(在本笔记本)。我使用了更大的数据集和更多的超参数(总共 1560 个组合)。natureinspiredsearchv找到了与 GridSearchCV 相同的解决方案,并且比快了 4.5 倍!花了GridSearchCV2h 23 分 44 秒找到了最佳方案,natureinspiredsearchv在 31 分 58 秒找到了。
受自然启发的算法非常强大,在超参数调整方面优于网格搜索,因为它们能够更快地找到相同的解决方案(或非常接近)。在本教程中,我们使用 Bat 算法,其默认参数由 Sklearn 自然启发的算法库设置,但也有许多其他自然启发的算法可用于超参数调整。
改善数据展示的一些技巧
7 个简单步骤的例子
在这篇文章中,我将展示一个如何改进结果图的例子。假设你致力于通过修改神经网络的稀疏性和丢弃的使用来改进某种神经网络(它显然可以是其他东西)。原始数据看起来像这样:
作者图片
在此图中,我们可以看到不同的颜色稀疏值、x 轴的 dropout 值和 y 轴的 accuracy 值。
步骤 1:通过删除值和使用百分比来修复轴标签
由于两个轴中的值太多,我们希望通过删除一些值并使用百分比来提高可读性:
作者图片
步骤 2:显示稀疏值,而不是使用图例
当查看不同的线条时,我们需要在图例和线条之间来回移动,以了解哪种颜色对应于哪种稀疏度值。这样做对读者来说心理上并不舒服,我们选择显示每行的稀疏值:
作者图片
第三步:使用连续的调色板
稀疏值实际上是连续的,但是当前的调色板不使用它。当不同的值是有序的时,默认颜色是很好的,但是在这个例子中,我们可以改进调色板。为了选择一个调色板,我使用了 chroma.js 调色板网站。我想要从蓝色到绿色的 5 种颜色。我选择了两种亮度大约为 50-60%的颜色,这样它在白色背景下是可读的(例如,而不是< 40%的亮度)。这些颜色不是完全色盲安全的(但仍然可以,因为亮度是不一样的),可以改进。
作者图片
现在更明显的是,不同的稀疏度/颜色是连续的,图形看起来更专业,因为初学者经常使用默认的调色板,专业人员使用他们自己的调色板(顺便说一下,我不是数据可视化专业人员)。
步骤 4:显示一个代表稀疏度的条形
我们有一个连续的调色板,它在“颜色空间”中是线性间隔的,但是稀疏值实际上根本不是均匀间隔的。很难想象我们正在处理的稀疏性的数量。为了澄清这一点,我们添加了一个表示稀疏度的线段:
作者图片
第五步:降低对比度,删除顶部和右边的部分
图形看起来有点奇怪,因为 x 轴对右边部分没有太大意义。我们删除 30%后的 x 轴,并删除没有实现任何东西的右边和顶部部分。我们还把黑色换成了不那么咄咄逼人的灰色。同样,它使图形更加专业。大多数专业人士使用深灰色而不是纯黑色。在 Medium 中,默认情况下,我写的文本是 84%不透明度的黑色,这使它成为深灰色。我们还把标题做得高一点,大一点,为几个字幕做准备。
作者图片
第六步:展示一些价值观
查看图表时,我们很想找到精度值,但很难读懂,因为我们只有 y 轴上的 4 个值来计算。此外,最有趣的值是 10%的下降值,这似乎是最佳下降值。所以我们把这些值加起来,写一个副标题解释一下(可选) :
作者图片
第七步:增加百分比来回答读者的问题
我们现在很想量化 10%压差精度对 0%压差设置的帮助有多大。为了帮助读者理解这一点,我们增加了这个百分比:
作者图片
我们完事了。
最终的 matplotlib 代码是:
结论
在这些步骤中,它们是几种类型的转换:
-清理:例如,当我们移除一些刻度标签时,我们试图使绘图更干净。当你在做演示时,寻找要删除的东西,而不是要添加的东西(在开始的时候)。
-预见读者的问题:试着设身处地为读者着想,你想了解数据中的哪些内容,但又很难了解?在我的例子中,我们需要添加一些数值和百分比
——视觉上很难理解的是什么?在我的例子中,不容易看出稀疏值不是均匀分布的。
获得你梦想中的远程数据科学工作的现场指南
找到一份完全远程的数据科学工作并不是一件容易的事情,但是这些提示将帮助你实现这个目标。
最近,维基·博伊基斯,数据科学推特圈的标志性人物,宣布她加入automatic(Wordpress 背后的公司)成为一名机器学习工程师。
Automattic 是第一批完全分布式的公司之一,并已成为如何实现远程化的参考。事实上,它已经成为求职者梦寐以求的远程工作最明显、最有吸引力的目标之一。
虽然这听起来对 Vicky 和 Automattic 来说都是一个好消息,但对于寻找远程工作的候选人来说,这也可能会挫伤他们的积极性,因为这提醒他们,他们可能会与地球上最引人注目和最有才华的专业人士竞争。但是不要失去希望,找到一份远程工作还是有可能的。
以下建议主要基于我的个人经验(我已经在两份不同的工作上远程工作了 4 年多)以及与其他远程工作者的交谈。它还包括一个我得到目前工作的故事。
每篇远程工作文章都有一张强制性的热带海滩图片,这里就有一张。照片由埃里佐·迪亚斯在 Unsplash 上拍摄
是的,竞争是艰难的
让我们不要设定不切实际的期望,找到一份完全远程的全职数据科学工作并不容易。如前所述,你将与这个星球上最合格的专业人士竞争,而且一年没有那么多的空缺。
不要因为每天在 Linkedin 上收到现场工作的邀请,就认为几个月后你会找到工作,就马上辞职。你应该设定一个现实的期望,并把它视为一个长期的项目,其中包含了大量的奉献和失望。
希望事情会变得更容易,因为许多知名公司如 Twitter,Shopify 或 Slack 宣布,即使在 Covid 危机结束后,他们也将完全或部分远程化。
从…你目前的工作开始
你会在任何地方读到:远程工作都与信任有关,例如,相信你会在没有密切监督的情况下完成任务。利用你与时间建立的关系应该是你的第一步,没有比现在的工作更好的起点了。
如果您的经理对您很满意,并且您的公司没有明确的反远程工作政策,您应该开始讨论。
2016 年,我的妻子得到了一个 500 公里外的工作机会,我们认为这是一个与家人一起生活在一个更小更平静的城市的机会。接下来的问题是如何处理我的工作。她漫不经心地提到“你可以要求在家工作”,我觉得自己很愚蠢,以前甚至没有考虑过这个问题。不久之后,我开始和我的经理交谈,说我想在不久的将来开始远程工作,最好的办法是仍然和他们一起工作。一个月后,我离开了巴塞罗那,开始远程工作,不需要寻找新的工作(但转到了一个不同的团队)。
这并不总是可能的,即使在同一个公司里,这在很大程度上取决于你在和谁交谈。就我而言,如果换一个经理,这可能是不可能的。但可以肯定的是,如果你不问,肯定不会发生。
使用你的网络
寻找已经信任你的人的第二个好地方是你的关系网。很可能有一些你过去共事过的人欣赏你的专业素养,他们现在在不同的公司工作,很乐意再次与你共事。
联系他们吧。在 LinkedIn 上给他们发一条信息,询问他们的近况,祝贺他们最近的相关变动,并随意提及你正在寻找新的机会——理想情况下,这将允许全职远程工作。因为你有私人关系,他们会给你一个诚实的答案,甚至可能接触不同的人(可能在不同的公司)来询问潜在的机会。
询问招聘人员
如果你在 LinkedIn 上有一个数据科学家的头衔,你可能会通过 LinkedIn 定期收到邀请。
利用这些机会与招聘人员联系,询问工作是否可以完全远程化。在 99%的情况下,情况可能并非如此(根据我的经验,尽管这可能会在 Covid 之后发生变化),但这也是一种非常省力的方法,因为您只需快速回复收到的消息。
招聘人员会感谢你回答他们(他们并不都是坏人!)可能会考虑让你去做他们正在做的另一份工作,而且是远程友好型的。
在你的申请中投入额外的爱
请记住,远程职位竞争激烈,公司可能会收到千份申请一个空缺职位。不用说,你应该确保你发送了一个顶级的申请脱颖而出。
- 根据职位定制你的简历。这可以适用于任何求职,但当你与成千上万的其他候选人竞争时,你必须确保你的简历反映出你有多适合这个职位。
- 破解你的求职信或演示邮件。远程工作需要很强的沟通技巧。如果你不能用几段话来表达为什么目标公司应该考虑你作为候选人,这会破坏你的申请。
- 找到如何连接。找出你在公司的对话者可能是谁,他们喜欢什么。招聘经理可能活跃在社交网络上,写了一些文章或书……研究他们是谁,他们的文化背景,他们的成就,这样你就有更好的机会了解如何最好地抓住他们的注意力。
使用正确的工具
虽然,人们可能首先会认为寻找现场或远程工作没有区别,但有一些方法可以改善你的远程求职:
- 使用正确的过滤器。像 StackOverflow 这样的网站可以选择只显示远程工作。
- 跟随正确的公司。这里有远程招聘公司的名单,还有一些非常显眼的名单,比如自动招聘、缓冲招聘、扎皮尔、 Hotjar 、……留意他们的工作页面,以防有新的职位空缺。
- 看看初创企业。初创企业更有可能采用新的工作方式,因为它们从零开始建立自己的工作文化(而且租赁办公室的资金更少)。像 AngelList 这样的网站提供了大量的创业工作,有些完全是远程的。
- 看看专门的董事会和社区。有大量专门从事远程空缺职位的工作委员会或社区(例如remove、 RemoteOK 、…)。密切关注他们,并设置你的提醒,尽管数据科学的工作机会不如开发人员那么频繁。
做自由职业者
如果你的申请运气不好,你仍然可以考虑做自由职业者。由于自由职业者通常是经验丰富的专业人士,与公司的合作时间较短,所以他们通常更愿意让自由职业者远程工作。
自由职业者的生活当然不适合每个人,找到一份远程自由职业者的工作也不一定更容易。你仍然可以通过在 UpWork(或更专业的本地网站)等平台上创建个人资料来测试这些理由,看看获得一些体面的第一份工作有多容易(或多难)。
有创造力
虽然有些人会假装如此,但找工作并没有金科玉律。一些通常对其他人有效的方法可能对你无效,反之亦然。因此,如果你足够幸运得到一些反馈,建议你尝试不同的方法并从中学习(我们仍然可以说,得到 ghosted 是反馈的最小单位)。
如果你能找到招聘经理,试着直接联系他们,发送没有列出的工作申请(公司可能会给你回复),如果这是你唯一的选择,通过公司的在线表格申请,尽管每个人都会告诉你这永远不会成功(有时会这样,我通过这种方式获得了多次面试和一份工作),总的来说,试着找到与打电话的人联系的最佳方式。
举个例子,我在不和谐中得到现在的工作… !对于一份我大材小用的工作。
我对一家年轻的初创公司感兴趣,该公司正在寻找一名数据分析师,而我正在寻找一个更高级的职位,最好是主管/总监级别的职位。经过一些研究,我意识到他们还没有任何数据科学家,他们可以使用更有资历的人。此外,他们有一个链接到他们的 Discord 服务器(他们在游戏领域运营),在那里我可以直接联系首席执行官,并介绍自己是一名数据主管。几通电话后,我被录用了。
像任何类型的方法一样,这肯定不是每次都有效的方法。但这表明,如果你足够坚持,花足够的精力去了解你的目标公司,他们将需要什么,以及如何获得他们的关注,你最终会脱颖而出。
坚持不懈
最后,记住你只控制招聘过程的一小部分。即使你发出了最好的申请,并且非常适合这个职位,也有很多因素是你无法控制的:你的竞争对手、与招聘者的个性匹配、公司战略的变化、适合这个职位的预算、时间安排等等
求职是一个数字游戏,对于远程工作更是如此。你可能不会在第一次申请时就得到一份工作,但也许你会得到!只要确保使用本文中强调的各种方法,并在每个应用程序上尽最大努力,以增加成功的几率,并获得梦想中的数据科学远程工作。