TowardsDataScience-博客中文翻译-2016-2018-六十二-

74 阅读1小时+

TowardsDataScience 博客中文翻译 2016~2018(六十二)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

协作过滤和嵌入—第 1 部分

原文:towardsdatascience.com/collaborati…

推荐系统就在我们身边。从网飞、亚马逊到 even Medium,每个人都在试图理解我们的口味,这样他们就能促使我们持续参与。你会惊讶于这背后的工作量。让我们试着理解开发推荐系统的一种方法的机制。

介绍

在这一系列文章中,我将解释协作过滤,这是开发自动推荐系统的一种非常常见的技术(尽管用例不限于推荐)。然而,使这个讨论有趣的是我们如何在实现这个技术的同时理解一个更一般的嵌入的概念。如果你没有听说过这个术语,不用担心,在这篇文章结束时你会有一个好主意。

第一部分:

  • 协同过滤背后的基本思想
  • 一个在 excel 中实现协同过滤的简单算法(是的你没看错!!)
  • 理解嵌入和偏差的概念

第二部分:

  • 利用 fastai 库实现协同过滤
  • 解释和可视化嵌入

协同过滤和嵌入—第二部分

这篇文章中提出的大多数想法都来自于杰瑞米·霍华德作为T21数据研究所的一部分进行的 深度学习 MOOC - v2 。这篇文章只是我尝试分享我在这个课程中学到的一些惊人的东西。

现在,事不宜迟,让我们开始吧…

什么是协同过滤?

Figure 1: Collaborative filtering [1]

推荐系统的上下文中,协同过滤是一种通过分析与所述用户相似的用户的喜好来预测用户兴趣的方法。通过协作多个观点来过滤模式的想法是它被称为协作过滤的原因。

协同过滤方法的基本假设是,如果一个人 A 在一个问题上与一个人 B 有相同的观点,那么 A 在另一个问题上比随机选择的人更有可能有 B 的观点

——维基百科[2]

协同过滤是一个通用的概念,有几种算法来实现它。查看这篇比较不同算法性能的文章。

[## 协同过滤的各种实现

利用协同过滤构建推荐系统的不同方法比较

medium.com](medium.com/@pgrover3/v…)

一种这样的算法是**概率矩阵分解。**不要被名字吓到。我们将使用 excel 中的虚拟示例来理解这一点。

Excel 中的协同过滤

方案

如图 2 所示,我们有不同用户对不同电影的评分数据,评分范围为 0-5。空白单元格表示用户尚未对电影进行评级。我们的目标是尽可能地模拟这个系统。

Figure 2: Original ratings

模型

Figure 3

在图 3 中,您可以看到完整的框架。让我们试着去理解用户-电影**(乔恩-阿甘)的特定组合在这里发生了什么。**

本质上,这个模型就是这个等式:

模型预测的评分(黄色单元格中的 3.25)= 2 个绿色矢量(嵌入矢量)的点积+ 0.14(电影偏差)+ 0.87(用户偏差)

类似地,我们将预测每个用户-电影组合的评分,除了那些在实际数据中不存在用户-电影评分的组合。基于此,我们将通过比较预测评级和实际评级来计算损失( RMSE(均方根误差)(在我们的例子中:底部的红色单元格)。

很明显,我们的预测是基于这些 2 个嵌入矩阵和 2 个偏差矩阵。但是里面的数字呢,它们看起来是随机的,实际上是随机初始化的。那么,什么样的正确数字会让我们的预测接近实际的收视率呢?

是的,你猜对了。我们将通过使用某种优化算法使损失最小化来学习这些数字。事实上,这可以在 excel 中完成!!

梯度下降

转到数据→解算器,您将看到以下窗口。在设置目标中选择损失单元,在可变单元中选择嵌入和偏置矩阵范围。点击求解,求解器将通过最小化损失开始学习嵌入和偏差矩阵中的正确值。

Figure 4

Figure 5 : Predicted ratings using collaborative filtering

我们可以在图 5 中看到,求解器已经学习了嵌入和偏差矩阵中的值。我们的损失从 26.04 减少到 4.58 。我们从模型中得到的预测似乎也接近实际的收视率。所以现在我们有了一个看起来运行良好的模型。但是我们仍然不知道它为什么有效。基本上这个算法背后有 3 个关键的想法。

嵌入

关键思想#1:找到每个用户和每部电影作为嵌入的正确表示

是时候解决房间里的大象了。我们来看一个具体的例子。这里,乔恩阿甘向量(求解器已经学习的一串 5 个数字)表示。这些向量被称为嵌入。本质上在一个 5 维向量空间中,乔恩和阿甘由这两个嵌入向量表示。

Embedding : Jon

Embedding : Forrest Gump

嵌入是特定实体的多维向量表示

这种将实体表示为高维向量的方式是关键。这种表示可以捕捉不同实体之间的复杂关系。

为什么是 5?

嵌入向量的维数没有特定的规则,更多的是关于实验。维度应该足以捕捉实体的复杂性。一维或二维向量可能无法捕捉 Jon 的复杂性。但也不应该过高。我们的乔恩和阿甘没那么复杂。

嵌入向量中数字背后的直觉

您可以将这些数字视为捕捉它所代表的实体的不同特征。比如乔恩 (1.34) 中的第一个数字,可能代表他有多喜欢奇幻小说。而《阿甘正传》中的第一个数字 (-1.72) 告诉了我们在多大程度上可以把阿甘当做幻想(由于数字是负数,所以非常少)。

注意:从理论上讲,这是一个思考嵌入向量中的数字的好方法,但是我们永远不能真正说出每个数字实际上在捕捉什么。我们可以做一个有根据的猜测。

嵌入空间的封闭性

关键思想#2:如果一部电影和一个用户在一个向量空间中很接近,那么用户很可能会给这部电影很高的评价

捕捉接近度有不同的方法:点积,欧氏距离,余弦相似度。在我们的例子中,我们使用了点积

偏见的作用

关键思想#3:实体有一个独立于它与其他实体的交互的固有性质

简而言之,一些用户比其他人更挑剔。类似地,一些电影可以被普遍认为是好的,并且会被大多数用户评价很高。这些信息是通过偏见获得的。

该模型的建议

现在,我们有了一个训练有素的模型,它已经为每个用户和电影学习了正确的嵌入和偏好。考虑这样一种情况,我们必须向用户推荐一组电影中的一部电影(假设该组中的所有电影都没有被该用户看到)。

使用计算出的嵌入和偏差,我们可以预测用户将对该组中的每部电影给出的评级。所建议的电影将是具有最高预测等级的电影。

预测评分=嵌入向量点积(用户、电影)+用户偏差+电影偏差

链接到 excel 文件:https://github . com/shik 3519/collaborative-filtering/blob/master/collab _ filter . xlsx。受此文件启发→[3]

结束注释

这篇文章中讨论的方法肯定不是实现协同过滤的最佳方式。使用神经网络有更好的执行算法,但是嵌入的核心思想是共同的。

看看这篇文章,它讨论了神经网络的实现以及其他很多东西。

[## 协同过滤的各种实现

利用协同过滤构建推荐系统的不同方法比较

medium.com](medium.com/@pgrover3/v…)

接下来

的下一篇文章中,我将讨论我们如何使用由杰瑞米·霍华德 等人开发的名为 fastai 的库来实现协同过滤。这个库构建在 pytorch 之上,专注于更容易实现的机器学习和深度学习模型

此外,我们将了解如何使用【t-SNE】Bokeh(Python 交互式可视化库,面向现代 web 浏览器进行演示)。下面是一个什么在商店的预告。****

【协同过滤与嵌入—第二部分

更多资源

**** [## 一口气学习实体嵌入

也许不会,除非你经常打破屏住呼吸的世界纪录!从好的方面来看,实体…

medium.com](medium.com/@apiltamang…) [## 结构化深度学习

快的

towardsdatascience.com](/structured-deep-learning-b8ca4138b848) [## 面向程序员的深度学习——36 小时免费课程

fast.ai 面向编码员的实用深度学习 MOOC。学习 CNN,RNNs,计算机视觉,NLP,推荐系统…

course.fast.ai](course.fast.ai/lessons/les…)

参考

[1]https://commons . wikimedia . org/wiki/File % 3a collaborative _ filtering . gif

[2]en.wikipedia.org/wiki/Collab…

[3]https://github . com/fastai/fastai/blob/master/courses/dl1/excel/collab _ filter . xlsx

[4]http://www . wired . co . uk/article/how-do-netflixs-algorithms-work-machine-learning-helps-to-predict-what-viewers-will-like****

协作过滤和嵌入—第 2 部分

原文:towardsdatascience.com/collaborati…

Movie embeddings

在第一部分的中,我已经介绍了协同过滤背后的基本思想以及嵌入偏差的概念。建议您在继续之前阅读该帖子。

协同过滤和嵌入—第一部分

在这一部分,我将讨论我们如何使用由杰瑞米·霍华德 等人开发的一个名为 fastai 的库来实现协同过滤。这个库建立在 pytorch 的基础上,专注于更容易实现的机器学习和深度学习模型

此外,我们将了解如何使用【t-SNE】Bokeh(Python 交互式可视化库,面向现代 web 浏览器进行演示)。****

这篇文章中提出的大多数想法都来自于 深度学习 MOOC - v2杰瑞米·霍华德作为 数据研究所 的一部分进行的。这篇文章只是我尝试分享我在这个课程中学到的一些惊人的东西。

资料组

我用过movie lens【1】数据集( ml-latest-small )。该数据集描述了来自电影推荐服务 MovieLens五星评级和自由文本标记活动。它包含 100004 评级1296 标签应用横跨 9125 部电影。这些数据是由 671 位用户在 1995 年 1 月 09 日至 2016 年 10 月 16 日之间创建的。

我们将使用两个文件:ratings.csvmovies.csv

使用 fastai 的协同过滤

开始之前,我们需要两件东西:

  • 支持 GPU 的机器(本地或 AWS)
  • 在你的机器上安装 fastai 库:pip install fastai

注意:在这篇文章的最后,我已经详细解释了如何为 fastai 设置你的系统

下面是使用 fastai 实现的一步一步的代码演练。底层算法和我们在 第一部分 讨论过的一样。

步骤 1:数据加载

我们正在看 2 个文件:收视率和电影

Figure 1: Ratings

评分包含不同用户对不同电影的评分。

Figure 2: Movies

电影包含关于电影的元数据。movieid是连接 2 个数据集的关键。

第二步:模特训练

**#fastai function
**val_idxs = get_cv_idxs(len(ratings))** #get validation indices** 

我们将把数据分为训练集和验证集。我们的验证是原始数据集的 20%。

****wd=2e-4** #weight decay
**n_factors** = 50 #dimension of embedding vector**

我们将使用 重量衰减 来减少过度拟合。我们还必须定义我们的嵌入向量的维度。

**#fastai function
**cf = CollabFilterDataset.from_csv(path, 'ratings.csv', 'userId', 'movieId', 'rating')** #creating a custom data loader**

现在我们必须为协同过滤创建一个数据对象。你可以把它看作是将原始数据转换成模型所要求的形式的东西。from_csv意味着输入应该是一个 csv 文件

函数的参数:

  • path:CSV 文件的位置路径
  • ratings.csv:CSV 文件的名称。它应该是图 1 所示的长格式
  • userID/movieID:2 个实体的列名
  • rating:要预测的因变量的列名
**#create a learner (model) and specify the batch size and optimizer 
**learn = cf.get_learner(n_factors, val_idxs, 64, opt_fn=optim.Adam)** 
#fastai function**

下一步是创建一个模型对象,它是我们已经创建的数据对象的函数。learner在 fastai 库中与 model 同义。该函数采用以下参数:

  • n_factors:嵌入向量的维数(在我们的例子中为50
  • val_idxs:验证时必须考虑的 ratings.csv 文件中的行索引
  • batch size:梯度下降的每一步传递给优化器的行数。在我们的例子中,每次迭代将传递 64 行数据
  • opt_fn:我们想要使用的优化器。在我们的例子中我们使用的是 亚当 。在这个库中,你可以访问不同的优化器

Figure 3: Optimisers

**#training with learning rate as 1e-2 
**learn.fit(1e-2, 2, wds=wd, cycle_len=1, cycle_mult=2, use_wd_sched=True)** 
#fastai function**

训练的最后一步是实际训练模型。在learner对象上调用fit训练模型并学习嵌入和偏置矩阵中的正确值。

函数的参数:

  • learning rate : 1e-2 是我们用于优化的学习率
  • wd:通过重量衰减
  • cycle_len/cycle_mult:这些是 fastai 的好东西,整合了最先进的学习率计划方法。帖子末尾包含与此相关的有用文章的链接。
  • use_wd_sched:是否使用体重衰减时间表

当您运行上面的代码时,模型将开始训练,如下所示。您可以在每个时期后观察训练(左)和验证(右)损失。我们优化的损失函数是MSE (Mean squared error)

Figure 4: Model training

步骤 3:验证预测

****preds = learn.predict()** #prediction on validation
**math.sqrt(metrics.mean_squared_error(y,preds))** #calculating RMSE**

我们将使用训练好的模型来预测验证并计算 RMSE 。我们得到了一个 ~.90 的 RMSE,与该数据集的当前基准相当。

****y=learn.data.val_y** #actual ratings for validation
**sns.jointplot(preds, y, kind='hex', stat_func=None);****

Figure 5: Predictions (y) vs Actual (x) (Ratings)

我们还可以看到,我们从模型预测与实际收视率相符。

现在,我们将尝试解释嵌入和偏见,看看它们是否捕捉到一些有意义的信息。

解释嵌入和偏见

我们将把重点放在电影的嵌入和偏见上,因为我们有电影的实际名称

电影嵌入

我们知道我们的嵌入向量的维数是 50 。可视化这样的高维向量是困难的,几乎是不可能的。

t-分布式随机邻居嵌入(t-SNE) 是一种有效的方法,可以在较低的维度上可视化它们,同时保持这些向量之间的空间关系

使用上面的代码,我已经将嵌入向量的维数减少到 2 (t-SNE 分量)。下面我们可以看到为 3000 部电影嵌入的 2 个 t-SNE 组件。每个点代表一部电影。

y-tsne vs x-tsne components of embedding vectors (3000 movies)

你可以在这里玩这个剧情:http://tsne.getforge.io/

进一步放大我们可以看到来自同一个系列的电影在嵌入空间非常接近(几乎重叠)。这表明嵌入不仅仅是为了减少损失而优化的一些数字。

我们希望同一个系列的电影在风格、导演、演员等方面或多或少有些相似。嵌入空间的紧密性反映了嵌入正在捕捉这些特征

电影偏见

电影偏差可以被认为是对电影实际质量的一种度量,针对不同用户的不同分级模式进行调整**。**

偏见可以被认为是电影实际上有多好/受欢迎的代表

让我们看看这是否反映在我们模型的偏差中

Bottom 15 movies based on bias

Top 15 movies based on bias

看着这个列表,我想大多数人都会同意这个列表看起来或多或少是合适的,并且更接近我们的大多数期望。

基于偏见对电影进行排名比仅仅平均所有用户给出的评级更有意义。与名字相反,它实际上使排名不偏不倚

嵌入聚类(基于评级)

对我来说,这是最有趣的部分。下面我挑选了一个评价电影数量最多的用户( userID:547 )。现在我在尝试看看用户给出的评分和不同电影的嵌入向量之间有没有什么看得见的关系。

猜猜看…

t-SNE components of movie embeddings clustered by ratings (userID: 547)

很明显,高评级(黑与红)的电影集中在嵌入空间的一部分。类似地,那些等级低的电影(绿色和蓝色)集中在空间的另一部分。

链接到 html 文件的情节。下载并在浏览器中打开:https://github . com/shik 3519/collaborative-filtering/blob/master/t-SNE _ cluster _ rating . html

嵌入聚类(基于偏差)

类似地,我也尝试过根据电影偏好对电影嵌入进行聚类。期望具有相似偏差(如所讨论的无偏流行度的度量)的电影在嵌入空间中应该是接近的。

我们可以在下图中看到。

t-SNE components of movie embeddings (clustered by movie bias)

好(或坏)的电影都有一些共同的特征,这些特征被嵌入捕捉到了

链接到绘图的 html 文件。下载并在浏览器中打开:https://github . com/shik 3519/collaborative-filtering/blob/master/t-SNE _ emb _ cluster _ bias . html

我觉得很新奇,所以我试着想象电影嵌入的三个 t-SNE 组件。每个点代表一部电影,点的大小和颜色取决于偏差。

下面是实际剧情的链接:plot.ly/~shik1470/2…****

链接到用于此图的数据:https://github . com/shik 3519/collaborative-filtering/blob/master/t-SNE 1 . CSV

最后的想法

到现在为止,我想你会有点相信嵌入的想法是非常强大的。这个概念可以扩展到任何有大量分类变量的结构化数据问题。

分类变量的每一级可以被表示为高维向量,该向量可以捕获标签或一位热码编码未能捕获的关系。标签或一个热编码假设每个实体都是相互独立的,如果你仔细想想,肯定不是这样。

这是另一个关于在结构化环境中使用嵌入的很酷的帖子,你一定要看看。

**** [## 结构化深度学习

快的

towardsdatascience.com](/structured-deep-learning-b8ca4138b848)

有用的资源

  1. 学习率选择和调度:

[## 提高我们的工作方式和学习速度。

一.导言

techburst.io](techburst.io/improving-t…) [## 估计深度神经网络的最佳学习速率

学习率是用于训练深度神经网络的最重要的超参数之一。

towardsdatascience.com](/estimating-optimal-learning-rate-for-a-deep-neural-network-ce32f2556ce0) [## 探索重新开始的随机梯度下降(SGDR)

这是我第一篇深度学习的博文。我在 2017 年 1 月左右开始了我的深度学习之旅,在我听说了…

medium.com](medium.com/38th-street…)

2.t-SNE:

[## 如何有效地使用 t-SNE

一种流行的探索高维数据的方法叫做 t-SNE,是由范德马滕和辛顿提出的…

蒸馏. pub](distill.pub/2016/misrea…) [## 在 Python 中使用 PCA 和 t-SNE 可视化高维数据集

任何与数据相关的挑战的第一步都是从探索数据本身开始。这可以通过查看…

medium.com](medium.com/@luckylwk/v…) [## LDA 和 T-SNE 交互式可视化

使用 NIPS 2015 论文中的数据

www.kaggle.com](www.kaggle.com/ykhorramz/l…)

3.法斯泰:

设置 fastai 的说明:

  1. 本帖 GitHub 回购 : 本回购包含本帖中显示的笔记本和剧情

参考文献和引文

[1] F .麦克斯韦·哈珀和约瑟夫·康斯坦。2015.电影镜头数据集:历史和背景。ACM 交互式智能系统汇刊(TiiS) 5,4,第 19 篇(2015 年 12 月),19 页。dx.doi.org/10.1145/282…****

基于协同过滤的推荐系统举例..

原文:towardsdatascience.com/collaborati…

在我的上一篇文章中,我对推荐系统做了简单的解释,举例说明了各种类型的推荐系统。在这篇文章中,我将使用 Python 实现一些这类推荐系统的简单例子。

给定下面的用户项目评级矩阵 M,其中 6 个用户(行)对 6 个项目(列)进行了评级。评级可以取 1-10 之间的整数值,0 表示没有评级。(注意,我们对行和列使用 Python 中使用的从零开始的索引。但是,对于用户输入,user_id 将占用 1–6 之间的数字,item_id 将占用 1–6 之间的数字。假设,我们必须发现用户 3 是否会喜欢项目 4。因此,用户 3 成为我们的目标用户或活动用户,项目 4 是目标项目。

sample user-ratings matrix

基于用户的协同过滤

首先,我们必须预测用户 3 对项目 4 的评分。在基于用户的 CF 中,我们会找到与用户 3 最相似的 k=3 个用户。常用的相似性度量有余弦、皮尔逊、欧几里德等。这里我们将使用余弦相似度,其定义如下:

和,皮尔逊相关,定义为:

在 sklearn 中, NearestNeighbors 方法可以用来基于各种相似性度量来搜索 k 个最近邻居。

查看我的 Jupyter 笔记本下面嵌入的

[## csaluja/JupyterNotebooks-中号

在 GitHub 上创建一个帐户,为 JupyterNotebooks-Medium 开发做出贡献。

github.com](github.com/csaluja/Jup…)

findksimilarrusers函数使用此方法返回活动用户的 k 近邻的相似度和索引。函数predict _ user based****使用基于用户的 CF 方法进一步预测用户 3 将给予项目 4 的评级。预测计算为邻居平均值偏差的加权平均值,并将其添加到活跃用户的平均评级中。偏差用于调整与用户相关的偏差。由于某些用户可能总是倾向于给所有项目高或低的评级,所以会出现用户偏差。**

其中 p(a,I)是项目 I 的目标或活动用户 a 的预测,w(a,u)是用户 a 和 u 之间的相似性,K 是最相似用户的邻域。

基于项目的协同过滤

在这种方法中,使用余弦相似性度量来计算项目对之间的相似性。活跃用户 a 的目标项目 i 的评分可以通过使用简单加权平均来预测,如下所示:

其中 K 是活动用户 a 评价的最相似项目的邻域,w(i,j)是项目 ij之间的相似度

在 Jupyter Notebook embed 中检查,函数findksimilaritems使用利用余弦相似度的最近邻居方法来查找与项目 i. 相似的 k 个项目,函数predict _ item based使用基于项目的 CF 方法(上面的公式)进一步预测用户 3 将给予项目 4 的评分。

调整后的余弦相似度

将余弦相似性度量用于基于项目的 CF 方法不考虑用户评级的差异。调整后的余弦相似性通过从每个共同评级对中减去相应用户的平均评级来弥补这一缺陷,并且定义如下

为了在 Python 中实现调整后的余弦相似度,我定义了一个名为 *computeAdjCosSim,的简单函数,该函数返回调整后的余弦相似度矩阵,给定评级矩阵。函数findksimilaritems _ adj cospredict _ item based _ adj cos利用调整后的余弦相似度来寻找 k 个相似项目并计算预测评分。*

功能re commenditem提示用户选择推荐方式(基于用户(余弦)、基于用户(相关)、基于项目(余弦)、基于项目(调整余弦)。基于所选择的方法和相似性度量,该功能预测指定用户和项目的评级,并且还建议是否可以向用户推荐该项目。如果用户尚未对该项目进行评级,并且如果预测评级大于 6,则向用户推荐该项目。如果评级小于 6,则不向用户推荐该项目。

相似性度量的选择

在选择相似性度量时,一些有用的线索是

当您的数据受到用户偏差/不同用户评级尺度的影响时,请使用 Pearson

如果数据稀疏(许多评级未定义),请使用余弦

如果您的数据不稀疏并且属性值的数量很大,请使用欧几里得

对基于项目的方法使用调整余弦来调整用户偏差

推荐系统的评价

评价推荐系统的评价指标有很多。然而,最流行和最常用的是 RMSE(均方根误差)。函数 评估者 使用 sklearn 的均方误差函数计算预测额定值和实际额定值之间的 RMSE,并显示所选进近的 RMSE 值。(为了解释简单,使用了小数据集,因此没有将其分成训练集和测试集;本帖也不考虑交叉验证)。

在用户基数很大的应用程序中,基于用户的方法面临可伸缩性问题,因为它们的复杂性随着用户数量的增加而线性增长。基于项目的方法解决了这些可伸缩性问题,根据项目相似性推荐项目。混合技术利用了各种此类方法的优势,并以多种方式将它们结合起来以实现更好的性能。

感谢阅读。这篇文章是为了分享我对推荐系统的理解,欢迎任何关于改进这个实现的反馈。

变形应用的协同过滤

原文:towardsdatascience.com/collaborati…

ecSys 第一周:这篇文章是对论文' 【协同过滤推荐系统】 的简要总结和个人评论,发表在'【自适应网络'这本书上,作者是本·斯查费、丹·弗兰科斯基、乔恩·赫洛克和施罗德·森,2007 年。这篇博客是作为智利天主教大学推荐系统 (IIC3633)课程的每周读物而写的。

收到推荐在每个消费产品中都很常见,我们经常从朋友那里得到推荐,比如一部很酷的电视剧或一本鼓舞人心的书。但不仅仅是人,像 Amazon.com 这样的网站向你推荐相机,或者 Spotify 告诉你一个你从未听说过的团体。但是 Amazon.com 怎么知道你会喜欢那台相机,或者 Spotify 上关于那个团体的信息呢?他们主要使用协同过滤系统,预测你是否会喜欢一个产品。

协同过滤(CF)系统的一些想法试图模仿口碑相传的行为,让用户向其他可能喜欢该项目的人发送推荐,或者你可以看看你信任的某个朋友给出的评级:这被称为主动 CF。但由于这些依赖于人们做工作的系统的存在,还有自动 CF (ACF),其中使用不同算法的计算机生成推荐。 由于我们经常有一个与我们品味相似的朋友,我们可以从他那里获得推荐,常见的 ACF 系统也试图这样做,并寻找与每个人的品味相似的用户或物品。为了确定两个人是否相似,他们比较他们给出的评分,他们越接近,那么这个人就越相似。

但是如何为一个新用户做推荐,或者像脸书的宣传那样,没有给出评级?现在在网页上跟踪用户交互变得非常普遍。例如,看一个产品的描述所花的时间,在 Instagram 上滚动时你停留的图片,你首先注意到的新闻的位置(通过鼠标的位置或点击它们来识别)。 以上例子是隐性的信息收集方法,不一定完全可靠。也许你花了很多时间阅读亚马逊上某个产品的描述,结果却发现它并不是你所需要的,但是你的主页上却显示了这个产品。但是,对于用户和提供商来说,相关信息仍然可以通过这种方法获得,并且不一定产生产品的推荐。

Behavior gathering. Source: www.gravityrd.jp/en/technolo…

与这个主题相关,我认为作者没有为 CF 系统添加一个有趣的使用案例(可能只是因为这些跟踪实现的新颖性)。我们经常听说脸书优秀的 A/B 测试系统,它允许他们决定,例如,哪种布局对他们的用户更有吸引力。诸如此类的事情,几乎不能被用户评价,因为他们可能不会注意到大的差异,允许提供一个更令人满意的应用程序体验。

如果我们可以基于用户配置文件个性化整个应用程序结构,会怎么样?一些用户可能喜欢不同的 SAP 仪表板,一些用户可能讨厌脸书视频的自动播放(并且不知道它可以被禁用)。正如我们可以为购买者的兴趣生成一个配置文件一样,通过使用跟踪实现,实际上不同的应用程序可以交付给使用它时具有相似行为的用户组。有了变形应用,我们不仅可以满足大多数人的偏好,还可以满足几乎所有人的偏好,并提高应用的整体满意度。

为了建立用户档案,我们可以跟踪的一个例子是:

  • 执行一个动作所花费的时间(越少越好)。
  • 花在应用上的时间(时间越多越享受)。
  • 点击链接的数量。
  • 等等。

当然,也有许多必须面对的困难,比如实现这种变形应用程序的方法,或者允许我们跟踪感兴趣的行为的系统,但也有一个好的部分,这将是过去几年在推荐系统方面取得的进展,一旦收集到正确的数据,它将允许匆忙建立简档。

感谢您的阅读,如果您喜欢这篇文章,您可以点击这里的在它的 Steemit 链接上投稿。任何更正,评论,相关阅读我都会欣然接受。对于这篇文章,我并不打算曲解或指出这篇文章的大部分内容(如果不是全部的话)是基于什么样的原著。

协同过滤:从浅到深的学习

原文:towardsdatascience.com/collaborati…

协同过滤通常用于创建推荐系统(例如,网飞演出/电影推荐)。当前最先进的协同过滤模型实际上使用了一种非常简单的方法,结果证明效果很好。在这篇文章中,我将概述这些利用“浅层学习”的最新模型,然后介绍一种更新的方法(在我看来很有前途!),它利用了深度学习。在这篇文章中,我将使用 MovieLens 数据集 作为例子,其中包含用户对电影的评级。我还在我的 Github 上提供的脚本中演示了如何使用浅层和深层协同过滤,所以如果你想使用这些模型,请查看我的 Github!这个脚本利用了优秀的深度学习库 fastai(写在 PyTorch 之上)和 PyTorch。

浅薄的学问

当前最流行的协同过滤模型利用了一种叫做嵌入矩阵的东西。嵌入矩阵包含多维信息。例如,假设我们有一个包含三个因素的电影嵌入矩阵。这三个因素可能对应于电影的动作片程度、电影的浪漫程度以及电影是否更像纪录片。当然,这些因素可以对应于任何东西(并且不一定容易解释),嵌入矩阵通常包含许多因素。正是这些矩阵在训练协作过滤模型时被更新。使用 MovieLens 数据集示例,通过我们的标准协作过滤技术,我们将拥有用户和电影的嵌入矩阵(见下图)。矩阵的大小将是用户或电影的数量乘以我们选择的因素的数量。关于选择嵌入矩阵中因子的数量,这需要一些试错法。在我的Github 上的示例脚本中,嵌入因子的数量被设置为 50。在训练开始之前,这些嵌入矩阵中的值被随机初始化。在训练期间,这些值被更新以减少损失(即,使预测评级更接近实际评级)。在训练的每次迭代期间,对于每个用户对电影的评级,取相应向量的点积。这个点积就是预测评级。点积是针对每个用户对每部已评级电影的评级(注意:未被用户评级的电影被设置为 0),并将预测评级与实际评级进行比较。然后,使用随机梯度下降(或随机梯度下降的近似变体)来更新嵌入矩阵内的值,以减少损失函数。除了嵌入矩阵之外,现有技术的协同过滤模型包含偏差项,其本质上是考虑总是给出更高或更低评级的某些用户或者总体上被给出更高或更低评级的电影(即,好电影或坏电影)。这些偏置项被加到点积上。

这就是最先进的协同过滤模型的全部内容。正如你所看到的,所有这些背后的数学非常简单,如果你看一看我的 Github 上发布的附带脚本,你会看到使用 fastai 库,只需几行代码就可以创建和训练一个最先进的协作过滤模型。

深度学习

好了,我们已经介绍了当前最先进的协同过滤模型,它工作得很好,并利用了“浅层学习”,但该领域的下一步是什么?一个有前途的方向可能是深度学习的协同过滤,因为(1)深度学习在其他工作领域(例如,计算机视觉)非常成功,以及(2)它允许更大的模型规格,这乍听起来真的很烦人,但可能允许机器学习实践者创建适合他们数据集的模型。据我所知,深度学习协同过滤的想法最初是在 fastai MOOC 中提出的,我认为这是该领域一个非常令人兴奋的方向!在进入深度学习协同过滤的细节之前,我必须承认,使用示例 MovieLens 数据集,浅层学习模型优于深度学习模型。然而,我认为只要对模型的架构进行足够的修改,并使用正确的数据集(可能是更大的数据集——我只使用了 MovieLens 数据集的一部分),深度学习的协同过滤可以胜过浅层学习模型。

在这里,我将检查一个只有一个隐藏层的模型,但是这些模型可以按照你想要的任何方式定制!注意:我确实尝试添加了更多的层,对于这个数据集,一个隐藏层模型表现得最好。

就像之前一样,我们首先用随机初始化的权重为电影和用户创建一个嵌入矩阵(大小是用户或电影的数量乘以指定数量的因子)。然后,对于每个用户和相应的电影嵌入因子向量,我们连接这些向量(见下图)。在示例脚本中,在这一点(0.05)有一点点下降,以防止过度拟合。然后,我们将级联的嵌入因子向量乘以另一个矩阵,该矩阵的嵌入因子大小为*2(在该示例中,必须是这个,因为这是级联的嵌入向量中的列数)乘以某个其他数(在该示例中,我有 10)。然后,矩阵乘积通过整流线性单位激活函数(ReLU 这是负值被改成 0 的一种花哨说法);这在深度学习中非常常见,会使函数变得非线性。同样,为了防止过度拟合,我们应用更多的压差。然后,我们取矩阵乘积(经过 ReLU 和 dropout ),并将其乘以一个具有其他行数(在本例中也是 10 行)和一列的矩阵。因此,矩阵乘法的输出将是一个数字,这正是我们想要的,因为我们试图预测一个评级。然后,将该预测评级通过 sigmoid 函数(乘以[(最大评级-最小评级)+最小评级]),以使预测值更接近数据集中的实际预测值。这对于单个用户和评级的所有事情都是重复的,就像之前一样,预测值与实际值进行比较,我们的模型中的值通过反向传播的随机梯度下降进行更新(就像任何深度学习问题一样)。

这里需要注意的是,我没有提到任何关于偏差的东西,这是因为 PyTorch 中的线性层已经考虑了偏差,所以我们不必担心它。

同样,正如我之前提到的,深度学习模型比浅层学习模型做得更差,但我相信这个框架是一个有前途的工作路线。如果你想试试这篇文章中提到的例子,看看我的 Github 。我期待听到读者的评论,或许还能看到协同过滤与深度学习的其他用途。

通过熊猫图书馆获取交易数据🐼

原文:towardsdatascience.com/collect-tra…

“A street sign pointing to Wall Street in black and white” by Chris Li on Unsplash

(我的博客里也有这个帖子)

Pandas 是一个开源库,为 Python 编程语言提供高性能、易于使用的数据结构和数据分析工具。Pandas 是最受欢迎的交易策略开发工具之一,因为 Pandas 有各种各样的数据收集、操作和分析工具。

对于相信交易的定量分析师,他们需要访问股票价格和交易量,以便计算技术指标的组合(例如,SMA、BBP、MACD 等)。)进行策略。幸运的是,这些数据可以通过 REST APIs 在许多平台上获得(例如 IEXQuandl )。更幸运的是,pandas_datareader 为您从这些平台收集数据提供了一致的简单 API。在这个故事中,我将介绍如何用熊猫收集股票数据。

先决条件:Python 3

步骤 1:环境设置(虚拟环境)

python3 -m venv tutorial-env
source ~/tutorial-env/bin/activate
pip install panda
pip install pandas_datareader
pip install matplotlib
pip install scipy

(不要忘记激活环境“source ~/tutorial-env/bin/activate”或选择 IDE 中的虚拟 env)

步骤 2:代码(获取数据并转储到 csv 文件)

**import** matplotlib.pyplot **as** plt
**import** pandas_datareader.data **as** web
# collect data for Amazon from 2017-04-22 to 2018-04-22
start = **'2017-04-22'** end = **'2018-04-22'** df = web.DataReader(name=**'AMZN'**, data_source=**'iex'**, start=start, end=end)
print(df)
df.to_csv(**"~/workspace/{}.csv"**.format(symbol))

数据帧的输出

open       high        low    close    volume
date                                                         
2017-04-24   908.680   909.9900   903.8200   907.41   3122893
2017-04-25   907.040   909.4800   903.0000   907.62   3380639
2017-04-26   910.300   915.7490   907.5600   909.29   2608948
2017-04-27   914.390   921.8600   912.1100   918.38   5305543
2017-04-28   948.830   949.5900   924.3335   924.99   7364681
2017-05-01   927.800   954.4000   927.8000   948.23   5466544
2017-05-02   946.645   950.1000   941.4130   946.94   3848835
2017-05-03   946.000   946.0000   935.9000   941.03   3582686
2017-05-04   944.750   945.0000   934.2150   937.53   2418381
...

在本例中,相应的 csv 文件保存在输出目录(~/workspace/AMZN.csv)中。

步骤 3:可视化用 matplotlib 收集的内容

*# select only close column* close = df[[**'close'**]]
*# rename the column with symbole name* close = close.rename(columns={**'close'**: symbol})
ax = close.plot(title=**'Amazon'**)
ax.set_xlabel(**'date'**)
ax.set_ylabel(**'close price'**)
ax.grid()
plt.show()

就是这样!现在您已经下载了用于分析的股票数据。

整个例子

**import** pandas_datareader.data **as** web
**import** matplotlib.pyplot **as** plt

*# collect data for Amazon from 2017-04-22 to 2018-04-22* start = **'2017-04-22'** end = **'2018-04-22'** symbol=**'AMZN'** df = web.DataReader(name=symbol, data_source=**'iex'**, start=start, end=end)
df.index = df.index.to_datetime()
print(df)
df.to_csv(**"~/workspace/{}.csv"**.format(symbol))
*# select only close column* close = df[[**'close'**]]
*# rename the column with symbole name* close = close.rename(columns={**'close'**: symbol})
ax = close.plot(title=**'Amazon'**)
ax.set_xlabel(**'date'**)
ax.set_ylabel(**'close price'**)
ax.grid()
plt.show()

如果你想了解更多关于机器学习的知识,educative.io 中有一系列有用的课程。这些课程包括像基本的 ML,NLP,图像识别等主题。

最后一句话,如果你觉得用 Excel 更舒服,并且有兴趣轻松地分析股票,广墨有一个关于用 Intrinio Excel addin 收集数据的帖子

推荐阅读:

动手机器学习

用于数据分析的 Python:与熊猫、NumPy 和 IPython 的数据角力

对冲基金真正在做什么

我的帖子:

我关于金融和科技的帖子

我的 YouTube 频道

我关于 FAANG 访谈的帖子

从 CRUD web 应用开发到语音助手中的 SDE——我正在进行的机器学习之旅

全栈开发教程:将 AWS Lambda 无服务器服务集成到 Angular SPA 中

全栈开发教程:用运行在 AWS Lambda 上的无服务器 REST API 提供交易数据

全栈开发教程:在 Angular SPA 上可视化交易数据(1)

强化学习:Q 学习简介

使用 Python 收集您自己的 Fitbit 数据

原文:towardsdatascience.com/collect-you…

Python Generated Fitbit Cloud

所以你在圣诞假期有了你的 Fitbit,你也有了一些新年决心。你上网查看仪表盘上的图表,但还是不满意。你想要更多的数据、更多的图表和更多的信息。好了,不多说,因为我将教你如何收集你自己的 Fitbit 数据,只用一点 Python 代码。有了这个教程,你可以得到你难以捉摸的分分钟数据(也称为日内数据),这是你第一次得到 Fitbit 时不容易得到的。

第一步:设置你的账户并创建应用程序

你需要做的第一件事是创建一个 Fitbit 账户。一旦你完成了这些,你就可以去 dev.fitbit.com 的 T4。在“管理”下,转到“注册应用程序”。这将引导您进入一个如下所示的页面:

Application Registration

对于应用网站和组织网站,可以用“http://”或“https://”开头的任何名称命名。其次,确保 OAuth 2.0 应用程序类型为“个人”,因为这是允许我们下载当天数据的关键。最后,确保回调 URL 是“http://127.0.0.1:8080/”,以便让我们的 Fitbit API 正确连接。之后,点击协议框并提交。

注意:根据应用程序的不同,我们可能需要一个额外的步骤来填写表格,以便在这个链接获得我们当天数据的许可。Fitbit 支持个人项目和任何其他非营利研究,因此这些应该已经可以调用,但商业应用程序可能需要更长时间才能获得批准。

之后,您将被重定向到如下页面:

Registered Application

我们将从这个页面中需要的部分是 OAuth 2.0 客户端 ID 和客户端密码。

**第二步:**API

一旦第一步完成,我们的下一步是使用一个 Fitbit 非官方 API 。点击右侧的绿色按钮下载回购文件,然后解压文件。然后,打开命令行,将目录切换到包含解压缩文件的目录,并快速运行“sudo pip install-r requirements/base . txt”。

现在我们终于准备好开始编码了。首先,我们需要导入必要的包,并引入之前的 Client_ID 和 Client_Secret 来授权我们自己。

import fitbit
import gather_keys_oauth2 as Oauth2
import pandas as pd 
import datetimeCLIENT_ID = '22CPDQ'
CLIENT_SECRET = '56662aa8bf31823e4137dfbf48a1b5f1'

使用 ID 和 Secret,我们可以获得授权我们获取数据的访问和刷新令牌。

server = Oauth2.OAuth2Server(CLIENT_ID, CLIENT_SECRET)
server.browser_authorize()ACCESS_TOKEN = str(server.fitbit.client.session.token['access_token'])
REFRESH_TOKEN = str(server.fitbit.client.session.token['refresh_token'])auth2_client = fitbit.Fitbit(CLIENT_ID, CLIENT_SECRET, oauth2=True, access_token=ACCESS_TOKEN, refresh_token=REFRESH_TOKEN)

What the page should look like after authorization and signing in

我们进去了。…但没那么快。我们已经验证了自己的身份,但仍未获得数据。在开始之前,我有一个方便的技巧,可以节省大量的手工输入:许多调用都需要日期格式(YYYY-MM-DD)作为字符串格式。因此,如果您每天收集数据,我们必须每天手动更改该字符串。相反,我们可以导入有用的“datetime”包,让它替我们格式化。

yesterday = str((datetime.datetime.now() - datetime.timedelta(days=1)).strftime("%Y%m%d"))yesterday2 = str((datetime.datetime.now() - datetime.timedelta(days=1)).strftime("%Y-%m-%d"))today = str(datetime.datetime.now().strftime("%Y%m%d"))

第三步:采集数据

我们现在终于可以调用我们的数据了。

fit_statsHR = auth2_client.intraday_time_series('activities/heart', base_date=yesterday2, detail_level='1sec')

Heart Rate Data

虽然这些数据对我们来说是可读的,但它还不能保存在我们的电脑上。以下代码读取字典格式并遍历字典值——在将两者组合成一个熊猫数据帧之前,将各自的时间和值保存为列表。

time_list = []
val_list = []for i in fit_statsHR['activities-heart-intraday']['dataset']:
    val_list.append(i['value'])
    time_list.append(i['time'])heartdf = pd.DataFrame({'Heart Rate':val_list,'Time':time_list})

Our Newly Created Fitbit pandas data frame

现在终于可以在本地保存我们的数据了。考虑到未来,我们将一次一个数据地调用我们的数据(1 个文件= 1 天),所以我们希望有一个良好的命名约定,以防止任何未来的混淆或覆盖数据。我的首选格式是 heartYYYMMDD.csv。以下代码获取我们的心脏数据帧,并将其作为 csv 文件保存在/Downloads/python-fitbit-master/Heart/目录中。

heartdf.to_csv('/Users/shsu/Downloads/python-fitbit-master/Heart/heart'+ \
               yesterday+'.csv', \
               columns=['Time','Heart Rate'], header=True, \
               index = False)

Small army of heart rate files

但是等等!还有更多!

阅读文档,我们还可以收集很多其他数据,比如:

我们的睡眠日志数据:

"""Sleep data on the night of ...."""fit_statsSl = auth2_client.sleep(date='today')
stime_list = []
sval_list = []for i in fit_statsSl['sleep'][0]['minuteData']:
    stime_list.append(i['dateTime'])
    sval_list.append(i['value'])sleepdf = pd.DataFrame({'State':sval_list,
                     'Time':stime_list})sleepdf['Interpreted'] = sleepdf['State'].map({'2':'Awake','3':'Very Awake','1':'Asleep'})
sleepdf.to_csv('/Users/shsu/Downloads/python-fitbit-master/Sleep/sleep' + \
               today+'.csv', \
               columns = ['Time','State','Interpreted'],header=True, 
               index = False)

Sleep Log

或者我们的睡眠总结:

"""Sleep Summary on the night of ...."""fit_statsSum = auth2_client.sleep(date='today')['sleep'][0]ssummarydf = pd.DataFrame({'Date':fit_statsSum['dateOfSleep'],
                'MainSleep':fit_statsSum['isMainSleep'],
               'Efficiency':fit_statsSum['efficiency'],
               'Duration':fit_statsSum['duration'],
               'Minutes Asleep':fit_statsSum['minutesAsleep'],
               'Minutes Awake':fit_statsSum['minutesAwake'],
               'Awakenings':fit_statsSum['awakeCount'],
               'Restless Count':fit_statsSum['restlessCount'],
               'Restless Duration':fit_statsSum['restlessDuration'],
               'Time in Bed':fit_statsSum['timeInBed']
                        } ,index=[0])

Sleep Summary

这就是开始收集所有 Fitbit 数据所需的全部内容!所以,再玩一会儿,阅读 Python Fitbit 文档,完全沉浸其中,找到出路,看看你的心脏数据有多棒。如果你想知道如何利用这些数据,这里有一个链接指向我对自己心脏数据的分析。

感谢您花时间阅读我的教程,并随时在 LinkedIn 上发表评论或联系,因为我将发布更多关于数据挖掘和数据科学的教程。

参考资料:

  1. Orcas Fitbit API Github
  2. Python-Fitbit 文档
  3. 官方 Fitbit API 文档
  4. Fitbit 日内访问表
  5. 个人 Github 与所有代码
  6. 熊猫数据框文档

收集数据科学备忘单

原文:towardsdatascience.com/collecting-…

正如你可能已经知道的,我已经专门为那些刚刚开始接触数据科学的人或者那些在处理数据科学问题时需要额外帮助的人制作了 Python 和 R 备忘单。

现在,您可以在 DataCamp 社区的一个地方找到它们。

你可以在这里 找到所有的小抄

概括地说,这些是迄今为止我们已经制作并与社区分享的数据科学备忘单:

基础知识

数据操作

机器学习、深度学习、大数据

数据可视化

IDE

尽情享受,随意分享!

PS。您是否看到了另一份想要推荐的数据科学备忘单?让我们在这里了解

使用 CoreML 的碰撞检测系统

原文:towardsdatascience.com/collision-d…

最近在 WWDC 17,苹果推出了 CoreML 和 ARKit。这开启了无数的可能性,让数以百万计的人可以通过他们的手机来设计令人惊叹的应用程序。利用这些新技术,我们想为什么不设计一个可以在日常通勤中帮助每个人的应用程序。经过一番头脑风暴,我们决定建立一个驾驶辅助 dashcam 应用程序。

我们计划设计的驾驶员辅助应用程序将由一个碰撞检测管道组成,该管道将检测驾驶员是否会撞到车辆前方的障碍物。该应用程序将不断从相机中获取帧,检测每帧中的对象,找到每个对象的深度,传感器融合以计算车辆的速度和碰撞时间。

物体检测:

从上面的讨论中,我们可以理解,解决这个问题的第一个里程碑是使对象检测算法在移动电话上工作。理想的算法应该以最高的精度预测障碍物,几乎实时运行,并且没有假阳性。基于这些要求,解决对象检测问题的最佳方法是使用深度学习算法。

以对象检测问题而闻名的深度学习算法有 R-CNN、快速 R-CNN、更快 R-CNN、YOLO、YOLO 9000、SSD、MobileNet SSD。

经过一个月的头脑风暴和编码,我们使用 CoreML 框架实现了 YOLO,达到了目标检测的里程碑。

Object Detection Prototype

我们在下面的博客中记录了我们是如何完成这项任务的— 链接

深度计算:

障碍物的深度可以定义为障碍物距离摄像机的距离。

Depth (or) Distance of obstacle from car

一般来说,深度可以通过一些特殊的硬件立即计算出来,这些硬件通常被称为 RGBD 相机。现在流行的消费级 RGBD 相机是微软的 Kinect (Xbox)。但另一方面,消费者手机没有深度传感器。它们只是 RGB 相机(又称单目视觉)。我们怎么计算深度呢?

为了使用单目摄像机计算与汽车的距离,我们可以遵循以下策略之一

  1. 时间方法——根据图像中运动的时间顺序计算深度(例如:视觉里程计)
  2. 每帧方法-其中在当前帧中计算的深度独立于先前的帧(例如:三角测量技术,或深度学习技术等)。)

在我们的例子中,我们现在选择了每帧三角测量法,并提出了一些数学公式,找到了计算汽车深度的方法。用我们的公式计算的深度在米的尺度上是精确的,但在厘米的尺度上就不那么精确了。因此,我们决定保持三级(安全、中等和危险)碰撞检测报警系统,而不是非常精确的深度精度。

传感器融合:

一旦我们从上述阶段计算出深度,我们将使用传感器融合来组合手机中的各种传感器,以获得我们汽车的速度。然后,我们在简单的运动学公式中使用它来计算特定帧中的 T.T.C(碰撞时间)。在研究人类对警报的平均反应时间的基础上,我们战略性地将 T.T.C .划分为警报系统的三个阶段。

此外,假设用于检测汽车的算法是鲁棒的并且视野良好,那么我们很有可能在一帧中检测到许多汽车。在这种情况下,我们可能需要找到一辆我们将来可能会撞上的车。通过传感器融合,我们通过图像处理技术稳健地计算我们汽车的轨迹,将问题从' n 辆汽车归结为 1 辆汽车,然后我们计算那辆特定汽车的 T.T.C。

Trajectory of car estimation from sensor fusion and T.T.C

将这些放在一起,我们已经准备好了管道的基本工作演示,可以在下面的视频中看到。

Demo (Testing Phase)

未来工作:

在这篇博客中,我们展示了如何利用 CoreML、计算机视觉和传感器融合的力量来创建一个能够真正帮助人们日常通勤的应用程序。我们正在积极工作,使用深度学习技术或鲁棒的视觉惯性里程计技术来改进检测到的车辆的深度估计。此外,我们正在计划是否可以使用 iPhone 7 Plus(窄基线相机系统)中提供的两个相机的功率来估计深度。根据从两个不同视点(或两个相机)捕获的图像来估计场景中对象的深度的区域被称为“来自立体的深度”。这个领域是受人类视觉系统的启发而产生的,下图概括了我试图解释的内容。

Depth estimation of objects through stereo vision

感谢您阅读本博客,并请留下您对我们工作的评论/看法。我还要感谢苹果公司的 CoreML 团队,是他们惊人的 API 让这一切成为可能。

口袋妖怪图像的均值聚类

原文:towardsdatascience.com/color-diffe…

Developing strategies to group similar Pokemon Images

探索性算法是在数字属性上明确定义的,通过提供描述性统计的摘要,然后是可视化,如直方图、散点图和其他一些可能与问题相关的内容。然而,简单的摘要更容易与图像数据集混淆。

图像数据聚类,也称为图像检索,有许多有趣的算法,如使用自动编码器来获得图像相似性。然而,这些算法很难实现,并且需要一些时间来训练。本文的目的是尝试一个简单的概念,根据与平均图像的距离对相似图像进行分组。

在浏览 Kaggle 内核时,我看到了一个非常有趣的想法,即使用“平均图像”对国际足联球员数据库中的人脸图像进行聚类:

在面部数据集上,平均面部图像的概念是相当直观的,然而,我怀疑这将如何转化为其他数据集。

尽管如此,我还是开始了这个项目,来看看在一个由口袋妖怪图像组成的数据集上,普通的图像会是什么样子。我最初的反应是,这种方法实现起来比构建卷积自动编码器简单得多,因此,如果这能产生有意义的聚类,它将是有用的。

在本文中,我们将探索一个包含 150 个原始口袋妖怪图像的数据集,并根据它们与平均图像的差异对它们进行聚类。本文将进一步探讨均值图像的使用,以及如何使用它在图像数据中形成聚类。

图像聚类的一个潜在应用可能是改进数据扩充算法。图像聚类对于改进用于添加数据的生成对抗网络(GANs)的使用非常有用。我们将从本文中导出的集群中进行采样,而不是从整个数据集中进行采样。

以下是我们将遵循的形成口袋妖怪图像集群的工作流程:

# Load Images
# Calculate Mean Image
# Calculate Distance from Mean to each Image
# Sort by Distance
# Select Clusters based on Distance Quantiles

我已经在 Github 上传了我在这里使用的口袋妖怪图片:

所有代码都是用 Python 写的

# Load Pokemon Imagesfrom PIL import Image
import numpy as np
import os
from random import shuffle
from tqdm import tqdm
import matplotlib.pyplot as pltDIR_NAME = './Pokemon'
IMG_SIZE = 100pokemon = []
for img in tqdm(os.listdir(DIR_NAME)):
    path = os.path.join(DIR_NAME, img)
    if "DS_Store" not in path:
        img = Image.open(path)
        img = img.convert('L')
        img = img.resize((IMG_SIZE, IMG_SIZE), Image.ANTIALIAS)
        pokemon.append(np.array(img))

print(type(pokemon[0]))
print(pokemon[0].shape)
plt.imshow(pokemon[0], cmap = 'gist_gray')
plt.show()

现在我们已经加载了图像,我们想要计算整个数据集的平均图像:

# Calculate Mean Image
sums = np.zeros((100, 100))
for x in range(len(pokemon)):
    for i in range(100):
        for j in range(100):
            sums[i][j] += pokemon[x][i][j]
#print(sums)
for idx in range(100):
    for idy in range(100):
        sums[idx][idy] /= len(pokemon)
#print(sums)
plt.imshow(sums, cmap='gist_gray')
plt.show()

平均图像:

前 5 幅图像的平均图像:

# Define Distance functiondef SquaredDistance(x, y):
    return (x-y)**2
def ImageDistance(img1, img2):
    distance = 0
    for i in range(100):
        for j in range(100):
            distance += SquaredDistance(img1[i][j], img2[i][j])      
    return distance

我们将使用距离的平方来计算每个口袋妖怪与平均口袋妖怪图像的距离。

# Calculate Distance from Mean Image to each Imagemean_image = sums
Distance_Dict = {}
for i in range(len(pokemon)):
    Distance_Dict[i] = ImageDistance(mean_image, pokemon[i])

本词典采用以下形式:

0: distance from image 0 to mean image
1: distance from image 1 to mean image
...
150: distance from image 150 to mean image

现在,我们根据这个排序的分区对字典和集群进行排序:

import operator
sorted_d = sorted(Distance_Dict.items(), key=operator.itemgetter(1))
print(sorted_d)

最后,让我们想象一下每个集群中的一些图像,看看我们在这里做了什么…

总之,使用均值距离来形成聚类并没有什么好处。虽然它在基于图像的集中暗度对图像进行聚类方面做得很好,但它没有捕捉到我们在图像聚类中想要的任何视觉相似性(除了第一组中的 Diglet 和 Dugtrio)。我很高兴能继续研究图像检索和相似性技术,以形成更有意义的基于除颜色密度之外的视觉特征的图像簇,感谢阅读!

CShorten

Connor Shorten 是佛罗里达大西洋大学计算机科学专业的学生。对软件经济学、深度学习和软件工程感兴趣。

图像中的颜色识别

原文:towardsdatascience.com/color-ident…

机器学习应用

Photo by Henry Lorenzatto on Unsplash

我最近开始阅读如何用 Python 处理图像。当我偶然发现 OpenCV 允许用 Python 导入和处理图像时,我开始想知道是否可以使用机器学习从这些图像中提取信息并以某种方式使用。

我们都知道,我们可以基于某些过滤器进行在线搜索,其中一个过滤器是颜色。我受到启发,实际上编写了代码,可以从图像中提取颜色,并根据这些颜色过滤图像。

在本文中,我解释了我如何理解 OpenCV 的基础知识,使用 KMeans 算法从图像中提取颜色,并基于颜色的 RGB 值从图像集合中过滤图像。完整的笔记本可以在这个资源库中找到。我点击了sample_image.jpg,文件夹images中的其他 5 张图片取自 Unsplash

导入库

我们导入的基本库包括matplotlib.pyplotnumpy。为了提取计数,我们将使用集合库中的Counter。要用 OpenCV,我们就用cv2KMeans算法是sklearn's cluster子包的一部分。为了比较颜色,我们首先使用rgb2lab将它们转换到 lab,然后使用deltaE_cie76计算相似度。最后,为了在从目录中读取文件时组合路径,我们导入了os

使用 OpenCV

Sample Image

为了读取任何图像,我们使用方法cv2.imread()并指定作为 Numpy 数组导入笔记本的图像的完整路径。然后我们可以使用 pyplot 的方法imshow()来绘制它。

数组的形状是(3456,4608,3)。前两个值匹配图像的像素。第三个值设置为 3,因为每个像素表示为三种颜色(红色、蓝色和绿色)的组合。

Image read by OpenCV

图像的颜色看起来有点不对。这是因为,默认情况下,OpenCV 按照蓝绿色红色(BGR)的顺序读取图像。因此,为了查看实际的图像,我们需要将渲染转换为红绿蓝(RGB)。

方法cvtColor允许我们将图像渲染转换到不同的颜色空间。为了从BGR色彩空间移动到RGB,我们使用方法cv2.COLOR_BGR2RGB

RGB Colors set for the image

在某些情况下,我们可能想要黑白图像。在这种情况下,我们可以将图像表示为灰色。我们现在使用转换空间作为cv2.COLOR_BGR2GRAY,并用色图显示输出作为gray

Gray Image

我们还可以将图像调整到给定的尺寸。我们使用cv2提供的方法resize。第一个参数是我们要调整大小的图像,第二个参数是括号内定义的宽度和高度。

Resized image to 1200 x 600

现在让我们来识别图像中的颜色,并将顶部的颜色显示为饼图。

颜色识别

RGB 到十六进制转换

我们将首先定义一个将RGB转换为hex的函数,这样我们就可以将它们用作饼图的标签。

在读取RGB空间中的颜色时,我们返回一个字符串。{:02x}简单显示相应颜色的十六进制值。

读取 RGB 颜色空间中的图像

接下来,我们定义一个方法,它将帮助我们在RGB空间中把一个图像放入 Python。

我们提供图像的路径作为参数。首先,我们使用imread读取文件,然后在返回之前改变它的颜色空间。

从图像中获取颜色

我们现在将完整的代码定义为一个方法,我们可以调用该方法从图像中提取顶部的颜色,并将它们显示为饼图。我将该方法命名为get_colors,它有 3 个参数:

  1. image:我们希望提取颜色的图像。
  2. number_of_colors:我们要提取的总颜色。
  3. show_chart:决定是否显示饼图的布尔值。

为了更好的理解,我们来分解一下这个方法。

首先,我们将图像调整到尺寸600 x 400。不需要将其调整到较小的尺寸,但我们这样做是为了减少像素,从而减少从图像中提取颜色所需的时间。KMeans 期望输入是二维的,所以我们使用 Numpy 的 reshape 函数来整形图像数据。

KMeans 算法根据提供的分类计数创建分类。在我们的例子中,它将形成颜色的集群,这些集群将是我们的顶部颜色。然后,我们在同一幅图像上用fitpredict将预测提取到变量labels中。

我们使用Counter来计算所有标签的数量。为了找到颜色,我们使用clf.cluster_centers_ordered_colors遍历 count 中出现的键,然后将每个值除以255。我们可以直接将每个值除以 255,但是这样会打乱顺序。

接下来,我们得到hexrgb颜色。正如我们之前将每种颜色除以 255 一样,我们现在在寻找颜色时再次将其乘以 255。如果show_chartTrue,我们绘制一个饼图,每个饼图部分使用count.values()定义,标签为hex_colors,颜色为ordered_colors。我们最终返回了rgb_colors,我们将在后面的阶段使用它。

瞧啊。!我们都准备好了!!

让我们把这个方法叫做get_colors(get_image(‘sample_image.jpg’), 8, True),我们的饼状图显示了图像的前 8 种颜色。

Identified colors

这为许多高级应用打开了大门,例如在搜索引擎中搜索颜色,或者寻找一件有某种颜色的衣服。

我们刚刚确定了图像中存在的 8 种主要颜色。让我们尝试实现一个搜索机制,它可以根据我们提供的颜色过滤图像。

使用颜色搜索图像

我们现在将深入研究基于我们想要的颜色过滤一组五个图像的代码。对于我们的用例,我们将提供颜色绿色蓝色黄色的 RGB 值,并让我们的系统过滤图像。

获取所有图像

图像在文件夹images中。我们把COLORS定义为颜色的字典。然后,我们读取该文件夹中的所有图像,并将它们的值保存在images数组中。

显示所有图像

我们首先使用下面提到的for循环显示文件夹中的所有图像。

我们将该区域分割成与图像数量相等的支线剧情。该方法采用的参数为行数= 1列数=所有图像,即在我们的例子中为 5 以及索引

All images in the ‘images’ folder

用颜色匹配图像

我们现在定义一个方法match_image_by_color来过滤所有匹配所选颜色的图像。

我们首先使用之前定义的方法get_colorsRGB格式提取图像颜色。我们使用方法rgb2lab将选择的颜色转换成我们可以比较的格式。for循环简单地遍历从图像中获取的所有颜色。

对于每种颜色,循环将其更改为lab,在迭代中找到所选颜色和该颜色之间的差值(基本上是差异),如果该差值小于阈值,则选择该图像与该颜色匹配。我们需要计算增量,并将其与阈值进行比较,因为每种颜色都有许多阴影,我们无法始终将所选颜色与图像中的颜色完全匹配。

通过说绿色,用户可以指浅绿色、绿色或深绿色。我们需要扫描所有的可能性。

如果我们从一幅图像中提取 5 种颜色,即使其中一种颜色与所选颜色匹配,我们也会选择该图像。threshold基本上定义了图像和所选颜色的差异。

让我们考虑这样的情况,我们试图找到绿色的图像。如果阈值太高,我们可能会在搜索中看到蓝色图像。类似地,另一方面,如果阈值太低,那么绿色甚至可能不匹配包含深绿色的图像。这都是基于手头情况的需要,我们可以相应地修改这些值。我们需要仔细设置threshold值。

显示选定的图像

我们定义了一个函数show_selected_images,它遍历所有图像,调用上面的函数根据颜色过滤它们,并使用imshow将它们显示在屏幕上。

我们现在将简单地调用这个方法,并让它绘制结果。

过滤结果

我们按如下方式调用该方法。我们将变量selected_color替换为绿色的COLORS['GREEN'],蓝色的COLORS['BLUE'],黄色的COLORS['YELLOW']。我们设置阈值为60,从图像中提取的总颜色为5

寻找绿色

Search for ‘GREEN”

寻找蓝色

Search for ‘BLUE’

寻找黄色

Search for ‘YELLOW’

结论

在本文中,我们讨论了使用 KMeans 算法从图像中提取颜色,然后使用该算法基于颜色搜索图像的方法。

希望你喜欢我的作品。请分享你的想法和建议。

机器学习算法的颜色参数

原文:towardsdatascience.com/color-param…

说到机器学习,你不能低估数据工程的重要性。

在为我的项目准备数据时,我遇到了几个挑战,我正在开发一种机器学习算法,根据影响彩色宝石价值的参数来预测它们的价格。挑战之一是颜色。

颜色是宝石的一个极其重要的特性,因为它对宝石的价值有很大的影响,将颜色参数正确地输入系统是至关重要的。

广泛使用的用于描述宝石颜色的模型是 GIA(美国宝石学院)提出的模型。它通过三个参数来描述每种颜色——色调、色调和饱和度。

色调定义了宝石的暗度或明度,可以很容易地用数字表示(GIA 建议从 2 到 8 的整数范围,较大的数字对应较暗的色调)。

这同样适用于饱和度,其范围从较弱的饱和度到生动的饱和度。它也可以映射到一个数字范围(1 到 8,较大的数字对应于更鲜明的饱和度)。

GIA® Hue wheel. ©GIA

当你开始使用色调时,问题就出现了。标准 GIA 色调色轮由 31 个描述彩色宝石的色调名称组成。对于宝石专业人员来说,这是一种很好的颜色视觉表现,在他们的日常工作中非常实用。但是为了将色调参数传递给算法进行进一步分析,我们需要用数字来表示它。

糟糕的是,如果你只是简单地将色调名称映射到 1 到 31 的数字(对于你的特定任务,你也可以考虑将色调映射到 0 到 360 的角度值),你会丢失非常重要的关于颜色的实际接近度的信息,这些信息位于数字范围的最开始和最末端。

例如,如果我们从映射到 1 的“红色”开始,我们以映射到 31 的名为 slpR 的“略带紫红色”的颜色结束。所以,这两种在现实中非常接近的颜色在机器学习算法看来会完全不同。算法的这种颜色错误表示对于整体成功是至关重要的,必须避免。

那么,我们如何将色轮中的色调值映射到一个数字表示中,而不会丢失关于颜色接近度的重要信息呢?

乍一看,这里可以应用的一个可能的变通方法是用两个参数定义色调值,这两个参数可以作为 Sin 和 Cos 函数来计算。看看这个图表。

Replacing one Hue parameter with Sin and Cos seems to solve the problem. But this is not good!

这样,在色轮上具有接近 0 度或接近 360 度的色调的颜色将由数值接近的成对 *Sin(色调)*和 *Cos(色调)*呈现。答对了,我们已经解决了问题!或者我们有吗?

等等,我们现在已经向算法传递了 4 个描述颜色的参数——色调、饱和度、Sin(色调)、Cos(色调)!因此,我们增加了模型的维度,而我们希望尽可能地减少维度以避免数据稀疏。因此,这种方法似乎不是最佳解决方案。

换句话说,我们来思考这个问题。我们在这里试图实现的是在 3D 空间中找到这样一种颜色位置的数字表示,它将保留关于该空间中实际颜色的接近度的信息。

HSL color model based on polar coordinate system

用色调、色调和饱和度操作的颜色模型通常被称为 HSL 颜色模型 (L 代表亮度,在我们的例子中是色调)。HSL 模型基于柱坐标系,而柱坐标系本身是将极坐标系统扩展到三维的结果。

正如我们已经了解的,极坐标系统的缺点是当用数字表示边缘颜色时,不能解决它们的接近性。但是,如果我们研究另一种流行的坐标系类型——笛卡尔坐标系,我们会发现这种类型的系统对于进一步的机器学习目的来说没有这种缺点。

A Cartesian coordinate system

有几种基于笛卡尔坐标系的颜色模型,RGB 就是其中之一。在 RGB 中,我们通过对应于 RGB 3D 颜色空间中三个轴上的坐标的三个数字来寻址颜色。如果我们写下上例中颜色“红色”(色调= 1)和颜色“略带紫红色”(色调= 31)的坐标(r,g,b ),我们会看到这两种颜色的 r g b 值非常接近。Vuala!我们的算法将理解这两种颜色彼此接近,它现在可以正常工作了。非常重要的是,我们避免了增加模型的维数,因为我们仍然只用三个参数来描述颜色。

最后一点是在将颜色信息传递给算法之前,将我们的颜色从 HSL 颜色模型转换为 RGB。这可以通过使用 Python 中的colorsys模块非常容易地实现。本模块定义了colorsys**功能。hls _ to _ rgb(h,l,s) 将颜色从 HLS 坐标转换到 RGB 坐标。

这些是我从这个案例中得出的结论:

  • 当心机器学习系统的极坐标系统的数字表示的限制
  • 选择合适的颜色模型,并在输入算法之前转换您的颜色数据
  • 小心导致维度增加的快速解决方案

这个案例是我现实生活项目Gemval(【www.gemval.com】T2)的一部分——基于机器学习算法的在线宝石鉴定服务。

使用整数规划的彩色地图

原文:towardsdatascience.com/colour-maps…

运筹学有很多很酷很实用的应用,比如供应链优化(我的最爱!)、乘务调度、车辆路径和投资组合优化。

本文讨论了这些酷运筹学应用之一。我们将使用一种称为整数规划(IP)的技术来解决地图着色难题。该难题指出,给定一个带有边界实体(例如国家、州、县)的地图,为每个实体着色所需的最少颜色数是多少,使得没有两个相邻实体具有相同的颜色。

这个地图着色问题对应于运筹学中一个著名的问题,称为顶点着色问题。在顶点着色问题中,给我们一个无向图,要求我们给它的顶点分配颜色,使得没有两个相连的顶点具有相同的颜色,当然,使用尽可能少的颜色。地图着色和顶点着色之间的对应是非常明显的,这使得它成为“商业问题”如何映射到“一般运筹学问题”的一个很好的例子,正如我在以前的文章运筹学的大图景中所讨论的。

下图描述了一般流程。

  • 选择未着色的地图
  • 将地图建模为无向图
  • 用你最喜欢的算法给无向图上色
  • 将彩色无向图转换回相应的地图

我写了两个 Python 包,顶点颜色解算器地图绘制器,它们将帮助我们用大约 10 行代码完成这个过程。让我们浏览一下代码。

首先,您需要按照 Github 存储库上的说明安装软件包。

成功安装软件包后,导入以下类和函数

from vertex_colorer.solver import Solverfrom map_grapher.core import load_map_data, plot_map, color_map,\save_to_file, build_adjmat

map_grapher 加载的函数允许你选择一个地图,将其建模为一个无向图,并使用一个彩色无向图给你的地图着色。该软件包目前支持美国所有州的县地图以及一个国家地图。

在这个演示中,我将选择亚利桑那州作为一个例子。让我们加载地图

state = load_map_data('Arizona')

状态变量保存从 geojson 文件加载的地图数据。接下来,我们将使用 plot_map 函数绘制地图

figure = plot_map(state, map_title='Arizona map')

如果您使用 Jupyter 笔记本,您可以直接从图形查看地图,如果您在命令行上,您可能希望将图形保存到文件中

save_to_file (figure, 'arizona_black_and_white_map.png')

不错!现在下一步是将这个地图建模为一个无向图。我们可以使用下面的代码做到这一点

matrix = build_adjmat(state)

build_adjmat 函数获取地图数据并将其转换为邻接矩阵,这是我们将用来表示无向图的数据结构。邻接矩阵看起来像这样

[[1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
 [0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1],
 [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1],
 [1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0],
 [1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
 [0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1],
 [0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0],
 [0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0],
 [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
 [0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0],
 [0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0],
 [0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1],
 [1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0],
 [0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1],
 [0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1]]

每个元素代表无向图的两个顶点之间的一条边。如果有边(即两个顶点相连,或者从业务问题的角度来看,对应的地图实体相邻),则值为 1,否则为 0。

我们现在可以将这个矩阵传递给我们的求解器

solver = Solver(matrix)

求解器被实例化并保存无向图。为了给图表上色,你需要选择一种方法来使用。这里我使用术语“方法”而不是“算法”,因为它们并不完全相同。例如,我们将在本演示中使用的 IP 求解器将无向图本身建模为一个整数程序,然后使用分支算法(以及其他方法)来求解该模型,然后将其转换回无向图。或者,我们可以使用动态规划算法或贪婪启发式算法直接在无向图上操作。

让我们要求求解器使用 IP 给无向图着色

solver.solve('IP')

瞧啊。我们完了。可以使用解决方案属性访问该解决方案。

solver.solution

这将为我们提供以下数据结构

[[0, 0], [1, 1], [2, 3], [3, 1], [4, 2], [5, 0], [6, 2], [7, 3], [8, 3], [9, 3], [10, 3], [11, 0], [12, 2], [13, 1], [14, 2]]]

列表中的每一对都有两个值,第一个是顶点标识符(索引),第二个是指定的颜色。

最后,我们使用颜色映射函数将这个解决方案传递给业务层面的问题

colored_map = color_map(state, solver.solution)

我们按照同样的步骤绘制地图并保存到文件中

fig = plot_map(colored_map, map_title='map of Arizona')save_to_file (fig, 'arizona_colored_map.png')

这是完整的脚本

#!/usr/bin/env python from vertex_colorer.solver import Solverfrom map_grapher.core import load_map_data, plot_map, color_map,\save_to_file, build_adjmat SELECTED_MAP = 'Arizona' if __name__=="__main__": state = load_map_data(SELECTED_MAP) figure = plot_map(state, SELECTED_MAP+'_bw') matrix = build_adjmat(state) solver = Solver(matrix) solver.solve('IP') colored_map = color_map(state, solver.solution) fig = plot_map(colored_map, map_title=SELECTED_MAP+'_colored') save_to_file (fig, 'arizona_colored_map.png')

你应该能够自己使用代码并给一些地图上色。请注意,根据您选择着色的州,求解器运行时间会有所不同。在我自己试验了几个州之后,我建议你从没有那么多县的州开始,然后一步步往上。您会注意到,运行时间不是县(顶点)数量的线性函数,而是连接密度的线性函数。当你尝试管理加州时,你会看到这一点(祝你好运!).

到目前为止,我只实现了 IP 解算器。下一步是实现其他求解器,如约束编程、动态编程和贪婪试探法,看看它们与 IP 相比如何。完整的代码和更详细的解释可以在这个要点中找到。如果你有任何问题,请尽情享受并随时给我写信!

组合优化:使用 Google 的 OR 工具从理论到代码

原文:towardsdatascience.com/combinatori…

在这篇文章中,我将考虑一个来自组合优化的问题,这个问题可以理解为一般图上的约束优化。这让我有机会以一种比通常只涉及神经网络更普遍的方式介绍复杂网络的概念和语言。这里开发的概念将用于神经网络模型物理学的后续系列。

我不会从最一般的角度来讨论网络理论,我将在这里专注于解决一个特定的问题,从建立数学模型到使用 Google 的运筹学(或工具)库对其进行数值实现。最后,我将讨论组合优化的一些应用以及它与统计力学和计算机科学的联系。这篇文章本质上是技术性的,我决定不回避方程,而是一步一步地引导你通过数学。希望这能引发你的好奇心!

如何用最少的切口在饥饿的孩子中分享巧克力棒?

让我们开始定义我们想要解决的问题。有长度不等(整数)的 m 巧克力棒和想要不同数量巧克力的 n 饥饿儿童。你可以切巧克力棒,目标是确保每个孩子都能得到他们想要的量。写一个程序来分配巧克力,这样你可以切得最少。

**解决方案:**我决定解决问题的方式是把它映射成一个网络优化问题。我们有两个长度为 m 的输入向量 BC

表示巧克力棒的数量。每个酒吧有 b1,b2 …可用的巧克力单位

n 是孩子的数量,每个孩子想要 c1,c2,…块巧克力。我们定义了全连接(FC)有向网络(意味着连接仅从源节点到漏节点)。下图是 B = (2,5,7,3)和 C = (3,2,6,1,2)的问题实例。

请注意,连接有一个箭头来定义它们的方向。在数学上,这些连接被编码在一个连接矩阵中

其条目指定从源节点 i 移动到漏节点 j 的单元数量。我们为每个连接分配一个成本

我们希望优选完美匹配(例如,示例中的 2 — >2 和 3 — >3),即零成本。这意味着供应和需求节点之间的“距离”必须为零。将欧几里德距离作为图上的自然度量,我们定义:

此时我们需要定义系统的目标函数,或者用物理学家的语言来说,问题的哈密顿量:

第二个等式中的表达式是哈密顿量的“矢量化”实现;我们已经定义了

作为长度为 m 的单位向量,而 Ic 的长度为 n 。注意,矩阵 MX 之间的乘积是逐元素的。这是最小成本问题的哈密顿量;通过最小化哈密顿量,我们选择成本较低的矩阵元素 X 。我们现在推测最小截形对应于图上最小长度(即成本)的路径。有两个约束要强加:一个关于“当前”守恒,另一个关于 X 的元素是正定的。在节点之间流动的两股“电流”表示:

如果我们将通过网络的“通量”定义为

和偏置向量

然后我们需要加强元素方面的“巧克力保护”约束:

最后,我们需要强制连接矩阵的矩阵元素都是正的:对于[1,m]中的所有 i 和[1,n]中的 j ,X >0。这个问题可以用拉格朗日形式重新描述为:

其中我们引入了两个拉格朗日乘数λ和μ来加强约束。注意不等式约束需要遵循卡鲁什-库恩-塔克条件[2]: X > 0, mu > 0 和

上述示例的解决方案如图所示。

切割对应于每一行 X 上非零元素的数量。我们认为一个切割是一个分叉,所以在下面的例子中,单元 2(自下而上计数)用一个切割将原来的 5 个单元一分为二。因此,切割对应于在每一行 X 上具有 l > 1 个非零矩阵元素。你可以在我的 GitHub 上找到解决问题的 python 代码,连同一步一步的讲解,或者下面随便看看。我使用过谷歌的约束优化库,我发现相对于 Scipy 的优化工具来说,它更容易使用,也更有效。因此,如果您对学习如何使用这些库感兴趣,您会发现这里考虑的简单问题是解决更复杂问题的有用教程。另请注意,OR tools 已经实现了一个最小成本函数,您可以调整该函数来解决上述问题。如果你不想从头开始做这件事,这是一个有效的选择…但是乐趣在哪里呢?

最小费用问题是组合优化中的经典问题之一;左图给出了这个问题的一个更经典的表述:

工厂(节点 1)生产一定数量的货物,需要通过不同的路线运送到目的地(节点 4 和 5)。每条路线都有相关的成本和可以运输的货物的最大容量。这个问题可以按照上述步骤连同对矩阵元素边缘连接矩阵的进一步限制来解决,

其中 l 是每个边的最大容量。

从这里去哪里

在过去的几十年里,物理学家被*随机、*组合优化问题所吸引,因为它们与统计力学有关,见参考文献。[1,3].这些问题与一类被称为自旋玻璃的模型有关,这类模型对应于具有随机耦合的伊辛模型。这些模型展示了几个有趣的特征,并且是几个神经网络模型的灵感来源。

在下面的帖子里会有更多关于这个的内容!目前,我只想展示巧克力分配问题是如何在随机输入/输出关系的统计力学问题中被重新铸造的。关联吉布斯测度和约束配分函数:

请注意,该问题的哈密顿量是无量纲的,因此可以认为逆“温度”在 h 中被重新调整。如果β是随机变量,我们需要对其分布的自由能进行平均

其中最后一个表达式是复制的分区函数。如何解决这类问题将是以后文章的主题。

一些有用的参考资料:

[1] M. Mezard,A. Montanari,信息、物理和计算,牛津大学出版社(2009)

[2] C. M. Bishop,模式识别与机器学习,Springer (2006)。

[3] M .梅扎德,g .帕里西,《形体快报》杂志,1985 年,46 期(17),第 771–778 页

理论物理学家,从事复杂系统和量子突现现象的研究。我目前在人工智能领域工作,尤其对神经网络、它们与物理学的联系以及相关的基础问题感兴趣。查看 Mirco Milletari 的所有帖子

发布2018 年 1 月 28 日 2018 年 1 月 30 日

原载于 2018 年 1 月 28 日 equat10ns.wordpress.com

结合 LDA 和词嵌入的主题建模

原文:towardsdatascience.com/combing-lda…

“Business newspaper article” by G. Crescoli on Unsplash

潜在狄利克雷分配(LDA)是一种经典的主题建模方法。主题建模是无监督学习,目标是将不同的文档分组到同一个“主题”中。

一个典型的例子是将新闻聚集到相应的类别,包括“金融”、“旅游”、“体育”等。在单词嵌入之前,我们可能大部分时间使用单词袋。然而,在 Mikolov 等人于 2013 年引入 word2vec(单词嵌入的例子之一)后,世界发生了变化。Moody 宣布了 lda2vec,它将 lda 和词嵌入结合起来解决主题建模问题。

看完这篇文章,你会明白:

  • 潜在狄利克雷分配
  • 单词嵌入
  • lda2vec

潜在狄利克雷分配

Photo: pixabay.com/en/golden-g…

LDA 在主题建模领域很有名。基于单词使用的文档聚类。简单来说,LDA 使用单词袋作为聚类的特征。详细情况,你可以看看这个博客

单词嵌入

Credit: pixabay.com/en/books-st…

单词嵌入的目标是解决自然语言处理问题中的稀疏和高维特征。有了单词嵌入(或向量),我们可以使用低维(大多数时候是 50 或 300)来表示所有单词。详细情况,你可以看看这个博客

lda2vec

lda2vec 包括两个部分,即单词向量和文档向量,用于预测单词,以便同时训练所有向量。它通过跳格模型构建了一个词向量。简而言之,它使用目标词预测周围的词来学习向量。第二部分是文档向量,由

  • 文档权重向量:每个主题的权重。利用 softmax 将权重转换为百分比。
  • 主题矩阵:主题向量。一列表示一个主题,而一行存储每个主题附近的相关单词。

multithreaded.stitchfix.com/blog/2016/0…

文档向量的公式为

Moody, Mixing Dirichlet Topic Models and Word Embeddings to Make lda2vec (2016)

  • DJ:j 文档向量
  • pj0:“0”主题中 j 文档的权重
  • pjn:“n”主题中 j 文档的权重
  • t0:“0”话题的向量
  • TN:“n”话题的向量

当主题向量被共享时,文档之间的权重是不同的。更多细节,你可以查看穆迪的原创博客

拿走

对于源代码,你可以看看这个笔记本

  • 正如作者所建议的,如果你想拥有人类可读的主题,你应该使用 LDA。如果你想用另一种方式重做光学模型或者预测用户的话题,你可以试试 lda2vec。

关于我

我是湾区的数据科学家。专注于数据科学、人工智能,尤其是 NLP 和平台相关领域的最新发展。你可以通过媒体博客LinkedInGithub 联系我。

参考

穆迪·克里斯托弗。“混合狄利克雷主题模型和单词嵌入来制作 lda2vec”。2016.arxiv.org/pdf/1605.02…

用 D3.js 从玩具视觉过渡到真实应用

原文:towardsdatascience.com/combining-d…

将 UI 元素绑定到 D3 视觉效果

注意 : D3 现在使用了 Observable,我在这篇文章中提到过。

我们经常孤立地学习技术和方法,与数据科学的真正目标脱节;创造由机器学习驱动的真实应用。但是我说的真正的是什么意思呢?对我来说,真实意味着我们接触的任何技术都应该是整体应用的一部分,提供真正的用户体验。

训练新的 TensorFlow 模型?建立一个基于面部识别的应用程序。编写了一个自动执行常见数据清理任务的库?创建一个界面,使团队能够通过浏览器合并和清理数据。发现了一种新的文档分类方法?制作一个上传公司电子邮件档案的工具,识别与相关主题相关的所有主题,如团队建设。

我热衷于制造真正的产品,因为我知道这是在这个领域做好的唯一途径。我们需要通过人们与之互动的真实软件来表达机器学习概念,并理解如何用数据来打造用户体验。

孤立工作的一个常见例子是数据可视化。虽然“用数据讲故事”可能很强大,但故事本身并不能带来真正的解决方案。如果您的数据科学从未超越幻灯片,那么您就没有真正做过数据科学。利益相关者需要接触和感受解决方案的样子。有了今天的高级工具,数据科学家没有借口不编写真正的应用程序来展示他们的工作。

如果您的数据科学从未超越幻灯片,那么您就没有真正做过数据科学。

在这篇文章中,我将展示如何通过结合 D3 和 Azle 来构建真正的应用程序。让这些应用成为现实的是 D3 的绑定到应用中的 UI 元素。正是元素和视觉之间的这种联系确保了可视化不仅仅是讲故事的人;它们是解决实际问题的应用程序的组成部分。

内容

  • 简介
  • 设置您的项目
  • 构建一个 AZLE 应用程序
  • 增加 D3 视觉效果
  • 包装器参数和额外函数
  • 将 D3 绑定到 UI 元素
  • 添加动画
  • 动态改变数据
  • 图表间的通信
  • 运行时间表
  • 委托点击事件
  • 客户端数据

我创建了一个演示应用程序,展示了本文中讨论的主题。你可以在这里查看应用以及在 GitHub 上对应的回购

Example application that combines Azle with D3.

D3 和 AZLE

在我题为学习构建机器学习服务、原型化真实应用程序以及将您的工作部署给用户的文章中,读者第一次接触到了 Azle 。Azle 使用布局、预样式元素和易于使用的 REST API,支持快速的产品原型开发。

D3.js 是一个 JavaScript 库,用于生成动态的、交互式的数据可视化。D3 能够生成由数据驱动的图表和图形,并且已经成为行业标准的可视化工具。

虽然在 D3 的网站上有很多视觉效果的例子,但是对于如何在应用程序中包含这些视觉效果却没有什么支持。尽管许多库有助于更容易地创建 D3 视觉效果,但这并不等同于实现应用程序和 D3 之间的通信。

我们可以尝试使用我们组织当前的技术堆栈进行原型制作,但是当我们想要快速产生一个新的想法时,这是多余的。我们也可以使用一个包,允许我们用 R 或 Python 来构建“交互式 web 应用程序”。但是这种选择并不能使应用程序具有组织现有产品的外观和感觉。想象一下,试图用 Shiny 重现亚马逊或网飞的界面。还有一种将 UI 元素添加到视觉效果的“小部件方法”,但这将 UI 限制在视觉效果本身,而不是与完整的应用程序集成。

Azle 对 D3 的支持是不同的,因为没有你不能用 Azle 完成的布局或样式。任何 HTML、CSS 或 JavaScript 都可以添加到 Azle 应用程序中,尽管您通常只需要它自己高度声明性的语法。您组织的产品的外观和感觉可以很快被模仿,这意味着您的机器学习正在利益相关者认可的应用程序上进行测试。从对知名产品进行改进的原型中赢得认同要容易得多。

让我们开始吧。

设置

在这一节中,我将介绍设置 D3 与 Azle 一起工作的必要步骤。一旦你完成了这些步骤几次,你会发现设置你的 Azle_D3 项目又快又简单。这些步骤对于您决定与 Azle 一起使用的任何 D3 可视化都是相同的。

步骤 1:选择初学者视觉

网上有大量的 D3 例子,从头开始构建 D3 是没有意义的。你可能要重新发明轮子,把宝贵的开发时间花在寻找现有视觉效果上。第一步是从 D3 的网站选择一个现有的 D3 视觉。你可以点击顶部的例子来预览许多视觉效果,这里有更大的列表。

D3 Website

让我们选择一个基本图表来展示我们如何设置我们的项目。我将选择这里的条形图:

[## 条形图

迈克·博斯托克街区 3885304 号

bl.ocks.org](bl.ocks.org/mbostock/38…)

步骤 2:创建目录结构

与任何应用程序一样,我们需要创建一个目录结构来保存我们的文件。你可以在这里下载目录结构以节省时间。下载后,检查您的下载文件夹。您应该看到以下内容:

**azle_d3_directory**
├── **d3_visuals** └── barchart.html
├── **data** └── barchart.tsv
├── index.html
├── **scripts**

d3_visuals 文件夹保存 d3 提供的 html 文件。数据文件夹保存 D3 读取的本地数据。脚本保存任何 Azle 脚本,index.html是我们应用程序的主页面。这些文件现在是空的,因为我们将在本文中粘贴所需的代码。

无论我们需要支持多少视觉效果或数据集,这种相同的结构都将服务于我们的应用程序。更多的 D3 视觉效果意味着更多的*。d3_visuals 文件夹中的 html* 文件,以及 data 文件夹中的更多数据集。

步骤 3:从 D3 添加 HTML 和数据

因为我们使用 D3 的条形图,所以我们将添加 D3 示例页面上提供的 HTML 和数据用于条形图。

获取 HTML:

Grabbing html from D3 example page

在上面的 GIF 中,你可以看到我从 D3 的条形图示例中抓取 html,并将其粘贴到 d3_visuals 文件夹中的 barchart.html 文件中。

获取数据:

Grabbing data from D3 example page

上面,我从 D3 的条形图示例中抓取 data.tsv,并将其粘贴到 data 文件夹中我的条形图. tsv 文件中。D3 使用的另一种常见数据格式是 CSV。数据格式并不重要,因为我们正在抓取的视图已经被创建来读取这种数据类型。稍后,我们还将看看使用 JavaScript 对象存储在客户端的本地数据。

步骤 4:从 Azle 添加 HTML 模板

我们现在准备开始使用 Azle 创建一个与 D3 条形图交互的应用程序。我们从所有 Azle 应用程序开始;通过使用 Azle 的 html 模板文件:

Beginning HTML template for Azle application.

这是我们开始添加 Azle 函数来构建我们的应用程序所需要的一切。

步骤 5:包装 D3 视觉效果

我们需要一种方法来将数据从我们的应用程序传递到我们的 D3 视图。为了做到这一点,我们使用以下 3 个步骤对 D3 HTML 文件(【barchart.html】T2)做了一个小小的修改:

  1. 将 Azle 库添加到 D3 文件中;
  2. 所有原生 D3 代码包装在 draw_visual 函数内;
  3. 将所有函数参数设置为 azle_args。

让我们用条形图视觉效果来做这些事情:

Azle has been added to D3’s .html file. Also, all D3 code has been wrapped inside the draw_visual function. Finally, we have set arguments[0] to azle_args.

取任意一个 D3 代码,简单地用 draw_visual 函数将它包装起来。还要添加行 azle_args = arguments[0] 。这使得数据和函数能够进出我们的 D3 视觉。

寻找钩子

有了上面的步骤,我们可以使用 Azle 将数据和函数传入传出我们的 D3 visual。决定传递哪些数据/函数取决于我们希望动态改变什么。

例如,假设我们希望允许用户通过简单地单击应用程序中的一个按钮来更改驱动可视化的数据集。在这种情况下,我们查看 D3 代码以了解数据集在哪里被读取,并用 azle_args 和我们选择的替换文件名:

Finding D3 hooks and replacing with azle_args.

在上面的 GIF 中,我使用了 [“数据选择”]。这个键可以是您喜欢的任何键,只要您在 wrapper_arguments 中使用相同的键,这将在下面讨论。换句话说,azle_args 用于接受来自 azle 的数据,并使用它的值替换 D3 的硬编码部分。

我们可以在 D3 中找到各种挂钩,将我们的视觉绑定到应用程序的其他部分。另一个例子是使用 Azle 的颜色选择器来允许用户改变我们的条形图的颜色。在这种情况下,我们在 D3 内部查找设置条形颜色的位置,并用 azle_args["bar_color"]替换颜色。

用 D3 制作真正的应用程序

现在我们已经设置好了一切,我们可以将我们的 D3 可视化添加到一个真实的应用程序中。因为 Azle 是为构建应用程序而设计的,所以让我们创建一个 Azle 布局添加我们的条形图。然后我们会看到我们如何与我们的视觉沟通。

1)启动一个简单的 Web 服务器

为了使用我们的应用程序,我们需要一个 web 服务器。这些很容易在任何本地机器上创建。例如,在我的 Mac I 上打开终端,进入 azle _ d3 _ 目录,运行下面一行:

python3 -m http.server

现在我打开浏览器,进入 http://localhost:8000

2)准备页面

我们一如既往地从准备 Azle 的基础页面开始。虽然我有一个脚本文件夹,但我会将脚本标签之间的所有内容放在我的 index.html 文件的底部,create_azle 函数内的**:**

Basic page setup for Azle.js

让我们给我们的应用程序添加一些基本的样式、一个部分和一个布局:

我们现在有了一个布局,可以用来在屏幕上定位我们的内容:

An Azle layout

我使用 1 行 2 列的布局,因为我希望我的 UI 元素在左边,我的 D3 视觉在右边。

4)添加 D3 可视化

在我们的应用程序中添加 D3 视觉效果需要 3 个主要部分:

  1. add_d3_visual 函数;
  2. wrapper_arguments 对象;
  3. 额外功能对象。

add_d3_visual

为了添加我们的 D3 视觉,我们使用 Azle 的 add_d3_visual 函数。在这里,我将条形图添加到我在上面创建的布局的第二个单元格中:

Adding a D3 visual in Azle

注意我是如何在 add_d3_visual 函数中指定 wrapper_argumentsextra_functions 的。我们现在将创建这些对象。

包装 _ 参数

与任何 JavaScript 对象一样,wrapper_arguments 是一个属性列表,每个属性是一个键/值对。在这里,我们列出了想要传递给 D3 视觉效果的任何值(就像上面的 data_choice 示例)。我将在我的条形图中找到一串我想使用 Azle 设置的钩子(并最终在我的应用程序中使用 UI 元素动态控制)。下面是我的条形图的 wrapper_arguments 对象:

Setting properties in wrapper_arguments object

对于其中的每一个,我都用 azle_args["key"] (例如,azle_args["bar_color"])替换了我的条形图 D3 代码的一部分。

额外功能

实际上有 2 种方法我们可以使用 Azle 将信息传递给 D3 。我们已经看到了如何使用 wrapper_arguments 传递数据。只要我们在 D3 中找到挂钩,我们只需添加 azle_args["key"]来控制该属性。但是如果我们的 D3 视觉是用 CSS 而不是 D3 来样式化的呢?

例如,我们的条形图中的条形颜色使用 CSS 设置在顶部:

在这种情况下,我们可以像上面一样修改 D3 代码,使用 azle_args 为条形着色,或者我们可以将一个函数传递到我们的 visual 中,并直接设置“bar”类的样式。让我们来看看这两种场景的区别。

场景 1 :用 azle_args 传递值

在下面的 GIF 中,我在 D3 内部查找创建条形图的位置,然后添加必要的代码以接受来自 azle_args 的条形图颜色:

Modifying D3 to accept bar color dynamically using azle_args.

这意味着我添加到我的 wrapper_arguments(在 barchart_wrapper_args 中)的 bar_color 属性将被传递到我的 D3 visual 中,并且条将被适当地着色。

场景 2 :将函数直接传递给 D3

在这个场景中,我将使用 extra_functions 来设置条的颜色,允许我们在视觉中操作 CSS。在这种情况下,我们使用我们想要影响的元素的类名。上图(红色箭头)中,我们看到我们的酒吧的类名是“酒吧”Azle 使用类名来定位元素,所以这是一个自然的选择。也就是说,JavaScript 和 D3 在样式和事件方面有一些差异,所以我们将在额外的函数中使用 Azle 专用的 style_d3 函数。

因为我们已经使用 wrapper_arguments 很好地实现了条形颜色,所以我将使用其他颜色。事实上,我发现如何使用 D3 给条形图上的标签着色和调整大小很有挑战性。在一些 D3 例子中,我们看到这些标签使用 CSS 样式,使用名称文本以及填充字体大小。让我们在 extra_functions 中使用 Azle 的 all_style_d3 函数来定位“文本”:

我们将我们的 style_d3 函数添加到 extra_functions 对象**,**中,我称之为条形图 _extras:

Creating a barchart_extras object

style_d3 前面的 all_ 前缀是 Azle 定位一个类的所有实例的方式。因为我们想给所有的条着色,所以我们在这里使用它。你可以回顾一下 Azle 的文档来熟悉 Azle 的风格语法。

现在,当我们的 add_d3_visual 函数被调用时,两个包装器 _ 参数额外 _ 函数都将被传递给我们的 D3 visual :

让我们为更好的对比设计我们的应用程序。

az.**style_sections**('my_sections', 1, {
     "background" : "darkslategrey"
 })

我们可以看到,因为列在 wrapper_arguments 中,所以设置了条形颜色,因为在 extra_functions 中使用了 all_style_d3,所以对文本标签进行了着色和调整大小。

添加条形图后,我们的布局有点变形,但我们会尽快修复。

我们不必在 extra_functions 中使用 Azle 函数。我们还可以使用 extra_functions 将普通的 Javascript 传递给任何 D3 visual。只要确保函数用引号括起来。

5)添加 UI 元素

让我们在布局的左侧添加一些 UI 元素。我首先将另一个布局添加到我的原始布局的第一个单元格,以便将我的 UI 元素放置在左侧。然后,我将我的 UI 元素添加到新布局的每个单元格中:

Adding UI elements to Azle Application

让我们清理一下我们的布局,做一些基本的样式。首先,我将设置第一个布局上每一列的宽度:

az.**style_layout**('my_layout', 1, {
     "column_widths" : ['20%', '80%']
 })

我们可以看到 UI 元素和 D3 visual 现在在布局中的位置是正确的。我还想让左边的 UI 元素在它们自己的单元格内居中。

az.**all_style_layout**('element_layout_cells', {
     "halign" : "center"
 })

另外,默认的按钮颜色滑块标签与深色背景不太匹配。让我们改变这些:

az.**style_button**('data_button', 1, {
     "background" : "rgb(254, 225, 180)",
     "color" : "black"
 })

 az.**style_slider**('my_slider', 1, {
     "color" : "white"
 })

最后,让我们移除两个布局上的边框,给我们一个干净的应用程序。将两种布局样式都设置为包含 0 的边框属性:

az.**style_layout**('my_layout', 1, {
     "column_widths" : ['20%', '80%'],
     "border" : 0
 })

 az.**style_layout**('element_layout', 1, {
     "border" : 0
 })

Removing Borders on Azle Layouts

既然我们已经知道了如何添加一个可视元素,以及一些基本的 UI 元素,那么是时候开始将我们的 D3 可视元素绑定到 UI 元素了。

将 D3 视觉效果绑定到 UI 元素

用 D3 创建真正的软件是为了确保我们可以在应用程序中使用 UI 元素与可视化交互。Azle 使用了 2 个函数来与 D3 交互:

  1. call_d3_wrapper
  2. call_d3_extra

调用 _ d3 _ 包装器

在上面的第 4 部分中,我们使用了 wrapper_arguments 来列出我们想要传递给 D3 visual 的任何值。 call_d3_wrapper 函数用于动态改变我们的 wrapper _ arguments*。这意味着我们放在 D3 视觉元素中的任何挂钩(使用 azle_args)都将响应我们在 call_d3_wrapper 中指定的更改。*

call_d3_wrapper 函数使用普通的 Azle 风格的目标,带有 target_class 和 target_instance,还列出了与我们的 wrapper_arguments 相关的属性:

*az.**call_d3_wrapper**('my_barchart', 1, {
    "wrapper_arguments" : barchart_wrapper_args,
    "extra_functions" : barchart_extras,
    "bar_color" : passed_value
})*

注意 call_d3_wrapper 函数期望 列出 wrapper_arguments extra_functions 。我们指定 extra_functions 的原因是为了在重绘视图时保留样式。在上面的例子中,我计划向“bar_color”属性动态传递一个值。

让我们将更改数据按钮绑定到条形图上。在 Azle 中,我们使用 add_event 函数来将事件附加到 UI 元素:

*az.**add_event**('data_button', 1, {
     "type" : "click", 
     "function" : ""
 })*

这里我们简单地指定了事件的类型(比如点击)和事件触发时调用的函数。我们想在用户点击按钮时调用 call_d3_wrapper 函数。为了让这更有用,让我们允许用户在点击按钮时在数据集之间来回切换。我将创建两个独立的 change_data 函数,每个函数都用适当的 data_choice 调用自己的 call_d3_wrapper。然后我会用 Azle 的 toggle_functions 作为 add_event 里面的函数。让我们使用 Azle 的包装函数来组织我们的代码。

结果:

我们刚刚创建了 UI 元素和 D3 视觉元素之间的第一个绑定。

对于下拉菜单,让我们允许用户在 3 种不同的颜色中选择我们的条。首先,我们需要返回到我们的 add_dropdown 函数,并添加选项,我们最初将其留空:

*az.**add_dropdown**('element_layout_cells', 2, {
     "this_class" : "choose_drop", 
     "title" : "choose color...",
     "options" : ['blue', 'yellow', 'hotpink']
 })*

我还把标题改成了“选择颜色”

现在我们可以像以前一样使用 add_event ,但是这一次将目标指向我们的 dropdown 元素,并选择 change 作为事件类型。我将把我的 call_d3_wrapper 放在一个名为 recolor_bars 的函数中,然后用我的 add_event 调用它:

Binding a dropdown to a D3 Visual in Azle

*注意,这次我是向 add_event 内部的函数传递一个参数(*recolor _ bars()函数)。我传递的参数是从下拉列表中选择的值(使用 this.value 是 JavaScript 中的标准做法)。

结果:

现在让我们将滑块绑定到条形图上。现在我们知道该怎么做了。这次最大的不同是事件类型被称为 as_change 。当滑块移动时,该事件类型传递参数*。让我们允许用户更改图表的上边距:***

Binding a slider to a D3 Visual in Azle

如果你试着移动滑块,你会发现图表变化不大。我们需要增加滑块元素的取值范围,使其对我们的用例有用:

*az.**add_slider**('element_layout_cells', 3, {
     "this_class" : "my_slider", 
     "min_value" : 0,
     "**max_value**" : 100,
     "default_value" : 5
 })*

结果:

call_d3_extra

正如我们有一个函数可以动态改变我们的 wrapper _arguments 一样,我们也有一个函数可以动态改变我们的 extra_functions。我们在上面的第 4 节中使用了 extra_functions 来设置文本的颜色和大小。让我们使用 call_d3_extra 将我们的滑块绑定到文本大小,允许用户动态地改变文本大小。 call_d3_extra 函数的使用方式与 call_d3_wrapper 相同:**

Dynamically changing tick size in a D3 visual using Azle

注意,当我们使用 call_d3_extra 时,转换更加平滑,因为图表没有被重画。

我想展示的另一个 UI 元素是颜色选择器。让我们添加另一个按钮,它提供了一个颜色选择器,用户可以使用它来动态地改变条形的颜色。首先,我们需要向 elements_layout 添加另一行。然后我们可以添加并样式化我们的按钮,并使用 add_event 来触发 add_color_picker 函数:

结果:

Using the color picker in Azle

在本文的剩余部分,我将展示视频开头提到的演示应用程序中内置的示例。这个包含所有源代码的完整示例应用程序可以在 GitHub 这里找到。

添加动画

我们有很多方法可以将 Azle 功能与 D3 混合搭配。一种选择是添加动画。我们可以结合* call_d3_extra 和 Azle 的 animate_element 函数来动画化 d3 里面的一个特定元素。*

在这种情况下,我们需要为 D3 中的每个元素分配一个惟一的 id。我们可以在 D3 中直接这样做,或者使用 Azle 的 all_apply_id 函数。

一旦分配了 id,我们就可以使用 Azle 的 all_add_event 函数来添加一个悬停事件,每当元素被悬停时,该事件就会调用 Azle 的 animate_element 函数。

结果:

注意我们没有使用 all_ 前缀来动画显示所有的条。这将导致当只有一个条被悬停时,所有的条都被激活,这不是期望的行为。

这是另一个动画示例:

你可以用 Azle 提供的任何动画进行实验。

动态更改数据

一个常见的场景是允许用户更改驱动特定视觉的数据。我们已经看到了这样的例子。下面是演示应用程序中使用的示例:

这里有一个带有单选按钮的按钮,我们可以在不同的数据集以及数据子集之间进行选择:

稍后,我们将看到如何使用从 REST API 获取的客户端数据来实现这一点。

保留样式

需要注意的一件重要事情是,我们如何在 UI 元素之间移动,而不破坏最近的更改。例如,在下面的散点图中,我可以更改圆形大小,然后更改图表宽度,更改数据集,并过滤数据,同时始终保持样式(注意 GIF 动画使过渡看起来不太平滑)。

2 个 D3 图表之间的通信

让 2 D3 图表相互交流通常很有用。例如,允许用户与一个视觉对象交互,并让该交互影响显示相应信息的第二个视觉对象,这可能是有意义的。

我们简单地添加 2 个视觉效果和一个桥接功能来完成这个工作。让我们试一试。

我们创建一个布局,用 1 行和 2 个单元格来容纳两种视觉效果。我称之为双重布局。然后我们像往常一样添加视觉效果:

条形图图表添加到布局单元格 1

折线图添加到布局单元格 2

将悬停事件添加到条形图中,即调用一个 桥函数 :

Calling a 2nd D3 visual with Azle

这里,我们将一些属性添加到条形图的 extra_functions 对象中。最重要的一个是“call_line_chart”,在这里我做了以下事情:

  • 将 id应用于所有条形元素;
  • 将悬停事件添加到所有 bar 元素中;
  • 悬停时调用桥接函数

前两步和我们制作动画的步骤是一样的。bridge 函数是当用户将鼠标悬停在条形图上的某个条上时调用的函数。桥函数需要调用第二张图上的call _ D3 _ wrapper:

桥接功能:

注意我们的条形图上的悬停事件是如何调用桥函数的。它使用前缀。这是因为桥函数存在于 D3 视觉之外。它还使用 Azle 的 get_target_instance()函数来获取使用其 id 的 bar 的实例。

结果:

2 D3 charts communicating with each other using Azle

注意,我们为这个条形图重用了相同的 HTML 文件(与本文开始时使用的相同)。我们只改变了它的 wrapper_arguments 和 extra_functions。

在上面的例子中,我使用 Azle 将一个悬停事件添加到视觉效果中。但是 D3 有自己的事件,使用 visual 自带的事件可能更有意义,尤其是 D3 支持的非标准事件。在下面的例子中,我使用 Azle 将笔刷可视化和水平条形图结合起来。在这里,我将左边刷牙的最小值和最大值传递给右边的条形:

在这种情况下,我找到了在 D3 中更新刷取值的位置,并使用了前面示例中讨论的相同的父前缀和桥函数方法,将这些值传递给我的 call_d3_wrapper 函数:

Passing Values from D3’s Brush Visual to Azle’s call_d3_wrapper

我创建了一个GithubGist你可以查看,查看上面例子的所有文件。

运行时间表

随着时间的推移,有时自动播放一组视觉效果是有意义的。当我们需要用时间维度的数据讲述一个故事时,这是有意义的。在下面的例子中,我将 call_d3_wrapper 与 Azle 的 call_every 函数结合起来,来遍历一组视觉效果:

结果:

Using Azle’s call_every function to play timelines with D3

委派点击事件

委托 click 事件也是有用的,这样就可以有计划地点击 D3 visual* 中的元素。例如,D3 上的圆形包装视觉通常期望用户点击不同的圆形来放大。让我们允许用户从下拉菜单中选择一个选项来放大视图的各个部分。***

为此我们使用 Azle 的 click_d3 函数。

结果:

Using Azle’s click_d3 with packing visual

同样的方法,这次用的是地图*:***

Using Azle’s click_d3 with map visual

…以及可折叠采油树*:***

Using Azle’s click_d3 with tree visual

客户端数据

到目前为止,我们假设 D3 数据保存在磁盘上。例如,上面我们使用了 TSV 和 CSV 文件。对于模拟应用程序,这通常就足够了。但是有时我们需要使用客户端数据,在这种情况下,数据作为 JavaScript 对象被存储、读取或上传。

在这一节中,我将通过 3 种主要的客户端场景展示如何使用 Azle 和 D3:

  1. JavaScript 对象硬编码到我们的文件中;
  2. 从 RESTful API获取数据*;***
  3. 通过浏览器上传数据。

文件中的 JavaScript 对象

有时我们不需要磁盘上的数据,比如当我们模仿一个快速演示应用程序或使用不变的数据时。

在这个例子中,我将展示如何在数据存储为 JavaScript 对象的数据集之间进行转换。我将使用和弦图,它使用值的矩阵作为数据。首先,让我们创建 3 个矩阵,并将它们存储在一个名为 all_chord_data 的 JavaScript 对象中。我还将创建一个名为 switch_client_side 的函数,它使用 call_d3_wrapper 来设置 data_choice,就像我们之前所做的那样:

Switching between D3 datasets stored client-side using Azle

我们简单地将单选按钮绑定到 Azle 的 call_d3_wrapper 函数,以更改我们的 chord 图上的数据集。

结果:

从 REST API 获取数据

任何应用程序中的一个常见场景是从 REST API 获取数据。在需要运行分析并将结果返回给产品的机器学习应用中尤其如此。

Azle 的 call_api 函数就是用于这个目的。熟悉我的文章构建机器学习服务和原型化真实应用的读者会认识到这个功能。这允许我们进行 REST 调用,等待响应,然后在收到数据后运行我们选择的函数。让我们使用 call_api 从我为本文编写的 api 中获取数据:

结果:

这里我们可以看到从 call_api 接收到新数据后和弦图的变化。

从浏览器上传数据

允许用户从浏览器上传数据会很有用。与其他客户端场景一样,这适用于较小的汇总数据集。

在这里我创建了一个名为 my_data.json文件*。在这个文件中是和弦图的矩阵,正如我们在上面看到的:***

my_data.json

这是标准的 JSON 格式,允许我索引不同的数据集。这里我只在我的文件中存储了一个矩阵,但是它可以是多个,就像我们在上面使用 JS 对象时所做的那样。

我们将使用 Azle 的 add_upload_button 函数来添加必要的 UI 元素:

Adding an upload button in Azle

数据文件上传后,我们必须决定要做什么。这里,我将在 function 属性(在 JavaScript 中称为“字符串文字”)的单引号之间嵌入我的 call_d3_wrapper 函数:

结果:

我们可以看到在上传时驱动我们视觉变化的数据集。

摘要

在本文中,我展示了如何将 D3 和 Azle 结合起来。具体来说,我们已经看到了如何将 UI 元素绑定到可视化,以确保我们的故事被集成到一个真实的应用程序中。如果 D3 和/或 Azle 不是你选择的工具,那也没关系。重要的是构建真正的应用而不是仅仅停留在幻灯片上的东西。你的组织将更好地理解数据和机器学习的好处,你的个人数据科学教育将增加十倍。

一如既往,请在评论区提问。

如果您喜欢这篇文章,您可能也会喜欢以下内容:

*** [## 学习建立机器学习服务,原型真实的应用程序,并部署您的工作…

在这篇文章中,我将向读者展示如何将他们的机器学习模型公开为 RESTful web 服务,原型真实…

towardsdatascience.com](/learn-to-build-machine-learning-services-prototype-real-applications-and-deploy-your-work-to-aa97b2b09e0c) [## 机器学习工作流的 GUI 化:快速发现可行的流水线

前言

towardsdatascience.com](/gui-fying-the-machine-learning-workflow-towards-rapid-discovery-of-viable-pipelines-cab2552c909f) [## 创建 R 和 Python 库的分步指南(在 JupyterLab 中)

r 和 Python 是当今机器学习语言的支柱。r 提供了强大的统计数据和快速…

towardsdatascience.com](/step-by-step-guide-to-creating-r-and-python-libraries-e81bbea87911)

奖金票据

通过 call_d3_extra 使用其他 JavaScript

如果您对普通 JavaScript 和/或 jQuery 的语法更熟悉,您可以使用它们。任何脚本都可以传入 call_d3_extra 函数。下面是一个使用 jQuery 设计图表中条形样式的示例:

Passing regular jQuery into D3 visual using Azle

wrapper_arguments 和 extra_functions 中的“调用”属性

有时我们用 Azle 动态地改变 D3 值,并且需要我们前端的 UI 元素来记住我们传递的最后一个值。例如,假设我们在一个模态中有一个滑块,我们用它来调整我们的 D3 视觉。当我们关闭模型时,滑块消失了,每次弹出模型时,滑块都是从头开始创建的。为了确保滑块记住相同的值,我们可以简单地访问我们的 wrapper_arguments 对象:

Recalling the last set property in wrapper_arguments in Azle

现在,每当我们再次打开滑块时,该值就是我们最后设置的值。这可以防止 D3 在我们重新绘制图表时跳跃:

我们可以对我们的 extra_functions 对象使用类似的方法,尽管这次我们不能像上面那样只访问属性的键值。相反,我们使用 Azle 的 get_current_d3_value 函数,传递 barchart_extras 对象、我们赋予样式的名称以及样式本身:

Recalling the last set property in extra_functions in Azle

Azle 中的嵌入式函数

在本文使用的大多数例子中,从函数调用函数是通过如下方式实现的:

在这种情况下,我们从 add_event 内部调用 change_data,change_data 是它自己包含的函数。

另一种选择是直接将 嵌入 change_data()中的一个“字符串文字

为了嵌入函数,我们将要嵌入的函数放在两个单引号中。

这可能是编写应用程序的一种更快的方式,但是它也导致代码的模块化程度降低。向嵌入式函数传递参数也会带来一些挑战。您应该尝试使用 Azle 的 add_wrapped_function 来代替,如前所述,因为它允许我们将一组函数分组到一个单独的命名函数中。

更改个人 Web 服务器上的端口

如果您的端口 8000 已经被占用,您可以简单地在命令末尾添加您想要的端口号:

python3 -m http.server 7777

提交。失败。提高。

原文:towardsdatascience.com/commit-fail…

这是我今年在加州圣地亚哥举行的数据科学围棋大会上,在 400 多人面前演讲的书面形式。

你如何将你的热情转化为事业?

我的答案是:通过不计后果的承诺。

去年,我参加了我的第一次数据科学会议。会议期间,我在笔记本上做了笔记,每个人都收到了一份礼包。在所有这些笔记中,有一个特别的笔记在一年内彻底改变了我的生活。

2017 年 11 月。加州圣地亚哥。我刚刚从德国飞过来参观第一届数据科学 GO 会议,由基里尔·叶列缅科和他的超级数据科学团队组织。在在线教育平台“Udemy”上成功教授超过 600,000 名学生数据科学知识后,他们希望召集有抱负的数据科学家参加一个拥挤的会议。

由于这也是我第一次参加会议,我不太知道会发生什么。但是我思想开放,什么都愿意做。当时,我的目标是进入数据科学领域,我对自己说:如果我能遇到一个人,一个唯一能在这个旅程中激励我的人,那就值了。

第一天,第二次谈话。这是本·泰勒的演讲(如果你不知道本,他是 Quora 上人工智能的头号作家。这应该暗示了他讲话的质量。).他在谈论如何成为一名摇滚明星数据科学家,他的观点之一是关于不计后果的承诺。

"如果你想进入数据科学领域,不要犹豫不决."

本认为,在这个领域,任何人都可以从零到六位数的年薪。但是这需要极大的热情和承诺。这肯定会很难。但是他建议:如果你刚刚从零开始,并且想进入这个领域,那么今天就开始参加聚会吧。今天去参加一个,然后承诺 3 个月后参加下一个。一定要提出一个让每个人都印象深刻的话题,比如胶囊网络或连体网络。 通常,Ben 对这一建议的第一个回答是,顺便说一下,这也是我当时作为数据科学新手的第一个想法:

“但我不是专家”——我不知道那个题目!”——“如果我让自己难堪了怎么办?”

正如你所看到的,逻辑阻碍了。而且理由很充分!你不是专家。你可能是数据科学的初学者,所以这看起来完全不合逻辑。但是本说:

“如果你承诺在 3 个月后的一次聚会上发言,3 个月后你就会成为那个主题的专家。”

尽管我有疑虑,但我很好奇。想想看: 我们参加多少次会议,得到多少启发? 在我们的生活中,有多少次我们会遇到鼓舞人心的人,并被激励去改变一些事情?

起初,我们非常活跃。但问题是,一旦我们开始以理性的方式思考改变某件事是否有意义,我们就会拖延。 更糟糕的是,几天后,我们在会议后达到顶峰的动力又降了下来。 什么都没变。 逻辑挡路。因此,我们找到了行不通的原因,并回到了老的做事方式。但是我们有办法防止这种情况吗?

这就是鲁莽承诺这个概念出现的地方: 先承诺。不考虑是否可能。

“如果你承诺在三个月后的一次聚会上展示自己,你将在三个月后成为一名专家”。

致力于你为自己设定的目标,一旦你在脑海中形成了这个目标是什么的形象,你的大脑就会激发你的创造力,让你想出一些东西。也就是说,你的大脑会告诉你如何到达那里,哪些资源可能有帮助,以及如何开始。

当我从会议回来时,我发现自己处于那种兴奋的状态。我在周末遇到的所有人和得到的所有意见都让我深受鼓舞。我以前也经历过这种问题:我有动力去改变生活中的某些事情,但却一直推着它,直到我失去了灵感。所以我向自己保证,这次不会了。我飞了半个世界不是为了这个。受本演讲的启发,我想参加一个聚会来谈论某个话题,这样我就可以成为这方面的专家。回家的同一天晚上,我带着笔记本电脑去汉堡查看是否有任何与人工智能相关的聚会,这是我目前居住的城市。但是什么都没有。

那时,我仍然兴奋不已,我决定干脆创建自己的聚会。为了确保我能信守承诺,我把第一次约会定在了 12 月中旬。由于我在那年 11 月中旬回来,我有一个月的时间。

做出这样的承诺感觉很棒,因为我终于做了一些事情,让自己免于陷入失去最初灵感的陷阱。但是,说实话,我真的没有考虑过后果: 仅仅两天后,我创建的小组已经有了 100 多名成员,一周后,有 250 多人加入了这个小组。慢慢地,一些疑问开始浮现,我想这是否是一个合理的决定。因为那时,我从未组织过活动。我甚至还没去过聚会。事实上,当本告诉我这件事的时候,我甚至不知道 Meetup 是什么!

但是我已经设定了目标。关于外部承诺的事情是这样的:他们让你负责。日历上有这件事,人们期待着我做些什么。我已经告诉了我的一些朋友,所以它必须发生。他们说:

"如果你想占领这个岛,那就烧了船"

设定这些外部承诺是我破釜沉舟的方式。所以我想了想第一场比赛我可能需要什么。我的清单包括: -演讲者 -场地 -餐饮 -赞助商 ,当然,还要确保人们到场!我必须保证不仅仅是我和另一个人进行一对一的交流。

一个月后的一个周五晚上: 在花了很大力气与人交谈并试图让一切运转起来之后,这是第一次活动的日子。我非常兴奋。它将在我大学的一个演讲室举行。这个房间可以容纳大约 150 人,我点了餐饮服务,以确保每个人都玩得开心。这是我们大学里比较好的房间之一,有非常舒适的椅子。我告诉了我所有的朋友,总共有 120 个回复。

不幸的是,事情并不总是按计划进行。好消息是:我们得到了所有的赞助。 坏消息:在报名参加活动的 120 人中,只有三分之一的人真正到场。我们两个演讲者中的一个根本没有准备,在演讲中东拉西扯。最重要的是,我们吃了太多的食物,因为我估计至少有 100 个人。40 人到场。嗯,至少每个人都可以带些第二天的午餐回家。 玩笑归玩笑。想象一下,我坐在那里。人们似乎很沮丧,他们一直看着我。我很沮丧。有些人提前离开了活动,这是最糟糕的感觉,因为你知道你可能已经毁了他们的夜晚。 我们的赞助商在那里,他们肯定不兴奋。 我呢? 我失败了;没有把一切都计划好。

我从 Ben 在 Data Science GO 上的演讲中学到的一点是: 首先提交。但是最重要的是,我知道你必须愿意失败。所以首先要承诺,但要做好在通往目标的路上失败的准备。但是现在最重要的部分来了:

我仍然给自己设定了一个目标:在汉堡创建一个人工智能社区,以便能够随时与志同道合的人交流。几个月后,我敢于再次尝试。我采纳了负面反馈,从中吸取了教训,并修正了我们的路线。这次我们在不同的地方,没有食物,我事先检查了两个扬声器。最后,有 100 人到场,一切都按计划进行,我们收到了很好的反馈。我们的一位演讲者来自柏林,所以活动结束后,我们与他合作,在那里开设了第二个 Meetup 小组。

在这一点上,我想强调的是,如果我一开始没有做出承诺,我永远不会这么做。我会永远不会组织活动。我甚至从未想过组织一次活动。 先提交。 做好失败的准备。 但要准备好改进。 因为今天,我们是德国发展最快的聚会。 2000 名会员,人数还在增加。 我们在德国两个最大的城市汉堡柏林经营最大的聚会。 事后我明白了,失败很酷,只要你从反馈和正确的过程中学习。

“没有所谓的失败,只有暂时的失败。”

永远坚持尝试,永远进步。提交。失败。提高。

大约在参加会议的六个月前,我刚刚开始学习深度学习和人工智能的在线课程。通过这些课程,我有机会看到许多实际应用和使用案例,并看到了巨大的潜力。我现在工作的公司是德国最大的电子商务服务提供商之一,为最大的零售商建立网上商店。客观地说,我们的一个客户在德国相当于亚马逊在美国的地位。这就是为什么我知道会有很多数据要处理,因此会有一个应用人工智能的巨大机会。当我查找并发现许多使用案例时,我正在考虑让一个研究小组研究其中的一些应用程序,以使我们的产品和流程更加高效。

唯一的问题是,我不知道如何向我们的执行团队提出整个事情,因为从逻辑的角度来看,这没有意义。想象一下,在你的公司里,某个自下而上的人会过来告诉你如何运行你未来的数据战略。 再次,逻辑挡住了的路。整个努力似乎遥不可及,因此我一直在拖延。我一直把它往后推。 但是我从数据科学围棋大会回来之后,我就下定决心了。 回到工作的第一天,我做出了一个承诺,我给我们的一位董事发了一封电子邮件,说了这样的话: “我想向你推销这个想法。下周有空吗?”

那时我几乎一无所有。我没有计划。我没有统计数据。只是我想推销的东西的一个模糊的想法。 所以这可能不是最合理的决定……

一周后,我演讲的那天: 这是我第一次向一位高管演讲,我非常紧张。让我告诉你,这不是一个好的演示。 现在回过头来看,它实际上相当糟糕。但是这个想法本身就足以说服我的概念总监,所以我继续努力。 我保持改进。几周后,我想出了一个结构化的计划。我安排了一次会议,向我们整个执行团队推销这个计划。 这次会议的结果是,我获得了启动人工智能研究实验室的批准。 我们制作的产品现已集成到我们的在线商店软件中。当我开始学习人工智能时,我的梦想是有一天应用它来解决实际问题。 因为我做了一个承诺,这个梦想变成了现实。 先提交。从某处开始。然后利用你能得到的任何反馈来改进和不断修正你的路线。提交.失败.改进。

我在这里写的东西最棒的一点是,这些概念没有一个是我或本的观点。它深深植根于我们大脑的工作方式。我们给它一个目标,它就想出了如何实现的方法。把它想象成一枚自导鱼雷。目标是已知的,目的是达到它。鱼雷通过前进、犯错误和不断修正错误来完成它的目标。它以之字形运动向目标前进。仔细想想,当我们试图完成任何目标时,这正是我们大脑的工作方式。想一些简单的事情:比如从地上捡起一支笔。我们所做的只是选择目标,我们的大脑会自动找到到达目标的方法。不涉及也不需要有意识的思考。 我们不认为:“现在我必须用我的肩部肌肉来抬高我的手臂,然后我必须用我的二头肌来伸展我的手臂。”因为实际上我们甚至不知道涉及哪些肌肉。我们所做的就是设定目标,让我们的大脑想出实现目标的方法。就像本说的那样:如果你承诺在三个月后的一次聚会上展示自己,你将在三个月后成为一名专家。把它想象成一辆自行车:只要朝着某个方向前进,自行车很容易保持平衡。当你坐着不动,无处可去,试图保持平衡时,麻烦就出现了。 看,你走得快还是慢都没关系。只要你一直在前进,平衡会更容易,你会更接近你的目标。 你需要给你的大脑一个目标。 提交。失败。提高。*

事实上,我已经写了一篇关于汽车的文章,有这样一个故事:

19 世纪初,工程师们发现了如何用蒸汽机来驱动车轮,于是蒸汽机车诞生了。最初它只是用来运输货物和资源,人们很快发现它也是一种很好的运输工具。 然而,由于当时的科学水平,早期的采用者建议火车不要以超过 30 英里的时速运行,因为车上的人体会爆炸。

是的,你没看错。 人们真的相信如果他们的速度超过 30 英里每小时,他们的身体会爆炸。 幸运的是,一些“寻求刺激的人”无论如何都决定开到 31 英里,而我们现在开着时速超过 280 英里的车。

“我们能做多少往往只取决于我们尝试了多少。”

想象一下被堵在高速公路上。 以每小时 30 英里的速度向前爬行。如果不是因为那个疯子,我们的速度会是最快的。 首先承诺,在真正可能的事情上突破界限。

总的来说,我认为大多数人看到的问题是,他们可能会想: 在这种情绪状态下做出承诺难道不危险吗?未经深思熟虑就做出承诺不是很危险吗?如果我失败了怎么办? 我完全能理解这种观点,但请这样想: 如果你发现自己真的想改变什么,如果你对目前的状况不满意: 没关系。你必须做出改变才能前进。你必须站出来做些不同的事情。即使有风险。

最大的风险是不要冒险。

正如马克·扎克伯格所说:“在这个快速变化的世界里,唯一肯定会失败的策略就是不冒险。”

现在。如果你想承诺什么,我请你闭上眼睛。 我希望你考虑任何目标。想想你想改变的事情,你渴望完成的事情。不一定是和职业相关的事情。它必须是你真正热爱的事情。 想想目标是什么?时间框架是什么?这是你想在下周、几个月后或明年实现的事情吗?细节很重要。你在哪里?你和谁在一起?考虑一下环境。现在生动地想象如果你成功了会发生什么。试着在那一刻描绘出自己的样子。那让你感觉如何?你感到兴奋吗?好吧,现在你正处于做出承诺的最佳状态。写下你的想法并付诸行动!你可以随时把你的目标发给我,我很乐意和你聊聊。

因为这正是我去年在大会上所做的。在本文的开头,我谈到了去年我参加的一个会议的笔记本中的一个笔记,它改变了我的生活。 事后看来,那张纸条引发了我所写的一切。 那张纸条启发我创建了一个聚会。 那张纸条促使我去找公司的高管,为一个人工智能研究实验室做宣传。 如前所述,我在会议期间做了一些笔记。在本·泰勒演讲的时候,我在第三页的背面草草写了些东西。我对自己做出了承诺。

我想通过这篇文章表达的是,一切皆有可能。这听起来肯定让你疲惫不堪,但我确信你可以实现你下定决心要做的任何事情。因为一旦你为自己设定了目标,你就会清楚地知道自己在朝着什么方向努力。在这个信任点上,当你做出承诺并相信找到方法的可能性时,机会很快就会向你敞开。这可能需要一天、一周甚至一个月。但是在某些时候,你的大脑会给你一些想法,你可以用它们来开始。 有时候,你认为需要多长时间就需要多长时间。

“可能的程度往往受到我们尝试的程度的限制”

当我写下那张纸条的时候,我想这是绝对不合逻辑和不可能的。 为什么他们会允许一个 21 岁的孩子在这个会议上发言?我能贡献什么呢?我怎样才能获得必要的经验来确保这是一次成功的演讲?我能谈些什么呢?

在去年数据科学围棋大会的第一天结束时,也就是我写下那张纸条的那一天,我忘记了所有这些问题,去找了会议的组织者基里尔·叶列缅科。对他来说,这是漫长的一天,他看起来非常疲惫,但我当场告诉他,我想在明年的会议上发言。这是我的承诺。我非常认真。那时候我没有任何答案。但是我知道我会找到他们的。他回头看着我,只是说:“嗯,首先你得成功”。

*对于任何感兴趣的人,我强烈推荐阅读以下深入这一概念的书籍: 心理控制论,麦克斯韦·马尔茨 思考致富,拿破仑·希尔 思考的魔力,大卫·施瓦茨