TowardsDataScience-博客中文翻译-2019-三十五-

news/2024/10/13 15:33:47

TowardsDataScience 博客中文翻译 2019(三十五)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

如何保护云中的健康数据

原文:https://towardsdatascience.com/how-to-secure-health-data-in-the-cloud-541fbdad811a?source=collection_archive---------16-----------------------

数据保护是一个大新闻,人们开始意识到保持健康数据安全的重要性。在这篇博客中,我将探讨数字健康公司应该使用哪些数据安全技术来保护您的健康数据的安全。

我一生都在研究健康数据安全。我在医疗保健 IT 巨头 GPI 做了 4 年的软件架构师。然后,我对这个主题的热情让我完成了一个博士学位。2014 年,我将我对商业和数据安全的兴趣结合起来,创建了 Chino.io ,这是一家专注于数字健康的网络安全公司。

五年后的今天,GDPR 让所有人都关注这个话题。数据保护不再仅仅是一项“值得拥有”的功能。最近,我在看到了许多案例,在这些案例中,公司因为犯错而遭受巨额罚款和名誉损失。2019 年早些时候,英国 IPO 因违反 GDPR 对英国航空公司和马里奥特处以总计 3 . 2 亿€的罚款。在这两起事件中,违规都与糟糕的数据安全实践有关。

遗憾的是,你不能依靠你的云提供商来确保你的应用安全。保护健康数据需要你做比 Azure 或 AWS 所能提供的更多的事情。

背景

在读博士期间,我意识到妥善保护健康数据极其困难。从法律上讲,健康数据受到特殊对待,因为它非常敏感。在美国,它受《健康保险流通与责任法案》( HIPAA )保护。而在欧盟,根据 GDPR和的规定,它被定义为一个特殊的个人数据类别。

这些法律对数据安全采取了非常不同的方法。HIPAA 对数据安全给出了精确的指示,而 GDPR 谈论的是提供“最先进的”安全。但是,最终的结果是一样的。有些特定的数据安全和管理措施是你必须实施的,而这些并不容易做好。

2017 年,谷歌 DeepMind 因不当访问 160 万患者的健康数据而被判有罪。这场争议对他们的 Streams 应用程序的声誉产生了持久的影响。

数据保护与数据安全

在这一点上,澄清数据保护和数据安全之间的区别可能是有用的。数据保护是指保护个人数据的安全。这是通过结合组织措施和数据安全来实现的。组织措施包括用户协议、关于谁可以访问数据的政策、关于数据可以存储多长时间的准则等。数据安全性与您如何存储数据有关,以便只有被允许的人才能访问这些数据。本文主要关注数据安全性。

健康数据的数据安全性

历史上,健康数据存储在本地。例如,每家医院都有自己的患者记录服务器。然而,电子医疗应用程序需要数据在应用服务器上可用。这些服务器通常位于云中。正确保护这些数据很难。使用了 3 种关键技术:加密、假名化和匿名化。让我们详细看一下其中的每一个。

加密

数据加密通过使用合适的加密操作对数据进行编码来保护您的数据。您可以加密静态数据(例如,存储在您的设备或服务器上的数据)或传输中的数据(通过网络)。如下图所示,有三种主要的加密形式。

通常,数据库级安全性对于大多数数据来说已经足够好了。这就是云提供商为客户提供的服务。但是,对于健康数据,您应该使用记录级(应用程序级)加密。在这里,每个单独的记录都用自己的密钥加密。对于保护敏感聊天(例如医生和患者之间的聊天),端到端加密可能更合适。在这里,消息在发送到网络之前被加密,并且只能由接收者解密。这些技术不是主流云提供商提供的。

假名化

假名化包括用假名替换所有的个人标识符。这可能是一个真实的假名,但通常是一个数字或字母数字标识符。假名是随机生成的。这一过程如下图所示。

假名在数据保护中被用来掩盖一个人的身份。然后,敏感数据可以与假名一起存储,而假名和相关个人信息的列表(映射)被分开存储。这使得攻击者更难窃取数据。但是,假名数据仍然算作个人数据。

匿名化

匿名包括完全删除所有个人数据,然后混淆或掩盖剩余数据。这样做的目的是确保您无法从剩余的数据中重新识别特定的个人。标准技术包括概括、交换、扰动和聚合。众所周知,正确对待匿名非常困难。下图显示了聚合的工作原理。

问题是,匿名化要求将根据数据的独特性而变化。例如,如果你有一组 20 个病人,但只有一个超过 50 岁,那么简单地将年龄四舍五入到最近的十年是不够的。人们对不同的技术进行了大量的研究,如 k-匿名和差分隐私,这些技术试图保证数据的匿名性。

我应该使用哪种数据安全技术?

在设计电子医疗应用程序时,您需要了解使用哪种技术或技术组合。当我向客户提供建议时,我首先会问他们的使用案例是什么。他们是否只需要存储数据,是否需要能够搜索数据,或者是否需要将数据用于商业智能和分析。

存储健康数据

如果您只想安全地存储健康数据,最好的方法是使用记录级加密。然而,有几个问题你需要明白。

  1. 记录级加密很难实现。它需要密钥管理和强大的登录和权限系统来控制谁可以访问密钥。
  2. 数据在数据库中被加密。这意味着您无法直接搜索它。您需要考虑这对您的应用程序设计的影响。
  3. 像这样的加密数据库永远不会像未加密数据库那样响应迅速。在设计应用程序时,您需要记住这一点。
  4. 理想情况下,您需要将用户详细信息和记录数据存储在不同的系统中。这增加了一层额外的保护。它还允许您减少加密的数据量。

共享健康数据

通常,您需要能够在受信任的各方之间共享健康数据。例如,一个病人,他们的家庭医生和医院顾问。这里,重要的是提供强大的 AAA 控制。AAA 代表认证、授权和计费。它用于控制谁有权访问数据,允许他们对数据做什么,并记录每次数据访问/更改。

通常,你只需要分享实际的健康数据,而不是随之而来的个人信息。这通常是您的系统使用 AI 来分析扫描和患者观察数据的情况。在决定加密哪些数据时,这是您应该考虑的事情之一。

分析健康数据

大数据是大新闻,即使这些数据像健康记录一样敏感。例如,制药公司可以从分析和理解典型的患者档案中获得巨大的利益。这就是数据匿名化的用武之地。问题是,匿名健康数据尤其困难。很多时候,留下的数据对任何有意义的分析都不再有用。

结论

确保数据安全总是很重要的。但是健康数据让这个问题变得更加困难。你不能只是把问题委托给你的云提供商。既然您已经了解了相关技术,那么您就知道应该向您的技术团队提出哪些正确的问题,以确保您不会与 GDPR 或 HIPAA 发生冲突。

关于作者

Jovan Stevovic ,博士在完成博士学位后于 2014 年联合创办了 Chino.io 。Jovan 是健康数据的数据保护、隐私和安全方面公认的专家。他担任过 5 个创业加速器的顾问,是柏林和整个欧盟健康技术社区的受人尊敬的成员。

如何保护你的 Azure 数据工厂管道

原文:https://towardsdatascience.com/how-to-secure-your-azure-data-factory-pipeline-e2450502cd43?source=collection_archive---------13-----------------------

1.介绍

Azure Data Factory (ADFv2)是一个流行的工具,用于协调从内部到云的数据接收。在每个 ADFv2 管道中,安全性都是一个重要的主题。常见的安全方面如下:

  • Azure Active Directory (AAD)对数据和端点的访问控制
  • 管理身份(MI)以防止关键管理流程
  • 数据和端点的虚拟网络(VNET)隔离

在本博客的剩余部分,将讨论如何使用 AAD、MI、VNETs 和防火墙规则来保护 ADFv2 管道。关于 Azure 功能安全性的更多细节,请参见我的另一篇博客。关于如何使用快照和增量备份来防止数据湖中的数据丢失的解决方案,请看这个博客。

更新 2020–07–26:现在可以在一个 托管的 VNET 中运行 ADFv2 Azure 托管集成运行时。这是在公共预览,这个博客还没有更新这个功能。

2.Azure 数据工厂管道的架构

在这个 ADFv2 管道中,数据从 SQLDB 中读取,使用 Azure 函数进行转换,并写入 ADLS gen2 帐户。该项目的架构可以在下面找到。

2. Azure Data Factory pipeline architecture

Azure 服务及其在本项目中的使用描述如下:

  • SQLDB 被用作包含将被复制的表格数据的源系统。
  • Azure 数据工厂 v2 (ADFv2)被用作将数据从源复制到目的地的编排器。ADFv2 使用一个自托管集成运行时 (SHIR)作为计算,它运行在 VNET 中的虚拟机上
  • Python中的 Azure 函数用于解析数据。函数无法访问其他 Azure 资源
  • Azure 数据湖存储 gen2 (ADLS gen2)用于存储来自 10 个 SQLDB 表的数据和由 Azure 函数创建的元数据文件
  • ****Azure Active Directory(AAD)是微软的身份和访问管理服务,用于对 Azure 资源进行认证和授权

以下安全方面是该项目的一部分。

  • AAD 访问控制 : SQLDB、ADLS gen 2、Azure 函数只允许 ADFv2 的 MI 访问数据。这意味着不需要在 ADFv2 或密钥库中存储任何密钥。
  • 防火墙规则 : SQLDB、ADLS gen 2、Azure Function 都有防火墙规则,只允许 SHIR 的 VNET 作为入站网络

在下一章中,将实现 ADFv2 流水线架构。

3.创建和部署 ADFv2 管道

在本章中,将执行以下步骤来创建和部署 ADFv2 管道。

  • 3a。安装准备工作和资源
  • 3b。在 ADFv2 中创建自托管集成运行时
  • 3c。保护 ADLS 第二代帐户
  • 3d。安全 SQLDB 数据库
  • 3e。部署和保护 Azure 功能
  • 3f。配置并运行 ADFv2 管道

3a。安装准备工作和资源

在本教程中,资源的部署将尽可能使用代码来完成。需要安装以下资源:

  • 安装 Azure CLI
  • 安装 Azure PowerShell
  • 安装 Visual Studio 代码
  • 在 Visual Studio 代码中安装 Azure 函数 Python 库

安装好预备程序后,就可以安装基础资源了。打开 Visual Studio 代码,创建一个新的终端会话并执行下面的命令。

# Login with your AzureAD credentials
az login# set parameters
$rg = "<<Resource group>>"
$loc = "<<Location, e.g. westeurope>>"
$adfv2 = "<<Adfv2 name>>"
$sqlserv = "<<Logical sql server>>"
$sqldb = "<<SQLDB name>>"
$sqluser = "<<SQLDB username>>"
$pass = "<<SQLDB password, [use https://passwordsgenerator.net/](https://passwordsgenerator.net/)>>"
$adls = "<<adls gen 2 account, only alphanumeric>>"
$funname = "<<Azure Function name>>"
$funstor = "<<Azure Function storage>>"
$funplan = "<<Azure Function plan>>"
$vnet = "<<Azure VNET name>>"# create resource group
az group create -n $rg -l $loc# create Azure Data Factory instance
az resource create --resource-group $rg --name $adfv2 --resource-type "Microsoft.DataFactory/factories" -p {}# create logical SQL server and SQLDB
az sql server create -l $loc -g $rg -n $sqlserv -u sqluser -p $pass
az sql db create -g $rg -s $sqlserver -n $sqldb --service-objective Basic --sample-name AdventureWorksLT# create ADLS gen 2 account and container
az storage account create -n $adls -g $rg -l $loc --sku Standard_LRS --kind StorageV2 --hierarchical-namespace true
az storage container create --account-name $adls -n "sqldbdata"# create Azure Function
az storage account create -n $funstor -g $rg --sku Standard_LRS
az appservice plan create -n $funplan -g $rg --sku B1 --is-linux
az functionapp create -g $rg --os-type Linux --plan $funplan --runtime python --name $funname --storage-account $funstor# create VNET
az network vnet create -g $rg -n $vnet -l $loc --address-prefix 10.100.0.0/16 --subnet-name shir --subnet-prefix 10.100.0.0/24

3b。在 ADFv2 中创建自托管集成运行时

在这一部分中,将配置 ADFv2 中的自托管集成运行时。这将使用之前创建的 VNET 中运行的虚拟机来完成。执行下面的 Azure CLI 脚本。

# use the same parameters in step 3a, plus additional params below:$shir_rg="<<rg name>>"
$shir_name="<<shir name>>"
$shir_vm="<<name of VMs on which SHIR runs>>"
$shir_admin="<<name of VMs on which SHIR runs>>"
$shir_pass="<<VM password, [use https://passwordsgenerator.net/](https://passwordsgenerator.net/)>>"az group deployment create -g $shir_rg --template-uri [https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-vms-with-selfhost-integration-runtime/azuredeploy.json](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-vms-with-selfhost-integration-runtime/azuredeploy.json) --parameters existingDataFactoryName=$adfv2 existingDataFactoryResourceGroup=$rg existingDataFactoryVersion=V2 IntegrationRuntimeName=$shir_name NodeCount=2 adminUserName=$shir_admin adminPassword=$shir_pass existingVirtualNetworkName=$vnet existingVnetLocation=$loc existingVnetResourceGroupName=$rg existingSubnetInYourVnet="shir"

脚本可能需要 15 分钟才能完成。运行脚本后,您可以在 ADFv2 实例中验证它是否已成功部署,另请参见下文。

3b1. Self-hosted Integration Runtime successfully deployed

3c。保护 ADLS 第二代帐户

在这一部分中,ADLS gen2 帐户将受到保护。这是按如下方式完成的:

  • 添加 RBAC 规则,即只有 ADFv2 的 MI 可以访问 ADLS gen 2
  • 添加防火墙规则,只有 SHIR 的 VNET 可以访问 ADLS gen 2 容器

在这种情况下,Azure PowerShell 用于使用相同的变量配置规则

# Get params, PowerShell is used here, can be done in VSC terminal
Set-AzDataFactoryV2 -ResourceGroupName $rg -Name $adfv2 -Location $l
$adfv2_id = Get-AzDataFactoryV2 -ResourceGroupName $rg -Name $adfv2
$sub_id = (Get-AzContext).Subscription.id# Give ADFv2 MI RBAC role to ADLS gen 2 account
New-AzRoleAssignment -ObjectId $adfv2_id.Identity.PrincipalId -RoleDefinitionName "Reader" -Scope  "/subscriptions/$sub_id/resourceGroups/$rg/providers/Microsoft.Storage/storageAccounts/$adls/blobServices/default"New-AzRoleAssignment -ObjectId $adfv2_id.Identity.PrincipalId -RoleDefinitionName "Storage Blob Data Contributor" -Scope  "/subscriptions/$sub_id/resourceGroups/$rg/providers/Microsoft.Storage/storageAccounts/$adls/blobServices/default/containers/sqldbdata"# Turn on firewall
Update-AzStorageAccountNetworkRuleSet -ResourceGroupName $rg -Name $adls -DefaultAction Deny# Set service endpoints for storage and SQL to subnet
Get-AzVirtualNetwork -ResourceGroupName $rg -Name $vnet | Set-AzVirtualNetworkSubnetConfig -Name "shir" -AddressPrefix "10.100.0.0/24" -ServiceEndpoint "Microsoft.Storage", "Microsoft.SQL" | Set-AzVirtualNetwork# Add firewall rules
$subnet = Get-AzVirtualNetwork -ResourceGroupName $rg -Name $vnet | Get-AzVirtualNetworkSubnetConfig -Name "shir"
Add-AzStorageAccountNetworkRule -ResourceGroupName $rg -Name $adls -VirtualNetworkResourceId $subnet.Id

在最后一步之后,从 Azure 门户访问您的存储帐户将被拒绝(因为它不是 VNET 的一部分)。要允许从门户访问,您需要将您的 IP 地址列入白名单。

3d。安全 SQLDB 数据库

在这一部分中,SQLDB 将受到保护。这是按如下方式完成的:

  • 添加数据库规则,只有 ADFv2 的 MI 可以访问 SQLDB
  • 添加防火墙规则,只有 SHIR 的 VNET 可以访问 SQLDB

Azure PowerShell 用于配置规则。

# Configure AAD access to logical SQL server
Connect-AzureAD
$aaduser = "<<your aad user email address>>"
Set-AzSqlServerActiveDirectoryAdministrator -ResourceGroupName $rg -ServerName $sqlserver -DisplayName $aaduser# log in SQL with AAD (e.g. via portal query editor, SSMS or VSC)
# Execute following SQL statement
CREATE USER [<<your Data Factory name>>] FROM EXTERNAL PROVIDER;
EXEC sp_addrolemember [db_datareader], [<<your Data Factory name>>];# Add firewall rules
$subnet = Get-AzVirtualNetwork -ResourceGroupName $rg -Name $vnet | Get-AzVirtualNetworkSubnetConfig -Name "shir"
New-AzSqlServerVirtualNetworkRule -ResourceGroupName $rg -ServerName $sqlserver -VirtualNetworkRuleName "shirvnet" -VirtualNetworkSubnetId $subnet.Id

要从计算机进行访问以进行测试,您需要清空您的 IP 地址。

3e。部署和保护 Azure 功能

在这一部分,将部署 Azure 功能。这是按如下方式完成的:

  • 将源部署到功能
  • 添加防火墙规则,只有 SHIR 的 VNET 可以访问 Azure 功能
  • 添加只有 ADFv2 的 MI 才能访问 Azure 功能的 App 注册

第一步是使用这个快速入门在 python 中创建一个 Azure 函数。随后,更新 requirement.txt,init。py 并从这个 git 库添加 cdmschema.py。然后将您的函数发布到步骤 3a 中创建的$funname。要增强安全性,请使用以下 Azure CLI 脚本添加防火墙规则:

az webapp config access-restriction add -g $rg -n $funname --rule-name "shirvnet" --action Allow --vnet-name $vnet --subnet "shir" --priority 300

最后,对 Azure 函数的 AAD 访问可以通过向 Azure 函数添加一个 app 注册来配置,并且只允许 ADFv2 的 MI 访问 Azure 函数。参考这个教程和这个 PowerShell 脚本如何做到这一点。

3f。配置并运行 ADFv2 管道

在这一部分中,将配置和运行 ADFv2 管道。转到您的 Azure Data Factory 实例,选择设置一个代码存储库并导入下面的 GitHub 存储库 rebremer 和项目 adfv2_cdm_metadata ,见下文。

3f1. Setup code repository in ADFv2

只有管道 BlogADFv2sec 与这个博客相关。为 ADLS gen2、Azure Function 和 SQLDB 定制此管道的相关链接服务,另请参见下文。

3f2. Customize linked services in pipeline BlogADFv2sec

查看此链接如何使用 Applications Insights 登录 Azure 功能。下面是一个日志记录的例子。

3f3. Logging ADFv2 pipeline

最后一步,管道可以在 ADFv2 中运行。转到您的管道并单击 debug。当一切顺利时,所有的绿色检查将出现在输出中,如下所示。

3f4. Successful run of pipeline

4.结论

在这篇博客中,创建了一个部署安全 ADFv2 管道的架构,其中数据从 SQLDB 读取,使用 Azure 函数转换,并写入 ADLS gen2 帐户。其中,AAD 访问控制、托管身份、虚拟网络和防火墙规则用于保护管道,另请参见下面的架构。

4. Azure Data Factory pipeline architecture

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

如何销售你的数据集?

原文:https://towardsdatascience.com/how-to-sell-your-dataset-2b458175a738?source=collection_archive---------13-----------------------

构建新的人工智能商业模式

Source

作为一名顾问,我经常帮助公司认识到数据的战略重要性。大多数时候,决策者希望利用这些数据集来构建可靠的人工智能解决方案,但在某些情况下,他们将数据视为新的收入来源。因此,越来越多的公司正在探索将数据资产出售或授权给第三方的方法。

我希望这篇文章能帮助你更好地理解数据集在 AI 项目中的战略重要性,以及如何销售它们。

在当今世界,拥有大量数据并不是独一无二的。的确,数据本身越来越成为一种商品。然而,有效利用数据的能力可以成为竞争优势的来源。

从战略的角度来看,访问高质量的数据对于各种企业都变得越来越重要。事实上,数据非常有价值。它有助于创造优质产品,形成进入壁垒,并且可以直接货币化。

近年来,数据处理技术的重大进步推动了对数据的需求。云存储,新的数据科学技术,处理能力的提高,以及人工智能子领域的进一步发展和普及,都使公司能够从他们的数据资产中释放出新的见解,通常是以趋势,模式和关联的形式。

在人工智能背景下,挑战在于创建大型相关数据集,以便模型可以被训练,结果可以更准确。

数据是用文本、数字或多媒体表示的观察或测量结果(未处理或已处理)。数据集是一个结构化的数据集合,通常与一个独特的工作主体相关联。

我的数据集应该收费多少?

给数据集定价可能很棘手,但总的来说,我发现三个因素让数据集更有价值:

此外,其他人很难从头开始构建你的数据集,这也是一个强大的因素。根据我的经验,“最佳”数据集是符合预算、满足项目数据数量和质量需求以及时间限制的数据集。

最近,我不得不为一个计算机视觉项目购买一个数据集。选择可能是压倒性的,价格和方法各不相同。知道你到底在买什么,以及这个特定的数据集是否会对你的人工智能项目有所帮助,这一点至关重要。

根据您的项目,您可能只需要开放数据,但在许多情况下,CV 模型的真正优势只能通过收集专有训练数据来开发,这些数据类似于您期望您的最终模型在上工作良好的数据。这些数据通常是细微的,并且不同于一般可用的数据集。

为什么数据估值很重要?

一些决策者寻求将他们的数据货币化,以创造新的收入流。然而,他们往往低估了将数据暴露给第三方的可能后果。实际上,尽管越来越多的人认识到潜在的好处,但大多数组织对向公司外部公开什么数据非常谨慎。事实上,花时间评估您的数据的战略重要性,以确定销售您的数据集是否真的会影响您的竞争地位或实现您从中获益的能力,这是非常关键的。

在并购过程中,对数据资产不准确的估价会让股东付出高昂的代价(M&A)。

在您尝试从数据集获得收入之前,请确保它:

  • 可靠的

您必须能够验证您的数据是从可靠的来源收集的,并且是以不损害有效性的方式收集的。你还需要足够的数据和正确的数据才能有代表性的样本。这个元素在人工智能项目中很重要,可以避免偏见。

  • 相关的

您的数据必须符合客户的业务需求。显然,这些需求会因公司而异。因此,您必须了解他们的目标,并弄清楚您的数据集如何能有所帮助。此外,你应该确保它是有组织的,并且是他们可以使用的格式。

  • 所有权

不要以为因为你可以访问某些数据,这些数据就自动归你所有……例如,在医疗行业,确保你的数据集中的那些患者已经签署了一份合同,授权对他们的数据、图像等进行商业使用。而且在出售的时候,一定要让买家签下一份专门用于研究目的的合同,并加上一条不公开披露数据库中那些数据的条款。

  • 安全且匿名

重要的是,您的数据是安全的,并且可能是匿名的。有几种技术确实存在:
加密隐藏了数据,因此如果被盗就无法读取。否则可以使用标记化。它替换数据中的值,同时保留某些元素,但使用不同的流程来执行此操作。它始终保证信息的安全,您可以更加灵活地选择应该标记哪些字段,甚至可以只标记部分字段。

你的数据集值多少钱?

事实是,在数据集上贴上价格标签并没有精确的公式。可能基于多个属性,包括使用类型和频率、内容、年龄、作者、历史、声誉、收入潜力、安全要求等。此外,数据价值会随着时间的推移而变化,以响应新的公司优先事项、诉讼或法规。但是,这些元素应该有助于您更好地理解数据集的价值。有三种最常见的方法来评估数据集:

您还应该考虑其他因素,如数据量、收集数据的频率、数据集的完整性、信息的稀缺性、信息的组织、可靠性以及分析的难易程度。

现实情况是,大多数组织仍然专注于存储、保护、访问和分析大量数据的挑战,这些工作主要由信息技术(IT)部门负责。此外,他们中的大多数没有正式的数据评估实践。

作为战略资产的数据

对于一些公司来说,利用数据资产赚钱并不是一个新概念。的确,客户数据可以直接或间接产生货币价值。然而,越来越多的公司试图通过结合内部和外部数据来创建独特的数据集。

传统的有形资产通常表现出递减的使用回报。也就是说,它们用得越多,价值就越低。但是数据经常会随着使用次数的增加而增值。也就是说,被视为资产的数据可以展示出不断增加的使用回报。

的确,数据被使用得越多,价值就越大。换句话说,如果您将数据视为一种资产,那么它可以变得更有价值(它是不可耗尽的、不会退化的、持久的、具有战略意义的)。

另一个需要考虑的因素是使用时间:在正确的时间使用正确的数据,例如,在特定的零售销售时刻收集的交易数据可能具有非常高的价值。

公司能做什么?

在考虑出售数据集之前,公司制定数据评估政策至关重要。首先要有一个数据目录,这样所有的数据资产以及它们的用途都是已知的。总体而言,在整个公司范围内创建数据策略是确定数据价值优先级的第一步。

不幸的是,我意识到,当公司正在收购、出售或剥离拥有大量数据资产的业务部门时,他们往往会考虑数据估值流程。可以肯定的是,在未来,首席数据官的一些不断演变的职责可能包括为此目的对公司数据进行估值。

需要建立内部数据评估专业知识。

有数据卖和知道怎么卖不是一回事。一些公司依靠外部专家,而不是内部专家来评估他们的数据。随着数据和人工智能项目日益增长的战略重要性,这种情况可能会改变。

我认为,寻求将其数据资产货币化的公司将首先需要解决如何在自己的组织中获取和发展估值专业知识的问题。

了解如何评估公司数据资产的价值有助于确定哪些项目比其他项目更具战略意义。

原始和外部数据的重要性

由外部数据和内部数据组成的数据集的兴起还有一个有趣的因素。你接触的独立数据源越多,你的洞察力就越强。您可以将数据连接到其他专有数据集或公共数据集,以创建唯一的数据集。

此外,我们更倾向于原始数据,因为它有无限多的可能最终用途,这取决于用户和意图,并且可以随着时间的推移而改变。事实上,两家公司可能有不同的用例,因此需要集成不同的数据源和不同类型的分析,并会导致很大程度上不同的最终价值。数据的这一方面使得通过基于收入的方法进行货币化估值变得特别困难,因为不同买家之间可能的用途会发生巨大变化。

销售是最难将数据集货币化的方式,这主要是因为它需要一种独特的商业模式,而大多数公司并不具备这种模式。

大多数进入数据货币化业务的公司都确定了能够增强内部数据的合作伙伴。我建议公司从数据中发现趋势和见解,这些趋势和见解不容易被复制或从竞争对手那里获得。

商业模式

数据货币化可以通过不同的方式实现。你既可以卖给你整个数据集,也可以分析它并出售你的人工智能结果。我确定了 3 种商业模式:

另一件要记住的事情是,当你在市场上出售数据集时,你基本上是在授予买方以某种方式使用该数据集的许可,但你也可以保留你所出售的特定数据集的所有权,并可以出售任意数量的数据集许可。

如何使用 Python 发送带附件的电子邮件

原文:https://towardsdatascience.com/how-to-send-email-with-attachments-by-using-python-41a9d1a3860b?source=collection_archive---------11-----------------------

使用 Python 电子邮件库实现报告自动化的几个简单步骤。

Photo by Web Hosting on Unsplash

作为一名数据分析师,我经常会收到这样的请求:“你能每周给我发一份报告吗?”或者“你能每个月通过邮件把这些数据发给我吗?”。发送报告很容易,但如果你每周都要做同样的事情,那就太烦人了。这就是为什么您应该学习如何使用 python 来发送电子邮件/报告以及在您的服务器上安排脚本。

在本文中,我将向您展示如何从 Google BigQuery 中提取数据,并将其作为报告发送。如果你只想知道如何使用 Python 发送电子邮件,你可以跳到电子邮件部分。

导入库

像往常一样,我们必须在进入编码部分之前导入库。我们将使用 SMTP 协议客户端发送电子邮件。 ConfigParser 用于读取存储 SQL 查询的配置文件。我将在下一部分解释细节。

从 BigQuery 提取数据

首先,您必须创建一个配置文件来存储所有的 SQL 查询。将 python 脚本与 SQL 查询分开是一种很好的做法,尤其是当您的 SQL 查询很长(超过 20 行)时。这样,您的主脚本就不会被冗长的 SQL 查询弄得杂乱无章。

配置文件示例

【报告 1】是您的子配置。filenamedialectquery是子配置的属性。

您可以使用以下代码读取配置文件。

写一个函数来读取子配置的属性

这个自定义函数将读取您传入的子配置文件的属性,并输出一个 CSV 文件。

yourProjectID将是您的 BigQuery 项目 ID,而credential.json将是您的 BigQuery 凭证 JSON 文件。如果您希望使用 Web Auth 登录,您可以删除它。

现在,您只需要一个循环来提取您在配置文件中定义的所有文件。config.sections()将返回您的配置文件中的子配置文件列表。

通过电子邮件发送您的报告和附件

定义您的电子邮件内容

以上是你如何定义你的电子邮件属性,如发件人,收件人,抄送和主题。htmlEmail将是你的邮件正文。您可以使用纯文本或 html 作为您的电子邮件正文。我更喜欢使用 html,因为我可以做更多的格式化工作,比如粗体、斜体和改变字体的颜色。

同样的事情,我们将使用循环来附加所有的文件。

发送电子邮件

出于演示目的,密码被硬编码在脚本中。这不是一个好的做法。为了更安全,您应该将密码保存在其他文件中。

现在你已经学会了如何使用 Python 发送带有附件的电子邮件。如果我犯了任何错误或打字错误,请给我留言。

您可以在我的 Github 中查看完整的脚本。如果你觉得这篇文章对你有用,请鼓掌支持我。干杯!

如何在 Oracle Cloud 上用 Ubuntu 18 设置 GPU VM

原文:https://towardsdatascience.com/how-to-set-up-a-gpu-vm-with-ubuntu-18-on-oracle-cloud-a484967f1bdf?source=collection_archive---------26-----------------------

介绍

如果你想开发一个深度学习模型,并希望获得成功的可能性很大,你需要两样东西:

  • 大量的数据,用于模型的训练
  • GPU 形式的足够的计算能力

深度学习模型通常基于深度(多层)神经网络。通常用于模型训练的算法是基于某种形式的“反向传播算法,它需要许多“张量”运算。对于这种操作,GPU 比 CPU 更有效,因为它可以以一定程度的并行性执行,即使使用现代 CPU 也无法实现。举例来说,英伟达 P100 拥有 3584 个内核,能够处理 5.3 万亿次浮点运算。

因此,与使用 CPU 所需的时间相比,如果您采用现代 GPU,您将能够将训练模型所需的时间减少至少一个数量级。

但是 GPU 还是很贵。另外,在这个领域,发展势头强劲,你的 GPU 可能会很快老化。

因此,选择采用基于云的环境,你只需为使用付费,这是现在最好的选择。仅举一个例子,在 Oracle Cloud 上,您可以使用一个带有一个 NVidia P100 (16 GB)、12 个 OCPU 和 72 GB Ram (VM)的 VM。GPU2.1 形状)约 30 $/天。如果需要,您可以使用更多的 GPU 来获得图形。

话虽如此,为 TensorFlow 正确设置环境并不是一件最简单的事情,你有可能无法充分利用你的 GPU。我在网上做了一些研究,发现文档并不完美。为此,我决定写这篇关于如何为 TensorFlow 和 GPU 设置 Ubuntu 18 环境的笔记。

环境。

如前所述,我正专注于在 Oracle 云基础架构(OCI)中设置虚拟机,我希望使用以下组件:

  • Ubuntu 18.04
  • Anaconda Python 发行版
  • 张量流
  • Jupyter 笔记本

稍微复杂一点的是操作系统库、用于 GPU 的 Nvidia 驱动程序、CUDA 工具包版本和 TensorFlow 版本之间的正确对齐。如果所有这些都没有正确对齐,您可能会面临 TensorFlow 程序将正确运行的环境,但不使用 GPU,并且执行时间要长得多。不完全是你想要的。

我在这里记录了到目前为止我发现的最简单的一系列步骤,老实说,我是从个人角度开始写这篇笔记的。然后我决定,也许这是值得分享的。

虚拟机。

从 OCI 控制台,我为创建虚拟机选择的设置如下:

  • 外形:VM。GPU2.1 (1 个 GPU,12 个 OCPU)
  • 操作系统:Ubuntu 18.04
  • 公共 IP:是
  • 启动卷:100 GB 的磁盘空间

我还添加了一个公钥,以便能够使用 ssh 远程连接。

虚拟机的创建速度很快。很好。

虚拟机操作系统设置。

首先要做的是更新可用包的列表:

sudo apt update

那么,既然我们要使用 Jupyter 笔记本 ,我们就需要在板载防火墙中打开端口 8888。推荐的方法如下:

sudo iptables -I INPUT -p tcp -s 0.0.0.0/0 --dport 8888 -j ACCEPT
sudo service netfilter-persistent save

不要使用 ufw。您可能会取消将虚拟机连接到存储所需的一些设置。

在此之后,我们需要添加一个入站网络安全规则,以便能够从浏览器连接到端口 8888:

Log into OCI console.Under **Core Infrastructure** go to **Networking** and then **Virtual Cloud Networks**.Select the right cloud network.Under **Resources** click on **Security Lists** and then the security list that you’re interested in.Under **Resources**, click **Ingress Rules** and then **Add Ingress Rule**.Enter 0.0.0.0/0 for the Source CIDR, TCP for the IP Protocol, and 8888 for the destination port.At the bottom of the page, click **Add Ingress Rules**.

此时,我们需要安装正确的 Nvidia 驱动程序。这是一个关键点,我已经浪费了一些时间。对于 Ubuntu 18,我发现的最简单的方法如下:

sudo apt install ubuntu-drivers-commonsudo ubuntu-drivers autoinstall

重新启动后(强制),您可以使用以下命令检查驱动程序是否正确安装(输出被报告)。从命令中,您还可以获得驱动程序的版本。

**nvidia-smi**Mon Sep 30 13:34:03 2019+ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -+| NVIDIA-SMI 430.26 Driver Version: 430.26 CUDA Version: 10.2 || — — — — — — — — — — — — — — — -+ — — — — — — — — — — — + — — — — — — — — — — — +| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC || Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. ||===============================+======================+======================|| 0 Tesla P100-SXM2… Off | 00000000:00:04.0 Off | 0 || N/A 37C P0 24W / 300W | 0MiB / 16280MiB | 0% Default |+ — — — — — — — — — — — — — — — -+ — — — — — — — — — — — + — — — — — — — — — — — ++ — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -+| Processes: GPU Memory || GPU PID Type Process name Usage ||=============================================================================|| No running processes found |

“nvidia-smi”命令在未来也将有助于检查 GPU 在训练过程中的使用。

软件安装。

下一步是安装 Anaconda Python 发行版。

在撰写本文时,“七月版”是最新的版本,但是您应该查看 Anaconda 站点。

wget [https://repo.continuum.io/archive/Anaconda3-2019.07-Linux-x86_64.sh](https://repo.continuum.io/archive/Anaconda3-2019.07-Linux-x86_64.sh)bash Anaconda3–2019.07-Linux-x86_64.sh -becho -e ‘export PATH=”$HOME/anaconda3/bin:$PATH”’ >> $HOME/.bashrcsource ~/.bashrc

使用以下命令对 Anaconda 发行版进行最后一次更新是值得的:

conda update -n base -c defaults condaconda init bash
source ~/.bashrc

至此,我得到了 4.7 版本。最后两个命令允许使用“conda 激活”命令。

接下来,我们需要创建一个新的“conda”虚拟环境,我们称之为“gpu”

conda create --name gpu
conda activate gpu

之后,我们可以在创建的“GPU”env 中安装 Python:

conda install python

下一个重要步骤是 TensorFlow 的安装。这里要安装支持GPU的版本。重要的是使用 conda 而不是 pip 进行安装,因为这样可以确保正确安装和满足所有依赖关系。

conda install tensorflow-gpu

接下来,Jupyter 安装:

conda install nb_condajupyter notebook --generate-config

之后,您需要在 Jupyter 的配置中写入以下几行

In /home/ubuntu/.jupyter/jupyter_notebook_config.py file, add the following linesc = get_config()
c.NotebookApp.ip = '0.0.0.0'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8888

这样,您就可以从 VM 外部(任何 IP 地址)连接到 Jupyter。

然后,因为您只希望通过 SSL 进行连接,所以可以使用 OpenSSL 生成自签名证书:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout jupyter-key.key -out jupyter-cert.pem

完成所有这些步骤后,您可以使用以下命令启动 Jupyter

jupyter notebook — certfile=jupyter-cert.pem — keyfile=jupyter-key.key

(最终,您可以添加 nohup)。

浏览器会给你一个安全警告,但你知道你在做什么,可以马上继续。

测试你的 GPU。

现在,终于到了检查一切是否正常的时候了。在开始训练复杂的深度学习模型之前,我们希望确定 TensorFlow 将使用 GPU。因此,我们使用 TensorFlow 进行测试。

在笔记本电池类型中:

import tensorflow as tffrom time import strftime, localtime, timewith tf.Session() as sess:devices = sess.list_devices()devices

在输出中,您应该在可用设备列表中看到 GPU。

然后作为最后的检查(我在 StackOverflow 上找到的)

import tensorflow as tfif tf.test.gpu_device_name():print(‘Default GPU Device: {}’.format(tf.test.gpu_device_name()))else:print(“Please install GPU version of TF”)

您希望看到第一个“print”语句的输出。

作为最终检查:

  • 看看 Jupyter 生产的日志;
  • 运行你的模型,同时执行“nvidia-smi”命令;您应该会看到大于 0 的“易变 GPU 利用率”

结论。

如果你想在深度学习领域认真实验,你需要 GPU。有几种方法可以用 GPU 建立 Linux 环境:在这篇文章中,我记录了如何在 Oracle OCI 上用最新的 LTS Ubuntu 版本建立一个环境。

此外,我还记录了如何确保 TensorFlow 实际使用 GPU。

如何在 Amazon RDS 上建立 PostgreSQL 数据库

原文:https://towardsdatascience.com/how-to-set-up-a-postgresql-database-on-amazon-rds-64e8d144179e?source=collection_archive---------13-----------------------

LPhoto by Joshua Sortino on Unsplash

PostgreSQL 是一个开源的对象关系数据库系统,使用 SQL 语言进行交互和维护。它已经被证明是一个高度可扩展的数据库解决方案,因为它允许您管理万亿字节的数据,并且可以处理许多并发用户。PostgreSQL 也是符合 ACID 的,以确保出错时的有效性。

当您需要创建关系数据库时,您应该选择 PostgreSQL 数据库,其中数据被组织到一个或多个由列和行组成的表中,使用唯一的键来标识每一行。一个表中的行通常使用该唯一键链接到其他表中的行。

虽然有许多地方可以托管您的 PostgreSQL 数据库,但是本文特别关注在 亚马逊关系数据库服务 (亚马逊 RDS) 上托管您的数据库。Amazon RDS 允许在 AWS 云中设置关系数据库,非常容易使用。

如果您刚刚开始使用所有 AWS 服务,希望您会发现这很有帮助!在本文的大部分时间里,我将介绍 AWS 上的 PostgreSQL 设置,然后介绍如何执行一些其他有用的数据库操作。如果您已经建立了数据库,请随意跳过!⏭⏭

这篇文章涵盖了哪些内容:

  • 如何在 Amazon RDS 中创建 PostgreSQL 数据库
  • 如何从外部连接到 PostgreSQL 数据库
  • 如何使用 SQL 在数据库中创建表
  • 如何使用 SQL 将数据插入数据库的表中
  • 如何使用 SQL 删除数据库中的表

在 Amazon RDS 中创建 PostgreSQL 数据库

要在 AWS 中创建 Postgres 数据库,首先登录您的帐户并在 AWS 管理控制台中搜索RDS。点击左边工具条上的Databases,你将被带到一个如下所示的页面。

RDS Databases View

点击右上角的橙色Create database按钮,现在你可以开始为你的新数据库选择选项了。

选择一种数据库创建方法

选择Standard Create以便您可以定制数据库配置。

选择发动机选项

我们正在创建 Postgres 数据库,因此选择 PostgreSQL 并保留默认版本 11.5-R1。

为您的用例选择一个模板

因为我们正在测试,所以我选择了免费层!

自定义设置

您可以更改DB instance identifierMaster username或保留默认值。我把我的用户名改成了test-db和,并保留了默认用户名postgres。您也可以让 Amazon RDS 为您生成一个密码,或者您可以指定自己的密码。在这个例子中,我指定了我自己的。

数据库实例大小

DB instance 类决定 Amazon RDS DB 实例的计算和内存容量。您需要的 DB 实例类取决于您的处理能力和内存需求( Amazon 文档)

这是您希望选择满足内存需求的实例的地方。对于免费层,我们只有Burstable classes作为选项,我将这部分保留为默认的db.t2.micro

存储大小

您可以在这里指定数据库的存储要求。您还可以选择启用存储自动扩展,以便您的数据库是动态的,可以自动扩展🙂

同样,我只是保留了storage typeallocated storagemaximum storage threshold的默认值,并保留了enable storage autoscaling选中的✅

可用性&耐用性

该选项用于创建一个备用数据库,以防停机,这样您的数据库就可以一直正常运行。该选项在空闲层不可用。

连通性

您可以在这里指定以下连接配置:

  • VPC —为该数据库实例定义虚拟网络环境的 VPC
  • 子网组 —定义数据库实例可以使用哪些子网和 IP 范围的子网组
  • 公共可访问性 —数据库是否可公开访问
  • VPC 安全组 —允许 VPC 之外的流量进入的安全组
  • 可用性区域 —通过将故障与其他可用性区域隔离来提高高可用性
  • 数据库端口 —数据库实例将用于应用程序连接的 TCP/IP 端口

我保留了除Publicly accessible部分之外的所有默认值,我将它改为Yes,这样我的数据库就可以在 VPC 之外访问,就像从 Jupyter 笔记本上访问一样。

数据库认证

在此部分中,您可以从以下选项中选择如何验证您的数据库凭据:

  • 密码认证 —通过 DB 引擎的本机密码认证特性管理您的数据库用户凭证。
  • 密码和 IAM 数据库认证 —通过 DB 引擎的本机密码认证功能和 IAM 用户和角色管理您的数据库用户凭证。
  • 密码和 Kerberos 认证 — 通过 DB 引擎的原生密码认证特性和 AWS 目录服务创建的 AWS 托管 Microsoft AD 管理您的数据库用户凭证。这样,您可以集中存储和管理用户凭证,而不是为每个数据库实例单独存储和管理。

让我们和Password authentication一起去吧。

创建数据库

最后,单击底部的create database开始创建数据库,您应该会在页面上看到以下消息。这需要几分钟时间!

连接到 AWS RDS 中的 PostgreSQL 数据库

下载 Jupyter 笔记本跟随

我们将使用 psycopg2 库在 Jupyter 笔记本中本地连接到 postgres 数据库(您也可以从 IDE 或终端连接)。继续使用!pip install psycopg2-binary安装 psycopg2,然后可以运行下面的代码进行连接。

注意 :对于 *POSTGRES_DBNAME* ,当我放入真正的数据库名时,它实际上从来没有工作过,在这种情况下我将其命名为 test-db,我必须放入 *postgres* 来代替。如果它最终不能使用您给定的数据库名称,尝试默认的 *postgres* 它可能会工作。

import psycopg2 as ps# define credentials 
credentials = {'POSTGRES_ADDRESS' : '', # change to your endpoint'POSTGRES_PORT' : '', # change to your port'POSTGRES_USERNAME' : '', # change to your username'POSTGRES_PASSWORD' : '', # change to your password'POSTGRES_DBNAME' : ''} # change to your db name# create connection and cursor    
conn = ps.connect(host=credentials['POSTGRES_ADDRESS'],database=credentials['POSTGRES_DBNAME'],user=credentials['POSTGRES_USERNAME'],password=credentials['POSTGRES_PASSWORD'],port=credentials['POSTGRES_PORT'])cur = conn.cursor()

如果你没有得到一个错误,你已经成功地连接到你的 postgres 数据库!🎊

在 Postgres 数据库中创建表

既然您已经成功地创建了一个 postgres 数据库,让我们在其中创建一个表。

首先,验证数据库中有什么—应该什么都没有。您可以使用以下返回空列表的代码进行检查。

query = """SELECT * FROM pg_catalog.pg_tablesWHERE schemaname != 'pg_catalog'AND schemaname != 'information_schema';"""cur.execute(query)
cur.fetchall()

注意: 如果您跳过了本文的部分内容,请先确保您已经连接到了数据库(见上文)😀

您可以通过运行以下代码来创建您的第一个表:

cur.execute("""CREATE TABLE table_1(column_1 integer, column_2 float,column_3 varchar(50),column_4 boolean);""")# Commit table creation
conn.commit()

这将创建一个名为table_1的表,包含 4 列。我已经包含了一些常见的 SQL 数据类型,因此您可以将它们更改为您的表的数据类型。

如果我们运行上面的代码来检查数据库中的表,我们会得到下面的响应,可以看到 table_1 现在在数据库中:

[(‘public’, ‘table_1’, ‘postgres’, None, False, False, False, False)]

好处:如果您想要系统地创建一组给定了表名列表的表,您可以使用下面的代码:

table_list = [] # a list of string table namesfor table_name in table_list:cur.execute("""CREATE TABLE {table_name}(column_1 float,column_2 float,column_3 float,column_4 float);""".format(table_name=table_name))# Commit table creation
conn.commit()

将数据插入 PostgreSQL 数据库的表中

现在 postgres 数据库中有了一个表,可以开始输入数据了。

若要插入一行数据,请运行以下代码:

data = [1, 2.2, 'three', True]
insert_query = """INSERT INTO table_8(column_1, column_2, column_3, column_4)VALUES (%s, %s, %s, %s);"""# execute insert
cur.execute(insert_query, data)# commit data insert
conn.commit()

我将数据放入一个列表中,确保数据类型与为表中的列选择的数据类型相匹配。确保自定义正在创建的表,以匹配将要插入的数据类型。然后,我编写了将该列表插入到表中的查询,执行该查询,并将它提交到表中。如果不提交执行,您的数据将不会保存到表中。

通过从表中提取数据来验证数据是否已保存:

select 语句返回我们插入的数据,所以我们知道它是有效的!

要在表中插入多行数据,请运行以下代码:

data = [[5, 5.5, 'five', True], [5, 5.5, 'five', True], [5, 5.5, 'five', True]]
insert_query = """INSERT INTO table_1(column_1, column_2, column_3, column_4)VALUES (%s, %s, %s, %s);"""# execute multiple inserts
cur.executemany(insert_query, data)# commit data insert
conn.commit()

这里的区别在于,变量data是一个包含要插入的数据的列表列表。我们还使用cur.executemany而不是cur.execute来遍历我们的数据列表并插入所有的输入。

同样,您可以使用简单的 select 语句验证是否插入了三行新数据:

现在,您可以看到 select 语句返回了使用前面的 insert 语句添加的 3 个新行。

删除/删除 SQL 中的表

你最终会想要删除这个测试表,开始你真正的工作——或者你可能像我一样搞砸了一些事情🙃

使用 SQL 命令DROP TABLE删除 postgres 数据库中的一个表:

cur.execute("""DROP TABLE table_1""")
conn.commit()

确保您确实提交了,否则您的表不会被删除!使用我们之前用来检查的代码来验证您的数据库包含的表。

就是这样!现在,您可以在 AWS 上建立自己的 PostgreSQL 数据库,创建表,添加数据,并删除任何不需要的表。如果你按照教程学习并发现任何错误,请让我知道,这样我可以修复它!

您还可以使用更好的用户界面来管理 PostgreSQL。我推荐 pgAdmin,这里可以免费下载。

这篇文章最终将成为我和我的团队在从事一个名为 Cryptolytic 的项目时所学到的经验的系列文章的一部分(文章将很快写出来并链接到这里)。这是我们在进行项目时希望拥有的指南。

包含本文中使用的所有代码的笔记本可以在这里找到,这是我们的密码破解项目的回购文件中的内容——所以如果你很好奇,可以去看看!

在 twitter @elizabethets 上找到我或者在 LinkedIn 上联系我!

来源:

**** [## 什么是亚马逊关系数据库服务(Amazon RDS)?

Amazon 关系数据库服务(Amazon RDS)是一个 web 服务,它使设置、操作和扩展关系数据库变得更加容易

docs.aws.amazon.com](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Welcome.html) [## 关于

PostgreSQL 是一个强大的、开源的对象关系数据库系统,它使用并扩展了 SQL 语言和

www.postgresql.org](https://www.postgresql.org/about/) [## 密码破解-app/密码破解

你可以在 Cryptolytic 找到这个项目。Trello 板产品 Canvas Cryptolytic 是一个为初学者修修补补的平台…

github.com](https://github.com/Cryptolytic-app/cryptolytic) [## 关系数据库

关系数据库是基于数据关系模型的数字数据库,由 E. F. Codd 于 1970 年提出。一个…

en.wikipedia.org](https://en.wikipedia.org/wiki/Relational_database) [## 酸

在计算机科学中,ACID(原子性、一致性、隔离性、持久性)是数据库的一组属性…

en.wikipedia.org](https://en.wikipedia.org/wiki/ACID)****

如何建立假设

原文:https://towardsdatascience.com/how-to-set-up-hypotheses-c59d8f2d6b81?source=collection_archive---------8-----------------------

一些读者要求在我的文章中附上一个简单的基于事实的例子(没有不确定性或概率),以向您展示如何建立决策环境。你的愿望就是我的命令!**

让我们用两个不同的默认动作来演示两个场景,看看它是如何工作的。假设我刚刚接到朋友的电话:“我们今晚出去好吗?”**

第 0 步:接触你的感觉

场景 1 - 我生活在一个永久的状态 FOMO 。街道充满了冒险!

场景 2 - 这是漫长的一周。这张沙发有多舒服?太舒服了。

本例中的场景彼此无关。它们代表了两个平行的宇宙。我给你们看这两个只是为了教学的目的。实际上,你只生活在一个世界,所以你只看到一个场景。

第一步:写下默认的动作

场景一 —默认情况下,我们出去吧!说服我不要。

场景二:默认情况下,我会留在家里。说服我不要。

由决策者选择他们喜欢的默认操作。如果你得不到更多的信息,这个行动就是你承诺要做的任何事情。这些默认动作对不同版本的平行宇宙我来说似乎是合理的。没有一个是“正确”的,除非我诚实地去做。

第二步:写下可供选择的行动

情景 1 —替代行动是留在家中。

场景二 —备选行动是外出。

这与默认操作正好相反。

步骤 3:描述零假设(H0)

如果天气好的话,我很乐意默认(出去)。无效假设是没有雨。

场景 2 —如果没有有趣的现场音乐,我很乐意做我的默认(不出去)。无效假设是我今晚的音乐选择是可证明的蹩脚。

步骤 4:描述备选假设(H1)

场景 1 —我的 null 的反义词是什么?下雨了。呃。比错过更糟。那会说服我改变主意。

场景二 —我的 null 的反义词是什么?我喜欢的一个乐队在我附近有现场演出。那会说服我改变主意。

现在,让我们来看一些数据可能到达的三种不同方式…

分析证据然后决定!(无聊的数据)

场景一——你给我看数据:“科学家刚刚发现了一种新的海蛞蝓。”我该怎么办?我没学到任何改变主意的东西,我们出去吧!

场景二 —你给我看数据:“科学家刚刚发现了一种新的海蛞蝓。”我该怎么办?我没学到任何改变我主意的东西,我要留在家里。

请注意,sea slug 仿真陈述导致拒绝 null 失败,而不是接受 null。可能还会下雨,我只是从数据上不知道,所以我还是继续做我打算做的事情。

分析证据然后决定!(惊人的数据)

场景一 —你给我看数据:“下雨了。”我该怎么办?不是我默认的动作。我会待在家里。

场景二 —你给我看数据:斯潘塞·克鲁格 一小时后登台。”我该怎么办?不是我默认的动作。我随时都可以离开沙发去斯潘塞。

这些事实很容易解释——它们让我的无效假设看起来很可笑(事实上, p 值为 0 ),所以它们迫使我在每种情况下采取替代行动。如果我们得到了相同的数据,但是我们颠倒了它出现在哪个场景(世界)中,会怎么样?

分析证据然后决定!(无聊的数据)

场景一 —你给我看数据:斯潘塞·克鲁格 一小时后登台。”我该怎么办?我没学到任何改变主意的东西,我们出去吧!**

场景二**—你给我看数据:“下雨了。”怎么办?我没学到任何改变我主意的东西,我要留在家里。

如果你不小心,你可能会错误地认为证据与决策有关。事实上,这个证据不会比海蛞蝓仿真陈述更能改变我的想法…尽管我更想去看一场精彩的表演。不管音乐如何,我也会在场景 1 中做出同样的决定。当然,看一场精彩的演出会让我对出去感觉更好,但无论如何我都会这么做。

如果你已经理解了这一点,你已经准备好添加一些细微的差别——深入研究“ 一句话中的统计推断 ”以获得更深入的例子。

感谢阅读!人工智能课程怎么样?

如果你在这里玩得开心,并且你正在寻找一个为初学者和专家设计的有趣的应用人工智能课程,这里有一个我为你制作的娱乐课程:

Enjoy the entire course playlist here: bit.ly/machinefriend

喜欢作者?与凯西·科兹尔科夫联系

让我们做朋友吧!你可以在 Twitter 、 YouTube 、 Substack 和 LinkedIn 上找到我。有兴趣让我在你的活动上发言吗?使用表格取得联系。

如何为数据科学或其他任何事物建立一个令人敬畏的 Python 环境

原文:https://towardsdatascience.com/how-to-setup-an-awesome-python-environment-for-data-science-or-anything-else-35d358cc95d5?source=collection_archive---------6-----------------------

介绍

用 Python 编码很棒,而且随着每个新版本的发布,越来越棒!对我来说,这主要是由于大量免费可用的库、其可读性以及最近引入的类型注释。然而,尤其是我们作为数据科学家,往往会产生大而乱的 Jupyter 笔记本或 python 文件,难以理解。除此之外,当一个项目依赖于同一个库的不同版本时,我们经常会遇到版本冲突。修复这个问题需要太多时间,并且经常会导致其他项目出现问题。必须有一种方法来避免这种情况,并方便我们的生活。在本文中,我将介绍我使用的工具和我通常遵循的技术。希望这能帮助未来的我记住所有这些,更重要的是,也能帮助你学到一些有用的东西。事不宜迟,让我们把手弄脏吧。

Python 环境

翻译

让我们从使用 python 时最重要的事情开始:解释器。当然,你可以简单地下载并安装你最喜欢的 python 版本,然后把所有东西都放进去。但是,如果您的程序需要不同的 python 版本,或者程序依赖于同一第三方模块的不同版本,并且您希望在这些程序之间无缝切换,该怎么办呢?

Pyenv 会帮你做到的!

Pyenv 是一组三个工具,我在这里介绍其中的两个,它们是 pyenv (用于安装 python)和 pyenv-virtualenv (用于配置你的全局工具)。您可以通过以下方式安装它们

curl [https://pyenv.run](https://pyenv.run) | bash

之后,给你的加上以下几行。bashrc (同为。zshrc)在您的终端中使用 pyenv

export PATH="~/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

最后,重启你的终端。如果你是 mac 用户,当然可以用 brew 安装 pyenv。

现在,您可以使用 pyenv 安装几乎任何 python 解释器,包括 pypy 和 anaconda。注意,pyenv 在您的机器上本地构建 python。构建 python 需要几个库。在我的 Ubuntu 机器上,我必须安装以下几个软件,以免遇到问题

sudo apt-get install build-essential libsqlite3-dev sqlite3 bzip2 libbz2-dev zlib1g-dev libssl-dev openssl libgdbm-dev libgdbm-compat-dev liblzma-dev libreadline-dev libncursesw5-dev libffi-dev uuid-dev

现在,要安装 python 解释器,只需

pyenv install VERSION_YOU_WOULD_LIKE_TO_INSTALL

您可以通过 pyenv 列出所有可用的版本

pyenv install --list

具体来说,让我们安装 python 3.7.5,并将其作为默认的全局解释器

pyenv install 3.7.5
pyenv global 3.7.5

当您键入 Python-version 时,应该会返回 Python 3.7.5

依赖性管理

在 python 中管理项目依赖关系可能会变得混乱或手动。有很多工具可以帮你做到这一点。

我用的最多的是诗词。

除了许多其他的东西,诗歌可以帮助你轻松地

  • 管理项目的依赖关系,
  • 通过虚拟环境分离您的项目,
  • 轻松构建应用程序和库。

作者建议安装诗歌的方式是

curl -sSL [https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py](https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py) | python

另一种方式,我将向您展示的是使用 pip 和 pyenv-virtualenv。你可能会问:为什么不只是皮普?因为这将在你的全球环境中安装诗歌及其依赖项,而你可能不需要也不想要它们。所以,这里是必要的命令

**# Create a virtual environment called tools that is based on 3.7.5**
pyenv virtualenv 3.7.5 tools 
**# Install poetry into the tools virtual env**
pyenv activate tools
pip install poetry 
**# Check installed poetry version**
poetry --version
**# Leave the virtual env** 
pyenv deactivate 
**# This does not work yet** 
poetry --version
**# Add your tools virtual env to the globally available ones**
pyenv global 3.7.5 tools
**# Now this works and you can start using poetry**
poetry --version

在我们开始使用 poem 创建我们的第一个项目之前,我建议对它进行配置,这样它可以在项目目录内的. venv 文件夹中创建您项目的虚拟环境。当您使用像 VS Code 或 PyCharm 这样的 ide 时,这非常方便,因为它们会立即识别出这一点并选择正确的解释器

# That seems to be peotry prior to 1.0.0
poetry config settings.virtualenvs.in-project true# That is poetry since 1.0.0
poetry config virtualenvs.in-project true

请注意,您只需设置此配置一次,因为它是全局设置并保持不变的。

最后,我们已经准备好了使用诗歌创建我们的第一个项目,太棒了!我把这个项目叫做 dsexample ,一个我知道的愚蠢的名字,但是我不想浪费更多的时间去寻找一个更好的名字。为了向您展示如何使用诗歌,我添加了特定版本的 pandas 和带有所有额外要求的 fastapi

**# Initialze a new project**
poetry new dsexample 
cd dsexample
**# Add modules and create virtual environment.**
poetry add pandas=0.25 fastapi --extras all
**# As an example of how you could add a git module**
poetry add tf2-utils --git [git@github.com](mailto:git@github.com):Shawe82/tf2-utils.git

如果你想看一个使用我在这里给你的所有东西的真实项目,请去我的 Github Repo 。

一致的格式和可读性

现在,我们已经创建了我们的项目,我们将开始在它上面添加越来越多的代码。理想情况下,您的代码库格式一致,以确保可读性和可理解性。这可能会成为一个非常乏味的过程,尤其是如果你不是唯一一个在代码库上工作的人。

黑色 前来救援!

Black 是 python 的一个工具,可以让你专注于必要的内容。它通过自动化将您从手工代码格式化中解放出来。因为它太棒了,让我们把它添加到我们的 dsexample 项目中,并格式化所有文件

**# We add black as a development dependency with --dev as we don't
# need it when it comes to production**
poetry add --dev black=19.3b0
**# Assume we are inside the current toplevel dsexample folder**
poetry run black .

很好,现在所有的文件看起来都很好。

类型正确性

从 Python 3.5 开始,如果我说错了请纠正我,类型注释是标准库的一部分。通过类型注释,您的代码变得更容易理解、维护,并且不容易出错。为什么不容易出错?因为您可以静态地检查变量和函数的类型是否与预期的匹配。当然,这必须是自动化的

又来了 mypy !

Mypy 是 python 代码的静态类型检查器,可以在错误出现之前发现它们。使用诗歌向您的项目添加 mypy 和类型检查就像添加 black 一样简单

**# We add mypy as a development dependency with --dev as we don't
# need it when it comes to production**
poetry add --dev mypy
**# Assume we are inside the current toplevel dsexample folder**
poetry run mypy .

运行 mypy 可能会产生很多错误。当然,你可以把它配置成只警告你感兴趣的东西。你可以在你的项目中添加一个 mypy.ini 文件,并让你和未来的我参考文档以获得更多细节。

自动化自动化

有了 black 和 mypy,我们可以避免手动格式化代码或遇到可避免的错误。但是,我们仍然需要手动执行这些工具。那不也应该是自动化的吗?是啊!

预提交就是你所需要的一切。

Pre-commit 是一个在您将代码提交到存储库之前执行检查的工具(我想当然地认为您的代码在 git 版本控制之下)。当这些检查失败时,您的提交将被拒绝。这样,您的存储库将永远看不到 mall 格式的代码,或者没有类型检查的代码,或者其他任何依赖于您将要包含的检查的代码。所以让我们安装预提交。

您可以使用 poem 将它直接安装到您的项目中,或者安装到您的本地机器上。我更喜欢后者,因为预提交只在本地使用,而不在 CI/CD 服务器上使用。相反,black 和 mypy 应该运行在 CI/CD 服务器上,因此,将它们添加到项目的 dev 依赖项中是有意义的。下面是我建议如何利用现有的工具虚拟环境来安装它

**# Install pre-commit** **into the tools virtual env**
pyenv activate tools
pip install pre-commit 
**# Leave the virtual env** 
pyenv deactivate
**# As we have already added the tool venv, it will work directly**
pre-commit --version

要使用它,你首先需要添加一个名为的配置文件。将 pre-commit-config.yaml 提交到项目的顶层文件夹。在这个文件中,您配置了所有应该运行的钩子。使用 mypy 和 black,这个文件看起来像

repos:
-   repo: [https://github.com/ambv/black](https://github.com/ambv/black)rev: 19.3b0hooks:- id: blacklanguage_version: python3.7
-   repo: [https://github.com/pre-commit/mirrors-mypy](https://github.com/pre-commit/mirrors-mypy)rev: v0.740hooks:- id: mypy

最后,您必须告诉预提交通过执行来设置挂钩

**# I assume your are in the top level folder**
pre-commit install

现在,钩子将在每次提交时运行。黑色挂钩不仅会检查格式问题,还会相应地格式化文件。每当您添加一个新的钩子时,建议您在所有文件上手动运行预提交,因为它只涉及自上次提交以来已经更改的文件

pre-commit run --all-files

就这样,我们实现了自动化!

包裹

有很多工具可以帮助你专注于重要的事情。在这里,我只给你介绍了几个,当然,还有其他更多。希望你已经学到了新的东西,可以专注于内容。感谢您的关注,如果有任何问题、意见或建议,请随时联系我。

如何使用良好的软件工程实践来设置 Python 和 Spark 开发环境

原文:https://towardsdatascience.com/how-to-setup-the-pyspark-environment-for-development-with-good-software-engineering-practices-5fb457433a86?source=collection_archive---------7-----------------------

在本文中,我们将讨论如何设置我们的开发环境以创建高质量的 python 代码,以及如何自动化一些繁琐的任务以加快部署。

我们将回顾以下步骤:

  • 使用 pipenv 在隔离的虚拟环境中设置我们的依赖关系
  • 如何为多项任务设置项目结构
  • 如何运行 pyspark 作业
  • 如何使用 Makefile 来自动化开发步骤
  • 如何使用 flake8 测试我们代码的质量
  • 如何使用 pytest-spark 为 PySpark 应用运行单元测试
  • 运行测试覆盖,看看我们是否已经使用 pytest-cov 创建了足够的单元测试

步骤 1:设置虚拟环境

虚拟环境有助于我们将特定应用程序的依赖关系与系统的整体依赖关系隔离开来。这很好,因为我们不会陷入现有库的依赖性问题,并且在单独的系统上安装或卸载它们更容易,比如 docker 容器或服务器。对于这个任务,我们将使用 pipenv。

例如,要在 mac os 系统上安装它,请运行:

brew install pipenv

为了声明应用程序的依赖项(库),我们需要在项目的路径路径中创建一个 Pipfile :

[[source]]
url = '[https://pypi.python.org/simple'](https://pypi.python.org/simple')
verify_ssl = true
name = 'pypi'[requires]
python_version = "3.6"[packages]
flake8 = "*"
pytest-spark = ">=0.4.4"
pyspark = ">=2.4.0"
pytest-cov = "*"

这里有三个组成部分。在 [[source]] 标签中,我们声明了下载所有包的 url ,在【requires】中,我们定义了 python 版本,最后在【packages】中定义了我们需要的依赖项。我们可以将一个依赖项绑定到某个版本,或者使用**" ***符号获取最新的版本。

要创建虚拟环境并激活它,我们需要在终端中运行两个命令:

pipenv --three install
pipenv shell

一旦这样做了一次,您应该看到您在一个新的 venv 中,项目的名称出现在命令行的终端中(默认情况下,env 使用项目的名称):

(pyspark-project-template) host:project$ 

现在,您可以使用两个命令移入和移出。

停用环境并移回标准环境:

deactivate

再次激活虚拟环境(您需要在项目的根目录下):

source `pipenv --venv`/bin/activate

步骤 2:项目结构

项目可以有以下结构:

pyspark-project-templatesrc/jobs/   pi/__init__.pyresources/args.jsonword_count/__init__.pyresources/args.jsonword_count.csvmain.pytest/jobs/pi/test_pi.pyword_count/test_word_count.py

init。为了使事情更简单,py 文件被排除在外,但是您可以在 github 上找到教程末尾的完整项目的链接。

我们基本上有源代码和测试。每个作业都放在一个文件夹中,每个作业都有一个资源文件夹,我们可以在其中添加该作业所需的额外文件和配置。

在本教程中,我使用了两个经典的例子——pi,生成圆周率数字直到小数位数,以及字数统计,计算 csv 文件中的字数。

步骤 3:使用 spark-submit 运行作业

让我们先看看 main.py 文件是什么样子的:

当我们运行我们的作业时,我们需要两个命令行参数: —作业,是我们想要运行的作业的名称(在 out case pi 或 word_count 中)和 — res-path ,是作业的相对路径。我们需要第二个参数,因为 spark 需要知道资源的完整路径。在生产环境中,当我们在集群上部署代码时,我们会将资源转移到 HDFS 或 S3,我们会使用那条路径。

在进一步解释代码之前,我们需要提到,我们必须压缩作业文件夹,并将其传递给 spark-submit 语句假设我们在项目的根中:

cd src/ 
zip -r ../jobs.zip jobs/

这将使代码在我们的应用程序中作为一个模块可用。基本上在第 16 行的 main.py 中,我们正在编程导入 job 模块。

我们的两个作业, piword_count,都有一个 run 函数,所以我们只需要运行这个函数,来启动作业(main.py 中的 line 17)。我们也在那里传递作业的配置。

让我们看一下我们的 word_count 工作来进一步理解这个例子:

这个代码在 init 中定义。py 文件在 word_count 文件夹中。我们可以看到,我们使用两个配置参数来读取 csv 文件:相对路径和 csv 文件在 resources 文件夹中的位置。剩下的代码只是计算字数,所以我们在这里不再赘述。值得一提的是,每个作业在 resources 文件夹中都有一个 args.json 文件。这里我们实际上定义了传递给作业的配置。这是字数作业的配置文件:

{"words_file_path": "/word_count/resources/word_count.csv"
}

现在我们已经有了运行我们的 spark-submit 命令的所有细节:

spark-submit --py-files jobs.zip src/main.py --job word_count --res-path /your/path/pyspark-project-template/src/jobs

要运行另一个作业, pi,,我们只需更改 —作业标志的参数。

步骤 4:编写单元测试,并在覆盖范围内运行它们

为了编写 pyspark 应用程序的测试,我们使用了 pytest-spark ,一个非常容易使用的模块。

word_count 作业单元测试:

我们需要从 src 模块中导入我们想要测试的函数。这里更有趣的部分是我们如何进行 test_word_count_run。我们可以看到没有初始化 spark 会话,我们只是在测试中将它作为参数接收。这要感谢 pytest-spark 模块,所以我们可以专注于编写测试,而不是编写样板代码。

接下来让我们讨论一下代码覆盖率。我们如何知道我们是否写了足够多的单元测试?很简单,我们运行一个测试覆盖工具,它会告诉我们哪些代码还没有被测试。对于 python,我们可以使用 pytest-cov 模块。要使用代码覆盖运行所有测试,我们必须运行:

pytest --cov=src test/jobs/

where — cov 标志告诉 pytest 在哪里检查覆盖率。

测试覆盖率结果:

---------- coverage: platform darwin, python 3.7.2-final-0 -----------
Name                              Stmts   Miss  Cover
-----------------------------------------------------
src/__init__.py                       0      0   100%
src/jobs/__init__.py                  0      0   100%
src/jobs/pi/__init__.py              11      0   100%
src/jobs/word_count/__init__.py       9      0   100%
-----------------------------------------------------
TOTAL                                20      0   100%

我们的测试覆盖率是 100%,但是等一下,少了一个文件!为什么 main.py 没有列在那里?

如果我们认为我们有不需要测试的 python 代码,我们可以将其从报告中排除。为此,我们需要创建一个。coveragerc 文件放在我们项目的根目录下。对于这个例子,它看起来像这样:

[run]
omit = src/main.py

步骤 5:运行静态代码分析

太好了,我们有一些代码,我们可以运行它,我们有覆盖率良好的单元测试。我们做得对吗?还没有!我们还需要确保按照 python 的最佳实践编写易读的代码。为此,我们必须用名为 flake8 的 python 模块来检查我们的代码。

要运行它:

flake8 ./src

它将分析 src 文件夹。如果我们有干净的代码,我们应该不会得到警告。但是没有,我们有几个问题:

flake8 ./src
./src/jobs/pi/__init__.py:13:1: E302 expected 2 blank lines, found 1
./src/jobs/pi/__init__.py:15:73: E231 missing whitespace after ','
./src/jobs/pi/__init__.py:15:80: E501 line too long (113 > 79 characters)

让我们看看代码:

我们可以看到在第 13 行有一个 E302 警告。这意味着我们需要在这两个方法之间多加一行。然后在 15 线上安装 E231E501这一行的第一个警告,告诉我们在**range(1, number_of_steps +1),****config[** 之间需要一个额外的空格,第二个警告通知我们这一行太长了,很难读懂(我们甚至不能完整的看到大意!).

在我们解决了所有的警告之后,代码看起来更容易阅读了:

步骤 6:用一个 Makefile 把它们放在一起

因为我们已经在终端中运行了许多命令,所以在最后一步中,我们将研究如何简化和自动化这项任务。

我们可以在项目的根目录下创建一个 Makefile ,如下图所示:

.DEFAULT_GOAL := runinit:pipenv --three installpipenv shellanalyze:flake8 ./srcrun_tests:pytest --cov=src test/jobs/run:find . -name '__pycache__' | xargs rm -rfrm -f jobs.zip cd src/ && zip -r ../jobs.zip jobs/ spark-submit --py-files jobs.zip src/main.py --job $(JOB_NAME) --res-path $(CONF_PATH)

如果我们想要运行覆盖率测试,我们可以简单地输入:

make run_tests

如果我们想要运行 pi 作业:

make run JOB_NAME=pi CONF_PATH=/your/path/pyspark-project-template/src/jobs

那都是乡亲们!我希望你觉得这是有用的。

一如既往,代码存储在 github 上。

如何缩短数据与价值的距离?

原文:https://towardsdatascience.com/how-to-shorten-the-distance-between-data-and-value-a48e2f1ef086?source=collection_archive---------31-----------------------

上次我写了一篇关于数据重力的文章,分享了关于如何提高数据质量和价值的想法。如前所述,今天本帖将给你关于缩短数据和价值之间距离的提示。换句话说,建立数据链接。在这方面,IT 部门扮演着最关键的角色,它是公司数据链的保障。

开始之前,让我解释一下什么是数据链路。

公司里的管理环节就是给压力的过程。当公司出现问题时,老板通常会给中层管理人员施加压力,不管是从业务表现还是运营角度来看。然后中层管理者向运营人员询问业务数据。为此,运营团队向管理团队提交原始数据。

数据链路的方向与管理链路的方向相反。为了支持管理链接,IT 部门需要以数据链接的形式及时提供数据。

但是 IT 部门如何建立数据链接呢?

以下是对支持数据分析和 BI 项目的团队的弱点的研究。

“2018 China Enterprise Data Research Report”, from FanRuan Data Institute

从图中我们可以发现,问题最初源于人、方法和工具。

因此,IT 部门应该通过改善这三个方面来建立数据和价值之间的桥梁。

同样,你可能会问怎么做?大多数公司都有自己的 IT 培训系统。他们中的一些人可能会向 IT 咨询部门寻求解决方案或购买 BI 工具。

在这里,我将结合泛软提供的解决方案,向大家展示如何建立数据与价值之间的联系。

先从‘人’的角度说起吧。

一个好的团队应该具备以下三种能力。首先是认知,涵盖理解数据分析、构建知识框架、数据共识、培训体系的能力。

第二是数据能力。换句话说,团队可以实现数据项目,包括组织索引、统计分析、可视化应用和数据管理。

最后是应用能力。它需要团队进行业务分析,支持软件,激发专业流程,开发数据价值。

在这方面,我建议 IT 部门建立一个培训系统,并鼓励团队成员加入在线社区进行学习、交流或互助。

然后,我们将重点放在“实施”上。

为了支持其他部门,IT 部门需要两支部队。一个是负责构建企业报表的主要力量。另一个是侦察力量。他们熟悉不同部门的业务,通过探索业务数据为业务注入活力。基于这些现实需求,前团队需要一个报表平台,比如fine report来处理复杂的报表。后者应该使用 数据分析工具 对公司进行分析、预测和创新。

以上是关于“工具”的一个要素——工具。“实施”的另一个要素是解决方案。要构建全面的解决方案,IT 部门不仅要考虑公司的情况,还要考虑行业解决方案。

在过去的几年里,泛软为 233 个行业的公司提供服务。在这个过程中,凡软发现,即使产品很优秀,当推向不同行业时,这些行业的各种需求会降低项目实施的效率。

而且其实每个板块都有一定的共性。只要把这些共性总结成行业解决方案,重用它,不断改进它,产品在行业中的价值就能得到极大的发挥。这就是为什么 泛软 除了提供产品之外,还提供全面的行业解决方案。

有了这些,最后就是“方法”的问题了。

“方法”的要点是交流思想。我非常推荐 IT 人员参加各种活动,例如新加坡的大数据世界欧洲的 AI &大数据博览会、伦敦的大数据 LDN、美国的 Tableau 大会、中国的智能数据大会。你必须了解行业趋势,与世界接轨。向别人学习永远是最快的方法。

总之,缩短数据和价值之间距离的主体是 IT 部门,我们应该从人、工具和方法开始建立数据和价值之间的联系。

您可能也会对…感兴趣

2019 年 6 大数据分析工具

2019 年你不能错过的 9 款数据可视化工具

初学者财务报表分析指南

制作销售仪表盘的分步指南

如何用神经网络求解常微分方程

原文:https://towardsdatascience.com/how-to-solve-an-ode-with-a-neural-network-917d11918932?source=collection_archive---------9-----------------------

如今,自动微分使得从机器学习的角度处理微积分问题成为可能。也许你在 NIPS 2018 上听到过关于神经常微分方程论文的一些议论,这篇论文是由作者之一大卫·杜文瑙德提交并签名的。同时,亲笔签名已经被 JAX 取代,这就是我们将在这里使用的。

主要问题如下:我们想找一个由微分方程定义的未知函数 y=f(x) ,比如 y'=-2xy,加上一些初始条件,比如 y(0)=1 。例子来自 Kreyszig 的 高等工程数学 的前几页。这个特定初始值问题的解析解是 y=exp(-x),我们将使用它来验证神经网络提供的结果。

一般来说,对于常微分方程可能没有封闭形式的解,但是可以用神经网络来近似未知函数 y=f(x) 。为了简单起见,我们将使用一个具有带 10 个节点的单个隐藏层的神经网络来解决问题y’=-2xyy(0)=1

这是我们神经网络的示意图:

总的来说,网络有 31 个可训练参数:隐藏层的权重和偏差,加上输出层的权重和偏差。

让我们按如下方式实现网络:

我们使用类似 JAX NumPy 的 API,这样,稍后,我们可以通过自动微分计算f的导数。注意,f有两个参数:一个网络参数数组(params)和一个输入值(x)。在机器学习中,我们通常根据模型的参数来区分模型,这里我们也将根据x来区分f,以便求解 ODE。

网络参数可以随机初始化,例如使用正态分布:

这里我们使用 JAX 提供的伪随机数发生器 (PRNG)。通过用某个种子创建 PRNG 键,我们确保我们的结果是可重复的。

f相对于x的导数可以通过调用grad来获得:

其中1表示我们想要f相对于其第二自变量x(从零开始的索引)的梯度。在 JAX 中,grad返回一个函数,该函数计算f的梯度,并具有与原始f相同的参数。

现在,我们会想要求解某个域中的 ODE,例如在 -2 ≤ x ≤ 2 中。因此,我们在该范围内创建一个输入值数组:

其中 401 点是任意选择在区间 [-2,2] 内具有 0.01 的分辨率。

然而,f接受单个值x作为输入。我们可以以数组的形式传递给它,但是为了便于区分,JAX 需要一个标量函数,所以我们必须传递一个单一的值作为输入,以便得到一个单一的值作为输出。为了有效地计算输入值数组的f及其导数dfdx,我们使用vmap对这些函数进行矢量化:

其中(None, 0)指定每个函数将映射到第二个参数(x)的0-轴上,而第一个参数(params)应保持不变(使用None,它将在映射中传播)。

我们现在可以定义我们的损失函数(是的,任何机器学习项目中出现的损失函数,其最小化将产生我们想要的解决方案):

注意微分方程 y'=-2xy 和初始条件 y(0)=1 是如何分别在eqic中被捕获的。为了使训练过程中的残差 y'+2xyy(0)-1 最小化,它们被表示为 y'+2xy=0y(0)-1=0 。我们在这个函数上使用 JIT(实时编译)来加速它在加速器硬件上的执行,比如 GPU 或 TPU,如果可用的话。

如同任何机器学习项目一样,我们现在根据可训练参数来区分损失函数:

其中0意味着我们想要损失函数相对于它的第一个自变量(params)的梯度。同样,我们使用 JIT 来加速这个新函数的执行。

该开始训练了!为了加快速度,我们将使用带有内斯特罗夫动量的梯度下降。回想一下内斯特罗夫加速梯度 (NAG)的公式:

因此,我们实施如下培训流程:

让我们运行它!

最后,让我们绘制结果并与解析解进行比较:

这就对了,神经网络近似看起来和精确的解析解几乎没有区别。

最后一个问题:在近似的域 [-2,2] 之外会发生什么?好吧,我将把它作为一个练习留给读者……
(提示:重新定义inputs,并再次绘制结果。)

如何加快你的 AB 测试

原文:https://towardsdatascience.com/how-to-speed-up-your-ab-test-10c1f1702b94?source=collection_archive---------20-----------------------

Spot the difference

第 1 部分:测量两次,切割一次

本帖最初发表于The Craft,Faire 的技术博客。这是我们关于使用 A/B 测试加速决策的系列文章中的第一篇。

像许多超增长的创业公司一样,Faire 使用实验来快速迭代我们的产品,并做出更好的决策。然而,与服务于数亿甚至数十亿潜在用户消费市场的许多同行不同,我们的市场是为小型企业构建的,在美国大约有 3000 万小型企业[0]。再加上我们才刚刚成立三年,这意味着我们实验的样本量往往小于其他科技公司数据科学团队进行实验的规模。举个例子,我们的平台目前为 100,000 家零售商和 10,000 家制造商提供服务。

当一个团队测试相对较大的效应尺寸时,较小的样本可能不是问题。但是在我们的案例中,许多简单的产品已经实现了,我们必须运行大量的实验来找到真正的大提升(这是我们计划很快写更多的主题。)由于这些限制,我们经常被产品经理问到,为什么他们的实验要花这么长时间才能达到显著效果,或者他们能做些什么来加速实验。为了响应这些要求,我们构建了第一个版本的工具来加速我们的实验结果,并为设计实验的数据科学家、工程师和产品经理制定了指南,以确保我们能够更快地做出决定,并对我们的结论有更高的信心。

在这一系列的文章中,我们提供了当前加速 AB 测试所使用的各种技术的概述,有些是简单的,有些是技术性更强的。随附的 Python 笔记本提供了示例和工作代码,以具体展示这些技术的影响,并为您提供一个改进自己的实验程序的起点。

试验设计

提前花时间设计能尽快产生最有用结果的实验是一种有效的方法,可以确保团队不会在回答错误问题的测试上浪费时间,也不会花太多时间来回答正确的问题。此外,以系统化的方式记录实验让公司更难忘记或记错之前测试的结果[1]。这对于非直观结果的实验和那些不能推广到整个用户群体的实验来说尤其重要。有了这个历史数据的存储库,团队可以围绕什么样的产品处理起作用和不起作用,在用户群的什么部分,他们移动哪些指标,以及移动多少,开发更好的先验信念。

更好的指标

在 Faire 设计实验时,我们首先要做的决定之一就是主要的度量标准是什么。我们通常必须做出许多权衡,以找到一种既能捕捉到我们试图通过治疗影响的行为,又能快速收敛以给出具有统计学意义的结果的指标。最重要的两个维度是度量与治疗的接近度(作为效果大小的代表)和度量的预期方差(T3)。

Consider proximity and variance when choosing metrics

接近度

因为我们的零售商比制造商多一个数量级,所以我们的大多数实验都是在市场的需求方进行的。就零售商而言,PMs 大多数时候希望衡量的指标与商品总值(GMV)相关,因为商品总值的增加反映了零售商从产品中获得了更多的经济价值,这也是我们的关键业务指标之一。这在实践中可能具有挑战性,因为 GMV 位于我们测试的所有项目的下游。例如,我们对注册流程所做的更改通过许多中间步骤从实际下单的零售商处删除。因此,我们看到的注册数量的任何提升往往会因零售商在客户旅程中下单的时间点而显著减少。

我们可以用一个简单的例子来强调这一点,在这个例子中,我们通过注册、添加到购物车和下订单来吸引访问者,然后让他们通过转换漏斗。在本例中,我们观察到从访问到注册的转化率大幅提升,并假设添加到购物车和订购的转化率没有差异。

Lifts can be harder to measure downstream from the treatment

为了简单起见,我们对治疗组和对照组在漏斗中每个步骤的转化率不同的假设进行卡方检验。我们看到了注册和添加到购物车转换的显著结果,但订单转换没有。这是因为当我们沿着漏斗向下移动时,绝对升力下降,而当值接近零时,转换的方差增加。

**print(proportion.proportions_chisquare(summary_treatment_1['signed_up'], summary_treatment_1['count'])[1])
print(proportion.proportions_chisquare(summary_treatment_1['added_to_cart'], summary_treatment_1['count'])[1])
print(proportion.proportions_chisquare(summary_treatment_1['ordered'], summary_treatment_1['count'])[1])4.826037697355727e-06
0.0027419906333688462
0.11399561233236452**

这个问题的一般解决方案是选择一个与我们在产品中所做的改变最接近的主要度量。在这种情况下,显而易见的选择是从访问转换为注册。然而,我们不能确定由我们的治疗导致的任何额外注册实际上最终参与了我们最终想要推动的下游行为,例如下订单。我们缓解这一问题的两种方法是选择适当的二级指标(在这种情况下,添加到购物车和订单转换将是很好的选择),以及利用我们以前的实验和观察研究的资料库,围绕我们的一级指标和它的下游指标之间的关系强度开发先验信念。简而言之,如果我们有理由相信注册量的增加转化为订单量的增加,那么我们不一定需要等待订单转换量的增加达到显著性(但不要在测试不足的情况下得出次要指标没有变化的结论[2])。)最后,在我们提升注册转化率但不提升下游指标的情况下,未来的注册实验仍将受益于样本量的增加,从而使我们能够随着时间的推移获得更有意义的结果。

差异

选择指标时要考虑的第二个因素是它们相对于预期效果大小的预期方差。例如,比例指标(分子是分母的子集)如注册转化率或访问品牌的零售商百分比被限制在 0 和 1 之间,产生的估计值比无界指标的估计值误差更小。

选择比例指标,而不是像 GMV/零售商这样的无限制指标,是我们缩短实验达到显著结果所需时间的常用方法。但是在一组可用的数学上无界的度量中,一些比其他的在现实中“更无界”。就 Faire 上的零售商而言,他们可以访问网站上的制造商页面的次数实际上不受限制,而他们向我们下订单的能力受到他们可以通过商店销售的库存数量的限制。这意味着每个零售商的订单分布通常比每个零售商的品牌访问量分布具有更低的方差。

Orders often increase logarithmically with visits

为了说明这一点,我们构建了一个假设的实验,在这个实验中,预期的订单数量与品牌访问量成对数关系。这种类型的关系并不罕见,因为它反映了这样一个事实,即数字行为实际上是不受约束的,而现实世界中的财务预算肯定是不受约束的。我们进一步假设就诊和订单在治疗中均提高了 5%。同样,运行 t-tests 比较访问和订单的两个样本显示,我们会发现后者的显著结果,因为与前者相比,它的均值方差更低。

**print(stats.ttest_ind(experiment_2['visits'][experiment_2['treatment'] == 1], experiment_2['visits'][experiment_2['treatment'] == 0]))
print(stats.ttest_ind(experiment_2['orders'][experiment_2['treatment'] == 1], experiment_2['orders'][experiment_2['treatment'] == 0]))Ttest_indResult(statistic=0.7573654245170063, pvalue=0.44884881305779467)
Ttest_indResult(statistic=2.5239860524427873, pvalue=0.011618610895742018)**

加速

使用比例度量的最后一点:小心加速。如果你衡量采取了他们最终很有可能采取的行动的用户比例,不管他们接受了什么样的治疗,随着你继续进行你的实验,你的比例指标显示没有提升的可能性会增加。虽然你可能提高了采取行动的次数或减少了采取行动的时间,但你不会在实验中提高每个用户的唯一转化率。

在下面的例子中,我们将控制和处理平均分开,具有相同的和确定的访问转换。然而,我们将这些访问的首次到达时间建模为具有对数正态分布的单个 lambdas 的指数。此外,我们假设治疗成员的λ增加 10%。

A simple hierarchical model captures acceleration without lift

我们看到治疗组的访问转化率在收敛到我们事先知道的相同的长期转化率之前处于领先地位。

We would have naively called this test at one week

在 Faire,当我们在现有零售商样本中跟踪访问品牌页面的独特转换时,就会发生这种情况。因为大多数活跃的零售商会在几天或几周内访问一个品牌,我们有时会看到这个指标的提升最初达到峰值,然后随着实验的成熟收敛到零。如果没有被发现,这些新奇和首要效应可能是有害的。这并不是说促进良好行为是不值得的。但是重要的是要理解你是在提升指标还是简单地加速它们。

更少的指标

最后,当谈到实验度量选择时,通常越少越好。随着你在实验中测试的假设数量的增加,你也增加了第一类错误的可能性。根据你对犯这些错误的容忍度,你会想要控制家庭错误率 (FWER)或不太严格的错误发现率 (FDR)。FWER 技术,如霍尔姆-邦费罗尼方法,控制至少一个 I 型错误的概率,而 FDR 程序,如常用的本杰明-霍赫伯格程序,对错误拒绝的无效假设的预期比例提供较弱的保证。下面我们演示了在一个有十个指标的实验中,如何使用 FDR 控制将重要测试的数量从六个减少到四个。无论您采用哪种方法或具体使用哪种方法,通过额外的指标进行的比较越多,您就需要越多的数据来获得有意义的结果。

FDR control renders fewer metrics significant

同样的原理也适用于你实验中的变异数。包含更多变量的测试测试更多的假设,在其他条件相同的情况下,需要更多的数据来达到显著性。基于成本、复杂性甚至是对什么可行什么不可行的强烈先验信念等因素排除额外的治疗方案,不仅可以设计出更强大的测试,还可以缩小产品、工程和设计团队的范围。通过迫使您的团队选择一个单一的主要指标、更少的变量和尽可能少的次要指标来做出决策,您可以显著减少做出决策和交付产品的时间。

机器学习

在本系列的下一篇文章中,我们将讨论如何使用时间盒、离群点去除和分层来减少度量方差。然后,我们将讨论一种称为 CUPED 的分层一般化,我们使用简单的线性模型使用这种技术取得的成功,以及如何使用非线性机器学习方法将其一般化。后面的文章将涵盖功耗分析、顺序测试和减少实验持续时间的动态流量分配策略。

致谢

Daniele Perito 感谢您的投入和指导。

[0] 2018 小企业简介

[1] 机构记忆

[2] 十二个肮脏的游戏:在线控制实验中十二个常见的度量解释陷阱

[3] 随机在线控制实验中的新颖性/首要效应检测

如何在数据科学工作机会中发现危险信号

原文:https://towardsdatascience.com/how-to-spot-red-flags-in-a-data-science-job-opportunity-22191e71f21?source=collection_archive---------9-----------------------

数据科学职业建议

以下是我在决定接受工作之前评估工作的几种方法

This job looks delicious.

不久前,我收到了一个人的问题,他读了我之前关于找数据科学工作的一篇帖子。他提到了我对工作与生活平衡的重视,并问道:

“我绝对同意,但你如何评估这一点?你会在面试中问类似“你周末多久工作一次?”我总是害怕被认为缺乏热情,我想,我只是试图在 Glassdoor 或类似的网站上搜寻信息。即使你真的问了,我也不知道答案会有多可靠。无论如何,我很想听听你自己在这方面对一家公司的评估方法。"

这让我更广泛地思考当我还是一名求职者时,我想从一份工作中得到的所有东西,在我实际接受这份工作之前,我尝试过(但往往失败)的所有方法都找到了这些东西。我认为每一份工作的接受都是一场赌博,就像每一份工作邀请都是一场赌博一样,但我确实认为有一些方法可以让求职者最大限度地减少意想不到的负面影响——不管这份工作与我想象的有多差,我至少可以避免很多远远超出我预期的工作。这是事实,即使不像我希望的那样确定。

所以这篇文章是关于我在接受一份工作后发现的主要问题,以及我如何在被这份工作束缚之前发现这些问题的一些想法。

发现工作生活平衡问题

让我们从引发这一思路的问题开始。工作与生活的平衡很难评估,所以我通常不会评估它,直到我合理地确定我和我未来的雇主都觉得这份工作很适合彼此。如果雇主要解雇我还有其他原因(而且有很多,即使对最有经验的申请人来说也是如此),那么谈论其他任何事情都没有意义。等到面试快结束的时候,我就能确保和招聘经理保持尽可能好的关系,而不用真的被录用。如果谈话仍然让我觉得很有威胁性,那就告诉我这份工作可能不太适合我。

我通常这样开始对话:“我想谈谈工作与生活的平衡。我习惯于投入任何时间和精力来完成工作,但我也知道保护自己免于精疲力竭对我来说有多重要。你能告诉我一些关于这方面的期望吗?我多久需要在晚上或周末工作一次?如果我有家庭问题,在某一天在家工作会更好,我有这样做的自由吗?”

我发现这些问题的答案没有我在回答时观察到的语气和肢体语言重要。我经历了明显的防御性:经理生气地说,当然,这种迁就有时不得不发生,期望它不发生是不现实的,但他们试图把它保持在最低限度,因为他们真的需要人们投入任何需要的工作。我曾经历过以高人一等的态度拒绝回答:经理靠在椅子上,说了一些毫无意义的话,比如“你知道,我们在这里努力工作,也努力玩耍”,或者明确表示,他们正在利用这一时刻教育我,做成人工作意味着什么。我也经历过一般的无能:经理明确表示他们没有认真考虑过这个问题,也不能告诉我这种事情发生的频率。

防御性意味着他们知道工作与生活的平衡是他们公司的一个问题,但觉得没有权力去做任何事情。居高临下意味着他们不尊重员工的时间和健康,只是试图从员工身上榨取尽可能多的利益,而不考虑长期可持续性。无能要么是假装的,在这种情况下,这意味着情况很糟糕,但他们不愿意诚实地告诉我——换句话说,他们撒谎——要么是真实的,这意味着他们与他们的劳动力脱节,他们真的不知道。

发现对数据科学不切实际的期望

大家都说要数据科学。很少有人愿意投入维护全面数据科学能力所需的工作。有几种方法可以发现这一点。根据我的经验,以瀑布式规划方法为代表的围墙花园式工程组织是一个非常强烈的迹象,表明一家公司没有准备好或不愿意支持数据科学家。同样,在我看来,专注于开发报告或制作仪表板是工作描述的主要部分,这表明他们并不真正需要数据科学家。他们需要一名分析师——也许是一名具有统计专业知识的分析师,但毕竟是一名分析师。但这些都是症状,不是疾病。

在我看来,真正的问题是一家公司是否重视数据科学工作的生产化。分析报告是用来扔掉的——不管报告是交给工程师还是高管。任何仅用于通知某人的输出都不会持久。扔掉我工作的工作不是令人满意的工作——这表明公司并不真正知道如何处理我的工作。

根据我的经验,当被问及生产化时,我可以通过他们的舒适程度来判断一个公司有多重视生产化。就工作与生活的平衡而言,人们的反应可能从防御到屈尊俯就到毫无头绪。我经常看到未来的雇主试图通过谈论他们如何管理项目来回避这个问题。这是一个危险信号。

项目经理是一个行政职位。每当一个团队在做任何事情,从构建软件到计划一个事件,一堆后勤问题(截止日期,利益相关者,劳动分工,等等。)需要协调。团队越大,项目越复杂,让某人关注所有这些移动的部分就越有帮助。项目管理不是产品管理。项目管理找出整个计划的哪一部分需要立即编写代码,决定当新功能暴露现有功能中的缺陷时该做什么,并保持对“足够好”定义的控制(这是所有数据科学项目唯一真正的验收标准),以及其他日常问题。产品管理关注团队下一步有能力做什么(相对于现在),涉众要求什么,需要什么会议来充实它,以及将实现工作与更大的组织联系起来的其他方法。

如果一个公司只能以项目来谈数据科学工作,我知道我不想为他们工作。如果他们可以从耐用产品的角度谈论数据科学,以及他们如何决定什么应该放在产品中,什么不应该放在产品中,那么我知道我可能想为他们工作。

发现一个懦弱的经理

我发现利兹·瑞安关于懦弱的经理的概念很有用。以我的经验来看,很少能找到一个真正刻薄或虐待的经理,尽管我知道这种类型的经理肯定比我们任何人想要的都多。相对而言,更常见的情况是,经理们对自己的职位或能力如此不确定,以至于他们试图让周围的每个人(尤其是那些向他们报告的人)看起来都不称职,同时强加一些武断的规则,旨在让他们看起来“强大”和“果断”。

我发现懦弱的经理会系统地向下属展示,经理的时间比员工想要的任何东西都重要。他们取消了我的约会。他们不停地谈论他们做过的所有重要的事情,以及他们交谈过的所有重要的人,这使得他们无法真正关注他们要求我做的任务。他们不能谈论任何不是他们提出的想法。如果我在寻找这些东西,它们往往会在面试过程中出现。

虽然一个明显不关心我时间的经理是应该避免的,但我也不想要一个痛苦地迁就我的经理:从不故意与我意见相左,一有异议就让步,似乎急于向我保证我想要什么就有什么。以我的经验来看,这要么意味着他们自己被一个懦弱的经理所控制,以至于失去了坚持自己意愿的能力,要么意味着他们告诉我他们认为我想听的任何事情。不管怎样,这种类型的经理不会管理,他们只是做出反应。数据科学家通常是个人贡献者,这意味着对业务需求做出反应通常是数据科学家的工作。当我不得不不断对别人的反应做出反应时,我已经精疲力尽了。

发现缺少优先化流程

当一个公司权力分离时,数据科学(我相信,还有一般的代码开发)会很好地工作。权力的分离意味着所有权的分离——对流程的一部分拥有权力的人不会对另一部分拥有权力。我倾向于将数据科学工作分为三个部分:优先级、产品和人员。

在敏捷框架中,优先级通常由产品经理(或者产品经理所在的部门——在许多组织中被混淆地称为“产品管理”或者仅仅是“产品”)拥有。这个所有者可以定义和区分组织要求的优先级,并负责理解和记录系统,以及管理涉众。该所有者对计划和承诺的内容有最终的决定权——如果他们确定某个功能足够重要,足以消耗所有可用的资源,他们可以暂停其他优先级,即使其他人不同意他们的观点。

产品通常由产品所有者拥有,或者有时是实现团队本身(或者是产品所有者和实现者所在的部门——在许多组织中只称为“工程部门”)。这个所有者组织实现者的日常工作,安排工作,跟踪交付承诺,对 bug 报告进行优先级排序,等等。该所有者对产品的完整性具有最终的权威——如果他们确定某个变更将威胁到已经构建的某个产品的稳定性或未来可用性,他们可以阻止该变更的发生,直到进行了适当的规划、流程开发和变更管理。

人员归人事经理所有(或人事经理所在的部门,最终是人力资源部,但在实践中通常看到个人人事经理嵌入所有部门)。该负责人负责职业规划和人事评估,管理人际冲突,包括当人们没有达到预期时,并处理团队运营中所有其他人的方面。该所有者拥有最终的雇佣/解雇权力,尽管他们经常从其他所有者那里获得关于这些主题的信息。

个人工程师和分析师也拥有所有权——对他们实现的细节——但是他们的所有权并没有与其他权力分开。分析师可能不认为分析解决方案是合理的,但是产品经理仍然可以决定该解决方案足够好,可以发布,产品所有者仍然可以决定该解决方案是可维护的,人事经理仍然可以决定开发和维护该解决方案对于员工满足期望和保住工作是必要的。好的组织不会一贯地践踏他们的实现者所关心的事情,但是这样做的权力总是存在的,并且有时是必要的和有益的,因为实现者对于什么是足够好以满足客户需求的标准通常过高。

除非一家公司是一家非常小的初创公司,买不起更好的东西,否则不将这三种权力分开将阻止大多数数据科学家从事任何有意义或持久的工作。当优先级和产品归同一个人所有时,不切实际的特性会在不切实际的时间框架内被批准。当优先权或产品由拥有人的同一个人拥有时,那么错误的优先权或保护产品的失败就会得到加强,因为任何可能反对它们的人都害怕被解雇。

根据我的经验,判断一家公司是否有优先化流程的最佳方式是询问一些最近建造的东西,并询问是如何决定它们应该被建造的。如果这类问题的答案是“[在此处插入高管或经理姓名]表示我们需要它”,那就有问题了。一个企业有一个体面的优先化过程的最好迹象是,人们能够谈论症状、诊断和处方。值得为之工作的公司可以谈论公司感受到的痛苦,解释他们如何确定痛苦的原因,并讲述他们如何建立一些东西来解决原因。其他公司会回避这个问题。

我真正寻找的

在每一种情况下,我真正寻找的是能给我具体细节而不脸红的人。让我们回到工作与生活平衡的例子:

在我目前的工作中,我已经做了两年了,我有两次整个周末都在工作(包括几乎不睡觉)。我这样做是因为我痴迷于一个特定的分析问题,而不是因为任何人要求我这样做,甚至暗示他们希望我这样做。只要不在办公室不妨碍其他人的工作,我可以随时在家工作。如果你和我一起面试,我会看着你的眼睛告诉你所有这些。事实上,很明显,我会有点兴奋地告诉你,因为这是这份工作真正高度重视的一个方面。

与我之前的工作形成对比:我一年有四次通宵/周末工作,一个月有几次工作到很晚,大多数时候我这样做是因为我被告知我必须这样做(或者被告知,带着一种愤世嫉俗的窃笑,有时“你只需要投入完成工作所需的时间”,从而让人们知道期望是什么,而不是实际上告诉我夜以继日地工作)。管理层不太赞同在家工作,尽管我们部门在这个问题上比公司其他部门稍微宽容一些,因为我认为这是一项重要的自由,而且我是那个部门的主管。期限很短是很常见的,设定这些期限的人对个人问题没有多少耐心。如果你和我一起面试这家公司的一个职位,我会给人一种有点防御性的印象。我尽量不做出居高临下的回应,但因为我的经理们经常采取居高临下的态度,其中一些可能会被忽略。你会发现回答这个问题让我感到不舒服。

如果某件事对我来说很重要,和我谈论这件事不会让未来的雇主感到不舒服。如果这确实让他们不舒服,如果我接受这份工作,我可能会对现状感到失望。这适用于我对工作的所有潜在担忧。这不是一个万无一失的方法,但这是我能想到的最好的方法。

如何启动一个有助于你脱颖而出的数据科学项目

原文:https://towardsdatascience.com/how-to-start-a-data-science-project-that-will-help-you-stand-out-915c90d326b3?source=collection_archive---------18-----------------------

寻找有影响力的项目打入该领域的实用方法

Photo by Randy Fath on Unsplash

在未来的某一天,我看到自己在杂乱的数据中寻找答案,发现对一家公司重要的战略洞察力。对于许多像我一样有抱负的数据分析师来说,通往那个目的地的道路正在建设中。知道你正与许多背景和项目都很强的候选人竞争,你会感到沮丧。

你已经完成了一系列关于数据科学的在线课程,或者可能是一个训练营,现在,你渴望应用你新学到的技能。但是你如何着手做这件事呢?什么样的项目可以帮助你获得潜在雇主的注意,你如何寻找他们?

如果你有像我一样的非传统背景,并希望成为一名数据分析师,那么寻找一个项目可能会很有挑战性。具有挑战性,但并非不可能。

在完成 Udacity 的数据分析师 Nanodegree 之后,我开始在网上寻找项目。谷歌搜索显示了大量我可以使用的在线数据集。Kaggle 是我遇到的最受欢迎的来源之一,在那里我找到了我感兴趣的数据集,我喜欢将我的结果与其他用户进行比较的可能性。但是我觉得很失落,不知道从何说起。

我恍然大悟。分析它们是一个很好的练习方法,但是如果我在做一些有可见的影响的事情呢?那不是更有意义和满足感吗?对我来说,是的。

想法不错,但是我怎么才能找到这样的东西呢?

Photo by Toa Heftiba on Unsplash

数据随处可见。你可能在一个充斥着杂乱无章数据的部门工作,或者你可能与产生或消耗数据的团队一起工作。

如果这听起来对你来说很熟悉,那就有机会了。我想分享一下我作为一个初学者,从寻找项目机会到启动项目的经历。

寻找一个项目

一个项目解决一个挑战。寻找你的团队面临的挑战。因为你已经熟悉了流程,所以更容易观察你的团队内部,并且发现改进机会也相对容易。

  • 在您的团队中寻找挑战或流程改进的机会
  • 有数据可以分析和可视化吗?

从小做起。不一定要很大的东西,因为它会让人感到势不可挡。请记住,当我们从小的成功中获得经验时,我们可以继续更大的项目。我们将一步一步地到达那里。

你想解决什么问题?

Photo by Matt Noble on Unsplash

在一个挑战或问题被确定后,是时候把它塑造成一个明确的目标了。这是每个项目的核心,不仅仅是数据科学。而且它很容易失去它所需要的注意力,在这个过程中,你可能会偏离主题,进入其他不相关的问题。

我使用了一个核心工具,这个工具被用来驱动六个名为“DMAIC”的适马项目。你可以在这里 了解更多 。该工具通过提供更好的结构,使复杂的改进项目更容易进行,并有助于将注意力集中在手头的问题上。

“DMAIC”中的“D”代表“定义”。这就是我们定义问题、改进机会或项目的目标的地方。

你如何将挑战表述为一个明确的目标,你能用一个度量标准来定义它吗?

示例: 将 xyz 流程的轧制成品率从 55%(当前状态)提高到 85%(未来状态或目标)。

尽可能具体。这就像你的北极星,你会知道你需要去哪里。

影响

Photo by Jordan McDonald on Unsplash

我再怎么强调这一点的重要性也不为过。你将投入大量时间进行头脑风暴和开发你的项目。要充分利用它,你必须有一个可衡量的影响或结果。招聘经理会有兴趣知道你的计划对公司有什么影响。

韵律学

指标可以帮助您最好地展示影响。仔细选择你的度量标准。它们必须与项目目标相一致,并且应该激励行动。

度量是衡量进展的简单方法。它使团队意识到业务流程的当前状态,并使他们专注于改进和维护它。

影响可以包含在目标中,也可以是结果。例如,减少 40%的处理时间(目标)导致成本降低(影响),比如每年 1 万美元。

谁将使用您的报告或仪表板?

Photo by Miguel Henriques on Unsplash

你的问题陈述现在已经成型了。是时候确定你的利益相关者了。谁是你的观众?

当我在构建仪表板时,我喜欢把我的项目想象成一部电影。目标受众是谁?哪些部门或团队会与我的工作产生互动?

为了进行这一步,我与目标受众和利益相关者交谈,了解他们面临的挑战。你的目标可能与他们的一个或多个挑战相关联。

如果你的项目旨在通过展示洞察力来帮助团队做出更好的决策,那么站在他们的立场上可以帮助你获得更好的视角。

这与下一个要点联系在一起:沟通。

通信

Photo by Christin Hume on Unsplash

通信是数据科学项目的关键方面之一。根据我目前的经验,沟通是两个阶段的关键。

  1. 与团队成员和利益相关者交流,了解需求和要求
  2. 通过可视化表达结果和见解

当我为一个产品测试团队开发仪表板时,我意识到了它的重要性,这对我来说是一个未知的领域。

该项目的目标是“将调试数据的准确性从 50%提高到 95%”。我没有测试工程领域的专业知识,但是我能够通过问很多问题和与团队会面来回避这个挑战。

  • 您的团队目前面临的最紧迫的挑战是什么?
  • 哪些因素/指标可以定义和衡量您的挑战?
  • 产品测试数据输入的要点是什么?
  • 数据是如何输入的?它是自动化的还是有人类参与的?
  • 测试团队测量的重要度量是什么?

通过提问,即使你在那个领域之外工作,你也可以对问题有一个全面的了解。

选择您的工具

Photo by Todd Quackenbush on Unsplash

在您开始提取和分析数据之前,了解您在工具和软件方面能走多远是很重要的。您可能需要花一些时间来学习新的分析和可视化包。有时候,我意识到我的大块代码可以使用 Python 库用两行代码轻松完成。但是我想经验会告诉你的。

你也可能有费用限制,比如购买付费软件的许可证。所以你必须寻找免费的替代品。我遵循下面给出的一些简单步骤。

数据提取和分析

  • 你的数据来源是什么(Excel,SQL 数据库,文本文件等)?
  • 这些文件有多大?
  • 数据存储在哪里(云、本地计算机等)?
  • 您的数据源始终可用吗?你如何连接到它?
  • 数据刷新的频率是多少?
  • 是整齐的数据吗?你将如何清洗它?
  • 你会用什么来分析和探索数据(Python,Excel,R 等)?

可视化和可用性

  • 这是临时分析还是将与团队共享的仪表板?
  • 您需要多久创建一次此报告?
  • 用户会与之交互吗(比如改变过滤器、日期等)?
  • 您将如何共享此报告或仪表板?
  • 你能自动共享和刷新数据吗?

完成这个练习将帮助您评估项目的复杂性,并帮助您决定将使用的工具。

最初,我用一些可视化工具来来回回地寻找哪一个最合适。一开始你可能不会选择“完美”的工具。这是正常的,这是学习过程的一部分。

启动您的工作

Photo by SpaceX on Unsplash

在开始工作之前,确保满足所有要求,并验证数据的准确性。在数据清理、探索和可视化之间来回是很正常的。

当我的项目准备启动时,我与团队召开了一次会议,培训他们如何使用它。

我还参加了团队会议,见证了成员根据开发的仪表板提供的可视化和洞察力做出决策。让管理层参与这些会议也是一个好主意。这会让你的工作更加引人注目,他们可能会给你带来更好的工作机会。

永远做一个初学者

专家和初学者的区别在于,专家已经多次经历了初学者的循环,并努力克服它。

当我开始用 Python 编程时,我是熊猫的初学者,但随着时间的推移,我变得更好了。最近,我在做一个需要我学习 SQLAlchemy 的项目。所以我又回到了初学者的状态。渐渐地,我越来越擅长了。这个循环将会贯穿你的学习过程,我们必须拥抱它。

抬头!

一路上可能会有很多非技术性的挑战,这可能会让你感到气馁。

我曾经遇到过这样一种情况,我在一个过程中发现了一个缺陷,而一个团队成员对此很不高兴,因为他对此负有责任。我和他安排了一次一对一的会面,他逐渐敞开了心扉。在他的帮助下,我们绘制了流程图,确定了瓶颈和衡量流程绩效的指标。

练习情感共鸣和积极倾听团队成员的问题帮助我应对这一挑战。保持开放的心态有助于我更好地理解并找到根本原因。

最后的想法

从小处着手,然后扩展到更大的计划,这是一个很好的尝试方法。这将激励你接受更大的项目,你会在这个过程中学到很多。一个强烈的想法浮现在我脑海,我想与大家分享。

“如果你忘记了你必须攀登的山峰,只关注下一步,伟大的事情就会发生。”

—德里克·菲茨杰拉德,铁人三项赛选手,心脏移植幸存者

你有什么想法?我很想知道。

如何开始在介质上写作

原文:https://towardsdatascience.com/how-to-start-a-writing-carrier-on-medium-5df87c62b3e9?source=collection_archive---------22-----------------------

数据科学作家第一个月的实践建议分析

Photo by Free-Photos on Pixabay

一个月前,我开始在媒体上写故事。作为一名人工智能爱好者,我将我的博客帖子发给了一家名为走向数据科学 (TDS)的出版物,该出版物目前拥有大约 28 万名粉丝。这个故事是我经过一个月 6 个故事的分析思考的总结。

上个月,我在 TDS 上发表了 6 篇自然语言处理领域的故事。我的故事涉及伯特和机器翻译。总的来说,我有超过 12k 的浏览量,5k 的阅读量和 100 个粉丝。希望这个故事可以成为考虑在介质上开始书写载体的人的指南。

对写作的热爱

首先,我想谈谈我的动机。我开始写这些故事,作为我经历的总结。我在研究新的科学领域,我想保留我对它的第一印象。像日记一样。然而,我想分享它,这样每个新进入这个领域的人都可以从中受益。

第一个月结束时,我注意到我可以在日常工作中使用我的故事作为帮助。为了有一个好的媒介故事,我已经把实验打磨成一个可读的、可理解的工具,如果我需要的话,我可以回头去找它。

我还有第二个动机:作为一个非英语母语的人,我发现写作是保持语言技能的一个很好的练习。作为一个早期职业科学爱好者,我认为写媒介故事是写科学论文的一个很好的练习,也是在该领域获得更多认可的一个好方法。

我对中型合作伙伴计划也很好奇。有可能以此为生吗?当它的第一个结果出来时,我意识到我的动机开始从“写一个好故事”转变为“写一个高薪的故事”。最明显的影响是,我每天都感受到写作的压力,而不是分享知识的快乐。目前,如果我觉得我的主要动机是错了,我会有意识地停止写作。

My stories on Medium. The first one is published in Quick Code, the others in Towards Data Science

一个中等故事的阶段

Medium 提供读者分布的统计数据。你可以了解你的故事是如何传播给谁的。基于此,我把故事的生命分成三个主要阶段。

  1. 早期观众
  2. 社交媒体分享
  3. 媒体和出版物发行(TDS)
  4. Android 应用和谷歌 Chrome 建议
  5. 来世(幸好谷歌搜索结果)

Reader distribution of one of my stories published in TDS.

早期读者是你发送给你的故事的朋友,你的追随者和出版物的编辑。他们是潜在的第一批粉丝,他们可以纠正你故事中的明显错误。

社交媒体分享来自你的 Twitter /脸书/ LinkedIn /等。以及早期观众的分享。对于我所有的故事,一些我不认识的随机 twitter 用户分享了它,导致了 10-20 次浏览。(非常感谢!)

媒体和出版物发行:前两个阶段对于第三个阶段非常重要。媒体策展人和出版物的编辑都可以选择在网站的某个地方分享你的文章。我不知道这些决定背后的实际过程,但我认为故事的早期观点和掌声是重要的。当然最重要的还是故事的质量!

我的故事的原始数据是,我在 TDS 上发表的所有故事都是由媒体策展人选择发行的。根据其他的故事(像这个),这是一个伟大的成就。关于 TDS 分发,对我来说重要的一步是当 TDS 在他们的 Twitter 上分享故事时。我一半的故事都发生了这种情况,我不知道这是什么模式。

安卓应用&谷歌 Chrome 建议:这些都是大数字!为了在 Android 应用程序或 Chrome 建议中赢得一个好位置,故事必须在前面的阶段表现良好。中等适合 Chrome 建议,所以在 Chrome 建议中有很多中等的文章。然而,要获得这些位置,你必须写一些热门的东西,一些人们现在想读的东西。

来世:媒介故事就是新闻。它们在开始时有一个 3 天的高峰,但过后就消失了。对于一个在第一天获得 100 次浏览的故事,在第一周之后,它每天有 10 次浏览。一个 500 次浏览的高峰故事有 20-40 次浏览,一个第一天有 2000 次浏览的故事在第一周之后有 300 次浏览。相关性显而易见。然而,令我惊讶的是,在第一周之后,这些数字相当稳定。我预计未来几个月会缓慢下降,但这只是一个假设,因为我在 TDS 上的第一篇文章才发表了一个月。到目前为止,我的故事里还看不到这种趋势。

增加来世浏览量的一个方法是给这个故事加上一个标题,这个标题很适合用谷歌搜索。比如我有一个故事叫简单 BERT 使用 TensorFlow 2.0 它在标题中有两个热门话题的名字( BERTTensorFlow )和一个不错的 Google 搜索关键词(简单)。如果我考虑得更周到,我可能也会在标题中添加关键字 example

Views of a story: 3-day peak and afterlife

我的操作列表

如果你对这个话题感兴趣,你可以在 Medium 上找到很多关于如何成为一名优秀作家的文章。在这里,我将添加我的列表建议。

我的成功作家清单:

0.英语

  1. 质量
  2. 一致性
  3. 出版物
  4. 最畅销的关键词

以英语为母语的人可能没有意识到他们的障碍,但是如果你把英语作为第二语言,你可能会在生活中有这样的时刻,你认为“用英语会容易得多”。是的,用英语写作更容易。即使它不是我的母语。假设我用匈牙利语写了一个故事,它有 100 次浏览,以同样的速度,一个英语写的故事将有 20,000 次浏览!(根据本文对英语用户的估计。

关于质量我不想写太多。是的,质量很重要。很多。阅读高质量的论文,认真写作,使用工具,倾听读者和编辑的意见。你会进步的。

我预测一致性的重要性会变小,但在第一个月之后,我不得不纠正自己。我已经提到过,我的老故事的每日视图是相对恒定的。这些故事每天的收入都差不多。如果你写了 4 篇文章,每天赚 0.5 美元,你每天赚 2 美元。如果你写了 40 篇文章,就是 20 美元。

此外,写一个新的故事也可以促进旧的故事,因为如果你写了一篇好文章,你的读者可能会想你是否也有其他伟大的文章。

My views in the first month.

如果你打算在媒体上写作,你可能知道出版物的存在。找到高质量的出版物,它们会帮助你写出更好的文章,提高你的浏览率。因为对数据科学感兴趣,我的故事被媒体策展人选中发行,并被 Chrome Suggestions 推荐。

我的最后一个要点是我称之为畅销关键词的东西。总有热门话题,读者搜索的词。你的兴趣并不总是与大多数读者的兴趣相同。但有时确实如此。如果你找到合适的术语,并把它放在你文章的标题中,它可以提升你的观点。但是不要写你不真正感兴趣的东西。即使你以写作为生,也要找到非常适合你的话题!

基于介质读取的支付

11 月初,Medium 换成了基于阅读的支付方式,他们升级了故事的统计数据。下面是基于我的故事的表现对这个新特性的分析。

Earnings of my stories since Medium shows daily earnings

首先,我们对故事有了一个新的总体衡量标准,叫做平均阅读时间。对我来说总是在 30 到 50 秒之间。我认为这包括那些点击了我的文章,但在意识到这个故事在付费墙之下后关闭了它的读者。那些刚刚浏览过的人。根据文章的长度,Medium 估计阅读时间为 3-8 分钟。不是每个人都深思熟虑地阅读它。

对于一个故事的每日浏览量,我们得到了两个新的每日统计数据:每日收入和每日会员阅读时间。一个故事的收入是基于会员的阅读时间。对于每个媒体会员,他/她的会员资格$5 被分配给他所阅读的文章的作者,该作者根据他/她在文章上花费的阅读时间进行加权。

下图是从我的三个故事中提取的数据。其中一个共有 600 次浏览,另一个 1800 次,最后一个 7000 次浏览。所有数据都来自新时代的第一天(10 月 28 日-11 月 15 日)。由此,我们可以计算出,我的读者每阅读一分钟,我的平均收入是 0.04 美元。

The correlation between reading time and earnings based on 3 stories

摘要

这个故事是我作为一个媒介作家的经验总结。我在出版物《走向数据科学》中撰写数据科学文章(更具体地说是自然语言处理相关的故事)。我在 10 月 14 日发表了我的第一篇文章,这篇文章分析了第一个月的情况。我写了 6 篇文章,总共有 12k 的浏览量,5k 的阅读量和 100 个粉丝。到目前为止,我在中等合作伙伴计划中赚了 91.47 美元。

如何从数据科学入手

原文:https://towardsdatascience.com/how-to-start-with-data-science-93d3ca32d7e5?source=collection_archive---------27-----------------------

数据科学从零到英雄

数据科学是最热门的领域之一。它既实用又有创造性,你会学到很多东西,并解决现实世界中的问题。如果你想知道如何开始,这里有一个简短的指南。

How to make a career change and become a data scientist

数据科学课程

已经建立了许多课程和组织来帮助人们开始学习。谷歌数据科学训练营或面向所有人的数据科学,你会发现专门帮助人们开始学习 Python 数据科学的课程。线下课程可能会很贵。但是如果你已经准备好开始学习,我建议你每周花几个小时参加在线课程,你肯定会感觉更舒服。如果你决定参加数据科学训练营,我建议你先做一个可以展示的真实项目。这将让您对 data scientist 的工作有一个很好的了解。

在我的另一篇文章中,我写了关于建立数据科学项目组合的文章。

数据科学会议

另一件事是数据科学会议。你绝对应该在你所在的地区寻找一些,并至少参加一次,看看数据科学家在谈论什么,现在什么是趋势。这是跟上该领域最新工具和技术并向业内最优秀的数据科学家学习的绝佳方式。如果你想了解该领域数据科学家的最新动态,请关注数据科学子网站和最佳数据科学家的博客。确保跟上数据科学界在大数据领域开发的所有最新工具和技术。这将确保您能够获得最新的工具和技术,从而利用您的经验和技能。

数据科学家的收入

这是学习数据科学的大好时机。你可以作为一名数据科学家创业,你可以开始建立自己的事业,你会过得很好。

我已经在这个帖子里谈到了如何进入数据科学,是时候学习如何做好它了。

这需要一些时间,但你会成功的。

当我第一次开始时,我开始阅读所有关于这个主题的书,但我很快意识到其中许多都过时了。

我现在更喜欢接触真实的数据。我现在开始处理来自真实世界的真实数据。

如果你想开始数据科学家的职业生涯,是时候开始收集数据了。

现在有比以往更多的信息和工具可以帮助你收集数据——首先是 Kaggle 的公共数据库,GitHub 的开源代码,Reddit 的许多链接和文章,你可以抓取和重复使用。

获得数据科学领域的实习机会

当然你不一定要创业才能成为数据科学家。另一个自然的方法是找实习。

有很多方法可以获得实习机会,但第一种方法是直接联系招聘公司。

第二种方法是寻找那些想雇佣实习生的公司,并与他们接触,看看你是否能得到实习机会。如果你能展示你的作品,电话推销真的有用(再次 GitHub!).

你越主动越好。开始在 LinkedIn 上写你的数据科学项目,在 Medium 上发布帖子以获得更多的关注。最理想的情况是当招聘人员找上你,而你是他们要选择的人。唯一的方法是将工作投入到你的开源数据科学项目中,并推广你正在做的事情。

如果这不适合你——因为你只是对如此公开感到不方便,这很好——那就开始在许多求职网站和团体上寻找实习机会。这是一个员工市场,如果你能展示出你的参与度和热情,你应该能够得到潜在雇主的初次电话或会面。

努力工作,祝你好运!

Data Science Job

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

如果你想了解更多,请阅读我关于成为数据科学家的其他文章:

  • 成为数据科学家的 5 种方法
  • 给数据科学家的最佳建议
  • 数据科学家常犯的 3 个错误
  • 成为数据科学家的实用指南
  • 数据科学推荐

如何开始你的第一个数据科学项目

原文:https://towardsdatascience.com/how-to-start-your-first-data-science-project-9c2afcaaa1a?source=collection_archive---------5-----------------------

启动您的数据科学之旅

在面试时展示一些数据科学项目是进入数据科学领域最重要的先决条件之一。

你可能问了一些问题,如下:

我应该如何开始一个数据科学项目?

我应该做哪种题目?

我应该使用哪种数据集?

以前,当我在考虑我应该从事什么样的数据科学项目时,我努力想出一些实用而独特的想法来开始我的第一个数据科学项目。网上有大量的数据科学项目,但我确实希望我能做一些不同的事情。

需要注意的一点是,我所说的数据科学项目不是一个学校项目,而是一个个人数据科学项目。

你可能会想,为什么不是学校项目

假设您是招聘经理,您打算只招聘一名数据科学家。假设你心中只有两个候选人。他们两个似乎有相似的背景,但是你只考虑雇佣其中一个。因此,你给了他们两个人一个面试的机会,并告诉他们准备好他们之前的项目提交给你。

候选人 A:这是我在一个四人小组中完成的一个学校项目。我负责建立机器学习模型。

应聘者 B:我在找房子的时候一直面临一个问题——我如何知道我喜欢的房子的面积租金是否合理。因此,我开始致力于这个项目,以澄清我的疑虑。

那么,你会更有兴趣听哪位候选人的呢?我觉得答案挺明显的,就是候选人 b。

在这篇文章中,我将分享如何开始一个个人项目的逐步指南。

第一步:确定一个要解决的现实问题

找到自己的痒处。例如,你有一个销售钥匙链的网站。你已经厌倦了浏览评论,你想自动化这个过程。因此,您可以建立一个情绪分析模型来确定您的客户是否满意。

也许你认为这个项目太容易了,并愿意进入下一个阶段。您可以使用构建主题建模模型来了解您可以改进的领域。例如,你发现你的客户一直在评论的一个话题是钥匙链设计缺乏变化。因此,通过不看评论,你可以知道你应该改进的地方。

另一方面,也许你正在持有一些股票。你根据一些规则或技术指标来买卖你的股票,但是你想让它自动化。这里有两种自动化的方法,要么你写一个程序来找出信号,要么训练一个模型来读取最新的消息,这样你就可以比信号出现的速度更快地出售或购买它。

你仍然可以从 Kaggle 项目开始,但是如果你能发现并解决你的问题,这意味着你有能力自己定义和解决问题。

如果你想要一些关于这个主题的参考资料,你可以参考下面的网站:

  1. https://www . analyticsvidhya . com/blog/2018/05/24-ultimate-data-science-projects-to-boost-your-knowledge-and-skills/
  2. 【http://intellspot.com/data-science-project-ideas/

步骤 2:决定要处理哪个数据集

你可以选择使用 Kaggle 等开源数据集,但也可以选择自己收集数据。

有几种方法可以自己检索数据。最简单的方法是使用目标网站提供的应用程序接口(API)。如果你想挑战自己,你可以尝试抓取网站来获取你的数据。通常,数据会更脏,因此你可以展示你的数据清理技能。

如果你不想抓取数据,我的建议是选择一个更大的数据集,这样你就可以在处理大型数据集时有更多的机会。

另一方面,您可以选择更难检索的数据集。例如,当我试图对马来西亚汽车市场进行分析时,我能得到的公共数据集只有 PDF 扫描图像。因此,我必须执行 OCR(光学字符识别)来从 PDF 中的表格中提取数据。

如果你有兴趣知道更多关于我如何设法提取数据的细节,请随意访问这个链接。

访问开源数据集的链接:

  1. https://github.com/awesomedata/awesome-public-datasets
  2. https://www.kaggle.com/datasets
  3. https://www . freecodecamp . org/news/https-medium-freecodecamp-org-best-free-open-data-sources-any one-can-use-a65b 514 b 0f 2d/

执行分析和建模

在尝试任何模型之前,尽最大努力深入研究数据。仔细观察,以确定可能的模式或趋势,并输入到机器学习模型中。

请注意,收集、清理和分析部分将消耗您的大部分时间。不要太强调建模部分,反而应该多花点时间在特征工程部分。如果你能为你的模型找到一个好的学习特征,你的模型很有可能从这个特征中学到很多。

此外,画出你认为对解决问题很重要的有用的图表。不要为了展示你的绘图技术而画图表。永远记住,大多数人寻找的技能是克服商业障碍的能力

最后的想法

对于那些没有数据科学背景的人来说,项目可以被描述为你解决任务能力的代理。因此,一定要明智地选择一个题目,并努力去做。

默默努力,让你的成功成为你的噪音——蒂芙尼·特朗普

非常感谢你阅读到最后,这是我的新网站提供网络爬行服务。如果你想找人帮你抓取数据,请随时通过 Linkedin 或上述网站联系我。

关于作者

低伟鸿是 Shopee 的数据科学家。他的经验更多地涉及抓取网站,创建数据管道,以及实施机器学习模型来解决业务问题。

他提供爬行服务,可以为你提供你需要的准确和干净的数据。你可以访问这个网站查看他的作品集,也可以联系他获取抓取服务

你可以在 LinkedIn 和 Medium 上和他联系。

如何开始自己的机器学习项目

原文:https://towardsdatascience.com/how-to-start-your-own-machine-learning-projects-4872a41e4e9c?source=collection_archive---------4-----------------------

哪些课程没有(也不能)教给你

Where most of my project work goes down. See more on YouTube.

戴夫开始说话。

测试结果出来了。怀尔德是聋子。

完全?

是啊,他没有在听力表上记录任何东西,即使他们在他耳边播放一种像喷气式飞机起飞一样大的噪音。

接下来会发生什么?

我们将进行更多的测试,如果他符合条件,他将接受耳蜗植入来帮助听力。但是他们还不确定。

戴夫是我最好的朋友。怀尔德是他的儿子。他天生失聪。医生说:“十万分之一的几率。”

我知道除了听,我什么也做不了。感到无助不是一种好的感觉。

几个星期后,我们在怀尔德的开关上。这是他第一次打开人工耳蜗,使他能够听到声音。他通过了所有的测试,是这些设备的主要候选人。

当他们上场时,这位女士放了三个音。一个高,一个中,一个低。她追踪了怀尔德对每一封信的反应。"该软件将在两者之间的空隙中构建."她说。

接下来还需要几次预约才能让植入物充分发挥作用,但这是第一次,即使只有轻微的声音,Wylder 也能听到了。

活动的前一天早上,我早早起床,开始在 Coursera 上学习生物信息学专业。我想知道更多。必须知道更多。什么是生物信息学?这是生物学和技术的交叉。维基百科增加了一点深度。

生物信息学是一个跨学科领域,开发理解生物数据的方法和软件工具。作为一门跨学科的科学,生物信息学结合了生物学、计算机科学、信息工程、数学和统计学来分析和解释生物数据。

为什么是生物信息学?我想知道更多关于怀尔德的事情。耳蜗是什么?是什么原因造成的?是基因吗?哪个基因?我所知道的编程知识能有所帮助吗?

为什么 Coursera ?因为在过去的两年里,我的很多知识都是从这里开始的。

关键词是基础。课程和专业非常适合这个。但是知识增长的真正方式是通过修补,探索,扩展,建立在这些基础之上。

所以我建立了自己的项目。一个探索 DNA。寻找与内耳毛细胞发育有关的基因。他们做了什么?毛细胞将声波转化为大脑可以解释为声音的电信号。我能在生物信息学专业中使用我所学的代码操作 DNA 吗?是的。

但事实证明这一切都是错的。

我所做的一切都没有生物学或科学基础。我给做了一个关于它的视频,评论里有人这么说。我已经知道了。我在视频的开头加了一条,在描述中也加了一条。

如果错了又有什么意义呢?

我们会谈到这一点。最好先从为什么开始。

为什么是你自己的项目?

当你开始学骑自行车时,你戴着辅助轮。你学会了如何兜售,如何刹车,如何移动车把。

但是你遗漏了一些东西。骑自行车最重要的技能。平衡。

只有当训练轮脱落后,你才学会如何保持平衡。

我在 Coursera 上使用了应用数据科学和 Python 专门化来建立数据科学的知识基础。但是当我致力于构建探索性数据分析的温和介绍时,我学到了更多。这也是不对的。看过的人自己研究了一下,告诉我。所以我修好了。然后还有一个别人发现的错误。我修正的每一个错误,都让我学到了新的东西。更深层的东西。一些我以前没见过的东西。

有知识基础很重要。知道如何兜售,如何刹车和如何驾驶对骑自行车很重要。但是当训练的车轮停下来的时候,学习更多的这些东西是不会帮助你的。

课程也是一样。你可以继续完成更多的课程,提高你的知识基础(你应该这样做),但不要把这误认为是能力。

参加更多关于如何更好地兜售的课程不会让你骑自行车。

只有当你卸下辅助轮,你才能学会骑车。

一些可能不起作用的东西

最好的项目就是这样开始的。

当你去旅行时,有一个指南针和一张地图是很好的。但是如果你只能选择一个呢?哪个更重要?

指南针。

为什么?

因为地图只有一定数量的路径。指南针可以有无数种用途。

这就是你如何构建自己的项目。从你想去的方向开始。一个想法,一个主意。那是你的指南针。

计划好你要采取的步骤是有价值的,但是不要让它阻碍探索。

没有一个伟大的项目是从一个人预先知道他们要走的确切路线开始的。如果你已经知道事情会如何发展,你会感到厌烦。已知的未来已经成为过去。

交叉规则

这就是混合想法的切入点。假设你一直在学习数据科学和机器学习。你已经学了一些课程,但现在你想学更多。

你不可能在一件事情上做到最好。你可以试试,但是记住,竞争很激烈。更好的选择是成为跨界者中的佼佼者。两件事,三件事,四件事的交叉。但是不要太多,否则质量会开始下降。

这与项目有什么关系?

你可以利用你在课程中积累的知识基础,并将其与你在心理健康方面所做的研究相结合。你如何利用数据向他人展示对精神健康世界的见解?

如果你是一名音乐家,你可以使用机器学习从你的旧录音带中创作一首新歌。

例子不胜枚举,但公式保持不变。无论你的兴趣是什么,健康、艺术、技术、科学、金融、工程、天气,交叉在哪里?

The crossover happens when you take one of your skills and pair it with another.

允许犯错

在考试中做错了什么,它通常会返回一个红叉,旁边写着你错了

学校强调避免犯错。生活鼓励它。

这并不意味着你应该有错的目标。但是当你开始自己的新工作时。一个可能行不通的项目,允许自己犯错。

为什么?

因为犯错会调整你的罗盘。这是一个学习的机会。现在你知道哪里不能去了。

我的下一个项目会更好,因为我的上一个项目有错误。

创建一个时间表,从小处着手

我将为此工作四周。

你可以这么说。连续四周每天一小时是很好的时间。

你可以根据自己的需要调整这些数字。但是有一个截止日期给了你努力的方向。

我哥哥和我在咖啡馆。他开始说话。

我一直在看这门课。

给我看看。

他给我看了。我通读了一遍。我说话了。

但是你已经做了所有这些事情?你已经完成了基础,你已经完成了高级数据结构,你已经完成了发布你自己的项目。你想从中得到什么?

我不确定我认为了解更多会有帮助。

你一个月做一个小 app 怎么样?称之为 App 一个月,分享一个关于每一个的故事。

是的,你说得对,第一周是设计,第二周是计划和原型制作,第三周也一样,然后在第四周发布。

他的眼里充满了想法。我笑了。然后说话了。

现在你在想。

你可能无法控制你的项目是否达到你想象的一切,但是投入一定的时间和精力是可以做到的。

总会有干扰。生活就是这样。当它发生时,处理好它,然后带着时间表回到你的项目中。

Once you’ve picked something to work on, shut everything else out for a period of time.

当你准备好 70%的时候开始

够了。你永远不会 100%准备好。

分享一个故事

你选择了一些不可行的东西,你使用了交叉法则。你还没完全准备好就开始了。你坚持你的时间表。

现在怎么办?

装运它。分享你的所作所为。

现在其他人可以批评你的工作,告诉你哪里错了,告诉你哪里对了,帮助你变得更好,这就是你所追求的,不是吗?

下次有人问你在忙什么,你就有故事了。

我开始从事一个生物信息学项目,我不知道结果会如何,但我脑海中有一个想法。我想看看我是否能把我在 Coursera 上的生物信息学专门化课程中学到的东西结合到我最好的朋友的儿子身上。他天生失聪,所以我研究了是什么基因导致婴儿失聪。我发现了 ATOH1 基因。它负责触发耳朵中毛细胞的生长。毛细胞将声波转化为电信号。我花了大约一个月的时间进行研究和构建,但当我有了一些东西时,我制作了一个视频,并在网上发布了我的代码。我意识到我的发现没有一个是生物学或科学上合理的。有人给我指出来了。但是现在我知道我下一步要去哪里了。我被迷住了。

我的生物信息学项目错了。但是我学到了一些东西。我知道下一步该做什么。

我的探索性数据分析教程有错误。人们好心地给我指出来。这让它变得更好。这让我以后的工作更好。

你听过我的。你呢?

你可以在 Twitter 、 LinkedIn 、 YouTube 和mrdbourke.com上找到更多我的作品和故事。

学习数据科学时如何保持动力和生产力

原文:https://towardsdatascience.com/how-to-stay-motivated-and-productive-when-learning-data-science-6b3fbdf8697f?source=collection_archive---------15-----------------------

学习数据科学需要耗费大量的时间和精力。你需要理解数学、计算机科学和无数不断变化的工具的组成部分。这是一项艰巨的任务,很难保持动力。

随着时间的推移,我发现了各种有效学习数据科学技能的方法,同时对我的工作保持兴奋。我把这种智慧浓缩成了 5 个“秘诀”。我希望你能和我一样从下面的概念中受益!

Photo by JESHOOTS.COM on Unsplash

所有这些技巧都来自我读过的各种书籍。提示一来自 James Clear 的 原子习惯 ,提示二和三来自 Sean Covey 的执行的 4 个纪律,最后两个提示来自 Cal Newport 的 深度作业 。这些书对我的生活和工作方式产生了巨大的影响,所以我强烈推荐它们。

秘诀 1:从小处着手,培养良好的习惯

习惯是学习任何新领域的关键。不幸的是,所有伟大的习惯都需要重复。如果某件事稍微有点困难,我们就不太愿意去做。这里的智慧是在开始的时候让习惯尽可能简单,然后在此基础上发展。首先,找出你想要培养的行为,然后提炼出它最基本的形式。

例如,当我第一次试图减肥时,我开始每天只做一个俯卧撑。希望即使我躺在病床上,我也能完成这项活动。门槛太低了,如果我不这么做,我会觉得自己很糟糕。

我很快发现,一旦我趴在地上做俯卧撑,我会倾向于做更多(谁会只做一个俯卧撑呢?).我还发现,如果我只有时间创作一首单曲,我也不会感到难过。对我来说,创造可持续习惯的两个关键是:( 1)让开始变得容易;( 2)如果你做了最少的事情,不要感觉不好。

几周后,当俯卧撑根深蒂固时,我开始建立这个习惯。我慢慢增加我每天做的次数。我还加了一个引体向上和 2 分钟的动感单车。经过一年的这种结构,我已经建立了每天大约 45 分钟的拉伸和锻炼,我几乎从未错过。

从数据科学的角度来看,我会从每天写一行代码开始。你甚至不需要电脑,你可以在笔记本上做伪代码。你也可以承诺每天阅读你最喜欢的数据科学账户的推文,看看 kaggle 内核,或者看一小段数据科学 YouTube 视频。如果你养成了这些习惯,在你意识到之前,你每天都会做大量的数据科学实践!

技巧 2:设定明确的目标,专注于你的“领先指标”

我们大多数人都关注那些我们不能立即控制的事情。最明显的例子就是减肥。大多数人关注的是体重秤上的数字;然而,这在日常生活中是很难影响的。通常,立即减肥是不健康做法的结果。另一方面,我们可以跟踪许多其他我们可以“健康”控制的事情。我们测量每周去健身房多少次,或者我们吃了多少卡路里。这两件事高度相关(甚至是因果???)的减肥。此外,我们几乎可以完全控制是否执行这些活动。

去健身房和计算卡路里是领先指标的例子,因为它们在目标(减肥)之前。我们减掉的体重被认为是一个滞后指标,因为它跟随着我们采取的行动。

控制和即时反馈是自我激励的组成部分。关注销售线索指标允许您将这两个元素注入到您的工作流程中。

知道目标是什么并为其设定界限仍然很重要。如果我们不知道在特定的时间段内我们想要减掉多少体重,我们应该如何调整我们的健身房和饮食需求就不清楚了。在离散的时间框架内创建具有清晰结果的滞后指标。

在我职业生涯的早期,每当我试图学习一种新的算法时,我都会应用这个方法。我的目标通常是每两周用一种新方法做一个项目。完整理解的一些示例指标如下:

  • (导语)观看 3 段解释这一概念的视频
  • 阅读两篇使用该方法的学术文章
  • (lead) 用 python 从头开始编写算法
  • (领导)完成项目并与同事或在 YouTube 上分享
  • (滞后)在两周时间内展示对新算法的理解

如果我执行了这些步骤,我对自己对新概念的理解感到满意。

我在找新工作的时候也应用了这个。我的目标是在两个月内找到一个新的角色。这项活动的一些主要指标是:

  • (领导)每天发出 3 份申请
  • 每周进行两次信息访谈
  • (lead) 每天花 30 分钟编写&数据科学面试问题
  • (领导)每两周完成一个项目,添加到我的投资组合中
  • (滞后)两个月内获得一份新的数据科学工作

同样,我知道如果我虔诚地做这些活动,我想要的结果就会随之而来。

提示 3:通过记录分数和依靠你的同事来保持责任感

将你的生活分成超前和滞后指标并不难。然而,很难在他们身上执行。我发现的最好的方法是记分。我在成长过程中参加过许多运动,我知道当我知道我们在记分时,我总是会提高我的水平。我个人在每天填写的“记分卡”上记录我所有的领先和落后指标。这是把你所有的日常习惯都放在一个地方,并收集一些关于你自己的数据的好方法。你已经收集和分析了所有其他方面的数据,为什么不看看你自己的呢?

从动机的角度来看,这个行动让你的生活变得有趣。它还鼓励你对自己诚实,这有时很难做到。

虽然为自己记分会给你指明正确的方向,但让别人对你负责会增加赌注。让你的学习伙伴、朋友、同事或家庭成员也对你负责,会对你的工作效率产生奇迹。让自己失望是一回事,但让你在乎的人失望是完全不同的另一回事。

理想的情况是和另一个人一起学习数据科学。如果你没有跟上你的目标,你可能会觉得你被落下了。

提示 4:安排好你的一整天,包括休息时间

在我开始工作之前安排我的一天对我的能量水平来说是革命性的。以前,我会花费大量的时间和精力在“下一步”要完成的活动上。日程安排消除了所有的认知努力,让你不用去想接下来一天要做什么。你只需要看看你的日历,执行它告诉你做的任何事情。如果你想学技术,按计划编写就像编译代码然后执行它。在大多数情况下,要求您预编译代码的语言执行速度更快。在编译的过程中,所有的变量类型都被检查,所以计算机知道它可以执行这个文件。在解释语言中,由于这个额外的步骤,运行代码需要更长的时间。

我支持安排你一天中的每一部分,包括休息时间。通过这样做,你可以避免休息蠕变,因为你已经限制了你的休息时间。我过去常常做完事情,完全不知道休息时间有多长,因为我不确定下一次休息会在什么时候。用这种方法,你可以准确地知道何时何地你会得到另一次休息。

当安排时间时,如果你的一天被劫持了,重新调整是很重要的。这对我来说非常普遍,可以认为是积极计划的一个陷阱。我发现只要我花一些时间(5-10 分钟)来调整我的时间表,我就可以相对容易地完全回到正轨。如果我在一颗小行星毁了我的一天后试图即兴表演,事情会很快失控。

技巧 5:设计你的工作场所,优化工作质量

成功学习的关键是让事情对你来说尽可能简单。如果你不想吃垃圾食品,你可以把它留在身边,用意志力来抵抗这种渴望,或者你可以一开始就不买。对抗你的意志力会消耗我们的注意力和精力。后一种选择是最大化你的生产力和内心平静的最佳选择。

学习数据科学时,您希望限制任何外界干扰。我建议在投入时间学习时,做以下环境方面的调整:

  • 关闭电脑上所有多余的窗口。只打开与手头任务相关的窗口。最坏的情况是,把你所有的其他东西放在你电脑上的另一个虚拟工作空间里。
  • 把你的手机放在另一个房间,只在你预定的休息时间查看
  • 关闭手机和电脑上的所有通知
  • 在一个与你放松或休息的地方分开的地方工作。人们很容易被舒适的床、沙发或电视所诱惑。

你还在等什么?

这些见解改变了我个人的工作方式。我希望它们能帮助您学习数据科学,并最大限度地提高您的生产力和积极性!

作为一名数据/研究科学家,如何与时俱进

原文:https://towardsdatascience.com/how-to-stay-up-to-date-as-a-data-research-scientist-3846ef6b1739?source=collection_archive---------10-----------------------

我如何跟上所有新的研究论文和新的机器学习更新?让我告诉你我是做什么的。

I am sitting somewhere in there if you can spot me. (Image is from https://www.flickr.com/photos/teamrework/31974957947/in/album-72157676030072907/)

介绍

你好。

S o 看了我的教程 无学位如何数据科学 ( 39k 浏览量和统计截至 2019 年 1 月!谢谢你。 ) ,但你的旅程才刚刚开始。随着每年数百篇研究论文的发表和深度学习行业的重大技术进步,很难保持领先。

尽管我热爱我的工作,但我知道如果我不跟上时代并继续学习,就很难保持胜任和相关的工作。尽管你在数学、编程和机器学习方面的基础知识总是必不可少的,但是新的想法和工具每天都在被引入。你必须不断学习。

跟上时代是我不断努力掌握的东西。是的,这可能让人不知所措,但是深呼吸一下,知道这对任何人来说都不容易,你就会感到安慰。为了让你的旅程更轻松,我想分享一些我非常喜欢用来保持领先的技巧和资源。这些是:会议、Twitter、工程博客、时事通讯、研究论文和 YouTube。

1.会议

At the Rework Deep Learning Conference

我想从会议开始,因为我刚刚在 2019 年 1 月从一个会议回来。在我看来,这可能是最昂贵但也是最有趣的选择。自从我成为数据科学家以来,我已经参加了以下会议:

  • 2018data bricks Spark+AI Summit @三藩
  • 2019 返工深度学习峰会@旧金山

置身于一个充满专家、领导者和渴望学习你所呼吸和实践的话题的人的环境中是相当超现实的。虽然我发现在这些会议上与陌生人交谈并不容易,但与会的每个人都很高兴与你谈论他们的兴趣和项目。例如,午餐时,我和坐在我旁边的人就他们的工作和项目进行了许多有趣的对话。了解不同的人和行业如何应用深度学习真是太棒了。

此外,我真的很喜欢参加会议上的演示,因为你可以看到其他人正在做什么,看到趋势和新技术。看到像谷歌脸书OpenAI 这样的研究领导者在做什么是非常激励人心的。此外,你还可以听到像 Dropbox易贝Airbnb优步网飞这样的公司在深度学习方面做了什么。发布会结束后,我想起了(生成对抗网络)的力量,想尝试学习一下 PyTorch 因为1.0 版本终于在 2019 年 1 月发布了。

既然你不再处于一个结构化的学校环境中,我把这些会议视为学校课程。记得参加 Spark 峰会的时候,了解到熊猫 UDF (我相信是在 Spark2.3 版上),回去后马上开始在工作中使用。

当你在自学或在公司做项目时,行业的所有变化和趋势可能都不是很明显。但是参加会议真的给了你视角,让你亲身感受到每个人都在做什么。

有几种方式可以参加:

  • 让您的公司支付费用(最佳选择)。如果你们一起去,要求打折。即使你不跟团去,他们也经常提供折扣。所以就问吧!
  • 要求在大会上做志愿者,免费去(我遇到过这样做的人)。
  • 作为学生参加,你通常可以得到很大的折扣。

接下来,我想尝试去 NIPS(神经信息处理系统)ICLR(国际学习代表大会)这两个更偏重学术的地方。

2.推特

Example Deep Learning News on Twitter

我之前并不是很喜欢 twitter,但是因为深度学习新闻我又开始了。我发现许多人(研究人员和公司)在 twitter 上发布有价值的最新信息。正如你在上面看到的, GoogleAI 账户经常发布他们深度学习研究的更新。

当我开始关注一些著名的深度学习的人和公司账号( @GoogleAI、@OpenAI、@AndrewYNg、@ KDNuggets、@Goodfellow_Ian、@YLeCun、@Karpathy )时,我很容易找到其他人,因为 twitter 一直在推荐类似的账号。

我的账号目前超级无聊,不过可以随意关注: @jasjung_ 。我计划用它来发布自发的提示或更新,但主要是向其他深度学习明星学习。

3.工程博客和电子邮件简讯

如果你搜索类似“最佳数据科学通讯”的东西,你会得到很多很棒的结果。这是我收集资源的方式之一。

3.1.公司工程/技术博客

Image caption from Airbnb Tech Blog on Medium

我认为这些工程博客是公司在纸上举行的迷你会议,向世界炫耀和分享他们最新最聪明的成就。他们经常在这里展示有趣的实验、研究和项目。因为是公司维护的,所以质量通常很高。我认为 Medium 开始在这里发挥重要作用,因为许多公司开始在 Medium 上托管他们的工程和技术博客。这里有几个我喜欢的网站!

  • T3【网飞理工大学博客】中型
  • 脸书研究博客
  • 谷歌人工智能博客
  • 优步工程博客 (如需机器学习相关内容,请点击此处
  • Airbnb Tech Blog on Medium(如果你只想要机器学习相关的内容,点击这里

请记住,工程博客不会只谈论机器学习,但他们经常这样做,并有许多其他有趣的事情可以阅读。

3.2.时事通讯

除了工程博客,还有许多在线出版物的时事通讯,如 Medium 或 personal,你可以订阅。我认为这些内容更个人化,更容易理解,因为像我这样的任何人都可以写这些文章。它们通常包含小型的个人项目,而来自公司博客的项目对于个人来说可能有点深远。

  • 走向数据科学 这样的刊物绝对是我关注的一个。我发现每天的简讯太多了,但每周订阅一次对我来说已经足够了。
  • 我真正喜欢的一个个人简讯是 机器学习很有趣 。它发送有趣的每周文章,如果你想的话,你可以自己尝试一下。
  • 杰森·布朗利的【machinelearningmastery.com】也包含了很多实用的教程和代码。

我知道还有很多,但我还没有真正探索太多。所以如果你知道更多,请在下面的评论里告诉我!

4.研究论文

最后但同样重要的是,这是另一个免费但最困难的选择。对于这一部分,我建议你查看以下 Medium 上的帖子:开始阅读深度学习研究论文:为什么和如何 。”作者提供了许多阅读研究论文的有用信息和技巧。综上所述,如果你有兴趣阅读机器学习研究论文,你应该去Arxiv Sanity Preservera project byAndrej kar pathy。它基本上向你展示了最新、最受欢迎的研究论文,这样你就可以读到最有趣的论文。用他自己的话来解释这个项目:****

这个项目是一个网络界面,试图驯服 Arxiv 上铺天盖地的论文。它允许研究人员跟踪最近的论文,搜索论文,根据与任何论文的相似性对论文进行排序,查看最近的热门论文,将论文添加到个人图书馆,并获得(新的或旧的)Arxiv 论文的个性化推荐…

我说这是最难的选项,因为我不能随便看这些论文。我需要集中注意力,需要更长的时间来阅读。有时候,我需要一张纸来完成数学。尽管这对我来说是最困难的选择,但也是最有收获的,因为你真的很好地理解了这个主题。我计划在我的机器学习 Github 库中有一个研究论文目录来记录我的阅读。我会尽我所能经常更新。

如果你需要一篇论文作为开始,看看下面这篇论文。由于在卷积神经网络中的成功工作,许多人将此视为深度学习中最有影响力的论文之一。

  • 【ImageNet 分类与深度卷积神经网络(2012) 作者Alex Krizhevsky、Ilya Sutskever、Geoffrey Hinton。

以下是该论文的摘要,供您参考:

我们训练了一个大型深度卷积神经网络,将 ImageNet LSVRC-2010 竞赛中的 120 万幅高分辨率图像分类为 1000 个不同的类别。在测试数据上,我们实现了 37.5%和 17.0%的前 1 名和前 5 名错误率,这大大优于以前的最先进水平。具有 6000 万个参数和 650,000 个神经元的神经网络由五个卷积层组成,其中一些卷积层后面是 max-pooling 层,以及三个完全连接的层,最后是 1000 路 softmax。为了加快训练速度,我们使用了非饱和神经元和卷积运算的高效 GPU 实现。为了减少全连接层中的过拟合,我们采用了最近开发的正则化方法“dropout ”,该方法被证明非常有效。我们还在 ILSVRC-2012 竞赛中加入了该模型的变体,并获得了 15.3%的前五名测试错误率,而第二名的错误率为 26.2%。

5.YOUTUBE(2019–04–13 更新)

我在这里增加了一个部分,因为我真的相信这是有帮助的!许多人都会同意,YouTube 是一个学习如此多主题的好地方。我喜欢在 YouTube 上关注 Siraj Raval 的频道。他发布了许多关于人工智能主题的最新更新和教程。它们看起来也很有趣。

结论

当大量的新信息铺天盖地而来时,保持最新是一项令人生畏的任务。这是我每天都在纠结的事情。但是我希望这些资源可以帮助你引导你的旅程,保持在这一切之上。如果你知道什么好的资源,请在下面的评论里分享!我很想了解他们。

最后,不要感到阅读和学习一切的压力。学习所有的东西可能是不可能的,所以你必须挑选。选择一个让 火花四射的 给你。如果你不喜欢内容,那学习还有什么意义?

祝你好运,感谢你的阅读!

( 领英 推特 )

2019–07–31 更新。

查看我的最新项目www。薪.忍者 及相应文章 欢迎来到薪忍者

2019–10–30 更新。

看看我的程序( AlphaBlitz ),它用深度学习打败了脸书的文字游戏。喜欢并订阅!😃

如何存储金融市场数据以进行回溯测试

原文:https://towardsdatascience.com/how-to-store-financial-market-data-for-backtesting-84b95fc016fc?source=collection_archive---------4-----------------------

我正在处理中等规模的金融价格数据集。我所说的适度大是指每个资产少于 4 百万行。

400 万行可以覆盖常规资产(如指数期货合约或常规现金股票)在没有延长交易时间的情况下所做的过去 20 年的分钟价格棒线。

当处理价格柱时,分钟和 5 分钟柱会产生大量的数据集。如果你碰巧处理分笔成交点分析,那么它将是巨大的而不是巨大的,但是分笔成交点数据的获取、管理和货币化是非常昂贵的;除非你在回溯测试刷单策略,或者在 HFT 行业工作,否则他们的优势是可疑的。

尽管 400 万行听起来并不令人印象深刻,但我们需要理解,每项资产有 400 万行。因此,分析来自 Russell 2000 的所有资产将意味着 80 亿行(现在我们越来越大)。添加一些欧洲股票市场、你所在国家的中小市值股票、大宗商品和外汇就可以了:你刚刚登上了大数据竞技场。

世界上有 1700 多个受监管的市场,一旦你开始积累日内数据,这些数字就会变得令人印象深刻——非常快。

还要记住,目前的趋势是延长所有期货合约的交易时间——欧洲期货交易所从去年 1 月开始延长 FDAX 期货的交易时间,所以就需要分析的数据量而言,情况并没有好转。

现在,每个“金融数据科学家”都会问自己一个问题:我应该把我的数据放在哪里,怎么放。

关系数据库是第一个答案,可能不是最有效的,但肯定是最简单的。

我可以列举四个选项作为主要的存储库策略:

  1. SQL 关系数据库。
  2. 大型数组的序列化存储。
  3. 键/值数据库(比如 Oracle Berkeley DB )。
  4. CSV 文件。

出于明显的原因,我放弃了最后一个,对于其他三个,我只评估了前两个。

我计划探索第三个:键/值数据库。这些数据库并不是真正的主流,但在处理需要大量阅读的简单数据结构时,它们可以提供出色的性能(金融数据就是这种情况)。我真的相信这可能是序列化存储和关系数据库之间的最佳折衷解决方案。

在这篇文章中,我主要关注第一个策略。在进入细节之前,我们将回顾一下我们正在处理的数据。

烛台的快速历史回顾:我们为什么使用它们

几乎所有你要在金融市场上交易的数据都是价格条或烛台。这是有原因的。金融价格条的高/低/开/闭结构类似于统计学中使用的经典须状图和盒状图,但是它们更容易获得。

Price bar used in financial markets.

我使用了类似于 T1 的词,因为胡须和箱形柱(四分位数和中位数)提供的所有重要信息在金融烛台上是无法获得的。四分位数和中位数不是任意值,它们提供了关于被分析变量的描述性信息。

Whiskers and box bar used in statistics.

有人可能想知道为什么在金融市场中不使用晶须和盒棒线(我认为它的使用可能会导致有用和创新的价格行为洞察力),原因很简单。烛台图表被认为是在 18 世纪由一个叫 Munehisa Homma 的日本大米商人首先使用的。如果你想知道 18 世纪是否有期货合约,你会想知道虽然第一个现代期货合约交易所是 T2 芝加哥期货交易所,但在 17 世纪欧洲和日本已经建立了期货市场。

The Dōjima Rice Exchange Monument. First future contracts exchange in Japan.

获得最高价、最低价、开盘价和收盘价来建造一个特定时期的烛台是非常容易的。你只需要一段时间内所有交易的清单。现在交易是电子化的,并且以有序的方式进行,但是请记住,情况并非总是如此。电子交易是相对现代的(它在 80 年代开始获得相关性)。在那之前,场内交易是常态,资产只在特定时间在场内交易。我们所知的持续交易市场的概念在当时并不适用。

即使在几乎所有交易都以电子方式进行的当前情况下,存储和分析在给定时期发生的所有交易以构建胡须和箱线图也是具有挑战性的(可行,但具有挑战性)。这意味着要么对订单簿进行严格的连续跟踪— 阅读磁带— ,要么以不太严格的方式将较短的时间框架整合为较长的时间框架。

通过使用烛台,你最终会得到与四分位数和中位数类似的信息(请注意,突出显示了与 T9 类似的信息)。这就是所谓的烛台或烛台模式的价格行为,实际上,这只是对所有烛台系列中价格相关之处的解释性分析。所以一根大胡须和一个小身体(比如你在一只蜻蜓身上发现的)将意味着价格拒绝,如果大部分时间价格都集中在身体部分,当它试图移动到该区域下方或上方时,它很快就会被拒绝。这就是你可以从烛台上得出的结论(同样,当你在给定的市场背景下阅读它时)。

因此,存储开盘价/收盘价/最低价/最高价的区间价格信息将能够进行一定程度的价格行为分析,并且根据经验,给定环境中的某些模式具有统计相关性,并且将导致有利可图的策略。

存储烛台的数据模型

现在我们理解了为什么使用烛台,我们可以提出一个简单的数据模型来存储我们的信息。

CREATE TABLE candlestick (“id” INTEGER PRIMARY KEY AUTOINCREMENT,“timezone” TEXT NOT NULL,“timestamp” DATETIME NOT NULL,“open” DECIMAL(12, 6) NOT NULL,“high” DECIMAL(12, 6) NOT NULL,“low” DECIMAL(12, 6) NOT NULL,“close” DECIMAL(12, 6) NOT NULL,“volume” DECIMAL(12, 6) NOT NULL
);

我肯定您对这个简单的数据模型印象不深,但是即使是这个模型也可能会受到挑战。我们将不讨论timezone列(我计划写另一篇关于时区和数据的文章),但是timestamp的用法已经是相关的并且有性能问题。

从可用性的角度来看,这种存储财务信息的方式简单且结构良好。查询数据非常简单:

sqlite> select * from candlestick where date(timestamp)='2018-01-12' limit 10;3489458|Europe/Berlin|2018-01-12 07:00:00+01:00|13243.5|13245.5|13234.5|13245.5|294
3489459|Europe/Berlin|2018-01-12 07:01:00+01:00|13244.5|13250|13243|13245|149
3489460|Europe/Berlin|2018-01-12 07:02:00+01:00|13244.5|13246|13242.5|13244|39
3489461|Europe/Berlin|2018-01-12 07:03:00+01:00|13242.5|13243.5|13239|13241.5|64
3489462|Europe/Berlin|2018-01-12 07:04:00+01:00|13241|13241|13235.5|13236.5|61
3489463|Europe/Berlin|2018-01-12 07:05:00+01:00|13236.5|13240|13236|13239.5|49
3489464|Europe/Berlin|2018-01-12 07:06:00+01:00|13239|13241.5|13237|13240|49
3489465|Europe/Berlin|2018-01-12 07:07:00+01:00|13238.5|13241|13237|13239|43
3489466|Europe/Berlin|2018-01-12 07:08:00+01:00|13239|13239|13236.5|13237|24
3489467|Europe/Berlin|2018-01-12 07:09:00+01:00|13237|13239|13237|13239|11

获取给定时段的开盘价很简单:

sqlite> select * from candlestick where date(timestamp)='2018-01-12' limit 1;3489458|Europe/Berlin|2018-01-12 07:00:00+01:00|13243.5|13245.5|13234.5|13245.5|294

所以它得到了收盘价:

 sqlite> select * from candlestick where date(timestamp)='2018-01-11' order by timestamp desc limit 1;3489457|Europe/Berlin|2018-01-11 21:03:00+01:00|13241|13241|13241|13241|25

但是这种方式有一些性能问题,我们将在后面讨论。

注意,我们使用了datetime字段来存储时间戳。我们也可以使用单独的字段来表示年、月、日、小时和分钟,但这将使以后在 Python(或 Java)中处理datetime类型变得复杂。这些复杂类型可能会带来性能问题,但也有助于处理时间、时区、时间偏移等。它还支持在 SQL 查询中使用时间范围。

未经优化的性能问题

使用这种方法存在性能问题:

  1. 当进行数据的批量加载时(使用 Python 和 ORM 来确保在 SQLite 中正确处理时间戳),在单核 VPS 服务器上需要 14 分钟。
  2. 在同一台 VPS 服务器上,获取给定会话的所有数据需要 5 秒钟。获得开盘价或收盘价的类似结果。

14 分钟听起来太长了,但批量装载并不常见,这可能是可以接受的。即使可以找到更优化的数据加载方式,这也不是重点。只需喝杯咖啡或为初始数据供应进行程序批量加载,这只会发生一次。

相反,5 秒钟可能听起来没什么大不了的,但确实如此。请记住,我们在这里处理的是多资产蒙特卡罗模拟场景。这意味着数千发子弹。所以 5 秒乘 1000 秒太长了。我们需要在这里进行优化。

虽然我不打算在这篇文章中讨论序列化策略,但我会分享一些关于这两种策略的时间比较:

# Bulk provisioning of 3.5Million price bars:SQLite + Pyhon ORM: 15 min              
Serialized Stored Arrays + ANSI C: 1.5 min# Retrieve a given specific 1 minute price bar:SQLite + Pyhon ORM: 5 seconds
Serialized Stored Arrays + ANSI C: Negligible (microseconds)

如前所述,这些环境中的真正问题是检索时间。在序列化数组中,它可以低至微秒,因为可以定义一种策略来为所有数据分配内存空间。

如果假设所有月份都有 31 天,那么检索给定的分钟只是一个超级简单的内存查找操作。没有索引或搜索操作这样的东西。

如果我们不知道交易时间(即使我们知道交易时间,也可能会有异常情况,如交易暂停或数据不一致),获得给定时段的收盘价或开盘价可能会有点困难,但我们可以遍历特定的一天。遍历所有每日数据的阵列既快速又简单。

在介绍具有内置优化功能的数据库如何加快这些数字时,我们可能会使分析过于复杂。如果您的项目能够为 DBA 优化专家分配每年 150000 美元的成本,Oracle 数据库的性能将会更好,但这里要指出的是,简单的数组查找(序列化方法)永远不会被任何关系数据库击败。作为一个缺点,关系数据库使得查询和移动数据比存储序列化数组容易得多。

我尽可能使用 SQLite,因为它非常简单,易于使用和备份。尽管许多人说它是一个太基础的数据库,但它可以处理巨大的数据集。它的主要缺点是缺乏页面或区域锁定,这导致写很多的应用程序出现性能问题。除此之外,它的性能通常比预期的好得多,它非常轻便,而且无需维护。

创建索引以提高性能

最简单、最容易的优化是使用索引(这也是 SQLite 中唯一可以做到的)。

sqlite> create index idx_timestamp on candlestick(timestamp);sqlite> select * from candlestick where date(timestamp)='2018-01-11' order by timestamp desc limit 1;
3489457|Europe/Berlin|2018-01-11 21:03:00+01:00|13241|13241|13241|13241|25

现在搜索只需不到一秒钟。这是一个有意义的性能改进。

[user@host gaps]$ ls -ltr dax*
-rw-r--r-- 1 memmanuel memmanuel 284292096 Jan 26 12:43 dax-withoutindex.db
-rw-r--r-- 1 memmanuel memmanuel 409865216 Jan 26 22:32 dax-withindex.db

请注意,索引也极大地增加了数据库的大小。

将不同数据库中的资产分开

在 SQLite 中,拥有几个数据库非常简单。每个数据库只是一个文件的连接。因此,没有理由将所有资产合并到同一个数据库中。您可以将每个资产拆分到一个数据库文件中,并依赖于文件系统。将文件移动到不同的服务器并进行备份也将变得更加容易。在 SQLite 中处理每个数据库的多个资产将变得非常困难,它将需要一个额外的索引来跟踪资产报价器。所以这更像是一个必须要做的事情,而不是一个优化技巧。

在适用的情况下使用混合策略

将会话或每周数据从 SQLite 检索到内存数组或列表中。然后,您的数据会飞起来,您将使用 SQLite 作为永久的数据存储,在那里您可以检索大块的数据。这将减少对关系数据库性能不足的影响,同时仍然给你使用关系数据库的优势。

摘要

就性能而言,将金融价格数据存储在关系数据库中并不是最好的主意。金融市场数据是时间序列数据,其消费通常是使用基本搜索和检索查询的长链数据。

尽管如此,在关系数据库中存储数据简化了操作。所以你可以用它。

这里提到的三个简单的优化技巧/模式将会带来更好的结果:

  1. 为时间戳创建索引。
  2. 将数据集划分到不同的数据库中(在 SQLite 中,这非常简单)。
  3. 从关系数据库中检索数据子集,并使用后来的内存列表/数组。

还有更多信息可能与使用序列化数组的方法以及处理时区这一复杂的主题相关,但这些将是其他帖子的素材。

如何构建您的 PyTorch 项目

原文:https://towardsdatascience.com/how-to-structure-your-pytorch-project-89310b8b2da9?source=collection_archive---------14-----------------------

一个构建 PyTorch 培训代码的建议

自从我开始训练深度神经网络,我就在想我所有的 Python 代码应该是什么结构。理想情况下,一个好的结构应该支持广泛的模型实验,允许在一个紧凑的框架中实现各种不同的模型,并且容易被每个阅读代码的人理解。您必须能够通过编码和重用各种数据加载器来使用来自不同数据源的数据。此外,如果模型支持在一个模型中组合多个网络(如 GANs 或原始 R-CNN 的情况),那就更好了。该框架还应该具有足够的灵活性,以允许复杂的可视化(这是我在数据科学中的核心信念之一,即可视化使一切变得更容易,尤其是在计算机视觉任务的情况下)。

深度学习框架的详细实现当然取决于您正在使用的底层库,无论是 TensorFlow、PyTorch 还是 CNTK。在这篇文章中,我将介绍我基于 PyTorch 的方法。然而,我认为通用结构同样适用于您正在使用的任何库。你可以在 https://github.com/branislav1991/PyTorchProjectFramework 的找到整个资料库。

总体结构

Project structure for our deep learning framework.

在上面的图片上(取自 VS code,我选择的 Python 编辑器),你可以看到我为我的框架创建的一般文件夹结构。框架由一些启动脚本 (train.py,validate.py,hyperopt.py)以及隐藏在文件夹内的库组成。数据集文件夹包含类和方法,用于加载各种类型的数据进行训练。损失文件夹可能包含额外的损失函数或验证指标。如果您的项目不需要任何自定义损失函数,您可能不需要此文件夹。模型文件夹是最重要的:它包含实际的模型优化器文件夹包含定制优化器的代码。与 losses 文件夹一样,如果您没有任何自定义优化器,也可以忽略该文件夹。最后, utils 文件夹包含了在整个框架中使用的各种实用程序,最著名的是可视化器。您还会注意到项目根文件夹中的 config_segmentation.json 文件。该文件包含培训所需的所有配置选项。

您可能已经猜到,训练是通过调用 train.py 脚本启动的。使用适当的配置文件作为命令行参数调用该脚本。它负责所有高级别的训练工作,例如加载训练和验证数据集以及模型,设置可视化,运行训练循环,最后导出训练好的模型。

类似地,通过调用适当的脚本并将配置文件作为参数传递来使用验证。

数据集

Files in the datasets folder with a 2D segmentation dataset as an example.

在上图中,你可以看到数据集文件夹的结构。它包括 init。py 模块,包括一些必要的函数来查找和创建正确的数据集,以及一个自定义的数据加载器,它将数据转发到训练管道(有关这方面的更多信息,请查看 PyTorch API 文档)。顾名思义,base_dataset.py 为您在框架中定义的每个数据集定义了抽象基类。

对于您定义的每个自定义数据集,您必须实现 getitemlen 方法,以便 PyTorch 可以对其进行迭代。您不必再处理数据加载器,因为它是在 datasets/init 中定义的。已经开始了。您还可以为数据集定义自定义回调,以便在每个时期之前和之后调用。如果您希望使用某种预热方法,在最初的几个时期向模型提供不同的数据,然后切换到更复杂的数据集,这可能会很有用。

为了实例化数据集,train.py 脚本调用以下代码:

print(‘Initializing dataset…’)
train_dataset =create_dataset(configuration[‘train_dataset_params’])train_dataset_size = len(train_dataset)
print(‘The number of training samples = {0}’.format(train_dataset_size))

这将调用 create_dataset 函数,该函数查看配置文件并根据其名称选择正确的数据集。在命名数据集时,遵循约定_ dataset . py 很重要,因为这是脚本能够根据配置文件中的字符串找到数据集的方式。最后,上面的脚本调用数据集上的 len() 函数来通知您数据集的大小。

模型

Files in the models folder with a segmentation model as an example.

框架中的模型以与数据集相同的方式工作:init__。py 模块包括根据模块名和配置文件中定义的字符串查找和创建正确模型的函数。模型类本身继承自抽象的 BaseModel 类,并且必须实现两个方法:

  • forward(self) 运行正向预测,并且
  • optimize _ parameters(self)在训练通过后修改网络的权重。

所有其他方法都可以被重写,或者您可以使用默认的基类实现。您可能想要覆盖的函数包括 pre_epoch_callbackpost_epoch_callback (在每个 epoch 之前和之后调用)或 test (在验证期间调用)。

为了正确使用框架,了解如何使用网络、优化器和模型中的损耗是很重要的。由于在一个模型中可能有多个使用不同优化器的网络以及多个不同的损失(例如,您可能想要显示语义本地化模型的边界框分类和回归损失),所以界面会更复杂一些。具体来说,您为 BaseModel 类提供损失和网络的名称以及优化器,以了解如何训练您的模型。在提供的代码中,我包含了一个 2D 分割模型的例子和一个数据集例子,让你看看这个框架应该如何使用。

看看提供的 2D 分段模型的 init()函数:

class Segmentation2DModel(BaseModel):def __init__(self, configuration):super().__init__(configuration)self.loss_names = [‘segmentation’]self.network_names = [‘unet’]self.netunet = UNet(1, 2)self.netunet = self.netunet.to(self.device) if self.is_train: # only defined during training timeself.criterion_loss = torch.nn.CrossEntropyLoss()self.optimizer = torch.optim.Adam(self.netunet.parameters(), lr=configuration[‘lr’]) self.optimizers = [self.optimizer]

这里发生的事情是这样的:首先,我们读取模型配置。然后,我们定义“分段”损失,并将其放入 self.loss_names 列表中。损失的名称很重要,因为我们使用变量 self.loss_segmentation 来表示损失。通过了解名称,基本模型可以查找损失,并在控制台中打印或可视化(下一节将详细介绍可视化)。同样,我们定义网络的名称。这确保了 BaseModel 知道如何训练模型,而无需我们明确定义它。接下来,我们初始化网络(在本例中是 U-Net ),并将其移动到 GPU。如果我们处于训练模式,我们还定义损失标准并实例化优化器(在本例中是 Adam)。最后,我们将优化器放入self . optimizer列表中。该列表再次在基本模型类中使用,以更新学习率或从给定的检查点恢复训练。

让我们也来看看 forward()optimize_parameters() 函数:

def forward(self):self.output = self.netunet(self.input)def backward(self):self.loss_segmentation = self.criterion_loss(self.output, self.label)def optimize_parameters(self):self.loss_segmentation.backward() # calculate gradientsself.optimizer.step()self.optimizer.zero_grad()

正如您所看到的,这是标准的 PyTorch 代码:它唯一的职责是在网络上调用 forward(),在计算梯度后逐步优化程序,并再次将它们归零。为您自己的模型实现这一点应该很容易。

形象化

Files in the utils folder.

可视化可以在可视化器类中找到。这个类负责将损失信息打印到终端,以及使用 visdom 可视化各种结果。它在训练脚本开始时初始化(加载 visdom 服务器)。训练脚本还调用其 plot_current_losses()print_current_losses() 函数来可视化并写出训练损失。它还包含类似plot _ current _ validation _ metrics()plot_roc_curve()show _ validation _ images()的函数,这些函数不会自动调用,但可以从 post_epoch_callback() 中的模型中调用,以在验证时进行一些有用的可视化。我试图让可视化工具相当通用。当然,您可以自己扩展可视化工具的功能,让它对您更有用。

结论

我提出了一种编写通用深度学习框架的方法,该框架可以用于深度学习的所有领域。通过使用这种结构,您将为进一步的开发获得一个清晰而灵活的代码库。当然,解决这个问题还有许多其他方法。如果你有其他建议,请在评论中告诉我!

如何在 Mac 上成功安装 Anaconda(并让它实际工作)

原文:https://towardsdatascience.com/how-to-successfully-install-anaconda-on-a-mac-and-actually-get-it-to-work-53ce18025f97?source=collection_archive---------0-----------------------

正确安装 Anaconda 并修复可怕的“找不到 conda 命令”错误的快速而轻松的指南

Image by Michael Schwarzenberger from Pixabay

你知道你需要它。

当您开始学习数据科学、机器学习或人工智能时,您很快就会意识到您需要能够使用 Anaconda。你可能想用 Jupyter 笔记本,Spyder,或者其他很棒的程序,但是不管怎样,你都需要这个东西来工作。

最近在安装电脑时,我想起了第一次让 Anaconda 工作有多难。安装本身没有问题!官方 guid e 对于安装本身是清晰而全面的。你完成它,遵循一些简单的步骤,你就可以开始了!

最后,它告诉您通过键入类似“conda list”的命令来验证您的安装是否成功,这样就完成了!

没有。

康达没有

“康达”我第一次装的时候没用。没有现成的链接可以告诉你该怎么做。你验证一下就完事了。

你只能靠自己了。

没有什么比甚至不能打开你需要的程序更令人沮丧的了。

在机器学习和人工智能方面入门并不是一件容易的事情,无法正确安装必要的工具只会造成严重后果。随着你开始理解更多的语言和命令,你会发现有很多简单的答案。但是当一切都是新的时候,它们就没有任何意义了!仅仅谷歌一下你的问题就很有挑战性。

我实际上已经这样对自己了。

我在苹果电脑上工作(如果你感兴趣的话,可以叫我莫哈维)。在终端工作了一段时间后,我把它变成了一个快速、高效、外观漂亮的东西。你可以在这里看到我为了让我的终端变得更棒而做的一切,但本质上,它是在运行的

  • iTerm2
  • 公司自产自用
  • Zsh
  • 哦,我的 Zsh
  • 几个我的 Zsh 插件
  • Z
  • 语法突出显示

[## 在 10 分钟或更短时间内搞定你的终端

如何在短短几分钟内打造一个更好、更快、更强、更性感的终端

towardsdatascience.com](/trick-out-your-terminal-in-10-minutes-or-less-ba1e0177b7df)

我一点也不知道这会让我的 Anaconda 安装变得更加困难。事实证明,一行代码更难,但对新手来说,挑战性是一百万倍。

这是一步一步的安装过程,通过简单的一行修复程序,您可以“conda”任何您想要的东西。即使你用的是可爱又惊艳的 Zsh。

发生了什么事?

事情是这样的:安装是成功的,但是在 Zsh 和我的终端想要与 Anaconda 对话的方式之间有一个小问题。发生这种情况的原因有很多,但 Zsh 是罪魁祸首。

它非常容易修理!但是因为我不知道我在做什么,所以我花了很长时间才弄明白。

Image by boanergesjr via Pixaby

其他人不应该经历这些。

修复

官方安装指南 在这里,如果你想检查一下。

我第一次决定下载 Anaconda ,我经历了正常的图形化 Mac 安装。作为一个应用程序,它工作得很好,但它就是不能在我的终端上工作。

不愿意放弃,我卸载了 Anaconda,然后尝试命令行安装。这一点非常好,因为您可以在安装过程中决定让您的终端与 Anaconda 通信。在安装过程中,您会得到一个提示,询问“您希望安装程序通过运行 conda init 来初始化 Anaconda3 吗?”

我建议给这个答案一个大大的肯定。

当然还是没有效果。不过,如果你没有一个精心设计的终端,它可能会!如果你没有使用 Zsh 和我的 Zsh,你可能已经设置好了。

那么,如果您对终端进行了更改,如何让它正常工作呢?

很简单!

这些是成功安装 Anaconda 的简单步骤,即使面对可怕的“conda command not found”错误消息。

步骤 1:下载 Anaconda

可以去这里下载 Anaconda 。然后向下滚动一点,到显示“Anaconda 2019.03 for MAC OS Installer”的部分

您需要知道您使用的是哪个版本的 Python,所以请在您的终端上键入

python

This shows Python version 3.7.3

你有几个下载的选择。您可以选择图形化安装程序,这意味着您将像安装任何其他程序一样安装 Anaconda。或者您可以选择命令行安装程序,这意味着您将进入您的终端并键入(或复制和粘贴)命令。

我们将执行命令行安装程序,因此单击您的 Python 版本下的链接,您的下载应该会开始。

步骤 2:命令行安装

下载完成后,前往您的终端。

如果你有 Python 3.7,你会跑

bash ~/Downloads/Anaconda3-2019.03-MacOSX-x86_64.sh

对于 Python 2.7,运行

bash ~/Downloads/Anaconda2-2019.03-MacOSX-x86_64.sh

请记住,如果您没有将 Anaconda 下载到您的下载文件夹中,您将需要更改该路径。

查看许可协议,点击“回车”接受它,直到你看到最后。最后,如果你想同意,请键入“是”。

(会提示你。错过的话会反复提示。)

如果你对它建议的位置满意,点击“输入”您可以通过输入 CTRL-C 来更改位置或取消安装。注意这个位置!如果您收到错误消息,它会派上用场。

现在保持不动。耐心点。这可能需要几分钟的时间,而且您一开始并不知道是否发生了什么。如果您愿意,您可以去喝点饮料,但是要快,因为安装程序会问,“您希望安装程序通过运行 conda init 来初始化 Anaconda3 吗?”当别人问你的时候,你几乎肯定想在那里输入“是”。

“感谢您安装 Anaconda!”

安装完成后,关闭您的终端窗口并打开一个新窗口,以使更改生效。想看看有没有用吗?在您的终端中,键入如下命令

*conda list*

看看会发生什么。如果成功了,你会看到这样的东西

如果您想知道您的环境中安装了哪些包和版本,这是一个非常有用的命令!

如果成功了,恭喜你!!!您现在已经准备好开始使用 Anaconda、Jupyter Notebooks、Spyder 和所有其他好东西了。庆祝的时间到了!

Image by StockSnap from Pixabay

步骤 3:找不到 conda 命令

另一方面,你可能会看到这个:

这个问题的解决方法其实很简单。

故障排除步骤#1:

** * * 重启你的终端!!!***

(我知道我已经说过了,但是 Anaconda 团队告诉我,不刷新您的终端是人们在这一点上遇到问题的最常见原因。)

故障排除步骤#2:

您需要知道您的 Anaconda 二进制目录在哪里,以及您的用户名是什么。如果您在安装过程中注意了,您已经有了这些信息!您需要在安装过程中指定的位置。

如果没有,如果你只是简单地按照安装说明操作,很有可能你的目录是/Users/(如果你在 macOS 上)。(或者 Linux 上的/home/或者 Windows10 上的\Users\。)

如果您不知道自己的用户名,请运行

*echo $USER*

** * 更新!!***

我建议修改 PATH 来解决这个问题(您可以在下面看到最初的修复),但是 Anaconda 团队提供了一些非常有用的信息!

他们不建议修改路径!

你可以阅读下面的完整评论,但这里有一个信息的压缩版本,你可以在评论部分找到惊人的迈克尔萨拉汉:

“如果您的系统中有任何其他程序具有相同的名称,那么修改路径会导致问题,Anaconda 会首先发现这些程序,然后隐藏它们(阴影)。“conda init”所做的是建立一个 conda“shell 函数”,并使其他东西远离路径。除了康达什么都没有。然后,它默认在启动时激活您的基本环境。净效果非常像您的路径添加,但有一些微妙的,但至关重要的差异:

激活确保了 anaconda 的路径内容是正确的。将 anaconda 永久地放在 PATH 的前面是好的,因为它可以防止混淆,但是不好的是它会遮蔽其他东西,并且可能会破坏东西。激活是一种不太持久的方法。您可以使用“auto _ activate _ base”condarc 设置关闭基础环境的自动激活。

激活不仅仅是修改路径。它还提供任何 activate.d 脚本,这些脚本可以设置附加的环境变量。有些东西,比如 GDAL,需要这些。没有激活,这些软件包将无法工作。

因此,如果您选择不运行 conda init,我们建议您遵循安装程序末尾的说明,而不是您修改路径的提示:

这看起来像两个命令:

1.eval " $(/home/msarahan/mc3 _ dummy/bin/conda shell . bash hook)"

2.conda 初始化

注意,在步骤 1 中,我将 shell 名称从 YOUR_SHELL_NAME 改为 bash。您可能需要根据您的 shell 自行调整。"

长话短说,修改 PATH 很有可能会给你带来一些问题。更聪明的做法是激活,因为它不是永久的,并且会允许一些原本不能运行的包运行。

因此,在安装程序结束时,不是运行原始解决方案:

*export PATH="/Users/myname/anaconda2/bin:$PATH"*

你想跑吗

*eval "$(/home/msarahan/mc3_dummy/bin/conda shell.bash hook)”
conda init*

(但是要确保将目录位置和 shell 更改为您自己的!)

**** * 更新结束*****

原始解决方案:

你所需要做的就是运行

*export PATH="/Users/myname/anaconda3/bin:$PATH"*

你可以走了!!!

(一定要确保用您的用户名替换“myname ”,并在需要时更改目录的路径。如果你看上面的那一行,*/Users/myname/anaconda3*将被先前安装位置的*/Users/anneb/anaconda3*所取代。其他一切保持不变。)

如果您没有安装 Anaconda3,那么您需要运行

*export PATH="/Users/myname/anaconda2/bin:$PATH"*

对于 Anaconda2 或者

*export PATH="/Users/myname/anaconda/bin:$PATH"*

确保在必要时更改“myname”和目录位置。

现在试试conda list

恭喜你!

你做到了!!!

您已经成功安装了 Anaconda,现在可以从命令行运行它了!

试着打字

*jupyter notebook*

看看会发生什么!

GIF via GIPHY

感谢阅读!如果你想接触或者找到更多很酷的文章,请来内容简约和我一起吧!

想了解创建、运行、发布甚至共享 Jupyter 笔记本的最简单方法吗?

* [## 如何毫不费力地创建、发布甚至共享云托管的 Jupyter 笔记本

完全初学者指南,以闪电般的速度在 Jupyter 笔记本上创建、运行和协作…

towardsdatascience.com](/getting-started-with-saturn-cloud-jupyter-notebooks-b3f509a500ef)

感谢阅读!*

如何成功管理数据科学交付渠道

原文:https://towardsdatascience.com/how-to-successfully-manage-a-data-science-delivery-pipeline-33bdec1a9a27?source=collection_archive---------8-----------------------

数据科学项目:交付还是不交付。

根据 Gartner 的说法,这不是选项,而是 85%的数据和数据科学项目未能交付商业价值或看不到业务适应的令人失望的现实。事实是,在商业环境中成功掌握数据科学是一项复杂的挑战。你可以在我之前的博文中读到关于独特的战略需求和技术需求。这个博客涵盖了拼图的最后一块,即数据科学项目的交付管理。

[## 生产中数据科学的会合体系结构

如何构建一个前沿的数据科学平台来解决数据科学中的真正挑战:生产化。

towardsdatascience.com](/rendezvous-architecture-for-data-science-in-production-79c4d48f12b) [## 如何让您的数据科学团队取得成功?

出于某种原因,让数据科学取得成功真的很难,超过 75%的企业报告称面临业务挑战…

towardsdatascience.com](/how-to-make-a-success-story-of-your-data-science-team-1719129941ba)

当我们审视项目交付管道时,重要的是要记住数据科学(a)仍然是一个新兴的业务功能,以及(b)从持续的创新中不断发展。

构建基础层

许多数据科学家发现自己在运行敏捷软件开发周期的科技公司中,这感觉有点像圆孔中的方钉。数据科学职能与软件开发的不同之处在于该角色所带来的开放式研究的数量,这也是标准敏捷流程与数据科学家的兴趣相冲突的地方。

研究是数据科学的重要组成部分,但不太适合标准的敏捷流程。

任何数据科学团队都需要花费大量时间进行研究,以构建他们的基础层,其中数据科学使不断发展的领域适应业务的特定环境。我们可以将这项基础研究工作分为三类:

长期:由成熟的数据驱动型高科技公司的专业研究团队进行。这不是典型的企业商业数据科学家。

中期:通过调整数据科学中不断发展的关键领域以适应特定的业务环境,构建可扩展的基础。

短期:应用特定的挑战,如解决方案设计、表示层、算法选择以及模型和指标的验证方法。

许多企业通过从相关领域(如 NLP 或计算机视觉)雇用特定的专业知识和人才来快速推进他们的研究积压。无论如何,需要对基础层进行持续投资,以保持资源的相关性,并为数据科学团队提供发展机会。这对于团队激励和保留至关重要。

[OC]

当我们将数据科学的职责分成两个工作流时,很明显哪个部分应该作为敏捷交付管道和项目管理委员会(如吉拉)的一部分,哪个部分与标准敏捷流程相冲突。

一方面,构建基础层和管理这个工作流应该是数据科学家的内部职责。另一方面,我一次又一次地发现这对于团队来说是非常个人化的。通常,这是用于未定义成功标准或截止日期的概念证明的合适工作流。与其顺应这种混乱,不如对这一工作流的资源分配实施透明,围绕协作和知识转移设定期望,并通过博客帖子和社区会议等方式交流这一工作的进展和价值。

转向项目管理需求

在团队坚实的基础上,我们扩展了越来越多的应用程序和业务用例,成为标准交付管道的一部分,具有更严格的项目管理要求:

Adapted Flow Chart originally by Shay Palachy

数据科学项目的交付是科学、产品和工程的团队运动。其协调和优先级的关键是项目交付管理中的价值证明思维,而不是激励团队研究工作的概念证明思维。

范围界定阶段必须从具体的产品需求开始,目标是在产品和数据科学之间就成功项目将解决的范围和指标达成一致。这一阶段是对已建立的产品和科学关系的巨大考验。在成熟的合作中,产品团队尚未解决合适的数据科学项目。构思过程应大量参考数据,以定义现实的项目范围,并应主要由数据科学团队负责。

研究阶段这将未完成的研究限制在短期应用特定的挑战,如最终解决方案设计(包括表示层和 API)、算法选择以及模型和商定指标的合适验证方法。因此,对这一阶段进行时间限制是合适的,但有可能需要重复一个研究阶段。研究阶段的成功完成见证了工程部门的感觉检查,以及对范围和商定指标仍然有效的确认。

这是真正的模型开发开始的时候。数据科学家编写代码,但这与软件工程师的工作方式有很大不同。这个阶段是高度迭代的,在模型开发和模型评估之间有大量的来回,以优化解决方案。这就是数据科学家使用笔记本而不是传统 ide 的原因。这让他们可以快速制作原型。

笔记本电脑非常适合快速原型开发,但是对于可重复性和企业部署来说却很糟糕。数据科学开发环境的成熟度以及工程对访问和处理大量数据的支持至关重要。它不仅影响模型开发过程中的生产力,而且保证解决方案的质量,以避免后续解决方案部署过程中的意外。

您可以在我的另一篇文章中了解更多有关 MLFlow 以及它如何帮助数据科学家开发可用于生产部署的模型的信息:

[## 用 Mlflow 为非傻瓜完成数据科学项目模板。

数据科学项目最佳实践,适用于在本地或云中工作的每个人,从刚起步的忍者到大…

towardsdatascience.com](/complete-data-science-project-template-with-mlflow-for-non-dummies-d082165559eb)

模型的部署本身就是一个具有挑战性的话题。通常,模型数据科学家在前一阶段开发的模型数据需要大量的工作来将其转化为可以在现有堆栈上部署的企业解决方案。这包括日志记录、监控、审计、身份验证、SLA 等要求。

为每个模型解决部署问题根本无法扩展。此外,一个大问号仍然存在。谁拥有生产中已部署模型的操作职责?模型因其在生产中复杂的生命周期管理需求而独一无二。因此,关注平台化数据科学很重要,你可以在我之前关于机器学习物流和 Rendezvous 架构的文章中了解更多。

这个故事已经作为甲骨文的 AI 影响者博客系列的一部分重新发布:

https://blogs.oracle.com/ai-and-datascience/post/ai-influencer-blog-series---how-to-successfully-manage-a-data-science-delivery-pipeline

Jan 是公司数据转型方面的成功思想领袖和顾问,拥有将数据科学大规模应用于商业生产的记录。他最近被 dataIQ 评为英国 100 位最具影响力的数据和分析从业者之一。

在领英上连接:https://www.linkedin.com/in/janteichmann/

阅读其他文章:https://medium.com/@jan.teichmann

如何增强你的熊猫工作流程

原文:https://towardsdatascience.com/how-to-supercharge-your-pandas-workflows-ae642b03ba52?source=collection_archive---------16-----------------------

Photo by Bill Jelen on Unsplash

当我处理结构化数据时,Pandas 是我的首选工具。我认为这并不奇怪,因为 Pandas 是最流行的用于数据操作、探索和分析的 Python 库。它提供了很多现成的功能。此外,还存在各种其他模块来进一步增强和扩展 Pandas 核心。在这篇文章中,我想和你分享我用来增强我的熊猫工作流程的工具和技术。

增压步骤

准备

为了跟随例子,你需要 Python 3.7+和熊猫、 funcy 和 seaborn 。你可以在我的GitHub repo上找到所有的例子。

一如既往,我推荐使用poem来管理您的 Python 包和环境。你可以查看这篇文章了解如何设置它。作为一种快捷方式,我建议使用 pip 或 pipx 将其安装在您的机器上。

现在,让我们快速创建一个名为 awesome-pandas 的诗歌项目,在这里我们实现示例并添加必要的包

poetry new awesome-pandas
cd awesome-pandas
poetry add pandas seaborn funcy

现在我们有了一个独立的 Python 环境,安装了我们需要启动的所有东西。太好了,我们可以开始增压我们的熊猫工作流程了!

探索性数据分析

不管你有什么样的数据集,你首先要做的可能是对其中发生的事情有一个想法和理解。这个过程被称为探索性数据分析,EDA。

数据集中有多少要素和样本?那些特征是什么?它们有哪些数据类型?是否有任何缺失值?它们是如何分布的?有什么关联吗?这些只是人们在查看新数据集时通常会遇到的许多问题中的一部分。

对于熊猫来说,获取这些信息的通常嫌疑人是函数 headinfodescriptioncorr、等等。因此,对于您的 EDA,您可以从一个接一个地调用这些函数开始。接下来,您可以从控制台或 Jupyter 笔记本上读取结果,并将结果关联起来。这个过程对我来说听起来很乏味。此外,它不包括任何可以很容易解释的视觉效果。创建它们需要额外的步骤和代码。以结构化和整合的方式获取所有这些信息不是很好吗?理想情况下只调用一个函数?

这里是熊猫的光辉之地!

Pandas-profiling是一个扩展 Pandas DataFrame API 的库。它将常见的第一个 EDA 步骤合并到一个函数调用中。这些包括 数据类型、 缺失值、相关性、分位数和描述性统计以及直方图 等。所有这些信息被组合成一个单一的输出。您可以通过一个配置文件 来配置 分析什么以及结果如何呈现。听起来很棒,不是吗?让我们简单看一下。

首先,我认为将它添加到我们的示例环境中是有意义的

poetry add pandas-profling

现在,您所要做的就是导入 pandas-profiling 并在 DataFrame 对象上调用 profile_report。如果你用的是 Jupyter Notebook,这个足以看到输出。当使用 IDE 或编辑器时,您必须将报告保存为 HTML 文件,并在浏览器中打开它。我不是一个笔记本电脑爱好者,所以我必须做更多的工作

这就是为什么我想出了下面的函数。它使我能够检查只调用单个函数的报告,就像 Jupyter 人一样。

现在,我们拥有和 Jupyter 人几乎一样的舒适。

但是,我希望一样舒适,并使用一个 专用数据框架 API 来创建和打开我的报告。

扩展熊猫 API

Pandas 已经提供了一套丰富的现成方法。但是,您可能希望根据需要扩展和自定义索引、系列或数据框架对象。幸运的是,从 0.23 版本开始,Pandas 允许你通过自定义的 访问器 来实现。如果你想在 Pandas < 0.23 中添加一个自定义的访问器,你可以使用 Pandas-flavor 。

编写自定义访问器相当简单。让我们用上一节中的例子来看看它;在浏览器中为数据帧创建并打开 pandas-profiling 报告。

我们从一个 Python 类报告开始,我们必须用@pandas.api.extensions.register_dataframe_accessor("report")来修饰它。class' __init__'方法必须将 DataFrame 作为其唯一的参数。您将该对象存储在一个实例变量中,并使用它来应用您自定义方法。自定义方法是您的类的实例方法。

作为一个例子,我们将一个方法 show_in_browser 添加到类报告中。我们可以通过df.report.show_in_browser()在数据帧 df 上调用它,为此,我们只需导入包含类报告的模块。

您可以使用传递给装饰器的名称来访问您的自定义方法。举个例子,如果我们用“ wicked ”交换“ report ”,而不改变其他任何东西,我们必须调用df.wicked.show_in_browser()在浏览器中打开我们的报表。

说够了,下面是代码,它给我们带来了和 Jupyter 人一样的舒适

注意,我通过添加__call__使类 a 成为可调用的。为什么这很有用?因为现在你可以调用df.report()来执行一个函数,就是在这里获取报告。如果你只想给你的对象添加一个函数,并且不想调用df.report.report().之类的函数,这就非常方便了

关于自定义访问器的最后一件有用的事情是,ide 可以识别它们并启用自动完成功能。这增强了整体开发体验。

现在我们知道了我们的数据是什么样子,以及如何扩展 Pandas 对象。所以,让我们继续有趣的事情,看看如何改善处理体验。

跟踪应用调用的进度

假设您想对数据帧应用一个函数。根据数据帧的大小或函数的复杂程度,执行df.apply(func)可能需要很长时间。所以你可能会坐在电脑前等待它结束。不幸的是,你没有得到任何反馈,不知道你要等多久,也不知道它到底有没有用。你可能只听到一个响亮的风扇和你的电脑正在升温。如果你像我一样,你会在那一点上变得紧张和不耐烦。得到有事情发生的反馈不是更好吗?或者更好的是,得到一个关于事情完成需要多长时间的预测?

Tqdm 是你的朋友!

Tqdm 是一个 Python 模块,它让你用很少的代码和很小的执行开销就能给你的循环添加智能进度条。除此之外,它还提供了剩余执行时间的预测。而且,对本文来说最重要的是,它附带了一个熊猫集成。让我们看看那是什么样子。

和往常一样,我们首先将模块添加到我们的示例环境中

poetry add tqdm

现在你要做的就是导入 tqdm 和调用 tqdm.pandas 向熊猫注册。现在您可以在 DataFrame 对象上调用 progress_apply 而不是 apply 。下面是使用一些无意义的示例数据的完整代码

在我的电脑上,产生的进度条看起来像

Hello Medium: 42%|████▏ | 4177/10000 [00:01<00:02, 2232.11it/s]

你现在知道你在这个过程中的位置,并且估计你还剩多少时间来喝完你的咖啡。

增加申请电话

在上一节中,我们已经看到了如何获得关于执行长时间运行的应用函数的反馈。这让我们可以在继续工作之前估计我们可以喝多少咖啡。然而,有些人说你不应该喝太多咖啡,因为它不健康。因为我们都想保持健康,所以减少等待时间,从而减少我们喝咖啡的数量是一件好事。即使你不喝咖啡,更少的等待时间意味着更多的生产时间。我们都想拥有它。

Swifter 提升您的数据框架应用调用。

更快使更容易最快 可用 方式将任何功能应用到您的熊猫系列或数据帧。它首先尝试以矢量化的方式运行函数。如果失败,swifter 会决定是执行 Dask 并行处理更快还是使用标准 Pandas apply 更快。所有这些都是通过一个函数调用自动完成的。这是一个很好的抽象层次!

让我们快速看一下代码。首先,我们将 swifter 添加到我们的示例环境中(我想这会变得很无聊,但我想保持这种结构)

poetry add swifter

我们现在只需要导入得更快,并且可以在我们的数据帧或系列对象上调用df.swifter.apply(func)。搞定了。Swifter 还带有 tqdm 进度条实现。要调用它,您需要调用df.swifter.progressbar(True,”Hello Medium").apply(func) Sweat!

当你看到你必须做什么来使用 swifter 时,你能猜出它是如何注册到熊猫对象的吗?如果你的答案是“它使用熊猫扩展 API”,那你就对了。哦,这一切是如此完美地结合在一起:)

最后,让我们比较一下 swifter apply 和 Pandas apply 对上述虚拟数据的执行时间

df = pd.DataFrame(np.random.rand(10000, 10))
%timeit df.swifter.apply(lambda s:s**1/2, axis=1)
**29.1 ms** ± 118 µs per loop
%timeit df.apply(lambda s:s**1/2, axis=1)
**2.96 s** ± 6.39 ms per loop

使用 swifter 的 29.1 毫秒比使用正常应用的 2.96 秒少得多。具体来说,大约快 100 倍。

我相信您也可以手动实现这种性能,但 swifter 可以为您实现。

包裹

在这篇文章中,我向你展示了如何增压你的熊猫工作流程和经验。总之,对你来说最重要的三点是

  • 使用 pandas-profiling 对 pandas 数据帧执行 EDA。
  • 利用 Pandas 扩展 API 根据您的需要定制 Pandas 对象。
  • 使用 tqdm 和 swifter 来增强和加速对熊猫对象应用函数。

感谢您关注这篇文章。一如既往,如有任何问题、意见或建议,请随时联系我。

如何采用数据驱动的方法进行 SEO

原文:https://towardsdatascience.com/how-to-take-a-data-driven-approach-to-seo-315c35e9cd7f?source=collection_archive---------17-----------------------

什么是数据驱动的 SEO?

“数据驱动”一词在大多数市场营销学科中都很常见,它指的是用于战略制定的定量和定性数据的积累和分析。因此,数据驱动的 SEO 意味着在制定 SEO 策略时将数据作为主要组成部分。

对许多人来说,网络分析和搜索引擎优化数据似乎很神秘。的确,有时感觉就像是在读一门外语。然而,如果你花时间收集可用的信息,看看它,并弄清楚这一切意味着什么,你可以找到机会,导致相关和有利可图的搜索流量。

关键词研究

SEO 中使用数据的最常见方式之一是生成关键字,并确定哪些关键字最有效。如果你花时间来选择合适的关键词,最好是选择那些与你的潜在在线客户正在搜索的关键词相一致的关键词。为此,您需要对与您的产品或服务相关的搜索查询进行深入分析,并分析潜在客户的浏览趋势和行为。

我知道寻找搜索量最高的关键词很有诱惑力,但如果你在与一个全新或年轻的网站合作,在这些查询的搜索结果中与老牌公司竞争会很有挑战性。所以,寻找你的竞争对手没有强大存在的关键词。一旦你的目标关键字开始排名,继续下去,直到你得到它的顶端。如果你在一个页面上同时定位了太多的关键词,你很可能会分散你的注意力,并且不能让你最有针对性的关键词排名靠前。记住:选择关键词的秘密是找到那些搜索量高、竞争少的关键词。

监控用户行为

SEO 社区中正在进行的一场辩论是关于用户行为指标和排名之间的相关性。可以理解的是,谷歌代表否认、确认、再否认两者之间有任何关联。然而,如果谷歌的目标是为其用户提供出色的体验,那么行为指标必须予以考虑。SparkToro 的创始人 rand Fishkin(Moz 的联合创始人)对搜索结果中的用户行为指标和排名进行了测试,发现它们高度相关。根据他的结果,用户行为指标显然是一个重要的排名因素。

不管行为和排名之间是否有联系,了解搜索引擎如何评估用户行为仍然很重要。以下是搜索引擎可能用来理解用户的一些信号:

  • 点击率
  • 点击其他搜索结果
  • 新一代搜索引擎
  • 跳出率
  • 保压时间
  • 现场时间
  • 每次访问页数
  • 重复访问
  • 这样的例子不胜枚举…

这里有一些方法,你可以用来改善和衡量你的搜索结果的用户行为:

点击率

“点进”是用户点击来自搜索引擎结果页面(SERP)的结果并被发送到另一个页面的动作。因此,点击率是一个结果从投放的印象数中获得的点击数的度量。如果你的页面在搜索结果中出现 100 次,并被点击 12 次,那么你的点击率是 12%。

您可以使用谷歌搜索控制台查看您的点击率和特定搜索查询的排名,这是一个适用于所有网站的免费工具。你可以将你的点击率和你的页面在目标关键词上的排名进行比较。如果你的点击率低于平均水平,那么这可能是你需要重点提高的地方。

你可以通过使用高级网页排名的谷歌有机点击率历史来查看你的行业点击率平均排名。重要的是要知道,不同类型的搜索查询会有不同的点击率(品牌与非品牌、信息、特定位置、长尾查询等)。).我更喜欢使用 Ahrefs 关键词浏览器来获取特定搜索查询的关键词点击量数据。

那么,如何提高自己的 CTR 呢?很简单:只需调整用户在 SERPs 中看到的元素(页面标题、URL 和元描述)。

虽然我不会在本文中讨论优化这些元素的最佳实践,但是您可以了解更多关于如何优化标题标签的信息,以及如何在 Portent 的博客上改进元描述。

停留时间和弹簧粘连

停留时间,也称为页面上的时间,衡量用户在给定页面上花费的时间。增加用户在页面上的时间可能会向搜索引擎发送信号,表明该页面质量良好。然而,如果你的有机流量有很高的跳出率,那么你的用户可能是 pogo-sticking。

Pogo-sticking 是一种典型的行为,表明满足用户搜索查询的结果较差。例如,当用户从 SERP 访问您的页面时,如果用户很快返回到搜索结果,然后点击另一个结果,这就是 pogo-sticking。在搜索查询中排名最高的页面会立即包含用户正在寻找的所有信息,这样用户就不会返回到搜索结果中寻找替代信息。

要确定这是否是您的目标页面的问题,请使用您网站的分析来查看有机流量跳出率(仅访问一个页面并离开的访问者的百分比)和网页的平均会话持续时间(停留时间)。正如已经提到的,用户意图和关键字将为可接受的跳出率和停留时间创建不同的结果。这里有一些行业跳出率基准来帮助你开始弄清楚什么是你的网站可以接受的。也有很多很棒的资源提供关于如何降低网页跳出率的提示和最佳实践。

选择正确的工具和资源

如果你想要一个精确的数据驱动的 SEO 策略,拥有合适的工具是必不可少的。令人惊讶的是,大多数 SEO 专业人士缺乏获得准确数据的途径,因此他们不得不做出假设。因此,搜索引擎优化预测并不总是正确的。数据驱动的方法利用准确性和精确性在搜索结果中领先于竞争对手。

在选择帮助您收集数据的工具时,需要考虑两个要点,一是您要分析哪些数据,二是哪些数据有助于提高策略的清晰度。数据驱动方法的目标是收集信息,以便改进您的计划。尽管很诱人,但不要在你已经成功的领域加倍下注。持批评态度,想办法填补你的策略中的漏洞,并在整个 SEO 领域创造更多的可见性。

最后,利用你所有的资源。也许你的公司已经投资了点击付费广告。如果是这样的话,与负责这些广告的人谈谈,因为他们的数据将能够提供有价值的信息,如哪些关键词转换了,哪些登录页面的跳出率低,等等。

结论

有大量的数据和资源可以帮助你提高搜索引擎优化。再次,坐下来,看看你可以得到的数据,并弄清楚这一切意味着什么。然后你会发现机会,可能会导致相关和有利可图的搜索流量。

感谢阅读!如果你有任何问题,或者你需要一些帮助来开始你的搜索引擎优化策略,请联系我。

如何使用转换预测模型确定促销目标,以最大化净增量收入?

原文:https://towardsdatascience.com/how-to-target-promotions-with-conversion-prediction-model-to-maximize-net-incremental-revenue-f51dabdb6320?source=collection_archive---------17-----------------------

Identifying the right set of customers to be targeted for the promotion is the key for a successful campaign Image Source

每当一家公司选择通过提供折扣或开展数字广告活动等策略来推广某种产品时,都会有一定的成本以及一些与之相关的潜在创收机会。如果公司不小心选择合适的客户群来接受促销,最终可能会损失很多钱,却没有获得多少回报。

如何量化促销活动的净回报?

让我们假设该公司有权向一组人推销其产品。他们可以被视为现有客户,或者只是通过社交媒体、搜索引擎广告、电子邮件或其他一些沟通机制可以接触到的受众。

假设该公司进行了一项实验,从这些人中随机抽取一小部分样本,从中得出统计结论。

它进一步将这个样本分成大小大致相等的两组。哪个人被分配到哪个组也是随机的。

对于其中一组,公司选择发送促销信息,为简单起见,我们假设所有人都收到了促销信息。我们称这个组为治疗组。例如,公司选择向该组中的所有成员发送折扣券,每个人都会收到并看到它。

让我们考虑一个人获得晋升的相关成本。例如社交媒体平台收取的每次点击成本。

考虑在接受促销后选择购买产品的人数。

公司从接受促销的人购买的产品中获得收入。

第二组是公司不向其发送促销的组。我们称这个组为控制组。

在这个对照组中,会有一些人没有收到促销,但他们仍然购买了产品。

公司从没有得到促销的人购买产品中获得收入。

假设公司在一段时间内进行了这个实验,在这段时间结束时,它得到了这些数据。然后它可以像这样计算促销活动的回报。

增量响应率(IRR) 量化接受促销后人们的响应或购买率的变化量。

净增量收入(NIR) 量化公司在开展促销活动后获得的净收入的变化,同时考虑与之相关的成本。

我相信上面的两个公式直观上是有意义的,它们很好地抓住了促销活动的效果。

公司的目标是最大化 IIR 和 NIR 这两个参数。

对于不同类型的公司或场景,IRR 可以捕捉来自个人的任何积极行为作为响应,如签约或购买等。

对于一个产品销售公司来说,NIR 反映了促销活动在直接金钱收益方面的有形结果。

想象一个场景,在接受促销后选择购买产品的人数大致等于(或可能少于)没有接受促销但仍然购买产品的人数。在这种情况下,如果治疗组和对照组的人均收入相同,则该活动的净增量收入为负。这意味着该公司通过开展促销活动造成了金钱损失!

公司如何最大化 IIR 和 NIR?

如果我们假设向一个人发送促销的成本和从接受促销的人的购买中产生的收入都是常数,那么我们留下来调整的唯一两个参数是接受促销的最小人数和接受促销后选择积极响应(例如购买)的最大人数。

公司应该只向那些在获得晋升后极有可能做出积极回应的个人发送晋升。

公司如何决定向谁发送促销信息?

根据通过实验收集的数据,该公司可以将其潜在购买者组成的可接触受众分为两类:在接受促销后购买的人和其他人。

请注意,其余的人将包括那些不值得被提升的人。其中包括:

  1. 那些购买了产品却没有得到促销的人。这一点很重要,因为发送促销信息是有成本的,公司不希望把这笔钱花在那些可能已经购买了产品的人身上。
  2. 接受促销但没有购买的人。这些人是公司花钱进行促销的对象,但他们选择不购买产品。这些人可能会因为某种原因(可能是隐私问题)在看到公司针对他们的促销活动后感到恼火,并有意识地选择不购买。
  3. 没有收到促销且没有购买产品的人。该公司从实验中获得的数据很少,无法判断是否向他们发送促销信息。保守的做法是不给这样的人升职。

这个问题转化为决定哪个人属于哪个类别。应用基于机器学习的统计模型可以有所帮助。如果公司有一些与潜在受众相关的个人数据,如人口统计、年龄、性别、地点、购买历史、财务状况、婚姻状况、教育、就业背景、兴趣等。然后,它可以使用它来识别这些人中的哪些子集在接受促销后更有可能购买该产品。

让我们看一个例子

为了进一步解释这种技术,我将举一个由 Starbucks 提供的样本数据集的例子。

你可以在这个笔记本这里找到我这个项目的代码,这个项目是在 GitHub 上可用。

Happy Hour, Starbucks’ invite only promotion Image Source

它曾经向数据科学家候选人提供该数据集。它包含 120,000 行,其中有 7 个名为 V1 到 V7 的数字变量,这些变量与他们实验中的每个人有关。它有两个额外的变量,表明这个人是否得到了促销和她是否购买了产品。

在星巴克的例子中,从接受和未接受促销的两类顾客那里,每次购买的收入是 10 美元。向一个人发送促销信息的成本是 0.15 美元。因此,在这种情况下,用于 NIR 的公式可以转换成如下形式:

为了评估我们的预测模型的性能,有必要将来自实验结果的可用数据集分成训练和测试数据集。测试数据集不得以任何形式用于训练模型。它必须仅在训练结束时用于对照一些预定参数评估模型,在我们的情况下是 IIR 和 NIR。如果我们想在训练阶段评估我们的预测模型,我们可以将训练数据集进一步分成两部分:训练数据集和验证数据集。该模型可以用训练数据集上的一些超参数来训练,并在验证数据集上进行评估,以选择超参数的最佳值。

有几种方法可以将该数据集用于训练基于机器学习的统计模型。我将讨论一些使用该数据集获得良好结果的方法。

第一种方法

由于公司只对那些只有在收到促销后才会购买产品的人感兴趣,我们可以定义一个名为Response的新的二进制变量,如果这个人同时有两个变量,即表示她是否收到促销的Promotion和表示她是否购买了产品的Purchase,则该变量将被设置为True。对于拥有其余PromotionPurchase变量值组合的人,分配给Response的值将为False。在用这个新的目标变量丰富数据集之后,像正则化梯度推进(XGBoost) 这样的机器学习模型可以用于通过将变量 V1 到 V7 视为输入变量并且将Response视为输出变量来训练数据集。

检查和处理数据集中的不平衡

在定义了这个新的Response变量之后,我决定检查分配给它的值是否不平衡。因为这通常是市场营销活动的情况,在这些接受促销的人中只有一小部分人选择按照它行动。在该数据集中,分配给TrueFalse的人数与目标变量Response的值之间的比率约为 1:116。这表明数据集中存在巨大的不平衡。

如果我们选择忽略这种不平衡,并继续在这个数据集上训练一个机器学习模型,它可以实现 0.99/1 的精度,只需在测试中收到的所有情况下,将Response变量的输出给False。得出该模型在准确性方面表现很好的结论可能会产生误导。具体来说,这种模型根本无法识别公司应该向哪些人发送促销信息。

有几种方法可以处理不平衡数据集

  1. 通过包含新的合成生成的数据点,对输出变量等于少数类的数据进行过采样(例如,使用 SMOTE 技术
  2. 通过在采样期间替换,用等于少数类的输出变量对数据进行过采样。在这种情况下,属于少数类的数据点附近的决策边界可能不能很好地概括。
  3. 对输出变量等于多数类的数据进行下采样。在这种情况下,我们删除了一些可以用来训练模型的数据。
  4. 使用机器学习模型中可用的类别加权机制,根据目标变量的值为训练样本分配不同的权重

对于这个数据集,我决定使用合成少数民族过采样技术,通过在分配给少数民族类的现有数据点之间引入新的数据点来实现数据集的平衡,输入变量值会有一些变化。

对于这个数据集,我决定在这个数据集上训练正则化梯度增强模型(XGBoost) 来预测一个人的Response变量,其属性被指定为V1 to V7作为输入变量。

XGBoost 有大量的超参数,需要基于交叉验证进行设置。我决定调整一些重要的值,并选择用那些在交叉验证测试中表现最好的值来训练模型。

该模型在验证集上获得的 F1 分数约为 0.028311,这被认为是相当低的。然而,我们必须记住,在我们的问题中,真正的评估指标是 IIR 和 NIR。

我继续使用 XGBoost 模型对最佳参数进行训练,并使用它对测试数据集进行预测,以决定给定的人是否是在接受公司促销后会购买的人。如果是,那么它将推荐发送促销给那个人。

在测试数据集上,该模型的 IIR = 0.0206,NIR = 259.25。

星巴克在数据集描述中提到,他们的团队实现了 IIR = 0.0188 和 NIR = 189.45

从我们的预测模型获得的结果表明,这种方法可以是解决这种类型问题的非常有效的方式,其中公司需要决策支持系统来决定向谁发送促销。

方法 2

另一种方法是对每个人进行评估,与未接受促销相比,接受促销的人进行购买的增量概率是多少。如果给定人员的递增概率足够高,我们的算法将推荐向该人员发送促销。

Formula for calculating Incremental Probability (IP)

为了实现这种方法,我们需要添加Promotion,作为该人是否获得晋升的指示变量,作为除我们拥有的每个人的个人数据之外的输入变量。目标输出变量将指示该人是否采取了期望的行动。

在我们的 Starbucks 数据集的例子中,我们将使用变量V1 to V7Promotion作为输入变量,使用Purchase作为目标输出变量。

下面是在这种方法中如何决定是否发送促销信息。我们首先通过将Promotion输入变量分别设置为真或假,并计算两个概率之间的差异,来计算得到促销和没有得到促销的人进行购买的概率。如果差异大于某个阈值,那么我们可以向该人发送促销信息。可以使用超参数优化技术来确定阈值,同时使用 NIR 公式来计算要最小化的目标函数的返回值,即分数可以是-NIR。

数据集的Purchase变量值在TrueFalse值之间的比率约为 1:80。这表明数据集中高度不平衡。我使用 SMOTE 技术对少数类进行过采样,以使两个类在训练数据集中的比例相等。

在这里,我使用对数损失作为评估指标,同时调整估计数作为 XGBoost 的超参数,因为我更感兴趣的是计算给出特定响应的人的准确概率,而不仅仅是预测响应类别。根据这个概率,我可以计算出人们在接受促销后购买某种产品的增量概率。

具有最佳超参数的经训练的 XGBoost 模型在验证数据集上获得 0.07 的对数损失分数。就对数损失而言,它越小,模型的预测性能就越好。

我使用这个模型对测试数据集提出建议,并计算出 IIR = 0.018826,NIR = 98.30。将其与星巴克声称其团队实现的 IIR = 0.0188 和 NIR = 189.45 进行比较,我们可以说该模型显示出不错的性能,但不如方法 1 或星巴克声称实现的效果好。然而,在不同的问题场景中,它可以被认为是一个值得考虑的选项。

可以尝试的方法 3

在与促销相关的文献中提出了一种基于两种模型的方法。在这种方法中,我们训练了两个独立的Purchase预测模型:一个针对获得晋升的人,另一个针对没有获得晋升的人。然后,我们计算每个人在有促销和没有促销的情况下进行购买的概率差异。如果差异足够大,我们可以选择向那个人发送促销信息。然而,一些人对这种方法提出的警告是,它训练两个独立的模型,每个模型都可以在输出中生成自己的概率范围,并且正确预测增量概率的误差会加倍,因为我们使用了两个预测模型。我将这种方法留给感兴趣的读者(或我自己)在将来的某个时候在这个数据集上进行尝试。

我希望你觉得这篇文章很有见地。

你可以在这里的这个笔记本里找到我这个项目的代码,带有星巴克数据集的项目在 GitHub 上有。

如何教代码

原文:https://towardsdatascience.com/how-to-teach-code-a4d8ee29e14e?source=collection_archive---------9-----------------------

程序设计教学中的问题及解决方法指南

学习编码真的很难,教编码更难。《如何教代码》里没有训练营。大多数教师没有受过任何正规的教育培训,都是软件出身。

我很高兴以不同的方式与几个训练营合作(作为学生、老师或经验伙伴)。我还:

  • 运行代码 Meetup 俱乐部教学代码
  • 发布了一系列黑客马拉松
  • 帮助开展各种学习代码活动。

问题

令人惊讶的是,教学规范中的规定如此之少。结果是学生可以获得完全不同的体验。我见过这个星球上一些最好的教育被免费赠送。然而,我也见过其他训练营给他们的学生提供 3 个月的困惑,并收取 9000 英镑的乐趣。

我看到训练营挣扎着前进,直到他们不可避免地失败,而其他人只是继续成长。拿钱让学生接受糟糕的教育是错误的,但我也不认为任何人只是想偷别人的东西。

随着当前大量潜在的工作被软件所取代,越来越多的学生希望转而从事技术工作。

像《T2》和《T3》惨败这样的故事只是一个大问题的表面。与其只是谈论问题有多大,不如采取措施解决它。

解决方法

以下是我自己了解到的关于教代码的困难。如何以给学生最佳体验的方式教授代码?以及如何通过提供出色的体验来发展可持续的业务。

(注意——作为一名新兵训练营的学生,这本书值得一读。如果你的课程犯了这些错误,你可以通过鼓励一些更好的实践来挽救你的教育。)

第 1 部分——为什么学习代码很难

学习说电脑很难。由于我们思考、感知和学习事物的方式普遍不同;有些人觉得这简单得令人沮丧,有些人觉得这不可能。对于一般人来说,这真的很难。然而,这是完全可行的…

学习你的第二种和第三种计算机语言相对来说比较容易,而且你知道的越多只会越容易。

你不知道你不知道的事情

教 it 的问题是,你得懂很多会说话的电脑,才有资格教别人会说话的电脑。然而对你来说,学习一门新的计算机语言现在很容易。很难理解 10 年前你所面临的困难。对你来说,它只是将一组新的语法分配到现成的概念中。

The most logical analogy is learning a new human language.

人类的第一种口语是最难学的,因为你以前从未学过一种语言。有特权的学生被教授拉丁语,以理解语言是如何建立的根源。有了这些核心知识,他们可以很快理解世界各地使用的新的现代语言。类似地,计算机科学家通常学习 C,这样他们可以理解他们遇到的大多数语言的根源,即使他们并不期望真正使用它。

在学校学语言是有好处的。多年来,你慢慢积累了一堆语法,最终让你能够理解和说大多数事情,但这需要沉浸才能真正了解上下文并掌握它。

浸没

或者,你可以去一个外国,通过上课和不断的沉浸,你会在 3 个月内学到更多。但这仍然是一个令人困惑和具有挑战性的经历,你没有资格在复杂的商业环境中从事高级工作,但你可以在咖啡店工作得很好。

与说计算机相比,你已经知道你的母语,这是你的零语言,它给你一堆模板概念来参考。

寻找参考点

人不会说计算机,第一次学没有任何参照系的语言零。

你可以每周练习说几个小时的电脑来学习语法,但你需要几年才能精通。如果你一周花很多时间学习,你可能要花一年的时间才会感到舒服。或者你甚至可以做一个 3 个月的完全沉浸式训练营。

然而,你仍然不是一个大师,你说的(写的)很多东西会显得有点迟钝,其他人对你说的很多东西可能会超出你的理解,但在你自己的时间里,你可以查阅并从那里建立。

你没有资格要求一份高层次的工作,但是初级的工作是完美的。

结论

总之,学习一个全新的东西并不容易,向初学者教授你所熟知的东西有很多挑战需要你注意。

这是教一个人他们的第一门编程语言的困难的宽泛概念。这篇博客的其余部分回答了“如何教授代码”的原始问题

第二部分——说教什么也没教,化繁为简

常见错误

老师通常喜欢向学生展示他们需要知道的关于一个概念的一切,这样他们就可以开始并成为专家。这可能是一个小时的讲座。计算机科学家(学习 C 语言后)可以处理这个问题。代码新手不行。

在开始 5 分钟的讲课后,你说的任何其他东西都是没有意义的,他们听不懂。停止说话,做一些他们能跟上的练习。

(如果你是通过视频学习,5 分钟后停下来做练习)。

锻炼需要在正确的时间以正确的水平进行。对于一群以不同速度和不同风格学习的学生来说,这不是一件容易的事情。当我稍后讨论这个问题时,需要掌握理解什么是合适的。

让我们停下来做另一个类比。

学习骑自行车

Imagine you are teaching students to ride a bike.

第一讲。你将深入了解自行车平衡的工作原理,以及如何转移身体重量,以在踏板上施加正确的力来提供动力。这是核心的东西,非常重要。

停下来喝杯咖啡休息一下,你会很好地安排一天。

第二讲。你谈论转向和如何倾斜入弯。并没有预期的那么久。你很兴奋,所以你解释了当你正确理解了上面的过程时,不用手骑并不困难。一个学生,吉米,说他以前骑过一次自行车,说没有手真的很难。你很聪明地纠正他说,这需要对物理有正确的理解,很明显他的上一个老师没有教好他。

哇,真有趣。午休时间——是的,午餐时间到了!。你告诉一些学生你在阿尔卑斯山骑自行车的经历,以及它有多美,但也提醒他们你每天是如何骑车上班的,即使是在下雨的时候,骑自行车并不好玩,你告诉他们骑自行车的高潮和低谷是件好事。(你要确保吉米在听。真是个混蛋。)

下午——让我们把它们放在一起!

你跳上一辆自行车,在教室里骑一会儿,这样学生们就可以看到它在现实世界中是如何工作的。你过分强调自己的动作,几乎摔倒,向他们展示如何慢慢地倾斜入弯,以便他们能正确地看到。这一切一定会在他们的脑海中完美地融合在一起。妈的,他们现在一定对骑自行车了如指掌。

你真是个好老师,他们会成为有史以来最好的摩托车手。

推迟其他计划

你已经有了如何解释换挡、安全驾驶、修补轮胎的计划,但现在是时候尝试一下了。你检查了你的自行车金属清单,是的,你真的教会了他们核心基础知识,涵盖了你实际骑自行车所需的一切。

其他东西是额外的绒毛,你有时间扔在没有手的概念,任何人都很快得到它。(真聪明,去你的吧!)

大事件

你应该给每个学生一辆自行车。

第一个学生像弱智一样直挺挺地倒在地板上。另外两人试图帮助他,但现在另一名学生试图骑上他们的自行车,她掉进了他们造成了混乱。啊呀,他们真蠢。这些人将会是慢性子,你记下花额外的时间和他们在一起,然后走过去帮忙。

当你问他们有什么问题时,你解开他们的自行车,并试图隐藏你对他们有多愚蠢的困惑。你被一声大叫分散了注意力,抬头一看,到处都是混乱。这是怎么回事?他们为什么不明白。接下来你知道你疯狂地跑来跑去,试图帮助每个学生骑上一辆该死的自行车,但他们似乎都不明白如何保持平衡的基本概念。这是第一堂课的开始,他们一定明白他们都在听!

很快,一个学生哭了,两个受伤了,另一个走出门外,声称他们再也不能骑自行车了。聪明的屁股吉米聪明的裤子,聪明的想法,聪明的傻逼向你走来。他问你为什么不给他们该死的稳定器。

这真的很尴尬。

学习代码

理论上的死亡

简单来说,编码就是知道一些语法和何时使用它的上下文。事实上就是这样。事实上,如果你能在适当的时候查找,你甚至不需要知道语法。

但是就像学习骑自行车一样,如果不做任何编码,这个理论在很大程度上是没有意义的。交谈 5 分钟后,其他任何事情都被浪费了。学生对你实际上在说什么没有真正的概念,然而,你扔给他们很多上下文和语法,仍然没有帮助。

人们在实践中学习。

学生们可能看起来像是在跟着做,但如果他们不做什么,他们的思维就会经常偏离任何抽象的理论,即使他们试图集中注意力,即使已经过了 6 分钟。

甚至不要费心向他们展示用例的超级简单版本,只要和他们一起做就行了。

一起构成这个概念/方法/功能的最简单的核心例子,没有任何其他东西模糊它。只是它的语法。然后让他们用不同的变量重新构建。

根据不同的概念,给出一个稍微复杂一点的版本,或者进入使用它的上下文。然后让我们提供一些练习给他们做。

继续构建肤色的层次,随着你的深入,在更长时间的独立练习中有更大的停顿。

到下午的时候,他们已经准备好在一个项目中或者在解决更难的算法时使用这些想法。别再教他们废话了。只是在不同的事情出错时在那里指导他们,让他们自学,真正探索他们可以用早上你教他们的东西做什么。

简单可能比复杂更难:你必须努力让你的思维变得清晰,让它变得简单。但最终还是值得的,因为一旦你到了那里,你就可以移山倒海了。

史蒂夫·乔布斯

第 3 部分——将上下文和语法结合起来的好练习

练习食谱

就建筑练习的诀窍而言,从** 语法开始**

完全的新手

给他们少量的语法。让他们使用它。

如果这是学习一门语言的第一天,那么你可能要教更多的语法,并让他们使用这些语法。

在他们学会一些东西后,他们可以把这些不同的语法放在一起,让他们互动,并开始理解他们所学内容的上下文

深潜

如果这是学习一个框架的几个星期,那么他们可能首先需要一些背景。但是要简短。

用于涵盖一个概念的代码可能位于多个文件的不同位置,并且可能没有直观的第一位置来教授语法。尝试从第一个逻辑用户操作开始。不要向他们展示用户操作的完整路径,只需向他们展示你编写的第一段代码的语法。

然后在上下文中添加它做什么以及它可能与哪些其他文件或函数交互。浏览与第一个文件/函数交互的语法。

用第一个功能构建所有交互的完整上下文。然后沿着第二个函数的路径,第三个函数的路径等等,直到你完成这个循环。

确保在第一次演示中,你已经把逻辑循环做得尽可能的小和干净,并且最好在结束时有一些事情发生。如果这真的是一个很长的循环,那么在完成整个事情之前,休息一下做一些练习。

Avoid navigating too many files to introduce a concept

注意事项

评论

随着学习的进行,在每个函数/方法上添加注释也很方便,这样学生们就有了一个他们自己构建的注释良好的演示文件来参考。当然,这也让他们进入良好的实践等等…

控制台

打印出你在这个过程中所做的许多事情,以显示每件事情在做什么,以及学生在逻辑的道路上应该期望什么。这可以帮助提供上下文,帮助他们掌握调试,这样你就不用花太多时间帮助他们调试了。

单独的项目和实例

当教授一个框架时,你通常会有一个项目,每个人都在工作,提供整体的背景,让他们自己构建一些东西。像猫的脸书之类的东西..在给出例子的同时,很容易用相同的项目类比来展示它们。使用不同的项目类比非常重要。

这可能只是狗的脸书,所以学生只需将单词 dog 改为 cat。

但理想情况下,你希望它是一个略有不同的概念,所以所有进一步后端的东西将有不同的名称,如数据库集合等…

资源

提供一个有用资源的列表很重要,但是你也必须预料到,除非你给他们一个在练习中使用它的具体理由,否则一个资源都不会被使用。

因此,你应该将最重要的资源融入他们的练习中。

因此,一个要求他们使用一个特定术语的超级简单的 API 参考查找的练习将使他们使用 API 文档。你想最终让他们自己导航这些,而不必问,但首先你需要为他们做。

举例

您正在教授回调,您希望他们使用 放大镜工具 。不要只是把它藏在一系列有用的东西中去探索。实际上,给他们一些练习,让他们解释你用工具给他们的回调函数。然后,也许他们可以尝试使用该工具使回调函数以不同的方式工作。

现在,每当他们陷入回调时,他们会立即想到去使用这个工具,并可能将它保存在他们的收藏夹中。看看这是多么有用,相比之下,它被藏在一个幻灯片甲板,他们不会打开下周当他们卡住了。

第四部分——家庭作业怎么办

家庭作业和额外作业。

和资源一样。仅仅列出学生必须做的额外作业是很诱人的。但只要假设这在很大程度上不会发生。为了更上一层楼,所有必须学习的东西都必须在教室里解释和完成。

students can drown if you don’t restrain yourself

学生们需要对一个想法有一个结论,并找到巩固它的方法。在工作日或每周末给学生留出时间和空间,让他们退后一步,评估哪些事情他们已经学得很好,哪些事情对他们有挑战。他们需要确定他们需要更多练习的关键部分。

这在周末尤其重要。提供大项目是如此诱人,因为他们喜欢建筑材料。学生不傻。如果他们有正确的工具,他们可以自己制作增加复杂性的项目,这应该是自我引导的。当然,学生们渴望尽快学习,但有些人总是有理由在周末不工作,不管是工作、生日还是生活…

定义什么是必需的,什么是额外的

应该加强的是复习他们没有理解的内容,并确保他们已经赶上了。到下周,你需要同一水平的每个人都准备好在平等的基础上进入下一组概念。

作业不好的例子**——在猫书项目中为每个猫用户添加谷歌地图旅程。

一些学生会真正投入其中,学到很多东西。而其他学生可能整个周末都在工作以支付他们的课程费用,并且仍然在丢失前一周的东西。假设所有学生在周一早上都掌握了 GoogleMaps API 是不公平的,因为事实并非如此。

在接下来的课程中,你不应该要求掌握地图应用编程接口知识,而应该先自己教授新的知识。

范例好作业**——考一周所学的东西。任何确定的弱点完成建议的额外练习

这个家庭作业帮助学生结束他们在一周内所学的内容,这样作为一名教师,你就知道课程直接涵盖的内容。

作为一个额外的,你可以为那些有时间学习酷的东西的人建议地图项目的想法。你不想阻碍那些比别人学得更快的人。但是你也不希望他们学习很多你以后会学到的新知识,因为他们会比其他人走得更远。

一般来说,最好是让他们在同一主题上达到更高的熟练程度,而不是让他们只学习下周的主题,这样会给你一个完全不同的班级。

第 5 部分—反馈和使用问题作为教学工具

反馈

拥有一个良好的反馈回路,让学生匿名发表意见是至关重要的。我已经解释了教授一个概念的基本布局和速度,但是在现实世界中,你的学生应该设定速度。

掌握学生理解和不理解的数据至关重要。它允许您在正确的时间动态地交付最好的内容,并为后面的学生不断改进它。

作为教学工具的问题

作为反馈的一部分,在任何讲座中简单地提问就可以成为你的飞行速度表。这似乎是显而易见的,但实际上本身就是一门艺术。

你必须避免加载问题****

当你解释完一些困难的事情时,不要简单地问是否可以。如果你没有得到任何真正的答案,这不是一个简单地继续前进的信号。

相反,尝试询问是否有人可以向全班解释这个概念。如果你得不到答案,这是继续前进的信号吗?当然不是。

当你开始的时候,人们会很害羞,什么也不说。如果你选择一个学生来解释一个概念,而他们用恐惧的眼神看着你,不要继续下去!这可能会让他们免于尴尬,但并不能解决他们的问题。用更简单的方式回顾一下这个概念,或者问一个更简单的问题。

当你开始了解这个班级,他们开始互相了解,这将变得更容易。你应该培养他们在别人面前说话时感到舒服。他们应该有信心尝试解释他们并不真正理解的事情。然后你就能确切的看到他们做的和没做的部分。理想情况下,你可以进行积极的小组讨论,这是听取不同人的理解的一个很好的动力。

互相解释

一个很好的练习可以是暂停整堂课,让几对学生互相解释一个概念。当两个一无所知的学生有机会发现另一个人不知道发生了什么时,他们不会因为问问题或承认他们不明白而感到尴尬。

在 60 秒的休息之后,人们将在心理上准备好谈话,当你询问哪些群体得到了反馈时,你将确切地知道发生了什么。即使整个房间里只有一个人明白,你也会知道,他们会向每个人解释。你很快就打破了公开讨论的障碍,培养了同伴学习,而不是孤立的随波逐流。

第 6 部分—在同一水平上教授学生

试图教不同水平的学生是一场噩梦,也是一场彻底的灾难。

代码新手

如果你的课程接受绝对初学者,那么它就是绝对初学者课程。让更高级的人上这门课将会是一场噩梦,因为你试图向不同的人教授不同的水平。

即使只有一群绝对的初学者,大多数也会非常慢。你冒着一些学生发现他们讨厌它,而另一些学生发现他们是天才并以每小时一百万英里的速度前进的风险。

课程前的必要条件

大部分课程面向对 JS、CSS、HTML 有基本了解的人。我个人认为,如果学生以前从未编写过代码,那么向他们收取一个月或更长时间课程的费用是错误的。他们不知道自己是否喜欢或擅长,至少需要先有某种形式的测试经验。

最好的策略是设置一些非任意的先决条件,所有学生都必须通过这些条件才有资格选修这门课程。这将剔除不适合编码的人,意味着你有一群有能力和兴趣学习的人。你可以为那些和你一起学习基础知识的人提供一个小型的预备课程,或者为新手提供每周一次的聚会,让他们学习预备课程的内容并了解什么是适合他们的。

拒绝人们背后的商业意识

我理解训练营是一门生意,老师需要挣钱,教室需要付费。但是很重要的一点是,你要拒绝那些不应该出现在球场上的人。

向少数人提供良好的教育,好过向许多人推销你无法提供的教育。那些可以学习的人会减少学习,那些不应该学习的人会失败并要求退款。你将面临混乱和一堆差评,你的生意将一事无成。

如果你只把你的教育给那些有能力接受它的人,你将提供一个很好的体验,并提供一群学生,他们将代表和发展你的品牌。这将导致一个可持续的长期业务。

但是难道没有人可以学习编码吗

考虑到我运行的成长心态播客教你如何做任何事情,永远不要把自己束缚在消极的信念中。我不相信每个人都应该学习编码。

我同意,假设任何有能力学习语言的人都应该能够学习一组新单词的定义和行为,从而最终能够学习编程。但是,有多少人:

  • 问过你关于电脑最荒谬的问题。
  • 会在他们的代码不起作用 4 个小时后继续努力吗?
  • 喜欢花 30 个小时教电脑玩数独,而他们却可以看《网飞》?

并不是每个人都喜欢它,接受一个突然产生学习技术的渴望的人学习一门课程是很危险的,这个人一生中从来没有敲过一行代码。

同样的,任何一个能在没有手机、书籍或电视的情况下静坐 5 分钟的人,完全有能力进行为期 10 天的冥想静修。在静修中,他们需要安静地静坐十天,除了自己的思想之外,不读、不写、不看任何东西。我很确定这不是大多数人喜欢的。

最终,有些人会过得更快乐,而不用学习编码,任何人都没有义务去尝试把不需要的信息强行塞进别人的大脑。你当然不应该说服别人为不适合他们的东西付钱。

摘要

我再说一遍,学习编码真的很难,掌握它是一条漫长的道路。但是学习教授编码也同样困难,并且有更少的文档资源。

让人们拥有这样一项令人敬畏的技能真的很令人兴奋。你希望学生们能从和你在一起的时间里学到尽可能多的东西,但是如果你以前从来没有教过新手,那么教新手的速度会慢得令人沮丧。

质不量

你需要专注于尽可能好地教他们,而不是试图尽可能多地教他们。如果他们的知识没有深度,你的教学就完全没有意义。

当他们还没有理解你到目前为止教过的所有部分时,匆忙完成他们构建一个全栈应用所需要知道的一切是没有意义的。如果你发现自己在为他们做一些事情,而他们什么都不懂,没有你他们就做不了。当他们离开这门课程时,他们将无法再做一次,你也不会有一群学生向世界展示你的课程有多好。

一些最好的训练营只是专注于真正擅长核心概念,这样学生就有能力自学 React 和其他框架。如果他们试图把这一切都塞进一个从零到英雄的课程中,他们最终会发现很多人都没有成功,只是后来又回到了零。

If there’s no one on the train stop and rethink

不如教他们一半的材料,让他们掌握。他们必须非常自信地走出去,继续使用他们所知道的东西,并在此基础上继续发展。如果他们结束时对你教他们的东西感到困惑,他们将无法找到工作或做出很酷的事情= >课程和你的努力都将付之东流。

完成意味着完成

就像建软件一样,做好了就做好了。你不能发布一个完成了 90%的应用程序,因为它根本就不工作。在教授重要概念时,如果 90%的学生理解了,但不能实际解释如何使用,那么就不能 使用

不要教他们更多的东西,希望这些东西会变得有意义。完成你已经开始的事情,或者授权他们把最后的 10%作为他们的家庭作业。

从小步开始

像学习任何东西一样,学习教学需要循序渐进,边做边学是关键。在开始一门完整的课程之前,最好在一个较小的环境中练习教学。

试着办一个聚会或者周末课程。找一些学生来指导。我喜欢它,但你可能会讨厌它,你不能告诉除非你试过。

这听起来可能是显而易见的,但有些人真的开始了训练营,第一天是他们第一次尝试教别人编码。不要这样做!

为什么这么做?

教书是世界上最好的事情。这并不容易,但很快你所有的学生都会说电脑,你会为让他们正确地说话而感到骄傲。即使像吉米这样的聪明人(见自行车类比)如果你没有在这个过程中杀死他们。看着他们掌握技能,走向世界,创造出很酷的东西,真是太棒了。

因此,请尝试这些原则,在上面添加你自己的个人风格,并提供任何意见以帮助其他人更好地教学。

如果你喜欢这篇文章,你可能会喜欢我写的一些关于编码和学习的文章:

  • 结对编程的好处和缺点
  • 学会了无助,学会了乐观

我运营着成长思维播客,在那里我将心理学、商业和生活中的领先理念进行分类。你可以在我的网站SamWebsterHarris.com找到更多关于我的信息。

如果你喜欢这个,那我会很高兴。如果你不喜欢这本书,我不知道你为什么还在读,人生苦短,去读点别的吧。

如何教授数据科学

原文:https://towardsdatascience.com/how-to-teach-data-science-505711be6ec?source=collection_archive---------29-----------------------

在指导 20 多名学生成为数据科学家后,我的建议是…

那么,如何才能教一个人成为数据科学家呢?这些问题的简短答案是:你不能教一个人成为数据科学家…但这不是本文的标题吗?

让我在这里进一步阐述这个观点。我相信你不能教一个人成为数据科学家,但是你可以在整个过程中指导他们,帮助他们学习。还记得当你第一次学习如何使用 python 或 R 编写和分析你的第一个数据集时犯的所有错误吗?现在你可以和你的学生分享这些知识,这样他们就可以避免你过去犯过的错误。

但这是他们能采取的最佳学习途径吗?我将在这里分享我在过去几个月指导数据科学学生时学到的一些技巧。

  1. 学生的目的是学习,而不是教他们。

对学生来说,重要的是要明白,要学习新概念,他们需要付出最大的努力。你不可能神奇地打开一个人的大脑,让它充满新的信息。他们需要寻找信息、阅读数据科学材料和练习给定的练习。

这实际上直接引出了下一点…

2。建议你的学生让自己置身于数据科学之中。

他们不应该仅仅遵循某本书或某门课程中概述的一些练习或教程。重要的是,他们要尽早开始阅读各种主题的数据科学文章:机器学习、数据清洗、数据可视化、工作机会,基本上是任何与数据科学相关的内容。如果他们订阅数据科学视频频道和播客,这是一个好主意,这样沉浸感来自各种资源。

3。利用以前的工作经验或兴趣。

这篇技巧特别针对那些试图从不同领域过渡到数据科学的人。我会鼓励他们尽早从事与他们当前专业领域相关的项目。因此,如果有人从事营销工作,我会建议他为与营销或销售相关的早期项目选择数据集。通过这种方式,学习曲线变得不那么曲折,他们可以利用他们的专业知识,这样他们的初始项目就可以大放异彩。

4。让你的学生犯错。

我相信这是一个重要的部分,这是学习应该做的。人们从错误中学习。您的学生可能会在特定操作中使用错误的函数。重要的是让他们自己去发现,自己去改进。他们可能会犯同样的错误一次或两次,但第三次他们会做对。这通常比一开始就告诉他们避免这个错误更有效。

5。教学生如何阅读文档和查找信息。

教您的学生如何阅读文档以及如何查找信息。我的学生经常问我类似的问题,“我在熊猫身上是怎么做到的?”“我需要做些什么才能让我的图表看起来像这样?”。我认为你不应该直接回答这些问题,而应该让你的学生去他们能找到答案的地方。它通常是库文档、特定教程或堆栈溢出讨论。随着时间的推移,他们将学会如何获得这些信息,甚至不需要你给他们指出合适的资源。

6。保持耐心、积极和鼓励。

最后但同样重要的是,记住要有耐心,积极和鼓励。人们学习的速度不同,一个人可能需要更长的时间来吸收某一特定的知识。在这种情况下,你可以试着回忆一下学习一些更复杂的编程概念有多难。你可以和你的学生分享这种经历,作为学习困难的例子,并告诉他们你是如何处理这种情况的。

结论

我给了你一份我教数据科学的建议清单。我希望你们中的一些人已经发现了这些有用的东西,并将在与学生一起工作时应用它们。我相信你们中的许多人都有关于如何教授数据科学的建议,所以如果你愿意,你可以在下面分享它们。

原载于 aboutdatablog.com: 如何教数据科学,2019 年 10 月 19 日。

PS:我正在 Medium 和上撰写深入浅出地解释基本数据科学概念的文章。你可以订阅我的* 邮件列表 每次我写新文章都会收到通知。如果你还不是中等会员,你可以在这里加入。***

下面还有一些你可能喜欢的帖子:

** [## python 中的 lambda 函数是什么,为什么你现在就应该开始使用它们

初学者在 python 和 pandas 中开始使用 lambda 函数的快速指南。

towardsdatascience.com](/what-are-lambda-functions-in-python-and-why-you-should-start-using-them-right-now-75ab85655dc6) [## Jupyter 笔记本自动完成

数据科学家的最佳生产力工具,如果您还没有使用它,您应该使用它…

towardsdatascience.com](/jupyter-notebook-autocompletion-f291008c66c) [## 当你开始与图书馆合作时,7 个实用的熊猫提示

解释一些乍一看不那么明显的东西…

towardsdatascience.com](/7-practical-pandas-tips-when-you-start-working-with-the-library-e4a9205eb443)**

如何使用 P 值一致性检验来检验您的假设

原文:https://towardsdatascience.com/how-to-test-your-hypothesis-using-p-value-uniformity-test-e3a43fc9d1b6?source=collection_archive---------16-----------------------

现实世界中的数据科学

你知道如果零假设为真,p 值是均匀分布的吗?

If you test 20 colours of jelly beans, how many null hypotheses do you expect to reject? (Webcomic from xkcd)

这篇文章是为那些熟悉假设检验和 p 值的定义和一些应用的人写的,希望加深对两者的理解。虽然这篇文章以一些评论开始,但鼓励读者在继续之前阅读这篇文章。

什么是假设?

我们每天都对新事物做出有根据的猜测。例如,我们可能会偶然发现一种新的神奇补充剂,声称可以提高注意力和工作效率。我们仔细阅读了公式,并坚信它会起作用。在这一点上,我们已经做出了一个假设,即补充剂会起作用,现在需要对其进行测试。

为了检验假设,我们首先需要收集经验数据。因此,我们对两组参与者进行了一项在线调查——一组每天服用补充剂,另一组不服用——报告他们的自我评估日常生产力水平,等级为 1 到 10。

我们如何测试它?

有各种各样的方法来检验假设,选择哪种方法实际上取决于个人的舒适程度。以下是一些常见的例子:

  1. 根据对照组结果,计算几个实验组结果的 p 值。如果它们是极端的,我们可以相信避孕药是有效的。
  2. 如上图所示,目视检查两个分布。
  3. 对相等的平均值进行 2 次样本 t 检验,以比较平均结果。
  4. 应用非参数双样本检验来比较两种分布(例如 Kolmogorov-Smirnov (KS),Anderson-Darling (AD)检验)。
  5. 进行 p 值均匀性测试。

在我们之前的例子中,我个人完全接受第二种选择,因为这是最快的选择,也容易解释。

然而,如果我们正在编写提交给美国和加拿大监管机构的白皮书,我们必须选择更严格的方法,如选项四或五。由于网上有更多关于 KS 和 AD 检验的信息,我将在本文中演示何时以及如何使用 p 值一致性检验。

Try to prove it and check your solution right here.

什么是 p 值均匀性检验?

本质上,p 值均匀性检验很简单:我们从观察值中获得一个 p 值样本,并测量它们与均匀分布的相似程度。通过进行这种检验,我们间接地检验了零假设的有效性,因为逆命题表示,如果 p 值不是均匀分布的,我们可以拒绝零假设。

为什么要用?

在众多优点中,这种方法提供的两个主要优点是:

  1. 它需要大样本量,产生统计上更可靠的结果
  2. 它可以适应动态零假设。

该方法不是拒绝基于小于 5%显著性水平的单个 p 值的零假设,而是将 p 值的经验概率分布与均匀分布进行比较。因此,这种方法需要更大的样本,自然产生相对可靠的结果。

更重要的是,在进行零假设是动态的实验时,这种方法很方便。这在非平稳数据中很常见,因为零假设可能会说预测值是基于最近两年的数据。换句话说,如果我们每周更新我们的数据,我们的零分布也会每周改变(见下图)。然而,我们的零假设,它定义了我们如何生成这些零分布,将保持不变。

Null distributions exhibit an increasing trend in estimated variance.

在这种情况下,我们只能将单个观测值与其对应的零分布进行比较。因此,我们不能有意义地比较一个样本的观察值与任何零分布。

我们如何测试它?

作为 p 值均匀性测试的第一步,我们可以根据各自的零分布将样本的观察值转换为经验 p 值,从而对样本进行归一化处理(见下面的公式)。

有了经验 p 值的衍生样本,我们可以继续找出它与从 0 到 1 的均匀分布有多相似。正式方法包括分布比较测试,如 KS 或 AD 测试,而快速直观方法通常足以理解结果。在本文的其余部分,我们将通过展示不同情况下的 p 值分布来结束。

我们如何解释 p 值分布的形状?

例 1:均匀 P 值分布

假设零假设说一个随机变量服从均值为 0,方差为 1 的正态分布。如上所述,如果样本遵循零分布,p 值分布将非常类似于均匀分布。

这是因为如果数据遵循零分布,则 5%的数据将高于第 95 百分位,5%的数据将介于第 90 和第 95 百分位之间。换句话说,5%的数据将给出从 0 到 0.05 的 p 值,另外 5%的数据将给出从 0.05 到 0.1 的 p 值,依此类推。

因此,当我们绘制直方图时,覆盖 5 个百分点的每个块将代表 5%的数据,包括均匀分布。

例 2:增加或减少 P 值分布

如果我们看到具有更高 p 值的 p 值分布,这表明我们的样本数据通常具有负的数据偏移。当样本分布出现负偏移时,与零分布相比,我们将拥有相对更多的低值样本数据。反过来,这些过剩的数据将被转化为过剩的高 p 值,显示出不断增加的 p 值分布。

相反,通过类似的推理,样本数据的正偏移将对应于 p 值分布的下降。

示例 3:尾部递增的 P 值分布

这种情况下,样本数据的方差高于零假设所表明的方差。方差高于预期的样本数据将具有相对更多的极值数据点,这些数据点将被转换为极值 p 值。

看完基本示例后,我建议您绘制样本数据的 p 值分布,该分布遵循均值为 1、方差为 2 的正态分布和标准正态零分布。这是一个很好的测试你对所涵盖的材料的理解的练习。解决方案在文章的结尾,所以如果你想试试,就在这里停下来。

我想做一个总结性的评论,p 值一致性检验是检验零假设的一个非常有效的方法,尤其是在与 KS 或 AD 检验结合使用时。学习可视化和解释 p 值分布特别方便,因为它有助于我们在投入更多时间之前预见实际数据与我们的假设有多接近。

好好利用它,下面是习题的解答!

解决方案

如何跟踪机器学习的准备情况,以及为什么我们都应该关心

原文:https://towardsdatascience.com/how-to-track-machine-learning-readiness-and-why-we-should-all-care-8639ca7dd7b6?source=collection_archive---------21-----------------------

这是一篇关于 BBC 技术和创意博客——机器学习就绪指数 的原始帖子的扩展版本。

无论是数学家、数据分析专家、经验丰富的软件工程师,还是在家接受推荐观看新系列《路德、浴血黑帮》或《隔壁两扇门》的观众,我们都在人工智能和机器学习的发展中发挥着作用。我们都应该关注这些系统如何发展,以处理我们的个人信息,并推动影响我们和我们所爱的人的生活的决策。最近,我发现围绕“机器学习”和“机器洞察力”的对话比那些以人工智能(AI)为主题的对话更能引发关于技术进化的实际、诚实、进步的对话。后者往往会激发更具创造性、更浪漫的未来图景,在这种图景中,人类和机器变得交织在一起,几乎无法区分,因此我们需要围绕权利、正义、道德以及活着意味着什么发展新的思维。我也准备好了这些对话,但在这篇文章中,我有意提到机器学习,这样就很少提到拥有智能和其他人类特征的机器。在这里,我将机器和机器学习视为工具和方法,通过这些工具和方法,我们可以收集、处理和呈现关于我们过去、现在和预测未来的洞察力。他们处理大量数据,以生成可重复使用的统计洞察、特征、趋势和异常。即使数学和计算机科学可能显得势不可挡,我们在社会中仍然需要关注机器学习如何进步,教育我们自己和我们的孩子,并且不要远离正在进行的对话。数字媒体和信息融入了我们的日常生活,并影响着我们对世界、人民、政治、经济和身份的看法。机器学习与现在和未来媒体的委托、开发、交付和消费方式密切相关。

在过去 3-5 年中,机器学习能力激增,这是由算法的根本改进、计算机硬件的进步、数据量的增加以及用于学习、开发和将机器学习能力纳入产品的知识库、社区和工具的增加所驱动的。随着机器学习的进步,我们对可能性有了更好的看法,围绕道德、责任和社会公益的紧张和讨论也在升级。随着机器学习领域最近的许多突破,包括机器在内的灾难和致命事故,如最近在亚利桑那州发生的自动驾驶汽车事件(见:https://www.bbc.co.uk/news/business-43459156),在部署机器学习时产生了一种谨慎的感觉,特别是在人类至关重要的环境中。理解这些事件的原因强化了机器学习在炒作中的现实:机器学习是大规模的计算,比较和选择最佳统计可能性,受限于过去数据的广泛性及其正确和全面编码当前感知的能力。

机器学习中的许多事件和事故都与当前被称为“对立例子”的难题有关。当物理环境中的微小变化严重危及机器学习系统决策的可靠性时,就会出现这种情况,而人类通常会忽略这些变化。例如,放置在停车标志上的一条白色胶带可能会改变机器学习系统的计算和区分路标的能力。日常场景、声音和物体的意外或有意改变,如涂鸦或不可避免的磨损会“扰乱”机器学习算法,导致不可靠的推理。这种对立的例子可以解释为什么会发生亚利桑那号这样的事故。然而,只有认识到机器学习对看似琐碎的日常调整的敏感性,才能更好地理解它的真正能力和局限性。

显然,自动驾驶汽车中的致命事故远比推荐系统在某人的媒体主页上呈现相关程序的失败更加关键和令人担忧。然而,我们应该记住,类似的概念和技术在幕后工作。假设一名记者依靠面部和物体识别来记录和验证故事中的事实,这些事实可能会影响人们和地方的声誉。如果这些类型的错误在没有审查和纠正的情况下频繁发生,对机器学习的依赖可能会导致报道不准确,并损害新闻的可信度。在某些情况下,审查和纠正的工作比一开始就做任务更乏味。机器学习能力,如计算机视觉、音频处理和自然语言理解,已经在产品就绪的媒体工作流中使用,都容易受到上述敌对例子的影响。此外,机器学习算法仍然消耗大量的计算和存储容量,并且难以在不牺牲质量和严格性的情况下进行优化。在一些应用中,机器学习是“生产就绪”的,而在另一些应用中,计算能力或算法能力不足。以有意义的、指示性的方式阐明“准备就绪”的方法将有助于导航机器学习能力的前景。

在 BBC 技术战略与架构(TS&A)中,我们一直在关注机器学习市场,并尝试不同的方法、工具、产品和服务,以更好地了解它们的能力、局限性以及当前的研发进展。这样做时,我们会问以下问题:

  1. 我们应该在哪里投资研究?
  2. 我们需要建立什么样的战略伙伴关系?
  3. 我们应该在哪里考虑试验和试点?
  4. 我们的下一个采纳计划应该是什么?
  5. 我们还不知道什么还为时过早?

我们的大部分讨论和分析都围绕着自动化以及在传统的手动媒体工作流程中增强人类认知功能的可能性。认知功能包括感知、决策和执行任务,每一项都为自动化和人机交互带来不同的挑战。以下是目前由各种提供商作为产品和服务提供的 8 类机器学习能力。

根据我们的讨论,我们开发了"机器学习就绪指数,如下图所示。这是一个 0–7 等级的方案,其中每增加一个等级,指定一个特定应用的能力准备程度就提高一个等级。“机器学习就绪”被定义为机器学习能力在给定场景中取代人类认知功能的能力。机器学习就绪性更具体地是指使用一种或多种机器学习能力来解决生产工作流程中的选定问题的方法的适合性或适用性,这通常依赖于人的认知。

索引中的级别描述如下:

0 级(早期):此阶段的能力本质上是概念性的。有一些关于该功能如何工作的建议和想法,也有一些理论上的甚至是模拟的工作流,但是没有发表实际的、同行评审的证明或演示。应用和好处是通过原型和实物模型展示的命题和用户体验。

第 1 级(初始):这个阶段的能力是用工作模型开发的,证明一个概念至少是可实现的。然而,为了证明规模效益,仍然需要开发相关能力(不一定是机器学习,而是在其他领域,例如动画、可视化和数据处理)、计算能力(处理、存储和网络)和训练数据,以便在实际工作流程中进行评估。如果市场需求很小,或者所需的计算能力和训练数据远远超出当前实践中可获得的范围,则能力可能会长时间保持在这一阶段。

第 2 级(渐进):此阶段的能力证明它们可以在实践中发挥作用。基本的计算和算法挑战已经解决,但仍然没有足够的训练数据来实现对现实世界场景的更广泛应用以及调整模型和学习算法。下一个挑战是收集相关的培训数据,并确定优化其性能的策略。

第 3 级(突破):在这一阶段,对能力的限制(提供有用结果的最低条件)和调整参数(可控地影响能力的行为、性能和质量的数据、算法和计算的可调属性)有了更好的理解。该功能可能会作为“测试版”向公众发布,目的是增强训练集并进行大规模使用的早期实验。

第 4 级(谨慎):在此阶段,能力的性能是稳定的,但输出并不总是可靠的。这种能力可能容易受到偏离其训练的细微差别、文化或其他特定领域特性(如行话、方言、手势、图标、颜色联想)的影响。由于这个原因,在没有人的监督和纠正的情况下,这种能力是不可信的。它可能提供“第一次切割”的产品,但工作流程将包括强制性的质量控制过程。

第 5 级(稳定):在这一阶段,在某些情况下,在输入的已知、可控条件和属性下,该能力提供可预测的、正确的结果。因此,可以在生产工作流中为选定的域委托重定向、升级或异常处理,以便在超出域的边界条件时通知并雇佣人员。机器能力被认为在其受限领域表现得与人类一样好,成本更低,并且在更长的时间内更可靠(即人类会疲劳并犯错误)。人工监督是监控通知和警报,以便按需进行质量控制和干预。考虑一下呼叫中心使用的自动聊天机器人,如果投诉的语气或问题变得过于敏感,它会将对话重定向到主管。

第 6 级(高级):这一阶段的能力被认为比人类工作得更好,更便宜,相当于更高质量的输出,并且在选定的领域更长时间内更可靠。监督是最少的,并且关注于确保整个工作流和系统保持可用,而不是能力的质量。为了不断提高能力,可以回顾日志,但是这个阶段的改进是微不足道的。对于可能影响执行该功能的个人的生命或生计的高风险情况,机器能力将优于人类。然而,如果担心更多的人群受到失败事件的影响,仍然可以选择一个人或给予他监督的、压倒一切的控制权。

第 7 级(复杂):这一阶段的能力是完全自主的,被认为能够在大多数领域实现超出人类能力的质量、性能和可靠性水平。在高度关键或高风险的任务中,这些能力将比人类更受青睐,这些任务可能会影响组织的声誉或履行职能的个人以外的人口的生计和福祉。

然后,机器学习就绪指数可以进一步用作视觉地图,提供方向(我们当前所在的位置)、目的地选项(我们想去的地方)、可选路径(什么是可能的)和方向(要到达那里需要做什么)。当应用机器学习就绪指数时,有三个问题以及要收集的信息类型:

1.当前准备程度:当前可能达到什么程度的准备程度?

2.期望的准备程度:根据受众和业务指标,我们希望在给定的时间范围内达到什么程度的准备程度

3.预计准备程度:根据技术评估和市场指标,在给定的时间范围内可能达到什么样的准备程度?

回答这些问题可以加强我们的战略地位,向合作伙伴、提供商和公众传达和挑战我们的利益、不感兴趣、意图和优先事项。另一个目标是使用该框架作为背景,支持与非技术观众围绕机器学习现实、事实和虚构进行更高级别的讨论。围绕机器学习采用的许多担忧是不理性的,是基于耸人听闻,但正如前面提到的,最近的事件确实有理由担忧。

下面显示了一个基于一组假设用例的示例结果(该图仅用于说明目的,并不代表我们对所呈现场景的当前立场)。

这种地图可以应用于用例、产品、平台、组织或行业合作伙伴和联盟级别,有助于围绕战略的对话。例如,以下是可以从上述地图中获取的一些信息:

使用语音到文本(STT)、自然语言理解(NLU)和文本到语音(TTS)的对话和反馈场景的当前准备程度为 5 级——稳定但预计准备程度为 6 级,相当于所需的准备程度。这表明需要建立伙伴关系,在下一个时间范围内开展试验和试点,以便过渡到准备就绪的高级阶段。

使用深度学习和分析(DLA)的推荐场景的当前准备程度为 6 级—高级,相当于期望的准备程度,并且没有计划的进一步改进。这表明商品和决策应该集中在选择合适的供应商上。

机器学习就绪性的问题通常集中在组织上,而不是技术能力上。这个框架不是评估一个组织是否适合纳入机器学习能力,而是评估这些能力是否准备好为组织带来价值。就绪指数不是一门绝对的科学,它取决于集体的主观意见,基于对场景和机器学习能力的共同理解。特别是用这个框架做的预测只不过是不精确的印象和最好的猜测。

其目的并不是放弃使用真实数据和工作负载对解决方案进行严格的基准测试和比较,而是为了在某个时间点提供市场相关性的高水平画面。创建这样一个视图的另一种方法是为每一个功能类型建立一个自动化的测试管道,其中包含来自不同场景的测试数据,并报告所选择的测试度量。尽管这看起来更加量化和以指标为导向,但仍然需要解释这些数字,并判断所评估的能力是否适合测试中的场景。

随着算法、框架和计算能力的进步,机器学习能力不断发展。作为一家媒体机构,我们将继续关注这些发展,以便做出明智的判断,找出有意义、现实的方法来改善我们的工作方式和体验。作为消费者、观众和公民,我们都应该关心机器学习,确保我们了解并参与塑造我们未来的方式。

如何像量化分析师一样分析债券

原文:https://towardsdatascience.com/how-to-trade-bonds-like-a-quant-da2c297958ef?source=collection_archive---------6-----------------------

我有 99 个问题,但我把它们减少到了 3 个。

放弃

一个成熟的定量分析师会使用大量其他工具来分析债券,尤其是公司债券(价值、价格、动量等)。).这只是一个普通观点的介绍。这并没有透露我的雇主的具体战略的重要信息。

介绍

今年夏天,我在一家固定收益投资基金实习,扮演数学家的角色。我被要求建立一个模型,分析不同国家的债券价格变动,虽然我不能透露我研究了哪些国家或结果,但我能做的是分享方法。

这绝不是对债券或股票进行定量分析的所有方法的全面指导,但它是观察价格变动最普遍的工具之一——主成分分析——的快速指南。

收益率曲线

A cute little yield curve

你可能听说过收益率曲线。这是一个图表,显示了债券发行时间和你得到的利率之间的关系。你期望看到的是,远期债券会带来更高的回报,因为你应该得到补偿,把你的钱锁定更长的时间。然而,随着时间越来越往后推,这个斜率会越来越小,因为储存资金 25 年和 30 年真的有很大的区别吗?因此,曲线。

问题是

假设我们在看收益率曲线,我们看到了这个。

This one inverted, so I’m sure there will be a Planet Money episode on it soon.

哪里出了问题?坏了吗?不,你看到的是利率随着人们相互买卖债券而调整。如果许多人希望购买 2 年期国债,需求就会压低该债券的收益率。

收益率曲线的这些重大转变来自影响投资者风险承受能力和乐观情绪的宏观经济条件。然而,我们应该看到的是一条总体上平滑的收益率曲线。即使它弯曲了,也不应该有一个键从弯曲处伸出来。3 年期与 2 年期和 4 年期看起来完全不同,这没有多大意义。

I would feel sick if I saw this on my Bloomberg Terminal.

那么,我们如何预测收益率曲线将如何变动?如果我们能买入一种债券,并在需求更大时卖出,我们就能获利。然而,宏观经济预测难以置信地困难,需要在你的投资组合中承担巨大的风险。

我们不用根据外部因素来预测收益率曲线将如何移动,相反,我们可以利用我们对其平滑度的了解,根据内部因素来预测它将如何移动。

主成分分析

主成分分析(或简称 PCA)从数学意义上来说是一种降维方法。这到底是什么意思?最好通过一个例子来说明。假设我们在三维空间中有一些点——x、y 和 z。

It’s hard to draw points in 3D.

注意这些点是如何形成对角线趋势的。不过,在三维空间工作很烦人。当然,三个轴的每一个都有变化,但是我们可以把它画在 2D 平面上。我们有办法做到吗?

PCA 来了。通过称为协方差矩阵的东西,您可以找到一组称为主成分的新轴,它们最有效地描述了数据中的方差,同时彼此之间没有相关性。您找到的第一个轴解释了最大的方差,第二个解释了次大的方差,第三个代表最小的方差。

It’s even worse drawing six axes.

你现在找到了一种新的方式来描述你所有的信息。然而,如果最后一个轴解释了一个微不足道的变化量,您可以选择忽略它。

Ignore z’ and simplify into this one plane.

把它带回债券

我们可以采用历史债券收益率,并绘制它们来得到我们的点。每个债券日期都是一个维度,所以如果我们使用美国所有的国债,我们最终会得到超过 200 个维度的数据。那是胡说八道。

你可以使用主成分分析来找到一组新的坐标轴,正如一些研究发现的那样,解释债券价格所需的坐标轴之少令人震惊。第一个轴定义了 90%多一点的运动!接下来的两个解释了剩下的 98%。有时你会考虑第四种,但很少。除此之外,你应该忽略它们或者只是把它们加在一起。

我们所做的是接管一个 200 维的空间,并将其简化为一个三维空间,它保留了我们开始时 98%以上的信息。这太疯狂了。

这些轴甚至可以用来描述市场的特征。第一个轴表示沿收益率曲线的水平效应。第二个轴与曲线斜率的倾斜有关。第三个描述了弯曲的翅膀和腹部。这些都是系统性风险的形式。

Left: 1st PC of level risk. Middle: 2nd PC of slope risk. Right: 3rd PC of curvature risk.

如何根据这些信息采取行动

您已经运行了您的 PCA 并准备好开始。你所做的不是找到收益率曲线整体的关系以及它的走向,而是找到每只债券的收益率如何相互关联。曲线是否弯得太多太快?收益率曲线是否比预期的更加崎岖不平?

我们早些时候指出,相邻的债券不应该相对于彼此定价过高,我们现在可以做的是在这组坐标轴上绘制今天的收益率,看看我们的债券收益率是否有任何异常。这种期望与现实的差异是残余的。我们可以打一个不错的赌,债券的定价可能会比 T4 低一点或高一点,最终会回到这个预期水平。不完全是均值回归,但也差不多。

If there is a larger residual, you should feel more confident in the reversion.

要计算残差,您需要确保将所有结果除以主成分得分变化的标准偏差。基本上,有些轴比其他轴更不稳定;控制它。

花絮和建议

根据定义,你的 PCA 在你的回看窗口的轴上是零相关的,但是有可能在后半部分发展的关系被前面的点抵消了。确保对另一个小于 PCA 的回看进行轴之间的相关性测试,以便对您是否隔离了某个特征有一些合理的怀疑。

用 PCA 管理你的投资组合是一种短期的相对价值策略。你没有对收益率曲线的走向采取立场,只是试图在市场上涨或下跌的地方寻找机会。

不要在 Excel 中这样做。这个用 R。最好通篇使用 R。我尝试使用 BERT 来进行与 Excel 集成的 R 会话,但它导致了更多的问题,得不偿失。

后续步骤

你可以用这个策略做一些更复杂的事情,从风险策略的角度来看,这些事情非常酷。当我们找到每个主成分的得分,而不仅仅是用它来寻找剩余,我们可以用它来创建一个系统风险中性的投资组合。

如果我们能找到一组债券,它们在每个轴上的总风险相互抵消,我们就能把赌注隔离在身上,只关注剩余价值,而不是担心宏观经济状况的恶化。两点总比一点好。三强。一旦你数到四,你会非常自信你受到了保护。

还有一种形式的 PCA 称为 kPCA,即核主成分分析。我们没有使用基本的线性代数来降低维度,而是首先增加维度来寻找非线性关系,然后再降回更少的维度。我发现了一些适用于股票而非债券的有趣文章,所以一旦我再次在一家拥有历史债券数据的公司工作,我会尝试做一些自己的研究。TL;DR,市场效率越低,你的模型应该越不线性。

Try making a best fit line through a circle. Try. I dare you.

结论

诚然,这些策略不适合普通人使用,但我们无法进入这些债券市场,也无法利用它们,所以我希望你觉得自己学到了一些东西。这种将问题简化为最重要的事情的思维模式不仅在金融领域出现了很多,在数据科学和其他具有复杂特征的领域也出现了很多。我强烈推荐你阅读其他文章,听听播客,比如 AQR 的《好奇的投资者。他们有一些很好的内容,关于在其他地方应该如何考虑风险管理的心态。

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

如何使用 PyTorch 在 128 GPUs 上训练 GAN

原文:https://towardsdatascience.com/how-to-train-a-gan-on-128-gpus-using-pytorch-9a5b27a52c73?source=collection_archive---------12-----------------------

如果你对 GANs 感兴趣,你会知道生成好看的输出需要很长时间。通过分布式培训,我们可以大幅缩短时间。

在另一个教程中,我介绍了你可以做的 9 件事来加速你的 PyTorch 模型。在本教程中,我们将实现一个 GAN,并使用分布式数据并行在 32 台机器(每台机器有 4 个 GPU)上训练它。

发电机

首先,我们需要定义一个生成器。该网络将随机噪声作为输入,并从噪声索引的潜在空间生成图像。

这个生成器也会有自己的优化器

opt_g = torch.optim.Adam(self.generator.parameters(), lr=lr, betas=(b1, b2))

鉴别器

Real or fake pirate?

鉴别器只是一个分类器。它接受一幅图像作为输入,并判断它是否是真实的。

鉴别器也有自己的优化器。

opt_d = torch.optim.Adam(self.discriminator.parameters(), lr=lr, betas=(b1, b2))

甘培训

甘训练有许多变化,但这是最简单的,只是为了说明主要的想法。

你可以把它看作是发生器和鉴别器之间的交替训练。所以,批次 0 训练发生器,批次 1 训练鉴别器,等等…

为了训练发电机,我们执行以下操作:

Generator Training

从上面我们看到,我们采样一些正常的噪声,并把它给鉴别器,因为它是假的,我们生成假标签,要求鉴别器分类为假的。

我们反向传播上述内容,然后继续下一批训练鉴别器的内容。

为了训练鉴别器,我们进行如下操作

Discriminator Training

鉴别器计算出 2 个损耗。首先,它能多好地检测真实的例子?第二,它能多好地检测假例子?全损刚好是这两个的平均值。

照明模块

PyTorch Lightning

为了在 128 个 GPU 上训练这个系统,我们将在 PyTorch 之上使用一个名为 PyTorch-Lightning 的轻量级包装器,它可以自动完成我们在这里没有讨论的所有事情(训练循环、验证等……)。

这个库的美妙之处在于,你唯一需要定义的是一个 LightningModule 接口中的系统,你可以获得免费的 GPU 和集群支持。

这是作为照明模块的整个系统

这个抽象非常简单。培训的实质总是发生在 training_step 中,因此您可以查看世界上的任何存储库,并知道在哪里发生了什么!

让我们一步一步来。

首先,我们定义这个系统将在 init 方法中使用的模型。

接下来,我们定义我们希望系统的输出在。正向法。这意味着,如果我从服务器或 API 运行这个模型,我总是给它噪声,并得到一个采样图像。

现在是系统的核心部分。我们在 training_step 方法中定义任何系统的复杂逻辑,在本例中是 GAN 训练。

我们还缓存我们为鉴别器生成的图像,并记录每一批的示例。

最后,我们配置我们想要的优化器和数据。

就是这样!总之,我们必须明确我们关心的事情:

  1. 数据
  2. 涉及的模型(初始)
  3. 涉及优化人员
  4. 整个系统的核心训练逻辑(训练 _ 步骤)
  5. 对于可能需要计算精度或使用不同数据集的其他系统,有一个可选的 validation_step。

在 128 个 GPU 上进行培训

这部分现在其实很琐碎。定义了 GAN 系统后,我们可以简单地将它传递给一个 Trainer 对象,并告诉它在 32 个节点上训练,每个节点有 4 个 GPU。

现在我们向 SLURM 提交一个作业,它有以下标志:

# SLURM SUBMIT SCRIPT
#SBATCH --gres=gpu:4
#SBATCH --nodes=32
#SBATCH --ntasks-per-node=4
#SBATCH --mem=0
#SBATCH --time=02:00:00 # activate conda env
conda activate my_env # run script from above
python gan.py 

我们的模型将使用所有 128 个 GPU 进行训练!

在后台,Lightning 将使用 DistributedDataParallel,并配置一切为您正确工作。分布式数据并行在本教程中有深入解释。

在高层次上,DistributedDataParallel 为每个 GPU 提供数据集的一部分,在该 GPU 上初始化模型,并在训练期间仅同步模型之间的梯度。所以,更像是“分布式数据集+梯度同步”。

但是我没有 128 个 GPU

别担心!你的模型不需要改变。只需从训练器中删除 nb_gpu_nodes 参数,即可使用机器上的所有 4 个 gpu:

然后在配有 4 个 GPU 的机器上运行脚本。

完整的代码可在这里。

这段 GAN 代码改编自这个棒极了的 GAN 库,并被重构为使用 PyTorch Lightning

通过 YARN + Spark +多线程训练多个机器学习模型并并行运行数据任务

原文:https://towardsdatascience.com/how-to-train-multiple-machine-learning-models-and-run-other-data-tasks-in-parallel-by-combining-2fa9670dd579?source=collection_archive---------14-----------------------

利用大规模计算资源,允许单个数据科学家并行执行数十或数百个大数据任务,扩展数据科学扩展和自动化的极限

图片:Freepik.com

摘要

本文的目的是展示单个数据科学家如何在不使用复杂部署框架的情况下同时启动数十或数百个数据科学相关任务(包括机器学习模型训练)。事实上,这些任务可以从一个“数据科学家”友好的界面启动,即一个可以从 Jupyter、Spyder 或 Cloudera Workbench 等交互式 shell 中运行的 Python 脚本。为了处理大量数据,任务本身可以并行化,这样我们就可以有效地增加第二层并行性。

这篇文章是写给谁的?

  • 希望用更少的时间做更多的工作的数据科学家,通过利用大规模计算资源(例如集群或公共云),可能通过 YARN 与其他用户共享。要理解这篇文章,你需要很好的 Python 知识,Spark 的工作知识,至少对 Hadoop YARN 架构和 shell 脚本有基本的了解;
  • 支持数据科学家利用可用计算能力和操作大规模数据的机器学习工程师

介绍

数据科学和自动化

“数据科学”和“自动化”是两个总是联系在一起的词,因为机器学习的关键目标之一是让机器比人类更快、更低成本和/或更好地执行任务。

自然,对于一个组织来说,在应该开发和维护自动化工作系统的技术人员(数据科学家、数据工程师、DevOps 工程师、软件工程师和其他人)身上花费比在人工工作的人员身上花费更多是没有意义的。因此,不足为奇的是,一个反复出现的讨论是我们可以在多大程度上自动化数据科学团队本身的工作,例如通过自动化机器学习。

为了实现经济高效的数据科学自动化,必须能够利用公共云或私有云的计算能力;毕竟,与高技能技术人员的成本相比,硬件的成本相当低。虽然实现这一点的技术肯定是可用的,但许多组织最终都面临着“大数据软件工程师与数据科学家的难题”,或者更准确地说,两者之间的巨大差异

  • “大数据软件工程师技能”,即在复杂的计算环境中处理大量数据,并以可靠的方式运行这些流程以及其他并发流程所必需的技能
  • “数据科学家技能”,即,将算法和数学应用于数据以提取从商业角度有价值的见解所必需的技能

Harnessing computational power is key to automating data science work

图片:Freepik.com

一些组织会让“数据科学家”负责在某种“受控分析环境”中开发分析模型,在这种环境中,人们不需要过多考虑底层计算资源或与其他流程共享资源,而让“大数据软件工程师”负责对数据科学家开发的模型的“生产就绪”版本进行编码,并将它们部署到生产中。这种设置导致了明显的低效,例如:

  1. 由于没有利用大规模数据和计算资源,数据科学家正在开发次优模型。在一些组织中,数据科学家甚至最终使用 Pandas/Scikit-Learn 等单节点框架,并将其模型完全基于通过采样或过度设计的功能获得的小数据集;
  2. 开发的模型在分析环境中表现良好,但在生产环境中表现不佳或完全无法运行;
  3. 评估业务价值的产生、识别和修复问题以及进行迭代改进的难度,因为一旦模型投入生产,数据科学家最终会严重失去对分析过程的监督。

不同的组织以不同的方式处理这种情况,要么迫使大数据软件工程师和数据科学家学习“其他角色”的技能,要么通过创造一种“第三角色”,名为“机器学习工程师”,以弥合两种角色之间的差距。

但事实是,现在有更多的资源允许没有特殊软件工程技能的数据科学家在“现实”环境中工作,即在计算复杂性方面类似于生产。Spark MLLib、Kubeflow、Tensorflow-GPU、MMLSpark 等机器学习库允许数据准备和模型训练分布在多个 CPU、GPU 或两者的组合上;同时,Apache Hadoop YARN 和 Kubernetes 等框架允许数据科学家使用相同的计算资源同时工作,只需了解底层服务器基础架构的基本概念,如可用 CPU/GPU 的数量和可用内存。

本文的目的是提供一个示例,说明如何利用这些库和框架以及大量(但共享的)计算资源来自动化数据科学模型的创建和测试。

从单个大规模并行任务到大规模并行运行任务

像 Spark 和 Kubeflow 这样的框架可以轻松地在 GPU 和/或数百个 CPU 之间分发大数据任务,如特征处理或机器学习模型训练,而无需详细了解服务器架构。另一方面,并行执行任务,而不是单独的并行任务,并不是无缝的。当然,对于一个数据科学家来说,在 Jupyter 中同时处理两三个 PySpark 会话并不难,但是为了自动化,我们可能会对同时运行几十个甚至几百个任务感兴趣,所有任务都以编程的方式指定,并尽量减少人工干预。

自然,有人会问为什么要并行运行任务,而不是简单地增加每个任务的内核数量,并使每个任务在更短的时间内运行。有两个原因:

  1. 处理速度通常与内核数量不成比例。例如,在训练机器学习模型的情况下,如果数据不够大,通过将内核数量从 10 个增加到 100 个,计算时间可能没有改善,有时计算时间甚至可能由于处理和通信开销而增加,以及无法利用一些机器学习库中可用的高效单处理器实现
  2. 机器学习算法模型的准确性也可能由于并行化而降低,因为这些算法通常依赖次优试探法来以分布式方式运行,例如数据分割和投票

使用部署工具(如 Airflow)运行任意复杂、动态定义和高度自动化的数据分析管道(涉及并行任务)当然是可能的。然而,这些工具需要低级别的脚本和配置,不适合数据科学家每天进行的快速“试错”实验,他们通常习惯于在 Jupyter 或 Spyder 等交互式 shells 中快速尝试和反复尝试想法。此外,让我们回到之前提到的“大数据软件工程师与数据科学家”难题,组织可能更喜欢数据科学家将时间花在数据实验和产生商业价值上,而不是沉浸在低级别的实施或部署中。

你将从这篇文章中学到什么?

在本文中,我将展示我们如何利用 Apache Hadoop YARN,通过 Python 多线程,直接从任何 Python 代码(包括来自 Jupyter 等交互式 Python shells 的代码)同时启动和监控 Hadoop 集群中的多个作业(包括单独并行的 Spark 作业)。虽然该示例将包括并行训练多个机器学习模型,但我将提供一个通用框架,可用于启动任意数据任务,如特征工程和模型度量计算。

多模型并行训练的一些应用是:

  • 超参数调整:对于相同的训练数据集,使用不同的模型类型(比如逻辑回归、梯度提升和多层感知器)以及不同的超参数配置同时进行训练,以便尽快找到最佳的模型类型/超参数集;
  • 多标签分类:并行训练多个二元/多类分类模型,其中每个模型训练任务将使用不同的列作为标签列,这样得到的模型组合将有效地成为多标签分类器;
  • 特征缩减:对于先前排序的特征的投票,训练多个模型,每个模型仅使用前 N 个排序的特征作为特征列,N 在训练任务中变化。

技术概述

在我们的框架中,我将调用主任务,即创建并行运行的附加任务的 Python 代码,作为控制器任务,而由控制器任务启动的任务作为从属任务。 (为了避免混淆,我故意避免使用“工人”这个表达,因为在 Spark 中,“工人”是 Spark 执行者的同义词)

控制器任务负责:

  • 定义应该同时运行多少个从属任务,以及在其中一个任务失败的情况下做什么;
  • 创建从属任务,将输入传递给每个任务,并获取它们的输出(如果有的话);
  • 生成输入并处理从属任务的输出。

YARN 的一个有趣的方面是,它允许 Spark 同时用于控制器和从属任务。尽管两者都不是必需的,但只要我们有足够的计算资源,我们就可以处理任意大的数据集,而无需担心数据工程。即控制器任务可以在客户端模式下运行 Spark,从属任务可以在集群模式下运行 Spark:

  • 在客户端模式下,Spark 驱动程序运行在控制器的 Python 代码正在运行的环境中(我们称之为客户端环境 ) 允许使用本地安装的交互式外壳,如 Jupyter,而 Spark 执行器运行在 YARN 管理的 Hadoop 集群中,驱动程序和执行器之间的交互通过也运行在 Hadoop 集群中的名为 Application Master 的第三类进程进行;
  • 集群模式中,驱动程序和执行器都运行在 YARN 管理的 Hadoop 集群中。请注意,没有什么可以阻止我们让控制器任务也以集群模式运行,但是交互式 shells 不能以这种方式使用。

该框架如下图所示:

Illustration of the parallelisation framework

关于上面的例子,有两点需要注意:

  • 虽然在示例中,控制器任务也是 Spark 进程的驱动程序(并因此通过 YARN 应用程序主机与 Hadoop 集群中的执行器相关联),但这不是必需的,尽管这在例如我们想要在部署到从属任务之前对数据进行一些预处理时是有用的;
  • 虽然从属任务不需要使用 Spark 并行化,但我们将使用spark-submit命令来启动它们,这样它们将始终有一个 Spark 驱动程序,尽管不一定是 Spark 执行器。这就是上面过程 3 的情况。

技术实现

作为 Spark 作业执行从属任务

在深入研究并行化之前,我将首先解释如何从用 Python 编写的控制器任务执行从属任务。如前所述,我们将使用 Apache Spark 安装中包含的spark-submit shell 脚本这样做,这样从属任务在技术上就是一个 Spark 作业,尽管它不一定有我之前提到的执行器或 Spark 代码。

原则上,我们可以通过简单地调用os.system函数从 Python 中使用spark-submit,这允许我们从 Python 中执行一个 shell 命令。在实践中,我们需要能够调试和监控任务;为此,最好使用优秀的subprocess图书馆。一个例子:

import json
import subprocessspark_config_cluster_path = "/home/edsonaoki/spark_config_cluster"
app_name = "some_model_training"
spark_config = {"spark.jars.packages" : "com.microsoft.ml.spark:mmlspark_2.11:0.18.1","spark.dynamicAllocation.enabled": "false","spark.executor.instances": "10","spark.yarn.dist.files": "/home/edsonaoki/custom_packages.tar"
}
command = "lightgbm_training.py "\"hdfs://user/edsonaoki/datasets/input_data.parquet "\"hdfs://user/edsonaoki/models"spark_submit_cmd = “SPARK_CONF_DIR=%s spark-submit -name %s %s %s"% (spark_config_cluster_path, app_name, " ".join(['-conf %s="%s"' % (key, value) for key, value in   spark_config.items()]),command)
cmd_output = subprocess.Popen(spark_submit_cmd, shell=True,stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True)for line in cmd_output.stdout:print(line)
cmd_output.communicate()

在代码的开始,我设置了包含集群模式基本 Spark 配置的路径,该路径稍后用于更改SPARK_CONF_DIR 环境变量。如果控制器任务被配置为在客户机模式下的 Spark 中运行,这实际上是一个至关重要的步骤,因为集群模式的 Spark 配置通常不同于客户机模式。

如果你不太了解如何在集群模式下配置 Spark,可以从复制现有的SPARK_CONF_DIR开始。在spark-defaults.conf文件中,我们需要

spark.submit.deployMode=cluster

代替

spark.submit.deployMode=client

某些配置选项,如spark.yarn.rmProxy.enabledspark.driver.options.*选项需要禁用,因为在集群模式下运行 Spark 时,驱动程序没有特定于网络的配置。如有疑问,检查纱线文件上的火花。当然,如果控制器任务也在集群模式下运行 Spark,就不需要有单独的配置。

现在,看看后续步骤:

app_name = "some_model_training"
spark_config = {"spark.jars.packages" : "com.microsoft.ml.spark:mmlspark_2.11:0.18.1","spark.dynamicAllocation.enabled": "false","spark.executor.instances": "10","spark.yarn.dist.files": "/home/edsonaoki/custom_packages.tar"
}
command = "lightgbm_training.py "\"hdfs://user/edsonaoki/datasets/input_data.parquet"\"hdfs://user/edsonaoki/models"
spark_submit_cmd = “SPARK_CONF_DIR=%s spark-submit -name %s %s %s"% (spark_config_cluster_path, app_name, " ".join(['-conf %s="%s"' % (key, value) for key, value in   spark_config.items()]),command)

在这里,我设置了应用程序名、额外的 Spark 配置选项和由spark-submit脚本执行的命令。这些很容易理解,但是应用程序名称在我们的例子中特别重要——我们稍后会明白为什么。我们还通过spark.yarn.dist.files配置参数提交一个定制的 Python 包,正如我将在后面展示的,这非常方便,因为从属任务在 Hadoop 集群中运行,因此无法访问本地(客户端)环境中可用的 Python 函数。

还要注意,我指定了两个 HDFS 路径作为lightgbm_training.py Python 脚本(从属任务的代码)的参数,原因与上面类似:由于 Python 脚本将在 Hadoop 集群中运行,它将无法访问客户端环境的文件系统中的任何文件,因此要在控制器或从属任务之间交换的任何文件必须通过spark.yarn.dist.files显式提交,或者放入共享文件系统,如 HDFS 或 AWS S3。

准备好 spark-submit shell 命令行后,我们准备使用subprocess.Popen命令来执行它:

cmd_output = subprocess.Popen(spark_submit_cmd, shell=True,stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, universal_newlines=True)

我们设置shell=True让 Python 启动一个单独的 shell 进程来执行命令,而不是试图直接从 Python 进程启动spark-submit。虽然在使用子进程库时设置shell=False通常更好,但是这样做限制了命令行格式,在我们的情况下不可行。

stdoutstderrbufsizeuniversal_newlines参数用于处理 shell 命令在执行期间发出的输出(STDOUT)和错误消息(STDERR)。当我们并行执行多个从属任务时,我们可能希望忽略所有的执行时间消息,因为它们会非常混乱,而且无论如何都无法解释。这对于节省内存也很有用,原因我们将在后面解释。但是,在尝试并行运行多个任务之前,最好首先确保每个单独的任务都能正常工作,方法是运行一个启用了输出/错误消息的从属任务。

在这个例子中,我设置了stdout=subprocess.PIPEstderr=subprocess.STDOUTbufsize=1universal_newlines=True,它们基本上将所有 shell 命令输出指向一个名为subprocess.PIPE的先进先出(FIFO)队列。

请注意,在集群模式下运行 Spark 作业时,subprocess.PIPE只能访问来自 YARN 应用主机的消息,而不能访问驱动程序或执行器。要检查驱动程序和执行器消息,您可以通过浏览器查看 Hadoop 集群 UI,或者在执行后检索驱动程序和执行器日志,我将在后面介绍。此外,如果在log4j.properties文件(位于 Spark 配置中)中启用了文件记录,来自应用程序主机的消息将被记录到一个文件中,而不是直接发送到subprocess.PIPE,因此如果需要,请禁用文件记录。

最后,为了在 Python 脚本的输出中显示输出/错误消息,我继续上面的代码,如下所示:

for line in cmd_output.stdout:print(line)
cmd_output.communicate()

cmd_output.communicate()的目的是在subprocess.PIPE为空后等待流程结束,即不再有从属任务的输出写入其中。强烈建议在调用上述cmd_output.communicate()方法之前读取整个队列,以防止队列大小增加和浪费内存。

在不使用调试消息的情况下监控从属任务

正如我前面提到的,当我们并行运行任务时,我们不希望显示调试消息;此外,如果大量任务同时向内存中的 FIFO 队列发送消息,内存使用率将会增加,因为从队列中读取消息的速度赶不上消息生成的速度。从调用spark-submit开始,上一节中没有调试的代码版本如下:

cmd_output = subprocess.Popen(spark_submit_cmd, shell=True,stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)def getYARNApplicationID(app_name):state = 'RUNNING,ACCEPTED,FINISHED,KILLED,FAILED'out = subprocess.check_output(["yarn","application","-list","-appStates",state], stderr=subprocess.DEVNULL, universal_newlines=True)lines = [x for x in out.split("\n")]application_id = ''for line in lines:if app_name in line:application_id = line.split('\t')[0]breakreturn application_idmax_wait_time_job_start_s = 120
start_time = time.time()
while yarn_application_id == '' and time.time()-start_time\< max_wait_time_job_start_s:yarn_application_id = getYARNApplicationID(app_name)cmd_output.wait()if yarn_application_id == '':raise RuntimeError("Couldn't get yarn application ID for application %s" % app_name)

代码像以前一样通过启动从属任务开始,但是禁用了调试:

cmd_output = subprocess.Popen(spark_submit_cmd, shell=True,stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

由于在进程运行时没有调试消息显示,我们使用cmd_output.wait而不是cmd_output.communicate()来等待任务完成。注意,虽然我们看不到应用程序主的消息,但我们仍然可以通过 Hadoop 集群 UI 在运行时调试 Spark 作业的驱动程序和执行器。

然而,我们仍然需要能够从编程的角度监控任务;更具体地说,控制器任务需要知道从属任务何时完成,是否成功,并在失败时采取适当的行动。为此,我们可以使用我们在开始时设置的应用程序名称:

app_name = "some_model_training"

YARN 可以使用应用程序名来检索 YARN 应用程序 ID,这允许我们检索从属任务的状态和其他信息。同样,我们可以借助子进程库来定义一个函数,该函数可以从应用程序名称中检索应用程序 ID:

def getYARNApplicationID(app_name):state = 'RUNNING,ACCEPTED,FINISHED,KILLED,FAILED'out = subprocess.check_output(["yarn","application","-list","-appStates",state], stderr=subprocess.DEVNULL, universal_newlines=True)lines = [x for x in out.split("\n")]application_id = ''for line in lines:if app_name in line:application_id = line.split('\t')[0]breakreturn application_id

注意到getYARNApplicationID解析了yarn application -list shell 命令的输出。根据您的 Hadoop 版本,输出格式可能略有不同,解析需要相应调整。如果有疑问,可以在终端中运行以下命令来测试格式:

$ yarn application -list -appStates RUNNING,ACCEPTED,FINISHED,KILLED,FAILED

棘手的是,只有当应用程序名称在 Hadoop 集群中是唯一的时,这种方法才有效。因此,您需要确保您正在创建一个唯一的应用程序名称,例如通过包含时间戳、随机字符串、您的用户 ID 等。可选地,当试图解析yarn application -list的输出时,您也可以添加其他过滤器,例如,用户 ID、纱线队列名称或一天中的时间。

由于 Spark 作业在使用spark-submit启动后需要一些时间在 YARN 中注册,所以我实现了这个循环:

max_wait_time_job_start_s = 120
start_time = time.time()
while yarn_application_id == '' and time.time()-start_time\< max_wait_time_job_start_s:yarn_application_id = getYARNApplicationID(app_name)

其中max_wait_time_job_start_s是等待注册的时间,以秒为单位,可能需要根据您的环境进行调整。

的意思

if yarn_application_id == '':raise RuntimeError("Couldn't get yarn application ID for"\" application %s" % app_name)

是直白的;如果没有应用程序 ID,这意味着 Spark 作业没有成功启动,我们需要抛出一个异常。这也可能表明我们需要增加max_wait_time_job_start_s,或者改变在getYARNApplicationID内部解析yarn application -list输出的方式。

检查从属任务的最终状态

从属任务完成后,可以按如下方式检查其最终状态:

def getSparkJobFinalStatus(application_id):out = subprocess.check_output(["yarn","application","-status",application_id], stderr=subprocess.DEVNULL, universal_newlines=True)status_lines = out.split("\n")state = ''for line in status_lines:if len(line) > 15 and line[1:15] == "Final-State : ":state = line[15:]breakreturn statefinal_status = getSparkJobFinalStatus(yarn_application_id)

同样,您可能需要根据您的 Hadoop 版本来调整对yarn application -status的解析。如何处理最终状态完全取决于您,但一种可能是将 Spark 作业的驱动程序和执行程序日志存储在一个文件中,并引发一个异常。例如:

log_path = "/home/edsonaoki/logs/%s_%s.log" % (app_name, yarn_application_id)if final_status != "SUCCEEDED":cmd_output = subprocess.Popen(["yarn","logs", "-applicationId",yarn_application_id],stdout=subprocess.PIPE, stderr=subprocess.STDOUT,bufsize=1, universal_lines=True)with open(log_path, "w") as f:for line in cmd_output.stdout:f.write(line)print("Written log of failed task to %s" % log_path)cmd_output.communicate()raise RuntimeError("Task %s has not succeeded" % app_name)

使用多线程并行执行从属任务

如果不明显,在尝试并行执行从属任务之前,确保在没有并行化的情况下测试尽可能多的任务,因为调试并行任务会非常困难。

为了执行并行化,我们将使用 Python 的concurrent库。并发库使用多线程而非多处理;即线程在同一处理器中运行,从而从控制器任务的角度来看,不存在真正的并行处理。然而,由于控制器任务中启动的线程在等待从属任务完成时处于 I/O 模式(未阻塞),因此多个从属任务可以异步启动,这样它们将实际上在 Hadoop 集群中并行运行。虽然我们在技术上可以使用multiprocessing库而不是并发库来实现控制器任务端的并行性,但我建议不要这样做,因为这将大大增加客户端环境中的内存消耗,几乎没有任何好处——其想法是“艰难的处理”在 Hadoop 集群中完成。

当我们启动一个 Spark 作业时,我们通常会意识到集群环境中的处理和内存约束,尤其是在共享环境的情况下,并使用配置参数(如spark.executor.memoryspark.executor.instances)来控制任务的处理和内存消耗。我们的情况也需要这样做;我们需要根据集群中计算资源的可用性来限制同时执行的从属任务的数量,这样当我们达到这个限制时,一个从属任务只能在另一个任务完成后开始。

并发包提供了futures.ThreadPoolExecutor类,它允许我们启动多个线程并等待它们完成。该类还允许我们通过max_workers参数来限制正在进行活动处理(即没有被 I/O 阻塞)的线程数量。然而,正如我之前提到的,当从属任务运行时,控制器任务中的一个线程被视为被 I/O 阻塞,这意味着max_workers不会有效地限制线程的数量。因此,所有从属任务将几乎同时提交,Hadoop 集群可能会过载。

这可以通过如下修改futures.ThreadPoolExecutor类很容易地解决:

import concurrent.futures
from queue import Queueclass ThreadPoolExecutorWithQueueSizeLimit(concurrent.futures.ThreadPoolExecutor): def __init__(self, maxsize, *args, **kwargs):super(ThreadPoolExecutorWithQueueSizeLimit, self).__init__(*args, **kwargs)self._work_queue = Queue(maxsize=maxsize)

这个新类ThreadPoolExecutorWithQueueSizeLimit的工作方式与futures.ThreadPoolExecutor完全一样,但它不允许在任何时间点存在超过maxsize个线程,这有效地限制了 Hadoop 集群中同时运行的从属任务的数量。

我们现在需要定义一个函数,包含线程的执行代码,它可以作为参数传递给类ThreadPoolExecutorWithQueueSizeLimit。基于前面在不调试消息的情况下从 Python 执行从属任务的代码,我给出了下面的通用线程执行函数:

def executeThread(app_name, spark_submit_cmd, error_log_dir, max_wait_time_job_start_s=120):cmd_output = subprocess.Popen(spark_submit_cmd, shell=True,stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)start_time = time.time()while yarn_application_id == '' and time.time()-start_time\< max_wait_time_job_start_s:yarn_application_id = getYARNApplicationID(app_name)cmd_output.wait()if yarn_application_id == '':raise RuntimeError("Couldn't get yarn application ID for"\ "application %s" % app_name)final_status = getSparkJobFinalStatus(yarn_application_id)log_path = %s/%s_%s.log" % (error_log_dir, app_name, yarn_application_id)if final_status != "SUCCEEDED":cmd_output = subprocess.Popen(["yarn","logs", "-applicationId",yarn_application_id],stdout=subprocess.PIPE, stderr=subprocess.STDOUT,bufsize=1, universal_lines=True)with open(log_path, "w") as f:for line in cmd_output.stdout:f.write(line)print("Written log of failed task to %s" % log_path)cmd_output.communicate()raise RuntimeError("Task %s has not succeeded" % app_name)return True

如您所见,该函数使用了之前定义的函数getYARNApplicationIDgetSparkJobFinalStatus,应用程序名称、spark-submit命令行和存储错误日志的目录作为参数传递给该函数。

请注意,如果找不到纱线应用程序 ID,或者 Spark 作业的状态不成功,该函数会引发一个异常。但是根据具体情况,我们可能只是希望函数返回一个假值,这样控制器任务就知道这个特定的从属任务没有成功,需要再次执行,而不需要再次运行已经成功的任务。在这种情况下,我们只需要替换线

raise RuntimeError("Couldn't get yarn application ID for application %s" % app_name)

raise RuntimeError("Task %s has not succeeded" % app_name)

随着

return False

下一步是创建一个通用代码来启动线程并等待它们完成,如下所示:

def executeAllThreads(dict_spark_submit_cmds, error_log_dir, dict_success_app=None):if dict_success_app is None:dict_success_app = {app_name: False for app_name in dict_spark_submit_cmds.keys()}with ThreadPoolExecutorWithQueueSizeLimit(maxsize=max_parallel, max_workers=max_parallel) as executor:future_to_app_name = {executor.submit(executeThread, app_name, spark_submit_cmd, error_log_dir,): app_name for app_name, spark_submit_cmd in                 dict_spark_submit_cmds.items() if dict_success_app[app_name] == False}for future in concurrent.futures\.as_completed(future_to_app_name):app_name = future_to_app_name[future]try:dict_success_app[app_name] = future.result()except Exception as exc:print('Subordinate task %s generated exception %s' %(app_name, exc))raisereturn dict_success_app

该函数的强制参数是:

  • 以应用程序名作为关键字,以相应的作业提交命令行作为值的字典;
  • 存储错误日志的目录。

该函数的输出也是一个字典,包含每个从属任务的返回值(真或假),按应用程序名称进行索引。可选参数是dict_success_app,如果我们只想运行尚未成功的从属任务,它可以是函数先前执行的返回值。稍后我将展示如何实现这一点。

为了方便读者,我将并行化框架的完整代码汇总如下:

import subprocess
import concurrent.futures
from queue import Queueclass ThreadPoolExecutorWithQueueSizeLimit(concurrent.futures.ThreadPoolExecutor): def __init__(self, maxsize, *args, **kwargs):super(ThreadPoolExecutorWithQueueSizeLimit, self).__init__(*args, **kwargs)self._work_queue = Queue(maxsize=maxsize)def getYARNApplicationID(app_name):state = 'RUNNING,ACCEPTED,FINISHED,KILLED,FAILED'out = subprocess.check_output(["yarn","application","-list","-appStates",state], stderr=subprocess.DEVNULL, universal_newlines=True)lines = [x for x in out.split("\n")]application_id = ''for line in lines:if app_name in line:application_id = line.split('\t')[0]breakreturn application_iddef getSparkJobFinalStatus(application_id):out = subprocess.check_output(["yarn","application","-status",application_id], stderr=subprocess.DEVNULL, universal_newlines=True)status_lines = out.split("\n")state = ''for line in status_lines:if len(line) > 15 and line[1:15] == "Final-State : ":state = line[15:]breakreturn statedef executeThread(app_name, spark_submit_cmd, error_log_dir,max_wait_time_job_start_s = 120):cmd_output = subprocess.Popen(spark_submit_cmd, shell=True,stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)start_time = time.time()while yarn_application_id == '' and time.time()-start_time\< max_wait_time_job_start_s:yarn_application_id = getYARNApplicationID(app_name)cmd_output.wait()if yarn_application_id == '':raise RuntimeError("Couldn't get yarn application ID for"\" application %s" % (app_name))# Replace line above by the following if you do not# want a failed task to stop the entire process:# return Falsefinal_status = getSparkJobFinalStatus(yarn_application_id)log_path = %s/%s_%s.log" % (error_log_dir, app_name, yarn_application_id)if final_status != "SUCCEEDED":cmd_output = subprocess.Popen(["yarn","logs", "-applicationId",yarn_application_id],stdout=subprocess.PIPE, stderr=subprocess.STDOUT,bufsize=1, universal_lines=True)with open(log_path, "w") as f:for line in cmd_output.stdout:f.write(line)print("Written log of failed task to %s" % log_path)cmd_output.communicate()raise RuntimeError("Task %s has not succeeded" % app_name)# Replace line above by the following if you do not# want a failed task to stop the entire process:# return Falsereturn Truedef executeAllThreads(dict_spark_submit_cmds, error_log_dir, dict_success_app=None):if dict_success_app is None:dict_success_app = {app_name: False for app_name in dict_spark_submit_cmds.keys()}with ThreadPoolExecutorWithQueueSizeLimit(maxsize=max_parallel, max_workers=max_parallel) as executor:future_to_app_name = {executor.submit(executeThread, app_name, spark_submit_cmd, error_log_dir,): app_name for app_name, spark_submit_cmd in                 dict_spark_submit_cmds.items() if dict_success_app[app_name] == False}for future in concurrent.futures\.as_completed(future_to_app_name):app_name = future_to_app_name[future]try:dict_success_app[app_name] = future.result()except Exception as exc:print('Subordinate task %s generated exception %s' %(app_name, exc))raisereturn dict_success_app

示例:使用梯度增强二元分类器的具有 2 级并行化的多标签模型训练

在这个例子中,我将展示如何使用上述框架来并行训练具有数百个标签的多标签分类器。基本上,我们将并行训练多个二元分类器,其中每个二元模型的训练本身通过 Spark 并行化。各个二元分类器是使用流行的 LightGBM 包的 Spark 版本训练的梯度提升模型,包含在Microsoft Machine Learning for Spark(MMLSpark)库中。

设置控制器任务

通过使用上面的框架,控制器任务只需要做另外两件事情:

  1. 在调用executeAllThreads函数之前,为每个下级任务设置应用名称和 spark-submit 命令;
  2. executeAllThreads函数返回后,检查哪些从属任务已经成功,并适当地处理它们的输出。

对于第一部分,我们可以从前面的例子开始,在这个例子中,我们提交了一个独立的从属作业:

spark_config_cluster_path = "/home/edsonaoki/spark_config_cluster"
app_name = "some_model_training"
spark_config = {"spark.jars.packages" : "com.microsoft.ml.spark:mmlspark_2.11:0.18.1","spark.dynamicAllocation.enabled": "false","spark.executor.instances": "10","spark.yarn.dist.files": "/home/edsonaoki/custom_packages.tar"
}command = "lightgbm_training.py "\"hdfs://user/edsonaoki/datasets/input_data.parquet"\"hdfs://user/edsonaoki/models"spark_submit_cmd = "SPARK_CONF_DIR=%s spark-submit -name %s %s %s"% (spark_config_cluster_path, app_name, " ".join(['-conf %s="%s"' % (key, value) for key, value in   spark_config.items()]),command)

我们需要什么来调整多标签分类的代码?首先,由于已经提到的原因,应用程序名称需要完全唯一。假设数据集input_data.parquet的标签列包含在变量lst_labels中,确保每个从属任务的唯一应用程序 id 的一种方法如下:

import time
curr_timestamp = int(time.time()*1000)
app_names = ["model_training_%s_%d" % (label,curr_timestamp) for label in lst_labels]

这确保了应用程序名称是唯一的,只要控制器任务不会在同一毫秒内启动多次(当然,如果我们有一个共享的 YARN 集群,可能需要其他的修改来使应用程序名称唯一,比如将用户名添加到应用程序名称中)。

我们还没有讨论lightgbm_training.py中包含的下级任务代码是什么样子,但是让我们假设它:

  • 使用与 Spark 作业一起提交的custom_packages.tar文件中包含的函数,根据标签列对训练数据执行一些预处理(如数据集平衡)
  • 基于“功能”列和“标签”列定型模型
  • 将训练好的模型保存在 HDFS 系统中

在这种情况下,控制器任务需要通过命令行参数向lightgbm_training.py传递训练数据集的 HDFS 路径、存储训练模型的 HDFS 路径以及用于每个从属任务的标签。这可以按如下所示完成:

dict_spark_submit_cmds = dict()
for i in range(len(lst_labels)):command = "lightgbm_training.py "\    "hdfs://user/edsonaoki/datasets/input_data.parquet "\"hdfs://user/edsonaoki/models "\+lst_labels[i]spark_submit_cmd = “SPARK_CONF_DIR=%s spark-submit -name %s "\"%s %s" % (spark_config_cluster_path, app_names[i], " ".join(['-conf %s="%s"' % (key, value) for key, value in   spark_config.items()]),command)dict_spark_submit_cmds[app_names[i]] = spark_submit_cmd

当然,还有许多其他方式来定制从属任务。我们可能想要使用不同的模型训练超参数、不同的数据集、不同的 Spark 配置,或者甚至为每个从属任务使用不同的 Python 脚本。我们允许spark-submit命令行对于每个子任务都是唯一的,这一事实允许完全的定制。

为了方便读者,我把调用executeAllThreads之前和之前的控制器任务代码放在一起:

import time
spark_config_cluster_path = "/home/edsonaoki/spark_config_cluster"curr_timestamp = int(time.time()*1000)
app_names = ["model_training_%s_%d" % (label,curr_timestamp) for label in lst_labels]spark_config = {"spark.jars.packages" : "com.microsoft.ml.spark:mmlspark_2.11:0.18.1","spark.dynamicAllocation.enabled": "false","spark.executor.instances": "10","spark.yarn.dist.files": "/home/edsonaoki/custom_packages.tar"
}dict_spark_submit_cmds = dict()
for i in range(len(lst_labels)):command = "lightgbm_training.py "\    "hdfs://user/edsonaoki/datasets/input_data.parquet "\"hdfs://user/edsonaoki/models "\+lst_labels[i]spark_submit_cmd = “SPARK_CONF_DIR=%s spark-submit -name %s "\"%s %s" % (spark_config_cluster_path, app_names[i], " ".join(['-conf %s="%s"' % (key, value) for key, value in   spark_config.items()]),command)dict_spark_submit_cmds[app_names[i]] = spark_submit_cmdexecuteAllThreads(dict_spark_submit_cmds, "/home/edsonaoki/logs")

对于第二部分,即控制器任务从executeAllThreads返回后应该做什么,假设成功的任务已经将训练好的模型保存在 HDFS 系统中,我们可以打开这些文件并适当地处理它们,例如将模型应用于一些适当的验证数据集,生成图并计算性能指标。

如果我们使用前面介绍的并行化框架,就不会有“不成功的从属任务”,因为任何失败都会导致出现异常。但是如果我们修改executeThread以在任务失败的情况下返回 False,我们可以将返回的dict_success_app字典存储在 JSON 或 Pickle 文件中,这样我们可以在以后调查并修复失败的任务。最后,我们可以使用可选参数dict_success_app再次调用executeAllThreads,这样我们只重新运行失败的任务。

设置从属任务

现在让我们在lightgbm_training.py脚本中编写从属任务的代码。第一步是读取脚本的输入参数,即 HDFS 文件系统中训练数据集的路径、存储模型的路径和标签列的名称:

import sys
train_data_path = sys.argv[1]
model_path = sys.argv[2]
label = sys.argv[3]

因为我们使用的是 LightGBM 的 Spark 版本,所以我们需要创建一个 Spark 会话,如下所示:

from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
spark.sparkContext.addPyFile("./custom_packages.tar")

注意,不需要为 Spark 会话设置任何配置,因为它已经在控制器任务提交的命令行中完成了。此外,由于我们向 Spark 作业显式提交了一个定制的 Python 包custom_packages.tar,我们需要使用addPyFile函数来使包的内容在我们的代码中可用,因为该包不包含在 Hadoop 集群的PYTHONPATH环境变量中。

在从属任务中进行实际处理的代码非常简单。从属任务将读取训练数据,调用custom_packages.tar(比如custom_data_preprocessing.datasetBalancing)内部的一些预处理函数,进行模型训练,并将训练好的模型以唯一的名称保存回 HDFS 文件系统中:

from custom_data_preprocessing import datasetBalancing
from mmlspark import LightGBMClassifierdf_train_data = spark.read.parquet(train_data_path)
df_preproc_data = datasetBalancing(df_train_data, label)
untrained_model = LightGBMClassifier(learningRate=0.3,numIterations=150,numLeaves=45)\.setFeaturesCol("features")\.setLabelCol(label)
trained_model = untrained_model.fit(df_preproc_data)
trained_model.write().overwrite()\  .save(model_path + "/trained_model_%s.mdl" % label)spark.stop()

为了方便读者,将lightgbm_training.py的完整代码汇总如下:

import sys
train_data_path = sys.argv[1]
model_path = sys.argv[2]
label = sys.argv[3]from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
spark.sparkContext.addPyFile("./custom_packages.tar")from custom_data_preprocessing import datasetBalancing
from mmlspark import LightGBMClassifierdf_train_data = spark.read.parquet(train_data_path)
df_preproc_data = datasetBalancing(df_train_data, label)
untrained_model = LightGBMClassifier(learningRate=0.3,numIterations=150,numLeaves=45)\.setFeaturesCol("features")\.setLabelCol(label)
trained_model = untrained_model.fit(df_preproc_data)
trained_model.write().overwrite()\  .save(model_path + "/trained_model_%s.mdl" % label)spark.stop()

结论

很容易看出,除了多机器学习模型训练之外,本文中提出的框架可以重复用于各种任务。一个可能出现的问题是,它是否可以用于不同的集群环境,例如在 Mesos 上使用 Spark 而不是在 YARN 上使用 Spark。我相信是这样的,但是需要做一些修改,因为给出的代码严重依赖于yarn命令来监控从属任务。

通过使用这个框架,数据科学家可以将更多的时间集中在设计数据任务上,而不是手动执行数十或数百个小变化。另一个优势是,通过利用并行化,任务可以在更短的时间内完成,或者从不同的角度完成,而不需要多名数据科学家同时工作,在相同的时间内完成任务。

当然,本文只是介绍了许多改进数据科学自动化的方法中的一种。意识到数据科学家和其他熟练技术专业人员的时间非常宝贵的组织,肯定会找到越来越多的方法来帮助这些专业人员专注于更高层次的问题。

如何训练 StyleGAN 生成逼真的人脸

原文:https://towardsdatascience.com/how-to-train-stylegan-to-generate-realistic-faces-d4afca48e705?source=collection_archive---------5-----------------------

为什么 StyleGAN 在人脸生成方面优于其他模型,以及如何训练自己的 StyleGAN

Sample output during my training of StyleGAN

生成对抗网络(GAN)是 Ian Goodfellow 和他的同事在 2014 年为生成建模推出的一种架构,它使用一个模型来生成模仿现有数据集的新样本。它由两个网络组成:产生新样本的发生器,以及检测假样本的鉴别器。发生器试图欺骗鉴别器,而鉴别器试图检测发生器合成的样本。

Overview of GAN structure https://developers.google.com/machine-learning/gan/gan_structure

一旦经过训练,该生成器可用于按需创建新样本。由于其各种有趣的应用,如风格转换、图像到图像的翻译或视频生成,GANs 迅速变得流行起来。例如,这种架构特别适合生成人脸。

今天,GAN 有各种各样的形式:DCGAN,CycleGAN,SAGAN…在这么多的 GAN 中选择,我使用 StyleGAN 生成人工名人脸。在这份报告中,我将解释什么使 StyleGAN 架构成为一个好的选择,如何训练模型,以及训练的一些结果。

StyleGAN 模型架构

如果你对 StyleGAN 更完整的解释感兴趣,你可以看看这篇伟大的 文章 并跳到下一节。本节将解释 StyleGAN 架构中的哪些特性使其对人脸生成如此有效。

2018 年,英伟达在他们的论文中提出了一种新的网络,一种基于风格的 GANs 架构。以前的 GAN 模型已经显示出能够生成人脸,但一个挑战是能够控制生成的图像的一些特征,如头发颜色或姿势。StyleGAN 试图通过合并和建立渐进式训练来解决这一挑战,以单独修改每个细节层次。这样,它可以控制每个细节层次中表达的视觉特征,从姿势和脸型等粗略特征到眼睛颜色和鼻子形状等更精细的细节,而不影响其他层次。

Sample outputs by the authors of StyleGAN. https://arxiv.org/pdf/1812.04948.pdf

渐进式训练最初是在 ProGAN 架构中引入的,目的是生成高清图像。在渐进式训练中,首先在低分辨率图像(如 8×8)上训练模型,然后通过在训练期间向模型添加新的更高分辨率的层,输入图像分辨率逐渐加倍。通过这样做,模型可以在训练的早期阶段快速学习粗略的细节,并在稍后学习更精细的细节,而不是必须同时学习所有尺度的细节。

Progressive training in action https://towardsdatascience.com/progan-how-nvidia-generated-images-of-unprecedented-quality-51c98ec2cbd2

然而,ProGAN 模型控制图像特定特征的能力仍然有限。因为这些特性不是单独训练的,所以很难在不影响其他几个特性的情况下调整一个特定的特性。StyleGAN 在渐进式训练的基础上进行扩展,增加了一个映射网络,它将输入编码为一个特征向量,其元素控制不同的视觉特征,以及风格模块,它将先前的向量转换为其视觉表示。通过对每个级别使用单独的特征向量,模型能够组合多个特征:例如,从两个生成的图像,模型可以使用来自第一个的粗略级别特征,来自第二个的精细细节特征,来生成组合两者的第三个。

https://arxiv.org/pdf/1812.04948.pdf

通过渐进式训练和独立的特征映射,StyleGAN 为这项任务提供了巨大的优势。与其他强大的 GAN 网络相比,该模型需要更少的训练时间来生成高质量的逼真图像。此外,在有许多不同特征的人脸生成中,每个特征有几个实例,这种架构特别适合,因为该模型能够单独学习人脸特征,而不受特征级别之间的相关性的影响,以生成具有良好多样性的图像。获得真实和多样的图像是这次挑战的两个主要目标,在这里我只有有限的资源来训练我的模型,这就是为什么 StyleGAN 成为我选择的架构。

数据处理

我使用 CelebA 数据集来训练我的模型。CelebA 包含了 10,177 位不同名人的 202,599 张人脸图片。原始数据集标注了二元特征,如眼镜大鼻子,但我们将只使用图像本身来生成人脸。

Samples from CelebA dataset http://mmlab.ie.cuhk.edu.hk/projects/CelebA.html

数据集中的图像尺寸为 178×218。因为我们想要生成正方形图像,所以我们裁剪图像。为了做到这一点,我们假设面部位于图像的中心附近,并采取中心裁剪。

我们调整图像大小以适应渐进训练,如前所述,从 8x8 到 128x128,即所选的最终输出大小。注意,这种技术能够用 1024x1024 的图像训练模型,但是这将需要一个月以上的 GPU 训练,并且至少 64x64 的分辨率已经给出了良好的视觉效果。调整每个图像的大小,使其具有尺寸为 8×8、16×16、32×32、64×64 和 128×128 的副本,从而经过训练的生成器将生成尺寸为 128×128 的图像。

我还没有使用过的其他可能的数据处理方法是检测和裁剪图像,使其更接近人脸,并删除人脸不面向前方的例子。

培养

为了训练我自己的模型,我在我最喜欢的机器学习框架中的 Github 上找到了一个很棒的 StyleGAN 的实现,代码可以理解。

训练以与传统 GAN 网络相同的方式进行,增加了渐进式训练的任务。我对鉴别器和生成器都使用了学习率为 0.001 的 Adam 优化器。由于内存限制,我使用的批量大小为 16,代码大小为 512,即输入到生成器中的随机噪声向量大小为 1x512。对于损失函数,我使用 Wasserstein 损失。对于渐进式训练,在增加大小之前,每个维度大小在 600,00 0 个图像实例上训练,直到达到维度大小 128x128,在那里我继续训练模型,直到收敛。

我们可以使用三种技术来进行正则化。首先,当在训练期间加载输入图像时,以概率 0.5 执行水平翻转。通过这种方式,我不需要增加数据集的大小,这样会降低训练速度,但模型在训练过程中会遇到更多不同的输入。

第二种正则化技术是 StyleGAN 特有的。为了避免模型学习特征级别之间的相关性,模型执行风格混合。它接受两个输入,为每个输入生成特征映射向量,然后使用第一个特征向量开始训练,并随机切换到第二个特征向量。这确保了网络不依赖于级别之间的相关性。

Example of style mixing. https://arxiv.org/pdf/1812.04948.pdf

GAN 使用的另一种正则化方式是在训练期间向每个通道添加随机噪声。这允许模型增加其输出的多样性,并在生成的图像中添加随机变化(例如雀斑、头发)

Effect of noise inputs at different layers of generator. (a) Noise is applied to all layers. (b) No noise. (c) Noise in fine layers only (642–10242 ). (d) Noise in coarse layers only (4 2–322 ). https://arxiv.org/pdf/1812.04948.pdf

图象生成

我们只使用经过训练的生成器来生成图像。在训练模型之后,我们首先计算平均特征向量。这可以简单地通过使用生成器来合成几个图像来完成,在我们的例子中,我们使用 10 个图像,然后计算前面提到的在每个级别获得的图像上的特征向量的平均值。然后,在生成期间,使用的特征向量是 v_mean + ψ(v — v_mean) ,其中 v 是特征映射网络的输出, v_mean 是先前计算的平均特征向量, ψ 是控制平均特征向量的强度的常数。 c 越大,最终生成的图像越偏离“平均”人脸。我们甚至可以为每个级别使用不同的值 ψ 来控制每个特征离平均值有多远。

Left to right: ψ = -1, -0.7, -0.5, -0.2, 0, 0.2, 0.5, 0.7, 1

经过训练,也可以使用风格混合。我没有为最终的输出使用风格混合,但下面是我在训练后获得的一个例子。网格内的图像从顶部的图像中提取精细特征,从左侧的图像中提取粗糙特征。

结果

这里是在我的 StyleGAN 最终版本的训练中获得的一些输出,在这里你也可以看到渐进式训练的效果。

迭代 100,维度 8×8

迭代 10000,维度 8×8

迭代 50000,维度 16x16

迭代 100000,维度 32x32

迭代 140000,尺寸 64x64

迭代 155000,维度 128x128

迭代 400000,维度 128x128

我在大约 400000 次迭代时停止了训练,因为模型似乎没有进一步改进。在我检查的每次迭代生成的 50 张人脸中,通常总有一两张看起来很不现实,但其余的结果非常令人满意。在我看来,最好的例子甚至与真实的面孔难以区分。

生成的看起来不太真实的图像通常是面部不面向前方的图像,或者是戴着太阳镜的图像。未来的改进将是在训练之前移除这样的样本,使得模型将仅生成正面人脸。

感谢阅读,我希望你喜欢这篇文章!随时让我知道你用 StyleGAN 做的任何很酷的实验:)

你可以找到我使用的全部代码,从下载 CelebA 数据集到在我的 Github 上使用 StyleGAN 进行训练和生成示例,但是 PyTorch 中 StyleGAN 的实现完全归功于 rosinality 。

如何训练 word2vec 模型

原文:https://towardsdatascience.com/how-to-train-the-word2vec-model-24704d842ec3?source=collection_archive---------6-----------------------

Image by Chuk Yong from Pixabay

我们已经讨论过 word2vec ( 此处)的模型,现在来看看如何实现。为了做到这一点,我们必须建立一个浅层神经网络并训练它。

注:我发现在 Medium 上使用 latex 是相当不满意和讨厌的,所以我选择了使用手绘配方(和方案)。我提前为我的书法道歉。

训练样本

首先要做的是生成训练数据。回到我们的文本,我们需要:

  • 跳过课文中的每个单词:这是我们的中心词
  • 在给定的距离内选择它的相邻单词:这些是上下文单词

Context with windows size of 3

  • 生成数据对,每个样本由中心词和上下文词组成

The resulting 6 data pairs

我们还注意从我们的文本中读取的唯一单词的总数,因为这个参数将决定我们嵌入的词汇 的大小。

此时,数据生成已完成,该轮到构建和训练神经网络了。

神经网络

用于训练模型的神经网络的结构非常简单。它是一个前馈网络,最基本的形式包括:

  • 一个输入层。它接受一个字 w 并返回它的独热编码向量表示, x 。独热编码向量是除了11 之外全为 0 的向量,它们用于指示从集合中挑选的一个成员。对于来自训练数据的每一对, w 是中心词。输入向量的大小是 V ,即词汇量的大小。这一层没有激活功能。
  • 一个隐藏层。它是一个具有 V 行和 E 列的矩阵,为每个输入单词 x 分配其嵌入表示 h 。就像图片中一样,每个第 i 个行代表第 i 个嵌入,输出将是一个大小为 E. 的向量。如果不清楚为什么,可以自己尝试转置一个一键编码的向量,并将其乘以一个小矩阵。这一层也没有激活功能。
  • 一个输出层。这一层与上一层相反。它作为一个具有 E 行和 V 列的矩阵,其中 i-th 列包含第 i-th 上下文词的嵌入。因此,给定嵌入 h,与这个矩阵相乘返回一个 V 大小的向量 y 。作为激活函数,一个 softmax 函数被应用于 y. 生成一个矢量 z ,在中,其中第 k 个元素表示第 k 个字在 w 上下文中的概率。

Scheme of neural network

zy相对于W’中第 j 个字的表达式分别为:

Output of W’

Output of softmax

对于每个训练对,大小为 V 的向量 t 是与该对相关联的基本事实。这也是一个热码编码向量,它在上下文单词处等于 1 ,在其他地方等于 0 。换句话说,它是输出标签的指示器功能。

Truth vector

训练网络

为了训练这样的神经网络,我们遵循以下步骤:

  • 我们获取一个训练样本,并生成网络的输出值
  • 我们通过比较模型预测和真实输出标签来评估损失
  • 我们通过对评估的损失使用梯度下降技术来更新网络的权重
  • 然后我们取另一个样本,重新开始

这些步骤在整个训练集上重复,然后整个过程重复多次,称为时期。

做数学

为了更新神经网络的权重(矩阵 WW’,我们需要评估损失对它们的导数。导数的计算并不复杂,因为输出主要是线性函数矩阵运算的结果。当然,除了激活功能和损耗。主要缺陷在于权重指数的正确管理。

帮助我们计算的工具也很简单:链式法则。它指出,两个或多个函数的组合的导数可以计算为它们的导数的乘积。

Chain rule is applied to F, a composed function, by multiplying derivatives of its composing functions

让我们从损失相对于矢量 z 的元素的导数开始,这对于将要进行的两种计算都是有用的。我没有报告所有的步骤,但是通过利用 softmax 的属性可以显示:

Derivative w.r.t. z

向前移动,输出矩阵W’的导数为:

Derivative for output matrix weights

对于隐藏层的矩阵,还需要做一些工作。首先,让我们展开矩阵 W 产生的向量 h :

Element of vector h

然后,记住之前显示的损失的导数,并且 z 是向量 h 与列W’的乘积,我们得到:

Derivative w.r.t. j-th element of h

最后,将最后一个导数与 h w.r.t. W 的导数结合,我们得到:

Derivative for hidden layer weights

更新权重

一旦计算出导数,更新方程就是标准方程:

Getting the new weights

更新步骤由 eta 因子控制,该因子通常在训练时期随着权重接近其最佳值而减少。

一点矢量化

现在,我们已经定义了关于 WW’的元素的点导数,我们可以通过使用张量积将直接给出的定义扩展到矩阵,从而具有更简单和更紧凑的符号:

Derivative for output layer weights

Derivative for hidden layer weights

在后一种情况下, x 是一个独热编码向量,它只有一个元素等于 1,所有其他元素都等于 0。因此,它在这里的作用是只选择与输入单词的表示相关的行。换句话说,W中只更新输入单词的权重。

负采样

正如我们在上一篇文章中看到的,在负采样的情况下,目标函数会发生变化,因此,损失也会发生变化,权重公式也会更新。

现在,对于由 h 表示的给定输入字,对于W’中的第 j 个字,模型的输出由下式给出:

New output

代替以前偏导数的新偏导数是:

第一个等式实际上保持不变,但是 y 在这里被替换为使用 sigmoid 函数的新表达式。

此外,这些等式以及用于权重更新的等式现在必须仅应用于 K 组单词(正样本和负样本),而不是整个词汇表。

关于实现的更多细节,你可以看看我在 github 上的代码。我写它主要是为了娱乐和学习,所以它远不是很快,但很容易理解。

如何训练你的神经网络:隐藏代码

原文:https://towardsdatascience.com/how-to-train-your-artificial-intelligence-the-hidden-code-20cb3a35e1d6?source=collection_archive---------7-----------------------

机器学习和动力游侠将如何让我们成为硅时代的龙骑士

诚然,人工智能不像龙那么酷。

另一方面,你在生活中遇到某种形式的人工智能的可能性远远大于你有一条龙——或者你有,谁知道呢?我不知道你的生活。

不用说,人工智能已经成为我们生活中不可或缺的一部分,从网飞算法神奇地让你的周末消失到 Google Duplex 为你打电话这样你就再也不用担心通过电话预约了(人类互动?**喘息)。

但人工智能正在解决比以往任何时候都更大的问题,从肿瘤检测到无人驾驶汽车。世界瞬息万变,所以知道未来会如何发展很重要。毕竟,人工智能究竟是如何变得如此聪明的?

机器学习

中的龙如何训练你的龙和地球上的人类(也就是我们)有很多共同点。我们都很聪明,但我们不是那样开始的。

在成长过程中,我们从父母、朋友、老师(对于龙来说,是训练师)等那里获得了关于我们周围世界的信息。利用这些信息,我们试图为自己和他人做出一些好的选择(除非你是某种无政府主义者,在这种情况下革命万岁,我猜?)

有时候,我们做出的选择结果并不那么好。例如,在 2012 年 5 月不买脸书的股票。或者在 2018 年 7 月买入脸书股票。但是我们从错误中学习,并相应地调整我们的决策过程,所以我们在未来会做出更好的决定。对我们有好处!

使用一些不太复杂的数学,计算机科学家开发了一种叫做机器学习的过程,基本上做同样的事情。机器学习描述了向神经网络输入大量数据的方法,让它从中找到模式,然后让它根据这些模式做出选择和预测。但是就像龙一样,我们必须首先训练这些系统。

那么什么是神经网络,它到底是如何学习的呢?

让我们从基础开始。

神经网络是由神经元或奇特的感知器组成的系统。感知器接受多个输入值,并通过一个称为正向传播的整个过程产生一个单一的输出——在高层次上,想象一下权力游侠聚集在一起形成一个 Megazord。

假设是 Morphin 时间是对输入值执行的函数,幂游侠,它们中的每一个都有与之对应的特定值,例如:

  • x₁ = 0
  • x₂ = 1
  • x₃= 0

现在让我们说黑人权力游侠比其他人更重要。他的意见将被赋予更大的重要性,或者说权重。事实上,所有的流浪者都有他们各自的权重:

  • w₁= 1
  • w₂ = 2
  • w₃3

然后,神经元被分配一个偏置,这使它能够在一些迭代之后改变,以更好地适应你的数据。通过将乘以各自权重的所有输入值相加,并考虑到 b =偏差,我们得到:

(w₁×x₁)+(w₂×x₂)+(w₃×x₃)+(1×b)

让这个神经元真正有用的是一个激活功能。这基本上是把我们得到的总和作为一个转换函数的自变量(或输入),使它成为非线性的。这是通过 Sigmoid 函数或其他复杂的多项式回归模型来实现的。

由于许多数据并不总是符合线性关系,这有助于我们的神经网络模型更好地拟合数据,并且是将流浪者变成 Megazord 的特殊调料。也可能是外星科技。我不记得了。

团队合作让梦想成真。

一个神经元本身并没有那么有用。但是当我们一起使用它们时,我们可以形成一个神经元网络,几乎就像一个神经网络……😃

这些网络可以被认为是分层的,输入层是所有数据的来源,输出层为您提供预测,中间还有一些隐藏层。

一层中的所有神经元(或节点)连接回前一层中的所有神经元。它们最终通过我们一直在谈论的这种奇特的前向传播产生一个输出。然而,真正的魔力来自反向传播

反向传播是确定输出端的误差或损耗的过程,然后返回网络,根据误差调整权重和偏差;用于实现这一点的常见算法包括梯度下降、,它涉及找到您的参数相对于权重的导数,并将其乘以您的学习率,这决定了您希望优化的速度

本质上,我们找到损失函数的导数,并试图使其最小化,从而使误差最小化。有道理吗?

这个过程的每一轮,或训练迭代,被称为时期。我知道这听起来很糟糕。对于更困难的数据集,我们需要大量的历元,就像所有不同版本的《超级游侠》(有多少,100 万种?)

让我们用一些代码来尝试一下…

我们现在可以用 Python 建立一个非常简单的神经网络,它可以进行二进制分类,或者预测 1 或 0。 注意: 我用的是 Python 3.6

当然,我们不能没有我们的好朋友 Numpy:

import numpy as np

让我们将 X 设置为输入数组,将 y 设置为输出数组:

X=np.array([[0,1,1,0],[0,1,1,1],[1,0,0,1]])
y=np.array([[0],[1],[1]])

让我们添加 Sigmoid 函数(这将是正向传播的一部分)及其导数(这将是反向传播的一部分):

def sigmoid ():return 1/(1 + np.exp(-x))def derivatives_sigmoid ():return x * (1-x)

现在让我们设置我们想要多少个历元,我们的学习速率lr将是多少,我们的数据集中的特征的数量(1),隐藏层神经元的数量(3)和输出神经元的数量(1):

epoch=10000
lr=0.1 
inputlayer_neurons = X.shape[1] 
hiddenlayer_neurons = 3 
output_neurons = 1

现在我们可以设置初始权重和偏差。假设whbh是隐含层神经元的权重和偏差,woutbout是输出神经元的相同权重和偏差:

wh=np.random.uniform(size=(inputlayer_neurons,hiddenlayer_neurons))
bh=np.random.uniform(size=(1,hiddenlayer_neurons))
wout=np.random.uniform(size=(hiddenlayer_neurons,output_neurons))
bout=np.random.uniform(size=(1,output_neurons))

好了,舞台已经准备好了:我们有了数据,我们的初始权重和偏差已经设置好,我们的正向和反向传播函数已经准备好像 bosses 一样进行计算了。让我们把剩下的部分放好:

正向传播:

  • 首先,我们将得到权重输入值的乘积。
  • 接下来,我们将把偏差添加到产品中。
  • 然后,我们使用我们的 sigmoid 函数来转换/激活它。
  • 我们将在输出层神经元中重复这个结果。
hidden_layer_input1=np.dot(X,wh)
hidden_layer_input=hidden_layer_input1 + bh
hiddenlayer_activations = sigmoid(hidden_layer_input)output_layer_input1=np.dot(hiddenlayer_activations,wout)
output_layer_input= output_layer_input1+ bout
output = sigmoid(output_layer_input)

反向传播:

  • 我们将计算误差,即 y 和输出之间的差值。
  • 接下来,我们将找到输出和转换/激活的梯度。
  • 现在,让我们通过将输出层的变化系数乘以误差来找出变化系数。
  • 现在误差将传播回网络,所以我们必须得到第二层和第三层之间的δ和权重参数的点积。
  • 我们将对隐藏层做同样的事情,然后更新权重和偏差。
E = y-output
slope_output_layer = derivatives_sigmoid(output)
slope_hidden_layer = derivatives_sigmoid(hiddenlayer_activations)d_output = E * slope_output_layerError_at_hidden_layer = d_output.dot(wout.T)
d_hiddenlayer = Error_at_hidden_layer * slope_hidden_layerwout += hiddenlayer_activations.T.dot(d_output) *lr
bout += np.sum(d_output, axis=0,keepdims=True) *lrwh += X.T.dot(d_hiddenlayer) *lr
bh += np.sum(d_hiddenlayer, axis=0,keepdims=True) *lr

我们可以通过打印输出来结束:

print (output)

它应该会返回如下内容:

[[0.03391414][0.97065091][0.9895072 ]]

我们原来的输出是 0,1,1,这些输出超级接近。它们不精确是好事,因为它允许其他数据的灵活性。你可以通过改变历元的数量来降低模型的准确性。

我们做到了!当然,有不同的方法来编码神经网络,你可以找到大量的文章来教你,这只是我学到的方法之一。现在,当其他人都在星巴克忙着敲他们的剧本时,你可以高兴地知道你正在骑着未来的龙。

写出来的东西比我想象的要俗气得多。)

所以你已经做到了…

你已经训练好了你的龙。花了 10 000 个纪元,但你做到了。但这仅仅是开始。你面前有一整个特许经营权。

今天,机器学习正以一些真正令人兴奋的方式得到应用。像 Cogito 这样的公司正在用它来帮助呼叫中心的工作人员通过分析他们的声音来判断 T2 客户对电话的兴趣。医学界正在使用人工智能来帮助诊断恶性血细胞和肿瘤。计算机视觉正在帮助无人驾驶汽车上路。甚至还有 AI 写整本书!

如何训练你的龙中,与龙合作让伯克的骑手改善社会和农业生活。正如我们所知,人工智能已经在改善我们的生活;它现在正在扰乱世界上的每一个行业,所以尽快加入进来是很重要的。理解神经网络是如何工作的,哪怕只是一点点,都会让你领先于潮流。

因此,理解人工智能可能不会让你变得像养龙的人一样酷,但它是革命性的、令人兴奋的,而且一定会确保你在未来的地位。

关键要点

  • 一个神经元接收多个输入并产生一个输出。输入有关联的权重,神经元应用自己的偏置
  • 神经元还包括一个激活函数,它使得数据图是非线性的。当我们把这些放在一起,我们就有了一个神经网络。
  • 反向传播是调整权重和偏差以最小化输出误差的过程,通常使用像梯度下降这样的训练算法。
  • 数据需要多轮训练迭代,或历元才能准确。
  • 从医疗行业到文学,人工智能正在改变世界的工作方式。这是一辆你希望乘坐的颠覆性列车。

如果你喜欢这篇文章…

  1. 看看我的另一篇文章关于我们将如何制造情感人工智能…
  2. 在 LinkedIn 上与我联系!如果你想谈论 AI/ML 或龙,我很乐意连接!

如何训练你的四轴飞行器

原文:https://towardsdatascience.com/how-to-train-your-quadcopter-adventures-in-machine-learning-algorithms-e6ee5033fd61?source=collection_archive---------7-----------------------

教四轴飞行器飞行的完全初学者指南(附代码!)

Photo by Pixaby via Pexels

最近,我在尝试训练四轴飞行器飞行时获得了很多乐趣。

太有趣了。

Photo by наталья семенкова from Pexels

关于四轴飞行器的一切!

四轴飞行器是很神奇的东西。

它们体积小,机动性强,可以在室内和室外飞行。他们对摄影和新闻业很感兴趣。你可以用它们来送货,人道主义行动,搜索和救援,以及拍摄电影。当然,它们也有军事和执法应用。它们也非常适合研究!有了四轴飞行器,你可以测试飞行控制理论、实时系统、导航和机器人等领域的新想法。

此外,他们可以由业余爱好者建造和维护!

GIF via GIPHY

在一个非常基本的层面上,四轴飞行器是一种由四个旋翼(大部分时间)提升和推进的直升机。他们通常使用两对相同的固定螺距螺旋桨。两个顺时针运行,两个逆时针运行。对于控制,他们使用每个转子速度的独立变化。通过改变每个转子的速度,您可以产生所需的总推力,定位推力中心(横向和纵向),并产生所需的总扭矩。

四轴飞行器真正酷的地方在于,你可以通过使用机器学习技术训练的神经网络来控制它!

使用强化学习,你可以训练一个网络直接将状态映射到执行器命令。甚至可以用模拟训练的神经网络完全控制四轴飞行器!如果你感兴趣的话,Jemin Hwangbo 等人写了一篇很棒的论文概述了他们的研究。

虽然大多数四轴飞行器有四个发动机提供推力(……将“四轴飞行器”中的“四轴飞行器”),但一些实际上有 6 个或 8 个。有更多的推力点可以提高稳定性,并实现一系列酷的飞行行为。但更复杂的系统意味着手动控制每个发动机的推力几乎是不可能的。

幸运的是,您可以使用强化学习来构建能够自主学习行为的代理!

Photo by Jimmy Chan from Pexels

我为什么要这么做?

这是 Udacity 的机器学习工程师 Nanodegree 的必考项目之一。这是一个非常酷的项目,你可能想看看!你得到了一些坚实的基本代码,一些有用的文件,然后你插入你自己的代码,让它运行起来。

听起来很简单,对吧?

没有那么多。

Photo by Pixabay via Pexels

让我们把手弄脏吧!

要让这个东西发挥作用,你需要设计自己的强化学习任务和一个代理来完成它。为您提供了一个样例代理来开始使用,以及一个四轴飞行器模拟器。

剩下的就看你的了。

代理通过设置四个旋翼的每秒转数来控制四轴飞行器。您可以通过包含速度信息来扩展状态向量的大小。(Udacity 使用四轴飞行器的 6 维姿态来构建每个时间步的环境状态)。也可以使用姿势、速度和角速度的任意组合。

您将使用__init__()方法初始化几个变量,包括您的任务。如果您浏览一下代码,您会看到模拟器在这里被初始化为physics_sim类的一个实例。受这篇深度确定性政策梯度论文的启发,Udacity 还利用了动作重复。您将设置状态向量中的元素数量,并将目标位置指定为一个变量。

我们为您提供了一个示例代理。它使用非常简单的线性策略来直接计算动作向量,作为状态向量和权重矩阵的点积。它通过添加一些高斯噪声来随机扰动参数,以产生不同的策略。根据每集获得的平均奖励,它会跟踪到目前为止找到的最佳参数集以及分数的变化情况。然后,它调整一个比例因子来扩大或收紧噪声。

他们给你安排的那个简单的不太好用…

接下来由你来指定你选择的任务。您将定义自己的代理,并为您的任务调整各种超参数和奖励函数,直到您获得一些值得骄傲的行为。

我们来训练一架四轴飞行器吧!

我们需要在 task.py 文件中定义我们的任务(环境)。我们还会有一个文件夹存放我们的增援特工。我们将在那里保存一个 agent.py 文件,我们在其中定义代理,并利用包含四轴飞行器模拟器的 physics_sim.py 文件。你可能想考虑创建更多的文件,比如一个定义神经网络的文件,如果你想尝试的话。

首先,我们的任务是:

任务. py

import numpy as np
from physics_sim import PhysicsSimclass Task2():"""Task that defines the goal and provides feedback to the agent."""def __init__(self, init_pose=None, init_velocities=None, init_angle_velocities=None, runtime=5., target_pos=None):"""Initialize a Task object.Params======init_pose: initial position of the quadcopter in (x,y,z) dimensions and the Euler anglesinit_velocities: initial velocity of the quadcopter in (x,y,z) dimensionsinit_angle_velocities: initial radians/second for each of the three Euler anglesruntime: time limit for each episodetarget_pos: target/goal (x,y,z) position for the agent"""# Simulationself.sim = PhysicsSim(init_pose, init_velocities, init_angle_velocities, runtime) self.action_repeat = 3self.state_size = self.action_repeat * 6self.action_low = 0self.action_high = 900self.action_size = 4# Goalself.target_pos = target_pos if target_pos is not None else np.array([0., 0., 10.])def get_reward(self):"""Uses current pose of sim to return reward."""#reward = 1-(0.3*(abs(self.sim.pose[:3] - self.target_pos))).sum()#reward = np.tanh(reward)reward = np.tanh(1 - 0.0005*(abs(self.sim.pose[:3] - self.target_pos)).sum())return rewarddef step(self, rotor_speeds):"""Uses action to obtain next state, reward, done."""reward = 0pose_all = []for _ in range(self.action_repeat):done = self.sim.next_timestep(rotor_speeds) # update the sim pose and velocitiesreward += (self.get_reward()/2)#if reward > 1: reward = 1#if reward < -1: reward = -1#reward = np.tanh(0.5*reward)pose_all.append(self.sim.pose)next_state = np.concatenate(pose_all)return next_state, reward, donedef reset(self):"""Reset the sim to start a new episode."""self.sim.reset()state = np.concatenate([self.sim.pose] * self.action_repeat) return state

我们肯定需要设计代理。在浪费了大量时间和无用的浪费之后,我决定使用 actor、critical、policy search、replay buffer 和 ou_noise 文件。(你可以在这里阅读奥恩斯坦-乌伦贝克进程。)

显示您的代理文件夹

agent.py

from agents.actor import Actor
from agents.critic import Critic
from agents.replay_buffer import ReplayBuffer
from agents.ou_noise import OUNoise
import numpy as np
import random
from collections import namedtuple, dequeclass DDGP():"""Reinforcement Learning agent that learns using DDPG."""def __init__(self, task):self.task = taskself.state_size = task.state_sizeself.action_size = task.action_sizeself.action_low = task.action_lowself.action_high = task.action_high# Actor (Policy) Modelself.actor_local = Actor(self.state_size, self.action_size, self.action_low, self.action_high)self.actor_target = Actor(self.state_size, self.action_size, self.action_low, self.action_high)# Critic (Value) Modelself.critic_local = Critic(self.state_size, self.action_size)self.critic_target = Critic(self.state_size, self.action_size)# Initialize target model parameters with local model parametersself.critic_target.model.set_weights(self.critic_local.model.get_weights())self.actor_target.model.set_weights(self.actor_local.model.get_weights())# Noise processself.exploration_mu = 0self.exploration_theta = 0.15self.exploration_sigma = 0.3self.noise = OUNoise(self.action_size, self.exploration_mu, self.exploration_theta, self.exploration_sigma)# Replay memoryself.buffer_size = 1000000self.batch_size = 64self.memory = ReplayBuffer(self.buffer_size, self.batch_size)# Algorithm parametersself.gamma = 0.99  # discount factorself.tau = 0.001  # for soft update of target parametersdef reset_episode(self):self.noise.reset()state = self.task.reset()self.last_state = statereturn statedef step(self, action, reward, next_state, done):# Save experience / rewardself.memory.add(self.last_state, action, reward, next_state, done)# Learn, if enough samples are available in memoryif len(self.memory) > self.batch_size:experiences = self.memory.sample()self.learn(experiences)# Roll over last state and actionself.last_state = next_statedef act(self, states):"""Returns actions for given state(s) as per current policy."""state = np.reshape(states, [-1, self.state_size])action = self.actor_local.model.predict(state)[0]return list(action + self.noise.sample())  # add some noise for explorationdef learn(self, experiences):"""Update policy and value parameters using given batch of experience tuples."""# Convert experience tuples to separate arrays for each element (states, actions, rewards, etc.)states = np.vstack([e.state for e in experiences if e is not None])actions = np.array([e.action for e in experiences if e is not None]).astype(np.float32).reshape(-1, self.action_size)rewards = np.array([e.reward for e in experiences if e is not None]).astype(np.float32).reshape(-1, 1)dones = np.array([e.done for e in experiences if e is not None]).astype(np.uint8).reshape(-1, 1)next_states = np.vstack([e.next_state for e in experiences if e is not None])# Get predicted next-state actions and Q values from target models#     Q_targets_next = critic_target(next_state, actor_target(next_state))actions_next = self.actor_target.model.predict_on_batch(next_states)Q_targets_next = self.critic_target.model.predict_on_batch([next_states, actions_next])# Compute Q targets for current states and train critic model (local)Q_targets = rewards + self.gamma * Q_targets_next * (1 - dones)self.critic_local.model.train_on_batch(x=[states, actions], y=Q_targets)# Train actor model (local)action_gradients = np.reshape(self.critic_local.get_action_gradients([states, actions, 0]), (-1, self.action_size))self.actor_local.train_fn([states, action_gradients, 1])  # custom training function# Soft-update target modelsself.soft_update(self.critic_local.model, self.critic_target.model)self.soft_update(self.actor_local.model, self.actor_target.model)def soft_update(self, local_model, target_model):"""Soft update model parameters."""local_weights = np.array(local_model.get_weights())target_weights = np.array(target_model.get_weights())assert len(local_weights) == len(target_weights), "Local and target model parameters must have the same size"new_weights = self.tau * local_weights + (1 - self.tau) * target_weightstarget_model.set_weights(new_weights)class OUNoise:"""Ornstein-Uhlenbeck process."""def __init__(self, size, mu, theta, sigma):"""Initialize parameters."""self.mu = mu * np.ones(size)self.theta = thetaself.sigma = sigmaself.reset()def reset(self):"""Reset the internal state mean (mu)."""self.state = self.mudef sample(self):"""Update internal state and return it as a noise sample."""x = self.statedx = self.theta * (self.mu - x) + self.sigma * np.random.randn(len(x))self.state = x + dxreturn self.stateclass ReplayBuffer:"""Fixed-size buffer to store experience tuples."""def __init__(self, buffer_size, batch_size):"""Initialize a ReplayBuffer object.Params======buffer_size: maximum size of bufferbatch_size: size of each training batch"""self.memory = deque(maxlen=buffer_size) # internal memory (deque)self.batch_size = batch_sizeself.experience = namedtuple("Experience", field_names=["state", "action", "reward", "next_state", "done"])def add(self, state, action, reward, next_state, done):"""Add a new experience to memory."""e = self.experience(state, action, reward, next_state, done)self.memory.append(e)def sample(self, batch_size=64):"""Randomly sample a batch of experiences from memory."""return random.sample(self.memory, k=self.batch_size)def __len__(self):"""Return the current size of internal memory."""return len(self.memory)

actor.py

from keras import layers, models, optimizers, regularizers
from keras import backend as Kfrom keras import layers, models, optimizers, regularizers
from keras import backend as Kclass Actor:"""Actor (Policy) Model."""def __init__(self, state_size, action_size, action_low, action_high):"""Initialize parameters and build model.Params======state_size (int): Dimension of each stateaction_size (int): Dimension of each actionaction_low (array): Min value of each action dimensionaction_high (array): Max value of each action dimension"""self.state_size = state_sizeself.action_size = action_sizeself.action_low = action_lowself.action_high = action_highself.action_range = self.action_high - self.action_lowself.build_model()def build_model(self):"""Build an actor (policy) network that maps states to actions."""# Define states (input layer)states = layers.Input(shape=(self.state_size,), name='states')net = layers.Dense(units=512, kernel_regularizer=regularizers.l2(0.01))(states)net = layers.BatchNormalization()(net)net = layers.Activation('relu')(net)net = layers.Dense(units=256, kernel_regularizer=regularizers.l2(0.01))(net)net = layers.BatchNormalization()(net)net = layers.Activation('relu')(net)#net = layers.Dense(units=128, kernel_regularizer=regularizers.l2(0.01))(net)#net = layers.BatchNormalization()(net)#net = layers.Activation('relu')(net)# Add final output layer with sigmoid activationraw_actions = layers.Dense(units=self.action_size, activation='sigmoid',name='raw_actions',kernel_initializer=layers.initializers.RandomUniform(minval=-3e-3,maxval=3e-3))(net)# Scale [0, 1] output for each action dimension to proper rangeactions = layers.Lambda(lambda x: (x * self.action_range) + self.action_low,name='actions')(raw_actions)# Create Keras modelself.model = models.Model(inputs=states, outputs=actions)# Define loss function using action value (Q value) gradientsaction_gradients = layers.Input(shape=(self.action_size,))loss = K.mean(-action_gradients * actions)# Incorporate any additional losses here (e.g. from regularizers)# Define optimizer and training functionoptimizer = optimizers.Adam(lr=0.001)updates_op = optimizer.get_updates(params=self.model.trainable_weights, loss=loss)self.train_fn = K.function(inputs=[self.model.input, action_gradients, K.learning_phase()],outputs=[],updates=updates_op)

critic.py

from keras import layers, models, optimizers, regularizers
from keras import backend as Kclass Critic:"""Critic (Value) Model."""def __init__(self, state_size, action_size):"""Initialize parameters and build model.Params======state_size (int): Dimension of each stateaction_size (int): Dimension of each action"""self.state_size = state_sizeself.action_size = action_sizeself.build_model()def build_model(self):# Define input layersstates = layers.Input(shape=(self.state_size,), name='states')actions = layers.Input(shape=(self.action_size,), name='actions')net_states = layers.Dense(units=512, kernel_regularizer=regularizers.l2(0.01))(states)net_states = layers.BatchNormalization()(net_states)net_states = layers.Activation('relu')(net_states)#net_states = layers.Dropout(0.2)(net_states)net_states = layers.Dense(units=256, activation='relu', kernel_regularizer=regularizers.l2(0.01))(net_states)#net_states = layers.BatchNormalization()(net_states)#net_states = layers.Activation('relu')(net_states)# Add hidden layers for action pathwaynet_actions = layers.Dense(units=256, activation='relu', kernel_regularizer=regularizers.l2(0.01))(actions)# Combine state and action pathwaysnet = layers.Add()([net_states, net_actions])net = layers.Activation('relu')(net)# Add final output layer to produce action values (Q values)Q_values = layers.Dense(units=1, name='q_values',kernel_initializer=layers.initializers.RandomUniform(minval=-3e-3,maxval=3e-3))(net)# Create Keras modelself.model = models.Model(inputs=[states, actions], outputs=Q_values)# Define optimizer and compile model for training with built-in loss functionoptimizer = optimizers.Adam()self.model.compile(optimizer=optimizer, loss='mse')# Compute action gradients (derivative of Q values w.r.t. to actions)action_gradients = K.gradients(Q_values, actions)# Define an additional function to fetch action gradients (to be used by actor model)self.get_action_gradients = K.function(inputs=[*self.model.input, K.learning_phase()],outputs=action_gradients)

策略 _ 搜索. py

import numpy as np
from task import Taskclass PolicySearch_Agent():def __init__(self, task):# Task (environment) informationself.task = taskself.state_size = task.state_sizeself.action_size = task.action_sizeself.action_low = task.action_lowself.action_high = task.action_highself.action_range = self.action_high - self.action_lowself.w = np.random.normal(size=(self.state_size, self.action_size),  # weights for simple linear policy: state_space x action_spacescale=(self.action_range / (2 * self.state_size))) # start producing actions in a decent range# Score tracker and learning parametersself.best_w = Noneself.best_score = -np.infself.noise_scale = 0.1# Episode variablesself.reset_episode()def reset_episode(self):self.total_reward = 0.0self.count = 0state = self.task.reset()return statedef step(self, reward, done):# Save experience / rewardself.total_reward += rewardself.count += 1# Learn, if at end of episodeif done:self.learn()def act(self, state):# Choose action based on given state and policyaction = np.dot(state, self.w)  # simple linear policyreturn actiondef learn(self):# Learn by random policy search, using a reward-based scoreself.score = self.total_reward / float(self.count) if self.count else 0.0if self.score > self.best_score:self.best_score = self.scoreself.best_w = self.wself.noise_scale = max(0.5 * self.noise_scale, 0.01)else:self.w = self.best_wself.noise_scale = min(2.0 * self.noise_scale, 3.2)self.w = self.w + self.noise_scale * np.random.normal(size=self.w.shape)  # equal noise in all directions

ou_noise.py

import numpy as np
from task import Taskclass PolicySearch_Agent():def __init__(self, task):# Task (environment) informationself.task = taskself.state_size = task.state_sizeself.action_size = task.action_sizeself.action_low = task.action_lowself.action_high = task.action_highself.action_range = self.action_high - self.action_lowself.w = np.random.normal(size=(self.state_size, self.action_size),  # weights for simple linear policy: state_space x action_spacescale=(self.action_range / (2 * self.state_size))) # start producing actions in a decent range# Score tracker and learning parametersself.best_w = Noneself.best_score = -np.infself.noise_scale = 0.1# Episode variablesself.reset_episode()def reset_episode(self):self.total_reward = 0.0self.count = 0state = self.task.reset()return statedef step(self, reward, done):# Save experience / rewardself.total_reward += rewardself.count += 1# Learn, if at end of episodeif done:self.learn()def act(self, state):# Choose action based on given state and policyaction = np.dot(state, self.w)  # simple linear policyreturn actiondef learn(self):# Learn by random policy search, using a reward-based scoreself.score = self.total_reward / float(self.count) if self.count else 0.0if self.score > self.best_score:self.best_score = self.scoreself.best_w = self.wself.noise_scale = max(0.5 * self.noise_scale, 0.01)else:self.w = self.best_wself.noise_scale = min(2.0 * self.noise_scale, 3.2)self.w = self.w + self.noise_scale * np.random.normal(size=self.w.shape)  # equal noise in all directions

replay _ buffer.py

import random
from collections import namedtuple, dequeclass ReplayBuffer:"""Fixed-size buffer to store experience tuples."""def __init__(self, buffer_size, batch_size):"""Initialize a ReplayBuffer object.Params======buffer_size: maximum size of bufferbatch_size: size of each training batch"""self.memory = deque(maxlen=buffer_size)  # internal memory (deque)self.batch_size = batch_sizeself.experience = namedtuple("Experience", field_names=["state", "action", "reward", "next_state", "done"])def add(self, state, action, reward, next_state, done):"""Add a new experience to memory."""e = self.experience(state, action, reward, next_state, done)self.memory.append(e)def sample(self, batch_size=64):"""Randomly sample a batch of experiences from memory."""return random.sample(self.memory, k=self.batch_size)def __len__(self):"""Return the current size of internal memory."""return len(self.memory)

是时候训练我们的特工了!

我们开始吧!

首先,设置您的环境

conda create -n quadcop python=3.6 matplotlib numpy pandas
source activate quadcop

现在去你的笔记本上拿你的进口货

conda create -n quadcop python=3.6 matplotlib numpy pandas
source activate quadcop

然后继续看你的笔记本。从你的进口开始

import sys
import pandas as pd
from agents.agent import DDGP
from task import Task2
import csvimport matplotlib.pyplot as plt
%matplotlib inline

现在让我们飞吧!

num_episodes = 500
target_pos = np.array([0., 0., 10.])
task = Task2(target_pos=target_pos)
agent = DDGP(task) 
best_score = -1000
best_x = 0
best_y = 0
best_z = 0
data = {}
reward_log = "reward.txt"reward_labels = ['episode', 'reward']
reward_results = {x : [] for x in reward_labels}for i_episode in range(1, num_episodes+1):state = agent.reset_episode()score = 0while True:action = agent.act(state) next_state, reward, done = task.step(action)agent.step(action, reward, next_state, done)state = next_statescore += rewardif score > best_score:best_x = task.sim.pose[0]best_y = task.sim.pose[1]best_z = task.sim.pose[2]best_score = max(score, best_score)data[i_episode] = {'Episode': i_episode, 'Reward':score,'Action':action,'Best_Score':best_score,'Position_x':task.sim.pose[0],'Position_y':task.sim.pose[1],'Position_z':task.sim.pose[2]}if done:print("\rEpisode = {:4d}, score = {:7.3f} (best = {:7.3f}), last_position = ({:5.1f},{:5.1f},{:5.1f}), best_position = ({:5.1f},{:5.1f},{:5.1f})".format(i_episode, score, best_score, task.sim.pose[0], task.sim.pose[1], task.sim.pose[2], best_x, best_y, best_z), end="")breakreward_results['episode'].append(i_episode)reward_results['reward'].append(score)sys.stdout.flush()**Episode =  500, score =  94.111 (best =  95.349), last_position = ( -4.6, 23.7,158.8), best_position = (-14.1, 31.0, 25.8))**

我们可以这样规划奖励:

plt.figure(figsize=(16,4))plt.plot(reward_results[‘episode’], reward_results[‘reward’], label=’reward/episode’, color=’indigo’)plt.title(‘Reward Results’, color=’indigo’, fontsize=18)plt.legend()

Photo by Jean van der Meulen from Pexels

影响最大的是什么?

首先,我们可以看看奖励函数。无人机在每集的每一步都会根据其当前位置和 x、y、z 维度的目标位置之间的差异获得-1 到 1 之间的奖励。因为最初的奖励函数没有给我们好的结果,我们切换到 tanh 奖励函数。

我们从这个奖励开始:

reward = 1-(0.3*(abs(self.sim.pose[:3] — self.target_pos))).sum()`

然后,在确定提供的奖励函数不令人满意之后,我们使用了 tanh 奖励函数:

np.tanh(1–0.3*(abs(self.sim.pose[:3] — self.target_pos)).sum())`

降低“0.3”常数会得到更好的结果。经过反复试验,我决定使用:

reward = np.tanh(1–0.0005*(abs(self.sim.pose[:3] — self.target_pos)).sum())`

(除了成绩提升之外,无人机也随着这个变化学习快了很多!)

Actor 模型有两个密集层,分别包含 512 个和 256 个单元。在这两层上,我们使用了 12 个正则化,批量归一化,和 ReLU 激活函数。最后一层具有四个细胞的致密层和 s 形激活函数。Adam optimizer 工作良好,学习率为 0.001。

Critic 模型类似于 Actor 模型,也有两个密集层,分别是 512 和 256 个单元。批处理规范化和 ReLU 激活函数在这里也有意义。

根据参数的随机初始化,您的代理可能会在前 20-50 集学习一项任务。但是大多数算法在 500-1000 集内学习任务。他们也有可能陷入局部极小,永远出不来(或者很久以后才出不来)。你的训练算法可能需要更长时间。这取决于你选择的学习率参数等细节。

这个代理学的很快!它的学习曲线非常陡峭。无人机获得的奖励周期性大幅增加,而不是一个渐进的学习曲线。过去 10 集的平均回报约为 93.3。

print("Final Performance (Mean Reward over last 10 episodes): {}".format(np.sum(reward_results['reward'][-10:])/10))**Final Performance (Mean Reward over last 10 episodes): 93.29302608958609**

因为我不是机器人或四轴飞行器方面的专家,这个项目很艰难!但是我在尝试把这个项目组合在一起时学到的东西是惊人的。如果你有任何兴趣,你可能想尝试一下这个项目!

如果你想看看原来的项目,你可以在这里找到。这是您可以找到所有原始代码和指令的地方。

如果你对我的代码感兴趣,它在 GitHub 上!

感谢阅读!和往常一样,如果你对这些信息做了什么很酷的事情,请在下面的评论中让所有人都知道,或者联系 LinkedIn @annebonnerdata !

如何使用深度学习训练你的自动驾驶汽车

原文:https://towardsdatascience.com/how-to-train-your-self-driving-car-using-deep-learning-ce8ff76119cb?source=collection_archive---------2-----------------------

一个端到端的指南,使用深度学习编程你的自动驾驶汽车转向

Photo by Robin Pierre on Unsplash

被困在付费墙后面?点击这里阅读完整故事与我的朋友链接!

每年,交通事故占全球死亡人数的 2.2%。一年累积起来大约是 130 万——每天 3287。除此之外,每年约有 2000-5000 万人在与汽车相关的事故中严重受伤。这些事故的根源?人为错误。

从分心驾驶到酒后驾驶到鲁莽驾驶到粗心驾驶,一个糟糕或疏忽的决定可能是典型驾驶和危及生命的情况之间的差异。但是如果我们能从等式中消除人为错误会怎么样呢?

“自动驾驶汽车不再受制于好莱坞科幻电影”——特斯拉公司和 SpaceX 的创始人埃隆·马斯克认为,十年内,自动驾驶汽车将像电梯一样普遍。

业内专家表示,这项技术将会颠覆并彻底改变我们所知的交通运输的未来。

挑战

训练一个端到端的深度学习模型,让汽车在驾驶模拟器中自动驾驶。这是一个汽车转向角和汽车摄像头实时拍摄的道路图像之间的监督回归问题。

这个项目的灵感来自英伟达的端到端自动驾驶汽车论文,可以在这里找到。

数据收集

High-level view of the Nvidia’s data collection system

在这个项目中,使用了 Udacity 驾驶模拟器,它有两条不同的赛道。其中一个用于收集训练数据,另一个——模型从未见过——作为测试集的替代品。

驾驶模拟器将保存三个前置“摄像机”的画面,从汽车的角度记录数据;以及各种驾驶统计数据,如油门、速度和转向角度。我们将使用相机数据作为模型输入,并期望它预测[-1,1]范围内的转向角。

环境和工具

  1. matplotlib
  2. 克拉斯
  3. numpy
  4. 熊猫
  5. sci kit-学习

Google’s self-driving car — Waymo

代码在哪里?

事不宜迟,让我们从代码开始吧。github 上的完整项目可以在这里找到。

我从加载所有需要的库和依赖项开始。

该数据集有 6 列—中间、左侧、右侧(摄像机图像路径)、转向、油门、倒车、速度(值)。我使用 pandas dataframe 来显示数据集中的前五行。

因为左、右和中心图像路径的前缀对于所有行都是相同的,所以我决定移除整个数据集中的前缀部分。

接下来,我绘制了方向盘角度值的分布。正如你所看到的,在零附近有一个巨大的尖峰,这意味着大部分时间汽车是直线行驶。

然后,我创建了一个函数,将所有图像以及方向盘角度值加载到一个 numpy 数组中。

下一步是使用 80–20 规则分割数据,这意味着使用 80%的数据进行训练,而剩余的数据用于在看不见的图像上测试模型。此外,我绘制了样本训练和验证转向角分布。

我继续做一些图像处理。我裁剪了图像以去除不必要的特征,将图像转换为 YUV 格式,使用高斯模糊,减小尺寸以便于处理,并对值进行归一化。

为了比较和可视化,我绘制了原始图像和预处理图像。

到目前为止一切顺利。接下来,我将所有图像转换成 numpy 数组。

下一步是构建模型。我已经使用 ResNet 作为预训练的权重。我已经删除了最后 4 层,使我自己的定制神经网络。

Training the Neural Network

在沉重的 resnet 架构之上,我使用了 flatten 层来归一化权重。接下来,我使用了分别具有 100、50 和 10 个神经元的三个密集层,并将 elu 作为激活函数。此外,在这两者之间,我使用了 50%的退出率来减少对训练集的过度拟合。

最后,我用 128 的批量训练了 25 个时期的模型。此外,我绘制了训练和验证损失作为时代的函数。

Loss vs epoch

这个模型在仅仅 25 个时期内收敛得相当好。这意味着它正在学习一个相当好的策略,在看不见的道路环境中驾驶汽车。请随意使用超参数以获得更好的效果。

结果

我对这辆车在试车跑道上的表现感到惊讶。美国有线电视新闻网从未见过这个轨道。在训练赛道上的表现有点偏离,但我认为这没什么,因为这表明赛车不仅仅是在记忆赛道。它成功地从一些危急情况中恢复过来,尽管这些机动在训练中没有进行过。

结论

总的来说,这是一个非常有趣,同时又富有挑战性的项目。深度学习是一个令人兴奋的领域,我们很幸运生活在这个发明的时代。

10 年后,我们大多数人可能都不会拥有汽车。我们会向像优步这样的公司订购一些服务……我们会每月支付 149 美元,每天早上醒来,我们的车道上会有一辆车载着我们去上班。

参考资料/进一步阅读

[## 自动驾驶汽车的端到端深度学习

在一个新的汽车应用中,我们使用卷积神经网络(CNN)来映射来自一个

devblogs.nvidia.com](https://devblogs.nvidia.com/deep-learning-self-driving-cars/) [## 使用交互式代码实现英伟达用于自动驾驶汽车的神经网络[手动…

所以最近碰到这个 Quora 的问题,“用于自动驾驶汽车的神经网络有几层?”…

towardsdatascience.com](/implementing-neural-network-used-for-self-driving-cars-from-nvidia-with-interactive-code-manual-aa6780bc70f4) [## uda city/自动驾驶汽车模拟

这个模拟器是为 Udacity 的自动驾驶汽车 Nanodegree 建造的,旨在教学生如何训练汽车如何导航…

github.com](https://github.com/udacity/self-driving-car-sim)

在你走之前

github 上相应的项目可以在这里找到。

[## abhinavsagar/自动驾驶汽车

使用 google colab 中预先训练的 ResNet50 权重进行端到端自动驾驶的转移学习。火车 a…

github.com](https://github.com/abhinavsagar/Self-Driving-Car)

快乐阅读,快乐学习,快乐编码!

联系人

如果你想了解我最新的文章和项目,请关注我的媒体。以下是我的一些联系人详细信息:

  • 个人网站
  • 领英
  • 中等轮廓
  • GitHub
  • 卡格尔

如何将 SQL 知识转移到 R

原文:https://towardsdatascience.com/how-to-transfer-sql-knowledge-to-r-e9ec951f33dc?source=collection_archive---------17-----------------------

使用替代语法操作数据

为什么要在 R 的上下文中使用 SQL 语法呢?也许你学过一些生物信息学课程,但后来转向 Python,回到 r 的语法时有些犹豫。也许你想扩展你的数据科学工具包,并且迫切需要编码创可贴来让你远离 Stackoverflow。也许您已经编写了 SQL 查询,但是想要使用 ggplot2 来可视化结果。在数据结构经常令人困惑的环境中,SQL 语法可以简化 R 中的数据帧操作,这样就可以将更多的时间花在可视化上,而不是花在争论数据上。这里的代码可以在我的 GitHub 上完整找到。

R 中的 sqldf 包是一个对分析师友好的神奇工具。通过简单地在字符串中编写一个 SQL 查询,该函数根据该查询输出一个新的数据帧。在下面的代码块中,我将使用 sqldf 函数和适当的 R 语法来分享一些基本的重构工具。使用 R 的动机是 ggplot2 包允许我们只用几行代码就能创建视觉上吸引人的静态图。它是学术出版的最佳选择,并且得到了很好的支持和记录。我将可视化数据帧操作的结果,以显示包的有效性和查询的结果。下面是我用来设置数据的代码:

使用的数据集由 1990 年至 2018 年的篮球工资组成。数据帧包括球员的名字、他们的薪水、赛季开始年份、赛季结束年份、他们球队的三个字母缩写以及完整的球队名称。下图显示了所有按团队进行颜色编码的薪水(,因为纯黑色散点图一点也不好玩!)。

现在,我的家人最喜欢的球队是圣安东尼奥马刺队,所以我只看到马刺队过去 28 年的薪水是至关重要的。使用下面的 SQL 风格的查询,我将获取那个子集并绘制它。

使用 r 中的 subset 函数可以达到同样的效果。下面的代码和图表显示了与上面完全相同的数据。

这两个图的唯一区别是轴标签。因为我在 SQL 查询中重命名了列标题,所以它们在绘图中自动大写。简单地使用 subset 函数需要在 plot 函数中添加一行代码来更改轴标签。

SQL 语法的另一个用例是聚合函数。如果我们想要跟踪一段时间内的平均工资,我们可以使用这个 SQL 查询或 r 中的聚合函数。聚合方法中的 FUN 参数指定在聚合数据时要应用哪个函数,在本例中,它对值进行平均。我将在下面的要点中包括查询符号和聚合符号——我保证图形是相同的!

最后,我们将把这两个概念放在一起!要显示过去 28 年中平均工资最高的 10 个团队,我们需要几行 SQL:按团队分组平均工资,然后按降序列出前 10 名。一个相对基本的查询,尤其是与 R 语法的对应查询相比。在 R 中,我们必须使用 mean 函数按组进行聚合,然后重置列名,最后在数据帧被第二列重新排序后获取数据帧的头部。SQL 可读性更强,更直观,特别是对于不是 R 专家的人来说。下面的代码和图表显示了这些等效操作的结果。

希望这对于任何有 SQL 背景、试图进入 R 进行探索性分析的人都有帮助;语法比原生的 R 函数更简单易懂。如果你喜欢这篇文章或我的其他文章,我很乐意连接!我还要感谢 Jonathan Balaban ,我写 r 的原因

如何用简单的统计问题欺骗聪明的数据科学家

原文:https://towardsdatascience.com/how-to-trick-a-smart-data-scientist-with-a-simple-statistical-problem-531f91e40ba5?source=collection_archive---------4-----------------------

“概率是人生的向导”
――列纳德·蒙洛迪诺,《酒鬼的行走:随机是如何主宰我们的生活的》。

这是我的《我们生活的算法》系列之一。参见 链接 中另一个有趣的问题。

首先,确保你想捉弄的人真的很聪明。

其次,你使用的问题应该直截了当。

事实上,随着互联网的扩散,没有太多严谨的话题仍然存在争议。(感谢谷歌和维基百科)

但是,我今天要讨论的话题已经在网上激烈争论了几年了。这也导致了科学专业人士和数据科学家之间的分歧。

事不宜迟,我们开始吧。

看问题

列纳德·蒙洛迪诺是一名物理学家,也是史蒂芬·霍金的合著者。他的书 《酒鬼之行:随机性如何主宰我们的生活》 谈到了随机性和导致人们错误判断周围世界的认知偏差,然后给了我们如何做出明智决定的建议。

在介绍“样本空间”概念的章节中,Mlodinow 使用了下面的例子,

问题 A:男孩还是女孩

我的朋友尼克有两个孩子,他告诉你他至少有一个女孩,那么另一个孩子是女孩的概率是多少?

这似乎是一个简单的问题,直觉的回答是:我们知道一个是女孩,因此另一个是女孩的可能性应该是 50-50?

其实不然。

基于样本空间理论,我们可以列出所有可能的随机样本。

所以根据这个表,答案是 1/3,又名,33.3%

这个问题令人困惑的部分是上下文,Mlodinow 指出,如果我们指定第个第个是女孩,那么第个第二个女孩的概率是 50 %。

讨论

然而,另一个聪明人不同意 Mlodinow 的理论。

来自波莫纳学院的经济学教授加里·史密斯。他在耶鲁大学获得了经济学博士学位,之后被聘为助理教授。

在他的书中, 基本统计学、回归和计量经济学 引用了上面 Mlodinow 的例子作为对现实世界的一个标志性误解。他用不同的方式提问。

问题 B:另一个孩子

你看到我的朋友尼克和他的女儿走在街上。尼克告诉你他家里还有一个孩子。那么,另一个孩子是女孩的概率是多少?

这个问题看起来与 Mlodinow 的问题非常相似,但 Gary 有不同的答案和解释。

首先,他批评了答案“33.3%”的说法是错误的,然后他在下表中通过推理展示了他的理论。

男孩用 B 表示,因此 BB 表示第一个和第二个孩子都是男孩。

女孩用 G 表示,BG 表示第一个孩子是男孩,但第二个是女孩。

该表显示了平均分布在四个类别中的 400 个家庭。根据加里的说法,我们可以做出如下推论,

已知事实

  • 对于 BB 的 100 个随机样本,Nik 总是和一个男孩一起散步
  • 在 GG 的 100 个随机样本中,Nik 总是和一个女孩一起散步。
  • 如果尼克有一个男孩和一个女孩,一个合理的假设是,他和一个男孩或女孩一起走路的概率是相同的。

分析

  • 检查表格的第一行。当尼克和一个女孩散步时,我们可以假设有 100 个样本(GG)表明缺席的孩子也是一个女孩,而在其他 50+50 个样本(BG & GB)中,缺席的孩子是一个男孩。
  • 当尼克和一个男孩散步时,可以做出同样的推断,我们只需要比较 BB 和 BG+GB 的概率(100 比 50+50)

结论

不管尼克现在和谁在一起。另一个孩子的“男孩或女孩”概率保持不变。(它们是自变量)因此答案是的 1/2,而不是 1/3

当然,还有一个更直观的解释:当你看到一个女孩时,这是一个独立的事件,因此对其他孩子的性别没有影响。

如果你现在没有感到一点困惑,你可能仍然对这个问题有肤浅的理解(或者你是一个真正的天才,等着看你是否有与下面解释相似的思维过程)。

深入问题…

那么,Gary 和 Mlodinow,谁是对的,谁是错的?

事实上,他们都是对的,因为他们试图解决两个不同的问题。让我们再来看看上面的问题,

  • 我的朋友尼克有两个孩子,他告诉你他至少有一个女孩,另一个孩子也是女孩的概率是多少?
  • 你看到我的朋友尼克带着他的女儿走在街上。尼克告诉你他家里还有一个孩子,那么,另一个孩子是女孩的可能性有多大?

“看见一个女孩”和“至少是一个女孩”有区别吗?

你怎么想呢?现在是迷惑聪明人的时候了。经济学教授加里混淆了这两种说法的不同之处。

解释这种困惑的最简单也是最优雅的方式是贝叶斯方程。但是现在,我想尝试一种不同的方式来解释这个问题。(利用全概率定律)。

“至少有一个女孩”和“看到一个女孩”不是一回事。

这两个前提之间的差异可以表示为“时间和空间”维度中的“全局关系与局部关系”。

  1. 空间维度的“全球关系 VS .社会关系”。

“至少有一个女孩”并不保证你能看到一个女孩。

如上图所示,“至少有一个女孩”比“看见一个女孩”的覆盖面更大,因此在某种程度上,“看见一个女孩”的信息有更多的概率描述。

  1. 时间维度的“全局与局部关系”。

“至少有一个女孩”是鸟瞰统计结果的视图。

“看见一个女孩”是人类观察的一个视角。

下面显示了更直观的描述,

统计是对样本空间的总体描述。观察是平行宇宙中一个可能组合的实际事件(所有可能同时发生的事情)。

在理解了这两个问题之间的根本区别之后,我们可以得出结论说

  • “至少有一个孩子是女孩”是自然样本空间中一个普遍的概率问题。因此,答案应该是 1/3
  • “看见一个女孩”是要求从当前的观察中预测未知。这是贝叶斯统计。

因此,“看到一个女孩,并询问另一个孩子是女孩的概率”,等于“有两个孩子,你看到其中一个是女孩,那么这个女孩来自'女孩-女孩'家庭的概率是多少?”

对于“猜性别”这个话题就够了。

综上所述,即使是我们的系统 1 ( 快,直觉的本能,以及来自‘思考,快与慢’的感性大脑)也没有对概率有很好的直觉。但是,我们总是可以通过提高对概率因果关系的认识来提高我们解释周围环境中的动态和不确定性的能力。

摘要

如何通过概率建立主观假设和客观结果之间的联系?

为什么事件的偶然性概率会受到现实世界观察的影响?

未来将要发生的事情和过去发生的事情有什么根本的区别?

最后,如果你想找到一种方法来回答这些问题,或者你想欺骗你的聪明的数据科学朋友,下面的书将是一个好的开始。

  • 酒鬼的行走:随机性如何主宰我们的生活
  • 统计、回归和计量经济学
  • 《为什么之书:因果的新科学》

关于我,我是👧🏻现居澳大利亚墨尔本。我学的是计算机科学和应用统计学。我对通用技术充满热情。在咨询公司做 AI 工程师👩🏻‍🔬,帮助一个组织集成人工智能解决方案并利用其创新力量。在LinkedIn上查看更多关于我的内容。

如何对你的 Azure 数据科学项目进行审计跟踪

原文:https://towardsdatascience.com/how-to-troubleshoot-your-azure-data-science-project-in-production-5382b66cbaf9?source=collection_archive---------18-----------------------

1.介绍

假设一个机器学习模型正在生产中运行,重要的决策都是基于它的预测。或者假设一个模型有奇怪的结果,需要进行故障排除。因此,模型的审计跟踪是必不可少的,至少可以追溯到以下内容:

  • 模型预测的记录
  • 模型的版本和度量
  • 模型中使用的数据和算法
  • 创建模型的个人/团队

在这篇博客中,定义了一个 Azure 数据科学项目,然后讨论了如何创建审计跟踪。如果你对这个项目具体是如何实施的感兴趣,可以参考我之前的博客。请注意,这篇博客是独立的,没有必要先阅读前面的博客。

2.Azure 数据科学项目的设置

Azure 提供了很多进行数据分析和数据科学的可能性。在这个项目中,流行的 Azure 服务的功能被组合起来,以创建一个预测端点。项目的设置可以描述如下:

2. Setup of Azure data science project using popular Azure services

Azure 服务及其在本项目中的使用可以描述如下:

  • Azure Storage gen 2 用于存储数据。数据是不可变的,并且新数据被添加到具有时间戳的单独文件夹中,使得当它被添加时是清楚的。
  • Azure Databricks 用于模型的交互开发和特征工程。Azure ML 服务使用 Databricks Spark 集群作为计算来训练模型。请注意,创建了 sparkml 模型,但也可能创建了 scikit-learn 模型。
  • Git 用于笔记本的源代码控制,并作为资源库链接到 Azure Devops。在这个项目中,使用了 Azure DevOps 中的 git,但也可以使用 GitHub。
  • Azure 机器学习(ML)服务用于跟踪模型及其指标。Azure ML Service SDK 用于创建模型的 docker 映像并将其部署到 Azure Container 容器和 Azure Kubernetes 服务。有关使用 Azure ML 服务的部署可能性的概述,请参见此处的。
  • Azure DevOps 用于设置构建/发布管道。在构建阶段,使用 git、Databricks Spark Clusters 和 Azure ML Service SDK 创建 docker 映像。在发布阶段,docker 映像被部署为 Azure 容器实例用于测试,然后部署到 Azure Kubernetes 服务用于生产。
  • Azure 容器实例(ACI) 用作测试端点,而 Azure Kubernetes 服务(AKS) 用于生产。AKS 具有可扩展性、安全性和容错性。将 AKS 与 Azure ML Service SDK 一起使用,许多功能都是现成的,例如记录和评估模型数据和监控失败率、请求率

本项目的设置可视为“同类最佳”方法,具有以下优点/缺点:

  • 这种设置的优点是团队可以使用他们最喜欢和最有经验的工具。例如,使用已经用于其他 IT 项目的 Azure DevOps。或者使用已经用于公司内部其他大数据项目的 Azure Databricks。
  • 缺点是保留审计线索和故障排除会变得更加复杂。这将在下一章讨论。

3.审查跟踪

假设一个审计员想知道为什么使用 ML 模型做出某个决定(例如,为什么这个抵押被拒绝?).然后需要使用审计线索追溯模型决策的基础。在本章的剩余部分,将对本博客第一部分中介绍的主题进行审计跟踪,如下所示:

  • 3a。记录模型请求和预测
  • 3b。模型、图像和 HTTP 端点的版本
  • 3c。模型的度量和统计
  • 3d。模型中使用的数据和源代码
  • 3e。创建模型的个人/团队

3a。记录模型请求和预测

在数据科学项目中,该模型使用 Azure ML 服务 SDK 部署在 AKS 产品中。使用 Azure ML service SDK 和记录和评估模型数据特性,可以记录所有的模型请求和预测。这记录在 Azure 存储帐户中,该帐户附加到/modeldata/文件夹中的 Azure ML 服务工作区,另请参见下文:

3a1. Storage account where logging is stored

在 data.csv 中,可以找到请求的时间戳、输入数据和预测,请参见下面的示例

3a2. Logging of input request and logging

3b。模型、docker 映像和 HTTP 端点的版本

为了链接模型、图像和 HTTP 端点,请转到 Azure portal 中的 Azure ML 服务工作区,然后转到“部署”选项卡。这里可以看到 AKS 中使用的 HTTP 端点的 IP 地址和 docker 镜像版本。

3b1. HTTP endpoint, AKS and image

随后,可以在模型选项卡中找到模型版本。

3b2. Model used in docker image

请注意,可以在标签中找到的运行 id。这可以用于在下一部分中检索模型度量。

3c。模型的度量和日志记录

使用前一部分中的 run_id,您可以查找模型的度量和统计数据。转到 Experiments 并使用过滤器中的 run_id 来查找模型的指标。

3c1. Retrieve model metrics

对于该模型,记录 roc、prc 和假/阴性阳性/阴性。此外,您还可以使用 matplotlib 创建图像。

3c2. Display metics of models

3d。模型中使用的数据和源代码

在这一部分中,将确定用于训练模型的数据和来源。所有源代码和数据都存储在 Azure DevOps 项目的存储库中,因此第 3b 部分中确定的模型需要链接到存储库。

首先,查找使用 Azure ML 服务 API 将图像部署为容器的发布管道。在这个项目中,创建了一个夜间构建/发布管道,因此可以查看最后一个成功的发布,如下所示

3d1. Last succesfull build/release in Azure DevOps

在发布的日志中,可以找到发布步骤的日志。在部署步骤的日志中,可以找到对应于步骤 3b 中的 IP 和版本的 HTTP IP 地址和映像版本,见下文。

3d2. Logging of release

随后,通过点击工件框来下载发布的所有输入。在这个下载中,可以找到所有源代码,见下文。

3d3. Download build artifact

在这个项目中,数据不是版本控制的一部分,也没有存储在工件中。相反,数据存储在 Azure Storage gen 2 上,并且是不可变的。新数据被添加到带有时间戳的新文件夹中。随后,在构建管道中,记录哪些文件夹用于训练模型,从而可以清楚地知道使用了什么数据。

3e。创建模型的个人/团队

在上一节中,确定了用于创建模型的源代码和数据。在这一部分,追溯了是哪个人/团队更改了代码,以及这是在什么时候发生的。在步骤 3c 中下载的构建工件中,也可以找到提交 id,在本例中是 e670024。当您单击这个发布时,代码与之前的提交有所不同。此外,还可以找到变更的人员和日期,见下文。

3e1. Code compare with previous commit

通过单击 Parent 1 链接,您可以追溯到上一次提交,直到发现可疑的更改。或者,您也可以直接转到“提交”选项卡,查看最近提交的概述,并从那里开始,见下文。

3e2. Commit overview

最后,请注意,可以将您的 Azure Git 存储库与 Azure Databricks 连接起来,Azure Databricks 在本项目中用作交互式开发环境,请参见下面的截图以及使用此处的解释

3e3. Azure Databricks integration with Azure DevOps

4.结论

在这篇博客中,描述了一个数据科学项目的设置,其中结合了流行的 Azure 服务的功能。然后讨论了如何在这个项目中保留审计线索,以便可以追溯预测所基于的内容。当模型预测令人费解时,拥有一个良好的审计线索也有助于排除故障。这有助于将你的项目投入生产,参见下面的架构。

4. Setup of Azure Data Science project

如何调优决策树?

原文:https://towardsdatascience.com/how-to-tune-a-decision-tree-f03721801680?source=collection_archive---------0-----------------------

决策树的超参数如何影响您的模型,您如何选择要优化的超参数?

超参数调谐

超参数调优是在超参数空间中搜索一组可以优化模型架构的值。

这与调整模型参数不同,在模型参数调整中,您会搜索最能最小化成本函数的特征空间。

超参数调整也很棘手,因为没有直接的方法来计算超参数值的变化将如何减少模型的损失,所以我们通常求助于实验。首先,我们为所有超参数指定一个可能值的范围。现在,这是大多数人陷入困境的地方,我要尝试什么值,为了回答这个问题,你首先需要理解这些超参数的含义,以及改变超参数将如何影响你的模型架构,从而尝试理解你的模型性能可能如何改变。

定义值的范围后,下一步是使用超参数调整方法,有一堆,最常见和最昂贵的是网格搜索,其他如随机搜索和贝叶斯优化将提供“更智能”,更便宜的调整。这些方法并不是本文的重点,但是如果您想了解更多,请查看参考资料部分[1]。

决策图表

决策树是最流行和最广泛使用的机器学习算法之一,因为它对噪声的鲁棒性、对丢失信息的容忍度、对不相关的冗余预测属性值的处理、低计算成本、可解释性、快速运行时间和鲁棒预测器。我知道,这太多了😂。但是学生问我的一个常见问题是如何调整决策树。对于最大深度,我应该尝试的值的范围应该是什么,在叶节点上需要的样本的最小数量应该是什么?这些都是很好的问题,没有直接的答案,但我们可以做的是了解改变一个会如何影响你的模型。比如增加最大深度到底意味着什么,改变最小样本叶子对你的模型有什么影响。因此,在本文中,我试图向您介绍这些参数,以及它们如何影响您的模型架构,以及它对您的模型的一般意义。

让我们看看 Scikit-learn 的决策树实现,让我解释一下这些超参数是什么,以及它们如何影响您的模型。顺便说一下,我假设你对决策树有一个基本的了解。

由于决策树主要是一个分类模型,我们将研究决策树分类器。

决策树分类器

条件:字符串,可选(default="gini"):

衡量分割质量的函数。支持的标准是基尼杂质的“基尼”和信息增益的“熵”。

如果你想知道决策树节点是如何分裂的,那是通过使用杂质。杂质是节点上标记同质性的量度。有许多方法来实现杂质测量,其中两个 scikit-learn 已经实现的是信息增益和基尼杂质或基尼指数。

信息增益使用熵度量作为杂质度量,并且分割节点,使得它给出最大量的信息增益。而 Gini 杂质测量目标属性值的概率分布之间的差异,并分割节点以使其给出最少量的杂质。

根据论文“基尼指数和信息增益标准之间的理论比较”[3],基尼指数和信息增益一致/不一致的频率仅占所有情况的 2%,因此对于所有意图和目的,您几乎都可以使用两者之一,但唯一的区别是熵的计算可能稍慢,因为它需要您计算对数函数:

许多研究人员指出,在大多数情况下,分裂标准的选择不会对树的性能产生太大影响。正如“没有免费的午餐”定理所表明的那样,每个标准在某些情况下是优越的,而在另一些情况下是低劣的。

拆分器:字符串,可选(默认= "最佳")

用于在每个节点选择拆分的策略。支持的策略是选择最佳分割的“最佳”和选择最佳随机分割的“随机”。

根据 scikit-learn 的“最佳”和“随机”实现[4],“最佳”分离器和“随机”分离器都使用基于 Fisher-Yates 的算法来计算特征阵列的排列。您实际上不需要担心算法,唯一的区别是,在“最佳”拆分器中,它在拆分之前使用标准评估所有拆分,而“随机”拆分器使用随机统一函数,将最小特征值、最大特征值和随机状态作为输入。我们将在下面研究这些是什么,但现在,让我们看看拆分器将如何影响模型。

假设您有数百个要素,那么“最佳”拆分器将是理想的,因为它将根据杂质测量计算要拆分的最佳要素,并使用它来拆分节点,而如果您选择“随机”,则您很有可能最终得到的要素实际上不会提供那么多信息,这将导致树更深、更不精确。

另一方面,“随机”拆分器有一些优点,特别是,由于它随机选择一组要素并进行拆分,因此它没有计算最佳拆分的计算开销。其次,它也不太容易过度拟合,因为在每次分割之前,您基本上不会计算最佳分割,额外的随机性将在这里帮助您,所以如果您的模型过度拟合,那么您可以将分割程序更改为“随机”并重新训练。

因此,对于一个没有任何过度拟合的具有很少特征的树,为了安全起见,我会选择“最好的”拆分器,这样你就可以得到最好的模型架构。

max_depth: int 或 None,可选(默认=None)

树的最大深度。如果没有,则扩展节点,直到所有叶子都是纯的,或者直到所有叶子包含少于 min_samples_split 样本。

决策树可以达到的理论最大深度比训练样本的数量少 1,但是没有算法会让你达到这一点,原因很明显,一个很大的原因是过度拟合。请注意,这是训练样本的数量,而不是特征的数量,因为数据可以在同一特征上拆分多次。

让我们先来谈谈缺省的 None 情况,如果你不指定树的深度,scikit-learn 将扩展节点直到所有叶子都是纯的,这意味着如果你为 min_samples_leaf 选择 default,叶子将只有标签,其中缺省值是 1。请注意,这些超参数中的大多数都是相互关联的,我们将很快讨论 min_samples_leaf。另一方面,如果您指定一个 min_samples_split(我们接下来将会看到),那么节点将会展开,直到所有叶子包含的样本数都少于最小样本数。Scikit-learn 将根据哪个给你的树提供最大深度来选择一个。这里有许多移动的部分,min_samples_split 和 min_samples_leaf,所以让我们单独取 max_depth,看看当您更改它时,您的模型会发生什么,这样在我们完成 min_samples_split 和 min_samples_leaf 后,我们可以更好地直观了解所有这些是如何组合在一起的。

一般来说,你允许你的树增长得越深,你的模型将变得越复杂,因为你将有更多的分裂,它捕获更多的关于数据的信息,这是决策树过度拟合的根本原因之一,因为你的模型将完全适合训练数据,并且将不能在测试集上很好地概括。因此,如果您的模型过度拟合,减少 max_depth 的数量是防止过度拟合的一种方法。

深度太低也不好,因为模型会过拟合,所以如何找到最佳值,请进行实验因为过拟合和过拟合对数据集来说都是非常主观的,没有一个值适合所有解决方案。所以我通常做的是,让模型首先决定 max_depth,然后通过比较我的训练和测试分数,我寻找过度拟合或欠拟合,并根据我减少或增加 max_depth 的程度。

min_samples_split: int,float,optional(默认值=2)

分割内部节点所需的最小样本数:

  • 如果 int,那么考虑 min_samples_split 作为最小数。
  • 如果是 float,那么 min_samples_split 是一个分数,ceil(min _ samples _ split * n _ samples)是每次拆分的最小样本数。

min_samples_split 和 min_samples_leaf,如果你读了它们的定义,听起来好像是一个隐含着另一个,但是你需要注意的是,leaf 是一个外部节点,min_samples_split 指的是一个内部节点,根据定义,内部节点可以进一步拆分,而根据定义,leaf 节点是一个没有任何子节点的节点。

假设您指定了一个 min_samples_split,并且产生的拆分导致一个具有 1 个样本的叶,并且您将 min_samples_leaf 指定为 2,那么您的 min_samples_split 将不被允许。换句话说,无论 min_samples_split 值是多少,min_samples_leaf 始终是有保证的。

根据该论文,关于决策树的超参数调整的实证研究[5]对于在 scikit-learn 中实现的 CART 算法,理想的 min_samples_split 值往往在 1 到 40 之间。min_samples_split 用于控制过拟合。较高的值会阻止模型学习可能高度特定于为树选择的特定样本的关系。过高的值也会导致欠拟合,因此根据欠拟合或过拟合的程度,您可以调整 min_samples_split 的值。

【min _ samples _ leaf:int,float,optional(默认值=1)

叶节点上所需的最小样本数。任何深度的分裂点只有在左和右分支的每一个中留下至少 min_samples_leaf 训练样本时才会被考虑。这可能具有平滑模型的效果,尤其是在回归中。

  • 如果 int,那么考虑 min_samples_leaf 为最小数。
  • 如果是 float,那么 min_samples_leaf 是一个分数,ceil(min _ samples _ leaf * n _ samples)是每个节点的最小样本数。

类似于 min_samples_split,min_samples_leaf 也用于通过定义每个叶具有多个元素来控制过拟合。从而通过为每个样本专门创建一堆小分支来确保树不会过度适应训练数据集。实际上,这实际上只是告诉树,每片叶子的杂质不一定是 0,我们将在 min _ infinity _ decrease 中进一步研究杂质。

论文《决策树超参数调优的实证研究》[5]也指出,对于 CART 算法,理想的 min_samples_leaf 值往往在 1 到 20 之间。本文还指出,根据其相对重要性分析,min_samples_split 和 min_samples_leaf 对最终树的性能影响最大[5]。

根据 scikit-learn,我们可以使用 min_samples_split 或 min_samples_leaf,通过控制将考虑哪些拆分来确保多个样本为树中的每个决策提供信息。他们还说,一个非常小的数字通常意味着树会过度适应,而一个大的数字会阻止树学习数据,这应该是有意义的。我认为一个例外是当你有一个不平衡的阶级问题时,因为少数阶级占多数的地区会很小,所以你应该用一个较低的值。

min _ weight _ fraction _ leaf:float,可选(默认值=0。)

要求位于叶节点的权重总和(所有输入样本)的最小加权分数。当未提供 sample_weight 时,样本具有相等的权重。

min_weight_fraction_leaf 是要求位于叶节点的输入样本的分数,其中权重由 sample_weight 确定,这是处理类不平衡的一种方法。类别平衡可以通过从每个类别中采样相等数量的样本来完成,或者优选地通过将每个类别的样本权重之和归一化为相同的值来完成。另请注意,min_weight_fraction_leaf 将比不知道样本权重的标准(如 min_samples_leaf)更少偏向主导类。

如果样本是加权的,那么使用基于权重的预修剪标准(例如 min_weight_fraction_leaf)来优化树结构将会更容易,这确保了叶节点包含样本权重总和的至少一部分。

max_features: int、float、string 或 None,可选(默认=None)

寻找最佳分割时要考虑的特征数量:

  • 如果 int,那么在每次分割时考虑 max_features 特性。
  • 如果是 float,那么 max_features 是一个分数,在每次分割时考虑 int(max_features * n_features)个特征。
  • 如果“自动”,那么 max_features=sqrt(n_features)。
  • 如果“sqrt”,那么 max_features=sqrt(n_features)。
  • 如果“log2”,那么 max_features=log2(n_features)。
  • 如果没有,那么 max_features=n_features。

注意:直到找到节点样本的至少一个有效分区,对分割的搜索才会停止,即使它需要有效地检查多于 max_features 的特征。

每次出现分裂时,您的算法都会查看大量特征,并使用基尼不纯度或熵选取具有最佳度量的特征,然后根据该特征创建两个分支。每次查看所有特征的计算量很大,因此您可以使用各种 max_features 选项来检查其中的一些特征。max_features 的另一个用途是限制过度拟合,通过选择数量减少的特征,我们可以增加树的稳定性,并减少方差和过度拟合。

至于在选项中选择哪一个,这将取决于您拥有的功能的数量、您想要减少的计算强度或您拥有的过度拟合的数量,因此如果您有很高的计算成本或您有很多过度拟合,您可以尝试使用“log2 ”,根据产生的结果,您可以使用 sqrt 稍微提高它,或者使用自定义浮点值进一步降低它。

【random _ state:int,RandomState 实例或无,可选(默认=无)

如果 int,random_state 是随机数生成器使用的种子;如果是 RandomState 实例,random_state 是随机数生成器;如果没有,随机数生成器就是 np.random 使用的 RandomState 实例。

哈哈臭名昭著的 random_state,大部分新手都这么问我,为什么是 1,为什么是 0,为什么是 42?42 因为那是生命的意义,咄。

random_state 并不是一个真正需要优化的超参数,您应该这样做吗😋。让我从何时以及为什么应该设置 random_state 开始。最直接的答案是,这样你就可以得到一致的结果,这在一定程度上是因为记住 splitter,它会给你的结果带来一些随机性,所以如果你重新运行决策树,你的结果会有所不同,但不应该太不同。

这就引出了我的下一个观点,我看到新学生在玩 random_state 值,他们的精度会发生变化,这是因为决策树算法是基于贪婪算法[6]的,它使用随机选择的特征(拆分器)重复多次,这种随机选择受到伪随机数发生器[7]的影响,伪随机数发生器[7]将 random_state 值作为种子值, 因此,通过改变 random_state,您可能会随机选取好的特征,但您需要认识到的是,random_state 不是一个超参数,随着 random_state 改变您的模型的准确性仅意味着您的模型有问题。 这是一个很好的暗示,在你的数据中有许多局部最小值,决策树没有很好地处理它,所以我宁愿让你设置一个 random_state 并调整你的其他参数,这样你就不会陷入局部最小值,而不是玩弄 random_state。

min _ infinity _ decrease:float,可选(默认=0。)

如果该分裂导致杂质减少大于或等于该值,则该节点将被分裂。

加权杂质减少公式如下:

N_t / N * (impurity - N_t_R / N_t * right_impurity - N_t_L / N_t * left_impurity)

其中 N 是样本总数,N_t 是当前节点的样本数,N_t_L 是左子节点的样本数,N_t_R 是右子节点的样本数。

N,N_t,N_t_R,N_t_L 都是指加权和,如果传递 sample_weight。

最小杂质减少帮助我们根据杂质来控制树的生长深度。但是,这种杂质是什么,它如何影响我们的决策树?记得在标准部分,我们快速看了基尼指数和熵,它们是杂质的一种度量。杂质测量定义了多个类别的分离程度。通常,当属性值的数据被平均分割时,杂质测量值应该最大,当所有数据属于同一类时,杂质测量值应该为零。更详细的解释将需要我们进一步进入信息论,这不是本文的范围,所以我将尝试解释改变杂质值如何影响您的模型,以及如何知道何时改变这些值。

最好的方法是绘制决策树,并研究基尼指数。如果您对正在处理的数据集有领域知识,那么解释决策树应该相当容易,因为叶节点的基尼指数为 0,因为它是纯的,这意味着所有样本都属于一个类。然后,您可以查看导致基尼系数为 0 的分割,并查看是否有必要对您的类进行这样的分类,或者您是否可以减少深度,从而得到一个更概化的树,如果是这样,您可以增加 min _ infinity _ decrease 以防止进一步分割,因为现在,如果杂质没有减少您指定的数量,节点将不会进一步分割。请注意,这将影响你的整个树,所以,你必须用这些数字做实验,但上面的解释应该给你一个起点。

class_weight:字典,字典列表,“平衡”或无,默认=无

与{class_label: weight}形式的类相关联的权重。如果没有给定,所有类的权重都应该是 1。对于多输出问题,可以按照与 y 的列相同的顺序提供字典列表。

class_weight 用于为每个输出类提供权重或偏差。但这实际上意味着什么,看当算法计算熵或基尼不纯度以在节点处进行分裂时,产生的子节点由 class_weight 加权,根据您指定的类比例给出子样本权重。

当数据集不平衡时,这非常有用。通常,您可以从类的分布作为类权重开始,然后根据决策树的倾向,您可以尝试增加或减少其他类的权重,以便算法相对于其他类惩罚一个类的样本。最简单的方法是指定“平衡的”,然后从那里开始自定义权重。

请注意,这不像欠采样或过采样技术,一个类中的样本数量实际上不会改变,而是分配给它的权重会改变,您可以在打印决策树和每个节点中的值时看到这一点,它将变为

weight * (the number of samples from a class in the node) / (size of class)

预排序:bool,可选(默认=False)

是否对数据进行预排序,以加快拟合中最佳分割的查找速度。对于大型数据集上决策树的默认设置,将此设置为 true 可能会减慢训练过程。当使用较小的数据集或受限的深度时,这可以加速训练。

这个参数相当简单,如果您有一个小数据集,或者如果您将限制树的深度,并且在运行第一次迭代后,您有一个不平衡的树,其中大多数数据点仅位于叶节点的一小部分上,使用预排序将有助于您。

预排序的工作方式是,在学习之前首先对所有变量进行排序,在每个节点评估时使用排序向量,在选择最佳分割后,您将分割数据点和排序索引,以便将数据子集和排序索引子集发送到子节点。因此,你可以在递归中应用这一思想。但是,请注意,如果数据实例的数量大于输入要素的数量,则这种方法有效。

摘要

决策树的复杂性对其准确性有着至关重要的影响,并且它由所使用的停止标准和所采用的修剪方法来明确控制。通常,树的复杂性是通过以下度量之一来衡量的:节点总数、叶子总数、树深度和使用的属性数量[8]。max_depth、min_samples_split 和 min_samples_leaf 都是停止标准,而 min_weight_fraction_leaf 和 min _ infinity _ decrease 是修剪方法。

尽管所有这些几乎都实现了停止或修剪方法,但它在应用于模型的级别上有所不同。如果你有一个硬停止标准,你的模型可能会拟合不足,所以如果你把它改为一个宽松的停止标准,那么你的模型可能会过度拟合,这就是为什么我们有修剪方法。我们应该有一个宽松的停止标准,然后使用修剪来删除导致过度拟合的分支。但是请注意,修剪是准确性和可推广性之间的折衷,因此您的训练分数可能会降低,但是训练分数和测试分数之间的差异也会降低。

我希望您对这些参数有更好的了解,并且在优化超参数时,它们可能会如何相互作用。但是如果有不清楚的地方,请在评论中告诉我,我会很乐意进一步解释。

随时加我上 领英 或者关注我上 脸书

参考

[1] 机器学习模型的超参数调优。

[2]sci kit-学习决策树分类器

[3] Laura Elena Raileanu 和 Kilian Stoffel,“基尼指数和信息增益标准之间的理论比较”《数学和人工智能年鉴》41:77–93,2004 年。

[4] Scikit-Learn 拆分器实现

[5]拉斐尔·戈梅斯·曼托瓦尼、托马什·霍瓦特、里卡多·切里、西尔维奥·巴尔邦·茹尼奥尔、华金·范舍伦、安德烈·卡洛斯·庞丝·德莱昂·费雷拉·德卡瓦略,“决策树超参数调整的实证研究”
arXiv:1812.02207

[6] 贪婪算法

【7】伪随机数发生器

[8] Lior Rokach,Oded Maimon,"第 9 章:决策树"

如何调整 tSNE 的超参数

原文:https://towardsdatascience.com/how-to-tune-hyperparameters-of-tsne-7c0596a18868?source=collection_archive---------3-----------------------

生命科学的数理统计和机器学习

三个简单的规则,使美丽的 tSNE 图

Image source

这是生命科学的数理统计和机器学习专栏的第二篇文章。在第一篇中我们讨论了在生命科学中我们是否以及在哪里有适合机器/深度学习的大数据,并强调了单细胞是最有前景的大数据资源之一。t-分布式随机邻居嵌入(tSNE) 是一种机器学习非线性降维技术,对于单细胞数据分析来说是绝对核心的。然而,为 tSNE 选择超参数可能会让初学者感到困惑。

在这篇文章中,我将分享我对选择超参数的最佳值的建议,如困惑度、要保留的主成分数和运行 tSNE 的迭代次数

如何有效地使用 tSNE

在教授单细胞 RNA 测序(scRNAseq)课程时,我不断收到关于tSNE 对超参数如困惑度的敏感性的问题。这些问题通常是由这篇精彩的文章激发的,这篇文章讲述了解读剧情的挑战。

A popular tutorial on developing intuition behind tSNE

尽管我非常尊重帖子的主要信息,但我认为 scRNAseq 社区不应该过于担心 困惑和其他 tSNE 超参数,因为:a)帖子中的许多例子来自抽象的数学拓扑,并不真正类似于 scRNAseq 数据,b)帖子专注于在现实世界 scRNAseq 分析中很少使用的极端 tSNE 超参数。

如果你做 scRNAseq 分析,你不会避免流行的 Rtsne 函数和 R 包,它是基于 Barnes-Hut C++实现的原始 tsne 算法。Rtsne 函数有三个主要的超参数:

  1. initial_dims(默认值为 50)假设 pca=TRUE
  2. 困惑(默认 30)
  3. max_iter(默认值为 1000)

在这里,我们将浏览这些超参数并解释它们的含义。显然,它们的默认值可能不适用于任意数据。在这里,我将解释如果您不确定从哪里开始,如何为您的特定数据集选择最佳 tSNE 超参数。

如何选择最佳的电脑数量?

scRNAseq 是高维数据(~20 000 维/基因),而 tSNE 难以处理高维数据。因此,通常您希望使用 PCA 等线性或 Autoencoder 等非线性方法(参见此处的)将初始维数减少到 30 - 50 个潜在变量( initial_dims ),并将其用作输入 tSNE 的新数据集。这里为了简单起见,我们将使用 PCA 进行预降维,因为 PCA 在分离信号和噪声方面非常出色。让我们使用来自癌症相关成纤维细胞(CAFs) 的 scRNAseq 数据,绘制由主成分(PCs)解释的方差百分比:

看起来很眼熟,不是吗?然而,我们应该保留多少个主成分(PC)来输入到 tSNE 中,即 initial_dims 应该取什么值:20、30、50 或者更多?这里我们有一个难题:1)如果我们选择太多的电脑,我们将包括“噪音”电脑从图的尾部,但是 2)如果我们选择太少的电脑,我们可能会失去信号从数据。为了做出这个决定,我们记得随机化是数据科学家的朋友,并将比较由 PCs 解释的观察方差置换方差。为此,我们对表达式矩阵的元素进行混洗,执行 PCA,并检查置换矩阵的上图是什么样的:

第一个图中的红色曲线是 PCs 解释的置换方差的平均值,这可以被视为“噪声区”。换句话说,观察方差(绿色曲线)与置换方差(红色曲线)的交点决定了我们的数据中有多少信息量。此外,由于我们有一个置换方差的向量,因此可以计算每个 PC 的观察方差与置换方差的差异的 p 值。对于 caf 的情况,我们的结论是,应该为 tSNE 保留 30 个 PCs,其余的应该忽略,因为它们的值属于“噪声区”。

如何选择最佳困惑度?

困惑也许是 tSNE 最令人困惑的超参数。tSNE 的作者 Laurens van der Maaten ,在FAQ:5 到 50 之间的困惑范围的典型值。一个显而易见的问题立即浮现在我的脑海:“对于多少个数据点?如果我有 10 000 个单元格,我还应该使用介于 5 和 50 之间的困惑度吗?”。在 FAQ 的下一句中,Laurens van der Maaten 补充道:

粗略地说,可以说更大/更密集的数据集需要更大的困惑

这听起来很合理,但是为了捕获局部和全局数据结构,应该用什么函数形式来表示困惑与单元数量?为了回答这个问题,一年前我收集了当时公开可用的 43 个 scRNAseq 数据集,其中许多是从这里下载的。 Valentine Svensson 有另一个更全面和更新的 500 个 scRNAseq 数据集的列表。对于 43 个数据集的每一个,我做了几个 tSNE 图,复杂度从 3 到 N/3 不等(Rtsne 函数中默认的最大复杂度),N 是细胞的数量。对于 CAFs 数据集,看起来是这样的:

接下来,我仔细查看了这些图,以选择一系列对我来说聚类看起来最透明的困惑,并绘制了这个困惑范围的平均值与每个数据集的单元格数量的关系。正常(上图)和对数标度(下图)的曲线如下:

对对数标度的依赖性看起来是线性的,拟合线性模型 I 得到log(Perp)=-0.179+0.51 * log(N)。请注意 log(N)前面的系数 1/2 ,这暗示着困惑随着 Perp ~ N^(1/2) 而增长。后来我意识到这个幂律非常类似于在 K -最近邻(KNN)算法中选择最佳 K 的经验法则。事实上,在 KNN 机器学习中,人们普遍认为最优的k~n^(1/2。由于困惑背后的直觉是每个数据点能“感知”到多少个邻居,这就印证了上面得到的幂律。

现在让我们试着分析推导这个幂律。由于 tSNE 是基于最小化 Kullback-Leibler (KL)散度,所以也许可以从 KL 的最小值中找到最佳困惑?然而,如果我们将 KL 绘制为在其他参数固定的情况下的困惑度的函数,则它单调下降。

因此,就困惑度而言,KL 没有最小值,KL 总是更喜欢更高的困惑度,尽管我们知道太大的困惑度会导致一大堆没有任何聚类的点。因此,我们需要建立另一个分数 函数,它包括 KL 和一个额外的贡献,因为太大的困惑而惩罚 KL。假设 KL 表现为 1/困惑,一个总是有最小值的简单函数将是分数~ 1/困惑+困惑。然而,困惑通常是一个很大的数字,因此得分函数将由第二项支配。使两个贡献处于相同数量级的一个简单技巧是将第二项归一化单元数 n,最后,为了找到分数的最小值,我们计算其关于困惑度的导数,并使其等于零。解这个方程导致困惑~ N^(1/2).

Simple scaling derivation of the power law Perplexity ~ N^(1/2)

尽管得出幂律的经验方法,《困惑~ N^(1/2 》,不能被认为是适当的研究,但它有助于发展关于困惑的概念及其与细胞数量的关系的直觉。另一方面,关于 tSNE 的许多事情都是基于纯粹的直觉和经验法则,因为与 UMAP 相比,tSNE 没有坚实的数学背景。因此,如果你不确定对你的特定数据集使用什么样的困惑,试试 N^(1/2 ),你就不会太离谱了。

如何选择最优迭代次数?

当谈到 tSNE 收敛所需的迭代次数时,最简单的建议可以是迭代次数越多越好。然而,实际上这对于大数据集是不可行的,因为可能需要等待几天才能达到例如 10 000 次迭代。相比之下,如果使用的迭代次数太少,聚类可能不可见,通常会在 tSNE 图的中心发现大量数据点。这种情况下该怎么办?如果你仔细观察文献中可用的 tSNE 图,你会注意到数据点之间的最大距离约为 100。这个简单的经验法则表明算法达到了收敛,进一步增加迭代次数只会略微改变图形。对于 CAFs 数据集,我们可以观察到规模如何在训练开始时仅跨越几个单位,并在大量迭代(如 max_iter = 1000)时增长到约 60 个单位,这也导致更明显的聚类。

Changes in tSNE plot when increasing the number of iterations

摘要

在这篇文章中,我们了解到,尽管 tSNE 可能对其超参数很敏感,但有一些简单的规则可以为 scRNAseq 数据获得好看的 tSNE 图。通过表达式矩阵的随机化可以找到输入 tSNE 的最佳 PC 数量。根据简单的幂定律困惑~ N^(1/2) 可以从单元的数量计算出最佳困惑。最后,最佳迭代次数应该提供 ~100 个单位的数据点之间的最大距离。

在下面的评论中,让我知道生命科学中的哪些分析对你来说特别神秘,我会在这个专栏中尝试解决它们。在媒体关注我,在 Twitter @ NikolayOskolkov】关注我,在 Linkedin 关注我。我打算写下一篇关于做集群而不指定集群数量的帖子,敬请关注。

如何将黑暗的湖泊变成黄金

原文:https://towardsdatascience.com/how-to-turn-dark-lakes-into-gold-6961f390b8?source=collection_archive---------31-----------------------

在过去的几年里,许多公司已经“人工智能清洗”了他们的品牌,以加入人工智能的潮流。人工智能驱动、人工智能内部、人工智能驱动这些术语似乎已经被默认添加到每一个软件和服务产品中。问题是,这些公司是通过人工智能战略赚钱(做“认知”),还是像大数据收集和存储投资那样赔钱。

在这篇博客中,我将总结我从上周在圣克拉拉举行的 AI &北美大数据博览会 2019 活动中获得的信息。我将介绍人工智能创造的潜在价值,以及为 ML 模型的创建减少著名的 80%数据准备的机会。显然,这是当前全行业的话题。

乍一看,人工智能&大数据博览会北美 2019 是一个相当不寻常的设置,人工智能/大数据、区块链、5G 和安全共同位于一个大型博览会中,有一个展厅和平行的会议轨道。自然,我对人工智能/大数据感兴趣,希望了解趋势在哪里,行业在哪里,以及围绕这一学科正在进行的一些研究。有趣的是,在查看议程后,我很快发现了许多跨学科的内容;5G 分析、Calibra 采用因素、用于安全测试自动化的人工智能等等。

我花了两天时间吸收、开会、讨论和整合。以下是最让我产生共鸣的。

有一个共识,数据战略的圣杯涉及促进业务的战略、战术和运营问题的生成,这些问题到分析的翻译是通过文本、或语音、或任何对首先提出问题的人来说更容易接近的东西来提供的。听起来很简单,对吧?没那么快。

迷失在翻译中:

  1. Gartner 预测“到 2020 年,50%的组织将缺乏足够的人工智能和数据读写技能来实现商业价值。”以及“人工智能实施增加 270%”、“250,000-预计到 2024 年美国将出现 DS 短缺”、“90 天以上才能完成任务”和“全球 DSs 供应紧缩”。

看起来数字不匹配。我们打算利用人工智能,但没有足够的人力资源来这样做。当供应减少时,价格就会上涨,这使得数据科学(DS)的工资飙升。由于高成本、短缺和无法有效利用他们的 DS 人员,许多项目在翻译中失败或丢失。

2)为什么无法利用这一资源?我们都知道,业务人员对盈利能力、可持续性、品牌、客户、合作伙伴关系和合规性感兴趣,而 DS 团队则关注 NLP、CV、OCR 和 NN。在这两者之间,有确保可伸缩性、安全性、可靠性、性能和容量的 RnD 团队。因此,在业务人员和 DS 人员之间有一条沟通的护城河。他们只是说不同的语言。

3)结果,由于 a)缺乏信任和对业务逻辑的理解,以及 b)训练数据中的固有偏见,以及 c)要求过程更加清晰的立法(在某种意义上是一个黑箱),新的人工智能解决方案和应用被创建和放弃。

数据谱系

要实现数据驱动,我们不仅要提出正确的业务问题,还必须构建坚实的数据基础,使我们能够使用数据回答这些问题。

可能的解决方案是驻留在单个技术堆栈上的数据沿袭。挑战:如何让每个人都可以访问数据谱系?DBA 需要看到与 VP 不同的东西。这里的度量标准是沿袭调查的速度,以及基于沿袭所提供的信任的决策速度。俗话说,真理没有单一的来源,只有单一版本的真理。换句话说,让每个人都可以使用数据谱系将克服“确认偏差”,并用支持它的数据来辅助论证。

数据引力的第 22 条军规:

数据量呈指数级增长。例如,一辆自动驾驶汽车每天产生 4TB 的数据,相当于 3000 个人产生的数据。将数据移动到 BI/Analytics 中会产生成本限制。另一方面,由于数据重力,拥有相同的存储和分析提供商将使客户陷入困境(Google/Looker)。这导致了过多的工具和解决方案,这些工具和解决方案经常不能相互集成,使得寻找答案或理解其来源变得更加困难。

一些供应商倾向于在边缘(GPU、FPGAs、ASICs)执行特征提取,并集中运行逻辑计算。

最终,除了吞吐量等物理限制之外,每个人都应该计算维护的 OPEX、资本支出和总拥有成本。这是一个权衡的游戏。

会话/自然语言处理

高达 23%的企业用户是数据盲。除非消费问题得到解决,否则拥有数据收集、存储、沿袭和分析不会帮助他们做出决策。关于自然语言查询和对话式人工智能作为人工智能应用程序的接口,可以桥接数据(il)读写问题,有过多次讨论。

一位来自优步的研究人员(他以前从事过 Alexa 开发)提出了在开发这些界面时需要解决的几个重点领域:

自然语言理解很难实现,因为它不能用数学来表示

开放式问题会导致不确定的答案,即实际观点

领域系统对话系统仍处于研究阶段

由于对话流程的实施和答案的构建,一次处理多个句子是一个挑战

测试人工智能

根据 Forrester 的调查,在过去几年中,软件测试自动化在所有记录的测试中占 46%。我们可以用人工智能来改善这一点吗?

显然,37%的受访公司使用 ML 进行测试,主要用于预测性维护(不完全是测试,更像是操作)和增强人工测试人员的视觉测试。只有 26%的人声称测试过自主 AI 应用。在未来,预计会有 API 测试生成自动化、测试生命周期优化,以及最终的体验测试。

在没有 XAI(人工智能的可解释性/可解释性)的情况下,完全自主地将人类从循环中带走,人工智能应用的风险会增加。这使得企业公司更难甚至不可能扩展人工智能,特别是在医疗、金融和保险等高度监管的领域。

例如,固有的偏见可能会对有关人类生命的决定构成巨大威胁,就像美国 12 个法院使用的指南针推荐系统一样。

那么应该如何测试 AI 呢?我们可以使用 F1 得分指标来衡量准确性,Fair ML,AI fairness toolkit 和 openscale 都可以是一个好的开始。

XAI

谈到可解释性,Zynga 在一个标准化的管道中自动提取特征,适用于所有游戏,支持牵引力、采用率和终身客户价值的优化。将人为因素排除在流程之外可以成倍提高效率。如果你想知道工程特征的自动化是否减少了 XAI,答案肯定是肯定的。因此,这些游戏将能够进化和改进,变得更加令人上瘾,而我们却不知道是如何做到的。社交网络上有一集《黑镜》突然看起来不那么牵强了。

新的商业模式:

认知术语出现了很多——试图找出如何利用人工智能来增加收入或降低成本。

例如,众所周知的消费电子和家用电器公司 LG 推出了 LG ThinQ,这是一个“融合先进人工智能技术的产品和服务品牌”。这里的新奇之处在于“零 UX 或原理”。LG 不打算为其 ThinQ 产品开发任何界面,而是与 Alexa、谷歌助手和 Yandex 等其他本地助手集成,以与消费者沟通。LG 开源的 Auptimizer 是一款用于优化人工智能模型的工具,可以在内部或与 AWS 一起使用,并且是模型不可知的。这是进入汽车即服务市场的一步。

这出乎意料,尤其是当 DS 自助服务平台有了有趣的发展时。他们不仅加强了 ML-ops 解决方案(数据流等),还开创了专业服务实践业务,这仅支持以下主张,即通用工具在没有业务目标与 DS 问题之间的正确映射时,或者在使用混乱/稀疏/不适当的数据时经常失败。

埃森哲在 5G 分析方面提供了一个意想不到的角度(至少对我来说是意想不到的)。据称,价值将位于连接提供商之外,或下游,在分析应用程序、安全等方面..这将是 5G 电子竞技/游戏的实时分析,这将推动 5G 的采用,包括脑机接口。

将黑暗的湖水变成金色

说到商业模式,现有的大多数都包含了经济价值曲线收益递减的范式。意味着用同样的收益投入更多。想想软件产品。越来越多的资金被投入到没有额外相关收入的研发中,只是为了跟上竞争的步伐。

答案是数据。

如何确定数据的价值?

评估资产的框架是基于你为之付出的和因使用而被剥夺的。数据不一样。你用得越多,它就越有价值,而且零使用成本。

Schmarzo 经济数字资产估值定理是这样的:

“在以知识为基础的行业中,学习经济比规模经济更有力量。改进分析模型的预测效果会对以前使用这些分析模型的用例产生影响。”数据是一种永不枯竭、永不磨损的资产,可以以接近零的边际成本在无限的用例中使用。这就是为什么特斯拉是一种不断升值的资产,因为它收集数据,学习和改进。

总而言之,转化为技术定义的业务问题的自动化(如果你愿意,也可以说是自助式 BI 的发展)得到了单一数据基础的加强,这将优化人工智能的支出,而新的商业模式,例如 5G 分析将推动货币化。

你想改变游戏吗?换框架。将您的数据变成黄金。

如何把物理变成优化问题

原文:https://towardsdatascience.com/how-to-turn-physics-into-an-optimization-problem-11b3fbf83062?source=collection_archive---------6-----------------------

思想和理论

如果你知道机器学习的基础,你就已经知道如何在没有意识到的情况下解决大量的物理问题。

这篇文章主要是关于一个叫做拉格朗日力学的工具,它可以让你解决物理问题,比如最优化问题。

在机器学习中,你最小化预测和标签之间的损失,以找到最佳预测器

在拉格朗日力学中,你可以最小化一个系统的总作用力来寻找它的运动

代表权问题

拉格朗日力学比传统的牛顿力学有一个巨大的优势,因为它的表示不变,这意味着你可以自由选择最简单的表示来工作。

作为一个例子,我们将讨论最简单的一种机器人,一个二维钟摆——你的每个肢体都是一个钟摆,而你的身体是由一堆钟摆组成的。

Image by Mark Saroufim

在这种情况下,我们感兴趣的是描述弦末端的质心运动,所以在每一时刻 t,我们需要找到 3 个变量

  1. p →质量的位置
  2. v →质量速度
  3. 质量的加速度

v 是 p 随时间的变化率

a 是 v 随时间的变化率

所以我们只需要预测一个变量 p。

p 是物体从开始时间 s 到结束时间的位置序列

但是我们如何准确地表示质心的位置呢?显而易见的首选是使用笛卡尔坐标 x,y。

Image by Mark Saroufim

但是现在我们面临一个两难的问题——我们应该把坐标放在球本身的中心,还是放在墙上,或者其他什么地方?有没有什么原则性的方法来决定哪个坐标更好?

我们可以用钟摆的另一种表示法:

Image by Mark Saroufim

我们可以完全描述钟摆所有可能的位置

  • θ →天花板和绳子之间的角度
  • l →绳子的长度

综合起来,你就得到极坐标。

极坐标和笛卡尔坐标是同构的(数学上是相同的),但是极坐标在这种情况下更有优势。

在系统的演化过程中,l 从未如此有效地改变,我们可以只用一个变量θ,而不是两个变量 x 和 y,来描述整个系统的运动。

配置空间

θ表示更好的一个主要原因是,如果我们试图从 t 时刻开始预测球在 t + 1 时刻的位置,只有 3 个可能的解

在笛卡尔坐标中,解在 x,y 平面的某处,但是从时间 t 到 t + 1 有无限多可能的方向。

Image by Mark Saroufim

但是在极地环境中,解决方案只能有两个方向。

Image by Mark Saroufim

圆圈是摆问题所有可实现解决方案的集合中的配置空间,粒子通过该空间的特定路径描述了其实际运动,称为配置路径

以这种方式研究系统的“形状”是被称为拓扑学的更大领域的一部分。拓扑学在研究物理系统的运动时非常有用,所以这里先介绍一下。

让我们来看一个更复杂的系统,一个双摆——想象第一个球是你的肘部,你可以看到它是如何代表更有趣的东西,也就是你的手臂。

Image by Mark Saroufim

你可以从两个角度来描述这个系统

如果固定第一个角度,那么第二个角度的配置空间又是一个圆,因此两个角度的新空间看起来像。

Image by Mark Saroufim

由于在较大的圆上面有无限多的小圆,我们最终得到的形状就是拓扑学中著名的圆环。

Image by Mark Saroufim

这个三维物体上的每一点都代表了双摆位置的一个可能的解决方案。我们本质上把这个系统的解描述为一个空间。

然后,一个示例摆的实际运动由该环面上的路径来描述。

Image by Mark Saroufim

如果你用牛顿力学工作,需要改变你的表示,看看什么是最好的,你需要重新推导你所有的公式,当你进入双摆领域时,涉及到一些棘手的三角学。

另一方面,拉格朗日 L 与表象无关,这意味着。

现在让我们定义什么是拉格朗日函数,看看它是如何工作的。

拉格朗日算符

现在我们知道,我们可以用路径来描述一个系统的运动,但是一个系统在它的构型空间中,实际上会走哪条路径呢?

大自然是懒惰的

所有物理过程都选择最小化总动作的路径。

一个著名的例子是折射,光在这里弯曲,因为它这样做更快。

Image by Mark Saroufim

系统 L 的拉格朗日量可以理解为它的“活泼性”。它的正式定义是

其中 T 是动能,V 是势能。

动能 T 总是不变的

势能取决于被描述的系统的类型,但是对我们来说,我们主要看重力势能

在哪里

m →物体的质量

g →重力常数

h →离地高度

更著名的能量守恒定律是势能和动能之和,它在剔除糟糕的物理理论方面非常可靠。

能量守恒定律告诉我们的是,没有新的能量可以创造,也没有能量可以损失。相反,我们有一个权衡,如果 T 增加,V 减少,如果 T 减少,V 增加。

Image by Mark Saroufim

系统产生的总作用记为 S,可以通过将构型空间中每个位置的所有拉格朗日量相加来计算。

欧拉-拉格朗日方程

那么现在我们可以推导出任何系统的拉格朗日 L,那么我们如何得到最小的 S 和产生它的路径呢?

从拉格朗日方程到解决方案的转换是通过欧拉-拉格朗日方程完成的,该方程将找到最小作用的路径。

欧拉-拉格朗日方程是

这个公式看起来比实际更复杂,通过几个例子可以更好地理解。

落球

我举的两个例子都深受这个系列的启发

假设我们有一个质量为 m 的球落到地上

Image by Mark Saroufim

动能 T 只是 y 的函数,因为没有侧向运动

势能 V 是

所以拉格朗日量是

欧拉-拉格朗日方程只是 y 的函数,所以我们可以简化它

插入 L

这简化为

所以我们最终从零开始推导牛顿定律🤯

移动小车摆锤

最后一个例子是向你们展示拉格朗日力学是如何工作的,但这不是拉格朗日力学发光的例子。

当系统复杂,有许多变量,用牛顿力学很难建模时,拉格朗日力学就大放异彩。

所以我们要想象一下,我们有一辆质量为 M 的移动小车,有一个质量为 M 的摆,一想到我需要在这里建模的不同力的数量,我就头疼。

Image by Mark Saroufim

谢天谢地,拉格朗日使得求解这个系统容易得多,因为我们可以独立地对每个对象求和。

我们可以用 2 个变量来模拟球和车的位置,每个变量总共有 4 个变量,或者我们可以使用一个技巧来改变坐标系,使我们的生活更容易。

我们做了以下两个替换

有了这个变量的变化,我们就可以导出拉格朗日 l。

记住,自然不在乎我们如何表现它

动能很容易。小车只能在 x 方向移动,而摆锤可以在 x 和 y 方向移动。

势能

所以总拉格朗日量是

一旦有了 L,你就可以应用欧拉-拉格朗日方程,来看看这个系统是如何运行的。

对比一下牛顿力学的方法

  1. 在每一个物体和每一个其他物体之间创建一个力图,以创建一组方程——可能是指数级的
  2. 将这些方程代入常微分方程求解器,因为物理学中的大多数导数都没有封闭形式的解——祈祷吧

牛顿力学和拉格朗日力学的区别就是命令式和声明式编程的区别。像拉格朗日力学这样有效的声明性范例总是更受欢迎,因为 SQL 比 UNIX 脚本更受欢迎。

建模约束

拉格朗日力学的最后一个优点是,我想简单地讲一下,给系统添加约束是很容易的。

约束是这样的函数

f 可以是对最大速度的约束,也可以是对关节可以弯曲多远的约束,或者是对两个对象的碰撞应该有多柔和的约束。

您可以有任意多的约束

你所需要做的,不是把 L 代入欧拉-拉格朗日方程,而是代入,λ是权重,代表每个约束的重要性。这个技巧被称为“拉格朗日乘子”,广泛用于凸优化。

密码

尽管拉格朗日力学是一个强大的想法,让你大大简化实现物理引擎,据我所知,它还不是一个主流想法。如果你知道任何使用它的物理引擎,请让我知道,我会在以后的博客文章中描述它在真实的物理引擎中是如何工作的。

我第一次看到拉格朗日力学的完整实现是在那本神奇的书——经典力学的结构与解释。这里的实现是用 LISP 实现的,LISP 是一种很好的学习语言,但以我的经验来看,这是一种很难在大型项目中使用的语言。

因此,我建议看一看 https://github.com/MasonProtter/Symbolics.jl项目,它提供了一个受 SICM 实现启发很大的 Julia 实现。

自述文件特别谈到了谐振子,这只是一个附加在弹簧上的重物的花哨术语。

Image by Mark Saroufim

https://github.com/MasonProtter/Symbolics.jl

后续步骤

哈密顿力学

拉格朗日力学让我们很容易计算出一个系统将要走的路径,但是它并没有给我们太多的洞察力,去了解构型空间中的点的速度。所以只有拉格朗日力学,我们不能真正描绘一个系统是如何完全进化的。

哈密顿力学是解决物理问题的第三种方法,它不是在组态空间中工作,而是在相空间中工作。

这本身是一个很大的话题,对描述动力系统非常有用,在非线性动力学和混沌中被详细使用

我正计划再写一篇关于这个话题的博文,所以我会放一些图片,激发你想了解更多的想法。

phase space of simple pendulum — CC BY-SA 4.0 Krishnavedala https://en.wikipedia.org/wiki/Phase_portrait#/media/File:Pendulum_phase_portrait.svg

如果你喜欢这篇文章,我强烈推荐你看看这本由里基·罗瑟写的关于域名着色的可观察笔记本

可微物理学

一个新兴的研究领域是可微物理学。伟大论文的一个例子是这里的。

任何种类的物理预测都涉及到编写和求解许多微分方程,所以这个想法是你用一种可微分的语言编写一个物理引擎,比如 Pytorch 或 Flux.jl,然后在线性时间内计算导数。

这种方法的主要好处是,你只需要描述你的系统需要如何发展(前向传递),并且你可以免费得到衍生产品(后向传递)。

就个人而言,我发现这是当今机器学习中最令人兴奋的研究领域。

我将在以后的博客中更多地谈论自动微分,所以这个想法很快就会变得清晰。

深入研究数学和物理

许多在物理学中有重大应用的数学技术正在走向机器学习和机器人技术。因此,我推荐一些参考资料来开始学习这种超越线性代数和基本微积分的新数学。我推荐这个列表中的很多书→ 我喜爱的技术书籍。

特别是,在未来的博客文章中,我想更多地谈论配置空间的拓扑结构,并将向您展示如何应用这些想法来简单地描述三维机器人的运动。

如何理解一家使用人工智能的公司

原文:https://towardsdatascience.com/how-to-understand-a-company-using-artificial-intelligence-e111888d8a30?source=collection_archive---------26-----------------------

这篇文章是关于使用人工智能为高管团队产生洞察力的。

合规性不是一个性感的话题,所以这里有一个噩梦般的场景:你是一家财富 500 强公司的首席财务官,许多内部报告定期送到你的办公桌上。假设你的年度内部审计在一月份进行,一份重要的报告在二月份放在你的办公桌上。如果你的办公室在下一次年度审计之前没有处理好报告中的关键信息,那么你的工作可能会有危险。这里的困难在于,声誉风险、数据泄露、隐私侵犯甚至规划错误等非财务风险都可能导致未来的损失。这些风险很难被发现,因为它们是以文本而不是数字的形式到达你的办公桌的。通常情况下,长篇报告太多,关键的见解被忽略了。除非危机降临,否则它们不会出现在账本上,不管是罚款、诉讼还是失去客户账户。

在董事会上,很难解释为什么你把报告放在办公桌上(或收件箱里),却从未提出这个问题。在小公司里,这只是一个问题。没有足够的报告来激励一个基于人工智能的解决方案。只有当你面对潮水般的报告时,高管们才突然无法有效地处理大量和各种各样的风险。这些报告通常在文档管理系统(DMS)中整理了几十年,但没有到达一些分析工具来生成见解,也没有得到人类的评估。

此外,详细阅读每一份报告仍然会错过大局。您无法定期查看业务部门的非财务绩效,这导致最佳情况下只能看到人为生成的年度快照,或者根本看不到任何图片,而不是在注重细节的层面上对公司情况的实时视图,无论您在飞行中编造了什么关键字。

一年多来,我们的团队一直在开发和完善一个名为 AuditMap.ai 的审计人工智能,我在过去的文章中描述了这个工具的动机(这里和这里)。当我写这篇文章时,当你搜索内部审计人工智能时,我们关于 AuditMap.ai 的文章仍然在谷歌上排名第一。

我今天想做的这篇文章是向你展示结果,而不是关注人工智能是如何工作的。

主要想法是让人工智能在所有内部审计报告的大集合中找到关键语句,并在仪表板、列表中向高管展示底层信息,并作为行动项目。这种可配置的解决方案评估个人陈述、并将信息提炼为可操作的见解

Example of the tool in action, showing risk and controls per year using the PEFA framework and an off-the-shelf audit universe.

请记住,内部审计的工作是发现不好的东西,并提供可行的见解。让我们一起来看看人工智能引擎在处理了一些大规模公开可用的文档数据集后,在各个业务领域识别出的一些关键风险陈述。

以下陈述摘自内部报告数据集,并被标记为业务运营各个领域的风险:

管理:

  • 当前的指南不要求信息系统部项目管理系统制定正式的项目风险评估。
  • 没有基于风险的计划的组织不知道这是预期的。
  • 限制。无法具体确定专门用于治理职能的资源。
  • 鉴于分支机构没有一致考虑风险来源,也没有进行可靠的控制评估,报告的完整性可能仅限于形式上的工作。

财务:

  • 我们在监测中观察到的弱点使[实体]面临这样的风险,即它提供资金的项目可能不符合商定的条件,而且[实体]不会及早意识到不符合情况,从而减轻潜在的环境或社会影响。
  • 因此,存在一种风险,即行使病人差旅支出启动权限的员工可能没有被正式授予这些权限。
  • 分析工作仅限于这些国家是现有证据中的一个严重缺陷。
  • 此外,我们注意到支持各种风险评估的文件水平不一致。

隐私:

  • 对于保密和匿名之间的区别似乎没有明确的理解。
  • 调查结果。由于缺乏关于隐私的国家指令,导致了不同地区指令的发展,这些指令并不一定满足所有关于保护个人信息的要求。
  • 受访的分支机构联系人指出,他们没有适当的政策或流程来识别分支机构内需要进行隐私影响评估的所有活动。
  • 同样,该策略本身不符合财政委员会隐私政策中规定的实践管理要求。

数据:

  • 不完善的分离流程会导致对信息的不当访问,从而损害信息的机密性和完整性。
  • 然而,需要进行改进,以确保所有要求的文件都保存在中央储存库中,并在合同审批过程中有审计跟踪,以展示最佳价值、竞争性、公平性和透明度。
  • 然而,当评估小组要求提供进一步的细节以围绕绩效展开讨论时,所提供的数据(在[小组]总部进行广泛的收集和分析之后)与最初观察到的数据不同。
  • 此外,没有定期测试系统数据备份的准确性和完整性,使该部面临没有其系统数据最后一份已知完好副本的完整记录的风险。

正如我们从上述报表中看到的,有许多非财务报告报表是危险信号,表明潜在的未来监管或财务损失需要立即采取纠正和预防措施。显然,AI 可以读取和标记关键陈述,并且它可以在风险管理框架和程序分离的上下文中(例如, PEFA 和 COSO )以及在公司的上下文中(例如,特定的审计领域)这样做。然而,我们如何为管理层提取关键的洞察力呢?我们如何从已确定的问题中退一步,总结全局?

让我和你们分享 3 种方法:仪表板、上下文窗口和风险控制矩阵。这些视图获得了客户端拉取和特性请求。

1)仪表板

AuditMap 充满了仪表板,用于从数据中提取高级别见解。我将在这里展示 4 个仪表板,让您了解如何获得洞察力,并了解贵公司的整体情况。

要查看的第一个视图是 ETL 作业摘要。简单地说,这个视图告诉你数据库中有多少东西,以及有多少东西被 AI 标记为相关的。在我们最新的版本中,我们跟踪风险、控制、发现、建议和观察。

This dashboard component shows how many sentences, entities (e.g., “Kitchen Sink”), risk statements, and control statements are in the database for a given project.

另一个要考虑的仪表板是审计宇宙树。请将此视为组织内审计员可以审计的所有空间的列表。每个公司的做法都有所不同,因为这个树适合公司结构和他们直接业务伙伴的某些部分。

audit universe 树让您了解公司每个部分的报告中有多少数据,以及 AI 在这些内部报告中标记了多少信息。

A dashboard for exploring coverage gaps, areas where data is missing, and trends in mentions of various entities.

接下来,我们有一个高级仪表板(见上图),用于识别主题中的覆盖差距和趋势。左上方的块让高管们发现在他们的审计宇宙树中哪里有覆盖缺口以及有多长时间了。从 2016 年开始,回溯到过去,AuditMap 发现了一个点,在这个点上,没有一个文件被绑定到审核宇宙树的这个分支。

在真实的应用程序中,这可能意味着两种情况之一。要么:

(1)每个人都知道在这个业务分支上执行的工作是以 4 年周期完成的,

(2)这里的工作被搁置了,最终在 2016 年被砍掉。这种潜在的 3 年信息封锁在项目规划阶段使用 AuditMap 进行标记。

在同样出现的令人恐惧的空白中,上图的右上部分详细描述了审计领域中没有相关文档工作的领域。右上角标记了 3 个区域,其中未找到报告。除了最近添加到审计领域的内容之外,不言而喻,当这个框列出业务线时,需要提出问题。当发现报告但没有发现风险或控制时,可以部署相同类型的小部件来显示。这种情况下,该职能部门每年都会收到报告,但这些报告只是钉在白纸上的笑脸,因此不会暴露风险或控制措施以供管理层审查。

这个特定仪表板的底部组件标记为“实体趋势”,它跟踪热门提及在一段时间内的移动。这个小部件告诉您随着时间的推移,哪些内容在报告中被提到得最多,这有助于在规划过程中产生一些高层次的想法,从而在面向细节的下钻中深入了解特定的风险。

向下钻取发生在浏览页面中,这些页面的仪表板向您显示特定上下文(如控制活动)中特定计划(如分销和物流>计划)的非常狭窄的视图。

This dashboard is used to understand the high-level situation over time for the detail-oriented drill-down into specific Enterprise Risk Management (ERM) aspects within a specific business unit.

在上面的仪表板中,您可以看到一个高度定制的企业职能部门内的风险和控制视图。该工具可以为企业的任何部分、任何 ERM 方面做到这一点,还可以使用小部件中的“搜索风险”和“搜索控制”框任意过滤。因此,你可以一次深入到多个维度,形成一个关于组织中正在发生什么的论文。

2)上下文窗口

对于从文档中提取的每一条语句,AuditMap 使您(用户)能够:

  1. 在两个层次上感受标记数据的上下文:段落(通过下图中围绕着粗体句子的上下文文本)和文件级(使用工具的内置文档摘要器)。
  2. 最重要的是,团队 AuditMap 整合了我们的引擎透明理念,让人们看到甚至纠正人工智能的预测,以纠正错误或简单地推翻人工智能的意见。
  3. 有趣的是,找到任何感兴趣的东西并不意味着乐趣就此停止。这些标记的语句可以保存到可导出的列表中,然后生成风险控制矩阵

3)风险控制矩阵

谈到风险控制矩阵(RCM)设计,审计经理比最高管理层更熟悉。

RCM 是在审计程序中确认适当覆盖范围的一个关键工具,因此探索可以直接进入审计计划。从另一个角度来看,通过快速建立陈述之间的关系,您可以使用它来建立一个关于公司某个职能或风险领域正在发生什么的案例。

风险控制矩阵本质上是给定审计范围内所有控制措施的列表,以及这些控制措施在公司运营中降低风险的直观关系。这是另一个视图,你可以用它来建立一个关于公司的某个职能或风险领域正在发生什么的案例。风险和控制语句可以从 explore 选项卡的视图中提取,并以如下所示的漂亮的矩阵格式设置。

An example risk-control matrix in AuditMap.ai

该矩阵非常紧凑,因为典型的 RCM 实际上可以变得非常大。这些通常在 excel 中编译,我们确实想到了这一点,并构建了一个 excel 导出工具。

带回家的信息:用人工智能理解企业

人工智能可以用来以真正自动化和复杂的方式理解公司的内部报告。可以在较高的级别查看数据,并对数据进行切片和切块,以获得不同时间和特定上下文中的数据视图。用人工智能处理数据让你知道数据中的差距在哪里,问题(风险)或努力(控制)在哪里呈上升趋势。

想要试玩吗?这里有一些关于如何联系我们团队讨论试点项目的信息。

发现你的审计图:
马修·勒梅matt @ audit map . ai
T:+1–819–923–6288

我们也很高兴地宣布 AuditMap.ai 正式从 Lemay.ai 中分离出来成为自己的公司,我们计划在 2019 年筹集资金以提高我们的销售额。这是一个非常激动人心的时刻!

如果你喜欢这篇文章,那么看看我过去最常读的一些文章,比如“如何给人工智能项目定价”和“如何聘请人工智能顾问”

下次见!

——丹尼尔
LEMAY . AI
1(855)LEMAY-AI
丹尼尔@lemay.ai

如何理解 Numpy 文档

原文:https://towardsdatascience.com/how-to-understand-numpy-documentation-897d5307609b?source=collection_archive---------19-----------------------

当我们开始学习数据科学、机器学习、深度学习或任何将使用 Python 作为编程语言的激动人心的领域时,很可能我们所有人都会使用 numpy 。在这篇文章中,我将根据我使用 numpy 的经验,编写 numpy 基础知识以及如何正确阅读文档。在阅读我的帖子之前,如果你知道编程语言和 python 的基础知识是很好的。我将使用 python 3.6 作为例子。

什么是 Numpy

你可能想知道为什么所有的机器学习教程都将使用 numpy ,为什么其他库不用?在我们进入 numpy 之前,请先让我说一下什么是 Python。

Python 是一种编程语言,我们可以神奇地导入用 C++编写的库。C++是一种非常快速的语言,代码将被直接编译成机器代码,因此 C++中的库可以比纯 python 编写的库执行得更快。

Numpy 很快!它是由互联网上许多伟大的程序员维护的。

Numpy 是一个用 C++编写的开源库,它是用 Python 实现科学计算的基础包。安装非常简单,如下所示:

pip install numpy

它包含许多工具和算法,用于大多数机器学习任务,例如

  1. 强大的 N 维数组对象
  2. 复杂的(广播)功能
  3. 有用的线性代数、傅立叶变换和随机数功能

numpy 中的常用技术术语

形状

np.random.rand(d0,d1,…,dn)-给定形状中的随机值。
np.full(shape,fill_value,dtype=None,order='C') —返回给定形状和类型的新数组,用 fill_value 填充。

每当描述中提到“形状”,它就意味着数组的大小,或者维度的大小。如果 numpy 数组的“shape”是[4,3,2],这意味着它是一个 3d 数组,因为形状本身有 3 个值 4,3 和 2。让我们看看下面的图片。

An array with shape of [4, 3, 2]. 4 2d array with [3,2]. For each 2d array, it has 3 rows and 2 columns.

对于形状为 4d 的数组,可以认为该数组包含了多个 3d 数组。然后你就可以想象使用 3d 数组的数据如上图。

数量

当你在描述中看到“标量”时,它只是一个单一的值。比如 x = 1,y = 3.0。所有这些都被认为是“标量”。

数据类型

dtype 是数据类型,其中常见的数据类型有图像的 uint8 (无符号 8 位整数,0–255),标量的 int32 (有符号 32 位整数,-对 1),标量的 float32 (有符号 32 位浮点)。大多数操作将使用 float32,因为机器学习数据中有很多小数。

可以读作{有符号/无符号} _ { int/float } _ {位数,8,16,32,…}

数组 _like

array_like 通常表示 numpy 数组或 list ,可以解释为 array。在库中,它将有助于转换为 numpy 数组。

恩达雷

输入必须是 numpy 数组,不能是列表,

强大的 N 维数组对象

在机器学习中,我们将永远与【数据】打交道。通俗地说,数据就是一个 excel 文件,存储着关于某个事物的信息。(例如公司的销售记录)

Illustration of a simple sales record

上面的例子是一个非常简单的销售记录,它有日期项目名称和价格

当我们想要将这个文件加载到 python 中时,我们很可能会使用 numpypandas (另一个基于 numpy 的库)来加载文件。加载后会变成数组形状为(3,3)的 numpy 数组,意思是 3 行数据,3 列信息。

为了更好地理解什么是 numpy 数组,或 N-d 数组,我们可以想象 1-d 数组是一个向量或一个项目列表,2-d 数组是一个矩阵,3-d 数组可以是矩阵列表。你可以参考上面的图片进行说明。

Numpy 会自动将数据转换成 N-d 数组,这样我们就可以执行更多像加法一样简单和像矩阵乘法一样复杂的运算。

复杂的(广播)功能

这可能解释起来有点复杂,当你在 numpy 中变得有经验时,你会理解什么是正确的广播

广播更像是自动数组分配。在 Java 中,我们有 ArrayList,它会自动扩展数组的大小。广播更像是神奇地执行数组扩展来执行一些算术运算,比如加法。

Example on what is broadcasting

在上面的例子中,我们有一个形状为(2,3)的二维数组 x 和形状为(3)的一维数组 y 。x 是一个有 2 行的数组,每行有 3 列。第一行是[0,1,2],第二行是[3,4,5]。

执行一个简单的加法运算,就是通过语法将 x 和 y 相加: z = x + y ,将结果存储到 z. 然而,你可能会想,它们两个具有不同的数组大小,为什么它可以像 x + y 一样简单地实现。这就是“广播”的工作方式。可以理解为对于 x 的每一行,返回 x[i] + y. 那么输出 z 会自动生成,形状为 x (2,3) ,存储 x + y 的结果。

如何阅读 numpy 文档

好了,终于说到正题了!每当你在 numpy 函数的使用上遇到问题,你不知道如何使用它,你可以用“np.dot”这样的关键字进行谷歌搜索。

how to search numpy function

通常第一个会是你想要的,进入页面会像下面这样

numpy.dot documentation page

当我第一次阅读文档时,我发现它很难,因为我不知道从哪里看,文本似乎复杂而混乱。但是熟悉 numpy 之后,我只搜索我想知道的东西,也就是输入输出。

numpy.dot documentation page highlight

首先,这是你想要的功能吗?例如,您想要对两个二维数组(也称为矩阵)执行点积,其中 C = AB。现在你看文档的第一行,它描述的是你想要的吗?嗯,“两个数组的点积”似乎是正确的。

numpy.dot documentation page more description

对于初学者来说,这似乎是一篇很长的文章。有时我会跳过这一部分,因为我觉得它对我没有帮助😂。在你熟悉 numpy 之后,我建议你阅读一下描述,也许会帮助你进一步理解它是如何工作的。但是,我会一直关注参数样本输入和输出。

numpy.dot documentation parameter

每当我们看到 array_like ,就意味着函数输入是一个 numpy 数组,从点积的意思来看,你应该知道输入是一维或者二维数组(虽然也可以接受 N-d (N > 2)。几乎大多数 numpy 操作都有 out 作为参数,这是为了内存引用,可能是为了内存高效的程序,但是,我建议我们总是这样调用函数: out = np.dot(a,b) 而不是 np.dot(a,b,out) 。它与一些编程语言概念有关,我总是使用第一种方式,即 out = np.dot(a,b)

大多数 numpy 操作都返回一个 numpy 数组。只有一些操作会返回其他内容,比如元组或索引。

numpy.dot documentation output

我总是看例子来找出如何使用这个函数,但是有时你可能会弄不清看哪个。

在这种情况下,您应该尝试运行该示例,或者将任何值放入该示例中,以测试该函数是否能输出您期望的结果。

TLDR;

  1. 阅读描述的前几行,它与你想要的匹配。
  2. 您可能会在文档页面中找到很多信息,只搜索参数。
  3. 看例子。
  4. 不断地试错。

让我知道你在阅读 numpy 文档时遇到了什么问题,这样我就可以继续撰写阅读 numpy 文档的好教程(或者任何常见的库文档,例如 pytorch)。

如何使用聚类技术生成合成数据

原文:https://towardsdatascience.com/how-to-use-a-clustering-technique-for-synthetic-data-generation-7c84b6b678ea?source=collection_archive---------13-----------------------

我们展示了如何使用高斯混合模型(GMM),一个强大的聚类算法,合成数据生成。

聚类和 k-均值

对于利用数据科学的商业或科学企业来说,聚类是机器学习管道的重要组成部分。顾名思义,它有助于识别数据块中密切相关(通过某种距离度量)的数据点的集合,否则很难理解。

k-means 算法在未标记的多维数据集中搜索预定数量的聚类。它使用最佳聚类的简单概念来实现这一点:

  • “聚类中心”是属于该聚类的所有点的算术平均值。
  • 每个点离自己的聚类中心比离其他聚类中心更近。

它通过从随机分配聚类中心开始,然后分阶段迭代来完成聚类,其中,在每个阶段,它为每个聚类中心分配特定的点,然后根据这些点的算术平均值来重新计算聚类中心的位置。这里有一个很好的视频演示了这个过程。

k 均值和高斯混合模型(GMM)的局限性

k-means 算法的一个关键优势是其简单性,这使得它成为快速处理大规模数据的流行选择。但是这种简单性也导致了一些关键的实际挑战。

特别是,k-means 的非概率特性及其采用简单的径向距离度量来分配集群成员资格,导致许多现实情况下性能不佳。

例如,想象以下数据点。在这里,它们由它们的标签来着色,但是在无监督的机器学习设置中,我们不会有类别标签。

如果我们运行一个简单的 k-means,我们很可能会得到下面的最终聚类排列,

两个中间的聚类看起来有重叠,即我们可能对重叠区域中点的聚类分配没有完全的信心。不幸的是, k-means 模型没有对聚类分配的概率或不确定性的内在度量。

k-means 从设计上来说是非概率的。

此外,对于 k-means,当数据分布的形状是圆形时,它工作得最好。这是因为 k-means 没有考虑长方形或椭圆形簇的内置方法。因此,举例来说,如果我们获取相同的数据,并通过向一个方向拉伸来转换它,则聚类分配会变得次优。

k-means 不够灵活,无法解释这种“拉长的数据,并试图将数据强行拟合到四个圆形聚类中,这些聚类并不代表数据点的真实形状。

k-means 在“非圆形”数据(即长方形或椭圆形聚类)上表现不佳

G 澳大利亚 M ixture M 模型(GMMs),可以看作是 k-means 背后思想的延伸。GMM 试图将给定数据建模为多个多维高斯概率分布的混合物。

它基于 期望最大化(E-M)算法 工作,并从本质上处理生成数据的概率性质。

在最简单的情况下,GMM 可以像 k-means 一样用于寻找聚类。然而,它对于非圆形数据斑点执行得完美无缺,因为它可以用参数(std。dev 和 mean)适合于拟合数据的特定形状。

在本文中可以找到对这些模型的全面总结,

[## 高斯混合模型解释

在机器学习领域,我们可以区分两个主要领域:监督学习和非监督学习。主要的…

towardsdatascience.com](/gaussian-mixture-models-explained-6986aaf5a95)

作为生成模型的 GMM

GMM 最流行的分类是聚类算法。然而,从根本上说,它是一种用于 密度估计 的算法,属于 生成模型 家族。

这意味着,当 GMM 适合某些数据时,生成的模型不仅仅是一组固定聚类的描述,而是描述数据真实分布的生成概率模型。

GMM 是一种生成式建模技术,可以生成接近拟合数据分布的合成数据。

这里有一个关于生成模型的很好的介绍,

[## 生成模型与判别模型

我想以一个故事开始这篇文章。

medium.com](https://medium.com/@mlengineer/generative-and-discriminative-models-af5637a66a3)

使用 GMM 的合成数据生成

假设我们有一些数据点的月牙形聚类排列。这是一个流行的玩具例子,经常用来展示 k 均值的局限性。一种称为谱聚类的特殊聚类方法最适合这种类型的数据。

有多少个自然集群?

显然是两个。如果我们选择两个集群运行 GMM,我们将得到类似这样的结果。

印象不深,是吗?对于这种特殊形式的数据,它显示了与 k-means 相同的限制。

但是假设我们对聚类不感兴趣,但是基于给定的数据样本生成更多的合成数据。

为此,我们需要大量的高斯星团。看看当我们选择 4、8 和 16 个集群运行相同的 GMM 算法时会发生什么。

这些聚类似乎紧密地跟随数据的形状。GMM 的伟大之处在于我们有一种sample方法。这意味着它已经学会了数据的分布,而不仅仅是对数据进行聚类,并且可以从分布中生成任意数量的样本。

GMM 的标准算法实现有一个生成数据的sampling方法。k-means 没有这样的方法。

看看当我在这些模型(4、8 和 16 集群模型)上调用predict方法时会发生什么。

它能够生成新的数据,紧密跟随它所聚类的原始数据的形状!

很明显,4 簇模型不太擅长模拟原始数据,但是 16 簇模型非常接近原始数据,不是吗?

当然,这种能力并不局限于任何特定的形状或二维空间,而是通常扩展到多变量情况。下面是一个 4 簇数据集的例子。

警告和含义

就像任何生成技术一样,这容易受到过度拟合和泛化能力差的影响。您可以无限制地增加高斯分量的数量,但这将开始适应噪声,而不是代表真实的分布。

一般来说,必须对高斯分量、初始化、容差和迭代次数的选择进行仔细的实验。

增加高斯分量的数量,直到开始获得足够接近的原始数据集表示,但不再增加。遵守奥卡姆剃刀的原则,并尝试在足以满足您的应用的最小复杂度处停止。

这种技术的一个潜在应用是直接用于商业分析和市场细分案例。通常,市场调查产生的数据点数量有限。如果您的内部聚类算法或其他数据处理技术需要更多的数据点,该怎么办?这是一种接近模拟真实数据集分布并为进一步处理生成相似聚类的潜在方法。

业务分析可以使用这种合成数据生成技术从有限的真实数据样本中创建人工聚类。

关于这个的练习 Jupyter 笔记本可以在这里找到。

如果您有任何问题或想法要分享,请通过tirthajyoti【AT】Gmail . com联系作者。此外,您可以查看作者的 GitHub 资源库,了解 Python、R 和机器学习资源中其他有趣的代码片段。如果你像我一样对机器学习/数据科学充满热情,请随时在 LinkedIn 上添加我或在 Twitter 上关注我。

[## Tirthajyoti Sarkar - Sr .首席工程师-半导体、人工智能、机器学习- ON…

通过写作使数据科学/ML 概念易于理解:https://medium.com/@tirthajyoti 开源和有趣…

www.linkedin.com](https://www.linkedin.com/in/tirthajyoti-sarkar-2127aa7/)

如何将气流式 Dag 用于高效的数据科学工作流

原文:https://towardsdatascience.com/how-to-use-airflow-style-dags-for-highly-effective-data-science-workflows-b52053dedd32?source=collection_archive---------10-----------------------

Airflow 和 Luigi 对于数据工程来说很棒,但是对于数据科学来说并没有优化。 d6tflow 为数据科学带来了气流式的 Dag。

数据科学工作流是 Dag

数据科学工作流通常如下所示。

此工作流类似于数据工程工作流。它包括将参数化的任务链接在一起,这些任务在彼此之间传递多个输入和输出。参见为什么你的机器学习代码可能不好的 4 个原因为什么在函数之间传递数据或硬编码文件/数据库名称而没有明确定义任务依赖关系不是编写数据科学代码的好方法。

# bad data science code
def process_data(data, do_preprocess):data = do_stuff(data, do_preprocess)data.to_pickle('data.pkl')data = pd.read_csv('data.csv')
process_data(data, True)
df_train = pd.read_pickle(df_train)
model = sklearn.svm.SVC()
model.fit(df_train.iloc[:,:-1], df_train['y'])

R&D 与生产数据工作流

使用气流和 luigi 比编写用于管理数据工作流的功能代码前进了一大步。虽然数据工程和数据科学工作流相似,但它们的注意事项是相同的。这两个库都是为数据工程师在生产环境中使用而设计的,其重点是:

  • 确保一切按时顺利进行
  • 时间安排和协调
  • 从故障中恢复
  • 数据质量

相比之下,研发工作流程的重点是:

  • 产生洞察力
  • 原型速度
  • 评估不同模型和参数的预测能力
  • 可视化输出

因此,研发工作流程:

  • 不太明确
  • 涉及反复试验
  • 当模型、参数和数据发生变化时,需要频繁重置任务和输出
  • 接受数据工程师的输出

R&D 环境中的气流/luigi 问题

由于这两个库都针对数据工程生产环境进行了优化,因此数据科学研发环境的 UX 并不是很大:

  • 用于读/写数据的湿代码
  • 手动跟踪保存数据的文件名或数据库表名
  • 当模型、参数和数据改变时,不方便重新设置任务
  • 不方便跟踪不同参数设置的模型结果

在复杂的数据工作流中手动跟踪文件名…不可扩展。

# example of manually caching dataframes and keep track of files
cfg_fpath_cc_base = cfg_fpath_base + 'vendor/'
cfg_fpath_cc_raw = cfg_fpath_cc_base + 'df_cc_raw.pkl'
cfg_fpath_cc_raw_recent2 = cfg_fpath_cc_base + 'df_cc_raw_recent2.pkl'
cfg_fpath_cc_yoy = cfg_fpath_cc_base + 'df_cc_yoy.pkl'
cfg_fpath_cc_yoy_bbg = cfg_fpath_cc_base + 'df_cc_yoy_bbg.pkl'
cfg_fpath_cc_yoy_fds = cfg_fpath_cc_base + 'df_cc_yoy_fds.pkl'
cfg_fpath_cc_var_fds = cfg_fpath_cc_base + 'df_cc_var_fds.pkl'
cfg_fpath_cc_yoy_recent2 = cfg_fpath_cc_base + 'df_cc_yoy_recent2.pkl'
cfg_fpath_cc_actual = cfg_fpath_cc_base + 'df_cc_sales_actual.pkl'
cfg_fpath_cc_monthly = cfg_fpath_cc_base + 'df_cc_monthly.pkl'
cfg_fpath_cc_yoy_cs2 = 'data/processed/df_cc_yoy_cs2.pq' # consistent shopper data for new methodology from 2018

d6tflow 与 airflow/luigi 有何不同

d6tflow 针对数据科学研究和开发工作流进行了优化。以下是在数据科学中使用 d6tflow 的好处。

好处:任务有输入和输出数据

不再需要手动加载和保存数据,而是外包给图书馆。这可以更好地伸缩,并减少维护,因为输入/输出数据的位置可以改变,而不必重写代码。这也使得数据工程师更容易将数据交给数据科学家。

class TaskProcess(d6tflow.tasks.TaskPqPandas): # define output format def requires(self):return TaskGetData() # define dependency def run(self):data = self.input().load() # load input datadata = do_stuff(data) # process dataself.save(data) # save output data

好处:轻松使任务无效

实现了常见的失效场景。当您在试错过程中更改代码和数据时,这将提高原型开发速度。

# force execution including downstream tasks
d6tflow.run(TaskTrain(), force=TaskGetData())# reset single task
TaskGetData().invalidate()# reset all downstream tasks
d6tflow.invalidate_downstream(TaskGetData(), TaskTrain())# reset all upstream tasks
d6tflow.invalidate_upstream(TaskTrain())

优点:使用不同的参数轻松训练模型

更改参数后,您可以智能地重新运行工作流。参数从目标任务传递到相关的下游任务。因此,您不再需要手动跟踪要更新的任务,从而提高了原型开发速度并减少了错误。

d6tflow.preview(TaskTrain(do_preprocess=False))'''
└─--[TaskTrain-{'do_preprocess': 'False'} (PENDING)]└─--[TaskPreprocess-{'do_preprocess': 'False'} (PENDING)]└─--[TaskGetData-{} (COMPLETE)] => this doesn't change and doesn't need to rerun
'''

好处:轻松比较模型

用不同参数训练的不同模型可以容易地加载和比较。

df_train1 = TaskPreprocess().output().load()
model1 = TaskTrain().output().load()
print(sklearn.metrics.accuracy_score(df_train1['y'],model1.predict(df_train1.iloc[:,:-1])))df_train2 = TaskPreprocess(do_preprocess=False).output().load()
model2 = TaskTrain(do_preprocess=False).output().load()
print(sklearn.metrics.accuracy_score(df_train2['y'],model2.predict(df_train2.iloc[:,:-1])))

加速数据工程师向数据科学家的移交

要快速共享工作流输出文件,可以使用 d6tpipe 。参见共享工作流和输出。

import d6tflow.piped6tflow.pipe.init(api, 'pipe-name') # save flow output 
pipe = d6tflow.pipes.get_pipe()
pipe.pull()class Task2(d6tflow.tasks.TaskPqPandas): def requires(self):return Task1() # define dependency def run(self):data = self.input().load() # load data from data engineer

或者,您可以使用 d6tflow premium 将输出保存在数据库中。

d6tflow2.db.init('postgresql+psycopg2://usr:pwd@localhost/db', 'schema_name')class Task1(d6tflow2.tasks.TaskSQLPandas): def run(self):df = pd.DataFrame()self.save(df)

最后,数据科学家可以继承数据工程师编写的任务来快速加载源数据。

import tasks_factors # import tasks written by data engineer
import utilsclass Task1(tasks_factors.Task1):external = True # rely on data engineer to run def run(self):data = self.input().load() # load data from data engineer

d6tflow 快速入门

这是一个完整的例子,展示了如何使用 d6tflow 进行 ML 工作流https://github.com/d6t/d6tflow#example-output

可扩展 ML 项目的模板

在https://github.com/d6t/d6tflow-template有一个用于真实项目的 d6t 流代码模板

  • 多任务输入和输出
  • 参数继承
  • 模块化任务,运行和

如何使用气流而不头疼

原文:https://towardsdatascience.com/how-to-use-airflow-without-headaches-4e6e37e6c2bc?source=collection_archive---------3-----------------------

Photo by Sebastian Herrmann on Unsplash

按计划处理和移动数据的数据管道和/或批处理作业为所有美国数据人员所熟知。事实上的标准工具来编排所有的是阿帕奇气流。它是一个以编程方式创作、调度和监控工作流的平台。工作流是表示为直接非循环图(DAG)的一系列任务。例如,将提取、转换、加载(ETL)作业视为一个工作流/DAG,其中 E、T 和 L 步骤是其任务。您可以使用 Python 在代码中配置工作流。这允许您在 Git 这样的源代码控制系统中对工作流进行版本控制,这非常方便。

总而言之,气流是一个很棒的工具,我喜欢它。但是,我最初用错了方法,可能其他人也是这样。这种误用会导致令人头疼的问题,尤其是在工作流部署方面。为什么?简而言之,我们将它用于在同一个气流实例上协调工作流和运行任务的 。在这篇文章中,我将告诉你为什么这是一个问题。当然,我还将向您展示如何轻松地解决这个问题。我希望这能减少你未来的阿司匹林摄入量,就像我一样:)

气流流向不好的方向

我以一个关于我自己和气流的小故事开始这篇文章。

创建工作流时,您需要实现和组合各种任务。在 Airflow 中,您使用运算符来实现任务。Airflow 提供了一组开箱即用的操作符,比如 BashOperator 和 PythonOperator 等等。显然,我在工作中大量使用了 PythonOperator,因为我是一名数据科学家和 Python 爱好者。这开始很好,但是过了一会儿,我想

“嗯,我如何将我的工作流部署到我们的生产实例中?我的包和其他依赖项是如何安装在那里的?”

一种方法是为每个工作流添加一个 requirements.txt 文件,该文件在部署时安装在所有 Airflow workers 上。我们试过了,但是我的任务和同事的任务需要不同的熊猫版本。由于这个包依赖问题,工作流不能在同一个 Python 实例上运行。不仅如此,我使用了需要 Python 3.7 的 Dataclasses 包,但是在生产实例上,我们只安装了 Python 3.6。这可不好。

所以我继续谷歌了一下,找到了另一个由 Airflow 提出的解决方案,名为 Packaged-DAGs。上面写着:“将所有 Dag 和外部依赖项打包成一个 zip 文件,然后部署它。”您可以点击此链接了解更多详情。对我来说,这听起来不是一个很好的解决方案。它也没有解决 Python 版本问题

作为操作符提供的另一种可能性是将您的任务包装在一个 PythonVirtualEnvOperator 中。我不得不说,我没有试过,因为它仍然没有解决 Python 版本的问题。但是,我想如果你每次执行一个任务都要创建一个虚拟环境的话,可能会很慢。除此之外,文档中还提到了其他一些注意事项。

Damm,三次尝试仍然没有令人满意的解决方案来部署用 Python 编写的任务。

最后,我问自己如何使用 Python 之外的语言编写任务?那一步会不会变成语言不可知?甚至有人能执行一个不知道具体气流的任务吗?我如何在气流中部署和集成这样的任务?我是否必须编译它,并在每个 worker 上安装带有所有依赖项的结果,以便最终通过 BashOperator 调用它?这听起来像是一次痛苦的部署和开发经历。此外,这可能再次导致依赖性冲突。总之,这听起来不太令人满意。

但是我要用气流!

那么,我们能修好它吗?

Taken from https://knowyourmeme.com/photos/292809-obama-hope-posters

良好的气流方式

每当我听到“依赖冲突”、“版本问题”或“我想成为语言不可知者”之类的话,我马上会想到容器和 Docker 。幸运的是,Airflow 提供了一个开箱即用的docker operator(还有一个用于 Kubernetes )。这允许我们从气流中调用隔离的 docker 容器作为任务。

好快啊:)

但是现在,更详细一点。在下文中,我将向您展示从开发基于 Docker 的任务和 Dag 到部署它们的端到端过程。对于每一步,我都突出了各自解决的问题。

任务开发和部署

  1. 用你想要的任何语言和语言版本来开发和测试你的任务。这允许你在与气流细节和其他任务隔离的情况下测试和开发任务。它降低了新开发人员的门槛,因为他们可以选择自己最熟悉的语言。
  2. 将工件和所有依赖项打包到 Docker 映像中。这解决了依赖和版本冲突的问题。它大大有助于减轻你的头痛。
  3. 使用 DockerOperator 从容器中公开一个入口点来调用和参数化任务。这使你能够从气流中使用你的图像。
  4. 构建您的图像,标记它,并将其推送到一个中心 Docker 注册表。理想情况下,这是自动化的,并且是您的 CI/CD 渠道的一部分。气流将图像从注册表中拉到执行任务的机器上。这有助于部署任务。又是一个减少头痛的步骤。此外,它允许您拥有同一任务的多个版本。最后,拥有一个中央注册中心使您能够在整个组织中共享和重用任务。

DAG 开发和部署

  1. 使用 DockerOperator 作为唯一的操作符来构建 DAG。使用它来调用 Docker 注册表中的各种任务。对我来说,这使我的 DAG 定义变得小巧、清晰、易读。除了 DockerOperator 之外,我也不必学习任何特定的气流操作符。
  2. 将您的 DAG 放入版本控制系统。这样,部署您的 DAG 只是一个简单的推拉动作。同样,这应该是自动化的,并成为您的 CI/CD 渠道的一部分。

我希望这听起来合理,你会得到它提供的许多好处。你所要做的就是学习 Docker 如果你还不知道并且你已经准备好了。

现在,我们知道该做什么了。下一段,我们通过一个例子来看看是怎么做的是怎么做的。

例子

让我们快速浏览一个示例 DAG,其中我只使用了 DockerOperator。使用这个 DAG,我模拟了一个 ETL 作业。请注意,DAG 定义文件并没有显示它只是一个模拟的 ETL 作业。它可能是一个超级复杂的或者只是一个虚拟的。实际的复杂性从 DAG 定义中去除,并转移到各自的任务实现中。生成的 DAG 定义文件简洁易读。你可以在我的 Github 库中找到所有代码。您不仅可以在这里找到 DAG 定义,还可以了解如何使用 Docker 构建和运行相应的 Airflow 实例。您还可以找到模拟的 ETL 任务实现以及 Dockerfile 文件。但是现在,让我们具体点。

代码

首先,让我们导入必要的模块,并为 DAG 定义默认参数。

**from** datetime **import** datetime, timedelta
**from** airflow **import** DAG
**from** airflow.operators.docker_operator **import** DockerOperator
d_args = {"start_date": datetime(2019, 11, 14),"owner": "shawe","depends_on_past": False,"retries": 1,"retry_delay": timedelta(minutes=5),
}

这里没有什么特别的,但是您可以看到我只导入了 DAG,这是必需的,还有 DockerOperator。在这个阶段,我们不需要气流以外的东西。

在我们构建 DAG 之前,关于 DockerOperator 和您将看到的内容,还有一些话要说。我的所有任务都使用同一个 Docker 映像,名为 etl-dummy ,标记为 latest 。该映像提供了一个名为 etl 的 CLI。该 CLI 有 3 个子 CLI,分别是提取转换加载。子 CLI 有不同的参数。例如,要运行转换任务,您需要调用

etl --out-dir /some/path transform --upper

要从 DockerOperator 中调用 Docker 图像,只需将图像名称指定为 name:tag,并指定要调用的命令。请注意,我的图像存储在本地 Docker 注册表中。这样,我的 etl dag 定义看起来像

si = "@hourly"
**with** DAG("etl", default_args=d_args, schedule_interval=si) **as** dag:**def** etl_operator(task_id: str, sub_cli_cmd: str):out_dir = "/usr/local/share"**cmd = f"'etl --out-dir {out_dir} {**sub_cli_cmd**}'"****return** DockerOperator(command=cmd,task_id=task_id,image=f"**etl-dummy:latest**",volumes=[f"/usr/local/share:{out_dir}"],)extract = etl_operator("e-step", **"extract --url http://etl.de"**)transform = etl_operator("t-step", **"transform --lower"**)load = etl_operator("l-step", **"load --db 9000://fake-db"**)**# Combine the tasks to a DAG**extract >> transform >> load

我只是添加了一个小的助手函数来创建 DockerOperators。对我来说,这看起来又好又干净。

最后的笔记和提示

如果您在一个可远程访问的 Docker 注册表中托管您的图像,您必须以registry-name/image-name:image-tag的形式传递图像名称。此外,您必须提供一个 docker_conn_id 来使气流能够访问注册表。这个 docker_conn_id 引用了一个由 Airflow 管理的秘密。

您可以添加的另一个功能是将图像名称和标签作为变量存储在 Airflow 中。如果你想更新你的 DAG,你所要做的就是用一个新的标签将另一个图像推送到你的注册表中,并改变 Airflow 中变量的值。

最后,我想重复一遍,你可以在我的 Github 资源库中找到包括 Docker 上的 Airflow 和示例 Docker 镜像在内的所有代码。

包裹

我希望这篇文章对你有用,如果你过去有过头痛,我希望它们将来会消失。感谢您关注这篇文章。一如既往,如有任何问题、意见或建议,请随时联系我。

如何在日常分析工作中使用因果推理——第 1 部分,共 2 部分

原文:https://towardsdatascience.com/how-to-use-causal-inference-in-day-to-day-analytical-work-part-1-of-2-b5efbdbf8ab0?source=collection_archive---------10-----------------------

商业世界中的分析师和数据科学家充斥着大量的观察数据。这是在业务运营过程中产生的数据。这与的实验数据形成对比,在实验数据中,受试者被随机分配到不同的治疗组,结果被记录和分析(想想随机临床试验或 AB 测试)。

实验数据可能很昂贵,或者在某些情况下,不可能/不道德地收集(例如,将人们分为吸烟组和非吸烟组)。另一方面,观察数据非常便宜,因为它们是商业运作的副产品。

鉴于大量廉价的观测数据,“询问”这些数据是日常分析工作的主要内容也就不足为奇了。最常见的询问技巧之一是在重要的指标上比较各组“主题”——客户、员工、产品等等。

使用“50 美元以上订单免运费”优惠券的购物者比没有使用优惠券的购物者多花了 14%。

商店前面的产品比商店后面的产品多被购买 12%

从多个渠道购买的客户比从单一渠道购买的客户每年多花费 30%。

西部地区的销售代表比东部地区的销售代表的人均预订量高出 9%。

Source: http://bit.ly/2VtX2FV

比较非常有用,可以让我们深入了解系统(即业务、组织、客户群)实际上是如何工作的。

而这些见解反过来又建议我们可以做些什么——干预——来改善我们关心的结果。

从多个渠道购买的客户比从单一渠道购买的客户每年多花费 30%。

30%已经很多了!如果我们能吸引单一渠道的购物者下次从不同的渠道购买(也许是给他们一张只适用于那个新渠道的优惠券),也许他们第二年会多花 30%的钱?

商店前面的产品比商店后面的产品多被购买 12%。

哇!所以如果我们把销量弱的产品从店铺后面移到前面,也许他们的销量会增加 12%?

如果计算原始比较的数据是实验性的(例如,如果一个随机的产品子集被分配到商店的前面,我们将它们的性能与后面的进行比较),这些干预可能会产生预期的效果。

但是如果我们的数据是观察性的——零售商出于商业原因选择了一些产品放在商店的前面;给定一组渠道,一些客户自己选择使用单个渠道,其他人使用多个渠道—您必须小心。

为什么?

因为从观测数据计算出来的比较可能不真实。它们可能并不能反映你的业务是如何运作的,按照它们行事可能会给你带来麻烦。**

在因果推理领域中研究了如何从观察数据中回答‘干预性’问题的一般问题。有一些有用的文章(示例、示例)、书籍(因果推理、为什么的书)和课程(示例)教授关键概念,如因果关系与相关性、混杂、选择偏差、因果图、反向因果关系等。

虽然这种知识有趣且有价值,但还是有很多的。套用查理·芒格“承担大部分运费”——我们可以在周一早上例行应用来测试一个暗示性的比较是否真实,这里面有什么基本的想法吗?

是的。当一个比较误导你的时候, 混淆 往往就是这个原因(我们很快就会看到这样的例子)。

混杂 发生在什么时候

  • 受试者根据非随机因素自行选择分组或被分配分组
  • 这些因素影响着被比较的对象。

这些因素被称为混杂因素。把混杂因素想象成 共因 共因既有受试者如何在群体中结束又有群体在利益衡量标准中的表现。

我们来看几个例子。

  • 对比:经常冥想的人比不冥想的人患心脏病的几率低 X%。锻炼和饮食可能造成的混淆:锻炼和遵循更健康饮食的人= >更可能在冥想组更不容易患心脏病(来源:改编自http://bit.ly/2TQjzus)**
  • 对比:单身人士比已婚人士在脸书上活跃的可能性高 X%。因年龄而产生的可能混杂因素:更年轻的人= >更有可能属于单一群体更有可能活跃在脸书上(来源:改编自分类数据分析,第 2.1.8 章,第 43 页)。**
  • 对比:一家医院想要更换超声波设备,进行了一项测试,发现新设备比旧设备多花了 X%的时间。因专业水平而可能产生的混淆:新技术人员= >更有可能尝试新装置可能需要更长时间在任何装置上做超声波检查(来源:改编自http://bit.ly/2V0yfsZ)。**

学习混杂因素就像学习一个新单词。一旦你意识到他们的存在,你会发现他们无处不在。

对于混杂因素,我们能做些什么?

我们需要为他们控制。有大量关于如何做到这一点的文献(文章、文章、文章),许多领域的研究人员——例如生物统计学和流行病学——已经这样做了几十年。当你在报纸上读到一篇文章“X 与 Y 的高风险有关,在控制了年龄、性别、身体质量指数、血压和身体活动水平后”,混杂因素正在得到控制。

控制混杂因素的一种简单且广泛使用的方法是分层。

  • 我们根据混杂值将受试者分组,并计算每个组的比较。
  • 根据定义,在每个时段内,混杂因素的值不会改变。 因此,该时段内结果指标的任何变化都不能归因于混杂因素的变化。 这就是为什么分层行得通的本质。
  • 然后,我们通过计算每个桶的数字的加权平均值来计算新的总体比较。我们在这里使用的权重是关键,我们将在下面详细检查它们。
  • 如果最初的比较和新的比较彼此非常不同,那么混淆就起作用了,我们不应该相信最初的比较。

让我们把这些想法汇总成一个清单,当你看到一个提示性的比较时使用。

1。首先,确认基础数据实际上是观察性的,也就是说,受试者是自我选择还是以某种非随机的方式结束分组?如果数据是实验性的,就不需要这个清单:-)

2。想到潜在的 混杂因素 那影响 *(a)哪个主体最终在哪个群体(b)利益衡量标准?如果受试者自己选择分组,思考是什么因素导致他们有意识或无意识地选择一组而不是另一组。***

3。如果你发现的任何一个混杂因素都有数据,就按照上面的描述进行分层分析。

让我们将清单应用到几个例子中。

几个月前,您在您的电子商务网站的一个部分介绍了产品推荐,并想知道它是否“有效”。你可以做的一个最简单的比较就是比较点击了一个推荐的访问者和没有点击的访问者的花费。

这是你发现的。

点击产品推荐的网站访客比没有点击的访客多花了 18%的钱。

这种比较应该相信吗?

如果你这样做了,你可以决定在网站的所有部分显示推荐,以增加购物者点击推荐的机会。对于这样做的购物者,他们可能会平均多花 18%的钱?

让我们应用清单。

  1. 观测数据?**是的。虽然 A/B 测试在电子商务中无处不在,并且由于其使用了随机化,是可靠比较的来源,但像上面这样的比较不太可能来自随机测试,因为你不能强迫访问者点击产品推荐。参观者必须自选。**
  2. 潜在的混杂因素。显而易见的是来访者的既往病史。如果他们是一个忠实的客户,他们可能会经常访问网站,更多地浏览网站,点击产品推荐,在购买时花费更多等等。因此,忠诚度可以影响他们点击推荐的倾向和他们的花费。
  3. 分层分析。

****步骤 1:定义混杂变量桶。如果我们认为忠诚度是一个混淆因素,也许我们可以做的最简单的事情就是定义两个桶,新访客和回访访客,作为访客忠诚度的近似衡量标准。

****第二步:计算每个混杂因素的数量。我们分别计算新访客和回头客的人均消费数字。这将扩展原始表…

…到这

等一下!点击产品推荐对任何一种访问者类型都没有影响——0.70 美元保持为 0.70 美元,1.30 美元保持为 1.30 美元——然而,总体影响是 18%!这怎么可能?****

为了深入了解这是如何发生的,让我们从桶级别数字开始,自下而上计算总数——1.18 美元和 1.00 美元。

我们将首先计算样本中新访客和回头客的总体百分比:

然后,我们计算每种访问者类型点击推荐的百分比:

虽然 83%的回头客会点击产品推荐,但只有 55%的新访客会这样做。

有了这两个表,我们可以计算点击者和非点击者组中新的和返回的的百分比(即在每一列中)。例如,新访问者的点击者百分比= 27% * 55% / (27% * 55% + 73% * 83%) = 20%,返回的点击者百分比为 100% — 20% = 80%。完整的表格是:

现在,总体数字只是新的和返回的支出数字的平均值,加上上面计算的数字…

$0.70 * 20% + $1.30 * 80% = $1.18

$0.70 * 50% + $1.30 * 50% = $1.00

从图像上看,

…导致

我们现在可以看到它的危害有多严重。

每组(即列)中新老员工的比例因组而异**

如果组合不完全相同,可能会出现奇怪的事情——例如,的总人数可能会减少,而 的每一个 阶层人数都会增加! ( 辛普森悖论)。

为什么两列中的混合物不一样?

因为回头客比新访客更有可能点击推荐。

需要注意的是,这种现象与你的数据样本中新访客和回头客的组合无关。关键因素是点击推荐的新访客的百分比与点击推荐的回头客的百分比。

如果这两个百分比相同,混合将是相同的。如果这两个百分比不同,混合将是不同的。

(顺便说一句,这就是随机分配如何防止混淆。如果我们以某种方式随机将访问者分配到“点击”和“未点击”组,点击推荐的新访问者的百分比将与点击推荐的回访访问者的百分比相同。因此,“点击”组和“未点击”组中的新信息和返回信息的混合应该是相同的,防止了我们上面看到的失真)

****第三步:计算调整后的总比较数

我们通过在两列中使用相同的权重来“取消发现”。哪些砝码?新客户和回头客的百分比。

正如我们之前看到的,新访客和回头客的总体比例分别为 27%和 73% …

…我们将它们作为权重来计算调整后的比较。

你现在可以看到,每种游客类型的 0%的消费差异也反映在调整后的总人数中。差异已经消失。

混杂因素扭曲了这些权重,因此每一列的权重都不同。通过对每根柱子使用相同的重量,我们消除了损害。

概括一下:使用数据中混杂组的受试者组合作为两组的权重,计算组级数字的加权平均值,以得出调整后的总体数字。

第四步:比较比较:-)

由于原始比较和调整后的比较大相径庭,因此原始比较不可信。

(旁白:评估产品推荐效果的一个更好的方法是将网站访问者随机分配到 A 组和 B 组,A 组的推荐而 B 组的关闭,并测量这两组在特定时间段内的每次点击收入、转换率等)。

警告:这种“控制混杂因素”的方法远非万无一失。

  • 可能还有其他你没有想到的混淆因素。关于如何识别一整套混杂因素(例如后门标准),有一个高度发展的理论,我鼓励你去阅读。我的希望是,这里提倡的尝试非正式地(基于你对业务的了解)识别混杂因素的方法足以让你开始。
  • 你可能想到了其他混杂因素,但是你没有关于它们的数据,所以你无法控制它们。
  • 你发现的混杂因素并不是真正的混杂因素。
  • 你的控制方法不够好,例如,在上面的例子中,我们将游客分为两个桶,但也许这些桶太大了,以至于混淆在每个桶的内继续(在文献中称为剩余混淆)。
  • 另一方面,如果您创建了太多的存储桶,这些存储桶中的一些可能有太少的主题,这将导致度量的不可靠的估计。

尽管有这些警告,当你看到一个有趣的比较,并想付诸行动时,还是值得使用这个清单。

这可能不会让你成为工作中的摇滚明星,但至少在某些时候会让你避免得出错误的结论。

在第 2 部分中,我们看了更多的例子,并解决了混杂因素太多导致分层变得混乱的情况。

(如果您觉得这篇文章有帮助,您可能会发现这些感兴趣的内容)

如何使用卷积神经网络进行时间序列分类

原文:https://towardsdatascience.com/how-to-use-convolutional-neural-networks-for-time-series-classification-56b1b0a07a57?source=collection_archive---------1-----------------------

一个温和的介绍,最先进的模型概述,和一个动手的例子。

Photo by Christin Hume on Unsplash.

介绍

大量数据以时间序列的形式存储:股票指数、气候测量、医学测试等。时间序列分类有着广泛的应用:从股票市场异常的识别到心脑疾病的自动检测。

时间序列分类有多种方法。大多数方法包括两个主要阶段:在第一阶段,你要么使用某种算法来测量你想要分类的时间序列之间的差异(动态时间弯曲是一种众所周知的方法),要么使用你可以使用的任何工具(简单的统计学,先进的数学方法等)。)将您的时间序列表示为特征向量。在第二阶段,你使用某种算法对你的数据进行分类。它可以是从 k-最近邻和 SVM 到深度神经网络模型的任何东西。但是有一点将这些方法统一起来:它们都需要某种特征工程作为分类执行前的一个单独阶段。

幸运的是,有些模型不仅将特征工程整合到一个框架中,还消除了任何手动操作的需要:它们能够自动提取特征并创建时间序列的信息表示。这些模型是递归和卷积神经网络(CNN)。

研究表明,与其他方法相比,使用 CNN 进行时间序列分类有几个重要的优势。它们是高度抗噪声的模型,并且它们能够提取与时间无关的非常有用的深层特征。在本文中,我们将详细研究一维卷积如何对时间序列进行运算。然后,我将概述一个由圣路易斯华盛顿大学的研究人员提出的更复杂的模型。最后,我们将查看一个简化的多尺度 CNN 代码示例。

时间序列的一维卷积

想象一个长度为 n 宽度为 k 的时间序列。长度是时间步长的数量,宽度是多元时间序列中变量的数量。例如,对于脑电图,它是通道的数量(人头部的节点),对于天气时间序列,它可以是温度、压力、湿度等变量。

卷积核始终具有与时间序列相同的宽度,而它们的长度可以变化。通过这种方式,内核从一个时间序列的起点向终点沿一个方向移动,执行卷积。它不会像通常的 2-D 卷积应用于图像时那样向左或向右移动。

1-D Convolution for Time Series. Source: [2] (modified).

核的元素乘以它们在给定点覆盖的时间序列的相应元素。然后将乘法的结果加在一起,并将非线性激活函数应用于该值。结果值成为新的“过滤”单变量时间序列的元素,然后内核沿着时间序列向前移动以产生下一个值。新的“过滤”时间序列的数量与卷积核的数量相同。根据核的长度,初始时间序列的不同方面、属性、“特征”在每个新的过滤序列中被捕获。

下一步是对每个过滤的时间序列向量应用全局最大池:从每个向量中取最大值。从这些值形成一个新的向量,并且这个最大值的向量是最终的特征向量,其可以被用作常规全连接层的输入。整个过程如上图所示。

让我们把它带到另一个水平

记住这个简单的例子,让我们检查用于时间序列分类的多尺度卷积神经网络的模型[1]。

该模型的多重可伸缩性在于其架构:在第一卷积层中,卷积在 3 个并行的独立分支上执行。每个分支从数据中提取不同性质的特征,以不同的时间和频率尺度进行操作。

这个网络的框架由 3 个连续的阶段组成:变换、局部卷积和全卷积。

Multi-Scale Convolutional Neural Network Architecture [1].

转换

在这一阶段,不同的变换应用于 3 个独立分支上的原始时间序列。第一个分支转换是身份映射,这意味着原始时间序列保持不变。

第二个分支转换是用不同窗口大小的移动平均值平滑原始时间序列。通过这种方式,创建了几个具有不同平滑度的新时间序列。这背后的想法是,每个新的时间序列都整合了来自原始数据的不同频率的信息。

最后,第三个分支变换是用不同的下采样系数对原始时间序列进行下采样。系数越小,新的时间序列就越详细,因此,它会在更小的时间范围内整合有关时间序列特征的信息。系数较大的下采样会产生不太详细的新时间序列,这些序列捕捉并强调原始数据在较大时间尺度上表现出来的特征。

局部卷积

在这个阶段,我们前面讨论的具有不同滤波器大小的 1-D 卷积被应用于时间序列。每个卷积层之后是最大池层。在前面更简单的例子中,使用了全局最大池。这里,最大池不是全局的,但池内核的大小仍然非常大,比您在处理图像数据时习惯的大小要大得多。更具体地说,池内核大小由公式 n/p 确定,其中 n 是时间序列的长度,而 p 是池因子,通常在值 {2,3,5} 之间选择。这个阶段称为局部卷积,因为每个分支都是独立处理的。

全卷积

在这一级,来自所有 3 个分支的局部卷积级的所有输出被连接。然后再增加几个卷积层和最大池层。在所有的变换和卷积之后,您只剩下一个具有深度、复杂特征的平面向量,这些特征在广泛的频率和时间尺度域中捕获关于原始时间序列的信息。然后,该向量被用作最后一层上具有 Softmax 函数的完全连接层的输入。

Keras 示例

from keras.layers import Conv1D, Dense, Dropout, Input, Concatenate, GlobalMaxPooling1D
from keras.models import Model#this base model is one branch of the main model
#it takes a time series as an input, performs 1-D convolution, and returns it as an output ready for concatenationdef get_base_model(input_len, fsize):
#the input is a time series of length n and width 19
input_seq = Input(shape=(input_len, 19))
#choose the number of convolution filters
nb_filters = 10
#1-D convolution and global max-pooling
convolved = Conv1D(nb_filters, fsize, padding="same", activation="tanh")(input_seq)
processed = GlobalMaxPooling1D()(convolved)
#dense layer with dropout regularization
compressed = Dense(50, activation="tanh")(processed)
compressed = Dropout(0.3)(compressed)
model = Model(inputs=input_seq, outputs=compressed)
return model#this is the main model
#it takes the original time series and its down-sampled versions as an input, and returns the result of classification as an outputdef main_model(inputs_lens = [512, 1024, 3480], fsizes = [8,16,24]):
#the inputs to the branches are the original time series, and its down-sampled versions
input_smallseq = Input(shape=(inputs_lens[0], 19))
input_medseq = Input(shape=(inputs_lens[1] , 19))
input_origseq = Input(shape=(inputs_lens[2], 19))#the more down-sampled the time series, the shorter the corresponding filter
base_net_small = get_base_model(inputs_lens[0], fsizes[0])
base_net_med = get_base_model(inputs_lens[1], fsizes[1])
base_net_original = get_base_model(inputs_lens[2], fsizes[2])embedding_small = base_net_small(input_smallseq)
embedding_med = base_net_med(input_medseq)
embedding_original = base_net_original(input_origseq)#concatenate all the outputs
merged = Concatenate()([embedding_small, embedding_med, embedding_original])
out = Dense(1, activation='sigmoid')(merged)model = Model(inputs=[input_smallseq, input_medseq, input_origseq], outputs=out)
return model

该模型是多尺度卷积神经网络的更简单版本。

它将原始时间序列及其 2 个下采样版本(中等长度和小长度)作为输入。模型的第一个分支处理长度为 3480、宽度为 19 的原始时间序列。相应的卷积滤波器长度是 24。第二个分支处理时间序列的中等长度(1024 时间步长)下采样版本,这里使用的滤波器长度为 16。第三个分支处理时间序列的最短版本(512 个时间步长),滤波器长度为 8。这样,每个分支提取不同时间尺度的特征。

在卷积和全局最大池层之后,添加了丢弃正则化,并且所有输出被连接。最后一个全连通层返回分类结果。

结论

在这篇文章中,我试图解释深度卷积神经网络如何用于时间序列分类。值得一提的是,提出的方法并不是唯一存在的方法。有多种方法可以将时间序列以图像的形式呈现出来(例如,使用它们的光谱图),可以对其应用常规的二维卷积。

非常感谢您阅读这篇文章。我希望它对你有帮助,我真的很感谢你的反馈。

参考文献:

[1]崔,陈,陈.多尺度卷积神经网络用于时间序列分类(2016),。

[2] Y. Kim,卷积神经网络用于句子分类(2014),https://arxiv.org/abs/1408.5882。

如何利用数据科学产生社会影响

原文:https://towardsdatascience.com/how-to-use-data-science-for-social-impact-e9b272b1a4b3?source=collection_archive---------19-----------------------

Photo by Arjunsyah on Unsplash

透明度腐败协作信任

数据科学是一个真正的跨学科领域。

数学家、统计学家、计算机科学家、社会科学家、数据库管理员、数据工程师、图形设计师、用户界面专家、记者、说书人、研究人员和企业管理人员都参与了这个过程。

随着机器学习和人工智能的不断发展,哲学家和伦理学家也有望被纳入这一过程。

数据科学强大。如果使用正确,它将授予对以下内容的访问权限:

  1. 客观理解世界的能力。
  2. T4 利用这种理解来创造进步的能力。

故事是这样的:

Figure 1

利用数据以多种形式出现。网飞利用数据科学向顾客推荐电影和电视节目。脸书利用数据科学来制作有针对性的广告。谷歌使用数据科学来优化搜索结果。亚马逊使用数据科学与 Alexa 进行对话。微软利用数据科学创造虚拟现实。

但是等等,还有更多。

Kaggle 正在使用数据科学来预测贫困水平,以确定哪里最需要社会福利援助。Code for Africa 正在使用数据科学来创建一个工具,帮助肯尼亚公民出现在投票箱前了解情况并准备投票。DataKind 正在使用数据科学来创造更多简化的摆脱无家可归的途径。

这两组数据科学用户之间存在明显的差异。前者利用数据获得收入。后者利用数据进行社会影响

我们如何继续利用数据科学产生社会影响?

关键:公开数据

什么是开放数据?

由开放知识基础定义:

“开放数据是指任何人都可以自由使用、重用和重新分发的数据。”

很明显,数据科学首先依赖于数据收集。没有数据就没有数据清理,数据分析数据利用率。来自 Kaggle,Code for Africa 和 DataKind 的社会影响项目非常棒,但是如果没有数据,这些项目是不可能实现的。

如果 IDB 没有给他们家庭收入数据,Kaggle 不可能开始预测贫困。如果独立选举&边界委员会没有发布他们在选民登记中心的位置数据,“非洲代码”不可能创造出任何工具。

这正是为什么开放数据是通过数据科学创造社会影响的关键。可用的数据越多,利用它的机会就越多。

我承认,当谈到开放数据时,有一点二分法。这是透明度和安全性之间的一种不稳定的平衡。

我已经分享了我对数据隐私需求的想法。在达到不可逆转的地步之前,解决开放数据的潜在滥用是很重要的。剑桥分析公司(Cambridge analytic a)、 Strava 和 Equifax 丑闻清楚地概述了为什么公开数据可能是糟糕的。

这就是为什么它必须被正确地做。

如何正确做开放数据

对脸书来说,突然向公众开放他们的数据库并不是一个好主意。对谷歌来说,分享他们所有的私人用户信息也是一个同样糟糕的主意。需要明确的是,开放数据并不意味着适用于所有平台。

公开数据的最佳用途是在政府和人民之间。

故事是这样的:

Figure 2

开放数据开启对话

布宜诺斯艾利斯利用他们的开放数据平台告知公众政府正在做什么。他们用数据可视化制作了有趣的报告,向他们的公民展示重要信息。他们甚至创造了一个互动工具来帮助公众了解政府如何为季度预算分配资金。

“预算反映了国家如何利用从全体公民那里获得的资源。重要的是要传达这些资金是如何用于刺激参与、优化控制和提高公众讨论水平的。”-布宜诺斯艾利斯城

开放数据打击犯罪

在哥伦比亚的卡利,开放数据平台已经允许像 DataPico 这样的公司创建工具,告知公众他们城市的犯罪分布情况。

当我住在卡利时,我甚至使用开放数据平台告诉公众在他们的城市哪里最有可能发生凶杀案。

This visual was created using data provided by Cali’s open data platform

预测性警务是数据如何用于打击犯罪的一个很好的例子。虽然在政府采用这一系统之前,预测性警务还有一些重要问题需要解决,但哥伦比亚波哥大的国立大学已经在制定一项为期三年的计划,以利用数据更有效地管理城市。目标是减少犯罪。

开放数据对抗暴力

当数据公开时,就更容易与大量受众分享严酷的现实。Vox 是通过数据可视化向公众提供信息的平台的一个很好的例子。在这个故事中,Vox 使用来自美国实体的数据来提高人们对枪支暴力的认识。

请记住,数据科学提供了一种“客观理解世界的能力”。新闻媒体倾向于主观地向公众展示数据分析。公开数据的美妙之处在于原始数据是客观的。开放数据为公众提供了获取信息的途径,这使得每个人都可以得出自己的结论。

这个工具是一个很好的例子,展示了暴力是如何在卡利市被客观地可视化的。数据可视化提高了公众意识。

开放数据对抗腐败

当政府被迫公开数据时,隐藏腐败变得更加困难。这方面的一些例子:

  • 布宜诺斯艾利斯政府向公众提供他们的预算分配,要求他们负责准确使用预算。
  • 被要求在执勤时佩戴人体照相机的美国警察被要求在法庭上保持诚实。
  • 在墨西哥,使用公开数据来识别腐败合同让政府有责任停止将贿赂作为商业交易。

图 2 概述了这一过程。当公众意识到这一点时,政府和公众之间的对话就开始了。对话导致合作。合作使政府能够与其公民一起创造进步。

进步在人民和政府之间建立信任

对于有腐败历史的国家来说,信任非常重要。一个国家的腐败感知指数(CPI)是一个每年收集的指数,用于衡量腐败公民对其政府的看法。CPI 与人均 GDP 直接相关。

当公民相信他们的政府不那么腐败时,GDP 就会上升。仅仅一个单位的 CPI 增长就被证明可以使人均 GDP 年均增长 1.7%。对腐败的看法在发展中国家有很大影响。

TLDR:在政府和公民之间建立信任非常重要。开放数据有助于做到这一点。

是什么在挡路?

开放数据的主要障碍是它只有在每个人都参与的情况下才能发挥作用。我将在本文中进一步讨论这个问题。

我们建设未来

像 DataKind、Code for Africa 或 Kaggle 这样的组织面临的严峻现实是,大多数社会影响项目都依赖于志愿者工作。不幸的是,很难将有所作为的项目货币化。

好消息是变革的工具就在我们的指尖。开放式数据平台正在增长。许多编码课程可以在免费在线获得。社会影响似乎触手可及。如果你有一台电脑和互联网,你就和其他人一样有资格开始做一些项目来改变你的社区。

数据是我们的历史。数据科学是我们的未来。我们要做的就是建造它。

*结语 *

这篇文章的灵感来自我和我哥哥在哥伦比亚卡利共同举办的主题为“如何编码和实现社会影响”的编码研讨会

The workshop filled up in just a few days!

在研讨会上,我们讨论了开放数据平台如何帮助经济增长、打击腐败和犯罪、建立信任社区以及在政府和公民之间架起桥梁。

为了在 Cali 推广开放数据平台,我们创建并发布了 Datos Profundos。

[## jesmith14/DatosProfundos

欢迎来到 Datos Profundos!这是一个为英语和西班牙语使用者开放的资源仓库,他们对…

github.com](https://github.com/jesmith14/DatosProfundos)

Datos Profundos 是一个开源存储库,为具有任何编码能力的个人提供讲座和教程,以理解数据科学。这些教程使用 Cali 的开放数据平台来推动创建社会影响视觉效果和工具,就像在布宜诺斯艾利斯和肯尼亚那样。

讲西班牙语和英语的人都可以访问该平台。

感谢阅读!感觉有动力?我和我哥哥正在哥伦比亚发起一项运动,旨在提供无障碍编码教育,同时利用技术产生积极的社会影响。如果你有兴趣参与,请联系我们!

[## 杰西·史密斯-数据科学实习生- datapico | LinkedIn

数据伦理技术社会影响透明度真实性*教育我喜欢学习和与人交流。我…

www.linkedin.com](https://www.linkedin.com/in/jessiejsmith/)

如何在机器学习项目中使用数据版本控制(dvc)

原文:https://towardsdatascience.com/how-to-use-data-version-control-dvc-in-a-machine-learning-project-a78245c0185?source=collection_archive---------9-----------------------

当在一个多产的机器学习项目中工作时,你可能会处理一些数据和几个模型。为了跟踪哪些模型是用哪些数据训练的,您应该使用一个系统来对数据进行版本化,类似于对代码进行版本化和跟踪。解决这个问题的一种方法是 dvc(数据版本控制,https://dvc.org/),它以类似于 Git 的方式处理数据版本控制。

为了说明 dvc 在机器学习环境中的使用,我们假设默认情况下我们的数据分为训练、测试和验证文件夹,数据量随着时间的推移通过主动学习周期或通过手动添加新数据而增加。下面的结构就是一个例子,为了简化起见,这里省略了标签:

├── train
│    ├── image1.jpg
│    ├── image2.jpg
│    └── image3.jpg
├── val
│    └── image4.jpg
└──test└── image5.jpg

通常,最低版本系统应该具有以下两种功能:

  • 用新版本标记一组新数据,例如 vx.y.z
  • 返回旧数据版本或在不同数据版本之间切换非常容易

在其他功能中,dvc 能够完成这些任务。为此,它与 Git 紧密合作。首先,您需要安装 dvc,这可以使用 pip 来完成

pip install dvc 

要开始版本化过程,您必须在数据的基本文件夹中创建一个 git 存储库,然后通过

git init
dvc init

通过 init 命令,dvc 现在已经创建了一个包含其缓存的. dvc 文件夹,以便保存不同数据版本和存储元信息的配置文件之间的差异。

在这种情况下,你想知道 git 如何适应这个概念:在这种情况下,git 的任务不是对数据本身进行版本化,而是对 dvc 文件进行版本化,DVC 文件保存了版本的元信息,如对应于特定版本的文件的位置,或者数据的哪个文件属于当前数据版本的信息。

为了让 git 忽略数据本身,dvc 还会自动写入。gitignore 文件。提交 dvc 的配置文件和。gitignore 文件我们需要做一个初始提交

git commit -m “Initial commit”

每个数据版本都与其自己的相关联。dvc 文件,同样与一个提交或一个 Git 头相关联。dvc 文件定义并跟踪给定版本的数据,由此 dvc 文件本身被 Git 跟踪。对我来说,将新数据版本与 Git 头相关联的一个好方法是为新数据版本创建一个新分支。为此,在定义我们的第一个版本之前,我们用版本的名称创建一个新的分支,并签出到这个分支:

git checkout -b v0.0.1

现在,我们可以通过告诉 dvc 应该跟踪哪些数据来定义我们的第一个版本,在我们的例子中是 train、val 和 test 文件夹。这可以通过 dvc add 命令来完成:

dvc add train test val

之后,我们现在看到新的。每个文件夹的 dvc 文件,如基本文件夹中的 train.dvc。文件夹本身已被添加到。gitignore,这样 git 就不会跟踪数据本身,在我们的例子中,这是 dvc 的任务。为了追踪新的。我们用 Git 创建了标准的 Git 提交过程

git add .
git commit -m "Data versioning files added to Git"

现在,我们已经创建了数据的第一个版本,将哪些数据属于我们的。dvc 文件并参考了。dvc 自己被当前提交。请注意,您还可以将 git 连接到远程 git 来保存和版本化。远程 dvc 文件。在这种情况下,数据保留在当前文件夹中,而不是远程存储(这也可以使用 dvc 推拉进行更改)。

我们现在已经将数据的一种状态与一个版本相关联,但是当然,您不需要为一个 fix 数据集进行数据版本化。因此,我们现在假设两个新图像(image6.jpg 和 image7.jpg)被添加到 train 和 test 文件夹中,因此结构现在看起来像这样:

├── train
│    ├── image1.jpg
│    ├── image2.jpg
│    ├── image3.jpg
│    └── image6.jpg
├── val
│    └── image5.jpg
└── test├── image4.jpg  └── image7.jpg

为了创建新的数据版本,我们重复前面的步骤。因此,我们创建一个对应于新数据版本的新分支

git checkout -b v0.0.2

正如我们已经知道的,一个新的数据版本总是与它们自己相关联的。存储版本元信息的 dvc 文件。为了更新。dvc 文件我们需要告诉 dvc,它应该再次跟踪 train 和 test 文件夹,因为这些文件夹中有新数据:

dvc add train test

train.dvc 和 test.dvc 文件已更改,dvc 现在可以跟踪哪些文件属于当前版本。为了追踪新的。git 分支中的 dvc 文件,我们必须提交:

git add .
git commit -m "Data versioning files added to Git"

现在爽的部分来了。当检查您的 git 分支时,您会看到两个不同的分支(主分支除外),其中每个分支对应一个数据版本:

master
v0.0.1
* v0.0.2

现在,您可以返回到旧的数据版本,并直接更新您的数据目录,以便重新创建旧的数据版本。为了回到之前的版本,我们需要做两件事。首先,我们需要签出到数据版本的相应标题,在本例中是 branch v0.0.1:

git checkout v0.0.1

在这个脑袋里。与 v0.0.2 相比,dvc 文件有所不同,但我们当前的数据目录看起来仍然相同,目录中的数据仍然对应于 v0.0.2。这是因为 dvc 尚未将数据目录与其对齐。dvc 文件。将您的数据目录与正确的数据版本对齐,这同样在。dvc 文件,需要执行 dvc checkout 命令:

dvc checkout

该命令使用其缓存恢复旧的数据版本(在本例中为 v0.0.1)。现在,当您查看您的数据存储库时,您会再次看到以下结构:

├── train
│    ├── image1.jpg
│    ├── image2.jpg
│    └── image3.jpg
├── val
│    └── image4.jpg
└──test└── image5.jpg

文件 image6.jpg 和 image7.jpg 被从数据目录中删除并存储到 dvc 的缓存中。现在,您可以像往常一样使用三个文件夹来处理旧数据版本。

此过程还适用于包含比当前持久存储在数据文件夹中的数据多得多的数据版本,因为 dvc 在其缓存中存储不同版本之间任意大小的差异,因此可以通过其 checkout 命令重新创建数据目录的较旧或较新状态。当然,结账也可以是另一个方向。您可以将 git 签出到 branch v0.0.2 并执行 dvc 签出,以便将数据目录设置为 v0.0.2 版本的状态。

除了 init、add 和 checkout 命令之外,dvc 还有更多功能,以便使机器学习/大数据工作流程更加简单。例如,可以在多台机器之间共享数据版本吗?使用像亚马逊的 S3 存储桶这样的远程存储桶,并使用 dvc 推拉与存储桶进行交互(有关详细信息,请参见。https://dvc.org/。

我希望这篇文章可以帮助更好地组织机器学习项目中的数据,并保持更好的概览。

更多关于机器学习、数据科学和统计学的博文,请查看

如何使用深度学习,即使是小数据

原文:https://towardsdatascience.com/how-to-use-deep-learning-even-with-small-data-e7f34b673987?source=collection_archive---------2-----------------------

以及为什么它如此重要

你已经听说了这个消息——深度学习是自切片面包以来最热门的东西。它承诺以极小的代价解决大量数据中最复杂的问题。唯一的问题是,你既不是在谷歌也不是在脸书工作,数据很少。那你打算怎么办?你还能利用深度学习的力量吗?还是你运气不好?让我们来看看你如何能够利用深度学习,即使数据有限,以及为什么我认为这可能是未来研究中最令人兴奋的领域之一。

从简单开始

在我们讨论利用深度学习处理有限数据的方法之前,请从神经网络后退一步,建立一个简单的基线。通常不需要很长时间就可以试验一些传统的模型,比如随机森林。这将帮助你衡量深度学习的任何潜在提升,并为你的问题提供深度学习与其他方法之间的权衡的大量见解。

获取更多数据

这听起来可能很荒谬,但是你真的考虑过你是否能收集更多的数据吗?我惊讶地发现,我经常向公司提出这样的建议,他们看着我,好像我疯了一样。是的——投入时间和金钱来收集更多的数据是可以的。事实上,这通常是你的最佳选择。例如,也许你正在尝试对稀有鸟类进行分类,但数据非常有限。几乎可以肯定的是,只要标注更多的数据,解决这个问题会更容易。不确定需要收集多少数据?尝试绘制学习曲线,添加额外的数据并观察模型性能的变化。

微调

Photo by Drew Patrick Miller on Unsplash

好吧。让我们假设您现在有一个简单的基线模型,并且收集更多的数据要么是不可能的,要么太昂贵。在这一点上,最可靠的方法是利用预先训练好的模型,然后针对您的问题对它们进行微调。

微调的基本思想是获取一个非常大的数据集,希望它与您的领域有些相似,训练一个神经网络,然后用较小的数据集微调这个预训练的网络。你可以在这篇文章中了解更多。

对于图像分类问题,要去的数据集是 ImageNet 。该数据集包含跨越许多对象类别的数百万幅图像,因此可用于许多类型的图像问题。它甚至包括动物,因此可能有助于珍稀鸟类的分类。

要开始微调一些代码,请查看 Pytorch 的伟大的教程。

数据扩充

如果您无法获得更多数据,并且在大型数据集上的微调没有任何成功,那么数据扩充通常是您的下一个最佳选择。它也可以与微调结合使用。

数据扩充背后的想法很简单:以提供新数据的方式改变输入,同时不改变标签值。

例如,如果你有一张猫的图片,旋转图像,它仍然是一张猫的图片。因此,这将是很好的数据扩充。另一方面,如果你有一张道路的照片,并希望预测合适的转向角度(自动驾驶汽车),旋转图像会改变合适的转向角度。这是不行的,除非你也适当地调整转向角度。

数据扩充是最常见的图像分类问题,你可以在这里找到技术。

你可以经常想到创造性的方法来增加其他领域的数据,如 NLP(参见这里的一些例子),人们也在尝试用 GANs 来生成新数据。如果对 GAN 方法感兴趣,我会看看 DADA :深度对抗数据增强。

余弦损失

最近的一篇论文,在没有使用余弦损失进行预训练的情况下对小数据集进行深度学习,发现当将损失函数从分类交叉熵损失切换到分类问题的余弦损失时,小数据集的准确性提高了 30%。余弦损失简单来说就是 1 — 余弦相似度。

在上面的图表中,您可以看到性能如何根据每个类的样本数量而变化,以及微调如何对一些小数据集(CUB)非常有价值,而对其他数据集(CIFAR-100)没有价值。

深入

在 NIPs 的一篇论文中,现代神经网络对小数据集进行归纳,他们将深度神经网络视为整体。具体来说,“不是每一层都呈现出不断增加的特征层次,而是最终层提供了一个整体机制。”

我对此的看法是,对于小数据,确保你建立了深厚的人际网络,以利用这种整体效应。

自动编码器

已经有一些成功使用堆叠式自动编码器用更优的起始权重来预训练网络。这可以让你避免局部优化和其他不好的初始化陷阱。不过,安德烈·卡帕西建议不要对无人监督的预训过于兴奋。

如果你需要温习自动编码器,你可以查看斯坦福深度学习教程。基本想法是建立一个预测输入的神经网络。

先验知识

Photo by Glen Noble on Unsplash

最后,但同样重要的是,尝试并找到整合特定领域知识的方法来指导学习过程。例如,在通过概率程序归纳的人类级概念学习中,作者构建了一个模型,该模型通过利用过程中的先验知识从零件构建概念。这导致了人类水平的性能,并超过了当时的深度学习方法。

您还可以使用领域知识来限制网络的输入,以减少维数或将网络架构调整得更小。

我把这作为最后一个选项,因为整合先前的知识可能具有挑战性,并且通常是最耗时的选项。

再次制造小爽

希望这篇文章给了你一些关于如何利用深度学习技术的想法,即使数据有限。我个人发现,这个问题目前没有得到应有的讨论,但它有着非常令人兴奋的影响。

有大量的问题只有非常有限的数据,而获取更多的数据是非常昂贵或不可能的。比如检测罕见病或者教育成果。找到将我们的一些最佳技术(如深度学习)应用于这些问题的方法是非常令人兴奋的!甚至吴恩达也同意:

这个故事也可以在这里找到。

如何使用不同的数据模型和数据库的可视化表示

原文:https://towardsdatascience.com/how-to-use-different-data-models-and-visual-representation-of-databases-e2d41c940532?source=collection_archive---------20-----------------------

数据库和 SQL 初级课程

当您进入数据库和数据科学领域时,您必须掌握的第一件事是数据库中实体之间的关系。这很重要,因为您使用的数据必须对其进一步的实现绝对有效。

Photo by JESHOOTS.COM on Unsplash

让我们马上看看如何最好地概述数据并准备它。
举个例子,我将使用一个基于 1954-2014 年 FIFA 世界杯的数据库。

在这个数据库中,我们有多个实体,它们代表了数据库中最重要的部分,并且应该是相互连接的。这是这种关系的可视化表示:

当连接实体时,您还必须添加符号,以便更容易识别实体之间的关系。对于这个数据库,我准备用修改陈的符号。Chen 的实体关系建模符号使用矩形表示实体集,菱形表示适合一级对象的关系:它们可以有自己的属性和关系。如果实体集参与关系集,它们用一条线连接起来。

这看起来是这样的:

1:1 — [1]到[1]
1:C — [1]到[0 或 1]
1:M — [1]到[至少 1]
1:MC — [1]到[任意多]
C:C — [0 或 1]到[0 或 1]见陈
C:M — [0 或 1]到[至少 1]见 1

C ("choice"/"can ")到模型 0 或 1,而 1 恰好表示 1,M 至少表示 1

对关系建模有多种表示方式,这意味着实体之间的符号可以不同。

例如,您可以使用(min,max)符号,对于同一个数据库,该符号如下所示:

这是一个 SQL 脚本,它将表创建为上面的实体:

下图显示了用关系表(红色)连接实体(绿色)的过程:

这就是数据的可视化表示。就不同的符号和关系而言,还有很多方法可以做到这一点。

激励的遗言

当开始使用数据库时,尽量精确处理数据和数据中实体之间的关系。掌握数据科学的每一步都有其特殊之处,正确开始非常重要!坚持学习编程!

感谢阅读!

如何设计最快的汽车

原文:https://towardsdatascience.com/how-to-use-doe-to-design-the-fastest-car-8ddafba905ab?source=collection_archive---------25-----------------------

从有限数量的乐高积木中研究实验设计(DOE)

ZEUS — The Mighty Truck

项目目标和目的

这个“实验设计”项目的目的是最大限度地增加乐高赛车在走下预先建造的坡道后可以行驶的距离。这辆赛车是由数量有限的乐高积木组装而成的。通过建造这款赛车,我们对距离进行了细致的比较,以找到最佳型号。

描述你的实验装置

首先,当实验进行时,所有的观察都是在同一天进行的。如前所述,这个模型有两个不同的复制,四个因素(将在下一节介绍)。这个斜坡与墙壁的夹角为 24 度,斜坡的尺寸为 28 英寸(长)x 12.5 英寸(高)。为了测试的目的,汽车从这个稳定的斜坡的顶部被释放,并在房间内行驶一段距离。每一个测试的变化,关于模型,举行了不同的因素组合,以发现最好的赛车。

选择的因素

Factors

为项目选择的第一个因素是 【离地间隙(A) ,它描述了模型底部离地面的高度,单位为厘米。为了了解离地间隙是否重要,选择了 2 厘米作为“-1”因子等级,另一方面,2.2 厘米低于因子等级“1”。在这个项目中选择的第二个因素是模型的【B】,这与汽车前后轴基的宽度有关。为了了解这一因素是否重要,因子级别“-1”选择了 4.8 厘米,因子级别“1”选择了 6.4 厘米。为该项目挑选的第三个因素是 【前轮尺寸(C) ,它描述了可以安装到模型上的不同车轮组。同样,小车轮尺寸将由因子等级“-1”表示,大车轮尺寸将由因子等级“1”表示。第四个也是最后一个因素是模型的(D),这是模型背面的迷你翼形机构。要查看结果是否有实际变化,因子级别“-1”将用于复制没有扰流板的车型,而“1”将用于复制有扰流板的车型。

响应变量测量

用卷尺测量离坡道末端的距离。在本项目中,响应变量(y)是从匝道终点测量的水平距离。对于每一次观察,都要测量离斜坡底部中心的距离。就赛车而言,测量是从模型的左后轮进行的,以便在所有观察中获得更好的准确性。通过这个实验设置,收集了包含所有 32 个观察值的完整数据表。

实验设计和方法

该实验的设计包括不断测试具有相同基础模型的乐高赛车,同时还实施四个因素和两个复制。为了减少该模型中的变化,我们选择了前面提到的在测试期间进行快速调整的因素。这使得在存在不同因素组合的情况下,可以通过观察模型的比较来做出比较决策。为了避免任何噪音,该实验再次运行两次,以避免和阻止这些罕见情况下的任何噪音参数。在这个项目的方法中,遵循了两个约束条件,以确保汽车的性能不会受到任何外部因素的影响。第一个限制是给定的乐高积木是 DOE 项目中唯一使用的积木。第二个约束包括确保所有测试的模型都有乐高套装中提供的挡风玻璃和方向盘。

数据分析和模型充分性检查

下图中的 “残差与拟合” 表明所有残差围绕 0 的中线随机分离。这种模式支持回归的假设,即关系是线性的,并表明残差具有恒定的方差,同时也指出没有异常值。通过图表中各种各样的点可以进一步看出这一点。图中没有任何危险信号或趋势表明数据中存在问题。现在, “残差对顺序” 图也显示了所有残差随机围绕 0 的中间线,其结果与前面提到的图非常相似。因此,这两个图表明残差是独立的,并且彼此不相关。看 【正态概率图】 时,点呈正态分布,有很强的线性关系,表示正态。 【直方图】 图也讲述了一个类似的故事,因为残差的频率显示了一组非常正态分布的数据。

结果

观察

  • Normal Plot and Pareto Chart

Normal Plot and Pareto Chart

如上图所示,通过来自数据集的四个组合可以看出重要因素。第一个重要因素是轴距。第二个重要因素是赛车底座到地板的离地间隙。第三个重要因素是汽车前部的车轮尺寸。最后也是最有趣的因素是离地间隙、轴距和扰流板的组合。首先,这一点包括 D,它本身并不是一个重要因素。另一方面,这种特殊的因素组合产生了数据差异,与前面提到的其他重要因素不相上下。

  • Main Effects Plot

Main Effects Plot

此处的“主效应”图显示,与 d 相比,因素 A、B、C 的影响更大。原因是线更陡,这表明存在强烈的主效应。其中最陡的大约是轴距,因为这个因素有非常重要和积极的影响。虽然可能有轻微的主效应,但关于扰流器,该线更接近于水平,这将表明这实际上不太重要。

  • Interaction Plot

Interaction Plot

上面的“距离相互作用图”显示了数据中可能存在的各种相互作用。这里每一个接近平行的图,比如左上角的 AB,都没有数据中存在的相互作用。另一方面,AD 有一个相互作用,即“离地间隙扰流器”,因为两条线相互交叉,因此表明存在一种关系。此外,由于这种情况,这两个因素 AD 相互影响。

  • Cube Plot

Cube Plot

上面显示的“立方体图”显示了与实验测试结果和数据集相关的拟合平均值。这些值中的最大值是左立方体右上角的 46.3828。这表明 A*B 关系产生了一个大值,如图所示。此外,与另一个立方体相比,左边的立方体具有更高的拟合平均值。

因子回归

  • Analysis of Variance

下面的 ANOVA 表表明,所有 4 个因素(A、B、C 和 ABD)分别是显著的。这可以通过 P 值 0.017、0.000、0.002 和 0.026 看出。由于这些值都小于 0.05,所以它们在统计上是显著的,并显示出它们在数据中的差异。此外,它们还具有较高的 F 值,这表明在大多数情况下具有统计学意义。

Analysis of Variance

  • Model Summary

80.09%的高 R2 值表明拟合值非常接近实际观察值。

Model Summary

  • Coded Coefficients

下面的编码系数表显示所有 VIF 值均为 1,这表明这些因子没有多重共线性。

Coded Coefficients

结论

总之,在 DOE 项目中发现的最重要的因素是离地间隙和轴距。这些部件对乐高赛车的距离和速度都有很大的影响。在财务分析中选择的最好的汽车是“AB”型,它有更宽的轴距,更高的离地间隙,小前轮,没有扰流板。与其他型号相比,这辆车达到了最大的平均行驶距离。就推荐而言,轴距大、离地间隙高、前轮小、没有扰流板的车型是最佳的赛车。现在,就 DOE 项目期间经历的其他事情而言,建议任何型号都采用更宽的轴距。总的来说,找到的性价比高的模型显示了最佳距离,并将成为“比赛日”比赛的竞争者。

关于我

非常感谢您阅读我的文章!大家好,我是雪莉,目前在亚利桑那州立大学攻读商业分析硕士学位。特别感谢我的队友 Divya,Raghu 和 Andrew 的贡献。如果您有任何问题,请随时联系我!

Email me at ***kchen122@asu.edu***and feel free to connect me on [**LinkedIn**](https://www.linkedin.com/in/kuanyinchen-shirley/)!

如何使用改变游戏规则的人工智能来提高决策质量(案例研究 1)

原文:https://towardsdatascience.com/how-to-use-game-changing-ai-to-boost-decision-quality-case-study-1-6bc4d9c7a897?source=collection_archive---------28-----------------------

source: rarehistoricalphotos.com

注:本文由 诺贝特·多勒 合著。

免责声明:精选照片显示的是加利福尼亚州斯德哥尔摩的旧电话塔。1890.它连接了大约 5500 条电话线。如果你完全接受它的复杂性,那你就看错了文章。然而,如果它让你想起你自己的事业,并且你相信总有更好的方法——这篇文章就是为你准备的。

在本系列的介绍中,我们讨论了游戏人工智能对于商业应用的潜力。企业通过其决策的质量创造价值。通常,这些决策非常复杂。有数以百万计的选择、冲突的驱动因素、不确定性、隐藏的偏见等等。这些复杂性加在一起,使得人类很难做出好的决策。与人类不同,游戏人工智能是为处理这种复杂性而设计的。它擅长支持复杂的决策。

为了说明游戏人工智能如何帮助增强决策能力,我们发布了一系列案例研究。这些例子展示了游戏 AI 在现实世界行业应用中的优势。

本文讨论了我们想要涉及的第一个案例:维护计划。我们将关注能源行业,但这是一个跨许多行业的高风险问题。

Photo by Nicholas Doherty on Unsplash

我们将逐步介绍我们的方法:

  1. 将业务问题转化为游戏
  2. 开发正确的游戏人工智能代理来控制游戏
  3. 分析人工智能的制胜策略——从而解决业务问题

但是,在我们进入游戏、人工智能和获胜策略之前,让我们后退一步,从基础开始。什么是维修规划,更重要的是:为什么是这么复杂的问题

“行业局外人可能会对(……)运营商经常忽视或忽略详细的活动规划感到惊讶,这要么是因为更紧迫的中断修复问题优先考虑,要么是因为在一个专注于激动人心的发现和新产品的行业中,它似乎不那么有趣。”(贝恩&公司

维护规划—它是什么,为什么复杂?

想象一家能源公司的离岸资产。它有十个无人平台需要维护。资产面临着维护范围的巨大工作量,大约有 9,000 个活动需要执行。

这些活动在硬性指标方面有很大不同,例如:

  • 所需工人(员工)总数
  • 工人的技能(如焊工、架子工和技术员)
  • 执行工程的材料要求
  • 工作地点
  • 工程持续时间

此外,活动在软指标方面有所不同,例如

  • 相对重要性
  • 相对紧迫性

最后,更糟糕的是,执行能力受到约束。只有一艘工作船将维护人员运送到平台上。那艘船的载客量是固定的,限制了每天和每个地点可用的工人数量。

资产面临的问题是:计划活动的“最佳”策略是什么?

Photo by Hans-Peter Gauster on Unsplash

这个问题在很多方面都很复杂。

首先是规模的问题。有 9000 件作品,可能的计划选项的数量绝对是巨大的。

第二,有约束。工作船在任何给定的行程中只能承载这么多的工人。每个船员都有特殊的技能,需要相应的计划。活动可能是相互依赖的,有些活动取决于其他活动的时间安排。一些活动可以并行执行,而另一些则不能。

第三,更软的指标通常由意见驱动。意见往往没有量化,有偏差。优先级是由“谁喊得最响”驱动的。不同的利益相关者有不同的看法。而这些意见都在争夺同样的资源。

最后,条件一直在变。检测结果、生产混乱或泄漏经常会改变产品组合。因此,除了非常大、受约束和意见驱动之外,工作范围也一直在变化。

因此,公平地说,资产正面临着驱动因素、约束、意见和数学的复杂局面。找到规划工作的“最佳”策略一点也不简单。

source: gratisography on pexels

处理这一挑战的现有流程基于手工作业。计划是通过优秀、经验和直觉的结合而产生的。结果是维护人员的效率远远低于预期。计划不稳定,维护积压逐年增加。这种积压影响了资产的安全和生产性能。

想象一个星期五晚上下班后在任何一个石油城镇,从阿伯丁到卡尔加里或珀斯。钻井工人和维修工程师讲述了本周的小胜利——其中不少包括吹嘘需要长时间加班才能解决意外问题的英勇努力,或支付溢价将零件和人员紧急送往急需的地方——所有这些都是石油和天然气行业闻名的“能行”精神的一部分。

虽然这些都是好故事,但这绝不是经营企业的方式。“(贝恩&公司)

换言之,提高规划效率是一个需要解决的关键问题。而目前的流程并不能解决这个问题。

幸运的是,还有一个选择:制作一个游戏。

游戏人工智能——步骤 1:将问题转化为游戏

我们的第一步是把手头的业务问题变成一个游戏。为了让游戏人工智能有效,这种翻译的准确性是至关重要的。在实践中,这一步需要对问题有深入的业务理解。

像现实生活中的游戏一样,所有的商业游戏都有相同的关键元素来定义它们。有一个目标,球员,动作和规则,以及一个得分系统。让我们来看看维护游戏中的这些元素。

Photo by Robert Collins on Unsplash

比赛目标

游戏的目标是以可能的最佳方式及时分配资源给任务。资源是工作船和船上的维修人员。任务是从(不断变化的)工作范围组合中提取的活动。

选手,招式&规则

维护计划是一个单人游戏,人工智能代理与自己竞争。代理人做出的移动代表规划决策。它们是:

  1. 船会去哪些地方,按什么顺序?
  2. 船将在每个地点停留多长时间?
  3. 船上有什么船员?每次访问期间,剧组会完成哪些活动?

The AI Agent assigns work to workers, workers to a boat, and a boat to a specific location at a specific time.

这些决策需要遵守各种规则,例如

  • 这艘工作船最多只能运送 50 名工人。
  • 工作船需要每两周返回岸边更换一次船员。
  • 工作船每天只能支持一个平台
  • 夏季平台的工作时间为上午 8 点到下午 6 点,冬季为上午 9 点到下午 5 点。

评分系统

有了规则,我们就有了一个可以在计划游戏中合法行动的玩家。将动作串在一起对应一个维护计划。掌握这个游戏意味着学习如何做出获胜的招式。一系列获胜的棋步产生一个优化的计划

为了确定如何获胜,我们需要引入一个评分系统。计分系统反映了玩家每一步棋的价值。也就是说,每一个计划好的维护活动——一次游戏移动——都会为玩家赢得点数。点数反映了在给定时间执行维护活动的价值。

Photo by Crissy Jarvis on Unsplash

当然,对于这个估值会有意见分歧。也就是说,不同的意见会产生不同的评分系统。例如,假设生产经理优先考虑最高生产平台上的工作。我们可以通过在这些平台上工作赚取额外积分的选项来适应这一点。或者,让我们说维护经理优先减少积压。我们可以通过奖励积压工作来解决这个问题。每一套观点对应一套分数,和一个要玩的游戏。每一个被掌握的游戏都对应着一个为驱动它的观点而优化的计划。

在此阶段,维护游戏的所有主要组件都已就绪。接下来,让我们解释我们如何开发人工智能来掌握它。

第二步:开发正确的人工智能代理来控制游戏

游戏人工智能作为一个研究课题最近有了巨大的发展。有大量关于前沿求解器架构的论文。也有相当多的开源代码被 DeepMind、 OpenAI 和其他人共享。这很棒,但这并不意味着为一个新游戏开发一个 AI 代理——像维护游戏——是微不足道的。用最好的算法来匹配一个游戏会变得非常棘手。开发通常是迭代的,游戏和求解器是并行调整的。

Photo by Lenin Estrada on Unsplash

一般来说,我们结合使用

  • 深度强化学习(DRL),
  • 树搜索,有时是随机的,
  • 运筹学方法,以及
  • 进化算法

这个列表并不详尽,但让我们对我们所研究的体系结构的广度有所了解。在开发我们的人工智能时,有几件事对我们很重要:

  • 表现——做决策有多好?
  • 速度 —它学习的速度有多快?
  • 可扩展性 —它能处理多少选项?
  • 易用性 —需要调多少音才能让它学会?
  • 鲁棒性 —它有多敏感?
  • 配合游戏 —够简单吗?我们不想拿出一把大锤来砸坚果。

在维护游戏中,我们观察到以下情况:

  • 树搜索有潜力,但我们的选择空间太大,不能单独使用它们。
  • 或者方法在小范围内非常有效,但在我们感兴趣的范围内就失效了。
  • 深度强化学习是灵活的,但需要仔细调整以刺激学习。
  • 进化算法不太适合这种排序游戏。

Non-exhaustive list of thoughts on solver architectures for a maintenance game

像普通游戏一样,商业游戏在设置和复杂程度上有很大的差异。因此,游戏人工智能代理往往也非常不同。一刀切的求解器架构方法是行不通的。

因此,我们使用许多架构的元素来构建我们的 AI 代理。就像 AlphaZero 结合强化学习和树搜索来掌握围棋一样。

对于这个案例研究,我们也开发了一种混合方法。在顶层,我们使用了树搜索和深度强化学习。这些方法擅长于做大规模的决策(例如,我把船送到哪里,多长时间?).在的底层,我们建立了一个运筹学引擎。它擅长于专门的排序(例如,我在任何给定的地点和持续时间执行什么工作?).这种组合架构速度快、灵活且高性能。通过结合其构建模块的优势,我们的解决方案优于单引擎解算器。

第三步:分析人工智能的制胜策略——并解决业务问题

质量决策需要对所有可行的备选方案进行全面的概述。以及对这些选择之间的权衡的理解。通过我们的游戏设置,很容易将不同的意见转化为可供选择的计划。

Photo by StartupStockPhotos on Pixabay

例如,有人可能会说在某些平台上每天 24 小时工作是可能的。(这是一个观点)这将极大地提高生产力。然后我们可以更新游戏规则让 AI 机器人掌握这个新游戏,并审查由此产生的优化计划。

另一个例子:维护经理可能对他的积压工作感觉强烈。他可能会争辩说(另一个观点)减少积压是最重要的。我们可以在评分系统中反映这一点,让 AI 智能体再次进行比赛并掌握比赛。这就产生了另一个可供选择的优化方案。

游戏人工智能方法的美妙之处在于,任何数量的观点都可以使用相同的基础和衡量标准进行比较。对于每一组规则,人工智能代理都会产生一个优化的计划。比较优化的计划就是比较苹果和苹果。

那么,我们如何比较这些备选方案呢?

首先,我们与业务利益相关者一起定义关键指标。这些反映了对他们很重要的指标,并推动决策制定。有时这些是现有的指标,有时我们定义新的指标。

在本案例研究中,我们使用了以下指标:

  • 安全关键范围完成的百分比
  • 年底积压工作的规模(工作范围的数量)
  • 产量面临风险
  • 已执行的工作范围总数

其次,我们定义需要评估的场景的。这些代表要玩的优化游戏的集合——根据需要,可以多达数千个。

场景和它们的度量标准充分洞察了意见和结果计划之间的权衡。这使得最终决策者能够做出明智的质量决策。

在本案例研究中,我们发现与现有的规划理念相比,可以规划多达 30% 的工作。正常的业务改进计划很少会带来两位数的改进。此外,在能源行业,两位数代表巨大的货币价值。

30%的改进对 T2 来说是一个巨大的进步,可以扭转积压订单逐年增加的趋势。但是,30%是一个惊喜吗?不,当你想到团队用来玩如此复杂游戏的过时工具集时,就不会了。我们的改进至少部分是由当前的低标准推动的。但是这个标准是真实的——它是规划者每天都要面对的。他们不应该这么做。

更换过时的工具集,并重新设计流程

在我们的简介中,我们建议把你复杂的商业问题带到绘图板上。我们力劝您用 21 世纪的工具取代陈旧的 Excel 规划表。挑战自我,重新设计和改进工作流程和方式。并围绕最新技术重新设计它们。

我们希望这个案例研究是变革的动力。大多数复杂的商业决策都是基于有缺陷或不完整的分析。如果你看着自己的企业,不知道如何改进,那么我们希望这篇文章能激发你的灵感。

Photo by Ben White on Unsplash

我们很想听听你的看法。请随时联系 info@whitespaceenergy.eu 或在 LinkedIn 上发表评论。

如何使用改变游戏规则的人工智能来提高决策质量

原文:https://towardsdatascience.com/how-to-use-game-changing-ai-to-boost-decision-quality-d7f6c1b28ba2?source=collection_archive---------24-----------------------

是时候增强人类在商业决策中的能力了

source: rarehistoricalphotos.com

注:本文与 诺贝特·多勒 合著。

围绕人工智能在商业应用中的潜在价值,存在大量炒作。根据我们的行业经验,大多数炒作都是被误导的。在许多成功的故事中,“人工智能英雄”只是作为一个抛光工具,用于调整现有的流程。这不是因为人工智能的局限性——而是因为缺乏想象力。

我们应该围绕最新的人工智能重新设计我们的业务,而不是把人工智能作为一个附加产品。我们将展示游戏 AI 特别适合这一点。业务流程可以被视为游戏。决策就像游戏中的走法。赢得比赛是最新的人工智能所擅长的。

与其他任何技术相比,游戏人工智能更有潜力推动商业变革。

这篇文章是一系列案例研究的序幕。在每项研究中,我们将分享一个游戏人工智能支持复杂商业决策的例子。在进入这些研究的细节之前,我们先从这个介绍开始。并展示为什么游戏人工智能对商业决策有如此大的意义。

让我们开始吧。

数据与决策

在关于商业人工智能的辩论中,很多焦点都集中在数据上,但数据本身并不产生价值。企业通过将数据转化为决策来创造价值。引用的话 Cassie Kozyrkov ,谷歌决策情报主管:

“数据是美丽的,但决策才是重要的。正是通过我们的决定——我们的行动——我们影响着我们周围的世界”。

正是通过我们的决策,我们创造价值,或者把价值留在桌面上。

高赌注,古老的工具

现在想想你自己在复杂商业决策中的经历。你曾经做过或支持过让你深感不适的决定吗?对分析没有涵盖所有选项感到紧张?知道有更多的观点和风险需要了解?你的信心因为输入数据的不确定性而受到影响?最痛苦的是,意识到时间已经不多了?我们确实有。

许多商业领袖都认识到了这种感觉。然而,大多数人都承认,重要的决策是基于不完整的分析。他们已经接受了他们的决定是由直觉、共识和人类偏见驱动的。

因此,如果你在自己的企业中处理复杂的决策,问问自己这个问题。如果 Excel 是您拥有的最复杂的工具,您对自己的决策质量有多少信心?如果你手机里的技术比驱动你决策的工具更先进,那一定是出了问题。

Image by ElisaRiva from Pixabay

参加比赛

决策和优化决策的策略已经被博弈论广泛研究。对一个游戏理论家来说,游戏就像是:

“……两个或更多人之间的互动,互动的结果取决于每个人的所作所为,每个人对不同的结果都有不同程度的快乐。”

现在——这听起来像大多数的商业互动。对于博弈理论家来说,商业决策代表了博弈中的一步棋。多年来,赢得比赛是人工智能一直擅长的。

所以,我们想象的是这样的:

我们能否利用游戏 AI 做出制胜的商业决策?

事实证明,你可以。

我们将展示如何将商业问题变成游戏。用人工智能掌握这些游戏会导致超出人类能力的决策质量。这是非常宝贵的——尤其是在高风险的商业决策中。

用人工智能控制游戏——简史

通过游戏及其复杂性的镜头来考虑人工智能的历史是很迷人的。随着人工智能的发展,人工智能机器人已经学会掌握更复杂的游戏——并支持更复杂的决策。对于那些感兴趣的人,我们推荐Andrey Kurenkov 的《从人工智能到 AlphaGo 的游戏简史》。

跳棋和国际象棋是 IBM 瞄准的第一个展示人工智能能力的棋盘游戏。1996 年,深蓝是第一台打败国际象棋世界冠军的计算机。深蓝的技能等级低于顶级人类。然而,它分析数百万步棋的能力确保了对加里·卡斯帕罗夫的胜利。

人工智能研究的下一个著名展示是围棋。围棋是出了名的难,因为棋盘上有大量的位置——远远超过了国际象棋。谷歌旗下的 DeepMind 创造了 AlphaGo,在 2016 年击败了世界顶级棋手之一。然后他们继续前进,建造了 AlphaGo Zero,以 100 比 0 击败了它的前身。AlphaGo 是围绕人类经验设计的,Zero 完全通过自我对弈掌握了围棋。

尽管棋盘游戏并不总是反映真实世界的决定。他们是回合制的,所以在变化的环境中做决定没有压力。此外,在棋盘游戏中,人工智能拥有关于环境的完整信息。没有基于未知因素的猜测或冒险。

视频游戏《星际争霸》成为人工智能研究的下一个“重大挑战”。在星际争霸中获胜需要玩家平衡短期和长期目标。它还要求适应意外情况的能力。2018 年末 DeepMind 的 AlphaStar 是第一个在这场比赛中击败顶级职业选手的 AI。

接下来,在 2019 年 7 月,由脸书和卡耐基梅隆大学研究人员组成的团队构建了一个名为 Pluribus 的人工智能。Pluribus 在 6 人扑克游戏中击败了顶级职业玩家,表明了人工智能研究的又一次突破。这场胜利的不同之处在于人工智能学习如何虚张声势的能力——这种技能被认为是人类特有的。此外,Pluribus 在笔记本电脑上运行,与深蓝的超级计算机相距甚远。

Photo by Michał Parzuchowski on Unsplash

Big Tech 了解游戏人工智能的商业潜力

那么,为什么像 IBM、谷歌和脸书这样的公司在开发游戏人工智能上投入如此多的时间和金钱呢?财富注:

“Pluribus 的发展……对商业世界有着潜在的影响,就像在扑克中一样,人们需要在巨大的不确定性中做出战略选择,而且结果往往不是零和的。”

为 Pluribus 提供动力的相同 AI 可能在现实世界的战略决策中胜过人类。例如,政治谈判和合同投标与扑克有许多相似之处。他们的共同点是,AI 要冒险,要为长期收益做出短期牺牲。

DeepMind 应用 AlphaGo Zero 技术提高英国电网效率。它应用同样的算法来降低谷歌数据中心的电力成本。

Big Tech 明白,游戏人工智能在现实世界的应用中具有巨大的潜在价值。在复杂的决策中帮助人类是一个明显的高价值应用。为什么?因为许多公司仍然依赖有缺陷的人为分析来做出高风险决策。

决定质量…还是不?人类决策分析中的缺陷

我们大部分职业生涯都在能源行业工作。这个行业的决策几乎总是非常复杂。决策者经常面临许多选择、不确定性、风险、意见和价值驱动因素。而做出错误决定的后果往往非常高。

因此,为了帮助决策者,该行业采用了一种工具来评估决策的质量。决策质量框架是一种分析决策的结构化方法。它是在 60 年代发展起来的,可以认为它就像一份清单,列出了导致决策的所有方面。

有这样一个清单是很好的,但是如果我们用不良或不完整的输入填充它,那么它的用处是有限的。我们经常依赖缓慢、迭代和手动的工作流。我们的工作流程阻止我们探索完整的选项空间。它们限制了我们对风险和价值权衡的理解。我们通常有一个过时的工具集,而且更多的时候,我们引入了各种类型的偏见,时间不够了。

让我们看一个例子。

现实世界中有缺陷的决策

假设你负责一个炼油厂的维护。您面临着 50 项需要安排的独立维护活动。任何时候只能执行一个。这为 10⁶⁴的规划团队提供了不同的排列方式。每项活动在安全和生产关键程度方面都有不同的优先级。有些活动需要专业技能,动员成本很高。更糟糕的是,你正面临持续的检查。这些可能会导致优先级的改变或额外的日常维护活动。这关系到什么?次优规划可能会导致重大的安全风险、更高的成本或不必要的延期。对于一个每天产生数百万美元收入的工厂来说,这是一件大事。

大多数工业资产的维护范围包括 50 多项活动。排列的数量很容易超过围棋中可能的棋盘组合。然而,您的规划团队拥有的最复杂的工具是 Excel 电子表格。

source: xkcd

所以作为一名维护经理,你的工作就是决定最佳的维护策略。遵循决策质量原则,您的目标是探索替代方案。您希望了解安全性、成本和延期之间的权衡。然而,从你的规划团队那里问这个问题是不可能的——他们并没有准备好给出这些答案。

那你是做什么的?你依赖规划者的直觉和经验(以及偏见)。每个人都知道由此产生的计划是次优的,但这是可以接受的。没人知道如何改进— 因为没人知道什么是好的样子

围绕新技术重新思考工作

许多公司仍然依赖与 80 年代相同的工具和流程来支持复杂的决策。Excel 仍然是支持决策的主要工具。正如汤姆·古德温 写的:

“尽管我们谈论人工智能抢走了工作,但现实是,大约 10 年前,几乎所有主要使用 Excel 的工作都可能被初级软件取代或增强。问题是,我们将技术添加到旧流程中,而不是围绕新技术重新思考工作应该是什么。”

想象一下,如果围绕最新技术重新设计 T2,工作会有多么不同。那将是多么令人满意,有趣和有趣。团队将有更多的时间进行战略思考。他们将能够测试权衡,并真正帮助决策。决策会有更高的质量,计划会产生更多的价值吗?当然——而且经常是逐步改进。

这对你意味着什么?挑战现状。

假设你今天开了一家新公司。你需要好的计划来做战略决策。你也知道你的规划团队面临的排列比宇宙中的原子还要多。你会给他们一个 Excel 电子表格作为他们最好的工具吗?或者,你会选择更复杂的东西来帮助你做决定吗?

我们建议您将最复杂的业务问题带到绘图板上。给自己一些思考的空间。挑战自己如何从根本上重新设计和改进底层流程。并围绕最新技术重新设计它们。

Image by mohamed Hassan from Pixabay

如果大科技正在使用游戏人工智能来做出更好的决策,为什么你不会呢?

本文是一个系列的介绍。在下一篇文章中,我们将分享一个游戏人工智能支持商业决策的案例研究。商业决策在很多方面都像复杂的游戏。同样的技术可以提高决策速度和质量。

当然,在组织的各个层面都会有变革的阻力。因此,我们也想谈谈变革管理。对“裁员”的恐惧会出现在许多专业人士的脑海中。再次引用凯西·科兹尔科夫的话:

“…如果你认为人工智能让人类出局了,那就再想想吧!所有技术都是其创造者的反映,大规模运行的系统会放大人类的缺点,这就是为什么发展决策智能技能对于负责任的人工智能领导如此必要的一个原因。”

大多数复杂的决策没有数学上的最优解。风险与回报之间的权衡常常是选择的驱动力。经验、引导和直觉将继续在决策中发挥作用。人类将需要保持控制。然而,正确的人工智能可以帮助揭示完整的选项空间。它能把不同的意见转化为可供选择的方案。它可以量化这些权衡。

由于游戏在推动人工智能研究方面的作用,人工智能已经可用。

我们很想听听你的看法。请随时联系 info@whitespaceenergy.eu 或在 LinkedIn 上发表评论。

Photo by Josh Couch on Unsplash

如何在 Python 中使用 ggplot2

原文:https://towardsdatascience.com/how-to-use-ggplot2-in-python-74ab8adec129?source=collection_archive---------3-----------------------

Python 的图形语法

介绍

由于严格实现了图形的语法,ggplot2 提供了一种非常直观和一致的方式来绘制数据。ggplot2 的绘图方法不仅确保每个图包含某些基本元素,而且还在很大程度上简化了代码的可读性。

但是,如果您经常使用 Python,那么实现图形的语法会非常具有挑战性,因为在流行的绘图库中缺乏标准化的语法,如 matplotlib 或 seaborn。如果你仍然想利用图形的语法,那么 Python 包 plotnine 为你提供了另一种选择。

图形的语法

如果您不熟悉图形的语法,这里有一个快速概述:

Main Components of the Grammar of Graphics

正如您所看到的,从数据开始,有几个组件组成了图形的语法。在确定您想要可视化的数据之后,您必须指定您感兴趣的变量。例如,您可能希望在 x 轴上显示一个变量,在 y 轴上显示另一个变量。第三,你必须定义你想要使用什么类型的几何对象(简称 geom)。这可以是从条形图到散点图或任何其他现有的绘图类型。

前三个部分是强制性的。没有数据,就没什么好出图的。如果没有轴定义,也没有什么可绘制的。最后,如果没有定义一个几何对象,你只会看到一个空的坐标系。构成图形语法的其余组件是可选的,可以被实现来改善可视化。面是指子图的规格,也就是说,在单独的图中将数据中的几个变量一个接一个地绘制出来。统计转换主要指在图中包含汇总统计数据,如中位数或百分位数。坐标描述了可供您使用的不同坐标系。最常用和默认的坐标系是笛卡尔坐标系。根据您想要绘制的数据结构,较少使用的坐标系(如极坐标系统)可能会提供更好的数据可视化方式。最后,主题提供了各种选项来设计绘图的所有非数据元素,如图例、背景或注释。

虽然有许多可视化图形语法的方法,但我特别喜欢我在上面创建的一个,因为它暗示了这些层的可加性以及它们建立在彼此之上的事实。如果您曾经使用过 ggplot2,您会对其语法中的“+”很熟悉,它象征着与上述相同的思想。

普洛特宁

plotnine 是一个 Python 包,允许您使用类似 ggplot2 的代码来实现图形语法。通过这样做,就像在 ggplot2 中一样,您能够专门将数据映射到组成可视化的可视对象。这使您能够提高代码的可读性和结构。虽然您可以将 matplotlib 的样式设置为 ggplot,但是您不能像在 ggplot2 中那样在 matplotlib 中实现图形语法。

装置

在开始之前,你必须安装 plotnine。和往常一样,这样做有两个主要选项:pip 和 conda。

测绘

安装 plotnine 后,您可以使用图形语法开始绘图。让我们从构建一个非常简单的情节开始,只使用三个必要的组件:数据、美学和几何对象。

Building a plot using the grammar of graphics

可以看到,语法非常类似于 ggplot2。首先,我们指定数据源。在我们的例子中,我们使用的数据是经典的 mpg 数据集。接下来,我们定义变量“class”将显示在 x 轴上。最后,我们说我们希望使用一个大小为 20 的条形图来可视化我们的数据。让我们看看完整的代码和结果图:

上面的代码将产生以下输出:

虽然这是一个好的开始,但看起来还不是很好。让我们用图形语法的其他成分来美化我们的情节。

例如,我们可以使用 coord_flip() 翻转轴,并使用 labs() 定制绘图和轴标题,以改进我们的绘图。使用上面的代码块,我们的绘图将如下所示:

绘制多维数据

除了基本的绘图之外,您还可以做几乎所有在 ggplot2 中可以做的事情,比如绘制多维数据。如果您希望可视化三个变量之间的关系,您可以为二维图增加美感:

颜色添加到美学中将促使 plotnine 在其 x 轴上使用 displ (发动机排量,以升为单位)并在其 y 轴上使用 hwy (公路里程/加仑)显示二维图,并根据变量 class 对数据进行着色。我们还将几何对象切换到 geom_point() ,这将给我们一个散点图而不是条形图。让我们来看看那会是什么样子:

结论

如您所见,plotnine 为您提供了利用 Python 中图形语法的能力。这增加了代码的可读性,并允许您专门将部分数据映射到可视对象。如果你已经熟悉了 ggplot2,那么你就不需要学习任何新的东西来掌握 plotnine。如果没有,这里有一个到 ggplot2 网站的链接,在这里你可以找到更多关于图形语法和所有类型的几何对象的信息。

如何使用 Google 语音转文本 API 转录长音频文件?

原文:https://towardsdatascience.com/how-to-use-google-speech-to-text-api-to-transcribe-long-audio-files-1c886f4eb3e9?source=collection_archive---------0-----------------------

Credit: Pixabay

语音识别是一项有趣的任务。现在市场上有很多 API 资源,这使得用户更容易选择其中一个。然而,当涉及到音频文件,尤其是呼叫中心数据时,这项任务就变得没什么挑战性了。让我们假设一次呼叫中心的谈话大约需要 10 分钟。对于这种场景,市场上只有少数可用的 API 资源可以处理这种类型的数据(谷歌、亚马逊、 IBM 、微软、 Nuance 、 Rev.ai 、开源 Wavenet 、开源 CMU Sphinx )。在本文中,我们将详细讨论 Google 语音转文本 API。

谷歌语音转文本 API

Google 语音转文本有三种基于音频内容的 API 请求。

Credit: GCP

同步请求

音频文件内容应该大约为 1 分钟,以便进行同步请求。在这种类型的请求中,用户不必将数据上传到 Google cloud。这为用户提供了将音频文件存储在他们的本地计算机或服务器中并引用 API 来获取文本的灵活性。

异步请求

音频文件内容应该约为 480 分钟(8 小时)。在这种类型的请求,用户必须上传他们的数据到谷歌云。这正是我们将在本文中讨论的内容。

流式请求

它适用于用户直接对着麦克风说话并需要转录的流数据。这种类型的请求适合聊天机器人。同样,对于这种类型的请求,流数据应该大约是一分钟。

初始设置

在开始之前,您需要做一些初始设置。请点击下面的链接完成设置。

[## 快速入门:使用客户端库|云语音转文本 API | Google Cloud

setvar launch _ type % } API { % endsetvar % } { % setvar launch _ name % }云语音转文本 API{% endsetvar %} {% setvar…

cloud.google.com](https://cloud.google.com/speech-to-text/docs/quickstart-client-libraries)

我还写了一篇文章详细解释了第一步。

[## 使用 Python 创建自己的基于语音的应用程序

基于语音的设备/应用正在大量增长。今天,有谷歌助手,Alexa 把我们的声音作为…

medium.com](https://medium.com/@sundarstyles89/create-your-own-google-assistant-voice-based-assistant-using-python-94b577d724f9)

一旦创建了 API 客户机,下一步就是创建一个存储桶。您可以使用下面的链接创建一个存储桶。对于这个项目,我将这个桶命名为“callsaudiofiles”。

[## 谷歌云平台

Google 云平台让您可以在同一基础设施上构建、部署和扩展应用程序、网站和服务…

console.cloud.google.com](https://console.cloud.google.com/storage/)

让我们把一些语音转换成文本

步骤 1:导入必要的包

这里的‘file path’变量包含了音频文件在你的本地计算机中的位置。因此,您可以在路径中存储多个音频文件,它仍然会工作。在‘输出文件路径’中,所有由谷歌云创建的文本都将被存储在你的本地计算机中。此外,在‘bucket name’变量中提供上一步中创建的存储桶名称。你不需要把你的文件上传到谷歌存储器。我们将在后面的部分讨论如何上传到 Google storage。

步骤 2:音频文件编码

谷歌语音到文本处理一些特定类型的音频编码。你可以在下面的链接中详细阅读。

[## 音频编码简介|云语音转文本 API | Google Cloud

谷歌云提供安全、开放、智能和变革性的工具,帮助企业实现现代化,以适应当今的…

cloud.google.com](https://cloud.google.com/speech-to-text/docs/encoding)

Credit: GCP

这限制了我们在使用 Google 语音转文本 API 之前转换不同格式的音频文件。

我在下面提供了一个将 mp3 文件转换成 wav 文件的示例代码。

步骤 3:音频文件规格

另一个限制是 API 不支持立体声音频文件。因此,用户需要在使用 API 之前将立体声文件转换为单声道文件。此外,用户必须提供文件的音频帧速率。下面的代码可以帮助你找出任何的。wav' 音频文件。

第四步:上传文件到谷歌存储

正如我们之前讨论的,为了执行异步请求,文件应该上传到 google cloud。下面的代码将完成同样的任务。

第五步:删除谷歌存储中的文件

语音转文本操作完成后,文件就可以从 Google cloud 中删除了。下面的代码可以用来从谷歌云中删除文件。

第六步:转录

最后,下面的转录函数执行所有必要的操作来获得最终的抄本。它调用前面步骤中描述的其他函数,并将抄本存储在变量‘抄本’中。

这里需要注意的一点是超时选项。这是转录功能将主动转录当前音频文件的秒数。如果音频文件秒数大于此处提供的数字,您可以将此设置调整为一个较大的数字。

第七步:写成绩单

语音到文本的操作完成后,您需要将最终的文本存储在一个文件中,下面的代码可以用来执行同样的操作。

第八步:执行你的代码。等着看笔录吧

下面的代码开始执行。在文件路径中可以有多个音频文件。它按顺序执行每个文件。

生成的最终文本如下所示。

I was on the other roommate had to leave before I got half of them by him. I guess no way to get a hold back to you. Alright. Yeah, kinda I mean like what? What are you I have to I have to play with the other guys. So yeah, go ahead and I with me I can let my people like the one that you were calling me, but I go ahead and do it cuz I'm sure he's not work for lunch, but they just had them or is it 10 o'clock? I want to go ahead and get out with me. Call me. I understand. They probably to talk about Mom and I need to call back or maybe I can just figured after taxes advertises. It's 110 feet in so I guess alright. Well shoot let me know and then maybe I'll just minus the weather. Okay. Well so much for your help. Like I said, no problem. Alright, you have a good day. Okay. Bye.

如果我需要在我的成绩单中分开发言者,该怎么办?

说话人二进制化是在音频文件中区分说话人的过程。事实证明,你可以使用谷歌语音到文本 API 来执行说话人二进制化。Google 在扬声器二进制化后生成的最终文本如下所示。

speaker 1: I was on the other roommate had to leave before I got half of them by him I guess no way to get a hold back to you alright
speaker 2: yeah kinda I mean like what what are you I
speaker 1: have to I have to play with the other guys so yeah go ahead and I with me I can let my people like the one that you were calling me but I go ahead and do it cuz I'm sure he's not work for lunch but they just had them or is it 10 o'clock I want to go ahead and get out with me
speaker 2: call me I understand
speaker 1: they probably to talk about Mom and I need to call back or maybe I can just figured after taxes
speaker 2: advertises it's 110 feet in so I
speaker 1: guess alright well shoot let me know and then maybe I'll just minus the weather okay well so much for your help like I said no problem alright you have a good day okay bye

为此,您需要对前面描述的代码进行一些更改。让我们从包导入开始。

现在,我们来谈谈转录部分的变化。

这两个项目的完整代码可以在 Github 链接中找到。

玩得开心!

如何通过 Maingear 的新数据科学 PC 使用 NVIDIA GPUs 进行机器学习

原文:https://towardsdatascience.com/how-to-use-gpus-for-machine-learning-with-the-new-nvidia-data-science-workstation-64ef37460fa0?source=collection_archive---------3-----------------------

是的,你没看错:是机器学习,不是深度学习

深度学习使我们能够执行许多类似人类的任务,但是如果你是一名数据科学家,并且你不在 T2 的 FAANG T3 公司工作(或者如果你没有开发下一个人工智能初创公司),你很可能仍然使用好的和旧的(好的,也许不是 T4 的 T5 旧的)T6 机器学习 T7 来执行你的日常任务。

深度学习的一个特点是计算量非常大,所以所有主要的 DL 库都利用 GPU 来提高处理速度。但是,如果你曾经因为不从事深度学习而感到被排除在派对之外,那种日子已经过去了:现在有了 RAPIDS 库套件,我们可以完全在 GPU 上运行我们的数据科学和分析管道

在本文中,我们将讨论其中的一些 RAPIDS 库,并进一步了解 Maingear 的新型数据科学 PC。

为什么人们会使用 GPU 呢?

一般来说,GPU 速度很快,因为它们有高带宽存储器和执行浮点运算的硬件,其速度明显高于传统 CPUs】。GPU 的主要任务是执行渲染 3D 计算机图形所需的计算。

但是在 2007 年,NVIDIA 创造了 CUDA。CUDA 是一个并行计算平台,为开发者提供 API,允许他们构建能够利用 GPU 进行通用处理的工具。

GPU 已经发展成为高度并行的多核系统,可以非常高效地处理大块数据。在并行处理大块数据的情况下,这种设计比通用中央处理器(CPU)更有效

处理大块数据基本上是机器学习做的事情,所以 GPU 对于 ML 任务来说就派上用场了。TensorFlow 和 Pytorch 是已经使用 GPU 的库的例子。现在有了 RAPIDS 库套件,我们还可以操纵数据帧,并在 GPU 上运行机器学习算法

湍流

RAPIDS 是一套开源库,其中集成了流行的数据科学库和工作流来加速机器学习【3】。

一些 RAPIDS 项目包括 cuDF ,一个类似熊猫的数据帧操作库; cuML ,一个机器学习库的集合,将提供 sciKit-learn 中可用算法的 GPU 版本;cuGraph,一个类似 NetworkX 的加速图形分析库[4]。

Pandas 和 sciKit-learn 是两个主要的数据科学库,所以让我们了解更多关于 cuDFcuML 的知识。

cuDF:数据帧操作

cuDF 为数据帧操作提供了一个类似 pandas 的 API,所以如果你知道如何使用 pandas,你就已经知道如何使用 cuDF。如果你想在多个 GPU 上分布你的工作流,还有 Dask-cuDF 库。

我们可以像熊猫一样创造系列和数据框架:

import numpy as np
**import cudf**s = **cudf.Series(**[1,2,3,None,4]**)**df = **cudf.DataFrame(**[('a', list(range(20))),('b', list(reversed(range(20)))),('c', list(range(20)))]**)**

也可以将 pandas 数据帧转换成 cuDF 数据帧(但是不建议这样做):

import pandas as pd
**import cudf**df = pd.DataFrame({'a': [0, 1, 2, 3],'b': [0.1, 0.2, None, 0.3]})
gdf = **cudf.DataFrame.from_pandas(**df**)**

我们也可以做相反的事情,将 cuDF 数据帧转换成 pandas 数据帧。

import cudfdf = **cudf.DataFrame(**[('a', list(range(20))),('b', list(reversed(range(20)))),('c', list(range(20)))]**)**pandas_df = df.head().**to_pandas()**

或者转换成 numpy 数组:

import cudfdf = cudf.DataFrame([('a', list(range(20))),('b', list(reversed(range(20)))),('c', list(range(20)))])df.**as_matrix()**df['a'].**to_array()**

我们对数据帧所做的其他事情(查看数据、排序、选择、处理缺失值、处理 csv 文件等等)都是一样的:

import cudfdf = **cudf.DataFrame**([('a', list(range(20))),('b', list(reversed(range(20)))),('c', list(range(20)))]**)**df.**head**(2)
df.**sort_values**(by='b')
df['a']
df.**loc**[2:5, ['a', 'b']]s = cudf.Series([1,2,3,None,4])s.fillna(999)df = cudf.**read_csv(**'example_output/foo.csv'**)** df.**to_csv(**'example_output/foo.csv', index=False**)**

关于性能,仅举一个例子,用熊猫加载一个 1gb 的 csv 文件需要 13 秒,用 cuDF 加载需要 2.53 秒。

Loading a 1gb csv 5X faster with cuDF

cuML:机器学习算法

cuML 与其他 RAPIDS 项目集成实现了机器学习算法数学原语函数。在大多数情况下,cuML 的 Python API 与来自 sciKit-learn 的 API 相匹配。该项目仍然有一些限制(例如,目前 cuML RandomForestClassifier 的实例不能被腌制),但他们有一个短暂的 6 周发布时间表,所以他们总是添加新的功能。

除了其他工具之外,还有对回归、分类、聚类和维度缩减算法的实现。该 API 确实与 sciKit API 非常一致:

import cudf
import numpy as npfrom **cuml.linear_model** import **LogisticRegression**X = cudf.DataFrame()X['col1'] = np.array([1,1,2,2], dtype = np.float32)
X['col2'] = np.array([1,2,2,3], dtype = np.float32)y = cudf.Series( np.array([0.0, 0.0, 1.0, 1.0], dtype = np.float32) )# trainingreg = **LogisticRegression()**
reg.**fit(**X,y**)**print("Coefficients:")
print(reg.coef_.copy_to_host())
print("Intercept:")
print(reg.intercept_.copy_to_host())# making predictionsX_new = cudf.DataFrame()X_new['col1'] = np.array([1,5], dtype = np.float32)
X_new['col2'] = np.array([2,5], dtype = np.float32)preds = reg.**predict(**X_new**)**print("Predictions:")
print(preds)

Maingear 的数据科学电脑

这些都很棒,但是我们如何使用这些工具呢?嗯,首先你需要弄一个 NVIDIA GPU 卡 兼容 RAPIDS 。如果你不想花时间找出硬件规格的最佳选择,NVIDIA 将发布数据科学 PC

PC 自带软件栈,优化运行所有这些用于机器学习和深度学习的库。它带有 Ubuntu 18.04,你可以使用来自 NVIDIA GPU Cloud 的 docker 容器,或者使用原生的 conda 环境。PC 最大的好处之一就是你可以完全安装所有的库和软件。如果你曾经不得不在 Linux 发行版上安装 NVIDIA 驱动程序,或者不得不从源代码安装 TensorFlow,你就会知道这有多梦幻。这些是系统规格:

  • GPU

配备 24 GB GPU 内存的 NVIDIA Titan RTX 双路 NVIDIA Titan RTX 通过 NVIDIA NVLink 连接,提供 48 GB GPU 内存

  • CPU

英特尔酷睿 i7 类 CPU 更高

  • 系统内存

最少 48 GB DDR4 系统内存用于单 GPU 配置和最少 48 GB DDR4 系统内存用于双 GPU 配置

  • 磁盘

最少 1 TB 固态硬盘

Maingear VYBE PRO 数据科学 PC 配备了多达两个双 NVIDIA TITAN RTX 24GB 卡,每台 PC 都是手工组装的

A VYBE PRO PC from Maingear with two NVIDIA TITAN RTX cards (this thing is so beautiful I was afraid to turn it on)

使用具有 4,000,000 行和 1000 列的数据集在 VYBER PRO PC 上训练 XGBoost 模型(此数据帧使用大约。15 GB 内存)在 CPU 上占用 1min 46s(内存增量为73325 MiB)在 GPU**上仅 21.2s(内存增量为 520 MiB )。**

Training a XGBoost model 5X faster with GPUs

结论

对于数据科学,我们总是需要探索和尝试新事物。在使我们的工作流程变得困难的其他软件工程挑战中,计算我们的数据所需的大小和时间是两个瓶颈,它们阻止我们在运行我们的实验时达到流状态。拥有一台电脑和工具可以改善这一点,可以真正加快我们的工作,帮助我们更快地发现数据中有趣的模式。想象一下,获取一个 40 GB 的 csv 文件,然后简单地将其加载到内存中,看看它是关于什么的。

RAPIDS 工具为机器学习工程师带来了深度学习工程师已经熟悉的 GPU 处理速度提升。为了制造使用机器学习的产品,我们需要迭代并确保我们有可靠的端到端管道,使用 GPU 来执行它们将有望提高项目的输出。

参考

[1]https://graphics . Stanford . edu/papers/gpumatrixmult/gpumatrixmult . pdf

https://en.wikipedia.org/wiki/CUDA

[3]https://NVIDIA news . NVIDIA . com/news/NVIDIA-introduces-rapids-open-source-GPU-acceleration-platform-for-large-scale-data-analytics-and-machine-learning

https://rapids.ai/about.html

[5]https://rapidsai . github . io/projects/cuDF/en/0 . 10 . 0/10min . html # When-to-use-cuDF-and-Dask-cuDF

如何使用 H2O AutoML 进行卡纳达语 MNIST 数字分类

原文:https://towardsdatascience.com/how-to-use-h2o-automl-for-kannada-mnist-digits-classification-c0bb21ee3774?source=collection_archive---------27-----------------------

Kaggle Kannada MNIST

卡纳达语 MNIST 数据集是另一个 MNIST 类型的卡纳达语(印度)的数字数据集。数据集管理的所有细节已在题为:“卡纳达语-MNIST:一个新的卡纳达语手写数字数据集”的论文中捕获。作者维奈乌代帕布。作者的 github repo 可以在这里找到。

这篇文章的目的是演示如何使用h2o.aiautoml函数快速获得(更好的)基线。这也证明了一点,这些automl工具如何帮助机器学习模型构建过程民主化。

78%的数据营折扣

加载所需的库

  • h2o -用于机器学习
  • tidyverse -用于数据操作
library(h2o)
library(tidyverse)

正在初始化 H2O 集群

h2o::h2o.init()

读取输入文件(数据)

train <- read_csv("/Kannada-MNIST/train.csv")
test <- read_csv("/Kannada-MNIST/test.csv")
valid <- read_csv("/Kannada-MNIST/Dig-MNIST.csv")
submission <- read_csv("/Kannada-MNIST//sample_submission.csv")

检查数据框的形状/尺寸

dim(train)

784 个像素值+ 1 个表示数字的标签。

标签计数

train  %>% count(label)

可视化卡纳达语 MNIST 数字

# visualize the digits
par(mfcol=c(6,6))par(mar=c(0, 0, 3, 0), xaxs='i', yaxs='i')for (idx in 1:36) { im<-matrix((train[idx,2:ncol(train)]), nrow=28, ncol=28)im_numbers <- apply(im, 2, as.numeric)image(1:28, 1:28, im_numbers, col=gray((0:255)/255), main=paste(train$label[idx]))
}

将 R 数据帧转换成 H2O 函数所需的 H2O 对象

train_h <- as.h2o(train)
test_h <- as.h2o(test)
valid_h <- as.h2o(valid)

将我们的数字目标变量转换为算法执行分类的因子

train_h$label <- as.factor(train_h$label)
valid_h$label <- as.factor(valid_h$label)

解释变量和响应变量

x <- names(train)[-1]
y <- 'label'

行动中的汽车

aml <- h2o::h2o.automl(x = x, y = y,training_frame = train_h,nfolds = 3,leaderboard_frame = valid_h,max_runtime_secs = 1000)

nfolds表示交叉验证的折叠次数,而max_runtime_secs表示 AutoML 过程可以持续的最大时间。

AutoML 排行榜

排行榜是 AutoML 列出表现最佳车型的地方。

aml@leaderboard

预测和提交

pred <- h2o.predict(aml, test_h) submission$label <- as.vector(pred$predict)#write_csv(submission, "submission_automl.csv")

提交(为 Kaggle)

write_csv(submission, "submission_automl.csv")

这是目前 Kaggle 上的一个游乐场比赛。所以,这个提交文件可以提交给这个比赛。根据上述参数,提交的内容在公共排行榜上的得分为0.907200.90在 MNIST 分类中得分接近于零,但我希望这段代码片段可以作为任何试图开始使用 AutoML 的人的快速入门模板。

参考

  • 卡纳达 MNIST H2O 汽车在 R-Kaggle 笔记本
  • 卡纳达语-MNIST 卡格尔语比赛
  • H2O 汽车文件

此文最初发表于

如果你喜欢这个,请订阅我的 语言无关的数据科学时事通讯 并分享给你的朋友!

如何在谷歌云虚拟机上使用 Jupyter

原文:https://towardsdatascience.com/how-to-use-jupyter-on-a-google-cloud-vm-5ba1b473f4c2?source=collection_archive---------8-----------------------

谷歌云平台上 AI 平台笔记本的菜谱

注意:本文中的方法仍然有效,但是我建议您现在使用笔记本 API。做:

gcloud beta 笔记本-帮助

在 GCP 上启动笔记本最简单的方法是从 GCP 控制台浏览工作流程。进入 AI 平台,点击笔记本实例。您可以从用户界面创建新实例:

Create a new notebook instance from the UI

实例启动后,您可以单击一个链接来打开 JupyterLab:

Click on the blue link to open Jupyter Lab. Once you are done working for the day, Stop the VM. Then, restart. I tend to have different notebook instances for different projects.

当实例启动时,它有一个持久磁盘。那个磁盘可以装你的笔记本。您可以停止并重新启动虚拟机(从 GCP web 控制台),而不会丢失这些笔记本。

请注意,您可以从用户界面将 GPU 附加到笔记本实例:

Attaching a GPU to a notebook instance

尽情享受吧!

本文收集了我使用笔记本实例的一些“诀窍”。

A.如何编写创建笔记本实例的脚本

该实例是一个计算引擎映像,因此如果您想要编写脚本、定制机器、更改防火墙规则等。您可以使用计算引擎功能。笔记本实例是一个深度学习虚拟机,这是一系列图像,提供了一种在谷歌云上启动带有/不带有 GPU 的虚拟机的便捷方式。它已经安装了 Jupyter Lab,你不需要代理或者 ssh 就可以访问它。

A1。使用 gcloud 启动深度学习虚拟机

最简单的方法是指定一个图像族(参见文档了解可用的图像族)。例如,您可以使用以下方式获取 tensorflow-gpu 系列中附加了 P100 GPU 的最新图像:

IMAGE=**--image-family=tf-latest-gpu**
INSTANCE_NAME=dlvm
GCP_[LOGIN_NAME=**google-cloud-customer@gmail.com**](mailto:MAIL=google-cloud-customer@gmail.com)  # CHANGE THISgcloud config set compute/zone **us-central1-a**  # CHANGE THISgcloud compute instances create ${INSTANCE_NAME} \--machine-type=**n1-standard-8** \--scopes=[https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email](https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email) \--min-cpu-platform="Intel Skylake" \${IMAGE} \--image-project=deeplearning-platform-release \--boot-disk-size=100GB \--boot-disk-type=pd-ssd \ --accelerator=**type=nvidia-tesla-p100**,count=1 \--boot-disk-device-name=${INSTANCE_NAME} \--maintenance-policy=TERMINATE --restart-on-failure \--metadata="proxy-user-mail=${GCP_LOGIN_NAME}**,install-nvidia-driver=True**"

A2。获取 Jupyter 实验室的网址

用于访问 Jupyter Lab 的 URL 是您刚刚启动的虚拟机的元数据的一部分。您可以通过以下方式获得:

gcloud compute instances describe ${INSTANCE_NAME} | grep dot-datalab-vm

下面是一个脚本,它将执行第 1 步和第 2 步,一直等到 Jupyter 笔记本服务器启动:

#!/bin/bashIMAGE=--image-family=tf-latest-cpu
INSTANCE_NAME=dlvm
GCP_[LOGIN_NAME](mailto:MAIL=google-cloud-customer@gmail.com)[=google-cloud-customer@gmail.com](mailto:MAIL=vlakshmanan@google.com)  # CHANGE THISgcloud config set compute/zone **us-central1-a**  # CHANGE THISecho "Launching $INSTANCE_NAME"
gcloud compute instances create ${INSTANCE_NAME} \--machine-type=n1-standard-2 \--scopes=[https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email](https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email) \${IMAGE} \--image-project=deeplearning-platform-release \--boot-disk-device-name=${INSTANCE_NAME} \--metadata="proxy-user-mail=${GCP_[LOGIN_NAME](mailto:MAIL=google-cloud-customer@gmail.com)}"echo "Looking for Jupyter URL on $INSTANCE_NAME"
while true; doproxy=$(gcloud compute instances describe ${INSTANCE_NAME} 2> /dev/null | grep dot-datalab-vm)if [ -z "$proxy" ]thenecho -n "."sleep 1elseecho "done!"echo "$proxy"breakfi
done

A3。在 web 浏览器中访问 URL

只需导航到那个网址,你就会进入 JupyterLab。

B.如何在笔记本实例上使用 Git

B1。Git 交互式克隆存储库

单击左侧窗格中图标带的最后一个图标,您将能够 git 克隆一个存储库。用我书里的那个:

https://github.com/GoogleCloudPlatform/data-science-on-gcp

Running a Jupyter notebook on a cloud VM without any ssh tunnels or proxies

导航到 updates/cloudml 并打开 flights_model.ipynb。您应该能够浏览笔记本。

你也可以打开一个终端,使用 git 克隆、git 检验、git 推送等等。我倾向于发现它比使用内置的 Git UI 更容易。但是您的里程可能会有所不同!

C.如何指定启动脚本

您可以指定一组在 Jupyter 启动后运行的操作。这些将以 root 用户身份运行。

IMAGE=**--image-family=tf-latest-gpu**
INSTANCE_NAME=dlvm
GCP_[LOGIN_NAME=**google-cloud-customer@gmail.com**](mailto:MAIL=google-cloud-customer@gmail.com)  # CHANGE THIS
STARTUP_SCRIPT="git clone [https://github.com/GoogleCloudPlatform/data-science-on-gcp](https://github.com/GoogleCloudPlatform/data-science-on-gcp)"gcloud config set compute/zone **us-central1-a**  # CHANGE THISgcloud compute instances create ${INSTANCE_NAME} \--machine-type=**n1-standard-8** \--scopes=[https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email](https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email) \--min-cpu-platform="Intel Skylake" \${IMAGE} \--image-project=deeplearning-platform-release \--boot-disk-size=100GB \--boot-disk-type=pd-ssd \ --accelerator=type=nvidia-tesla-p100,count=1 \--boot-disk-device-name=${INSTANCE_NAME} \--maintenance-policy=TERMINATE --restart-on-failure \--metadata="proxy-user-mail=${GCP_LOGIN_NAME}**,**install-nvidia-driver=True,**startup-script=${STARTUP_SCRIPT}**"

D.如何安排笔记本

D1。转移到生产时,使用映像,而不是映像系列

一般来说,使用映像系列方法进行开发(这样您就可以一直使用最新的东西进行开发),但是一旦您将产品化,就要使用特定的映像。您希望在产品中固定一个特定映像的原因是,您希望在一个已经实际测试过代码的版本上运行。

获取图像列表并找到您正在使用的图像(您在上面指定的图像系列中的最新图像):

gcloud compute images list \--project deeplearning-platform-release \--no-standard-images

然后,在创建深度学习虚拟机时指定它(您可能想要更改的行以粗体显示):

IMAGE=--image=**tf-latest-cpu-20190125b2** # CHANGE
INSTANCE_NAME=**dlvm**
GCP_[LOGIN_NAME](mailto:MAIL=google-cloud-customer@gmail.com)[=**google-cloud-customer@gmail.com**](mailto:MAIL=vlakshmanan@google.com)  # CHANGE THIS
ZONE="us-central1-b"  # CHANGEgcloud compute instances create ${INSTANCE_NAME} \--machine-type=**n1-standard-8 \** --zone=$ZONE \--scopes=[https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email](https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email) \--min-cpu-platform="Intel Skylake" \${IMAGE} \--image-project=deeplearning-platform-release \--boot-disk-size=**100GB \**--boot-disk-type=pd-ssd \--boot-disk-device-name=${INSTANCE_NAME} \--metadata="proxy-user-mail=${GCP_[LOGIN_NAME](mailto:MAIL=google-cloud-customer@gmail.com)}"

D2。使用 papermill 提交计划执行的笔记本

这里的关键点是使用启动脚本启动 papermill,并在 papermill 完成后使用 TERMINATE 退出笔记本虚拟机,而不需要在出现故障时重启。然后,删除该虚拟机。更多详情见这篇博文。

# Compute Engine Instance parameters
IMAGE=--image=tf-latest-gpu-20190125b2 # CHANGE
INSTANCE_NAME=dlvm
ZONE="us-central1-b"  # CHANGE
INSTANCE_TYPE="n1-standard-4"  #CHANGE
# Notebook parameters
GCS_INPUT_NOTEBOOK="gs://my-bucket/input.ipynb"
GCS_OUTPUT_NOTEBOOK="gs://my-bucket/output.ipynb"
GCS_INPUT_PARAMS="gs://my-bucket/params.yaml" # Optional
**export STARTUP_SCRIPT="**[https://raw.githubusercontent.com/GoogleCloudPlatform/ml-on-gcp/master/dlvm/tools/scripts/notebook_executor.sh](https://raw.githubusercontent.com/GoogleCloudPlatform/ml-on-gcp/master/dlvm/tools/scripts/notebook_executor.sh)**"**gcloud compute instances create $INSTANCE_NAME \--zone=$ZONE \--image=$IMAGE \--image-project=deeplearning-platform-release \** --maintenance-policy=TERMINATE** \--accelerator='type=nvidia-tesla-t4,count=2' \--machine-type=$INSTANCE_TYPE \--boot-disk-size=100GB \--scopes=https://www.googleapis.com/auth/cloud-platform \--metadata="input_notebook_path=${GCS_INPUT_NOTEBOOK},output_notebook_path=${GCS_OUTPUT_NOTEBOOK},parameters_file=${GCS_INPUT_PARAMS},startup-script-url=$LAUNCHER_SCRIPT,**startup-script=${STARTUP_SCRIPT}**"gcloud --quiet compute instances delete $INSTANCE_NAME --zone $ZONE

E.如何使用 Jupyter 的 TPU

要创建附加到 TPU 的深度学习虚拟机,首先创建深度学习虚拟机,然后创建具有相同 TensorFlow 版本的 TPU:

INSTANCE_NAME=**laktpu**   # CHANGE THIS
GCP_[LOGIN_NAME](mailto:MAIL=google-cloud-customer@gmail.com)[=**google-cloud-customer@gmail.com**](mailto:MAIL=vlakshmanan@google.com)  # CHANGE THISgcloud config set compute/zone **us-central1-a**  # CHANGE THISTPU_NAME=$INSTANCE_NAME
gcloud compute instances create $INSTANCE_NAME \
--machine-type n1-standard-8 \
--image-project deeplearning-platform-release \
--image-family **tf-1-12-cpu** \
--scopes cloud-platform \
--metadata proxy-user-mail="${GCP_[LOGIN_NAME](mailto:MAIL=google-cloud-customer@gmail.com)}",\
startup-script="echo export TPU_NAME=$TPU_NAME > /etc/profile.d/tpu-env.sh"gcloud compute tpus create $TPU_NAME \--network default \--range 10.240.1.0 \--version **1.12**

创建深度学习虚拟机时唯一的区别是,您在启动脚本中指定了 TPU 名称。

F.如何在笔记本电脑中使用最终用户凭据

如果你创建了一个深度学习虚拟机,并且你指定了一个 GCP 登录名(除了生产虚拟机之外,我上面的所有例子都是这样做的),那么只有你(和项目管理员)能够通过 ssh 进入虚拟机。

所有 Jupyter 笔记本都将在一个服务帐户下运行。在大多数情况下,这没问题,但是如果您需要运行服务帐户没有权限执行的操作,您可以通过执行以下操作让 Jupyter 中的代码以您的身份运行:

  • 在启动菜单中,打开一个终端
  • 在终端中,键入:
gcloud auth application-default login
  • 按照提示执行 OAuth2
  • 如有必要,重启 Jupyter 内核

注意:不要使用最终用户凭证,除非您在“单用户模式”下启动机器。

G.如何创建 TF-nightly 虚拟机

在 tf-latest 系列中创建映像使用最新的稳定 TensorFlow 版本。要使用 TF-nightly(例如,这就是如何获得 TensorFlow 2.0-alpha),请使用:

INSTANCE_NAME=**tfnightly**   # CHANGE THIS
GCP_[LOGIN_NAME](mailto:MAIL=google-cloud-customer@gmail.com)[=**google-cloud-customer@gmail.com**](mailto:MAIL=vlakshmanan@google.com)  # CHANGE THIS
ZONE="us-west1-b" # CHANGE THIS
INSTANCE_TYPE="n1-standard-4" # CHANGE THISgcloud compute instances create ${INSTANCE_NAME} \--machine-type=$INSTANCE_TYPE \--zone=$ZONE \--scopes=[https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email](https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/userinfo.email) \--min-cpu-platform="Intel Skylake" \--image-family="**tf-latest-gpu-experimental**" \--image-project=deeplearning-platform-release \--boot-disk-size=100GB \--boot-disk-type=pd-ssd \--accelerator=type=nvidia-tesla-p100,count=1 \--boot-disk-device-name=${INSTANCE_NAME} \--maintenance-policy=TERMINATE --restart-on-failure \--metadata="proxy-user-mail=${GCP_LOGIN_NAME},install-nvidia-driver=True"

H.Jupyter 故障排除

重启 Jupyter: 通常你需要做的就是点击笔记本菜单里的图标重启内核。但是偶尔,你可能会彻底破坏环境,想要重启 Jupyter。为此,转到 GCP 控制台的计算实例部分,并单击与您的笔记本实例对应的 SSH 按钮。在 SSH 窗口中,键入:

sudo service jupyter restart

启动日志:如果 Jupyter 启动失败,或者你没有得到笔记本链接,你可能要查看完整的日志(包括启动日志)。使用以下方式完成:

gcloud compute instances \get-serial-port-output --zone $ZONE $INSTANCE_NAME

一.使用 conda

张量流图像使用 pip,但 PyTorch 图像使用 conda。所以,如果你想使用 conda,PyTorch 图像是一个更好的起点。

J.如何在本地运行笔记本实例

如果您想在本地机器上使用深度学习 VM 容器映像进行开发,可以使用 Docker:

IMAGE_NAME="gcr.io/deeplearning-platform-release/tf-latest-cpu"
docker pull "${IMAGE_NAME}"
docker run -p 127.0.0.1:8080:8080/tcp -v "${HOME}:/home" \"${IMAGE_NAME}"

如果您的本地机器上有一个 GPU,请将映像名称从 tf-latest-cpu 更改为 tf-latest-cu100。


我对这些食谱很感兴趣。如果您对我应该添加的问题/答案有任何建议,请联系我。为了方便起见,这里有一个包含所有代码的要点。

如何通过 SSH 在深度学习平台上远程使用 Jupyter

原文:https://towardsdatascience.com/how-to-use-jupyter-on-your-deep-learning-rig-remotely-with-ssh-cefd78fbfe2c?source=collection_archive---------26-----------------------

当处理多台机器时,将你的文件和硬件分开可能是一件好事,也可能是一件可怕的坏事。我们都遇到过这样的情况,我们需要将工作转移到 USB 闪存驱动器上,以便在旅行时将它们放在笔记本电脑上。最重要的是,你的笔记本电脑也有臭名昭著的

集成显卡

没有我们每天都要访问的文件系统会对我们的性能产生负面影响。对于我们这些喜欢轻薄笔记本电脑、宁愿在沙发上而不是电脑椅上工作的人来说,对远程台式机的渴望可能会更强烈。

我决定用 RedHat 来运行我的 SSH 服务器。RedHat 是非常成熟的,并且是最常运行的服务器发行版之一。

老实说,如果你是 Linux 新手,发行版并不重要,因为 Linux 在整体上是相当一致的。

我不打算回顾安装过程或用户创建过程,因为它们都很简单“你希望它是什么”,并键入答案。

现在我们已经安装了操作系统,我们需要做什么呢?对于我来说,我有两个 GPU,和一个不支持内核驱动程序的 Wifi 适配器,所以第一步是驱动程序。我们可以获得并安装带有驱动程序的闪存驱动器,并使用 build-essential 或 DKMS 来安装它们:

make
sudo make install
sudo modprobe __

或者,在将文件复制到/usr/src 之后

sudo dkms add -m ___ --version 1.0
sudo dkms build -m ___ --version 1.0
sudo dkms install -m ___ --version 1.0
modprobe ___

现在,我们的 wifi 驱动程序已经就绪,我们必须实际连接到我们的 wifi,第一步是打开我们的网络连接。

sudo ifconfig wlan0 up

然后扫描可用的 wifi SSIDs:

sudo iwlist scan | more

并添加我们的 WPA 密钥:

wpa_passphrase

然后我们将这些信息放到一个文本文件中。会议)

wpa_passphrase (SSID)> /etc/wpa_supplicant/wpa_supplicant.conf

然后我们将 CD 放入该目录,并连接!

sudo wpa_supplicant -B -D driver -i interface -c /etc/wpa_supplicant/wpa_supplicant.conf && sudo dhclient

恭喜,我们正式有 wifi 了!

现在我们可以做我们最喜欢的两件事,更新我们的包和库。需要注意的是,包管理器当然取决于你选择的发行版。对于 RedHat 可以是 dnf 也可以是 yum,Debian(或者 Ubuntu)会用 apt,Arch 会用 Pacman,openSuse 会用 man。所以如果你没有选择使用 RedHat,就用你各自的包管理器替换我的 dnf。

sudo dnf update && sudo dnf upgrade

在按下 y 键并输入至少一次之后,你现在必须得到你的新的最好的朋友:SSH。虽然现在有很多 SSH 工具,但是我们将会使用 SSH 的 FOSS 版本。

sudo dnf install openssh-server

现在让我们用主机名、端口等快速配置我们的网络。

$ nano ~/.ssh/config

现在,我们只需为我们的服务器启用 systemctl:

sudo systemctl enable ssh
sudo systemctl start ssh

如果你使用的是 Ubuntu,你需要运行以下命令为你的防火墙打开一个端口(端口 22 ):

sudo ufw allow ssh
sudo ufw enable
sudo ufw status

现在 SSH 应该正在运行,您的服务器应该已经启动并正在运行。如果你使用 CUDA 或 OpenCL,现在是 wget 或 dnf 安装一些图形驱动程序的好时机。

在将要连接到 SSH 服务器的客户机上,您还需要安装 openssh 客户机:

sudo dnf install openssh-client

这样一来,我们可以连接到我们的无头服务器:

ssh emmett@192.168.0.13

如果你不知道 IPv4 地址(最后带点的部分),WiFi 和互联网的情况会有所不同:

无线局域网(wireless fidelity 的缩写)

ipconfig getifaddr en1

以太网

ipconfig getifaddr en0

祝贺您,您现在已经连接到了您的 ssh 服务器,您可以像使用任何其他终端一样使用它。如果你碰巧正在使用 Nautilus,你也可以把服务器添加到你的文件管理器中,方法是转到文件,然后在左边点击其他位置,在底部有一个包含 ssh、ftp 等的组合框。你可以利用的关系。

那我们怎么和 Jupyter 一起用呢?

当然,首先我们必须安装 Jupyter,所以回到你的服务器,安装 pip for python3:

sudo apt-get install python3-pip

然后用 pip 安装 Jupyter Lab:

sudo pip3 install jupyterlab

要启动笔记本服务器,只需运行

jupyter notebook

要访问服务器,只需转到您的客户机,打开您选择的 web 浏览器,并输入您的 SSH 构建的 IP。现在你可以拔掉除了机器电源线以外的所有东西。

下一步

下一步是扔掉你的鼠标和键盘,因为你已经正式

没头了

如何使用 Jupyter 进行健康科学的初步数据分析

原文:https://towardsdatascience.com/how-to-use-jupyter-to-conduct-preliminary-data-analysis-for-health-sciences-r-tidyverse-edition-8c3260976cf2?source=collection_archive---------16-----------------------

在本教程中,我将讲述一个可以用于 Jupyter 笔记本/Jupyter 实验室进行数据分析的工作流程。我将讨论

  • 建立一个基于网络的 Jupyter 环境来完成你的工作,并且
  • 如何使用 R 来处理 Jupyter 笔记本或 Jupyter lab

以下是 Jupyter 笔记本的外观:

Jupyter notebook (code and text are woven here)

Jupyter 笔记本(和 Jupyter lab)是一种“笔记本”,可以在网络浏览器上运行,它的组件可以让你在一页纸的空间内做数据科学的事情,统计数据分析,写笔记,论文,生成图表。从他们的网站上阅读更多关于 Jupyter 笔记本的信息,点击这里:【https://jupyter.org/】

在他们的网站上,您可以了解到:

  • 如何下载 Jupyter 笔记本(免费开源,就像免费啤酒一样免费,像自由一样免费),
  • 如何在您的特定操作系统上安装它们。
  • 你甚至可以在tryjupyter.org上测试 Jupyter 笔记本。

能有多简单?我建议您在安装 Jupyter Notebooks(或 Jupyter lab)后,或访问 Jupyter notebook 或 Jupyter Lab 的托管实例后,务必阅读《走向数据科学》中的以下两个教程:

为数据科学带来 Jupyter 笔记本电脑的最佳性能

朱庇特实验室:朱庇特笔记本的进化

您将掌握如何使用 Jupyter 笔记本电脑以及如何使用它们的实用知识。

本教程的目的

在本教程中,我将向您展示如何使用 Jupyter Notebooks/Jupyter Lab,使用 R (tidyverse) 从头开始进行真实世界的数据分析。我就写一下用 R (tidyverse 和 ggplot) 做数据分析。在以后的文章中,我将向您展示如何使用 Python (pandas、matplotlib、statsmodel 和 seaborn)进行数据分析和创建图形。因为这些都是开源和免费的(免费的啤酒和免费的言论)工具。(点击下面的图片听理查德·斯托尔曼的采访是什么意思,😃:

因此,学习如何使用这些工具进行数据分析和写作,将使您能够轻松直观地完成数据分析项目,并与所有人分享。

完成本教程需要什么?

  • R 的实用知识
  • 网络浏览器和安装了 Jupyter notebook 或 Jupyter Lab 的计算机。然而,如果你不需要在你的电脑上安装 Jupyter notebook/Jupyter Lab。你也可以在这些网站上创建免费账户。几乎任何浏览器都可以工作。如果有任何浏览器不支持这些,请在评论中告诉我。
  • 如何在 markdown 中写作

我说的“R 的工作知识”是什么意思?

如果你以前没有用过 R,现在是个好时机。R 是一个统计编程环境(这意味着您不仅可以进行统计数据分析,还可以开发“例程”或程序,您可以使用 R 与他人共享,这是一件好事)。您可以从以下网站了解更多关于 R 的信息(什么是 R,如何获取和安装 R):

  • r 首页:https://www.r-project.org/
  • 从以下网站下载 R:【https://cran.r-project.org/
  • 学习如何在工作中采用 R 的一系列页面:【https://cran.r-project.org/web/views/】T4
  • 在本教程中,我将使用“tidyverse ”,这是一套 R 语言的包,可以用于数据科学;下面是链接:https://www.tidyverse.org/
  • 我建议您熟悉以下由 Hadley Wickham 和 Garrett Grolmund 编写的关于 r 中的数据科学的在线文本。它是免费的,很容易理解:https://r4ds.had.co.nz/

这些是让你开始的基本资源。在这里,我将介绍 R 的一些重要的关键组件,您可以使用它们来学习。在本教程中,我们将使用 R 和 tidyverse 读取一个数据集,对数据集进行“清洗和预处理”,然后在数据集中找到一些意义。我们将使用 R 中称为“gg plot 2”(Grammar of Graphics Plotting Version 2,基于 Leland 和 Wilkinson 的书“Grammar of Graphics”)的包来创建简单的图形。

关于 R 和 markdown 快速烹饪之旅

让我们开始吧。我们将在 Cocalc.com 免费使用一个 jupyter 实验室实例(URL:https://cocalc.com);如果你想使用它并跟随它,考虑在那里创建一个免费帐户并启动一个 jupyter 实验室服务器。当你游览 cocalc.com 时,它看起来是这样的:

Figure 1. Cocalc online jupyter environment. You can sign in with your other social media sign-ons.

登录并打开 Jupyter 实验室环境后,它应该如下所示:

Figure 2. Jupyter lab interface

我不会在这里进入 Jupyterlab 接口的细节,因为这已经在我上面分享的链接中很好地记录了,请阅读相关的文档,它写得真的很好。相反,让我们专注于手头最有趣的任务:

  • 文件扩展名为“”。ipynb ':“交互式 ipython 笔记本”
  • 我们将需要建立一个文件名,而不是“untitled.ipynb”,让我们称之为' first_analysis.ipynb '。您可以在第二个大的白色面板中右键单击文件名,然后更改文件名。
  • 然后我们需要获取一些数据,编写代码和文本来开始工作。

但在此之前,我们需要触及另外两点:

  1. 让我们学习一些关于 R 本身的知识,并整理数据
  2. 让我们来介绍一下编写文本的 markdown 语法

关于 R 的最基本的信息

我在下面的“灰色”框中提供了一些带注释的代码,您可以复制并粘贴到 Jupyterlab 中的代码块中,当您准备好运行时,请按“Shift+Enter”

# Comments in R code blocks are written using 'hash' marks, and 
# you should use detailed comments on all your codes
x <- 1 
# '<- ' is an assignment operator. Here x is set to the value of 1
# This is same as x = 1
x == 1
# Here, we evaluate whether x is equal to 1; 
# Everything in R is an object and you can find out about objects
# using the function typeof()
typeof(x) # should put 'double'
# double tells you that x is a number as in 1.00
# you can and should write functions to accomplish repetitive 
# tasks in R
# The syntax of function is:
my_function = function(x){function statements}
# You can call functions anywhere in R using the function name and 
# by writing the function parameters within parentheses
# as in my_function(x)
# An example of a function where two numbers x, and y are 
# multipliedmultiply_fn = function(x, y){z = x * yreturn(z)
}
multiply_fn(2,3) # will produce 6
# You can see that a function can call within itself another 
# function
# Combination of data and functions are referred to as packages
# You can call packages using library() function
# You can install packages using install.packages() function
# You can find help in R using help("topic") function
# In our case we will use "tidyverse" package. 
# We will need to install this first if not already installed

在这个小练习的最后,在我们把这个库叫做“tidyverse”之后,它看起来是这样的:

Figure 3. Our basic set up with tidyverse library ready to go

开始降价的基本要求

由于 html 是万维网的通用语言,它也相当复杂。约翰·格鲁伯发明了一种叫做 markdown 的语言,你可以用简单的装饰来书写文本的所有基本元素。可以写标题(我一般用两级标题)、链接、插码。你也可以使用 jupyter 笔记本上使用的 markdown 风格的表格和引用标记,所以你几乎可以在这里写你的整篇论文。在下面的框中,我提供了一个用 markdown 编写的短文版本和之后的渲染版本。希望这也能让你在 jupyter 笔记本上写作。

这是我们在 Jupyter 笔记本的文本框中所写的内容

# Purpose
This above was a first level header where we put one hash mark before the header. If we wanted to put a second level header, we would add another hash mark. Here, for example the goal is to demonstrate the principles of writing in markdown and conducting data analyses entirely on a web browser after installing jupyter notebook and optionally jupyter lab on the computer or the server.
## What we will do?
We will do the following:
- We will learn a little about R and markdown
- We will go grab some data sets
- After loading the data set in Jupyter, we will clean the data set
- We will run some tables and visualisations## So is it possible to add tables?
Yes, to add tables, do something like:| Task | Software |
|------|----------|
| Data analysis | Any statistical programme will do |
| Data analysis plus writing | An integrated solution will work |
| Examples of integrations | Rstudio, Jupyter, stata |## How do we add links?
If you wanted to add links to say sometihng like Google, you would insert the following code: [Name the URL should point, say Google]([http://www.google.com](http://www.google.com)), and it would put an underlined URL or name to your text.## Where can I learn more about markdown and its various "flavours"?
Try the following links:
- [Markdown]([https://daringfireball.net/projects/markdown/](https://daringfireball.net/projects/markdown/))
- [Github flavoured markdown]([https://github.github.com/gfm/](https://github.github.com/gfm/))
- [Academic markdown]([http://scholarlymarkdown.com/](http://scholarlymarkdown.com/))

这是它看起来的样子(部分,你可以在 Jupyter 实验室或 Jupyter 笔记本上复制它)

Screen output of a markdown rendered in a text block in Jupyter

让我们收集一些数据

现在我们已经:

  • 了解了一点 R 并安装和加载了 tidyverse
  • 学习如何在 markdown 中书写,以便我们可以描述我们的结果

是时候从网上抓取一些数据,并使用这些工具做一些分析了。现在,你将从哪里得到数据?数据无处不在,但有些网站让你更容易获取和使用它们。如何获取数据本身可以是另一个帖子,所以我不会进入细节,但一般来说:

  • 你可以搜索数据(我们将使用两个这样的网站:Figshare 和 Google Data Explorer)
  • 您可以使用应用程序编程接口(API)从网站上获取数据并使用它们。
  • 有几个网站提供玩具数据或真实世界数据供您使用(例如,数据和故事库)
  • 政府网站和卫生部门提供“一卡车”的数据供你分析和理解

这里的关键是学会如何理解这些数据。这就是数据科学的用武之地。具体来说,您可以:

  • 免费下载数据
  • 以对你理解它们的模式有意义的方式塑造它,并使它们成为“整齐的数据”
  • 使用可用的工具运行可视化
  • 使用不同的软件预处理数据(在本教程中,我们将使用 R 和 tidyverse,但是您也可以使用 Python 或其他专门的工具,如 OpenRefine 和电子表格)

出于本练习的目的,让我们访问 Figshare 并为我们的工作搜索数据。假设我们有兴趣确定工作场所健康问题的数据,并看看我们从 Figshare 获得了哪些数据来完成我们的工作。由于这是一个演示练习,我们将保持我们的数据集较小,这样我们就可以学习关于从网上抓取数据并分析它们的最基本的要点。使用 tidyverse 实现这一点实际上非常直观。

当我登录 Figshare 时,我的仪表盘看起来是这样的:

Figshare dashboard

我们搜索了基于“工作”和“健康”的数据,并确定了来自一项研究的原始数据集,研究人员在这项研究中研究了行为激活与抑郁和生活质量之间的关系。当我们搜索的时候,我们确保我们只想下载那些自由和公开共享的数据(有 CC-0 许可),并且我们想要数据集。

数据取自以下出版物:

[## 评估生活质量和行为激活之间的关系使用日本…

生活质量(QOL)是一个重要的健康相关的概念。确定影响 QOL 的因素可以帮助开发和…

journals.plos.org](https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0185221)

在描述这项研究时,论文作者在摘要中写道:

生活质量(QOL)是一个重要的健康相关的概念。确定影响 QOL 的因素有助于开发和改善健康促进干预措施。先前的研究表明,行为激活促进主观 QOL,包括幸福感。然而,行为激活改善 QOL 的机制尚不清楚。考虑到治疗后抑郁症状改善时 QOL 改善,并且行为激活是抑郁症的有效治疗,行为激活可能间接而非直接影响 QOL。为了阐明行为激活对 QOL 的影响机制,有必要检查与行为激活、抑郁症状和 QOL 相关的因素之间的关系。因此,我们试图研究这些因素之间的关系。参与者包括 221 名日本大学生,他们完成了关于行为激活、QOL 和抑郁症状的问卷调查:行为激活抑郁量表简表(BADS SF)、世卫组织生活质量 BREF 量表(WHOQOL-26)和流行病学研究中心抑郁量表(CES-D)的日本版本。BADS-SF 包括两个分量表,激活和回避,WHOQOL-26 测量总体 QOL 和四个领域,身体健康,心理健康,社会关系和环境。中介分析以 BADS-SF 激活和回避作为独立变量,CES-D 作为中介变量,每个世卫组织-QOL 作为结果变量。结果表明,抑郁完全中介了回避和 QOL 的关系,部分中介了激活和 QOL 的关系。此外,对 QOL 每个领域的分析表明,激活直接和间接积极影响 QOL 的所有方面,但回避主要通过抑郁对 QOL 的一部分产生负面影响。本研究提供了针对 QOL 增强的行为激活策略。

论文全文是开源的,您可以从以下网站下载并阅读论文:

[## 评估生活质量和行为激活之间的关系使用日本…

生活质量(QOL)是一个重要的健康相关的概念。确定影响 QOL 的因素可以帮助开发和…

journals.plos.org](https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0185221)

您可以从这里直接下载数据:

https://ndownloader.figshare.com/files/9446491

数据显示如下:

A look at how the data appears

在这里,我们将使用数据集并运行一个带注释的 jupyter 笔记本来展示以下不同步骤:

  • 获取数据
  • 将数据读入 R
  • 清理数据集
  • 问问题
  • 回答问题

如果你愿意,你可以在作者提供的数据集上复制他们的论文,但我们不会在本教程中这样做。在本教程中,我们已经介绍了使用基于网络的工具,您可以使用 Jupyter 笔记本/Jupyter 实验室进行数据分析。我已经介绍了 Cocalc,但是还有其他类似的工具。一些例子:

  • 微软 Azure 笔记本一系列语言全部免费,你可以使用 R 或 Python 或其他语言;免费的,你可以注册并马上开始工作
  • 谷歌合作实验室:来自谷歌,免费。您可以在 Python 笔记本上工作
  • Tryjupyter :给你不同语言和不同设置的免费笔记本。

因此,我们可以在任何一台笔记本上开始和结束我们的分析,因为这些笔记本是可互操作的。您还可以在 github 和 binder 上托管笔记本,并与世界各地的人分享您的笔记本。

第一步:下载数据 你可以看到这是一个 Excel 电子表格文件。您可以在电子表格程序(如 Excel 或 OpenOffice Calc)中打开它,并将文件导出为逗号分隔值文件。或者,我们可以直接在 Jupyter 中读取文件。我们就在这里做。

为此,我们需要使用“readxl”包。所以我们做如下:

# first load the package
library(readxl)
# If you find that your Jupyter instance does not have "readxl" 
# package in itself, then you will need to install it. 
# Easiest, install.packages("readxl") and then do 
# library(readxl)

加载后,它看起来是这样的:

After loading a data set, this is how it looks like

嗯,什么都没发生!为什么?因为 read_excel 函数读取 excel 文件“S1 _ 数据集. xlsx”的内容,并存储在一个名为 mydata 的对象中。我们现在将使用这个对象 mydata 来检查它的内部内容。

第二步:整理数据并进行预处理

现在,我们已经阅读了数据集,让我们深入了解其中的内容。第一件事是找出标题信息。我们可以在 R 中使用 head()函数来实现。这是它的样子:

Output of head(mydata)

我们还想找出数据集中的变量列表,所以我们这样做:

names(mydata) # produces the list of variables'Sex' 'Age' 'BADS-SF' 'BADS-SF_Activation' 'BADS-SF_Avoidance' 'CES-D' 'WHOQOL-26_Mean total score' 'WHOQOL-26_Phisical health' 'WHOQOL-26_Psychological health' 'WHOQOL-26_Social relationships' 'WHOQOL-26_Environment' 'WHOQOL-26_Overall QOL'

如您所见,虽然该数据集包含 12 个具有“表达性”名称的变量。有些变量的名称中包含“空格”。我们将重命名这些变量,以便它们对我们有意义。“性别”和“年龄”等变量相对容易理解,但我们可能需要重命名其他变量。您将从主论文和 Figshare 中的伴随数据描述中找到关于这些变量名的更多信息。

下表将变量名与其代表的概念和简短描述对应起来:

| Variable Name | What it stands for |
|---------------|--------------------|
| Sex           | 1 = Male, 2 = Female |
| Age           | Age in years          |
| BADS-SF       | Behavioral Activation for Depression Scale-Short Form |
| BADS-SF_Activation | BADS for activation |
| BADS-SF_Avoidance | BADS for avoidance |
| CES-D | Center for Epidemiologic Studies Depression Scale |
| WHOQOL-26_Mean total score | Japanese version of the WHO Quality of Life-BREF mean total score |
| WHOQOL-26_Phisical health | WHOQol-26 physical health |
| WHOQOL-26_Psychological health | WHOQoL-26 psychological health |
| WHOQOL-26_Social relationships | WHOQoL-26 social relationships |
| WHOQOL-26_Environment | WHOQoL-26 Environment |
| WHOQOL-26_Overall QOL | WHOQoL-26 Overall |

这些变量中的 QoL 是生活质量的简称。您可以在此通过相关网站了解更多关于世卫组织 QoL 的信息:https://www . who . int/substance _ abuse/research _ tools/who QoL bref/en/

我们不会在这里讨论细节,因为我们正在迈向下一步。在这个阶段,您可以看到:

  • 变量名有点长,所以您可能希望缩短它们,但在您继续工作时要让它们易于理解
  • 许多变量的名称中都有空格,因此需要小心处理(我们建议您使用下划线来表示空格)

我们如何重命名 tidyverse 中的变量?

这是我们的工作:

Renaming variables in the data set

需要注意几件事:

  1. 我们将把重命名的变量存储在一个新的数据集中(否则我们的更改将不会持续到我们在代码中完成并立即执行的内容之外,所以请确保将它保存在一个不同的命名对象中)
  2. 我们用一个符号“% > %”;这个符号被称为“管道”,读作“然后”。在这里,我们使用这个将许多不同的操作或命令链接在一起。如果你想了解更多这方面的知识以及如何使用它,请参考 Hadley Wickham 与 R 合著的关于数据科学的优秀著作,他在书中写道,

在幕后,x %>% f(y)变成了f(x, y),x %>% f(y) %>% g(z)变成了g(f(x, y), z)等等。您可以使用管道以从左到右、从上到下的方式重写多个操作。从现在起,我们将经常使用管道,因为它大大提高了代码的可读性

  • 然后我们使用了“rename()”函数,在这里,我们做了如下操作:
  • “新变量名”是第一个元素,接下来是
  • 一个“等号”,而“旧变量名”是第二个元素,表示
  • 我们将旧的变量值存储在新的变量中
  • 注意,在最后,一旦我们执行了它,我们得到了一个新的数据集,所有的值都保持不变,但是有了新的变量名。如果您不想转换某些变量的名称,请保持原样(就像我们对“年龄”和“性别”所做的那样)

让我们来了解一些争论数据的“语法”

当我们得到一个全新的数据集时,我们要做的第一件事就是“争论”这些数据。我们检查变量,我们绘制它们,我们重新编码它们以适应我们的目的,我们提出问题并试图回答它们。然后,一旦我们发现了一些我们认为可以深入研究的模式,我们就开始以各种方式对数据进行建模。在本教程中,我将仅限于写第一部分,我们如何做简单的表格和图形。同样,如果你正在与 R 和 tidyverse 合作(这是我推荐的),你的主要文本是 Hadley Wickham 的书: R for Data Science 。这本书是免费的;你可以用网上的免费软件来学习和练习,所以请试一试。正如您所看到的,您可以从不同的站点免费获取数据。我不会详细重复这本书里的所有内容,但我会指出五种语法,你会发现它们对处理数据很有帮助:

  • 选择 —使用此选项从数据集中选择列。假设我们只想处理该总体的 BADS 和 CES D 变量,我们将必须选择要处理的列:

Using Select

滤镜。 —如果我们想要处理数据集中的某些“个人”,我们将根据我们在列上设置的一些标准来过滤行。比方说,我们想和女性(" Sex == 2 ")和青少年("年龄< 20 ")一起工作,看看我们会怎么做:

Grammar: filter()

请注意简单性:

  • 我们使用“==”等价运算符来设置过滤条件
  • 我们使用“,”(逗号)来分隔不同的条件

排列 。—如果我们想按升序或降序查看数据集,我们使用动词“arrange()”来实现,如:

Grammar: arrange()

如您所见,数据集中最年轻的人只有 2 岁!您需要返回并纠正或测试这是否确实是值。这就是数据清理和预处理变得重要的地方。我们对此有何理解?

变异。 —您想要创建新的变量并将其存储在数据集中。您希望使用其他函数从现有变量中创建这些变量。假设,现在我们知道一个人的年龄被插入为 2 岁,可能是一个错误,我们不想丢失这个人的信息,我们想在 4 个组中减少年龄变量,我们该怎么做?我们使用变异动词,像这样:

Grammar: mutate

所以你看:

  • 使用 mutate 将一个变量重新编码为另一个变量
  • 使用 mutate 创建新变量
  • Mutate 使用新函数

让我们对 age_rec 变量进行计数,看看我们得到了什么:

Count of recoded age based on the Age

如你所见,如果你让计算机来决定,它可以创建我们不能使用的类别。因此,让我们对一个新的年龄组进行重新编码和变异,并将其保存到一个新的数据集,如下所示:

Binarised Age

你看到我们做了什么吗?

  • 我们创建了一个新的数据集(mydata4),并在其中创建了一个新的变量二进制年龄(“age_bin”),其中我们有 20 岁及以上的青少年和受访者(实际上应该是≥ 20 岁)
  • 你也可以分配你选择的标签(所以如果我们愿意,我们可以加上“青少年”和“二十岁以上”。

Mutate 是一个强大的动词,可以让您重新创建数据集和代码变量。你应该掌握这个。

汇总和分组 _ 依据。——选择、过滤、排列数据集、变异或改变变量,听起来可能是很多有用的事情,但你还需要更深入地了解数据,并学会如何从中找到意义。你需要找到汇总的摘要,以及那些连续变量的平均值,并把那些分类变量制成表格。通过这种方式,您可以深入了解数据。让我给你介绍一下“summarise()”和“group_by()”函数。

假设您有兴趣了解本次调查中受访者的平均年龄,然后想了解男性的平均年龄是否大于女性。你会怎么做?参见:

# What is the average age of the respondents?
average_age = mydata4 %>%summarise(average_age = mean(Age, na.rm = T))
average_age# Will return 19.36652

请注意,这是一个合并了所有个人的整个数据集的单一数字。这很好,你可以得到你发布的连续变量的平均值的完整列表。

然而,如果我们将 分割 数据集到不同的离散组(比如二进制年龄组,或者性别,就此而言),然后计算其他变量的平均值,这将有助于识别模式的有趣显示。因此,基本上,在分割数据集之后,我们将 应用一些函数,在我们的情况下 表示的意思,然后我们 将结果组合回当前值, 这将有助于有趣地显示同样有意义的结果。要全面了解这个主题,请阅读下面的文章(下载 PDF 格式):

所以,让我们把这个付诸行动,看看是否:

  • 在我们的数据中,男性比女性年龄大吗?
  • 青少年在健康相关生活质量(平均 WHOQoL)上的平均得分较低吗?

The code and results for males vs. females

那么,你的收获是什么?

  • 我们首先传递数据集,然后
  • 我们要求 tidyverse 按照分类变量进行分组(首先这样做,因为这是您对数据的“分割”),然后
  • 我们要求总结我们想要的变量。

聚散 。—让我们将这些概念付诸实践,并尝试回答这个问题,不同年龄组的男性和女性的生活质量得分有何不同?

  • 我们先来看看平均分:

We summarised all quality of life scores

这很好,但是解释起来很复杂。我们必须先看第一行,然后找到男性(性别等于 1)的个人生活质量参数的分数,然后读取下一行,依此类推。如果我们有一个“生活质量”的变量,列出生活质量、身体、心理、足球、环境等,并把它们读下来,这会对我们有所帮助。也就是说,我们将不得不 收集这些不同的分数,并将它们放在一个变量下,比如“生活质量”,我们将在那里看到的所有分数放在旁边的另一个变量下,我们可以将该变量称为“所有平均值”(因为这些基本上是平均值)。 在 tidyverse 中,我们现在引入另一个名为“gather”的动词来做这件事:

  • 使用一个“键”,在那里你可以收集你想要分组的变量的名字。例如,这里的“生活质量”
  • 使用一个“值”,在这里您可以放置它们各自的值。你给什么名字,关键和价值是由你决定的。我只关心给它们起个有意义的名字。

因此,下面是供您检查的代码:

Code and results of “gather”

看到发生了什么吗?我们现在已经“收集”了所有年龄组和所有性别的生活质量分数(各种参数)。但这仍然相当复杂,因为存在性别重复和年龄组重复。如果我们想把 展开 出来,那么现在我们就会把“all_means”的 分展开在性(1 和 2)的键下,我们就可以很直观地看到它们了。下面是代码:

Code and results of spread

所以,现在你可以看到你可以阅读每个年龄组(根据每个年龄组分组),每个分数,并可以比较男性和女性。这样你可以做一些有趣的比较。“spread”变得特别有用的一个领域是当您交叉表列变量时,例如在这个数据集中交叉表列二进制的年龄和性别。首先,看看你跑步时会发生什么

*crosstab = mydata4 %>% count(age_bin, Sex) # crosstabs binarised age and Sex*

Counting binarised age and sex, code and result

好吧,但我们需要一个适当的交叉表格,其中性别出现在列中,二进制年龄出现在行中。所以,我们用“传播”来达到这个目的,明白吗

Cross-tabulation of Age with Sex

好多了。现在你可以看到二元年龄组是如何在性别 1 和性别 2 中分布的(记住 1 =男性,2 =女性)。另外,请注意,这是一个数据框,这意味着您可以使用 mutate()添加一列来找出每种性别青少年的行百分比。你怎么能这样做?

Code and results for finding out the male percentage in the binarised age

如你所见,男性在青少年群体中较高,在 20 岁以上年龄组中较低(26%)。所以,当你评估一些分数和性别之间的关系时,请记住年龄分布可能是一个混杂变量。

第三步:可视化数据

在前两个步骤中,如何从各种来源(免费)获得数据,以及如何使用 Jupyter 等免费软件来编写和处理数据,使其适合于分析。但是准备表格和摘要以及清理数据是一半的乐趣。能够创建简单的图表来深入研究数据是令人满意的。所以在今天的第三步,也是最后一步,我们将学习如何在 tidyverse 中创建简单的图表。

我建议您使用“ggplot()”来创建图表。Ggplot()是一个很大的主题,网上有很多书可供你阅读。阅读以下资源开始学习:

  • Tidyverse ggplot 文档
  • R 图形食谱
  • 数据科学 R 的数据可视化部分

除了上面的网站,我建议你阅读下面的文章来深入了解图的构造(至少是原理),不管你是否使用 tidyverse:

为了绘制图形以显示数据,我们将在本教程中使用 ggplot()函数,我们将遵循一般方案:

*ggplot([data]) +geom_[geometry](mappings = aes(x = [variable],y = [variable],stats = "<choices>") +facet_<wrap | grid>() +coord_<choices>() +labs("title of the plot) +xlab("label for x axis") +ylab("label for y axis")*

要完全理解 ggplot()是如何工作的,请点击我上面列出的链接。在这里,当我们开始介绍并“尝试”时,我将只涉及基本的。记住一些规则:

  • 这个函数是 ggplot(),数据是强制的(这就是我把它放在方括号中的原因)
  • 然后有一个“+”号,这个“+”号必须在一行的末尾,不能在开头
  • 加号表示“层”,来自“图形的分层语法”
  • 您必须始终指定美学(“aes”)值,否则将无法构建图形
  • 其余的选项都是可选的(我说“有点”,因为你会在继续使用它的过程中学习)

让我们从 mydata4 开始,看看它现在是如何显示的:

The mydata4 data frame

让我们用图表来探索:

  • 年龄分布是什么样的?
  • 男性和女性是什么样子的?
  • bads_sf 和 whoqol_mean 是什么关系?男女都差不多吗?

我们可以继续探索,但是用图形方式回答这些问题将为您提供一些思路,您可以用这些思路来探索这个数据集中您自己的问题,以及您可能想要处理的未来数据集中的问题。

年龄分布是什么样的?

首先,研究代码:

*mydata4 %>%ggplot() +geom_bar(aes(x = Age)) +ggtitle("A bar plot of age") +xlab("Age in years") +ylab("Counts") +ggsave("age_bar.png")*
  • 我的数据 4 是包含我们想要绘制的所有变量的数据集
  • 管道符号将关于 mydata4 的信息发送给 ggplot()函数
  • 然后,我们开始了一个新的层,并添加了层+符号
  • 我们需要一个条形图,因为年龄主要是数字,因此用条形表示。我们只需要指定一个 X 轴,ggplot 就会计算出原始计数。
  • 我们用 ggtitle()为图表命名,并将标题插入引号中
  • 我们使用 xlab()和 ylab()函数标记 x 和 y 轴
  • 我们使用 ggsave()函数保存了该图

它看起来是这样的:

Bar plot of age

男性和女性的年龄分布柱状图看起来一样吗?

现在我们应该使用 facet 函数来绘制两个不同的图,或者我们可以拆分图形:

  • 首先,看代码:
*mydata4 %>%ggplot() +geom_bar(aes(x = Age)) +***facet_wrap(~Sex) +***ggtitle("A bar plot of age by gender") +xlab("Age in years") +ylab("Counts") +ggsave("age_bar_sex.png")*

请注意,我们添加了性别变量来将图形分成两部分,这样它就可以将图形分成两部分,如下图所示。你怎么想呢?男性和女性看起来相似吗?

Plot of the Age distribution by gender

bads_sf 和 whoqol_mean 是什么关系?男女都差不多吗?

这一次,我们将探讨两个变量之间的关联或关系。我们要画什么样的图,取决于我们要处理的变量的性质。下表将为您提供一些思路:

*| X variable | Y variable | Type of graph | Geometry         |
|------------|------------|---------------|------------------|
| Continuous | Continuous | Scatterplot   | geom_point()     |
| Continuous | Categorical| Boxplot       | geom_boxplot()   | 
| Categorical| Continuous | Boxplot       | geom_boxplot()   |
| Categorical| None       | Barplot       | geom_bar()       |
| Continuous | None       | Histogram     | geom_histogram() |*

因为 bads_sf 和 whoqol_mean 都是连续的,所以我们可以画一个散点图。但是还有什么能解释呢?如果我们认为 whoqol_mean 之间可能存在某种关系,因此如果 bads_sf 得分增加,那么 whoqol_mean 也会增加,我们可以使用散点图来测试这一点,并绘制线性回归来绘制它们之间的关系(线性回归或建模超出了本教程的范围,但我们将只显示图表,而不会在此写更多)。

代码如下:

*mydata4 %>%ggplot() +***geom_point(aes(x = bads_sf, y = whoqol_mean))*** +ggtitle("Association between bads_sf and whoqol") +xlab("BADS-SF score") +ylab("WHOQoL Score") +ggsave("bads_who.png")*

这是关联图:

Association between BADS-F score and WHOQoL score, you see a positive association

现在我们需要进一步验证它,看看男性和女性之间的联系是否相似。因此,我们添加了一条回归线,并为男性和女性的点和线涂上不同的颜色:

首先是代码:

*mydata4 %>%***mutate(gender = as.factor(Sex)) %>%***ggplot() +geom_point(aes(x = bads_sf, y = whoqol_mean, ***colour = gender***)) +***geom_smooth(aes(x = bads_sf, y = whoqol_mean, colour = gender), method = "lm")*** +ggtitle("Association between bads_sf and whoqol") +xlab("BADS-SF score") +ylab("WHOQoL Score") +ggsave("bads_who_lm.png")*

然后是图:

Association between BADS-SF and WHOQoL scores

这是怎么回事?

  • 我们必须添加一个新的变量“性别”,从“性别”开始,所以使用 mutate 函数将其转换为因子变量,而不是字符变量。因子变量是一个分类变量,但是明确地具有根据字母或数字顺序排列的级别。这对于后续步骤是必要的,在这些步骤中,我们想要测试关系中的差异。
  • 我们想测试这些点会有什么不同,所以我们用性别变量给它们涂上不同的颜色。请注意,我们将颜色参数放在了贴图的美学中。
  • 类似地,我们想使用平滑函数,在我们的例子中,这是“线性模型”,因此选择“lm”作为方法。但这必须贴在美学参数之外的 。在平滑线条的美学中,我们需要指出,我们想要不同颜色的线条来表示性别变量的级别。

那么,你认为你在这段关系中看到了什么?性别差异大吗?我们可以继续探索更多的数据集,但我们需要在这里停下来,总结一下我们迄今为止所做的工作。

结论

这是一个教程,我们涵盖了以下主题:

  • Jupyter notebooks 是免费的开源工具,使您能够进行数据科学工作,同时还允许您充分利用 R 和 Python(以及其他语言)的潜力来进行数据分析。
  • 您可以进行二次数据分析和整理数据,而实际上无需使用任何其他工具(如电子表格)来清理和争论数据。
  • 我们在网上找到了一个使用 CC-0 许可(creative commons licence,可以自由使用数据集)的数据集和一篇研究数据集的文章。
  • 我们学习了如何使用 tidyverse 环境来检查、子集化、过滤和绘制数据。

我希望这能激励你去处理更多的数据集。记住,你练习得越多,你的技能就会越好。如果你需要更多的信息和问题,请在评论区发表。我希望它是一个快速的介绍,所以没有介绍一些关于整齐的数据和统计程序的其他概念;这将在随后的文章中讨论,你会在网上找到更多的信息。快乐分析!

这里有一个到 jupyter 笔记本的链接,用于这个分析

如何在 BigQuery ML 中使用 K-Means 聚类来更好地理解和描述数据

原文:https://towardsdatascience.com/how-to-use-k-means-clustering-in-bigquery-ml-to-understand-and-describe-your-data-better-c972c6f5733b?source=collection_archive---------9-----------------------

谷歌云上仅使用 SQL 的无监督学习

BigQuery ML 现在支持无监督学习——您可以应用 K-Means 算法将您的数据分组到聚类中。与监督机器学习不同,监督机器学习是关于预测分析的,非监督学习是关于描述性分析的——它是关于理解你的数据,以便你可以做出数据驱动的决策。

K-Means clustering is an unsupervised learning algorithm that can help you understand your data and provide descriptive labels to your it. Photo by Randy Fath on Unsplash

你在聚集什么?

首先,确定什么是集群,为什么要集群。假设你是一个零售商,拥有客户交易的数据。有几种方法可以对该数据集进行聚类,这取决于您想要对聚类做什么。

  • 你可以在你的顾客中找到自然群体。这叫做客户细分。用于客户细分的数据可能包括他们去过的商店、购买的商品、支付的金额等。你会试着去了解这些顾客群是什么样的(这些被称为人物角色),这样你就可以设计出吸引这些顾客群成员的商品。
  • 你可以在购买的物品中找到自然群体。这些被称为产品组。您可以根据购买者、购买时间、购买地点等对商品进行分类。你可以试着了解一个产品群的特征,这样你就可以学习如何减少自相残杀或者提高交叉销售

在这两种情况下,你都在使用聚类作为一种启发式方法来帮助你做决定——设计个性化的产品或理解产品交互太难了,所以你为客户群或项目群设计。

请注意,对于产品推荐的特定用例(向客户推荐产品或针对某个产品的客户),最好训练一个 ML 模型来做确切的事情,使用一种协作方法,如 WALS 。但是对于没有现成的预测分析方法的其他决策,聚类可能会给你一种方法来做出数据驱动的决策。

设置聚类问题

为了很好地使用集群,您需要做四件事:

  1. 确定您正在聚类的字段。CustomerId?ItemId?然后,根据该字段的属性对数据进行聚类。
  2. 查找给定客户/项目等的群。属于。
  3. 了解集群的一些属性。
  4. 利用这种理解来做决定。

在本文中,我将展示伦敦自行车共享数据的聚类方法。假设我们围绕自行车共享站的设计和库存做出了许多决策,我们希望了解我们系统中不同类型的站点,以便我们能够以数据驱动的方式做出这些决策。

我们需要做这四件事:

  1. 集群自行车租赁站。我们需要聚类的字段是 station_name,为了这样做,我们需要找到一个站点的属性。
  2. 找到每个站属于哪个集群。
  3. 了解每个集群的特征。
  4. 利用这种理解来做出数据驱动的决策。

但在这之前,我们首先要收集我们需要的数据。

0.收集数据

我们将使用的数据由伦敦的自行车租赁组成,它是欧盟地区的公共数据集,因此如果您想跟踪我的查询,请确保在欧盟地区创建一个名为 demos_eu 的数据集。

我们希望根据以下因素对电台进行分类:

  • 租赁期限
  • 每天的旅行次数
  • 自行车架的数量
  • 离市中心的距离

我们通常在工作日和周末做出不同的决定,例如储备加油站的自行车(即确保加油站有自行车出租)。因此,我们实际上要对其“主键”是 station_name 和 isweekday 组合的实例进行集群。

下面是一个将相关数据汇集在一起的查询:

WITH **hs** AS (
SELECT 
h.start_station_name as **station_name**,
IF(EXTRACT(DAYOFWEEK FROM h.start_date) = 1 OREXTRACT(DAYOFWEEK FROM h.start_date) = 7, "weekend", "weekday") as **isweekday**,
h.**duration**,
s.**bikes_count**,
ST_DISTANCE(ST_GEOGPOINT(s.longitude, s.latitude), ST_GEOGPOINT(-0.1, 51.5))/1000 as **distance_from_city_center**
FROM `bigquery-public-data.london_bicycles.**cycle_hire**` as h
JOIN `bigquery-public-data.london_bicycles.**cycle_stations**` as s
ON **h.start_station_id = s.id**
WHERE h.start_date BETWEEN CAST('2015-01-01 00:00:00' AS TIMESTAMP) AND CAST('2016-01-01 00:00:00' AS TIMESTAMP)
),**stationstats** AS (
SELECT 
station_name,
isweekday,
AVG(duration) as duration,
COUNT(duration) as num_trips,
MAX(bikes_count) as bikes_count,
MAX(distance_from_city_center) as distance_from_city_center
FROM hs
**GROUP BY station_name, isweekday**
)**SELECT * 
from stationstats
ORDER BY distance_from_city_center ASC**

我们正在提取 2015 年自行车租赁的数据(start_station_name,weekend/weekday,duration )(参见 WHERE 子句),并将其与车站信息(自行车数量,距市中心的距离)相结合。

然后,我们在 stationstats 中计算车站的属性(骑行的平均持续时间、出行次数),并传递车站属性(自行车数、距市中心的距离)。我们的数据集看起来像这样:

Dataset that we will use for clustering; The primary key for our data is the combination of station_name and isweekday.

1.BigQuery ML 聚类

进行聚类只需要在上面的 SELECT 查询中添加一个 CREATE MODEL 语句,并删除数据中的“id”字段:

**CREATE OR REPLACE MODEL demos_eu.london_station_clusters
OPTIONS(model_type='kmeans', num_clusters=4,** standardize_features = true**) AS**WITH hs AS (
SELECT 
h.start_station_name as station_name,
IF(EXTRACT(DAYOFWEEK FROM h.start_date) = 1 OREXTRACT(DAYOFWEEK FROM h.start_date) = 7, "weekend", "weekday") as isweekday,
h.duration,
s.bikes_count,
ST_DISTANCE(ST_GEOGPOINT(s.longitude, s.latitude), ST_GEOGPOINT(-0.1, 51.5))/1000 as distance_from_city_center
FROM `bigquery-public-data.london_bicycles.cycle_hire` as h
JOIN `bigquery-public-data.london_bicycles.cycle_stations` as s
ON h.start_station_id = s.id
WHERE h.start_date BETWEEN CAST('2015-01-01 00:00:00' AS TIMESTAMP) AND CAST('2016-01-01 00:00:00' AS TIMESTAMP)
),
stationstats AS (
SELECT 
station_name,
isweekday,
AVG(duration) as duration,
COUNT(duration) as num_trips,
MAX(bikes_count) as bikes_count,
MAX(distance_from_city_center) as distance_from_city_center
FROM hs
GROUP BY station_name, isweekday
)**SELECT * except(station_name, isweekday)
from stationstats**

该查询处理了 1.2 GB 的数据,耗时 54 秒。模型模式列出了聚类中使用的 4 个因素:

The K-Means model schema

请注意,我们已经在我的创建模型中指定了所需的集群数量(num_clusters=4 ),并删除了我们不想在其上进行集群的因素(station_name 和 isweekday)。如果您的要素具有不同的动态范围,标准化要素是一个很好的选择(bikes_count 在 10–50 范围内,而 num_trips 在数千范围内,所以我正在这样做)。

如果我们忽略分类的数量,BigQuery ML 将根据训练数据集中的总行数选择一个合理的默认值。我们也可以做超参数调整来找到一个好的数字。本质上,我们将为 num_clusters 的不同值运行聚类,找到误差度量,并选择图形稳定的点。误差测量可通过下式获得:

SELECT davies_bouldin_index 
FROM ML.EVALUATE(MODEL demos_eu.london_station_clusters)

数字越小,聚类越好。

2.一个站属于哪个集群?

特定的站属于哪个集群?您可以使用 ML.PREDICT 获得该值。以下是查找名称中包含“Kennington”的每个电台的聚类的查询:

WITH hs AS ...,
stationstats AS ...,SELECT * except(nearest_centroids_distance) 
FROM **ML.PREDICT(MODEL demos_eu.london_station_clusters, 
(SELECT * FROM stationstats WHERE REGEXP_CONTAINS(station_name, 'Kennington')))**

这会产生:

Which cluster do the Kennington stations belong to?

3.检查集群

您可以查看聚类质心,即模型模式中 4 个因子的值,使用:

SELECT * FROM ML.CENTROIDS(MODEL demos_eu.london_station_clusters)
ORDER BY centroid_id

通过一点 SQL 操作,我们可以透视上表:

WITH T AS (
SELECT 
centroid_id,
ARRAY_AGG(STRUCT(feature AS name, ROUND(numerical_value,1) AS value) ORDER BY centroid_id) AS cluster
FROM ML.CENTROIDS(MODEL demos_eu.london_station_clusters)
GROUP BY centroid_id
)SELECT
CONCAT('Cluster#', CAST(centroid_id AS STRING)) AS centroid,
(SELECT value from unnest(cluster) WHERE name = 'duration') AS duration,
(SELECT value from unnest(cluster) WHERE name = 'num_trips') AS num_trips,
(SELECT value from unnest(cluster) WHERE name = 'bikes_count') AS bikes_count,
(SELECT value from unnest(cluster) WHERE name = 'distance_from_city_center') AS distance_from_city_center
FROM T
ORDER BY centroid_id ASC

这会产生:

Clusters’ attributes

要可视化该表,请单击“在 Data Studio 中浏览”并选择“带条形的表”。将质心列作为“维度”,其余列作为度量。然后你会得到:

Cluster attributes, visualized in Data Studio

这使我们能够解释集群。本质上,聚类#1 由人们长途乘车的郊区车站组成,聚类#2 由其他郊区车站组成,聚类#3 由繁忙的城市车站组成,聚类#4 由不那么繁忙的城市车站组成。

基于这些特征和对伦敦的一些了解,我们可以为这些集群想出描述性的名字。群组 1 可能是“一日游”,群组 2 可能是“卧室社区”,群组 3 可能是“旅游区”,群组 4 可能是“商业区”。

4.做出数据驱动的决策

让我们使用这些集群来做出不同的决定。

  • 我们刚刚得到资金,可以扩大自行车架。我们应该在哪些车站增加额外的容量?如果我们没有聚类数据,我们会倾向于选择出行量大但自行车数量不足的站点,即聚类#3 中的站点。但是我们做了聚类,发现这组车站主要服务于游客。他们不投票,所以我们将把额外的容量放在集群#2(卧室社区)。
  • 我们需要试验一种新型的锁。我们应该在哪一组站上做这个实验?商业区站似乎是合乎逻辑的,果然这些站有很多自行车,并且足够繁忙以支持 A/B 测试。
  • 我们想在一些加油站储备赛车。哪些?第一组,为出城一日游的人服务的车站。

显然,我们可以通过每次进行定制数据分析来单独做出这些决定。但是把电视台聚集在一起,想出描述性的名字,并用这些名字来做决定要简单得多,也更容易解释。

你只用 SQL 就能做到这一切的事实?那很酷。

如何利用学习和发展培训来推动创新

原文:https://towardsdatascience.com/how-to-use-learning-development-training-to-drive-innovation-793ec5b91ff?source=collection_archive---------22-----------------------

L&D 对数据科学的优势和益处。

最近的研究揭示了各行各业的组织如何利用学习和发展(L & D)培训来最大化他们的创新潜力。实践培训专家已经确定了一些关键的策略,这些策略有助于将创新文化带入你的办公室。

在当今全球化的市场中经营企业的复杂现实往往意味着面临激烈的全球竞争,并不断更新您组织的目标,以跟上您所在行业的最新和最大的创新趋势。在以技术为基础的行业和数据科学功能中尤其如此,在这些行业中,新的创新和通往数字化的道路是每天的现实。

虽然竞争前景可能令人望而生畏,但职业发展培训是在你的工作场所文化中巩固创新的直接而有效的方式。

来自 findcourses.com 的 2019 年 L&D 报告基准测试了各行业和市场的公司如何利用 L&D 培训来保持其组织在各自领域的创新前沿。该报告发现了收入增长、学习和创新之间的持续关系。从在您的培训基础设施中构建敏捷性,到在培训环境中利用最新技术,培训专业人员展示了企业如何利用 L&D 培训来构建可持续的创新文化,从而在 21 世纪的市场中导航。

敏捷的培训基础设施孕育着灵活性

在数据科学部门或以技术为基础的行业工作时,您可能会觉得敏捷性已经成为您日常职责的一个固有方面。诚然,这些角色和行业通常需要相当大的灵活性,但问自己一些关键问题也是值得的:

贵组织的培训基础设施中融入了多少灵活性?此外,这种敏捷性可以转化为您的整体工作场所文化吗?

据 Wyndham Destinations 负责学习和发展的副总裁 Anthony Sandonato 称,为 110 多个国家的 25,000 多名员工实施敏捷培训基础设施是成功的核心战略。Sandonato 解释说,温德姆的“L&D 团队结构建立在灵活的框架之上,旨在保持敏捷并适应持续的组织变化,而不会影响我们人才发展战略的速度或质量。”

创建敏捷培训功能将有助于您将培训目标与组织目标的整体转变保持一致。这些目标可以随时改变,因为每个企业都试图跟上最新的创新和趋势。虽然数据科学是一个技术密集型领域,但如果你希望吸引和留住最优秀的人才,那么在评估技术的创新性之前,你应该接受这样一种心态,即灵活和创造性的工作场所文化应该是你的优先事项。

该报告还发现,高管高度参与 L&D 事务的公司认为自己公司有创新文化的可能性是其他公司的 3 倍。在具有敏捷培训功能(由高层管理人员引入)的培训室中展示灵活心态的重要性,将有助于自下而上地带来
文化变革。

在来自英国的一份类似的研发报告中,41%的市场挑战者预测他们的研发预算会增加。L & D 有助于为员工创造空间,将适应性和敏捷性从理论领域带入实际应用。

敏捷数据科学并不总是所有团队的完美方法,但是根据 Eugene Yam 的说法,“数据科学团队在‘倾听数据’和研究方面有优势。应用创新来改善组织成果应该是他们使命的一部分。”[1]一旦您将敏捷性确立为贵组织培训职能的一个关键原则,在培训室学到的灵活技能和策略就可以扩大规模,以提高您数据科学职能的整体质量和能力。

从数据科学到培训室,技术无处不在

一旦你在你的培训职能和整个运营层级中建立了创新文化,重新评估技术在你的培训产品中的使用是使创新成为新的文化规范的合乎逻辑的下一步。

技术和数字化是商业世界中一条持续且不可避免的道路,在评估完成工作的最佳技术时,培训行业与数据科学没有什么不同。

报告发现,在所有被调查的公司中,高达 84%的公司在他们的 L&D 职能部门使用技术。从电子学习到微视频再到虚拟现实,创新技术彻底改变了培训行业。此外,该报告发现,收入增长的公司在其 L&D 产品中使用虚拟现实和基于游戏的学习等创新技术的可能性是其他公司的两倍。

在培训环境中利用这些创新技术,不仅会影响您培训基础设施的整体灵活性,还会强化理论培训原则,并将其引入您蓬勃发展的创新文化中。深度强化学习(DRL)通过游戏化的人工智能训练策略如平均场、随机和进化游戏都是利用技术力量并最大限度地发挥其训练潜力的创新方式。

虚拟现实(VR)通过你的培训功能提供了另一个保持创新文化的机会。数字教练公司 STRIVR 的首席战略官丹尼·贝尔彻(Danny Belch)表示:“由于虚拟现实的按需特性,只需点击一个按钮,就可以激发真实的生活体验。你现在可以练习这些情况。通过完整的端到端实践,您可以获得合法的逼真场景。这不是角色扮演。它是孤独的,赌注是免费的。你有这个美丽的自由空间去练习,去结结巴巴地说你的话。”

除了基于游戏的学习,通过虚拟现实创建真实生活场景来培训新员工或现有员工不仅是强化重要学习目标的好方法,还可以帮助您在测试中从员工那里获得即时而有价值的反馈,深入了解正在使用的技术的具体特性。

外卖

拜耳美国学习与人才发展主管凯伦·比金说:“当你生活在创新中时,你可以影响创新。”利用创新的 L&D 培训战略,开始构建基础设施,以支持您组织中的创新文化,并期待培训技术的力量进一步推动培训室的创新。推动创新不会在一夜之间带来变化,但 L&D 培训可以让每个参与者的旅程变得更加高效、富有成效和创造性。

引用资料来源:
[1] E. Yam。数据科学与敏捷(2019),走向数据科学。

如何利用机器学习预测药物不良反应

原文:https://towardsdatascience.com/how-to-use-machine-learning-to-forecast-adverse-drug-reactions-abc83ab91afd?source=collection_archive---------34-----------------------

利用机器学习改善患者结果

更新:我开了一家科技公司。你可以在这里找到更多

当病人对药物产生意外反应时,对个人来说是危险的,对社会来说也是昂贵的。然而,如果医疗专业人员可以使用机器学习来预测不良药物反应(ADRs)并最小化对患者的风险,会怎么样?

药品不良反应是医疗保健行业的一个大问题,直接占所有住院人数的大约5%,估计是全球第六大死亡原因。个性化药物已经是一个快速发展的趋势,但是想象一下,如果医生能够在给病人开药之前预测出病人发生药物不良反应的可能性。

FDA 的不良事件报告系统( FAERS )收集全世界记录的每一个不良事件的信息。我们利用这些数据训练了一个机器学习模型来预测 ADRs,并探索奥美拉唑药物不良反应的原因。

1.将数据加载到 Mind Foundry

FAERs 数据集包含大量信息,但我们采取了额外的预防措施来排除那些预先假定存在 ADR 的变量,如去挑战/再挑战代码。

将数据加载到 Mind Foundry 后,我们能够看到遭受药物不良反应的患者的汇总统计数据。

特别是,我们可以看到每个 ADR(例如住院)在其他变量中的分布情况。

我们用来预测不良反应的因素是患者的:

  • 性别、年龄和体重
  • 剂量、形式、频率和途径
  • 累积剂量
  • 药品制造商

数据集中包括的 ADR 有:

  • 死亡
  • 危及生命的情况
  • 残疾
  • 住院治疗(= hospitalization)
  • 其他严重

2.准备数据

Mind Foundry 会自动扫描数据以发现潜在问题,并就如何最好地为机器学习建模准备数据向用户提供建议。

基于我们对数据的理解,我们选择简单地将剂量、频率和形式中的缺失值标记为“未知”。然后,我们可以通过简单的点击来自动应用建议。

Mind Foundry 还对应用于数据的每个处理步骤进行完整的审计跟踪,然后可以编辑或导出新数据。

3.模拟不利住院

当我们准备好构建我们的模型时,我们需要做的就是告诉 Mind Foundry 我们希望预测哪一列。然后,它会自动处理数据到训练集和测试集的严格分割,所以它不会过度适应您的解决方案。

然后,Mind Foundry 将开始搜索最佳数据科学管道,并在搜索过程中提供一些性能统计数据。

4.验证和解释模型

一旦找到最佳解决方案,Mind Foundry 会通过指示其预测能力与随机模型相比是否显著来验证模型的健康状况。这些测试是在从训练中排除的原始数据集的 10%范围内执行的。

Mind Foundry 还指出了每个变量在模型决策中的相对权重,以及每个变量如何影响结果。

4.调查结果

Mind Foundry 指出,住院的机会随着患者年龄的增长而增加,但随着体重的增加而减少。

这可能看起来很奇怪,但考虑到超过一定体重后残疾的可能性会显著增加,因此成为主要的 ADR,这是可能的。

制药商似乎对住院几率也有轻微影响。最后,口服途径和 40 毫克剂量的片剂将增加住院的机会。

这项简短的研究强调了机器学习使用患者数据预测 ADR 的潜力。从更大的角度来看,它还揭示了医生根据每个患者的具体情况量身定制处方的可能性,以及药品制造商为高危患者群体重新设计治疗方法的可能性。

如何利用机器学习有可能成为百万富翁:预测股市?

原文:https://towardsdatascience.com/how-to-use-machine-learning-to-possibly-become-a-millionaire-predicting-the-stock-market-33861916e9c5?source=collection_archive---------2-----------------------

我们的置信区间在 50%到 70%之间

When you’re so bored with your stacks

在华尔街工作和你想象的一样紧张和有回报。许多西装,许多阴沉的脸和大量的香烟烟雾。在你所期待的世界金融中心的疯狂中,每个人的潜在目标都很简单。冒着把事情过于简单化的风险,我现在就告诉你,金融就是用钱(你自己的或者你借的)来获得更多的钱。金融业实际上并不创造任何价值,而是利用其他因素来获得投资回报。

股票市场是最著名的基础设施之一,通过它任何人都有可能发财。如果有人能破解预测未来股票价格的密码,他们将几乎统治世界。

只有一个问题。准确预测股票市场的未来几乎是不可能的。那么多的分析师,那么多的研究人员,那么多超级聪明的人都试图弄清楚这一切。没有人能够获得一致的结果。没有人。

那么这篇文章的重点是什么呢?为什么我要写关于使用机器学习来预测股票市场的可能性?我猜主要是为了好玩。然而,更重要的是,对于机器学习和金融来说,这是一个很好的学习练习。

议程

  1. 储料器模块
  2. 移动平均线
  3. 简单线性回归
  4. k-最近邻
  5. 多层感知器
  6. 你应该做什么
  7. 需要改进的地方
  8. 资源

如果你想更深入地了解这个项目,或者如果你想添加代码,查看一下 GitHub 库

使用储料器模块

Stocker 模块是一个简单的 Python 库,包含了许多有用的股票市场预测函数。在初始化时,它们不是那么准确(最好抛硬币决定)。但是通过一些参数的调整,结果会好得多。

首先我们需要克隆 GitHub 库。

!git clone [https://github.com/WillKoehrsen/Data-Analysis.git](https://github.com/WillKoehrsen/Data-Analysis.git)

我们还需要导入一些库。既然已经克隆了 repo,我们也可以导入 Stocker 模块了。

!pip install quandl
!pip install pytrends
import stocker
from stocker import Stocker

让我们创建一个 Stocker 对象。我选择谷歌作为我的公司,但你没有义务也这样做。Stocker 模块有一个名为 plot_stock()的函数,它自己做了很多工作。

Google’s stock is very nice

如果您注意的话,您会注意到 Stocker 对象的日期不是最新的。止于 2018–3–27。仔细看看实际的模块代码,我们会发现数据来自 Quandl 的 WIKI 交换。也许数据没有更新?

我们可以使用 Stocker 进行技术股票分析,但现在我们将专注于成为媒介。Stocker 使用了一个由脸书开发的叫做 prophet 的软件包,这是一个很好的附加建模软件。

现在让我们测试一下斯托克的预测。我们需要创建一个测试集和一个训练集。我们将培训时间定在 2014 年至 2016 年,测试时间定在 2017 年。让我们看看这个模型有多精确。

Look how terrible this prediction is!

结果相当可怕,预测几乎和掷硬币一样糟糕。让我们调整一些超参数。

Here we can see the results of using different changepoints

对变点进行验证是调整超参数以更好地调整股票预测算法的有效方法。

现在,我们可以评估优化的模型,看看预测估计值是否有任何改进。

This is only SLIGHTLY better than the previous model

现在是做终极测试的时候了:去股市碰碰运气(当然是模拟的)。

Looks like it’s just better to buy and hold.

即使在所有这些调整之后,很明显,简单地买入并持有会产生更好的回报。

为机器学习准备数据

现在让我们继续尝试用机器学习来预测股票价格,而不是依赖于一个模块。对于这个例子,我将使用 Stocker 提供的 make_df 函数来使用 Google 股票数据。

Narrowing down the dataframe to get the stuff we care about

移动平均线

总之,均线是技术分析中常用的指标。这是一个滞后指标,这意味着它使用过去的价格来预测未来的价格。它可以有效地消除任何短期波动,并找到整体趋势。我们将使用移动平均线来看看我们是否能更好地预测股票价格。

Here’s the closing prices for Google stock

让我们用 RMS(均方根误差)来衡量我们模型的准确性。

现在让我们看看我们的预测在实际价格旁边的位置。

Yikes

就找出股票数据的总体趋势而言,移动平均线方法做得不错,但它未能看到价格上涨的全部幅度,这不好。我们肯定不想用这种方法进行实际的算法交易。

简单线性回归

让我们尝试使用另一种方法来预测未来的股票价格,线性回归。

首先,让我们基于原始数据集创建一个新的数据集。

现在,让我们为线性回归算法的数据集添加更多的要素。我们将使用 fastai 模块中的一些函数。

现在让我们做一个火车测试分裂。

现在我们可以实现算法并得到一些结果。

再一次,预测算法在某种程度上指出了总体趋势,但是它没有抓住我们最需要的东西。

k-最近邻

让我们继续另一个机器学习算法,KNN。

让我们用和线性回归一样的数据经历同样的过程。唯一的区别是我们将对数据实施不同的算法。让我们看看哪些预测更好。

我们的结果是什么?

What a horror story

呀!这是迄今为止我们得到的最糟糕的预测!k-最近邻对于分类问题和小规模回归更有用是有原因的。这似乎是过度拟合的典型案例。因为 KNN 实际上只是计算从一个点到另一个点的距离,它完全无法计算出价格走向的趋势。下一步是什么?

多层感知器

让我们进入一些深度学习,更具体地说,神经网络。多层感知器是最简单的神经网络类型之一,至少比卷积神经网络和长短期记忆简单。我们不需要深入算法实际工作的细节。如果您感兴趣,请查看本文末尾的参考资料。

让我们看看结果。

这比 KNN 还糟糕!关于为什么神经网络在预测股票价格方面如此糟糕,有许多因素,其中之一肯定是缺乏有意义的特征和数据。显然,还有许多超参数可以调整。

结论

我们今天学了什么?所有这些技术分析向我们展示了什么?答案很简单:如果你不是雷伊·达里奥、沃伦·巴菲特或任何伟大的投资者,那么试图跑赢股市的风险很大,最终也不会那么有利可图。根据一些消息来源,大多数对冲基金甚至不能比标准普尔 500 做得更好!因此,如果你想在你的投资上获得最好的回报,就采取买入并持有的策略。在很大程度上,简单地投资于标准普尔 500 这样的指数基金已经获得了相当不错的回报,即使是在经济出现几次大幅下滑的时候。最后还是要由你来决定。

需要改进的地方

感谢您花时间通读这篇文章!请随意查看我的作品集网站或我的 GitHub 。

1.使用不同的股票数据

我只在相对较短的时间内使用了谷歌股票数据。随意使用不同的数据,这些数据可以通过 Stocker 或 Yahoo Finance 或 Quandl 获得。

2.尝试不同的机器学习算法

有许多非常好的机器学习算法。我只使用了其中的一小部分,其中只有一个是深度学习算法。

3.调整更多超参数

这是不言自明的。大多数情况下,任何算法的默认设置都不是最优的,因此尝试一些验证来找出哪个超参数最有效是很有用的。

资源

  1. 了解股市
  2. 技术分析
  3. 什么是机器学习?
  4. 移动平均线
  5. 线性回归
  6. K-最近邻
  7. 神经网络
  8. 张量流
  9. Keras

如何利用新闻文章预测 BTC 价格变化

原文:https://towardsdatascience.com/how-to-use-news-articles-to-predict-btc-price-changes-c37e305a97f?source=collection_archive---------9-----------------------

itcoin (BTC)的价格变化是不稳定的,原因有很多,例如公众对其特别不同的感知价值和高知名度的损失。在本文中,我们关注的是其中的一个主要因素,BTC 新闻文章的影响。由于 BTC 过去的势头和加密货币市场中 BTC 市场的巨大份额,已经存在一个庞大的 BTC 玩家群体。然而,在这个市场中仍然缺乏一种定量分析的方法来做决定,所以我们在这里努力基于机器学习算法来帮助解决这种情况。

利用各种普通的监督机器学习算法并探索半监督算法,我们建立了一个模型来预测某篇新闻文章是否会导致 BTC 价格的明显上涨或下跌,以帮助 BTC 玩家做出更合理的卖出或买入 BTC 的决定。

我们的项目大致分为三个主要部分,金融数据处理、新闻文章处理和最终预测模型。迫不及待地想现在就走完整个流程!

财务数据处理

我们在 Kaggle 上收集了 BTC 从 2018 年 1 月 1 日到 2018 年 1 月 4 日的逐秒数据集,这些数据集在转换为基于天的数据集后由以下信息组成。

根据股票市场的经验法则,股票价格的明显变化被定义为价格波动超过过去 30 天滚动平均价格的 2 个标准差,但没有公认的明显 BTC 价格变化的定义。由于 BTC 价格的剧烈和不断变化,很难测试哪个数量的标准差是最明显的。因此,我们使用与 BTC 股票市场相同的 2 个标准差。代码如下所示,

Basic math equation of calculating 2 standard deviations

根据指标,我们得到并标记了在我们选定的时期内 BTC 价格发生明显变化的日期。然后,我们将日期分为三组,第一组具有明显的价格上涨,即正标记(日期:2018 年 3 月 19 日),第二组具有明显的价格下跌和正标记(日期:2019 年 2 月 5 日、2019 年 3 月 15 日、2019 年 3 月 17 日、2019 年 3 月 18 日),另一组价格变化在 2 个标准偏差内。

现在我们进入第二部分,新闻文章的数据处理。这两部分的逻辑联系将在第三部分阐述。

新闻文章

我们使用 news API(可以使用下面的键)来提取与第一部分相同的指定日期范围内的新闻文章。

Available News API keys

从新闻文章中摘录的内容如下表所示:

News articles’ extracted contents

由于新闻文章的导语总是包含着最重要的信息,而且有很多读者只是略读导语段落,所以对于 内容 栏目,我们只提取了新闻文章的导语。

我们将所有提取的文章的引言段落中出现频率最高的前 100 个词(首先完成了词干化和词干化,并删除了停用词)作为我们的语料库,我们认为它们与 BTC 交易和价格最相关,因此如果一篇新闻文章在前 300 个词中没有提到这些关键词中的任何一个,我们就认为这篇文章与 BTC 无关,然后将其从我们待探究的文章中排除。(前 300 个单词是通过实证分析得出的新闻文章的主要思想,我们不选择介绍性段落是因为有时导语少于 300 个单词,我们希望涵盖更多的文章),

以下是 100 字的部分内容。

Words of top occurrences in news articles

与上述三个日期组相匹配,新闻文章也被分成三组。三者中,价格变化明显的两个群体是我们关注的重点。

然后我们处理我们的功能,直到现在,我们已经得到了每篇文章的作者和出版商。为了将文本数据转换为数字数据,首先,我们根据作者和出版商在我们选择的文章中发布的文章数量对他们进行排名,然后通过查看文章数量的分布,我们将作者和出版商分成编号为 1 到 5 的五组,以使每组的人口大致相同。

我们没有简单地对作者和出版商进行分类的原因是,只有基于树的算法(如随机森林)才能识别类别号,而非基于树的算法(如 SVM)会将类别号视为一些有意义的数字,这将极大地影响模型的准确性。

情感分析

新闻文章有一个非常重要的特性,即其中所表达的主流情绪。许多组织已经开始对新闻文章进行情感分析,比如微软的 Azure、谷歌的云自然语言 API 以及 python 的 NLTK 包。

我们研究了谷歌的 API 和 Azure,在将两者与我们自己对文章中情感的判断进行比较后,结果表明谷歌在我们的模型中表现得更好。在许多研究中,谷歌的 API 也是所有工具中准确率最高的。

要使用 Google API 或 Azure,你必须获得认证,用 Python 进行情感分析的详细设置过程可以参考https://www . ka ggle . com/c/new-York-city-taxi-fare-prediction/data

Google API 给出的结果有 4 列,我们只使用其中的两列,一列是分数,另一列是震级。分数对应于总体的消极、中性或积极情绪,范围从 -11-1 表示完全消极的情绪,1 表示积极的极端,0 表示中性情绪。总体情绪的其他程度在 -11 之间变化。评分已经归一化,也就是说新闻文章的字数不会影响这个数字。量级衡量积极和消极情绪的整体强度。与 s 核心不同,幅度没有归一化,所以它与文章长度成比例,范围从 0 到 +inf 。例如,如果一个作者在一篇文章中表达了强烈的积极和消极情绪,抵消了积极情绪,那么这篇文章中传达的整体情绪将是中性的。然而,量级统计了所有的累积情绪,所以最终的分数可能是 0 ,但是量级大于 3 或者其他什么大的数字。

以下是谷歌给出的一些例子,

Examples of sentiment judgment

(详细的文档可以在

https://cloud . Google . com/natural-language/docs/basics # interpreting _ 情操 _ 分析 _ 价值观

为了避免新闻文章字数会影响量级数量的问题,我们也对其进行了归一化处理。

TF-IDF 探索

在一组新闻文章中,一些重要的词可能在某篇新闻文章中多次出现,而在其他新闻文章中很少出现。当读者阅读一篇文章时,重复出现会加强视觉效果,因此读者更有可能对这些文章做出反应。TF-IDF 分数正好帮助我们很好地衡量影响。TF-IDF 代表术语频率-逆数据频率,是两部分的乘积。

第一部分是词频,它用一个等式计算文档(在我们的研究中是新闻文章)中每个词在语料库中的出现频率,

n_i,j 表示一个单词 i 在一个文档 j 中出现的次数,分母为文档 j 中的总字数。

第二部分是逆数据频率,其用途是计算我们所有文档(所有新闻文章)中的稀有词的权重,如下所示:

N 是文档总数, df_t 是包含单词 t 的文档数。因此,很少出现在所有文档中但只出现在少数文档中的单词将由于低的 df_t 值而具有高的 IDF 分数。

最后将以上两部分相乘得到 TF-IDF 得分。

因此,如果单词 i 在一篇新闻文章中出现多次,但在其他新闻文章中很少出现,从而导致 TF-IDF 得分较高,我们可以得出结论,该单词在这篇文章中很重要。在删除停用词后,我们将 TF-IDF 得分高的词视为新闻中的重要词,因此我们对最高的 5 个 IF-IDF 得分进行平均,以衡量视觉效果。计算结果基本上如下所示:

TF-IDF calculation result

干杯!所有的食物洗好了,调料拌好了,剩下的唯一任务就是倒入锅里煮。现在让我们来看看预测模型吧!

预测

监督算法

在我们的模型中,我们总共有 5 个特征,即出版商、作者、情感得分、情感幅度得分和 TD-IDF 得分,数据如下

Prediction model’s five features

预测的数据是二进制数。如果预测值为 0,则认为新闻文章对 BTC 市场没有影响,不会引起明显的价格变化。否则,这篇新闻文章将引起明显的价格变化。我们的 BTC 应用程序即时发布的结果可以供 BTC 投资者参考,以决定是否购买或出售,投资者的即时反应可以帮助他们节省或赚取合理的金额。

预测的精确程度由两个指标来检验。首先,我们使用传统的度量标准“准确性”来测试它。此外,我们还绘制了内置概率计算功能的算法的 ROC 曲线,并显示了每条 ROC 曲线的 AUC 值。我们还探索 ROC-AUC 度量的原因是我们希望更多地关注阳性结果 1。如果 BTC 玩家在当天的大部分新闻中看到 1,他们将获得 BTC 价格极有可能上涨的信息,从而购买更多的 BTC 来投机。然而,如果价格实际上是下降而不是上升,买家将需要相当大的成本来弥补损失。相反,如果预测价格会下降,但实际上是上升的,与买方的反应相比,卖方的损失相对较小。总之,积极的是更有价值的,因为它的高成本的属性。从准确性和 ROC-AUC 度量,我们可以找到性能最好的算法。

我们使用逻辑回归、随机森林、SVM、KNN、感知器和 XGBoost 进行预测。准确度结果如下所列,

Comparison of tranning and test accuracy

可以看出,随机森林算法是 6 种算法中训练和测试精度最高的算法。

并且 ROC-AUC 产生了相同的结论,在所有其他算法中具有最大的 AUC 分数,

ROC-AUC of Random Forest

半监督算法

在现实情况下,很难像预期的那样收集大量数据,因此我们提出了探索半监督算法的想法,以仅利用部分可接近的数据来生成更多的自我标记数据,然后进行预测。

目前的半监督学习领域已经发展成为一个完善的知识体系,所以我不打算在这里讲述它的细节。基本上,有三种半监督学习,主动学习,纯直推式学习和模型丰富的直推式学习。具有不同数据集特征和最终目标的项目应该匹配合适的半监督模型。因为我们的模型的目标函数不是凸的,我们选择使用直推式支持向量机(TSVM)。

我们利用 100 个标记样本和 1014 个未标记样本来预测 478 个未标记测试样本。最后,TSVM 得到了 67%的准确率。与使用监督算法 SVM 的 60%相比,TSVM 显示出改进,这基本上是半监督学习的主要使用,同时受到有限数据集的约束。

Comparison of SVM and TSVM

我们还努力检查了基于图的模型,标签传播。它的方法论可以简化为下图,

Graph-based semi-supervised model

然而,其中一个关键的输入数据集是由专家给出的标记数据,旨在不断改进标签,但我们缺乏,所以在未来,我们将更深入地挖掘这种方法,并试图从中寻找一些有用的输出。

未来的探索与思考

尽管我们的模型取得了令人满意的结果,但仍有一些潜在的问题需要考虑。已经出现的一个与神经网络有关,这是我们将来要探索的。

在范式 NLP 公式的约束下,神经网络(NN)可以提取当前文章中包含的信息,但是它们不能提取与未来事件相关的信息。也就是说,作为一个例子,如果我是以色列公民,我读到某个重要人物被暗杀,那么作为一个不仅了解历史而且了解报复能力的知情读者,我可以推断这种行为的后果——比如经济和/或军事报复。另一方面,一个完全的局外人会阅读同一篇文章,只知道有人被暗杀了,而且这个人很重要,值得写出来。NN 的就像后者。

所以我们必须弄清楚是否有办法绕过老练的读者和天真的读者之间的鸿沟——但是基于 ML 公式/方法。

对于未来的应用,我们计划开发一个聊天机器人来自动化我们的预测显示。原型接口是

Prototype interface of Chatbot

它一般有三个部分,一个用于提问的聊天窗口,可供参考的实时 BTC 价格图表和带有作者和出版商标签的新闻文章,以及情感评分、幅度和 TF-IDF 评分。

我们对任何问题都持开放态度,我们非常欢迎您提出建议。如果你对这个项目有热情,请随时与我在 chelsea.yangmi@gmail.com 联系!

如何使用 NLP 分析 WhatsApp 消息

原文:https://towardsdatascience.com/how-to-use-nlp-to-analyze-whatsapp-messages-1adf0e85907c?source=collection_archive---------8-----------------------

NLP-WhatsApp

使用 NLP 分析我和妻子之间的 WhatsApp 消息

2018 年 8 月 17 日,我和我梦想中的女人结婚了,想在婚礼前一天送她一份礼物给她一个惊喜。当然,作为一名数据科学家,我必须通过数据进行交流!

我们的 WhatsApp messages 似乎是一个很好的信息来源。我使用 NLP 来分析消息,并创建了一个小的 python 包,名为【SOAN】,它允许你这样做。

在这篇文章中,我将指导你完成我所做的分析,以及你将如何使用我创建的包。点击此链接,获取将 WhatsApp 文本下载为. txt 的说明。

预处理数据

该包允许您预处理。txt 文件作为特定的格式是进行分析所必需的。只需导入 helper 函数来导入数据和处理数据。 import_data 用于导入数据,而 preprocess_data 用于准备数据,以备分析。

from soan.whatsapp import helper      # Helper to prepare the data
from soan.whatsapp import general     # General statistics
from soan.whatsapp import tf_idf      # Calculate uniqueness
from soan.whatsapp import emoji       # Analyse use of emoji
from soan.whatsapp import topic       # Topic modeling
from soan.whatsapp import sentiment   # Sentiment analyses
from soan.whatsapp import wordcloud   # Sentiment-based Word Clouds%matplotlib inline
df = helper.import_data('Whatsapp.txt')
df = helper.preprocess_data(df)

在对数据进行预处理后,您将得到几个列:Message_Raw、Message_Clean、Message_Only_Text、User、Date、Hour、Day_of_Week。Message_Raw 包含原始消息,Message_Clean 仅包含消息本身,不包含用户或日期,Message_Only_Text 仅保留小写文本并删除任何非字母数字字符:

The first row of our cleaned messages. It is in Dutch but basically states if I made it home alright 😛

探索性数据分析(EDA)

既然已经对数据进行了预处理,就可以根据消息的频率创建一些初始图。调用 plot_messages 绘制每周的信息频率:

general.plot_messages(df, colors=None, trendline=False, savefig=False, dpi=100)

Weekly count of the number of messages over time.

有趣的是,这表明在 2016 年 12 月左右,消息似乎出现了明显的下降。那时我们搬到了一起住在 T21,这解释了为什么我们不需要给对方发那么多短信。

我还对我和妻子之间每天的信息频率感兴趣。从 Github 借鉴了一些灵感来创建一个日历情节(使用修改版的 CalMap ):

general.calendar_plot(df, year=2017, how='count', column='index')

The frequency of messages (darker = more often)

有一段时间,我们发短信的频率更高,但这似乎不是一种视觉上可以观察到的模式。让我们和 TF-IDF 一起更深入的探讨一下!

独特的文字(TF-IDF)

我想展示一些对我们来说独一无二但也经常使用的单词。例如,单词“Hi”可能对我来说是唯一的(因为她总是使用单词“Hello”),但如果我在数百条消息中只使用一次,它就不会那么有趣了。为了对此建模,我使用了一种流行的算法,称为 TF-IDF(即,术语频率-逆文档频率)。它获取文档中单词的频率,并计算这些单词在语料库中的反比:

TF-IDF slightly adjusted to work with text messages

基本上,它会告诉你哪些单词重要,哪些不重要。例如,像“the”、“I”和“an”这样的词出现在大多数文本中,通常并不那么有趣。

你在上面看到的 TF-IDF 版本略有调整,因为我关注的是一个人发短信的字数,而不是文本的数量。

下一步是通过简单地划分每个人的 TF-IDF 分数来计算每个人的独特性分数:

Uniqueness score for each person.

正如你在上面的公式中看到的,它考虑了聊天中每个人的 TF-IDF 分数。因此,它也适用于群组聊天。

从事数据科学的一件重要事情是以清晰、有趣和吸引人的方式交流结果。因为我的观众是我的妻子,我必须确保我的视觉效果是清晰的。我决定使用一个水平直方图来显示最独特的单词和它们的分数。水平直方图中的单词通常更容易阅读。为了使它在视觉上更有趣,您可以使用条形作为您想要包含的任何图像的遮罩。出于演示的目的,我用了一张我婚礼的照片:

unique_words = tf_idf.get_unique_words(counts, df, version = 'C')
tf_idf.plot_unique_words(unique_words, user='Me', image_path='histogram.jpg', image_url=None,title="Me", title_color="white", title_background='#AAAAAA', width=400,height=500)

My top 10 most unique words used in our text messages.

表情符号和情感分析

我们使用的表情符号在一定程度上可以描述我们的感受。我觉得将你之前看到的公式(即 TF-IDF +独特词汇)应用于表情符号会很有趣。换句话说,哪些表情符号是谁独有的,但也经常使用?

我可以简单地获取原始信息并提取表情符号。然后,这是一种简单的方式来计算表情符号的数量并应用公式:

emoji.print_stats(unique_emoji, counts)

Unique and frequently emojis per person.

显然,我独特的表情符号更积极,而她的表情符号似乎是消极的。这并不一定意味着我使用更多积极的表情符号。这仅仅意味着她独特的表情符号倾向于更加消极。

这些分析的自然结果是情绪。从我们的信息中可以看出我们之间的关系是否有所下降?首先,我们需要提取积极的信息。请确保通过以下方式创建一个包含情感得分的新列:

from pattern.nl import sentiment  as sentiment_nl
df['Sentiment'] = df.apply(lambda row: sentiment_nl(row.Message_Clean)[0], 1)

我决定不把情感步骤放在包里,因为有很多方法(和语言)来创造情感。也许你想使用不同的方法,而不是基于词典的方法。然后,我们可以计算平均每周情绪,并绘制结果:

sentiment.plot_sentiment(df, colors=[‘#EAAA69’,’#5361A5'],     savefig=False)

Our sentiment over time. The y-axis shows how happy or sad we communicated in that period.

2018 年 1 月,我遭遇了一场事故,这解释了那段时间信息的负面性。

基于情感的词云

词云通常用于演示哪些词在文档中频繁出现。经常出现的词比只出现几次的词大。

为了让云彩更有趣,我用情感将它们分开。积极的词语和消极的词语有着不同的含义:

(positive, 
negative) = wordcloud.extract_sentiment_count(counts, user = "Me")wordcloud.create_wordcloud(data=positive, cmap='Greens', mask='mask.jpg', stopwords='stopwords_dutch.txt',     random_state=42, max_words=1000,  max_font_size=50, scale=1.5, normalize_plurals=False,  relative_scaling=0.5)wordcloud.create_wordcloud(data=negative, cmap='Reds', mask='mask.jpg', stopwords='stopwords_dutch.txt',     random_state=42, max_words=1000,  max_font_size=50, scale=1.5, normalize_plurals=False,  relative_scaling=0.5)

Sentiment-based Word Clouds for my messages.

这些单词是基于模式包中的现有词典选择的。我们通常使用的正面词汇是 goed (好)和 super (超级)。负面词有 laat (后期)和 verschrikkelijk (恐怖)。有趣的是,我发现有些词被贴上了负面标签,而我并没有这样使用它们。例如,我通常使用waanzining(疯狂)作为 very 来强调某些单词。

主题建模

主题建模是一种试图从文本文档中提取主题的工具。一组文档可能包含用户可能感兴趣的多个主题。一个主题由一组单词表示。例如,一个主题可能包含单词马。根据这些话,好像题目是关于动物的。

我在 SOAN 实现了两个创建主题的算法,即 LDA(潜在狄利克雷分配)和 NMF(非负矩阵分解)。NMF 使用线性代数来创建主题,而 LDA 基于概率建模。查看这篇帖子,获取对模型的深入解释。

我决定删除对两个模型的参数进行工作的选项,因为它旨在给出可能的主题的快速概述。它为每个用户分别运行模型:

topic.topics(df, model='lda', stopwords='stopwords_dutch.txt')
topic.topics(df, model='nmf', stopwords='stopwords_dutch.txt')

Topics generated per person using LDA and NMF

在生成的主题中你能看到的(如果你能读懂荷兰语)是可以找到描述做杂货的主题。也有相当多的话题在某种程度上描述了第二天见面或说晚安。这是有意义的,因为我们大部分的信息都是在我们不住在一起的时候发出的。

使用主题建模的缺点是用户需要自己解释主题。它还可能需要调整参数来找到高质量的主题。

感谢您的阅读!

如果你和我一样,对人工智能、数据科学或心理学充满热情,请随时在 LinkedIn 上添加我,或者在 Twitter 上关注我。

如果您想全面了解代码,请务必访问笔记本!你可以通过这个链接简单地获取代码并添加你自己的 WhatsApp.txt 文件。

如何在调查报告中使用开源卫星数据

原文:https://towardsdatascience.com/how-to-use-open-source-satellite-data-for-your-investigative-reporting-d662cb1f9f90?source=collection_archive---------3-----------------------

Investigation on water levels of the Theewaterskloof Dam dam, South Africa

毫无疑问,这是一座巨大的信息金矿——也许太大了——许多记者仍然回避广泛使用卫星数据。自从像digital globePlanet Labs这样的公司提供高分辨率数据以来,卫星故事的供应如雨后春笋般增长。但是开源数据——尽管分辨率较低,但仍然是有效和及时的故事来源——仍然没有得到充分利用。手里有一座未被触及的数据山,许多人要么害怕错过森林——或者这个案例中的故事——因为树木或者误解。两者都是合理的担忧。今天,我们将尝试解决您可能与同事分享的一些保留意见,并教授一些访问、理解和处理开源卫星数据的基础知识。

最近关于在新闻编辑室内外开展遥感活动的技术评论试图揭开如何利用开源卫星数据平台的神秘面纱。有些人试图解释如何简化收集数据的过程。很少有人在可行的故事和技术能力之间建立可行的联系。本教程试图挑战这种观念。我们将带您看一些基本的例子——从初学者到更高级的技术水平。

了解卫星图像的工作原理:

不同的卫星向地球发送不同的图像。区别包括分辨率(图像的清晰度),它们产生的波段的数量和类型,以及它们更新的频率。

决议事关重大

Finding the balance between resolution, capabilities of bands and availability: Credit: Mark Corcoran, Reuters Institute Fellowship Paper, University of Oxford

有多频繁?

Credit: Mark Corcoran, Reuters Institute Fellowship Paper, University of Oxford

什么是光谱带?

Not a new musical genre: Spectral bands determine what type of analysis you can do with the data; Credit: Mark Corcoran, Reuters Institute Fellowship Paper, University of Oxford

例如,Sentinel 2 卫星图像数据以 13 个不同光谱带的形式出现,范围从可见和近红外到短波红外,具有 10 米的 4 个光谱带、20 米的 6 个光谱带和 60 米空间分辨率的 3 个光谱带。

将这些波段视为一种双筒望远镜,它可以让您发现原本隐藏在数据中的东西。这些乐队的正确组合是关键。可以在数据上运行各种脚本(可以是不同的波段组合,如果你愿意的话)(可以在本地机器上运行,也可以在 Sentinel hub 上运行)。

如果你是在广泛的基础上报道,你要让自己熟悉这些不同的组合,以及它们为你实现的目标,因为当其他渠道错过节拍时,它可能会派上用场。

教程:从这里你需要什么?

  • Python 3.6
  • 一个合适的 Tif 阅读器(如果你想下载光栅文件)
  • Jupyter 笔记本和各种 python 包
  • Sentinel hub 的免费帐户(在 python 教程中找到描述)

2.使用 Sentinel Hub 浏览器工具搜索报道:

如果你是一个热爱技术的人,你可能会对使用浏览器应用程序的想法有点反感。但是请听我说完。对于探索和调查来说, EO 浏览器是一个不错的选择(如果你想退得更远,哨兵游乐场的卫星更少,但提供了一种稍微简单的探索方式)。

Predecessor 和其他开源卫星平台在工作流中使用 python 时可能会提供有限的选项。在这方面,Sentinel Hub 提供了一些有用的选项。此外,不需要为了做一些有趣的事情而下载整个栅格切片(可以说,调查很少同时需要所有切片数据)。相反,它允许放大特定区域。

以下是 EO 浏览器提供的数据列表以及使用这些数据的理由:

Description of EO Browser data

让我们开始沉迷于卫星狂潮吧。

1.新手

追踪野火:

对野火突然扩散和破坏的检测和报告,去年创纪录的火焰肆虐美国加利福尼亚州。这可能不是最后一次。专家称,这样的火灾在不久的将来有可能再次出现。免费获取的资源构成了 Landsat 8 数据(在美国地质调查局的帮助下提供)和 Sentinel-2 数据。

Sentinel-2 在可见光和红外光谱部分提供了比其开源同事更高分辨率的图像,完全可以胜任监测植被、土壤和水覆盖、内陆水道和沿海地区的任务。

挑战

  • 进入 EO 浏览器 —注册并登录(免费)
  • 选择哨兵-2
  • 通过将云覆盖率限制在 30%来缩小数据收集范围。
  • 发现美国加利福尼亚州的野火,这些野火在 2018 年 7 月至 8 月期间达到高潮(它们在全州范围内如此全面地宣布,你应该不会有问题来发现云的羽状物)

2018 年火灾可能的例子:

纳齐兹大火(2018 年 7 月 20 日):41.956N 123.551 W卡尔大火(2018 年 7 月 28 日):40.6543N 122.6236 W门多西诺复杂大火(2018 年 7 月 29 日):39.243283 N

接下来,我们要渲染一个特定的波段组合,以便更清楚地看到地面上的行动正在发生。

复制' 野火脚本':

Pierre Markuse 好心地提供了这份文件。将其插入显示“< / >”的“自定义”部分(可视化选项卡下)(手动按钮旁边)。

Locating California wildfires (August 2018)

有趣的角度:消防员在控制/隔离火势方面有多成功

Example by Pierre Markuse: Fire retardant caused by firefighting planes https://flic.kr/p/Wt8Vzo

如果您在指定的时间范围内成功发现了野火,您应该会发现黄红色的斑点。重要的是:不要把这些解释为火焰。尽管展示了它,你应该告诉你的观众所能看到的并不是真正的火灾,而仅仅是一个红外覆盖图——在某种程度上,它与活跃的火灾和热点是一致的。

挑战

在写这篇文章的时候,新的野火已经蔓延了近一周。

如果您有时间,发现这些火灾,像以前一样应用脚本并进行调查。

中规模集成电路(medium-scale integration 的缩写)

其他波段组合可用于说明潜在的野火风险区域。植被的干燥就是这样的指标之一。潮湿压力指数(MSI)可以揭示这种干燥区域,并有助于所谓的“火灾条件分析”。

该指数与其他水植被指数相反。值越高,水分胁迫水平越大(含水量越少)。试一试,用不同的乐队脚本遵循相同的程序,看看您能检索到什么。

MSI 脚本:

现在让我们使用 Python:

为了使用 Sentinel Hub 服务,您需要一个 Sentinel Hub 帐户(如果您还没有注册,请在此【https://www.sentinel-hub.com/】免费注册)。

登录 Sentinel Hub 配置器。具有实例 ID(长度为 36 的字母数字代码)的配置已经存在。对于本教程,建议您创建一个新的配置(通过“添加新配置”),并将配置设置为基于' Python 脚本模板'

记下您的配置的实例 ID,并将其粘贴到 INSTANCE_ID 变量声明中:

所有请求都要求给定一个边界框作为 sentinelhub.geometry.BBox 的实例,并带有相应的坐标参考系统(sentinelhub.geometry.CRS)。我们将使用 WGS84,并且可以使用 sentinelhub.geometry.CRS 中预定义的 WGS84 坐标参考系统。

现在,我们只需提供一个 JS evalscript 的 URL 地址(在这个专用页面上有许多其他巧妙的脚本)。

让我们再次选择 fire 脚本,并将其 URL 作为参数 CustomUrlParam.EVALSCRIPTURL 的值提供。

Python output: Downloaded Sentinel-2 image with the provided wildfire JS evalscript

腈基丁二烯橡胶(nitrile-butadiene rubber 的缩写)

另一个专门检测火灾的自定义脚本是 NBR——归一化燃烧比的缩写— ( 链接到此处的脚本)。如果你报道一场大火的事后状态,这将有助于你的分析和报道。

Further explanation of NBR here

挑战

用 NBR 脚本 t 找到被烧毁的植被。

Python output: Downloaded Sentinel-2 image with the provided NBR JS evalscript

2.中级—变得更具调查性

依靠火力脚本找到苏黑尔·哈桑准将的藏身之处——叙利亚最臭名昭著的军阀之一

这位绰号“老虎”的将军是“老虎部队”的舵手,这是一场俄罗斯支持的战役,也是叙利亚阿拉伯军队的精英部队,在叙利亚内战中主要作为进攻部队。

在叙利亚夺回东姑塔的行动中,根据侵犯人权文献中心(VDC)的数据,最近由猛虎组织执行的行动造成至少 600 名平民死亡,其中至少 100 名是儿童。

为了找出 2016 年苏黑尔·哈桑的藏身之处,我们进行了一次典型的情报工作,从看下面的视频开始:

我们可以看到向左飘来的几缕烟。在另一个序列中,我们看到了将军的藏身之处。

The Hideout (left) of Brigadier General Suheil al-Hassan, a.k.a the Tiger — “If you’re not with God then you’re with the devil. Be on the side of God so that God will be with you,” should Hassan reportedly have said at a more recent campaign on the edge of eastern Ghouta

Smoke clouds from nearby Aleppo thermal plant

从视频中,我们了解到这是为“打击 ISIS 的巴尔米拉之战”拍摄的。这可能是阿勒颇热电厂。

Confirmation: Google earth pics for the power plant show the extent of destruction after the fire raged (burned out circles on the right)

一个简单的网络搜索为我们提供了一定程度的澄清:

  • 在谷歌上搜索' 阿勒颇热电厂 ' 。维基百科的链接为我们提供了热电厂的长/纬度。
  • 接下来,进入谷歌地球或谷歌地图,输入你找到的坐标:'36° 10′30″N 37° 26′22″E'。你将会看到在工厂的右边有一组烧毁的塔。

在 EO Brower 上,打开 roads 并输入谷歌地图结果中的经度和纬度(36.175000,37.439444)(进入 EO 浏览器的搜索窗口)。在我们的例子中,我们对 2016 年 2 月 16 日(2016-02-16)感兴趣,在这一天我们目睹了奇妙的烟柱。

Smoke plums move to the left

接下来,我们像以前一样继续并应用火灾脚本来可视化 Sentinel-2 图像中的火灾(挑战:如果你有信心,在你的 Python 环境中做,或者在你的 EO 浏览器窗口中模拟)。

既然我们有了更好的了解,我们就可以推断火灾发生时老虎的藏身之处。

Al-Hassan hideout (left) and Aleppo thermal plant (right) on google maps

为了证实我们的怀疑,我们可以检查谷歌地图卫星图像,并了解到藏身之处已被炸毁。

冲突、安全、武器和数字取证领域的开源专家 Benjamin Strick 解释说,这确实有助于显示当时哪座大楼着火了。后来,哈桑在工厂里的照片证实了这一点:那天那四座塔着火了。

从太空中观察某些地方的具体细节有其优点。事实上,是在人权领域。最近的一项调查显示卫星图像有助于从太空揭示奴隶制。英国诺丁汉大学权利实验室数据项目主任 Doreen Boyd 估计,三分之一的奴隶制将在太空中可见——无论是以窑的疤痕形式,还是以非法矿场或短暂的鱼类加工营地的轮廓形式(可以说,高分辨率的商业图像可能更适合这种调查)。

3.高级-运行算法

水位提取

让我们假设你正在报道水位下降的情况,可能会报道由此引发的冲突(根据最近的研究,缺水导致的紧张局势和冲突越来越有可能发生,这一点已被《经济学家》特别报道)报道过。

使用 Sentinel-2 多光谱和多时相图像制作了一个 Jupyter 笔记本*来探测水体的水位。

我们将在 python 中运行水检测算法,并在给定的时间间隔内提取单个水库的地表水位。

你要做的是:

  1. 定义一些水体的几何形状
  2. 准备并执行水探测的完整工作流程:使用 SentinelHub 服务下载 Sentinel-2 数据(真彩色和 NDWI 指数),使用 s2cloudless 云探测器进行云探测,最后探测水
  3. 可视化一段时间内的水体和水位
  4. 过滤掉多云的场景以改善结果

你需要什么?

  • EO-learn—https://github.com/sentinel-hub/eo-learn
  • 水观测站后端-【https://github.com/sentinel-hub/water-observatory-backend T2

基本终端/文件设置:

和前面的例子一样:之前,为了运行它,您还需要一个 Sentinel Hub 帐户。您可以在 Sentinel Hub 网页创建一个免费试用账户。帐户设置好后,登录 Sentinel Hub Configurator 。默认情况下,您已经拥有了带有实例 ID (长度为 36 的字母数字代码)的默认配置。对于本教程,我们建议您创建一个新的配置("Add new configuration")并将配置设置为基于 Python 脚本模板。这种配置将已经包含这些示例中使用的所有层。否则,您必须自己为您的配置定义层。准备好配置后,请按照配置说明将配置的实例 ID 放入sentinelhub包的配置文件中。

通过加载以下 Python 库来设置 Python 工作环境。确保按照上面的说明运行 Python 虚拟环境

获得水体的几何形状

让我们以南非的 Theewaterskloof 大坝为例——这个巨大的水资源储备为开普敦 400 万居民中的大部分人提供了宝贵的资源。它是西开普省供水系统中最大的水坝,在干旱时水量会减少。有迹象表明人们对水资源短缺的意识增强了。如何覆盖这样一个话题说明了这个例子。

在the waters kloof Dam或地球上任何其他大型水体的情况下,你可以通过BlueDot Water ObservatoryAPI 轻松获得几何图形。

通过搜索特定水体,您可以复制 URL 中的ID号,以便访问相应水体的标称几何形状(即 url [https://water.blue-dot-observatory.com/38538/2019-02-05](https://water.blue-dot-observatory.com/38538/2019-02-05))中的38538号 ))

The BlueDot Water Observatory

用于下载几何图形的 Python 代码:

现在,为了下载 Sentinel-2 数据,我们需要这个几何体的边界框。我们定义了一个边界框,并对其进行了一点膨胀,以构建一个 BBox 对象,用于 Sentinel Hub 服务。BBox 类也接受坐标系(CRS),这里我们使用与几何图形相同的坐标系(即 WGS84 )。

Plotting the BBox and the geometry

准备/执行水检测的完整工作流程

哨兵枢纽服务安装有eo-learn。它是 Python 中用于机器学习的开源地球观测处理框架,提供无缝访问和处理任何卫星舰队获取的时空图像序列的能力。

eo-learn以工作流的形式工作——工作流由一个或多个任务组成。每个任务完成一个特定的工作(下载数据,计算波段组合等。)在一个区域的一小片上,叫做 EOPatch。EOPatch 是 EO 和非 EO 数据的容器。

让我们定义一个工作流来下载和获取水检测所需的数据。我们将下载 RGB 波段,以便实际可视化水体的真彩色图像。此外,我们将下载NDWI波段组合(归一化差异水体指数),用于水体检测。它被定义为

Formula for Normalized Difference Water Index

其中 B3 和 B8 分别是绿色和近红外哨兵-2 波段。

**Next: Definitions of some custom tasks that will be used in the workflow**
**Initializations of EOTasks:**
Output: Finished loading model, total used 170 iterations
Output: CPU times: user 3min 9s, sys: 14.7 s, total: 3min 24s
Wall time: 3min 23s

“EO patch”的结构

通过键入来检查结构

Input: eopatch

现在让我们来看一下给定时间序列中所选水体的前几张真彩色图像。我们在下面看到一些图像包含云,这导致了正确的水位检测问题。

**Plot the NDWI to see how the water detector traces the waterbody outline:**

Plotting of Normalized Difference Water Index

**Plot true-color images with the detected water outlines:**

Clear as day: comparing true water levels with Theewaterskloof Dam dam’s outline

**Plotting the detected water levels**

由于云的干扰,您应该会看到数据中有很多波动(灰色表示云的覆盖范围。它与水位异常值共享相同的日期)。

现在让我们设定一个最大云量为 2 %的阈值,并过滤掉对应于多云场景的日期。这是通过过滤掉值eopatch.scalar['COVERAGE']大于 0.02 的日期来完成的。

A lot less vacillating

瞧,这就是 T2。水位在 2018 年年中创下三年来的历史新低,但此后逐渐恢复。

结论:

仍然渴望更多的卫星图像分析?我在这里介绍了一些与经济夜灯分析相关的基本技术(它充当了经济增长的代理)。99 . Gisgeography.com 汇集了其他应用设想,列举如下。请自便。

c

本教程由一名调查记者撰写,并得到了 Matic Lubej 在 @sinergise 、 的数据科学家、遥感布道者 Pierre MarkuseBenjamin Strick的友好支持,Benjamin Strick 是 BBC 的一名开源调查员,也是 EUArms 工作室的讲师。

如何使用光学字符识别进行安全系统开发

原文:https://towardsdatascience.com/how-to-use-optical-character-recognition-for-security-system-development-9dc57258afa3?source=collection_archive---------14-----------------------

用于身份证件数据识别的深度学习和计算机视觉。

将机器学习技术应用于安全解决方案是当前 AI 趋势之一。本文将介绍使用深度学习算法开发基于 OCR 的软件的方法。该软件可用于分析和处理身份证明,如美国驾照,作为验证身份的安全系统的一部分。

机器学习公司已经在使用 OCR(光学字符识别)技术进行业务流程自动化和优化,使用案例从 Dropbox 使用它解析图片到谷歌街景识别不同的街道标志到搜索短信和实时翻译文本。

在这种特殊情况下,OCR 可以用作自动化
生物特征验证系统的一部分。该解决方案使用自拍照片,并与包含从驾驶执照中提取的面部特征(面部嵌入)的数据库进行比较。

OCR 过程使用以下数据:

  • 一张与官方身份照片对比的自拍照。
  • 驾照正面的照片,用于检测脸部。
  • 包含条形码的驾驶执照背面的图片,我们从中获取数据,如出生日期、姓名和其他字段。

在 beta 测试中,很明显用户能够欺骗验证过程。一种方法是传递来自多个文档的图片。用户展示的第一张照片是有效的身份证明,但第二张背面的照片包含虚假信息。对于任何现实世界的实施来说,欺诈企图都是已知的,并且已经创建了一个独立的验证系统来防止欺骗企图。它交叉检查代表 ID 两侧的两张图片,以确认匹配或标记差异。

决定最佳 OCR 解决方案

一旦阐明了用例的范围,我们就开始使用光学字符识别 SDK 和 API。OCR 解决方案有多种形式,从开源到商业的现成解决方案。

人们可能会认为简单的方法是最好的,在这种方法中,可以实现顶级的商业 OCR 解决方案来读取图片并处理相关信息。但是这并不是一个有效的方法。

OCR 的用户友好性和安全性问题

一个重大挑战是,身份证上的照片和自拍照片有时会有明显的定位和质量差异。这是用不同的相机和工艺拍摄不可避免的后果。

如果系统在查找匹配时要求高的准确性阈值,大量合法的照片将被拒绝,这可能导致用户体验的问题。需要在保持高安全标准的同时将错误拒绝保持在最低限度之间取得平衡。

解决这个问题的一个方法是提高用户提交的自拍照的质量。通过创建一个平滑的用户界面/UX 体验以及一套易于遵循的拍照说明,自拍照片的质量可以大大提高。

一旦用户提交的图片变得标准化,就有可能在用户友好性和安全性之间取得更好的平衡。虽然许多基于计算机视觉的 OCR 解决方案可以被描述为一个“黑盒”,但这个解决方案需要原始数据才能运行。

驾照数据识别的挑战

美国的每个州都会创建一个独特的驾照格式,这些格式会定期更改。因此,不可能简单地预先生成用于解析许可证的模板。另一个障碍是驾照照片的质量经常很差。任何使用它们的 OCR 解决方案都必须考虑这些问题。

任何使用 CV 和 ML 的 OCR 系统都会产生错误。对于这个系统,有必要创建一个安全可靠的解决方案,能够处理与 OCR 组件配对的低质量图片。因此,DS 和软件工程团队都参与了开发过程。

为了规划任何基于人工智能的解决方案的开发,有必要回答几个基本问题。首先,强制性的数据要求是什么,可用数据的使用方式是什么?

我们开始对大约 150 个 id 和 100 个驾照进行数据挖掘,这些数据来自现有的公开数据集和我们收集的数据。

在初始阶段,对现有的开源和商业 OCR 系统进行了比较和评估。选择了最适合的 OCR 解决方案的短列表,并使用真实数据集对这些系统进行了评估。

研究过程中跟踪的指标是出生日期、姓名和姓氏的直接匹配,谷歌视觉是这一过程的自然选择。

评估大型开放数据集

另一种方法可能是尝试用书籍扫描或包含文本的图片来处理大型开放数据库。然而,这种方法不适合处理驾照的独特任务。考虑到驾照模板的可变性以及随之而来的低质量照片,许多原本适用的 OCR 解决方案根本无法胜任这项任务。需要完美对齐的文本和优秀图片才能运行的 OCR 解决方案在这方面将会失败。

解析驾照和其他 id 的实际任务给出了解决方案适用性的最真实指标。最佳数据集是根据目标受众的任务专门收集的数据集。

实现 OCR 引擎

符合数据安全的 OCR 解决方案需要一种结合 ds、ML 和软件工程的方法。

一个主要挑战是处理 Google Vision 提供的原始数据,并以 100%的准确度将其与条形码提供的数据进行交叉引用。虽然谷歌的 OCR 系统是行业顶级的,但错误是不可避免的。虽然许多情况下允许出现错误,但在与安全相关的领域中,这些错误不会出现。这种 OCR 解决方案需要额外的安全层来挫败利用 OCR 的局限性进行欺诈的企图。

对机器可读区的额外关注

MRZ(机器可读区)是任何旅行证件的一部分,具有清晰的数据字段,无论是数字还是字母。MRZ 还会有校验位,以确保数据被准确解析。

然而,即使使用谷歌视觉,MRZ 识别能够达到的准确度值也远低于 100%。因此,有必要创建一个额外的数据交叉检查流程。

OCR 在读取数据时容易犯一些常见的错误。一个例子是符号“1,l,I,I”和“O,D,Q,0”。这些符号在物理上是相似的,可能会被引擎错误分类。通过收集历史错误数据,可以构建一个组件来纠正 OCR 系统造成的错误。

总之,使用 OCR 的四个技巧:

  1. 首先确定系统需要能够实现的所有用例以及业务目标。这推动了您选择工具和系统架构的方法。
  2. 了解您的数据并使用尽可能多的真实数据至关重要。
  3. 一旦理解了数据的基本原理,您就可以做出明智的决定,决定是使用商业数据集还是开放数据集。
  4. 在训练神经网络和创建自定义数据科学模型时,最好在较小的数据集中使用更相关的数据。虽然使用大规模数据集可能看起来很有吸引力,但如果它不能很好地反映您最终的真实数据,您的结果将是无效的。
  5. 基于深度学习的 OCR 可以作为初步工具,将提供的信息与用户文档进行比较开发多模态生物特征认证系统。

如何以正确的方式使用熊猫来加速你的代码

原文:https://towardsdatascience.com/how-to-use-pandas-the-right-way-to-speed-up-your-code-4a19bd89926d?source=collection_archive---------9-----------------------

Just a Panda, chillin'

想获得灵感?快来加入我的 超级行情快讯 。😎

熊猫图书馆对数据科学界来说是一份天赐的礼物。问任何一个数据科学家他们喜欢如何用 Python 处理他们的数据集,他们无疑会谈论熊猫。

Pandas 是一个优秀编程库的缩影:简单、直观、功能广泛。

然而,在熊猫数据帧上进行数千甚至数百万次计算,这是数据科学家的常规任务,仍然是一个挑战。你不能只是把你的数据扔进去,写一个 Python for-loop,然后期望你的数据在合理的时间内得到处理。

Pandas 是为一次处理整行或整列的矢量化操作而设计的——遍历每个单元格、行或列根本不是该库的设计用途。因此,当使用 Pandas 时,你应该从高度并行化的矩阵 运算的角度考虑问题。

本指南将教你如何使用熊猫的设计方式,并根据矩阵运算进行思考。在这个过程中,我将向您展示一些实用的节省时间的技巧和诀窍,它们将使您的熊猫代码运行得比那些可怕的 Python for-loops 快得多!

我们的设置

在整个教程中,我们将使用经典的鸢尾花数据集。让我们开始用 seaborn 加载数据集,并打印出前 5 行。

厉害!

现在让我们建立一个基线,用 Python for-loop 来测量我们的速度。我们将通过循环遍历每一行来设置要在数据集上执行的计算,然后测量整个操作的速度。这将为我们提供一个基线,看看我们的新优化对我们有多大帮助。

在上面的代码中,我们创建了一个基本函数,使用 If-Else 语句根据花瓣长度选择花的类别。我们编写了一个 for 循环,通过遍历数据帧将函数应用于每一行,然后测量循环的总运行时间。

在我的 i7–8700k 的机器上,在 5 次运行中,循环平均花费了 0.01345 秒。

循环使用。iterrows()

我们可以马上做的最简单但非常值得的加速是使用 Pandas 内置的.iterrows()功能。

当我们在前一节中编写 for 循环时,我们使用了range()函数。然而,当我们在 Python 中循环大量的值时,生成器往往要快得多。你可以在本文这里阅读更多关于发电机如何工作并使事情变得更快的信息。

Pandas 的.iterrows()函数在内部实现了一个生成器函数,它将在每次迭代中yield一行数据帧。更准确地说,.iterrows()为数据帧中的每一行生成(index,Series)对(元组)。这实际上与在原始 Python 中使用类似于enumerate()的东西是一样的,但是运行起来要快得多

下面我们修改了代码,使用.iterrows()代替常规的 for 循环。在我在上一节中用于测试的同一台机器上,平均运行时间是 0.005892 秒——加速了 2.28 倍!

完全丢弃循环。应用()

这个.iterrows()函数让我们的速度有了很大的提升,但是我们还远远没有完成。永远记住,当使用一个为向量运算设计的库时,可能有一种完全不用 for 循环就能最有效地做事的方法。

为我们提供这种能力的 Pandas 函数是.apply()函数。我们的函数.apply()将另一个函数作为其输入,并沿着数据帧(行、列等)的轴应用它。在我们传递函数的情况下,lambda 通常可以方便地将所有东西打包在一起。

在下面的代码中,我们用.apply()和一个 lambda 函数完全替换了我们的 for 循环,以打包我们想要的计算。在我的机器上,这段代码的平均运行时间是 0.0020897 秒,比我们原来的 for 循环快了 6.44 倍。

.apply()快得多的原因是它在内部试图循环遍历 Cython 迭代器。如果你的函数恰好针对 Cython 进行了优化,.apply()将会给你带来更大的速度提升。额外的好处是,使用内置函数会产生更干净、更易读的代码

最终剪辑

之前我提到过,如果你正在使用一个为矢量化运算设计的库,你应该总是寻找一种不使用 for 循环的方法来进行任何计算。

类似地,许多以这种方式设计的库,包括 Pandas,将有方便的内置函数来执行你正在寻找的精确计算——但要快得多。

Pandas 的.cut()函数将一组定义 If-Else 的每个范围的bins和一组定义每个范围返回哪个值的labels作为输入。然后,它执行与我们用compute_class()函数手动编写的完全相同的操作。

查看下面的代码,看看.cut()是如何工作的。我们再次得到了更干净、更易读的代码的好处。最终,.cut()函数平均运行时间为 0.001423 秒——比原来的 for-loop 快了 9.39 倍!

喜欢学习?

在推特上关注我,我会在这里发布所有最新最棒的人工智能、技术和科学!也请在 LinkedIn上与我联系!

如何用熊猫分析数值型数据?

原文:https://towardsdatascience.com/how-to-use-pandas-to-analyze-numeric-data-9739e0809b02?source=collection_archive---------10-----------------------

这比你想象的要容易得多。

Python 已经成为数据科学领域一种流行的编程语言。Pandas 是数据科学中许多受欢迎的库之一,它提供了许多帮助我们转换、分析和解释数据的强大功能。我确信已经有太多的教程和资料教你如何使用熊猫。然而,在这篇文章中,我不仅仅是教你如何使用熊猫。相反,我想用一个例子来演示如何在熊猫的帮助下正确流畅地解读你的数据。

熊猫大战熊猫

Photo by Ilona Froehlich on Unsplash

在我们开始之前:

  1. 准备一个 python 环境

  2. 从 Kaggle 下载数据集

  3. 进口熊猫

  4. 准备一个 python 环境

既然我们使用 Python 来分析数据,当然首先我们需要安装 Python。对于初学者,我强烈建议您安装 Anaconda,因为 Anaconda 已经预装了一系列对数据科学非常有用的库。你不需要关心编译器或 IDE。

这里是免费下载 Anaconda 发行版的链接

去下载

Jupyter Notebook 是一个很好的数据分析工具,因为你可以一部分一部分地看到结果,这样你就可以知道结果是否是你预测的,你也可以立即知道你是否犯了任何错误。

Jupyter Notebook in Anaconda Distribution

启动 Jupyter Notebook 后,会弹出一个网页,你会看到这样的页面。您可以选择并创建存储文件的路径。在右边,有一个“新建”按钮。单击此处创建文件夹或 Python 文件。

Jupyter 笔记本提供的有用功能和快捷方式太多了。我在这里不做详细描述和解释。另外,我希望你已经掌握了一些编写 Python 代码的基础知识,因为这不是对 Python 的介绍。不管怎样,如果你有任何问题,请随意评论,我会解决你的问题。

2.从 Kaggle 下载数据集

本文将使用的数据集来自 Kaggle。该数据集包括 1985 年至 2016 年不同国家的自杀率及其社会经济信息。

下载链接

3.进口熊猫

最后准备,进口熊猫

通常我们会给每个库一个缩写。你可以跳过这一步,但每次当你想使用任何功能时,你必须输入完整的名称。所以为什么不给它一个简短的缩写。

虽然这篇文章关注的是使用熊猫,但是我们仍然需要 numpy 的帮助,所以我们也将导入 numpy。

我们开始吧

第一步是导入我们从 Kaggle 下载的数据集。虽然您可以从任何路径导入数据,但我的建议是将所有数据和代码放在一起,这样您就不需要键入确切的路径,而只需键入文件名。下载的文件名是“master.csv”。所以我们知道数据集是 csv 文件类型。其他常见的文件类型包括 excel 文件和 json。

熊猫我们用的第一个熊猫函数是 read_csv。称为数据的数据帧是通过以下方式创建的:

data= pd.read_csv('master.csv')

我们可以使用它将 csv 文件导入到 python 中,并将其存储为数据帧。Dataframe 就像一个 excel 表格。

通常情况下,pandas 会自动解释数据集并识别所有必要的参数,以便正确导入数据集。但是,如果您发现输出不像您期望的那样,您可以手动更改参数。以下是使用 read_csv 时可以修改的一些常见参数:

  1. sep:用于分隔变量间值的分隔符。默认使用逗号','。您可以更改 sep,如下所示
data = pd.read_csv('master.csv', sep = ';')

2.header:通常 csv 文件的第一行显示所有变量的名称。但是,如果在 csv 文件中没有这样的名称行,最好告诉 pandas 没有标题

header = None

现在您已经导入了数据集。如前所述,您可以在运行代码后直接看到结果。让我们来看看数据集

data

我希望你会得到和我一样的结果。现在当你向下滚动时,你可以看到一个数字,但不是所有的记录。如果您不想显示这么多记录,您可以通过键入来显示一些顶部或底部的记录

data.head(5) # showing top 5 records from the dataframe# ordata.tail(5) # showing bottom 5 records from the dataframe

在进行任何分析之前,了解数据集是必要的,因为首先这将使您有一个简要的了解,其次这将防止您在分析时产生误解。

导入后您可能会问的第一个问题是数据集中有多少条记录。幸运的是,您可以通过一行代码得到答案。

data.shape

第一个数字(index 0,python 从零开始)显示了行数,第二个数字(index 1)显示了列数。因此数据集有 27,820 行和 12 列。

你可能会问的第二个问题是这 12 列是什么。有很多方法可以显示列名。但是我最喜欢的是用

data.info()

info()不仅为您提供数据帧中的所有列名,还为您提供存储在该数据帧中的数据类型。此外,您可以知道数据帧中是否有丢失的值。如上所示,number 列显示了该变量中有多少个非空计数。除人类发展指数外,这一年的所有指数都是 27,820。因此,至少我们知道导入的数据集中有缺失值。

现在你想知道这个数据帧里有什么数据。例如,在那些几乎 28k 的记录中有多少个国家?你想得到所有国家的列表。您可以通过以下方式获得每列的值

data['country']

但是这将返回没有重复数据删除的所有值。如果你想得到一个独一无二的国家,我最喜欢的方法是使用 set 函数。Set 函数将只返回一个没有重复的唯一值列表。

总共有多少个国家?

总共有 101 个国家。

然后你想知道每年自杀的人数。在 Excel 中,您可以通过透视表来执行此操作。熊猫也有类似的功能,叫做 pivot_table。假设你现在使用 excel 数据透视表来计算自杀人数。您将把 year 拖到行标签上,并将 sudience _ no 拖到 Values 上

如果您熟悉 excel 数据透视表,那么请记住与 pandas pivot_table 相同的格式。

data.pivot_table(index='year',values='suicides_no',aggfunc='sum')

哦,你也想分解成性?

data.pivot_table(index='year',columns='sex',values='suicides_no',aggfunc='max')

这里的“index”表示要放在行标签中的变量;“columns”表示列;“值”表示数据透视表中的数字。就像 excel 一样,你可以计算总和、平均值、最大值或最小值。

data.pivot_table(index='year',columns='sex',values='suicides_no',aggfunc=['sum','mean','max','min'])

您还可以对行或列执行多重索引。

data.pivot_table(index=['country','year'],columns='sex',values='suicides_no',aggfunc=['sum'])

通过使用数据透视表,我们可以根据不同的变量了解数据集的一般分类。您还可以发现数据集中的任何异常,这可能有助于您进一步的分析。就像下面这样:

data.pivot_table(index=['year'],columns='sex',values='suicides_no',aggfunc=['sum'])

2016 年发生了什么?为什么会突然下降?

现在你想检查数据集,看看 2016 年会发生什么。在 pandas 中,您需要指定要返回的行和列。这可以通过提供索引号或名称或标准来实现。现在的标准是 2016 年。您可以通过以下方式获得结果

data[data['year']==2016]

如何解读这行代码?

有两部分。内部分“数据['年份']==2016”是需要满足的条件。这里表示数据中的年份列必须是 2016 年。小心有两个等号,代表比较。类似地,你可以有一个更大、更小或不相等的条件

data['year'] >= 2016 # larger than or equal to 
data['year']!=2016 # not equal to

条件多,没问题。但是,如果你想满足全部或其中一个条件,请确保你明确说明。

# year must be larger than 2010 and smaller than 2015
(data['year'] > 2010) & (data['year']<2015)# year can be larger than 2010 or smaller than 2000
(data['year'] > 2010) | (data['year']<2000)

外部部分“data[…]”表示返回内部部分中满足条件的所有行。回到示例,我们希望返回年份等于 2016 年的所有行。

似乎没问题。但如果算上 2016 年和 2015 年的国家数量,问题就出现了。

现在,我们想从数据集中获取列 country,其年份必须是 2016 年。最简单的方法是用

data[data['year']==2016]['country']

然后再次使用 set 和 len 函数计算 2016 年的国家数量。

len(set(data[data['year']==2016]['country']))

在 2015 年做同样的事情。我们来了

2016 年的数据显然不完整,因此我们不应将 2016 年与其他年份进行比较。所以我们最好删除 2016 年的所有记录。

如上所述,我们可以应用一个条件来过滤 2016 年的记录,如下所示:

data2= data[data['year']!=2016]

现在,我们创建另一个名为“data2”的数据帧,用于进一步分析。

找到哪些变量与数据集相关至关重要,因为这可以帮助您发现哪些变量会导致结果的变化。例如,在数据集中有一些分类变量:

国家、年份、性别和世代

选一个简单的,比如性。你可以比较一下每种性别的总自杀人数。如果差异很大,那么性别是导致自杀差异的一个因素

当然,我们可以使用 pivot_table 函数来实现。但是我在这里介绍另一个功能,groupby。如果你有使用 SQL 的经验,我相信你对 group by 很熟悉。

data2.groupby('sex').agg({'suicides_no':'sum'})

就 SQL 而言,上述语句相当于:

select sex, sum(suicides_no) from data2 group by sex

Python 将首先根据“性别”列中的值对所有记录进行分组。之后 python 会计算每组‘性’的自杀总数。

男性自杀率远高于女性自杀率。这时,我们可以相当肯定,性别是影响自杀人数的一个因素。

groupby 的高明之处在于,您可以再次将数据集分成更多级别。请记住,当您包括多个级别时,您需要使用方括号[ ]向熊猫提供一个列表。

data2.groupby(['sex','generation']).agg({'suicides_no':'sum'})

此外,就像 SQL 一样,您可以在 groupby 函数中执行多个聚合。

data2.groupby(['sex']).agg({'suicides_no':['sum','max']})

或者

data2.groupby(['sex']).agg({'suicides_no':'sum', 'population':'mean'})

现在我们知道性是一个因素。那年龄呢?

data2.groupby(['age']).agg({'suicides_no':'sum'})

所以自杀最流行的年龄范围是 35-54 岁。对吗?

不完全是。不像性是一半一半,每个年龄组的人口都不均匀。这是一种常见误解,因为不同的类别有不同的人口规模或基数。

因此,为了更好地进行比较,我们应该更好地比较每个总人口的自杀人数。为了在熊猫中做到这一点,首先创建另一个数据框架来存储每个年龄层的自杀人数和人口。然后计算一个除法,得到每个年龄段的平均自杀人数。

# create a dataframe called data_age for age groupby 
data_age = data2.groupby([‘age’]).agg(
{‘suicides_no’:’sum’,’population’:’sum’})# calculate average of suicide number for each age group 
data_age[‘suicides_no’]/data_age[‘population’]

代码的第一部分与前面类似。第二部分是执行除法。python 的好处是可以将计算作为一整列来执行,而不是像 excel 那样逐个单元格地执行。所以我们把自杀人数一栏和人口一栏分开。

现在结果不同了。随着年龄的增长,自杀的情况变得更糟。

这时,你可能会说排名不明确,你想根据平均自杀人数来排列结果。那么是时候引入 sort_values 函数了。

(data_age['suicides_no']/data_age['population']).sort_values()

因为这里只有一列,所以我们不需要指定按哪一列排序。但是,如果数据帧中有多列,则必须指定哪一列。此外,默认顺序是升序,您可以通过在括号内添加 ascending = False 来更改它。就像下面这样:

(data_age['suicides_no']/data_age['population']).sort_values(ascending=False)

现在你可以很容易地看到随着年龄增长的趋势。

我们已经研究了性别和年龄的影响。现在我们转到乡下。我们可以找到哪个国家更流行自杀。

第一步是创建一个表格,包括各国自杀人数和人口。这可以通过使用 groupby 函数来完成。

data_country = data2.groupby(['country']).agg({'suicides_no':'sum','population':'sum'})

在这里,我们不关心是否所有国家都有相同数量的记录,因为我们正在计算一段时间内的平均数。

然后我们用自杀人数除以人口来计算平均自杀人数。

data_country['average_suicide'] = data_country['suicides_no']/data_country['population']

这里我们创建了一个名为“average_suicide”的新列,它将存储除法结果。稍后使用 sort_values 函数以降序获得结果。我们可以使用 head 函数只显示前 N 个国家,而不是显示所有国家

data_country.sort_values(by='average_suicide',ascending=False).head(10)

从结果中,我们可以看到大多数国家在东欧。那么你可以说地理位置也是影响自杀的一个指标。

今天到此为止。我希望你不仅能学会如何使用 Python,还能学会如何处理数据集,从而得出更好、更准确的结论。

欢迎评论,这样我就知道如何改进和写一个更好的博客。如果你喜欢,就鼓掌,分享给和你一样同样有需要的人。下次见。

如何将 Pipenv 与 Jupyter 和 VSCode 一起使用

原文:https://towardsdatascience.com/how-to-use-pipenv-with-jupyter-and-vscode-ae0e970df486?source=collection_archive---------4-----------------------

Activating the right environment in VSCode for Jupyter Notebook

更新 2021

本文写于 2019 年。在多年的开发过程中,我遇到了 pipenv 设置的各种问题。我将环境和依赖管理改为使用一个 conda 环境和一个带有 pip-compile 的需求文件。在我的新文章“如何开始一个数据科学项目”https://towards data science . com/How-to-start-a-data-science-project-boilerplate-in-2021-33d 81393 e50中描述了我的最新设置

如果你还想用 pipenv,那么这篇文章应该还是有价值的。享受吧。

介绍

目前,我在 JKU 大学学习人工智能,对于一些练习,我们需要使用 jupyter 笔记本。使用 Python 一点点之后,包管理器 pipenv 被证明是有价值的。现在,我在 Jupyter 笔记本和 VSCode 中使用它时遇到了一些问题。因此,一个简短的指导我如何解决它。

目录

  • 问题
  • 在浏览器中使用 Jupyter 笔记本开发
  • 在 VSCode 中用 Jupyter 笔记本开发
  • 关于

问题

正如我在上一篇文章使用 Jupyter 和 VSCode 中所描述的,我使用 pyenv 和 pipenv 来管理我的 python 开发中的所有包。我还参考了一些文章,为什么这种方式是有帮助的,易于使用。现在,有必要再深入一点。有两种方法可以让你用 jupyter notebook 进行开发。您可以直接在浏览器中或在 VSCode 中使用它。在这两种用例中,都会出现问题。

在浏览器中用 Jupyter 笔记本开发

Jupyter Notebook in the browser

假设您的系统上已经有了合适的 python 环境,现在您想为一个项目创建一个特定的环境。

  1. 首先,创建一个 Pipenv 环境。
  2. 确保导航到正确的目录。
  3. 使用pipenv install <packages>来安装你所有的软件包。
  4. 然后用pipenv shell激活你的外壳。
  5. 然后用pipenv install jupyter,之后用pipenv run jupyter notebook

现在 jupyter 服务器已经启动,您的笔记本将可以访问正确的环境。

Activating the right environment for Jupyter notebook in the browser

在 VSCode 中用 Jupyter 笔记本开发

Jupyter Notebook in VSCode

现在来看看 VSCode 中的工作流。在这里,了解不同的 shells 是很重要的。我经常使用单独的终端(iterm2 ),有时激活的 shell 无法被 VSCode 识别,或者您位于错误的目录中,或者它没有被激活。所有这些都会带来问题。因此我的工作流程如下:

  1. 首先,创建一个 Pipenv 环境。
  2. 确保导航到正确的目录。
  3. 使用pipenv install <packages>来安装你所有的软件包。
  4. 然后,确保在 vscode 文件夹中有一个正确的设置文件,其内容如下:
{"python.venvPath": "${workspaceFolder}/.venv/bin/python","python.pythonPath": ".venv/bin/python",
}
  • 之后,您可以在 VSCode 中选择合适的 python 环境。(应该是用 Pipenv 创建的!)现在,python 文件可以识别正确的环境。

通常这对于 VSCode 应该足够了,你可以在其中启动 Jupyter 服务器。

但是有时你改变了环境,或者设置文件有问题。如果是这种情况,您需要打开 VSCode 终端并运行pipenv shell来激活 shell。(检查是否仍在 VSCode 中选择了正确的环境):

Activating the right environment in VSCode for Jupyter Notebook

现在打开。ipynb 文件,您将能够运行单元格,而不会得到错误"... was not able to start jupyter server in environment xxx"

如果有帮助,或者在 VSCode 和 Jupyter Notebook 中使用 Pipenv 有其他问题或解决方案,请告诉我。

You can support me on https://www.buymeacoffee.com/createdd

关于

我认为自己是一个解决问题的人。我的强项是在复杂的环境中导航,提供解决方案并分解它们。我的知识和兴趣围绕商业法和编程机器学习应用发展。我在构建数据分析和评估业务相关概念方面提供服务。

接通:

  • 领英
  • Github
  • 中等
  • 推特
  • Instagram

如何在数据分析项目中使用 Python 特性

原文:https://towardsdatascience.com/how-to-use-python-features-in-your-data-analytics-project-e8032374d6fc?source=collection_archive---------11-----------------------

使用 OO,NumPy,pandas,SQL,PySpark 的 Python 教程

1.介绍

许多公司正在向云迁移,并考虑应该使用什么工具进行数据分析。在内部,公司大多使用专有软件进行高级分析、商业智能和报告。然而,这种工具在云环境中可能不是最合理的选择。原因可能是 1)缺乏与云提供商的集成,2)缺乏大数据支持,或者 3)缺乏对机器学习和深度学习等新用例的支持。

Python 是一种通用编程语言,广泛用于数据分析。几乎所有的云数据平台都提供 Python 支持,并且通常新特性首先在 Python 中可用。在这方面,Python 可以被视为数据分析的瑞士军刀。

1. Python as Swiss Army knife for data analytics

2.目标

在本教程中,创建了两个考虑到 Python 重要特性的项目。项目描述如下:

  • 在第一个项目中,在 Azure 中的数据科学虚拟机(DSVM)上执行 Jupyter 笔记本。面向对象(OO)类是使用数据的继承、重载和封装创建的。随后,NumPy 和 pandas 用于数据分析。最后,数据存储在 DSVM 上的数据库中。
  • 在第二个项目中,Databricks 笔记本在具有多个虚拟机的 Spark 集群上执行。PySpark 用于创建机器学习模型。

因此,将执行以下步骤:

  • 3.先决条件
  • 4.DSVM 上带有 Jupyter 的 OO、NumPy、pandas 和 SQL
  • 5.Spark 集群上带有 Azure 数据块的 PySpark
  • 6.结论

这是一个独立的教程,重点是学习 Python 的不同方面。重点不在于“深入”各个方面。如果你对深度学习更感兴趣,请参见这里或在 devops for AI,参考我以前的博客,这里和关注安全,请参见这里。

3.先决条件

需要创建以下资源:

  • 数据科学虚拟机(第四部分)
  • Azure Databricks 工作区(第五部分)

4.DSVM 上带有 Jupyter 的 OO、NumPy、pandas 和 sql

在这一部分中,一个包含三个类的示例 Python 项目。使用这些类,足球运动员的数据被登记。执行以下步骤:

  • 4a。开始
  • 4b。面向对象编程
  • 4c。使用 NumPy 的矩阵分析
  • 4d。使用熊猫进行统计分析
  • 4e。读取/写入数据库

4a。开始

登录到您的 Windows 数据科学虚拟机(DSVM)。在桌面上,可以找到预装组件图标的概述。点击 Jupyter 快捷方式开始 Jupyter 会话。

4a1. preinstalled components on DSVM needed in this tutorial

随后,打开可以在任务栏中找到的 Jupyter 命令行会话。复制 URL 并在 Firefox 会话中打开它。

4a2. Localhost URL to be openen in Firefox

然后将以下笔记本下载到 DSVM 的桌面上:

[https://raw.githubusercontent.com/rebremer/python_swiss_army_knife/master/SwissArmyKnifePython.ipynb](https://raw.githubusercontent.com/rebremer/python_swiss_army_knife/master/SwissArmyKnifePython.ipynb)

最后,选择在 jupyter 会话中上传笔记本。然后点击菜单中的运行按钮,运行单元格中的代码。笔记本最重要的部分也将在本章的剩余部分讨论。

4b。面向对象编程

这部分教程的灵感来自 Theophano Mitsa 的教程。在这一部分中,创建了三个类来跟踪足球运动员的数据。一级球员的片段可以在下面找到:

# Class 1: Player
class Player(object):_posList = {'goalkeeper', 'defender', 'midfielder', 'striker'}def __init__(self,name):self._playerName=nameself._trainingList=[]self._rawData = np.empty((0,3), int)def setPosition(self, pos):if pos in self._posList:self._position=posprint(self._playerName + " is " + pos)else:raise ValueError("Value {} not in list.".format(pos))        def setTraining(self, t, rawData):self._trainingList.append(t)self._rawData = np.append(self._rawData, rawData, axis=0) def getTrainingRawData(self):return self._rawData #def getTrainingFilter(self, stage, tt, date):# see github project for rest of code

在这个类中可以看到以下内容:

  • 一个 _rawData 属性在新玩家被实例化时被创建。该属性用于用 setTraining 方法封装训练数据
  • _rawData 被创建为受保护的变量。这告诉程序员应该使用 get 和 set 方法来处理 _rawData

随后,可以在下面找到 FirstTeamPlayer 类:

# Class 2: FirstTeamPlayer
class FirstTeamPlayer(Player):def __init__(self,ftp):Player.__init__(self, ftp)def setPosition(self,pos1, pos2):if pos1 in self._posList and pos2 in self._posList:self._posComp=pos1self._posCL=pos2print(self._playerName + " is " + pos1)print(self._playerName + " is " + pos2 + " in the CL")else:raise ValueError("Pos {},{} unknown".format(pos1, pos2))   def setNumber(self,number):self._number=numberprint(self._playerName + " has number " + str(number))

在这个类中可以看到以下内容:

  • FirstTeamPlayer 从 Player 类继承了,这意味着 Player 类的所有属性/方法也可以在 FirstTeamPlayer 中使用
  • 方法 setPosition 在 FirstPlayerClass 中被重载,并有了新的定义。方法 setNumber 仅在 FirstPlayerClass 中可用

最后,可以在下面找到培训课程的一个片段:

# Class 3: Training
class Training(object):_stageList = {'ArenA', 'Toekomst', 'Pool', 'Gym'}_trainingTypeList = {'strength', 'technique', 'friendly game'}def __init__(self, stage, tt, date):if stage in self._stageList:self._stage = stageelse:raise ValueError("Value {} not in list.".format(stage))if tt in self._trainingTypeList:self._trainingType = ttelse:raise ValueError("Value {} not in list.".format(tt))#todo: Valid date test (no static type checking in Python)self._date = datedef getStage(self):return self._stagedef getTrainingType(self):return self._trainingTypedef getDate(self):return self._date

在这个类中可以看到以下内容:

  • Python 中没有静态类型检查。例如,日期属性不能声明为日期,必须创建一个附加检查

这三个类是如何实例化和使用的示例可以在下面的最终代码片段中找到:

# Construct two players, FirstTeamPlayer class inherits from Player
player1 = Player("Janssen")
player2 = FirstTeamPlayer("Tadic")# SetPosition of player, method is overloaded in FirsTeamPlayer
player1.setPosition("goalkeeper")
player2.setPosition("midfielder", "striker")# Create new traning object and add traningsdata to player object. 
training1=Training('Toekomst', 'strength', date(2019,4,19))
player1.setTraining(training1, rawData=np.random.rand(1,3))
player2.setTraining(training1, rawData=np.random.rand(1,3))# Add another object
training2=Training('ArenA', 'friendly game', date(2019,4,20))
player1.setTraining(training2, rawData=np.random.rand(1,3))
player2.setTraining(training2, rawData=np.random.rand(1,3))

4c。使用 NumPy 的矩阵分析

NumPy 是使用 Python 进行科学计算的基础包。在本教程中,它将被用来做矩阵分析。请注意,attribute _rawData 已经作为 NumPy 数组封装在 Player 类中。NumPy 通常与 Matplotlib 一起使用来可视化数据。在下面的代码片段中,数据取自玩家类,然后进行一些矩阵运算,从基础到更高级。完整的例子可以在 github 项目中找到。

# Take the matrix data from player objecs that were created earlier
m1=player1.getTrainingRawData()
m2=player2.getTrainingRawData()# print some values
print(m1[0][1])
print(m1[:,0])
print(m1[1:3,1:3])# arithmetic
tmp3=m1*m2 # [m2_11*m1_11,  ..,  m1_33*m2_33]
print(tmp3)# matrix multiplication
tmp1 = m1.dot(m2) # [m1_11 * m2_11 + m1_23 * m2_32 +  m1_13 * m2_31, #   ..., # m1_31 * m2_13 + m1_23 * m2_32 +  m1_33 * m2_33]
print(tmp1)# inverse matrix
m1_inv = np.linalg.inv(m1)
print("inverse matrix")
print(m1_inv)
print(m1.dot(m1_inv))# singular value decomposition
u, s, vh = np.linalg.svd(m1, full_matrices=True)
print("singular value decomposition")
print(u)
print(s)
print(vh)

4d。使用熊猫进行统计分析

Pandas 是 Python 中高性能、易于使用的数据结构和数据分析工具的包。在幕后,pandas 使用 NumPy 作为它的数组结构。在本教程中,它将用于计算一些基本的统计数据。在下面的代码片段中,数据取自 player 类,然后进行一些统计操作。完整的例子可以在 github 项目中找到。

# Create the same matrices as earlier
m1=player1.getTrainingRawData()
m2=player2.getTrainingRawData()# create column names to be added to pandas dataframe
columns = np.array(['col1', 'col2', 'col3'])# Create pandas dataframe
df_1=pd.DataFrame(data=m1, columns=columns)
df_2=pd.DataFrame(data=m2, columns=columns)# calculate basic statistics col1
print(df_1['col1'].sum())
print(df_1['col1'].mean())
print(df_1['col1'].median())
print(df_1['col1'].std())
print(df_1['col1'].describe())# calculate correlation and covariance of dataframe
tmp1=df_1.cov()
tmp2=df_1.corr()print("correlation:\n " + str(tmp1))
print("\n")
print("covariance:\n " + str(tmp2))

4e。读取/写入数据库

最后,数据将被写入 SQL 数据库。在本教程中,使用了作为 DSVM 一部分的 MSSQL 数据库。在任务栏中查找 Microsoft SQL Server Management Studio(SSMS)图标,并启动一个新会话。使用 Windows 身份验证登录,另请参见下文。

4e1. SSMS session using Windows Authentication

在菜单中查找“新查询”并开始新的查询会话。然后执行以下脚本:

USE [Master]
GOCREATE DATABASE pythontest
GOUSE [pythontest]CREATE TABLE [dbo].[trainingsdata]
(  [col1] [float] NOT NULL,[col2] [float] NOT NULL,[col3] [float] NOT NULL
)
GO

最后,可以将数据写入数据库和从数据库中读取数据。熊猫数据帧将用于此,也见下面的片段。

# import library
import pyodbc# set connection variables
server  = '<<your vm name, which name of SQL server instance >>'
database = 'pythontest'
driver= '{ODBC Driver 17 for SQL Server}'# Make connection to database
cnxn = pyodbc.connect('DRIVER='+driver+';SERVER='+server+';PORT=1433;DATABASE='+database + ';Trusted_Connection=yes;')
cursor = cnxn.cursor()#Write results, use pandas dataframe
for index,row in df_1.iterrows():cursor.execute("INSERT INTO dbo.trainingsdata([col1],[col2],[col3]) VALUES (?,?,?)", row['col1'], row['col2'], row['col3'])cnxn.commit()#Read results, use pandas dataframe
sql = "SELECT [col1], [col2], [col3] FROM dbo.trainingsdata"
df_1read = pd.read_sql(sql,cnxn)
print(df_1read)
cursor.close()

5.Spark 集群上带有 Azure 数据块的 PySpark

在前一章中,所有的代码都在一台机器上运行。如果产生更多的数据或需要进行更高级的计算(例如深度学习),唯一的可能是采用更重的机器,从而将放大以执行代码。也就是说,计算不能分配给其他虚拟机。

Spark 是一个分析框架,可以将计算分配给其他虚拟机,因此可以通过添加更多虚拟机来横向扩展。这比让一台“超级计算机”做所有的工作要高效得多。Python 可以在 Spark 中使用,通常被称为 PySpark。在本教程中,将使用 Azure Databricks,这是一个针对 Azure 优化的基于 Apache Spark 的分析平台。在这种情况下,执行以下步骤。

  • 5a。开始
  • 5b。项目设置

5a。开始

启动 Azure Databricks 工作区并转到群集。使用以下设置创建新群集:

5a1. Create cluster

接下来,选择工作区,右键单击,然后选择导入。在单选按钮中,选择使用 URL 导入以下笔记本:

[https://raw.githubusercontent.com/rebremer/devopsai_databricks/master/project/modelling/1_IncomeNotebookExploration.py](https://raw.githubusercontent.com/rebremer/devopsai_databricks/master/project/modelling/1_IncomeNotebookExploration.py)

另请参见下图:

5a2. Import notebook

选择您在 4b 中导入的笔记本,并将该笔记本连接到您在 4a 中创建的集群。确保集群正在运行,否则启动它。使用快捷键 SHIFT+ENTER 逐个单元格地浏览笔记本。

5a3. Run notebook

最后,如果你想跟踪模型,创建模型的 HTTP 端点和/或创建项目的 DevOps 管道,请参见我的高级 DevOps for AI 教程这里,关于安全性,请参见这里。

5b。项目的设置

在这个项目中,创建了一个机器学习模型,该模型使用年龄、每周工作时间、教育程度等特征来预测一个人的收入阶层。在这种情况下,执行以下步骤:

  • 以 Spark 数据框架的形式接收、探索和准备数据
  • 逻辑回归-使用一周工作时间的 1 个特征
  • 逻辑回归—所有特征(工作时间、年龄、状态等)
  • 逻辑回归—防止过度拟合(正则化)
  • 决策树—不同的算法,找出性能最好的算法

请注意,pyspark.ml 库用于构建模型。也可以在 Azure Databricks 中运行 scikit-learn 库,但是,工作只能由驱动程序(主)节点完成,计算不是分布式的。请看下面使用 pyspark 包的片段。

from pyspark.ml import Pipeline, PipelineModel
from pyspark.ml.classification import LogisticRegression
from pyspark.ml.classification import DecisionTreeClassifier
#...

6.结论

在本教程中,创建了两个 Python 项目,如下所示:

  • Jupyter 笔记本在数据科学虚拟机上使用面向对象编程、NumPy、pandas 进行数据分析,并使用 SQL 存储数据
  • 分布式 Spark 集群上的 Databricks 笔记本,具有多个使用 PySpark 构建机器学习模型的虚拟机

许多公司考虑在云中使用什么工具进行数据分析。在这方面,几乎所有的云数据分析平台都支持 Python,因此,Python 可以被视为数据分析的瑞士军刀。本教程可能会帮助你探索 Python 的可能性。

6. Python as Swiss Army knife for data analytics

没有管理权限如何使用 Python

原文:https://towardsdatascience.com/how-to-use-python-without-administrative-right-at-your-workplace-a50ee2ee2267?source=collection_archive---------6-----------------------

现实世界中的数据科学

在您的工作场所或在便携模式下使用

Image from freepik.com

从我的经验来看,Python 是一门漂亮的语言。它工作如此之快,简单易学,可以适用于各种领域。我开始使用 Python 学习数据科学,但最近发现它还可以扩展到 web 抓取或自动化机器人编程。通常,大多数工作在我有管理权限的个人笔记本电脑上运行良好。然而,当我试图将这些知识应用到我在工作场所的职责领域时(即,在我公司的没有管理权限的用户工作环境中),他们感到沮丧,并且大多数时候,软件包安装工作不顺利。经过几天的寻找和尝试,我终于找到了一个有效的方法。因此,我相信写这篇博客可以帮助其他人解决我所面临的同样的问题。也就是说,如何在没有管理权限的情况下在工作场所使用 Python。

没有管理权限,我将需要使用软件,可以安装在便携式模式或基于网络的应用程序。我尝试过很多可以用来运行 Python 的便携软件或者云平台。其中包括 Anaconda 、 SublimeText 、 PortablePython 、 WinPython 、 Google Colaboratory 、微软 Azure services 等等。由于我只是彻底尝试了其中的一部分,所以我在这里只提到其中的一部分。

第一个推荐的软件是使用 Anaconda ,因为它附带了大多数有用的便捷包,并且它可以以便携模式直接安装到您的工作机器上,而不需要管理权限。我开始用这个软件是通过 Jupyter 笔记本运行自学的,用了几个月。但是,我不能使用这个 Anaconda 环境安装任何额外的包,比如著名的 XGBoost ML 算法。在 Stackoverflow 上有几个帖子,像这个我已经浏览过了,但是并没有解决问题。归根结底,我似乎需要配置系统路径,但我没有权限这样做。对于 Windows 10,您可以通过控制面板访问此路径配置,并在搜索栏中键入“PATH”。正如您在下面的快照中看到的,我没有更改系统路径的管理权限。我也许可以请 IT 支持人员帮我修改一下,但是应该有一些更好的方法在用户模式下编写 Python 代码。让我们试试其他的选择。

PATH configuration in Windows 10

其次,我在 Google 联合实验室尝试过免费的云平台。这只是典型的免费 Jupyter 笔记本环境,不需要设置,完全在云中运行。我可以用!pip install XXX 在我的个人笔记本上安装类似 Jupyter notebook 的新包。对我来说,这在一段时间内相当有效。直到我发现使用这个平台有三个主要缺点。首先,这个 Colab 平台是为间歇用户设计的,因为运行一整套冗长的机器学习模型可能会消耗服务器的大量资源。在我尝试了 2 天的运行时间后,我收到了一些警告消息,要求我降低 GPU 级别,以便将资源让给其他人使用。其次,模型中需要输入的数据需要上传到 Colab 中。虽然它可以很好地与 Google Drive 同步,但这违反了我公司关于数据保留的政策。每一个上传到外部服务器的文件都将被跟踪,我不想仅仅因为这个愚蠢的原因被解雇。第三,由于这个平台在云中工作,一些 GUI 包无法安装。对于我来说,我打算使用 pyautogui 构建一些 BOT 来控制鼠标移动,并使用 keyboard 来帮助我减少一些重复的复制和粘贴任务。这个 Colab 不支持 GUI 控制,因为它在云中没有鼠标或键盘。

Google Colab

第三,我试过 SublimeText3 。在未注册版本中使用代码编辑软件是免费的(您需要为注册版本付费,但您可以继续使用免费版本)。这个软件不仅是为 Python 用户设计的,它还可以选择编译哪种语言。它非常好,因为代码编辑模块可以定制,批量编辑,并添加一些代码检查器包。对我来说,它看起来像是真正为开发者而建的。不幸的是,在尝试了几天之后,我无法在不修改系统路径的情况下安装任何额外的软件包。你可以注意到它漂亮的教程视频。

https://www.sublimetext.com/

最后,在尝试了几种方法都没有成功之后,我发现 WinPython 可能是一种有用的可移植 Python 编辑器软件方法。在我看来,与 Anaconda 相比,有一些可移植的软件,如 PortablePython 等,它们的根文件夹/安装文件更容易理解,WinPython 对我来说最好。我可以在 WinPythonCommandPrompt for 中使用 pip install 添加新的软件包安装。whl 文件或者我可以解压.tar.gz 文件,放在 WinPython 包根文件夹。与之前解释的两个平台不同,这两种包安装方法都运行良好,我可以使用这个 WinPython 安装 XGboost 和 pyautogui。它在 Jupyter notebook 中工作,不需要任何管理权限,我想让您知道,这是我让 Python 在公司环境中运行的最佳方法,但仍符合数据泄漏预防政策,并且不使用外部云服务器。我也把我的赞成/反对的比较放在这个博客的底部。感谢您的阅读。有什么建议可以随意评论。

Jupyter notebook running from WinPython

提升你的正则表达式技能

原文:https://towardsdatascience.com/how-to-use-regex-7aeaf4dd25e9?source=collection_archive---------15-----------------------

为了乐趣和利益的正则表达式

正则表达式名声不好。它们很硬,不透明,会打碎东西。

They even broke Stack Overflow.

依赖内置模块进行字符串匹配对于某些任务来说是不错的,但是您将错过编写自己的正则表达式所带来的强大功能和灵活性。(如果你真的很专注,你甚至可以让他们做算术。)

这篇文章将向你展示一些你以前可能没有尝试过的正则表达式的用例,并给你一些资源,让学习它们变得有趣。

让你的 f 弦更加百搭

Python 的 f-strings 非常棒——它们可读性强、简洁,并且比旧的%格式化方法更不容易出错。

使用 regex,您可以从中获得更多。为表达式加上前缀 r 表示“raw ”,这告诉 Python 忽略所有的转义字符。

But beware, even a raw string can’t consist entirely of a single backslash.

当你需要交换你的正则表达式的部分时,结合使用前缀 r 和前缀 f 。您可以用它来编写更短的循环,或者为您还没有或不需要编译的值保留一个位置。(这里有一个后一种情况的例子。)

Use re.compile to pre-compile a regular expression object.

精确查找和替换文本

正则表达式为您提供了一种改变字符串内容的简洁方法。在一行中,您可以使用捕获组来定位要替换和更改的项目。

在这里,我用这种技术扫描新闻文章中的句子,并用单词“alien”制作标签。

Use a numbered reference to the capturing group enclosed in parentheses.

The second expression replaces the targeted substring in the call to re.sub.

从嘈杂的数据中获取有价值的信息

我在日常生活中使用 regex 来简化其他任务(是的,真的)。例如,我想要 requirements.txt 文件中的包列表,但是不想要它们的具体版本。

Not pleasant.

Regex 避免了手动提取包名的繁琐。你可以在 Regex101 看到我是怎么做的。为此,我喜欢使用 BBEdit (以前的 TextWrangler),但是你也可以使用 Regex101 中的“导出匹配”特性。这个网站给了你实时调试你的表达的额外好处。

花在学习正则表达式上的时间可以让你从繁琐的搜索中解脱出来,从而获得数倍的回报。我使用正则表达式从其他 Python 脚本中提取正则表达式,并在命令行中使用 T2 对文件进行 grepping。

训练你的大脑,享受挑战

在应用正则表达式时,您将通过分解搜索问题、抽象模式并在算法上应用它们来提高您的计算思维技能。

I’m fun at parties.

但是使用正则表达式的最好理由可能是它们只是的乐趣。如果你是那种喜欢解谜的人,你会沉迷于寻找不同的方法来解决同一个问题和解决边缘案例。

虽然正则表达式确实很难,有时甚至很危险,但生活中大多数美好的事情都是如此。做几个填字游戏,打一点 regex 高尔夫,看你合不同意。

如何在处理无聊任务时使用硒作为救命稻草

原文:https://towardsdatascience.com/how-to-use-selenium-as-life-saver-when-dealing-with-boring-tasks-ca264d1ce88?source=collection_archive---------18-----------------------

以 Selenium 的方式自动化永无止境的重复任务

如果您是一名开发人员,那么您可能不需要介绍 selenium。Selenium 是一个强大的工具,用于与 web 服务器交互,以编程的方式处理请求。它用于自动执行各种各样的任务,包括与远程 web 服务器的交互。在本文中,我将通过一个简单的例子来演示它的强大用法。

让我们考虑使用在线服务从扫描图像样本中自动提取文本的任务,称为光学字符识别(OCR)。该过程包括以下步骤。

  1. 从本地存储器上传图像。
  2. 启动 OCR 提取过程
  3. 等待文本提取完成
  4. 找到文本元素并检索
  5. 将它写在 txt 文件中

我正在使用 newocr 在线 ocr 服务进行任务演示。当我们一步一步地看代码时,我会解释正在做什么。代码是用 python 写的,但是没有 python 知识的读者也能理解这里讨论的概念。我已经挑选了一个样本扫描图像。让我们来看看样本图像。

1.导入所需的库

webdriver —与服务器交互的 Selenium 驱动类对象

WebDriverWait —暂停执行一段时间的功能

预期条件 —等待条件通过

超时异常 —用于处理因服务器响应延迟而导致的错误

By —用于指定要查找的元素类型

ChromeDriverManager —用于启动浏览器的 Chrome 版本

列出文件名以'结尾的所有文件。工作目录中的 jpeg' (jpeg 图像)。此外,你应该会看到一个 Chrome 浏览器自动启动,并登陆到 Newocr 主页。

注意:如果 chromedriver.exe 在 executable_path 中不可用,那么您将遇到“web driver exception”这意味着驱动程序存储在其他地方或者驱动程序不存在。如果 chromedriver.exe 不存在,下载它并指定位置的完整路径。

2.找到元素标签

对于每个动作,我们希望 selenium 在元素上执行,我们需要提供相应的元素路径。元素路径是指向 HTML 文档中给定标签的东西。这样做背后的想法是,我们要求 Selenium 在给定的位置标记并对其执行指定的操作。按照下面显示的步骤获取元素路径。

有许多方法可以定位元素,“CCS 选择器”是其中之一。一旦你做了上面的步骤,CSS 选择器的元素就会被复制到剪贴板上。然后使用这个选择器来定位元素。下面是从图像中提取文本的代码片段。

上面的代码片段做了以下事情:

  1. 找到“选择文件”按钮并发送图像文件的完整路径
  2. 找到“预览”按钮,并执行触发上传过程的点击操作。
  3. 等待,直到“#ocr”元素出现,这意味着上传过程已完成,但不会超过 25 秒。
  4. 一旦元素“#ocr”出现,就执行触发文本提取过程的点击动作。
  5. 等待提取完成。
  6. 定位检索到的文本元素,然后复制结果并存储在变量“txt”中。

让我们付诸行动吧。

您可能想知道手动执行过程是否比编程更容易,为什么要编写代码。想象一下你自己处于这样一种情况,你必须处理 100 张图像来从中提取文本,这是一个繁琐的过程。在这种情况下,硒可能是救命稻草。当你在办公室自助餐厅和同事聊天、喝咖啡时,Selenium 会让你的机器完成工作。让我们看看它是怎么做的。

该代码循环遍历每个图像,并应用前面讨论过的操作。对样本图像运行的代码片段产生以下结果。

Output from the Sample_1.jpeg :In 1830 there were Dut twenty-three
miles of railroad in operation in the
United States, and in that year Ken-
tucky took the initial step in the work
weat of the Alleghanies. An Act to
incorporate the Lexington & Ohio
Railway Company was approved by
Gov. Metcalf, January 27, 1830.. {t
provided for the construction and re.Output from the Sample_2.jpeg :When you skim and scan, you need to cover
everything, even titles, subtitles, side features, and
visuals. That bit of information you need may not be
tidily packaged in a paragraph, so you need to check
the entire page--not just the main body of the text,
there are also many visual clues that help you to
find information. Heads and subheads break up the
text and identify the content of each part. Where
key terms are introduced and defined, they appear
in boldface type. Graphs and charts have titles
and/or captions that tell you what they are about.
These clues will help you to find information. . . but
only if you use them.Output from the Sample_3.jpeg :irks ScanTris scanning meusures the iris pattern in the cotored part of the eye,
although the iris color has nothing to do with the biornetric. tris
patterns are formed randomly. As a result, the iris patterns in your
left and right eyes are different, and so are the iris patterns of identi-
cal twins, Iris scan templates ure typically around 256 bytes. bis
scanning can be used quickly for both identification and verification
applications because of its large number of degrees of freedom, Cur-
Tent pilot programs and applications include ATMs (“Eye-TMs"),
grocery stores (for checking out), and the Charlotte/Douglas Inter-
national Airport (physical access}. During the Winter Otympics in
Nagano, Japan, an iris scanning identification system controlled
access to the rifles used in the biathlon.

感谢您的阅读。

如何使用 SQL 进行数据分析(房产销售时间序列)

原文:https://towardsdatascience.com/how-to-use-sql-to-perform-data-analysis-house-property-sales-time-series-bf36cd3c2528?source=collection_archive---------13-----------------------

欢迎阅读我的新文章。如果你想在求职过程中脱颖而出,数据分析永远是一项必要的技能。也许你知道怎么用 Python 或者 R 甚至 SAS/Matlab 来执行。但是了解 SQL 通常是您应该拥有的一项必要而重要的技能。许多公司仍然大量使用 SQL 进行数据提取和分析。简单但能够处理足够多的数据帮助 SQL 在多年后仍然很重要(我编写 SQL 已经超过七年了)。

因此,我在这里演示一个使用 SQL 的数据分析。我做 SQL 用的平台是 MySQL Workbench。您可以从以下链接免费下载:

[## MySQL::下载 MySQL 工作台

MySQL Workbench 为数据库管理员和开发人员提供了一个集成的工具环境,用于:数据库设计和建模

dev.mysql.com](https://dev.mysql.com/downloads/workbench/)

而这个分析的数据集是来自 Kaggle 的“房产销售时间序列”。

[## 房产销售时间序列

下载数千个项目的开放数据集+在一个平台上共享项目。探索热门话题,如政府…

www.kaggle.com](https://www.kaggle.com/deltacrot/property-sales)

关于如何使用 MySQL Workbench 超出了本文的范围。您可以从文档中获得更多信息。有一点要提的是,我是用 MySQL 编码 SQL 的。如果您使用 Oracle 或其他软件编码,可能会有一些不同。如果遇到错误,不必惊慌。只要变回你的语言应该有的样子。

[## MySQL 工作台

这是 MySQL 工作台参考手册。它记录了 MySQL Workbench 社区和 MySQL Workbench…

dev.mysql.com](https://dev.mysql.com/doc/workbench/en/)

该模式称为“数据集”,数据存储为一个名为“raw_sales”的表

第一步总是打印数据集中的一些记录。

SELECT * FROM dataset.raw_sales
LIMIT 10

因此,数据集中有五列,日期出售、邮政编码、价格、财产类型和卧室。

select min(datesold) as min_datesold, max(datesold) as max_datesold 
from dataset.raw_sales;select count(1) from dataset.raw_sales;

该数据集涵盖了从 2007 年 2 月 7 日到 2019 年 7 月 27 日的 29580 条记录。

那么哪个日期的销售最频繁呢?

select datesold, count(1) as sales_count, sum(price) as price_sum
from dataset.raw_sales
group by datesold
order by sales_count desc 
limit 10;

所以一天的最大销售量是 50 件,总价是 4200 万英镑。

哪个邮政编码的平均销售价格最高?

select postcode,avg(price) as price_avg , count(1) as sales_count
from dataset.raw_sales
group by postcode
order by price_avg desc
limit 10;

邮编 2618 的共 9 笔销售,均价 1.08M

而哪一年的销量最低?

select year(datesold) as year , count(1) as sales_count, sum(price) as price_sum 
from dataset.raw_sales
group by year 
order by sales_count
limit 10;

有没有可能知道每年价格排名前五的邮编?当然可以,但是要知道什么是窗函数。

一开始我不知道什么是窗口函数。但是后来我在面试中被一次又一次地问到。所以我查了一下,意识到我应该早点知道这个(至少帮我面试回答问题)。

基本上,window 函数可以基于分区执行聚合,并将结果返回给一行。如果您想了解更多关于窗口函数的语法和用法,我建议您阅读 Oracle 的文档,如下所示:

[## MySQL :: MySQL 8.0 参考手册::12.21.1 窗口函数描述

在以下函数描述中,over_clause 表示 over 子句,如第 12.21.2 节“窗口…”所述

dev.mysql.com](https://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html)

所以我首先按年份和邮编合计价格

select year(datesold) as year ,postcode, sum(price) as price_sum 
from dataset.raw_sales
group by year, postcode

然后我使用窗口函数得到每年总价的排名。

select year,postcode, price_sum, row_number() over (partition by year order by price_sum desc) as ranking
from (
select year(datesold) as year ,postcode, sum(price) as price_sum 
from dataset.raw_sales
group by year, postcode
)  a

最后,选择所有排名小于或等于 5 的记录

select * from
(
select year,postcode, price_sum, row_number() over (partition by year order by price_sum desc) as ranking
from (
select year(datesold) as year ,postcode, sum(price) as price_sum 
from dataset.raw_sales
group by year, postcode
)  a
) b
where ranking <=5 
order by year,ranking

接下来,我将继续讨论 propertyType。有两种类型,房子和单位。

那么每年有多少房子和单元的销售呢?

最简单的方法是分组,然后数有多少条记录。但在这里,我通过使用 case when 提出了另一种方法。函数是根据标准进行聚合的另一个有用函数的情况。在这里,当我计算记录的数量时,我没有使用 count 函数,而是使用 sum 函数和 case when 函数。

select year(datesold) as year, 
sum(case when propertyType = "house" then 1 else 0 end) as house_sales_count,
sum(case when propertyType = "unit" then 1 else 0 end) as unit_sales_count 
from dataset.raw_sales
group by year;

因此,对于 house_sales_count,如果 propertyType 等于 house,则返回 1。否则,它返回 0。然后对所有记录求和。这将显示 propertyType 等于 house 的销售数量。

另一个优点是结果看起来像 Excel 数据透视表。可以直接做个对比。

你可以清楚地看到,每年的房屋销售量都比单位销售量多。那么后续的问题一定是关于房子和单位的平均差价。当然我们也可以用 case 当函数。但有一点需要谨慎的是,else 部分。

select year(datesold) as year,
avg(case when propertyType = "house" then price else null end) as house_price_avg,
avg(case when propertyType = "unit" then price else null end) as unit_price_avg
from dataset.raw_sales
group by year;

有必要返回一个空值,而不是返回 0,这样在计算平均值时就不会包括该特定记录。

再说一次,房子的平均价格比单位价格更高。

进一步考虑卧室数量怎么样?

select year(datesold) as year,
avg(case when propertyType = "house" then price/bedrooms else null end) as house_price_bedroom_avg,
avg(case when propertyType = "unit" then price/bedrooms else null end) as unit_price_bedroom_avg
from dataset.raw_sales
group by year;

这次的情况有所不同。就卧室数量而言,该单元的平均价格高于房子。

这个分析到此结束。我会说 SQL 已经削弱了它在数据分析中的重要性,尤其是许多公司仍然只将 SQL 用于数据挖掘和分析。知道如何掌握 SQL 绝对有助于你获得一个分析职位。希望你看完我的文章能有所收获。请随意给出你的评论或者下次你想让我介绍什么。希望你喜欢,下次再见。

如何在熊猫小组中运用分裂-运用-结合策略

原文:https://towardsdatascience.com/how-to-use-the-split-apply-combine-strategy-in-pandas-groupby-29e0eb44b62e?source=collection_archive---------1-----------------------

通过这个熊猫视觉指南掌握 Python 中的分割-应用-组合模式groupby-apply

TL;速度三角形定位法(dead reckoning)

Pandas groupby-apply是 Python 数据科学家工具箱中的一个无价工具。在没有完全理解其所有内部复杂性的情况下,您可能会走得很远。然而,有时这可能会表现为意外的行为和错误。吃过吗?或者也许您正在努力解决如何处理更高级的数据转换问题?然后阅读这个熊猫groupby-apply范例的视觉指南,一劳永逸地理解它是如何工作的。

来源:我的团队在 晒版机 提供。

介绍

在 Pandas 中处理更高级的数据转换和数据透视表时,对groupby-apply机制的深入理解通常是至关重要的。

这对新手来说可能是一个陡峭的学习曲线,对中级熊猫用户来说也是一种“陷阱”。这就是为什么我想与你分享一些视觉指南,展示当我们运行groupby-apply操作时实际发生的事情。

下面是我认为您应该首先了解的一些事情,以便更直接地使用更高级的 Pandas 数据透视表:

Groupby —它是做什么的?

  1. 应用—它是如何工作的,我们传递给它什么?
  2. 联合收割机阶段会发生什么?
  3. 当自定义函数返回一个序列时会发生什么?
  4. 当它返回一个数据帧时呢?
  5. 当自定义函数返回除了上面两个以外的东西时会发生什么?

请继续阅读,以获得这些问题的答案以及关于在 Pandas 中使用数据透视表的一些额外见解。

我们的示例表

让我们以经典的 Iris 数据集为例(可从 Seaborn 绘图库中获取),为简单起见,将其限制为 15 行:

import seaborn as snsiris_data = sns.load_dataset(‘iris’)
df = iris_data.head(5).copy()
df = pd.concat([df, iris_data..iloc[50:55]])
df = pd.concat([df, iris_data.iloc[100:105]])

该表很小,但足以满足我们的需求,非常适合本文中的演示目的:

使用 groupby()分组

让我们从更新一些关于groupby的基础知识开始,然后在我们进行的过程中在上面构建复杂性。

您可以将groupby方法应用于具有简单 1D 索引列的平面表。它还没有在表上执行任何操作,只是返回了一个DataFrameGroupBy实例,因此需要链接到某种聚合函数(例如,summeanminmax等)。更多的见这里的,它们将对分组行起作用(我们将在后面讨论应用)。

这里需要记住的重要一点是,它会自动将单个聚合结果连接回一个数据框架。

一个非常简单的例子是按特定的列值分组(如我们表中的“物种”),并对所有剩余的适用列求和:

df.groupby(‘species’).sum()

或者,我们可以指定要对哪些列求和。一些人犯的一个常见错误是先计算总和,然后在末尾添加一个列选择器,如下所示:

df.groupby(‘species’).sum()[‘sepal_width’] *# ← BAD!*

这意味着首先对每个适用的列(数字或字符串)进行求和,然后选择一个指定的列进行输出。

这里有一个更好的方法:

在聚合函数之前指定列,以便在过程中只对一列求和,从而显著提高速度(对于这个小表是 2.5 倍):

df.groupby(‘species’)[‘sepal_width’].sum() *# ← BETTER & FASTER!*

注意,由于只有一列被求和,因此结果输出是一个pd.Series对象:

species
setosa 16.4
versicolor 14.6
virginica 14.9
Name: sepal_width, dtype: float64

但是,如果您想直接自动返回 dataframe 对象(毕竟它的可读性要好得多),就没有必要通过pd.Dataframe()进行强制转换。相反,将列名作为列表提供给列选择(本质上,使用双括号),如下所示:

df.groupby(‘species’)[**[**‘sepal_width’**]**].sum()

最后,groupby可以接受一个列名列表,并对所有剩余的适用列(之前没有提到)执行聚合函数。

理解这一点很重要,结果表将有一个 **MultiIndex** 对象作为索引,其行为与常规表略有不同。

multicol_sum = df.groupby([‘species’, ‘petal_width’]).sum()

有用提示:使用 **MultiIndex** 表时,您可以使用 **.xs** 选择数据帧的子集,方法是选择一个值,然后选择特定的索引级别。产生的输出通常也是 dataframe 对象。

这里有一个例子:

multicol_sum.xs(‘virginica’, level=’species’)

另外,不要忘记您可以通过运行reset_idnex方法将索引“展平”成列:

multi_sum.reset_index()

此外,如果您将一个drop=True参数传递给reset_index函数,您的输出数据帧将删除组成MultiIndex 的列,并创建一个具有增量整数值的新索引。

apply()

现在让我们进入下一个阶段。

我们可以定义自己的自定义函数,并通过apply()方法在表上运行它,而不是使用 Pandas 提供的常用函数来操作组。

要写好一个自定义函数,你需要理解这两个方法如何在所谓的 Groupby-Split-Apply-Combine 链式机制中相互协作(更多关于这个在这里)。

正如我已经提到的,第一阶段是创建一个 Pandas groupby对象(DataFrameGroupBy),它为 apply 方法提供一个接口,以便根据指定的列值将行分组在一起。

我们暂时将这些组分开,并通过一个优化的 Pandas 内部代码将它们循环。然后,我们将每个组作为一个SeriesDataFrame对象传递给一个指定的函数。

函数的输出被临时存储,直到所有组都被处理。在最后一个阶段,所有结果(来自每个函数调用)最终被组合成一个输出。

这里有几点我们需要记住,以避免在使用groupbyapply方法时可能出现的意外。

在极少数情况下,当我们被迫使用一个 for-in 循环迭代单个行组时,这一点尤其重要(通常,这是一种不好的做法——然而,在某些情况下这可能是不可避免的)。

1]应用功能

您可以通过几种方式为每组操作提供逻辑。

您可以定义单独的函数并将其作为要应用的对象传递,也可以直接传递 lambda 表达式。还有一种.agg()方法,它通过提供一个名称或一系列函数名称来实现多个聚合函数(但这超出了本文的范围)。

例如,这两个命令

df.groupby(‘species’).apply(lambda gr: gr.sum())

def my_sum(gr):return gr.sum()df.groupby(‘species’).apply(my_sum)

产生完全相同的结果:

顺便说一下,是的,具有字符串值的列也被“求和”,它们只是简单地连接在一起。

2]功能输入

定制函数应该有一个输入参数,该参数可以是一个Series或一个DataFrame对象,这取决于通过groupby方法指定的是一列还是多列:

def foo(gr):print(type(gr))return Nonedf.groupby(‘species’).apply(foo)

产出:

<class ‘pandas.core.frame.DataFrame’>
<class ‘pandas.core.frame.DataFrame’>
<class ‘pandas.core.frame.DataFrame’>
<class ‘pandas.core.frame.DataFrame’>

,而(忽略这里有 4 行的事实,我稍后会解释)

df.groupby(‘species’)[‘petal_length’].apply(foo)

退货:

<class ‘pandas.core.series.Series’>
<class ‘pandas.core.series.Series’>
<class ‘pandas.core.series.Series’>

3]在自定义函数中使用 print()语句

当编写一个复杂的表转换时,你有时可能想要遍历applyed 函数的内部工作方式,并添加一个print()语句来检查操作过程中发生了什么(我经常这样做,以便在遇到困难时确定方向)。

对你们中的一些人来说,这可能很令人吃惊,但是当你运行下面的代码时,你将得到一个你可能没有预料到的额外的位:

def foo(gr): print(gr, ‘\n’)df.groupby(‘species’).apply(func=foo)

这是打印出来的内容:

这种神秘的行为实际上在熊猫文档中有解释,但是很容易被忽略——我知道我是这么做的,而且不得不艰难地学习它,所以让我来帮你省点麻烦:

在当前实现中,在第一列/行上应用调用 func 两次,以决定它是否可以采用快速或慢速代码路径。如果 func 有副作用,这可能会导致意外的行为,因为它们会对第一列/行生效两次。

4]功能输出

拼图的最后一块是应用函数的输出,以及如何在合并阶段处理它。这里发生的事情是,Pandas 从每个后续的组操作中获取所有的输出,并将它们与它们相应的标签连接起来,这些标签也是由DataFrameGroupBy对象提供的。后者随后被用于创建新的索引。

这意味着您可以设计一个自定义函数来返回任何内容,它将被放置在组名标签下的特定组的一行中。

这个例子应该很好地说明了这一点:

def foo(gr):return pd.Series(“This is a test”)df.groupby(‘species’).apply(func=foo)

将创建:

然而,在大多数情况下(例如,使用 sum 函数),每次迭代都返回每行一个 Pandas Series对象,其中索引值用于将值分类到最终数据帧中的正确列名。

这个例子应该说明:

让我们创建一个定制的Series对象,并通过apply方法在每个组上返回它:

myseries = pd.Series(data=[‘one’, ‘two’, ‘3’],index=[‘a’, ‘b’, ‘c’]
)def foo(gr):return myseriesdf2.groupby([‘species’, ‘petal_width’]).apply(func=foo)

如果我们为每个迭代组返回一个DataFrame会怎么样?结果有点有趣,因为它将创建一个具有MultiIndex结构的表。它将把DataFrame按原样追加到每一行中,并且它的索引将与组标签值集成在一起,例如:

def foo(gr):return pd.DataFrame(myseries) df2.groupby([‘species’, ‘petal_width’]).apply(func=foo)

现在就这样。

理解这些问题将使您更容易在 Pandas 表上处理一些更复杂的枢轴和操作。每当我陷入困境时,我会时不时地重温这些基础知识——它总能帮助我大大加快这个过程!

如何在 Seaborn 中使用自己的调色板

原文:https://towardsdatascience.com/how-to-use-your-own-color-palettes-with-seaborn-a45bf5175146?source=collection_archive---------5-----------------------

前几天,我用 seaborn 制作了一些可视化效果,这是一个基于 Matplotlib 的非常棒的超级易用的库。

即使我很喜欢 seaborn 的默认风格,因为它们的美学非常干净,但我通常喜欢定制的一点是数据点上的颜色。

我试图寻找如何在 seaborn 中使用或创建自定义调色板的端到端示例,但是很难找到。

所以我决定利用我的 matplotlib 知识,收集我能找到的关于 seaborn 调色板的所有信息,来创建我自己的代码示例/模板。

希望你觉得有用。

像往常一样,您从漂亮的虚拟数据开始😀

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as pltdata = np.array([[1, 3, 'weekday'], [2, 2.5, 'weekday'],[3, 2.7, 'weekend'], [4, 2.8, 'weekend'], [5, 3, 'weekday'], [6, 3.1, 'weekday'], [7, 3, 'weekday'], [8, 3.1, 'weekday'], [9, 3.1, 'weekday'], [10, 3.1, 'weekend']])# Creating a data frame with the raw data
dataset = pd.DataFrame(data, columns=['day', 'miles_walked', 'day_category'])

如果你想看一眼数据集

print(dataset)

你会看到这样的东西

1.使用现有的调色板

seaborn 和 matplotlib 有很多不同的调色板可供选择。在这个例子中,我将使用配对调色板。

# Set the color palette
sns.set_palette(sns.color_palette("Paired"))# Plot the data, specifying a different color for data points in
# each of the day categories (weekday and weekend)
ax = sns.scatterplot(x='day', y='miles_walked', data=dataset, hue='day_category')# Customize the axes and title
ax.set_title("Miles walked")
ax.set_xlabel("day")
ax.set_ylabel("total miles")# Remove top and right borders
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)plt.show()

使用现有的调色板,您唯一需要做的事情是在调用 plot 方法和您想要的任何其他定制之前设置它。

2。使用自己的调色板

如果你想使用一组特定的颜色,或者因为它们是你最喜欢的颜色,或者是你正在使用的风格指南的一部分,你也可以这样做!

# Create an array with the colors you want to use
colors = ["#FF0B04", "#4374B3"]# Set your custom color palette
sns.set_palette(sns.color_palette(colors))# And then, from here onwards, it's exactly like the previous example# Plot the data, specifying a different color for data points in
# each of the day categories (weekday and weekend)
ax = sns.scatterplot(x='day', y='miles_walked', data=dataset, hue='day_category')# Customize the axes and title
ax.set_title("Miles walked")
ax.set_xlabel("day")
ax.set_ylabel("total miles")# Remove top and right borders
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)plt.show()

如果您想在多个图中使用自己的调色板,您也可以在 seaborn 图中使用参数palette,并在整个代码中引用您的自定义调色板。

# Create an array with the colors you want to use
colors = ["#FF0B04", "#4374B3"]# Set your custom color palette
customPalette = sns.set_palette(sns.color_palette(colors))# Use the parameter palette and use your own palette across all your
# plots
ax = sns.scatterplot(x='day', y='miles_walked', data=dataset, hue='day_category', palette=customPalette)# Customize the axes and title
ax.set_title("Miles walked")
ax.set_xlabel("day")
ax.set_ylabel("total miles")# Remove top and right borders
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)plt.show()

这样就会造成和上面一样的剧情!但是现在你可以在你的任何一幅 seaborn 图中引用customPalette来使用相同的调色板。

就是这样!一个很好的方式来定制您的情节,使您的可视化更有见地。

感谢阅读!

如何用 Python (2020)三步可视化决策树

原文:https://towardsdatascience.com/how-to-visualize-a-decision-tree-in-5-steps-19781b28ffe2?source=collection_archive---------10-----------------------

用 Python 学习 Scikit 的一个例子

Photo by Alexandre Chambon on Unsplash

决策树是一种非常流行的机器学习模型。它的美妙之处在于其易于理解的可视化和在生产中的快速部署。

在本教程中,你将发现一个的三步程序,用于可视化 Python(Windows/Mac/Linux)中的决策树

跟着做,画出你的第一棵决策树!

2020 年 4 月更新****:
sci kit-learn(sk learn)库增加了一个新功能,允许我们在没有 GraphViz 的情况下绘制决策树。
所以我们可以使用 matplotlib 库的 plot_tree 函数。

步骤 1:下载并安装 Anaconda

根据您的计算机操作系统版本,选择正确的 Anaconda 包进行下载。Anaconda 是一个常见的 Python 发行版,通常允许大型公司下载和安装。

** [## Anaconda Python/R 发行版-免费下载

开源的 Anaconda 个人版(正式的 Anaconda 发行版)是执行 Python/R…

www.anaconda.com](https://www.anaconda.com/distribution/#download-section)

相关文章: 如何安装/设置 Python 并立即准备数据科学
查看使用 Anaconda 安装 Python 的分步说明。

步骤 2:导入包并读取数据

首先,让我们从 Python 机器学习库 scikit-learn 导入一些函数。

sklearn 需要 0.21 或更高版本。如果你刚刚安装了 Anaconda,它应该足够好了。

接下来,让我们读入数据。这里以乳腺癌数据为例。

第三步:创建决策树并将其可视化!

在您的 Python 版本中,复制并运行以下代码来绘制决策树。我更喜欢 Jupyter 实验室,因为它的互动功能。

恭喜你的第一个决策树图!

希望本指南对您有所帮助。

如果你有任何问题,请留言。**

在你离开之前,别忘了 报名参加刚刚进入数据快讯的 !或者通过推特、脸书与我们联系。

更多数据科学相关文章来自 Lianne 和 Justin:

** [## 如何在线学习数据科学:你需要知道的一切——进入数据

这是利用在线资源进入数据科学的完整路线图/课程。你是否想学习…

www.justintodata.com](https://www.justintodata.com/how-to-learn-data-science-online-all-you-need-to-know/) [## Python 中的数据清理:终极指南(2020)——只进入数据

我们用 Python 创建了这个新的完整的分步指南。你将学习如何寻找和清理的技巧:丢失…

www.justintodata.com](https://www.justintodata.com/data-cleaning-python-ultimate-guide/) [## 预测时间序列的三个步骤:LSTM 与 TensorFlow Keras -只是进入数据

这是利用在线资源进入数据科学的完整路线图/课程。你是否想学习…

www.justintodata.com](https://www.justintodata.com/forecast-time-series-lstm-with-tensorflow-keras/)**

如何用 40 行代码可视化卷积特征

原文:https://towardsdatascience.com/how-to-visualize-convolutional-features-in-40-lines-of-code-70b7d87b0030?source=collection_archive---------2-----------------------

卷积神经网络彻底改变了计算机视觉,并将彻底改变整个世界。开发解释它们的技术是一个重要的研究领域,在本文中,我将向您解释如何可视化卷积特征,如标题图片所示,只需 40 行 Python 代码。

最近,在读杰里米·里夫金的书《工作的终结》时,我看到了人工智能的一个有趣定义。里夫金写道:“今天,当科学家们谈论人工智能时,他们通常指的是‘创造机器的艺术,这些机器执行的功能需要人来执行。”(摘自 Kurzweil,Raymond 著《智能机器时代》(麻省剑桥:麻省理工出版社,1990 年),第 14 页。)".我喜欢这个定义,因为它避免了人工智能在我们的智能意义上是否真正智能的大肆讨论。作为一名科学家,揭示我们大脑的功能原理并创造一个真正智能的机器的想法让我兴奋,但我认为重要的是要认识到深度学习模型不是大脑的模型(弗朗索瓦·乔莱,用 Python 进行深度学习(纽约州谢尔特岛:曼宁出版公司,2018 年),第 8 页)。深度学习研究旨在从数据学习规则,以自动化到目前为止还不能自动化的过程。虽然这听起来不那么令人兴奋,但它确实是一件伟大的事情。仅举一个例子:深度卷积神经网络的出现彻底改变了计算机视觉和模式识别,并将允许我们在医疗诊断等领域引入大量自动化。这可以让人类迅速将顶尖的医学诊断带给贫穷国家的人们,这些国家没有能力培养他们原本需要的许多医生和专家。

尽管有关于深度学习的所有令人兴奋的消息,但神经网络看待和解释世界的确切方式仍然是一个黑箱。更好地理解它们如何准确地识别特定的模式或对象,以及它们为什么工作得如此好,可能会让我们 1)进一步改进它们,2)还会解决法律问题,因为在许多情况下,机器做出的决定必须是人类可以解释的。

有两种主要方法可以尝试理解神经网络如何识别某种模式。如果您想知道哪种模式显著激活了某个特征图,您可以 1)尝试在数据集中查找导致该特征图高平均激活率的图像,或者 2)尝试通过优化随机图像中的像素值来生成这种模式。后一种想法是由尔汗等人 2009 提出的。在本文中,我将向您解释如何通过优化随机图像的像素值来为封面图片所示的卷积神经网络生成特征可视化,只需大约 40 行 Python 代码。

这篇文章的结构如下:首先,我将向您展示一个 VGG-16 网络的几层中卷积特征的可视化,然后我们将尝试理解其中一些可视化,我将向您展示如何快速测试某个过滤器可能检测到哪种模式的假设。最后,我将解释创建本文介绍的模式所必需的代码。

我们开始吧:)

特征可视化

神经网络学习将输入数据(如图像)转换成意义越来越大、越来越复杂的连续层。

你可以把一个深层网络想象成一个多阶段的信息提炼操作,信息经过连续的过滤,越来越纯净。(弗朗索瓦·乔莱(Franç ois Chollet),用 Python 进行深度学习(纽约州谢尔特岛:曼宁出版公司,2018 年),第 9 页)

阅读完他的文章后,您将知道如何生成模式,以最大化在那些分层表示的特定层中所选特征图的平均激活,如何能够解释其中一些可视化,以及最终如何测试所选过滤器可能响应哪种模式或纹理的假设。下面你会看到一个 VGG-16 网络的几层中过滤器的可视化特征。在观察它们的同时,我希望你能观察到,随着我们深入网络,生成的模式的复杂性是如何增加的。

第 7 层:Conv2d(64,128)

filters 12, 16, 86, 110 (top left to bottom right, row-wise)

第 14 层:Conv2d(128,256)

filters 1, 6, 31, 32, 54, 77, 83, 97, 125, 158, 162, 190 (top left to bottom right, row-wise)

第 20 层:Conv2d(256,256)

filters 3, 34, 39, 55, 62, 105, 115, 181, 231 (top left to bottom right, row-wise)

第 30 层:Conv2d(512,512)

filters 54, 62, 67, 92, 123, 141, 150, 172, 180, 213, 233, 266, 277, 293, 331, 350, 421, 427 (top left to bottom right, row-wise)

第 40 层:Conv2d(512,512) —网络顶部

filters 4, 9, 34, 35, 75, 123, 150, 158, 203, 234, 246, 253, 256, 261, 265, 277, 286, 462 (top left to bottom right, row-wise)

那些图案真的让我大吃一惊!部分原因是我认为它们中的一些非常漂亮(以至于我会立刻把它们裱起来挂在墙上),但主要原因是我认为它们只是通过最大化一个复杂的参数化数学函数产生的某个值而创造出来的,这个函数是对数千张图像进行训练的。在扫描通过最大化最后一个卷积层中特征映射的平均激活而获得的 512 个模式时,我遇到了几个让我想到“等等,这是一只鸡!”或者“这看起来不像羽毛吗?”

识别模式

让我们试着解释一下这些可视化的特性!

从这个开始,有没有让你想起什么?

layer 40, filter 286

这张照片立刻让我想起了教堂里拱形天花板的圆形拱门。

Source

那么我们如何检验这个假设呢?人造拱门的图片是通过最大化第 40 层中第 286 个特征地图的平均激活来创建的。因此,我们简单地将网络应用于图片,并在第 40 层绘制特征图的平均激活。

我们看到了什么?在特征地图 286 处有一个强烈的尖峰,正如所料!那么这是否意味着层 40 中的过滤器 286 是负责检测拱形天花板的过滤器?好吧,我会小心一点的。滤波器 286 显然响应图像中的拱形结构,但是要记住,这种拱形结构可能对几个不同的类别起重要作用。

注意:当我使用第 40 层(一个卷积层)来生成我们正在看的图像时,我使用第 42 层来生成显示每个特征图的平均激活的图。层 41 和 42 是批量标准和 ReLU。ReLU 激活函数移除所有负值,选择层 42 而不是层 40 的唯一原因是,否则,图中将显示大量的负噪声,使得难以看到我们感兴趣的正尖峰。

继续下一个例子。我可以发誓那些是鸡头(或者至少是鸟头)!你看到尖尖的嘴和黑黑的眼睛了吗?

layer 40, filter 256

我测试了这张图片:

Source

瞧,特征图 256 显示了一个强尖峰。

下一个:

layer 40, filter 462

会不会是滤镜 462 对羽毛有反应?

Source

是的,过滤器 462 响应羽毛:

对 265 号过滤器有什么猜测吗?

layer 40, filter 265

或许是锁链?

Source

是的,似乎是对的!

然而,还有一些其他的大高峰!让我们来看看为两个相应的过滤器生成的特征可视化:

layer 40, filters 95, 303

当快速浏览为第 40 层的 512 个滤镜生成的图案时,两张图片都没有响铃。但是现在网络说话了?也许有一点点连锁,你说呢?

这是一个很酷的例子:

layer 40, filter 64

我相信我看到了许多类似羽毛的结构,这让我想起了鸟的腿,在左下方可能有一些类似于黑色眼睛和长喙的鸟头的东西。比“鸡特征可视化”中的喙长。我真的不是鸟类专家,但这两只呢?它们有长长的腿和喙。

Source

好吧,很明显在特征地图 64 上有一个尖峰,但是有更多甚至更大的尖峰!让我们来看看为其他四个滤波器生成的模式,这些滤波器的特征图显示了尖峰:

layer 40, filters 172, 288

layer 40, filters 437, 495

更多的鸟腿和更多的眼睛和嘴在最上面一排?然而,关于最下面一行,我没有任何线索。也许这些图案与图像的背景有关,或者只是代表了网络检测我不理解的鸟类所需的东西。我想这将是目前黑匣子的一部分…

最后一个可爱的,然后我们直接跳到代码,我保证。猜猜这是什么?

layer 40, filter 277

我养了两只猫很多年了,当我看到一只:D 时,我能认出一只小猫的耳朵,你看到它们了吗?在左上角找一个大的!

Source

是的,在特征地图 277 上有一个尖峰,但是是什么导致了它右边的尖峰呢?

让我们快速生成最大化层 40 中的特征地图 281 的平均激活的图片:

layer 40, filter 281

可能是条纹猫毛?

试图从网络中窥探一些秘密让我很开心。然而,事实是,大多数滤波器甚至在最后的卷积层对我来说仍然是绝对抽象的。

更严格的方法是将网络应用于许多不同种类图像的整个数据集,并跟踪最能激发特定图层中特定过滤器的图像。

还有一件事我觉得很有趣。在浏览生成的模式时,我发现许多模式似乎出现在不同的方向(有时甚至是相同的方向)。

layer 20, filters 11, 36, 50, 125, 144, 213

这是有道理的!卷积是平移不变的,因为过滤器在图像上水平和垂直滑动。但是它们不是旋转不变的,因为过滤器不旋转。因此,该网络似乎需要不同方向上的几个类似的滤波器来检测不同方向上的对象和模式。

代码

想法如下:我们从包含随机像素的图片开始。我们将评估模式中的网络应用于该随机图像,计算某一层中某一特征图的平均激活,然后从该层计算相对于输入图像像素值的梯度。知道了像素值的梯度,我们接着以最大化所选特征图的平均激活的方式来更新像素值。

我知道这听起来可能令人困惑,所以让我们用不同的话再次解释它:网络权重是固定的,网络将不会被训练,我们试图通过对像素值执行梯度下降优化来找到最大化某个特征图的平均激活的图像。

这种技术也用于 神经风格转移

为了实现这一点,我们需要:

  1. 一个随机的图像开始
  2. 评估模式下的预训练网络
  3. 一个很好的方法来访问我们感兴趣的任何隐藏层的激活结果
  4. 计算梯度的损失函数和更新像素值的优化器

让我们从生成一个噪声图像作为输入开始。我们可以这样做,即按照下面的方式:img = np.uint8(np.random.uniform(150, 180, (sz, sz, 3)))/255其中sz是图像的高度和宽度,3 是颜色通道的数量,我们除以 255,因为这是uint8类型的变量可以存储的最大值。如果你想要更多或更少的噪音,玩数字 150 和 180。然后,我们使用img_var = V(img[None], requires_grad=True)(这是 fastai 语法)将其转换为需要渐变的 PyTorch 变量。像素值需要梯度,因为我们希望使用反向传播来优化它们。

接下来,我们需要一个评估模式下的预训练网络(这意味着权重是固定的)。这可以通过model = vgg16(pre=True).eval()set_trainable(model, False)来完成。

现在,我们需要一种方法来访问其中一个隐藏层的功能。我们可以在我们感兴趣的隐藏层之后截断网络,这样它将成为输出层。然而,PyTorch 中有一个更好的方法来解决这个问题,叫做钩子,它可以在 PyTorch ModuleTensor上注册。要理解这一点,你必须知道:

  1. Pytorch Module是所有神经网络模块的基类。
  2. 我们神经网络中的每一层都是一个Module
  3. 每个Module都有一个名为forward的方法,用于计算给定输入的Module的输出。

当我们将我们的网络应用于我们的噪声图像时,第一层的forward方法将图像作为输入并计算其输出。这个输出是第二层的forward方法的输入,依此类推。当你在某一层注册一个前向钩子时,该钩子在该层的forward方法被调用时被执行。好吧,我知道这听起来很混乱。我想让你从这里得到的是:当你把你的网络应用到一个输入图像时,第一层计算它的输出,然后第二层,等等。当我们到达一个注册了钩子的层时,它不仅计算输出,还执行钩子。

那么这有什么好处呢?假设我们对图层 i 的特征地图感兴趣。我们在层 i 上注册一个 forward 钩子,一旦调用层 i 的 forward 方法,就将层 i 的特征保存在一个变量中。

下面的类实现了这一点:

当钩子被执行时,它调用方法hook_fn(见构造函数)。方法hook_fn保存self.features中输出的图层。注意,这个张量需要梯度,因为我们想对像素值进行反向传播。

你将如何使用一个SaveFeatures对象?

activations = SaveFeatures(list(self.model.children())[i])为层 i 注册你的钩子,用model(img_var)将你的模型应用到图像后,你可以在activations.features中访问钩子为我们保存的特性。记得调用方法close来释放已用的内存。

太好了,我们现在可以访问图层 i 的特征图了!特征图可以具有形状[1,512,7,7],其中 1 是批量维度,512 是过滤器/特征图的数量,7 是特征图的高度和宽度。目标是最大化所选特征图 j 的平均激活。因此,我们定义以下损失函数:loss = -activations.features[0, j].mean()和优化像素值的优化器optimizer = torch.optim.Adam([img_var], lr=lr, weight_decay=1e-6)。默认情况下,优化器会将损失最小化,因此我们只是将平均激活乘以-1,而不是告诉优化器将损失最大化。用optimizer.zero_grad()重置梯度,用loss.backward()计算像素值的梯度,用optimizer.step()改变像素值。

我们现在已经有了我们需要的一切:我们从一个随机图像开始,在评估模式中定义了一个预训练的网络,注册了一个前向挂钩来访问层 i 的特征,并定义了一个优化器和一个损失函数,允许我们以最大化层 i 中的特征图 j 的平均激活的方式来改变像素值。

很好,让我们来看一个例子:

layer 40, filter 265

等等,这不是我们想要的,对吗?这应该会导致我之前给你们看的连锁模式。如果你捏捏你的眼睛,你也许能猜出“锁链”可能在哪里。然而,我们必须以一个非常差的局部最小值结束,并且必须找到一种方法来引导我们的优化器朝向一个更好的最小值/更好看的模式。与我之前给你看的生成模式相比,这幅图是由一个类似于对立例子的高频模式主导的。那么,我们能做些什么来解决这个问题呢?我尝试了不同的优化器、学习率和规则,但似乎没有减少高频模式。

接下来,我改变了噪声输入图像的大小。

image sizes 200x200, 300x300, 400x400

你能观察到“链状图案”出现的频率随着图像尺寸的增加而增加吗?我知道可能很难理解我的意思。然而,对我来说,生成模式的频率随着图像大小的增加而增加确实是有意义的,因为卷积滤波器具有固定的大小,但是它们与图像相比的相对大小随着图像分辨率的增加而减小。换句话说:假设创建的图案总是具有大致相同的像素尺寸。如果我们增加图像尺寸,则生成的图案的相对尺寸将减小,并且图案频率增加。

如果我的假设是真的,我们想要的是低分辨率示例的低频模式(甚至低于上面显示的模式),但具有高分辨率。这有道理吗?我们如何做到这一点?

我试图从一个非常低分辨率的图像开始,即 56×56 像素,优化了几个步骤的像素值,然后以一定的系数增加图像大小。放大图像后,我又优化了几个步骤的像素值,然后再次放大图像…

这样效果更好:

layer 40, filter 265

我们现在有了一个分辨率更好的低频模式,没有太多的噪声。为什么会这样?我有以下想法:当我们从低分辨率开始时,我们会得到低频模式。放大后,放大模式的频率低于优化器在随机图像的较大图像尺寸下生成的频率。因此,当在下一次迭代中优化像素值时,我们处于更好的起点,并且似乎避免了糟糕的局部最小值。这有道理吗?为了进一步减少高频模式,我在放大后稍微模糊了图像,这对高频模式的影响比对低频模式的影响更大。

我发现按 1.2 的因子放大 12 倍会得到很好的结果。

看看下面的代码。你会发现我们已经讨论了最重要的几行,比如创建随机图像,注册钩子,定义优化器和损失,以及优化像素值。唯一重要的新方面是,1)我将代码包装在一个类中,2)在优化像素值几个步骤后,我们将图像放大几次。

像这样使用FilterVisualizer:

如果你想玩这个,请随意使用和更换笔记本。如果你不明白每一行,不要担心,首先你可以简单地改变层和过滤器指数,并运行笔记本从上到下。按照 自述文件 中的说明创建一个安装了fastai==0.7.0的 conda 环境。

你能找到其他能识别模式的特征地图吗?如果你想像我在这篇文章中一样用一张图来测试你的假设,请随意使用这个笔记本。如果你发现了很酷的东西,现在就告诉我吧!😃

我希望你和我一样喜欢这些视觉化特征的美丽,并且我能够教你一些有趣的东西。如果有任何不清楚的地方或者你需要更多的解释,请留下评论,我很乐意帮助你理解:)

更新:一位读者给我看了这篇令人兴奋的新 论文 ,它表明神经网络可能无法识别形状,而是对纹理做出反应。看看吧!

如何使用 Geoviews 库在 Python 中可视化地图顶部的数据

原文:https://towardsdatascience.com/how-to-visualize-data-on-top-of-a-map-in-python-using-the-geoviews-library-c4f444ca2929?source=collection_archive---------9-----------------------

所以让我们从我们将要解决的问题开始。假设您有一些数据代表一个特定的数字(如人口),该数字因地点而异(如不同的城市),您希望绘制一个图表来可视化该数据。你是怎么做到的?

一种方法(也是最常用的方法)是创建一个条形图。y 轴代表数字(如人口),x 轴代表地点(如城市)。我敢打赌,这种数据上的绝大多数图都是这种类型的。结果,网上有无数这样的例子,因此我没有必要再增加一个。

幸运的是,有一种更好的方法来可视化这种数据。请记住,情节必须直观,观众才能更好地掌握他们面前的东西。因此,在这种情况下,将数据可视化的更直观的方法是将它们绘制在地图上。有什么比交互式地图更直观的呢?在交互式地图上,你可以放大、缩小和查看你要找的地方或人物。

出于本教程的目的,我们将绘制一个图表来显示我国希腊和邻国土耳其最繁忙的机场的客流量,以便进行比较。

首先,我们需要导入将要使用的库和方法。

import pandas as pd
import numpy as np
import geoviews as gv
import geoviews.tile_sources as gvts
from geoviews import dim, opts
gv.extension('bokeh')

我们的两个数据框架greek_aiportsturkish_airports,分别由客流量排名前 10 位的希腊机场和前 5 位的土耳其机场组成。

Stats for 2018

对于这些数据帧,我们将添加一个额外的列country

greek_airports['country']= 'GR'
turkish_airports['country']= 'TR'

我们还将添加列color。你以后会明白我们为什么这样做。

greek_airports['color']= '#30a2da'
turkish_airports['color']= '#fc4f30'

现在如果我们把这两个数据帧合并成airports

airports = pd.merge(greek_airports, turkish_airports, how='outer')

airports数据帧看起来像这样。

airports dataframe

对于这个例子,我不需要citizens(k)列,所以我将删除它。

airports.drop('citizens(k)', axis=1, inplace=True)

所以最终的airports数据帧看起来会像这样。

airports dataframe

(对于那些想在笔记本上跟随的人,可以在这里找到airports数据框)

现在让我们开始使用 geoviews 模块。具体来说,让我们使用geoviews.Points功能创建一个带有我们的点的情节。

airports_gv_points = gv.Points(airports, ['longitude', 'latitude'],['IATA', 'city', 'passengers','country', 'color'])

airports_gv_points

为了在地图上标出这些点,我们需要一张…地图。geoviews 模块提供了许多我们可以使用的 tilemaps。如果我们输入的话,我们可以看到什么是可用的

gvts.tile_sources

Available tilemaps

例如,让我们使用 CartoLight tilemap。让我们看看我们能得到什么

gvts.CartoLight

CartoLight

现在,我们可以在 CartoLight 的顶部用

gvts.CartoLight * airports_gv_points

gv.Points on CartoLight

这里有几个问题:

  • 剧情维度真的很小。
  • 我不喜欢经纬度的轴标签。
  • 我不喜欢地图上的网格。

我可以通过在gvts.CartoLight上添加一些选项来解决这些问题,比如

gvts.CartoLight.options(width=1300, height=800, xaxis=None, yaxis=None, show_grid=False)  * airports_gv_points

geoviews.Points on CartoLight

现在,因为点仍然只是点,因此它们不能说明客流量,我将使用我们之前导入的opts方法。我们需要的参数是size。此外,为了让数字更接近,我将使用np.sqrt函数来获得它们的平方根。

airports_plot = (gvts.CartoLight * airports_gv_points).opts(opts.Points(width=1200, height=700, alpha=0.3,xaxis=None, yaxis=None,size=np.sqrt(dim('passengers'))*10))

airports_plot

如你所见,我们现在有了互动地图,显示了希腊和土耳其的机场有多繁忙。显然,雅典拥有希腊最繁忙的机场,而土耳其最繁忙的机场位于伊斯坦布尔。

为了使绘图更好,我们可以为每个国家使用不同的颜色,同时我们还可以添加一个悬停工具,以便在我们将光标移动到机场上方时获得一些关于机场的信息。为了添加颜色,我们添加了参数color=dim('color'),它使用我们在color列中指定的颜色,对于悬停工具,我们添加了参数tools=['hover']

airports_plot = (gvts.CartoLight * airports_gv_points).opts(opts.Points(width=1200, height=700, alpha=0.3,color=dim('color'), hover_line_color='black',  line_color='black', xaxis=None, yaxis=None,tools=['hover'],size=np.sqrt(dim('passengers'))*10))

airports_plot

我们甚至可以创建自己的悬停工具来完全控制悬停工具显示的内容。例如,我不希望它显示每个国家使用的颜色代码。
最后,当我将光标放在每个点上时,我希望每个点的颜色变暗一点,所以我添加了参数hover_fill_alpha=0.5

from bokeh.models import HoverTool
tooltips = [('IATA', '[@IATA](http://twitter.com/IATA)'),('Passengers', '[@passengers](http://twitter.com/passengers){0.00 a}m'),('City', '[@city](http://twitter.com/city)'),('Country', '[@country](http://twitter.com/country)'),('Longitude', '$x'),('Latitude', '$y'),]
hover = HoverTool(tooltips=tooltips)airports_plot = (gvts.CartoLight * airports_gv_points).opts(opts.Points(width=1200, height=700, alpha=0.3,color=dim('color'), hover_line_color='black',  line_color='black', xaxis=None, yaxis=None,tools=[hover],size=np.sqrt(dim('passengers'))*10,hover_fill_color=None, hover_fill_alpha=0.5)) 

airports_plot

如果你像我一样喜欢深色主题,你可以随时使用gvts.CartoDark tilemap。

airports_plot = (gvts.CartoDark.options(alpha=0.8) * airports_gv_points).opts(opts.Points(width=1200, height=700, alpha=0.3,color=dim('color'), hover_line_color='black',  line_color='black', xaxis=None, yaxis=None,tools=[hover],size=np.sqrt(dim('passengers'))*10,hover_fill_color=None, hover_fill_alpha=0.5))

airports_plot

今天到此为止。希望你觉得有用。下次见!

你可以点击这里在 LinkedIn 上找到我。

如何赢得房地产投标战

原文:https://towardsdatascience.com/how-to-win-a-bidding-war-in-real-estate-49ef50903449?source=collection_archive---------36-----------------------

利用机器学习预测竞价战中的最优价格

加州马林县是全国最昂贵的住宅房地产市场之一。它也是竞争最激烈的市场之一,2018 年超过 45%的单户住宅收到了多个报价。买家或买家代理人如何确定房屋的最优出价——一个足以赢得竞标战的价格,但又不高于下一个最高出价的价格。本质上这是一个经典的拍卖问题。

下面的 web 应用程序使用户能够确定面临竞价战的房屋的预测价格。预测价格是基于 2015 年至 2019 年的历史数据,所有在马林出售的单户住宅都收到了两个或更多的报价。用户可以选择面积,卧室数量,浴室数量,预期报价和上市价格的数量,应用程序将提供预测的销售价格。

点击此处查看多重报价计算器!

作为一个经验法则,房地产经纪人用每份报价的 2%到 3%来决定竞标中的价格。例如,如果有 3 个出价,那么出价应该比标价高出 6%到 9%。

要使用 web 应用程序,只需选择预测选项卡,选择标准,应用程序将返回预测的报价。有关目标、数据、评估协议和模型选择的说明,请使用解释选项卡。“评估”选项卡提供了用于评估预测相对于实际中标报价的准确性的指标。

我欢迎建设性的批评和反馈,请随时给我发私信。

这篇文章最初出现在我的 GitHub 页面网站上。

在 Twitter 上关注我 @The_Jim_King

马林房地产数据来源:马林 MLS (BAREIS),2015–2019 数据

如何用机器学习在 NFL 中获胜

原文:https://towardsdatascience.com/how-to-win-in-the-nfl-b2b441ca8f5d?source=collection_archive---------12-----------------------

预测足球比赛

你被达拉斯牛仔队聘为防守协调员,你将在超级碗比赛中执教新英格兰爱国者队。我意识到这是一个极不可能的场景,因为牛仔队看起来一点也不像超级碗的竞争者。然而,我们仍然可以使用它作为创建 AI/ML 模型的步骤的示例项目。

在过去的二十年中,爱国者队一直是 NFL 中最好的球队,而爱国者队的四分卫汤姆·布拉迪可以说是同一时期 NFL 中最好的球员。作为防守协调官,阻止爱国者将是一项巨大的任务。但是,我们这边有优势:AI/ML。让我们设计一个流程,看看我们是否能在事情发生之前预测到,这将使我们能够相应地调整我们的防御方案。对于这个例子,我们将使用 Python 和 sklearn 。我们将遵循以下流程:

  1. 获取或生成数据
  2. 为探索性数据分析(EDA)准备数据。
  3. 分析数据以寻找潜在的模式。
  4. 为 AI/ML 模型准备数据。
  5. 训练和评估你选择的 AI/ML 模型。

获取或生成数据

你首先需要的是一个数据集。如果您无法访问相关的数据集,您可以使用类似于本文的流程生成一个样本数据集。对于我们的例子,我们将使用这个数据集,其中包含自 2009 年以来运行的每场 NFL 比赛的信息。它在 Kaggle 上主持。如果你不熟悉 Kaggle,它是一个编码竞赛网站,有许多不同的数据集;当我想找到一些数据时,这通常是我首先检查的地方。

一旦我们下载并解压缩了文件,我们需要它的格式能够让我们探索数据。为此,我们将使用 Pandas,这是一个 Python 库,其中包含许多修改和探索数据集的函数。下面是从我们的 CSV 文件加载数据帧的代码:

import pandas as pd
import matplotlib
from sklearn import preprocessing
%matplotlib inline
df = pd.read_csv('data/nfl_plays.csv')

为探索性数据分析(EDA)准备数据

EDA 是探索数据问题(缺失值、错误输入的数据等)的过程,希望我们可以看到数据中的一些趋势。

首先,让我们看看已经加载了多少行和列:

df.shape

这给出了:

(449371, 255)

如您所见,这个数据集中有很多信息(255 列)。如果能知道每个字段代表什么就好了。经过一番挖掘,我最终找到了这个页面,它描述了所有的栏目以及它们的含义。我对这些领域感兴趣:

  • posteam —拥有控球权的球队(在这种情况下,我们只需要 NE)
  • game_seconds_remaining —游戏还剩多少时间
  • yardline_100 —团队在哪个码线上(比例为 100)
  • 下降—我们处于什么水平(1.0、2.0、3.0、4.0)
  • ydstogo——第一次进攻所需的码数
  • 散弹枪——他们排成散弹枪队形了吗?
  • 分数差异—他们的分数—我们的分数
  • 比赛类型——比赛的类型(跑动、传球等)
  • run_location —他们朝哪个方向跑了(左、中、右)
  • pass_location —他们朝哪个方向走了(左、中、右)

我们还可以使用其他字段来帮助预测,但是让我们先使用这些字段。下面是根据这些行和列进行过滤的代码

#filter rows
nedf = df[(df.posteam=='NE') & (df.down.isin([1.0, 2.0, 3.0, 4.0])) & ((df.play_type=='run') | (df.play_type == 'pass'))]#filter columns
nedf = nedf[['game_seconds_remaining', 'yardline_100', 'down', 'ydstogo', 'shotgun', 'score_differential', 'play_type', 'pass_length', 'pass_location', 'run_location']]nedf.head()

此时,在开始 EDA 之前,我们还有一个步骤。我们试图预测的值由依赖于 play_type 的四列表示。例如:

  • 如果玩法类型是“跑步”,则会填充跑步位置,但不会填充传球位置。
  • 如果玩法类型是“传球”,则传球位置将被填充,而跑动位置不会被填充。

我们需要将所有这些值合并到一个字段中。下面是实现这一点的代码(注意,我们还过滤掉了 location='unknown '):

import numpy as np
def get_full_play_type(play):play_type, pass_location, run_location = playif(play_type == 'run'):return play_type+'_'+ run_locationelse:return play_type+'_'+ pass_location
nedf = nedf.replace(np.nan, 'unknown', regex=True)    
nedf['full_play_type'] = nedf[['play_type','pass_location', 'run_location']].apply(get_full_play_type, axis=1)
nedf = nedf[(nedf.full_play_type.isin(['pass_left', 'pass_middle','pass_right','run_left', 'run_middle', 'run_right']))]

这段代码将创建一个名为 full_play_type 的列,这就是我们试图预测的。让我们最后看一下我们的数据,以确保一切正常:

nedf.head()

分析数据以寻找潜在的模式

首先,让我们看看我们的 full_play_type 包含哪些值:

nedf.groupby(['full_play_type']).count()[['play_type']]

如你所见,如果我们随机猜测下一出戏,我们有六分之一的机会(16.66%)是正确的。我们将以此为基准,看看我们是否可以改进。

有时以图表形式查看会有所帮助:

nedf.groupby(['full_play_type']).count()[['play_type']].plot(kind='bar')

接下来,我们来了解一下哪些重头戏按占总数的百分比被调用:

nedf.groupby(['full_play_type']).count()[['play_type']].apply(lambda x:100 * x / float(x.sum()))

我们的预测已经有所改进了!如果我们预测每场比赛的 pass_left,我们的正确率是 23%对 16.66%。我们还可以做得更好。

为 AI/ML 模型准备数据

AI/ML 模型需要数字输入和输出。当数字规模相似时,它们也能更好地工作。在本节中,我们将利用一些不同的技术来实现这一点。

首先,我们将使用 sklearn 的预处理库将我们的 full_play_types 转换为 numeric:

le = preprocessing.LabelEncoder()
le.fit(nedf.full_play_type)
nedf['full_play_type_code'] = le.transform(nedf['full_play_type'])

这将创建一个名为 full_play_type_code 的列,它是 full_play_type 的数字表示。让我们看看 full_play_type_code 数据,确保它仍然与 full_play_type 匹配。

nedf.groupby(['full_play_type_code']).count()[['down']].plot(kind='bar')

正如您所看到的,图表与上面的图表相匹配,但是现在 x 轴是一个数值,而不是文本。

接下来,我想简化 ydstogo 值。从技术上讲,这可以是 1 到 99 之间的一个值。但是,我想将这个距离放入一些桶中(1-4 码、5-8 码、9-12 码、13-16 码、≥17 码),这将使我们的模型能够识别模式。我选择的范围是任意的,可以很容易地修改。

def bucketize(val, size, count):i=0for i in range(count):if val <= (i+1)*size:return ireturn idef bucketize_df(df):df['ydstogo'] = [bucketize(x, 4, 5) for x in df['ydstogo']]return dfnedf = bucketize_df(nedf)

现在,我想对 down 和 ydstogo 列进行热编码,这意味着我们将把行“透视”到列,并用“1”填充包含我们正在编码的值的列,否则为 0。例如,足球比赛中有四个回合。当我们对 down 列进行热编码时,我们将得到四列,其中 1 只被填充一次。如果我们要对一个表示第三个向下的行进行热编码,我们将得到新列的这些值[0,0,1,0]。请注意,第三列是唯一包含 1 的列。这样做的好处是,我们的 down 和 ydstogo 数据现在表示为 0 和 1,这也应该有助于我们的模型学习。sklearn 中的代码非常简单:

nedf = pd.concat([nedf, pd.get_dummies(nedf['down'], prefix='down')], axis=1)
nedf = pd.concat([nedf, pd.get_dummies(nedf['ydstogo'], prefix='ydstogo')], axis=1)

以下是我们的数据样本此时的样子:

现在,你可以看到 ydstogo_和 down_用 0 和 1 表示。但是,game_seconds_remaining、yardline_100 和 score differential 列仍然与零和一处于不同的刻度。例如,“游戏剩余秒数”包含 0 到 3600 之间的值。

我们可以通过在列中添加一些数学来解决这个问题。首先,让我们看看这些列包含的值的范围。

nedf.describe()

在本练习中,我们将查看最小值和最大值,并使用它们将数据标准化为介于 0 和 1 之间的值。game_seconds_remaining 的最小值是 3,而最大值是 3600。我们将游戏剩余时间除以 3600。Yardline_100 将除以 100。对于分数差异,我们将应用以下公式:

(score_diff + min_diff) / (max_diff-min_diff)

然而,为了简化,我们将对 min_diff 使用-50,对 max_diff 使用 50。我们的逻辑是,如果你赢了或输了超过 50 分,此时你脑子里想的是别的事情。下面是我们应用这些公式的代码:

nedf['game_seconds_remaining']/=3600
nedf['yardline_100']/=100
nedf['score_differential']=(nedf['score_differential']+50)/100

现在,如果我们看看我们的数据集,这是我们得到的结果:

我们现在已经将所有的输入字段转换为 0 到 1 之间的值,所以我们准备在模型上进行试验。

训练和评估你选择的人工智能/人工智能模型

在本教程中,我们将使用 RandomForestClassifier 来看看我们能否预测下一场比赛。但是首先,我们需要去掉我们的模型中不需要的所有列。然后,我们需要将数据分成一个训练集和一个测试集,每个测试集包含一个 X(输入数据)和 y(结果数据)。这可以用三行 Python 快速完成。

from sklearn.model_selection import train_test_split#select important columns for input
X=nedf[['yardline_100', 'shotgun', 'score_differential', 'game_seconds_remaining', 'down_1.0', 'down_2.0', 'down_3.0', 'down_4.0','ydstogo_0','ydstogo_1','ydstogo_2','ydstogo_3','ydstogo_4']]#select result column for output
Y=nedf['full_play_type_code']#split data for train and test
train_x, test_x, train_y, test_y = train_test_split(X, Y, random_state = 0)

此时,我们可以训练我们的模型来拟合输入数据。

from sklearn.ensemble import RandomForestClassifier
the_clf=RandomForestClassifier(max_depth=8, n_estimators=64)
the_clf.fit(train_x, train_y)

现在我们的模型已经被训练好了,让我们看看它在我们的测试数据上得分如何。

from sklearn.metrics import accuracy_score
pred = the_clf.predict(test_x)
acc =accuracy_score(test_y, pred)
print(acc)

我们现在能够在 31%的时间里预测正确的打法,这听起来可能不太好,但请记住,这几乎是我们开始随机猜测的两倍(16.66%),比仅仅猜测他们最喜欢的打法好 25%(pass _ left,23%)。

后续步骤

仅用几行 Python 代码,我们的教练技能几乎提高了一倍。然而,您可能已经注意到,我们编写的大部分代码都与组织和管理我们的数据有关。现在我们已经完成了,我们可以使用这些数据来训练更复杂的模型。

在我们的下一篇文章中,我们将探索四种技术,利用我们处理过的数据生成更好的预测:

  1. 过采样/数据扩充
  2. 型号选择
  3. 模型评估
  4. 模型调整

感谢阅读,本文的代码将托管在 github 上。

如何可视化地处理数据—R 语言教程

原文:https://towardsdatascience.com/how-to-work-visually-with-data-tutorial-in-r-6841be051f2f?source=collection_archive---------34-----------------------

了解如何在对数据集应用 ML 算法之前对其进行可视化解码

数据就是数字。人类并不擅长同时处理大量数字。人类是视觉动物。因此,在你开始对数据应用机器学习之前,获得数据的可视化解释总是有意义的。

Photo by Austris Augusts on Unsplash

1.第一步—准备数据

每个机器学习项目都是从准备数据集开始的。本文描述了一个 ML 项目的整个生命周期。我们将选择一个准备好的数据集。

我们将使用来自 r 包 mlbench 的玻璃数据集

Glass Dataset

它有 214 个观察值,包含 7 种不同类型玻璃的化学分析实例。

2.安装并加载库

在本教程中,我们将使用 2 R 库。

  1. ML 工作台
  2. Corrplot
**#clear all objects**
rm(list = ls(all.names = TRUE))
**#free up memrory and report the memory usage** gc() **#Load the libraries** library(mlbench)
library(corrplot)

3.加载数据

然后,我们实际加载数据集并显示它的前几个数据点。

**#Load the dataset** data("Glass") **# display first 10 rows of data** head(Glass, n=10) **# display the dimensions of the dataset** dim(Glass)

我们很快就掌握了哪些列以及它们各自的取值范围。如果你的数据集很大,这是常有的事,你可以取一个小样本来检查。

快速浏览一下,我们可以看到这些列对应的是化学元素—(钠:钠,镁:镁,…)。

我们还看到每一行都有 9 个不同的特征。所有这些都有助于形成玻璃。最后一栏告诉你玻璃的实际类型。

这样的数据集可用于建立逻辑回归模型,该模型基于 9 个特征预测玻璃类型。

记录数据的维度也能让我们了解数据集有多大

4.了解每个功能

然后,我们试图掌握数据的统计和其他属性

**# list types for each attribute**
sapply(Glass, class)
**# standard deviations and mean for each class**
y<-sapply(Glass[,1:9], mean)
sapply(Glass[,1:9], sd)
xn<-colnames(Glass[,1:9])
x<-c(1:9)
y<-sapply(Glass[,1:9], mean)
barplot(y, main = "Average Value For Each Feature",xlab = "Feature Name",ylab = "Average Value")

我们还可以查看数据类型来评估数据兼容性。

注意,最后一列是称为因子的分类数据类型,其余的是数字浮点。这个信息非常重要,因为类型决定了进一步的分析、观想的类型,甚至是你应该使用的学习算法。

我们还可以绘制每个特征的标准偏差来指导我们稍后的标准化过程。

标准差和均值都是有用的工具

例如,对于高斯分布,它可以作为一个快速剔除异常值的工具,任何大于标准偏差三倍的值都被视为异常值。

5.了解每个类

Number of data points in each class

除了根据数据的特征查看数据之外,我们还可以分析每个类。一个快速测试的东西可能是类分布

在任何分类问题中,您必须知道属于每个类值的实例的数量。这充当了数据集中不平衡的快速测试。在多类分类问题的情况下,可能会暴露具有少量或零个实例的类,这些实例可能是从数据集中移除的候选。这可以通过再平衡技术来增强。

**# distribution of class variable**
y <- Glass$Type
cb <- cbind(freq=table(y), percentage=prop.table(table(y))*100)
barplot(table(y), main = "Frequency Distribution of All Classes",xlab = "Class Name",ylab = "Number of Data Points", legend = TRUE)

6.特征之间的关系

courtesy the corrplot library

要考虑的最重要的关系之一是特征之间的相关性。在 ML 中,我们从不需要高度相关的特征。本文展示了使用 Python 实现 KNN (K 近邻)算法时检测这些特征的技术。作为 R 中的一个快速测试,我们可以做以下事情

**# calculate a correlation matrix for numeric variables**
correlations <- cor(Glass[,1:9])
**# display the correlation matrix**
print(correlations)
corrplot(correlations, method = "circle")

正相关显示为蓝色,负相关显示为红色。颜色强度和圆圈的大小与相关系数成正比。

我们可以很容易地看到,Ca 与 RI 高度相关,可以从我们的分析中去掉其中一个。

xkcd

可视化解码数据集为您提供了理解数据集的最快方式。这成为实际应用机器学习算法的一个非常重要的先驱。

如何使用大地理空间数据

原文:https://towardsdatascience.com/how-to-work-with-big-geospatial-data-4ba919a8ffc2?source=collection_archive---------8-----------------------

我作为一名自由 webGIS 开发人员已经工作了三年多,在此之前,我获得了地理信息学学士学位,所以我必须与地理空间数据打交道。

地理空间数据变大并不罕见,尤其是在处理栅格数据时。几千兆字节的数据非常常见,大多数桌面 GIS 软件(如 ArcGIS 和 QGIS 等。)通常能够处理这么多数据。

但是如果数据变得非常庞大怎么办?比如兆兆字节或者千兆字节?

例如,当您必须在国家或大陆范围内处理高分辨率多光谱或高光谱图像的镶嵌时。这时数据集的大小可能会膨胀到万亿字节甚至千兆字节,真正的麻烦就开始了,因为传统的 GIS 软件无法轻松处理如此大量的数据。

这时,你必须开始寻找桌面 GIS 软件的替代品,因为关于这个主题的在线帮助还不多,所以我想我应该分享我的经验,以帮助那些期待使用大型地理空间数据集的人。以下是我在这种情况下推荐的一些工具和技术:

1.谷歌大查询地理信息系统

Google BigQuery 是 Google 的一个工具,用于数据仓库和对大型数据集进行分析。幸运的是,它还附带了一个名为 Bigquery GIS 的空间扩展。这里有一个简短的介绍:

Google BigQuery GIS

值得注意的是,BigQuery 有其自身的局限性,例如,它只能与 WGS 84 投影(EPSG: 4326)一起工作,并且没有其他开源 GIS 数据库(如 PostGIS)那么多的功能。

但是当涉及到大型数据集时,没有什么能打败 BigQuery GIS。我曾经试图在 PostGIS 中从一个巨大的数据集(它有超过 7 亿条记录)中找到错误的多边形,几乎需要一天的时间才能找到它们,而 BigQuery GIS 能够在不到 3 分钟的时间内找到它们。

如果你有兴趣,你可以在这里阅读更多关于 BigQuery GIS 及其可用功能的内容。

2.开源库和二进制文件

处理这种数据集的另一种方式是拥有一个进程,并通过开源库和二进制文件以编程方式运行它,您可以在 shell 脚本中使用它们以获得优势。

OpenSource tools capable of handling large GIS datasets

我的团队曾经在 Linux 环境中使用 python GDAL 绑定(我们编写了 python 脚本)处理数万亿字节的数据,还使用了一些 ogr2ogr 命令,并将它们全部封装在 bash 脚本中,这些脚本将一个接一个地执行所有步骤。对于一个非常大的数据集,我们使用格网将大陆尺度的栅格划分为数百个小方块,单独处理它们,最后合并最终结果。这项技术甚至可能需要几天才能完成,但它能够处理非常大的数据集。

这些脚本也可以使用不同的工具和技术来加速。一旦我们有了一个 python 脚本来处理大型数据集,一名团队成员使用 Google DataFlow 对其进行扩展,原本需要几天的过程可以在几分钟内完成,使我们能够处理大量数据。

3.空间 Hadoop

Apache Hadoop 是一个开源软件实用程序的集合,有助于使用许多计算机的网络来解决涉及大量数据和计算的问题。它还带有一个地理空间扩展,被称为 SpatialHadoop 。到目前为止,我自己还没有使用过它,但是如果没有 SpatialHadoop,谈论处理地理空间大数据是不公平的。

SpatialHadoop 具有对空间数据的原生支持,并且知道位置。它使用传统的地理空间索引,如 R 树、网格等。在 Hadoop 代码基础之上,从而使其具有位置感知能力。

4.谷歌地球引擎

Google Earth Engine 无疑是处理地理空间数据的最好和最简单的工具之一。它拥有数 Pb 来自遥感卫星的开源图像,并持续实时接收这些图像,你可以不用下载就能使用它们。它还处理它们以创建其他数据集。下面简单介绍一下地球发动机:

Introduction to Google Earth Engine

Earth Engine 附带了一个已经可用的无数数据集,你可以进一步做波段计算和/或使用其他函数根据你的需要操纵这些数据集。它还允许你在简单的平台中上传和操作你自己的数据集。它看起来是这样的:

Google Earth Engine Platform

Earth Engine 最棒的地方在于,它完全免费用于研究和非商业目的。如果你懂 Python 或者 Javascript,你很容易上手。还可以准备实时图层,添加到谷歌地图中,使用谷歌地球引擎创建令人兴奋的网络地图。

我已经使用地球引擎来监测洪水,监测植被及其变化,并监测降雨和降雪。尽管如此,我从来不需要在我的电脑上下载大量的卫星图像。在未来,我会写更多的博客来展示地球引擎的实际应用,并分析不同的现象,如洪水、森林砍伐和森林火灾等。

编辑:以下是人们在回应这个故事时推荐的工具和技术,我没有使用过它们,但我想我也应该添加它们,因为它们似乎也做得很好。

5.AWS 雅典娜

Amazon Athena 是一种交互式查询服务,它使得使用标准 SQL 直接分析 Amazon 简单存储服务(Amazon S3)中的数据变得很容易。

这也支持地理空间数据类型,并提供地理空间查找和功能。

AWS Athena

6.波斯特吉斯

现在你一定在想为什么是波斯特吉斯?我甚至将其与 Bigquery GIS 进行了比较,后者的性能不如前者。我个人将它用于较小的数据集,在使用它处理大型数据集时没有太多经验。但事实证明,如果数据集大小在几兆字节左右,甚至可以使用 PostGIS。

但是在那种情况下你必须让它工作。你需要非常依赖于分析和解释,并且你必须虔诚地监控日志以减少你的查询。您需要对表进行优化和索引,积极的清空是必不可少的。

7.NoSQL 和图形数据库

像 MongoDB 和 ElasticSearch 这样的 NoSQL 数据库擅长处理大型数据集,并且有不错的地理空间支持。我们也有像 Neo4j 这样的图形数据库,它们擅长处理大型数据集并支持地理空间查询。

边注

要了解地理空间大数据的运行情况,请看一下滑翔机。我们使用谷歌 BigQuery GIS 和开源库和二进制文件来处理大量数据,以建立这个可以实时监控野火的网站。如果你有兴趣了解更多关于它是如何制作的,可以看看 CTO 的博客

[## GlideFinder:我们如何在谷歌云上建立一个可以监控野火的平台|谷歌云博客

我们选择 Google Cloud infrastructure 是因为它的可扩展性(允许数百万并发用户从…

cloud.google.com](https://cloud.google.com/blog/products/data-analytics/glidefinder-how-we-built-a-platform-on-google-cloud-that-can-monitor-wildfires)

没有“一种工具可以统治所有人”

现实世界的问题是复杂的,它们互不相同,处理这些问题所需的数据集的性质也各不相同。你不能指着一种工具或技术说它可以帮助所有的数据集。您应该选择哪个选项始终取决于您想要实现的目标,并且在许多情况下,您需要使用不同工具、技术和技巧的组合。

我是拉米兹·萨米。我爬山、举重、构建 WebGIS 解决方案。请随时在 Linkedin 上与我联系。

作为数据科学家,如何与利益相关方合作

原文:https://towardsdatascience.com/how-to-work-with-stakeholders-as-a-data-scientist-13a1769c8152?source=collection_archive---------11-----------------------

Image source

数据科学家最重要的技能之一是能够与利益相关方有效合作。你的影响力将取决于你与产品经理集思广益、与工程师合作以及说服高管的能力。这确实是工作中令人兴奋的部分,然而,很难找到做好它的建议。过去两年,我在 Booking.com 和优步的产品团队中担任数据科学家。这里有一些在项目过程中与利益相关者合作的技巧,我希望我在开始时就知道。

1。将请求转化为对话

当一个利益相关者向你要求一个特定的产出时,这个产出几乎总是实现其他目标的手段。尝试将请求转化为关于他们主要目标和实现目标的最佳方式的对话。

例如,假设产品经理要求您尝试取消用户在注册时提供邮寄地址的要求。如果产品经理的主要目标是推动转化,你可能会认为从详细的漏斗分析开始有助于发现更有影响力的机会。

一个类似的想法支撑着基于利益的谈判,它建议谈判各方应该探索他们的潜在利益,而不是他们来到谈判桌前的更直接的立场。作为一名数据科学家,不要只关注利益相关者的初始立场(他们的直接要求),要理解支撑这一立场的利益。

2。学会说不

作为一名数据科学家,在开始工作的前几周内,你会收到比可能处理的更多的请求。接受你无法完成的请求对任何人都没有帮助,所以你必须说不。但是如果你用错误的方式说不,你会惹恼很多人。这里有一些我认为有用的技巧。

从假设最好的情况开始,或者至少意识到你缺乏完整的信息。例如,如果你收到一个请求,你认为这个人应该照顾好自己,你可能会很容易忽略它或者没好气地回应。停下来!你有可能遗漏了一条重要的信息,而这个要求比你想象的更合理。不管怎样,得罪任何人都没有意义。

即使你的回答是出于好意,说“不”而不引起别人的反感也是不容易的。我发现一个有用的方法是“将人们与问题分开”,这是基于利益的谈判的另一个有用的教训。将讨论框定为两个人一起努力解决如何最好地投资数据科学资源的问题,而不是你拒绝他们的个人请求。

第二个与之密切相关的策略是,公开你不优先考虑某个项目的原因。拥有每个人都同意的目标可以让你更容易对不太重要的想法说不。说不不是一场政治或情感辩论,而是对承诺的理性回应。”组织有序的任务积压也有助于将潜在的紧张分歧转化为关于在哪里消磨时间的理性讨论,即使当优先事项不明确并成为对话的一部分时。

真诚地讨论如何最佳利用你的时间也会让你更有效率,因为有时你会发现“不”实际上是错误的答案。

3。管理预期

当你刚开始一份工作,一位同事问他们要等多久才能得到他们急需的东西时,你很想告诉他们你认为他们想听的话,或者至少说些积极的话。抵制诱惑!

我们系统地低估了任务需要多长时间,因为我们专注于眼前的事情,忽略了“未知的未知”,例如,你实验中没有预料到的错误。与此同时,根据期望-不一致理论,人们的期望和他们感知的结果之间的差距在形成他们的满意度方面发挥了很大的作用。

把这两种心理现象放在一起,你就有了制造麻烦的方法。你给利益相关者你过于乐观的估计(可能为了让他们高兴而进一步夸大)设定了很高的期望,然后当你不能实现时,他们对你的看法就崩溃了。所以在管理期望时要小心。

Image source

帮助解决你预测中过度自信的一个策略是事前分析:在你开始之前,想象一下这个项目非常糟糕,然后写一份事后分析。如果你认为一个完整的预死亡是多余的,至少花点时间想想可能会出错的不同事情。考虑潜在的陷阱将有助于限制你的过度自信,并在问题发生前抓住它们。

4。了解背景并拥有执行力

本·霍洛维茨认为,好的产品经理应该“了解背景……并负责设计和执行一个成功的计划(没有借口)。”数据科学家也是如此,因为你也应该在推动项目前进中发挥作用。

当作为一个更大的团队的一部分从事项目时,不要把头埋在数据里。深刻理解问题的来龙去脉,有助于你更好地开展工作。与利益相关者沟通也很重要,因为如果你不能回答一个关于大项目的基本问题,这将损害你的可信度。

一旦你投入到一个项目中,掌握细节和执行。例如,您对用于部署您的模型的代码理解得越多,您就越有可能在问题出现之前发现它们。一个项目的结果比谁做了什么更重要,因此,超越你的严格责任,取得项目的成功。

5。产生最小可行分析

从产生一个最小可行的分析开始:最快的分析将让你开始测试你的项目的可行性。然后迭代并改进你最初的工作。例如,如果您正在构建一个预测模型,从一个简单的模型和几个有前途的特性开始。

从与利益相关者合作的角度来看,从最基本的可能分析开始有两个好处。首先,你要么有东西可以展示你的工作,要么可能很快失败,如果项目不工作的话。你不希望自己在第一个项目中花了三周时间构建一个复杂的模型,却没有任何东西可以分享,也不确定是否会产生任何有用的东西。

Image source

第二,从一个简单的分析开始可以让你在迭代的时候得到反馈。最小可行产品的想法是从产品的最小版本开始,允许一个完整的构建循环,测量产品的性能,并学习。在进行分析时,您可以考虑类似的循环,测量阶段包括获得反馈。我不会把你的结果告诉这里的一大群人。相反,向少数人寻求反馈,比如产品经理或其他数据科学家。

这种迭代工作流不是构建数据科学项目的唯一方式,但它是一种有效且低风险的方法,尤其是对于团队中的第一个项目。

6。经常清晰地沟通

作为一名产品经理,Lenny Rachitsky 注意到,“过度沟通非常困难”。对数据科学家来说也是如此,因为你经常会帮助管理项目。当项目被延迟时,频繁的交流尤其有价值,但却很容易避免。定期传达信息让利益相关者了解最新进展,并帮助他们确信你正在处理问题。

优秀的数据科学家,就像优秀的产品经理一样,“宁可选择清晰。”分享见解时非常注意清晰。你需要确保你的发现能很快被理解并被正确解释。例如,如果你的结果只适用于一个特定的用户群体,那么就要清楚地表明,人们应该谨慎地推断出更广泛的人群。

你还应该特别注意用书面形式清晰地交流。与我共事的一位工程经理 Gergely Orosz 强调,文笔好能让你“提升你与多个团队、一个组织或整个公司有效沟通的能力。”作为一名数据科学家,写好文章的一个关键部分是避免错误。你要求人们根据你的数字做出重大决定,如果你写的东西充满错别字,他们会发现很难相信你的勤奋。在分享之前,一定要通读邮件和文件,检查错误。

7。广泛沟通:让你的工作引人注目

沟通的重要性并不仅限于完成分析或部署模型。确保让你的项目在你的直接团队之外可见。

Photo by Headway on Unsplash

有很多方法可以做到这一点:在你的项目还在进行的时候,主动与人讨论你的项目(你也可能得到有用的信息),写下你的项目,并广泛传播一封链接到它的电子邮件(确保在电子邮件中包含你的要点的摘要),创建常见问题解答、论文和其他资源,人们可以利用这些资源(一个有说服力的情节可以走得很远),或者在内部或外部活动中展示你的结果。

如果人们看到你正在做的工作,这对你的职业生涯有好处,但这不仅仅是自我推销。让你组织中的其他人知道你在做什么,对于避免重复工作和寻找合作机会非常有帮助。

我希望这篇文章对你有所帮助。这个列表是主观的,远非详尽,如果有更多关于数据科学家如何在组织内有效工作的讨论,那就太好了。因此,如果你有任何不同意见或有其他建议要分享,请在下面发表评论或在推特上联系。

大大感谢 马克*尼克 小纳 对本帖草稿的审阅。*

如何在媒体上写一篇成功的数据科学文章

原文:https://towardsdatascience.com/how-to-write-a-successful-data-science-article-on-medium-e984c3eb1b39?source=collection_archive---------8-----------------------

获得你应得的掌声的秘方

介绍

既然您正在阅读这篇文章,那么您可能至少是在随意阅读 Medium 上的数据科学文章。也许你自己也在写。如果是这样,您是否想过是什么让一篇关于 Medium 的数据科学文章取得成功?为什么你会把所有的努力投入到一个深入分析的项目中,然后却忽略了以一篇关于媒介的文章的形式呈现它的所有分析方面?

作为一个有分析头脑的人,我不只是想继续写我的文章,而不知道我的文章是否符合一篇成功的关于媒体的数据科学文章的要求。相反,我想找出是否有特定的特征使某些文章比其他文章表现得更好。在这种情况下,性能指的是一篇文章获得的掌声数量。

工作流程

现在,我是如何着手解决这个问题的呢?让我们先来看看我的工作流程:

您可能知道,没有包含所有标记为“数据科学”的媒体文章的可用数据集。因此,我不得不通过使用 Selenium 和 Python 抓取 Medium 的文章存档来自己创建数据集。为了确定是什么让一篇文章成功,我决定从每篇文章中收集以下信息:

首先,我显然需要掌声的数量来决定文章的成功与否。第二,我刮掉了标题、出版日期和阅读文章需要多长时间,因为这些和标题图片是人们在浏览文章时首先看到的东西。最后,我收集了文章文本本身和每篇文章的标签:

最终,从 2018 年 12 月 19 日到 2019 年 1 月 3 日,我收集了 736 篇文章。这部分被证明是一个挑战,因为 Medium 上的“最新文章”页面通过向下滚动来加载新文章,而不是点击类似“下一页”的按钮。

在 CSV 中收集了我需要的数据后,我将其导入 Python,并使用 Pandas 将其转换为数据帧。与大多数未处理的数据集一样,它需要相当多的数据清理。这包括从我的数据中提取更多的信息,例如,将标题的字符数存储为一个单独的列。数据清理的另一个有趣的方面是,出版物数据以 ISO 8601 格式存储(包括长达微秒的信息),即使您在网站上只能看到日、月和年。由于 Medium 还在“最新文章”页面上列出了标记为“数据科学”的文章的评论,我删除了这些评论,并将所有文本转换为小写,以确保在分析过程中不会重复计算某些单词。

探索性数据分析

技术细节说够了。我们来看看数据。因为我们用掌声来衡量成功,所以知道掌声的分布情况会很有趣。

不幸的是,似乎绝大多数数据科学文章根本没有得到任何掌声。掌声的分布严重向右倾斜,平均为 58.3 次。如果你的文章获得了 49 次掌声,你已经获得了超过 75%的数据科学文章的掌声。这表明,有几篇异常文章比其他所有文章获得了更多的掌声。

文章的长度呢?毕竟,你阅读文章的时间是你文章的潜在读者首先会浏览的内容之一。

这个分布看起来仍然有点右偏,但是,它似乎集中在 5 分钟左右。正如人们所料,除了少数很长的文章外,大多数文章都很短。该数据集中最长的数据科学文章将花费读者大约 26 分钟来阅读。直觉上,人们会认为文章只要能阻止潜在读者点击文章。

另一个重要的方面涉及标签的数量和类型。对于 Medium 上的每篇文章,您最多可以选择五个标签。人们自然会认为所有作者都充分利用了这一点,并选择了五个标签来最大化他们文章的可见性,但事实并非如此:

不管出于什么原因,该数据集中 51%的作者使用的标签少于 5 个。这似乎是许多作者可以很容易提高他们文章的可见性的一个方面。

文章的标题极其重要。因此,在深入研究如何撰写一篇成功的数据科学文章之前,值得看一看标题的长度和标题中最常用的单词。

这种分布以大约 47 个字符(包括空格)的平均值为中心。常用词,忽略'和'等填充词,包括'数据科学'、'机器学习'和' python '。

如何写一篇成功的数据科学文章

现在是你期待已久的时候了。如何写出一篇成功的数据科学文章?我需要注意哪些特点?

别担心,你的问题现在会得到解答。为了定义成功,我在我的数据框架中添加了一个百分点列,并创建了一个单独的数据框架,只包含那些获得超过 80%的文章的文章,并检索它们的特征。

让我们一步一步地了解每个方面:

我应该用什么标题?

你的标题应该有 47-48 个字符的长度,包括空格(成功文章标题的意思)。你应该用什么词?看看成功文章中最常用的 5 个词:

使用“数据科学”和“机器学习”似乎是一个好主意。我决定不删除“with ”,因为这可能意味着指定您使用的编程语言也会影响成功。

我应该使用多少和什么标签?

不出所料,答案是 5 !与 51%的文章相比,只有 19%的成功文章使用少于 5 个标签。与标题类似,让我们来看看成功文章最常使用的具体标签:

显然,你不应该只是给你的文章贴上不真实的标签。这表明,如果你的文章涉及这五个主题,它更有可能获得更多的掌声。

我的文章应该有多长?

成功文章的平均阅读时间比所有文章稍长,平均约为 6.5 分钟,这表明将目标定在6–7 分钟* 是个好主意。平均而言,成功文章的总文本长度(同样包括空格)大约为 6750 个字符 。*

我应该什么时候发布?

不要忘记把出版时间也算进去!由于我收集的所有时间戳都是 UTC(协调世界时),你可能需要根据你的居住地做一些调整。

从这个 seaborn distplot 可以明显看出,大多数成功的文章都是在 UTC 下午 3 点左右发表的

最后一点,有一个吸引人的标题图片在让读者点击你的帖子方面也起着很大的作用。在免费的股票图片网站上找到一些或者自己创建它们应该不会太难。

结论

如果您遵循所有这些说明,那么您的文章也将具有成功的数据科学文章的特征,并且看起来像您刚刚阅读的文章。

一如既往,如果您有任何反馈或发现错误,请随时联系我。

如何写作者回应/反驳信

原文:https://towardsdatascience.com/how-to-write-author-response-rebuttal-letter-1aebbf7f3354?source=collection_archive---------32-----------------------

关于任何 ML,NLP,CV 会议

Photo by Green Chameleon on Unsplash

在本帖中,我将简单总结一下我所学到的写好作者回应/反驳信的方法。如果你想要更详细的,我强烈推荐阅读参考部分列出的文章。

方法:确定主要问题

不管评论是长是短,我们首先要做的是找到审稿人认为论文不应该被接受的主要问题。主要问题可能不只是一个,我们需要确定所有问题,并逐一做出回应。

至于其他小问题,像格式和打字错误,我们应该诚实地承认并承诺改变它们。

简单的响应格式

不管是主要问题还是次要问题,我们都可以用下面的格式来回应。

  • 注释:粘贴审阅者的注释。
  • 回应:先谢谢评论者,表示尊重。然后写下你对评论的回应。
  • 承诺:尽可能详细的告诉审稿人你会修改哪部分,你会如何修改。

下面是一个例子

-(comment) The main issue with this paper is that the analysis is not particularily informative or well carried out. It is not surprising that xxxx are important for xxxx, .....-(response) Thanks for the comment. We agree that the conclusion xxxx may be unsurprising. But we think xxxxxx. The figure xxx shows that xxxx, and table xxx also points out xxxx.-(commitment) We will modify the xx section (page xx, line xx) to make the statement more clear.

查看我的其他帖子 一个分类查看
GitHub:
荆棘徐 领英: 徐亮 博客:

参考

  • https://agtb . WordPress . com/2012/03/31/an-insiders-guide-to-author-responses/
  • https://sites . umi ACS . UMD . edu/elm/2016/11/19/writing-outlets/
  • https://peerj.com/benefits/academic-rebuttal-letters/

如何成为一个精明的机器学习博主:从零到英雄

原文:https://towardsdatascience.com/how-to-write-machine-learning-like-a-pro-d2a2ebfc4041?source=collection_archive---------23-----------------------

数据科学:技术写作

要遵循的 5 条规则和要避免的陷阱

Photo by Denerio Watkins on Unsplash

最近更新于 2020 年 1 月 4 日

权力越大,责任越大。

机器学习是强大的。

向《走向数据科学》的编辑们大声喊一声:安妮·邦纳和卢多维克·贝尼斯坦特,并向我的数据科学家同事们致以最美好的祝愿。

写作对每个人来说都是痛苦的。

尽管我很享受从我的笔(或键盘)里出来的最终产品,但写作的过程本身是痛苦的。

大约两个月前,我开始写关于因果推理、机器学习和媒体数据科学的技术博客。截至今天(2019 年 12 月 1 日),我在 10 月份贡献了 12 篇帖子,在 11 月份贡献了 6 篇帖子,几乎都是由《走向数据科学》发布的,并由中型策展人挑选。

在过去的两个月里,我收到了 18k+的浏览量,6K+的阅读量,和 100+的新粉丝。

我第一个月赚了 110.26 美元,第二个月赚了 62.29 美元。官方媒体报道称,大约 8.9%的作家每月收入 100 美元。

最重要的是,我成为了商业领域的顶级作家。

9.30–10.27

10.28–10.31

当然,这是一个很好的赞美和激励。深吸一口气后,我承认我在技术写作方面肯定做对了一些事情。

在这篇文章中,我将分享我的个人经历和奋斗,并希望我的写作尝试可以帮助你从零开始,快速成为机器学习英雄。

A 调整站立桌的高度,放上我最喜欢的 Spotify 播放列表(顺便说一句,是 Piano Guys)和一杯绿茶,我试图找到最佳的位置、合适的时刻和舒适的写作节奏。

几个小时后,我看着我刚刚写的毫无意义的东西,捶着头。

我现在已经筋疲力尽了,今天就到此为止吧。

这曾经是我在尝试写作。我不会说技术写作现在变得更容易了,但它产生的焦虑更少了。

Writing in the old-school way; Photo by Aaron Burden on Unsplash

作为一个新的开始,首先弄清楚你为什么要写作是个好主意。

对我来说,我不想很快成为一名自由职业者,也不需要任何来自博客的固定收入。

两个原因让我保持动力:

  1. 架起学术和商业世界之间的桥梁。我目睹了如此多的误解和沟通失误,我想尽我的努力来促进研究人员和商业领袖之间的故事。
  2. 为我的机器学习研究伙伴创造价值。无论你是数据科学家、机器学习工程师,还是定量 UX 研究人员,我希望我的博客能提供技术支持,并激励你的下一步努力。

就是这样。

我写作是为了创造价值,不是为了钱。

这是一个顿悟的时刻,我调整了我的写作风格和选择来服务于这个首要目标。例如,我定期在 ML 和因果推理之间轮换话题。

此外,我关注不同方法的应用方面,并展示我们如何使用该方法解决实际的业务问题,包括问题的类型、技术挑战、陷阱和一步一步的实施。

最后,我删除了所有 CTA(行动号召)。有一段时间,我偏离了目标,试图通过创建电子邮件列表、加入亚马逊联盟计划、促进图书销售等来赚取额外收入。

我停止做所有的事情,因为它们不创造价值。

人们读诗是为了好玩,但读技术报告是为了快速解决问题。牢记这一点,我在写作时力求清晰易懂:任何阅读我的帖子的人都可以很容易地复制结果。

Photo by TK Hammonds on Unsplash

让我们深入探讨一下这五条黄金法则。

规则 1:清晰的布局可以完成 90%的工作。

我会让我的读者提前知道他们将要阅读的内容。

在这篇帖子和这篇帖子中,我在标题中解释了我的意图,并在执行摘要中陈述了主要发现。

在其余的帖子中,我会清楚地说明我是如何将研究问题分解成不同的部分,以及我是如何处理每一部分的。

这是一个实用的布局。读者马上就能理解主要论点,也能理解不同部分是如何联系在一起并链接回问题的。

有时候,我发现自己在阅读别人的帖子时迷失了方向,因为作者在展示大图之前玩弄了一些小细节。

R ule #2 了解我的读者,温和地与他们交谈

对于《机器学习 101》【T21 邮报】,我最不愿意做的事情就是用数学或者展示复杂的技术来吓跑新手读者。

如果我想为更高级的读者写作,我可能会稍微涉及一些基础知识,把重点放在技巧本身,包括更多的数学知识。

我花了一段时间找到我的利基观众。找到利基后,我为我的读者量身定做我的故事。

规则#3 简单、简短、明了

选择简单的单词。

写短句。

写简单的句子(比如这个)。

如前所述,技术写作是关于清晰和准确。如果读者不得不花时间检查复合句,那就没有附加价值。

规则四:和时间做朋友

不要着急。

制作高质量的作品需要时间。

如果我没有准备好草稿,从头开始要花 2、3 天的时间。我通常会让草稿搁置几天,然后回去,通过在线工具(比如 Grammarly 很棒)运行它,并在点击发布按钮之前修改它,直到我满意为止。

一篇经过事实检验的好文章要比十篇陈述不准确的文章重要得多。

质量>数量!

规则 5:向我的读者学习

获得反馈至关重要。

我对前四个帖子没有太多的看法,一位同行朋友提醒我,我需要更实际一些,应该包括 R 实现。总之,我必须演示如何实现该方法。

外卖食品

1.清晰的布局

2.了解我的读者,用他们的语言和他们交谈

3.简单

4.和时间做朋友

5.获得反馈

Medium 最近进化出了它的 作家伙伴计划 ,支持像我这样的普通作家。如果你还不是订户,通过下面的链接注册,我会收到一部分会员费。

[## 阅读叶雷华博士研究员(以及其他成千上万的媒体作家)的每一个故事

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

leihua-ye.medium.com](https://leihua-ye.medium.com/membership)

喜欢读这本书吗?

请在 LinkedIn 和 Twitter 找到我。

查看我关于人工智能和机器学习的其他帖子。

机器学习& AI 产品的产品说明书怎么写?

原文:https://towardsdatascience.com/how-to-write-product-specifications-for-machine-learning-ai-products-68f6fe750a6d?source=collection_archive---------28-----------------------

为成功设置您的产品

根据您组织的规模、产品的类型、您的开发生命周期和您组织的实践,您将有自己定义产品规范的方式。无论你遵循哪种机制,这里都有一些关键的调整和见解,可以包括在你的规范中,以构建有效的机器学习和人工智能产品:

利益相关者

它需要一个村庄

为了构建有效的机器学习产品,通常你会有来自多个学科的几个利益相关者,包括数据科学家(各种各样)、工程师、设计师、领域专家、产品营销等等。确保他们所有人从产品规格开始就参与进来,并与您合作,为您产品的成功而努力。

目标/特征

不要为 ML/AI 设计,要为用户价值设计

在过去的几十年里,科技行业经历了快速发展的阶段,每隔几年就会有一项技术彻底改变我们解决各种问题的方式。在过去的十年里,机器学习和人工智能达到了前所未有的高度,几乎每个产品都声称或希望朝着使用 ML/AI 的方向发展。这促使各种产品经理几乎感到必须为“机器学习”或“人工智能”解决方案进行设计。作为产品经理,我们几乎有责任记住:技术会发展和变化,但解决用户问题永远不会过时。这是优化的关键目标,而解决方案可以是任何东西。请记住,产品只有在解决用户问题时才是成功的,而不是它是否使用 ML 或 AI 将有助于确保您的产品目标/功能符合正确的目标。

给实验留有余地

产品经理,尤其是机器学习和人工智能领域的新手,对他们产品中潜在使用的各种新算法和技术充满热情。大多数这些新技术都是日常对话的一部分,当谈到机器学习或人工智能技术时,项目经理很难在产品和技术规范之间划清界限。在你的说明书中,确保用户问题和预期的产品解决方案是清楚的,避免提及特定的机器学习或人工智能技术。这将为您的技术团队提供自由,让他们不受约束地进行试验并找到最佳解决方案。这也将允许您的规范随着技术的发展而保持相关性,这是非常快的!

产品目标/关键绩效指标

设定相关的目标或者不要预先设定

大多数产品规格包括设定产品要达到的某些目标。如果您的产品是基于 ML/AI 的,那么在您的产品和底层模型目标之间建立一致性是非常重要的。这将确保技术实现针对相同的 KPI 进行优化,并且有一种端到端评估产品的方法。在我的 上一篇文章中,我写了如何为你的模型设定目标。

如果你的产品是独一无二的,而且是新的,在这个领域,一开始设定特定的数字目标可能并不明显,那么可以从定义成功的标准开始,然后让来自你产品的数据来驱动你的目标。最好是数据驱动,迟做比早做好,但要完全偏离目标。

将模型评估作为产品的一部分进行烘焙

很多时候,基于机器学习模型的产品从一开始就没有考虑现实世界场景中的模型评估。一开始不考虑这些情况会对你以后造成伤害,因为:

  • 即使您从一开始就不需要评估,您的产品也可能会丢弃稍后需要进行评估的数据点。因此,在开始时考虑各种场景将有助于避免以后出现这种情况
  • 除非你有一个机制来做评估,否则你是盲目的,这可能会很快导致问题,特别是在基于人工智能的产品中,这些产品可以实时学习和适应
  • 在许多高影响力的行业中,你的用户会寻找能够信任你的产品并认为它有用的评价。因此,虽然你的产品输出本身可以让你的用户激活,其验证和评估将有助于你的用户采用和参与。

限制

解决数据的现实问题

在指定机器学习产品的新特性/功能时,最常见的错误是没有评估和深入研究您的产品必须处理的数据挑战。预先确定数据限制有助于你为你的产品描绘一个现实的路径,并有助于避免你的产品规格在以后的多次迭代。

如何像专业人士一样编写 Python 命令行界面

原文:https://towardsdatascience.com/how-to-write-python-command-line-interfaces-like-a-pro-f782450caf0d?source=collection_archive---------2-----------------------

Photo by Kelly Sikkema on Unsplash

作为数据科学家,我们面临着许多重复和相似的任务。这包括创建每周报告,执行提取、转换、加载( ETL) 作业,或者使用不同的参数集训练模型。通常,我们最终会有一堆 Python 脚本,每次运行它们时,我们都会更改代码中的参数。我讨厌这样做!这就是为什么我养成了将脚本转换成可重用的命令行界面(CLI)工具的习惯。这提高了我的效率,让我在日常生活中更有效率。我开始用 Argparse 做这件事,但是这并不愉快,因为我不得不产生很多难看的代码。所以我想,我不需要一遍又一遍地写很多代码就能实现吗?我能享受编写 CLI 工具的乐趣吗?

点击是你的朋友!

那么什么是点击呢?从网页上:

(点击)它旨在使编写命令行工具的过程变得快速而有趣,同时防止因无法实施预期的 CLI API 而导致的任何挫折。

对我来说,这听起来很棒,不是吗?

在本文中,我将向您提供如何使用 Click 构建 Python CLIs 的实践指南。我一步一步地构建了一个示例,向您展示 Click 提供的基本功能和好处。学完本教程后,您应该能够愉快地编写下一个 CLI 工具,而且只需一眨眼的功夫:)所以,让我们动手吧!

教程

在本教程中,我们使用 Click 逐步构建一个 Python CLI。我从基础开始,每一步都引入 Click 提供的新概念。除了 Click,我还使用poems来管理依赖项和包。

准备

首先,我们来装诗。有多种方法可以做到这一点,参见我的文章,但是这里我们使用 pip

pip install poetry==0.12.7

接下来,我们使用诗歌创建一个名为 cli-tutorial 的项目,添加 click 和 funcy 作为依赖项,并创建一个文件 cli.py,稍后我们将在其中填充代码

poetry new cli-tutorial
cd cli-tutorial
poetry add click funcy
**# Create the file we will put in all our code**
touch cli_tutorial/cli.py

我已经添加了 funcy,因为我稍后会用到它。要了解这个模块有什么用处,我建议感兴趣的读者参考这篇文章。现在,我们已经准备好实施我们的第一个 CLI。顺便说一下,所有示例代码都可以在我的 GitHub 账户上找到。

我们的第一个 Click CLI

我们的初始 CLI 从磁盘读取一个 CSV 文件,对其进行处理(如何处理对本教程并不重要),并将结果存储在 Excel 文件中。输入文件和输出文件的路径都应该由用户配置。用户必须指定输入文件路径。指定输出文件路径是可选的,默认为 output.xlsx 。使用 Click,这样做的代码读作

**import** click**@click.command()
@click.option("--in", "-i", "in_file", required=True,help="Path to csv file to be processed.",
)
@click.option("--out-file", "-o", default="./output.xlsx",help="Path to excel file to store the result.")**
**def** process(**in_file**, **out_file**):**""" Processes the input file IN and stores the result to output file OUT."""**input = read_csv(in_file)output = process_csv(input)write_excel(output, out_file)**if** __name__ =="__main__":process()

我们在这里做什么?

  1. 我们用 click.command. 修饰我们想要从命令行调用的方法 process
  2. 我们使用 click.option 装饰器定义命令行参数。现在,您必须小心在修饰函数中使用正确的参数名。如果我们将不带破折号的字符串添加到 click.option 中,参数必须与该字符串匹配。这是- in 和 in_file 的情况。如果所有名称都包含前导破折号,单击将使用最长的名称生成参数名称,并将所有非前导破折号转换为下划线。该名称被转换为小写。出文件和出文件就是这种情况。更多详情,请参考点击文档 n。
  3. 我们使用 click.option 的相应参数来配置所需的先决条件,如默认值或必需参数。
  4. 我们将帮助文本添加到我们的参数中,当使用- help 调用我们的函数时会显示该文本。来自我们函数的 docstring 也将显示在那里。

现在,您可以通过多种方式调用这个 CLI

**# Prints help**
python -m cli_tutorial.cli --help
**# Use single char -i for loading the file**
python -m cli_tutorial.cli -i path/to/some/file.csv
**# Specify both file with long name**
python -m cli_tutorial.cli --in path/to/file.csv --out-file out.xlsx

太棒了,我们已经使用 Click 创建了第一个 CLI!

注意,我没有实现 read_csvprocess_csvwrite_excel ,而是假设它们存在并做它们应该做的事情。

CLIs 的一个问题是我们将参数作为通用字符串传递。为什么这是一个问题?因为这些字符串必须被解析为实际类型,这可能会由于用户输入的格式不正确而失败。看看我们的例子,我们使用路径并尝试加载一个 CSV 文件。用户可以提供一个根本不代表路径的字符串。即使字符串格式正确,相应的文件也可能不存在,或者您没有访问它的正确权限。自动验证输入,如果可能的话解析它,或者在失败的早期给出有用的错误消息,这难道不是一件好事吗?理想情况下,所有这些都不需要编写大量代码?Click 通过为我们的参数指定类型来支持我们。

类型规范

在我们的示例 CLI 中,我们希望用户传入一个有效路径到一个现有文件,我们对该文件拥有读取权限。如果满足了这些要求,我们就可以加载输入文件了。此外,如果用户指定输出文件路径,这应该是一个有效的路径。我们可以通过传递一个点击来执行所有这些操作。路径对象到 click.option decorator 的类型参数

@click.command()
@click.option("--in", "-i", "in_file", required=True,help="Path to csv file to be processed.",**type=click.Path(exists=True, dir_okay=False, readable=True)**,
)
@click.option("--out-file", "-o", default="./output.csv",help="Path to csv file to store the result."**,****type=click.Path(dir_okay=False)**,
)
**def** process(in_file, out_file):""" Processes the input file IN and stores the result to output     file OUT."""input = read_csv(in_file)output = process_csv(input)*write_excel*(output, out_file)
...

点击。路径是 Click out of the box 提供的各种类型之一。您也可以实现自定义类型,但这超出了本教程的范围。有关更多细节,我建议感兴趣的读者参考 Click 文档。

布尔标志

Click 提供的另一个有用的特性是布尔标志。可能,最著名的布尔标志是详细标志。如果设置为 true,您的工具将向终端打印出大量信息。如果设置为 false,则只打印少量内容。通过点击,我们可以实现为

**from** funcy **import** identity
...
**@click.option('--verbose', is_flag=True, help="Verbose output")**
**def** process(in_file, out_file, **verbose**):**""" Processes the input file IN and stores the result tooutput file OUT."""**print_func = print **if** verbose **else** identity    print_func("We will start with the input")input = read_csv(in_file)print_func("Next we procees the data")output = process_csv(input)print_func("Finally, we dump it")write_excel(output, out_file)

你所要做的就是再添加一个click . optiondecoration 并设置 is_flag=True 。现在,要获得详细的输出,您需要调用 CLI 作为

python -m cli_tutorial.cli -i path/to/some/file.cs --verbose

特征开关

假设我们不仅想在本地存储 process_csv 的结果,还想将它上传到服务器。此外,不仅有一个目标服务器,还有一个开发实例、一个测试实例和一个生产实例。您可以通过不同的 URL 访问这三个实例。用户选择服务器的一个选项是将完整的 URL 作为参数传递,她必须键入该参数。但是,这不仅容易出错,而且是一项繁琐的工作。在这种情况下,我使用功能开关来简化用户的生活。他们所做的最好通过代码来解释

...
@click.option(**"--dev", "server_url"**, help="Upload to dev server",**flag_value**='https://dev.server.org/api/v2/upload',
)
@click.option(**"--test", "server_url"**, help="Upload to test server",**flag_value**='https://test.server.com/api/v2/upload',
)
@click.option(**"--prod", "server_url"**, help="Upload to prod server",**flag_value**='https://real.server.com/api/v2/upload',**default=True**
)
**def** process(in_file, out_file, verbose, **server_url**):""" Processes the input file IN and stores the result to outputfile OUT."""print_func = print **if** verbose **else** identityprint_func("We will start with the input")input = read_csv(in_file)print_func("Next we procees the data")output = process_csv(input)print_func("Finally, we dump it")write_excel(output, out_file)print_func("Upload it to the server")upload_to(server_url, output)
...

这里,我为三个可能的服务器 URL 添加了三个click . optiondecorator。重要的一点是,所有三个选项都有相同的目标变量 server_url 。根据您选择的选项,**server _ URL的值等于 flag_value 中定义的相应值。您通过添加- dev 、- test 或- prod 作为参数来选择其中之一。所以当你执行的时候

*python -m cli_tutorial.cli -i path/to/some/file.csv **--test***

server_url 等于“https://test . server . com/API/v2/upload”。如果我们不指定这三个标志中的任何一个,Click 将取- prod 的值,因为我设置了 default=True

用户名和密码提示

不幸的是,或者说幸运的是:),我们的服务器有密码保护。所以要上传我们的文件,我们需要一个用户名和密码。当然,您可以提供标准的 click.option 参数。但是,您的密码会以纯文本的形式出现在您的命令历史记录中。这可能会成为一个安全问题。

我们喜欢提示用户输入密码,而不将密码回显到终端,也不将密码存储在命令历史中。对于用户名,我们也希望一个简单的提示回显。当你知道点击时,没有比这更容易的了。这是代码。

*import os
...
@click.option('--user', **prompt=True**,**default=lambda: os.environ.get('USER', '')**)
@click.**password_option**()
def process(in_file, out_file, verbose, server_url, **user**, **password**):...upload_to(server_url, output, user, password)*

要为一个参数添加提示,你必须设置提示=真。每当用户没有指定- user 参数时,这将添加一个提示,但是她仍然可以这样指定。当您在提示符下点击 enter 键时,将使用默认的值。默认值由函数决定,这是 Click 提供的另一个便利特性。

提示密码而不回显到终端并要求确认是如此普遍,以至于 Click 提供了一个名为 password_option 的专用装饰器。重要的注释;这不会阻止用户通过-password my cretpassword 传递密码。这只能让她不那么做。

仅此而已。我们已经构建了完整的 CLI。在今天结束之前,我想在下一部分给你一个最后的提示。

诗歌脚本

我想给你的最后一个技巧是创建诗歌脚本,它与点击无关,但与 CLI 主题完全匹配。使用诗歌脚本,您可以创建可执行文件来从命令行调用您的 Python 函数,就像您使用 Setuptools 脚本一样。那看起来怎么样?首先,需要将以下内容添加到 pyproject.toml 文件中

*[tool.poetry.scripts]
your-wanted-name = 'cli_tutorial.cli:process'*

**your-want-namecli_tutorial.cli 模块中定义的函数进程的别名。现在,你可以通过

*poetry run your-wanted-name -i ./dummy.csv --verbose --dev*

例如,这允许您向同一个文件添加多个 CLI 函数,定义别名,并且您不必添加 if name == "main" 块。

包裹

在本文中,我向您展示了如何使用点击和诗歌来轻松构建 CLI 工具,并提高工作效率。这只是 Click 提供的一小部分功能。还有很多其他的,比如回调、嵌套命令,或者选择选项等等。现在,我建议感兴趣的读者参考 Click 文档,但我可能会写一篇后续文章来讨论这些高级主题。敬请关注,感谢您关注这篇文章。如有任何问题、意见或建议,请随时联系我。

如何为数据科学家使用简单的 Python 编写 Web 应用?

原文:https://towardsdatascience.com/how-to-write-web-apps-using-simple-python-for-data-scientists-a227a1a01582?source=collection_archive---------1-----------------------

Relax and Code on. Photo by Cody Black on Unsplash

无需了解任何 web 框架,即可轻松将您的数据科学项目转换为酷炫的应用程序

如果我们没有一个好的方式来展示它,机器学习项目就永远不会真正完成。

在过去,一个制作精良的可视化工具或一个小 PPT 足以展示一个数据科学项目,随着 RShiny 和 Dash 等仪表板工具的出现,一名优秀的数据科学家需要具备相当多的 web 框架知识。

Web 框架很难学。为了一些看似简单的事情,我仍然会对所有的 HTML、CSS 和 Javascript 感到困惑。

更不用说做同一件事的许多方法,这让我们数据科学的人感到困惑,因为 web 开发对他们来说是次要技能。

那么,我们注定要学习 web 框架吗?或者半夜打电话给我们的开发者朋友问些愚蠢的问题?

这就是 StreamLit 的用武之地,它承诺只用 Python 创建 web 应用。

Python 的禅:简单比复杂好,简化让创建应用程序变得非常简单。

本文旨在了解如何使用 Streamlit 创建支持数据科学项目的应用。

为了更好地理解导致 streamlit 的架构和思维过程,请看最初的开发者/创始人之一 Adrien Treuille 的这篇精彩的帖子。

如果你想在亚马逊 ec2 上部署一个 streamlit 应用,请查看我的下一篇帖子。

装置

安装就像运行命令一样简单:

pip install streamlit

要查看我们的安装是否成功,我们只需运行:

streamlit hello

这应该会显示一个屏幕,上面写着:

你可以在浏览器中访问本地网址:localhost:8501,查看一个正在运行的 Streamlit 应用程序。开发者提供了一些很酷的演示,你可以玩玩。回来之前,一定要花时间感受一下这个工具的威力。

Streamlit Hello World

Streamlit 旨在使用简单的 Python 简化应用程序开发。

因此,让我们编写一个简单的应用程序,看看它是否能实现这一承诺。

这里我从一个简单的应用程序开始,我们称之为 streamlit 的 Hello World。只需将下面给出的代码粘贴到名为helloworld.py的文件中

import streamlit as stx = st.slider('x')
st.write(x, 'squared is', x * x)

在终端上运行:

streamlit run helloworld.py

瞧,你应该能在localhost:8501看到一个简单的应用程序在你的浏览器中运行,它允许你移动滑块并给出结果。

A Simple slider widget app

这很容易。在上述应用中,我们使用了 Streamlit 的两个功能:

  • 我们可以滑动这个st.slider小部件来改变 web 应用程序的输出。
  • 还有多才多艺的st.write指挥。我很惊讶它是如何从图表、数据框架和简单文本中写出任何东西的。稍后将详细介绍。

重要提示:记住每次我们改变 widget 值,整个 app 都是从上到下运行的。

简化小部件

小部件为我们提供了一种控制应用程序的方式。阅读这些小部件的最佳地方是 API 参考文档本身,但是我将描述一些您可能最终会使用的最突出的小部件。

1.滑块

**streamlit.slider****(*label*, *min_value=None*, *max_value=None*, *value=None*, *step=None*, *format=None*)**

我们已经在上面看到了st.slider的动作。它可以与最小值、最大值和步长一起使用,以获取某个范围内的输入。

2.文本输入

获取用户输入的最简单的方法是一些 URL 输入或一些用于情感分析的文本输入。它只需要一个标签来命名文本框。

import streamlit as sturl = st.text_input('Enter URL')
st.write('The Entered URL is', url)

这是应用程序的外观:

A Simple text_input widget app

提示:你只需更改文件helloworld.py并刷新浏览器即可。我的工作方式是在 sublime text 中打开并更改helloworld.py,并在浏览器中并排查看更改。

3.检验盒

复选框的一个用例是隐藏或显示/隐藏应用程序中的特定部分。另一个可能是在函数的参数中设置一个布尔值。[st.checkbox()](https://streamlit.io/docs/api.html#streamlit.checkbox)接受一个参数,即小部件标签。在这个应用程序中,复选框用于切换条件语句。

import streamlit as st
import pandas as pd
import numpy as npdf = pd.read_csv("football_data.csv")
if st.checkbox('Show dataframe'):st.write(df)

A Simple checkbox widget app

4.选择框

我们可以使用[st.selectbox](https://streamlit.io/docs/api.html#streamlit.selectbox)从系列或列表中选择。通常情况下,用例是将其用作简单的下拉菜单,从列表中选择值。

import streamlit as st
import pandas as pd
import numpy as npdf = pd.read_csv("football_data.csv")option = st.selectbox('Which Club do you like best?',df['Club'].unique())'You selected: ', option

A Simple dropdown/selectbox widget app

5.多选

我们也可以使用下拉列表中的多个值。这里我们使用st.multiselect在变量options中获取多个值作为列表

import streamlit as st
import pandas as pd
import numpy as npdf = pd.read_csv("football_data.csv")options = st.multiselect('What are your favorite clubs?', df['Club'].unique())st.write('You selected:', options)

A Simple multiselect widget app

逐步创建我们简单的应用程序

了解重要的小部件就到此为止。现在,我们将一次使用多个小部件创建一个简单的应用程序。

首先,我们将尝试使用 streamlit 可视化我们的足球数据。借助上面的小部件,做到这一点非常简单。

import streamlit as st
import pandas as pd
import numpy as npdf = pd.read_csv("football_data.csv")clubs = st.multiselect('Show Player for clubs?', df['Club'].unique())nationalities = st.multiselect('Show Player from Nationalities?', df['Nationality'].unique())# Filter dataframe
new_df = df[(df['Club'].isin(clubs)) & (df['Nationality'].isin(nationalities))]# write dataframe to screen
st.write(new_df)

我们简单的应用程序看起来像:

Using multiple widgets in conjunction

那很容易。但是现在看起来很基本。我们可以添加一些图表吗?

Streamlit 目前支持许多用于绘图的库。 Plotly、Bokeh、Matplotlib、Altair 和 Vega 图表 就是其中的一些。 Plotly Express 也是可以的,虽然他们在文档里没有明确说明。它也有一些内置的图表类型,像st.line_chartst.area_chart

我们将在这里与plotly_express合作。这是我们简单应用程序的代码。我们刚刚使用了四个调用来简化它。其余的都是简单的 python。

import streamlit as st
import pandas as pd
import numpy as np
import plotly_express as pxdf = pd.read_csv("football_data.csv")**clubs = st.multiselect('Show Player for clubs?', df['Club'].unique())
nationalities = st.multiselect('Show Player from Nationalities?', df['Nationality'].unique())**new_df = df[(df['Club'].isin(clubs)) & (df['Nationality'].isin(nationalities))]
**st.write(new_df)**# create figure using plotly express
fig = px.scatter(new_df, x ='Overall',y='Age',color='Name')# Plot!
**st.plotly_chart(fig)**

Adding charts

丰富

一开始我们说过,每次我们更改任何小部件,整个应用程序都会从头到尾运行。当我们创建将服务于深度学习模型或复杂的机器学习模型的应用时,这是不可行的。Streamlit 通过引入 缓存 在这方面为我们做了介绍。

1.贮藏

在我们简单的应用程序中。每当一个值改变时,我们就一遍又一遍地读取熊猫数据帧。虽然它适用于我们拥有的小数据,但它不适用于大数据,或者当我们必须对数据进行大量处理时。让我们使用 streamlit 中的st.cache decorator 函数来使用缓存,如下所示。

import streamlit as st
import pandas as pd
import numpy as np
import plotly_express as px**df = st.cache(pd.read_csv)("football_data.csv")**

或者对于只需要运行一次的更复杂和耗时的函数(考虑加载大型深度学习模型),使用:

@st.cache
def complex_func(a,b):DO SOMETHING COMPLEX# Won't run again and again.
complex_func(a,b)

当我们用 streamlit 的 cache decorator 标记一个函数时,无论何时调用该函数,Streamlit 都会检查调用该函数时使用的输入参数。

如果这是 Streamlit 第一次看到这些参数,它将运行该函数并将结果存储在本地缓存中。

下次调用该函数时,如果这些参数没有改变,Streamlit 知道它可以完全跳过执行该函数。它只是使用缓存中的结果。

2.补充报道

为了根据您的偏好获得更整洁的外观,您可能希望将您的小部件移动到侧边栏中,类似于 Rshiny dashboards。 这个挺简单的。只需在您的小部件代码中添加 ***st.sidebar*** 即可。

import streamlit as st
import pandas as pd
import numpy as np
import plotly_express as pxdf = st.cache(pd.read_csv)("football_data.csv")clubs = **st.sidebar.multiselect**('Show Player for clubs?', df['Club'].unique())
nationalities = **st.sidebar.multiselect**('Show Player from Nationalities?', df['Nationality'].unique())new_df = df[(df['Club'].isin(clubs)) & (df['Nationality'].isin(nationalities))]
st.write(new_df)# Create distplot with custom bin_size
fig = px.scatter(new_df, x ='Overall',y='Age',color='Name')# Plot!
st.plotly_chart(fig)

Move widgets to the sidebar

3.降价?

我喜欢用 Markdown 写作。我发现它没有 HTML 冗长,更适合数据科学工作。那么,我们可以在 streamlit 应用程序中使用 Markdown 吗?

是的,我们可以。有几种方法可以做到这一点。在我看来,最好的方法是使用魔法指令。神奇的命令让你写 markdown 像写注释一样容易。您也可以使用命令st.markdown

import streamlit as st
import pandas as pd
import numpy as np
import plotly_express as px'''
# Club and Nationality AppThis very simple webapp allows you to select and visualize players from certain clubs and certain nationalities.
'''
df = st.cache(pd.read_csv)("football_data.csv")clubs = st.sidebar.multiselect('Show Player for clubs?', df['Club'].unique())
nationalities = st.sidebar.multiselect('Show Player from Nationalities?', df['Nationality'].unique())new_df = df[(df['Club'].isin(clubs)) & (df['Nationality'].isin(nationalities))]
st.write(new_df)# Create distplot with custom bin_size
fig = px.scatter(new_df, x ='Overall',y='Age',color='Name')'''
### Here is a simple chart between player age and overall
'''st.plotly_chart(fig)

Our final App Demo

结论

Streamlit 使创建应用程序的整个过程民主化了,我不能再推荐它了。

在这篇文章中,我们创建了一个简单的 web 应用程序。但是可能性是无限的。这里举个例子就是细流网站的脸甘。它的工作原理与小部件和缓存的指导思想相同。

我喜欢开发人员使用的默认颜色和样式,我发现它比使用 Dash 要舒服得多,直到现在我还在我的演示中使用 Dash。您还可以在您的 streamlit 应用程序中包含音频和视频。

最重要的是,Streamlit 是一款免费的开源软件,而不是一款开箱即用的专有网络应用。

在过去,我必须联系我的开发人员朋友来解决演示或演示中的任何一个变化;现在做那件事相对来说是微不足道的。

我的目标是从现在开始在我的工作流程中更多地使用它,考虑到它所提供的功能,我认为你也应该这样做。

我不知道它是否会在生产环境中表现良好,但它对于小型概念验证项目和演示来说是一个福音。我的目标是从现在开始在我的工作流程中更多地使用它,考虑到它所提供的功能,我认为你也应该这样做。

你可以在这里找到最终应用的完整代码。如果你想在亚马逊 ec2 上部署这款应用,请查看我的下一篇帖子。

如果你想了解创建可视化的最佳策略,我想从密歇根大学调出一门关于 数据可视化和应用绘图 的优秀课程,这是一门很好的 数据科学专业的一部分,Python 本身就是其中之一。一定要去看看。

谢谢你的阅读。将来我也会写更多初学者友好的帖子。在关注我或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系。

此外,一个小小的免责声明——这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意。

如何编写你的第一个 Quine 程序

原文:https://towardsdatascience.com/how-to-write-your-first-quine-program-947f2b7e4a6f?source=collection_archive---------6-----------------------

Python 中自我复制程序的快速指南

A quine-relays: a Python program generates a Java program that generates a Ruby program that generates the first Python program

本指南的目的是展示如何编写一个程序,让在没有输入的情况下输出自己的源代码。这一系列程序被称为奎因。

这为什么有意思?因为自我引用的东西总是很有趣:)

构建这样的程序有很多方法,但最常见的方法叫做构造方法

但首先…这不是一个有效的奎因计划:

This is not Quine, is cheating in Python

一个程序只有在完全不需要输入的情况下才能被称为蒯因。在这种情况下,程序读取其源代码作为文件,从而使其使用自己作为输入。此外,本指南不考虑琐碎的 Quine 程序(如0 字节程序或自我评估原子如 Lisp)。

建设性蒯因

最有效和最容易理解的方法是将程序分成两部分:

  • 委托打印信息的代码(如 Python 中的print()函数、Java 中的System.out.println()或 C++中的全局对象std::cout)。
  • 可以存储部分源代码的数据结构(如字符串或列表)。注意,程序甚至需要打印字符串周围的引号。

这些要求必须根据您想要使用的语言规范进行调整和校准。由于每种语言使用不同的机制来管理数据结构和打印,这里不可能涵盖所有的变化,所以本指南只关注 Python 规范。

python str()vs repr()

如果你已经知道这个机制,那么你可以跳过这一节。

否则,这不仅对完成我们的任务非常重要,而且对更好地理解语言本身的有趣之处也非常重要。

str() —人类可读对象

[str()](https://docs.python.org/3/library/stdtypes.html#str)是 Python 中的标准函数,返回对象的字符串版本。它应该生成一个友好的人类可读的字符串。

repr()-可评估对象

Notice the quotes surrounding the string

另一方面,[repr()](https://docs.python.org/3/library/functions.html#repr)返回表示对象的字符串的可求值版本(通过[eval()](https://docs.python.org/3/library/functions.html#eval)函数)。对于字符串,它返回用引号括起来的字符串本身。

通过使用下面的语法,同样可以用printf的方式编写,其中%r表示用[repr()](https://docs.python.org/3/library/functions.html#repr)格式化第二个%之后的字符串。

蒯因通过评估

这项技术包括使用[eval()](https://docs.python.org/3/library/functions.html#eval)功能。我们将要创建的程序的主要模式如下:

是我们的数据结构,我们必须在里面放一段代码来打印和评估它自己。为什么我们希望在字符串中也有 eval 函数?因为程序的最后一行使用了[eval()](https://docs.python.org/3/library/functions.html#eval),我们必须在字符串中找到它。

由于程序以variable='开始,我们必须把这部分作为第一件要打印的东西。同样,出于同样的原因,最后要打印的部分必须是eval(variable)

执行过程打印了variable = ??? eval(variable),这很好,但是我们还必须打印print()函数、引号和换行符。我们不能在字符串 a print(...)中再写一次,否则我们将通过无限增加print(...)进入一个无限递归循环。

所以主要思想是再次使用variable,因为它已经包含了print()函数!就像这样连接它:

输出与源代码非常相似,但是我们必须处理围绕print()函数的引号和断行。幸运的是,我们现在知道 Python 提供了[repr()](https://docs.python.org/3/library/functions.html#repr)函数来返回一个字符串的可求值版本,对于换行符,我们可以添加一个转义的\n:

The Quine program perfectly working

这是你用 Python 写的第一个 Quine 程序,因为没有输入,输出就是程序的源代码!

其他奎因计划

还有其他方法来创建奎因程序,你可以在下面找到一些简短的描述。

最短的蟒蛇奎因

这是 Python 中最著名的 Quine 程序,也是有史以来最短的非平凡程序。请注意,它没有使用[eval()](https://docs.python.org/3/library/functions.html#eval),而是以printf的方式使用[repr()](https://docs.python.org/3/library/functions.html#repr)。与我们的版本没有太大的不同,因为它使用了一种建设性的方法。

误差奎因

This program must be saved as quine.py

这很有意思。该程序是一个生成IndentationError的无效 Python 代码。它输出自己,但在stderr标准流中,而不是在stdout(在我看来,这仍然是一个有效的查询)。

奎因继电器

Quine-relay 是用一种语言编写的程序,它输出另一种语言的程序,后者又生成启动程序。

本文的特色图片给出了一个直观的例子。

你也可以在这里找到一个用于 128 种编程语言的 Quine-relays 的实际例子!

你能用你最喜欢的语言写一个蒯因程序吗?

迁移学习如何成为深度学习模型中的幸事?

原文:https://towardsdatascience.com/how-transfer-learning-can-be-a-blessing-in-deep-learning-models-fbc576dc42?source=collection_archive---------20-----------------------

转移学习要点

迁移学习是深度学习领域的一大进步,它不仅允许我们将高性能模型用于各种任务,还减少了对越来越多数据的依赖。在这篇文章中,我将讨论什么是迁移学习,以及我们如何利用它来解决手头的问题。笔记本链接如下:

[## 谷歌联合实验室

编辑描述

colab.research.google.com](https://colab.research.google.com/drive/18GACFV395iu9hS47-wkKW7LSdkmOyE0P)

什么是迁移学习?

迁移学习是一种技术,在这种技术中,针对某项任务训练的模型可用于根据其学习(权重)对另一项任务进行预测。

让我们以理解三角形的卷积神经网络为例,尝试更好地理解它。让我们考虑模型有两层。在第一层,模型将检测边缘。在第二层,模型将结合这些边来理解三角形。

让我们考虑另一个 CNN 模型,它必须被训练来检测矩形。如果我们可以使用以前的 CNN 模型的知识来理解边缘,并只改变最后一层,这样在训练期间,它现在可以检测矩形而不是三角形。这就是迁移学习。使用已经训练好的模型对另一项任务进行预测。

为什么要转学?

迁移学习是一个非常重要的概念,在处理许多深度学习模型时非常有用。它带来的好处包括:

  1. 使用专家模型:利用迁移学习,我们只要冻结参数,改变输出层,就可以直接使用专家精心高效创建的模型。
  2. 没有模型结构开发:由于我们使用的是已经存在的模型,我们不再需要考虑要包含的层,应该分配什么参数等等。
  3. 更高更好的表现:由于迁移学习中使用的模型是精心设计的,它们在其他类似的任务中也表现得更好。

让我们试着用迁移学习来解决猫和狗的问题。

猫和狗的问题解决方案

Photo by Anusha Barwa on Unsplash

问题描述

我们有一组猫和狗的图像。我们希望使用深度学习模型来区分这两个类别。

方法

我将首先自己创建一个 CNN 模型,并测量它的性能。然后,我将在一个流行的模型 MobileNet 上使用迁移学习来训练分类。我将把每个模型的图像大小设置为统一的 224x224,并对提供给每个模型的数据进行数据扩充。

培养

由于这个问题是一个 2 类分类问题,我将用adam优化器、sparse_categorical_crossentropy损失函数和度量标准accuracy来编译每个模型。

训练定制模型 我创建了一个 CNN 模型,有 4 个Conv2D层,分别有 32、64、128、256 个节点和relu激活函数。这些卷积层中的每一层都跟随着一个MaxPooling2D层。接下来,我添加一个Dropout层,防止过度渲染。我添加了一个Flatten层,这样我可以把它传递给 256 节点Dense层。最后一层是一个 2 节点Dense层,带有softmax激活函数,给出每一类的概率。当我从头开始训练模型时,我将运行它 100 个时期。

Custom CNN Model

用迁移学习训练 MobileNet 模型 我会从 Tensorflow Hub 下载 MobileNet 模型。然后我会冻结它,这样模型内部的重量就不会改变。我将添加一个有 2 个节点的密集层(两个类——猫和狗)和softmax激活函数。由于这是一个预训练的模型,我将只运行 5 个时期。

Transfer Learning model

结果比较

让我们来看看这两种模型的精度和损耗曲线。

Custom CNN model training curves

对于定制的 CNN 模型,在 50 个时期之后,该模型实现了 76%的验证准确度。然而,即使准确性仍在提高,训练和验证准确性之间的差异正在扩大,这表明它开始过度拟合。

Transfer Learning model training curves

就在 5 个时期之后,MobileNet 迁移学习模型实现了 96%的验证准确性。

迁移学习模型的准确性比定制模型高出 20%。这也减少了训练时间。

从使用现有模型的过程,到在数据集上训练它,都是如此简单和容易。这对任何人来说都是一个巨大的机会,只要拿起一个经过训练的模型,用它来解决他们的问题。

结论

正如我们所看到的,迁移学习模型与定制 CNN 模型相比表现得非常好,并且也具有非常少的时期。很明显,迁移学习是一种非常特殊和强大的技术,可以创建深度学习模型,并帮助解决现有模型的多个问题。

查看其他文章:

[## Google Colab——您在云上的 Python 工作空间

了解 Google Colab

towardsdatascience.com](/google-colab-your-python-workspace-on-cloud-c3aed424de0d) [## 使用 React 和 Flask 创建一个完整的机器学习 web 应用程序

用 UI 和后端构建完整的 ML 应用程序

towardsdatascience.com](/create-a-complete-machine-learning-web-application-using-react-and-flask-859340bddb33) [## 使用深度学习通过确保驾驶员的注意力来拯救生命

现实生活中的卷积神经网络

towardsdatascience.com](/using-deep-learning-to-save-lives-by-ensuring-drivers-attention-e9ab39c03d07) [## 通过预测游客购买意向学习人工神经网络

使用 Keras 和 Tensorflow 构建人工神经网络

towardsdatascience.com](/learning-artificial-neural-networks-by-predicting-visitor-purchase-intention-724ba2be7c29) [## 迁移学习指南:一个实用的教程与图像和文本的例子在 Keras …

在大型数据集上训练一个神经网络可能需要数周时间。幸运的是,由于有了模型,这个时间可以缩短…

海王星. ai](https://neptune.ai/blog/transfer-learning-guide-examples-for-images-and-text-in-keras)

感谢阅读!请分享你的想法、观点和建议。我很乐意收到你的来信。

Twitter 和 AI (KDE + LDA)如何帮助预测犯罪?

原文:https://towardsdatascience.com/how-twitter-and-machine-learning-kde-lda-help-to-predict-crime-5b8abbd15596?source=collection_archive---------8-----------------------

这是对 Mattew S. Gerber 的论文“使用 Twitter 和内核密度估计预测犯罪”的 5 分钟评论。

犯罪预测被反犯罪组织用来优化他们在热点犯罪地区巡逻的有限资源的调度。

这种预测通过使用被称为“潜在狄利克雷分配”(LDA)模型的 NLP 机器学习(ML)技术处理的 Twitter 消息以及另一种被称为“核密度估计”(KDE)的 ML 技术得到了增强。使用这些消息的直觉是,人们通常用 twit 谈论他们所在的位置,而 Gerber 提出的方法利用了这些消息是地理定位的(twit 以纬度+经度的形式提供其来源位置。)

如何使用 twits 使预测更加准确?除了 KDE 之外,他(Gerber)还使用这些消息的主题建模,特别是 LDA 。作为简要总结, LDA 是一种生成概率主题建模方法,其发现遍及文本语料库的预设数量的主题。我们想要提取的主题的数量代表模型超参数( K ),并且需要先验地提供。这些K-主题按照出现概率的降序排列,在这种情况下,语料库由所有考虑的 twits 消息表示。例如,如果一个人在机场发 twit,很可能会包含诸如航班、飞机、登机口、航空公司、美国航空公司等词语,因此我们可以推断 twit 来自 twit 本身提供的地理位置,在这种情况下,位置发生在机场(在所研究的区域中)。在定位犯罪的情况下,让我们假设卖淫犯罪的最大概率主题(在 500 个主题中)是“lounge studios continental village Ukrainian……”,那么 twitter 消息提供的位置将指示这种犯罪可能在哪里发生。

Figure 1. Division of Chicago Illinois USA city neighborhood boundaries for tweet-based topics, only the green cells were considered in Gerber’s analysis.

在他的论文中,Gerber 考虑了两种人工智能技术:Twitter 上的 KDE + LDA 。为了进行分析,他考虑了美国伊利诺伊州的芝加哥市,在那里他将该市划分为 1000 米乘 1000 米的正方形单元(小区)(见图 1)。

这种方法是如何工作的?预测方法的功能如下:对于每个邻居,发布的 twits 使用 LDA 进行主题建模。 LDA 将以最高概率贡献 K tweet-topics,并且 twit 携带 twit 本身的地理位置。同时, KDE 将量化犯罪的历史密度(按类型和单元)。

通过结合 KDE 和经过 LDA 处理的 Twitter 内容,他制定了一个预测模型,在应用该模型后,Gerber 观察到,在大多数犯罪类型中,预测准确性都有所提高。为了展示他在这种技术的预测准确性方面发现的收益和损失,我在 3 种犯罪类型(B、W 和 S)的 3 个示意图中总结了它们,其中类型 B 代表实现了更好的预测准确性(比单独使用 KDE )的那些犯罪,Gerber 声称在 AUC 方面获得了高达 0.10%的改善(见图 2)。),对于那些预测准确性较差的犯罪,键入 W(见图 3。)和 S 型犯罪,其中预测准确性是相似的(见图 4)。我从 Gerber 的研究结果中任意选择了以下等级,根据犯罪类型对其进行分类(见表 1)。

Table 1

Figure 2

Figure 3

Figure 4

为了清楚起见,三幅图一起呈现(参见图 5),如所解释的,他的模型报告了对于犯罪类型 B 的预测精度的提高,对于犯罪类型 P 的预测精度较差,对于犯罪类型 S,与仅使用 KDE 相比,预测精度相似。

Figure 5

下图显示了(a)仅使用 KDE 生成的热点图,而(b)显示了使用 KDE + Twitter 主题要素生成的热点图,在这里我们可以看到更明确、更密集的预测,这甚至类似于用于分析该区域的邻域划分(像元)。参见图 6。

Figure 6

在我看来,这篇论文通过使用 LDA 添加 Twitter 分析,为改进犯罪预测技术(仅基于 KDE)做出了很好的努力。然而,作者声称的预测准确性的提高并没有扩展到每一种犯罪类型。作者承认,很难解释为什么一些类型的犯罪或多或少受益于 Twitter 话题的增加,也许这将是一个关于这个问题的进一步研究的问题。除了 Twitter 消息的地理位置,或许还可以包括其他特征来提高犯罪预测的准确性,如 Twitter 情绪,甚至影响犯罪,如天气?

来源:

使用 Twitter 和核密度估计预测犯罪

Gerber 女士 —决策支持系统,2014 年—爱思唯尔

【书】用于统计和数据分析的密度估算

taylorfrancis.com BW Silverman—2018 年——T4

[PDF] 加速潜在狄利克雷分配模型的校准以改进软件工程中的主题分析

JA lópez—2017—digital . library . ryerson . ca

关于本文作者:https://www.georgelopez-portfolio.com/

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

亲爱的读者:

我有兴趣从你那里知道,根据你的标准,Twitter 正在捕捉的其他什么特征可以被认为是预测犯罪?

你可以留下评论,我会很乐意阅读。谢了。

大规模实现推荐系统的挑战

原文:https://towardsdatascience.com/how-twitter-does-it-challenges-in-implementing-recommender-systems-at-scale-353f7a1ae4ab?source=collection_archive---------12-----------------------

从行业角度总结了实现推荐系统的挑战

大多数情况下,数据科学项目停留在基于数据子集达到某种令人满意的准确性。推荐系统也是如此。在受控环境和有限数据集的情况下,可能会获得令人印象深刻的结果,但将算法部署到现实生活中需要的远不止这些。

在这篇文章中,我将总结我对 Twitter 在使用其推荐系统时所面临的挑战的有趣了解。理解 Twitter 面临的挑战可能会让我们中的一些人对推荐问题的范围有一个新的看法,并将帮助我们做出适当的设计决策。这也可能有助于在不同行业的推荐系统之间进行比较。此外,我将简要介绍一下 Twitter 为其平台使用的推荐系统方法。

在旧金山举行的 2019 年深度学习峰会上,来自 Twitter 的 Ashish Bansal 分享了这些挑战和方法。

让我们开始吧。

简介:

众所周知,Twitter 是一个微博客网站,每天在全球发布数亿条推文。如果你已经是 twitter 的成员,你会看到“关注谁”和“你的趋势”这样的内容。这些功能背后运行的核心引擎是推荐引擎。

Twitter 推荐与非 Twitter 推荐的比较:

推特推荐产品:

Twitter 向其客户推荐 3 种主要的推荐产品

  1. 关注用户:该产品可产生的总推荐量可能高达 10 亿条,且推荐有效期可长达数月至数年。换句话说,这些建议有更长的保质期
  2. Tweets: 在用户的 feed 上推荐给用户的 Tweets 可以是上亿条的量级,保质期只有几个小时。众所周知,现在信息的保质期很短,因为新闻变化如此之快,甚至在一天之内
  3. 趋势/事件:趋势需要推荐的数量最少,因为大多数用户可能是类似趋势的一部分,并且它们的保质期也很短,因为它们不会持续很久

非 Twitter 推荐产品:

电影和电子商务是这方面的两个很好的例子。每年有几千部电影被创作出来,并且有更长的保质期。电商虽然有几个亿的推荐量订单,但是保质期更高。

保质期更长有什么好处?

对于电影和电子商务,推荐系统可以以较慢的速度学习,并且学习得很慢,因为有足够的时间让任何推荐变得完全不相关。但在 Twitter 的情况下,它们完全取决于趋势和人们想要什么,并且注定每天都在变化。由于 Twitter 的数据速度和数据量都很高,推荐系统应该更加健壮,能够提供推荐。

为了适应这种速度,生成实时特征并输入到推荐系统中也是很重要的。

用户-用户和用户-项目推荐的挑战:

用户-用户:

基于用户关注寻找相似性,并向关注他/她的用户推荐某个特定人的所有推文,可能不是一个稳健的方法。例如,你可能会在 Twitter 上关注一个特定的人,了解他对机器学习的看法。你可能对他/她关于政治的推文不感兴趣,应该避免在你的订阅中出现。

用户兴趣:

用户兴趣一直在变化:用户会有长期兴趣,如健康偏好,以及短期兴趣,如趋势/事件和兴趣一直在变化。例如,在 11 月,数百万用户对美国中期选举感兴趣,并希望观看与政治相关的内容。但是对于同一个人来说,在不同的时间段,情况就不一样了。

地理相关兴趣:用户的地理相关兴趣总是基于特定时间点发生的事情而变化。“你的趋势”应该始终跟上用户的地理相关兴趣的变化。

方法:

Twitter 采用了协作和内容推荐系统,或者有时是两种模式的混合,这取决于他们所做的推荐类型。我不会在这篇文章中讨论这些算法,因为它们在很多其他文章中都有清楚的解释,我将集中讨论它们的应用。

协同过滤:

当谈到使用协同过滤方法时,Twitter 有一个独特的优势,因为它的用户追随概念。这使得 Twitter 更容易计算用户相似度,因为信息是直接的。这也增加了创建基于图的模型的可行性,并在此基础上使用社区检测技术来发现用户之间的相似性。

基于内容的方法:

当谈到基于内容的过滤时,它在 Twitter 的规模上变得有点复杂。

  1. 在 280 个字符的限制下,考虑到一个英语单词平均有 5 个字符,我们每条 tweet 最多可以有 46 个单词。这导致必须处理大量内容
  2. Twitter 帖子可能有多种语言的文本,很难将不同语言的单词转换成上下文

将内容映射到实体:

向用户推荐内容的方法之一是在推文中使用实体,并推荐与用户喜欢的推文中的实体更相关的内容。但是主要的挑战是识别和处理这些实体。

命名实体识别可以用来识别这些实体,但挑战在于识别同一条 tweet 中的多个实体/重复实体。例如,一个特定的人可以通过多种方式调用足球世界杯,如足球世界杯、FIFA 世界杯和 FIFA 2018。所有这些实体都应该被识别,这些推文背后的共同情感必须被提取出来,以向该用户推荐内容。否则,由于一条推文中的多个实体,将会出现相互冲突的推荐。

考虑主题而不是实体是 Twitter 正在研究的一种新方法,用于处理一条推文中多个实体的问题。通过考虑主题,我们可以消除重复实体,识别用户感兴趣的主题,并基于此推荐内容。

像文本标记化、NER 的共现、NER 的嵌入以及嵌入的聚类等方法是 Twitter 正在积极研究的一些技术。遗憾的是,由于会议时间有限,没有详细讨论这些方法。

部署推荐系统的一些关键方面:

  1. 覆盖率:随着商品种类的增加,在保持低延迟的同时获得高覆盖率总是很重要的
  2. 多样化:向用户提供多样化的建议是很重要的。
  3. 适应性:推荐系统应该快速适应快速变化的内容世界
  4. 可扩展性:它应该可以扩展到数十亿具有不同习惯和偏好的用户
  5. 用户偏好:框架应该能够在一个排名框架中处理不同的用户兴趣

这是所有的乡亲。希望你喜欢阅读这篇文章,并对设计你的推荐系统有一个新的视角。请继续关注推荐系统、数据科学中的统计学和数据可视化。

强大的图形对数据科学有多重要?

原文:https://towardsdatascience.com/how-vital-are-powerful-graphics-for-data-science-5ead7a54d50c?source=collection_archive---------21-----------------------

当谈到深度学习时,通常你可以将模型带到的规范与你机器内部的硬件绑定在一起。我们都见过强化的深度学习机器,它们配有巨大的鼓风机式冷却器、一体机,以及大量的内存插槽,只有最快的 DDR4 才能填满。考虑到这一点,我们的 GPU 对机器学习有多重要?当我们拟合模型和构建神经网络时,我们可以期望我们的 GPU 为我们执行什么样的角色?

(确切地说)不重要。

硬件对标准深度学习的影响可以像这样映射出来。

  • 处理器
  • 随机存取存储器
  • 互换
  • 读写速度(在某些情况下)
  • 图形卡

随着这些信息在你的大脑中跳跃,你可能会思考 GPU 在日常 ML 中可能扮演的角色。首先,虽然渲染可视化只依赖于处理器,但是 GPU 仍然需要估算所有的单独向量,向量 2,以及你放入屏幕的任何其他几何图形。因此,对于你绘制数百万对数百万的可视化来说,一个能够支持计算的显卡是必不可少的。

然而,有了股票包的经验,我们注定要 CPU 来做我们所有的计算,并拉和推一切来回到内存,并最终到我们的显卡。

人们添加它们的原因

GPU 的可取之处在于它以包的形式设计了 CUDA。大多数统计机器学习操作涉及以数字矩阵的形式移动大量数据,并实时计算值。幸运的是,这正是显卡的设计目的。

虽然在您的包中使用 CUDA 有一些缺点,但是好处远远超过这些问题。CUDA 允许你的 GPU 和 CPU 互换通信,其中你的显卡非常擅长矩阵乘法和矢量渲染,你的 CPU 非常擅长发送、接收和存储数据。当然,从优化的角度来看,这是一个粗略的话题。在我使用 CUDAnative.jl 在 Julia 中进行的测试中,结果肯定比使用原始 CPU 能力来提供所有结果要快。这是一个严重的缺点,我们称之为频率步进。在典型的情况下,中央处理器更小,更不专业。而图形处理单元更专用于较低的核心时钟。因此,在一起计算时,GPU 和 CPU 可以有效地交换意见。

这不是问题,问题是跨硬件 IRQ 不平衡:当一个硬件必须等待另一个硬件时,时间就被浪费了,整个几百 mHz 都因为这个问题而丢失了。

考虑到这一点,CPU 绝对擅长处理这个问题,这个问题以任何明显的瓶颈的形式出现,所以一个平衡的系统可能是理想的。

所以回到一个系统上的四个 GPU,通常这对于机器学习来说是一个低效的设置,因为尽管图形能力非常棒,但单个 CPU 的能力根本不足以支持这样的事情。这就是为什么我们通常会在数据科学 ThinkStation 中看到匹配良好的双 CPU 和双 GPU。在这个特定的使用案例中,我们充分利用了两个显卡的全部潜力,并拥有支持每个显卡的处理速度。

没有人知道未来几年处理器、显卡和中央处理器会怎么样。就我个人而言,当我们看到英特尔试图对抗新的锐龙处理器,同时试图推出一款产品来击败 amd 即将推出的 5 纳米台式机(而不是服务器)CPU 时,我非常兴奋地看到明年的“巨人的冲突”。我能确定的是,2020 年对计算机、人工智能和技术爱好者来说肯定会是激动人心的一年。

WaveNet 如何工作

原文:https://towardsdatascience.com/how-wavenet-works-12e2420ef386?source=collection_archive---------1-----------------------

是关于时序深度学习进化的!

WaveNet 是一种强大的新预测技术,它使用来自计算机视觉(CV)和音频信号处理模型的多种深度学习策略,并将它们应用于纵向时间序列数据。它是由伦敦人工智能公司 DeepMind 的研究人员创造的,目前为谷歌助手语音提供动力。

The building blocks of the WaveNet Deep Learning Model

这篇博客文章伴随着我最近在西雅图全球人工智能大会(2019 年 4 月 23 日至 25 日)上的一次演讲。它也是我用来讲课和实验的 Jupyter 笔记本的精华,可以在我的 GitHub 上找到,还有支持数据和资源。

我们将主要探索 WaveNet 及其工作原理,但首先让我们深入研究数据准备、当前的高性能模型(作为基线,脸书预言家),然后比较结果!

我们正在分析雅虎财经 2000 年 1 月至 2019 年 5 月的 AAPL、MSFT、S&P500、纳斯达克指数数据;这些都在回购的数据文件夹里。

背景

在我们转向笔记本和我们的结果之前,我们必须了解 WaveNet 是如何形成的。DeepMind 正在研究音频排序问题,特别是与学习和模仿人类语言有关的问题。解决这个问题对于突破我们多年来一直使用的机器人声音至关重要,而且让数字助理听起来更像人类。

DeepMind 寻找灵感的一个领域是计算机视觉和卷积网络架构。有趣的是,滤波和卷积这两个概念不仅适用于图像和视频,也适用于音频应用 。简而言之,DeepMind 对这种被标记为“WaveNet”的架构的实验开始启用谷歌复杂的助手语音。

随着深度网络的跨功能应用如此成功,研究人员想知道 WaveNet 是否还有其他应用,如序列或时间序列数据。嗯…你猜怎么着?它运行得非常好,但是需要一些调整。让我们深入研究这些调整,以及我们需要为顺序数据优化的架构。

WaveNet 架构

Gated Activations and Skip Connections

我们上面看到的是一个门控激活。与 LSTM 或格鲁什的门类似,双曲正切分支是一个激活滤波器,或者说是下面发生的扩张卷积的修改器。这就是我们之前在 CNN 上看到的“挤压功能”。s 形分支本质上充当了一个二进制门,能够消除之前的一切;它知道哪些数据是重要的,可以追溯到过去任意数量的时期。

还要注意指向右侧的灰色箭头:这些是跳过连接。它们允许完全绕过卷积层,并使原始数据能够影响未来任意多个时期的预测公式。这些是可以在数据切片上验证的超参数;最佳值取决于您想要学习的序列的结构和复杂性。

请记住,在全连接神经网络中,一个神经元接收来自前一层所有神经元的输入:早期层通过中间计算的层次结构影响后期层。这允许神经网络建立原始输入/信号的复杂交互。

但是…如果早期的原始输入对预测直接有用,并且我们希望它们直接影响输出,那该怎么办?具体来说,跳过连接允许任何层的输出绕过多个未来层,并且跳过影响稀释! Keras 允许我们使用skips.append()存储每个卷积块的张量输出——除了通过进一步的层传递之外。请注意,对于上面堆栈中的每个块,门控激活的输出如何加入跳过连接的集合。

Residual Connections

剩余连接类似于跳过连接:把它们想象成持续可用的短层跳过!我们将为我们的模型使用一层跳跃,但它也是一个超参数。他们为什么帮助是神秘的,但它最有可能是由于在反向传播中帮助消失或爆炸梯度障碍。对于较大的模型来说,这变得更加重要,但是出于教育目的,我将向您展示一个较小设置中的实现。

我的结果

正如您在笔记本中看到的,与脸书先知相比,我的结果非常好:

  • 预言者平均绝对误差:8.04
  • 验证集上的 wave net MAE:~ 1.5

MSFT Volume Prediction

然而,当谈到股票预测时,有一些棘手的趋势,没有简单的答案:

MSFT Adjusted Close Prediction

整体趋势愚弄了 WaveNet 进入一个强大的回归,而不是跟随局部势头。唉,市场上没有容易赚到的钱!!

然而,我只对我的模型进行了轻微的超参数调整,我的训练集非常有限。我们能做得更好吗?请在下面的评论中告诉我你得到了什么结果,以及你是如何部署 WaveNet 的!

如何用 Python 构建基于内容的音乐过滤推荐系统

原文:https://towardsdatascience.com/how-we-built-a-content-based-filtering-recommender-system-for-music-with-python-c6c3b1020332?source=collection_archive---------9-----------------------

背景:这个项目指的是 Lambda School 的 Lambda 实验室,学生们在过去的 5 周时间里构建了生产级的 web 应用程序,其中一些人利用机器学习模型作为他们后端的一部分。我们小组的任务包括开发一个应用程序,根据他们的情绪推荐无版权音乐。我是使用 Python 和 Django 等工具实现后端的数据科学团队的一员。如果你想看成品,去 moodibeats.com 看看,在那里你会找到超过 1000 首无版权音乐的目录——其中一些被你即将在这里看到的机器学习模型标记。

第一部分:推荐系统一瞥

每当我想到推荐系统,我就会想到这部电影:

高保真19 年前上映的一部电影,讲的是一个名叫罗布·戈登的唱片店老板,他的员工据说对音乐非常了解,以至于他们实际上阻止顾客购买他们想买的音乐。我提到这一点是因为在我们有网飞、亚马逊和 YouTube 之前,真人是最接近个性化推荐系统的。

知道你喜欢什么并推荐最新 Blink-182 或 Green Day 专辑的唱片店老板,尝过菜单上所有东西并根据你以前吃过的东西确切知道你想要什么的餐馆服务员,或者在街上告诉你去你正在寻找的地方的最快和最容易的方法的随机陌生人——这些都是活生生的推荐系统——并且非常有效。

问题是它们无法扩展。直到有了像谷歌这样的互联网,它才得以扩展。即便如此,直到数据科学的到来及其处理大量数据的能力出现之前,也没有办法有效地评估推荐过程。

推荐系统通常可以分为两种类型:

  1. 基于协作的过滤:基于用户相似性提供推荐——使用kNN(k-最近邻)或矩阵分解算法。协同过滤是个性化推荐系统的黄金标准,但你需要大量的用户数据,这就是为什么像 YouTube 和亚马逊这样的应用程序能够如此有效地做到这一点。
  2. 基于内容的过滤:基于元数据或你想推荐的东西的特征提供推荐。如果你推荐电影之类的东西,那么你可以使用类型、演员、导演、电影长度等。作为预测你是否喜欢一部电影的输入。

对于 MoodiBeats,由于数据的限制,我们最终选择了基于内容的过滤。

第二部分:对 MoodiBeats 起源的一瞥

回到我们的 Lambda Labs 项目,在 MoodiBeats 的规划阶段,我们团队内部有一些相当大的斗争。试图将机器学习集成到尚不存在的 web 应用程序中的一个主要问题是先有鸡还是先有蛋的问题——在没有实际数据的情况下,如何设计数据科学驱动的前端,以及如何为您不太确定其规范的网站获取数据?

最初,数据科学家希望使用现成的 CSV 文件,所以我们花了近两周时间分析了 last.fm 数据集和臭名昭著的 FMA 数据集。最终,为了避免版权问题和让用户下载歌曲的不可行性,前端团队决定使用 YouTube 的 API 和播放器来播放无版权音乐。这迫使数据科学团队完全放弃了在 last.fm 和 FMA 数据集上所做的所有工作,并在项目中途重新专注于尝试从 YouTube v3 API 获取数据。

第三部分:让我们构建一个作为 REST API 的准系统 Django 后端

警告 1:我将快速构建一个 Django 后端,只做最少的解释,这样对 Django 没有太多经验但感兴趣的读者可以参考 Medium 或 YouTube 上的无数教程,或者这里的。

警告 2:第三和第四部分必然会很长。但是,要知道我们在这里所做的实际上是建立一个机器学习管道,它将:

  • 从 YouTube API v3 自动检索数据
  • 运行机器学习模型
  • 将 YouTube 数据和机器生成的预测(在这种情况下是情绪)作为 RESTful 端点公开

因此,对于希望收集大量新数据并以世界其他地方可以访问的形式拥有这些数据的数据科学家来说,这是非常重要的,而且可能非常有用。*如果您只关心数据科学部分,请直接跳到第五部分。

在命令行上:

"""Working within a virtual environment is highly recommended.  For this project either Conda or Pipenv is sufficient.  I'm using Python 3.6 and Django 1.11.20 and PostgreSQL for this project."""$ mkdir MoodiBeatsAPI && cd MoodiBeatsAPI# psycopg2 is for interfacing with PostgreSQL database
$ pip install Django==1.11.20 psycopg2# don't forget the trailing period
$ django-admin startproject music_selector .

现在在你选择的文本编辑器中打开项目文件夹(MoodiBeatsAPI ),现在很多人使用 VS 代码,我仍然使用 Sublime 文本。

Django 将 SQLite3 作为数据库提供,但是我更喜欢使用 PostgreSQL,所以如果您还没有 PostgreSQL,我建议您在系统上安装它。

您的项目结构应该如下所示:

.├── manage.py└── music_selector ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py

首先创建 PostgreSQL 数据库:

$ psql -d postgrespostgres=# CREATE DATABASE moodibeats;# You can verify that the database has been created by running postgres=# \l# And exit
postgres=# \q

进入您的 settings.py 并进行一些更改:

### Change this:DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': os.path.join(BASE_DIR, 'db.sqlite3'),}
}### To this:DATABASES = {'default': {'ENGINE': 'django.db.backends.postgresql_psycopg2','NAME': 'moodibeats', # Name of our database'USER': 'sammylee', # This would be different for you'PASSWORD': '','HOST': 'localhost','PORT': '5432', }
}

在命令行上:

$ python manage.py migrate
$ python manage.py createsuperuser# Create your credentials$ python manage.py runserver# Go to [http://127.0.0.1:8000/](http://127.0.0.1:8000/) on your web browser
# Append 'admin' at the end of your localhost to gain access to your # Django admin app

如果一切顺利,您应该会看到:

现在让我们制作 Django 应用程序,它将是我们项目的主要功能核心。我们在这里所做的就是创建一个数据库来保存我们的数据,并将其公开为一个端点,这样就不再需要 views.pyDjango 模板系统了。在命令行上:

$ python manage.py startapp songs

然后将新的“歌曲”应用添加到 INSTALLED_APPS 下的 settings.py :

INSTALLED_APPS = [# ...'songs',]

您的项目结构现在应该是这样的:

让我们为我们的新歌曲应用程序创建一个数据库表:

models.py

# songs/models.pyclass NewVideo(models.Model):MOOD_CHOICES = (('HAPPY', 'Happy'),('IN-LOVE', 'In-Love'),('SAD', 'Sad'),('CONFIDENT-SASSY', 'Confident-sassy'),('CHILL', 'Chill'),('ANGRY', 'Angry'),)video_title = models.TextField(db_index=True, null=True,        blank=True)   video_id = models.CharField(max_length=11, null=False, blank=True, primary_key=True) moods = models.CharField(choices=MOOD_CHOICES, max_length=20,  default='HAPPY')labeled = models.NullBooleanField() video_description = models.TextField(null=True, blank=True) predicted_moods = models.CharField(max_length=17, null=True, blank=True) def __str__(self):return self.video_title

你在上面看到的六种情绪[快乐、悲伤、自信、时髦、恋爱、寒冷、愤怒]将是我们的机器学习模型试图预测并最终作为 REST 端点公开的情绪。

这个新的视频模型也是我们为后端保存训练数据的地方。数据将来自一个 python 函数,该函数将对 YouTube v3 API 进行一系列调用,并自动保存到我们的数据库。

现在在 admin.py

# songs/admin.pyfrom .models import NewVideoclass NewVideoAdmin(admin.ModelAdmin):list_display = ['video_id','video_title','moods','labeled','predicted_moods',
]search_fields = ['video_id','video_title','moods',]list_editable = ['moods','labeled',]admin.site.register(NewVideo, NewVideoAdmin)

然后在命令行上:

$ python manage.py makemigrations
$ python manage.py migrate

如果你已经走了这么远,拍拍自己的背,我们已经走了一半的路了。

对于那些不熟悉 RESTful web APIs 的人来说,最简单的理解是,这只是后端 web 应用程序将其数据库公开为 JSON 的一种方式。它被认为是软件工程中最重要的发明之一,但是一旦你开始自己实现它们,它就非常容易掌握和使用。

为此,我们需要 Django REST 框架,我们可以将它覆盖在我们的项目之上。

在命令行上:

$ pip install djangorestframework==3.8.2# And add to INSTALLED_APPS on settings.py
INSTALLED_APPS = [# ... 'rest_framework',
]

现在,我们实际上要创建一个单独的“api”应用程序,它将保存我们所有的 API 相关代码:

$ python manage.py startapp api

在 api 内部,创建一个serializer . py文件:

# api/serializers.pyfrom rest_framework import serializersfrom songs.models import NewVideoclass NewVideoSerializer(serializers.ModelSerializer):class Meta:model = NewVideofields = ['video_title','video_id','moods',]

然后在你的views . pyAPI app 里面:

# api/views.pyfrom django.shortcuts import renderfrom rest_framework import genericsfrom songs.models import NewVideofrom .serializers import NewVideoSerializer# Create your views here.class NewVideoAPIView(generics.ListCreateAPIView):queryset = NewVideo.objects.all()serializer_class = NewVideoSerializer

现在在 api 应用程序中创建一个 urls.py ,并且:

# api/urls.pyfrom django.conf.urls import urlfrom .views import NewVideoAPIViewurlpatterns = [url(r'^new-videos/$', NewVideoAPIView.as_view()),
]

然后在你的 urls.py 里面的项目配置文件夹(music_selector):

# music_selector/urls.pyfrom django.conf.urls import url, include
from django.contrib import adminurlpatterns = [url(r'^admin/', admin.site.urls),url(r'^api/', include('api.urls', namespace='api')),]

现在转到 Django 管理员,通过插入一些数据创建一个新的视频对象:

现在运行您的本地服务器,并在浏览器上转到该端点:

$ python manage.py runserver# Point your browser to [http://127.0.0.1:8000/api/new-videos/](http://127.0.0.1:8000/api/new-videos/)

Django REST 框架最棒的特性之一是它的可浏览 API,如果一切顺利,应该是这样的:

祝贺您——您已经创建了一个 RESTful 端点!

创建这个的重要性在于,我们现在可以以一种方式公开我们的数据,这种方式可以作为 API 被 React-made FrontEnds 之类的东西消费,这正是我们在 MoodiBeats 项目中所做的。

第四部分:让我们创建一个训练数据集

Django 最酷的部分之一是能够创建所谓的管理命令——管理员用户可以在命令行上运行的功能:

$ python manage.py do_something

对于 MoodiBeats 的数据科学部分,我们需要一个从 YouTube API 获取数据并填充数据库的函数。为了做到这一点,我们在 Django 中创建了一个管理命令来获取 video_id 和 video_title,并在我们的 Heroku 服务器上设置了一个名为 Heroku Scheduler 的东西,每 24 小时运行一次相同的功能——有效地创建了所谓的 Cron 作业

为此,您必须完成以下步骤:

  1. 在歌曲应用程序中创建一个名为管理的文件夹
  2. 在管理内部创建一个名为 init 的文件。py
  3. 同样在管理内部创建另一个名为命令的文件夹
  4. 然后在命令内部创建另一个名为 init 的文件。py
  5. 最后,在命令内部,创建一个名为 get_new_videos.py 的文件
  6. 给自己弄一个 YouTube v3 API 密匙
  7. $ pip 安装 python-dotenv

如果您确实想要运行这个管理命令,请确保您已经安装了 python-dotenv。然后在您的顶层目录中,创建一个名为的文件。env 你想在这里存储 SECRET_KEY 或者 YouTube API Key 之类的东西,然后添加。env 到你的。gitignore 文件。如果你想把你的项目提交给 GitHub Repo,你需要做这些事情。

记住,永远不要把 API 密匙之类的东西或者任何私人的东西放到你的 GitHub Repo 或者任何公共场所。如果你这么做了,你就冒着非常糟糕的事情从非常糟糕的人那里发生的风险。

get_new_videos.py

# Credit goes to my data science teammate John Humphreys. for writing 
# this functionfrom django.core.management.base import BaseCommandfrom googleapiclient.discovery import build
from dotenv import load_dotenv
import osimport jsonfrom songs.models import NewVideoload_dotenv()def html_reverse_escape(string):'''Reverse escapes HTML code in string into ASCII text.'''# see Ned Batchelder post [https://stackoverflow.com/questions/2077283/escape-special-html-characters-in-python](https://stackoverflow.com/questions/2077283/escape-special-html-characters-in-python)return (string \.replace("&amp;", "&").replace("&#39;", "'").replace("&quot;", '"'))def search_api():'''Searches YouTube Data API v3 for videos based on project-specified parameters; returns list of videos.'''api_service_name = 'youtube'api_version = 'v3'DEVELOPER_KEY = os.getenv('DEVELOPER_KEY')youtube = build(api_service_name, api_version,developerKey = DEVELOPER_KEY)request = youtube.search().list(part='id,snippet',maxResults=20,q='instrumental edm',relevanceLanguage='en',type='video',videoDuration='medium',videoLicense='creativeCommon',videoSyndicated='true',).execute()videos = []
result_count = 0for search_result in request['items']:video_title = search_result['snippet']['title']video_title = html_reverse_escape(video_title)video_id = search_result['id']['videoId']video_description = search_result['snippet']['description'] try:new_videos = NewVideo(video_id=video_id,      video_title=video_title, video_description=video_description, predicted_moods=predicted_moods)new_videos.save()except:passclass Command(BaseCommand):def handle(self, *args, **options):print("Pulling data from YouTube API and saving")search_api()

如果您研究一下这个函数,它被设置为从 YouTube API 检索最多 20 个结果。我们特意将q设置为“乐器 edm ”,将videoLicense设置为“creativeCommons ”,因为我们只想要没有版权的音乐视频。

让我们运行命令

$ python manage.py get_new_videos

现在运行你的本地 Django 服务器,回到你的管理员那里。

您应该会看到类似这样的内容:

如果您单击 video_id 进入详细视图,您应该会在 description 字段中看到视频描述。

在大约 7 天的时间里用不同的查询参数做这件事,最终给了我们一个超过 1000 首歌曲的数据库。

在我们进入项目的数据科学部分之前,为了完成一个训练集,你需要做的是给你的数据贴上标签。这对我来说是一个突然的觉醒,因为我最终给 800 多个 YouTube 视频贴上了“正确”情绪的标签。

我给数据科学学生的建议是:不要习惯 UCI 数据仓库。

第五部分:数据科学时代的到来

我们将使用数据科学工具,因此请确保您的虚拟环境中安装了 Conda(我建议使用 miniconda)、Jupyter、Pandas 和 Scikit-Learn 等工具。

现在我们终于有了数据,是时候将它们转换成我们开始时期望的整洁的小 CSV 文件了。

我们将连接到 postgreSQL 数据库,查看一下表模式,然后运行一个简单的复制命令,复制到桌面上我创建的名为 CSV 的文件夹中。

$ psql -d postgrespostgres=# \c moodibeats;moodibeats=# \dtmoodibeats=# SELECT * FROM songs_newvideo LIMIT 5;\copy songs_newvideo(video_id,video_title,moods,labeled,video_description,predicted_moods) TO '/Users/sammylee/desktop/CSV/videos.csv' DELIMITER ',' CSV HEADER;

现在启动你的 Jupyter 笔记本,导入熊猫,看看数据:

# In the same directory which contains your 'videos.csv' file
$ jupyter notebook

然后

import pandasvideos = pd.read_csv('videos.csv', encoding='utf-8')video.head()

当然,在我的例子中,我们有更多的数据,其中大多数都有标签,但这正是我们想要的。

让我们回顾一下迄今为止我们所取得的成就:

  1. 我们构建了我们的问题(基于内容的过滤),并制定了一个计划来为数据科学构建 Django 后端,供 React 前端使用。
  2. 然后,我们使用 Django REST 框架构建了后端
  3. 利用 YouTube v3 API 检索数据

我们已经有效地为 MoodiBeats 的数据科学部分创建了一个第一通道的迷你管道。

我们还需要记住,我们使用文本数据进行分析,这意味着我们需要使用不同的工具来进行机器学习。

这些不同工具中最重要的是单词袋模型,它允许我们将文本表示为数字向量。单词袋模型基本上是一个两步过程,首先是 对文本文档 进行标记,然后将它们转换为字数的特征向量。

例如

"""This is taken straight out of Sebastian Raschka & Vahid Mirjalili's Python Machine Learning 2nd Edition, and in fact this project owes a debt of gratitude to their chapter 8 on Sentiment Analysis"""import numpy as np
from sklearn.feature_extraction.text import CountVectorizer
count = CountVectorizer()
docs = np.array(['The sun is shining','The weather is sweet','The sun is shining and the weather is sweet'])
bag = count.fit_transform(docs)# print out the vocabulary of our bag-of-words:
print(count.vocaulary_)

这将返回包含唯一单词及其索引位置的 Python 字典:

{'the': 5, 'sun': 3, 'is': 1, 'shining': 2, 'weather': 6, 'sweet': 4, 'and': 0}

此外,我们可以看到单词袋模型为我们创建的特征向量:

print(bag.toarray())# Returns
[[0 1 1 1 0 1 0][0 1 0 0 1 1 1][1 2 1 1 1 2 1]]

此数组的第一列[0,0,1]位于索引位置 0,表示单词“and”,它只出现在第三个句子中,因此为[0,0,1]。第二列[1,1,2]代表‘是’,我们可以看到‘是’在前两句出现一次,在最后一句出现两次。

我们需要的第二个工具是实际的机器学习算法。对于 MoodiBeats,我们选择了一个逻辑回归分类器。

Sigmoid function for Logistic regression

我们本质上正在做的是通过获取关于 YouTube 音乐视频的元数据(在这种情况下是文本形式的视频描述)并使用它来预测视频本身的情绪,来建立一个非个性化的基于内容的过滤推荐系统。逻辑回归试图根据样本的概率函数对样本进行分类,概率函数是一种称为 sigmoid 函数的 S 形函数。阈值设置为 0.5,超过该阈值的概率被分类为 1,低于该阈值的概率被分类为 0。在视频描述的数字表示上使用这种方法允许我们找到情绪的概率,并选择概率最高的一个作为我们的预测( One-vs-Rest method )。

另一个重要的考虑是,当处理文本数据时,几乎总是会处理脏数据 HMTL、表情符号、标点符号等。我们还将编写一个函数来预处理脏数据。因此,在这里,我们将文本清理和文本标记化结合起来,为我们提供数据,然后我们可以在这些数据上运行逻辑回归分类器。

"""A simple text cleaning function borrowed from Sebastian Rachska""" import refrom nltk.corpus import stopwordsstop = stopwords.words('english')def tokenizer(text):text = re.sub('<[^>]*>', '', str(text))emoticons = re.findall('(?::|;|=)(?:-)?(?:\)|\(|D|P)', text.lower())text = re.sub('[\W]+', ' ', text.lower()) +\' '.join(emoticons).replace('-', '')tokenized = [w for w in text.split() if w not in stop]return tokenized

实际训练之前的下一步是对我们的目标变量进行编码,也就是说将我们的情绪(快乐、自信、时髦、悲伤、愤怒、寒冷、恋爱)转化为我们的算法可以使用的数字。

在这里,我们假设你已经在 Django admin 中浏览了你的数据,观看了所有的 YouTube 音乐视频,并在将它们发送到熊猫数据帧作为训练数据进行分析之前正确地标记了它们。

from sklearn import preprocessingle = preprocessing.LabelEncoder()videos['moods_enc'] = le.fit_transform(videos['moods'])
df.head()

以下是我们最终培训的核心内容:

from sklearn.feature_extraction.text import HashingVectorizer
from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import LogisticRegressionvect = HashingVectorizer(decode_error='ignore',n_features=2**21,preprocessor=None,tokenizer=tokenizer)param_grid = {'C': [0.001, 0.01, 0.1, 1, 10, 100]}lr = LogisticRegression()grid_search = GridSearchCV(lr, param_grid, cv=5)X_train = vect.transform(X_train.tolist())grid_search.fit(X_train, y_train)X_test = vect.transform(X_test)print('Test set accuracy: {:.3f}'.format(grid_search.score(X_test, y_test)))print("Best parameters: {}".format(grid_search.best_params_))print("Best cross-validation score: {:.2f}".format(grid_search.best_score_))

在我们更大的 YouTube API 数据集上训练这个模型给了我们:

Test set accuracy: 0.368
Best parameters: {'C': 10}
Best cross-validation score: 0.42

虽然这些结果不是很好,但由于我们的项目处于功能冻结状态,我们基本上没有时间收集更多的数据并重新训练我们的模型。事实上,在我写这些文字的时候,离我们向全校做报告只有一个小时了。

下一个挑战是将模型投入生产。

我们所做的是通过在 Django 应用程序中插入我们训练过的模型来自动化这个过程,以作为管理命令运行:

$ python manage.py get_new_videos

您可以在生产中的 Heroku 调度程序上将该函数设置为 Cron 作业,以便在调用 YouTube API 的同时自动运行您的预测。为了简洁起见,我将跳过这一部分,但是如果你想了解它,请在评论中告诉我。

第六部分:经验教训

看看这首歌

An awesome band I discovered as a freshman in college

如果我要求把这归类为我们的六种情绪之一:

[HAPPY, CHILL, CONFIDENT-SASSY, SAD, ANGRY, IN-LOVE]

我敢肯定,你们大多数人会回答说,这首歌清楚地表达了愤怒,达到了愤怒的程度。

但是如果我给你这样的东西呢:

这是怎么回事?

普通观众水平的歌曲有两个维度(歌曲、歌词),但音乐视频有三个维度(歌曲、歌词、视觉)。

乍一听,这首歌听起来很冷。视觉效果有点傻(看看所有关于小预算和绿色屏幕的评论)。

现在来看看这首歌的一些歌词:

[Verse 1: Ed Sheeran]
I’m at a party I don’t wanna be at
And I don’t ever wear a suit and tie, yeah
Wonderin’ if I could sneak out the back
Nobody’s even lookin’ me in my eyes
Can you take my hand?
Finish my drink, say, “Shall we dance?” (Hell, yeah)
You know I love ya, did I ever tell ya?
You make it better like that[Pre-Chorus: Ed Sheeran]
Don’t think I fit in at this party
Everyone’s got so much to say (Yeah)
I always feel like I’m nobody, mmm
Who wants to fit in anyway?[Chorus: Ed Sheeran]
‘Cause I don’t care when I’m with my baby, yeah
All the bad things disappear
And you’re making me feel like maybe I am somebody
I can deal with the bad nights
When I’m with my baby, yeah
Ooh, ooh, ooh, ooh, ooh, ooh
‘Cause I don’t care as long as you just hold me near
You can take me anywhere
And you’re making me feel like I’m loved by somebody
I can deal with the bad nights
When I’m with my baby, yeah
Ooh, ooh, ooh, ooh, ooh, ooh[Verse 2: Justin Bieber]
We at a party we don’t wanna be at
Tryna talk, but we can’t hear ourselves
Press your lips, I’d rather kiss ’em right back
With all these people all around
I’m crippled with anxiety
But I’m told it’s where we’re s’posed to be
You know what? It’s kinda crazy ’cause I really don’t mind
And you make it better like that[Pre-Chorus: Justin Bieber]
Don’t think we fit in at this party
Everyone’s got so much to say, oh yeah, yeah
When we walked in, I said I’m sorry, mmm
But now I think that we should stay

这首歌真的很寒意吗?难过?或者甚至是恋爱中?

你如何让一台机器学习像恋爱这样复杂的情感?爱情是人类情感的那不勒斯冰淇淋。有一种幸福的爱情,一切都很顺利,两个人都无法忍受彼此分离。有一种单相思,只有一个人感受到它的情感。甚至有一种爱是为结婚很久的夫妇保留的,在那里事情不是疯狂的,而是稳定的。

情绪是超级主观的,因此对于机器来说是一个超级难解决的问题。但是非常有趣。

第七部分:致谢

我要感谢我在 Lambda 学校 MoodiBeats 项目中的队友:

Jonathan Bernal、John Humphreys、史云光 Jake de los Santos、医学博士 Kawsar Hussen、Logan Hufstetler、Davina Taylor 和我们的项目经理 Kevin Brack。

搭建 MoodiBeats 是我在 Lambda 学校经历的最好、最有趣的经历之一。我们的团队太棒了,我不会忘记这次经历。

这篇文章的代码在这里:

[## captmoonshot/moodibeats _ API _ medium

对于中等职位。在 GitHub 上创建一个帐号,为 Captmoonshot/moodibeats _ API _ medium 开发做贡献。

github.com](https://github.com/Captmoonshot/moodibeats_api_medium)

我们如何建立一个人工智能驱动的搜索引擎(而不是谷歌)

原文:https://towardsdatascience.com/how-we-built-an-ai-powered-search-engine-without-being-google-5ad93e5a8591?source=collection_archive---------7-----------------------

你也可以!

由 Jack Pertschuk 合著,看看我们的 Github

在这篇文章中,我将讲述创建一个通用的人工智能搜索引擎的困难,以及我们如何开发我们的解决方案, NBoost 。

爆炸场

人工智能信息检索是一个蓬勃发展的研究领域。该领域的研究集中在基于搜索结果的含义而不仅仅是关键词来检索最相关的搜索结果。前沿研究通常涉及利用现有的深度神经网络(如谷歌的 BERT),并训练它们对搜索结果进行排名。然而,问题是大量的(我将在下面谈到)。建立一个健壮的、可扩展的语义搜索引擎不是一件容易的事,所以谷歌赚这么多钱也就不足为奇了。

跨栏

  1. 很难击败现有的解决方案。现有的搜索引擎如 Elasticsearch 利用文本匹配算法,如最佳匹配 25 。这些算法通过计算词频和其他单词模式来工作。它们实际上工作得非常好。因此,他们很难被打败。
  2. 即使你击败了现有的解决方案,也很难一概而论。机器学习中经常遇到的一个问题是,在一个特定的任务上训练一个模型太多,以至于它不能对一个新的任务得出结论。这被称为过拟合。即使你的模型对研究文章的搜索结果比基于文本的搜索引擎更好,那也不意味着它对烹饪食谱的搜索效果也一样好。
  3. 最先进的(SoTA)模型通常速度缓慢且不可扩展。即使你已经有了既能击败文本匹配算法,又能在许多不同领域工作的完美模型,在生产中使用起来可能还是太慢了。通常,SoTA 模型(如 BERT)必须在特殊的硬件(GPU)上运行,以适应生产工作负载。这种硬件在计算上是昂贵的(因此在财政上也是如此)。要建立一个对数百万文档进行排序的搜索引擎,不能只告诉一个大模型对每一个搜索结果进行逐一排序。

我们是如何做到的

正如我之前提到的,有大量的研究正在研究机器学习在搜索引擎中的意义。这意味着研究人员正在竞争赢得信息检索基准上的头名,如马可女士。与现有的搜索引擎相比,其中一些模式的搜索结果质量提高了一倍多。我们使用这些模型,从中学习,并创建了我们自己的模型(使用顶级基准)。这就是我们击败现有解决方案的方式。

我们意识到,如果我们不能扩大规模,这些都没有多大用处。这就是我们构建 NBoost 的原因。当你部署 NBoost 时,你部署了一个位于用户和搜索引擎之间的前沿模型,一种代理。每次用户查询搜索引擎时,模型都会对搜索结果进行重新排序,并将最佳结果返回给用户。我们还内置了对将 NBoost 部署到云的支持,并通过 Kubernetes 引擎根据需要扩展到任意数量的计算机。这个解决了可扩展性问题

从一开始,我们就想创建一个平台,为特定领域的 T2 搜索引擎奠定基础。因此,我们需要确保 NBoost 具有足够的通用性,能够应用于知识领域内的不同应用程序/数据集。默认模型在数百万个 bing 查询上被训练。我们发现,与现成的弹性搜索相比,我们的默认模型将搜索结果的相关性提高了 80%。为了测试该模型在不同语料库上的可推广性,我们在维基百科查询(TREC·卡尔)上测试了它,这是一个它以前从未见过的数据集。当前端显示默认模型在不同的数据集上将搜索结果提升了 70%时,这是一个惊喜。

您可以在此复制我们的结果。

你也可以!

当我们在构建 NBoost 的时候,我们尽力让我们的工具开源并易于使用。我们通过 pip、Docker 和 Helm (Kubernetes)提供它。我们的模型托管在 Google Buckets 上,当您通过nboost --model_dir <model>运行 NBoost 时会自动安装。您可以在我们的基准表中找到可用型号列表。

你可以按照我们的教程来创建你自己的人工智能搜索引擎!

我们如何用深度学习构建虚拟人的大脑

原文:https://towardsdatascience.com/how-we-construct-a-virtual-beings-brain-with-deep-learning-8f8e5eafe3a9?source=collection_archive---------18-----------------------

3 个视频演示,展示了 TwentyBN 用于人类行为理解的深度学习技术

A trip inside a virtual being’s brain (Illustrated by Luniapilot)

这篇博文是由 TwentyBN 撰写的来自 Embodied AI 你的关于 AI 化身和虚拟存在背后的最新新闻和技术的双周刊。不要错过👉 订阅此处

下面这张照片是 VentureBeat 的院长高桥两周前在首届虚拟存在峰会上拍摄的,它充分说明了这篇博文:“ 人工智能使虚拟存在成为可能 ”。在过去的几周里,我们的几位读者联系了我们,希望了解更多关于 TwentyBN 的人工智能化身 米莉 背后的智能。

“AI makes a virtual being possible” (Credit: Dean Takahashi @ Virtual Beings Summit)

因此,我们很高兴带你去 TwentyBN 的人工智能化身米莉的大脑深处旅行。请务必观看下面的 3 个视频演示👇

人工智能化身的大脑

Millie 的大脑由深度学习模型驱动,该模型在 TwentyBN 收集的超过 300 万个专有视频数据上进行训练。由于我们的座右铭是教会机器像人类一样感知世界,米莉的大脑有两个主要组成部分,一个视觉模型和一个音频模型,类似于我们的大脑如何处理我们每天经历的视觉和声音。

视觉模型:理解人类行为

我们的视觉模型是经典的基于图像的对象检测器到视频的扩展。类似于典型的对象检测器,如 YOLOv3 ,我们的视觉模型同时进行定位和分类:它通过在对象周围放置边界框来检测对象,并识别每个边界框的对象类型(如面部、身体等)。).

与基于图像的检测器不同,我们的模型还理解每个对象正在执行的动作。这意味着它不仅可以检测和区分人脸和人体,还可以确定,例如,一张脸是“微笑”还是“说话”,或者一个身体是“跳跃”还是“跳舞”。这是通过在视频数据而不是静态图像上训练我们的模型来实现的。

与只处理二维图像的图像检测器相比,我们的模型可以处理时间维度。在架构方面,我们通过使用 3D 卷积层而不是 2D 卷积层来实现这一点,这使得神经网络能够提取识别每个对象执行的动作所需的相关运动特征。

这种端到端的方法为我们分析和理解人类行为提供了一个非常有效的工具。总之,我们的模型经过训练,可以检测超过 1,100 种人类活动和手势。我们试验的另一种方法包括将定位和分类分成两个独立的子任务:首先,我们提取包围盒,并使用对象检测器在每个对象周围进行裁剪;然后,我们使用第二个动作识别模型对每个作物中执行的动作进行分类。

我们的经验告诉我们,端到端方法比这种两步方法有几个好处:

  • 简单:只需要维护一个深度学习模型。
  • 多任务/转移学习:同时解决两个任务应该会让模型在每个单独的任务上做得更好。
  • 全知:动作的识别不限于场景中的一个人;该模型知道同时发生的所有动作。
  • 恒定复杂度:场景中有多少人并不重要。多人识别和动作分类所需的计算和一个人一样高效。
  • 速度:同时识别和分类人体动作,节省推理时间。这使得在 iPad Pro 等边缘设备上实时运行视觉模型成为可能。

音频模型:语音到意图

以前依赖于云解决方案,现在我们有自己的边缘音频模型,不仅可以理解人们做什么,还可以理解他们说什么。与典型而复杂的管道(见下图)不同,我们受到人类处理语音的启发,选择了最直接和端到端的方法:语音到意图。在这种方法中,一个人不需要听和抄写每个单词来理解另一个人的意思。已经探索了各种语音到意图的方法(例如这个)。类似于 Jasper 模型,我们模型的架构是完全卷积的。

TwentyBN 的首席执行官 Roland 喜欢语音到意图的方法:

“我们是一家捕捉意图的公司,所以直奔人类意图是我们 TwentyBN 的工作方式。通过为我们的人工智能化身开发内部音频功能,我们只是将我们在视频理解方面的成功转移到语音识别上。这一切之所以成为可能,要归功于我们建立的全球最大的群体行动平台,它让我们能够快速获取大规模的基于意图的数据。”

3 语音转意图方法的优势包括:

  • 鲁棒性:在我们对不同语音识别方法的实验中,语音到意图最终对噪声、口音和人们单词发音的变化更加鲁棒。
  • 轻量级:神经网络可以轻松地在小型嵌入式设备上实时运行,如平板电脑和智能手机。
  • 反应性:与使用云解决方案相比,在本地运行音频模型大大减少了延迟,显著改善了与 Millie 等人工智能化身的交互和整体用户体验。

走向 SenseNet:一个视听模型

就在我们说话的时候,TwentyBN 的研究人员和工程师正在研究一种新的深度学习模型,称为 SenseNet ,它将我们的视觉和音频模型融合成一个单一的视听模型,用于意图分类。

SenseNet 在将虚拟生物从高度受限的环境带到“野外”方面至关重要(想象一下在拥挤的超市里看到 Alexa)。人工智能就像人类一样,需要依赖视觉线索,这些线索可以揭示话语的来源或场景的背景。融合视觉和音频是在混乱环境中实现高意图分类准确性的必要步骤。

我们希望你喜欢这次在虚拟人大脑中的旅行。如果您有任何意见或问题,请告诉我们。确保你和你的朋友分享这篇文章🙌并且 s 订阅在下面👇

[## 人工智能化身时事通讯

具体化的人工智能是权威的人工智能化身时事通讯。报名参加最新新闻、技术…

www.embodiedai.co](http://www.embodiedai.co/)

写的是 纪尧姆 那华 。编辑 罗兰大卫 安托万 ,以及 莫里茨 。插图由 氹欞侊 绘制。

我们如何为机器学习抛弃 A/B 测试

原文:https://towardsdatascience.com/how-we-dumped-a-b-testing-for-machine-learning-2b44632ba9df?source=collection_archive---------11-----------------------

我之前的工作是 A/B 测试员。我们将成千上万的访问者从付费渠道吸引到我们的网站,所以自然地,我们希望通过优化我们的转化率来确保我们的广告支出得到最大的回报。每隔一周,我会启动新的测试并分析之前测试的结果。

有一次,当我正在为我们的一个文凭网站(我在一所私立大学工作)完成一个页眉图像测试时,我决定做一个简单的实验:我让我的同事根据他们的表现对页眉图像的变体进行排名——旨在将我队友的猜测与实际结果进行比较。至少可以说,这个结果是令人惊讶的。

他们的猜测大错特错。这并不罕见;A/B 测试意在引出顾客想要的和营销人员认为顾客想要的之间的差异。但我的一些队友是那个文凭项目的毕业生,这使他们成为我们的目标市场。他们对统计上表现最差的标题图像的强烈偏好让我想到:也许在 A/B 测试的设计中有一个根本性的缺陷。

让我来举例说明:假设你决定 A/B 测试你的标题。

在变体 A 和变体 B 之间平分网站流量后,你意识到 70%的总转化发生在变体 A 上,30%的转化来自变体 B。

根据 A/B 测试的方法——你会得出结论,与变体 B 相比,变体 A 表现出更好的性能——因此它应该成为默认标题。

这就是错误所在:绝对不能保证在变体 B 上转化的人也会在变体 a 上转化。也许变体 B 的标题与你的目标市场的子集产生了共鸣,这是总转化的 30%。如果你决定选择变式 A,你可能最终会疏远那些喜欢变式 B 的人——从而损害你的整体转化率。

由于我的人工智能创业经验,我对 Tensorflow 有一些初步的了解,它似乎是解决这个问题的完美工具。目标是在页面呈现之前预测用户最有可能转换的标题。收集数据和做出预测的时间限制迫使我依赖客户端的特性列表。使用免费服务,我能够找到访客的真实 IP 地址,并随后找到他们来自的城市。另一个 API 调用给了我他们城市当前的天气情况。

我必须给浏览器、操作系统和城市名称分配一个数字 id,因为机器学习模型使用统计数据,这使它们无法消化单词。由于世界上城市的数量太多,我将 ML 实验的范围限制在加拿大——即使在那时,也有数百个城市需要标记,它本身就成了一个迷你项目。

最后,我们用以下特征来训练我们的模型:

时区—浏览器名称—操作系统名称—浏览器的默认语言—启用 cookie 启用 java 屏幕宽度—屏幕高度—屏幕颜色深度—一周中的某一天—一天中的某一小时—城市—一天中的最低预测温度—一天中的最高预测温度—风速—风向—能见度—大气压

为了找出标题的变化,我们调查了“前线”的同事:招生顾问。本质上,我们不只是试图预测最好的标题,我们试图猜测潜在客户的意图,在我看来,没有人比你的销售团队更了解这一点。

调查显示,我们的大多数学生属于两大类:

  1. 想要在事业上出人头地的职场人士。
  2. 想要享受从任何地方学习的自由的年轻人。

为了迎合这两个类别,我们创建了以下两个网站标题:

  1. 职业人士的 BBA
  2. 从任何地方为你的 BBA 学习

The two variants

现在,随着我们的功能集和标题变化锁定,是时候收集数据了。计划是运行每个标题,直到我们有 100 个数据点。由于登录页面是使用 Vue.js 框架构建的,让页面收集数据并在稍后阶段进行实时预测相对容易。

我们花了四周的时间来收集数据——我们让每个标题运行了大约两周,并收集了在这些标题上转化的访问者的属性。在那段时间里,我编写了管道代码来进行预测,并重新训练模型。为了简单起见,我使用了 Softmax 回归机器学习模型。

当每个标题有 100 个数据点时,就该训练 ML 模型了。我有一个坦白:理想情况下,在这个阶段,我应该执行一些被称为特征工程的东西,在那里你找出无关紧要的特征,并组合显示出强相关性的特征。但是由于我急于尽快得到解决方案,我将特性工程推迟到以后。

训练模型的第一遍只给了我们 52%的准确率——仍然优于抛硬币,但我们必须做得更好,ML 模型才是可行的。对超参数的修改将准确率提高到了 67%——不是最佳的,但我们用 160 个数据点(40 个数据点用于测试)训练模型,我们不可能指望性能比这更好。随着时间的推移,通过不断的再训练,准确率有望提高。

Adjusting hyper-parameters to improve the accuracy

在我们部署模型之前,需要做一些整理工作。例如,我们必须优化页面加载速度,以补偿实时预测算法增加的额外毫秒数。我们的策略是,最初在 20%的总会话中推出该模型,如果一切顺利,每周以 20%的速度增加该百分比,直到我们实现 80%的流量流向 ML 驱动的页面,20%流向常规页面的分布。我们希望 20%的流量总是流向非 ML 页面的原因是为了不断地训练模型(我们的探索利用策略)。

部署一个月后,我们注意到转化率增加了 4%。这个数字看起来并不令人兴奋,但对于一个在 PPC 广告上花费数百万美元的公司来说,这是值得的。

另一个指标显示了相当大的改进,这完全出乎意料:访问者在页面上花费的时间增加了 25% 。由于谷歌的算法奖励网站的用户参与度,会话持续时间的增加导致我们的每次点击成本大幅下降——使我们的线索更便宜。

但是就这样吗?最终目的是获得更便宜的线索吗?不。我们的目标是通过在第一次互动时定制我们的信息来满足他们的需求,从而改善我们学生的旅程,并在这样做的过程中,打破常规,推动可能性的边界。

有一句名言:“如果你不成长,你就是在死亡。”在我看来,增长是包括创新在内的诸多因素的副产品。所以,实际上…

“如果你不创新,你就死定了。”

我们如何获得第三名并赢得数据科学竞赛

原文:https://towardsdatascience.com/how-we-finished-3rd-and-still-won-a-data-science-competition-bf8a71cf8c38?source=collection_archive---------22-----------------------

我们有很多工作要做——甚至在最终分数公布之后。

made with ♥️ by Luciano Infanti

Listen to Unboxing Data Science on Spotify

这是一场新手对决全球资深科学家的对决,所以你可以想象结局。

几个月前,我们只是两个积累数据科学知识并努力专业进入该领域的学生。当时, Victor 是 IBM Research 的一名数据科学家实习生,而我是埃森哲的一名软件架构分析师。我们的共同目标使我们开始了越来越令人沮丧的竞争搜索,因为它总是归结为获胜纯粹是技术上的,像排行榜探测这样的事情变得司空见惯。

一个月后,我们发现了测试我们纯技术以外技能的机会:T2 EY next wave 数据科学竞赛 T3。它解决了亚特兰大的城市流动性问题,挑战参与者根据地理定位数据预测轨迹是否会在市中心结束。

这一次不同。

这不是另一个只靠硬技能的挑战,因为建立一个得分最高的模型只是成功的一半:一流的科学家必须向 EY 大学最高职位的评委展示他们的方法和研究背景。外部数据的使用、EDA 鲁棒性和面向问题的方法是主要标准。

在这里,我们给一个战略时间表,说明如何通过专注于解决潜在的问题,在获胜项目中转变我们的第三名模式。请跟随 GitHub 上的完整代码,全面了解我们。

我们如何分析数据

正如已经指出的那样,我们的工作方法是面向问题的,而不是面向竞争的。严格来说,这意味着我们已经使用以业务为中心的数据科学流程来管理我们的时间,以了解问题、探索数据、提取特征、训练模型和分析结果,从而使我们能够在需要时在真实环境中实施该解决方案,而不仅仅是产生一个事后可能无用的分数。

Our Data Science Cycle

第一个重要的步骤是深入理解我们试图解决的问题。在那里,我们在文献中进行了详尽的搜索,以澄清人们通常如何处理这个问题,以及使用了哪些工具。我们完成竞赛和处理数据的时间有限,这使得这一阶段对于定义和缩小我们对可行备选方案的关注非常重要,而不是在我们可投资的时间内花费时间在可能证明无用的技术上。

在开始我们的探索性数据分析阶段时,我们进行了一系列的可视化以了解总体数据分布,同时尝试检查数据生成中的不一致性和问题。然后我们遇到了一个主要问题:超过一半的数据是零距离轨迹,即它们的进入和退出位置是相同的。

这给建模带来了一些困难,如果没有广泛的分析,是不可能识别的。最后,我们把它变成了一个优势——在一个人的旅程中,零距离轨迹的计数后来成为一个特征。

A pair of 0-distance routes coupled with normal ones

此外,组织者提供的数据来自笛卡尔投影,而不是通常的纬度/经度值。将它们转换成后一种格式对我们的 EDA 和工程过程将是一个很大的优势,尽管我们最初缺乏这方面的知识。幸运的是,通过更深入的分析和研究,我们发现了如何使用 python 中的墨卡托投影pyproj库来转换所有值。

Visualization of most common trajectory paths using KMeans and Google Maps API

在探索和讨论了数据的空间复杂性之后,理解它们随时间的分布是至关重要的。像任何例行的人类活动一样,这些事件发生的时间对它们如何发生有着广泛的影响。

有效性是关键。我们分析中的这一点必须满足两个需求:1)断言训练集和测试集分布之间的一致性,以及 2)随着时间的推移提供基本的可视化。两者都显示在下面的柱状图中,但只有后者引发了讨论。

Fundamental visualizations through available time period (0h — 16h)

从图#1 中,我们可以观察到平均行驶距离的第一个局部最大值,发生在午夜(0h)。之后,上升趋势在早上 6 点左右达到全球最大值。根据上面的时间判断,我们得出结论,这些旅行将是上下班的路线——即使是午夜高峰也可能是夜班结束的标志。

虽然第一个可视化是启发性的,但第二个似乎是令人担忧的复杂性。市中心的人数不断打破最高记录,从早上 6 点到下午 3 点,我们预测的目标时段是下午 3 点到 4 点。

这意味着,正如趋势所示,我们的目标可能包含全球最大值,或者,在一个复杂的转折中,这些数字的第一次重大下降——这是现有数据中尚未看到的模式。我们必须赋予我们的模型更高的深度,以便它们能够准确预测目标。

我们如何投资于功能工程

我们最大的工作量是放在这个部门的有效增长上。我们希望通过研究和分析支持的特性来提升排名,所以性能最好的特性应该是我们最了解的。

因为我们的问题是关于轨迹分析,我们必须知道任何一点离中心和轨迹入口/出口有多远。所以在我们的第一轮研究之后,我们选择了对我们来说最有意义的三个距离公式。

Our main distances

哈弗线距离从根本上不同于其他距离-它考虑了表面的球形形式-并要求我们掌握我们在 EDA 上学习的墨卡托投影。

此时,我们已经创建了一组广泛的距离特征,如到中心顶点、到原点和先前条目的距离。进一步的分析让我们明白,并不是我们数据中的所有旅行者都有一个干净利落的旅程。通过我们的火车和测试设备,许多人开始从与他们最后一站不同的地方出发。这是后来的一个重要特征,我们称这些间隙为盲区

Blind Distance drawn — the 4th entry here is disconnected from the 3rd exit

然而,直到用哈弗辛公式而不是欧几里得公式计算,这个特征才显得如此重要。看到每个公式的表现如此不同,我们决定计算每个距离特征 三次——以欧几里德、曼哈顿和哈弗森的形式。

这三者之间有明显的相关性,但它们中的每一个都在我们的最终模型中扮演着特定的角色。我们的策略旨在通过组合距离公式以及对所有特征执行(minmaxstd、…)聚合,最大化可识别模式的数量。通过这种方式,我们还利用了梯度增强算法(如 LightGBM)的鲁棒性,用于大量可能高度相关的特征。

没有任何距离分析可以单独提供一个关于时空问题的完整观点。清楚地理解时间的作用是至关重要的,我们通过将 EDA 的最大见解与一天中的时间段、不同数量的增量以及小时和分钟的连续表示等特征联系起来来寻求时间的作用。

A continuous representation of time (15h30 = 15.5) and time delta w.r.t origin

现在进一步分析单一路线,应用几何学的中心方面对我们的分类无疑是重要的,特别是分析角度特征。对任何过去轨迹的方向有一个数字尺度,最终将我们与一个主要平台区分开。

Trajectory direction & angles to city center’s a) midpoint, b) vertexes.

总结我们的特征工程范围,在比赛的后半段,我们的模型中需要某种内存管理——旅程中的前几个点可以帮助揭示连续性模式。一种模式在这里变得更加清晰,那就是人们住在市中心,但在远离市中心的地方工作,最后还是回家。回忆他们过去的一些旅行肯定会有所帮助。由于 LSTMs 的性能不如 LightGBM,我们继续将数据集转换成序列。

Sequence format for the T4 row of ID #1

像这样,每一行都记录了一个人以前的轨迹。为了避免过度拟合,我们对不同的窗口大小进行了基准测试,以限制在一个序列中保留多少轨迹——达到最终提交的最佳window = 6值。

从系统性错误中学习

在比赛进行到一半时,我们已经达到了一个主要的平台期,一个多星期以来我们所做的任何尝试都没有超过它(这在一个长达一个月的比赛中是很多的)。

进化停滞让我们采取了一种更成熟的方法,并开始通过执行残差分析从我们模型的错误中不断学习。

简而言之,这是一个跟踪和分析两个相反样本的过程:正确预测的数据点和错误的数据点。我们在这里的目标是以每一种合理的方式面对这些组之间的区别,识别我们的错误中最大的模式,并制定任何优化来最小化它们。

多层的解释让我们得出结论,我们的模型对大多数轨迹都是正确的,这些轨迹要么在亚特兰大中心之内,要么在中心之外。最常出错的是那些进出亚特兰大的

Shortest-distance wrong predictions (left) vs correct (right). Purple rectangles are Atlanta’s center area.

人们可以清楚地看到上面的空间稀疏性差异,以及错误预测的数据(左)与城市中心的相互作用有多强。在意识到这是我们预测中的主要失败后,我们开始创建一组重要的特征:

Prominent features born from Residual Analysis

高原被克服了。如果我们没有停止漫无目的地尝试改进,或者没有真正评估我们的弱点,我们可能仍然在与绩效停滞作斗争。

超越给定的数据

通常,竞赛通过尽你所能从给定的数据集中榨取分数来让你茁壮成长。Victor 和我反对将 T5 作为主要实践 T6,因为它不能反映现实项目中发生的事情。

现实生活中很少——如果有的话——会给你一个完美的数据集来支持你刚刚想出的很酷的新项目。你通常需要研究、搜集、收集和清理你想要使用的数据。这给你带来了一层通常的竞赛所没有的困难。

然而在这里,他们的指导方针鼓励使用外部数据。我们认为这是一个完全测试我们在数据科学方面的弹性的机会,所以我们立即抓住了这个机会。

Traffic data from Georgia’s federally required traffic monitoring program

搜索并真正找到有用的数据并不容易——在竞争泡沫之外,有一个充满论文和研究的世界,它们使用与你的意图不同的数据,或者不公开发布你想要的数据。在几次阅读中,我们发现了佐治亚州的交通相关研究,它为我们的特征空间中最重要的组之一做出了贡献。

验证和培训策略

另一个让这次比赛感觉像一个真实项目的有趣之处是,组织者没有给我们一个可以用来直接预测我们的目标变量的标签。也就是说,由我们决定选择监督(分类、回归)还是非监督学习。

第一个显而易见的选择是应用线性回归预测 x 和 y 的位置,然后推断它是否在市中心内结束。然而,在考虑使用这种策略时,我们遇到了一些警告:我们不会最小化真正的目标,预测两个不同变量的误差度量没有考虑入口点和出口点之间的距离,而是独立地计算 x 和 y。考虑到这些障碍,我们决定应用二元监督分类来促进我们的工作。

Sketch of our supervised approach.

接下来,我们需要定义我们的验证方法。根据竞赛规则,所提供数据的 30%被保留为测试集,即组织者将计算分数以确定最终排名的数据。为了创建一致的验证并且不过度适应测试集,我们将剩下的 70%的数据分成训练集和验证集来评估我们的模型结果。为了进行超参数调整,我们仅使用训练数据对k = 5使用交叉验证 K-Fold——这样我们可以避免过度拟合我们的验证集。

Validation strategies.

还有更多的吗?

是的。这篇文章主要是对我们所做的部分工作的总结,目前最完整的参考文献是我们的 GitHub repo 。获胜是我们理性的结果,但也是由此而来的算法和分数的结果,因此理解这里的深度需要进一步研究实现了什么。

替代方法

没有胜利是完美的象征。在我们看来,成为一名有意识的数据科学家意味着意识到所采取的任何策略的缺点。在这里,我们打算清楚地陈述我们的方法能够实现的最佳模型的几个好步骤。

通过提出利用距离公式组合、特征聚集和序列格式转换来最大化可识别模式,我们还最大化了我们的特征计数。LightGBM 已经优化了性能,到比赛结束时,我们将 AWS Sagemaker 设置为用于大多数训练和调优,但人们可以通过应用主成分分析(PCA)等降维策略来更好地花费时间和资源。计算时间和负载是任何迭代过程中最宝贵的资源,更不用说数据科学管道了,所以这种优化是我们首先想到的。

此外,值得注意的是,我们在 EDA 阶段使用了聚类作为指导,但我们在特征提取中没有像我们希望的那样探索它。例如,我们可以使用 DBSCAN 在数据中创建感兴趣区域(ROI) ,如下图所示。

Regions of Interest using DBSCAN.

更好的是,我们可以使用这些区域来创建不同的预测位置,并增加可能值的范围,而不是将数据建模为二元分类任务。另一个没有深入研究的方法是使用回归技术直接预测 x 和 y 位置,如下图所示。

Predicting x and y positions directly

然而,所有上述方法也有其缺点。使用聚类技术创建新要素会给数据的时间方面带来一些困难-我们不能使用邻近位置但不同时间的点来查看该点有多少个邻居(或我们可能想要提取的任何其他要素)。预测 x 和 y 位置的表现不如预期,因为我们没有尝试最小化真实到达点和预测到达点之间的距离,而是独立地预测 x 和 y,这对我们的分数产生了负面影响。当然,由于我们在功能工程上花费了大量的时间,我们没有足够的时间用科学的方法来探索替代方法。

经验教训

团队中的数据科学项目远不像大学中的小组项目。即使在 Google Colab 中,你仍然不能像在 Google Docs 中那样实时协作——也许你不应该这样做。我们试图这样做,认为如果我们在一个给定的模型中合作,事情会做得更快,但现在我们知道 Jupyter 笔记本是为了用代码讲述一个故事。让两个人同时编辑同一个故事和代码可能会产生许多混乱的结果。

我们最终一起做了一些基本的东西(EDA,特性工程…),但是在不同的笔记本上,这样我们就可以比较我们个人的,不带偏见的见解。更多的主题(残差分析、聚类…)被并行化。没有永远完美的方法,这种方法对我们有效,因为(另一个教训)我们专注于在第一时间设计我们具体的工作流程,而不是马上投入工作。

在整个比赛过程中,我们感到越来越需要比较和评估我们过去提交的作品。为此,我们甚至尝试将提交的笔记本副本存放在一个单独的文件夹中。当然,这是不可持续的,因为我们已经提交了 100 多份,到最后只保留了高分的。很少跟踪架构基准(LSTM 对梯度推进对…),这正是我们需要做得最好的,以决定我们的最终提交和堆叠策略。

具有讽刺意味的是,我们只是在比赛结束后才意识到,但想想看:我们使用了 git、 one 这个星球上最广泛的 版本控制 工具。其主要目的是启用文件历史导航。我们本可以为每个提交创建 git 标签,为了更好的组织,遵循一种命名模式,比如architecture/public score。创建标签就像做git tag -a lightgbm/882一样简单,要检查它的文件,我们只需git checkout lightgbm/882——就像处理分支一样。

组织者保留了提交分数的历史,到最后,他们显示了所有转换为私人的公开分数。但是由于我们没有跟踪每一个提交,我们无法知道给定分数中的架构/变化是什么。0.856 是 LSTM 吗?我们是否在 0.788 中移除了功能聚合?如果我们已经创建了标签,那么这篇文章现在可能已经有了完整的公共和私有分数基准,通过将标签创建的日期与 EY 模型历史中的日期进行匹配,可以很容易地收集到这些分数。

我们很高兴将这个项目作为我们在数据科学领域的第一个大型项目,因为这个竞赛优先考虑了我们的确切价值观:科学在解决问题中的作用,以及将你的解决方案与其他人交流,而不仅仅是增加分数。毕竟,复杂问题的解决是一种协作努力,超越了纯技术能力的界限。

我们如何训练一个从西非洋泾浜语到英语的翻译模型,而没有一个平行的句子

原文:https://towardsdatascience.com/how-we-trained-a-translation-model-from-west-african-pidgin-to-english-without-parallel-sentences-e54efa9f8353?source=collection_archive---------13-----------------------

"每一次交流都是翻译的奇迹."

刘宇昆

source — https://unsplash.com/photos/I_LgQ8JZFGE

TLDR: 我们训练了一个模型,它可以将句子从西非洋泾浜语(克里奥尔语)翻译成英语,反之亦然,而不会向它显示一个平行句子(洋泾浜语句子及其英语等价物)来学习。您可以跳到文章末尾的结果部分,查看我们的模型的一些示例翻译和 github 上的代码链接。

介绍

翻译是人工智能研究的一个重要领域,最重要的是交流。许多机器翻译工作都集中在流行语言上,如英语、法语、德语、汉语等。然而,关于非洲语言的工作做得很少。

西非和中非有 1000 多种语言,其中 250 多种是尼日利亚语。尽管这些语言之间存在明显的差异,但有一种语言将它们显著地统一起来——洋泾浜英语。仅在尼日利亚就有超过 7500 万人使用这种语言,然而,目前还没有关于这种语言的自然语言处理工作。

这项研究解决的问题如下:

  1. 提供洋泾浜语语料库并训练洋泾浜语词向量
  2. 洋泾浜语和英语的跨语言嵌入
  3. 从洋泾浜语到英语的无监督机器翻译

1。获取语料库和训练词向量

总的来说,我们通过搜集洋泾浜新闻网站获得了一个由 56048 个句子和 32925 个独特词汇组成的语料库。以下是语料库中的句子示例:

这是我们今年为尼日利亚创作的第一首歌,但是随着他们的发行。

二世。如果他们在校园内抓到任何有恐惧症的人,他们会说严重的种族歧视

我们使用 Glove 初始化单词向量,并在语料库上使用 CBOW 模型进行微调,该模型使用 8 负样本、 5 的窗口大小、 300 的维度以及 5 时期的 3000 的批量大小来训练。

2。培训跨语言嵌入

鉴于缺乏平行数据,我们进行了无监督翻译,这依赖于跨语言嵌入。由 1097 个单词对组成的字典被刮擦并被手动编辑用于监督对齐。方法评估在 108 对的验证集上进行。

使用 Procrustes 方法执行单词向量的对齐,在该方法中,学习正交权重矩阵以将源单词向量映射到目标单词向量(Conneau 等人,2018 年),并使用以下检索标准(Joulin 等人,2018 年)。与前者的 0.0853 和基线 0.009(从 108 对的验证集中选择正确的最近邻的概率)相比,后者的方法优于前者,实现了 0.1282 的最近邻准确度。

给定一个单词,下面是对齐后其三个英语最近邻单词及其余弦相似性的一些示例:

皮金—儿童(0.7461),婴儿(0.5493),儿童(0.5357)

总统——总统(0.9173),副总统(0.6589),总统(0.5875)

瓦哈拉——问题(0.7265),问题(0.6983),麻烦(0.6906)

3。无人监管的 NMT

为此,我们使用了带有 10 个注意力头的变压器。有 4 个编码器和 4 个解码器层,其中 3 个编码器和解码器层跨两种语言共享。

为了使解码器工作良好,其输入应该由训练它的编码器产生,或者应该来自与该编码器类似的分布。因此,我们确保编码器将源语言和目标语言的句子编码到相同的潜在空间。这确保了解码器可以翻译,而不管输入源语言。我们通过对抗训练(Lample 等人,2018a)来执行这种实施,其中我们约束编码器将两种语言映射到相同的特征空间。我们通过训练一个鉴别器来对源句子和目标句子的编码进行分类。编码器被训练来欺骗鉴别器,使得源或目标的潜在表示不可区分。

我们还确保相同的潜在空间用于语言建模和翻译,以便语言模型可以很好地转移到翻译任务。

在每个培训步骤中,我们执行以下操作:

  1. 旨在预测编码句子的语言的鉴别器训练。
  2. 对每种语言上的自动编码器训练进行去噪(这相当于训练语言模型,因为该模型学习用于重构的有用模式,并且变得对有噪声的输入句子免疫)
  3. 即时反向翻译,使得用当前翻译模型 M 翻译给定的句子,然后我们尝试在利用上述步骤 2 中训练的语言模型的同时从翻译中重建该句子。

algorithm for our PidginUNMT

因此,我们的最终目标函数是:

objective function

鉴频器损耗以并联方式最小化。

我们在 V100 上训练了 8 个时期(大约 3 天)。为了选择最佳模型,我们对一组测试的平行句子进行了评估。

结果

性能最好的模型在 2101 个句子对的测试集上实现了从洋泾浜语到英语的 7.93 和从英语到洋泾浜语的 5.18 的 BLEU 分数。

下面是我们模型做的一些翻译。

注意:[pd —洋泾浜英语,en —英语]

translations from model

从这些结果中,我们可以看到语言模型有助于执行不一定是逐字翻译,但也是语法正确的翻译,如 translation 2。

代码、经过训练的翻译模型、对齐的洋泾浜词向量和模型的更多翻译可以在项目的 Github 知识库中看到—https://github.com/keleog/PidginUNMT

结论

已经有一些关于非洲语言的有趣的 NLP 工作,但是与更流行的语言相比,它仅仅触及皮毛。据我们所知,这是第一个在西非洋泾浜上表演的 NLP 作品。我们希望这项工作能刺激对非洲语言更多无人监管的研究的探索。

致谢

  • 特别感谢我在 Instadeep 的同事们,感谢他们在整个项目过程中不断的支持和建设性的反馈。
  • 感谢 Naijalingo.com 的允许抓取他们的网站来创建一个洋泾浜英语词典。
  • 感谢 Deepquest AI 和 AI 周六的拉各斯的计算支持。
  • 测试集从 JW300 数据集[6]中获得,并由 Masakhane 组进行预处理

参考文献

1.米克尔·阿尔特塞、戈尔卡·拉巴卡和埃内科·阿吉雷。2017.在(几乎)没有双语数据的情况下学习双语单词嵌入。

2.Alexis Conneau、Guillaume Lample、Marc'Aurelio Ranzato、Ludovic Denoyer 和 Herv Jegou。2018.没有平行数据的单词翻译。在 ICLR

3.纪尧姆·兰普尔、亚历克西斯·康诺、卢多维克·德诺耶和马克·奥雷里奥·兰扎托。2018a。仅使用单语语料库的无监督机器翻译。在 ICLR。

4.纪尧姆·兰普尔、米勒·奥特、亚历克西斯·康诺、卢多维克·德诺耶和马克·奥雷利奥·兰扎托。2018 年 b。基于短语和神经的无监督机器翻译。在 EMNLP。

5.A. Joulin,P. Bojanowski,T. Mikolov,H. Jegou,E. Grave,《翻译中的损失:用检索标准学习双语单词映射》,载于 EMNLP。

6.eljko Agi,Ivan vuli:“jw 300:低资源语言的大范围平行语料库”,载于计算语言学协会第 57 届年会会议录,2019 年。

7.j . tie demann:“OPUS 中的并行数据、工具和接口”载于 2012 年第八届语言资源与评估国际会议论文集。

更新:编辑 2019 年 7 月 11 日在更多平行句子上对模型进行最终测试后得出的 BLEU 分数。

我们如何使用 NLTK 和 NLP 从歌词中预测歌曲的风格

原文:https://towardsdatascience.com/how-we-used-nltk-and-nlp-to-predict-a-songs-genre-from-its-lyrics-54e338ded537?source=collection_archive---------11-----------------------

本文的目的是概述我们使用 NLTK 和自然语言处理方法来清理和预处理文本数据并将歌词转换为数值矩阵的过程,以便我们可以训练一个机器学习算法,该算法可以根据歌词对每首歌曲的流派进行分类。

什么是自然语言处理(简称 NLP)?

NLP 指的是处理文本或语音形式的自然人类语言的分析任务。这些任务通常涉及某种机器学习,无论是文本分类还是特征生成,但 NLP 不仅仅是机器学习。诸如文本预处理和清理之类的任务也属于 NLP 范畴。

用于 NLP 任务的最常见的 python 库是自然语言工具包,或 NLTK。NLTK 是 NLP 所有事情的“一站式商店”。与大多数其他 Python 库和 ML 模型不同,NLTK 和 NLP 的独特之处在于,除了统计学和数学,它们还非常依赖语言学领域。本文其余部分描述的许多处理文本数据的概念和方法都基于语言学规则。

获取数据:我们从哪里获取数据?

我们在 Kaggle 上发现了一个包含 30 万首歌词的 CSV,这些歌词来自 11 种不同的流派和 6-7 种不同的语言。该数据集包含关于歌曲名称、艺术家、年份、专辑、流派的信息,以及一个包含完整歌词的列。

清理和预处理文本数据

现在我们有了数据,有趣的部分开始了。首先,我们需要预处理和清理我们的文本数据。正如您可能已经怀疑的那样,预处理文本数据比处理更传统的数据类型更具挑战性,因为对于我们需要做什么样的预处理和清理没有明确的答案。使用传统数据集时,我们在这一阶段的目标通常非常明确——标准化和清理数值数据、将分类数据转换为数值格式、检查并处理多重共线性等。我们采取的步骤在很大程度上取决于我们获得数据时它的样子。

文本数据不同 —在其原始格式中,文本数据仅从一维开始—在项目的初始阶段,我们对数据集中唯一感兴趣的功能是包含每首歌词全文的列。这意味着我们需要决定如何预处理我们的数据,并从文本文档中提取特征,以便稍后用于训练 ML 模型。在我们开始清理和预处理文本数据之前,我们需要做出一些决定,例如:

  • 我们要不要删除停用词?
  • 我们是对我们的文本数据进行词干化或词目化,还是让单词保持原样?
  • 基本的标记化是否足够,或者我们是否需要通过使用正则表达式来支持特殊的边缘情况?
  • 我们是坚持只使用英语单词,还是允许使用其他语言?
  • 我们是使用整个词汇表,还是仅仅将模型限制在最常用单词的子集?如果有,有多少?
  • 我们是否设计了其他特征,如二元模型、词性标签或互信息分数?
  • 我们应该在模型中使用哪种矢量化?布尔矢量化?计数矢量化?TF-IDF?Word2Vec 等更高级的矢量化策略?

这些都是我们在处理文本数据时需要考虑的问题。

探索数据:查看我们的熊猫数据帧,我们发现…

我们做的第一件事是检查无价值的歌曲,并删除带有 NaN 歌词的歌曲,在清理后,我们仍然有 200,000 行。

然后,我们查看了流派的价值计数,决定放弃民谣、独立音乐和其他音乐,因为前两者没有足够的数据,“其他”不能为我们的最终分类任务提供任何预测价值。

在所有这些清理之后,我们只剩下八种基本风格:摇滚、流行、嘻哈、金属、乡村、爵士、电子、R & B 。这些是我们将试图预测的目标类别。

流派之间的分布是不均匀的,所以我们决定随机选择每个流派 900 首歌曲,这样我们的总行数 900 首歌曲 8 个流派= 7200 首歌曲*。

特征工程和模型优化:

  1. 我们结合使用 NLTK、Pandas 和 Regex 方法来:
  • 清除文本中的标点符号和奇数字符
  • 删除停用词
  • 仅标记英语单词
  • 返回词干语料库
  • 返回词条化单词的语料库
  • 将最终的干净歌词附加回熊猫数据帧

2.我们使用 TF-IDF 矢量器将单词转化为每个单词对特定歌词的重要性的数字表示。

什么是 TF-IDF?

TF-IDF 代表词频-逆文档频率,TF-IDF 权重是信息检索和文本挖掘中经常使用的一种权重。该权重是一种统计度量,用于评估一个单词对集合或语料库中的文档有多重要。重要性与单词在文档中出现的次数成比例增加,但是被单词在语料库中的频率抵消。

TF-IDF 是如何计算的?

通常,TF-IDF 权重由两项组成:第一项计算归一化项频率(TF),aka。单词在文档中出现的次数,除以该文档中的总单词数;第二项是逆文档频率(IDF ),计算为语料库中文档数量的对数除以特定术语出现的文档数量。

  1. TF:术语频率衡量一个术语在文档中出现的频率。因为每个文档的长度不同,所以一个术语在长文档中出现的次数可能比短文档多得多。因此,术语频率通常除以文档长度(又名。文档中的术语总数)作为标准化的一种方式:

TF =(术语 t 在文档中出现的次数)/(文档中的总术语数)。

2。IDF:逆文档频率,它衡量与所有其他文档相比,一个术语对于语料库中特定文档的意义/内容有多重要。众所周知,某些术语,如“is”、“of”和“that”,可能会在大多数文档中非常频繁地出现,但这并没有给我们任何关于这些常用词对特定文档含义的重要性的信息。因此,我们需要通过计算以下各项来降低过于频繁的术语的权重,同时增加仅特定于少量文档的罕见术语的权重:

  • IDF = log_e(文档总数/其中包含术语 t 的文档数)。

在对所有歌词进行词干化和词汇化并创建特征 TF-IDF 矩阵后,我们发现自己拥有了一个最终的熊猫数据帧,该数据帧有7200 行30,000 。每一行代表一个特定的歌词,每一列是一个唯一的单词及其对应的 TF-IDF 值。

培训和优化我们的模型

我们想做的第一件事是测试我们的基本 ML 模型在处理词干化或词条化文本时是否表现得更好。我们训练和评估了多项式朴素贝叶斯、随机森林、AdaBoost、梯度增强和 K-最近邻的性能,使用词干和词条。下表显示了我们的结果:

我们选择使用词汇化的单词而不是词干化的单词,因为当使用词汇化的文本时,每个模型的性能始终至少提高 1%。

从这里开始,我们选择关注我们的前三个模型- 多项式朴素贝叶斯、梯度推进和随机森林的模型优化。

我们做的下一件事是 PCA ,我们对我们的数据进行了一次测试,看看有多少组件可以保留 80%的变化。然后,我们在我们的前三个模型上运行 n_components = 1800 的 PCA,看看这是否提高了性能。下图显示了结果:

从图中可以看出,PCA 在两种模型中都没有提高性能,所以我们决定不继续使用 PCA。

接下来我们要做的事情是 GridSearch 三个表现最好的模型,并选择具有产生最高准确度分数的参数组合的模型。结果汇总如下:

  • 随机森林上的网格搜索****准确率从 41%提高到 43%。
  • 网格搜索 上的梯度提升将性能精度从 45%提高到 50%。
  • **朴素贝叶斯网格搜索**上的网格搜索 没有产生改进的性能,因为默认参数是最优的。

解释和传达最终结果:

下面你可以看到我们的前三个模型在使用 GridSearch 优化和超参数调整后的最终性能图。

网格搜索后,我们的最高模型 GradientBoost 产生了 50%的准确性,这比随机猜测(从 8 个可能的类别中随机猜测一个类别= 1/8 或 12.5%)好了大约 4 倍。尽管 50%并不是一个很大的数字,但我们仍然对只有 7200 首歌词的情况印象深刻,我们能够训练一个模型,通过只扫描这首歌的歌词,就可以在 50%的时间内正确猜测这首歌属于什么类型。

通过对网格搜索和 PCA 优化的实验,我们发现多项式朴素贝叶斯是最快和最简单的开箱即用模型。在没有任何额外优化技术的情况下,它的准确率仅比顶级模型 GradientBoosted 分类器低 5%。

结论:

根据我们有趣的实验,似乎有一组特定于每种歌曲类型的词汇,可以允许人们训练一种 ML 算法,该算法可以仅通过分析歌词来猜测歌曲的类型。另一个有趣的发现是,NaiveBayes 分类器似乎可以立即生成非常强大的性能。因此,如果您正在处理一个非常大的文本数据集,其中的特征生成和模型优化被证明是计算量大且耗时的,那么您可能会选择使用朴素贝叶斯来简化和提高效率,而不会牺牲太多的性能。如果您有足够的时间和计算能力,并且希望尽可能地优化性能,那么在一系列集成模型(如随机 Fores 或 GradientBoosted 分类器)上运行网格搜索将是一个不错的选择。

有趣的附加功能: 使用无监督学习模型来识别每个流派的独特主题和关键词

我们使用 gensim.corpora.Dictionary 为词汇化、标记化的单词集创建了一个频率词典。我们从每个流派中抓取关键词,并生成主题模型分数。使用 Word2Vec 字典生成器,我们运行了一个主题建模 LDA 算法,并打印了下面每个流派中热门关键词的词云。

****

可穿戴设备和生物传感器如何利用机器学习帮助研究人员抗击克罗恩病

原文:https://towardsdatascience.com/how-wearables-biosensors-can-help-researchers-fight-crohns-disease-using-machine-learning-1517090f0a35?source=collection_archive---------37-----------------------

Photo by Luke Chesser on Unsplash

男朋友 20 岁的时候发现自己得了克罗恩病。就像我们中的许多人一样,他控制着疼痛,直到他无法再忽视它,并在几周内避免去看医生。在遇到他之前,我从未听说过克罗恩病,但现在,我遇到的每个人似乎都认识被诊断出患有克罗恩病的人。

克罗恩病是一种自身免疫性疾病,过去被认为是“罕见的”。这是一种第一世界的疾病,也就是说,这种疾病主要出现在发达国家。研究人员还没有找到这种疾病的确切原因,但这种疾病主要发生在发达国家的事实使他们相信一些环境因素可能会引发这种疾病。尽管控制这种疾病的治疗方法在不断改进,但目前还没有治愈 CD 的方法。缓解是可能的,但克罗恩病的结果和症状因患者而异。我很高兴地说,现在,我的男朋友是“幸运”的一部分。

数据科学能为克罗恩病做些什么?

一方面,数据科学可以帮助回答这个大问题,因为它可以帮助找到模式,病例之间的相似之处,以便找出这种疾病几乎神秘的原因。机器学习模型可以发现饮食习惯之间的模式,也可以发现患者基因中的模式。人工智能已经帮助识别与疾病相关的未发现基因,并准确预测哪些患者受到 CD 的影响。

另一方面,机器学习模型也可以预测某人对某种药物反应良好的机会。最近,今年 6 月发表的一项研究表明,ML 模型可以准确地估计哪些患者可能对药物治疗有良好的反应,然后他们才会接受长期治疗,并且无需昂贵的药物水平测量。在预测用于治疗克罗恩病的硫嘌呤药物的临床反应时,随机森林模型甚至被证明比普通技术更准确、更便宜。

我们怎么还不知道是什么导致了这种疾病?

美国国家医学图书馆将克罗恩病的原因描述为复杂且不为人知的 T2。作为一名数据科学家,我很震惊地得知,虽然我们在世界范围内有如此多的病人,我们仍然不知道为什么这种疾病首先会发生。我想知道为什么没有一个机构在疾病被宣布之前收集了足够的关于病人生活的数据,以便找出大多数病人共有的一个或多个环境因素。我的男朋友本人在确诊前从未被采访过他的习惯,也没有被采访过他的饮食。

缺乏准确的数据

通过更深入地研究这个问题,我明白了获得关于病人的准确数据可能是一项相当困难的任务。食物日志或关于过去习惯的记忆可能会提供非常不准确的事实,因为人们会有意或无意地误报自己的行为。如果你知道医生会查看数据,并且你前一天已经喝了 2 杯,你会写下你喝了 3 杯酒吗?如果第三个杯子非常小,它可能会被算作 2,而不是 3。多少钱才算“一杯”?你也可能忘记在前一天的食物日志中写下你的食物量,现在记不起确切的量了,所以你写下了近似值。研究人员期望客观的测量,但是当涉及到人的判断时,测量可能变成非常主观的事情。

世界最大数据库能为机器学习带来希望

试图用机器学习解决各种问题的研究人员经常遇到同样的问题:缺乏可靠和准确的数据。关于人们在被诊断前几年的饮食或生活习惯的数据要么不存在,要么可能非常不准确。你还记得 5 年前你在做什么或吃什么吗?即使是两个月前?大概不会。

为了解决这一问题,CCFA ( 克罗恩病&结肠炎基金会)在 2015 年获得了一笔赠款,用于建立可能是克罗恩病和溃疡性结肠炎 的 最大的研究数据库,目标是“集中和汇总多个研究项目的患者信息”。该中心选择了几个方面的研究重点,包括 环境触发 和新技术。关于触发因素,基金会目前正在支持研究以下因素:饮食、心理、压力、病毒和吸烟

[## 环境触发因素

环境触发因素是五个重点领域的一部分,包括临床前人类 IBD 机制,新技术…

www.crohnscolitisfoundation.org](https://www.crohnscolitisfoundation.org/research/challenges-ibd/environmental-triggers)

用于更精确测量的生物传感器和可穿戴设备

Biosensors recently designed by the EPFL

如上所述,新技术是基金会目前支持的 5 个重点之一。为了收集更精确的测量数据,研究人员提议为患者使用生物传感器和可穿戴设备。这种类型的工具允许比人工日志更准确的数据,因为患者不必参与报告。它还允许在没有护士或医生参与的情况下进行测量。然后可以将测量结果结合起来,以获得一个长期的可靠的患者状况图,而不是在医院就诊的当天。

此外,CCFA 目前正在开发一种 可摄取电子设备 ,可以连接智能手机进行(近)实时数据采样。该设备可以检测肠道何时出现炎症,并直接报告给智能手机,以通知患者或医务人员。最终,该技术的一个版本可以被开发出来,通过传递抗炎信号来检测甚至相应地对炎症做出反应。

[## 新技术

新技术是五个重点领域的一部分,包括临床前人类 IBD 机制,环境触发…

www.crohnscolitisfoundation.org](https://www.crohnscolitisfoundation.org/research/challenges-ibd/novel-technologies)

具有机器学习的个性化医疗

个性化(或精确)医学是一种疾病管理形式,它使用关于一个人的基因、蛋白质和环境的信息来预防、诊断和治疗疾病。——NCI 癌症术语词典

根据南安普顿大学和南安普顿儿童医院的几位研究人员的说法,机器学习是炎性肠病(如克罗恩病)诊断和治疗个性化药物开发的关键因素,它根据患者的特征将患者分为不同的风险类别,允许提供适合的营养、药物和管理。

虽然监督和非监督模型都用于患者的分层,但随机森林分类器和支持向量机在使用多组学数据模拟生物现象时非常流行,因为这两种算法都易于解释,并且在计算要求上非常相似。

研究人员预计,在未来几十年里,个性化治疗将会发生重大转变。这种转变可以通过使用生物传感器等新技术来实现,但特别依赖于可理解和可访问的 ML 模型的可用性。

网络爬行如何有益于数据科学

原文:https://towardsdatascience.com/how-web-crawling-benefit-data-science-a6ff0bd4cd1?source=collection_archive---------20-----------------------

用 3 个真实场景解释

你可能想知道,数据科学中是否需要网络爬行?

当我是数据科学家的时候,数据的标注部分就不是我的事了,那我为什么还要费心去学网页抓取来检索数据呢?

想到这个问题是很正常的,因为对于那些想成为数据科学家的人来说,网络爬行并不是必须的。不过,有这个技能绝对是加分项。当我在大学学习的时候,我不认为拥有这种技能是有益的。我认为网络抓取只是一个自动化工具。

然而,在工作了几年后,我开始注意到在信息爆炸的时代,对这项技能的需求越来越大。你在网站上看到的每一条信息都很容易被抓取。

话不多说,我想分享一些我在就业市场观察到的真实使用案例。您将看到 web 爬行如何直接受益于数据科学。

场景 1

让我们想象一下,你目前正在网购。你的目标是买一部新的 iPhone 来奖励自己完成了一个大项目。所以,你去 taobao.com 搜索 iPhone。

清单可能会到处都是。您正在滚动查找您想要购买的型号。然而,你观察到的是 iPhone 11 Pro 和 iPhone 11 的最新型号,你更愿意看看是否有其他型号在平台上销售。

然后,您决定搜索一个更通用的词:如图所示的 iPhone。你注意到下面有推荐的 iPhone 型号,你不仅可以点击查看所有型号的列表,还可以查看淘宝上提供的一些型号。

淘宝到底是怎么做的?

有许多方法可以做到这一点,但我将只分享如何实现使用网页抓取。其中一种方法是抓取的网站,其中有所有的型号名称的特定清单。然后,训练一个模型将列表分类到抓取的模型名称。

嘣!这就是网络抓取如何帮助你免费获得你需要的数据。也许你只需要对你搜集的数据进行一些简单的清理,你将能够拥有一个干净的数据集来开始训练机器学习模型。

场景 2

另一方面,假设你要去一家人工智能公司参加数据科学工作面试。你工作的公司是一家提供多种实时 API 服务的公司,但是这里让我们假设只有一种服务。

这个特定的服务被赋予一个 web URL,API 应该返回该网站是否是合法网站。换句话说,这意味着该公司实际上是在进行合法的商业运作。

可能存在两种情况。该公司要么将网页抓取部分分包给其他公司去做,要么雇佣其他人来做这项工作。假设这家公司把这个项目转包给另一家公司。同时,你知道如何刮网站。你认为公司雇用你的机会大吗?答案显然是肯定的,但还是要看你面试的表现。

所以,如果你想有机会进入数据科学领域,不要认为网络搜集是无用的。

抓住生活中的每一个机会。因为有些事情只会发生一次。—凯伦·吉布斯

场景 3

你刚从大学毕业,得到了一家金融科技公司的数据科学工作机会。你正在做的主要项目是信用评分。让我们假设公司只有一些基本数据,例如出生日期、性别等。然而,它没有相对更重要的数据,比如这个人挣多少工资,这个人有没有贷款等等。

也许你的公司足够大,你可以通过网站或应用程序挖掘重要的功能。如果你现在工作的公司是小公司怎么办?

你将努力提高机器学习模型的性能。你已经包括了公司的所有数据,但仍然不能提高业绩。

你能做什么?

如果你知道如何抓取 facebook 网站,你将能够获得更多的功能。如果这些特征中的一个看起来是你正在寻找的宝石呢?

有了更多的数据,你就有更多的机会找到你需要的突破口。更多的时候,你会发现,获取模型的正确数据,更容易找到突破口。

最后的想法

这不是给你洗脑学习网页抓取的文章。然而,我想从我的所见所闻中指出。这三个场景实际上是 web 爬行如何影响数据科学领域的真实例子。信不信由你,这项技能值得学习,它将有利于你的职业生涯。

学习的能力是一种天赋;

学习的能力是一种技能;

愿意学习是一种选择。—布莱恩·赫伯特

我真的很感激你读到最后。希望你喜欢这篇文章,并发现它是有益的。如果你有任何想让我讨论的话题,请在下面评论!

关于作者

低伟鸿是 Shopee 的数据科学家。他的经验更多地涉及抓取网站,创建数据管道,以及实施机器学习模型来解决业务问题。

他提供爬行服务,可以为你提供你需要的准确和干净的数据。你可以访问这个网站来查看他的作品集,也可以联系他获取抓取服务

你可以在 LinkedIn 和 Medium 上和他联系。

基于价值的回归模型在 2016 年总统选举中表现如何?

原文:https://towardsdatascience.com/how-well-does-a-value-based-regression-model-perform-in-the-2016-presidential-election-251ea7d10674?source=collection_archive---------38-----------------------

使用多元回归调查唐纳德·特朗普选民在 2016 年大选中的价值观预测

A D3.js map comparing the actual 2016 election results to the model predictions. Visit www.zach-alexander.com/pres2016-regression to interact with the full visualization.

可能很难相信,但 2020 年总统大选大约还有 300 天。今年将是政治上又一个充满争议的一年,预测称,将会有空前数量的选民出来投票给那些无疑对我们国家的未来有着截然不同的议程的被提名者。

随着民主党寻求在未来一年赢得前特朗普选民的支持,我认为回顾 2016 年的选举结果以确定导致他成功的因素将是有趣的。在我的分析中,很明显,某些价值观和意识形态可以预测全州范围内投票给唐纳德·特朗普的选民比例。

通过使用线性回归,我创建了一个模型,捕捉到了唐纳德·特朗普投票比例中近 87%的可变性。

现在,对于那些更懂统计学的人来说,这一模型在预测 2020 年大选(甚至是 2016 年大选)的结果方面绝不有效,但它确实告诉了我们一些关于选民对某些“热点”问题的感受的有价值的东西,以及它们对他们决定是否投票给特朗普总统的影响。

用于此分析的数据集

2016 年的选举结果最终是从 Townhall.com的那里获得的,在此之前,他们清理了 html 格式的表格并做了一些整理。如果有兴趣,你可以在 GitHub 上阅读更多关于这个的内容。网络抓取的功劳归于托尼·麦戈文。

我处理的第二个数据集包含对 2017 年美国价值观调查的回答。这个数据集是在公共宗教研究所(PRRI)) 网站上找到的。它包含大量与价值观相关的问题,从受访者对移民、枪支管制法律、医疗保健等的看法。

调查的主要版本可以在这里找到,关于调查方法的更多信息可以在这里找到。

用 R 建立回归模型

由于时间关系,我不会详细介绍我所做的数据整理工作。如果你对这个过程的这个方面感兴趣,你可以在我的 Rpubs 出版物上读到更多。

需要注意的是,我需要以某种方式整理数据,将两个数据集连接在一起。幸运的是,美国价值观调查数据有一个变量可以捕捉每个受访者的居住州——我最终用它来联系 2016 年的选举结果。

有了可供分析的数据,我决定先看看 2016 年实际选举结果的一些地图,以及对美国价值观调查问题的平均评分。

使用 ggplot 和 R,我创建了一个快速地图,显示了特朗普在每个州的选民比例:

正如我们所见,中西部和南部的大部分地区在很大程度上支持选举唐纳德·特朗普为总统。请记住,这只是唐纳德·特朗普的得票率,不包括选举团。此外,我想看看各州对美国价值观调查问题的平均回答是否有所不同。一些值得注意的差异是:

正如我们从上面所看到的,在从气候变化到伊朗核协议等问题上存在很大的分歧。要查看美国价值观调查中许多其他问题的分类,你可以参考我的 RPubs 出版物这里。

最后,这些回答中的许多有助于多元线性回归模型的创建。在多次调整模型,并使用诸如反向消除、绘制残差和检查诊断等技术后,最可靠的模型得出的 R 值为 0.87。还不错!

模型中具有高度预测性的问题

你是强烈赞成、赞成、反对还是强烈反对…

  • 允许同性恋合法结婚?
  • 允许你所在州的小企业主拒绝向同性恋者提供产品或服务,如果这样做违反了他们的宗教信仰?
  • 沿着美国和墨西哥的边界建一堵墙?
  • 允许童年时被带到美国的非法移民在参军或上大学后获得合法居民身份?

您完全同意、基本同意、基本不同意还是完全不同意……

  • 今天的美国为世界树立了一个良好的道德榜样?
  • 体育赛事奏国歌时应该要求职业运动员起立?

你认为以下应该是最高优先级,高但不是最高优先级,还是较低优先级?…

  • 颁布更严格的枪支管制法律。
  • 降低医疗保健成本。
  • 改变联邦所得税制度,使其更加公平。

外卖

从统计学的角度来看,最终结果是一个相当强的模型,其 R 平方值高于 0.85。然而,这是一个真实世界的边际比数学世界的边际精细得多的主要例子。我们的模型的残差有时接近 0.10,这意味着特朗普在几个州(即马里兰州、俄克拉荷马州和加利福尼亚州——所有这些州最终都被从最终的模型计算中删除)将获得 10%的选票。

然而,在完成这一过程的同时,我能够检验似乎相当有助于唐纳德·特朗普投票的价值观。例如,有趣的是,对枪支管制、医疗保健、税收制度、移民以及在南部与墨西哥边境修建隔离墙等问题的回答都进入了模型。这些话题一直是特朗普竞选和执政期间的最重要话题。这表明最近的问题,以及由唐纳德·川普这样一个两极分化的人物制造的问题,对是否有人会投票给他有很大的影响。

2016 年的选举被证明是一场非常两极分化的选举,人们有时声称他们会投票反对某个特定的候选人,而不是投票支持某个候选人。构成最终模型的一长串价值观证明了这一点,因为选民有足够的机会表达为什么他们认为他们的候选人是领导美国的正确选择。

请参见 D3.js 地图可视化

要查看我创建的显示 2016 年大选特朗普选民实际比例与模型预测之间差异的地图可视化,可以访问我的网站。

这一分析的功劳与我在数据科学领域的同事 Misha Kollontai 分享。

如何通过学习数据结构和算法来改变世界

原文:https://towardsdatascience.com/how-you-can-change-the-world-by-learning-data-structures-and-algorithms-84566c1829e3?source=collection_archive---------19-----------------------

作为开发者,你有改变世界的力量!你可以编写支持新技术的程序。例如,开发软件来发现疾病的早期诊断。但是,这不是唯一的方法,你可以通过创建项目间接做到这一点,让人们更有效率,并帮助他们腾出时间做其他令人惊叹的事情。无论你做什么,它都有可能影响使用它的社区。

然而,这些成就只有在我们编写快速且可伸缩的软件时才有可能实现。学习如何测量你的代码性能是这篇文章的目标。

我们将探索如何使用算法分析来测量代码性能:时间复杂度大 O 符号

首先,让我们看一个真实的故事来了解为什么这很重要。

拯救了数百万人生命的算法

在第二次世界大战期间,德国人使用调幅无线电信号与欧洲各地的军队通信。任何一个有 AM 频率无线电和一些莫尔斯电码知识的人都可以截获这个信息。然而,信息被编码了!所有被攻击的国家都试图破译它。有时,他们很幸运,能够在一天结束时理解一些信息。不幸的是,纳粹每天都在改变编码!

一位名叫艾伦·图灵的杰出数学家加入了英国军队,破解了德国的“谜”密码。他知道如果他们继续用笔和纸来计算,他们将永远不会成功。所以经过几个月的努力,他们造出了一台机器。不幸的是,这个设备的第一个版本需要很长时间来解码一条信息!所以,它不是很有用。

艾伦的团队发现每条加密信息都以同样的字符串结尾:“希特勒万岁”啊哈!改变算法后,机器解码传输的速度快了很多!他们用这些信息来更快地结束战争,拯救数百万人的生命!

同一台即将因故障而关闭的机器变成了一个活的拯救者。同样,当你编写高效的代码时,你可以用你的计算资源做更多的事情。这就是我们在这个帖子系列中要学习的内容!

另一个流行的算法是谢尔盖·布林和拉里·佩奇(谷歌创始人)在 1998 年开发的PageRank。这种算法曾经(现在也是)被谷歌搜索引擎用来理解数万亿的网页。谷歌不是唯一的搜索引擎。然而,由于他们的算法返回了更好的结果,大多数竞争者逐渐消失了。今天,它为每天 30 亿次搜索中的大部分提供了快速的动力。这就是可扩展算法的力量!🏋🏻‍

那么,为什么要学习写高效的算法呢?

优点很多;这些只是其中的一部分:

  • 你会成为一名更好的软件开发人员(并获得更好的工作/收入)。
  • 花更少的时间调试、优化和重写代码。
  • 您的软件将在相同的硬件上运行得更快(扩展成本更低)。
  • 你的程序可能被用来帮助拯救生命的发现(也许?).

事不宜迟,让我们加紧我们的游戏!

什么是算法?

算法(你可能知道)是如何完成某项任务的步骤。例如,当你做饭时,你按照一个食谱来准备一道菜。如果你玩游戏,你正在设计策略来帮助你获胜。同样,计算机中的算法是用来解决问题的一组指令。

算法是执行任务的指令

有“好”和“坏”的算法。好的很快;坏的很慢。缓慢的算法花费更多的钱,并使一些计算在我们的生命周期内不可能!

我们将探索算法的基本概念。此外,我们将学习如何区分“快”和“慢”。更好的是,您将能够“测量”您的算法的性能并改进它们!

如何提高自己的编码技能?

改善某事的第一步是衡量它。

测量是控制并最终改进的第一步。如果你不能衡量一件事,你就不能理解它。如果你不能理解它,你就不能控制它。如果你不能控制它,你就不能改善它。

H. J .哈灵顿

你如何“测量”你的代码?你会计算跑步需要“多长时间”吗?如果你在移动设备或者量子计算机上运行同样的程序呢?同样的代码会给你不同的结果吧?

要回答这些问题,我们需要先确定一些概念,比如时间复杂度

时间复杂度

时间复杂度(或运行时间)是算法运行所需的估计时间。然而,你不用秒来度量时间复杂度,而是作为输入的函数。(我知道这很奇怪,但请原谅我)。

时间复杂度 不是关于计时算法需要多长时间。而是执行多少个操作。一个程序执行的指令数量受输入大小和元素排列方式的影响。**

为什么时间复杂度被表示为输入的函数?好吧,假设你想对一组数字进行排序。如果元素已经排序,程序将执行较少的操作。相反,如果项目顺序相反,将需要更多的时间来排序。因此,程序执行的时间与输入大小和元素的排列方式直接相关。

我们可以说对于每一个算法都有如下的运行时间:

  • 最坏情况下的时间复杂度(例如,输入元素顺序相反)
  • 最佳情况时间复杂度(例如,已经排序)
  • 平均情况时间复杂度(例如,随机顺序的元素)

我们通常更关心最坏情况下的时间复杂度(我们抱着最好的希望,但也在为最坏的情况做准备)。

计算时间复杂度

这里有一个如何计算时间复杂度的代码示例:在一个数组中找到最小的数

我们可以将getMin表示为输入n大小的函数,基于它必须执行的操作数量。为了简单起见,让我们假设每行代码在 CPU 中花费相同的时间来执行。让我们算一下总数:

  • 线 6: 1 操作
  • 线 7: 1 操作
  • 第 9–13 行:这是一个执行大小为n倍的循环
  • —10 号线:1 操作
  • —第 11 行:这个比较棘手。它在一个条件中。我们将假设最坏的情况,即数组按升序排序。每次都会执行条件(if块)。因此,1 次操作
  • 第 14 行:1 操作

总而言之,我们在循环外有3操作,在forEach块内有2操作。因为循环的大小是n,所以我们只有2(n) + 3

但是,这个表达式有些过于具体,很难用它来比较算法。我们将应用渐近分析来进一步简化这个表达式。

渐近分析

渐近分析只是评估函数,因为它们的值接近无穷大。在我们之前的例子2(n) + 3中,我们可以将其概括为k(n) + c。随着n值的增长,值c越来越不重要,如下表所示:

Input size vs Number of Operation

信不信由你,常量k也不会有太大的区别。使用这种渐近分析,我们采用高阶元素,在这种情况下:n

让我们再做一个例子,这样我们就可以得到这个概念。假设我们有下面的函数:3 n + 2n + 20。使用渐近分析的结果会是什么?

3 n + 2n + 20 随着` n '越长越大;最重要的术语是“n”。

回到我们的例子getMin,我们可以说这个函数的时间复杂度为n。正如你所看到的,我们可以把它近似为2(n),去掉+3,因为随着‘n’不断变大,它不会增加太多的价值。

我们感兴趣的是这里的大图,我们将使用渐近分析来帮助我们。有了这个框架,对比算法,就舒服多了。我们可以用它们最重要的术语来比较运行时间:n 或 n 或2^n.

函数的 Big-O 符号和增长率

大 O 符号结合了我们在上两节学到的关于最坏情况时间复杂度渐近分析的内容。

字母‘o’指的是某个功能的 顺序

大 O 符号用于根据算法的最差运行时间对算法进行分类,也称为函数增长率的上限。

在我们之前使用getMin函数的例子中,我们可以说它的运行时间为O(n)。有许多不同的运行时间。以下是我们将在下一篇文章中讨论的最常见的问题,以及它们与时间的关系:

Input size (n) vs Time Taken by Growth Rate

如你所见,有些算法非常耗时。一个小至 100 的输入大小,即使我们有一个 1 PHz(100 万 GHz)的 CPU 也无法计算!!硬件的可扩展性不如软件。

在下一篇文章中,我们将通过一两个代码示例来探究所有这些时间复杂性!你准备好成为一名超级程序员并扩展你的代码了吗?!

其他资源:

  • 使用 JS-Github 解释的数据结构和算法
  • 算法教程——帖子

原载于 2019 年 4 月 5 日https://adrianmejia.com

如何获得体育分析工作

原文:https://towardsdatascience.com/how-you-can-land-a-sports-analytics-job-4ef13ba97995?source=collection_archive---------11-----------------------

体育分析

我打入体育行业的最佳建议

体育分析是一个迷人但神秘的领域。在面向球迷的方面(每日幻想&体育赌博)有巨大的分析机会,但在 NBA、NFL 和 MLB 特许经营权背后发生的事情可能是一个完全的谜。对于想进入这个领域的人来说,这可能是一个非常令人困惑的起点。

在过去的 4 年里,我一直从事体育分析(高尔夫和篮球)工作,以下是我对如何进入该领域的建议:

Photo by Daniel McCullough on Unsplash

大量阅读——互联网上有大量的体育分析内容。我建议尽可能多的熟悉它。我还推荐探索以下这本书: 数学 韦恩·温斯顿著。这是理解三大运动中的分析的一个很好的起点。它可能有点过时,但是你应该能够在完成这本书后自学和扩展分析。以下是我最喜欢的几个在线学习体育分析的地方:

  • https://www.playingnumbers.com/(我的网站)
  • https://fivethirtyeight.com/
  • http://www.sloansportsconference.com/blog/
  • http://harvardsportsanalysis.org/
  • http://statsheetstuffer.com/
  • https://fansided.com/author/nyloncalculus/
  • https://cleaningtheglass.com/
  • https://backpicks.com/

学习必要的技能和工具 —编码语言和可视化工具在分析中越来越重要。Excel 模型将很快成为过去的遗留物。如果你想进入这个领域,你需要学习使用 Python 或 r。使用这些工具,你可以处理比传统电子表格多得多的信息。您还应该探索像 Power BI 和 Tableau 这样的可视化工具。如果你不能解释,洞察力是没有意义的。比起文字,人们更容易理解图表和图片,所以尽你所能通过视觉来解释你的发现。

与专业运动队合作 —运动队总是在寻找新的方法来寻找高质量的候选人。有很多机会遇到合适的人,在会议上展示你的东西(麻省理工斯隆、 SABR )。这些节目通常也向学生提供免费或打折的价格。黑客马拉松在体育界也越来越受欢迎。NBA每年举办一次,NFL已经开始在 kaggle.com 举办。这些都是获得独一无二的体育数据和让你的工作得到认可的好方法。我合作过的许多团队都是直接从这些竞赛中招聘的。如果你真的赢得了其中的一个,你就能得到一份工作。

与你的大学运动队合作——如果你是学生,我会建议你想办法与你所在学校的运动队合作。即使这个角色与数字无关,团队也重视那些熟悉高水平运动队运作的人。从事体育工作有点像兄弟会,进入这个领域非常重要。如果你能设法使用分析来帮助你的大学团队,这将是你帽子上的一根额外的羽毛。

做项目——我相信这是你能做的最重要的事情。项目不仅能帮助你熟悉工具和分析技术,还能为你的简历增色不少。如果你能用你已经完成的项目为团队创造价值,他们会更愿意雇佣你。如果他们雇佣了你,他们可以看到你以前的工作/发现以及你发现的任何新发现。

制作内容 —我可能是少数几个会告诉你多发推特的人之一。你应该把你的项目发布到 github、kaggle、你的博客、你的网站、twitter、facebook、Instagram、play Numbers,或者你能想到的任何其他在线地方。没有人会知道你的能力,如果他们没有看到你的工作。公开你的工作也会给你带来额外的压力和审查,这将有助于提高你的技能。

联系 —如果你有一个有趣的发现,你认为可以帮助一个团队获胜,不要害怕联系分析决策者。我也会积极在 twitter 上发布分析,并在社区内进行联络。你永远不知道你会和谁联系上。

体育分析是一个很难攻克的市场;然而,如果你遵循这些建议,你将为自己的成功做好准备。

对于那些喜欢视频版本的人:https://www.youtube.com/watch?v=SLC5sPZSLY4

如何学习机器学习

原文:https://towardsdatascience.com/how-you-can-learn-machine-learning-5991dee49362?source=collection_archive---------31-----------------------

由数据科学家分享

那时候我还在上大学,尽管我学的是数学,但我不知道什么是机器学习。在学校里,我学习数学的基本原理,试图证明已经被证明的方程。另外,对于编程方面,我学会了如何使用 Matlab,我以为大部分行业都不在用。

以下是我在上一篇文章中收到的问题之一。

那么 R 是否正在慢慢被遗忘?一些已经投资学习 R 的人,他们应该坚持学习 R 还是转向 Python?

我真的理解她的感受。我在大学最后一年刚开始学习第一门机器学习相关的课程,也就是所谓的数据挖掘课程的时候,是用 r 授课的,学完这门课程之后,我天真的以为可以申请数据科学实习。然而,我发现超过 90%的数据科学实习,其中一个要求是 Python 编程技能。

来自非计算机科学背景,学非主流编程语言的人,我究竟是如何学习机器学习的?这样我就能进入数据科学领域?在这篇文章中,我将与你分享无论你来自哪种背景,你都可以如何学习机器学习。

我学习机器学习的旅程

我在大学读书的时候,为了我的学位,并没有强制去实习。然而,我想尝试获得一份数据科学实习。这很难,在申请了 50 多家公司后,我终于得到了我的第一份实习。我是在不知道任何机器学习算法的情况下得到的。

这次实习其实激发了我对机器学习的兴趣。我能够见证机器学习如何应用于营销行业。此外,我能够了解市场对数据科学的实际技能需求,因此我能够在毕业前磨练这些技能。

我给你的第一个建议是找一份数据科学实习。即使你没有任何机器学习的背景,一些公司也愿意接受没有任何机器学习知识的实习生。学习机器学习不仅仅是了解所有的概念,而是要恰当地应用到现实世界的场景中

回到我的故事。在我第一次实习的时候,为了拾起我在机器学习方面的知识,我居然拾起了我在库塞拉的第一门课程, 吴恩达免费课程 关于机器学习。这个课程太棒了!吴恩达用非常简单的方式解释这个概念,以便每个人都能理解。我仍然记得,在我一个小时的交通时间里,也是在我实习的晚上,我听了他的课程。因此,我能够以最快的速度获取知识。

除此之外,我还同时学习了另一门课程,那就是数据科学专精课程。虽然这门课是用 R 语言教的,但是还是挺实用的。如果你想感受一下数据科学,这个课程绝对物有所值。

第一次实习结束后,我得到了第二次实习,是数据分析师实习。你可能会问,你说你对数据科学充满热情,但你为什么要去做数据分析师实习呢?

这是拍摄。实习头衔并不是求职最重要的因素,有时,工作描述才是最重要的。我发现一些数据科学实习,实际上是以全职数据标签工作结束的。期待一些标签数据任务,但最终要确保你能够在实习期间建立一些模型来解决业务问题

在我第二次实习期间,虽然是数据分析师实习,但我应用了一些机器学习技术来解决任务。最重要的是,我有机会处理大量的数据。我有机会提高自己在 Hive、Python 和 SQL 方面的技能。

之后,我和阿德蒙德李、柯辛冲、魏翁组成一个团队,参加由 Shopee 组织的一个 Kaggle 比赛,任务是解决一个图像分类问题。比赛持续时间约为 2 周。问题是我们事先都不知道 CNN 是什么。如果你对我们如何做的整个过程感兴趣,你可以参考这篇文章。

为什么我要参加一个连 CNN 是什么都不知道的比赛?这是因为这是学习新知识最快的方法。讲座结束后,我们分享了哪些文章或视频对学习极其有用。此外,我们讨论了有哪些方法可以提高我们模型的准确性,这是一次非常有趣而又富有成效的经历。

Kaggle 比赛是一个很好的方式,不仅可以展示你的技能,还可以从其他人的内核中学习。组成一个团队,尝试一场你没有任何先验知识的比赛。你会震惊地发现在有限的时间内你能学到多少知识。

今天走出你的盒子,做一些不舒服的事情。你不必满足于你是谁——你可以创造你想成为的人——霍华德·沃尔斯坦

最后的想法

进入数据科学领域对我来说并不容易。老实说,这对我来说太难了。因此,我希望如果你正在进入数据科学领域,不要放弃。

当你不能马上看到结果的时候,不要放弃。有些事情需要时间。对自己有耐心就好。

非常感谢你一直读到最后。我希望你能从我的经历中获得一些有价值的收获。敬请关注我的下一篇文章!如果你有任何问题要问我,欢迎在下面评论!

关于作者

低伟鸿是 Shopee 的数据科学家。他的经验更多地涉及抓取网站,创建数据管道,以及实施机器学习模型来解决业务问题。

他提供爬行服务,可以为你提供你需要的准确和干净的数据。你可以访问这个网站来查看他的作品集,也可以联系他获取抓取服务

你可以在 LinkedIn 和 Medium 上和他联系。

零信任和零泄漏策略如何实现人工智能机器学习

原文:https://towardsdatascience.com/how-zero-trust-and-zero-leakage-strategies-enable-ai-machine-learning-31dbaf597247?source=collection_archive---------19-----------------------

最近备受瞩目的数据泄露事件让 AI/ML 在云上止步不前。以下是零信任和零泄漏策略如何解决这些问题。

Photo by Bernard Hermant on Unsplash

迈向更安全的企业云租赁

越来越多的证据表明,云上的企业人工智能/人工智能正在拖延。罪魁祸首:真实有效的安全顾虑。尽管如此,AI/ML 的商业利益是压倒性的,对 AI/ML 的需求似乎是无法满足的。

但 AI/ML 对数据(其中许多是敏感数据)的不懈需求,加剧了人们对数据安全的担忧。不幸的是,旧的安全方法似乎不太管用。最近来自 Capital One 的数据泄露和来自 Desjardins Group 的数据泄露似乎强化了这一点。

这使企业陷入困境。美其名曰,一股不可阻挡的力量(业务需求)遇到了一个不可动摇的对象(企业安全否决)。

然而,企业正在反击,引入新技术,如基于身份的安全,这些技术已经能够解决许多安全问题。但是需要做更多的工作。

在本文中,我将描述一种“零信任”和“零泄漏”的安全方法,这种方法建立在基于身份的安全等技术之上,以提供额外的(可能是必要的)功能来保护 AI/ML 赖以发展的敏感数据。通过采用“零信任”和“零泄漏”的安全方法,企业有很好的机会再次加快 AI/ML 在云上的采用。

企业需求推动了 AI/ML 云的采用

今天,AI/ML 正在扩展内部数据中心的能力。简而言之,他们没有计算资源(例如,GPU 农场、按需分配的容量等。)AI/ML 所要求的。

不足为奇的是,许多企业现在已经得出结论,通过云可以获得一个更具可伸缩性、按需且经济高效的解决方案。迈向云原生 AI/ML 的旅程正在进行中。

或者看起来是这样。早期采用者——那些现在在云上有一些 AI/ML 实践经验的企业——已经提出了有效和严重的安全问题。有些甚至有相当公开和负面的经历(比如 Capital One 和 Desjardins Group )。

不幸的是,这些担忧阻止了之前企业大规模使用云原生 AI/ML 的宏伟目标。

Photo by Artem Sapegin on Unsplash

有缺陷的假设是数据泄露的根本原因

直到最近,企业安全性一直专注于确保企业数据中心周围的网络安全。当时,这是有意义的,因为大多数应用程序和资产几乎只在数据中心内工作。此外,从应用程序开发、运营和安全管理的角度来看,它使管理变得更加容易。所谓的双赢局面。

不幸的是,默认的假设——这些旧技术将在未来应用——已经被证明是非常不正确的。更具体地说,旧的基于网络边界的安全方法不适用于云。最近的数据泄露也印证了这一事实。哪里出了问题?

三个关键问题动摇了这一假设。

首先,今天的敌人更加聪明,他们获得了更好的工具,导致网络边界变得更加漏洞百出。优步最近在云上的数据泄露无疑证明了这一点。

第二,在安全和企业云租赁方面可能会出现错误。不幸的是,只需一个配置错误,就会导致一个受威胁的端点,从而开启企业的大范围云租赁。似乎即使是最优秀、最有经验的云团队也是“人质熵”——安全配置确实不可避免地会随着时间的推移而漂移,并且不可避免地会导致违规。或许 Capital One 最近在云上的体验是这种情况最令人心酸的例子。

最后,云的本质也产生了一个安全问题:默认情况下,许多资源被设计为“开放的”,或者在创建时就可以通过互联网访问。这要求企业安全团队为更大范围的云组件提供安全性,不幸的是,一个错误就可能导致灾难性的数据泄露。

有鉴于此,现代云安全方法现在可以说是在网络边界可能被攻破的明确假设下设计的。

保护云安全需要新的技术

有几个主要概念是安全企业云租赁的基础。

首先,“零信任”安全方法规定,除非提供明确的身份验证和授权,否则在企业的云租赁中不能访问任何内容。这种方法与基于身份的安全方法紧密集成在一起(可能没有它就无法实现)。

第二,“零泄漏”策略,即数据不能以任何未经授权的方式在企业云租赁之外传输,无论是意外还是有意。这解决了两种情况:第一,它阻止了未授权的黑客进入系统获取任何信息;其次,它可以防止被授权访问敏感数据的员工意外或恶意地允许数据泄露企业云租赁。

Photo by Clem Onojeghuo on Unsplash

零信任——从不信任,总是验证

零信任是一种基于两个前提的安全方法:“永远不信任”和“永远验证”。第一个是“永远不要信任”,默认情况下,在企业的安全边界内(在我们的例子中,是企业的云租用)没有任何东西是可访问的。第二个是“总是验证”,规定只有那些具有明确验证的凭证的人才被允许访问资源。

应用于云的零信任架构使用身份和相关凭据以及设备声明/信息(例如,IP 地址)来验证用户身份和验证授权,然后再提供对企业云租户中的数据和应用程序的访问。

对于 AI/ML,零信任确保驻留在云上的敏感数据只能由数据科学家访问,这些数据科学家经过身份验证并有权访问和使用关键敏感数据。认识到有效的安全问题是在云上采用 AI/ML 云的主要障碍,实现这种能力形成了再次加速云 AI/ML 计划的基础。

零信任实现注意事项

通常情况下,没有任何安全控制是孤立的:“零信任”最好使用一些补充技术来实现。以下是用于实施整体“零信任”解决方案的一些注意事项:

  • 过渡到基于身份的安全方法:该方法确保在所有企业资源中使用一致的身份,包括数据中心和云上的资源,这是“零信任”的“始终验证”部分的基础
  • ****实施粒度执行技术:应使用所有可用信息来验证请求/代理,不仅包括身份,还包括位置和设备信息,这些信息有助于确定:在高安全性场景中,应考虑多因素身份认证来提供额外的验证级别
  • ****建立严格的支持性治理政策:虽然“治理”可能是一个过重的术语,但就我们的目的而言,“需要知道”和“最小特权”原则应该得到严格的监控和执行
  • ****协调角色和访问控制:建立一个跨越企业数据中心和企业云租户的 RBAC(基于角色的访问控制)方案,从而提供一致的机制来实施授权、资源许可和安全控制
  • ****检查并记录所有流量:应扫描并验证在云租赁内流动的信息,并对照企业安全控制进行扫描和验证;应记录所有流量,以支持任何必要的调查或安全分析活动
  • ****安全流程的集中管理:零信任和相关的身份管理流程应集中管理,以确保安全控制的设计、实施和治理保持一致,从而最大限度地减少出现安全错误的机会
  • ****监控配置变更和配置漂移:熵——变更发生的必然性——将影响企业云租用的安全配置;为了解决这种情况,应监控所有配置更改,以确保尽快检测到危及零信任模型的意外或未经授权的更改并进行补救

Photo by Yogesh Pedamkar on Unsplash

零泄漏政策

云的相对可扩展性和计算能力显然有其优势。而 AI/ML 贪婪的数据需求和与之相称的计算能力需求是云的理想匹配。

但是云的设计也考虑到了“开放性”。默认情况下,可以通过互联网访问资源。在安全措施到位的地方,黑客现在拥有更多的工具来破坏这些安全措施。显然,如果没有适当的注意,这种开放性也可能成为安全隐患。

虽然 AI/ML 是云的理想候选,但它对数据的贪婪胃口(其中许多数据通常非常敏感)在任何情况下都不能离开企业的云租户,无论是意外还是有意的。

那么,企业如何确保数据不会因为某个恶意员工或者某个无意的事故而逃脱企业的边界呢?

如前所述,基于身份的安全和“零信任”策略对保护资源大有帮助。

但是当它涉及到消除数据泄露时,第一个也是最明显的起点是解决基本的云数据卫生问题。以下建议可作为这方面的起点:

  • ****对所有静态(存储)和动态(传输)数据进行加密:这将确保数据具有基本的保护级别,使非预期的访客无法查看或更改数据。根据企业的安全状况,大多数云供应商现在允许企业管理自己的密钥,从而确保即使是云供应商也无法访问企业的数据
  • ****提供基本的网络安全、日志记录和监控:注意云上的网络安全点不一定是保护资源(是的,它执行这个角色,但是零信任和零泄漏,以及相关的身份管理方法做得更好)。相反,它的作用主要是确保网络健康,以及为网络管理、检查和记录建立一个分界点;在这种情况下,这些成熟的技术防火墙方案、网络日志管理和网络分段可以应用于企业的云租用

但仅此并不能阻止“泄漏”,或者更具体地说,数据泄漏到批准的企业边界之外。

考虑一个必须解决的实际和真实的场景:当一个有权访问非常敏感的数据的授权员工(比如一个数据科学家)决定非法共享这些数据时,会发生什么?它确实发生了,而且可能比我们意识到的更频繁。

最明显的解决方案可能是锁定员工的设备(例如笔记本电脑或台式机)。可能设备 USB 和外部设备被锁定。并且为了停止任何基于网络的数据传输,可能会限制设备的网络接入。可以说这种方法是可行的,但是在大型企业用户群中执行起来非常复杂,管理起来更加困难。

一个更好更简单的机会是使用“安全门户”。这个“安全门户”相当于一个浏览器窗口,可以访问云租户,但禁用了允许数据移动的特定功能(通常是“剪切-粘贴”和下载的功能)。实际上,“安全门户”充当了访问云租用的安全观察口。

对于数据科学家和他们的组织来说,这提供了两个世界的最佳选择:不仅是一个功能相对完整的访问云原生 AI/ML 功能的视口(几乎所有的云功能都可以通过这种方式访问),而且是一种保证消除数据泄漏的机制。

这些“安全门户”功能非常常见,由许多供应商提供:思杰有许多支持这一功能的产品,微软(远程桌面,以及 VMWare ( 地平线)也是如此。

Photo by Samuel Zeller on Unsplash

AI/ML 是重新思考云安全的催化剂

AI/ML 的商业利益是压倒性的,对 AI/ML 的需求似乎是无法满足的。但越来越多的证据表明,云上的企业人工智能/人工智能正在停滞不前。和真正的安全关切是主要的罪魁祸首。

不幸的是,旧的安全方法似乎不能很好地工作。

因此,这是新安全方法的催化剂。例如,基于身份的安全性有望解决这些问题,现在已经在企业中站稳脚跟。但是企业意识到需要做更多的工作。

这就是“零信任”和“零泄漏”的由来。越来越多的证据表明,零信任和零泄漏策略对解决许多剩余的安全问题大有帮助。

事实上,“零信任”和“零泄漏”策略现在不仅被视为先决条件,而且可能是改变企业传统上谨慎的安全态势的催化剂,使企业在云上采用 AI/ML 的速度再次加快。

如何减轻处理不平衡数据的痛苦

原文:https://towardsdatascience.com/https-medium-com-abrown004-how-to-ease-the-pain-of-working-with-imbalanced-data-a7f7601f18ba?source=collection_archive---------27-----------------------

使用不平衡数据集创建模型的方法和资源概述

您最终收集并清理了数据,甚至完成了一些探索性数据分析(EDA)。所有的努力终于有了回报——是时候开始玩模型了!然而,你很快意识到 99%的二进制标签属于多数类,而只有 1%属于少数类。使用准确性作为主要评估指标,您的模型将所有预测归类为多数类,并且仍然 99%准确。你做了一点谷歌搜索来找到栈溢出的正确搜索词,然后当你读到处理不平衡数据的痛苦时,你深深地叹了口气…

什么是不平衡数据?

欺诈检测通常用作不平衡数据集的一个例子。也许每 1000 笔交易中只有 1 笔是欺诈性的,这意味着只有 0.1%的标签属于少数类别。疾病数据也可能是不平衡的。在环境健康方面,在 10^6,患癌症风险升高的典型临界值是 1,即百万分之一。在我的项目中,我处理的是诉讼数据,与整个数据集相比,被起诉的公司很少。总之,不平衡数据就像它听起来的那样:少数类的标签很少,这使得精度度量对于评估模型结果有些无用。

我应该做些什么不同?

使用不同的指标

另一个关键区别是使用传统准确性指标的替代指标。因为我主要对识别真阳性和避免假阴性感兴趣,而不是最大化准确性,所以我使用了曲线下面积接收算子特征(AUC ROC)度量。这篇 TDS 文章对 AUC ROC 指标有很好的解释。总之,AUC ROC = 0.5 实质上意味着该模型相当于随机猜测,AUC ROC = 1 意味着该模型可以完美地区分少数类和多数类。

我还依靠混淆矩阵来最大化真阳性假阳性的数量,并最小化假阴性的数量。由于我在处理诉讼数据,我决定将假阳性结果视为未来被起诉的可能性很高的迹象。因此,假阳性结果对我也很重要。我喜欢这个 Kaggle 内核中的代码来可视化混乱矩阵。

Summary of True Positives and False Negatives using the Confusion Matrix

我还计算了更传统的精确度和召回率指标(下面的公式可供快速参考)来比较不同的学习算法,我还将不太传统的遗漏率(假阳性率)添加到指标列表中进行比较。

精度= TP / (TP + FP)

召回率(真实阳性率)= TP / (TP + FN)

漏检率(假阳性率)= FN / (FN +TP)

方法学

处理不平衡数据有两种主要的方法:(1)在算法层面和(2)在数据层面。我将在下面的小节中总结每种方法。

算法相关方法

成本敏感学习

在算法级别考虑不平衡数据集的解决方案需要理解支持成本敏感学习的算法。在我的案例中(也可能用于疾病和欺诈检测),识别真阳性是该模型的主要目标,即使以选择一些假阳性为代价。这就是成本敏感学习派上用场的地方。成本敏感学习考虑不同类型的误分类(假阳性 & 假阴性)。

逻辑回归

经典的逻辑回归算法是不平衡数据集的稳健模型。逻辑回归算法包括一个损失函数,用于计算错误分类的成本。使用 SciKit-Learn,可以使用惩罚权重来操作损失函数,该权重包括“L1”或“L2”正则化,具体取决于所使用的求解器。

支持向量机

在 SciKit-Learn 中,支持向量分类器包括一个“class_weight”参数,可用于为少数类赋予更多权重。“‘平衡’模式”使用 y 值来自动调整输入数据中与类别频率成反比的权重。"本文进一步详述了开发成本敏感型 SVM 的细节。

朴素贝叶斯

SciKit-Learn 包括一个补码朴素贝叶斯算法,这是一个对成本敏感的分类器,它“使用每个类的补码的统计数据来计算模型的权重。”优化模型权重是处理不平衡数据集的有效方法。

集成方法—增强

Boosting 算法对于不平衡数据集来说是理想的“因为在每次连续迭代中,少数类被赋予更高的权重。”例如,“ AdaBoost 通过在每次迭代期间调整误分类数据的权重,迭代地构建弱学习器的集成。

数据相关方法

重新取样

在数据级别解决类不平衡问题通常涉及操纵现有数据,以强制用于训练算法的数据集达到平衡。这种方法称为重采样,典型的重采样技术包括:

  • 对少数民族阶层过度取样,
  • 欠采样多数类,
  • 结合过采样和欠采样,或者
  • 创建系综平衡集。

对少数民族阶层进行过度采样

过采样包括通过创建合成数据来平衡数据集,以增加少数类中的结果数量。一种常见的过采样方法称为合成少数过采样技术(SMOTE),它使用 k 近邻来创建合成数据。

更进一步,SMOTEBoost 结合了过采样和提升。 SMOTEBoost 是“一种基于 SMOTE 算法的过采样方法,在每次增强迭代中注入 SMOTE 方法。”

对多数类欠采样

欠采样涉及减少包含在多数类中的数据,以平衡训练数据集。注意这个减少了数据集的大小。欠采样的一种常见技术是随机欠采样(RUS),它随机选择多数类的子集。这篇中篇文章详细介绍了各种欠采样方法。

RUSBoost 将欠采样与增强相结合。与 SMOTEBoost 类似,“ RUSBoost 通过在每次增强迭代中执行随机欠采样(RUS)而不是 SMOTE 来实现相同的目标。”

整体方法——装袋

Bagging 是数据级集成技术的一个例子。打包涉及“从训练数据集的不同子样本中构建多个模型(通常是同一类型)。”在诸如随机森林决策树算法的算法中,装袋可以减少方差并防止过度拟合。

结论

对于我的数据集,最好的方法是结合使用少数类的整体提升和过采样方法(SMOTEBoost ),并使用逻辑回归算法实现 0.81 的 AUC ROC 值。有了花在特征工程上的额外时间,我可以进一步提高 AUC ROC 值。

商业领袖人工智能入门

原文:https://towardsdatascience.com/https-medium-com-aiprescience-an-introduction-to-artificial-intelligence-for-business-leaders-93b6fe3d2163?source=collection_archive---------27-----------------------

未来几年,所有企业都将受到人工智能的影响,对大多数企业来说,这种影响将是巨大的。作为一名企业高管,你准备好迎接这对你和你的组织意味着什么了吗?

这种人工智能的介绍可能会有所帮助。它主要针对对人工智能不熟悉的商业领袖,其重点是理解人工智能是什么以及在商业环境中意味着什么。

这是首次发表在 AIPrescience.com 的一篇较长文章的独立摘录。整篇文章还讨论了组织如何构建、应用人工智能并从中受益。

问题可能始于我们如何定义“人工智能”&商业受众的类似术语

如果你阅读关于人工智能的最受欢迎的文章,很容易被它们发人深省的含义和预测所吸引。人工智能对社会和日常生活的影响将触及每个人,许多记者和未来学家可以帮助我们应对这将意味着什么。

但商业更平淡无奇,最重要的通常归结为收入、成本、客户和竞争。显然有必要考虑更大的问题,包括伦理问题。但即使是这些,在商业环境中也会受到同样的 4 个优先事项的强烈影响。

因此,要理解人工智能对商业领袖意味着什么,我们应该从通过他们使用的那种镜头来看待这个主题开始。很快变得清楚的是,即使澄清“人工智能”这个术语对商业受众的意义也不像我们希望的那样简单。

有许多定义,每一个都服务于不同受众的需求。有些专注于计算机科学,有些反映了这个术语的历史。有一些是哲学性质的,许多是可疑的有用性。

例如,“什么是人工智能”的前五名搜索结果之一通知我们,“人工智能,有时也被称为机器智能,是由机器展示的智能。。。

我们在这里将“AI”作为几个类似术语的总括标签,如人工智能、机器学习、深度学习和大数据,从而加剧了这种情况。当然,它们之间存在有意义的差异,但在这里并不重要。

出于我们的目的,我们将使用一个标签(“AI”),并用面向业务的术语来定义它。业务受众通常更喜欢强调行动、产出和业务价值。因此,为了给商业受众提供讨论的框架,我们在 AI Prescience 中使用了以下人工智能的定义:

对于商业而言,“人工智能”是指基于计算机的系统,通过模拟人类行为来执行、增强或改变商业活动,目的是提高商业效率或有效性

在某种程度上,这是对人工智能非常直接的看法,强调商业结果。

但请注意,它将人工智能的定义特征提炼为其模拟人类行为的能力,而不是 T2 复制人类行为的能力。这并不总是人们所期望的,因为它暗示了如何实现模拟相对于实现什么来说是次要的。但对于企业来说,这是典型的现实。

为什么商业领袖不应该关心人工智能是否真的“聪明”

这种定义的要点是,在商业环境中,人工智能是否像人脑一样工作并不重要。人工智能是否是“真正的”智能也无关紧要。

对商业来说,重要的是人工智能能否在过去需要人类的领域取得或更好的结果

这种观点将人工智能视为计算机化甚至工业化进程中的又一步。这一步与早期技术的不同之处在于,它执行(并不断改进)我们认为只有人才能做的活动。

它能做到这一点是因为它由计算机系统组成,这些系统具有我们认为是为人类保留的特征。人工智能模拟的人类特征的例子包括:

  • 对周围环境的感知和识别(如无人驾驶汽车中的摄像头)
  • 解释并赋予信息“意义”(例如将手绘草图和笔记转换成 HTML 网页)
  • 处理模糊性(比如知道某人在网上搜索“高尔夫俱乐部”是想买高尔夫设备还是想找地方打高尔夫)
  • 运用判断(例如评估一个奇怪的保险索赔是否可能是欺诈性的)
  • 做出决策,即使是在信息不完整的情况下(例如权衡是否在不确定的癌症筛查后进行活检、另一项筛查测试或“一切正常”)

在人工智能出现之前,如果一项任务需要任何这些特征,我们就需要人来完成。现在,我们有可能实现部分或全部自动化。如果结果更好,就商业结果而言,智能是“真实的”还是人工的并不特别相关。

这并不是说商业领袖不应该关心人工智能的其他影响,例如道德困境和对劳动力的影响。如果有的话,恰恰相反。只是如果他们做决定的标准仅仅是商业结果,潜在复杂的人工智能选择可能会变得相当简单。但这将我们带入了一个非常不同的讨论,一次又一次。

目前,商业领袖的主要观点是,商业中的人工智能技术完全是为了改善以前需要人来做的活动。

但是当然,这只是触及了表面。关于 AI,商业领袖还需要了解什么?

为什么商业领袖应该关心人工智能就是数据&计算

一旦商业领袖清楚了人工智能是什么,他们通常不需要理解它如何工作的细节。然而,如果没有对一些基本概念的理解,这种清晰是不完整的。

在人工智能背后的关键思想中,也许商业的基础是人工智能涉及强大的计算机处理大量难以想象的数据。不管应用和目的如何,人工智能本质上是在给定的数据中寻找模式、相似性和异常性。

对商业受众而言,这意味着:

为了从人工智能中受益,企业必须获得&管理海量数据,使用大量计算机处理、存储&工具从中提取价值。这可能需要新的技能,而这些技能在大多数企业中是不相关的。

我们谈论的数据不仅仅是传统的计算机化商业信息,如销售交易、产品目录和客户账户详情。它还包括印刷文档、在线内容、手写页面和视听文件(例如照片、视频和电话)。

这是因为今天的技术可以以数字方式捕捉几乎任何相关信息,几乎不管其形式如何。在前几代技术中,数据通常只有在数字化和结构化的情况下才能进入计算机系统。

实现这一点的一个方法是考虑一个人是否能够识别给定的数据,并理解它的含义。如果可以,那么人工智能要么已经可以做同样的事情,要么可以学习如何做。而且可能会做得更快,处理的数量也更多。

企业生成的数据量令人难以置信——数亿或数十亿条数据(如金融交易或客户的在线点击和滚动)司空见惯。

但是经济实惠的储物方式意味着我们可以轻松储藏所有这些东西,甚至更多。负担得起的计算能力意味着我们可以快速搜索这些数据。因此,从某些角度来看,存储我们可能知道的关于商业活动的一切是有意义的,以防它被证明是有用的。

这就是为什么云计算经常在与人工智能相同的对话中被谈论。今天人工智能可以为商业做的许多事情在以前理论上是可能的,但成本或时间表令人望而却步。现在,对于任何人来说,使用以前只有政府和最大的公司才有的计算设备都是负担得起的和简单明了的。

因此,为了在你的业务中有效地使用人工智能,你需要捕捉和处理大量你以前可能不关心的数据,使用你以前可能认为不必要的技术。

要做到这一点,你还需要获得以前可能不需要的技能。

人工智能技能如何释放数据的综合力量&计算

人工智能团队以两种广泛的方式构建结合数据和计算的系统。

一套人工智能技术将捕获的数据转换成可用的信息,传递给其他(人工智能和非人工智能)系统,这些系统利用这些信息做一些有用的事情。例子包括

  • 识别由图像或手写组成的数据中的文本
  • 识别由语音指令或录音组成的数据中的单词
  • 在由视频和照片组成的数据中提取面部特征

第二种人工智能技术分析捕获的数据,以找到模式、相似性和异常性。这些用于通知业务决策或行动。例如

  • 人工智能可以检查销售数据,以发现意想不到或以前未知的见解,即什么使产品受到特定客户的欢迎
  • 如果自动驾驶的叉车遇到障碍,AI 可以让它停下来,并以最少的延迟重新路由到目的地。如果障碍是一个俯卧的人,它可以召唤帮助

在商业中很好地使用人工智能包括应用这样的技术来解决特定的、合适的商业问题。人工智能专家应该熟悉问题的特征,这将使它适合人工智能解决方案。

这种特征最明显的例子是有足够数量的可靠数据。但是,一个问题有许多其他特征,使它适合(或不适合)人工智能解决方案。

为了解决一个商业问题,人工智能系统也需要学习一些东西——通常是足够多的正确和错误答案的例子,以确定如何处理新的例子。然而,也有可能提出一套规则供 AI 系统遵循。

人工智能系统如何学习、训练和处理意外情况是构建人工智能系统的一个主要部分。这也是术语差异开始起作用的地方,出现了像“监督的”和“非监督的”学习,或者“狭义的”和“广义的”智能这样的短语。

因此,商业领袖优先考虑的关于人工智能的最重要的事情之一是选择正确的问题来解决,以及正确的商业改进目标。这将很大程度上取决于他们的人工智能团队的知识,以及时间表和预算等限制。

但在理想情况下,这将是一些商业领袖也有一定程度的了解自己。这是因为在商业中应用人工智能是一个名副其实的雷区,会产生意想不到的结果和意想不到的后果。我们似乎看到越来越多的案例,商业领袖而不是技术领袖为引人注目的 IT 问题付出代价。

因此,如果人工智能的商业结果不是积极的,责任很可能在于委托这项工作的商业领袖,而不是执行这项工作的数据科学家。

数据包含我们业务的秘密&我们可能还没有意识到的客户

我们拥有的关于客户和产品等商业实体的数据越多,AI 可以分析的它们之间的关系就越多。

例如,如果你知道客户姓名、地址、出生日期和交易历史,你就可以开始建立一些有用的见解。但是,如果你也了解他们的工作生活,他们如何度过空闲时间,以及对他们的最大影响,那么你会发现更多关于他们的有用知识。

多年来,零售商一直在这样做,例如利用年龄、性别、社会经济特征等来确定促销目标。但是今天,我们能接触到的数据比我们想象的要多。例如,社交媒体档案和订阅源一起提供了一个人的个人和职业生活的复杂画面。

人工智能提供了解开数据中秘密的能力,而商业只是刚刚开始理解这种能力。事实上,“理解”可能不是一个恰当的词。更准确地说,我们刚刚开始意识到我们的数据可以传达什么,以及随之而来的推论和假设。

通常,这是由于意想不到的后果而产生的,并且总是只有事后才知道。例如,围绕招聘算法中无意的种族或性别特征的高调问题表明,在未来很长一段时间内,多样性可能仍然是人工智能中有争议的一个方面。

另一个例子从广告位置开始,但在我们可能还没见过的地方结束:

  • 当一个在线广告“知道”你以前访问过的一个网站,也许是使用另一个浏览器时,你会越来越普遍地感到有点害怕。
  • 当广告提到你在电子邮件或社交媒体信息中提到的东西时,这就更令人不安了。
  • 今天使用人工智能投放广告的企业的未来行动,可能会让它从不安走向更多

如果企业对你了解如此之多,以至于他们可以挑选高度相关的广告, 【世卫组织】将决定他们还可以/愿意/应该利用这些知识做什么, 因为他们发现了新的赚钱方法?

根据今天的情况,答案可能是这些组织中的商业领袖。只有他们。

商业领袖的秘诀

  • 为了在你的业务中有效地使用人工智能,你需要大量不同形式的数据。
  • 您还将需要比以前可能需要的更多的计算能力和存储,以及您当前技术和业务团队的额外技能。
  • 随着你开始使用人工智能技术,你获得的数据越多,你可能会发现更多使用它的方法。
  • 随着你使用数据和人工智能的方式增加,赚钱和省钱的机会也会增加。
  • 但这将与利用数据和人工智能技术做不恰当事情的可能性增加密切相关——无论是无意还是有意。
  • 成功使用人工智能技术来改善业务是一项集体努力,作为一名业务领导者,你是一个可以实现改善的大型团队的一部分。
  • 但当人工智能引发问题时,责任可能不会被广泛分担。
  • 作为一名商业领袖,你是一个小得多的团队的一部分,这个团队将决定一个组织如何准备和应对人工智能在商业中的机遇和风险。
  • 由于监管机构和政府通常很难跟上技术创新的步伐,你可能会发现自己面临的问题、选择和困境远远超出了你自己的业务。

图形神经网络的应用

原文:https://towardsdatascience.com/https-medium-com-aishwaryajadhav-applications-of-graph-neural-networks-1420576be574?source=collection_archive---------3-----------------------

由于图形能够以一种可以客观分析的方式表现现实世界,因此图形及其研究自古以来就受到了广泛的关注。事实上,图形可以用来表示许多有用的真实世界数据集,如社交网络、网络链接数据、分子结构、地理地图等。除了这些具有自然结构的情况之外,诸如图像和文本的非结构化数据也可以以图形的形式建模,以便对它们执行图形分析。由于图的表达能力和近来可用计算能力的巨大增长,大量注意力已经转向分析图的机器学习方式,即图神经网络。

那么,什么是图神经网络(GNNs)?

根据这篇论文,图形神经网络(GNNs)是连接主义模型,它通过图形节点之间的消息传递来捕捉图形的依赖性。它们是神经网络模型的扩展,用于捕获以图形表示的信息。然而,不同于标准的神经网络,GNNs 保持状态信息以捕获节点的邻居属性。然后,图的节点的这些状态可以用于产生输出标签,例如节点的分类或由节点计算的任意函数值。网络试图通过在节点的邻居之间以迭代的方式相互共享数据来学习每个节点的这些编码(hv ),直到收敛。

鉴于 GNNs 可以应用的广泛领域,基于数据类型,大多数 GNNs 可以被分类为结构化应用或非结构化应用。结构化案例表示具有固有结构的数据,如社会互动网络或分子网络。因此,非结构化场景表示数据中的结构不明确的情况,如文本和图像。在这些非结构化场景中,一般的方法是尝试将数据转换成结构化格式,然后应用 GNN。还有一些其他应用程序不属于上面提到的任何一个类的范围。我们将在这里讨论这些类别中的一些有趣的应用。

物理系统

据说,人脑通过创建从现实世界的日常经验中学到的图表来帮助其推理过程。因此,现实世界的实体建模和它们之间的相互作用被赋予了极大的重要性。这被认为是迈向类人人工智能的第一步。通过将对象视为节点,并将它们之间的关系或相互作用视为边,简单的物理系统可以被建模为图形,并且可以使用 GNN 进行有效的分析。

交互网络 可以被训练来推理复杂物理系统中对象的交互。它可以对碰撞动力学(刚性和非刚性)等领域的各种系统属性进行预测和推断。它使用图形上的深度神经网络,使用以对象和关系为中心的推理来模拟这些系统。这些 gnn 已经被证明可以预测未来数千个时间步的不同物体的轨迹。

视觉互动网络 利用上面的互动网络更进一步,从原始视觉观察中了解系统的动态,或者简单地说,只需系统运行中的六个视频帧。除了像其母网络一样预测一系列物理系统的未来轨迹,该模型还可以根据未知物体对可见物体的影响来推断未知物体的质量和未来状态!这是通过感知前端卷积神经网络的共同训练来实现的,感知前端卷积神经网络解析视觉场景以向后端交互网络提供一组对象节点表示。

化学

纳米尺度的分子具有内在的图形结构,离子或原子是节点,它们之间的键是边。GNNs 可以应用于两种情况:了解现有的分子结构以及发现新的化学结构。这对计算机辅助药物设计产生了重大影响。

分子指纹是代表分子的特征向量。通过从示例分子中学习来预测新分子属性的机器学习模型使用固定长度的指纹作为输入。GNNs 可以取代给出分子固定编码的传统方法,以允许生成适合于需要它们的任务的可区分指纹。此外,GNN 从分子的图形结构中学习的这些分子指纹不需要像固定指纹那样大,固定指纹必须在单个特征向量中编码所有可能的子结构。可区分的指纹可以被优化以仅编码相关的特征,减少下游计算和正则化要求。

图像分类

图像分类是一个经典的计算机视觉问题,许多最先进的机器学习机制都有出色的解决方案,其中最受欢迎的是卷积神经网络(CNN)。GNN 把他们的动机赶出了 CNN,也被应用于这个领域。这些模型中的大多数,包括 GNN,在给定一个巨大的标签类训练集时,确实提供了有吸引力的结果。现在的重点是让这些模型在零镜头和少镜头学习任务中表现良好。零镜头学习 (ZSL)指的是试图学习识别模型在训练中没有遇到的类别。ZSL 识别依赖于已知类的标记训练集的存在,以及关于每个未知类如何与已知类在语义上相关的知识。一种方法是在 ZSL 图像分类中利用图形形式的结构信息。因此,GNN 在这方面显得颇有吸引力。知识图表可以提供必要的信息来指导 ZSL 任务。不同的方法在知识图中表示的信息种类不同。这些图表可以基于图像本身或通过对象检测提取的图像中的对象之间的相似性。这些图还可以结合来自图像的类别标签的单词嵌入的语义信息。然后,GNNs 可以应用于这种结构化数据,以帮助 ZSL 图像分类识别任务。

文本

像图像一样,文本内部的关系也是不明确的,即文本不能被认为是可以直接应用 GNN 的结构化数据。但是,有一些方法可以将文本文档转换成结构化数据,如单词或句子的图形,然后使用图形卷积来卷积单词图形。构造文本数据的另一种方法是使用句子 LSTM,它将整个句子视为由子状态即单词组成的单个状态(节点)。文档引用关系也可以用来构建以文档为节点的图。然后,文本 gnn 可以用于学习单词和文档的嵌入。这些方法可用于各种自然语言处理任务,如文本分类、序列标记、机器翻译、关系和事件抽取。

一个有趣的应用领域是阅读理解;给定一段文字,模型必须能够通过巩固文章中的信息来回答基于这段文字的问题。

阅读理解是人类执行的复杂推理任务之一;问题的答案可能不在摘录的任何单个部分中,但可能需要全局推理。使用句子 LSTM 以图表的形式表示段落有助于更好地连接全局证据。

组合最优化

图上的组合优化问题是一组 NP 难问题。其中一些可以通过启发式方法解决。最近,人们正在尝试使用深度神经网络来解决这些问题。因此,gnn 也被用来操作这些图形结构的数据集。

Travelling Salesman Problem

有趣的是,一个通用的基于 GNN 的框架可以应用于图的许多优化问题,例如最小顶点覆盖问题、最大割、旅行推销员问题、最小生成树等。一些方法将 GNNs 与强化学习相结合,在给定输入图的情况下迭代学习解决方案。GNNs 优于传统方法的一个例子是二次分配问题。它的目的是测量两个图的相似性。使用 GNN 学习的节点嵌入的图的比较提供了比标准的基于松弛的技术更好的性能。

结论

鉴于图形神经网络的表达能力和图形数据的显式表示,图形神经网络越来越受欢迎。因此,它们在可以从数据中利用图形结构的领域中有广泛的应用。上面介绍的只是冰山一角。随着新架构的不断涌现,gnn 将继续涉足不同的领域。

图神经网络现在已经发展成为图卷积网络,顾名思义,是受卷积神经网络的启发。这些更加有效和强大,并形成了其他复杂图形神经网络架构的基础,如图形注意网络、图形自动编码器、图形生成网络和图形时空网络。在本帖中探索这些高级架构:超越图卷积网络。

数据湖:资产还是负债?

原文:https://towardsdatascience.com/https-medium-com-bachwehbi-data-lake-an-asset-or-a-liability-c424c74cfde8?source=collection_archive---------13-----------------------

撰写人:巴赫尔·韦赫比和希巴·内梅—2019 年 4 月 18 日

Photo by Paul Gilmore on Unsplash

数据湖,顾名思义,是存储结构化和非结构化数据的企业数据的中央存储库。数据湖的承诺是"获得更多可见性或结束数据孤岛",并因此打开各种用例的大门,包括报告、商业智能、数据科学和分析。

数据湖被视为数字化转型和数据驱动计划的核心关键资产。在过去的几年里,我们目睹了各种规模的公司加速发展自己的数据湖。尽管第一个数据湖是在 Hadoop 分布式文件系统(HDFS)的基础上构建的,但今天 AWS、微软、谷歌、IBM 和其他公司提供了数据湖即服务(DLaaS)解决方案,使构建数据湖变得相对容易。

然而,尽管数据湖和大数据解决方案取得了技术进步,但构建数据湖仍然是一项具有挑战性的任务。据报道,许多数据湖项目都失败了,原因是在数据湖之上构建和运营业务项目需要固有的组织和文化变革。

根据我们的经验,为了避免将您的数据湖变成一种负担,有一些要点应该仔细考虑。

建造它,他们会来的

建立一个数据湖本身不应该是目的,而应该是达到目的的一种手段;最终目标是解决公司的数字化转型和数据驱动计划。然而,许多 IT 部门开始构建数据湖,因为它很酷,很时尚,而且竞争对手也构建了自己的数据湖。然后,他们向业务用户展示他们的数据湖的好处,并邀请他们在一些用例中使用。

至少可以说,首先将所有企业数据集中在一个数据湖中,然后找出利用这些数据的用例的想法是非常危险的。必须构建一个数据湖来处理给定数量的已识别用例,并且从第一天开始就开始业务是一个关键的成功标准。

我们的建议是将您的数据湖设计成可扩展的,并通过包含已确定的用例所需的数据和元数据来逐步构建它,并在以后根据需要丰富它。如果您的公司没有需要来自多个来源的数据的用例,那么您首先就不需要构建数据湖(或者您需要改变您工作的公司)。

别忘了康威定律

以计算机程序员梅尔文·康威(Melvin Conway)命名的康威定律(Conway law)指出:“设计系统的组织被限制生产这些组织的通信结构的副本的设计”。

设计、构建、操作、支持和使用数据湖通常分布在多个业务单位和部门。这需要不同团队之间的密切合作,而这些团队恰好有不同的目标和优先事项。因此,每一项变更或决策都需要进入官僚且耗时的审批流程,并且您所有的敏捷和 DevOps 计划都会在此过程中受到影响。

为了快速有效地行动,你需要所有的参与者朝着一个共同的目标努力。您将需要 (a) 来构建小型敏捷的团队,这些团队拥有交付数据湖不同方面所需的自主权和责任,还需要 (b) 来定义这些团队之间的接口或协议。然后,每个团队将自主地对其范围进行变更,只要它不破坏与其他团队达成的接口或协议。

没有放之四海而皆准的方法

不同的用例在数据消费方面通常有不同的需求。BI 用例需要数据聚合和批量数据检索,AI 和数据科学用例需要手头的大量数据,而分析用例需要搜索引擎、内存缓存或索引数据库来优化对数据的随机访问

有很棒的工具可以满足这些需求中的每一个,我敢打赌你找不到适合所有需求的工具。因此,您会发现自己有不同的工具来满足您的需求,从而使您的架构变得更加复杂。但那真的很好,至少你必须忍受它。你最不想做的就是权衡用户体验和满意度。

我们的建议是为不同的用例定义可接受的性能指标,从业务角度和相关成本的角度确定它们的优先级,然后选择可以满足您预定义的 SLA 的工具。

细节决定成败

数据湖通常采用分层架构设计,包括:

  • 原始数据层:包括从不同源系统收集的不可变原始数据。该层为数据湖中的大多数处理管道提供输入数据。
  • 转换后的数据层:包括原始数据的不同转换管道的输出(清洗、过滤、格式协调等)。).
  • 服务层:包括原始数据和转换数据的处理结果。这一层向不同的应用程序公开 SQL 或 NoSQL 数据库中的数据。

维护这些层涉及许多摄取、转换和处理管道,以及它们的监控、错误处理、回滚过程和数据质量检查。数据湖冰山的水下部分是大部分技术工作所在。

在构建数据湖的第一天,就应该认真考虑这种隐性成本。否则,所有的成本估算和规划都将功亏一篑。

关键要点

为了充分利用数据湖的优势,请考虑以下几点:

  • 从第一天起就让业务参与进来,并确保您设计的数据湖能够解决已确定的业务用例。
  • 支持创建由业务能力引导的跨职能团队来构建您的数据湖。这将允许您避免过程开销,并产生具有更大发展能力的应用程序。
  • 在选择数据湖工具时,不要权衡用户满意度。构建以用户为中心的解决方案将需要使用无数的工具,这将不可避免地增加系统的复杂性,但这是最好的。
  • 不要忘记与数据接收、转换和错误处理等相关的某些隐性成本。评估项目时。

变压器模型文本分类实践指南(XLNet,BERT,XLM,RoBERTa)

原文:https://towardsdatascience.com/https-medium-com-chaturangarajapakshe-text-classification-with-transformer-models-d370944b50ca?source=collection_archive---------0-----------------------

关于使用 Transformer 模型进行文本分类任务的分步教程。学习如何使用 Pytorch-Transformers 库加载、微调和评估文本分类任务。包括伯特、XLNet、XLM 和罗伯塔模型的现成代码。

Photo by Arseny Togulev on Unsplash

更新通知

请考虑使用 Simple Transformers 库,因为它易于使用,功能丰富,并且定期更新。这篇文章仍然是 BERT 模型的参考,可能有助于理解 BERT 是如何工作的。然而,简单变形金刚提供了更多的功能,更简单的调音选项,而且快速易用!下面的链接应该可以帮助你快速入门。

  1. 二进制分类
  2. 多级分类
  3. 多标签分类
  4. 命名实体识别(词性标注)
  5. 问题解答
  6. 句子对任务和回归
  7. 对话式人工智能
  8. 语言模型微调
  9. ELECTRA 和语言模型培训从零开始
  10. 可视化模型训练

py torch-Transformers(现在是 Transformers)库在这篇文章写完之后有了很大的发展。我推荐使用simple Transformers,因为它与变形金刚库保持同步,而且更加用户友好。虽然本文中的思想和概念仍然有效,但是代码和 Github repo 不再被积极地维护。

  1. 语言模型微调
  2. ELECTRA 和语言模型培训从零开始
  3. 可视化模型训练

我强烈推荐为本文克隆Github repo,并在遵循指南的同时运行代码。它应该有助于你更好地理解指南和代码。阅读很棒,但编码更好 r. 😉

特别感谢拥抱脸的 Pytorch-Transformers 库让变形金刚模型变得简单有趣!

1.介绍

Transformer 模型已经席卷了自然语言处理的世界,转换(对不起!)领域突飞猛进。几乎每个月都会出现新的、更大的、更好的模型,为各种各样的任务设定了新的性能基准。

这篇文章的目的是作为一个直接的指南,来使用这些令人敬畏的模型进行文本分类任务。因此,我不会谈论网络背后的理论,或者它们是如何工作的。如果你对深入了解变形金刚的本质感兴趣,我推荐杰伊·阿拉玛的图解指南。

这也是对我之前关于使用 BERT 进行二进制文本分类的指南的更新。我将使用与上次相同的数据集(Yelp 评论),以避免下载新的数据集,因为我很懒,而且我的互联网很糟糕。更新背后的动机有几个原因,包括对我在上一篇指南中使用的 HuggingFace 库的更新,以及多个新的 Transformer 模型的发布,这些模型成功地将 BERT 从其高位上拉了下来。

背景设置好了,让我们看看我们将要做什么。

  1. 使用 HuggingFace 提供的 Pytorch-Transformers 库设置开发环境。
  2. 正在转换。csv 数据集到。HuggingFace 库使用的 tsv 格式。
  3. 设置预训练模型。
  4. 将数据转换为要素。
  5. 微调模型。
  6. 评价。

我将使用两个 Jupyter 笔记本,一个用于数据准备,一个用于培训和评估。

2.各就各位

让我们设置环境。

  1. 强烈建议在安装和使用各种 Python 库时使用虚拟环境。我个人最喜欢的是 Anaconda,但是你可以用任何你想用的东西。
    conda create -n transformers python pytorch pandas tqdm jupyter conda activate transformers conda install -c anaconda scikit-learn pip install pytorch-transformers pip install tensorboardX 请注意,本指南中使用的其他软件包可能没有安装在这里。如果遇到缺失的软件包,只需通过 conda 或 pip 安装它们。
  2. Linux 用户可以使用 shell 脚本下载并提取 Yelp 评论极性数据集。其他人可以在 fast.ai 手动下载这里还有,直接下载链接。
    我把train.csvtest.csv文件放在一个名为*data* 的目录下。 <starting_directory>/data/**

3.预备开始

是时候为变压器模型准备好数据了。

大多数在线数据集通常是.csv格式。遵循规范,Yelp 数据集包含两个csv文件train.csvtest.csv

开始我们的第一个(数据准备)笔记本,让我们用熊猫加载csv文件。

然而,这里使用的标签打破了常规,是 1 和 2,而不是通常的 0 和 1。我完全赞成一点叛逆,但这只是让我反感。我们来修正一下,让标签为 0 和 1,分别表示差评和好评。

在 Pytorch-Transformer 模型的数据准备好之前,我们需要做一些最后的润饰。数据需要在tsv格式,有四列,没有标题。

  • guid:行的 id。
  • label:行的标签(应为 int)。
  • 字母:所有行都有相同字母的列。不用于分类但仍然需要。
  • 文本:行的文本。

所以,我们把数据整理一下,保存成tsv格式。

这标志着数据准备笔记本的结束,我们将继续下一部分的培训笔记本。

4.走吧。(差不多)

从文本到特征。

在开始实际训练之前,我们需要将数据从文本转换成可以输入神经网络的数值。在变压器模型的情况下,数据将被表示为InputFeature对象。

为了让我们的数据转换器做好准备,我们将使用文件utils.py中的类和函数。(稳住自己,一墙代码来袭!)

让我们看看重要的部分。

InputExample类代表我们数据集的一个样本;

  • guid:唯一 ID
  • text_a:我们的实际文本
  • text_b:不用于分类
  • label:样品的标签

DataProcessorBinaryProcessor类用于从tsv文件中读入数据并转换成InputExamples

InputFeature类表示可以提供给转换器的纯数字数据。

三个函数convert_example_to_featureconvert_examples_to_features_truncate_seq_pair用于将InputExamples转换为InputFeatures,最终发送给变压器模型。

转换过程包括标记化,将所有句子转换为给定的序列长度(截断较长的序列,填充较短的序列)。在标记化期间,句子中的每个单词被分成越来越小的标记(单词片段),直到数据集中的所有标记都被转换器识别。

作为一个人为的例子,假设我们有单词理解。我们使用的转换器没有理解的令牌,但是它有理解ing 的令牌。然后,理解这个词就会被分解成令牌理解*和 *ing。序列长度是序列中此类令牌的数量。**

convert_example_to_feature函数获取单个数据样本,并将其转换为InputFeatureconvert_examples_to_features函数接受一个列表的例子,并通过使用convert_example_to_feature函数返回一个InputFeatures列表。之所以有两个独立的函数,是为了让我们在转换过程中使用多重处理。默认情况下,我已经将进程计数设置为cpu_count() - 2,但是您可以通过为convert_examples_to_features函数中的process_count参数传递一个值来更改它。

现在,我们可以转到我们的培训笔记本,导入我们将使用的材料并配置我们的培训选项。

仔细阅读args字典,记下您可以为训练配置的所有不同设置。在我的情况下,我使用 fp16 训练来降低内存使用和加快训练速度。如果你没有安装 Nvidia Apex,你将不得不通过设置为 False 来关闭 fp16。

在本指南中,我使用序列长度为 128 的 XL-Net 模型。请参考Github repo了解的完整可用型号列表。

现在,我们准备加载我们的模型进行训练。

Pytorch-Transformers 库最酷的地方在于,你可以使用上面的任何一个MODEL_CLASSES,只需改变参数字典中的model_typemodel_name。所有模型的微调和评估过程基本相同。拥抱脸万岁!

接下来,我们有定义如何加载数据、训练模型和评估模型的函数。

最后,我们做好了标记数据和训练模型的一切准备。

5.走吧。(真的)

培训。

从这里开始应该相当简单。

这将把数据转换成特征并开始训练过程。转换后的要素将被自动缓存,如果您以后想要运行相同的实验,可以重用它们。但是,如果您更改了类似于max_seq_length的东西,您将需要重新处理数据。改变使用的模型也是如此。要重新处理数据,只需在args字典中将reprocess_input_data设置为True

作为对比,我在 RTX 2080 上花了大约 3 个小时来训练这个数据集。

一旦训练结束,我们就可以挽救一切。

6.回首

评价。

评估也很容易。

在没有任何参数调整的情况下,使用一个训练时期,我的结果如下。

*INFO:__main__:***** Eval results  *****
INFO:__main__:  fn = 1238
INFO:__main__:  fp = 809
INFO:__main__:  mcc = 0.8924906867291726
INFO:__main__:  tn = 18191
INFO:__main__:  tp = 17762*

不算太寒酸!

7.包裹

Transformer 模型在处理各种各样的自然语言处理任务方面表现出了令人难以置信的能力。在这里,我们已经了解了如何使用它们来完成最常见的任务之一,即序列分类。

HuggingFace 的 Pytorch-Transformers 库使得驾驭这些庞大模型的能力变得几乎微不足道!

8.最后的想法

  • 当使用自己的数据集时,我建议编辑data_prep.ipynb笔记本,将数据文件保存为tsv文件。在大多数情况下,只要确保将包含文本标签的正确列传递给train_dfdev_df构造函数,就可以让事情运行起来。您也可以在utils.py文件中定义自己的类,该类继承自DataProcessor类,但我觉得第一种方法更简单。
  • 请使用 Github repo 而不是从这里复制粘贴。任何修复或额外的功能都将被添加到 Github repo 中,除非是重大变更,否则不太可能添加到这里。使用 Gists 将代码嵌入到介质中,因此,它们不会自动与回购代码同步。
  • 如果您需要支持,或者您发现了一个 bug,在 Github repo 上提出一个问题可能会得到比这篇文章上的评论更快的回复。在这里很容易错过评论,缺乏评论/聊天线索也很难跟进。另外,如果是在 Github 上,而不是在 Medium response 上,其他人可能会更容易找到同样问题的答案。

优化:普通最小二乘法与梯度下降法——从头开始

原文:https://towardsdatascience.com/https-medium-com-chayankathuria-optimization-ordinary-least-squares-gradient-descent-from-scratch-8b48151ba756?source=collection_archive---------7-----------------------

Photo by Trần Ngọc Vân on Unsplash

什么是优化?、优化技术—数值方法和迭代方法,以及最终的 Python 实现。

最佳化

优化是机器学习的核心。

用非常严格的术语来说,优化就是寻找你的成本函数给出最小值的过程。对于任何关于机器学习的优化问题,可以有数值方法或分析方法。数值问题是确定性的,这意味着它们有一个不变的封闭解。因此它也被称为时不变问题。这些封闭形式的解是解析可解的。但这些都不是优化问题。

当你有函数 f(x)的“最小”或“最大”这样的词时,优化就来了——目标函数或成本函数。这个目标函数可以定义与你正在优化的问题相关的任何东西。这可能是一家公司的成本,另一家公司的损失,甚至是收入等等。

这个函数在特定的点 X将是最优的。这个 X就是最优点。因此,你的优化问题可能是——找出 X*,其中 f(x)是最小值/最大值。这也可以写成 argmin(f(x)) —其中函数 f(x)是最小值的自变量(或者反过来是 argmax(f(x))。

普通最小二乘法

我很确定你知道线性回归的基本知识。如果你没有,也不用担心。看看这个就知道了。基本上,回归意味着找到最适合你的数字数据的线/曲线——数据的函数近似值。也就是说,您需要一个从输入数据到输出数据(目标)的映射函数。这个映射函数被写成:

其中 W0 是截距,W1 是直线的斜率,ŷ是预测输出。需要找到 W0 和 W1 的最佳值。让我们考虑这个非常小的数据集:

X = 1,2,3

Y = 5,12,18

所以我们需要优化的问题是:

其中 L 是损失函数或成本函数或误差函数。现在下一步是为我们的优化问题找到正确的损失函数。因为如果你最小化错误的目标函数,你最终会得到错误的最优点。我们将使用的损失函数 L 是均方误差,计算公式如下:

求解上述损失函数,我们得到以下用于找到最佳权重的公式:

使用 python 计算上述权重,我们得到以下值:

这是普通的最小二乘解,也就是解析解。因为我们找到了误差平方的最小值。

但是这种解决方案是不可扩展的。将此应用于线性回归相当容易,因为我们有很好的系数和线性方程。将此应用于复杂的非线性算法(如支持向量机)是不可行的。因此,我们将通过迭代法找到这个解的数值近似值——它将接近(但不完全等于)OLS 解——它给了我们精确的解。

梯度下降

我们先来了解一下梯度下降优化背后的直觉。假设 20 个人(包括你自己)被随机空投到一个山脉中。你的任务是在 30 天内找到完整区间的最高峰。你们每个人都有对讲机可以交流,还有高度计可以测量高度。每天,你们都要花几个小时寻找可能的最高峰,并向其他人报告他们在指定区域内发现的当天最高海拔——这就是他们的健康值。

假设在第一天你报告 1000 英尺。有人报告高度 1230 英尺。诸如此类。然后有一个人报告 5000 英尺。这是最大值。记住你的任务是集体到达山脉的最高峰。第二天你接下来做什么?第二天,每个人都会聚集到昨天发现最高海拔的地方。他们会认为山脉的最高峰很可能就在这个地区。如果有另一个区域已经有 5000 英尺,为什么昨天报告 500 英尺的人会再次搜索那个区域。于是所有的搜索者贪婪地向报道的最高点移动。现在,这种贪婪可能会把你带到这个范围的最高峰,但也可能会导致一个彻底的错误。

那个在 500 英尺高的家伙。昨天可能是在一座 10000 英尺高的山峰的底部。!他贪婪地忽略了它,走向另一个最大化 5000 英尺,比如 7000 或 8000 英尺。你实际上陷入了局部最大值/最优值(突变在某种程度上会有所帮助!).没有办法知道你是否停留在局部最优。

模拟退火也是一种可以拯救我们的算法。其中搜索者将彻底搜索整个搜索空间,而不会偏向于最有可能找到全局最大值。

现在回到我们用 OLS 定义的优化问题。让我们用梯度下降法求解。损失函数也是一样的。但这次我们将一步一步地迭代,以达到最佳点。从任意权重值开始,检查该点的梯度。我们的目标是到达最低点,也就是谷底。所以我们的梯度应该总是负的。

source

接下来,我们需要更新权重,使它们更接近最小值。我们有下面的等式:

这意味着下一次迭代的权重将是前一次迭代的权重减去更新的权重。现在这个更新有两个组成部分:方向 —斜率或梯度,以及 —步长。梯度将为:

所以如果在我们的初始重量下,斜率是负的,我们在正确的方向上。我们只需要增加权重的值来使它更接近。这正是上面的等式所做的。如果斜率在特定点为负,则第二项将被添加到上一次迭代的权重值中。相反,如果它是正的,那就意味着我们需要向相反的方向去达到最小值。在这种情况下,该等式从上一个等式的权重值中减去第二项。干净利落。

我们需要考虑的第二个因素是步长α。这是一个超参数,您需要在算法开始之前决定。如果α太大,那么你的优化器将会跳跃很大,永远找不到最小值。相反,如果你把它设置得太小,优化器将会花很长时间来达到最小值。因此,我们需要预先设定α的最佳值。

source

如果你理解正确,你会意识到我们在这里讨论的梯度本质上是误差的总和。我们实际上只是接受了这个错误的一小部分。并且我们传播该误差来更新我们的权重。

因此,我们的权重更新等式变为:

因此,让我们记下我们执行的清晰步骤:

  1. 初始化权重 W0、W1 的值(可以是任何值)和步长α(需要是一个好值)。
  2. 求目标 Ŷ的预测值= W0 + W1。所有 x 的 x。
  3. 计算误差值(Ŷ-Y)和 MSE。
  4. 根据梯度下降更新规则更新权重。
  5. 重复 2–4。

这被称为批次梯度下降,因为我们在每次迭代中获取整个批次或数据集的误差。我们还有以下梯度下降的变体:

  • 随机梯度下降,其中权重的更新在每次迭代中完成
  • 小批量梯度下降,介于批量和随机之间,将完整数据集分成小批量,然后在每个批量后应用权重更新。

最后,让我们用 Python 中的几行代码完成所有这些工作!

让我们从初始化我们的小数据集开始:

现在进入第一步,初始化权重和步长,我选择了 0.04。您可以尝试调整该值并亲自查看结果:

初始化后,我们对整个数据集进行多次迭代,计算每次迭代的均方误差,并更新权重:

所以我们迭代 10 次,希望我们的算法已经足够收敛。让我们看看我们的最终重量,看看它们与我们的 OLS 解决方案有多接近:

相当接近!现在让我们检查预测的目标变量,Ŷ和误差:

如你所见,预测变量非常接近实际值。最后,让我们画出每次迭代的均方误差值,看看我们的算法表现如何:

太好了!所以我们讨论了:

  • 优化到底是什么,
  • 关于机器学习,它有什么样的解决方案,
  • 它的分析方法和直觉是什么
  • 线性回归在 python 中的实现

这就是本文的全部内容。如需进一步阅读,您可以关注以下精彩内容:

  • https://machine learning mastery . com/gradient-descent-for-machine-learning/
  • https://www.youtube.com/watch?v=sDv4f4s2SB8
  • https://www . Amazon . in/Engineering-Optimization-Practice-Singiresu-Rao/DP/0470183527

希望这篇文章有所帮助。请在下面分享和评论你的想法!

回归——为什么是均方差?

原文:https://towardsdatascience.com/https-medium-com-chayankathuria-regression-why-mean-square-error-a8cad2a1c96f?source=collection_archive---------1-----------------------

Photo by Edu Grande on Unsplash

我如何知道我的算法的正确损失函数是什么?因为如果我选择了错误的损失函数,我会得到错误的解。

在机器学习中,我们的主要目标是最小化由损失函数定义的误差。每种算法都有不同的误差测量方法。在这篇文章中,我将介绍回归算法中使用的一些基本损失函数,以及它们为什么会这样。我们开始吧。

假设我们有两个损失函数。两个函数将具有不同的最小值。因此,如果你优化了错误的损失函数,你就会得到错误的解,这就是我的损失函数中的最优点或权重的优化值。或者我们可以说我们在解决错误的优化问题。因此,我们需要找到适当的损失函数,我们将最小化。

1.误差总和(标准误差):

让我们从考虑最基本的损失函数开始,它只不过是每次迭代中的误差之和。误差将是预测值和实际值之间的差异。因此,损失函数将由下式给出:

Ŷ is the predicted value; Y is the actual value

其中求和从 n=1 到 N,N 是数据集中实例的数量。现在考虑下面这条符合我们 3 个数据点的线:

当然不是你可能会说的最佳拟合线!但是根据这个损失函数,这条线是最佳拟合线,因为误差几乎为 0。对于点 3,由于预测值较低,误差为负。而对于点 1,误差是正的,并且大小几乎相同。对于点 2,它是 0。将所有这些相加将导致总误差为 0!但错误肯定不止于此。如果误差为 0,那么算法将假设它已经收敛,而实际上它并没有收敛——,并且将提前退出。它将显示一个非常小的误差值,而实际上该值要大得多。所以你怎么能说这是错误的路线呢?你真的不能。你只是选错了损失函数。

2.绝对误差之和(SAE):

SE 肯定不是我们想要使用的损失函数。所以让我们稍微改变一下来克服它的缺点。让我们只取所有迭代的误差绝对值。这应该能解决问题..对吗?还是没有?这是损失函数的样子:

所以现在误差项不会相互抵消,实际上会相加。这个函数有什么潜在的问题吗?嗯,是的。这个损失函数不是 在 0 处可微 。损失函数的图形将是:

Y axis is the loss function

导数在 0 处将不存在。我们需要对函数求导,并使其等于 0,以找到最佳点。这在这里是不可能的。我们无法解决这个问题。

3.误差平方和(SSE):

所以让我们用平方代替绝对值。损失函数现在将变成:

它在所有点上都是可微的,并且给出非负误差。但你可能会说,为什么我们不能达到更高阶,比如 4 阶左右。那么,如果我们考虑采用 4 阶损失函数,结果会是怎样:

因此它的梯度将在 3 点消失。所以它也会有局部最小值——这不是我们的最优解。我们需要找到全局最小值的点来找到最优解。所以让我们坚持正方形本身。

4。均方差(MSE):

现在考虑我们用 SSE 作为损失函数。因此,如果我们有一个 100 点的数据集,我们的上证指数就是 200。如果我们将数据点增加到 500,我们的 SSE 将会增加,因为平方误差现在将增加到 500 个数据点。所以假设它变成了 800。如果我们再增加数据点的数量,我们的 SSE 会进一步增加。够公平吗?绝对不行!

误差应该随着我们样本数据的增加而减少,因为我们数据的分布越来越窄(指正态分布)。我们的数据越多,误差就越小。但在上交所,情况完全相反。最后,我们的勇士——均方差出场了。它的表述是:

我们取上证指数的平均值。因此,数据越多,总误差 MSE 就越小。

这里你可以看到,随着我们的算法获得越来越多的经验,误差在减少。无论是 R、Python 还是 MATLAB,均方误差都被用作评估大多数回归算法性能的默认指标。

5。均方根误差(RMSE):

MSE 的唯一问题是丢失的次数多于数据的次数。由于我的数据是 1 阶的,损失函数的 MSE 是 2 阶的。所以我们不能直接把数据和误差联系起来。因此,我们取 MSE 的根,即均方根误差:

这里,我们不改变损失函数,解决方案仍然是相同的。我们所做的就是通过求根来降低损失函数的阶数。

6.胡伯损失:

Huber 损失结合了 MSE 和 MAE(平均绝对误差)的最佳特性。对于较小的误差,它是二次的,否则是线性的(对于它的梯度也是类似的)。它由它的变量参数识别:

Huber loss 比 MSE 对数据中的异常值更不敏感或更稳健。它在 0 也是可微的。基本上是绝对误差,误差小了就变成二次了。误差必须小到二次,这取决于一个可以调整的超参数𝛿(δ)。当𝛿 ~ 0 时,胡伯损失接近 MAE,当𝛿 ~ ∞(大数)时,接近 MSE。)

这就是本文的全部内容。一定要看看 Neptune 上这个令人惊叹的博客,了解关于性能指标的更多细节。请在下面评论你的想法!

了解学习速度

原文:https://towardsdatascience.com/https-medium-com-dashingaditya-rakhecha-understanding-learning-rate-dd5da26bb6de?source=collection_archive---------5-----------------------

最初发表于 OpenGenus IQ 。

W 在构建深度学习项目时,我们面临的最常见的问题是选择正确的超参数(通常称为优化器)。这是至关重要的,因为超参数决定了机器学习模型的专业知识。

在机器学习(以下简称 ML)中,超参数是模型外部的配置变量,其值不是根据给定的数据估计的。超参数是估计模型参数过程的重要部分,通常由专业人员定义。

当 ML 算法用于特定问题时,例如当我们使用网格搜索或随机搜索算法时,我们实际上是在调整模型的超参数,以发现有助于我们实现最准确预测的值。

什么是学习率?

学习率(λ)就是这样一个超参数,它定义了相对于损耗梯度下降的网络权重的调整。它决定了我们达到最佳体重的快慢

梯度下降算法通过在每一步最小化成本函数,在多次迭代中估计模型的权重。

算法是这样的:

Repeat until convergence {Wj = Wj - λ θF(Wj)/θWj}

其中:

  • Wj 是重量
  • θ 是θ
  • F(Wj) 分别是成本函数。

为了让梯度下降起作用,我们必须将学习率设置为一个合适的值。该参数决定了我们向最佳重量移动的快慢。如果学习率非常大,我们将跳过最优解。如果它太小,我们将需要太多的迭代来收敛到最佳值。所以使用一个好的学习率是至关重要的。

用简单的语言来说,我们可以把学习速度定义为我们的网络为了新的概念而抛弃到目前为止已经学习过的概念的速度。

通过孩子的互动解释学习率

为了更好地理解这一点,让我们考虑一个例子。

如果一个孩子看到十只狗并且它们都是黑色的,他可能会认为所有的狗都是黑色的,并且在试图识别一只狗时会考虑这一特征。

想象一下,他看到一只白色的狗,他的父母告诉他这是一只狗。有了令人满意的学习速度,他会很快明白黑色不是狗的重要特征,并会寻找另一个特征。

但是由于学习率低,他会认为白狗是异类,并且会继续相信所有的狗都是黑的。

如果学习率太高,他会立刻开始相信所有的狗都是白色的,尽管他见过的黑狗比白狗多。

关键是达到理想的学习率真的很重要,因为:

  • 学习率低和高都会导致时间和资源的浪费
  • 较低的学习率意味着更多的训练时间
  • 更多时间导致云 GPU 成本增加
  • 更高的比率可能会导致模型无法准确预测任何事情

理想的学习率是这样的,它足够低,使网络收敛到有用的东西,但又足够高,使它可以在合理的时间内被训练。

调整学习率

学习率是调节神经网络的最重要的超参数。一个好的学习率可能是一个没有学到任何东西的模型和一个呈现最先进结果的模型之间的差别。

下图展示了配置学习率时可能遇到的不同情况。

Effect of various learning rates on convergence (Img Credit: cs231n)

找到理想或最佳学习率的明显方法是通过反复试验。为了有效地做到这一点,有一些方法我们应该坚持。

从粗到细搜索学习率

0.01 和 0.011 的学习率不可能产生很大不同的结果。即使他们这样做了,以如此小的增量进行搜索是非常昂贵和低效的:如果两种学习速率都导致模型发散怎么办?花在训练上的时间将是一种浪费。

一个更有效的方法是尝试各种不同的学习速度,以确定你应该探索的学习速度范围,并在此范围内集中精力。

例如,每当我试图调整学习率时,我通常从搜索学习率 1e-7、1e-6、1e-5、… 0.01、0.1、1 开始。换句话说,我搜索了 10 个不同的顺序,以找到学习速度的最佳范围。然后,我以较小的增量搜索。例如,如果我发现最佳范围在 0.01 到 0.1 之间,我就会开始在这个范围内搜索学习率,比如 0.03。这与二分搜索法背后的想法非常相似,是一种广泛适用的技术。

不要一开始就对整个数据集进行训练

从整个数据集开始很可能是浪费时间。有可能,一些学习率会导致你的损失发散或波动,一些学习率可能会训练得非常慢,所以在几次迭代后,这些学习率的顺序可以从你的搜索中删除。

尽管试错法是一种相对可靠的调整学习率的方法,但是一种更有效的方法是“学习率测试”,这种方法通过最小的训练来找到最佳的学习率。
基本的想法是,你要有效地找到你可以使用的最大学习率,这将改善损失。为了找到这个值,你用多种学习率进行轻微训练,看看损失是如何变化的。
实际程序是:

选择一个最小和最大学习率进行搜索(例如 1e-7 和 0.1)
使用 SGD 为几个时期训练模型,同时从最小学习率到最大学习率线性增加学习率。

在每次迭代中,记录准确性(或损失)。

绘制测试精度图,查看损失/精度从哪里开始改善,何时开始变得更差/平稳/变得不稳定。后面的学习率是收敛的最大学习率,是你初始学习率的一个很好的值。前一个学习率,即最大学习率的 1/3–1/4,是一个很好的最小学习率,如果使用学习率衰减,可以降低这个学习率。

如果测试精度曲线看起来像上面的图表,一个好的学习率从 0.006 开始,在这里损失开始变得参差不齐。

学习速度应该是适应性的

这种提高超参数收敛速度的方法减少了手动调整初始学习速度的需要。这种方法通过在优化期间使用相对于更新规则本身的学习速率的梯度来动态更新学习速率。计算这个“超梯度”几乎不需要额外的计算,只需要将原始梯度的一个额外副本存储在存储器中,并且只依赖于反向模式自动微分所提供的。

结论和进一步阅读

很明显,配置模型的学习率是一项至关重要的任务,无论您选择哪种方法,都将非常耗时且富有挑战性

Leslie N. Smith 在论文“用于训练神经网络的循环学习率”中讨论了一种涉及选择神经网络学习率范围的强大技术。

谷歌如何解码大自然的生命公式——使用人工智能——这是他们迄今为止最大的打击

原文:https://towardsdatascience.com/https-medium-com-decoding-natures-formula-of-life-using-ai-this-is-google-deepmind-biggest-strike-yet-2da4a5992729?source=collection_archive---------7-----------------------

如果没有疾病会怎样?如果我们能够像自然界一样高效地获取能量,会怎么样?如果我们能立刻回收塑料、石油或其他任何东西?这些是如果人类能够解码生命的自然法则会发生什么的一些使用案例。Deepmind 的数据科学工程师最近朝着这一成就迈出了一大步。下面是如何:

Original Photo by Paweł Czerwiński on Unsplash

它是一次大爆炸,生命科学的新时代。新时代——由新技术驱动:数据科学和机器学习。在科学领域这个非凡而基本的里程碑背后的公司是 deep mind——谷歌的人工智能研发实验室。

Deepmind 因其在人工智能领域的成就而闻名。 AlphaGoAlphaZero 例如——强化学习领域的两个主要里程碑——最近制造了很多谣言。

相比之下,来自同一个 R&D 实验室的另一个团队完成的工作并不那么受欢迎,甚至是默默无闻。这个由数据科学家和数据工程师组成的团队最近一直在研究一种新算法。他们在去年年底向公众推出的一种算法。他们把它命名为

AlphaFold by Deepmind

AlphaFold 的适度目标是解读自然——我稍后会详细解释我这么说的意思——从而赋予人类新的能力。从那以后只有自然母亲才有的能力:生命的圣杯

发生了什么事?

去年年底,DeepMind 的 alpha fold——一种基于人工神经网络的解决方案——在著名的 CASP 竞赛中获得了第一名。CASP — 结构预测的关键评估 —是一项两年一度的科学竞赛,成立于 1994 年,已经举办了 13 届。这有点像好莱坞的分子生物学和蛋白质结构奥斯卡奖。CASP 小组——你也可以称之为奥斯卡评审团——评估全世界科学家和研究人员提交的作品。当然没有好莱坞那么迷人,但肯定更有影响力。

好吧,你可能会说——分子生物学和蛋白质结构——它有什么令人兴奋的?

嗯,我想这也是 AlphaFold 不像 AlphaGo 和 AlphaZero 那样受到公众关注如此之少的原因之一。分子生物学——听起来太像化学和生物学了。自学生时代以来,我们大多数人都乐于放弃的科目。蛋白质——它们到底是什么?当然,我们知道它们的存在和重要性。但是…

蛋白质不仅仅是我们在超市购买的产品背面的营养信息。它们是必不可少的,而且——嗯,是的,我必须承认——蛋白质相当令人兴奋。

蛋白质——大自然的秘密代理人

蛋白质是小分子化合物。我们身体的每一个过程都需要它们。它们是功能核心,是我们身体每个细胞的引擎,像特工一样控制着发生在它身上的一切:我们的荷尔蒙、我们的感情、出生、成长、疾病、幸福、生命、死亡。

它们在细胞分裂过程中传递物质,引发化学反应,保护细胞或制造新的 DNA 链。他们控制一切。因此他们控制了我们。这不仅适用于我们人类。地球上的每一个生物——无论大小和形状如何——都是建立在蛋白质结构上的。

从技术上讲,蛋白质是由 21 种不同的氨基酸组成的链,也称为多肽。每个氨基酸本身由以下 4 种可能的核苷酸构成三联体(密码子):

  • 克(鸟嘌呤)
  • C(胞嘧啶)
  • 甲腺素
  • T(胸腺嘧啶)

3 Nucleotides (a triplet called Condon) describe an amino acid. The exact order of the amino acids constructing a given protein are encoded in the double helix of our DNA. (src — wikimedia).

意味着只有 21 个相应的氨基酸有 64 个(4-4 个核苷酸的三联体)可能的密码子。例如,氨基酸 Ala(丙氨酸) 被编码为密码子 GCA、GCG、GCCGCT。

如果你愿意,这是内置于 DNA 密码功能中的性质——你可以用四个核苷酸中的三个来编码特定的氨基酸,但你不能逆转这个过程,并解码身体细胞中给定氨基酸的精确和原始的核苷酸片段。

Overview of Condons and the corresponding amino acids

尽管蛋白质是由非常简单的组成部分——氨基酸——构成的,但它的结构可能会变得复杂而精密。想想那些只用 26 个简单的英文字母写成的小说和故事吧。类似和简单的概念,但非常强大。

From 26 letters to stories like “Harry Potter” — the Alphabet is a simple, yet powerful concept to encode information. (Photo by Jack Anstey on Unsplash)

Proteins are a sequence of amino acids (Nucleotide triplets)

除此之外,几种蛋白质有时会相互结合,在细胞中产生更大更复杂的结构。

最后但并非最不重要的是,他们建造的链条在 3D 空间中以一种独特和非常具体的方式折叠。一个我们还没有应用到小说创作中的概念。(这是一个有趣的想法——如果字母和单词不仅是用 2D 语写的,也是用 3D 技术写的,那就能编码更多不同的信息。) .

在折叠过程中,蛋白质寻找其最低的能量状态。就像一根拉长的橡皮筋,松开后会卷在一起。只有在蛋白质链中,才会有无数的力——每个氨基酸——相互吸引或相互排斥,从而影响折叠过程中的最终状态。

Animation of a 3D folded protein (src: Proteopedia.org)

它是如何工作的

让我们再做一个简单的类比:我们可以将一个蛋白质结构与一个软件的代码进行比较。代码,不是软件工程师写的,而是天生的。该代码将告诉你身体任何器官的任何细胞该做什么,不该做什么。例如什么时候分裂自己。何时进行特定的化学反应,何时与另一个分子连接。或者什么时候自我毁灭。

因为我们的身体里发生了很多事情,所以我们需要很多这样的小程序。每个人都有特定的任务。目前的研究估计人体蛋白质种类的数量在一万到几十亿之间。

事实上,每个蛋白质结构都是一个独立的软件,以一种非常特殊的方式与所有其他蛋白质相互作用。生物学上称之为对接的过程:

Docking of proteins (src: https://en.wikipedia.org/wiki/Docking_(molecular))

换句话说——坚持类比——每个蛋白质都有其特定的应用程序接口 API,允许它与其他蛋白质进行交互。身体细胞中所有蛋白质及其 API 的编排是细胞的操作系统。因此,人们可以说—

蛋白质是自然界生命的操作系统。

这是一个独特的操作系统

还有一个更重要的方面需要解决:氨基酸的确切序列和蛋白质分子的折叠是由我们的基因决定的,换句话说,是由我们的 DNA 决定的。因为我们每个人的 DNA 都是独一无二的,蛋白质也是如此。

尽管人类基因在所有人中只有大约 0.025%的差异,但这个小数字具有重大影响。这就是为什么我,我和你,你。

这同样适用于蛋白质——即使蛋白质的酸性序列出现很小的偏差和/或其结构的错误折叠都可能导致细胞操作系统出现严重问题。我们称之为老年痴呆症、帕金森症或其他疾病的问题。

但现在让我们回到 Deepmind 在 AlphaFold 上的成就。

在过去的几年里,科学家们花了很多时间破译我们的 DNA。与此同时,人类的 DNA 被编码并广为人知。

科学家们仍在努力解决的是秘密的第二部分:蛋白质必须如何折叠才能让它按照预期的方式工作。

这就像知道软件代码包含的所有命令和关键字(DNA),但不知道它们是如何链接的(折叠)。只有所有这些命令和关键字的正确顺序才有意义,才能让软件正常工作——没有错误,没有瑕疵。

制药业制造的药物是人工生产的蛋白质,试图模仿它们的天然对应物。药物的许多副作用的原因正是如此——蛋白质没有正确折叠,因此与我们的机体不是 100%兼容。

****蛋白质折叠是生物学和制药业领域的一个圣杯难题。

在 CASP13 比赛上 Deepmind 的团队——alpha fold(现在这个名字很有意义了吧?)—提交了一个令人振奋的解决方案。而且他们不仅获得了第一名。不,他们远远超过了他们的竞争对手。

AlphaFolds 算法能够正确预测 43 个给定蛋白质结构中的 25 个的折叠。58%的准确率(排名第二的团队达到了 7%的准确率)。这意味着在给定的 DNA 序列中,他们能够预测 58%的给定蛋白质的 3D 折叠结构。

AlphaFold’s predicted(blue) protein structure vs. its ground truth(green) / src: Deepmind

你可以把它与 7 本哈利波特系列书中包含的 1084170 个单词中的每一个字母进行比较。把每本书放回原处,不分类,放在一个巨大的拼字板上,重新组合所有的 7 本书。逐字逐句。没错。不可能,不是吗?

Photo by Joshua Hoehne on Unsplash

一个小小的数学推断说明了其背后的复杂性:

Photo by Dev Asangbam on Unsplash

想象一个维度为 3x3x3 的三维立方体。意味着 27 个可能的立方体块/位置。让我们以一个简单的氨基酸链“仅由两个氨基酸“A”和“B”组成,并在 3D 空间中表示它。

氨基酸“A”可以位于 3D 立方体的中间。下一个氨基酸“B”现在在 3D 空间中将有 3x3x 3–1 = 26 个选项来连接到其前一个氨基酸“A”。

现在让我们看一个 100 个氨基酸的链——事实上,它是一个非常短的蛋白质。( Titin 例如——迄今已知最长的蛋白质——由 34350 个氨基酸组成)。可能的折叠数量增加到 26 ⁰⁰.一个有 141 个零的数字。一个非常大的数字。比整个宇宙中的原子数还要多。实际上比 universe^2.还要大

根据 Leventhal 悖论——尝试这 100 个氨基酸链的所有可能折叠以找出哪一个是正确的所需的时间,将比宇宙的年龄更长。再次——难以想象!

在未来,量子计算机也许能够在这样的维度上进行运算。如今,人们需要想出比暴力计算更聪明的解决方案。

经过数十亿年的试错进化时间,大自然显然也找到了解决这个问题的聪明办法。只要想想这个过程在你身体的细胞里需要几毫秒才能完成。几乎完美无瑕,一生中无数次,一次又一次。

大自然的聪明仍未实现。

AlphaFold 的人工智能方法

不可能——但 AlphaFold 做到了。第一次参加那项比赛的队伍!不是由分子生物学专家组成的团队,而是由数据科学家和机器学习工程师组成的团队。

AlphaFold 解决方案的核心是基于深度学习技术的巧妙结合。这似乎是解决问题的一个显而易见的方法

但是,这些细节仍然让我感到惊讶:由于有许多(> 150K)已知的蛋白质结构,在那个数据集上进行监督训练将是我的第一个猜测。

他们的方法更聪明。考虑到氨基酸的遗传序列,该团队更关注蛋白质结构独特物理特性的第一步。

该步骤的目标是:

(a)预测氨基酸对之间的距离****

(b)预测连接这些氨基酸的化学键之间的

这里应用的数据科学和机器学习技术是递归神经网络 (RNNs)和 L 长短期记忆 (LSTM)网络——一种特殊的 RNN。

RNNs 和 LSTMs 广泛用于处理时间序列数据和/或自然语言处理(NLP)。他们有一种“内置”的记忆,在那些用例中非常有用。在语言的语境中,这是相当明显的——有些词倾向于更频繁地以某种顺序出现在其他词的某种组合中。在时间序列的情况下,情况是相似的——一些事件更有可能与其他事件同时发生。

这同样适用于基因序列中的氨基酸——或者说它们之间的距离和角度。聪明!

这是新的。这些性质的结合导致了一对氨基酸在给定结构中彼此靠近的可能性。一个“向对方折叠的概率”——如果你喜欢,可以打分。

src: Deepmind

使用这些评分函数,AlphaFold 的团队能够

  1. 在真实蛋白质数据库中寻找匹配的结构。
  2. 并且训练生成神经网络(GAN)来发明新的、优化的蛋白质片段

创造优化的蛋白质片段并评估它们的分数和整个蛋白质链的分数的能力是成功的关键。

现在 AlphaFold 能够创造一个完整的蛋白质结构。计算它的分数。通过替换和重组氨基酸片段来逐步优化它,直到收敛。在这种情况下,收敛意味着:最低能量状态的最佳折叠结构。

src: Deepmind

作为最后一步优化算法,AlphaFold 应用了梯度下降技术。

src: Deepmind

结论和下一步

Deepmind 在解决蛋白质折叠问题上迈出了一大步。解决那个问题似乎是个时间问题。

AlphaFold 对我们人类、气候、健康、能源的影响将是巨大的。人工智能解锁的影响

我很有信心,AlphaFold 目前正在开发他们解决方案的 CASP14 版本。该版本将显著提高现有基准 58%的准确性。不幸的是,这可能是 Deepmind 至今仍未发表关于 AlphaFold 解决方案背后细节的论文的原因之一。

期待casp 142020 年底。

喜欢你读的书吗? 在下面给我留言 或者考虑看我另一篇关于 Medium/TDS 的文章:

** [## 如何在数据科学竞赛中胜出——洞察力、技术和策略

过去两天,我花了相当多的空闲时间在当前的数据科学竞赛上。我来分享一下我的经历…

towardsdatascience.com](/how-to-out-compete-on-a-data-science-competition-insights-techniques-and-tactics-95a0545041d5)**

PS:想接触一下?在 LinkedIn上找到我:

** [## Christo Zonnev -数据科学副总裁*人工智能车库主管-凯捷发明| LinkedIn

查看 Christo Zonnev 在世界上最大的职业社区 LinkedIn 上的个人资料。Christo 列出了 7 项工作…

www.linkedin.com](https://www.linkedin.com/in/christo-zonnev/)

或者在推特上关注我**

深入了解您的 Pytorch 模型,内置新的 Tensorboard

原文:https://towardsdatascience.com/https-medium-com-dinber19-take-a-deeper-look-at-your-pytorch-model-with-the-new-tensorboard-built-in-513969cf6a72?source=collection_archive---------3-----------------------

深度学习模型通常很复杂,难以理解,并被用作“黑盒”。使您的模型更容易访问并可视化其进度可以帮助您更好地理解培训过程中发生的事情。在一个表现良好的模型中,这是一种很好的教育能力,但当你遇到问题时,这是一种不可忽视的力量。它可以帮助您及早发现它们,更有效地调试并消除数据集中的任何偏差。

Tensorboard 允许您记录来自模型训练的事件,包括各种标量(例如,准确性、损失)、图像、直方图等。直到最近,Tensorboard 才得到 Tensorflow 的官方支持,但随着 Pytorch 1.2.0 的最新发布,Tensorboard 现在是一个本机 Pytorch 内置的。

Photo by Kelly Sikkema on Unsplash

这篇文章的目的是向读者介绍 Pytorch 内置 Tensorboard 的基本用法、功能和用途。该员额分为三个部分:

  1. 安装
  2. 基本运行
  3. 时尚 MNIST 数据集上的示例补充了使用选项

安装

要开始安装,请确保您已经创建了一个新的 conda 环境。查看此处的以获取更多 conda 环境管理说明。接下来,您需要安装最新的 Pytorch 版本(1.2.0):

conda install -n /yourenv/ pytorch torchvision cudatoolkit=/yourcudaver/ -c pytorch

分别用环境名和 cuda 版本名替换“yourenv”和“yourcudaver”。

安装 Pytorch 后,您应该激活您的环境并安装 Tensorboard 的每夜构建版本:

pip install tb-nightly

最后,为了避免依赖性错误“没有名为‘past’的模块”,应该安装库‘future ’:

pip install future

就是这样!

如果一切安装正确,你应该能够在 python 中导入torch . utils . tensor board并进入基本运行部分。

基本运行

Tensorboard 的一般使用模式包括两个互补的部分:(python 中的事件记录和(ii)命令行显示激活。

python 中的事件记录

首先,需要将 Tensorboard 导入 python,并创建 writer 类的新实例。writer 的可选输入是 logdir 的路径(否则它将记录到。/runs/)。

该路径表示一个目录,如果该目录不存在,将会创建该目录,所有事件文件都将被写入该目录。稍后,运行将基于 logdir 相互分离,因此您应该为每个运行构建一个唯一的目录路径。

现在,剩下的就是将各种日志写入编写器(在第三节中有详细介绍)。对于动态显示在板上的日志,应使用以下两个选项之一:

注意每次使用 writer.close() 都会随后生成一个新的事件文件供日志跟踪(但是不用担心,您仍然可以继续将事件记录到同一个板)。

命令行显示激活

要查看板上的日志,您需要在命令行中运行以下命令:

tensorboard --logdir=/path_to_log_dir/ --port 6006

到端口 6006 的链接将打印在命令行中,您可以通过 CTRL+单击链接或在浏览器中键入 localhost:6006 来访问它。

注意:使用到 logdir 的完整路径,和你在 python 中使用的一样。不要使用任何引号。即使显示了错误或不存在的路径,Tensorboard 也不会发出任何错误!

如果您想在同一块板上查看多个运行,最简单的方法是将所需的 logdir 移动到同一个目录,并在 logdir 中指明新的目录路径:

tensorboard --logdir=/path_to_joint_dir/ --port 6006

您也可以通过更改其中一个的端口(例如 8008)来同时监控多个运行,但在不同的板上。

时尚 MNIST 数据集上的示例补充了使用选项

既然 Tensorboard 已经安装并导入到 python 中,您可以开始记录各种有趣的指标来评估您的模型。

为了更好地解释不同的用法和它们的主要好处,我们将遵循一个简单的时尚 MNIST 分类器的案例研究。完整代码可从这里获得,数据集可以使用 Pytorch 下载,也可以从这里下载。

我们将用于分类器的模型相当简单。两个 conv2d 层,后面是两个完全连接的层,最终输出 10 个类。ReLU 用作模型内的激活,softmax 用作输出。

模型类:

记录标量:

也许检查模型性能的最直观方法是跟踪损失、准确性等标量指标输出。绘制这些指标可以更好地理解它们的时间背景,如果可以在运行模型时实时完成,就更好了。Tensorboard 可以让你做到这一点。

标量日志记录的格式为:

其中标签表示唯一的数据标识符(即标量值将被附加到哪个列表)。对指标进行分层排序的一种简便方法是对标记使用“截面/绘图”格式。Tensorboard 然后将所有具有相同截面的图聚集在一起(下面的代码中给出了示例)。

global_step 是一个整数,而T5 实际上是绘图中的 x 轴值。如果你让它不存在,那么模型将假设所有标量的 global_step=0。
注意:在同一次运行中不会发生覆盖,这意味着如果你用相同的全局步长绘制两个标量,它们都会出现在图上。默认的
墙壁时间是 time.time(),因为训练已经开始,可以更改为自定义时间。

查看时尚-MNIST 分类器,我们最感兴趣的是训练时期之间的损失变化以及每次验证之间的平均损失和准确性。我们将在测试和训练运行中记录这些标量(记住,您可以在完整的代码上下文中查看这些行,这里是)。

在 Tensorboard 中,数据显示在每个历元之后更新(由于 writer.flush()),在 10 个历元之后,我们的损耗和准确度日志图如下所示:

我们可以玩我们想要的情节显示的“平滑”程度,也可以放大到全屏。

所以,事实上,我们可以看到我们的模型正在做一些事情。它学习有效,训练和测试损失减少,测试准确率提高到 89%。10 个纪元后还不错。但是也许我们可以做得更好?数字是伟大的,但图像有时甚至更好。

记录图像:

人们可以想到可视化图像数据会有帮助的许多原因和步骤。

图像记录的格式为:

这里,标记再次代表一个唯一的数据标识符,这意味着对于要添加的多个图像,您应该更改标记名称。例外情况是一次添加多个图像。对于批量图像数据记录,您可以阅读 Pytorch 文档中的“添加图像”部分。分级排序也是可能的,如在标量日志中。注意在图像记录中全局 _ 步骤仅仅是一个标签。

在我们的案例研究中,我们首先希望用与模型相同的眼睛来观察数据,并在转换后检查所选图像的网格。
为此,我们使用 torchvision utils 创建一个网格对象,并将其添加到 writer:

Tensorboard 中显示的结果让我们很好地掌握了我们的数据在输入到我们的模型后的样子。你能说出所有图片的真实标签吗?

图像记录的另一个有趣的目的是在模型运行时跟踪模型的学习进度。例如,在对象检测/分割中,我们可以随时间可视化预测的遮罩或边界框,并且当训练生成模型时,我们可以通过训练过程来监控模型正在生成的图像的质量。

在我们的案例研究中,也许更有趣的是观察我们模型的错误分类。具体来说,在每个时期之后,我们可以记录一些带有错误预测和正确标签的错误分类图像。
我们可能认为模型在早期会犯“非常愚蠢”的错误,但随着模型的学习,我们会认为它只会错误地对非常硬的图像进行分类。

在 Tensorboard 中,这将看起来像:

事实上,我们可以看到,在纪元 0 时,我们的模型将裤子错误地归类为衣服,而在纪元 9 时,模型将套头衫错误地归类为外套(坦白地说,我不确定我能说出其中的区别)。

记录直方图:

另一个关于模型性能和任何数据偏差的很好的展望可以通过直方图提供。

直方图记录的格式为:

虽然标签的行为与标量中的行为相同,但这里的 global_step 变量是一个整数,它在创建直方图堆栈时指示 z 轴值。可以作为标量或 numpy 数组传递。

注意尽管理论上直方图无论是以累积方式还是使用 numpy 数组一次接收其值都应该表现相同,但实际上是不同的。逐个传递值会导致绘图出现不连续的现象,因此最好将值作为 numpy 数组传递。

也许直方图查看数据的一些更普通的用法可能包括输入图像大小(如果您的数据不均匀)、每幅图像的边界框数量等

但是有更多的选择。在我们的案例研究中,我们希望确保我们的分类器在学习不同的图像或标签时没有偏见。为此,我们从测试步骤中提取了两个变量:(I)对每个标签的置信度建模,以及(ii)对每个图像的最大置信度建模。
每个标签的模型置信度是我们在这个标签位置的预测向量中看到的软最大概率,而不管真实图像标签。
每幅图像的模型最大置信度是一幅图像的最大 softmax 概率输出。我们从第一个时期和随后的时期提取这些变量并绘制每批的分布直方图。这些批次是随机选择的,从第 0 个时期中选择的机会较高,因为大多数戏剧性的学习可能发生在那里。

现在,你应该停下来一分钟,不要向下滚动,试着在脑海中想象两个直方图堆栈的结果应该是什么样子。

以下是 Tensorboard 的一些结果:

在 Tensorboard 上,堆叠直方图以这样的方式显示,早期记录(在我们的例子中是批次)出现在后面,具有较深的橙色,而较新的图在前面。

让我们首先来看看每个标签的最大置信度直方图。正如你在这里显示的一个标签的例子中看到的,早期的批次更连续,有更多的“峰”。当我们转到后面的批次,甚至可能是时代,直方图看起来更像双峰。查看每个图像的最大置信度图,我们可以看到,随着我们移动到后面的批次,图上的临界质量向右移动,接近 1。

那么我们看到了什么?我们的模型随着学习变得更加自信。在开始时,它不能真正告诉每个图像的正确标签,因此对于许多图像,它犹豫地猜测多个标签,从而降低了每个图像的最大置信度。这也导致每个标签的置信度分布几乎是均匀的。但是随着它逐渐了解到这一点。现在,对于每个标签,分布都是双峰的——要么它知道它是有问题的标签(然后是值~ 1),要么它知道它不是(然后是值~0)。大多数情况下不是(90%)。相应地,每幅图像的最大置信度也增加了。

后记

Pytorch 内置 Tensorboard 是一个非常强大的工具,可以在训练期间可视化和评估您的模型和数据集。Pytorch 最终决定将 Tensorboard 的本地版本加入到他们的库中,这很棒,我真的希望他们继续开发和改进它。为了您的方便,也出于乐观的期望,我列出了一些错误和潜在的改进:

  • 从命令行运行 Tensorboard 无法识别两侧带有引号的路径,并且即使该路径不存在也不会报告任何错误。
  • 不幸的是,计算图形可视化不起作用(最后一次检查是在 2019 年 8 月 21 日)。它记录的图形没有任何错误,Tensorboard 中的图形部分变为“活动”,但它只显示两个空框。
  • 将值累积记录到直方图的行为很奇怪。单独的测井事件不会形成连续的图,如果使用直方图叠加,一些峰值不稳定。
  • 直方图堆叠相机角度可能非常有用,否则透视扮演太大的角色。
  • Tensorboard 缺少重置或覆盖标量数据 id 的选项(例如,用于每历元实时丢失跟踪)。

在不到 10 分钟的时间内对数据集进行最先进的图像分类

原文:https://towardsdatascience.com/https-medium-com-drchemlal-deep-learning-tutorial-1-f94156d79802?source=collection_archive---------2-----------------------

Photo by Andre Mouton on Unsplash

2019 年 7 月 3 日更新。

这个简短的教程是在您选择的任何图像数据集上构建和训练图像识别器的分步指南。

在本教程中,您将学习如何:

  • 从谷歌图片中抓取图片,创建你自己的数据集
  • 在数据集上构建和训练图像识别器
  • 可视化并充分解释分类结果
  • 用新图像测试模型

要运行这个笔记本,只需在这里用 Google Colab打开即可。

该笔记本是完全独立的,没有错误,所以你可以运行它。

一旦进入 Colab, 确保更改以下内容以启用 GPU 后端,

运行时- >更改运行时类型- >硬件加速器- > GPU

1.图像数据集下载和设置

选项 1: 使用您自己的数据集

如果您想使用自己的图像数据集,请重新排列它,使同一类的图像位于同一文件夹下。然后,用相应的类别标签命名文件夹。

选项 2: 从谷歌图片中抓取图片

如果你手头没有数据集,你可以从谷歌图片中抓取图片,组成一个你选择的数据集。为此,只需在您的谷歌 chrome 浏览器上安装 Fatkun 批量下载图片扩展,并通过点击扩展选项卡下载任何一组谷歌图片。将同一类别的所有图像放在同一文件夹下,并相应地命名文件夹。

选项 3: 使用我的猴子数据集,这是我最初从谷歌图片上搜集的:)

可以使用以下几个 bash 命令下载和解压缩数据集。

在本教程中,我们将对猴子进行分类,因此我们创建了 6 个文件夹,对应 6 种不同类型的猴子,如下所示。

****

如果您使用您的数据集运行此笔记本,只需将上面单元格中的 url 和文件名替换为您的。存储。Dropbox 中的 tar 文件对我来说效果最好。

2.图像识别

关于代码和函数的更详细的解释可以在我的另一个综合教程⬇中找到

** [## 一个全面的最先进的图像识别教程

使用 fastai 和 PyTorch 解密 CNN、ResNets、迁移学习、微调和 1Cycle 策略

towardsdatascience.com](/a-comprehensive-state-of-the-art-image-recognition-tutorial-c34c544d0b4)

初始化

PATH 是包含所有类文件夹的路径。如果使用自己的数据集,请相应地更改路径。

让我们检索图像类,

There are  6 classes:['Macaque', 'Orungatun', 'Chimpanzee', 'Gorilla', 'Mandrill', 'Gibbon']

让我们验证没有任何无法读取的损坏图像。如果找到了,它们将被删除。

创建和训练分类器

让我们创建我们的训练和验证集,80%的数据集将用于训练,20%用于验证。

There are 268 training images and 67 validation images.

让我们想象一些不同班级的图片,

让我们建立我们的深度卷积神经网络(CNN),

我们使用 ResNet34 作为我们的模型架构。ResNet architecture 在过去几年中取得了巨大的成功,并且仍然被认为是最先进的。

查看我的另一篇文章,了解更多关于 CNN、resnets、迁移学习、微调、1 周期策略调度器和更多⬇.的信息本教程全面而简洁,您将对底层架构和培训过程有一个很好的理解。

[## 一个全面的最先进的图像识别教程

使用 fastai 和 PyTorch 解密 CNN、ResNets、迁移学习、微调和 1Cycle 策略

towardsdatascience.com](/a-comprehensive-state-of-the-art-image-recognition-tutorial-c34c544d0b4)

尽管我们在这里使用的是 ResNet34,你也可以尝试其他 ResNet 型号。但是,请记住,增加层数将需要更多的 GPU 内存。

让我们训练模型,

太好了,我们只用几行代码就达到了很高的分类精度。

我们完成了,但是让我们进一步解释结果。

3.结果解释和可视化

我们可以从想象一个混乱矩阵开始。对角线元素表示预测标签等于真实标签的图像的数量,而非对角线元素是那些被分类器错误标记的图像。

我们还可以绘制损失最大的图像,这些图像是模型最困惑的图像。高损失意味着对错误答案的高度信任。

图像与顶部损失一起显示:
预测标签/实际标签/损失/实际图像类别的概率。

4.在新图像上测试模型

现在让我们给这个模型一个它以前从未见过的新图像,看看它做得有多好。

将图像上传到此笔记本的同一文件夹中。

It is a Mandrill

祝贺您完成、阅读或浏览本教程。

鸣谢:本教程使用 fastai 库,在此感谢杰瑞米·霍华德和 fast.ai 。我也感谢戴夫·史密斯的善意编辑。

我希望这篇简短的教程对你有所帮助。请分享它,并给它一些掌声,这样它也可以到达其他人😀欢迎留下任何评论,在 Twitter @ SalimChemlal 上与我联系,并在 Medium 上关注我了解更多信息!**

使用 Anaconda Navigator 安装 TensorFlow 和 Keras 无需命令行

原文:https://towardsdatascience.com/https-medium-com-ekapope-v-install-tensorflow-and-keras-using-anaconda-navigator-without-command-line-b0bc41dbd038?source=collection_archive---------0-----------------------

在命令行中对 pip 安装说不!分三步在你的机器上安装 TensorFlow 的另一种方法。

https://www.pexels.com/photo/silhouette-people-on-beach-at-sunset-315843/

我为什么要写这个?

我花了几个小时使用多种配置的 pip install,试图弄清楚如何为 TensorFlow 和 Keras 正确设置我的 python 环境。

why is tensorflow so hard to install — 600k+ results

unable to install tensorflow on windows site:stackoverflow.com — 26k+ results

就在我放弃之前,我发现了这个…

"使用 conda 而非 pip 安装 TensorFlow 的一个主要优势是 conda 软件包管理系统。当使用 conda 安装 TensorFlow 时,conda 也会安装软件包的所有必需和兼容的依赖项。

本文将带您了解如何使用 Anaconda 的 GUI 版本安装 TensorFlow 和 Keras。我假设你已经下载并安装了 Anaconda Navigator 。

我们开始吧!

  1. 启动蟒蛇导航器。转到“环境”选项卡,然后单击“创建”。

Go to ‘Environments tab’, click ‘Create’

2.输入新的环境名,我放‘tensor flow _ env’。这里一定要选择 Python 3.6!然后“创建”,这可能需要几分钟时间。

make sure to select Python 3.6

3.在您的新“tensorflow_env”环境中。选择“未安装”,输入“tensorflow”。然后,勾选“张量流”和“应用”。将出现弹出窗口,继续操作并应用。这可能需要几分钟时间。

对“keras”进行同样的操作。

通过导入软件包来检查您的安装。如果一切正常,该命令将不返回任何内容。如果安装不成功,您将得到一个错误。

no error pop up — Yeah!

You can also try with Spyder.

no error pop up — Yeah!

然后…哒哒!搞定了!你可以按照本文来测试你新安装的软件包:)

感谢您的阅读。请尝试一下,并让我知道你的反馈!

考虑在 GitHub 、 Medium 和 Twitter 上关注我,以获取关于您的提要的更多文章和教程。如果你喜欢我做的,不要只按一次拍手按钮。击中它 50 次:D

使用 Scikit 生成合成分类数据

原文:https://towardsdatascience.com/https-medium-com-faizanahemad-generating-synthetic-classification-data-using-scikit-1590c1632922?source=collection_archive---------2-----------------------

Generating Synthetic Data

这是关于不平衡和噪声数据系列文章的第 1 部分。关于偏斜分类指标的第 2 部分已经发布。

为什么我们需要数据生成器?

数据生成器帮助我们用不同的分布和概要文件创建数据来进行实验。如果您正在测试各种可用的算法,并且希望找到哪种算法在什么情况下有效,那么这些数据生成器可以帮助您生成特定于情况的数据,然后测试算法。

例如,你想检查是否梯度推进树可以做得很好,只给 100 个数据点和 2 个特征?现在,您可以搜索 100 个数据点的数据集,也可以使用您自己正在处理的数据集。但是你怎么知道这个分类器是不是一个好的选择,假设你有这么少的数据,做交叉验证和测试仍然留下了过度拟合的机会?或者,您可以使用生成的数据,看看在这种情况下什么通常效果好,是升压算法还是线性模型。

您需要生成数据的几个原因

  • 你的模型能处理嘈杂的标签吗?
  • 当你的标签 99%是负面的,只有 1%是正面的,会发生什么?
  • 如果你的模型能告诉你哪些功能是多余的?
  • 在模型提供特征重要性的情况下,模型如何处理冗余特征。
  • 移除多余的特征会提高模型的性能吗?
  • 当冗余要素、噪声和不平衡同时出现在数据集中时,您的模型会如何表现?
  • 如果你有 N 个数据点和 M 个特征,N,M 的安全值是多少,这样你的模型才不会过拟合?

找到一个真正的数据集来满足这种已知水平的标准组合将是非常困难的。因此,我们只考虑了生成器必须具备的几个能力,以给出真实世界数据集的良好近似。

发电机能力

在寻找发电机时,我们寻找某些功能。我列出了我们在生成器中寻找的重要功能,并对它们进行了相应的分类。

支持不平衡的类

很多时候,你会得到有巨大不平衡的分类数据。例如,欺诈检测具有不平衡性,使得大多数例子(99%)是非欺诈的。要检查分类器在不平衡情况下的表现,您需要能够生成多种类型的不平衡数据。

  • 高斯分位数
  • 制作分类 API

支持生成噪声数据

即使类别标签有噪音,你的分类器能完成它的工作吗?如果一些欺诈例子被标记为非欺诈,一些非欺诈被标记为欺诈怎么办?你如何知道你选择的分类器在有噪声的情况下的行为?你如何选择一个健壮的分类器?

  • 制作分类 API

添加冗余/无用的功能

这些是你有用特征的线性组合。许多模型,如线性回归,对相关特征给出任意的特征系数。在树模型的情况下,它们混淆了特征的重要性,并且随机地和可互换地使用这些特征进行分割。移除相关特征通常会提高性能。

  • 制作分类 API

例子

用于此的笔记本在 Github 中。助手功能在这个文件中定义。

在这里,我们将介绍 scikit 中可用的 3 个非常好的数据生成器,并了解如何在各种情况下使用它们。

高斯分位数

2 级 2D

from sklearn.datasets import make_gaussian_quantiles# Construct dataset
X1, y1 = make_gaussian_quantiles(cov=3.,n_samples=10000, n_features=2,n_classes=2, random_state=1)X1 = pd.DataFrame(X1,columns=['x','y'])
y1 = pd.Series(y1)
visualize_2d(X1,y1)

Gaussian Data

多级 2D

from sklearn.datasets import make_gaussian_quantiles# Construct dataset
X1, y1 = make_gaussian_quantiles(cov=3.,n_samples=10000, n_features=2,n_classes=3, random_state=1)X1 = pd.DataFrame(X1,columns=['x','y'])
y1 = pd.Series(y1)
visualize_2d(X1,y1)

3 Class Gaussian

2 级 3D

from sklearn.datasets import make_gaussian_quantiles# Construct dataset
X1, y1 = make_gaussian_quantiles(cov=1.,n_samples=10000, n_features=3,n_classes=2, random_state=1)X1 = pd.DataFrame(X1,columns=['x','y','z'])
y1 = pd.Series(y1)
visualize_3d(X1,y1)

3D Gaussian Data

通过组合两个高斯函数得到更硬的边界

我们创建两个中心位置不同的高斯。mean=(4,4)在第二个高斯创建中,它以 x=4,y=4 为中心。接下来,我们反转第二个高斯,并将其数据点添加到第一个高斯的数据点。

from sklearn.datasets import make_gaussian_quantiles# Construct dataset# Gaussian 1
X1, y1 = make_gaussian_quantiles(cov=3.,n_samples=10000, n_features=2,n_classes=2, random_state=1)X1 = pd.DataFrame(X1,columns=['x','y'])
y1 = pd.Series(y1) # Gaussian 2X2, y2 = make_gaussian_quantiles(mean=(4, 4), cov=1,n_samples=5000, n_features=2,n_classes=2, random_state=1)X2 = pd.DataFrame(X2,columns=['x','y'])
y2 = pd.Series(y2)# Combine the gaussiansX1.shape
X2.shapeX = pd.DataFrame(np.concatenate((X1, X2)))
y = pd.Series(np.concatenate((y1, - y2 + 1)))X.shapevisualize_2d(X,y)

Combined Gaussians

一滴

如果你想要更简单和容易分离的数据,Blobs 是个不错的选择。这些可以通过线性决策边界来分隔。这里我将展示一个 4 类 3D (3 特征斑点)的例子。

Blobs with 4 classes in 3D

你可以注意到斑点是如何被简单的平面分开的。因此,这些数据点非常适合测试线性算法,如 LogisticRegression。

制作分类 API

这是用于数据生成的最复杂的 scikit api,它带有所有的附加功能。它允许您拥有多种功能。还允许您向数据中添加噪声和不平衡。

一些更好的特性包括添加冗余特性,这些特性基本上是现有特性的线性组合。添加非信息特征来检查模型是否过度拟合这些无用特征。也增加了直接重复的特征。

此外,为了增加分类的复杂性,您可以拥有多个类簇,并减少类之间的间隔,以强制分类器具有复杂的非线性边界。

我在下面提供了使用这个 API 的各种方法。

3 类 3D 简单案例

from sklearn.datasets import make_classification
X,y = make_classification(n_samples=10000, n_features=3, n_informative=3, n_redundant=0, n_repeated=0, n_classes=3, n_clusters_per_class=2,class_sep=1.5,flip_y=0,weights=[0.5,0.5,0.5])X = pd.DataFrame(X)
y = pd.Series(y)visualize_3d(X,y)

Simple case of Make Classification API

3 类 2D 带噪声

这里我们将使用参数flip_y来添加额外的噪声。这可以用来测试我们的分类器在添加噪声后是否工作良好。如果我们有真实世界的噪声数据(比如来自 IOT 的设备),并且分类器不能很好地处理噪声,那么我们的准确性将会受到影响。

from sklearn.datasets import make_classification# Generate Clean dataX,y = make_classification(n_samples=10000, n_features=2, n_informative=2,n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=1,class_sep=2,**flip_y=0**,weights=[0.5,0.5], random_state=17)f, (ax1,ax2) = plt.subplots(nrows=1, ncols=2,figsize=(20,8))
sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax1);
ax1.set_title("No Noise");# Generate noisy DataX,y = make_classification(n_samples=10000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=1,class_sep=2,**flip_y=0.2**,weights=[0.5,0.5], random_state=17)sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax2);
ax2.set_title("With Noise");plt.show();

Without and With Noise

2 级 2D 与不平衡

这里我们会有比正面例子多 9 倍的反面例子。

from sklearn.datasets import make_classification# Generate Balanced DataX,y = make_classification(n_samples=1000, n_features=2, n_informative=2,n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=2,flip_y=0,weights=[0.5,0.5], random_state=17)f, (ax1,ax2) = plt.subplots(nrows=1, ncols=2,figsize=(20,8))
sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax1);
ax1.set_title("No Imbalance");# Generate Imbalanced DataX,y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=2,flip_y=0,weights=[0.9,0.1], random_state=17)sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax2);
ax2.set_title("Imbalance 9:1 :: Negative:Postive");plt.show();

Imbalance: Notice how the right side has low volume of class=1

使用冗余功能(3D)

这增加了冗余特征,这些冗余特征是其他有用特征的线性组合。

from sklearn.datasets import make_classification# All unique featuresX,y = make_classification(n_samples=10000, **n_features=3, n_informative=3, n_redundant=0,** n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=2,flip_y=0,weights=[0.5,0.5], random_state=17)visualize_3d(X,y,algorithm="pca")# 2 Useful features and 3rd feature as Linear Combination of first 2X,y = make_classification(n_samples=10000, **n_features=3, n_informative=2, n_redundant=1,** n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=2,flip_y=0,weights=[0.5,0.5], random_state=17)visualize_3d(X,y,algorithm="pca")

Non Redundant features

请注意,在存在冗余特征的情况下,第二张图似乎是由某个 3D 平面(而非完整的 3D 空间)中的数据点组成的。与第一张图相比,第一张图中的数据点是在所有 3 个维度上分布的云。

对于第二张图,我直觉地认为,如果我将我的坐标改变到数据点所在的 3D 平面,那么数据将仍然是可分离的,但是它的维度将减少到 2D,即,通过减少第二张图的维度,我将不会丢失任何信息。但是如果我减少第一个图的维度,数据将不再保持可分,因为所有 3 个特征都是非冗余的。让我们试试这个主意。

X,y = make_classification(n_samples=1000, **n_features=3, n_informative=3, n_redundant=0,** n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=0.75,flip_y=0,weights=[0.5,0.5], random_state=17)visualize_2d(X,y,algorithm="pca")X,y = make_classification(n_samples=1000, **n_features=3, n_informative=2, n_redundant=1,** n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=0.75,flip_y=0,weights=[0.5,0.5], random_state=17)visualize_2d(X,y,algorithm="pca")

Non Redundant — Can’t Separate in 2D

Redundant 3rd Dim — Separable in 2D as well

利用阶级分离

改变类分离会改变分类任务的难度。在低等级分离的情况下,数据点不再容易分离。

from sklearn.datasets import make_classification# Low class Sep, Hard decision boundaryX,y = make_classification(n_samples=1000, n_features=2, n_informative=2,n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,**class_sep=0.75**,flip_y=0,weights=[0.5,0.5], random_state=17)f, (ax1,ax2, ax3) = plt.subplots(nrows=1, ncols=3,figsize=(20,5))
sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax1);
ax1.set_title("Low class Sep, Hard decision boundary");# Avg class Sep, Normal decision boundaryX,y = make_classification(n_samples=1000, n_features=2, n_informative=2,n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,**class_sep=1.5**,flip_y=0,weights=[0.5,0.5], random_state=17)sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax2);
ax2.set_title("Avg class Sep, Normal decision boundary");# Large class Sep, Easy decision boundaryX,y = make_classification(n_samples=1000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,**class_sep=3**,flip_y=0,weights=[0.5,0.5], random_state=17)sns.scatterplot(X[:,0],X[:,1],hue=y,ax=ax3);
ax3.set_title("Large class Sep, Easy decision boundary");plt.show();

From Left to Right: Higher Class separation and easier decision boundaries

测试各种分类器以了解数据生成器的使用

我们将生成两组数据,并展示如何测试二进制分类器的性能并检查其性能。我们的第一组将是具有容易分离性的标准 2 类数据。我们的第二组将是具有非线性边界和较小类别不平衡的 2 类数据。

要测试的假设

我们想要检验的假设是,单独的逻辑回归不能学习非线性边界。梯度推进在学习非线性边界时最有效。

数据

from sklearn.datasets import make_classification# Easy decision boundaryX1,y1 = make_classification(n_samples=10000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=2,flip_y=0,weights=[0.5,0.5], random_state=17)f, (ax1,ax2) = plt.subplots(nrows=1, ncols=2,figsize=(20,8))
sns.scatterplot(X1[:,0],X1[:,1],hue=y1,ax=ax1);
ax1.set_title("Easy decision boundary");# Hard decision boundaryX2,y2 = make_classification(n_samples=10000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=1,flip_y=0,weights=[0.7,0.3], random_state=17)X2a,y2a = make_classification(n_samples=10000, n_features=2, n_informative=2, n_redundant=0, n_repeated=0, n_classes=2, n_clusters_per_class=2,class_sep=1.25,flip_y=0,weights=[0.8,0.2], random_state=93)X2 = np.concatenate((X2,X2a))
y2 = np.concatenate((y2,y2a))sns.scatterplot(X2[:,0],X2[:,1],hue=y2,ax=ax2);
ax2.set_title("Hard decision boundary");X1,y1 = pd.DataFrame(X1),pd.Series(y1)
X2,y2 = pd.DataFrame(X2),pd.Series(y2)

Easy vs Hard Decision boundaries

我们将用这些测试 3 个算法,看看算法的表现如何

  • 逻辑回归
  • 多项式特征的逻辑回归
  • XGBoost(梯度推进算法)

简单决策边界的测试

参考笔记本第 5 节的完整代码。

f, (ax1,ax2,ax3) = plt.subplots(nrows=1, ncols=3,figsize=(20,6))
lr_results = run_logistic_plain(X1,y1,ax1)lrp_results = run_logistic_polynomial_features(X1,y1,ax2)xgb_results = run_xgb(X1,y1,ax3)
plt.show()

让我们绘制性能和决策边界结构。

Decision Boundary : LR and XGB on Easy Dataset

Train and Test Performances

硬决策边界测试

判别边界

Decision Boundary for Hard dataset

表演

Train and Test Performance for Non Linear Boundary

请注意 XGBoost 如何以 0.916 的分数脱颖而出。这是因为梯度增强允许学习复杂的非线性边界。

我们能够检验我们的假设,并得出结论说它是正确的。由于生成数据很容易,我们节省了初始数据收集过程的时间,并且能够非常快速地测试我们的分类器。

其他资源

[## 合成数据生成(第 1 部分)-块引导

引言数据是定量研究的核心。问题是历史只有一条路。因此我们是…

www.blackarbs.com](http://www.blackarbs.com/blog/synthetic-data-generation-part-1-block-bootstrapping) [## Scikit 数据集模块

sklearn.datasets 模块包括人工数据生成器以及多个真实数据集…

scikit-learn.org](https://scikit-learn.org/stable/modules/classes.html#module-sklearn.datasets) [## 此处使用的笔记本

本笔记本中的全部代码连同助手一起给出…

github.com](https://github.com/faizanahemad/data-science/blob/master/exploration_projects/imbalance-noise-oversampling/Generating and Visualizing Classification Data using scikit.ipynb) [## 助手文件

此项目中使用的帮助器函数…

github.com](https://github.com/faizanahemad/data-science/blob/master/exploration_projects/imbalance-noise-oversampling/lib.py) [## 合成数据生成—新数据科学家的必备技能

为自驱动数据科学项目和深潜生成合成数据的包和想法的简要概述…

towardsdatascience.com](/synthetic-data-generation-a-must-have-skill-for-new-data-scientists-915896c0c1ae)

这是一系列文章中的第一篇,我计划在给定噪声和不平衡的情况下分析各种分类器的性能。接下来的第二部分在这里。

感谢阅读!!

我利用数据科学、人工智能、机器学习和深度学习来解决现实世界的问题。随时联系我 LinkedIn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/71093.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

TowardsDataScience-博客中文翻译-2019-三十三-

TowardsDataScience 博客中文翻译 2019(三十三)原文:TowardsDataScience Blog 协议:CC BY-NC-SA 4.0如何用 Python 编写公平抛硬币的代码原文:https://towardsdatascience.com/how-to-code-a-fair-coin-flip-in-python-d54312f33da9?source=collection_archive---------7…

TowardsDataScience-博客中文翻译-2019-六十-

TowardsDataScience 博客中文翻译 2019(六十)原文:TowardsDataScience Blog 协议:CC BY-NC-SA 4.0堆叠分类器以提高预测性能原文:https://towardsdatascience.com/stacking-classifiers-for-higher-predictive-performance-566f963e4840?source=collection_archive------…

TowardsDataScience-博客中文翻译-2016-2018-三十一-

TowardsDataScience 博客中文翻译 2016~2018(三十一)原文:TowardsDataScience Blog 协议:CC BY-NC-SA 4.0主成分分析:你的教程和代码原文:https://towardsdatascience.com/principal-component-analysis-your-tutorial-and-code-9719d3d3f376?source=collection_archive-…

TowardsDataScience-博客中文翻译-2016-2018-三十八-

TowardsDataScience 博客中文翻译 2016~2018(三十八)原文:TowardsDataScience Blog 协议:CC BY-NC-SA 4.0Python 属性的原因和方式原文:https://towardsdatascience.com/the-why-and-how-of-python-properties-b791817cf4b9?source=collection_archive---------3--------…

2024-2025-1 20241327 《计算机基础与程序设计》第三周学习总结

作业信息 |2024-2025-1-计算机基础与程序设计)| |-- |- |2024-2025-1计算机基础与程序设计第二周作业)| |快速浏览一遍教材计算机科学概论(第七版),课本每章提出至少一个自己不懂的或最想解决的问题并在期末回答这些问题 |作业正文|https://www.cnblogs.com/shr060414/p/18…

『模拟赛』多校A层冲刺NOIP2024模拟赛06(更新 T4)

『模拟赛记录』多校A层冲刺NOIP2024模拟赛06Rank 比较还行A. 小 Z 的手套(gloves) 签。 最大值最小,一眼二分答案。双指针 check 一下就完了,复杂度 \(\mathcal{O(n\log n)}\)。点击查看代码 #include<bits/stdc++.h> #define fo(x, y, z) for(register int (x) = (y…

Grafana学习笔记1

安装 Grafana容器镜像拉取 docker pull grafana/grafana启用Grafana容器 命名为Grafa,再把主机端口3000映射到容器端口3000,把主机上的目录/path/to/your/grafana/data(这个路径自己定义)挂载到容器内的目录/var/lib/grafana,设置管理员密码为admin,使用已经拉取的镜像grafan…

4.漏洞挖掘(长期)

具体漏洞复现,见奇安信攻防社区的帖子。 国庆假期,试挖漏洞算是揭开的漏洞挖掘的面纱。第一个练手的漏洞是敏感信息漏洞。一开始,手工查找,google搜索,后来在chatGPTd 帮助下,学习研究脚本进行扫描。 但现在了,脚本不太好研究下去了,并且没太大兴趣继续,感觉太low了,…