原文:TowardsDataScience Blog
协议:CC BY-NC-SA 4.0
原文:https://towardsdatascience.com/building-a-food-recommendation-system-90788f78691a?source=collection_archive---------0-----------------------
任何影响个人健康的因素,如体育锻炼、睡眠、营养、遗传和污染。营养是我们生活中最大的可变因素之一,微小的变化也会产生巨大的影响。随着可供选择的食物数量呈指数增长,不可能再把它们都考虑进去了。考虑用户偏好、最大化食品中健康化合物的数量并最小化不健康化合物的唯一方法是使用(3D)推荐系统。
这个项目的目标是使用最大的公开可用食谱数据集合(Recipe1M+)来构建一个食材和食谱推荐系统。训练、评估和测试一个模型,该模型能够从多种配料中预测菜肴。根据预测的菜肴,估计负面配方-药物相互作用的概率。最后,构建一个 web 应用程序,作为构建 3D 推荐系统的一个步骤。
从 GitHub 库下载 web 应用并在本地执行。
已知有许多因素会影响一个人的健康。体育锻炼、睡眠、营养、遗传、污染以及其他外部因素[1]。营养是我们生活中最大的可改变因素之一,所以小的改变会导致重大的结果也就不足为奇了。
由于我们的饮食与文化有着紧密的联系,我们有可能在世界范围内找到大量的美食。每一种中最常见的成分都与该地区的特征密切相关,例如气候。这对当地食谱中每种成分的可用性有很大的影响[3]。
众所周知,一些分子对健康有积极的影响,即抗癌。能够确定哪些成分含有较高的浓度,可能有助于我们治疗和预防疾病[4]。此外,通过在美味和负担得起的膳食中加入这些成分,它可以促进人们营养习惯的转变。在一个快餐消费不断增长的世界里,很明显,除了前面两点,准备的速度也是一个重要因素。
随着越来越多的数据在网上公布,无论是来自研究还是网络应用,这是一个分析这些数据并创建新的食物推荐系统的机会,这些系统不仅考虑了抗癌特性等因素,还考虑了味道、营养成分以及与药物的负面相互作用。这将使用户在购买或准备下一餐时做出更好的决定[5]。
二十一世纪疾病(图 1)。癌症属于更广泛的肿瘤,是细胞分裂不受控制的一种亚型,有可能扩散到不同的组织。相反,良性肿瘤局限于某个器官。随着寿命的增加,衰老和一些调节途径的功能丧失之间存在密切的相关性,疾病的发病率也呈同样的趋势[6]。
众所周知,营养可以在预防和治疗这种疾病中发挥重要作用[4]。这样,它将有利于最大限度地增加食物中抗癌化合物的数量,并减少已知的与抗癌药物发生负面作用的化合物。
图 12016 年全球主要死亡原因。癌症排在第二位。改编自[7]。
尽管在线数据集和 API(应用程序编程接口)包含易于检索的结构化信息,但大多数在线资源并不具有这种有组织的结构。因此,需要不仅能够提取数据,而且能够获得其上下文的算法[8]。这一部分集中在单词嵌入和主题建模。
有几种方法可以实现单词的矢量表示。一种可能是将它们全部对齐,并将每一个表示为 0 的向量,数字 1 位于对齐的相应位置。那么,向量空间的维数将等于词汇表的大小。虽然这种方法对于小词汇表是可行的,但是计算效率不高。或者,有一种不同的单词嵌入机制,该机制通过考虑单词在句子中的上下文,允许使用低维向量来表示大型词汇表。
Word2Vec 由谷歌的 Tomas Mikolov 领导的研究团队开发,是一个浅层的两层神经网络特定类别的模型,可以产生单词嵌入[9]。它将文本语料库作为输入,并跨越一个向量空间,其中每个单词都被映射到一个向量。更经常出现在相似上下文中的单词被映射到由更短的欧几里德距离分隔的向量中。
Word2Vec 并不是主题建模的唯一工具。 Doc2Vec 和 FastText 分别能够对整个文档进行编码或者专门查看每个单词的形态结构【10】。
Word2Vec 被选择来编码这个项目中使用的数据集中的成分,作为向量。这使得从食谱的上下文中捕捉它们的相似性成为可能。
这种食谱检索算法是由脸书人工智能研究所开发的,它能够直接从图像中预测配料、烹饪说明和食谱标题[11]。
过去,算法一直使用简单的配方检索系统,该系统基于某些嵌入空间中的图像相似性。这种方法高度依赖于学习嵌入的质量、数据集大小和可变性。因此,当输入图像和静态数据集不匹配时,这些方法就会失败[11]。
反向烹饪算法不是直接从图像中检索食谱,而是提出了一个流水线,其中有一个中间步骤,首先获得配料集。这使得指令的生成不仅考虑了图像,还考虑了成分(图 2) [11]。
图 2 使用多个编码器和解码器的反向烹饪食谱生成模型,生成烹饪指令[11]。
这种方法的主要成就之一是在试图从图像中预测成分时,呈现出比基线配方检索系统[12]和普通人[11]更高的准确性。
本项目开发的美食推荐系统中包含了反向烹饪算法。基于 web 应用程序中的预测成分,向用户提供若干建议,例如:不同的成分组合。
一般来说,降维的目的是从高维向量中保留尽可能多的信息。主成分分析(PCA) [13]和 T-分布随机相邻实体(T-SNE) [14]是两种最常用的方法。第一种通常被定义为用数学方法解决问题,第二种是用统计方法。
PCA 的主要目的在于保留数据中具有较高可变性的矢量分量,同时丢弃增加较少信息的分量。这种分解可以通过两种不同的方式实现。一种是通过分解数据协方差矩阵的特征值。第二种方法是在通常将初始数据标准化后,对数据矩阵进行单值分解[13]。
另一方面,T-SNE 将点之间的相似性转换成联合概率。并且最小化低维嵌入和高维数据上的这些概率之间的 Kullback-Leibler 散度。这种方法具有非凸的成本函数,因此,不同的初始化可能产生不同的降维向量[14]。
能够可视化高维数据是至关重要的,尤其是在对执行聚类感兴趣的情况下。根据应用,社区发现算法可以输入不同的阈值参数,这些阈值参数影响集群的大小和连通性。能够可视化数据如何分布允许在选择这些值时使用人类推理。
其快速的执行和可靠的结果,使 PCA 成为首选。
有许多优化不同成本函数的聚类算法。
Louvain 算法反复分割网络,优化模块化[15]。它的值与同一集群内节点间的连接数成比例,当集群间的连接数开始增加时,该值会减少。数学上,模块化被定义为:
Aij 是表示连接节点 i 和 j 的边的权重的邻接矩阵条目, ki = ∑j Aij 是节点 i , ci 是其所属的社区, 𝛿(u,v) 如果 u = v 则为 1,否则为 0。 m = 1/2∑ij Aij* 是图中所有边的权重之和【15】。
在迭代步骤之间,要优化的值是它的变化,这使得计算更有效[15]:
虽然需要为每个试验社区计算 ki,in 和 ∑tot ,但是 ki/2m 是特定于正在被分析的节点的。这样,后一个表达式只有在优化模块性时考虑不同节点时才重新计算[15]。
Infomap 算法试图通过减少在网络内部确定的集群之间随机传播的假想流来减少网络的描述长度[16]。数学上可以表示为:
被 q = ∑(m)(j=1) qj 每个社区的退出概率之和, H(Q) 社区间移动的平均码长, p(i)(o)= qi + ∑(m)(β∈i) pβ 在一个社区中随机行走的停留概率 c 和*H(Pm)*a 的平均码长
第三种方法也被广泛使用,称为谱聚类[17]。与前两者相比,它有几个优点。最重要的是,在检测高度非凸的聚类时,或者当聚类的中心和扩散的度量不是预测社区的合适描述时,它显示出更高的准确性。此外,与其他两种方法相反,它的 Python 实现允许用户输入数据中出现的所需集群的数量。这是沿着项目执行集群的第一选择。
Python 中有几个工具可用于数据可视化。即 Matplotlib [18]、Plotly [19]、Seaborn [20]和 Pandas [21]。有些被认为在表示大量数据时更有效,而其他的则以非常通用和允许用户以多种方式轻松可视化数据而闻名。其他的则与现有的数据容器集成在一起,最终促进了它的可视化。与最新的数据分析和可视化平台(如 Jupyter Notebook 或 JupyterLab)兼容也是一个重要的标准。
Matplotlib 允许生成各种类别,例如:散点图、误差图、条形图、功率谱、直方图等。尽管它们是静态的,当散点图中的节点数量超过数万时,就不再能够代表它们[18]。
Plotly 不同于 Matplotlib,它允许数据点及其标签的动态表示。当点的数量超过数万个时,它也能更好地伸缩[19]。
Seaborn 是一个构建在 Matplotlib 之上的 Python 库。在表示大量数据点方面,它与后者一样强大,并允许用户以更简单的方式探索新的可视化选项[20]。
由于之前强调的要点和与 JupyterLab 完全兼容的事实(在 Plotly 的情况下,在安装相应的扩展之后),这 3 个模块在项目中一起使用。
虽然吃是一种基本需求,但有时人们不知道选择什么。事实上,当购买食品或在线订购时,选项的数量太大,无法将它们全部考虑在内。
人类有不同的营养需求,并以不同的方式感受味道。出于这个原因,满足他们需求的唯一选择是通过了解这个人。无论推荐对象是单纯的饥饿用户、烹饪爱好者、关心健康的人、节食者还是希望改善自己健康状况的人,这都会影响最终的选择[5]。
此外,被推荐的产品也有重要的影响:简单的配料替代、食谱、饭菜、餐馆甚至是一道菜。推荐的时机:实时或简讯。并且它可以考虑用户的位置并建议最近的地方。提出建议的平台。根据推荐的生成方式(协作过滤、基于内容、图形聚类或嵌入),它们可能需要设备提供不同的功能。这样,它们可以在网站、应用程序或纯文本(SMS)中共享。过敏或不耐受化合物(如坚果和牛奶)的存在,品牌,烹饪所需的时间,课程,烹饪,动物衍生物的存在,菜肴类型,配料,成本,配料数量,准备时间,味道或烹饪所需的技术[5]。
构建这些系统时的一个重要因素是数据的来源。它可以来自过去的订单,用户对某个帖子的反应(喜欢或不喜欢),社区的评级,观看的图像或视频,或其他社交网络相关的行为,包括帖子,分享,搜索,评论或追随者[5]。
食品推荐系统的成功(图 3)与其考虑用户偏好、最大化食品中健康化合物的数量和最小化不健康化合物的能力相关。
在这个项目中,探索了基于公开可用数据生成食物推荐的不同方法。大型食谱数据集(Recipe1M+和 Kaggle 和 Nature (K&N))包含关于现有配料、标题、源统一资源定位器(URL)和烹饪的信息,经过解析后可提供最精确的建议。
图 3 一个食物推荐系统的例子[5]。
这个项目的目的是建立一个食材和食谱推荐系统。这包括预处理 Recipe1M+数据集以进行成分检索。优化配料的词汇,使之与食谱中的相匹配。训练 Word2Vec 模型,使其能够将配料和配方转换为数字向量。将 2D 空间中的配料可视化,并将其用作配料推荐系统。训练、评估和测试支持向量分类器(SVC)模型,该模型能够通过考虑菜谱的配料集来预测菜谱所属的菜系。基于预测的烹饪,预测负面配方-药物相互作用的概率。为了鉴别菜肴,每份食谱中抗癌分子的平均数量较高。最后,创建一个 web 应用程序,该应用程序能够从图像中预测成分,建议新的组合,并检索食谱所属的菜肴,以及与抗肿瘤药物的预期负面相互作用次数的分数。
在介绍中,讨论了癌症、自然语言处理、逆向烹饪算法、降维、社区发现、数据可视化和在线食物推荐系统背后的基本概念。方法详述了项目的目标,并介绍了用于解决这些目标的工具。在结果中,介绍并讨论了项目的成果。最后,在结论中,回顾了项目的目标,讨论了目标是否实现,提出了主要的困难和对未来工作的建议。
简介涵盖了广泛的理论概念,尤其是项目中使用的工具。在方法上,将描述如何根据要实现的目标调整和应用这些方法。在项目的每一步中使用的最重要的 Python 和 JavaScript 包也包括在内。
首先,Recipe1M+和 K&N 数据集,以及成分的词汇表,根据它们的结构和对项目的价值进行描述。它还包括他们提交的优化过程。
将成分嵌入向量空间、减少其维数和聚类的过程根据所采用的工具和考虑到先前数据集的特征而执行的参数调整来详细描述。
接下来,考虑到参数和函数的选择,并考虑到训练集的维度,解释了预测每个食谱配料集的烹饪的分类器。
然后,描述了根据抗癌分子的数量和预测的负面配方-药物相互作用的数量对配方和烹饪进行分类的方法。
指定了每个地块使用的数据可视化工具。
最后,介绍了一个 web 应用程序,该应用程序从菜谱图像中检索配料,并使用了本项目开发的许多食物推荐系统,并详细介绍了它的实现。
Recipe1M+数据集是最大的公开配方数据集[22]。每个配方包含的信息被分成两个 JavaScript 对象符号(JSON)文件。
第一个用 ID 标识每个配方,并定义成分、说明、标题、URL 和它所属的集合:训练、验证或测试集合。这三组用于训练、验证和测试反向烹饪算法。第二个文件包括第一个文件的配方 id 和一组指向配方被废弃的网站的图片的 URL。一些网址不再活跃。虽然使用 Wayback 机器(【archive.org/web】)也可以访问和可视化菜谱。
除了这个数据集之外,还有两个 pickle 文件,其中包含配料词汇表和食谱说明。
构建食物推荐系统的一个必要步骤是从 Recipe1M+数据集中的食谱文本中提取配料。为了实现这一点,它优化了现有成分的词汇,其中所有的停用词和标点符号都被删除,其余的词被词条化。
一旦 Recipe1M+数据集从公开网站上抓取,包含来自访问者的食谱,预计会出现错误信息、错别字、非拉丁字符等。例如,有人证实,有些食谱中的配料或说明是空的,或者完全是由数字或标点符号组成的。所有这些情况都得到了纠正。在开始从数据集中的词汇中搜索成分之前,所有的停用词都被删除,剩下的被词条化。
这个数据集包含几个标有它们所属菜系的菜谱(github . com/altos AAR/food 2 vec/blob/master/dat/ka ggle _ and _ nature . CSV)。它被用来训练监督学习模型,该模型能够从一系列配料中预测菜肴。使用上一节中描述的词汇确定的相同成分。
它的结构是一个逗号分隔的文件,每行包含一个不同的配方。第一个值是菜谱的菜系。剩下的都是令牌化的成分。因此,不需要使用任何词汇来检索它们。
为了尽可能地使该数据集中的配料名称与 Recipe1M+中的一致,所有配料名称都进行了词条化,并删除了停用词。
为了构建一个配料和食谱推荐系统,最基本的是将它们表示为向量。这将允许用数学方法计算它们的上下文相似性。
使用 Recipe1M+和 K&N 数据集训练 Word2Vec 模型。在 Recipe1M+和 K&N 数据集的情况下,按照 Recipe1M+数据集和 K&N 数据集的说明分别检索每个配方中的成分。Word2Vec 工具可以在 python 库 Gensim 中免费获得。
训练 Word2Vec 模型的关键点之一是捕捉单词的周围环境。考虑到这一点,确保每个食谱中的配料顺序遵循一定的标准是非常重要的。否则,模型会将排序不同的相同成分解释为具有不同的上下文。为此,配料按字母顺序排列。作为模型输入而引入的语料库是来自 2 个数据集的食谱中存在的一组配料。
需要适当调整的超参数是尺寸、工人、窗口、 sg 和最小计数。尺寸指的是代表配料的每个向量所考虑的维数(100)。该值的选择是基于所获得的配料嵌入(配料推荐)的质量以及从烹饪方法到烹饪一节中介绍的配料集中检索烹饪的模型的准确性。工作人员的数量被设置为等于模型被训练的核心的数量(8)——MacBook Pro 15’2016 年末。这大大加快了培训过程。窗口指的是与被编码的单词的最大距离,该单词被认为是周围环境的一部分。为了计算该值,确定了 Recipe1M+和 K & N 中配料数量最高的配方。在 K & N 数据集中找到 66 个元素的配方后,窗口被设置为 65。最后,由于模型的目标是从相邻单词中预测目标向量,因此选择连续单词包。这意味着, sg 被作为 1 引入。考虑的最后一个参数是最小计数*。为了获得每种配料的矢量表示,即使较少表示, min_count 被设置为 1。*
在获得成分的向量之后,它们在 2D 图中被可视化。使用下一节介绍的工具降低维度后,这是可能的。
为了将 Word2Vec 创建的成分嵌入的维数从 100 减少到 2,使用了 PCA。在 scikit-learn 中,在分解包中,有几个模块可以减少向量维数。其中一个是 PCA ,用于允许 Recipe1M+数据集中所有成分的可视化。
为了根据相似性对 Recipe1M+数据集中的成分进行聚类,将谱聚类应用于用 Word2Vec 创建的成分嵌入和用 PCA 降维。同样,它使用了 scikit-learn ,但是是一个不同的包。 cluster 包含了很多能够在数据中发现社区的函数,但是使用的是 SpectralClustering 。
该功能为用户提供了输入所需聚类数的可能性。选择的数量与[3] — 9 中确定的成分类别的数量相同。它们是主菜、小吃、饮料、汤/炖菜、面包、沙拉、开胃菜、配菜和甜点。
一个 SVC 模型被训练来根据它们的配料预测食谱的烹饪。
选择 K&N 数据集来训练模型是因为它的大小,包含每个食谱和各自菜肴的成分列表。然而,不可能向 SVC 提供一组字符串来执行训练。在对所有成分的矢量表示进行平均后,每个配方都被转换成一个矢量。之前介绍的 Word2Vec 模型是用来自 Recipe1M+和 K&N 数据集的数据训练的,因此,第二个数据集中每种成分的矢量表示已经可用。
为了训练支持向量机(SVM)模型,使用了来自 scikit-learn 的 SVM 软件包。它需要选择一个函数,还需要根据训练数据集调整几个参数。
由于大量的功能(100 个)、配方和模型训练的计算限制(MacBook Pro 15 ’ 2016 年末),它使用了线性内核来减少训练时间。使用的函数是 LinearSVC 。
需要调整函数的几个参数。发现 K&N 是一个不平衡的数据集。数据集中某些类别(菜系)的规模有时相差两个数量级。由于这个原因, class_weight 被设置为平衡。这意味着每个类的权重与它们的元素数量成反比。接下来,为了保证训练收敛,将最大迭代次数( max_iter )从标准值 1000 增加到 5000。此外,每当数据集包含的元素数量比每个特征配方的元素数量多时,建议设置算法来解决对偶优化问题。这是通过将双参数设置为假来实现的。有一些参数(例如:正则化)不能从数据集的特征中直接推断出来。因此,使用 model_selection 包(也属于 scikit-learn )中的 GridSearchCV 函数是很重要的,这样就可以对它们进行详尽的搜索,并优化模型的精度。对于正则化参数,测试范围从 0.00001 到 10000 的 10 的倍数的值。发现 0.0001 是最佳的,然后将其用于训练模型。该参数说明了数据点错误分类的重要性。
这个项目的目标之一是根据抗癌分子的数量对菜肴进行排序。首先,使用表 1 中的全套成分(包括未列出的成分),确定 Recipe1M+数据集中每种配方中抗癌分子的数量[4]。为了将它们的名称与数据集中的成分相匹配,它们被简化了。比如普通葡萄转化为葡萄。在使用《烹饪方法》中介绍的 SVC 检索数据集中每种烹饪方法后,计算出每种烹饪方法中抗癌分子的平均存在量。
表 1 每种成分在第一栏和第二栏分别用其(修改后的)通用名称和学名表示。抗癌分子的数量及其名称出现在最后两位。只有五种抗癌分子数量最多的成分被显示出来。改编自[4]。
烹饪也可以根据它们的食谱与药物的预期负面相互作用的数量来分类。对于抗肿瘤药和免疫调节剂,引入了预期有害相互作用的百分比(表 2) [3]。在使用 HyperFoods 应用程序从食谱图像中检索菜肴后,这些信息将用于预测负面食谱-药物相互作用的可能性。
表 2 抗癌药与全球美食之间预期的负面相互作用的千分之一[3]。缩写:NA(北美)、WE(西欧)、NE(北欧)、EE(东欧)、SE(南欧)、ME(中东)、SA(南亚)、SEA(东南亚)、EA(东亚)、LA(拉美)和 A(非洲)。
Matplotlib、Plotly 和 Seaborn 是三个 python 可视化框架,用于可视化项目的一些数据。
Matplotlib 用于绘制报告中所有 2D 成分的矢量嵌入。在项目存储库中可用的 Jupyter 笔记本中,可以使用 Plotly 来动态可视化相同的数据。使得逐个成分的检查变得更容易,一旦它们的标签最初被隐藏,仅当鼠标悬停在相应的节点上时才出现。也可以分别放大和缩小以获得更多或更少的细节。
Seaborn 绘制了困惑矩阵,这是评估《烹饪法到烹饪法》中详述的烹饪检索算法的结果。
作为建立新的食材和食谱推荐平台的一个步骤,它开发了一个 web 应用程序。这能够从图像(由 URL 提供)中预测成分。基于它们在嵌入向量空间中与由反向烹饪算法识别的成分的接近度来建议替代成分。从检索到的一组配料中预测菜系。并且基于预测的烹饪来估计负配方-抗肿瘤药物相互作用的概率。
下面描述 web 应用程序的后端和前端的实现。
后端是使用 Node.js 开发的。在服务器端,导入了包含词汇表中前 3 个最相似成分的文件。这个文件是在计算嵌入空间中所有向量之间的欧几里德距离并将结果字典导出为 JSON 文件之后获得的。通过设置监听端口,在前端 HTML 页面和服务器之间建立连接。python 外壳用于:执行用 Python 实现的反向烹饪算法;加载 Word2Vec 模型;将图像的成分转换成矢量;计算每个食谱的矢量表示,并加载 SVC 模型,以便能够根据食谱矢量预测菜肴。在服务器端实现并执行了一个将二进制代码转换回字符串的函数。由于一般 URL 的格式,不可能从前端获取到服务器的链接。所以,这在前端被转换成二进制,在后端被转换回字符串。
在前端,使用 HTML 构建界面的主要结构。CSS 被用来使界面简单直观。JavaScript 支持响应性网页和与服务器的通信。用于使网站用户友好的一个基础 JavaScript 库是 D3.js 的缩小版,版本 4。它处理所有的鼠标事件。
在实现后端和前端之后,目标是使 web 应用程序在线可用。由于 Heroku 应用程序(托管平台)的大小限制和一些 PyTorch 文件的大小,这没有实现。在执行反向烹饪算法时,它使用了 PyTorch 模块的一个版本,该版本包括 GPU 和 CPU 支持。模块占用的内存超过 1GB。由于托管平台的存储限制(500 MB ),它使用了仅在 CPU 上执行的 PyTorch 的较轻版本。一旦 Heroku 不提供图形处理能力,这不会影响应用程序的执行。这一修改将应用程序的大小减少了一半。但仍然有来自反向烹饪算法的训练 PyTorch 模型导致应用程序超出服务器的内存限制。克服这一点的一种方法是使用较小的训练数据集来重新训练模型,但这将显著降低检测的准确性。由于时间限制,没有遵循这条路线。模型的大小(436 MB)不足以超过阈值,但与执行应用程序所需的 Node.js 和 Python 包并行,不可能使其在线可用。虽然,从 GitHub 库下载后,web 应用仍然可以在本地运行。
在方法上,项目的目标和实现它们所使用的工具被详细描述。在结果中,呈现了来自数据分析和可视化的结果。同时讨论结果的可预测性及其影响。
首先,提供了用于数据分析(Recipe1M+数据集)和模型训练(K&N 数据集)的数据集的详细概述。然后,指定成分嵌入和在二维空间中可视化它们的标准(成分推荐)。接下来,使用混淆矩阵评估 SVC 的性能,并在之后进行测试(食谱到烹饪)。每份食谱中抗癌分子数量较多的菜系会被排名(菜系分类)。最后,介绍了开发的食物推荐 web 应用程序(HyperFoods App)。
该数据集包含 1029715 种配方,由 1480 种不同的成分混合而成。
为了更好地了解菜谱的来源,对数据集进行了解析,并返回了一个抓取的网站列表(表 3)。大多数数据库是欧洲或美国的。通过这种方式,烹饪检索算法可以将大量的食谱分类到这些类别中。
表 3 左侧废弃的用于创建 Recipe1M+数据集的网站。中间是各自的网址。右边是每个来源的食谱数量。
为了从 Recipe1M+中检索配料,开发了一个词汇表的优化版本,它是由发布数据集的同一个团队创建的。
表 4 显示了 Recipe1M+数据集中最常从食谱中检索到的前 5 种配料及其各自的出现次数。在 2D 嵌入向量空间中绘制成分时使用了该数据,并讨论了其在成分推荐方面的相关性(成分推荐)。
表 4 左侧 Recipe1M+数据集中出现频率最高的 5 种配料。右边是各自出现的次数。
K&N 数据集包含 96250 种食谱和 3904 种不同的配料,涵盖 11 种菜系:北美、西欧、北欧、东欧、南欧、中东、南亚、东南亚、东亚、拉丁美洲和非洲。尽管这个数据集包含 Recipe1M+中大约 10%的食谱,但它包含的不同配料的数量是前者的两倍多。这是因为在该数据集中,糖等简单成分根据其颜色或来源(例如:有机砂糖、超细白糖、烘焙糖等)被分成不同的成分。
表 5 列出了前 5 种最常见的成分。Recipe1M+和 K&N 数据集中最常见的成分明显重叠。在前 5 名中,洋葱和胡椒同时出现在两个数据集中。
表 5 在左边,K & N 数据集中出现频率更高的成分。右边是各自的存在数量。
在表 6 中,根据食谱的数量,表示了数据集中的烹饪的分布。在 K&N 数据集中检测到的每种菜肴的食谱数量不平衡。北美烹饪包含的食谱比东欧多 2 个数量级。这将影响 SVC 模型的准确性(混淆矩阵)。
表 6K&N 数据集中属于不同菜系的菜谱数量。缩写:NA(北美)、WE(西欧)、NE(北欧)、EE(东欧)、SE(南欧)、ME(中东)、SA(南亚)、SEA(东南亚)、EA(东亚)、LA(拉美)和 A(非洲)
在 100 个特征嵌入中表示 Recipe1M+数据集中存在的每种成分,并将维度减少到二维空间后,获得了图 4 中的图。为了清楚起见,在数据集中出现少于 4500 次的所有成分都没有表示出来。不同的颜色对应于使用光谱聚类识别的不同聚类。
光谱聚类确定了沙拉、亚洲菜肴、水果&坚果和甜点类别(图 4)。
图 4recipe 1m+中几种成分的上下文相似性。仅表示在数据集中至少出现 4500 次的那些。配料根据它们所属的种类而着色。
这种食物表征允许我们提取关于哪些成分最常同时出现的信息。因此,它为根据它们在图中的接近程度尝试新的组合提供了基线。重叠成分的半径越大,它们组合成功的信心就越大。
一些成功的组合是大蒜、鸡肉和洋葱;番茄,罗勒和芹菜或蜂蜜和橘子。
相同的图像被重印,但是具有不同的着色标准。这一次,含有至少一种抗癌分子的成分被涂成绿色,其余成分被涂成黑色(图 5)。
图 5recipe 1m+中成分的上下文相似度。仅表示在数据集中至少出现 4500 次的那些。绿色节点(成分)包含至少 1 个抗癌分子。
通过识别与含有抗癌分子(绿色节点)的成分更接近的成分,人们可以假设,鉴于它们在食谱中存在的相似背景,可能更有可能在食谱中找到这些相同的分子。
此外,图 5 不仅为我们提供了通常同时出现的成分的信息,还为用户提供了它们在抗癌分子中的含量信息。这样,用户可以考虑他们的抗癌特性,同时考虑上下文相似性。检索了一些潜在的组合,如图 6 所示。
图 6 肉桂、核桃、蔓越莓;观察图 5,花生和芒果是两种最成功的配料组合。
在 Recipe to Cuisine 中讨论过,SVC 的实现能够在给定 Recipe1M+和 K&N 数据集包含的一组食材的情况下预测菜系。在这一节中,在构建混淆矩阵后评估其准确性,在 Recipe1M+数据集中测试该模型,并确定在菜系分类中起重要作用的一些食材。
为了理解分类器如何检测不同的菜肴,从训练集计算出多维混淆矩阵(图 7)。它包括对 K&N 食谱数据集中 11 种烹饪法中每一种的预测。
图 7 使用 K & N 数据集训练的 SVM 模型的混淆矩阵。每一行,以及各自的值,代表正确分配给真正的菜肴的配料比例。每一列都是由算法预测的菜系。
属于北欧、东欧、西欧和中东地区的食谱经常被误归类为北美食谱。就北欧、东欧和中东而言,这可能是因为它们在数据集中代表性不足:分别为 739、381 和 645 种食谱。以及过多的北美美食。
另一个重要因素是常见的成分。事实上,所有的欧洲美食经常被错误地归入其中。例如,11.5%的北欧食谱被错误地归类为西欧食谱。欧洲是拥有最多美食的大陆(4)。这可能会降低它们之间的特异性。
该模型在预测东亚、南亚和北美食谱时更加准确。事实上,分别有 84.8%、83.4%和 73.0%的人回答正确。
在训练分类器之后,它被用来预测 Recipe1M+数据集中每个食谱的烹饪。各自的比例如表 7 所示。
为了测试分类器,使用了以下方法:首先,检索标题中出现单词 tea 的所有食谱。然后,计算出最终的菜肴分布(表 7)。
表 7recipe 1m+内菜系分布。另外,过滤标题中包含关键字沙拉和茶的。
正如所料,标题中包含单词 tea 的大多数食谱被归类为,第一,属于东亚(27%的食谱),第二,属于北欧(25%的食谱)(图 8)。
这两个领域在 tea 精选食谱中比在整个 Recipe1M+数据集中表现得更多。在东亚,中国是世界上最大的茶叶绝对消费国,每年消费 16 亿英镑[23]。从北欧国家来看,爱尔兰、英国和俄罗斯是人均消费率较高的前 4 个国家[23]。另一方面,排名最高的南欧国家(西班牙)在人均茶叶消费量上仅排在第 40 位[23]。事实上,数据集的最大下降(从 21%到 5%)是在这个地区得到验证的。
图 8 全球每人每年的茶叶消费率。[23]
为了分析不同菜肴中抗癌分子的存在,人们使用了每种菜肴中抗癌分子数量的信息。在对一个烹饪类别中的所有食谱进行平均后,确定每个食谱的得分(表 8)。
表 811 种代表性菜系中每一种的平均抗癌分子数量。缩写:NA(北美)、WE(西欧)、NE(北欧)、EE(东欧)、SE(南欧)、ME(中东)、SA(南亚)、SEA(东南亚)、EA(东亚)、LA(拉美)和 A(非洲)。
地中海地区的三个地区获得了最高的抗癌得分:南欧、中东和非洲(图 9)。另一方面,北美菜肴被认为是抗癌分子数量最少的。
这些结果与对北美烹饪的预测一致,北美烹饪通常被归类为不健康,并与肿瘤疾病的发病率呈正相关[24]。地中海饮食富含水果和蔬菜,通常被认为可以预防癌症[25]。
图 9 包含抗癌分子数量较高的食谱的菜肴。使用[26]生成的世界地图。
为了了解哪些配料可能是导致南欧、中东和非洲菜肴排名靠前的原因,通过只考虑标题中包含关键字沙拉的配料来计算它们的分布(表 7)。
表 7 显示沙拉食谱大多被归类为南欧菜肴的一部分。它们可能是增加这种菜肴抗癌得分的主要原因之一,因为表 1 完整版本中的大多数成分通常在沙拉中都能找到。此外,值得强调的是,南欧饮食的主要组成部分之一是沙拉[27]。
在网页的顶部,FoodReco 接收在线可用图像的 URL,并在执行反向烹饪算法后返回预测的配料列表。它们将显示在已处理图像的下方。将鼠标悬停在每种成分上,会显示 Recipe1M+和 K&N 中最常同时出现的前 3 种成分的有序列表。底部显示的是根据一系列配料预测的菜肴。每当与药物的负面相互作用数量低于平均值时,该文本字段的背景颜色为绿色,如果高于平均值,则为红色(图 10)。该值是对表 2 中的所有许可值求平均值后计算得出的。
点击可下载网络应用。
图 10FoodReco web 应用界面。它能够从图像中预测配料,建议每种配料的 3 种替代物,并检索出这道菜最可能属于的菜肴。
这个项目的目标是使用最大的公开可用食谱数据集合(Recipe1M+)来构建一个食材和食谱推荐系统。训练、评估和测试一个模型,该模型能够从多种配料中预测菜肴。基于预测的烹饪,预测负面配方-药物相互作用的概率。最后,建立一个 web 应用程序,作为建立一个考虑用户口味偏好的推荐系统的一个步骤,使食物中健康化合物的数量最大化,不健康化合物的数量最小化。
使用 Word2Vec 生成每种成分的矢量表示。通过对矢量化配料的所有成分进行平均,获得了食谱的类似表示。SVC 模型被训练来从它们的配料集合中返回食谱的烹饪。南亚、东亚和北美菜肴的预测准确率超过 73%。非洲、南欧和中东的菜肴含有最多的抗癌分子。最后,它开发了一个 web 应用程序,能够从图像中预测成分,建议新的组合,并检索食谱所属的菜肴,以及与抗肿瘤药物的预期负面相互作用次数的分数。它不可能在网上发布,但是可以在本地执行(github.com/warcraft12321/HyperFoods)。
这个项目中使用的方法的未来增强是为成分创建更详尽和准确的词汇表。在使用 Word2Vec 嵌入成分之前,Recipe1M+和 K&N 数据集中存在的成分之间的一致化可以增强嵌入和 SVC 的准确性。为考虑到不同成分的比例的配方生成向量。这个项目朝着这个方向迈出了一步,开发了一个词汇表,其中包括 Recipe1M+数据集中的所有单位(习惯单位和常用公制单位)。以及所有确定的单位与克之间的转换系统。除了线性核之外的不同的核可以用于训练烹饪检索 SVC 模型。或者,深度学习被用来优化相同的问题。最后,虽然 web 应用程序可以在本地计算机上顺利运行,但下一步将是使其在线可用并具有更多功能,例如:添加额外的食物推荐,以选择富含抗癌分子的成分(超食物),同时减少除抗肿瘤药之外的其他类型药物的药物-菜肴负面相互作用的数量。
报告 | 海报 | GitHub 资源库
[1] H. Arem 和 E. Loftfield,“癌症流行病学:预防和生存的可变风险因素调查”,*美国生活方式医学杂志,*第 12 卷,第 3 期,第 200–210 页,2018 年。
[2] M. S. Donaldson,“营养与癌症”,*《营养杂志》,*第 3 卷,第 19-25 页,2004 年。
[3] M. Jovanovik,A. Bogojeska 和 D. e. a. Trajanov,“使用关联数据方法推断烹饪-药物相互作用”,*科学报告,*第 5 卷,第 9346 号,2015 年。
[4] K. Veselkov,G. Gonzalez,S. Aljifri,D. Galea,R. Mirnezami,J. Youssef,M. Bronstein 和 I. Laponogov,“HyperFoods:食品中抗癌分子的机器智能绘图”,*科学报告,*第 3 卷,第 9237 号,2019 年。
[5] C. Anderson,《食品推荐者调查》, *ArXiv,*第一卷 abs/1809.02862,2018。
[6] J. R. Aunan,W. C. Cho 和 K. Sø reide,“衰老和癌症的生物学:共享和分歧分子特征的简要概述”,*衰老和疾病,*第 8 卷,第 5 期,第 628-642 页,2017 年。
[7]“IHME,全球疾病负担,数据中的世界”,2016 年。【在线】。可用:http://www.healthdata.org/gbd.【2020 年 3 月 8 日获取】。
[8] M. Chary,S. Parikh,A. F. Manini,E. W. Boyer 和 M. Radeos,“医学教育中的自然语言处理综述”,*《西方急诊医学杂志》,*2019 年第 20 卷第 1 期。
[9] T. Mikolov,K. Chen,G. Corrado 和 J. Dean,“向量空间中词表征的有效估计”,学习表征国际会议论文集, 2013。
[10]r . řehůřek,“gensim:人类的主题建模”,[在线]。可用:https://radimrehurek.com/gensim/.【2020 年 3 月 8 日获取】。
[11] A. Salvador,M. Drozdzal,X. Giro-i-Nieto 和 A. Romero,“逆向烹饪:从食物图像生成食谱”,计算机视觉与模式识别, 2018。
[12] A. Salvador,N. Hynes,Y. Aytar,J. Marin,F. Ofli,I. Weber 和 A. Torralba,“学习烹饪食谱和食物图像的跨模态嵌入”,计算机视觉和模式识别, 2017。
[13] I. T. Jolliffe 和 J. Cadima,《主成分分析:回顾与近期发展》,*英国皇家学会哲学汇刊 A 数学物理与工程科学,*2016 年第 374 卷第 2065 期。
[14] L. v. d. Maaten 和 G. Hinton,“使用 t-SNE 可视化数据”,《机器学习研究杂志》,,第 9 卷,第 2579-2605 页,2008 年。
[15] V. D. Blondel,J.-L. Guillaume,R. Lambiotte 和 E. Lefebvre,“大型网络中社区的快速展开”, J. Stat 机甲战士。, 2008 年。
[16] M. Rosvall、D. Axelsson 和 C. T .博格斯特伦,“地图方程”,*《欧洲物理杂志专题》,*第 178 卷,第 1 期,第 13-23 页,2009 年。
[17] A. Y. Ng,M. I. Jordan 和 Y. Weiss,“关于谱聚类:分析和算法”,*第 14 届国际神经信息处理系统会议记录:自然和合成,*第 849-856 页,2001 年。
[18]《Matplotlib:Python 绘图》,Matplotlib,[在线]。可用:https://matplotlib.org/.【2020 年 3 月 8 日获取】。
[19]“Plotly:面向企业的现代分析应用”,Plotly,[在线]。可用:https://plot.ly/.【2020 年 3 月 8 日获取】。
[20]“seaborn:统计数据可视化”,Seaborn,[在线]。可用:https://seaborn.pydata.org/.【2020 年 3 月 8 日获取】。
[21]《熊猫》,[在线]。可用:https://pandas.pydata.org/.【2020 年 3 月 8 日获取】。
[22] J. Marin,A. Biswas,F. Ofli,N. Hynes,A. Salvador,Y. Aytar,I. Weber 和 A. Torralba,“Recipe1M+:用于学习烹饪食谱和食物图像的跨模态嵌入的数据集”, IEEE 模式分析和机器智能汇刊, 2019。
[23] R. A. Ferdman,“地图:喝茶最多的国家”,《大西洋月刊》,2014 年 1 月 21 日。【在线】。可用:https://www . theatlantic . com/international/archive/2014/01/map-the-countries-the-drink-the-most-tea/283231/。【2020 年 3 月 7 日访问】。
[24] M. S. Donaldson,“营养与癌症:抗癌饮食证据综述”,*《营养杂志》,*第 3 卷,第 19 期,2004 年。
[25] A. Maruca,R. Catalano,D. Bagetta,F. Mesiti,F. A. Ambrosio,I. Romeo,F. Moraca,R. Rocca,F. Ortuso,A. Artese,G. Costa,S. Alcaro 和 A. Lupia,“地中海饮食作为具有多靶向抗癌概况的生物活性化合物的来源”,*《欧洲药物化学杂志》,*第 181 卷,2019 年。
[26]《地图图》,[在线]。可用:【https://mapchart.net/world.html. 【2020 年 3 月 7 日接入】。
[27] C. M. Lăcătușu,E. D .格里戈里斯库,m .弗洛里亚,a .奥诺弗雷斯库和 B. M .米海,《地中海饮食:从环境驱动的饮食文化到新兴医学处方》,*《国际环境研究与公共卫生杂志》,*第 6 卷,第 16 期,2019 年。
[28]“朱庇特项目”,朱庇特,[在线]。可用:https://jupyter.org/.【2020 年 3 月 8 日获取】。
原文:https://towardsdatascience.com/building-a-game-recommendation-engine-870a1ccd11c4?source=collection_archive---------35-----------------------
对于我的 Flatiron 数据科学训练营顶点项目,我知道我想建立一个推荐引擎。推荐系统已经成为我们日常生活的一部分,从网飞推荐电影到亚马逊展示我们感兴趣的商品。虽然 MovieLens 数据集似乎是学习和构建推荐系统的首选数据集,但我希望使用不同的数据源来确保项目更加独特。
在 COVID 疫情期间,随着人们更多地呆在家里,视频游戏出现了激增。事实上,Steam 在 2020 年 3 月报告了创纪录的在线并发用户数。因此,我决定调查游戏推荐,看看我的预测是否与 Steam 的一致。
由亚历克斯·哈尼在 Unsplash 拍摄的照片
第一步:获取数据
这些数据是从朱利安·麦考利的推荐系统数据集页面获得的。我使用了两个文件:版本 1:用户和物品数据,其中包含了协作过滤模型所必需的用户-物品交互数据;以及版本 2:物品元数据,其中包含了与游戏相关的信息,比如发布日期、标签、价格等等。
第二步:加载并预处理数据
虽然数据据说是 JSON 格式的,但我无法用 Pandas 直接加载它。当通过 JSON linter 运行它时,我注意到它不是正确的 JSON,因为使用了单引号而不是双引号。一个可行的解决方案是使用读取数据,数据预处理相对简单,从字典列表中提取游戏 id 是一个小小的挑战。
第三步:建模
为了创建用户推荐模型,我使用了 LightFM 库。文档非常简单。在实例化模型之前,我将数据框架修改为稀疏交互矩阵。有许多可能的损失函数可以使用,我发现 WARP 提供了最好的模型。这种方法通过重复采样负样本直到找到一个违反规则的样本来最大化正样本的等级。当只有积极的互动,人们希望优化推荐列表的顶部时,这也是最常用的,这两种情况都适用于我的情况。
步骤 4:生成用户推荐
随着我们的最终模型在完整的交互矩阵上得到训练,我现在可以为用户生成推荐了。我创建了一个函数,它将训练好的模型、交互矩阵、用户 id 和所需推荐的数量作为输入,并为该用户返回排名前的游戏。
第五步:单品推荐
我还使用余弦相似性作为距离度量,使用该模型来生成项目到项目的推荐。我创建了一个函数,它接受一个游戏 id 并返回最相似的游戏。
示例输出:五个类似于美国卡车模拟器的游戏
更多细节和底层代码,请看我的 GitHub 库。
参考
https://www . games industry . biz/articles/2020-03-16-record-number-of-steam-users-online-during-coronavirus-outbreak
原文:https://towardsdatascience.com/building-a-gan-general-adversarial-network-6d0f69747945?source=collection_archive---------27-----------------------
致谢: Pexels 的 jimmy teoh
在过去的一个月里,我一直在开发一个人脸识别系统。我从一开始就对 gan 感兴趣,因为它们能够创造新的照片和不存在的数据集。在本文中,我将介绍什么是 GAN,然后简单介绍一下我使用的代码。
GAN 或通用对抗网络是利用两个神经网络的网络,一个生成器和一个鉴别器。生成器的工作是创造新的数据,鉴别器的工作是决定生成器吐出的数据是不是假的。在我的例子中,生成器创建图像,鉴别器决定图像是否真实。在训练过程中,生成器的目标是生成越来越好的图像来欺骗鉴别器,而鉴别器的作用是越来越好地决定图像是不是假的。目标是鉴别器不能区分图像是否来自训练数据。如您所见,这为两种算法创建了一个正反馈循环,从而改善了生成器生成的最终图像。
GAN 的基本图。署名:维克拉姆·梅农
我专门构建了一个 DCGAN,一个深度卷积的一般对抗网络,它的工作方式有点不同。它利用卷积网络,而不是在发生器和鉴别器中使用多层感知器。
DCGAN 图。署名:维克拉姆·梅农
这有利于我们,因为需要更少的训练数据和时间。ConvNets 基于数据相关的思想。在我的例子中,它允许算法将图像一侧的像素关联到另一侧。这使得它能够为图像中的不同结构赋予重要性,并区分它们。这对于图像非常有帮助,因为常规的多层神经网络单独观察和训练每个像素,而 ConvNet 可以训练一个区域,并将其应用于其他像素。此外,DCGAN 不使用池,而是使用 Stride。这是因为池只关心图像中的对象是否存在,而 Stride 也关心位置。总的来说,DCGANs 能够实现更平滑和更高效的过程,这就是为什么它是最常见的 GAN。
我将回顾所使用的代码,以及这些代码对于 DCGAN 如何工作的意义。
发电机
如上所述,生成器的工作是生成一个图像来欺骗鉴别器。那么,它到底是怎么做到的呢?
发电机的输入是一个潜向量。潜在向量是映射到潜在空间中的一组隐藏点,这些点应用于向量算法。矢量算法建立点之间的关系,例如距离和地形数据。
图像尺寸开始很小,最后变大。署名:维克拉姆·梅农
然后,潜在向量被送入一系列步长二维卷积转置层。这基本上包括一个跨越(或跳过)输入矩阵的内核。为了增加图像的大小,需要上采样。上采样是指程序将维度加倍,以获得特定维度的更大、更密集的图像。
接下来,我们通过批量标准化来运行它,以使训练更容易。通过规范化图层,它减少了潜在值的变化量。这稳定了层的激活,允许最佳权重并降低损失函数。
信用:笑库存,通过维基 (CC BY-SA 4.0)
接下来我们通过一个 ReLU 激活来运行它。Relu 的特别之处在于,虽然它在照片的右半部分看起来像一条直线,但在左半部分可以看到,它并不是。这是一个基本的激活功能,它允许程序超越线性回归,学习更复杂的数据,如视频、音频或对我来说是图像。
最后,我将我的数据输出到一个双曲正切函数中,该函数依次输出-1 和 1 之间的数据。这将使数据正常化,并将其返回到原始范围。
鉴别器
图像发生器的尺寸减小了。署名:维克拉姆·梅农
如前所述,鉴别器将生成的图像作为输入,并输出图像来自训练数据的概率。鉴别器只是做与生成器相反的事情。首先,它将数据输入到一个 2dConv 网络中,这次没有放大(因为我们在缩小)。然后,它通过批处理规范化和 Relu 来馈送它。最后,它使用 sigmoid 激活函数输出概率,而不是生成器中的双曲正切函数。这样做的好处是它输出 0 到 1 之间的概率。
既然我们已经有了生成器和鉴别器,我们必须实际训练网络并得到结果。我们首先根据训练数据训练鉴别器,然后从生成器生成图像,并对生成的图像运行鉴别器。
快速旁注:
那就是 Goodfellow 的论文中提到的 GAN 损失函数。D(G(z))是生成器(G)的输出是真实图像的概率。鉴别器 D 试图最大化它对生成的图像进行正确分类的机会(log(D(x))。另一方面,G 试图最小化鉴别器将图像分类为假图像的概率(log(1D(G(x)))。这迫使生成器和鉴别器在工作中做得更好。
经过一个时期的训练后,结果如下:
经过 10 个时期的训练,结果看起来像这样:
正如你所看到的,随着时间的推移,生成的图像在识别和再现人脸的面部结构方面变得越来越好
疯狂的是生成的人都是百分百假的。这太疯狂了。这方面的应用有很多。从图像编辑到安全和银行业务,GANs 拥有巨大的潜力。能够生成新的数据集是理解和创造新事物的关键因素
创作这个 GAN 对我来说是一次非常享受的经历,因为我必须真正弄清楚所有复杂的部分是如何组合在一起的。请继续关注我的下一个版本!
教程:https://py torch . org/tutorials/初学者/dcgan_faces_tutorial.html
联系我:
领英:https://www.linkedin.com/in/vikram-menon-986a67193
电子邮件:vikrammenon03@gmail.com
原文:https://towardsdatascience.com/building-a-job-recommender-for-non-technical-business-roles-via-nlp-and-machine-learning-626c4039931e?source=collection_archive---------12-----------------------
我为非技术背景的人建了一个工作推荐器。这篇文章是关于这个应用的特性和我构建它的步骤。
剧组在 Unsplash 上拍照
这里是 app 的链接。
由于我以前的公司最近裁员,我受到启发创建了一个工作推荐器。我的许多被解雇的前同事进入职业生涯不到 3 年,他们想知道,根据他们的经验,他们适合什么样的角色,他们应该从哪里开始找工作。我记得大学毕业时也有过类似的挣扎,当时我也不知道应该把目光放在哪里。我相信这个问题对于非技术背景的人来说是相当普遍的。
因此,我决定为我们这种职位的人——那些非技术背景的人,如心理学专业的人——建立一个工作推荐器,它将使用基于我们过去经历的信息来帮助我们走上正确的道路。
该应用程序结合了自然语言处理技术,如主题建模和分类风格的机器学习,以确定最适合你的。你复制并粘贴你的简历/ LinkedIn 到文本框中,应用程序解析文本并为你提供 ML 驱动的分析,分析你适合哪些工作以及为什么适合。
功能 1: 按作业类型返回匹配百分比。
功能 2: 根据主题匹配,返回一张你的简历与其他职位的匹配度图。这个图表有望对你从特性 1 中得到的结果提供某种解释。
特点 3: 选择不同工作原型的下拉列表,看看你的简历中哪些关键词匹配,哪些不匹配。
在本文的剩余部分,我将回顾我构建工作推荐器的步骤。我的代码的链接在这里。
数据科学项目最重要的部分是范围界定,也就是说,规划您的项目,使其符合您的时间和精力限制,但仍然能够回答有价值的问题。某个领域可以拥有如此多的数据和探索途径,其数量之大令人难以招架。因此,你需要清楚你要解决什么问题,你要寻找什么具体数据,成功的最低门槛是什么。
我研究的关键问题是找出需要分析的工作类型。在非技术性的商业领域,有如此多不同的工作。我觉得如果我包括太多的工作申请,这个项目就不会达到预期的效果。建模可能不太准确,应用程序最终可能过于混乱和不集中,对最终用户没有帮助。因此,我回想了一下自己的初衷,并为乔布斯的分析确定了两个标准:
- 这些工作必须是不需要技术技能的商业角色。这不包括软件工程师、医学或表演。
- 这份工作的薪水必须在 40-120,000 英镑之间。这反映了具有 0-3 年工作经验的人的典型收入范围。
之后,我想到了一些有意义的宽泛的工作原型,但也发出了一份调查,看看别人对我的想法有什么看法。然后,我让我的同事对他们感兴趣的工作类型进行排名,这样我就可以限制我必须分析的工作类型的数量。理想情况下,我希望分析不到 10 种工作类型。
有了这些信息,我选择了 5 个最受欢迎的工作作为我分析的基础,但后来当我确信我的模型可以正确区分工作类型时,我又添加了更多。我最终在非技术业务领域选择了 8 种不同的工作类型,还出于个人兴趣添加了“数据科学家”。
我计划使用的数据是符合上述标准的各个工作类型的职位发布。我第一次看 LinkedIn 和确实,但他们的网站证明太难刮,因为动态加载。
我决定从 Glassdoor 上抓取招聘信息,它也使用动态加载。但这一次,我借用了一位数据科学家同事的代码,并根据我的需要进行了修改。我很感激这段代码,因为构建我自己的 scraper 将花费我更多的时间!
在修改了 scraper 以适应我的需求后,我为每个工作类型刮了 40 个帖子并加入了文件。许多工作显然不符合正确的工作原型——例如,当我担任“项目经理”时,我得到了许多建筑方面的工作。我还得到了许多头衔为“高级(工作类型)分析师”或“主管(工作类型)”的工作,这些职位对于有 0-3 年工作经验的人来说显然是高不可攀的。因此,我设置了文本过滤器来筛选这些工作类型,并仔细检查以确保其余的数据符合我的要求。最终,我得到了来自 9 个不同工作类型的 149 个工作列表的文本描述作为我的数据集。
下一步是清理文本描述。我使用了标准的清理技术,比如删除标点符号和大写,然后对单词进行标记化和词干化,以实现语义标准化。最后,我使用矢量器将数据放入数组格式。
一旦数据是可分析的格式,我就执行主题建模,尝试了几种技术,但最终还是采用了 TruncatedSVD。优化因素是我在步骤 4 中建立的分类模型预测工作类型的准确度。我总共想出了 20 个不同的主题。
在主题建模之后,我使用了主题-文档矩阵,并将其输入到分类算法中。为了提高准确性,我最终选择了随机森林分类器。该模型在验证集上返回了约 90%的准确度,显示了在预测每个职位描述的正确职位类型方面的强大能力。
接下来,是时候赋予模型一个功能性的目的了。我用了上面的主题模型来改造一个人的简历,然后用上面的分类模型来预测简历最适合哪些工作。然后,我根据工作类型提取了匹配百分比,给出了一个人最佳工作匹配的更细致的视图——例如,60%的项目经理,40%的产品经理——并为最终用户提供了多种职业发展途径进行调查。
当我向人们展示他们各自工作匹配百分比的结果时,他们问为什么他们适合这些群体。我很难向非技术人群解释模型的基本机制,因此我决定向他们展示一个简化的图表来解释这些工作匹配结果。
首先,我使用主成分分析将主题-文档矩阵简化为二维。然后,我根据缩减后的维度划分出每种工作类型。我还对一个人的简历进行了降维处理,并在图表上画出了一个人的简历与其他工作的对比。在解释新的 PCA 特性时,我发现它们主要面向两种主题类型:市场营销相关的关键词和项目管理相关的关键词。
用户感兴趣的是如何改善他们的简历,以便在他们瞄准的任何工作中获得更好的机会。为了让应用程序更有用,我决定做一个匹配关键词的功能。
在这个功能中,用户从下拉列表中选择他们感兴趣的工作,应用程序会返回他们简历中匹配和缺失的关键词。人们可以看到他们的简历目前所处的位置,以及他们可以在更有针对性的申请中加入哪些词语和经历。
这个特性可能是最容易制作的。我使用了上面相同的主题模型来找出每种工作类型中最重要的单词——比如前 20 个——并使用列表理解来查看哪些单词匹配或错过了。
既然我已经创建了函数和模型,我需要在线部署一个应用程序,以便人们可以使用它。
对于 app 编写,我用的是 Streamlit。这是最简单和最有效的软件包之一。然后我用 Heroku 和 git 把它上传到网上,尽管回想起来,使用 streamlit 新发布的应用程序部署功能要容易得多。
我们做到了!工作推荐人。我为这个项目感到非常自豪,我希望人们会发现它很有用。如果你认为这个应用可以帮助某人,就发给他们吧!如果你有任何批评,欢迎在下面评论或者给我发信息。感谢阅读。
原文:https://towardsdatascience.com/building-a-k-nn-similarity-search-engine-using-amazon-elasticsearch-and-sagemaker-98df18d883bd?source=collection_archive---------12-----------------------
NeONBRAND 在 Unsplash 拍摄的照片
亚马逊 Elasticsearch 服务最近增加了对 k 近邻搜索的支持。它使您能够像运行任何常规的 Elasticsearch 查询一样轻松地在数千个维度上运行高规模和低延迟的 k-NN 搜索。
k-NN 相似性搜索由 Elasticsearch 开放发行版提供支持,这是一个 Apache 2.0 许可的 Elasticsearch 发行版。
在这篇文章中,我将展示如何使用 Amazon Sagemaker、Amazon Elasticsearch、Amazon Elastic File System (EFS)和 Amazon ECS 构建一个可扩展的相似性问题搜索 api。
- 在 VPC 部署并运行一个 Sagemaker 笔记本实例。
- 将 EFS 装载到笔记本实例。
- 下载 Quora 问题对数据集,然后使用 DistilBERT 模型将数据集中的变长问题映射到定长向量。
- 创建下游任务以减少嵌入维数,并将句子嵌入器保存到 EFS。
- 将问题文本转换为向量,并将所有向量索引到 Elasticsearch。
- 将容器化的 Flask rest api 部署到 ECS。
下图显示了上述步骤的架构:
首先,让我们创建一个连接到 Elasticsearch 的 Sagemaker 笔记本实例,并确保它们在同一个 VPC 中。
要在 Sagemaker 控制台中配置 VPC 选项,请在创建笔记本实例页面的网络部分的中,设置 VPC 网络配置详细信息,如 VPC 子网 id 和安全组 id:
我们将在 SageMaker 笔记本中完成所有必要的句子转换步骤(代码在 处找到 )。
现在,将 EFS 安装到型号目录,关于 EFS 的更多详情,请查看 AWS 官方文件。
注:
- 是 EFS 的 DNS 名称。
- EFS 山目标和萨格马克在同一个 VPC。
要运行最近邻搜索,我们必须获得句子和标记嵌入。我们可以使用句子变形器,这是一个用 PyTorch 使用 BERT/RoBERTa/distil BERT/ALBERT/XLNet 的句子嵌入。它让我们只用几行代码就能把句子映射成固定长度的表示。
我们将使用轻量级 DistilBERT 模型到生成句子嵌入在这个例子中,请注意 DistilBERT 的隐藏单元数量是 768。这个维度对于 Elasticsearch index 来说似乎太大了,我们可以通过在合并后添加一个密集层来将维度减少到 256:
接下来,将句子嵌入器保存到 EFS 安装的目录中:
我们需要确保数据集已经下载,本例中的数据集是。
接下来,将每个问题的全文提取到 dataframe 中:
首先,创建一个 kNN 索引,
然后将问题向量转换并索引到 Elasticsearch。
弹性搜索中的问题具有以下结构:
我们将问题嵌入到固定长度的向量中,并将所有向量编入索引以进行弹性搜索。让我们创建一个连接到 Elasticsearch 的 rest api 并进行测试!
我们将使用示例云形成模板在 VPC 创建 ECS 集群和服务(模板和 bash 脚本在 这里 )。
我们将使用带有 ECS 的 EFS 卷,搜索流程为 1) Flask 应用程序将保存的句子嵌入器加载到 EFS 卷中, 2) 将输入参数句子转换为向量, 3) 然后在 Elasticsearch 中查询 K-最近邻居。
我们现在已经在 ECS 容器中运行了 flask api,让我们使用基本的搜索功能来查找类似的问题,以进行查询:“ 在线赚钱的最佳方式是什么 ?”:
查看结果:
正如你所看到的,结果是相当惊人的,你也可以微调你自己的句子嵌入方法,这样你就可以为 k-NN 搜索得到特定任务的句子嵌入。
太好了!我们有我们需要的!我希望这篇文章对你有用。
完整的脚本可以在我的 GitHub repo 中找到。
原文:https://towardsdatascience.com/building-a-language-translation-chatbot-in-python-step-by-step-40709393a98?source=collection_archive---------14-----------------------
沃洛德梅尔·赫里先科在 Unsplash 上的照片
这里,在本文中,我们将制作一个语言翻译模型,并通过提供一种语言的输入并获得您想要的语言的翻译输出来进行测试。对于使用 Python 的语言翻译模型,我们将使用序列到序列模型架构。
一个序列到序列模型有两个部分。第一部分是编码器,第二部分是解码器。这两个特征是两个不同的神经网络模型组合成一个巨大的神经网络。编码器模型的任务是在应用其他文本清理机制后理解输入序列并创建给定输入文本的较小矢量表示。然后,编码器模型将创建的向量转发到解码器网络,解码器网络生成序列,该序列是表示模型输出的输出向量。
作者照片
我们将使用英语到印地语的翻译数据集,其中包含我们日常生活中使用的大约 3000 个对话。我们可以从任何开源资源中获取数据。你可以在卡格尔买到。
这里,我使用一个简单的文本文件,它是空格分隔的对话。它基于英语到印地语的对话,但是你也可以使用你自己的语言。但是,数据格式应该与文本文件相同,这将有助于您更好地遵循我的代码,不做任何更改。否则你可能需要根据你的数据格式做一些小的改变。
作者照片
我们需要将我们的数据分成一些部分,并使用这些部分来训练出深度学习模型,以便我们的机器不会耗尽内存。
我们需要设置向量的大小。向量大小是我们需要定义的输出数组的大小,这样所有的输出数组都可以有相同的大小。
如前所述,需要对编码器和解码器的数据进行处理,以获得更好的结果。这里,在我们的语言翻译中,我们将使用一些文本清理方法,如:
- 移除所有停用字词
- 单词大小写的变化
- 删除所有数字数据
- 删除重复的单词
我们将使用 word2vec 模型将文本数据转换成定义大小的向量。
Word2Vec 是一种把单词变成数字的技术。我们的机器学习或深度学习模型接受数字形式的输入。
鸣谢:维基百科
我们有两种著名的单词嵌入技术:
- CBOW:
- 跳跃图
作者照片
我们可以使用任何预先训练好的 word2vec 模型。这里,我们将利用手套模型。 GloVe 模型在单词类比任务中结合了 word2vec skip-gram 模型的优点。这个手套模型可以在谷歌上找到。它有一个. txt 格式,我们可以使用下面的代码导入。
手套嵌入以小尺寸嵌入而闻名,足以满足我们的日常聊天。
初始化单词嵌入后,我们需要使用嵌入来标记数据。嵌入将每个单词转换成定义大小的数字向量。我们的机器学习或深度学习模型对数字数据起作用,因为有必要通过将每个单词定义为特定的向量来将任何文本数据转换为数字数据,以便我们稍后可以识别它们。
最后,我们需要使用我们定义的数据处理步骤来清理我们的数据,并使用 tokenized_data.py 将它们转换为令牌。这里,我们将把一个问答集作为输入。我们将应用文本清理步骤,最后,我们将通过我们预先训练的 word2vec 模型,为每个单词分配一个向量。然后,取单词向量的平均值来构成句子向量。
斯科特·格雷厄姆在 Unsplash 上拍照
这里,我们还需要定义聊天句子的开始和结束,以便模型可以理解特定句子的结束位置和句子的开始位置,这有助于我们的模型进行推理。
最后,是时候训练我们的模型了。这里,我们将使用清理后的矢量格式数据将其传递给序列对序列模型。我们的模型将在所有对话中使用我们在开始时定义的批量数据进行训练。
Liam Charmer 在 Unsplash 上的照片
现在,是时候使用我们训练好的模型了。但是,在使用它之前,我们需要定义一些函数来帮助我们清理输入数据,将其转换为向量,并将其传递给经过训练的语言翻译模型,并获得输出向量,我们将解码该向量以获得输出的翻译句子。
因此,我们已经在我们创建的大量数据上训练了我们的模型。我们在不同的时代接受训练。现在,为了检查模型性能,我们可以开始给出输入,并观察我们从模型接收到的输出类型。这里,我使用一个循环向我们的模型提出 10 个语言翻译问题。我们的模型接受输入。清理输入,创建一个词向量,最后取词向量的平均值,生成一个句子向量。句子向量进入模型,模型作为输出提供另一个句子向量,我们解码并输出。
运行语言翻译
所以,现在我们有了语言翻译模型,可以将任何英语句子转换成印地语。我们也可以使用任何其他语言,代码也是一样的。
micha Parzuchowski 在 Unsplash 上的照片
模型的准确性取决于数据源和适合您的数据的模型使用类型。您拥有的数据越多,您就越能训练和验证您的模型。
所以,在这里。我们已经用 Python 建立了我们的语言翻译。用自己的数据,自己的语言去尝试。如有任何疑问,欢迎在评论区提问。快乐学习!
原文:https://towardsdatascience.com/building-a-linear-regression-model-for-predicting-the-price-of-a-used-car-now-with-logs-54a478438d1?source=collection_archive---------10-----------------------
约翰·皮门塔尔在 Unsplash 上拍摄的照片
欢迎大家回到另一个激动人心的环节,建立一个线性回归模型来给你的二手车定价!我知道你看到这个结局有多激动。对于那些希望跳到实际工作模型的人,我已经把它上传到 Heroku 这里。
我们叙叙旧吧。在我们这次旅程的第一篇文章中,我们从 Cars.com 收集了数据,稍微清理了一下,并对新清理的数据运行了一些 EDA。我们了解到一些汽车具有绝对可怕的零售价值,我们推测了零售市场中某些品牌的代表性。与此同时,我了解到一些有趣的事实:奔驰在转售市场上非常突出,因为奔驰车主倾向于租赁,因为他们希望每 3 年买一辆新车。日产代表了转售市场的很大一部分,因为日产将其年产量的 30%送给租车公司,而大多数其他汽车公司最多只给 10%。这意味着,如果这个有趣的事实是正确的,如果你要买一辆二手尼桑,那么你很有可能会买一辆在以前的历史中作为租赁的汽车。你可以在这里通读第一部分。
我们的第二个博客致力于做一些探索性的关联,我们设法发现了一些有趣的关联。高城 _mpg 和高速公路 _mpg 与价格负相关,导致我推测 2019 年的人不太在乎节省油钱。这可能是由于与 2018 年相比,当年的平均燃料价格较低。我们还使用线性回归查看了一些初始运行,发现了一些有希望的 R 数,并取消了奢侈品作为一个新特征,以帮助平滑我们的模型。你可以在这里阅读所有这些。
我认为在这一点上,我们可以开始进入标准的线性回归工具箱。第一个也是最明显的工具是获取一个或多个变量的自然日志。自然对数的目的是减少偏斜数据的可变性。也就是说,如果您的数据到处都是,希望对其应用一个数学函数(如自然对数)将减少其可变性,从而使人们更容易确定模式。然而,你必须记住,一旦你创建了你的模型,你的自然日志,实际上所有的数据转换,必须被逆转,这样你才能产生真实的结果。
所以我们要做的第一件事是取目标变量价格的自然对数。让我们看看我们的模型现在是什么样子!
现在好了!那是一个好看的 R,不是吗?记录我们的价格,我们已经达到了最高的 R 值 0.752。让我们看看我们的剩余部分,好吗?
哦,伙计,我喜欢这个,现在它变得很有意义了。我几乎可以通过它画一条线,并考虑能够预测我可怜的二手车的价格!
为了让事情变得更有趣一点,我和我的伙伴决定尝试通过玩这些特性来微调我们的模型。我们为低里程的汽车创建了一个新功能,并将其设置为小于 7500 英里,以查看它是否会影响我们的模型。我们还喜欢我们创造的豪华功能,因为豪华在二手车定价中发挥了如此巨大的作用,所以为了简单起见,我们将它用于所有品牌,并重新运行我们的模型:
我们仍然有很大的 R 值,但低里程的 P 值是 0.844!这是一个可怕的 P 值。基本上,它告诉我们的是,增加低里程数在统计学上是无关紧要的!这意味着我们可以扔掉它,让我们看看没有它我们会得到什么,或者在功能创建方面进行实验,相同的价格日志,不低的里程数:
相同的 R 和我们的 P 值已经平静了很多。所以我们要用那个。我们的残值怎么办?
看起来相当不错!最终测试,让我们运行一些预测,看看它是如何摇出来的!
左:价格预测,右:残差
好吧,该死,我喜欢它的样子。它并不完美,没有一个模型会完全完美,但我认为我们已经创建了一个逻辑回归模型,它可以很好地估计我们假设的二手车的价格。
所以我运行了一个模型,它符合。我们已经经历了许多线性回归,我已经向你们展示了对统计学家、计算机科学家和数据科学家有意义的统计数据。如果你是数学新手,或者你只是对汽车感兴趣,我该如何让你更容易理解呢?所有这些只是为了推导系数,你可以在下面的 OLS 图表中看到。
看到这些系数告诉我们多少调整我们的预测价格的轨迹。所以比如我们看 city_mpg,系数是. 0134。也就是说,每 0134 city _ mpg 上涨,我们的价格就增加 1 美元。整个模型试图根据所有这些竞争因素重新定价。事实上,所有的线性回归都是为了创建一个数学公式,通过一组代表汽车价格的点来画一条线。这条线试图足够完美地拟合,使得它覆盖或位于路径上合理距离内的所有这些点。
那看起来像什么?因为所有的线性回归只是试图建立一个公式,我们有从建立模型中得到的系数,我们所要做的就是考虑每个系数,然后建立公式。看起来像这样:
使用这个公式,我们只需将我们知道的汽车价值乘以我们通过线性回归得出的系数,一旦我们完成公式,我们就有了预测的二手车价格!这太简单了,你可以用纸和笔来做!
在 Streamlit 前端应用程序这里上尽情体验吧!
我们已经实现了我们设定的目标。我们有一个相当准确的线性回归模型,它将考虑汽车的特征,并以相当的准确度预测价格。在我看来,更有趣的是我们从 EDA 中获得的有趣见解。我的意思是,我很高兴我的合作伙伴和我能够创造一个模型,帮助人们正确地为他们的汽车定价,帮助人们对我来说是世界上最重要的事情之一。但是,举例来说,发现开奔驰的人大多是租车,这让我了解了很多开奔驰的人是什么样的。正是这些小事影响了我们看待周围世界的方式,这让我很高兴,我决定从事数据科学方面的职业。
原文:https://towardsdatascience.com/building-a-lstm-by-hand-on-pytorch-59c02a4ec091?source=collection_archive---------3-----------------------
LSTM 细胞图解—来源:https://upload . wikimedia . org/Wikipedia/commons/thumb/3/3b/The _ LSTM _ cell . png/300 px-The _ LSTM _ cell . png—2020 年 5 月 24 日获取
所有提到的代码都在下面的列表中或者在我们的回购中。
LSTM 细胞是深度学习的递归神经网络研究领域中最有趣的架构之一:它不仅使模型能够从长序列中学习,而且还为长期和短期记忆创建了一个数字抽象,能够在需要时用一个代替另一个。
在这篇文章中,我们不仅要浏览 LSTM 单元的架构,还要在 PyTorch 上手工实现它。
最后但同样重要的是,我们将展示如何对我们的实现做一些小的调整,以实现一些确实出现在 LSTM 研究领域的新想法,如窥视孔连接。
LSTM 有翼被称为门控结构:一些数学运算的组合,使信息从计算图上的那个点流动或被保留。正因为如此,它能够在长期记忆和短期记忆之间“做出决定”,并对序列数据输出可靠的预测:
LSTM 单元格中的预测序列。注意,它不仅流过预测 h_t,还流过 c_t,它是长期记忆的代表。来源:https://medium . com/turing-talks/turing-talks-27-modelos-de-predi % C3 % A7 % C3 % A3o-lstm-df 85d 87 ad 210。访问时间:2020 年 5 月 24 日
我们将一部分一部分地讲述:
遗忘门是输入信息和候选信息一起操作的门,作为长期记忆。请注意,在输入、隐藏状态和偏置的第一个线性组合上,应用了一个 sigmoid 函数:
忘记 LSTM 牢房的门。来源:https://medium . com/turing-talks/turing-talks-27-modelos-de-predi % C3 % A7 % C3 % A3o-lstm-df 85d 87 ad 210。访问时间:2020 年 5 月 24 日
这个 sigmoid 将遗忘门的输出从 0“缩放”到 1——通过将其乘以候选值,我们可以将其设置为零,这表示长时间记忆中的“遗忘”,或者设置为一个更大的数字,这表示我们从长时间记忆中记住了“多少”。
输入门是包含在输入和隐藏状态上的信息被组合,然后与候选和部分候选 c’_t 一起操作的地方:
LSTM 池的输入门。来源:https://medium . com/turing-talks/turing-talks-27-modelos-de-predi % C3 % A7 % C3 % A3o-lstm-df 85d 87 ad 210。访问时间:2020 年 5 月 24 日
在这些操作中,决定了有多少新信息将被引入内存以及它将如何改变——这就是为什么我们使用一个双曲正切函数(“从-1 到 1 的标度”)。我们结合来自短时和长时记忆的部分候选项,并将其设置为候选项。
现在我们可以进入输出门了。
之后,我们可以收集 o_t 作为 LSTM 细胞的输出门,然后将其乘以已经通过适当操作更新的候选(长期记忆)的 tanh。网络的输出将是 h_t。
LSTM 电池的输出门。来源:https://medium . com/turing-talks/turing-talks-27-modelos-de-predi % C3 % A7 % C3 % A3o-lstm-df 85d 87 ad 210。访问时间:2020 年 5 月 24 日
最后,我们有:
为了在 PyTorch 上实现它,我们将首先进行适当的导入。
我们现在将通过从继承来创建它的类,然后实例化它的参数和权重初始化,您将在下面看到(注意它的形状由网络的输入大小和输出大小决定):
为了了解每个砝码的形状,让我们看看:
矩阵的输入形状为(batch_size,sequence_length,feature_length)-因此将乘以序列中每个元素的权重矩阵必须具有形状(feature _ length,output_length)。
序列中每个元素的隐藏状态(也称为输出)的形状为(batch_size,output_size),这在序列处理结束时会产生(batch_size,sequence_length,output_size)的输出形状。—因此,与其相乘的 weight_matrix 必须具有与单元格的参数 hidden_sz 相对应的形状(output_size,output_size)。
这里是权重初始化,我们使用的和 PyTorch 默认的一样:
前馈操作接收参数,该参数是具有上述等式的(h_t,c_t)参数的元组,如果不引入,该参数被设置为零。然后,我们对保持(h_t,c_t)的每个序列元素执行 LSTM 方程的前馈,并引入它作为序列的下一个元素的状态。
最后,我们返回预测和最后的状态元组。让我们看看它是如何发生的:
这种 LSTM 在运算方面是正确的,但在计算时间方面不是很优化:我们分别执行 8 次矩阵乘法,这比以向量化的方式执行要慢得多。我们现在将展示如何通过将它减少到 2 个矩阵乘法来实现,这将使它更快。
为了进行这种操作,我们设置两个矩阵 U 和 V,它们的权重包含在 4 次矩阵乘法中。然后,我们对已经通过线性组合+偏置运算的矩阵执行门控运算。
通过矢量化运算,LSTM 单元的方程将为:
所以它的类应该是:
最后但同样重要的是,我们可以展示使用 LSTM 窥视孔连接来调整您的实现有多容易。
LSTM 窥视孔对其前馈操作进行了细微调整,优化后的情况是:
有了 LSTM 的良好实现和优化实现,我们就可以添加窥视孔连接的选项,并做一些小的调整:
这样我们的 LSTM 就完成了。你可能想在我们的回购上看到它,并用我们的 LSTM 文本情感分析笔记本进行测试,我们准备用火炬 LSTM 内置层进行测试和比较。
我们可以得出一个结论,尽管这是一种深度学习的禁忌,但是如果一步一步地完成,并且有干净和良好的编码,实际上很容易将它的操作执行成一个干净、易于使用的。我们也看到了改变和调整它的连接来完成像窥视孔连接这样的操作是多么容易。
## piEsposito/py torch-lstm-手工
一个关于如何制作 LSTM 神经网络的小而简单的教程。PyTorch 上的手工模块。记得执行 bash…
github.com ## 了解 LSTM 网络
2015 年 8 月 27 日发布人类不是每秒钟都从零开始思考。当你读这篇文章时,你…
colah.github.io ## LSTM 神经网
机器学习
medium.com
原文:https://towardsdatascience.com/building-a-machine-learning-pipeline-3bba20c2352b?source=collection_archive---------14-----------------------
马库斯·斯皮斯克在 Unsplash 上的照片
数据科学项目需要迭代进展。例如,我们清理和准备用于建模的数据,将其转换为适当的格式,运行模型,获得结果,改进模型/更改模型,进行特征工程,获得新的结果,将它们与其他结果进行比较,等等。把每一步都做一遍又一遍,不容易,也不聪明。为了解决这个问题,我们可以使用管道来集成机器学习工作流的步骤。
管道对于快速转换和训练数据非常有用。此外,我们可以通过在管道中集成网格搜索来比较不同的模型和调整超参数。在本文中,我将讲述如何在 scikit 中创建管道——学习展示管道的神奇世界。
制作管道的方法有很多,但我将在这篇博客中展示其中一种最简单、最聪明的方法。
要使用 scikit-learn 的管道功能,我们必须导入管道模块。
通过使用(键,值)对的列表,可以构建管道。这里,键是一个字符串,其中包含您要给出的名称,值是 estimator 对象。非常简单的示例代码,显示如何使用;
更多细节,你可以查看 scikit-learn 文档。
“make_pipeline”是一个实用函数,是构造管道的简写。它接受可变数量的估计,并通过自动填充名称来返回管道。
我想在示例中解释管道的用法,因为我认为,当我们看到代码中模块的应用时,更容易理解。在现实生活中,数据集通常由数字列和分类列组成。我们必须用不同的技术改造这些柱子。当我们使用缩放器缩放数字列时,我们应该用编码器对分类列进行编码。第一次进行这种转换很容易,但通常,在数据科学项目中,我们会尝试不同的缩放器和编码器。为了快速简便地实现这一点,我们使用了管道。
在我的一个项目中,我用分类技术预测了坦桑尼亚水井的状况。我对管道使用了不同的缩放器、编码器和分类模型。如果你想看完整的带数据的木星笔记本,以及如何在建模过程中使用管道,可以在我的 Github 上找到这里。项目中的管道示例;
我在这里只展示如何导入管道模块。但是当然,我们需要导入我们计划使用的所有库和模块,比如 pandas、NumPy、RobustScaler、category_encoders、train_test_split 等。
如果您的数据包含一些无意义的要素、空值/错误值,或者需要任何类型的清理过程,您可以在此阶段进行清理。因为数据的质量影响模型的质量。在这篇博客中,我的目的是展示管道过程,所以我跳过这一部分,使用我的数据的清理版本。
在这个例子中,我们可以看到,我们可以添加功能到我们的管道,如预处理器,其中包含缩放器和编码器。针对不同的问题,我们还可以在流水线中增加更多的函数。这有助于以快速简单的方式转换我们的数据。在这个例子中,make_pipeline 函数自动将 scaler、encoder 和我们的模型应用到管道中,我们可以非常轻松地对其进行拟合。
当我们写一个函数,把我们的管道放在这个函数中并返回结果时,改变模型也是非常容易的。对于这个例子,当我们只改变 model_name 来尝试另一个分类模型并运行调用相应函数的单元时,它很容易在管道内得到结果。简而言之,我们不需要为了转换数据而改变数据集。我们可以在管道中进行每一次转换,并保持我们的数据集不变。
我们也可以使用 make_pipeline 来集合数值列的估算器和缩放器;
在这个例子中,我还在我的管道中添加了 imputer。如您所见,当我们构建一个好的管道而不需要手动转换数据时,添加和更改模块是非常容易的。
管道的目的是在设置不同参数时,将几个可以交叉验证的步骤组合在一起。通过收集这些步骤,可以帮助我们轻松地添加新参数或对模型进行更改。此外,它使我们的代码更具可读性和可理解性。通过建立一个可理解的工作流程,它有助于项目的可重复性。通过使用管道,我们不需要在流程开始时转换数据。Pipeline 为我们完成所需的转换,并保留原始数据。
如果您想深入了解 scikit-learn 库文档,这里有一些有用的链接。
## 6.1.管道和复合估计器-sci kit-了解 0.23.2 文档
转换器通常与分类器、回归器或其他估计器结合,以构建复合估计器。的…
scikit-learn.org ## sk learn . pipeline . pipeline-sci kit-learn 0 . 23 . 2 文档
具有最终估计器的变换流水线。依次应用一系列转换和一个最终估计器…
scikit-learn.org
如果您对本文有任何反馈或建议,请随时通过 LinkedIn 与我联系。
原文:https://towardsdatascience.com/building-a-machine-learning-pipeline-part-1-b19f8c8317ae?source=collection_archive---------48-----------------------
照片由 JJ 英在 Unsplash
以下是构建 ML 管道的常用步骤:
- 输入数据
- 探索性数据分析
- 缺失值插补
- 异常值处理
- 特征工程
- 模型结构
- 特征选择
- 模型解释
- 保存模型
- 模型部署*
我用一个相对更大更复杂的数据集来演示这个过程。参考 Kaggle 竞赛— IEEE-CIS 欺诈检测。
导航到数据浏览器,您会看到类似这样的内容:
选择 train_transaction.csv ,它将向您展示数据的大概情况。单击红色箭头突出显示的下载图标获取数据。
除了通常的库导入语句,您还需要检查另外两个库——
这是构建机器学习管道系列的第一篇文章。在本文中,我们将重点关注关于在 Jupyter notebook 中导入数据和更快执行的优化。
这篇文章中有 3 个关键点需要注意—
- Python zipfile
- 减少数据集的内存使用量
- 保存/加载工作数据集的更快捷方式
下载压缩文件后。使用 python 来解压文件要好得多。
**提示 1:**se 函数从 python 的 zipfile 库中解压文件。
这将创建一个文件夹并在该文件夹中解压缩 CSV 文件。
我们将使用 pandas 方法将数据集加载到 Jupyter 笔记本中。
该数据约为 1.5 GB,包含 50 多万行。
***技巧二:*我们将使用 fast_ml 中的一个函数来减少这种内存占用。
这一步花了将近 5 分钟,但是它将内存大小减少了将近 70%,这是一个相当显著的减少
为了进一步分析,我们将创建一个包含 20 万条记录的样本数据集,这样我们的数据处理步骤就不会花费很长时间。
现在,我们将把它保存在本地驱动器中— CSV 格式
***技巧三:*使用羽化格式代替 csv
一旦从这两个来源加载数据,您将会看到显著的性能改进。
加载保存的样本数据— CSV 格式
加载保存的样本数据—羽毛格式
I .加载 CSV 文件所花费的时间几乎是加载羽毛格式数据所花费时间的 10 倍。
二。加载的数据集的大小以羽化格式保留,而在 CSV 格式中,数据集再次消耗大量内存,我们将不得不再次运行 reduce_memory_usage 函数。
- 如果你喜欢这个,在 medium 上跟随我了解更多。
- 你们的掌声对写更多、写得更好是一个巨大的鼓励和帮助。
- 有兴趣合作吗?我们在 Linkedin 上连线吧。
- 请随意写下您的想法/建议/反馈。
- 我们将使用我们创建的新样本数据集进行进一步分析。
- 我们将在下一篇文章中讨论探索性数据分析。
- Github 链接
原文:https://towardsdatascience.com/building-a-mental-model-for-backpropagation-987ac74d1821?source=collection_archive---------27-----------------------
安德烈·韦莱在 Unsplash 上拍摄的照片
作为深度学习的跳动的心脏,任何深度学习实践者都需要对反向传播有坚实的理解。虽然互联网上已经有很多解释反向传播的好资源,但大多数都是从非常不同的角度来解释的,并且每个都适合特定类型的受众。在这篇文章中,我将把直觉、动画图和代码结合在一起,供深度学习的初学者和中级水平的学生更容易使用。对任何算法的理解的一个好的评估是你是否能从头开始自己编码。看完这篇文章后,你应该知道如何用 Python 实现你自己版本的反向传播。
从数学上讲,反向传播是通过应用链式法则来计算函数分量梯度的过程。在神经网络的情况下,感兴趣的函数是损失函数。我喜欢 Andrej Karpathy 在 CS231n 中的解释:把计算图看成是带有逻辑门的实值电路。门是函数中的运算,例如加、乘、取幂、矩阵乘法等。
来源:https://cs231n.github.io/optimization-2/
这是一个很好的心理模型,因为它意味着反向传播是一个局部过程。电路中的每个门都可以计算其输出和局部梯度,而无需了解全局。
在反向传递(反向传播)期间,门应用链规则,即,在电路的最终输出上取其输出的梯度,并将其乘以关于其所有输入的局部梯度。可以使用递归方法从电路的输出返回到所有输入来实现反向传递。
直观上,反向传播及其相关权重更新的最终效果是,电路**“想要】输出一个更接近我们所拥有的任何目标值的值。以上图中加法门(-4)的梯度为例,意思是将 q 改变+1ε会导致 f** 中-4ε的变化。如果我们想要更高的 f 值,我们可以把 q 值降低。这就是梯度的本质。人们有时称之为“敏感”。另一个很好的类比是修正力。梯度的符号表示校正的方向,大小表示强度。
可视化反向投影的最好方法之一是绘制函数的计算图。让我们看看下面这个奇怪的函数,演示如何绘制它的计算图,然后手动反向投影。( σ()是 sigmoid 函数)
为了计算其梯度,我们可以将其分解为加法、s 形、正方形门,如下面的动画步骤所示:
具体来说,该流程包括 3 个高级步骤
- 从操作(门)构建计算图
- 在每个操作中运行正向传递
- 基于(1)正向过程中计算的值和(2)每个门的反向函数运行反向过程,以计算其局部梯度
您可以跟随并手动计算这些值。我将在最后一节展示如何实现它,但是现在让我们来看一个技巧,它将帮助我们简化这个过程。
任何一种可微函数都可以充当一个门,我们可以在方便的时候将多个门组合成一个门。
因为我们不应该明确地解析求解梯度,所以这些函数分量的选择就成了一个需要考虑的问题。以 sigmoid 函数为例:
我们可以将其分解为加法、乘法、求反、取幂和倒数门,如下图所示:
资料来源:https://cs231n.github.io/optimization-2/
一个简单的乙状结肠已经有这么多的运算和梯度,这似乎是不必要的复杂。我们可以做的另一件事就是将一个 sigmoid gate 与计算其梯度的函数一起应用于红框的输出。乙状结肠的坡度非常简单:
这样我们避免了许多不必要的计算。它节省了我们的时间、空间和能量,使代码更加模块化和易于阅读,并避免了数值问题。
乙状结肠门的代码可能类似于:
它既有向前传递的输出,又有计算向后传递的局部梯度的功能,只需几行代码。在下一节中,我将把它放到更大的图片中,并展示如何用这样的组件编写一个迷你的亲笔签名的库。
要让计算机使用链规则计算任何用有向无环图(DAG)表示的函数的梯度,我们需要为前面提到的 3 个高级步骤编写代码。这样的程序通常被称为自动分化或自动签名。正如您接下来将看到的,我们可以将代码组织成一个定义数据和操作的类,这样它不仅可以支持动态构建动态计算图,还可以递归地反向传播。
卡帕西显微图中的代码
一个张量对象有、、一个方法、一组张量节点和一个操作。当我们执行一个表达式时,它会动态构建计算图,因为我们已经用定制的 dunder 方法覆盖了 Python 操作符,如、和。当前张量的、和由其父张量定义,即产生它的张量。例如中的有中定义的,还有、。这样我们就可以定义任何我们想要的操作,并让 Python 来构造图形。
这里说的是神经网络,所以我们关心的表达式是损失函数。以 MSE 损失为例(为简单起见,使用 1 个标量数据点),其中、和为张量对象,分别初始化为 3、-4 和 2。然后,图形会自动构建为:
注意减法其实就是否定和加法。我命名中间节点只是为了便于说明。有了图形,我们就可以实现反向投影了!
卡帕西显微图中的代码
应该从当前张量节点开始逐个计算梯度,并移动到其祖先。遍历的顺序需要进行拓扑排序,以确保每一步都计算了依赖关系。实现这种拓扑排序的一个简单方法是深度优先搜索。这里有一个动画来展示如何在 MSELoss 示例中执行它。
这是图遍历 101:一个普通的老 DFS。如果你有一个大型复杂的神经网络,你只需用你的大图替换左上角的,并且假设所有的操作和它们的都在类中定义,那么 DFS 将会去那里计算梯度。这里我们需要的一些显而易见的操作包括、、矩阵乘法、转置等。要使用渐变来更新权重,请执行以下操作:
就这样,几行代码中的亲笔签名算法。它是任何深度学习框架的支柱。现在,困难的部分已经过去了,要完成您的 mini 深度学习框架的实现,您只需要实现一个模型接口,其中包含层类型、损失函数和一些优化器的集合。
这篇文章的灵感很大程度上来源于 Andrej Karpathy 令人敬畏的 CS231n 讲座和漂亮的文字微图:最小的亲笔签名引擎。如果你想看看一个 DIY 深度学习框架的不同和更扩展的版本,它非常类似于 PyTorch,请查看 Andrew Trask 在 Grokking Deep Learning 中实现的那个。如果你更喜欢直接阅读 PyTorch 的亲笔签名,埃利奥特·韦特在 Youtube 上有一个很棒的视频,它将为你节省大量钻研源代码的时间。坚持学习!
- CS231n 讲座
- 微克:最小的亲笔签名引擎
看我在 上的其他帖子 ,或者关注我在 上的推特 。
原文:https://towardsdatascience.com/building-a-modern-analytics-stack-966b0525dbc5?source=collection_archive---------23-----------------------
美国宇航局在 Unsplash 拍摄的照片
各行各业各种规模的公司都很快认识到,为了保持竞争力,他们必须接受一种文化,在所有业务中,决策都以数据为依据,并快速做出。这可以是在管理层,BI 仪表板用于监控公司的整体健康和绩效,分析师通过查询多个来源的数据来寻找见解,或者工程师在公司数据的基础上构建机器学习工具和智能自动化应用程序。
随着数据量和使用案例的增加,组织、集成和管理数据访问变得更加困难,在较小规模下有效的工具和流程不再有效。试图处理数据并将其嵌入整个组织的公司需要一个强大的基础架构,能够快速、轻松地提供数据。随着数据规模的增长,他们需要考虑指导数据管理的框架。这项工作的一个重要部分是建立分析堆栈。
分析堆栈是作为集成系统的一部分执行特定流程的一组工具。通过组合执行简单过程的工具,如存储来自多个来源的数据、合并和转换数据以及可视化数据,我们能够组装更复杂的行为。通过使用具有特定功能的工具,您可以获得可定制性和可互换性的好处。这意味着,例如,当您的数据存储需求急剧增加,而您当前的存储解决方案变得太贵或太慢时,您可以轻松替换堆栈中的该层,或者添加满足您需求的新层,而不必替换整个堆栈。
如今,大多数公司都在一系列应用程序上运营,如用于 CRM 的 Salesforce、用于在线销售的 Shopify、用于 ERP 的 Workday、用于收集、组织和可视化数据的 Microsoft Excel 以及用于存储和共享数据的 Sharepoint。这些工具对于业务任务来说非常棒,但是对于分析来说却变得非常有限。您很快意识到 Excel 电子表格对于存储或操作大量数据来说效率不高,或者对 Sharepoint 的不同访问级别会导致孤立的数据,而其他团队无法利用这些数据来构建他们的用例。至少,你会发现有些人使用来自 Salesforce 和 Hubspot 等工具的自动化报告和仪表盘。这样做的最大问题是,您无法跨应用程序合并数据来构建自动化工具或进行高级分析。此外,这些服务提供了汇总和聚合级别的数据,如果您想深入了解细节或比较不同时间的数据,这是没有帮助的。
那些对构建可靠的分析基础设施不够重视的公司意识到,数据分析师和科学家在 ETL 等基本数据处理和管理任务上分配的时间不均衡。软件公司 Jetbrains 的一项调查显示,分析团队中高达 75%的成员最终从事这些任务,而不是商业智能、数据科学或机器学习,这些才是分析的真正附加值。
那些已经采取下一步措施,通过内部部署数据仓库、数据集成工具和 BI 来构建分析基础架构的公司面临着自己的挑战。硬件服务器需要大量的 IT 参与,难以维护,并且需要很长时间来证明其价值。此外,高昂的设置成本使得随着需求的变化很难互换解决方案,并且随着时间的推移,对于许多公司来说,这是一个负担不起和难以扩展的障碍。
AWS 和 Azure 等云计算平台的兴起及其基于使用的数据仓库、集成和高级分析产品的成本,减轻了设置的重大负担,并大大缩短了分析的价值实现时间。下一阶段的 SaaS 和云分析公司(如 Snowflake、Stitch 和 Looker)进一步推动了这一趋势,这些公司提供自助服务技术,这些技术非常容易设置和运行,并且彼此无缝集成。
为了建立一个功能性的数据操作,一个组织通常需要将几个服务组合成一个数据栈。从根本上说,有效的数据堆栈将使执行三种基本操作成为可能,包括从许多来源收集数据并将其吸收到存储系统中,为各种用例清理和转换数据,以及最终将转换后的数据用于可视化或机器学习等分析的增值部分。这三个过程都是数据管道的一部分。您在每个流程中使用的工具构成了分析堆栈。根据公司的需求,数据管道的架构可能会有所不同,但它们在上述主要流程中都有共同点,如下图所示。
分析数据管道
我们将详细介绍每个流程的功能,并列出一些可用的流行云平台。
任何分析项目的最初挑战都是使来自多个孤立数据源的数据可用。这些可能是您的 SaaS 工具、企业应用程序、应用程序数据库、来自您的 IOT 系统的遥测数据,也可能是许多其他来源。有许多云优先工具越来越受欢迎,用于将数据从源移动到目标,如 Stitch 和 Fivetran 。这些工具可以从 100 多个来源移动数据,包括公司使用的最流行的应用程序和数据库。但是一些公司可能需要自己的方法或途径来收集数据,也有很多编程工具来帮助这一点。例如, Singer 是一个开源工具,可用于编程连接器,在任何自定义源和目标(如 web APIs 和文件)之间发送数据。
实时流
分析中的一些主要用例,如检测信用卡欺诈,依赖于实时数据流。不断生成新数据的应用程序可以使用流式 API 将数据推送到接收方,也可以由接收方应用程序从队列中或通过对 API 的轮询请求来提取数据。像 Stitch 这样的工具可以用来在很短的时间间隔内轮询数据,以模拟实时流,但像 Apache Kafka 和 Amazon Kinesis 这样的流处理服务是专门为处理实时数据馈送而设计的。你可以在这里阅读一篇关于如何使用亚马逊 Kinesis 的文章。
ETL
一旦建立了数据接收流程,您将需要决定是以原始形式存储数据,还是将数据转换为更有利于分析的形式。这将取决于原始数据的有用程度。在将数据加载到数据存储器之前,您可能希望清理并统一不完整、混乱或不相关的数据。此外,数据的格式可能与您的存储解决方案不兼容;例如,您可能希望从 API 中展平嵌套的 JSON 对象,以便可以将它们存储在数据库中。
提取、转换、加载
在存储数据之前对其进行转换的过程称为 ETL(提取、转换、加载)。有很多云 ETL 工具,其中 Talend 和 Matillion 是著名的例子。
ELT
另一方面,您可以选择在将原始数据加载到存储提供程序后立即对其进行转换。这就是所谓的 ELT(提取、加载、转换)。这种方法允许来自许多来源的原始数据的历史可用于更广泛的分析用例。 DBT 是一款开源工具,因为它将工程最佳实践与分析相结合,所以在英语教学中非常流行。
提取、加载、转换
许多现代分析架构更喜欢 ELT 方法,因为它增加了管道中的灵活性。有了像雪花数据仓库这样允许存储和查询半结构化数据的存储解决方案,这变得更加容易。但是,这不是选择 ETL 还是 ELT 的问题,因为根据公司的需要,两种方法的组合可能是正确的。
数据分析堆栈的下一部分是数据存储平台。最流行的策略是将来自所有数据源的数据放入一个公共存储库中,在那里可以针对各种用例对数据进行转换和组合。最流行的数据存储解决方案是数据仓库——它们将原始数据和转换后的数据存储在数据库中,便于公司内的不同团队访问。传统上,数据集市一直是将特定领域(如人力资源和财务)的数据管理到他们自己的数据库和服务器中的流行解决方案,但代价是被孤立。云数据仓库的革命和像雪花、 AWS 红移和谷歌 BigQuery 这样的平台正在彻底打破这种模式。例如,雪花越来越受欢迎,因为它的架构将存储和计算资源分开。随着存储成本的大幅降低,雪花的分离架构使公司能够廉价地存储来自所有来源的大量原始数据,并将计算资源仅用于转换分析用例的数据。阅读这篇关于如何建立雪花架构的文章。
另一种方法是将目前没有任何特定目的的原始数据存储到数据湖中。数据湖不像数据仓库那样是基于关系 SQL 的平台,在概念上与数据集市完全相反。数据湖是一般数据的广泛存储,它允许任何类型的数据,无论是结构化的还是非结构化的,都可以在没有任何组织的情况下存储。虽然它们很难导航,但它们有利于轻松启动新的分析用例和数据科学探索。AWS S3 和 Azure Blobs 就是数据湖的一些例子。然而,像雪花这样的平台也结合了数据湖的优势,使用 S3 这样的云存储作为他们的存储解决方案,使雪花的存储成本一样低。此外,凭借其存储半结构化数据和自动优化数据以进行存储和查询的能力以及其他功能,像雪花这样的解决方案可以替代许多分析堆栈中的数据湖。
在分析堆栈中,分析位于层次结构的顶部。对于每一个分析用例,团队都希望制定出相关的目标指标和 KPI。然后,他们可以选择在数据仓库中建模和存储数据以服务于用例,或者在数据进入他们选择的分析工具后建模数据。选择使用哪种分析工具取决于正在执行哪种活动以及用户是谁。这些用户可能是业务团队、产品和工程团队或数据团队。
商业智能是大多数公司最常见的分析用例。从根本上说,BI 为用户提供了一种分析业务运营的历史、当前和预测视图的简单方法。要选择 BI 工具,我们必须首先缩小用例范围。公司现在认识到,为业务线用户和高管提供 BI 仪表板有很大的好处。控制面板让终端用户能够自助获取能够影响利润的见解。它们还提供具有数据过滤器等功能的即席分析,以及分组或隔离数据以发现有趣趋势的能力。像 Chartio 和 Microsoft PowerBI 这样 BI 平台的例子也非常容易为业务团队部署,而不需要持续的 IT 参与。建立后,业务用户可以轻松地将 BI 平台连接到数据仓库中满足其需求的模型数据。此外,许多公司也在寻找将分析工具集成到现有应用程序和整体业务流程中的方法。嵌入式分析工具通过允许开发人员将可视化嵌入到应用程序中来提供这些功能。Sisense 是一个平台的例子,它帮助开发者使用 API 将定制分析构建到任何类型的应用中。
高级分析的部署频率仍然较低,但它们可能是一些让公司脱颖而出的最高价值活动。数据科学是将更复杂的统计技术和建模应用于大量结构化和非结构化数据以生成预测性或规范性见解的活动之一。数据科学涉及大量探索性工作,因此数据科学家通常使用查询工具进行初始数据探索,然后构建连接到数据仓库的自定义程序来提取数据,或者与 RapidMiner 等平台集成,为挖掘和预测分析工作提供集成环境。机器学习是数据科学工作的延伸,其中建模数据被输入到 AWS SageMaker 或数据机器人等服务中,以训练、评估和部署模型。然后,这些模型被集成到公司的现有产品中,以实现面向客户的功能,如推荐引擎,与现有的分析工具一起用于增强分析,如流失预测,或者作为智能自动化应用的一部分,如服务器负载的预测性维护。由于高级分析和机器学习下的用例范围巨大,很难缩小几个工具的范围。与 BI 不同,高级分析可以有自己非常复杂的架构,但分析堆栈的数据处理和数据仓库组件保持不变。
从依赖孤岛式应用程序进行基本分析转变为构建自己的堆栈可能是一项重大任务。我们已经为您应该如何考虑堆栈中的组件提供了指南。如果您的公司刚刚开始这一旅程,那么知道没有放之四海而皆准的工具是很重要的。此外,随着数据的增长,适用于您当前使用情形的工具可能需要改变。因此,您的分析堆栈将不断发展。无论您处于哪个阶段,都要仔细考虑一下哪些工具能很好地满足您目前的需求,但在未来是可扩展的或可互换的。
您的分析堆栈需要帮助吗?通过 LinkedIn 联系。
原文:https://towardsdatascience.com/building-a-modern-batch-data-warehouse-without-updates-7819bfa3c1ee?source=collection_archive---------4-----------------------
在 Unsplash 上由 Helloquence 拍摄的照片
在这篇文章中,我将描述如何设计维度、事实以及在不执行可变变更的情况下为其提供信息的流程。
出于本文的目的,我将假设数据在一个便宜的云存储上,由一个直接操作文件的计算引擎处理,并写入不可变的块中。
了解大数据堆栈中的事务性、更新和锁定选项。Databricks 和 Snowflake 围绕提供这些服务(以及更多服务)建立了非常成功的企业。Databricks 甚至开源了“ Delta Lake ”,为 Apache Spark 带来了其中的一些功能。
然而,更新是大数据堆栈中复杂的操作。我相信保持我们的大部分数据处理不变是更容易维护和推理的。
更新可能会给数据管道带来不必要的灵活性。我见过一个团队只通过(非常低效的)更新来扩展另一个团队拥有的表,而不是协作和扩展公共脚本。不变性迫使数据管道具有某种结构。
我将从高层次描述星型模式概念开始,并解释为什么它们今天仍然相关。如果你熟悉这些概念,我邀请你跳到**“管理维度”**。
星型模式是一种关系建模技术,它将与业务流程相关的度量或事件(事实)从其上下文(维度)中分离出来。
与关系数据库模式(应用程序数据库)相比,它更加非规范化,并且被设计为对分析查询( OLAP 工作负载)高效。
举例:
在电子商务网站中,业务流程的一个例子是网站上的交易。
在这种情况下,一些示例度量是:交易期间支付的金额和购买的产品数量。
上下文包括:进行交易的用户、交易日期和购买的产品。
简化星形模式提取
实际上,每个交易可能包含不同的产品:这是一个简化的模型
星型模式的名字来源于物理模型与星型的相似性,星型的中心有一个事实表,周围的维度表代表星型的点
https://en.wikipedia.org/wiki/Star_schema
维度可以进一步规范化:例如,产品的“品牌”可以保存在一个单独的表中,该表具有与“产品”的外键关系,从而创建一个从维度到维度的关系。
星型模式维度的进一步规范化导致了“雪花模式”,从历史上看,其主要目标是减少冗余数据量(节省存储)。
缺点是雪花模式通过更多的连接引入了更多的复杂性。随着存储变得不那么受关注,对于大多数情况来说,“雪花模式”方法是不合适的。
星型模式是在存储和计算昂贵的时代创建的。因为存储昂贵且有限,减少数据冗余是数据仓库团队的主要关注点。
这也是支持数据仓库查询的有效方式,因为通过维度表的连接和过滤器,可以跳过事实表上的大量数据。可预测的访问模式允许简单的优化,比如在事实表的外键上创建索引。
简洁明了—所有外键列都应该有一个非聚集的非唯一索引。
https://www . data vail . com/blog/how-to-index-a-fact-table-a-best-practice/
如今,存储很便宜,并且根据需要配置计算能力(相对而言)很容易。我们可以衡量设计和实现这些模型的工程成本与节省的硬件成本,并问自己— 这样做还值得吗?
照片由阿齐兹·阿查基在 Unsplash 上拍摄
公司从越来越多的来源收集越来越多的数据,需要对产生的数据集进行协调以进行分析。
例如,有线电视网络可能有非常不同的系统来托管有关其电视订户和其新推出的流媒体服务的订户的信息。同样,他们的“客户支持”分析必须整合来自 Twitter、第三方呼叫中心和支持电子邮件的数据。
标准化工作的目标是汇集“订户”、“客户反馈”和其他逻辑实体的不同定义,消除否则将由异构源系统引入的分析复杂性。
Ralph Kimball 编写的数据仓库工具包(1996)和 Kimball 集团网站定义了业内广泛理解的概念(如星型模式)。
新员工可以快速掌握数据仓库结构,而不需要熟悉组织的具体情况。
数据工程师、数据科学家和分析师有共同的术语(事实、维度、粒度),有助于协作。
新添加的事实可以重用现有的维度。
通过向事实表添加更多的外键,可以向事实添加新的维度。
因此,可以集成新的数据集,而无需对模式进行重大更改。
星型模式可以完全通过在 Map-Reduce 框架中容易并行化的插入和计算来填充(我们将在下一节中看到“如何进行”)。
查询性能调优:
虽然外键索引通常不是一个选项,因为它们在许多现代数据仓库框架中不受支持,但是我们有其他选项来提高性能。
维度通常很小,有时可以放在内存中,支持地图端连接优化(参见 Spark 的 BroadcastJoin )。
我们可以在维度表上使用桶。
Spark 支持星型模式检测、对连接进行重新排序并有效地跳过数据。
1996 年的许多实践今天仍然适用,但是一些方法需要重新定义。
Lyft等公司已经成功地更新了这些数据仓库实践,以适应新的技术环境。 Maxime Beauchemin 就这个主题做了一个很棒的演讲,这篇文章的“管理维度”部分很大程度上受到了它的启发。
来自同一个演讲:
先学习规则,再打破规则
照片由 乔治·贝克尔 发自 派克斯
数据仓库书籍警告不要重复使用“自然键”(来自生产系统的唯一 id)作为事实表中的外键。
如果表被部分清空(出于性能原因),生产系统中的自然键可能会重用 id。因为数据仓库保存历史数据,IDs 的重用会产生难以解决的冲突。
创建“代理键”的最佳实践是使用由数据处理系统顺序生成的整数 id,并与生产系统的自然键分离。
整数可以节省存储空间,创建更小更高效的 T4 索引。
现代数据仓库中不使用索引。Hive 3.0 移除了索引,它们被替换为在文件(ORC、Parquet)、物理分区和存储桶中编译的统计信息/元数据,这同样能够跳过大部分数据。
生成代理键是一个复杂的并行操作。
这篇 BigQuery (Google)博客文章描述了使用通用方法(对新行使用函数)添加生成序列的限制:
不幸的是,这种方法是有限的。为了实现,BigQuery 需要在执行树的根节点对值进行排序,这受限于一个执行节点的内存量。
UUIDs 和散列更容易并行化,这使得它成为为“大”数据集生成 id 的更具可伸缩性的方法。
对于“维度快照”,我们更喜欢使用散列而不是 UUIDs,我们将在下面的小节中讨论动机:“管理维度”/“代理键”。
照片来自 创业股票照片 来自 Pexels
一些特殊维度如“日期”维度(静态维度),是生成,而不是数据处理的结果。这些表可以预先生成,并且不会保留它们的更改历史。
当一个维度是静态的时,我们可以在每次需要对它进行修改时简单地用覆盖整个数据。
对于要求随时间变化的维度,我们需要一种策略来改变数据。
用户可以更改其家庭地址,产品可以更改名称,品牌可以更换所有者。
多年来,许多“类型”的缓慢和快速变化的维度管理策略被形式化了。其中一些保留历史记录,大多数使用“更新”就地添加或修改信息。
这里的是具有快速改变属性的维度和具有缓慢改变属性的维度之间的分离。
在保存历史记录的维度中,当记录中的任何属性发生更改时,需要复制整行数据,如果属性经常更改,则会使用更多的存储空间。
这些技术很复杂,因为它们是在严格的存储限制下设计的。
维度快照使用更多的存储,但是它们更容易创建和查询。
尺寸应该比事实小得多。一个电子商务的交易、订单和客户评论(事实)可能有数百万,但是独立客户的数量(维度)会小得多。
维度也因其携带的“状态”而不同于事实。维度中的记录将有一个“身份”,当其他属性改变时,需要保留该身份。
维度快照易于管理
每天,我们都会在版本化快照中重写整个维度表
因为不管发生多少变化,整个表都会被重写,所以对于快速和缓慢变化的维度采用不同的策略没有什么好处。
历史
有了这个模型,我们可以通过在特定的日子加入一个过滤器来轻松回答历史问题。
历史记录也不会减慢查询速度,因为传递特定日期实际上会跳过其他日期的文件。
该表的结构使得尺寸表上的时序变得容易。例如,我们可以计算一段时间内每个居住国家的用户数量。
代理键
UUIDs 引入了随机性。为了保持新的代理键与前一个快照的代理键一致,我们需要查询那个快照。
相反,散列是基于构成记录“身份”的键的连接(不包括自然键),因此我们只能从当前数据重新计算它。这就是为什么我们更喜欢在维度快照中使用 UUIDs 散列的原因。
请注意,每日快照消除了对第二个密钥的需要。某些类型的渐变维度实现了两个代理键:一个指向维度记录的“最新”状态,另一个指向特定事实被摄取时记录的历史快照。因为每个快照都包含该时间点的所有数据,所以我们可以使用快照的日期来获得“最新”状态,或者给定时间点的状态。
那不会产生大量数据吗?
数据重复是维度快照的主要缺点。
另一个缺点是维度只需要从的一个进程中创建,因为一天多个快照会加重重复。
以比每天更频繁的频率刷新维度的要求也会放大重复。
收益是简单性、易于访问历史、维度上的时间序列和在写入和查询方面的性能。
然而,在数据复制不可行的情况下,我们可以求助于另一种缓慢变化的维度管理。使用像三角洲湖这样的项目来支持更新。
照片由Unsplash上的气候现实项目拍摄
事实表是数据仓库的基础。它们包含企业的基本度量,并且是大多数数据仓库查询的最终目标
https://www.kimballgroup.com/2008/11/fact-tables/
有多种类型的事实模型来涵盖事实表旨在捕捉的不同度量和事件。
在设计事实时,我们需要决定表中每一行的详细程度。
预先汇总事实可以节省存储空间,但这是一个高风险的赌注,因为来自业务的分析需求可能在未来需要更多的细节。对于今天的大多数情况,在最低细节层次捕捉事实信息是可取的。
绝大多数事实不需要更新。即使在累积快照的特定情况下,我们也可以通过一种消除可变性需求的方式来设计模型。
例如,对于电子商务订单,如果我们有状态:。我们可以创建新的状态来象征先前状态的结束,而不是每次动作结束时都去事实表并用一个来更新行:。现在每个状态的改变都是一个可以插入的独立事件。
为了创建在上游错误或业务需求变化的情况下可以被覆盖的不可变分区,我们需要按照“提取日期”——从源系统提取数据的日期——对我们的数据进行分区。
第一个分区键通常对查询性能没什么用,但是对于实现等幂批处理作业来说很重要。
此外,建议按“事件日期进行分区,因为查询经常使用它作为过滤器(WHERE 子句)。
可以添加其他分区键来额外提高查询速度,但是我们需要确保它们在过滤器中使用,并且生成的文件不会太小。
表格结构示例:
我们的数据处理作业在 5 号创建了 1 个分区:即分区。
然而在 6 号:在前一天发生的一些事务被延迟捕获,因此创建了两个分区:和,这通常被称为、,并且由该表结构支持。
通过采用“星型架构”方法来利用廉价的云存储,我们可以避免数据仓库中的更新、锁定和 ACID 合规性需求。
- 外键是散列而不是整数序列
- 维度使用每日快照
- 事实按照“提取日期进行分区,以支持等幂处理和分区的潜在覆盖
原文:https://towardsdatascience.com/building-a-monorepo-for-data-science-with-pantsbuild-2f77b9ee14bd?source=collection_archive---------18-----------------------
塞尔吉奥·索萨在 Unsplash 上的照片
在 HousingAnywhere ,我们在扩展数据团队时必须面对的第一个主要障碍是建立一个包含我们不断增长的机器学习应用程序的集中式存储库。在这些项目之间,许多项目相互依赖,这意味着代码重构可能会成为一种痛苦,并消耗大量时间。此外,由于我们非常反对数据科学家复制/粘贴代码的倾向,我们需要一个统一的位置来存储可以轻松访问的可重用函数。
我们用例的完美解决方案是构建一个 monorepo。在本文中,我将介绍如何使用构建自动化系统 Pantsbuild 构建一个简单的 monorepo。
monorepo 是一个存储库,其中存储了许多项目的代码。为您的团队建立一个集中的存储库有很多好处:
- 复用性:允许项目共享功能,在数据科学的情况下,预处理数据、计算度量甚至绘制图形的代码可以跨项目共享。
- 原子变更:只需要一个操作就可以跨多个项目进行变更。
- 大规模的重构 : 可以简单快速地完成,确保项目在之后仍然有效。
然而,Monorepo 并不是一个适合所有人的解决方案,因为它有许多缺点:
- 安全问题:没有办法只暴露存储库的一部分。
- 大代码库:随着回购规模的增长,它会带来问题,因为开发人员必须检查整个存储库。
在 HousingAnywhere,我们的数据科学家团队发现 monorepo 是我们数据团队用例的完美解决方案。我们的许多机器学习应用程序都有从中派生出来的较小的项目。monorepo 使我们能够快速地将这些新项目整合到 CI/CD 管道中,减少了为每个新项目单独设置管道的时间。
我们尝试了许多构建自动化系统,我们坚持使用的是。Pants 是为数不多的原生支持 Python 的系统,是 Twitter、Toolchain、Foursquare、square、Medium 广泛使用的开源项目。
最近 Pants 已经更新到了 v2,目前只支持 Python,但是对于数据科学项目来说并没有太大的限制。
有几个关于裤子的概念你应该事先了解:
- ****目标帮助用户告诉裤子采取什么行动,例如
- ****任务是运行动作的裤子模块
- ****目标描述对哪些文件采取这些操作。这些目标是在构建文件中定义的
- ****目标类型定义可在目标上执行的操作类型,例如,您可以在测试目标上执行测试
- ****地址描述回购中目标的位置
要了解更多信息,我强烈推荐阅读这篇文档,裤子的开发者在详细解释这些概念方面做得非常好。
在本节中,我将介绍如何使用 Pants 轻松设置 monorepo。首先,确保满足以下安装裤子的要求:
- Linux 或者 macOS。
- Python 3.6+可在您的上发现。
- 互联网接入(这样裤子就可以完全自举了)。
现在,让我们建立一个新的存储库:
或者,您可以通过以下方式克隆示例回购:
接下来,运行以下命令下载安装文件:
然后,通过奔跑拉起裤子。您应该收到作为输出。
让我们向回购中添加几个简单的应用程序。首先,我们将创建一个和一个,它们包含几个实用函数:
现在,我们将添加一个应用程序来导入这些代码。应用程序使用来自的数据,将它们传递给线性回归模型,并输出平均绝对百分比误差。
另一个应用程序使用第一个应用程序代码:
然后,我们为这些应用程序添加了几个简单的测试,例如:
在每个目录中,我们都需要一个构建文件。这些文件包含关于目标及其依赖项的信息。在这些文件中,我们将声明这些项目需要什么需求,以及声明测试目标。
让我们从存储库的根开始:
这个构建文件包含一个宏,它创建了多个目标来从同一个目录下的中提取第三方依赖项。它节省了我们为每个需求手工操作的时间:
中的构建文件如下所示:
这里我们有两个目标:第一个是 Python 库,包含在中定义的 Python 代码,即我们的两个实用程序文件。它还指定了运行这些代码所需的需求,这是,我们在根构建文件中定义的第三方依赖项之一。
第二个目标是我们之前定义的测试集合,它们依赖于之前的 Python 库。要运行这些测试,只需从 root 运行或即可。第二个告诉 Pants 运行构建文件中的所有测试目标。输出应该如下所示:
类似地,我们将为和创建两个构建文件
在构建文件中,我们将上面中的库声明为这个库的依赖项。这意味着来自该库的所有依赖项,连同它的源,将成为的依赖项。
类似地,我们也向这些构建文件添加一些测试目标,它们可以用或运行。
最终的目录树应该如下所示:
Pants 的强大之处在于它能够跟踪受变更影响的项目和测试目标之间的可传递依赖关系。Pants 的开发人员为我们提供了这个漂亮的 bash 脚本,可以用来追踪受影响的测试目标:
为了展示它的威力,让我们运行一个例子。我们将创建一个新分支,对进行修改(例如,更改的默认参数)并提交:
现在,运行 bash 脚本,我们将看到一个,它包含所有受影响的项目和将要执行的测试目标:
传递依赖性
查看上图,我们可以清楚地看到,更改会影响它上面的所有节点,包括和。
让我们再做一个例子,这次我们只修改。切换分支,提交并再次运行脚本。在内部,我们只会得到,因为它是最顶层的节点。
就这样,希望我已经成功地向你们展示了 Pantsbuild 对于数据科学 monorepos 是多么有用。加上正确实现的 CI/CD 管道,开发的速度和可靠性可以大大提高。
原文:https://towardsdatascience.com/building-a-movie-recommender-using-python-277959b07dae?source=collection_archive---------8-----------------------
照片由晨酿在 Unsplash 拍摄
在这篇文章中,我将向你展示如何使用 Python 来构建一个电影推荐程序。这将是一个简单的项目,我们将能够看到机器学习如何在我们的日常生活中使用。如果你查看我的其他文章,你会发现我喜欢演示动手项目。我觉得这是练习我们编码技能,提升自己的最好方式。建立一个电影推荐程序是开始使用机器推荐器的好方法。在分享了目录之后,我想给你介绍一下推荐系统。
- 简介
- 电影数据
- 数据准备
- 基于内容的推荐器
- 显示时间
- 视频演示
推荐系统已经伴随我们有一段时间了,它们是如此的强大。这些天来,他们确实对我们的决定有很大的影响。从电影流媒体服务到在线购物商店,它们几乎无处不在。如果你想知道在你的购物车中添加一个“x”项目后,他们如何知道你可能会购买什么,答案很简单: 数据的力量 。
我们可能看起来非常不同,但我们的习惯可能非常相似。这些公司喜欢寻找他们客户的相似习惯。由于他们知道许多购买了“x”商品的人也购买了“y”商品,他们建议您将“y”商品添加到购物车中。你猜怎么着,你买得越多,你就在训练你自己的推荐者,这意味着机器会更了解你。
推荐系统是机器学习的一个非常有趣的领域,它的酷之处在于它就在我们身边。关于这个话题有很多东西要学,为了简单起见,我就讲到这里。让我们开始建立自己的电影推荐系统吧!
我在 Kaggle 上找到了很棒的电影数据。如果你没有听说过 Kaggle,Kaggle 是世界上最大的数据科学社区,拥有强大的工具和资源来帮助你实现数据科学目标。
这里是下载数据集的链接。
- 数据文件夹包含完整的 MovieLens 数据集中列出的所有 45,000 部电影的元数据。
- 该数据集由 2017 年 7 月或之前上映的电影组成。数据点包括演员、工作人员、情节关键词、预算、收入、海报、上映日期、语言、制作公司、国家、TMDB 票数和平均票数。
- 该数据文件夹还包含评级文件,该文件具有来自 270,000 个用户对所有 45,000 部电影的 2,600 万个评级。
首先,让我们从导入和探索我们的数据开始。下载数据文件夹后,您将多个数据集文件。对于这个项目,我们将使用 movies_metadata.csv 数据集。这个数据集包含了我们创建电影推荐器所需的所有内容。
电影数据头
完美!我们的数据都准备好了。准备接受我们模特的训练。是时候进入下一步了,我们将开始构建基于内容的推荐器。
基于内容的推荐器是一种推荐模型,它根据特定的项目返回项目列表。推荐者的一个很好的例子是网飞、YouTube、Disney+等等。例如,网飞推荐你以前看过的更喜欢的类似节目。通过这个项目,你将更好地理解这些在线流媒体服务的算法是如何工作的。
回到这个项目,作为训练我们模型的输入,我们将使用我们之前检查过的电影的概述。然后我们将使用一些 sci-kit learn ready 函数来构建我们的模型。我们的推荐程序将在四个简单的步骤中准备就绪。我们开始吧!
理解上面的代码
- 从 sci-kit 学习模块导入矢量器。在这里了解更多。
- Tf-idf 矢量器对象删除所有英文停用词,如’ the ‘,’ a '等。
- 我们用空字符串替换空值,这样在训练它们时就不会返回错误消息。
- 最后,我们通过拟合和转换数据来构建所需的 Tf-idf 矩阵
我们将从 sci-kit 学习模块中导入线性内核函数开始。线性核将帮助我们创建一个相似性矩阵。这些行执行起来要花一点时间,不要担心这是正常的。计算两个巨大矩阵的点积并不容易,即使对机器来说也是如此:)
现在,我们必须构建索引和电影标题的反向映射。在系列函数的第二部分,我们用一个简单的函数 drop_duplicates 清除重复的电影标题。
前十个指数
干得好!是时候测试我们的推荐者了。让我们看看实际情况,看看它到底有多强大。我们将通过添加电影名称作为一个字符串参数来运行该函数。
项目视频演示
恭喜你。!您创建了一个向您推荐电影的程序。现在,当你想选择下一场网飞秀时,你有一个程序可以运行。希望你喜欢阅读这个动手项目。如果你今天学到了新东西,我会很高兴。从事像这样的动手编程项目是提高编码技能的最好方式。
如果您在执行代码时有任何问题,请随时联系我。
关注我的博客和 youtube 频道,保持灵感。谢谢你,
[## 用 Python 构建人脸识别器
使用 OpenCv 库进行实时人脸识别的分步指南
towardsdatascience.com](/building-a-face-recognizer-in-python-7fd6630c6340) [## 使用 Python 从视频中提取语音
使用 Google 语音识别 API 的简单实用项目
towardsdatascience.com](/extracting-speech-from-video-using-python-f0ec7e312d38)
原文:https://towardsdatascience.com/building-a-multi-functionality-voice-assistant-in-10-minutes-3e5d87e164f0?source=collection_archive---------33-----------------------
图像取自— 图像 1 、图像 2 、图像 3 、图像 4
如今,人们没有时间手动在互联网上搜索信息或问题的答案,而是希望有人为他们做这件事,就像个人助理一样,听取提供的命令并据此采取行动。由于人工智能,这种个人助理现在可以以语音助理的形式提供给每个人,比人类快得多,也可靠得多。一个甚至能够完成困难任务的助手,比如在线下单、播放音乐、开灯等。仅仅通过听用户的命令
在本文中,我将向您展示如何构建一个语音助手来响应基本的用户查询。读完这篇文章后,你会对什么是网络抓取以及如何用它来构建一个语音助手有一个基本的概念。
注意:要阅读本文,您需要对 Python 语言有一个基本的了解。
- 语音助手
2.网页抓取
3.履行
语音助手是一个软件代理,可以根据命令或问题为个人执行任务或服务。一般来说,语音助手对语音命令做出反应,并向用户提供关于他/她的查询的相关信息。
该助手可以理解用户发出的特定命令并做出反应,如在 YouTube 上播放歌曲或了解天气。它将搜索和/或抓取网页以找到对命令的响应,从而满足用户。
目前,语音助手已经能够处理产品订单,回答问题,执行播放音乐或与朋友打电话等操作。
实现的语音助手可以执行以下任务:
- 提供天气详情
- 提供电晕更新
- 提供最新消息
- 搜索一个词的意思
- 做笔记
- 播放 YouTube 视频
- 在谷歌地图上显示位置
- 在谷歌浏览器上打开网站
在构建语音助手时,有两个重要的库是你应该考虑的。Python 的 SpeechRecognition 包帮助语音助手理解用户。它可以按如下方式实现:
Python 的 pyttsx3 包通过将文本转换成音频来帮助语音助手响应用户。它可以按如下方式实现:
网页抓取是指从网站中提取数据。网站上的数据是非结构化的。Web 抓取有助于收集这些非结构化数据,并以结构化形式存储。
网页抓取的一些应用包括:
搜集社交媒体如 Twitter,以收集推文和评论来进行情感分析。
抓取亚马逊等电子商务网站提取产品信息进行数据分析,预测市场趋势。
收集电子邮件地址以收集电子邮件 id,然后发送大量电子邮件用于营销和广告目的。
抓取谷歌图片以创建数据集,用于训练机器学习或深度学习模型。
虽然可以手动完成,但是 Python 的库美汤让抓取数据变得更加简单快捷。
要通过 python 使用 web 抓取来提取数据,您需要遵循以下基本步骤:
- 找到您想要抓取的网站的 URL
- 提取网站的全部代码
- 检查网站并找到您想要提取的数据
- 使用 html 标签过滤代码以获得所需的数据
- 以要求的格式存储数据
让我们首先在您的 python 笔记本中导入以下库,如下所示:
现在让我们创建我们的主函数,它由一系列 if-else 语句组成,告诉助手在特定条件下如何响应。
案例一:如果用户想了解天气,他/她可以问助手*“嘿!孟买今天的天气怎么样?”*
由于音频中出现了单词 “weather” ,函数**scrape _ weather(words[-1])**将被调用,参数为 "Mumbai "。
让我们来看看这个函数。
我们将使用“*accuweather.com”*网站搜集所有与天气相关的信息。函数 request.get(url) 向使用 BeautifulSoup(page.text,’ lxml’) 提取完整 HTML 代码的 url 发送 get 请求
一旦提取了代码,我们将检查代码以找到感兴趣的数据。例如,温度的数值以下列格式表示
可以使用提取
类似地,我们提取时间、真实感觉和气候,并使用 engine.say()让助手对用户做出响应。
案例二:如果用户想要当前新冠肺炎的更新,他/她可以问助手嘿!你能给我印度的 COVID 更新吗?”或“嘿!你能给我世界的 COVID 更新吗?”
由于单词*“covid”*出现在音频中,函数**corona _ updates(words[-1])将被调用,参数为“印度”或“世界”
让我们来看看这个函数。
我们将使用网站“world ometers . info*”*搜集所有与日冕相关的信息。函数 request.get(url) 向使用 BeautifulSoup(page.text,’ lxml’) 提取完整 HTML 代码的 url 发送 get 请求
一旦提取了代码,我们将检查代码以找到总电晕情况、总恢复和总死亡的数值。
这些值存在于具有类“maincounter-number”的 div 范围内,如下所示。
这些可以提取如下。
我们首先找到所有具有类“maincounter-number”的 div 元素。然后我们遍历每个 div 以获得包含数值的跨度。
案例三:如果用户想了解新闻,可以问助理*“嘿!你能告诉我最新的消息吗?”*
由于音频中出现了单词*“news”*,因此将调用函数 scrape_news() 。
我们将使用“谷歌新闻”来抓取新闻标题。函数 request.get(url) 向使用 BeautifulSoup(page.text,’ lxml’) 提取完整 HTML 代码的 url 发送 get 请求
一旦提取了代码,我们将检查代码以找到最新新闻的标题。
这些标题出现在 h3 标记的 href 属性中,具有如下所示的类“ipQwMb ekueJc RD0gLb”。
我们首先找到所有具有类“ipQwMb ekueJc RD0gLb”的 h3 元素。然后,我们遍历每个元素以获取 href 属性中的文本(新闻标题)。
案例四:如果用户想知道任意单词的含义,可以问助手*“嘿!刮是什么意思?”*
由于音频中出现了单词*,意思是*,函数 scrape_meaning(单词[-1])将被调用,参数为*“scraping”*
让我们来看看这个函数。
我们将使用网站“”*”*来刮取意思。函数 request.get(url) 向使用 BeautifulSoup(page.text,’ lxml’) 提取完整 HTML 代码的 url 发送 get 请求
一旦提取了代码,我们将检查代码,找到所有包含作为参数传递的单词含义的 html 标签。
这些值存在于具有类“css-1o58fj8 e1hk9ate4”的 div 中,如下所示。
我们首先找到所有具有类“css-1o58fj8 e1hk9ate4”的 div 元素。然后,我们遍历每个元素以获取 div 中的文本(单词的含义)。
情况 5:如果用户想让助手**做笔记,他/她可以问助手“嘿!你能帮我记笔记吗?”
由于单词*“做笔记”*出现在音频中,将调用函数 take_notes() 。
让我们来看看这个函数。
我们首先初始化识别器,向用户询问他们的“任务清单”。然后我们听用户说话,并使用 recognize_google 来识别音频。现在我们将打开一个名为“MyNotes.txt”的记事本,记下用户给出的笔记和日期。
然后,我们将创建另一个名为 show_notes()的函数,它将从名为“MyNotes.txt”的记事本中读出今天的笔记/待办事项列表。
案例六:如果用户想**播放 YouTube 视频,他/她可以问助手“嘿!能不能玩催眠?”
由于音频中出现了单词*“play”,因此将调用函数 play _ YouTube(words[-1]),并传递“催眠”作为参数。*
让我们来看看这个函数。
我们将使用 G oogle Videos 来搜索视频标题,并打开第一个链接来播放 YouTube 视频,该视频出现在具有类“r”的 div 元素中。
*情况 7:如果用户想要*搜索位置,他/她可以问助手“嘿!IIT 孟买在哪里?”
由于单词“where is”出现在音频中,下面的代码将被执行。
(这段代码出现在主函数的 if-else 循环中)
我们将加入谷歌地图链接用户提供的位置,并使用 webbrowser.open(链接)打开链接定位’ IIT 孟买’。
案例 8:如果用户想**打开一个网站,**他/她可以问助手嘿!能不能向数据科学开放?”**
由于单词“打开”出现在音频中,下面的代码将被执行。
(这段代码出现在主函数的 if-else 循环中)
我们将把用户提供的网站名称与任何 URL 的标准格式连接起来,即https://{网站名称}。com 打开网站。
这就是我们如何创建一个简单的语音助手。您可以修改代码以添加更多功能,如执行基本的数学计算、讲笑话、创建提醒、更改桌面壁纸等。
你可以在下面链接的我的 GitHub 资源库中找到完整的代码。
* ## sakshibutala/语音助手
在这个笔记本中,我建立了一个语音助手,可以回答基本的询问。“VoiceAssistant.ipynb”包含…
github.com
## 什么是网页抓取,它是用来做什么的?ParseHub
一些网站可能包含大量宝贵的数据。股票价格,产品详情,体育统计,公司…
www.parsehub.com ## 使用 Python 进行 Web 抓取-初学者指南| Edureka
使用 Python 进行 Web 抓取想象一下,您必须从网站中提取大量数据,并且您希望尽可能快地完成这些工作…
www.edureka.co ## 什么是语音助手,它们是如何工作的?Onlim
科幻电影中的场景,我们回到家,开始对着我们的个人家用电脑说话…
onlim.com*
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/75506.html