TowardsDataScience 博客中文翻译 2019(七十九)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

带有 Tensorflow hub 的 Keras 中的 BERT

原文:https://towardsdatascience.com/bert-in-keras-with-tensorflow-hub-76bcbc9417b?source=collection_archive---------2-----------------------

Strong Analytics ,我们的许多项目都涉及使用深度学习进行自然语言处理。在最近的一个项目中,我们努力鼓励孩子们自由探索在线,同时确保他们免受网络欺凌和在线虐待,而另一个项目涉及预测日历和电子邮件活动的可扣除费用。

任何 NLP 项目的一个关键组成部分是使用技术快速测试和迭代的能力。Keras 提供了一种非常快速的方法来原型化最先进的深度学习模型,因此是我们在工作中使用的重要工具。

之前的一篇文章中,我们展示了如何集成 ELMo 嵌入作为定制的 Keras 层,以简化使用 Tensorflow hub 的模型原型。 BERT ,谷歌推出的语言模型,使用变形金刚和预训练来实现许多语言任务的最先进水平。它最近被添加到 Tensorflow hub 中,简化了 Keras 模型中的集成。

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

Deeply bidirectional unsupervised language representations with BERT

让我们开始建造吧!首先,我们加载之前使用的相同 IMDB 数据:

接下来,我们使用 tf-hub 模型对数据进行标记,这简化了预处理:

接下来,我们使用 Keras 构建一个自定义层,集成 tf-hub 的 BERT。模型很大(110,302,011 参数!!!)所以我们微调层的子集。

现在,我们可以使用 BERT 层轻松构建和训练我们的模型:

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

Using a GPU for large models like BERT is advised!

相当简单!在 Github 上查看完整的笔记本,并创建很酷的东西!

想和芝加哥的顶级数据科学家团队一起从事各种行业中具有挑战性的 NLP、机器学习和 AI 工作?我们正在招聘有才华的数据科学家和工程师!

strong.io 了解更多信息,并在 careers.strong.io 申请

伯特不擅长 ____。

原文:https://towardsdatascience.com/bert-is-not-good-at-7b1ca64818c5?source=collection_archive---------20-----------------------

查看 BERT 语言模型的一些缺点

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

CC

如果你对 NLP 感兴趣,我毫不怀疑你已经广泛阅读了关于 BERT 的内容。谷歌的一组研究人员于去年年底首次推出了这种新的语言模型,看到这种新语言模型的性能并思考其潜力,这是非常了不起的。它已经为一些语言任务设定了新的标准,并且在 Medium 上不缺少教程,这些教程提供了许多可以用 BERT 完成的语言建模项目的见解。对于这个领域来说,这是令人着迷的一年,至少可以说有了这样的发展。

在所有的赞扬中,我一直对伯特可能没有击中要害的地方感兴趣。Allyson Ettinger 有一篇有趣的论文叫做“伯特不是什么:来自一套新的语言模型心理语言学诊断的教训”测试了一些语言失误。我强烈推荐阅读整篇论文,因为她对自己的过程和结果有一些非常好的解释,但这里只是提到了 BERT 不足之处的一些见解:

常识与语用推理

他抱怨说,在她吻了他之后,他无法去掉脸上的红色。他最后只是要求她不要再穿那件 ____。

阅读上面的句子,你可能很容易推断出缺少的单词是“口红”。你可能没有意识到你正在做的是“口红”这个词之前没有被提及,你只是从之前的句子中推断出它,而没有直接提及它是如何使用的。有一个读者可以理解的语用推理。

在她的研究中,Ettinger 发现 BERT 在这样的测试中可以做得很好,但是很少成功。伯特能够更喜欢好的完成(“口红”)而不是差的完成(“睫毛膏”),但没有压倒性的信心。她发现,研究结果表明,它对常识性场景中的答案不像人那样敏感。它未能在很大程度上把握前一句话提供的上下文。

否认

柯基犬不是 _____。

因此,如果你问“柯基犬是 ____”,你可能会有一百万个选项,比如“一只狗”或“一只宠物”,但它不是什么?你肯定可以想出一个答案(“一只猫”、“一把椅子”),但是当你这样做的时候,你可以看到这些是如何需要一点独特的创造力,什么是最合适的取决于你所谈论的更大的背景。

艾丁格发现,尽管伯特非常擅长正面(“是”),但肯定会与负面(“不是”)作斗争。它能够将名词与相近的直接描述词联系起来,但不能处理肯定或否定的措辞。这是论文中的一个例子:

知更鸟是一种 ____

伯特大预言:鸟、知更鸟、人、猎人、鸽子

知更鸟不是 ____

伯特大型预测:鸟,知更鸟,人,猎人,鸽子

你看到的不是 double,它预测了两个相同的名词!虽然表现出很强的联想能力,但它显然没有处理否定。这是一个看起来很简单的概念对 BERT 来说并不简单的领域。

还有一个问题没有在这里详细说明,我不会破坏伯特在句子中角色互换的斗争,所以如果你觉得这些见解有趣,一定要深入研究这篇论文。

BERT、RoBERTa、DistilBERT 和 XLNet——使用哪一个?

原文:https://towardsdatascience.com/bert-roberta-distilbert-xlnet-which-one-to-use-3d5ab82ba5f8?source=collection_archive---------1-----------------------

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

image source (https://www.maxpixel.net)

oogle 的 BERT 和最近基于 transformer 的方法席卷了 NLP 领域,在几个任务上超过了最先进的技术。最近,人们展示了相对于 BERT 的各种改进——在这里,我将对比主要的相似之处和不同之处,以便您可以选择在您的研究或应用中使用哪一种。

BERT 是一个双向转换器,用于对大量未标记的文本数据进行预训练,以学习一种语言表示,可用于微调特定的机器学习任务。虽然 BERT 在几个具有挑战性的任务上超过了 NLP 最先进的技术,但其性能的提高可以归功于双向转换器、掩蔽语言模型的新颖预训练任务和 Next 结构预测,以及大量数据和谷歌的计算能力。如果你还不熟悉 BERT 的基本技术,我推荐你快速阅读这篇 3 分钟的博文。

最近,出现了几种方法来改善 BERT 的预测指标或计算速度,但不能同时改善两者。

XLNet 和 RoBERTa 提高了性能,而 DistilBERT 提高了推理速度。下表对它们进行了比较!

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

Comparison of BERT and recent improvements over it

**使用更大的小批量、学习率和步长进行更长时间的训练,并在掩蔽程序上有所不同。

***原始出版物中给出的数字,除非另有说明。

XLNet 是一个大型双向转换器,它使用改进的训练方法、更大的数据和更强的计算能力,在 20 个语言任务上实现了优于 BERT 的预测指标。

为了改进训练,XLNet 引入了置换语言建模,其中所有的记号都被预测,但顺序是随机的。这与 BERT 的屏蔽语言模型相反,在该模型中,仅预测屏蔽的(15%)标记。这也与传统的语言模型形成对比,在传统的语言模型中,所有的标记都是以连续顺序而不是随机顺序预测的。这有助于模型学习双向关系,从而更好地处理单词之间的依赖性和关系。此外,Transformer XL 被用作基础架构,即使在没有基于排列的训练的情况下,它也表现出良好的性能。

XLNet 使用超过 130 GB 的文本数据和运行 2.5 天的 512 个 TPU 芯片进行训练,这两个数据都比 BERT 大得多。

罗伯塔 。【RoBERTa 是脸书大学推出的经过稳健优化的 BERT 方法,它是对 BERT 的再培训,具有改进的培训方法、1000%以上的数据和计算能力。

为了改进训练过程,RoBERTa 从 BERT 的预训练中移除了下一句预测(NSP)任务,并引入了动态屏蔽,使得屏蔽的令牌在训练时期期间改变。还发现较大的批量训练规模在训练过程中更有用。

重要的是,RoBERTa 使用 160 GB 的文本进行预训练,包括 16GB 的书籍语料库和 BERT 中使用的英语维基百科。附加数据包括 CommonCrawl 新闻数据集(6300 万篇文章,76 GB)、网络文本语料库(38 GB)和来自 CommonCrawl 的故事(31 GB)。这加上庞大的 1024 V100 特斯拉 GPU 的运行一天,导致罗伯塔的预训练。

因此,RoBERTa 在 GLUE 基准测试结果上优于 BERT 和 XLNet:

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

Performance comparison from RoBERTa.

另一方面,为了减少 BERT 或相关模型的计算(训练、预测)次数,自然的选择是使用较小的网络来逼近性能。有许多方法可以用来做到这一点,包括修剪、提取和量化,然而,所有这些都会导致较低的预测度量。

DistilBERT 学习了一个经过提炼的(近似)版本的 BERT,保留了 97%的性能但只使用了一半数量的参数( paper )。具体来说,它没有令牌类型的嵌入,pooler,并且只保留了 Google 的 BERT 的一半层。DistilBERT 使用一种称为蒸馏的技术,这种技术近似于谷歌的 BERT,即一个较小的神经网络代替一个较大的神经网络。这个想法是,一旦一个大的神经网络被训练,它的全部输出分布可以用一个较小的网络来近似。这在某种意义上类似于后验近似。贝叶斯统计中用于后验近似的一个关键优化函数是 Kulback Leiber 散度,自然也在这里使用。

:在贝叶斯统计中,我们是在逼近真实的后验概率(来自数据),而使用蒸馏,我们只是在逼近由更大的网络学习到的后验概率。

那么用哪一个呢?

如果你真的需要一个更快的推理速度,但可以在预测指标上妥协几个百分点,DistilBERT 是一个合理的选择,但是,如果你正在寻找最好的预测指标,你最好使用脸书的 RoBERTa。

从理论上讲,XLNet 的基于排列的训练应该能够很好地处理依赖性,并且从长远来看可能会工作得更好。

然而,Google 的 BERT 确实提供了一个很好的工作基准,如果你没有上述任何关键需求,你可以用 BERT 保持你的系统运行。

结论

大部分性能提升(包括 BERT 本身!)是由于增加的数据、计算能力或训练过程。虽然它们有自己的价值,但它们往往在计算和预测指标之间进行权衡。需要在使用更少数据和计算资源的同时提高性能的根本性改进。

更新

讨论 2020 年和 2021 年最新方法的博客第二部分可以在找到

作者在@SuleimanAliKhan 发推文。—我们正在招聘—

伯特:应用商店评论的情感分析

原文:https://towardsdatascience.com/bert-sentiment-analysis-of-app-store-review-db68f7721d94?source=collection_archive---------16-----------------------

利用最先进的模型分析应用商店的用户情绪

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

Photo by William Hook on Unsplash

本文为您提供了对 app store 公众用户的评论进行情感分析的必要步骤。在本教程中,我将使用基于中文的模型来测试 Bert 应用于英语以外的语言时的性能。无论您使用哪种模型,情感分析的步骤都是一样的。如果您不确定使用哪种模型,请查看下面的链接,了解有关 BERT 团队提供的预训练模型的更多信息。如果你是 BERT 的新手,请查看我之前关于使用 BERT 的多分类任务的教程。本教程有 5 个部分:

  1. 数据集准备
  2. 培养
  3. 预言;预测;预告
  4. 结果
  5. 结论

1.数据集准备

我将使用来自 Taptap 的评论,这是一个迎合中国市场的游戏应用商店。请随意使用您自己的数据集。你甚至可以在谷歌 Play 商店和苹果商店的评论上测试一下。如果是这种情况,请确保您对 BERT 使用的是英语模型。让我们来看看我们可以从 Taptap 的评论中获得的细节。

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

Image by Author. Taken from a review in Taptap.

这里有相当多有用的数据:

  • 用户发布的评论
  • 评分从 1 到 5
  • 竖起大拇指
  • 数数拇指朝下
  • 其他用户对此评论的回复

我们可以很容易地使用可用的数据来标记情感。如果你有时间的话,强烈建议你手工贴标签。在这种情况下,我将使用评级来确定标签。

  1. 负:1-3⭐
  2. 中立:4 名⭐
  3. 阳性:5 ⭐

我设法从几个游戏的用户评论中收集了相当多的数据集。我已经将数据集加载到三个数据帧中。

  1. 训练数据集
  2. 评估数据集
  3. 测试数据集

让我们看看训练评估的数据内容。两者结构相同。

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

Image by Author

  • Guid :注释的 id。
  • 标签:评论的情绪。标签是基于用户的评价。
  • Alpha :一次性栏。我刚填了一个。
  • 文本:用户的实际评论。

如果您在创建上面的数据帧时遇到问题,请随意使用下面的代码(相应地修改):

df_bert = pd.DataFrame({'guid': id_list,
    'label': label_list,
    'alpha': ['a']*len(count),
    'text': text_list})

测试数据会略有不同,因为它应该只包含 guid文本

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

Image by Author

完成后,让我们使用以下代码将其保存为 tsv 文件(相应地修改数据帧的名称):

df_bert_train.to_csv('data/train.tsv', sep='\t', index=False, header=False)
df_bert_dev.to_csv('data/dev.tsv', sep='\t', index=False, header=False)
df_bert_test.to_csv('data/test.tsv', sep='\t', index=False, header=True)

请注意,文件存储在数据文件夹中。您可以根据自己的使用情况随意修改,但文件名必须如下所示:

  • train.tsv
  • 开发 tsv
  • test.tsv

此外, test.tsv 数据必须有一个不同于 train.tsvdev.tsv 的头。将 test.tsv 的割台设置为 True

完成数据准备后,让我们进入下一部分。

2.培养

我们现在将开始训练和微调模型。确保您已经从官方站点中克隆了存储库。此外,您应该将以下文件和文件夹放在存储库中的某个位置:

  • 数据目录:存放 train.tsv、dev.tsv、test.tsv 的目录
  • Vocab 文件:Vocab . txt 文件。它与您下载的模型一起提供。我创建了一个新的模型文件夹,并将文件放入其中。
  • 配置文件:Config . JSON 文件。它也包含在模型中。同样,我把它放在模型文件夹中。
  • 初始模型:用于训练的模型。您可以使用基于预先训练的模型,或者从您已经微调的现有模型中恢复。我将它存储在型号文件夹中
  • 输出目录:模型将要写入的文件夹。您可以简单地为它创建一个空文件夹。

下一步是确定以下变量:

  • 最大序列长度:分词后最大总输入序列长度。长于此长度的序列将被截断,短于此长度的序列将被填充。默认值是 128,但在本教程中我将使用 256。
  • 训练批量:训练的总批量。默认值为 32。我将在本教程中使用 8,因为我只在一个 GeForce RTX 2080 上训练。
  • 学习率:Adam 的初始学习率。默认为 5e-5。我已经将值设置为 2e-5。
  • Num train epoch :要执行的训练总次数。我将只使用默认值 3.0

如果您不确定使用哪种 GPU,请运行以下命令找出答案:

nvidia-smi

我们需要修改 run_classifier.py 中的代码,因为这个用例有 3 个类。打开 python 文件,在**cola processor(data processor)**类中搜索 get_labels ()函数。将其更改为以下内容并保存:

def get_labels(self):
    """See base class."""
    return ["0", "1", "2"]

完成后,激活虚拟环境,并将目录更改为存储库的根目录。在终端中键入以下命令。

CUDA_VISIBLE_DEVICES=0 python run_classifier.py --task_name=cola --do_train=true --do_eval=true --data_dir=./data/ --vocab_file=./model/vocab.txt --bert_config_file=./model/bert_config.json --init_checkpoint=./model/bert_model.ckpt --max_seq_length=256 --train_batch_size=8 --learning_rate=2e-5 --num_train_epochs=3.0 --output_dir=./output/ --do_lower_case=False

运行它,您应该会看到以下输出:

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

Image by Author

它可能需要相当长的时间来训练,这取决于你使用的数据集的大小。一旦训练完成,终端将输出以下内容。

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

让我们进入下一步。

3.预言;预测;预告

将在输出文件夹中生成一个模型。请检查最高步骤数,以确定您拥有的最新型号。如果您不确定哪个型号是最新的,请打开检查点文件找出答案。在我的例子中,我将 37125 作为模型的最后一步。

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

Image by Author

在同一个终端中,运行以下代码(确保最大序列长度与您在培训中使用的长度相同):

CUDA_VISIBLE_DEVICES=0 python run_classifier.py --task_name=cola --do_predict=true --data_dir=./data/ --vocab_file=./model/vocab.txt --bert_config_file=./model/bert_config.json --init_checkpoint=./output/model.ckpt-37125 --max_seq_length=256 --output_dir=./output/

代码将在输出文件夹中生成一个 test_results.tsv 文件。在我的例子中,我得到了以下结果。

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

Image by Author

每列代表预测类别的概率或置信水平,最高的是模型预测的类别。

4.结果

是我们分析结果的时候了。第一个任务是加载 test_results.tsv,并根据最高预测概率将其转换为 dataframe。使用以下代码读取文件:

df_result = pd.read_csv('output/test_results.tsv', sep='\t', header=None)
df_result.head()

您应该有一个包含三列的测试数据的数据框架(我将其命名为 df_test_with_label):

  • 全局唯一标识符
  • 标签
  • 文本

创建一个新的数据帧,并使用 idxmax 映射结果。

df_predict = pd.DataFrame({'guid':df_test_with_label['guid'],
                            'label':df_result.idxmax(axis=1),
                            'text':df_test_with_label['text'],})
df_predict.head()

导入

完成后,让我们从 sklearn 导入以下度量函数来计算我们的模型的性能。

from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix

准确(性)

你可以如下计算模型的精确度。

accuracy_score(df_test_with_label['label'], df_predict['label'])

结果得到 0.7033952594490711。

回忆

基于 sklearn 文档。召回率是比率tp / (tp + fn),其中tp是真阳性的数量,fn是假阴性的数量。召回直观上是分类器找到所有肯定样本的能力。最佳值为 1,最差值为 0。它还需要一个名为 average 的参数。我正在将它设置为

recall_score(df_test_with_label['label'], df_predict['label'], average='macro')

运行代码的结果是输出 0.6312777479889565。

精确

精度是比率tp / (tp + fp),其中tp是真阳性的数量,fp是假阳性的数量。精确度直观上是分类器不将阴性样品标记为阳性的能力。最佳值为 1,最差值为 0。同样,平均参数被设置为

precision_score(df_test_with_label['label'], df_predict['label'], average='macro')

精度比 recall 低一点,只有 0.6375505256。

混淆矩阵

仅仅有回忆和精确是不够好的,因为我们不知道哪个类有最好的预测,哪个类得到最差的结果。我们可以使用混淆矩阵方法来为我们提供这方面的更多见解。

confusion_matrix(df_test_with_label['label'], df_predict['label'])

我得到了以下输出。

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

Image by Author

我们可以看到,该模型在预测第二个标签(中性)时有一些困难。在这种情况下,我们可能需要对数据集进行一些修改,并再次尝试重新训练它。

5.结论

祝贺您完成本教程。让我们回顾一下今天所学的内容。

首先,我们开始为我们的情感分析项目准备数据集。这包括获取数据并根据提供的详细信息自动标记数据。在我们的例子中,我们使用应用评论等级作为情感的标签。我们把它定为三类,即消极、中立和积极。我们从数据集生成了三个 tsv 文件。

接下来,我们配置了所需的参数,如最大序列长度和批量大小。我们训练该模型,并使用它对测试数据进行预测。

最后,我们将结果加载到一个数据框架中,并使用 sklearn 的度量函数对其进行分析。所提供的见解允许我们确定模型的性能。

感谢阅读,希望你喜欢这篇教程。下一篇文章再见。祝你有美好的一天!❤️

参考

  1. https://towards data science . com/beginners-guide-to-Bert-for-multi-class ification-task-92f 5445 c2d 7 c
  2. https://github.com/google-research/bert
  3. https://sci kit-learn . org/stable/modules/classes . html # module-sk learn . metrics
  4. https://www.taptap.com/

3 分钟内介绍 BERT 技术

原文:https://towardsdatascience.com/bert-technology-introduced-in-3-minutes-2c2f9968268c?source=collection_archive---------3-----------------------

oogle BERT 是一种用于自然语言理解的预训练方法,它比以往任何时候都更好地执行各种 NLP 任务。

BERT 分两步工作,首先,它使用大量未标记数据,以无监督的方式学习一种语言表示,称为预训练。然后,预训练模型可以以监督的方式微调,使用少量标记的训练数据来执行各种监督任务。预训练机器学习模型已经在包括图像处理和自然语言处理(NLP)在内的各个领域取得了成功。

BERT 代表 B 方向En 编码器 R 代表 T 变压器。它基于 transformer 架构(Google 在 2017 发布)。通用转换器使用编码器和解码器网络,然而,由于 BERT 是预训练模型,它仅使用编码器来学习输入文本的潜在表示。

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

Photo by Franki Chamaki on Unsplash

技术

BERT 将多个变压器编码器堆叠在一起。transformer 基于著名的多头注意力模块,该模块在视觉和语言任务方面都取得了巨大的成功。有关注意力的回顾,请参见

伯特的艺术表演基于两点。首先,称为掩蔽语言模型(MLM)下一个句子预测(NSP) 的新颖的预训练任务。第二,大量的数据和计算能力来训练 BERT。

MLM 使得从文本中执行双向学习成为可能,即它允许模型从出现在之前和之后的单词中学习每个单词的上下文。这在以前是不可能的!之前最先进的方法叫做生成式预训练使用的是从左到右训练 ELMo 使用的是浅层双向训练。

MLM 预训练任务将文本转换成记号,并将记号表示用作训练的输入和输出。标记的随机子集(15%)在训练期间被屏蔽,即隐藏,并且目标函数是预测标记的正确身份。这与使用单向预测作为目标或者使用从左到右和从右到左训练来近似双向的传统训练方法形成对比。NSP 任务允许伯特通过预测一对句子中的下一句是否是正确的来学习句子之间的关系。为此,用 50%的随机对补充 50%的正确对,并训练模型。伯特同时训练 MLM 和 NSP 目标。

数据和 TPU/GPU 运行时

伯特使用了总共 33 亿个单词进行训练,其中 25 亿个来自维基百科,0.8 亿个来自图书语料库。训练是使用 TPU 完成的,而 GPU 的估计如下所示。

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

Training devices and times for BERT; used TPU and estimated for GPU.

使用 2.5K 至 392K 标记的样品进行微调。重要的是,超过 100K 训练样本的数据集在各种超参数上表现出稳健的性能。每个微调实验在单个云 TPU 上运行 1 小时以内,在 GPU 上运行几个小时。

结果

BERT 大大超过了 11 个最先进的 NLP 任务。这些任务分为三个主要类别,文本分类、文本蕴涵和 Q/A。在两个任务 SQUAD 和 SWAG 中,BERT 第一个超越了人类水平的表现!

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

BERT results from the paperhttps://arxiv.org/abs/1810.04805

在你的分析中使用伯特

BERT 可作为开源软件获得:【https://github.com/google-research/bert】T2,并针对 104 种语言进行了预训练,在 TensorFlow 和 Pytorch 中实现。

它可以针对几种类型的任务进行微调,如文本分类、文本相似性、问答、文本标注(如词性)、命名实体识别等。然而,预先训练 BERT 在计算上可能很昂贵,除非你使用 TPU 的或者类似于 Nvidia V100 的 GPU。

BERT 的人还发布了一个单一的多语言模型,该模型基于整个维基百科的 100 种语言。多语种的 BERT 比那些只接受一种语言训练的要低几个百分点。

评论

MLM 的 BERT 掩蔽策略使模型偏向实际单词。这种偏差对训练的影响没有显示出来。

更新:最近在 BERT-之上提出了几个新方法,这篇博文讨论了使用哪一个?

参考

[1]https://cloud.google.com/tpu/docs/deciding-pod-versus-tpu

[2]假设第二代 TPU,第三代快 8 倍。https://en.wikipedia.org/wiki/Tensor_processing_unit

[3]http://timdettmers . com/2018/10/17/tpus-vs-GPU-for-transformers-Bert/

使用 Keras 在 3 行代码中实现 BERT 文本分类

原文:https://towardsdatascience.com/bert-text-classification-in-3-lines-of-code-using-keras-264db7e7a358?source=collection_archive---------3-----------------------

**2019–08–17:**文章中的代码演示已经分享到 Google Colab 上。

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

BERT ( 来自变形金刚的双向编码器表示)是谷歌开发的深度学习模型。它代表了今年机器学习的重大突破之一,因为它在 11 个不同的自然语言处理(NLP)任务中取得了最先进的结果。此外,谷歌开源了代码,并提供了类似于 ImageNet 上预训练的计算机视觉模型的预训练模型供下载。由于这些原因,人们对 BERT 仍有很大的兴趣(尽管其他车型略微超过了它)。

虽然 BERT 打破了许多不同任务的记录,从问答(SQuAD v1.1)到自然语言推理,文本分类仍然是最实用和广泛适用的 NLP 任务之一。在本文中,我们将展示如何用少至 3 行代码将 BERT 应用于文本分类问题。为了实现这一点,我们将使用 ktrain ,一个类似 fastai 的接口到 Keras。 ktrain 是开源的,在这里可以获得

要安装 ktrain ,只需输入以下命令:

pip3 install ktrain

为了在 ktrain 和 Keras 中演示 BERT 文本分类,我们将使用在许多学术论文中使用的 IMDb 电影评论数据集对电影评论进行情感分析。目标是正确地将验证集中的每个电影评论分类为正面或负面。你可以从这里下载数据集,然后解压。首先,让我们导入 ktrainktrain.text 模块:

import ktrain
from ktrain import text

导入了 ktrain 之后,我们开始吧。

步骤 1:加载数据

我们将首先使用texts_from_folder函数从上面提取的文件夹中加载数据。

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

第一个参数应该是提取 Imdb 数据集的文件夹的路径。maxlen参数指定每个电影评论中要考虑的最大字数(较长的评论被截断到这个长度)。BERT 可以处理的最大长度为 512,但是如果可以的话,您会希望使用更少的长度来减少内存并提高速度。必须以特定的方式对文本进行预处理,以便在 BERT 中使用。这通过将preprocess_mode设置为‘Bert’来实现。如果需要的话,BERT 模型和词汇表将被自动下载。最后,texts_from_folder函数需要以下目录结构,aclImdb 文件夹已经符合该结构:

├── folder
    │   ├── train
    │   │   ├── class0       # folder for class 0 documents
    │   │   ├── class1       # folder for class 1 documents
    │   │   ├── class2       # folder for class 2 documents
    │   │   └── classN       # folder for class N documents
    │   └── test 
    │       ├── class0       # folder for class 0 documents
    │       ├── class1       # folder for class 1 documents
    │       ├── class2       # folder for class 2 documents
    │       └── classN       # folder for class N documents

步骤 2:加载 BERT 并将其包装在一个学习者对象中

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

get_learner的第一个参数使用 ktrain text_classifier函数来用随机初始化的最终密集层加载预训练的 BERT 模型。第二个和第三个参数分别是定型数据和验证数据。get_learner的最后一个参数是批量大小。我们基于谷歌对12GBGPU 的以下建议,使用 6 个小批量:

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

Seq Length corresponds to the maxlen argument from STEP 1.

第三步:训练模型

为了训练模型,我们使用了 ktrainfit_onecycle方法,该方法采用了1 周期学习率策略,该策略在训练的前半段线性增加学习率,然后在后半段降低学习率:

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

有关调整学习率的更多详情,请参见 ktrain 上的这篇文章。根据论文中的建议使用最大学习率 2e-5 (并通过执行 ktrain 学习率查找器确认)。

Keras 输出可以看出,这在单个历元中实现了 93.71% 的精度:

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

由于我们似乎没有过度拟合,如果需要的话,该模型可以针对更多的时期进行训练,以产生甚至更高的精度。例如,在这个数据集上,三个时期的训练可以产生超过 94% 的准确度。

关于伯特实践的几点思考

速度: 虽然 BERT 的表现令人印象深刻,但在训练和推理(即对新数据的预测)方面都相对较慢。试图通过压缩来提高 BERT 的速度似乎并不成功。出于这些原因,如果训练超过一个历元,您可能希望省略get_learner中的val_data参数,并且仅在训练结束时进行验证。这可以在 ktrain 中用learner.validate的方法完成,如这个 Google Colab 笔记本所示。鉴于 BERT 的缓慢,您还应该考虑更简单和更快的模型作为替代方案,以决定 BERT 提高的准确性是否值得。在某些情况下,你会惊讶地发现事实并非如此。

更新 2020-01–14:【蒸馏】可用于 加速变压器型号 。关于在 ktrain 中使用 DistilBERT 模型的教程,请参见 我们的新媒体帖子

内存: BERT 可能相当占用内存。如果您遇到可能表明您超出 GPU 内存限制的错误(例如Blas GEMM launch failedCUDA_ERROR_OUT_OF_MEMORY,您可以尝试减少步骤 2 中使用的batch_size参数或步骤 1 中使用的maxlen参数。

保存 BERT 模型: 在数据集上训练 BERT 后,可能需要将其保存到磁盘上,以便以后对新数据进行预测。如您所知,您可以分别使用model.save方法和 Keras 内置的load_model函数在 Keras 中保存和加载模型。然而,Keras load_model函数在这里不会像预期的那样工作,因为 BERT 使用了自定义层。在重新执行上述步骤 1 和 2 后,您可以使用 ktrain 中的learner.load_model方法加载模型,而不是使用 Keras 的内置load_model函数。这将正确工作,因为 ktrain 将自定义 BERT 层传递给 Keras 的load_model函数。或者,您可以使用对model.save_weightsmodel.load_weights的标准调用来保存和加载权重。(在这两种情况下,Keras 模型总是可以作为learner.model直接访问。)

**文章源代码:**这篇文章的源代码以下面这个 Jupyter 笔记本的形式提供:IMDb-伯特. ipynb 。笔记本包括估计好的学习率和对新数据进行预测的例子。请随意在您自己的数据集上进行尝试。

**更多信息:**有关 *ktrain、*的更多信息,请参见关于 ktrain 的教程笔记本和我们之前的 TDS 媒体出版物:

k Train:Keras 的一个轻量级包装器,用于帮助训练神经网络

Google Colab 上使用 ktrain ?另请参见BERT 在多分类设置中的演示

参考

  • ktrain 通过 keras_bert 包由赵 HG 支持 BERT 文本分类。

伯特来救援了。

原文:https://towardsdatascience.com/bert-to-the-rescue-17671379687f?source=collection_archive---------3-----------------------

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

在这篇文章中,我想展示如何将 BERT 应用于一个简单的文本分类问题。我假设您或多或少地熟悉 BERT 在高层次上是什么,并通过向您展示如何在您的工作中利用它来更加关注实践方面。粗略来说,BERT 是一个知道表示文本的模型。你给它一些序列作为输入,然后它左看右看几次,产生每个单词的向量表示作为输出。在他们的论文中,作者描述了两种使用 BERT 的方法,一种是“特征提取”机制。也就是说,我们使用 BERT 的最终输出作为另一个模型的输入。通过这种方式,我们使用 BERT 从文本中“提取”特征,然后在一个单独的模型中用于手头的实际任务。另一种方法是“微调”伯特。也就是说,我们在 BERT 上添加额外的层,然后一起训练整个东西。通过这种方式,我们可以训练我们的附加层,还可以改变(微调)层的权重。在这里,我想展示第二种方法,并介绍一个非常简单和流行的文本分类任务的分步解决方案——IMDB 电影评论情感分类。这个任务可能不是最难解决的任务,将 BERT 应用于它可能有点矫枉过正,但是这里显示的大多数步骤对于几乎每个任务都是相同的,不管它有多复杂。

在深入实际代码之前,让我们了解一下 BERT 的一般结构,以及在分类任务中使用它需要做些什么。如前所述,一般来说,BERT 的输入是一个单词序列,输出是一个向量序列。BERT 允许我们根据它的输出执行不同的任务。因此,对于不同的任务类型,我们需要稍微改变输入和/或输出。在下图中,您可以看到 4 种不同的任务类型,对于每种任务类型,我们可以看到模型的输入和输出应该是什么。

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

您可以看到,对于输入,在每个序列的开头总是有一个特殊的[CLS]标记(代表分类),还有一个特殊的[SEP]标记将输入分成两部分。

对于输出,如果我们对分类感兴趣,我们需要使用第一个令牌([CLS]令牌)的输出。对于更复杂的输出,我们可以使用所有其他的令牌输出。

我们对“单句分类”感兴趣(右上),所以我们将添加特殊的[CLS]标记,并将其输出作为线性层的输入,然后激活sigmoid,执行实际的分类。

现在让我们来理解手头的任务:给定一个电影评论,预测它是正面的还是负面的。我们使用的数据集是 PyTorch-NLP 库中的 50,000 条 IMDB 评论(25,000 条用于训练,25,000 条用于测试)。每个评论都被标记为posneg。在训练集和测试集中,正面评价和负面评价各占 50%。

你可以在这个笔记本里找到所有的代码。

1.准备数据

我们使用pytorch-nlp库加载数据:

train_data, test_data = imdb_dataset(train=True, test=True)

这个数据集中的每个实例都是一个字典,包含两个字段:textsentimet

{
    'sentiment': 'pos',  
    'text': 'Having enjoyed Joyces complex nove...'
}

我们为每个集合创建两个变量,一个用于文本,一个用于标签:

train_texts, train_labels = list(zip(*map(lambda d: (d['text'], d['sentiment']), train_data)))test_texts, test_labels = list(zip(*map(lambda d: (d['text'], d['sentiment']), test_data)))

接下来,我们需要标记我们的文本。伯特是用词块符号化来训练的。这意味着一个单词可以分解成多个子单词。例如,如果我对句子“嗨,我的名字是马頔”进行分词,我会得到:

tokenizer.tokenize('Hi my name is Dima')# OUTPUT
['hi', 'my', 'name', 'is', 'dim', '##a']

这种标记化在处理词汇之外的单词时是有益的,并且它可以帮助更好地表示复杂的单词。子词是在训练期间构建的,并且依赖于模型被训练的语料库。当然,我们可以使用任何其他的记号化技术,但是如果我们使用训练 BERT 模型的相同记号化器进行记号化,我们会得到最好的结果。PyTorch-Pretrained-BERT 库为我们提供了每个 BERTS 模型的标记器。这里我们使用基本的bert-base-uncased型号,还有其他几种型号,包括更大的型号。BERT 的最大序列长度是 512,因此我们将截断任何长于此长度的评论。

下面的代码创建标记器,标记每个评论,添加特殊的[CLS]标记,然后只获取训练集和测试集的前 512 个标记:

tokenizer = BertTokenizer.from_pretrained('bert-base-uncased', do_lower_case=True)train_tokens = list(map(lambda t: ['[CLS]'] + tokenizer.tokenize(t)[:511], train_texts))test_tokens = list(map(lambda t: ['[CLS]'] + tokenizer.tokenize(t)[:511], test_texts))

接下来,我们需要将每个评论中的每个标记转换成标记化器词汇表中的id。如果有一个标记不在词汇表中,标记器将使用特殊的[UNK]标记并使用它的 id:

train_tokens_ids = list(map(tokenizer.convert_tokens_to_ids, train_tokens))test_tokens_ids = list(map(tokenizer.convert_tokens_to_ids, train_tokens_ids))

最后,我们需要填充我们的输入,这样它将具有相同的大小 512。这意味着对于任何少于 512 个令牌的评论,我们将添加零以达到 512 个令牌:

train_tokens_ids = pad_sequences(train_tokens_ids, maxlen=512, truncating="post", padding="post", dtype="int")test_tokens_ids = pad_sequences(test_tokens_ids, maxlen=512, truncating="post", padding="post", dtype="int")

我们的目标变量目前是一个由negpos字符串组成的列表。我们将把它转换成布尔的numpy数组:

train_y = np.array(train_labels) == 'pos'
test_y = np.array(test_labels) == 'pos'

2.模型结构

我们将使用 PyTorch 和优秀的py torch-pre trained-BERT库来构建模型。实际上,这个库中已经实现了一个非常相似的模型,我们可以使用这个模型。对于这篇文章,我想自己实现它,这样我们可以更好地了解正在发生的事情。

在我们创建模型之前,让我们看看如何使用在 PyTorch-Pretrained-BERT 库中实现的 BERT 模型:

bert = BertModel.from_pretrained('bert-base-uncased')x = torch.tensor(train_tokens_ids[:3])
y, pooled = bert(x, output_all_encoded_layers=False)print('x shape:', x.shape)
print('y shape:', y.shape)
print('pooled shape:', pooled.shape)# OUTPUT
x shape :(3, 512)
y shape: (3, 512, 768)
pooled shape: (3, 768)

首先,我们创建 BERT 模型,然后我们创建 PyTorch 张量,其中包含来自我们训练集的前 3 条评论,并将其传递给它。输出是两个变量。让我们来理解所有的形状:x的大小是(3, 512),我们只取了 3 个评论,每个评论有 512 个标记。y的大小为(3, 512, 768),这是每个令牌的 BERTs 最终层输出。我们可以使用output_all_encoded_layer=True来获得所有 12 层的输出。使用大小为 768 的向量来表示每个评论中的每个标记。pooled的大小是(3, 768)这是我们的[CLS]令牌的输出,我们序列中的第一个令牌。

我们的目标是采用 BERTs 池输出,应用线性层和sigmoid激活。我们的模型看起来是这样的:

class BertBinaryClassifier(nn.Module):
    def __init__(self, dropout=0.1):
        super(BertBinaryClassifier, self).__init__() self.bert = BertModel.from_pretrained('bert-base-uncased')
        self.linear = nn.Linear(768, 1)
        self.sigmoid = nn.Sigmoid()

    def forward(self, tokens):
        _, pooled_output = self.bert(tokens, utput_all=False)
        linear_output = self.linear(dropout_output)
        proba = self.sigmoid(linear_output)
        return proba

PyTorch 中的每个模型都是一个nn.Module对象。这意味着我们构建的每个模型都必须提供 2 个方法。__init__ 方法声明了模型将使用的所有不同部分。在我们的例子中,我们创建了将要微调的 BERT 模型、线性层和 Sigmoid 激活。forward方法是正向传递期间运行的实际代码(类似于sklearnkeras中的predict方法)。这里我们将tokens输入传递给 BERT 模型。BERT 的输出是 2 个变量,正如我们之前看到的,我们只使用第二个变量(使用_名称是为了强调没有使用这个变量)。我们将汇集的输出传递给线性层。最后,我们使用 Sigmoid 激活来提供实际概率。

3.培训/微调

训练相当标准。首先,我们准备好张量和数据加载器:

train_tokens_tensor = torch.tensor(train_tokens_ids)
train_y_tensor = torch.tensor(train_y.reshape(-1, 1)).float()test_tokens_tensor = torch.tensor(test_tokens_ids)
test_y_tensor = torch.tensor(test_y.reshape(-1, 1)).float()train_dataset = TensorDataset(train_tokens_tensor, train_y_tensor)
train_sampler = RandomSampler(train_dataset)
train_dataloader = DataLoader(train_dataset, sampler=train_sampler, batch_size=BATCH_SIZE)test_dataset = TensorDataset(test_tokens_tensor, test_y_tensor)
test_sampler = SequentialSampler(test_dataset)
test_dataloader = DataLoader(test_dataset, sampler=test_sampler, batch_size=BATCH_SIZE)

我们将使用Adam优化器和二元交叉熵(BCELoss)损失,并训练 10 个时期的模型:

bert_clf = BertBinaryClassifier()
bert_clf = bert_clf.cuda()
optimizer = Adam(bert_clf.parameters(), lr=3e-6)
bert_clf.train()for epoch_num in range(EPOCHS):
    for step_num, batch_data in enumerate(train_dataloader):
        token_ids, labels = tuple(t.to(device) for t in batch_data)
        probas = bert_clf(token_ids)
        loss_func = nn.BCELoss()
        batch_loss = loss_func(probas, labels)
        bert_clf.zero_grad()
        batch_loss.backward()
        optimizer.step()

对于那些不熟悉 PyTorch 的人,让我们一步一步地看代码。

首先,我们创建上面定义的BertBinaryClassifier。我们通过应用bert_clf.cuda()将其移动到 GPU。我们用我们的模型参数(优化器将会更新)和一个学习率创建了 Adam 优化器,我发现效果很好。

对于每个时期中的每个步骤,我们执行以下操作:

  1. 通过应用.to(device)将我们的张量移动到 GPU
  2. bert_clf(token_ids)给出了概率(向前传递)
  3. loss_func(probas, labels)计算损失
  4. 将上一步的梯度归零
  5. 通过batch_loss.backward()计算并传播新的梯度
  6. 通过optimizer.step()更新与梯度相关的模型参数

经过 10 个时代,我得到了相当不错的结果。

结论

BERT 是一个非常强大的模型,可以应用于许多任务。对我来说,它为我的工作任务提供了一些非常好的结果。我希望这篇文章能帮助你更好地理解与 BERT 一起工作的实际方面。如前所述,您可以在本笔记本中找到代码

嵌入式投影仪中的 BERT 可视化

原文:https://towardsdatascience.com/bert-visualization-in-embedding-projector-dfe4c9e18ca9?source=collection_archive---------14-----------------------

这个故事展示了如何在 Tensorflow 的 Tensorboard 嵌入投影仪中可视化预训练的 BERT 嵌入。该故事使用了大约 50 个独特的句子及其通过 TensorFlow Hub BERT 模型生成的 BERT 嵌入。

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

BERT visualization in Embedding Projector

创造历史

为了生成 BERT 嵌入[1],我使用了模型为BERT-base-uncased的 BERT 的 TF Hub 实现。在我的以前的故事中看到一个简短的介绍,或者在 Colab 上查看代码!

交互式嵌入式投影仪可视化包含两个数据集。第一个有 20 个随机句子,由这个随机句子生成器生成。第二个包含 23 个自制的句子,只有 36 个独特的标记。该数据集具有一小组标记,因此嵌入投影仪可以通过标记给点着色。

使用主成分分析的数据可视化

高维数据的可视化并不总是容易的。为了用 2D 或 3D 来表示数据以便我们可以看到,我们必须将数据投影到一个更低的维度,而不会丢失太多的信息。

一种方法是使用 PCA(主成分分析)[2]。PCA 找到正交基,从而将数据投影到这些基上,点之间的总差异是最大的。如果你对 PCA 更感兴趣,我在之前的一个故事中描述过。下图显示了一个单词的 100 个嵌入向量到其前两个主要成分的 2D 投影。

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

PCA for the embeddings of the word ‘city.’

使用 PCA,我们可以直观地识别嵌入数据集中的聚类。分析单词’ city 和’ *game,'*的嵌入,我们可以看到基于嵌入,有两种不同类型的点。

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

PCA for the embeddings of the words ‘city’ and ‘game

嵌入式投影仪

用 PCA 说明越来越多的数据并不总是最好的选择。谷歌的 TensorBoard 提供了一个嵌入式投影仪来使用 PCA、UMAP [3]和 t-SNE [4]在 2D 或 3D 中可视化数据。不幸的是,嵌入式投影仪无法处理这么多样本的数据。它也不能显示超过 50 类的颜色。因此,这里使用的数据只包含几个句子。如果你想探索 TensorBoard 的可视化工具,我建议这个教程

我建议你激活颜色来获得单词/句子类别的感觉。下图显示了投影的视图。

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

Embedding Projector. Activate colors using the drop-down in the red circle!

让我们看看交互式投影仪中的 UMAP 投影、t-SNE 投影和主成分分析投影!我建议阅读这篇介绍来了解 UMAP 和 t-SNE 。或者看参考文献找原论文!

UMAP 和 t-SNE 都有同样的两个抽象步骤:

  1. 基于最近邻,保留连接、相似性和数据集的结构。
  2. 使用梯度下降优化低维表示。

UMAP 嵌入群

让我们用 UMAP 来形象化令牌之间的关系!

如果我们对 20 个随机句子数据集使用具有 5 个邻居的 UMAP,我们可以看到 UMAP 投影对句子具有单独的记号组。在下图中,我们可以看到句子的标记彼此接近。一个句子的标记有相同的颜色。

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

UMAP 2D projection with sentence colorization

如果我们使用第二个数据集,有 36 个标记的 23 个句子,我们也可以看到标记的颜色。让我们再次使用有 5 个邻居的 2D UMAP!在这里,我们可以看到,UMAP 组点标记水平,但句子的标记也有一个主要领域。

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

2D UMAP visualization: a) tokens of a sentence, b) token colorization, c) sentence colorization

摘要

这个故事展示了 20 个双 BERT 嵌入表示数据集的可视化,每个数据集包含大约 20 个不同的句子。这个故事包含了生成数据集的 Colab 代码和一个带有预加载数据的交互式可视化工具。

参考

[1] Devlin,j .,Chang,M. W .,Lee,k .,& Toutanova,K. (2018 年)。 Bert:用于语言理解的深度双向转换器的预训练。 arXiv 预印本 arXiv:1810.04805

[2]h .霍特林(1933 年)。将复杂的统计变量分析成主要成分。 《教育心理学杂志》24 (6),417 页。

[3]麦金尼斯、希利和梅尔维尔(2018 年)。 Umap:一致流形逼近和投影降维。 arXiv 预印本 arXiv:1802.03426

[4]马滕博士和辛顿博士(2008 年)。使用 t-SNE 可视化数据。 机器学习研究杂志9(11 月),2579–2605。

自然语言处理搜索训练

原文:https://towardsdatascience.com/bert-your-new-search-ally-840d1c6cd2bc?source=collection_archive---------31-----------------------

来自变压器的双向编码器表示

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

名义评分从来都是零和博弈,而在搜索中,数学从来都是多和博弈。信息如何被索引、编译和传送背后的复杂结构是变量规模的逻辑因素。

通过 BERT(来自变压器的双向编码器表示)和 NLP(自然语言处理),这些结果的决定性度量变得更加突出。

类似于以先进先出(FIFO)方式运作的仓库,其中一个项目作为所选产品,影响产品需求要求供应。随着回报率的边际开始趋于平稳,引入可行的替代方案和细分市场成为并行市场的一个认知特征。毛巾需要一个架子,干净的毛巾需要一个架子,架子上有纸巾等等。

一旦市场运作建立起来,你的仓库就变成了一个物品的聚集地,足够占据全球发达家庭的浴室。为这些利益服务,你的运作开始规模化,因为对物流影响的需求成为一种定价游戏,以满足消费者的需求。毛巾仓库、主要支持产品和次要创新产品成为您的业务遍布全球的目录点。

作为前馈训练方法的供给和需求范例

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

这些产品变成了编码器,仓库变成了变压器,你每月邮寄的目录变成了搜索引擎。

当理想的复杂性是适当的词缀,而不是开发成功的邻近性时,解释机器学习理论就变成了一系列类似这些的隐喻。深入解释毛巾及其对卫生的影响,同时理解市场规模上消费者需求的开始,提供将这些实践用于商业的经验。

随着业务从一个产品扩展到一个仓库体验 (1:1) ,移动物品和填充空间的操作顺序开始划分和展开。随着越来越多的产品来满足需求和支持主要产品,空间本身变得共享,基于需求的倾向。

当运输成本超过利润的明显距离之外的地区的需求增加时,就需要额外的运输立足点。

100 英里,是对分化的兴起的一个有力的基础认识,同样地以 15 度的经度,作为时间。

在这一点上,企业现在跨两个仓库复制其方法,以支持具有独特产品的多个社区。在某些情况下,在社区 1 每户可能有更多人,需要更多毛巾,而社区 2 有更多淋浴,需要更多方式存放毛巾的情况下,也有抵消信息分发的特定需求。所应用的分隔空间的影响支持正在入库的货物数量的优化。

来自预训练数据源的参考编码

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

参考社区的利基部分,仓库抵消了额外的需求,并预测了社区的个人需求,以优化效率和利润。

编码器是企业的产品,因为它们是搜索引擎贡献的类型,每个企业都会在数字空间做出贡献。定义这些经验是成为一种等同的艺术形式,并列举评估其重量的原则。

这些编码器考虑了每条毛巾的重量值,提供了与被评定为较软的毛巾、纱线支数较多的毛巾以及购买频率较高的产品的更多一致性。

在这个意义上,权重是一个数学函数,它考虑了频率的总和。将总和的最高比率归因为最主要的;最有利。

这为消费者提供了理解他们想要寻找的信息如何不仅是真实的,而且为他们的体验提供了最佳解决方案的效率,因为它考虑了不直接可见但有影响力的数据。

这些编码器被认为是人工智能中过滤输入的节点。将价值表示划分为所提供的附加价值的概念是整个搜索体验的一部分,也是解决方案价值的单独加权。

解读语言相关性的转换策略

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

随着理解原则的积累,随着时间的推移,企业自身将向市场提供有竞争力的补充产品。对成功公司的观察,对机会本身的观察,就变成了一个分裂的交集,叠加在商品的使用上。

像这样的市场变得非常强劲,从颜色到定制,毛巾及其市场空间成为一个很好的例子,因为它们需要一定的操作经验,但价值基于简单的叙述。

随着这些市场的融合,该空间需要考虑最初的品牌、仓库和产品,同时还要根据其竞争和产品的评估标准来衡量其重量。

为这些市场提供公平的服务、目录、索引和搜索意味着理解个人的贡献,并将其作为进入市场的有效手段。从产品的数据,在这种情况下,神经节点的编码器的解释,然后有一个评估算法,转换加权统计的输出,以呈现一个结果。

NLP 输入操作和源的双向一致性

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

对数据、市场、产品供应、评论、购买和访问的观察被收集到一系列可测量的统计数据中,成为需求曲线。根据这条曲线,这种加权的实现方式被分解,然后被重构,以说明产品对空间的单独贡献,同时考虑市场的需求以及与该产品的交互。

这些空间现在遇到的次要方向不仅是产品及其**【需求】**的有效性,而且是其体验的“**声誉”**的以下性质。与所有产品加权统计数据同时连接在一起的是上下文信息,该信息还提供了对市场的洞察,以及所有其自身的交互。

简而言之,内容是围绕预期意图积累的支持信息的集合,以近似在没有直接对话或体验的情况下错过的解释摩擦。

多信息文本

页面交互是一个权重很大的指标,它提供了对在引导和定义个人花费时间的空间周围累积空间的价值的理解。这个空间中的词提供了独特的参考,为 fit 提供了解释。

录像

观看视频并与视频互动提供了对与 观看时间分享喜欢评论 的参与度的洞察。阐明这一指标,公司可以利用社区来提高对其产品的考虑。开发带有描述和术语的清晰标题,以与他们的产品保持一致,在这个公式中占据了更多的空间。关注他们对注释和字幕的贡献提供了另一个有利的需求因素。

复习

特定于产品的措辞内容和评论深度提供了对产品相关性的权重和深度的数字计算的洞察。将消费者的愿景与公司的愿景相一致成为一个有价值的标识符。

开放式数据

数据领域中产品的可用性,例如通过引擎索引的产品、开发的具有开放端点的 API,以及页面中可索引的结果都提高了相关性。

数据消费的自然语言处理算法

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

当试图理解空间能力的差异时,引擎必须测量作为一种结构体验的生存能力的适应需求。协调细致的数据,在这些数据中,给定的对象、产品和需求与空间中的确定性词语密切相关,it 部门不仅要重视相关性,还要重视空间中关系的方向性价值。

如果说毛巾是焦点,那么柔软、优雅和蓬松就是具有独立分量的形容词,也是验证该产品解决消费者需求的效率的前提。

标准化这些抽象成为机器的任务,参考引擎来收集和理解市场的生存能力。将这些向量建立为变量错综复杂,通知源词以下信息:属性、变量、质量和每个的加权值。

从人工智能和搜索的发展到这一点,与 BERT 交互的前提是由场景中现有的清晰焦点额外加入的。公司、品牌和市场定义这些错综复杂的变量并背诵它们,当他们产品的优势成为其所有特征的累积前景时,将验证他们的努力。

您可以从这些文章中找到更多关于 NLP 和 BERT 本身在搜索引擎中的技术集成的信息,开源 BERT:自然语言处理的最先进的预培训BERT 解释:NLP 的最先进的语言模型

感谢阅读,继续参考!

寻找更多的应用程序开发建议?在 TwitterGitHubLinkedIn 上关注。在线访问最新更新、新闻和信息,网址为 collectedview.io

2020 年 5 大免费股市 API

原文:https://towardsdatascience.com/best-5-free-stock-market-apis-in-2019-ad91dddec984?source=collection_archive---------0-----------------------

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

Photo by Chris Li on Unsplash

金融 API 市场增长如此之快,去年的帖子或平台今年都不是一个好的选择。所以在这个故事里,我会给大家展示我在 2019 年用过的最好的 5 个股市 API。

什么是股市数据 API?

股票市场数据 API 提供当前在市场上交易的金融资产的实时或历史数据。这些 API 通常提供公共股票、ETF、etn 的价格。

这些数据可用于生成技术指标,这些指标是建立交易策略和监控市场的基础。

数据

在这个故事中,我主要关心价格信息。对于其他数据,有一些其他的 API 主要用于用例,这里不做介绍。

我将讨论以下 API 以及它们的使用场合:

  • 雅虎财经
  • Google Sheets 中的 Google 金融
  • IEX 云
  • 阿尔法优势
  • 世界贸易数据
  • 其他 API(polygon . io、Intrinio、Quandl)

1.雅虎财经

Docs:y finance

雅虎财经 API 于 2017 年被关闭。所以你可以看到很多关于雅虎财经替代方案的帖子。然而,它回到了 2019 年的某个时候。所以你仍然可以使用雅虎财经获得免费的股市数据。雅虎的 API 是个人和企业级用户使用的股票数据 API 的黄金标准。

雅虎财经提供了超过 5 年的每日 OHLC 价格数据。而且免费又可靠。

有一个新的 python 模块 yfinance 包装了新的雅虎金融 API,你可以直接使用它。

# To install yfinance before you use it.
> pip install yfinance

下面是一个如何使用 API 的例子。请点击上面的 Github 链接查看完整的文档,您可以开始了。

2.谷歌金融

谷歌金融在 2012 年被弃用。然而,它并没有关闭所有的功能。Google Sheets 中有一个支持你获取股票营销数据的功能。在 Google Sheets 中它被称为 GOOGLEFINANCE

它的工作方式是键入如下内容,您将获得最后的股票价格。

GOOGLEFINANCE("GOOG", "price")

语法是:

GOOGLEFINANCE(ticker, [attribute], [start_date], [end_date|num_days], [interval])
  • **股票代号:**证券要考虑的股票代号。
  • 属性(可选,默认为"price"):从 Google Finance 中获取关于ticker的属性。
  • start_date (可选):取历史数据时的开始日期。
  • end_date|num_days (可选):取历史数据的结束日期,或者从start_date开始返回数据的天数。
  • 间隔(可选):返回数据的频率;不是“每日”就是“每周”。

附上使用示例。

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

3.IEX 云

网址:https://iexcloud.io/

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

IEX 云是今年刚刚发布的新金融服务。它是从 IEX 集团的旗舰证券交易所分离出来的独立业务,是一个连接开发者和金融数据创造者的高性能金融数据平台。

与其他订阅服务相比,它非常便宜。9 美元/月,你几乎可以得到所有你需要的数据。此外,基本免费试用,你已经得到 500,000 核心讯息免费为每个月。

有一个 python 模块来包装他们的 API。你可以很容易的查出来: iexfinance

4.阿尔法优势

网址:https://www.alphavantage.co/

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

Alpha Vantage Inc .是各种免费 API 的领先提供商。它提供 API 来访问历史和实时股票数据、外汇数据和加密货币数据。

使用 Alphavantage,您可以每分钟执行多达 5 个 API 请求,每天执行 500 个 API 请求。每分钟 30 个 API 请求,每月 29.9 美元。

5.世界贸易数据

【https://www.worldtradingdata.com/】网址:

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

此外,还提供了完整的日内数据 API 和货币 API 访问权限。对于那些需要更多数据点的人来说,从每月 8 美元到每月 32 美元的计划都是可用的。

目前有四种不同的计划可供选择。对于免费访问,每次请求最多可以获得 5 只股票(实时 API)。每天最多 250 个请求。订阅计划不是很贵,你可以得到一个

他们提供 URL,您的响应将是 JSON 格式。目前还没有可用的 python 模块来包装他们的 API。所以你得用 请求 或者其他 web 模块来包装自己的 API。

6.其他 API

****网址:https://polygon . io

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

仅美国股市每月 199 美元。对于初学者来说,这可能不是一个好的选择。

****网址:【https://intrinio.com】

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

只有实时股票市场每月 75 美元。此外,对于 EOD 的价格数据,它是 40 美元/月。你可以从我推荐的其他 API 获得几乎免费的 EOD 价格数据。尽管他们有 206 个价格提要、10 个金融数据提要和大量其他数据要订阅。价格对独立交易者来说并不友好。

****网址:https://www.quandl.com/

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

Quandl 是一个金融、经济和其他相关 API 的聚合市场。Quandl 将来自第三方市场的 API 聚合为服务,供用户购买他们想要使用的任何 API。

所以你需要订阅不同的市场来获得不同的财务数据。而且不同的 API 会有不同的价格体系。有些是免费的,有些是基于订阅或一次性购买的。

此外,Quandl 在其网站内有一个分析工具。

如果不在乎钱的话,Quandl 是个不错的平台。

包裹

学习和建立一个交易系统并不容易。但是财务数据是一切的基础。如果你有任何问题,请在下面提问。

用于异常检测的最佳聚类算法

原文:https://towardsdatascience.com/best-clustering-algorithms-for-anomaly-detection-d5b7412537c8?source=collection_archive---------3-----------------------

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

Photo by Agence Olloweb on Unsplash

让我首先解释一下任何通用的聚类算法是如何用于异常检测的。

使用聚类进行异常检测背后的主要思想是学习已经可用的数据(训练)中的正常模式,然后在提供新数据(测试)时使用该信息来指出一个点是否异常。

一般步骤(一般预处理后):
1 —根据你的数据选择最佳模型。
2 —将模型拟合到训练数据,该步骤的复杂程度取决于所选的模型,此时应进行一些超参数调整。
3-一旦收到新数据,将其与模型的结果进行比较,并确定它是正常点还是异常点,执行这种分类的方式高度依赖于模型(我将讨论如何为解释的模型执行),一些基于距离,而另一些使用概率。

4-如果随着时间的推移有任何类型的数据演变,则模型应在一段时间后重新训练,以便学习新的行为(否则这种新的行为可能总是被归类为异常)。

注意:当然聚类对于所有与异常检测相关的问题并不理想(就像任何其他方法一样,你知道,没有免费的午餐*),但是将这种技术与其他类似智能特征提取的技术结合起来可以帮助你解决很多问题;例如,当你有时间序列,问题是一个值增加太快,但仍然在一个正常的范围内,会发生什么?将导数添加到聚类算法中可以帮助您找到异常。*

基于密度的噪声应用空间聚类

DBSCAN 是一种基于密度的聚类算法(实际上 DBSCAN 代表Den sity-BasedSpatialClustering ofA**应用程序实际上,这是我个人喜欢 DBSCAN 的主要原因之一,不仅我可以检测到测试中的异常,而且训练中的异常也会被检测到,不会影响我的结果。**

在该模型中有两个关键参数:
eps: 两点之间视为邻居的最大距离。如果这个距离太大,我们可能会将所有的点聚集在一个巨大的集群中,然而,如果这个距离太小,我们甚至可能不会形成一个集群。
min_points: 形成一个聚类的最小点数。如果我们为这个参数设置一个较低的值,我们可能会得到很多非常小的聚类,但是,一个较大的值可能会停止创建任何聚类的算法,最终得到一个只有异常的数据集。

该算法创建聚类的方式是通过查看每个点有多少个邻居,考虑所有距离小于特定距离的邻居( eps )。如果多于个 min_points* 是邻居,则创建一个聚类,并且该聚类用邻居的所有邻居来扩展。但是,由于一张照片比一千张照片更有价值,我从这个媒体帖子中借用了这张照片来解释 DBSCAN 😗

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

Image obtain from the post “DBSCAN: What is it? When to use it? How to use it?

现在我们有了集群…

怎样才能检测出测试数据中的异常?

我所遵循的将点分类为异常或不异常的方法如下:
1-计算从新点到所有核心点的距离(仅计算核心点,因为它们实际上是定义聚类的点)并寻找最小值(到聚类内最近邻居的距离)。
2 —用 eps 比较到集群内最近邻居的距离,因为这是被认为是邻居的两个点之间的界限,这样,我们就可以用我们的测试数据发现是否有任何核心点实际上是邻居。
3-如果距离大于 eps 该点被标记为异常,因为它在聚类中没有邻居。

高斯混合模型

假设所有数据点都是由有限数量的高斯分布混合生成的概率模型。该算法试图恢复生成该分布的原始高斯分布。为此,它使用期望最大化(EM)算法,该算法初始化一个随机的 n 初始高斯分布,然后调整参数,寻找一个组合,使该分布生成的点的可能性最大化。

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

Figure obtained from Angus Turner’s blog: “Gaussian Mixture Models in PyTorch

高斯混合模型的问题之一是需要指定聚类数,另一种可能性是使用变分贝叶斯高斯混合,以避免这个问题。

当然,就像 K-Means 一样,由于集群的初始化是随机的,我们可能会得到一个对我们的问题来说不是最优的局部最小值。这个问题可以通过多次执行来解决,然后计算出概率的平均值。然而,如果模型需要投入生产,这种解决方案并不是最佳的,当模型需要部署在流环境中时,我仍然在寻找解决这个问题的最佳方法。

变分贝叶斯高斯混合

我不想在这里讲太多细节,scikit-learn 页面有完整的解释。但这种变异值得一提。该模型背后的思想类似于高斯混合,然而,实现是不同的,这里,代替 EM,使用变分推理算法。

这里,只需要指定最大数量的聚类,然后算法可以找到实际数量的聚类,并将不相关的聚类的权重设置为非常接近零。

当然,这种选择也不是完美的,有许多超参数可供选择,实际上比高斯混合模型中的要多。其中最重要的是权重 _ 浓度 _ 先验*,它将在很大程度上影响你最终得到的有效聚类数。*

怎样才能检测出测试数据中的异常?

一旦算法被训练,我们得到新的数据,我们可以把它传递给模型,它会给我们这个点属于不同聚类的概率。这里,可以设置阈值,即如果概率低于该值,则该点应该被视为异常。在贝叶斯高斯混合的情况下,有一件重要的事情要记住:不是所有的聚类都应该被考虑,记住算法忽略了不重要的聚类,给它们一个接近于零的权重(它们没有被移除,但是你可以知道哪些应该被移除),我过去所做的是检查点属于重要聚类的概率,为了做到这一点,我为聚类权重设置了一个阈值,以移除

为什么不是 K-Means?

虽然 K-Means 可能是其他应用程序中最著名和最常用的聚类算法,但它不太适合这个应用程序。

这样做的主要原因是,它仅适用于预期聚类具有非常规则的形状的情况,一旦不满足这一点,该模型就不能成功地分离聚类。

另一个原因是所有点都适合聚类,因此如果训练数据中有异常,这些点将属于聚类,并可能影响它们的质心,特别是聚类的半径。由于阈值距离的增加,这可能导致您无法检测到测试集中的异常。

另一种可能性是,你甚至会形成一个异常的集群,因为集群中的点数没有下限。如果你没有标签(你可能没有,否则有比聚类更好的方法),当新数据进来时,你可能认为它属于一个正常行为的聚类,而实际上它是一个完美定义的异常。

这种情况下的另一个缺点是需要事先指定聚类的数量,我们已经讨论过,在其他算法中有一些参数不容易调整,但我发现这一个特别棘手。由于我们的数据会随着时间而变化,所以聚类的数量也会变化,并且一旦我们将我们的模型部署到生产中,如果没有人的探索,就没有简单的方法来决定其他的。

怎样才能检测出测试数据中的异常?

对于 K-Means 来说,并非一切都是不好的,实际上这是测试阶段最简单的情况,因为我们有聚类的质心,形状预计会非常规则,我们只需要计算每个聚类的边界距离(通常最好不要选择到质心的最大距离,以防我们有异常值,根据您的数据,95%或 99%这样的值应该可以工作)。

然后,对于测试数据,计算到质心的距离。然后将该距离与每个聚类的边界进行比较,如果该点不属于任何聚类(距离>边界),则该点被归类为异常。

综上

我在这里介绍了一些聚类算法,并解释了如何使用它们进行异常检测(其中一些比其他方法更成功),显然这些不是唯一的方法,根据我处理的数据,我可能会偏向其中一些方法。

我真的认为 DBSCAN 和(贝叶斯)高斯混合模型是这个应用程序最有用的聚类算法。如果你刚开始接触异常检测,了解更多关于它们的信息是值得的,如果它们现在对你没有用,至少是你学到的新东西。

一些有趣的链接:

* [## DBSCAN:是什么?什么时候用?如何使用。

DBSCAN(带噪声的基于密度的应用程序空间聚类)是一种流行的无监督学习方法

medium.com](https://medium.com/@elutins/dbscan-what-is-it-when-to-use-it-how-to-use-it-8bd506293818) [## DBSCAN 如何工作,为什么要使用它?

首先,这是我在 medium 上的第一个故事,如果我做错了什么,我很抱歉。其次,我不太擅长…

towardsdatascience.com](/how-dbscan-works-and-why-should-i-use-it-443b4a191c80) [## 2.1.高斯混合模型-sci kit-学习 0.21.2 文档

高斯混合模型是一个概率模型,它假设所有的数据点都是从一个混合的高斯混合模型中产生的

scikit-learn.org](https://scikit-learn.org/stable/modules/mixture.html)

如果有更多的聚类算法,你发现有用的异常检测,我没有提到他们请让我知道,我很乐意扩大这个列表!

如果你想聊更多,请随时通过 LinkedIn 联系我!*

2020 年 Coursera 上的最佳数据科学课程

原文:https://towardsdatascience.com/best-data-science-courses-on-coursera-in-2020-f7de4ab414ff?source=collection_archive---------5-----------------------

如果你想提升你的数据科学职业生涯,选择什么课程

在线学习成为最受欢迎的学习形式之一。有了像数据营UdemyCoursera 这样的好平台,任何水平的人都能找到可以学习的东西。在这篇文章中,我想强调 Coursera 上目前提供的顶级数据科学课程。

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

Never stop learning! Increase your data science salary thanks to certification and new skills.

初级课程

你刚刚开始,你想学习 Python 的基础知识,以及如何编译你的第一个数据科学模型。你以前没有做过太多的数据科学或统计,你听说过一些术语,但这些对你来说只是时髦的词汇。你想从头开始积累你的知识。

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

密歇根大学的 Python 数据科学导论是目前最受欢迎的两门入门课程之一。它不做任何假设,你会从 Python 开始,然后遍历不同的数据结构(熊猫!)以及如何操纵它们。非常适合初学者。UMich 的另一门热门课程是 Python 数据结构,也是推荐给初学者的。

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

IBM 数据科学是由 9 门课程组成的专业证书。它从解释什么是数据科学,使用什么方法和工具开始,慢慢进入数据处理和数据可视化,最终达到机器学习。无论你是刚刚开始还是已经做了一点数据科学,这都是你简历上的一个很好的证明。

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

最后但同样重要的是,如果你想进入数据科学,你需要学习一些数学和统计学。不要担心,没有那么多,但你仍然应该对向量,矩阵的运算感到舒服,知道什么是均值,方差,偏差,并能够计算一些概率。这门课解释的就是:杜克大学的数据科学数学技能

中级课程

你已经有了一些经验,你已经开始对 Python 充满信心,你已经做了一些实验,现在你希望扩展你的知识。在这一点上,机器学习可能是你应该学会的。

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

华盛顿大学的机器学习专业是开始你的机器学习冒险的完美方式。本课程假设你精通 Python,了解数据结构,并带你了解机器学习的基本概念:分类和聚类算法。1 个专业的 4 门课程。

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

IBM 的应用人工智能课程是对深度学习和在云上部署深度学习模型的一个很好的探索。你将了解到像 Keras 和 Tensorflow 这样的深度学习框架(如果你还不知道的话)。这实际上是部署的问题。

专家课程

你至少有几年的经验,你是 Python 和使用数据科学提取信息的专家。您希望巩固您的知识,将它们放在一起,并了解数据科学的最新发展。

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

吴恩达在斯坦福大学开设的机器学习课程现在已经成为经典。Coursera 由吴恩达共同创建,这是该平台上的第一批课程之一。还有更多最新的课程,但这一门仍然很好地向你展示了机器学习背后的理论。强烈推荐!

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

由吴恩达再次创立的 deeplearning.ai 提供的深度学习专业化是一个获取关于深度学习及其应用的最新知识的地方。无论你想进入卷积神经网络,调整你的超参数或只是玩 LSTMs 本课程有一切。这绝对是我目前为止看到的最好的关于数据科学/机器学习这个层面的在线课程。

暂时就这样吧!

我希望你已经找到了你感兴趣的东西。如果您正在寻找学习数据科学的其他材料,请查看我关于您可能想要阅读的书籍的其他文章:

我也评论了一些适合数据科学家使用的笔记本电脑。

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

Data Science Job

最后,如果你想了解成为一名数据科学家意味着什么,那么看看我的书数据科学工作:如何成为一名数据科学家,它将指导你完成这个过程。

[## 加入我的时事通讯

技术、人工智能和数据科学新闻](https://creative-producer-9423.ck.page/c3b56f080d)

用 Scipy 线性化数据的最佳指数变换

原文:https://towardsdatascience.com/best-exponential-transformation-to-linearize-your-data-with-scipy-cca6110313a6?source=collection_archive---------13-----------------------

如何用 scipy 优化包找到拟合线性关系的最佳指数?

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

对于我们希望找到最优解的任何应用来说,迭代搜索都是必要的,但是问题的解不能以显式的形式表达。例如,机器学习中有很多算法使用迭代方法来寻找最佳参数集,如 Lasso 线性回归、梯度推进机器等。
在本文中,我们将尝试在 ETL 过程中使用数值方法,通过最佳指数变换将两个变量之间的非线性关系转换为线性关系。

作为一名数据科学家,我经常要检查不同变量之间的关系,并用它们总结一些关键指标。我最近遇到了一个评估发动机效率的项目,我想表达一种运输寿命期间的燃料消耗/速度比。案例研究变量之间的关系是非线性和单调递增的,所以我开始在谷歌上搜索是否有一种统计测试可以利用我的数据进行转换,使其更加线性,就像正态性的 box-cox 一样。
在这一点上,我想做一个实验:一个迭代过程,通过最小化一个成本函数线性化我的数据。
在我平时的工作中,我经常利用**scipy.optimize**模块寻找函数极小值,为什么不把它用于其他用途呢?
你可以更好地阅读官方文档中的**scipy.optimize**,其中提供了有用的解释和示例。

开始设置

在我的搜索中,我将重点放在了指数变换上,因为我们可以轻松地将指数设置为一个参数,并提供一个连续的探索范围。尽管这种选择排除了一些强非线性的界限,但它通常会返回好的结果。

让我们准备测试数据并创建两个相关变量 x,y ,其中 y 等于 x 的幂 e ,加上一些高斯噪声。为了方便起见,我也设置了依赖于指数的高斯噪声方差。

#test data setting
e = 2.465 #exp
x = np.arange(0,25,0.01)
y = x**e + np.random.normal(0,10**e,x.shape)

如果我们用**seaborn**回归图绘制数据,我们可以很容易地发现非线性关系。

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

成本函数

我们现在需要的是一个成本函数,一个我们想要最大化的线性关系的“好”的度量。一个很好的指标是皮尔逊积差相关系数 r ,它确定了两个变量之间线性相关的强度。
Pearson r 的取值在-1 和 1 之间,其中 1 为完全正线性相关,0 为无线性相关,1 揭示完全负线性相关;意思是 r = -1 和 r = 1 一样好。
因此,为了正确使用 Pearson r,我们将取其绝对取反值,因为**scipy.optimize**函数搜索最小值,而我们想要其最大值。

让我们定义成本函数:

#define cost function
def cost_function(e):
    #y and x are already defined
    r = np.corrcoef(y,x**e) #returns correlation matrix
    #print each iteration
    print('r value: {:0.4f} exp: {:.4f}'.format(r[0][1],e)) 
    return -abs(r[0][1])

优化功能

此时,我们必须调用其中一个 Scipy 方法。
合适的选择可能是**minimize_scalar**方法,因为我们的成本函数是标量函数。这个包背后的算法是 Brent 的方法,一个不需要梯度估计的求根算法。

我发现了一个非常详尽的视频,是奥斯卡·维利兹频道关于布伦特方法及其对德克尔和割线方法的依赖性的视频。检查出来,如果你想知道更多关于这一点,以及其他,优化功能。

让我们导入并调用**minimize_scalar**函数:

from scipy.optimize import minimize_scalarminimize_scalar(cost_function)

我们还可以设置一个搜索范围,避免指数的 0 值,这意味着 Pearson r 返回一个无效值,即使**numpy.corrcoeff** 可以处理它。

事实上,该系数定义为:

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

如果 x 被提升到 0,则标准偏差为 0,比率返回无效值。为了执行有界搜索,让我们调用:

minimize_scalar(cost_function,bounds=(0.1, 10), method='bounded')

结果列表如下:

r value: 0.9242 exp: 3.8815
r value: 0.8681 exp: 6.2185
r value: 0.9416 exp: 2.4371
r value: 0.9100 exp: 1.2663
r value: 0.9407 exp: 2.7565
r value: 0.9416 exp: 2.4255
r value: 0.9416 exp: 2.4861
r value: 0.9416 exp: 2.4815
r value: 0.9416 exp: 2.4819
r value: 0.9416 exp: 2.4819
r value: 0.9416 exp: 2.4819
r value: 0.9416 exp: 2.4819fun: -0.9416331392353501
 message: 'Solution found.'
    nfev: 12
  status: 0
 success: True
       x: 2.4818969221255713

仅仅 12 次迭代中,得到的指数是 2.482,非常接近我们用来生成数据的指数 2.465。

声音**fun**显示皮尔逊 r 的负绝对值的值,好像挺高的。让我们应用在 *x、*上找到的指数再次绘制 yx 我们将注意到一个强线性关系:

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

如果我们存储每个迭代指数和相关的皮尔逊系数,我们可以绘制 r-指数曲线。

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

其他测试

如果我们增加测试数据中噪音的影响会怎样?让我们在噪声发生器中增加高斯方差:

y = (x**e) + np.random.normal(0,20**e,x.shape)

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

优化函数的执行返回以下结果:

fun: -0.42597730774659237
 message: 'Solution found.'
    nfev: 13
  status: 0
 success: True
       x: 2.2958258442618553

找到的最佳指数不如以前的结果精确,但它仍然是一个很好的近似值。

噪声影响越大,由于噪声对岩心数据的影响越大,会导致错误的结果。

结论

优化方法是许多待开发应用的金矿。通过这篇文章,我不想教一种新技术,但我想促进这些有效方法在“不寻常”问题上的实验。

学习数据科学的最佳免费在线资源

原文:https://towardsdatascience.com/best-free-online-resources-for-learning-data-science-6dadb555b0c9?source=collection_archive---------19-----------------------

面向初学者和专业人士的数据科学学习资源综述

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

在完成生物信息学硕士学位后,我用 ML 研究了肠道中的微生物群落,我知道我的目标是在行业中找到一份数据科学家的工作,但也觉得我必须学习一段时间来准备面试,原因有两个:

1)在攻读理学硕士期间,我主要使用 Matlab 和一点 R,所以我不得不转向 Python 及其基本库。

2)例如,我对标准 ML 管道的一些主题和阶段不够熟悉——非常方便的是,我总是在一个非常有组织的表中接收我的数据,这些表具有已经设计和标准化的特征。然而,在现实世界中,大量的工作是找出如何通过特征工程将原始数据转换成表格数据。

在准备面试的过程中,我在网上找到了许多好的免费资源,其中大多数都提供入门级课程以及高级材料,对于已经在该领域工作的人来说,这些材料对进一步学习非常有用。在这篇博文中,我将与你分享我找到的最好的学习资源,所以不再多说——让我们开始吧。

1.谷歌的机器学习速成班 —这门课程彻底有效地将任何人——无论是初级 DS 还是完全的新手——带入机器和深度学习的世界,同时涵盖梯度下降和损失函数等重要概念,并介绍从线性回归到神经网络的主要算法。课程材料包括阅读材料、练习和笔记本,其中包含用 Tensorflow 实现并在 google Colab 上运行的真实代码,这意味着您无需安装即可运行它。

除了速成班之外,这个网站上还有大量关于数据科学和人工智能的材料,分为以下几类:

-课程-在这里,您可以找到对特定主题的深入探究,如聚类、推荐系统等。

  • Practica —“谷歌如何在产品中使用机器学习”的例子。

-指南—逐步指导常见 ML 问题的解决方案。

-词汇表-我最喜欢的资源,我认为每个数据科学家都应该在自己的桌面上放上这个。

链接:【https://developers.google.com/machine-learning/crash-course

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

2。 IBM 用 Python 实现的机器学习

本课程首先介绍两种主要类型的学习算法——有监督的和无监督的——之间的区别,然后对机器学习中的所有基本算法进行了很好的回顾,包括关于推荐系统的一章(我认为很有趣)。每章都以学习者可以在浏览器上运行的代码结尾,此外,一旦你完成了所有要求,你将收到一个徽章,以后可以在 LinkedIn、Twitter 等网站上分享。

链接到课程-

https://cognitive class . ai/courses/machine-learning-with-python

这里也有许多其他课程,涉及与数据科学家相关的许多主题,但也涉及与该领域没有直接联系但仍然有趣的其他主题,如区块链、反应式架构、比特币等。

链接到其他材料–

https://cognitiveclass.ai/courses

3。 AWS 的《数据科学的要素》

去年,亚马逊向其开发人员开放了在公司内运行的公共课程,结果是从 ML 基础知识到介绍其服务(例如 Neptune、ElastiCache)到使用 AWS 工具的特定应用程序(例如——使用 GluonCV 的计算机视觉、使用 QuickSight 的可视化)的各种主题的大量知识。

当我为 DS 面试做准备时,我发现他们的数据科学课程的元素非常有用,主要有两个原因,首先,它涵盖了从数据准备到模型培训和评估的标准 ML 管道的实践阶段,这很有帮助。 第二,每个主题都用实际的代码示例进行了介绍和解释,这些示例让我们对该领域的实际情况有了很好的了解,同时也展示了我不熟悉的 Pandas 和 Scikit Learn 的强大功能(您知道 SKlearn 包中有内置的数据集,您可以加载并用于您的个人实践吗? 我确实感谢这门课)。在这里,当你完成所有的要求时,你也会得到一个证书。

课程链接:

https://www.aws.training/Details/eLearning?id=26598

链接到所有材料:

https://www.aws.training/LearningLibrary?filters = language % 3a 1&search =&tab = digital _ courses

4。 快。艾

我必须承认,我从未完成这门课程,但我喜欢我做的部分,而且它非常受欢迎,所以我觉得有义务把它列入这个列表。在这里,您可以找到附有代码示例的长录音讲座(每次约 1.5 小时)。与列表中的其他课程相比,它们也有不同的课程,涵盖更高级的主题,包括计算机视觉和自然语言处理。我要说的是,当我第一次想开始这门课程时,我被它第一部分提到的技术要求吓住了,但后来我了解到所有笔记本都可以在 Google Colab 上运行,这意味着不需要安装和免费的 GPU。

课程链接–

https://www.fast.ai/

5。 摇摇晃晃学

Kaggle 是众所周知的获得数据科学实践经验的最佳场所,这要归功于它的大量有组织的数据集和许多竞赛,但它还有另一个很棒的部分,那就是他们的“学习”部分。你在这里会发现的并不完全是课程,而是如 Kaggle 自己所称的,带有许多互动练习的微型课程,旨在通过特定的库教授和提升从 Python for DS 到深度学习、SQL 和高级机器学习的所需技能。这可能是用最少的投入和时间扩展你的知识的最好方法。

https://www.kaggle.com/learn/overview

底线—数据科学是一个巨大的领域,有很多东西需要学习和了解,我敢说这里最重要的技能之一是保持更新和不断学习新技能和熟悉新技术的能力。我希望这些资源能对你的工作有所帮助,也希望在评论中听到其他有用的资源。

用 Python 进行蒙特卡罗模拟的最佳投资组合

原文:https://towardsdatascience.com/best-investment-portfolio-via-monte-carlo-simulation-in-python-53286f3fe93?source=collection_archive---------1-----------------------

从头到尾使用 Python 中的蒙特卡罗模拟寻找最佳投资组合

本文着重于通过蒙特卡罗模拟生成最优投资组合。我已经用 Python 实现了一个端到端的应用程序,本文记录了该解决方案,以便更多的读者能够从中受益。

文章将以通俗易懂的方式讲解投资管理所需的金融、数学和编程知识。

因此,这篇文章对数据科学家、程序员、数学家和那些对金融感兴趣的人很有用。

请阅读 fintech explainedisclaimer。这个应用程序是基于我的意见,他们可能是错误的。在投资之前,一定要向专业理财顾问寻求建议。

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

1.我们想达到什么目的?

假设我想投资 1000 美元一年。我所在的当地商业街银行提供的一年定期存款利率很低。因此,我对它提供的年回报率并不满意。因此,我决定投资股票,用我的 1000 美元购买不同公司的股票。尽管它们相对来说风险更大,但它们可能会帮助我在承担风险后获得更多回报。到目前为止,一切顺利。

我想以这样一种方式投资,即我可以通过承担最少的风险来获得最高的回报。对我来说,这是最佳投资组合,我将在本文中演示的应用程序将解释我们如何实现它。

代码上传到 Github 上,这里提供了链接

2.高层次的概念

我已经选择了 7 家有潜力的公司,我想通过购买它们的股票找到投资的最佳方式。

简而言之,我将执行以下步骤:

  • 我有兴趣将我的 1000 美元投资于以下 7 家公司的股票(资产):ZM、优步、SWI、RNG、CRWD、工作、SYMC。

注意:在我以后的文章中,我将用 Python 实现一个解决方案,它将决定我们应该投资的合适公司。它将使用传统的分析概念以及先进的机器学习概念。

  • 现在我们来问这个问题。我应该从我的 1000 美元投资资金中拿出多少来购买这些股票?传统上,新的投资者会平等地投资于他们的目标公司,但是资产可以互相转移,一些资产可能互相负相关。

因此,我们需要找到最佳的投资组合。最佳投资组合是以最低风险产生最高回报的投资组合。

  • 生成每一个可能的投资组合可能是压倒性的。因此,我将使用蒙特卡罗方法在 Python 中生成 10,000 多个不同的投资组合。

该方法围绕这样一个概念,即随着投资组合数量的增加,我们将更接近实际的最优投资组合。

  • 对于每个投资组合,我将生成其回报和风险。因此,我需要获取投资组合中每项资产的股票价格。
  • 最后,我将得出回报率/风险比,并从 10,000+个投资组合中选择回报率/风险比最高的投资组合。

这将是我们选择的最佳投资组合。

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

Photo by Ben White on Unsplash

注意:由于我对这个应用程序有很大的未来计划,我将以组件化的方式来架构和设计这个应用程序,以便这个应用程序在未来可以很容易地增强。我还将在本文中解释应用程序的架构和设计。

3.让我们开始吧:戴上我的金融帽子

  • 存在一种无风险利率,即投资者在不承担任何风险的情况下从其投资中获得的利率,例如购买政府国库券。
  • 风险和回报之间有一个权衡。如果投资者期望投资于比无风险利率风险更高的投资选择,那么他/她期望获得更多回报。这是为了补偿投资者承担的风险。到目前为止,这一切都说得通!
  • 投资者可以通过购买不同公司的股票开始他/她的投资之旅。让我从现在开始把这些交易称为 资产 。我们可以获得资产的历史股票价格,并计算它们的风险和回报。当我们开始在我们的投资组合中增加资产时,我们开始意识到这些资产中有一些是相互关联的。因此,资产可以彼此有关系,因此它们可以彼此一起移动。
  • 一个 投资组合 将资产组合在一起。我们知道,当资产组合在一起时,它们的净风险不仅仅是它们各自风险的简单总和。这里的诀窍是将投资组合视为一种资产,并计算其集体风险和回报。

阅读这篇解释投资管理如何运作的文章

[## 投资管理和因素

了解如何明智地投资

medium.com](https://medium.com/fintechexplained/investment-management-and-factors-ee9eb5aa0a24)

4.流程的 7 个步骤

概括地说,我们需要执行以下七个步骤,如下图所示:

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

这是我们的商业案例。我们需要实现的应用程序将以一种我们可以在未来轻松扩展和增强每个步骤的方式来执行这些步骤。我会在这篇文章中详细解释。

5.让我们专注于上述流程的第 5 步——风险和回报的衡量标准

对于每项资产,我们将生成以下衡量标准:

5.1.资产回报

第一步是计算你投资组合中资产的回报。

为了计算资产回报,我们需要执行以下两个步骤:

  1. 我们需要获取资产的历史每日价格

2.然后,我们需要通过计算以下等式来计算它们的几何收益:

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

产生回报是为了让我们能够标准化股票价格,以便进行比较。

5.2.资产预期平均收益

上面计算的资产回报都是二维的,因为有一个时间轴。我们现在需要计算一个数字来表示资产的收益。最常见的方法之一是计算回报的平均值,即预期回报。

为了计算资产预期平均收益,我们需要每只股票收益的均值:

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

5.3.从资产到投资组合预期收益

现在准备计算投资组合的预期收益。投资组合将资产组合在一起。投资组合中的资产已被分配了总投资额的一部分。例如,投资组合可能持有 40%的资产 ABC 和 60%的资产 DEF。

从资产的预期收益,我们可以计算出投资组合的预期收益。它通过计算加权平均值来计算:

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

5.4.投资组合风险

资产的风险可以用许多风险度量来计算。其中一个指标是标准差,它可以告诉我们资产的价格是如何偏离其均值的。例如,一些资产可能彼此负相关,这意味着随着第一个资产的价值下降,负相关资产的价值增加。这向我们表明,投资组合的风险不是单个资产风险的简单总和。

投资组合的波动性就是投资组合的风险。波动率的计算方法是使用以下公式计算每只股票收益的标准差以及每对股票之间的协方差:

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

在这种情况下,波动率是标准差,即投资组合的总风险。

标准差衡量平均值周围的值的离差。

5.5 使用夏普比率寻找最佳投资组合

我们本可以把钱投资到一个储蓄账户(无风险),在不承担任何风险的情况下获得回报。我们如何决定我们获得的回报是否值得我们承担的风险?因此,我们可以计算夏普比率。

最后一步是计算每个投资组合的夏普比率。夏普比率是相对于无风险利率的超额回报率,作为风险的相关衡量标准:

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

如果您想了解更多有关投资绩效衡量的信息,请阅读本文:

[## 我们如何衡量投资业绩?

解释我们如何评估和计算投资业绩

medium.com](https://medium.com/fintechexplained/how-do-we-measure-investment-performance-7970042c6ae8)

6.端到端运行 7 个步骤

为了简单起见,在我记录技术细节之前,我想一步一步地展示最终结果。我将采用自下而上的方法,因为这有助于我们更好地理解概念。

在这一节中,我将使用应用程序为每个步骤生成的可视图表来演示这个概念,以便我们可以更好地理解这个概念。

注意:我将在下面解释的所有数据都由代码自动保存在 Excel 电子表格中。

**6.1 最终结果:**展示最优组合

到目前为止,我们已经了解到,该应用程序将获取我们选择的 7 家公司的历史股票价格。然后,它将通过计算每个投资组合的回报、风险和夏普比率,生成 10,000+个投资组合。

在这些投资组合中,它将指明以下三个投资组合:

  1. **具有最大夏普比率的投资组合。**这是我们的最佳投资组合
  2. 风险最小的投资组合。这是为那些有风险意识但不想承担高风险的投资者准备的投资组合。
  3. 对每项资产的投资平均分配的投资组合。如果我不使用这个应用程序,我会盲目地在资产中平均分配我的投资。因此,这个投资组合将表明,同等投资是否比我所有的其他选择表现更好。

因此,总共将有 10,001 个投资组合:

  1. 资产平均分配的投资组合
  2. 10,000 个随机生成的投资组合

我执行应用程序后,显示了 10’001 个投资组合及其风险回报权衡:

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

我们来回顾一下图表:

每个圈都是一个独特的投资组合。x 轴是风险,y 轴是投资组合的回报。投资组合的颜色是夏普比率。

我们可以看到,这种关系并不是完全线性的。当投资者将资产组合在一个投资组合中时,资产的同步运动可以帮助我们分散风险,这就是所谓的风险回报权衡。图表上有三颗钻石:

  1. **绿钻组合:**这是我们选择的最优组合。对于每个投资组合,我们生成夏普比率。这是夏普比率最大的投资组合。它以最低的风险给了我们最高的回报。这个投资组合被命名为投资组合 2187。
  2. **黑钻石投资组合:**这是我们平均分配的投资组合。我们可以看到平均分配的投资组合处于中间位置。它不如标有绿钻的投资组合 2187。我们还可以看到,如果我们平等地投资,对于同样的风险,有许多投资组合会产生更高的回报。因此,这意味着应用程序为我们生成了优秀的投资组合。事实上,所有位于 y 轴黑钻石上方、x 轴价值相同的投资组合都是比平均分配投资组合更好的投资组合,因为对于相同的风险,它们会产生更高的回报。
  3. 红钻组合:这是产生最低风险的组合。

这些是投资组合 2187 的细节。

需要注意的两个要点是:

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

  1. 它建议我们不要在工作上投资。
  2. 这也突显出,我们应该将大部分资金投资于 RNG 和 CRWD。

通过承担 41%的风险,投资组合的投资组合回报率为 130%。它的夏普比率大约是 316% (=130/41)。

6.2 第一步是获取股票价格

我们构建了一个获取过去 3 年历史股票价格的组件:

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

股票价格是时间序列数据。

这是代码存储在 excel 电子表格的 StockPrices 表中的数据快照,如下所示。

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

正如你所看到的,我们不能简单地比较 ZM 和 SYMC,因为它们的股票价格是不同的。因此,我们需要计算回报率来标准化股票价格。

6.3 然后我们需要产生回报

我们计算了每日几何收益:

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

返回的是时间序列数据。这是存储在 excel 电子表格的返回表中的数据的快照,如下所示。

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

注意:历史回报是正确的选择吗?我们是否应该制定不同的衡量标准?我将在未来实现一个优秀的应用程序,演示我们如何实现时间加权回报。

6.4 根据回报,我们需要生成协方差矩阵

然后,代码准备协方差矩阵:

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

协方差矩阵存储在 Excel 电子表格的协方差表中,如下所示:

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

6.5 下一步是生成 10001 个投资组合

代码生成 10’001 个投资组合,其中一个投资组合是我们在 7 项资产上平均分配投资的投资组合。对所有 10,000 个投资组合施加了一个约束,即它们的分配总和必须是 100%。这意味着我们只打算购买资产。

代码将投资组合绘制在风险回报图上,其中 y 轴是投资组合的回报,x 轴是投资组合的风险。

我们可以看到这三个投资组合都有标记。绿钻是我们的最佳投资组合。

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

投资组合存储在 Excel 电子表格的 MonteCarloPortfolios 表中,如下所示:

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

然后,我们可以找到投资组合 2187 的配置(我们的最佳投资组合如图所示),然后对该投资组合进行投资。

所有生成的投资组合的风险、回报和夏普比率存储在 MonteCarloPortfolioRatios 表中,如下所示:

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

7.让我们来设计应用程序:戴上我的技术帽子

最后,我将记录我实现的代码。

我将从解释如何架构和设计应用程序开始这一部分。我将详细解释每个组件和代码。

该应用程序的设计核心仅围绕一个概念:

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

当应用程序运行时,它将产生大量的数据,如股票价格、回报、协方差矩阵、投资组合及其分配以及风险、回报和夏普比率。Python 代码还会将所有这些数据保存在 Excel 电子表格中。

7.1 应用程序结构

请点击这里访问 GitHub 上的全部代码

以下文件夹结构是在 C: drive 中创建的。

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

以下 Python 文件放在code文件夹中

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

我们将在以后的文章中处理文档和测试文件夹。

7.2 让我们了解每个 Python 文件

Python 包

certify = = 2020 . 4 . 5 . 1
chardet = = 3 . 0 . 4
cycler = = 0 . 10 . 0
idna = = 2.9
kiwi solver = = 1 . 2 . 0
lxml = = 4 . 5 . 0
matplotlib = = 3 . 2 . 1
numpy = = 1 . 18 . 2
pandas = = 0 . 22 . 0
pandas-pandas

1.配置设置

目标是实现一个可配置的应用程序。未来的计划是实施更好的风险和回报指标。此外,我们希望代码自动获取正确的公司。

因此,我在代码中实现了一个存储可配置设置的区域:

文件名:settings.py

import numpy as np
import datetime as dt
from calculator import risk_return_calculatorclass settings:PriceEvent = 'Adj Close'
    ReturnType = 'Geometric'
    NumberOfPortfolios = 10000
    YearsToGoBack = 3
    RiskFreeRate = 0
    CompanyFetchMode = "PreFixed" #Auto
    MyCompanies = ['ZM','UBER','SWI','RNG','CRWD', 'WORK', 'SYMC']
    PortfolioOptimisationPath = 'C:\Temp\PortfolioOptimisation.xlsx'
    RiskFunction = risk_return_calculator.calculate_portfolio_risk
    ReturnFunction = risk_return_calculator.calculate_portfolio_expectedreturns
    AssetsExpectedReturnsFunction = risk_return_calculator.calculate_assets_expectedreturns
    AssetsCovarianceFunction = risk_return_calculator.calculate_assets_covariance
    DailyAssetsReturnsFunction = risk_return_calculator.calculate_daily_asset_returns[@staticmethod](http://twitter.com/staticmethod)
    def get_my_targets(min_risk):
        return np.arange(min_risk, 1.5, 0.05)[@staticmethod](http://twitter.com/staticmethod)
    def get_end_date():
        return dt.date.today()[@staticmethod](http://twitter.com/staticmethod)
    def get_start_date(end_date):
        return end_date - dt.timedelta(days=settings.YearsToGoBack*365)

需要注意的关键是,风险和回报函数,以及投资组合的数量和公司的符号都存储在这里。这将允许我们添加新的公司或生成新的投资组合,并改变风险函数,而不改变代码的其他部分。

当代码执行时,它将输出 excel 电子表格中的数据,这些数据将存储在PortfolioOptimisationPath = ‘C:\Temp\PortfolioOptimisation.xlsx’

2.对象工厂

该应用程序大量使用面向对象的设计。因此,在应用程序中实例化了许多对象。我们想从对象的使用中提取对象的创建。因此,对象工厂的职责是为我们实例化所需的对象。

如果我们想改变实现,那么我们只需要改变那里的逻辑。这将允许我们在将来轻松扩展功能。

文件名:object_factory.py

from chart_plotter import chart_plotter
from file_repository import file_repository
from monte_carlo_simulator import monte_carlo_simulator
from companies_extractor import static_companies_extractor as static_companies_extractor
from price_extractor import price_extractor
from calculator import metrics_calculatorclass object_factory:
    def __init__(self, settings):
        self.__settings = settings 

    def get_price_extractor(self, companies):
        return price_extractor(self.__settings.API, companies)def get_metrics_calculator(self):
        return metrics_calculatordef get_charts_plotter(self):
        return chart_plotter(self.get_metrics_calculator())def get_companies_extractor(self):
        return static_companies_extractor(self.__settings.MyCompanies)def get_portfolio_generator(self):
        return monte_carlo_simulator(self.get_metrics_calculator(), self.__settings.RiskFunction, self.__settings.ReturnFunction, self.__settings.NumberOfPortfolios)def get_file_repository(self):
        return file_repository(self.__settings.PortfolioOptimisationPath)

作为一个例子,在下一阶段,我们可以实现一个web_companies_extractor 类,通过删除维基百科网页来获取纳斯达克 100 公司的名称。我们所需要做的就是从函数get_companies_extractor()中返回web_companies_extractor,而不改变其余的代码。

3.公司提取器获取目标公司

公司提取器的唯一目的是返回一个数据框,其中填充了所有必需的公司信息。

文件名:companies_extractor.py

import pandas as pd
class static_companies_extractor:
    def __init__(self, my_companies):
        self.__my_companies = my_companiesdef get_companies_list(self, current_portfolio=None):
        return pd.DataFrame({'Ticker':self.__my_companies})

在这个实例中,顾名思义,静态公司提取器返回在 settings.py 文件中配置的公司的静态列表。

4.提取资产价格的价格提取器

价格提取器的目的是获取目标开始和结束日期所需资产的股票价格。

文件名:price_extractor.py

import pandas as pd
import numpy as np
import pandas_datareader.data as web
import matplotlib.pyplot as plt
import scipy.optimize as solver
import datetime as dt
from functools import reduceclass price_extractor:def __init__(self, api, companies):
        print('Initialised Price Extractor')
        self.__api = api
        self.__companies = companies
        passdef get_prices(self,  event, start_date, end_date):
        prices = pd.DataFrame()
        symbols = self.__companies['Ticker']
        tmp={}
        for i in symbols:
            try:
                tmp = web.DataReader(i, self.__api, start_date, end_date)
                print('Fetched prices for: '+i)                
            except:
                print('Issue getting prices for: '+i)
            else:
                prices[i] = tmp[event]            
        return prices

5.度量计算器计算夏普比率,并给我们我们的目标投资组合

文件名:calculator.py 第一类

class metrics_calculator:[@staticmethod](http://twitter.com/staticmethod)
    def calculate_sharpe_ratio(risk, returns, risk_free_rate):
        return (returns-risk_free_rate)/risk[@staticmethod](http://twitter.com/staticmethod)
    def get_max_sharpe_ratio(df):
        return df.ix[df['SharpeRatio'].astype(float).idxmax()][@staticmethod](http://twitter.com/staticmethod)
    def get_min_risk(df):
        return df.ix[df['Risk'].astype(float).idxmin()]

6.风险回报计算器,用于计算风险和回报

计算风险和回报的代码位于risk_return_calculator 类中。

文件名:calculator.py 第一类

import numpy as np
from functools import reduce
import pandas as pdclass risk_return_calculator:
    [@staticmethod](http://twitter.com/staticmethod)
    def calculate_assets_expectedreturns(returns):        
            return returns.mean() * 252[@staticmethod](http://twitter.com/staticmethod)
    def calculate_assets_covariance(returns):        
            return returns.cov() * 252[@staticmethod](http://twitter.com/staticmethod)
    def calculate_portfolio_expectedreturns(returns, allocations):
        return sum(returns * allocations)[@staticmethod](http://twitter.com/staticmethod)    
    def calculate_portfolio_risk(allocations, cov):
        return np.sqrt(reduce(np.dot, [allocations, cov, allocations.T]))[@staticmethod](http://twitter.com/staticmethod)
    def calculate_daily_asset_returns(stock_prices, return_type):
        return np.log(stock_prices / stock_prices.shift(1))

当我们引入高级风险指标时,我们将在这里添加指标,并相应地更改配置文件。这将允许我们在将来轻松地维护和增强这些特性。作为一个实例,我计划实现 EWMA 来计算资产的预期收益。我所要做的就是实现risk_return_calculator 中的方法,并指向settings.py 文件中所需的方法。

7.生成投资组合的蒙特卡罗模拟器

这是为我们生成 10,001 个投资组合的主要类。

文件名:monte_carlo_simulator.py

import pandas as pd
import numpy as npclass monte_carlo_simulator:
    def __init__(self, mc, risk_function, return_function, numberOfPortfolios):
        self.__numberOfPortfolios = numberOfPortfolios
        self.__risk_function = risk_function
        self.__return_function = return_function
        self.__mc = mcdef generate_portfolios(self, returns, covariance, risk_free_rate):

        portfolios_allocations_df = pd.DataFrame({'Symbol':returns.index,'MeanReturn':returns.values})
        extra_data = pd.DataFrame({'Symbol':['Return','Risk','SharpeRatio'], 'MeanReturn':[0,0,0]})
        portfolios_allocations_df = portfolios_allocations_df.append(extra_data, ignore_index=True)portfolio_size = len(returns.index)
        np.random.seed(0)#Adding equal allocation so I can assess how good/bad it is
        equal_allocations = self.get_equal_allocations(portfolio_size)
        portfolio_id = 'EqualAllocationPortfolio'
        self.compute_portfolio_risk_return_sharpe_ratio(portfolio_id, equal_allocations, portfolios_allocations_df, returns, covariance, risk_free_rate)#Generating portfolios        
        for i in range(self.__numberOfPortfolios):
            portfolio_id = 'Portfolio_'+str(i)
            allocations = self.get_random_allocations(portfolio_size)
            self.compute_portfolio_risk_return_sharpe_ratio(portfolio_id, allocations, portfolios_allocations_df,returns, covariance, risk_free_rate)
        return portfolios_allocations_dfdef compute_portfolio_risk_return_sharpe_ratio(self, portfolio_id, allocations, portfolios_allocations_df, returns, covariance, risk_free_rate):

        #Calculate expected returns of portfolio
        expected_returns = self.__return_function(returns, allocations)
        #Calculate risk of portfolio
        risk = self.__risk_function(allocations,covariance)
        #Calculate Sharpe ratio of portfolio
        sharpe_ratio = self.__mc.calculate_sharpe_ratio(risk, expected_returns, risk_free_rate)

        portfolio_data = allocations
        portfolio_data = np.append(portfolio_data,expected_returns)
        portfolio_data = np.append(portfolio_data,risk)
        portfolio_data = np.append(portfolio_data,sharpe_ratio)
        #add data to the dataframe            
        portfolios_allocations_df[portfolio_id] = portfolio_datadef get_equal_allocations(self, portfolio_size):
        n = float(1/portfolio_size)
        allocations = np.repeat(n, portfolio_size)
        return allocationsdef get_random_allocations(self, portfolio_size):

        allocations = np.random.rand(portfolio_size)
        allocations /= sum(allocations)
        return allocations

需要注意的关键是,它是用风险和回报函数实例化的。它只是生成一个分配相等的投资组合和 10,000 个分配随机生成的投资组合。每个投资组合的分配总和是 100%,这意味着我们只对购买资产感兴趣。

然后计算每个投资组合的风险、回报和夏普比率。

8.图表绘图仪绘制投资组合并标记最佳投资组合

这个文件为我们准备了所需的图表。

文件名:chart_plotter.py

import matplotlib.pyplot as pltclass chart_plotter:def __init__(self, mc):
        self.__mc = mcdef show_plots(self):
        plt.show()def plot_single_point(self, x,y,title,colour):
        plt.scatter(x=x, y=y, c=colour, marker='D', s=200)
        plt.annotate(title, # this is the text
                 (x,y), # this is the point to label
                 textcoords="offset points", # how to position the text
                 xytext=(0,10), # distance from text to points (x,y)
                 ha='center') # horizontal alignment can be left, right or centerdef plot_portfolios(self, df):
        # find min Volatility & max sharpe values in the dataframe (df)

        max_sharpe_ratio = self.__mc.get_max_sharpe_ratio(df)
        min_risk = self.__mc.get_min_risk(df)plt.scatter(df['Risk'], df['Return'],c=df['SharpeRatio'],cmap='RdYlGn', edgecolors='black')
        x = max_sharpe_ratio['Risk']
        y = max_sharpe_ratio['Return']
        name = max_sharpe_ratio['Portfolio']

        plt.title(str(len(df))+" Portfolios Risk-Return")
        plt.xlabel("Risk")
        plt.ylabel("Return")self.plot_single_point(x,y,'Max Sharpe Ratio: '+name, 'green')
        x = min_risk['Risk']
        y = min_risk['Return']
        name = min_risk['Portfolio']
        self.plot_single_point(x,y,'Min Risk: '+name, 'red')equal_allocations_portfolio = df.loc[df['Portfolio'] == 'EqualAllocationPortfolio']
        x = equal_allocations_portfolio['Risk'].values[0]
        y = equal_allocations_portfolio['Return'].values[0]
        name = equal_allocations_portfolio['Portfolio'].values[0]
        self.plot_single_point(x,y,'Portfolio: '+name, 'black')def plot_prices(self, closing_prices):
        ax = plt.gca()
        columns = [c for c in closing_prices.columns if c not in 'Date']
        closing_prices.plot(kind='line',use_index=True,y=columns,ax=ax, title='Asset (Stock) Prices')
        plt.show()def plot_returns(self, returns):
        ax = plt.gca()
        columns = [c for c in returns.columns if c not in 'Date']
        returns.plot(kind='line',use_index=True, y=columns,ax=ax, title='Asset (Stock) Returns')
        plt.show()def plot_correlation_matrix(self, df):
        cols = df.columns.values
        fig = plt.figure()
        ax = fig.add_subplot(111)
        cax = ax.matshow(df.corr(), interpolation='nearest')
        fig.colorbar(cax)ax.set_xticklabels(cols)
        ax.set_yticklabels(cols)
        plt.show()

9.文件存储库将所有数据保存在一个文件中

中间数据和最终投资组合一起存储在一个 excel 文件中。数据的保存由文件存储库执行。

文件名:file_repository.py

import pandas as pdclass file_repository:def __init__(self, directory):
        self.__writer = pd.ExcelWriter(directory, engine='xlsxwriter')def save_to_file(self, data, sheet_name=None):        
        data.to_excel (self.__writer, sheet_name=sheet_name, header=True)def close(self):
        self.__writer.save()

10.地图绘制者

蒙特卡洛模拟器在具有以下形状的数据框架中为每个投资组合生成分配以及风险、回报和夏普比率:

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

然而,海图绘制者期望风险、回报和夏普比率的 3x1D 阵列:

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

映射器将蒙特卡洛模拟器输出的数据映射为海图绘图仪所需的输入格式。

这是单一责任模式的一个例子。每个组件/类都有自己明确的职责。这个特性允许我们在将来轻松地维护和扩展应用程序。

文件名:mappers.py

import pandas as pd
class portfolios_allocation_mapper:
    [@staticmethod](http://twitter.com/staticmethod)
    def map_to_risk_return_ratios(input):
        portfolios = input.columns.values[2:]
        returns = input.loc[input['Symbol'] == 'Return'].values[0][2:]
        risks = input.loc[input['Symbol'] == 'Risk'].values[0][2:]
        sharpe_ratios = input.loc[input['Symbol'] == 'SharpeRatio'].values[0][2:]
        df = pd.DataFrame(
            {'Portfolio': portfolios,
            'Return': returns,
            'Risk': risks, 
            'SharpeRatio': sharpe_ratios})
        return df

11.最后一部分——主文件——胶水

当我们开始这篇文章时,我们概述了这个过程的 7 个步骤。

主文件按照正确的顺序执行这些步骤

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

我们是如何实现的?

我们实现了一个 Main.py 文件,它运行上述所有步骤:

from settings import settings
from object_factory import object_factory
from mappers import portfolios_allocation_mapperdef generate_optimum_portfolio():#instantiate the objects with the settings
    obj_factory = object_factory(settings)
    ce = obj_factory.get_companies_extractor()
    cp = obj_factory.get_charts_plotter()
    mcs = obj_factory.get_portfolio_generator()
    fr = obj_factory.get_file_repository()
    mc = obj_factory.get_metrics_calculator()#1\. Get companies
    companies = ce.get_companies_list()#2\. Get company stock prices

    end_date = settings.get_end_date()
    start_date = settings.get_start_date(end_date)
    closing_prices = obj_factory.get_price_extractor(companies).get_prices(settings.PriceEvent, start_date, end_date)#plot stock prices & save data to a file
    cp.plot_prices(closing_prices)    
    fr.save_to_file(closing_prices, 'StockPrices')#3\. Calculate Daily Returns    
    returns = settings.DailyAssetsReturnsFunction(closing_prices, settings.ReturnType)
    #plot stock prices & save data to a file
    cp.plot_returns(returns)
    fr.save_to_file(returns, 'Returns')#4\. Calculate Expected Mean Return & Covariance
    expected_returns = settings.AssetsExpectedReturnsFunction(returns)
    covariance = settings.AssetsCovarianceFunction(returns)
    #Plot & Save covariance to file
    cp.plot_correlation_matrix(returns)
    fr.save_to_file(covariance, 'Covariances')#5\. Use Monte Carlo Simulation
    #Generate portfolios with allocations
    portfolios_allocations_df = mcs.generate_portfolios(expected_returns, covariance, settings.RiskFreeRate)
    portfolio_risk_return_ratio_df = portfolios_allocation_mapper.map_to_risk_return_ratios(portfolios_allocations_df)

    #Plot portfolios, print max sharpe portfolio & save data
    cp.plot_portfolios(portfolio_risk_return_ratio_df)
    max_sharpe_portfolio = mc.get_max_sharpe_ratio(portfolio_risk_return_ratio_df)['Portfolio']
    max_shape_ratio_allocations = portfolios_allocations_df[[ 'Symbol', max_sharpe_portfolio]]
    print(max_shape_ratio_allocations)
    fr.save_to_file(portfolios_allocations_df, 'MonteCarloPortfolios')
    fr.save_to_file(portfolio_risk_return_ratio_df, 'MonteCarloPortfolioRatios')   

  fr.close()
#This function will execute the steps abovegenerate_optimum_portfolio()

注意函数generate_optimum_portfolio() 按正确的顺序执行步骤:

  1. 它首先实例化所需的对象
  2. 获取公司提取器以获取所需的公司。
  3. 获取价格提取器以检索资产价格
  4. 计算资产的日收益和协方差
  5. 调用蒙特卡洛模拟器生成投资组合及其回报、风险和夏普比率。
  6. 然后,绘图仪绘制所需的数据,文件存储库保存数据以供分析。

此功能演示了我们如何实现一个解决方案,将任务委托给负责执行其职责的功能。然后它帮助我们构建一个可维护的应用程序。

7.3.GitHub 中的完整代码

请点击此处访问 GitHub 上的完整代码

8.后续步骤

这是一个可行的解决方案,可以让我们获得最佳的投资组合。现在框架已经构建好了,我们可以轻松地增强它。我将添加以下功能:

  1. 使用优化器来建立一个有效的边界。这将通过先进的优化技术产生大量优秀的投资组合。
  2. 扩展 companies extractor 以生成包含所有 NASDAQ 100 公司的投资组合。
  3. 实施卓越的风险和回报措施,以及前瞻性协方差矩阵。
  4. 使用数据科学和机器学习的概念来帮助我们获得卓越和最佳的投资组合。
  5. 构建一个应用程序,为我们找到前 x 名,例如 10 家公司,然后运行最佳投资组合应用程序。

9.摘要

如果您希望看到这些后续步骤得以实施,请告诉我。此外,让我知道你如何喜欢这篇文章。

本文的重点是通过蒙特卡罗模拟生成最优投资组合。我已经用 Python 实现了一个端到端的应用程序,本文记录了该解决方案,以便更多的读者能够从中受益。

文章还深入浅出地解释了投资管理所需的金融、数学和编程知识。

希望有帮助。

注来自《走向数据科学》的编辑: 虽然我们允许独立作者根据我们的 规则和指导方针 发表文章,但我们不认可每个作者的贡献。你不应该在没有寻求专业建议的情况下依赖一个作者的作品。详见我们的 读者术语

朱莉娅是量化金融的最佳语言吗?

原文:https://towardsdatascience.com/best-language-for-quantitative-finance-here-are-my-findings-f1f458be48b7?source=collection_archive---------5-----------------------

在过去的几个月里,我一直在研究日内量化策略。附带的结果是,我用 Python、C、Fortran 和 Julia 测试了类似任务的工作流。这是我的发现。

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

背景

为了给出已测试项目性质的背景,我将开始澄清:

  1. 这些项目与工具交易相关(即我设计和模拟衍生品市场算法/量化策略)。
  2. 我没有在这些策略中使用机器学习或人工智能技术,只是简单的统计和模拟。
  3. 处理的数据集很大,但并不庞大,通常我的模拟涵盖每个资产/工具的 3000 万个记录数据集,每个数据都使用多次,我做参数和蒙特卡罗分析。这意味着大量的迭代。
  4. 我不是专业的程序员,也不想成为一名程序员,我只想专注于市场逻辑和利用有利可图的优势的策略。

我的任务是找到一个合适的工具组合,既能表现得足够好,又能简化我的工作流程。因此,审查是基于这些技术的最终用户的观点。

这种情况有一些含义:

  1. 我需要一种可以轻松处理大型数据集的语言。
  2. 我需要速度。
  3. 我不需要那么高的速度来要求多核或并行处理。
  4. 我现在不需要机器学习或人工智能库。

这篇文章是我寻找最佳工作流程之旅的成果。这是对每种语言的优势和劣势的一种主观但有根据的看法。我希望你觉得有用和愉快。

开端:Python 和 R

接近这个领域意味着你可能会从 Python 或 R 开始,我也是。

早在数据科学术语出现之前,r 语言就已经是科学/学术团体进行统计的自然选择。r 是 S 语言的开源实现,它是 70 年代在贝尔实验室创建的。虽然 R 是革命性的,非常适合统计学,但我发现它很难掌握,并且在处理大型数据集时效率极低。我无法完成简单的任务,例如从 CSV 加载几年来的整个价格集。

交易模拟通常需要大量数据,如果您需要提前开始拆分数据,或者寻找其他加载方法,或者只是加载过程复杂,那么探索其他选项是值得的。这并不意味着 R 不能应付它,只是我不觉得它简单明了。数据加载是数据分析不可或缺的一部分,应开箱即用。

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

Quantitative finance ends up having large data sets. Storing and loading large amounts of data for simulation is necessary

令人惊讶的是,像加载一个平均/大尺寸的 CSV 这样的基本任务对于某些现代语言来说可能是一个障碍。将一个 200Mb 的 CSV 文件加载到内存中可能会在每次分析的第一阶段显示出一些弱点:数据加载和准备。

在过去的几年里,Python 一直是我的中小型项目的伙伴语言。Python 易于学习,易于编码,当与 Numpy 和 Pandas 结合使用时,在数据科学领域享有良好的声誉。Jupyter 作为一个交互式控制台也有助于使 Python 成为数据科学项目中最广泛选择的语言之一。它的成功部分是因为它是一种广泛使用的通用语言,也可以用于数据科学。这使得它对有编程背景的新人更有吸引力。

虽然 Python 很简单,但我们不能忘记 Numpy 和 Pandas 是通过外部库对该语言的扩展。它们不是语言的自然组成部分。Python 也是一种缓慢的数字处理器,因为它被设计成一种非常高级的松散类型语言。Python 爱好者会说你可以改进它,现代 Python 有 Cython 这样的东西和无数的解决方案。但如果我必须处理数字运算,我更喜欢自然的数字运算。

Python 中最有用的一点是使用数据帧的概念。DataFrames 是一个出色的策略,我已经将它融入到我的工作流程中(即使在使用普通数组执行密集的数字处理分析时)。数据框架允许在模拟/分析过程中丰富、调试和可视化所有工作流程。我将它们作为一个管道,模拟的不同步骤将它们的结果添加到分析中。我喜欢把它们想象成一个列表板,所有的结果、分数、测试和条件都被标注并在不同的模拟阶段之间传递。每个阶段都使用以前的数据,并将数据添加到板上,在模拟结束时,数据帧包含评估模拟策略的所有信息。

在使用 Python 的第一次测试中,我在加载大型数据集时遇到了很多问题,尤其是在我为此任务分配的小型服务器中。我也经历了糟糕的表现。虽然很容易得到一个更强大的服务器,但我决定让 C 试试。

C/C++

用 C 是不会错的。C 是成熟的,它几乎可以做任何事情,并且提供非常高效的代码。自从 ANSI C 标准在 1989 年制定以来,C 语言并没有实质性的改变。现代标准增加了功能、更可移植的数据类型和其他特性,但对于模拟来说,即使旧标准也适用。C++被广泛使用,但是面向对象的范例在这类任务中没有提供价值。我认为它的使用更多地与年轻人学习 C++而不是 C 有关,而不是与面向对象范例在这个特定领域的实际好处有关。

C 的主要问题是很难用它做复杂的事情。对于小的算法例程来说,它大放异彩,而要让它执行缓慢实际上是相当困难的。但最大的问题是速度和性能是通过指针来实现的,调试指针可能很有挑战性。

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

C/C++ language is widely used in HFT industry. It is the preferred choice when performance is paramount. OpenMP & MPI standards allow to easily implement parallel computing in C.

我开始开发一个 C 库来帮助模拟测试,当我设法得到合适的结果时,我注意到随着项目越来越大,调试的时间和复杂性在缓慢但稳定地增长。当这种情况发生时,这是一个早期的警告,表明项目在复杂性方面获得了太多的权重。我可能想用 c 做太多了。

c 是一个杰出的工具,它在 HFT 工业中被广泛使用,因为它是一个自然的执行者,但是你必须准备好应对需要熟练资源的长期项目。此外,某些在 Python 等语言中非常简单的任务在 c 语言中可能非常具有挑战性。调试也是一个大问题,这一点已经说过了。

Python + NumPy +熊猫

一旦我意识到用 C 做任何事情的复杂性,我就回到 Python,试图找到一种使用更小的子集和 SQL 的变通方法。这也有助于当时一位同事向我展示了一个名为back trader的库,我们花了几个联合会议来实施一些测试,我提议分析 DAX 开盘。

Backtrader 被证明是缓慢的,有时是一种负担,但它也有助于检测工作流程中的一些早期需求。如果您想要现成的东西,并且愿意为性能和定制付出代价,那么这是一个很好的库。根据我的经验,如果你在这个行业,你最终会想要一些更具体的策略。

有了从这些经历中获得的信息,我设法用 Jupyter 在 Python 中完全实现了所有东西,第一个策略也完全实现了。

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

Python is the cool chap of Data Science. While it is not the best in terms of performance. It is easy to learn and code language and can be applied to many different areas. In the last years it has become the preferred Data Science platform.

虽然看到积极的和不断增长的权益曲线是一件非常高兴的事情,但我注意到工作流程中存在严重的瓶颈。这个模拟对朱庇特来说太大了。我发现在 Jupyter 中包含蒙特卡罗或参数分析并不自然,也不清楚如何实现报告以交叉验证结果并确保在编程阶段没有错误。

Python 对于这项任务来说总体上也非常慢,而 Jupyter 在小型项目中被证明是一个很好的助手,但是在大型模拟中有点难以理解。

从所有问题来看,主要的问题显然是性能和代码缺乏结构。

声称在 2019 年进行结构化编程可能会被视为不合时宜,但事实上模拟程序与 80 年代的结构化编程有许多共同的根源。对于这些特定的任务,像面向对象或函数式编程这样的概念是不必要的复杂层次,我发现基本的、普通的、简单的结构化编程是解决这类问题的好方法。

我发现很难在 Python 中正确地构造代码;包/模块实现落后于 Python 在其他领域提供的简单性的平均水平。不过这是个人观点。

使用 Python 进行调试一如既往地简单,事实证明,与以前的 C 解决方案相比,这是一个很大的改进。

Python + C

下一个合乎逻辑的步骤是用 C 语言替换 Python 中速度较慢的部分。根据我第一次尝试纯 C 语言解决方案所获得的经验,我定义了一个例程层来处理模拟本身。由于这是集中在核心模拟例程更简单,因此更容易在 C 中调试和实现,而 Python 负责协调其他一切。

编排模拟工作流不需要速度,Python 提供了更友好的环境。C 例程打包在一个共享库(Windows 的 DLL,Unix 的 shared object)中,稍后使用 CTypes 从 Python 调用它。

这种结合使得 C 能够在 200/300 毫秒内通过序列化完成预加载所有数据(3000 万条记录)这样的事情——这只是为了举例说明 C 有多快。当不使用序列化时,CSV 读取也非常快,因为使用了固定长度的记录(比使用 Python 快得多)。在这样的速度下,不需要使用任何数据库。它只是一个普通的文件和内存。其余的统计分析也非常快,因为 C 允许通过使用指针和数组来实现快速算法。这种设置的瓶颈总是 Python 中的 Matplotlib。

在我看来,将 Python 和 C 语言结合起来是一个双赢的解决方案,可以让你两全其美。

FORTRAN 语言

我决定付出额外的努力来测试另外两种语言:Fortran 和 Julia。目标是在同一种语言中加入高级模拟工作流编码和低级回溯测试例程。尽管它远不是一种流行的语言,但我首先评估了 Fortran。

Fortran 是最古老的编程语言之一。撇开 COBOL 不谈,它可能是最古老的。虽然它曾经是科学和工程分析的首选,但在 90 年代它基本上被 Matlab 取代,但它在计算要求高的科学领域仍然保持强劲。

Fortran 现在是一种小众语言(目前在世界上最常用的编程语言列表中排名第 30 位),但它在高能物理、天体物理和分子动力学等专业领域仍然有活跃的社区。与 C 一起,它也是超级计算的主要编程语言。OpenMP 和 MPI 等标准定义了在内核和分布式计算机之间分配计算的方法,它们总是首先为 C 和 Fortran 实现。

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

If you think Fortran is dead, think twice. Astronomy, climate modelling, computational chemistry, fluid dynamics, physics, hydrological modelling, structural engineering, all of them use Fortran.

虽然现代 Fortran 与大多数人所想的(大写代码、goto 指令和穿孔卡片)毫无关系,但它的语法显示出了一些年龄。它允许一个好的代码结构,并且很容易学习(甚至是掌握)。我在将最后一个模拟移植到 Fortran 时的经验是,编码很容易,特别是用 C 编写的算法部分更容易用 Fortran 编写。结构化代码也优于 Python,尽管这是个人观点,我知道很多人不同意这种说法。

还有一些问题:与图形工具的集成更加困难,以及变量需要提前声明的事实(这是我不喜欢的),但在我看来,主要问题是调试非常困难,因为 Fortran 最终会调用 C 编译器。所以我的经验是调试 Fortran 比调试 Python+C 解决方案要难一些。

从积极的方面来看,Fortran 也有一些独特的解决方案来处理数组和结构化数据,其中包括自定义索引——array[2000:2020]是一个有效的索引范围,这是其他语言无法实现的——向量运算和初始化变量和结构的简单方法。

如果您需要速度并计划进行需要多 CPU 和/或多核的分析(HFT 工业界大量使用 C++),那么 Fortran 或 C 是合适的选择,AMD 和 Intel 保持其编译器部门同时销售 C++和 Fortran 编译器也不是偶然的。但是如果你不需要那么快的速度,最好是牺牲一些性能来换取一个更友好、更容易调试的环境和使用数据帧的可能性。

Fortran 性能惊人。Fortran 能够从一个 CSV 文件中读取一整年的价格,将它们转换为整数以避免精度损失,将它们向下舍入为合约价格,并在大约 1 秒钟内将它们存储到内存中。这意味着使用 20 年 1 分钟价格的策略将被载入内存,并准备在 20 秒内使用。它比我尝试过的任何其他语言都要好。

它对数组的自然使用也使得计算速度非常快。在许多运算中,Fortran 优于 c。信不信由你,60 年后,它仍然是头号数字处理器,它的结构非常适合模拟问题,因为它在设计时就考虑了这类问题。

朱莉娅,新来的

我最后尝试的语言是茱莉亚。随着经验的积累,以及 Julia 承诺用 C 语言的速度提供 Python 和 Pandas 的简单性,尝试 Julia 是必须的。

我发现这种语言很容易学习,而且结构合理。语法清晰,不啰嗦,一目了然。模块允许(一旦你理解了它们)充分地分离代码,就像它们分离域和变量一样。模块还允许轻松共享全局变量。

这种语言的某些方面在开始时有点令人费解。花了一些时间去理解什么是可变的,什么是不可变的。变量既不通过引用也不通过值传递,而是绑定到特定的对象。这样,如果我正确理解了这个机制,它就类似于 Python。

这种语言足够灵活,允许您强制使用类型(我发现这在这个领域很有用,因为它有助于优化内存使用和性能),但对于少量使用,如果您不想指定类型,则不需要指定类型。时间戳处理也非常简单,这与这个行业相关。

使用 Julia 感觉你是一个新技术的早期采用者。主要的担心是稳定性,而且你也要面对一个事实,那就是大多数人会选择 Python。

Julia 将向量符号和数据帧作为语言的一部分。事实上,数据帧并不是语言的一部分,而是作为一个库并入的——就像 Python 中的 Pandas 一样——但感觉上它们是语言的一部分,这是我在使用 Pandas 时没有体验到的。

数据加载比其他语言稍慢,但是我使用 CSV 和一个辅助数据帧来解析输入数据。通过直接转换和使用固定长度,我确信可以获得更好的性能。执行计算所需的总时间接近 C,所以一般来说,您不会注意到任何差异。

Julia 可能不像其他语言那样稳定和成熟。在我的 BSD 工作站上,我不得不直接从网站上下载最新版本,因为默认包含在发行版中的版本无法正确编译软件包。

正如已经提到的,Julia 易于编码并且相对容易学习——一旦你克服了语言的一些不太直观的方面,例如可变性/不变性、变量范围和模块如何工作。优点是数据帧和向量操作比 Python 更好地结合在一起。Julia 预先编译了代码,并且它被设计得很快。包安装服务也比 Python 更好地集成了。

总的来说,我的感觉是朱莉娅是这项任务的合适工具。它是现代的,易于学习,它更好地结合了操作矢量和数据帧的功能,性能远远优于 Python。它免除了您使用 C 代码(更难调试)或 Fortran(在行业中可能被视为更奇特的语言)的麻烦。唯一担心的是,由于不够成熟,你可能会担心大型项目中的问题,甚至是计算错误。我还没有发现这些,但我也没有花足够的时间学习这门语言。

摘要

定量金融学中发现的问题与科学模拟中发现的问题非常相似。

工作流程、向量运算、调试、代码清晰度、数据帧的存在和性能等方面是决定语言是否适合这项任务的关键因素。

对于要求最高的任务,C 和 Fortran 保持了成熟解决方案的地位,但它们在技能方面要求很高。Fortran 可能在这个特定的行业中并不常用,但是如果您想使用它,它非常适合。

对于较轻的用途,Python 是最简单的方法,但是对于某些任务来说,它会很慢。当使用 C 编写核心模拟任务时,Python 和 C 的结合可以很好地权衡简单性和性能。

茱莉亚是极有前途的,干净快速的语言。虽然我没有在这门语言上花足够的时间,但我觉得它可能是这份特殊工作的合适工具,因为缺乏成熟度是我指出的最大担忧。除此之外,它结合了所有现代功能和优势,这是有用的定量金融,它很容易学习,非常快。

对于资金充足的大型机构来说,这可能不是正确的选择,因为它可能被视为一个有风险的提议,但另一方面,个人和较小的组织可以通过早期采用来获得竞争优势。我个人的观点是,这是值得探索的,因为它可以有助于建立一个生产级的战略开发和分析工作流程,这是你想在这个行业长期需要的东西。

当 Pytorch-transformers 遇上 Fastai (w/ Google Colab)

原文:https://towardsdatascience.com/best-of-two-worlds-pytorch-transformers-meets-fastai-5fd51ef34b0f?source=collection_archive---------19-----------------------

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

Photo from Kapa65 at Pixabay

更新:

在我发表这篇文章后,我有幸得到了 fastai 创始人之一杰瑞米·霍华德的回应,他建议我们可以使用 fastai 的回调系统来简化这里的工作,而无需调整 fastai 库中的基本训练循环。

这似乎是一个简单的解决办法,然而,我已经尝试了很长时间(在 @waydegilli am 的帮助下),但并不能完全正确(训练指标根本没有改善……)。我已经在 fastai 论坛上解决了这个问题,并且幸运地让 Sylvain 检查了代码。然而,度量仍然不动,训练循环无效。

为了您的方便,我已经用所有的结果编辑了一个 Google Colab,如果您对问题所在有任何想法,我将不胜感激:

[## 谷歌联合实验室

编辑描述

colab.research.google.com](https://colab.research.google.com/drive/1KFlyttLs7aAX35lMLiDw9Bb0s_74ILMy#scrollTo=NPgXRybJk2XN)

鉴于我在使用回调系统时遇到的小缺陷,下面的解决方案,看似“愚蠢”的改变训练循环的方式,仍然是合并 fastai 和 Pytorch-transformers 的最佳方式。

介绍

如果你关注深度学习的趋势,尤其是 NLP,你不可能没有听说过 Fastai 或 Pytorch-transformers 。这两个库为 NLP 实践者提供了友好的 API 和灵活的定制能力来进行原型设计和实验。Fastai 是一个通用的深度学习库,具有精心配置的 API,以适应各种应用程序:例如,文本,视觉,表格和协同过滤。Pytorch-transformers 是一个用于自然语言处理(NLP)的最新预训练模型库,包括 SOTA 模型,如 BERT 和 GPT2。同样值得注意的是,它们都是建立在 Pytorch 之上的,因此在它们之间建立连接不会太困难。考虑到这两个库的优点,把它们结合起来,这样我们就可以通过同时使用这两个包来简化建模过程,这不是很好吗?

答案是肯定的,并且在这篇精彩的文章中有详细的记录。本文提供了将数据集转换为特殊形式的过程,这样它就可以适合 BERT 模型,而这又可以通过使用 fastai API 进行微调。这篇文章也激发了下面这篇文章的写作,这篇文章比较了伯特和乌尔菲特的表现。

[## Fastai 与 BERT 的集成

序言

medium.com](https://medium.com/@abhikjha/fastai-integration-with-bert-a0a66b1cecbe)

上述文章在解释实现中的所有必要细节方面做了令人惊讶的工作,因此这篇文章不会进一步讨论,而是主要通过解决 Pytorch-transformers 库(来自 pytorch-pretrained-bert)的更新引起的一个关键问题来做出贡献。

我们有一个问题

在 Pytorch-transformers 更新之前,上面提供的解决方案和代码都运行良好。如果您浏览了更新之前撰写的上述文章中的代码。您可能会遇到这样一个异常:

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

如果你像我一样,对 Pytorch-transformers 没有太多经验,你可能会感到非常困惑,想知道为什么它对其他人有效,但对我的机器无效!在没有深入探究异常回溯的情况下,我认为这是因为我的手电筒过时了。我将 Torch 更新到了最新版本,但是仍然收到了异常。

在阅读 Pytorch-transformers 文档后,我意识到这个异常是由 Pytorch-transformers 包中 API 的变化引起的。简而言之,在 Pytorch-transformers 更新之前的日子里,model()会在网络向前传递之后产生结果;更新之后,模型的 forward 方法生成一个元组,其第一个元素是原始模型输出。如果你想了解更多细节,请阅读这里

# If you used to have this line in pytorch-pretrained-bert:
loss = model(input_ids, labels=labels)# Now just use this line in pytorch-transformers to extract the loss from the output tuple:
outputs = model(input_ids, labels=labels)
loss = outputs**[0]**

现在我们找到了代码中断的原因,让我们想出一个解决方案。

解决办法

解决方案是我们需要修改 Fastai 的代码,以适应 Pytorch-transformers 中model()行为的变化。

代码的关键部分是basic_train.py中的loss_batch(),我们可以看到model()输出不是一个元组,而是直接发送给损失函数。

def loss_batch(model:nn.Module, xb:Tensor, yb:Tensor, loss_func:OptLossFunc=None, opt:OptOptimizer=None,
cb_handler:Optional[CallbackHandler]=None)->Tuple[Union[Tensor,int,float,str]]:
    "Calculate loss and metrics for a batch, call out to callbacks as necessary."
    cb_handler = ifnone(cb_handler, CallbackHandler())
    if not is_listy(xb): xb = [xb]
    if not is_listy(yb): yb = [yb]
    out = model(*xb) **# Here the output is NOT a tuple**
    out = cb_handler.on_loss_begin(out)if not loss_func: return to_detach(out), yb[0].detach()
         loss = loss_func(out, *yb)if opt is not None:
        loss,skip_bwd = cb_handler.on_backward_begin(loss)
        if not skip_bwd:                     loss.backward()
        if not cb_handler.on_backward_end(): opt.step()
        if not cb_handler.on_step_end():     opt.zero_grad()return loss.detach().cpu()

一旦我们在库中找到了确切的位置,更改就变得轻而易举了:简单地选择如下所示的model()输出中的第一个元素,并为该函数提供一个新名称:

def loss_batch_bert(model:nn.Module, xb:Tensor, yb:Tensor, loss_func:OptLossFunc=None, opt:OptOptimizer=None,
               cb_handler:Optional[CallbackHandler]=None)->Tuple[Union[Tensor,int,float,str]]:
    "Calculate loss and metrics for a batch, call out to callbacks as necessary."
    cb_handler = ifnone(cb_handler, CallbackHandler())
    if not is_listy(xb): xb = [xb]
    if not is_listy(yb): yb = [yb]
    out = model(*xb)[0] **# we take the first element as the model output
**    out = cb_handler.on_loss_begin(out)if not loss_func: return to_detach(out), yb[0].detach()
         loss = loss_func(out, *yb)if opt is not None:
        loss,skip_bwd = cb_handler.on_backward_begin(loss)
        if not skip_bwd:                     loss.backward()
        if not cb_handler.on_backward_end(): opt.step()
        if not cb_handler.on_step_end():     opt.zero_grad()return loss.detach().cpu()

现在我们有了一个新的loss_batch_bert()函数,我们需要它来替换 Fastai 中加载到我们环境中的原始loss_batch()。我们可以通过以下方式做到这一点:

***# To change the loss_batch function in the loaded fastai module***import sys
module_basic_train = sys.modules['fastai.basic_train']
module_basic_train.loss_batch = loss_batch_bert
sys.modules['fastai.basic_train'] = module_basic_train

然后我们调整后的loss_batch_bert()被嵌入到 Fastai 库中,它应该可以满足 Pytorch-transformers 的需求。剩下的都是 Fastai 魔法:组装一个Learner()物体,进行试衣!

只需两个周期的训练,我们就可以在私人排行榜上取得 98.427%的成绩!考虑到我们的短期训练和非常“普通”的训练循环,这还不错。

如果您没有更新 Fastai 库,请注意。如果您想在训练过程中查看准确性,您可以传递一个准确性回调函数。但是,accuracy 函数可能已经过时,它的 return 语句中包含一个小错误:

((y_pred>thresh) == y_true.byte())。浮动()。意思是()#缺乏。byte()

它可以被固定如下

*# The more recent version fastai implemented exactly this version thus you could just directly call a partial funtion*
*# accuracy_thresh*
**def** accuracy_thresh2(y_pred:Tensor, y_true:Tensor, thresh:float=0.5, sigmoid:bool=**True**)->Rank0Tensor:
    "Computes accuracy when `y_pred` and `y_true` are the same size."
    **if** sigmoid: y_pred = y_pred.sigmoid()
    **return** ((y_pred>thresh)**.byte()**==y_true.byte()).float().mean()

我希望这篇文章是有帮助的,特别是对那些不熟悉 Fastai 或 Pytorch-transformers 的人。

代码可以在这里的笔记本中找到。

如果您在此过程中遇到其他问题,请随时告诉我。

编码快乐!

数据科学项目的最佳实践

原文:https://towardsdatascience.com/best-practice-for-data-science-projects-d91193fbd0ff?source=collection_archive---------9-----------------------

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

https://www.knime.com/blog/analytics-and-beyond

由于计算机处理能力的提高,以及处理器和内存成本的降低,现在使用数据科学技术来分析大量数据是可行的。这种增长变成了工业上的严重需求。这导致了对数据科学家的严重需求。为了满足这种就业需求,来自不同背景的人已经开始将他们的职业道路转向数据科学。人们渴望进入这个领域,不幸的是,其中包括许多缺乏适当技能和对数据科学生命周期了解的人。这一缺点已经开始在行业中引发问题。

数据科学项目需要遵循几个步骤,为了保持连续性,这些步骤应该一起进行。没有一个系统的工作流程,很容易迷失在其中的一个步骤中。在工业中,当人们认为他们完成了一个项目时,他们经常努力使项目得到全面的运营支持,因为他们没有考虑到这些生命周期步骤。这是一个常见但严重的问题,原因是人们不知道或不理解术语“生产就绪”的含义。

在我的工作中,我遇到过声称准确率为 92%的工程师,而测试的准确率为 83%。此外,我还看到一些已部署的项目省略了一些关键步骤,而这些步骤仍然在工程师的笔记本中。一个月后,产品经理要求每两周进行一次模型培训,这给工程师们带来了震惊。本文的目标是更好地理解进行数据科学项目时所需的生命周期和工作流。

数据科学项目的性质要求在项目的每一步都进行许多测试。出于这个原因,数据科学项目的一个非常常见的做法是使用笔记本。在项目结束时,很可能会有跨多个笔记本的多余代码不会用于生产。当工程师完成一个步骤时,他们会频繁地将完成的步骤输出,让笔记本上的所有内容都变得杂乱无章,然后立即继续下一步。当代码运行到最后一步时,假设代码已经准备好投入生产,项目已经完成是错误的。这种误解会造成时间和金钱的损失。

**什么是生产就绪?**生产就绪包含多项检查:

1.它跑吗?

2.是否满足项目要求?

3.系统稳定吗?

4.是否可维护?

5.是否可扩展?

6.有记录吗?

让我们深入研究其中的每一个。

它跑吗?意思是代码运行正常吗?代码应该能够平稳运行,任何步骤都不需要任何干预或修改。如果你有一个好的理由,你可以做一些手动的步骤,但是好的实践是从数据采集到预测有一个连续的流程,这是生产中最可能需要的。一种非常常见但不好的做法是写下每一步的输出,然后再次读取前一步的输出。您希望避免每一步都从磁盘中写入和读取。将信息保存在内存中,并将信息传递给下一步,而不将其写入文件,这将提高软件的性能。如果分析数据也超出了内存容量,则成批接收和传递数据。

软件应该满足项目的需求。当工程师完成项目的最后一步时,他们经常跑到项目经理那里演示模型的度量标准(大部分是根据准确性定义的)。产品经理认为项目需求得到满足是错误的。此时,如果产品经理不具备理解和评估模型的技术知识,工程师应该鼓励经理指派另一名主题专家来询问这些问题:

1.数据是如何收集/采样的?工程师可以有意或无意地引入数据偏差。数据科学家可以采用相同的数据,并显示相同的结果为有利或不利。模型评估应该基于您正在查看的那些指标。

2.如何将数据分成训练/验证/测试组?数据的不适当分割可能导致生产结果的显著差异。对任意大小的数据集应用 80-20%的分割,并且不对倾斜的数据集进行分层是工程师经常犯的错误。如果数据集很小,以 80-20%的比例分割数据是可以的,但是如果数据集很大,比如 1000 万。在这种情况下,以 80–20 的比例分割将产生 800 万个训练集大小和 200 万个测试集大小。你真的想让你的测试集那么大吗?因此,正确率应该在 95–05%左右,这将产生 950 万个训练集和 50 万个测试集。如果你的数据量越来越大,你需要增加这个比率。对于大数据集,我的意思是超过 2000 万,使用 99–01%的分割率将为训练和测试提供合理的大小。

3.测试数据是否代表了模型将要使用的数据?工程师和产品经理应该始终考虑数据流动的速度,以及数据可能会随着时间的推移而变化。在一定时间内,有多少百分比的数据在变化?一项基本检查是确保项目完成后收到的数据仍然代表业务需求。

在得到这些问题的满意答案后,工程师和产品经理就可以说软件满足了项目的需求。

一个健壮的架构师并在项目开发之初最小化软件缺陷,将有助于工程师开发出一个稳定的系统,在开发过程中不需要剧烈的变化。

工程师可以理解项目的每一部分和每一行代码,因为他们创建了代码。然而,好的文档可以让新员工快速上手。新人应该不会花太多时间去理解现有的工作。好的可维护软件不应该太复杂而难以理解。工程师应该记住,运行代码的是计算机,而阅读和支持代码的是人。创造一个复杂的代码不是一种天赋,让它简单、易读和易懂。

数据科学家必须确保软件能够处理增加的工作量。可伸缩性将减少未来花费在项目上的总时间。如果该模型有效,它是否会随着数据增加 1,000,000 倍而扩展?

文档是项目的关键部分,缺少了它,项目就不完整。大多数情况下,文档是在项目结束时创建的。这是一种不良做法,因为在数据科学项目中,每一步都需要记录详细信息,以便进行充分的文档记录,而在项目结束时从记忆中回忆这些细节并不是一种可靠的做法。在开发项目的同时开始文档构建。确保记下每个步骤的要点,以避免遗漏关键步骤。

遵循这些步骤,增加了拥有健壮项目的机会。在建立一个项目结构之后,创建一个 Docker 映像并从这个映像开始工作是开发软件项目的一种安全而有效的方式。由于 Docker 镜像已经包含了一个操作系统和编程语言的所有依赖项,所以即使在开发过程中也很容易向不同的方向移动。这将避免为每次代码更改创建新映像的需要,因为只需要在更新 docker 文件时创建一个新映像。此外,docker 文件将提供一个独立于操作系统的产品。您可以在任何操作系统上部署这个 Docker 映像。

确保在项目结束时你有以下东西:

1.一切都已编写好脚本,笔记本上的所有代码都已实现。

2.上述六项检查中描述的产品就绪项目。

3.该系统展示了从开始(第一步)到结束(最后一步)的平稳流程。

4.docker 图像已生成。

最佳实践——创建 ETL 第 1 部分

原文:https://towardsdatascience.com/best-practices-creating-an-etl-part-1-bdb563381025?source=collection_archive---------16-----------------------

ETL(和 ELT 的表亲相差不远)是一个通常不会在大学教授的概念,至少不会在本科课程中教授。然而,ELT 在几乎每个公司的日常运营中都扮演着重要的角色。

ETL 是将数据填充到业务仪表盘和算法中的管道,这些仪表盘和算法为管理者提供重要的见解和指标。这些管道从将数据从操作数据库提取到数据仓库的非常简单的过程,到支持更复杂的转换和应用的复杂的分析层。

问题是,我们的许多 IT 毕业生没有学到这一非常重要的技能,如果他们决定从事数据科学或数据工程方面的职业,他们很可能会在日常生活中使用这一技能。虽然数据科学工作在技术上并不真正包括 ETL,但是他们所做的很多工作最终会与数据工程师交叉。

我们希望涵盖 ETL 和良好的 ETL 设计的基础。

一个好的 ETL 看起来像什么,关键组件是什么,是什么使管道可维护和健康?这些都是数据工程师和数据库经理在开始新项目之前需要问的重要问题。

这将是几篇文章中的第一篇。在这篇文章中,我们将涉及一些基本概念,如提取/加载原始数据和日志记录。这些都是重要的话题,有很多细微的差别,我们想开始讨论

我们还将在 2 月 23 日上午 10 点(太平洋时间)提供一个免费网络研讨会来讨论这个话题。我们希望您能参加!

操作到原始

作战数据库

您的 ETL 将接收的所有数据都有一些来源,这些来源代表现实生活中的一种或另一种事务。这些数据可以代表去医院就诊的患者、在社交媒体上发帖的人或购买产品的客户。有些人可能会问,为什么不能只分析来自操作数据库的数据,而要通过额外的步骤将数据处理到另一个系统中。

最大的问题是,试图运行从运营数据库中聚合和分析大型数据集的分析流程会降低客户运营数据库的速度。此外,操作数据库高度规范化,从分析的角度来看,这使得它们的查询效率很低。这就是开发这种或那种形式的数据仓库的原因。

下面是一个向 SQL Server 中批量插入数据的方法示例

流程的第一步是将数据提取为某种形式的原始格式。

原始文件提取

从操作数据库中提取数据的方式可能会有所不同。然而,最一致的方法之一是将数据提取到一个原始文件中,如 CSV 或 XML 文件。将数据提取到原始文件中有几个好处。第一,提取数据的直接链接限制了外部系统与操作数据库的交互。这将避免阻塞需要发生的重要操作任务。此外,它还创建了数据在提取时的快照。如果您因为管道中可能发生的问题而需要重新加载数据,这可能是有益的。

拥有这种数据备份是有益的,以防有人意外删除重要数据。然后你会很高兴有容易重装的生抽。应该在某个表中跟踪这些原始摘录,该表记录了加载了哪些文件以及它们存在于何处。这样,您可以轻松地自动进行任何重新加载。此外,文件应该有一个命名标准。

一个简单的例子是 date extracted _ DateRangeInTheFile _ business object(例如 2017 01 01 _ 2016 09 01 _ 2016 12 31 _ customers . CSV)

元数据库和日志

在开发一个自动化的、可维护的和健壮的系统时,跟踪 ETL 过程中发生的事情是至关重要的一步。您的跟踪和日志记录的范围取决于您的公司有多大,以及需要进行多少 ETL/ELT 和其他数据转换。较大的公司可能有一个标准化的工具,如 Airflow,来帮助管理 Dag 和日志记录。

但是,如果你是一家初创公司或者非科技公司,有一个简化的日志系统可能就可以了。该系统的目的是管理需要加载/已经加载的文件,跟踪已运行的存储过程、错误、依赖性等。

深入了解系统的这些方面将有助于维护、改进系统,并填充任何丢失或加载不正确的数据。这意味着您实际上需要创建 3-4 个表(至少)来跟踪正在运行的内容、运行时间、计算等。特别是当我们推动越来越多的自动化系统时,这将是确保系统可维护性的关键。

将原始数据加载到原始表格中

一旦您从操作数据库中提取了原始数据并用新的文件信息更新了元表,那么您就可以开始专注于加载数据了。

尝试在 raw 的初始加载中添加许多复杂的业务逻辑可能很有诱惑力。这似乎可以简化过程,减少加载数据的步骤。所以为什么要增加更多的步骤。事实是,在早期添加太多的逻辑会使跟踪错误发生的地方变得困难。错误发生在摘录中、业务逻辑中还是其他地方?此外,更新新逻辑变得更加困难,因为您必须分析更新逻辑的最佳位置。

所有这些额外的考虑使整个系统更难维护。这就是按原样加载原始数据非常重要的原因。如果需要进行重复数据消除逻辑或映射,则可以在管道的暂存部分进行。

将数据加载到原始数据库后,接下来的步骤是 QA 和将数据加载到临时数据库。我们将在下一篇文章中继续讨论。如果你想了解更多关于 ETL 开发/ 自动化的知识,那么就注册我们的 ETL 网络研讨会,在这里我们将从头到尾讨论创建 ETL 的过程。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值