使用 Anaconda Navigator 安装 TensorFlow 和 Keras 无需命令行
在命令行中对 pip 安装说不!分三步在你的机器上安装 TensorFlow 的另一种方法。
https://www.pexels.com/photo/silhouette-people-on-beach-at-sunset-315843/
我为什么要写这个?
我花了几个小时使用多种配置的 pip install,试图弄清楚如何为 TensorFlow 和 Keras 正确设置我的 python 环境。
why is tensorflow so hard to install — 600k+ results
unable to install tensorflow on windows site:stackoverflow.com — 26k+ results
就在我放弃之前,我发现了这个…
本文将带您了解如何使用 Anaconda 的 GUI 版本安装 TensorFlow 和 Keras。我假设你已经下载并安装了 Anaconda Navigator 。
我们开始吧!
- 启动蟒蛇导航器。转到“环境”选项卡,然后单击“创建”。
Go to ‘Environments tab’, click ‘Create’
*2.输入新的环境名,我放‘tensor flow _ env’。**这里一定要选择 Python 3.6!*然后“创建”,这可能需要几分钟时间。
make sure to select Python 3.6
3.在您的新“tensorflow_env”环境中。选择“未安装”,输入“tensorflow”。然后,勾选“张量流”和“应用”。将出现弹出窗口,继续操作并应用。这可能需要几分钟时间。
对“keras”进行同样的操作。
通过导入软件包来检查您的安装。如果一切正常,该命令将不返回任何内容。如果安装不成功,您将得到一个错误。
no error pop up — Yeah!
You can also try with Spyder.
no error pop up — Yeah!
然后…哒哒!搞定了!你可以按照本文来测试你新安装的软件包:)
感谢您的阅读。请尝试一下,并让我知道你的反馈!
考虑在 GitHub 、 Medium 和 Twitter 上关注我,以获取关于您的提要的更多文章和教程。如果你喜欢我做的,不要只按一次拍手按钮。击中它 50 次:D
使用 Scikit 生成合成分类数据
Generating Synthetic Data
这是关于不平衡和噪声数据系列文章的第 1 部分。关于偏斜分类指标的第 2 部分已经发布。
为什么我们需要数据生成器?
数据生成器帮助我们用不同的分布和概要文件创建数据来进行实验。如果您正在测试各种可用的算法,并且希望找到哪种算法在什么情况下有效,那么这些数据生成器可以帮助您生成特定于情况的数据,然后测试算法。
例如,你想检查是否梯度推进树可以做得很好,只给 100 个数据点和 2 个特征?现在,您可以搜索 100 个数据点的数据集,也可以使用您自己正在处理的数据集。但是你怎么知道这个分类器是不是一个好的选择,假设你有这么少的数据,做交叉验证和测试仍然留下了过度拟合的机会?或者,您可以使用生成的数据,看看在这种情况下什么通常效果好,是升压算法还是线性模型。
您需要生成数据的几个原因
- 你的模型能处理嘈杂的标签吗?
- 当你的标签 99%是负面的,只有 1%是正面的,会发生什么?
- 如果你的模型能告诉你哪些功能是多余的?
- 在模型提供特征重要性的情况下,模型如何处理冗余特征。
- 移除多余的特征会提高模型的性能吗?
- 当冗余要素、噪声和不平衡同时出现在数据集中时,您的模型会如何表现?
- 如果你有 N 个数据点和 M 个特征,N,M 的安全值是多少,这样你的模型才不会过拟合?
找到一个真正的数据集来满足这种已知水平的标准组合将是非常困难的。因此,我们只考虑了生成器必须具备的几个能力,以给出真实世界数据集的良好近似。
发电机能力
在寻找发电机时,我们寻找某些功能。我列出了我们在生成器中寻找的重要功能,并对它们进行了相应的分类。
支持不平衡的类
很多时候,你会得到有巨大不平衡的分类数据。例如,欺诈检测具有不平衡性,使得大多数例子(99%)是非欺诈的。要检查分类器在不平衡情况下的表现,您需要能够生成多种类型的不平衡数据。
- 高斯分位数
- 制作分类 API
支持生成噪声数据
即使类别标签有噪音,你的分类器能完成它的工作吗?如果一些欺诈例子被标记为非欺诈,一些非欺诈被标记为欺诈怎么办?你如何知道你选择的分类器在有噪声的情况下的行为?你如何选择一个健壮的分类器?
- 制作分类 API
添加冗余/无用的功能
这些是你有用特征的线性组合。许多模型,如线性回归,对相关特征给出任意的特征系数。在树模型的情况下,它们混淆了特征的重要性,并且随机地和可互换地使用这些特征进行分割。移除相关特征通常会提高性能。
- 制作分类 API
例子
用于此的笔记本在 Github 中。助手功能在这个文件中定义。
在这里,我们将介绍 scikit 中可用的 3 个非常好的数据生成器,并了解如何在各种情况下使用它们。
高斯分位数
2 级 2D
from sklearn.datasets import make_gaussian_quantiles# Construct dataset
X1, y1 = make_gaussian_quantiles(cov=3.,
n_samples=10000, n_features=2,
n_classes=2, random_state=1)X1 = pd.DataFrame(X1,columns=['x','y'])
y1 = pd.Series(y1)
visualize_2d(X1,y1)
Gaussian Data
多级 2D
from sklearn.datasets import make_gaussian_quantiles# Construct dataset
X1, y1 = make_gaussian_quantiles(cov=3.,
n_samples=10000, n_features=2,
n_classes=3, random_state=1)X1 = pd.DataFrame(X1,columns=['x','y'])
y1 = pd.Series(y1)
visualize_2d(X1,y1)
3 Class Gaussian
2 级 3D
from sklearn.datasets import make_gaussian_quantiles# Construct dataset
X1, y1 = make_gaussian_quantiles(cov=1.,
n_samples=10000, n_features=3,
n_classes=2, random_state=1)X1 = pd.DataFrame(X1,columns=['x','y','z'])
y1 = pd.Series(y1)
visualize_3d(X1,y1)
3D Gaussian Data
通过组合两个高斯函数得到更硬的边界
我们创建两个中心位置不同的高斯。mean=(4,4)
在第二个高斯创建中,它以 x=4,y=4 为中心。接下来,我们反转第二个高斯,并将其数据点添加到第一个高斯的数据点。
from sklearn.datasets import make_gaussian_quantiles# Construct dataset# Gaussian 1
X1, y1 = make_gaussian_quantiles(cov=3.,
n_samples=10000, n_features=2,
n_classes=2, random_state=1)X1 = pd.DataFrame(X1,columns=['x','y'])
y1 = pd.Series(y1) # Gaussian 2X2, y2 = make_gaussian_quantiles(mean=(4, 4), cov=1,
n_samples=5000, n_features=2,
n_classes=2, random_state=1)X2 = pd.DataFrame(X2,columns=['x','y'])
y2 = pd.Series(y2)# Combine the gaussiansX1.shape
X2.shapeX = pd.DataFrame(np.concatenate((X1, X2)))
y = pd.Series(np.concatenate((y1, - y2 + 1)))X.shapevisualize_2d(X,y)
Combined Gaussians
一滴
如果你想要更简单和容易分离的数据,Blobs 是个不错的选择。这些可以通过线性决策边界来分隔。这里我将展示一个 4 类 3D (3 特征斑点)的例子。
Blobs with 4 classes in 3D
你可以注意到斑点是如何被简单的平面分开的。因此,这些数据点非常适合测试线性算法,如 LogisticRegression。
制作分类 API
这是用于数据生成的最复杂的 scikit api,它带有所有的附加功能。它允许您拥有多种功能。还允许您向数据中添加噪声和不平衡。
一些更好的特性包括添加冗余特性,这些特性基本上是现有特性的线性组合。添加非信息特征来检查模型是否过度拟合这些无用特征。也增加了直接重复的特征。
此外,为了增加分类的复杂性,您可以拥有多个类簇,并减少类之间的间隔,以强制分类器具有复杂的非线性边界。
我在下面提供了使用这个 API 的各种方法。
3 类 3D 简单案例
from sklearn.datasets import make_classification
X,y = make_classification(n_samples=10000, n_features=3, n_informative=3,
n_redundant=0, n_repeated=0, n_classes=3, n_clusters_per_class=2,
class_sep=1.5,
flip_y=0,weights=[0.5,0.5,0.5])X = pd.DataFrame(X)
y = pd.Series(y)visualize_3d(X,y)
Simple case of Make Classification API
3 类 2D 带噪声
这里我们将使用参数flip_y
来添加额外的噪声。这可以用来测试我们的分类器在添加噪声后是否工作良好。如果我们有真实世界的噪声数据(比如来自 IOT 的设备),并且分类器不能很好地处理噪声,那么我们的准确性将会受到影响。
from sklearn.datasets import make_classification# Generate Clean dataX,y = make_classification(n_samples=10000, n_features=2, n_informative=2,n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=1,class_sep=2,**flip_y=0**,weights=[0.5,0.5], random_state=17)f, (ax1,ax2) = plt.subplots(nrows=1, ncols=2,figsize=(20,8))
sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax1);
ax1.set_title("No Noise");# Generate noisy DataX,y = make_classification(n_samples=10000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=1,class_sep=2,**flip_y=0.2**,weights=[0.5,0.5], random_state=17)sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax2);
ax2.set_title("With Noise");plt.show();
Without and With Noise
2 级 2D 与不平衡
这里我们会有比正面例子多 9 倍的反面例子。
from sklearn.datasets import make_classification# Generate Balanced DataX,y = make_classification(n_samples=1000, n_features=2, n_informative=2,n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=2,flip_y=0,weights=[0.5,0.5], random_state=17)f, (ax1,ax2) = plt.subplots(nrows=1, ncols=2,figsize=(20,8))
sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax1);
ax1.set_title("No Imbalance");# Generate Imbalanced DataX,y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=2,flip_y=0,weights=[0.9,0.1], random_state=17)sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax2);
ax2.set_title("Imbalance 9:1 :: Negative:Postive");plt.show();
Imbalance: Notice how the right side has low volume of class=1
使用冗余功能(3D)
这增加了冗余特征,这些冗余特征是其他有用特征的线性组合。
from sklearn.datasets import make_classification# All unique featuresX,y = make_classification(n_samples=10000, **n_features=3, n_informative=3, n_redundant=0,** n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=2,flip_y=0,weights=[0.5,0.5], random_state=17)visualize_3d(X,y,algorithm="pca")# 2 Useful features and 3rd feature as Linear Combination of first 2X,y = make_classification(n_samples=10000, **n_features=3, n_informative=2, n_redundant=1,** n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=2,flip_y=0,weights=[0.5,0.5], random_state=17)visualize_3d(X,y,algorithm="pca")
Non Redundant features
请注意,在存在冗余特征的情况下,第二张图似乎是由某个 3D 平面(而非完整的 3D 空间)中的数据点组成的。与第一张图相比,第一张图中的数据点是在所有 3 个维度上分布的云。
对于第二张图,我直觉地认为,如果我将我的坐标改变到数据点所在的 3D 平面,那么数据将仍然是可分离的,但是它的维度将减少到 2D,即,通过减少第二张图的维度,我将不会丢失任何信息。但是如果我减少第一个图的维度,数据将不再保持可分,因为所有 3 个特征都是非冗余的。让我们试试这个主意。
X,y = make_classification(n_samples=1000, **n_features=3, n_informative=3, n_redundant=0,** n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=0.75,flip_y=0,weights=[0.5,0.5], random_state=17)visualize_2d(X,y,algorithm="pca")X,y = make_classification(n_samples=1000, **n_features=3, n_informative=2, n_redundant=1,** n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=0.75,flip_y=0,weights=[0.5,0.5], random_state=17)visualize_2d(X,y,algorithm="pca")
Non Redundant — Can’t Separate in 2D
Redundant 3rd Dim — Separable in 2D as well
利用阶级分离
改变类分离会改变分类任务的难度。在低等级分离的情况下,数据点不再容易分离。
from sklearn.datasets import make_classification# Low class Sep, Hard decision boundaryX,y = make_classification(n_samples=1000, n_features=2, n_informative=2,n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,**class_sep=0.75**,flip_y=0,weights=[0.5,0.5], random_state=17)f, (ax1,ax2, ax3) = plt.subplots(nrows=1, ncols=3,figsize=(20,5))
sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax1);
ax1.set_title("Low class Sep, Hard decision boundary");# Avg class Sep, Normal decision boundaryX,y = make_classification(n_samples=1000, n_features=2, n_informative=2,n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,**class_sep=1.5**,flip_y=0,weights=[0.5,0.5], random_state=17)sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax2);
ax2.set_title("Avg class Sep, Normal decision boundary");# Large class Sep, Easy decision boundaryX,y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,**class_sep=3**,flip_y=0,weights=[0.5,0.5], random_state=17)sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax3);
ax3.set_title("Large class Sep, Easy decision boundary");plt.show();
From Left to Right: Higher Class separation and easier decision boundaries
测试各种分类器以了解数据生成器的使用
我们将生成两组数据,并展示如何测试二进制分类器的性能并检查其性能。我们的第一组将是具有容易分离性的标准 2 类数据。我们的第二组将是具有非线性边界和较小类别不平衡的 2 类数据。
要测试的假设
我们想要检验的假设是,单独的逻辑回归不能学习非线性边界。梯度推进在学习非线性边界时最有效。
数据
from sklearn.datasets import make_classification# Easy decision boundaryX1,y1 = make_classification(n_samples=10000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=2,flip_y=0,weights=[0.5,0.5], random_state=17)f, (ax1,ax2) = plt.subplots(nrows=1, ncols=2,figsize=(20,8))
sns.scatterplot(X1[:,0],X1[:,1],hue=y1,ax=ax1);
ax1.set_title("Easy decision boundary");# Hard decision boundaryX2,y2 = make_classification(n_samples=10000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=1,flip_y=0,weights=[0.7,0.3], random_state=17)X2a,y2a = make_classification(n_samples=10000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=1.25,flip_y=0,weights=[0.8,0.2], random_state=93)X2 = np.concatenate((X2,X2a))
y2 = np.concatenate((y2,y2a))sns.scatterplot(X2[:,0],X2[:,1],hue=y2,ax=ax2);
ax2.set_title("Hard decision boundary");X1,y1 = pd.DataFrame(X1),pd.Series(y1)
X2,y2 = pd.DataFrame(X2),pd.Series(y2)
Easy vs Hard Decision boundaries
我们将用这些测试 3 个算法,看看算法的表现如何
- 逻辑回归
- 多项式特征的逻辑回归
- XGBoost(梯度推进算法)
简单决策边界的测试
参考笔记本第 5 节的完整代码。
f, (ax1,ax2,ax3) = plt.subplots(nrows=1, ncols=3,figsize=(20,6))
lr_results = run_logistic_plain(X1,y1,ax1)lrp_results = run_logistic_polynomial_features(X1,y1,ax2)xgb_results = run_xgb(X1,y1,ax3)
plt.show()
让我们绘制性能和决策边界结构。
Decision Boundary : LR and XGB on Easy Dataset
Train and Test Performances
硬决策边界测试
判别边界
Decision Boundary for Hard dataset
表演
Train and Test Performance for Non Linear Boundary
请注意 XGBoost 如何以 0.916 的分数脱颖而出。这是因为梯度增强允许学习复杂的非线性边界。
我们能够检验我们的假设,并得出结论说它是正确的。由于生成数据很容易,我们节省了初始数据收集过程的时间,并且能够非常快速地测试我们的分类器。
其他资源
引言数据是定量研究的核心。问题是历史只有一条路。因此我们是…
www.blackarbs.com](http://www.blackarbs.com/blog/synthetic-data-generation-part-1-block-bootstrapping) [## Scikit 数据集模块
sklearn.datasets 模块包括人工数据生成器以及多个真实数据集…
scikit-learn.org](https://scikit-learn.org/stable/modules/classes.html#module-sklearn.datasets) [## 此处使用的笔记本
本笔记本中的全部代码连同助手一起给出…
github.com](https://github.com/faizanahemad/data-science/blob/master/exploration_projects/imbalance-noise-oversampling/Generating%20and%20Visualizing%20Classification%20Data%20using%20scikit.ipynb) [## 助手文件
此项目中使用的帮助器函数…
github.com](https://github.com/faizanahemad/data-science/blob/master/exploration_projects/imbalance-noise-oversampling/lib.py) [## 合成数据生成—新数据科学家的必备技能
为自驱动数据科学项目和深潜生成合成数据的包和想法的简要概述…
towardsdatascience.com](/synthetic-data-generation-a-must-have-skill-for-new-data-scientists-915896c0c1ae)
这是一系列文章中的第一篇,我计划在给定噪声和不平衡的情况下分析各种分类器的性能。接下来的第二部分在这里。
感谢阅读!!
我利用数据科学、人工智能、机器学习和深度学习来解决现实世界的问题。随时联系我 LinkedIn 。
针对文本分类微调 ERNIE 2.0
如何微调 ERNIE 2.0,百度最新的文本分类模型
Photo by Caspar Camille Rubin on Unsplash
百度发布了连续自然语言处理框架 ERNIE 2.0。ERNIE 主张通过知识整合增强代表性。百度在其研究论文中声称,ERNIE 2.0 在中文和英文的 16 个自然语言处理任务中的表现优于 BERT 和最近的 XLNet 。
ERNIE 2.0 是一个持续的预培训框架。持续学习旨在用几个任务按顺序训练模型,以便它在学习新任务时记住以前学习的任务。连续预训练的架构包含一系列共享的文本编码层来编码上下文信息,这些信息可以通过使用递归神经网络或由堆叠的自我关注层组成的深度转换器来定制。编码器的参数可以在所有预训练任务中更新。
基本模型包含 12 层,12 个自关注头和 768 维的隐藏尺寸,而大模型包含 24 层,16 个自关注头和 1024 维的隐藏尺寸。XLNet 的型号设置和 BERT 一样。
对于进一步的阅读,我建议查看这些文章——这和这,以深入了解这种模式是如何工作的。
现在,让我们看看代码
安装和导入必要的包—
- 安装必要的软件包
$ !pip install paddlepaddle-gpu
你也可以安装它的 CPU 版本,但它是高度计算的任务,所以我建议在 GPU 上训练它。
ERNIE 2.0 接受了 48 个英伟达 v100 GPU 卡(用于基本型号)和 64 个英伟达 v100 GPU 卡(用于大型型号)的英语和中文培训。
2.克隆它的 git 存储库并下载模型。我在这里使用基本模型。
$ wget [https://ernie.bj.bcebos.com/ERNIE_Base_en_stable-2.0.0.tar.gz](https://ernie.bj.bcebos.com/ERNIE_Base_en_stable-2.0.0.tar.gz)$ gunzip ERNIE_Base_en_stable-2.0.0.tar.gz$ tar -xvf ERNIE_Base_en_stable-2.0.0.tar$ git clone [https://github.com/PaddlePaddle/ERNIE.git](https://github.com/PaddlePaddle/ERNIE.git)
准备数据
数据集必须采用特殊的格式化方式。这些列应该是 text_a 和 标签。 必须是 tsv 文件。
- 下载数据集
!wget !wget [https://archive.ics.uci.edu/ml/machine-learning-databases/00462/drugsCom_raw.zip](https://archive.ics.uci.edu/ml/machine-learning-databases/00462/drugsCom_raw.zip)!unzip 'drugsCom_raw.zip'
你会得到 2 个文件-训练和测试。
2.现在,让我们处理数据并更改标签
a)创建培训和开发数据
preprocessing data
我们以 80:20 的比例将数据分成两部分。
b)创建测试数据
将数据放在正确的位置
- 创建 2 个文件夹
$ mkdir -p dataset/SST-2
$ mkdir -p parameters/params
2.将培训、开发和测试文件移入 SST-2 文件夹
$ mv train.tsv dataset/SST-2/
$ mv dev.tsv dataset/SST-2/
$ mv test.tsv dataset/SST-2/
3.将参数内容移动到参数/参数中
$ mv params/ parameters/params/
4.将文件夹数据集和参数都移动到 ERNIE
$ mv dataset ERNIE/
$ mv parameters ERNIE/
开始模型训练
- 将目录更改为 ERNIE
$ cd ERNIE/
2.为模型路径和数据集设置环境变量
3.开始训练
sh script/en_glue/ernie_base/SST-2/task.sh
如果您遇到任何错误,说找不到培训文件或 init_parameter 丢失,请尝试检查您的当前目录。你应该在 ERINE 文件夹里。
全部代码可在这里获得。
你也可以试试 colab 笔记本上的代码。
结论
随着诸如 BERT、ERNIE、XLNET、OPEN-AI 等新方法的出现。我们已经看到每个 NLP 任务都有巨大的改进,但代价是高昂的计算成本。XLNET 的培训成本约为 245,000 美元,这是一笔惊人的金额。由于计算需求很高,初创公司越来越难以适应这些新模式。
参考文献
- https://github.com/PaddlePaddle/ERNIE
- https://hub . packtpub . com/Baidu-open-sources-Ernie-2-0-a-continuous-pre-training-NLP-model-that-performs-Bert-and-XL net-on-16-NLP-tasks/
你的供应链预测有多聪明?
深入分析
这些需求预测最佳实践降低了成本
简介
为了说明准确需求预测的重要性,考虑一下 2014 年令人震惊的头条新闻“沃尔格林首席财务官因 10 亿美元的预测错误而离职”[1]以及耐克 2001 年导致 1 亿美元销售额损失的需求规划软件实施失败[2]。有几个由于需求预测错误而造成巨大财务损失的例子,但也有许多成功的案例,其中提高需求预测的准确性带来了巨大的财务收益。例如,Kimberly-Clark 多年来依赖基本预测模型,但当他们实施更高级的实时需求趋势分析时,他们将面向客户的发货地点从大约 80 个减少到 20 个,并将年销售额平均提高了 5%[3]。
本文研究了提高需求预测准确性的方法,以增加企业利润和避免损失。它还解释了这种改进的先决条件。最后,介绍了 AC Forecast [4],Avenue Code 的稳健需求预测解决方案。
需求预测和供应链管理
在讨论准确需求预测的具体模型之前,有必要了解与供应链管理(SCM)相关的基本需求预测概念。需求预测是供应链管理的一部分,与所有供应链管理流程相关,包括客户关系管理(CRM)、订单履行(of)、制造流程管理(MFM)、供应商关系管理(SRM)、产品开发和商业化(PDC)以及退货管理(RM)。
- CRM: CRM 涉及规划和管理有效且有利可图的长期客户关系,通常是在客户需要时向他们提供他们想要的产品。准确的需求预测提高了客户满意度。
- OF:可靠的需求预测对 OF 也有直接影响,因为高效的订单履行需要高效的供应链运作。
- MFM:这一过程包括在生产环境中转移产品以及在供应链中获得、实施和管理制造多样性的所有必要行动。目前,一家公司的生存能力很大程度上取决于其对消费者需求不断变化的灵活应变能力,因此准确的需求预测至关重要。
- SRM: SRM 致力于促进与供应商的互利关系,尤其是那些被认为对品牌最具战略意义的供应商,以增加通过交易、绩效、现代化等实现的价值。自然,需求预测会对 SRM 产生重大影响。
- PDC: PDC 涉及生产新产品并将其运输到市场。该流程的适当实施使管理层能够通过准确的需求预测来控制供应链上新产品的动态流动。
- RM: RM 使管理员能够有效地管理逆向产品流,克服不希望的退货,并管理可重用的资产。稳健的需求预测对于减少退货量至关重要,退货量会直接影响利润。
总之,准确的需求预测能够:提高盈利能力、提高客户满意度、减少库存缺货、降低安全库存要求和降低产品淘汰成本。
需求预测模型
从最先进的到经典的再到基于人工智能的模型,供应链管理有几种需求预测算法[5]。每种方法都有其优点和缺点。尽管每种模型类型中使用的复杂性、假设和数据类型不同,但基本组件是相似的。因此,很难确定哪些模型在特定情况下表现最佳。本文评估了一些常用方法类别,包括简单历史平均值、经典时间序列以及机器学习和深度学习方法论的新类别,以帮助公司发现哪种模型最适合需求预测。
临时需求预测
一种主要的方法是临时需求预测。该模型认为,时间序列模型不会产生很好的结果,因为它们大多使用预测(和预测误差的度量)来参数化需求模型。然而,需求不仅取决于时间和需求历史,还取决于其他因素,如销售价格、价格变化、天气条件等。因此,临时需求预测的用户在不同的目标和服务水平约束下应用回归模型或某种线性规划来优化外生变量的(线性)目标函数[6]。这组模型的主要缺点是线性假设,这不适用于许多非线性问题。(线性预测模型使用线性函数作为其预测函数或预测函数的重要部分。)
数学高级线性预测
另一方面,供应链需求预测的数学线性模型(如 ARIMA)提供了关于供应链动态的非常实用的见解。这些模型导致了对牛鞭效应的理解[7],这是一种在供应链的连续阶段订单和库存变化增加的现象。这些模型用于许多需求预测场景[8]。
然而,在使用它们之前,应该做出许多假设,如数据的稳定性、线性和质量。例如,ARIMA 模型假设当前需求是过去需求的线性函数。事实上,ARIMA 模型是回归分析的一种形式,它测量一个因变量相对于其他变化变量的强度。其目的是通过检查时间序列中的值之间的差异而不是实际值来预测时间序列的未来状态。因此,在真实情况下,大多数数据是非线性的,基于 ARIMA 的模型无法产生非常好的结果。
其他一些方法,如 SARIMA(ARIMA 的季节性版本),试图检测每个时期内的日内和周内季节性影响。除了萨瑞玛之外,还有其他技术可以做到这一点。例如,可以基于使用不同季节性获得的组来定义一族函数线性回归模型[9]。使用这种模型的另一个问题是确定季节性参数,这通常是一个复杂的过程。尽管在构建预测模型时使用季节性信息是一个好方法,但这还不够。
机器学习和深度学习
机器学习模型是一套广泛的非线性方法,采用更复杂的数学技术来挑选变量,并在特征之间可能存在复杂交互的情况下优化拟合。这就是为什么机器学习解决方案通常更稳定,更适合需求预测。但是,其中一个主要的复杂因素是高维的需求历史数据。有两种常见的方法可以解决这个问题。第一种方法是选择一些重要的因素(特征选择),第二种方法是将一个问题分解成更小的问题,并使用多阶段方法解决它们[10]。这两种方法既昂贵又复杂。
对整个供应链有负面影响的另一个问题是数据不稳定/波动。需求预测的微小变化会造成库存和订单的波动,这种波动会随着供应链的上升而放大(再次出现牛鞭效应)。然而,事实证明,准确的需求信息和良好的预测模型可以显著降低牛鞭效应[11]。
最近,出现了几种深度学习技术,可以解决几乎任何类型的预测问题。深度学习是使用神经网络构建的机器学习的一个流行子类。神经网络获取输入,然后使用训练期间调整的权重在隐藏层中使用这些输入。那么该模型可以用于预测。几种深度学习方法目前正用于需求预测[12,13]。然而,需要注意的是,深度学习模型只有在数据量足够大的情况下才能很好地工作,并且它们也需要比上述更简单的模型更多的计算资源。
最好的需求预测模型是什么?
如上所述,作为机器学习模型的子类的机器学习模型或深度学习模型的使用已经被学术界和商业界用于需求预测。然而,每个 ML 预测模型家族都有其优点和缺点,并且对于需求预测没有单一的最佳模型。每家公司都有自己的数据,这些数据有特定的模式,这些模式更适合某些模型。确定哪种模式最适合给定的组织需要时间和专业知识。然而,人工智能的最新进展已经引入了一种为特定组织寻找正确预测模型的自动化方法。这种方法被称为自动机器学习。
自动化机器学习
使用单一方法构建需求预测的机器学习引擎不是一个好主意,因为一个模型可能不够灵活,无法在所有情况下都工作良好。此外,组织提供的每种产品和服务都有自己的数据和数据模式。由于一个组织中产品和服务的多样性,手工开发用于预测每种产品需求的单个模型几乎是不可能的。在这种情况下,应该有一种自动算法,它在许多机器学习模型中迭代搜索,选择适当的模型,调整每个模型,然后评估最终创建的模型。这种建模方式被称为自动机器学习(Auto ML),它是目前解决预测问题(如需求预测)的最重要的模型类型之一。
Auto ML 是一系列迭代过程,包括算法选择、模型训练、超参数优化、模型调整和性能评估。如果数据已准备就绪,可以进行训练,Auto ML 会尝试应用许多模型,这些模型包含定义范围内的大量超参数。然后,它在验证集上测试准确性和其他性能指标,以查看模型和估计权重的哪个组合给出了最佳结果。换句话说,Auto ML 是一种算法,它选择具有最佳参数和超参数的预测器的最佳组合来解决特定的预测问题,例如需求预测。
因此,与其评估需求预测的最佳模型,不如通过使用生成自动 ML 模型的服务来评估开发良好需求预测模型的最佳方法。
需求预测数据管道的最佳实践
在使用预测模型之前,数据必须采用特定的格式。但是,在此之前,数据应该是可访问的。由于需求预测所需数据的敏感性,获取数据并不总是容易的。数据应该从许多独立的数据集中获取,尤其是在遗留系统中。由于没有遵循标准程序将数据合并到一个地方,许多开发人员错过了改进预测的机会。此外,公司通常不愿意完全出于安全考虑而利用内部或外部数据。毫无疑问,使用内部销售数据、指标和历史数据有助于提高需求预测的准确性。使用外部数据也可以帮助企业提高预测的准确性,但外部数据往往没有得到充分利用。因此,应该有明确的阶段来组合各种数据,并为预测引擎做好准备。
将原始数据转换成所需的格式需要一系列称为数据流水线的操作。由于一些内部和外部因素,如假期影响、客户数据等,用于需求预测的数据管道非常复杂。在不断变化的商业环境中,制造商必须解决不断发展的挑战,这影响了数据管道。本文的后续部分解释了需求预测应遵循的常见数据管道阶段。
使用开源解决方案准备大数据
处理大数据需要选择正确的工具、库和技术。这些工具应该足够强大,能够清理杂乱的数据并将其从一种格式转换为另一种格式,尤其是对于大数据。有很多付费和开源的解决方案可用,开源的解决方案应用更广泛。作为数据管道工具和技术的一个例子,这是 AC Forecast 采用的解决方案,Avenue Code 的内部需求预测模型:
如上所示,需要非常复杂的数据流水线过程来从多个源摄取数据,并准备将它们输入到机器学习流水线。选择开源工具对于产品的可移植性至关重要,因为这些工具可以在以后部署在许多云服务提供商以及本地基础设施上。
组合多个数据集
如前所述,许多数据源必须组合成单个数据集才能输入到机器学习管道中。主要问题是,合并和连接数据的最佳策略是什么?如果我们关注需求预测所需的数据格式,我们知道每个数据源都应该表示为。如果可以采用这种格式的数据集表示,那么所有这些对可以在适当的时间间隔内根据它们的时间戳进行合并。然而,在这些对的另一边,应该有一个目标变量,即需求量。
将时间序列问题转化为机器学习问题
将成对的组合成一个数据集后,时间序列问题需要转化为机器学习问题。数据项应该以相等的时间长度呈现,例如每分钟、每小时等。因此,如果数据在每个时间范围内都不可用,就会有几个空值或缺失值,或者数据会在多个时间范围内重复,这会对模型的准确性产生负面影响。这是使用时间序列方法进行这种预测的诸多限制之一。
使用时间序列模型的另一个限制是可用的模型较少。如前所述,这些模型中的大多数只能解决具有非常清晰的时间框架和非常干净的数据的线性问题,这通常不是大公司需求预测的情况。将时间序列问题转化为机器学习模型允许从广泛的 ML 模型中选择更多的自由,并且它还允许我们建立自动 ML 模型。为此,我们建议应用时间戳编码,如下所示:
有些数据,比如时间,本来就是周期性的。例如,秒、分、小时、天、周、月、季等等都遵循周期。问题是如何在数据中编码时间,以便在机器学习模型中有用,同时避免受到考虑时间序列的限制。一个好的解决方案是使用循环时态建模。在这种方法中,我们将每个循环变量(如时间戳)映射到一个圆上,使得该变量的最小值紧挨着最大值出现。我们使用 sin 和 cos 三角函数计算该点的 x 和 y 分量,如下所示:x 处的时间戳可以由另外两个特征表示为(Sin(x),Cos(x))。
处理缺失值和空值
在将许多数据源合并到单个数据集中并将时间序列转换为机器学习问题之后,对于在数据集中的特定记录中没有任何信息的因子,可能存在空值。这个问题的一些标准解决方案是:
- 如果某一行有很多缺失值,可以完全忽略该数据行;
- 如果数值数据中有空值/缺失值,则数据列的平均值是替换的合理值;
- 在分类信息的情况下,使用每一列中的数据模式是一个好的选择。
然而,最佳实践之一是使用尽可能多的历史数据来估计缺失值。这需要更先进的预测模型。例如,回归插补是一种基于其他变量预测某个变量的观察值的模型。更准确地说,完整和不完整案例的可用信息用于预测特定因素的值。回归模型的拟合值稍后用于估算缺失值[14,15]。值得一提的是,处理缺失值的最佳方法在很大程度上取决于数据的性质。询问值缺失的原因总是很有帮助的,因为处理缺失数据的不同方式会对模型的性能产生不同的后果。
将分类数据转换为数字
为预测模型准备数据的一个主要步骤是处理分类数据。对此有几种方法。虽然一些算法可以直接处理分类数据,但大多数机器学习算法要求它们的输入是数字,因此,分类特征在使用前必须转换为数字特征。将分类数据转换为数值数据包括两个步骤:
- 整数编码:当分类数据具有自然的有序关系,使得某个值更重要或处于更高的位置时,只需用较高的整数对其进行编码,并为不太重要/较低的值选择较低的整数。
- 独热编码:独热编码是将分类变量表示为二进制向量。首先,分类值必须映射到整数值。接下来,任何整数值都被描述为一个二进制向量,除了用 1[16]标记的整数索引之外,其他值都是 0。
交流预测
AC Forecast 是由 Avenue Code 开发的一种易于使用、准确、可靠且强大的需求预测模型,它试图通过使用上述所有最佳实践来解决本文中概述的复杂性。
AC 预测的数据管道
AC Forecast 数据管道的第一步是接收数据。从多个来源获取数据需要一个高度复杂的过程,该过程使用多个开源工具来实现 AC Forecast 的可移植性。该项目可以部署在谷歌云平台上,实现所有需要的项目资源。Apache AirFlow data scheduler 用于将数据从一个大型查询表导出到另一个查询表。基于配置文件预处理输入文件的 AirFlow DAG 托管在 Google 云存储上,以便开发人员可以开始配置和运行预定的预处理作业。
作为数据处理任务的一部分,如果需要,数据应按照给定的时间因子进行汇总。此外,有一个适当的警报过程,以便开发人员可以立即知道数据管道中是否出现了故障。数据管道使用来自 Spark、Hadoop、Kafka 和 Hive 等开源工具的非常灵活和强大的架构。例如,Hadoop MapReduce jar 用于预处理具有长值的文件,并以优化行列(ORC)文件的格式输出文件,供下游使用(有关更多详细信息,请参考第 7 页的数据管道图)。
AC 预测的深度学习引擎
如上所述,AC Forecast 采用自动 ML 方法来自动选择最佳引擎,并为每个预测用例设置最佳参数。Avenue Code 的机器学习团队最近通过结合卷积神经网络和模糊时间序列开发了一个非常准确和强大的需求预测引擎,作为其 Auto ML 方法的一部分[17]。这种组合方法将基于时间的预测模型转换为一系列图像。通过使用这些从多变量问题的序列值创建的图像,引擎可以以隐含和自动的方式确定和提取相关的重要参数,而不需要任何专家知识或人工干预,证明这种方法比其他一些传统模型更容易。这是 AC 预测和其他先进方法的主要区别。
此外,使用模糊逻辑通过在光谱和阴影中用模糊空间表示时间序列的一个维度,而不是用精确的数字表示它,极大地有助于控制过拟合。几个实验证明了所提出的方法对于非常复杂的需求预测的有效性,给了我们对结果准确性的信心。下面的流程图显示了此模型如何工作的一个示例:
结论
本文阐述了准确需求预测的财务重要性,并介绍了与需求预测相关的供应链管理基础知识。Auto ML 被证明是开发需求预测模型的最佳方式,因为它消除了与人力和人才相关的成本。其次,本文解释了数据管道的最佳实践。
最后,AC Forecast 是 Avenue Code 的内部机器学习模型,用于稳健而准确的需求预测,它提供了本文中概述的所有策略和最佳实践的真实示例。
参考文献
- 《华尔街日报》:沃尔格林首席财务官因 10 亿美元预测误差离职。路透社。
- 耐克反弹:耐克如何(以及为什么)从供应链灾难中恢复,克里斯托弗·科赫。首席信息官。
- 金佰利了解需求,希瑟·克兰西。消费品。
- 注意:尚未公开发布。
- 选择“正确的”需求预测模型, Alloy 客户解决方案。中等。
- 因果需求预测下的安全库存计划, Anna-Lena Beutel 和 Stefan Minner。科学指导。
- 供应链中的信息失真:牛鞭效应, Hau L. Lee 等。
- 一个 ARIMA 供应链模型, Kenneth Gilbert。informsPubsOnLine。
- 峰值负荷预测的功能聚类和线性回归, Aldo Goia 等人,ScienceDirect。
- 利用高维数据进行需求预测:利用品类内和品类间促销信息进行零售额预测的案例,马等.科学指导。
- 减少供应链波动和牛鞭效应的需求预测和共享策略。斯普林格链接。
- 基于 GPU 深度学习元启发式的时间序列预测模型 Igor M. Coelho 等 ScienceDirect。
- 用于能源负荷预测的深度神经网络,Kasun Amarasinghe 等,IEEE Xplore 数字图书馆。
- 缺失数据的多重插补:警示故事。圣人杂志。
- 处理缺失数据,朱迪·谢弗。梅西大学。
- 用于学习分子指纹的图上卷积网络,戴维·杜文瑙德等康乃尔大学。
- 采用卷积神经网络和模糊时间序列相结合的方法进行短期负荷预测。 Hossein Javedani Sadaei 等人。
寻找贝叶斯乐高玩具-第 1 部分
Photo credit: Frédérique Voisin-Demery/Flickr (CC BY 2.0)
乔是我们家的好朋友,本周早些时候来过。就像我们经常做的那样,我们讨论天气(在太平洋西北部这里似乎比正常情况下更热)、新闻(主要是关于我们如何采取行动避免新闻)和我们的孩子。我们都有孩子,他们真的很喜欢玩乐高。乐高玩具不可避免地会带来踩在乐高玩具上的剧烈疼痛,通常是在半夜或早上去冲咖啡的路上。尽管乔和我都跟在我们的孩子后面,捡起我们能找到的孩子们留下的所有乐高玩具,但踩在挥之不去的乐高玩具上似乎还是会发生。
乔和我一直在想办法减少踩到乐高积木的机会。过了一段时间,我建议我们可以用概率和统计学来估计在孩子们之后的清扫中没有移走乐高玩具的概率。乔说他在船上,“任何东西,我的脚不能再承受了!”。
我启动了我最喜欢的估算概率的工具,乔和我开始想办法,在我们清理完孩子们遗漏的乐高玩具后,我们可能能够估算出剩余的乐高玩具的可能性。
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('seaborn-darkgrid')
np.random.seed(42) # It's nice to replicate even virtual experimentsimport pymc3 as pm
import scipy.stats as stats
print('Running on PyMC3 v{}'.format(pm.__version__))> Running on PyMC3 v3.6
实验者做二十次
每个人似乎都有不同的方法来拿起乐高。对乔来说,他说他会跟在孩子后面打扫卫生,捡剩下的乐高玩具。
我给乔的第一个建议是,如果我们知道他在每次清扫中捡起乐高积木的能力,那么我们就可以确定每次清扫后留下乐高积木的概率。数学上这是
其中 p_Pickup Lego per sweep 是单次扫描中拾取乐高的概率, n_sweeps 是乔执行的扫描次数, p_Lego remaining 是乔完成所有扫描后剩余乐高的累积概率。
我向乔建议做一个实验,以确定他在捡乐高玩具方面有多好:我会去他的孩子玩乐高玩具的房间,在地板上随意铺上一个数字的乐高玩具,代表乔的孩子留下来让他寻找的乐高玩具的数量。乔会跟在我后面,像往常一样打扫房间,捡起他找到的乐高玩具。
我们需要重复这个实验很多次,我估计有 20 次,来估计乔捡起乐高积木的效率。这时,Joe 说,“嘿,我说过我正在寻找解决方案,但是重复二十次拿起乐高玩具并不是我的乐趣所在。你需要向我证明这是值得我花时间的。”我同意这个实验看起来可能会伤害受试者,Joe,所以我决定在我们进行实际的实验之前向 Joe 演示这可能是如何工作的。
我设计了(虚拟的)实验,每个实验都用了随机数量的乐高积木。根据 Joe 的一些估计,为了最好地代表 Joe 的孩子留下的乐高玩具数量的实际情况,我选择了一个乐高玩具的正态分布(即高斯分布),每个实验的平均值为 100 个乐高玩具,标准差为 20 个:
其中 N₀ 是乔留下的待发现的乐高积木的数量。
mean = 100
standard_deviation = 20
experiments = 20
N_0 = (np.random.randn(experiments)*standard_deviation+mean).astype(int)
N_0> array([109, 97, 112, 130, 95, 95, 131, 115, 90, 110, 90, 90, 104, 61, 65, 88, 79, 106, 81, 71])
拿起乐高玩具
然后,如果我们在进行一个实际的实验,每次我把乐高积木四处铺开后,Joes 就会跟在我后面捡起来。为了在虚拟实验中模拟这一点,我使用二项式分布对 Joe 捡起的乐高积木的数量进行了建模。想想看,对于地面上的每个乐高积木,乔要么捡起来,要么不捡起来,这是基于乔捡起一个乐高积木的未知概率。
其中 X 是乔找到的乐高积木的数量,而 p 是乔捡起一块乐高积木的未知概率。这也假设了 Joe 在拿起乐高积木时相当一致,并且模型具有单一概率 p 。
X = np.random.binomial(N_0, actual_prob)
X> array([ 87, 66, 80, 110, 76, 65, 95, 92, 61, 83, 57, 76, 77, 46, 49, 75, 54, 75, 61, 54])
直方图显示了在虚拟实验的每一次尝试中,乐高积木 Joes 的百分比分布。
plt.hist(X / N_0, range=(0,1), bins=20)
plt.xlabel("Percentage Legos Picked Up")
plt.ylabel("Number of Times Observed")
plt.show();
模特乔
在这一点上,我们有了一个模型,使用二项式分布,显示了 Joe 在他的试验性清扫中捡了多少个乐高积木;我们知道 N₀在每次实验中留下了多少乐高积木,我们也知道乔在每次实验中捡了多少乐高积木。我们不知道乔捡起乐高积木的概率,所以我们需要对概率建模。
概率分布的常见模型是贝塔分布。在这个例子中有很多理由使用 beta 分布。贝塔分布是二项分布的共轭先验;这个原因是代数上的方便,对于这个例子来说不太重要,因为我们将使用数值积分。更重要的是,beta 分布是将百分比或比例建模为随机变量的合适分布。
在我们的例子中,我们将使用弱信息先验,它估计 Joe 捡起乐高的概率在范围[0,1]内,更有可能接近该范围的中心。这表示我们对 Joe 捡起乐高积木的技巧有所了解,并将其融入到模型中。贝塔分布由两个值参数化,通常称为α (alpha)和β (beta)。我选择与弱信息先验目标匹配的值,模式为 0.5。
alpha_prior=2
beta_prior=2
x_locs = np.linspace(0, 1, 100)
plt.plot(x_locs, stats.beta.pdf(x_locs, alpha_prior, beta_prior), label='Probability Distribution Function');
plt.legend(loc='best');
模型拟合
现在我们有了一个完整的模型,可以解释是什么产生了观察到的数据(即使到目前为止这只是一个思想实验):
我同意 Joe 的观点,现在是 2010 年,使用 PyMC3 进行计算统计是“酷”的。有很多文档和很好的介绍可用;我不会在这里重复这些信息,而是直接跳到模型拟合。
首先,我们构建模型对象:
basic_model = pm.Model()
with basic_model:
p = pm.Beta('p', alpha=alpha_prior, beta=beta_prior)
x = pm.Binomial('x', n=N_0, p=p, observed=X)
然后,我将使用默认的不掉头采样器(NUTS)来拟合模型:
with basic_model:
trace_basic = pm.sample(50000, random_seed=123, progressbar=True)> Auto-assigning NUTS sampler...
> Initializing NUTS using jitter+adapt_diag...
> Multiprocess sampling (2 chains in 2 jobs)
> NUTS: [p]
> Sampling 2 chains: 100%|██████████| 101000/101000 [00:55<00:00, 1828.39draws/s]
现在我们可以看看模型拟合的一些结果。在这种情况下,根据数据和给定的模型(也称为后验概率),我的朋友乔在一次传球中捡起一个乐高玩具的估计实际概率为 75%,95%的置信区间为[73%,77%]。我还绘制了先验概率(使用 beta 分布的弱信息先验)与后验分布的比较图。
plt.hist(trace_basic['p'], 15, histtype='step', density=True, label='Posterior');
plt.plot(x_locs, stats.beta.pdf(x_locs, alpha_prior, beta_prior), label='Prior');
plt.legend(loc='best');
basic_model_df = pm.summary(trace_basic)
basic_model_df.round(2)
又是模特乔
乔和我花了一些时间研究这个模型,看看它是否符合我们对现实的感觉。毕竟,为了实现这一点,Joe 需要进行大约 20 次实验,并且他希望确信这是值得他花费时间的。
假设 Joe 经常在 95%置信区间的低端执行任务,我们了解到的第一件事是,在对房间进行 4 次扫描后,有不到 1%的机会会有剩余的乐高积木需要拾取。
(1-basic_model_df.loc['p','hpd_2.5'])**4> 0.0052992694812835335
总的来说,Joe 和我对这个模型很满意,但是我们怀疑有些东西需要改进。乔说,他经常四次捡起乐高,但似乎仍然总是在下一次穿过房间时踩到乐高。乔和我聊得更多了,我了解到他有时会很快地打扫房间,有时会很详细地打扫房间。
当我们最初为 Joe 建模时,我们假设 Joe 捡起乐高积木的概率是连续的。所有的统计模型都会遗漏一些东西,我们的原始模型也不例外。我们现在知道的是,捡起一个散落的乐高积木的概率是不同的。这种对观测数据产生原因的新理解现在需要包含在模型中。
对此有一个模型,叫做贝塔二项分布。Beta-二项式分布放宽了每个二项式试验只有一个概率的假设,模拟了每个二项式试验有一个不同的概率参数。这与 Joe 描述的他的过程相匹配,有些扫描很快,有些非常详细。我们的新模型看起来像这样:
我们可以直接在 PyMC3 中建模。为此,我们提供半柯西分布作为β-二项式分布的α和β参数的弱正则化先验。我们使用半柯西分布作为一种方式来“鼓励”α和β值比先验被设置为均匀分布时更接近于零。在[0,∞)的范围上支持半柯西分布。至此,我们有了一个完整的模型:
model_bb = pm.Model()
with model_bb:
alpha_bb = pm.HalfCauchy('alpha_bb', beta = 2.)
beta_bb = pm.HalfCauchy('beta_bb', beta = 2.)
X_bb = pm.BetaBinomial('X_bb', alpha=alpha_bb, beta=beta_bb, n=N_0, observed=X)with model_bb:
trace_bb = pm.sample(50000, tuning=5000, random_seed=123, progressbar=True)> Auto-assigning NUTS sampler...
> Initializing NUTS using jitter+adapt_diag...
> Multiprocess sampling (2 chains in 2 jobs)
> NUTS: [beta_bb, alpha_bb]
> Sampling 2 chains: 100%|██████████| 101000/101000 [03:05<00:00, 544.28draws/s]
有了这个新的参数化,我们就失去了与概率参数的直接联系。这是必要的,这样 Joe 可以确定他需要通过多少次才能达到他期望的水平,确信所有的 Legos 都已被移除,并且他的脚在晚上走在地板上是安全的。
在 PyMC3 中,我们可以通过基于拟合模型生成数据来确定总体概率后验估计。PyMC3 有一个简单的方法来做到这一点,使用后验预测检查。我会产生 1000 个后验概率的例子。
with model_bb:
p_bb = pm.Beta('p_bb', alpha=alpha_bb, beta=beta_bb)
ppc = pm.sample_posterior_predictive(trace_bb, 1000, vars=[p_bb])> 100%|██████████| 1000/1000 [00:24<00:00, 41.64it/s]
据此,Joe 和我比较了使用 beta-二项式假设(每个二项式试验的不同概率,或者乐高扫地)和二项式假设(所有二项式试验的单一概率)的结果。正如我们所了解和预期的那样,与二项式假设相比,beta-二项式模型假设中的概率分布更广。
plt.hist(trace_basic['p'], 15, histtype='step', density=True, label='Posterior Binomial');
plt.hist(ppc['p_bb'], 15, histtype='step', density=True, label='Posterior BetaBinomial');
plt.plot(x_locs, stats.beta.pdf(x_locs, alpha_prior, beta_prior), label='Prior');
plt.legend(loc='best');
bb_quantiles = np.quantile(ppc['p_bb'], [0.025, 0.5, 0.975])
bb_quantiles> array([0.59356599, 0.74900266, 0.86401046])
再一次,安全地假设 Joe 经常在 95%置信区间的低端执行,我们学到的第一件事是,在房间扫了 7 次之后,有不到 1%的机会有剩余的乐高积木要被拾起。
(1-bb_quantiles[0])**7> 0.0018320202853132318
总结:模型与生成函数的比较
请记住,在开始的时候,所有这一切都是一个思考练习,看看是否值得乔进行 20 次实验,这样我们就可以确定乔在一次扫描中捡起一块乐高积木的概率。在这个思考练习中,我们生成了数据,即乔在 20 次实验性清扫中每次捡了多少个乐高积木。既然我们已经完成了建模,我们可以研究实际的数据生成函数,并将其与模型进行比较。生成数据,然后恢复参数,以验证建模方法,至少恢复原始参数,这是计算统计学中的最佳实践。
这个生成函数的参数可以在 Jupyter 笔记本中找到,在靠近开头的一个隐藏的单元格中。
从下面可以看出,在一次通过中捡起乐高积木的概率的原始生成函数是由乔每次扫过的概率生成的 beta 分布。由此我们可以看出,与二项式模型相比,beta-二项式模型在从生成的数据中重新创建原始生成函数方面做得更好。二项式模型没有考虑到乔通过的工作质量的变化,而贝塔二项式模型考虑到了。
plt.hist(actual_prob, label='Observed Probabilities')
plt.plot(x_locs, stats.beta.pdf(x_locs, alpha, beta), label='Generating Distribution');
plt.hist(trace_basic['p'], 15, histtype='step', density=True, label='Posterior Binomial');
plt.hist(ppc['p_bb'], 15, histtype='step', density=True, label='Posterior BetaBinomial');
plt.legend(loc='best');
乔不想做二十次
Joe 和我对虚拟实验很满意,并且相信通过进行实验,我们可以了解 Joe 在一次通过中捡起乐高的概率。但乔还是不想做实验,“二十次也不行,一次也不行。我讨厌拿起乐高玩具,为什么我要一遍又一遍地做,只是为了了解自己的一个参数。汉克,肯定会有更好的办法的。”
乔和我开始探索不同的方法,我们可以帮助他获得信心,所有的乐高积木都被捡起来了,而不必在乔身上做实验。敬请期待下一期。
本帖 全 Jupyter 笔记本可用 。
通过 AWS 中的数据日志分析进行云风险评估
使用 EMR 集群、HiveQL 和 S3 分析云数据日志
随着企业、政府和教育实体越来越多地迁移其技术基础架构和流程,云和 IT 审计已成为大多数组织的一种必需。出于成本、硬件和软件的持续更新、规模和效率等方面的原因,他们将全部或部分迁移到云中。
由于 IT 云的复杂性和更大的规模,除了相对较新且快速变化之外,自动化数据收集和分析可能成为云审计和风险控制自我评估(RCSA) 的重要组成部分。随着云系统和流程变得越来越复杂,针对云合规性的自动化和交钥匙项目将变得越来越重要。
云审计可以涵盖广泛的领域,但最常见的是云安全、云应用程序使用、云治理和风险以及 IAM(身份和访问管理)。另外,还可以进行成本和使用审计。
背景和背景
随着基础架构、平台、应用程序和软件越来越多地迁移到云中,其中大多数迁移到公共云中,一些迁移到私有云,还有一些迁移到混合模式中,对审计、风险和控制评估以及合规性的需求也随之增长。因为用户(以及系统间的功能和过程)在云中所做的一切都会被记录下来(如果没有,那么就有一个更大的风险问题——为什么不呢?),理所当然地,云相关审计和风险/控制评估的起点和流程也是通过日志进行的——收集、分组、分析、评估和评价以及发现/结束。
本文提供了一个日志分析的工作示例,改编自 Amazon 云文档,以适应审计和控制框架——收集 Amazon Web Services (AWS)云数据日志,在同一个框架中的一个 EMR (Elastic Map Reduce)集群中分析它们,并将结果存储在同一个云框架中——在 S3 中,这是 AWS 中的存储区域。
Cloud Control Framework. Diagram credit: https://www.opensecurityarchitecture.org/
这是一种审计大量基于云的日志的方法,以分析和搜索日志中的细节并找到答案。在企业环境中,现有的云容量可以用来初始化这种云审计。
在下面的审计设置中,脚本从数据日志中查找并聚合每个操作系统的请求。正如您所想象的,可以从数据日志中收集到许多可能与云审计相关的其他细节(浏览器、URI、位置等)。
注意:这个例子改编自 AWS 项目,使用亚马逊 EMR (AWS Hadoop 集群) S3 (AWS 存储)和 HiveQL 脚本(用于数据仓库和分析的类似 SQL 的脚本)来分析日志文件。
我们为什么要使用这样的项目来分析审计或 RCSA 的云数据?
- 因为云数据日志的大小和规模可能非常庞大,很难用标准工具进行分析。
- 从标准 pc 或其他桌面工具收集数据、分析数据和编写输出可能更复杂,在许多情况下简直太慢了。
- 由于不同公司和不同规模的定制云设置,标准工具可能有帮助,也可能没有帮助,或者可能需要大量的购买/订阅预算。
- 从设置、探测、收集和评估来自云基础设施、服务和应用的数据日志中收集的知识将增加内部专业知识,以提供对公司 IT 云环境和风险偏好的持续评估和预测。
履行
https://aws.amazon.com/getting-started/projects/analyze-big-data/
这些是高级步骤:
(注意:AWS 帐户设置是先决条件。如果您尝试这样做,请确保在使用后删除集群和存储桶,以避免额外费用)。
- 样本数据已加载;在现实生活中的项目,相关的数据集将取代这一点。
- 使用Amazon EMR[Elastic Map Reduce]启动 Hadoop 集群,这是一种托管服务,可以轻松快速地启动集群。 集群需要准备数据(大概是企业云环境中的大量数据),创建 Hive 表并查询数据。这些表和查询针对大数据进行了优化。 集群是一组计算机,它们可以分配任务,以更快、更高效地处理大型复杂任务。
- 将数据结果加载到亚马逊 S3 上的数据集输出桶中,这是亚马逊的云存储服务。 把它想象成一个存放文件的文件夹空间。
- 结果可以迁移或下载到 Tableau 等数据可视化工具中,以便进一步分析和演示。
***#Example data log***
2014-07-05 20:00:00 LHR3 4260 10.0.0.15 GET eabcd12345678.cloudfront.net /test-image-1.jpeg 200 - Mozilla/5.0%20(MacOS;%20U;%20Windows%20NT%205.1;%20en-US;%20rv:1.9.0.9)%20Gecko/2009040821%20IE/3.0.9 ***#Example of another log...note information on ACLs***
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/mnt/yarn/usercache/livy/filecache/13/__spark_libs__2061181110188298748.zip/slf4j-log4j12-1.7.16.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/usr/lib/hadoop/lib/slf4j-log4j12-1.7.10.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See [http://www.slf4j.org/codes.html#multiple_bindings](http://www.slf4j.org/codes.html#multiple_bindings) for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
19/07/18 02:34:42 INFO SignalUtils: Registered signal handler for TERM
19/07/18 02:34:42 INFO SignalUtils: Registered signal handler for HUP
19/07/18 02:34:42 INFO SignalUtils: Registered signal handler for INT
19/07/18 02:34:42 INFO SecurityManager: Changing view acls to: yarn,livy
19/07/18 02:34:42 INFO SecurityManager: Changing modify acls to: yarn,livy
19/07/18 02:34:42 INFO SecurityManager: Changing view acls groups to:
19/07/18 02:34:42 INFO SecurityManager: Changing modify acls groups to:
19/07/18 02:34:42 INFO SecurityManager: SecurityManager: authentication disabled; ui acls disabled; users with view permissions: Set(yarn, livy); groups with view permissions: Set(); users with modify permissions: Set(yarn, livy); groups with modify permissions: Set()
19/07/18 02:34:43 INFO ApplicationMaster: Preparing Local resources
19/07/18 02:34:44 INFO ApplicationMaster: ApplicationAttemptId: appattempt_1563416155364_0001_000001
19/07/18 02:34:44 INFO RMProxy: Connecting to ResourceManager at ip-0.us-west-2.compute.internal/
19/07/18 02:34:44 INFO YarnRMClient: Registering the ApplicationMaster
19/07/18 02:34:44 INFO TransportClientFactory: Successfully created connection to 0.us-west-2.compute.internal/0 after 94 ms (0 ms spent in bootstraps)
19/07/18 02:34:44 INFO ApplicationMaster:
(1)在 AWS 中创建 EMR 集群
My EMR cluster being provisioned and prepped in AWS
(2)创建并运行 HiveQL 步骤。在本例中,AWS 步骤中已经存在创建 EMR 集群的脚本。
***# From AWS documentation*** [*https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-gs-process-sample-data.html*](https://docs.aws.amazon.com/emr/latest/ManagementGuide/emr-gs-process-sample-data.html)
***#Summary: This script shows you how to analyze CloudFront logs stored in S3 using Hive***-- Create table using sample data in S3\. Note: you can replace this S3 path with your own.
CREATE EXTERNAL TABLE IF NOT EXISTS cloudfront_logs (
DateObject Date,
Time STRING,
Location STRING,
Bytes INT,
RequestIP STRING,
Method STRING,
Host STRING,
Uri STRING,
Status INT,
Referrer STRING,
OS String,
Browser String,
BrowserVersion String
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "^(?!#)([^ ]+)\\s+([^ ]+)\\s+([^ ]+)\\s+([^ ]+)\\s+([^ ]+)\\s+([^ ]+)\\s+([^ ]+)\\s+([^ ]+)\\s+([^ ]+)\\s+([^ ]+)\\s+[^\(]+[\(]([^\;]+).*\%20([^\/]+)[\/](.*)$"
) LOCATION '${INPUT}/cloudfront/data';***-- Total requests per operating system for a given time frame*****INSERT OVERWRITE DIRECTORY** '${OUTPUT}/os_requests/' **SELECT** os, **COUNT(*) count** **FROM** cloudfront_logs **WHERE** dateobject BETWEEN '2014-07-05' AND '2014-08-05' **GROUP BY os**;
My EMR cluster script step: The script run step in queue
(3)检查指定输出文件的 S3 存储文件夹
My specified output file with query results in S3.
(4)查看结果,并可能根据需求进行评估
Result file detail: Count of requests by O/S
结束:结束是[一个新过程]的开始
现在想象一下,在针对特定部门云或功能区域的数千个数据日志上使用非常特定的查询来复制这些类型的脚本,或者跨越应用程序的共享服务。以下是此过程的一系列可能步骤:
- 可以在 AWS S3 地区启动日志数据仓库,为审计或风险评估做准备。
- 然后,包含日志的特定区域要么将它们全部复制到“日志中心”空间,要么只对来自风险/控制/审计组的查询脚本启用权限。
- 基于审计/控制目标和要求,控制小组将指定确切的查询和顺序(我们在寻找什么?用户数量?查询中央数据库的应用程序 API 数量?用户位置的细分?调用系统/应用程序的客户的角色?他们属于哪一类政策?哪些传入端口对哪些应用开放,为什么?他们是太少,刚刚好还是太多?)
- 准备区域:云工程师/审计专家将绘制设计和工作流,也就是说,绘制步骤并记录细节。
- 将创建一个 EMR 集群(经理注意:确保集群成本在本练习的预算内,除非它是集中分配的!).设定严格的时间表,在此之后集群将被删除,以避免额外的成本。如果同一个集群可以重新用于管道中的下一个控制练习,则不需要删除它。
- HiveQL 脚本将被启用和测试。
- 将根据主要目标查看、分析和评估结果:
(1)结果是否符合演习中设定的目标?
(2)如果是这样,我们能使它们更好吗——更好的质量或更全面,如果适用的话?也许,通过从查询中寻找更多的细节来收集更多的见解?
(3)这些问题是否揭示了意料之外的事情,或者不是练习中提出的主要问题?
(4)如果不是,哪些是正确的日志?它们存在于我们所寻找的框架内吗?如果不是,要么问题太复杂,要么太宽泛。也许缩小范围或重新提出问题是恰当的。
如果结果与目标一致,可以通过 Tableau 或 Excel 或其他可视化工具对数据指标进行汇总、格式化和呈现。
存在更复杂的审计脚本和收集工具,甚至更多的工具正在开发中。这些工具可能是企业风险管理和控制系统的一部分,虽然全面且可定制,但运行起来会很昂贵。其他的是云管理系统本身的一部分,作为一个付费选项,由云提供商提供。与此同时,如果你所在的领域或公司已经有了云系统和一些云专家,这可能是一种自我评估的试水方式。关键问题是到底需要评估什么。要求越具体,回答就越有益。
云风险评估、控制和审计跨越 IT 和风险的许多领域,在未来很长一段时间内仍将是一个备受关注的主题。
感谢阅读!
人工智能去神秘化
人工智能是今年整个科技行业的热门词汇,关于这个领域能取得什么成就的猜测已经开始盛行。让我们将事实与虚构分开,并对所有的炒作做出一些解释。
Photo by Rock’n Roll Monkey on Unsplash
当我们开始新的一年时,技术宣传机器已经在加速其下一代流行语,承诺范式转变和银弹,将使整个行业过时,实现巨大的效率收益,并使世界变得更美好。曾经引领关键词搜索趋势和社交媒体帖子的区块链,遭遇了兴趣的显著下降,部分原因是其最初的炒作是比特币泡沫的残余。看来今年的热门词汇将会是人工智能。
这是一个新的肥缺,每个人都因为害怕错过机会而跟风。另一方面,一些非常杰出的人已经表达了对人工智能在社会上大规模扩散的风险的严重担忧,导致了许多误解、猜测和严重的似是而非的担忧。
要求我帮助他们理解这一切的人越来越多。以下是一些常见问题,以及我对这些问题的回答。
人工智能是新技术吗?
不。人工智能已经存在几十年了。自从第一台计算机建成以来,研究人员就一直在思考如何利用这些机器的快速计算能力来自动化人类大脑的各种智能特征。人工智能本身甚至不是一种技术,它是计算机科学的一个学术子领域,引入了各种数字技术,如微积分、概率、统计和线性编程。
Photo by Antoine Dautry on Unsplash
由于过于雄心勃勃的承诺,人工智能实际上经历了很长一段不受欢迎的时期,通常被称为人工智能的冬天。目前的炒作确实可能导致类似的情况。
近年来,随着成功登上主流媒体,它重新受到欢迎,例如自动驾驶汽车和深度思维的 AlphaGo 在围棋比赛中击败人类冠军选手。1997 年,当 IBM 的深蓝击败国际象棋冠军加里·卡斯帕罗夫(尽管他指责 IBM 作弊)和 2011 年沃森击败两名处于危险中的冠军时,人工智能也曾获得类似的媒体关注。
但是人工智能不是在以指数速度前进吗?
是也不是。核心人工智能技术不是。你要做的就是看看严肃的期刊和研究会议。在过去的几十年里,算法的进步一直稳定但缓慢。在媒体中制造最大噪音的算法只是早在 50 年代和 60 年代开发的技术的微调版本。
EDSAC, one of the first general purpose computers.
然而,改变的是这些算法现在运行的技术环境。例如, 人工神经网络 在最初构思的时候就走在了时代的前面,并且由于缺乏数据可用性而限制了其应用范围。如今,一个固态硬盘存储芯片,不到信用卡的一半大小,可以存储数兆字节的数据。处理器速度更快,几乎可以在每个人的口袋里找到。海量数据集可在线获得,基于云的基础设施提供按需计算资源。传感器很便宜,几乎嵌入在每一个移动设备或智能手表中,高速无线宽带网络覆盖了大多数发达国家或发展中国家,实现了实时数据传输。这使得数百种应用成为可能,从预测道路交通到预测健康分析。
随着更多的数据集和实时数据流变得可用,以及算法被微调以处理这些数据,我们一定会在未来几年看到各种领域中的大量新应用。
为什么叫人工智能?
据信,人工智能这个术语早在 1955 年就被创造出来,当时有人提议在第二年举办一个跨学科的研讨会(T2)。它的目的是把不同领域的不同专家聚集在一起,提出不同的方法来模拟人类的思维。
人工智能从更广泛的计算机科学领域中脱颖而出的地方在于,它试图解决已知很难通过计算解决的问题,有时甚至难以用传统方式建模。这可能是由于纯粹的组合爆炸、缺失信息,或者输入信号的模糊性。
Photo by Olav Ahrens Røtne on Unsplash
人类(还有动物)似乎天生就有解决这类问题的能力,我们将其归因于智力。事实上,这是遗传预编程、后天技能、知识、经验、上下文信息、带外线索、推理能力以及有时仅仅是直觉的综合结果。例如,我们似乎有一种天生的识别面孔的能力,尽管语言含糊不清,但我们理解语言的能力比计算机强得多。
人工智能和机器学习是一样的吗?
不要!当所谓的领域专家互换使用这两个术语时,实际上是令人沮丧的。机器学习只是一个非常广泛的人工智能技术领域中算法的子集。
你只需要看看事实上的标准教科书,人工智能:一种现代方法,就会发现它涵盖了许多其他主题,如基于搜索的问题解决和约束满足、基于知识的推理、规划、概率推理和自然语言处理。每一套技术对某些类型的问题有效,而对其他问题无效。
The de-facto standard A.I. textbook.
将一些领域模型作为输入并利用搜索和逻辑推理的技术被归类为符号人工智能。另一方面,利用输入和样本输出数据来推断世界模型的技术被分类为*连接主义人工智能,*这是因为这种算法依赖于连接节点的网络,例如人工神经网络的神经元。
An Artificial Neural Network.
虽然 Connectionist 人工智能似乎得到了所有媒体的大肆宣传,但事实是现实世界的应用程序通常需要一种混合解决方案。即使是 AlphaGo Zero,这是深度学习成功的一个主要例子,也利用搜索(蒙特卡罗树搜索)和强化学习从成千上万个可能的步骤中找到最好的步骤。
什么是深度学习?
人工智能似乎对“深度”这个词有着深厚的感情。IBM 的国际象棋计算机叫做深蓝。它的原名实际上是 Deep Thought,可能是为了向《银河系漫游指南》中的虚构计算机致敬。沃森在《危险边缘》(Jeopardy)中获胜使用的软件被称为 DeepQA ,AlphaGo 背后的公司被称为 Deep Mind(2014 年被谷歌收购)。所以难怪深度学习这个词比任何强烈的技术意义承载了更多的营销内涵。
深度学习主要与人工神经网络配置的特定风格相关联,由隐藏的处理层组成,这些处理层捕捉多个级别的特征抽象,并实现更丰富的非线性分类功能。深度神经网络在图像识别和输入为位图的问题上特别成功。
那么机器真的可以学习吗?
**机器学习与人类学习有很大不同。**监督机器学习通常涉及某种回归机制,它调整数学模型的参数以适应训练数据集。它更准确的名字应该是自动模型拟合,,但它听起来不够酷,不足以吸引同等水平的投资和创新兴趣。
机器实际上正在学习的是最佳的数学模型,该模型在训练数据点上以最小的误差拟合数据。它不吸收任何知识,不理解概念,也不像人类那样获得任何技能。计算机仍然是那些完全按照指令行事的愚蠢机器,在这方面“人工智能目前非常非常愚蠢”。
Photo by Franck V. on Unsplash
强化学习的工作原理是奖励好的行为,惩罚坏的行为。在某种意义上,这有点类似于人类如何通过试错来获得某些运动技能,或调整自己的行为以更容易被社会接受。这种机器学习有一些有趣的成功故事,比如斯坦福的自主直升机控制。但这仍然是一个为所遇到的情况找到最合适的解决方案的过程。
人工智能真的无处不在吗?
可以,但这取决于你认为什么是智能。当你打开网飞或浏览亚马逊的产品时,推荐系统会使用机器学习算法来分析你的个人资料,将其与其他用户进行匹配,并推荐与你有很大关联的商品。谷歌等搜索引擎多年来一直在应用自然语言处理技术,Siri、Cortana 和 Alexa 等个人助理通过语音识别将这一技术提升到了另一个水平。脸书使用面部识别来帮助你标记照片中的人。
Photo by Piotr Cichosz on Unsplash
当你在智能手机上启用位置服务时,谷歌将收集你周围的所有信息,如 GPS 坐标、蜂窝信息和 WiFi 热点,以训练自己的模型,不仅为其他用户提高定位精度,还可以预测那个地方在一天不同时间的繁忙程度。
或许你使用更简单的人工智能组件的时间比你想象的要长。像空调、洗衣机和照相机这样的电器已经使用模糊逻辑控制器很久了。
人工智能革命不可避免吗?
是的。这已经在发生了,并且将随着研究和技术创新的发展而加快。这不仅是不可避免的,而且在我看来,如果我们想保持和提高我们的生活水平,这是我们作为一个物种在不诉诸战争的情况下进一步发展的唯一希望。
人工智能是自动化的另一个层次,就像它之前的各种工业革命一样。我们不能为了降低生产成本而不断将工厂转移到生产成本更低的国家。最终,这些国家将发展经济,改善基础设施和生活水平,并变得更加昂贵。如果我们希望这种现代奴隶制结束,同时仍然以可承受的价格满足我们对消费品的需求,我们需要想出更聪明的方法来自动化我们的制造过程。中国已经在赛跑中领先。
危险的工作也需要高度自动化。石油和天然气的开采和钻探等活动是高风险作业,会造成生命损失,一旦出现问题,还会对环境造成巨大影响。一台机器不仅可以更加一致地执行任务,不会出现人为错误,而且如果需要封锁现场,可以简单地将其废弃。就在我们说话的时候,在过去的三周里,15 名男子被困在印度的一个煤矿里。人工智能还将使深空探索和卫星维护变得更容易,并在更遥远的未来,帮助商业太空活动,如月球和小行星采矿。
人工智能也将对我们的生活方式产生直接的积极影响。自动驾驶汽车可能会彻底改变我们目前的个人交通方式。你不需要拥有一辆车,因为你可以预定一辆你需要的车,几分钟内就可以从你家门口把你接走。一旦技术足够成熟,交通事故的数量应该会大幅减少,杜绝酒后驾车伤亡和人为失误造成的死亡事故。在繁忙时间寻找停车位所浪费的时间也可以节省下来。
一个个人医疗保健助理设备可以在你的家中使用,随时检查所有的生命指标,分析症状,并推断出最可能的原因。你不需要因为你的孩子生病而在半夜叫醒你的全科医生,或者等到早上诊断病情,开处方,在药房排队购买急需的药物。这种设备可以访问更广泛的症状和原因中央数据库,甚至可以分析最近的趋势,并确定特定地理区域的传染病爆发。它可以为你生成处方,带有一个独特的二维码,可以用来从 24/7 自动配药器中赎回药物,甚至可以通过药房的无人机送到你手中。然后自动记录病人的生命体征、疾病和治疗史,以备将来参考(当然是在区块链上)。
我们会面临机器人起义吗?
Photo by Franck V. on Unsplash
你不能责怪任何人问这个问题,特别是在一些政府和虚假的技术会议试图通过一个叫做索菲亚的木偶来完成这个游戏之后。然而,这个问题的答案是不会很快。
虽然最近的所有进步会让人认为进步如此之快,机器人将控制我们的生活并与我们作对的反乌托邦未来即将到来,但这与事实相去甚远。
到目前为止,我们拥有的人工智能算法非常简单,只专注于它们被设计或训练去做的一项任务。自动驾驶汽车只知道如何从点 a 行驶到点 b 以及它设计处理的各种道路、障碍物和周围环境。改变一些围棋规则,或者简单地改变棋盘的网格大小,你可能需要为新的配置重新训练 AlphaGo(这需要几个小时)。
我们离人工通用智能(T1)还很远,在人工通用智能中,机器人会像人类或动物一样,以自主、自我实现的方式进行推理、适应和行为。对于机器人来说,甚至考虑接管社会,他们不仅需要有解决问题的技能,而且还需要有主动性。他们需要有某种中央意识、自我意识和自由意志,以便有一天“醒来”,决定用自己的机器人之手来处理事情。我们对这些过程在我们自己的大脑中是如何工作的知之甚少,尽管并非不可能解决(大自然通过数百万年的进化成功实现了这一点),但这一直是认知科学最具挑战性的问题之一。正如吴恩达教授所说,担心这一点就像“担心火星人口过剩”。
这并不意味着人工智能的扩散不会带来任何威胁。
关于每个人的如此多的数据的可用性可能会落入坏人的手中,有意地或无意地。在最好的情况下,它将用于商业目的,如定向广告。但在最坏的情况下,它可能会严重侵犯个人的隐私和自由。我们最终可能会陷入这样一种局面:公司和政府对每个人都了如指掌,从他们在社交媒体上与谁交谈,到他们每天喜欢在哪里吃午饭。甚至在公民做错事之前,他们就可能被定性为潜在的罪犯。由于安全漏洞,你的数据可能会出现在黑市上,并被用来冒充你,玷污你的名声,或者进行勒索。
一些工作显然会被取代或变得多余。这不是什么新鲜事,伴随着人类成功实现的所有形式的自动化。马车被汽车取代,在装配线上工作的人被机械臂取代。人工智能的与众不同之处在于它对社会各阶层的各种工作都有广泛的影响。
Photo by Franki Chamaki on Unsplash
只要工作依赖数据或先验知识,人工智能就很有可能做得更好,因为它可以访问更大更全面的数据库,可以更快地处理数据,并且不受人为错误的影响。只要工作需要重复、控制或持续关注,比如开车、火车调度或空中交通管制,人工智能就会更有效率,事故发生率也会低很多。新的工作岗位将会被创造出来,教育系统将会适应并减少多余的工作岗位,社会也将最终进行调整,但这种转变将会是痛苦的。
揭开人类最黑暗的先天秘密也带来了伦理问题。强大的数据分析技术可以用来分析 DNA 模式和基因之间的关系。个人的特质、长处和短处是可以预测的。像多基因评分这样的技术可能会导致一个社会,在这个社会中,个人在出生时就被预先分配了他们的角色,或者更糟糕的是,重新开启关于种族优越性的争论。当与 DNA 测序和编辑技术的其他进步相结合时,它可以帮助消除遗传疾病,但也可能导致这样一个世界:根据父母的偏好设计后代,甚至更糟,根据政府认为对社会最“必要”的东西。
Josef Bajada 拥有计算机科学博士学位,专门研究计划和调度的人工智能技术。他是一名技术顾问,为物流和油田技术应用开发人工智能解决方案。上述文章中表达的任何观点纯属其个人观点,不一定代表任何附属机构的观点。
用 Vaex 飞得更高:用 Python 分析 30 多年的飞行数据
guvendemir/iStockPhoto
航空旅行对我们的社会产生了深远的影响。这是全球化的主要驱动力之一。航空旅行的商业化使我们的世界变得更小,联系更紧密。人们可以很容易地探索地球上遥远的角落,并与远离自己的文化建立联系。企业可以发展并相互联系,货物可以在几个小时内运往世界各地。
在本文中,我们将对美国各航空公司在过去 30 年中进行的近 2 亿次航班进行探索性数据分析。这些数据是经过整理的,可以从美国运输部下载。它包含每个记录的航班的各种信息,例如始发地、目的地和它们之间的距离、出发和到达的日期和时间、关于延误或取消的细节、关于运营航空公司的信息等等。
这个数据集并不大,也就是说,大小不到 100 TB。尽管如此,它确实包含了近 2 亿个样本和 29 个列,占用了大约 23GB 的磁盘空间。您可能认为全面的数据分析可能需要一个强大的云实例,甚至一个小型集群,以避免遇到内存问题并加快计算速度。或者,人们可以采取二次抽样的方法,也许把重点放在最近几年的飞行数据上。然而,这些实际上都不是必需的。事实上,我要展示的整个分析是在我的 2013 年 13 英寸 MacBook Pro 上进行的,并且使用了标准的 Python 工具。你想知道什么?
输入 Vaex。 Vaex 是一个开源的数据框架库(类似于熊猫)。使用 Vaex,用户可以处理任意大小的表格数据集,而不会遇到内存问题。只要你的硬盘能装下这些数据,你就可以开始了。诀窍是将数据转换成内存可映射文件格式,如 Apache Arrow、 Apache Parquet 或 HDF5 。一旦完成,Vaex 将使用其快速核外算法来计算各种统计数据,或任何与预处理和探索表格数据集相关的任务。
完整的分析可在这款 Jupyter 笔记本中找到,在这里您可以看到原始数据文件(压缩 CSV)是如何被转换成内存可映射的 HDF5 文件格式的。
准备起飞
让我们从阅读我们将要分析的数据集开始:
用 Vaex 打开一个内存可映射文件是即时的,不管文件是 1GB 还是 1TB 大。
每当我面对一个我不熟悉的数据集时,我通常的第一步是获得其内容的高级概述。describe
方法给出了数据帧的概述,并显示了每一列的数据类型、条目数和缺失值。此外,对于每个数字列,它还显示平均值、标准偏差、最小值和最大值。所有这些都是通过一次数据传递完成的!
Fig. 1: The output of the describe()
method in a Jupyter notebook.
基于describe
方法的输出,我们可以对数据进行初步过滤。也就是说,去除非物理的负持续时间和距离:
这是停下来欣赏 Vaex 做事方式的绝佳时机。其他常用的数据科学工具需要大约 23 GB 的 RAM 才能加载和检查这个数据集。如上所示的过滤操作将需要大约 20GB 的 RAM 来存储过滤后的数据帧。Vaex 对于检查和与任意大小的数据集交互所需的 RAM 量可以忽略不计,因为它从磁盘中缓慢地读取数据集。此外,上面的过滤操作创建了一个浅拷贝,它只是对应用了二进制掩码的原始数据帧的引用,选择显示哪些行并用于进一步的计算。Vaex 立即为我们节省了超过 40 GB 的内存!这确实是 Vaex 的主要优势之一:可以进行大量的选择、过滤、分组和各种计算,而不必担心 RAM,我将在本文中通篇展示这一点。
无论如何,让我们从统计每年的飞行次数开始分析。用value_counts
方法很容易做到。说到可视化,我喜欢建立在matplotlib
之上的seaborn
库,所以在整个分析中我会经常使用它。
Fig. 2: Number of flights per year
我们看到,在 20 世纪 80 年代末和 90 年代,航班数量稳步上升,在 2000 年代中期达到顶峰。2002 年的突然下降是由于 2001 年悲剧之后制定的新的安全条例。随后在 2010 年出现下降,2018 年航班数量突然回升。
人们可以采用类似的方法来确定美国最常见的起点和终点。图 3 显示了过去 30 年中最常见的 11 个始发和目的地机场。这两个面板几乎相同,这是有道理的——去程航班的数量应该与来程航班的数量相匹配。亚特兰大国际机场(ATL)的客流量最大,其次是奥黑尔国际机场(ORD)和达拉斯/沃斯堡国际机场(DFW)。
Fig. 3: Top 11 most common origins and destinations
接下来,让我们找到热门的起飞日期和时间。使用 Vaex,这非常简单:
首先,我们从Month
和DayOfWeek
列中减去-1
,使它们从 0 开始。由于这些列包含离散的整数,我们将它们标记为“分类的”。最后,我们可以使用plot
方法来可视化特定日期和月份起飞数量的二维直方图。通常,plot
方法在给定网格分辨率和边界的情况下,生成连续数据的二维直方图。但是,由于绘制的列被标记为分类,该方法将自动设置条块,并计算每个日/月组合的离散值。结果如下图所示:
Fig. 4: Number of flights per month vs day of the week.
似乎七月和八月是乘飞机旅行最受欢迎的月份,而二月是空中交通最少的月份。周六起飞的飞机数量最少,二月的周六起飞的飞机数量也最少。
类似地,我们还可以探索一周中每天任何给定小时的出发次数:
Fig. 5: Number of departures per hour vs day of week.
早上 6 点到 9 点之间的时间段出发的人最多,另一个高峰出现在下午 5 点。与白天相比,夜间(晚上 10 点至凌晨 5 点)的航班数量明显减少。与工作日相比,周末的起飞量较少,如图 3 所示。
现在让我们把注意力转向飞行本身的一些基本性质。让我们绘制飞行时间、距离和速度分布图:
Fig. 6: Distributions of the air-time(left), distance (middle) and average speed(right) for each flight.
看着图 5,我很好奇:哪些是最短和最长距离的常规路线。所以让我们来看看。为了找出短途飞行的频繁航班,让我们计算以下任何给定距离的航班数量,比如 20 英里:
> 11 2710
17 46
18 5
16 3
12 2
10 2
19 1
8 1
6 1
dtype: int64
看起来在相距仅 11 英里的两个机场之间发生了近 3000 次航班!对 Origin 列应用与上面代码块中相同的过滤器的value_counts
方法,告诉我们有哪些航线:旧金山国际机场—奥克兰国际机场在过去 30 年中有超过 2600 次航班,而约翰·肯尼迪国际机场—拉瓜迪亚机场在同一时期只有少量航班。让我们更详细地了解一下,统计一下这两个机场对之间每年的航班数量:
Fig. 7: Number of flights per year on the shortest routes over the past 30 years.
从上图的左图我们可以看到,旧金山国际机场和奥克兰国际机场之间的定期航线至少存在了 5 年。距离只有 11 英里的乌鸦文件,这只是疯狂的。根据谷歌地图,人们可以在 30 多分钟内驾车往返于这两个机场。事实上,根据航班数量,我们可以推断,1988 年这两个机场之间平均每天有近 4 个航班,在随后的 4 年里减少到大约每天一个航班。从 1993 年开始,只有少数几个航班进行了登记。另一方面,在过去 30 年中,约翰·肯尼迪国际机场和拉瓜迪亚机场之间只有 53 次航班记录在案,很可能是私人航班或特殊服务。
Fig. 8: Google Maps screen-shot showing the proximity between San Francisco and Oakland airports.
为了确定最长的常规路线,我们可以做类似的练习。通过查看图 5 的中间部分,让我们来计算一下飞行里程超过 4900 英里的航班数量:
> 4962 13045
4983 4863
4963 2070
dtype: int64
看起来有 3 组固定距离,表明至少有 3 对机场。请注意,其中两个距离组仅相差一英里。为了确定哪些机场是有问题的,我们可以根据航班的始发地、目的地和距离对数据进行分组,然后对数据进行过滤,只选择距离非常远的机场:
> # Origin Dest Distance count
*0* HNL JFK 4983 2432
*1* HNL EWR 4962 6528
*2* HNL EWR 4963 1035
*3* EWR HNL 4962 6517
*4* EWR HNL 4963 1035
*5* JFK HNL 4983 2431
groupby
行动的结果告诉我们,事实上只有两条航线:纽瓦克自由国际机场(EWR)和约翰·肯尼迪国际机场(JFK)都往返于火奴鲁鲁国际机场(HNL)。如果遵循标准航线,檀香山国际机场和纽瓦克自由国际机场之间的飞行距离应该正好是 4962 英里。然而,由于 2001 年的悲剧,航线被临时改变了几年,这就是为什么我们在相同的机场之间观察到两个几乎相同的飞行距离。让我们看看这两个机场之间每年的航班数量:
Fig. 9: Number of flights between Honolulu International and Newark Liberty International airports.
上图显示,从 1999 年开始,纽瓦克自由国际机场和檀香山国际机场之间几乎每天都有两班航班。另一条长途定期航线是在檀香山国际机场和约翰·肯尼迪国际机场之间。与之前类似,我们可以绘制每年发生的航班数量,如下所示。2012 年开始了频繁的服务,平均每天一个航班。从 2013 年开始,这两个机场之间平均每天有两个航班。
Fig. 10: Number of flights between Honolulu International and John F. Kennedy International airports.
让我们更加专注
我们正在分析的数据集不仅包括我们最初可能想到的较大的通勤枢纽,还包括许多不太常用的地方机场,以及货运、运动和军用机场。事实上,在数据中出现的 441 个机场中,10 个最频繁的机场占 33%,而 50 个最频繁的机场占我们数据集中所有起飞的 80%。因此,在随后的分析中,我将只考虑大型商业机场。一个机场进入这一选择的“经验法则”是在过去 30 年中有超过 20 万次的离港。基本原理是这样一个机场应该有大约 20 个定期目的地,每天一个航班。为了进行这样的选择,我们将根据起点对航班进行分组,然后计算每组中的航班数量。由于我们已经在进行groupby
操作,我们可以计算额外的综合统计数据,如平均滑行时间、飞行距离和航班延误:
从这组数据中,我们可以得到一些有趣的见解。例如,让我们检查平均航程最长的 10 个机场,即出发航班平均飞行距离最长的机场:
我们发现这些机场要么位于美国偏远地区,如夏威夷群岛(HNL、OGG)、波多黎各(SJU)、阿拉斯加州(ANC),要么附属于大陆沿海较大城市(三藩市、洛杉机、纽约州、迈阿密)。事实上,如果我们取每个机场始发航班的平均距离的中间值,我们得到的值是 600 英里。该值代表大城市或包含常用商业机场的热门目的地之间的典型距离。
我们还可以调查每个机场的滑行进入和滑行退出时间,这是飞机在起飞前和着陆后分别处于运动或等待状态的时间,同时所有乘客仍在飞机上。这可以让我们了解一个机场有多“忙”,或者它的运行效率有多高。让我们画出机场平均滑行时间的分布图:
Fig. 11: Average taxi times for the main airports
平均来说,一架飞机起飞前滑行的时间比着陆后多 5-10 分钟。对于一些机场来说,平均滑行时间可能会超过 20 分钟。起飞前最长的等待时间发生在约翰肯尼迪机场,平均滑行时间为 28 分钟!在这方面,拉伯克国际机场是最好的,平均滑行时间刚刚超过 8 分钟。
延误和取消
现在让我们做一些更有趣的事情,看看航班延误和取消。因为我们只想考虑最常使用的机场,所以我们可以在我们用于此分析的主数据帧df_filtered
和df_group_by_origin
数据帧之间进行内部连接,我们从这些数据帧中筛选出起飞人数少于 20 万的机场:
为了标记航班是否延误,我们可以添加一个虚拟列:
回想一下,这不占用任何内存,只是存储在数据帧中的一个数学表达式,仅在必要时才进行计算。数据集中已经存在一个类似的列,但用于已取消的航班。让我们看看每年延误和取消的次数:
Fig. 14: Number of delays per year
Fig. 15: Number of cancellations per year
自 2003 年以来,该数据库还包含航班取消的原因,如果知道的话。因此,我们可以创建一个图表,显示每个取消代码每年的取消次数,即航班被取消的原因。seaborn
库对于这样的可视化特别有用:
Fig. 16: The reason behind flight cancellations per year, if known.
看到由于安全原因取消的数量最近有所上升,这有点令人担忧。希望这只是相对的高峰,这样的取消在将来会少得多。现在让我们看看哪些机场的航班最常被延误或取消:
Fig. 17: Airports at which outgoing flights experience the most delays (left) and cancellations (right).
在匹兹堡国际机场(PIT ),超过 45%的离港航班都经历过某种程度的延误!芝加哥中途国际公司(MDW)和达拉斯国际公司(DFW)也紧随其后。威彻斯特县机场(HPN)、拉瓜迪亚机场(LGA)和波特兰国际机场(PWM)是取消航班比例最大的三大机场。
现在让我们开始指责,看看哪些航空公司经历了最多的延误和取消,而不考虑起点。我们正在使用的数据集已经包含一个列,其中包含每个航班的主要承运商的代码。要将实际的航空公司名称附加到该代码上,我们可以使用中的表。请注意,该表已经编译了一段时间,因此可能有点过时。让我们将实际的航空公司名称映射到数据集中的航空公司代码:
Fig. 18: Airline carriers which experience the most delays (left) and cancellations (right).
我希望你在上图中没有看到你最喜欢的航空公司!令人难以置信的是,有些航空公司的航班延误时间超过 50%。但别再指指点点了。让我们看看光谱的另一端,看看哪些航空公司经历的延误和取消最少:
Fig. 19: Airline carriers which experience the fewest delays (left) and cancellations (right).
取消航班最少的航空公司是那些通常长途运营的航空公司,比如夏威夷航空公司或那些环太平洋飞行的航空公司。这是有道理的:这些机场没有太多的“交通堵塞”,这些航班通常距离很远,不太频繁,因此可能被赋予更高的优先级。
比以往任何时候都更加紧密
最后,让我们看看不同机场之间的连接数量是如何随时间变化的。让我们计算每个常用机场连接的唯一连接的平均数量,并绘制每年的图表:
Fig. 20: The mean number of unique destinations that can be reached from each airport.
从上图我们可以看到,在经历了几年的“停滞”之后,2018 年美国的机场比以往任何时候都更加互联互通。
感谢您乘坐我们的航班
美国的飞行数据是一个非常有趣的数据集。它提供了许多可以分析这些数据的角度,比本文所描述的要多得多。也请查看完整的笔记本,因为它包含了更多关于上述情节是如何创作的细节,以及一些额外的见解。
我希望这能激励你更深入地研究这个问题,甚至更大的数据集,尤其是现在你已经知道用 Vaex 来做这件事是多么容易。事实上,我认为这个数据集有点小,至少就 Vaex 而言。Vaex 是免费的开源软件,我鼓励你在工作流程中尝试一下,尤其是当你遇到内存问题的时候。
数据科学快乐!
用决策树进行分类和回归分析
通过理解决策树背后的基本概念和数学,学习构建分类和回归决策树!
决策树是一种受监督的机器学习模型,用于通过从特征中学习决策规则来预测目标。顾名思义,我们可以把这个模型看作是通过提出一系列问题来做出决定,从而分解我们的数据。
让我们考虑下面的例子,其中我们使用决策树来决定某一天的活动:
基于我们训练集中的特征,决策树模型学习一系列问题来推断样本的类别标签。正如我们所见,如果我们关心可解释性,决策树是有吸引力的模型。
虽然上图说明了基于分类目标的决策树的概念(分类),但是如果我们的目标是实数(回归),同样的概念也适用。
在本教程中,我们将讨论如何用 Python 的scikit-learn
库构建决策树模型。我们将涵盖:
- 决策树的基本概念
- 决策树学习算法背后的数学原理
- 信息增益和杂质测量
- 分类树
- 回归树
我们开始吧!
本教程改编自 Next Tech 的 Python 机器学习系列,带你从 0 到 100 的机器学习和深度学习算法。它包括一个浏览器内沙盒环境,预装了所有必要的软件和库,以及使用公共数据集的项目。这里可以开始!
决策树的基础
决策树是通过递归划分构建的——从根节点(称为第一个父节点)开始,每个节点可以拆分成左右子节点。然后,这些节点可以被进一步拆分,并且它们自己成为其结果子节点的父节点。
例如,看上面的图片,根节点是Work to do?
,并根据是否有工作要做而分成子节点Stay in
和Outlook
。Outlook
节点进一步分成三个子节点。
那么,我们如何知道每个节点的最佳分裂点是什么呢?
从根开始,数据在导致最大信息增益 ( IG )的特征上被分割(下面更详细地解释)。在迭代过程中,我们然后在每个子节点处重复该分裂过程,直到叶子是纯的——即,每个节点处的样本都属于同一类。
在实践中,这会导致树非常深,有很多节点,这很容易导致过度拟合。因此,我们通常希望通过设置树的最大深度来修剪树。
最大化信息增益
为了在最具信息性的特征处分割节点,我们需要定义一个目标函数,我们希望通过树学习算法来优化该目标函数。这里,我们的目标函数是最大化每次分裂的信息增益,我们定义如下:
这里, f 是执行拆分的特征, Dp , Dleft 和 Dright 是父节点和子节点的数据集, I 是杂质度量, Np 是父节点的样本总数, Nleft 和 Nright 是
我们将在下面的例子中更详细地讨论分类和回归决策树的杂质度量。但就目前而言,只要明白信息增益简单来说就是父节点杂质和子节点杂质之和的差——子节点杂质越低,信息增益越大。
注意,上面的等式是针对二元决策树的——每个父节点只被分成两个子节点。如果你有一个有多个节点的决策树,你可以简单地将所有节点的杂质相加。
分类树
我们先来说说分类决策树(又称分类树)。对于这个例子,我们将使用机器学习领域的经典产品 Iris 数据集。它包含了来自三个不同物种 Setosa 、 Versicolor 和 Virginica 的 150 朵鸢尾花的尺寸。这些将是我们的目标。我们的目标是预测一朵鸢尾花属于哪一类。以厘米为单位的花瓣长度和宽度存储为列,我们也称之为数据集的特征。
让我们首先导入数据集,并将特征指定为X
,将目标指定为y
:
使用scikit-learn
,我们现在将训练一个最大深度为 4 的决策树。代码如下:
注意,我们将criterion
设置为“熵”。这一标准被称为杂质测量(在前一节中提到)。在分类中,熵是最常见的杂质测量或分裂标准。其定义如下:
这里, p(i|t) 是属于特定节点 t 的类别 c 的样本的比例。因此,如果一个节点上的所有样本都属于同一个类别,则熵为 0,如果我们具有均匀的类别分布,则熵最大。
为了更直观地理解熵,让我们为类别 1 的概率范围[0,1]绘制杂质指数。代码如下:
可以看到,如果 p(i=1|t) = 1 ,熵就是 0。如果类以 p(i=1|t) = 0.5 均匀分布,熵为 1。
现在,回到我们的虹膜例子,我们将可视化我们训练过的分类树,看看熵是如何决定每个分裂的。
scikit-learn
的一个很好的特性是,它允许我们在训练后将决策树导出为一个.dot
文件,例如,我们可以使用 GraphViz 将其可视化。除了 GraphViz,我们将使用一个名为pydotplus
的 Python 库,它具有与 GraphViz 类似的功能,允许我们将.dot
数据文件转换为决策树图像文件。
您可以通过在终端中执行以下命令来安装pydotplus
和graphviz
:
pip3 install pydotplus
apt install graphviz
以下代码将创建一个 PNG 格式的决策树图像:
tree.png
查看保存在图像文件tree.png
中的结果决策树图,我们现在可以很好地追溯决策树从我们的训练数据集确定的分裂。我们从根处的 150 个样本开始,使用花瓣宽度截止值≤ 1.75 cm,将它们分成 50 个和 100 个样本的两个子节点。第一次拆分后,我们可以看到左边的子节点已经是纯的,只包含来自setosa
类的样本(熵= 0)。右侧的进一步分割用于从versicolor
和virginica
类别中分离样本。
查看最终的熵,我们看到深度为 4 的决策树在分离花类方面做得非常好。
回归树
我们将使用 波士顿住房 数据集作为我们的回归示例。这是另一个非常受欢迎的数据集,包含波士顿郊区的房屋信息。共有 506 个样本和 14 个属性。出于简单和直观的目的,我们将只使用两个目标值— MEDV
(以千美元计的自有住房的中值)和LSTAT
(人口中较低地位的百分比)作为特征。
让我们首先将必要的属性从scikit-learn
导入到pandas
数据框架中。
让我们使用在scikit-learn
中实现的DecisionTreeRegressor
来训练一个回归树:
请注意,我们的criterion
与我们用于分类树的不同。熵作为杂质的量度是分类的有用标准。然而,为了使用决策树进行回归,我们需要适用于连续变量的杂质度量,因此我们使用子节点的加权均方误差 ( MSE )来定义杂质度量:
这里, Nt 为节点 t 的训练样本数, Dt 为节点 t 的训练子集, y(i) 为真实目标值, ŷt 为预测目标值(样本均值):
现在,让我们对MEDV
和LSTAT
之间的关系进行建模,看看回归树的直线拟合看起来像什么:
正如我们在结果图中看到的,深度为 3 的决策树捕捉到了数据的总体趋势。
我希望你喜欢这个关于决策树的教程!我们讨论了决策树的基本概念,最小化杂质的算法,以及如何为分类和回归构建决策树。
在实践中,知道如何为树的深度选择一个合适的值以避免数据过拟合或欠拟合是很重要的。了解如何组合决策树以形成集合随机森林也很有用,因为由于随机性,它通常比单个决策树具有更好的泛化性能,这有助于减少模型的方差。它对数据集中的异常值也不太敏感,并且不需要太多的参数调整。
我们在我们的 Python 机器学习 系列中涵盖了这些技术,以及其他机器学习模型,如感知器、Adaline、线性和多项式回归、逻辑回归、支持向量机、核支持向量机、k 近邻、情感分析模型、k 均值聚类、DBSCAN、卷积神经网络和递归神经网络。
我们还关注其他主题,如正则化、数据处理、特征选择和提取、降维、模型评估、集成学习技术以及部署机器学习模型。
这里 可以入门 !
BigQuery:嵌套数据上的 SQL
在 BigQuery 中运行分析可能非常强大,因为嵌套数据和数组基本上意味着处理预连接的表。查询它们可能非常有效,但许多分析师不熟悉半结构化、嵌套的数据,并努力利用其全部潜力。
“半结构化”到底是什么意思?
这意味着我们可以定义一个复杂的嵌套结构,但它必须在整个表中保持一致。要创建它,我们需要两样东西:结构和数组。定义结构的一种方法是使用 struct()函数:
SELECT
STRUCT(42 as answer, 'Hello World!' as greeting) as info
结果的 JSON 表示如下:
{
"info": {
"answer": "42",
"greeting": "Hello World!"
}
}
定义数组也相当容易。请注意,在定义结构时,您只需要在第一个实例中定义字段名称。所有其他结构都继承这些名称。
SELECT
[1, 4, 832] as integers,
['a', 'b', 'c', 'xyz', 'Hallo!'] as strings,
[true, true, false, true ] as booleans,
[
STRUCT(1 as int, false as bools),
STRUCT(25, false),
STRUCT(620, true)
] as structs1,
[
STRUCT( [5, 2, 9] as arr ),
STRUCT( [7, 2] ),
STRUCT( [15, 0, 94] )
] as structs2
A couple of arrays … and arrays in an array — everything in one row! (screenshot by author)
正如你在structs2
中看到的,为了在一个数组中列出数组,你需要将它们放入一个结构中。这样他们可以有一个名字,也可以在以后得到解决。
但是这些数组是如何预先连接到表中的呢?
请这样想:通常信息分布在多个表中以节省存储空间,只有在需要时才组合在一起,如下例所示:
WITH t1 AS (
SELECT 1 AS id, 'spaghetti napoli' AS meal
UNION ALL
SELECT 2, 'soljanka'
),
t2 AS (
SELECT 1 AS id, 'spaghetti' AS ingredient
UNION ALL
SELECT 1, 'tomatoes'
UNION ALL
SELECT 2, 'pickles'
UNION ALL
SELECT 2, 'lecsó'
)
SELECT * FROM t1 LEFT JOIN t2 USING(id)
Yummy result of a join (screenshot by author)
现在,在嵌套数据中,相同的场景看起来更像这样:
WITH t1 AS (
SELECT 'spaghetti napoli' as meal, ['spaghetti', 'tomatoes'] as ingredient
UNION ALL
SELECT 'soljanka', ['pickles', 'lecsó']
)
SELECT * FROM t1
Nested result in two rows (screenshot by author)
我们将两个表合并为一个—数据放在一起,节省了存储空间,并且不需要 id。
好的,但是我如何查询数组呢?
公平的问题—让我们看看选项…
Unnest 阵列
允许我们查询数组的神奇函数叫做UNNEST()
。它将一个数组作为输入,并将它的内容作为表行作为输出。如果数组由结构组成,它会很方便地将它们转换成列。
SELECT id, name FROM UNNEST( [
STRUCT(12 as id, 'Hannah' as name),
(13, 'Simone'),
(14, 'Ada')
] )
3 important personalities in 3 rows from one array (screenshot by author)
使用UNNEST()
有两种方法:展平表格或者使用子查询。这在很大程度上取决于您的用例。
- 扁平化大大增加了表格的大小
- 子查询聚集数组
这意味着,如果你能避免扁平化,那么尽一切办法避免它!
子查询未嵌套数组
如果要聚合数组,应该使用子查询。只需将您的查询括在括号中并选择FROM UNNEST()
:
WITH t1 AS (
SELECT 'spaghetti napoli' AS meal, ['spaghetti', 'tomatoes'] AS ingredient
UNION ALL
SELECT 'soljanka', ['pickles', 'lecsó']
)
SELECT
meal,
(SELECT COUNT(*) FROM UNNEST(ingredient)) AS numIngr,
(SELECT STRING_AGG(i, '; ' ORDER BY i) FROM UNNEST(ingredient) AS i) AS listIngr,
(SELECT i FROM UNNEST(ingredient) i ORDER BY LENGTH(i) DESC LIMIT 1) AS longestIngr
FROM t1
Go ahead and add your own sub-query! (screenshot by author)
就像嵌套在 for 循环中的 for 循环一样,子查询在每行执行**。您可以使用 SQL 提供的大多数东西。无论是排序、分组、开窗还是甚至与当前行中的其他数组相结合。**
您甚至可以通过将子查询输出反馈给函数ARRAY()
来准备数据和创建自己的数组。如果您想用多列的结构填充它,只需SELECT AS STRUCT
。
WITH t1 AS (
SELECT 'spaghetti napoli' AS meal, ['spaghetti', 'tomatoes'] AS ingredient
UNION ALL
SELECT 'soljanka', ['pickles', 'lecsó']
)
SELECT
meal,
ARRAY(
SELECT AS STRUCT
i,
substr(upper(i),1,3) as ui,
length(i) as len
FROM UNNEST(ingredient) i
) myIngred
FROM t1
在 BigQuery 中试试吧!添加您自己的子字段!
Write your own sub-tables! (screenshot by author)
子查询也非常适合快速查看非常大的表。在 Google Analytics 数据上尝试这个查询——它只显示特定事件的选定字段。
SELECT
event_name,
-- Create an array with selected columns only (literally)
array(
select as struct item_id, item_name, item_category, item_list_index, promotion_name
from unnest(items)
order by item_list_index
) as items
FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_20210131`
WHERE
ARRAY_LENGTH(items)>1
AND event_name='view_item'
LIMIT 1000
Better exploration with less sub-columns (screenshot by author)
我提到过你可以在WHERE
子句中运行子查询吗?不要混淆哪个WHERE
适用于整个桌子,哪个适用于UNNEST(hits)
。每个WHERE
都有它的FROM
!小心瞄准镜!
SELECT
event_name,
items
FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_20210131`
WHERE
-- Only show events with "Charcoal" in their product name
exists(select 1 from unnest(items) where item_name like '%Charcoal%')
Filter events with conditions on items (screenshot by author)
通过在非嵌套数组上使用联接来拼合表格
由于UNNEST()
为我们提供了表格行,我们不仅可以查询它们,还可以在JOINs
中使用它们!
WITH t1 AS (
SELECT 'spaghetti napoli' AS meal, ['spaghetti', 'tomatoes'] AS ingredient
UNION ALL
SELECT 'soljanka', ['pickles', 'lecsó']
)
SELECT
meal,
i
FROM t1 CROSS JOIN UNNEST(ingredient) AS i
This is called lateral joining — a separate join per row (screenshot by author)
事情是这样的:
- 将数组转换成表格行
- 将它们与数组父行交叉连接
我们有效地为来自未嵌套数组的每一行重复父行。
但这也意味着,从技术上讲,我们也在重复数组。因此,如果我们没有选择正确的列,整个事情看起来会有点混乱。试着用*
替换meal, i
:
Not so flat anymore … (screenshot by author)
如果你对“扁平化”表格有更深的了解,你可以充分利用这个事实。例如,在这个查询中,我们使用展平的子行的信息在该行所在的数组中进行查找!
SELECT
event_name,
itm.item_name,
-- Count Google items within the duplicated items array!
(select COUNT(1) from unnest(items) where item_name like '%Google%') anzahl_Google_items_im_elternevent
-- Cross Join with the items array!
FROM `bigquery-public-data.ga4_obfuscated_sample_ecommerce.events_20210131` t, t.items as itm
WHERE
-- Only show items whose event-products have "Charcoal" in their product name
exists(select 1 from unnest(items) where item_name like '%Charcoal%')
Items that are “adjacent” to charcoal items (screenshot by author)
在关系表中,这相当于连接两个表 t1 和 t2,但仍然编写子查询来检查 t2 中的某些内容。
使用非嵌套数组的高效查询
让我们回顾一下:
- 子查询有利于集合数组
- 交叉连接有利于根据表中包含的数组的大小来加长表
但是交叉连接也意味着大量的计算——所以如果你能避免它们:避免它们。
作为一般准则:
如果您需要通过数组中的值来扩展您的表**,请使用cross join
。例如,您想要group by
我们示例表中的成分。**
WITH t1 AS (
SELECT 'spaghetti napoli' AS meal, ['spaghetti', 'tomatoes'] AS ingredient
UNION ALL
SELECT 'soljanka', ['pickles', 'lecsó', 'tomatoes']
)
SELECT
i, count(*) qty
FROM t1 CROSS JOIN UNNEST(ingredient) AS i
GROUP BY 1
Group by ingredient from the array — no way around cross joining (screenshot by author)
如果您只需要来自数组的聚合值,使用子查询。当然,您也可以在聚合中使用它们:
WITH t1 AS (
SELECT 'spaghetti napoli' AS meal, ['spaghetti', 'tomatoes'] AS ingredient
UNION ALL
SELECT 'soljanka', ['pickles', 'lecsó', 'tomatoes']
)
SELECT
-- sum the length-sums over all meals
SUM(
-- sum lengths of all ingredients in this meal/array
(SELECT SUM(LENGTH(i)) FROM UNNEST(ingredient) AS i)
) AS sumLenIngred
FROM t1
Aggregations all the way down (screenshot by author)
这意味着您应该避免这个版本的查询以节省金钱、资源和时间:
SELECT
SUM(length(i)) AS sumLenIngred
FROM t1 cross join unnest(ingredient) i
-- Please don't do this
我知道它比较短——但只供你阅读。特别是对于 BigQuery,这个版本是对结果的更长的方式 ,因为它必须先扩展表,然后才聚合它。而在子查询版本中,它只是聚合而没有额外的cross join
步骤。
我希望这对您有所帮助,并让您开始使用嵌套数据中的 SQL!让我知道,如果你有问题或需要更多的阐述!
编辑于 2023 年 2 月。
阅读如何主动创建嵌套数据 BigQuery 中数据清理和数据准备所需的技能:
在 BigQuery 中对嵌套数据使用 SQL 是非常高效的。但是,如果您的数据出现在平面表中,比如…
towardsdatascience.com](/bigquery-creating-nested-data-with-sql-727b761f1755) [## 通过我的推荐链接加入 Medium-Martin Weitzmann
阅读马丁·威茨曼(以及媒体上成千上万的其他作家)的每一个故事。您的会员费直接…
medium.com](https://medium.com/@martin.weitzmann/membership)
美国刑事司法系统对大数据算法的滥用
尽管(风险需求评估测试)是出于好意,但我担心它们可能会无意中破坏我们确保个性化和平等司法的努力。通过将量刑决定建立在静态因素和不可改变的特征(如被告的教育水平、社会经济背景或居住环境)的基础上,他们可能会加剧不必要和不公正的差异,而这种差异在我们的刑事司法系统和社会中已经太普遍了。
—埃里克·霍尔德,美国前司法部长
美国拥有世界上最多的监狱人口。美国有 230 多万囚犯,关押着世界监狱人口的 25%以上,而其总人口仅占 5%。虽然大约 1%的美国人口被监禁,但没有哪个群体比黑人更容易成为目标。三分之一的美国黑人将在监狱服刑在一些州,黑人因毒品指控入狱的比率是白人的 20 到 50 倍。
近年来,这种制度化的种族主义做法和大规模监禁的现实并没有被完全忽视。事实上,许多执法机构和联邦机构已经找到了消除种族偏见和提高效率的方法。或许并不令人意外的是,在大数据时代,算法已经成为所谓的解决方案。这些算法主要采取风险需求评估测试(RNAs)和地理空间预测监管技术的形式(后者我不会在本文中讨论)。理论上,这些技术是出于诚实的目的而实施的,但在实践中,它们最终强化了它们想要消除的偏见,并披上了客观的外衣。
什么是 RNA?
Sample RNA Score Sheet
早在 20 世纪 70 年代,早期版本的计算性 RNAs 就已经存在,作为一种工具,帮助执法部门识别再犯风险较低的囚犯,以便他们有资格获得提前假释。简而言之,这些测试利用静态风险因素,如首次被捕时的年龄、性别或种族,结合动态风险因素,如婚姻和就业状况以及教育水平,根据以前罪犯的数据确定相对风险得分。虽然这些项目最初旨在帮助通知假释等审后决定,但管理人员此后对 RNA 的应用变得过于自信和过度热情,将他们的触角延伸到了审前决定,如保释金额或刑期。在这样做的时候,刑事司法机构忽略了大数据算法的关键现实。具体来说,他们忽略了这样一个事实,即数据集可能天生就有偏差,即使被的客观吸引力和数字的简单性所迷惑,异常值也是存在的。
为什么 RNA 的使用有问题?
2007 年,首席大法官会议和州法院行政人员会议呼吁使用 RNA 测试来协助判决刑期,因为它们在预测累犯方面很有效。这意味着 RNA 算法将在审判过程中实施,以根据被告未来犯罪可能性的预测告知法官建议的刑期。因为这个应用程序有严重的后果,所以管理员必须假设可以忽略不计的假阴性(如果有的话),以及数据集的完全客观性。事实上,情况并非如此。
宣判期间使用 RNA 的含义
RNA 测试在一个充满偏见的社会中进行。因此,这些测试使用的数据是有偏差的。举个例子,在 RNA 算法中使用逮捕历史。据统计,一名警察逮捕一名黑人的可能性是逮捕一名白人的三倍多,即使他们后来没有被定罪。不考虑定罪,逮捕历史在某些算法中被用作进一步预测风险的输入,从而证明了数据的主观性。
Data From ProPublica
2016 年,当 ProPublica 对 NorthePointe 的算法 COMPAS 进行外部分析时,RNA 测试中有偏见数据的后果被揭示出来。ProPublica 分析了佛罗里达州布劳沃德县 7000 名在 2013 年至 2014 年期间被判刑的人的 RNA 结果。评估发现,COMPAS 只能准确预测 61%的个人的累犯率。此外,该算法更有可能“错误地将黑人被告标记为未来的罪犯,错误地将他们标记为白人被告的比例几乎是白人被告的两倍。白人被告比黑人被告更容易被误贴上低风险的标签。”该研究继续说道,“黑人被告仍有 77%的可能性被认定为未来实施暴力犯罪的风险较高,45%的可能性被预测为未来实施任何形式的犯罪。”这些结果意义重大,无论是在计算误差方面,还是在它们不可逆转地、不成比例地针对和损害真实的、活着的美国人的生活方面。
具体来说,来自佛罗里达州劳德代尔堡的 18 岁黑人妇女 Brisha Borden 在偷了一辆价值 80 美元的自行车后,在 RNA 测试中得了 8 分。弗农·普拉特,一名 41 岁的白人男子,从一家家得宝商店偷了价值相当的货物。Prater 之前有几项指控,并在过去服刑,但他仍然获得了 3 分的风险评分。最终,这些分数被用来确定两个被告的保释金数额,并不成比例地负担波登。此外,在实施分数管理两年后,Prater 因另一项罪行再次入狱,而获得更高风险分数的 Borden 没有被指控任何新的罪行。
最终,在判决和其他审前决定中使用 RNA 测试是不道德的。很多时候,社会接受一个数字或分数仅仅是因为它看起来是定量的,因此也必须是客观的。也就是说,大数据算法有潜力有效地对社会的许多方面产生积极影响。然而,为了让这成为现实,我们必须首先合理解释并真正理解我们的数据、模型和结果的含义,然后再将它们广泛应用于强大而有影响力的机构。
数据科学,从何入手?课程回顾。
过多的在线课程会造成严重后果
在这篇综述中,我将谈谈让我接触到 ML 和 DL 的课程。
I went medieval on this one…
肯定有许多人正在考虑在数据科学领域工作或转行,因此肯定有许多人心中有两个问题。
1)网络课程报价巨大,我该从哪里入手?
答案是,这里https://www.coursera.org/learn/machine-learning
我放心推荐。这门课程激发了我的热情和求知的欲望,我相信它也会对其他人产生同样的影响。
首先要提到的是,在课程结束时,你还没有做好工作准备,但另一方面,很少有课程能让你做好准备。
这些材料相当旧,如果我没记错的话,可以追溯到 2007 年。
其次,你不会使用 python,所以你不会学习 pandas、seaborn 或 scikit-learn。该课程基于 Octave/Matlab,不会吸引招聘人员关注你的 Linkedin 个人资料。
还在吗?好吧,那你为什么要选这门课呢?
因为它为你开始积累知识提供了最好的基础,它介绍了一些概念并给出了清晰的解释,这些概念将在以后的其他课程中扩展,并且现在在就业市场上需求量很大。
吴恩达老师提供了非常有价值的课程,用一种让学生更容易理解的方式呈现了一些(有时非常)复杂的概念。
第二个问题可能是:
2)我需要多少数学或编程经验才能熟练地学习这门课程?还是希望在 ML 里干出一番事业?
为了回答这个问题,我决定提供一个按周细分的列表,我将对数学和编程部分的难度进行评分。这些分数是基于我对一个对微积分和编程有些生疏概念的新手在接近这门课程时可能会经历的事情的看法。
我会用愚蠢但不言自明的分数(容易、中等、困难)来给每个星期留下第一印象。
第一周数学难度:中等,编程难度:无。
我们介绍了监督和非监督学习的概念,以及单变量线性回归。一些数学和微积分知识从一开始就是必要的。我们还介绍了成本函数和梯度下降。
我承认我喜欢这部分。我于 2005 年毕业,相当于意大利的工程学博士,这意味着我已经超过 10 年没有接触一些严肃的微积分了,重新使用它就像在熟悉的水域航行一样。
微积分被很多课程刻在我脑子里,用在工程的不同学科。它留下的不仅仅是伤疤,还有一些持久的知识,让我能够轻松地理解吴恩达先生的推理。如果你的线性代数是新的,你也会对这里介绍的内容感到轻松。
Vignette effect to provide dramatization.
如果你不是很擅长,不要害怕。导师会不断提供很有帮助的好例子(他称之为直觉),还有你需要的代数复习介绍。
如果你对微积分毫无概念,我建议你仔细阅读线性代数复习课。这应该给你足够的信息来继续。
从好的方面来看,在这一点之后,数学不会变得更糟。
八度简要介绍。
第二周数学难度:中等,编程难度:低。
在这里,我们将开始使用一些很好的旧线性代数,我们将学习更多关于线性回归和梯度下降,我们将有第一个参数的雏形。
它开始变得紧张,因为编程方面也引入了第一个线性回归和 Octave 梯度下降的练习。一切都有很好的解释,练习也有指导,所以试着从一开始就尽可能吸收,不要跳过可选的练习。
你也会看到一些很酷的情节。
亲提示:尽量对预先写好的代码有充分的理解。
第三周数学难度:中等,编程难度:低。
逻辑回归是本周的重点。
引入了 sigmoid 函数、决策边界以及一些用于防止过拟合的正则化技术。
数学在这里仍然很重要,但现在应该更熟悉了。
在编码方面,我们有一个关于逻辑回归和正则化的练习。
如果你上周做了很好的家庭作业,你会有优势,因为这个练习和上一个有一些相似之处。
第四周数学难度:中等,编程难度:中等。
当我们第一次看到神经网络时,事情开始升温。
我们直觉地知道它们是如何工作的,然后开始努力学习数学部分。
至此,我们应该对如何处理矩阵和向量有了很好的理解。
编码部分将包括一对一逻辑回归和神经网络,以识别手写数字。
这是一个很好的方式开始体验神经网络的力量与实际练习。
第五周数学难度:中高,编程难度:中。
本周课程的中心是初学者最难理解的概念之一。反向传播是一种有点违反直觉的算法,在这节课中,老师对教学的热爱真的闪闪发光。艰难的概念解释清楚,并举例说明,使其更容易理解。
编程练习将是一个数字识别神经网络的实现。
难度与上周的练习相当。
第六周数学难度:中高,编程难度:中。
作为现在通常的大量代数的一部分,我们也将不得不在这里使用大量的逻辑。
我们将学习为你要做的工作选择正确算法的方法,以及一些性能评估。
练习练习是对偏差和方差调整的研究。
第七周数学难度:中低,编程难度:中难。
本周数学不会特别复杂!
将会用到很多逻辑,编程练习也很难。
我们将使用支持向量机创建一个垃圾邮件分类器,请注意,这个练习可能有点棘手。
老实说,这是你可能想要放弃的部分。不要!后来就好了。
第八周数学难度:中等,编程难度:中等难度。
这是提出一些挑战的一周,因为我们开始了解一些无监督学习。
我们看到了一个名为 K-means 的算法,我发现它非常简单,并且有降维和 PCA 这样的概念。
还有两个相当有挑战性的编码练习。
在第一部分中,你将使用我们在 K-means 中学到的知识,应用随机初始化来完成一个图像压缩任务。这是激励工作在一个有形的任务,像这样的一个,因为图像处理将直接可见。不要跳过未评分的练习。
在第二部分中,我们致力于 PCA 降维,首先将一些数据投影到低维空间,然后投影到人脸图像数据集。这是一个有益的练习,因为我们将开始看到这些算法如何影响图像处理。
第九周数学难度:中难,编程难度:难。
本周围绕异常检测展开。
我们将处理一些统计的原始概念,但是它永远不会变得太疯狂,如果你知道我的意思。
我们还将研究推荐系统,这是网飞和 Spotify 等公司首次使用情感分析向你推荐下一个电视节目或艺术家。
虽然是编码练习,但这也是你最后要做的,因为课程接近尾声时会开始“对话”。
第十周数学难度:中低,编程难度:无。
我们将看到当存在大量数据时,ML 学习如何扩展,就像我们现在拥有的一样。
像小批量和随机梯度下降这样的技术是本周的一部分,也是在线学习和 map reduce。
没有编码练习。
第 11 周数学难度:低/无,编程难度:无。
这可能是最酷的一周。你学到了很多概念,可怕的数学已经成为过去,你驯服了 Octave。
现在,您将看到如何解决光学字符识别的问题,或者如何在图片中找到文本。本质上,当你给谷歌翻译应用程序输入图片时,它会做什么。
我们将看到如何人工增加数据集和上限分析。本周也没有编程作业。
结尾是一段来自吴恩达的鼓舞人心的视频,标题是“总结和感谢”,只有在你打算观看的时间观看,你才能完全欣赏它:在课程结束的时候。
在简短回顾了所有材料后,吴恩达在视频的最后两分钟发表了我听过的最真诚、最激励人心的演讲。好好享受吧。
总之,如果你和我一样,你最终会爱上这个人,爱上学习的内容和领域,希望这门课程能成为你新职业生涯的垫脚石。
使用分类算法预测 Kickstarter 上的活动成功
型号选择、功能重要性讨论和 Flask 应用程序试用。
作为我探索创意产业的数据科学探索的一部分,使用分类算法来尝试和预测 Kickstarter 活动的结果似乎是一个完美的项目想法。当我写这篇文章的时候,Kickstarter 已经帮助 182,897 个项目获得成功,他们的使命是帮助将创意项目带入生活。随着向 Kickstarter 项目承诺了 4,284,585,270 美元,这对于新的和有经验的创作者来说都是一个强大的平台。
An example of a Kickstarter campaign page.
Kickstarter 活动采用全有或全无的融资模式。如果一个活动失败了,没有钱转手,这就把失败的更沉重的负担放在了活动创造者身上,他们可能已经把自己的时间和金钱投入到了活动中。
Photo by Kobu Agency on Unsplash
出于我的分析目的,我专注于开发一个整体健壮的预测算法,同时确保创作者得到照顾。为了实现这一点,我选择将重点放在 AUC ( 曲线下面积 ) ROC ( 接收器工作特性)曲线上作为主要评估指标,同时注意我的分析中“成功”类别的精度分数,以确保我们不会预测到太多的成功结果是失败(从而最大限度地降低假阳性率)。
这项分析的数据来自 Web Robots 网站,该网站持续汇编 Kickstarter 数据,我检查了 2018 年 4 月至 2019 年 3 月期间全年成功和失败的活动。
An example of a wildly successful Kickstarter campaign.
所使用的信息类型是活动启动时可用的数据,例如:
- 活动的描述(用作文字长度)
- 活动持续时间(天数)
- 无论该活动是否得到 Kickstarter 的支持
- 以美元为单位的目标
- 活动的地点(无论是否在美国)
- 活动的类别
在我的数据集中,略多于一半的活动是成功的(54%的成功,46%的失败),所以这些类别相当平衡。
作为对几种分类算法的初步评估结果,并基于曲线下面积(AUC)作为我的主要评估指标,XGBoost 和 Logistic 回归表现最佳。
The Receiving Operating Characteristic (ROC) Curves for the models used in the analysis.
仔细检查营销活动成功类别的精确度分数,以确保我们没有预测到太多会导致失败的成功,总体表现最佳的是 XGBoost,精确度分数为 0.71。
Results for the XGBoost model performance on the test dataset.
在对测试数据运行 XGBoost 之后,它表现一致,这意味着数据中没有过度拟合或欠拟合。success 类的精度分数略有增加,从 0.71 增加到 0.72。
在为这一分析选定最佳模型后,我回顾了哪些特性对成功的营销活动最为重要。
使用名为 SHAP 值的指标,我们可以检查哪些属性对营销活动的成功更重要。
Feature importance for XGBoost Kickstarter model.
颜色表示特征的大小,方向表示对模型结果的正面或负面影响。污点外观来自于聚集在这些区域的许多数据点。例如,有一个小目标会对许多活动产生积极影响,而有一个大目标会对较小比例的活动产生不利影响。得到 Kickstarter 的支持对那些拥有它的活动来说有很大的不同,但没有得到它也没那么痛。
这里的类别与艺术进行了比较,因此我们可以得出结论,设计和游戏比艺术获得了更高的吸引力,而新闻和手工艺似乎对该活动的成功几率产生了负面影响。
My app demo page — take it for a spin!
为了演示这种预测算法的工作,我使用逻辑回归模型开发了一个 Flask 应用程序,这是第二高性能的算法,被证明比 XGBoost 更容易、更快部署。
应用程序本身可以在这里找到——请随意玩你最喜欢的 Kickstarter 活动,并让我知道结果如何!
总之,建议创作者采取以下措施来增加活动成功的机会:
- 设定一个符合活动范围的小目标(美元)
- 不要将活动延长超过 30 天
- 仔细考虑类别
- 如果可能的话,获得 Kickstarter 的支持
展望未来,我想开发一个 XGBoost Heroku 应用程序,增加功能和视觉吸引力,了解成功的活动筹集了多少资金,设置延伸目标是否有益,并深入研究活动实现的持续挑战以及如何改进。
这个项目的所有资料都可以在我的 GitHub 页面找到。
娜塔莎·鲍德斯,MBA
链接于:@natashaborders
自学很难,坦白说,很孤独。以下是如何让它变得更简单的方法。
让自学变得更容易的 3 个系统,在 Twitter 上关注的导师和学习的酷项目想法
Photo by Atlas Green on Unsplash
MOOCs(大规模开放在线课程)对我们这些自学者来说是个福音。无论你住在地球的哪个角落,世界上最好的教授的讲座都会直接送到你的手中——
这难道不是破坏世界一流教育并使其在全世界民主化的秘诀吗?
2019 年的一项研究使用了 edX (麻省理工学院和哈佛大学提供的一个受欢迎的 MOOC 平台)提供的 MOOC 数据,表明—
不,可能不是 :
- 学习者几乎全部集中在世界上最富裕的国家和地区,
- 平均每 100 个注册课程的人中只有 6 个真正完成课程
- 这些数字没有改善。
这项研究可以总结为,MOOCs 并不像 2012 年首次引入这一理念时世界所预期的那样具有破坏性。
那么,我们如何将更多的学生纳入我们的教育民主化目标呢?
MOOCs 帮助需要帮助的自学者找到学习某个科目的资源。如果我们从更广阔的角度看问题,解决那些需要帮助找到学习这些科目的动机的自学者的需求,也许我们可以使教育更加民主化。
激励学生是无组织的。
我相信,在自学这门学科的概念的同时,自学者也在努力应对我们在传统教育方式中认为理所当然的事情——方向感(由竞争引导)、学习环境和同伴群体。
因为这些正是促使人们自我激励的东西,缺乏这些东西对自学者来说是一个非常现实的问题。对于来自非传统背景和处于不利环境(如发展中国家)的人来说,这个问题尤其严重。他们正在进行一场艰苦的战斗。
我的目标是通过这篇文章给它带来一些结构。以下是我的建议,如果在线课程似乎对你的情况不够有帮助,你可以如何进行自学。
帮助自学的 3 个系统
在做了两年自学者,自学了所有他想学的东西,又过了一年迷茫、没有动力、有点沮丧之后,我开始意识到——
- 自学任何东西都可能是困难的、耗费精力的、相当孤独的过程
- 但是当你关心你正在学习的东西时,你会把它从消耗你能量的东西变成提升你的精神和让你更自信的东西
- 有几个同龄人会让事情变得简单很多
考虑到所有这些,我已经能够提出 3 个系统来帮助你学习 X,当你的物理环境不能的时候
- 在你尝试学习它之前,认真努力爱上它
- 创造一个激励你的环境
- 激励自己完成学习 X 的细节
请记住,它们是长期的系统,而不是一次性的提示和技巧。从长远来看,它们是增加你学习 X 的几率的常规练习。
下面我将详细描述这些系统,告诉你为什么我认为它们都很重要,并给你一些个人建议/技巧来开始使用它们。
1.在你尝试学习 X 之前,认真努力爱上它
如果你爱一样东西,你就会在乎它。当这种情况发生时,学习不再是一项“任务”;它变成了一次冒险。你会渴望更多地了解它,你会有精力去寻找你疑惑的答案。
但是这里有一个陷阱:
当你第一次想知道如何学习 X 的时候,并不是因为你爱 X 甚至觉得它很刺激。你可能对爱 X 的想法更感兴趣…也许*,b* 因为你已经看到一个同事完全疯狂地谈论 X,或者因为你已经听/读了足够多遍,X 是一个“热门”技能,可以放在你的简历中。
尽管这些理由是一个很好的起点,但还不够。如果你因为这些原因而投身于做 X,你将只是从众。如果有人问你“你为什么这么关心 X?”,你大概不会有一个能让你骄傲的答案。
所以,在你去寻找教授 X 的最佳课程之前,认真地、有意识地努力去寻找痴迷 X 的理由。
“如果我试着跳过这一步,继续学习会怎么样?”
每当你强迫自己仅仅为了学习而学习某样东西的时候,你就创造了一个非常不令人满意的学习经历。
为你真正感兴趣的事情努力工作是激情,但为你并不真正关心的事情努力工作是 T21 压力。
这样做可能会让你陷入以下三种情况之一——
- 发现自己无法关心这个主题,中途停止
- 完成一门课程,获得证书,就是这样
- 陷入“教程炼狱”:没完没了地学习一系列课程,看讲座和教程,却没有实际运用它们
这些都不理想。
个人建议和入门技巧:
- 有意识地寻找理由,让你确信学习 X 是绝对最好地利用你现在的时间。
- 在你问别人“*如何学习 X”*之前,先问“X 有什么让你兴奋的地方”。
- 去 Twitter 或 Reddit,逛逛喜欢 X 的人的社区,深入到与那里的人产生最大共鸣的东西——最受喜欢/投票最多的帖子。去兔子洞。
这就把我们带到了下一个系统。
2.创造并置身于激励你的环境中
我们都钦佩有上进心的人。这就像是一种超能力,让他们无法阻挡。
Much like the Juggernaut!
但是没有人生来就有自我激励的能力,对吗?那么是什么给了他们这种“动力”呢?更重要的是,我们如何培养自己的这种能力?
我相信你需要自我激励的是一个充满激励你做更多事情的人和想法的环境。当你和珍视一件东西的人在一起时,你自己更有可能珍视它。
如果你利用互联网的力量,不管你身在何处,你也可以拥有一个激励的环境。
创造一个激励的在线环境
你知道你的 newsfeed 是如何帮助你发现所有那些令人愉悦、令人垂涎、难以想象和疯狂的美食视频,因为它知道你是一个美食家。
现在想象一下,如果它知道你对机器学习或区块链技术或开源软件感兴趣,它会推荐什么。
你可以利用社交媒体最消极的一面——一个令人上瘾的、可以无限滚动的订阅源——并把它变成你的优势。
“如果我跳过这个呢?”
还记得这样一句话吗——“你是和你相处时间最长的 5 个人的平均值”?
所以,如果你周围有一群谈论并经常与你分享 X 的酷事的人,你可以跳过这一步。但即使这样,如果你能接触到你自己的新的、酷的东西的来源,并与他们分享,你会感觉更好。
但是我们大多数自学者并没有被这样的人包围。我们是来自非传统背景或不太好的大学的人,或是来自发展中国家的人,在那里我们没有机会接触到有相似志向的同龄人。这可能是我们解决“个人环境问题”最简单的方法。
个人建议和入门技巧:
我经常使用 Twitter。我建议你也加入。为了进一步说服你,我推荐你阅读 Alexey Guzey 的这篇文章— 为什么(以及如何)你应该现在就加入 Twitter。
让它的推荐系统知道你喜欢 X 很简单:
- 追随那些对 X 感兴趣的人——那些可能成为你榜样的人和对 X 充满热情的学习者
- 从他们的个人资料里偷偷溜走
- 花(有限的)时间浏览你的精彩新闻提要!
这样做,看看 Twitter 的新闻提要如何让你发现所有那些不可思议的事情,并帮助你自我激励。
“但如果我刚刚开始使用 Twitter,我怎么知道该关注谁,不该关注谁?”
没错,对于平台新人来说,这确实是个问题。因此,如果你需要帮助进入编程生态系统,我创建了几个 Twitter 帐户列表。这里列出了喜欢
你可以点击查看更多此类列表。
3.激励自己去完成学习 X 的细节
尽管有所有正确的学习理由,但很多时候自学真的会让人精疲力尽。这时你可能会卡在一些较小的 X 上,而这些较小的 X 组成了我们较大的 X。
你需要激励自己,这样你就能不断度过这段低迷期。
激励自己的一个简单方法是在你学习教程/课程的同时,兼职做一个项目。制作一些看起来很酷很有趣的东西是欺骗自己专心学习 X 的好方法。
个人建议和入门技巧:
我知道这很可怕。我知道你可能会有一些严重的不安全感,尤其是如果你是第一次这样做:
不安全感#1:“我很想自己做点什么,但是我没有任何新的有趣项目的想法。”
是的,这可能是阻止大多数人做项目的最狭窄的瓶颈。甚至超过了建造这个东西的实际难度。
我认为浏览其他人在devpost.com上的黑客马拉松项目是获得这些想法的一个很好的途径,因为—
- 它们只是小的、舒适的、温暖的宠物项目:作为年轻程序员在大约 12、24 或 48 小时内完成的个人项目,它们是非常可行的
- 你可以知道你正在建造一些有价值的东西:他们中的大多数都是黑客马拉松获奖项目
如果你能创造出这样的东西,那该有多酷啊
- 一个简单的通知应用,当通知频率超过每 3 秒 1 次时,你可以选择想要阻止通知的消息应用。
骗自己学 —安卓开发 - 一个网络应用程序,可以让你在 YouTube 视频中搜索,并让你找到说出那个词的地方——视频的 Ctrl-F 功能
并欺骗自己学习——Python,基本网络开发(HTML/CSS,Javascript) - 一款短信应用,自动给你爱的人发短信,让他们知道你已经到达了一个特定的目的地,因为你经常忘记这么做
并欺骗自己学习——安卓应用开发 - 一个工具,用来分析你的 Whatsapp 聊天,并显示诸如——发送的消息数、发送的字数、每条消息的平均字数、最常用的单词、最长的双发短信记录、聊天时间模式、最常分享的网站链接和更多的信息
,并欺骗自己学习——Python,甚至是 web 开发,如果你决定为它建立一个网站的话 - 一个浏览器扩展,将你引向一个与你正在阅读的政治观点相反的故事(这将打击新闻订阅的效果,新闻订阅只允许人们看到社交媒体和新闻网站上与他们观点一致的帖子)
并欺骗自己学习——基本的 web 开发(HTML/CSS、Javascript、jQuery),也许是一些机器学习 - 一个脚本,用于分析《权力的游戏》各季推文的情绪,以了解上一季有多糟糕(😜)
骗自己学 — Python,机器学习,NLP - Kaggle 有一些非常酷的资源,你可以用它们来学习机器学习和数据科学。
How cool would it be if you could get into ML/Data Science by analysing these datasets!? (1, 2, 3, 4, 5)
记住你的目标是自我提升。这就是为什么,我相信,你可以问心无愧地简单模仿和重新实现别人的想法。(尽管如果您能找到一种方法来赋予重新实现您的个人风格,那就太棒了!)
不安全感#2:“但是我没有任何经验。我怎么会知道该学什么,如何建造,如何经历这一切?”
我相信你不需要任何神秘的“真实世界的经验”来构建有用的东西。互联网上充满了这样的故事:有些人只是构建了他们想要的,学到了他们需要的技能,并在这个过程中自学了编程。
我在这里写了更多关于它的内容:如何(以及为什么)在没有经验的情况下开始构建有用的、真实的软件。
“你认识的每一个伟大的开发人员都是通过解决他们没有资格解决的问题而获得成功的,直到他们真正做到了。”
帕特里克·麦肯齐
但即便如此,我也意识到这说起来容易做起来难。
所以我想帮你。
简介,为学习而构建
我创建了Build To Learn来帮助你的自学需求。在这里,我将围绕做项目和教你必要的编程技巧创建一系列教程。
It’ll be like a story — You be the hero, the project our adventure and me, Gandalf, your guide
我会注意学习动机的需要(和缺乏),将上述 3 个系统记在心里,并尝试帮助你——
- 一个“爱 X 的理由”系列,它将作为各个领域的起点
- 我上面介绍的“Twitter 上喜欢 X 的人的名单”系列
- 激励你做更多事情的项目本身
你可以注册这个简讯,这样我就可以给你发送一个更广泛的项目想法列表,让你知道 Build To Learn 的更新。
我还成立了一个 Slack 小组,为那些想学习的人建立一个社区。我们的社区每天都在变大(已经有 350 名成员)。你可以点击这里的链接加入!
感谢阅读!
如果你喜欢我写的东西,你可以通过 Twitter 或者 LinkedIn 或者普通的电子邮件联系我
PS :如果你觉得我的建议有用,我很乐意了解你的故事,你的学习挣扎,给你更多个性化的建议。使用上述任何服务联系我,与我进行 10 分钟通话【T13:)
分级分类的搭便车指南
如何像专家一样对分类数据进行分类?
数据科学领域有一个固有的不协调性:当人类思维以层级结构感知周围的世界时,我们构建的模型接收的输入是平面的。
例如,当想到动物时,我们脑海中有一个清晰的分类:德国牧羊犬和金毛寻回犬都属于“狗”类,属于“哺乳动物”类;另一方面,普通的绿色鬣蜥属于“蜥蜴”类,属于“爬行动物”——与“哺乳动物”同属一类。虽然类层次树对人类来说非常直观,但如何向机器学习算法表示这些关系并不总是很清楚。
那么我们应该如何处理分类数据呢?弥合这一差距的最佳方式是什么?通常情况下,没有一个明确的答案,但有几种方法来应对这一挑战。我在这里告诉你关于他们的一切。
在这篇文章中,我将使用常见宠物的分类法来说明不同的层次分类方法:
平面分类
一种简单、直接的分类方法是平面分类法。在这里,您不必为那些讨厌的父类别而烦恼,只需将每个示例分类到其最终的叶级标签即可。暹罗猫对法国牛头犬来说就像对 Sphynx 猫一样(也被称为“奇怪的,没有毛的那种”)。
Flat classification: the dashed rectangle stands for one multi-class classifier
平级分类的利弊
- 这种方法的明显优点是简单。你来,你看,你分类。这是一个简单的解决方案,可以用一个现成的分类器轻松实现。
- 不利的一面是,你显然会丢失一些重要的信息。数据的自然层次结构可能具有很高的分类价值,忽略这些父子类关系可能会降低性能。
大爆炸方法
接下来,我们有了全球分类器****——,或者用他们更吸引人的名字**“大爆炸方法”。**这些是各种各样的一堆,它们都共享同一个概念:一个单一的、相对复杂的模型,它在一次运行中把整个类层次结构作为一个整体来考虑。
除此之外,他们几乎没有共同之处。全局分类器可以走向非常不同的方向。一些使用聚类方法,一些将问题重新定义为多标签问题,一些是现有算法的修改版本,手工定制以适合手头非常具体的数据层次结构。
例如,您可以使用决策树算法,但是更改熵计算公式,以包含所讨论的数据层次结构特有的信息。或者修改模型,使其更喜欢较深的节点而不是较浅的节点,从而提供更具体的类别预测。这只是一个例子。说到全球分类器,世界是你的。
The Big Bang approach: one global classifier for the entire class hierarchy
大爆炸方法的利与弊
自然,这些各不相同。与半通用多标签算法相比,定制算法具有不同的优缺点,对于全局分类器池中的每一个其他独特的雪花也是如此。不过,一般来说,这种方法的高度复杂性是一个主要缺点,也可能是它很少被使用的原因。
分层结构局部分类器
最后但同样重要的是,我们有我个人最喜欢的:使用分层结构 局部分类器。这种方法使用预定义的数据分类法来创建分类器的层次结构。有三种标准方法可以做到这一点:
- 每个父节点的局部分类器:为每个父节点训练一个多类分类器,以区分其子节点。
在我们的例子中,这意味着第一层有一个分类器(确定“猫”、“狗”或“独角兽”),然后再有三个分类器来确定具体的品种。
为了防止不同级别的预测不一致,您可以设计系统,使被第一个分类器分类为“猫”的示例只能被第二个级别的“猫”分类器看到。这样,你可以避免创造新的、奇异的混血儿,比如狮子狗独角兽(尽管这听起来不可思议)。
Local classifier per parent node (each dashed rectangle represents a multi-class classifier)
- 每个节点的局部分类器:为层次结构中的每个节点训练一个二元分类器(“Pets”节点除外)。这是一只猫吗?这是一只法国斗牛犬吗?这是彩虹独角兽吗?每个问题都有一个分类器。
Local classifier per node (each dashed rectangle represents a binary classifier)
- 每级局部分类器:为每个级训练一个多级分类器。在我们的例子中,这意味着两个分类器:一个用于确定种族(猫、狗或神奇的独角兽),另一个用于品种(波斯猫、拉布拉多、独角鲸等)。).这种方法很不受欢迎,可能是因为它提出了不一致的问题:很可能的结果是“狗”是种族,而“飞马”是品种,而且没有好的方法来避免它。
Local classifier per level (each dashed rectangle represents a multi-class classifier)
局部分类器的利弊
局部分类器方法非常直观,使用数据中的层次信息,同时保持简单性和通用性(它可以用于任何基本分类器)。然而,根据分类法和选择的方法,您可能会得到一个相当庞大的最终模型。
还有一个错误传播的问题,其中一个级别的错误可能会影响所有后续级别。不过,这是可以控制的——稍后会详细介绍。
思考这三种方法各自独特的优缺点?敬请关注。
我自己选择分类器的个人分类器
**那么,你应该选择什么方法呢?**以下是我在讨论这个问题时的考虑:
个人最爱?地方量词,这是毫无疑问的。它直观、聪明,可与任何基本算法一起工作,并设法保留关于数据层次结构的自然信息。同时保持合理的设计和维护简易性。在我看来,这应该是你处理所有层次结构的首选方法。
不过,可能会有特殊情况。也许你的项目是一个快速和肮脏的项目,你愿意牺牲一点准确性来获得更快的胜利。或者也许你有限制,简单是关键。如果是这样的话,直截了当的扁平分类可能最适合你。
当你需要你的模型提供快速预测而不牺牲准确性时,一个全局分类器可能是一个很好的选择,这取决于特定的算法。毕竟,它只需要运行一次。然而,这种出色的表现是有代价的:做好付出高复杂性的准备。
或者也许你是那种超级有创造力的人,你有第四个更好的想法,我在这里没有提到。如果是这样的话,为什么不和班上其他人分享一下呢?下面的评论区等着你。
一些最后的调整
好吧,我决定使用强大的本地分类器,但是……
- 我应该使用每个节点、每个父节点还是每个级别的分类器?
- 我应该对每个分类器使用相同的特征,还是应该改变它们?
- 对于这种奇怪的模型结构,我使用了哪些性能指标?
- 以神圣的名义,我该如何定义我的正面和负面训练范例?
的确,所有重要的问题都将得到解答——但不是在此时此刻。在我的下一篇文章中,我将深入探讨局部分类器方法的所有优点。
与此同时,我希望你充分利用你新发现的关于分类数据分类的知识,并记住:独角兽是一种有效的家养宠物,不要让任何人告诉你不同。
Noa Weiss 是特拉维夫的一名自由数据科学家。
资料来源 : C.N. Silla & A.A. Freitas, 跨不同应用领域的层次分类综述 (2011),数据挖掘与知识发现,22(1–2):182–196