TowardsDataScience 博客中文翻译 2020(七十八)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

Python 中群组分析的分步介绍

原文:https://towardsdatascience.com/a-step-by-step-introduction-to-cohort-analysis-in-python-a2cbbd8460ea?source=collection_archive---------0-----------------------

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

来源: Unsplash

学习如何进行群组分析,以更好地了解顾客的行为

群组分析是一种非常有用且相对简单的技术,有助于获得关于任何企业客户/用户行为的有价值的见解。为了进行分析,我们可以关注不同的指标(取决于业务模式)——转化率、留存率、产生的收入等。

在本文中,我提供了群组分析的简要理论介绍,并展示了如何在 Python 中实现它。

队列分析导论

让我们从基础开始。一个群组是一群有共同之处的人,比如某个 app 的注册日期,第一次购买的月份,地理位置,获取渠道(有机用户,来自效果营销等。)等等。在群组分析中,我们随着时间的推移跟踪这些用户群,以识别一些共同的模式或行为。

在进行群组分析时,考虑我们正在跟踪的指标和业务模式之间的关系至关重要。根据公司的目标,我们可以关注用户保留率、转换率(注册付费版本的服务)、产生的收入等。

在本文中,我将讨论用户保持的情况。通过了解用户保持率,我们可以推断客户的粘性/忠诚度,并评估业务的健康状况。重要的是要记住,不同企业之间的预期保留值差异很大,一年购买 3 次对一个零售商来说可能很多,而对另一个零售商来说可能太少。

留住客户对任何企业都至关重要,因为留住现有客户(通过使用 CRM 工具、会员折扣等)要便宜得多。)而不是获得新的。

此外,群组分析还可以帮助观察产品变化对用户行为的影响,无论是设计变化还是全新的功能。通过观察这些群体在一段时间内的行为,我们可以或多或少地观察到我们的努力是否对用户产生了一些影响。

现在这应该是足够的理论了,让我们来看看现实生活中的例子。

设置

在本文中,我们将使用以下库:

数据集

我们将使用从 UCI 机器学习库下载的数据集,该库是不同种类数据集的绝佳来源。它们已经根据可用于机器学习的领域进行了标记:

  • 监督(回归/分类),
  • 无监督(聚类)。

你可以在这里找到数据集。或者,您可以使用以下代码行直接从 Jupyter 笔记本下载数据:

!wget [https://archive.ics.uci.edu/ml/machine-learning-databases/00352/Online%20Retail.xlsx](https://archive.ics.uci.edu/ml/machine-learning-databases/00352/Online%20Retail.xlsx)

该数据集可以简单描述为:“这是一个跨国数据集,包含了一家总部位于英国的注册无店铺在线零售商在 2010 年 1 月 12 日至 2011 年 9 月 12 日之间发生的所有交易。该公司主要销售独特的适合各种场合的礼品。公司的很多客户都是批发商。”

接下来,我们从 Excel 文件中加载数据。

加载的数据如下所示:

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

我们还使用df.info()检查了数据帧,看看是否有丢失的值。至于分析,由于我们需要客户 id,我们删除了所有没有客户 id 的行。

df.dropna(subset=['CustomerID'], inplace=True)

为了完整起见,我们还做了一个非常快速的 EDA,重点是用户。EDA 始终是任何分析的一个非常重要的步骤,因为我们会发现我们正在处理的数据集的细节。

我们首先检查数字变量的分布——数量和单价。

df.describe().transpose()

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

从上表中,我们可以看到存在数量为负的订单,这很可能是退货。总的来说,大约有 9000 个负数量的采购。我们将它们从数据集中移除。这就引入了一种偏差,因为我们包含了初始订单并删除了退货,这样初始订单就被考虑在内,即使理论上它没有实现也没有产生收入。但是,为了简单起见,我们保留初始订单,至于保留率(表示客户参与度)等指标,这仍然是一个有效的假设。

然后,我们计算一个聚合指标,表明每个客户下了多少订单。

使用上面的代码,我们可以得出 65.57%的客户订购了不止一次。这已经是一条有价值的信息,因为客户似乎下了多个订单。这意味着至少会有一些保留。鉴于数据集没有注册/加入日期,如果大多数用户只下了一个订单,这将是有问题的,但我们稍后将回到这个问题。

此外,我们查看每个客户订单数量的分布。为此,我们可以重用之前聚合的数据(n_orders)并将数据绘制在直方图上。

运行代码会生成以下图形:

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

有一些不常见的客户案例,他们订购了 50 次以上。

断代分析

我们在本例中使用的数据集不包含客户注册日期,即他们向零售商注册的日期。这就是为什么我们假设他们所属的群组是基于第一次购买日期的。这种方法的一个可能的缺点是,数据集不包含过去的数据,我们在这个快照(2010 年 1 月 12 日至 2011 年 9 月 12 日之间)中已经看到的数据包括重复出现的客户。换句话说,我们在这个数据集中看到的第一次购买可能不是给定客户的实际第一次购买。但是,如果不能访问零售商的整个历史数据集,就无法对此做出解释。

第一步,我们只保留相关的列并删除重复的值——一个订单(由InvoiceNo表示)可以包含多个项目(由StockCode表示)。

第二步,我们创建cohortorder_month变量。第一个指示基于第一次购买日期的每月群组(按客户计算)。后一个是购买日期的截断月份。

然后,我们根据cohortorder_month汇总数据,并计算每组中独立客户的数量。此外,我们添加了period_number,它指示群组月份和购买月份之间的周期数。

下一步是以这样一种方式透视df_cohort表,即每行包含关于给定群组的信息,每列包含某个时间段的值。

为了获得保留矩阵,我们需要将每行的值除以该行的第一个值,这实际上是群组大小——在给定月份中第一次购买的所有客户。

最后,我们将保留矩阵绘制成热图。此外,我们希望包括关于队列规模的额外信息。这就是为什么我们实际上创建了两个热图,其中一个指示群组大小的热图使用的是纯白色的色图——没有任何颜色。

最终结果是以下保留矩阵:

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

在图中,我们可以看到在第二个月(指数为 1)已经出现了大幅下降,平均约 80%的客户在第二个月没有进行任何购买。第一组(2010-12)似乎是个例外,与其他组相比,表现出人意料地好。第一次购买一年后,有 50%的保留。这可能是一群忠诚的顾客,他们最初加入平台是基于与零售商已经存在的一些联系。然而,仅从数据来看,这很难准确解释。

在整个矩阵中,我们可以看到保留时间的波动。这可能是由业务的特点造成的,客户会定期购买,随后会有一段时间不活动。

结论

在本文中,我展示了如何使用 Python 的pandasseaborn进行群组分析。在路上,我做了一些简化的假设,但这主要是由于数据集的性质。当在一个公司的真实场景中工作时,我们会对业务有更多的了解,并能从分析中得出更好、更有意义的结论。

你可以在我的 GitHub 上找到本文使用的代码。一如既往,我们欢迎任何建设性的反馈。你可以在推特或评论中联系我。

喜欢这篇文章吗?成为一个媒介成员,通过无限制的阅读继续学习。如果你使用这个链接成为会员,你将支持我,不需要额外的费用。提前感谢,再见!

我最近出版了一本关于使用 Python 解决金融领域实际任务的书。如果你有兴趣,我贴了一篇文章介绍这本书的内容。你可以在亚马逊或者 Packt 的网站上买到这本书。

Giraffle 的逐步介绍

原文:https://towardsdatascience.com/a-step-by-step-introduction-to-giraffle-b23fd19d4b53?source=collection_archive---------43-----------------------

如何以编程方式在 TigerGraph 上创建图形

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

照片来自 UnsplashCharl Durand 拍摄

为什么要用长颈鹿?

Giraffle 由 Joshua Meekhof 创建,是一种在 TigerGraph 中以编程方式创建图形的方法。当与许多团队成员一起处理一个图表项目时,将我们的图表写在代码中会使协作更容易。此外,在协作空间中,如果有人不小心丢失了全部或部分数据,您的模式和查询都会被保存并可重用。总的来说,通过以编程方式创建图形,Giraffle 可以帮助简化与 TigerGraph 中的图形的协作。

开始的步骤

在这篇博客中,我们将讨论:

  1. 在 TigerGraph 上创建解决方案
  2. 设置 Giraffle
  3. 创建模式
  4. 加载数据
  5. 创建查询

到这篇博客结束时,你将知道足够用 Giraffle 创建你自己的项目!如果你遇到困难或困惑,GitHub 链接在博客的最后,供你参考。

另外, Jon Herke 创建了一个博客来帮助 Giraffle 入门,而 Ramki Pitchala 写了一个关于迁移到 Giraffle 的博客。我强烈建议你也去看看那些博客!

步骤 1:在 TigerGraph 上创建一个解决方案

首先,我们需要在 TigerGraph 上运行一个解决方案。你需要去 TigerGraph Cloud 。如果您还没有帐户,请创建一个。另一方面,请访问解决方案。

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

点击我的解决方案(图片由作者提供)

接下来,点击右上角的Create Solution

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

创建解决方案

点击第一部分的空白。

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

(图片由作者提供)

不要更改第二部分的任何内容,只需点击Next

在第三部分中,您可以对其进行命名、标记、添加密码、创建子域以及添加描述。其中,确保你记得你的密码和子域。

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

键入名称、解决方案、密码、子域和描述。(图片由作者提供)

请注意,每个子域必须是唯一的。因此,你可能会或可能不会得到子域blog

单击下一步,然后提交。接下来你需要等待它,因为它可能需要几分钟来加载。加载后,通过按 Solution Operations(蓝框)和 start 来启动您的解决方案。加载可能需要一段时间

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

按下蓝框,开始。(图片由作者提供)

恭喜你。现在,您的解决方案已经开始运行了!

步骤 2:设置 Giraffle

首先,确保你已经在电脑上安装了 gradle。您可以使用命令gradle检查您是否已经升级。然后,键入以下命令:

gradle init

在接下来的两个选项中,键入 1 和 2。你可以给这个项目起任何你喜欢的名字。

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

键入 1(基本),然后键入 2 (Kotlin)(图片由作者提供)

您将看到您将在目录中获得几个文件夹。

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

创建的文件夹(图片由作者提供)

从这里,去build.gradle.kts。将其更新为:

import com.optum.giraffle.tasks.*
import com.optum.giraffle.*
plugins {
    id("com.optum.giraffle") version **"1.3.4.1"**
    id("net.saliman.properties") version "1.5.1"
}
repositories {
    jcenter()
}

请注意 1.3.4.1,因为这是最新版本!没有正确的版本,您的代码可能会生成,也可能不会生成。

如果gradle build跑成功了,你就厉害了!接下来,在您的终端中,记住第一步中的子域,键入:

gradle gsqlNewProject --console=plain

按照步骤,填写子域等。

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

我的图是 GiraffleBlog,我的子域是 blog.i.tgcloud.io。我使用默认的用户名和密码。最后,我没有使用多种环境,而是使用 Kotlin。(图片由作者提供)

接下来,我们需要创建一个证书。要生成一个,请使用以下命令:

openssl s_client -connect SUBDOMAIN.i.tgcloud.io:14240 < /dev/null 2> /dev/null | openssl x509 -text > cert.txt

对我来说,应该是:

openssl s_client -connect blog.i.tgcloud.io:14240 < /dev/null 2> /dev/null | openssl x509 -text > cert.txt

如果所有运行都没有错误,那么您已经完成了存储库的设置。现在你应该可以开始开发了!

步骤 3:创建一个模式

您首先需要创建一个模式。一个模式就像一个地图,显示了图形将会有什么。在db_scripts/schema中,创建schema.gsql

在该文件中,我将在这里创建一个非常基本的模式:

CREATE VERTEX Blog(primary_id title STRING) WITH primary_id_as_attribute="true"CREATE VERTEX Person(primary_id name STRING) WITH primary_id_as_attribute="true"CREATE UNDIRECTED EDGE BLOG_CREATOR(FROM Blog, TO Person) CREATE GRAPH @graphname@(Blog, Person, BLOG_CREATOR)

我们有两个顶点叫做 Blog 和 Person,它们通过一条叫做“BLOG_CREATOR”的边连接在一起。

将您的build.gradle.kts更新为:

这是我们将要构建的构建函数的模板。

我们来破解密码。本文档提供了供您运行的任务。例如:

register<GsqlTask>("createSchema") {        
     scriptPath = "schema/schema.gsql" // Where the schema is
     useGlobal = true 
     group = schemaGroup // The group the task is associated with
     description = "Runs gsql to create a schema" // Description of the task
}

对于createSchema,如果您以任何不同的方式命名您的模式文件,您可以更改脚本路径。然后它有一个描述和一个组。它应该可以编译,但是,为了仔细检查,您可以运行gradle tasks

接下来,我们将更新我们的gradle-local.properties。将文件更新为以下内容(填写您的详细信息):

gHost=SUBDOMAIN.i.tgcloud.iogAdminUserName=INSERT_YOUR_ADMIN_USERNAMEgAdminPassword=INSERT_YOUR_ADMIN_PASSWORDgUserName=INSERT_YOUR_USERNAMEgPassword=INSERT_YOUR_PASSWORDgGraphName=GRAPH_NAMEgCertPath=cert.txtgHostUriType=httpsgRestPort=9000

(注意:如果您完全按照说明进行,用户名/密码的默认值是 tigergraph。如果您自定义设置了用户名或密码,请将其更改为您的用户名和密码。将第一步中的子域插入 gHost。gGraphName 是您希望图形使用的名称。)

接下来,我们将把我们的模式上传到云中。为此,请前往https://tgcloud.io/app/solutions。点按“应用程序”(带有四个形状的蓝色按钮),然后点按“GraphStudio”。

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

按下应用程序按钮,然后单击 GraphStudio 启动它。(图片由作者提供)

现在,回到您的终端,我们将使用我们添加的 createSchema 命令。键入:

gradle createSchema

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

您应该得到一个显示成功的输出。如果出现任何其他错误,可能是出了问题。(图片由作者提供)

如果它工作,你的输出应该像上面一样。最后,如果您转到 GraphStudio 并点击 Design Schema,您应该能够看到您的模式。

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

Graph Studio 中的模式(图片由作者提供)

恭喜你!您已经创建并加载了您的模式!

步骤 4:加载数据

接下来,我们将把实际数据加载到图表中。我将创建一个充满作者姓名和博客的 CSV。

在主目录下创建一个名为data的文件夹(应该和db_scripts在同一层,但不在里面。在data文件夹中,创建data.csv,并添加以下数据:

AUTHOR,TITLE"John Smith", "Cool Things to do in Paris""Jack Paul", "101 Best Tourist Spots""Alice Walker", "101 Best Tourist Spots""Blake Coles", "Lessons Learned from a Dog""Amelia-Rose Kim", "Cool New Places""Taha Wardle", "An Awesome Guide to Awesomeness""Bella Bloom", "Cool Things to do in Paris""Nakita Talbot", "Why Learn French?""Kaison Reilly", "Why Learn Spanish?""Philippa Palacios", "Five Habits of Successful People""Pawel Medrano", "101 Best Tourist Spots""Jasper Franklin", "Cool New Places""Abid Little", "How to Love Yourself""John Smith", "Cool Things to do in Lorraine""Alice Walker", "Five Habits of Successful People"

接下来,在db_scripts/load中,创建一个名为loadData.gsql的新文件。在该文件中,添加以下代码:

drop job loadData // deletes past load job called loadDatacreate loading job loadData for graph @graphname@ { // creating a load job called loadData define filename f1; // set the file load f1 // loads the file to vertex Blog values($1), // loads data from the 2nd column in the CSV to the vertex Blog to vertex Person values($0), // loads data from the 1st vertex to vertex Person to edge CREATOR values($1, $0) // connects all data from the 2nd column with the data from the 1st column using header="false", separator=","; // Comma separator, not using headers}

为此,我们创建了一个名为loadData的加载作业。如果您想创建更多的加载作业,将其他文件添加到db_scripts/load,并用您的加载作业名称替换loadData

接下来,在您的build.gradle.kts中,在tasks {下,添加

register<GsqlTask>("createLoadData"){ scriptPath = "load/loadData.gsql" // Call the file you have the load job in. group = loadingGroup description = "Loads our data"}register<HttpTask>("loadData") { group = loadingGroup description = "Load data via the REST++ endpoint" post { httpConfig -> httpConfig.request.uri.setPath("/ddl/${gGraphName}") httpConfig.request.uri.setQuery( mapOf( "tag" to "loadData", "filename" to "f1", "sep" to ",", "eol" to "\n" ) ) httpConfig.request.setContentType("text/csv") val stream = File("data/data.csv").inputStream() // If your data file was called anything else, you can change the File(""). httpConfig.request.setBody(stream) }}

这里,我们创建两个任务:一个创建或“构建”文件,另一个将数据加载到图表中。

在将我们的更改加载到图表之前,我们需要生成一个秘密。进入 GraphStudio 并点击右上角的Admin按钮。点击后,点击左侧栏中的User Management

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

你应该在这里结束。(图片由作者提供)

最后,在标有 Create Secret 的框下,点击橙色的Create按钮并复制密码。

gradle-local.properties中,添加一个新字段:

gSecret=SECRET_YOU_COPIED

要运行,只需:

gradle createLoadData
gradle loadData

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

您的终端输出应该如下所示。(图片由作者提供)

最后可以去 Graph Studio。转到Load Data以确保所有东西都已装载。

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

注意右边顶点和边的数字。因为它们不全是 0,我们的数据加载!(图片由作者提供)

接下来去Explore Graph看看数据。您可以选取几个顶点并双击它们,以探索与其连接的其他顶点。

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

探索图表的一些结果(图片由作者提供)

步骤 5:创建查询

最后,我们可以使用查询来分析数据。在db_scripts/queries中,用以下内容创建一个名为selectAll.gsql的文件:

drop query selectAllcreate query selectAll (STRING auth) for graph @graphname@ { ListAccum<EDGE> @@edgelist; People = {Person.*}; author = select s
              FROM People:s -() -:t
              where s.name == auth; blogs = select c
              from People:s -(BLOG_CREATOR:e) -Blog:c
              where s.name == auth ACCUM @@edgelist+=e;

     print author; print blogs; PRINT @@edgelist;}install query selectAll

接下来,在与加载任务相同的区域中,您需要为build.gradle.kts(在tasks部分中)中的查询添加一个任务。您应该添加以下内容:

register<GsqlTask>("createQuerySelectAll") { scriptPath = "query/selectAll.gsql" group = queryGroup description = "Creates a select all"}

最后,要将查询推送到解决方案,运行:

gradle createQuerySelectAll

转到 GraphStudio,转到查询,您应该会找到 selectAll。

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

注意左上角附近的 selectAll。(图片由作者提供)

您可以单击 selectAll,按顶部的 play 按钮,然后它将运行查询并接收参数。现在,您可以运行自己的查询了!

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

接受查询的名称(图片由作者提供)

第六步:创建你自己的项目!

恭喜你!您现在知道了如何用 Giraffle 以编程方式创建图形。现在,您可以开始为自己的项目建模和查询数据了。祝你好运!

额外资源

对 PCA 的逐步介绍

原文:https://towardsdatascience.com/a-step-by-step-introduction-to-pca-c0d78e26a0dd?source=collection_archive---------4-----------------------

关于如何使用 python 对数据集应用主成分分析的指南

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

鸢尾花。图片由 S. Hermann & F. Richter 从 Pixabay 拍摄。

在本文中,我将讲述如何解决对高维数据集(即每个样本都有大量测量值的数据集)进行可视化、分析和建模的问题。对于这种类型的数据集,很难确定要素之间的关系,也很难可视化它们之间的关系。将模型应用于高维数据集时,通常会导致过拟合,即不在训练集中的样本性能较差。

我今天要讨论的方法是一种无监督的降维技术,称为主成分分析,简称 PCA。在这篇文章中,我将讨论执行 PCA 的步骤。我还将使用 python 演示数据集上的 PCA。你可以在这里找到完整的代码脚本。执行 PCA 的步骤如下:

  1. 将数据标准化。
  2. 从数据集中计算要素的协方差矩阵。
  3. 对协方差矩阵执行特征分解。
  4. 根据相应特征值的大小,按降序对特征向量进行排序。
  5. 确定 k,即要选择的顶部主成分的数量。
  6. 从所选数量的顶部主成分构建投影矩阵。
  7. 计算新的 k 维特征空间。

选择数据集

为了使用示例演示 PCA,我们必须首先选择一个数据集。我选择的数据集是 Fisher 收集的虹膜数据集。

该数据集由来自三种不同类型鸢尾的 150 个样本组成:刚毛鸢尾、杂色鸢尾和海滨鸢尾。对于每个样本,数据集有四个测量值。这些测量值是萼片长度、萼片宽度、花瓣长度和花瓣宽度。为了访问这个数据集,我们将从 sklearn 库导入它:

from sklearn.datasets import load_iris

现在数据集已经导入,可以通过执行以下操作将其加载到数据框中:

iris = load_iris()
colors = ["blue", "red", "green"]
df = DataFrame(
    data=np.c_[iris["data"], iris["target"]], columns=iris["feature_names"] + ["target"]
)

既然数据集已经加载,我们可以像这样显示一些样本:

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

使用 df.sample 从数据集中选择一些样本(n=5)。

箱线图是可视化数据分布的好方法。可以使用以下方法创建一组箱线图:

df.boxplot(by="target", layout=(2, 2), figsize=(10, 10))

这给出了:

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

箱线图显示每种类型虹膜的每次测量值的分布。

箱线图向我们展示了许多细节,比如弗吉尼亚的花瓣长度中值最大。我们将在本文的后面回到这些箱线图。

使数据标准化

既然数据集已经加载,就必须为降维做准备。当所有特征都在同一尺度上时,大多数机器学习和优化算法的性能会更好。为了做到这一点,可以实施标准化方法。通过使用以下计算,特征值 xⁱ可以变成标准化的特征值 xⁱₛ:

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

其中,μₓ是特征列的平均值,σₓ是相应的样本方差。这导致特征值具有平均值 0 和标准偏差 1,因此具有与正态分布相同的参数。例如,对于具有从 0 到 5 的值的特征列,应用标准化将产生以下新值:

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

值从 0 到 5 被标准化的特征列的示例。

就我们的数据集而言,虹膜特征的标准化可以使用 sklearn 实现,如下所示:

X = StandardScaler().fit_transform(X)

计算协方差矩阵

协方差衡量两个要素之间的差异。正协方差表示要素同时增加和减少。反之,负协方差表示两个特征的变化方向相反。对于两个特征向量 xⱼ和 xₖ,它们之间的协方差σⱼₖ可以使用下面的等式来计算:

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

协方差矩阵包含要素之间的协方差值,形状为 d × d。因此,对于我们的数据集,协方差矩阵应如下所示:

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

由于特征列已被标准化,因此它们各自的均值为零,协方差矩阵σ可通过以下公式计算:

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

其中 Xᵗ是 x 的转置。如果你需要矩阵乘法如何工作的提示,这里的是一个很好的链接。

这可以用 python 实现,如下所示:

cov = (X.T @ X) / (X.shape[0] - 1)

执行特征分解

特征向量代表协方差矩阵的主要分量(最大方差的方向)。特征值是它们相应的大小。具有最大相应特征值的特征向量代表最大方差的方向。特征向量 v 满足以下条件:

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

其中λ是一个标量,称为特征值。手动计算是相当复杂的,可能是一个帖子本身。然而,如果你想知道更多,我推荐你看看这个视频。相反,我将使用 python 中的特征分解函数:

eig_values, eig_vectors = np.linalg.eig(cov)

这给出了协方差矩阵的特征向量(主分量)和特征值。

确定选择哪些主成分

既然已经计算了特征对,现在需要根据它们的特征值的大小对它们进行排序。这可以在 python 中通过执行以下操作来完成:

idx = np.argsort(eig_values, axis=0)[::-1]
sorted_eig_vectors = eig_vectors[:, idx]

既然已经根据主成分对应特征值的大小对主成分进行了排序,那么是时候决定选择多少主成分进行降维了。这可以通过绘制特征值的累积和来实现。累积和的计算方法如下:

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

上述公式可以计算并绘制如下:

cumsum = np.cumsum(eig_values[idx]) / np.sum(eig_values[idx])
xint = range(1, len(cumsum) + 1)
plt.plot(xint, cumsum)

plt.xlabel("Number of components")
plt.ylabel("Cumulative explained variance")
plt.xticks(xint)
plt.xlim(1, 4, 1)

该图显示了以下内容:

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

显示特征值累积和的图。

从图中,我们可以看到,超过 95%的方差包含在两个最大的主成分中。因此,选择前两个最大的主成分构成投影矩阵 w 是可以接受的。

计算转换

既然已经决定了有多少个主分量构成投影矩阵 W,则得分 Z 可以计算如下:

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

这可以在 python 中通过执行以下操作来计算:

eig_scores = np.dot(X, sorted_eig_vectors[:, :2])

绘制结果

现在数据集已经被投影到一个新的更低维度的子空间上,结果可以如下绘制:

def biplot(score, coeff, labels):
    xs = score[:, 0]
    ys = score[:, 1]
    n = coeff.shape[0]

    for i, u in enumerate(iris["target_names"]):
        xi = [
            score[j, 0] for j in range(score.shape[0]) if df["target"].tolist()[j] == u
        ]
        yi = [
            score[j, 1] for j in range(score.shape[0]) if df["target"].tolist()[j] == u
        ]
        plt.scatter(xi, yi, c=colors[i], label=u)
    for i in range(n):
        plt.arrow(
            0, 0, coeff[i, 0], coeff[i, 1], color="r", head_width=0.05, head_length=0.1
        )
        plt.text(
            coeff[i, 0] * 1.35,
            coeff[i, 1] * 1.35,
            labels[i],
            color="g",
            ha="center",
            va="center",
        )

plt.xlabel("PC{}".format(1))
plt.ylabel("PC{}".format(2))
plt.grid()

biplot(scores, sorted_eig_vectors, iris["feature_names"])
plt.legend()

这给出了:

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

绘制在二维特征空间上的虹膜样本。

从图中可以看出,versicolor 和 virignica 样品之间的距离较近,而 setosa 与它们之间的距离较远。如果你还记得上面的双标图,海滨锦鸡儿有最大的平均萼片长度、花瓣长度和花瓣宽度。然而,刚毛藻具有最高的平均萼片宽度。通过跟踪原始特征的轴可以看出这是正确的。

使用奇异值分解(SVD)计算 X 的替代方法

特征分解的一些缺点是计算量大,并且需要一个方阵作为输入。部分由于这些原因,寻找 PCA 的主成分的更流行的方法是使用奇异值分解(SVD)。SVD 将矩阵分解为满足以下条件的三个独立矩阵:

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

其中 U 是左奇异向量,V*是右奇异向量的复共轭,S 是奇异值。奇异值与从特征分解计算的特征值相关。SVD 的另一个有用特性是奇异值是数量级的,因此不需要重新排序。右奇异向量与通过特征分解得到的特征向量相同,因此 W=V。使用 python,矩阵的 SVD 可以如下计算:

u, s, vh = np.linalg.svd(X)

由此,现在可以计算分数:

svd_scores = np.dot(X, vh.T[:, :2])

从这些分数可以画出双标图,当使用特征分解时,将返回与上面相同的结果。查看代码了解全部细节。

摘要

在这篇文章中,我们讨论了 PCA,以及如何使用它来更清楚地了解数据集特征之间的关系,同时消除不必要的噪声。我们经历了每一步,也讨论了不同的计算方法。我希望这篇文章能对您未来的数据科学工作有所帮助。

原载于 2020 年 4 月 25 日 datasciencesamurai.com

加入我的邮件列表,了解更多关于数据科学的知识。

处理预测分析问题的一步一步的过程

原文:https://towardsdatascience.com/a-step-by-step-process-to-deal-with-a-predictive-analytical-problem-bee174b68653?source=collection_archive---------33-----------------------

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

马库斯·斯皮斯克在 Unsplash 上的照片

W 什么是机器学习项目?什么是真正的预测分析问题陈述?我们该如何解决这个问题?这些问题将在本文中得到解答,一些新颖的问题将会被提出,这将有助于我们更好地理解和更准确地解决问题

基本上,使用一些以前的信息,对未来的预测是机器学习模型的基础。提取信息和生成趋势的过程被称为训练或建模,讲述未来被称为预测。ML 模型包括各种步骤,如探索性数据分析、处理数据、特征工程、训练、预测、模型评估,以及我们如何改进我们的性能。我们将经历创建任何模型的非常基本的结构,并理解基本术语的含义。

数据

通常,我们的数据集是以一个 CSV (逗号分隔文件)或一个 Excel 文件或一个文本文件或图像和声音的形式给出的。

例如, CVS 文件或 Excel 文件有行和列。行基本上是一个观察,列是决定我们目标的特征。对于其他类型,我们需要通过一些规定的方法来提取特征信息,如定义图像包含像素值的三维矩阵,该矩阵可以转换为二维矩阵,用于训练深度学习模型。

但是为了方便起见,让我们考虑一下我们想要预测房价,你认为影响房价的基本因素是什么?(将在文章后面回答)

第一步:问题陈述

非常非常仔细地阅读问题陈述。大多数人和不成功的数据科学家都会犯这个错误。阅读问题是非常关键的一步,因为从中可以提取很多信息。

一旦你读完了,问自己这些基本问题

  1. 有什么问题?
  2. 为什么需要解决这个问题
  3. 怎样才能解决问题?

我发现回答这些问题对于理解这个问题非常重要。我们可以使用有史以来最好的算法来获得最高的准确性,但如果我们解决了错误的问题,这将毫无意义。

这些问题不仅会向我们介绍一个问题,还会帮助我们理解和验证收集的数据,并改进结果。

步骤 2:假设生成

一旦你阅读了问题陈述,是时候利用我们的知识和经验来列出目标变量所依赖的因素了。这是一种头脑风暴。它让我们知道哪些因素是重要的,而哪些不是,这可以在稍后的 EDA 部分中证明。我们在预测房价。那么,它依赖于什么?可能是位置,大小,房子的年龄,房间的数量,中央空调的存在,停车场的可用性,该地区的人口密度,等等。也许房子的颜色也很重要?嗯,这些答案都可以找出来。

人们应该钦佩这一步是多么重要。这个过程是初学者的必经过程。在第一步,这不是准确性,我们的意图应该是成为一个好的数据科学家,而不仅仅是一个问题解决者!

第三步:阅读和理解

阅读你的数据,让自己适应它。阅读你的数据的中心趋势。问问自己什么是连续特征,什么是分类特征,是否有任何缺失值,涉及什么数据类型等。

步骤 4:探索性数据分析(EDA)

有两种类型的可视化分析,即单变量分析和双变量分析,

单变量分析:

它由一次一个特征的可视化组成。这些可以用来了解我们的连续特征是如何分布的,有没有异常值或者缺失值?对于分类特征,我们可以提取每个类别的数量。主要是,直方图箱线图用于连续特征的情况,而计数图用于分类数据。

双变量分析:

当我们用目标变量来检验每个特征的趋势时,我们称之为双变量分析。数据是如何关联的,每个特征对目标变量的影响是什么,这些都是分析中回答的基本问题。
在对不同的特征、趋势和模式对进行双变量分析时,可以生成缺失值的插补。
对于连续-连续特征,我们使用散点图。它告诉我们特征之间的线性关系有多强。对于连续分类,我们使用 violin 图,因为它们包含了特征的范围和分布。对于分类-分类,我们可以使用在 Pandas 库中预定义的跨表方法

第五步:特征工程

这是建模过程中最具创造性和决定性的因素。但是由于每一个难题都可以被分解成更小的简单问题,这也可以制定为两个主要部分,即。特征生成编码

特征生成是从现有特征生成新特征的过程。例如,给出一个字符串日期特征,可以提取关于年和月的信息。另一个很好的例子是,当预测一个商场的销售额时,价格和重量是可以给出的特征,我们可以生成新的特征,即每单位重量的价格。这有助于我们减少数据的维度,同时保持数据的质量。

在所有上述过程之后,我们的数据集已准备好进行模型构建,但问题是大多数机器学习算法无法读取诸如男性、女性、否、是等分类值。我们使用编码方法将它们转换成数值。这主要涉及标签编码、一键编码、计数编码等

步骤 6:建模和评估

这一步是关于机器学习算法的选择和我们的训练数据对它的拟合。选择算法取决于问题是分类的还是回归的,是有监督的还是无监督的。有各种型号可供选择。

线性算法:

梯度下降,线性回归,逻辑回归,线性判别分析

非线性算法:

分类和回归树,朴素贝叶斯,K 近邻,学习矢量量化,支持向量机

集成算法:

装袋和随机森林、Boosting 和 AdaBoost

在使用算法将训练数据拟合到模型之后,我们对新数据进行一些预测,这对于模型来说是新的。

许多算法可以预测,但问题是哪一个是最好的?因此,我们需要评估我们的模型。目前,有各种方法来评估我们的模型,如 MSE、MAE、roc-curve、f1-score、log loss 等等。

Scikit Learn 的备忘单

下面的流程图旨在为用户提供一点粗略的指导,告诉他们如何处理关于使用哪些估计器来处理数据的问题。

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

来源:Scikit 学习算法备忘单:https://scikit-learn.org/stable/_static/ml_map.png

总结一下:

对于任何问题来说,这都是一个非常基础和幼稚的方法,但是对于初学者来说已经足够好了。一旦你掌握了这些步骤,并对预测建模有所了解,你可以从几个方面着手提高你的技能。

请分享你对这篇文章的看法,我很想听听!

进行情感分析的分步指南

原文:https://towardsdatascience.com/a-step-by-step-tutorial-for-conducting-sentiment-analysis-9d1a054818b6?source=collection_archive---------18-----------------------

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

Unsplash 上的hkon grim stad拍摄的照片

第 2 部分:用 TFIDF 矢量器转换文本数据

在我的上一篇文章中,我讨论了进行情感分析的第一步,即预处理文本数据。这个过程包括标记化、去除停用词和词条化。在本文中,我将讨论将“干净的”文本数据转换成稀疏矩阵的过程。具体来说,我将通过简单的例子讨论不同矢量器的使用。

在我们进入更多的技术之前,我想介绍两个在文本分析中广泛使用的术语。对于我们想要分析的文本数据集合,我们称之为语料库。一个语料库包含几个观察结果,如新闻文章、顾客评论等。这些观察结果中的每一个都被称为文档。从现在开始我将使用这两个术语。

转换步骤的作用是搭建一座桥梁,连接文本数据中携带的信息和机器学习模型。对于情感分析,要对每个文档进行情感预测,机器学习模型需要学习文档中每个唯一单词的情感得分,以及每个单词在那里出现的次数。例如,如果我们想要对某个产品的客户评论进行情感分析,在训练模型之后,机器学习模型更有可能从负面评论中提取像“糟糕”、“不满意”这样的词,而从正面评论中获得像“棒极了”、“棒极了”这样的词。

面对有监督的机器学习问题,为了训练模型,我们需要指定特征和目标值。情感分析是在解决一个分类问题,大多数情况下是一个二元分类问题,目标值定义为正和负。用于模型的特征是来自矢量器的转换的文本数据。不同的矢量器构造的特征也不同。在 Scikit Learn 中,有三个矢量器,CountVectorizer、TFIDFVectorizer 和 HashingVectorizer。我们先来讨论一下 CountVectorizer。

计数矢量器

CountVectorizer 使用单词包方法,该方法忽略文本结构,只从单词计数中提取信息。它会将每个文档转换成一个向量。向量的输入是这个文档中每个唯一单词的出现次数。当语料库中有 m 个文档,并且所有 m 个文档中有 n 个唯一单词时,CountVectorizer 会将文本数据转换为 m*n 稀疏矩阵。以下示例显示了计数矢量器的用法:

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

CountVectorizer 获取文档列表,并通过两步生成稀疏矩阵:拟合和转换。在拟合过程中,矢量器读入文档列表,计算语料库中唯一单词的数量,并为每个单词分配一个索引。对于上面的例子,我们可以看到这两个文档有六个不同的单词,我们根据字母顺序给它们分配了一个索引。请注意,您可以在这里指定停用字词来排除无用的字词。您可以使用默认列表,也可以自定义列表。或者如果已经对文本数据进行了预处理,就可以通过这一步。

下一步是转换拟合的数据。CountVectorizer 将计算每个文档中每个唯一单词的出现次数。这里我有两个文档和六个唯一的单词,因此我们将得到一个如上所示的 2*6 矩阵。为了更好地理解矩阵的元素,这里我有一个图表:

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

这里,行 id 与每个文档相对应,列 id 在匹配过程中跟随唯一单词的索引。例如,单词“day”在两个文档中都出现了,所以第一列输入是(1,1)。如果某个单词没有出现在文档中,则该单词在该文档行中的输入将为 0。随着文档数量的增加,矩阵变成稀疏矩阵,因为矩阵中会有更多的 0。

tfidf 矢量器

另一个更广泛使用的矢量器是 TFIDFVectorizer,TFIDF 是术语频率,逆文档频率的缩写。除了每个文档中的字数,TFIDF 还包括该单词在其他文档中的出现次数。具体来说,TFIDF 的计算公式如下:

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

其中 t_i,wj 是单词 wj 在文档 I 中出现的频率。通过检查等式,可以清楚地看到,第一项是计算术语频率,第二项是计算逆文档频率。第一项是评估单词 wj 在文档 I 中出现了多少次,用文档 I 的长度归一化。较高的词频率指示较高的 TFIDF 值,表明单词 wj 通过出现显著的次数而在文档 I 中扮演非常重要的角色。但是如果 wj 也出现在 I 之外的很多其他文档中,wj 的作用就会减弱,也就是说它是这个题目的常用词。这个过程被第二项捕获,第二项是 wj 出现的文档数除以文档总数的倒数。综合两种效果,文档 I 中 TFIDF 值高的一个词 wj,意味着 wj 在文档 I 中出现多次,在其他文档中只出现很少。

使用前一个示例的 TFIDF,区别如下:

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

我们可以看到每个元素的值都变小了,但是矩阵的形状还是一样的。

哈希矢量器

另一种常用的矢量器叫做哈希矢量器。它通常在处理大型数据集时使用。使用特征散列,散列矢量器是内存高效的,并确保大型数据集的更好的模型性能。在这篇文章里我不会讲太多细节,但是你可以在这里查阅更多信息

附加功能输入

除了指定和定制停用词,我们还可以定制矢量器中的标记化功能。正如我在上一篇文章中所讨论的,在这里包含定制的 tokenize 函数会减慢矢量化过程。

在前面的例子中,我们正在构建只有单个单词的稀疏矩阵,我们可以通过包含二元模型来增加特征的数量。我们可以通过在函数中添加 ngram_range 来在函数中指定它。这里有一个例子:

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

通过包含 bigram,特性的数量从 6 个增加到 11 个。有时,当我们在文档中有“不错”这样的词时,包含 bigram 会提高模型性能。

您还可以在矢量函数中指定 min_dfmax_df 。通过指定一个单词在不同的文档中出现多少次才能被认为是一个特征,我们过滤掉在语料库中不太常见的单词。此外,当设置一个单词在不同文档中出现的次数限制(max_df)时,我们忽略了太常见的内容,比如停用词。在不同场景中定制矢量器函数输入应该会提高模型性能。

了解矢量器的定制选项非常有用。更多选择,你可以访问每个矢量器的 sklearn 文档。为了确保最佳的模型性能,我们可以使用 GridSearchCV 来调整变压器的超参数。在我的下一篇文章中,我将讨论在我的项目中应用 TFIDF 的更多细节,并构造估计器。

感谢您的阅读!这是我所有博客帖子的列表。如果你感兴趣的话,可以去看看!

[## 我的博客文章库

我快乐的地方

zzhu17.medium.com](https://zzhu17.medium.com/my-blog-posts-gallery-ac6e01fe5cc3) [## 阅读朱(以及媒体上成千上万的其他作家)的每一个故事

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

zzhu17.medium.com](https://zzhu17.medium.com/membership)

进行情感分析的分步指南

原文:https://towardsdatascience.com/a-step-by-step-tutorial-for-conducting-sentiment-analysis-a7190a444366?source=collection_archive---------6-----------------------

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

科塞拉·博尔塔在 Unsplash 上的照片

第 1 部分:预处理文本数据

据估计,全球 80%的数据是非结构化的。因此,从非结构化数据中获取信息是数据分析的重要组成部分。文本挖掘是从非结构化的文本数据中获取有价值见解的过程,情感分析是文本挖掘的一个应用。它使用自然语言处理和机器学习技术从文本数据中理解和分类主观情绪。在商业环境中,情感分析广泛用于理解客户评论、检测电子邮件中的垃圾邮件等。本文是教程的第一部分,介绍了使用 Python 进行情感分析的具体技术。为了更好地说明这个过程,我将使用我的一个项目作为例子,在那里我对 WTI 原油期货价格进行新闻情绪分析。我将展示重要的步骤以及相应的 Python 代码。

一些背景信息

原油期货价格短期波动较大。虽然任何产品的长期均衡都是由供求状况决定的,但价格的短期波动反映了市场对该产品的信心和预期。在这个项目中,我使用原油相关的新闻文章来捕捉不断更新的市场信心和预期,并通过对新闻文章进行情绪分析来预测原油未来价格的变化。以下是完成此分析的步骤:

1、收集数据:网络抓取新闻文章

2、预处理文本数据(本文)

3、文本矢量化:TFIDF

4、使用逻辑回归的情感分析

5、使用 python flask web app 在 Heroku 部署模型

我将讨论第二部分,即本文中的文本数据预处理。如果您对其他部分感兴趣,请点击链接阅读更多内容(即将推出)。

预处理文本数据

我使用 NLTK、Spacy 和一些正则表达式中的工具对新闻文章进行预处理。要导入库并在 Spacy 中使用预构建的模型,您可以使用以下代码:

import spacy
import nltk# Initialize spacy ‘en’ model, keeping only component needed for lemmatization and creating an engine:nlp = spacy.load(‘en’, disable=[‘parser’, ‘ner’])

之后,我用熊猫来读取数据:

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

“Subject”和“Body”是我将对其应用文本预处理过程的列。我按照标准的文本挖掘程序对新闻文章进行预处理,从新闻内容中提取有用的特征,包括标记化、去除停用词和词条化。

标记化

预处理文本数据的第一步是将每一个句子分解成单个的单词,这就是所谓的标记化。采用单个单词而不是句子会破坏单词之间的联系。但是,这是一种用于分析大量文本数据的常用方法。通过检查什么词在文章中出现以及这些词出现了多少次,计算机分析文本数据是高效和方便的,并且足以给出有见地的结果。

以我的数据集中的第一篇新闻文章为例:

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

您可以使用 NLTK 标记器:

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

或者您可以使用 Spacy,记住 NLP 是上面定义的 Spacy 引擎:

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

需要将每个令牌改为字符串变量

在标记化之后,每篇新闻都将转化为一系列单词、符号、数字和标点符号。您可以指定是否要将每个单词都转换成小写。下一步是删除无用的信息。例如,符号、数字、标点符号。我将使用 spacy 结合正则表达式来删除它们。

import re#tokenization and remove punctuations
words = [str(token) for token in nlp(text) if not token.is_punct] #remove digits and other symbols except "@"--used to remove email
words = [re.sub(r"[^A-Za-z@]", "", word) for word in words]#remove websites and email address
words = [re.sub(r”\S+com”, “”, word) for word in words]
words = [re.sub(r”\S+@\S+”, “”, word) for word in words]#remove empty spaces 
words = [word for word in words if word!=’ ‘]

应用上述转换后,原始新闻文章看起来是这样的:

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

停用词

经过一些改造后,新闻文章更干净了,但我们仍然会看到一些我们不希望看到的词,例如,“和”,“我们”等。下一步是删除无用的词,即停用词。停用词是在许多文章中频繁出现但没有重要意义的词。停用词的例子有’ I ‘,’ the ‘,’ a ‘,’ of '。这些词如果被删除,将不会影响对文章的理解。要删除停用词,我们可以从 NLTK 库中导入停用词。除此之外,我还包括其他在经济分析中广泛使用的停用词列表,包括日期和时间,更一般的没有经济意义的词等。我是这样构造停用词列表的:

#import other lists of stopwords
with open(‘StopWords_GenericLong.txt’, ‘r’) as f:
 x_gl = f.readlines()
with open(‘StopWords_Names.txt’, ‘r’) as f:
 x_n = f.readlines()
with open(‘StopWords_DatesandNumbers.txt’, ‘r’) as f:
 x_d = f.readlines()#import nltk stopwords
stopwords = nltk.corpus.stopwords.words(‘english’)#combine all stopwords
[stopwords.append(x.rstrip()) for x in x_gl][stopwords.append(x.rstrip()) for x in x_n][stopwords.append(x.rstrip()) for x in x_d]#change all stopwords into lowercase
stopwords_lower = [s.lower() for s in stopwords]

然后从新闻文章中排除停用词:

words = [word.lower() for word in words if word.lower() not in stopwords_lower]

应用到前面的例子,它看起来是这样的:

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

词汇化

除去停用词、符号、数字和标点符号,每篇新闻文章都将转化为一系列有意义的单词。然而,要统计每个单词的出现次数,就必须去除语法时态,将每个单词转换为其原始形式。例如,如果我们想计算单词“open”在一篇新闻文章中出现了多少次,我们需要计算“open”、“opens”、“opened”的出现次数。因此,词汇化是文本转换的一个重要步骤。另一种将单词转换成原始形式的方法叫做词干提取。它们之间的区别如下:

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

词干化是将一个单词提取到它的原始词干中,词干化是提取一个单词的语言学词根。我选择词汇化而不是词干化,因为词干化之后,一些单词变得难以理解。为了解释的目的,引理比语言根更好。

如上所示,用 Spacy 实现引理化非常容易,这里我调用。引理 _ 函数从空间开始。在词汇化之后,每篇新闻文章都将转化为一个单词列表,这些单词都是它们的原始形式。新闻报道现在变成了这样:

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

总结步骤

让我们总结一个函数中的步骤,并在所有文章中应用该函数:

def text_preprocessing(str_input):      #tokenization, remove punctuation, lemmatization
     words=[token.lemma_ for token in nlp(str_input) if not         token.is_punct]

     # remove symbols, websites, email addresses 
     words = [re.sub(r”[^A-Za-z@]”, “”, word) for word in words] 
     words = [re.sub(r”\S+com”, “”, word) for word in words]
     words = [re.sub(r”\S+@\S+”, “”, word) for word in words] 
     words = [word for word in words if word!=’ ‘]
     words = [word for word in words if len(word)!=0] 

     #remove stopwords     
     words=[word.lower() for word in words if word.lower() not in     stopwords_lower] #combine a list into one string   
     string = “ “.join(words) return string

上面的函数 text_preprocessing()结合了所有的文本预处理步骤,这里输出的是第一篇新闻文章:

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

在推广到所有新闻文章之前,按照下面的代码,将它应用到随机的新闻文章中并看看它是如何工作的是很重要的:

import randomindex = random.randint(0, df.shape[0])
text_preprocessing(df.iloc[index][‘Body’])

如果有一些额外的词你想排除这个特定的项目或一些额外的多余信息你想删除,你可以随时修改该功能之前,适用于所有的新闻文章。这是一篇在标记化前后随机选择的新闻文章,去掉了停用词和词条。

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

预处理前的新闻文章

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

预处理后的新闻文章

如果一切正常,您可以将该功能应用于所有新闻文章:

df[‘news_cleaned’]=df[‘Body’].apply(text_preprocessing)
df[‘subject_cleaned’]=df[‘Subject’].apply(text_preprocessing)

一些言论

文本预处理是文本挖掘和情感分析中非常重要的一部分。有很多方法可以对非结构化数据进行预处理,使其对计算机可读,以便将来进行分析。下一步,我将讨论我用来将文本数据转换成稀疏矩阵的矢量器,以便它们可以用作定量分析的输入。

如果您的分析很简单,并且在预处理文本数据时不需要太多的定制,那么矢量器通常有嵌入式函数来执行基本步骤,比如标记化、删除停用词。或者,您可以编写自己的函数并在矢量器中指定自定义函数,这样您就可以同时对数据进行预处理和矢量化。如果您希望这样,您的函数需要返回一个标记化单词的列表,而不是一个长字符串。不过个人来说,我更倾向于先对文本数据进行预处理,再进行矢量化。通过这种方式,我不断地监控我的函数的性能,实际上这样更快,尤其是当你有一个大的数据集的时候。

我将在我的下一篇文章中讨论转换过程。感谢您的阅读!这是我所有博客帖子的列表。如果你感兴趣的话,可以去看看!

[## 我的博客文章库

我快乐的地方

zzhu17.medium.com](https://zzhu17.medium.com/my-blog-posts-gallery-ac6e01fe5cc3) [## 阅读朱(以及媒体上成千上万的其他作家)的每一个故事

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

zzhu17.medium.com](https://zzhu17.medium.com/membership)

进行情感分析的分步指南

原文:https://towardsdatascience.com/a-step-by-step-tutorial-for-conducting-sentiment-analysis-cf3e995e3171?source=collection_archive---------24-----------------------

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

马库斯·温克勒在 Unsplash 上的照片

第三部分:最后一步,应用逻辑回归

按照我以前文章中的步骤,我对文本数据进行了预处理,并且将“清理”后的数据转换为稀疏矩阵。请点击链接查看更多详情。

现在我正处于对 WTI 原油期货价格进行新闻情绪分析的最后阶段。在本文中,我将讨论逻辑回归的使用,以及我在项目中发现的一些有趣的结果。我这里有一些这个项目的背景介绍

定义并构建目标值

正如我在以前的文章中简要讨论的那样,进行情感分析是通过机器学习模型和文本数据来解决分类问题(通常是二元的)。解决一个分类问题就是解决一个有监督的机器学习问题,在训练模型的时候既需要特征也需要目标值。如果是二元分类问题,目标值通常是正面情绪和负面情绪。它们是根据你的研究问题的上下文来分配和详细定义的。

以我的项目为例,我的项目的目的是从最近发布的新闻文章中预测原油期货价格的变化。我把好消息定义为预测价格上涨的消息,而坏消息则预测价格下跌。因为我已经收集并转换了文本数据,并将它们用作要素,所以现在需要为数据集分配目标值。

我的项目的目标值是不同新闻文章的价格变化方向。我从彭博收集了 WTI 原油期货收盘价的高频交易数据,每五分钟更新一次。我将数据绘制在下图中:

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

资料来源:彭博

数据是 2019 年最后一个季度的。价格有很多波动,但是没有明显的趋势,非常适合情绪分析。这里的价格数据是一个连续变量,我需要将它转换成一个带有二进制值的分类变量,以便进行情感分析。

假设金融市场是完全有效的,并且市场对新信息的反应足够快,我定义新闻对 WTI 原油期货价格的影响在新闻发布后的五分钟内得到反映。我建立了一个虚拟变量:如果一篇新闻文章发布后五分钟内价格上涨,价格虚拟变量将是 1。否则,如果价格下降或不变,虚拟价格将为零。在整个数据集的五分钟时间段内,价格几乎不可能保持不变。因此,当虚拟价格等于零时,意味着价格在新闻发布后的五分钟内下降。

对于每篇新闻文章,通过寻找发布后五分钟内的价格变化,本文将新闻和价格虚拟进行匹配。下图显示,通过比较价格上涨事件和价格下跌事件的数量,数据大致平衡:

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

引入逻辑回归

在构建目标值之后,我已经为每篇新闻文章准备好了文本特征(TFIDF 矢量化文本数据)和价格虚拟数据。现在我需要应用一个估计器来建立机器学习模型。解决二元分类问题的模型有很多,这里我选择的是 logistic 回归。

逻辑回归是一个线性分类器,它是一个线性函数的转换:

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

线性回归

其中 b0,b1…bn 是一组独立变量 x =(x_1,x_2…x_n)的回归系数的估计值。逻辑回归函数 p( x )是 f( x )的 sigmoid 函数:

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

sigmoid 变换

变换后 p( x )的值会在[0,1]之间,可以解释为一个概率。一般 p( x )解释为 x 在正类时的预测概率,1-p( x )是 x 在负类的概率。在本项目中,p( x )定义为新闻文章 I 发布后五分钟内 WTI 原油期货价格上涨的概率。

应用逻辑回归进行新闻情感分析,我将每篇新闻文章视为一个观察,将新闻文章中的内容视为特征,并通过以下等式估计β_w0,β_w1,… β_wj:

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

这里 I 代表每篇新闻文章作为观察,wj 是所有新闻文章中第 j 个唯一的词。在左边,Y_i 是上一节描述的价格变化虚拟值。具体而言,Y 的值由以下条件决定:

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

虚拟价格

在右边,第一项是一个稀疏矩阵,每行代表一篇新闻文章,每列代表一个独特的单词。在 4616 篇新闻文章中出现过超过 20,606 个独特的单词,它们表明了稀疏矩阵的形状。稀疏矩阵的每个值 X_{i,wj}被表示为每个新闻文章 I 中每个唯一单词 wj 的 TFIDF 值,有关 TFIDF 变换的更多详细信息,请查看我的上一篇文章

实施逻辑回归

为了实现逻辑回归和训练模型,我首先将数据集分为训练集和测试集。“df[‘news’]”这里是“干净的”新闻文章,“df[‘price’]”是作为目标值的价格虚拟。为了找到最好的转换器和最好的估计器,我建立了一个机器学习管道,并使用 GridSearchCV 来找到最好的超参数。我在此附上代码供您参考:

#train and test split
X_train, X_test, y_train, y_test = train_test_split(df['news'], 
                                                    df['price'], 
                                                    random_state=0)#build a machine learning pipeline
est = Pipeline([(‘vectorizer’, TfidfVectorizer(lowercase=False)),
 (‘classifier’, LogisticRegression(solver=’liblinear’))])#GridSearchCV with a transformer and a estimator
parameters = {‘vectorizer__max_df’: (0.8,0.9), 
 ‘vectorizer__min_df’: [20,50,0.1],
 “classifier__C”:np.logspace(-3,3,7), 
 “classifier__penalty”:[“l1”,”l2"]}gs=GridSearchCV(est,param_grid=parameters)#fit the training data
gs.fit(X_train, y_train)#Evaluate the model
predictions = model.predict(vect.transform(X_test))
print('AUC: ', roc_auc_score(y_test, predictions))
AUC:  0.719221201684

如果没有指定,GridSearchCV 将寻找为模型评估生成最高精度的超参数。有时候,准确性不是评估模型的最佳指标,我们可能会使用其他指标。您可以通过在 GridSearchCV 函数中定义“计分”输入来指定它。对于如何选择合适的度量标准,我有一篇文章《模型评估分类度量标准终极指南》详细回答了这个问题。

我使用 AUC 作为我的模型度量,它在我的测试集中达到 0.71。鉴于我必须训练模型的观察数量(超过 4000 篇新闻文章),我相信模型已经准备好部署了。

有趣的发现

按照前面的步骤,我估计了每个唯一单词的系数(βs)。总的来说,我得到了超过 20,000 个独特的单词,下面的图显示了每个独特的单词的β:

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

x 轴上的每个点代表从所有新闻文章中收集的一个独特的词,总共有 20606 篇。y 轴代表每个单词的符号和系数的大小。该图表明,大多数独特词本身对价格的影响非常有限,其系数非常接近于零。但是,有一些词的系数绝对值超过 0.5,它们在估计价格变化时非常具有预测性。

使用 Python 单词云函数,根据系数的值,我绘制了预测不同方向价格变化的最积极和最消极的单词。字体越大,表示预测价格变化的影响越大。

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

部署在 Heroku

在构建和评估模型之后,我将模型实现为 Flask web 应用程序,并将其部署在 Heroku:

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

在“新闻正文”框中,您可以粘贴任何新闻文章并按“提交”,然后模型将预测该新闻文章的情绪,即该新闻发布后价格上涨的概率。

构建 web 应用程序需要在线部署训练好的模型,并根据新的输入进行预测。除了用 Python 编码来构建机器学习模型和构造 flask app,还需要一些 web app 的 HTML 背景知识。以后我会写一个关于部署机器学习模型的教程。

在 web 应用程序中,也有一些关于我的项目的解释性数据分析和其他有趣的发现。请随意查看并在这里玩。

这都是为了进行情感分析。如果您有任何意见或问题,请随时联系我。感谢您的阅读!

这是我所有博客帖子的列表。如果你感兴趣的话,可以去看看!

[## 我的博客文章库

我快乐的地方

zzhu17.medium.com](https://zzhu17.medium.com/my-blog-posts-gallery-ac6e01fe5cc3) [## 阅读朱(以及媒体上成千上万的其他作家)的每一个故事

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

zzhu17.medium.com](https://zzhu17.medium.com/membership)

构建和部署影像分类 API 的分步教程

原文:https://towardsdatascience.com/a-step-by-step-tutorial-to-build-and-deploy-an-image-classification-api-95fa449f0f6a?source=collection_archive---------7-----------------------

从使用 Labelme 的数据注释到使用 FastApi+Docker 的部署的所有步骤

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

图恩·nguyễn·明在 Unsplash 上拍摄的照片

在这个小项目中,我们的目标是从头开始构建一个图像分类 API。
我们将经历实现这一目标所需的所有步骤:

  • 数据注释(使用 Unsplash API + Labelme)
  • 模型训练(使用 Tensorflow)
  • 制作 API(使用 Uvicorn 和 FastApi)
  • 在远程服务器上部署 API(使用 Docker 和 Google 云平台)

数据注释:

任何机器学习项目最重要的部分之一是注释数据的质量和数量。这是部署 API 时影响预测质量的关键因素之一。

在这个项目中,我们将尝试将输入图像分为四类:

  • 城市
  • 海滩
  • 日落
  • 树木/森林

我选择这些课程是因为很容易在网上找到大量代表它们的图片。我们使用这些类来定义多标签分类问题:

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

来自https://unsplash.com/的输入和目标/图像示例

现在我们已经定义了我们想要解决的问题,我们需要获得足够数量的标记样本来进行训练和评估。
为了做到这一点,我们将首先使用 Unsplash API 来获取给定多个搜索查询的图像的 URL。

# First install [https://github.com/yakupadakli/python-unsplash](https://github.com/yakupadakli/python-unsplash)
# Unsplash API [https://unsplash.com/documentation](https://unsplash.com/documentation)
import json
import osfrom unsplash.api import Api
from unsplash.auth import Authwith open('tokens.json', 'r') as f:
    data = json.load(f)client_id = data['client_id']
client_secret = data['client_secret']redirect_uri = ""
code = ""keyword = 'beach'auth = Auth(client_id, client_secret, redirect_uri, code=code)
api = Api(auth)photos = api.search.photos(keyword, per_page=1000, page=i)['results']for photo in photos:
    print(photo)
    print(photo.id)
    print(photo.urls)
    print(photo.urls.small)

我们将尝试获取与我们的目标类相关的图像 URL,加上一些其他随机图像,作为反面例子。

下一步是遍历所有的图像,并给每一个图像分配一组标签,如上图所示。为此,使用专为此任务设计的注释工具总是更容易,例如 LabelMe,它是一个 python 库,您可以从命令行轻松运行:

labelme . -flags labels.txt

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

Labelme 用户界面

使用 Labelme 我标记了大约一千张图片,并在这里提供了 urls 标签:https://github.com/CVxTz/ToyImageClassificationDataset

模型

现在我们有了标记的样本,我们可以尝试使用 Tensorflow 构建一个分类器。我们将使用 MobileNet_V2 作为分类器的主干,因为它速度快,而且不太可能过度拟合。鉴于我们只有少量的标记样本,您可以通过从 keras_applications 导入它来轻松使用它:

from tensorflow.keras.applications import MobileNetV2base_model = MobileNetV2(include_top=False, input_shape=input_shape, weights=weights)

由于这是一个具有四个类别的多标签分类问题,我们将有一个具有 Sigmoid 激活的四个神经元的输出层(给定一个示例,我们可以将多个神经元激活或没有神经元激活作为目标)

迁移学习

解决标记样本缺乏的一个常用技巧是使用迁移学习。它是当你把从源任务(像带有不同标签集的图像分类)中学到的一些权重转移到你的目标任务,作为你训练的起点。与从随机开始相比,这允许更好的初始化,并且允许为我们的多标签分类重用在源任务上学习的一些表示。

这里我们将转移在 ImageNet 中训练得到的权重。在为 MobileNet_V2 使用 Tensorflow+Keras 时,做到这一点非常容易,您只需要在创建 MobileNetV2 的实例时指定 weights="imagenet "

base_model = MobileNetV2(include_top=False, input_shape=input_shape, weights="imagenet")

数据扩充

当有一小组带注释的样本时,提高性能的另一个技巧是进行数据扩充。应用随机扰动的过程保留了标签信息(扰动后的城市图片看起来仍然像一个城市)。一些常见的变换是垂直镜像、椒盐噪声或模糊。

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

数据扩充示例/图片来自https://unsplash.com/

为了实现这一点,我们使用了一个名为 imgaug 的 python 包,并定义了一系列变换及其幅度:

sometimes = **lambda** aug: iaa.Sometimes(0.1, aug)
seq = iaa.Sequential(
    [
        sometimes(iaa.Affine(scale={**"x"**: (0.8, 1.2)})),
        sometimes(iaa.Fliplr(p=0.5)),
        sometimes(iaa.Affine(scale={**"y"**: (0.8, 1.2)})),
        sometimes(iaa.Affine(translate_percent={**"x"**: (-0.2, 0.2)})),
        sometimes(iaa.Affine(translate_percent={**"y"**: (-0.2, 0.2)})),
        sometimes(iaa.Affine(rotate=(-20, 20))),
        sometimes(iaa.Affine(shear=(-20, 20))),
        sometimes(iaa.AdditiveGaussianNoise(scale=0.07 * 255)),
        sometimes(iaa.GaussianBlur(sigma=(0, 3.0))),
    ],
    random_order=**True**,
)

培养

我们将数据集分为两部分,训练和验证,并使用 binary_crossentropy 作为我们的目标,binary_accuracy 作为评估度量。

在更新一些配置文件后,我们从命令行运行培训:

# data_config.yaml for defnining the classes and input size **input_shape**: [null, null, 3]
**resize_shape**: [224, 224]
**images_base_path**: **'../example/data/'
targets**: [**'beach'**, **'city'**, **'sunset'**, **'trees'**]
**image_name_col**: **'name'**# training_config.yaml for defining some training parameters **use_augmentation**: true
**batch_size**: 32
**epochs**: 1000
**initial_learning_rate**: 0.0001
**model_path**: **"image_classification.h5"**

然后运行训练脚本:

**export PYTHONPATH=$PYTHONPATH:~/PycharmProjects/FastImageClassification/****python train.py --csv_path "../example/data.csv" \
       --data_config_path "../example/data_config.yaml" \
       --training_config_path "../example/training_config.yaml"**

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

我们最终得到的二进制验证准确率为 94%

制作 API

我们将使用 FastAPI 通过一个易于使用的 API 来公开一个预测器,该 API 可以将一个图像文件作为输入,并输出一个包含每个类的分类分数的 JSON。

首先,我们需要编写一个预测器类,它可以轻松地加载 tensorflow.keras 模型,并有一个方法来对文件对象形式的图像进行分类。

**class** ImagePredictor:
    **def** __init__(
        self, model_path, resize_size, targets, pre_processing_function=preprocess_input
    ):
        self.model_path = model_path
        self.pre_processing_function = pre_processing_function
        self.model = load_model(self.model_path)
        self.resize_size = resize_size
        self.targets = targets @classmethod
    **def** init_from_config_path(cls, config_path):
        **with** open(config_path, **"r"**) **as** f:
            config = yaml.load(f, yaml.SafeLoader)
        predictor = cls(
            model_path=config[**"model_path"**],
            resize_size=config[**"resize_shape"**],
            targets=config[**"targets"**],
        )
        **return** predictor @classmethod
    **def** init_from_config_url(cls, config_path):
        **with** open(config_path, **"r"**) **as** f:
            config = yaml.load(f, yaml.SafeLoader) download_model(
            config[**"model_url"**], config[**"model_path"**], config[**"model_sha256"**]
        ) **return** cls.init_from_config_path(config_path) **def** predict_from_array(self, arr):
        arr = resize_img(arr, h=self.resize_size[0], w=self.resize_size[1])
        arr = self.pre_processing_function(arr)
        pred = self.model.predict(arr[np.newaxis, ...]).ravel().tolist()
        pred = [round(x, 3) **for** x **in** pred]
        **return** {k: v **for** k, v **in** zip(self.targets, pred)} **def** predict_from_file(self, file_object):
        arr = read_from_file(file_object)
        **return** self.predict_from_array(arr)

我们可以使用一个配置文件来实例化一个 predictor 对象,该对象具有进行预测的所有参数,并将从项目的 GitHub 存储库中下载模型:

**# config.yaml
resize_shape**: [224, 224]
**targets**: [**'beach'**, **'city'**, **'sunset'**, **'trees'**]
**model_path**: **"image_classification.h5"
model_url**: **"https://github.com/CVxTz/FastImageClassification/releases/download/v0.1/image_classification.h5"
model_sha256**: **"d5cd9082651faa826cab4562f60e3095502286b5ea64d5b25ba3682b66fbc305"**

完成所有这些之后,当使用 FastAPI 时,我们的 API 的主文件变得微不足道:

**from** fastapi **import** FastAPI, File, UploadFile**from** fast_image_classification.predictor **import** ImagePredictorapp = FastAPI()predictor_config_path = **"config.yaml"**predictor = ImagePredictor.init_from_config_url(predictor_config_path) @app.post(**"/scorefile/"**)
**def** create_upload_file(file: UploadFile = File(...)):
    **return** predictor.predict_from_file(file.file)

我们现在可以用一个命令运行应用程序:

uvicorn main:app --reload

这使我们能够访问 Swagger UI,在那里我们可以在一个新文件上尝试我们的 API。

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

http://127 . 0 . 0 . 1:8080/docs

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

Antonio ResendizUnsplash 上拍摄的照片

上传上面的图像会产生以下输出:

{"beach": **0**,"city": **0**.**999**,"sunset": **0**.**005**,"trees": **0** }

这是预期的输出!

我们还可以通过 curl 发送请求并计时:

time curl -X POST "[http://127.0.0.1:8080/scorefile/](http://127.0.0.1:8000/scorefile/)" -H  "accept: application/json" -H  "Content-Type: multipart/form-data" -F "file=[@antonio](http://twitter.com/antonio)-resendiz-VTLqQe4Ej8I-unsplash.jpg;type=image/jpeg">> {"beach":0.0,"city":0.999,"sunset":0.005,"trees":0.0}
>> real 0m0.209s
>> user 0m0.012s
>> sys 0m0.008s

部署应用程序

码头工人

如果一个应用在 Docker 这样的容器中,部署起来会更容易。

在安装正确的环境后,我们将创建一个 docker 文件,其中包含运行我们的应用程序所需的所有说明:

**FROM** python:3.6-slim
**COPY** app/main.py /deploy/
**COPY** app/config.yaml /deploy/
**WORKDIR** /deploy/
**RUN** apt update
**RUN** apt install -y git
**RUN** apt-get install -y libglib2.0-0
**RUN** pip install git+https://github.com/CVxTz/FastImageClassification
**EXPOSE** 8080**ENTRYPOINT** uvicorn main:app --host 0.0.0.0 --port 8080

安装 Docker:

sudo apt install docker.io

然后我们可以运行 Docker 构建:

sudo docker build -t img_classif .

我们最后运行容器,同时将容器的端口 8080 映射到主机的端口:

sudo docker run -p 8080:8080 img_classif .

在远程服务器上部署

我试图在 AWS 的 ec2 实例上这样做,但是 ssh 命令行很笨拙,终端在最后一个命令时会死机,不知道为什么。所以我决定使用谷歌云平台的应用引擎进行部署。点击链接到关于这个主题的更详细的教程

cd FastImageClassificationgcloud config set project_idgcloud app deploy app.yaml -v v1

最后一个命令需要一段时间,但是…瞧!

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

结论

在这个项目中,我们使用 Tensorflow、Docker、FastAPI 和谷歌云平台的应用引擎,从头开始构建和部署了机器学习支持的图像分类 API。所有这些工具使整个过程简单明了,相对容易。下一步是探索处理大量查询时与安全性和性能相关的问题。

重现结果的代码可从这里获得:https://github.com/CVxTz/FastImageClassification

走向工业化的一步:用 pyspark 和 argparse 为您的代码提供参数

原文:https://towardsdatascience.com/a-step-towards-industrialization-parameters-your-code-with-python-and-argparse-118783d09bfd?source=collection_archive---------31-----------------------

使用 argparse 创建您自己的命令行参数,并对 prophet 预测模型的运行进行参数化

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

【https://unsplash.com/photos/qjnAnF0jIGk

Argparse 是什么?

argparse 是一个 python 库,它允许我们编写自己的命令行,以便在代码中包含灵活性。我个人在我的许多脚本中使用它,以使我的数据管道更加灵活,并形成例如在移动时间窗口上的模型。快速浏览一下库之后,我们会看到一些用例。

参数化你的代码:生产力,灵活性和更高的质量。

首先,我们需要导入库。

import argparse

然后我们定义一个“解析器”

parser = argparse.ArgumentParser()

[ArgumentParser](https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser)对象将保存将命令行解析成 Python 数据类型所需的所有信息。然后我们可以传递一些参数给解析器对象。

就说那个吧:

parser.add_argument(
    '--train_start',
    help='''Our algorithm deal with a moving window so we need to flexibilise our filename and so on it will be initialised with a flexible name like my_training_set_at_{train_start}''',
    required=True,
)

我们向解析器添加了一个名为“train_start”的参数,并创建了一个帮助消息,它定义了参数的用途和用法,或者您想要编写的任何内容。最后,我们设置一个顺序条件,强制使用该参数,如果为 False,则可以忽略。

先说教程:(https://docs.python.org/3/library/argparse.html)

我们将把脚本复制到. py 文件中:

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

这里我们定义一个 ArgumentParser 对象来存储我们的参数。然后我们定义两个参数,一个有一个值,另一个会把它们加在一起,让我们来详述一下。

ArgumentParser.**add_argument** ( 名称或标志… [,动作 ][, nargs ][, const ][,默认 ][,类型 ][,选择 ][,必需 ][,帮助 ][, metavar ][, dest ]

我们首先添加一个参数:

  • 一个名称或标志:‘整数
  • 类型:这里的数据类型是整数
  • 帮助:帮助命令用户的消息
  • 一个元变量:改变显示的名称。
  • nargs:它定义了应该使用的命令行参数的数量。这次行动'+'。就像'*'一样,所有存在的命令行参数都聚集到一个列表中。此外,如果没有至少一个命令行参数,将会生成一条错误消息。

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

在第二个增加的参数中

  • 一个名字或旗帜:'- -sum ’
  • 默认操作:如果没有指定,则返回最大值
  • const:对整数列表求和的动作
  • a dest:要添加到由[parse_args()](https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.parse_args)返回的对象的属性的名称
  • 助手消息

现在,我们将它保存为“parser _ exemple.py ”,然后打开控制台查看它:

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

那就试试吧

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

好了“教程”,现在让我们来看一个真实的例子。

几个使用的例子

我们将从我之前关于熊猫的一篇文章开始——UDF 和 prophet 对于这个脚本的预测和参数化,这将允许我们通过一个真实的例子使用 argparse 来参数化我们的脚本,避免一篇冗长无用的文章。下面是这篇文章的链接,其中包含了我们将要参数化的大部分代码

https://towards data science . com/py spark-forecasting-with-pandas-UDF-and-FB-prophet-e 9d 70 f 86d 802

它将成为我们的工作基地:

参数化你的文件名和文件路径

其实也不是很难,我们会在一个不同的文件里用几个参数定义我们的解析器(这是我个人的偏见:其实你可以在同一个空间里做所有的事情)。

因此,我们将定义一个函数来创建 ArgumentParser,向其中添加所需的参数并返回分析后的参数。

在 main 中,我们导入我们的函数并检索我们在启动 spark submit 时放入的参数。

然后使用正确的参数通过 shell 将其作为 python 作业或 spark 提交作业启动,就这样。

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

这些基本元素对于构建高度通用的管道是必不可少的,并且不需要特殊的开发技能。

最后

这看起来很简单,但是这种工具对于拥有灵活的管道和使生活变得更容易是绝对必要的。我在我的项目中经常使用它,特别是与气流一起使用,以便对一段时间内的重复预测进行编程——这将是未来文章的主题。

感谢您的关注,您会在我的 github*😗https://github.com/AlexWarembourg/上找到所有的要点和要旨

数据产品的战略蓝图

原文:https://towardsdatascience.com/a-strategy-blueprint-for-data-products-a158ad6bf449?source=collection_archive---------37-----------------------

如何用数据构建战略护城河

在当今的商业环境中,战略护城河是用数据构建的。不用数据游戏就能在软件上建立新的业务线的日子已经一去不复返了。数据最初被比作石油,表明数据为创新引擎提供燃料。最近,经济学家将数据比作阳光,因为像太阳光线一样,数据将无处不在,成为一切的基础。数据也是精明的商业人士建立差异化商业模式的新基础设施。

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

航空焦点Unsplash 上拍摄的照片

设计数据产品成本高昂。数据科学家和机器学习工程师是收入最高的专业人士,仅次于外科医生和医生。不用说,将一个数据科学项目从实验转变为生产应用需要强大的财务实力和一致的商业激励。成功数据产品的蓝图由三个核心要素组成:业务工作流、分销渠道和数据源。

业务工作流程

数据产品作为建立在业务工作流之上的应用层出现。数据产品在管理流程自动化、客户支持、法规遵从性等运营环境中部署时,都有成功的记录。也就是说,数据产品目前被分配给“安全”的后台部门,在那里性能故障的代价较低。

并不是每个业务流程都能支持一个数据产品。我已经为许多企业准备并审核了记分卡,以证明数据产品应用程序的业务工作流是合格的。看看吧!

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

数据源

公共数据或开放数据可供每个人访问、修改、重用和共享。开放数据组织是支持开放源代码软件的组织的对应组织。他们的工作赋予公民权力,可以加强民主,简化社会、政府和私营企业的流程和系统。几个很棒的开放数据源是世界银行开放数据全球健康观察站数据谷歌公共数据浏览器AWS 开放数据注册中心美国人口普查局

私有数据来源是谷歌、亚马逊和脸书等差异化公司的支柱。先发战略使公司能够在数据聚合游戏→数据引力中实现跨越。搜索结果、产品/电影推荐和社交网络随着数据而改善。这就是为什么老牌玩家会留在这里,除非我们让机器学习系统简单地分享和学习不同的数据源。
私有数据的许可权变得复杂。一个普遍的问题是,数据源的所有者不能从外部再授权数据。这意味着私有数据只能由拥有该数据的同一组织所拥有的产品利用。第二十二条军规?如果数据是根据带有分许可条款的许可收集的,这就为在母公司之外将私人数据商业化提供了机会。我们必须解决房间里的大象。在各公司中,数据管理实践的范围很广。领先的公司通过遵守道德、隐私和安全规则树立了榜样。一些行业自行处理事务,并建立了数据隐私标准和框架。在医疗保健和金融服务领域,数据隐私由监管机构强制执行。消费行业必须遵守消费者隐私法。适用于任何人的经验法则:总是尽可能经常地消除数据标识并许可聚合数据的孤岛。

合成数据是一种可取之处,取决于手头的数据产品。计算机算法已经非常擅长生成合成数据:无论是名人的视频还是《T2》杂志的文章,我们都可以伪造。类似的技术可以用来生成合成数据,这些数据训练数据产品背后的机器学习模型。为了用相关的数据种子引导这样的算法,公司可以建立数据捐赠计划——内部的或外部的——并签订适当的数据使用协议。

分配路线

一个好的产品只是故事的一半。您的产品已经签名盖章,现在需要交付。一些分销渠道可用于企业产品。每个分销渠道都对产品定价模式和整体产品策略有影响(构建对购买对收购)。

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

最后,数据驱动型产品需要持续监控质量表现。你可能会问,为什么所有这些审查,做同样工作的人没有被全天候监控。这么说吧,人类每季度都要接受伦理方面的培训,并对自己的行为负责。机器在沉默中行动,所以我们需要使用监控脚本来查询它们的行为。监控产品性能和标记角落案例是一个很好的做法。从定义故障管理、产品道德和人在回路中的审查的内部政策开始。

软件工程面试者的学习计划

原文:https://towardsdatascience.com/a-study-plan-for-software-engineering-interviewees-b67914520489?source=collection_archive---------28-----------------------

成为技术面试的专家——第三部分

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

照片由来自佩克斯克里斯蒂娜·莫里洛拍摄

这是软件工程师面试准备系列的第三部分。

我强烈建议您查看本系列的第一部分第二部分,以了解该学习计划的背景。

该计划旨在实施我在第二部分中提到的刻意练习方法。

以此为指导——这里的主要目的是遵循有意练习的原则和我将在下面谈到的 7 步流程。享受旅程!

学习计划

设置:

好了,我们已经就什么是刻意练习进行了一次大讨论,但是现在让我们来谈谈我们如何实际实施刻意练习以达到我们的最终目标并赢得现场面试。

总结一下,我们的最终目标是:

每个主题都达到 3 级。

我们首先需要拿出一个空间,在那里我们可以客观地捕捉和跟踪每个主题的进展,每周。为此,我们将利用上面提到的 3 分制评分系统。这就是我们如何努力保持这个过程客观

我将通过一个例子向你展示我如何跟踪进度,但我鼓励你发挥创造力,想出一种适合你和你的学习风格的方式。

首先,创建一个谷歌文档或表格来跟踪每个主题的进展。对于每个主题,创建一个表格来记录该主题每周的分数,并创建另一个表格来记录您的带有“正确/错误”列的题库。

我个人也喜欢用分区来记录每个主题的笔记、有用的链接和待办事项。这将成为下一步要做什么、你遇到了什么问题以及你克服了什么的列表——这有助于你更加关注自己一周的进步。

对我来说,布局可能是这样的:

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

如何跟踪主题进展的示例。(图片由作者提供)

我还会在周末维护一个每周更新的每个主题的水平表。刚开始的时候,这些话题大部分会是 1 级(也没关系!!).我可能会这样追踪:

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

每周记录每个主题的水平。(图片由作者提供)

日程安排:

既然我们已经有了一个有组织的空间来跟踪我们的进展,我们需要弄清楚 什么时候 我们实际上要把所有这些研究都放进去!

每个人的时间表都不一样——有些人在全职工作时准备面试,有些人在全职找工作(🙋🏼‍♀️).因此,你学习每个主题的时间和顺序完全取决于你自己和你的时间。

不管你如何选择你的主题,你有多少时间来学习,你的学习课程的结构将是相同的,并遵循以下循环:

  1. 确定问题区域
  2. 研究问题领域(谷歌/YouTube/书籍/同行讨论等。)
  3. 测试(来自 LeetCode 等的问题。)
  4. 学习试题解答(重要!!!)
  5. 重新评估和反思(确定成功和问题领域)
  6. 复试(与#3 相同的问题)
  7. 重复

我们需要在这些步骤之间留出空间。例如,你不会在同一个小时内重新测试同一个问题。这通常会在当天晚些时候完成,或者最好在几天后完成。

我们还需要决定如何平衡 20 个主题,以及如何为每个级别适当地学习。谢天谢地,我们有一个评级系统,这将有助于指导我们。

一级主题:

  • 这些主题在开始时不会有很多“测试”。
  • 在研究开始时做其中的一两个问题可以帮助你找到不足之处,并指导你的研究工作,但除此之外,钻研一个你一无所知的问题没有多大用处。
  • 1 级课题的研究将主要包括整理一份棘手领域的清单,然后研究/学习这些领域。
  • 根据题目的不同,你可能会在解决一个问题之前花整整一周的时间做研究(尤其是如果这是一个大题目的话)。
  • 对于困难的话题,在一周结束时(经过一周的集中研究)尝试问一个问题,给自己一个新的基线。这里的要点不是把问题做对,而是把你所学的内容放回背景中,给自己机会去研究解决方案。即使你不知道从哪里开始,也要给这个问题一个明确的答案——说点什么。然后,花大量时间研究解决方案——这就是你学习如何解决问题的方法!(相对于仅仅阅读理论)。然后将这个问题添加到你的“错误”堆中,你将在以后再次测试它。

二级主题:

  • 这些主题将在研究和测试之间保持平衡。
  • 保持与这些主题的良好流程:确定问题领域、研究、测试、研究解决方案、评估、重新测试。
  • 强调 题对二级题目很重要。
  • 真正挑战自己,只是“做”。这就是这些主题如何到达第三级的原因!

第 3 级主题:

  • 某样东西被评为 3 级意味着你对它“几乎无所不知”,根本不需要做太多的研究。
  • 在这个阶段,只是实践:测试、解决方案、测试、解决方案…
  • (当然还要重新测试你做错的题!).

改变级别:

不要对自己太苛刻——如果你觉得自己在某个话题上取得了进步,那就让自己进步吧!

然而,在以这种方式学习之后,你可能会意识到你需要把某些东西降低一个等级——不要为此惊慌。这是发现问题领域过程的一部分。你可能习惯于通过“感觉”来评估你在某方面的能力——现在我们有了一个客观的衡量标准,所以可以预料我们可能会出错。

对于第 2 级主题,如果你花更多的时间研究而不是做题,那么这是一个信号,表明这个主题可能应该下降到第 1 级。

对于第 3 级问题,如果你发现你得到了正确的答案,但是它的时间和空间复杂度一直很低,并且你的解决方案感觉有点“粗糙”,那么也许将这个问题移到第 2 级并研究这些类型问题的一些更优的解决方案是一个好主意。

相信你的判断,不要想太多!

学习计划示例:

这里有几个学习计划的例子,告诉你如何安排我们刚刚谈到的所有内容。抱歉,它们不太漂亮。

我假设每个计划每天学习 2 小时。当然,这些只是建议**——你显然可以根据你的时间表和时间框架进行相应的调整。我相信你会想出更好的时间表!**

关键是保持上面的 7 步流程**。**

14 天计划示例:

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

实施深思熟虑练习的 14 天学习计划示例。(图片由作者提供)

7 天计划示例:

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

实施深思熟虑练习的 7 天学习计划示例。(图片由作者提供)

5 天计划示例:

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

实施深思熟虑练习的 5 天学习计划示例。(图片由作者提供)

我在这里提供了 5、7 和 14 天的计划,告诉你无论你的时间表是什么,你都可以适应学习!作为一名教师,我听过各种各样的借口,比如“你不适合学习”,但我更乐意和你坐在一起,为你找时间!

请给我发消息告诉我你想到了什么——我总是很想知道人们是如何利用他们的时间来创造的!

数据科学家注意:

我和软件工程师一起实施了这个学习计划,并取得了巨大的成功。然而,我是一名数据科学家,目前正在接受数据科学职位的面试。这个领域比软件工程面试稍微微妙一些,因为对于数据科学的角色还没有直接的共识。

直接联系我如果你想讨论如何准备数据科学面试,以防你不知道,我喜欢谈论这个话题😝。

我们到了!

现在我知道了,我知道了。这是一个很大的数字,可能看起来有点过了。这是一个我充满热情的话题,我也相信这个话题的需求量很大。

让我们提高现场面试成功率,同时提高我们的学习效率!

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

照片由来自 Pexels伊恩·帕内洛拍摄

一个成功的数据科学模型需要 GitHub。原因如下。

原文:https://towardsdatascience.com/a-succesful-data-science-model-needs-github-heres-why-da1ad019f4e0?source=collection_archive---------55-----------------------

GitHub 给你的数据科学项目带来的好处。

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

Unsplash 上由 Roman Synkevych 拍摄的照片。

目录

  1. 介绍
  2. 开源代码库
  3. 利益
  4. 摘要
  5. 参考

介绍

数据科学家经常独自开始他们的学术甚至职业之旅,所以他们习惯于自己在本地驱动器上组织他们的概念和代码——也许是以某种临时的方式。但是,当你在一个由几个数据科学家、数据工程师、软件开发人员甚至产品经理组成的团队中工作时,会发生什么呢?你必须以某种方式合作。对于您的数据科学模型,您的代码将在哪里共享和控制?GitHub 就是这些问题的答案。

这个平台作为一个工具,让团队和组织的跨职能成员使用 Git 在同一版本的代码库上工作,并批准和评论通过 pull 请求请求和记录的新代码更改。

下面,我将在一个数据科学项目上分享和描述 GitHub 的好处。

开源代码库

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

照片由 Jantine DoornbosUnsplash【2】拍摄。

GitHub【3】通过使用 Git、pull requests、issues、wikis 和 gist 来记录和指导软件开发人员、设计人员和项目经理。建立数据科学项目相当简单,并允许您的团队对您的文件和代码进行检查和平衡。Git 是在终端中进行交互的主要系统,用于导航分支、代码更改以及最终的版本控制。Gists 对于提交代码片段以供共享也很有用,例如,如果您不想共享整个数据科学项目。下面,我就来讨论一下 GitHub 的好处。

利益

数据科学模型可以在您的本地计算机上工作,但一旦您将其他人纳入同一项目,GitHub 就可以作为一种工具,它有几个好处,可以确保成功的机器学习模型到位。我将包括更多描述性的好处和 Git、拉请求、协作和 gist 的例子。

【Git】—您可以执行某些命令,这些命令会推高您代码库的新版本。使用如下 Git 命令,可以创建一个 pull 请求,然后您的数据科学模型代码将被监控和增强。以下是一些常用的、有用的 Git 命令:

  • *查看你在哪个分支——*git 分支
  • *从您的主分支创建一个新的分支—*git branch branch _ name
  • 拉你的主分支,使其保持最新— git 拉
  • 检查您的文件(代码)变更— git 状态
  • 添加您的文件(代码)从您的分支— git 添加
  • *从您的分支提交您的更改—*git commit-m " Added change "
  • 从你的分支推送你的变更— git 推送

拉请求 —这个动作是 GitHub 平台极其有用的一部分。对于 pull 请求,通常命名为“ PR 的”,您可以有第二个、第三个,甚至更多对代码变更的关注。当您想要将代码添加到现有的主分支时,您可以创建自己的分支,该分支将包含新的代码。您团队中的人必须查看并测试它,以确保您新添加的内容是正确的。公关过程不仅有利于消除错误,确保人们会仔细检查你的工作,而且在某种意义上,它也有利于你团队中的所有人都在同一页上。当其他人必须查看您的更改并批准新的代码时,他们将重申模型的知识,因为它扩展到更多的文件和系统。

协作 —通过使用 GitHub,还可以实现来自多个团队成员的相关协作,包括其他数据科学家、软件工程师、数据工程师和产品经理。协作是一种优势,因为它将使您的数据科学模型更加健壮、高效,并且在受到其他人的影响时可能更加准确。您可以在数据科学模型中包括所有合适的人员,并对整个项目产生积极的影响。

Gists —如果你想与他人分享一个更小的代码片段,甚至在这里,就在介质上,你可以用适当的编程语言显示代码,这些都很有用。这是一种显示代码示例的简单方法。当您以. py 格式指定编程语言(比如 Python)时,您可以很容易地看到彩色编码的函数——例如,导入代码以红色突出显示。下面是一个例子的要点:

要点示例。作者代码[4]。

摘要

GitHub 是您组织内数据科学项目的有用工具。它可以通过使用协作、Git、pull 请求和 gist 来存放、共享和增强代码。GitHub 还有其他几个好处,在他们提到的网站上也有概述。数据科学模型需要所有这些关键组件来确保成功。

虽然学术界对数据科学的关注不一定是 GitHub,而是通用机器学习模型的理论、概念和代码,但在学生进入劳动力市场并必须立即开始与其他人合作之前,应该重点关注这个平台。总之,这有利于开发成功的数据科学模型。

要了解更多关于 GitHub 的 Git 部分,请在下面找到这篇文章[5]:

[## 每个数据科学家都需要知道的通用 GitHub 命令

通过使用 GitHub 成为更好的数据科学家指南

towardsdatascience.com](/common-github-commands-every-data-scientist-needs-to-know-e7d5d9c4f080)

我希望你觉得这篇文章有趣并且有用。感谢您的阅读!

参考

[1]照片由 Roman SynkevychUnsplash(2019)上拍摄

[2]照片由 Jantine DoornbosUnsplash 上拍摄,(2017)

[3] GitHub,Inc ., GitHub 主页,(2020)

[4] M.Przybyla, pandas-append.py ,(2020)

[5] M.Przybyla,每个数据科学家都需要知道的通用 Git 命令,(2020)

句子向量表征中作文评价综述

原文:https://towardsdatascience.com/a-summary-of-assessing-composition-in-sentence-vector-representations-4dce904220cd?source=collection_archive---------56-----------------------

自然语言处理领域著名研究论文综述

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

照片由来自 UnsplashPatrick 拍摄

来源:https://www.aclweb.org/anthology/C18-1152.pdf(艾丁格等人,2018)

**背景:**为了理解什么是句子嵌入,有必要理解单词嵌入。单词嵌入已经变得非常著名,因为它们能够以可以普遍使用的向量的形式来表示单词。著名的嵌入有 word2vec、Glove 等。
单词嵌入的相同概念可以扩展到句子,使得每个句子用向量表示。诸如“发现两个堆栈溢出问题是否重复”之类的任务需要使用句子嵌入。

**引言:**为了理解语言,理解句子的意思和组成是必不可少的。今天的大部分神经网络模型本质上都是黑盒。因此,很难理解句子嵌入作为最终产生它们的训练的一部分正在捕捉什么。

本文讨论了专门用来测试句子嵌入是否抓住了句子的组成和意义的特定任务。本文基于另一篇论文(Adi 等人。al,2016),其中,(Adi 等人。al,2016)使用弓模型和自动编码器进行类似的实验。然而,由于数据集中的非预期偏差,他们的结果非常可疑。例如,他们表明,在单词顺序任务中,BOW 模型实现了 70%的性能,即使这种模型在逻辑上不可能保留与单词顺序相关的信息。因此,这篇论文的作者认为,BOW 模型的这种表现是一个偶然事件,因为数据集中存在偏差。

本文提出消除/减少这种偏见,并测试其他深度学习模型。它们还引入了额外的任务,这些任务将在下面详细讨论。本文的贡献包括一个句子生成集,一个已证实的模型来测试组成和意义是否确实被嵌入,生成系统和用于分类的数据集作为开源提供给其他人进行进一步的探索和分析。

**研究问题:**本文试图回答的研究问题有:

1.当前的神经句子嵌入模块在它们的句子嵌入中捕获句子的含义和组成的情况如何?

2.我们能提出一种方法和框架来评估句子嵌入和它们的模型在多大程度上捕捉了句子的意义和组成吗?

**意义和构成:**构成句子的元素向读者传递意义。它通常包含一个代理、一个患者和一个事件。构图是元素排列的一种方式,有助于传达意义。一个句子的不同部分可以结合起来达到它的意思。

**数据集准备:**作者提出了一种新的句子生成系统,减少了数据集中的偏差。例如,它根据英语的句法、语义和词汇规则生成多样化的、完全带注释的句子。它由三部分组成。

**事件/句子表征:**这些是句子的部分表征,接受诸如施事、受事、及物、不及物动词以及关系从句的存在与否等参数。这些表示作为输入提供给事件生成系统。例如,考虑如下所示的句子。

**事件填充:**系统从句子表示系统获取输入,并用给定的信息填充事件。它使用副词和 17 个词汇。字数受到限制,以保持对生成句子的控制。它循环通过副词和名词来生成句子。

**句法实现:**它使用基于规则的技术对生成的句子中的单词进行词形变化,以遵循词法。他们使用(Bird 等人,2009)中提到的 NLTK 框架,屈折从 XTAG 形态学数据库中提取(Doran 等人,1994)。

分类任务:设计不同的任务来测试句子嵌入是否保持句子的组成和意义。大致可分为两种类型,肯定否定。SemRole 任务旨在测试句子嵌入是否抓住了意思。要回答的问题是,给定一个名词(n),一个动词(v)和一个句子嵌入(s),n 是 v 在 s 中的施事吗?

否定任务是测试句子嵌入是否捕捉到动词的否定。即给定一个动词(v)和一个句子嵌入(s),v 是否在 s 中被否定?生成的句子在动词和否定之间填充副词,使得动词在否定之后不明显,并且该模式易于模型学习和检测。

其他三项任务与单词内容和顺序有关。第一个任务, Content1Probe 被设计为测试句子嵌入是否包含输入句子中存在的动词。 Content2Probe 类似于 Content1Probe,它测试句子嵌入是否同时包含名词和动词,假设两者在句子嵌入生成之前都作为输入出现。

排序任务旨在测试合成句子嵌入是否捕捉到句子中单词顺序的信息。给定一个既包含动词(v)又包含名词(n)的句子嵌入(s ),那么名词(n)出现在动词(v)之前吗?

**分类实验:**作者建立了一个神经网络/多层感知器模型,其输入大小等于句子嵌入的大小。ReLU 用作神经元的激活函数。上述分类任务本质上是二元的。因此,对于生成的句子,每个任务的标签(是或否)被分配。生成 5000 个这样的句子,其中 4000 个具有适当标签的句子被用作训练集,其余 1000 个句子(具有适当标签)被用作测试集。不需要超参数调谐,因为网络规格在(Adi et。al,2016)。作者不执行任何训练来生成句子嵌入。他们也没有设计一个句子嵌入算法。他们使用嵌入算法,这些算法已经可以作为他们自己的语料库上的预训练模型。这些模型用于为生成的 5000 个句子产生句子嵌入。句子的嵌入和它们各自的任务标签形成了神经网络模型的数据集。该模型用训练集进行训练,并用测试集进行测试。

**句子嵌入模型:**下面描述所使用的不同句子嵌入模型:

**BOW:**BOW 模型是一个简单的模型,它使用一个向量来表示句子中的每个单词。它对这些嵌入进行平均,并将其用作句子嵌入。

**顺序去噪自动编码器:**它是一种无监督学习技术,使用基于 LSTM 的自动编码器。

**跳过思想嵌入:**他们利用 GRUs 生成句子嵌入。有两种可用的变体,uni-skip (ST-UNI)和 bi-skip (ST-BI)。Uni-skip 编码器在正向传递时进行回复,而 bi-skip 在神经网络中同时使用正向和反向传递。

InferSent: InferSent 是最先进的模型,它使用多层双向 LSTM 来生成句子嵌入。

结果:

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

表。1(摘自 来源 论文)

各种任务的模型结果如上表所示。它摘自 Ettinger 等人(2018 年)。

单词袋(BOW)模型在基于内容的任务上表现良好。这说明弓模型完美地编码了单词的意思。人们期望它在顺序、语义角色和否定任务中表现糟糕,它确实如此。这用作对数据集的检查,并且它满足该标准。这也可能是由于数据生成模块中使用的 17 个单词的词汇集非常有限。

在否定任务中,除了 ST-BI,所有模型都表现良好。这可能是因为在向前传递时,它首先遇到否定,然后是动词,但在向后传递时,这个顺序是相反的。因此,信息可能没有被很好地捕获。其他模型做得很好,即使很难捕捉到否定和动词之间的关系,即使很难做到这一点。这也可能是由于嵌入的维数从 1200 减少到 300。

对于语义角色(SemRole)任务,InferSent 表现随机,其他模型也表现不佳。正如本文作者(Ettinger 等人,2018 年)所述,句子嵌入模型没有提供有力的证据表明它们充分捕捉了语义角色。

还可以推断出,当通过它们的嵌入进行评估时,具有不同设计架构和目标的不同句子嵌入模型未能对句子的含义和组成产生任何显著影响。所有的模型在其嵌入中捕获几乎相同水平的意义和组成。

实验结果也证明了所提出的方法是可靠的,可以检测句子嵌入捕获了多少或是否捕获了句子的意义和成分。可以定义更多的任务来更好地理解句子嵌入中捕获的信息。

作者计划通过显式嵌入 e 中提到的句法结构来测试其他模型(Bowman 等人,2016;戴尔等人,2016;Socher 等人,2013 年)在他们未来的工作。

参考文献

Ettinger,a .,Elgohary,a .,Phillips,c .,& Resnik,P. (2018)。评估句子向量表示中的成分。arXiv:1809.03992。

约西·阿迪、埃纳特·克尔马尼、约纳坦·贝林科夫、奥弗·狮式战斗机和约夫·戈德堡。2016.使用辅助预测任务对句子嵌入进行细粒度分析。arXiv 预印本 arXiv:1608.04207。

史蒂文·伯德、伊万·克莱恩和爱德华·洛珀。2009.用 Python 进行自然语言处理:用自然语言工具包分析文本。奥赖利媒体公司。

克里斯蒂·多兰、达尼亚·埃杰迪、贝丝·安·霍基、班加罗尔·斯里尼瓦斯和马丁·扎伊德尔。1994.XTAG 系统:覆盖面广的英语语法。《第 15 届计算语言学会议论文集》第 2 卷,第 922-928 页。计算语言学协会。

塞缪尔·R·鲍曼、加博·安格利、克里斯托弗·波茨和克里斯托弗·D·曼宁。2015.用于学习自然语言推理的大型标注语料库。在 EMNLP。

克里斯·戴尔、阿迪古纳·昆科罗、米盖尔·巴列斯特罗斯和诺亚·史密斯。2016.递归神经网络语法。纳克。

理查德·索彻、亚历克斯·佩雷金、让·吴、贾森·庄、克里斯托弗·曼宁、和克里斯托弗·波茨。2013.情感树库语义合成的递归深度模型。2013 年自然语言处理经验方法会议论文集,第 1631-1642 页。

Twitter 美国航空公司情感数据集的监督或半监督 ULMFit 模型

原文:https://towardsdatascience.com/a-supervised-or-semi-supervised-ulmfit-model-to-twitter-us-airlines-sentiment-dataset-db3a6550abdf?source=collection_archive---------29-----------------------

Twitter 美国航空公司情感数据集的监督或半监督 ULMFit 模型

我们的任务是将类似 ULMFit (Ruder 等人,2018 年)的监督/半监督技术应用于 Twitter 美国航空公司情绪分析数据。
这个问题是半监督的原因是,它首先是一种非监督的训练方式,然后通过在网络顶部添加一个分类器网络来微调网络。

我们使用 Twitter 美国航空公司数据集(https://www . ka ggle . com/crowd flower/Twitter-airline-情操 )

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

https://unsplash.com/photos/rf6ywHVkrlY

我们将从 开始:

  • 浏览数据集,为模型进行预处理和准备
  • 探索情感分析的历史
  • 探索语言模型及其重要性
  • 设置基线模型
  • 探索文本分类技术
  • ULMFit 概述
  • 将 ULMFIT 应用于 Twitter 美国航空公司数据
  • 结果和预测
  • 结论和未来方向

数据集

我们将从探索数据集统计数据和执行所有强制特征转换开始。

  • 由于这是一个多类分类问题,我们将对目标变量进行编码。
  • 我们将改变列的显示顺序
  • 我们将执行基本的统计以从数据中获得一些洞察力
  • 最后,我们将把新的数据帧分成 df_train、df_val 和 df_test
# Loading datasetdf = pd.read_csv(DATA_DIR)# LabelEncoder to change positive, negative and neutral to numbers (classes)labelEncoder = LabelEncoder()def cleanAscii(text):"""Remove Non ASCII characters from the dataset.Arguments:text: str"""return ''.join(i for i in text if ord(i) < 128)def gather_texts_and_labels(df=None, test_size=0.15,random_state=42):"""Gathers the text and the corresponding labels from the dataset and splits it.Arguments:df: Pandas DataFrametest_size: represents the test sizerandom_state: represents the random stateReturns:(x_train, x_test, y_train, y_test, new_df)"""# textstexts = df["text"].values# encoding labels (positive, neutral, negative)df['airline_sentiment'] = labelEncoder.fit_transform(df['airline_sentiment'])labels = df['airline_sentiment'].values# changing the order for fastai tokenizers to capture data.new_df = pd.DataFrame(data={"label":labels, "text":texts})df_train, df_test = train_test_split(new_df, stratify = new_df['label'], test_size=test_size, random_state = random_state)df_train, df_val = train_test_split(df_train, stratify = df_train['label'], test_size = test_size,random_state = random_state)print("Training: {}, Testing: {}, Val: {}".format(len(df_train), len(df_test), len(df_val)))return df_train, df_test, df_val,new_dfdef describe_dataset(df=None):"""Describes the datasetArguments:df: Pandas Dataframe"""print(df["airline_sentiment"].value_counts())print(df["airline"].value_counts())print("\nMean airline_sentiment_confidence is {}".format(df.airline_sentiment_confidence.mean()))# Optionaldef add_negativereason_to_text(df=None):# change negativereason to "" if NaN else remain as is.df['negativereason'] = df['negativereason'].apply(lambda x: "" if pd.isna(x) else x)# add negativereason to textdf['text'] = df['text'] + df['negativereason']add_negativereason_to_text(df)df['text'] = df['text'].apply(cleanAscii)describe_dataset(df)df_train, df_test, df_val, new_df = gather_texts_and_labels(df)

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

数据的统计

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

一些基本功能

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

一些视觉统计

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

更多统计数据

我们将依靠不同的指标来衡量模型的性能(精度、召回率、F1 得分)

历史

历史

B 在 ULMFit (2018)或 NLP 中的迁移学习之前准确地说,我们使用 word2Vec 或 GLove 等单词嵌入将单词表示为密集稀疏向量表示。通常,我们使用嵌入层作为模型中的第一层,然后根据我们的需要附加一个分类器。这使得该系统很难训练,因为它需要大量的数据。这些语言模型是早期的统计 LMs,使用概率分布来表示单词。(《由公司一言保管》)。

  • ULMfit,BERT,Universal sentence encoder,OpenAI GPT-2 使用一种叫做神经语言模型的东西来以分布式方式表示单词,并允许微调一个大型预训练语言模型来帮助我们完成任务。
  • 具体来说,ULMfit (2018)引入了三种新技术来微调预训练语言模型
  • 微调是计算机视觉中的一种流行方法,虽然这种方法在 NLP 上尝试过,但结果证明这种方法在 ULMFit 之前是错误的。

在本文的后面,我们将看到语言模型和分类器的概述。

设定基线

B 在任何机器学习实验之前,我们都应该设立一个基线,并与我们的结果进行比较。

为了建立基线,我们将使用 word2vec 嵌入矩阵来尝试预测情绪。

  • 为了加载我们的 word2vec,我们将使用嵌入层,然后是基本的前馈神经网络来预测情绪。

我们也可以加载一个预先训练好的 word2vec 或 glove 嵌入,并输入到我们的嵌入层中。
我们可以在嵌入层之后使用 LSTM 或 CNN,然后激活 softmax。

# The word2vec requires sentences as list of lists.texts = df['text'].apply(cleanAscii).valuestokenizer = keras.preprocessing.text.Tokenizer(num_words=5000, oov_token='<OOV>')# fittingtokenizer.fit_on_texts(texts)vocab_size = len(tokenizer.word_index) + 1# max length to be padded (batch_size, 100)max_length = 100train_text = tokenizer.texts_to_sequences(df_train['text'].values)test_text = tokenizer.texts_to_sequences(df_test['text'].values)# getting the padded length of 100padded_train_text = keras.preprocessing.sequence.pad_sequences(train_text, max_length, padding='post')padded_test_text = keras.preprocessing.sequence.pad_sequences(test_text, max_length, padding='post')labels_train = keras.utils.to_categorical(df_train['label'].values, 3)labels_test = keras.utils.to_categorical(df_test['label'].values, 3)metrics = [keras.metrics.Accuracy()]net = Sequential()# return 50 dimension embedding representation with input_length as 100net.add(keras.layers.Embedding(vocab_size, 50, input_length=max_length))net.add(keras.layers.Flatten())net.add(keras.layers.Dense(512, activation='relu'))net.add(keras.layers.Dense(3, activation='softmax'))net.compile(optimizer='adam', loss=keras.losses.categorical_crossentropy, metrics=metrics)net.summary()# The word2vec requires sentences as list of lists.texts = df['text'].apply(cleanAscii).valuestokenizer = keras.preprocessing.text.Tokenizer(num_words=5000, oov_token='<OOV>')# fittingtokenizer.fit_on_texts(texts)vocab_size = len(tokenizer.word_index) + 1# max length to be padded (batch_size, 100)max_length = 100train_text = tokenizer.texts_to_sequences(df_train['text'].values)test_text = tokenizer.texts_to_sequences(df_test['text'].values)# getting the padded length of 100padded_train_text = keras.preprocessing.sequence.pad_sequences(train_text, max_length, padding='post')padded_test_text = keras.preprocessing.sequence.pad_sequences(test_text, max_length, padding='post')labels_train = keras.utils.to_categorical(df_train['label'].values, 3)labels_test = keras.utils.to_categorical(df_test['label'].values, 3)metrics = [keras.metrics.Accuracy()]net = Sequential()# return 50 dimension embedding representation with input_length as 100net.add(keras.layers.Embedding(vocab_size, 50, input_length=max_length))net.add(keras.layers.Flatten())net.add(keras.layers.Dense(512, activation='relu'))net.add(keras.layers.Dense(3, activation='softmax'))net.compile(optimizer='adam', loss=keras.losses.categorical_crossentropy, metrics=metrics)net.summary()

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

模型摘要

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

培养

# test the baseline model
def test_baseline_sentiment(text):"""Test the baseline modelArguments:text:str"""padded_text = keras.preprocessing.sequence.pad_sequences(tokenizer.texts_to_sequences([text]), max_length, padding='post')print(net.predict(padded_text).argmax(axis=1))net.evaluate(padded_test_text, labels_test)preds = net.predict(padded_test_text).argmax(axis=1)

如您所见,使用简单的前馈神经网络和嵌入层,我们很难达到 12%的精度

加载语言模型和微调

astAI 为我们提供了一个易于使用的基于维基文本(AWD)的语言模型。

我们将从加载 LM 数据并使用所需的数据初始化它开始。

data_lm = TextLMDataBunch.from_df(train_df = df_train, valid_df = df_val, path = "")# Saving the data_lm as backupdata_lm.save("data_lm_twitter.pkl") # saving as a back stop# Loading the language model (AWD_LSTM)learn = language_model_learner(data_lm, AWD_LSTM, drop_mult=0.3)print(learn)

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

我们的样本数据

正如你所看到的,fastai 库使用了 spacy tokenizer,所以除了删除 asci 字符之外,我们不对数据进行任何预处理。ULMFit 的作者在经验上很好地检验了标记化过程。

培养

# Finding the optimal learning ratelearn.lr_find(start_lr=1e-8, end_lr=1e2)learn.recorder.plot()# Fit using one cycle policylearn.fit_one_cycle(1, 1e-2)# Unfreeze all layerslearn.unfreeze()# fit one cycle for 10 epochslearn.fit_one_cycle(10, 1e-3, moms=(0.8,0.7))# save the encoderlearn.save_encoder('fine_tuned_enc') # we need the encoder in particular..FOr classifier

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

模型进度

文本分类

我们现在创建添加我们的分类器在下面的网络(微调)。这是将指定的任务分类器添加到预训练语言模型中的最后一步

这是逐步冻结步骤。

# Preparing the classifier datadata_clas = TextClasDataBunch.from_df(path = "", train_df = df_train, valid_df = df_val, test_df=df_test, vocab=data_lm.train_ds.vocab)# Building the classifierlearn = text_classifier_learner(data_clas, AWD_LSTM, drop_mult=0.5)# loading the saved encoderlearn.load_encoder('fine_tuned_enc') # load th encoder from the LM# slanted learning rate scheduler# fine tuning the whole networklearn.fit_one_cycle(3, 1e-2, moms=(0.8,0.7))  # you can of course train more, Jeremy promises its hard to over fit here :D# fine tuning the network layer by layer to preserve as much information is possible.learn.freeze_to(-2) # unfreeze last 2 layerslearn.fit_one_cycle(2, slice(1e-2/(2.6**4),1e-2), moms=(0.8,0.7))learn.freeze_to(-3) # unfreeze last 3 layerslearn.fit_one_cycle(2, slice(5e-3/(2.6**4),5e-3), moms=(0.8,0.7))learn.freeze_to(-4) # unfreeze last 4 layerslearn.fit_one_cycle(2, slice(5e-3/(2.6**4),5e-3), moms=(0.8,0.7))learn.freeze_to(-5) # unfreeze last 5 layerslearn.fit_one_cycle(2, slice(5e-3/(2.6**4),5e-3), moms=(0.8,0.7))# Unfreezing all the layers and traininglearn.unfreeze() # unfreze alllearn.fit_one_cycle(3, slice(1e-3/(2.6**4),1e-3), moms=(0.8,0.7))

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

我们达到了 94%的准确率

ULMFit 概述

ULMfit 流程的回顾

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

https://arxiv.org/abs/1801.06146

不同类型的流程如下:

  • LM 预训练:这是我们遵循无监督学习来捕获大型语料库的语义和概率表示的步骤。(维基文本-103)
  • LM 微调:这是我们通过使用某些新技术来微调 LM 的步骤。由于 AWD-LSTM(预训练模型)的每一层都捕获关于语料库的不同信息,我们首先微调最后一层,因为它包含最少的信息,而所有其他层都被冻结。然后,我们解冻所有其他层,用指定的任务重新训练模型。这样,我们不会丢失信息。通过使用倾斜的三角形学习率(模式为三角形的循环学习率)来完成训练。
  • 最后一步是分类器微调,其中分类器模型附加到模型的顶部,并通过使用逐步解冻来训练,我们通过逐层解冻来训练模型。

T 这些技术是:

  • 区别微调
  • 倾斜三角形学习率
  • 逐渐冻结

乌尔菲特在推特上表达了美国航空公司的观点。(预测和准确性)

def get_sentiment(text:str):"""Get the sentiment of text.Arguments:text: the text sentiment to be predicted"""index = learn.predict("This was a great movie!")[2].numpy().argmax()print("Predicted sentiment: {}".format(mapping[index]))def evaluate():"""Evaluates the networkArguments:NoneReturns:accuracy: float"""texts = df_test['text'].valueslabels = df_test['label'].valuespreds = []for t in texts:preds.append(learn.predict(t)[1].numpy())acc = (labels == preds).mean() * 100print("Test Accuracy: {}".format(acc))return preds, labelsget_sentiment("This is amazing")preds, labels = evaluate()print(classification_report(labels, preds, labels=[0,1,2]))print(confusion_matrix(labels, preds))

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

模型结果

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

混淆矩阵

  • 如你所见,我们的模型很好,但可以通过试验超参数来改进。
  • 如果我们看到混淆矩阵,我们可以看到我们的模型对大多数类别进行了正确的分类。
  • 黑色代表 0,从图上看,我们得到的大多数预测都是黑色的

结论和未来方向

到得出结论,我们取得以下结果:

  • 我们使用美国航空公司的推文数据库训练一个模型来预测推文的情绪。
  • 我们使用 ULMFit (Ruder 等人,2018 年)通过上面给出的新技术来训练我们的模型。
  • 我们使用流行的 fastai 库来训练模型,因为它包含 AWD-LSTM 的预训练权重。
  • 我们实现了 94 的测试准确度,由于我们的数据集不平衡,我们使用 F1 分数等指标。
  • 我们得到一个 F1 分,即 89 的准确度。
  • 我们使用混淆矩阵进一步检验我们的模型的性能。

为了建立一个更好的模型,我们还可以使用其他语言模型和技术,如 BERT、use、Transformers、XLNet 等。

Colab 笔记本:https://Colab . research . Google . com/drive/1 eismifjg 1 aengepsfseb 55 bjcciop 5 pq?usp =共享

混合蛙跳算法综述

原文:https://towardsdatascience.com/a-survey-on-shuffled-frog-leaping-algorithm-d309d0cf7503?source=collection_archive---------27-----------------------

自然;人类最优秀的老师

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

穆罕默德·N·穆罕默迪的图片

T 何混合蛙跳算法(SFLA)是受自然界中青蛙的社会行为启发的最具创新性的优化算法之一,在分类方面,行为算法或模因算法都包含在其中。蛙跳优化算法的其他名称包括蛙跳算法、蛙跳算法和 SFLA 算法。该算法由 Eusuff 和 Lansey 在 2003 年首次提出,尽管此后提交了许多论文来改进该算法。在下载链接的底部是青蛙优化算法的主要文章。

什么是 SFLA 算法?

SFLA 算法是一种基于元启发式模因论的算法。memetic 算法是一种基于种群的算法,用于复杂而重要的优化问题。该算法的主要思想是在遗传算法的结构中使用一种局部搜索方法来提高搜索强化过程的水性能。memetic 算法首先加密初始答案的总和,然后 Ibn 算法基于一个适应度函数计算每个答案的效用,并生成新的解。

SFLA 算法的灵感来自青蛙寻找食物的方式。该算法使用诺模法在青蛙子群中进行局部搜索。青蛙混合跳转算法使用混合策略,并允许在局部搜索中交换消息。该算法结合了诺模算法和粒子群优化的优点。在青蛙混合跳转算法中,不仅在局部搜索中而且在全局搜索中交换单词。因此, 局部全局 搜索在该算法中得到了很好的结合。青蛙混合跳转算法是高度可搜索和易于实现的。青蛙混合跳转算法可以解决许多非线性、不可检测和多状态问题。

青蛙变异算法的描述

该算法结合了两类基于遗传算法(如模因论)和基于社会行为算法(如粒子群鸟算法)的优点。它试图在可能的答案空间中的广泛审查之间取得平衡。在这种群体算法中,一群青蛙(答案)组成,每只青蛙在遗传算法中都有一个类似染色体的结构。青蛙的整个种群被分成更小的组,每组代表不同类型的青蛙,它们分散在答案空间的不同地方。然后,每组青蛙开始在它们的栖息地周围进行精确的局部搜索。

每一类中的每一只青蛙都受到其群体中其他成员以及其他群体的影响。几个步骤之后,混合发生了,信息在所有组中传播,以建立收敛和到达答案的条件。如何在该算法中找到最优解包括全局和局部搜索两个阶段。

初级种群形成

在初始种群的形成中,首先确定群体的数量和每个类别中应该有的青蛙数量。如果群体的数量和每个群体中青蛙的数量被认为是 1,那么样本的总数量将是 F = m * n。然后为生产的所有样本计算成本函数。分类和分配基于计算的成本函数来计算选择的青蛙的总数,使得具有最低成本函数和最佳位置的示例在第一位置。最佳青蛙的位置存储在整个种群中。然后将所有的青蛙分成 m 个选定的类别,这样每个类别中就有一只青蛙。

划分方法如下:在有序群体中,第一个成员在第一个类别中,第二个成员在第二个类别中,依此类推,直到受托人被选择并被置于“m”类别中,然后 1 + m 成员将在第一个类别中,因此划分青蛙的过程将继续。

群体的进化青蛙在每个群体的不同类别之间的划分以预定的数量重复进化的步骤。在这个步骤之后,所有的青蛙被组合,并且重复全局搜索步骤。

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

SFLA 流程图

SFLA 蛙跳算法的步骤

SFLA 算法的元探索策略按照以下步骤概括为全局探索和局部探索两个主要阶段。

全球勘探阶段

  • 第一步:初始化

选择 M,N. M 代表 memeplex 的数量,n 代表每个 meme plex 中青蛙的数量,所以池塘的总种群大小由关系式 f = m * n 得到。

  • 步骤 2:虚拟人口的产生

从可用空间中,采样 F 个虚拟青蛙 U(1),U(2),…,U(F)。计算每个 U(i)的能力值。

u(I)=(ui1 \u 2,…\u Uid)。此外,d 是决策变量的数量。

  • 步骤 3:对青蛙进行分级和分类

将青蛙按优劣降序存放在数组 X = {U(i),f(i) & i=1…,F}中。记录种群中最好的 Px 蛙的位置。(U = Px(1))。

  • 第四步:把青蛙分成复合物

将数组 X 分成 Y,每个数组包含 n 只青蛙。

  • 第五步:模因论在每个模因丛中的进化

每个 Yk memeplex(k = 1,2,3,…,m)由下面描述的局部搜索蛙跳算法进化而来。

  • 第六步:合并 memeplexes

在每个模因丛中发生一定数量的模因进化后,将模因丛(Y1,…,Ym)置于 X 中,使得关系 X = {Y(k),k = 1,2,…。,m}成立。然后,更新(Px)种群的最佳位置。

  • 步骤 7:趋同研究

如果满足收敛条件,则停止。否则,转到全局搜索的第四步。

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

穆罕默德·N·穆罕默迪的图片

当地探险步骤:

在全局搜索的第五阶段,每个迷因复合体的进化被独立执行 N 次。在 memeplexes 进化之后,算法返回到全局搜索以完成组合。以下描述了每个 memeplex 中本地搜索的详细信息:

  • 步骤 1:初始化

将中的 im、置零,im 统计 memeplexes 的个数,iN 统计进化步数。

  • 第二步:1 + im = im
  • 第三步:1 + iN = iN
  • 步骤 4:创建一个子复合体

青蛙的目标是通过改善它们的迷因来移动到最佳位置。选择子丛的方法是给性能较高的青蛙分配较多的权重,给性能值较低的青蛙分配较低的权重。权重通过三角概率分布来分配,Pi = {2(j-1 + n) / n(n+1),j = 1,…,n}。为了构建子 memeplex Z 数组,从每个 memeplex 的 n 只青蛙中随机选择 q 只青蛙。子丛中的那些分别用 PB 和 PW 表示。

  • 第五步:纠正最差青蛙的位置。

子模板中最差的青蛙(具有最差性能的青蛙)的新位置通过关系 U(q) = S + PW 来计算。s 是青蛙的步长(跳跃的速率),它将被获得:

如果新位置比前一个位置更好,那么用前一个 U(q)替换新的 U(Q ),并转到局部搜索的步骤 8。否则,转到本地搜索的步骤 6。

  • 第六步:用 PX 计算步长。

如果在步骤 5 中没有获得更好的结果,那么使用下面的等式计算青蛙的步长:

并且通过关系式 U (q) = S + PW 来计算新位置(U(q))。如果 U(q)在可能的空间内,则计算新效率 f(q)的值。如果 f(q)新的优于前一个,那么用前一个 U(q)替换新的 U(q ),进入局部搜索的第八步。否则,转到本地搜索的第七步。

  • 第七步:审查

如果新位置不在可实现区域内或不比先前位置好,则在可用位置随机产生新的辙叉(r ),并替换其新位置不适合前进的辙叉。计算 f®,设 U(q)等于 r,f(q)等于 f®。

  • 第八步:更新 memeplex。

在子丛中最差的青蛙模仿变化后,将 Z 中的青蛙放在 Yim 上它们原来的位置。按性能降序排列 Yim。

  • 第九步:如果 N > iN,转到第三步本地搜索。
  • 第十步:如果 m > im,则进入本地搜索的第一步。否则,返回全局搜索以合并 memeplexes。

希望有帮助。如果您对 Linkedin 有任何问题或反馈,请告诉我。

Common Lisp 快速入门

原文:https://towardsdatascience.com/a-swift-introduction-to-common-lisp-16a2f154c423?source=collection_archive---------18-----------------------

熟悉有史以来第二种高级编程语言。

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

在 1958 年,一个新成员以第二高级和第一函数式编程语言 Lisp 的形式出现了。Lisp 是一种伟大的开源语言,尽管它已经存在了很长时间,但这些年来一直在不断地发展。此外,Lisp 已经发展成许多更小的方言,这些方言通常允许在 Lisp 内部更容易地完成特定的任务。Lisp 是一种很棒的语言,因为它得到了很好的支持,有很好的文档记录,并且非常受人尊敬。最流行的现代 Lisp 方言有 Common Lisp、闭包、Scheme、Machine Lisp、Arc,当然还有 Emacs Lisp。

如果你来自任何一种不是基于 Lisp 本身的语言,Lisp 是一种非常不同的语言。Lisp 编程非常具有功能性,它围绕着使用宏来断言数据的功能。这是一件需要注意的重要事情,因为语法一点都不相似。

获取 CLisp

Common Lisp (CLisp)实际上是可爱的 GNU 基金会的产品,并且是完全免费和开源的。要在非 Unix 系统上安装 Common Lisp,您需要从 SourceForge 或其他地方找到的镜像下载二进制文件。由于我不知道如何在 Windows 上安装应用程序,我就不讲我不知道如何做的东西了。至于 Linux,你当然可以使用你的包管理器,在我的例子中是 dnf。

sudo dnf install clisp

至于 MacOS,你也可以通过你的软件包管理器来安装它:

brew install clisp

(这里是公式化)

要测试您的 CLisp 安装,只需在终端中输入以下命令就可以进入 REPL

clisp

变成巴什。

基本语法

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

今天,我将专门在 REPL 工作。这是为了确保文本编辑保持编译器、编辑器和语法高亮之间的一致性,而且我们不必保存文件。因此,首先,我将像之前一样使用命令进入 CLisp REPL

clisp

关于 Lisp 首先需要了解的是语法。Lisp 的语法当然很漂亮,也很酷,但最重要的是它是独一无二的。在 Lisp 中,几乎所有的命令都包含在括号中,并且使用空格作为语法,所有的命令都不区分大小写(所有的命令都是大写的)。)在我开始解释 Lisp 之前,我认为需要解释 Lisp 的范例,函数式编程范例。这对于学习 Lisp 非常重要,尤其是在学习非函数式语言的时候。

阅读更多关于函数式编程的内容(由我!)

首先,构造类型只能保存数据,不能保存函数。Lisp 的独特之处在于数据可以作为代码使用,甚至可以在后台编写代码。构造类型被称为构造函数,与面向对象的类不同,尽管它们填补了同样的空白。换句话说,如果不使用多态,我们就不能将函数作为构造函数的属性来应用。例如,在 Python 中,我们可以有一个名为 cl 的类,该类可以有一个子类,并有可以用 cl.function 或 cl.subclass 调用的子方法。

换句话说,Lisp 函数调用总是以方法开头,而不是以变量开头。这也可以和另外两种函数式语言相提并论,它们是我一生的挚爱,

朱莉娅

另一个很酷,

稀有

所以很可能来自这两种语言会让你更接近。所以让我们从定义一个变量开始。当我们命名一个变量时,注意语法的结构是很重要的。在下面的例子中,我使用 setq,它将生成一个全局变量。我们使用 setq 的方式与使用 Lisp 中任何其他函数的方式基本相同。

 v-method   vvv-Variable Value
(setq x '(5 4 8 4))
      ^-Variable Name

这将创建一个我们可以用列表类型的 x 调用的变量,它是通过在括号前放一个’来定义的。下面是 Lisp 中的简单加法:

 vvv Parameters
(+ 5 5)
 ^ Method (addition)

这里有一个类似的例子,打印一个字符串:

(prin1 "Hello World!")

要记住的最重要的事情是方法和变量是如何对齐的,因为这将使你更习惯于在 Lisp 中调用函数的方式。

函数和 For 循环

Lisp 中的函数是用 defunc 定义的。我们可以定义一个函数,它有一个名字,和一组参数,参数之间用空格分开,放在一组单独的括号中。

(defunc add (x y)
; (We'll add logic later)
)

这个函数定义非常典型,就好像我们把它与 Python、Julia 和 R 相比,R 是唯一一个显著不同的。

计算机编程语言

def add(x, y):

朱莉娅

function add(x, y)

稀有

add <- function(x, y){}

因此,给定我前面展示的添加 5 + 5 的代码,很容易猜到我们在这里需要做什么,特别是有了其他语言的经验之后。

(defunc add (x y) (+ x y))

是的,真的就这么简单。

当我学习一门新语言时,我总是喜欢写一个函数,它是一个均值函数。虽然这是非常基本的,但是尝试写一个需要 sigma(总和)和 n(样本大小)。)求和以及样本大小对于很多编程都是必不可少的,尤其是统计编程,这也是我特别使用 Lisp 的原因。

如上所述,我们需要两个东西,n 和σx。幸运的是,Lisp 有一个长度函数,可以这样使用:

(length x)

很简单,对吧?唯一的问题是求和没那么简单。为了对数组求和,我们需要使用 reduce。我们可以通过简单的操作做到这一点:

(defun sum  (x) (reduce '+ y)
)

Lisp 中的 Reduce 是一种简单的说法,即从开始处开始,到列表的末尾。为了进行这样的操作,因为它是基于数组的,我们需要使用’+操作数,而不是+操作数。现在,我们可以用我们的函数来总结一个数组:

(sum x)

现在我们已经有了求和的方法,我们需要决定如何来设计这个函数。以最简洁的方式,不定义任何变量,并通过计算建立回报。这当然是编写这个函数的最佳方式,但是以这种方式思考公式可能会特别令人困惑——所以在这种情况下,我每次都会使用它,而且在大多数情况下我都会这样做。然而,当有大量的数学运算时,这可能会很困难,有时会导致使用更多的编译能力和内存。)

但是首先,让我们写出我们的平均函数。

(defunc mean (x) (/ (sum x) (length x))

为了更好地理解这一点,我们首先在括号中进一步计算数学(运算顺序),然后对 sigma 和 n 执行除法运算。

为了使用我们的函数,记住‘是指数组,所以在 Lisp 中创建一个数组,我们使用:

(setq x '(5 8 4 6 8))

所有的暗都被空间隔开。

至于 for 循环,想象一下 Python、Julia 或 R 中典型的简明 for 循环:

x = [u = u * 5 for u in x]

在 Lisp 中,我们将完全遵循这种循环风格,除了一个例外,我们将首先在括号中使用 loop,并且逻辑将需要翻转,使用单词“do”来代替,就像这样:

(loop for w in array do (+ w 1))

这当然只是给每个元素加一。另一个需要记住的重要事情是,do 后面的括号之外的任何逻辑都不会包含在循环中,这意味着层次结构中的所有内容都将期待一个返回,类似于我们的 mean 函数,操作的顺序决定了先做什么。

再用力一点…

最后一部分,我们要写一个函数来计算标准差。为了计算一个数组的标准差,我们需要μ。幸运的是,我们刚刚创建了一个函数,它将为我们提供 mu。使用 mean 函数和 setq,我前面谈到的全局变量定义(这会使 dims 公开,这并不总是一个好主意,但我认为知道如何使用全局变量比私有变量更好。)我们可以将平均值定义为μ,并使用一个简单的 for 循环来计算。在 for 循环内部,我们有(x 减去 mu),我们可以通过将这个数乘以它本身来执行。

正如我前面讨论的,这个选项可能不总是优于 setq,为了看起来更简洁,可能不值得这样做。无论如何,在我们将这个 for 循环应用到我们的列表之后,我们将能够求平均值的平方根并返回标准偏差。

(defun std (x) (setq μ (mean x)) (loop for y in x do
  (* (- x μ) (- x μ)))) (sqrt (mean x)
)

总结一下…

我喜欢编写 Lisp,我真的希望这篇文章能为有兴趣学习它的人提供很多信息。我有可能在未来做类似的工作。在我看来,Lisp 是一种美丽的语言,它在我心中占有一席之地。虽然 Lisp 肯定不同于许多其他语言,但我认为它的语法看起来很酷也很漂亮。在相关新闻中,我的 Julia 模块,用于机器学习、统计和数据处理的车床即将进入 Lisp、Python 和 R,Python 和 R 在 Julia 中本地运行包,Lisp 从包的 Lisp 端口本地运行包。此外,这让我对 Lisp 感到兴奋和激动。

Julia 对 Flux 的快速介绍(使用 CUDA)

原文:https://towardsdatascience.com/a-swift-introduction-to-flux-for-julia-with-cuda-9d87c535312c?source=collection_archive---------21-----------------------

用 Flux 在 Julia 中建立你的第一个渐变模型

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

(src = http://fluxml.ai)

自从经典的 Mocha.jl 时代以来,Julia 中的机器学习已经走过了漫长的道路,对该生态系统做出贡献的最具开创性的创造之一是 Flux.jl. Flux 是 Julia 的权威梯度下降库,可以与 Python 的 Tensorflow 相提并论。Flux 遵循与许多 Julia 包类似的概念,如 Lathe.jl 和 DataFrames.jl,只用大约 1000 行代码编写,并且只依赖于 Julia 本身。与 Tensorflow 和 Pytorch 等解决方案相比,它们都使用各种语言,包括 C++、Go 和 C。

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

(src = http://juliacomputing.com)

Julia 的一个优点是并行计算平台和多线程与语言的无缝结合。没有比这更形象化的了(明白吗?相比 NVIDIA 图形处理器的古老平台 CUDA。Julia 和您的硬件之间的紧密集成很好地延续到 Flux 中,使 Flux 和 CUDA 成为真正的天作之合。将机器代码中的零标志设置为一,系好安全带,因为这肯定会令人兴奋!

获取数据

对于我今天的样本数据,我选择了来自 MLDatasets.jl 的数据集,它是可爱的 Julia Computing 的产品,您可以使用 Pkg 添加它:

using Pkg;Pkg.add("MLDatasets")

或者,在 Pkg REPL:

bash -$ julia
julia> ]
pkg> add "MLDatasets"

我通常不从常用的包中选择数据集,但是我做了这个例外,以确保这段代码不需要任何下载就可以重现(至少不需要通过您的 web 浏览器)。我要使用的数据集是时尚敏斯特数据集,我们可以这样下载:

**using** MLDatasets FashionMNIST.download(i_accept_the_terms_of_use=true)
train_x, train_y = FashionMNIST.traindata();  
test_x,  test_y  = FashionMNIST.testdata();

您还可以选择添加一个验证集,或者用 Lathe 分割您自己的数据集:

using Pkg; Pkg.add("Lathe")
using Lathe.preprocess: TrainTestSplitusing DataFrames
# Validation:
train_x, train_y = FashionMNIST.traindata();
test_x, test_y = FashionMNIST.testdata();
df = DataFrame(:Feature => train_x, :Target => train_y)
train, val = TrainTestSplit(df)f = :Featuret = :Target
val_x = val[f]
val_y = val[t]
train_x = train[f]
train_y = train[t]# Bring your own data:
using CSV
df = CSV.read("data.csv")
train, test = TrainTestSplit(df)

因为我的数据集处理图像,所以我应该将数据从各自的文件格式转换成图像,我们可以这样做:

**using** ImageCore
FashionMNIST.convert2image(FashionMNIST.traintensor(4))

建模

首先,我们需要导入通量本身:

**using** Flux, Statistics 
**using** Flux: onehotbatch, onecold, crossentropy, throttle, params **using** Lathe.stats: mean 
**using** Base.Iterators: partition 
**using** Random

我还直接从 Flux 导入了几个模块包括 onehotbatch,onecold,crossentropy,throttle,params,还有从 Lathe.stats 导入的 mean 函数,从 Julia 的迭代器导入的 partition,还有 Random。所有这些都是我们可以用来制作通量模型的拼图的一部分。下一步将是构建模型链。这是 Flux 真正闪光的地方,因为与大多数其他机器学习库不同,Flux 的渐变层使用链工作。Flux 使用 Julia 语言中各种独特而令人敬畏的语法点的组合来创建一个非常优雅的机器学习环境,chain 就是一个很好的例子。

model() = Chain(
  Conv((5, 5), 1 => 64, elu, pad=(2, 2), stride=(1, 1)),
  BatchNorm(64),
  MaxPool((3, 3), pad=(2, 2), stride=(2, 2)),
  Dropout(0.25),
  Conv((5, 5), 64 => 128, elu, pad=(2, 2), stride=(1, 1)),
  BatchNorm(128),
  MaxPool((2, 2), stride=(2, 2)),
  Dropout(0.25),
  Conv((5, 5), 128 => 256, elu, pad=(2, 2), stride=(1, 1)),
  BatchNorm(256),
  MaxPool((2, 2), stride=(2, 2)),
  Dropout(0.25),
  x -> reshape(x, :, size(x, 4)),
  Dense(2304, 256, elu),
  Dropout(0.5),
  Dense(256, 10),
  softmax) |> gpu

接下来,我们需要为我们的训练数据获取 N:

N = size(train_x)[**end**]

现在,我们可以使用 N 通过范围迭代来随机混洗和排列我们训练索引:

ixs = collect(1:N)
shuffle!(ixs)
n = Int(floor(.9 * N))

这里需要注意的重要一点是,我们的数据需要存储在子数组或字典中。鉴于这将适用于字典,它很可能也适用于数据帧。将我们的数据转换成 Flux 批处理可以接受的格式后,我们可以像这样对数据进行批处理:

**function** make_batches(data; bs=100)
    n = size(data[1])[**end**]
    sz = (28, 28, 1, bs)
    iter = [(reshape(Float32.(data[1][:, :, i]), sz), onehotbatch(data[2][i], 0:9)) **for** i **in** partition(1:n, bs)] |> gpu
**end**

train = make_batches(train)
val = make_batches(val)
test = make_batches(test);

现在,我们简单地用预期回报构建我们的模型:

m = model()

这是输出:

**Chain(Conv((5, 5), 1=>64, elu), BatchNorm(64), MaxPool((3, 3), pad = (2, 2), stride = (2, 2)), Dropout(0.25), Conv((5, 5), 64=>128, elu), BatchNorm(128), MaxPool((2, 2), pad = (0, 0, 0, 0), stride = (2, 2)), Dropout(0.25), Conv((5, 5), 128=>256, elu), BatchNorm(256), MaxPool((2, 2), pad = (0, 0, 0, 0), stride = (2, 2)), Dropout(0.25), #9, Dense(2304, 256, elu), Dropout(0.5), Dense(256, 10), softmax)**

我没有为这个特定的模型进行超参数调整,所以很可能只需要一点优化就可以提高精度。

接下来,我们需要一个度量函数,它将允许我们的模型检测它什么时候做得好或者坏。为此,我们需要三大部分:

尝试、验证、重建

我喜欢把这种尝试称为网络学习任何东西之前的初步猜测。验证是该过程中的一个重要步骤,模型需要检测它是变得更准确了,还是变得不准确了。最后但同样重要的是,重构是一个递归过程,在这个过程中,猜测被恢复并从中学习。这是我的函数:

**function** met(data)
    **global** batch_idx
    acc = 0
    **for** batch **in** data
        x, y = batch
        pred = m(x) .> 0.5
        tp = Float32(sum((pred .+ y) .== Int16(2)))
        fp = Float32(sum((pred .- y) .== Int16(1)))
        fn = Float32(sum((pred .- y) .== Int16(-1)))
        tn = Float32(sum((pred .+ y) .== Int16(0)))
        acc += (tp + tn) / (tp + tn + fp + fn)
    **end**
    acc /= length(data)
    push!(eval_acc, acc)
    **if** batch_idx % 100 == 0
        @show(batch_idx)
    **end**

    batch_idx += 1
**end**

然后我们可以将所有这些部分插入语法表达式:

loss(x, y) = crossentropy(m(x), y)
evalcb = () -> met(val)

然后训练我们的模型!

Flux.train!(loss, params(m), train, opt, cb = evalcb)

现在,我们可以使用相同的度量函数来检查我们的精度:

met(test)
println("accuracy:", eval_acc[1])

百分之九十七的准确率!

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

结论

Flux 的语法、表达式和速度使其成为在 Julia 工作的数据科学家的一个非常有价值的工具。Flux 在许多测试中击败了竞争对手,因为它体积小、简单、快速且有效。Flux 的另一个巨大好处是模块化模型可以是什么样的,正如我通过在一个链中构建我的网络层,然后在其上传递更多内置来说明的那样。总的来说,我对 Flux 的发展以及 Julia 在机器学习和统计方面的整体发展感到兴奋。如果你对 Flux 感兴趣,另一个你可能感兴趣的很酷的东西是 KNet,我将很快写一篇关于它的“快速介绍”!你现在可以亲自去看看 Metalhead.jl,这是一个用 Flux 编写的图像分类器,可以适应新数据,并可回收用于任何分类用例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值