如何使用良好的软件工程实践来设置 Python 和 Spark 开发环境
在本文中,我们将讨论如何设置我们的开发环境以创建高质量的 python 代码,以及如何自动化一些繁琐的任务以加快部署。
我们将回顾以下步骤:
- 使用 pipenv 在隔离的虚拟环境中设置我们的依赖关系
- 如何为多项任务设置项目结构
- 如何运行 pyspark 作业
- 如何使用 Makefile 来自动化开发步骤
- 如何使用 flake8 测试我们代码的质量
- 如何使用 pytest-spark 为 PySpark 应用运行单元测试
- 运行测试覆盖,看看我们是否已经使用 pytest-cov 创建了足够的单元测试
步骤 1:设置虚拟环境
虚拟环境有助于我们将特定应用程序的依赖关系与系统的整体依赖关系隔离开来。这很好,因为我们不会陷入现有库的依赖性问题,并且在单独的系统上安装或卸载它们更容易,比如 docker 容器或服务器。对于这个任务,我们将使用 pipenv。
例如,要在 mac os 系统上安装它,请运行:
brew install pipenv
为了声明应用程序的依赖项(库),我们需要在项目的路径路径中创建一个 Pipfile :
[[source]]
url = '[https://pypi.python.org/simple'](https://pypi.python.org/simple')
verify_ssl = true
name = 'pypi'[requires]
python_version = "3.6"[packages]
flake8 = "*"
pytest-spark = ">=0.4.4"
pyspark = ">=2.4.0"
pytest-cov = "*"
这里有三个组成部分。在 [[source]] 标签中,我们声明了下载所有包的 url ,在**【requires】中,我们定义了 python 版本,最后在【packages】中定义了我们需要的依赖项。我们可以将一个依赖项绑定到某个版本,或者使用" ***符号获取最新的版本。
要创建虚拟环境并激活它,我们需要在终端中运行两个命令:
pipenv --three install
pipenv shell
一旦这样做了一次,您应该看到您在一个新的 venv 中,项目的名称出现在命令行的终端中(默认情况下,env 使用项目的名称):
(pyspark-project-template) host:project$
现在,您可以使用两个命令移入和移出。
停用环境并移回标准环境:
deactivate
再次激活虚拟环境(您需要在项目的根目录下):
source `pipenv --venv`/bin/activate
步骤 2:项目结构
项目可以有以下结构:
pyspark-project-template
src/
jobs/
pi/
__init__.py
resources/
args.json
word_count/
__init__.py
resources/
args.json
word_count.csv
main.py
test/
jobs/
pi/
test_pi.py
word_count/
test_word_count.py
某 init。为了使事情更简单,py 文件被排除在外,但是您可以在 github 上找到教程末尾的完整项目的链接。
我们基本上有源代码和测试。每个作业都放在一个文件夹中,每个作业都有一个资源文件夹,我们可以在其中添加该作业所需的额外文件和配置。
在本教程中,我使用了两个经典的例子——pi,生成圆周率数字直到小数位数,以及字数统计,计算 csv 文件中的字数。
步骤 3:使用 spark-submit 运行作业
让我们先看看 main.py 文件是什么样子的:
当我们运行我们的作业时,我们需要两个命令行参数: —作业,是我们想要运行的作业的名称(在 out case pi 或 word_count 中)和 — res-path ,是作业的相对路径。我们需要第二个参数,因为 spark 需要知道资源的完整路径。在生产环境中,当我们在集群上部署代码时,我们会将资源转移到 HDFS 或 S3,我们会使用那条路径。
在进一步解释代码之前,我们需要提到,我们必须压缩作业文件夹,并将其传递给 spark-submit 语句**。**假设我们在项目的根中:
cd src/
zip -r ../jobs.zip jobs/
这将使代码在我们的应用程序中作为一个模块可用。基本上在第 16 行的 **main.py 中,**我们正在编程导入 job 模块。
我们的两个作业, pi 和 **word_count,**都有一个 run 函数,所以我们只需要运行这个函数,来启动作业(main.py 中的 line 17)。我们也在那里传递作业的配置。
让我们看一下我们的 word_count 工作来进一步理解这个例子:
这个代码在 init 中定义。py 文件在 word_count 文件夹中。我们可以看到,我们使用两个配置参数来读取 csv 文件:相对路径和 csv 文件在 resources 文件夹中的位置。剩下的代码只是计算字数,所以我们在这里不再赘述。值得一提的是,每个作业在 resources 文件夹中都有一个 args.json 文件。这里我们实际上定义了传递给作业的配置。这是字数作业的配置文件:
{
"words_file_path": "/word_count/resources/word_count.csv"
}
现在我们已经有了运行我们的 spark-submit 命令的所有细节:
spark-submit --py-files jobs.zip src/main.py --job word_count --res-path /your/path/pyspark-project-template/src/jobs
要运行另一个作业, pi,,我们只需更改 —作业标志的参数。
步骤 4:编写单元测试,并在覆盖范围内运行它们
为了编写 pyspark 应用程序的测试,我们使用了 pytest-spark ,一个非常容易使用的模块。
word_count 作业单元测试:
我们需要从 src 模块中导入我们想要测试的函数。这里更有趣的部分是我们如何进行 **test_word_count_run。**我们可以看到没有初始化 spark 会话,我们只是在测试中将它作为参数接收。这要感谢 pytest-spark 模块,所以我们可以专注于编写测试,而不是编写样板代码。
接下来让我们讨论一下代码覆盖率。我们如何知道我们是否写了足够多的单元测试?很简单,我们运行一个测试覆盖工具,它会告诉我们哪些代码还没有被测试。对于 python,我们可以使用 pytest-cov 模块。要使用代码覆盖运行所有测试,我们必须运行:
pytest --cov=src test/jobs/
where — cov 标志告诉 pytest 在哪里检查覆盖率。
测试覆盖率结果:
---------- coverage: platform darwin, python 3.7.2-final-0 -----------
Name Stmts Miss Cover
-----------------------------------------------------
src/__init__.py 0 0 100%
src/jobs/__init__.py 0 0 100%
src/jobs/pi/__init__.py 11 0 100%
src/jobs/word_count/__init__.py 9 0 100%
-----------------------------------------------------
TOTAL 20 0 100%
我们的测试覆盖率是 100%,但是等一下,少了一个文件!为什么 main.py 没有列在那里?
如果我们认为我们有不需要测试的 python 代码,我们可以将其从报告中排除。为此,我们需要创建一个**。coveragerc** 文件放在我们项目的根目录下。对于这个例子,它看起来像这样:
[run]
omit = src/main.py
步骤 5:运行静态代码分析
太好了,我们有一些代码,我们可以运行它,我们有覆盖率良好的单元测试。我们做得对吗?还没有!我们还需要确保按照 python 的最佳实践编写易读的代码。为此,我们必须用名为 flake8 的 python 模块来检查我们的代码。
要运行它:
flake8 ./src
它将分析 src 文件夹。如果我们有干净的代码,我们应该不会得到警告。但是没有,我们有几个问题:
flake8 ./src
./src/jobs/pi/__init__.py:13:1: E302 expected 2 blank lines, found 1
./src/jobs/pi/__init__.py:15:73: E231 missing whitespace after ','
./src/jobs/pi/__init__.py:15:80: E501 line too long (113 > 79 characters)
让我们看看代码:
我们可以看到在第 **13 行有一个 E302 警告。这意味着我们需要在这两个方法之间多加一行。然后在 **15 线上安装 E231 和 E501 。这一行的第一个警告,告诉我们在**range(1, number_of_steps +1),**
和**config[**
之间需要一个额外的空格,第二个警告通知我们这一行太长了,很难读懂(我们甚至不能完整的看到大意!).
在我们解决了所有的警告之后,代码看起来更容易阅读了:
步骤 6:用一个 Makefile 把它们放在一起
因为我们已经在终端中运行了许多命令,所以在最后一步中,我们将研究如何简化和自动化这项任务。
我们可以在项目的根目录下创建一个 Makefile ,如下图所示:
.DEFAULT_GOAL := runinit:
pipenv --three install
pipenv shellanalyze:
flake8 ./srcrun_tests:
pytest --cov=src test/jobs/run:
find . -name '__pycache__' | xargs rm -rf
rm -f jobs.zip cd src/ && zip -r ../jobs.zip jobs/ spark-submit --py-files jobs.zip src/main.py --job $(JOB_NAME) --res-path $(CONF_PATH)
如果我们想要运行覆盖率测试,我们可以简单地输入:
make run_tests
如果我们想要运行 pi 作业:
make run JOB_NAME=pi CONF_PATH=/your/path/pyspark-project-template/src/jobs
那都是乡亲们!我希望你觉得这是有用的。
一如既往,代码存储在 github 上。
如何缩短数据与价值的距离?
上次我写了一篇关于数据重力的文章,分享了关于如何提高数据质量和价值的想法。如前所述,今天本帖将给你**关于缩短数据和价值之间距离的提示。换句话说,建立数据链接。**在这方面,IT 部门扮演着最关键的角色,它是公司数据链的保障。
开始之前,让我解释一下什么是数据链路。
公司里的管理环节就是给压力的过程。当公司出现问题时,老板通常会给中层管理人员施加压力,不管是从业务表现还是运营角度来看。然后中层管理者向运营人员询问业务数据。为此,运营团队向管理团队提交原始数据。
数据链路的方向与管理链路的方向相反。为了支持管理链接,IT 部门需要以数据链接的形式及时提供数据。
但是 IT 部门如何建立数据链接呢?
以下是对支持数据分析和 BI 项目的团队的弱点的研究。
“2018 China Enterprise Data Research Report”, from FanRuan Data Institute
从图中我们可以发现,问题最初源于人、方法和工具。
因此,IT 部门应该通过改善这三个方面来建立数据和价值之间的桥梁。
同样,你可能会问怎么做?大多数公司都有自己的 IT 培训系统。他们中的一些人可能会向 IT 咨询部门寻求解决方案或购买 BI 工具。
在这里,我将结合泛软提供的解决方案,向大家展示如何建立数据与价值之间的联系。
先从‘人’的角度说起吧。
一个好的团队应该具备以下三种能力。首先是认知,涵盖理解数据分析、构建知识框架、数据共识、培训体系的能力。
第二是数据能力。换句话说,团队可以实现数据项目,包括组织索引、统计分析、可视化应用和数据管理。
最后是应用能力。它需要团队进行业务分析,支持软件,激发专业流程,开发数据价值。
在这方面,我建议 IT 部门建立一个培训系统,并鼓励团队成员加入在线社区进行学习、交流或互助。
然后,我们将重点放在“实施”上。
为了支持其他部门,IT 部门需要两支部队。一个是负责构建企业报表的主要力量。另一个是侦察力量。他们熟悉不同部门的业务,通过探索业务数据为业务注入活力。基于这些现实需求,前团队需要一个报表平台,比如fine report来处理复杂的报表。后者应该使用 数据分析工具 对公司进行分析、预测和创新。
以上是关于“工具”的一个要素——工具。“实施”的另一个要素是解决方案。要构建全面的解决方案,IT 部门不仅要考虑公司的情况,还要考虑行业解决方案。
在过去的几年里,泛软为 233 个行业的公司提供服务。在这个过程中,凡软发现,即使产品很优秀,当推向不同行业时,这些行业的各种需求会降低项目实施的效率。
而且其实每个板块都有一定的共性。只要把这些共性总结成行业解决方案,重用它,不断改进它,产品在行业中的价值就能得到极大的发挥。这就是为什么 泛软 除了提供产品之外,还提供全面的行业解决方案。
有了这些,最后就是“方法”的问题了。
“方法”的要点是交流思想。我非常推荐 IT 人员参加各种活动,例如新加坡的大数据世界欧洲的 AI &大数据博览会、伦敦的大数据 LDN、美国的 Tableau 大会、中国的智能数据大会。你必须了解行业趋势,与世界接轨。向别人学习永远是最快的方法。
总之,缩短数据和价值之间距离的主体是 IT 部门,我们应该从人、工具和方法开始建立数据和价值之间的联系。
您可能也会对…感兴趣
如何用神经网络求解常微分方程
如今,自动微分使得从机器学习的角度处理微积分问题成为可能。也许你在 NIPS 2018 上听到过关于神经常微分方程论文的一些议论,这篇论文是由作者之一大卫·杜文瑙德提交并签名的。同时,亲笔签名已经被 JAX 取代,这就是我们将在这里使用的。
主要问题如下:我们想找一个由微分方程定义的未知函数 y=f(x) ,比如 *y’=-2xy,*加上一些初始条件,比如 y(0)=1 。例子来自 Kreyszig 的 高等工程数学 的前几页。这个特定初始值问题的解析解是 *y=exp(-x),*我们将使用它来验证神经网络提供的结果。
一般来说,对于常微分方程可能没有封闭形式的解,但是可以用神经网络来近似未知函数 y=f(x) 。为了简单起见,我们将使用一个具有带 10 个节点的单个隐藏层的神经网络来解决问题y’=-2xy和 y(0)=1 。
这是我们神经网络的示意图:
总的来说,网络有 31 个可训练参数:隐藏层的权重和偏差,加上输出层的权重和偏差。
让我们按如下方式实现网络:
我们使用类似 JAX NumPy 的 API,这样,稍后,我们可以通过自动微分计算f
的导数。注意,f
有两个参数:一个网络参数数组(params
)和一个输入值(x
)。在机器学习中,我们通常根据模型的参数来区分模型,这里我们也将根据x
来区分f
,以便求解 ODE。
网络参数可以随机初始化,例如使用正态分布:
这里我们使用 JAX 提供的伪随机数发生器 (PRNG)。通过用某个种子创建 PRNG 键,我们确保我们的结果是可重复的。
f
相对于x
的导数可以通过调用grad
来获得:
其中1
表示我们想要f
相对于其第二自变量x
(从零开始的索引)的梯度。在 JAX 中,grad
返回一个函数,该函数计算f
的梯度,并具有与原始f
相同的参数。
现在,我们会想要求解某个域中的 ODE,例如在 -2 ≤ x ≤ 2 中。因此,我们在该范围内创建一个输入值数组:
其中 401 点是任意选择在区间 [-2,2] 内具有 0.01 的分辨率。
然而,f
接受单个值x
作为输入。我们可以以数组的形式传递给它,但是为了便于区分,JAX 需要一个标量函数,所以我们必须传递一个单一的值作为输入,以便得到一个单一的值作为输出。为了有效地计算输入值数组的f
及其导数dfdx
,我们使用vmap
对这些函数进行矢量化:
其中(None, 0)
指定每个函数将映射到第二个参数(x
)的0
-轴上,而第一个参数(params
)应保持不变(使用None
,它将在映射中传播)。
我们现在可以定义我们的损失函数(是的,任何机器学习项目中出现的损失函数,其最小化将产生我们想要的解决方案):
注意微分方程 y’=-2xy 和初始条件 y(0)=1 是如何分别在eq
和ic
中被捕获的。为了使训练过程中的残差 y’+2xy 和 y(0)-1 最小化,它们被表示为 y’+2xy=0 和 y(0)-1=0 。我们在这个函数上使用 JIT(实时编译)来加速它在加速器硬件上的执行,比如 GPU 或 TPU,如果可用的话。
如同任何机器学习项目一样,我们现在根据可训练参数来区分损失函数:
其中0
意味着我们想要损失函数相对于它的第一个自变量(params
)的梯度。同样,我们使用 JIT 来加速这个新函数的执行。
该开始训练了!为了加快速度,我们将使用带有内斯特罗夫动量的梯度下降。回想一下内斯特罗夫加速梯度 (NAG)的公式:
因此,我们实施如下培训流程:
让我们运行它!
最后,让我们绘制结果并与解析解进行比较:
这就对了,神经网络近似看起来和精确的解析解几乎没有区别。
最后一个问题:在近似的域 [-2,2] 之外会发生什么?好吧,我将把它作为一个练习留给读者……
(提示:重新定义inputs
,并再次绘制结果。)
如何加快你的 AB 测试
Spot the difference
第 1 部分:测量两次,切割一次
本帖最初发表于The Craft,Faire 的技术博客。这是我们关于使用 A/B 测试加速决策的系列文章中的第一篇。
像许多超增长的创业公司一样,Faire 使用实验来快速迭代我们的产品,并做出更好的决策。然而,与服务于数亿甚至数十亿潜在用户消费市场的许多同行不同,我们的市场是为小型企业构建的,在美国大约有 3000 万小型企业[0]。再加上我们才刚刚成立三年,这意味着我们实验的样本量往往小于其他科技公司数据科学团队进行实验的规模。举个例子,我们的平台目前为 100,000 家零售商和 10,000 家制造商提供服务。
当一个团队测试相对较大的效应尺寸时,较小的样本可能不是问题。但是在我们的案例中,许多简单的产品已经实现了,我们必须运行大量的实验来找到真正的大提升(这是我们计划很快写更多的主题。)由于这些限制,我们经常被产品经理问到,为什么他们的实验要花这么长时间才能达到显著效果,或者他们能做些什么来加速实验。为了响应这些要求,我们构建了第一个版本的工具来加速我们的实验结果,并为设计实验的数据科学家、工程师和产品经理制定了指南,以确保我们能够更快地做出决定,并对我们的结论有更高的信心。
在这一系列的文章中,我们提供了当前加速 AB 测试所使用的各种技术的概述,有些是简单的,有些是技术性更强的。随附的 Python 笔记本提供了示例和工作代码,以具体展示这些技术的影响,并为您提供一个改进自己的实验程序的起点。
试验设计
提前花时间设计能尽快产生最有用结果的实验是一种有效的方法,可以确保团队不会在回答错误问题的测试上浪费时间,也不会花太多时间来回答正确的问题。此外,以系统化的方式记录实验让公司更难忘记或记错之前测试的结果[1]。这对于非直观结果的实验和那些不能推广到整个用户群体的实验来说尤其重要。有了这个历史数据的存储库,团队可以围绕什么样的产品处理起作用和不起作用,在用户群的什么部分,他们移动哪些指标,以及移动多少,开发更好的先验信念。
更好的指标
在 Faire 设计实验时,我们首先要做的决定之一就是主要的度量标准是什么。我们通常必须做出许多权衡,以找到一种既能捕捉到我们试图通过治疗影响的行为,又能快速收敛以给出具有统计学意义的结果的指标。最重要的两个维度是度量与治疗的接近度(作为效果大小的代表)和度量的预期方差(T3)。
Consider proximity and variance when choosing metrics
接近度
因为我们的零售商比制造商多一个数量级,所以我们的大多数实验都是在市场的需求方进行的。就零售商而言,PMs 大多数时候希望衡量的指标与商品总值(GMV)相关,因为商品总值的增加反映了零售商从产品中获得了更多的经济价值,这也是我们的关键业务指标之一。这在实践中可能具有挑战性,因为 GMV 位于我们测试的所有项目的下游。例如,我们对注册流程所做的更改通过许多中间步骤从实际下单的零售商处删除。因此,我们看到的注册数量的任何提升往往会因零售商在客户旅程中下单的时间点而显著减少。
我们可以用一个简单的例子来强调这一点,在这个例子中,我们通过注册、添加到购物车和下订单来吸引访问者,然后让他们通过转换漏斗。在本例中,我们观察到从访问到注册的转化率大幅提升,并假设添加到购物车和订购的转化率没有差异。
Lifts can be harder to measure downstream from the treatment
为了简单起见,我们对治疗组和对照组在漏斗中每个步骤的转化率不同的假设进行卡方检验。我们看到了注册和添加到购物车转换的显著结果,但订单转换没有。这是因为当我们沿着漏斗向下移动时,绝对升力下降,而当值接近零时,转换的方差增加。
**print(proportion.proportions_chisquare(summary_treatment_1['signed_up'], summary_treatment_1['count'])[1])
print(proportion.proportions_chisquare(summary_treatment_1['added_to_cart'], summary_treatment_1['count'])[1])
print(proportion.proportions_chisquare(summary_treatment_1['ordered'], summary_treatment_1['count'])[1])4.826037697355727e-06
0.0027419906333688462
0.11399561233236452**
这个问题的一般解决方案是选择一个与我们在产品中所做的改变最接近的主要度量。在这种情况下,显而易见的选择是从访问转换为注册。然而,我们不能确定由我们的治疗导致的任何额外注册实际上最终参与了我们最终想要推动的下游行为,例如下订单。我们缓解这一问题的两种方法是选择适当的二级指标(在这种情况下,添加到购物车和订单转换将是很好的选择),以及利用我们以前的实验和观察研究的资料库,围绕我们的一级指标和它的下游指标之间的关系强度开发先验信念。简而言之,如果我们有理由相信注册量的增加转化为订单量的增加,那么我们不一定需要等待订单转换量的增加达到显著性(但不要在测试不足的情况下得出次要指标没有变化的结论[2])。)最后,在我们提升注册转化率但不提升下游指标的情况下,未来的注册实验仍将受益于样本量的增加,从而使我们能够随着时间的推移获得更有意义的结果。
差异
选择指标时要考虑的第二个因素是它们相对于预期效果大小的预期方差。例如,比例指标(分子是分母的子集)如注册转化率或访问品牌的零售商百分比被限制在 0 和 1 之间,产生的估计值比无界指标的估计值误差更小。
选择比例指标,而不是像 GMV/零售商这样的无限制指标,是我们缩短实验达到显著结果所需时间的常用方法。但是在一组可用的数学上无界的度量中,一些比其他的在现实中“更无界”。就 Faire 上的零售商而言,他们可以访问网站上的制造商页面的次数实际上不受限制,而他们向我们下订单的能力受到他们可以通过商店销售的库存数量的限制。这意味着每个零售商的订单分布通常比每个零售商的品牌访问量分布具有更低的方差。
Orders often increase logarithmically with visits
为了说明这一点,我们构建了一个假设的实验,在这个实验中,预期的订单数量与品牌访问量成对数关系。这种类型的关系并不罕见,因为它反映了这样一个事实,即数字行为实际上是不受约束的,而现实世界中的财务预算肯定是不受约束的。我们进一步假设就诊和订单在治疗中均提高了 5%。同样,运行 t-tests 比较访问和订单的两个样本显示,我们会发现后者的显著结果,因为与前者相比,它的均值方差更低。
**print(stats.ttest_ind(experiment_2['visits'][experiment_2['treatment'] == 1], experiment_2['visits'][experiment_2['treatment'] == 0]))
print(stats.ttest_ind(experiment_2['orders'][experiment_2['treatment'] == 1], experiment_2['orders'][experiment_2['treatment'] == 0]))Ttest_indResult(statistic=0.7573654245170063, pvalue=0.44884881305779467)
Ttest_indResult(statistic=2.5239860524427873, pvalue=0.011618610895742018)**
加速
使用比例度量的最后一点:小心加速。如果你衡量采取了他们最终很有可能采取的行动的用户比例,不管他们接受了什么样的治疗,随着你继续进行你的实验,你的比例指标显示没有提升的可能性会增加。虽然你可能提高了采取行动的次数或减少了采取行动的时间,但你不会在实验中提高每个用户的唯一转化率。
在下面的例子中,我们将控制和处理平均分开,具有相同的和确定的访问转换。然而,我们将这些访问的首次到达时间建模为具有对数正态分布的单个 lambdas 的指数。此外,我们假设治疗成员的λ增加 10%。
A simple hierarchical model captures acceleration without lift
我们看到治疗组的访问转化率在收敛到我们事先知道的相同的长期转化率之前处于领先地位。
We would have naively called this test at one week
在 Faire,当我们在现有零售商样本中跟踪访问品牌页面的独特转换时,就会发生这种情况。因为大多数活跃的零售商会在几天或几周内访问一个品牌,我们有时会看到这个指标的提升最初达到峰值,然后随着实验的成熟收敛到零。如果没有被发现,这些新奇和首要效应可能是有害的。这并不是说促进良好行为是不值得的。但是重要的是要理解你是在提升指标还是简单地加速它们。
更少的指标
最后,当谈到实验度量选择时,通常越少越好。随着你在实验中测试的假设数量的增加,你也增加了第一类错误的可能性。根据你对犯这些错误的容忍度,你会想要控制家庭错误率 (FWER)或不太严格的错误发现率 (FDR)。FWER 技术,如霍尔姆-邦费罗尼方法,控制至少一个 I 型错误的概率,而 FDR 程序,如常用的本杰明-霍赫伯格程序,对错误拒绝的无效假设的预期比例提供较弱的保证。下面我们演示了在一个有十个指标的实验中,如何使用 FDR 控制将重要测试的数量从六个减少到四个。无论您采用哪种方法或具体使用哪种方法,通过额外的指标进行的比较越多,您就需要越多的数据来获得有意义的结果。
FDR control renders fewer metrics significant
同样的原理也适用于你实验中的变异数。包含更多变量的测试测试更多的假设,在其他条件相同的情况下,需要更多的数据来达到显著性。基于成本、复杂性甚至是对什么可行什么不可行的强烈先验信念等因素排除额外的治疗方案,不仅可以设计出更强大的测试,还可以缩小产品、工程和设计团队的范围。通过迫使您的团队选择一个单一的主要指标、更少的变量和尽可能少的次要指标来做出决策,您可以显著减少做出决策和交付产品的时间。
机器学习
在本系列的下一篇文章中,我们将讨论如何使用时间盒、离群点去除和分层来减少度量方差。然后,我们将讨论一种称为 CUPED 的分层一般化,我们使用简单的线性模型使用这种技术取得的成功,以及如何使用非线性机器学习方法将其一般化。后面的文章将涵盖功耗分析、顺序测试和减少实验持续时间的动态流量分配策略。
致谢
Daniele Perito 感谢您的投入和指导。
[0] 2018 小企业简介
[1] 机构记忆
[2] 十二个肮脏的游戏:在线控制实验中十二个常见的度量解释陷阱
如何在数据科学工作机会中发现危险信号
数据科学职业建议
以下是我在决定接受工作之前评估工作的几种方法
This job looks delicious.
不久前,我收到了一个人的问题,他读了我之前关于找数据科学工作的一篇帖子。他提到了我对工作与生活平衡的重视,并问道:
“我绝对同意,但你如何评估这一点?你会在面试中问类似“你周末多久工作一次?”我总是害怕被认为缺乏热情,我想,我只是试图在 Glassdoor 或类似的网站上搜寻信息。即使你真的问了,我也不知道答案会有多可靠。无论如何,我很想听听你自己在这方面对一家公司的评估方法。"
这让我更广泛地思考当我还是一名求职者时,我想从一份工作中得到的所有东西,在我实际接受这份工作之前,我尝试过(但往往失败)的所有方法都找到了这些东西。我认为每一份工作的接受都是一场赌博,就像每一份工作邀请都是一场赌博一样,但我确实认为有一些方法可以让求职者最大限度地减少意想不到的负面影响——不管这份工作与我想象的有多差,我至少可以避免很多远远超出我预期的工作。这是事实,即使不像我希望的那样确定。
所以这篇文章是关于我在接受一份工作后发现的主要问题,以及我如何在被这份工作束缚之前发现这些问题的一些想法。
发现工作生活平衡问题
让我们从引发这一思路的问题开始。工作与生活的平衡很难评估,所以我通常不会评估它,直到我合理地确定我和我未来的雇主都觉得这份工作很适合彼此。如果雇主要解雇我还有其他原因(而且有很多,即使对最有经验的申请人来说也是如此),那么谈论其他任何事情都没有意义。等到面试快结束的时候,我就能确保和招聘经理保持尽可能好的关系,而不用真的被录用。如果谈话仍然让我觉得很有威胁性,那就告诉我这份工作可能不太适合我。
我通常这样开始对话:“我想谈谈工作与生活的平衡。我习惯于投入任何时间和精力来完成工作,但我也知道保护自己免于精疲力竭对我来说有多重要。你能告诉我一些关于这方面的期望吗?我多久需要在晚上或周末工作一次?如果我有家庭问题,在某一天在家工作会更好,我有这样做的自由吗?”
我发现这些问题的答案没有我在回答时观察到的语气和肢体语言重要。我经历了明显的防御性:经理生气地说,当然,这种迁就有时不得不发生,期望它不发生是不现实的,但他们试图把它保持在最低限度,因为他们真的需要人们投入任何需要的工作。我曾经历过**以高人一等的态度拒绝回答:经理靠在椅子上,说了一些毫无意义的话,比如“你知道,我们在这里努力工作,也努力玩耍”,或者明确表示,他们正在利用这一时刻教育我,做成人工作意味着什么。我也经历过一般的无能:**经理明确表示他们没有认真考虑过这个问题,也不能告诉我这种事情发生的频率。
防御性意味着他们知道工作与生活的平衡是他们公司的一个问题,但觉得没有权力去做任何事情。居高临下意味着他们不尊重员工的时间和健康,只是试图从员工身上榨取尽可能多的利益,而不考虑长期可持续性。无能要么是假装的,在这种情况下,这意味着情况很糟糕,但他们不愿意诚实地告诉我——换句话说,他们撒谎——要么是真实的,这意味着他们与他们的劳动力脱节,他们真的不知道。
发现对数据科学不切实际的期望
大家都说要数据科学。很少有人愿意投入维护全面数据科学能力所需的工作。有几种方法可以发现这一点。根据我的经验,以瀑布式规划方法为代表的围墙花园式工程组织是一个非常强烈的迹象,表明一家公司没有准备好或不愿意支持数据科学家。同样,在我看来,专注于开发报告或制作仪表板是工作描述的主要部分,这表明他们并不真正需要数据科学家。他们需要一名分析师——也许是一名具有统计专业知识的分析师,但毕竟是一名分析师。但这些都是症状,不是疾病。
在我看来,真正的问题是一家公司是否重视数据科学工作的生产化。分析报告是用来扔掉的——不管报告是交给工程师还是高管。任何仅用于通知某人的输出都不会持久。扔掉我工作的工作不是令人满意的工作——这表明公司并不真正知道如何处理我的工作。
根据我的经验,当被问及生产化时,我可以通过他们的舒适程度来判断一个公司有多重视生产化。就工作与生活的平衡而言,人们的反应可能从防御到屈尊俯就到毫无头绪。我经常看到未来的雇主试图通过谈论他们如何管理项目来回避这个问题。这是一个危险信号。
项目经理是一个行政职位。每当一个团队在做任何事情,从构建软件到计划一个事件,一堆后勤问题(截止日期,利益相关者,劳动分工,等等。)需要协调。团队越大,项目越复杂,让某人关注所有这些移动的部分就越有帮助。项目管理不是产品管理。项目管理找出整个计划的哪一部分需要立即编写代码*,决定当新功能暴露现有功能中的缺陷时该做什么,并保持对“足够好”定义的控制(这是所有数据科学项目唯一真正的验收标准),以及其他日常问题。产品管理关注团队下一步有能力做什么(相对于现在),涉众要求什么,需要什么会议来充实它,以及将实现工作与更大的组织联系起来的其他方法。*
如果一个公司只能以项目来谈数据科学工作,我知道我不想为他们工作。如果他们可以从耐用产品的角度谈论数据科学,以及他们如何决定什么应该放在产品中,什么不应该放在产品中,那么我知道我可能想为他们工作。
发现一个懦弱的经理
我发现利兹·瑞安关于懦弱的经理的概念很有用。以我的经验来看,很少能找到一个真正刻薄或虐待的经理,尽管我知道这种类型的经理肯定比我们任何人想要的都多。相对而言,更常见的情况是,经理们对自己的职位或能力如此不确定,以至于他们试图让周围的每个人(尤其是那些向他们报告的人)看起来都不称职,同时强加一些武断的规则,旨在让他们看起来“强大”和“果断”。
我发现懦弱的经理会系统地向下属展示,经理的时间比员工想要的任何东西都重要。他们取消了我的约会。他们不停地谈论他们做过的所有重要的事情,以及他们交谈过的所有重要的人,这使得他们无法真正关注他们要求我做的任务。他们不能谈论任何不是他们提出的想法。如果我在寻找这些东西,它们往往会在面试过程中出现。
虽然一个明显不关心我时间的经理是应该避免的,但我也不想要一个痛苦地迁就我的经理:从不故意与我意见相左,一有异议就让步,似乎急于向我保证我想要什么就有什么。以我的经验来看,这要么意味着他们自己被一个懦弱的经理所控制,以至于失去了坚持自己意愿的能力,要么意味着他们告诉我他们认为我想听的任何事情。不管怎样,这种类型的经理不会管理,他们只是做出反应。数据科学家通常是个人贡献者,这意味着对业务需求做出反应通常是数据科学家的工作。当我不得不不断对别人的反应做出反应时,我已经精疲力尽了。
发现缺少优先化流程
当一个公司权力分离时,数据科学(我相信,还有一般的代码开发)会很好地工作。权力的分离意味着所有权的分离——对流程的一部分拥有权力的人不会对另一部分拥有权力。我倾向于将数据科学工作分为三个部分:优先级、产品和人员。
在敏捷框架中,优先级通常由产品经理(或者产品经理所在的部门——在许多组织中被混淆地称为“产品管理”或者仅仅是“产品”)拥有。这个所有者可以定义和区分组织要求的优先级,并负责理解和记录系统,以及管理涉众。该所有者对计划和承诺的内容有最终的决定权——如果他们确定某个功能足够重要,足以消耗所有可用的资源,他们可以暂停其他优先级,即使其他人不同意他们的观点。
产品通常由产品所有者拥有,或者有时是实现团队本身(或者是产品所有者和实现者所在的部门——在许多组织中只称为“工程部门”)。这个所有者组织实现者的日常工作,安排工作,跟踪交付承诺,对 bug 报告进行优先级排序,等等。该所有者对产品的完整性具有最终的权威——如果他们确定某个变更将威胁到已经构建的某个产品的稳定性或未来可用性,他们可以阻止该变更的发生,直到进行了适当的规划、流程开发和变更管理。
人员归人事经理所有(或人事经理所在的部门,最终是人力资源部,但在实践中通常看到个人人事经理嵌入所有部门)。该负责人负责职业规划和人事评估,管理人际冲突,包括当人们没有达到预期时,并处理团队运营中所有其他人的方面。该所有者拥有最终的雇佣/解雇权力,尽管他们经常从其他所有者那里获得关于这些主题的信息。
个人工程师和分析师也拥有所有权——对他们实现的细节——但是他们的所有权并没有与其他权力分开。分析师可能不认为分析解决方案是合理的,但是产品经理仍然可以决定该解决方案足够好,可以发布,产品所有者仍然可以决定该解决方案是可维护的,人事经理仍然可以决定开发和维护该解决方案对于员工满足期望和保住工作是必要的。好的组织不会一贯地践踏他们的实现者所关心的事情,但是这样做的权力总是存在的,并且有时是必要的和有益的,因为实现者对于什么是足够好以满足客户需求的标准通常过高。
除非一家公司是一家非常小的初创公司,买不起更好的东西,否则不将这三种权力分开将阻止大多数数据科学家从事任何有意义或持久的工作。当优先级和产品归同一个人所有时,不切实际的特性会在不切实际的时间框架内被批准。当优先权或产品由拥有人的同一个人拥有时,那么错误的优先权或保护产品的失败就会得到加强,因为任何可能反对它们的人都害怕被解雇。
根据我的经验,判断一家公司是否有优先化流程的最佳方式是询问一些最近建造的东西,并询问是如何决定它们应该被建造的。如果这类问题的答案是“[在此处插入高管或经理姓名]表示我们需要它”,那就有问题了。一个企业有一个体面的优先化过程的最好迹象是,人们能够谈论症状、诊断和处方。值得为之工作的公司可以谈论公司感受到的痛苦,解释他们如何确定痛苦的原因,并讲述他们如何建立一些东西来解决原因。其他公司会回避这个问题。
我真正寻找的
在每一种情况下,我真正寻找的是能给我具体细节而不脸红的人。让我们回到工作与生活平衡的例子:
在我目前的工作中,我已经做了两年了,我有两次整个周末都在工作(包括几乎不睡觉)。我这样做是因为我痴迷于一个特定的分析问题,而不是因为任何人要求我这样做,甚至暗示他们希望我这样做。只要不在办公室不妨碍其他人的工作,我可以随时在家工作。如果你和我一起面试,我会看着你的眼睛告诉你所有这些。事实上,很明显,我会有点兴奋地告诉你,因为这是这份工作真正高度重视的一个方面。
与我之前的工作形成对比:我一年有四次通宵/周末工作,一个月有几次工作到很晚,大多数时候我这样做是因为我被告知我必须这样做(或者被告知,带着一种愤世嫉俗的窃笑,有时“你只需要投入完成工作所需的时间”,从而让人们知道期望是什么,而不是实际上告诉我夜以继日地工作)。管理层不太赞同在家工作,尽管我们部门在这个问题上比公司其他部门稍微宽容一些,因为我认为这是一项重要的自由,而且我是那个部门的主管。期限很短是很常见的,设定这些期限的人对个人问题没有多少耐心。如果你和我一起面试这家公司的一个职位,我会给人一种有点防御性的印象。我尽量不做出居高临下的回应,但因为我的经理们经常采取居高临下的态度,其中一些可能会被忽略。你会发现回答这个问题让我感到不舒服。
如果某件事对我来说很重要,和我谈论这件事不会让未来的雇主感到不舒服。如果这确实让他们不舒服,如果我接受这份工作,我可能会对现状感到失望。这适用于我对工作的所有潜在担忧。这不是一个万无一失的方法,但这是我能想到的最好的方法。
如何启动一个有助于你脱颖而出的数据科学项目
寻找有影响力的项目打入该领域的实用方法
Photo by Randy Fath on Unsplash
在未来的某一天,我看到自己在杂乱的数据中寻找答案,发现对一家公司重要的战略洞察力。对于许多像我一样有抱负的数据分析师来说,通往那个目的地的道路正在建设中。知道你正与许多背景和项目都很强的候选人竞争,你会感到沮丧。
你已经完成了一系列关于数据科学的在线课程,或者可能是一个训练营,现在,你渴望应用你新学到的技能。但是你如何着手做这件事呢?什么样的项目可以帮助你获得潜在雇主的注意,你如何寻找他们?
如果你有像我一样的非传统背景,并希望成为一名数据分析师,那么寻找一个项目可能会很有挑战性。具有挑战性,但并非不可能。
在完成 Udacity 的数据分析师 Nanodegree 之后,我开始在网上寻找项目。谷歌搜索显示了大量我可以使用的在线数据集。Kaggle 是我遇到的最受欢迎的来源之一,在那里我找到了我感兴趣的数据集,我喜欢将我的结果与其他用户进行比较的可能性。但是我觉得很失落,不知道从何说起。
我恍然大悟。分析它们是一个很好的练习方法,但是如果我在做一些有可见的影响的事情呢?那不是更有意义和满足感吗?对我来说,是的。
想法不错,但是我怎么才能找到这样的东西呢?
Photo by Toa Heftiba on Unsplash
**数据随处可见。**你可能在一个充斥着杂乱无章数据的部门工作,或者你可能与产生或消耗数据的团队一起工作。
如果这听起来对你来说很熟悉,那就有机会了。我想分享一下我作为一个初学者,从寻找项目机会到启动项目的经历。
寻找一个项目
一个项目解决一个挑战。寻找你的团队面临的挑战。因为你已经熟悉了流程,所以更容易观察你的团队内部,并且发现改进机会也相对容易。
- 在您的团队中寻找挑战或流程改进的机会
- 有数据可以分析和可视化吗?
从小做起。不一定要很大的东西,因为它会让人感到势不可挡。请记住,当我们从小的成功中获得经验时,我们可以继续更大的项目。我们将一步一步地到达那里。
你想解决什么问题?
Photo by Matt Noble on Unsplash
在一个挑战或问题被确定后,是时候把它塑造成一个明确的目标了。这是每个项目的核心,不仅仅是数据科学。而且它很容易失去它所需要的注意力,在这个过程中,你可能会偏离主题,进入其他不相关的问题。
我使用了一个核心工具,这个工具被用来驱动六个名为“DMAIC”的适马项目。你可以在这里 了解更多 。该工具通过提供更好的结构,使复杂的改进项目更容易进行,并有助于将注意力集中在手头的问题上。
“DMAIC”中的“D”代表“定义”。这就是我们定义问题、改进机会或项目的目标的地方。
你如何将挑战表述为一个明确的目标,你能用一个度量标准来定义它吗?
示例: 将 xyz 流程的轧制成品率从 55%(当前状态)提高到 85%(未来状态或目标)。
尽可能具体。这就像你的北极星,你会知道你需要去哪里。
影响
Photo by Jordan McDonald on Unsplash
我再怎么强调这一点的重要性也不为过。你将投入大量时间进行头脑风暴和开发你的项目。要充分利用它,你必须有一个可衡量的影响或结果。招聘经理会有兴趣知道你的计划对公司有什么影响。
韵律学
指标可以帮助您最好地展示影响。仔细选择你的度量标准。它们必须与项目目标相一致,并且应该激励行动。
度量是衡量进展的简单方法。它使团队意识到业务流程的当前状态,并使他们专注于改进和维护它。
影响可以包含在目标中,也可以是结果。例如,减少 40%的处理时间(目标)导致成本降低(影响),比如每年 1 万美元。
谁将使用您的报告或仪表板?
Photo by Miguel Henriques on Unsplash
你的问题陈述现在已经成型了。是时候确定你的利益相关者了。谁是你的观众?
当我在构建仪表板时,我喜欢把我的项目想象成一部电影。目标受众是谁?哪些部门或团队会与我的工作产生互动?
为了进行这一步,我与目标受众和利益相关者交谈,了解他们面临的挑战。你的目标可能与他们的一个或多个挑战相关联。
如果你的项目旨在通过展示洞察力来帮助团队做出更好的决策,那么站在他们的立场上可以帮助你获得更好的视角。
这与下一个要点联系在一起:沟通。
通信
Photo by Christin Hume on Unsplash
通信是数据科学项目的关键方面之一。根据我目前的经验,沟通是两个阶段的关键。
- 与团队成员和利益相关者交流,了解需求和要求
- 通过可视化表达结果和见解
当我为一个产品测试团队开发仪表板时,我意识到了它的重要性,这对我来说是一个未知的领域。
该项目的目标是**“将调试数据的准确性从 50%提高到 95%”。**我没有测试工程领域的专业知识,但是我能够通过问很多问题和与团队会面来回避这个挑战。
- 您的团队目前面临的最紧迫的挑战是什么?
- 哪些因素/指标可以定义和衡量您的挑战?
- 产品测试数据输入的要点是什么?
- 数据是如何输入的?它是自动化的还是有人类参与的?
- 测试团队测量的重要度量是什么?
通过提问,即使你在那个领域之外工作,你也可以对问题有一个全面的了解。
选择您的工具
Photo by Todd Quackenbush on Unsplash
在您开始提取和分析数据之前,了解您在工具和软件方面能走多远是很重要的。您可能需要花一些时间来学习新的分析和可视化包。有时候,我意识到我的大块代码可以使用 Python 库用两行代码轻松完成。但是我想经验会告诉你的。
你也可能有费用限制,比如购买付费软件的许可证。所以你必须寻找免费的替代品。我遵循下面给出的一些简单步骤。
数据提取和分析
- 你的数据来源是什么(Excel,SQL 数据库,文本文件等)?
- 这些文件有多大?
- 数据存储在哪里(云、本地计算机等)?
- 您的数据源始终可用吗?你如何连接到它?
- 数据刷新的频率是多少?
- 是整齐的数据吗?你将如何清洗它?
- 你会用什么来分析和探索数据(Python,Excel,R 等)?
可视化和可用性
- 这是临时分析还是将与团队共享的仪表板?
- 您需要多久创建一次此报告?
- 用户会与之交互吗(比如改变过滤器、日期等)?
- 您将如何共享此报告或仪表板?
- 你能自动共享和刷新数据吗?
完成这个练习将帮助您评估项目的复杂性,并帮助您决定将使用的工具。
最初,我用一些可视化工具来来回回地寻找哪一个最合适。一开始你可能不会选择“完美”的工具。这是正常的,这是学习过程的一部分。
启动您的工作
在开始工作之前,确保满足所有要求,并验证数据的准确性。在数据清理、探索和可视化之间来回是很正常的。
当我的项目准备启动时,我与团队召开了一次会议,培训他们如何使用它。
我还参加了团队会议,见证了成员根据开发的仪表板提供的可视化和洞察力做出决策。让管理层参与这些会议也是一个好主意。这会让你的工作更加引人注目,他们可能会给你带来更好的工作机会。
永远做一个初学者
专家和初学者的区别在于,专家已经多次经历了初学者的循环,并努力克服它。
当我开始用 Python 编程时,我是熊猫的初学者,但随着时间的推移,我变得更好了。最近,我在做一个需要我学习 SQLAlchemy 的项目。所以我又回到了初学者的状态。渐渐地,我越来越擅长了。这个循环将会贯穿你的学习过程,我们必须拥抱它。
抬头!
一路上可能会有很多非技术性的挑战,这可能会让你感到气馁。
我曾经遇到过这样一种情况,我在一个过程中发现了一个缺陷,而一个团队成员对此很不高兴,因为他对此负有责任。我和他安排了一次一对一的会面,他逐渐敞开了心扉。在他的帮助下,我们绘制了流程图,确定了瓶颈和衡量流程绩效的指标。
练习情感共鸣和积极倾听团队成员的问题帮助我应对这一挑战。保持开放的心态有助于我更好地理解并找到根本原因。
最后的想法
从小处着手,然后扩展到更大的计划,这是一个很好的尝试方法。这将激励你接受更大的项目,你会在这个过程中学到很多。一个强烈的想法浮现在我脑海,我想与大家分享。
“如果你忘记了你必须攀登的山峰,只关注下一步,伟大的事情就会发生。”
—德里克·菲茨杰拉德,铁人三项赛选手,心脏移植幸存者
你有什么想法?我很想知道。
如何开始在介质上写作
数据科学作家第一个月的实践建议分析
Photo by Free-Photos on Pixabay
一个月前,我开始在媒体上写故事。作为一名人工智能爱好者,我将我的博客帖子发给了一家名为走向数据科学 (TDS)的出版物,该出版物目前拥有大约 28 万名粉丝。这个故事是我经过一个月 6 个故事的分析思考的总结。
上个月,我在 TDS 上发表了 6 篇自然语言处理领域的故事。我的故事涉及伯特和机器翻译。总的来说,我有超过 12k 的浏览量,5k 的阅读量和 100 个粉丝。希望这个故事可以成为考虑在介质上开始书写载体的人的指南。
对写作的热爱
首先,我想谈谈我的动机。我开始写这些故事,作为我经历的总结。我在研究新的科学领域,我想保留我对它的第一印象。像日记一样。然而,我想分享它,这样每个新进入这个领域的人都可以从中受益。
第一个月结束时,我注意到我可以在日常工作中使用我的故事作为帮助。为了有一个好的媒介故事,我已经把实验打磨成一个可读的、可理解的工具,如果我需要的话,我可以回头去找它。
我还有第二个动机:作为一个非英语母语的人,我发现写作是保持语言技能的一个很好的练习。作为一个早期职业科学爱好者,我认为写媒介故事是写科学论文的一个很好的练习,也是在该领域获得更多认可的一个好方法。
我对中型合作伙伴计划也很好奇。有可能以此为生吗?当它的第一个结果出来时,我意识到我的动机开始从“写一个好故事”转变为“写一个高薪的故事”。最明显的影响是,我每天都感受到写作的压力,而不是分享知识的快乐。目前,如果我觉得我的主要动机是错了,我会有意识地停止写作。
My stories on Medium. The first one is published in Quick Code, the others in Towards Data Science
一个中等故事的阶段
Medium 提供读者分布的统计数据。你可以了解你的故事是如何传播给谁的。基于此,我把故事的生命分成三个主要阶段。
- 早期观众
- 社交媒体分享
- 媒体和出版物发行(TDS)
- Android 应用和谷歌 Chrome 建议
- 来世(幸好谷歌搜索结果)
Reader distribution of one of my stories published in TDS.
早期读者是你发送给你的故事的朋友,你的追随者和出版物的编辑。他们是潜在的第一批粉丝,他们可以纠正你故事中的明显错误。
社交媒体分享来自你的 Twitter /脸书/ LinkedIn /等。以及早期观众的分享。对于我所有的故事,一些我不认识的随机 twitter 用户分享了它,导致了 10-20 次浏览。(非常感谢!)
**媒体和出版物发行:**前两个阶段对于第三个阶段非常重要。媒体策展人和出版物的编辑都可以选择在网站的某个地方分享你的文章。我不知道这些决定背后的实际过程,但我认为故事的早期观点和掌声是重要的。当然最重要的还是故事的质量!
我的故事的原始数据是,我在 TDS 上发表的所有故事都是由媒体策展人选择发行的。根据其他的故事(像这个),这是一个伟大的成就。关于 TDS 分发,对我来说重要的一步是当 TDS 在他们的 Twitter 上分享故事时。我一半的故事都发生了这种情况,我不知道这是什么模式。
**安卓应用&谷歌 Chrome 建议:**这些都是大数字!为了在 Android 应用程序或 Chrome 建议中赢得一个好位置,故事必须在前面的阶段表现良好。中等适合 Chrome 建议,所以在 Chrome 建议中有很多中等的文章。然而,要获得这些位置,你必须写一些热门的东西,一些人们现在想读的东西。
来世:媒介故事就是新闻。它们在开始时有一个 3 天的高峰,但过后就消失了。对于一个在第一天获得 100 次浏览的故事,在第一周之后,它每天有 10 次浏览。一个 500 次浏览的高峰故事有 20-40 次浏览,一个第一天有 2000 次浏览的故事在第一周之后有 300 次浏览。相关性显而易见。然而,令我惊讶的是,在第一周之后,这些数字相当稳定。我预计未来几个月会缓慢下降,但这只是一个假设,因为我在 TDS 上的第一篇文章才发表了一个月。到目前为止,我的故事里还看不到这种趋势。
增加来世浏览量的一个方法是给这个故事加上一个标题,这个标题很适合用谷歌搜索。比如我有一个故事叫简单 BERT 使用 TensorFlow 2.0 *,*它在标题中有两个热门话题的名字( BERT 和 TensorFlow )和一个不错的 Google 搜索关键词(简单)。如果我考虑得更周到,我可能也会在标题中添加关键字 example 。
Views of a story: 3-day peak and afterlife
我的操作列表
如果你对这个话题感兴趣,你可以在 Medium 上找到很多关于如何成为一名优秀作家的文章。在这里,我将添加我的列表建议。
我的成功作家清单:
0.英语
- 质量
- 一致性
- 出版物
- 最畅销的关键词
以英语为母语的人可能没有意识到他们的障碍,但是如果你把英语作为第二语言,你可能会在生活中有这样的时刻,你认为“用英语会容易得多”。是的,用英语写作更容易。即使它不是我的母语。假设我用匈牙利语写了一个故事,它有 100 次浏览,以同样的速度,一个英语写的故事将有 20,000 次浏览!(根据本文对英语用户的估计。
关于质量我不想写太多。是的,质量很重要。很多。阅读高质量的论文,认真写作,使用工具,倾听读者和编辑的意见。你会进步的。
我预测一致性的重要性会变小,但在第一个月之后,我不得不纠正自己。我已经提到过,我的老故事的每日视图是相对恒定的。这些故事每天的收入都差不多。如果你写了 4 篇文章,每天赚 0.5 美元,你每天赚 2 美元。如果你写了 40 篇文章,就是 20 美元。
此外,写一个新的故事也可以促进旧的故事,因为如果你写了一篇好文章,你的读者可能会想你是否也有其他伟大的文章。
My views in the first month.
如果你打算在媒体上写作,你可能知道出版物的存在。找到高质量的出版物,它们会帮助你写出更好的文章,提高你的浏览率。因为对数据科学感兴趣,我的故事被媒体策展人选中发行,并被 Chrome Suggestions 推荐。
我的最后一个要点是我称之为**畅销关键词的东西。**总有热门话题,读者搜索的词。你的兴趣并不总是与大多数读者的兴趣相同。但有时确实如此。如果你找到合适的术语,并把它放在你文章的标题中,它可以提升你的观点。但是不要写你不真正感兴趣的东西。即使你以写作为生,也要找到非常适合你的话题!
基于介质读取的支付
11 月初,Medium 换成了基于阅读的支付方式,他们升级了故事的统计数据。下面是基于我的故事的表现对这个新特性的分析。
Earnings of my stories since Medium shows daily earnings
首先,我们对故事有了一个新的总体衡量标准,叫做平均阅读时间。对我来说总是在 30 到 50 秒之间。我认为这包括那些点击了我的文章,但在意识到这个故事在付费墙之下后关闭了它的读者。那些刚刚浏览过的人。根据文章的长度,Medium 估计阅读时间为 3-8 分钟。不是每个人都深思熟虑地阅读它。
对于一个故事的每日浏览量,我们得到了两个新的每日统计数据:每日收入和每日会员阅读时间。一个故事的收入是基于会员的阅读时间。对于每个媒体会员,他/她的会员资格$5 被分配给他所阅读的文章的作者,该作者根据他/她在文章上花费的阅读时间进行加权。
下图是从我的三个故事中提取的数据。其中一个共有 600 次浏览,另一个 1800 次,最后一个 7000 次浏览。所有数据都来自新时代的第一天(10 月 28 日-11 月 15 日)。由此,我们可以计算出,我的读者每阅读一分钟,我的平均收入是 0.04 美元。
The correlation between reading time and earnings based on 3 stories
摘要
这个故事是我作为一个媒介作家的经验总结。我在出版物《走向数据科学》中撰写数据科学文章(更具体地说是自然语言处理相关的故事)。我在 10 月 14 日发表了我的第一篇文章,这篇文章分析了第一个月的情况。我写了 6 篇文章,总共有 12k 的浏览量,5k 的阅读量和 100 个粉丝。到目前为止,我在中等合作伙伴计划中赚了 91.47 美元。
如何从数据科学入手
数据科学从零到英雄
数据科学是最热门的领域之一。它既实用又有创造性,你会学到很多东西,并解决现实世界中的问题。如果你想知道如何开始,这里有一个简短的指南。
How to make a career change and become a data scientist
数据科学课程
已经建立了许多课程和组织来帮助人们开始学习。谷歌数据科学训练营或面向所有人的数据科学,你会发现专门帮助人们开始学习 Python 数据科学的课程。线下课程可能会很贵。但是如果你已经准备好开始学习,我建议你每周花几个小时参加在线课程,你肯定会感觉更舒服。如果你决定参加数据科学训练营,我建议你先做一个可以展示的真实项目。这将让您对 data scientist 的工作有一个很好的了解。
在我的另一篇文章中,我写了关于建立数据科学项目组合的文章。
数据科学会议
另一件事是数据科学会议。你绝对应该在你所在的地区寻找一些,并至少参加一次,看看数据科学家在谈论什么,现在什么是趋势。这是跟上该领域最新工具和技术并向业内最优秀的数据科学家学习的绝佳方式。如果你想了解该领域数据科学家的最新动态,请关注数据科学子网站和最佳数据科学家的博客。确保跟上数据科学界在大数据领域开发的所有最新工具和技术。这将确保您能够获得最新的工具和技术,从而利用您的经验和技能。
数据科学家的收入
这是学习数据科学的大好时机。你可以作为一名数据科学家创业,你可以开始建立自己的事业,你会过得很好。
我已经在这个帖子里谈到了如何进入数据科学,是时候学习如何做好它了。
这需要一些时间,但你会成功的。
当我第一次开始时,我开始阅读所有关于这个主题的书,但我很快意识到其中许多都过时了。
我现在更喜欢接触真实的数据。我现在开始处理来自真实世界的真实数据。
如果你想开始数据科学家的职业生涯,是时候开始收集数据了。
现在有比以往更多的信息和工具可以帮助你收集数据——首先是 Kaggle 的公共数据库,GitHub 的开源代码,Reddit 的许多链接和文章,你可以抓取和重复使用。
获得数据科学领域的实习机会
当然你不一定要创业才能成为数据科学家。另一个自然的方法是找实习。
有很多方法可以获得实习机会,但第一种方法是直接联系招聘公司。
第二种方法是寻找那些想雇佣实习生的公司,并与他们接触,看看你是否能得到实习机会。如果你能展示你的作品,电话推销真的有用(再次 GitHub!).
你越主动越好。开始在 LinkedIn 上写你的数据科学项目,在 Medium 上发布帖子以获得更多的关注。最理想的情况是当招聘人员找上你,而你是他们要选择的人。唯一的方法是将工作投入到你的开源数据科学项目中,并推广你正在做的事情。
如果这不适合你——因为你只是对如此公开感到不方便,这很好——那就开始在许多求职网站和团体上寻找实习机会。这是一个员工市场,如果你能展示出你的参与度和热情,你应该能够得到潜在雇主的初次电话或会面。
努力工作,祝你好运!
Data Science Job
最后,如果你想了解成为一名数据科学家意味着什么,那么看看我的书数据科学工作:如何成为一名数据科学家,它将指导你完成这个过程。
如果你想了解更多,请阅读我关于成为数据科学家的其他文章:
如何开始你的第一个数据科学项目
启动您的数据科学之旅
在面试时展示一些数据科学项目是进入数据科学领域最重要的先决条件之一。
你可能问了一些问题,如下:
我应该如何开始一个数据科学项目?
我应该做哪种题目?
我应该使用哪种数据集?
以前,当我在考虑我应该从事什么样的数据科学项目时,我努力想出一些实用而独特的想法来开始我的第一个数据科学项目。网上有大量的数据科学项目,但我确实希望我能做一些不同的事情。
需要注意的一点是,我所说的数据科学项目不是一个学校项目,而是一个个人数据科学项目。
你可能会想,为什么不是学校项目?
假设您是招聘经理,您打算只招聘一名数据科学家。假设你心中只有两个候选人。他们两个似乎有相似的背景,但是你只考虑雇佣其中一个。因此,你给了他们两个人一个面试的机会,并告诉他们准备好他们之前的项目提交给你。
候选人 A:这是我在一个四人小组中完成的一个学校项目。我负责建立机器学习模型。
应聘者 B:我在找房子的时候一直面临一个问题——我如何知道我喜欢的房子的面积租金是否合理。因此,我开始致力于这个项目,以澄清我的疑虑。
那么,你会更有兴趣听哪位候选人的呢?我觉得答案挺明显的,就是候选人 b。
在这篇文章中,我将分享如何开始一个个人项目的逐步指南。
第一步:确定一个要解决的现实问题
找到自己的痒处。例如,你有一个销售钥匙链的网站。你已经厌倦了浏览评论,你想自动化这个过程。因此,您可以建立一个情绪分析模型来确定您的客户是否满意。
也许你认为这个项目太容易了,并愿意进入下一个阶段。您可以使用构建主题建模模型来了解您可以改进的领域。例如,你发现你的客户一直在评论的一个话题是钥匙链设计缺乏变化。因此,通过不看评论,你可以知道你应该改进的地方。
另一方面,也许你正在持有一些股票。你根据一些规则或技术指标来买卖你的股票,但是你想让它自动化。这里有两种自动化的方法,要么你写一个程序来找出信号,要么训练一个模型来读取最新的消息,这样你就可以比信号出现的速度更快地出售或购买它。
你仍然可以从 Kaggle 项目开始,但是如果你能发现并解决你的问题,这意味着你有能力自己定义和解决问题。
如果你想要一些关于这个主题的参考资料,你可以参考下面的网站:
- https://www . analyticsvidhya . com/blog/2018/05/24-ultimate-data-science-projects-to-boost-your-knowledge-and-skills/
- 【http://intellspot.com/data-science-project-ideas/
步骤 2:决定要处理哪个数据集
你可以选择使用 Kaggle 等开源数据集,但也可以选择自己收集数据。
有几种方法可以自己检索数据。最简单的方法是使用目标网站提供的应用程序接口(API)。如果你想挑战自己,你可以尝试抓取网站来获取你的数据。通常,数据会更脏,因此你可以展示你的数据清理技能。
如果你不想抓取数据,我的建议是选择一个更大的数据集,这样你就可以在处理大型数据集时有更多的机会。
另一方面,您可以选择更难检索的数据集。例如,当我试图对马来西亚汽车市场进行分析时,我能得到的公共数据集只有 PDF 扫描图像。因此,我必须执行 OCR(光学字符识别)来从 PDF 中的表格中提取数据。
如果你有兴趣知道更多关于我如何设法提取数据的细节,请随意访问这个链接。
访问开源数据集的链接:
- https://github.com/awesomedata/awesome-public-datasets
- https://www.kaggle.com/datasets
- https://www . freecodecamp . org/news/https-medium-freecodecamp-org-best-free-open-data-sources-any one-can-use-a65b 514 b 0f 2d/
执行分析和建模
在尝试任何模型之前,尽最大努力深入研究数据。仔细观察,以确定可能的模式或趋势,并输入到机器学习模型中。
请注意,收集、清理和分析部分将消耗您的大部分时间。不要太强调建模部分,反而应该多花点时间在特征工程部分。如果你能为你的模型找到一个好的学习特征,你的模型很有可能从这个特征中学到很多。
此外,画出你认为对解决问题很重要的有用的图表。不要为了展示你的绘图技术而画图表。永远记住,大多数人寻找的技能是克服商业障碍的能力。
最后的想法
对于那些没有数据科学背景的人来说,项目可以被描述为你解决任务能力的代理。因此,一定要明智地选择一个题目,并努力去做。
默默努力,让你的成功成为你的噪音——蒂芙尼·特朗普
非常感谢你阅读到最后,这是我的新网站提供网络爬行服务。如果你想找人帮你抓取数据,请随时通过 Linkedin 或上述网站联系我。
关于作者
低伟鸿是 Shopee 的数据科学家。他的经验更多地涉及抓取网站,创建数据管道,以及实施机器学习模型来解决业务问题。
他提供爬行服务,可以为你提供你需要的准确和干净的数据。你可以访问这个网站查看他的作品集,也可以联系他获取抓取服务。
如何开始自己的机器学习项目
哪些课程没有(也不能)教给你
Where most of my project work goes down. See more on YouTube.
戴夫开始说话。
测试结果出来了。怀尔德是聋子。
完全?
是啊,他没有在听力表上记录任何东西,即使他们在他耳边播放一种像喷气式飞机起飞一样大的噪音。
接下来会发生什么?
我们将进行更多的测试,如果他符合条件,他将接受耳蜗植入来帮助听力。但是他们还不确定。
戴夫是我最好的朋友。怀尔德是他的儿子。他天生失聪。医生说:“十万分之一的几率。”
我知道除了听,我什么也做不了。感到无助不是一种好的感觉。
几个星期后,我们在怀尔德的开关上。这是他第一次打开人工耳蜗,使他能够听到声音。他通过了所有的测试,是这些设备的主要候选人。
当他们上场时,这位女士放了三个音。一个高,一个中,一个低。她追踪了怀尔德对每一封信的反应。"该软件将在两者之间的空隙中构建."她说。
接下来还需要几次预约才能让植入物充分发挥作用,但这是第一次,即使只有轻微的声音,Wylder 也能听到了。
活动的前一天早上,我早早起床,开始在 Coursera 上学习生物信息学专业。我想知道更多。必须知道更多。什么是生物信息学?这是生物学和技术的交叉。维基百科增加了一点深度。
生物信息学是一个跨学科领域,开发理解生物数据的方法和软件工具。作为一门跨学科的科学,生物信息学结合了生物学、计算机科学、信息工程、数学和统计学来分析和解释生物数据。
为什么是生物信息学?我想知道更多关于怀尔德的事情。耳蜗是什么?是什么原因造成的?是基因吗?哪个基因?我所知道的编程知识能有所帮助吗?
为什么 Coursera ?因为在过去的两年里,我的很多知识都是从这里开始的。
关键词是基础。课程和专业非常适合这个。但是知识增长的真正方式是通过修补,探索,扩展,建立在这些基础之上。
所以我建立了自己的项目。一个探索 DNA。寻找与内耳毛细胞发育有关的基因。他们做了什么?毛细胞将声波转化为大脑可以解释为声音的电信号。我能在生物信息学专业中使用我所学的代码操作 DNA 吗?是的。
但事实证明这一切都是错的。
我所做的一切都没有生物学或科学基础。我给做了一个关于它的视频,评论里有人这么说。我已经知道了。我在视频的开头加了一条,在描述中也加了一条。
如果错了又有什么意义呢?
我们会谈到这一点。最好先从为什么开始。
为什么是你自己的项目?
当你开始学骑自行车时,你戴着辅助轮。你学会了如何兜售,如何刹车,如何移动车把。
但是你遗漏了一些东西。骑自行车最重要的技能。平衡。
只有当训练轮脱落后,你才学会如何保持平衡。
我在 Coursera 上使用了应用数据科学和 Python 专门化来建立数据科学的知识基础。但是当我致力于构建探索性数据分析的温和介绍时,我学到了更多。这也是不对的。看过的人自己研究了一下,告诉我。所以我修好了。然后还有一个别人发现的错误。我修正的每一个错误,都让我学到了新的东西。更深层的东西。一些我以前没见过的东西。
有知识基础很重要。知道如何兜售,如何刹车和如何驾驶对骑自行车很重要。但是当训练的车轮停下来的时候,学习更多的这些东西是不会帮助你的。
课程也是一样。你可以继续完成更多的课程,提高你的知识基础(你应该这样做),但不要把这误认为是能力。
参加更多关于如何更好地兜售的课程不会让你骑自行车。
只有当你卸下辅助轮,你才能学会骑车。
一些可能不起作用的东西
最好的项目就是这样开始的。
当你去旅行时,有一个指南针和一张地图是很好的。但是如果你只能选择一个呢?哪个更重要?
指南针。
为什么?
因为地图只有一定数量的路径。指南针可以有无数种用途。
这就是你如何构建自己的项目。从你想去的方向开始。一个想法,一个主意。那是你的指南针。
计划好你要采取的步骤是有价值的,但是不要让它阻碍探索。
没有一个伟大的项目是从一个人预先知道他们要走的确切路线开始的。如果你已经知道事情会如何发展,你会感到厌烦。已知的未来已经成为过去。
交叉规则
这就是混合想法的切入点。假设你一直在学习数据科学和机器学习。你已经学了一些课程,但现在你想学更多。
你不可能在一件事情上做到最好。你可以试试,但是记住,竞争很激烈。更好的选择是成为跨界者中的佼佼者。两件事,三件事,四件事的交叉。但是不要太多,否则质量会开始下降。
这与项目有什么关系?
你可以利用你在课程中积累的知识基础,并将其与你在心理健康方面所做的研究相结合。你如何利用数据向他人展示对精神健康世界的见解?
如果你是一名音乐家,你可以使用机器学习从你的旧录音带中创作一首新歌。
例子不胜枚举,但公式保持不变。无论你的兴趣是什么,健康、艺术、技术、科学、金融、工程、天气,交叉在哪里?
The crossover happens when you take one of your skills and pair it with another.
允许犯错
在考试中做错了什么,它通常会返回一个红叉,旁边写着你错了。
学校强调避免犯错。生活鼓励它。
这并不意味着你应该有错的目标。但是当你开始自己的新工作时。一个可能行不通的项目,允许自己犯错。
为什么?
因为犯错会调整你的罗盘。这是一个学习的机会。现在你知道哪里不能去了。
我的下一个项目会更好,因为我的上一个项目有错误。
创建一个时间表,从小处着手
我将为此工作四周。
你可以这么说。连续四周每天一小时是很好的时间。
你可以根据自己的需要调整这些数字。但是有一个截止日期给了你努力的方向。
我哥哥和我在咖啡馆。他开始说话。
我一直在看这门课。
给我看看。
他给我看了。我通读了一遍。我说话了。
但是你已经做了所有这些事情?你已经完成了基础,你已经完成了高级数据结构,你已经完成了发布你自己的项目。你想从中得到什么?
我不确定我认为了解更多会有帮助。
你一个月做一个小 app 怎么样?称之为 App 一个月,分享一个关于每一个的故事。
是的,你说得对,第一周是设计,第二周是计划和原型制作,第三周也一样,然后在第四周发布。
他的眼里充满了想法。我笑了。然后说话了。
现在你在想。
你可能无法控制你的项目是否达到你想象的一切,但是投入一定的时间和精力是可以做到的。
总会有干扰。生活就是这样。当它发生时,处理好它,然后带着时间表回到你的项目中。
Once you’ve picked something to work on, shut everything else out for a period of time.
当你准备好 70%的时候开始
够了。你永远不会 100%准备好。
分享一个故事
你选择了一些不可行的东西,你使用了交叉法则。你还没完全准备好就开始了。你坚持你的时间表。
现在怎么办?
装运它。分享你的所作所为。
现在其他人可以批评你的工作,告诉你哪里错了,告诉你哪里对了,帮助你变得更好,这就是你所追求的,不是吗?
下次有人问你在忙什么,你就有故事了。
我开始从事一个生物信息学项目,我不知道结果会如何,但我脑海中有一个想法。我想看看我是否能把我在 Coursera 上的生物信息学专门化课程中学到的东西结合到我最好的朋友的儿子身上。他天生失聪,所以我研究了是什么基因导致婴儿失聪。我发现了 ATOH1 基因。它负责触发耳朵中毛细胞的生长。毛细胞将声波转化为电信号。我花了大约一个月的时间进行研究和构建,但当我有了一些东西时,我制作了一个视频,并在网上发布了我的代码。我意识到我的发现没有一个是生物学或科学上合理的。有人给我指出来了。但是现在我知道我下一步要去哪里了。我被迷住了。
我的生物信息学项目错了。但是我学到了一些东西。我知道下一步该做什么。
我的探索性数据分析教程有错误。人们好心地给我指出来。这让它变得更好。这让我以后的工作更好。
你听过我的。你呢?
你可以在 Twitter 、 LinkedIn 、 YouTube 和mrdbourke.com上找到更多我的作品和故事。
学习数据科学时如何保持动力和生产力
学习数据科学需要耗费大量的时间和精力。你需要理解数学、计算机科学和无数不断变化的工具的组成部分。这是一项艰巨的任务,很难保持动力。
随着时间的推移,我发现了各种有效学习数据科学技能的方法,同时对我的工作保持兴奋。我把这种智慧浓缩成了 5 个“秘诀”。我希望你能和我一样从下面的概念中受益!
Photo by JESHOOTS.COM on Unsplash
所有这些技巧都来自我读过的各种书籍。提示一来自 James Clear 的 原子习惯 ,提示二和三来自 Sean Covey 的执行的 4 个纪律,最后两个提示来自 Cal Newport 的 深度作业 。这些书对我的生活和工作方式产生了巨大的影响,所以我强烈推荐它们。
秘诀 1:从小处着手,培养良好的习惯
习惯是学习任何新领域的关键。不幸的是,所有伟大的习惯都需要重复。如果某件事稍微有点困难,我们就不太愿意去做。这里的智慧是在开始的时候让习惯尽可能简单,然后在此基础上发展。首先,找出你想要培养的行为,然后提炼出它最基本的形式。
例如,当我第一次试图减肥时,我开始每天只做一个俯卧撑。希望即使我躺在病床上,我也能完成这项活动。门槛太低了,如果我不这么做,我会觉得自己很糟糕。
我很快发现,一旦我趴在地上做俯卧撑,我会倾向于做更多(谁会只做一个俯卧撑呢?).我还发现,如果我只有时间创作一首单曲,我也不会感到难过。对我来说,创造可持续习惯的两个关键是:( 1)让开始变得容易;( 2)如果你做了最少的事情,不要感觉不好。
几周后,当俯卧撑根深蒂固时,我开始建立这个习惯。我慢慢增加我每天做的次数。我还加了一个引体向上和 2 分钟的动感单车。经过一年的这种结构,我已经建立了每天大约 45 分钟的拉伸和锻炼,我几乎从未错过。
从数据科学的角度来看,我会从每天写一行代码开始。你甚至不需要电脑,你可以在笔记本上做伪代码。你也可以承诺每天阅读你最喜欢的数据科学账户的推文,看看 kaggle 内核,或者看一小段数据科学 YouTube 视频。如果你养成了这些习惯,在你意识到之前,你每天都会做大量的数据科学实践!
技巧 2:设定明确的目标,专注于你的“领先指标”
我们大多数人都关注那些我们不能立即控制的事情。最明显的例子就是减肥。大多数人关注的是体重秤上的数字;然而,这在日常生活中是很难影响的。通常,立即减肥是不健康做法的结果。另一方面,我们可以跟踪许多其他我们可以“健康”控制的事情。我们测量每周去健身房多少次,或者我们吃了多少卡路里。这两件事高度相关(甚至是因果???)的减肥。此外,我们几乎可以完全控制是否执行这些活动。
去健身房和计算卡路里是领先指标的例子,因为它们在目标(减肥)之前。我们减掉的体重被认为是一个滞后指标,因为它跟随着我们采取的行动。
控制和即时反馈是自我激励的组成部分。关注销售线索指标允许您将这两个元素注入到您的工作流程中。
知道目标是什么并为其设定界限仍然很重要。如果我们不知道在特定的时间段内我们想要减掉多少体重,我们应该如何调整我们的健身房和饮食需求就不清楚了。在离散的时间框架内创建具有清晰结果的滞后指标。
在我职业生涯的早期,每当我试图学习一种新的算法时,我都会应用这个方法。我的目标通常是每两周用一种新方法做一个项目。完整理解的一些示例指标如下:
- ***(导语)*观看 3 段解释这一概念的视频
- 阅读两篇使用该方法的学术文章
- (lead) 用 python 从头开始编写算法
- ***(领导)*完成项目并与同事或在 YouTube 上分享
- ***(滞后)*在两周时间内展示对新算法的理解
如果我执行了这些步骤,我对自己对新概念的理解感到满意。
我在找新工作的时候也应用了这个。我的目标是在两个月内找到一个新的角色。这项活动的一些主要指标是:
- ***(领导)*每天发出 3 份申请
- 每周进行两次信息访谈
- (lead) 每天花 30 分钟编写&数据科学面试问题
- ***(领导)*每两周完成一个项目,添加到我的投资组合中
- ***(滞后)*两个月内获得一份新的数据科学工作
同样,我知道如果我虔诚地做这些活动,我想要的结果就会随之而来。
提示 3:通过记录分数和依靠你的同事来保持责任感
将你的生活分成超前和滞后指标并不难。然而,很难在他们身上执行。我发现的最好的方法是记分。我在成长过程中参加过许多运动,我知道当我知道我们在记分时,我总是会提高我的水平。我个人在每天填写的“记分卡”上记录我所有的领先和落后指标。这是把你所有的日常习惯都放在一个地方,并收集一些关于你自己的数据的好方法。你已经收集和分析了所有其他方面的数据,为什么不看看你自己的呢?
从动机的角度来看,这个行动让你的生活变得有趣。它还鼓励你对自己诚实,这有时很难做到。
虽然为自己记分会给你指明正确的方向,但让别人对你负责会增加赌注。让你的学习伙伴、朋友、同事或家庭成员也对你负责,会对你的工作效率产生奇迹。让自己失望是一回事,但让你在乎的人失望是完全不同的另一回事。
理想的情况是和另一个人一起学习数据科学。如果你没有跟上你的目标,你可能会觉得你被落下了。
提示 4:安排好你的一整天,包括休息时间
在我开始工作之前安排我的一天对我的能量水平来说是革命性的。以前,我会花费大量的时间和精力在“下一步”要完成的活动上。日程安排消除了所有的认知努力,让你不用去想接下来一天要做什么。你只需要看看你的日历,执行它告诉你做的任何事情。如果你想学技术,按计划编写就像编译代码然后执行它。在大多数情况下,要求您预编译代码的语言执行速度更快。在编译的过程中,所有的变量类型都被检查,所以计算机知道它可以执行这个文件。在解释语言中,由于这个额外的步骤,运行代码需要更长的时间。
我支持安排你一天中的每一部分,包括休息时间。通过这样做,你可以避免休息蠕变*,因为你已经限制了你的休息时间。我过去常常做完事情,完全不知道休息时间有多长,因为我不确定下一次休息会在什么时候。用这种方法,你可以准确地知道何时何地你会得到另一次休息。*
当安排时间时,如果你的一天被劫持了,重新调整是很重要的。这对我来说非常普遍,可以认为是积极计划的一个陷阱。我发现只要我花一些时间(5-10 分钟)来调整我的时间表,我就可以相对容易地完全回到正轨。如果我在一颗小行星毁了我的一天后试图即兴表演,事情会很快失控。
技巧 5:设计你的工作场所,优化工作质量
成功学习的关键是让事情对你来说尽可能简单。如果你不想吃垃圾食品,你可以把它留在身边,用意志力来抵抗这种渴望,或者你可以一开始就不买。对抗你的意志力会消耗我们的注意力和精力。后一种选择是最大化你的生产力和内心平静的最佳选择。
学习数据科学时,您希望限制任何外界干扰。我建议在投入时间学习时,做以下环境方面的调整:
- 关闭电脑上所有多余的窗口。只打开与手头任务相关的窗口。最坏的情况是,把你所有的其他东西放在你电脑上的另一个虚拟工作空间里。
- 把你的手机放在另一个房间,只在你预定的休息时间查看
- 关闭手机和电脑上的所有通知
- 在一个与你放松或休息的地方分开的地方工作。人们很容易被舒适的床、沙发或电视所诱惑。
你还在等什么?
这些见解改变了我个人的工作方式。我希望它们能帮助您学习数据科学,并最大限度地提高您的生产力和积极性!
作为一名数据/研究科学家,如何与时俱进
我如何跟上所有新的研究论文和新的机器学习更新?让我告诉你我是做什么的。
I am sitting somewhere in there if you can spot me. (Image is from https://www.flickr.com/photos/teamrework/31974957947/in/album-72157676030072907/)
介绍
你好。
S o 看了我的教程 无学位如何数据科学 ( 39k 浏览量和统计截至 2019 年 1 月!谢谢你。 ) ,但你的旅程才刚刚开始。随着每年数百篇研究论文的发表和深度学习行业的重大技术进步,很难保持领先。
尽管我热爱我的工作,但我知道如果我不跟上时代并继续学习,就很难保持胜任和相关的工作。尽管你在数学、编程和机器学习方面的基础知识总是必不可少的,但是新的想法和工具每天都在被引入。你必须不断学习。
跟上时代是我不断努力掌握的东西。是的,这可能让人不知所措,但是深呼吸一下,知道这对任何人来说都不容易,你就会感到安慰。为了让你的旅程更轻松,我想分享一些我非常喜欢用来保持领先的技巧和资源。这些是:会议、Twitter、工程博客、时事通讯、研究论文和 YouTube。
1.会议
At the Rework Deep Learning Conference
我想从会议开始,因为我刚刚在 2019 年 1 月从一个会议回来。在我看来,这可能是最昂贵但也是最有趣的选择。自从我成为数据科学家以来,我已经参加了以下会议:
- 2018data bricks Spark+AI Summit @三藩 。
- 2019 返工深度学习峰会@旧金山 。
置身于一个充满专家、领导者和渴望学习你所呼吸和实践的话题的人的环境中是相当超现实的。虽然我发现在这些会议上与陌生人交谈并不容易,但与会的每个人都很高兴与你谈论他们的兴趣和项目。例如,午餐时,我和坐在我旁边的人就他们的工作和项目进行了许多有趣的对话。了解不同的人和行业如何应用深度学习真是太棒了。
此外,我真的很喜欢参加会议上的演示,因为你可以看到其他人正在做什么,看到趋势和新技术。看到像谷歌、脸书和 OpenAI 这样的研究领导者在做什么是非常激励人心的。此外,你还可以听到像 Dropbox 、易贝、 Airbnb 、优步和网飞这样的公司在深度学习方面做了什么。发布会结束后,我想起了甘(生成对抗网络)的力量,想尝试学习一下 PyTorch 因为1.0 版本终于在 2019 年 1 月发布了。
既然你不再处于一个结构化的学校环境中,我把这些会议视为学校课程。记得参加 Spark 峰会的时候,了解到熊猫 UDF (我相信是在 Spark2.3 版上),回去后马上开始在工作中使用。
当你在自学或在公司做项目时,行业的所有变化和趋势可能都不是很明显。但是参加会议真的给了你视角,让你亲身感受到每个人都在做什么。
有几种方式可以参加:
- 让您的公司支付费用(最佳选择)。如果你们一起去,要求打折。即使你不跟团去,他们也经常提供折扣。所以就问吧!
- 要求在大会上做志愿者,免费去(我遇到过这样做的人)。
- 作为学生参加,你通常可以得到很大的折扣。
接下来,我想尝试去 **NIPS(神经信息处理系统)和 ICLR(国际学习代表大会)、、**这两个更偏重学术的地方。
2.推特
Example Deep Learning News on Twitter
我之前并不是很喜欢 twitter,但是因为深度学习新闻我又开始了。我发现许多人(研究人员和公司)在 twitter 上发布有价值的最新信息。正如你在上面看到的, GoogleAI 账户经常发布他们深度学习研究的更新。
当我开始关注一些著名的深度学习的人和公司账号( @GoogleAI、@OpenAI、@AndrewYNg、@ KDNuggets、@Goodfellow_Ian、@YLeCun、@Karpathy )时,我很容易找到其他人,因为 twitter 一直在推荐类似的账号。
我的账号目前超级无聊,不过可以随意关注: @jasjung_ 。我计划用它来发布自发的提示或更新,但主要是向其他深度学习明星学习。
3.工程博客和电子邮件简讯
如果你搜索类似“最佳数据科学通讯”的东西,你会得到很多很棒的结果。这是我收集资源的方式之一。
3.1.公司工程/技术博客
Image caption from Airbnb Tech Blog on Medium
我认为这些工程博客是公司在纸上举行的迷你会议,向世界炫耀和分享他们最新最聪明的成就。他们经常在这里展示有趣的实验、研究和项目。因为是公司维护的,所以质量通常很高。我认为 Medium 开始在这里发挥重要作用,因为许多公司开始在 Medium 上托管他们的工程和技术博客。这里有几个我喜欢的网站!
- T3【网飞理工大学博客】中型
- 脸书研究博客
- 谷歌人工智能博客
- 优步工程博客 (如需机器学习相关内容,请点击此处
- Airbnb Tech Blog on Medium(如果你只想要机器学习相关的内容,点击这里
请记住,工程博客不会只谈论机器学习,但他们经常这样做,并有许多其他有趣的事情可以阅读。
3.2.时事通讯
除了工程博客,还有许多在线出版物的时事通讯,如 Medium 或 personal,你可以订阅。我认为这些内容更个人化,更容易理解,因为像我这样的任何人都可以写这些文章。它们通常包含小型的个人项目,而来自公司博客的项目对于个人来说可能有点深远。
- 像 走向数据科学 这样的刊物绝对是我关注的一个。我发现每天的简讯太多了,但每周订阅一次对我来说已经足够了。
- 我真正喜欢的一个个人简讯是 机器学习很有趣 。它发送有趣的每周文章,如果你想的话,你可以自己尝试一下。
- 杰森·布朗利的【machinelearningmastery.com】也包含了很多实用的教程和代码。
我知道还有很多,但我还没有真正探索太多。所以如果你知道更多,请在下面的评论里告诉我!
4.研究论文
最后但同样重要的是,这是另一个免费但最困难的选择。对于这一部分,我建议你查看以下 Medium 上的帖子:开始阅读深度学习研究论文:为什么和如何 。”作者提供了许多阅读研究论文的有用信息和技巧。综上所述,如果你有兴趣阅读机器学习研究论文,你应该去Arxiv Sanity Preserver,a project byAndrej kar pathy。它基本上向你展示了最新、最受欢迎的研究论文,这样你就可以读到最有趣的论文。用他自己的话来解释这个项目:****
这个项目是一个网络界面,试图驯服 Arxiv 上铺天盖地的论文。它允许研究人员跟踪最近的论文,搜索论文,根据与任何论文的相似性对论文进行排序,查看最近的热门论文,将论文添加到个人图书馆,并获得(新的或旧的)Arxiv 论文的个性化推荐…
我说这是最难的选项,因为我不能随便看这些论文。我需要集中注意力,需要更长的时间来阅读。有时候,我需要一张纸来完成数学。尽管这对我来说是最困难的选择,但也是最有收获的,因为你真的很好地理解了这个主题。我计划在我的机器学习 Github 库中有一个研究论文目录来记录我的阅读。我会尽我所能经常更新。
如果你需要一篇论文作为开始,看看下面这篇论文。由于在卷积神经网络中的成功工作,许多人将此视为深度学习中最有影响力的论文之一。
- 【ImageNet 分类与深度卷积神经网络(2012) 作者Alex Krizhevsky、Ilya Sutskever、Geoffrey Hinton。
以下是该论文的摘要,供您参考:
我们训练了一个大型深度卷积神经网络,将 ImageNet LSVRC-2010 竞赛中的 120 万幅高分辨率图像分类为 1000 个不同的类别。在测试数据上,我们实现了 37.5%和 17.0%的前 1 名和前 5 名错误率,这大大优于以前的最先进水平。具有 6000 万个参数和 650,000 个神经元的神经网络由五个卷积层组成,其中一些卷积层后面是 max-pooling 层,以及三个完全连接的层,最后是 1000 路 softmax。为了加快训练速度,我们使用了非饱和神经元和卷积运算的高效 GPU 实现。为了减少全连接层中的过拟合,我们采用了最近开发的正则化方法“dropout ”,该方法被证明非常有效。我们还在 ILSVRC-2012 竞赛中加入了该模型的变体,并获得了 15.3%的前五名测试错误率,而第二名的错误率为 26.2%。
5.YOUTUBE(2019–04–13 更新)**
我在这里增加了一个部分,因为我真的相信这是有帮助的!许多人都会同意,YouTube 是一个学习如此多主题的好地方。我喜欢在 YouTube 上关注 Siraj Raval 的频道。他发布了许多关于人工智能主题的最新更新和教程。它们看起来也很有趣。
结论
当大量的新信息铺天盖地而来时,保持最新是一项令人生畏的任务。这是我每天都在纠结的事情。但是我希望这些资源可以帮助你引导你的旅程,保持在这一切之上。如果你知道什么好的资源,请在下面的评论里分享!我很想了解他们。
最后,不要感到阅读和学习一切的压力。学习所有的东西可能是不可能的,所以你必须挑选。选择一个让 火花四射的 给你。如果你不喜欢内容,那学习还有什么意义?
祝你好运,感谢你的阅读!
2019–07–31 更新。
查看我的最新项目www。薪.忍者 及相应文章 欢迎来到薪忍者 。
2019–10–30 更新。
看看我的程序( AlphaBlitz ),它用深度学习打败了脸书的文字游戏。喜欢并订阅!😃
如何存储金融市场数据以进行回溯测试
我正在处理中等规模的金融价格数据集。我所说的适度大是指每个资产少于 4 百万行。
400 万行可以覆盖常规资产(如指数期货合约或常规现金股票)在没有延长交易时间的情况下所做的过去 20 年的分钟价格棒线。
当处理价格柱时,分钟和 5 分钟柱会产生大量的数据集。如果你碰巧处理分笔成交点分析,那么它将是巨大的而不是巨大的,但是分笔成交点数据的获取、管理和货币化是非常昂贵的;除非你在回溯测试刷单策略,或者在 HFT 行业工作,否则他们的优势是可疑的。
尽管 400 万行听起来并不令人印象深刻,但我们需要理解,每项资产有 400 万行*。因此,分析来自 Russell 2000 的所有资产将意味着 80 亿行(现在我们越来越大)。添加一些欧洲股票市场、你所在国家的中小市值股票、大宗商品和外汇就可以了:你刚刚登上了大数据竞技场。*
世界上有 1700 多个受监管的市场,一旦你开始积累日内数据,这些数字就会变得令人印象深刻——非常快。
还要记住,目前的趋势是延长所有期货合约的交易时间——欧洲期货交易所从去年 1 月开始延长 FDAX 期货的交易时间,所以就需要分析的数据量而言,情况并没有好转。
现在,每个“*金融数据科学家”*都会问自己一个问题:我应该把我的数据放在哪里,怎么放。
关系数据库是第一个答案,可能不是最有效的,但肯定是最简单的。
我可以列举四个选项作为主要的存储库策略:
- SQL 关系数据库。
- 大型数组的序列化存储。
- 键/值数据库(比如 Oracle Berkeley DB )。
- CSV 文件。
出于明显的原因,我放弃了最后一个,对于其他三个,我只评估了前两个。
我计划探索第三个:键/值数据库。这些数据库并不是真正的主流,但在处理需要大量阅读的简单数据结构时,它们可以提供出色的性能(金融数据就是这种情况)。我真的相信这可能是序列化存储和关系数据库之间的最佳折衷解决方案。
在这篇文章中,我主要关注第一个策略。在进入细节之前,我们将回顾一下我们正在处理的数据。
烛台的快速历史回顾:我们为什么使用它们
几乎所有你要在金融市场上交易的数据都是价格条或烛台。这是有原因的。金融价格条的高/低/开/闭结构类似于统计学中使用的经典须状图和盒状图,但是它们更容易获得。
Price bar used in financial markets.
我使用了类似于 T1 的词,因为胡须和箱形柱(四分位数和中位数)提供的所有重要信息在金融烛台上是无法获得的。四分位数和中位数不是任意值,它们提供了关于被分析变量的描述性信息。
Whiskers and box bar used in statistics.
有人可能想知道为什么在金融市场中不使用晶须和盒棒线(我认为它的使用可能会导致有用和创新的价格行为洞察力),原因很简单。烛台图表被认为是在 18 世纪由一个叫 Munehisa Homma 的日本大米商人首先使用的。如果你想知道 18 世纪是否有期货合约,你会想知道虽然第一个现代期货合约交易所是 T2 芝加哥期货交易所,但在 17 世纪欧洲和日本已经建立了期货市场。
The Dōjima Rice Exchange Monument. First future contracts exchange in Japan.
获得最高价、最低价、开盘价和收盘价来建造一个特定时期的烛台是非常容易的。你只需要一段时间内所有交易的清单。现在交易是电子化的,并且以有序的方式进行,但是请记住,情况并非总是如此。电子交易是相对现代的(它在 80 年代开始获得相关性)。在那之前,场内交易是常态,资产只在特定时间在场内交易。我们所知的持续交易市场的概念在当时并不适用。
即使在几乎所有交易都以电子方式进行的当前情况下,存储和分析在给定时期发生的所有交易以构建胡须和箱线图也是具有挑战性的(可行,但具有挑战性)。这意味着要么对订单簿进行严格的连续跟踪— 阅读磁带— ,要么以不太严格的方式将较短的时间框架整合为较长的时间框架。
通过使用烛台,你最终会得到与四分位数和中位数类似的信息(请注意,突出显示了与 T9 类似的信息)。这就是所谓的烛台或烛台模式的价格行为,实际上,这只是对所有烛台系列中价格相关之处的解释性分析。所以一根大胡须和一个小身体(比如你在一只蜻蜓身上发现的)将意味着价格拒绝,如果大部分时间价格都集中在身体部分,当它试图移动到该区域下方或上方时,它很快就会被拒绝。这就是你可以从烛台上得出的结论(同样,当你在给定的市场背景下阅读它时)。
因此,存储开盘价/收盘价/最低价/最高价的区间价格信息将能够进行一定程度的价格行为分析,并且根据经验,给定环境中的某些模式具有统计相关性,并且将导致有利可图的策略。
存储烛台的数据模型
现在我们理解了为什么使用烛台,我们可以提出一个简单的数据模型来存储我们的信息。
CREATE TABLE candlestick (
“id” INTEGER PRIMARY KEY AUTOINCREMENT,
“timezone” TEXT NOT NULL,
“timestamp” DATETIME NOT NULL,
“open” DECIMAL(12, 6) NOT NULL,
“high” DECIMAL(12, 6) NOT NULL,
“low” DECIMAL(12, 6) NOT NULL,
“close” DECIMAL(12, 6) NOT NULL,
“volume” DECIMAL(12, 6) NOT NULL
);
我肯定您对这个简单的数据模型印象不深,但是即使是这个模型也可能会受到挑战。我们将不讨论timezone
列(我计划写另一篇关于时区和数据的文章),但是timestamp
的用法已经是相关的并且有性能问题。
从可用性的角度来看,这种存储财务信息的方式简单且结构良好。查询数据非常简单:
sqlite> select * from candlestick where date(timestamp)='2018-01-12' limit 10;3489458|Europe/Berlin|2018-01-12 07:00:00+01:00|13243.5|13245.5|13234.5|13245.5|294
3489459|Europe/Berlin|2018-01-12 07:01:00+01:00|13244.5|13250|13243|13245|149
3489460|Europe/Berlin|2018-01-12 07:02:00+01:00|13244.5|13246|13242.5|13244|39
3489461|Europe/Berlin|2018-01-12 07:03:00+01:00|13242.5|13243.5|13239|13241.5|64
3489462|Europe/Berlin|2018-01-12 07:04:00+01:00|13241|13241|13235.5|13236.5|61
3489463|Europe/Berlin|2018-01-12 07:05:00+01:00|13236.5|13240|13236|13239.5|49
3489464|Europe/Berlin|2018-01-12 07:06:00+01:00|13239|13241.5|13237|13240|49
3489465|Europe/Berlin|2018-01-12 07:07:00+01:00|13238.5|13241|13237|13239|43
3489466|Europe/Berlin|2018-01-12 07:08:00+01:00|13239|13239|13236.5|13237|24
3489467|Europe/Berlin|2018-01-12 07:09:00+01:00|13237|13239|13237|13239|11
获取给定时段的开盘价很简单:
sqlite> select * from candlestick where date(timestamp)='2018-01-12' limit 1;3489458|Europe/Berlin|2018-01-12 07:00:00+01:00|13243.5|13245.5|13234.5|13245.5|294
所以它得到了收盘价:
sqlite> select * from candlestick where date(timestamp)='2018-01-11' order by timestamp desc limit 1;3489457|Europe/Berlin|2018-01-11 21:03:00+01:00|13241|13241|13241|13241|25
但是这种方式有一些性能问题,我们将在后面讨论。
注意,我们使用了datetime
字段来存储时间戳。我们也可以使用单独的字段来表示年、月、日、小时和分钟,但这将使以后在 Python(或 Java)中处理datetime
类型变得复杂。这些复杂类型可能会带来性能问题,但也有助于处理时间、时区、时间偏移等。它还支持在 SQL 查询中使用时间范围。
未经优化的性能问题
使用这种方法存在性能问题:
- 当进行数据的批量加载时(使用 Python 和 ORM 来确保在 SQLite 中正确处理时间戳),在单核 VPS 服务器上需要 14 分钟。
- 在同一台 VPS 服务器上,获取给定会话的所有数据需要 5 秒钟。获得开盘价或收盘价的类似结果。
14 分钟听起来太长了,但批量装载并不常见,这可能是可以接受的。即使可以找到更优化的数据加载方式,这也不是重点。只需喝杯咖啡或为初始数据供应进行程序批量加载,这只会发生一次。
相反,5 秒钟可能听起来没什么大不了的,但确实如此。请记住,我们在这里处理的是多资产蒙特卡罗模拟场景。这意味着数千发子弹。所以 5 秒乘 1000 秒太长了。我们需要在这里进行优化。
虽然我不打算在这篇文章中讨论序列化策略,但我会分享一些关于这两种策略的时间比较:
# Bulk provisioning of 3.5Million price bars:SQLite + Pyhon ORM: 15 min
Serialized Stored Arrays + ANSI C: 1.5 min# Retrieve a given specific 1 minute price bar:SQLite + Pyhon ORM: 5 seconds
Serialized Stored Arrays + ANSI C: Negligible (microseconds)
如前所述,这些环境中的真正问题是检索时间。在序列化数组中,它可以低至微秒,因为可以定义一种策略来为所有数据分配内存空间。
如果假设所有月份都有 31 天,那么检索给定的分钟只是一个超级简单的内存查找操作。没有索引或搜索操作这样的东西。
如果我们不知道交易时间(即使我们知道交易时间,也可能会有异常情况,如交易暂停或数据不一致),获得给定时段的收盘价或开盘价可能会有点困难,但我们可以遍历特定的一天。遍历所有每日数据的阵列既快速又简单。
在介绍具有内置优化功能的数据库如何加快这些数字时,我们可能会使分析过于复杂。如果您的项目能够为 DBA 优化专家分配每年 150000 美元的成本,Oracle 数据库的性能将会更好,但这里要指出的是,简单的数组查找(序列化方法)永远不会被任何关系数据库击败。作为一个缺点,关系数据库使得查询和移动数据比存储序列化数组容易得多。
我尽可能使用 SQLite,因为它非常简单,易于使用和备份。尽管许多人说它是一个太基础的数据库,但它可以处理巨大的数据集。它的主要缺点是缺乏页面或区域锁定,这导致写很多的应用程序出现性能问题。除此之外,它的性能通常比预期的好得多,它非常轻便,而且无需维护。
创建索引以提高性能
最简单、最容易的优化是使用索引(这也是 SQLite 中唯一可以做到的)。
sqlite> create index idx_timestamp on candlestick(timestamp);sqlite> select * from candlestick where date(timestamp)='2018-01-11' order by timestamp desc limit 1;
3489457|Europe/Berlin|2018-01-11 21:03:00+01:00|13241|13241|13241|13241|25
现在搜索只需不到一秒钟。这是一个有意义的性能改进。
[user@host gaps]$ ls -ltr dax*
-rw-r--r-- 1 memmanuel memmanuel 284292096 Jan 26 12:43 dax-withoutindex.db
-rw-r--r-- 1 memmanuel memmanuel 409865216 Jan 26 22:32 dax-withindex.db
请注意,索引也极大地增加了数据库的大小。
将不同数据库中的资产分开
在 SQLite 中,拥有几个数据库非常简单。每个数据库只是一个文件的连接。因此,没有理由将所有资产合并到同一个数据库中。您可以将每个资产拆分到一个数据库文件中,并依赖于文件系统。将文件移动到不同的服务器并进行备份也将变得更加容易。在 SQLite 中处理每个数据库的多个资产将变得非常困难,它将需要一个额外的索引来跟踪资产报价器。所以这更像是一个必须要做的事情,而不是一个优化技巧。
在适用的情况下使用混合策略
将会话或每周数据从 SQLite 检索到内存数组或列表中。然后,您的数据会飞起来,您将使用 SQLite 作为永久的数据存储,在那里您可以检索大块的数据。这将减少对关系数据库性能不足的影响,同时仍然给你使用关系数据库的优势。
摘要
就性能而言,将金融价格数据存储在关系数据库中并不是最好的主意。金融市场数据是时间序列数据,其消费通常是使用基本搜索和检索查询的长链数据。
尽管如此,在关系数据库中存储数据简化了操作。所以你可以用它。
这里提到的三个简单的优化技巧/模式将会带来更好的结果:
- 为时间戳创建索引。
- 将数据集划分到不同的数据库中(在 SQLite 中,这非常简单)。
- 从关系数据库中检索数据子集,并使用后来的内存列表/数组。
还有更多信息可能与使用序列化数组的方法以及处理时区这一复杂的主题相关,但这些将是其他帖子的素材。
如何构建您的 PyTorch 项目
一个构建 PyTorch 培训代码的建议
自从我开始训练深度神经网络,我就在想我所有的 Python 代码应该是什么结构。理想情况下,一个好的结构应该支持广泛的模型实验,允许在一个紧凑的框架中实现各种不同的模型,并且容易被每个阅读代码的人理解。您必须能够通过编码和重用各种数据加载器来使用来自不同数据源的数据。此外,如果模型支持在一个模型中组合多个网络(如 GANs 或原始 R-CNN 的情况),那就更好了。该框架还应该具有足够的灵活性,以允许复杂的可视化(这是我在数据科学中的核心信念之一,即可视化使一切变得更容易,尤其是在计算机视觉任务的情况下)。
深度学习框架的详细实现当然取决于您正在使用的底层库,无论是 TensorFlow、PyTorch 还是 CNTK。在这篇文章中,我将介绍我基于 PyTorch 的方法。然而,我认为通用结构同样适用于您正在使用的任何库。你可以在 https://github.com/branislav1991/PyTorchProjectFramework 的找到整个资料库。
总体结构
Project structure for our deep learning framework.
在上面的图片上(取自 VS code,我选择的 Python 编辑器),你可以看到我为我的框架创建的一般文件夹结构。框架由一些启动脚本 (train.py,validate.py,hyperopt.py)以及隐藏在文件夹内的库组成。数据集文件夹包含类和方法,用于加载各种类型的数据进行训练。损失文件夹可能包含额外的损失函数或验证指标。如果您的项目不需要任何自定义损失函数,您可能不需要此文件夹。模型文件夹是最重要的:它包含实际的模型。优化器文件夹包含定制优化器的代码。与 losses 文件夹一样,如果您没有任何自定义优化器,也可以忽略该文件夹。最后, utils 文件夹包含了在整个框架中使用的各种实用程序,最著名的是可视化器。您还会注意到项目根文件夹中的 config_segmentation.json 文件。该文件包含培训所需的所有配置选项。
您可能已经猜到,训练是通过调用 train.py 脚本启动的。使用适当的配置文件作为命令行参数调用该脚本。它负责所有高级别的训练工作,例如加载训练和验证数据集以及模型,设置可视化,运行训练循环,最后导出训练好的模型。
类似地,通过调用适当的脚本并将配置文件作为参数传递来使用验证。
数据集
Files in the datasets folder with a 2D segmentation dataset as an example.
在上图中,你可以看到数据集文件夹的结构。它包括 init。py 模块,包括一些必要的函数来查找和创建正确的数据集,以及一个自定义的数据加载器,它将数据转发到训练管道(有关这方面的更多信息,请查看 PyTorch API 文档)。顾名思义,base_dataset.py 为您在框架中定义的每个数据集定义了抽象基类。
对于您定义的每个自定义数据集,您必须实现 getitem 和 len 方法,以便 PyTorch 可以对其进行迭代。您不必再处理数据加载器,因为它是在 datasets/init 中定义的。已经开始了。您还可以为数据集定义自定义回调,以便在每个时期之前和之后调用。如果您希望使用某种预热方法,在最初的几个时期向模型提供不同的数据,然后切换到更复杂的数据集,这可能会很有用。
为了实例化数据集,train.py 脚本调用以下代码:
print(‘Initializing dataset…’)
train_dataset =
create_dataset(configuration[‘train_dataset_params’])train_dataset_size = len(train_dataset)
print(‘The number of training samples = {0}’.format(train_dataset_size))
这将调用 create_dataset 函数,该函数查看配置文件并根据其名称选择正确的数据集。在命名数据集时,遵循约定_ dataset . py 很重要,因为这是脚本能够根据配置文件中的字符串找到数据集的方式。最后,上面的脚本调用数据集上的 len() 函数来通知您数据集的大小。
模型
Files in the models folder with a segmentation model as an example.
框架中的模型以与数据集相同的方式工作:init__。py 模块包括根据模块名和配置文件中定义的字符串查找和创建正确模型的函数。模型类本身继承自抽象的 BaseModel 类,并且必须实现两个方法:
- forward(self) 运行正向预测,并且
- *optimize _ parameters(self)*在训练通过后修改网络的权重。
所有其他方法都可以被重写,或者您可以使用默认的基类实现。您可能想要覆盖的函数包括 pre_epoch_callback 和 post_epoch_callback (在每个 epoch 之前和之后调用)或 test (在验证期间调用)。
为了正确使用框架,了解如何使用网络、优化器和模型中的损耗是很重要的。由于在一个模型中可能有多个使用不同优化器的网络以及多个不同的损失(例如,您可能想要显示语义本地化模型的边界框分类和回归损失),所以界面会更复杂一些。具体来说,您为 BaseModel 类提供损失和网络的名称以及优化器,以了解如何训练您的模型。在提供的代码中,我包含了一个 2D 分割模型的例子和一个数据集例子,让你看看这个框架应该如何使用。
看看提供的 2D 分段模型的 init()函数:
class Segmentation2DModel(BaseModel):
def __init__(self, configuration):
super().__init__(configuration)
self.loss_names = [‘segmentation’]
self.network_names = [‘unet’]
self.netunet = UNet(1, 2)
self.netunet = self.netunet.to(self.device) if self.is_train: # only defined during training time
self.criterion_loss = torch.nn.CrossEntropyLoss()
self.optimizer = torch.optim.Adam(self.netunet.parameters(), lr=configuration[‘lr’]) self.optimizers = [self.optimizer]
这里发生的事情是这样的:首先,我们读取模型配置。然后,我们定义“分段”损失,并将其放入 self.loss_names 列表中。损失的名称很重要,因为我们使用变量 self.loss_segmentation 来表示损失。通过了解名称,基本模型可以查找损失,并在控制台中打印或可视化(下一节将详细介绍可视化)。同样,我们定义网络的名称。这确保了 BaseModel 知道如何训练模型,而无需我们明确定义它。接下来,我们初始化网络(在本例中是 U-Net ),并将其移动到 GPU。如果我们处于训练模式,我们还定义损失标准并实例化优化器(在本例中是 Adam)。最后,我们将优化器放入self . optimizer列表中。该列表再次在基本模型类中使用,以更新学习率或从给定的检查点恢复训练。
让我们也来看看 forward() 和 optimize_parameters() 函数:
def forward(self):
self.output = self.netunet(self.input)def backward(self):
self.loss_segmentation = self.criterion_loss(self.output, self.label)def optimize_parameters(self):
self.loss_segmentation.backward() # calculate gradients
self.optimizer.step()
self.optimizer.zero_grad()
正如您所看到的,这是标准的 PyTorch 代码:它唯一的职责是在网络上调用 forward(),在计算梯度后逐步优化程序,并再次将它们归零。为您自己的模型实现这一点应该很容易。
形象化
Files in the utils folder.
可视化可以在可视化器类中找到。这个类负责将损失信息打印到终端,以及使用 visdom 库可视化各种结果。它在训练脚本开始时初始化(加载 visdom 服务器)。训练脚本还调用其 plot_current_losses() 和 print_current_losses() 函数来可视化并写出训练损失。它还包含类似plot _ current _ validation _ metrics()、 plot_roc_curve() 和*show _ validation _ images()*的函数,这些函数不会自动调用,但可以从 post_epoch_callback() 中的模型中调用,以在验证时进行一些有用的可视化。我试图让可视化工具相当通用。当然,您可以自己扩展可视化工具的功能,让它对您更有用。
结论
我提出了一种编写通用深度学习框架的方法,该框架可以用于深度学习的所有领域。通过使用这种结构,您将为进一步的开发获得一个清晰而灵活的代码库。当然,解决这个问题还有许多其他方法。如果你有其他建议,请在评论中告诉我!
如何在 Mac 上成功安装 Anaconda(并让它实际工作)
正确安装 Anaconda 并修复可怕的“找不到 conda 命令”错误的快速而轻松的指南
Image by Michael Schwarzenberger from Pixabay
你知道你需要它。
当您开始学习数据科学、机器学习或人工智能时,您很快就会意识到您需要能够使用 Anaconda。你可能想用 Jupyter 笔记本,Spyder,或者其他很棒的程序,但是不管怎样,你都需要这个东西来工作。
最近在安装电脑时,我想起了第一次让 Anaconda 工作有多难。安装本身没有问题!官方 guid e 对于安装本身是清晰而全面的。你完成它,遵循一些简单的步骤,你就可以开始了!
最后,它告诉您通过键入类似“conda list”的命令来验证您的安装是否成功,这样就完成了!
没有。
康达没有
“康达”我第一次装的时候没用。没有现成的链接可以告诉你该怎么做。你验证一下就完事了。
你只能靠自己了。
没有什么比甚至不能打开你需要的程序更令人沮丧的了。
在机器学习和人工智能方面入门并不是一件容易的事情,无法正确安装必要的工具只会造成严重后果。随着你开始理解更多的语言和命令,你会发现有很多简单的答案。但是当一切都是新的时候,它们就没有任何意义了!仅仅谷歌一下你的问题就很有挑战性。
我实际上已经这样对自己了。
我在苹果电脑上工作(如果你感兴趣的话,可以叫我莫哈维)。在终端工作了一段时间后,我把它变成了一个快速、高效、外观漂亮的东西。你可以在这里看到我为了让我的终端变得更棒而做的一切,但本质上,它是在运行的
- iTerm2
- 公司自产自用
- Zsh
- 哦,我的 Zsh
- 几个我的 Zsh 插件
- Z
- 语法突出显示
如何在短短几分钟内打造一个更好、更快、更强、更性感的终端
towardsdatascience.com](/trick-out-your-terminal-in-10-minutes-or-less-ba1e0177b7df)
我一点也不知道这会让我的 Anaconda 安装变得更加困难。事实证明,一行代码更难,但对新手来说,挑战性是一百万倍。
这是一步一步的安装过程,通过简单的一行修复程序,您可以“conda”任何您想要的东西。即使你用的是可爱又惊艳的 Zsh。
发生了什么事?
事情是这样的:安装是成功的,但是在 Zsh 和我的终端想要与 Anaconda 对话的方式之间有一个小问题。发生这种情况的原因有很多,但 Zsh 是罪魁祸首。
它非常容易修理!但是因为我不知道我在做什么,所以我花了很长时间才弄明白。
Image by boanergesjr via Pixaby
其他人不应该经历这些。
修复
官方安装指南 在这里,如果你想检查一下。
我第一次决定下载 Anaconda ,我经历了正常的图形化 Mac 安装。作为一个应用程序,它工作得很好,但它就是不能在我的终端上工作。
不愿意放弃,我卸载了 Anaconda,然后尝试命令行安装。这一点非常好,因为您可以在安装过程中决定让您的终端与 Anaconda 通信。在安装过程中,您会得到一个提示,询问“您希望安装程序通过运行 conda init 来初始化 Anaconda3 吗?”
我建议给这个答案一个大大的肯定。
当然还是没有效果。不过,如果你没有一个精心设计的终端,它可能会!如果你没有使用 Zsh 和我的 Zsh,你可能已经设置好了。
那么,如果您对终端进行了更改,如何让它正常工作呢?
很简单!
这些是成功安装 Anaconda 的简单步骤,即使面对可怕的“conda command not found”错误消息。
步骤 1:下载 Anaconda
可以去这里下载 Anaconda 。然后向下滚动一点,到显示“Anaconda 2019.03 for MAC OS Installer”的部分
您需要知道您使用的是哪个版本的 Python,所以请在您的终端上键入
python
This shows Python version 3.7.3
你有几个下载的选择。您可以选择图形化安装程序,这意味着您将像安装任何其他程序一样安装 Anaconda。或者您可以选择命令行安装程序,这意味着您将进入您的终端并键入(或复制和粘贴)命令。
我们将执行命令行安装程序,因此单击您的 Python 版本下的链接,您的下载应该会开始。
步骤 2:命令行安装
下载完成后,前往您的终端。
如果你有 Python 3.7,你会跑
bash ~/Downloads/Anaconda3-2019.03-MacOSX-x86_64.sh
对于 Python 2.7,运行
bash ~/Downloads/Anaconda2-2019.03-MacOSX-x86_64.sh
请记住,如果您没有将 Anaconda 下载到您的下载文件夹中,您将需要更改该路径。
查看许可协议,点击“回车”接受它,直到你看到最后。最后,如果你想同意,请键入“是”。
(会提示你。错过的话会反复提示*。)*
如果你对它建议的位置满意,点击“输入”您可以通过输入 CTRL-C 来更改位置或取消安装。注意这个位置!如果您收到错误消息,它会派上用场。
现在保持不动。耐心点。这可能需要几分钟的时间,而且您一开始并不知道是否发生了什么。如果您愿意,您可以去喝点饮料,但是要快,因为安装程序会问,“您希望安装程序通过运行 conda init 来初始化 Anaconda3 吗?”当别人问你的时候,你几乎肯定想在那里输入“是”。
“感谢您安装 Anaconda!”
安装完成后,关闭您的终端窗口并打开一个新窗口,以使更改生效。想看看有没有用吗?在您的终端中,键入如下命令
*conda list*
看看会发生什么。如果成功了,你会看到这样的东西
如果您想知道您的环境中安装了哪些包和版本,这是一个非常有用的命令!
如果成功了,恭喜你!!!您现在已经准备好开始使用 Anaconda、Jupyter Notebooks、Spyder 和所有其他好东西了。庆祝的时间到了!
Image by StockSnap from Pixabay
步骤 3:找不到 conda 命令
另一方面,你可能会看到这个:
这个问题的解决方法其实很简单。
故障排除步骤#1:
** * * 重启你的终端!!!***
(我知道我已经说过了,但是 Anaconda 团队告诉我,不刷新您的终端是人们在这一点上遇到问题的最常见原因。)
故障排除步骤#2:
您需要知道您的 Anaconda 二进制目录在哪里,以及您的用户名是什么。如果您在安装过程中注意了,您已经有了这些信息!您需要在安装过程中指定的位置。
如果没有,如果你只是简单地按照安装说明操作,很有可能你的目录是/Users/
(如果你在 macOS 上)。(或者 Linux 上的/home/
或者 Windows10 上的\Users\
。)
如果您不知道自己的用户名,请运行
*echo $USER*
** * 更新!!***
我建议修改 PATH 来解决这个问题(您可以在下面看到最初的修复),但是 Anaconda 团队提供了一些非常有用的信息!
他们不建议修改路径!
你可以阅读下面的完整评论,但这里有一个信息的压缩版本,你可以在评论部分找到惊人的迈克尔萨拉汉:
“如果您的系统中有任何其他程序具有相同的名称,那么修改路径会导致问题,Anaconda 会首先发现这些程序,然后隐藏它们(阴影)。“conda init”所做的是建立一个 conda“shell 函数”,并使其他东西远离路径。除了康达什么都没有。然后,它默认在启动时激活您的基本环境。净效果非常像您的路径添加,但有一些微妙的,但至关重要的差异:
激活确保了 anaconda 的路径内容是正确的。将 anaconda 永久地放在 PATH 的前面是好的,因为它可以防止混淆,但是不好的是它会遮蔽其他东西,并且可能会破坏东西。激活是一种不太持久的方法。您可以使用“auto _ activate _ base”condarc 设置关闭基础环境的自动激活。
激活不仅仅是修改路径。它还提供任何 activate.d 脚本,这些脚本可以设置附加的环境变量。有些东西,比如 GDAL,需要这些。没有激活,这些软件包将无法工作。
因此,如果您选择不运行 conda init,我们建议您遵循安装程序末尾的说明,而不是您修改路径的提示:
…
这看起来像两个命令:
1.eval " $(/home/msarahan/mc3 _ dummy/bin/conda shell . bash hook)"
2.conda 初始化
注意,在步骤 1 中,我将 shell 名称从 YOUR_SHELL_NAME 改为 bash。您可能需要根据您的 shell 自行调整。"
长话短说,修改 PATH 很有可能会给你带来一些问题。更聪明的做法是激活,因为它不是永久的,并且会允许一些原本不能运行的包运行。
因此,在安装程序结束时,不是运行原始解决方案:
*export PATH="/Users/myname/anaconda2/bin:$PATH"*
你想跑吗
*eval "$(/home/msarahan/mc3_dummy/bin/conda shell.bash hook)”
conda init*
(但是要确保将目录位置和 shell 更改为您自己的!)
**** * 更新结束*****
原始解决方案:
你所需要做的就是运行
*export PATH="/Users/myname/anaconda3/bin:$PATH"*
你可以走了!!!
(一定要确保用您的用户名替换“myname ”,并在需要时更改目录的路径。如果你看上面的那一行,
*/Users/myname/anaconda3*
将被先前安装位置的*/Users/anneb/anaconda3*
所取代。其他一切保持不变。)
如果您没有安装 Anaconda3,那么您需要运行
*export PATH="/Users/myname/anaconda2/bin:$PATH"*
对于 Anaconda2 或者
*export PATH="/Users/myname/anaconda/bin:$PATH"*
确保在必要时更改“myname”和目录位置。
现在试试conda list
!
恭喜你!
你做到了!!!
您已经成功安装了 Anaconda,现在可以从命令行运行它了!
试着打字
*jupyter notebook*
看看会发生什么!
GIF via GIPHY
感谢阅读!如果你想接触或者找到更多很酷的文章,请来内容简约和我一起吧!
想了解创建、运行、发布甚至共享 Jupyter 笔记本的最简单方法吗?
* [## 如何毫不费力地创建、发布甚至共享云托管的 Jupyter 笔记本
完全初学者指南,以闪电般的速度在 Jupyter 笔记本上创建、运行和协作…
towardsdatascience.com](/getting-started-with-saturn-cloud-jupyter-notebooks-b3f509a500ef)
感谢阅读!*
如何成功管理数据科学交付渠道
数据科学项目:交付还是不交付。
根据 Gartner 的说法,这不是选项,而是 85%的数据和数据科学项目未能交付商业价值或看不到业务适应的令人失望的现实。事实是,在商业环境中成功掌握数据科学是一项复杂的挑战。你可以在我之前的博文中读到关于独特的战略需求和技术需求。这个博客涵盖了拼图的最后一块,即数据科学项目的交付管理。
如何构建一个前沿的数据科学平台来解决数据科学中的真正挑战:生产化。
towardsdatascience.com](/rendezvous-architecture-for-data-science-in-production-79c4d48f12b) [## 如何让您的数据科学团队取得成功?
出于某种原因,让数据科学取得成功真的很难,超过 75%的企业报告称面临业务挑战…
towardsdatascience.com](/how-to-make-a-success-story-of-your-data-science-team-1719129941ba)
当我们审视项目交付管道时,重要的是要记住数据科学(a)仍然是一个新兴的业务功能,以及(b)从持续的创新中不断发展。
构建基础层
许多数据科学家发现自己在运行敏捷软件开发周期的科技公司中,这感觉有点像圆孔中的方钉。数据科学职能与软件开发的不同之处在于该角色所带来的开放式研究的数量,这也是标准敏捷流程与数据科学家的兴趣相冲突的地方。
研究是数据科学的重要组成部分,但不太适合标准的敏捷流程。
任何数据科学团队都需要花费大量时间进行研究,以构建他们的基础层,其中数据科学使不断发展的领域适应业务的特定环境。我们可以将这项基础研究工作分为三类:
长期:由成熟的数据驱动型高科技公司的专业研究团队进行。这不是典型的企业商业数据科学家。
中期:通过调整数据科学中不断发展的关键领域以适应特定的业务环境,构建可扩展的基础。
短期:应用特定的挑战,如解决方案设计、表示层、算法选择以及模型和指标的验证方法。
许多企业通过从相关领域(如 NLP 或计算机视觉)雇用特定的专业知识和人才来快速推进他们的研究积压。无论如何,需要对基础层进行持续投资,以保持资源的相关性,并为数据科学团队提供发展机会。这对于团队激励和保留至关重要。
[OC]
当我们将数据科学的职责分成两个工作流时,很明显哪个部分应该作为敏捷交付管道和项目管理委员会(如吉拉)的一部分,哪个部分与标准敏捷流程相冲突。
一方面,构建基础层和管理这个工作流应该是数据科学家的内部职责。另一方面,我一次又一次地发现这对于团队来说是非常个人化的。通常,这是用于未定义成功标准或截止日期的概念证明的合适工作流。与其顺应这种混乱,不如对这一工作流的资源分配实施透明,围绕协作和知识转移设定期望,并通过博客帖子和社区会议等方式交流这一工作的进展和价值。
转向项目管理需求
在团队坚实的基础上,我们扩展了越来越多的应用程序和业务用例,成为标准交付管道的一部分,具有更严格的项目管理要求:
Adapted Flow Chart originally by Shay Palachy
数据科学项目的交付是科学、产品和工程的团队运动。其协调和优先级的关键是项目交付管理中的价值证明思维,而不是激励团队研究工作的概念证明思维。
范围界定阶段必须从具体的产品需求开始,目标是在产品和数据科学之间就成功项目将解决的范围和指标达成一致。这一阶段是对已建立的产品和科学关系的巨大考验。在成熟的合作中,产品团队尚未解决合适的数据科学项目。构思过程应大量参考数据,以定义现实的项目范围,并应主要由数据科学团队负责。
在研究阶段这将未完成的研究限制在短期应用特定的挑战,如最终解决方案设计(包括表示层和 API)、算法选择以及模型和商定指标的合适验证方法。因此,对这一阶段进行时间限制是合适的,但有可能需要重复一个研究阶段。研究阶段的成功完成见证了工程部门的感觉检查,以及对范围和商定指标仍然有效的确认。
这是真正的模型开发开始的时候。数据科学家编写代码,但这与软件工程师的工作方式有很大不同。这个阶段是高度迭代的,在模型开发和模型评估之间有大量的来回,以优化解决方案。这就是数据科学家使用笔记本而不是传统 ide 的原因。这让他们可以快速制作原型。
笔记本电脑非常适合快速原型开发,但是对于可重复性和企业部署来说却很糟糕。数据科学开发环境的成熟度以及工程对访问和处理大量数据的支持至关重要。它不仅影响模型开发过程中的生产力,而且保证解决方案的质量,以避免后续解决方案部署过程中的意外。
您可以在我的另一篇文章中了解更多有关 MLFlow 以及它如何帮助数据科学家开发可用于生产部署的模型的信息:
数据科学项目最佳实践,适用于在本地或云中工作的每个人,从刚起步的忍者到大…
towardsdatascience.com](/complete-data-science-project-template-with-mlflow-for-non-dummies-d082165559eb)
模型的部署本身就是一个具有挑战性的话题。通常,模型数据科学家在前一阶段开发的模型数据需要大量的工作来将其转化为可以在现有堆栈上部署的企业解决方案。这包括日志记录、监控、审计、身份验证、SLA 等要求。
为每个模型解决部署问题根本无法扩展。此外,一个大问号仍然存在。谁拥有生产中已部署模型的操作职责?模型因其在生产中复杂的生命周期管理需求而独一无二。因此,关注平台化数据科学很重要,你可以在我之前关于机器学习物流和 Rendezvous 架构的文章中了解更多。
这个故事已经作为甲骨文的 AI 影响者博客系列的一部分重新发布:
Jan 是公司数据转型方面的成功思想领袖和顾问,拥有将数据科学大规模应用于商业生产的记录。他最近被 dataIQ 评为英国 100 位最具影响力的数据和分析从业者之一。
在领英上连接:https://www.linkedin.com/in/janteichmann/
阅读其他文章:https://medium.com/@jan.teichmann
如何增强你的熊猫工作流程
Photo by Bill Jelen on Unsplash
当我处理结构化数据时,Pandas 是我的首选工具。我认为这并不奇怪,因为 Pandas 是最流行的用于数据操作、探索和分析的 Python 库。它提供了很多现成的功能。此外,还存在各种其他模块来进一步增强和扩展 Pandas 核心。在这篇文章中,我想和你分享我用来增强我的熊猫工作流程的工具和技术。
增压步骤
准备
为了跟随例子,你需要 Python 3.7+和熊猫、 funcy 和 seaborn 。你可以在我的GitHub repo上找到所有的例子。
一如既往,我推荐使用poem来管理您的 Python 包和环境。你可以查看这篇文章了解如何设置它。作为一种快捷方式,我建议使用 pip 或 pipx 将其安装在您的机器上。
现在,让我们快速创建一个名为 awesome-pandas 的诗歌项目,在这里我们实现示例并添加必要的包
poetry new awesome-pandas
cd awesome-pandas
poetry add pandas seaborn funcy
现在我们有了一个独立的 Python 环境,安装了我们需要启动的所有东西。太好了,我们可以开始增压我们的熊猫工作流程了!
探索性数据分析
不管你有什么样的数据集,你首先要做的可能是对其中发生的事情有一个想法和理解。这个过程被称为探索性数据分析,EDA。
数据集中有多少要素和样本?那些特征是什么?它们有哪些数据类型?是否有任何缺失值?它们是如何分布的?有什么关联吗?这些只是人们在查看新数据集时通常会遇到的许多问题中的一部分。
对于熊猫来说,获取这些信息的通常嫌疑人是函数 head 、 info 、description和 *corr、*等等。因此,对于您的 EDA,您可以从一个接一个地调用这些函数开始。接下来,您可以从控制台或 Jupyter 笔记本上读取结果,并将结果关联起来。这个过程对我来说听起来很乏味。此外,它不包括任何可以很容易解释的视觉效果。创建它们需要额外的步骤和代码。以结构化和整合的方式获取所有这些信息不是很好吗?理想情况下只调用一个函数?
这里是熊猫的光辉之地!
Pandas-profiling是一个扩展 Pandas DataFrame API 的库。它将常见的第一个 EDA 步骤合并到一个函数调用中。这些包括 数据类型、 缺失值、相关性、分位数和描述性统计以及直方图 等。所有这些信息被组合成一个单一的输出。您可以通过一个配置文件 来配置 分析什么以及结果如何呈现。听起来很棒,不是吗?让我们简单看一下。
首先,我认为将它添加到我们的示例环境中是有意义的
poetry add pandas-profling
现在,您所要做的就是导入 pandas-profiling 并在 DataFrame 对象上调用 profile_report。如果你用的是 Jupyter Notebook,这个足以看到输出。当使用 IDE 或编辑器时,您必须将报告保存为 HTML 文件,并在浏览器中打开它。我不是一个笔记本电脑爱好者,所以我必须做更多的工作
这就是为什么我想出了下面的函数。它使我能够检查只调用单个函数的报告,就像 Jupyter 人一样。
现在,我们拥有和 Jupyter 人几乎一样的舒适。
但是,我希望和一样舒适,并使用一个 专用数据框架 API 来创建和打开我的报告。
扩展熊猫 API
Pandas 已经提供了一套丰富的现成方法。但是,您可能希望根据需要扩展和自定义索引、系列或数据框架对象。幸运的是,从 0.23 版本开始,Pandas 允许你通过自定义的 访问器 来实现。如果你想在 Pandas < 0.23 中添加一个自定义的访问器,你可以使用 Pandas-flavor 。
编写自定义访问器相当简单。让我们用上一节中的例子来看看它;在浏览器中为数据帧创建并打开 pandas-profiling 报告。
我们从一个 Python 类报告开始,我们必须用@pandas.api.extensions.register_dataframe_accessor("report")
来修饰它。class’ __init__
'方法必须将 DataFrame 作为其唯一的参数。您将该对象存储在一个实例变量中,并使用它来应用您自定义方法。自定义方法是您的类的实例方法。
作为一个例子,我们将一个方法 show_in_browser 添加到类报告中。我们可以通过df.report.show_in_browser()
在数据帧 df 上调用它,为此,我们只需导入包含类报告的模块。
您可以使用传递给装饰器的名称来访问您的自定义方法。举个例子,如果我们用“ wicked ”交换“ report ”,而不改变其他任何东西,我们必须调用df.wicked.show_in_browser()
在浏览器中打开我们的报表。
说够了,下面是代码,它给我们带来了和 Jupyter 人一样的舒适
注意,我通过添加__call__
使类 a 成为可调用的。为什么这很有用?因为现在你可以调用df.report()
来执行一个函数,就是在这里获取报告。如果你只想给你的对象添加一个函数,并且不想调用df.report.report().
之类的函数,这就非常方便了
关于自定义访问器的最后一件有用的事情是,ide 可以识别它们并启用自动完成功能。这增强了整体开发体验。
现在我们知道了我们的数据是什么样子,以及如何扩展 Pandas 对象。所以,让我们继续有趣的事情,看看如何改善处理体验。
跟踪应用调用的进度
假设您想对数据帧应用一个函数。根据数据帧的大小或函数的复杂程度,执行df.apply(func)
可能需要很长时间。所以你可能会坐在电脑前等待它结束。不幸的是,你没有得到任何反馈,不知道你要等多久,也不知道它到底有没有用。你可能只听到一个响亮的风扇和你的电脑正在升温。如果你像我一样,你会在那一点上变得紧张和不耐烦。得到有事情发生的反馈不是更好吗?或者更好的是,得到一个关于事情完成需要多长时间的预测?
Tqdm 是你的朋友!
Tqdm 是一个 Python 模块,它让你用很少的代码和很小的执行开销就能给你的循环添加智能进度条。除此之外,它还提供了剩余执行时间的预测。而且,对本文来说最重要的是,它附带了一个熊猫集成。让我们看看那是什么样子。
和往常一样,我们首先将模块添加到我们的示例环境中
poetry add tqdm
现在你要做的就是导入 tqdm 和调用 tqdm.pandas 向熊猫注册。现在您可以在 DataFrame 对象上调用 progress_apply 而不是 apply 。下面是使用一些无意义的示例数据的完整代码
在我的电脑上,产生的进度条看起来像
Hello Medium: 42%|████▏ | 4177/10000 [00:01<00:02, 2232.11it/s]
你现在知道你在这个过程中的位置,并且估计你还剩多少时间来喝完你的咖啡。
增加申请电话
在上一节中,我们已经看到了如何获得关于执行长时间运行的应用函数的反馈。这让我们可以在继续工作之前估计我们可以喝多少咖啡。然而,有些人说你不应该喝太多咖啡,因为它不健康。因为我们都想保持健康,所以减少等待时间,从而减少我们喝咖啡的数量是一件好事。即使你不喝咖啡,更少的等待时间意味着更多的生产时间。我们都想拥有它。
Swifter 提升您的数据框架应用调用。
更快使更容易以 最快 可用 方式将任何功能应用到您的熊猫系列或数据帧。它首先尝试以矢量化的方式运行函数。如果失败,swifter 会决定是执行 Dask 并行处理更快还是使用标准 Pandas apply 更快。所有这些都是通过一个函数调用自动完成的。这是一个很好的抽象层次!
让我们快速看一下代码。首先,我们将 swifter 添加到我们的示例环境中(我想这会变得很无聊,但我想保持这种结构)
poetry add swifter
我们现在只需要导入得更快,并且可以在我们的数据帧或系列对象上调用df.swifter.apply(func)
。搞定了。Swifter 还带有 tqdm 进度条实现。要调用它,您需要调用df.swifter.progressbar(True,”Hello Medium").apply(func)
Sweat!
当你看到你必须做什么来使用 swifter 时,你能猜出它是如何注册到熊猫对象的吗?如果你的答案是“它使用熊猫扩展 API”,那你就对了。哦,这一切是如此完美地结合在一起:)
最后,让我们比较一下 swifter apply 和 Pandas apply 对上述虚拟数据的执行时间
df = pd.DataFrame(np.random.rand(10000, 10))
%timeit df.swifter.apply(lambda s:s**1/2, axis=1)
**29.1 ms** ± 118 µs per loop
%timeit df.apply(lambda s:s**1/2, axis=1)
**2.96 s** ± 6.39 ms per loop
使用 swifter 的 29.1 毫秒比使用正常应用的 2.96 秒少得多。具体来说,大约快 100 倍。
我相信您也可以手动实现这种性能,但 swifter 可以为您实现。
包裹
在这篇文章中,我向你展示了如何增压你的熊猫工作流程和经验。总之,对你来说最重要的三点是
- 使用 pandas-profiling 对 pandas 数据帧执行 EDA。
- 利用 Pandas 扩展 API 根据您的需要定制 Pandas 对象。
- 使用 tqdm 和 swifter 来增强和加速对熊猫对象应用函数。
感谢您关注这篇文章。一如既往,如有任何问题、意见或建议,请随时联系我。
如何采用数据驱动的方法进行 SEO
什么是数据驱动的 SEO?
“数据驱动”一词在大多数市场营销学科中都很常见,它指的是用于战略制定的定量和定性数据的积累和分析。因此,数据驱动的 SEO 意味着在制定 SEO 策略时将数据作为主要组成部分。
对许多人来说,网络分析和搜索引擎优化数据似乎很神秘。的确,有时感觉就像是在读一门外语。然而,如果你花时间收集可用的信息,看看它,并弄清楚这一切意味着什么,你可以找到机会,导致相关和有利可图的搜索流量。
关键词研究
SEO 中使用数据的最常见方式之一是生成关键字,并确定哪些关键字最有效。如果你花时间来选择合适的关键词,最好是选择那些与你的潜在在线客户正在搜索的关键词相一致的关键词。为此,您需要对与您的产品或服务相关的搜索查询进行深入分析,并分析潜在客户的浏览趋势和行为。
我知道寻找搜索量最高的关键词很有诱惑力,但如果你在与一个全新或年轻的网站合作,在这些查询的搜索结果中与老牌公司竞争会很有挑战性。所以,寻找你的竞争对手没有强大存在的关键词。一旦你的目标关键字开始排名,继续下去,直到你得到它的顶端。如果你在一个页面上同时定位了太多的关键词,你很可能会分散你的注意力,并且不能让你最有针对性的关键词排名靠前。记住:选择关键词的秘密是找到那些搜索量高、竞争少的关键词。
监控用户行为
SEO 社区中正在进行的一场辩论是关于用户行为指标和排名之间的相关性。可以理解的是,谷歌代表否认、确认、再否认两者之间有任何关联。然而,如果谷歌的目标是为其用户提供出色的体验,那么行为指标必须予以考虑。SparkToro 的创始人 rand Fishkin(Moz 的联合创始人)对搜索结果中的用户行为指标和排名进行了测试,发现它们高度相关。根据他的结果,用户行为指标显然是一个重要的排名因素。
不管行为和排名之间是否有联系,了解搜索引擎如何评估用户行为仍然很重要。以下是搜索引擎可能用来理解用户的一些信号:
- 点击率
- 点击其他搜索结果
- 新一代搜索引擎
- 跳出率
- 保压时间
- 现场时间
- 每次访问页数
- 重复访问
- 这样的例子不胜枚举…
这里有一些方法,你可以用来改善和衡量你的搜索结果的用户行为:
点击率
“点进”是用户点击来自搜索引擎结果页面(SERP)的结果并被发送到另一个页面的动作。因此,点击率是一个结果从投放的印象数中获得的点击数的度量。如果你的页面在搜索结果中出现 100 次,并被点击 12 次,那么你的点击率是 12%。
您可以使用谷歌搜索控制台查看您的点击率和特定搜索查询的排名,这是一个适用于所有网站的免费工具。你可以将你的点击率和你的页面在目标关键词上的排名进行比较。如果你的点击率低于平均水平,那么这可能是你需要重点提高的地方。
你可以通过使用高级网页排名的谷歌有机点击率历史来查看你的行业点击率平均排名。重要的是要知道,不同类型的搜索查询会有不同的点击率(品牌与非品牌、信息、特定位置、长尾查询等)。).我更喜欢使用 Ahrefs 关键词浏览器来获取特定搜索查询的关键词点击量数据。
那么,如何提高自己的 CTR 呢?很简单:只需调整用户在 SERPs 中看到的元素(页面标题、URL 和元描述)。
虽然我不会在本文中讨论优化这些元素的最佳实践,但是您可以了解更多关于如何优化标题标签的信息,以及如何在 Portent 的博客上改进元描述。
停留时间和弹簧粘连
停留时间,也称为页面上的时间,衡量用户在给定页面上花费的时间。增加用户在页面上的时间可能会向搜索引擎发送信号,表明该页面质量良好。然而,如果你的有机流量有很高的跳出率,那么你的用户可能是 pogo-sticking。
Pogo-sticking 是一种典型的行为,表明满足用户搜索查询的结果较差。例如,当用户从 SERP 访问您的页面时,如果用户很快返回到搜索结果,然后点击另一个结果,这就是 pogo-sticking。在搜索查询中排名最高的页面会立即包含用户正在寻找的所有信息,这样用户就不会返回到搜索结果中寻找替代信息。
要确定这是否是您的目标页面的问题,请使用您网站的分析来查看有机流量跳出率(仅访问一个页面并离开的访问者的百分比)和网页的平均会话持续时间(停留时间)。正如已经提到的,用户意图和关键字将为可接受的跳出率和停留时间创建不同的结果。这里有一些行业跳出率基准来帮助你开始弄清楚什么是你的网站可以接受的。也有很多很棒的资源提供关于如何降低网页跳出率的提示和最佳实践。
选择正确的工具和资源
如果你想要一个精确的数据驱动的 SEO 策略,拥有合适的工具是必不可少的。令人惊讶的是,大多数 SEO 专业人士缺乏获得准确数据的途径,因此他们不得不做出假设。因此,搜索引擎优化预测并不总是正确的。数据驱动的方法利用准确性和精确性在搜索结果中领先于竞争对手。
在选择帮助您收集数据的工具时,需要考虑两个要点,一是您要分析哪些数据,二是哪些数据有助于提高策略的清晰度。数据驱动方法的目标是收集信息,以便改进您的计划。尽管很诱人,但不要在你已经成功的领域加倍下注。持批评态度,想办法填补你的策略中的漏洞,并在整个 SEO 领域创造更多的可见性。
最后,利用你所有的资源。也许你的公司已经投资了点击付费广告。如果是这样的话,与负责这些广告的人谈谈,因为他们的数据将能够提供有价值的信息,如哪些关键词转换了,哪些登录页面的跳出率低,等等。
结论
有大量的数据和资源可以帮助你提高搜索引擎优化。再次,坐下来,看看你可以得到的数据,并弄清楚这一切意味着什么。然后你会发现机会,可能会导致相关和有利可图的搜索流量。
感谢阅读!如果你有任何问题,或者你需要一些帮助来开始你的搜索引擎优化策略,请联系我。
如何使用转换预测模型确定促销目标,以最大化净增量收入?
Identifying the right set of customers to be targeted for the promotion is the key for a successful campaign Image Source
每当一家公司选择通过提供折扣或开展数字广告活动等策略来推广某种产品时,都会有一定的成本以及一些与之相关的潜在创收机会。如果公司不小心选择合适的客户群来接受促销,最终可能会损失很多钱,却没有获得多少回报。
如何量化促销活动的净回报?
让我们假设该公司有权向一组人推销其产品。他们可以被视为现有客户,或者只是通过社交媒体、搜索引擎广告、电子邮件或其他一些沟通机制可以接触到的受众。
假设该公司进行了一项实验,从这些人中随机抽取一小部分样本,从中得出统计结论。
它进一步将这个样本分成大小大致相等的两组。哪个人被分配到哪个组也是随机的。
对于其中一组,公司选择发送促销信息,为简单起见,我们假设所有人都收到了促销信息。我们称这个组为治疗组。例如,公司选择向该组中的所有成员发送折扣券,每个人都会收到并看到它。
让我们考虑一个人获得晋升的相关成本。例如社交媒体平台收取的每次点击成本。
考虑在接受促销后选择购买产品的人数。
公司从接受促销的人购买的产品中获得收入。
第二组是公司不向其发送促销的组。我们称这个组为控制组。
在这个对照组中,会有一些人没有收到促销,但他们仍然购买了产品。
公司从没有得到促销的人购买产品中获得收入。
假设公司在一段时间内进行了这个实验,在这段时间结束时,它得到了这些数据。然后它可以像这样计算促销活动的回报。
增量响应率(IRR) 量化接受促销后人们的响应或购买率的变化量。
净增量收入(NIR) 量化公司在开展促销活动后获得的净收入的变化,同时考虑与之相关的成本。
我相信上面的两个公式直观上是有意义的,它们很好地抓住了促销活动的效果。
公司的目标是最大化 IIR 和 NIR 这两个参数。
对于不同类型的公司或场景,IRR 可以捕捉来自个人的任何积极行为作为响应,如签约或购买等。
对于一个产品销售公司来说,NIR 反映了促销活动在直接金钱收益方面的有形结果。
想象一个场景,在接受促销后选择购买产品的人数大致等于(或可能少于)没有接受促销但仍然购买产品的人数。在这种情况下,如果治疗组和对照组的人均收入相同,则该活动的净增量收入为负。这意味着该公司通过开展促销活动造成了金钱损失!
公司如何最大化 IIR 和 NIR?
如果我们假设向一个人发送促销的成本和从接受促销的人的购买中产生的收入都是常数,那么我们留下来调整的唯一两个参数是接受促销的最小人数和接受促销后选择积极响应(例如购买)的最大人数。
公司应该只向那些在获得晋升后极有可能做出积极回应的个人发送晋升。
公司如何决定向谁发送促销信息?
根据通过实验收集的数据,该公司可以将其潜在购买者组成的可接触受众分为两类:在接受促销后购买的人和其他人。
请注意,其余的人将包括那些不值得被提升的人。其中包括:
- 那些购买了产品却没有得到促销的人。这一点很重要,因为发送促销信息是有成本的,公司不希望把这笔钱花在那些可能已经购买了产品的人身上。
- 接受促销但没有购买的人。这些人是公司花钱进行促销的对象,但他们选择不购买产品。这些人可能会因为某种原因(可能是隐私问题)在看到公司针对他们的促销活动后感到恼火,并有意识地选择不购买。
- 没有收到促销且没有购买产品的人。该公司从实验中获得的数据很少,无法判断是否向他们发送促销信息。保守的做法是不给这样的人升职。
这个问题转化为决定哪个人属于哪个类别。应用基于机器学习的统计模型可以有所帮助。如果公司有一些与潜在受众相关的个人数据,如人口统计、年龄、性别、地点、购买历史、财务状况、婚姻状况、教育、就业背景、兴趣等。然后,它可以使用它来识别这些人中的哪些子集在接受促销后更有可能购买该产品。
让我们看一个例子
为了进一步解释这种技术,我将举一个由 Starbucks 提供的样本数据集的例子。
你可以在这个笔记本这里找到我这个项目的代码,这个项目是在 GitHub 上可用。
Happy Hour, Starbucks’ invite only promotion Image Source
它曾经向数据科学家候选人提供该数据集。它包含 120,000 行,其中有 7 个名为 V1 到 V7 的数字变量,这些变量与他们实验中的每个人有关。它有两个额外的变量,表明这个人是否得到了促销和她是否购买了产品。
在星巴克的例子中,从接受和未接受促销的两类顾客那里,每次购买的收入是 10 美元。向一个人发送促销信息的成本是 0.15 美元。因此,在这种情况下,用于 NIR 的公式可以转换成如下形式:
为了评估我们的预测模型的性能,有必要将来自实验结果的可用数据集分成训练和测试数据集。测试数据集不得以任何形式用于训练模型。它必须仅在训练结束时用于对照一些预定参数评估模型,在我们的情况下是 IIR 和 NIR。如果我们想在训练阶段评估我们的预测模型,我们可以将训练数据集进一步分成两部分:训练数据集和验证数据集。该模型可以用训练数据集上的一些超参数来训练,并在验证数据集上进行评估,以选择超参数的最佳值。
有几种方法可以将该数据集用于训练基于机器学习的统计模型。我将讨论一些使用该数据集获得良好结果的方法。
第一种方法
由于公司只对那些只有在收到促销后才会购买产品的人感兴趣,我们可以定义一个名为Response
的新的二进制变量,如果这个人同时有两个变量,即表示她是否收到促销的Promotion
和表示她是否购买了产品的Purchase
,则该变量将被设置为True
。对于拥有其余Promotion
和Purchase
变量值组合的人,分配给Response
的值将为False
。在用这个新的目标变量丰富数据集之后,像正则化梯度推进(XGBoost) 这样的机器学习模型可以用于通过将变量 V1 到 V7 视为输入变量并且将Response
视为输出变量来训练数据集。
检查和处理数据集中的不平衡
在定义了这个新的Response
变量之后,我决定检查分配给它的值是否不平衡。因为这通常是市场营销活动的情况,在这些接受促销的人中只有一小部分人选择按照它行动。在该数据集中,分配给True
和False
的人数与目标变量Response
的值之间的比率约为 1:116。这表明数据集中存在巨大的不平衡。
如果我们选择忽略这种不平衡,并继续在这个数据集上训练一个机器学习模型,它可以实现 0.99/1 的精度,只需在测试中收到的所有情况下,将Response
变量的输出给False
。得出该模型在准确性方面表现很好的结论可能会产生误导。具体来说,这种模型根本无法识别公司应该向哪些人发送促销信息。
有几种方法可以处理不平衡数据集
- 通过包含新的合成生成的数据点,对输出变量等于少数类的数据进行过采样(例如,使用 SMOTE 技术
- 通过在采样期间替换,用等于少数类的输出变量对数据进行过采样。在这种情况下,属于少数类的数据点附近的决策边界可能不能很好地概括。
- 对输出变量等于多数类的数据进行下采样。在这种情况下,我们删除了一些可以用来训练模型的数据。
- 使用机器学习模型中可用的类别加权机制,根据目标变量的值为训练样本分配不同的权重
对于这个数据集,我决定使用合成少数民族过采样技术,通过在分配给少数民族类的现有数据点之间引入新的数据点来实现数据集的平衡,输入变量值会有一些变化。
对于这个数据集,我决定在这个数据集上训练正则化梯度增强模型(XGBoost) 来预测一个人的Response
变量,其属性被指定为V1 to V7
作为输入变量。
XGBoost 有大量的超参数,需要基于交叉验证进行设置。我决定调整一些重要的值,并选择用那些在交叉验证测试中表现最好的值来训练模型。
该模型在验证集上获得的 F1 分数约为 0.028311,这被认为是相当低的。然而,我们必须记住,在我们的问题中,真正的评估指标是 IIR 和 NIR。
我继续使用 XGBoost 模型对最佳参数进行训练,并使用它对测试数据集进行预测,以决定给定的人是否是在接受公司促销后会购买的人。如果是,那么它将推荐发送促销给那个人。
在测试数据集上,该模型的 IIR = 0.0206,NIR = 259.25。
星巴克在数据集描述中提到,他们的团队实现了 IIR = 0.0188 和 NIR = 189.45
从我们的预测模型获得的结果表明,这种方法可以是解决这种类型问题的非常有效的方式,其中公司需要决策支持系统来决定向谁发送促销。
方法 2
另一种方法是对每个人进行评估,与未接受促销相比,接受促销的人进行购买的增量概率是多少。如果给定人员的递增概率足够高,我们的算法将推荐向该人员发送促销。
Formula for calculating Incremental Probability (IP)
为了实现这种方法,我们需要添加Promotion
,作为该人是否获得晋升的指示变量,作为除我们拥有的每个人的个人数据之外的输入变量。目标输出变量将指示该人是否采取了期望的行动。
在我们的 Starbucks 数据集的例子中,我们将使用变量V1 to V7
和Promotion
作为输入变量,使用Purchase
作为目标输出变量。
下面是在这种方法中如何决定是否发送促销信息。我们首先通过将Promotion
输入变量分别设置为真或假,并计算两个概率之间的差异,来计算得到促销和没有得到促销的人进行购买的概率。如果差异大于某个阈值,那么我们可以向该人发送促销信息。可以使用超参数优化技术来确定阈值,同时使用 NIR 公式来计算要最小化的目标函数的返回值,即分数可以是-NIR。
数据集的Purchase
变量值在True
和False
值之间的比率约为 1:80。这表明数据集中高度不平衡。我使用 SMOTE 技术对少数类进行过采样,以使两个类在训练数据集中的比例相等。
在这里,我使用对数损失作为评估指标,同时调整估计数作为 XGBoost 的超参数,因为我更感兴趣的是计算给出特定响应的人的准确概率,而不仅仅是预测响应类别。根据这个概率,我可以计算出人们在接受促销后购买某种产品的增量概率。
具有最佳超参数的经训练的 XGBoost 模型在验证数据集上获得 0.07 的对数损失分数。就对数损失而言,它越小,模型的预测性能就越好。
我使用这个模型对测试数据集提出建议,并计算出 IIR = 0.018826,NIR = 98.30。将其与星巴克声称其团队实现的 IIR = 0.0188 和 NIR = 189.45 进行比较,我们可以说该模型显示出不错的性能,但不如方法 1 或星巴克声称实现的效果好。然而,在不同的问题场景中,它可以被认为是一个值得考虑的选项。
可以尝试的方法 3
在与促销相关的文献中提出了一种基于两种模型的方法。在这种方法中,我们训练了两个独立的Purchase
预测模型:一个针对获得晋升的人,另一个针对没有获得晋升的人。然后,我们计算每个人在有促销和没有促销的情况下进行购买的概率差异。如果差异足够大,我们可以选择向那个人发送促销信息。然而,一些人对这种方法提出的警告是,它训练两个独立的模型,每个模型都可以在输出中生成自己的概率范围,并且正确预测增量概率的误差会加倍,因为我们使用了两个预测模型。我将这种方法留给感兴趣的读者(或我自己)在将来的某个时候在这个数据集上进行尝试。
我希望你觉得这篇文章很有见地。
你可以在这里的这个笔记本里找到我这个项目的代码,带有星巴克数据集的项目在 GitHub 上有。
如何教代码
程序设计教学中的问题及解决方法指南
学习编码真的很难,教编码更难。《如何教代码》里没有训练营。大多数教师没有受过任何正规的教育培训,都是软件出身。
我很高兴以不同的方式与几个训练营合作(作为学生、老师或经验伙伴)。我还:
- 运行代码 Meetup 俱乐部教学代码
- 发布了一系列黑客马拉松
- 帮助开展各种学习代码活动。
问题
令人惊讶的是,教学规范中的规定如此之少。结果是学生可以获得完全不同的体验。我见过这个星球上一些最好的教育被免费赠送。然而,我也见过其他训练营给他们的学生提供 3 个月的困惑,并收取 9000 英镑的乐趣。
我看到训练营挣扎着前进,直到他们不可避免地失败,而其他人只是继续成长。拿钱让学生接受糟糕的教育是错误的,但我也不认为任何人只是想偷别人的东西。
随着当前大量潜在的工作被软件所取代,越来越多的学生希望转而从事技术工作。
像《T2》和《T3》惨败这样的故事只是一个大问题的表面。与其只是谈论问题有多大,不如采取措施解决它。
解决方法
以下是我自己了解到的关于教代码的困难。如何以给学生最佳体验的方式教授代码?以及如何通过提供出色的体验来发展可持续的业务。
(注意——作为一名新兵训练营的学生,这本书值得一读。如果你的课程犯了这些错误,你可以通过鼓励一些更好的实践来挽救你的教育。)
第 1 部分——为什么学习代码很难
学习说电脑很难。由于我们思考、感知和学习事物的方式普遍不同;有些人觉得这简单得令人沮丧,有些人觉得这不可能。对于一般人来说,这真的很难。然而,这是完全可行的…
学习你的第二种和第三种计算机语言相对来说比较容易,而且你知道的越多只会越容易。
你不知道你不知道的事情
教 it 的问题是,你得懂很多会说话的电脑,才有资格教别人会说话的电脑。然而对你来说,学习一门新的计算机语言现在很容易。很难理解 10 年前你所面临的困难。对你来说,它只是将一组新的语法分配到现成的概念中。
The most logical analogy is learning a new human language.
人类的第一种口语是最难学的,因为你以前从未学过一种语言。有特权的学生被教授拉丁语,以理解语言是如何建立的根源。有了这些核心知识,他们可以很快理解世界各地使用的新的现代语言。类似地,计算机科学家通常学习 C,这样他们可以理解他们遇到的大多数语言的根源,即使他们并不期望真正使用它。
在学校学语言是有好处的。多年来,你慢慢积累了一堆语法,最终让你能够理解和说大多数事情,但这需要沉浸才能真正了解上下文并掌握它。
浸没
或者,你可以去一个外国,通过上课和不断的沉浸,你会在 3 个月内学到更多。但这仍然是一个令人困惑和具有挑战性的经历,你没有资格在复杂的商业环境中从事高级工作,但你可以在咖啡店工作得很好。
与说计算机相比,你已经知道你的母语,这是你的零语言,它给你一堆模板概念来参考。
寻找参考点
人不会说计算机,第一次学没有任何参照系的语言零。
你可以每周练习说几个小时的电脑来学习语法,但你需要几年才能精通。如果你一周花很多时间学习,你可能要花一年的时间才会感到舒服。或者你甚至可以做一个 3 个月的完全沉浸式训练营。
然而,你仍然不是一个大师,你说的(写的)很多东西会显得有点迟钝,其他人对你说的很多东西可能会超出你的理解,但在你自己的时间里,你可以查阅并从那里建立。
你没有资格要求一份高层次的工作,但是初级的工作是完美的。
结论
总之,学习一个全新的东西并不容易,向初学者教授你所熟知的东西有很多挑战需要你注意。
这是教一个人他们的第一门编程语言的困难的宽泛概念。这篇博客的其余部分回答了“如何教授代码”的原始问题
第二部分——说教什么也没教,化繁为简
常见错误
老师通常喜欢向学生展示他们需要知道的关于一个概念的一切,这样他们就可以开始并成为专家。这可能是一个小时的讲座。计算机科学家(学习 C 语言后)可以处理这个问题。代码新手不行。
在开始 5 分钟的讲课后,你说的任何其他东西都是没有意义的,他们听不懂。停止说话,做一些他们能跟上的练习。
(如果你是通过视频学习,5 分钟后停下来做练习)。
锻炼需要在正确的时间以正确的水平进行。对于一群以不同速度和不同风格学习的学生来说,这不是一件容易的事情。当我稍后讨论这个问题时,需要掌握理解什么是合适的。
让我们停下来做另一个类比。
学习骑自行车
Imagine you are teaching students to ride a bike.
第一讲。你将深入了解自行车平衡的工作原理,以及如何转移身体重量,以在踏板上施加正确的力来提供动力。这是核心的东西,非常重要。
停下来喝杯咖啡休息一下,你会很好地安排一天。
第二讲。你谈论转向和如何倾斜入弯。并没有预期的那么久。你很兴奋,所以你解释了当你正确理解了上面的过程时,不用手骑并不困难。一个学生,吉米,说他以前骑过一次自行车,说没有手真的很难。你很聪明地纠正他说,这需要对物理有正确的理解,很明显他的上一个老师没有教好他。
哇,真有趣。午休时间——是的,午餐时间到了!。你告诉一些学生你在阿尔卑斯山骑自行车的经历,以及它有多美,但也提醒他们你每天是如何骑车上班的,即使是在下雨的时候,骑自行车并不好玩,你告诉他们骑自行车的高潮和低谷是件好事。(你要确保吉米在听。真是个混蛋。)
下午**——让我们把它们放在一起!**
你跳上一辆自行车,在教室里骑一会儿,这样学生们就可以看到它在现实世界中是如何工作的。你过分强调自己的动作,几乎摔倒,向他们展示如何慢慢地倾斜入弯,以便他们能正确地看到。这一切一定会在他们的脑海中完美地融合在一起。妈的,他们现在一定对骑自行车了如指掌。
你真是个好老师,他们会成为有史以来最好的摩托车手。
推迟其他计划
你已经有了如何解释换挡、安全驾驶、修补轮胎的计划,但现在是时候尝试一下了。你检查了你的自行车金属清单,是的,你真的教会了他们核心基础知识,涵盖了你实际骑自行车所需的一切。
其他东西是额外的绒毛,你有时间扔在没有手的概念,任何人都很快得到它。(真聪明,去你的吧!)
大事件
你应该给每个学生一辆自行车。
第一个学生像弱智一样直挺挺地倒在地板上。另外两人试图帮助他,但现在另一名学生试图骑上他们的自行车,她掉进了他们造成了混乱。啊呀,他们真蠢。这些人将会是慢性子,你记下花额外的时间和他们在一起,然后走过去帮忙。
当你问他们有什么问题时,你解开他们的自行车,并试图隐藏你对他们有多愚蠢的困惑。你被一声大叫分散了注意力,抬头一看,到处都是混乱。这是怎么回事?他们为什么不明白。接下来你知道你疯狂地跑来跑去,试图帮助每个学生骑上一辆该死的自行车,但他们似乎都不明白如何保持平衡的基本概念。这是第一堂课的开始,他们一定明白他们都在听!
很快,一个学生哭了,两个受伤了,另一个走出门外,声称他们再也不能骑自行车了。聪明的屁股吉米聪明的裤子,聪明的想法,聪明的傻逼向你走来。他问你为什么不给他们该死的稳定器。
这真的很尴尬。
学习代码
理论上的死亡
简单来说,编码就是知道一些语法和何时使用它的上下文。事实上就是这样。事实上,如果你能在适当的时候查找,你甚至不需要知道语法。
但是就像学习骑自行车一样,如果不做任何编码,这个理论在很大程度上是没有意义的。交谈 5 分钟后,其他任何事情都被浪费了。学生对你实际上在说什么没有真正的概念,然而,你扔给他们很多上下文和语法,仍然没有帮助。
人们在实践中学习。
学生们可能看起来像是在跟着做,但如果他们不做什么,他们的思维就会经常偏离任何抽象的理论,即使他们试图集中注意力,即使已经过了 6 分钟。
甚至不要费心向他们展示用例的超级简单版本,只要和他们一起做就行了。
一起构成这个概念/方法/功能的最简单的核心例子,没有任何其他东西模糊它。只是它的语法。然后让他们用不同的变量重新构建。
根据不同的概念,给出一个稍微复杂一点的版本,或者进入使用它的上下文。然后让我们提供一些练习给他们做。
继续构建肤色的层次,随着你的深入,在更长时间的独立练习中有更大的停顿。
到下午的时候,他们已经准备好在一个项目中或者在解决更难的算法时使用这些想法。别再教他们废话了。只是在不同的事情出错时在那里指导他们,让他们自学,真正探索他们可以用早上你教他们的东西做什么。
简单可能比复杂更难:你必须努力让你的思维变得清晰,让它变得简单。但最终还是值得的,因为一旦你到了那里,你就可以移山倒海了。
史蒂夫·乔布斯
第 3 部分——将上下文和语法结合起来的好练习
练习食谱
就建筑练习的诀窍而言,从 语法开始
完全的新手
给他们少量的语法。让他们使用它。
如果这是学习一门语言的第一天,那么你可能要教更多的语法,并让他们使用这些语法。
在他们学会一些东西后,他们可以把这些不同的语法放在一起,让他们互动,并开始理解他们所学内容的上下文**。**
深潜
如果这是学习一个框架的几个星期,那么他们可能首先需要一些背景**。但是要简短。**
用于涵盖一个概念的代码可能位于多个文件的不同位置,并且可能没有直观的第一位置来教授语法。尝试从第一个逻辑用户操作开始。不要向他们展示用户操作的完整路径,只需向他们展示你编写的第一段代码的语法。
然后在上下文中添加它做什么以及它可能与哪些其他文件或函数交互。浏览与第一个文件/函数交互的语法。
用第一个功能构建所有交互的完整上下文。然后沿着第二个函数的路径,第三个函数的路径等等,直到你完成这个循环。
确保在第一次演示中,你已经把逻辑循环做得尽可能的小和干净,并且最好在结束时有一些事情发生。如果这真的是一个很长的循环,那么在完成整个事情之前,休息一下做一些练习。
Avoid navigating too many files to introduce a concept
注意事项
评论
随着学习的进行,在每个函数/方法上添加注释也很方便,这样学生们就有了一个他们自己构建的注释良好的演示文件来参考。当然,这也让他们进入良好的实践等等…
控制台
打印出你在这个过程中所做的许多事情,以显示每件事情在做什么,以及学生在逻辑的道路上应该期望什么。这可以帮助提供上下文,帮助他们掌握调试,这样你就不用花太多时间帮助他们调试了。
单独的项目和实例
当教授一个框架时,你通常会有一个项目,每个人都在工作,提供整体的背景,让他们自己构建一些东西。像猫的脸书之类的东西…在给出例子的同时,很容易用相同的项目类比来展示它们。使用不同的项目类比非常重要。
这可能只是狗的脸书,所以学生只需将单词 dog 改为 cat。
但理想情况下,你希望它是一个略有不同的概念,所以所有进一步后端的东西将有不同的名称,如数据库集合等…
资源
提供一个有用资源的列表很重要,但是你也必须预料到,除非你给他们一个在练习中使用它的具体理由,否则一个资源都不会被使用。
因此,你应该将最重要的资源融入他们的练习中。
因此,一个要求他们使用一个特定术语的超级简单的 API 参考查找的练习将使他们使用 API 文档。你想最终让他们自己导航这些,而不必问,但首先你需要为他们做。
举例
您正在教授回调,您希望他们使用 放大镜工具 。不要只是把它藏在一系列有用的东西中去探索。实际上,给他们一些练习,让他们解释你用工具给他们的回调函数。然后,也许他们可以尝试使用该工具使回调函数以不同的方式工作。
现在,每当他们陷入回调时,他们会立即想到去使用这个工具,并可能将它保存在他们的收藏夹中。看看这是多么有用,相比之下,它被藏在一个幻灯片甲板,他们不会打开下周当他们卡住了。
第四部分——家庭作业怎么办
家庭作业和额外作业。
和资源一样。仅仅列出学生必须做的额外作业是很诱人的。但只要假设这在很大程度上不会发生。为了更上一层楼,所有必须学习的东西都必须在教室里解释和完成。
students can drown if you don’t restrain yourself
学生们需要对一个想法有一个结论,并找到巩固它的方法。在工作日或每周末给学生留出时间和空间,让他们退后一步,评估哪些事情他们已经学得很好,哪些事情对他们有挑战。他们需要确定他们需要更多练习的关键部分。
这在周末尤其重要。提供大项目是如此诱人,因为他们喜欢建筑材料。学生不傻。如果他们有正确的工具,他们可以自己制作增加复杂性的项目,这应该是自我引导的。当然,学生们渴望尽快学习,但有些人总是有理由在周末不工作,不管是工作、生日还是生活…
定义什么是必需的,什么是额外的
应该加强的是复习他们没有理解的内容,并确保他们已经赶上了。到下周,你需要同一水平的每个人都准备好在平等的基础上进入下一组概念。
作业不好的例子——在猫书项目中为每个猫用户添加谷歌地图旅程。
一些学生会真正投入其中,学到很多东西。而其他学生可能整个周末都在工作以支付他们的课程费用,并且仍然在丢失前一周的东西。假设所有学生在周一早上都掌握了 GoogleMaps API 是不公平的,因为事实并非如此。
在接下来的课程中,你不应该要求掌握地图应用编程接口知识,而应该先自己教授新的知识。
范例好作业——考一周所学的东西。任何确定的弱点完成建议的额外练习
这个家庭作业帮助学生结束他们在一周内所学的内容,这样作为一名教师,你就知道课程直接涵盖的内容。
作为一个额外的,你可以为那些有时间学习酷的东西的人建议地图项目的想法。你不想阻碍那些比别人学得更快的人。但是你也不希望他们学习很多你以后会学到的新知识,因为他们会比其他人走得更远。
一般来说,最好是让他们在同一主题上达到更高的熟练程度,而不是让他们只学习下周的主题,这样会给你一个完全不同的班级。
第 5 部分—反馈和使用问题作为教学工具
反馈
拥有一个良好的反馈回路,让学生匿名发表意见是至关重要的。我已经解释了教授一个概念的基本布局和速度,但是在现实世界中,你的学生应该设定速度。
掌握学生理解和不理解的数据至关重要。它允许您在正确的时间动态地交付最好的内容,并为后面的学生不断改进它。
作为教学工具的问题
作为反馈的一部分,在任何讲座中简单地提问就可以成为你的飞行速度表。这似乎是显而易见的,但实际上本身就是一门艺术。
你必须避免加载问题****
当你解释完一些困难的事情时,不要简单地问是否可以。如果你没有得到任何真正的答案,这不是一个简单地继续前进的信号。
相反,尝试询问是否有人可以向全班解释这个概念。如果你得不到答案,这是继续前进的信号吗?当然不是。
当你开始的时候,人们会很害羞,什么也不说。如果你选择一个学生来解释一个概念,而他们用恐惧的眼神看着你,不要继续下去!这可能会让他们免于尴尬,但并不能解决他们的问题。用更简单的方式回顾一下这个概念,或者问一个更简单的问题。
当你开始了解这个班级,他们开始互相了解,这将变得更容易。你应该培养他们在别人面前说话时感到舒服。他们应该有信心尝试解释他们并不真正理解的事情。然后你就能确切的看到他们做的和没做的部分。理想情况下,你可以进行积极的小组讨论,这是听取不同人的理解的一个很好的动力。
互相解释
一个很好的练习可以是暂停整堂课,让几对学生互相解释一个概念。当两个一无所知的学生有机会发现另一个人不知道发生了什么时,他们不会因为问问题或承认他们不明白而感到尴尬。
在 60 秒的休息之后,人们将在心理上准备好谈话,当你询问哪些群体得到了反馈时,你将确切地知道发生了什么。即使整个房间里只有一个人明白,你也会知道,他们会向每个人解释。你很快就打破了公开讨论的障碍,培养了同伴学习,而不是孤立的随波逐流。
第 6 部分—在同一水平上教授学生
试图教不同水平的学生是一场噩梦,也是一场彻底的灾难。
代码新手
如果你的课程接受绝对初学者,那么它就是绝对初学者课程。让更高级的人上这门课将会是一场噩梦,因为你试图向不同的人教授不同的水平。
即使只有一群绝对的初学者,大多数也会非常慢。你冒着一些学生发现他们讨厌它,而另一些学生发现他们是天才并以每小时一百万英里的速度前进的风险。
课程前的必要条件
大部分课程面向对 JS、CSS、HTML 有基本了解的人。我个人认为,如果学生以前从未编写过代码,那么向他们收取一个月或更长时间课程的费用是错误的。他们不知道自己是否喜欢或擅长,至少需要先有某种形式的测试经验。
最好的策略是设置一些非任意的先决条件,所有学生都必须通过这些条件才有资格选修这门课程。这将剔除不适合编码的人,意味着你有一群有能力和兴趣学习的人。你可以为那些和你一起学习基础知识的人提供一个小型的预备课程,或者为新手提供每周一次的聚会,让他们学习预备课程的内容并了解什么是适合他们的。
拒绝人们背后的商业意识
我理解训练营是一门生意,老师需要挣钱,教室需要付费。但是很重要的一点是,你要拒绝那些不应该出现在球场上的人。
向少数人提供良好的教育,好过向许多人推销你无法提供的教育。那些可以学习的人会减少学习,那些不应该学习的人会失败并要求退款。你将面临混乱和一堆差评,你的生意将一事无成。
如果你只把你的教育给那些有能力接受它的人,你将提供一个很好的体验,并提供一群学生,他们将代表和发展你的品牌。这将导致一个可持续的长期业务。
但是难道没有人可以学习编码吗
考虑到我运行的成长心态播客教你如何做任何事情,永远不要把自己束缚在消极的信念中。我不相信每个人都应该学习编码。
我同意,假设任何有能力学习语言的人都应该能够学习一组新单词的定义和行为,从而最终能够学习编程。但是,有多少人:
- 问过你关于电脑最荒谬的问题。
- 会在他们的代码不起作用 4 个小时后继续努力吗?
- 喜欢花 30 个小时教电脑玩数独,而他们却可以看《网飞》?
并不是每个人都喜欢它,接受一个突然产生学习技术的渴望的人学习一门课程是很危险的,这个人一生中从来没有敲过一行代码。
同样的,任何一个能在没有手机、书籍或电视的情况下静坐 5 分钟的人,完全有能力进行为期 10 天的冥想静修。在静修中,他们需要安静地静坐十天,除了自己的思想之外,不读、不写、不看任何东西。我很确定这不是大多数人喜欢的。
最终,有些人会过得更快乐,而不用学习编码,任何人都没有义务去尝试把不需要的信息强行塞进别人的大脑。你当然不应该说服别人为不适合他们的东西付钱。
摘要
我再说一遍,学习编码真的很难,掌握它是一条漫长的道路。但是学习教授编码也同样困难,并且有更少的文档资源。
让人们拥有这样一项令人敬畏的技能真的很令人兴奋。你希望学生们能从和你在一起的时间里学到尽可能多的东西,但是如果你以前从来没有教过新手,那么教新手的速度会慢得令人沮丧。
质不量
你需要专注于尽可能好地教他们,而不是试图尽可能多地教他们。如果他们的知识没有深度,你的教学就完全没有意义。
当他们还没有理解你到目前为止教过的所有部分时,匆忙完成他们构建一个全栈应用所需要知道的一切是没有意义的。如果你发现自己在为他们做一些事情,而他们什么都不懂,没有你他们就做不了。当他们离开这门课程时,他们将无法再做一次,你也不会有一群学生向世界展示你的课程有多好。
一些最好的训练营只是专注于真正擅长核心概念,这样学生就有能力自学 React 和其他框架。如果他们试图把这一切都塞进一个从零到英雄的课程中,他们最终会发现很多人都没有成功,只是后来又回到了零。
If there’s no one on the train stop and rethink
不如教他们一半的材料,让他们掌握。他们必须非常自信地走出去,继续使用他们所知道的东西,并在此基础上继续发展。如果他们结束时对你教他们的东西感到困惑,他们将无法找到工作或做出很酷的事情= >课程和你的努力都将付之东流。
完成意味着完成
就像建软件一样,做好了就做好了。你不能发布一个完成了 90%的应用程序,因为它根本就不工作。在教授重要概念时,如果 90%的学生理解了,但不能实际解释如何使用,那么就不能 使用。
不要教他们更多的东西,希望这些东西会变得有意义。完成你已经开始的事情,或者授权他们把最后的 10%作为他们的家庭作业。
从小步开始
像学习任何东西一样,学习教学需要循序渐进,边做边学是关键。在开始一门完整的课程之前,最好在一个较小的环境中练习教学。
试着办一个聚会或者周末课程。找一些学生来指导。我喜欢它,但你可能会讨厌它,你不能告诉除非你试过。
这听起来可能是显而易见的,但有些人真的开始了训练营,第一天是他们第一次尝试教别人编码。不要这样做!
为什么这么做?
教书是世界上最好的事情。这并不容易,但很快你所有的学生都会说电脑,你会为让他们正确地说话而感到骄傲。即使像吉米这样的聪明人(见自行车类比)如果你没有在这个过程中杀死他们。看着他们掌握技能,走向世界,创造出很酷的东西,真是太棒了。
因此,请尝试这些原则,在上面添加你自己的个人风格,并提供任何意见以帮助其他人更好地教学。
如果你喜欢这篇文章,你可能会喜欢我写的一些关于编码和学习的文章:
我运营着成长思维播客,在那里我将心理学、商业和生活中的领先理念进行分类。你可以在我的网站SamWebsterHarris.com找到更多关于我的信息。
如果你喜欢这个,那我会很高兴。如果你不喜欢这本书,我不知道你为什么还在读,人生苦短,去读点别的吧。