TowardsDataScience 博客中文翻译 2020(二百二十九)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

适用于大多数 ML 用例的一个容器

原文:https://towardsdatascience.com/container-for-almost-all-ml-use-cases-de-mystifying-xgboost-iii-434310b782e8?source=collection_archive---------25-----------------------

揭开 XgBoost 的神秘面纱

设置 Docker 和远程 Jupyter 服务器(在 GCP 上)

序幕

这是去神秘化 XGBoost 第一部分第二部分的延续。不过你可以单独阅读。如果您正在使用 XgBoost 进行您的机器学习项目,并且想要深入了解内部工作方式和超级参数,请查看第一部分第二部分

在这篇博客中,我将深入构建一个 docker 容器,它可以用于几乎所有的 ML 用例。集装箱内还将设置 Jupyter 笔记本和 Jupyter 实验室。我们将能够在 notebook 的 python 内核中同时使用 Python 和 R 进行编码!(R 有我喜欢使用的非常酷的绘图库,包括 XGBoost 的 plot_tree 的树可视化实现)。我们还将能够在本地浏览器上,通过 ssh 隧道和分别到容器主机和容器的端口转发,远程连接到 Jupyter 实验室服务器。

因为我最近在 GCP 上这么做了,所以我还将添加特定于 GCP 的指令,以便在 GCP 的 VM 上托管和运行这个容器,以及将持久磁盘映射到容器的指令。我们走吧!

安装步骤

安装 Docker

第一步,显然是安装 Docker。对我来说,我在 Debian 上,在 GCP 的一个虚拟机中。我跟着下面的链接,去安装 docker。或者可以关注 Docker 官方链接

无论你的操作系统是什么,找出正确的安装步骤。谷歌。冰!

文档文件

下面是 docker 文件。我选择了 Ubuntu 18.04 作为基础映像,因为我喜欢 Ubuntu😀。您可以选择 Centos 或其他 linux 版本。不幸的是,所有的运行命令都依赖于操作系统,或者至少选择 Linux。

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

请从https://github . com/run 2/demystify-xgboost/blob/master/docker file下载该文件

从上面的链接获取文件。

我将运行分割成逻辑单元,这样容器可以一层一层地构建。在层中包含这些(单次运行命令)可以帮助您构建其他这样的 other 文件,在使用上述缓存层时(在您从该 other 文件构建映像之后),为您的用例构建更具体的层。

首先,我有所需的 Ubuntu 包,然后是 python 和 pip,然后是所有常见的 ML 库,然后是安装 graphviz 所需的库(我们需要它进行可视化),然后安装 graphviz 和 R,接着是 rpy2,它基本上允许我们在 python 内核中运行 R,然后是 R 包,然后是 github,最后是可选的 gcloud sdk 和一些清理工作。

它还安装了许多实用程序包,如 Kaggle、Shap、Jupyter extensions、Seaborn、arff2pandas,它们广泛用于 ML 项目。

接下来,Dockefile 创建一个本地目录来映射主机卷。创建一个名为 ml-user 的用户(无密码)。建立了朱庇特和朱庇特实验室。我没有遇到使用密码作为参数的麻烦,但是有一个注释部分显示了如何做。不过我不建议你这么做,因为你真的不需要那个密码。永远不会。

最后,Dockerfile 从主机复制三个文件。一个 jupyter 配置文件,一个允许我们通过 https 运行 Jupyter 服务器的证书文件,以及一个在容器启动时启动 Jupyter 服务器的入口点文件。

主持人

容器主机可以是物理机或虚拟机。从 GitHub 下载 Dockerfile,并将其作为“Dockerfile”保存在您主机上的一个目录中。

要构建这个 docker 容器,您还需要三个文件。一个 Jupyter 配置文件 jupyter_notebook_config.py .一个 ssl 证书文件 mysert.pem 和一个名为 entryPoint.sh 的 entrypoint 文件。

让我们过一遍。

Jupyter 的证书和配置文件

这两个文件没什么内容。如果您遵循 Jupyter 设置中给出的程序,我们基本上需要

  1. 使用 Openssl 创建一个证书文件。我没有上传这个文件,很明显:)
  2. 为安全访问 Jupyter 实验室创建散列密码
  3. 生成 Jupyter 配置,并使用 a)证书文件位置,b)密码哈希 c)Jupyter 为笔记本提供服务的文件夹位置 d)以及允许从所有 IP 访问服务器的一些更改 e)默认端口(8888)等更新配置文件。

您可以在 github 链接上使用配置文件(没有密码散列)。

记得修改配置文件中的部分(参见 Jupyter 设置链接以了解如何生成散列)

您将需要 config 和 cert 文件(我将其命名为 mycert.pem。如果您想命名为其他名称,您将需要在 config 文件中更改名称),位于您启动 docker build 命令的相同位置。

入口点

最后,让我们谈谈入口点。这个脚本以 root 用户的身份从容器的/root 目录运行(参见 docker 文件的最后一行)。但是我们需要在用户 ml-user 的许可下在后台启动 Jupyter lab(不想暴露在 root 下运行的 Jupyter lab),然后确保容器启动并运行,并将 std 和 error 通过管道返回到一个可以从主机访问的文件中。

下面是执行该操作的命令

#!/bin/bash
echo "$1"
sudo -H -u ml-user -- sh -c '. /home/ml-user/.bashrc ; \
cd ; pwd ; chown -R ml-user /ml-disk ; chgrp -R ml-user /ml-disk ; \
PATH=$PATH:/home/ml-user/.local/bin:/home/ml-user:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin; 
export PATH; nohup jupyter lab 2>&1 > /ml-disk/lab.log &'
bash

H 转到-u ml-user 的主目录。注意用户 ml-用户是在 docker 文件中创建的。然后运行 ml-user 的 bashrc 来设置本地环境变量。接下来移动到 ml-user 的主目录,并将所有需要的路径添加到 path 变量中(记住我们是在 root 用户的身份下运行的)。

最后,我们使用 nohup 在后台运行 Jupyter,并在一个目录中的文件中捕获标准错误和标准输出,该目录是专门创建的(再次在 Dockerfile 文件中),用于映射来自主机的卷。最后的 bash 命令确保容器在运行时不会退出,并保持对交互式会话可用。

用于存储 jupyter 日志文件的/ml-disk 目录是容器中的目录,当运行 docker run 命令时,它将被映射到主机上的一个卷,如下所示。

你可以从https://github . com/run 2/demystify-xgboost/blob/master/entryPoint.sh下载 entry point . sh

建造它

让我们将这个容器命名并标记为 de-神秘化/rnpython:1.0。

我们可以使用下面的命令来构建它

docker build -t 去神秘化/rnpython:1.0。(不要忘记点号或合适的目标路径)

这将需要一些时间,你完成了!!🥳🥳🥳

此时,如果您在 gcp 上,您可以标记它,并将其推入 GCP 容器注册。或者使用自己的容器注册中心。甚至是 dockerhub。

注意,如果您在运行 docker 命令时遇到权限问题,您需要将您的用户添加到 sudo 组。见上面提到的 docker 的官方链接。

标记并推送到容器注册表

首先发射命令 docker 图像

获取刚刚创建的 de-mystic/rn python:1.0 docker 图像的图像 id

为了 GCP

标记一下:docker tag【gcr.io/<你的 gcp 项目名>/demystify-rnpython:1.0
Push:docker Push gcr.io/<你的 gcp 项目名>/dr-神秘化-rn python:1.0

对 Dockerhub 或您自己的回购使用类似的标记和推送。

搞定了。!

运行它

您现在已经准备好运行容器了。

先拉一下。

码头工人拉 gcr.io//去神秘化-rnpython:1.0

那就运行它。

docker run-v/home//ml-disk:/ml-disk-p 8888:8888-it-d gcr.io//de-神秘化-rnpython:1.0

它使您的容器在伪 tty 上交互,而-d 分离它,这样交互 shell 就不会启动。

这里的-v 命令将/home/ /ml-disk 目录(可以在主机硬盘上创建,也可以是外部持久性磁盘的挂载目录)映射到容器上的/ml-disk 目录。

-p 命令设置从主机端口 8888 到容器端口 8888 的端口转发(Jupyter 服务器将监听的默认端口,在配置文件中有提及)

就是这样。此时,您应该能够在主机上直接打开 https://localhost 。或者,如果您的主机是一台 VM 或服务器,并且您想从您的本地机器访问 Jupyter,您可以从您的本地主机使用 ssh 隧道,如下所示。

ssh -N -f -L localhost:8888:localhost:8888 [ml-user@host](mailto:dbhatt@addawser.engba.symantec.com)

或者如果你在 GCP,你可以从你的本地主机使用 ssh 隧道

gcloud compute ssh --project <your gcp project id> --zone <zone of your hosting vm> <name of your hosting vm> -- -L 8888:localhost:8888

现在,您应该能够从本地浏览器启动 https://localhost 。它会将本地主机上的 8888 通过隧道传输到 VM 主机或服务器的 8888。从那里,端口转发将负责与容器的端口 8888 交换数据包。

你看到了什么?

一旦你启动了浏览器,它应该像下面这样

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

在左侧,您应该能够看到您的主机上的卷的所有内容(例如/home/ /ml-disk,它被挂载到容器的/ml-disk)。

父目录是容器上的/ml-disk,该目录映射到主机的/home/ /ml-disk 目录。开始吧!

GCP 持久磁盘

这一部分只给在 GCP 做这个的人。并且想要在主机 VM 上安装永久磁盘。

在暴露 IAP 隧道和 Https 的情况下,在主机虚拟机上装载磁盘

在 GCP 拥有共享持久磁盘的最佳方式是通过云文件存储。它就像一个 NFS,如果您在由不同用户运行的许多容器实例上使用训练数据集,那么 CFS 是最佳选择,因为它允许在多个实例上进行读写共享。然而,这有点贵,所以我打算用一个普通的磁盘。

但是请记住,对于普通磁盘,您将无法选择多租户读写。它将被锁定,供主机虚拟机独占使用。

下面是我如何创建一个 500GB 的普通磁盘(SSD 很贵),将其命名为 ml-disk (你可以命名为任何东西)并启动我的主机 VM(命名为 hosting-mlcontainer),这个磁盘连接到它。

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

创建永久磁盘

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

在创建虚拟机时将其添加到虚拟机中

此外,记住,你的虚拟机需要比你想给容器的更多的内存,所以,相应地分配,比如下面

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

选择虚拟机体系结构、虚拟 CPU、内存

我通常还会确保不能通过互联网访问启动虚拟机。因此,关闭短暂的外部 ip 地址。而且要确定!您已经打开了 https 访问——因为我们将通过 https 从本地主机进入我们在容器上的 Jupyter 服务器,以便我们可以在本地运行它!!

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

将外部 ip 设置为无并允许 https 流量

现在,这不是一个 GCP 的博客,所以我不会进入细节,但要访问没有外部 ip 的虚拟机,你可能需要启用 IAP 转发权限。无论如何,一旦虚拟机启动并运行,登录并启动 lbsck 命令。您应该会看到类似这样的内容

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

sdb 是外部磁盘卷

最后一行是我们刚刚创建的名为 ml-disk 的外部磁盘的卷。现在我们需要装入这个卷。首先,我们需要使用如下命令格式化驱动器

sudo mkfs . ext 4-m 0-F-E lazy _ ritable _ init = 0,lazy_journal_init=0,discard /dev/sdb

然后,我们需要创建一个目录,并将磁盘装入该目录。但是我们每次都需要这样做,对吗?就像每次我们使用相同的外部磁盘创建或启动虚拟机一样,我们需要挂载该磁盘。所以我们最好在虚拟机上(或者在虚拟机模板上)有一个启动脚本。脚本如下所示。

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

将/dev/sdb 加载到~/ml-disk 目录并允许它对 ml-user 进行写访问的脚本。这个脚本保存了 fstab 文件的副本,该文件将磁盘挂载到分区中,并修改它以在上述目录中挂载/dev/sdb 卷。你可以在https://github . com/run 2/demystify-xgboost/blob/master/VM-startup找到这个脚本

我们需要将该启动脚本放在虚拟机或虚拟机模板的“管理”选项卡下。

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

将外部磁盘装入指定文件夹的虚拟机启动脚本

搞定了。

改进 docker 有很多方法和细节可以做。请评论并告诉我你们是如何改进它的。

在本系列的下一部分,我将展示如何通过 Jupyter Lab 内核在这个容器上使用 R 和 Python,并在解开 XGBoost 之谜中使用真实的例子。

参考

[## 揭开 XGBoost 第二部分的神秘面纱

序幕

medium.com](https://medium.com/@b.debanjan/de-mystifying-xgboost-part-ii-175252dcdbc5) [## 揭开 XGBoost 第一部分的神秘面纱

为什么为什么?

medium.com](https://medium.com/@b.debanjan/de-mystifying-xgboost-part-i-f37c5e64ec8e) [## 运行笔记本服务器- Jupyter 笔记本 6.0.3 文档

Jupyter notebook web 应用程序基于服务器-客户机结构。笔记本电脑服务器使用两个进程…

jupyter-notebook . readthedocs . io](https://jupyter-notebook.readthedocs.io/en/stable/public_server.html)

使用 tf-idf 构建基于电影内容的推荐系统

原文:https://towardsdatascience.com/content-based-recommender-systems-28a1dbd858f5?source=collection_archive---------9-----------------------

基于内容的电影推荐方法

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

吕山德元Unsplash 上拍照

介绍

随着时间的推移,我们越来越依赖在线平台和应用程序,如网飞、亚马逊、Spotify 等。我们发现自己不得不不断地从广泛的选项中进行选择。

有人可能会认为,与选择很少相比,选择多是件好事,但选择过多会导致所谓的“决策瘫痪”。正如巴里·施瓦茨在《选择的悖论》中写道:

“大量的选择可能会使消费者泄气,因为这迫使他们在做决定时付出更多的努力。所以消费者决定不决定,不买产品。或者,如果他们这样做了,做决定所需要的努力会降低从结果中获得的快乐。”

这也导致了另一个更微妙的负面影响:

“大量的选项可能会降低人们实际选择的吸引力,原因是考虑一些未选择的选项的吸引力会降低从选择的选项中获得的快乐。”

一个显而易见的结果是,除非对我们来说变得更容易,否则我们最终不会在多种选择中做任何努力;换句话说,除非这些是根据我们的喜好过滤掉的。

这就是为什么推荐系统已经成为上述平台中的关键组件,在这些平台中,用户有无数的选择。他们的成功将在很大程度上取决于他们缩小选择范围的能力,让我们更容易做出选择。

该领域的一个主要推动力是网飞,它通过研究不断推进最先进的技术,并在 2006 年至 2009 年间赞助了 Netflix 奖,极大地推动了该领域的研究。

此外,网飞的推荐者在平台中有巨大的存在。当我们搜索一部电影时,我们会立即得到一系列我们可能也会喜欢的相似电影:

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

网飞-个人账户

概述

这篇文章从揭示推荐系统中的不同范例开始,并通过一个基于内容的推荐系统的实践方法。我将使用众所周知的 MovieLens 数据集,并展示我们如何根据它们的特点推荐新电影。

这是关于推荐系统的两篇系列文章(可能更多)中的第一篇,下一篇将是关于协同过滤

在这里 找到这篇帖子的 jupyter 笔记本版,里面有所有代码

推荐系统的类型

大多数推荐系统利用协同过滤和基于内容的过滤中的一种或两种。尽管当前的推荐系统通常将几种方法组合成一个混合系统。以下是这些方法的概述:

  • 协同过滤:这些方法背后的主要思想是利用其他用户的偏好和品味向用户推荐新的项目。通常的程序是找到相似的用户(或项目)来推荐那些用户喜欢的新项目,并且被推荐的用户可能也会喜欢。
  • **基于内容:**基于内容的推荐器将使用关于项目的专有数据。为此,我们需要对用户的偏好有一个最低限度的了解,这样我们就可以推荐与用户指定(或推断)的标签/关键词相似的新项目。
  • 混合方法:,顾名思义,包括结合协同过滤、基于内容和其他可能方法的技术。现在大多数推荐系统是混合的,如因式分解机的情况。

电影镜头数据集

测试推荐系统最常用的数据集之一是movie lens 数据集,它包含来自 MovieLens 网站的评级数据集。对于这篇博客,我将使用一个数据集,其中包含 6000 名 MovieLens 用户制作的大约 4000 部电影的 100 万匿名评级,这些电影于 2003 年 2 月上映。

让我们看一下这个数据集中包含的数据。我们有三个。csv 文件:收视率用户电影。这些文件将作为熊猫数据帧加载。我们有一个评级文件,看起来像:

ratings.sample(5)
        user_id  movie_id  rating
376907     2201      2115       5
254402     1546      2329       5
520079     3208      3300       3
534583     3300      2248       5
325635     1926      1207       4

movies数据集如下:

movies.sample(5)
      movie_id                           title          genres
948        960     Angel on My Shoulder (1946)     Crime|Drama
645        651           Superweib, Das (1996)          Comedy
3638      3707           Nine 1/2 Weeks (1986)           Drama
511        515  Remains of the Day, The (1993)           Drama
2144      2213      Waltzes from Vienna (1933)  Comedy|Musical

既有一个movie_idtitle又有一个字符串,所有的genres都由字符|分隔。

和用户数据集,包含用户的基本信息:

users.head()
   user_id gender zipcode  age_desc              occ_desc
0        1      F   48067  Under 18          K-12 student
1        2      M   70072       56+         self-employed
2        3      M   55117     25-34             scientist
3        4      M   02460     45-49  executive/managerial
4        5      M   55455     25-34                writer

电影类型

正如我们将在下一节中探讨的,类型本身可以用来提供一个相当好的基于内容的推荐。但在此之前,我们需要分析一些重要的方面。

  • 最受欢迎的流派有哪些?

这将是在构建基于内容的推荐器时要考虑的相关方面。我们想了解在定义用户的*品味时,哪些类型是真正相关的。*一个合理的假设是,恰恰是那些不受欢迎的类型更符合用户的口味。

最相关的类型有:

genre_popularity = (movies.genres.str.split('|')
                      .explode()
                      .value_counts()
                      .sort_values(ascending=False))
genre_popularity.head(10)Drama         1603
Comedy        1200
Action         503
Thriller       492
Romance        471
Horror         343
Adventure      283
Sci-Fi         276
Children's     251
Crime          211
Name: genres, dtype: int64

或者,为了更直观地展示,我们可以绘制一个带有流派的词云:

genre_wc = WordCloud(width=1000,height=400,background_color='white')
genre_wc.generate_from_frequencies(genre_popularity.to_dict())plt.figure(figsize=(16, 8))
plt.imshow(genre_wc, interpolation="bilinear")
plt.axis('off')

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

生成体裁词云

如你所见,最常见的类型是戏剧、喜剧和动作片。然后,我们有一些不太常见的其他类型,如西部片、奇幻片或科幻片。正如我之前指出的,后者是我们在推荐时想要给予最大重视的。但是,这是为什么呢?

作为一个例子,让我们考虑一个用户想要找到一部类似于“ 【善、恶、丑 ”的电影,它是西部片、动作片和冒险片的混合体。你认为哪种类型更适合向用户推荐电影?大概是西方的,因为将会有许多非西方的动作或冒险电影,这可能会导致推荐许多非西方电影。

构建基于内容的推荐器

在这篇文章中,我们将基于**电影类型建立一个非常简单的推荐器。**解决这个问题的一个相当常见的方法是使用一个 tf-idf 矢量器。

虽然这种方法更常用于文本语料库,但是它拥有一些有趣的属性,这些属性对于获得数据的 向量表示 是有用的。该表达式定义如下:

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

这里我们有术语频率的乘积,即给定术语(类型)在文档(电影的类型)中出现的次数乘以右侧术语,这基本上根据给定术语在所有文档(电影)中出现的次数来衡量术语频率。

包含给定流派( df_i) 的电影越少,得到的权重越高。对数基本上是为了平滑除法的结果,即避免由于右手项而导致的巨大差异。

那么,为什么这对我们有用呢?

正如已经提到的,tf-idf 将通过给予不太频繁的类型更高的权重来帮助捕捉每部电影的重要类型,这是我们用CountVectorizer无法获得的。

tf-idf

为了获得 tf-idf 向量,我将使用 sklearn 的TfidfVectorizer。然而,我们必须考虑这个问题的一些特殊方面。在处理文本数据时,通常的设置是设置一个word分析器和一个ngram_range,它也将包括指定范围内的 n 元语法。一个例子是:

from sklearn.feature_extraction.text import TfidfVectorizers = "Animation Children's Comedy"
tf_wrong = TfidfVectorizer(analyzer='word', ngram_range=(1,2))
tf_wrong.fit([s])
tf_wrong.get_feature_names()
# ['animation', 'animation children', 'children', 'children comedy', 'comedy']

然而,在这种情况下,这实际上没有意义,因为类型的顺序是不相关的,我们想要考虑给定电影的类型的组合,而不考虑顺序。对于上面的例子,我们想要:

from itertools import combinations
[c for i in range(1,4) for c in combinations(s.split(), r=i)]

[('Animation',),  ("Children's",),  ('Comedy',),  ('Animation', "Children's"),  ('Animation', 'Comedy'),  ("Children's", 'Comedy'),  ('Animation', "Children's", 'Comedy')]

在这里,我们找到了直到k(这里是 4)的流派组合集,或者用数学术语来说,就是超集。包括类型的n>1组合,将意味着 tf-idf 矢量器也将考虑这些组合在所有电影中出现的频率,给出现最少的那些分配较高的分数。

我们可以使用analyser参数应用上面的逻辑,我们可以使用这个参数从原始输入中获得特征序列,使用一个可调用的:

tf = TfidfVectorizer(analyzer=lambda s: (c for i in range(1,4)
                     for c in combinations(s.split('|'), r=i)))
tfidf_matrix = tf.fit_transform(movies['genres'])
tfidf_matrix.shape
# (3883, 353)

这将产生以下 tf-idf 向量(注意,只对列和行的子集进行采样):

pd.DataFrame(tfidf_matrix.todense(), columns=tf.get_feature_names(),   index=movies.title).sample(5, axis=1).sample(10, axis=0)

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

向量间的相似性

下一步将寻找类似的 tf-idf 向量(电影)。回想一下,我们已经每部电影的类型编码到一个 tf-idf 表示中,现在我们想要定义一个*接近度度量。*一个常用的度量是余弦相似度

这种相似性度量因其等于被比较的两个向量之间角度的余弦值而得名。两个向量之间的角度越小,余弦值就越高,从而产生更高的相似性因子。它表示如下:

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

图片来源

其中,由于内积可以表示为幅度乘以两个向量之间角度的余弦的乘积,因此很明显,上述内容可以表示为余弦:

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

图像来源

因此,通过取两个向量之间的内积,并根据它们各自的幅度进行归一化,得到两个向量之间的余弦

为了计算所有 tf-idf 向量之间的余弦相似性,我们可以再次使用 scikit-learn。[sklearn.metrics.pairwise](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise_distances.html)包含许多成对的距离度量,其中有[cosine_similarity](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.pairwise.cosine_similarity.html) ,它将计算所有输入行之间的余弦相似性,在本例中为 tf-idf 向量:

from sklearn.metrics.pairwise import cosine_similarity
cosine_sim = cosine_similarity(tfidf_matrix)

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

现在我们必须定义一些逻辑来找到给定电影的最高权重或 tf-idf 分数。为此,我定义了以下函数,该函数将一部给定的电影i、相似度矩阵M、项目数据帧作为输入,并返回多达k的推荐:

通过使用argpartition,我们在给定的索引(电影)i上取M(相似矩阵)中的k最高值。然后,我们对M中的列进行索引,并进一步从最高权重到最低权重进行切片(排除最高权重,这将是同一项,因为矩阵是对称的,因此第二行中有2s)。

测试推荐器

我们用几个例子来测试一下推荐器。由于movies数据集包含了 2000 年以前的电影,我们将不得不使用一些经典电影。

'2001: A Space Odyssey'怎么样?

movies[movies.title.eq('2001: A Space Odyssey (1968)')]
    movie_id                              title              genres
912      924       2001: A Space Odyssey (1968)  Drama|Mystery|Sci-Fi|Thriller

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

2001:太空漫游

我们可以看到它的流派是Drama|Mystery|Sci-Fi|Thriller。看看有什么推荐吧!😃

genre_recommendations('2001: A Space Odyssey (1968)', cosine_sim_df, movies[['title', 'genres']])

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

正如所料,最相似的电影是那些分享最多类型的电影。有趣的是,我们看到大部分都是Sci-Fi电影。请注意,这很可能受到以下事实的影响:在上面出现的流派中,Sci-Fi通常具有较高的分数,因为它出现的频率最低,因此具有较高的权重。

让我们看看我最喜欢的科幻电影《T2 》:

movies[movies.title.eq(‘Contact (1997)’)]
      movie_id           title        genres
1543      1584  Contact (1997)  Drama|Sci-Fi

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

接触

在这种情况下,我们会得到:

genre_recommendations('Contact (1997)', cosine_sim_df, movies[['title', 'genres']])

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

似乎有许多电影分享相同的类型,因此我们得到了所有Drama|Sci-fi电影的推荐。

现在让我们来看一部像《T4》这样的动画电影:

movies[movies.title.eq('Jungle Book, The (1967)')]
      movie_id                    title                             
2009      2078  Jungle Book, The (1967) 
                             genres
Animation|Children's|Comedy|Musical

我们得到以下建议:

genre_recommendations('Jungle Book, The (1967)', cosine_sim_df, movies[['title', 'genres']])

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

似乎有两部电影分享了完全相同的类型组合,其余的也类似,但没有Comedy类型。

或者让我们试试最后一个,'Saving private Ryan':

print(movies[movies.title.eq('Saving Private Ryan (1998)')])
      movie_id                       title            genres
1959      2028  Saving Private Ryan (1998)  Action|Drama|Wargenre_recommendations('Saving Private Ryan (1998)', cosine_sim_df, movies)

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

结束的

总的来说,我们已经看到,一个相当幼稚的基于内容的推荐器可以提供相当好的结果。

基于内容的推荐器的一个明显优势是,它们不会遭受 冷启动 问题,因为我们只需要关于用户的基本信息(在这种情况下是单部电影)来基于项目提供类似的推荐。另一个有趣的优势是,我们能够向具有独特品味的用户推荐,这对于协同过滤方法来说可能更具挑战性。

然而的一个重要缺点是它倾向于向用户推荐相同类型的项目。为了能够推荐不同类型的项目,用户必须已经对新类型的项目进行了评级或者已经表现出了兴趣。这是协同过滤方法没有的问题,因为这里的匹配是在具有相似品味但不同项目评级的相邻用户之间进行的。

非常感谢你花时间阅读这篇文章,希望你喜欢:)

处理高偏差和方差

原文:https://towardsdatascience.com/contents-9b2e49f49fe9?source=collection_archive---------10-----------------------

通过方程解释正则化

内容

在本帖中,我们将了解:

(I)评估机器学习模型性能的方法

㈡适配不足和适配过度的问题

(三)偏差-方差权衡

㈣解决高偏差和高差异问题

之前的帖子中,我们研究了逻辑回归、数据预处理,并在 Kaggle 上的 titanic 数据集上进行了实际操作,获得了不错的结果。在到目前为止的两篇帖子中,你一定已经注意到我在这里和那里抛出了过度拟合这个术语,并且还提到它会导致机器学习模型的性能不佳。现在,我们将详细了解机器学习模型可能遇到的问题,以及它们可能的解决方案。在这篇文章中,我们不会亲自动手,但是在接下来的文章中,我们将应用我们在这篇文章中学到的概念。

评估模型的性能

在直接进入机器学习模型中出现的问题之前,我们如何知道我们的模型有问题?为此,我们需要一个模型的评估指标。我们已经看过一些了。我们使用决定系数(r 分数)来评估线性回归模型,使用精确度来评估逻辑回归模型。这两个指标都是由我们通过它们各自的成本函数得到的潜在误差计算出来的。为了解决机器学习模型的问题,我们将使用这个错误来做决定。

线性回归和逻辑回归的误差计算方式不同。为了让事情更容易理解和发展直觉,我们将从线性回归的角度来看待事情,但我们将定义的术语和它们扮演的角色将与任何其他机器学习模型完全相同。

一个错误就是一个“错误”,这个错误的程度可以量化为真实值和估计值之间的绝对差值。对于“n”个数量,它可以表示为:

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

在训练和测试集上计算模型性能的误差有助于我们识别模型所面临的问题。考虑以下场景:

(I)低训练集误差,低测试集误差

(ii)低训练集误差,高测试集误差

(iii)高训练集误差,高测试集误差

(iv)高训练集误差,低测试集误差

让我们一个一个地看看这些场景。

如果训练集误差和测试集误差都很低,这意味着模型在训练集上很好地学习了输入-输出映射,并且也能够很好地将其推广到测试集。这是一个好的机器学习模型的期望输出。我们在上一篇文章中训练的逻辑回归模型就是这种情况。

当训练集误差较低但测试集误差较高时,我们说模型过度拟合了训练集。这意味着在训练集上训练机器学习模型后,它对训练集的输入输出映射学习得非常好,但不能将这些映射推广到测试集。让我们试着理解为什么会发生这种情况。为任何任务收集的数据都不可能没有错误,不管过程有多仔细。一个好的机器学习模型应该总是对噪声进行采样,并且只生成那些排除了噪声数据点的输入-输出映射,即一个好的机器模型对噪声是鲁棒的。考虑一场音乐会的情况,艺术家的旋律和人群的噪音都有,但我们只关注艺术家的旋律(输入),因为它使我们愉快(输出),忽略了人群的所有噪音。如果我们注意所有的声音(艺术家+噪音),我们可能不会那么快乐。过度拟合是指机器学习模型关注每一个声音(艺术家+噪音),而实际上我们只需要专注于旋律。对训练数据过度拟合的机器学习模型据说会遭受**高方差。**在这篇文章的后面,我们将看到如何处理过度拟合。

如果训练集和测试集的误差都很高,则表明机器学习模型没有正确地学习训练集上的输入-输出映射,并且也不能在测试集上进行推广。换句话说,我们可以说我们的机器学习模型处于原始状态。据说这种模型在训练和测试数据集上都存在不足,并且存在高偏差

具有高训练集误差和低测试集误差的机器学习模型很少出现,但是当训练和测试数据没有被适当地采样时(例如,在分类问题中每个类的样本数量几乎相等)会出现这种情况,这导致测试集的统计特性的显著差异。考虑一个二元分类问题,其中对 A 类的预测给出 10%的训练误差,而对 B 类的预测给出 40%的训练误差。平均分类精度在整个数据集上给我们 25%的误差。但这不是一个好的措施。在现实生活的测试集中,A 类的出现次数很可能多于 B 类。这意味着现实生活数据集中的实际预测误差将大大低于 25%。发生这种情况的另一种情况是,当测试集明显小于训练集时,尽管与训练集相似,但我们在测试集上得到的错误较少,因为与训练集相比,它没有那么多噪声。除了在对数据应用任何机器学习算法之前研究和采样数据之外,没有什么可以避免这种情况。

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

高偏差、完美拟合和高方差的直观表示(来源

偏差和方差的定义

对于熟悉统计学的读者来说,偏差和方差这两个术语一定不陌生。标准差衡量的是数据点离中心位置有多近或多远,从数学上来说,方差就是标准差的平方。因此,方差衡量的是一组数据分布的范围。用于机器学习任务的数据没有特定的输入-输出映射,这些模型的任务是找到足够好的映射来概括结果。一个机器学习模型,它(过)适合所有的数据点,包括有噪声的数据点,或者换句话说,适合所有的数据点,不管它们分布得有多广,都被称为遭受高方差。

在统计学中,估计量(这里是机器学习模型)的偏差(或偏差函数)是估计量的期望值和给定输入的真实值之间的差异。零偏差的估计量或决策规则称为无偏的。机器学习模型的高偏差是机器学习模型的输出与实际输出相差甚远的情况。这是因为模型简单。我们之前看到,具有高偏差的模型在训练集和测试集上都具有高误差。

偏差-方差权衡

偏差-方差权衡是监督机器学习算法的核心属性。理想情况下,我们需要一个机器学习模型,它考虑所有模式以及训练数据中的异常值,并将它们推广到测试(看不见的真实世界)数据,以便实现非常小的误差和非常高的准确性。我们之前看到,高方差模型非常复杂,可以很好地表示训练集的所有特征,从而使训练集的误差最小,但无法推广到看不见的数据。相比之下,高偏差模型表示极其简单的映射,并且可以将一些特征推广到看不见的数据,但是这些模型的简单性导致对训练集的欠拟合,并且当应用于训练集之外的数据时,生成具有较低方差(高偏差)的预测。特定机器学习模型应该具有的偏差和方差的理想量取决于误差(包括偏差误差、方差误差和噪声)的最小化。

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

偏差-方差权衡(来源

解决机器学习中的问题

建立机器学习模型是一个迭代的过程。看过数据集后,我们应该总是从简单的模型开始,然后不断增加它们的复杂性,直到我们在看不见的数据上得到想要的结果。极其简单的机器学习模型遭受高偏差,而极其复杂的机器学习模型遭受高方差。由于我们是从简单模型逐步过渡到复杂模型的,因此我们消除了高偏差的问题,但消除高方差并不容易,因为有些情况下,使用给定的一组参数和方法,我们无法获得最佳模型,而高方差模型需要经过处理才能获得最佳模型。所以先讨论几种解决方差大的方法。

解决高差异

考虑逻辑回归分类器的例子。如果我们说分类器过拟合训练数据,这意味着等式 y = sigmoid(Wx + b)的输出非常接近实际训练数据值。那么,过度拟合的根本原因是什么呢?显然,是我们在构建分类器时训练的参数值造成了机器学习模型的高方差(过拟合)。调整这些参数值有助于消除过度拟合,这个过程称为正则化。在正式术语中,正则化是添加信息以解决不适定问题或防止过度拟合的过程。正则化使参数值变小,这可以防止过度拟合。在这篇文章的后面,我们会看到为什么会这样。

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

高方差模型训练和测试误差

正规化

因为我们正在修改参数值,所以我们需要更新我们的成本函数,以便看到正则化的效果。 L2 正则化最常用于成本函数,并产生相当好的结果。L2 正则化后的成本函数为:

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

其中 y(i)表示训练示例 I 的实际输出,φ(z(I))是通过逻辑回归对训练示例 I 的预测值, λ 是正则化参数,||w||是权重 w 的向量的 L2 范数。权重的矢量化只不过是由向量包围的彼此堆叠的所有 Wi。Python 的机器库使用矢量化参数方程来加速计算。

假设向量 W 具有 3 个值 W1、W2、W3,则向量 W 的 L2 范数计算如下:

||W|| = sqrt(W1 + W2 + W3)

请注意,我们没有像在一般逻辑回归分类器中那样正则化参数 b,每个特征都有一个相应的 W 值,因此有多个 W 值和一个偏差 b 值,正则化偏差参数实际上没有任何区别。为了完整起见,我们通过在成本函数的末尾添加( λ/2)*||b|| 来正则化 b,并对两者使用单独的 λ 值。

为什么以及如何正规化工作?

现在,在执行梯度下降以更新参数时,更新将如下所示:

W = W — alpha * dJ/dW

b = b—α* dJ/db

dJ/dW 项由由于正则化而产生的附加项组成,并且在数值上是正值,即当代价函数被正则化时,代价函数 wrt W 的偏导数值比没有正则化时更大。因此,在更新参数时,我们从 W 的先前状态中减去一个更大的块,并且我们进行多次迭代,W 的最终值小于我们在没有正则化的情况下获得的值。同样,我们可以通过正则化来计算 dJ/db。

现在我们知道,正则化导致小的参数值,这导致收敛于代价函数的全局最小值。我们将使用带有“n”个例子的逻辑回归来看看为什么正则化有效。我们知道 y = sigmoid(w1x 1+w2x 2+w3x 3+…………+ Wnxn + b)。因为正则化导致比非正则化更小的参数值,所以让我们考虑参数值 Wi 非常小并且非常接近于 0。因此,逻辑回归分类器的输出将简单地为 y = sigmoid(b ),这是一个非常简单且非常差的输出估计。换句话说,这个输出非常简单,以至于它有一个极高的偏置。从偏差-方差权衡中,我们知道高偏差和高方差是机器学习模型的两个相反端,理想情况下,我们希望我们的模型处于两者之间。为了实现这一点,我们必须非常明智地选择正则化参数 λλ 是使用开发集设置的,其中我们尝试各种 λ 值,并选择一个为我们的机器学习模型产生最佳性能的值,然后使用该模型在测试集上进行预测。

像 L2 正则化一样,还有另一种类型的正则化项可以添加到成本函数中。添加此 L1 正则化项后的成本函数如下:

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

其中||w||是矢量 W 的 L1 范数,具有 3 个元素的矢量 W 的 L1 范数计算如下:

||W|| = |W1| + |W2| + |W3|其中,|Wi|代表 Wi 的绝对值。

添加更多培训数据

处理机器学习模型过度拟合的另一种方式是向训练集添加更多数据。这背后的原因很简单。如果机器学习模型在训练集上过度拟合,它也在学习数据中的噪声输入。添加更多的数据将导致数据中更多的噪声,并且机器学习模型变得难以考虑如此多的噪声,以至于它最终离开有噪声的输入,并且更加关注输入-输出对的一般模式。这导致模型不会过度拟合训练数据,并且没有高方差的问题。要添加到训练集中的数据量取决于机器学习模型的过拟合程度。

解决高偏置

机器学习模型中的偏见不是我们前面看到的大问题,并且很容易消除。由于高偏差导致极其简单的机器学习模型,该模型不能捕获所有必要的特征来进行更准确的预测,因此我们可以做以下事情来消除高偏差:

(I)使用比现有模型更复杂的机器学习模型(通过引入多项式特征而不是线性特征,如 y = Wx + b ),因为它可以很好地捕捉训练数据中的所有重要特征和模式。

(ii)我们看到正则化大幅缩小了参数值,这也可能导致高偏差。因此,减小正则化参数有助于消除高偏差。

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

高偏差模型训练和测试误差

在这篇文章中,我们首先发展了对高偏差和高方差的直觉,然后理解了当其中一个或两个都出现时,机器学习模型可能遇到的问题。后来,我们研究了从机器学习模型中消除高偏差和高方差的方法,并对正则化的工作提出了见解。

在下一篇文章的中,我们将看看另一种被称为支持向量机的监督机器学习方法,并将使用它来解决 Kaggle 的数据集。

使用 KDWD 的基于上下文的实体链接

原文:https://towardsdatascience.com/context-based-entity-linking-using-kdwd-69a633f9e4e7?source=collection_archive---------30-----------------------

由蔚茹·陈、迪安·哈索特、大卫·郑、泰勒·柳撰写

的代码可以在我们的 Github 上找到

海报可以在这里找到:**

我们要感谢ken sho的 Gabriel Altay 和 Georg Kucsko,感谢他们在整个项目中与我们分享时间和资源。

最后,我们感谢哈佛大学 IACS 的克里斯·坦纳对我们团队的宝贵指导,以及他在整个 顶点 经历中的领导。

简介

命名实体链接,也称为命名实体消歧(NED),是唯一识别文本中提到的实体(如个人、位置、公司或历史事件)的任务。举一个典型的例子,如果给定句子“巴黎是法国的首都”,我们希望能够辨别单词“巴黎”是指法国首都、其他城市、巴黎希尔顿还是许多其他可能性,如下所示。

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

图 1:维基百科的“巴黎”消歧页面

与命名实体识别(NER)——实际识别文本中提到的这种实体的过程——一起,NED 是自然语言处理(NLP)中最基本的任务之一;能够识别文本谈论的特定事物对于无数的自然语言处理应用来说是必不可少的,包括一般的文本分析、语义搜索系统、构建聊天机器人等等。

让我们考虑一个金融市场中有趣的例子来说明这项任务在 NLP 应用中的重要性。假设我们正在构建一个算法股票交易器,它被设计用来根据新闻事件进行交易。一天早上,我们的算法在一个新闻标题中发现了“特斯拉崩溃,吉姆·克莱姆期待反弹”这句话。马上,我们看到了一个我们的算法交易员必须能够解决的问题:“特斯拉”这个词是指上市公司、特斯拉汽车的一个实例,还是(荒谬地)尼古拉·特斯拉?这个问题对我们的投资组合有非常实际的影响;如果“特斯拉”指的是该公司,那么我们知道标题是说特斯拉股票暴跌,鉴于其目前的低价,这可能是购买特斯拉股票的好时机。另一方面,如果“特斯拉”指的是特斯拉汽车,我们知道这对特斯拉来说是一个坏消息(可能是自动驾驶技术的问题导致特斯拉汽车在高速公路上坠毁),这意味着现在是出售特斯拉股票的好时机。

作为人类,我们发现这个问题微不足道——我们可以很容易和自信地从标题其余部分的上下文中推断出,这实际上是指特斯拉股票,因为提到了实体“Jim Cramer”和“Rally”,以及这些实体与金融的关系。

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

图 2:维基百科中关于“吉姆·克莱姆”的条目

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

图 3:维基百科中“反弹(股票市场)”的条目

命名实体消歧的任务旨在对这种基于上下文的推理能力进行建模。

知识图和 KDWD

对基于上下文的推理能力进行建模的重要的第一步是开发可用于从上下文进行推理的知识的表示(例如,单词“集会”具有与“股票”相关的含义)。我们通过知识图来做到这一点,这是一个知识库的图形化表示,节点对应于实体,边对应于实体之间的关系(参见图 4)。

这样的表示有什么帮助呢?嗯,在我们上面的例子中,如果我们可以使用我们的知识图表来识别单词“集会”是股票市场运动的一个例子,我们就更接近于推断“特斯拉”指的是特斯拉股票。

对于我们的方法,我们使用 Kensho 衍生的维基媒体数据集(KDWD),这是由 Kensho 设计的维基数据知识图的结构化、多层呈现,Kensho 是最著名的机器学习和人工智能公司之一,部分专注于 NLP。Kensho 慷慨地向公众提供了 KDWD,为感兴趣的研究人员提供了一种资源来处理 NLP 任务,如消歧。

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

图 KDWD1 的鸟瞰图

KDWD 由三个数据层组成:维基百科文本、维基百科链接和维基数据图表。第一层,顾名思义,就是来自维基百科大量文章的文本。第二层添加链接标注,第三层是全知识图。KDWD 将图表过滤成 5100 万个条目和 1.4 亿条语句,比如“哈佛马克一号是计算机的一个实例。”我们将参考 KDWD 中包含的文件,这些文件可以在https://www . ka ggle . com/kenshoresearch/ken sho-derived-wikimedia-data上查看和下载

探索性数据分析

对于 KDWD 数据集,我们有两个主要目标:

  1. 创建带标签的训练/测试数据集
  2. 减少查找项目所需的时间

标注训练/测试数据集:

我们从’link _ annotated _ text . jsonl文件中生成了一个带标签的数据集。由于文本简介拥有最多的链接,也就是标签实体,我们创建了两个新的 CSV,一个包含 530 万个简介文本,另一个包含 3500 万个标签实体。这些步骤将大小从 17.7 Gb 减少到 3.7 Gb。

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

图 5:创建了维基百科介绍性文本和标签实体的 CSV 文件。

减少访问次数:

我们为基线模型使用了’ item.csv '、 item_aliases.csv ‘和’ page.csv '文件,如下所述。然而,在 item 和 item_aliases 中查找一个“item”的所有实例,然后将item _ id与相应的 page _ ids 链接起来,需要大约 1 分钟的时间。这当然太慢了,所以我们采取了以下步骤来大幅提高性能。

  1. ****减少数据集大小:我们通过删除在“ page.csv ”中不存在的带有 item_id 的所有项目,过滤了“ item.csv ”和“ item_aliases.csv ”数据集。这是因为我们的训练/测试数据集中的实体仅由 page_id s 标记。这将组合的 itemitem_aliases 数据集大小减少了 88.2%。

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

图 6:项目过滤

****2。重构数据以提高性能:减少数据集将每个实体的查找时间减少到大约 10 秒,但这仍然太慢了。因此,我们将数据结构改为字典,以利用 O (1)查找时间:

2.1.合并过滤后的’ item.csv 和’ item_aliases.csv ',这样我们只有两列: item_iden_label

2.2.小写并剥离所有 en_label 条目

2.3.通过 en_label 对数据集进行分组

2.4.将与每个 en_label 相关联的item _ id转换成一个列表,并丢弃重复的item _ id

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

图 7:带有 en_label 和相应item _ id的数据帧

2.5.创建一个字典,将 en_label 条目作为键,将相应的 item _ ids 列表作为值。

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

图 8:创建 2.5 中描述的字典的代码片段

完成上述所有步骤后,我们将项目数据集大小从 4.04Gb 减少到 177Mb。我们现在也有了近乎瞬时的查找时间。

基线建模

我们现在准备为实体链接开发一些简单的基线模型。

人气基线模型

第一个基线模型只是选择最流行的实体作为每次提及的实体预测。对于每个提及,我们从 item_dict 字典中识别出与之相关的所有 item_id 。每个 item_id 都唯一地链接到一个 page_id ,这是我们对实体的引用。对于每个 page_id ,还有一个相关联的页面视图,表明特定实体的受欢迎程度(也就是说,最‘受欢迎’的实体是具有最高维基百科页面视图的实体)。因此,对于每一次提及,我们可以创建一个候选实体列表,并给出它们各自的流行度值。然后,我们的基线模型预测提及的最受欢迎的实体。

第二个基线模型与第一个基线模型相同,只是它选择指向它的链接最多的实体作为每次提及的实体预测。

基线模型的算法: 给定一个提及 w ,其关联的实体候选 e_1e_2 ,…, e_k ,以及实体候选 p_1p_2 ,…,的页面浏览量(或第二基线模型中指向它的链接数)

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

并返回 e_m 。所以对于提 w 的实体的预测是:

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

带有单词嵌入的基线模型

对于给定段落中的任何提及,我们首先使用 spaCy 包来识别上下文窗口中所有相邻的命名实体。然后,我们从 google2vec 模型中加载预训练的单词嵌入,并将单词嵌入分配给所有实体。通过计算我们在上下文窗口中识别的相邻命名实体的词嵌入和每个提及的实体候选的词嵌入之间的余弦相似度,这个具有词嵌入的基线模型然后用与相邻实体具有最小余弦距离的实体来标记提及。

具有单词嵌入的基线模型的算法: 给定一个提及 w ,其关联的候选实体 e_1e_2 ,…, e_k ,以及相对于候选实体 p_1p_2 ,…, p_k 的单词嵌入,识别所有邻近的命名实体 n 然后,计算每个候选实体的单词嵌入和相邻命名实体的单词嵌入之间的平均余弦距离:

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

查找:

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

并返回 e_m 。所以对于提 w 的实体的预测是:

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

模型评估的标准:
我们使用总体准确率作为评估所有基线模型的标准。我们从来自 link_annotated_text.jsonl 文件的 combined_entity_df 数据帧中随机抽取 k = 20,000 个项。这些被采样的项目都来自文本数据,它们的实际实体是已知的。因此,对于每个项目 wi,我们从基线模型中获得其预测实体 predi,从组合的 _entity_df 数据框架中获得其实际实体 yi。整体准确率测量为 1 {pred _ I= =y _ I}/k .

所有基线模型的结果和见解:

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

图 9:所有基线模型准确性得分

基于来自组合 _ 实体 _df 数据帧的采样项目,我们的第一流行度基线模型具有 61.83%的准确率,第二流行度基线模型具有 59.135%的准确率。这表明我们的流行度基线模型表现相对较好,考虑到它完全基于流行度选择,并且项目的上下文信息(在文本数据中提及)被完全丢弃。

我们的带有单词嵌入的基线模型表现最好,准确率为 66.74%,略好于前两个基线模型。

超越基线:作为组合优化的歧义消除

我们对开发一种更复杂的方法感兴趣,这种方法使用 KDWD 图结构中的连通性信息来消除歧义。具体来说,当我们看到一个目标单词 X 及其候选消歧词 d_1,d_2,…,d_n 时,我们希望图结构告诉我们候选词集中的哪个 d_k 与目标单词的上下文窗口(包含该单词的句子)中的其余单词在语义上最相关。

Hulpus 等人提出了一种有趣的用于图形表示的联合消歧方法。这种方法将消除歧义视为一个组合优化问题。因此,给定一个目标单词 X 和它的上下文窗口,我们识别上下文窗口中的所有歧义术语。然后,我们考虑所有唯一的歧义消除组合,并选择一个最小化所有歧义术语的所有不同成对行走距离总和的组合。

正式地说,对于消歧的唯一组合的集合 D,如果我们将 w(a,b) 定义为在图上从节点 a 移动到节点 b (沿着经由 BFS 找到的最短路径)的行走次数,我们的消歧选择 D 被定义如下:*

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

作为一个例子,考虑这句话,“本田在电动车行业与捷豹竞争。”三个突出显示的实体及其所指的候选集是:

本田:[H1:企业家,H2:汽车品牌]

捷豹:[J1:汽车品牌,J2:动物]

电动汽车:[E1:电动汽车,E2:期望值]

因此,所有这些可能的组合是:

(H1,J1,E1),(H1,J1,E2),(H1,J2,E1),(H1,J2,E2),(H2,J1,E1),(H2,J1,E2),(H2,J2,E1),(H2,J2,E2)

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

图 10:显示示例节点之间语义距离的示例图

现在,使用图 10 中显示这些候选的图形部分,我们测量每个组合的成对距离之和,例如,对于第一个组合, D(H1,J1) + D(H1,E1) + D(E1,J1) 。然后,我们选择最小化该度量的组合,从而最大化语义相关度。

结果和未来可能性

在我们测试基线模型的同一数据集上评估该模型,我们实现了 85.5%的准确率,比基线有了显著提高,并且与具有完全不同的高度调整范例的最先进方法相差不远。

速度提升

为了大规模测试这种方法的可行性,必须提高计算效率。我们看到了通过图嵌入和图截断等技术对预测和评估的图遍历瓶颈的潜在改进。

与最先进基线模型的比较

有了更高的计算效率,我们可以在不使用上下文窗口预测的高级消歧学习技术和使用我们的上下文方法的类似技术之间进行富有成效的比较。

参考文献

[1]加布里埃尔·阿勒泰。"介绍 Kensho 衍生的维基媒体数据集."2020 年 2 月 3 日。https://blog . ken sho . com/announcing-the-ken sho-derived-wikimedia-dataset-5d 1197d 72 BCF

[2] OpenAI,“发现实体消歧的类型。”2018 年 2 月 7 日。https://open ai . com/blog/discovering-types-for-entity-diffusion/

[3] Hulpus,Ioana,Narumol Prangnawarat,Conor Hayes。"基于路径的关联数据语义相关度及其在词和实体消歧中的应用."爱尔兰国立大学高威分校数据分析洞察中心(NUIG)。2015.

上下文管理器:数据科学家的观点

原文:https://towardsdatascience.com/context-managers-a-data-scientists-view-9733392ff9c9?source=collection_archive---------40-----------------------

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

https://unsplash.com/photos/KVihRByJR5g?utm_source=unsplash&UTM _ medium = referral&UTM _ content = creditShareLink

python 上下文管理器如何清理您的代码

这篇文章是一个系列的一部分,在这个系列中,我将分享我在干净的 python 代码这个主题上所学到的东西。我是一名数据科学家,希望通过编写更多的 python 代码来提升自己的 python 技能,并找到更好的方法来构建更大的代码库。我正在通读 Python 中的干净代码,并用其他资源丰富材料。我的目标是通过在这里总结来巩固我正在学习的主题,并希望帮助其他人理解这些主题!

这篇文章是关于 Python 中的上下文管理器的。首先,我将描述什么是上下文管理器,以及它们为什么有用。然后,我将带您看一个 web 抓取的实际例子。

什么是上下文管理器?

描述上下文管理器的最好方式是展示一个几乎每个 Python 程序员都在某个时候遇到过的例子,而不知道他们正在使用它!下面的代码片段打开一个. txt 文件,并将这些行存储在 python 列表中。让我们看看这个是什么样子的:

with open('example.txt') as f:
    lines = f.readlines()print(lines)

我们来分析一下。第一行打开一个文件,并将文件对象分配给f。下一行在 file 对象上执行readlines方法,返回一个列表,列表中的每一项代表example.txt文件中的一行文本。最后一行打印列表。使它成为上下文管理器的原因是,一旦 with 语句下的缩进被退出,文件就会被隐式关闭。如果没有上下文管理器,代码将如下所示:

f = open('example.txt')
lines = f.readlines()
f.close()print(lines)

使用上下文管理器使其可读性更好。想象一个打开和关闭多个文件的脚本,它们之间有操作行。它可能会变得难以阅读,并且您很容易忘记关闭文件。即使遇到异常,也要保证成交。

编写自己的上下文管理器

为了说明如何编写自己的代码,我们将使用一个实际的例子。我最近在使用 selenium 进行网络抓取时遇到了一个问题,我无法在现有的浏览器中打开一个新的 url。解决方案是打开一个新的浏览器来访问 url,并在我收集完数据后关闭它。有两种方法可以做到。我们将从定义一个类开始,并使用__enter____exit__ dunder 方法。

# imports
from selenium import webdriver
from selenium.webdriver.common.keys import Keys# define context manager class
class OpenBrowser():

    def __enter__(self):
        self.driver = webdriver.Chrome(chrome_driver_path)
        return self.driver

    def __exit__(self, exception_type, exception_value, 
                 exception_traceback):
        self.driver.close()# use context manager
with OpenBrowser() as driver:
    driver.get("[http://www.python.org](http://www.python.org)")
    elem = driver.find_element_by_name("q")
    elem.clear()
    elem.send_keys("pycon")
    elem.send_keys(Keys.RETURN)
    html = driver.page_sourceprint(html)

这看起来很复杂,其实不然。你用__enter()____exit()__定义了一个类,它们分别定义了当你通过with调用它时会发生什么,以及当你退出缩进时会发生什么。__exit__的参数是固定的,而__enter__的返回值是可选的。现在读者很清楚,这个驱动程序的存在只是为了在 python.org 搜索 pycon 并获取结果 html。无论发生什么,浏览器都会关闭。

这个语法不算太差,但是有更简单的方法。上下文库提供了一个 decorator 来处理 boiler 板,并用函数替换类。让我们看看上面的例子是如何使用装饰器的:

# imports
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import contextlib[@contextlib](http://twitter.com/contextlib).contextmanager
def open_browser():
    driver = webdriver.Chrome(chrome_driver_path)
    yield driver
    driver.close()with open_browser() as driver:
    driver.get("[http://www.python.org](http://www.python.org)")
    elem = driver.find_element_by_name("q")
    elem.clear()
    elem.send_keys("pycon")
    elem.send_keys(Keys.RETURN)
    html = driver.page_source

这里,我们只是导入contextlib并用 contextlib.contextmanager 修饰一个函数。该函数需要有一个 yield 语句,yield 值是可选的,但它告诉上下文管理器__enter____exit__出现的位置,分别在 yield 之前和之后。

结论

我希望我不仅足够好地解释了上下文管理器,而且让你相信它们在你的工具箱中非常有价值。即使作为一名数据科学家,我也发现了许多这些派上用场的案例。欢迎留下任何问题或评论,编码愉快!

法律行业与技术和数据科学的复杂关系

原文:https://towardsdatascience.com/contextualising-the-legal-industry-e5ecb406b6f7?source=collection_archive---------72-----------------------

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

Giammarco Boscaro 在 Unsplash 上拍摄的照片

法律技术中的数据科学

采访阿培尔的斯蒂芬·威尔科克

最近,我们有机会与法律技术公司 Apperio 的首席技术官 Stephen Wilcock 进行了一次交谈。他分享了对整个法律行业的见解;它对创新的立场以及法律技术补充法律的方式。此外,我们还简要讨论了渴望进入法律技术行业的学生应该具备的技能。

为了更好地理解法律技术,最重要的是理解整个法律行业的背景。法律科技是一个新生的新兴行业,仍然比它更著名的兄弟 Fin-Tech(金融科技)落后十年。斯蒂芬将此归因于法律的本质,更具体地说是商法,它构成了英国所有法律支出的绝大部分。商法中的两个主要当事方是律师事务所,另一方是由总法律顾问(“ GC ”)领导的内部法律部门。全科医生向律师事务所支付法律工作和咨询费用;它们是成本中心,因此在它们所属的公司中“不太受欢迎”。因此,他们产生的成本往往被认为是表面价值,并受到审查。

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

作者图片

没有这种外部压力,律所就缺乏创新的动力。除了极少数例外,它们都是以合伙模式运行的;历史上禁止接受可能损害独立性的外部股东的资本。合作伙伴可能对技术创新不感兴趣,原因有几个。首先,创新是昂贵的——这对一个花股东钱的 CEO 来说可能是微不足道的——合伙人花他们自己的钱;虽然合伙人已经赚了很多钱,但是任何投资都是他们的底线。此外,由于个人合伙人已经获得了巨额收入,他们几乎没有独立改变任何事情的权力。此外,法律领域惯用的按小时计费模式会削弱提高效率的内部商业案例。如果一项法律工作花费的时间更长,客户的账单会更多。这就是 Clayton Christensen 描述的经典的“创新者困境”:在其他人破坏它们之前,公司能否让自己进行昂贵的效率投资,在短期内蚕食其收入,以维护公司的长期竞争力。

根据 Stephen 的说法,摆脱这种困境的方法将通过一系列的措施来实现,包括:不断增加的客户压力,新型结构的出现;如进入法律市场的四大咨询公司,以及“在稳固的商业优势下”提供较低成本的公司。这些因素的结合开始施加必要的外部压力,以改变律师事务所合伙人的计算方式,促进法律行业更快速的技术创新。

创新针对法律行业的两个方面;斯蒂芬称他们为:T2 的法律实践和 T4 的法律事务。法律实践处理实际法律工作的机制。这一领域的技术解决方案通常侧重于研究、证据收集、文本处理以及某些情况下的评估和决策。这些解决方案通常以使用人工智能技术自动化重复活动为目标,如自然语言处理或机器学习。另一方面,法律业务与法律工作本身关系不大,而是专注于法律领域中资金如何转手的机制,其中涉及工作流程工具和分析。大多数法律科技公司都在这两者之间运营。Apperio 提供法律支出跟踪,专门处理法律事务。

在评估对那些渴望进入该领域的人有益的技能组合时,法律技术中这两个领域的区别也是相关的。在主要处理法律事务时,斯蒂芬承认法律知识并不是他进入这个行业的先决条件。尽管领域知识可能对那些进入法律行业的人更有意义,但对工程师来说,领域知识不如其他部门的员工重要。“当你开始研究数据科学的细节时,你可以在任何领域研究数据科学,同样,图像识别技术可以观察乳房 x 光片或汽车上的凹痕”。评价这两个方面的重要性,斯蒂芬说;“技术位用 60 号字体,法律位用 4 号字体”。

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

作者图片

技术专家需要的关键领域知识通常是由专家提供给他们的,这些专家是为完成特定任务而请来的。唯一真正需要综合法律和技术知识的团队是创始团队。总的来说,他们需要具备识别和阐明他们打算解决的法律问题的知识,以及看到和理解潜在的技术解决方案。

帮助那些对法律技术感兴趣的人,斯蒂芬发现学术数据科学的区别尤其重要。“当人们去大学[…]时,大部分都围绕着[…]如何围绕数据做出决策;你得到了这个很好的数据集;找出这条路径、相关性或模式。”在像法律技术这样的新兴行业中,情况非常不同,大多数数据结构不良,存储在传统的本地技术中。因此,更大的初始挑战是在进入实际的数据科学之前,对基础数据集进行检索、聚合、清理、规范化和修剪。

现在我们已经有了必要的背景,我们可以更好地理解法律技术公司在法律行业中可以和确实扮演的角色,从 Apperio 开始。本系列的下一篇文章将详细介绍 Apperio 提供的产品以及 Apperio 如何与法律行业互动。

【1】参见 2007 年《法律服务法》颁布后,法律中出现的替代性企业结构(ABS)

这篇文章最初发表在 UCL 数据科学协会的数据博客上,现在仍然可以在那里找到,此外还有许多其他有见地的文章讨论数据科学的最新发展。

[## 帖子| UCLDSS

数据科学可能是人类最有用的发明之一。我们研究和建立共享 DS 系统和博客…

www.ucldss.co.uk](https://www.ucldss.co.uk/blog/)

持续学习——我们在哪里?

原文:https://towardsdatascience.com/continual-learning-where-are-we-d5706e78a295?source=collection_archive---------15-----------------------

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

图像来源

随着深度学习社区旨在弥合人类和机器智能之间的差距,对能够适应不断发展的环境的代理的需求比以往任何时候都更大。这一点在 ICML 2020 上表现得很明显,该展会举办了两场不同的研讨会,主题分别是持续学习终身学习。作为一名与会者,我收集了我认为将影响该领域即将到来的发展的关键要点,包括两个方面:(a) 体验回放(无论是真实的还是增强的)对于最佳表现是不可或缺的,以及(b)一个暂时进化的智能体必须意识到任务语义。在这篇博文中,我将尝试阐明这些特质对于持续学习(CL)代理人的有效性。

【虽然有上述术语的背景会有所帮助,但这篇文章是为没有持续学习文献知识的读者准备的。]

快速复习:在任务增量设置中,持续学习代理在时间步长‘t’被训练识别任务 1,…,t-1,t 而任务 1,…,t-1 的数据可能可用也可能不可用。这种学习动力有两个主要障碍需要克服。第一个是正向迁移(FT) ,它衡量学习如何递增到任务 t 影响代理的知识。就性能而言,一个正** FT 表明,如果允许代理通过任务 1、…、t-1 逐步学习,它应该在任务 t 上提供更好的准确性。

另一个令人满意的特性是反向迁移(BT) ,它测量学习一项任务 t 对先前任务表现的影响。一个正的 BT 意味着学习一个新的任务 t 会提高模型在先前学习的任务 1,…,t-1 上的性能。这种在学习新任务的同时保留先前学习任务的知识的折衷被称为可塑性-稳定性权衡。

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

持续学习代理的三个权衡:当计算效率高的代理同样令人满意时,可伸缩性开始发挥作用。

基于增量任务训练时采取的步骤,连续学习文献主要包括两类代理来处理上述权衡:(a) 基于经验重放的代理通常存储来自先前任务的有限数量的示例(真实的或生成的)并将这些与新任务的训练数据混合在一起,以及(b) 基于正则化的方法使用额外的损失项来巩固先前的知识。记住这些,现在让我们进入真正的问题!

1.为什么基于记忆预演的方法效果更好?

Knoblauch 等人的工作是 2020 年 ICML 会议上 CL 领域的一个亮点,Knoblauch 等人通过集合论的方法表明,一个最优的连续学习算法需要解决集合相交决策问题的 NP-hard 问题,给定两个任务 A 和 B,它需要辨别 A 和 B (A ∩ B)的学习所共有的参数。然而,确定这一点至少与确定A∩B 是否为空一样困难(并且可能被认为是击中集合问题?)并且解决方案需要对以前的任务示例有完美的记忆。

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

图片来源:Knoblauch 等人(2020)。左图:最优 CL 算法搜索满足所有观察任务的任务分布的参数。右图:基于重放的 CL 算法试图找到满足实际任务分布(SAT1:3)的重构近似值(SAT(Q1:3))的参数。

这种完美的记忆有助于重建所有观察到的任务上的联合分布的近似,使得算法现在有效地学习求解单个时间分布的任务,,即,对于时间步长 t ,这相当于找到跨越 1:t 的任务分布的共同表示。我们在 CL 研讨会上的工作进一步倡导了基于重放的方法在人类活动识别环境中的经验有效性[2]。

除了集合论之外,还可以通过参数训练的动态性,将持续学习视为一个学分分配问题来看待重播的好处。正如我们所知,梯度下降通过迭代更新神经网络的参数来工作,目标是最小化训练集的总损失。因此,训练过程可以被视为拔河游戏,其中目标函数导致每个参数的值增加或减少,较大的正值指示该参数应该被分配更多的信用并且更重要。

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

图片来源:足球蔻驰

因此,在给定的增量时间步长,我们可以将每项任务视为一个团队试图以与训练算法最小化任务损失所需的动量相等的张力来拉动拖船。由此带来的后果是,在每一个增量步骤中,都需要对所有先前和当前的任务进行评估,以平衡这种紧张关系。在给定任务在特定情况下不存在的情况下,模型的参数空间将被更新以被剩余的任务占据。因此,在基于经验重放的方法中,同时存在来自所有先前任务的数据有助于更好地平衡拔河游戏各方之间的紧张关系,同时没有单一任务目标完全支配训练标准。

2.任务语义如何影响 CL 代理的性能?

合作学习研讨会的另一个亮点是 Ramesesh 等人 (2020)研究任务之间的相似性如何影响遗忘程度。他们的结论是,当前一个任务和后一个任务之间的表征相似度为中等时,网络具有最大遗忘。

为了理解这一点,我们需要根据模型学习的权重向量的分量来考虑后续任务的 CL。对于不相关的任务,所学习的权重向量保持彼此正交,而对于具有高相似性的任务,权重向量分量具有最小的角度间隔。受梯度下降训练影响的权重向量 θ 的唯一分量是位于训练数据子空间中的分量,而受训练影响最小的分量是与训练数据子空间正交的分量(见下图,改编自他们的谈话)。

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

玩具线性回归模型的权重向量的分量

Ramesesh 等人提供了两个描述性的 CL 设置来支持他们的假设。在设置 1 中,模型被训练为将船-卡车分类为第一任务,然后将猫-马或飞机-汽车分类为第二任务,我们看到猫-马识别任务遭受更多遗忘。在设置 2 中,首先训练模型来识别鹿-狗-船-卡车,然后是飞机-汽车识别,对于船-卡车,性能降级最大。

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

Rama sesh 等人(2019)的两个增量学习设置:(a)设置 1 首先在船-卡车分类问题上训练模型,然后是任务 2,任务 2 可以是猫-马或飞机-汽车分类,(b)设置 2 训练模型首先识别鹿、狗、船和卡车,然后是飞机-汽车识别。

作者指出,在设置 1 中,模型只为车辆建立其表征,因此在第二个任务中动物(猫-马)越来越不相似的表征导致对先前学习的车辆表征的更多遗忘。然而,设置 2 涉及同时在车辆和动物上训练模型,因此动物的表示现在在潜在空间中占据与车辆不同的区域。结果,当面对后一项任务时,动物的学习表征与飞机和汽车的学习表征是正交的,并且退化较少。

本节的其余部分试图从传递干扰的角度对此进行解释。里默尔等人(2019)首先从迁移-干扰权衡的角度来看待持续学习。为了理解这一点,让我们先深入了解一下稳定性-可塑性困境的局限性。正如我们之前看到的,困境表明可以通过减少遗忘来提高学习模型的稳定性,到目前为止,它保持检查由于当前任务的学习而导致的权重转移,同时最小化由于共享对先前任务重要的权重而导致的干扰。

然而,由于我们对未来任务可能会是什么样子的了解有限,最小化先前任务的权重共享仅解决了问题的一半——与先前学习的任务之一非常相关的未来任务可能需要进一步共享这些权重,并且模型必须能够在不中断先前任务的性能的情况下这样做。我们注意到,显然需要扩展稳定性-塑性两难问题的时间限制,以便考虑未来任务的不确定性。

迁移-干扰权衡考虑了由于增量任务的学习而产生的反向干扰,同时还检查了权重之间的表示的迁移,使得它们不会损害未来的学习。因此,里默尔等人的研究表明,使用相同权重成分学习的任务很有可能在范例之间产生干扰和迁移,而使用不同成分学习的任务受到的迁移和干扰较少。

记住上述观点,现在让我们看看 Ramasesh 等人的两个 CL 设置。在设置 1 中,船-卡车分类任务不同于增量猫-马任务,并且由于模型试图使用相同的权重分量来学习它们,高干扰导致对先前任务的更大遗忘。

然而,在设置 2 中,我们看到该模型被迫对鹿狗和轮船卡车采用不同的表示。由于飞机-汽车的表征更类似于轮船-卡车的分类任务,并且要使用相同的权重分量来学习,这催化了它们之间的权重转移,从而导致更大的遗忘。另一方面,鹿和狗的表示具有与平面和汽车的表示正交的分量,因此不受它们之间禁止的重量转移的影响。

**结论:**简而言之,我们看到了一个持续学习的代理如何在每个训练步骤中面临一个学分分配问题,以及经验回放如何增强每个手头任务的可信度。此外,任务的语义在被试的遗忘量中起着重要的作用,这可以从迁移干扰的角度来解释。随着该领域继续向大规模和独立于领域的学习发展,更好地理解这些权衡确实是元学习者等更高级培训策略的关键[3]。

参考

  1. Knoblauch、h . husa in 和 t . die the(2020 年)。最优连续学习具有完美的记忆,并且是 NP 难的。 ArXiv,abs/2006.05188
  2. 韩建华,,米,,叶(2020)。人类活动识别中的持续学习:正则化的实证分析。 ArXiv,abs/2007.03032
  3. m .、Cases、I .、Ajemian、r .、Liu、m .、Rish、I .、Tu、y .、& Tesauro、G. (2019)。通过最大化迁移和最小化干扰来学会学习而不遗忘。 ArXiv,abs/1810.11910
  4. Ramasesh,v .,Dyer,e .,和 Raghu,M. (2020 年)。灾难性遗忘的剖析:隐藏表征和任务语义学。 ArXiv,abs/2007.07400

朴素贝叶斯分类器中的连续数据和零频率问题

原文:https://towardsdatascience.com/continuous-data-and-zero-frequency-problem-in-naive-bayes-classifier-7784f4066b51?source=collection_archive---------9-----------------------

如何从数学和概念上处理它

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

凯文·Ku 在 Unsplash 上的照片

在监督学习(分类)的背景下,朴素贝叶斯或者更确切地说贝叶斯学习作为评估其他学习算法的黄金标准,同时作为一种强大的概率建模技术。但是,使用朴素贝叶斯会带来一些挑战。

  • 与数值数据相比,它在分类数据的情况下表现良好。那么,当我们拥有的数据本质上是连续的时,我们如何使用朴素贝叶斯进行分类呢?
  • 如果测试数据集中的一个实例有一个在训练期间不存在的类别,那么它将赋予它“零”概率,并且不能进行预测。这就是所谓的**零频率问题。**它扭曲了分类的整体性能。作为一个机器学习爱好者,每个人都应该知道如果出现这种情况应该如何应对。

在这篇文章中,我们将讨论朴素贝叶斯分类器对数字/连续数据的工作原理和零频率问题,以便它可以在以后应用于现实世界的数据集。

这里有两种方法来估计朴素贝叶斯分类器中连续属性的类条件概率:

  • 我们可以将每个连续属性离散化,然后用其对应的离散区间替换连续的属性值。这种方法将连续属性转换为有序属性。条件概率 P(X|Y= y ),其中 Y 是目标变量,是通过计算属于类别 y 的训练记录中落在 X 的相应区间内的部分来估计的

估计误差取决于离散化策略以及离散区间的数量。如果间隔的数量太大,则每个间隔中的训练记录太少,无法为 P(X|Y)提供可靠的估计。另一方面,如果间隔的数量太小,那么一些间隔可能聚集来自不同类的记录,并且我们可能错过正确的决策边界。因此,离散化策略没有经验法则。

  • 我们可以假设连续变量的某种形式的概率分布,并使用训练数据来估计分布的参数。通常选择高斯分布来表示连续属性的类条件概率。该分布由两个参数表征,均值和方差。

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

图片 1

现在,我们已经为如何将高斯分布用于连续属性建立了基础,让我们通过一个示例来看看如何将其用作机器学习中的分类器:

以下是我们将使用的数据集:

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

威滕、弗兰克和霍尔的数据挖掘

在这个特定的数据集中,我们总共有 5 个属性。其中 4 个是我们将要预测的自变量(天气、温度、湿度、风力),一个是因变量(玩耍)。这是一个二元分类问题,因为因变量具有布尔性质,包含“是”或“否”。数据集是序数和数字属性的混合。温度和湿度是数字。Outlook 和 Windy 是序数属性。

由于这是非确定性的或者更确切地说是概率性的方法,因此模型没有学习

我们将对一个实例进行分类

x = <前景=晴朗,温度=66,湿度=90,风=真>

为了计算这个,我们需要目标变量 Play 的先验概率

实例总数为 14,其中 9 个实例的值为 yes ,5 个实例的值为 no

p(是)= 9/14

p(否)= 5/14

按照目标变量,自变量的分布可以写成:

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

图片 2

为了对实例 *x,*进行分类,我们需要计算 play=yesplay=no 的最大可能性,如下所示:

播放的可能性=是

P(x/是)* P(是)= P(晴天/是)* P(温度= 66/是)* P(湿度= 90/是)* P(真/是)* P(是)

发挥的可能性=否

P(x/否)* P(否)= P(晴/否)* P(温度= 66/否)* P(湿度= 90/否)* P(真/否)* P(否)

由于天真的独立假设,属性个体概率成倍增加。

对于温度和湿度属性,可以使用图像 1 中的高斯分布公式,通过插入图像 2 中属性的平均值和方差值来计算概率。

计算上述等式所需的值为:

p(晴天/是)= 2/9

p(温度= 66/是)= 0.034

p(湿度= 90/是)= 0.0221

p(真/是)= 3/9

p(晴/否)= 3/5

p(温度= 66/否)= 0.0279

p(湿度= 90/否)= 0.0381

p(真/否)= 3/5

P(x/是)* P(是)=(2/9)* 0.034 * 0.0221 (3/9)(9/14)= 0.000036

P(x/否)* P(否)=(3/5)* 0.0279 * 0.0381 (3/5)(5/14)= 0.008137

0.008137*>*0.000036

分类—无

现在,我们已经在朴素贝叶斯分类器中转移了对连续/数字数据的处理,让我们深入研究如何处理零频率问题。

当在整个可能性乘法中任何一个概率为零的条件使得整个可能性为零时,就会发生这种情况。在这样的情况下,有一种叫做的拉普拉斯估计器被使用。

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

图 3

在哪里,

NC = Xi = x 和 yi = y 的实例数,

yi = y 的实例数,

p =先验估计,示例:假设属性值 p=1/ m 均匀分布,其中 m 定义不同(唯一)属性值的数量。

m =该属性的唯一值的数量。

因此,如果假设均匀分布,图像 3 中的公式修改如下:

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

图 4

T 他对图 3 中公式的解释可能有点难以理解。让我们借助一个例子来更好地理解它:

我们将在图像 1 和图像 2 中使用相同的数据集和分布对实例进行分类。

x = <前景=阴天,温度=66,湿度=90,风=真风>

为了计算这个,我们需要目标变量发挥的先验概率

实例总数为 14,其中 9 个实例的值为 yes ,5 个实例的值为 no

p(是)= 9/14

p(否)= 5/14

按照目标变量,自变量的分布可以写成:

为了对实例 x,进行分类,我们需要计算播放=是播放=否的最大可能性,如下所示:

播放的可能性=是

P(x/是)* P(是)= P(阴/是)* P(温度= 66/是)* P(湿度= 90/是)* P(真/是)* P(是)

活动的可能性=否

P(x/否)* P(否)= P(阴/否)* P(温度= 66/否)* P(湿度= 90/否)* P(真/否)* P(否)

计算上述方程所需的新值为:

p(阴/是)= 4/9

p(阴/否)= 0/5 = 0

计算可能性所需的其余值取自前面的例子本身。

P(x/是)* P(是)=(2/9)* 0.034 * 0.0221 (3/9)(9/14)= 0.000036

P(x/否)* P(否)= 0 * 0.0279 * 0.0381 (3/5)(5/14)= 0

0.000036 > 0

分类—是

这里可以看出,一个条件概率 P(阴/否) 是分类的驱动因素。现在,让我们看看在均匀分布假设下,如何利用来自图像 4拉普拉斯估计器的公式。

对于**前景=阴天,**新的概率变成

p(阴/是)= (4 + 3 * (1/3)) / (9 + 3)= 5/12

在哪里,

nc = 4,因为 Outlook =阴天& play =是,

n = 9,因为 play = yes 的实例总数,

m = 3,因为属性 Outlook 具有 3 个唯一值(晴天、阴天、雨天),

p = 1/ m = 1/3,因为假设均匀分布

同样的,

p(阴/否)= (0 + 3 * (1/3)) / (5 + 3)= 1/8

在哪里,

nc = 0,因为 Outlook =阴天& play =否的 0 个实例,

n = 5,因为 play = no,

m = 3,因为属性 Outlook 具有 3 个唯一值(晴天、阴天、雨天),

p = 1/ m = 1/3,因为假设均匀分布

注意:在应用拉普拉斯估计器时,请确保将其应用于所有有序属性。你不能仅仅将 is 应用于零频率问题发生的属性。

因为在我们的实例中要分类的另一个有序属性是属性 Windy,所以我们也需要在那里应用拉普拉斯估计器。应用修改后的概率为:

对于 **Windy = True,**新的概率变成

p(真/是)= (3 + 2 * (1/2)) / (9 + 2) = 4/11

在哪里,

nc = 3,因为在 3 个例子中 Windy = True & play = yes,

n = 9,因为 play = yes 的实例总数,

m = 2,因为属性 Windy 有 2 个唯一值(真,假),

p = 1/ m = 1/2,因为假设均匀分布

同样的,

p(真/否)= (3 + 2* (1/2)) / (5 + 2)= 4/7

在哪里,

nc = 3,因为 Windy = True & play = no 的 3 个实例,

n = 5,因为 play = no,

m = 2,因为属性 Windy 有 2 个唯一值(真,假),

p = 1/ m = 1/2,因为假设均匀分布

P(x/是)* P(是)=(5/12)* 0.034 * 0.0221 (4/11)(9/14)= 0.0000731

P(x/否)* P(否)= 1/8 * 0.0279 * 0.0381 (4/7)(5/14)= 0.0000271

0.0000731 > 0.0000271

分类—是

尽管分类没有改变,但现在我们有了更好的科学推理来支持我们的结论。

如果你喜欢阅读这样的故事,并想支持我成为一名作家,可以考虑注册成为一名媒体会员。每月 5 美元,你可以无限制地阅读媒体上的故事。如果你注册使用我的链接,我会赚一小笔佣金,不需要你额外付费。

[## 加入我的推荐链接-塔伦古普塔

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

tarun-gupta.medium.com](https://tarun-gupta.medium.com/membership)

我将免费赠送一本关于一致性的电子书。在这里获得你的免费电子书。

感谢您的阅读。我希望阅读这篇文章的人能够弄清楚朴素贝叶斯分类器中连续数据和零频率问题的处理。如果你觉得它能帮助别人,就分享吧。你可以在这里阅读我的更多帖子:

[## 标记故事列表的快速链接—感谢您的访问

我也有一份以快节奏出版为目标的出版物。读书成为作家。

tarun-gupta.medium.com](https://tarun-gupta.medium.com/thank-you-for-visiting-my-profile-9f708062c75e)

机器学习系统的连续交付

原文:https://towardsdatascience.com/continuous-delivery-for-machine-learning-8770390db18c?source=collection_archive---------34-----------------------

以可持续的方式安全快速地将机器学习系统部署到生产中

目录

什么是持续交付?
持续集成
持续交付与持续部署
机器学习工作流程
持续交付如何帮助应对 ML 挑战?
数据管理

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

机器学习的连续交付

传统软件开发的大多数原则和实践都可以应用到机器学习(ML)中,但某些独特的 ML 特定挑战需要以不同的方式处理。我们在之前的文章中讨论了那些独特的“将机器学习模型部署到生产中的挑战”。本文将探讨如何将帮助传统软件解决其部署挑战的连续交付应用于机器学习。

什么是持续交付?

持续交付是以可持续的方式安全、快速地将所有类型的变更(包括新功能、配置变更、错误修复和实验)投入生产或交付给用户的能力。

-杰兹·亨布尔和戴夫·法利
(连续交付图书作者)

以下是书中定义的持续交付原则,你可以在这里了解更多

  • 将质量建立在
  • 小批量工作
  • 计算机执行重复的任务,人解决问题
  • 坚持不懈地追求持续改进(Kaizen)
  • 每个人都有责任

连续累计

持续集成(CI)应该是团队开始持续交付之旅的第一步。正如您在下面的定义中所看到的,CI 有助于尽快发现任何集成错误,从而提高团队生产力。

持续集成是一种软件开发实践,团队成员经常集成他们的工作,通常,每个人至少每天集成一次——导致每天多个集成。每个集成都由一个自动化构建(包括测试)来验证,以尽可能快地检测集成错误。

——马丁·福勒

持续交付与持续部署

在本文中,我们不会过多地讨论持续部署,但是理解持续交付和持续部署之间的区别是有好处的。如下图所示,在部署到生产环境之前,连续交付包括一个手动批准步骤。尽管如此,每次代码被推送到主分支时,它都会经过各种自动化步骤,并准备好进行部署。同时,如果所有步骤都成功,它会自动将新代码部署到生产环境中,以防持续部署。

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

图 1: 连续交付连续部署

机器学习工作流

正如我们在上一篇文章中看到的,典型的 ML 工作流包括数据管理、实验和生产部署,如下图所示。我们将挑战分为三个阶段。

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

图 2: 机器学习工作流程

持续交付如何帮助应对 ML 挑战?

现在,让我们看看连续交付如何帮助解决机器学习的具体挑战。我们将回顾 ML 工作流程的每个阶段,它的挑战,以及 CD 如何解决它们。

数据管理

训练数据集是数据管理阶段的输出,然后输入训练过程。这是决定一个模型表现如何的基本因素之一。这一阶段通常包括数据采集和准备。添加用于生成训练数据集的自动化数据管道有助于解决此阶段的大多数挑战。

自动化数据管道

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

图 3: 自动化数据管道

自动化数据管道包括以下步骤:

  1. **数据采集:**从各种来源采集数据,如 S3 桶、公共数据集等。有效的方法之一是使用适配器模式
  2. **数据验证:**验证数据模式和其他类型的验证,以获得更高质量的数据。
  3. **数据准备:**在验证的基础上,为了使数据为训练过程做好准备,该步骤进行归一化、转换、特征提取等。
  4. 数据测试:这一步经常被忽视,但却非常重要。添加偏倚和公平性测试,以确保通过数据在模型中不引入偏倚,这一点至关重要。此外,添加自动化测试以确保获得的数据是安全且符合(基于您需要遵守的法规,如 HIPAA、PCI 或 GDPR)。
  5. **数据版本化:**添加一个步骤来对生成的训练数据集进行版本化,以便您可以轻松地返回到特定版本并跟踪更改。当您主要尝试各种体系结构或训练模型,并希望对数据集的多个版本的多次运行的准确性结果进行比较时,版本化会有所帮助。

参见上一篇文章中定义的挑战&添加自动化数据管道如何帮助解决这些挑战。你可以在这里阅读更多关于挑战的内容。

**挑战:**大数据量
**解决方案:**由于模型训练通常需要大数据集,手工处理耗时&成本高。拥有如上所述的自动化数据管道,使流程可重复,节省了大量时间,并降低了出现数据问题的几率。

**挑战:**高质量数据
**解决方案:**增加自动化数据验证和测试,如偏见和公平,加上安全性和合规性,有助于确保数据的高质量,这有助于产生更好的模型。

**挑战:**数据集跟踪
**解决方案:**跟踪实验和训练有助于比较各种训练运行,看看哪些有效,哪些无效。对数据进行版本控制有助于追踪哪个数据集能提供更好的结果。如上图所示,应该有一个到版本数据集的步骤。有像 dvc 这样的工具可以为数据提供版本控制。

**挑战:**位置
**解决方案:**当数据集驻留在不同的位置时,由于数据量大、传输成本高或合规性原因,传输数据集可能没有意义,因此在更靠近数据驻留的位置运行数据管道、培训甚至预测是有意义的。在这种情况下,拥有一个可以轻松运行的自动化管道会有所帮助。

小心:确保这是值得努力的。如果您可以在不增加复杂性的情况下进行管理,并集中运行,我建议您这样做。

**挑战:**安全性和合规性
**解决方案:**如上图所示,为了确保数据的安全性和合规性,请在您的数据管道中添加自动化的安全性和合规性测试。

实验

这一阶段包括模型开发,在这一阶段,数据科学家将大量时间用于研究各种架构,以了解哪些架构符合他们的需求。他们需要编写训练代码,并使用从数据管理阶段和配置中生成的训练数据集来训练模型。

培训代码

尽管这是一个培训代码,而不是一个生产代码,但是代码的持续集成有助于更快地发现问题。由于研究和实验阶段,许多编写的代码通常质量不高,但添加静态分析和单元测试等内容将有助于更快地发现任何问题,并提供更快的反馈。在训练代码的 CI 的末尾,应该生成一个版本化的工件(docker 映像、zip 文件等)。)然后将用于训练模型。由于这是一个试验阶段,可能会发生很多变化。尽管如此,我还是强烈建议您经常将变更合并到主分支并运行 CI。使用像特性切换或者将工件版本化为 alpha、beta 或者 release 这样的技术有助于识别可以在培训过程中使用的工件。

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

图 4: 培训代码的持续集成

培训过程

见下图(图 5 ),典型的培训流程和各种相关部分。前一阶段生成的训练数据集和最后一步编写的训练代码,以及任何训练环境配置都用作训练过程的输入。数据科学家触发训练过程,这可能会运行几个小时或几天。完成之后,应该添加自动化的准确性评估,以查看模型是否满足预期的标准。在这里添加一个偏差和公平性测试步骤也有助于确保模型在生产中针对实时数据运行时是公平的。如果一切顺利,模型应该被版本化,并存储在工件存储库中,以便在部署到生产时获取。

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

图 5: 培训流程

挑战你可以在这里阅读更多:

**挑战:**持续的研究和实验工作流
**解决方案:**为训练代码添加 CI,并确保生成的训练代码、训练数据集和模型是版本化的,这有助于更快地发现问题并跟踪所做的任何更改。如上所述,尽管在这个阶段通常会发生许多变更,我还是强烈建议频繁地将变更合并到主分支并运行 CI。

**挑战:**跟踪实验
**解决方案:**通过跟踪训练过程的各种组件,如训练数据集、训练代码、模型等。我们可以很容易地复制结果和跟踪实验。

**挑战:**代码质量

**挑战:**培训时间和故障排除
**解决方案:**由于培训通常需要几个小时甚至几天的时间,自动化可以更快地发现问题并进行适当的监控,因此警报&日志聚合有助于更好地对这些问题进行故障排除。

**挑战:**模型精度评估
**解决方案:**增加一个自动评估模型精度的步骤,可以在各次运行之间进行比较,并挑选性能最佳的模型用于生产部署。

**挑战:**再训练
**解决:**通常情况下,当出现数据漂移或逻辑发生变化时,需要对模型进行再训练。为此,上面提到的自动化会有所帮助。

**挑战:**基础架构需求
**解决方案:**训练有时预测有一定的特殊基础架构需求像 GPU &高密度内核。这些通常是昂贵的,并且仅在周期性突发时需要。使用基础架构作为代码来自动配置/取消配置基础架构(尤其是在使用云时)可以降低成本,并减少长期基础架构带来的问题。要了解更多信息,请在这里阅读我的关于基础设施的文章

生产部署

在模型经过训练并达到一定的准确性后,它将被部署到生产中,并开始根据实时数据进行预测。

应用代码

一旦模型定型,应用程序代码(web 服务或应用程序)就会使用它来根据实时数据进行预测。应用程序代码的持续集成通过各种步骤来确保代码的质量,并将模型打包到 CI 结束时生成的工件中。(注意:您也可以在生产中的运行时提取模型,但是您会失去“构建一次,在任何地方运行”的特性。)

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

图 6: 应用代码的持续集成

生产部署期间的挑战您可以在此了解更多:

**挑战:**离线/在线预测
**解决方案:**根据需要提供离线(批量)和在线(实时)预测的支持是必不可少的。当您在构建一个用于生产部署的系统时,您应该考虑这一方面。

**挑战:**模型退化
**解决方案:**在每次部署后增加冒烟测试,并适当监控&因数据漂移或其他原因引起的模型准确性变化,良好的事件管理流程有助于避免准确性水平降低并从中恢复。

将这一切结合在一起

请参见下图,其中包含了我们到目前为止讨论的端到端处理的所有阶段/步骤。

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

图表#7: 将所有内容整合在一起

稍后我会写一篇关于这个的详细文章,但是人对于持续交付的有效性是必不可少的。消除您的 ML 研究人员、ML 工程师、应用程序开发人员、数据工程师和 DevOps/SRE 人员之间的任何隔阂,促进合作会有所帮助。实施本文中提到的建议将使不同团队/个人之间能够协作。

结论

感谢您阅读这篇文章,我希望它对您有用。如果你有任何问题,请在下面的评论中告诉我,或者通过 twitter 联系我。

原载于 我的网站

CICD——神话、陷阱和实践方法

原文:https://towardsdatascience.com/continuous-integration-continuous-delivery-myths-pitfall-and-practical-approach-aaec22edacc5?source=collection_archive---------40-----------------------

DevOps - CI/CD

CICD 不仅仅是工具。设计安全、可扩展、强大且自动化的企业 CI/CD 解决方案。

在本系列文章中,我们将全面讨论 CI/CD、神话、陷阱,然后在下一篇文章中,我们将继续 在 AWS 上实际演示 CI/CD 管道,并分别使用 GitHub、Jenkins 和 code deploy 演示 CI/CD 管道。

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

图片来自 Pixabay罗布森·马查多

在当今快速变化的世界中,技术颠覆已经成为一种常态,并改善了企业的经营方式。组织正试图保持精益,因为这使他们能够快速变化,适应更新的技术,并快速推动创新。这带来了 DevOps,它并不新鲜,但在过去几年中已经有了很多实现。DevOps 是一种软件开发和运营的哲学方法。其核心在于促进协作文化,推动创新速度,并实现自动化软件管理&交付。DevOps 的重要支柱之一是我们将在本文中讨论的持续集成(CI)和持续交付(CD)。

那么问题来了:为什么是 CI/CD?组织越来越以客户为中心,越来越以数据为导向。这导致了更多的独立和并发特性的发布。云服务提供商通过提供无服务器框架和许多其他有利可图的节省成本的功能,为它增添了许多甜头。请注意,只有精心设计的框架才能带来实际的成本效益。显然,用于软件交付的传统工具无法赶上快速发展的“敏捷开发方法”。这导致了对 CI/CD 工具的需求和发展。

持续集成

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

连续累计

持续集成指的是软件发布的构建或集成阶段。它涉及开发人员定期将他们的代码合并到一个触发构建和测试的中央代码库中。持续集成的目标是更快地发现和修复错误,提高软件质量,并减少验证和发布新软件特性的时间。有两个重要组件:

自动化 —构建&测试过程的自动化,包括从故障中恢复。目的是使 CI 流程变得枯燥、简单和快速。这意味着开发人员有更多的时间来构建新功能、测试和合并。

文化和思维转变 —这是 DevOps 的一个重要方面。传统上,团队中的开发人员过去常常长时间地开发代码,并一次性地将变更合并到代码库中。这使得合并变更既困难又耗时。集成失败的可能性更大,并且如果没有修复,错误会存在更长时间。这使得更快地交付软件变得更加困难。另一方面,频繁的集成意味着更少的集成问题,并且 bug 被立即修复。

好处

**提高生产力:**通过自动化构建和测试中的手动步骤,释放开发人员的带宽。更频繁的提交可以确保代码问题得到及时解决。

**更快地修复 bug:**频繁的提交和测试确保问题在成为大问题之前更快地被发现和修复。

**更快更频繁的发布:**持续集成帮助团队向产品频繁发布更多的特性。

**标准化:**包括回归和集成测试在内的标准化测试用例的测试代码确保代码遵循强制性检查。

连续交货

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

连续交货

持续交付是对持续集成的扩展,其中代码变更以构建工件的形式自动准备,以备部署。现成的工件可以部署到测试环境中进行进一步的测试,或者部署到生产环境中。这种整体集成确保标准化代码经过全面测试,并随时准备部署。它还确保了代码的完整性,因为相同的代码部署在不同的阶段。另一个好处是只需一次点击就可以在多台机器上部署相同的代码。

持续交付与持续部署

这两个术语经常被认为是相同的或混淆的。一个理想的场景是开发人员将代码提交到中央存储库,这可以触发构建和测试管道,并在没有失败或问题的情况下将更改自动部署到生产中。然而,我们大多数人都知道这并不完全是部署工作的方式。在部署到生产环境之前,通常需要手动批准或签署。

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

持续集成 vs 持续集成 vs 持续交付

在连续部署中—按一个按钮将代码合并到中央存储库中,如果管道中的所有阶段都成功,代码将自动部署到生产中。另一方面,连续交货需要人工批准。这并不意味着连续交付缺少任何东西,但是实际上在签核之前需要人工批准。

可变与不可变基础设施

在继续之前,我想提出一个属于配置管理的重要话题,但是云平台上的现代 CI/CD 工具包括了这一特性——不可变基础设施。简单讨论一下吧。在同一基础设施上升级应用程序或软件被称为可变方法。不变的方法是指构建新的虚拟机或独立的基础架构,升级到所需的技术体系,如果一切正常,则迁移到新的虚拟机并转储/回收旧的基础架构。这两种方法各有利弊,但是如果您的用例需要不变的基础设施,那么现代 CI/CD 云平台服务也支持这种方法。

好处

**自动化软件发布过程:**持续交付有助于从持续集成管道中部署现成的构建工件,并更快地交付更新&特性。

**提高生产力:**通过将开发人员从手工任务中解放出来,并鼓励有助于减少部署到产品中的错误和 bug 数量的行为,帮助团队提高生产力。

更快地修复错误:连续交付让您的团队可以轻松地对您的代码执行其他类型的测试,因为整个过程已经自动化了。

**更快地交付特性:**持续交付帮助您的团队更快更频繁地向客户交付更新。当正确实现时,您将总是拥有一个已经通过标准化测试过程的部署就绪的构建工件

CI/CD 管道

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

CI/CD 管道

现在,我们已经分别讨论了 CI 和 CD,让我们看一下 CI/CD 渠道。CI/CD 管道是自动化整个软件交付过程的过程。从提交代码到中央存储库,运行测试用例,构建包,以及将代码部署到测试或生产环境。设置 CI/CD 管道没有单一的顺序,但是根据您的组织选择的部署模式,会有最佳实践。

CI/CD 更像是即插即用。它有不同的组件,可以以任何方式使用。有许多开源和付费服务可以单独用于上面列出的每个阶段。例如,下面是管道的一种形式

提交更改->触发构建->构建->通知构建结果->运行测试->通知测试结果->将构建交付到环境->在必要的地方部署

好处

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

CI/CD 渠道优势

陷阱

**不要忘乎所以:**市场上有这么多可用的工具和特性,其中大部分可能并不是特定用例所需要的。所以头脑风暴一下什么最适合你的软件交付,并且只实现相关的组件。如果有一个特别的部分,比如单元测试,它不稳定并且有更多的问题,那么一旦它成熟了,就自动化这个过程,否则你将会花费更多的时间,而不是自动化它。

**不要构建庞大的脚本:**不要构建庞大的测试脚本;相反,构建具有已定义功能的小脚本,并在需要时跨管道重用它。

**运行本地单元测试用例:**在推送到中央存储库之前,在开发人员机器上本地运行特定于业务场景的测试用例。它提供了额外的验证层,并确保较少的集成问题。

**建立以流程而不是工具为中心的管道:**这是一个分裂的时代。软件交付服务正在迅速改进。今天很好的工具明天可能就不够用了(比如几年后)。因此,构建架构时要保持对工具的独立性。尝试在云平台上构建代码库,提供无限的安全存储。最大的好处是,它将数据保存在远离计算设备的中央存储库中,如果您想要过渡到新的服务和软件,这将变得非常容易。

**将正确的组件放置在正确的位置:**根据用例将正确的阶段放置在正确的位置。目标必须是通过关闭高故障管道组件来节省启动时间。例如,您可能想先打包,然后并行运行多个测试用例。

**避免在内部 CI/CD 中构建:**有大量价格合理的开源和付费服务。CI/CD 的主要目标是释放开发人员的带宽,将其用于最重要的事情。内部解决方案需要前期投资和大量维护。管道目标应该是使 CI/CD 无缝。

**使用云原生服务:**AWS 和 Azure 等主要云提供商提供选择原生或流行服务的灵活性,以构建完整的 CI/CD 管道。此外,尽可能不使用服务器,以避免维护成本并关注结果。

结论:

在本文中,我们讨论了 CI/CD、好处、误区和要避免的陷阱。如果你喜欢这篇文章,请告诉我并关注我。点击此处阅读下一篇文章,我们将在 AWS 平台上构建 CI/CD 管道。

免责声明——文中观点仅代表作者个人,不代表作者所属任何组织的观点。

使用 GitHub Actions 对 ML 项目进行持续质量评估。

原文:https://towardsdatascience.com/continuous-quality-evaluation-for-ml-projects-using-github-actions-78f2f078e38f?source=collection_archive---------24-----------------------

如何为 GitHub repo 设置自动指标收集,以及我如何使用它赢得 NLP 竞赛。

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

斯蒂芬·道森在 Unsplash 上拍摄的照片

在这篇文章中,讨论了基于机器学习(ML)的算法的自动质量评估。

最近,我和我的团队在俄罗斯储蓄银行 AIJ 竞赛 2019 中获得了第二名,这是俄罗斯最大的 ML 竞赛之一(100 个团队,45,000 美元奖金)。今年的任务是解决俄语高中毕业考试由许多不同的自然语言处理(NLP)子任务组成,每个子任务都需要一个单独的 ML 模型。这使得我们的团队迫切需要一个自动化的质量评估系统。根据我的生产经验,我建立了这样一个系统,我想在这里分享一下。

这篇文章的所有代码都可以在 Github 资源库中找到:https://github.com/vladimir-chernykh/ml-quality-cicd

介绍

在过去的几年里,ML 领域发展非常迅速。由于这种增长和尽可能快地做每件事的持续需求,许多项目缺乏测试。与此同时,经典软件开发是更成熟的领域,有很多值得学习的地方(软件 1.0 vs 软件 2.0 )。对产品进行适当的测试就是其中之一。从这些链接[ 1234 开始,你可以了解更多关于测试及其不同类型的知识

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

图 1:软件测试分类之一

虽然经典算法和应用程序是确定性的,但大多数基于机器学习的对应程序本质上是随机的。

它引入了另一种类型的测试,这种测试在以前可能并不相关:算法质量测试。他们评估模型解决底层任务的准确性,例如,预测股票价格,区分图像中的猫和狗等。当然,很久以前就有近似和随机算法,但随着 ML 的兴起,它们变得无处不在(许多经典算法在质量上有理论界限)。

当涉及到生产部署时,质量评估至关重要。人们需要知道模型的表现如何,它的适用范围和薄弱环节。只有这样,模型才能被有效地使用,并使产品受益。

几乎每个数据科学家都知道如何在开发环境中评估模型的质量,例如 Jupyter notebook、IDE of choice 等。但是对于生产来说,重要的是不仅要知道当前的质量指标,还要跟踪它们随时间的变化。至少有三种方法可以解决这个问题:

  • 浏览代码存储(GitHub、BitBucket 等)中的提交历史。)
  • 将结果存储在电子表格、维基页面、自述文件等中。
  • 自动化指标收集和存储

这些选项中的每一个都有其使用场景。前两个选项在模型没有太多变化时工作得很好,它们很少发生。而最后一种方法在模型频繁变化时是不可避免的,人们希望有一种稳定而方便的方法来跟踪它。在下文中,最后一种方法称为连续法。

CI/CD

实施持续评估的一种便捷方式是使用持续集成/持续交付 (CI/CD)系统。市场上有许多选择:

所有 CI/CD 系统的最终目标是自动化构建、测试、合并、部署等。整个 CI/CD 管道与代码存储库协同工作,并由特定事件(通常是提交)触发。

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

图 2: CI/CD 主要方案。在源[ 567 ]中查找更多信息

最近 GitHub 推出了自己的 CI/CD 系统,名为 GitHub Actions 。以前,我在几个生产级 CI/CD 系统中使用 Jenkins。AIJ 竞赛是一个试验新工具的绝佳机会,我决定试一试。关于行动,有几点很突出:

  • 与 GitHub 的内在集成。如果已经在使用 GitHub 库进行代码管理,那么操作应该可以无缝地工作。
  • GitHub 提供按需虚拟机来运行整个管道。这意味着不需要管理自己的机器及其与 GitHub 动作的连接。虽然如果你需要一个巨大的虚拟机或者有任何其他特定的要求,这是有可能的(自托管运行程序最近已经在测试版中发布)。
  • 对于私人回购,免费账户有使用限制(2000 分钟/月),但对于公共回购没有限制。更多信息点击这里。我已经在两个小项目中使用了 GitHub Actions,还没有达到极限,但是对于较大的项目来说还是很容易的。在这种情况下,詹金斯/特拉维斯/等。可能是更好的选择。

有关更全面和详细的描述,请查看官方文档

工作

为了说明系统是如何构建的以及它是如何工作的,我将使用玩具示例并构建一个模型来解决波士顿房价任务。在实践中,该系统被应用于 AIJ 竞赛的自然语言处理任务中。

真实任务:AIJ 竞赛

这个连续质量评估系统产生的真实世界的实际任务是关于解决 AIJ 竞赛中的俄语考试。

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

图 4: AIJ 竞赛评估管道

这个竞赛的特点是有许多完全不同的子任务(27 ),我们最终用不同的模型来解决。子任务的例子有:

  • 从几个单词中选出重音不正确的单词
  • 应该插入逗号的位置
  • 在哪些句子中,破折号是根据相同的规则放置的
  • 对于给定的文本,哪些语句成立
  • 在语法错误的类型和它出现的句子之间建立一个映射

有 3 个不同的自动化度量标准(图 4 ),每个子任务由其中一个来判断。最终的排名是基于子任务之间的指标总和。

我们一直在一个接一个地解决这些子任务,并且经常回到我们之前解决的那个来改进它。因此,我们迫切需要一个自动系统来跟踪特定任务的度量变化以及聚合度量。

我没有在这里描述 AIJ 竞赛的精确解,因为它太庞大和复杂了。这会偏离文章的主旨。但是,进入系统构建的背景可能有助于理解系统和所做的决策。

玩具任务:波士顿房价

这是一个回归问题,需要根据不同的因素(如房间数量、社区犯罪率等)来预测住房设施的价格。

这是“默认”经典数据集之一。它甚至直接出现在 scikit-learn 库中

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

图 3:来自波士顿房价数据集的数据示例

总共有 13 个特征(见笔记本中的详细描述)和一个名为“MEDV”的目标,代表“1000 美元的自有住房的中值”。

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

图 5:波士顿房价数据集和 LightGBM 模型的模型开发管道

我会使用三种不同的模型(+基线)来模拟任务的逐步“工作”:

  • 平均模型(基线)

  • 随机预测

  • 线性回归

  • 决策树上的梯度增强( LightGBM )

在现实世界的问题中,它相当于持续改进模型,其变更被推送到存储库。

还应该定义度量标准来评估模型的好坏。在这种情况下,我要使用:

  • 均方根误差( RMSE )
  • 平均绝对误差( MAE )
  • 平均绝对百分比误差( MAPE )

所有的数据预处理和模型训练/评估代码都可以在 GitHub repo 中相应的笔记本中找到。这不是文章的重点:

  1. 构建最佳模型
  2. 解释如何进行特征工程和开发模型

因此,我不在这里详细描述它。这本笔记本被大量评论并且自成一体。

解决方案包装

该解决方案作为dockeredRESTful web 服务发布。使用 Flask 将模型包装到服务器应用程序中(详见 repo 中的 this 文件)。

这里需要注意几件事:

  • 特征的顺序很重要。否则,模型将无法正确预测。
  • 有一个简单返回“OK”的ready端点。可以向其发送请求,以了解是否所有模型都已经加载到 RAM 中。如果端点没有回答,则意味着模型仍在加载或者已经加载失败。
  • predict端点做预测价格的实际工作。输入是一个 JSON,提供了所有必要的特性。
  • 输入可能包含一列数据实例,即不止一个。

人们可以通过进入ml-quality-cicd/src并运行python server.py来使用本地 Python 启动解决方案服务器。尽管这是一种可以接受的方法,但是使用 Docker 有一种更好的平台无关的方法。我创建了一个特殊的 Makefile 来运行所有必要的命令。要运行解决方案服务器,只需键入( Docker 应已安装)

它启动一个 Docker 容器,在主机的端口 8000 上有一个可用的解决方案 web 服务器。有关全面的技术说明,请访问 repo

人们可以以任何合适的方式查询启动的网络服务,例如,使用 Python、JS、Go 等。CURL 命令行实用程序和 Python 示例如下:

在这两种情况下,输出应该是相同的:

{"predictions":[21.841831683168305]}

该解决方案的格式选择由 AIJ 竞赛决定。最近,在洗钱竞赛中有一种转向基于集装箱的解决方案的强劲趋势(ka ggle deep fake DetectionSberbank AIJ 竞赛等)。)

人们可以选择方便用于特定目的的任何其他形式的解决方案交付。例如,从命令行启动带有数据路径和存储结果的位置的脚本。

估价

为了进行评估,我将使用保留技术,并将整个数据集分成训练和验证子集。交叉验证 (CV)也可以用于 Boston House Prices 任务的特殊情况,因为这里使用的模型简单快速。在实际应用中,可能有一个模型被训练了几天。因此,几乎不可能使用 CV。

拆分是在训练笔记本中完成的。这个步骤也显示在图 5 中。

请注意随机状态和其他参数是如何固定的,以保证再现性。之后,将训练和验证数据集保存到 CSV 文件中,以便以后使用,而无需再次启动代码。这些文件位于 repo 中的data 文件夹中。

接下来,有几个可供评估的选项:

  • 笔记本
  • 通过网络服务手动操作
  • 通过网络服务自动完成

下面我们来分解一下每一个是怎么做的。

评价:笔记本

在这种方法中,一个是就地测量模型的质量:在开发它的相同环境中。这种方法有助于通过比较许多模型来建立更好的模型。

下面是所有 3 个模型+基线的比较表(完整代码在培训笔记本):

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

图 6:在 Jupyter 笔记本上完成的验证集的模型比较

算法的就地评估对于即时开发来说是很好的,但是它不允许容易地跟踪变化的历史(在“*简介”*中讨论)。

评估:通过网络服务手动进行

这是通向全自动连续质量测试的中间步骤。

这里我将使用上面“解决方案打包”部分中描述的服务接口。一方面,有一个 web 服务接受 POST 请求的 JSON 主体中的数据实例列表。另一方面,CSV 文件(train 和 validation)包含行中的数据实例。人们需要:

  • 从 web 服务获取 CSV 文件中所有数据的预测
  • 计算预测值和实际值的度量

若要运行本节中的代码,请确保包含该解决方案的服务器正在运行,或者使用运行它

请注意,因为端口固定为 8000,所以一次只能运行一台服务器。要终止所有服务器,可以使用make destroy_all命令或使用docker stop ...手动停止它们。

客户

客户端解决这两个任务中的第一个。它的主要目标是:

  • 将一种格式(CSV)转换为另一种格式(词典列表)
  • 向服务器发送请求
  • 接收并处理回答

客户端的完整代码可在回购的client.py 文件中获得。在这里,我只谈要点。

下面是一个核心逻辑,它能够以适当的格式将文件发送到端点。client.py中的所有其他 120 线路实际上都是接口,以使这些线路正常工作。

当答案返回时,需要处理并保存它们。

注意,一行对应一个输入文件。在此任务中,一个文件可以包含多个数据实例。当一行包含一个实例而不是多个实例的列表时,使用 CSV 更容易。因此,下一步是将答案转换成更方便的格式。

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

图 7:解析和转换后的答案数据帧。这里,客户机同时启动两个文件:训练集和验证集。转换后的数据帧包含对两个文件的预测。所有预测都是相同的,因为部署了 MeanRegressor 模型。

注意,这个阶段完全依赖于数据。对于每个新的任务和数据结构,应该相应地重写这种转换。

度量计算

在接收到答案并以适当的格式存储后,需要将基础真值正确地加入到答案中。它将允许我们计算实例和全局的所有指标。此功能由回购中的metrics.py文件覆盖。

注意,赋值是在没有任何连接的情况下完成的,因为parsed_answers数据帧是按“路径”、“行编号”字段排序的。

一旦基础真值可用,就可以计算所有的实例-wisse 度量,在这种情况下是 MSE、MAE 和 MAPE。

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

图 8:由基本事实标签和基于实例的计算指标丰富的转换答案

这个丰富的表允许分析错误分布和具有最高/最低错误的实例。

最后,让我们通过平均文件间的实例度量来计算全局度量。

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

图 9:文件间的平均全局度量

注意,这里测试的型号是MeanRegressor。可以将验证质量与图 6 中的相应行进行比较,并确保它们是相同的。

评估:通过网络服务自动进行

上一节讨论的所有内容都在 repo 中的client 文件夹中实现。现在的目标是自动化这个过程,并将其包装到 CI/CD 管道中。

自动化是通过 Makefile 完成的。我之前在这里使用它来启动 web 服务,现在让我们仔细看看它的主要细节。这个 Makefile 中有几个目标我想讨论一下:

  • 运行时变量。请注意主机端口是如何随机选择的(根据启动时的 UNIX 时间戳)。这样做是为了允许多台服务器同时运行。

  • buildpush是准备(构建和推送)Docker 映像的目标。图像非常标准,可以在dockers 文件夹中找到。

  • create通过解决方案服务器启动 Docker 容器。设置了资源限制,等于 200 MB RAM 和 1 个 CPU。请注意,相对于总 CPU 内核,CPU 限制是如何处理的。这样做是因为如果有人要求比主机上可用的 CPU 更多的 CPU,Docker 无法启动容器。

  • evaluator启动“评估:通过 web 服务手动操作”一节中讨论的客户端和公制计算机。代码可以在client 文件夹中找到。请注意,启动是在单独的 Docker 容器中进行的(尽管是从同一个 Docker 映像开始的),网络是与主机共享的。它允许从启动的评估 Docker 内部访问解决方案服务器。

  • destroy停止并移除解决方案服务器。请注意在出现错误的情况下,日志是如何转储并打印到输出中的。

用户可以结合上述所有步骤,使用一个命令启动评估:

依次触发createevaluatordestroy。输出应该是在client/reports/<timestamp>_<data folder name>文件夹下可用的评估工件。

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

图 10:评估工件

所有这三个文件都在前面的“评估:通过 web 服务的手动操作”一节中讨论过,现在应该清楚了。

完成全自动系统的最后一步是将描述的评估过程与 CI/CD 系统联系起来。

CI/CD: GitHub 操作

GitHub Actions 平台被用作 CI/CD 引擎。关于 GitHub 动作和 CI/CD 的更多细节,请参阅本文的“ CI/CD ”部分。这里也有官方文件。在接下来的内容中,我将使用三种方法。它们之间的区别在于在哪里以及如何执行 CI/CD 管道步骤:

  • GitHub 机器
  • 使用 SSH 的远程机器
  • 使用自托管运行器的远程机器

GitHub 机器

这是最容易使用的选项。GitHub 为用户提供了虚拟机(VM ),每当特定事件触发管道时,虚拟机就会自动启动。GitHub 管理虚拟机的整个生命周期,用户不应该为此而烦恼。

所有管道定义都应遵循一些规则:

  • YAML 格式
  • 存储在/.github/workflows文件夹内的回购
  • 遵循语法规则

让我们构建一个执行评估过程并打印结果的工作流。该规范位于回购中的evaluate_github.yml 文件中。

主分支上发生的每个push都会触发管道,并对指定文件进行更改。VM 运行ubuntu-18.04并在包列表后安装。也有其他系统可用(见完整列表此处)。

第一步是执行被称为checkout的公开可用的动作(更多细节在这里)。它将代码从父存储库签出到虚拟机。下一步是执行评估。如前所述,这是使用make evaluate完成的。最后,将指标打印到 stdout。

一旦 YAML 配置被推送到回购,管道将在每个合适的事件上被触发。管道运行的结果可以在 repo 的上部选项卡菜单中的“Actions”选项卡下找到。

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

图 11:GitHub 提供的 VM 的工作流运行界面和结果

成功的管道运行如图 11 所示。可以注意到,指标与图 6 和图 9 中的相同。

GitHub 管理的虚拟机是不需要大量资源的工作流的好方法。所有虚拟机只有 2 个 CPU,7GB 内存和 14 GB 磁盘空间(链接)。当一个人运行像波士顿房价预测这样的玩具任务时,这是可以的。但对于 AIJ 竞赛,我们很快就用完了资源,这使得它不可能用于评估。并且对于许多 ML 应用来说,这些资源是不够的。这让我想到了下一小节中描述的解决方案。

使用 SSH 的远程机器

现在假设,有一个人想要用来执行工作流的工作站。如何做到这一点?

人们可以出于任何目的使用 GitHub 启动的 VM,而不仅仅是直接启动管道。除此之外,GitHub 允许用户存储机密并在工作流执行期间使用它们。这个秘密可能是安全地存储在 GitHub 中的任何信息,并且可以传递给 VM。

这两种思想的结合使得使用 SSH 连接到远程工作站并在那里执行所有必要的步骤成为可能。

为此,让我们首先向 GitHub 添加三个秘密:

  • 哪一个是远程机器的 IP 地址
  • EVAL_SSH_USER是远程机器上的用户名
  • EVAL_SSH_KEY是一个私有的 SSH 密钥,对应于所提供的用户和远程机器

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

图 12:GitHub 提供的秘密管理 UI

在初始化所有必要的秘密之后,你可以在 GitHub 动作管道定义中使用它们。所述工作流程的代码可在 repo 的evaluate_remote_ssh.yml 文件中找到。

触发条件和初始checkout步骤与上例相同。下一步是初始化 SSH 私有密钥。注意如何使用特殊的上下文占位符{{ secrets.<SECRET_NAME> }}将秘密传递给环境变量。一旦初始化了 ssh 凭证,就可以在 GitHub VM 上用代码创建一个档案,并使用scp命令将其加载到远程机器上的指定路径。注意,归档文件是以提交散列GITHUB_SHA命名的,默认情况下,提交散列作为环境变量可用(参见此处的以获得默认环境变量的完整列表)。之后,通过运行make evaluate进行评估,并将结果从远程机器复制回 GitHub VM。

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

图 13:使用 SSH 连接到远程机器的工作流运行结果

使用自托管运行器的远程机器

通过 SSH 远程连接解决了 GitHub VM 资源不足的问题。但是与 GitHub VM 执行(31 行 vs 5 行)相比,它也引入了太多完成目标所需的额外命令。为了解决这个问题,同时兼顾两个世界,你可以使用最近发布的自托管运行器的测试版

其背后的核心思想是使用特殊的软件将远程机器暴露给 GitHub 动作用于管道执行(关于安装的更多信息在这里)。

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

图 14:添加自托管运行程序

建立连接后,用户可以通过 YAML 配置文件的指令runs-on在管道中使用新的流道

下面定义了自承载流道的管道。

注意runs-in: self-hosted指令是如何告诉 GitHub 动作在之前添加的定制远程机器上运行的(图 14)。

除了几个步骤之外,YAML 的配置与 GitHub 管理的虚拟机几乎相同。

  • 管道执行前后的环境清理。必须这样做,因为没有人再为我们处理 env 了(以前是由 GitHub 处理的),而且它可能包含以前版本的工件。make clean命令起作用。
  • 将工件上传到存储器。这里我用的是 GitHub 中DASH_SSH secrets 定义的自定义(可能是单独的)机器。我将结果存储在一个单独的文件夹中,其中每个文件都以其对应的提交散列命名。用户可以使用任何其他存储(AWS S3、GCP 存储等)。)和文件格式。

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

图 15:通过自托管运行器的 CI/CD 管道执行结果

结果

本文中所做的所有评估都是一致的,并且给出了相同的MeanRegressor基线模型的相同指标。

现在,让我们依次将模型更改为RandomRegressorLinearRegressionLGBMRegressor,看看指标是如何变化的。我已经使用 Dash Python 库实现了这个特殊的仪表板。人们可以在回购协议的这里获得代码细节。仪表板在 GitHub 中的DASH_SHH secrets 指定的特殊远程机器上手动启动。

仪表板跟踪的文件夹对应于 CI/CD 自承载管道存储其结果的文件夹。仪表板本身在端口 7050 上可用。

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

图 16:用不同的模型提交。他们在模型上模拟真实的渐进工作。

图 16 所示的每个提交都会触发所有 3 个描述的 CI/CD 管道。所有的执行都很顺利,这由提交附近的绿色标记表示。自托管运行器还将结果推送到仪表板,如图 17 和 18 所示。

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

图 17:带有 MAE 度量结果表的仪表板。绿色的行显示最后一个模型的质量比基线好(否则该行被涂成红色)。

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

图 18:结果表中一行的图表。注意模型名称是如何重复图 16 中的提交散列的。

仪表板允许用户方便地跟踪历史进度,并比较不同子集/子任务之间的度量。

在现实世界的 AIJ 竞赛中,该仪表板如下所示:

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

图 19:AIJ 竞赛评估表。每行对应于考试的一个子任务。

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

图 20:一个任务的模型进度。

结论

在这篇文章中,我描述了我对构建持续质量评估系统的观点,并提供了所有必要的代码和步骤来重现它。

这篇文章中构建的系统对于中小型项目或 ML 竞赛已经足够好了。它还可以在许多方面得到改进,例如:

  • 更可靠的日志和指标存储
  • 更好的可视化系统
  • 日志分析
  • 等等。

通过将配置文件重写为适当的特定于工具的格式,所描述的连续质量评估工作流可以很容易地移植到任何其他 CI/CD 引擎。

GitHub Actions 有利有弊。最大的优势是与 GitHub 的紧密集成,以及按需 GitHub 管理的虚拟机的可用性。这对于使用 GitHub 的人来说很方便,如果不使用的话则完全无法接受。主要的缺点是私有存储库的构建数量有限(2000 分钟)。对于大型项目,这导致需要支付保费账户或使用另一种 CI/CD 工具。如果一个人面临分钟溢出的问题,我可能会选择后一种方法。

在我看来,GitHub Actions 是中小型项目的一个很好的选择,这些项目需要一个易于安装的 CI/CD 引擎,并且不太关心它的基础设施。对于更大的项目和更细粒度的控制,可以选择其他 CI/CD 平台。

附注:我要感谢我在 AIJ 大赛中的队友(德国人诺维科夫奥列格·阿伦金亚历山大·安尼西莫夫)为解决方案做出的贡献。

简而言之,用于无监督领域适应(CUDA)的对比识别器

原文:https://towardsdatascience.com/contradistinguisher-for-unsupervised-domain-adaptation-cuda-in-a-nutshell-68182572fbcd?source=collection_archive---------57-----------------------

一个处理各种域调整方法中涉及的域对齐的某些缺点的模型,同时给出了最新的结果。

正如我们所知,在深度学习世界中,我们可能没有足够的监督数据来训练我们的模型。所以领域适应是一个非常有用的话题。我最近读了一篇ICDM 19 年的论文“无监督域适配的对比识别器”,它提出了一种无监督域适配的直接方法,不需要域对齐。

在这篇博客中,我将尝试简单地给出我对这篇论文的理解。该论文的作者还发布了该论文的一个实现

领域适应

正如我们所知,在深度学习的世界中,我们可能没有足够的监督数据来训练我们的模型。但是可能存在另一组非常相似的数据(具有不同的分布),对于这些数据,我们有足够数量的标记数据。在这种情况下,如果我们能够以某种方式将基于这些数据训练的模型用于我们的任务,那就太好了。为了了解我们正在讨论的内容,让我们讨论一个小例子:

假设我们手里有一个情感分析任务,为了训练的目的,给我们一些带标签的书评。让我们看看其中的一篇书评。

回顾-1: “这本书对其涵盖的主题有深入的概念构建材料。完全值得你花时间。”

现在假设我们要做情感分析任务,评论是关于家具的。让我们看看其中一个家具评论。

评论-2: “这件家具的边缘处理非常好,非常舒适。”

我们在这里可以推断的是,没有家具评论会类似于评论-1,即,由于基础分布的差异,在书评上训练的情感分析引擎将与家具评论的不确定性一起工作。

在我们对视觉数据的分类任务中也可以看到另一个类似类型的例子,其中我们有同一物体的两个不同图像,但它们都来自不同的数据集(如图 1 所示)。

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

图 1:左边是一个电子商务网站上展示的一辆自行车的图像,右边是一个手机摄像头拍摄的自行车的图像。

回到我们之前的例子,假设我们没有标记家具评论,在这种情况下,如果我们可以以某种方式使用我们标记的书评数据集,这将是有用的。处理这些类型的域转移的子学科被称为**域适配。**在更进一步之前,我们需要了解域的含义。

任意一组数据的域 (D)由其三个属性来表述:其输入特征空间(X)、标签空间(Y)及其底层联合概率分布。

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

图 2:一个域的表示

假设:

域自适应由两个不同的域组成,即源域和目标域,具有共同的输入和输出空间,具有*域偏移。*域偏移是具有公共输入和输出特征空间的两个域的联合概率分布的差异。

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

图 3:域转移

动机

领域适应方法的一般趋势是首先实现源和目标领域对准的中间目标,但是它有一些缺点。大的畴变使畴变得更难对齐。另一个缺点是使用多分类器,这增加了模型的复杂性。域对齐有时会导致特定于域的信息丢失,因为在此过程中域正在被转换。

本文提出了一种方法,该方法跳过这个无关的中间比对步骤,并分别在源数据和目标数据上以监督和非监督的方式联合学习单个分类器。作者从 Vapnik 那里得到了一口气解决问题的灵感。

Vapnik 的想法:任何想要的问题都应该用最直接的方式解决,而不是解决一个更一般的中间任务。

本文具体讨论了无监督版本的域自适应,其中训练数据包含已标记的源域实例和未标记的目标域实例。

**目的:**通过转移已标记源领域的知识,学习未标记目标领域的分类器。

对比识别器(CUDA)

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

图 4:两种域分布的公共决策边界。

该模型充当两种域分布的分类器。这种方法背后的基本思想是调整在源标记数据上学习的决策边界,使其遵循目标域先验。

我们手里有两个发行版。可以使用监督学习来学习源分布。但是我们需要目标分布来建立目标领域分类器。为了调整在源分布上学习到的决策边界,我们试图提出目标联合分布,作为源分布的函数,加强目标域先验。

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

图 5:包含目标无监督学习前后的决策边界。

CUDA 模型包含一个编码器和一个同时使用三个数据集训练的分类器。

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

图 9:每个时期训练 CUDA 模型。

寻找源联合分布

根据领域适应的定义,为了传递知识,使用源标记数据来训练模型。交叉熵损失用于学习用于最大化标签相对于它们各自的源实例的条件对数似然的参数。设源分布为 P(θ)。

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

图 6:关注从标记的源数据中学习。

设计目标联合分布

由于源域和目标域之间的唯一区别是其固有的联合概率分布,并且使用监督学习,我们获得了源域的联合概率之后的参数,我们的任务现在转移到获得目标域的联合分布上。

我们知道,任何域的联合分布都满足给定的两个条件,即 x[t]上的边际应给 p(y[t])和 y[t]上的边际应给 p(x[t])。建议的目标分配也必须遵循这两个条件。由于对目标数据进行的学习只能在无人监督的情况下进行,作者巧妙地提出了目标联合分布,它:

  • 是 P(θ)以及目标域先验的函数。
  • 遵循上述两个条件。
  • 可以用来寻找最具对比性的特征。

为了获得最多的对比特征,所提出的联合分布被最大化。当最大化时,建议的分布实施两个属性。它试图增加一个实例被标记为一个类的概率,同时减少所有其他实例被标记为同一类的概率。这两个强制使 contradistinguisher 提取出唯一指定每个实例的特性集。

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

图 7:聚焦于根据未标记的目标数据进行调整。

正规化

在训练期间使用伪标签时可能出现的一个问题是过拟合伪标签。为了解决这个问题,作者还包括了对抗性正则化,其目标是当模型引入一组不属于任何一类的假阴性样本时,包含不确定性。我们首先构建一组假阴性样本,并同时将它们标记到每个类别。在训练期间,模型将学习将不确定性包括到预测中,这在我们的情况下是一个有效的场景。

这种方法类似于熵正则化,其中不是最小化真实目标样本的熵,而是最小化多类、多标签分类任务的二进制交叉熵损失。用于生成假样本的方法取决于所使用的域。该方法提出了两种类型的伪样本生成:

  1. 对于语言类领域,使用高斯或均匀分布随机采样假样本。
  2. 对于类似图像的域,使用生成器网络对伪样本进行采样,该生成器网络也在整体模型训练期间被训练。

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

图 8:专注于包含对抗性的正规化。

作者还提出了对多源域适应的进一步扩展,其中我们可以有多个源域和一个目标域。此处唯一需要的更改是源监督损失。来源监督损失现在将是所有单个来源监督损失的总和。

结果

作者对各种类型的数据做了详细的实验。本文给出了低分辨率和高分辨率可视化数据集上的结果,提出的模型给出了所有这些数据集上的最新结果。他们还尝试了语言数据集,在这里,模型也给出了最先进的结果。要详细了解所使用的数据集和与之对应的结果,可以看一下论文

结论

本文提出的联合学习对比鉴别器的方法在不牺牲效率的情况下解决了域对齐的缺点。该方法给出了各种测试场景的最新结果。它有可能成为领域适配领域的里程碑。

对比对比损失函数

原文:https://towardsdatascience.com/contrasting-contrastive-loss-functions-3c13ca5f055e?source=collection_archive---------12-----------------------

用于对比学习的四种对比损失函数综合指南

在之前的一篇文章中,我写了关于监督分类中的对比学习,并在 MNIST 数据集上做了一些实验,发现科斯拉等人提出的两阶段方法。2020 年论文通过学习具有对比损失的有意义嵌入,确实显示了监督分类任务的显著改进。后来我发现我的实验实际上使用了与科斯拉等人不同的对比损失函数。已提议。尽管共享相同的直觉,即关于它们的标签,显式地对比彼此的例子,但是不同的对比损失函数可以有它们自己的细微差别。在这篇文章中,我将回顾一系列对比损失函数,并比较它们在监督分类任务中的性能。

初步的

对比损失函数是为度量学习发明的,它旨在学习测量一对对象之间的相似性或距离的相似性函数。在分类的上下文中,期望的度量将使得具有相同标签的一对示例比具有不同标签的一对示例更加相似。深度度量学习涉及深度神经网络,将数据点嵌入到具有非线性的低维空间,然后使用对比损失函数来优化神经网络中的参数。最近的研究项目已经将深度度量学习应用于自我监督学习、监督学习甚至强化学习,例如对比训练的结构化世界模型(C-SWMs)

为了在深度度量学习的背景下回顾不同的对比损失函数,我使用以下形式化。让𝐱作为输入特征向量,𝑦作为它的标签。设𝑓(⋅)是将输入空间映射到嵌入空间的编码器网络,设𝐳=𝑓(𝐱)是嵌入向量。

对比损失函数的类型

这里我按时间顺序回顾四个对比损失函数。我稍微修改了几个函数的名称,以突出它们与众不同的特点。

1.最大利润对比损失(Hadsell 等人,2006 年)

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

最大间隔对比损失函数以一对嵌入向量 z_iz_j 作为输入。如果它们具有相同的标签( y_i=y_j ),那么它们之间的欧几里德距离基本上相等,否则等于铰链损耗。它有一个余量参数 m > 0 来对具有不同标签的一对样本之间的距离施加一个下限。

2.三重态损失(Weinberger 等人,2006 年)

三元组丢失对其标签遵循𝑦_𝑖=𝑦_𝑗和𝑦_𝑖≠𝑦_𝑘.的三元组向量进行操作也就是说,三个矢量中的两个(𝐳_𝐢和𝐳_𝐣)共享相同的标签,而第三个矢量𝐳_𝐤具有不同的标签。在三元组学习文献中,它们分别被称为锚( z_i )、正( z_j )和负( z_k )。三重态损耗定义为:

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

其中,𝑚也是一个边缘参数,要求锚正和锚负之间的距离增量大于𝑚.这个损失函数的直觉是将负样本推到邻域之外一个余量,同时将正样本保持在邻域内。这是一个很好的图形演示,显示了原始论文中三重态损失的影响:

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

使用三重态损失的训练前后(来自 Weinberger 等人,2005)

三重开采

根据三联体丢失的定义,在任何训练之前,三联体可能有以下三种情况:

  • 简单:损失为 0 的三元组,因为负数已经比正数离锚点多了一个裕量
  • :三连音,其中负数比正数更接近锚点
  • 半硬:三连音,负片位于页边

三重损失已经被用于在面网中学习面的嵌入(Schroff 等人)。2015)论文。施罗夫等人。认为三元组挖掘对于模型性能和收敛性至关重要。他们还发现,最难的三元组在训练早期导致局部最小值,特别是导致模型崩溃,而半难的三元组产生更稳定的结果和更快的收敛。

3.多类 N 对损耗(Sohn 2016)

多类 N 对损失是三重损失的推广,允许在多个负样本之间进行联合比较。当应用于一对阳性样品时,𝐳_𝐢和𝐳_𝐣与 2𝑁样品具有相同的标签(𝑦_𝑖=𝑦_𝑗),计算公式如下:

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

,其中 z_i z_j 为内积,当两个向量都有单位范数时等价于余弦相似。

如下图所示,N 对丢失同时将 2N-1 负样本推开**,而不是一次一个:**

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

三重态损失(左)及其延伸(N+1)-三重态损失(右)(来自 Sohn 2016)

通过一些代数运算,多类 N 对损耗可以写成如下:

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

这种形式的多类 N 对损失帮助我们引入下一个损失函数。

4.监督 NT-Xent 损失(Khosla 等人,2020 年)

我们先来看一下 NT-Xent loss 的自监督版本。NT-Xent 是由等人杜撰的。2020,是“归一化温度标度交叉熵损失”的简称。它是对多类 n 对损耗的修改,增加了温度参数(𝜏)来衡量余弦相似性:

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

自我监督 NT-Xent 损失

发现一个合适的温度参数可以帮助模型从硬底片中学习。此外,他们还表明,最佳温度在不同的批次大小和训练时期数上有所不同。

科斯拉等人。用于监督学习的后来扩展的 NT-Xent 损失:

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

监督 NT-Xent 损失

实验结果

接下来,我评估这些对比损失函数是否可以帮助编码器网络学习数据的有意义的表示,以帮助分类任务。遵循与我前一篇文章中完全相同的实验设置,使用小批量(32)和低学习率(0.001),我发现除了具有硬负挖掘的三重损失之外,所有这些对比损失函数都优于没有阶段 1 预训练的 MLP 基线:

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

在 MNIST 和时尚 MNIST 数据集的保留测试集上的性能(准确性)(来自具有硬负挖掘的三元组的结果未显示)。

这些结果证实了在网络的编码器部分的预训练中使用对比损失函数对于后续分类的益处。它还强调了三重态开采对三重态损失的重要性。具体来说,半硬开采在这些实验中效果最好,这与 FaceNet 的论文一致。

Chen 等人 (SimCLR)和 Khosla 等人都使用非常大的批量和更高的学习率来获得更好的 NT-Xent 损失性能。接下来,我用不同的批量 32、256 和 2048 进行了实验,学习率分别为 0.001、0.01 和 0.2。

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

结果表明,对于所有损失函数,性能随着批量的增加而降低。虽然半硬负挖掘的三重丢失在中小批量上表现非常好,但它非常占用内存,我的 16G RAM 不可能处理 2048 的批量。与同类产品相比,受监督的 NT-Xent 损失确实在较大批量上表现得相对更好。如果我要优化温度参数,受监督的 NT-Xent 可能还有改进的空间。我用的温度是 0.5。

接下来,我检查了使用对比损失函数学习的嵌入的 PCA 投影,以查看它们是否在预训练阶段学习了任何信息表示。

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

****MNIST 数据集上不同对比损失函数和批量大小的编码网络学习嵌入的 PCA 投影。从左到右:通过 1)最大边际损失学习的预测;2)半硬开采的三重损失;3)多类 N 对损失;4)监督 NT-Xent 丢失。从上到下:批量大小为 32,256,2048。

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

****显示 MNIST 数据集模型学习的 PCA 投影密度的联合图。从左至右:通过 1)最大边际损失学习的预测;2)半硬开采的三重损失;3)多类 N 对损失;4)监督 NT-Xent 丢失。从上到下:批量大小为 32,256,2048。

从彩色 PCA 投影和它们的密度来判断,我们可以看到最大余量和监督 NT-Xent 为每个类学习更紧密的聚类,而来自半硬挖掘的三重丢失的聚类最大程度地扩大,但仍然是独特的。随着批量大小的增加,在多类 N 对损失和最大边际损失中,表示质量退化,但在监督 NT-Xent 损失中不那么严重,这表明这种损失对于更大的批量大小确实更稳健。

下面是在更困难的时尚 MNIST 数据集上的学习表示的 PCA 投影。总的来说,它显示了与 MNIST 相似的观察结果。

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

****不同对比损失函数和批量大小的编码网络学习到的嵌入在时尚 MNIST 数据集上的 PCA 投影。从左至右:通过 1)最大边际损失学习的预测;2)半硬开采的三重损失;3)多类 N 对损失;4)监督 NT-Xent 丢失。从上到下:批量大小为 32,256,2048。

总结

对比损失函数对于通过学习有用的表示来改进监督分类任务非常有帮助。最大利润和监督 NT-Xent 损失在实验数据集(MNIST 和时尚 MNIST)中表现最佳。此外,NT-Xent 损失对于大批量是稳健的。

值得注意的是,这里回顾的所有对比损失函数都具有超参数,例如输入向量的裕度、温度、相似性/距离度量。这些超参数可能会严重影响其他研究的结果,因此应该针对不同的数据集进行优化。

这些实验所用的代码可以在这里找到:https://github.com/wangz10/contrastive_loss

参考

对比 VIX 和 VIX 期货的价格动态

原文:https://towardsdatascience.com/contrasting-the-price-dynamics-of-the-vix-and-vix-futures-cbb42e889f4f?source=collection_archive---------28-----------------------

期货市场

交易 VIX 期货之前你需要知道什么

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

蒂姆·斯蒂夫在 Unsplash 上的照片

一个最广泛认可的预期市场波动指标是 CBOE 波动指数(VIX)。直接投资 VIX 的优势是显而易见的,但实际上 VIX 是不可直接交易的。

下行保护的 VIX 风险敞口

为了说明持有 VIX 债券的好处,可以考虑一下 2011 年标准普尔下调美国信用评级的事件。2011 年 4 月 18 日,S&P 对美国信用评级持负面展望的消息传出。如图 1(a)所示,在 2011 年 8 月 5 日官方降级后的几个月里,仅持有 SPDR 标准普尔 500 交易所交易基金(SPY)的投资组合将继续下跌约 10%。

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

(a)2011 年 4 月 1 日至 2011 年 9 月 30 日,以及(b)2014 年 1 月 1 日至 2014 年 12 月 31 日期间,100%投资于 SPY,90%投资于 SPY,10%投资于 VIX 的投资组合的历史投资组合价值。

(a)2011 年 4 月 1 日至 2011 年 9 月 30 日,以及(b)2014 年 1 月 1 日至 2014 年 12 月 31 日期间,100%投资于 SPY,90%投资于 SPY,10%投资于 VIX 的投资组合的历史投资组合价值。

相比之下,一个混合了间谍(90%)和 VIX (10%)的假设投资组合在降级期间将保持稳定,最终获得正回报。图 1(b)显示了 2014 年同一对投资组合。

两者都获得了大致相同的 15%的回报,尽管《间谍》一书明显比《间谍》和 VIX 的投资组合更不稳定。VIX 股市上涨应对了大规模的下跌(例如 2014 年 10 月 15 日),对投资组合的价值产生了稳定效应。

这个例子激发了对直接跟踪 VIX 和其他指数的交易策略的研究,或者实现任何关于指数或市场因素的预先指定的暴露。

获取 Vol 曝光

相反,波动性敞口是通过使用 VIX 期货或期权以及一些交易所交易基金/票据(ETF/Ns)来实现的。众所周知,VIX ETF/etn 无法一对一地跟踪 VIX,并持续带来负回报。

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

VXX(蓝色)明显偏离 VIX(红色),在过去几年中损失了 93%以上。

但是直接持有 VIX 期货怎么样呢?

在任何时间点,市场上都有少量合约交易,期限从 1 个月到 10 个月不等。

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

这里先来看看单一 VIX 期货合约与 VIX 期货合约的不同回报动态:

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

VIX(红色)和 2020 年 10 月到期的 VIX 期货(蓝色)的累积收益时间序列。

在我们的论文中,我们讨论了 VIX 期货和标的指数的价格动态,并构建了 VIX 期货的静态和动态投资组合以跟踪该指数。除了推导和实施最佳跟踪策略,我们还检查跟踪投资组合的有效性。

数据

我们从分析 VIX 期货相对于现货 VIX 的价格动态开始。VIX 期货的历史价格数据来自 Quandl。我们已经将 Quandl 的数据与直接来自 CBOE 的数据进行了对比。对于现货 VIX 数据以及相关的 etn,我们使用雅虎!金融。

编译后,我们的数据集由从 2004 年 3 月 26 日(VIX 期货开始交易的第一天)到 2017 年 1 月 27 日的全部收盘价历史组成。但是,我们选择只分析从 2011 年 1 月 3 日(2011 年的第一个交易日)到 2016 年 12 月 30 日,即从 2011 年到 2016 年的 6 年时间。

这个数据量可能足以避免过度拟合,并且足够新以理解 VIX、期货和 VXX 之间的动态。当然,人们可以用更近的数据来遵循我们的程序。

整个样本期包含 1510 个交易日的数据。此外,在样本集的任何一天,都有 7 到 9 个期货合约可用。特别是,有 15 天只有 7 个期货合约可用,278 天只有 8 个期货合约可用,以及 1217 天有整整 9 个月的合约可用。

在这段时间内,期货合约总是连续几个月(从 1 个月合约开始)。换句话说,当有 N 个期货合约可供交易时,它们总是由 N 个前月组成。

例如,如果当前交易日期是 1 月初的某个时间(在 1 月期货到期日之前),并且有 7 个期货合同可用于交易,则期货合同的到期日将是连续的 1 月到 7 月。数据集的这些特征符合 CBOE 协议。他们表示,他们目前将列出最多 9 个月的近期交易。然而,在我们的分析中,我们排除了第八个月和第九个月的合约,因为人们并不总是可以交易第八个月或第九个月的合约。

这允许我们使用全部 1510 天的数据,并且避免了消除只有 7 或 8 个期货交易的 15 + 278 = 293 天的需要。

针对 VIX 的倒退

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

表 1:1 个月至 7 个月期货的一天收益对现货 VIX 的一天收益进行回归的回归系数和拟合优度的总结。

我们观察到所有期货的高 R 值,表明它们与现货高度相关。期限较短的期货有较高的 R 值。这可以解释为

(I)期货价格趋向于接近到期日的现货价格,

㈡长期合同的流动性不如短期合同。

斜率系数都具有统计显著性,并且小于 1,这是直观的,因为期货回报往往比现货回报波动性小。负截距具有统计学意义,表明即使现货价格不动,期货价格也会下跌。

原因在于 VIX 期货的期限结构,它通常在到期日增加。即使现货价格不动,期货价格也倾向于下降,以匹配到期日的现货价格,从而形成负截距。

期限结构

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

(a) 2016 年和(b) 2009 年 1 月至 6 月的期限结构。图例显示了构建期限结构的日期。

如上图所示,VIX 市场的典型案例是一条上升的凹形期货曲线(左图)。然而,2016 年 1 月,VIX 价格飙升,对未来波动性的预期也是如此。像这样的峰值会导致 VIX 期货的期限结构反转,产生一条递减的凸形期货曲线。在 2009 年初(右图),期货价格处于非常高的水平,期限结构显示出不同的形状属性。

保持时间的影响

当我们对长期持有的期货回报和现货回报进行回归时,新的模式出现了。当我们计算回报时,我们使用不同长度的不相交区间,这意味着对于更长的时间范围,我们有更少的数据点。

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

我们绘制了 1 个月期货回报相对于 1 天回报(左)和 10 天回报(右)的 VIX 回报的回归曲线,绘制在相同的 x -y 轴刻度上。红色的 x 是成双成对的回报,而黑色的线是最好的 t 线。人们注意到,10 天的回报要大得多,因此比 1 天的回报更不稳定。

然而,对于两个持有期,期货回报比相应的现货回报波动性小。准确地说,我们发现现货的 1 天收益率在-26.96%和 50%之间变化,而 10 天收益率在-39.76%和 148.06%之间变化(即持有期越长,波动性越大)。

另一方面,对于 1 个月的期货,1 天的收益率在-20.81%和 35.83%之间变化,而 10 天的收益率在-36.91%和 88.89%之间变化(即期货收益率的波动性小于相应的现货收益率)。

在上图中,10 天回报率的斜率略高于 1 天回报率的斜率。此外,对于 1 天的回报,散点图更紧密地绑定到最佳拟合线,表明比 10 天的回报观察到的拟合更好。然而,这种模式并不普遍适用。随着保持时间的延长,在 R 或斜率中没有可辨别的模式。

这可以通过观察 R 或斜率与保持时间的关系图来证明。我们在这里省略了这样的图,因为没有增加或减少预测能力(以 R 衡量)或杠杆的清晰模式,这是复制图中任何到期合约的即期回报所必需的。(杠杆可以用斜率的倒数来衡量。)

另一方面,如果我们 x 持有期,增加合同的到期时间,我们看到预测能力下降,斜率下降。(因此,复制现货需要增加杠杆。)我们在表 2 中针对多个不同的持有期(1、5、10 和 15 天)证明了这一点。

在上半部分,我们给出了相对于现货回报的期货回报回归的斜率系数,在下半部分,我们显示了 R 值。通过查看任一半中的行,可以注意到报告的统计数据减少了。这再次证实了我们之前的观察,即短期期货比长期期货更接近现货。

事实上,在 15 天的时间里,结果表明,跟踪 1 个月期货需要大约 1.6 倍的杠杆,而 7 个月期货需要 7.2 倍的杠杆。这些隐含的杠杆值是通过计算斜率的倒数(分别为 0.622 和 0.139)获得的。7 个月期货的杠杆相当大,由于交易成本或交易限制,在市场上可能不可行。

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

表 2:对期货收益和 VIX 回归的斜率和 R 的总结

接下来,我们绘制了许多不同持有期(从 1 天到 30 天)的 1 个月期货(黑色)、3 个月期货(红色)和 6 个月期货(蓝色)的回归截距。很明显,随着持有期的延长,截距变得越来越负。

此处报告的所有截距(以及之前的斜率)在 1%显著性水平上具有统计显著性。因此,存在统计上的显著差异,并且随着保持期的延长而继续恶化。

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

这证实了我们已经讨论过的一个属性:相对于现货回报,VIX 期货往往表现不佳并亏损。更负的截距表明这种表现不佳在更长的时间内会恶化。

参考

T.Leung 和 B. Ward,用 VIX 期货跟踪 VIX:投资组合构建和业绩[pdf链接,载于应用投资研究手册, J. Guerard 和 W. Ziemba 合编。,世界科学出版公司,印刷中,2020 年

更多信息,请关注/联系 Linkedin:https://www.linkedin.com/in/timstleung/

对比损失解释

原文:https://towardsdatascience.com/contrastive-loss-explaned-159f2d4a87ec?source=collection_archive---------2-----------------------

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

对比损失最近在一些论文中使用,显示了无监督学习的最新成果。 MoCoPIRLSimCLR 都遵循非常相似的使用具有对比损耗的连体网络的模式。当阅读这些论文时,我发现总的想法非常简单,但是从数学到实现的翻译没有得到很好的解释。正如机器学习论文中经常出现的情况一样,一旦你掌握了主要思想,数学就不难了。我将尝试清楚地解释对比损失是如何工作的,并使用 Python 和 Numpy 提供一个完整的实现。

暹罗网络

在深入了解细节之前,先谈谈暹罗网络(也称为孪生网络,但这不是一个广泛使用的术语)会有所帮助。训练连体网络时,会对 2 个或更多输入进行编码,并比较输出特征。这种比较可以在中以多种方式进行。一些比较是三重损失、具有交叉熵损失的伪标记和对比损失。

连体网络通常显示为共享权重的两个不同的编码网络,但实际上,在进行反向传播之前,同一个网络只使用了两次。

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

例子

让我们来看一个例子,在这个例子中,我们想从 MNIST 数中提取特征。MNIST 数的每个图像应该被编码成与来自相同类别的图像的向量接近的向量。相反,不同的数字应该编码成彼此远离的向量。

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

嵌入向量空间的正(上)样本和负样本

由于我们有 MNIST 输入的分类标签,因此可以使用常规网络和分类交叉熵损失。问题是当我们没有很好标记的数据时,这是通常的情况。世界上没有标签的数据比有标签的数据多得多。这就是对比损失的来源。

对比损失将网络的输出作为一个正例,并计算其与同类样本的距离,并将其与到负例的距离进行对比。换句话说,如果正样本被编码成相似(更接近)的表示,而负样本被编码成不同(更远)的表示,则损失较低。

这是通过取向量的余弦距离并将所得距离视为来自典型分类网络的预测概率来实现的。大意是,你可以把正例的距离和反例的距离当作输出概率,并使用交叉熵损失。

执行监督分类时,网络输出通常通过 softmax 函数运行,然后是负对数似然损失。

让我们把这个说得更具体些。这个例子将有两个相似的向量和一个不相似的向量的数组。p1 和 p2 是正向量,p2 是 P1 的稍微修改版本。Neg 是相异向量的数组。

示例设置

import numpy as npp1 = np.array([-0.83483301, -0.16904167, 0.52390721])
p2 = np.array([-0.83455951, -0.16862266, 0.52447767])
neg = np.array([
 [ 0.70374682, -0.18682394, -0.68544673],
 [ 0.15465702,  0.32303224,  0.93366556],
 [ 0.53043332, -0.83523217, -0.14500935],
 [ 0.68285685, -0.73054075,  0.00409143],
 [ 0.76652431,  0.61500886,  0.18494479]])

请注意,我在这里使用了预归一化向量(又名单位向量)。

计算距离

为了测量两个向量有多相似,我们需要一种测量距离的方法。在二维或三维中,欧几里德距离(“普通”或直线距离)是测量两点之间距离的最佳选择。然而,在一个大维度空间中,通过欧几里德度量,所有点往往相距很远。在更高维度中,向量之间的角度是更有效的度量。余弦距离测量向量之间角度的余弦值。相同向量的余弦为 1,而正交向量和相反向量分别为 0 和-1。更多的相似向量将导致更大的数量。计算余弦距离是通过取向量的点积来完成的。当不使用单位向量时,你要么将向量归一化,要么将乘积除以归一化向量。

# P1 and p2 are nearly identically, thus close to 1.0
pos_dot = p1.dot(p2)
pos_dot -> 0.999999716600668# Most of the negatives are pretty far away, so small or negative
num_neg = len(neg)
neg_dot = np.zeros(num_neg)
for i in range(num_neg):
    neg_dot[i] = p1.dot(neg[i])neg_dot -> [-0.91504053,  0.30543542, -0.37760565, -0.44443608, -0.64698801]

Softmax

softmax 函数获取一个实数向量,并强制它们在 0 到 1 的范围内,所有数字之和等于 1。softmax 的另一个好特性是其中一个值通常比其他值大得多。计算类别交叉熵的损失时,第一步是取值的 softmax,然后是标记类别的负对数。

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

Softmax,数学版

让我们把 pos_dot 的 softmax 加上 neg_dot 向量。

# make a vector from the positive and negative vectors comparisons
v = np.concatenate(([pos_dot], neg_dot))# take e to the power of each value in the vector
exp = np.exp(v)# divide each value by the sum of the exponentiated values
softmax_out = exp/np.sum(exp)softmax_out -> [0.4296791, 0.0633071, 0.2145353, 0.1083572, 0.1013523, 0.0827687]

我们的正例(0.4296791)现在比随机的大得多,而且都大于 0 小于 1。

对比损失

最后,我们得到了本文的重点,对比损失。

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

对比损失函数

对比损失看起来很像 softmax 函数。这是因为它增加了向量相似性和温度归一化因子。相似度函数就是我们之前讲过的余弦距离。另一个区别是分母中的值是从正样本到负样本的余弦距离。与 CrossEntropyLoss 差别不大。这里的直觉是,我们希望我们的相似向量尽可能接近 1,因为-log(1) = 0,这是最优损失。我们希望反例接近 0,因为任何非零值都会降低相似向量的值。

# Contrastive loss of the example values
# temp parameter
t = 0.07# concatenated vector divided by the temp parameter
logits = np.concatenate(([pos_dot], neg_dot))/t#e^x of the values
exp = np.exp(logits)# we only need to take the log of the positive value over the sum of exp. 
loss = - np.log(exp[0]/np.sum(exp))
loss -> 4.9068650660314756e-05

这就是全部了。对比损失可以被实现为交叉熵损失的修改版本。对比损失,如三重损失和磁损失,用于映射对输入项的相似性建模的向量。这些映射可以支持许多任务,如无监督学习、一次性学习和其他距离度量学习任务。我希望这篇文章能帮助你更好地理解对比损失。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值