TowardsDataScience 博客中文翻译 2016~2018(一百四十二)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

对 Reddit 帖子内容进行分类的引擎:自然语言处理的应用

原文:https://towardsdatascience.com/how-to-build-an-engine-that-classifies-the-content-of-a-reddit-post-an-application-of-natural-6306cfe94742?source=collection_archive---------9-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

“white text on black background” by Lauren Peng on Unsplash

在我发表了关于自然语言处理决策树的博文之后,我认为谈论 NLP 和随机森林的具体应用是个好主意,特别是关于我最近参与的一个项目。

1.定义问题

本主题的目的是从两个不同的子编辑中收集帖子,并且仅通过分析帖子的文本,建立一个能够对哪些帖子属于哪个子编辑进行分类的模型。我决定挑战自己,挑选两个彼此没有太大区别(但也很搞笑)的子主题:淋浴思想和深刻的哲学。想想看:如果你分析科学与艺术,这两个子主题的关键词可能会非常不同,模型将很容易识别哪个帖子属于哪个页面。然而,淋浴的想法和深刻的哲学之间有很多重叠。为了让你有个概念,这里有两个这样的帖子的例子:

“你永远不会意识到你咀嚼食物用了多大的力量,直到你咬下嘴唇。”

“如果我克隆自己,它杀了我,这是谋杀还是自杀?我需要在周二之前知道。”

你能猜出哪个帖子属于哪个子编辑吗?

除了算法本身,这个项目还包含另一个对数据科学家来说常见的巨大挑战:收集数据!没错,这次没有。csv 文件与**一起工作。

2.收集数据

定义问题后,我们数据科学流程的下一步是收集数据!足够幸运的是,一旦我们有了想要抓取的 Reddit 页面的 url,如果我们添加*。json* 在 url 的末尾,我们将可以访问到 json 格式下的页面内容。对于那些不熟悉这种格式的人来说,它类似于 Python 字典。开始的时候可能会有点乱,但是经过一些尝试和错误,你可以找出关键,提取你需要的数据是相当容易的!

每次我们 ping Reddit 服务器,我们将可以访问 25 个帖子,但这当然远远不足以解决我们的问题,这意味着我们必须 ping 服务器几次,以便收集相关数量的帖子。我们还必须对代码进行一些更改,以便正确地执行此操作。我们必须改变我们的User-agent并改变一个名为after的参数,这样我们就不会每次尝试都刮到相同的 25 个帖子!这样,我们就可以在每次获取新数据时,向下移动页面,收集不同的 Reddit 帖子。的。Reddit 给我们的 json 文件包含了很多关于页面的信息,经过初步探索,我注意到实际的帖子包含在[data][children]键下,如下面代码的第 41 行所示。

上面的代码从 Reddit 页面返回一个子对象列表。然而,为了找到它,必须进行一些数据探索和清理,然后确保每个帖子的内容不会分成两个字段。下面的 Python 代码将查找并清理数据。

这是淋浴思想 subreddit 的前几行。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,我们将不得不对第二个子编辑页重新做一遍,并将这些观察结果附加到我们的数据帧中。一旦我们收集了足够的数据(就我而言,超过 2000 篇帖子),就该进行下一步了!

3.清理和准备数据

幸运的是,我提取的数据非常干净。然而,我想最终将自然语言处理(NLP)技术应用于这些数据。在此之前,我通过删除标点符号、停用词和最有可能是网页中 unicode 残余的字符来清理数据。我利用 scikit-learn 的feature_extraction模块来帮助清理这些数据。还得定义我的 Y 变量,建模时要预测的变量。我选择“淋浴思想”的值为 1,选择“深层哲学”的值为 0。

当把文本转换成计算机可以解释的变量时,我们通常会做一些叫做“矢量化”的事情。一种简单的矢量器称为“计数矢量器”。这是一个频率计数器,计算一个单词在帖子中出现的次数。例如,如果一篇文章包含单词“thinking”三次,那么我的 CountVectorizer 将创建一个名为“thinking”的变量,这篇文章在该列中的值为 3。对于每一篇帖子,该算法会计算单词“thinking”被看到的次数,并将该数字放入该列。因此,“思考”列将是一个大的数字列表,它计算每个帖子中出现“思考”的次数。对于我的项目,我使用了一个不同的矢量器,叫做“TFIDFVectorizer”它以稍微复杂一点的方式统计我们的单词:在这种情况下,矢量器不仅统计一个单词在每个帖子中出现的次数,还考虑该单词在整个语料库(即帖子集合)中的重要性。实际上,我尝试了这两种方法,发现我的模型在 TFIDFVectorizer 和 CountVectorizer 上的表现大致相同。

现在我们有了训练和测试数据,是时候建模了!

4.建模

当完成一个二元分类问题时,有许多方法可以衡量它的表现。可视化这个模型性能的一种方法是通过混淆矩阵,它将显示我的模型生成了多少真阳性、真阴性、假阳性和假阴性。

在我的模型中:

  • 一个真正的肯定是一个预测来自淋浴思想子编辑的帖子,并且确实来自淋浴思想子编辑。
  • 一个真正的否定是一个预测来自深层哲学子编辑的帖子,并且确实来自深层哲学子编辑。
  • 误报是一个预测来自我的淋浴思想子编辑的帖子,但实际上来自深层哲学子编辑。
  • 假阴性是一个预测来自深层哲学子编辑的帖子,但实际上来自淋浴思想子编辑。

在这种情况下,假阳性和假阴性一样糟糕。因为它们同样糟糕,所以我想建立一个模型,使我的准确率尽可能高。

在训练和测试不同的模型之前,我定义了一个函数来打印我的测试集的分类矩阵,并将真/假阳性/阴性分配给变量。由于我计划尝试几个不同的模型,这个函数在评估每个模型的表现时就派上了用场!

我测试了逻辑回归模型、高斯朴素贝叶斯模型、多项式朴素贝叶斯模型和随机森林模型。当根据我的测试集进行测量时,随机森林模型显示出最少的过度拟合和最好的整体性能。然后,我决定在各种超参数上实现 GridSearch,看看能否提高基本随机森林模型的性能。

。有了这两个非常密切相关的子数据集,我的最佳随机森林模型在测试集上有 84%的准确率。(对于一个刚学了六周的人来说,这已经不错了!).是的,它花了很多的调整,这个模型仍然稍微超出了我的训练数据,但这与我开始的地方相比绝对是一个进步。

下面,您将看到一个功能重要性图。这个图直观地显示了每个术语在分类一篇文章所属的子主题中的重要性。“深刻的”和“深刻的思考”是两个最重要的术语,但是“可能”和“意思”在预测某件事是哲学的还是只是一个随机的想法方面出奇的好!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Top 20 most important features of the Random Forest Classifier

注意:作为一个随机森林分类器,Importance被定义为集合中所有树的平均节点杂质(通过到达该节点的概率加权)的总减少量。如果你想了解更多关于节点杂质的知识,可以看看我关于决策树的博文。

5.回答问题

任务完成了!我不确定为什么一家公司想要实现这种预测子数据集的特定模型,但是这种类型的模型在现实世界中有很多应用。例如,电子邮件服务想要检测垃圾邮件,或者公司可能想要尝试检测垃圾评论。这个问题可以用这种方法解决。如果我在一家试图检测垃圾邮件和合法评论的公司工作,我会和一个团队一起将这个模型投入生产并自动过滤评论。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

请随意查看:

我的其他中帖。

我的 LinkedIn 个人资料。

如何用 API 构建 FAQ 聊天机器人?使用 Node.js 和 PHP 的人工智能

原文:https://towardsdatascience.com/how-to-build-an-faq-chatbot-with-api-ai-using-node-js-a802aff53e6a?source=collection_archive---------1-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通用聊天中,我们实现了一个聊天机器人,任何人都可以毫不费力地训练它。逻辑很简单;只要给它你的问题和答案,机器人就会回复任何提出类似问题的顾客。

在本文中,我将向您展示我们是如何做到这一点的,这样您也可以这样做。

框架的选择

首先,我测试了许多不同的机器学习框架——Wit。AI,微软认知服务,我瞄了一眼 Luis……对我来说,原来是 API。AI 是正确的选择。它是完全免费的,有很好的响应率,它有一个很好的开发用户界面,并且很容易设置、开始使用和扩展。

我不打算进行 Api.ai 开发,因为那里的文档已经很棒了。Node.js SDK 只有一个缺点;涉及开发人员令牌的方法都没有实现。所以,我创造了我自己的叉子来解决这个问题。随意克隆和使用它。

独特的问题和解决方案

当您构建一个将被许多用户使用的服务时,您希望确保信息不会重叠。例如,一个用户可能会提出一个问题,比如“哪个 ML 框架是最好的?”并将答案设置为“Api.ai ”,而另一个用户可能会将“Wit.ai”作为答案。机器人应该理解哪个用户正在被询问,并返回相应的答案。

为了解决这个问题,我们使用了上下文变量——通过定义上下文,我们可以在一个单独的线程上为每个用户和她的客户端分离答案。

让用户创建他们自己的常见问题

Api.ai 非常聪明——将它变成一个对话代理只是添加新的意图并定义机器人的响应。您还可以通过从 Api.ai 库中导入现成的模板来丰富体验,这会让您在自己的领域中占得先机。

要创建新的意图,你需要我之前提到的 github fork

在我们开始之前还有一个问题。聊天机器人不会一直准确无误。当这种情况发生时,我们需要一种后退的方法。

通用聊天中,我们用两种方式来处理这个问题:

  1. 对于每个回答,我们允许访问者升级到一个实时操作员。当访问者这样做时,我们也会记录他们提出的问题,以便以后可以将正确答案添加到数据库中
  2. 有时 Api.ai 找不到答案,在这种情况下,它会返回“input.unknown”结果。这是另一个需要注意和创造问题的地方

所以,现在我们有了所有的原料;

  • Api.ai 作为机器学习框架
  • 可以正确创建新意图的 Node.js 分支
  • 如何构建它的路线图

让我们开始吧。我不会详细讨论你在网上其他地方可以找到的问题,但是我会向你展示我们上面讨论的两个主要问题:使用上下文调用和创建意图。

在上下文中调用

我们将创建这个方法来查询 Api.ai:

函数 ask(text,options){
let apiaiRequest = apiai . text request(text,options);

apiaiRequest.on('response ',(response)= > { console . log(response);})

apiaiRequest.on('error ',(error)= > { console . log(error);});

apiairequest . end();
}

然后,您可以这样查询它:

询问(‘某个问题’,{
sessionId:'某个会话的某个唯一 Id ',
上下文:[{名称:‘用户 1’ }]
}

仅此而已。用更有用的代码替换 console.log 代码。在 github 中,我展示了如何使用 promises 来重写上述内容,以获得更干净的替代方案。

创造新的意图

要创建新的意图,请使用 POST 方法。同样,所有这些都是有据可查的,所以我们只讨论新的内容:

函数 create intent(options){
return new Promise((resolve,reject)=>{
let request = app . intentpostrequest(options);

request.on('response ',(response)= > { return resolve(response);});

request.on('error ',(error)= > { return reject(error);});

request . end();
})
}

现在,像这样调用它:

var opts = {“name”: " “,
“auto”: true,
“templates”: [” <新问题> " ],
“contexts”: [’ <上下文> ’ ],
" user says “:[
{ " data “:[{ " text “:<新问题> “} ],” isTemplate”: false,” count”: 0 }],

创建意图(opts)

需要注意的重要事项:

  • 不要忘记auto:true——否则你将无法从机器学习的魔力中获益
  • 你可能已经注意到我用了几次“新问题”——没关系,它很有效
  • 您还注意到,我们在这里包含了上下文—保证问题和答案被保存起来,并分别提供给每个客户

奖金;用 PHP SDK 创建意图

如果你已经建立了一个网站来管理这些东西,你可以使用 PHP SDK。同样,最初的那个也不支持创建意图,所以我们在这个分支中添加了它。Readme.md 中有一个不言自明的例子,所以我不会在这里打扰你。

结论

现代机器学习框架使得建立对话代理变得非常容易——你刚刚在不到 4 分钟的时间里见证了一个对话代理。只是一定要引入适当的回退,以便在遇到更难的查询时拯救机器人的皮肤。

如何为数据集构建图像重复查找器

原文:https://towardsdatascience.com/how-to-build-an-image-duplicate-finder-f8714ddca9d2?source=collection_archive---------12-----------------------

借助神经网络隐藏层执行图像相似性分析

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

This is a duplicate found by the algorithm

当你从网上下载图片时,你通常会发现有噪音的数据。此外,流行的图片到处都是。一个接一个地查看它们并试图找到重复项来清理数据集是很乏味的。

考虑到这个问题,我构建了一个重复查找器来为您查找重复项,因此您只需选择是否要删除它们。你可以在 fastai 库中找到代码。在这篇文章中,我将解释我是如何构建这个工具的。

步骤 1:获取激活

我们通常使用 CNN 对图像进行分类,我们只对网络末端 softmax 的输出感兴趣,它会告诉我们网络认为我们图像的标签是什么。在这种情况下,我们将比较网络的内层,希望网络学习的一些特征有助于找到相似的图像。为了实现这一点,我利用了 fastai 库中强大的 钩子 功能,它允许我们保存网络中任何子层的激活。

hook = hook_output(learn.model[0][7][2])

我使用的激活是 Resnet 架构的最后一个卷积块的输出,因为我注意到它们在经验上工作得更好。

第二步:合并

您可能知道,CNN 中的隐藏层有四个维度:批量大小、特征数量、高度和宽度。让我们假设我们正在谈论一个特定的图像,或者 bs=1。例如,在 Resnet 50 的情况下,最后一层的输出将具有维度( 1,512,7,7)。由于这里的维数非常高,计算相似度将非常耗时,这对用户来说是一种痛苦。这个问题的答案是用。我们将汇集每一个 7x7 矩阵,从而得到一个维度为的张量(1,512,pool_dim,pool_dim)。

我使用的池函数是 AdaptiveConcatPooling(自适应平均池和自适应最大池连接在一起),我使用的池维数是 4,因为我发现它是速度和性能的良好组合。

第三步:展平

我们用一个四维张量结束了最后一步。然而,为了计算不同例子之间的相似性,我们需要一维张量(向量)。我们将展平每个图像的激活,以获得大小为 pool_dim x pool_dim x 512 的向量,并将每个图像的向量连接成一个具有维度的矩阵( n_exs,vector_dim )。现在我们有了每个 n_exs 图像的特征向量。是时候计算相似度了!

def get_actns(learn:Learner, dl:DataLoader, hook:Hook, pool=AdaptiveConcatPool2d, pool_dim:int=4, train:bool=True):
"""Gets the activations at the layer specified by `hook`, 
   applies `pool` of dim `pool_dim` and concatenates.""" pool = pool(pool_dim) 

    actns = []
    learn.model.eval()
    with torch.no_grad():
        for i,(xb,yb) in enumerate(dl):
            learn.model(xb)
            actns.append((hook.stored).cpu())

    return pool(torch.cat(actns)).view(len(dl.x), -1)

第四步:计算相似度

为了计算每个特征向量之间的相似度,我们将使用余弦相似度函数。请注意,如果我们将每个向量与其他向量相结合,所有的相似性都会被计算两次。还要注意,如果我们计算一个向量与其自身的相似性,相似性的度量显然是最高的。因此,对于我们的相似性矩阵,我们将用零替换对角线和右上部分。

def comb_similarity(t1: torch.Tensor, t2: torch.Tensor, sim_func=nn.CosineSimilarity(dim=0)):
    """Computes the similarity function `sim_func` between each embedding
       of `t1` and `t2` matrices.
       t1` and `t2` should have dimensions [n_embeddings, n_features]."""

    self_sim = False
    if torch.equal(t1, t2): self_sim = True

    sims = np.zeros((t1.shape[0], t2.shape[0]))
    for idx1 in range(t1.shape[0]):
        for idx2 in range(t2.shape[0]):
            if not self_sim or idx1>idx2:
                ex1 = t1[idx1,:]
                ex2 = t2[idx2,:]
                sims[idx1][idx2] = sim_func(ex1,ex2)

    return sims

第五步:结果

看看我们的方法行不行!让我们看看我们数据集中最相似的图像,看看我们是否能找出一些重复的(我在这里贴了一些截图,更多请访问我的 repo )。我用来测试算法的数据集是牛津-IIIT 宠物数据集,有 37 种狗和猫。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Perfect duplicates. This image was included 5 times in the dataset.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Duplicates (one has a signature)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Similar but not duplicates

我还用 CIFAR10 测试了该算法,cifar 10 是计算机视觉中一个著名的数据集,看我能否找到一些重复的数据。这些是我发现的一些例子:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Perfect duplicate

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Nearly a duplicate truck but with different logos

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Not a duplicate, more like data augmentation

我还运行了 relabeler 小部件,这里有一个额外的有趣发现:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Not a truck

一旦我们有了网络对复制品的建议,我们该怎么处理它们呢?嗯,我们应该选择那些实际上是重复的,并从我们的数据集中删除它们,因为有重复会导致网络对这些图像给予太多的重视。怎样才能轻松删除重复?有了 fastai 的互动小工具就非常容易了!您可以通过运行以下命令来尝试一下:

from fastai.widgets import *ds, fns_idxs = DatasetFormatter.from_similars('learner')
ImageCleaner(ds, fns_idxs, path, duplicates=True)

想用吗?用 CIFAR 查看我的教程笔记本

如何构建和部署歌词生成模型——与框架无关

原文:https://towardsdatascience.com/how-to-build-and-deploy-a-lyrics-generation-model-framework-agnostic-589f3026fd53?source=collection_archive---------7-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你会发现大量关于如何建立机器学习模型的文章。你会发现关于如何明智地消费它的文章比较少。而且你会发现几乎没有关于如何从零开始服务它的文章。

我将详细说明我们到上面可以看到的产品的步骤:rap lytics . eu所有代码都是开源的,可以在 GitHub 上获得。

更新:在这篇帖子中,我们提出了一种更具成本效益、更直接的方式来为你的机器学习项目服务。

什么?

和我的一个好朋友一起,我们真的很喜欢听说唱音乐。说唱音乐是强大的,因为它有能力只用几个词就创造出野蛮的笑点。
由于仍然很难用 RNN 生成长文本,我们认为说唱音乐是一个很好的候选。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The final product

怎么会?

大局

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Project’s architecture

我不会在帖子中过多描述实现,因为我们试图在代码库中做到详尽,见READMEs。我将坚持对我们具有挑战性的转折点。

基本的系统管理员知识和 unix 熟练程度会有所帮助。

1-数据提取和处理

GitHub 库: RapLyrics-Scraper

—刮削

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先,我们需要一个数据集来训练我们的神经网络。

足够幸运的是,Genius.com有大量的在线歌词,甚至还有一个不错的 API

它可能不是为废弃歌词而设计的,但通过一些变通方法,我们设法在它上面建立了一个歌词刮刀。

如果您需要技术细节,请查看源代码或在评论中寻求帮助。
经过多次拍摄,我们意识到专注于高质量的自然语言处理数据集非常重要。我们决定关注 40 位美国艺术家的 60 首最受欢迎的歌曲。

✔:报废了。

预处理

抓取部分为我们提供了一个.txt数据集。我们现在必须清理它— 删除非抒情内容:、演职员表、错别字和同一单词的各种拼写。想想gettin'getting之类的东西。

我们遵循的方法:
1。识别模式以消除
2。手工正则表达式捕捉那些模式— 正则表达式测试资源:pythex.org
3 .使用文本编辑器直接在数据集上执行这些正则表达式

如果你想自动清理正则表达式,要知道这是有风险的。您必须彻底考虑执行正则表达式的顺序。

扩充数据集 【可选】

我们只选择了歌词真正有意义的艺术家,我们选择了他们最受欢迎的歌曲。这并不构成一个庞大的语料库。因此,我们决定执行一个数据扩充步骤,以便实际上增加我们数据集的大小。

📖数据扩充意味着增加数据点的数量。在我们的上下文中,它意味着增加句子的数量。

我们复制了我们的数据集,打乱了所有的诗句,然后把它粘贴到原始数据集的末尾。

你可以在这里找到一个关于如何打乱段落的片段。

使用这个技巧,我们将数据集的大小加倍。这将对神经网络的训练产生积极的影响。实际上,由于洗牌,每个新批次都是不同的,所以网络权重用不同的输入来更新。

✔:数据扩充到此结束。

2-建立歌词生成模型

标注文本创成式模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

许多神经网络实现可在线获得。我们选择了一个并对其进行了微调以满足我们的需求: textgenrnn一个使用神经网络生成文本的 python 项目

您可以在我们的代码库中找到模型超参数和训练设置的基本描述READMEs

本文的目的不是深入研究神经网络设计。实现就不细说了。您可以查看源代码或在评论中 ping 我们。

训练文本生成模型

根据您的数据集和配置,您可以考虑使用云计算来加速训练。我们使用 AWS——亚马逊网络服务。

如果您在本地培训您的模型,您可以跳过这一部分。否则,考虑到下面的部分会变得有点技术性。

我会更详细地介绍我们的训练设置,因为这需要我们花时间去适应。

我们启动了 aws ec2 spot 实例来降低成本。我们需要至少 3gb 的内存和 8gb 的默认固态硬盘足够了。训练不是 GPU 加速的(一个改进点)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

83% savings on a spot instance comparing to a classic ec2 instance

ec2 spot 实例与传统 ec2 实例有何不同?

您出价购买一个具有特定规格的 ec2 实例,只要您的出价高于平均市场价格,您就拥有了一个行为类似经典 ec2 的实例。

如果你的出价低于市场价格,你的实例在一个短时间通知后被终止。关于聚光灯实例的更多信息。

我们提出了一个现场请求,很快就完成了,然后我们克隆了我们的 repo 并安装了一个包含所有项目需求的 python3 虚拟环境。

注意:如果您想要保存您的模型检查点,您需要使您的实例能够在 s3 存储桶上写入(如图所示👇)

texgenrnn 在每个时期保存一个模型检查点。

  • 为了应对实例终止的风险并在安全的地方保存我们的检查点,我们使用aws cli在 aws s3 桶中复制检查点。cd到您的检查点文件,并将它们复制到您的 s3 存储桶。
# run `pip install awscli` beforehand
aws s3 cp my-checkpoint-file.ckpt s3:*//my-s3-bucket/model-saves/*

注意:要做到这一点,您需要向实例授予对 ec2 的写权限。为此,向您的 ec2 实例添加一个角色,使用 s3 完全访问和 ec2 完全访问策略,如下图所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Attach those 2 policies to the IAM role attached to your ec2 instance.

政策处理中有许多偷偷摸摸的细节,不要犹豫,在评论中问我们。

——————测试文本生成——

一旦你训练好了你的模型,你就可以使用 Jupyter 笔记本[RapLyrics-Back/exploration/sample_explorator.ipynb](https://github.com/cyrilou242/RapLyrics-Back/blob/master/exploration/sample_explorator.ipynb)来生成你的第一首人工智能歌词。

3。服务于文本生成模型

为了给用户提供更好的歌词,我们使用了一个自定义生成函数

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们使用 gunicorn烧瓶上提供应用程序。这个想法是不要在每次 API 调用时重新加载模型——这会导致很长的响应时间。
我们只在应用程序初始化时恢复一次会话,它在 API 调用之间持续存在。

API 调用及其响应的演示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

curl on back-end

如果您还没有实现该模型,请随时调用我们的 API:

curl '[https://raplyrics.eu/apiUS'](https://raplyrics.eu/apiUS') -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "input=struggle"

参见api/serve_us.py中的get_model_api_us函数,了解我们如何建立一个持久的张量流会话。只需从 shell 中运行gunicorn app:app来启动应用程序。模型默认在127.0.0.1:8000端上。

你现在可以在将被用作网络服务器的机器上克隆 RapLyrics-Back

4-插入前端

GitHub 资源库: RapLyrics-Front

本文描述了 apache web 服务器的必要步骤。如果没有它sudo apt-get install apache

将所有要提供的文件从 RapLyrics-Front 移动到/var/www/html/
记住在index.html 中更新你的端点的"url"设置就这样,你就大功告成了(差不多)。现在,您可以通过网络浏览器访问您的服务器ip来访问网站。

生产设置 【可选】

如果您想让前端和后端在同一台机器上使用 https 连接,下面是几个步骤。

1.让我们加密我们的网站🔒→按照如何用加密来保护 Apache 的步骤进行(数字海洋有非常棒的教程)

2.当用户提交输入时,apache 服务的index.html调用raplyrics.eu/apiUS。事实上,阿帕奇上没有/apiUS航线。我们需要将这个调用重定向到运行在同一台机器上的gunicorn服务器。这就是所谓的反向代理。

让我们来处理这两个步骤。
由于代码与 apache 配置相关,因此不受版本控制。

  • /etc/apache2/sites-available

您应该会看到一个000-default.conf和一个000-default-le-ssl.conf文件。它们是模板文件,处理 apache 如何服务于 http 和 https ( le-ssl)网站的配置。

我们为我们的网站复制了一份。(用您的域名替换raplyrics.eu👇)

sudo cp 000-default.conf raplyrics.eu.conf
sudo cp 000-default-le-ssl.conf raplyrics.eu-le-ssl.conf

1。将流量从 **http** 重定向到 **https**

编辑raplyrics.eu.conf以包括以下重写条件:

Rewrite rules to redirect traffic from http to https. Remember to replace raplyrics.eu by your site name.

2。反向代理 API 调用

编辑raplyrics.eu-le-ssl.conf以包含代理反向指令。

Reverse proxy to redirect the API call to the gunicorn app

在这里,我们处理从raplyrics.eu/apiUS127.0.0.1:8000的本地 gunicorn 服务器的代理传递

现在我们告诉 apache 更新网站配置:

sudo a2ensite raplyrics.eu.conf
sudo a2ensite raplyrics.eu-le-ssl.conf

最后,sudo systemctl restart apache2要把变化考虑进去。

就这样,你在制作中。🚀
你可以在 raplyrics.eu 上查看我们的

参考📚

关于在 heroku 上提供 python 应用的有趣博客文章(Heroku dynos 无法处理我们的应用——没有足够的 ram)很好地描述了步骤。

Apache 2 上的反向代理

数字海洋在 apache 上的反向代理,数字海洋再次做了一个非常值得赞赏的文档工作,非常详细。

非常有趣,所以在上发布如何用 GitLab 和 AWS 构建 CI / CD 管道

神经网络参数微调的启示

有趣的关于微调批量训练参数的交叉验证帖子。

谷歌大脑论文提出了一组文本生成 LSTM 的超级参数(尤其是 4。我们用例的实验和 4.1 语言建模。)

如何像汉斯·罗斯林一样制作动画图表——全部用 R 语言完成

原文:https://towardsdatascience.com/how-to-build-animated-charts-like-hans-rosling-doing-it-all-in-r-570efc6ba382?source=collection_archive---------3-----------------------

一个学习数据可视化技能的小型教育项目,利用了两个库(gganimate 和 plot . ly)——更新了新的 gganimate 版本

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

汉斯·罗斯林是统计学大师。他毕生致力于推动使用数据和动画图表来探索发展问题,并分享基于事实的世界观。他最受欢迎的 TED 演讲:“你见过的最好的统计数据”点击量超过 1200 万次。这也是世界上 100 个最受欢迎的 TED 演讲之一。

你曾经梦想过像他的 最受欢迎的一张 一样免费制作动画图表吗,从零开始,不到 5 分钟,并且可以以不同的格式(gif,html 用于你的网站等)共享。)?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

What we will be building with gganimate 😉

本文将向您展示如何使用两种方法用 R 构建动画图表:

  • 将创建 GIF 文件的 R + gganimate 库
  • R + plot.ly 将生成一个 HTML 文件,您可以将它嵌入到您的网站中(参见下面的 plot.ly 版本)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

What we will be building with plot.ly 😉

假设您已经安装了 Rstudio,并且了解一些基础知识,因为本文将只介绍生成视觉效果的步骤和代码。完整代码可从 Github 上获得,用于教育目的。

第一步:搜索并下载你需要的数据集

第一站是在gapminder.com下载所需的 3 个数据集。这个基金会是罗斯林家族创立的。它有奇妙的可视化和数据集,每个人都应该检查“用每个人都能理解的基于事实的世界观来战胜无知”。

我们将下载 3 个 excel 文件(xlsx):

  1. 每名妇女的子女数(总生育率)
  2. 人口总数
  3. 预期寿命(年)

一旦文件被下载并保存在你的工作文件夹中,就该清理并合并数据集了。

第二步:清理并合并数据

a1)用 xlsx 库加载数据(替换’…'您的文件夹旁)

# Please note that loading xlsx in R is really slow compared to csvlibrary(xlsx)population_xls <- read.xlsx("indicator gapminder population.xlsx", encoding = "UTF-8",stringsAsFactors= F, sheetIndex = 1, as.data.frame = TRUE, header=TRUE)fertility_xls <- read.xlsx("indicator undata total_fertility.xlsx", encoding = "UTF-8",stringsAsFactors= F, sheetIndex = 1, as.data.frame = TRUE, header=TRUE)lifeexp_xls <- read.xlsx("indicator life_expectancy_at_birth.xlsx", encoding = "UTF-8", stringsAsFactors= F, sheetIndex = 1, as.data.frame = TRUE, header=TRUE)

a2)更新—在 R 版本 5.3+上安装 gganimate 新版本

library(devtools)
library(RCurl)
library(httr)
set_config( config( ssl_verifypeer = 0L ) )
devtools::install_github("RcppCore/Rcpp")
devtools::install_github("thomasp85/gganimate", force = TRUE)

b)使用 reshape 和 dplyr 库清理和合并数据

# Load libraries
library(reshape)
library(gapminder)
library(dplyr)
library(ggplot2)# Create a variable to keep only years 1962 to 2015
myvars <- paste("X", 1962:2015, sep="")# Create 3 data frame with only years 1962 to 2015
population <- population_xls[c('Total.population',myvars)]
fertility <- fertility_xls[c('Total.fertility.rate',myvars)]
lifeexp <- lifeexp_xls[c('Life.expectancy',myvars)]# Rename the first column as "Country"
colnames(population)[1] <- "Country"
colnames(fertility)[1] <- "Country"
colnames(lifeexp)[1] <- "Country"# Remove empty lines that were created keeping only 275 countries
lifeexp <- lifeexp[1:275,]
population <- population[1:275,]# Use reshape library to move the year dimension as a column
population_m <- melt(population, id=c("Country")) 
lifeexp_m <- melt(lifeexp, id=c("Country")) 
fertility_m <- melt(fertility, id=c("Country"))# Give a different name to each KPI (e.g. pop, life, fert)
colnames(population_m)[3] <- "pop"
colnames(lifeexp_m)[3] <- "life"
colnames(fertility_m)[3] <- "fert"# Merge the 3 data frames into one
mydf <- merge(lifeexp_m, fertility_m, by=c("Country","variable"), header =T)
mydf <- merge(mydf, population_m, by=c("Country","variable"), header =T)# The only piece of the puzzle missing is the continent name for each country for the color - use gapminder library to bring it
continent <- gapminder %>% group_by(continent, country) %>% distinct(country, continent)
continent <- data.frame(lapply(continent, as.character), stringsAsFactors=FALSE)
colnames(continent)[1] <- "Country"# Filter out all countries that do not exist in the continent table
mydf_filter <- mydf %>% filter(Country %in% unique(continent$Country))# Add the continent column to finalize the data set
mydf_filter <- merge(mydf_filter, continent, by=c("Country"), header =T)# Do some extra cleaning (e.g. remove N/A lines, remove factors, and convert KPIs into numerical values)
mydf_filter[is.na(mydf_filter)] <- 0
mydf_filter <- data.frame(lapply(mydf_filter, as.character), stringsAsFactors=FALSE)
mydf_filter$variable <- as.integer(as.character(gsub("X","",mydf_filter$variable)))
colnames(mydf_filter)[colnames(mydf_filter)=="variable"] <- "year"
mydf_filter$pop <- round(as.numeric(as.character(mydf_filter$pop))/1000000,1)
mydf_filter$fert <- as.numeric(as.character(mydf_filter$fert))
mydf_filter$life <- as.numeric(as.character(mydf_filter$life))

第三步——升级到新版 gganimate:用 gganimate 构建图表并生成 GIF 文件与你的朋友分享

现在我们有了一个包含 3 个 KPI(人口、生育率和预期寿命)和 3 个维度(国家、年份、洲)的清晰数据集,我们可以用 gganimate 生成可视化效果。

# Load libraries
library(ggplot2)
library(gganimate)
#library(gifski)
#library(png)# Add a global theme
theme_set(theme_grey()+ theme(legend.box.background = element_rect(),legend.box.margin = margin(6, 6, 6, 6)) )# OLD VERSION
# Create the plot with years as frame, limiting y axis from 30 years to 100
# p <- ggplot(mydf_filter, aes(fert, life, size = pop, color = continent, frame = variable)) +
#  geom_point()+ ylim(30,100)  + labs(x="Fertility Rate", y = "Life expectancy at birth (years)", caption = "(Based on data from Hans Rosling - gapminder.com)", color = 'Continent',size = "Population (millions)") + 
#  scale_color_brewer(type = 'div', palette = 'Spectral') 
# gganimate(p, interval = .2, "output.gif")# NEW VERSION# Create the plot with years as frame, limiting y axis from 30 years to 100
p <- ggplot(mydf_filter, aes(fert, life, size = pop, color = continent, frame = year)) +
  labs(x="Fertility Rate", y = "Life expectancy at birth (years)", caption = "(Based on data from Hans Rosling - gapminder.com)", color = 'Continent',size = "Population (millions)") + 
  ylim(30,100) +
  geom_point() +
  scale_color_brewer(type = 'div', palette = 'Spectral') + 
  # gganimate code
  ggtitle("Year: {frame_time}") +
  transition_time(year) +
  ease_aes("linear") +
  enter_fade() +
  exit_fade()# animate
animate(p, width = 450, height = 450)# save as a GIF
anim_save("output.gif")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在你可以享受你当之无愧的 GIF 动画,并与你的朋友分享。

第四步:用 plot.ly 构建图表并生成一个 HTML 文件嵌入你的网站

# Load libraries
library(plotly)
library(ggplot2)# Create the plot
p <- ggplot(mydf_filter, aes(fert, life, size = pop, color = continent, frame = year)) +
  geom_point()+ ylim(30,100)  + labs(x="Fertility Rate", y = "Life expectancy at birth (years)", color = 'Continent',size = "Population (millions)") + 
  scale_color_brewer(type = 'div', palette = 'Spectral')# Generate the Visual and a HTML output
ggp <- ggplotly(p, height = 900, width = 900) %>%
  animation_opts(frame = 100,
                 easing = "linear",
                 redraw = FALSE)
ggp
htmlwidgets::saveWidget(ggp, "index.html")

代码可在 Github 上获得。感谢你阅读我的帖子,如果你喜欢,请鼓掌。如果你想在你的组织内制作动画图表,请随时联系我。

其他有趣的链接,了解有关 R 动画图表的更多信息:

[## 了解关于 Gapminder 的更多信息

Gapminder 是一个独立的瑞典基金会,没有任何政治、宗教或经济背景。Gapminder 是一个…

www.gapminder.org](https://www.gapminder.org/about-gapminder/) [## dgrtwo/gganimate

用 ggplot2 创建简单的动画

github.com](https://github.com/dgrtwo/gganimate/blob/master/README.md)

我如何建立一个数据科学实验室并休假

原文:https://towardsdatascience.com/how-to-build-data-science-unit-f84ee3de63f5?source=collection_archive---------9-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

毫无疑问,对数据分析的需求巨大,几乎每家公司都希望被视为数据驱动型,能够提取有用的见解,最终使其在竞争中处于领先地位。以人工智能和机器学习为实现目标,数据科学部门正在发展,将继续在各种规模和行业的组织内传播

尽管如此,建立这样一个单位肯定是一个挑战,因为它的研究&创新性质及其所有后果和所需的资本投资。所需的技能目前很难在市场上找到,但通过获得支持,组建和组织合适的团队,你可以保证成功和盈利。

JLL ,作为一家企业房地产公司(财富 500 强),为我们的客户管理着大量的建筑组合,因此产生了大量的数据。在过去,这些数据主要用于可视化和报告,但问题是,我们能否通过应用数据科学做一些更高级的事情,并提取更多有意义的有用信息,以造福于我们的客户?带着这个目标,我们开始了我们的旅程,这使我们得以开发一个数据科学实验室,到目前为止,这是一个由六名数据科学家和工程师组成的团队,他们在工作场所、能源&可持续发展和设施管理领域提供创新的高级分析解决方案。

许多这样的单元在早期阶段失败或经历巨大困难,我们的开始也不例外。这是一条崎岖不平的道路,但在几个月内,我们的团队设法建立了一个平稳运行的实验室。下面你会发现我的一些最重要的非技术性提示,你可能希望遵循它们来节省时间和金钱,抄近路,避免可避免的错误。它们展示了新团队遇到的最常见问题和解决方案,可以帮助任何数据科学团队取得更大的成功。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1。 从你的上级和下级那里获得支持

没有适当的支持,你的项目将一事无成。首先,你的赞助商需要明白,组建一个数据科学部门很像为一家初创企业融资**,它需要投资和时间来获得盈利。所需的时间取决于许多变量和限制因素,但应该在您的项目计划中明确定义,因为通常需要9-18 个月才能开始显示积极的结果。**

虽然非常重要,盈利能力不应该是一个单位的唯一目标,因为建立正确的团队会带来其他切实的利益,包括为您的公司提供数据驱动的&创新形象,这可能在其他业务部门产生收入,并帮助公司在竞争中处于领先地位。并非每个客户都准备好了成熟的数据科学解决方案,但总有空间开发更简单的产品,如数据管理、报告或可视化。

发展一个数据科学部门就像坐过山车一样,这是大多数初创企业的经历。因此,要取得成功,你需要获得赞助商的信任和自由,以及在你进步和适应不断变化的环境的过程中做出自己决定的灵活性。

此外,该部门应在组织内尽可能靠近首席信息官/CDO** 进行**定位,以确保其他部门有足够的资金、影响力和支持。建立数据科学团队不是一个人的工作,而是需要利益相关者的积极参与,尤其是那些将直接或间接受益于您所在单位的利益相关者。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2。 发现人才,组织好他们

建立一个团队可能是棘手的,往往需要许多权衡,例如在预算和薪水、硬技能和软技能、专业化和普遍化、个性或数据能力和职位之间找到正确的平衡。最好和一个新的团队一起开始新的生活,这个团队将致力于这个单位和你的目标。在从市场人才库中招聘新员工之前,先从你的组织内部寻找可用的人才,然后从外部寻找最优秀的人才,这些人才将带来打破常规的思维,不会受到组织文化的偏见或威胁。

由于高需求,招募优秀的数据科学家可能是一个相当大的挑战。为了获得外部帮助,不要犹豫使用你自己和其他团队成员的专业网络、数据科学聚会和会议,因为这些可能是最有效的招聘手段。

运行一个单元需要多少数据科学家和工程师?从小处着手,按需增长。根据您组织的规模,通常您可以从 3 到 4 名数据科学家开始,并随着新业务的出现而扩展。

人工智能和数据科学炒作的一个不利方面是,可用的熟练数据科学家短缺。不要指望找到一个完全符合你的具体工作规格。科技技能差别很大,公司对数据科学家必备能力的认知也不尽相同,他们会根据自己的需要进行培训,但总会有灵活、愿意学习并随时准备迎接新挑战的能干的候选人。

硬技能是非常重要的,但要记住,如果一个潜在的候选人是缺乏某些领域,他们总是可以培训,以满足你的期望。招聘时,要专注于最基本的技能,比如机器学习、用 R/Python 编程以及在 sharing 或 Tableau 中创建可视化效果。然而,你的关注点应该是软技能,个性以及候选人与你的团队保持一致的能力。最好是组建一个性格各异的团队,由谁来平衡团队的情绪——根据我的个人经验,我建议你也加入一个“T10”叛逆!他们经常帮助刺激必要的改变,不害怕风险,愿意在需要的时候努力工作。

无论你的组织的文化,创造力是任何创新单位的基本要素。重要的是要推广由有着共同目标的专家组成的临时启动机构。这将有助于支持团队敏捷性、开箱即用的思维、协作、文化共享、开放性和完整性。不要忘记使用个人培训方式培养你的团队,其中应包括在线课程和参加会议。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3 . 着力打造有形效益

由于过度设计交付的解决方案,大量数据科学、通用研究和创新部门在某个时候出现了故障。始终记住必要的开发工作、时间和成本,因为在大多数情况下,解决方案甚至是基于规则引擎的解决方案通常满足客户期望,并且可能不需要到处部署深入学习。瞄准最简单的那些可以快速部署并且易于维护的。

由于数据科学是一个相对较新的概念(由来已久),许多客户可能没有特定的需求,只是依赖您来提供有用的解决方案。做你的学术和工业研究,和你的团队一起头脑风暴用例,咨询专家和你的客户,为了概念证明,只选择那些给你的客户带来切实利益的用例(速赢)。当然,我的意思是…钱!因此,专注于能够节约成本、提高运营绩效、增加收入或带来竞争优势的解决方案。

运行数据科学计划时,无论您的起点是研究、概念验证还是试点,都要利用项目管理和软件开发方法。为了完成这类项目的研究性质,调整和定制敏捷方法,包括 scrum、快速原型和连续交付,这将确保成功完成。

从项目的角度看待你单位的发展没有结束日期的限制。您的最终产品应该按照您在路线图中定义的中间步骤交付。这应作为至少 2-3 年的总体规划,并与您的使命和愿景(或同等目标)一起尽早确定(随着您的发展,在必要时进行更改)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

4。 培养研究和创造力

这说起来容易,但是如何在团队中激发好奇心、学习和创造力呢?这些是每个数据科学部门取得成功的基本因素。你会经常发现自己在未知的水域航行,研究新方法,并首次将它们应用到主题中。因此,你需要一个能够一起工作、分享想法、集思广益并提出解决方案的团队——但这是如何做到的呢?

重要的是不要让你的团队承担过多的项目,给他们留一些研究和自我发展的空间。你甚至可以批准一些特殊的时间,比如每周五举行创意会议**,学习新技术,研究选定的主题等等。**

多元化是与团队及其项目/职责相关的另一个关键因素。在一个单位里,不同个性的人结合在一起,肯定能引发建设性的讨论。

通过促进开放、非正式文化,知识共享和引入创意会议或实践社区来加强沟通,这可能会拓宽每个成员和团队的界限。此外,通过混合项目团队,转移重点和责任领域,团队将获得更广阔的业务视角,并将能够从不同角度理解主题。

领导者的角色还包括提供愿景并定义所采取措施的目的。给团队成员一个关于组织目标的更广阔的视角,向团队灌输他们是更大项目不可或缺的一部分,并帮助他们理解他们的个人工作如何适应整体战略。

团队成员也应该有自主权和信任来进行项目并做出自己的决定。给失败留有余地必要时提供辅导。因此,您应该拥有自我驱动和富有创造力的数据科学家,他们可以研究某个主题,定义 PoC 所需的方法,并端到端地实施项目。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5。 营销和 UX

在房地产领域,我们喜欢说——位置,位置,位置。在确保一个萌芽的数据科学部门成功起步的情况下,我认为关键词是——营销、营销、营销。如果没有适当的营销,即使是最先进的解决方案,也可能会产生巨大的成本节约。因此,投入巨资将您的解决方案包装成带有营销材料的产品,包括网站、社交媒体和其他可用渠道。因为你不可能在每个领域都是专家,向你公司的市场营销和销售人员寻求支持

然而,任何数据科学解决方案成功的关键因素如何将见解交付给最终用户,以及他如何与解决方案互动。因此,不要只局限于 Tableau、Shiny 或其他类似产品中的数据可视化,而是要投资于适当的 UI 和 java script web 应用程序开发。

雇佣专家或顾问和培训你剩下的数据科学家进行现代 UI/UX 设计,因为它是你的前端,反映客户的需求,提供可用性并提供愉快的体验,这将增加你的客户对更多的胃口,并显著促进你的销售。毕竟视知觉才是关键。

那休假呢?

当我写这篇文章时,我正在夏洛茨维尔,这是许多美国总统的绿色家园,也是许多矛盾的地方。在过去的几个月里,我们的家庭扩大了,我的妻子在弗吉尼亚大学获得了一笔有声望的研究基金,我们决定我们三个人在美国呆 4 个月。因此,我现在正在休公休假/育儿假,专注于我最近忽视的家庭和研究——写一篇学术论文,与研究人员会面,开阔我的视野。

在扩大规模阶段离开我的团队绝对不是一个容易的决定,但我花了几周时间为他们做准备。我的团队中的大多数人都是经验丰富、自我驱动的数据科学家,他们可以独自忽略他们的项目,并继续创造新的业务。然而,我考虑到,由于缺乏明确的领导和研究指导,团队的创造力可能会受到影响。因此,该股目前的重点是向新客户宣传现有产品,而不是确定新的解决方案。然而,在短期内,我缺席的影响应该是有限的,而是有助于团队的成熟。

最后一条建议是,坚持建立自己的数据科学部门。你会遇到许多障碍,但请记住——如果你不成功,没人会成功。像我们大多数人一样,你也可能不是每个主题的专家,所以尽管这可能很难,但试着让你周围的人填补你的知识或专业知识的空白——最好是在某些领域比你更有成就的人。

坚持不懈,你就会成功——祝你好运!

当然,这篇文章只是触及了表面。因此,请随时在 LinkedIn 上留下您对该主题的经验或看法或联系方式。

## Przemyslaw Pospieszny 博士| LinkedIn

如何用自然语言处理构建基于内容的电影推荐系统

原文:https://towardsdatascience.com/how-to-build-from-scratch-a-content-based-movie-recommender-with-natural-language-processing-25ad400eb243?source=collection_archive---------0-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

“empty brown theater chairs” by Tyler Callahan on Unsplash

在某种程度上,我们每个人肯定都想知道网飞、亚马逊、谷歌给我们的所有推荐来自哪里。我们经常在互联网上对产品进行评级,我们表达的所有偏好和分享的数据(明确地或不明确地)都被推荐系统用来产生实际上的推荐。推荐系统的两种主要类型要么是协作式的,要么是基于内容的过滤器:这两个名称都是不言自明的,但是让我们看几个例子来更好地理解它们之间的区别。我将使用电影作为例子(因为如果可以的话,我会一直看电影/电视节目),但是请记住,这种类型的过程可以应用于您观看、收听、购买的任何类型的产品,等等。

协同过滤器

这种类型的过滤器是基于用户的比率,它会向我们推荐我们尚未观看过,但与我们相似的用户已经观看过,并且喜欢的电影。为了确定两个用户是否相似,该过滤器考虑他们观看的电影以及他们对电影的评价。通过查看共同的项目,这种类型的算法将根据相似用户的评价,基本上预测尚未观看该电影的用户的评价。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Collaborative-based filter.

为了准确地工作,这种类型的过滤器需要评级,并且不是所有用户都不断地对产品进行评级。他们中的一些人几乎从不评价任何东西!这种方法的另一个特点是建议的多样性,这可能是好的或坏的,取决于具体情况。比如说用户 A 非常喜欢反乌托邦电影和黑色喜剧。用户 B 也喜欢反乌托邦电影,但从未看过黑色喜剧。协作过滤器将基于两个用户对反乌托邦电影的共同品味,向用户 B 推荐黑色喜剧表演。这种情况可能有两种方式:要么用户 B 发现他/她非常喜欢黑色喜剧,在这种情况下,很好,他/她的列表上有很多新的东西可以看!或者,用户 B 确实喜欢较轻的喜剧风格,在这种情况下,推荐没有成功。

基于内容的过滤器

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Content-based filter.

这种类型的过滤器不涉及其他用户,如果不是我们自己。基于我们喜欢的东西,该算法将简单地挑选内容相似的项目来推荐给我们。

在这种情况下,推荐的多样性将会减少,但是这将会影响用户对事物的评价。如果我们将此与上面的示例进行比较,可能用户 B 潜在地喜欢黑色喜剧,但他/她永远不会知道,除非他/她决定自主尝试,因为该过滤器只会继续推荐反乌托邦电影或类似的电影。当然,我们可以计算许多类别的相似性:在电影的情况下,我们可以决定只基于类型建立自己的推荐系统,或者我们可能希望包括导演、主要演员等等。

当然,现有的过滤器并不只有这两种。还有基于集群或行为的,仅举几个例子。

到目前为止,我已经多次提到这个词*相似性,*但是它到底是什么呢?这似乎不是我们可以量化的东西,但令人惊讶的是它是可以测量的!在进入如何构建基于内容的系统的实际例子之前,让我们简单回顾一下余弦相似性的概念。这是我们在计算用户或内容之间的相似性时可以使用的指标之一。

余弦相似性

我们都很熟悉向量:它们可以是 2D、3D 或其他什么-D。让我们在 2D 想一会儿,因为它更容易在我们的脑海中描绘出来,让我们首先刷新一下点积的概念。两个向量之间的点积等于其中一个向量在另一个向量上的投影。因此,两个相同向量(即具有相同分量的向量)之间的点积等于它们的平方模,而如果这两个向量垂直(即它们不共享任何方向),则点积为零。一般来说,对于 n 维向量,点积可以计算如下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Dot product.

点积在定义相似性时很重要,因为它与相似性直接相关。两个向量 uv 之间的相似性的定义实际上是它们的点积和它们的大小的乘积之间的比率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Similarity.

通过应用相似性的定义,如果两个向量相同,这实际上等于 1,如果两个向量正交,则等于 0。换句话说,相似性是一个介于 0 和 1 之间的数字,它告诉我们两个向量有多相似。相当简单!

现在是编码的时候了!

1.收集数据

对于这个问题,我决定使用包含 IMDB 中排名前 250 的电影的数据集。事实上,这个表收集了 250 个观察值(电影)和 38 列。然而,我希望我的推荐者只基于电影导演、主要演员、流派和情节,所以这些是我在建模中考虑的唯一列。

这是数据帧头部的样子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我的目标是为包含上述所有特征的每部电影只获取一列,以便执行矢量化。没错,我们需要使用 NLP,因为我们需要数字来计算余弦相似度,而我们还没有…还没有!当然,首先要做一些清洁工作。

2.数据清理

我在nltk包中发现了一个很好的特性,允许我们从文本中提取关键词,它甚至给每个词打分。我没有真正考虑这个基本推荐者的分数,但是我使用这个Rake函数从Plot列中提取关键词,所以我没有使用描述情节的整个句子,而是只考虑描述中最相关的词。为了做到这一点,我将这个函数应用于Plot列下的每一行,并将关键字列表分配给一个名为Key_words的新列

Extracting key words from movie plots.

其他的柱子也需要清洗。一切都需要小写以避免重复,我还决定将所有的名和姓合并成一个唯一的单词。因为,想想看:如果我们有导演是丹尼·鲍伊尔的电影 A,和主要演员之一是丹尼·德维托的电影 B,推荐者会因为他们的名字而发现相似性,而这是我们不想要的。我希望推荐器只在与不同电影相关联的人完全相同时才检测相似性。

在所有的清理和合并之后,我将索引重新分配给电影标题列(这不是我的功能之一),这就是准备进行矢量化的数据帧。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.建模

为了检测电影之间的相似性,我需要向量化,正如我上面提到的。我决定使用CountVectorizer而不是TfIdfVectorizer,原因很简单:我需要为我的bag_of_words列中的每个单词设置一个简单的频率计数器。Tf-Idf 倾向于对出现在整个语料库(在本例中是我们的整个专栏)中的单词不太重视,这不是我们在这个应用程序中想要的,因为每个单词对检测相似性都很重要!一旦我有了包含每个单词计数的矩阵,我们就可以应用cosine_similarity函数了

相似矩阵是这样的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Similarity matrix.

让我们简单看一下:对角线上的所有数字都是 1,因为,当然,每部电影都和它自己一模一样。矩阵也是对称的,因为 A 和 B 之间的相似性与 B 和 A 之间的相似性相同。

此时,我可以编写实际的函数,该函数以电影标题作为输入,并返回前 10 部类似的电影。为了做到这一点,我还创建了一个简单的带有数字索引的电影标题系列,以便将相似性矩阵中的索引与实际的电影标题相匹配。事实上,我的函数一旦接收到输入,就检测与输入的电影对应的行中的 10 个最高数字,获取相应的索引并将它们与电影标题系列进行匹配,以返回推荐的电影列表。当我说该函数考虑 10 个最高的相似性值时,我是在丢弃单元值(很容易是最高的),以便该函数不会返回我输入的相同电影标题。

4.测试推荐器

任务完成了!当然,这是一个非常有限的推荐系统,因为我只使用了一个包含 250 部电影的数据集,但它一点也不差!遵循相同的程序,但使用更多的数据,并实现关键字的分数,例如,这个系统可以很容易地完善。但是让我们通过输入 Fargo: 来测试一下,这是(250 部电影中)最值得推荐的 10 部电影。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Movies recommended because I like Fargo.

我看这个不错!主要是基于导演和剧情我能看出一些相似之处。我喜欢上面列表中我已经看过的电影,就像我喜欢《法戈》一样,所以我想我会去看我仍然错过的几部电影!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

请随意查看:

我的其他中等岗位。

我的 LinkedIn 个人资料。

我的这个项目的 GitHub 资源库。

感谢您的阅读!

如何构建能够自我更新的闪亮应用

原文:https://towardsdatascience.com/how-to-build-r-shiny-apps-that-update-themselves-6ce2d9606e90?source=collection_archive---------9-----------------------

R 生态系统现在是一个非常好的地方。特别是,R 中的基础设施允许人们通过闪亮的应用程序与数据进行交互,这为减少数据分析师的工作量提供了不可思议的潜力。

现在有可能构建闪亮的应用程序,可以定期更新自己,引入更新的数据,以便人们总是看到最新的分析。因此,通过一个预先开发 sprint,分析师可以将特定主题的持续分析工作量减少近 100%。

你需要什么

  1. 一个项目,在该项目中,您定期以相同的格式交付报表,并且数据库中的所有数据都可用。
  2. R,R 降价和 R 闪亮技能
  3. 访问包含闪亮服务器的运行 R 的 Linux 服务器,或者如果你真的幸运,访问 RStudio Connect 发布平台,这使得整个过程变得更加容易。

第一步:根据本地数据源构建你的应用

使用本地数据源,以.csv.feather文件、.RData文件甚至是SQLLite本地数据库的形式,编写一个闪亮的应用程序,使其成功部署在您的本地机器上。确保它按预期运行。

步骤 2:编写一个可以在服务器上运行的 ETL 脚本或文档

用 R 编写一个脚本,从远程数据库中提取原始数据,将其转换成您闪亮的应用程序所需的形式。然后,您需要将这些数据写入某个地方,以便您的闪亮应用程序可以远程访问这些数据。选项包括:

  • 在新表中写回源数据库(如果您有权限这样做)
  • 写入托管您的闪亮服务器的 Linux 服务器的文件系统
  • 如果你使用 RStudio Connect,在/var/cache/data写入它的缓存。

步骤 3:将您的脚本部署到您的 Linux 服务器或 RStudio Connect 上

您需要在 Linux 服务器上的 R 中设置数据库连接。这里的是一个很好的指南。然后,您需要编辑您的脚本来指向这些连接。

如果您将输出写入 Linux 文件系统,您将需要确保它位于 Shiny 服务器可以访问的目录中。

如果您在 RStudio Connect 中操作,您可以将您的脚本包装到一个 R Markdown 文档中,并发布它,包括源代码,这样每当文档被刷新时,代码就会执行,从而执行一个新的 ETL。

步骤 4:将你的闪亮应用部署到闪亮服务器或 RStudio Connect

您需要编辑您的应用程序代码,以指向远程数据源,无论它是数据库还是文件系统中的某个地方。然后,您可以将应用程序文件加载到 Linux 服务器上的子目录shiny-server中。应用的 URL 将是 shiny 服务器的 URL,后跟子目录名称,例如[https://my.shiny.server/myappname](https://my.shiny.server/myappname.)

如果在 RStudio Connect 中工作,您只需正常发布并在 RStudio Connect 中自定义 URL。

第五步:设置数据自动刷新

如果您的脚本位于您的 linux 服务器上,您可以使用各种调度工具来设置脚本在期望的时间间隔自动运行。cron是一种简单的方法。在您的 Linux 用户文件夹中找到您的crontab文件,并适当地编辑它。例如,要设置您的脚本在每个星期天的凌晨 2 点运行,编辑您的crontab文件,如下所示:

0 2 * * 0 Rscript /mypath/myscript

这将自动以所需的频率运行您的脚本,提取原始数据并用新数据覆盖您的应用程序访问的文件。

如果您使用的是 RStudio Connect,您可以为包含脚本的 R Markdown 文档设置,以便使用文档的“设置”菜单刷新到计划。

所以你有它。一个完全自动化的应用程序,可以自我刷新。想想如果你能设置好这个,你能节省多少时间。不客气

你可以在这里 了解更多关于 Shiny Server 和 RStudio Connect

最初我是一名纯粹的数学家,后来我成为了一名心理计量学家和数据科学家。我热衷于将所有这些学科的严谨性应用到复杂的人的问题上。我也是一个编码极客和日本 RPG 的超级粉丝。在LinkedInTwitter上找我。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如何使用 Scrapy,ScrapingHub 和亚马逊 S3 建立重复的网络蜘蛛工作

原文:https://towardsdatascience.com/how-to-build-recurring-web-spider-jobs-using-scrapy-scrapinghub-and-amazon-s3-43dbe3c73b69?source=collection_archive---------3-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最近我和一个好朋友一直在尝试自学机器学习。根据许多行业专家的说法,在未来 10-15 年内保持有收入的工作是编程世界的必要的下一步。

注:如果你听说过同样的事情,但不确定从哪里开始,我会给你指出这个不可思议的 中帖 和这个 Coursera 课程 来开始。

我们很快遇到的一个问题是需要一个数据集。虽然世界上有很多令人难以置信的有趣的数据集可以免费下载,但我们有特定的兴趣(火箭发射,太空探索,火星等等。)并认为通过刮刮来建造我们自己的会很有趣。

就我个人而言,我从来没有构建过一个 scraper(或者使用 Python),但是我认为这不会太难。我们花了大约一天半的时间来构建我们的蜘蛛,让它们按照每天的时间表运行,并将数据放入 S3 桶中。

很难找到任何关于这个过程的指南,所以我想我应该写下我们是如何做的,并在互联网上公开我们的过程。如果您看到我们做错了什么,请随时告诉我们如何才能做得更好。我们正在学习。

建造蜘蛛

  1. 安装Scrapy——他们的文档是令人敬畏的。如果您遵循安装指南,应该没有问题
  2. 安装依赖项: boto (可能已经安装,这取决于你如何安装 Scrapy) & dotenv (这是为了不检查 AWS 的秘密到我们的 VCS)
  3. scrapy startproject directoryname建立一个新的 Scrapy 项目

您应该有一个scrapy.cfg文件和一个目录(在上面的步骤中命名。)在目录内部,您将看到 Scrapy 的工作原理。首先,我们将使用settings.py/spiders目录。

让我们开始建造蜘蛛。进入您的/spiders目录并创建一个新的spidername.py文件。这里有一个使用 CSS 和 XPath 选择器的蜘蛛示例。

这是一个难以置信的简化版本,但让我们现实一点。你的需求会有所不同,Scrapy 的文档比我在这篇文章中写的要好 100 倍。重要的是要认识到,你可以创建多个spider.py文件,并为不同的网站有不同的蜘蛛。

一旦你的蜘蛛启动并运行,下一步就是正确设置你的settings.py文件。

Scrapy 为您提供了大量样板代码。我只包括我修改过的相关部分。您会注意到几件重要的事情:

  1. 通过遵守robots.txt并在抓取之前手动检查每个网站的服务条款,我们成为了互联网的好公民。我们不刮那些要求不被刮的网站。
  2. 我们使用dotenv来保护我们的 AWS 访问密钥 id 和秘密访问密钥。这意味着您将在与settings.py相同的目录中拥有一个.env文件。您会希望将.env包含在您的.gitignore中。
  3. Scrapy 的超级合法部分是,你需要的只是为它设置的几个选项,以处理向 S3 的推送。

酷毙了。我们已经准备好了。一旦我们给了它正确的凭证,蜘蛛就被构建好了,并且settings.py已经准备好将数据推送到 S3。

设置 AWS

如果你不熟悉 AWS,它可能会相当吓人。我们需要做两件事:

  1. 创建一个 IAM 用户,并获取访问密钥 id 和秘密访问密钥
  2. 设置一个存储桶并添加正确的权限

IAM 用户可能有点棘手,所以我建议阅读 AWS 的文档。实际上,您需要登录 AWS 控制台,进入 IAM 部分,创建一个新用户,然后生成一个访问密钥。我建议创建这个用户仅仅是为了对您的 bucket 进行 API 调用。您将需要来自您创建的用户的三个字符串。把它们保存在安全的地方。

  • 用户 ARN
  • 访问密钥 ID
  • 秘密访问密钥

现在,让我们设置一个新的铲斗。这很简单。创建您的存储桶,然后导航至“权限”选项卡。您需要设置一个 bucket 策略,允许您刚刚创建的 IAM 用户将数据推送到这个 bucket。这是我们的样子:

必要时,交换[your-user-id][your-bucket-name]部件。这可能不言而喻,但不包括[]。

最后,将访问 id 和密钥添加到 Scrapy 项目中的.env文件中。

部署到报废网络

ScrapingHub 是由支持 Scrapy 和十几个其他开源项目的了不起的人运营的一个漂亮的服务。手动触发蜘蛛抓取是免费的,但它有一个非常合理的价格 $9 /月计划,允许单个蜘蛛在任何给定时间并发运行。对于我们的需求,它允许我们每 5 分钟调度不同的蜘蛛,即 280+独特的蜘蛛,只要它们的运行时间是< 5 分钟。

我们在最后冲刺阶段。这部分很简单。您将创建一个 ScrapingHub 帐户,登录并生成一个 API 密钥。你将安装 shub,清除掉 Hub 的命令行界面,并按照指示添加你的密钥和项目 ID。

**注意:**如果你已经用.env混淆了你的 AWS id &密钥,那么在部署到 ScrapingHub 之前,你需要在你的settings.py中注释掉几行。即上面要点中的第 5-7 行和第 14-18 行。

一旦一切就绪,你就可以使用shub deploy将你的项目推向报废。

您需要做的最后一件事是进入蜘蛛设置区域,手动添加 AWS 凭证。您会注意到,我们还添加了一个超时,以确保如果出现任何错误,我们会正常失败。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你完了!嗯,差不多了。

我建议首先至少手动运行一次蜘蛛,检查 S3 桶中生成的文件,并确保您对所有结果都满意。一旦你对此感到满意,转到你的项目的定期作业部分,设置你的蜘蛛在你需要的任何时间间隔运行。例如,世界协调时每天 04:30。

摘要

我意识到这并不是对每一行代码或点击的每一个按钮的完全详尽的指导,但希望它能让你步入正轨。接下来,我们将获取生成的 CSV 文件,规范化数据,并将其插入 Postgres 数据库。

请关注我的最新消息!

如何打造值得信赖的 AI 产品

原文:https://towardsdatascience.com/how-to-build-trustworthy-ai-products-3f49de63209a?source=collection_archive---------7-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Photo by Andy Kelly on Unsplash

你不能只是在一个项目中添加人工智能,然后指望它能工作。它不是可以洒在产品上的魔法粉。

建立融入人们生活的系统的关键是信任。如果你没有足够的信任,你就会让这个系统被废弃和滥用。

这篇文章(以及下面的这个对应的对话)最初是为 5 月 30 日作为产品学校的一部分,开始接触数据科学、机器学习和人工智能的产品人员创建的。虽然对 AI/ML 有一个简单的介绍,但是更有经验的从业者可以学习很多关于 AI 中信任的东西。

信任 101

信任之所以重要,是因为它有助于促进合作行为。这是我们创造复杂社会的基石。

归结起来有几个关键点:

  • 合同——书面或非书面
  • 关注对未来的期望
  • 基于过去的绩效、问责制和透明度
  • 构建缓慢,但可能很快丢失

信任和机器有什么关系?

当我在一家名为 Complete Seating 的餐厅初创公司工作时,我们开发了许多功能来帮助主人管理他们的餐厅地板。我们包括了智能等候名单时间和自动餐桌推荐。

我们当时称之为分析、商业智能、预测和约束编程,但如果我们今天筹集资金,它应该被称为“人工智能餐厅管理”。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不幸的是,我们没有获得他们的信任,因为我们缺乏信任的三个关键方面中的两个:性能和透明度。

  • 性能——这是一个测试版产品,起初它没有达到预期。一旦服务开始发挥应有的作用,我们就有一座大山要爬上去重建信任。
  • 责任——当出现问题时,我们总是会接听他们的电话,或者出现在现场提供帮助。他们知道我们在尽力帮忙,但还是没有解决另外两个问题。
  • 透明性——我们没有给他们很好的抽象概念,所以他们可以理解幕后发生的事情。他们想应用他们的专业知识,但他们不知道我们涵盖了什么。

我们最初试图通过向主机提供更多的上下文来解决这些问题。

回顾过去,我们应该从指出主持人可能犯的错误开始,而不是混淆整个座位引擎。

机器如何与人类建立信任?

当我们考虑与他们建立信任时,我们需要以人为中心。这是我认为未来几年人工智能面临的最大危险之一。

使用相同的框架,我们可以如下考虑机器构建信任:

  • 性能——这不像传统的准确度、精确度和召回那么简单。我们需要担心对人类目的来说什么是正确的度量标准。
  • 责任——关于系统的设计者在他们的操作中需要承担什么责任,有许多道德和法律问题需要回答。
  • 透明度——我们如何构建可解释的系统,提供适应性的行动,提供控制感,允许人类干预,并获得反馈以改进系统。

查看演讲深入了解这些关键方面。

对于机器来说,什么是正确的信任级别?

在《人类与自动化:使用、误用、废弃、滥用》一书中,他们讨论了人们基于信任使用自动化的各种方式:

  • 使用—“[自动]由操作员激活或解除自动化。”这是信任达到“正确”程度的时候。
  • 误用—“[过度]依赖自动化,这可能导致监控失败或决策偏差。”这是人类过于信任系统的时候。
  • 当人类对自动化不够信任时,就会出现弃用——“[忽视]或未充分利用自动化……”。
  • 滥用—“[自动化]功能…没有适当考虑对人的表现的后果…”当设计自动化时没有考虑操作者(或那些受影响的人)时,就会发生这种情况。从我的角度来看,这是我认为未来几年人工智能面临的最大危险之一。

我们怎样才能了解对机器的信任?

我们可以通过原型和研究来了解对信任的期望和需求。

在构建原型时,您不需要实际构建和训练模型。你只需要考虑几种不同的情况,然后假装:

  • 正确操作或“快乐路径”
  • 不正确的操作—自动化的误报/漏报
  • 理解“正确”信任级别的误用/废弃边界的两边
  • 从人到机器的反馈的适当场景
  • 为你的抽象陈述从机器到人类的交流

我还发现,当开始构建时,使用“绿野仙踪”或“门房”方法来开发人工智能的 MVPs】可以帮助你专注于你真正需要学习的东西。

最后

请记住:

  • 使用人工智能就像任何其他有权衡的技术一样…你应该意识到其中的细微差别。
  • 建立适量的信任——不多也不少。
  • 信任基于绩效、责任和对人类的透明性。

请观看视频了解完整的演讲以及每一点的更多细节。

关于克里斯·巴特勒

我帮助团队理解他们应该用以人工智能为中心的解决方案解决的真正的商业问题。我们工作的团队通常被要求用他们拥有的数据做一些有趣的事情(T2)。我们通过偶发事件相关性帮助他们避免局部极值,并专注于解决巨大的业务问题。我的背景包括在微软、KAYAK 和 Waze 等公司超过 18 年的产品和业务开发经验。在 Philosophie,我创造了像机器移情映射混淆映射这样的技术,以在构建人工智能产品时创建跨团队对齐。如果你想了解更多或者通过邮箱LinkedIn 联系,或者访问http://philosophie.is/human-centered-ai

幻灯片:

[## 克里斯·巴特勒- PS 演示

旧金山、硅谷、洛杉矶、纽约、奥斯汀、波士顿、西雅图的兼职产品管理课程…

docs.google.com](https://docs.google.com/presentation/d/e/2PACX-1vQt1aD_sq_zvVC9ulRgEWBUpasLb07gjss6VVTHQHu5Rsw6yJq8_XuBruyIJhsHJPx8an4lI5e1d-LB/pub?start=false&loop=false&delayms=3000)

参考资料:

如何用 Python 从零开始构建自己的神经网络

原文:https://towardsdatascience.com/how-to-build-your-own-neural-network-from-scratch-in-python-68998a08e4f6?source=collection_archive---------0-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

理解深度学习内部运作的初学者指南

更新:当我一年前写这篇文章的时候,我没有想到它会受到这个的欢迎。从那以后,这篇文章被观看了超过 45 万次,有超过 3 万次鼓掌。它还登上了谷歌的首页,并且是“神经网络”的前几个搜索结果之一。你们中的许多人都联系过我,这篇文章对你们学习之旅的影响让我深感谦卑。

这篇文章也引起了 Packt 出版社编辑的注意。这篇文章发表后不久,我就被提出作为《用 Python 做 **神经网络项目》一书的唯一作者。今天,很高兴和大家分享我的书出版了!

这本书是这篇文章的延续,它涵盖了神经网络项目在人脸识别、情感分析、噪声消除等领域的端到端实现。每章都有一个独特的神经网络结构,包括卷积神经网络,长期短期记忆网络和暹罗神经网络。如果你正在寻找用深度学习项目创建一个强大的机器学习组合,请考虑购买这本书!

你可以从亚马逊得到这本书: 用 Python 做的神经网络项目

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**动机:**作为我个人更好地理解深度学习之旅的一部分,我已经决定从零开始建立一个神经网络,而不需要像 TensorFlow 这样的深度学习库。我认为,理解神经网络的内部工作对任何有抱负的数据科学家都很重要。

这篇文章包含了我所学到的东西,希望对你也有用!

什么是神经网络?

大多数介绍神经网络的文章在描述它们时都会提到大脑类比。在不深究大脑类比的情况下,我发现简单地将神经网络描述为将给定输入映射到期望输出的数学函数更容易。

神经网络由以下组件组成

  • 一个输入层x
  • 任意数量的隐藏层
  • 一个输出层
  • 一组权重在各层之间偏置W 和 b
  • 选择激活功能用于每个隐藏层,。在本教程中,我们将使用一个 Sigmoid 激活函数。

下图显示了 2 层神经网络的架构(注意,在计算神经网络的层数时,输入层通常被排除在外

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Architecture of a 2-layer Neural Network

用 Python 创建神经网络类很容易。

训练神经网络

简单 2 层神经网络的输出 ŷ 为:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

您可能会注意到,在上面的等式中,权重 W 和偏差 b 是影响输出 ŷ.的唯一变量

自然,权重和偏差的正确值决定了预测的强度。从输入数据中微调权重和偏差的过程称为训练神经网络。

训练过程的每次迭代包括以下步骤:

  • 计算预测输出 ŷ ,称为前馈
  • 更新权重和偏差,称为反向传播

下面的序列图说明了这个过程。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

前馈

正如我们在上面的序列图中看到的,前馈只是简单的微积分,对于一个基本的 2 层神经网络,神经网络的输出是:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们在 python 代码中添加一个前馈函数来做到这一点。注意,为了简单起见,我们假设偏差为 0。

然而,我们仍然需要一种方法来评估我们预测的“好性”(即我们的预测有多远)?损失函数允许我们这样做。

损失函数

有许多可用的损失函数,我们问题的性质决定了我们对损失函数的选择。在本教程中,我们将使用简单的平方和误差作为我们的损失函数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

也就是说,平方和误差就是每个预测值和实际值之间的差值之和。差值是平方的,因此我们可以测量差值的绝对值。

我们训练的目标是找到使损失函数最小化的最佳权重和偏差集。

反向传播

既然我们已经测量了预测的误差(损失),我们需要找到一种方法来传播误差回来,并更新我们的权重和偏差。

为了知道调整权重和偏差的合适量,我们需要知道损失函数相对于权重和偏差的导数。

回想一下微积分,函数的导数就是函数的斜率。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Gradient descent algorithm

如果我们有导数,我们可以简单地通过增加/减少来更新权重和偏差(参考上图)。这就是所谓的梯度下降

然而,我们不能直接计算损失函数关于权重和偏差的导数,因为损失函数的方程不包含权重和偏差。因此,我们需要链式法则来帮助我们计算它。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Chain rule for calculating derivative of the loss function with respect to the weights. Note that for simplicity, we have only displayed the partial derivative assuming a 1-layer Neural Network.

唷!这很难看,但它让我们得到了我们需要的东西——损失函数相对于权重的导数(斜率),这样我们就可以相应地调整权重。

现在我们有了这个,让我们把反向传播函数添加到我们的 python 代码中。

为了更深入的了解微积分的应用和反向传播中的链式法则,我强烈推荐 3Blue1Brown 的这个教程。

把所有的放在一起

现在我们已经有了完整的 python 代码来进行前馈和反向传播,让我们将我们的神经网络应用于一个例子,看看它做得有多好。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们的神经网络应该学习一组理想的权重来表示这个函数。请注意,仅仅通过检查来计算重量对我们来说并不简单。

*让我们训练神经网络 1500 次迭代,看看会发生什么。查看下面的每次迭代损失图,我们可以清楚地看到损失**朝着最小值单调递减。*这与我们之前讨论过的梯度下降算法是一致的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们看看神经网络经过 1500 次迭代后的最终预测(输出)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Predictions after 1500 training iterations

我们做到了!我们的前馈和反向传播算法成功地训练了神经网络,并且预测收敛于真实值。

请注意,预测值和实际值之间略有不同。这是可取的,因为它防止过度拟合,并允许神经网络更好地将推广到看不见的数据。

下一步是什么?

幸运的是,我们的旅程还没有结束。关于神经网络和深度学习,还有很多东西需要学习。例如:

  • 除了 Sigmoid 函数之外,我们还可以使用什么其他的激活函数
  • 训练神经网络时使用学习率
  • 使用卷积进行图像分类任务

我很快会写更多关于这些话题的文章,所以请在 Medium 上关注我,留意它们!

最后的想法

从零开始编写自己的神经网络,我确实学到了很多。

尽管 TensorFlow 和 Keras 等深度学习库可以在不完全了解神经网络内部工作原理的情况下轻松构建深度网络,但我发现,对有抱负的数据科学家来说,更深入地了解神经网络是有益的。

这个练习花费了我大量的时间,我希望它对你也有用!

如何计算各行业的流失率

原文:https://towardsdatascience.com/how-to-calculate-churn-rates-across-industries-68c692b64605?source=collection_archive---------0-----------------------

一个可悲的商业事实是,你不可能永远留住客户。随着时间的推移,你会失去客户,因为他们的需求不断变化,竞争加剧,或者只是因为他们离开(如果你是一个实体零售商)。

你在一段时间内失去的客户百分比被称为你的流失率,或者简称为流失率。了解你的客户流失对于控制你的客户获取成本和确保你的业务增长至关重要。你要确保增加客户的速度快于失去客户的速度!

计算你的客户流失看起来很难。事实上,客户流失可能是你在业务中使用的最复杂的指标,因为很难可靠地定义和计算。在这篇文章中,我们将涵盖许多不同的方法来计算客户流失,即使我们不强调一种方法适合你的业务,给你的想法,就如何计算自己的客户流失。

具体来说,我们将涵盖:

  • 第一部分 —定义流失
  • 第二部分 —收入流失
  • 第三部分 —交易型流失
  • 第四部分 —合作

异常值 监控您的业务数据,并在发生意外变化时通知您。 我们帮助营销/增长&产品团队从他们的业务数据中获取更多价值。 今天安排一个演示

让我们从定义客户流失的确切含义开始,并理解为什么说起来容易做起来难。

第一部分。什么是流失?

在我们开始分析我们的客户流失之前,我们需要就一个定义达成一致。流失率通常被定义为你失去现有客户的比率。在这种情况下,通过以下方式计算客户流失应该很容易:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

A typical churn calculation that disregards time

然而,这并不完全清楚!我们什么时候衡量客户流失?我们从哪一点开始计算我们的客户总数?为了做到这一点,我们需要测量特定时间窗口内的客户流失。因此,客户流失率通常是按月来衡量的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Typical churn calculation by month

这更有道理,但仍有一个大问题。我们如何定义客户总数?如果当月增加客户,要不要统计?他们在第一个月没有机会流失,所以这可能会扭曲我们的指标。为了解决这一问题,仅对当月开始的客户计算流失率:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Churn calculation for customers at start of month

这更好,因为现在我们可以了解有多少开始这个月的客户在这个月流失了。这仍然不能捕捉到在第一个月开始并流失的客户,但至少他们不会扭曲我们的计算。

即使在三次迭代之后,该解决方案仍然存在许多问题:

  • 延迟洞察。在任何给定的时间,你最近的客户流失指标至少是一个月前的。三月份,您将获得的最新客户流失指标来自二月份!这使得实时解决客户流失问题变得困难。
  • 顾客交融。这一指标无法区分与您合作多年并流失的客户和最近成为客户并在下个月离开的客户。将这些价值观融合在一起,就无法判断你是在失去长期客户还是短期客户!

我们可以继续完善我们的等式[1],但是,最终,您使用的流失计算将取决于您希望它包含的内容。你想每周都进行客户流失测量吗?你想用不同的方式衡量你的顾客吗?没有神奇的、单一的客户流失方程式,因为每个公司对客户流失的看法都不一样。

要创建你的客户流失公式,就像我们上面做的那样,列出它需要包含的重要特性,并对其进行提炼。注意不要把它弄得太复杂,因为它变得越复杂,就越有可能有人在某个时候计算错误,你就会有一个误导性的指标。

第二部分。收入流失

到目前为止,我们已经介绍了如何根据一段时间内获得和失去的客户来计算客户流失率。然而,并不是所有的顾客都是平等的!如果一个每月付给你 10 美元的客户流失了,那也没有失去一个每月付给你 1000 美元的客户重要!事实上,低价客户留存率高,高价客户留存率低是很常见的。这将被我们昨天讨论的流失计算所隐藏。

收入流失是另一种思考流失的方式,它关注的是你如何从客户那里保持收入。如果您的客户有各种各样的定价,这可能是一种更有用的思考客户流失的方式。

在计算收入流失时,您的第一反应可能是像我们的客户流失公式一样处理它:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Calculating churn for revenue.

然而,计算收入不同于计算客户,因为任何给定的客户都可能在给定的一个月内开始多付或少付你钱。我们需要更具体地了解“收入损失”的含义:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

A better way to calculate churn for revenue, this time accounting for upgrades

我们已经用一个简单的等式代替了“收入损失”,该等式从每月第一天的总收入开始,减去该月最后一天来自这些客户的收入(从而得出损失的收入),然后减去升级的价值。我们需要减去升级,因为如果您的客户向上销售非常有效,它们可能会隐藏客户的流失。

这个等式的一个有趣的副作用是,如果你的客户升级率高于客户流失率,你的收入流失率可能是负数!这被认为是非常好的,因为负收入流失率是建立高增长业务的关键因素[1]。

第三部分。事务性流失

大多数交易业务,如电子商务,使用重复购买率等指标来评估客户保持率。这是因为客户流失指标要求您知道何时会失去客户,这对于交易型企业来说非常困难。在订阅业务中,你知道他们何时会取消订阅,但如果是一个网站,客户可以随心所欲地来来去去,那该怎么办?但是,难不代表不值得做!

确定何时失去交易型客户的一个常用方法是使用活动时间窗口。每当顾客购物时,你就启动一个计时器。如果同一个客户在一段时间内没有回来,你就认为他们被解雇了。我在下面举例说明了这一点:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Using a purchase history window to measure customer churn

这很有道理,但是如果同一用户在你把他们标记为“搅动”的第二天又回来购买,你会怎么做呢?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Options to handle a use-case where the customer has churned: treat them as a new customer or re-calculate churn rates.

对于如何处理这些情况,您有几个选择:

  • 把他们当成新客户。将回头客视为新客户似乎是欺骗,但如果你的时间足够长,这可能是最好的。如果你的网站和产品在客户上次购买你的产品后的 6 个月内发生了显著的变化,他们的体验将是全新的,他们在大多数方面都将是一个新客户。
  • 重新计算你的流失率。每个月,你可以重新计算过去一年的流失率,因为你可以识别那些被认为已经流失但后来又回来购买的客户。这是最准确的方法,但在实践中最难使用,因为您过去的指标会不断变化!

这似乎很容易,尽管选择你的时间窗口是至关重要的。你是用一周,一个月,还是几个月?如果你选择的窗口太短,你会显示一个人为的高流失率。如果你选择的时间太长,那么你不会知道你什么时候失去了顾客,直到他们离开很久以后。您将需要利用您对业务和典型使用模式的了解来做出明智的选择,如果您觉得客户流失指标不能反映真实的客户流失,请重新进行评估。

第四部分。合作

不管你用什么方法来衡量客户流失,所有的方法都很大程度上依赖于使用预先确定的时间间隔(比如几个月)。这种方法的一个挑战是,它可以通过混合许多不同类型的客户来隐藏长期趋势。例如,在一个特定的月份里,你可能会失去三个和你在一起超过一年的客户,和 10 个只和你在一起一个月的客户。你可能想知道为什么你会失去这三个长期客户,但是他们可能会被你的流失指标所淹没。

出于这个原因,客户流失几乎总是根据客户群来衡量和可视化。这种协作可以让你看到,随着你改进产品、调整定价和对业务做出其他改变,客户流失是如何随着时间的推移而变化的。例如,群组可以是客户开始使用你的产品的月份。

让我们来看一个数字示例,说明客户是如何通过每月的购买群体流失的。在这个例子中,我将使用保留率(这是流失率的倒数),因为它可以更直观地看到保留率随着时间的推移而下降,而不是流失率增加。你觉得哪个更容易理解取决于你:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于每个月(3 月至 9 月),该图表显示了客户首次成为客户后每个月的流失情况。第一行表示,对于 3 月份开始的客户,此后每个月的保留率。第 0 个月将始终是 100%,因为该月是客户成为客户的第一个月,因此他们不会有变动。在这一行中,每个群组的保留率始终小于或等于前一列中的值,因为群组无法增加久而久之。

请注意,并非所有行都有 7 个月之后的值,因为这些月份可能还没有发生!这张图表是在假设现在是 10 月份的情况下查看您的数据,因此 9 月份获得的客户只有一个月的时间来衡量他们的保留率。

按群组考虑人员流动会很容易发现模式。从第 1 个月开始,从 3 月份开始,我们的客户保持率约为 2%,直到 7 月份开始下降,9 月份获得的客户一直下降到 1.21%。很明显,我们在业务中所做的一些改变导致了第 1 个月更高的流失率,我们需要解决这个问题!

回顾:流失率可能很难计算,但随着时间的推移,它是了解和提高客户保持率的非常有价值的工具。无论你从事哪种业务,你都可以也应该把流失率作为一个关键的绩效指标来衡量。

离群值 监控您的业务数据,并在发生意外变化时通知您。 我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。 今天安排一个试玩

[1]为了更好地了解负收入流失及其如何创造高增长,我推荐 Tomasz Tunguz 的帖子

[2]重复购买率是再次购买的顾客的百分比。它为您提供了一个简写方式,让您知道在给定的时间范围内,新客户或现有客户购买了多少商品。理想情况下,随着你积累更多的忠实客户,这个比率会随着时间的推移而增加。

如何计算你的荟萃分析的统计功效

原文:https://towardsdatascience.com/how-to-calculate-statistical-power-for-your-meta-analysis-e108ee586ae8?source=collection_archive---------3-----------------------

生物行为科学领域的大多数研究在统计上不够有力,这降低了具有统计显著性的发现反映真实效果的可能性。

元分析是一种流行的方法,用来综合解决特定研究问题的大量研究。然而,在规划或解释荟萃分析时,很少考虑统计能力。这可能是因为没有可访问的软件或 R 脚本来计算元分析功效,像 G*Power“PWR”R package,它们是计算主要研究的统计功效的伟大选项。

多亏了这篇论文中的公式,我写了自己的脚本来计算随机效应元分析的功效。只需在下面的脚本中输入您预期的汇总效应大小、每组参与者的平均人数、效应大小的总数以及研究异质性。

下面是一系列异质性水平、汇总效应大小、分组样本大小和包含样本大小总数的统计功效。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Effect sizes of d = 0.2, d = 0.5, and d = 0.8 are considered small, medium, and large effect sizes. As per convention, 80% statistical power is considered sufficient.

有趣的是,在大多数情况下,荟萃分析足以检测大的汇总效应大小(底部一行)。然而,在大多数情况下,它们很难有足够的能力来检测微小的影响(顶行)。检测中等效应的能力(中间一行)是一个大杂烩,似乎很大程度上取决于研究的异质性。

**更新:**感谢 Jakob Tiebel ,他组装了一个 Excel 计算器来使用相同的公式计算您的元分析的统计功效。对于不熟悉 r 的人来说是一个很好的选择。

想要一步一步的指导来执行你自己的相关性元分析吗?看看我的论文和相关的视频。如果你已经在度过了这个,你可能会喜欢万物赫兹,这是我共同主持的元科学播客。这是我们关于元分析的集。

如何计算你公司的增长率

原文:https://towardsdatascience.com/how-to-calculate-your-companys-growth-rate-63b6852638c6?source=collection_archive---------0-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你的业务是否在增长是一个重要的事实,但了解它的增长速度可能很难确定。正如我们在客户流失调查中看到的那样,甚至很难定义一个像增长这样的简单指标,甚至更难计算它。那么你的业务增长有多快呢?

你的增长率是未来分配资源的一个重要指标。如果你的业务增长速度超过了你的承受能力,你可能会发现自己的负担太重了。如果增长太慢,你的企业可能无法生存。增长对你意味着什么将影响你如何计算你的增长率,以及你如何使用这个指标。

误导性的正增长率可能代表数据的阴暗面,使人们认为你的业务比实际增长得更快。有时这是有目的欺骗的结果,有时是基于计算增长的复杂性的诚实错误。赌注很高,因为大多数企业的增长率与其整体盈利能力一样重要。

在这里,我们将深入探讨是什么让增长率难以定义,以及如何确保增长率指标的可靠性。具体来说,我们将涵盖:

  • 第一部分 —定义增长
  • 第二部分 —复合增长率
  • 第三部分 —季节性增长
  • 第四部分 —预测增长

让我们从定义增长开始…

离群值 **监控您的业务数据,并在发生意外变化时通知您。**我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。今天安排一次演示

直觉上,定义增长似乎应该很简单。给定一个像收入这样的指标,计算今天的收入比过去高多少应该很容易:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

用这个简单的方法,增长率就是一个月到下一个月收入的百分比变化。如果我们要绘制一段时间内的收入图表,增长率就是每个数据点之间的变化率。以下面一家样本公司的收入随时间变化的图表为例:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Chart of simple growth rate: revenue over time

根据我们的简单公式,这家公司的增长率将是每月 10%的直线。

然而,如果我们透过表面看,上面简单的图表可以告诉我们许多不同的故事,因为这样一个简单的增长率可以隐藏许多事情。如果你的价格改变了呢?这一个月你获得和失去的客户呢?例如,考虑下面的两个图表,其中旧客户收入反映了每个月初之前的所有客户的收入,新客户收入反映了该月的新收入。

示例 A:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Segmented growth rate of revenue over time: new vs. old customers where old customers drive most growth

示例 B:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Segmented growth rate of revenue over time: new vs. old customers where new customers drive most growth

在示例 A 中,除了现有客户之外,业务还在稳步增长,新客户也在健康增长。在示例 B 中,企业正在快速流失客户,但却隐藏在新客户快速增加的背后!使用我们的简单公式,这两个示例将导致相同的增长率(两个示例中的面积图顶部)。

新老客户之间的这种混淆是增长率的一个重要问题,需要解决。零售店普遍存在这个问题,因为开设新店可以很容易地抵消老店销售额下降的影响。因此,零售商店的增长率是用一种叫做“同店销售额的指标来衡量的,这种指标只衡量开业至少一年的商店的增长率。这将真正的销售增长与新开业率区分开来。

你可以类似地修改你的增长率计算,并通过考虑你的流失率来隔离现有业务和新业务的增长。你需要做的就是从上面我们的增长率公式中减去它:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Growth rate calculation, including churn

正如我们上周讨论的,你的流失率实际上可能是负数,在这种情况下,它会增加你的增长率!

这种新的增长率公式可能是对我们业务的更好衡量,因为它清楚地告诉我们,在保留客户价值方面,我们的增长情况如何。然而,这种方法仍然存在挑战:

  • 短月。有些月份的天数(31)比其他月份(28 或 30)多,这意味着产生收入的时间更长。因此,二月看起来总是像一个缓慢增长的月份!由于假期的原因,几周的时间可能会变短,这使得我们的增长率超出了应有的范围。
  • 公制组件。理解增长的驱动因素和增长率本身一样重要。你将增长率分解成几个部分的能力与你如何计算增长率直接相关。

就像客户流失一样,增长率没有神奇的公式,你需要自己决定如何最好地衡量你的业务增长。到目前为止,我们所介绍的内容应该足以让您开始定义业务增长,并找到相应的计算方法。

第二部分。复合增长率

很容易想到一个月到下一个月(或几天或几周)的增长率。然而,增长率通常会被考虑更长的时间,因为在你的增长中可能会有很多变化。

为了说明这一点的重要性,让我们以一家公司为例,这家公司每月收入稳定增长 1,000 美元(每月流失率为 0)。他们的总收入图表是一条简单的直线,显示了持续增长的业务:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

linear growth over time — a straight line

然而,如下图所示,这个线性增长率正在随着时间的推移而降低!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

linear growth over time means a decreasing growth RATE!

这是因为随着公司的发展,1000 美元在总收入中所占的比例越来越小。最终,如果公司每月收入达到 100 万美元,他们每月增加的 1000 美元将只有 0.1%的增长!

每月 10%的持续增长率意味着你实际上在产生复合增长,也就是说你每个月都在更快地增长。同一家公司,从 1,000 美元的初始收入开始,以 50%的增长率持续增长,其总收入将增长如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Revenue growth on $1,000, with a consistent 50% monthly growth rate.

为了在一段时间内保持一个增长率,你的规模越大,你的增长速度就越快。对于那些设定未来增长率目标的公司来说,这是一个隐藏的陷阱——随着时间的推移,你设定的具体增长率目标越往后,就越难保持。

第三部分。季节性增长

到目前为止,在我们对增长率的探索中,我们做了一个隐含的假设,即您的业务全年将以大致相同的速度增长。大部分商家都不是这样!有些业务会在某些月份快速增长,而在其他月份收缩。以一辆冰淇淋车为例:在夏季的几个月里,生意会很兴隆,增长很快,只是在秋季和冬季,随着室外天气变冷,生意会萎缩。

在季节性很强的企业中,理解增长更难,但也更重要。从你的图表上看不出你是否在增长,以下连续两年季节性业务的收入图表就证明了这一点:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Growth in seasonal business becomes more complex to understand

我们需要重新思考我们最初关于增长的假设,因为在这些业务中,通过比较一个月与前一个月来计算增长并不是一个很好的增长衡量标准。如果你不相信我,这是上例中的业务在第二年的天真增长率:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Understanding growth becomes more complex with ups and downs!

很难从这张图表中获得太多,因为它从正增长率跳到负增长率,然后再跳回来。我们所能看到的是,夏季的几个月对生意不利,但我们在增长吗?

我们可以做得更好!让我们将每个月与前一年的同一个月进行比较,前一年是一年中的同一时间(季节)。你可以在下面看到:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

For seasonal businesses consider modeling growth year over year to adjust for seasonality

我们的增长率稳定在 20%到 30%之间,直到 12 月份出现大幅增长。

这非常有用,我们可以利用它来了解我们的决策是如何影响业务的。

如果你的业务是季节性的,你可能想使用类似的方法,因为它使增长更容易理解,与你的业务更相关。

第四部分。预测增长

几乎在你定义了你的成长指标之后,你会想把它投射到未来。今年你会长得更快吗?你目前的增长速度会持续多久?你越能预测你未来的成长,你就能越准确地分配你的资源和提前计划。

不幸的是,真实世界的增长很难预测。例如,给定以下每日收入数据,让我们尝试预测下周每天的收入:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Forecasting growth can be difficult when looking at daily numbers.

像大多数真实世界的数据一样,这些数据中隐藏着模式和趋势,这使得外推变得困难。幸运的是,有一个简单的方法来模拟周期性周数据的增长。我们可以观察到,重复的循环意味着我们可以独立地关注一周中的每一天,而不是试图从整体上理解数据。这样一来,way 就可以使用像线性回归这样的技术来给我们一个下周每天的预测(阅读更多关于这个)。

例如,如果我们只分析周一,趋势实际上是一条直线!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

consider forecasting trends by day of week to smooth out the noise from day of week fluctuations

通过为一周中的每一天创建单独的趋势,我们可以以相当高的准确度为我们认为下周每天的收入建立一个模型(我们可以使用更高级的技术,如双指数平滑来平滑单个估计值):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Aggregate your day of week trends into a single model to smooth out the noise from day of week fluctuations

有了这个预测,我们就可以像本周前几章那样计算未来的增长率了!

回顾:你的业务是否在增长是一个重要的事实,但是增长速度有多快却很难确定。您计算和预测增长的方式将取决于您对业务增长的定义,最好尽早做出决定。

离群值 **监控您的业务数据,并在发生意外变化时通知您。**我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。安排今天的演示

  • Outlier 是 Strata+Hadoop World 2017 观众奖得主。

如何用 Apache Spark 和 Apache Kafka 实时捕捉和存储推文?使用云平台,比如 Databricks 和 GCP(第 1 部分)

原文:https://towardsdatascience.com/how-to-capture-and-store-tweets-in-real-time-with-apache-spark-and-apache-kafka-e5ccd17afb32?source=collection_archive---------8-----------------------

包含代码和教程的可重复的端到端解决方案

大家好,借此机会我想分享一个关于如何使用云平台如 Databricks谷歌云平台实时捕获和存储 Twitter 信息的例子 Spark StreamingApache Kafka 作为开源工具。

这次我们将使用 Spark 与 Twitter 进行交互,并通过 Producer 的 API 将数据带到 Kafka 主题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在开始开发之前,必须理解一些基本概念:

Spark Streaming: 它是 Apache Spark core API 的扩展,以可扩展的方式响应近实时(微批处理)的数据处理。Spark Streaming 可以连接不同的工具,如 Apache Kafka、Apache Flume、Amazon Kinesis、Twitter 和 IOT 传感器。

Apache Kafka: 这是一个快速、可伸缩、持久、容错的发布订阅消息系统。Kafka 通常用于使用流数据提供实时分析的实时架构中。

我们开始吧!

  1. **Twitter 应用:**要获取推文,我们必须在Twitter devs注册并创建一个应用。Twitter 会给我们 4 个重要的价值观,让我们能够消费信息:
  • 消费者密钥(API 密钥)
  • 消费者秘密(API 秘密)
  • 访问令牌
  • 访问令牌秘密

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**2.**Spark data bricks:data bricks 平台允许我们创建一个免费的 Spark-Scala 集群。我们必须注册 Databricks ,然后创建一个 scala 笔记本,我们将在其中编写代码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在编写代码之前,我们必须创建一个集群并导入两个库,Twitter library将允许我们将 Twitter API 与 Spark 和 KafkaLibrary 一起使用,这有助于我们连接 Apache Kafka。

这里是如何使用 Maven 导入库的文档:https://docs.databricks.com/user-guide/libraries.html

创建集群:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后,我们必须选择选项:导入库

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后,我们选取漫威坐标为源,写出库名:spark-streaming-Kafka-0–10 _ 2.11。

之后,我们对spark-streaming-Twitter _ 2.11做同样的事情

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,我们只需要让我们的 Kafka 集群开始执行我们的开发。

****3.Google 云平台中的 Apache Kafka:要创建集群,我们必须遵循以下步骤

a)在 GCP 创建一个实例并安装 Kafka,遵循下一个Kafka-Cloud教程。

b)启用并创建规则以公开端口 2181(zookeeper)和 9092(kafka)。从我们虚拟机的 ssh 控制台输入以下命令:(记住要更改变量 NAME_VM

***gcloud compute firewall-rules create rule-allow-tcp-9092 --source-ranges 0.0.0.0/0 --target-tags allow-tcp-9092 --allow tcp:9092**gcloud compute firewall-rules create rule-allow-tcp-2181 --source-ranges 0.0.0.0/0 --target-tags allow-tcp-2181 --allow tcp:2181**gcloud compute instances add-tags NAME_VM --tags allow-tcp-2181
gcloud compute instances add-tags NAME_VM --tags allow-tcp-9092***

c)配置 Kafka 属性文件以公开其服务,在 SSH 的下一个配置文件 server.properties 中添加以下参数。

***vi /usr/local/kafka/config/server.properties**listeners=PLAINTEXT://your_internal_ip_vm:9092
advertised.listeners=PLAINTEXT://your_external_ip_vm:9092***

d)最后,重新启动 Kafka 服务以使所做的更改生效。

***sudo /usr/local/kafka/bin/kafka-server-stop.sh**sudo /usr/local/kafka/bin/kafka-server-start.sh -daemon /usr/local/kafka/config/server.properties***

现在我们准备消费来自 Twitter 的数据,并将其存储在 Apache Kafka 的一个主题中,走吧!

在我们的笔记本中,我们输入以下代码:

你可以从 jmgcode 下载完整的笔记本

要查看 Kafka 中的消息,您可以在 GCP 环境中启动以下命令:By SSH

**sudo /usr/local/kafka/bin/kafka-console-consumer.sh --bootstrap-server your_internal_ip_vm:9092 --topic llamada**

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

working 😃

在 Databricks 中,我们可以跟踪我们处理的推文:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

number of tweets per second

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这就是目前的全部内容,在第二部分中,我们将看到如何在 rt 中对这些信息进行一些转换,并将结果存储在 Apache Hbase、Cassandra 或 Apache Kudu 等数据库中。

下期帖子再见:)…

**** [## jmendezgal/卡夫卡-twitter-spark-streaming-cloud

通过在 GitHub 上创建帐户,为 jmendezgal/Kafka-Twitter-spark-streaming-cloud 开发做出贡献。

github.com](https://github.com/jmendezgal/kafka-twitter-spark-streaming-cloud/blob/master/KafkaTwitterSparkStreaming.scala)****

如何使用 R 和 ggplot2 更改日期时间轴上的中断数

原文:https://towardsdatascience.com/how-to-change-the-number-of-breaks-on-a-datetime-axis-with-r-and-ggplot2-douglas-watson-338f0d353f05?source=collection_archive---------5-----------------------

我花了惊人的时间才找到如何在 ggplot2 日期时间轴上更改刻度间隔,而无需手动指定每个位置的日期。一旦你知道了语法,解决方案就出奇的简单明了:

scale_x_datetime(breaks = date_breaks("12 hours"))

这意味着每 12 小时休息一次。间隔可以是scales包接受的任何值:“秒”、“分”、“小时”、“天”、“周”、“月”或“年”。尾部的s被忽略。请阅读如何旋转标签文本的示例和说明。

例子

我们用一些假数据来说明。我重用了我的闪亮教程中的 CSV 数据。你可以在这里下载文件。格式如下所示:

"timestamp","date","origin","variable","value" 
1448315085.07,2015-11-23 21:44:45,"kitchen","temperature",24.4 
1448315085.07,2015-11-23 21:44:45,"kitchen","humidity",44.9 
1448315085.07,2015-11-23 21:44:45,"bedroom","temperature",24.8 
1448315085.07,2015-11-23 21:44:45,"bedroom","humidity",46.1 
1448318685.07,2015-11-23 22:44:45,"kitchen","temperature",23 
1448318685.07,2015-11-23 22:44:45,"kitchen","humidity",41.1 
1448318685.07,2015-11-23 22:44:45,"bedroom","temperature",23.6 
1448318685.07,2015-11-23 22:44:45,"bedroom","humidity",45.7 
1448322285.07,2015-11-23 23:44:45,"kitchen","temperature",23.4 
...

让我们将它加载到 R dataframe 中,确保将 date 列转换为 R datetime 对象(参见我的上一篇关于这个主题的文章,然后创建一个简单的温度-时间图:

library(ggplot2) 
library(dplyr) data <- read.csv("data.csv") 
data$date <- as.POSIXct(data$date) 
temperatures <- filter(data, variable == "temperature", 
                       origin == "kitchen") qplot(date, value, data = temperatures, geom="line", 
      ylab = "Temperature [C]")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

默认的休息时间很合理,但是为了便于说明,让我们将它们改为每两天休息一次。标签格式遵循 strftime 语法(见http://www.foragoodstrftime.com/帮助构建它们):

qplot(date, value, data = temperatures, 
      geom="line", ylab = "Temperature [C]") + 
    scale_x_datetime(breaks = date_breaks("2 day"), 
                     labels = date_format("%b %d"))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你可以看到休息的次数已经改变了。很多时候,我更感兴趣的是增加它们的密度。让我们切换到以小时为单位的时间间隔,并在标签中包括时间:

qplot(date, value, data = temperatures, 
      geom="line", ylab = "Temperature [C]") + 
    scale_x_datetime(breaks = date_breaks("12 hour"), 
                     labels = date_format("%b %d - %H:%M"))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

哎哟!标签不可读。幸运的是,我们可以旋转文本以防止它们重叠:

qplot(date, value, data = temperatures, 
      geom="line", ylab = "Temperature [C]") + 
    scale_x_datetime(breaks = date_breaks("12 hour"), 
                     labels = date_format("%b %d - %H:%M")) +
    theme(axis.text.x = element_text(angle = 25, 
                                     vjust = 1.0, hjust = 1.0))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那好多了!如果您将角度设置为 90 度,或者如果您有一个旧版本的 R,您将需要调整vjusthjust值,直到标签正确排列。尝试将debug = TRUE添加到element_text来显示文本锚点。

包括图书馆里的这些

我发现自己在许多 R 笔记本上加载相同的数据格式并制作类似的图形,所以我编写了一个小型函数库,可以在我的所有分析中重用。希拉里·帕克的指南解释了你自己写作所需要的一切。我的函数类似于下面的代码,我可以选择指定一个刻度间隔。如果我以小时为单位指定时间间隔,标签会自动包含时间。如果我将参数留空,ggplot 将保持其默认值:

plot_temperature <- function(data, title = "", breaks = "", angle = 25) {
    p <- ggplot2::qplot(date, value, data = data, 
                        ylab="Temperature [C]") 

    if (title != '') {
      p <- p + ggplot2::ggtitle(title)
    }

    if ( breaks != '' ) {
      if ( grepl("hour", breaks) ) {
        fmt <- "%b %d - %H:%M"
      } else {
        fmt <- "%b %d"
      }
      p <- p + ggplot2::scale_x_datetime(date_breaks = breaks, 
                                         date_labels = fmt) +
        ggplot2::theme(axis.text.x = ggplot2::element_text(
          angle = angle, vjust = 1.0, hjust = 1.0
        ))
    }
    return(p)
}

当您将函数移动到外部库时,指定您调用的每个函数的名称空间非常重要。于是ggplot2::分散各处。

原载于Douglas-Watson . github . io

如何选择数据科学工作?

原文:https://towardsdatascience.com/how-to-choose-a-data-science-job-53007d7f195f?source=collection_archive---------2-----------------------

这是数据科学的全盛时期…

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Yes! Yes!Yes!

1。世界各地大学最热门的新课程都在这个领域。

2。数据科学家毕业生的起薪中值为 93,000 美元,令人印象深刻。

3。六位数数据科学工作的广告很常见。

数据科学似乎无愧于 21 世纪最性感工作的称号。”

但是随着这个领域的所有这些骚动,许多人想知道数据科学职业的趋势是否只是一种时尚。为什么要拿你的教育、职业和未来做赌注呢?

有这些犹豫是合理的。所有称职的数据科学家都应该知道用事实而不是直觉工作的重要性。

这就是为什么在下面的文章中,我们将揭示五种新兴角色如何产生公司不能忽视的已被证明的价值。

此外,我们将解释每个职位的共同期望和责任,以帮助你专注于获得你真正想要的工作。

在我们详细研究这五个角色之前,让我们先明确一下为什么数据科学工作如此有前途。

为什么从事数据科学职业是值得的?

数据科学角色将呈指数级增长

在我们热爱的领域里,工作是时尚的,但是不要让这种认为趋势是短暂的想法阻止你去学习更多关于这个主题的知识。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

So far — So good (source: Indeed.com)

我们生活在数字时代,随着技术的进步,获取、存储和处理数据的能力也会提高。

公司需要人来管理和控制这些阶段。因此,随着工作领域的技术义务变得更加苛刻,对数据科学家的需求只会增加,这是合乎逻辑的一步。

但不要相信我的话:专家预测,未来三年内,新的数据和分析工作将增加 364,000 个。这不是一个可以掉以轻心的数字。

数据科学工作的竞争较少

预计的 364,000,000 个新工作岗位将需要人员来填补。

尽管在线和传统机构的数据科学课程数量惊人增长,但由于其快速增长,未来十年该领域不太可能出现员工过剩。

公司正在努力填补职位空缺。数据科学职位的开放时间比更传统的职位发布时间更长,例如,专业服务行业的分析经理职位平均需要 53 天,比该领域的平均时间多 8 天。

因此,众所周知,确实缺乏合适的候选人,现在是在就业市场上利用这一需求的时候了。

各行各业都感受到了数据工作爆炸的余震,包括:

休闲&旅游: Airbnb 建立了一所内部大学,专门研究数据科学。
**金融:**人工智能将被会计师用于减轻审计负担。
医学: IBM 计划在其大获成功的沃森人工智能的基础上,创建一个跨学科的数据科学网络。

除此之外,在这些领域和许多其他领域,公司需要熟练的工人来带领他们穿越数据科学的波涛汹涌的水域。

数据科学可能是你未来工作保障的最佳选择

机器人有一天将取代许多目前由人类完成的工作,这种想法不再是科幻小说中的东西,对于任何开始职业生涯的人来说,这都应该是一个值得关注的问题。

德意志银行首席执行官 John Cryan 在接受美国消费者新闻与商业频道采访时表示,在通过技术简化工作流程的过程中,金融领域的非技术性工作将不可避免地受到影响。

《卫报》最近报道称,在未来 10 年内,英国私营部门的 400 万份工作可能会被机器人取代。

虽然很少有工作不存在未来自动化的风险,但数据科学的吸引力在于它直接分析、管理和改变工作流程和公司信息的数字后端。

对于那些在未来不确定时期寻找工作保障的人来说,这是一个合理的——如果不是完全可靠的——计划。

我很高兴给你一个数据科学工作的顶级概述。为了更深入地了解这一领域,请参加 2018 年 10 月 12 日至 14 日在圣地亚哥举办的数据科学大会。

在本次会议上,您将从该领域的专家那里获得有价值的信息,帮助您开启数据科学职业生涯。

开启您的数据科学职业生涯

这三个原因应该会激起你对这个领域的兴趣…

但是数据科学家实际上是做什么的呢?什么是数据分析师与数据科学家?

不喜欢数据科学技术方面的人有什么选择?

查看以下五个关键角色及其职权范围,以表明该领域不仅对公司越来越重要,而且数据科学是 21 世纪最令人振奋的工作领域。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

选择适合您的数据科学工作:

有许多职业道路可供选择,并且很难驾驭。为了帮助你找到理想的角色,以下是大多数广告中常见的五个头衔,以及对他们可能承担的职责的描述。

商业分析师:
这些类型的角色对许多公司来说都是舒适的领域,因为商业智能的概念在数据繁荣之前已经存在了很长时间。

因此,它们可能比更具分析性或需要编程知识的职位更具竞争力。

商业分析师不太可能自己分析数据。相反,他们应该将准备好的数据转化为公司未来运营的引人注目的视觉效果。

无论你的职责是什么,如果你有兴趣成为一名商业分析师,强大的表达能力是很重要的。

数据分析师(数据准备):
数据准备方面的专家才是真正的数据科学项目的中坚力量。数据准备不是一件容易的事情,在项目的这个阶段出现失误会导致失败。

在这些职位上,工作人员必须手动在无尽的数据行中搜寻,根据需要进行清理和结构化。这使得它成为一个繁琐而困难的过程,需要一些技术知识,更重要的是,相当注意细节。尽管有这些职责,这些角色通常被称为入门级职位。

这些工作对于那些可能已经上过数据科学课程并希望实践他们新获得的技能的人来说可能是理想的“实习”,以在承担其他责任之前增加他们在该领域的信心。在这个职位上证明你自己,你将比其他寻求立足之地的候选人更有竞争力。

数据分析师(建模)/数据建模师:
虽然名字相似,但数据分析师在建模方面实际上要比他们的数据分析师(数据准备)同行负责更多。

数据建模师的任务是开发能够管理和处理公司数据库的系统。编程专业知识对于这些角色来说是必不可少的。

虽然数据准备可能不是工作描述中的要求,但如果你准备数据集的技能不稳定,请谨慎从事:较小的公司可能会整合数据分析师的角色,这意味着除了数据建模员之外,你还可能被赋予数据准备员的职责。

数据科学家/高级分析师/机器学习(ML)从业者/高级数据科学家:
这些角色是数据科学跳动的心脏。任何想要解决这些问题的人都必须是一个多面手…并且是所有人的主人!对于这些职位,你必须精通数据科学项目的所有阶段。

对于普通读者来说,我们对这些迷人的角色垂涎三尺并不奇怪。这些工作需要人们跳出框框思考问题,然后为公司未来的健康发展创造可行的解决方案。

说了这么多,这些职位只适合喜欢主动的人。如果你想遵循一套严格的规则,在 5 点钟结束一天的工作,这些规则不适合你。

如果你喜欢挑战,如果你有创造力,如果你在工作中渴望编程和分析任务,立即申请吧!

数据科学经理/分析经理:
这些角色为回避更多技术职位的人开了绿灯。他们只是浏览了数据科学的表面——重点是客户和团队的一般管理。

管理职位自然最适合喜欢跨团队交流和与客户交流的人。由于它们不直接处理数据科学的技术方面,它们可能不适合希望成为“严肃”数据科学家的人。

这是因为经理们将忙于员工和预算控制,因此没有时间参与编程或分析。

然而,由于他们的管理职责,这些职位可能是那些已经在另一个领域进入职业生涯并计划转向数据科学的人的合理解决方案。

最终外卖

当你在寻找一份利润丰厚的数据科学职业时,把这些细目分类放在身边作为工作备忘单——它将帮助你快速剔除不太适合的职位。

请记住,虽然我们尽了最大努力来强调对每个角色的总体期望,但每个角色的实际工作规范会因公司而异。

和其他职位一样,在申请之前一定要通读说明书。数据科学家注重细节——确保你在应用中证明了这一点!

有关如何改善您的数据科学职业生涯的更多信息,点击此处参加我们 2018 年 10 月 12 日至 14 日的直播。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Click here to reserve your seat!

参考资料:

以下是领英 2017 届毕业生的前 15 份工作-https://tech.co/linkedin-jobs-grads-2017-05

数据科学家:21 世纪最性感的工作——https://HBR . org/2012/10/Data-Scientist-21 世纪最性感的工作

量子危机:对数据科学技能的需求正在扰乱就业市场https://www . IBM . com/analytics/us/en/technology/data-science/Quant-Crunch . html

IBM 预测到 2020 年对数据科学家的需求将飙升 28%https://www . Forbes . com/sites/louiscumbus/2017/05/13/IBM-Predicts-Demand-For-Data-Scientists-Will-Soar-28-By-2020/# 4 e5d 9 a 9 e 7 e 3 b

Airbnb 正在运营自己的内部大学,教授数据科学https://TechCrunch . com/2017/05/24/Airbnb-is-running-its-own-internal-university-to-teach-data-science/

IBM 的 Watson 数据平台旨在成为数据科学操作系统http://www . zdnet . com/article/ibms-Watson-Data-Platform-aims-to-be-Data-science-operating-system/

德意志银行首席执行官直言不讳地谈到自动化将对银行业的工作岗位产生什么影响https://www . CNBC . com/2017/09/17/jobs-and-automation-Deutsche-Bank-CEO-cry an-warns-at-Singapore-summit . html

机器人“可能在 10 年内夺走 400 万份英国私营部门工作岗位”——https://www . the guardian . com/technology/2017/sep/19/Robots-can-take-400 万份私营部门工作岗位——10 年内

如何选择有效的机器学习和数据科学课程

原文:https://towardsdatascience.com/how-to-choose-effective-moocs-for-machine-learning-and-data-science-8681700ed83f?source=collection_archive---------1-----------------------

给希望学习数据科学/机器学习并为之做出贡献的非 CS 领域的年轻专业人士的建议。根据个人经验策划。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

动机

比尔·盖茨在最近的毕业典礼上宣称,人工智能(AI)、能源和生物科学是当今年轻的大学毕业生可以选择的三个最令人兴奋和最有回报的职业。

我完全同意。

我坚信,我们这一代人面临的一些最重要的问题——与可持续性、能源生产和分配、交通、获得基本生活设施等有关。取决于我们如何明智地将盖茨先生提到的前两个知识分支结合起来。

换句话说,在物理电子世界(半导体行业构成了这个世界的核心部分),必须做更多的事情来充分享受信息技术的成果以及人工智能或数据科学的新发展。

我想学,但是从哪里开始呢?

我是一名半导体专业人士,在一家顶级科技公司拥有超过 8 年的博士后工作经验。我感到自豪的是,我在物理电子学的交叉领域工作,这直接有助于能源部门。我开发功率半导体器件。它们能够高效可靠地传输电力,从智能手机内部的微型传感器到处理日常消费食品或布料的大型工业电机驱动器,它们都可以供电。

因此,很自然地,我想学习和应用现代数据科学和机器学习的技术来改进这种设备和系统的设计、可靠性和操作。

但我不是计算机科学毕业生。我分不清链表支持向量机听起来像(几个月前)一些残疾人专用设备。我记得的人工智能的唯一关键词(来自我大三的选修课)是’ 一阶谓词演算 ',这是所谓的’旧人工智能知识工程方法的残余,与较新的基于机器学习的方法相对。

我必须从某个地方开始学习基础知识,然后深入学习。显而易见的选择是 MOOC ( 大规模开放在线课程)。我仍然处于学习阶段,但我相信我至少已经积累了一些选择适合这条道路的 MOOC 的好经验。在这篇文章中,我想分享我在这方面的见解。

了解你的“气”和你的“敌人”

这是 Netlfix 最新的超级英雄系列剧——《守卫者》。

但确实,在开始通过 MOOC 学习之前,你应该非常清楚自己的优势、劣势和技术倾向。

因为,让我们面对现实吧,时间和精力是有限的,你不能把你宝贵的资源浪费在你在当前工作或未来工作中不太可能实践的事情上。这是假设你想走 (几乎)免费的学习道路,即旁听 MOOCs 而不是花钱买证书 。我有一个“差不多”在这里,因为在本文的最后,我想列出几个我认为你应该付费来展示证书的 MOOCs。就我个人而言,我不得不为我参加的几门 Udemy 课程付费,因为它们从来都不是免费的,但你可以在促销时以一份美味午餐三明治的价格购买它们。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

What you can and cannot learn from MOOCs

在这幅图中,我只是想展示这个过程的可能性和不可能,即你希望通过自学和实践学到什么,以及无论你的职业是什么,在工作中必须学到什么或必须培养什么样的心态。然而,话虽如此,这些圈子广泛包含了一个人可以学习的核心技能,以便从非 CS 背景进入数据科学/机器学习领域。请注意,即使你在信息技术(IT)领域,你可能会有一个陡峭的学习曲线,因为传统的 IT 正在被这些新领域所破坏,核心技能和良好的实践往往是不同的。

就我而言,我认为数据科学领域比许多其他专业领域(例如我自己的工作领域半导体技术)更民主,在那里进入门槛低,只要足够努力和热情,任何人都可以获得有意义的技能。就我个人而言,我并没有“闯入”这个领域的强烈愿望,相反,我只是有一种热情,想借用这些成果来应用到我自己的专业领域。然而,这个最终目标并不影响人们必须经历的初始学习曲线。因此,你可以瞄准成为数据工程师、商业分析师、机器学习科学家或可视化专家——领域和选择都是敞开的。如果你的目标和我一样——停留在当前的专业领域,应用新学到的技术——你也很好。

你可以从真正的基础开始,这没什么不好意思的:)

我从真正的基础开始— 在 Codeacademy 上学习 Python。十有八九,你不能比这更基本:-)。但它成功了。我讨厌编码,但 Codeacademy 免费课程简单有趣的界面和正确的节奏足以让我继续下去。我本可以在 Coursera 或 Datacamp 或 Udacity 上选择 Java 或 C++课程,但一些阅读和研究告诉我,Python 是平衡学习复杂性和实用性(特别是对于数据科学)的最佳选择,我决定相信这种洞察力。

过了一段时间,你渴望更深层次的知识(但速度很慢)

odeacademy 的推出是一个良好的开端。我可以从这么多在线 MOOC 平台上选择,不出所料,我同时注册了多门课程。然而,在涉猎了几天 Coursera 课程后,我意识到我还没有准备好向教授学习 Python!我一直在寻找一门由一些热情的讲师讲授的课程,他们会花时间详细讲解概念,教我其他基本工具,如 Git 和 Jupyter notebook system,并在课程的基本概念和高级主题之间保持适当的平衡。我找到了这份工作的合适人选:何塞·马西亚尔·波尔蒂利亚。他在 Udemy 上为提供多门课程,并且是该平台上最受欢迎和最受好评的讲师之一。我报名完成了他的Python boot camp课程。这是对这门语言的惊人介绍,速度、深度和严谨都恰到好处。我向新学员强烈推荐这门课程,即使你不得不支付 10 美元( Udemy 课程通常不是免费的,它们的正常价格是 190 美元或 200 美元,但你总是可以等待几天,以获得经常性的推广周期,并注册 10 美元或 15 美元)。

保持对数据科学的关注非常重要

下一步对我来说至关重要。我可能会误入歧途,尝试学习 Python 上的任何东西。尤其是面向对象和类定义部分,很容易就能让你陷入漫长而艰难的旅程。现在,没有从 Python 世界的关键领域带走任何东西,可以有把握地说,您可以在不能够在 Python 中定义自己的类和方法的情况下实践深度学习和良好的数据科学。 Python 作为数据科学的首选语言越来越受欢迎的一个根本原因是,大量高质量、经过同行评审、由专家编写的库、类和方法的可用性,正等待着以一种良好的打包形式下载,并展开以无缝集成到您的代码中。

因此,对我来说,快速进入数据科学最广泛使用的包和方法非常重要——NumPyPandasMatplotlib

我是通过 edX 的一个简洁的小课程被介绍给这些人的。虽然 edX 上的大部分课程都是来自大学,性质严谨(而且长ish】,但是像微软这样的科技公司提供的短而多动手/少理论的课程很少。其中之一就是 微软数据科学专业计划 。你可以在这个项目下注册任意多的课程。然而,我只学了以下课程(我打算以后再来学其他课程)

  • 数据科学方向 :讨论典型的数据科学家的日常生活,并触及一个人在这个角色中应该具备的核心技能,以及对构成主题的基本介绍。
  • 数据科学 Python 入门 :讲授 Python 基础知识——数据结构、循环、函数,然后介绍 NumPyMatplotlibPandas
  • Excel数据分析入门:教授 Excel 的基本和少量高级数据分析函数、绘图和工具(例如透视表power pivot求解器插件)。
  • 数据科学用 R 简介 :用 ggplot2 介绍 R 语法、数据类型、向量和矩阵运算、因子、函数、数据帧、图形。

虽然这些课程以一种基本的方式呈现材料,并且只涵盖最基本的例子,但它们足以激发灵感!好家伙,我被迷住了!

我转而详细学习 R——有一段时间了

最后一门课程让我意识到几件重要的事情:(a)统计学和线性代数是数据科学过程的核心,(b)我不知道/已经忘得够多了,以及© R 自然适合于我想用我的数据集做的那种工作——由受控晶圆厂实验或 TCAD 模拟生成的几 MB 大小的数据,为基本的推理分析做好准备。

这促使我寻找一个坚实的 R 语言入门课程,还有谁比何塞·波尔蒂利亚更好呢!我报名参加了他的“ 数据科学和机器学习训练营与 R ”班。这是一笔“买一送一”的交易,因为课程在前半部分涵盖了 R 语言的基础知识,并转向教授基本的机器学习概念(入门课程中预期的所有重要概念都得到了足够的关注)。与使用基于服务器的动手实验室环境的 edX 微软课程不同,本课程涵盖了 R Studio 和必要软件包的安装和设置,向我介绍了 kaggle ,并为我从被动学习者(也称为 MOOC 视频观察者)转变为不怕玩数据的人提供了必要的推动力。它还遵循了加雷斯·詹姆斯、丹妮拉·威滕、特雷弗·哈斯蒂和罗伯特·蒂布拉尼所著的《》(ISLR)中的《统计学习导论》一章一章地讲述。

如果让你一生只看一本书学习机器学习,别的什么都不看,那就挑这本书,看完所有章节,无一例外。对了,这本书里没有神经网络或者深度学习的材料,所以有那个…

有了课程材料、ISLR 的书、从 kaggle 下载的随机数据集的练习,甚至是从 PG&E 下载的我自己的用电数据,我不再害怕编写小字节的代码,这些代码实际上可以模拟一些有趣或有用的东西。我分析了一些美国县级犯罪数据,为什么一个大型实验设计会导致虚假关联,甚至我公寓过去 3 个月的用电量。我还成功地使用 R 建立了基于我工作中的一些真实数据集的预测模型。语言的统计/功能性质和各种模型(回归或分类)的置信区间(p 值或 z 值)的现成估计确实有助于新手在统计建模领域轻松立足。

尽可能多学习数学基础知识

这方面的学习怎么强调都不为过——特别是对于非计算机专业的毕业生和 IT 工程师来说,他们在职业生涯中几年都没有接触过严谨的数学。我甚至写过一篇关于机器学习和数据科学需要具备哪些数学知识的中等文章。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Mathematics necessary to learn/refresh for gaining foothold in data science/machine learning

为此,我从 Cousera 和 edX 选择了几门课程。很少有作品在深度和严谨性上脱颖而出。那些是,

  • **数据科学和分析的统计思维 **(哥伦比亚大学):哥伦比亚大学 edX 上的数据科学高管证书课程的基础统计课程。严谨,但以结构化的方式很好地深化了概念。
  • **计算概率与推理 **(麻省理工):这是麻省理工出的硬题,要注意!它以无与伦比的深度涵盖了贝叶斯模型和图形模型等高级主题。
  • [统计学与 R 专业化](http://Statistics with R Specialization) ( 杜克大学):这是杜克大学的 5 门课程(最后一门是顶点项目,你可以忽略它)专业化,通过动手编程练习来增强你的统计学基础。推荐平衡难度和严格程度。
  • LAFF:线性代数——前沿基础(UT Austin):这是一门令人惊叹的线性代数基础课程(以及关于线性代数例程高性能计算的深入讨论),你必须尝试一下。由德克萨斯大学奥斯汀分校在 edX 平台上提供。相信我,在学完这门课程后,你将永远不会想求矩阵的逆来解一个线性方程组,即使这很诱人也很容易理解,但你会试图找到一种 QR 分解乔莱斯基分解来降低计算复杂度。****
  • 商业分析中的优化方法 ( 麻省理工):这是麻省理工的一门商业分析优化/运筹学方法的课程。我报名是因为这是我能找到的关于线性和动态编程技术的唯一一门在 good platform (edX)上评价很高的课程。我相信学习这些技术会非常有帮助,因为优化问题会出现在几乎所有的机器学习算法中。

请注意,我没有搜索和注册任何微积分课程,因为我对我能记得的知识水平(从大学时代)和我期望对任何机器学习或数据科学研究和实践有用的知识感到满意。如果你在这方面生疏,请寻找一个好的。

更新:这是我写的一篇专门关注数据科学数学的文章。这篇文章被放在 KDNuggets 和 Medium editorial choice 的显著位置。所以,试试吧…

机器学习——各种各样的个性让它变得丰富多彩

在所有这些业余学习中,我设法完成了被认为是所有 MOOCs 先驱之一的课程——吴恩达在 Coursera 上的机器学习课程。我猜已经有很多关于它的文章了,因此,我不会再浪费你的时间来描述这个课程了。拿着它,做所有的家庭作业和编程作业,学会用你知道的所有主要机器学习算法的矢量化代码来思考,并保存笔记以备将来工作时参考。

哦,对了,如果你想温习/从头学习 MATLAB(这门课你会需要写 MATLAB 代码,不是 R 或者 Python),那么你可以看看这门课:MATLAB 编程入门

现在,我想谈谈个性。

我参加了多门机器学习课程,我最喜欢的方面是意识到对同一基础学科的处理如何成为不同讲师的个性和世界观的函数:)这是一次迷人的经历。

我列出了我注册并参与的各种机器学习 MOOCs

  • 【机器学习(斯坦福大学)】 :吴恩达广为人知的课程。上一段讲到了。
  • 【机器学习专业化(华盛顿大学) :这和 ng 的味道不一样。Emily Fox 和 Carlos Guestrin 分别从统计学家和从业者的角度介绍了这些概念。我不能安装 Carlos 的公司提供的免费许可 Python 包,但是这个专门化对于它的理论讲座来说是值得完成的。一些基本概念的证明和讨论,如偏差-方差权衡、成本计算以及成本函数最小化的解析方法与数值方法的比较,甚至比 ng 教授的课程更直观、更仔细(鉴于 Ng 教授的教学质量非常高,这也说明了一些问题)。
  • ****【哥伦比亚大学】 :这门课程的教学大纲与一般的机器学习课程有些不同,它将整个前半部分都用于传统算法讲座。它涵盖了基本的排序、搜索、图遍历和调度算法。关于这些算法如何准确地用于机器学习问题,没有太多一对一的讨论,但研究它们会让你了解传统的计算机科学知识,这是理解如何解决大规模数据科学问题所必需的。当你要乘矩阵时,想想【o(n^3】)当你要对一个列表排序时,想想 O(nlog(n))。你可能不会在日常工作中专门使用这些知识,但是了解这些计算过程的具体细节肯定会拓宽你对手头问题的世界观。
  • 数据科学:Data to Insights (MIT xPro 6 周在线课程) :这是我上过的为数不多的付费课程之一(MOOCs 我一般走审计路线)。这在公共 edX 网站上不可用,尽管它使用 edX 平台来传送内容。为期 6 周的课程结构合理,充满有趣的内容,为门外汉打开了数据科学和机器学习的广阔世界。案例研究非常有趣,但编纂起来相当困难和耗时。讲座非常引人入胜,展示了这些案例研究。我特别喜欢的模块是关于推荐系统的。上完这门课后,我真的开始在我的笔记本电脑上用邻接矩阵查看 网飞屏幕了
  • 【T2 大学】用于机器学习的神经网络:这是 Coursera 上一门有些被低估的课程,即使有神经网络先驱 Jeff Hinton 作为指导老师。我意识到吴恩达新的深度学习专业将直接与这门课程竞争,如果 Coursera 在不久的将来删除它,我不会感到惊讶。然而,当它还在的时候,一个深度学习的热心人应该耐着性子看完这一关,即使只是为了揣摩深度网络的历史发展模式。
  • 【Deep Learning . ai】:这是最新的一个孩子,但它站在吴恩达的肩膀上,因此拥有非常强壮的腿:)我已经完成了第二个课程,现在正在进行第三个课程。陪审团仍然存在,但如果你想重温深度学习的最新趋势,你肯定应该考虑完成这个系列。即使编程任务看起来很难,并且你不想手工编程一个深度网络(你可以争辩说总有优秀的开源包,如 TensorFlow、Keras、Theranos,它们可以解决实际问题),深入理解正则化、爆炸梯度、超参数调整、批处理规范化等基本概念是必不可少的。来有效地使用那些高级的深度学习框架。

两个伞式数据科学 MOOCs,包含 R 和 Python

随着这篇长文的结尾越来越近,我想列出两个我觉得有趣和有用的多课程 MOOCs,以配合上面提到的特定主题领域。

  • 【约翰·霍普斯金大学】 :这是 Coursera 上提供的一个知名的 10 门课程的专业。不是每门课程都会吸引每个学习者。我个人只完成了 10 个中的 5 个。关键是时机,即何时开始这种专业化。当人们研究数据科学的 MOOC 时,这经常出现在谷歌搜索结果的顶部,因此这成为许多新学习者的第一个 MOOC。就我个人而言,如果我那样做了,我将很难从这门课程中获得全部价值。微软和 Udemy 关于 R 的入门课程,以及在此之前的一些统计学和线性代数课程极大地帮助了我从这些课程中获得最大的收益。由于专业化是由 JHU 生物统计系的教授指导的,人们在数据科学的两个方面得到了很好的处理,这两个方面在许多课程中往往是不足的——研究性学习和实验设计。
  • 【数据科学微硕士证书课程(加州大学圣地亚哥分校) :我刚刚注册并开始了这个系列/证书课程 4 门课程中的第 1 门。我喜欢这一事实,即它在广度和目标上与约翰·霍普斯金专业化相似,只是它选择 Python 作为动手部分的工作语言。结构和内容似乎经过深思熟虑,涵盖了 Python、Git、Jupyter 的基础知识,一直到 Apache Spark framework 的大数据处理(中间是统计学和机器学习课程)。案例研究和实践示例来自数据科学的现实应用,如野火建模、霍乱爆发或世界发展指标分析。首席讲师之一是 Ilkay Altintas,他创建了一个帮助野火动态预测的惊人平台,并将数据科学研究的成果用于追求社会公益。我确信我的专业化之旅将会是一次令人兴奋和有益的经历。欢迎你来参加聚会!
  • 数据科学顶点项目(Simplilearn) :通过专门的辅导课程,您将学习如何解决现实世界中与行业一致的数据科学问题,从数据处理和模型构建到报告您的业务成果和见解。

混合机器学习和大数据

随着大数据(Pb 级)的使用在商业和分析的每个方面都在增长,那些能够有效混合大数据和机器学习技能的工程师将会非常受欢迎。因此,关注围绕这一组合的几门课程是有意义的。

Simplilearn 的机器学习认证课程 :该课程通过动手实践的方式帮助你掌握有监督和无监督学习、推荐引擎和时间序列建模的概念,包括从事四个主要的端到端项目和 25 个以上的动手练习。优步和梅赛德斯-奔驰等主要行业合作伙伴对他们的课程提出建议。

谷歌基于云的 TensorFlow 专业化(Coursera) :这一 5 门课程的专业化专注于使用谷歌云平台的高级机器学习主题,在实践实验室中,您将获得优化、部署和扩展各种类型的生产 ML 模型的实践经验。

学习是相当大众化的——好好利用它

随着 MOOCs、开源编程平台、协作工具和几乎无限的免费云端存储的出现,学习变得越来越民主化、无处不在和普遍可用。如果你不是数据科学/机器学习方面的专家,但想学习这门学科,编写一些代码以提高工作效率,争取职业发展,或者只是寻找一些乐趣,现在是开始学习的时候了。几句离别的话,

  • 你是一名数据科学家 :不要让任何所谓的专家说“mooc 是给孩子们的,你不会像那样学到真正的数据科学”之类的话来打击你的士气。你试图通过参加 MOOC 学习数据科学,这一事实意味着两件事:(a)你已经在职业生涯中处理过数据;( b)你想学习从数据中提取最大价值的科学、结构化的方式,并围绕这些数据提出智能问题。这意味着你,我的朋友,已经是一个数据科学家了。如果仍然不相信,请阅读布兰登·罗勒 的博客,他是我所知道的最受尊敬和鼓舞人心的数据科学家之一。
  • 你不必花一大笔钱来学习 :我知道我列了很多课程,对你来说它们可能看起来很贵。但是,幸运的是,大多数(如果不是全部的话)可以免费注册。edX 课程总是免费注册的,它们通常在课程内容方面没有任何限制,即你可以查看、执行、提交所有评分作业(不像 Coursera,它让你观看所有视频,但隐藏评分材料)。如果你认为某个证书值得在你的简历上展示,你可以在完成一些视频并判断其价值和效用后,在课程中途支付费用。
  • 练习、编码、构建东西来补充你的在线学习 :在机器学习的背景下有一种真正的算法叫做‘在线学习’。在这种技术中,该算法不是处理数百万个数据点的完整矩阵,而是处理最近的几个数据点并更新预测。你也可以在这种模式下工作。停顿问题/停车问题总是一个迷人的问题,它也适用于学习。我们总是想知道在构建东西之前要学习和吸收多少东西,即在哪里停止学习并开始实施。不要犹豫,不要拖延。学习一个概念,通过简单的编码来测试它。使用你看过的视频中最新的技巧或技术,不要等到掌握了整个主题。你会惊讶地发现,简单的 20 行代码可以让你在观看视频时学到的最复杂的概念上进行扎实的练习(并让你流汗)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 那里有大量的数据 :你也会惊讶于网络上有多少丰富的免费数据来源。不要去 Kaggle,尝试不同的乐趣。试试data.gov或者 联合国数据门户 。前往 UCI 机器学习资源库 。感觉更冒险?那么 从 CIA 下载各个国家的数据,并尝试所有你在最新的 Matplotlib 或 ggplot2 讲座中学到的很酷的可视化效果呢?如果没有别的,从你的能源供应商那里下载你自己的用电数据,分析如果你在不同的时间打开空调或洗碗机,你是否可以节省一些钱。

本文中关于各种课程/讲师的观点完全是作者本人的观点。如果您有任何问题或想法要分享,请通过tirthajyoti【AT】Gmail[DOT]com联系作者。你可以查看作者的 GitHub 资源库 中其他有趣的 Python、R 或 MATLAB 代码片段和机器学习资源。此外,如果你像我一样对机器学习/数据科学/半导体充满热情,请随时在 LinkedIn 上添加我在 Twitter 上关注我

如何选择统计软件工具

原文:https://towardsdatascience.com/how-to-choose-statistical-software-tools-4870dd3c92a0?source=collection_archive---------4-----------------------

数据科学项目的好、坏和有帮助的方面

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The book — now in print — has an awesome picture on the cover.

摘自像数据科学家一样思考 —为您的数据科学项目选择软件时需要寻找什么。

节省 37 折 像数据科学家 用代码fccgodsey*。*

广泛的工具可用于实施统计方法。您可以将方法或模型与可用于实现它们的软件选项进行比较,并得出一两个好的选项。在选择软件工具时,有各种各样的事情要考虑,也有一些我遵循的一般规则。

工具有方法的实现吗?

您可以自己编写方法,但是如果您使用的是通用方法,有许多工具已经有了实现,使用其中一个可能更好。与你在一天内编写的、只使用一两次的代码相比,被许多人使用过的代码通常是相对无错误的。

根据您的编程能力和对各种统计工具的熟悉程度,在您最喜欢的工具中可能有一个现成的实现,您可以快速使用。如果 Excel 有,那么很可能其他工具也有。如果 Excel 不支持,那么中级工具可能支持,如果不支持,您可能需要编写一个程序。否则,您将选择不同的统计方法。

如果你决定使用一种编程语言,记住不是所有的包或库都是一样的。确保编程语言和软件包能够完全按照您的意图工作。阅读文档或一些与您想要做的分析类似的示例可能会有所帮助。

柔韧性好

除了能够执行主要的统计分析之外,如果一个统计工具能够执行一些相关的方法,通常也会很有帮助。通常,你会发现你选择的方法并不像你希望的那样有效,你在这个过程中学到的东西让你相信不同的方法可能更有效。如果你的软件工具没有任何选择,那么你要么坚持第一个选择,要么你将不得不切换到另一个工具。

例如,如果您有一个统计模型,并且想要找到最佳的参数值,您将使用似然函数和优化技术。有几种方法可以从似然函数中找到最佳参数,包括最大似然(ML)最大后验概率 (MAP)、期望最大化(EM)和变分贝叶斯 (VB)。Excel 有一些不同的具体优化算法,(它们都是 ML 方法),如果你认为你可以摆脱 ML,但你不确定,你可能想升级到一个更复杂的统计工具,有更多的优化选项。

有多种类型的回归、聚类、组件分析和机器学习,一些工具可能提供一种或多种这些方法。我倾向于支持统计工具,这些工具提供了这些方法类别中的一些,以防我发现需要切换或尝试另一种方法。

信息丰富就好

面对不确定性的意识是数据科学的主要方面;这涉及到统计软件工具的选择。一些工具可能会给出好的结果,但是没有提供如何以及为什么达到这些结果的洞察力。一方面,能够去构造方法和模型,以便更好地理解模型和系统,这是很好的。另一方面,如果您的方法在某种程度上犯了“错误”,并且您发现自己看到了一个奇怪的、意想不到的结果,那么有关该方法及其对数据的应用的更多信息可以帮助您诊断具体的问题。

一些统计工具,特别是像统计编程语言这样的高级工具,提供了查看几乎每种统计方法和结果内部的能力——甚至像机器学习这样的“黑盒”方法。这些内幕并不总是用户友好的,但至少他们是可用的。根据我的经验,像 Excel 这样的电子表格不能提供对其方法的深入了解,并且很难对比线性回归更复杂的统计模型进行解构或诊断。

普通就是好

对于生活中的许多事物——音乐、电视、电影和新闻文章——受欢迎并不总是意味着高质量;往往相反。有了软件,越来越多的人使用一个工具意味着有越来越多的人尝试它,得到结果,检查结果,并且可能报告问题,如果有的话。这样,软件就像开源软件一样,有一个反馈环,可以及时修复错误和问题。越多的人参与到这个反馈循环中,一个软件就越有可能相对来说没有错误或者健壮。

data = data.frame(X1 = c( 1.01, 1.99, 2.99, 4.01 ),
                  X2 = c( 0.0, -2.0, 2.0, -1.0 ),
                   y = c( 3.0, 5.0, 7.0, 9.0 ))linearModel <- lm(y ~ X1 + X2, data)
summary(linearModel)predict(linearModel,data)

文本 1:线性回归的 R 代码。

这并不是说现在最流行的东西是最好的。像其他事物一样,软件也有趋势和时尚。我倾向于查看过去几年中与我情况相似的人的使用情况。在统计工具的普及竞赛中,Excel 显然会胜出。但是,如果我们只考虑数据科学家,也许只考虑特定领域的数据科学家——不包括会计师、金融专业人士和其他半统计用户——我们可能会看到它的受欢迎程度下降,转而青睐更严肃的统计工具。

对我来说,工具必须满足的标准是:

  • 该工具必须至少有几年的历史;
  • 该工具必须由声誉良好的组织维护;
  • 论坛、博客和文献必须表明许多人已经使用这个工具很长时间了,而且最近没有太多重大问题。

请战好

除了被普遍使用之外,统计软件工具应该包括全面和有用的文档。当我试图使用一个软件时,我有一个应该有直接答案的问题,但我在任何地方都找不到答案,这很令人沮丧。

如果您找不到一些大问题的答案,例如如何配置进行线性回归的输入,或者如何格式化机器学习的特征,这是一个不好的迹象。如果大问题的答案不在文档中,那么就更难找到你不可避免会遇到的特定问题的答案。

文档通常是软件的年龄和流行程度的函数。该工具的官方文档应该放在维护组织的网页上,并且应该包含简单易懂的信息说明和规范。有趣的是,许多软件组织在他们的文档中不使用简单的语言,或者使他们的例子过于复杂。也许这是我对不必要的术语的厌恶,但是我避免使用我不容易理解其文档的软件。

> summary(linearModel)Call:
lm(formula = y ~ X1 + X2, data = data)Residuals:
       1        2        3        4
-0.02115  0.02384  0.01500 -0.01769Coefficients:
            Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.001542   0.048723  20.556  0.03095 *
X1          1.999614   0.017675 113.134  0.00563 **
X2          0.002307   0.013361   0.173  0.89114
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1Residual standard error: 0.03942 on 1 degrees of freedom
Multiple R-squared:  0.9999, Adjusted R-squared:  0.9998
F-statistic:  6436 on 2 and 1 DF,  p-value: 0.008813

Text 2:汇总的打印输出(linearModel)。

就像确定一个工具是否足够常用一样,我还会查看论坛和博客帖子,以确定是否有足够的示例和问题以及支持官方文档的答案。无论文档有多好,都有可能存在漏洞和歧义,有非正式文档作为备份是很有帮助的。

特制好的

一些软件工具或软件包是为特定目的而构建的,其他功能是后来添加的。例如,MATLAB 和 R 中的矩阵代数例程是构建这些语言时主要关心的问题,可以肯定地认为它们是全面而健壮的。相比之下,在 Python 和 Java 的最初版本中,矩阵代数并不是主要关注的问题,这些功能是后来以包和库的形式添加的。这不一定是坏事;Python 和 Java 现在都有健壮的矩阵功能,但是并不是每一种声称能够有效处理矩阵的语言都有这样的功能。

如果我想要的统计方法是一个包、库或软件工具的附件,那么我会像审查工具本身一样审查这个包:它是灵活的、信息丰富的、通用的、文档完善的,还是健壮的?

互通性好

互操作性是专门构建的一种逆过程,但它们并不相互排斥。一些软件工具与其他工具配合得很好,在这些工具中,您可以期望能够以普遍接受的格式集成功能、导入数据和导出结果。这当然有助于使用其他软件完成相关任务的项目。

如果您正在使用数据库,使用与数据库直接交互的工具会很有帮助。如果您打算基于您的结果构建一个 web 应用程序,请选择一个支持 web 框架的工具,或者至少选择一个能够以 JSON 或其他 web 友好格式导出数据的工具。或者,如果您的统计工具将在各种类型的计算机上使用,请确保该软件能够在各种操作系统上运行。将统计软件方法集成到完全不同的语言或工具中并不罕见。如果是这种情况,最好检查一下,例如,是否可以从 Java 调用 Python 函数(只要稍加努力,就可以)。

r 是专门为统计而构建的,互操作性在某种程度上是事后才想到的,尽管有一个庞大的软件包生态系统支持与其他软件的集成。Python 是作为一种通用编程语言而构建的,统计是后来才想到的,但是正如我所说的,Python 的统计包是最好的。在它们和其他软件之间进行选择是一个审查你打算使用的所有语言、应用程序和软件包的问题。

许可许可良好

大多数软件都有一个许可证,无论是明示的还是暗示的,说明了软件的使用存在哪些限制或许可。专有软件许可通常是显而易见的,但开源许可通常不那么清晰。

如果您将商业软件用于商业目的,这没问题,但是用“学术”或“学生”许可证做同样的事情可能会有法律风险。在没有确认许可不禁止的情况下,向他人出售商业软件,无论修改与否,也是很危险的。

当我使用开源工具进行数据科学研究时,我的主要问题是,我是否可以使用该工具创建软件,并在不泄露源代码的情况下将其出售给某人?有些开源许可允许这样做,有些不允许。我的理解是(尽管我不是律师),我不能在不提供源代码的情况下出售我用 R 编写的应用程序;在 Python 和 Java 中,这通常是允许的,这也是为什么生产应用程序通常不用 R 和其他语言构建,并有类似许可的一个原因。当然,通常有合法的途径解决这个问题,比如自己托管 R 代码,并以 web 服务或类似方式提供其功能。无论如何,如果你怀疑你可能违反了软件许可,最好检查许可并咨询法律专家。

import statsmodels.regression.linear_model as lmX = [ [ 1.01,  0.0, 1 ],
      [ 1.99, -2.0, 1 ],
      [ 2.99,  2.0, 1 ],
      [ 4.01, -1.0, 1 ] ]
y = [ 3.0, 5.0, 7.0, 9.0 ]linearModel = lm.OLS(y,X)
results = linearModel.fit()
results.summary()results.predict(X)

文本 3:线性回归的 Python 代码。

知识和熟悉度都不错

我把这条一般规则放在最后,尽管我怀疑大多数人,包括我自己,会首先考虑它。我承认:我倾向于使用我所知道的。使用你最熟悉的工具可能没什么问题,如果它在前面的规则中表现得相当好的话。例如,Python 和 R 在数据科学的几乎所有方面都很擅长,如果你知道其中一个比另一个好,就用那个。

另一方面,有许多工具并不适合这项工作。例如,尝试使用 Excel 进行机器学习通常不是最好的主意,尽管我听说随着微软扩大其产品,这种情况正在改变。在这种情况下,你可能能够使用你知道的工具,值得考虑学习一种更适合你的项目的工具。

最后,这是一个平衡的问题:使用你熟悉的工具可以节省时间,而使用不合适的工具会损失时间和质量。项目的时间限制和要求通常是决定性因素。

要了解更多信息,请下载免费的第一章 像数据科学家一样思考 并查看此 幻灯片演示文稿 了解更多信息和折扣代码。

Brian Godsey 博士是一名数学家、企业家、投资者和数据科学家,他的著作 像数据科学家一样思考 现已有印刷版和电子书。——briangodsey.com

如果您喜欢,请点击💚下面。

[## (我喜欢你)叫我大数据

恶名昭彰的 IDE 人群的滑稽嘻哈联合

medium.com](https://medium.com/@briangodsey/i-love-it-when-you-call-me-big-data-2e4b89e84740) [## 检查您对数据的假设

没有人喜欢糟糕的假设

medium.com](https://medium.com/towards-data-science/check-your-assumptions-about-your-data-20be250c143)

如何对您的客户数据进行聚类——使用 R 代码示例

原文:https://towardsdatascience.com/how-to-cluster-your-customer-data-with-r-code-examples-6c7e4aa6c5b1?source=collection_archive---------2-----------------------

聚类客户数据通过为你分组相似的东西,帮助你发现数据中隐藏的模式。例如,您可以根据活动创建客户角色,并为这些群体定制产品。

在另一篇文章中,我们讨论了如何利用你所了解的客户特征,通过手动标记客户群来建立人物角色。另一种方法是让计算机创建人物角色集群。这被称为无监督分类,因为您让计算机决定如何使用您的数据的值和特征。

无监督分类的另一个名称是“聚类”。有许多不同的聚类技术,根据它们解决问题的方法来区分。最常见的区别之一是由算法确定的聚类是否可以嵌套。嵌套的聚类算法被称为“分层的”,而非嵌套的被称为“分区的”。

在这里,我们将深入研究每种算法的示例,并在实践中观察它:

离群值 监控您的业务数据,并在发生意外变化时通知您。我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。 注册每日数据驱动 获取工作中更多数据驱动的每日提示。

  • Outlier 是 Strata+Hadoop World 2017 观众奖得主。

也许从 k-means 聚类算法开始的最好地方是分解它的名字,因为它有助于理解算法在做什么。让我们从头开始;“k”是指该算法将创建的聚类数。因此,尽管该算法在如何创建聚类方面是无人监督的,但它确实将您想要创建的聚类的数量(k)作为输入。k-means 中的术语“均值”指的是如何将每个数据点加入到一个聚类中,即将每个数据点分配到具有最接近均值的聚类中。综上所述,k-means 聚类为您提供了“k”个数据点聚类,其中每个数据点都被分配到其最接近的聚类中。

该算法首先选择“k”个点作为初始中心值(通常称为质心)[1]。接下来,数据中的每个点都被分配到它最接近的中心值。现在每个点都被分配了一个聚类,但是我们需要检查中心值的初始猜测是否是最好的(不太可能!).检查的方法是计算每个聚类的新中心值-如果所有重新计算的中心值都与原始值相同,则您处于最佳解,算法可以停止。否则,该算法通过将点重新分配给新计算的中心值来再次尝试。这将持续到重新计算的中心值不变。

k-means 聚类为您提供了“k”个数据点聚类,其中每个数据点都被分配到与其最接近的聚类中。

该算法的结果是“k”个聚类,其中您拥有的每个数据点都被唯一地分配给一个且仅一个聚类。这就是为什么这种算法被称为“分区”或“非嵌套”算法——每个点只在一个簇中。

以上都是理论——接下来,让我们看看实践中的 k-means。

实际上,k-均值聚类

昨天,我谈到了 k-means 理论,但让我们将它付诸实践,使用一些样本客户销售数据为我们之前谈到的理论上的在线表格公司构建。假设我们收集了关于最近销售的数据,我们试图将这些数据分组为客户角色:年龄(年)、平均餐桌尺寸购买量(平方英寸)、每年购买的数量以及每次购买的金额(美元)。绘制数据,我们看到我们的客户可能有一些有趣的分组。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

An example exploratory grouping using purchase attributes vs. purchase frequency

在这种情况下,看起来最年轻和最年长的顾客通常购买较小、较便宜的桌子,购买量低于中年顾客购买较大型号的数量,有时购买量更大。

现在,让我们针对 k、2、3 和 4 的几个不同值对这些数据运行 k-means 算法,看看该算法会产生什么结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

An example running k-means with several different k values

在所有情况下,2160 cm 餐桌的购买者都属于自己的顾客群,但其他顾客则根据各自的特点更加混杂。当 k 等于 2 时,集群看起来是合理的,但是对于购买较小表的客户来说,可能有更多的粒度可以区分。当 k 等于 3 和 4 时,这些客户被分成更小的部分。

那么,选择什么样的 k 数比较合适呢?没有很好的算法方法来回答这个问题,但通常的做法是对不同的 k 值运行 k-means 算法,并测量通过添加更多的聚类而减少的误差量[2]——权衡的结果是,随着添加更多的聚类,你减少了误差,但随着添加更多的聚类,你有过度拟合数据的风险(在极端情况下,最终每个数据点都有自己的聚类!).

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在我们的例子中,k 等于 2 和 3 之间的误差大幅下降,因此我们应该非常有信心至少有 3 个集群。在 3 和 4 个簇之间有另一个下降,但是比第一个下降小得多。随后的下降似乎没有太大的改善,所以在这种情况下,我会考虑创建 3 或 4 个客户角色。

如果你有兴趣看我用来运行 k-means 算法和创建这些图的 R 代码,一切都可以在我们的数据驱动每日 GitHub 页面上找到。

接下来,我们将回到理论,讨论一种不同类型的聚类算法,凝聚层次聚类。

理论上,凝聚层次聚类

我们刚刚在讨论一种分割聚类算法,k-means。现在,我将谈论凝聚层次聚类算法。像 k-means 一样,让我们分解算法的名称,以便更好地了解它的作用。先说“层级”这个词。这是指聚类分析算法的总体类型,在这种情况下,这意味着该算法通过不断嵌套数据点来创建聚类。“凝聚”这个词描述了我们正在做的层次聚类的类型。层次聚类有两种基本方法,凝聚法和分裂法。更常见的方法是聚集聚类,这意味着该算法通过自下而上的构建来嵌套数据点。换句话说,每个数据点都是它自己的聚类,然后它们被连接在一起以创建更大的聚类。分裂聚类意味着该算法通过自顶向下构建来嵌套数据点。换句话说,所有的数据点都从一个簇开始,然后被分解成更小的簇。

该算法通过合并两个最接近的聚类并重复直到只剩下一个聚类来工作。凝聚层次聚类的结果是每个聚类如何在每一步中合并在一起的映射。

k-means 和凝聚层次聚类之间的最大差异是由于它们解决问题的核心方法。特别是,在 k-means 聚类中,随着算法在每次迭代中提高其中心值,数据点可以在聚类之间移动。凝聚层次聚类算法不允许撤消任何以前的合并。这两种算法之间的另一个区别是,使用 k-means 时,因为它对其初始中心值使用猜测,所以每次使用相同的 k 值运行该算法时,您都可以得到不同的答案。另一方面,凝聚层次聚类将始终产生相同的结果,因为数据点之间的距离不会改变。

接下来,我将向您展示一个凝聚层次聚类的实际例子!

实际上,凝聚层次聚类

现在我们已经了解了凝聚层次聚类,让我们使用我们用于 k-means 的相同数据来实践它:年龄(年)、平均表大小购买(平方英寸)、每年购买的次数和每次购买的金额(美元)。绘制层次聚类结果的最常见方法之一是通过树形图或树状图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Clustering customer data using adendogram (tree diagram)

左侧的值是指原始数据集的行号(底部的值是指距离[3]的测量值)。从左向右阅读时,您可以看到群集合并在一起以创建更大群集的顺序。将该算法与 k-means 聚类进行比较,我们发现结果是相似的。例如,树状图底部的值 19、22、21、20 和 27 被分组在一起,这些都是购买了 2160 cm 表的客户,这些表在 k-means 算法中被类似地分组。

将这种聚类算法的结果显示为树状图加强了这种算法和 k-means 之间的结构差异-每个数据点都嵌套在一起以创建更大的聚类,这与 k-means 不同,k-means 每次迭代都创建新的非重叠聚类。

如果你有兴趣看我用来运行凝聚层次聚类算法和创建这些图的 R 代码,一切都可以在我们的 数据驱动每日 GitHub 页面 上找到。

我希望这篇关于聚类算法的综述对您有所帮助。正如您所知,即使这些是无监督的分类技术,仍然需要一些人工监督和解释,例如,决定应该使用多少个聚类(以及许多其他决定,如如何初始化 k-means 或距离的度量,我鼓励您阅读更多信息)。虽然聚类算法通常不能用来告诉你“正确”的答案,只要按一下按钮,他们是一个伟大的方式来探索和理解您的数据!

离群值 **监控您的业务数据,并在发生意外变化时通知您。**我们帮助营销/发展&产品团队从他们的业务数据中获取更多价值。 今天安排试玩。

  • Outlier 是 Strata+Hadoop World 2017 观众奖得主。在下面的 39 秒中了解更多关于离群值的信息。

[1]k 均值的挑战之一是确定从哪里开始。有许多不同的算法可以单独解决这个问题,例如,选择一个随机的值子集并取这些值的平均值。计算 k-means 的计算机程序应该可以帮你做这个初始化。

[2]对于此处所示的数字数据,通常以每个点与其聚类中心值之间距离的平方误差之和来衡量。

[3]有许多方法可以测量两个集群之间的距离。例如,它可以是不同聚类中任意两点之间的最小距离,不同聚类中任意两点之间的最大距离,或者不同聚类中所有点对的平均距离。

如何在 Pytorch 中编写变压器代码

原文:https://towardsdatascience.com/how-to-code-the-transformer-in-pytorch-24db27c8f9ec?source=collection_archive---------1-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

变压器会不会是 RNNs 棺材上的另一颗钉子?

去掉了笨重的 for 循环,它找到了一种方法,允许整个句子同时成批地进入网络。奇迹;NLP 现在重新利用了 python 高效的线性代数库的优势。节省下来的时间可以用于在模型中部署更多的层。

到目前为止,结果似乎是更快的收敛和更好的结果。有什么不喜欢的?

我个人的经历非常有希望。它对 200 万个法语-英语句子对进行训练,仅用三天时间就能创造出一个复杂的翻译器。

如果你去我在 Github 这里的实现,你可以在语言翻译任务中自己玩这个模型。也请查看我的下一篇文章,在那里我将分享我构建翻译器的旅程和结果。

或者最后,你可以自己造一个。这是如何做的指南,以及它是如何工作的。

本指南仅解释如何对模型进行编码和运行,有关如何获取数据并为 seq2seq 处理数据的信息,请参见我的指南 此处

变形金刚

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上图显示了变压器模型的概况。编码器的输入将是英语句子,进入解码器的“输出”将是法语句子。

实际上,我们需要了解五个流程来实施这一模型:

把…嵌入

嵌入单词已经成为 NMT 的标准做法,给网络提供了比一个热门编码更多的单词信息。关于这方面的更多信息,请看我的帖子这里

pytorch 中的嵌入操作非常简单:

class Embedder(nn.Module):
    def __init__(self, vocab_size, d_model):
        super().__init__()
        self.embed = nn.Embedding(vocab_size, d_model)
    def forward(self, x):
        return self.embed(x)

当每个单词被输入到网络中时,这个代码将执行一个查找并检索它的嵌入向量。然后,这些向量将被模型学习为参数,并随着梯度下降的每次迭代进行调整。

给我们的话语语境:位置编码

为了让模型理解一个句子,它需要知道每个单词的两件事:这个单词是什么意思?它在句子中的位置是什么?

每个单词的嵌入向量将学习意思,所以现在我们需要输入一些东西来告诉网络这个单词的位置。

Vasmari 等人通过使用这些函数创建一个特定于位置的常量值来解决这个问题:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个常数是一个二维矩阵。 Pos 是指句子中的顺序, i 是指沿着嵌入向量维的位置。pos/i 矩阵中的每个值随后使用上述等式计算出来。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

The positional encoding matrix is a constant whose values are defined by the above equations. When added to the embedding matrix, each word embedding is altered in a way specific to its position.

位置编码器的直观编码方式如下:

class PositionalEncoder(nn.Module):
    def __init__(self, d_model, max_seq_len = 80):
        super().__init__()
        self.d_model = d_model

        # create constant 'pe' matrix with values dependant on 
        # pos and i
        pe = torch.zeros(max_seq_len, d_model)
        for pos in range(max_seq_len):
            for i in range(0, d_model, 2):
                pe[pos, i] = \
                math.sin(pos / (10000 ** ((2 * i)/d_model)))
                pe[pos, i + 1] = \
                math.cos(pos / (10000 ** ((2 * (i + 1))/d_model)))

        pe = pe.unsqueeze(0)
        self.register_buffer('pe', pe)

    def forward(self, x):
        # make embeddings relatively larger
        x = x * math.sqrt(self.d_model)
        #add constant to embedding
        seq_len = x.size(1)
        x = x + Variable(self.pe[:,:seq_len], \
        requires_grad=False).cuda()
        return x

上面的模块让我们将位置编码添加到嵌入向量中,为模型提供关于结构的信息。

我们在加法之前增加嵌入值的原因是为了使位置编码相对较小。这意味着当我们将它们加在一起时,嵌入向量中的原始含义不会丢失。

创造我们的面具

屏蔽在变压器中起着重要的作用。它有两个目的:

  • 在编码器和解码器中:只要输入句子中有填充,就把注意力输出归零。
  • 在解码器中:防止解码器在预测下一个单词时在翻译句子的剩余部分提前“到达峰值”。

为输入创建掩码很简单:

batch = next(iter(train_iter))
input_seq = batch.English.transpose(0,1)
input_pad = EN_TEXT.vocab.stoi['<pad>']# creates mask with 0s wherever there is padding in the input
input_msk = (input_seq != input_pad).unsqueeze(1)

对于 target_seq,我们做了同样的事情,但是创建了一个额外的步骤:

# create mask as beforetarget_seq = batch.French.transpose(0,1)
target_pad = FR_TEXT.vocab.stoi['<pad>']
target_msk = (target_seq != target_pad).unsqueeze(1)size = target_seq.size(1) # get seq_len for matrixnopeak_mask **=** np**.**triu(np**.**ones(1, size, size),
k**=**1)**.**astype('uint8')
nopeak_mask = Variable(torch**.**from_numpy(nopeak_mask) **==** 0)target_msk = target_msk & nopeak_mask

解码器的初始输入将是目标序列(法语翻译)。解码器预测每个输出单词的方式是利用所有编码器输出和法语句子,直到每个单词的预测点。

因此,我们需要防止第一个输出预测能够看到后面的句子。为此,我们使用 nopeak_mask:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

When the mask is applied in our attention function, each prediction will only be able to make use of the sentence up until the word it is predicting.

如果我们稍后将这个掩码应用于注意力分数,那么在计算输出时,输入前面的值将不能起作用。

多头注意力

一旦我们有了嵌入值(带位置编码)和掩码,我们就可以开始构建模型的层了。

以下是多头注意力层的概述:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Multi-headed attention layer, each input is split into multiple heads which allows the network to simultaneously attend to different subsections of each embedding.

v、K、Q 分别代表“键”、“值”和“查询”。这些是在注意力函数中使用的术语,但老实说,我不认为解释这些术语对理解模型特别重要。

在编码器的情况下, V,KG 将只是嵌入向量的相同副本(加上位置编码)。它们的尺寸为 Batch_size * seq_len * d_model。

在多头注意力中,我们将嵌入向量分成 N 个头,因此它们将具有尺寸 batch _ size * N * seq _ len *(d _ model/N)。

这个最后的维度(d_model / N)我们称之为 d_k。

让我们看看解码器模块的代码:

class MultiHeadAttention(nn.Module):
    def __init__(self, heads, d_model, dropout = 0.1):
        super().__init__()

        self.d_model = d_model
        self.d_k = d_model // heads
        self.h = heads

        self.q_linear = nn.Linear(d_model, d_model)
        self.v_linear = nn.Linear(d_model, d_model)
        self.k_linear = nn.Linear(d_model, d_model)
        self.dropout = nn.Dropout(dropout)
        self.out = nn.Linear(d_model, d_model)

    def forward(self, q, k, v, mask=None):

        bs = q.size(0)

        # perform linear operation and split into h heads

        k = self.k_linear(k).view(bs, -1, self.h, self.d_k)
        q = self.q_linear(q).view(bs, -1, self.h, self.d_k)
        v = self.v_linear(v).view(bs, -1, self.h, self.d_k)

        # transpose to get dimensions bs * h * sl * d_model

        k = k.transpose(1,2)
        q = q.transpose(1,2)
        v = v.transpose(1,2)# calculate attention using function we will define next
        scores = attention(q, k, v, self.d_k, mask, self.dropout)

        # concatenate heads and put through final linear layer
        concat = scores.transpose(1,2).contiguous()\
        .view(bs, -1, self.d_model)

        output = self.out(concat)

        return output

计算注意力

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Equation for calculating attention

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Diagram from paper illustrating equation steps

这是我们今天要考虑的唯一一个等式,这张来自论文的图表很好地解释了每一步。

图中的每个箭头反映了等式的一部分。

最初,我们必须将 Q 乘以 k 的转置,然后通过将输出除以 d_k 的平方根来“缩放”。

等式中没有显示的一个步骤是屏蔽操作。在执行 Softmax 之前,我们应用掩码,从而减少输入填充的值(或者在解码器中,输入在当前字之前的值)。

另一个未显示的步骤是 dropout,我们将在 Softmax 之后应用。

最后,最后一步是在目前为止的结果和 v 之间做点积。

下面是注意力功能的代码:

def attention(q, k, v, d_k, mask=None, dropout=None):

    scores = torch.matmul(q, k.transpose(-2, -1)) /  math.sqrt(d_k)if mask is not None:
        mask = mask.unsqueeze(1)
        scores = scores.masked_fill(mask == 0, -1e9)scores = F.softmax(scores, dim=-1)

    if dropout is not None:
        scores = dropout(scores)

    output = torch.matmul(scores, v)
    return output

前馈网络

好了,如果你已经理解了,给自己一个大大的鼓励,因为我们已经完成了最后一层,从这里开始一切都很简单了!

这一层仅由两个线性操作组成,其间有一个 relu 和 dropout 操作。

class FeedForward(nn.Module):
    def __init__(self, d_model, d_ff=2048, dropout = 0.1):
        super().__init__() 
        # We set d_ff as a default to 2048
        self.linear_1 = nn.Linear(d_model, d_ff)
        self.dropout = nn.Dropout(dropout)
        self.linear_2 = nn.Linear(d_ff, d_model)
    def forward(self, x):
        x = self.dropout(F.relu(self.linear_1(x)))
        x = self.linear_2(x)
        return x

前馈层只是深化我们的网络,使用线性层来分析注意力层输出的模式。

最后一件事:正常化

规范化在深度神经网络中非常重要。它可以防止层中值的范围变化太大,这意味着模型训练速度更快,泛化能力更强。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们将对编码器/解码器中各层之间的结果进行归一化,因此在构建模型之前,让我们定义该函数:

class Norm(nn.Module):
    def __init__(self, d_model, eps = 1e-6):
        super().__init__()

        self.size = d_model
        # create two learnable parameters to calibrate normalisation
        self.alpha = nn.Parameter(torch.ones(self.size))
        self.bias = nn.Parameter(torch.zeros(self.size))
        self.eps = eps
    def forward(self, x):
        norm = self.alpha * (x - x.mean(dim=-1, keepdim=True)) \
        / (x.std(dim=-1, keepdim=True) + self.eps) + self.bias
        return norm

把所有的东西放在一起!

如果你理解了上面的细节,你现在就理解了这个模型。剩下的就是简单地把所有东西放回原位。

让我们再看一看整体架构,然后开始建造:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**最后一个变量:**如果您仔细观察图表,您会发现编码器和解码器架构旁边有一个“Nx”。实际上,上图中的编码器和解码器代表编码器的一层和解码器的一层。n 是层数的变量。例如,如果 N=6,数据通过六个编码器层(具有上述架构),然后这些输出被传递到解码器,该解码器也由六个重复的解码器层组成。

我们现在将使用上面模型中所示的架构构建 EncoderLayer 和 DecoderLayer 模块。然后,当我们构建编码器和解码器时,我们可以定义有多少层。

# build an encoder layer with one multi-head attention layer and one # feed-forward layerclass EncoderLayer(nn.Module):
    def __init__(self, d_model, heads, dropout = 0.1):
        super().__init__()
        self.norm_1 = Norm(d_model)
        self.norm_2 = Norm(d_model)
        self.attn = MultiHeadAttention(heads, d_model)
        self.ff = FeedForward(d_model)
        self.dropout_1 = nn.Dropout(dropout)
        self.dropout_2 = nn.Dropout(dropout)

    def forward(self, x, mask):
        x2 = self.norm_1(x)
        x = x + self.dropout_1(self.attn(x2,x2,x2,mask))
        x2 = self.norm_2(x)
        x = x + self.dropout_2(self.ff(x2))
        return x

# build a decoder layer with two multi-head attention layers and
# one feed-forward layerclass DecoderLayer(nn.Module):
    def __init__(self, d_model, heads, dropout=0.1):
        super().__init__()
        self.norm_1 = Norm(d_model)
        self.norm_2 = Norm(d_model)
        self.norm_3 = Norm(d_model)

        self.dropout_1 = nn.Dropout(dropout)
        self.dropout_2 = nn.Dropout(dropout)
        self.dropout_3 = nn.Dropout(dropout)

        self.attn_1 = MultiHeadAttention(heads, d_model)
        self.attn_2 = MultiHeadAttention(heads, d_model)
        self.ff = FeedForward(d_model).cuda()def forward(self, x, e_outputs, src_mask, trg_mask):
        x2 = self.norm_1(x)
        x = x + self.dropout_1(self.attn_1(x2, x2, x2, trg_mask))
        x2 = self.norm_2(x)
        x = x + self.dropout_2(self.attn_2(x2, e_outputs, e_outputs,
        src_mask))
        x2 = self.norm_3(x)
        x = x + self.dropout_3(self.ff(x2))
        return x# We can then build a convenient cloning function that can generate multiple layers:def get_clones(module, N):
    return nn.ModuleList([copy.deepcopy(module) for i in range(N)])

我们现在准备构建编码器和解码器:

class Encoder(nn.Module):
    def __init__(self, vocab_size, d_model, N, heads):
        super().__init__()
        self.N = N
        self.embed = Embedder(vocab_size, d_model)
        self.pe = PositionalEncoder(d_model)
        self.layers = get_clones(EncoderLayer(d_model, heads), N)
        self.norm = Norm(d_model)
    def forward(self, src, mask):
        x = self.embed(src)
        x = self.pe(x)
        for i in range(N):
            x = self.layers[i](x, mask)
        return self.norm(x)

class Decoder(nn.Module):
    def __init__(self, vocab_size, d_model, N, heads):
        super().__init__()
        self.N = N
        self.embed = Embedder(vocab_size, d_model)
        self.pe = PositionalEncoder(d_model)
        self.layers = get_clones(DecoderLayer(d_model, heads), N)
        self.norm = Norm(d_model)
    def forward(self, trg, e_outputs, src_mask, trg_mask):
        x = self.embed(trg)
        x = self.pe(x)
        for i in range(self.N):
            x = self.layers[i](x, e_outputs, src_mask, trg_mask)
        return self.norm(x)

最后…变形金刚!

class Transformer(nn.Module):
    def __init__(self, src_vocab, trg_vocab, d_model, N, heads):
        super().__init__()
        self.encoder = Encoder(src_vocab, d_model, N, heads)
        self.decoder = Decoder(trg_vocab, d_model, N, heads)
        self.out = nn.Linear(d_model, trg_vocab)
    def forward(self, src, trg, src_mask, trg_mask):
        e_outputs = self.encoder(src, src_mask)
        d_output = self.decoder(trg, e_outputs, src_mask, trg_mask)
        output = self.out(d_output)
        return output# we don't perform softmax on the output as this will be handled 
# automatically by our loss function

训练模型

随着变压器的建立,剩下的就是在 EuroParl 数据集上训练这个傻瓜。编码部分相当容易,但是要准备好等待大约 2 天,这个模型才开始收敛!

让我们先定义一些参数:

d_model = 512
heads = 8
N = 6
src_vocab = len(EN_TEXT.vocab)
trg_vocab = len(FR_TEXT.vocab)model = Transformer(src_vocab, trg_vocab, d_model, N, heads)for p in model.parameters():
    if p.dim() > 1:
        nn.init.xavier_uniform_(p)# this code is very important! It initialises the parameters with a
# range of values that stops the signal fading or getting too big.
# See [this blog](http://andyljones.tumblr.com/post/110998971763/an-explanation-of-xavier-initialization) for a mathematical explanation.optim = torch.optim.Adam(model.parameters(), lr=0.0001, betas=(0.9, 0.98), eps=1e-9)

现在我们可以开始训练了:

def train_model(epochs, print_every=100):

    model.train()

    start = time.time()
    temp = start

    total_loss = 0

    for epoch in range(epochs):

        for i, batch in enumerate(train_iter): src = batch.English.transpose(0,1)
            trg = batch.French.transpose(0,1) # the French sentence we input has all words except
            # the last, as it is using each word to predict the next

            trg_input = trg[:, :-1]

            # the words we are trying to predict

            targets = trg[:, 1:].contiguous().view(-1)

            # create function to make masks using mask code above

            src_mask, trg_mask = create_masks(src, trg_input)

            preds = model(src, trg_input, src_mask, trg_mask)

            optim.zero_grad()

            loss = F.cross_entropy(preds.view(-1, preds.size(-1)),
            results, ignore_index=target_pad) loss.backward()
            optim.step()

            total_loss += loss.data[0]
            if (i + 1) % print_every == 0:
                loss_avg = total_loss / print_every
                print("time = %dm, epoch %d, iter = %d, loss = %.3f,
                %ds per %d iters" % ((time.time() - start) // 60,
                epoch + 1, i + 1, loss_avg, time.time() - temp,
                print_every))
                total_loss = 0
                temp = time.time()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Example training output: After a few days of training I seemed to converge around a loss of around 1.3

测试模型

我们可以使用下面的功能来翻译句子。我们可以直接从我们的批处理中输入句子,或者输入自定义字符串。

翻译器通过运行一个循环来工作。我们从对英语句子进行编码开始。然后,我们向解码器提供令牌索引和编码器输出。解码器对第一个字进行预测,我们用 sos 标记将其添加到解码器输入中。我们重新运行循环,获得下一个预测,并将其添加到解码器输入,直到我们到达标记,让我们知道它已经完成翻译。

def translate(model, src, max_len = 80, custom_string=False):

    model.eval()if custom_sentence == True:
        src = tokenize_en(src)
        sentence=\
        Variable(torch.LongTensor([[EN_TEXT.vocab.stoi[tok] for tok
        in sentence]])).cuda()src_mask = (src != input_pad).unsqueeze(-2)
    e_outputs = model.encoder(src, src_mask)

    outputs = torch.zeros(max_len).type_as(src.data)
    outputs[0] = torch.LongTensor([FR_TEXT.vocab.stoi['<sos>']])for i in range(1, max_len):    

        trg_mask = np.triu(np.ones((1, i, i),
        k=1).astype('uint8')
        trg_mask= Variable(torch.from_numpy(trg_mask) == 0).cuda()

        out = model.out(model.decoder(outputs[:i].unsqueeze(0),
        e_outputs, src_mask, trg_mask))
        out = F.softmax(out, dim=-1)
        val, ix = out[:, -1].data.topk(1)

        outputs[i] = ix[0][0]
        if ix[0][0] == FR_TEXT.vocab.stoi['<eos>']:
            breakreturn ' '.join(
    [FR_TEXT.vocab.itos[ix] for ix in outputs[:i]]
    )

仅此而已。看我的 Github 这里我已经写了这个代码作为一个程序,它将接受两个平行文本作为参数,并在它们上面训练这个模型。或者把知识实践出来,自己去实施!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值