TowardsDataScience-博客中文翻译-2020-四十三-

TowardsDataScience 博客中文翻译 2020(四十三)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

2020 年如何管理数据科学项目

原文:https://towardsdatascience.com/do-data-science-good-until-do-it-great-in-2020-7466598c5cd0?source=collection_archive---------14-----------------------

成功 DS 项目管理的 4 个要素


祝新年快乐!

【2020 年 5 月又是成就和繁荣的一年。


反光

学数据科学和做数据科学是两码事。在学校,统计学教授教我们如何曲线拟合“完美的”机器学习模型,但不教我们如何务实,如何管理项目,以及如何倾听客户的需求。

正规教育有时会让我们失望,以一种可怕的方式让我们失望。

当与其他更有经验的数据科学家交谈时,对初级数据实践者最常见的抱怨是缺乏行业工作能力。

知道 DS 和实际做 DS 之间存在着巨大的差距。在这篇文章中,我想分享我从管理项目评估项目中学到的 4 个非技术成功要素。

背景

作为一名博士生,我接受了 5 年多的研究设计和数据科学培训。几年前,我在一家教育公司从事统计咨询工作。

这家公司为弱势学生提供社交礼仪和职业发展方面的培训。它以非政府组织的方式运作,严重依赖公众捐款和政府拨款。尽管有着很棒的节目,该公司发现自己陷入了财务困境,因为他们无法量化社会影响。他们的资助申请已经几次被公司和基金会拒绝。

顺便说一句,社会效果这种无形的概念总是很难量化。项目评估人员需要精通数据,并具备丰富的领域知识。

我的工作是想出一个有效的研究设计来量化他们的好工作。

从零开始。嗯,算是吧。

这说起来容易做起来难。当我第一次开始的时候,我惊讶地发现数据团队是如此的毫无准备和混乱。缺乏准备使得他们无法重新设计工作流程。举一个例子,作为教育培训提供商,他们甚至没有计划目标学习成果陈述(LOS)

对于那些不太熟悉这个领域的人来说,这两个要素是项目评估的基本要素。没有 LOS,我们就无法证明该计划是否达到了目标。

照片由 Neven KrcmarekUnsplash 上拍摄

成分 1:真正理解商业问题

首先要做的事。我与领导层坐下来,制定他们的具体目标。为了量化结果,我开发了一套新的度量标准,包括三个维度:知识、态度和行为

  • 知识 T3。 什么是职业操守?其中一个关键是教育学生什么是职业精神。
  • 态度 什么是专业设置中的正确态度?这与 LOS 一致。
  • 行为。 你如何表现得很专业?而且,这与 LOS 是一致的。

这个过程大约需要 1-1.5 周。

有了这些目标,下一步就是收集数据。我要求他们提供所有的数据,任何调查等等。此外,我要求进入他们的数据库和以前收到的不成功的资助申请的拒绝信。

这是关键的一步。拒绝信提供了失败的原因,并为我们指明了未来的方向。收集他们已经做了什么的信息肯定有助于我们理解还应该做什么。没有必要重新发明轮子。

不出所料,拒绝的最常见原因是缺乏可量化的结果。该公司提供了一些描述性数据,但没有推断性数据。描述性数据表明学生在小组中的表现,而推断性数据表明该计划是否有所不同。

在一系列的帖子中,我介绍了推导因果推理的实验方法(因果 VS 关联自然实验RDDITS做了)。

成分 2:更简单的解决方案是更好的解决方案

初级数据科学家喜欢陷入这个常见的陷阱:更喜欢花哨、复杂的解决方案,以显示他们能做什么,而不是可以解决问题的简单解决方案。

简单回归的 10 层深度学习模型?

真的吗???

这在项目评估领域至关重要。我们希望通过我们的伟大工作给利益相关者和基金会留下深刻印象。用更难解释的模型来混淆它们是我最不愿意做的事。

考虑到这一点,我采用了一个简单的准 A/B 测试,并包含了一些呈现结果的常用方法。

  • *均分数。比较治疗组和对照组的*均值。
  • 双样本 T 检验。确保实验组具有可比性。
  • 成熟度检查。作为一个稳健的检验,我消除了成熟效应,因为对照组的参与者在实验期间保持不变。
  • 配对 T 检验。数据分析显示,参加该计划后,有适度的、统计上显著的增长。

Jason Rosewell 在 Unsplash 上拍摄的照片

成分三:沟通是王道

在整个过程中,最具挑战性的部分是将模糊的业务问题转化为可测试的 DS 问题。这真的不容易。我和团队坐下来谈了几次,交换了关于什么是可测试的,什么是不可测试的想法。这个过程持续了几个星期,我们不得不不不情愿地放弃一些想法,专注于少数可行的想法。

在集思广益的过程中,我的非技术同事帮助我更好地了解公司的结构和独特的需求。作为回报,我帮助解释什么是可行的统计测试。伟大的想法不断涌现,对话持续很长时间。

作为团队中的数据员,我经常带着我的耳朵,而不是我的嘴巴,在说出来之前,倾听并了解他们的需求和关注。

正如所说,成功的项目管理的 20%来自好的模型,80%来自非技术部分。

同意!

照片由 Aron 视觉效果Unsplash 上拍摄

成分 4:时间管理

这是最后一个非技术成分,但却是必不可少的。为了让事情继续下去,我们的时间表很紧,必须在大约 2 个月的时间内提供可行的结果。最大值。

在一年的时间里交付完美的结果?

当然,但是公司会破产。

在短时间内,我重新设计了整个工作流程,使其更加实用,包括参与者招募、模型选择、数据分析、稳健测试和起草项目报告。

  • 采样。我建议不要随机抽样,而是接触潜在的学校,挑选同意参与的学校。另一方面,只要我们小心概括的范围,项目评估并不那么依赖随机抽样。
  • 案例选择。在选定的学校中,我们选择了两个在多方面彼此相似的班级,如性别比例、种族和家庭年收入。一个是对照组,一个是治疗组。
  • 型号选择。没有花哨的模型,只是两样本配对 T 检验。

照片由 Clem OnojeghuoUnsplash 上拍摄

结论和要点

总的来说,我对结果很满意,享受做这件事的每一秒钟。学习商业很有趣,与各种利益相关者交谈更好,并且产生真实的影响是最棒的部分!

由于我的工作,这家公司能够量化他们的良好工作,并在几个月内筹集到超过预期金额的资金。

外卖

第一课:真正理解商业问题

第二课:更简单的解决方案是更好的解决方案

第三课:沟通是王道

第四课:良好的时间管理

喜欢读这本书吗?

请在 LinkedInYoutube 找到我。

还有,看看我其他关于人工智能和机器学习的帖子。

决策树需要特征缩放吗?

原文:https://towardsdatascience.com/do-decision-trees-need-feature-scaling-97809eaa60c6?source=collection_archive---------26-----------------------

亚里沙·戈洛文斯卡的照片

决策树和集成方法需要特征缩放吗?

机器学习算法从一开始就一直走在进化的道路上。今天,这个领域已经从数学建模发展到集合建模等等。这种进化已经看到了更强大的 SOTA 模型,几乎弥合了人类和人工智能潜在能力之间的差距。集合模型给了我们一个 SOTA 模型 XGBoost。

招聘挑战

最*我碰巧参加了一个机器学习招聘挑战,其中的问题陈述是一个分类问题。虽然问题陈述是一个入门级的问题,但我想在这里分享一下竞赛中的一些关键收获。

我的日常工作是从数据清理、数据预处理、EDA 和类上采样开始的(因为训练数据集是不*衡的)。作为 EDA 的一部分,我发现数据集的特征具有很高的方差。因此,我计划用 MinMax Scaler 进行特征缩放。

*#Feature Preprocessing and Feature Transformation:* **def** feature_preprocess_transformation(data):
    **global** train,test
*#   data['X_12']=data['X_12'].fillna(value=1.0).astype(int)                                                    
#   scaler=MinMaxScaler(feature_range=(0,4))
#   for j in to_normalize:
#        data[j]=scaler.fit_transform(data[j].values.reshape(-1,1)).astype(int)

#Calling the preprocessing function for Train and Test Data* feature_preprocess_transformation(train)
feature_preprocess_transformation(test)

完成所有先决条件后,我决定尝试集成算法,因为它基于决策树的逻辑以及从弱学习者学习的能力,预计它在分类问题上表现更好。所以我决定使用 XGBoost。

xgb=XGBClassifier()
xgb.fit(X_train,y_train)
y_pred=xgb.predict(X_test)

tn,fp,fn,tp=confusion_matrix(y_test,y_pred).ravel()
recall=recall_score(y_test,y_pred)
precision=precision_score(y_test,y_pred)
print(**'\n'**,**'Recall : '**+str(recall))
print(**'\n'**,**'TN : '**+str(tn),**'\n'**,**'FP : '**+str(fp),**'\n'**,**'FN : '**+str(fn),**'\n'**,**'TP : '**+str(tp))

如下所示,该模型的召回分数为 0.9961,并且高假阳性计数表明该模型在对阴性类别进行分类时的难度。

具有最小最大标度模型的召回度量

后来,我删除了特性缩放的预处理部分,并尝试应用相同的 XGBoost 模型。

**def** feature_preprocess_transformation(data):
    **global** train,test
    data[**'X_12'**]=data[**'X_12'**].fillna(value=1.0).astype(int)                                                   *
#   scaler=MinMaxScaler(feature_range=(0,4))
#   for j in to_normalize:
# data[j]=scaler.fit_transform(data[j].values.reshape(-1,1)).astype(int)*xgb=XGBClassifier()
xgb.fit(X_train,y_train)
y_pred=xgb.predict(X_test)

tn,fp,fn,tp=confusion_matrix(y_test,y_pred).ravel()
recall=recall_score(y_test,y_pred)
precision=precision_score(y_test,y_pred)
print(**'\n'**,**'Recall : '**+str(recall))
print(**'\n'**,**'TN : '**+str(tn),**'\n'**,**'FP : '**+str(fp),**'\n'**,**'FN : '**+str(fn),**'\n'**,**'TP : '**+str(tp))

从下面可以看出,召回分数提高到 1.0,并且该模型能够更有效地对阴性类别进行分类,而假阳性更少。

具有最小最大标度模型的召回度量

直觉

礼貌:【https://homes.cs.washington.edu/~tqchen/pdf/BoostedTree.pdf】T2

  • 以上节选自 XGBoost 作者的一篇演讲。
  • 决策树分类不受数据中异常值的影响,因为数据是使用分数分割的,分数是使用所得数据点的同质性计算的。

外卖食品

  • 决策树和集成方法不需要执行特征缩放,因为它们对数据中的方差不敏感。

参考

https://papers with code . com/paper/xgboost-a-scalable-tree-boosting-system

[## 正常化有必要吗?问题#357 dmlc/xgboost

解散 GitHub 是超过 5000 万开发者的家园,他们一起工作来托管和审查代码,管理项目,以及…

github.com](https://github.com/dmlc/xgboost/issues/357)

伦敦东区的粉丝喜欢 Hollyoaks 吗?

原文:https://towardsdatascience.com/do-eastenders-fans-like-hollyoaks-analysis-in-r-4eed0fe3b7e?source=collection_archive---------61-----------------------

使用 rtweet 和 VennDiagram 进行简单的 Twitter 追随者重叠分析。

Joshua Hoehne 在 Unsplash 上拍摄的照片

想知道你和你最喜欢的名人有多少粉丝吗?没有吗?哦..我也没有。但是,如果你真的想知道,这里有一个简单的 R 脚本,使用 rtweet 和 VennDiagram 来找出答案。

例如,这是一个很棒的小脚本,可以用来写那些“值得拥有”的分析;分析你的品牌和竞争对手的追随者重叠,或者回答类似伦敦东区的粉丝喜欢 Hollyoaks 吗?继续滚动查看大揭秘!

完整的脚本(下面的分步指南):

逐步地

步骤 1 —运行所需的包

这个脚本使用了 3 个包:

  • rtweet —从 Twitter API 收集所需的数据。
  • Tidyverse —处理数据。
  • 文迪雅图 —可视化数据。
library(rtweet)
library(tidyverse)
library(VennDiagram)

当您第一次运行 rtweet 包时,R 会尝试打开您的网络浏览器,以便您登录并允许访问 Twitter。

第 2 步—设置账户

设置你想要分析的账户,在这个例子中,我们将会看到英国的 Soap Twitter 账户。在下面的代码片段中,我们陈述的用户名与 Twitter 上显示的完全一样。我们将存储它,以便在收集数据时在函数中使用,并在稍后命名维恩图的区域时使用,以使脚本可重用。

a_name <- “itvcorrie”
b_name <- “bbceastenders”
c_name <- “emmerdale”
d_name <- “Hollyoaks”

步骤 3 —收集数据

接下来,我们将使用 rtweet 包中的 get_followers 函数来收集英国肥皂剧关注者的用户 id📺推特账户。

以下代码片段将收集所有用户 id 的表数据帧,存储为 a、b、c 和 d,供以后在维恩图中使用。

如果您正在分析拥有大量追随者的帐户,此步骤可能需要一些时间。首先,我们使用 lookup_users 函数收集关于帐户的高级数据,并将其存储为 X _lookup。数据提取包含一个列,其中包含该帐户的关注者总数。

a_lookup <- lookup_users(a_name)

接下来,我们获取关注者的数量并存储为 n ,这将告诉下一个函数何时停止收集,以确保我们有一个完整的数据集。如果您想对数据集进行采样,您可以对该部分应用采样函数。在没有声明 n 的情况下, get_followers 函数会自动抽取一个非常大的数据样本。

n = a_lookup$followers_count

现在收集用户 id。使用 get_followers 函数,我们可以声明感兴趣的用户名(我们在步骤 2 中将其存储为一个值)、我们希望收集的关注者数量(n,如上所述)以及设置为 TRUE 的 retryonratelimit 子句。这将确保 get_followers 函数在达到速率限制时继续运行。注意,速率限制是为您的整个会话设置的,而不是为每个用户名设置的。达到速率限制和重试之间通常需要 10-15 分钟,所以如果您想处理大型数据集,请记住这一点。

a <- get_followers(a_name, n = n, retryonratelimit = TRUE)

我们重复这个过程来提取存储在 a、b、c、d _ name 下的用户名所需的所有数据,以创建 4 个整洁的数据集。

在你等待这个部分运行的时候,最好把水壶放上。 ☕

a_lookup <- lookup_users(a_name)
n = a_lookup$followers_count
a <- get_followers(a_name, n = n, retryonratelimit = TRUE)b_lookup <- lookup_users(b_name)
n = b_lookup$followers_count
b <- get_followers(b_name, n = n, retryonratelimit = TRUE)c_lookup <- lookup_users(c_name)
n = c_lookup$followers_count
c <- get_followers(c_name, n = n, retryonratelimit = TRUE)d_lookup <- lookup_users(d_name)
n = d_lookup$followers_count
d <- get_followers(d_name, n = n, retryonratelimit = TRUE)

步骤 4 —可视化数据

4 天后,我们终于收集到了我们需要的数据😄现在是我们期待已久的时刻,视觉化!

我们将使用 文迪雅图 包来分析结果。

下面使用的文氏图功能主要关注以下内容:

  • x =您想要可视化的数据。这里采取了一个额外的步骤,从每个表数据框中提取用户 ID 数据并转换为字符值,您可以减少或扩展列表以匹配您想要分析的用户数量。
  • category.names =步骤 2 中创建的值,您可以缩小或扩大列表以匹配您想要分析的用户数量。
  • filename =包含矢量输出的 png 文件的名称,您可以随意重命名。
  • col =每个区域周围的边框,这是灰色的,可以随意更改。
  • 填充 =你想要的每个区域的颜色,这将遵循与 x类别名称相同的顺序,同样,你可以减少或扩展以匹配你想要分析的用户数量。α和本节中的 0.3,表明颜色将透明到什么程度。

还有许多其他可用的定制,我建议浏览一下文档以获得更多样式。

venn.diagram(
 x = list(
           a %>% select(user_id) %>% unlist(),
           b %>% select(user_id) %>% unlist(),
           c %>% select(user_id) %>% unlist(),
           d %>% select(user_id) %>% unlist()
          ),
 category.names = c(a_name,
                    b_name,
                    c_name,
                    d_name),
 filename = ‘output.png’,
 output=TRUE,
 col = alpha(“#D3D3D3”,0.3),
 fill = c(alpha(“#581845”,0.3), 
          alpha(‘#FFC300’,0.3), 
          alpha(‘#C70039’,0.3),
          alpha(‘#FF5733’,0.3))
 )

完成后,您将在 R Studio 的文件窗格中看到输出。单击该文件,您应该会看到如下所示的内容:

那么,伦敦东区的粉丝喜欢好莱坞吗?

伦敦东区拥有 2,491,993 名推特粉丝,其中:

  • 51.64% 也跟随加冕街、
  • 35.62% 也跟着艾默代尔,
  • 7.76% 也跟着和利时,
  • 4.21% 沿着加冕街、埃默代尔和霍利亚克,
  • 2.05% 跟随 just EastEnders 和 Hollyoaks。

分析表明,Hollyoaks 在伦敦东区粉丝的肥皂剧排行榜上排名不高……或者他们只是认为自己的推文不有趣。

你会发现什么?

快乐分析!

克洛伊👩🏽‍💻📈

Instagram: @the.numerist

Github: chloeanalyst

通过功能工程领先一步

原文:https://towardsdatascience.com/do-feature-engineering-right-c3aa2d842563?source=collection_archive---------33-----------------------

利用分类数据创建更好的模型

图片由黛博拉·布林·怀汀拍摄,来自皮克斯拜

利用分类数据创建更好的模型

机器学习模型很难解释分类数据;特征工程允许我们重新将我们的分类数据置于上下文中,以提高我们的机器学习模型的严谨性。特征工程还为数据分析提供了额外的视角层。特征工程方法解决的大问题是:我如何以有趣而巧妙的方式利用我的数据,让它变得更有用。

它是什么&它不是什么

特征工程不是清理数据、删除空值或其他类似的任务;特征工程与改变变量有关,以改善它们所讲述的故事。它是关于利用内容知识和数据探索。

分类数据的方法

垃圾箱/桶

通常,当您使用分类数据作为预测值时,您可能会发现该变量的某些级别很少出现,或者变量级别严重冗余。

您做出的任何开始对可变级别进行分组的决定都应该是战略性的。

这两种方法的良好开端是 r 中的table()函数。

我将使用 UCI 银行营销数据集,该数据集详细描述了客户的人口统计数据&营销活动是否成功。数据集可以在这里找到:http://archive . ics . UCI . edu/ml/machine-learning-databases/00222/bank . zip

这里的想法是识别记录太少的级别的出现,或者看起来更能指示数据试图传达的信息的箱。

有时一个表格更难理解,所以把它放在条形图中也很好。

bank.df %>%
   group_by(job)%>%
   summarise(n = n())%>%
   ggplot(aes(x = job, y = n))+
   geom_bar(stat = "identity")+
   theme(axis.text.x = element_text(angle = 90, hjust = 1))

为了这个练习,让我们假设我们实际上想要理解在一个给定的角色中沿着技术使用的路线的职业。在这种情况下,我们将开始相应地绑定这些职称。

你可以在dplyrmutate中使用一个漂亮的case when函数,当你重新分配一个变量的许多不同级别时,这个函数非常方便,而不是使用一些嵌套的ifelse函数。这个函数在将数值变量转换为分类数据时也非常有用。如果你想了解更多,请发表评论。

bank.df <- bank.df %>%
   mutate(technology_use = 
          case_when(job == 'admin' ~ "med",
                    job == 'blue-collar' ~ "low",
                    job == 'entrepreneur' ~ "high",
                    job == 'housemaid' ~ "low",
                    job == 'management' ~ "med",
                    job == 'retired' ~ "low",
                    job == 'self-employed' ~ "low",
                    job == 'services' ~ "med",
                    job == 'student' ~ "high",
                    job == 'technician' ~ "high",
                    job == 'unemployed' ~ "low",
                    job == 'unknown' ~ "low"))

正如您在上面看到的,我创建了一个名为“技术使用”的新字段,并根据其技术使用情况为每个字段赋值。我肯定你会为这些不同的作业争论,但是为了这个例子,我没有想太多。

现在让我们快速回顾一下这个新领域。

table(bank.df$technology_use)

round(prop.table(table(bank.df$technology_use)),2)

如何决定如何绑定

宁滨应该依赖于你试图理解的东西。比方说,工作的粒度要大得多,我们有几个营销相关的工作,CMO,营销分析师,数字营销经理等。您可能想要了解一个部门、一组技能或者只是稍微高一点的粒度级别的影响。

请务必利用表格、道具表和条形图来更好地了解如何对可变级别进行重新分类。

虚拟变量&一种热编码

假设您有一个两级分类变量,机器学习模型仍然不喜欢它,因此我们不会将默认变量级别保留为“是”和“否”,而是将它编码为虚拟变量。虚拟变量是分类变量的数字表示。任何时候 default 的值为 yes,否则我们将把它编码为 1 和 0。对于互斥的两级变量,这消除了对 no 的额外列的需要,因为它隐含在第一列中。

bank.df <- bank.df %>%    
  mutate( 
    defaulted = ifelse(default  == "yes", 1, 0))

我们已经讨论了将单个列作为虚拟变量的创建,但是我们应该讨论一次性编码。一个热编码实际上是相同的事情,但是对于许多级别的变量,其中除了值对应于新列的位置之外,列在所有行中都为 0,那么它将为 1。

caret包里的dummyVars在这里很有用。

library(caret)
dmy <- dummyVars(" ~ .", data = bank.df)
bank.dummies<- data.frame(predict(dmy, newdata = bank.df))
print(bank.dummies)

上面,我们加载了caret包,对所有变量运行 dummyVars 函数,然后根据它识别的一个热编码变量创建一个新的 dataframe。

让我们看看新桌子

str(bank.dummies)

我没有包括所有的列,但是你可以看到它只留下了年龄,然后是一个热门的编码工作&婚姻。您可以看到所有列的数据类型现在都是数字。

注意稀疏字段,并准备将宁滨方法与一种热编码进行比较,以获得更有效的结果。

组合特征或特征交叉

特征交叉是将多个变量结合在一起的地方。有时将变量组合在一起可以产生比单独使用更好的预测性能。

类似于你对宁滨的探索,将你考虑交叉的两个变量分组,并计算每个组合的数量。

bank.df %>% 
   group_by(job, marital) %>%
   summarise(n = n())

这种形象化通常更容易理解

bank.df %>% 
  group_by(job, marital) %>%
  summarise(n = n()) %>%
  ggplot(aes(x = job, y = n, fill = marital))+
  geom_bar(stat = "identity", position = "dodge") +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

要在一个步骤中完成交叉和编码步骤,您可以使用我之前向您展示的相同的dummyVars函数。

dmy <- dummyVars( ~ job:marital, data = bank.df)
bank.cross <- predict(dmy, newdata = bank.df

请记住,当您将多个变量组合在一起时,您可能会有一些非常稀疏的新值。与对任何给定的分类变量执行宁滨相似,您应该检查任何要素交叉的输出,以验证它们是否应该被预先分箱。

结论

我希望这是对 r 中使用分类变量的特征工程的一个有帮助的介绍。我们可以使用主成分分析来提高解释变量的预测能力。我将在另一篇文章中讨论这些问题。有关 PCA 的课程,请查看我在https://datasciencelessons . com/2019/07/20/principal-component-analysis-in-r/的帖子,或者查看我在https://datasciencelessons.com/的博客

祝数据科学快乐!

女大学毕业生挣钱少吗?

原文:https://towardsdatascience.com/do-female-college-graduates-earn-less-than-their-male-peers-d5bdfd3165b9?source=collection_archive---------67-----------------------

利用线性回归,我研究了美国女性大学毕业生在劳动力市场上的境遇是否比男性大学毕业生差。

杨雅筑Unsplash 上拍照

我相信我们大多数人(如果不是所有人)都听说过生活中许多领域的性别差距,包括劳动力市场。它们仅仅是没有任何根据的说法吗?在这篇文章中,我调查了受过高等教育的人——美国的大学毕业生——在就业结果方面是否存在性别差异。

简单地比较所有女性和男性大学毕业生的就业结果会给我们一个不准确的性别差距,因为男性和女性毕业生在许多方面都有所不同。我不会进行详细的解释(并冒着让每个人都睡着的风险),但一般来说,我们经常说这两个群体在可观察的特征(如种族、公民身份、雇主部门)以及不可观察的特征(如能力和动机)方面有所不同。对于这项研究,我将假设女性和男性大学毕业生仅在可观察到的特征方面有所不同,并通过使用多元线性回归来解决这些差异。回归背后的主要思想是,我们试图让女性和男性大学毕业生在可能影响劳动力市场结果的可观察特征方面彼此相似(这些是我们控制的变量),以便这两个群体更具可比性。

资料组

我使用的数据集是 2017 年全国大学毕业生调查(NSCG)提供给公众使用。NSCG 是对美国大学毕业生进行的两年一次的调查。它是由美国国家科学基金会赞助的,所以它从他们感兴趣的领域中过度取样。但是,提供调查权重是为了允许进行调整,以使样本能够代表整个人口。这些砝码用于我的研究。

关注的结果

将研究以下结果。

  • 收入:这是从一个人的主要工作中获得的收入。我利用美国劳工统计局提供的年度 CPI,对通货膨胀进行了调整,以获得实际收入。使用收入的自然对数。
  • 全职长期就业:这只适用于那些劳动力。如果一个人从事全职长期工作(每周至少工作 35 小时),则其值为 1,否则为 0。
  • 工作满意度:如果一个人对自己的工作比较满意或非常满意,则该值为 1,否则为 0。
  • 工作匹配度:如果一个人的工作与他的大学学位有一定关系或密切相关,那么这个值为 1,否则为 0。

感兴趣的样本

为了进行清晰的对比,我将样本限于那些只有一个学士学位的人。换句话说,那些继续完成研究生学位、多个学士学位或副学士学位的人被排除在我的样本之外。

战略

使用以下回归规范:

至于标准误差,我在学校类型-领域-群组水*上对它们进行聚类,这将考虑到每个聚类内的异方差性和任意相关性。聚类的一个例子是在 1971 年到 1973 年间从一所研究型大学毕业并获得计算机和数学科学领域的学位的观察结果。

我将从两个层面进行分析。

  1. 同质效应:身为女性对大学毕业生的劳动力市场结果有什么总体影响?
  2. 异质效应:女性对大学毕业生劳动力市场结果的影响在不同的研究领域有所不同吗?

控制变量

我纳入了所有可能影响劳动力市场结果的控制变量。我使用的控制变量可以分为几组。

  • 社会人口特征:年龄、种族、出生地、国籍、家中是否有孩子、父母教育水*、婚姻状况
  • 身体特征:他们是否有任何身体上的困难,是否有任何残疾
  • 学院特征:学院机构类型(基于 1994 年卡内基准则),授予学位的年份,学院的位置,专业,他们是否参加了双学位课程
  • 雇主特征:公司部门、公司规模、公司所在地

此外,我还控制了他们所属的美国社区调查队列。

结果

让我们先来看看同质效应分析的结果——对于大学毕业生来说,女性对劳动力市场的总体影响是什么?

同质效应

表 1 总结了这一分析的结果。

表 1:同质效应分析的结果

在表 1 的第(1)栏中,对收入结果的估计在 1%的水*上具有统计显著性,它表明女大学毕业生的*均收入比具有类似观察特征的男大学毕业生低 30.6%。这表明男女大学毕业生之间的收入差距相当大!

让我们看看劳动力市场的其他结果。从第(2)栏来看,该估计表明,女性大学毕业生获得全职永久就业的可能性低 9.68 个百分点。从第(3)栏来看,没有证据表明女性大学毕业生更有可能对自己的工作感到满意,因为这一估计在统计学上是不重要的。从第(4)栏来看,该估计表明,女性大学毕业生从事与其学位相关的工作的可能性要低 2.43 个百分点。然而,与收入和全职长期就业的估计数相比,这一估计数没有那么重要。

总体而言,对这一部分的分析似乎表明,与男性相比,女性大学毕业生面临更不利的就业结果。

异质效应

在这一部分,我将考虑到跨研究领域的影响异质性。我想知道在不同的研究领域,感兴趣的就业结果的性别差异是否有所不同。例如,学社会科学的大学毕业生是否存在更大的性别差距?

1。计算机和数学科学

这将包括计算机科学、数学和统计学专业的大学毕业生。表 2 总结了该分析的结果。

表 2:计算机和数学专业大学毕业生的调查结果

如表 2 所示,在这些领域,与男性大学毕业生相比,女性大学毕业生的收入低 18.4%,获得全职长期就业的可能性低 10.6%。与同质效应分析相比,收入差距似乎要小得多。

2。生物、农业和环境生命科学

这包括主修动物科学、生物学和环境科学的大学毕业生。表 3 总结了该分析的结果。

表 3:生物、农业和环境生命科学专业大学毕业生的调查结果

如表 3 所示,在这些领域,与男性大学毕业生相比,女性大学毕业生的收入低 26%,获得全职永久就业的可能性低 8.06 个百分点。

3。物理科学

这包括主修物理和化学的大学毕业生。表 4 总结了该分析的结果。

表 4:主修物理科学的大学毕业生的成绩

如表 4 所示,在这些领域,与男性大学毕业生相比,女性大学毕业生的收入低 32.7%,找到全职长期工作的可能性低 6.67%,找到与其学位相关的工作的可能性低 24.9%。

4。工程

这包括化学工程、机械工程和土木工程专业的大学毕业生。表 5 总结了这一分析的结果。

表 5:工程专业大学毕业生的调查结果

如表 5 所示,在这些领域,与男性大学毕业生相比,女性大学毕业生的收入低 25.7%,找到全职长期工作的可能性低 10.4%,找到与其学位相关的工作的可能性低 12.2%。

5。社会科学

这包括主修经济学和心理学的大学毕业生。表 6 总结了这一分析的结果。

表 6:主修社会科学的大学毕业生的成绩

如表 6 所示,在这些领域,与男性大学毕业生相比,女性大学毕业生的收入低 24.7%,获得全职长期就业的可能性低 5.74%。

6。其他理工科相关领域

这包括药学和数据处理专业的大学毕业生。表 7 总结了该分析的结果。

表 7:主修其他科学和工程相关领域的大学毕业生的结果

如表 7 所示,在这些领域,与男性大学毕业生相比,女性大学毕业生的收入低 31.5%,获得全职长期就业的可能性低 13.9%。

7。非理工科相关领域

这包括主修教育、商业、艺术和人文学科的大学毕业生。表 8 总结了这一分析的结果。

表 8:非理工科相关专业的大学毕业生的调查结果

如表 8 所示,在这些领域,与男性大学毕业生相比,女性大学毕业生的收入低 32.3%,获得全职长期就业的可能性低 9.83%。

根据表 2 至表 8 中的结果,似乎是自然科学专业毕业生的收入差距最大,计算机和数学专业毕业生的收入差距最小。然而,收入差距确实存在于所有的研究领域,这似乎是事实。对于全职永久就业,所有研究领域的估计都是显著的负值。其他科学和工程相关专业的毕业生系数最大,而学习社会科学的毕业生系数最小。对于工作匹配,只有物理科学和工程专业的毕业生的估计具有统计学意义。系数为负,这意味着学习这些领域的女性大学毕业生不太可能找到与其学位相匹配的工作。

限制

这项研究的发现依赖于这样一个假设,即女性和男性大学毕业生只是在可观察到的特征方面有所不同。这可能是不现实的,因为男女大学毕业生可能在不可观察的特征方面有所不同,如能力和动机水*。这意味着从这项研究中获得的估计值可能有偏差。也可以采用其他技术,如差异中的差异、回归不连续性或固定效应分析。此外,该数据集没有提供任何关于这些毕业生在大学表现如何的信息,与他们父母的教育水*相比,这些信息可以更好地反映他们的能力。

结论

根据这项研究,男女大学毕业生之间确实存在收入差距,差距从计算机和数学科学毕业生的 18.4%到物理科学毕业生的 32.7%不等。各行各业的女大学毕业生在获得全职长期就业的可能性方面也经历了负面影响。这是否意味着女性大学毕业生在劳动力市场面临歧视?如果我们想找出是否存在性别歧视,使用另一种叫做 Blinder-Oaxaca 分解的统计模型会更合适,这将在另一篇文章中讨论!

注:所有分析均使用 Stata 进行。可用于复制本文中所有分析的 do 文件位于 GitHub 上。

好的预测者预测的好吗?

原文:https://towardsdatascience.com/do-good-predictors-predict-well-6f237e7e757e?source=collection_archive---------36-----------------------

论假设检验与分类性能的异同。

来源: lassedesignen 通过 shutterstock (SL)

不久前,我使用 SVM 构建了一个文本分类器,我很高兴看到 98.5%的初始准确率。然而,在一些快速检查之后,我注意到我的非目标类别流行率大约是 99%。如果我预测了所有情况下的“非目标”,实际上我会观察到比我的复杂模型更高的准确性!我检查了从 SVM 中提取的最具预测性的特征,它们肯定通过了快速的健全性检查:分类器肯定得到了有价值的信号,而不仅仅是噪声。我怎么能有一个工作的分类器,但它的性能并不比偶然的好?我的困惑部分来自于我的实验背景,计算效应大小和估计统计学意义通常是定量分析的最终目标。我熟悉其他一些适用于不*衡组的性能指标,但是我对统计显著性/效应大小和分类器性能之间的关系没有很好的直觉。为了对这种关系有一些基本的了解,我模拟了几个例子,我发现这些例子提供了很多信息,我希望这些结果能够帮助其他数据科学家解决同样的问题。

假设检验对比分类任务

对于那些通过实验进入数据科学的人来说,统计推断,更具体地说,假设检验可能是应用统计学的主要焦点。在讲授统计学导论课程时,教师通常将自变量称为“预测因素”,并将重要的预测因素描述为那些能提高我们对因变量的最佳猜测的变量。例如,回归模型的一个常见直观解释是,如果我们没有显著的预测值,我们对因变量的值的最佳猜测是它的*均值,而如果我们有一组显著的预测值,我们应该根据这些预测值来调整我们的预测。虽然这一术语在许多情况下肯定是有用的(有时学术期刊的评论者特别建议避免因果语言),但它可能导致错误的预期,即强预测因素(当样本量不变时,具有大的效应大小和相应的高统计显著性)必然会提高我们对结果的最佳猜测。

更具体地,在两个变量(结果和预测)的简单情况下,显著性测试和分类任务都基于两个变量的联合概率分布。如果结果变量和预测变量是独立的,例如,对于预测变量的所有值,P(目标|预测值)= P(目标),则任何统计测试都将是不显著的,并且分类性能不会比机会好。尽管这种对联合概率分布的共同依赖,然而,统计推断和分类任务正在回答本质上不同的问题。假设检验是关于比较两种不同水*结果的预测值的概率分布。另一方面,预测是关于选择考虑(或不考虑)预测值的结果值。Lo 等人( 2015 )展示了这两个目标在一般情况下如何产生分歧;这里我们将只探讨最明显的:不*衡组(例 1 和例 2),和非线性关系(例 3)。

例 1:二元预测器和预测的不对称性

假设你正在研究肺癌和吸烟之间的关系,给你一个列联表(表 1 ),上面有这两个变量的联合分布。

表 1。肺癌和吸烟的假设频率。

显然,吸烟与肺癌之间有很强的关系,χ (1,n = 100) = 30.72,p < 10e-7, and the effect size is phi = 0.58, which in Social and Behavioral Sciences is considered large. Will this relationship be helpful for predicting the value of one of the variables based on the value of the other? Let us first try predicting if someone is a smoker based on their lung cancer status. If for every smoker we predict the presence of lung cancer, and for everyone non-smoker we predict no lung cancer, we will be correct in 75% of all cases (recall what a 混淆矩阵 为)。这比肺癌的基本发病率(50%)要好得多,因此考虑吸烟状况有助于我们改进预测。但是反过来呢?关于肺癌状况的知识是否改善了我们对吸烟的预测?基于肺癌预测吸烟状况再次导致 75%的正确预测,但这与吸烟的基础率没有区别。如果我们预测每个人都是“吸烟者”,而不考虑任何其他信息,我们在 75%的情况下仍然是正确的。细心的读者可能已经注意到这种差异来自于患病率的不同。提高我们对*衡组预测的准确性要比不*衡组容易得多。

示例 2:连续预测器

在本例中,我们仍将使用二元结果变量,但这次预测器将是连续的。它将松散地基于信号检测理论框架。假设您希望根据连续信号的值来预测目标是否存在。当目标存在时,信号呈正态分布 N(M0,σ),当目标不存在时,信号为N(M1,σ)。如果我们想要预测目标是否存在,我们可以设置一个信号阈值,如果一个观察值低于它,我们预测“没有目标”,如果它高于它,我们将预测“目标”(见图 1)。在某些情况下,当目标不存在时,我们会观察到低于阈值的信号(真阴性),然而在其他情况下,我们会做出错误的预测,因为即使目标存在,信号也可能低于阈值(假阴性)。如果我们增加阈值并将其从 1 改为 2,我们将增加 TNs 的数量(理想的),但也不可避免地会有更多的 FNs(不理想的)。

图一。一个基本的信号检测设置,我们选择一个分界点来预测目标的存在和不存在。在该设置中,TP 和 TN 是正确的预测,而 FP 和 FN 是不正确的预测。

注意,在假设检验中,我们感兴趣的是这两个分布是否相同。在分类中,我们选择一个最大化给定性能指标(如准确性)的分界点。M0 和 M1 之间的差异越大,我们就越有可能拒绝零假设,分类器就越准确。然而,与例 1 类似,在高度不*衡组的情况下,即使两个*均值相差很远(例如,通过 t 检验,差异非常显著),我们仍然会有很差的预测。我们将用图 2 所示的一系列模拟来说明这一点。

图二。二元结果和连续预测因子的准确性和效应大小之间的关系。曲线代表理想化的(*滑的)直方图。横向上,我们改变了非目标群体的患病率。在垂直方向上,我们改变组均值之间的距离(以标准差表示)。r 是点-双列相关系数,可用作效应大小的量度。Acc。是使用红色虚线作为决策阈值时达到的最大精度。

图 2 中的关键信息是,两组之间的不*衡越大,预测变量对分类的用处就越小。例如,≈ 0.3 的相关性提高了*衡组(第 2 行,第 1 列)的准确性,但它不会提高不*衡组(第 3 行,第 3 列)的准确性。虽然效应大小和显著性都受到组不*衡的影响,但预测准确性的提高受到的影响更大。

示例 3:方法相同,但精确度提高

虽然前面的两个例子说明了即使结果和预测因子之间有很强的关联,预测的准确性也不会增加,但在这个例子中,我将说明相反的情况:在变量之间没有显著关联的情况下,准确性有所提高。

想象一下,您再次看到一个二元结果(目标和非目标)和一个连续信号,如图 3 所示。你检查相关性,它是 0,你运行 t 检验,两个组的*均值之间没有显著差异。你很容易忽略这个信号,并错误地认为这个信号不能帮助我们预测结果。事实上,在这种特殊的情况下,有一个最佳的阈值将导致 58%的准确性,这是一个比原来的患病率大幅度提高。

图 3。目标和非目标群体的理想化直方图。两种分布的均值相同,但目标分布的标准差比非目标组小两倍。这两个变量之间的相关性为 0,但我们可以找到一个决策阈值,它可以提高预测的准确性,超出流行程度。

这个例子揭示了统计推断和分类任务之间的另一个重要区别。在统计推断中,我们通常测试两个变量之间特定类型的相关性。最常见的是均值、比例或相关系数大小的差异。当然,我们也可以测试方差的相等性,测试两个变量是否来自同一个分布,或者测试更高阶的关系(二次关系对于当前的例子来说尤其合适)。然而,在大多数情况下,当处理大型数据集或在时间压力下工作时,相关性和 t 检验是显著性检验的主要工具。另一方面,分类模型将较少关注特定类型的关系,并且最有可能探索多个阈值/关系。例如,如果不是像信号检测理论中那样使用单个阈值,而是运行决策树,我们将获得两个阈值而不是一个,这将获得更高的精度。

结论

这篇文章的关键信息是提供一系列简单的例子来证明分类中的统计推断和预测任务应该区别对待。您可能有很强的统计关系和很差的分类性能。你也可以有一个与弱统计关系相关的良好表现(对于一个特定的假设)。

我们在这里没有解决的是如何评估一个基于一组重要预测因子的分类器的有效性,但是它的准确性并不比患病率好。当这种情况发生时,可以使用替代的性能指标,区分不同类型的正确和不正确的预测。事实上,我们在示例 2 中使用的点-双列相关也被用作分类器的性能度量,它被称为马修系数。结果和预测之间更强的关系可能不会提高准确性,但它会改善混淆矩阵中的某些特定单元。如果某些类型的误差比其他类型的误差代价更高,那么使用预测器可能会更好,即使这会影响整体精度。然而,这超出了本文的范围,对于感兴趣的读者来说,这里有很棒的学术论文( Davis & Goadrich,2006Ferri 等人,2009 )和关于该主题的优秀文章( Fawcett,2016 )。

要点

  • 统计推断和分类都基于联合概率分布,但它们回答不同的问题。
  • 如实施例 1 和 2 所示,较大的效应大小不能保证良好的预测。
  • 从实施例 3 中可以明显看出,小/零效应大小并不排除良好的分类性能。
  • 在所有其他条件相同的情况下,强预测器(大效应大小)将比弱预测器产生更好的分类器,然而这可能不会通过增加的准确性直接捕获。重要的预测因素可能是提高其他性能指标,这可能是您关心的,也可能是您不关心的。

参考文献:

[1] Davis,j .,& Goadrich,m . Precision-Recall 和 ROC 曲线之间的关系(2006 年 6 月),第 23 届机器学习国际会议论文集(第 233–240 页)。

[2] Ferri,c .、Hernández-Orallo,j .、& Modroiu,r .分类性能测量的实验比较(2009),模式识别字母30 (1),27–38。

[3] Lo,a .,Chernoff,h .,郑,t .,& Lo,S. H .为什么显著变量不是自动良好的预测器(2015),美国国家科学院学报112 (45),13892–13897。

脚注:

1.机器学习专家可能已经注意到,我在这里使用的是最简单的性能指标,叫做准确度。准确度是正确预测的比例,并假设所有正确和所有不正确预测的权重相同。度量标准的选择是 ML 领域的一个大话题,我在这里不讨论它,尽管,无可否认地,使用准确性作为度量标准会加剧统计推断和分类性能之间的差异。

香港人还在新冠肺炎下吃饭吗?

原文:https://towardsdatascience.com/do-hong-kongers-still-dine-out-under-covid-19-9ac4bf49d4ab?source=collection_archive---------36-----------------------

事实证明,在疫情爆发期间,有一样东西可以吸引美食家

叶晨Unsplash 上拍照

整体情况

自 1 月 21 日至 1 月 22 日以来,一切都发生了变化,当时 mainland China 的情况变得非常严重,他们开始报告新冠肺炎的统计数据,出现了第一例通过高铁输入香港的“高度易感”病例。

由于这种病毒在香港越来越流行,人们倾向于减少外出就餐是很自然的。在下面的图表中,数据来自一个流行的餐厅预订应用程序,我们可以看到自 1 月下旬以来,酒店自助餐预订数量一直在下降,从 40000+的水*下降到 15000 左右。(注意:这些数字是某一时期的滚动总和,因此并不是某一天的确切预订量,但仍然显示了趋势)

不仅外出就餐的人越来越少,酒店餐厅也从该应用中退出,从 1 月下旬的 27 家餐厅减少到 3 月的 14-15 家餐厅——可能酒店预计外出就餐的人会少得多,因此为预订*台付费可能没有太大价值。

为什么是自助餐?

为什么我们要看自助餐厅的数量?

  1. 他们是预订应用程序上最受欢迎的类别之一,预订容量很高。
    = >测量误差更小
  2. 我的感觉是,自助餐没有太多的季节性,人们对它有一个相当恒定的需求,不像火锅,它更像是一种“冬季食品”。少了一个需要担心的变量
  3. 我的感觉是,在新冠肺炎的统治下,自助餐厅是一个危险的环境。与其他餐厅不同,吃自助餐的人必须步行去取食物,而酒店的自助餐厅通常会容纳很多人。
    = >所以要让 COVID 因子更敏感。如果环境不是那么危险,人们可能会像往常一样做出决定。
  4. 我相信大多数去自助餐的人会通过应用程序预订桌子(考虑到折扣),所以预订应用程序趋势很好地代表了人们去餐馆的情况。

海军部是一个异数

当按香港地区查看预订数量时,我们可以看到一个有趣的趋势。自 1 月下旬以来,几乎所有地区的房价都在下跌,只有一个例外——金钟。

自 1 月下旬以来,金钟(深蓝线)自助餐厅的预订量一直在飙升,从 2500 英镑左右升至 9000 英镑。另一方面,尖沙咀自一月以来下跌了很多。是什么造成了如此大的差异?

让我们更深入地研究一下餐厅的预订数量。下面是位于金钟的两家 JW 万豪自助餐厅。JW 咖啡馆似乎在去年 12 月暂停了一段时间,从 2 月初开始激增。自去年 11 月以来,休息室的人数一直呈上升趋势,并在 2 月底被 JW 咖啡馆超过

对于尖沙咀,我们可以看出为什么这个地区的数量下降了这么多——许多自助餐厅不再使用这个*台了!厨房(W 酒店)是*台上点击率最高的餐厅之一,于 2 月中旬退出*台。这可能是由 1 月 29 日的一条新闻引发的,该新闻报道了一名新冠肺炎患者在 1 月 22 日至 28 日期间住在 W 酒店。一些餐厅在 3 月份恢复了该*台,但自那以来趋势仍然是向下的。

尖沙咀和金钟距离地铁站仅 1 站之遥,两者相距约 7 分钟。事情怎么会如此不同?

如何?有意义的折扣

海军部

让我们看看两家金钟餐厅的折扣百分比热图:

  1. 从 2 月开始,我们可以看到这两家餐厅在午餐、茶点和晚餐期间的折扣%有了“有意义的”增加。尤其是午餐,他们只保留 1 强 13:00 时段。从他们过去很少提供超过 10%的折扣,但现在他们定期提供 30%以上的午餐折扣的意义上来说,这种增加是“有意义的”。
  2. 如果有很好的折扣,人们实际上愿意出去吃饭,即使是在自助餐的环境下!

尖沙嘴

对于尖沙咀来说,许多餐馆没有二月/三月的时间段。即使对那些有影响的人来说,他们似乎也确实对午餐/晚餐时间做出了重大改变。我想,从另一个角度来看,他们中的许多人实际上已经给出了相当好的折扣,他们可能没有太多的空间来“有意义地增加”折扣。这也可以解释辍学的原因。

关闭

原来 HKers 还是会在外面吃饭,原因是…$?

香港政府刚刚对餐馆实施了新的限制,包括限制每桌最多 4 人,并且每桌必须相距 1.5 米,这对这些餐馆经营者来说只会更糟。这些限制将如何应用于自助餐顾客?“有意义的折扣”的把戏还有效吗?

看到 JW 氏症 50%的折扣真的很令人难过,海军部的数字上升得比感染人数还快。我觉得香港人比这个强,不是吗?

编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

我需要大数据吗?如果是,有多少?

原文:https://towardsdatascience.com/do-i-need-big-data-and-if-so-how-much-ef29fc30e561?source=collection_archive---------40-----------------------

许多公司追随大数据的宣传,却不理解该技术的含义。

简·安东宁·科拉尔在 Unsplash 上拍摄的照片

我自称“大数据专家”。我已经驯服了不断增长的 Hadoop 动物园中的许多动物,如 HBase、Hive、Oozie、Spark、Kafka 等。我帮助公司使用这些技术的适当子集来构建和结构化他们的数据湖。我喜欢与来自多个来源的数据争论,以产生新的见解(或者用证据来证实旧的见解)。我喜欢为预测应用建立机器学习模型。所以,是的,我会说我在人们称之为“大数据”的许多方面都很有经验。

但与此同时,我越来越怀疑盲目地追随承诺和宣传,而不了解所有的后果,也不评估替代方案。

什么是“大数据”?

在开始讨论之前,让我先解释一下我对术语“大数据”的理解。如果你在街上问某人,他认为术语“大数据”代表什么,你可能会得到非常宽泛的答案,即“人们与计算机系统交互不断产生的大量数据,这些数据随后被用于分析个人偏好”。

“大数据”有一个众所周知的更正式的定义,它侧重于数据的三个特定方面:

  • 高容量—存储的数据量
  • 高速度—新数据到达的速度
  • 高多样性—多种格式和类型(图像、文本、结构化数据)

有趣的是,这个定义实际上只与数据本身有关,而与分析数据的过程无关。那和上面想象的答案形成了鲜明的对比,也包含了数据的用法。从我的经验来看,从公司和社会的角度来看,分析部分都是“大数据”最重要的方面。

在本文中,我想重点介绍“大数据”的技术方面,即处理大容量、高多样性以及可能的高速数据所需的软件和硬件堆栈。这既包括 Hadoop,也包括可扩展的 NoSQL 数据库,如 MongoDB、Cassandra 等。

大数据承诺

几年前,我有这样的印象,大型软件和咨询公司通过承诺从数据中创造新层次的洞察力,向客户兜售“大数据”宣传。今天,我要说的是,只有一小部分公司实际上成功实施了成功的大数据战略,大多数其他公司都失败了,或者很高兴他们没有遵循宣传。简单地想一想 Cloudera,它是构建数据湖的巨大支持者之一,它几乎破产了,尽管他们手头拥有所有的技术来生成洞察以做出正确的决策

但这种情况并不意味着大数据是无用的——我认为,大数据被严重高估了,因为它创造了一个简单按钮的期望,必须按下这个按钮才能产生新的见解。我们离这个单键解决方案还很远,甚至可能永远也不会实现。

成功创建大数据战略的公司的秘密非常简单而实际:他们没有简单地跟随宣传,而是分析他们的问题并寻找工具来解决他们的问题,并且只在有意义的地方使用大数据工具。也就是说,他们从具体的技术问题开始寻找解决方案,而不是从具体的解决方案开始寻找要解决的业务问题。

问正确的问题

在通过实施 Hadoop 和 Spark 加入“大数据”的行列之前,您应该问自己一个非常简单的问题“我实际上拥有大数据吗?”。仅仅因为你设置了一个 Hadoop 集群,你的操作系统产生的数据量不会神奇地增加。

大数据和技术

区分大数据本身(就像我上面给出的定义)和一些承诺以几乎无限的可扩展性支持您处理大数据的技术非常重要。

当然,通过组合不同来源的数据来获得新的见解,跟踪大数据的“多样性”是绝对有意义的。但是这已经需要新技术了吗?答案仅仅取决于数据量以及您当前的系统是否能够处理负载。

“大数据”技术从何而来?

为了说明什么时候使用 Hadoop 和 Spark 等大数据技术,让我们来了解一下这些技术的起源。雅虎没有启动 Hadoop 项目,只是因为他们认为它可能有用——他们启动了这个项目,因为现有的技术(可能是一些经典的关系数据库)无法再应对如此大的数据量。也就是说,雅虎达到了软件和硬件堆栈的硬限制,阻止了他们向前发展。

在这种情况下,他们决定实施一种可以更好地扩展其数据的新技术,这一点非常重要,同时他们接受失去传统数据库 90%的便利功能。他们启动了 Hadoop 项目,并获得了以下成果:

  • 数据的可扩展性
  • CPU 能力方面的可扩展性

同时,他们失去了 Hadoop 的以下功能:

  • 结构化查询语言
  • 桌子
  • 关系
  • 指数
  • 处理
  • 简单编程模型(你用过 Hadoop Map/Reduce 吗?)
  • 工具和集成

从形式上看,他们失去的比得到的多。但是别无选择,因为当时的技术已经无法处理雅虎的数据量及其伸缩需求。如果他们想继续使用他们的数据,他们没有其他选择。

当然,自从 Hadoop 出现以来,情况已经发生了变化:现在传统数据库的可伸缩性要好得多(尽管它们在这方面仍然受到限制)。另一方面,“大数据”技术也迎头赶上,例如数据湖的原子升级( DeltaLakeIceBerg )以及 SQL 支持的持续改进。所以双方(传统数据库和大数据技术)都是通过向对方学习来提高的。

逐步转向大数据

请记住,在横向扩展有意义之前,首先您实际上已经需要大数据,遵循渐进的方法通常是有意义的:不要从一开始就将所有赌注都押在大数据技术上,因为这将产生许多负面影响(下文将详细介绍)。相反,遵循敏捷思维:通过合理的开发努力让事情运转起来。如果这意味着使用 MariaDB,那么这是非常好的。如果你发现使用 Cassandra 是一个更好的长期决策,并且不会对开发成本造成太大的伤害,这也是完全合理的。但是,当您没有足够的交易量来证明这种方法时,不要试图使用 HBase 构建一个超级可伸缩的金融交易系统。

当你开始使用像 MariaDB 或 Postgres 这样的“简单”技术时,你会发现自己受到这些技术的限制,那么同样,不要立即跳到一个完全不同的堆栈上。相反,仔细分析整体情况,找出哪些场景没有按照预期执行,以及手头有哪些选项。这些可能包括将一些分析数据转移到一个更具可扩展性的 NoSQL 数据库或数据湖中。这可能还包括调查现有技术提供的可伸缩性选项。正如我在上面已经提到的,我将在下面更详细地解释,NoSQL 数据库和数据湖不是廉价的万能银弹。它们在某些用例中确实很出色,但远不如传统数据库灵活。

最佳策略是根据使用案例混合使用适当的技术:

  • 将 RDBMS 用于关系数据和主数据,如 CRM
  • 将高度可扩展的 NoSQL 数据库用于物联网事件或客户互动等高容量数据
  • 使用基于廉价存储和可扩展 CPU 能力(例如 S3 和 Spark)的数据湖进行分析

大数据技术的含义

既然我已经解释了两个世界(旧的关系型 SQL 数据库和闪亮的新大数据技术)都将继续存在,那么让我讨论一下使用大数据而不是关系型数据库的含义。

大数据的成本

大数据的东西很贵。如果你在街上随便问一个人,他们认为什么更贵:简单的数据库还是大数据,他们可能会回答“大数据”。这个术语听起来已经很昂贵了。但是尽管如此,许多公司已经为他们的 DB2 或 Oracle 数据库支付了额外的费用,显然这些系统是如此昂贵,以至于经理们无法想象“大数据”会更加昂贵。

我不知道甲骨文的许可证要花多少钱(显然是一大笔钱),但走“大数据”这条路也不便宜。首先,大多数大公司坚持使用“Hadoop 发行版”(即 Cloudera 作为唯一的幸存者),这也增加了许可成本。但不幸的是,整个故事并没有到此为止,它才刚刚开始。

当您购买传统数据库时,您会得到一个集成良好的软件包,包括存储后端、查询执行引擎、SQL 查询前端、索引、外键关系、聚合、事务等等。

当您实施大数据堆栈时,您会将 HDFS(或 S3,或 Azure Blob 存储,或…)作为存储后端,将 YARN(或 Kubernetes,或 Mesos,或…)作为集群操作系统,将 Spark(或 Map/Reduce,或 Tez,或…)作为执行引擎,将 Hive(或 Impala,或 Presto,或 Drill,或…)作为 SQL 前端,将 Solr(或 Elasticsearch)作为索引引擎,将 HBase(或 Cassandra)作为用于快速单个记录访问和事务的列存储。实际上,您得到的是一组分解的构建块,等待开发人员将它们粘合在一起,以提供传统数据库系统 20%的功能。

大数据的敏捷性

这并不意味着大数据技术是骗局,事实恰恰相反:所有这些组件都工作得非常好,并且可以很好地扩展,无论是数据量还是集群中的机器数量。每个大数据组件都是其领域的专家,但在所有相邻领域中通常完全无用。通常在一个域中有多个并发的候选项(就像 SQL 查询引擎的 Hive vs Impala vs Presto vs Drill vs Spark),每个候选项都有特定的优势和劣势。因此,你真的需要很好地理解每一项技术,作为一个好的决策的基础。

乍一看,这种情况可能看起来很可怕。我不得不承认,在开始大数据之旅时,这真的很可怕。不得不在这么多相互竞争的技术中做出选择并不容易。但是过一段时间后,你会理解基本概念,这有助于你简单地通过查看产品规格表来判断大多数产品。

一旦你到了这一步,你就会明白所有这些选项为你提供了分别选择最适合每个问题的技术的自由。这是一种与关系数据库提供的良好集成的包完全不同的方法。如果你主动意识到这个选择(而不是购买一个已经为你做好所有选择的完整的大数据包),它将为你的项目带来巨大的灵活性。

例如,我是 Spark 的忠实粉丝,它可以在没有 YARN、Mesos 或 Kubernetes 的“Spark 独立”集群上运行,甚至可以在本地机器上完全非分布式运行。最终你可以混合和匹配单个组件(如火花,普雷斯托,S3,Alluxio)来精确地满足你的要求。

结论

你的公司需要“大数据”技术吗?如果您处理的数据量越来越大,那么在某个时间点上可能是的。你能转储你的 RDBMS 吗?可能不会,除非你的公司财力雄厚,愿意接受旅途中的多次失败。你需要多少“大数据”?这取决于你的要求和你的目标。

大数据技术远不是免费的午餐。明智地选择并用于正确的任务,大数据技术可以实现新的使用案例并提升性能。你不应该在不知道暗示和你的需求的情况下简单地跟随任何宣传。对于庞大的大数据技术动物园来说,更是如此。

像实验科学家一样做机器学习

原文:https://towardsdatascience.com/do-machine-learning-like-an-experimental-scientist-35b827a70a01?source=collection_archive---------36-----------------------

开始跟踪你的实验,并变得非常高效

让我们回到几十年前。

莱纳斯·鲍林是唯一获得两次非共享诺贝尔奖的科学家,也是有史以来最伟大的化学家之一,他是一个条理清晰的人。除了其他事情之外,他还以一丝不苟地保存笔记本而闻名,其中包含他的实验、结论和想法。

在他一生的工作中,他留下了 46 本研究笔记本,这是一个令人印象深刻的数字。

鲍林并不是唯一这样做的科学家:查尔斯·达尔文、亚历山大·格雷厄姆·贝尔托马斯·爱迪生,以及他们那个时代之前和之后的几乎所有科学家。

亚历山大·格雷厄姆·贝尔笔记本中的一页。来源:国会图书馆

笔记本提供了一个很好的工具来帮助重现实验,制定假设,并得出结论。当一个实验有几个敏感的参数(如湿度、温度和植物生物学家的光照条件)时,如果不进行跟踪,复制结果是不可能的。

快进到今天。

尽管工具已经进化,实验科学家仍然在做这个。笔记本可能是数码的,但重点是一样的。

你可能会问,这跟数据科学或者机器学习有什么关系?让我解释一下。以下文件夹看起来熟悉吗?

models/
├── model_v1
├── model_v1_final
├── model_v1_final_l1_regularization
├── model_v2_adam_final
├── model_v2_final
├── model_v2_final_finetuning
└── model_v2_final_on_augmented_dataset

一个月后,事实证明model_v1_final_l1_regularization是最好的。现在你必须回去复制它。超参数是什么?最初的学习率?你用过哪个数据集?(因为从上一款的名字猜测,你有好几个。)什么是模型架构?这些都是本质问题。

如果你没有跟踪这个,你就有麻烦了。谢天谢地,你不是第一个面临这个问题的人,正因为如此,已经有了行之有效的解决方案。

记录参数和指标除了再现性之外还有其他好处。评估结果可以提供有价值的见解,了解模型如何变得更好,以及哪些超参数是重要的。最重要的是,由于大多数项目是由团队完成的,所以可以通过漂亮的图表和报告简化交流。

在您的工作流程中引入实验跟踪需要时间投入,这将在以后得到成倍的回报。改掉旧习惯需要有意识的努力,但这是值得花时间的。

如何跟踪实验

因此,您已经决定在您的机器学习开发工作流程中不仅仅使用 Jupyter 笔记本。有几种工具,从简单到复杂的全栈解决方案。

举一个具体的例子,假设您正在构建一个基于 ResNet 的分类模型。

即使不考虑模型架构产生的超参数(如卷积层学习的滤波器数量),您仍然有很多。例如,在

  • 学习率,
  • 学习速率衰减策略和速率,
  • 优化器及其参数,
  • 数据扩充方法,
  • 批量大小,
  • 时代数

都很重要,并且会影响结果。

在这篇文章中,我们将看看你可以用来跟踪你的机器学习实验的两个工具: MLFlowWeights and bias

快速解决方案:Excel 表格

在我们继续之前,我想提一下,如果你想快速实现一个解决方案,你应该在表格中记录你的实验。

我知道,手动跟踪远非最佳。记录是乏味的,如果你的笔记不够清楚,以后的解释会很困难。尽管如此,使用 Excel 表格(或 Google Sheet 或您使用的任何东西)来记录超参数和实验结果还是有很多理由的。

这个方法非常简单,你可以马上开始,不需要学习任何新的东西或者花几个小时浏览教程。你并不总是需要一个先进的解决方案,有时你只需要快速做出一些东西。打开一个 Excel 并记录下你的实验,会立刻给你的工作流程带来一些秩序。

然而,通常你需要更多。让我们看看你能用什么像 Kaggle 特级大师一样有条理!

MLFlow

第一个也是最成熟的实验跟踪工具之一是 MLFlow ,它由三个主要组件组成:跟踪项目模型

MLFlow Tracking 提供了一个交互式用户界面,用于记录超参数、指标和其他实验跟踪数据。我们将重点关注这一部分,然而,它与项目模型协同工作,前者是一种将模型轻松打包成 API 的工具,后者让您可以将模型部署到生产中。这些被设计成无缝集成,总结成一个完整的机器学习工作流程。(因此得名。)它可以与主要的机器学习框架一起使用,如 TensorFlowPyTorchscikit-learn 等。

一旦您用pip install mlflow安装了它,您就可以开始将它添加到您的代码中,而不需要任何额外的步骤。

MLFlow 在运行中跟踪您的实验。每次跑步都保存在硬盘上,您可以在交互式仪表盘中查看。要开始运行,您应该将训练代码包装到mlflow.start_run()上下文中。举个例子,它是这样工作的。

日志保存在工作目录中。要检查运行的结果,可以使用

mlflow ui

来自保存运行的同一个目录。默认情况下,用户界面可以在浏览器的localhost:5000打开。

MLFlow UI

记录数量的图表也是可用的,其中不同的运行可以相互比较。

比较 MLFlow 中运行之间的验证损失

下面是一个线性回归的教程示例。

[## 辅导的

本教程展示了如何使用 MLFlow 端到端地训练线性回归模型。

mlflow.org](https://mlflow.org/docs/latest/tutorials-and-examples/tutorial.html)

要使用 MLFlow,不必在本地记录所有实验。您可以使用远程跟踪服务器,通过使用 Databricks 上的托管 MLFlow 服务,甚至托管您自己的服务。(然而, Databricks 社区版是托管*台的免费版本,可以访问远程跟踪服务器。)

MLFlow 缺乏的一个特性是协作和团队管理。机器学习项目很少是孤立进行的,交流结果可能很困难。

总结一下,

  • MLFlow 是一个完全开源的工具,
  • 它具有管理(几乎)整个机器学习开发周期的特性,
  • 易于安装并整合到您的实验中,
  • 提供一个简单的 UI 来跟踪您的实验,您可以在本地或远程跟踪实验,
  • 但是对于远程跟踪,你要么拥有自己的服务器,要么使用 Databricks *台,
  • 此外,协作功能不可用。

*年来,人们创造了一些工具来改善用户体验,并使机器学习开发过程更加无缝。这两个工具在功能上是相似的,所以我们只挑选一个:权重和偏差工具

权重和偏差

名单上最新的应用之一是权重和偏差,或者简称为 wandb 。它也是免费使用的,但是某些功能只有付费会员才能使用。与 MLFlow 类似,它提供了一个可在线访问并实时更新的交互式仪表盘。但是,跟踪是由远程服务完成的。

有了权重和偏差,开始也非常容易,将实验跟踪添加到现有的代码库也尽可能简单。

注册后,用pip install wandb安装包,并获得您的 API 密匙,您可以通过输入

wandp login

命令行中,提示您使用密钥验证自己的身份。

现在,您已经准备好向代码中添加跟踪了!

为了简单起见,我们假设我们只有两个参数:批量大小和学习速率。首先,您必须初始化wandb对象,它将跟踪超参数并与 web 应用程序通信。

import wandbwandb.init(
    project="wandb-example",
    config=config,    # config dict contains the hyperparameters
)

这里,config字典存储了超参数,比如

config = {"batch_size": 4, "learning_rate": 1e-3}

这些会被记录下来,当稍后查看具有不同超参数的运行时,您可以在仪表板中对这些变量进行过滤和分组。

给定运行中权重和偏差的记录指标的可视化。此示例可在线探索。

设置好之后,您可以使用wandb.log方法来记录指标,比如一个时期之后的训练和验证损失:

wandb.log({"train_loss": train_loss, "val_loss": val_loss})

对该方法的每次调用都会将指标记录到交互式仪表板中。除了标量,还可以保存图像或 matplotlib 图等样本预测。

重量和偏差仪表板。这个例子可以在网上探究。

如果你使用 PyTorch,wandb.watch方法可以用来注册你的模型并跟踪它的所有参数。

Weights and Biases 收集的数据比您指定的要多得多。首先,它记录它可以访问的所有系统数据,如 GPU 和 CPU 利用率、内存使用情况,甚至 GPU 温度。

除此之外,日志中呈现的图表和可视化可用于创建研究论文质量报告,并将其导出为 pdf。它甚至支持数学公式的 LaTeX。(我喜欢这个功能。)见此例。

免费版本已经提供了大量的价值,但是如果你想访问协作和团队管理工具,你必须支付月费。

要更详细地了解这个工具,可以看看下面这篇文章,作者是 Weights and Biases 的创始人。

[## 机器学习实验跟踪

为什么实验跟踪对于进行真实世界的机器学习如此重要?

towardsdatascience.com](/machine-learning-experiment-tracking-93b796e501b0)

与 MLFlow 相比,一些功能非常突出。举个例子,

  • UI 设计精美,用户体验明显更好,
  • 默认情况下,追踪是在 web 应用程序中远程完成的,
  • 您可以创建漂亮的报告,并将其导出为 pdf 格式。

除了MLFlowWeights and bias之外,还有很多功能类似的工具。其中一些甚至超越并提供了全栈 MLOps *台。没有任何偏好,这里是其中的一些。

结论

与软件开发类似,创建机器学习解决方案不是一个线性过程。

在软件开发中,随着功能的增加,产品会不断地被测试和改进。随着用户反馈、特性请求和错误报告的涌入,工程师们经常回到绘图板,重新思考组件。

这是事情经常出错的地方。

随着每一次变化,事情都可能发生变化。可能会引入错误,事情会变得非常混乱。如果没有像 git 这样版本控制,在多个开发者之间管理一个共享的代码库是不可能的。

在机器学习中,复杂性被带到了另一个层面。不仅训练和服务模型的代码变化很快,而且模型开发本身更像是一个实验过程。如果没有专门的工具来跟踪结果,数据科学家就会迷失方向。

其中两个最好的工具是 MLFlow 套件和权重和偏差工具。根据你的需要,如果你没有花额外的时间来组织你的工作,这些可以给你介绍一个全新的世界。这些很容易学习,并带来了许多积极的东西,你不应该错过它们。

如果你喜欢把机器学习概念拆开,理解是什么让它们运转,我们有很多共同点。看看我的博客,我经常在那里发表这样的技术文章!

我的数据服从正态分布吗?

原文:https://towardsdatascience.com/do-my-data-follow-a-normal-distribution-fb411ae7d832?source=collection_archive---------5-----------------------

关于最广泛使用的分布以及如何检验 R 中的正态性的一个注记

摄影:Tra Nguyen

什么是正态分布?

T 正态分布是定义一组测量值如何围绕这些测量值的中心(即*均值)分布的函数。现实生活中的许多自然现象可以用钟形频率分布来*似,这种分布称为正态分布或高斯分布。

正态分布是一种山形、单峰和对称分布,其中大多数测量值聚集在*均值附*。此外,一个指标偏离均值越远,发生的概率就越低。从这个意义上说,对于一个给定的变量,找到接**均值的值是很常见的,但随着我们远离*均值,找到值的可能性越来越小。最后但同样重要的是,由于正态分布是围绕其均值对称的,所以分布的两个尾部都不太可能出现极值。例如,假设成年人的身高遵循正态分布,大多数成年人接**均身高,极矮的成年人和极高的成年人一样不常见。

在本文中,重点是了解正态分布、相关的经验规则、其参数以及如何计算 Z 得分以找到曲线下的概率(用示例说明)。由于这是一些统计检验的要求,我们也给出了 4 种互补的方法来检验 r 中的正态性假设。

经验法则

具有*似正态分布的数据具有明确的变化,如以下经验规则所示:

  • μ σ包括大约 68%的观测值
  • μ 2⋅σ包括大约 95%的观测值
  • μ 3⋅σ包含了几乎所有的观测值(更精确地说是 99.7%)

正态分布和经验法则(68–95–99.7%法则)

其中,μ和σ分别对应于总体均值和总体标准差。

经验法则,也称为 68–95–99.7%法则,通过下面两个例子来说明。假设已知比利时一所大学所有学生的统计学考试成绩大致呈正态分布,均值μ=67,标准差σ=9。然后可以推断,大约 68%的分数在 58 和 76 之间,大约 95%的分数在 49 和 85 之间,并且几乎所有的分数(99.7%)在 40 和 94 之间。因此,知道了*均值和标准差,我们就能很好地了解分数的分布情况。现在假设从参加考试的人中随机抽取一名大学生。她的分数在 49 到 85 之间的概率有多大?基于经验法则,我们发现 0.95 是这个概率问题的合理答案。

经验法则的效用和价值是由于自然界中普遍存在*似正态分布的测量值。比如智商,鞋码,身高,出生体重等。*似呈正态分布。你会发现,大约 95%的测量值在其*均值的 2σ以内(Wackerly、Mendenhall 和 Scheaffer,2014 年)。

因素

像许多概率分布一样,正态分布的形状和概率完全由一些参数定义。正态分布有两个参数:(I)均值μ 和(ii)方差σ^2 (即标准差σ 的*方)。均值μμ定位了分布的中心,即观测值的中心趋势,方差σ^2 定义了分布的宽度,即观测值的展宽。

均值μμ可以取任意有限值(即∞ < μ < ∞), whereas the variance σ^2 can assume any positive finite value (i.e., σ^2 > 0)。正态分布的形状基于这两个参数而变化。由于均值和方差的组合有无限多种,所以正态分布也有无限多种,因此也有无限多种形式。

例如,查看当两个参数改变时,正态分布的形状如何变化:

正如你在第二张图中看到的,当方差(或标准差)减小时,观察值更接**均值。相反,当方差(或标准差)增加时,观察值更有可能远离均值。

服从均值为 430、方差为 17 的正态分布的随机变量 x 表示为 x∞n(μ= 430,σ^2 = 17)。

我们已经看到,尽管不同的正态分布有不同的形状,但所有的正态分布都有共同的特征:

  • 它们是对称的,50%的人口高于*均值,50%的人口低于*均值
  • *均值、中值和众数相等
  • 前面详述的经验法则适用于所有的正态分布

概率和标准正态分布

正态分布的随机变量的概率和分位数可以通过函数pnorm()qnorm()使用 R 很容易地找到。使用这个闪亮的应用程序,也可以找到与正态分布相关的概率。但是,在计算概率之前,我们需要了解更多关于标准正态分布和 Z 得分的信息。

虽然正态分布有无限多种(因为均值和方差的每种组合都有一个正态分布),但我们只需要一张表就可以找到正态曲线下的概率:标准正态分布。正态标准分布是正态分布的特殊情况,其中*均值等于 0,方差等于 1。正态随机变量 X 总是可以转换为标准正态随机变量 Z,这个过程称为“缩放”或“标准化”,方法是从观察值中减去*均值,然后将结果除以标准偏差。形式上:

其中 X 是观测值,μμ和σσ是从中抽取观测值的总体的*均值和标准差。所以标准正态分布的均值是 0,方差是 1,记为 z∞n(μ= 0,σ^2 = 1)。

从这个公式中,我们看到 Z,称为标准分数或 Z 分数,允许看到一个特定的观察值与所有观察值的*均值有多远,距离用标准偏差表示。换句话说,Z 分数对应于一次观察偏离*均值的标准偏差数。正的 Z 值意味着特定的观察值高于*均值,而负的 Z 值意味着特定的观察值低于*均值。z 分数经常被用来比较一个人和她的同龄人,或者更一般地,一种与其分布相比的度量。

例如,假设一名学生在统计学考试中得了 60 分,班级的*均分数为 40 分,在经济学考试中得了 65 分,班级的*均分数为 80 分。考虑到“原始”分数,有人会说这个学生在经济学方面比在统计学方面表现更好。然而,考虑到她的同龄人,很明显,这名学生在统计学方面的表现相对好于经济学。计算 Z 分数允许考虑所有其他学生(即,整个分布)并给出更好的比较度量。让我们计算两次考试的 Z 分数,假设两次考试的分数遵循具有以下参数的正态分布:

z 分数为:

一方面,统计学考试的 Z 分数是正的(Zstat = 2.5),这意味着她比*均水*表现得更好。另一方面,她在经济学考试中的分数是负的(Zecon = 1.2),这意味着她的表现比*均水*差。为了便于比较,下面是她在标准正态分布中的成绩:

虽然经济学的分数从绝对意义上来说更好,但统计学的分数在比较每个分数在自己的分布范围内时,实际上相对更好。

此外,Z score 还能够比较观察值,否则这是不可能的,因为它们具有不同的单位。假设你想比较€的工资和公斤体重。没有标准化,就没有办法断定一个人是在她的工资方面更极端还是在她的体重方面更极端。多亏了 Z 分数,我们可以比较两个原本不可比较的值。

关于 Z 值解释的最后说明:经验法则是 Z 值在-3 和-2 之间或在 2 和 3 之间的观察值被认为是一个罕见值。Z 值小于-3 或大于 3 的观察值被认为是极其罕见的值。具有任何其他 Z 值的值被认为既不罕见也不极其罕见。

正态分布下的面积 R 和手动

现在我们已经了解了 Z 分数,我们将使用它来确定正态分布曲线下的面积。

请注意,在下面的练习中,有几种方法可以找到答案。因此,除了给出的步骤之外,您还可以使用其他步骤来获得相同的结果。

《出埃及记》一

设 Z 表示均值为 0,标准差为 1 的正态随机变量,求 P(Z > 1)。

我们实际上是在下图中寻找阴影区域:

标准正态分布:P(Z > 1)

在 R 中

pnorm(1,
  mean = 0,
  sd = 1, # sd stands for standard deviation
  lower.tail = FALSE
)## [1] 0.1586553

我们寻找 Z 大于 1 的概率,因此我们设置自变量lower.tail = FALSE。默认的lower.tail = TRUE将给出 P(Z < 1)的结果。注意 P(Z = 1) = 0 所以写 P(Z > 1)或者 P(Z ≥ 1)是等价的。

用手

看到随机变量 Z 已经有了均值 0 和标准差 1,所以不需要变换。要手动计算概率,我们需要参考下图所示的标准正态分布表:

标准正态分布表(Wackerly、Mendenhall 和 Scheaffer,2014 年)。

从表顶部的图示中,我们可以看到表中的值对应于某个 Z 上的正态曲线下的区域。因为我们正在精确地查看 z = 1 以上的概率(因为我们寻找 P(Z > 1)),所以我们可以简单地沿着表中的第一(Z)列向下,直到 z = 1.0。概率是 0.1587。因此,P(Z > 1) = 0.1587。这与我们使用 R 得到的结果相似,只是表中的值被四舍五入为 4 位数。

《出埃及记》2

设 Z 表示均值为 0、标准差为 1 的正态随机变量,求 P(1≤Z≤1)。

我们正在寻找下图中的阴影区域:

标准正态分布:P(1≤Z≤1)

在 R 中

pnorm(1, lower.tail = TRUE) - pnorm(-1, lower.tail = TRUE)## [1] 0.6826895

注意,默认情况下,*均值和标准偏差的自变量是mean = 0sd = 1。既然这是我们需要的,我们可以省略它们。 1

用手

在这个练习中,我们按步骤进行:

  1. 阴影区域对应于正常曲线下的整个区域减去曲线两端的两个白色区域。
  2. 我们知道正态分布是对称的。
  3. 因此,阴影区域是曲线下的整个区域减去曲线右尾部的白色区域的两倍,曲线右尾部的白色区域是 P(Z > 1)。
  4. 我们也知道正态曲线下的整个面积是 1。
  5. 因此,阴影区域是 1 减去 2 乘以 P(Z > 1):

p(1≤z≤1)= 1 2⋅p(z > 1)= 1 2⋅0.1587 = 0.6826

其中 P(Z > 1) = 0.1587 已在前面的练习中找到。

《出埃及记》3

设 Z 表示均值为 0,标准差为 1 的正态随机变量,求 P(0 ≤ Z ≤ 1.37)。

我们正在寻找下图中的阴影区域:

标准正态分布:P(0 ≤ Z ≤ 1.37)

在 R 中

pnorm(0, lower.tail = FALSE) - pnorm(1.37, lower.tail = FALSE)## [1] 0.4146565

用手

我们再次按步骤进行这个练习:

  1. 我们知道 P(Z > 0) = 0.5 因为曲线下的整个面积是 1,它的一半是 0.5。
  2. 阴影面积是曲线下整个面积的一半减去从 1.37 到无穷大的面积。
  3. 从 1.37 到无穷大的曲线下面积对应 P(Z > 1.37)。
  4. 因此,阴影区域为 0.5 P(Z > 1.37)。
  5. 要找到 P(Z > 1.37),请沿着表中的 Z 列向下找到条目 1.3,然后穿过表的顶部找到标有. 07 的列,得到 P(Z > 1.37)=.0853
  6. 因此,

P(0≤Z≤1.37)= P(Z > 0)-P(Z > 1.37)= 0.5 0.0853 = 0.4147

《出埃及记》四

回顾一下经验法则中的例子:假设比利时一所大学所有学生的统计学考试成绩呈正态分布,均值μ = 67,标准差σ = 9。分数的多少在 70 和 80 之间?

我们正在寻找下图中的阴影区域:

P(70 ≤ X ≤ 80)其中 x∞n(μ= 67,σ^2 = 9^2)

在 R 中

pnorm(70, mean = 67, sd = 9, lower.tail = FALSE) - pnorm(80, mean = 67, sd = 9, lower.tail = FALSE)## [1] 0.2951343

用手

提醒一下,我们要找的是 P(70 ≤ X ≤ 80)其中 x∞n(μ= 67,σ^2 = 9^2).随机变量 x 是“原始”格式,这意味着它还没有被标准化,因为*均值是 67,方差是 9^2.因此,我们需要首先使用以下公式应用变换来标准化端点 70 和 80:

标准化后,x = 70 变成(就 z 而言,因此就以标准差表示的与*均值的偏差而言):

并且 x = 80 变成:

上面用 X 表示的数字现在用 Z 表示:

P(0.3333 ≤ Z ≤ 1.4444)其中 z∞n(μ= 0,σ^2 = 1)

求概率 P(0.3333 ≤ Z ≤ 1.4444)类似于练习 1 至练习 3:

  1. 阴影区域对应于从 z = 0.3333 到 z = 1.4444 的曲线下的区域。
  2. 换句话说,阴影面积就是从 z = 0.3333 到无穷大的曲线下面积减去从 z = 1.4444 到无穷大的曲线下面积。
  3. 从表中可以看出,P(Z > 0.3333) = 0.3707,P(Z > 1.4444) = 0.0749。
  4. 因此:

P(0.3333≤Z≤1.4444)= P(Z > 0.3333)-P(Z > 1.4444)= 0.3707 0.0749 = 0.2958

与 R 中使用的概率的差异来自舍入。

总结这个练习,我们可以说,假设*均分数是 67,标准差是 9,29.58%的学生得分在 70 到 80 之间。

《出埃及记》5

参见上下文中的另一个例子

为什么正态分布在统计学中如此重要?

正态分布很重要,有三个主要原因:

  • 一些统计假设检验假设数据遵循正态分布
  • 中心极限定理指出,对于大量的观察值(n > 30),无论原始变量的基本分布是什么,样本均值和总和(Sn = ∑Xi)的分布都可以用正态分布来逼*
  • 线性和非线性回归假设残差是正态分布的

因此,知道如何检验 R 的正态性是有用的,这是下一节的主题。

如何检验正态假设

如上所述,一些统计测试要求数据遵循正态分布,否则测试结果可能有缺陷。

在本节中,我们将展示 4 种互补的方法来确定您的数据是否遵循 r 中的正态分布。

柱状图

直方图显示分布的分布和形状,因此它是评估正态性的良好起点。让我们来看看我们期望遵循正态分布的分布直方图,1,000 个成年人的身高,单位为厘米:

具有相应*均值和方差的正态曲线已添加到直方图中。直方图遵循正态曲线,因此数据似乎遵循正态分布。

在数据集iris的 R 中直方图的最小代码以下:

data(iris)
hist(iris$Sepal.Length)

[{ggplot2}](https://www.statsandr.com/blog/graphics-in-r-with-ggplot2/)中:

ggplot(iris) +
  aes(x = Sepal.Length) +
  geom_histogram()

然而,直方图是不够的,特别是在小样本的情况下,因为箱的数量极大地改变了它的外观。当观察值少于 20 时,不建议使用直方图,因为直方图并不总是正确地显示分布。请参见下面两个包含 10 个和 12 个观察值的数据集的示例:

你能说出这些数据集是否遵循正态分布吗?令人惊讶的是,两者都遵循正态分布!

在本文的剩余部分,我们将使用 12 个成年人的数据集。如果您想在自己的脚本中遵循我的代码,下面是我生成数据的方式:

set.seed(42)
dat_hist <- data.frame(
  value = rnorm(12, mean = 165, sd = 5)
)

rnorm()函数根据正态分布生成随机数(在本例中,12 个随机数的*均值为 165,标准偏差为 5)。这 12 次观察结果被保存在名为dat_hist的数据集中,变量为value。注意set.seed(42)对于获得与 me 完全相同的数据很重要。 2

密度图

密度图还提供了对数据是否遵循正态分布的直观判断。它们类似于直方图,因为它们也允许分析分布的分布和形状。然而,它们是直方图的*滑版本。这是从上面讨论的 12 个成年人的身高数据集中绘制的密度图:

plot(density(dat_hist$value))

{ggpubr}中:

library("ggpubr") # package must be installed first
ggdensity(dat_hist$value,
  main = "Density plot of adult height",
  xlab = "Height (cm)"
)

由于仅从直方图和密度图很难检验正态性,建议用 QQ 图来证实这些图。QQ 图,也称为正态图,是评价正态性的第三种方法。

QQ 图

像直方图和密度图一样,QQ 图可以直观地评估正态性假设。这是从上面讨论的 12 个成年人的身高数据中得出的 QQ 图:

library(car)
qqPlot(dat_hist$value)

## [1] 12  2

{ggpubr}中:

library(ggpubr)
ggqqplot(dat_hist$value)

不需要查看数据的分布(直方图和密度图就是这种情况),使用 QQ 图,我们只需要确定数据点是否遵循这条线(有时称为亨利线)。

如果点靠*参考线并在置信带内,则可认为满足正态性假设。点和参考线之间的偏差越大,并且它们越位于置信带之外,满足正态条件的可能性就越小。这 12 个成年人的身高似乎遵循正态分布,因为所有点都在置信带内。

当面临非正态分布时,如下面的 QQ 图所示(系统偏离参考线),第一步通常是对数据应用对数变换,并重新检查以查看经过对数变换的数据是否正态分布。应用对数变换可以通过log()函数来完成。

请注意,QQ 图也是评估回归分析的残差是否遵循正态分布的一种便捷方式。

正规性检验

上面介绍的 3 种工具是对正态性的目视检查。尽管如此,目视检查有时可能不可靠,因此也可以通过统计测试正式测试数据是否遵循正态分布。这些正态性检验将数据的分布与正态分布进行比较,以评估观察值是否与正态分布有重大偏差。

两种最常见的正态性检验是夏皮罗-维尔克检验和科尔莫戈罗夫-斯米尔诺夫检验。两种测试都有相同的假设,即:

  • H0:数据服从正态分布
  • H1:数据不符合正态分布

夏皮罗-维尔克检验被推荐用于正态性检验,因为它提供了比科尔莫戈罗夫-斯米尔诺夫检验更好的功效。 3 在 R 中,夏皮罗-维尔克正态性检验可以用函数shapiro.test() : 4 来完成

shapiro.test(dat_hist$value)## 
##  Shapiro-Wilk normality test
## 
## data:  dat_hist$value
## W = 0.93968, p-value = 0.4939

从输出中,我们看到 p 值> 0.05,这意味着我们不拒绝数据遵循正态分布的零假设。该测试与 QQ 图的方向相同,QQ 图没有显示出显著偏离正态性(因为所有点都在置信带内)。

值得注意的是,在实践中,正态性检验通常被认为过于保守,因为对于大样本量(n > 50),与正态性的微小偏差都可能导致违反正态性条件。正态性检验是一种假设检验,因此随着样本量的增加,它们检测较小差异的能力也增加。因此,随着观察次数的增加,夏皮罗-维尔克检验变得非常敏感,甚至对正态分布的微小偏离也是如此。因此,根据正态性检验,数据不符合正态分布,尽管偏离正态分布的情况可以忽略不计,但数据实际上符合正态分布。因此,通常情况下,正态性条件是基于本文中介绍的所有方法的组合来验证的,即目视检查(使用直方图和 QQ 图)和正式检查(例如,使用夏皮罗-维尔克检验)。

相对于直方图和正态性检验,我个人更倾向于 QQ 图,这样我就不用担心样本大小了。本文展示了可用的不同方法,您的选择当然取决于您的数据类型和您的分析环境。

感谢阅读。我希望这篇文章能帮助你了解更多关于正态分布的知识,以及如何检验 r 中的正态性。

和往常一样,如果您有与本文主题相关的问题或建议,请将其添加为评论,以便其他读者可以从讨论中受益。

相关文章:

参考

威克利、丹尼斯、威廉·门登霍尔和理查德·L·谢弗。2014.数理统计与应用。Cengage 学习。

原载于 2020 年 1 月 29 日 https://statsandr.com

我的回头客倾向于在第二次购买时花费更多吗?

原文:https://towardsdatascience.com/do-my-repeat-customers-tend-to-spend-more-on-their-2nd-purchase-6db1005500ff?source=collection_archive---------44-----------------------

一步一步地解决一个重大的细节层次的挑战。

今天,我在“Tableau-is-a-wonderful-tool-for-analytics-in-adding-to-visualizing-data”这一边醒来,作为挑战我的学生( 【纳亚学院】 伊斯雷尔)的持续模式的一部分,我想到了一个主意,它直接涉及 Tableau Desktop 中最具挑战性的分析主题——细节层次(LOD)。

简而言之,他们的任务是计算客户在总数中的比例,谁在第二次购买中花了更多的钱,并以单个文本数字的形式给出答案,在视图中没有维度。其灵感来源于著名的Bethany Lyons的 15 大 LOD 表达式文章(他提出了回头客的类似业务问题),以及由 Ann Jackson 撰写的 周三锻炼第 24 周挑战,她的重点是 Tableau Prep,并以不同的方式可视化答案。

以下计算基于 Tableau 给出的欧盟超市数据集样本。内容如下:

1.计算每个客户的第一个和第二个购买日期 LOD 表达式允许聚合维度数据,这些数据不一定在视图中。让我们从分类什么是第一次购买开始。这是第一次购买的语法,我们称之为第一次购买日期:

{Fixed [Customer Name]: MIN([Order Date])}

我们应该通过拖动第一个购买日期来检查自己,看看它是否忽略了订单日期字段(当客户在视图中时),如下所示,这意味着它忽略了视图中的粒度级别。

2.为了计算第二个购买日期,我们需要以不同的方式处理它。通常,如果所有的购买日期都在视图中,我会用查找函数来处理它。Bethany Lyons 用一个聪明的方法解决了这个问题,给每一个购买日期一个自己的日期,除非是第一次;因此,这将有助于我们在之后为该字段带来最小日期,即第二个购买日期。我们将这个字段称为重复购买日期及其语法:

IIF([Order Date] > [1st Purchase Date], [Order Date], Null)

将它放入视图中,就像我们之前做的那样,如下所示:

现在,正如我们对第一个购买日期所做的那样,我们可以对第二个购买日期实施相同的思路,取重复购买日期字段:

{FIXED [Customer Name]: MIN([Repeat Purchase Dates])}

3.1 日和 2 日购买日期的销售额:我们需要匹配他们的销售额进行比较。我们可以像以前一样与 IIF 职能部门沟通(常规的 IF 也可以),确定是第一天还是第二天,并分别匹配他们的销售。因为我们数据的粒度级别是购买的产品而不是订单 ID,所以我们应该合计给定的销售额,这样我们就可以在以后互相减去它。这些是第一次采购总销售额第二次采购总销售额的计算:

SUM(IIF([1st Purchase Date] = [Order Date], [Sales], 0))

SUM(IIF([2nd Purchase Date] = [Order Date], [Sales], 0))

注意——我们也可以给所有其他购买日期一个空值,而不是 0,因为总和不考虑空值。

4.如果第二次购买确实大于第一次购买,那么通过简单减去我们在条件语句中创建的最后两个字段来比较销售额将会分类。我们将命名为第二次购买更大吗?:

IFNULL(IIF[2ND Purchase Aggregated Sales] > [1st Purchase Aggregated Sales], 'Greater', 'Lower'), 'Didn''t Purchase Again')

注意——该语法包含在 IFNULL 函数中,因为他们是只有一次购买的客户;因为这些客户没有第二次购买的值,并且两个值之间的减法,如果其中一个是空值,将导致空值。为了方便起见,我们可以将他们归类为“没有再次购买”,这也是一个很好的信息。

第二次购买更大?在视图中,客户名称字段旁边的内容如下:

4.快到终点了!最后一个字段比较了两次购买,但是它没有给出我们需要的每个客户的“戳记”,而是给出了购买本身的“戳记”,并且这个字段的一个简单的过滤器用客户计数取“较大的”值是不行的,所以让我们再次汇总它,每个客户有一个状态字段 :

{FIXED [Customer Name]: [Is 2nd Greater?]}

5.以这种方式对每个客户状态进行分类后,让我们来数一数!将文本中的客户名称字段作为 COUNTD ( = COUNT DISTINCT)放入一个新表中,在过滤器中使用每个客户的状态字段,仅包括“更大的”值,将得到我们的数量(= 415 个客户,到 2019 年 12 月 31 日结束的数据集的有效数量)。但是我们试图将它与总数进行比较。为此,我们将使用额外的 LOD 表达式构建一个计算(最后但同样重要的是!)这将在过滤器之前评估客户计数,因为固定函数发生在维度过滤器之前。我们将新的计算方法命名为 %的客户在第二次订购时购买了更多:

COUNTD([Customer Name]) / MAX({COUNTD([Customer Name])})

分子代表我们的 415 个客户,而分母代表客户总数(= 795)。分母的花括号(即使没有固定的——冗余的)创建了我们需要的滤波器的旁路;但是分母包含在 MAX 函数中,因为每个 LOD 在某种程度上都是表格变量,即使没有在计算字段中指定维度,使用单个值作为聚合,它仍然算作一个表(很难理解!).最大化它(也可以是 SUM,MIN)将使它成为标量函数,因为它可以是分数的一部分,因为聚合表达式不能被 LOD 表达式除。

将新字段放入文本标记中,并将该字段格式化为带有 1 DP 的百分比,如下所示:

现在你知道了。这是衡量客户成功的一个重要指标和聪明的商业问题;当然,它还可以改进,甚至可以通过第三次购买来解决,或者甚至可以通过每位客户两次购买之间的百分比增长来衡量。但是本文的主要重点是在学生掌握了所需的 Tableau 功能和操作顺序知识后,通过实际业务示例向他们展示更高级的 LOD 挑战。但是说实话,还有一个隐藏的信息——为社区贡献知识是值得的,我希望他们也能通过阅读这篇文章学到这一课。

感谢阅读。我会很感激阅读任何评论——在我的 Linkedin 个人资料上,或者通过 alonrechavia@gmail.com。

除非在 Python 中,否则不要滥用 Try

原文:https://towardsdatascience.com/do-not-abuse-try-except-in-python-d9b8ee59e23b?source=collection_archive---------4-----------------------

光婆罗Pixabay 上的照片

试着除了有时会让你的生活变得困难

像大多数其他编程语言一样,Python 支持在运行时捕获和处理异常。但是,有时候我发现它已经被过度使用了。

原来有些开发者,尤其是 Python 新手,一旦发现这样的特性,就倾向于用 try …除了…很多。然而,我想说的是,如果可能的话,我们应该尽量避免使用它,尤其是在开发的早期阶段。你会发现,让问题显露出来,比隐藏起来更好。

在本文中,我将展示一些例子来说明“try … except …”如何产生问题,以及在 Python 编程中什么是更好的方式。

问题定义

照片由 geraltPixabay 上拍摄

先说一个有问题的例子,这是我见过的非常典型的场景。

def f1(num):
    try:
        return (num+1)*2
    except Exception as e:
        print('Error: ', e)def f2(num):
    try:
        return (num+1)*3
    except Exception as e:
        print('Error: ', e)def f3(num):
    try:
        return (num+1)*4
    except Exception as e:
        print('Error: ', e)

我们有三个函数来做一些简单的数值计算。都是用 try 实现的…除了…用 everything。然后,我们希望在代码中使用它们,如下所示。

num1 = f1(5)
num2 = f2('5')
num3 = f3(5)

请注意,我故意在第二个函数中传递了一个字符串“5”,因为我只是想人为地创建一个异常。我们得到的结果如下。

这里我们只有几行代码。或许,意识到这个问题并不太难。然而,假设你正在做一个更大规模的项目,错误消息must be str, not int对你定位问题没有太大帮助。

另一个例子

照片由 guvo59Pixabay 上拍摄

我们能从异常对象e中得到的错误信息有时非常有限。我认为在 Python 中这并不总是有意义的。事实上,前一个并不太坏,因为它至少告诉你为什么会发生错误。让我们看看这个。

def f4(key):
    try:
        d = {'a': 1, 'b': 2}
        return d[key]
    except Exception as e:
        print('Error: ', e)f4('c')

当然,在这个例子中我们只有一行代码,我们知道什么是“c”。然而,同样,如果这发生在一个项目中,如果我们只得到一个错误消息“c ”,我们如何解决这个问题呢?

最坏的情况

拉姆德隆皮克斯贝拍摄的照片

你能想象情况还能更糟吗?嗯,这个问题可能与我们的主题不是 100%相关,但我只是想提出它,因为它可能会被后面部分的解决方案解决。

如果我们把所有的代码放在 try 块中,并在 except 块中捕获所有的一般异常,你认为这样会非常安全吗?答案是否定的,不然我大概会推荐到处用:)

让我们看看这个例子。

def f5(num):
    try:
        return num*3
    except Exception as e:
        print('Error: ', e)num = f5('5')
print('Result is', num)

同样,我们定义了一个非常简单的数值计算函数,并向其中传递一个字符串。我们可能期望“异常”会被捕获,但是没有异常。

Python 太灵活了,不会有错误:)

丑陋的解决方案:回溯库

照片由 geraltPixabay 上拍摄

如果想尝试所有代码并捕捉异常,可以使用 Python 内置的traceback库。让我们使用如上所示的相同示例。

import tracebackdef f4(key):
    try:
        d = {'a': 1, 'b': 2}
        return d[key]
    except Exception as e:
        e = traceback.format_exc()
        print('Error: ', e)f4('c')

使用 traceback 帮助我们打印出关于错误的更多信息,因此我们可以更容易地解决问题。然而,我们需要导入一个额外的库并编写更多的代码来完成这个任务。

只是需要再三考虑这样做是否值得?让我们看看其他的好习惯。

解决方案 0:不要抓它

lechenie-narkomaniiPixabay 上拍摄的照片

添加这一部分是为了防止有人会说这样的话:

为什么使用 raise 或 assert?如果你根本不使用 try … except …的话,完整的回溯堆栈将会简单地显示出来!

的确,这也是我在这篇文章中想说的。正是对标题“不要滥用 try …除了…用 Python”的解决方案。我提供下面两个“解决方案”的原因只是想展示什么是好的方式。

解决方案 1:引发异常

照片由 PezibearPixabay 上拍摄

正如我前面所说的,我们应该避免使用太多的 try … except …这样会隐藏异常。相反,我们希望尽可能多地揭示异常。使用raise手动引发异常是一种很好的方式。

让我们修改我们的f1f2f3函数。

INVALID_NUM_EXCEPTION = Exception('The parameter must be integer!')def f1(num):
    if type(num) != int:
        raise INVALID_NUM_EXCEPTION
    return (num+1)*2def f2(num):
    if type(num) != int:
        raise INVALID_NUM_EXCEPTION
    return (num+1)*2def f3(num):
    if type(num) != int:
        raise INVALID_NUM_EXCEPTION
    return (num+1)*2

这里,我们定义了一个异常,并在函数中当传入的参数类型不是整数时引发它。

然后,让我们运行相同的代码来使用这些函数。

num1 = f1(5)
num2 = f2('5')
num3 = f3(5)

遇到一个错误并不太糟糕,如果它告诉你错误到底是什么,在哪里发生的。

解决方案 2:断言

照片由艾托夫Pixabay 上拍摄

尽管断言在测试中更常用,但我们仍然可以在开发过程中使用它来确保我们的代码有更少的 bug。此外,如果我们不关心确切的异常类型,使用断言通常比引发异常更简洁。

INVALID_NUM_MSG = 'The parameter must be integer!'def f1(num):
    assert isinstance(num, int), INVALID_NUM_MSG
    return (num+1)*2def f2(num):
    assert isinstance(num, int), INVALID_NUM_MSG
    return (num+1)*2def f3(num):
    assert isinstance(num, int), INVALID_NUM_MSG
    return (num+1)*2

摘要

照片由 pasja1000Pixabay 上拍摄

在编程语言中知道更多的技巧是有益的。我不得不说,每当我知道一些很酷的东西,我也会倾向于使用它。然而,它也需要再三考虑我们是否需要这样做,以及这样做是否比设置障碍给我们带来更多的好处。

因此,不要将所有代码放在 Python 中的 try … except …块中。让错误显露出来,让我们的生活更轻松!

[## 通过我的推荐链接加入 Medium 克里斯托弗·陶

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

medium.com](https://medium.com/@qiuyujx/membership)

如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和成千上万的其他作者!(点击上面的链接)

不要低估人工智能对 DevOps 的需求。进入深度学习 DevOps — DL 基础设施工程。

原文:https://towardsdatascience.com/do-not-underestimate-the-need-for-devops-in-ai-319077e2909?source=collection_archive---------20-----------------------

https://unsplash.com/photos/Zeu57mprpaI

你为什么要在乎?

随着机器学习越来越成熟,构建支持运行这些工作流的基础设施的需求就更大了。在一个大型企业中,*均至少有 200 多名数据科学家/DL/ ML 工程师在进行他们的模型训练和推理工作。确保这些用户能够方便地使用硬件/软件来训练他们的模型是非常必要的。这听起来像是一个简单的任务,我在这里告诉你它不是。

有多重挑战。例如:

  • 对于数据科学家来说,运行作业的抽象和硬件访问的简易性非常重要。
  • 不同的用户有不同的硬件和软件要求。一些用户使用 Tensorflow 训练他们的模型,而一些用户使用 Pytorch,其他用户使用他们自己内部构建的框架。
  • 一个团队使用大规模 BERT 甚至 图灵-NLG 据我们所知,分别使用 16 个或 256 个 V100s 来训练他们,而另一个团队使用预先训练好的 EfficientNet 和两个 T4 GPU。所有这些都是假设,但你得到了要点。不同的团队需要不同数量的 GPU、FPGAs、CPU、TPU 甚至IPU
  • 如何管理和维护这些资源?
  • 谁实际上保留了对这些硬件资源的控制权?是数据科学家还是 DevOps 团队?
  • 谁设置作业的优先级(作业是您想要在硬件上运行的任何东西,例如,培训、推理等。)?
  • 如何保持资源分配的合理性?我们都知道每个人都希望他们的模型先被训练。
  • 如何支持不知道充分利用分配给他们的资源的数据科学家——例如,他们跨 32 个 GPU 的 GPU 利用率低于 25%?
  • 如何处理安全问题—例如,确保只有需要的用户才能访问?
  • 如何确保所有加速器和节点都得到有效利用,同时又不会显著降低性能?
  • 谁来帮助数据科学家分析他们缓慢的应用程序?这有时是一个问题,因为数据科学家不一定建立最有效的模型训练管道。换句话说,数据科学家不是软件工程师。
  • 一些作业是一个依赖链:也许他们使用并行服务器-工作器架构,其中一些工作器必须在其他工作器之前被启动,如何处理它们来维护队列?
  • 谁安装和维护新工具-例如, MLFlowKubeFlowPolyaxonSeldonPachydermDomino Data LabArgo 等。最快下个月就会到来。
  • 如果这些问题还不足以引起麻烦,考虑安装和维护硬件级驱动程序,例如 CUDA 驱动程序、新的软件包等。
  • 数据科学家遇到的一些错误是 ML 库特有的,例如, NCCL 环形拓扑问题。典型的数据科学家可能不会接触到这些问题。
  • 处理部署和支持推理作业是另一个需要自己的基础设施团队的任务。

这篇文章没有完全提到将模型从开发转移到推理的问题。正如你所想象的,这本身就是一个问题,这些问题是大局的一部分。我们暂时把它放在一边。

一个典型的 DevOps 工程师不一定具有支持一些特定于 ML 库的问题的专业知识。另一方面,数据科学家本身并不是管理大规模集群的专家,将大型集群交给数据科学家也不是一个好主意。那么以上是谁做的工作呢?此时,你可能会想,“嗯…这听起来很像一个系统管理员的角色”,在某种程度上,的确如此!然而,由于这需要了解 ML 概念,因此需要有人是 SysAdmin+ML Engineer = EnterML/DL 基础架构工程师并且随着大型本地集群一起添加的通常是 HPC

结论

DL 基础设施工程师负责管理和维护集群。当您从云迁移到本地时,情况更是如此。在未来(不完全是,我们已经看到它正在发生),我们将能够看到一个基础设施分支,它迎合了解 ML 和 DevOps 概念的数据科学家。这样,让科学家做他们的科学,让基础设施工程师做他们的 DL 基础设施;)

不要像这样使用决策树

原文:https://towardsdatascience.com/do-not-use-decision-tree-like-this-369769d6104d?source=collection_archive---------26-----------------------

geraltPixabay 上拍摄的照片

展示 ID3 中信息获取的局限性以及使用 C4.5 的优势

作为最流行的经典机器学习算法之一,决策树在可解释性方面比其他算法更直观。在我以前的一篇文章中,我介绍了决策树模型的基本思想和机制。它使用一种称为 ID3 的算法演示了这种机器学习模型,ID3 是训练决策树分类模型的最经典的算法之一。

[## 出去锻炼还是不锻炼?让数据科学来决定

决策树机器学习算法简介

towardsdatascience.com](/go-out-for-exercise-or-not-let-data-science-decide-34f8f28ce7b4)

如果您对决策树不是很熟悉,强烈建议您在阅读本文之前先看看上面的文章。

要直观地理解决策树,从 ID3 开始确实不错。但是,在实践中使用它可能不是一个好主意。在本文中,我将介绍一种构建决策树模型的常用算法— C4.5。

经典 ID3 算法的缺点

照片由艾托夫Pixabay 上拍摄

在我们演示 ID3 算法的主要缺点之前,让我们先来看看它的主要构件是什么。基本上,重要的是熵和信息增益。

熵概述

这是熵的公式:

集合“ X ”是节点集合中的一切,“ xᵢ 是指每个样本的具体决策。因此,“【p(xᵢ】)”是用某个决策做出的集合的概率。

让我们以同一个训练数据集为例。假设我们的决策树中有一个“天气=下雨”的内部节点。可以看出,最后的决定都是“否”。然后,我们可以很容易地计算这个节点的熵,如下所示:

基本上,回答“否”的概率是 2/2 = 1,而回答“是”的概率是 0/2 = 0。

信息增益概述

在熵的概念之上,我们可以计算信息增益,这是决定一个特征是否应该作为要分裂的节点的基本标准。

比如我们有三个特征:“天气”、“温度”、“风力等级”。当我们开始使用 ID3 构建决策树时,我们如何决定哪一个应该被用作根节点呢?

ID3 使用信息增益作为标准。规则是,在所有特征中选择具有最大信息增益的特征。下面是计算信息增益的公式:

在哪里

  • “T”是父节点,“a”是“T”的属性集
  • 符号“|T|”表示集合的大小

使用相同的例子,当我们计算“天气=下雨”的信息增益时,我们还需要考虑它的子节点的熵。具体的推导和计算过程可以在引言中分享的文章中找到。

使用信息增益的主要缺点

使用信息增益作为确定将哪个特征用作根/下一个节点的标准的主要缺点是,它倾向于使用具有更多唯一值的特征。

但是为什么呢?让我用一个极端的场景来演示一下。比方说,我们的训练集多了一个特性:“日期”。

你可能会说,在这种情况下不应该考虑“日期”这个特征,因为直觉上它对决定我们是否应该出去跑步没有帮助。是的,你说得对。然而,实际上,我们可能有更复杂的数据集要分类,我们可能无法理解所有的特征。因此,我们可能并不总是能够确定一个特性是否有意义。在这里,我将用“日期”作为一个例子。

现在,让我们计算“日期”的信息增益。我们可以开始计算其中一个日期的熵,比如“2020–01–01”。

因为每个日期只有一行,所以最后的决定必须是“是”或“否”。所以,熵一定是 0!就信息理论而言,这相当于说:

日期没有告诉我们任何事情,因为结果只有一个,这是确定的。所以,根本不存在“不确定性”。

类似地,对于所有其他日期,它们的熵也是 0。

现在,让我们计算日期本身的熵。

哇,与其他功能相比,这是一个相当大的数字。所以,我们现在可以计算“日期”的信息增益了。

不出所料,“日期”的信息增益就是它本身的熵,因为它的所有属性的熵都是 0。

如果我们计算其他三个特征的信息增益(您可以在引言中链接的文章中找到详细信息),它们是:

  • 天气的信息增益为 0.592
  • 温度的信息增益为 0.522
  • 风级的信息增益为 0.306

显然,迄今为止的信息增益远远大于其他的。此外,可以看出,如果训练数据集更大,它甚至会更大。之后,别忘了“日期”这个特征实际上在决定我们是否应该出去跑步时没有意义,但它被决定为“最好”的一个作为根节点。

更有趣的是,在我们决定使用“日期”作为我们的根节点后,我们就完成了:)

我们最终得到如上所示的决策树。这是因为“约会”这个特性太好了。如果我们把它作为根节点,它的所有属性都会简单的告诉我们是否应该出去跑步。没有必要具有其他特征。

Pixabay 上的 Clker-Free-Vector-Images 拍摄的图像

是的,你此刻可能有一张像这条鱼一样的脸,我也有。

修复信息增益限制

照片由 jarmolukPixabay 上拍摄

ID3 算法中存在的信息增益限制的最简单解决方案来自另一种称为 C4.5 的决策树算法。减少这一问题的基本思想是使用信息增益比而不是信息增益。

具体来说,信息增益比是简单地通过除以父节点的熵在信息增益上添加惩罚。

换句话说,

因此,如果我们使用 C4.5 而不是 ID3,特性“日期”的信息增益比将如下。

与其他特性相比,它确实是最大的一个,但是不要忘记我们实际上是在使用一个极端的例子,特性“Date”的每个属性值只有一行。在实践中,信息增益比将足以避免信息增益将导致偏差的大多数情况。

C4.5 的其他改进

silviaritaPixabay 上拍摄的照片

在我看来,使用信息增益比是从 ID3 到 C4.5 最显著的改进。尽管如此,在 C4.5 中还有更多你应该知道的改进。

悲观错误修剪

如果您不熟悉决策树的“修剪”概念,您可能需要再次查看我之前的文章,该文章附在本文的介绍中。

PEP 是 C4.5 中的另一个重大改进。具体来说,它将以自顶向下的方式修剪树。对于每个内部节点,该算法将计算其错误率。然后,尝试剪枝这个分支,比较剪枝前后的错误率。因此,我们决定是否应该保留这个分支。

PEP 的一些特征:

  1. 这是后剪枝方法之一。
  2. 它在不依赖验证数据集的情况下修剪树。
  3. 通常很好地避免了过度拟合,从而提高了未知数据的分类性能。

离散化连续特征

C4.5 支持连续值。所以,我们并不局限于拥有“低”、“中”、“高”这样的分类值。取而代之的是,C4.5 会自动检测能够产生最大信息增益比的连续值的阈值,然后使用该阈值分裂节点。

摘要

照片由贝西Pixabay 上拍摄

在本文中,我解释了 ID3 不理想的原因。主要原因是它使用的标准-信息增益-可能会明显偏向那些具有大量不同值的特征。

另一个名为 C4.5 的决策树算法中给出了解决方案。它改进了信息增益与信息增益的比率,这将减少属性的大量不同值的影响。

同样,如果你觉得需要更多关于决策树的上下文和基础知识,请查看我以前的文章。

[## 出去锻炼还是不锻炼?让数据科学来决定

决策树机器学习算法简介

towardsdatascience.com](/go-out-for-exercise-or-not-let-data-science-decide-34f8f28ce7b4) [## 通过我的推荐链接加入 Medium 克里斯托弗·陶

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

medium.com](https://medium.com/@qiuyujx/membership)

如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和成千上万的其他作者!(点击上面的链接)

不要在 Python 中使用“+”来连接字符串

原文:https://towardsdatascience.com/do-not-use-to-join-strings-in-python-f89908307273?source=collection_archive---------0-----------------------

照片由 tcausleyPixabay 上拍摄

使用“+”和 join()方法在 Python 中连接字符串的方法比较。

当我开始使用 Python 的时候,使用加号运算符+来连接字符串是非常直观和容易出来的,很多编程语言都是这样做的比如 Java。

然而,很快我意识到许多开发人员似乎喜欢使用.join()方法,而不是+。在本文中,我将介绍这两种方法之间的区别以及为什么不应该使用+

开始

照片由戴恩·托普金Unsplash 上拍摄

作为一个初学者,或者刚刚从使用+连接字符串的其他语言转换过来的人,编写这样的代码是非常容易的:

str1 = "I love "
str2 = "Python."print(str1 + str2)

随着您越来越多地使用 Python,您可能会意识到其他人更喜欢像这样使用join()方法:

str1 = "I love "
str2 = "Python."print(''.join([str1, str2]))

老实说,当我第一次看到上面的方法时,我认为这不直观,而且看起来有点难看。

连接多个字符串

照片由 Tim BooteUnsplash 上拍摄

然而,有一次我需要在一个列表中连接多个字符串。

strs = ['Life', 'is', 'short,', 'I', 'use', 'Python']

最初,我是这样做的:

strs = ['Life', 'is', 'short,', 'I', 'use', 'Python']def join_strs(strs):
    result = ''
    for s in strs:
        result += ' ' + s
    return result[1:]join_strs(strs)

在这个例子中,我必须编写一个 for 循环来逐个连接字符串。此外,结果字符串需要修剪一个我在开始时添加的空格,因为所有的字符串都需要在前面添加一个空格,但不是第一个。您可能有其他解决方案,例如向 for 循环添加一个索引,这样索引= 0 处的字符串就不会添加这个空白。无论如何,你仍然需要这个 for 循环,并为空白做一些事情。

之后,我想起我以前见过.join()方法,也许这是我需要使用它的时候了!

def join_strs_better(strs):
    return ' '.join(strs)join_strs_better(strs)

多简单啊!一行代码完成所有工作。因为.join()方法是由一个字符串对象调用的,字符串对象将被用来连接列表中的每个字符串,所以你不需要担心开头的空格。

但是等等,你真的认为这是我们需要使用join()方法而不是+的唯一原因吗?不,请阅读下一节。

join()方法背后的逻辑

迈克尔·泽兹奇在 Unsplash 上拍摄的照片

现在,让我们比较这两种方法的性能。我们可以用《朱庇特笔记本》的神奇方法%timeit来评价他们。

上面显示的性能基于 100k 次试验,因此结果非常有把握且显而易见。使用join()方法可以比使用+连接列表中的字符串快 4 倍。

为什么?

这是我画的一个概念图,用来演示使用+连接字符串的方法。

使用+运算符和 for-loop 连接列表中的字符串

这显示了 for 循环和+操作符的作用:

  1. 对于每个循环,从列表中找到字符串
  2. Python 执行器解释表达式result += ' ' + s并为空白空间' '申请内存地址。
  3. 然后,执行程序意识到空白需要用一个字符串连接,所以它将为字符串s申请内存地址,这是第一个循环的“生命”。
  4. 对于每个循环,执行器需要申请两次内存地址,一次是空白,另一次是字符串
  5. 内存分配有 12 倍

然而,对于join()方法发生了什么?

使用“join()”方法连接列表中的字符串

  1. 执行程序将计算列表中有多少字符串。有 6 个。
  2. 这意味着用于连接列表中字符串的字符串需要重复 6–1 = 5 次。
  3. 它知道总共需要 11 个内存空间,所以所有这些都将立即应用并提前分配。
  4. 按顺序排列字符串,返回结果。

因此,显而易见,主要区别在于内存分配的次数是性能提高的主要原因。

想象一下,使用join()方法将 6 个字符串连接在一起已经快了 4 倍。如果我们要连接大量的字符串呢?这会产生更大的不同!

摘要

照片由利亚姆·布里斯Unsplash 上拍摄

在这篇短文中,我比较了在 Python 中连接字符串时+操作符和join()方法之间的区别。显然,join()方法因其性能而更受青睐。

学习一门编程语言通常是一条很长的曲线,但 Python 让它对于初学者来说相对较短,这绝对是很棒的。我们进了门之后,开始使用 Python,我们不应该止步于此,满足于我们能用 Python 做什么。通常情况下,高手和普通开发者的区别来自于细节方面的知识。

让我们继续寻找更多关于 Python 的技巧,让自己更接* Python 大师!

[## 阅读克里斯托弗·陶的每一个故事(以及媒体上成千上万的其他作家)

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

medium.com](https://medium.com/@qiuyujx/membership)

如果你觉得我的文章有帮助,请考虑加入中等会员来 支持我和其他成千上万的作家! 点击上面的链接。

他们想要数据科学家…还是应声虫?

原文:https://towardsdatascience.com/do-they-want-a-data-scientist-or-a-yes-man-a5d0dceb97f7?source=collection_archive---------41-----------------------

图片来自 Unsplash

我从一个从事数据科学的朋友那里听到了一个有趣的故事。让我们叫他鲍勃。

Bob 为一家中型创业公司工作,该公司销售自助订阅产品,价格浮动很大,有些客户的花费是其他客户的 10 倍。鉴于这部分业务的增长,在营销团队中成立了一个客户成功团队,以处理花费更多的客户。

一天,客户成功经理找到 Bob,请求他帮助分析正在运行的 AB 测试。客户成功经理正在进行一项实验,在该实验中,一半注册了每月 100 美元以上订阅的新客户会接到客户成功团队的电话,而另一半则不会。这是一项测试,旨在了解客户成功入职在防止*台流失方面有多有效。

鲍勃分析了实验,但发现了几个问题。一个是他们在测试运行的那个月没有很多注册。每个桶中只有大约 50 个客户购买了超过 100 美元/月的新订阅。在控制组中,有八个顾客发生了骚动,然而在测试桶中,每个顾客都接到一个来自成功顾客的电话,只有一个顾客发生了骚动。

“哇看起来差别太大了!”,客户成功经理感叹道。鲍勃重申,这是一个低样本量,他们不能做出任何真正的假设。但是客户成功经理提到,他们的老板营销总监给他们施加了一些压力,要求他们展示一些成果,表明他们的团队正在取得进展。他能告诉他他们的策略正朝着正确的方向发展吗?

鲍勃同意,推动他们的团队前进可能是最好的。他不想拘泥于看似有希望的方向。

然后所有人都在周五到达。全公司聚集在一起回顾过去几周的进展。首席收入官正在展示本周的新收入数字,他停顿了一下,然后结束了讲话。

“……以及我们产品部门的巨大收益。在我们的营销和客户成功团队的不断努力下,我们的最高价值客户现在已经将每月流失率降低到仅 2 %!!"

全公司的掌声。所有人都很惊讶。鲍勃坐在那里,对实际发生的事情完全目瞪口呆。

F 或者任何在分析领域工作过的人,鲍勃的故事并不奇怪。这可能很难相信,但是一个公司产生的每一个数字、统计、度量都可能是完全错误的。唯一免于此的数字是收入,它由会计和财务部门进行审计。

如此不准确的其他指标是如何渗透到整个组织中的?对鲍勃来说,这是一场电话游戏。Bob 对客户成功说了一些话,然后客户成功对营销总监说了一些更好的话,然后营销总监在他们与 CRO 的一对一谈话中提到“哦,你永远也猜不到我们上周做了什么……”

但很多时候,这也是通过组织数据文化如何影响数据科学家和分析师如何提供价值而产生的影响。公司通常可以通过两种方式实现数据驱动。

一种方法是通过使用数据来驱动决策,决定构建哪些功能以及产品的发展方向。第二种方式是公司使用数据和指标来验证高级管理层的现有意见。这是自上而下和自下而上的产品决策方法的区别。如果您的公司采用自上而下的方法制定决策,为什么还要雇佣数据科学家呢?

当你为一个<10 person startup where your CEO makes decision based on customer research and intuition in the product space. When a small startup needs to release something like a new landing page, AB testing is forgone by available engineering time. If there is AB testing, then you as the data scientist will run a query, walks over to the CEO’s desk, and tell them what the results are.

This does not happen at a company with > 100 人工作时,自上而下的决策是有意义的。现在你的首席执行官不再关注每一个细节。现在你们中间有一个哈佛 MBA 的主管,登陆页面比一个专注于设计的工程师连续两天都要花更多的时间;现在有了冲刺计划,有了喝咖啡的休息时间,有了设计团队的投入,有了前端工程师抱怨该用哪个框架。

在展示了缺乏通过新的登录页面转化更多客户的统计意义后,主管可能会不相信你的分析,也不会购买你的分析。主管建议你用不同的方式来分析,让他们的团队看起来不只是在不会增加收入的事情上花费了四周时间。即使你仍然说没有变化,他们也可能会发布新的登录页面,因为转化率并没有下降?!

这种与办公室政治相结合的组织文化可能是为数据科学家提供影响实际产品决策的方法的头号杀手,也就是说,做他们的工作!很多时候,这是因为从分析中获得的见解会影响组织中除了负责分析的数据科学家 T2 之外的其他员工。数据科学家被视为数据中事实上的证据,如果产品功能由于无数因素而实际上不起作用,所有与产品功能相关的员工都将受到结果的影响。因此,糟糕的指标会像极权国家的告密者一样被压扁。没有人希望在产品中看到不好的指标,并且没有人希望成为坏消息的传递者

鉴于数据科学家在提出见解方面的力量,数据驱动文化的重要性现在变得非常重要。用直觉使产品变化合理化比编造数字解释来证明成功更有意义。无论结果如何,当数据科学团队的任务是分析数据以获得确定的结果时,他们的动机会发生什么变化?

最终,Bob 公司的首席收入官意识到,当他们的公司在下个月没有看到 500%的收入增长时,这些指标是错误的。而鲍勃自己也觉得很奇怪,两个月后导演也悄悄走了。

如果您的组织在招聘数据科学家、数据分析师或机器学习工程师方面存在问题,我很乐意 了解更多相关信息 否则,如果你是一名面试数据科学家,请访问 面试查询 查看我们的数据科学面试准备简讯。

原载于https://www.interviewquery.com

做这个额外的步骤,你就做了一个一般化的机器学习模型

原文:https://towardsdatascience.com/do-this-additional-step-you-have-made-a-generalize-machine-learning-model-9d85b7e09313?source=collection_archive---------57-----------------------

Jukan Tateisi 在 Unsplash 上拍摄的照片

只是一个额外的步骤,它可以增加我们对预测未知数据的模型的信心。

想象一下,你正在做一些机器学习项目,并且你已经计算了指标。假设您的度量标准,在示例准确性中,大约是 90%,并且您已经基于 k 倍交叉验证计算了它。当您训练模型时,您通过拆分训练和测试数据来训练模型,因此您训练模型,然后使用我们制作的模型直接测试它。因为它不可推广,所以我们引入了 k 倍交叉验证的概念,这是通过 k 次对训练和测试数据进行不同的采样。由于使用了这种方法,模型开始变得更具普遍性,并在此基础上具有良好的准确性。

你确定吗?

模型如何处理不存在的看不见的数据呢?

如果模型是基于交叉验证分数而不是基于看不见的数据那么好呢?

这就是保留数据集概念的由来。什么是拒绝数据集?保留数据集是在我们使用交叉验证时不用于训练模型的数据集。因此,不用于交叉验证的数据集将成为看不见的数据。因此,这个数据集将增加我们的信心,证明我们的模型可以准确地预测看不见的数据,也更具普遍性。

交叉验证和保留数据集的图示

根据这个定义,我们知道拒绝数据集是我们分割的数据,这样一个可以用于交叉验证,然后另一个可以用作看不见的数据。现在的问题是我们如何在我们的模型上应用这个概念?我已经有了一个例子,我将向您展示如何使用 Python 应用保留数据集概念。

履行

第一步是将数据拆分为训练和测试数据。训练数据将被用于交叉验证,而测试数据将被用作看不见的数据。然后,拆分数据后,我们可以对训练数据进行交叉验证,您可以调整想要使用的 k 值。最后,我们可以对看不见的数据进行预测,我们可以看到模型的得分。执行这些操作的代码如下所示,

from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.pipeline import make_pipeline
from sklearn.model_selection import GridSearchCV, train_test_split
from sklearn.metrics import classification_report, confusion_matrix**# Split the X and Y**
X = df_preprocessed.drop(default, axis = 1).values
y = df_preprocessed[default].values**# Split the dataset for cross validation and unseen data**
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42, stratify=y)**# Doing Hyperparameter Tuning and Cross Validation without the 
# unseen data using Decision Tree. Then, fit the model on it**
param_grid = {
    'max_depth': [i for i in range(3, 10, 2)]
}
dt = DecisionTreeClassifier(random_state=42)
clf = GridSearchCV(dt, param_grid, cv=5)
clf.fit(X_train, y_train)**# Predict the unseen data and print the score** y_pred = clf.predict(X_test)
clf.score(X_test, y_test)
classification_report(y_test, y_pred)

基于上面的实现,我在测试数据上获得了大约 88.3%的准确率。这意味着该模型得分很高,能够处理看不见的数据。此外,当我们使用 classification_report 函数创建分类报告时,结果如下所示:

我们要预测的主要标签是 1,它有 92%的准确率和 71%的召回率。该模型还可以通过调整超参数以及进行一些特征选择和工程来改进。如果你想看看我在这方面的工作,你可以在这里看到我的 GitHub

结论

如你所知,拥有一个可概括的模型非常重要,因为我们将预测以前从未存在过的数据。通过执行这一额外的步骤,即拆分数据以进行交叉验证和保留,也许我们的模型没有任何改进,但我们可以增加我们的信心,即我们的模型可以通过使用这些数据来准确预测未知的数据。

感谢您阅读我的文章,您也可以在下面查看我以前的文章:

** [## 更高的准确性并不意味着更好的机器学习模型性能

我们可以定量地衡量机器学习模型的性能,但不仅仅是准确性,还有很多…

towardsdatascience.com](/greater-accuracy-does-not-mean-greater-machine-learning-model-performance-771222345e61) [## 如果我有自己的时间,我会这样学习数据科学

感觉不知所措和筋疲力尽让我在释放数据科学技能方面表现不佳。这个…

towardsdatascience.com](/this-is-how-i-will-learn-data-science-if-i-got-back-my-own-time-e9148c909ce9)**

美国大学城的*均房价在衰退期间受影响较小吗?

原文:https://towardsdatascience.com/do-university-towns-in-us-have-their-mean-housing-prices-less-effected-during-recession-e612e9808cf3?source=collection_archive---------63-----------------------

在这篇文章中,我使用 Python 的 PandasSciPy 库来测试一个假设,该假设指出,与非大学城相比,美国大学城的*均房价受经济衰退的影响较小。

大学城是众所周知的大学生占城市总人口比例很高的城市。SciPy 著名的 t_test 可以用来比较衰退开始前一个季度大学城的*均房价与衰退底部的比率。同样的测试也适用于非大学城,之后我比较了两个结果列表的*均房价值,以确定差异(如果有的话)。

在我们深入研究手头的数据集之前,我觉得有必要澄清一些术语,以免随着文章的进展而陷入混乱。

  • 季度是特定的三个月期间,Q1 是一月到三月,Q2 是四月到六月,Q3 是七月到九月,Q4 是十月到十二月。
  • 衰退的定义是从连续两个季度的 GDP 下降开始,到连续两个季度的 GDP 增长结束。
  • 衰退底部是衰退中 GDP 最低的一个季度。

数据源

Zillow 数据站点包含美国的住房数据。我们特别需要城市级别的住房数据,这些数据可以在名为City _ Zhvi _ all homes . CSV的数据文件中找到

接下来,我们需要美国所有大学城的列表,可以在维基百科上找到。这些数据存储在一个名为 university_towns.txt 的文本文件中。

最后,从经济分析局的网站中,我们按季度提取美国的 GDP 数据,并将其存储在一个名为 gdplev.xls. 的文件中。

数据清洗&数据提取

获取大学城数据

在整理好各自文件中的数据后,我们必须根据美国的对每个大学城进行分类。university_towns.txt 文件包含该州的数据。以下是存储在该文件中的信息:

从上面的片段中,可以推断出州名是前面带有'【编辑]' 字符串的州名,而其下的其余名称(直到下一个州名)是该州的大学城。我们必须提取州名及其给定的地区名,并将它们存储在数据帧中。应该是["State "," RegionName"],而 DataFrame 的一般格式应该是这样的:[ ["Michigan "," Ann Arbor"],["Michigan "," Yipsilanti"] ]。

遍历文本文件的每一行,我提取相关信息并设法以 DataFrame 的形式存储它,如下所示。这个名为 unidata 的数据帧的形状是(517,2):

发现衰退开始季度

接下来,我们必须设计一种方法来提取衰退开始的季度,衰退结束的季度,以及衰退期间的底部。如上所述,与 GDP 相关的数据存储在 gdplev.xls 中。下面是该文件的预览:

可以看出,很难从这个数据帧的当前形状中推断出任何有意义的信息。未命名的列 4 表示季度,而接下来的两列表示特定季度中各自的 GDP。出于本文的目的,我们限制自己只考虑 2000 年以后的季度,并使用 2009 年美元的环比值。因此,我们跳到第 219 行,即 2000 年的第一季度,并删除除第 4 列和第 6 列之外的所有列。

如介绍性段落中所述,衰退被定义为以连续两个季度的 GDP 下降开始,以连续两个季度的 GDP 增长结束,因此出现了 for 循环。经过清理和重新排列的数据帧如下所示:

将 get_recession_start()函数的返回值更改为 result 将为我们提供衰退期开始的季度。在这种情况下,是 2008 年第三季度,即 2008 年的第三季度。

发现季度末的衰退

然后定义一个名为 get_recession_end 的类似函数来查找衰退结束的季度。除了所选的索引发生了变化之外,逻辑基本保持不变。2009 年第四季度作为衰退结束季度返回。

发现衰退底部季度

衰退底部是指经济衰退期间 GDP 最低的季度。虽然,找到衰退的底部并不能帮助我们证明给定假设的正确性,但出于教育的目的,我还是会继续下去。get_recession_bottom()函数返回 2009 年第二季度,考虑到本季度在 2008 年第三季度和 2009 年第四季度之间的 GDP 最低,该函数是正确的。

将住房数据转换为季度数据

接下来,我们必须将 City_Zhvi_AllHomes.csv 文件中提供的住房数据转换为季度数据,并计算每个季度每个州每个地区的*均 GDP。将所需的数据帧列保存在名为的列表中,我们将列表分成三块,以便按季度制定数据。divide_chunks()函数主要用于此目的。它将输入的列表分成大小相等的子列表。

州名以两个字母的缩写形式给出,因此,它们需要映射到实际的州名,以确保进一步的分析。创建了一个名为 states 的字典,如下所示,它用字典的值替换“State”列中的数据,即将键映射到它们的值。

执行 convert _ housing _ data _ to _ quarters()函数会得到一个组织良好的数据帧,其形状为(10730,67):

房价走势

我们现在需要构建一个数据框架,显示衰退开始和衰退底部之间房价的下跌或上涨。

然后我们要进行 t 检验,比较衰退开始前一个季度大学城的*均房价与衰退底部的比率: price _ ratio = quarter _ before _ recession/recession _ bottom

在我们的例子中,我们已经发现衰退从 2008 年第三季度开始,衰退底部季度是 2009 年第二季度。因此,名为 housingdata 的所需数据帧以如下方式创建:

请注意,之所以选择 2008 年第二季度而不是 2008 年第三季度,是因为我们必须按照最初设计的方法选择紧接衰退开始季度之前的季度。

住房数据分离

一旦检索到数据,我们的下一个任务是根据大学城和非大学城对其进行分离,这样我们就可以在两个数据框架上执行 t_test。使用内部合并/连接方法,通过合并住房数据数据帧和单位所有数据帧来完成这种划分。这确保了我们提取的数据框架只包含大学城的住房数据。

然后,通过从住房数据框架中删除大学城数据的所有指数,获得非大学城的住房数据。这反过来给我们留下了所有非大学城各自的指数。

运行测试

最后,我们得出了我们进退两难的症结所在:全美大学城的*均房价是否较少受到衰退时期的影响?为了测试这个假设,我们在上面提取的两个数据帧上运行 SciPy 的 stats 包中的 ttest_ind() 函数。

此函数计算两个独立分数样本的*均值。这是对两个独立样本具有相同*均值(预期值)的零假设的双边检验。该测试假设总体在默认情况下具有相同的方差。

我们将 p 值设置为 0.01,这在统计上是有意义的。 P 值是统计假设检验中的边际显著性水*,代表给定事件发生的概率。

因此,获得的小于 0.01 的 p 值会使我们倾向于拒绝无效假设,反之亦然,对于大于或等于 0.01 的值。

如返回的元组所示,两个地区的*均房价实际上存在差异,大学城被认为更好。获得的 p 值为 0.003 ,四舍五入到小数点后三位,并且明显小于0.01。因此,替代假设被接受,事实证明,大学城的*均房价在经济衰退期间受影响较小。

我们需要深度图神经网络吗?

原文:https://towardsdatascience.com/do-we-need-deep-graph-neural-networks-be62d3ec5c59?source=collection_archive---------6-----------------------

被认为有害的深度?

深度学习的标志之一是使用数十层甚至数百层的神经网络。与之形成鲜明对比的是,图形深度学习中使用的大多数架构都很浅,只有少数几层。在这篇文章中,我提出了一个异端的问题:图神经网络架构中的深度带来任何优势吗?

T 今年,关于图形的深度学习被冠上了机器学习领域最热门话题的桂冠。然而,那些习惯于想象具有数十甚至数百层的卷积神经网络的人会失望地看到大多数关于图形“深度”学习的工作最多只使用了几层。“深度图神经网络”是一个误称吗?我们是否应该,套用经典的说法,想知道深度是否应该被认为对图形学习有害?

训练深度图神经网络是困难的。除了在深度神经架构中观察到的标准困境,如反向传播中的消失梯度和由于大量参数导致的过拟合,还有一些图形特有的问题。其中之一是过度*滑,由于应用了多个图卷积层,节点特征倾向于收敛到同一个向量并且变得几乎不可区分的现象[1]。这种行为首先在 GCN 模型[2,3]中观察到,其作用类似于低通滤波器。另一个现象是瓶颈,导致来自指数级邻居的信息“过度压缩”成固定大小的向量[4]。

最*,大量的努力致力于解决图形神经网络中的深度问题,希望获得更好的性能,并且在涉及只有两层的图形神经网络时,可能避免使用术语“深度学习”时的尴尬。典型的方法可以分为两类。首先,正则化技术,如逐边丢失(DropEdge) [5],节点特征之间的成对距离归一化(PairNorm) [6],或逐节点均值和方差归一化(NodeNorm) [7]。第二,架构变化包括各种类型的剩余连接如跳跃知识[8]或仿射剩余连接[9]。虽然这些技术允许训练具有数十层的深度图神经网络(否则这是一项困难甚至不可能的壮举),但它们未能展示出显著的收益。更糟糕的是,使用深层架构经常会导致性能下降。从[7]复制的下表显示了在节点分类任务上比较不同深度的图形神经网络的典型实验评估:

深度图神经网络架构的典型结果显示在合著者引文网络的节点分类任务中。随着深度的增加,基线(具有剩余连接的 GCN)表现不佳,性能从 88.18%急剧下降到 39.71%。使用 NodeNorm 技术的架构随着深度的增加表现一致。然而,当深入时,性能下降(尽管不显著,从 89.53%下降到 87.40%)。总体而言,深度 64 层架构实现的最佳结果(87.40%)不如简单基线的结果(88.18%)。此外,观察到 NodeNorm 正则化提高了浅层 2 层架构的性能(从 88.18%提高到 89.53%)。从[7]中复制的表(显示的是每类 5 个标签的情况;论文中研究的其他设置表现出类似的行为)。类似的结果显示在[5]和其他几篇论文中。

从该表中可以明显看出,很难将深度架构带来的优势与训练这种神经网络所需的“技巧”区分开来。实际上,上面例子中的 NodeNorm 也改进了一个只有两层的浅层架构,达到了最佳性能。因此,尚不清楚在其他条件不变的情况下,更深层次的图神经网络是否表现更好。

T 这些结果显然与网格结构数据深度学习的传统设置形成鲜明对比,其中“超深度”架构[10,11]带来了性能上的突破,并在今天得到了广泛应用。在下文中,我将尝试提供一些可能有助于回答这篇文章标题中提出的挑衅性问题的方向。我自己也没有一个明确的答案。

图表的结构。由于网格是特殊的图形,当然也有深度有助于图形的例子。除了网格之外,代表分子、点云[12]或网格[9]等结构的“几何”图形似乎也受益于深层架构。为什么这样的图与通常用于评估图神经网络的引用网络(如 Cora、PubMed 或 CoauthorsCS)如此不同?其中一个区别是,后者类似于低直径的“小世界”网络,人们可以通过几跳从任何其他节点到达任何节点。结果,仅仅几个卷积层的感受域就已经覆盖了整个图[13],所以增加更多的层无助于到达远程节点。另一方面,在计算机视觉中,感受野多项式增长,需要许多层来产生捕捉图像中对象的上下文的感受野[14]。

在小世界图(上图)中,从一个节点到达另一个节点只需要几跳。结果,邻居的数量(以及相应地,图形卷积滤波器的感受域)以指数速度增长。在这个例子中,为了从红色节点到达任何节点,只需要两次跳跃(不同的颜色指示从红色节点开始将到达的相应节点的层)。另一方面,在网格(底部)上,感受野的增长是多项式的,因此需要更多的层来达到相同的感受野大小。

在邻居呈指数增长的图中(如上图所示),会出现瓶颈现象:来自太多邻居的太多信息必须压缩到单个节点特征向量中。结果,消息无法传播,性能受到影响。

长程 vs 短程问题。一个稍微不同但相关的区别是问题需要长范围还是短范围的信息。例如,在社交网络中,预测通常仅依赖于来自节点的本地邻居的短程信息,并且不会通过添加远程信息来改进。因此,这样的任务可以由浅 gnn 来执行。另一方面,分子图通常需要长程信息,因为分子的化学性质可能取决于其相对侧的原子组合[15]。可能需要深层 GNNs 来利用这些长程相互作用。然而,如果图的结构导致感受野的指数增长,瓶颈现象可以阻止远程信息的有效传播,这解释了为什么深度模型在性能上没有改善[4]。

理论局限。除了更大的感受域,深度架构在计算机视觉问题中提供的一个关键优势是它们能够从简单的特征组合出复杂的特征。将 CNN 从面部图像中学习的特征可视化,显示出从简单的几何图元开始,到整个面部结构结束的越来越复杂的特征,这表明传说中的“祖母神经元”比神话更真实。这种复合性对于图形来说似乎是不可能的,例如,无论神经网络有多深,都无法从边组成三角形[16]。另一方面,研究表明,如果没有特定的最小深度,使用消息传递网络计算某些图属性(如图矩)是不可能的[17]。总的来说,我们目前缺乏对哪些图形属性可以由浅 gnn 表示,哪些需要深度模型,以及哪些根本无法计算的理解。

卷积神经网络在人脸图像上学习特征的例子。注意当进入更深的层时,特征如何变得越来越复杂(从简单的几何图元到面部分到整个面)。图改编自马修·斯图尔特的博客文章

深度与丰富度。与底层网格固定的计算机视觉相反,在对图形的深度学习中,图形的结构确实很重要,并且会被考虑在内。有可能设计更复杂的信息传递机制,考虑复杂的高阶信息,如标准 GNNs 不能发现的基序[18]或子结构计数 [19]。人们可以选择具有更丰富的多跳过滤器的浅层网络,而不是使用具有简单 1 跳卷积的深层架构。我们最*关于可扩展类初始图神经网络(SIGN) 的论文通过使用具有多个预先计算的过滤器的单层线性图卷积架构,将这一想法发挥到了极致。我们展示了比复杂得多的模型更好的性能,而时间复杂度只是它们的一小部分[20]。有趣的是,计算机视觉社区选择了相反的道路:早期带有大(高达 11×11)滤波器的浅层 CNN 架构,如 AlexNet ,被带有小(通常为 3×3)滤波器的非常深层架构所取代。

评价。最后但并非最不重要的一点是,图形神经网络的主要评估方法受到了来自 Stephan Günnemann 小组的 Oleksandr Shchur 及其同事的严厉批评[21],他们提请注意常用基准的缺陷,并表明如果在公*的环境下进行评估,简单模型的性能与更复杂的模型相当。我们在深度架构中观察到的一些现象,比如性能随深度而下降,可能只是源于对小数据集的过度拟合。新的 Open Graph Benchmark 解决了其中的一些问题,提供了非常大的图形,具有严格的训练和测试数据分割。我认为,我们需要做精心设计的具体实验,以便更好地了解深度在图形的深度学习中是否或何时有用。

[1]更准确地说,过度*滑使节点特征向量塌陷到一个子空间,参见 K. Oono 和 t .铃木,图神经网络对节点分类的指数松散表达能力 (2019)。arXiv:1905.10947,使用动态系统形式提供渐*分析。

[2] Q. Li,Z. Han,X.-M. Wu,对半监督学习的图卷积网络的更深入见解 (2019)。继续。AAAI。将 GCN 模型与拉普拉斯*滑法进行类比,并指出过度*滑现象。

[3] H. Nt 和 T. Maehara,重温图形神经网络:我们所拥有的只是低通滤波器 (2019)。arXiv:1905.09550。使用图形的频谱分析来回答 gcn 何时表现良好。

[4] U. Alon 和 E. Yahav,关于图神经网络的瓶颈及其实际意义 (2020)。arXiv:2006.05205。确定了图形神经网络中的过度挤压现象,这类似于在顺序递归模型中观察到的现象。

[5] Y. Rong 等 DropEdge:走向节点分类上的深度图卷积网络 (2020)。进行中。ICLR。一种类似于丢弃的想法,其中在训练期间使用边的随机子集。

[6]赵和阿科格鲁。 PairNorm:在 GNNs (2020)中解决过度投机问题。继续。ICLR。建议对结点要素之间成对距离的总和进行归一化,以防止它们塌陷为一个点。

[7] K. Zhou 等深度图神经网络的有效训练策略 (2020)。arXiv:2006.07107。

[8] K. Xu 等,具有跳跃知识网络的图上的表征学习 (2018)。继续。ICML 2018。

[9] S. Gong 等图神经网络中的几何原理连接 (2020)。继续。CVPR。

[10] C. Szegedy 等人,深入研究卷积(2015 年)。继续。CVPR。

[11] K. He 等,用于图像识别的深度残差学习(2016)。继续。CVPR。

[12] G .李等DeepGCNs:GCNs 能不能做到和 CNN 一样深? (2019)。继续。ICCV。展示了几何点云数据的深度优势。

[13] Alon 和 Yahav 将一个节点不能从比层数更远的节点接收信息的情况称为“欠达”。这一现象最早由 P Barceló等人在图神经网络的逻辑表达能力 (2020)中指出。继续。ICLR。Alon 和 Yahav 在分子图(使用层数比图的直径多的 gnn)中的化学性质预测问题上通过实验表明,性能差的原因不是不足,而是过度挤压。

[14] André Araujo 和合著者有一篇关于卷积神经网络中感受域的优秀博客文章。随着 CNN 模型在计算机视觉应用中的发展,从 AlexNet 到 VGG、ResNet 和 Inception,它们的感受域随着层数的增加而增加。在现代架构中,感受域通常覆盖整个输入图像,即,最终输出特征图中每个特征使用的上下文包括所有输入像素。Araujo 等人观察到分类准确性和感受野大小之间的对数关系,这表明大的感受野对于高水*的识别任务是必要的,但回报递减。

[15] M. K. Matlock 等用波网络在无向图中深度学习长程信息 (2019)。继续。IJCNN。观察图形神经网络捕捉分子图形中长距离相互作用的失败。

[16]这源于与 Weisfeiler-Lehman 图同构测试的消息传递 GNN 等价,参见例如 V. Arvind 等人关于 Weisfeiler-Leman 不变性:子图计数和相关图属性 (2018)。arXiv:1811.04801 和 Z. Chen 等人图神经网络能统计子结构吗? (2020)。arXiv:2002.04025。

[17] N. Dehmamy,A.-L. Barabási,于荣,理解图神经网络在学习图拓扑中的表示能力 (2019)。继续。神经炎。表明学习某阶图矩需要一定深度的 gnn。

[18] F. Monti,K. Otness,M. M. Bronstein, MotifNet:一种基于 motif 的图卷积网络,用于有向图 (2018)。arXiv:1802.01572。

[19] G. Bouritsas et al. 通过子图同构计数提高图神经网络表达能力 (2020)。arXiv:2006.09252。

[20] E. Rossi 等人签署:可扩展的初始图神经网络 (2020)。arXiv:2004.11198

[21] O. Shchur 等人图神经网络评估的陷阱 (2018)。关系表征学习工作坊。显示简单的 GNN 模型与更复杂的模型表现相当。

我非常感谢尤里·阿龙分享他在图形神经网络瓶颈方面的工作,也非常感谢他、法布里齐奥·弗拉斯卡、费德里科·蒙蒂和伊曼纽·罗西对这篇文章的校对。本帖的 中文翻译 刘止庸 提供。关于图形深度学习的其他文章,请参见我的 博客 关于走向数据科学, 订阅 到我的帖子,获取 中等会员 ,或者关注我的Twitter

在数据科学中我们需要面向对象编程吗?

原文:https://towardsdatascience.com/do-we-need-object-orientated-programming-in-data-science-b4a7c431644f?source=collection_archive---------17-----------------------

软件开发

让我们讨论一下作为一名数据科学家转向面向对象编程的利弊。

来自 UnsplashClément H 的图像

当我第一次涉足数据科学时,很明显面向对象编程不是主要的焦点。许多数据科学家在笔记本上或作为单个 Python 脚本编写代码来清理数据、开发模型并运行它们,但没有将代码放入函数或类中。大多数课程围绕理解机器学习(ML)模型、特征工程、训练/测试/验证集等。这项工作通常在笔记本环境中完成,并在学生和教授之间共享。通常,在软件开发过程中,数据科学家不会以与开发人员相同的方式考虑最终用户。

当我开始作为一名数据工程师工作时,我更多地关注面向对象语言和云技术,以托管、清理和向其他团队提供数据。即使在那时,大多数编程都是在 AWS 上的 Lambda 函数中进行的,或者使用开源库来完成必要的工作。当我转换到数据科学角色时,我又回到了长笔记本或链式笔记本,有些功能取决于开发人员。只有最少的面向对象的代码,而且这只是为了与其他团队进行交互,这些团队吸收了我们的工作并需要它来运行代码。

现在,我在一个团队工作,该团队的主要代码库几乎都是面向对象的,同时还有遵循类似编码标准的其他库和工具。测试管道和发布管道混合了笔记本、库和自动化。转向面向对象的思维模式非常有益。这种转变使得我们的代码可以投入生产,易于阅读,并且可以扩展到新的用例。

为什么要考虑面向对象编程?

当以面向对象的方式编写代码时,您关注的是函数、继承、方法和类。这些构造可以构建应用程序或工具,创建可扩展和可重用的库,并运行可重复的分析和报告。如果您想要开发利用您的分析模型的应用程序,这些应用程序将需要与您的代码交互,运行它,并产生与您在本地开发环境中产生的结果相同的结果。当您开发和细化您的模型时,您可以为其他应用程序或其他团队创建可扩展的库。

学习如何实现面向对象编程将有助于你编写类、创建对象和执行复杂的程序。当您学习以这种方式读写代码时,您可以通过重用已经编写过的代码来提高生产率和效率。它还将使您能够更好地利用他人的代码,尤其是在您可能想要扩展以包含您的用例的开源库中。

假设一个团队成员已经编写了一个数据清理函数库,这些函数库通常用于您团队的数据集。通过创建这个库,你可以克隆他们的作品并加以利用。这个库意味着您现在可以访问清理他们数据的相同功能,使您更容易重现他们的工作。现在,每个想要以相同方式清理数据的队友只需运行相同的代码,数据清理将不再有细微的差异。您可以将这一概念应用于创建用于数据接收、数据清理、开发分析、创建标准可视化等的库。如果您的团队开始使用相同的常规流程进行分析,您可以加快提供有用见解的速度。

面向对象编程的利弊

因此,在您的数据科学工作中使用面向对象编程有优点也有缺点。

优点

  • 面向对象的代码允许可重用和可扩展的代码。您可以在重复分析中使用这些函数和类,或者创建利用一些现有代码的新项目,从而减少产生结果的时间。
  • 如果你写干净的、面向对象的代码,发现 bug 会容易得多。
  • 当代码块更加模块化和细分时,测试和调试代码变得更加容易。
  • 面向对象编程允许多个数据科学家之间进行并行开发,这些科学家希望在他们的项目中使用相同的代码库。

缺点

  • 代码库有可能变得非常大,包含许多不需要的部分。
  • 在项目的实现过程中,您可能会遇到代码重复的问题。
  • 当开始利用面向对象编程时,可能会有一个学习曲线,可能需要一些时间来适应。
  • 这会增加运行代码的时间,因为通常要执行更多行代码。

摘要

最后,是否需要切换到面向对象编程取决于您,但是它可以提供许多好处。我发现这种编程风格的主要好处是在开始一个新项目时能够快速重用和扩展代码库。像这样一个开发的代码库允许开发人员之间共享,他们可以获得你的工作并在此基础上扩展他们的用例。谁知道呢,当他们看到你创造的东西时,他们甚至会找到一些灵感。

附加阅读

深度学习时代我们还需要传统的模式识别、机器学习、信号处理吗?

原文:https://towardsdatascience.com/do-we-still-need-traditional-pattern-recognition-machine-learning-and-signal-processing-in-the-age-9ffe58512ff9?source=collection_archive---------39-----------------------

指数增长领域的理论与实践

使用示波器的信号处理。图片:来源

深度学习是过去几年我们在计算机科学中看到的最成功的方法之一。结果表明,用这种方法可以解决许多问题,每天都有惊人的结果发表。事实上,模式识别中的许多传统方法似乎已经过时。在科学界,模式识别和信号处理的讲师讨论我们是否需要重新设计我们所有的课程,因为许多方法不再反映最先进的水*。基于深度学习的方法似乎优于所有这些方法。

尼曼之后的经典模式识别流水线。过程中的每一步都是独立优化的,这导致了经典的“特征工程”。图片:来源

对于经典意义上的模式识别和机器学习来说,我们感兴趣的是解决依赖于感知的任务,现有的先验知识非常少,可以利用这些知识来有效地解决任务。经典模式识别中使用的主要方法是使用专家知识来识别对给定任务有区别的特征。这种方法现在通常被称为“特征工程”。这些方法中的大多数已被证明优于在架构设计中勾画特定算法蓝图并以数据驱动的方式训练所有参数的深度方法。这样做,我们能够在许多问题上接*甚至超过人类的表现。

所有这些“感知任务”共有的一个主要目标是,我们无法真正理解人类大脑是如何解决它们的。因此,建立深层网络,在如何解决问题上提供很大的自由度,会给我们带来最好的结果。我还不知道有什么更好的方法来处理这个基本的限制。

深度学习现在也应用于其他领域,如医学图像重建,黄等人的实验表明。在这里,我们看到成功,但也有意想不到的结果。图片:来源

鉴于这一巨大成功,看到许多研究人员开始将深度学习应用于经典信号处理任务就不足为奇了。范围从助听器的降噪、图像超分辨率,到医学成像模式(如计算机断层成像)的 3D 体积图像重建。事实上,许多论文表明,对于许多给定的任务领域,深度学习能够胜过经典方法。在最好的情况下,这些网络学习针对特定应用优化的经典算法的变体。在其他情况下,我们甚至会看到惊人的结果,尽管网络架构在数学上无法模拟真正的底层功能。然而,在有限的应用领域,给定适当的训练数据,对于各种各样的问题,该任务仍然是*似的。

由于神经网络是通用函数逼*器,这些结果并不完全令人惊讶。如果我们已经知道,例如对于磁共振成像(MRI)的情况,处理链必须包含傅立叶变换,我们是否真的需要从头开始学习所有的可训练参数。事实上,最*的一篇论文提出了“T2 已知算子学习”的概念,研究了这种已知算子的积分效果,如 MRI 中的傅立叶变换。该论文证明了将操作包含到网络中实际上减少了学习问题的最大误差界限。因此,该知识有助于找到更稳定的解决方案,同时减少可训练参数的数量。在大多数情况下,这也减少了所需的训练样本数量。

已知算子学习允许混合经典和深度方法。图片由 Andreas MaierCC 4.0 下由提供。

在这一点上需要提及的一个重要前提是,允许计算相对于输入数据以及可选地相对于其参数的梯度/导数的任何操作都适用于该框架。因此,“算子”的范围可以从简单的矩阵乘法到复杂的方法,如计算机图形学中的整个光线跟踪器。即使是高度非线性的方法,如中值滤波器,也允许计算线性化的梯度,这使得能够在此框架内使用

到目前为止,“已知算子学习”已经被应用于构建将深度学习方法与经典信号处理相结合的网络。它可以用于为计算机断层摄影设计高效且可解释的重建方法,将物理学集成到 X 射线材料分解中,并减少分割和去噪网络中的参数数量。我们甚至看到深度学习和经典理论的融合能够在数学意义上“衍生”新的网络结构。这样做,一个新的数学图像重组公式被发现,这是以前未知的。这个新公式现在允许将并行 MRI 原始数据映射到 X 射线采集几何图形中。这一新发现是迈向新型核磁共振成像/X 射线混合扫描仪的重要一步,可能会为全新一代医疗扫描仪铺*道路。

PYRO-NN 是在 TensorFlow 中实现的利用深度学习进行图像重建的开源框架。在这里找到 GitHub 库。图片由 Andreas MaierCC 4.0 下由拍摄。

事实上,有人可能会说,我们已经在深度学习中使用这个概念很长时间了。原则上,卷积层和池层是受大脑中神经处理启发的已知运算符。因此,有人可能会说,它们的包含是一种应该存在于网络中的先验知识。然而,与 X 射线和 MRI 的例子相比,我们不能保证操作员需要出现在网络中。尽管如此,这些观察结果非常符合深度学习每天产生的结果。

我们还需要学习过滤器离散化吗?滤波器学习能够从分析初始化中找到正确的离散化。在这里找到一个代码示例。图片由 Andreas MaierCC 4.0 下由拍摄。

基于这些发现,我不认为我们应该在课堂上省略经典理论,而只用深度学习的讲座来代替。事实上,我确实相信经典理论和深度学习非常兼容,可以用来促进彼此的理解。一方面,我们已经观察到证据,例如噪声增强技术类似于维纳滤波器,并且端到端离散滤波器网络可以从很少的训练示例中学习正确的滤波器离散化。所以深度学习有助于简化经典理论中的实际问题。另一方面,我们也看到,我们可以在深度网络中用经典运算替换块,以了解它们的用途。这限制了网络的解空间,并允许我们用来自经典理论的方法分析它们的更简单的部分。因此,深度学习也可以受益于传统方法。事实上,我相信这两个世界的融合是未来研究的一个很好的方向,并可能使我们在未来联合符号处理和深度学习方法的领域。因此,我们需要继续传达经典方法,但是我们需要将它们放入正确的上下文中,并将它们连接到适当的深层方法。

如果你喜欢这篇文章,你可以在“医学图像处理深度学习的温和介绍中找到这个观点的扩展版本,或者看看我的 YouTube 频道。这篇文章最初出现在 MarkTechPost.com 的,以知识共享 4.0 归属许可发布。

你会举吗?通过锻炼和营养预测体重减轻

原文:https://towardsdatascience.com/do-you-even-lift-predicting-weight-change-with-workouts-and-nutrition-a6b8b4cf6f23?source=collection_archive---------14-----------------------

将经典的数据科学方法应用到我的减肥旅程中

维克多·弗雷塔斯在 Unsplash 上拍摄的照片

背景

新年新我!但是我没有新年决心,而是有一个新年前的决心:在 2020 年前让我的体重回到健康范围。我记得 2018 年我在一家节奏极快的初创公司实习了 3 个月,每天都有很高的进步要求,我没有意识到我给自己带来了多少压力。每一天结束时,我都筋疲力尽,没有任何精力去快速锻炼。

在我的实习和结束时,我的体重增加了 6 公斤,这让我的身体质量指数身份立刻变成了超重。3 个月 6 斤!我完全惊呆了,我外表的变化变得很明显。

快进到今天,谢天谢地,我在一家大公司担任数据分析师,工作与生活的*衡让我可以在下班后腾出一些精力去健身房。

我的体重状况

我一直想减掉身上的脂肪,保持身材,因为在这个项目开始时,我的身体质量指数处于临界超重状态。网上消息指出,保持 50-70%的运动强度是脂肪燃烧卡路里的最佳比例。

我试着在两周内每周去健身房五次,果然我已经看到了我身体形状的微妙变化。体重秤上显示的我的总重量变化不大,但我很高兴看到力量的增长。

动机

随着我继续频繁地去健身房,我受到启发利用应用机器学习的想法,根据我在健身房锻炼的类型和我的饮食来预测我未来的体重减轻。我想采用经典的数据科学方法,根据以下方法预测我的体重变化:

数据采集:通过移动应用程序记录我的营养和健身活动,并将数据输入 csv 文件,然后导入 Python 脚本。

分析:可视化我的饮食习惯和健身习惯的个人关系,并决定哪些特征适合回归模型。

统计:了解我的饮食习惯和健身程序如何影响我的体重变化,并去除高度相关的特征。

建模和评估:选择基于 R *方统计量和最小均方误差的最佳线性回归模型。

是的,我知道通过像全栈数据科学项目这样的网站收集数据是一种更酷的方法。但是,嘿,我可以减肥,保持身材,我觉得这对我来说足够酷了!

声明:我既不是营养学家,也不是运动科学专家。我写这篇文章是出于对结合数据科学和锻炼的兴趣。我在运动营养学方面的知识仅限于我在网上看到的和我的生物医学文凭上的一点点。因此,如果下面任何关于营养的信息对读者来说是不正确的,我道歉。我只是对数据方面感兴趣。

“这是我个人的减肥旅程,有我自己的一套数据,不一定对你有用。每个人的身体都有不同的工作方式,如果你有兴趣开始这段旅程,你应该提供自己的一组数据。”

为了正确看待我在这个项目开始时所处的位置,下面是一些测量结果:

  • 当前体重:74.9 公斤
  • 目前的身体质量指数:24.96(是的,我差 0.04 就被认为超重了)
  • 目标重量:68 公斤

数据采集

收集方法

每天早上醒来后测量体重和其他身体指标。卡路里和宏量营养素的分解记录在 MyFitnessPal 应用程序免费版中,锻炼数据由 Jefit 应用程序精英版获取。

所有工作日锻炼都在晚上下班后进行,周末锻炼通常在下午进行。

数据描述

在决定用于预测分析的变量之前,让我们看看每个变量,并探索它们与体重变化的关系。

体重变化:我考虑使用脂肪百分比变化作为感兴趣的变量。因为毕竟燃脂练肌是这个项目想要的结果。然而,许多消息来源指出浴室身体成分量表的不准确性,尽管很高兴看到与你的身体相关的某些指标。我尝试使用小米的身体成分量表和 e ven,尽管产品评论本身承认它不准确,尽管它包含了一系列有用的功能。

我决定使用体重变化作为感兴趣的因变量,因为我想探索我的活动和相应体重变化之间的关系。

weight_change 变量是用 weight_today 减去 weight_tomorrow 得到的。

出于一致性的目的,所有的测量都是在第二天早上醒来后进行的。

多余卡路里:我把多余卡路里定义为消耗的卡路里减去自己的基础代谢率(BMR)。人的基础代谢率通过以下公式计算:

  • **女性:BMR = 655 + (9.6 *体重公斤)+ (1.8 身高厘米)-(4.7 年龄岁)
  • **男性:BMR = 66 + (13.7 *体重公斤)+ (5 身高厘米)-(6.8 年龄岁)
  • 多余卡路里=消耗的卡路里-基础代谢率

一道蛋白质与碳水化合物比率极高的菜肴(照片由马克·德扬Unsplash 上拍摄)

蛋白质-碳水化合物比率:在互联网上查找关于低碳水化合物饮食的文章,你读得越多,你就越确信限制碳水化合物燃烧储存的脂肪作为能量。

如果你经常去健身房,你就会明白蛋白质对肌肉修复和生长是多么重要,这样你就能在随后的锻炼中恢复并继续前进。其他消息来源指出用蛋白质代替碳水化合物是减肥的关键。

这让我有兴趣研究它与减肥的关系,因为我打算用更多的蛋白质消费来代替碳水化合物,如肉、豆腐和蛋白奶昔。

单独吃炸鸡而不吃薯条或苏打水实际上可能有助于减肥。一些健身者称之为肮脏的膨胀

脂肪:与吃脂肪会让你变胖的普遍观点相反,用有益的脂肪代替碳水化合物有助于燃烧全部脂肪。不幸的是,我正在使用的移动应用程序不提供将脂肪准确分为饱和脂肪、多不饱和脂肪和反式脂肪的功能。但是很自然地,我会认为从常规饮食中持续摄入脂肪可能会导致体重增加..对吗?

锻炼类型:我遵循 Jefit 的“5 天肌肉量分割”计划,并根据我的要求和可用的健身房设备量身定制。这是一个分类变量,仅限于以下类型的健身程序:

  • 胸部和背部
  • 腿和腹肌
  • 手臂,胳膊(arm 的复数)
  • 肩膀和后背
  • 胸部和腿部
  • 休息

维克多·弗雷塔斯在 Unsplash 上拍摄的照片

由于该应用程序没有将每个肌肉成分花费的时间分开(除了 arms day),我决定将它们分组到单一的运动类型中以保持一致性,而不是用一键编码将每个肌肉成分分开。

健身房举重率:这是我试过的第一款显示每次锻炼举重量的应用。某些锻炼,如手臂日,会期望举起较低的重量,因为手臂不属于主要肌肉群,而我们会期望在包括胸部、背部和腿部的锻炼中看到较高的重量。一开始,知道每天举起多少重量似乎是对特定锻炼表现的充分衡量。然而,我认为休息的时间长短取决于锻炼的强度。想象一下休息 2 分钟和休息 1 分钟,差别是巨大的,这是保持 50-70%运动强度的关键。

探索性数据分析

是时候深入这个项目的数据方面了。以下是我减肥的 TL:DR 仪表盘总结:

首先,原谅变形图片的恐怖灯光。当我第一次拍这张照片时,我并不是很认真地开始这次旅程,我也不确定这张照片的正确角度。当我开始看到渐进的结果时,我意识到我应该选择一个光线更好的地方。为了保持一致性,我用相似的设置拍摄了“之后”的照片。

首先,下面是我每日体重随时间变化的简单快速线性回归:

在我继续之前,请注意,回归图是在整个数据集上绘制的,而汇总统计数据是从过去 14 天中提取的数据。稍后我会解释这一点。

显然,使用天数作为因变量进行简单的线性回归并不能真正解释我体重减轻的原因。然而,有趣的是,我每天*均减轻 0.068 公斤,每周*均减轻 0.476 公斤。有 98%的 R *方统计,它解释了我减肥习惯的一致性。

那么营养是如何影响体重变化的呢?

从不吃饭到大吃自助餐,你吃什么就是什么。每个人都有一个特定的基础代谢率,燃烧足够的热量来维持他们的身体机能。人们很自然地认为,你的体重与你摄入的超过你个人基础代谢率的量直接相关。

过量的卡路里和体重变化之间似乎存在着相当积极的关系。公*地说,我确实期望这两个变量之间有更强的相关性。出现这种现象有几个原因:

  1. 计算卡路里只是估算你吃了多少。MyFitnessPal 有一个食物数据库,但不一定提供大量营养素的准确分类,因为它是由全球用户共享的。某些食物,尤其是亚洲菜肴在数据库中不存在,我不得不通过与类似的菜肴进行比较来提供宏量营养素的粗略估计。
  2. 我身体的生理机能也起了作用。当我生病的时候,即使喝了很多水,我还是经常脱水。在我生病期间,我不断地减肥。但是当我恢复健康的时候,我的体重猛增。由于必须处理有限的数据,这些异常可能会影响我的分析。

我们知道,健美运动员发誓摄入高蛋白,同时减少一点碳水化合物,以达到轮廓分明的效果。对于初学者来说,将碳水化合物:蛋白质:脂肪的宏观营养比例分配到 40:30:30 是一个很好的开始,这就是我开始的地方。随着我旅程的进行,这个比例慢慢变成了 40:40:20。所以理想情况下,我会尽最大努力保持我的蛋白质和碳水化合物的比例在 1 以上来减肥。

这部分解释了为什么我的体重下降速度没有那些酮饮食的人快。我日常消费的大部分仍然含有高碳水化合物!即使我在旅程的后半段没有吃任何主食。负相关告诉我,减少碳水化合物的摄入并用蛋白质代替确实有助于减肥。但是脂肪呢?肯定是正相关的吧?

不完全是。

令人惊讶,不是吗?体重变化和脂肪消耗之间几乎没有任何关联。这真的可以归结为你摄入的碳水化合物的量和对你体重变化高度负责的多余卡路里!不要只相信我的话,你可以看看 Ariel Faigon 的这个实验。

** [## 减肥/减肥

该图表是由这个 git 存储库中的脚本 date-weight.r 从数据集 weight.2015.csv 生成的。它需要…

github.com](https://github.com/arielf/weight-loss)

在负责减肥的顶级食物中,它包括橄榄油、天妇罗、鸡蛋和培根!是的,美味的熏肉!许多主食是体重增加的原因,这也不足为奇。

正如你所注意到的,我已经使用皮尔逊系数作为主要指标来评估体重变化和营养变量之间的关系。因此,我必须强调相关性不等于因果关系。减少碳水化合物并用蛋白质代替并不总是能保证减肥。总会有一个独立的第三方因素影响体重变化,这就是为什么我们要调查我的锻炼对体重变化的影响。

锻炼的类型会影响体重变化吗?

如果你看过我体重减轻的仪表板资料,你会注意到我的体重减轻大部分来自腿部/腹肌日,累积休息日解释了积极的体重变化。然而,我们不能简单地得出结论,做腿部/腹肌运动一定会带来最大的减肥效果。让我们来看一个箱线图进行比较:

乍一看,我们可以看到包括休息日在内的某些锻炼类型具有高度倾斜的数据,其中中位数接*上/下四分位数。假设不是所有的锻炼类型都不符合正态分布是合理的。这在很大程度上是因为捕获的数据数量非常有限。回想一下,在这个项目总共 87 天中,我只有 12 天休息。随着数据数量的增加,每个变量很可能遵循正态分布。需要对独立变量进行非参数统计检验,以验证分布的差异,即“曼-惠特尼 U 检验”。然而,我最*发现 Python 的 statsmodels 库已经方便地包含了一个成对 t 测试。尽管这不是进行这个测试的正确方法,我还是继续做了,因为它仍然给了我某种程度上的洞察力,关于分布的差异。它看起来是这样的:

虽然结果显示,某些锻炼与休息日相比是不确定的。我相当有信心,随着数据收集变得越来越大,p 值将收敛到一个较低的值。

仍然有一些事情需要探索,但是我会在这里停下来,继续这个项目的主要目标。我将在我的 Github 中分享我的数据,你可以尽情探索。**

预测我的体重变化

系统模型化

在我的项目结束时,我已经将我的重点从减肥转移到增加体重,所以用我即将介绍的模型来预测我未来的体重是没有意义的。回想一下,我将把项目的最后 14 天作为测试集。这是我将用于建模的大约 16%的训练测试分割。

让我们从一个非常简单的多元线性回归开始,找出独立特征对体重变化的影响程度:

从 R *方统计数据来看,它似乎不是一个很好的预测模型。在这个列表中的所有特征中,蛋白质和碳水化合物的比例似乎在体重变化中起着最重要的作用,并且是一个负系数。

说到特征的重要性,我将应用随机森林回归和 XGBoost 以及使用 GridSearchCV 调整的超参数,来对哪些特征提供了较高的减肥幅度进行排序:

等一下…为什么过量卡路里变量的重要性排在第二位,而绝对过量卡路里变量(是/否)的重要性排在第二位?转念一想,似乎所有的独热编码特征都放在了图表的下半部分。环顾网络,这似乎是一个可行的解释,摘自一篇关于随机森林特征重要性的文章

缺点:

有偏见的方法,因为它倾向于夸大连续特征或高基数分类变量的重要性

让我们看看 XGBoost 在随机森林回归中表现如何:

现在这更有意义了!这次我们看到了分类变量和连续变量的巨大混合。当我们将其与营养方面的连续散点图进行比较时,我们可以观察到蛋白质-碳水化合物比率比过多的卡路里和脂肪起着更重要的作用。

然而,我仍然很怀疑它的预测能力。在之前的算法中,我特意将我选择的所有特征用于预测。回头来看,似乎有某些变量可能会危及性能,如“胸部和背部”在这两种情况下。

那么有哪些冗余的特征可以被去除以提高预测呢?我们用另一个随机森林回归的升级算法来回答这个问题,它的递归特征消除。

********

嗯嗯嗯…看起来所有的分类/二元特征都被消除了!虽然不得不删除这些特性让我很痛苦,但健壮的预测需要一点点牺牲。

预测和评估

老实说,这将是一个相当令人失望的部分,如果您希望看到 XGBoost 在 4 个版本中表现最好,请做好准备,因为它来了:

XGB 的 MAE 得分最高,预测最差。事实上,虽然我没有包括使用天数作为独立变量的线性回归,但是你可以很好地猜到,与这四个变量相比,它将做出最好的预测。

RFE 算法效果最好,因为某些与体重变化关系不大的特征被剔除了。

XGB 和 random forest regression 的表现不如我预期的那样好,因为它有太多的超参数需要优化,甚至连我的笔记本电脑都无法处理。

缺乏收集的数据可能是算法没有发挥应有作用的另一个因素。毕竟还不到 90 天!看看 RFE 算法的折线图上相当不稳定的模式,就能很好地概括这一点。

我可以继续使用一系列回归算法,甚至可能利用深度学习来使其更接*实际值。但我会在这里打住。如果你知道你能做出比我更好的预测,你可以再次访问我的 Jupyter 笔记本和我的 Github 中的体重数据。

最终想法和要点

一个全新的我

今天我的体重已经达到了健康的身体质量指数范围。我非常高兴在三个月内实现了我的目标。由于我的饮食选择和锻炼习惯,我在日常生活中不再感到昏昏欲睡。2020 年已经以积极的方式开始了!

虽然许多网站分享了类似的营养和减肥锻炼建议,但在这个个人项目中采用数据科学提供了关于每个特征与减肥相关的重要性的宝贵见解。

我是怎么做到的,你能做什么?

每个人都有不同的动力来塑造自己想要的身材。在大多数情况下,我们看着自己的反思,问自己我们能做些什么来实现它。

然后我们开始找借口。

然后我们停在那里。

保持一致性的最大障碍是我们许多人为了达到梦想中的身材而无法克服的。

对我来说,虽然听起来很奇怪,但数据科学将我推向了转折点。收集数据和监控我的活动是我成功减肥的主要驱动力。

每天我都注意我的食物摄入量,确保我尽最大努力吃得低于基础代谢率(包括作弊日),并确保我去健身房*均 1 小时。这些都是可能的,因为方便的应用程序让我可以跟踪我的进展。

健身房里普通的一天

我总是告诉人们,如果他们真的想增加或减少体重,他们必须养成饮食和锻炼一致的习惯。当我告诉他们我几乎每天锻炼一个小时时,“我真的没有时间”是他们的头号借口。

让我们做一点数学计算。

24 小时中的 1 小时是你一天中用于锻炼的 4.17%4.17% 。假设最好的情况,如果你一周锻炼 6 天,那你一生中只有不到 4%的时间用于锻炼。现在,除非你真的忙于工作,回到家继续埋头于你的脚本和电子表格,或者如果有某些健康状况阻止你进行艰苦的活动,那么没有理由不把你生命中的一小部分奉献给你渴望的转变。

走出去,从今天开始做出改变!

我希望这个小项目可以激励其他人将数据科学应用到他们自己的个人数据中。如果没有,我希望读者至少已经了解了他们的饮食选择和锻炼习惯对他们体重变化的影响,因为他们开始了自己的个人旅程,以改变自己的身体。

再一次,你可以在这里看到我的作品:

**** [## bobbymuls/通过健身和营养改变体重

此时您不能执行该操作。您已使用另一个标签页或窗口登录。您已在另一个选项卡中注销,或者…

github.com](https://github.com/bobbymuls/weight-change-with-gym-and-nutrition)

编码快乐!****

你有足够的数据吗?

原文:https://towardsdatascience.com/do-you-have-enough-data-87e31191f932?source=collection_archive---------42-----------------------

深入、广泛还是提高质量:如何找到您的数据瓶颈

图片来自 Pixabay像素

“如果我能够访问更多的训练数据,我的模型准确性将会大大提高”,“我们应该通过 API 获取更多的数据”,“源数据质量太差,我们无法使用它”

数据是每个机器学习或分析项目的基础,但尽管我们现在拥有比以往任何时候都多的数据,但与没有足够数据或正确类型的数据相关的借口并不短缺。

但是你怎么知道这些是真正的担忧还是借口呢?换句话说,你如何发现数据是否是一个项目的限制因素?

找到数据瓶颈

来自 Pixabay乌韦·鲍曼的图片

有三种不同的方法可以控制您的数据,通过:

  • 深入:增加数据点数量
  • 扩大范围:增加数据源的数量
  • 进行质量:修复烂摊子!

深入

这种情况下,你不改变你的数据结构,但你只是增加你的数据点。

你并不总是能控制这一点(比如你不能轻易增加你的客户),但通常你至少在某些方面能做到。

在一些不同的场景中,数据量会有所帮助。

A/B 测试或实验

如果您正在运行一个实验,您需要有足够的数据点来实现结果的统计显著性。你需要多少点,还取决于其他因素,如误差幅度、置信区间和分布的方差。对于您尝试运行的每个实验,都有一个最小数据量阈值:如果您已经达到了这个阈值,您可以继续,因为额外的数据点不会有任何帮助。否则,这可能是你的瓶颈。这篇文章也对此做了很好的概述。

机器学习中的预测精度

如果您运行的是预测模型,预测准确性会随着数据的增加而提高,但只达到某个“饱和点”。你如何发现你是否已经达到了这样一个点?您可以使用不同数量的训练点来重新训练您的模型,并绘制预测准确性与数据量的关系。如果你的曲线还没有变*,你可能会从额外的数据中进一步受益。

来源:Kim 和 Park 在 researchgate 上的文章

启用深度学习

虽然传统的机器学习模型也可以用较小的数据量运行,但你的模型越复杂,它需要的数据就越多。最极端的是,如果没有非常大量的数据可用,深度学习模型就无法运行。对他们来说,大数据是一种需求,而不是拥有来提高性能的好。

分析和洞察

即使您没有将数据用于预测目的,但也许您想要丰富您的报告或进行一次性分析来支持您的决策,数据量仍然是一个瓶颈。如果您的数据具有很大的异构性,并且您需要在不同的粒度级别对其进行分析,那么这一点尤其正确。例如,如果您有一支庞大的销售队伍和广泛的产品范围,每个销售人员可能只销售了产品的一个子集。如果你想比较他们在销售特定产品方面有多好,你可能做不到。

走向广阔

各种各样的数据可能是关键,但根据我的经验,这方面也经常被高估。

在我之前的一份工作中,我为一家利用机器学习预测房价的初创公司工作。我们的战略优势是我们拥有各种各样的数据,因此要整合所有可能的数据源,以帮助对房地产进行预测。

一个关键点是决定获取哪些来源,以提高模型的预测能力。

如何评估获取新数据的成本与收益?

评估新数据的好处涉及两个主要问题:新数据与我们试图预测的目标变量的相关性是什么(希望尽可能高),以及新数据与我们已经拥有的数据的相关性是什么(希望尽可能低)。不幸的是,这并不总是很容易定量分析,但一点定性判断可以帮助尝试筛选出最佳候选人。

评估新数据的成本可视为数据的总拥有成本。有时购买数据或支付 API 会有实际成本,但这只是故事的一部分。还需要考虑其他因素,通常是最大的因素:

  • 一次性摄入与重复摄入
  • 数据转换和存储的复杂性
  • 需要数据质量和数据清理
  • 数据处理和解析

持续质量

哈佛大学教授肖有一个非常激动人心的演讲,他说“数据质量远比数据数量重要”。这个演讲的美妙之处在于,他能够从数学上量化这个陈述,着眼于数据质量或数量的统计测量。

数据质量远比数据数量重要

我的商业经验也反映了这一点:公司往往希望开始获取或整合更多的数据,而没有首先考虑尝试处理现有数据是否足够。

数据质量往往是一个问题,一个大问题。这可能是由于手动输入错误、原始数据不准确、聚合或处理层中的问题、数据在一段时间内丢失等等。

这可能需要大量的工作,尤其是枯燥的工作,但也可能带来最有益的结果。

结论

尝试确定您的数据瓶颈在哪里,如果有的话。

数据量的问题通常可以通过对统计显著性或准确性曲线的简单检查来识别。如果这不是问题所在,请继续。

根据我的经验,数据的多样性经常被夸大,不是因为新的数据没有用,而是因为新的来源可能包含你已经以某种方式获取的信息,特别是如果你已经有了一个相对丰富的数据集。

数据质量是关键,关注一个更小但更干净的数据集比关注一个大而乱的数据集要好得多。

你有软件工程师和数据科学家的技能吗?可能不会

原文:https://towardsdatascience.com/do-you-have-the-software-engineer-and-data-scientist-skills-probably-not-7e8fb069e067?source=collection_archive---------62-----------------------

克里斯蒂娜@ wocintechchat.com 在 Unsplash 上的照片

采用技术成为更好的工程师和开发人员

为软件工程师和数据科学家开发人员的生产级别做准备

成为一名可靠的软件工程师和数据科学家开发人员,并为生产级编码做准备需要一些技巧。

  • 编写干净的模块化代码
  • 代码重构
  • 编写高效的代码
  • 添加有意义的文档
  • 测试
  • 原木
  • 代码审查

这些都是需要培养的基本技能,在实施生产解决方案时会有所帮助。此外,数据科学家经常与软件工程师并肩工作,因此有必要很好地合作。这意味着熟悉标准实践,并能够在代码上与其他人有效协作。

干净的模块化代码

当一个数据科学家第一次开始编码时,即使他们已经编码多年,他们也经常努力以一种干净和模块化的方式编写代码。实际上,当在行业中工作时,代码有可能用在生产中。生产代码是在生产服务器上运行的一个软件,用于处理实时用户和目标受众的数据,例如,使用笔记本电脑中的软件产品,如 Microsoft Office、Google 或 Amazon。运行这些服务的代码称为产品代码。理想情况下,生产中使用的代码在公开之前应该满足几个标准,以确保可靠性和效率。首先,代码需要干净。当代码可读、简洁且简单时,它就是干净的。

这里有一个例子,用简单的英语说,是一个不干净的句子。

人们会注意到你的裤子被弄脏了,因为你的裤子是粉红色的,看起来像某种果汁的颜色。

这句话多此一举,令人费解。光是读这个就让人应接不暇。这可以改写为:

看起来你把草莓汁洒在裤子上了。

这句话达到了同样的效果。尽管如此,这句话还是简洁明了得多。

产品质量代码的特性对于软件开发中的协作和可维护性至关重要。编写干净的代码在行业环境中是非常重要的,因为在团队中工作需要不断地重复工作。这使得其他人更容易理解和重用代码。除了干净之外,代码还应该模块化。事实上,代码在逻辑上被分解成函数和模块。此外,产品质量代码的一个基本特征是使代码更加有组织、高效和可重用。在编程中,模块只是一个文件。类似地,封装代码可以在一个函数中使用,并通过在不同的地方调用该函数来重用它。另一方面,通过将代码封装到可以导入其他文件的文件中,模块允许代码被重用。

为了更好地理解什么是模块化代码,试着把它想象成把衣服放好。我们可以把所有的衣服放在一个容器里,但是要找到任何东西都不容易,可能是因为同一件衬衫或袜子有好几个版本。如果我们有一个放 t 恤的抽屉,一个放衬衫的抽屉,一个放袜子的抽屉,那就更好了。有了这样的设计,告诉别人如何找到合适的衬衫、裤子和袜子就容易多了。写模块化代码也是如此。

将代码分成逻辑函数和模块可以快速找到相关的代码。需要考虑将在不同地方重用的代码片段一般化,以防止编写额外的不必要的代码行。将这些细节抽象成这些函数和模块有助于提高代码的可读性。因此,以一种让团队更容易理解和迭代的方式进行编程对于生产来说是至关重要的。

重构代码

很容易忽略编写好的代码。具体来说,当开始为一个新的想法或任务编写代码时,只关注让它工作。通常,在开发的这个阶段,它会变得有点混乱和重复。此外,在代码完成之前,很难知道最好的方法是什么。例如,如果我们没有足够的代码实验来遵循,那么理解什么功能最好地模块化代码中的步骤可能是具有挑战性的。因此,在获得一个工作模型之后,必须回去做一些重构。

代码重构是一个术语,指的是在不改变外部功能的情况下,对代码进行重组,以改善其内部结构。重构允许在生产后清理和模块化代码。从短期来看,这可能是浪费时间,因为我们可能会转向下一个特性。但是,分配时间给重构代码加速时间。从长远来看,团队需要开发代码。持续地重构代码不仅使我们以后更容易回到代码上,而且还允许我们在不同的任务中重用不同的部分,并在这个过程中学习可靠的编程技术。重构代码的实践越多,它就变得越直观。

高效代码

在重构过程中,除了使代码清晰和模块化之外,提高代码的效率也是必不可少的。提高代码效率有两个方面:减少代码执行的时间,减少代码占用的空间和内存。两者都会对公司或产品的表现产生重大影响。因此,在生产环境中工作时,实践这一点很重要。

但是,需要注意的是,提高效率有多重要是视情况而定的。缓慢的代码,可能在一种情况下可行,但在另一种情况下不可行。例如,如果某些批处理数据准备流程每三天运行一次,持续几分钟,则可能不需要立即进行优化。另一方面,用于生成在社交媒体 feed 上显示的帖子的代码需要相对较快,因为更新是即时发生的。此外,在代码运行后花大量时间进行重构来清理或优化代码是必不可少的。理解这个过程对开发人员的价值是至关重要的。每次优化代码,我们都会获得新的知识和技能,随着时间的推移,这将使程序员变得更加高效。

证明文件

文档是软件代码中附带或嵌入的附加文本或图解信息。文档有助于阐明程序的复杂部分,使代码更容易阅读、导航,并快速传达如何以及为什么使用程序或算法的不同组件。可以在程序的不同级别添加几种类型的文档——首先,使用行内注释来阐明代码的行级文档。第二,函数或模块级文档使用 docstrings 来描述其用途和细节。最后,项目级文档使用各种工具(如自述文件)来记录整个项目的信息以及所有文件如何协同工作。

行内注释

在整个代码中,哈希符号后面的文本是行内注释。它们用于解释部分代码,并帮助未来的贡献者理解。评论有不同的使用方式,好的评论,好的评论,甚至用户的评论也有不同。使用注释的一种方式是记录复杂代码的重要步骤,以帮助读者理解。例如,有了函数的指导性注释,未来的贡献者不需要理解代码就能理解函数的功能。注释有助于理解每个代码块的用途,甚至有助于找出单独的代码行或方法。

然而,其他人会认为使用注释有助于证明糟糕的代码或代码需要遵循注释。这是需要重构的迹象。注释对于解释代码不能解释的地方很有价值——例如,为什么一个特定的方法以一种特定的方式实现背后的历史。有时,由于某些未定义的外部变量会导致副作用,可能会使用非常规或看似任意的方法。这些东西很难用代码来解释。这些用于检测图像边缘水*的数字看起来可能是任意的。尽管如此,程序员试验了不同的数字,并意识到这是一个适合这个特定用例的数字。

文档字符串

文档字符串或文档字符串是解释代码中任何函数或模块的功能的有价值的文档。理想情况下,代码中的所有函数都应该有文档字符串。文档字符串总是用三重引号括起来。docstring 的第一行是对函数用途的简要说明。如果一行文档足以结束文档字符串,单行文档字符串是完全可以接受的。但是,如果函数足够复杂,需要更长的描述,可以在一行摘要之后添加一个更完整的段落。docstring 的下一个元素是对函数参数的解释。它应该类似于列出参数,陈述它们的目的,并陈述参数应该是什么类型。最后,通常提供函数输出的一些描述。docstring 的每一部分都是可选的。然而,文档字符串是良好编码实践的一部分。它们有助于理解生成的代码。

如果功能足够复杂,需要更长的描述,在一行摘要之后添加一个更全面的段落。

docstring 的下一个元素是对函数参数的解释。我们可以列出参数,说明它们的目的,并说明参数应该是什么类型。最后,通常提供函数输出的一些描述。docstring 的每一部分都是可选的;然而,文档字符串是良好编码实践的一部分。

项目文件

项目文档对于让其他人理解代码为何以及如何相关是必不可少的,无论他们是项目的潜在用户还是对代码有贡献的开发人员。项目文档中重要的第一步是一个 README 文件。这通常是大多数用户与项目的第一次互动。无论是应用程序还是软件包,项目都应该附带一个 README 文件。至少,这应该解释它是做什么的,列出它的依赖项,并提供关于如何使用它的足够详细的说明。对于其他人来说,理解项目的目的必须尽可能的简单,并且快速的得到一些工作。

来自 Github 页面的 README.md 文件示例

将所有想法和想法正式翻译到纸上可能有点棘手,但随着时间的推移,它会变得更好,并在帮助他人实现项目的价值方面产生重大影响。编写这些文档也有助于改进代码的设计。这也让以后的投稿人知道如何遵循初衷。

测试

在部署之前测试代码是必不可少的。这有助于在产生任何重大影响之前发现错误和错误结论。编写测试是软件工程中的标准实践。但是,测试往往是很多数据科学家刚入行时并不熟悉的做法。事实上,有时科学家提出的洞察数据,本应用于商业决策和公司产品,却是基于未经测试的代码结果。缺乏测试是与数据科学家一起工作的其他软件开发人员的常见抱怨。如果没有测试,由于软件问题,代码中有时会出现执行错误。它也可能根据错误的结论来支配商业决策和影响产品。如今,雇主正在寻找有技能为行业环境正确准备代码的数据科学家,包括测试他们的代码。

当一个软件程序崩溃时,这是非常明显的。出现错误,程序停止运行。然而,在数据科学过程中可能会发生许多问题,这些问题不像导致程序崩溃的功能错误那样容易被发现。所有代码看起来都运行顺利,完全不知道特定的值会被错误地编码。此外,功能被误用,或者意外的数据打破了假设。

这些错误更难发现,因为由于代码的质量,我们必须检查分析的质量和准确性。因此,应用适当的测试以避免意外并对结果有信心是至关重要的。事实上,测试已经被证明有如此多的好处,以至于有一个基于它的完整的开发过程叫做测试驱动 Development⁴.这是一个开发过程,在此过程中,在编写实现任务的代码之前,先编写任务测试。

测试驱动开发

测试驱动开发是在编写被测试的代码之前编写测试的过程。这意味着测试一开始会失败,当测试通过时,我们将知道如何完成任务的实现。这种开发代码的方式有许多在软件工程的标准实践中产生的好处。举个简单的例子,我们想写一个函数来检查一个字符串是否是一个有效的电子邮件地址。考虑一些要考虑的因素,比如字符串是否包含“@”符号和句点,并写出一个处理它们的函数,然后在终端中手动测试它。

尝试输入一个有效和一个无效的电子邮件地址,以确保它正常工作。用更多有效和无效的电子邮件地址尝试,其中一个会返回错误的结果。尝试创建一个测试来检查所有不同的 scenarios⁵.,而不是来来回回地做这件事这样,当我们开始实现一个功能时,我们可以运行这个测试来获得关于它是否在所有方面都工作的即时反馈。认为这个过程是一个函数调整。如果测试通过,实现就完成了。

当重构或添加代码时,测试有助于确保代码的其余部分在进行这些更改时不会中断。测试还有助于确保功能是可重复的,不受外部参数的影响,例如硬件和时间。数据科学的测试驱动开发相对较新,出现了许多实验和突破。

原木

日志对于理解运行程序时发生的事件很有价值。想象一下,一个模型每天晚上都在运行,第二天早上就在产生可笑的结果。日志消息有助于更好地了解原因、背景,并找出解决问题的方法。由于问题发生时我们并不在现场查看和调试,因此打印出描述性的日志消息来帮助追溯问题和理解代码中发生了什么是非常重要的。

看看几个例子,学习写好日志消息的技巧。

提示:专业而清晰

**BAD:** 
Hmmm… this isn’t working???**BAD:** 
idk…. :(**GOOD:** 
Could not parse file.

提示:要简洁,使用正常大小写

**BAD:** 
Start Product Recommendation Process.**BAD:** 
We have completed the steps necessary and will now proceed with the recommendation process for the records in our product database.**GOOD:** 
Generating product recommendations.

提示:选择合适的日志级别

**DEBUG**
level you would use for anything that happens in the program.**ERROR**
level to record any error that occurs.**INFO**
level to record all actions that are user-driven or system specific, such as regularly scheduled operations.

提示:提供任何有用的信息

**BAD:** 
Failed to read location data.**GOOD:** 
Failed to read location data: store_id 8324971.

代码审查

代码 reviews⁶有益于团队中的每个人,促进最佳编程实践并为生产准备代码。代码审查是工作中常见的 practice⁷,这是有充分理由的。审查彼此的代码有助于发现错误,确保可读性,检查产品级代码是否符合标准,并在团队中共享知识。它们对评审者和团队都是有益的。理想情况下,一个数据科学家的代码由另一个数据科学家审查,因为在数据科学中有特定的错误和标准需要检查——例如,数据泄漏、对功能的误解或不适当的评估方法。

在审查代码时,仔细检查一些问题。

**Is the code clean and modular?** * Can I understand the code easily?
* Does it use meaningful names and whitespace?
* Is there duplicated code?
* Can you provide another layer of abstraction?
* Is each function and module necessary?
* Is each function or module too long?**Is the code efficient?**
* Are there loops or other steps we can vectorize?
* Can we use better data structures to optimize any steps?
* Can we shorten the number of calculations needed for any steps?
* Can we use generators or multiprocessing to optimize any steps?**Is documentation effective?** * Are in-line comments concise and meaningful?
* Is there complex code that’s missing documentation?
* Do function use effective docstrings?
* Is the necessary project documentation provided?**Is the code well tested?** * Does the code high test coverage?
* Do tests check for interesting cases?
* Are the tests readable?
* Can the tests be made more efficient?**Is the logging effective?** * Are log messages clear, concise, and professional?
* Do they include all relevant and useful information?
* Do they use the appropriate logging level?

关于如何实际编写代码评审的一些提示。

提示:使用代码棉绒

这可以节省大量的代码审查时间。Code linter 可以自动检查编码标准。作为一个团队,就一个风格指南达成一致以处理关于代码风格的分歧也是一个好主意,无论这是一个现有的风格指南还是作为一个团队一起创建的。

提示:解释问题并提出建议

与其命令人们以特定的方式改变他们的代码,还不如向他们解释当前代码的后果,并由提出改进建议。如果他们理解流程并接受建议,而不是听从命令,他们会更容易接受反馈。他们也可能是故意以某种方式做这件事的,把它作为一个建议会促进建设性的讨论,而不是反对。

**BAD:** 
Make model evaluation code its own module - too repetitive.**BETTER:** 
Make the model evaluation code its own module. This will simplify models.py to be less repetitive and focus primarily on building models.**GOOD:** 
How about we consider making the model evaluation code its own module? This would simplify models.py to only include code for building models. Organizing these evaluations methods into separate functions would also allow us to reuse them with different models without repeating code.

提示:保持你的评论的客观性

尽量避免在评论中使用“我”和“你”这样的字眼。避免听起来很私人的评论,将评审的注意力转移到代码上,而不是代码本身。

**BAD:** 
I wouldn't groupby genre twice like you did here... Just compute it once and use that for your aggregations.**BAD:** 
You create this groupby dataframe twice here. Just compute it once, save it as groupby_genre and then use that to get your average prices and views.**GOOD:** 
Can we group by genre at the beginning of the function and then save that as a groupby object? We could then reference that object to get the average prices and views without computing groupby twice.

提示:提供代码示例

当提供代码评审时,节省作者的时间,并通过写出代码建议使他们容易对反馈采取行动。这表明我们愿意花一些额外的时间来审查他们的代码,并帮助他们解决问题。通过代码而不是解释来演示概念可能会快得多。

审查代码的示例:

first_names = [] 
last_names = [] for name in enumerate(df.name):     
  first, last = name.split(' ')     
  first_names.append(first)     
  last_names.append(last) df['first_name'] = first_names 
df['last_names'] = last_names**BAD:** 
You can do this all in one step by using the pandas str.split method.**GOOD:** 
We can actually simplify this step to the line below using the pandas str.split method.df['first_name'], df['last_name'] = df['name'].str.split(' ', 1).str

参考

PEP 257 — Docstring 约定
bootstrap github
ned batchelder
数据科学出错的四种方式以及测试驱动的数据分析如何帮助
集成测试
代码评审指南
代码评审最佳实践

免责声明:本文基于 Python 编程语言。也就是说,代码和文档样本将使用 Python 作为参考。

你知道权重和偏差吗?而不是用梯度下降法计算出来的。

原文:https://towardsdatascience.com/do-you-know-about-the-weights-and-biases-not-the-ones-calculated-using-gradient-descent-b7469b91e61a?source=collection_archive---------51-----------------------

每个数据科学家都应该使用该工具的 6 个理由

克里斯·利维拉尼在 Unsplash 上的照片

你知道权重和偏差吗?而不是使用梯度下降计算的权重和偏差。我说的是用于机器学习的权重和偏见开发者工具。

我最*偶然发现了这个非常酷的机器学习工具——权重和偏见,很快我就发现自己在玩它。因此,我决定与数据科学社区分享我对使用这一出色工具的看法。

如果你没有听说过它,那么让我告诉你它提供了什么,如果你是一个机器学习从业者,为什么你应该使用它。如果你已经知道了,请随意评论这篇文章。为了明确起见,我将在本文中把权重和偏差称为 W&B。

1.追踪机器学习实验变得简单多了

您如何跟踪您的模型、它们的超参数和它们的性能?当你继续实验的时候,你会用电子表格或记事本记录你建立的模型的所有细节吗?我经常这样做。有一次,在我的一个课程项目中,我在追求产生可重复的结果和更高的精确度方面更进一步,我发现自己复制了 Jupyter 笔记本,每个实验模型都有一个笔记本。这使我能够快速比较和巩固我的发现。现在,不再有这样的东西了。

现在,您可以专注于调整您的模型,而不必担心记下超参数或结果。让 W&B 为您处理所有这些。

通过向您的程序添加几行代码,W&B 将负责记录您的模型从输入(超参数)到输出(评估指标)的所有细节。稍后,这些记录的细节会以一些非常容易阅读的图形显示给你。您所需要做的就是啜饮您最喜欢的饮料,同时记录详细信息,并观察那些漂亮的度量图在您的模型构建时自动为您生成。

此外,您还将拥有关于您运行的模型或实验的所有必要的(A-Z)细节,所有这些都组织在一个地方,因此您可以随时回来查看。所有这些信息都可以在同一个*台上获得,那就是您的个人仪表盘。

典型的权重和偏差仪表板。现场演示来源:https://app.wandb.ai/example-team/keras-mnist

2.超参数调谐变得更加容易

来源:https://imgur.com/gallery/CAXMU

超参数调整是一件棘手的事情,我希望你们都同意我的观点。当您有几十个可以调整的超参数时,很难注意到调整超参数对优化指标的影响。现在,我们都听说过网格搜索、随机搜索和用于超参数调整的贝叶斯优化,但我们也知道所有这些技术的计算成本都很高。对于神经网络,这些技术都不是有效的。我过去常常根据自己的判断微调超参数,非常努力地注意优化指标的变化。

现在,W&B 的一个很好的功能——超参数扫描可以拯救我们。在这个所谓的超参数扫描中,W&B 创建*行坐标图,从而更容易发现优化指标和特定超参数之间的关系。如果您不熟悉*行坐标图,以下是它在 W&B 仪表板中的样子。你可以查一下住在这里的

*行坐标图—权重和偏差中的超参数扫描,来源:【https://docs.wandb.com/app/panels/parallel-coordinates

你可以看到,你的模型的不同运行的所有超参数都在一个简洁的图形中。此外,您甚至可以搜索最佳跑步记录。这个图也可以用几行代码添加到您的个人仪表板中!想象一下,在 Jupyter 笔记本上为这样的功能编写代码,而不是用 W&B 编写几行代码。

3.自定义可视化

除了通常的机器学习情节,W&B 还有许多东西可以提供。你基本上可以设计自己的可视化效果,从直方图,散点图,酷三维图,媒体可视化和许多其他先进的可视化。它提供了设计您喜欢的仪表板的灵活性。

在建立一个模型后,我经常做的一件事就是查看错误标注的例子。例如,在处理图像时,我想查看标签不正确的图像。每次实验时,您甚至可以设计自己的自定义可视化来显示来自验证集的那些错误标记的图像。同样,只需几行代码!

以下是训练示例图像和预测图像在您的仪表板上的自定义可视化效果。

添加自定义可视化的示例。现场演示来源:https://app.wandb.ai/sweep/simpsons

这只是你可能做的事情之一,当你把这些自定义的可视化添加到你的仪表板时,你可以变得更有创造性。

4.也要注意你的系统指标

如果你像我一样喜欢在你的模型运行时查看 CPU/GPU 内存的使用量,那么我希望你会喜欢这个很酷的功能。W&B 自动记录有用的系统指标,如 CPU/GPU 利用率、温度、分配的内存。并且,它为你创建了一个漂亮的图表,当你的模型被训练的时候,你可以追踪你的系统是如何应对的。在下图中,您可以看到这些指标是如何呈现在您的仪表板上的。也可以查一下住在这里

权重和偏差中的系统度量,来源:【https://app.wandb.ai/sweep/sweeps-tutorial/

所以,所有这些都可以实现——你可以猜到我接下来要说什么,但是——如果你已经在项目中正确加载了 W&B,就不需要额外的代码。它每 2 秒自动记录一次系统指标,*均记录时间为 30 秒。很酷,不是吗?

5。与流行框架集成

无论你来自 PyTorch 社区,还是 Tensorflow,你使用 Colab 或 Jupyter,他们都可以覆盖你。权重和偏差很容易与大多数流行的机器学习框架和工具集成。

您可以查看 Weights and Biases 文档,看看它是否集成了您最喜欢的框架和您最喜欢的工具

6.一个屋檐下的一切

关于 W&B 最好的一点是,每个记录的细节都组织在一个项目下,项目名称是您在项目中加载工具时指定的。它的作用是,为你的项目分配一个工作空间。正如我们在前面的例子中看到的,仪表板是工作区的一部分,当然工作区还提供了其他特性,这超出了本文的范围。但故事的寓意是,你创建的每一个可视化,你为那个项目记录的每一个细节,你所有的实验都可以在这个项目工作区下很好地组织起来——在一个屋檐下。不再疯狂地搜索机器学习实验笔记。

总之,这个工具旨在将所有机械 ML 实验跟踪与需要大脑汁的实际机器学习任务分开并自动化。因此,现在数据科学家可以继续利用他们的大脑汁液来建立有用的机器学习模型,而权重和偏见则完成所有不需要数据科学家关注的繁重工作。

他们的工具正在被包括 OpenAI 和丰田在内的尖端机器学习团队使用?为什么不是你?

另外,对于个人从业者是免费的!

我希望我已经引发了你对使用这个很酷的机器学习实验跟踪工具的足够兴趣。如果你碰巧学会使用这个工具,请在评论中告诉我你最喜欢的功能。请继续关注一篇关于如何开始研究重量和偏差的文章。当我写完这篇文章后,我会编辑它的链接。如果您非常感兴趣,那么您可以随时查看他们的文档(参见参考资料)并立即开始。感谢您的宝贵时间!😃

参考资料:

[1]权重和偏差,权重和偏差文档,https://docs.wandb.com/

[2] Lukas Biewald,机器学习实验跟踪(2020),https://towardsdatascience . com/Machine-Learning-Experiment-Tracking-93b 796 e 501 b 0

你知道 Python 有内置数据库吗?

原文:https://towardsdatascience.com/do-you-know-python-has-a-built-in-database-d553989c87bd?source=collection_archive---------0-----------------------

照片由麦克默里朱莉Pixabay 拍摄

Python 内置库 sqlite3 简介

如果你是一名软件开发人员,我相信你一定知道甚至使用过一个非常轻量级的数据库——SQLite。它几乎拥有关系数据库所需的所有功能,但所有内容都保存在一个文件中。在官方网站上,这里有一些您可以使用 SQLite 的场景。

  • 嵌入式设备和物联网
  • 数据分析
  • 数据传输
  • 文件存档和/或数据容器
  • 内部或临时数据库
  • 在演示或测试期间替代企业数据库
  • 教育、培训和测试
  • 实验性 SQL 语言扩展

你可能有更多的理由想使用 SQLite,请查阅文档。

[## SQLite 的适当用法

SQLite 不能直接与客户机/服务器 SQL 数据库引擎相提并论,如 MySQL、Oracle、PostgreSQL 或 SQL…

www.sqlite.org](https://www.sqlite.org/whentouse.html)

最重要的是,SQLite 内置于 Python 库中。换句话说,你不需要安装任何服务器端/客户端的软件,也不需要保持某个东西作为服务运行,只要你用 Python 导入了这个库并开始编码,那么你就拥有了一个关系数据库管理系统!

导入和使用

照片由pix abay上的 copyright free pictures 拍摄

当我们说“内置”的时候,意思是你甚至不需要运行pip install来获取库。只需通过以下方式导入即可:

import sqlite3 as sl

创建到数据库的连接

不要为驱动程序、连接字符串等等而烦恼。您可以创建一个 SQLite 数据库并拥有一个简单的连接对象,如下所示:

con = sl.connect('my-test.db')

在我们运行这行代码之后,我们已经创建了数据库,并且已经将它连接到数据库。这是因为我们要求 Python 连接的数据库不存在,所以它自动创建了一个空数据库。否则,我们可以使用相同的代码连接到现有的数据库。

创建表格

然后,让我们创建一个表。

with con:
    con.execute("""
        CREATE TABLE USER (
            id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
            name TEXT,
            age INTEGER
        );
    """)

在这个USER表中,我们添加了三列。正如您所看到的,SQLite 确实是轻量级的,但是它支持常规 RDBMS 应该具有的所有基本特性,比如数据类型、可空性、主键和自动增量。

运行这段代码后,我们应该已经创建了一个表,尽管它没有输出任何内容。

插入记录

让我们在刚刚创建的USER表中插入一些记录,这也可以证明我们确实创建了它。

假设我们想一次插入多个条目。Python 中的 SQLite 可以轻松实现这一点。

sql = 'INSERT INTO USER (id, name, age) values(?, ?, ?)'
data = [
    (1, 'Alice', 21),
    (2, 'Bob', 22),
    (3, 'Chris', 23)
]

我们需要用问号?作为占位符来定义 SQL 语句。然后,让我们创建一些要插入的样本数据。使用连接对象,我们可以插入这些样本行。

with con:
    con.executemany(sql, data)

在我们运行代码后,它没有抱怨,所以它是成功的。

查询该表

现在,是时候验证我们所做的一切了。让我们查询该表以获取示例行。

with con:
    data = con.execute("SELECT * FROM USER WHERE age <= 22")
    for row in data:
        print(row)

你可以看到它是多么简单。

同样,尽管 SQLite 是轻量级的,但作为一个广泛使用的数据库,大多数 SQL 客户端软件都支持消费它。

我用的最多的是 DBeaver,大家看看是什么样子的。

从 SQL 客户端(DBeaver)连接到 SQLite DB

因为我用的是 Google Colab,所以我要把my-test.db文件下载到我的本地机器上。在您的情况下,如果您在本地机器上运行 Python,您可以使用您的 SQL 客户端直接连接到数据库文件。

在 DBeaver 中,创建一个新连接,并选择 SQLite 作为 DB 类型。

然后,浏览数据库文件。

现在,您可以在数据库上运行任何 SQL 查询。它与其他常规关系数据库没有什么不同。

与熊猫无缝集成

图片由 Pixabay 上的图形妈妈团队拍摄

你以为就这些?不会,事实上,作为 Python 的内置特性,SQLite 可以与 Pandas Data Frame 无缝集成。

让我们定义一个数据框。

df_skill = pd.DataFrame({
    'user_id': [1,1,2,2,3,3,3],
    'skill': ['Network Security', 'Algorithm Development', 'Network Security', 'Java', 'Python', 'Data Science', 'Machine Learning']
})

然后,我们可以简单地调用to_sql()方法将数据帧保存到数据库中。

df_skill.to_sql('SKILL', con)

就是这样!我们甚至不需要预先创建表,列的数据类型和长度就会被推断出来。当然,如果你愿意,你仍然可以事先定义它。

然后,假设我们想要连接表USERSKILL,并将结果读入熊猫数据框。也是天衣无缝。

df = pd.read_sql('''
    SELECT s.user_id, u.name, u.age, s.skill 
    FROM USER u LEFT JOIN SKILL s ON u.id = s.user_id
''', con)

超级爽!让我们将结果写入一个名为USER_SKILL的新表中。

df.to_sql('USER_SKILL', con)

然后,我们还可以使用我们的 SQL 客户机来检索该表。

摘要

照片由monar _ CGI _ ArtisPixabay 上拍摄

的确,Python 中隐藏着很多惊喜。它们并不意味着被隐藏,只是因为 Python 中存在太多现成的特性,人们无法发现所有这些特性。

在本文中,我介绍了如何使用 Python 内置库sqlite3在 SQLite DB 中创建和操作表。当然,它也支持更新和删除,但我认为你会尝试自己在这之后。

最重要的是,我们可以很容易地将一个表从 SQLite 数据库读入 Pandas 数据框,反之亦然。这允许我们更容易地与轻量级关系数据库进行交互。

您可能会注意到 SQLite 没有身份验证,这是它的设计行为,因为所有东西都需要是轻量级的。去发现 Python 中更多令人惊讶的特性吧,尽情享受吧!

本文中的所有代码都可以在我的 Google Colab 笔记本中找到。

[## SQLite 熊猫示例

创建数据库、创建表、检索和连接

colab.research.google.com](https://colab.research.google.com/drive/1Nq6VjezN4Djx5smI0esP8VJ8QCWr73DR?usp=sharing) [## 通过我的推荐链接加入 Medium 克里斯托弗·陶

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

medium.com](https://medium.com/@qiuyujx/membership)

如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和其他成千上万的作者!(点击上面的链接)

了解通用建模框架是所有数据科学家的必备技能

原文:https://towardsdatascience.com/do-you-know-the-general-modeling-framework-c422f866a2dc?source=collection_archive---------89-----------------------

图片由 Wokandapix 来自 Pixabay

统计模型的基础

当涉及到建立统计模型时,我们这样做的目的是为了理解或*似我们世界的某个方面。

通用模型的概念在 g 框架中很好地分解了我们可能用来产生所述理解的目的和方法。

一般的建模框架是什么?

看看下面公式描述的一般建模框架:

y = f(x) + e

  • y:结果变量/我们试图更好理解的任何东西
  • x:自变量或任何我们用来解释 y 的东西
  • f():应用于 x 时*似于 y 值的函数
  • e:我们通过 X 的函数对 Y 的解释与实际 Y 之间的误差或距离。例如:我们不能通过 f(X)解释的一切

这里有几个要点。组成 y 的,是我们对 y 的理解,它是 x 的函数,上面有误差。我们努力确定这个功能就是建模的目的。如果你听说过信号&噪声,功能是信号、符号、指示器,噪声是误差、变化等。

这一框架的应用

让我们来看两个目的或方法,您可以结合这个框架来利用它们来指导您的建模过程。

至于建模机制,它的大部分将保持不变。这里的核心区别是指导你的过程的哲学。

解释或预测

为解释而建模

当谈到为解释而建模时,驱动力是我们试图理解哪些变量可能导致一个结果或与之相关

以此为序,让我们进入一些探索性的数据分析,开始我们的解释建模过程。

预测建模

一旦我们对 F 有了理解,一旦你梳理出了对(X 的)函数的解释,你就可以把它应用到其他数据(另一个 X)来产生预测。

虽然我们从事的 EDA 在很大程度上是相同的,但目的/用途可能会有所不同。同样,使用 X 和 y 之间的历史关系生成预测的意图突出了这种差异。

在为预测建模时,我们仍然发现自己处于不知道函数或误差的困境中,这仍然需要分开来理解。

更重要的是,当为了解释而建模时,我们非常关心函数的形式,而当为了预测而建模时,我们就不那么关心了。在这种情况下,我们关心的是我们的预测是否准确,因此得名..预测建模。

探索性数据分析

无论是为了解释或预测而建模,我们仍然会经历探索性数据分析的过程。这个过程会给我们正确的信息,指引我们理解 X 的功能的方向。

让我们从探索性数据分析(或者我们在商业中称之为 EDA) ).EDA 的目的是让我们在建模过程之前进行一系列的活动,这些活动有助于更好地理解我们试图建模的每个自变量和因变量,并在较高层次上理解它们之间的关系。

我从 kaggle 下载了一份房价数据。你可以在这里找到:https://www.kaggle.com/shree1992/housedata/data

让我们来看看住房数据

我们通常会用一系列函数来启动这个过程,这些函数可以让我们快速了解数据。

一瞥或一串

glimpse 和 str 都将为您提供字段、它们的数据类型、维度和样本的视图。

glimpse(housing)

str(housing)

我们现在来看看 head,看看数据集的前几行。

head(housing)

让我们可视化变量分布

我们将加载ggplot2并制作一个直方图来查看其中的一些变量

library(ggplot2)ggplot(housing, aes(x = bathrooms)) +
  geom_histogram(binwidth = 1)

通过geom_histogram,我们可以看到属于每个数字类别的房屋数量。我们可以看到最多的家庭有 2.5 个浴室。

为了举例,让我们对更多的变量做同样的事情。

下面你会看到*方英尺的分布。

我们可以看到稍微偏右的分布。

让我们想象一下房价。

正如你所看到的,由于一些极端价格的房屋,这有点偏右。

可视化扭曲的数据

在可视化分布时需要记住的一件事是,可视化变量的 log10 分布。

记录日志的好处在于它保留了值的顺序。

让我们快速浏览一下!

我们看到*方英尺居住分布有些右偏,让我们来想象一下。

housing %>%
  mutate(sqft_living_log = log10(sqft_living))%>%
  ggplot(aes(x = sqft_living_log)) +
  geom_histogram()

正如我们在上面看到的,我们有一个*方英尺的正态分布的对数值。这使得比较这些较低的值和那些存在于右尾较大的极端值变得更容易。

让我们可视化变量组合

现在让我们来看一个涉及多个变量的类似过程。这将让我们了解这些变量之间的关系。

我们将首先从 sqft & price 开始。

housing %>%
  ggplot(aes(x = sqft_living, y = price)) +
  geom_point()

这两个变量具有线性关系,相关系数为 0.43

现在我们知道这两个变量都是右偏的,让我们在将它们转换成它们的 log10 自我后再一次可视化它们。

housing %>%
  mutate(sqft_living_log = log10(sqft_living),
         price_log = log10(price))%>%
  ggplot(aes(x = sqft_living_log, y = price_log)) +
  geom_point()

为解释和预测重新建模

现在,我们已经经历了一些 EDA,让我们重温一下建模的概念。目的是了解哪些因素解释了 y,或者当它与住房数据相关时,变量(*方英尺、浴室数量等)如何。)或许可以解释 y。

当谈到预测建模时,我们的目的是估算房价。我们不一定关心什么变量对我们的函数有贡献,也不关心函数实际上由什么组成……我们真正关心的是我们的模型有多接*现实。一个很好的例子是 Zillow &他们的 zestimate。他们绝对关心他们当前的模型所产生的结果的准确性。

建模时,要记住的一点是,我们不会了解误差是如何产生的……这里的目的是通过评估 X 和 y 之间的关系来推导函数。我们之前提到的函数是信号,因此建模是我们分离信号和噪声的过程。

结论

希望对通用建模框架的介绍能让你对如何思考建模有所了解。

祝数据科学快乐!

你认识这朵花吗?使用 PyTorch 的图像分类器

原文:https://towardsdatascience.com/do-you-know-this-flower-image-classifier-using-pytorch-1d45c3a3df1c?source=collection_archive---------50-----------------------

Udacity 数据科学家纳米学位计划项目

https://en.wikipedia.org/wiki/Oenothera_speciosa

这个项目是数据科学家纳米学位项目 Udacity 的一部分:图像分类器项目,目标是应用深度学习技术来训练图像分类器,以识别不同的花卉品种

让我们从使用 CRISP-DM 流程(数据挖掘的跨行业流程)开始:

  1. 业务理解
  2. 数据理解
  3. 准备数据
  4. 数据建模
  5. 评估结果
  6. 部署

业务理解

图像分类是当今非常常见的任务,它包括将图像和一些类别作为输入,并输出输入图像属于一个或多个给定类别的概率。关于这一点,我想推荐安妮·邦纳的这个令人敬畏的故事。总之,这个项目的目标是建立一个应用程序,可以对任何一组标记图像进行训练,以对给定的输入进行预测。由uda city提供的具体数据集是关于花的

数据理解

该数据集包含属于 102 个不同类别的花的图像。这些图像是通过搜索网页和拍照获得的。这些图像具有很大的比例、姿态和光线变化。此外,有些类别在类别内有很大的差异,还有几个非常相似的类别。更多信息请参见 M. Nilsback、A. Zisserman 撰写的本文

准备数据和数据建模

Udacity 在 json 文件 cat_to_name.json 中提供了图像的标签以及类别名称和标签之间的映射

类别名称和标签之间的映射

Udacity 还在一个有组织的目录树中提供了所有数据集:

数据目录树

在每个文件夹中,都有一个以类别标签命名的文件夹,我们可以在其中找到图像。该类别的 jpeg 格式

该项目分为多个步骤:

  • 加载并预处理图像数据集
  • 在数据集上训练图像分类器
  • 使用训练好的分类器来预测图像内容

评估结果

应用程序使用的默认网络是由牛津大学的 K. Simonyan 和 A. Zisserman 在论文“Vvery Deep 卷积网络用于大规模图像识别中提出的卷积神经网络模型

https://neurohive.io/en/popular-networks/vgg16/

为了使用该网络,我们将图像的大小调整为 224x224 像素,因为 cov1 层的输入是固定大小的 224 x 224 RGB 图像。Udacity 通过一个 Jupyter 笔记本为这个项目的开发提供了指导,所以很多步骤都非常简单。为了帮助网络泛化以获得更好的性能,我们将应用随机缩放、裁剪和翻转等变换

您将使用的预训练网络是在 ImageNet 数据集上训练的,其中每个颜色通道都是单独标准化的。对于所有三组图像,您需要将图像的*均值和标准偏差归一化到网络预期的值。*均值为[0.485, 0.456, 0.406],标准偏差为[0.229, 0.224, 0.225],从 ImageNet 图像中计算得出。这些值将使每个颜色通道以 0 为中心移动,范围从-1 到 1

现在我们有了预训练网络,我们必须:

  • 使用 ReLU 激活和退出,定义一个新的、未经训练的前馈网络作为分类器
  • 使用预先训练的网络,使用反向传播来训练分类器层,以获得特征
  • 跟踪验证集的损失和准确性,以确定最佳超参数

网络安装程序

默认情况下,如果通过勾选torch.cuda.is_available()GPU 可用,则使用 GPU 完成训练

torch.cuda增加了对 CUDA 张量类型的支持,实现了与 CPU 张量相同的功能,但是它们利用 GPU 进行计算。更多信息点击此处

使用 10 个时期,我们在训练数据集上获得了 0.8944 的准确度

培训结果

在验证数据集上,我们获得了 0.8563 的准确度

展开

一个破折号的应用程序已经开发出来作为用户界面:可以上传一张图片进行分类。当没有图像被上传时,应用程序显示关于训练数据集的一些信息的概述

Dash web 应用程序主页

当提供一幅图像并按下分类按钮时,应用程序显示该图像的分类概率分布,并与相应类别的训练数据集中的图像进行比较

图像分类

在所示的例子中,我在 Google image 上搜索了花朵粉色樱草花,并将其作为输入来检查我的分类器的输出

你可以在我的网站上的这个页面中尝试一下

有趣的事实

我尝试对我的个人资料图片进行分类,显然我是一个剑百合****

我的个人资料图片分类

https://www . gardenia . net/storage/app/public/uploads/images/detail/216420% 20g ladiolus % 20 adrenaline optimized . jpg

****注意:代码可以在这个 github 仓库中找到

你现在可以从谷歌研究院获得 5779 份出版物。

原文:https://towardsdatascience.com/do-you-know-you-can-have-access-to-5779-publications-from-google-research-right-now-b42b2313c325?source=collection_archive---------49-----------------------

照片由晨酿Unsplash 拍摄

如果你正在为你的下一个研究或人工智能项目寻找灵感,这里你可以找到一个可以游泳的大湖:谷歌研究!

谷歌研究是谷歌的一个部门,专注于稍微远一点的项目或需要特定类型领域专业知识的项目,他们经常推出让世界变得更美好的产品。

我们可以将研究项目分为两类——短期的,如改进某些现有产品的性能;与长期相比,他们正在创建一个全新的产品/框架,如 TensorFlow 或自动驾驶汽车。

谷歌研究解决了定义今天和明天的技术的挑战,你可以在他们发表研究成果时获得。确切地说,您可以访问所有 5779 种可用出版物(2019 年只有 793 种),从中获得灵感、获得信息和学习。

来源:谷歌研究数据库

我正在使用这个令人印象深刻的研究数据库来支持我的新书的写作:用人工智能解决最大的全球挑战,我计划在明年 3 月推出。我正在写人工智能如何支持团队、公司和组织应对全球性挑战,如人工智能伦理、更准确的洪水预测、野生动物研究和儿童扫盲的工具等,并获得一些灵感和支持我对研究进展的理解。

我发现这个数据库是一个方便的温度计,特别是在量子算法和硬件的进步,新的机器学习算法和 AutoML 的改进等方面…

Google Research 的目标是创造一个充满产品影响机会的研究环境,建立一个积极受益于研究的生产环境,并为我们的员工提供自由,以解决与直接产品需求无关的重大研究问题。

研究领域

来源:谷歌研究数据库

从进行基础研究到影响产品开发,谷歌研究团队每天都在影响着数十亿人使用的技术。

正如他们网站上所描述的,谷歌研究团队渴望做出影响每个人的发现,我们方法的核心是分享我们的研究和工具,以推动该领域的进步。我们的研究人员定期在学术期刊上发表文章,以开源方式发布项目,并将研究成果应用于谷歌产品。

如果你愿意,你可以从总共 5779 份出版物中获得谷歌研究自 1998 年以来的所有出版物。

链接:谷歌研究数据库

还有一件事…

我刚刚在亚马逊上出版了我的新电子书,并且我已经开始着手在今年出版一些其他的书……保持联系,关注我,让我们一起努力。

[## 2020 年的人工智能:写人工智能的一年

2020 年的人工智能:写人工智能的一年。下载一次,阅读…

www.amazon.com](https://www.amazon.com/dp/B08RSJRNSN/)

你理性地做决定吗?

原文:https://towardsdatascience.com/do-you-make-decisions-rationally-d12a0eb9c89b?source=collection_archive---------12-----------------------

第 1 部分,共 3 部分——来自行为经济学的两个自我测试场景

好奇想知道你是否是一个理性的决策者并且正在进行数据驱动的决策?想象下面的场景,回答选择题就知道了!

图片:来源

小赌博游戏

让我们假设我的客厅里有一个装满 90 个高尔夫球的桶,我们要用它来玩一个赌博游戏。(哇哦,你在想,那可是个大水桶。是的,我们正在练习运用我们的想象力。)

你的工作是预先挑选两个潜在赌博游戏的条件。我将抛硬币来决定我们是玩游戏 1 还是游戏 2。

然后我会闭上眼睛,把球彻底打乱,拿出一个球给你看,我们会根据你在这个测验中的选择来看你是否赢了。(你将通过你的屏幕观看我的直播,这样我就不能作弊了)。

我们只玩一个游戏——这意味着你只有一次机会获得 100 美元的奖金,并且不能对冲任何赌注——但在我们开始之前,你不会知道是哪一个游戏,所以我要求你提前选择两种可能性的答案。明白了吗?好了,最重要的事情来了——你有关于水桶的什么信息?

图片:来源

桶里的东西

桶里有 30 个白色球60 个黄色或粉色的其他球(你不知道每种有多少)。

现在轮到你选择了。

第一场

你可以选择赌博 A赌博 B :

赌博 A: 如果我抽到一个白色的球,你会得到 100 美元,否则就是 0 美元。

赌博 B: 如果我抽到一个黄色的球,你会得到 100 美元,否则就是 0 美元。

明智地选择,在向下滚动到游戏 2 之前,记下你的选择( A 或 B )。如果你是如此强烈的漠不关心,以至于你很乐意让硬币为你做决定,那就做吧。

图片:来源

提醒: 桶里还有 30 个白色的球和另外 60 个不是
粉色就是黄色的球。

第二场

您可以在赌博 C赌博 D 之间进行选择:

赌博 C: 如果我画一个白色或粉色的球,你会得到 100 美元,如果球是黄色的,你会得到 0 美元。

赌博 D: 如果我画一个粉色或黄色的球,你会得到 100 美元,如果球是白色的,你会得到 0 美元。

记下你的选择( C 或 D ),这样我们就可以开始派对了。和以前一样,如果你真的没有偏好,抛硬币决定。

你理性选择了吗?

我们很快就会知道,但首先你为什么不点击这里看看你的选择与其他人的选择相比如何。这些选项是:

  • 甲&丙
  • A & D
  • B & C
  • B & D

继续,看看其他人选了什么,然后向下滚动查看您的诊断和解释…

图片:来源

准备好找出为什么大多数人对这样的决定不理智了吗?在此继续第 2 部分

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

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

你真的有数据策略吗?

原文:https://towardsdatascience.com/do-you-really-have-a-data-strategy-ff08795f10ce?source=collection_archive---------34-----------------------

许多公司声称拥有数据战略。让我们看看是什么让这成为现实。

玛丽·莱扎瓦Unsplash 上拍摄的照片

我读到了越来越多关于数字化转型和旨在实现业务转型或拥抱数字化之旅的企业的信息。

深入挖掘这些案例,有时你会感到失望。数据重复、角色重叠和代价高昂的数据湖仍然是一些公司面临的现实。

我们如何确定拥有一个健壮的数据策略?

我试着采用汉布里克教授(哥伦比亚大学)和弗雷德里克森教授(德克萨斯大学)提出的战略模型来看看我们如何能容易地检查我们是否在朝着正确的方向前进。你可以在下面的图表中看到这个模型。

作者根据 Hambrick D .,fredrick son j .(2001)“你确定你有策略吗?”《管理行政人员学会》,第 15 卷第 4 期。

  1. 策略是一组选择。

罗伯特·阿纳施在 Unsplash 上拍摄的照片

定义战略意味着做出清晰可见的决策

如果我们谈论数据,它意味着定义我们需要什么数据,我们有哪些数据以及如何使用它们。在过去的几年里,每个公司的数据量都呈指数级增长。其中大部分存在于 20 多年前的系统中,甚至不是为数据管理而设计的。这显然是一个需要克服的挑战。

如果我们有一个可靠的数据战略,我们就已经决定了我们想要用数据解决什么样的业务需求。我们已经确定了哪些数据我们可以使用,哪些数据我们不能使用(即由于质量差或缺乏数据)。我们已经选择了想要参与竞争的领域,并根据它们对公司整体战略的贡献对它们进行了优先排序。

2。战略需要指明实现目标的途径。

艾米丽·莫特在 Unsplash 上的照片

颠覆性、数字化、敏捷都是美妙而廉价的口号。

要实现它们,还需要更多的努力。

如果你有一个真正的数据战略,在如何实现数据的价值以促进业务需求上已经做出了选择。您可能会决定在使用数据之前专注于提高数据质量,或者从外部购买相同的数据(即客户信息以获得信用评级风险),从而一次性获得速度和准确性。

您可能已经决定从主数据开始,明确数据的治理和所有权。麦肯锡的一篇文章清楚地阐述了稳健的治理如何成为确保数据质量的关键。但根据我的经验,很明显,数据所有权不能只委托给 it 部门。

它必须靠*那些关心这些数据的人,也就是说职能或业务更受他们的影响。只有这样做,我们才能确保正确执行战略,关注有意义的事情。

这里的挑战是将数据转化为信息。在我看来,要做到这一点,需要三样东西:数据需要可用,质量不错,还需要加入一些情报。

而要做到这三点,你需要知道你的数据背后是什么。

3。选择您的竞争优势。

Joshua Coleman 在 Unsplash 拍摄的照片

这里要回答的问题是我们将如何取胜,什么将使我们成功实施数据战略。每一个数据策略都必须根据业务需求量身定制,并与业务策略紧密相连。

最有可能的是,我们赢得数据战略的方式将依赖于多种因素的组合。

举个例子,以我的经验来看,也许通过在 ERP 之上创建层来收集和汇总数据,比在全球范围内改变所有 ERP 更容易、更便宜,从而克服 ERP 的复杂性。

另一种方法是合理化应用程序,并构建一个包含足够数据的数据湖,以便能够对其进行处理。这可能意味着将预算从应用程序转移到这些层,减少对过时应用程序的投资,或者将它们的使用限制在核心功能上。也就是说,您可以决定使用 SAP 来管理您的财务和物流流程,而将建模、预测和深度数据分析的任务留给其他工具。

“最大的价值来自能够从不同种类的系统中收集和关联信息”—Anil Chakravarthy—Informatica 前首席执行官

4。罗马不是一天建成的

塔内利·拉蒂宁在 Unsplash 上拍摄的照片

速度和事件顺序是任何战略的两个组成部分。你必须有一个清晰的事件/项目顺序,还要定义执行的速度。

根据组织的文化,你可以走得更快,并行或首先创造一种改变的紧迫感。也许在一个业务中试验解决方案,然后在所有其他业务中展示并引起兴趣。

没有明确的顺序就开始执行一个数据项目,整体计划可能会让你付出更大的代价。许多公司在开始数据湖之旅时,并没有明确的目标:这转化为要维护的额外成本&复杂性。

战略的一部分必须是,在我看来,的人的成分。一个强大的数据战略必须使与数据相关的工作专业化:包括数据管家和数据科学家。一个不能离开另一个而存在。你可以拥有公司里最好的数据科学家,但是如果数据管家丢失了,他们不知道他们的数据有什么用,质量仍然不够好,无法进行任何准确的分析。如果你有最好的数据管家,但缺乏数据科学家,你就白白坐在了一座金山上。

5。我能从中得到什么?

照片由 Riccardo AnnandaleUnsplash 上拍摄

这是许多企业领导人在实施数据战略时会问你的典型问题。

虽然为执行数据策略所需的投资定价更容易,但量化其收益可能更困难。

然而,在我看来,这是至关重要的。您必须花时间确定容量释放、资源减少、硬件节省、质量差成本降低、决策速度提高

只要有适当的知识,所有这些方面都可以而且必须量化。通过这种方式,每当你开始一个项目时,你就可以让你的管理层兴奋起来,把你正在推动的节约或复杂性降低摆在桌面上

通过这样做,接受和认同的程度将会提高。

我见过为了把数字这个词放在网站上而采取数字策略的案例。但我也看到了成功的实施以及随之而来的强大的财务价值。

根据我的经验,这五项是验证您的数据策略并了解它是否足以全速前进的良好检查。

“没有数据,你只是另一个有观点的人”——w·爱德华·戴明

Luca Condosta(博士)是一名金融专业人士,拥有跨国企业的全球经验。对数据、领导力、战略和人充满热情。两本书的作者(可持续发展报告Natuzzi——意大利和谐制造者)喜欢寻找和分享故事。

你真的需要一个数据湖吗?

原文:https://towardsdatascience.com/do-you-really-need-a-data-lake-7faccb8c550d?source=collection_archive---------48-----------------------

编辑来自 Pixabay 的照片

让我帮你决定。

长期以来,数据湖在业界引起了相当大的轰动,并且通常被认为是所有数据问题的一站式解决方案。围绕数据湖的讨论误导了组织去设计那些对商业没有真正价值的数据湖。此外,多年来,关于数据沼泽的恐怖故事只会鼓励怀疑。如果您正在争论是否有必要建立一个数据湖来加强您的数据策略,那么这篇文章将为您提供一些启示,以便您能够做出决定。

您是否厌倦了从没有逻辑集中存储区域的不同系统中提取数据?

对于大多数处理各种数据源的组织来说,这是一个普遍问题。缺乏用于分析工作负载的集中式数据存储迫使数据消费者创建本地化系统,通常仅限于少数用户进行报告和分析。几个非标准化的流程最终导致数据孤岛的产生,这些数据孤岛有可能滚雪球般变成对数据访问、一致性和准确性的主要担忧。

数据湖架构可以将数据集中在分布式存储上,从而提供可扩展、快速、安全且经济的解决方案。这一点,加上强大的数据治理,最终可以解决数据孤岛问题,并使组织内的数据民主化。这些解决方案可以部署在内部、云中甚至混合基础架构上。

你是否会因为存储旧数据的成本很高而简单地删除它们?

随着数据的增长,数据库管理系统需要更多的计算能力,这导致许多设计决策,如分区和横向扩展,从而进一步增加费用。当成本不断上升时,IT 开始将数据归档,要么作为压缩数据库备份保存到更便宜的存储设备或*面文件中,要么在大多数情况下最终删除这些数据。存档数据或删除数据以降低费用可能会对 数据货币化 机会不利。

可以设计一个数据湖体系结构来实施数据保留策略,从而缓解控制数据增长的压力。借助便宜的 分层 存储,您可以轻松应用精心规划的保留策略并存储大量数据,而不会增加您的预算并大幅降低业务流程的开销。

您是否经常随着数据结构的变化而调整数据库?

如果您使用的是关系数据库,并且源数据的模式一直在变化,那么您要么忽略了正在进行的变化并可能丢失有价值的信息,要么花费资源调整数据库以适应源模式。不管怎样,你都不会赢。

数据湖允许存储原始数据(结构化/非结构化/半结构化),而无需运行任何前期 ETL 过程。您不会丢失正在进行的数据更改,还可以节省调整数据库表结构、ETL 管道等方面的费用。您(或消费者)可以在读取数据时定义数据的结构,而不是在存储数据时定义数据的结构(检查schema-on-read),这使得授权消费者可以以他们喜欢的任何方式读取数据。双赢。

您是否有不同的数据消费者需要相同数据集的不同形式?

并不是组织中的每个人都希望以一种特定的形式或方式消费数据。一些消费者需要符合其部门需求的关系形式的干净、结构化和必要的数据,一些消费者需要原始数据来运行机器学习实验,一些消费者属于受限类别并消费屏蔽数据。在传统*台中解决这些需求变得很麻烦(也很昂贵)。

一旦将原始数据存储在数据湖中,您就可以创建数据的逻辑视图,以便用户以他们想要的形式使用数据。您甚至可以创建流程,将结构化形式的数据存储到数据仓库中,并应用匿名化规则将数据推送给外部消费者。

你理解数据湖的概念吗?

关于数据湖有许多神话,在做出决定之前了解一些事实是很重要的。

  1. 数据湖是一个概念,不是一个产品。数据湖不是亚马逊 S3 或 Azure 数据湖存储或 Hadoop,而是一种指导如何在对象存储(如亚马逊 S3、ADLS、HDFS)或多个存储组件中存储和组织数据的架构。
  2. 数据湖并不能取代数据仓库。这是关于数据湖最大的困惑。以至于,当你在谷歌上搜索术语“数据湖”,你会发现大多数人把数据湖比作数据仓库。数据湖允许数据以原始格式存在,而数据仓库是存储经过处理、清理、结构化和感兴趣的数据的地方。数据湖和数据仓库是相互补充的概念,而不是相互替代的。
  3. 数据湖需要治理。您可以不经任何处理将原始形式的数据接收到数据湖中,但是一旦数据存储到数据湖中,就需要对其进行适当的编目、管理和控制,以确保数据只能被授权用户跟踪、识别和访问。
  4. 数据湖不是一个通用的架构。数据湖的设计因组织和使用案例而异。一个组织可以决定构建多个数据湖,或者一个数据湖可以服务于多个组织。无论哪种情况,具体的设计决策都是基于业务战略、基础设施、技术选择和人员技能做出的。

最后…

数据湖确实有巨大的好处,对于许多热衷于制定数据战略的组织来说,它可能是一个有吸引力的提议。你必须仔细审查它是否能解决你的业务问题,是否能与你组织中的其他技术*台很好地集成,以及是否能为企业创造真正的价值。做出好的 设计决策 并确保在整个组织中建立数据治理规则以使用数据湖是至关重要的。最重要的是,正是这些人能够让这一切成功,你将不得不支持和培养正确的技能,并鼓励一种 数据驱动的文化

深度学习真的需要 GPU 吗?

原文:https://towardsdatascience.com/do-you-really-need-a-gpu-for-deep-learning-d37c05023226?source=collection_archive---------21-----------------------

意见

获得一个 GPU 是深度学习的必备条件吗?了解 GPU 及其优势,并探索替代方案

卡斯帕·卡米尔·鲁宾在 Unsplash 上的照片

我一直是一个超级游戏迷,也是一个游戏迷。

从小到大,我看到的对显卡的唯一要求就是为了游戏的目的。

我很幸运,在我开始涉足人工智能和数据科学,尤其是深度学习之后,我意识到了显卡的真正潜力。

这几乎就像梦想成真。这就像是一箭双雕,因为我可以利用同一个显卡进行游戏以及学习和研究。

注意:GPU 和显卡的意思差不多,在本文中会互换使用。

GPU 针对训练人工智能和深度学习模型进行了优化,因为它们可以同时处理多个计算。它们拥有大量内核,可以更好地计算多个并行进程。

在本文中,我们将了解 GPU 和 CUDA 到底是什么,然后探讨图形处理单元的优势,以及如果您预算紧张,何时应该考虑购买它。最后,我们将讨论替代方案。

事不宜迟,让我们开始理解这些概念。

GPU 到底是什么?

照片由 Nana DuaUnsplash 上拍摄

图形处理单元是一种专用的电子电路,设计用于快速操作和改变存储器,以加速在帧缓冲器中创建图像,用于输出到显示设备。

GPU 是现代计算的关键部分。GPU 计算和高性能网络正在改变计算科学和人工智能。GPU 的进步为今天深度学习的发展做出了巨大贡献。

NVIDIA 提供了一种名为计算统一设备架构(CUDA) 的东西,这对支持各种深度学习应用至关重要。

CUDA 是 Nvidia 创建的并行计算*台和应用编程接口模型。它允许软件开发人员和软件工程师使用支持 CUDA 的图形处理单元(GPU)进行通用处理,这种方法称为 GPGPU。

这些 CUDA 核心在人工智能领域是高度有益和进化的。我们将在下一节进一步讨论这个话题。

GPU 的优势

Rafael Pol 在 Unsplash 上的照片

如前所述,NVIDIA GPUs 提供了 CUDA 内核的支持。

每种显卡的 CUDA 内核数量各不相同,但可以肯定的是,大多数显卡通常至少有 1000 个以上的内核。

当您使用 TensorFlow 或 Pytorch 等深度学习框架时,与使用 CPU 的相同性能相比,您可以利用这些 CUDA 核心来计算您的深度学习算法,速度要快得多。

虽然 CPU 一次只能执行少量操作,但 GPU 可以一次执行数千次这样的操作。仅举一个假设的例子,在一个质量不错的 GPU 的帮助下,一个需要在 CPU 上训练 2-3 个小时的任务可能在大约 10 分钟内完成。

GPU 是计算机视觉和超级计算的动态资源,具有深度学习和神经网络,可以执行复杂的任务,有时甚至超出人类的想象。

此外,GPU 还有许多其他应用。GPU 在嵌入式系统、移动电话、个人电脑、工作站和游戏控制台中都有应用。

您可以充分利用这些显卡来完成其他任务,如游戏和玩 AAA 游戏(AAA 游戏基本上是一种非正式的分类,用于由中型或大型发行商制作和发行的视频游戏,通常具有较高的开发和营销预算。)或其他需要 GPU 的图形软件用途,以及动画和设计。

GPU 在机器人领域也有巨大的应用范围,使高科技机器人能够通过集成人工智能来感知环境。

汽车行业对基于深度学习的自动驾驶汽车的应用也有很高的需求。为了改变未来,在这些汽车的开发上投入了大量的资金。

最后但同样重要的是,通过将数据用于理想的图像分割任务和其他医疗应用,这些 GPU 还可以在医疗保健和生命科学的医疗领域中找到各种应用。

什么时候应该考虑?

Viacheslav BublykUnsplash 拍摄

显卡挺贵的!

尤其是当你预算紧张的时候,你可能会很难决定是否要买显卡。那么,关于这个问题,你怎么能得出一个合理的结论呢?

我想提供的一个个人建议是,确保你在数据科学领域挖得更深。了解机器学习的概念,对深度学习有基本的概念理解。

如果你非常确定和自信地认为深度学习是你感兴趣的事情,并希望进一步探索这个有趣的话题,那么请放心地为自己购买一个。

如果您想知道在直接投入之前是否有任何替代选择或免费工具来测试该主题,那么您很幸运,因为有许多这些资源可用。

让我们研究一下这些替代办法和其他可行的选择。

可供选择的事物

尤金尼奥·马佐尼在 Unsplash 上的照片

如果你想测试深度学习,或者你已经得出结论,你不需要显卡,那么你可以选择什么样的替代品来进行深度学习?

首先,如果您想在自己的个人计算机上工作,并且您有一个能够进行一般计算的中等 CPU,那么您可以选择安装 TensorFlow 的 CPU 版本。这个简单的安装可以通过一个简单的 pip 命令来完成,如下所示:

pip install tensorflow

对于简单的深度学习计算,如处理 MNIST 数据集,如果您想利用 CPU 或 GPU 版本,不会有很大的区别。对于初级深度学习项目来说,CPU 版本应该很好。

然而,如果你想要实践经验和使用 GPU 的感觉,那么你可以在谷歌合作实验室谷歌实验室上完全免费地这样做。这是谷歌研究的一个产品。 Colab 允许任何人通过浏览器编写和执行任意 python 代码,特别适合机器学习、数据分析和教育。

在接下来的一周,我将会写两篇关于 Jupyter 笔记本和 Google Colab 的文章。如果你想了解使用它们的详细指南,请继续关注。

其他选择包括创建一个 AWS 云实例或使用 IBM Watson Studio,以及其他一些方法,在这些方法中,您可以为在云上使用 GPU 支付少量费用。

根据我的经验,这些是一些可供选择的方法。如果你有更好的替代建议,请在评论区告诉我。

但是有了这些替代品,你应该很容易就能自己探索深度学习,并对这个主题有一个基本的了解。

约翰·汤纳在 Unsplash 上拍摄的照片

结论

在本文中,我们讨论了 GPU 到底是什么以及它的众多优点。我还建议什么时候是考虑为自己拥有一个 GPU 的最佳时机。我们还检查了各种替代方案,这些方案可以帮助您在学习深度学习基础知识时茁壮成长,即使没有 GPU 也是如此。

所以,要回答“深度学习真的需要 GPU 吗?”简单来说—

如果你是一个初学者,你才刚刚开始,那么绝对不要。但是,如果你更认真,获得了更敏锐的理解和知识,想用深度学习走得更远,那么强烈推荐。

看看我的其他一些文章,你可能会喜欢读!

[## 机器学习和数据科学项目的 10 步终极指南!

详细讨论构建您的机器学习和数据科学项目的最佳方法…

towardsdatascience.com](/10-step-ultimate-guide-for-machine-learning-and-data-science-projects-ed61ae9aa301) [## 分步指南:使用 Python 进行数据科学的比例采样!

了解使用 python 进行数据科学所需的比例采样的概念和实现…

towardsdatascience.com](/step-by-step-guide-proportional-sampling-for-data-science-with-python-8b2871159ae6) [## 2020 年及以后最受欢迎的 10 种编程语言

讨论当今 10 种最流行的编程语言的范围、优缺点

towardsdatascience.com](/10-most-popular-programming-languages-for-2020-and-beyond-67c512eeea73) [## OpenCV:用代码掌握计算机视觉基础的完全初学者指南!

包含代码的教程,用于掌握计算机视觉的所有重要概念,以及如何使用 OpenCV 实现它们

towardsdatascience.com](/opencv-complete-beginners-guide-to-master-the-basics-of-computer-vision-with-code-4a1cd0c687f9)

谢谢你们坚持到最后。我希望你们都喜欢这篇文章。祝大家有美好的一天!

你真的需要垃圾桶吗?

原文:https://towardsdatascience.com/do-you-really-need-trash-cans-6837921d127c?source=collection_archive---------28-----------------------

用机器学习预测下一次投球

2019-2020 MLB 休赛期被休斯顿太空人队在 2017 年世界职业棒球大赛获胜赛季期间窃取对方投手标志的消息所主导。这是通过在球员休息区外观看来自中外场的现场摄像,并通过敲打垃圾桶向击球手传达下一次投球来实现的。这让我想到,“机器学习能预测接下来会是什么样的投球吗?你甚至需要偷窃标志,或者只是一台电脑?”

莱斯莉·华雷斯在 Unsplash 上的照片

太空人计划

到目前为止,Astros 计划已经被很好地覆盖了。我不会深究他们作弊的细节,但有两件具体的事情与用机器学习预测下一次投球的目标有关。首先,他们似乎只有在下一个球不是快速球的时候才会去砸垃圾桶。这意味着他们没有指定具体的投球类型,而只是在投球速度变慢时进行交流。第二个是来自棒球计划书的 Rob Arthur 确定太空人在 93%的时间里正确地判定了一个非快速球向本垒板飞来。

“总的来说,宇航员们倾向于获得正确的信号,但这并不完美。当他们重击易拉罐时,他们是最准确的:当他们这样做时,一个非快速球在途中的概率为 93%,而他们错误的概率为 7%。…根据亚当斯的数据,太空人经常使用垃圾桶,而且相对准确,敲打时比安静时更准确。"

(来源:https://blogs . fangraphs . com/the-most-important-bangs-of-the-astros-scheme/)

因此,为了让我们的机器学习模型能够与 Astros 的方案相媲美,它必须预测快速球和非快速球之间的投球,并且以相当高的准确度进行预测。

数据

将分析和机器学习应用于棒球的伟大之处在于,有大量的数据可以免费获得并且容易访问。由于我使用的是 Python,所以我选择了使用 pybaseball Python 包,它为 Statcast 数据提供了一个包装器,其中包含了在 MLB 投掷的每一个球的条目,包括游戏状态,比如第几局,谁在垒上,以及当前的计数。还包括投手用什么手投球和击球手的姿势。至关重要的是,Statcast 还提供了投掷的类型及其速度。在此基础上,我创建了一个前一个音高和前一个音高速度列。

一旦数据从 Statcast 中提取出来并稍加处理,我就把它分成一个训练集和一个测试集。在训练过程中出现的一个问题是,棒球的主要投球是快速球,因此投手投快速球的情况比投非快速球的情况多得多。这种不*衡意味着机器学习算法通过预测下一个投球总是会是快速球而获得了非常好的准确性。显然这不是很有帮助,所以为了解决这个问题,我使用了 SMOTE 来创建合成的非快速球训练数据,给我们留下了所有不同类型球场之间的*衡训练数据集。

在这次分析中,我们将使用两个不同的数据集,一个由何塞·贝里奥斯从 2017 赛季开始到 2019 赛季结束的投球组成,另一个由 2019 年 4 月 1 日至 2019 年 4 月 7 日期间 MLB 队每场比赛的所有投球组成。这两个数据集将让我们看到,与全联盟在特定情况下决定投什么球的偏好相比,个人投手的习惯是否更容易预测。

对于这两个不同的数据集,我还创建了每个数据集的一个版本,该版本只包含投球是快速球还是非快速球。对于这个版本的数据,我认为四缝线快速球、两缝线快速球和切球是“快速球”,其他的都是非快速球。我有根据地猜测,这也是太空人认为的快速球。

模特们

我从一些“基本”的机器学习模型开始,如决策树、支持向量机和 k *邻。这些模型在所有数据集上的准确率都很低(低于 50%)。然后,我决定将数据输入两个不同的神经网络:一个用于数据集的一个版本。

何塞·贝里奥斯模型

这些模型比我们的其他方法实现了更好的准确性,多间距分类器在测试集上实现了 74%的准确性,快速球/非快速球分类器实现了 58%的准确性。我不清楚为什么这两个分类器之间会有这样的差异,但是让我们深入研究它们产生的混淆矩阵。

何塞·贝里奥斯全音高预测器的混淆矩阵

查看上面的混淆矩阵,我们可以通过查看矩阵的对角线来了解给定类型的音高有多少与预测类型相匹配。例如,该模型正确预测了 52%的弧线球。查看矩阵中的行可以告诉你有多少百分比的真实音高被错误地归类为不同类型的音高。观察曲线球行(标记为“CU”),我们可以看到 52%的模型成功预测,而 20%的时间预测变速球将是下一个投球。第二个被预测最多的是双线快速球,有 18%的几率,接下来是四线快速球,有 10%的几率。如果你把这变成敲打垃圾桶,大约 30%的时间你会是错误的。虽然这个模型的真实精度相当好,但将其预测转化为可操作的结果将是困难的,仍然远远落后于 Astros 的精度。

何塞·贝里奥斯的快速球/非快速球预测者的混淆矩阵

以上是快速球/非快速球分类器的混淆矩阵。如你所见,我们的真实阳性率和真实阴性率非常相似,这使我们的准确率达到了 58%。与多音调分类器不同,结果相对*衡。这是一件好事,因为我们希望减少误报和漏报的数量,但这两个百分比都会给我们的垃圾桶攻击者带来更糟糕的结果:只有大约 60%的时间他们是正确的。也许我们全联盟的数据会更好?

联盟范围内的模型

在测试集上,联盟范围内所有投球的分类器准确率为 88%,但像以前一样,让我们看看下面的混淆矩阵:

全联盟全音高预测值的混淆矩阵(音高缩写参考:https://www.daktronics.com/support/kb/Pages/DD3312647.aspx

正如你所看到的,与特定于投手的模型相比,在提高垃圾桶爆炸的准确性方面没有太大的改进。该模型正确地预测了四缝线快速球被投出的概率是 43%,而它预测曲球或滑球被投出的概率是 20%。包括一个两缝线快速球的预测让我们正确地预测球会是四缝线快速球或是两缝线快速球的概率只有 51%。显然还不够准确,击球手无法从模型中获得任何好处。也许快速球/非快速球分类器这次会产生更好的结果?

全联盟快速球/非快速球预测者的混淆矩阵

所以,显然这也不是一个好结果。测试集的准确率为 57%,正如混淆矩阵所示,假阳性的数量非常高。这意味着我们的垃圾桶在 54%的时间里会砰击一个快速球,而它只应该砰击一个非快速球。分类器在预测非快球何时到来方面做得稍好,但仍有 32%的假阴性率。这意味着垃圾桶在 32%的非快速球被投出的时候不会被撞。这个模型对击球手毫无帮助。

结论

在这个项目中,我认为机器学习可能能够以足够高的精度预测下一次投球,这对击球手可能是有益的。显然不是这样的。即使某些模型产生了大于 75%的准确度,假阳性和假阴性率也足够大,以至于没有明显的益处。不同的神经网络架构和围绕每个音高的更多数据可能会产生更好的准确性,但我现在怀疑它是否会有那么大的帮助。然而,就目前而言,知道下一次推销会是什么的最好方法是作弊。

查看这里的代码:https://github . com/Parker Erickson/baseballDataScience/blob/master/next pitch prediction . ipynb

你是否纠结于量子叠加?

原文:https://towardsdatascience.com/do-you-struggle-with-the-quantum-superposition-86d0f2147bfb?source=collection_archive---------35-----------------------

实践量子计算——直观解释

本帖是本书的一部分: 用 Python 动手做量子机器学习

传统位可以是01。相比之下,量子位(称为量子位)可以处于叠加状态。量子叠加是01的线性组合。但是量子位只要你不测量,就只能处于叠加态。一旦你测量了你的量子位,它会立刻坍缩成01。就像古典音乐一样。

在这篇文章中,我们仔细观察了量子叠加,以及它的状态如何决定我们是将量子位测量为0还是1

一个量子位有两种可能的测量方式:01。因此,量子位是一个二维量子系统。每个维度都由一个标准基向量表示。在量子计算中,我们使用狄拉克符号。它表示 ket 旁边的列向量,看起来像“|ψ⟩":”

量子位的状态由两个维度的叠加来表示。这就是量子位状态向量|ψ⟩(“psi”)。

α和β是|0⟩和|1⟩.状态的概率振幅它们的*方分别表示测量量子位的概率为0(由α^2 给出)或1 (β^2)。

|ψ⟩必须通过以下方式标准化:

让我们看看下图中量子位态|ψ⟩的图形表示。

作者弗兰克·齐克特的图片

在此表示中,两个维度都位于垂直轴上,但方向相反。系统的顶部和底部分别对应于标准基矢量|0⟩和|1⟩。

当有两个维度时,通常的做法是把两个维度相互正交。虽然使用一个轴来表示两个维度对于二维系统来说是相当不寻常的表示,但是它非常适合于量子系统。

看看上图中的任意量子比特状态向量|ψ⟩。由于量子位状态向量是归一化的,|ψ⟩起源于中心,大小(长度)为 1/2。圆的直径是 1。由于这个相等的量级,所有的状态向量都在尖圆处结束。|ψ⟩.也是

状态向量|0⟩和|ψ⟩之间的角度称为θ(“theta”),控制向量头到系统顶部和底部的接*度(虚线)。

这些*似表示概率。

  • α^2 是衡量|ψ⟩的概率为0
  • 以及测量它的β^2 为1

接*度α和β位于它们所描述的状态概率
(|ψ⟩)的相反两侧。α是到|1⟩的接*度(或距离),因为随着到|1⟩的距离增加,测量0的概率增加。

因此,通过控制接*度,角度θ也控制了测量处于状态01的量子位的概率。

我们可以指定角度θ,并使用所需的归一化来导出α和β,而不是指定α和β之间的关系,然后对它们的值进行归一化处理。

我们可以推导出α和β的值,从而推导出状态|ψ⟩:

在 Python 中,双字段数组[cos(theta/2), sin(theta/2)]表示这种状态。

你想推导出这个公式吗?这里有一个小提示:泰勒斯和毕达哥拉斯定理在这里帮助你。

还有一个问题。对于θ∈R,如果π

下图显示了这种情况。

作者图片

数学上,我们没有问题。因为我们*方α和β,所以它们的符号(+或)与所得概率无关。

但这意味着什么呢?如图所示,α^2 或β^2 怎么会是负数?答案是 I,I 是一个*方为负的复数:i^2=−1.

而如果α和β是复数(α,β∈C),它们的*方可以是负数。

这必然会带来很多后果。这引发了很多问题。现在,我们将垂直轴左侧的所有向量解释为β^2 (β^2<0).)的负值

虽然这样一个值让我们能够区分垂直轴两侧的量子位状态向量,但它对于所得的概率并不重要。

例如,国家

产生相同的测量概率01(各 50%)。它位于水*轴。也是如此

尽管这些状态的概率相同,但它们是不同的。并且角度θ在它们之间是不同的。

θ=π/2 指定|ψ⟩=|0⟩+|1⟩/√2,也称为|+⟩.

θ=3/2 π或θ=,π/2 表示|ψ⟩=|0⟩−|1⟩√2,也称为|−⟩.

上面提到的α^2 或β^2 为负的结果之一是,我们的归一化规则需要一些调整。

我们需要将归一化方程改为:

这个帖子包含了很多公式。重要的一点是,我们可以指定量子态,这些量子态产生以角度θ测量01的特定概率。它描绘了一幅清晰的画面,有助于理解和记忆。

让我们来看看角度θ在 Python 代码中是如何工作的。

作者弗兰克·齐克特的图片

在这段代码中,我们引入了函数getState(第 5 行)。它将theta作为参数,并返回数组[cos(theta/2), sin(theta/2)]。这是我们在上面的等式中指定的向量。这导致有 50%的几率测量出量子位分别是01

结论

量子位及其叠加态很难解释。虽然数学为量子位是什么以及它的行为方式提供了一个清晰的定义,但对我们大多数人来说,光靠公式是不够直观的。在这篇文章中,我们提出了量子位状态的视觉解释,以及它如何决定测量量子位在状态01的概率。

把一个概念的图片放在眼前不仅有助于理解它,还能促进对它的记忆。

本帖是本书的一部分: 用 Python 动手做量子机器学习

在这里免费获得前三章。

你信任机器为你做决定吗?

原文:https://towardsdatascience.com/do-you-trust-machines-to-make-your-decisions-3dcab11c392c?source=collection_archive---------34-----------------------

卢克·切瑟在 Unsplash 上的照片

约翰有了一个主意。他经常有相当好的想法,但这是一个非常好的想法,他对自己非常满意。他发现,由于大多数同事使用的考勤卡系统出现异常,他的公司每个月都浪费了数千个工时。这些过程已经很多年没人看了,也没人记得为什么会有现在的协议,或者它有什么用,但是每个人都同意这是巨大的时间浪费。他决定开发一个简单的系统,在保留其核心功能的同时,将大部分程序自动化。

这是一个非常非常好的主意,正如我所说,他对自己非常满意。他在一个周一自豪地向管理层提交了他的提案,而在接下来的周五,他被召集参加一个会议,他认为这将是一个关于他的计划实施的讨论。相反,他面对的是一个冷漠无情的主管,他直截了当地告诉他这个提议不合适,然后一言不发地离开了房间。

约翰的会面并没有像这样进行(照片由奥斯汀·迪斯特尔Unsplash 上拍摄)

约翰相当恼火。他不明白为什么他的提议被拒绝,而且对主任没有花时间解释原因感到特别恼火。我们大多数人可能想知道为什么我们的推销没有成功,或者我们的应用程序有什么问题。被蒙在鼓里令人沮丧,会破坏我们对决策过程的信任。这对于算法来说更是如此——因为我们倾向于将技术拟人化当一个人工智能似乎将我们排除在外时,人们会变得非常不安。这就是为什么人工智能中的可解释性如此重要的原因之一,因为它进一步嵌入了我们的日常交易,信任变得至关重要。

图片由穆罕默德·哈桑来自 Pixabay

在任何一天,你或我都可能收集到成千上万个关于我们的数据点。这可能包括网络浏览行为、身体活动或消费模式。在用户的默许下,我们的个人数据被公开编辑和记录,并出售给相关方。对于谁可以购买用于预测我们未来行为和评估我们服务适用性的材料没有限制。

主要的科技公司继续成长,它们对日常生活的影响正在扩大。对于生活在发达国家的人来说,每天都接触不到谷歌、苹果、脸书、亚马逊或微软是极其困难的。软件几乎影响到人类活动的每个方面,因此收集点的范围很广。

企业或组织拥有的关于一个人的数据点越多,他们就能做出越多的决定。例如,银行会使用信用报告来评估申请人是否适合贷款。有完善的法规来管理信用报告中的可用信息、保留时间以及谁可以访问这些信息。但是直到最*,还很少有立法规定如何处理个人的个人数据。GDPR 和加利福尼亚州的 CCPA 隐私法于 2020 年 1 月生效,已经开始制定规则,规定如何以适当的方式对待这种已经变得异常珍贵的商品。

马库斯·斯皮斯克·temporausch.com 摄于派克斯

我曾在其他地方写过关于组织一旦获得这些数据后如何使用的问题。《GDPR 法案》第 22 条规定,任何个人都不能受制于完全自动化的决策过程,该过程不会以任何有意义的方式影响他们。这意味着,例如,乘客分数低的优步乘客不能被自动排除在进一步的乘坐之外。必须有一个人在循环中,以确保优步软件中的算法运行正常,乘客的分数不会因故障、错误或偏见而受到影响。

许多人担心的是这些组织对我们的信任程度。人们担心,当个人试图租车或办理电话合同时,他们可能会受到无法解释的算法的莫名其妙的影响。查理·布洛克的科技讽刺作品黑镜在“急转弯”这一集中很好地说明了这一点,在这一集中,一个角色在一系列不幸的互动后,她的算法计算社交得分大幅下降。因此,她无法在取消的航班上重新预订座位参加婚礼,在经历了几次巨大的压力后,她最终被迫接受一名卡车司机的搭车,在那里她得知司机的丈夫因社会分数低而被拒绝接受救命的医疗服务。

随着私营公司提供的服务进一步融入我们的日常生活,人工智能决策中必须有合法的人类监督。另一种选择可能会把我们引向一个怪诞的卡夫卡式的“计算机说不”的现实,在这个现实中,没有人可以挑战任何决定,没有人可以解释系统是如何工作的,也没有人承担责任。

欧盟立法者的立场是,问责制是消费者信任自动化决策的先决条件。不可否认的是,这个行为的后果是相关的——当谷歌地图选择了一条路线而不是另一条路线让你在晚上回家时,不需要解释。传统人工智能非常适合简单或琐碎的任务宋立科在 Spotify 或语音助手软件上的推荐。

无人驾驶汽车做出的决定将需要在发生碰撞时得到解释

然而,配备面部识别技术的警方人工智能系统可能会导致错误逮捕(或更糟)。像无人机这样的现代军事系统使用人工智能过程在战场上做出瞬间决定。医疗保健甚至股票交易应用中的诊断人工智能工具,当它们以意想不到的方式运行时,都有可能造成真正的损害。如果人工智能做出的决定不透明或不可解释,那么使用这些决定就很难被证明是正当的。我们如何确定我们可以信任这些系统?我们能确定它们是在没有有偏见的训练数据的情况下开发的,或者它们没有被恶意操纵吗?如果一个封闭的 AI 系统犯了误判、股灾或战争罪,谁能被追究责任?

诸如此类的考虑促使 IBM 和谷歌等大公司开始认真对待可解释的人工智能,尽管该技术的高级应用仍处于起步阶段。任何 XAI 应用中的两个关键因素是可检查性 & 可追溯性:事后调查者必须能够精确地检查在算法中的什么地方做出了决策,以及为什么。

图片由 Gerd AltmannPixabay 拍摄

DARPA(开发供美国军方使用的新兴技术的机构)已经确定,XAI 算法应该产生两种输出:决策和得出决策的模型。分解到基本级别,一个完整的算法由训练数据(输入层)、深度学习过程(隐藏层)和最终产生解决方案的解释界面以及到达那里的步骤(输出层)组成。这将意味着许多现代先进的人工智能技术,就其本质而言,永远无法解释。复杂人工神经网络的“黑匣子”永远无法产生一个如何做出决策的模型。相反,开发人员一直在研究其他可能有助于解释的技术。其中包括:

LRP——逐层相关性传播——可以解释一些机器学习系统如何得出结论的更简单的技术之一。LRP 通过神经网络逆向工作,查看哪些输入与输出最相关。

LIME——本地可解释的模型不可知解释——是一个临时模型,它稍微改变(或干扰)输入,以查看输出如何变化,从而提供关于决策如何做出的见解。

保留 —反向时间注意力模型可用于医疗诊断,并利用注意力机制观察两个可能的神经网络中哪一个对决策影响最大。

最*来自 Venture Radar 的这篇文章更详细地总结了在 XAI 技术领域处于领先地位的公司,包括【DarwinAI】,****使用了一种被称为“生成合成”的过程,以使开发人员能够理解他们的模型; Flowcast 使用机器学习技术为贷方创建预测性信用风险模型,以及Factmata旨在打击网上假新闻。****

所有观点均为我个人观点,不与甲骨文共享。 请随时在 LinkedIn 上联系我

要不要用强化学习训练一辆简化的自动驾驶汽车?

原文:https://towardsdatascience.com/do-you-want-to-train-a-simplified-self-driving-car-with-reinforcement-learning-be1263622e9e?source=collection_archive---------18-----------------------

试试我们新的 LongiControl 环境

NeONBRANDUnsplash 上的照片

在这里,我与简·多门和克里斯托夫·弗里贝尔一起展示了这项研究。

动机

*年来,使用强化学习(RL) [1]来解决具有挑战性的游戏和较小的领域问题[2][3][4]的应用成功激增。RL 的这些成功在一定程度上是由于 RL 社区在公共开源环境模拟器(如 OpenAI 的 Gym [5])上的强大协作努力,这些模拟器可以加快开发速度,并在不同的先进策略之间进行有效的比较。

然而,许多现有的环境包含游戏而不是真实世界的问题。只有最*的出版物开始向面向应用的 RL 过渡[6][7]。在这篇文章中,我们的目标是在一个高度相关的问题:自动驾驶车辆的纵向控制中,将现实世界中的激励 RL 与易访问性联系起来。自动驾驶是未来,但在自动驾驶汽车独立地在随机的现实世界中找到自己的路之前,仍然有无数问题需要解决。

强化学习

在我们仔细研究 Longicontrol 环境之前,我们将在下面简要描述一下 RL 的基础知识。如果你熟悉 RL,可以直接跳到纵向控制部分。

强化学习(RL)是一种从与环境的交互中学习以实现既定目标的直接方法。在这种情况下,学习者和决策者被称为代理,而与之交互的部分被称为环境。交互以连续的形式进行,因此代理在每个时间步 t 选择动作,环境对它们做出响应,并以状态 Sₜ₊₁ 的形式向代理呈现新的情况。响应代理的反馈,环境以数字标量值的形式返回奖励 Rₜ₊₁ 。代理人寻求随着时间的推移回报最大化[1]。

图 1:强化学习互动[1]

介绍了 RL 的概念后,下面是对某些术语的简要解释。详细介绍请参考[1]。

政策。政策是代理行为的特征。更正式地说,政策是从状态到行动的映射。

目标和奖励。在强化学习中,智能体的目标以一种称为奖励的特殊信号的形式形式化,这种信号在每个时间步从环境转移到智能体。基本上,代理人的目标是最大化其获得的标量报酬的总量,导致最大化的不是眼前的报酬,而是长期的累积报酬,也称为回报。

探索与剥削。强化学习的一个主要挑战是探索和利用的*衡。为了获得高回报,代理人必须选择在过去被证明特别有回报的行动。为了首先发现这种行为,必须测试新的行为。这意味着代理人必须利用已经学到的知识来获得奖励,同时探索其他行动以在未来拥有更好的策略[1]。

问学。很多流行的强化学习算法都是基于 Q 值的直接学习。其中最简单的是 Q 学习。更新规则如下:

当在状态 s 中选择一个动作 a 并遵循该动作的策略时,Q 对应于预期的未来回报。交互的回报表示为 r。Q 函数的自适应由学习速率和折扣因子控制。该策略隐含在 Q 值中:

深度确定性政策梯度(DDPG)。寻找最佳行动需要对 Q 函数进行有效评估。虽然这对于离散的和小的动作空间是简单的(计算所有的动作,并选择具有最高值的动作),但是如果动作空间是连续的,问题就变得无法解决。然而,在许多应用中,如机器人和能源管理,离散化是不可取的,因为它们对解决方案的质量有负面影响,同时在精细离散化的情况下需要大量的存储器和计算能力。Lillicrap 等人[8]提出了一种称为 DDPG 的算法,它能够通过深度强化学习来解决连续问题。与 Q-Learning 相反,使用了演员-评论家架构。详细的描述可以在[8]中找到。

纵向控制

在纵向控制领域中,目标是车辆在给定时间内尽可能节能地完成单车道路线,而不造成事故。总之,这对应于在从 t₀T 的间隔中使用的总能量 E 的最小化,作为功率 p 的函数:

根据外部要求,如其他道路使用者或速度限制,必须同时满足以下边界条件:

其中 v 为速度, a 为加速度,a_dot 为急动度,()ₗᵢₘ,ₘᵢₙ和()ₗᵢₘ,ₘₐₓ分别代表下限和上限。

规划方法

在这一点上,可能会出现这样的问题通常是如何解决的。一种可能性是规划方法。对于这些,假设路线是完全已知的,没有其他道路使用者,并且也知道驾驶员将如何使用辅助消耗装置。下图显示了一个示例性的解决方案。动态规划计算已知路线的两个速度限制之间的最有效速度轨迹。

图 2:使用动态规划的给定路线的示例性解决方案[9]

如果路线不确定,尤其是在你前方有其他道路使用者的情况下,你可能想知道该采取哪种方法。一方面,速度限制大多是已知的,另一方面,其他道路使用者的行为是非常随机的。这通常是不可预见的。因此,不同的方法是必要的。由于强化学习能够解决随机问题,这是一个有前途的方法来解决这个问题。由于在真实交通中直接训练自动驾驶汽车太危险和低效,模拟提供了一种解决方案。可以安全地开发和测试这些算法。因此,我们将处于我们的新 RL 环境中,这将在下面介绍。

远程控制环境

正如我们之前看到的,RL 设置由两部分组成:代理和环境。我们将仔细观察环境。它独立于代理。这意味着您可以为代理测试任何算法。

图 3:long control 可视化

环境由两部分组成。车辆和驾驶环境。首先,重点应该放在车辆上。

车辆的运动被简化为匀加速模型。模拟基于 t = 0.1 s 的时间离散化。当前速度 vₜ 和位置 xₜ 计算如下:

车辆的加速度由当前车辆状态和代理选择的发动机功率产生,因此是环境的作用。由于只考虑纵向控制,所以轨道可以模拟为单车道。因此,在这一点上,一维速度 vₜ 和位置 xₜ 就足够了。

为了确定车辆的能耗,我们从真实的电动车辆中创建了一个黑盒模型。当前速度和加速度是输入变量,能量消耗是输出变量。了解了车辆模型之后,接下来的话题就是车辆行驶的景观。

图 3 示出了模拟中的轨迹实现的例子。驾驶环境以这样的方式建模,即距离是任意长的,并且任意定位的速度限制指定了任意的允许速度。这可以被认为等同于随机模拟的交通。最多提前 150 米,车辆驾驶员接收关于即将到来的速度限制的信息,从而基本上可以进行前瞻性驾驶。结果是一个持续控制问题的环境。下面列出了国家的各个组成部分。

状态 s

国家由五部分组成:

  • 速度
  • 先前加速度
  • 当前速度限制
  • 未来速度限制
  • 未来限速距离

现在的速度和限速很直观。保持最后一次加速的状态,可能不是每个人都能马上看出来的。这是计算加加速度所需要的。描述车辆加速*稳程度的大小。

行动 a

代理在值范围[-1,1]内选择一个操作。因此,代理可以在取决于状态的车辆最大和最小加速度之间进行选择。这种类型的建模导致代理只能选择有效的动作。

奖励 r

奖励函数定义了代理人对每个行为的反馈,并且是控制代理人行为的唯一方法。它是 RL 环境中最重要和最具挑战性的组件之一。在这里介绍的环境中,这尤其具有挑战性,因为它不能简单地用一个标量来表示。如果只奖励(惩罚)能源消耗,车辆将简单地静止不动。代理将了解到,从能量消耗的角度来看,简单地不驾驶是最有效的。虽然这是事实,我们都应该更经常地使用我们的自行车,但我们仍然希望代理在我们的环境中驾驶。所以我们需要一个奖励,让驾驶对代理人更有吸引力。通过比较不同的方法,当前速度和当前速度限制之间的差异被证明是特别合适的。通过最小化这种差异,代理会自动启动自己。为了仍然将能量消耗考虑在内,奖励成分与能量消耗一起维持。第三个奖励因素是由颠簸引起的。这是因为我们的自动驾驶汽车也应该能够舒适地行驶。最后,为了惩罚违反速度限制的行为,增加了第四个奖励部分。

由于 RL 是为标量奖励设计的,所以有必要对这四个部分进行加权。合适的加权并不是微不足道的,而是一个巨大的挑战。为了让您更容易开始,我们已经预先配置了适当的权重。在本文的下一部分,我们将向您展示不同权重的效果的一些例子。但是,欢迎您自己探索更好的权重。

为了能够评估不同权重的效果,有效的 RL 学习过程是必要的。这是接下来要考虑的。

示例性学习过程

图 4:学习过程的开始

在第一个示例中,我们看到了代理在培训开始时的动作。是的,你没看错,代理不动。所以我们让他训练一下:

图 5:经过一些学习过程后

开了一段时间后,他开始开车,但无视限速。这是不可取的。因此,我们让他训练更长时间:

图 6:在较长的训练过程之后

通过让代理训练更长时间,他也开始尊重速度限制。曲线还不完美。如果你喜欢它,只要在一个更长的学习过程后尝试一下它会是什么样子。

可以总结一下。代理学习舒适驾驶,甚至遵守速度限制。值得注意的是,它能够在未来正确地使用速度限制。这不是明确的编程,但他自己学会了。令人印象深刻。

多目标优化

如前所述,这个问题有几个相互依赖的目标。因此也可以进行多目标调查。为了更好地理解,我们举了三个例子。

赏例 1。如果只应用了移动奖励(与允许速度的偏差):代理违反了速度限制。

图 7:奖励权重[1,0,0,0]

奖励例 2。在第二个例子中,增加了对超速的处罚。这导致代理实际上保持限制。

图 8:奖励权重[1,0,0,1]

奖励例 3。在第三个例子中,我们添加了能量和挺举奖励。这导致代理驱动更节能,也选择更*稳的加速。

图 9:奖励权重[1,0.5,1,1]

这只是理解的一个例子。因此,该环境为研究多目标算法提供了良好的基础。

摘要

在本文的最后,我们将总结最重要的几点。

通过所提出的适用于 OpenAI Gym 标准化的 RL 环境,我们展示了原型化和实现最先进的 RL 算法是容易的。此外,LongiControl 环境适用于各种检查。除了 RL 算法的比较和安全算法的评估,在多目标强化学习领域的研究也是可能的。其他可能的研究目标是与已知路线的规划算法进行比较,调查模型不确定性的影响,以及考虑非常长期的目标,如在特定时间到达。

LongiControl 旨在使社区能够利用强化学习的最新策略来解决自动驾驶领域的现实世界和高影响问题。

这里有 GitHub 链接报纸和我的 LinkedIn 简介

享受使用它😉

参考

[1] R .萨顿和 a .巴尔托,强化学习简介 (1988),麻省理工学院出版社

[2] V. Mnih 和 K. Kavukcuoglu 和 D. Silver 和 A. Graves 和 I. Antonoglou 和 D. Wierstra 和 M. A. Riedmiller,用深度强化学习玩雅达利 (2013),CoRR

[3] D. Silver 和 J. Schrittwieser 和 K. Simonyan K 和 I. Antonoglou 和 A. Huang 和 A. Guez 和 T. Hubert 和 L. Baker 和 M. Lai 和 A. Bolton 等人掌握没有人类知识的围棋游戏 (2017),《自然

[4] R. Liessner 和 C. Schroer 以及 A. Dietermann 和 b . bker,混合动力电动汽车高级能源管理的深度强化学习 (2018),ICAART

[5] G .布罗克曼和 v .张和 l .彼得森和 j .施耐德和 j .舒尔曼和 j .唐和 w .扎伦巴,开放健身房。CoRR,2016。

[6] M. Andrychowicz,B. Baker,M. Chociej,R. Jozefowicz 等人学习灵巧手操作。CoRR,2018。

[7] F. Richter,R. K. Orosco,M. C. Yip,外科机器人的开源强化学习环境,CoRR,2019。

[8] T. P. Lillicrap 等人,深度强化学习连续控制 (2015),CoRR

[9] S. Uebel, 高效纵向混合动力汽车的能源管理策略(2018),TU Dresden

Docker 101:你想知道的关于 Docker 的一切

原文:https://towardsdatascience.com/docker-101-all-you-wanted-to-know-about-docker-2dd0cb476f03?source=collection_archive---------23-----------------------

Docker 入门

绝对初学者的 Docker

拍摄的照片谁是德尼罗? on Unsplash

你有没有被 Docker 的花哨名字吓倒过,想知道它是什么?—太好了,这篇文章是写给你的。

在这篇文章中,我们将会介绍这个魔鬼到底是什么以及它做了什么。

首先,Docker 是什么?🧐

Docker 是一个开源的容器化工具,主要用于跨不同*台快速运输和运行应用程序。Docker 快速运输和部署代码的方式大大减少了编写代码和在生产中运行代码之间的延迟。它是使用 GO 开发的,于 2013 年首次发布。

为什么是 Docker?

Docker 有一系列的优点使它变得非常有用。其中一些是:

  1. 隔离

它帮助我们创建一个与环境无关的系统。您的应用程序可以在不同的*台上顺利运行。这基本上是使用容器实现的。

便携性

因为所有的依赖项都在同一个容器中,所以很容易从一个地方转移到另一个地方,这赋予了 Docker 可移植性。

3。轻量级

作为系统上的另一个应用程序运行,而不是消耗系统的全部资源。

4。鲁棒性

与虚拟机相比,对硬件的要求较低,需要的内存也很少,因此提供了高效的隔离级别,不仅有助于节省成本,还有助于节省时间。

在我们深入研究之前,我们为什么需要 Docker?我们没有足够的工具吗?🤨

是的,我们有。很多,但是 Docker 不一样。这让我们的生活更轻松。我会告诉你怎么做——继续读下去。

请允许我给你一些背景资料!

背景

从前,我们习惯于在操作系统上安装软件,而操作系统安装在一组特定的硬件上——CPU、内存和磁盘。让我们快进一点,虚拟化时代已经到来。在同一个操作系统中运行多个操作系统,允许一定程度的硬件隔离。比如——用 VirtualBox 在 Windows 上运行 Ubuntu。

容器 vs 虚拟机(图片来源:Docker.com[1])

你会发现这很酷,但是在敏捷时代,时间就是金钱,你需要持续地交付,并在每个冲刺阶段结束时提交可交付成果,追赶 IT 部门(如运营)以获得不同故事的不同开发环境(例如,需要更多内存/磁盘的资源密集型流程)可能会令人望而生畏,而且非常耗时。

别担心,码头工人来救你了。它有适合你的东西,一个名为 docker 的产品,它不仅提供了轻量级的虚拟化,还提供了基于开源 Linux 的软件,可以在任何支持 docker 实例的硬件上运行,如 Windows 或 OSX。Docker 通过使用容器实现了这种程度的虚拟化。这是一个比喻,因为它的工作方式和普通容器一样。它确实在里面储存东西。

容器是一个标准的软件单元,它将代码及其所有依赖项捆绑在一起,因此应用程序可以*稳快速地运行,而不受计算环境的影响。老实说,容器只不过是一个正在运行的进程,应用了一些额外的封装特性来保持它与主机和其他容器的隔离。[1]

你说轻巧?

Docker 容器作为可执行文件运行,与占用大量系统资源的虚拟化不同,容器就像另一个可执行的应用程序,它提供类似级别的虚拟化,但以资源高效和更安全的方式提供。由于 Docker 容器共享相同的系统资源,这使得它们很有效率。例如,在一个需要运行虚拟机的系统中,用户可以拥有不同的 Docker 容器,并拥有虚拟机中通常拥有的某种隔离级别。

容器隔离的一个最重要的方面是每个容器与其私有文件系统进行交互;这个文件系统是由 Docker 映像提供的。这实质上意味着需要更少的资源,从而降低成本。

酷,什么是形象?

不是你想的那样。它更像一台复印机。你可以用图像制作容器,就像你可以用复印机复印一样。它只不过是一个模板,包含一个应用程序,以及所有的依赖,需要运行你的应用程序,如你的代码,库,配置文件,环境变量(ex- PATH)等。该映像可以部署到不同的环境中。想知道图像和容器有什么不同吗?容器是一个图像的运行实例。

现在我们对 Docker 有了一些了解,让我们来看看它的架构。

Docker CLI(客户端)| Docker 守护进程(服务器)| Docker Hub(注册表)(图片来源:Docker.com[1])

客户端-服务器架构

Docker 命令行使用 Docker REST API 与 Docker 守护进程进行交互。Docker 客户端是命令行工具,这是用户与 Docker 交互的方式。Docker 守护进程监听 Docker 客户端 API 请求的端口,并管理图像和容器等 Docker 对象。客户端和服务器可以在同一台机器上。注册表是存储 docker 图像的地方。这是一个公共注册表,默认情况下,图像存储在 Docker hub 上。您可以使用自己选择的注册表来存储图像。

客户端-服务器架构(图片来源:Docker.com[1])

码头枢纽

这是一个官方的在线存储库,所有 docker 图片都存储在这里,它还允许这些图片被分发。如上所述,Docker 使用基于 Linux 的 CLI 工具与 Docker 守护进程进行交互。您可以使用这个 CLI 创建您的映像并将其发布到 Docker Hub。有两种方法可以实现这一点

1.在本地创建一个映像,并将其推送到 Docker Hub。

2.创建一个 docker 文件,并使用 Docker 连续构建系统来构建映像。(首选)

在将图像推送到 Docker hub 之前,你需要一个账户(基本版是免费的,点击这里获取你的)和 Docker hub 桌面应用。这样做的先决条件是你应该在你的系统上安装 Docker(获取 Docker CE(社区版))。通过身份验证后,您可以开始将您的图像推送到 docker hub。

谁需要 Docker?

如果您需要快速一致地交付您的应用程序,您可能需要使用 Docker。主要是软件工程师、开发人员、数据工程师和数据科学家可以从 Docker 中受益。Docker 简化了软件开发生命周期,允许开发人员在标准化的环境中工作,这对于持续集成和持续交付(CI/CD)工作流来说很有吸引力。

结论

在这篇文章中,我们快速浏览了作为容器化工具的 Docker、客户机-服务器架构及其功能。在接下来的文章中,我们将探索 Docker 命令,构建您的映像,运行容器,以及处理故障。

敬请关注😊

很高兴听到你对此的想法!

如果你觉得这很有用,并且知道任何你认为会从中受益的人,请随时发送给他们。

参考资料:

[1]https://docs.docker.com/get-started

数据科学家的 Docker 最佳实践

原文:https://towardsdatascience.com/docker-best-practices-for-data-scientists-2ed7f6876dff?source=collection_archive---------12-----------------------

码头工人…鲸鱼…你懂的。

作为一名数据科学家,我每天都与 Docker 打交道。对我来说,创建图像、旋转容器已经变得和编写 Python 脚本一样普通。这个旅程有它的成就也有它的时刻,“我希望我以前就知道”。

本文讨论了在数据科学项目中使用 Docker 时的一些最佳实践。这绝不是一份详尽的清单。但这涵盖了我作为数据科学家遇到的大多数事情。

本文假设读者对 Docker 有基本到中等程度的了解。例如,你应该知道 Docker 是用来做什么的,应该能够轻松地编写 Docker 文件,并理解 Docker 命令,如RUNCMD等。如果没有,通读这篇来自 Docker 官方网站的文章。你也可以浏览那里收集的文章。

为什么是 Docker?

自从《Docker》发行以来,它风靡了全世界。在 Docker 时代之前,虚拟机曾经填补了这一空白。但是 Docker 提供的不仅仅是虚拟机。

docker 的优势

  • 隔离—隔离的环境,无论底层操作系统/基础架构、安装的软件、更新
  • 轻量级—共享操作系统内核,避免每个容器都有操作系统内核
  • 性能——轻量级允许许多容器在同一个操作系统上同时运行

码头工人入门

Docker 有三个重要的概念。

这是一组可运行的库和二进制文件,代表了一个开发/生产/测试环境。您可以通过以下方式下载/创建映像。

  • 从图像注册表中提取:例如docker pull alpine。这里发生的是,Docker 将在本地计算机中查找名为alpine的图像,如果没有找到,它将在 Dockerhub 中查找
  • 使用 Dockerfile 文件在本地构建映像:例如docker build . -t <image_name>:<image_version>。在这里,您不是在尝试下载/拉取图像,而是在构建您自己的图像。但这并不完全正确,因为一个Dockerfile包含一个以FROM <base-image>开始的行,它寻找一个基础图像作为开始,这个基础图像可能是从 Dockerhub 中提取的。

容器——这是一个图像的运行实例。你可以使用语法``docker container run 建立一个容器,例如从alpine图像使用,docker container run -it alpine /bin/bash`命令创建一个容器。

—卷用于永久/临时存储数据(如日志、下载的数据)供容器使用。此外,卷可以在多个容器之间共享。您可以通过多种方式使用卷。

  • 创建卷:您可以使用docker volume create <volume_name>命令创建卷。请注意,如果该卷被删除,存储在此处的信息/更改将会丢失。
  • 绑定挂载一个卷:您还可以使用-v <source>:<target>语法将现有的卷从主机绑定挂载到您的容器。例如,如果您需要将/my_data卷作为/data卷安装到容器中,您可以执行docker container run -it -v /my_data:/data alpine /bin/bash命令。您在装载点所做的更改将反映在主机上。

1.创建图像

1.保持图像较小,避免缓存

构建图像时,您必须做两件常见的事情,

  • 安装 Linux 软件包
  • 安装 Python 库

当安装这些包和库时,包管理器将缓存数据,这样如果你想再次安装它们,将使用本地数据。但是这不必要地增加了图像尺寸。docker 图像应该是尽可能轻量级的。

当安装 Linux 包时,记得通过添加最后一行到您的apt-get install命令来删除任何缓存的数据。

RUN apt-get update && apt-get install tini && \
 rm -rf /var/lib/apt/lists/*

安装 Python 包时,为了避免缓存,请执行以下操作。

RUN pip3 install <library-1> <library-2> --no-cache-dir`

2.将 Python 库分离到 requirements.txt 中

您看到的最后一个命令将我们带到了下一点。最好将 Python 库分离到一个requirements.txt文件中,并使用下面的语法使用该文件安装库。

RUN pip3 install -r requirements.txt --no-cache-dir

这很好地区分了 Dockerfile 做“Docker 的事情”和不(明确地)担心“Python 的事情”。此外,如果您有多个 docker 文件(例如用于生产/开发/测试),并且它们都希望安装相同的库,您可以轻松地重用该命令。requirements.txt文件只是一堆库名。

numpy==1.18.0
scikit-learn==0.20.2
pandas==0.25.0

3.修复库版本

注意在requirements.txt中我是如何冻结我想要安装的版本的。这一点非常重要。因为否则,每次构建 Docker 映像时,您可能会安装不同东西的不同版本。属地地狱是真实的。

运行容器

1.拥抱非根用户

当您运行容器时,如果您没有指定一个用户来运行,它将假定为root用户。我不想撒谎。我天真的自己曾经喜欢使用sudo 或者root来按照我的方式做事(尤其是绕过许可)。但如果我学到了一件事,那就是拥有不必要的特权是一种恶化的催化剂,会导致更多的问题。

要以非根用户的身份运行容器,只需

  • docker run -it -u <user-id>:<group-id> <image-name> <command>

或者,如果你想跳到一个已存在的容器中去,

  • docker exec -it -u <user-id>:<group-id> <container-id> <command>

例如,您可以通过将<user-id> 指定为$(id -u)并将<group-id>指定为$(id -g)来匹配主机的用户 id 和组 id。

注意不同的操作系统如何分配用户 id 和组 id。例如,您在 MacOS 上的用户 ID /组 ID 可能是 Ubuntu 容器中预先分配/保留的用户 ID/组 ID。

2.创建非特权用户

我们可以以非 root 用户的身份登录我们的主机——远离主机——这太棒了。但是如果你像这样登录,你就是一个没有用户名的用户。因为,显然容器不知道用户 id 来自哪里。每次你想把一个容器或exec变成一个容器时,你需要记住并输入这些用户 id 和组 id。因此,您可以将这个用户/组创建作为Dockerfile的一部分。

ARG UID=1000
ARG GID=1000
  • 首先在Dockerfile上增加ARG UID=1000ARG GID=1000UIDGID是容器中的环境变量,您将在docker build阶段向其传递值(默认为 1000)。
  • 然后使用RUN groupadd -g $GID john-group在映像中添加一个组 ID 为GID的 Linux 组。
  • 接下来,使用useradd -N -l -u $UID -g john-group -G sudo john在映像中添加一个用户 ID 为UID的 Linux 用户。您可以看到,我们正在将john添加到sudo组中。但这是可有可无的事情。如果你 100%确定你不需要sudo的许可,你可以省去它。

然后,在映像构建期间,您可以传递这些参数的值,例如,

  • docker build <build_dir> -t <image>:<image_tag> --build-arg UID=<uid-value> --build-arg GID=<gid-value>

举个例子,

  • docker build . -t docker-tut:latest --build-arg UID=$(id -u) --build-arg GID=$(id -g)

拥有非特权用户有助于您运行不应该拥有 root 权限的进程。例如,当 Python 脚本所做的只是从一个目录(例如数据)读取和向一个目录(例如模型)写入时,为什么要以 root 用户身份运行它呢?还有一个额外的好处,如果您在容器中匹配主机的用户 ID 和组 ID,那么您创建的所有文件都将拥有您的主机用户的所有权。因此,如果您绑定装载这些文件(或创建新文件),它们看起来仍像是您在主机上创建的。

创建卷

1.使用卷分离工件

作为一名数据科学家,很明显你将与各种工件(例如数据、模型和代码)打交道。您可以将代码放在一个卷中(如/app),将数据放在另一个卷中(如/data)。这将为您的 Docker 映像提供一个良好的结构,并消除任何主机级的工件依赖性。

我说的工件依赖是什么意思?假设你在/home/<user>/code/src有代码,在/home/<user>/code/data有数据。如果将/home/<user>/code/src复制/挂载到卷/app并将/home/<user>/code/data复制/挂载到卷/data。如果代码和数据的位置在主机上发生变化,也没有关系。只要您挂载这些工件,它们将总是在 Docker 容器中的相同位置可用。因此,您可以在 Python 脚本中很好地修复这些路径,如下所示。

data_dir = "/data"
model_dir = "/models"
src_dir = "/app"

您可以使用COPY将必要的代码和数据放入图像

COPY test-data /data
COPY test-code /app

注意test-datatest-code是主机上的目录。

2.开发期间绑定安装目录

关于绑定挂载的一个伟大之处在于,无论你在容器中做什么,都会被反射到主机上。当您正在进行开发并且想要调试您的项目时,这非常有用。让我们通过一个例子来看看这一点。

假设您通过运行以下命令创建了 docker 映像:

docker build <build-dir> <image-name>:<image-version>

现在,您可以使用以下方式从该图像中建立一个容器:

docker run -it <image-name>:<image-version> -v /home/<user>/my_code:/code

现在,您可以在容器中运行代码,同时进行调试,对代码的更改将反映在主机上。这又回到了在容器中使用相同的主机用户 ID 和组 ID 的好处。您所做的所有更改,看起来都来自主机上的用户。

3.切勿绑定装载主机的关键目录

有趣的故事!我曾经将我的机器的主目录挂载到一个 Docker 容器中,并设法更改了主目录的权限。不用说,我后来无法登录到系统,花了好几个小时来解决这个问题。因此,只装载需要的东西。

例如,假设您有三个想要在开发期间挂载的目录:

  • /home/<user>/my_data
  • /home/<user>/my_code
  • /home/<user>/my_model

您可能很想用一行代码安装/home/<user>。但是写三行代码来分别挂载这些单独的子目录绝对是值得的,因为这将为您节省几个小时(如果不是几天)的时间。

其他提示

1.知道添加和复制的区别

你可能知道有两个 Docker 命令叫做ADDCOPY。有什么区别?

  • ADD可用于从网址下载文件,使用时如,ADD <url>
  • ADD当给定一个压缩文件(如tar.gz)时,会将文件提取到所提供的位置。
  • COPY将给定的文件/文件夹复制到容器中的指定位置。

2.入口点和 CMD 的区别

我想到的一个很好的类比是,把ENTRYPOINT想象成一辆汽车,把CMD想象成汽车中的控制装置(例如加速器、刹车、方向盘)。它本身什么都不做,它只是一个容器,你可以在里面做你想做的事情。它只是等待您将任何传入的命令推送到容器中。

命令CMD是容器中实际执行的内容。例如,bash会在你的容器中创建一个 shell,这样你就可以像在 Ubuntu 的普通终端上工作一样在容器中工作。

3.将文件复制到现有容器

又来了!我已经创建了这个容器,但忘了将这个文件添加到图像中。建立图像需要很长时间。有没有什么方法可以欺骗我并把它添加到现有的容器中?

是的,有,你可以使用docker cp命令。简单地做,

docker cp <src> <container>:<dest>

下一次你跳进容器时,你会在<dest>看到复制的文件。但是请记住,在构建时实际更改Dockerfile来复制必要的文件。

3.结论

太好了!这是所有的乡亲。我们讨论过,

  • 什么是 Docker 映像/容器/卷?
  • 如何写好 Dockerfile 文件
  • 如何以非根用户的身份启动容器
  • 如何在 Docker 中进行正确的卷安装
  • 以及使用docker cp拯救世界等额外提示

现在你应该有信心看着 Docker 的眼睛说“你吓不倒我”。玩笑归玩笑,知道你在 Docker 上做什么总是值得的。因为如果你不小心的话,你可能会使整个服务器瘫痪,并扰乱在同一台机器上工作的其他人的工作。

如果你喜欢我分享的关于数据科学和机器学习的故事,考虑成为会员吧!

[## 通过我的推荐链接加入媒体

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

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

Docker 撰写

原文:https://towardsdatascience.com/docker-compose-44a8112c850a?source=collection_archive---------31-----------------------

完全指南

在本节中,我们将使用 Docker 开发的名为 Voting App 的示例应用程序来了解 Docker Compose、它的文件和命令。

  1. 简介
  2. Docker 文件
  3. 基本对接命令
  4. 端口和卷映射
  5. Docker 联网
  6. 码头仓库
  7. Docker Compose(你在这里!)
  8. 删除 Docker 实体

投票应用是一个用 Python 写的 Flask 应用,用来在猫和狗之间投票。

Python 中的 Web 应用程序

这个投票然后被传输到 Redis,Redis 在这里充当内存中的 DB。工人应用程序,用。NET,然后处理这个投票并将其插入持久数据库——这里是 Postgres 容器。

投票应用

最后,投票结果通过用 NodeJS 编写的 web 应用程序显示出来。

NodeJS 中的 Web 应用

我强烈建议您克隆这个应用程序并试用它,即使您对 Docker Compose 一无所知。如果你能意识到这些服务运行在 5 个不同的容器上,你就有动力继续阅读。

git clone git@github.com:dockersamples/example-voting-app.gitcd example-voting-app/docker-compose up

接下来,我们看看 docker-compose 文件。这是一个简单的 YAML 文件,以服务名及其细节开始,包括创建它的映像、要映射的端口、要链接的其他服务等。

简单 Docker 合成文件

这里我们假设每个图像都是预先构建的,并且可以在 Docker 注册中心(在我们的例子中是 Dockerhub)上获得。为了能够在我们的 Docker 主机上构建服务,这就是我们将为投票、结果和工作者图像所做的,我们必须在 docker-compose 文件中用 build 属性替换 image 属性。

简单 Docker 合成文件

由于 docker-compose 文件多年来持续快速的发展,它有几个版本。从版本 1 到版本 2 的变化是将服务移入服务标签,并在第一行添加版本标签。此外,您不再需要链接,因为默认情况下,每个容器都使用桥接网络连接到其他容器。添加 depends_on 是为了支持在依赖关系的情况下,先完成一些容器的构建。对于本教程的有限范围来说,版本 2 和版本 3 基本上是相同的。请记住 Docker Swarm 和其他容器编排软件(如 Kubernetes)的几个特性是在 docker-compose 的第 3 版中添加的。

Docker 合成文件的各种版本

如果您希望将面向客户端的应用程序的流量与后端应用程序隔离开来,您可以通过添加两个网络(前端层和后端层)来修改 docker-compose 文件,并说明哪个服务位于哪个网络上。

注意,这不是一个完整的 docker-compose 文件,为了简洁起见,我省略了其他细节。

Docker 用两个网络组成文件

运行这个 docker-compose 文件将产生如下所示的应用程序堆栈。

拥有两个网络的投票应用程序

如果您需要记住任何 docker-compose 命令,那就是 docker-compose up ,正如我们在投票应用程序示例中看到的。我还提供了其他命令的列表作为参考。

Docker 编写命令

总之,使用 docker compose,您可以打包并交付一个多容器应用程序,您的客户端只需一个命令就可以启动它。

在下一节的中,我们将看到如何删除 Docker 的各种实体并回收一些空间。

参考:

[1] Docker,编写命令行参考 (2020),Docker 文档

[2]穆姆沙德·曼南贝斯, Docker for the Absolute 初学者 (2020),KodeKloud.com

BI/数据科学开发的 Docker 示例

原文:https://towardsdatascience.com/docker-example-for-bi-data-science-development-16e305ab70fa?source=collection_archive---------32-----------------------

实践教程

我发现 Docker 对于 BI 和数据科学开发工作流来说都是一个强大的工具。减轻“它在我的机器上工作”的问题本身就是非凡的,那么为什么不从健壮的业务解决方案的开发角度出发呢?在可伸缩性、工作流效率和最小化软件依赖性/共享库冲突之间找到*衡可能是困难的。然而,我发现 Docker 在这方面是一个非常强大的解决方案。通过 Docker,我已经能够利用开发工具、框架和软件语言,而无需安装在主机上。这种方法提供了可复制的环境,包含了独立的过程。能够从特定版本的 Python 或 Julia Docker 映像进行编程和开发,而不用担心我的主机上的实际安装或依赖性兼容性问题,这是一种令人难以置信的体验(更不用说不再需要整合虚拟 Python 环境的管理)。

尽管本文给出了一个简单的例子,展示了将 Docker 集成到 BI/数据科学开发工作流中的强大功能,但它确实需要一些 Python 和 Docker 的基础知识背景。

教程概述

该示例将采用一种简单的交互式动态 ML web 应用程序的方法,该应用程序从外部数据库服务器 MS SQL Server 中提取参数依赖性。要预测的函数是笛卡尔坐标中的对数螺线函数(一个向量值函数),web app 本身会依赖于 Dash 框架(Plotly)。使用 Docker Compose,Docker 可以轻松管理多容器环境。一个容器将专用于运行模拟最终生产环境的开发 MS SQL Server。另一个容器将用于主应用程序(Docker Compose 将处理这两个容器之间的内部网络)。每个容器将引用一个环境文件,用于提供动态和可再现的环境,同时减少在任意文件中存储代码中的静态值。这些值将通过引用 YAML 文件的 Python 脚本进行连接,以确定环境变量值。这种方法可能看起来像是增加了多余的逻辑层,但是我发现这种模板方法最终会使事情变得简单得多(特别是当项目变得复杂时)。

为了管理代码结构,额外的离散 Python 文件将用于运行应用程序、为应用程序提供服务、保持预测功能、在应用程序的 GUI 结构中提供帮助,以及自动化开发数据库的播种/搭建。为了帮助搭建和播种开发数据库,我将提供一种方法,使用 Python 脚本作为该过程的启动程序,该程序调用 bash 文件在两个 SQL 文件的帮助下处理搭建方面。

示例项目要在给定的机器上运行,只需安装 Docker 和 Docker-Compose。要运行实际的 web 应用程序,请在运行 Docker Compose UP 命令之前取消 Docker 文件底部的注释。另一种方法是从正在运行的 web 应用程序容器中执行“pythondash _ app _ server . py”(名称应该是interactive-vector-valued-function-app _ dash-app _ x)。如果 web 应用程序正在运行,它应该可以从端口 8080 访问(如果需要,可以在 Docker Compose 文件中更改)。点击此处获取项目代码的副本:

[## bmurders 2/交互式向量值函数应用程序

通过 Dash 实现的交互式 ML/AI web 应用程序。这个应用程序允许最终用户修改向量的参数…

github.com](https://github.com/bmurders2/Interactive-Vector-Valued-Function-App)

DEV、PRD 和 ENV 缩写将分别用于表示开发、生产和环境的代码中。下面是项目结构的快照:

项目文件夹概述-按作者分类的图像

主应用程序的 Dockerfile

主应用程序将从 docker 文件中派生出来,用于创建一个可重现的受控应用程序环境(针对开发和 PRD)。从 Python image 3.8.6-slim 开始,项目代码与工作目录的定义一起被复制(或者,这里可以使用 Git 引用,而不是引用项目代码的本地目录)。然后,运行命令用于应用程序预期运行所必需的依赖性和环境配置(例如,包括来自外壳的 sqlcmd )。我注释掉了 Dockerfile 的底部部分,该部分在作为非根用户启动容器时自动运行应用程序,以提升开发和测试环境。

Web 应用程序的 Dockerfile

Docker 撰写设置

除了建立容器编排配置之外,当 docker-compose UP 命令被执行时。将传入包含各自容器使用的环境变量的 env 文件。例如, dev_mssql.env 中的变量‘MSQL _ PID’将决定要启动的 mssql 服务器的类型(在本例中是 Developer)。如果在正式流程的生产环境中,请确保您的组织中存在有效的许可证,除非附加到现有的生产 SQL Server(无论是哪种情况,此示例都会复制生产环境以确保有效的调试和代码开发)。下图显示了的映射。env 文件从 docker-compose.yml 文件中复制到它们对应的 Docker 容器中。

的可视化映射。env 文件及其相应的服务

Web 应用程序文件

有一个主 web 应用程序文件( dash_app.py )用于 web 应用程序的主要功能,包括 dash 和定制包的包导入。在高层次上,应用程序布局是在导入和所需对象的初始实例化之后定义的,这为应用程序布局提供了总体布局和结构。以下是预期的应用程序视觉呈现的概述(简单明了,带有一个图表和一个参数列表,作为其下方预测函数的输入)。

Web 应用程序的可视化-作者图片

布局所需的一切都可以在这里内联定义,除了对自定义导入的调用,即预测函数的选项卡式参数列表。水*选项卡列表将是一个数组,因此自定义导入 gui_setup.py 将需要一个匹配这个输入要求的输出。这是为了管理潜在的动态变化,而不需要对主应用程序 Python 文件进行大量维护。对于每个参数选项卡,滑块用于确定相应的参数值。

Web 应用程序布局

由于应用程序用户界面的简单性,Dash 框架只需要两个应用程序回调:一个用于从 GUI 角度更新参数滑块,另一个用于传递预测函数所需的输入值,并返回 plot 对象。更新 GUI 滑块很简单,如下图所示。

滑块参数值的更新功能

用于调用预测函数并返回绘图的第二个回调函数比第一个回调函数稍微复杂一些,因此将预测函数本身包装在一个单独的文件中有助于压缩这里的代码。在将输入参数传递给预测函数之后,预期的输出是一个 Pandas 数据帧,可以通过 JSON 格式使用 Plotly 进行绘制。

实时更新绘图的功能

下面的代码是用来服务应用程序的。在这种情况下,将使用女服务员(Gunicorn 是服务基于烧瓶的应用程序的另一个可靠选择)。

为 Web 应用提供服务的代码

助手类和文件

在尝试播种和搭建开发数据库之前,了解相应数据库的生产环境结构是很重要的。该项目使用一个助手 GUI 文件 gui_setup.py ,用于辅助主要的应用程序功能和呈现,它依赖于 app_config.py 文件。然后, app_config.py 文件依赖于 config.yml 文件来确定检索所需值的环境变量名。为了本文的简洁,没有明确显示所有的项目代码。

提供给项目代码的应用程序配置参数概述—图片由作者提供

YAML 配置文件

config.ymlapp_config.py 的可视化关系—图片由作者提供

设定开发数据库服务器的种子

为了设置开发数据库服务器,我们将创建和播种预期的生产数据库、模式和表。这个过程的开始将包含在命令部分下的 docker-compose.yml 文件中(这在容器启动时执行)。这里,将检查一个条件,以确保我们应该通过来自 dev_app_env_vars.env 文件的环境变量继续播种开发数据库。如果这个条件成功,继续调用 Python 生成器文件,MSSQL _ db _ data _ generator . py(文件位置: app/helpers/seed_db )。用于植入/搭建开发数据库的 SQL 文件将要求在调用时传递变量(这些变量在每个文件中显示为“$( <变量>)”。sql 文件)。

Docker-Compose 文件的下半部分突出显示了对MSSQL _ db _ data _ generator . py的调用—图片由作者提供

数据生成概述-按作者分类的图像

参考同一个文件MSSQL _ db _ data _ generator . py中的get _ default _ GUI _ cls _ values()函数,下面是为数据库搭建执行MSSQL _ db _ seed _ script . sh(第 26 行)后将生成的数据插入开发数据库的代码。

搭建并播种开发数据库

下面是由MSSQL _ db _ seed _ script . sh:调用的 SQL 代码

用于创建开发数据库的 SQL 代码

用于创建开发数据库表的 SQL 代码

预测函数

对于应用程序的预测函数,scikit-learn 的两个离散支持向量回归模型将用于分别预测向量值函数曲线的 x 和 y 分量(对数螺线)。将预测结果作为 Pandas 数据框架进行训练和返回所需的代码非常简单。因为要预测的函数不是标量函数,而是向量值函数(由两个分量参数化的直线曲线),所以务必注意 x 和 y 坐标的曲线步长。

预测功能码

web 应用程序运行的最终结果将如下所示,带有模型的选项卡式交互式参数滑块:

结论

这个工作示例演示了在任何运行 Docker 的机器上同时工作的自动化方法中编排多个流程是多么容易。尽管该示例的某些部分对于简单的曲线拟合函数来说可能有些过头,例如当交互式仪表板应用程序本身已经生成值时,使用数据库来保存这些值,但是底层方法展示了在应用于业务解决方案时可伸缩性和敏捷开发的功效。

我想通过一个工作实例来分享利用 Docker 进行 BI/数据科学项目的方法。特别是考虑到 Docker 可以直接用于开发阶段,因为它减少了安装额外的软件工具或调试由于运行时不兼容问题引起的主机问题的需要。个人认为,Docker 是业务创新的有力工具。

数据科学 Docker 逐步指南

原文:https://towardsdatascience.com/docker-for-data-science-a-step-by-step-guide-1e5f7f3baf8e?source=collection_archive---------2-----------------------

卢卡斯·范·奥尔特在 Unsplash 上的照片

在这篇文章的最后,你将通过 Docker 在你的机器上运行一个 ML 工作空间,里面有你需要的 ML 库,VSCode,Jupyter Lab + Hub,以及许多其他好东西。

关于为什么 Docker 可以改善你作为数据科学家的生活,已经有很多 说过了。我和几个朋友正在使用 Fast.ai 做一个(不)酷的深度估计项目,这时我偶然发现了@ Jeremy Howard的这条推文。

开始这篇文章的推文

碰巧我们正在使用 Docker 为项目创建我们的数据科学工作区,所以我认为解决 Jeremy 的问题并与社区分享这些知识是有意义的。

我将非常简要地回顾一下 Docker 的核心概念和优势,然后展示一个使用 Docker 建立整个数据科学工作空间的分步示例。

如果你已经知道 Docker 是什么,为什么它很棒,那么跳到分步教程

Docker 是什么?

Docker 是一个创建和部署隔离环境(即虚拟机)的工具,用于运行具有依赖关系的应用程序。

您应该熟悉的几个术语(为了便于理解,包括一个烘焙类比):

  • Docker 容器 —应用程序的单个实例,它是实时运行的。在我们的比喻中,这是一块饼干。

一块跳舞的饼干。吉菲

  • Docker Image—创建容器的蓝图。图像是不可变的,从同一图像创建的所有容器都是完全一样的。在我们的比喻中,这是千篇一律的模式。

饼干切割器。伊莎贝拉·艾奇逊 / Unsplash

  • Dockerfile —包含创建 Docker 映像时要调用的命令列表的文本文件。在我们的类比中,这是创建千篇一律的模具的指令。

制作饼干切割器。吉菲

(作为一名数据科学家)我为什么要关心?

概括地说,ML 中的 Docker 有两个用例:

  • 只运行 : 只运行容器是指你在本地 IDE 上编辑你的代码,用容器运行它,这样你的代码就在容器里面运行了。这里有一个很好的例子。
  • 端到端*台 : 端到端*台容器是指你有一个 IDE 或者 Jupyter 笔记本/实验室,以及你的整个工作环境,在容器中运行,也在里面运行代码(可以挂载的工作文件系统除外)。

我们将关注第二个用例。

在数据科学项目中使用 Docker 的原因

使用 docker 容器意味着你不必处理“在我的机器上工作”的问题。

一般来说,Docker 提供的主要优势是标准化。这意味着您可以一次定义容器的参数,并在安装 Docker 的任何地方运行它。这反过来提供了两个主要优势:

  1. 再现性: 每个人都有相同的 OS,相同版本的工具等。这意味着你不需要处理“在我的机器上工作”的问题。如果它能在你的机器上工作,它也能在每个人的机器上工作。
  2. 可移植性: 这意味着从本地开发迁移到超算集群很容易。此外,如果你像我们在 DAGsHub 一样从事开源数据科学项目,你可以 为合作者提供一种简单的方法来绕过设置的麻烦

另一个巨大优势——学习使用 Docker 会让你成为一名更好的工程师,或者让你成为一名拥有超能力的数据科学家。许多系统依赖于 Docker,它将帮助您将 ML 项目转化为应用程序,并将模型部署到生产中。

面向数据科学的 docker 容器示例

  • pytorch/pytorch —包含 pytorch 的用例 1 的简单容器
  • jupyter/scipy-notebook —用例 2 的容器,包括作为 UI 的 jupyter,以及许多 python 数据科学模块
  • Dag shub/ml-workspace-minimal—是我将在上面展示逐步指南的容器。该容器是来自 ml-tooling/ml-workspace 存储库的更新版本。原来的已经有 7 个月没有维护了,所以我创建了一个最新的版本。它结合了以下工具:
    -💫Jupyter,JupyterLab
    👾VSCode 基于 web 的 IDE。
    • 🗃 Pytorch、Tensorflow、Sklearn、Pandas 等众多流行的数据科学库&工具。
      -可通过网络浏览器访问的🖥全 Linux 桌面图形用户界面。
      —🎮通过网络浏览器轻松访问终端。
      —🔀针对笔记本电脑优化的无缝 Git 集成。
      —📈集成硬件&通过 Tensorboard & Netdata 进行训练监控。
      —🚪从任何地方通过 Web、SSH 或 VNC 在单个端口下访问。
    • 🎛可通过 SSH 用作远程内核(Jupyter)或远程机器(VSCode)。
      —🐳易于通过 Docker 在 Mac、Linux 和 Windows 上部署。

听起来很棒,对吧?!现在让我们看看如何设置它。

设置您的数据科学 docker 容器—分步指南

安装 Docker

安装 Docker 是容易和免费的。只需根据您的操作系统遵循本指南即可。

建立码头工人形象

将不在本教程中讨论。一旦我们有了想要的图像,我们的重点将是如何运行 Docker 容器。

我们将使用来自Dag shub/ml-workspace-minimal的预构建图像。它是从 GitHub 上的这个中创建的。如果你想建立或修改这张图片或任何其他图片,我推荐杰瑞米·霍华德在他的原始推文中提到的那篇文章。

Docker Run +处理所有特殊修饰符

只需运行以下命令:

docker run -d \
    -v "/${PWD}:/workspace" \
    -p 8080:8080 \
    --name "ml-workspace" \
    --env AUTHENTICATE_VIA_JUPYTER="mytoken" \
    --shm-size 2g \
    --restart always \
    dagshub/ml-workspace:latest

docker run是获取 Docker 映像(cookie cutter)并从中创建容器的命令。在我们的类比中,这是制作饼干的步骤。

这个长命令可能看起来很吓人,但是我们可以把所有这些标志想象成我们的饼干(巧克力片和夏威夷果)的配料😋).以下是对各种标志以及为什么需要它们的解释:

挂载你的工作文件系统 **-v "/${PWD}:/workspace"** 这可能是最重要的标志。它允许您在容器关闭后保留您的工作(文件),并从容器外部访问它们。

它通过将您当前的工作文件夹(在这里您执行docker run命令),表示为/${PWD},映射到容器的虚拟文件系统中的/workspace文件夹。如果你想改变这一点,你可以适当地改变这个论点。

端口转发这个参数暴露了 8080 端口。本质上,这意味着在计算机上运行这个程序后,可以通过http://{computer-ip}:8080访问您的容器。如果您在本地系统上运行这个,那么这个地址将是[http://localhost:8080](http://localhost:8080)。对于更复杂的映像,出于 API 端点等其他原因,您可能需要转发多个端口。在我们的例子中,端口是 UI 端点,它将把您带到 ML-Workspace 的主屏幕:

http://localhost:8080—我的 ML-Workspace 主页

命名我们的容器 **--name "dags-workspace"** 这为我们的容器生成了一个惟一的标识符,以供将来参考。顾名思义,这个名称在您的系统中应该是唯一的,所以如果您从同一个映像创建多个容器,您需要为它们定义不同的名称。--name也有助于给我们的容器添加含义。如果不定义名字,会自动为你生成一个没有意义的。

定义环境变量**--env AUTHENTICATE_VIA_JUPYTER="mytoken"** --env标志为你的容器定义环境变量。这在不同的容器之间变化很大,因此很难给出一个通用的用例。

在我们的例子中,我们用它来定义工作区的密码。当有人第一次打开上面的链接时,Jupyter 会要求他们输入这里定义的密码。如果您在共享电脑上工作,这可能会很有用。

ML 工作区请求密码

定义共享内存 **--shm-size 2g** 这个标志用来定义你的容器的共享内存(越多越好)。请记住,这与您的常规系统使用相同的 RAM,所以如果您设置得太高,可能会降低您的计算机速度。对于大多数用例来说,一个好的大小应该在2g8g之间。

定义重启策略**--restart always** --restart标志代表容器的重启策略。根据码头文件:

重启策略控制 Docker 守护程序在退出后是否重启容器。

我们使用always选项,这意味着即使系统重启,Docker 也会试图保持容器运行。这对于保持您的项目上下文完整无缺非常有用。

恭喜你!现在你已经有一个完整的 ML 工作空间在你的 docker 上运行,包括你可能需要的所有东西。

如果你想更深入一层,我推荐你去docker run 命令参考查看所有可用的标志。

附加设置

让我们回顾一下我建议你建立一个理想工作空间的几件事情。

在 Docker 中设置 Conda/虚拟环境

我们设置了一个标准化的独立机器来运行我们的 ML。如果你是第一次设置你的项目,你可能会跑去找你的环境管理器conda / pip安装一些很棒的包。

让我打断你一下。

为什么要花这么大力气去创建一个隔离的、可复制的环境,然后去安装一堆没有人知道的不同的包。您应该创建一个 Conda 或虚拟环境来管理您的软件包。如果您决定使用DAGsHub/ml-workspace-minimal容器,您应该这样做:

在 ML 工作区主页中,点击打开工具下拉菜单并选择终端。然后键入以下命令:

# Input your <env-name> and the <python-version> you want
conda create -y --name <env-name> python=<python-version>
# Activate your environment
source activate <env-name># If you have a `requirements.txt` file, you should install those requirements
pip install -U pip setuptools wheel
pip install -r requirements.txt

安装完包之后,如果您想保存项目(希望提交给 Git ),您应该通过运行以下命令来保存包列表:

# This will override your existing `requirements.txt`. 
# If you want to append, use `>>` instead of `>`
pip list --format=freeze > requirements.txt

注意:想知道为什么你应该使用这个命令来列出你的需求(而不是pip freeze >> requirements)?阅读本期 GitHub

包装它

现在,你已经用 Docker 建立了一个隔离的、可复制的、可移植的、令人敬畏的 ML 工作空间。我希望这篇文章对你有用,如果你有任何问题或反馈,请通过我们的 DAGsHub Discord Channel 联系。

杰西·贝利 / Unsplash 拍摄的照片

Python-Dash 和 R-Shiny 的 Docker

原文:https://towardsdatascience.com/docker-for-python-dash-r-shiny-6097c8998506?source=collection_archive---------6-----------------------

Docker & docker-compose 快速入门。以及显示新冠肺炎案例编号的仪表板示例。

您想使用 Docker & Docker Compose 部署您的数据驱动型应用程序吗?然后继续读下去,因为这篇文章会让你在几分钟内就开始运行。对于最广泛传播的数据科学/分析堆栈: Python & R

在我最*的媒体报道中,我解释了如何建立一个数据驱动的 web 应用程序,以显示冠状病毒的病例数。我用下面的两个栈创建了完全相同的 web 应用:

在本文中,我将向您展示如何使用 Docker & Compose 部署这些应用。我将首先介绍 Docker,包括 Python 和 R,稍后再介绍 docker-compose。

托马斯·詹森在 Unsplash 上拍摄的照片

码头工人

装置

在你选择的服务器上安装 Docker 很容易——有大量的说明。例如,如果您有一个运行 Amazon Linux 的 AWS 实例(EC2) ,只需输入:

sudo yum install -y docker  # Install Docker.
sudo service docker start   # Start the service.
sudo usermod -a -G docker ec2-user  # Add ec2-user to Docker group.
sudo chkconfig docker on    # Let docker auto-start.

完美。码头工人准备好了!

Python-Dash 的 docker 文件

首先,我们要创建requirements . txt文件,包括所有必要的库。这可以使用命令来完成

pip freeze > requirements.txt

或者通过手动创建文本文件并输入库的名称。对于提到的 app ,我们需要以下库(顺便说一下, plotly 安装有破折号):

dash
pandas

然后我们准备设置 DOCKERFILE 本身。对于一个简单的 Python-Dash 应用程序,以下代码就足够了:

FROM python:3.8
LABEL maintainer "Meinhard Ploner <[dummy@host.com](mailto:meinhard.ploner@gmail.com)>"WORKDIR /codeCOPY requirements.txt /
RUN pip install -r /requirements.txt
COPY ./ ./EXPOSE 8050CMD ["python", "./app.py"]

单个命令的描述:

  • FROM …:提取标签为 3.8(=版本)的 Python 图像。
  • 标签…:可选。维护者的姓名和电子邮件。
  • WORKDIR …:设置工作目录。
  • 复制需求…:复制需求. txt 文件。
  • 运行 pip …:安装所有列为需求的库。
  • 收到。/ …:将所有文件复制到 Docker 映像。
  • EXPOSE …:设置监听端口。
  • CMD …:设置运行映像时要执行的命令。

完美。如果我们对 R 解决方案不感兴趣,我们可以跳到****docker-compose的定义。否则,请继续…

R-Shiny 的 docker 文件

在 R 上,通常不在需求文件中列出,而是直接成为 DOCKERFILE 代码的一部分。与 Python 类似,我提出了一个 DOCKERFILE,它适用于简单的应用程序,就像我在其他帖子中解释的那样。

该文件比 Python 稍微复杂一些,但仍然很紧凑:

FROM rocker/shiny:3.6.1
LABEL maintainer "Meinhard Ploner <[dummy@host.com](mailto:meinhard.ploner@gmail.com)>"WORKDIR /srv/shiny-serverRUN apt-get update \
    && apt-get install -y libsasl2-dev libssl-devRUN echo \
  'options(repos=list(CRAN="[https://cloud.r-project.org/](https://cloud.r-project.org/)"))' > \
  ".Rprofile"
RUN R -e "install.packages(c('dplyr','tidyr', 'plotly'))"ADD https://raw.githubusercontent.com/rocker-org/shiny/master/shiny-server.sh /usr/bin/COPY ./ ./EXPOSE 3838RUN chmod a+w .
RUN chmod +x /usr/bin/shiny-server.shCMD /usr/bin/shiny-server.sh

单个命令的描述:

  • 来自…:提取标签为 3 . 6 . 1(=版本)的 R-闪亮图像。
  • 标签…:可选。维护者的姓名和电子邮件。
  • WORKDIR …:设置工作目录。
  • 运行 apt-get …:安装 libssl ,这是 plotly 所需要的。在其他 Linux 实例或 Windows 上可能有所不同。
  • 运行 echo …:将 CRAN 库 URL 写入。Rprofile ,在后续的 R 调用中使用。
  • 运行 R …:调用 R 来安装各种包。
  • ADD …:下载 shiny-server.sh 文件并将其添加到映像中。
  • 收到。/ …:将所有文件复制到 Docker 映像。
  • EXPOSE …:设置监听端口。
  • 运行 chmod +w…:使镜像的主目录可写。
  • 运行 chmod +x…:使 shiny-server.sh 可执行。
  • CMD …:设置运行映像时要执行的命令。

就是这样。让我们继续进行作曲部分。

Docker 撰写

装置

docker-compose 的安装也很简单。从 GitHub 复制适当的二进制文件,并修复权限:

sudo curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose

你可能想知道 uname 这个命令是干什么用的? uname 返回操作系统的基本信息。在搭载亚马逊 Linux 的 AWS EC2 上,对于“ uname -s ”给出了“ Linux ”,对于“ uname -m ”给出了“ x86_64 ”。

docker-为 Python-Dash & R-Shiny 编写文件

docker-compose . ymlYAML 文件在两个堆栈之间没有区别。但是在创建它之前,先设置一个名为“的环境文件。env "带基本应用信息:

VERSION=1.0.0
TARGET=LIVE

现在创建合成文件,在我们的例子中,它是极简的:

version: "3.7"services:
  app-name:
    build:
      context: .
    image: app-name:$VERSION
    container_name: app-name
    ports:
      - "to:from"
    environment:
      - TARGET=$TARGET
    restart: unless-stopped

将“ 应用名称 ”替换为您选择的应用名称。映像名称将使用版本号,在我们的例子中是“ app-name:1.0.0 ”。

此外,Python-Dash 应用程序通常运行在端口 5050 上,而 R-Shiny 应用程序默认使用端口 3838。因此将端口 ( “至:”)替换为:

  • Python-Dash 为 80:5050
  • 80:3838 代表 R-闪亮

除了端口 80,您还可以使用您想要服务的任何其他端口。将文件另存为 docker-compose.yml,就大功告成了。

构建并运行!

要构建图像,请使用:

docker-compose build

构建完映像后,通过键入以下命令构建并启动容器:

docker-compose up -d

选项-d "确保应用程序在后台运行。如果没有该选项,您将直接看到日志,这对测试设置的最初几次运行非常有用。

如果您从 GitHub 下载了应用程序代码并按照说明操作,您的应用程序将在服务器上运行。

否则,您也可以测试运行在 my EC2 实例上的应用程序:

结论

如您所见,部署一个简单的 Dash 或闪亮的应用程序没什么大不了的。即使一个应用变得更加复杂,这些例子也可以作为一个蓝图。

我希望你喜欢这篇文章,它有助于让你自己的应用程序运行起来!

Docker 网络

原文:https://towardsdatascience.com/docker-networking-919461b7f498?source=collection_archive---------19-----------------------

容器是如何与它们的宿主以及彼此通信的!

当你安装 docker 时,它会自动创建三个网络——网桥、主机和无网络。其中,网桥是容器运行时所连接的默认网络。要将容器连接到任何其他网络,您可以使用 run 命令的 - network 标志。

  1. 简介
  2. Docker 文件
  3. 基本对接命令
  4. 端口和卷映射
  5. Docker 联网(你来了!)
  6. 码头仓库
  7. Docker 撰写
  8. 删除 Docker 实体

Docker 中自动创建的网络

网络将 172.17.x.x 范围内的 IP 分配给其中的容器。要从外部访问这些容器,您需要将这些容器的端口映射到主机上的端口。另一个自动创建的网络是主机。选择主机网络将移除 docker 主机和容器之间的任何网络隔离。例如,如果您在端口 5000 上运行一个容器,它将可以在 docker 主机上的同一个端口上被访问,而不需要任何显式的端口映射。这种方法的唯一缺点是不能对任何容器两次使用同一个端口。最后, None 网络保持容器完全隔离,即它们不连接到任何网络或容器。

这些容器可以使用它们的名字相互联系。这是通过运行在地址 127.0.0.11 上的嵌入式 DNS 实现的。

嵌入式 DNS

默认情况下,容器连接到同一个网络。如果我们希望两个容器在不同的网络上,我们该怎么办?

默认网络

为此,我们可以使用以下命令定义一个用户定义的网络,并在运行容器时分配该网络。

docker network create \
	--driver bridge \
	--subnet 182.18.0.0/16 \
	user-def

用户定义的网络

下一节中,我们将了解 Docker 储物件!

参考:

[1]穆姆沙德·曼南贝斯, Docker for the Absolute 初学者 (2020),KodeKloud.com

码头仓库

原文:https://towardsdatascience.com/docker-storage-598e385f4efe?source=collection_archive---------12-----------------------

Docker 数据架构和持久存储

在本节中,我们将讨论 docker 如何在本地文件系统上存储数据,了解哪些层是可写的,并加深我们对容器持久存储的了解。

  1. 简介
  2. Docker 文件
  3. 基本对接命令
  4. 端口和卷映射
  5. Docker 联网
  6. Docker 存储(你在这里!)
  7. Docker 撰写
  8. 删除 Docker 实体

在 linux 系统上,docker 将与映像、容器、卷等相关的数据存储在 /var/lib/docker 下。

Linux 系统上 Docker 文件的位置

当我们运行 docker build 命令时,docker 为 docker 文件中的每条指令构建一个层。这些图像图层是只读图层。当我们运行 docker run 命令时,docker 构建容器层,这是读写层。

Docker 层

你可以在容器上创建新的文件,例如,下图中的 temp.txt 。您还可以修改属于容器上图像层的文件,例如,下图中的 app.py 。当您这样做时,会在容器层上创建该文件的本地副本,并且更改只存在于容器中,这称为写入时复制机制。这很重要,因为几个容器和子图像使用相同的图像层。只要容器还活着,容器上的文件就一直存在。当容器被销毁时,其上的文件/修改也被销毁。为了持久化数据,我们可以使用我们在上一节中看到的卷映射技术。

写入时复制机制

您可以使用 docker volume create 命令创建一个 docker 卷。这个命令将在/var/lib/docker/volumes目录中创建一个卷。

docker volume create data_volume

现在,当您运行 docker run 命令时,您可以使用 -v 标志来指定使用哪个卷。这称为卷安装。

docker run -v data_volume:/var/lib/postgres postgres

如果该卷不存在,docker 会为您创建一个。现在,即使容器被销毁,数据也将保留在卷中。

如果希望将数据放在 docker 主机上的特定位置,或者磁盘上已经有数据,也可以将这个位置挂载到容器上。这被称为绑定安装。

docker run -v /data/postgres:/var/lib/postgres postgres

具有卷映射的持久存储

下一节中,我们将了解 Docker Compose、它的文件和它的命令。

参考:

[1]穆姆沙德·曼南贝斯, Docker for the Absolute 初学者 (2020),KodeKloud.com

Docker + TensorFlow + Google 云*台=爱

原文:https://towardsdatascience.com/docker-tensorflow-google-cloud-platform-love-87c026f08cc7?source=collection_archive---------44-----------------------

记录你的张量流,让你的生活更轻松

Docker, TensorFlow and Google Cloud Platform logos. Heart by Bohdan Burmich from the Noun Project.

Docker 改变了我的工程生活。我已经学会爱那条鲸鱼了!

几年前,当我第一次在 Windows 笔记本电脑上安装支持 GPU 的 TensorFlow 时,我对这个过程的复杂和脆弱感到震惊。当我在笔记本电脑上启动双引导 Ubuntu 时,我不得不重复这个可怕的过程。当我的桌面有了 GPU 后,我不得不重温过去的创伤。

如果有一种与操作系统无关的运行 TensorFlow 的方式,可以让您在几分钟内启动并运行,那会怎么样?

这是本帖的重点!我们将使用一个Google Cloud Platform (GCP)计算引擎虚拟机作为我们的机器。但是你可以很容易地用你自己的带有NVIDIA GPU的笔记本电脑/台式机替换这个虚拟机。

注意:我将假设您已经安装了 **GCP account** **GCP SDK** ,这样您就可以从您的终端运行 GCP 命令。

我们将访问的主题

以下是本文将涉及的主题的概述:

  • GPU quotas在 GCP
  • GCP 计算引擎VM startup scripts
  • 我们支持 GPU 的TensorFlow Dockerfile
  • GCP Cloud Build在云中构建我们的 Docker 映像
  • GCP,GCP 的码头中心
  • 测试我们是否可以从 Docker 容器中访问我们的 GPU

我们开始吧!

你有 GPU 配额吗?

当你第一次在 GCP 开始时,你不会被分配一个 GPU 来玩。如果你试图让一个虚拟机的 GPU 配额不足,你会得到一个错误,告诉你你的配额已经超过。所以让我们现在就解决这个问题。

转到IAM & Admin -> Quotas

Metrics下拉列表中,首先点击None

在文本框中搜索GPUs (all regions)并点击出现的结果:

勾选下面列表中的方框,然后点击EDIT QUOTAS:

填写屏幕右侧出现的表格,并请求至少一个 GPU:

现在我们等待我们的批准。这应该很快——我不到两分钟就被批准了!

构建虚拟机

一旦我们增加了配额,我们就可以开始构建至少有一个 GPU 的虚拟机。为了做到这一点,我们可以进入 UI 中的Compute Engine,或者我们可以学习如何使用 GCP 的Cloud SDK。还是做后者吧!

假设我们想在名为deep-docker的区域us-west-1b中创建一个虚拟机。假设我们已经安装了 Cloud SDK,我们可以在终端中发出这个命令:

gcloud compute instances create deep-docker \
	--zone=us-west1-b \
	--accelerator="type=nvidia-tesla-k80,count=1" \
	--image-family "ubuntu-1804-lts" \
	--image-project "ubuntu-os-cloud" \
	--boot-disk-device-name="persistent-disk" \
	--boot-disk-size=100GB \
	--boot-disk-type=pd-standard \
	--machine-type=n1-standard-4 \
	--maintenance-policy=TERMINATE \
	--metadata-from-file startup-script=./startup.sh

现在不要担心metadata-from-file startup-script=...的争论。我们将在下一节探讨这一点。

当我们可以使用gcloud compute instances create-with-container创建一个带有容器的 VM 时,为什么我们选择了 Ubuntu?好问题!这个命令创建了一个基于 Chromium OS 的带有Container-Optimized OS的虚拟机。在这样的虚拟机上安装 NVIDIA 驱动程序要复杂得多,所以我们选择 Ubuntu,让我们的生活变得更轻松。如果你热衷于使用容器优化的操作系统,那么请看这份报告中的 GPU 驱动程序安装解决方案。

在发出这个命令之前,我们需要在当前目录中有一个启动脚本。让我们来看看这个启动脚本是怎么回事!

启动脚本

这里的是完整的启动脚本。

启动脚本会处理一些棘手的事情:

  • 它安装 Docker 并将gcloud设置为 Docker 凭证助手。这将允许我们从 GCP 的Container Registry中提取我们稍后将构建的 Docker 图像。
  • 它将 NVIDIA 驱动程序安装到虚拟机上。
  • 它安装了 NVIDIA 容器工具包,这将允许我们的 Docker 容器访问我们虚拟机上的 GPU。

让我们最后发出命令,等待我们的 VM 完成构建。

您可以通过 SSH 进入您的机器来跟踪启动脚本的进度:

gcloud compute ssh whale@deep-docker --zone=us-west1-b

进入虚拟机后,发出以下命令并查看您的日志流:

tail -f /var/log/syslog

在某些时候,您应该会看到类似这样的内容:

Apr 12 08:09:49 deep-docker startup-script: INFO Finished running startup scripts.

在这里你可以跳一小段庆祝舞。这个过程最难的部分已经过去了!

让启动脚本运行一次

我们的启动脚本的一个问题是,它在每次虚拟机启动时运行。如果我们频繁重启我们的虚拟机,这将变得不必要的耗时。

确保我们的脚本只运行一次的一种方法是使用gcloud CLI 将它从虚拟机的元数据中删除:

gcloud compute instances remove-metadata deep-docker --keys=startup-script

另一种方法是遵循此处的建议。这是我采取的方法。在启动脚本中,您会看到它的大部分被包含在一个if语句中:

if test ! -f "$STARTUP_SUCCESS_FILE"; then
	...
	touch /home/$LOGIN_USER/.ran-startup-script
else
	echo "$STARTUP_SUCCESS_FILE exists. not running startup script!"
fi

我们根据特定位置是否存在名为.ran-startup-script的文件来决定是否运行启动脚本的主体。在第一次引导时,那个文件不存在,所以执行了if语句的主体。如果我们的虚拟机第一次启动一切顺利,上面的touch行将创建.ran-startup-script。在第二次启动时,启动脚本中所有耗时的部分都不会被执行。我们可以检查/var/log/syslog以确认这是事实:

Apr 12 09:05:58 deep-docker startup-script: INFO startup-script: /home/whale/.ran-startup-script exists. not running startup script!
Apr 12 09:05:58 deep-docker startup-script: INFO startup-script: Return code 0.

文档文件

这里的是我们的 Dockerfile。超级简单!

  • 我们在 Python 3 中使用 TensorFlow GPU 基础映像。在编写时,该图像是tensorflow/tensorflow:2.1.0-gpu-py3图像。
  • 我们安装 JupyterLab。
  • 我们安装了一些其他的 Python 包。

我们现在将建立这个图像。

在云中构建 Docker 映像

我们使用的 TensorFlow 图像大小约为 2GB。我们将利用 GCP 的强大功能,在云中构建 Docker 映像,而不是在本地构建并从本地机器推送到Container Registry

我们将建立的形象将位于gcr.io/GCP_PROJECT_NAME/SOME_IMAGE_NAME。我的项目叫learning-deeply。我想把图像叫做tf-2.1.0-gpu。因此,我将在我的终端中发出以下命令:

REMOTE_IMAGE_NAME=gcr.io/learning-deeply/tf-2.1.0-gpu \
	&& gcloud builds submit --tag $(REMOTE_IMAGE_NAME) \
        --timeout=15m

我指定了一个更长的超时来解决我遇到的超时问题。让我们发出命令,看着我们的构建发生吧!

我们可以在 GCP 控制台的Cloud Build部分监控我们的构建进度:

一旦完成,让我们前往Container Registry部分,我们应该在那里看到我们美丽的形象!

点燃我们的容器,检查图形处理器

这太令人兴奋了!我看到你期待地搓着手掌。让我们看看我们的努力是否有回报。

首先,让我们 SSH 进入我们的 VM(参见startup script部分了解如何操作)。

让我们将 Docker 映像放入我们的虚拟机中!发出与此类似的命令,用您在前面发出gcloud builds submit时提供的内容替换对图像位置的引用:

docker pull gcr.io/learning-deeply/tf-2.1.0-gpu:latest

由于我们已经在启动脚本中处理了容器注册认证,这应该会从Container Registry中提取您的图像。

接下来,让我们启动我们的容器。注意,我们有一个--gpus参数,它将我们虚拟机上的所有 GPU 暴露给我们的容器:

docker run -it -d --name tf --gpus all gcr.io/learning-deeply/tf-2.1.0-gpu

问题docker ps我们应该看到我们的容器运行!

现在让我们在容器上执行一个交互式 Bash shell:

docker exec -it tf bash

你应该会看到像这样美丽的东西:

现在交叉手指运行这个来检查我们是否可以访问我们的 GPU:

python3 -c "import tensorflow as tf;print(tf.config.list_physical_devices('GPU'))"

将打印一串文本。但是如果你最后看到这样的东西,你就知道你成功了,我的朋友们:

[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]

结论

Docker 改变了我的工作方式。我不仅将它用于我的机器学习工作,还将它用于我的常规数据分析工作和构建我的博客。

如果你的职称以“数据”开头,那就帮自己一个忙,学会使用它。你也可以学会爱鲸鱼!

直到下一次,

贾斯廷

原载于 2020 年 4 月 13 日

码头工人:你做错了

原文:https://towardsdatascience.com/docker-you-are-doing-it-wrong-e703075dd67b?source=collection_archive---------6-----------------------

使用 VS 代码和 Docker 扩展成为 Docker 超级用户。

micha Parzuchowski 在 Unsplash 上的照片

您已经用自己选择的语言实现了服务。现在,您希望在将它部署到生产环境之前,将其打包并在本地进行测试。第一步是编写 Dockerfile 文件、构建映像、运行容器并检查日志。对吗?

插图作者劳雷尔·杜尔马尔

不完全是。虽然这个过程是完全可以接受的,但有一个更好的方法:一个可以为您编写 Docker 文件的工具,如果您想要编辑它,它可以帮助您自动完成,并提供一个图形用户界面来与 Docker 引擎进行交互。

如果有一个工具可以为你编写 Docker 文件,帮助你自动完成,并提供图形用户界面与 Docker 引擎进行交互,会怎么样?

Visual Studio 代码的 Docker 扩展不仅仅是另一个 IDE 扩展。它有能力提升你与 Docker 的工作方式。在这个故事中,我们深入探讨了 Docker Visual Studio 代码扩展可以做什么,以及如何使用它成为 Docker 超级用户。

学习率是我每周给那些对 AI 和 MLOps 世界好奇的人发的简讯。你会在每周五收到我关于最新人工智能新闻、研究、回购和书籍的更新和想法。在这里订阅!

Docker + VS

VS 代码的 Docker 扩展使得从 Visual Studio 代码构建、运行、管理和部署容器化的应用程序变得容易。要开始使用它,请确保下载 Visual Studio 代码市场的扩展。此外,这是一个开源项目,因此您可以检查它的代码,安装过程非常简单,因此没有必要在这里的另一节中介绍它。

主要特征

在这一节中,我们将介绍 Docker 扩展的突出特性。稍后,我们将在一个简单的示例中使用它们中的许多。

  • 编辑 docker 文件:编辑Dockerfiledocker-compose.yml文件时,您可以使用智能感知自动完成功能。此外,您还可以获得常用命令的语法帮助。

VS 代码上 Docker 的智能感知和语法帮助

  • 通用 Dockerfiles: 通过使用命令面板中的Docker: Add Docker Files to Workspace命令,你可以生成并添加一个 Dockerfile 到你的工作空间。该命令将生成Dockerfile.dockerignore文件,并将它们添加到您的工作区。您也可以使用此命令来生成 Docker 合成文件。这将证明在调试时非常方便。

为一个简单的 flask 应用程序生成 docker 文件

  • Explore:Docker 扩展为 VS 代码贡献了一个 Docker 视图。Docker 视图允许您检查和管理 Docker 资产:容器、映像、卷、网络和容器注册表。一切只需点击鼠标右键。

VS 代码中的 Docker 视图

  • 执行 Docker 命令:许多最常见的 Docker 命令都内置在命令面板中。您可以运行 Docker 命令来管理图像网络图像注册表,以及 Docker 组合。此外,**Docker: Prune System**命令将删除停止的容器、悬挂的图像以及未使用的网络和卷。

集成到调色板中的通用 Docker 命令

  • 调试容器:使用 Docker 扩展,我们可以调试使用 Node.js、Python 或。NET (C#)在一个容器内运行。

还有更多的特性,比如注册表连接和上下文管理,但是仅仅通过使用这些关键的产品,你就可以走很长的路。接下来,我们实现一个简单的 Python Flask 应用程序,对它进行 dockerize 并部署它,而无需摆弄 Docker CLI。

简单的例子

在本节中,我们构建一个简单的" Hello World " Flask 应用程序,并使用 Docker 扩展部署它。首先,代码:

如果您熟悉 Flask,您会发现这是您可以实现的最简单的应用程序。每当您点击根端点时,它就返回“ Hello World ”。接下来,我们需要一个requirements.txt文件来保存依赖项,我们已经准备好了:

Flask==1.1.2
gunicorn

要创建 Dockerfile 和其他任何东西,你只需要在命令面板中运行Docker: Add Docker Files to Workspace(windows 中的ctlr+shift+p)。

为第一个问题选择Python: Flask选项,然后,扩展将询问您是否想要包含可选的 Docker 编写文件。选择是;这样,您将能够在以后调试运行在容器内部的应用程序。最后,选择包含 Flask 应用程序的 python 文件(上面提供的代码)和您想要公开的端口(5000是默认的)。你准备好了!

现在,要构建图像,右键单击生成的 Dockerfile 并选择Build Image...。一个终端将打开,你的图像将在几秒钟内准备好。

使用 VS 代码的 Docker 扩展构建您的映像

要运行应用程序,从左侧面板选择 Docker 图标,在Images部分找到您的图像,右键单击它并选择 run。就这么简单。

使用 VS 代码的 Docker 扩展运行你的容器

Containers部分找到正在运行的容器,右键单击它并选择View Logs。这个命令将在终端中显示容器的日志。获取它正在监听的端点(应该是[http://0.0.0.0:5000](http://0.0.0.0:5000))。要获得 Python 服务的结果,请运行curl [http://0.0.0.0:5000](http://0.0.0.0:5000)

使用 VS 代码的 Docker 扩展查看日志

就是这样!VS 代码的 Docker 扩展简化了这个过程,你可以有时间专注于你的代码。

排除故障

要用 Gunicorn 配置调试,我们需要更多的东西。The Docker: Python-Flask使用 Python 调试器,自动创建的启动配置会覆盖容器的 Gunicorn 入口点。要调试运行 Gunicorn 的应用程序,我们应该遵循以下步骤:

  1. debugpy添加到您的requirements.txt文件中。
  2. 将以下代码片段添加到要调试的文件中:
import debugpy
debugpy.listen(("0.0.0.0", 5678))
debugpy.wait_for_client()

3.将一个Python: Remote Attach配置添加到.vscode文件夹中的launch.json中。JSON 文件现在应该如下所示:

4.通过将5678:5678添加到 ports 部分,修改docker-compose.yml文件以公开调试器端口。该文件现在应该如下所示:

5.右键单击一个docker-compose.yml文件并选择 Compose Up 来启动容器。

6.在所选文件中设置断点,导航至Run and Debug并选择Python: Remote Attach启动配置。

7.按 F5 或按播放按钮来连接调试器。

调试愉快!

结论

在这个故事中,我们探索了 VS 代码的 Docker 扩展,以及它如何帮助我们编写 Docker 文件、构建映像并部署它。要深入了解,请查看 Visual Studio 代码文档网站上的使用容器主题。

学习率是我每周给那些对 AI 和 MLOps 世界好奇的人发的简讯。你会在每周五收到我关于最新人工智能新闻、研究、回购和书籍的更新和想法。在这里订阅!

关于作者

我的名字是 Dimitris Poulopoulos ,我是一名为 Arrikto 工作的机器学习工程师。我曾为欧洲委员会、欧盟统计局、国际货币基金组织、欧洲央行、经合组织和宜家等主要客户设计和实施过人工智能和软件解决方案。

如果你有兴趣阅读更多关于机器学习、深度学习、数据科学和数据运算的帖子,请在 Twitter 上关注我的 MediumLinkedIn@james2pl 。此外,请访问我的网站上的资源页面,这里有很多好书和顶级课程,开始构建您自己的数据科学课程吧!

通过 API 对接、部署和调用我的 SDR 电子邮件检测器模型

原文:https://towardsdatascience.com/dockerize-deploy-and-call-my-sdr-email-detector-model-via-api-68e238b7ecff?source=collection_archive---------66-----------------------

这是我之旅的第二部分,建立一个系统,最大限度地减少我每天处理的销售邮件数量。概括地说,该系统通过 OAuth 连接到用户的 Gmail,确定收到的电子邮件是否来自销售开发代表(from_SDR=1),并将这些电子邮件移动到一个特殊的文件夹中“稍后阅读”如果电子邮件不是from_SDR,那么它会将分类邮件留在主收件箱中。

使用自然语言处理的 SDR 电子邮件检测器

我的最后一篇帖子中,我从收件箱中取出带标签的电子邮件,训练一个机器学习模型来分类电子邮件是否来自 SDR,并评估该模型的性能。在这里,我描述了如何将我的模型部署到 API 端点,这样我就可以从 Gmail 小程序中调用它。

有很多方法可以让你的模型进入云端。我从 AWS 找到了这个例子,自带 Sci-kit 模型,它是最简单的,解释得最好的,也最适用于我的项目。下面的步骤展示了我如何将我的模型容器化,将容器推入 Sagemaker 服务器,然后使用 Chalice 管理该服务器的 API 端点。

设置我的 Docker 容器

Docker 提供了一种将代码打包成映像的方法,该映像可以作为一个自包含的环境在服务器上运行。 Dockerfile 指定应该如何创建图像。在这种情况下,我制作了一个 Docker 映像,它可以运行 Python 3.7.7 来匹配我的本地环境,并导入必要的包来执行我在第一部分中描述的培训脚本。

如果您正在关注这个 AWS 示例,请注意这些使其与 Python 3 一起工作所需的重要更新:(I)我在第 3 行升级到了 Python 3.7.7,这(ii)改变了第 17 行中的包的位置。

我从 AWS 示例中复制了容器目录,它提供了打包 Amazon SageMager 算法所必需的文件。例如,该目录包含用于构建和使用docker push将容器映像推到 AWS ECR 的 shell 代码。请注意,我修改了示例代码以与 AWS CLI v2 配合使用(参见第 45–50 行):

但是在我构建和推送 AWS ECR 之前,我必须在容器目录中准备执行训练和预测步骤的文件。

将我的训练脚本添加到容器中

我用我自己的训练脚本替换了示例容器中的train文件(参见本系列的第一部分了解详细信息):

请注意从preprocess.py引入的两个模块,它们将数据转换成我的机器学习模型可以接受的格式。这些类和函数包含在同一个文件夹中:

最后,我修改了示例容器中的predictor.py文件,如下所示:

我的更改主要反映在第 64–78 行,在那里我更新了 AWS 示例以使用最新版本的 StringIO,并在data数据帧上包含标题以匹配我的模型的预期输入。

编辑完这些文件后,我运行了构建和推送脚本:

$ sh build_and_push.sh sg_linearsvm

它创建了 Docker 容器并将其推送到 AWS ECR。

部署算法之前在本地主机上测试它

在部署模型之前,确定容器化的代码是否正常工作是很有用的。 AWS 示例为此提供了一个子目录local_test。我克隆了那个 repo,并将我的样本训练数据添加到适当的文件夹/local_test/test_dir/input/data/training中,然后运行:

$ ./train_local.sh sg_linearsvm

该 shell 脚本以train模式运行 docker 映像:

image=$1
mkdir -p test_dir/model
mkdir -p test_dir/output
rm test_dir/model/*
rm test_dir/output/*
docker run -v $(pwd)/test_dir:/opt/ml --rm ${image} train

使用我的容器的local_test版本,我能够诊断和解决与将我的脚本从 Google Colab 移植到 Docker 容器相关的各种问题。一旦这些问题得到解决,我还必须测试serve的功能。所以我跑了:

./serve_local.sh sg_linearsvm

这是一个执行以下代码的 shell 脚本:

image=$1
docker run -v $(pwd)/test_dir:/opt/ml -p 8080:8080 --rm ${image} serve

一旦 Docker 服务器运行本地映像,我就能够从我的终端命令行得到一个预测:

./predict.sh payload.csv text/csv

其中payload.csv是一个模拟模型预期输入的 CSV 文件:

以下是响应,显示该容器的行为符合预期:

接下来,我需要将我的容器放入 SageMaker 服务器,这样我就可以在 web 上训练和托管我的模型。

将我的容器部署到 Amazon SageMaker

首先,我设置了环境,指定了 S3 bucket 和 SageMaker 角色。我还创建了sess来记住连接参数,我用它来执行各种 SageMaker 操作。

接下来,我指定了模型应该在 S3 的哪里找到我的训练数据(第 1-3 行),并使用适当的帐户、地区和容器名称(第 5-11 行)标识了image

为了适应我的算法,我创建了一个 SageMaker 估计器,它定义了如何使用容器进行训练(下面的第 1–4 行)。然后我使用estimator上的.fit来训练我上传到data_location的数据(下面第 6 行)。

将模型部署到 SageMaker 主机需要对 fitted 模型进行部署调用(上面的第 9 行)。该调用接受实例计数、实例类型以及可选的序列化程序和反序列化程序函数。

有了这个,我就有了一个训练有素的模型来获得实时预测。在下一节中,我将描述如何公开一个 web 可访问的 API 端点。

通过 API 访问模型

对于这个项目,我选择了 AWS Chalice 来使用 Amazon API Gateway 和 AWS Lambda 创建和部署应用程序。开箱即用,它提供:

用于创建、部署和管理应用程序的命令行工具
熟悉且易于使用的 API,用于在 python 代码中声明视图
自动生成 IAM 策略

从命令行,我运行:

$ chalice new-project sg_to_api

然后,我导航到那个文件夹并编辑了app.py文件,它定义了视图和结果逻辑。我是这样配置我的 API 的:

我获取一个传入的请求并解码它(第 24–25 行)。然后,我遍历数据来构建一个字典(第 27–36 行),将它输入到 Pandas 数据帧(第 38–39 行),这样我就可以将文本重新格式化为一个漂亮的 CSV 有效负载(第 40 行)。接下来,在第 46–51 行,我调用了sagemaker.invoke_endpoint(),引用了本文前面部分中的端点名称。最后,结果被存储并作为 HTML 响应传递(第 53–92 行),这样我就可以在 web 浏览器上演示了。

为了部署这个应用程序,我导航到sg_to_api目录并运行chalice deploy:

$ chalice deploy
...
Initiating first time deployment...
https://xyz123.execute-api.us-east-1.amazonaws.com/api/

就是这样。我使用 API Gateway 和 Lambda 启动并运行了一个 API。

(我喜欢更新app.py文件,然后通过再次运行chalice deploy快速重新部署 API 变更。)

在野外测试我的 API 端点

虽然我可以使用curl来运行我的 API,但我渴望向一些不习惯使用命令行的非技术朋友展示这一点。对于他们,我使用 S3 托管了一个静态网页,它接受文本输入并向我的端点发出 POST 请求,并从app.py输出 HTML 响应。

首先,我创建了一个 S3 桶:

$ aws s3api create-bucket --bucket sg-learner-test-1 --region us-east-1

然后我配置我的桶支持静态网站托管:

$ aws s3 website s3://sg-learner-test-1/ --index-document index.html --error-document error.html

最后,我创建了一个index.html文件,并将其复制到我的具有全局访问权限的 S3 存储桶中:

$ aws s3 cp index.html s3://sg-learner-test-1/index.html --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers

为了这个例子,我没有花任何时间美化网页——请忍受它的丑陋:

输入代码后,我翻遍收件箱,将邮件粘贴到网页的“邮件正文”部分。如果我从来没有给发件人发过邮件,那么我把“冷联系”字段设为 1,否则,我输入 0。

看到结果感觉像魔术一样!虽然我很乐意在这里提供端点,以便您可以自己测试模型,但是托管 SageMaker 端点每小时的费用是 0.28 美元(每月大约 201 美元),这对于您想使用它的可能性来说有点高😉

相反,我为你记录了几个例子:

3 通过网络可访问的 SDR 电子邮件检测器进行演示检测

(你在想为什么上面的动画里会有一个火腿?简单: ham 是一种标记“非垃圾邮件”的更快捷的方式

未来方向

我冒险的下一步是跳过网页界面,从另一个应用程序调用我的 API 端点。很快会有更多的报道!

让这个帖子成为可能,要感谢的人太多了。这里有几个人极大地指导了我的旅程: Quinn Lanners (关于在 AWS 上部署 Scikit-Learn 模型);Leon Gerritsen(关于用 Chalice 创建 REST API);Patrick Michel Berger(关于部署无服务器 ML 微服务);David ArpinTom Faulhaber 等(关于构建您的

用可视化调试器 Dockerize Jupyter

原文:https://towardsdatascience.com/dockerize-jupyter-with-official-visual-debugger-enabled-cbce1840b7f?source=collection_archive---------49-----------------------

在 docker 容器中启用和使用 Jupyter 可视化调试的分步指南。

尼兰塔·伊兰加穆瓦在 Unsplash 上拍摄的照片

Jupyter 最*宣布了期待已久的可视化调试器的首次公开发布。虽然这是第一个版本,但它支持调试和检查变量等所需的所有基本调试要求。

数据科学界非常依赖 Jupyter 笔记本电脑,因为它能够以互动的方式轻松交流和分享成果。

然而,唯一担心的是缺少可视化调试能力,因此人们通常不得不转向其他可用的经典 ide,它们提供了更好的调试和代码重构能力。这个特性是数据科学界期待已久的,现在终于发布了。

有关可视化调试器如何运行的简要概述,请参考下面的截屏:

杰瑞米Github 上截屏

在本文中,我们将介绍在现有的 JupyterLab 环境中设置可视化调试器所需的步骤,还将介绍默认情况下启用了可视化调试器的 JupyterLab 环境。

先决条件:

JupyterLab 2.0+
基本了解任何编程语言的调试
基本了解 Docker。

安装:

假设您已经在使用 JupterLab,那么您只需要安装 JupyterLab 调试器扩展来进行前端调试,并在后端安装任何支持 Jupyter 调试协议的内核。

安装 JupyterLab 扩展以启用前端调试:

JupyterLab 使用 nodejs 来安装扩展,所以为了安装前端调试器扩展,我们也需要安装 nodejs。

在未来的版本中,Jupyter 可能会默认包含这个扩展。

conda install -c conda-forge nodejs
jupyter labextension install @jupyterlab/debugger

安装内核 xeus-python:

在后端截至目前,只有 xeus-python 支持 Jupyter 调试协议。将来,可能会有许多其他内核支持这个协议。

conda install xeus-python -c conda-forge

现在,如果您运行 Jupyter 实验室,您应该能够看到另外两个图标,分别位于 xeus-python 内核的控制台和笔记本部分。

为什么要集装箱化?

容器使得跨多个环境的开发更加顺畅。这就是为什么它们是应用交付的云原生方法的技术基础。

Docker 的创建者 Solomon Hykes 说,当支持的软件环境不一致时,问题就出现了。“您将使用 Python 2.7 进行测试,然后它将在生产中运行于 Python 3 上,奇怪的事情将会发生。或者,您将依赖于某个 SSL 库版本的行为,然后会安装另一个。你将在 Debian 上运行你的测试,在 Red Hat 上生产,各种奇怪的事情都会发生。”

Container 通过将运行应用程序所需的环境、依赖项、二进制文件、所有必要的配置和应用程序本身打包到一个包中来解决这个问题。这样,我们不再需要担心操作系统和其他特定于环境的依赖性,因为一切都打包在一个独立的实体中,可以在任何地方运行。

启用可视调试器的 Dockerize Jupyter

我假设您熟悉基本的 Docker 命令和术语。解释 docker 如何工作超出了本文的范围。但是,如果您觉得需要重新查看,请参考 Docker 文档

现在,我们将创建所需环境的 Docker 映像所需的 Docker 文件。您可以将图像看作是一个文件,其中包含了在容器中运行我们的应用程序所需的所有内容。

我们将使用 Miniconda,它是 Anaconda 的一个最小的轻量级安装程序。它是 Anaconda 的一个小型引导版本,只包含 conda、Python、它们所依赖的包以及少量其他有用的包。

FROM continuumio/miniconda3

定义 Docker 文件和工作目录的元数据:

LABEL maintainer=”Manish Tiwari <m***[@gmail.com](mailto:mtiwari5@gmail.com)>”
LABEL version=”0.1"
LABEL description=”Debugging Jupyter Notebook”WORKDIR /jup

安装 JupyterLab

RUN conda install -c conda-forge jupyterlab

为前端调试安装 nodejs 和 labextension

RUN conda install -c conda-forge nodejs
RUN jupyter labextension install [@jupyterlab/debugger](http://twitter.com/jupyterlab/debugger)

安装支持 Jupyter 调试协议的内核

RUN conda install xeus-python -c conda-forge

注意:这里我们使用了 conda 软件包管理器,您也可以使用 pip,但是,不建议同时使用两者,因为这可能会破坏环境。

最后,公开端口并定义入口点

EXPOSE 8888
ENTRYPOINT [“jupyter”, “lab”,” — ip=0.0.0.0",” — allow-root”]

我们的最终文档应该如下所示:

启用可视化调试器的 Dockerize JupyterLab

从以上 Docker 文件构建 Docker 映像。

导航到包含上述 docker 文件的文件夹,并运行以下命令。

docker build -t visualdebugger .

或者,您也可以从任何提供 Dockerfile 文件绝对路径的地方运行该命令。

成功构建映像后,通过以下命令列出 docker 映像进行验证

docker image ls

输出应该如下所示:

现在,在一个新的容器中运行 docker 映像,如下所示:

docker container run -p 8888:8888 visualdebugger-jupyter

这里,我们将主机端口(冒号前的第一个端口)8888 映射到容器 8888 中的公开端口。这是主机与容器的端口通信所必需的,Jupiter 在容器中监听该端口。

运行上述命令后,您应该会看到如下输出(假设端口没有被其他进程使用):

这意味着我们的 docker 容器已经启动并正在运行。现在,您可以打开上面输出中指定的 URL,使用 Jupyter 和可视化调试器,甚至不会意识到它没有在主机上运行。

您还可以通过以下命令查看可用容器的列表:

docker container ls

上面的命令应该列出容器以及容器的元数据,如下所示:

一旦打开上面输出中指定的 URL,您应该看到 JupyterLab 在主机的 localhost 和端口 8888 上运行。

容器中运行可视化调试器的 JupyterLab

现在来玩一下可视化调试器,用启动器中显示的 xpython 而不是 python 打开笔记本或控制台。

我已经发布了上面我们刚刚在 docker hub 上构建的 docker 映像,以防你想要一个启用了可视化调试的随时可用的 Jupiter 环境。

你可以通过下面的命令来拖动 docker 图像,并使用它。

docker pull beingmanish/visualdebugger-jupyter

如果你想更深入地了解 Jupyter 的可视化调试架构,你可以参考这里的。

建议或问题?请写在评论里。

参考资料: Jupyter 博客
Jupyter @ Github

无 Dockerless 笔记本:期待已久的数据科学未来

原文:https://towardsdatascience.com/dockerless-notebook-the-long-awaited-future-of-data-science-7cde7707f7ff?source=collection_archive---------16-----------------------

无坞站笔记本是未来

数据科学很难。数据科学家花费数小时想出如何在他们的笔记本电脑上安装 Python 包。数据科学家阅读了许多页的谷歌搜索结果,以连接到那个数据库。数据科学家为工程师编写详细的文档,以便将机器学习模型部署到生产中。数据科学家准备了精美的幻灯片来说服业务人员如何提高留存率。数据科学家担心他们的数据管道中断会导致数据质量问题。

数据科学的挑战是真实的。他们不熟悉的新语言有陡峭的学习曲线。没有人知道如何在有限的时间内满足业务影响需求。有最佳的工程实践可以遵循,以确保他们的交付物的质量。对数据科学团队的工程支持有限。

docker 容器解决了哪些问题?

对于个体数据科学家和其他数据团队成员来说:建立开发环境和维护一致的操作环境是一种令人沮丧的经历。安装说明通常不会涵盖所有必需的依赖项。一些基于 GPU 的人工智能库要求数据科学家熟悉硬件的底层细节。错误信息的信息量不足以解释错误的原因。库之间的依赖冲突使得很难为多个项目维护一个工作的开发环境。数据科学家和工程师之间的合作需要双方进行额外的和不必要的工作。

照片由史蒂夫·哈拉马Unsplash 拍摄

Python 虚拟环境怎么样?

不可否认,Python 虚拟环境对一些数据科学家来说工作得很好。但是,它不能满足数据科学任务的多样化要求:

  1. 数据科学家每天使用 Spark、R 和 SQL 变得越来越普遍。Python 虚拟环境如何适用于 Python 之外的不同语言和框架?
  2. 一些数据科学家主要与他们的工程队友合作,将机器学习模型部署到生产中。如果存在对操作系统而不是 python 库的依赖,Python 虚拟环境如何?

conda的诞生缓解了这两个问题,事实上 conda 在数据科学界非常受欢迎。conda 本身的安装并不困难,它为环境提供了许多常见的数据科学包。

然而,并非所有在pip可用的包都在conda可用。如果在conda上找不到一个包,那么数据科学家可能不得不与conda一起使用 pip,这是混乱和意外问题的主要来源。例如,在这个未解决的 Github 问题中,有许多关于pip如何与conda一起工作的争论。

具有讽刺意味的是,Anaconda 的副总裁曾经做过一个题为“Conda、Docker 和 Kubernetes:数据科学的云原生未来”的演讲。如果 99%的环境相关问题都解决了,那就没用了。剩下的 1%的问题让开发者的体验无法接受。

docker 容器有什么帮助?

不严格地说,docker 容器是一个“轻量级虚拟机”,它将运行应用程序所需的一切打包到一个 docker 映像中。Docker 映像旨在在服务器之间移动,并保证环境的一致性。

因此,当将机器学习模型部署到生产中时,数据科学家将不再担心依赖性的破坏。上周入职的新毕业生可以在 docker 容器运行后立即开始为团队做出贡献,而不是偷偷在拥有更好基础设施的公司寻找新职位,成立数据科学团队。

为什么 docker 容器在数据科学社区中不受欢迎?

Docker 根本不是什么新技术,为什么大多数数据科学家都没有采用?主要有两个原因:

  1. 学习曲线很陡。
  2. 开发者体验不好。

要开始使用 docker 容器,至少要学习如何

  1. 启动/停止集装箱
  2. 将外壳连接到正在运行的容器
  3. 将本地卷装入容器

在现实中,这些还不够:如何在一个不知道密码的容器里?为什么我的 docker 容器在停止后会丢失所有数据?我如何设置一个私有的 docker 注册中心,以便从我的远程集群中提取 docker 映像?如何终止正在使用端口 8808 的进程?

当谈到编写Dockerfile时,人们必须熟悉 Linux Shell 命令和Dockerfile语法。如果一个项目要使用一个 docker 映像,那么一个软件工程师可能要管理太多的 docker 映像。

因此,数据科学家要么很难解决与环境相关的问题,放弃可再现性并遭受糟糕的工程实践,要么花太多时间学习和操作 docker。

保护环境不是数据科学家的工作

数据科学家应该而不是在环境上花费时间,以便他们可以专注于他们擅长的事情:构建仪表盘、开发机器学习模型、向业务团队成员提供可操作的见解。

无坞站笔记本是未来

想象一下,有一个聪明能干的 docker 助手为你做所有的事情:当你启动笔记本时,它可以自动启动容器并将其附加到笔记本上。当您想要将笔记本移动到远程集群上运行时,它可以提交您的本地 docker 容器,将其发送到远程本地集群,并自动管理它。

Dockerless notebook 的想法是,它允许你不用考虑 docker 容器就能开发和操作笔记本。它与科学家日常使用的笔记本数据紧密集成。它消除了学习 docker 容器和操作任务,例如启动/停止容器、将外壳附加到容器以及将卷安装到容器。你甚至不会注意到 docker 正在你的笔记本上运行,就像你不会注意到 Jupyter 笔记本如何在浏览器和内存之间交换数据一样。

无 Dockerless notebook ”将帮助数据科学社区向“可再现的数据科学”和“无摩擦的数据科学”迈进,而不会产生不可接受的成本。

使用 Microsoft Custom Vision 进行文档分类

原文:https://towardsdatascience.com/document-classification-with-custom-vision-handwriting-typed-text-and-signatures-d1f75dee21d3?source=collection_archive---------17-----------------------

使用微软的自定义视觉服务根据手写、键入的文本和签名进行分类

介绍

从实体文件向数字文件转变的一个巨大优势是现在可以使用快速有效的搜索和知识提取方法。具有自动实体和知识提取的 NLP 驱动的应用程序现在可以很容易地从文档中提取特定的短语,甚至是一般的概念。虽然文件本身的类型可能有所不同——合同、表格、发票等。即使在每一类文档中,这些特征也常常包含很大程度的可变性。

要提取的文本的特征在多个维度上有所不同。该实验集中于基于手写、键入文本和签名的存在的分类

具有挑战性的是:

  1. 当将传统的搜索和知识提取方法容易地应用于这些文档时,实现可接受的提取准确性。
  2. 创建一个健壮的模型,以推广到所有文档

因此,导出结构化见解、帮助文档搜索和从文档的非结构化源提取知识的文档智能管道通常依赖于由多层分类和提取模型组成的集成方法,以基于适当的信号将文档路由到正确的模型。

本文只关注分类层,并展示了如何使用 Azure Custom Vision 服务基于手写、键入的文本和签名进行文档分类。

为什么要手写、打字和签名?

分类和提取中的主要挑战是较差的文档图像质量和手写部分/注释。当以预期的格式呈现正确的数据时,所有基于现代 AI/ML 的模型都表现良好。模型如何处理异常值、意外数据点,并能够对大量输入文档进行归纳,这成为一个显著因素。

图像质量差的原因在于,这些文档通常是已签署协议的扫描副本,以 pdf 格式存储,通常与原件相差一两代。这将导致许多光学字符识别(OCR)错误,从而引入伪像和错误的单词。

对于手写文本,易读性、风格和方向变化很大;并且手写可以出现在机器打印的合同页上的任何位置。手写注释也用于修改或定义关键部分/项目,例如,合同中的协议条款。手写指针和下划线通常还会指出手写内容应该合并到文档的其余打印文本中的位置。

微软定制视觉

*年来,使用深度神经网络的计算机视觉对象检测模型已被证明在许多不同的对象识别任务中是有效的,但需要大量专业标记的训练数据。幸运的是,转移学习使模型能够使用预先训练的数据集,如 COCO 用有限的数据创建强大的定制检测器。

有大量的预训练模型和 API 来构建对象检测模型;许多解决方案遵循裁剪感兴趣的特定区域的方法,但是这通常依赖于文档模板/格式/部分/布局等。这个实验的焦点是能够创建与文档类型无关的模型。我应该注意到,虽然我通常支持构建定制模型,因为它提供了控制,但我选择了 Custom Vision ,因为它使用起来非常简单。

Custom Vision 服务采用 Azure 提供的预建图像识别模型,并通过提供一组用于更新的图像来定制它以满足用户的需求。所有的模型训练和预测都在云中完成,模型是预先训练好的,因此用户不需要非常大的数据集或很长的训练时间来获得良好的预测(理想情况下)。微软也有更全面的 C 计算机视觉认知服务,它允许用户使用 VOTT 标记工具来训练你自己的定制神经网络,但是定制视觉服务对于这项任务来说要简单得多。

自定义视觉由训练 API 和预测 API 组成。这个实验使用用于训练和预测 API 的 webapp 用户界面来从已训练的模型中检索结果。您可以在此阅读更多关于定制视觉服务的详细工作内容。

webapp 允许我们一步就将整批图像(页面)标记到手写类。其他类也可以这样做。

实验

我们的训练集总共包含 126 幅图像。按照微软的文档,图像最少的标签和图像最多的标签之间保持 1:2 的比例。

每类训练集中的图像数(页数)

您可能会注意到这里没有为带有签名的手写文本页面创建一个类。这是因为区分签名和常规笔迹需要更多的数据强调特征,如章节信息、位置信息等。此外,还值得考虑的是,定制视觉预训练的通用对象检测模型本身是否可以被调整到将签名(也基本上是手写文本)与文档页面的图像内的常规手写文本区分开的程度。

结果

快速测试功能有助于检查少量样本测试文档的预测,以评估模型性能。如前所述,我们训练过的模型应该能够概括任何文档类型。训练集仅由表单中的页面组成,但应该仍然能够预测任何文档类型的类别。

使用经过训练的模型进行快速测试,可以正确地对只有键入文本的页面的随机图像进行分类

用另一页手写文本进行快速测试也能正确分类

一旦发布了定型模型,就可以使用预测 API 以编程方式检索结果。这里需要注意的是,这是您的模型的第一次迭代,随着您继续完善您的训练方法,您应该会看到准确性的提高。

webapp 仪表板还显示模型准确性的指标

结论

利用自定义视觉服务实现基于手写、键入文本和签名的分类层对我们的文档智能渠道非常有用,帮助我们节省了培训和构建自定义实施的时间。该服务的另一个好处是可以轻松集成 Azure Cognitive Services 的更大功能套件。如果需要,带标签的文档也可以适当地发送到手写 OCR 工具的替代 API 模型。该实验的下一步将集中在如何改进模型性能和解决区分签名和笔迹的问题上。

参考

  1. https://en.wikipedia.org/wiki/Object_detection
  2. https://en.wikipedia.org/wiki/Transfer_learning
  3. http://cocodataset.org/#home
  4. https://docs . Microsoft . com/en-us/azure/cognitive-services/computer-vision/home
  5. https://github.com/microsoft/VoTT
  6. https://www.customvision.ai/
  7. https://docs . Microsoft . com/en-us/azure/cognitive-services/custom-vision-service/getting-started-improving-your-classifier
  8. https://dev blogs . Microsoft . com/CSE/2018/05/07/扫描文档中的手写检测和识别-使用-azure-ml-package-computer-vision-azure-cognitive-services-ocr/

文档扫描仪和私人数据共享

原文:https://towardsdatascience.com/document-scanner-and-private-data-sharing-2fb82b3f0fbb?source=collection_archive---------53-----------------------

如何给文档拍照,使用变换矩阵和变换视角并私信

照片由 Depositphotos

摘要

问题:我们想用手机给一份文件拍照,然后私下发给收件人。通过这篇文章,我们试图解决现实生活中可能出现的问题:

  • 给文档拍照可能会很麻烦——并不是所有的文档都读得很好,有一堆不需要的数据;
  • 图片可以通过第三方(如托管、图像共享服务等)获取。).我们希望一切都是私人的;
  • 我们希望有一种快速的方式在浏览器中显示图像,直接从密文转换而来。

这是现实生活中的问题吗?拍一张影像,“修复”视角并不是什么新鲜事,但却是现实妻子身上出现频率非常高的东西。这是一件常见的事情——有人问:“请扫描这份合同,并在今天发给我”或“请扫描这份声明,并在一个小时内发给我”,但如果我们没有扫描仪,我们怎么办?当然——用我们的手机拍个照,发个乱七八糟的图。然后我们得到回应——“嘿,你有扫描仪吗?我不想照片上有你的鞋子”等等。

我们将如何解决这个问题——当然是用数学。我们将使用一些步骤来抛出这个过程。我们将使用检测角度、改变视角和加密库来隐藏重要信息并方便地传输。

我们将使用什么库 —我们将使用和组合各种类型的库:

  • numpy —作为 Python 数值运算中的标准
  • OpenCV—Python 中的图像处理;
  • blurhash-python —获取图像的占位符。它对文档不是很有用,但也许我们会想在功能上扩展这个私人共享图像服务。如果我们这样做,占位符将非常非常重要。读者只能看到最初的预览,但如果没有密码,就没有办法看到整个画面。
  • imutils —一系列方便的功能,使基本的图像处理功能,如*移、旋转、调整大小、骨架化、显示 Matplotlib 图像、排序轮廓、检测边缘等,在 OpenCV 中变得更加简单。
  • py AES—AES(FIPS-197)分组密码算法和常见操作模式(CBC、CFB、CTR、ECB、OFB)的纯 Python 实现,不依赖于标准 Python 库。有关 API 参考和详细信息,请参见 README.md。
  • pbkdf2—RSA PKCS # 5v 2.0 中规定的基于密码的密钥派生函数 pbk df 2

我们将使用什么加密算法来保护数据?

  • base64 —用于将图像转换为文本,并以相反的方式进行转换。它对于向浏览器发送图片很有用;
  • blurhash —用于生成图像的占位符;
  • AES —用于文本(base64)加密;

数学视角的改变

为什么在这篇文章中改变视角如此重要?在当前的文章中,我们将看看视角的实际变化。但是更深入地了解这个概念和数学基础对于理解整个图景是至关重要的。

在这里你可以找到一篇文章,它对透视变换背后的数学进行了深入的概述:https://www.math.utah.edu/~treiberg/Perspect/Perspect.htm那些发生在艺术和计算机图形学中的数学思想。

阿尔贝提的问题

这个问题促进了一门新学科——射影几何的发展,其代表人物是吉拉德·笛沙格(1591-1661)。

点的*行变换

描述三维空间中的点如何映射到绘图*面的透视变换可以使用初等几何来简单地解释。我们从建立坐标开始。投影涉及两个坐标系。待画物体坐标系中的一点由 X=(x,y,z) 给出,在成像系统中(在绘图*面上)对应的是 P=(u,v) 。如果我们使用标准的右手系统,那么 xy 对应宽度和深度, z 对应高度。在绘图*面上,我们让为水*变量, v 为垂直变量。

将对象投影到绘图*面

我们可以使用欧几里德度量以通常的方式测量成对点之间的距离。

如果

以此类推,然后:

如果物体中的所有*行线组都映射到图上的*行线,则从 X 到 P 的投影称为*行投影。这种映射由仿射变换给出,其形式为

其中 T 是*面中的固定向量,而 A 是 3×2 常数矩阵。*行投影还具有保持比值的特性。也就是说,如果 X (1,2,3,4) 是物体中的共线点,那么在*行投影下保持距离比

当然,分母被假定为非零。

全过程

步骤 0。要求

当你不知道所需的库和版本时,启动 Python 脚本总是一件痛苦的事情。我就是这样创建一个 requirements.txt 文件(链接):

requirements.txt

第一步。阅读图像

在这个阶段,我们需要进行导入,我们将在本文中进一步使用它们。请不要忘记让所有的导入按预期工作。此外,我们还定义了一些函数,这些函数在将来会很有用。这些是 OpenCV 的基本操作,可以重复多次,在函数中使用它们是很好的做法(如 read_imageshow_image_opencvsave_image_opencv 等)。我们还创建了一个函数 get_current_dir ,如果我们不知道当前目录,或者我们想要包含来自不同位置的图像,这个函数可以帮助我们。

请记住,对于nix 系统(比如 Mac),show_image_opencv 不能很好地工作。可以“冻结”在 destroyAllWindows() 的部分;*

我们读取我们的输入文件,名为bulsatcom.png,它和课程项目文件放在同一个目录下。然后我们可以创建一个变量来保存输入文件+一个副本。

原始文件:

bulsatcom.png

这一步的预期结果:我们现在有了保存图像的 OpenCV 对象。我们在 input_image.png 中也有一份图像的副本

第二步。识别边缘

每个图像都有一些噪声,我们在这一步的目标是进行清理。其中一种方法是将彩色图像转换成灰色图像。之后,我们应用一个模糊函数,用(3,3)滤波器模糊图像。模糊减少了任何高频噪声,使轮廓检测更容易。

这里我们只有一个函数 detect_edges,它接受输入图像并返回一个带有边缘的实例。

也许这里最有趣的部分是精明的边缘检测。Canny 边缘检测是一种流行的边缘检测算法。它是由约翰·f·坎尼在 1986 年开发的。这是一个多阶段算法,简而言之,步骤如下:

  • 降噪;
  • 找到图像的强度梯度;
  • 非最大抑制;
  • 滞后阈值处理。

所以我们最终得到的是图像中的强边缘。第一个参数是图像实例(已经是灰色和模糊的),第二个和第三个参数分别是我们的 minVal 和 maxVal。

这一步的预期结果:我们这里只有一个函数,但却是非常重要的一个。我们应用过滤器对图像中的噪声进行一些清理。

edged_image.jpg

其他方法,文章&边缘检测方法:

第三步。检测图像中的文档边缘

最有趣的部分之一是找到图像中的轮廓。找出面积最高的等高线也是一个挑战(但非常重要)。在这一点上,我们将排除文件中的一些大字母或图像。我们只需要最大的部分,也就是整个文档。

我们创建了一个函数calculate _ draw _ contours,其中我们使用了一些内置的 OpenCV 函数,比如 findContours。该函数返回

这一步的预期结果:我们有了图像的轮廓。

contoured_image.jpg

第四步。识别和提取文档边界/边缘

这是本文中最难的时刻之一。我们有文档中所有角的坐标,排列它们并知道哪个坐标对应于一个角是至关重要的。
图像由像素组成。当我们有一张灰色的图片时,我们没有颜色的深度,这也是一个维度。所以我们可以在两个维度上处理这些图片——宽度和高度。

第五步。应用透视变换

当我们有了维度,我们就可以构建目的点。我们可以使用 OpenCV 中的 getPerspectiveTransform 函数,它从四对对应点计算透视变换。之后,我们可以使用 warpPerspective,它对图像应用透视变换。

这一步的预期结果:一个几乎扫描的图像,哪一个视角更好显示。

scanned_image.jpg

第六步。用 base64 编码图像

但是 Base64 是什么呢?

Base64 是一种将 8 位二进制数据编码成可以用 7 位表示的格式的方式。只使用字符 a-z、A-Z、0–9、+和/来表示数据,用=来填充数据。例如,使用这种编码,三个 8 位字节被转换成四个 7 位字节。

术语 Base64 取自多用途互联网邮件扩展(MIME) 标准,该标准广泛用于 HTTP 和 XML,最初是为编码电子邮件附件以便传输而开发的。

我们为什么使用 Base64?

Base64 对于二进制数据表示非常重要,因为它允许二进制数据以看起来和行为上都像纯文本的方式来表示,这使得在数据库中存储、通过电子邮件发送或以基于文本的格式(如 XML)使用二进制数据更加可靠。Base64 主要用于以 ASCII 字符串格式表示数据。

为什么我们不到处使用 Base64?

base64 能为我们做一些重要的事情是好的,但我们必须记住,我们不应该在每个地方都使用 Base64,尤其是在 web 开发中。在这里你可以找到一篇关于这个的有趣文章。

第七步。也获取图像的 blurhash 值

BlurHash 是图像占位符的紧凑表示。我发现它在项目中很有用,在项目中,我希望节省带宽并在图像实际加载之前显示一个占位符。此外,它非常适合本文,因为我们可以计算图片的 BlurHash 值并将其存储在 DB 中。之后,我们可以在用户的浏览器中显示“预览”,用户不允许查看完整的图片/文档。
它可以用来做一些事情,比如一张图像的秘密变体,上面有一些数据,但不足以读取或识别模式。

照片由 BlurHash 拍摄

更多相关链接信息

第八步。用 AES 加密

下面的例子将说明一个简单的基于密码的 AES 加密(PBKDF2 + AES-CTR),没有消息认证(未经认证的加密)。我发现这对于本文很有用,因为我们希望对图像进行 base64 编码,并使其“受密码保护”,如果有人拥有服务器,或者以某种方式阅读我们的消息,他就不能看到内容。

此类操作的有用链接:https://crypto book . nakov . com/symmetric-key-ciphers/AES-encrypt-decrypt-examples

第九步。发送密文并在浏览器中可视化

这一步是可选的,我们不打算深入这个主题。这个想法是,当我们在浏览器中显示加密的 image + blurhash(简短预览)时,拥有密码的用户可以加密密文并看到 base64 字符串。他也可以把它转换成图像。创建一个 JavaScript 库非常容易,它接受 BlurHash 值+密文,并在成功输入密码后可视化 base64 图像(原生为 HTML 格式)。

可用于此类操作(AES 在浏览器中解密)的示例库可在此处找到:【https://github.com/ricmoo/aes-js

摘要

简而言之,我们想在这篇文章中表达什么?

  • 用我们的手机拍一张图像;
  • 修复透视图以获得几乎扫描的文档;
  • 用 base64 编码;
  • 获取 blurhash 值;
  • 用 AES 加密;
  • 发送密文;
  • 显示 blurhash 预览;
  • 在有可用库的浏览器中解码。

它将解决一些私人文件/图片共享+修复一个文件的图片透视的问题。我们使用各种技术来获得这一点,这种方法可以很容易地成为一个 API,我试图在最大的部分像函数一样,可以转换为端点。

类似的文章/研究

这篇文章中我们还有哪些内容?

  • 用加密方法扩展私人文件共享的想法;
  • 对函数、步骤和数学概念的描述性解释;
  • 一些函数的测试,如果在计算中出现问题,这些测试会对我们有所帮助。

一些函数的快速测试

链接

具有片段嵌入的文档搜索

原文:https://towardsdatascience.com/document-search-with-fragment-embeddings-7e1d73eb0104?source=collection_archive---------18-----------------------

新冠肺炎问题—改进句子片段搜索的用例

图一。展示了用于回答特定问题(左图)和更广泛问题(右图)的嵌入驱动的片段搜索。用黄色突出显示的文本片段是使用 BERT 嵌入获得的与搜索输入匹配的文档。右图是具有冠状病毒存在的文献证据的动物样本——字体大小是文献中参考计数的定性度量。蝙蝠(一般而言,特别是中国马蹄形蝙蝠)和鸟类被认为是冠状病毒的来源——蝙蝠是α和β冠状病毒的基因来源,鸟类是γ冠状病毒和δ冠状病毒的基因来源。还报道了来自果子狸和穿山甲的冠状病毒(β冠状病毒)的人畜共患传播。以上所有信息都是使用机器学习模型自动获得的,无需人工处理。对于右侧面板中的宽泛问题,通过搜索术语“动物”和在 Word2vec 嵌入的邻域中的聚类结果,创建了一个引导列表。然后使用 BERT 的无监督 NER 对该列表进行生物实体类型筛选,然后使用片段中捕获的文献证据创建动物的最终列表,作为相应文件的摘要。新冠肺炎的动物来源至今未被确认。疾病预防控制中心制作的冠状病毒插图

TL;速度三角形定位法(dead reckoning)

从文档中收获的句子片段的嵌入可以作为该文档的提取概要方面,并且潜在地加速其发现,特别是当用户输入是句子片段时。这些片段嵌入不仅比传统的文本匹配系统产生更好的质量结果,而且还避免了现代分布式表示驱动的搜索方法中固有的问题——创建有效的文档嵌入的挑战,即在文档级别的单个嵌入,其捕获文档的所有方面并允许通过搜索发现它。

句子片段的例子有作为、、冠状病毒的来源、、、穿山甲中的由介词、形容词等连接一个或多个名词短语的短序列。这些在很大程度上被传统搜索系统忽略的突出显示的连接性术语不仅在捕获用户意图中可以发挥关键作用(例如 bats 中的“冠状病毒 ”具有与“bats 不同的搜索意图,作为 冠状病毒或者 bats 中不存在的“冠状病毒”)通过将这些句子片段嵌入到适当的嵌入空间(例如 伯特 ) 中,我们可以使用搜索输入片段作为对该嵌入空间的探测,以发现相关文档。**

使用句子片段改进搜索的需要

对问题“新冠肺炎****的动物来源是什么?”“冠状病毒结合的受体”即使在像最*发布的新冠肺炎数据集 这样的微小数据集上也具有挑战性(大约 500 MB 的语料库大小,大约 13k 个文档,8500 多万个单词,标准化文本中大约有 100 万个独特的单词)。

传统的文档搜索方法对于典型的用例是非常有效的,在这种用例中,通过在搜索中使用一个或多个名词短语可以从几个文档中获得答案。传统的文档搜索方法还满足以下对单词和短语的用户体验约束:

“what we **see** (results) is what we **typed** (searched for)”

例如,当我们搜索单词和短语(连续的单词序列,如 New York,Rio De Janeiro)——时,结果通常包含我们输入的术语或它们的同义词(例如,新冠肺炎搜索产生关于 Sars-COV-2 或新型冠状病毒等的结果。).

然而,随着搜索输入中单词数量的增加,结果的质量往往会下降,特别是在名词短语之间使用连接术语时。这种结果质量的下降是显而易见的,甚至通过这些搜索引擎在结果中突出显示的术语。

例如,在下图中,“bats as a source of corona virus”中的大部分名词被当前的搜索引擎以分布式方式在所显示的文档摘要的句子/段落内和句子/段落间选择性地突出显示,有时甚至不考虑这些单词在输入序列中的顺序。尽管文档相关性排序通常在很大程度上缓解了这种情况,但我们仍然需要检查每个文档的摘要,经常不得不导航到文档中,然后再次返回到主结果集,因为文档不满足我们的搜索意图。

****图二。当前的搜索引擎,包括像谷歌学术这样的文献证据搜索引擎,对于片段搜索不如对于单词和短语搜索有效。

本文中描述的文档搜索方法除了产生更相关的结果之外,还可以减少搜索系统中存在的这种认知超载,特别是在搜索句子片段时。举例来说,我们在现有搜索系统中使用的相同查询可以产生如下所示形式的结果(该界面是一个示意图,纯粹是为了展示搜索方法)。在下面的示意图中值得注意的关键点是,提取的概要面是文档中的实际匹配(括号中的数字是包含片段的文档的数量以及片段与输入搜索片段的余弦距离),与传统搜索系统中显示的建议查询或相关搜索查询相反。这些概要面给出了结果空间的全景,减少了无用的文档导航并加速了对感兴趣的文档的收敛。

****图三。片段搜索示意图。匹配用户输入的片段的摘要有助于减少查找感兴趣的文档的时间

输入片段可以是完整的或部分的句子,其组成或风格没有限制。例如,它们可以是疑问的,而不是上面的肯定询问——我们可以通过搜索“受体冠状病毒结合”来找到冠状病毒结合的蛋白质受体

****图 4。另一个例子片段搜索示意图。输入可以是完整或部分句子的任何单词序列,并且可以是任何性质的(肯定、疑问等)。)

上述搜索系统之间的比较只是为了说明文档发现的基本方法的差异。否则,鉴于语料库规模的数量级差异,这将是一个不公*的比较——我们肯定会在一个小语料库中获得更多相关结果。

嵌入在文献搜索中的作用

鉴于分布式表示相对于传统的纯符号搜索方法的优势,分布式表示已经成为任何形式的搜索的组成部分。现代搜索系统越来越多地利用它们的属性来补充符号搜索方法。如果我们广义地将文档搜索视为文档空间的广度优先和深度优先遍历的组合,那么这两种形式的遍历需要具有特定于这些遍历的特征的嵌入。例如,我们可能会从搜索引起冠状病毒的动物开始,然后深入到蝙蝠,然后再扩大到爬行动物等。

文档方面的分布式表示——无论是单词、短语还是句子片段,都来自 Word2vec 和 BERT 的嵌入空间,具有独特的互补属性,有助于执行广泛和深入的搜索。具体来说,

  • Word2vec 术语的嵌入 ( 术语 指的是单词和短语——例如蝙蝠、灵猫)对于广度优先搜索有效,对结果应用基于实体的聚类。搜索单个单词"蝙蝠"或短语"灵猫"的结果会产生其他动物,如穿山甲、骆驼等。
  • BERT 句子片段嵌入(穿山甲中的冠状病毒】蝙蝠作为冠状病毒的来源】等。)有助于找到片段变体,这些变体很大程度上保留了原始名词,取决于它们在语料库中的存在。例如,“蝙蝠作为冠状病毒的来源”会产生片段变体,如“蝙蝠携带冠状病毒”“源自蝙蝠的冠状病毒”等。
  • 这些嵌入虽然在很大程度上是互补的,但也有重叠的特性——word 2 vec 嵌入可以产生深度优先的结果,而 BERT 嵌入在统计显著性结果的分布尾部产生广度优先的结果。例如,使用 word2vec 嵌入搜索蝙蝠,除了骆驼、穿山甲等其他动物之外,还会产生蝙蝠种类(例如果蝠、蝙蝠、狐蝠、狐蝠)。使用 BERT 对“孔雀中的冠状病毒”进行片段搜索,得到“猫的冠状病毒疾病”、“猎豹中的冠状病毒”,尽管结果主要是鸟类中的冠状病毒。
  • BERT 模型允许搜索输入(术语或片段)在词汇表之外,使任何用户输入候选项都能找到相关文档。

这种方法是如何工作的?

****图 5。片段搜索中涉及的离线和实时流程/流。

从用于用户输入的 word2vec/BERT 嵌入中获得的扩展术语/片段被用于精确匹配已经使用这些术语/片段离线索引的文档。离线时,使用词性标注器和组块器的组合从语料库中获取片段,并使用 word2vec 和 BERT 两种模型为它们创建嵌入。

  • 将用户输入映射到术语和片段嵌入的中间步骤,然后用于查找文档,不仅具有增加搜索的广度和深度的优点,而且避免了创建匹配用户输入的高质量文档嵌入的问题。具体来说,片段扮演了文档索引的双重角色,并且使得单个文档能够具有由嵌入其中的片段表征的可搜索的多个“提取子摘要”。与纯粹使用术语或短语找到这样的文档相比,片段还增加了找到“大海捞针”文档(语料库中包含问题答案的单个文档)的机会。搜索冠状病毒的潜在动物来源是大海捞针的一个明显用例——我们可以在上面的图 3 和图 4 中看到片段与单个文档的匹配(这在下面的注释部分中详细讨论)
  • 将嵌入纯粹用于寻找候选术语/片段的中间步骤,并利用传统的搜索索引方法来寻找匹配那些术语/片段的文档,这使得我们能够大规模地执行文档搜索。
  • 最后,在寻找像这些宽泛问题的答案时,动物的来源是什么?******

当前方法的局限性

如前所述,word2vec 嵌入扩展了单词和短语的搜索范围。它们没有扩大碎片搜索的广度——邻域的直方图经常缺少明显的尾部(下图 8)。这是因为片段由于它们的长度而没有足够的相邻上下文来学习高质量的嵌入。这种不足可以通过扩大训练的窗口大小和通过忽略句子边界来增加周围的上下文来部分解决,但是在实践中这仍然是不够的,因为片段的低出现计数(图 8)

BERT 嵌入在很大程度上仅增加了搜索的深度,特别是对于片段和短语(使用 BERT 嵌入的单词的搜索深度扩展在实践中没有用)。虽然它们在一定程度上增加了广度,例如,查询“猕猴中的冠状病毒”扩展到在重要结果的分布尾部中包括“棕榈果子狸中的冠状病毒”,但广度不如 word2vec 为单词和短语提供的深度。下面的图 6 说明了它的不足之处。实施说明中还有一些片段搜索缺乏广度的例子,以及规避这种限制的方法。

****图 6。说明了基于搜索输入长度使用的嵌入类型(单词序列少于 5-项;≥5 个片段)和搜索的深度/广度。Word2vec 嵌入对于术语(单词/短语)的深度和广度(它们提供的广度大于深度)搜索都是有效的,而 BERT 嵌入对于使用片段的深度搜索更有效。片段的 BERT 邻域也有提供宽度的结果,但不如 Word2vec 多-当输入片段没有许多匹配深度结果时,我们通常会在 BERT 邻域中看到更多宽度(在重要结果的尾部)。例如,“蝙蝠是冠状病毒的来源”中的句子几乎都是关于蝙蝠的。然而,搜索“孔雀中的冠状病毒”将从鸟类中的冠状病毒开始,并有类似“猎豹中的冠状病毒”的广泛结果。实际上,这可能被认为是优点而不是缺点,特别是当用户键入片段来寻找特定答案时。然而,当用户键入用于广泛搜索的片段时,例如“带有冠状病毒的动物”,这是不够的。然而,这样的问题不能仅仅通过一次搜索来解决——它本质上是一个多步骤的过程,如图 1 所示。

最终想法/总结

大约七年前,Word2vec 可能是第一个明确建立分布式表示能力的模型。由这个简单模型输出的嵌入对于其“体系结构”来说基本上具有两个向量阵列,对于下游应用,例如上述的文档搜索方法,仍然具有巨大的价值。

Word2vec ,与BERTembedding 一起,为文档搜索提供了一个解决方案,该解决方案在结果质量和收敛时间方面有可能改进传统方法(这一声明需要量化)。该解决方案避免了在单个向量表示中学习文档的所有重要方面的问题,然后搜索系统可以使用该向量表示来不仅挑选特定的文档,还可以找到与所挑选的文档相似的文档。

通过使用嵌入(无论是单词、短语还是句子片段)来在文档挑选之前扩大/深化搜索,规避是可能的。单词和短语的 Word2vec 嵌入大大增加了文档搜索的广度。句子片段的 BERT 嵌入大大增加了搜索的深度。BERT 嵌入还消除了词汇表之外的情况,以及促进了文档的不同显著方面的可搜索的提取摘要,这加速了向相关文档的收敛。

参考

实施说明

1。这种方法中使用的 NLP 方法/模型是什么?

词性标注器,用于标注句子 (基于可扩展的 CRF,与具有一流 F1 分数的最新模型相比,至少快一个数量级。然而,该模型的召回对于该标记任务是足够的),

chunker 创建短语,

word 2 vec用于单词和短语的嵌入,

伯特 片段嵌入(句子变形金刚)

伯特为 无监督实体标注

2。如何计算文档结果的相关性?

片段的排序基于与输入片段的余弦距离。从匹配每个方面片段的文档集中挑选第一个文档,并以与输入片段顺序相同的顺序列出。文档的排序可以基于一些其他的文档相关性排序。从每个片段匹配集中挑选文档也可以基于一些其他的相关性排序。

3。这种搜索方法会扩展到实时搜索吗?

实时搜索中的计算密集型步骤是嵌入空间中的相似性搜索(Word2vec 或 BERT)。已经存在现有的 开源解决方案 来大规模执行该操作。我们可以做一些优化来减少时间/计算周期,例如,根据输入搜索长度,仅在两个嵌入空间中的一个中进行搜索,因为这些模型的优势/劣势依赖于输入搜索长度。

4。片段不就是一个很长的短语吗?如果是,为什么要换个称呼?

片段本质上是一个长短语。与短语的区别有两个原因

a)片段可以是完整的句子,而不仅仅是部分句子

b)这些模型的强度依赖于我们前面看到的输入长度(见图 6)。BERT 在片段区域表现最佳(≥ 5 个单词)

5。邻域的直方图分布如何寻找术语和片段?

下面针对单词、短语(3 个单词)和片段(8 个单词)的 BERT 和 Word2vec 邻域说明了这两个模型的互补性质。对于 BERT,分布的尾部随着单词长度的增加而增加,与短语或单词相比,片段具有明显的尾部。当术语计数较低时,分布有时可能具有非常厚的尾部,这表明结果不佳。与Bert-as-service嵌入相比,由 句子变形器 创建的嵌入往往具有明显的尾部,尽管两者都使用子词的总和作为汇集(两者也有其他汇集方法),因为句子变形器中的监督训练步骤使用带有蕴涵、中性和矛盾标签的句子对。

Word2vec 社区有一个单词和短语的尾巴。对于长短语,即使具有高出现计数,分布也几乎分解成“病态形式”,拥挤在高端,然后其余的质量集中在低端。长短语的分布形状也各不相同。然而,不管形状如何,邻域结果清楚地显示了质量的下降。

图七。**随着输入字数的增加,BERT 邻域呈现出明显的尾部。当术语计数较低时,分布有时可能具有非常厚的尾部,这表明结果不佳。

图 8。Word2vec 邻域表现出与 BERT 相反的行为。事实上,这种分布呈现出一种“病态的转折”,一部分项集中在高端(一些项的值为 1 ),而其余部分集中在低端。不管片段在语料库中的出现次数是多少,都会发生这种分解,尽管在形状上有一些变化。对碎片的一致观察是邻域质量下降——邻居看起来几乎像噪音。这可能是因为长短语没有足够的上下文来训练。

6。结果对输入片段的变化敏感。这就是我们使用输入变量收敛到相同结果的可能性。

虽然针对同一问题的不同变体检索到的片段集是不同的,但是在检索到的片段集中似乎有很多交集。然而,由于前面讨论的片段宽度的限制,一些问题可能不会产生涉及所有搜索名词的任何片段。例如“作为冠状病毒来源的狐蝠”或“狐蝠中的冠状病毒”可能不会产生任何含有狐蝠或蝙蝠(狐蝠属于蝙蝠家族)的片段。当片段不包含所有名词时,可以考虑的一种方法是找到该词的 Word2vec 邻居,并使用这些词重建查询。

7。这些模型与使用术语、短语和片段的大海捞针相比如何?

Word2vec 嵌入在这种情况下并不直接有用,因为单个出现的术语/短语的向量没有足够的上下文来学习丰富的表示。由于从子词构造单词的本质,BERT 嵌入不会遭受这一缺点——子词有足够的上下文来学习好的表示。然而,Word2vec 仍然可以在搜索中找到一个名词的等价名称,这就像大海捞针一样。例如,如果文档空间只引用了果蝠中的冠状病毒,则在狐蝠中搜索冠状病毒可能不会得到该文档。然而,在果蝠(使用 Word2vec 创建)中搜索冠状病毒片段将在 BERT 的嵌入空间中找到该单个文档。除了存在分布尾部的片段(如果确实存在)使其有资格作为候选者之外,大多数片段中固有的可解释性提供了一个优势,这是单词或短语不一定具有的。

8。关于动物冠状病毒信息提取的更多细节

使用 Word2vec 和实体标记收集了大约 1000 个 (998) 生物实体提及。这些用于收获 195 个提及病毒的片段。显示了 30 个片段的样本

带有动物证据的片段样本是冠状病毒的潜在来源

9。片段搜索需要两种形式的嵌入吗?

我们可以只做一个——伯特嵌入。然而,我们至少需要将它与传统的词汇搜索系统配对,以在它的薄弱领域——单个术语和短语搜索——对其进行补充。

下面的流程显示了这两个系统一起用于发现文档的用例

一个基于 BERT 嵌入和传统词汇搜索的文档搜索系统。使用单个术语在片段空间中专门搜索(tmprss2)有助于规避 BERT 嵌入的不足,以找到具有单个单词和短语的良好余弦*邻。将单个词汇的词汇搜索限制在只有片段的数据空间有助于我们发现可能相关的片段嵌入。另一方面,用长片段搜索更有可能在余弦空间产生结果。如果精确合取匹配的概率随着长度的增加而降低,那么它们不太可能通过词汇搜索产生任何结果。使用meilisearch对片段进行词法搜索

下图显示了使用上述两种流程的文档发现示例。

在使用 BERT 和传统词汇搜索的搜索系统中使用长片段进行文档发现的示例流程示意图—发现的两个步骤

使用单个单词和传统词汇搜索进行文档发现的示例流程示意图。(BERT 空间中的余弦邻居对于单个单词是无用的。(2)然而,将用户输入与片段匹配有助于发现相关片段。挑选相关片段的余弦相邻链接有助于发现更多感兴趣的片段,其中之一(3)可能产生我们正在寻找的文档。

本文由 Quora 手动导入

使用潜在语义索引的文档摘要

原文:https://towardsdatascience.com/document-summarization-using-latent-semantic-indexing-b747ef2d2af6?source=collection_archive---------11-----------------------

文档摘要是从文本中获取文档的要点或摘要的方法。有两种总结方法。抽象概括和摘录概括。

摘录摘要基本上是严格根据你在文本中得到的内容创建一个摘要。这可以比作把一篇文章的要点抄下来,不做任何修改,然后重新安排要点和语法的顺序,使摘要更有意义。

抽象概括技术倾向于模仿从文本中“解释”的过程,而不仅仅是简单地概括它。使用这种技术总结的文本看起来更像人类,并且产生更精简的摘要。这些技术通常比提取摘要技术更难实现。

潜在语义索引或潜在语义分析是抽取摘要方法之一。

UX·印尼在 Unsplash 上拍摄的照片

潜在语义索引

潜在语义索引用于分析一组文档和文档中包含的术语之间的关系。这使用一种称为奇异值分解(SVD)的数学概念来计算给出文档之间相似性的矩阵集。

潜在语义分析使用数学技术奇异值分解(SVD)来识别术语和概念之间的关系模式。这是基于这样一个原则,即出现在相同上下文中的单词往往有相似的意思。

奇异值分解

奇异值分解是降维技术之一。奇异值分解是将矩阵分解成 3 个矩阵。所以如果我们有一个矩阵 A,它用

a 是维数为 mxn 的矩阵。u 是维数为 mxm 的正交矩阵。∑是维数为 mxn 的对角矩阵,V 是维数为 nxn 的正交矩阵。

u 是指左奇异向量,∑是奇异值或特征值,V 是右奇异向量。

“文件:奇异值分解 visualization . SVG”BYcm gleeCC BY-SA 4.0 下授权

(下面的例子摘自大卫·A·格罗斯曼和奥菲尔·弗里德所著的《信息检索、算法和启发式》

考虑以下 3 个文档

d1:在火灾中受损的黄金货物。

d2:用一辆银色卡车运送白银。

d3:一批黄金用卡车运到。

现在我们创建术语文档矩阵

如果我们对这个矩阵进行奇异值分解,我们得到的分量为

考虑将这些文档分为两个主题

U 的列给出了与属于该主题的每个单词相匹配的权重。例如,单词 silver 对第二主题具有更大的权重,而单词 truck 对第一主题具有更大的权重

在矩阵 S 或∑中,第一对角线条目给出第一主题的权重,第二对角线条目给出第二主题的权重

矩阵 VT 的列给出了属于每个主题的文档的权重。像前两个文件属于第二个主题,第三个文件属于第一个主题。

LSI 主要帮助对属于不同主题的文档进行分类。LSI 也用于搜索引擎。由于矩阵 U 给出了单词与每个主题的相关性,并且我们还具有属于每个主题的文档的相关性,因此我们可以估计单词与每个文档的相关性。这样我们就可以得到查询词属于每个文档的权重。

使用潜在语义分析的摘要

LSI 给出了属于不同主题的文档的权重。通过根据权重从每个主题中选择前 N 个文档来完成摘要。

这给出了一个摘要,其中我们从摘要的每个主题中获得权重较高的文档。

应用潜在语义分析进行摘要

我们试图用下面的代码片段来解释这一点

我们需要首先加载所需的包

我们需要从文件中载入数据

接下来,我们将预处理数据。这是为了标记,删除停用词和词干

现在我们为文档创建术语频率。

现在我们创建 LSI 模型。我们使用 Gensim 的 LSIModel 函数

现在我们尝试对文档应用 LSI 模型。我们选择主题的数量为 2

现在我们将文件按重量分类

我们试着选择最上面的文件

我们试着按顺序排列句子编号

现在我们试着总结一下

结论

潜在语义索引是一种抽取摘要技术。因为文档是按照主题的数量排序的,所以我们得到了所有主题的文档摘要。此外,根据语义相似度对文档或句子进行分类。

作者

斯里尼瓦斯·查克拉瓦蒂—Srinivas.yeeda@gmail.com

钱德拉舍卡 B N-chandru4ni@gmail.com

参考文献

https://radimrehurek.com/gensim/

信息检索、算法和启发式

https://github . com/yee das/abstract ive _ Summary _ of _ Transcriptions/blob/master/Summary _ using _ Latent _ Semantic _ analysis . ipynb

证明文件

原文:https://towardsdatascience.com/documentation-511c1fcb8fe?source=collection_archive---------35-----------------------

以正确的方式向正确的人传达正确的信息!

图片由皮克斯拜的 Gerd Altmann 提供

名称又能代表什么呢

这一步可以有多种名称,例如,“讲故事”或“交流”。在本系列的介绍性概述中,我们将这一步比作 CRISP-DM 的“部署”阶段。我们在这里不深入部署机器学习模型,但我们可以在“我们设计并训练了一个模型,并获得了一些结果,这是你需要了解的关于这些结果以及如何处理它们”的上下文中表述这一步骤。它不是逐字重复整个过程的每一个小细节;这就是你的 Jupyter 系列笔记本的用途!正是这些以可重复的方式作为您的过程演化的审计线索。不,在这一点上,如果你是一名汽车设计工程师,你的新车已经被设计,工程,制造,并即将上市。你现在正在写销售手册。“这辆车能在 3 秒内从 0 加速到 60 英里,一加仑油能跑 50 英里,并且有变道辅助技术。这就是变道辅助技术的作用,也是你需要它的原因……”支持汽车性能统计的研究,以及你如何开发新的变道辅助技术,是你之前的数据科学产品的目的。哦,技术开发和实施的技术细节很可能是公司专有的秘密。嘘。

如果没有人看到使用它的意义,如果他们不知道如何使用它,或者它如何能给他们带来好处,那么您的数据科学工作将毫无价值。你的车是为四口之家设计的。展示您的汽车如何让孩子们的假期旅行变得愉快和安全。展示如何启动(好吧,你们所有人——行李箱!)安全地拿着每周购买的食品杂货,尽管有突然的刹车操作,也能保持直立。展示其功能如何为客户解决问题!这是客户想知道的,也是他们会采纳你的解决方案并再次向你寻求更多的原因。

格式

滑梯甲板

您可能会被要求使用多种格式。首先,有幻灯片甲板。幻灯片不应过于冗长。试图将尽可能多的单词压缩到一张幻灯片上并不是一个游戏。你也应该避免方程。不过,这里有一个*衡。当你根据你的幻灯片进行演示时,你不希望它们太罗嗦,否则观众会试图阅读你在屏幕上写的段落而不注意你。另一方面,对于忙碌的高管来说,在开会前提前阅读幻灯片是很常见的。在这种情况下,幻灯片绝对需要在无人陪伴的情况下被目标受众理解,而不是一系列一个词的要点。请记住,这并不是要在页面上获得每一个微妙之处,每一个理由或枝节问题。你到底想让他们知道什么?当考虑购买新车时,琼斯夫妇不太可能在乎你在电子控制单元中调整参数有多聪明;他们会关心舒适的乘坐或改进的燃油经济性。把你的技术骄傲留给你的团队会议吧!

该报告

你也可能被要求写一份报告。这是你以一种绝对独立的方式讲述一个更完整的故事的机会(不需要你站在读者的肩膀上解释事情)。再说一次,这不是展示你的方程式或深厚技术知识的地方。可能的受众是有更多空闲时间的客户和/或业务主管。这里最重要的建议是考虑你的听众。还要考虑报告的预期长度。这些,以及你想要确保你能理解的信息,将引导你达到适当的技术深度。其他的都只是写作风格。而且文笔很重要!一个经典的指南是斯特伦克和怀特。它不是没有批评者,但它绝对不是一个坏的开始。你可以找别人。你的公司很可能有自己的风格指南!你可以,也愿意,发展你自己的声音。

关于这篇文章

这是一个链接系列的第七篇也是最后一篇文章,旨在简单介绍如何开始数据科学过程。这里可以找到介绍,这里可以找到之前的文章

无需编码的文档嵌入和文本分类

原文:https://towardsdatascience.com/documents-embeddings-and-text-classification-without-coding-e274b4e191e9?source=collection_archive---------26-----------------------

什么是文档嵌入,如何在没有一行代码的情况下对文本进行分类?

安妮·斯普拉特在 Unsplash 上的照片

T ext 是由字符序列描述的。由于每个机器学习算法都需要数字,因此我们需要将文本转换为实数向量,然后才能继续进行分析。为此,我们可以使用各种方法。在深度学习进化之前,最知名的方法是单词袋,由于其优点,该方法仍被广泛使用。最*深度学习的蓬勃发展给我们带来了新的方法,如单词和文档嵌入。在这篇文章中,我们解释了什么是文档嵌入,为什么它是有用的,并展示了它在没有编码的分类例子中的用法。为了分析,我们将使用 Orange 开源工具

单词嵌入和文档嵌入

在理解文档嵌入之前,我们需要理解单词嵌入的概念。单词嵌入是单词在多维空间中的表示,使得具有相似含义的单词具有相似的嵌入。这意味着每个单词都被映射到代表该单词的实数向量。嵌入模型大多基于神经网络。

文档嵌入通常分两步从单词嵌入中计算。首先,文档中的每个单词被嵌入单词嵌入,然后聚集单词嵌入。最常见的聚合类型是每个维度的*均值。

为什么以及何时应该使用嵌入器?

与统计文档中每个标记(单词)出现次数的单词袋相比,嵌入有两个主要优势:

  • 他们没有维度问题。词袋的结果是一个表,该表的特征数量等于语料库中所有文档中唯一标记的数量。具有长文本的大型语料库导致大量独特的标记。这会导致巨大的表格,超过计算机内存。巨大的表格也增加了机器学习模型的学习和评估时间。嵌入具有恒定的向量维数,Orange 使用的 fastText 嵌入维数为 300。
  • 大多数预处理是不需要的。在单词袋方法的情况下,我们通过文本预处理来解决维度问题,在文本预处理中,我们移除似乎对分析不太重要的标记(例如单词)。它还会导致删除一些重要的令牌。当使用嵌入器时,我们不需要删除令牌,所以我们不会失去准确性。此外,在快速文本嵌入的情况下,可以省略大多数基本预处理(例如归一化)。
  • 嵌入可以在拥有数十亿标记的大型语料库上进行预训练。这样,它们捕捉到了语言的重要特征,并生成了高质量的嵌入。然后使用预训练的模型来获得较小数据集的嵌入。

嵌入器的缺点是难以理解。例如,当我们使用单词袋时,我们可以很容易地观察到哪些标记对于分类是重要的,因为标记本身就是特征。在文档嵌入的情况下,特征是人类自身无法理解的数字。

柑橘

对于这个故事中的演示,我将使用我最喜欢的数据分析工具——Orange。Orange 是最知名的交互式数据分析、可视化和机器学习工具之一。它是开源的,你可以从它的网站下载。Orange 由画布组成,您可以在画布上放置小部件,并将它们连接在一起以创建工作流。每个小部件代表数据分析中的一个步骤。

示例工作流—在后面的分析中使用并解释了相同的工作流(作者的图片)

文档嵌入小部件

Orange 通过文档嵌入小部件提供文档嵌入器。它使用了 fastText 预训练嵌入器,支持 157 种语言,将每个文档映射到包含 300 个元素的向量中。Orange 的文档嵌入小部件目前支持 31 种最常见的语言。

在小部件中,用户设置文档的语言和聚合方法——这就是如何将文档中每个单词的嵌入聚合成一个文档嵌入(作者图片)

假新闻数据集

在本教程中,我们使用的是假新闻数据集的样本。数据集样本在这里可用。它包含两个数据集:包含 2725 个文本项的训练集和包含 275 个文本项的测试集。每一件物品都是贴有真假标签的物品。

假新闻识别

在这里,我们提出了如何使用文件嵌入的假新闻识别一步一步。首先,我们将使用语料库小部件加载数据集的训练部分。

语料库小工具及其选项(作者图片)

小部件加载包含三列的表格:文本、标题和标签。加载数据集后,我们确保在已用文本特征字段中选择了文本特征。这意味着该特征中的文本用于文本分析(来自该变量的标记将被嵌入),而不使用标题特征。当加载数据集时,我们将语料库小部件连接到文档嵌入器小部件,后者将计算文本嵌入。我们的工作流应该是这样的:

带有加载数据的语料库小部件和嵌入数据的文档嵌入小部件的工作流。下图显示了文档嵌入小部件设置。(作者图片)

在文档嵌入小部件中,我们检查语言是否设置为英语,因为该数据集中的文本是英语。在这个实验中,我们将使用均值(*均)聚合,这是最标准的方法。一分钟后,文档被嵌入—嵌入进度显示在小部件周围的栏中。

当嵌入准备好时,我们可以训练模型。在本教程中,我们训练两个模型—逻辑回归和随机森林。我们将对两个学员使用默认设置。

上图中的工作流扩展了两个额外的小部件,用于训练两个模型,一个是逻辑回归,另一个是随机森林。(作者图片)

当我们的模型被训练时,我们准备测试数据,以查看我们的模型在新数据上的表现。为了加载测试数据,我们使用另一个语料库小部件,并将其连接到文档嵌入器小部件。设置与之前相同。唯一的不同是,这次我们在第二个语料库小部件中加载数据集的测试部分。为了在测试数据集上进行预测并检查预测结果,我们使用了预测小部件。

最终的工作流程。工作流的顶部加载训练数据,嵌入它们,并训练模型。工作流的底部加载测试数据,嵌入它们,并将它们发送到预测小部件,小部件使用模型对它们进行预测。在底部,我们看到预测小部件窗口,我们可以在其中检查来自数据集测试部分的每个数据实例的预测。(图片作者)

在小部件的底部,我们检查准确性。在名为 CA(分类精度)的列中,我们可以看到两个模型的精度都在 80 %左右。在上表中,我们可以找到模型出错的案例。如果我们选择行,我们可以在连接到预测小部件的 Corpus Viewer 小部件中检查它们。我们还将混淆矩阵小部件连接到我们的工作流,它显示了预测类和实际类之间的比例。

左边是随机森林的混淆矩阵,右边是逻辑回归模型的混淆矩阵(作者的图片)

我们可以看到,逻辑回归在真实新闻的情况下稍微更准确,而随机森林模型在预测假新闻方面更好。

在本教程中,我们解释了什么是文档嵌入,并展示了如何在包含真实或虚假新闻的数据集上使用它们的示例。您可以尝试对自己的文档进行类似的分析,也可以使用嵌入来完成其他任务,如聚类、回归或其他类型的分析。

参考

[1] Grave,Edouard 等人,学习 157 种语言的词向量。 arXiv 预印本 arXiv:1802.06893 ,2018。

[2]demar,Janez,等. Orange:Python 中的数据挖掘工具箱.机器学习研究杂志,2013,14.1:2349–2353。

[3]张、尹;金、容;周,志华。理解词袋模型:一个统计框架。国际机器学习与控制论杂志,2010 年,1.1–4:43–52。

[4]维基百科:单词袋模型。在https://en.wikipedia.org/wiki/Bag-of-words_model有售

[5] Joulin,Armand,等. Fasttext .压缩文本分类模型。 arXiv 预印本 arXiv:1612.03651 ,2016。

一个数据科学家需要懂 SQL 吗?

原文:https://towardsdatascience.com/does-a-data-scientist-need-to-know-sql-5494cf599e75?source=collection_archive---------21-----------------------

意见

…还是有其他东西更适合您的数据需求?

照片由贝瑟尼·莱格Unsplash【1】上拍摄。

目录

  1. 介绍
  2. 结构化查询语言
  3. 替代方法
  4. 摘要
  5. 参考

介绍

你可以把 10 个人放在一个房间里,很可能有 5 个数据科学家说他们需要 SQL 来工作,而另一半会回答说还有其他方法来争论他们的数据。那么,作为一名数据科学家,你用什么呢?可以用别的吗?是数据科学家的责任吗?下面,我将讨论 SQL 在数据科学中的作用,以及结构化查询语言的替代品。

结构化查询语言

照片由阿尔瓦罗·雷耶斯Unsplash【2】上拍摄。

您可能最终需要了解 SQL,这取决于您的公司和数据科学团队。一些团队有几名数据工程师和数据分析师,以及机器学习工程师,而一些团队可能只由一名数据科学家组成。如果你作为数据科学家需要了解 SQL,你很可能知道这个问题的答案是。然而,讨论为什么你需要它,为什么你不需要它,以及什么时候你不需要它是有趣和重要的。此外,讨论这个问题也有助于新数据科学家在进入职场时熟悉期望值。下面是我使用 SQL 的原因:**

  • 我需要使用 SQL 查询表以获得有用的数据集
  • 自主的感觉很好(尽管帮助是受感激的)
  • 可以在现有的 SQL 查询中随时发现和创建新功能

虽然数据科学可以被视为一项职业,在这项职业中,您只关注 Python 和 R,以及复杂的机器学习算法,但如果不以某种方式利用 SQL 的优势,可能很难作为一个团队来执行您的数据科学过程。然而,根据您在数据科学中的特定角色,有时您并不完全需要它。

您可以参考替代方法的时候是,如果您从数据工程师或数据分析师以及类似职位的其他人那里获得了一些帮助。此外,您可能会发现自己不需要 SQL,因为 SQL 查询的角色根本不是您专业角色的一部分,因为您更专注于数据科学模型开发,例如在您已经收到的数据上测试各种机器学习算法。

替代方法

Bruce HongUnsplash【3】上的照片。

当您已经通过从数据分析师或数据工程师处获取数据集来查询数据集时,数据集的下一步改进可以是创建新要素,而不仅仅是数据表中的字段。例如,如果您的数据集中有 10 个字段,您可以开发几个新的度量作为字段,而不是通过计算第 1 列和第 2 列来创建新的第 11 列。除了 SQL 本身,在pandas【4】中有一个更简单的地方可以进行这种计算。这个库被数据分析师和数据科学家广泛使用是有原因的。

有了 pandas,你就能快速完成复杂的计算,而且只用一行代码。

有时我发现很难使用 SQL 对我的数据进行计算,因为它在视觉上显示为多行(仅是我的观点)

以下是一些常见的 pandas 数据框架操作,使您的数据集要素工程更加方便。

* groupby* items* loc* iloc* iteritems* keys* iterrows* query (*this operation is quite similar to SQL quering, I highly recommend*)* aggregate* corr* mean, median, min, and max* quantile* rank* sum* std* var* append* merge* join* sort_values* isnull* notna* between_time

正如你所看到的,有大量的操作可以应用到你的熊猫数据帧上。完整的清单在这里【5】。

我最喜欢使用的是:

  • groupby —对数据进行分组时,对这些分组执行进一步的操作
  • 查询 —类似 SQL 的另一种查询方式,但在您的数据框架内

我个人发现计算新的字段或指标更容易,这些字段或指标最终将用于您的熊猫数据科学模型。然而,有些人喜欢只在 SQL 中执行他们的计算(在一个地方管理所有的字段可能更简单)。对我来说,好处是我不必一直追加到一个很长的查询中,这样当我想添加一个新的特性时,就非常简单和有效。

摘要

Unsplash【6】上由米米·蒂安拍摄的照片。

一个数据科学家需要懂 SQL 吗?答案既有也有。这取决于你的公司、团队,有时还取决于你的偏好。您可以从使用 SQL 查询自己中受益,如果您不知道它,您可以学习。如果你喜欢像熊猫这样的替代方法,那么你可能会发现自己在一个更大的数据科学团队中。一些数据科学家同时使用 SQL 和 Python 来为他们各自的模型创建最终的数据集。pandas 最独特的部分是有一个类似 SQL 的查询操作,所以在 pandas 数据框架中可以混合使用这两种方法。

如果你想了解更多的话,这是我的一篇讨论熊猫查询功能的文章

[## 熊猫查询类似 SQL 的查询

使用 pandas 查询函数查询数据帧的数据科学家 python 教程

towardsdatascience.com](/pandas-query-for-sql-like-querying-279dc8cbfe3f)

作为一名数据科学家,请随意在下面评论您更喜欢哪种或哪些方法。我希望你觉得我的文章有趣并且有用。谢谢你的阅读,我很感激!

参考

[1]照片由 Bethany LeggUnsplash(2015)上拍摄

[2]阿尔瓦罗·雷耶斯 Unsplash 上拍摄的照片,(2018)

[3]Bruce Hong 在 Unsplash 上拍摄的照片,(2018)

[4]熊猫发展团队, 熊猫主页 ,(2008–2020 年)

[5]熊猫开发团队,熊猫数据框架运营,(2008–2020)

[6]照片由米米·蒂安Unsplash(2018)上拍摄

[7] M.Przybyla,Pandas Query for SQL-like Query,(2020)

AutoML 会在预测模型中引入偏差吗?

原文:https://towardsdatascience.com/does-automl-introduce-bias-into-predictive-models-phiona-afd1887d3001?source=collection_archive---------42-----------------------

保持人在循环中,以确保数据上下文

来源: @lensinkmitchel,经由 Unsplash

在过去的几年里,以数据为中心的自动化能力发展速度惊人——从机器人过程自动化,到计算机视觉,再到 AutoML。所有这些技术都通过减少人类完成任务所需的人工工作量,显著提高了多个行业的生产率。然而,随着这些技术的改进,人类离这些解决方案想要取代的实际过程越来越远。扩大这种距离有可能侵蚀自动化提供的潜在好处;一台不能推理或感觉的机器会通过在数据中强化歧视性偏见以及增加其产生的无法解释的结果的数量(“黑箱”效应)来产生意想不到的后果。构建保持“人在循环中”的技术以确保这些后果不会变得无处不在,这是非常重要的。

有价值的算法

自动化的当前趋势不仅仅是一个抽象问题,工具将一个更漂亮或更容易使用的界面放在通常是脚本代码的上面。软件总是随着时间的推移而发展,以简化生产软件所需的工作量。开发人员很少再构建自己的编译器了。

但是今天,许多软件工具超越了前端和后端架构的协同作用;应用程序越来越需要从某个地方(单个用户、整个用户群或另一个系统)生成的数据,作为在软件应用程序中交付价值的关键组件。算法的建立是为了理解数以百万计的数据点,并推动个人预测值,以确保信息的消费者发现它是有用的。这些算法构建起来极其复杂,但如果操作正确,在未经训练的人看来就像魔术一样。

难怪如此多的公司希望在未来几年内建立机器学习能力。在没有人为干预的情况下,自动产生针对个人消费者的个性化价值,这种能力有可能改变公司的经营方式。公司通过在正确的时间提出正确的建议而使收入增加两倍的故事,或者医生能够主动接触可能有某些临床风险的患者的故事,似乎是技术的胜利和对未来的展望。人类终于能够使用数学和工具大规模地提前预测行动,而不是一次一个地做出反应。

这些预测之所以可能,是因为我们的应用程序每天每秒都在生成大量数据集。随着更多数据成为算法逻辑的基础,算法通常会变得更具预测性,从我们的信用卡交易历史到我们的医疗记录,再到我们的智能手机点击和滚动,一切都可以用来构建越来越大的数据集来驱动这些模型。

毫无疑问,如果以正确的方式使用,这些算法的复杂性可以为社会创造难以置信的价值。以目前机器学习技术的进步水*,人们可以说,建立这些模型的数据科学家能够(在很大程度上)*衡预测的能力与使用个人数据来推动这些预测的潜在隐私和歧视影响。

歧视性后果

然而,也有很多组织不考虑歧视性偏见的例子。2019 年,高盛因歧视申请信用卡的女性而在陷入困境,无论是在审批过程中还是在她们获得的信用额度方面。几十年来,保险公司一直使用数据来评估风险,最*的研究表明居住在主要是少数民族聚居区的人比居住在白人聚居区的人支付更多的汽车保险,尽管整体风险水*相同。

这两个例子都表明,当歧视被有意或无意地引入数据集时,这种可能性是存在的,数据集表面上是为了对产品或服务提供客观的推荐。这些算法模型的问题是双重的——不仅它们做出歧视性的建议,而且它们也是黑箱的定义——我们人类不一定理解他们为什么首先做出那些有缺陷的建议。

复合效应

顾名思义,算法使用自己掌握的数据来生成答案。“更好”的答案可以通过更广泛的数据(例如:结合智能手机使用数据的交易信息)或更深入的数据(例如:20 年的信用卡支付历史)来产生。当使用脏数据时,会出现“更糟”的答案,也就是人们常说的:垃圾进,垃圾出。让数据达到一定的清洁程度需要大量的工作——一些评估认为清洁任务要花费 80%的时间处理数据。

数据清理工作本质上通常是相当手动的——寻找正确的数据集来使用和组合,梳理行和列来找到要纠正的错误,并编写脚本或 Excel 公式来解决问题。持续做好这项工作需要大量熟练的人工干预,而现实是这并不是一项非常有魅力的工作,尤其是对于从事这项工作的专业人员来说。但既然是 80%的数据工作,总得有人去做。

在这个过程中,歧视性偏见的潜在问题可能会渗透进来——精通数据的分析师可以认识到,为包含性别、种族或收入(或潜在的三者)数据列的预测模型构建数据集,可能会导致算法将种族或性别视为最有可能预测高汽车保险费的因素。构建和清理数据集的人类可以理解,这种方法和结果可能会产生重大的社会问题,因为他们必须生活在这些歧视性建议产生不*等和不公*结果的世界中。

因此,人类数据分析师可以选择省略这些列,从而降低算法主要基于人口统计数据产生歧视性结果的可能性。但是,机器会知道省略这些列吗?

煤矿里的金丝雀

对于机器学习工作所需的复杂程度,市场的反应一直是尽可能将其自动化。尽可能简单!放入一个数据集,我们会自动清理它,并为几十种算法中的一种做好准备,这些算法可能会得到您想要的预测!看起来很不错——能够放入数据并得到 75%可能性的预测。

但是这个过程包含什么呢?这是黑盒效应导致意外结果的典型例子——我们不知道幕后发生了什么。清理流程脚本是否会删除调查数据中被调查者拒绝注明其种族的所有行(空白值可能会扭曲结果)?该脚本删除了合理的高医疗测试结果,因为其余的测试结果普遍低于*均水*吗?如果你不知道这些问题的答案,你能相信你得到的结果吗?如果算法的结果是歧视性的,你说你不知道结果中的所有因素是否足以为其辩护?

这个 AutoML 例子是过度自动化给我们带来的难题。最初,人类是建立数据集和训练算法的人,以至于自动化是足够接*的*似值。但是,当我们试图去除支撑自动化的人为步骤时,我们可能会产生意想不到的后果。虽然许多人认为自动化的危险是一般人工智能创造了下一个终结者或其他一些低可能性场景,但危险可能没有那么夸张,但也没有那么危险:数据工作已经自动化到了一个地步,甚至没有人意识到生成的建议如何包含偏见,因为我们已经变得如此依赖机器为我们思考。

中间立场

机器学习和更不均衡定义的术语人工智能的重点一直是取代人类工作。也许相反,在数据工作的范围内,建立增强而不是取代人的能力的解决方案更好。到目前为止,计算机还没有能力理解某些数据类型的上下文——尽管对某些信息是否是个人身份信息(PII)可能有二元理解,但计算机不识别为什么该信息被认为是 PII。人类必须做出决定。

因此,找出自动化框架中人类可以从他们的判断和理解中增加最大价值的地方可能是有利的,即使工作是由脚本和算法执行的。我们已经做了很多这种“人在回路中”的工作,即使是在机器学习的背景下。人类在回路中可能看起来更像飞机上的自动驾驶仪,而不是自动驾驶汽车,在自动驾驶汽车中,可以明确确定数据工作的某些部分不会引入偏差(例如,删除文本周围的空格),而其他部分可能会引入偏差,这就是人类会介入的地方。

随着我们有越来越好的工具来处理信息,围绕什么是合适的以及技术将如何改进的讨论肯定会发展。与此同时,重要的是不要随意地完全改变这种或那种方式——我们不必手动地对 Excel 中的每个单元格进行更改,或者将我们的工作交给 AutoML。

Phiona 是一个增强的数据管理*台,使非技术用户能够减少数据工作:我们的技术标记了可能需要清理和标准化的领域,节省了手动梳理数据的时间,而不牺牲对数据准备过程的控制。你可以在 https://phiona.com 看到更多。

原载于 2020 年 3 月 25 日【https://phiona.com】

CNN 代表卷积神经网络还是相关神经网络?

原文:https://towardsdatascience.com/does-cnn-represent-convolutional-neural-networks-or-correlational-neural-networks-76c1625c14bd?source=collection_archive---------53-----------------------

试图解开为什么我们在 CNN 中提到使用卷积,而实际上我们使用的是互相关…

图片来源: Pixabay

CNN 或俗称的卷积神经网络(甚至 CovNets)是深度学习中使用的高效深度神经网络的关键成分之一,尤其是在处理非结构化数据时。但是我们在使用 CNN 的时候真的进行卷积运算吗?我知道数据科学和人工智能社区在有效使用 CNN 方面已经获得了很多专业知识,并且有像 Tensorflow,Keras 和 PyTorch 这样的框架,可以非常快速有效地使用 CNN 来构建深度学习模型?但是每当我们讲授 CNN 的概念时,为什么我们提到使用卷积的数学运算,而实际上我们做的是执行互相关!等等,你不相信我说的话?那么就让我们来深入探究一下这篇文章吧!

对于一些正在阅读这篇文章的人来说,我在接下来的部分将要讨论的内容可能会让你大吃一惊!但是最*,我和我的一个朋友进行了一次大讨论,他试图让我相信卷积和相关运算实际上是相同的,这就是为什么我们仍然说 CNN 使用卷积,而不是相关运算,我强烈反对,因此我想表达我的想法和我的观点,CNN 实际上是相关的神经网络!

图片来源:( Pixabay )

卷积与相关滤波

对于我们中的一些人来说,我们可能没有足够的时间重温我们很久以前学过的数学概念,所以我想重放数学术语卷积和相关性之间的区别,以便更好地论证:

相关 vs 卷积

所以基本上当我们在计算机视觉或者图像处理相关的工作中做相关滤波的时候,我们通常会在图像上滑动相关滤波器的中心,然后将相关滤波器中的每个值乘以图像中的像素值,最后将这些乘积求和。那么这一系列的操作你听起来是不是很熟悉呢?什么事?是的,你是对的,这正是我们在对图像等非结构化数据应用 CNN 时所想做的!

相关滤波步骤

我让你困惑了吗?那么让我来解释一下当我们尝试应用卷积滤波时会发生什么。像相关滤波一样,卷积滤波也是一种线性滤波,但是相关和卷积之间有很小的区别。在卷积滤波中,我们在两个维度(从下到上,从右到左)翻转内核或滤波器,然后执行与相关滤波相同的步骤。

在卷积滤波中在两个维度上反转滤波器

产量有什么区别?

你们中的一些人可能会想,好吧,没关系,这可能只是术语上的缺陷,所以这有什么大不了的?你们中的一些人可能会想,如果我们应用实际的卷积运算而不是伪装的相关操作符,会有什么变化呢

为了回答这些问题,让我给你看一些通过卷积和相关运算在图像上使用高斯模糊滤镜的输出。

在左边的基础图像上使用相关性应用高斯模糊滤镜(图片由作者提供)

使用卷积在左边的基础图像上应用高斯模糊滤镜(图片由作者提供)

从上面两幅图像中,我们可以清楚地看到,当我们使用卷积和相关对同一幅图像应用相同的滤波器时,输出有所不同。所以,现在问题来了,对于神经网络学习权重和偏差来说,哪一个是真正有用的?我在这里的答案是相关滤波,因为卷积滤波在某些情况下实际上可能会引入噪声,这可能会导致深度学习模型的误导性结果。

命名法中为什么会有这种谬误?

你可能想知道,即使我们在 CNN 中使用互相关,为什么我们仍然称它为卷积神经网络?是因为卷积听起来更复杂吗?还是 CovNet 看起来比 CorrNet 更时髦?嗯,这些原因可能是真的,但当我做我的研究时,我发现 CNN 的最开始被认为是源于论文 Neocognitron ,已知它使用卷积滤波,但后来的 CNN 和大多数 ML/DL 包的实现都使用相关滤波而不是卷积滤波,但我们仍然继续使用卷积神经网络的名称。虽然数学或算法的复杂性实际上几乎保持不变,但结果却有所不同。

现在,看完这篇文章,你会支持我把 CovNets 重命名为 CorrNets 的观点吗?或者至少支持我,当有人争论说 CovNets 和 CorrNets 实际上是一样的,当有明显的区别时?

你喜欢这篇文章吗?还想多看几篇同一主题的文章?那么请看看这个:卷积 Vs 相关卷积神经网络 Conv (CNN):相关还是卷积?我们的媒体作者同事在强调差异方面做得很好,因此这些文章可能对你真的有帮助。

因此,这就把我们带到了本文的结尾。在 我的个人网站 中,我正在尝试编写一个 深度学习词汇表 ,里面会有更多深度学习中用到的有趣概念的细节,我会在以后挑选一些更有趣的概念。在那之前,请鼓掌并激励我进行更多的讨论,并与社区分享我的发现。希望我能帮上忙!继续关注:**和我的网站:https://www.aditya-bhattacharya.net/

**** 更新*** : 我正在用 python 写一本关于应用计算机视觉的书,正在寻找可以在写作或审查内容和代码方面做出贡献的投稿人。我最感兴趣的是接收研究生,通过写一本书和维护一个开源项目来帮助他们成为应用计算机视觉专家!请看看我的这篇文章了解更多: 链接 。如果你想看看该倡议的早期努力,请看看我在YouTube中关于应用计算机视觉的详细实践研讨会。如果你有兴趣成为其中的一员,请随时通过这里提到的任何交流方式联系我们:https://aditya-bhattacharya.net/contact-me/带着你更新的简历。*

深度学习总是要重新发明轮子吗?

原文:https://towardsdatascience.com/does-deep-learning-always-have-to-reinvent-the-wheel-2c526018c5c5?source=collection_archive---------39-----------------------

机器学习,特别是深度学习,彻底改变了我们今天所知道的世界。我们已经看到了语音和图像识别方面的巨大进步,随后是深度学习在许多其他领域的应用。在其中的许多领域,深度学习现在是最先进的,甚至正在超越它。一个明显的趋势是网络变得越来越复杂,计算要求越来越高。

今天,我们正在构建越来越多的网络,这些网络建立在前几代网络拓扑之上。由于神经网络固有地与其他神经网络兼容,我们能够将它们结合并适应新的目的。如果你的目标是解决一个新问题,没有明确的准则来定义一个合适的网络拓扑。最常见的方法是看看其他人试图解决类似问题的工作,或者自己设计一个全新的拓扑。这种新设计通常受到经典方法的启发,但它取决于网络和训练数据来学习正确的权重,以便它们收敛到似乎合理的解决方案。因此,它们甚至是从零开始学习众所周知的函数的网络,例如傅立叶变换。由于离散傅立叶变换是一种矩阵乘法,因此它通常被建模为完全连接的层。使用这种方法,很明显有两个缺点是无法避免的:首先,全连接层引入了许多自由参数,这些参数可以模拟完全不同的功能。第二,用这种方法永远达不到快速傅立叶变换的计算效率。

已知操作员学习的可视化

如果我们已经知道解决一个特定的问题需要一个特定的函数,我们就会想到这样一个问题:把它作为一种先验知识包含到我们的网络结构中是否会有好处。已知操作员学习的方法在一个新的理论框架中研究了这个过程。虽然这个想法看起来简单而直观,但是理论分析也确定了明显的优点:首先,将已知操作引入神经网络总是导致较低或相等的最大训练误差界限。第二,减少了模型中自由参数的数量,从而也减少了所需训练数据的大小。另一个有趣的观察结果是,任何允许计算相对于输入的梯度的操作都可以嵌入到神经网络中。事实上,如我们从例如最大汇集操作中所知,即使是次梯度也已经足够了。

有趣的是,这段理论是 2019 年才发表的。它是为将物理先验知识嵌入神经网络的理论分析而开发的。然而,这些观察也很好地解释了为什么我们看到卷积神经网络和池层的巨大成功。与生物学类似,我们可以认为卷积和汇集运算是感知的先验知识。最*的工作甚至走得更远:有一些方法甚至将复杂的滤波器功能,如血管性滤波器导向滤波器纳入神经网络。

Frangi-Net 是血管性过滤器的可微分版本。在我们的代码海洋实验环境中测试代码。

理论分析还表明,前几层的建模误差会被后几层放大。这个观察结果也符合特征提取在经典机器学习和模式分析中的重要性。在深度学习中进行的特征提取和分类的组合,允许我们同步这两个过程,从而减少训练后的预期误差。

由于精确学习允许结合经典理论方法和深度学习,我们现在能够将这些想法更进一步:最*的一篇出版物提出从底层物理方程中推导出特定问题的整个神经网络拓扑。这种方法的美妙之处在于,拓扑的许多操作符和构建块都是众所周知的,并且可以有效地实现。然而,它们仍然是计算效率非常低的操作。然而,我们从类似问题的其他解决方案中知道,特定的矩阵求逆或其他不太容易处理的运算可以用其他函数来表示。在这个例子中,昂贵的矩阵逆矩阵被循环矩阵代替,即卷积层,它是所提出的网络的唯一可学习部分。在他们的实验中,他们证明了所提出的架构确实解决了以前只能*似解决的问题。虽然他们只在模拟数据上进行训练,但在真实数据上的应用也是成功的。因此,包含先验知识也有助于构建针对特定问题的通用网络架构。

该动画示出了用于投影重排的已知操作者网络的拟合,该投影重排仅在合成数据上训练并应用于来自真实扫描仪的拟人幻像数据。代码可在我们的代码海洋实验环境中获得。

我们认为这些新方法对深度学习社区很有意思,深度学习社区今天已经远远超出了仅仅对感知任务进行建模。对我们来说,看到传统方法与今天在深度学习中所做的一切内在兼容是令人兴奋的。因此,我们相信在不久的将来,在机器和深度学习领域会有更多新的发展,跟踪这些发展将是令人兴奋的。

如果你认为这些观察是有趣和令人兴奋的,我们建议阅读我们的深度学习温和介绍作为这篇文章的后续,我们的免费深度学习资源我的 YouTube 频道

本文的文本和图像根据知识共享许可 4.0 署名进行许可。因此,请随意重用和共享这项工作的任何部分。这篇文章最初发表在 MarkTechPost.com。

身高真的很重要吗?

原文:https://towardsdatascience.com/does-height-really-matter-c3db062e8333?source=collection_archive---------16-----------------------

埃里克·麦克林在 Unsplash 上的照片

身高对排球成功影响的数据驱动研究

介绍

我是职业排球运动员。

不完全是。但是当被问到“如果你能做任何事,你会以什么为生?”,我的回答几乎都是,“打排球。”这是我最喜欢的运动,但不幸的是,我对它感兴趣太晚了,以至于没有任何好处。最*,看旧的 NCAA 比赛的视频让我思考:我能不能打 NCAA 排球?我够高吗?

排球显然是一项高度重要的运动——高个子球员有更高的触及范围,可以更容易更快地越过网,并且有更多的击球选择。我身高 6 英尺 1 英寸,我想知道我的身高是否足以胜任我在 NCAA 级别的外线击球手的位置。自然,我第一个去回答这个问题的地方是谷歌。

图片来自谷歌

图片来自 NCSA 体育

经过一番挖掘,这些是我能找到的最具体的数字——我并不满意。6 尺 1 到 6 尺 10.5?这是一个很大的范围,这些范围都不能告诉我在 NCAA 我将如何实际上与外部击球手相比。看起来我必须自己找到答案。

数据收集

首先,我从 NCAA 目录中获取了所有 D1 和 D3 NCAA 男子排球队网站的列表。这些链接只指向学院的一般体育网站,所以我必须将这些链接转换为每个学院男子排球队的特定链接。我用 Selenium 从所有 156 支球队的花名册上刮出了每个球员的名字、位置和身高。我认为一年的数据不够全面,所以我收集了 2010-2011 赛季的球员名单数据。

这个过程并非没有痛苦。花名册的布局改变了,球队将不再拥有在线花名册,链接风格改变了,位置名称和高度格式也变了,还有其他困难。在我不愿意承认的长时间之后,我终于收集并清理了所有的数据,产生了下面的数据框架。

作者使用熊猫的图片

15000 多条记录之后,我终于准备好回答我的问题了。我够高可以在 NCAA 打排球吗?

探索性分析

堆积起来

我想直入问题的核心,所以我创建了一个表格,按位置和部门显示球员的*均身高。

作者使用熊猫的图片

对于外侧击球手,D1 高度是 6 英尺 3.7 英寸,D3 高度是 6 英尺 1.5 英寸。我不符合标准。为了挽回我的自尊,我看了一段时间内一名外线击球手的身高分布,看看我的身高是否够得上比赛。

图片由作者使用 Seaborn

虽然随着时间的推移,身高会有所变化,但看起来我总是比*均水*低一点。D1 和 D3 高地在 2010 年和 2013 年之间的显著背离让我吃惊;我认为 D1 的球队和球员一直都要高得多,但早期的情况并非如此。

总而言之,事情看起来不太妙。我甚至不够高,不能为 D3 球队效力,我可以忘记 D1 排球。然而,这些结论是基于一个基本假设:身高在排球比赛中很重要。但是真的吗?我想自己找出答案。

身高的重要性

衡量一个排球队成功的主要方法是他们赢了多少。他们的胜率是多少?与他们所在部门的其他队伍相比,他们的排名如何?我从 NCAA 统计搜集数据,找出每个赛季每个球队的胜败,以及他们的分区排名。在汇总了我每个赛季每支球队*均身高的原始数据后,我加入了球队获胜的数据。

作者使用熊猫的图片

我制作了散点图,看看球队的*均身高和他们的胜率或排名百分比之间是否有任何明显的关系。等级百分位数用于说明跨部门/年度的不同团队数量,标准化 0 到 1 之间的值。在 50 分中排名 1 的团队的排名百分位数将是 0.02;一个 50 分中排名 30 的团队的百分位数为 0.6。

图片由作者使用 Seaborn

虽然看起来这两个部门之间没有很强的关系,但是 D1 和 D3 之间 R2 值的差异是令人惊讶的。D3 的值比 D1 的百分位值大三倍多,比胜率大四倍多。这种差异揭示了一个有趣的观点,表明对于 D3 团队来说,身高是一个团队成功的更大决定因素,而不是 D1 团队。

直觉上,这是有道理的。正如我后来对各个赛区高个子球员的分析所支持的那样,D1 球队在获得非常高的球员方面没有任何困难,所以身高并不能强烈反映他们的获胜能力。另一方面,D3 球队发现获得同样的 6 英尺 5–6 英尺 10 的巨人要困难得多,所以这些高大球员的存在(导致球队整体高大)可以使球队比其他球队更有优势。

然而,这些数字和视觉结合了所有季节。虽然我们知道随着时间的推移,*均位置或球队身高没有一致的模式,但身高仍然会发生变化,在一个赛季内比较球队是有意义的,因为他们的胜率和排名百分点与其他球队在那个赛季的表现直接相关-2012-2013 年斯坦福红雀队不受 2019-2020 年加州大学洛杉矶分校布鲁因斯分校的身高或胜率的影响。

我绘制了等级百分比和胜率随时间变化的 R2 和相关值,结果很有趣。

图片由作者使用 Seaborn

图片由作者使用 Seaborn

对于相关性,D1 和 D3 的两个成功指标的值非常相似。这表明 D1 和 D3 的身高和成功之间的线性关系的强度是相似的。有趣的是,在这两个部分中,相关系数都低于 0。

R2 讲述了一个不同的故事。这两个指标遵循一个非常相似的趋势:D1 R2 值到处都是,没有真正的模式,而 D3 R2 值从 2010 年到 2014 年有明显的上升趋势,然后下降,然后变*。我们无法从 R2 值中推断出因果关系,但 R2 值随着时间推移的趋势似乎符合我们之前的直觉:身高并不能很好地反映 D1 队的获胜能力,所以线性模型不能很好地解释因变量,R2 值到处都是基于球队最终的表现。

另一方面,D3 球队从 2010 年到 2014 年可以看到非常高的球员的突出程度上升,随着高个子球队获得更多优势,身高成为他们获胜能力的更好预测因素,R2 增加。2014 年后的下降和随后的持*可以解释为非常高的球员的新鲜感逐渐消失,使球队在身高上的优势减少。

虽然这种说法是推测性的,但它在一定程度上得到数据的支持。如果我们随着时间的推移观察每个分区中非常高(6 英尺 5 英寸以上)的球员的数量,两种情况下都明显有增加的趋势(尽管 D3 在 2011-2012 年有异常,这一年特别高,不太符合模式)。

图片由作者使用 Seaborn

尽管总体上 D3 球员的数量更多,但是 D1 的高个子球员的数量比 D3 多得多,这表明 D1 队比 D3 队更容易甚至更容易接触到这些球员。这解释了 D3 的 R2 模式对 D1 的非模式。

团队级分析

我想看的最后一件事是,随着时间的推移,身高在团队层面上是否重要——如果一支球队变高了,它是否会提高胜率和排名百分位数?我添加了球队在身高、胜率和排名百分比方面的变化的列。如果身高和成功一起移动(身高上升和成功上升,身高下降和成功下降),身高的变化乘以胜率或排名百分位数的变化会得到一个正数,如果身高和成功反向移动,则会得到一个负数。如果随着时间的推移,身高对于一个特定团队的成功非常重要,那么身高和成功在大多数时候应该是同步的。我还研究了身高变化和成功变化之间的 R *方值。

作者使用熊猫的图片

如你所见,差别相对来说很小。即使我们只看*均高度超过一英寸的变化,在同一方向上移动的最高比例是 D1 队胜率的 60%。我们在不同级别的变化中看到类似的数字,尽管有趣的是,D1 在 1 英寸以上的变化中具有更高的同向移动比例,并且比任何其他组合中的 R *方值都高得多。

所有比例都超过 50%的事实进一步表明,身高意味着一些东西,只是不太多。

结论

我们发现身高绝对是排球队成功的一个因素,而且对于 D3 球队来说,身高比 D1 球队重要得多。尽管身高对一个团队的成功有一定影响,但它显然不是成功的唯一决定因素;我们观察的大多数成功的衡量标准与身高的相关性只比随机的好一点点。虽然身高在排球中很重要,但练习和技术更重要,还有一点天赋。

所以,最后回答这个问题,我可以打 NCAA 排球吗?大概不会。但是我现在发现,这不是因为我的身高。这是因为缺乏必要的训练和练习年数,而这是在这样一个竞争激烈的水*上进行一项运动所必需的。

Imagenet 预处理对胸部放射摄影图像有效吗(新冠肺炎)?

原文:https://towardsdatascience.com/does-imagenet-pretraining-work-for-chest-radiography-images-covid-19-2e2d9f5f0875?source=collection_archive---------33-----------------------

动物、胸部 x 线摄影和新冠肺炎

我们被包围了。未知敌人的围攻。一个让我们困惑的敌人。除非你在过去的几个月里生活在岩石下(像杰瑞德·莱托一样),你知道我在说什么——新冠肺炎。无论你打开新闻,还是浏览社交媒体,你现在获取的大部分信息都是关于 SARS-COV2 病毒或新型冠状病毒的。

疾控中心拍摄

但是在所有的负面情绪中,有一丝光亮闪耀着。当面对共同的敌人时,人类跨越国界团结起来(在很大程度上;总是有害群之马)互相帮助度过当前的难关。科学家是当今的英雄,他们加倍努力寻找治疗方法、疫苗和其他一百万种有助于对抗新冠肺炎的东西。除了真正的英雄之外,数据科学家也被号召以任何可能的方式提供帮助。许多人尽最大努力预测疾病的发展,以便政府能够更好地计划。更多的人花时间分析来自各种来源的数据,准备仪表板或网络图等。帮助理解疾病的发展。还有一批人试图将人工智能技术应用于识别病人的风险,或用 X 射线帮助诊断疾病等。

在关注这些发展的同时,很多人做了一些尝试的一个特定领域是基于胸部 x 线摄影的新冠肺炎病例识别。其中一个早期的尝试得到了很多关注、志愿者和资金等。伴随着对该研究定位的大量批评(你可以在这里阅读更多信息)。TLDR;澳大利亚的一名博士候选人使用了一个预训练模型(Resnet50),对 50 幅图像进行了训练,由于训练验证泄漏而打乱了代码,并声称对新冠肺炎病例识别的准确率为 97%。有些人甚至获得了 100%的准确率(结果它是在获得 100%准确率的同一数据集上训练的)。

伴随着这种噪音,加拿大滑铁卢大学的 Linda Wang 和 Alexander Wong 发表了 arxiv 预印本,标题为 COVID-Net:一种定制的深度卷积神经网络设计,用于从胸部放射摄影图像中检测新冠肺炎病例。在论文中,他们提出了一种新的 CNN 架构,该架构是在 5941 个后前胸部放射摄影图像的数据集上从头开始训练的。为了生成数据集,他们结合了两个公开可用的数据集——COVID 胸部 x 光数据集,和 Kaggle 胸部 x 光图像(肺炎)数据集。在论文中,他们将这个数据集分为四类——新冠肺炎、病毒、细菌和正常。下面的条形图显示了训练和测试分割的类别分布。这是一个规模相当大的数据集,尽管 COVID 的情况较低。他们报告了该模型 100%的召回率和 80%的准确率。

这是 COVIDx 上第一个相当大的数据集,它引起了我的兴趣。由于他们在 Github Repo 中共享了经过训练的模型和代码来进行评估,这是进行分析的最佳时机。

放弃

我觉得我需要在这里声明一个免责声明。接下来的一切都是纯粹的学术活动,并不意味着这是对新冠肺炎的一种可验证的有效的测试方式。重要的事情先来。我个人并不赞同试图用这些模型来识别新冠肺炎。我对医学知之甚少,对看 x 光片更是一窍不通。除非这已经被医学专业人士验证和审查,否则这比在竞争数据集上训练的模型好不了多少。

关于数据集也有一些问题。

  1. 新冠肺炎案例和其他案例来自不同的数据来源,模型是否识别代表新冠肺炎的数据来源或实际视觉指标令人怀疑。我试图查看 GradCAM 的结果,但我在阅读 x 光片方面是一个绝对的零,我不知道模型是否在查看正确的指标。
  2. 同样不清楚的是,病人在拍 x 光片时处于什么阶段。如果是在他的疾病中服用得太晚了,这种方法就站不住脚了。

为什么不转学?

当我看到模型和数据集时,我的第一个想法是——为什么不转移学习呢?数据集很小,尤其是我们感兴趣的类。从零开始训练一个模型,并试图恰当地捕捉不同类的复杂表示,尤其是新冠肺炎类,对我来说有点吃力。

但是唱反调,为什么一个接受过动物和食物(ImageNet 中最受欢迎的课程)培训的 CNN 会在 x 光方面做得更好?对自然和彩色图像进行训练的网络,可能已经学会了处理单色 X 射线所需的完全不同的特征表示。

作为一个理性的人和科学过程的坚定信徒,我决定查阅现有的相关文献。令人惊讶的是,研究界在这个问题上存在分歧。让我说清楚。对于预训练或迁移学习是否适用于医学图像,没有争议。但是争论的焦点是在 Imagenet 上进行预训练是否有任何好处。有论文声称 Imagenet 预处理有助于医学图像的分类和分割。也有报纸推动权重的随机初始化。

Veronika Cheplygina 最*发表的一篇论文[1]从 Imagenet 预处理是否有益于医学图像的角度对文献进行了综述。结论是——“视情况而定”。Google Brain 最*的另一篇论文(被 NeurIPS 2019 接受)[2]深入探讨了这个问题。尽管总的结论是使用 Imagenet 权重的迁移学习对医学成像没有好处,但他们确实指出了一些其他有趣的行为:

  • 当样本量很小时,如医学成像中的大多数情况,迁移学习,即使它是基于 Imagenet 的,也是有益的
  • 当他们观察不同模型的收敛速度时,预先训练的模型收敛得更快
  • 最有趣的结果是,他们尝试用随机权重初始化网络,但根据预训练的权重导出随机初始化的均值和标准差,并发现它也提供了预训练模型所具有的收敛速度。

底线是,该研究并没有显示 Imagenet 训练模型的性能更差,而且收敛速度更快。即使大的 Imagenet 模型对于这个问题来说可能是过度参数化的,但是如果你想让一个模型尽可能快地工作,它确实提供了一些好处。

实验

既然我已经完成了文献综述,是时候验证我的假设了。我收集了数据集,写了一个训练脚本,并测试了几个预训练的模型。

我用过 FastAI 库(PyTorch 的一个包装器),它非常容易使用,特别是如果你正在用它简单的“冻结”和“解冻”功能进行迁移学习。大部分实验要么在我装有 GTX 1650 的笔记本电脑上进行,要么在谷歌的 Colab 上进行。除了 torchvision 之外,我还使用了 Cadene 的神奇库预训练模型作为我的预训练模型的来源。

数据扩充

由于我们的训练数据集相对较小,并且因为它有两个不同的 X 射线源,我使用了一些转换作为数据扩充。它既增加了数据集样本,又为模型提供了更好的泛化能力。所使用的转换是:

培训程序

以下是我用来训练这些模型的基本步骤。完整代码发布在 GitHub 上。

  1. 导入模型并从 fastai 创建一个学习者。fastai 有一些内置的机制来切割和分割预训练的模型,这样我们就可以使用一个定制的头部,并轻松应用判别学习速率。对于 torchvision 中的模型,切割和分割在 fastai 中预定义。但是对于从 torchvision 外部加载的模型,我们也需要定义它们。“cut”告诉 fastai 在 CNN 的特征提取器部分和分类器部分之间进行分离,以便它可以用自定义头来替换它。“拆分”告诉 fastai 如何拆分 CNN 上的不同区块,使每个区块可以有不同的学习率。
  2. 使用分层的 ShuffleSplit 将训练分成训练和验证
  3. 将损失作为标准交叉熵
  4. 冻结 CNN 的特征提取器部分,训练模型。我用的是 Leslie Smith[3]提出的单周期学习率调度器。这是杰瑞米·霍华德在他的 fastai 课程中大力提倡的,并在 fastai 图书馆中实现。
  5. 在学习饱和后,解冻模型的其余部分并微调模型。是否使用单周期调度程序以及是否使用差分学习率,是通过查看损失曲线根据经验决定的。

训练中使用的技巧

混合

mix up【4】是一种数据扩充形式,我们通过对两个现有示例进行加权线性插值来生成新示例。

λ介于 0 和 1 之间。实际上,它是从以α为参数的贝塔分布中取样的。通常,α在 0.1 到 0.4 之间,此时混合的影响不会太大而导致欠拟合。

渐进调整大小

对于 DenseNet 121,我也尝试了渐进式调整大小,只是为了看看它是否能给我带来更好的结果。渐进式调整大小是指我们开始用小尺寸图像训练网络,然后使用从小尺寸图像学习的权重,并开始在大尺寸图像上训练,并分阶段转移到更高分辨率的图像尺寸。我分三个阶段试过——64×64,128×128,224×224。

结果呢

事不宜迟,我们来看看结果。

Densenet 121

最佳 DenseNet 模型是通过逐步调整 64×64 -> 128×128 的大小并在训练期间使用 mixup 得到的。

例外

使用 mixup 训练最佳异常模型,并在使用冻结权重进行初始预训练后进行微调。

ResneXt 101 32x4d

最好的 ResNeXt 模型是在没有 mixup(没有尝试)和没有 finetuning(由于某种原因,finetuning 给了我更差的性能)的情况下训练的。

让我们将这些结果汇总在一个表格中,并将它们与 COVID-Net 论文中的结果放在一起。

我们可以马上看到,所有的模型都比 COVID-Net 具有更好的准确性。但是准确性并不是这里评估的正确标准。F1 得分最高的 e Xception 车型似乎是所有车型中表现最好的车型。但是,如果我们分开来看精度和召回,我们可以看到 COVID-Net 具有高召回率,特别是对于新冠肺炎的情况,而我们的模型具有高精度。Densenet 121 具有完美的召回率,但是精确度很差。但是 Xception 模型的精度很高,召回率也不算太差。

组装

我们已经看到 DenseNet 是一个高召回模型,而 Xception 是一个高精度模型。如果我们对这两个模型的预测进行*均,性能会更好吗?

和以前没多大区别。我们的合奏仍然没有更好的回忆。让我们尝试一个加权系综,给在新冠肺炎有着完美回忆的 Densenet 更多的权重。为了确定最佳权重,我使用了验证集中的预测,并尝试了不同的权重。

让我们将这些集合也添加到前面的表中进行比较。

最后,我们有一个模型,它在精确度和召回率之间取得了*衡,并且在所有指标上都超过了 COVID-Net 分数。让我们来看看系综的混淆矩阵。

模型复杂性和推理时间

当我们在考虑模型的可用性时,我们还应该记住模型的复杂性和推理时间。下表显示了在我的机器(GTX 1650)上作为模型复杂性和推理时间的代理的参数数量。

注意——无法在我的笔记本电脑上运行 COVID-Net 上的推理(它与 Tensorflow 的关系很糟糕),因此不知道模型的推理时间。但是从参数数量来看,应该比其他型号多。

注意:集合的参数数量和推断时间被视为成分的总和。

模型分析

GRAD CAM

早在 2015 年,周、等人[5]就引入了类别激活图,作为理解 CNN 在打包预测时在看什么的一种方式。这是一种理解 CNN 在进行预测时关注的图像区域的技术。他们通过将输出层的权重投射回卷积神经网络部分的输出来实现这一点。

Grad CAM 是 CAM 在许多最终用例中的推广,除了分类,他们通过在卷积层的最后一个输出中使用梯度来实现这一点。这篇论文的作者[6]说:

梯度加权类激活映射(Grad-CAM)使用任何目标概念的梯度(比如“狗”的逻辑或者甚至是标题),流入最终卷积层以产生粗略的定位图,该定位图突出显示图像中用于预测概念的重要区域。

让我们看几个例子,看看我们的预测和它们的激活叠加成一个热图。虽然我不知道网络是否在寻找正确的地方,但如果有人正在阅读这篇文章,知道如何去做,联系我让我知道。

新冠肺炎(新型冠状病毒肺炎)

病毒的

细菌

常态

当神经网络作弊时

特征表示(t-SNE)

我们还可以看看这些网络生成的要素制图表达有多好。由于卷积层的输出是高维的,我们必须使用降维技术来绘制二维图。

一种流行的探索高维数据的方法是 t-SNE,由 van der Maaten 和 Hinton 在 2008 年提出[7]。SNE 霸王龙不像 PCA,它不是;t 线性投影。它使用点之间的局部关系来创建低维映射。这允许它捕捉非线性结构。

让我们来看看 t-SNE 的可视化,三种模型的困惑度为 50——COVID-Net、Xception 和 DenseNet。

我们的 Imagenet 预训练模型(Xception 和 DenseNet)似乎比 COVID-Net 具有更好的特征表示。COVID-Net 的 t-SNE 相当分散,在不同的类之间有很多点缀。但是,Xception 和 DenseNet 要素制图表达显示了不同类之间更好的分离程度。这三个案例中的新冠肺炎案例(绿色)显示了分离,但是因为数据集很小,我们需要对这个推论有所保留。

最后的话

我们已经看到,Imagenet 预训练模型的性能优于 COVID-Net 模型。最佳例外模型具有更好的精度,最佳 DenseNet 模型具有更好的召回率。在这种特殊的情况下,回忆更重要,因为你需要的是安全而不是遗憾。即使你把少数非新冠肺炎病例归类为阳性,他们也只会被引导去做适当的医学测试。但是另一种错误并不那么宽容。因此,单纯从这一点来看,我们的 DenseNet 模型更好。但我们也需要记住,这是在有限的数据集上训练的。同样,新冠肺炎病例的数量也只有 60 例左右。很有可能这个模型已经记住或过拟合了这 60 个。这是一个典型的例子,模型使用 x 光片上的标签将它归类为新冠肺炎。GradCAM 检查也不是很有帮助,因为一些例子看起来像模型正在寻找正确的地方。但是对于一些例子来说,热图照亮了几乎所有的 X 射线。

但是在检查了 GradCAM 和 t-SNE 之后,我认为例外模型对这些情况有了更好的表示。回忆率低的问题是可以解决的。

从更大的角度来看,我们已经开始了整个练习,我认为我们可以有把握地说,Imagenet 预训练确实有助于新冠肺炎胸部放射摄影图像的分类(我确实试图在相同的数据集上训练 DenseNet,但没有预训练权重,没有取得多大成功)。

未探索的方向

这个问题还有很多未被探索的方面,我会提到这些,以防我的读者想了解这些。

  • 收集更多数据,尤其是新冠肺炎案例,并重新训练模型
  • 处理阶级不*衡
  • 灰度 ImageNet[9]上的预训练和灰度 X 射线上的后续转移学习
  • 使用 CheXpert 数据集[8]作为 Imagenet 和胸部 x 线摄影图像之间的桥梁,通过微调 CheXpert 数据集上的 Imagenet 模型,然后应用于手头的问题

Github Repo带训练和推理代码。

呼吁合作

如果你是医学专业人士,认为这是一个值得研究的方向,请联系我。我想确信这是有效的,但目前还没有。

如果你是一个 ML 研究者,想要合作发表论文,或者继续这方面的研究, 联系我

更新——在我克隆了 COVID-Net 回购协议之后,有了一次更新,既在数据集中增加了几个新冠肺炎的案例,也增加了一个更大的模型。而且我们合奏的表现还是比大模型好。

编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

参考

  1. Cheplygina,Veronika,“CAT 或 CAT 扫描:从自然或医学图像源数据集转移学习?,“arXiv:1810.05444 [cs。简历],2019 年 1 月。
  2. Raghu,Maithra 等,“输血:理解医学成像的迁移学习”,arXiv:1902.07208 [cs .简历],2019 年 2 月
  3. 史密斯,莱斯利·n .,“训练神经网络的循环学习率”,arXiv:1506.01186 [cs .简历],2019 年 6 月
  4. 张弘毅、穆斯塔法·西塞、扬·n·多芬、戴维·洛佩斯·帕兹,“混乱:超越经验风险最小化”。ICLR(海报)2018
  5. 周,等,“学习深度特征进行鉴别性定位”,arXiv:1512.04150,2015 年 12 月
  6. Selvaraju,Ramaprasaath R .等人,“Grad-CAM:通过基于梯度的定位从深度网络进行视觉解释”。arXiv:1610.02391 [cs。简历],2016 年 10 月
  7. 劳伦斯·范德·马腾,杰弗里·辛顿,“使用 t-SNE 可视化数据”。2008
  8. Irvin,Jeremy 等人,“CheXpert:带有不确定性标签和专家比较的大型胸片数据集”,arXiv:1901.07031 [cs .简历],2019 年 1 月
  9. 谢,伊婷&里士满,大卫。(2019).灰度 ImageNet 预培训改善医学图像分类:德国慕尼黑,2018 年 9 月 8 日至 14 日,会议录,第六部分。10.1007/978–3–030–11024–6_37.

原载于 2020 年 4 月 5 日http://deep-and-shallow.com

生产率提高了工资吗?

原文:https://towardsdatascience.com/does-productivity-increase-wages-f50ce24f41d0?source=collection_archive---------76-----------------------

探索固定效应回归的 R 项目

介绍

经济理论告诉我们,劳动生产率是工资的主要决定因素。然而,许多评论家认为这种关系已经破裂,尤其是在最*几十年。该项目将探索一种固定效应回归,以分析经合组织国家小组的生产率和工资之间的联系。

这个项目并不打算面面俱到——相反,更多的是一个实验,提供一些来自不同国家的关于这个主题的证据。

数据源

我所有的数据都将来自经合组织的数据库。我下载了 CSV 文件中的三个数据序列:劳动生产率(每小时工作的 GDP)年*均工资年*均工作时间。我选取了 1990 年至 2018 年的时间段,因为这是所有三个数据集中可用的最多的数据。

在我的 Github 上有完整的代码和数据集。

该项目

首先,我将把每个数据集放入 r 中。我还加载了几个我在几乎所有项目中使用的标准包。

library(ggplot2)
library(dplyr)#Bring in labour productivity data
GDPh <- read.csv("DP_LIVE_16062020201012437.csv")#Bring in average annual wages
Wage <- read.csv("DP_LIVE_16062020201639206.csv")#Bring in average annual hours worked
Hours <- read.csv("DP_LIVE_16062020202140847.csv")

清理和准备数据

对于几乎任何项目来说,数据都会以我们想要的形式出现。经合组织的数据设计得很好,但仍需要做一些工作才能得到所需的格式。对于每个数据系列,为了可读性,我将重命名几列,然后删除我不需要的列。

#GDP per hour
names(GDPh)[1] <- "Country"
names(GDPh)[7] <- "GDP.h"
GDPh <- GDPh[-c(2:5,8)]#Annual wages
names(Wage)[1] <- "Country"
names(Wage)[7] <- "Wage"
Wage <- Wage[-c(2:5,8)]#Hours worked per year
names(Hours)[1] <- "Country"
names(Hours)[7] <- "Hours.a"
Hours <- Hours[-c(2:5,8)]

从这里,我可以将数据集合并到一个数据框中:

Comb <- merge(GDPh, Hours)
Comb <- merge(Comb, Wage)

这个数据集包括作为一个国家的整个经合组织,我不想把它包括在内(因为我是在看单个国家)。我需要从我的数据中删除这些观察结果。有几种方法可以做到这一点,但我发现了一种创建“不在”函数的简洁方法,在这种情况下很容易使用。

#Create 'notin' function
`%notin%` <- Negate(`%in%`)#Remove OECD observations
Comb <- subset(Comb, Country %notin% c("OECD"))

最后,我想创建一个新列,其中包含每小时的*均工资,而不是我现在的年*均工资。为此,我可以简单地用“Hours.a”列除“工资”列来创建一个新列。

#Create an hourly wage column
Comb$H_wage <- Comb$Wage/Comb$Hours.a

此时,数据是我可以处理的格式。

统计数字

普通最小二乘法

首先,让我们用数据生成一个标准的普通最小二乘(OLS)回归:

#OLS regression
ols <- lm(H_wage~GDP.h, Comb)
summary(ols)

然后,Summary 会提供以下输出:

系数 0.466(意味着劳动生产率每增加 1 美元,工资增加 0.466 美元)具有统计意义。

我们也可以想象这种回归。虽然我可以使用默认的 plot 函数,但大多数人认为 ggplot 包更有吸引力。

library(ggplot2)#Visualize fit
ggplot(Comb, aes(x=GDP.h, y=H_wage)) +
  geom_point() +
  geom_smooth(method=lm) +
  labs(x = "GDP Per Hour Worked",
       y = "Hourly Wage")

这产生了下面的情节:

阴影区域代表 95%的置信区间

然而,由于国家之间的异质性,这不是分析数据的最佳方式。

*衡面板

第一步将是检查面板是否*衡(意味着我们对所有国家都有相同的时间段)。我已经知道面板是*衡的,但是我们还是会显示代码。为此,我们将使用“plm”包。

library(plm)is.pbalanced(Comb)
[1] FALSE

此功能已确认我们的面板不*衡。幸运的是,这个包也有*衡我们面板的功能。但是,我们必须选择如何*衡我们的面板(该功能提供了三个选项)。我将选择保留所有可用时间段的选项,删除不可用的国家。

length(unique(Comb$Country))
[1] 35

这段代码告诉我,我的面板目前有 35 个国家。

Comb <- make.pbalanced(Comb, balance.type = "shared.individuals")
length(unique(Comb$Country))
[1] 15

新的数据集现在只有 15 个国家,这是一个相当小的国家样本。确认新面板是*衡的:

is.pbalanced(Comb)
[1] TRUE

面板现在是*衡的。现在,我将在剩余的面板中制作一个国家的可视化。

ggplot(Comb, aes(x=GDP.h, y=H_wage)) +
  geom_point() +
  facet_wrap(.~ Country, scales = "free") +
  labs(title = "Country Panel",
       caption = "Source: OECD",
       y = "Average Wage",
       x = "GDP/Hour Worked")

固定效应模型

现在,我们可以在面板上运行固定效果模型。

f <- plm(H_wage~GDP.h, data=Comb, model="within")
summary(f)

它产生以下输出:

该系数现在是 0.486,仍然具有统计学意义。我们能够绘制一个显示国内回归的图表:

plot(f,
     pooling=F,
     within=T)

虽然我们的面板有太多的国家来产生视觉上吸引人的图,但这对于具有较少实体的数据集是有用的。然而,我们仍然可以看到,几乎所有国家都表现出积极的关系。

检验固定效应模型对 OLS 的影响

首先,我在*衡数据集上重新运行 OLS。现在我们可以针对 OLS 测试固定效应模型,看看它是否能更好地解释这些数据:

#Test fixed-effects against OLS
pFtest(f, ols)

我们可以拒绝零假设;固定效应模型产生的结果明显优于 OLS。

模型诊断

我将测试该模型是否具有时间固定效应。

#Time fixed effects
ft <- plm(H_wage ~ GDP.h + factor(TIME), data=Comb, model="within")
summary(ft)

#Test time-fixed effects--null hypothesis is no time fixed effects
pFtest(ft,f)

p 值为 0.029 是困难的——它提供了好的,但不是时间固定效应的结论性证据。这表明这个模型可能更适合。

其他诊断

虽然我不会在这里执行它们,但是您可以执行各种其他测试。一个特别值得关注的问题是截面依赖性。你也可以测试序列相关性和异方差性。

公众情绪影响股市吗?

原文:https://towardsdatascience.com/does-public-sentiment-effect-the-stock-market-ea3836e3b2b?source=collection_archive---------28-----------------------

stocktwits.com

众所周知,股票市场的表现会对公众产生影响,但如果情况正好相反呢?随着社交媒体的兴起,人们已经发布了大量关于各种主题的信息,研究人员越来越有兴趣了解金融相关社交媒体数据在金融模型中可能扮演的角色。这可能是关于股市乐观或悲观的总社交媒体情绪可以预测未来的股票走势,如果这是真的,那么社交媒体数据可能对金融机构非常有价值。

衡量公众对股市情绪的一种方法是使用社交媒体*台 StockTwits 的数据。StockTwits 类似于 Twitter,但信息更详细,因为用户可以选择将他们的推文标记为“看涨”或“看跌”。通过查看使用这些标签的推文,研究人员可以避免在分析中使用自然语言处理,这将节省大量时间。假设有足够大比例的人使用这些标签,通过比较当天看涨和看跌标签的推文总数,可以估计出公众每天的整体市场情绪。

对于这个项目,我通过查看 80 个来自标准普尔 500 的报价机来测试这个方法。为了确保结果不会被少数推文中的情绪所扭曲,我根据粉丝数量挑选了 80 个报价器(每个报价器有 10,000 或更多粉丝)。这个项目的目标是看看情绪是否与股票的未来价格行为有任何关联。

tickers = ['spy', 'ABBV', 'ATVI', 'ADBE', 'AMD', 'GOOGL', 'GOOG', 'MO', 'AMZN', 'AAL', 'AAPL', 'AMAT', 'T', 'BAC', 'BRK.B', 'BBY', 'BIIB', 'BA', 'BKNG', 'BMY', 'AVGO', 'CAT', 'CVX', 'CMG', 'CSCO', 'C', 'KO', 'COST', 'CVS', 'DAL', 'EBAY', 'EA', 'XOM', 'FB', 'FDX', 'F', 'FCX', 'GE', 'GM', 'GILD', 'GS', 'HD', 'INTC', 'IBM', 'ISRG', 'JNJ', 'JPM', 'KMI', 'KHC', 'KR', 'LMT', 'M', 'MA', 'MCD', 'MRK', 'MU', 'MSFT', 'NFLX', 'NKE', 'NVDA', 'ORCL', 'PYPL', 'PFE', 'PG', 'QCOM', 'CRM', 'SWKS', 'LUV', 'SBUX', 'TMUS', 'TTWO', 'TGT', 'TWTR', 'ULTA', 'UAA', 'VZ', 'V', 'WMT', 'DIS', 'WFC', 'WYNN', 'QQQ', 'GLD', 'XLF']

为了收集数据,我在今年 1 月 1 日至 2 月 14 日股票市场开放的日子里,分别在上午 9:30、下午 1:30 和下午 4:00 左右从 Stocktwits.com 收集了每个股票的情绪。为了计算股票价格的百分比变化,我比较了情绪发生时的价格和下一个数据点的收盘价。

数据框架中的示例行

在实践中,数据科学家通常与样本一起工作,但大多数时候我们实际上对描述样本本身并不感兴趣;我们想用这些样本来推断相应的人群。由于我仍处于数据收集的早期阶段,我现在将查看到目前为止我所收集的数据的分布情况。

总的来说,数据的分布看起来很正常。情绪的*均值是-.153。这表明,*均而言,整个数据集的公众情绪只是有点悲观。

所有 80 个报价机的综合*均情绪

在同一时期,标准普尔 500 上涨了 4.35%。考虑到整体情绪略显悲观,这无疑很有趣。

2020 年 1 月 2 日至 2 月 14 日 S&P 价格行动。上涨 4.35%,而*均情绪略有看跌

均值告诉我,来自样本的*均情绪是-0.153,但这并不意味着每个数据点的情绪是-0.153。通过使用标准差公式,我可以了解*均情绪的变化程度。计算告诉我,*均而言,情绪在*均值上下波动约 4.10 倍。

df['sentiment'].std(ddof = 1)

然而,情绪可能会偏离均值 1 个标准差以上。一些异常值低至-15 或高达 11,如上图所示。

因为该数据集是情感的样本,所以在计算标准偏差时使用 n-1。原因是样本标准差通常低估了总体标准差。有些样本标准偏差较低,有些较高,有些相同,但*均而言,样本标准偏差低于总体标准偏差。

这意味着,当从总体中抽取样本时,如果你从分布差的角度考虑,你更有可能得到一个分布差低于总体分布差的样本。获得具有较高标准偏差的样本是可能的,但可能性较小。这主要是特定于具有高分布且没有聚类的样本。

为了纠正低估问题,分母减少 1。这种由除以 n-1 而不是 n 组成的小修正被称为贝塞尔修正。(来源:维基百科)

情绪能预测价格行为吗

根据我收集的数据,我查看了情绪超过或低于*均值两个标准差的数据点。对于这个样本,这意味着 8.2%(看涨)或-8.2%(看跌)的情绪。

significant_data[(significant_data['sentiment'] <= -8.2)]significant_data[(significant_data['sentiment'] >= 8.2)]

我的假设是,在对股票的情绪极度看涨或看跌的日子里,价格行为将遵循相同的方向。原因是极端情绪无论如何通常是因为一些外部因素。

我发现,即使情绪在两个方向都很极端,百分比变化的分布仍然是正常的。在下图中,蓝线代表情绪为 8.2%或更高时的百分比变化。红线代表情绪为-8.2%或更低时的百分比变化。

当市场情绪极度看涨时(偏离*均值+2 个标准差),*均价格变化为+0.223%。

df_2_std_pos['percent_change'].mean()
#0.2227859276042125

当情绪极度悲观时,*均价格变化为负,为-0.558

df_2_std['percent_change'].mean()
#-0.5578316295700224

这很有趣,因为根据目前的数据,它确实表明极端情绪可以预测。

目前我只能做到这一步,因为我需要更多的数据来进行任何有意义的分析。尽管这些初步结果确实很有趣。

与大市值公司相比,新冠肺炎造成的经济损失对小市值公司的影响更大吗?

原文:https://towardsdatascience.com/does-the-economic-damage-caused-by-covid19-affect-smaller-cap-companies-more-compared-to-bigger-7693cab360e0?source=collection_archive---------68-----------------------

根据权威人士的说法,他们真的能更好地抵御这场飓风吗?

新冠肺炎·疫情让我们所有人都大吃一惊。在短短几周时间内,美国股市已跌至超过 2008 年金融危机的水*,更让人想起大萧条,而从香港到日本再到东京,世界各地的股市都经历了类似的冲击。但是新闻报道说在这次股市崩盘中。较大的公司可以更好地抵御危机,因为与中小型公司相比,它们拥有更大的储备。因此,我将利用数据科学,用数据做一个快速的比较,看看这是真的还是假的。

在美国,有两个市场指数,即 S&P(标准普尔)和罗素 2000/3000 指数。这两个指数跟踪大型和小型/中型公司的股票价格。我用股票价格来代表公司的健康状况,但这涉及到许多因素,如现金储备、债务额等。但是为了让事情变得简单并继续前进。我决定从 S&P 和罗素 2000 指数中获取前 10 只股票的总股价。S&P 排名前十的股票在这里列出https://www . investopedia . com/top-10-s-and-p-500-stocks-by-index-weight-4843111

S&P 排名前十的股票是:
1——微软
2——苹果
3——亚马逊
4——脸书
5——Alphabet
6——谷歌
7——强生&强生
8——伯克希尔·哈撒韦
9——Visa
10——摩根大通

我挑选的罗素 2000 指数的前 10 只股票列在这里https://www . fool . com/investing/stock-market/indexes/Russell-2000/

1—Teladoc
2—novo cure
3—Generac
4—lumen tum
5—Trex
6—Amedisys
7—Portal General Electric
8—Haemonetics
9—第一工业地产信托
10 —德克斯户外公司

我从雅虎财经网站上下载了所有的股票价格,这些价格是基于从 2020 年 1 月 7 日到 6 月 5 日的 6 个月时间范围。这两个 CSV 文件可以从这里下载S&P 的和这里Russell 2000 的

有了这两个 CSV 文件。我需要先把它们画在图上,看看它们是什么样子。所以用谷歌的 Colab,Python,和 Panda。我开始导入和读取 CSV

import numpy as np import matplotlib.pyplot as plt import pandas as pd

dataset = pd.read_csv('S_n_P - V-2.csv') X = dataset.iloc[:, 1].values.reshape(-1, 1) y = dataset.iloc[:, 12].values.reshape(-1, 1)

现在,CSV 文件显示日期、股票价格和 10 家公司的总数。图表需要显示 X 的日期和 y 的股票价格。但是 Panda 不允许我在导入时使用日期作为值。所以我修改了我的 CSV,增加了一列 day ,这是一个流水号序列,从 1 月 7 日的第 1 天开始,到 6 月 5 日的最后一天,即第 105 天。这个新日柱位于指数 1 处,而组合股票价格位于指数 12

接下来,我绘制图表,看看如何使用这段代码显示数据点

plt.scatter(X, y, color = 'red') plt.title('S&P') plt.xlabel('Day') plt.ylabel('Price') plt.grid(b=True, color='blue', alpha=0.6, linestyle='dashdot') plt.show()

正如你所看到的,你可以看到股价上涨,然后在图表中心大幅下跌,然后再次上涨。

从罗素 2000 指数前 10 名股票的图表中,我们可以看到这一点

股价像预期的那样上涨,然后在之前 S&P 图表显示的日期范围内再次下跌。所以从这两张图中,我们很难得到更多的数据,因为数据点或多或少非常相似。此外,图表显示股价不断上涨、下跌和上涨,因此线性回归没有意义,因为它不会反映数据点的涨跌。所以我决定用多项式回归来代替,这是我用的代码

from sklearn.preprocessing import PolynomialFeatures polynomial_reg = PolynomialFeatures(degree = 5) X_polynomial = polynomial_reg.fit_transform(X) lin_reg_2 = LinearRegression() lin_reg_2.fit(X_polynomial, y)

接下来,我添加这些代码行来显示曲线,并添加更多次要的网格线,以便我们可以更好地看到这些点

plt.plot(X, lin_reg_2.predict(polynomial_reg.fit_transform(X)), color = 'grey')

plt.minorticks_on() plt.grid(which='minor', linestyle=':', linewidth='0.5', color='black')
plt.grid(b=True, color='blue', alpha=0.6, linestyle='dashdot') plt.show()

有了 S&P,我们可以看到图表中的曲线

你会注意到曲线上升到 6500,然后下降到 5450,然后上升到 6750。这意味着在第 55 天出现了 16%的下跌,然后再次上涨至 6750 点,比最初的高点 6500 点上涨了约 3.8%。

现在对于罗素 2000 曲线,我们得到这个

在下跌 13%至 950 点之前,它达到约 1100 点的高点,然后从 1100 点的初始高点上涨 0.9%至 1110 点。

这表明中小型公司和大公司都受到了 Covid19 危机的同等影响,如曲线的下降所示。但是与大公司相比,中小型公司并没有恢复那么多。这可能是由于投资者信心、对蓝筹公司的看法、公司现金储备等原因造成的。因此,这张图确实显示了中小市值公司在复苏方面确实受到了更大程度的影响。

好的,如果你看过前 10 大 S&P 股票,其中大部分是科技股,如亚马逊、微软、苹果等。这是否会影响 S&P 10 大股票的整体反弹,因为 S&P 10 大股票中的大多数都是科技股?为此,我决定通过雅虎财经(Yahoo Finance)从以科技股为主的纳斯达克(NASDAQ)调出前 10 只股票,这 10 只股票是

1 —苹果
2 —亚马逊
3 —康卡斯特
4 —思科
5 —脸书
6 —谷歌
7 — Alphabet
8 —英特尔
9 —微软
10—英伟达

我已经提取了纳斯达克股票的数据,并将它们放在这里。

使用多项式回归的相同代码集,我们可以看到图形是如何排列的。这是纳斯达克十大股票的图表

因此,该曲线首先在 6240 点见顶,然后开始下跌至 5250 点,跌幅为 15.8%,然后反弹至 6600 点,从 6240 点上涨 5%。这说明科技股的回升幅度要大得多。这可能是因为看涨的投资者希望将资金投入他们认为更安全的公司,如科技股,因为它们不受 Covid19 局势的影响,尽管由于投资者的信心,股票全面下跌。

因此,从这三张图表来看,似乎有一些事实是,较大的公司更有能力抵御由 Covid19 整体引起的危机,而科技公司比其他公司更好地经受住了这场风暴。

下面是我用的 CSV 文件的链接
Russell 2000:https://gist . github . com/gib Tang/f 60 fbcdc 973 f 4 fdf 90 e 8 a 0 f 9 EDC 668 e 3Nasdaq:
https://gist . github . com/gib Tang/8924 b 61 c 06043003d 9d 49 D5 AEC 842 b 73
S

以及我在本文中使用的代码
https://gist . github . com/gib Tang/62e 854d 6 FB 5976601193 b 089 E8 DC 85d 4

病例对照研究和棒球

原文:https://towardsdatascience.com/does-throwing-hard-give-you-tommy-john-cbab2f153e0b?source=collection_archive---------48-----------------------

高速和汤米·约翰的统计探索

斯蒂芬·斯特拉斯堡只是汤米·约翰众多成功案例中的一个

目前超过四分之一的 MLB 投手进行了汤米·约翰,更正式的名称是尺骨副韧带重建手术。一些最*的受害者?纵火犯 Luis Severino,Chris Sale 和 Noah Syndergaard。

Syndergaard 经常投 90 多分的球(图片来自维基共享)

对于一个没有医疗经验的统计学学生来说,这个过程似乎比破译 Nats 的世界大赛标志更难。实质上,外科医生从身体的其他地方获取肌腱(通常是腿筋),在有问题的手臂上钻孔,然后将移植肌腱穿过几次。抱歉,我曲解了你的解释。

奇迹般地,手术几乎成了常规。恢复率估计为 80-90 %,大多数投手继续领导漫长的职业生涯。相反,大多数棒球运动员仍在试图找出 为什么 这种情况一直发生。为什么手肘一直爆,为什么越来越年轻?

普遍共识是过度使用;运动员招募发生在生命的早期,孩子们被鼓励更努力地投掷,淡季是失败者的。也有许多生物力学的解释,说明某些投球类型,如滑球,如果投得太年轻会有危险。

我着手解决这个解释的一小部分,即:

  1. 更高的俯仰速度会增加汤米·约翰的可能性吗?
  2. 某些球场类型会增加汤米·约翰的可能性吗?

为了简洁起见,我将从此把这个手术称为“TJ”。

方法

我在 MLB 的投手中进行了一项病例对照研究,病例组是接受过 TJ 的投手,对照组是没有接受 TJ 的投手。

投手总数因数据可访问性而异;例如,关于快速球使用的更细粒度的数据只从 2017-19 年开始提供,因此某些模型只考虑了这些年。我会在必要的地方阐明选择方法。

病例对照研究快速入门

对于那些不熟悉的人,病例对照研究试图确定建议的风险属性和观察到的条件之间的关系(对我们来说,这个观察到的条件将是 TJ)。

这是通过考虑仅在条件状态上不同的两个组来完成的,一个组有条件,一个组没有条件。然后,通过风险属性的水*(例如,俯仰速度、滑动百分比)对这两组进行比较,并计算比值比。

比值比表明,在风险属性增加的情况下,出现病例情况的机会增加。请注意,如果属性不是定量的而是定性的,例如,惯用手,级别将被转换为属性的普遍性。

TL;【T2 博士】我们正在比较有 TJ 和没有 TJ 的投手的速度和投球类型,希望在这个过程中找到一些有意义的东西。从病例对照研究中计算出的优势比也有助于我们量化速度对 TJ 可能性的影响。否则,仅仅知道 TJ 投手投得更努力并不能揭示太多。

数据

我使用了 3 个来源:来自 Brook 棒球的 PITCHf/x棒球专家和 Jon Roegele 的极其有史以来每个 Tommy John 手术的极有帮助的列表

分析

第 1 部分:更高的俯仰速度会增加汤米·约翰的可能性吗?

我首先使用以下参数从 Brooks 收集 PITCHf/x 数据:

  • 2007–2019 赛季(从数据开始算起)
  • 所有音高类型的*均速度
  • 首发和替补队员
  • 至少投出 200 个球(只抓住主要的联盟球员,排除位置球员)

这给了我 2001 个投手,数据如下:

这看起来不太有希望。TJ 组以较高的*均值为中心,但几乎没有。如果放大并使用密度,看起来会更*:

这并不意外。又不是每个投出 95+ mph 的都自动得到汤米约翰。我们继续吧。

我使用逻辑回归从我们的速度属性预测我们的二元响应(对 TJ 是/否)。这对应于统计模型:

Yᵢ是我们的响应变量,表示 iᵗʰ球员是否有汤米·约翰。μᵢ是 iᵗʰ球员拥有 TJ 的概率,x 是包含投球速度的模型矩阵,这是我们唯一的独立变量。因此,Xᵢβ是独立变量的线性组合。

logit 函数将二元响应变量与我们的协变量联系起来。在高层次上,我们这样做是因为线性标度更好使用,但是我们的是/否回答必须被转换以适应;因此,logit 函数!

结果如下:

我来解释一下如何解读有用的部分。

Coefficients指的是我们的模型,即

如果我们对实际概率或μᵢ感兴趣,我们必须提取μᵢ:

最终表达式给出了拥有 TJ 的实际概率,或μᵢ 。例如,我们可以计算*均速度为 95 英里/小时的投手出现 TJ 的概率:

因此,*均投球速度为 95 英里/小时意味着汤米·约翰接受手术的概率为 39.5%。

我们可以这样做来计算在一定速度下 TJ 的概率,但这并不能量化增加速度和增加 TJ 可能性之间的关系。为了提取这些信息,我们对这些Coefficients进行指数运算以产生优势比。

请注意,我对系数的 置信区间 进行了指数运算,因为这比特定的点估计更好地反映了可能值的范围。

>>> exp(confint(brooks_glm)) 2.5%   97.5%
Intercept  5.45e-05  0.0183
Velo       **1.036133  1.1062**

我们将保持InterceptVelo作为我们指数化变量的名称,给我们以下赔率等式:

这与线性回归不同,在线性回归中,当变量值改变时,我们添加系数。取而代之的是,当变量值改变时,现有的赔率被乘以可变系数。

因此,如果一个变量的系数是 1 ,那么这个变量对响应没有影响,因为我们将现有的值乘以 1。请注意,我们使用的是置信区间,因此包含 1 的范围实际上使我们的变量变得无用。

要点如下:如果系数的置信区间包含 1 ,我们可以认为该变量对响应没有影响。

从输出的最后一行(上面加粗的部分),我们看到*均俯仰速度增加 1mph 相当于将 TJ 的现有几率乘以 1.036 到 1.106 之间的值。这可以解释为:

每增加一英里/小时,患 TJ 的几率增加 3.6-10.6%。

我重复了这个练习,但是专注于*均四缝线快速球速度,而不是所有球路的*均速度。

>>> exp(confint(brooks_glm_4seam)) 2.5%   97.5%
Intercept  1.1e-5   0.026
Velo       **1.0313   1.121**

使用同样的解释过程,我们可以看到四缝线快速球速度每增加一英里/小时,TJ 的几率增加 3.1–12%,与我们之前的发现非常相似。

某些音高类型会增加汤米·约翰的可能性吗?

速度的增加似乎增加了汤米·约翰的胜算,但是对于某些类型的投球来说也是这样吗?在棒球专家上可以很容易地获得细分球场使用情况的数据,但仅限于 2017-2019 年;因此,本部分的结论仅来自这三个季节。

为了澄清,投球使用数据是以百分比的形式给出的,表示由某种投球类型(如快速球)构成的总投球数的百分比。

我分别研究了快速球、滑球、变速球和切球,以分离每种球种的效果。我也考虑了每种投球类型的*均速度,例如在同一模型中包括快速球的使用速度。

以下是已清理数据集的一瞥:

每一列对应一个玩家的统计;第一位投手以 89.3 英里/小时的*均速度在 16.3%的时间里投出了他们的 4 缝线球,以 80.5 英里/小时的*均速度在 7.3%的时间里投出了他们的滑球,以此类推。(我也研究了每局的投球数,但结果并不显著)

然后,我以 TJ 状态作为反应进行了一项类似的病例对照研究,同时考虑了音高使用和速度。注意,同样的解释成立:如果置信区间包含 1,我们将认为它没有影响——为了便于阅读,我将这些区间加粗。

快速球

>>> exp(confint(fastball_glm))

                 2.5%  97.5%
Intercept       0.001  0.095
fastball_usage  **0.986  1.001**
fastball_velo   1.020  1.096

看来快速球的使用并不影响 TJ 可能性,因为它的置信区间包含 1。这意味着快速球使用率每增加一个百分点,现有的 TJ 赔率就会乘以一个很可能是 1 的值,因此没有效果。

然而,快球速度增加 1 英里/小时,似乎增加了 TJ 几率 2–9.5%,这一发现与我们从第一部分得出的结果一致。由于仅考虑 2017-19 年数据,具体百分比有所不同。

滑块

>>> exp(confint(slider_glm))

               2.5%  97.5%
Intercept     0.001  0.084
slider_usage  **0.995  1.011**
slider_velo   1.018  1.095

类似地,滑块使用的置信区间包含 1 ,意味着它不影响 TJ 可能性。然而,滑块速度每增加 1 英里/小时,TJ 几率就会增加 1.8-9.5%。

变速球

>>> exp(confint(changeup_glm))

                 2.5%  97.5%
Intercept       0.002  0.679
changeup_usage  **0.982  1.005**
changeup_velo   **0.996  1.068**

变速使用和速度的置信区间都包括 1,表明这两个属性都不影响 TJ 可能性。这并不奇怪;变速球是低速球,理想情况下比快球慢得多,可能会减少肘部的压力。

虽然变速球以相似的「手臂速度」投出,以掩饰它们是快速球,但是很少有投手会尽全力向后仰投变速球。更难的变速球实际上可能不太受欢迎,因为它们的部分效果来自于欺骗打者提早挥棒。

如果我们的假设是真的,增加快速球的速度会增加 TJ 的胜算,变速球不影响这些胜算就说得通了。

倾斜节理

>>> exp(confint(cutter_glm))

               2.5%  97.5%
Intercept     8e-05  14.29
cutter_usage  **0.987  1.010**
cutter_velo   **0.962  1.102**

像变速一样,两个置信区间都包括 1,这意味着刀具使用和速度都不会影响 TJ 可能性。

这个有点难以解释,甚至可能表明所用统计方法的缺陷。

切割球,或切割快速球,移动起来像是快速球和滑球的混合体。这项研究更相关的方面是如何投掷刀具。许多投手只是简单地改变他们的四缝线快速球握拍,对球的外侧施加稍微多一点的压力,像快速球一样释放出切球。

由于释放动作类似于快速球,人们可能会期望增加切割速度来增加 TJ 的几率。我们的发现表明并非如此;一个可能的解释是交付背后的努力

虽然削球像快球一样被投出,但是削球的效率来自于移动和位置,而不是速度。因此,投手可能不会像投速度依赖型快速球一样努力投出切球,这种努力可能会导致过度用力和汤米·约翰。支持这一论点的是许多投手采用切割器来抵消速度的损失,承认投球不需要高速度才能有效。

投手们明白,当涉及到切球时,用力投掷不太重要,这可能解释了其速度对 TJ 可能性的微弱影响。

结论

也许,仅仅是也许,力学与此有关(图片来自维基共享)

  • 快球速度每增加 1 英里/小时,汤米·约翰接受手术的几率就会增加3.6–10.6%
  • 滑块速度每增加 1 英里/小时,TJ 赔率就会增加1.8–9.5%
  • 增加变速和刀具速度并不会增加 TJ 赔率(尽管你可能无论如何都不会想把它们扔得更重,因为高速度不一定会让这些投球更好)
  • 音高的使用无关紧要

我写这份报告的目的之一是复习优势比、逻辑回归和病例对照研究。当我找到课程内容的真实应用时,我会学得更好,我非常鼓励你也这样做!

带着一份健康的盐接受这些结论——数据和方法不可否认地远非完美。例如,对我们数据的原始探索表明,逻辑回归可能不是一个理想的分类器。

不管怎样,有证据表明汤米·约翰手术和高音高速度之间有联系。这并不奇怪,但我现在更加确信了。

应用神经网络中的迁移学习进行犬种分类

原文:https://towardsdatascience.com/dog-breed-classification-using-cnns-and-transfer-learning-e36259b29925?source=collection_archive---------20-----------------------

图片来自乔尼·林德纳皮克斯拜拍摄

…还有人和狗的相似之处

这篇文章提出了使用预先训练的卷积神经网络来分类养狗。除了用于狗的狗品种分类,CNN 也用于识别与任何给定的人类图片最相似的狗品种。

本文分六个步骤介绍了该项目:

  1. 数据集。
  2. OpenCV 实现了基于 Haar 特征的级联分类器来识别人类。
  3. ImageNe t 数据集预训练 ResNet50 以识别狗。
  4. 犬种分类的迁移学习。
  5. 微调
  6. 图像分类

缩写列表:

FC 层:全连接层
Conv。层:卷积层

数据集

Udacity 提供的数据集相对较小。它包含了 8351 张狗的图片,来自 133 个可能的狗品种类别,大约每个类别 63 张。数据集分割如下:

  • 训练集的 6680 幅图像;
  • 835 幅图像用于验证集;
  • 测试集的 836 幅图像。

提供另一个具有 100 个图像的数据集来测试预训练的人类标识符。

1.用于人体识别的 OpenCV

OpenCV 库在 GitHub 库中提供了许多预先训练好的人脸检测器。对于这个项目,我们将Haar scades用于正面人脸检测器

# extract pre-trained face detector
model_file_name = 'haarcascades/haarcascade_frontalface_alt.xml'
face_cascade = cv2.CascadeClassifier(model_file_name)# load color (BGR) image
img = cv2.imread(human_files[83])# convert BGR image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# find faces in image
faces = face_cascade.detectMultiScale(gray)

从包含人类的 100 幅图像中,预先训练的模型可以识别所有人,100%准确。在这 100 张照片中,有三张发现了不止一张脸。这些例子如图 1 所示。在第一个例子中,只有一张脸,它被识别了两次。

图 1 —发现多个面的情况。

当我把另一组 100 张狗的图片交给分类器时,它识别出其中 11 张是人的图片。您可以在下面的图 2 中看到其中的 9 个错误。但是,如果您看到下面的错误 1,除了狗之外,图像中还有一个人,人脸检测器正确地识别了这个人。因此,让我们认为它不是一个错误。探测器只犯了 10 个错误,而不是 11 个。

图 2–人脸检测器在 100 多张狗的图像中出现的 10 个错误中有 9 个错误。

人脸检测器很好地识别了人,没有假阳性。另一方面,区分狗和人不太好,它把 100 只狗中的 10 只误归类为人类。

2.预先训练 EGG16 识别狗

Keras 提供了已经在 ImageNet 数据集上训练过的 CNN 模型。该数据集包含 1000 个不同类别的图像,其中 118 个与狗有关。这意味着我们可以使用这些预训练的模型来确定一幅图像是否包含一只狗。

区分前一个分类器和下一个分类器是很重要的。第一个的目的是识别图像是否包含一个人。接下来的目的是识别图像是否包含。结合两个分类器,我们可以确定图像中何时有狗、人、两者或没有。**

下面的代码展示了如何使用 Keras 中预先训练好的模型 ResNet50 来确定图像中是否有狗。

*# Import the ResNet model and the preprocess_input function.
from keras.applications.resnet50 import ResNet50, preprocess_input# Import the functions to load and transform images
from keras.preprocessing.image import load_img, img_to_array# Create a Redidual-network already trained in the IMAGENET
ResNet50_model = ResNet50(weights='imagenet')# Load the image in the size expected by the ResNet50_model
img = load_img('some_image.jpg', target_size=(224, 224))# Transform the image into an array
img_array = img_to_array(img)# Pre-process the image according to IMAGENET standarts
img_ready = preprocess_input(img_array)# Predicts
probs= ResNet50_model.predict(img_ready)# Find the position with the maximum probability value
position_of_max = np.argmax(probs)# Verify if the position of max corresponds to a dog class
is_dog = ((position_of_max >= 151) & (position_of_max <= 268))*

Keras 提供了函数preprocess_input来根据 IMAGENET 数据集的分布对新图像进行规范化。该函数从图像的每个 RGB 像素中减去数据集已知的*均像素[103.939,116.779,123.68]。

ResNet50_model.predict中进行的预测返回每个类的概率列表。对应于狗的类在 151 和 268 之间的位置,包括 151 和 268。要验证图像是否是狗,最大概率必须在 151 到 268 范围内的位置是狗,否则不是狗。

从包含人类的 100 张图像中,预训练的模型没有识别出它们上面的任何狗,这很棒。此外,该分类器还能够识别所有其他 100 张包含狗的图像。这个模型在这 200 张图片上没有犯任何错误。

此时,你可能会疑惑,为什么我们不简单地用这 118 个狗类来划分狗的品种呢?这是因为我们试图将狗分为 133 个可能的犬种类别,15 个新的类别。即使我们知道预训练 ResNet50 模型的 118 个类别中的一些与 133 个犬种类别重叠,我们仍然没有针对这些不重叠的特定类别的好的解决方案。事实上,我们有一个解决方案,它使用预训练模型中的知识,并可用于对所有 133 个狗品种进行分类。这是迁移学习。

3.用于犬种分类的迁移学习

幸运的是,可以使用已经在一个数据集中训练过的 CNN 来缩短在其他数据集中的训练。我们只需考虑两件事,新数据集的大小和新数据集与之前用于训练网络的数据集之间的相似度。对于这两个变量,我们有四种可能的情况,如图 3 所示。**

当新数据集与用于训练网络的数据集相似时,我们可以保留大部分层。如果我们没有太多数据,我们可以保留几乎所有图层,只需用新图层替换输出图层,以匹配新数据集中的类数量,如图 3 的场景 1 所示。

如果新数据集相似,但很大,我们可以保持卷积层不变,并替换所有完全连接的层。这种情况显示在图 3 的场景 2 中。可选地,我们可以在完全连接的层中选择每层相同数量的神经元,只要我们用随机数重置这些层的权重,并证明输出的数量与数据集中的类的数量相同。

当我们有一个不同于模型训练数据集的新数据集时,我们不能保留所有卷积层。我们必须替换一些最后的卷积层,因为这些层提取仅与用于训练模型的数据集中的类相关的高级特征。因此,我们应该提取与新数据集中的类更相关的其他高级要素。这种情况如图 3 的场景 3 所示。我们可以保留网络的架构,在卷积层的情况下,用相同数量的滤波器创建新层,在全连接层的情况下,用相同数量的神经元创建新层。输出图层必须与新数据集中的类数量相匹配。

图 3

我使用了在 ImageNet 数据集上训练的 ResNet50。新的数据集类似于 ImageNet,所以训练好的模型之前已经见过狗了。此外,新数据集有 8351 幅图像,这并不算小。使用一种叫做数据扩充的技术,我们可以转换我们数据集中已经存在的图像,以生成稍微不同的图像。使用数据扩充,我们可以有一个大约 5 倍大的数据集。在这种情况下,我们可以使用场景 2,大型且相似的数据集。**

为了训练新的光纤通道层,我需要用于喂养第一个光纤通道层的功能。这些特性被称为瓶颈特性。此名称是因为这些要素是从最后一个 Conv 图层中获得的,该图层具有最窄的要素地图。第一个 Conv 图层提取的要素地图较少,分辨率较高,而最后一个 Conv 图层提取的要素地图较多,分辨率较低。**

我们可以通过 Conv 层预处理数据集中的所有图像,以生成瓶颈特征并将其存储到文件中,从而节省时间。为了训练网络,我们必须从文件中读取瓶颈特征,并将它们馈送到 FC 层。从文件中读取所有瓶颈特征比通过 Conv 层提交所有图像要快得多。这样,我们节省了宝贵的时间,因为所有的数据集都迭代了很多次。

我训练过三种不同型号的 FC 层。这些模型如图 4 所示。
模型 A —第一个隐藏层是 GlobalAveragePooling2D 层,后面是输出密集层。
模型 B-该模型在 GlobalAveragePooling2D 和输出密集图层之间添加了一个下降图层,有 50%的下降几率。
模型 C —此模型在输出密集层之前添加了另一个密集和丢弃层,有 50%的几率丢弃。

图 4 — 培训中使用的三种 FC 模型。

所有模型在 50 个时期内被训练(在整个数据集上 50 次迭代)。训练和验证精度和损失如图 5 所示。

图 5 — 三种型号在 50 个周期后的性能。

所有模型都有非常相似的结果。模型 A 和模型 C 的准确率最高,均为 84.19%,但模型 C 的损耗稍好。迭代 50 次后的损耗和精度如下:
模型 A —精度:84.19%,损耗:0.5594。
B 型 —准确率:82.16%,损耗:0.5532。
C 型 —准确率:84.19%,损耗:0.5098。

注意训练和验证性能之间的差异是很重要的。模型 A 在训练中取得了非常好的结果,但是它不能被复制到验证中。这种差异是过拟合的良好信号,表明该模型在训练期间非常好,但它对以前从未见过的图像进行分类是不一致的。这表明该模型泛化能力较低。

模型 B 在训练和验证之间呈现更一致的结果。但是 C 型是他们中最好的。模型 C 在对以前从未见过的图像进行分类方面比对训练中使用的图像进行分类具有更好的结果。而且,C 型也做到了亏损最低。

4.用数据扩充微调 CNN

在上一步中,仅使用 ResNet50 中的瓶颈功能训练了 FC 层。为了微调网络,我将原来的 Conv 层连接到我刚刚训练的 FC 层,从而形成了一个完整的 CNN。

*def append_resnet(fc_model):
    # Load the pre-trained Conv layers from Keras
    ResNet50_convs = ResNet50(include_top=False, weights='imagenet')

    # Create a complete CNN joining the Conv and FC layers
    Resnet50_full = Sequential()
    Resnet50_full.add(ResNet50_convs)
    Resnet50_full.add(fc_model)return Resnet50_full*

训练继续进行,但是这次调整了整个 CNN 中的所有权重,而不仅仅是 FC 层。

在这一点上,我还使用了数据扩充来对数据集中的图像进行随机修改。数据扩充使用了以下参数:

*train_datagen = ImageDataGenerator(
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')valid_datagen = ImageDataGenerator(
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')*

在用数据扩充对三个完整的 CNN 模型进行了超过五个时期的训练之后,他们获得了下面图 6 所示的结果。

图 6 — 插入数据扩充和 5 个以上时期后三个模型的性能。

数据扩充的插入导致了性能的短暂下降,但是验证值在五个时期之后返回到先前的点。

图 7 — 插入数据扩充和 5 个以上时期后三个模型的性能。

这三个模型实现了非常相似的结果。从图上很难看出哪个是最好的型号。我们可以在下表中看到迭代 55 次后实现的精度和损耗:

模型 C 提供了最好的结果,具有最高的精度和最低的损失。考虑到这个模型也提供了最好的泛化能力,我只训练了模型 C 超过 10 个时期。

模型 C 在测试集中的最终准确率为 86.12%,这是以前从未见过的。

图像分类

结论

当我们只训练完全连接的层时,提取瓶颈特征有利于节省时间。

FC 层中增加的漏失层提高了模型的泛化能力。此外,添加第二个密集层和另一个丢弃层,不仅提高了网络的泛化能力,而且有助于模型实现更好的分类性能。

声明:Udacity 可能部分提供了此处展示的部分源代码。

使用深度学习概念的狗品种分类

原文:https://towardsdatascience.com/dog-breed-classification-using-deep-learning-concepts-23213d67936c?source=collection_archive---------11-----------------------

开发狗识别应用程序的想法

衍生作品: Djmirko ( talk ),黄拉拉新,神经迁移学习, CC BY-SA 3.0

这篇博文是 Udacity 数据科学家纳米学位计划 的一部分。

简介

世界犬类组织( FCI )目前列出了 300 多种官方认可的犬种。几千年来,人类已经成功创造了令人印象深刻的犬类表型多样性,以及它们忠实的四条腿朋友的一系列几乎不可思议的身体和行为特征。然而,除了犬学学者、养狗者和一些久经考验的爱狗人士之外,当被要求说出一只随机出现的狗的品种时,至少当它不是最受欢迎和最知名的品种如腊肠狗、德国牧羊犬或哈巴狗的代表时,大多数人都只是耸耸肩,表示无能为力。如果你是为数不多的觉得不能像犬类学家一样识别狗有点尴尬的人之一,你可能很高兴知道可能有一个技术解决方案。因为谢天谢地,深度学习和人工神经网络这一令人惊叹的领域为解决这种分类任务提供了强大的概念和方法。

在这个项目中,我们将使用深度学习概念开发狗识别应用程序的想法。该软件旨在接受任何用户提供的图像作为输入。如果在图像中检测到狗,它将提供狗的品种的估计。如果检测到人类,它将提供一个最相似的狗品种的估计。

我们的项目包括以下步骤,这些步骤将在这篇博文的后续部分详细介绍。

  • 第 0 步:导入数据集
  • 第一步:探测人类
  • 第二步:检测狗
  • 第三步:创建一个 CNN 对狗的品种进行分类(从头开始)
  • 第四步:使用 CNN 对狗的品种进行分类(使用迁移学习)
  • 第五步:创建一个 CNN 对狗的品种进行分类(使用迁移学习)
  • 第六步:编写你的算法
  • 第七步:测试你的算法

第 0 步:导入数据集

显然,为了能够建立一个旨在识别狗的算法,我们需要一些“狗数据”。很多。值得庆幸的是,为了这个项目,Udacity 提供了相当数量的狗图片,包括相应的品种标签。具体地,图像数据包括 8351 幅狗图像和 133 个单独的狗品种名称。

由于该应用程序有一个额外的任务,将最相似的狗品种分配给给定的人脸,我们还需要一个人脸数据集。Udacity 提供的数据集包括来自野生数据集中标记的人脸的 13233 张图像。

第一步:检测人类

这似乎是狗识别应用程序开发中有点令人惊讶的一步,但它的额外工作是将最相似的狗品种分配给给定的人脸。

为了检测图像中的人脸,我们将使用 OpenCV 实现的基于 Haar 特征的级联分类器。该分类器的方法基于 Haar-like features 的概念,由于其令人信服的计算速度而广泛应用于对象识别领域。

在实例化新的预训练分类器之后,图像被加载并转换成灰度。将分类器应用到图像中,我们得到了检测到的人脸的边界框。

使用 OpenCV 的级联分类器检测人脸的代码

以下是本项目中使用的野生数据集中的标记人脸在通过我们的级联分类器后的几个例子:

图片来源:野生标签脸,http://vis-www.cs.umass.edu/lfw/

评估人类探测器

现在让我们来看看分类器如何处理来自我们数据集的图片。我们将该算法应用于我们的 100 幅狗图像,并好奇探索其中分类器有趣地识别了人类内容的 12 幅图片。我们有点失望,因为在所描绘的狗的脸上几乎找不到任何奇怪和不可思议的人类特征,这些特征可能骗过了我们的算法

图片来源:Udacity 提供的狗狗图片数据集

相反,在我们的评估中使用的 100 个人类图片样本中,分类器在以下两个样本中遗漏了人脸:

图片来源:野外贴标签的脸,http://vis-www.cs.umass.edu/lfw/

尽管如此,我们的分类器似乎足够可靠,可以在我们的项目中尝试一下。

第二步:探测狗

现在我们有了一个相当不错的算法来检测图像中的人脸,我们当然希望为狗的检测建立一个类似的功能。不幸的是,目前 OpenCV 的级联分类器没有类似的“狗检测器”。因此,我们选择了另一种方法,采用一种在 ImageNet 的庞大图像数据库上预先训练好的图像分类模型。更具体地说,我们将使用高级深度学习 API Keras 来加载 ResNet-50 卷积神经网络,并通过该模型运行图像。对于一个特定的图像,网络预测总共 1000 个图像类别中每一个的概率。如果模型将最大概率分配给 118 个与狗相关的类别中的一个,我们将肯定的狗检测归因于图像。

下面的源代码列出了用于预处理图像数据并通过 ResNet-50 模型运行它们的函数。

评估狗检测器

ResNet-50 狗检测器在我们的图像数据集上表现如何?我们将用下面的源代码对此进行测试。

我们用我们的狗图像获得了令人信服的 100%准确性,但 Frank Solich 可能会担心唯一的狗,在人类图像数据集中发现的最具开创性的深度学习网络模型之一,在他的肖像中:

弗兰克·索利希,图片来源:野生的标签脸,http://vis-www.cs.umass.edu/lfw/

第三步:创建一个 CNN 来分类狗的品种(从头开始)

现在,我们将进入真正有趣的部分,解决应用程序的主要任务的实现,从狗的图像中辨别正确的狗品种标签。我们可以使事情变得简单,只需使用第二步中预先训练好的模型,并预测 ImageNet 数据集类别中定义的狗品种标签。当然,构建我们自己的解决方案更令人兴奋、有趣,也更有教育意义,所以让我们开始吧!在我们开始构建自己的分类器之前,先简单介绍一下卷积神经网络。

卷积神经网络(CNN)是一类主要用于图像分析的深度神经网络。在一定程度上,卷积网络的设计受到了哺乳动物大脑处理视觉印象的方式的启发。*移不变性和共享权重最常被引用来解释 CNN 在图像分析中相对于使用其他类型的神经网络的优势。卷积网络的体系结构涉及使用多个隐藏层,这些隐藏层对其输入执行数学卷积运算。

第一次尝试

Udacity 提供了一个 CNN 结构的典型示例,它建议在本步骤中使用以下模型。

因此,我们有一个输入层,图像数据馈入其中,在完全连接的“密集”层产生输出之前,共有三对卷积层和池层。卷积层由一组具有一定高度和宽度的滤波器组成,而汇集层的任务是降低输入的维数。通常,每个卷积层中的滤波器数量增加,而处理数据的维数减少。因为模型的性能通常随着深度的增加而增加,所以我们在 Udacity 提出的模型中增加了两个额外的阶段。

使用 Keras 库创建模型的源代码如下所示:

在产生一个输出之前,我们插入一个额外的脱落层,它随机地去激活一些神经元。丢弃层的使用是防止训练数据过度拟合的常用正则化方法。

最后,我们的第一个模型如下图所示:

CNN 从零开始(与 Netron 一起策划)

现在,让我们通过网络运行我们的训练集 30 次来训练我们的模型:

让我们来看看我们的训练在每个时期取得的进步:

我们可以看到准确性几乎呈线性增长,在训练结束时,我们的训练集获得了大约 23 %的过度拟合效果,这意味着我们的验证集的准确性明显落后,但不是那么多。我们用测试数据进行的额外测试给出了 16.5 %的准确度。

还不错,但是对于一个严肃的应用程序来说肯定不够准确,所以让我们看看我们是否能做得更好。

第二次尝试使用 AlexNet

现在我们要用 CNN 模特界的一个真正经典来再试一次。 AlexNet 是一个 CNN 模型,它在 2012 年 ImageNet 大规模视觉识别挑战赛中远远超过了竞争对手,并引入了一些开创性的新概念,如 ReLU 激活功能和使用脱落层来防止过度拟合。该模型的一般结构如下:

AlexNet(用 Netron 绘制)

让我们用 Keras 库实现一个 AlexNet 模型:

与第一次尝试一样,我们通过网络运行我们的训练数据 30 次,并取得了以下进展。

所以,哇,训练集的准确性确实在接*尾声时超过了我们第一次尝试的结果,但是,天哪,验证曲线发生了什么???我们显然是在处理一个过度拟合的问题。

第三次尝试。通过数据扩充解决过度拟合问题

除了使用 dropout 层,我们可以使用另一种流行的方法来控制我们的问题。数据扩充是一种通过应用随机变换(如图像旋转、图像移动、改变图像亮度和图像翻转)来增加训练集多样性的技术。所以让我们在下一次尝试中试试这个方法:

好了,现在让我们检查一下进度历史:

是的,现在看起来好多了,即使避免过拟合问题显然是以牺牲精度水*为代价的,所以我们的测试数据集只达到了 10.9 %。但是如果我们比较我们第一次和第三次尝试的两个图的轨迹,AlexNet 似乎有一个更陡峭的曲线,并且可能很快在其他时期超过我们第一次尝试的模型。

但总的来说,使用 CNN 模型的方法,即我们从头开始构建的方法,似乎非常复杂、乏味且耗时,这需要很大的耐心和大量的计算能力。所以,下一步我们来看看更好的方法。

第四步:使用 CNN 对狗的品种进行分类(使用迁移学习)

迁移学习背后的一般思想是这样一个事实,即向一个已经掌握特定领域基础知识的学科教授专业技能要容易得多。有很多神经网络模型已经专门研究图像识别,并在大量数据的基础上进行训练。我们现在的策略是利用这种预先训练好的网络,我们的计划可以概括如下:

  • 找到为一般图像分类任务预先训练的网络模型
  • 用预训练的权重加载模型
  • 删除“模型的顶部”,即具有完全连接的层的部分,因为模型的特定任务通常由网络的这一部分来定义
  • 通过预训练模型的卷积部分运行新数据。(这也被称为特征提取并且该步骤的输出也被称为瓶颈特征。)
  • 创建一个新的网络来定义手头的特定任务,并用上一步的输出(瓶颈特性)来训练它。

正如我们马上会看到的,我们用来填充瓶颈特性的模型结构通常非常简单,因为大部分训练工作已经由预训练模型完成了。在这个项目的第 4 步中,Udacity 为这一策略提供了某种蓝图,它已经将我们的图像数据集输入到预训练的 VGG16 模型(另一个用于图像分类的 CNN 模型领域的经典模型)中,并使输出作为瓶颈特征可用,我们现在可以将其输入到一个非常简单的训练网络中,该网络基本上只包含一个全局*均池层和一个最终的密集输出层。

下面的源代码加载瓶颈特性,为我们的特定分类任务定义顶层,并用瓶颈特性训练这些新层:

同样,让我们来看看进度历史:

除了快速的训练速度之外,我们还观察到在准确性方面的显著表现,并在我们的测试数据中实现了大约 75 %的准确性,尽管这是以明显的过拟合问题为代价的。

第五步:创建一个 CNN 对狗的品种进行分类(使用迁移学习)

我们现在将步骤 4 作为模板,使用迁移学习定义我们自己的 CNN。我们选择 InceptionV3 作为应该为我们的训练层提供特性的网络。Inception 是 ImageNet 数据集上的另一个高性能模型,它的强大之处在于,通过引入称为 inception 模块的子网,该网络可以设计得比其他模型更深入。

源代码看起来与步骤 4 中的代码非常相似:

为了防止我们在步骤 4 中观察到的过拟合问题,我们插入了一个额外的丢弃层,并在输出层之前添加了批量归一化。

正如我们从进度历史中看到的,我们仍然有一些过度拟合的问题,但是我们也注意到精度的另一个提高。我们的测试数据达到了 83 %的准确率。

为了使我们的模型更好,我们可以考虑以下选项:

  • 使用数据扩充来防止过度拟合
  • 向我们的简单训练模型添加层
  • 获取更多培训数据

但是现在,我们对最*一次尝试的结果非常满意,并在接下来的步骤中将它们用于我们将要编写和测试的算法中。

第六步:编写你的算法

因此,现在让我们收集前面步骤中的成果和发现,并编写一个算法,该算法获取一张狗或人的图像,并吐出一个狗品种以及该特定品种的 4 个样本图像。

第七步:测试你的算法

最后,让我们用一些测试图像来测试我们的算法。

杜宾犬图片来源:由 Udacity 提供的狗图片数据集

牧羊犬,图片来源:由 Udacity 提供的狗狗图片数据集

图片来源:Udacity 提供的狗狗图片数据集

结论

在这个项目中,我们开发了几种方法来开发识别狗品种的应用程序,并且我们通过应用迁移学习模型取得了最好的结果。我们在测试中获得了 83%的准确率。我们还学习了如何从零开始构建卷积网络,这是一项非常有教育意义的任务,尽管我们很快意识到还有更有前途的方法,特别是应用迁移学习。

然而,我们仍然看到未来进一步改进我们算法的几种选择:

  • 我们可以收集更多的训练数据。
  • 我们可以使用数据扩充来防止过度拟合。
  • 我们可以添加更多的层,使我们的模型更复杂,希望更强大。
  • 我们可以延长我们的训练时间,给训练增加更多的纪元。

但总而言之,我们测试的准确性水*,以及对特定样本图像的测试,表明我们已经有了一个可以在真实应用程序中使用的严肃模型。

这个项目的源代码是在一个 Jupyter 笔记本上用 Python 编写的,并利用了流行的深度学习库 TensorFlowKeras 。可以在对应的 github 库中找到。

Udacity 在这个中提供了一些源代码。

在 R 中做并报告你的第一次计划对比

原文:https://towardsdatascience.com/doing-and-reporting-your-first-planned-contrasts-in-r-ee77ff277088?source=collection_archive---------5-----------------------

如何用方差分析事后检验来检验你的方向假设

这是我们很多人都面临的情况:你刚刚进行了方差分析,你的结果是显著的…但是接下来呢?我们基本上知道有些事情正在发生,但具体是什么呢?哪些治疗有所不同?

这就是有计划的对比的用武之地。它们听起来比实际更复杂,而且它们是一种灵活的统计工具,使得这种方差分析事后检验非常有效。

在我开始之前,有一个小提示:在本教程中,我将只讨论正交对比…你不需要知道这是什么意思,以防你听说过这个术语,我们正在寻找它。

丹尼尔·利维斯·佩鲁西在 Unsplash 上的照片

加载数据集并运行方差分析

在本教程中,我们将使用薪水数据集。它包含了不同教授的工资数据。使用以下命令加载它。

df=Salaries

下一步我们将需要“car”包,所以如果您还没有安装这个包,请使用下面的命令安装它。如果您不确定是否已经安装了这个包,只需运行这个命令。

install.packages("car")

现在,我们想做的方差分析是看教授的排名对他们的工资有没有影响。我们还想考虑所有其他直观的重要变量…从技术上讲,这是一个协方差。我们运行下面的命令来获得输出。

library(car)aov1 = aov(salary ~ sex + rank + yrs.since.phd + yrs.service + discipline, df)Anova(aov1 ,type="III")

这会产生以下结果。

所以我们可以看到等级确实影响教授的薪水。但是具体怎么做呢?有计划的对比可以帮助我们找到更多这方面的信息。然而,有计划的对比需要你真正理解你感兴趣的自变量。

设置计划对比度

我们先来看利息这个自变量。“等级”包含什么。为此,运行以下命令来查看“rank”的级别

levels(df$rank)

这将产生以下输出。

在美国…这是一个美国的数据集…助理教授和副教授之间有很大的区别。副教授是教师的一部分,通常是终身教授。助理教授不是教师的一部分,通常也不是终身教授。有计划的对比可以帮助我们回答的一个问题是,“成为副教授对教授的薪水重要,还是成为教师的一部分重要?”…你看到我们在这里做什么了吗?我们正在使用数据中的隐含信息,以新的方式对我们的级别进行分组,并揭示关于该效果的真正潜在驱动因素的更多信息。基本上,我们在说…“我们知道有三个级别,但是我们如何将这些级别分组以揭示更多信息?”—我们正在对比各组数据。

在这种情况下,你通常会进行两种有计划的对比:首先,你会想看看成为教员是否会有所不同。第二,你会想看看教员之间的差异是否会产生影响。下面是我们试图实现的目标的图示。

我们借助使用特定符号的正交对比将这一点传达给 R。符号由四条规则组成:

  • 我们将零(0)用于从对比中排除的组。
  • 我们对治疗组使用负值(<0) for the baseline group.
  • We use positive values (> 0)。
  • 每个对比度中处理值的总和必须为零(0)。

这听起来并不容易,但是一旦你看到这个例子是如何进行的,就非常简单了。示意图中的对比将以如下方式传达给 R:

对比 1: 在第一个对比中,我们将 AssocProfProf 归为治疗状态。因此,它们都被赋予一个正值。为了简单起见,我们选择一个较低的值(1)。由于 AssistProf 现在是基线,需要为负,并且总对比度 1 需要加起来为零(0),我们需要将其赋值为 a -2。

对比 2: 在第二个对比中,我们只想看看终身职位之间的差异是否会影响薪酬。因此,我们通过将赋值为 0 来排除asst prof。我们选择将 Prof 作为治疗条件,将 AssocProf 作为基线条件……我们也可以将两者互换,但是方向的改变是危险的,因为当我们后来解释结果时可能会忘记它们。为了简单起见,我们保持方向不变(治疗是更高级的条件)。同样,为了简单起见,我们再次选择低值,并将处理条件 Prof 指定为 1。因此,基线条件 AssocProf 必须为 a -1,因为总对比度需要加起来为 0。

这正是我们向 r 传达指定对比的方式。

contrast1 = c(-2,1,1)
contrast2 = c(0,-1,1)

然后,我们告诉 R 将这些对比分配给数据集 df 中的变量 rank

contrasts(df$rank) = cbind(contrast1, contrast2)

为了检查对比度的分配是否正确,我们可以重复 contrast()命令,看看它们现在是如何保存在 r 中的。

contrasts(df$rank)

正如我们所看到的,它们已经被正确地实现了。所以现在我们可以继续分析了。

分析、解释和报告计划对比

我们通过重新运行之前运行的 ANOVA 命令来分析我们的对比。但是,因为现在 R 以对比的形式拥有了更多关于变量 rank 结构的信息,所以输出会有所不同。

aov1 = aov(salary ~ sex + rank + yrs.since.phd + yrs.service + discipline, df)

这一次,我们不想以 ANOVA 输出的形式访问信息,而是以回归输出的形式访问信息。因此,我们使用 summary.lm 命令来请求输出。

summary.lm(aov1)

可以看到,R 现在产生输出,其中变量 rank 的级别被替换为两个对比度。这两个对比都很明显,这意味着成为终身教授会影响教授的薪水,在终身职位上的晋升也会影响。

我们将以如下方式报告这一发现:

方差分析显示,在控制了性别、完成博士学位后的年数、服务年数和所从事的学科后,教授的级别对他们的工资有显著影响(F(2390)= 68.41, p < .001)。使用计划对比进一步调查教授级别对其工资的影响,发现与助理教授相比,成为教员(副教授或正教授)与工资显著增加有关, t (390) = 7.64, p < .001(双尾),而一旦成为教员,成为正教授而不是副教授与进一步增加有关, t (390) = 9.08,【T20

在“普通”公司做数据

原文:https://towardsdatascience.com/doing-data-in-a-normal-company-5db7c1602bcc?source=collection_archive---------41-----------------------

一份个人的诚实评论

彼得·基斯特曼Unsplash 上拍摄

我小时候想要的第一个合适的礼物是一台电脑,一台黑色的 MacBook,便宜的是塑料的,贵的是铝的。尽管我很难摆脱这个定义,但这让我成为了一名工程师,而不是我挂在房间墙上的硕士学位——我的意思是,真的有人还在做这个吗?在我硕士学位的最后一年,我决定转向数据,主要是因为传统计算机工程师工作(全栈开发人员?)到处给我的一些实习机会看起来并不完全像是我每天想做的事情。我想更有创造力,与不同的人和背景互动;最终将计算机科学的技能更多地作为一种工具,而不是一种非常具体的能力。到目前为止,事情进展得相当顺利,但我的工程背景和与该头衔相关的一些任务比我预期的要多得多,这让我重新考虑了一点关于数据工作实际意味着什么的浪漫而可能天真的想法。

我想更有创造力,与不同的人和背景互动;最终将计算机科学的技能更多地作为一种工具,而不是一种非常具体的能力。

我目前是荷兰一家快速发展的公司中许多不同数据相关问题的关键人物。我们非常受数据驱动,具有创新的思维模式和坚实的工程文化,但它不是一个在数据上花费数百万预算的科技巨头,也不可能雇佣拥有非常有限的惊人技能的伟大专家;一个正常的公司

我最初是一名数据科学家,在一个由数据科学家和数据分析师组成的团队中[1],很少关注改善数据基础设施。一年半后,当人们问我以什么为生时,我发现自己回答的是数据工程师(有时)。我觉得很有趣的是,这种转变并不是别人的决定,而主要是我的一系列技能的自然结果,是我在正确的时间找到了正确的地点。

网上有很多很有见地的文章描述了数据工程师在创业公司中的角色和当实际上是雇佣一个数据工程师的正确时间,然而可能更难定义的是 2020 年数据工程师的实际含义。如果你和这个行业的一些专业人士交谈,很难有一个清晰的画面。当然,有一些模式,没有人试图重新发明轮子,但与其他领域相比,不同的公司面临着非常不同的挑战,任务、技术堆栈和职责可能会有很大差异。成功找到工作的人通常都有扎实的计算机工程背景;有更多经验的人甚至有几年 T4 传统软件工程师的工作经验。他们现在都是云爱好者,如果他们愿意,可以非常容易地转换到开发运营职位。

就我个人而言,我注意到我们的数据架构还有改进的空间,我们有一个非常熟练的运营团队来学习概念和最佳实践。刚开始的时候并不容易,但是我的工科背景帮助我窃取了后者的一些知识和经验,应用到别的地方。在 K8s 集群上编写和调度 cron-jobs,在 Airflow 上编写 Dag,在 dbt 上执行 ETL 任务,这些都是就业市场为其创造了特定角色的事情,但在一家规模不断扩大的公司的早期阶段,一名优秀的软件工程师没有做不到的事情,并且很可能最终会这样做。数据工程师只是专注于数据的软件工程师,就像传统工程师负责产品的特定部分(支付、信息等)一样。由于这是一个相当新的领域,并且仍在不断发展,数据工程师很可能还需要管理他们的基础设施,这需要更广泛的技能组合,这使得优秀的数据工程师更难找到,而且肯定更昂贵。

数据工程师只是专注于数据的软件工程师,就像传统工程师负责产品的特定部分(支付、信息等)一样。

在没有专门团队的情况下长时间处理大量数据的公司可能是现在给数据工程师带来更多挑战的公司,而托管 ETL 和云数据仓库的爆炸式增长为年轻公司的工作提供了很多便利,这些公司可以从第一天起就有可靠可靠的东西。

改进数据流和数据架构的整体质量应该是一种愿望,而不是一种需求,因为为非(严格地)技术人员设计的托管解决方案在达到一定规模后就开始变得不够了。如果你发现自己需要雇佣一名数据工程师,那可能就太晚了,而且这已经影响到了交付。将工程技能添加到数据团队中,不仅使流程更加坚实可靠,而且经常会打开新的可能性和用例,为公司增加价值。数据工程师可以被视为倍增器,利用他的技能和引入新技术可以让数据利益相关者做得更多或更容易。

数据工程师可以被视为倍增器,利用他的技能和引入新技术可以让数据利益相关者做得更多或更容易。

尽管增加了数据基础设施的复杂性和所用工具的多样性,但这只是发挥了一些潜力。为了让公司抓住这种产生实际价值的潜力,需要所有数据利益相关者拥有正确的技能组合(或心态)来迎接挑战,并开始自己使用这些工具。在一个不断增长的数据团队中,要求每个成员都具有相当广泛的技能,并且要求数据分析师在不*凡的水*上了解 Python,这大大加快了交付速度。

在当今的就业市场上,对数据科学家来说,拥有广泛(有时甚至是庞大)技能的要求更加重要。只要看看对机器学习工程师空缺职位的要求,你就会意识到,这些人必须负责在生产中部署机器学习所需的所有阶段,除了工程相关任务之外,还要有良好的数学和统计知识。不太可能在半小时的时间间隔内完成从 LSTMs 到 TCP 服务器的工作面试。我们的团队也在朝这个方向发展,寻找新人总是一件困难的事情,即使拥有计算机科学背景很有帮助。这里的问题是,对于一个中等规模的公司来说,拥有专业领域非常狭窄的全职数据科学家是不值得的。投资人工智能是一个非常冒险的决定,有许多不同的变量难以预见。雇佣独角兽让这个过程更容易管理,也更有可能成功。

投资人工智能是一个非常冒险的决定,有许多不同的变量难以预见。雇佣独角兽让这个过程更容易管理,也更有可能成功。

作为个人偏好,我仍然最喜欢的工作部分是与建模和机器学习实验相关的部分,基本上是我梦想登陆数据时希望做的事情。然而,在一个成长中的公司的小团队中,尽快交付价值是很重要的,最终做了大量的工程工作,只是为了有机会继续做这种事情。在另一个层面上,作为一名工程师,我意识到我是多么喜欢建造可以工作的东西,我是在实际工作的时候发现这一点的。如今,身处数据行业,因为它的挑战性,让你可以两者兼得,经常改变关注点和任务,降低厌倦或过于习惯你正在做的事情的风险(也是技术方面的)。如果我看着我现在的每一天,它充满了几个月前我真的不想做的事情,但我现在是一个狂热的爱好者和内在的驱动者。如果这在很大程度上归功于我工作的这家伟大的公司是真的,那么这个领域奖励员工的方式也是真的,因为在技术领域没有其他人能做到这一点。

[1]一个月前,我和我的一位同事进行了一次谈话,他希望转换研究数据。她希望对这个世界有一个快速入门,并简要介绍一个适当的数据团队必须扮演的所有角色,主要是谁做什么。前几天,我花了一些时间来定义数据科学家和分析师之间的区别,以及在哪个抽象层次上需要数据工程师。最后我对她说的是,分析师更关心过去,而科学家更关心未来。当然,这是一个口号,但离现实并不远。机器学习的大领域,其知识可能是这两个轮廓之间的边界,主要与建模有关,从数据(过去)中学习,以便对未来的、看不见的样本产生影响,这些样本具有在报告或普通数据分析中找不到的味道。

使用 Python 的内置统计库进行数据科学研究

原文:https://towardsdatascience.com/doing-data-science-with-pythons-built-in-statistics-library-72cfb2663074?source=collection_archive---------43-----------------------

python 内置统计库之旅

手动计算组中值

让代码在本地运行,然后看着它在生产中失败,这是我们都能体会到的。尤其是当生产环境不完全在我们的控制之下时(例如:AWS Lambdas,Elastic Beanstalk…)。

出于这个原因,我相信除非必要,否则不要引入依赖。如果一个标准的库可以实现一个结果,就没有必要引入一些花哨的东西。

虽然大多数数据科学家都热衷于 Scipy,但 Python 在其标准库中包含了许多统计函数。问题是这是否足够。

让我们浏览一下 Python 的标准统计库。我们将导入一个数据集来使用,然后遍历statistics中的函数。

设置

导入统计库本身。

import statistics

然后导入我们将要使用的数据集,并将其放入数据帧中。数据帧与statistics无关,但让我们更容易看到。

导入 sklearn 的葡萄酒数据集。

import pandas as pdfrom sklearn.datasets import load_wine
dataset = load_wine()df = pd.DataFrame(dataset['data'], columns=dataset['feature_names'])
df.head()

功能

*均

算术*均值。一个集合中值的总和,除以该集合中值的个数。虽然它是最广为人知的,但它只是一套价值观中心的一个衡量标准。

如果数据不*衡,也可能会产生很大的误导。例如,让我们比较“苹果酸”在数据集中的分布及其*均值。

round(
    statistics.mean(df.malic_acid),2
)
#=> 2.34

df.hist('苹果酸')

请注意*均值是如何被高端的一些异常值向上倾斜的。

调和*均值

思考调和*均值的一种快捷方式是将其视为保守*均值,为较低的输入值赋予额外的权重。

在评估机器学习模型时,我们一直使用调和*均值。f1 分数是精确度和召回率的调和*均值。

在精度为 0.65、召回率为 0.8 的模型评估场景中,我们可以使用harmonic_mean来计算 f1 分数。

precision = 0.65
recall = 0.8round(
    statistics.harmonic_mean([precision, recall]),2
)
#=> 0.72

也就是说,如果我们一开始没有使用 sklearn,我们就必须编写自己的函数来计算精度和召回。

中位数

中位数是一组有序数据的中间值。

中位数很有趣,因为它不会因为一个集合中的几个大值或小值而向上倾斜。由于这个原因,我一直认为除了算术*均值之外,看一下也是很重要的。

Median 返回具有奇数个值的集合的中间数,如果该集合具有偶数个值,则取两个中间值的*均值。

li = [-3,-1,0,1,2,5,100]
statistics.median(li)
#=> 1li2 = [-3,-1,0,1,2,5,100,101]
statistics.median(li2)
#=> 1.5

让我们再来看看“苹果酸”,这样我们就能看出*均值和中间值的区别。

round(
    statistics.median(df.malic_acid), 2
)
#=> 1.87

作为参考,*均值为 2.34。

中值下限

几乎与中位数完全相同,但如果集合中的值为奇数,则采用中间较低的数字。

中值高

如果集合有奇数个值,则取中间较高的数。

中位数分组

查找连续类的中值,其中每个类的宽度等于间隔的大小(默认情况下为interval=1)。

下面的例子用手来说明。

我在上面举例说明了一个对应于我们在下面使用的函数的数据。

statistics.median_grouped([1, 3, 3, 5, 7], interval=1)
#=> 3.25

请注意,使用该函数比我们自己计算要容易得多。

方式

返回集合中最频繁出现的数据点。

li = ['cat', 'dog', 'dog', 'fish']
statistics.mode(li)
#=> 'dog'

总体标准差

对总体中数据分布的度量。

如果数据分布很广,该值将很大,如果数据围绕一个点分组,该值将很小。它是以方差的*方根来计算的。

round(
    statistics.pstdev(df.alcohol),2
)
#=> 0.81

0.81 告诉我们数据高度集中。如果我们把它形象化成柱状图,看到酒精浓度完全在 11 到 15 之间,那就更明显了。

df.hist('酒精')

总体方差

数据传播的另一个衡量标准。

但是请注意,报告数据的标准偏差稍微更常见,因为它与*均值更密切相关。

round(
    statistics.pvariance(df.alcohol),2
)
#=> 0.66

样品标准偏差

除了我们使用n-1而不是N作为分母之外,它的计算几乎与总体标准差完全相同。可汗学院有一个很棒的视频介绍我们为什么要这么做,这里是。

我们在计算样本而不是总体的标准差时使用这个。

round(
    statistics.stdev(df.alcohol[:10]),2
)
#=> 0.58

采样离散

我们计算样本而不是总体的方差。n-1 vs N在这里同样适用。

round(
    statistics.variance(df.alcohol[:10]),2
)
#=> 0.33

结论

我们在statistics中有一些有用的函数,但是很明显numpypandas把它打得落花流水。也就是说,理解 Python 开箱即用的能力并没有坏处。

不是每个计算统计数据的人都在做数据科学,对于一个应用程序来说,均值和标准差可能已经足够了。

也就是说,Python 3.8 增加了一些我没有在这里介绍的新功能,所以谁知道他们将来会增加什么。

在 Twitter 上做赠品

原文:https://towardsdatascience.com/doing-giveaways-on-twitter-a5adc02d1ac0?source=collection_archive---------35-----------------------

使用 Twitter API 和 Python 随机绘制转发者

澳门图片社Unsplash 上拍摄的照片

Twitter 是一个分享内容和进行推广的绝佳*台。我已经用它发了几次我的书——《T4——机器学习图书营》。在这篇文章中,我将告诉你我是如何做到的,以及如何使用 Python 和 Twitter API 来简化这个过程。

特别是,这个职位包括:

  • 在 Twitter 上做赠品
  • 使用 Twitter API 获取转发推文的人的列表
  • 计划作业
  • 随机抽取获奖者

我们开始吧。

赠品活动

这个想法很简单:你免费赠送一些东西。这是你的追随者可能会喜欢的东西。例如,它可以是一本书或一门课程。

为了得到它,参与者需要转发它——有时,还需要关注你。

一个免费推文的例子

这是吸引新粉丝和传播你的作品的好方法。就我而言,我想让更多的人知道机器学习图书营——我目前正在写的这本书。

管理此类赠品活动的最简单方法是使用 Twitter API,并以编程方式处理所有事情。

Twitter 开发者 API

Twitter 开发者 API——运行赠品的最简单方式

要使用 Twitter API,您需要注册一个应用程序。打开https://developer.twitter.com,登录进入应用页面。到达后,点击“创建应用程序”按钮。

然后按照说明去做,这很简单。

要创建应用程序,只需按照说明进行操作

点击“创建”按钮后,就可以开始了。

要获得转发者列表,我们只需对status/retweeters/ids进行 API 调用。

有了这些,接下来的步骤似乎就简单了:

  • 创建推文
  • 让比赛持续几天
  • 使用 API 获取转发者列表
  • 随机抽取获胜者
  • 通过 DM 向获奖者表示祝贺

不幸的是,获得转发者名单并不像看起来那么容易。让我们来看看为什么和如何真正做到这一点。

获得转发

上面的算法有一个问题:使用 API 只能得到最后 100 个转发者。不更。没有办法在一个请求中获得超过 100 个,也没有办法对结果进行分页以获得另外的 100 个。

不幸的是,API 只返回最后 100 个转发者

但是有一个方法可以解决它:定期点击 API 并保存结果!

因此,我们的方法如下:

  • 创建推文
  • 设置一个定期作业,将最后 100 个转发者保存到一个文件中
  • 让比赛持续几天
  • 将所有保存的结果汇总到一个列表中
  • 从名单中随机抽取获胜者
  • 通过 DM 向获奖者表示祝贺

接下来,我们将看到如何使用 API 来获取转发者列表。

使用 Python 获取转发者

现在让我们使用 Twitter API 来获取最后的转发者。我们将使用 Python 和请求库。

如果您没有请求,您可以通过运行

pip install requests

为了能够使用 API,我们首先需要进行身份验证。为此,我们需要 API 密钥和 API 秘密密钥。你可以通过应用程序的设置来获取它们。

要获取 API 密钥,请进入“应用详情”→“密钥和令牌”

一旦我们有了密钥,我们就可以使用它们进行身份验证:

import requestskey = '<KEY>'
secret = '<SECRET>'auth_url = '[https://api.twitter.com/oauth2/token](https://api.twitter.com/oauth2/token)'
data = {'grant_type': 'client_credentials'}
auth_resp = requests.post(auth_url, auth=(key, secret), data=data)
token = auth_resp.json()['access_token']

结果,我们得到一个令牌——一个我们需要包含在每个请求中的字符串。

让我们用它来获得转发者:

tweet_id = '1235296848627273735'url = 'https://api.twitter.com/1.1/statuses/retweets/%s.json?count=100' % tweet_idheaders = {'Authorization': 'Bearer %s' % token}
retweets_resp = requests.get(url, headers=headers)
retweets = retweets_resp.json()

retweets 变量包含最* 100 个 retweets 的详细信息。

结果是最后 100 个转发者的列表

回复中有很多信息,比我们需要的多得多。我们只需要每个转发者的昵称,也就是他们的 Twitter 账号。我们来摘录一下:

retweeters = [r['user']['screen_name'] for r in retweets]

现在唯一要做的就是将结果保存到一个文件中。

为了避免意外覆盖旧文件,我们需要确保我们的输出文件有一个唯一的名称。实现这一点最简单的方法是在文件名中添加当前时间戳。

让我们开始吧:

from time import timet = int(time())with open('results/retweeters-ids-%s-%s.txt' % (tweet_id, ts), 'w') as f_out:
    for r in retweeters:
        f_out.write(r)
        f_out.write('\n')print('done')

就这样——现在我们可以获得最后 100 条转发,并将结果保存到一个文件中。你可以在这里看到完整的代码。

我们将代码保存到一个文件中,并安排它定期运行。

安排它

因为我们只能获得一条推文的最后 100 次转发,所以我们需要定期运行这个脚本,每次都将结果保存到一个文件中。

最简单的方法是使用Cron——Linux 和 macOS 上可用的基于时间的任务调度程序。如果你使用 Windows,有一个类似的工具叫做“任务调度器”,你可以用它来运行周期性的任务。

让我们配置 Cron 每小时运行一次我们的作业。为此,我们将使用以下 Cron 表达式:

30 * * * *

表示“每小时 30 分钟执行一次该命令”

为了调度它,我们需要向 crontab——Cron 的设置文件——添加一行。我们可以通过在终端中键入以下命令来实现:

crontab -e

现在我们添加下面一行:

30 * * * * python /home/ubuntu/retweeters-script.py

用 nano 编辑 crontab

最后,保存它并退出编辑器。如果你使用 nano 进行编辑(像我一样),你可以按 Ctrl+X 退出。 Vim 有点棘手。

要验证 crontab 是否已更新,请运行

crontab -l

这项工作已经安排好了,所以我们可以让竞赛进行几天。

随机抽取

几天过去了,比赛结束了,我们想选出获胜者。

在这段时间里,我们收集了许多带有转发者的文件,现在我们需要把它们放在一起。这很容易做到:我们只需一个接一个地加载文件,并将内容放入一个集合中:

from glob import globretweeter_files = sorted(glob('results/retweeters-ids-*.txt'))all_retweeters = set()for f in retweeter_files:
    with open(f, 'r') as f_in:
        retweeters = [line.strip() for line in f_in]
        all_retweeters.update(retweeters)

运行后,all_retweeters 包含转发您的推文的用户列表。

抽取获胜者很容易:

  • 将转发者放入列表中
  • 洗牌吧
  • 选择顶部

让我们来实现它:

from random import shuffleall_retweeters = list(all_retweeters)
shuffle(all_retweeters)
winners = all_retweeters[:12]for i in winners:
    print('@%s' % i)

抽奖的幸运赢家

现在是宣布获胜者的时候了!

祝贺获胜者!

并开始通过直接消息发送后续步骤的信息。

我希望这篇文章对你有用。别忘了在 Twitter 上关注我的最新动态!

[## 阿列克谢·格里戈里耶夫

阿列克谢·格里戈里耶夫(@Al_Grigor)的最新推文。OLX 集团首席数据科学家。对#机器学习感兴趣…

twitter.com](https://twitter.com/Al_Grigor)

使用 Python 做统计作业:分析分类数据

原文:https://towardsdatascience.com/doing-your-statistics-homework-with-python-part-1-b0d1f939e11?source=collection_archive---------73-----------------------

同时提高你的统计和编程水*。

Unsplash 上由黄圣贤拍摄的照片

在我教学的最后一年,我同时教授三门 AP 系统课程——AP 统计学和 AP 计算机科学原理在那一年对我来说都是新的,但我在前一年已经教了 AP 计算机科学 A。我冒了一次险,花时间学习如何用 Python 做统计,试图在我的两个预科生之间建立一个重叠。最终,我得到了回报:我找到了新的激情,现在正在从事数据科学方面的职业。

这篇博客是致力于使用 Python 从头开始解决基本的 AP 风格的统计问题的一系列独立文章中的第一篇。我会尽量少用专门的库。重要的是要记住,只有部分统计管道可以(或者应该)自动化,计算特定值只是解决问题的一个步骤——解释和应用结果才是最终目标。许多学生倾向于沉迷于数字运算,以至于看不到更大的图景。通过用代码自动化计算,我们可以专注于那些计算实际上告诉我们什么。

请记住,这篇文章不是对 Python 的介绍,也不是对统计学的介绍。相反,它是一个融合两者的介绍,以增强您对两者的理解。它可以被学生、老师或自学者使用。

分析单个分类变量

这里有一个涉及分类变量的 AP 统计问题的例子:

例题:分析分类变量的分布

这是在过山车数据库中找到的过山车的全球分布

  1. 根据这张表,世界上总共有多少过山车?
  2. (a)创建这些数据的相对频率表。用百分比给出你的答案,四舍五入到小数点后一位。你的百分比加起来是 100 吗?为什么或为什么不?
  3. 北美或南美有百分之多少的过山车?
  4. 构建这些数据的条形图和饼图。不要忘记包括标签和描述性的标题!

我们将单独解决这些问题。我们的方法将是创建一组函数,我们可以用它们来解决这种类型的问题,而不仅仅是这个问题。我们的目标不是解决这个单独的问题,而是理解看起来像这样的问题一般是如何解决的。

首先,我们需要某种对象将我们的数据与我们的级别联系起来。我们可以用两个list对象来完成这个任务(这绝对没有错),但是我将利用我最喜欢的 Python 对象之一:一个dict。出于各种原因,字典是很好的,许多库比如pandas允许你在构造更复杂的对象比如DataFrame时传递字典。

这是我们将要使用的字典:

coasters = {'Africa':90, 'Asia':2649, 'Australia':27, 'Europe':1329, 'North America':905, 'South America':175}

特别是,我喜欢如何将value(频率)与key(大陆)直接联系起来。请记住,随着我们的进展,我们的实现将使用dict的方法和属性,因此如果您不熟悉这种类型的对象,您可能希望在继续之前查看一下 [dict](https://www.w3schools.com/python/python_dictionaries.asp) 类型

在这一点上,值得检查并反复检查我的字典中的值是否正确——如果它们是正确的,这是我们唯一需要做的一次。(相比之下,你在计算器中输入一长串数字,却发现漏掉了其中一个数字。)

类似于表是如何分成左列(洲名)和右列(过山车数量)的,我们的字典很自然地把洲分成keys,频率分成values,表中的每一个“行”都是自己的键值对。

进入我们的第一个问题!

1.世界上总共有多少过山车?

要手动解决这个问题,我们可以查看我们的表格,将右侧列中的所有数字相加:

90 + 2649 + 27 + 1329 + 905 + 175 = 5175

不幸的是,这种方法不能推广到其他问题。如果给我另一个计数表,我将不得不拿出我的 TI-84 Plus(以真正的 AP 统计方式)并从头开始输入所有的数字,希望我不会出现任何打字错误或意外错过某个数字。对于这么小的数据集,这可能不是问题,但随着类别数量的增加,我用胖手指拨弄数字键盘的可能性也会增加。

相反,我们可以在 Python 中编写一个函数,该函数将接受我们的 dictionary 对象(表示上表),并返回右列中计数的总和(由字典中的values表示):

def total_values(dictionary):
    return sum(dictionary.values())

现在我们可以处理任何类别在左列(我们的keys)而计数在右列(我们的values)的表。

让我们看看当我们将coasters字典传递给 total_values 函数时会得到什么:

print('There are', total_values(coasters), 'rollercoasters in the world.')

输出:There are 5175 rollercoasters in the world.

2.(a)创建这些数据的相对频率表。用百分比给出你的频率。

为了解决这个问题,我们需要做以下事情:

  1. 计算世界上过山车的总数(幸运的是,这是问题 1)。
  2. 将每个类别中的值除以世界上过山车的总数。
  3. 将每个值乘以 100。
  4. 将输出格式化成一个漂亮的表格。

我们已经写了一个函数来处理#1,它返回我们将在#2 中使用的值。对于#3,我想保持函数的灵活性,所以我给自己一个选项来打开和关闭百分比。我还希望能够指定精度,因为问题明确地告诉我要舍入到特定的小数位数。

def relative_frequencies(dictionary, percents=False, precision=1):
    total = total_values(dictionary)
    rel_freq = {} for key, value in dictionary.items():
        rel_freq[key] = value / total if percents:
        rel_freq[key] = round(rel_freq[key] * 100, precision) return rel_freq

首先,我们依靠我们写的函数找到valuestotal。接下来,我们创建一个新的字典rel_freq来保存相对频率。对于每个键-值对,我们将向rel_freq添加相同的键,但是原始的value除以total。如果percent已被指定为True,我们将这些比例转换为给定precision(或默认为 1)的百分比。将这种方法与必须在计算器上反复手动除法进行比较。

接下来,我们有一个函数将打印我们的相对频率表。花大量时间编写这个函数相当于通过用尺子和彩笔仔细画一个表来拖延你的统计作业所需要的繁重的智力劳动。显然,这是我今天所能做的最好的投资。

def display_dictionary(dictionary, title='Table Title', left_header='Category', right_header='Values'):
    max_len = max(max(len(value) for value in dictionary.keys()),  
                  len(left_header))
    spaces = {key:(max_len — len(key)) for key, value in dictionary.items()}
    header = left_header + ' '*(2 + max_len — len(left_header)) + '| '+ right_header
    bar = '-' * max(len(title), len(header))

    print(title + '\n' + bar + '\n' + header + '\n' + bar)

    for key, value in dictionary.items():
        print(key, ' '*(spaces[key]), '|', value)

对于问题 2 的(b)部分(查看百分比之和是否等于 100),我们可以再次重用我们的total_values函数。

3.北美或南美有百分之多少的过山车?

为了完成这项任务,我们将创建一个函数,对列表中对应于类别的值进行求和。

def sum_from_list(dictionary, categories):
    return sum(dictionary[cat] for cat in categories)

尽管默认情况下这个函数并不完全符合我们的要求(它只是对值求和,并不返回百分比),但是我们可以通过仔细考虑如何与它交互来回答我们的问题:

sum_from_list(relative_frequencies(coasters, percents=True, precision=2), ['North America', 'South America'])

4.使用你在第 2 部分中找到的相对频率,构建一个条形图和一个饼图。不要忘记包括标签和描述性的标题!

现在,使用 Python 比手工做这些真正的优势是:漂亮的图表。学习如何用 Python 制作图表实际上是引导我发现matplotlib并打开数据科学大门的原因,所以这个函数在我心中占有特殊的位置。

我们将在一个Axes(1 行,2 列)排列的Figure上绘制这两个图。左边的Axes是条形图,右边的Axes是饼图。深入研究每一行代码是一个值得自己发表许多博客文章的主题,所以我只展示代码,没有太多评论。特别是,我编写了这个函数来接受任何dictionary(假设包含频率)、图表的title、分类变量的名称、y 轴的标签以及频率是否应该转换为相对频率。

def display_bar_and_pie(dictionary, title, categorical_name, ylabel='Frequency', relative_frequency=False, percent=False):
    if relative_frequency:
        rel_freqs = relative_frequencies(dictionary)
        categories = list(rel_freqs.keys())
        values = list(rel_freqs.values())
        ylabel = 'Relative Frequency' if percent:
            ylabel += '(%)'
            values = [val * 100 for val in values] else:
        categories = list(dictionary.keys())
        values = list(dictionary.values()) # create two subplots
    fig, (ax_bar, ax_pie) = plt.subplots(nrows=1, ncols=2, figsize=(15, 5)) # create the bar chart
    ax_bar = sns.barplot(x=categories, y=values, ax=ax_bar)
    ax_bar.set_xlabel('Continent')
    ax_bar.set_xticklabels(categories, rotation=45)
    ax_bar.set_ylabel(ylabel)

    # create the pie chart
    ax_pie.pie(values, labels=categories, autopct='%1.1f')
    ax_pie.axis('equal')
    plt.suptitle(title, size=24)
    plt.show()

我们做到了!现在我们准备彻底上交这个问题:

print('1\. There are', total_values(coasters), 'rollercoasters in the world.\n')print('\n2\. a.')
display_dictionary(dictionary=relative_frequencies(coasters, percents=True, precision=2), title=’Relative Frequencies of Rollercoasters by Continent’, left_header=’Continent’, right_header=’Percent of Rollercoasters’)print('\n2\. b. The total of the percents is {}%. If this does not equal 100, it is due to rounding errors.\n'.format(
    total_percents(relative_frequencies(coasters, percents=True, precision=2))))print('\n3\. {:.1f}% of rollercoasters are in North America or South America.\n'.format( sum_from_list(relative_frequencies(coasters, percents=True, precision=2), ['North America', ‘South America’])))print('\n4\. Below are a bar chart and pie chart of the relative frequencies.')display_bar_and_pie(coasters, 'Rollercoasters of the World', 'Continent', relative_frequency=True, percent=True)

虽然编写这段代码可能比简单地手工处理数字要花更多的时间,但是我们现在有代码可以为我们解决这种类型的问题。笔记本里有一个奖金问题,可以在我的 github 上找到

享受你的数字运算!

乳腺癌检测中的域适应

原文:https://towardsdatascience.com/domain-adaptation-in-breast-cancer-detection-4d04da1bc7b?source=collection_archive---------27-----------------------

图像来源

探索 CNN 图像分类在整个行业中的应用

作者:Arjun Rao、David Kinman、David Sterling Owen、、Katie Grant 和 Pengdi Xia

概述和项目目标

在美国,癌症是导致死亡的主要原因之一,仅次于心脏病。2017 年,美国有* 60 万人死于癌症,全球经济负担估计为 1800 亿美元[A,B]。在所有癌症中,乳腺癌是第二常见的,也是女性中最常见的。组织学通常是患者癌症治疗过程中的转折点。如果常规乳房 x 光检查(X 射线)发现异常肿块,将进行活检以确定诊断。然而,检查和评估活检切片所需的漫长时间可能会给患者带来巨大的压力。一种能够识别癌组织并降低误诊率的有效算法可以让患者更快地开始治疗并改善患者的总体结果。

卷积神经网络(CNN)的使用先前已经被探索用于癌症应用。然而,基于 CNN 的模型的一个共同弱点是它们的脆弱性和对训练数据的依赖性。部署模型时,假设训练和测试数据来自同一个分布。这在医学成像中可能是一个问题,因为相机设置或染色化学品的年龄等因素会因设施和医院而异,并可能影响图像的颜色。这些变化对人眼来说可能不明显,但它们可能会影响对 CNN 重要的特征,并导致模型性能下降。为此,开发一种能够适应域间差异的健壮算法是很重要的。

在过去,已经举行了几次比赛来开发用于从组织学载玻片检测癌症的算法,例如 ICIAR 系列(BACH) [C]、乳腺癌组织病理学数据库(BreakHist) [D]和 Kaggle 组织病理学癌症检测[E]。在之前的课程中,我们团队的一名成员使用 ICIAR BACH 数据集开发了一个癌症分类模型[F]。在这个项目中,我们将探索使用领域适应来开发一个更强大的乳腺癌分类模型,以允许在多个医疗机构部署模型。

背景

根据癌症护理中心的说法,“癌症是体内异常细胞不受控制的生长。当身体的正常控制机制停止工作时,癌症就会发展。在美国,八分之一的女性预计会在一生中患上乳腺癌。2020 年,预计将有超过 30 万例乳腺癌被确诊,每 38 人中就有 1 人因此死亡。

组织学用于评估患者的身体组织并识别癌细胞。在评估之前,组织样本被染色以突出组织的不同部分。苏木精和伊红是常见的染色剂,因为它们能有效地突出异常细胞团。苏木精是一种碱,与嗜碱性结构结合,如细胞核,将它们染成紫色,曙红将嗜酸性结构染成粉红色,如细胞质[H]。在理想情况下,不同的颜色和结构足以识别组织异常。然而,染色组织的确切色调会因年龄、染色化学品浓度、湿度和样本大小等变量而异(图 1)。这些颜色的变化可能会混淆 CNN 的模型。因此,我们的目标是设计一个对组织染色中的颜色变化具有鲁棒性的 CNN 模型。

图一。薄厚组织切片的颜色差异[I]。

数据

对于这个项目,我们使用了来自 ICIAR BACH 2018 案例竞赛[C]和 BreakHist 数据库[D]的数据。每张图片都由几名医学专业人士审核后贴上标签。样本图像如图 2 所示。

图二。来自 BreakHist 数据库的示例图像。

BACH 数据集提供了 400 幅图像,分为四类:正常、良性、、原位和侵入性。良性肿瘤是一种异常的细胞团,对患者的风险极小。往往认定了,就不管了[J]。T4 原位肿瘤是一组尚未扩散到全身系统的侵袭性细胞。一般来说,它被认为是一种恶变前的癌症,随着时间的推移会变成恶性的[J]。侵袭性癌症是最严重的癌症类型,因为它已经转移到身体中其原始位置之外。对于这种分析,我们将正常和良性标记视为健康组织,而将原位和浸润性标记视为癌组织。

BreakHist 数据集提供了大约 8000 个良性和恶性肿瘤的图像,这些图像是在多个缩放级别(40x、100x、200x 和 400x)下拍摄的。这些组中包括的不同类型的肿瘤如下所列。

  • 良性肿瘤:腺病、纤维腺瘤、叶状肿瘤和管状腺瘤
  • 恶性肿瘤:癌、小叶癌、粘液癌和乳头状癌(PC) [K]。

预处理

为了开发一个健壮的域适应模型,我们选择使用 BreakHist 数据作为我们的训练集。由于幻灯片图像的大小/放大倍数通常在行业内没有标准化,因此多个缩放级别可作为模型稳健性的良好起点。

为了减少计算时间,所有图像都被缩放为 224x224 像素。对于 CNN 模型,随着输入图像大小的增加,权重和节点的数量呈指数增长。不幸的是,当整个幻灯片图像从原始尺寸缩小时,许多信息可能会丢失。因此,在模型复杂性和准确性之间有一个折衷。

图 1 和图 2 展示了污渍中存在的各种颜色。为了使我们的模型可以跨域使用,我们为训练集中的每个原始图像实现了九种颜色增强。这些颜色增强改变了图像的颜色和强度。此外,我们对每个转换后的图像进行了一系列 3 次旋转,以说明相机定位和组织样本方向的差异。这些预处理步骤将我们的训练集的大小从 7,909 个图像增加到 285,000 个图像。

图 3。训练集中的单个图像的图像增强摘要。

培训和建模

基线模型

为了理解领域适应的优势,我们首先在原始 BreakHist 数据集上训练 CNN 模型,并在 ICIAR 数据集上测试该模型。这个初始模型允许我们理解一个模型在应用到不同领域时的准确性,而无需进行设计考虑。

如前所述,BreakHist 数据集包含大约 8,000 张图像。每个图像从其原始尺寸缩小到 224x224 *方的图像。因此,CNN 的输入是所有 224x224 像素的 RGB 值。ResNet34 模型架构经过十个时期的训练;并记录从原始 BreakHist 数据集中提取的验证集上模型的准确性。为了确定该模型的准确性是否适用于另一个领域,该模型在来自 ICIAR 数据集的 400 幅图像上进行了测试。

接* 1

为了提高我们在第二个领域检测癌症的能力,我们使用颜色标准化技术和旋转增加了 BreakHist 数据。处理完所有这些数据后,我们有了大约 285,000 张图片。对于这么多的图像,运行一个时期需要 7 个多小时。为了找到一个计算上更可行的解决方案,我们将训练数据下采样到一个由 25,000 幅图像组成的*衡集。

一个新的 CNN 在 25,000 个增强图像上被训练。所有其他模型参数,如 ResNet34 架构和历元数,都保持与以前相同。该模型在验证集上的准确性被确定。然后,在 ICIAR 数据集上测试该模型,以确定增强图像是否提高了我们在不同领域检测癌症的能力。

方法 2

为了提高模型精度并进一步探索领域适应性,ICIAR 测试集以与 BreakHist 训练集相同的方式进行预处理。对测试集中的每个图像执行颜色增强,以产生原始图像的九个变体。九种变化通过 CNN 模型,并对其输出进行多数投票,以确定原始图像的预测标签。然后通过比较多数投票标签和真实标签来确定模型的准确性。

结果

基线模型

测试的第一个模型是我们的基线模型,它允许我们量化领域适应的优势。当该模型在包含来自与训练集相同来源的数据的验证集上测试时,该模型达到了 89.31%的准确度。这表明当在它被训练的相同领域中使用时,该模型在诊断癌症方面是成功的。然而,该模型随后在来自不同领域的数据上进行测试,并且仅产生 45%的准确性。这种准确性比随机猜测差,表明设计考虑是必要的,以产生可用于多种医疗保健设置的模型。对这些不良结果的可能解释包括扫描仪和染色技术的差异。该测试的混淆矩阵如图 4 所示。该模型似乎没有过度预测癌症。

图 4:未增强/预处理的结果

接* 1

先前的研究和期刊出版物表明,域适应可以提高乳腺癌分类器的准确性。为了测试这个想法,我们在增强图像上训练了一个新模型,试图使该模型对颜色和方向的变化更加鲁棒。当该模型在不同领域的数据上测试时,准确率为 55.25%。尽管这个领域中的性能仍然明显低于原始领域中的性能,但它确实证明了领域适应允许对基线模型进行一些改进。此外,我们可以观察到模型预测的巨大变化。基线模型倾向于过度预测没有癌症。然而,这个新模型有相反的问题,并且过度预测癌症。这个模型的混淆矩阵如图 5 所示。

图 5。方法 1 的测试结果。

接* 2

为了使训练域和测试域更加相似,使用与训练集相同的增强对测试图像进行预处理。增强的测试图像然后通过来自方法 1 的 CNN 模型。不幸的是,在这种方法下,模型精度下降到 53.75%。这个模型的混淆矩阵如图 6 所示。

图 6。方法 2 的测试结果。

学习和未来工作

这个项目的目标是了解医学领域算法领域适应所带来的挑战。之前的研究表明,深度学习模型可能会有效地减轻医生缓慢而单调的工作,但在现实世界中实施之前必须经过充分的训练和测试。从我们的模型中可以看出,验证准确性(经过最小的预处理/扩充)是 89%,但是在不同的领域中使用时,验证准确性迅速下降到 45%。这突出了领域适应的挑战。一旦我们在设计中考虑到了域的变化,我们的模型的测试精度就提高到了 55.25%。这表明,通过更多的数据、准备和训练,我们可以提高模型的准确性。

然而,在该模型可用于诊断癌症之前,进一步的改进是必要的。由于项目限制,我们将训练集从 285,000 张图像减少到 25,000 张图像。此外,每个图像的尺寸缩小到 224x224 像素。这些修改可能限制了我们模型的性能,特别是在这个领域,因为色阶看起来非常类似于人眼,并且缩小可能导致太多的信息丢失,特别是数据集之间。未来的工作应该探索使用更多的可用数据,并且在寻找精细细节时,可以对颜色安排和大量相同颜色如何影响模型和各种类型的 CNN 过滤器进行更多的研究。这种分析的另一个局限性是我们无法解释模型错误的可能原因,因为组织学切片的解释需要一定程度的专业知识。对于更大规模的解释,有一个病理学家来识别潜在的趋势并提供见解将是有帮助的。

也可以使用其他方法来潜在地提高模型精度。例如,可以根据来自多个领域的数据来训练模型。我们希望这个模型能够展示出改进的性能,因为过度适应特定源特有的模式会得到缓解。在乳腺癌的情况下,这将必须由医院提供,并且由于 HIPAA 代码,这通常不是免费提供的。

该项目表明,CNN 模型可能非常脆弱,领域适应至关重要,并强调了对稳健性的需求,尤其是在医疗领域,决策可能对患者的生活产生重大影响。我们希望这种模式在未来能够得到改进,以提高乳腺癌诊断的准确性,并为癌症患者带来更好的结果。

来源:

A.https://www . CDC . gov/nchs/fastats/leading-causes-of-death . htm

B.http://phr ma-docs . phr ma . org/sites/default/files/pdf/08-17-2010 _ economic _ impact _ study . pdf

C.【https://iciar2018-challenge.grand-challenge.org/

D.https://www . ka ggle . com/ambarish/break his

E.https://www.kaggle.com/c/histopathologic-cancer-detection

F.https://medium . com/@ the purple blobs/breast-cancer-detection-the-purple-blobs-6ac 40984 CEB 4

G.https://www.cancercenter.com/what-is-cancer

H.http://histology.leeds.ac.uk/what-is-histology/H_and_E.php

一、https://www . Leica biosystems . com/knowledge-pathway/he-basics-part-4-trouble shooting-he/

J.https://www . webmd . com/a-to-z-guides/良性-肿瘤-病因-治疗#1

K.https://web . INF . ufpr . br/vri/databases/breast-cancer-organism-database-break his/

使用 Xception 和 VGG16 模型进行域适配

原文:https://towardsdatascience.com/domain-adaptation-with-xception-and-vgg16-models-993744b06d31?source=collection_archive---------61-----------------------

当开始人工智能算法之旅时,有必要问自己两个基本问题:

  1. 我们试图解决的问题是什么?
  2. 如何建立一个模型来帮助解决这个问题?

要回答第一个问题,唯一的限制因素是我们的想象力和可用于训练模型的数据的可用性。对于第二个问题,选择哪种模式将在很大程度上取决于以下因素:我们正在解决的问题、可用的资源和我们可支配的时间框架。

这在一个例子中得到最好的展示。让我们假设我们正在尝试创建一个算法,帮助根据照片正确地分离废物。当谈到选择算法本身时,它将取决于所提出的问题。在我们从图像中提取适当的特征后,我们可以使用随机决策森林支持向量机。我们也可以使用卷积神经网络,它直接对图像数据进行操作。我们可以自己设计这个网络的架构。然而,考虑预先训练的模型是值得的,这将允许节省大量时间。为了解决这个问题,我决定采用预先训练的人工神经网络进行图像分类。这在实践中看起来如何?让我们一步一步地经历这个过程。

数据分析和准备

我决定用的数据集可以在这里找到: 垃圾分类 。它包含了分为 6 类的垃圾照片:纸板、玻璃、金属、纸张、塑料和混合垃圾。最后一个类别包含的项目照片可以大部分分配给其他 5 组。为此,我们将其排除在进一步分析之外。下面是一个图表,显示了每个班级可用的照片数量。

在准备数据集的过程中,一个非常重要的阶段是将数据集分成至少两个子集:训练子集和验证子集。更好的做法是创建三个独立的数据集:训练、验证和测试。在这种情况下,在测试集上获得的结果是有代表性的,并且显示了该系统对于新的、以前未见过的照片的真实有效性。在我的例子中,60%的照片用于训练,20%用于验证集,另外 20%用于测试集。

以下是每个班级的照片样本。每张照片都是 512 x 384 像素。当使用现成的神经网络时,将集合中图像的大小调整到网络接受的输入数据的大小是非常重要的。在 除了 网络的情况下,输入层的大小是 299×299,而在 VGG16 网络的情况下,这个大小是 224×224。因此,在训练模型之前,我们需要缩放我们的图像。

模型的准备和训练

为了解决给定的问题,我使用了两种流行的网络架构: VGG16Xception 。我选择的两个模型都在 ImageNet 集合上进行了预训练,该集合包含属于 1000 个类的对象的图片。因此,负责输入图像分类的输出层具有 1000 个输出。在我们正在分析的问题的情况下,输出层的大小应该是 5。下面是允许根据我们的数据集调整预训练模型的代码。

由于用于训练模型的数据集有限,我决定使用数据扩充来扩展它。下面是负责训练所选模型的代码片段。

在选定车型的训练中,我使用了早停。其工作方式是,如果来自验证集的照片的识别效率在一定数量的时期内没有增加,则训练被中断。使用这种方法可以降低模型过度拟合数据的风险。下面是训练集和验证集的学习曲线。很明显,在这种情况下,Xception 网络做得更好,在从验证集中识别照片时实现了超过 80%的效率。

创建的解决方案的有效性

正如我之前提到的,最好是在没有参与我们模型训练的新数据集上确定我们模型的实际有效性。因此,下面我将展示通过让模型处理测试集而获得的结果。这个收藏包含 480 张照片。结果证实了这样的结论,即在这种情况下,基于预训练的例外网络的模型做得更好。实现了 83% 的效率,几乎比基于 VGG16 架构的模型高出 10 个百分点。

VGG16: ACC = 74%

例外:ACC = 83%

总结

本文展示了如何使用预先训练好的网络架构,并将其应用于我们想要解决的特定问题。简要讨论了数据分析和准备的过程、预训练模型对个人需求的适应性以及评估创建的解决方案的有效性的方法。源代码可在 这里

这是一系列文章中的第一篇,旨在为想要开始人工智能算法冒险的人提供帮助。我邀请您在 博客 上关注我们的条目,在 【李】【FB】上关注我们的公司简介,并订阅我们的时事通讯。

深度学习需要什么来更好地检测新冠肺炎

原文:https://towardsdatascience.com/domain-expertise-what-deep-learning-needs-for-better-covid-19-detection-56cdeefde564?source=collection_archive---------49-----------------------

现实世界中的数据科学

这个世界可能不需要另一个神经网络,但它需要与那些在第一线的人进行咖啡聊天。

照片由欧文·Unsplash 拍摄

到目前为止,你可能已经看过一些关于深度学习如何帮助检测新冠肺炎的文章。特别是,通过分析患者的计算机断层扫描(CT)扫描,卷积神经网络(CNN)已经被研究为黄金标准聚合酶链式反应测试的更快更便宜的替代方案。这并不奇怪,因为 CNN 在图像识别方面非常出色;许多地方有 CT 扫描仪,而不是新冠肺炎检测工具(至少在最初)。

尽管 CNN 在图像识别任务中取得了成功,如 ImageNet challenge,但它真的能帮助医生检测新冠肺炎吗?如果可以,它能做到多准确?众所周知,CT 扫描是敏感的,但不是针对新冠肺炎的。也就是说,新冠肺炎几乎总是产生 CT 扫描可见的异常肺模式。然而,其他肺炎也可以产生同样的异常模式。强大且有时神奇的 CNN 能解决这个模糊问题吗?

我们有机会自己回答这些问题(与我的同事和顾问 A/P 陈)。我将带你看一个新冠肺炎分类器,这是我们为 2020 年 QSR 数据挑战建造的入口。如果您不熟悉 CNN,或者想重温 CNN 的主要功能,我强烈建议您首先阅读这篇文章:

[## 卷积神经网络:它与其他网络有何不同?

CNN 有什么独特之处,卷积到底是做什么的?这是一个无数学介绍的奇迹…

towardsdatascience.com](/a-math-free-introduction-to-convolutional-neural-network-ff38fbc4fc76)

另外,如果你想亲自动手,你可以从这个 Github repo 中获得所有代码和数据。

关键要点

  1. 使用预训练的 CNN 的迁移学习可以在新冠肺炎分类上实现非常强的基线性能(85%的准确度)。
  2. 然而,需要基于领域专业知识的特征工程和适应来将 CNN(或其他 ML 方法)提升到医学上令人信服的水*。

挑战是什么?

新冠肺炎·疫情改变了世界各地的生活。据世卫组织报道,这是截至 2020/09/26 的现状。

CT 扫描已被用于筛查和诊断新冠肺炎,尤其是在拭子检测资源严重缺乏的地区。这项数据挑战的目标是使用胸部 CT 扫描诊断新冠肺炎。因此,我们需要建立一个分类模型,它可以根据患者的胸部 CT 扫描尽可能准确地将患者分类为 COVID 或非 COVID

提供什么?

提供相对偶数的 COVID 和非 COVID 图像来训练模型。比赛还要求,模型的训练与提供的数据必须少于一个小时。

  • 训练数据集:251 个 COVID 图像和 292 个非 COVID 图像
  • 元信息:患者信息、严重性、图像标题等。

所有质询数据均取自公共数据集

模型性能

我们先来看看结果,好吗?

用一组独立的测试数据对训练好的模型进行评估。这里你可以看到混淆矩阵。总体准确率约为 85%,灵敏度略高于特异性,即真阳性率>真阴性率。

履行

值得注意的是,挑战在于区分 COVID 和非 COVID CT 扫描,而不是 COVID 和正常扫描。事实上,可能有一些不属于其他肺炎患者的 ct 扫描(特异性问题)。以下是 COVID 和其他肺炎 CT 扫描的一个示例:

新冠肺炎引起的肺炎患者的 CT 扫描。资料来源:SJin,y,Cai,l,Cheng,z 等人/ CC BY

非细菌性肺炎的 CT 扫描。来源:詹姆斯·海尔曼,医学博士/ CC BY-SA

训练-验证分割

我们保留 20%的数据进行验证。由于一些连续的图像来自同一个患者,它们往往彼此相似。也就是说,我们的很多数据都是而非独立。为了防止数据泄漏(训练数据的信息溢出到验证数据),我们保留原始图像序列,并使用最后 20%作为验证集。拆分后,我们有两对数据:

1.X_train,y_train
2。x 值,y 值

x 是 CT 扫描的列表,y 是二进制标签的列表(0 表示非 COVID,1 表示 COVID)。

数据扩充

数据扩充是在训练数据中包含更多随机变化的常用方法。这有助于防止过度拟合。对于图像相关的学习问题,增强通常意味着应用随机几何(例如,裁剪、翻转、旋转等。)和外观变换(例如,对比度、边缘滤波、高斯模糊等。).我们使用tf.keras.Sequential创建一个管道,其中输入图像通过以下操作进行随机转换:

  1. 随机水*和垂直翻转
  2. 在[-5%,5%]*2pi 范围内随机旋转度数
  3. 高度随机放大 5%
  4. 随机翻译 5%
  5. 随机对比度调整 5%

使用预先训练的 CNN 作为主干

我们不能从零开始建立 CNN。对于只有少量训练图像的图像相关问题,建议使用预训练模型作为主干,并在其上进行迁移学习。选择的型号是 EfficientNetB0 。它属于谷歌研究人员提出的名为高效网络的模型家族。EfficientNets 是当前用于计算机视觉任务的最先进的 CNN 之一。他们

  1. 需要数量少得多的参数,
  2. 在 ImageNet 上取得了非常高的准确率,
  3. 很好地转移到其他图像分类任务。

EfficientNets 和其他众所周知的预训练模型可以很容易地从tf.keras.applications加载。我们首先导入预先训练的 EfficientNetB0,并将其用作我们的模型主干。我们删除了 EfficientNetB0 的原始输出层,因为它是为 1000 类分类而训练的。此外,我们冻结了模型的权重,以便它们不会在初始训练期间更新。

# Create a base model from the pre-trained EfficientNetB0
base_model = keras.applications.EfficientNetB0(input_shape=IMG_SHAPE, include_top=False)
base_model.trainable = False

用我们的模型包裹它

导入 EfficientNet 后,我们可以用它来包装我们的分类模型,从而解决我们的问题。你可以把 EfficientNetB0 想象成一个训练有素的特征提取器。最终模型具有:

  1. 输入层
  2. EfficientNetB0 基本型号
  3. *均池层:通过*均操作来池化信息
  4. 丢弃层:将输入的百分比设置为零
  5. 分类层:输出不一致的概率

我们也可以使用tf.keras.utils.plot_model来可视化我们的模型。

我们可以看到:

  1. 输入和输出形状中的?是为样本数预留的位置,模型还不知道。
  2. EfficientNetB0 位于输入层之后。
  3. 最后一层(分类层)的输出为 1 维:非 VID 的概率。

训练我们的模型

公共数据预训练:为了帮助 NetB0 更有效地适应 COVID 与非 COVID 图像分类,我们实际上已经在另一个公共 CT 扫描数据集上训练了我们的模型。希望在 CT 扫描上训练模型将允许它学习我们的新冠肺炎分类任务的特定特征。我们不会深入到公共数据训练部分,但是这个过程本质上和我下面要展示的是一样的。

迁移学习工作流程:我们使用一个典型的迁移学习工作流程:

  1. 阶段 1(特征提取):固定 EfficientNetB0 的权重,仅更新最后一个分类层的权重。
  2. 阶段 2(微调):允许一些 EfficientNetB0 '权重也进行更新。

你可以在这里阅读更多关于工作流程的信息。

关键配置:我们使用以下指标和损失函数:

  1. 指标:评估模型性能
  • 二元精度
  • 假阳性和真阳性
  • 假阴性和真阴性

2。损失函数:引导梯度搜索

  • 二元交叉熵

我们使用Adam优化器,对于这两个阶段,学习率被设置为[1e-3, 1e-4],训练次数被设置为[10, 30]。两阶段训练迭代两次。

训练历史:让我们把训练历史形象化;

在这里,你可以看到,在我们允许一些层的效率网络更新后(在纪元 10 之后),我们在分类准确性方面获得了显著的提高。最终的训练和验证准确率在 98%和 82%左右。

它在测试数据上的表现如何?

我们可以从包含 105 个非 COVID 图像和 98 个 COVID 图像的相同数据报告中获得一组测试数据。让我们看看训练好的模型在他们身上表现如何。下面是使用sklearn.metrics.classification_report的测试数据的结果分析:

分类报告

这是 ROC 曲线:

什么是正确和错误分类的 CT 扫描?

我们可以深入分类结果,看看哪些是正确识别的,哪些是错误识别的。发现的潜在模式可以用来帮助进一步改进模型。请看这个 jupyter 笔记本中的图片。从这些图像中,我们看到:

  1. 真阳性有明显的异常模式,肺结构保存完好。
  2. 很多真阴性都是完全黑肺(无异常模式)。
  3. 很多假阳性的肺边界不清楚。

关键是,对于像我这样的非医学人士来说,许多 COVID 和非 COVID 图像看起来是一样的。当一些图像具有不清楚的肺边界时,模糊甚至更严重。看起来我们的 CNN 也很难区分这些图像。

我们将何去何从?

从上面的结果,我们可以看到,一个预训练的 CNN 可以适应实现一个真正强大的基线性能。然而,深度学习模型(或任何其他模型)单独能够实现的目标有明显的限制。在这种情况下,计算机视觉研究人员和医学专家需要以一种有意义的方式进行合作,以便最终模型既有计算能力又有医学可靠性。

我们可以从几个方面改进模型:

  1. 肺部分割:对每一幅图像进行处理,只保留 CT 扫描的肺部区域,例如这里的
  2. 更复杂的迁移学习设计:例如,参见多任务学习或监督域适配
  3. 集合模型:这似乎是一个普遍的信念,尤其是在 Kaggle 用户中,构建一个集合模型几乎总是会给你额外增加几个百分点的准确度。

以上就是我们 CNN 新冠肺炎 CT 扫描分类!谢谢大家!

原载于https://yang xiaozhou . github . io

领域专业知识—为什么它对数据科学家很重要?

原文:https://towardsdatascience.com/domain-expertise-why-is-it-important-for-data-scientists-2d6a406d544d?source=collection_archive---------17-----------------------

追求纯粹的可预测性不应该是数据科学家的唯一目标。

马丁·比约克Unsplash 上的照片

领域专长是对特定领域的知识和理解。作为数据科学家,您可能在各种各样的行业工作,每个行业都有自己的复杂性,只能随着时间的推移逐渐了解。

举个简单的例子,看看这些不同行业的单词:

行业一

损失率、综合比率、转换率、价格弹性、价格优化、交叉补贴、关税、业务组合、超额、损耗索赔

行业 B

赔率,差点,长赔率,劣势,优势,庄家

行业 C

订单簿,套利,空头,夏普比率,数量加权*均价格,时间加权*均价格,阿尔法,贝塔

行业 D

漏斗分析、群组分析、用户细分、留存分析、点击率、推荐引擎

行业 E

基因组、临床/表型、药物代谢动力学和其他分子数据

照片由理查德·博伊尔Unsplash 上拍摄

他们看起来眼熟吗?你能猜出每组单词来自什么行业吗?

如果答案是肯定的,你可能已经在那个领域有了一些专业知识!

(向下滚动到本文底部,了解他们是什么行业。)

请注意,A 组是其中最长的列表。原因很简单,我在这个行业工作了很多年,在这个行业中我有更多的专业知识。😂

这些只是术语。它们是用来让你在业外人士面前显得聪明的,或者根据《牛津词典》的说法,它们是:

特定职业或群体使用的,其他人难以理解的特殊词语或表达。

这些话别人确实很难理解,除非你恰好在那个行业工作。

从交流的角度来看,抛开所有的笑话,我们应该避免在向外人介绍时使用行话,或者至少先简单解释一下。永远不要假设人们知道他们的意思,否则你可能会很快失去他们的兴趣。

另一方面,我们也可以将行话视为高度浓缩的领域知识。例如,在两个简单的词后面加起来的比,我们有这些概念:**

  1. 综合比率=损失率+费用率
  2. 所有这些比率的共同点是“溢价”
  3. 损失意味着索赔
  4. 费用是指分销费用(佣金)和运营费用(人工、办公室租金等。)
  5. 所有这些比率都可以在承保期、事故期或会计期进行计算
  6. 索赔可以是再保险和/或一般恢复的净额或总额

行业 A** 中,这些概念每天都被整个组织的人(包括管理岗位上的人)使用。**

一个从未在这个行业工作过并且对这些概念毫无头绪的数据科学家可能很难(至少在最初)有效地工作。了解这些概念有助于数据科学家:

  • 了解数据
  • 了解业务目标
  • 问正确的问题并提出要解决的问题
  • 通过“说他们的语言”与决策者有效沟通
  • 使用相关标准衡量预测模型的成功

你可能会争辩说,拥有或没有领域知识的人都赢得了比赛。

如果你有领域知识,你可以做一些与问题背景相关的特定特性工程,并获得超越他人的优势。

另一方面,您也可以(或者有时不得不)放弃领域知识,采用纯软件工程方法并赢得竞争,特别是当数据需要匿名时,从而阻止了领域知识的使用。查看第一名获奖者对 Porto Seguro 安全驾驶员预测的解决方案。

在这场比赛中,你的挑战是建立一个模型,预测司机在下一年提出汽车保险索赔的概率。(来源:kaggle.com)

然而,我相信对纯粹预测性的追求不应该是数据科学家的唯一目标。

kaggle 中的数据科学与现实世界中的不一样。定义业务目标怎么样?与决策者有效沟通?了解数据是如何收集的?这些问题在 kaggle 竞赛中被隐藏了起来,但在现实世界中为一个组织工作时却非常重要。

还有,考虑一下这个。目前,许多数据科学工作涉及软件开发技能,例如纯超参数调优技能。在 5-10 年的时间里,随着机器学习基础设施的改善和自动化机器学习的兴起,许多繁重的工作将会消失。

一个伟大的数据科学家的与众不同之处在于他的领域知识——能够证明你对这个行业了如指掌,你会说这门语言,并且你可以通过帮助找到正确的业务问题来帮助企业实现目标。

对这些技能的需求不会消失。

答案:

答:保险;b:投注;c:量化交易 D:市场营销 E:基因组学

家庭暴力 Covid19 的阴影疫情

原文:https://towardsdatascience.com/domestic-violence-the-shadow-pandemic-of-covid19-2db1167a1988?source=collection_archive---------61-----------------------

使用人工智能技术和数据分析来寻找封锁和家庭暴力之间的相关性。

政策措施对弱势群体的影响

为了防止 Covid19 的传播,许多政府已经采取了严格的措施,如关闭边境,实行全国封锁,并建立隔离设施。虽然这些措施可以确保认真遵守社会距离,但它们可能对经济产生间接影响,并对人民的福祉产生不利影响,特别是弱势群体。

为了帮助政府做出数据驱动的政策决策,以有效应对 Covid19 等流行病, Omdena 为人工智能专家、数据科学家和领域专家提供了一个支持*台,以便他们可以研究 Covid19 政策措施对弱势人群的影响。本文描述了这一挑战的许多方面之一的结果,重点是 Covid19 对家庭暴力的影响。

这项任务的目标是更好地控制家庭暴力,评估问题的严重程度。为此,使用了不同的数据源,包括新闻文章、政策数据、移动趋势和家庭暴力搜索率。调查结果表明,家庭暴力问题可能比新闻中提到的一些关键数字所显示的要严重得多。此外,对行动的限制和严格实施封锁可能进一步加剧了这一问题。可以说,家庭暴力是疫情的一个阴影,理解这一问题的严重性并确保对幸存者和弱势群体的补救和支持是不可或缺的。

家庭暴力——疫情越来越大的阴影

联合国妇女署(T2)最*将针对女性的暴力事件的增加称为“日益增长的阴影疫情”。作为 Covid19 政策措施的结果,许多受害者发现自己因封锁措施而接*施虐者。如下图所示,全球求助热线电话和家庭暴力报告的数量急剧上升。这突出表明,迫切需要反思先前存在的和日益增多的家庭暴力事件,并提高基层组织和社区的认识,以提供帮助和支持。

关于 Covid19 和家庭暴力的信息图,改编自联合国妇女署。

影子疫情的规模——新闻报道

新闻中充斥着家庭暴力的报道和案例,以及在疫情期间家庭暴力的激增。三月初,新闻报道了中国家庭暴力的增加。与去年同期相比,湖北省二月份报告的病例数量增加了两倍。几周后,世界各地都出现了类似的文章。

为了首次掌握这种阴影疫情的重力和传播,使用了约 80,000 篇 Covid19 相关新闻文章的数据集。这个数据集是使用 GDELT 查询相关文章和新闻-请提取内容而创建的。所述数据集已被用于奥姆德纳艾疫情挑战赛的不同分析。为了识别与家庭暴力相关的新闻文章,基于与家庭暴力相关的关键词过滤语料库。总共有 1,500 篇文章与 Covid19 和家庭暴力有关,揭示了两者之间的联系。

基于 Covid19 和家庭暴力相关文章建模的其中一个主题的词云。

Covid19 与家庭暴力相关的文章

为了评估家庭暴力相关新闻文章子集的相关性,使用 gensim 进行 LDA 主题建模。模拟了三个主题,其中一个清楚地说明了所考虑的子集涵盖了家庭暴力。本题的词云如图。

一段时间内 Covid19 和家庭暴力相关新闻文章的数量。

与家庭暴力有关的文章绝对增加

与 Covid19 和家庭暴力相关的新闻文章数量在欧洲实施首批封锁措施(2 月底)几周后开始增加。

家庭暴力相关新闻文章相对于 Covid19 相关新闻文章。

相对增长

家庭暴力相关文章的增加趋势可以用 Covid19 相关文章的总体增加来解释。为了研究家庭暴力这一主题是否在讨论中变得更加突出,图表显示了家庭暴力相关文章占 Covid19 相关文章总数的比例。可以观察到一种上升趋势,这表明在疫情爆发后,家庭暴力问题变得更加突出。

影子疫情的规模——搜索率

新闻中提到的数据通常是摘要形式,类似于联合国妇女署的信息图中显示的关键数字。为了更详细地掌握阴影疫情的范围和大小,使用了不同的数据集:

  • 政策数据: 【牛津新冠肺炎政府应对跟踪报告(OxCGRT) ,覆盖 152 个国家采取的政策措施(2020 年 5 月 8 日访问)。
  • 移动数据:
    谷歌新冠肺炎社区移动报告,显示了 132 个国家移动模式的百分比变化(2020 年 5 月 8 日访问)。该数据与 2020 年 1 月 7 日至 2 月 7 日之间的移动模式相关( _rel )。为了限制随机性,应用了 7 天(1 周)的移动*均( _ma )过滤器。
  • 搜索数据: Google Trends 数据,表示某个话题随时间的搜索趋势(2020 年 5 月 8 日访问)。为了得到搜索率的百分比变化 ( _rel ),这个日期也是相对于基线期(1 月 3 日-2 月 13 日)而言的。为了消除随机性,对谷歌趋势数据应用了 14 天(2 周)的移动*均过滤器( _ma )。

分析的重点是所有三个数据集中的国家,这些国家有足够的 Google Trends 数据可用。强加了在至少 50%的考虑时间段(1 月 3 日-5 月 8 日)内数据可用的条件。这确保了分析的广泛性,包括总共 53 个国家。

一个人正在寻求帮助能够访问互联网对能够提供帮助的社会组织具有一定程度的信任 的情况下,搜索趋势数据被认为与研究问题的规模相关。显然,后两个条件在不同的国家并没有达到全世界所期望的水*。除其他外,这反映在人类发展数据中——例如,可以访问互联网的(女性)人口的百分比。因此,在考虑结果时,应该牢记这些条件、注意事项和细微差别。

此外,使用搜索率有一个明显的优势。受害者寻求帮助和接受帮助预计包括几个步骤;需要采取的每一个后续步骤都需要更多的勇气。最基本的步骤可能是浏览网页,寻找处理家庭暴力和寻求帮助的方法。 因此,搜索率数据可能比家庭暴力报告数量更准确地反映了实际问题的规模,因为搜索率可能是受害者寻求援助的第一步。

政策措施、流动性和家庭暴力搜索率之间的相关性

分析的第一步是研究数据集中不同要素之间的相关性。法国的相关图如下所示。可以观察到工作场所流动性家庭暴力搜索率之间的高度负相关(-0.95)。不出所料,工作场所流动性与政府实施的关闭工作场所政策高度相关。

政策、移动性和搜索率数据集(法国)的不同功能的关联图。

政策措施、流动性和搜索率的长期趋势(法国)。

在图中,随着时间的推移,工作场所流动性和家庭暴力搜索率的趋势被可视化。这两个变量之间的负相关关系表现为工作场所流动性的下降,同时家庭暴力搜索率上升。与基线相比,搜索率几乎翻了一番(增长 100%)。这表明,随着工作场所流动性的下降以及人们发现自己被困在家里,搜索与家庭暴力有关的信息的发生率增加了。

回归模型量化流动性对家庭暴力搜索率的影响

回归模型用于评估工作场所流动性和家庭暴力搜索率之间关系的大小和重要性。

流动性对家庭暴力搜索率影响的回归模型结果(法国)。

散点图中的直线显示了法国案例研究回归模型的输出。流动性和家庭暴力之间的关系是显著的,斜率表明流动性每降低 1%,家庭暴力搜索率就增加 1.4%。

下面列出了前 10 名后 10 名国家的模型结果。在十大国家中,流动性下降与家庭暴力搜索率的急剧上升相关。在排名垫底的 10 个国家中,观察到了相反的趋势:流动性和家庭暴力同时下降。为了进一步研究和解释不同模型的结果,下一节显示了前 10后 10 国家类别中前六个国家的单独地块。

流动性下降与家庭暴力增加之间存在密切关系的国家

显示了前 10 个国家中前 6 个国家的个别数字。这些国家的流动性下降和家庭暴力增加之间有着密切的关系。

  • 除了日本之外,在所列举的每个国家中,搜索率的峰值都翻了一倍甚至两倍。
  • 虽然日本的系数比较高,但是搜索率峰值‘刚好’60%。这是因为流动性的下降相对有限,可能是因为这个国家的封锁措施不太严格。
  • 越南表现突出,家庭暴力搜索率达到峰值,增长了基线的三倍多。本条也强调了越南社会距离背景下的家庭暴力问题,指出与 2018 年和 2019 年相比,需要庇护的人数翻了一番。
  • 德国法国比利时、南非的数字清楚地表明,随着流动性下降,家庭暴力搜索率呈上升趋势。

国家说明流动性下降和家庭暴力增加之间的关系

倒数 10 个国家中最后 6 个国家的数字如下所示,显示出流动性和家庭暴力之间的关系。

  • 首先,澳大利亚的情节很突出,在二月底家庭暴力有了很高的增长。澳大利亚家庭暴力的突然增加被认为是这一时期发生的森林大火的结果。这篇文章也表达了这种关系:'森林大火的隐藏后果:家庭暴力的激增风险【T3 ' '
  • 南韩,封锁措施可能被认为比严格的一揽子措施更有针对性,这可以解释该国与其他国家相比所表现出的独特趋势。
  • 对于菲律宾、泰国、萨尔瓦多、牙买加、来说,家庭暴力搜索率和流动性的同时下降是显而易见的。这并不意味着家庭暴力事件减少了。可能有各种其他因素影响观察到的搜索率趋势。例如,这些国家的搜索率在 2 月底/3 月初达到峰值,这可以解释为 3 月 8 日国际妇女节(媒体)对家庭暴力的关注。那天有很多人参加了不同的游行,无论是在亚洲还是拉丁美洲。

讨论——需要采取行动来减少家庭暴力的增加

本文研究了 Covid19 全球疫情对家庭暴力的影响。家庭暴力的增加可以被视为“疫情成长的阴影”。新闻也强调了这一点——报道这一问题的文章数量呈增长趋势。这些文章中的一些以摘要的形式提供了对“成长中的疫情阴影”的严重性和规模的洞察。例如,本文开头显示的联合国妇女署信息图提到,在法国、阿根廷、塞浦路斯和新加坡,家庭暴力紧急呼叫和报告增加了 30%以上。

调查结果表明,家庭暴力问题可能比新闻中一些关键人物所显示的要严重得多

对谷歌移动性和搜索率趋势的分析表明,封锁措施对家庭暴力的影响,如关闭工作场所,可以远远高于 30%。在流动性下降和家庭暴力增加之间的反比关系最强的国家,搜索率翻了一番,有些国家翻了两倍多。搜索查询可以被认为是寻求帮助的最容易的步骤。这可以解释为什么这篇文章的结果表明家庭暴力问题可能比前面提到的关键数字要大得多。

值得注意的是,还有许多其他因素会影响搜索率的结果。搜索率在多大程度上可以准确反映家庭暴力问题日益严重的程度,还取决于各国的情况。如前所述,只有当受害者能够访问互联网并且**对* 社会组织具有一定程度的信任,从而能够提供帮助时,受害者才会执行搜索查询。这些假设可以解释这项研究中在许多欧洲国家发现的紧密联系。*

这项工作的目的是帮助建立对家庭暴力问题的认识。尽管一些国家已经采取措施缓解问题,但结果清楚地表明,问题依然存在。有鉴于此,联合国最*发表了一份简报,其中载有“供社会所有部门,从政府到国际组织和民间社会组织考虑的建议,以便在公共卫生危机开始、期间和之后预防和应对暴力侵害妇女和女童行为,并附有已经采取的行动的例子”。

学分——奥姆德纳艾疫情挑战赛

本文介绍的工作是奥姆德纳人工智能疫情项目的一个专门任务的一部分。没有所有团队成员的帮助,这项工作是不可能完成的。特别感谢 Albina Latifi 为新闻文章分析和主题建模所做的一切努力。

不要把所有无聊的东西自动化

原文:https://towardsdatascience.com/dont-automate-all-the-boring-stuff-84d493ecc135?source=collection_archive---------40-----------------------

有时候无聊是可以的。

打哈欠然后去工作!—Vincent van ZalingeUnsplash 上拍摄的照片

我倾向于让事情自动化。

学习和实施新事物是一件非常有趣的事情。特别是作为一个编程新手,感觉就像让你的计算机表演魔术一样。但是有时候,自动化是不必要的,而且会适得其反。

菲律宾食品:一个需要自动化的项目

作为一个个人项目,我决定从菲律宾食谱网站“ Panlasang Pinoy ”获取所有食谱。我希望最终产品是一个 Excel 电子表格,聚集了网站上所有的食谱数据。这样,每当我想做些新东西的时候,我都会在电脑上有一个文件。

手动获取几千份食谱是一项不可能完成的任务。相反,我想尝试使用 Scrapy,一个用于网络抓取的 Python 库。我浏览了文档,认为我可以在几个小时内做出一些东西。

在温习了 HTML、学习了 xpath 选择器和“yield”的功能之后,我运行了我的第一个蜘蛛。迎接我的是一个错误。经过一点调试,我意识到我错过了几个必需的变量赋值。15 分钟后,我的蜘蛛运行没有错误,并提取每一个食谱到一个 Excel 文件。

我的蜘蛛在 Excel 上的输出(2k+行)—来自https://panlasangpinoy.com/的数据

我的最终目标很简单,这就是为什么从一无所有到“最终产品”只花了几个小时的原因。尽管简单,该文件易于使用,并作为一个基本的食物汇编。在 Excel 上做了一点格式化后,我把数据上传到了脸书的“微妙的菲律宾人特质”小组。

我在脸书微妙的菲律宾特质小组上的帖子

这个快速项目对我来说是一个完成需要自动化的任务的机会。在学习编码时,我读过的很多建议都是构建自己的项目。一个建议是审视你做的每一件事,尝试自动化每一项任务,即使你不需要。这样,你就可以通过“边做边学”的方法来提高你的知识。在这种情况下,如果不写代码,我甚至无法完成我的项目。这证明了花时间学习设置和部署蜘蛛是值得的。

自动化一切可能对学习有好处,但它可能不是获得结果的最有效方式。

AEX 指数和新冠肺炎:一个不需要自动化的项目

最*,我想跟踪在新冠肺炎引发的隔离期间,阿姆斯特丹交易所指数(AEX)的表现。

我这个项目的最终目标是一个 KPI 和可视化的 Tableau 仪表板,包含三类数据:

  • 一段时间内的 AEX 指数价格。
  • 能够解释市场运动的新闻文章。
  • 荷兰电晕病例的数量。

这三类数据存在于网络上的各种来源中。我的目标是创建一个仪表板来尽快了解情况。因此,我的首要任务是分析数据,而不是花太多时间收集数据。该项目不需要定制的蜘蛛,但我认为我的经验将有助于这个项目的数据收集。

以下是我收集数据的过程:

1。AEX 指数数据

https://finance.yahoo.com/quote/^AEX/history?p=^AEX AEX 指数雅虎财经数据

在 AEX 的“历史数据”选项卡上,所有价格信息都可以通过“下载数据”按钮获得。在这一点上,我甚至懒得去检查 HTML,因为我不需要这样做。我只需设置日期过滤器,然后点击下载。然后,我直接把那个 Excel 输出连接到 Tableau。

完成时间:< 5 分钟

2。新冠肺炎病例

到目前为止,每个人可能都看过新冠肺炎统计公司的约翰·霍普斯金·CSSE 仪表盘。

https://coronavirus.jhu.edu/map.html 约翰·霍普斯金新冠肺炎仪表板—

我一时兴起,在那个页面上搜索“Github”,找到了他们的资源库。我点击了这个存储库,试图找到另一个包含所有 Corona 案例的 Excel 文件。我登陆了另一个存储库,那里有人将来自约翰·霍普斯金的原始数据转换成了 csv 格式。

Github 存储库,包含 https://github.com/RamiKrispin/coronavirus-csv 新冠肺炎的 csv 数据—

我下载了那个 csv,检查以确保数据都在,然后把它加载到 Tableau 中。

完成时间:20 分钟

3。AEX 指数公司新闻稿

我把这个留到了最后,因为我知道这将花费我最长的时间来弄清楚。我开始查看常规新闻网站,输入“AEX”和“科罗纳”作为关键词。这些搜索的大部分内容看起来并不能解释 AEX 指数的趋势。接下来,我想到用公司新闻稿和季度报告。

有 25 家公司被纳入 AEX 指数。我不想去每个网站,点击它,直到我找到他们的“媒体”页面,然后把我在那里找到的任何东西复制粘贴到 Excel 表格中。作为测试,我试着做了一个网站,花了大约五分钟。一些快速的心算让我得出结论,我绝对不想花 2.08 小时复制粘贴东西。

之后,我上了泛欧交易所(股票交易所)网站,点击了指数中的一家公司。我发现公司主页有一个“监管新闻”标签,显示最*的新闻发布。

泛欧交易所网站 ABN AMRO 页面截图—https://live . Euronext . com/en/product/equities/nl 0011540547-XAMS

主站点依靠 JavaScript 来加载其站点的部分内容。因为 Scrapy 不能解析 JavaScript 站点,所以我不能写一个蜘蛛来抓取整个站点。然而,当我点击每个公司的新闻稿选项卡时,我被重定向到的网站没有任何 JavaScript!此外,只需要修改 URL 中的一个子字符串就可以访问 Euronext 网站上的任何公司。

有了这些,我想我可以写一个快速的蜘蛛来获取每家公司所有必要的新闻稿。

ABN AMRO—https://live . Euronext . com/listview/Company-Press-release/nl 0011540547的公司新闻稿选项卡截图

于是我开始了。我建立了一个虚拟环境,安装了 Scrapy,并测试了服务器是否会阻止我进行 Scrapy。我初始化了一个基本的蜘蛛模板,然后打开浏览器检查网站。

HTML 格式起初看起来不错,但后来我意识到有几个问题:

  • 一些新闻稿的标题不是英文的,这意味着我需要想出如何翻译它们。
  • 不是所有的标题都属于同一个 HTML 类,所以我必须找到一种方法来包含任何一个出现的标题。
  • 相对于我想要研究的时间框架,新闻的页数在不同的公司之间是不同的。一些公司只有一页上的几篇新闻稿,而其他公司有三页的更新。我需要弄清楚如何在我的目标时间框架内只浏览这些页面。

这些问题可能看起来不是很难,但我在网页抓取(以及一般的编码)方面完全是个新手。

我被难住了。

我知道我可以花时间学习更多关于刮痧的知识,并最终解决并发症。然而,由于我的知识有限,我无法估计达到抓取速度和实际编写蜘蛛需要多少时间。我已经花了两个小时来测试和发现这些问题。我走开了一会儿,清醒一下头脑。

回来后打开一家随机公司的新闻稿选项卡,复制新闻表格,粘贴到一个空的 Excel 文件中。我花了大约十秒钟。我做了一些快速心算(完全公开,这是我打开计算器)第二部分,我意识到我将花 4.16 分钟完成所有 25 家公司。

我太沉迷于试图找出如何自动化这个过程,以至于忘记了我项目的目标。这不应该是学习网络抓取的练习。我的目标是尽快将原始数据转化为关键见解。

我很想忽略这一点,继续进行刮擦,因为我已经为此投入了大量时间。谢天谢地,我的大脑想:

“拜伦,我们学习了沉没成本。放手吧”。

10 分钟后,我把 AEX 指数中每家公司的所有新闻稿都从泛欧交易所网站上复制粘贴了下来。所以不到 4 分钟,因为我需要额外的 6 分钟来处理复制粘贴的数据。完成后,我将 Excel 文件加载到 Tableau 中,并最终准备好开始制作一些图表。

完成时间:130 分钟。

完成这项工作可能需要的时间:10 分钟。

按比例还是不按比例?

我的大脑现在已经在尖叫了:

“但是拜伦,规模呢?你不想最终扩大这个项目的规模吗?为什么不把它做成可扩展的?”

明白了吗?尺度?鱼有鳞?—paweczerwińskiUnsplash 上拍摄的照片

答案是肯定的。在某种程度上,我确实想让 Tableau 上的仪表盘拥有实时数据,但这并不是我这么做的原因。这个项目的目标是制作一些图表。这个练习对我来说是一个快速而又肮脏的方法,让我重温 Tableau,了解 AEX 指数的变化。

绘制图表比收集数据要快得多,因为我已经学会了使用 Tableau。我不需要去找那些小众的东西,比如同步轴、编写 LOD 表达式和混合数据源。

当我完成时,我有了一个组合了所有三个数据集的仪表板。从一页纸上,我可以很快对事件如何影响股票价格有一个基本的了解。我还可以看到随着时间的推移,新冠肺炎病例和 AEX 指数之间是否有任何关联。

我从中学到的是,有时候,你真的不需要自动化你正在尝试做的事情。如果我能实时更新每一类数据,那就太好了。事实上,这就是我接下来要做的。但这对于概念验证项目来说是不必要的,而这正是本练习的目的。

我在自动化方面取得了一些早期的成功。我安排电子邮件,处理 RSS 订阅,用熊猫来分析数据,所有这些都是在学习 Python 的几个月内完成的。正因为如此,我有点痴迷于尝试在任何地方应用自动化。我艰难地认识到,开发自动化解决方案的过程可能会妨碍实际工作。

这是如此真实——https://xkcd.com/1319/

从一个网站上复制粘贴有点像走捷径,尽管这种捷径无聊得令人麻木。

这个:

“我设置了一个高级的 scraper,它在云中填充了一个关系数据库,然后连接到一个 Tableau 仪表板。”

听起来比这性感多了:

“我从一个网站上复制了一些东西,粘贴到 Excel 中。然后我把它放在舞台上。”

事情是这样的:性感不是目标。

如果我不性感的话,我可以节省一个小时。我不需要变得性感来完成概念验证仪表板。

所以在 1944 年的单词之后(谢谢你能走到这一步),我的大收获是双重的:

  • 说到学习,想怎么做就怎么做吧。
  • 当涉及到交付一个项目时,关注获得结果,而不是实验。

TLDR;不要总是性感。

旁注:如果你集成了 Splash 或者 Selenium,Scrapy 可以解析 JS,但是我还没有学会这么做。这是我还没有接触过的东西,这就是为什么我甚至没有想过去尝试去做。抓取常规(非 JS)站点的任务已经有些熟悉了。这就是为什么我有一个是否自动化数据收集的有效难题。

不要害怕非参数主题模型

原文:https://towardsdatascience.com/dont-be-afraid-of-nonparametric-topic-models-d259c237a840?source=collection_archive---------35-----------------------

你好,我是尼克🎞 on Unsplash

在本文中,我将介绍高级基础材料。如果您对如何用 Python 实现我下面描述的模型感兴趣,我将很快发表第二篇文章。

想想你最后一次阅读一本书或一篇文章。我打赌你不可能记住你读过的每一个单词,但是,你可以回忆起文章中的某些趋势或主题。这只是因为我们的大脑倾向于那些可以轻易储存在微小细节中的摘要。主题建模本质上模仿了我们大脑用来捕捉文本数据趋势的“摘要”技术。

这些类型的模型通常在工业中用于定义文本数据中的共性或潜在趋势。例如,根据与以前票据的文本相似性自动标记客户支持票据,或者在开放式客户反馈调查中发现潜在趋势,以便为未来的产品功能提供信息。

那么,这和非参数有什么关系呢?好吧,让我们继续上面的例子。在开始读这篇文章之前,我不相信你的第一想法是“对于这本书,我会准确地记住 5 个主题。”相反,你的大脑决定了一些对文章有意义的主题,这个数字会随着书籍/文章的不同而变化。这里是非参数进入场景的地方。这只是一种“让模型从数据中推断其参数”的奇特说法,或者在我们的情况下,让模型推断主题的数量(就像我们的大脑在某种程度上一样)。

你们中的一些人可能会被这篇文章中的术语吓到(例如,Dirichlet,混合模型,等等。).我明白,这不是一个简单的话题(相信我,我一开始也很纠结)。但是,不用害怕!我的目标是在本文结束时,您将学到一些关于非参数建模和主题模型的新知识。

概率主题模型的简要总结

如果你没有任何概率模型或狄利克雷分布的介绍,我强烈推荐你在继续之前阅读这篇文章

在深入细节之前,提供一些关于主题建模和相关方法的一般背景是有帮助的。根据定义,主题建模是指用于分析文档中的文本数据和识别重要词组(主题)的一组无监督技术。因此,主题模型输出 1)一组主题和 2)一组按主题分组的文档。

一种常用的参数模型是潜在的狄利克雷分配(LDA ),它利用两个基本假设

  1. 相似的主题将使用相似的单词(具体来说,每个主题将有一个单词分布)
  2. 文档可以被认为是多个主题的混合体

下图将为您提供一些关于 LDA 的直觉。我们看到,主题(左侧)是由一组相似的、共现的单词归纳而成的,而文档(右侧)是由主题混合而成的。

潜在狄利克雷分配(LDA)背后的直觉——资料来源:Blei,David M (ACM,2012)

这是一个过于简单的解释,该模型有其复杂性,如假设主题是狄利克雷分布,但我们不会在这里逗留。

这种设置的一个主要缺点是,我们必须预先定义要生成的主题数量。如果你真的不知道有多少话题可以期待,这可能是一个问题(想想我们书的阅读例子在开始)。为了克服这个限制,我们可以使用非参数方法,如狄利克雷过程混合。

狄利克雷过程混合物(DPMs)

在您被这个术语吓倒之前,请将 DPMs 看作是以前的 LDA 模型的扩展。代替预先定义的主题

  1. 这些是从文本数据中学习到的
  2. 它们只受文档集合中的词汇(唯一的单词)的限制

这最后一点很重要,因为它考虑到了无限数量的主题的可能性,如果你要训练世界上每个可能的单词的模型。“但那要花很长时间才能跑完!”你可能会说。我不反对,但狄利克雷过程(DPs)给了我们一个概率公式,使这变得可行。

关于狄利克雷过程(DPs)的简短而重要的旁白

下面的内容听起来很吓人,但请耐心听我说。

形式上,DP 被定义为分布上的分布,并且由可计数的无限数量的点质量组成

唷!那是一口。

简单来说,DP 创建了一个被认为是“无限”的离散分布这种无限离散的特性源于这样一个事实,即我们可以将 DP 看作是首先从一个连续的基本分布(例如高斯分布)中抽取样本,它可以取无限多个值。当我们分配非零权重时,这些样本被认为是离散的。我们使用一个断棒构造来创建这些样本结果是一个遵循狄利克雷的无限离散分布。

下图提供了一种直觉。在第一幅图像中, G (浅蓝色)是通过具有参数 αG0 的狄利克雷过程生成的离散概率分布(连续的基本分布,例如高斯分布)。参数 α 控制 G 与基本分布的相似程度——例如,当我们增加 α 时, G 的形状将看起来更像 G0 的形状。换句话说,分布 G 由离散的(“可计数的”)分量组成,这些分量通过将非零权重分配给无限数量分量的子集的过程来实现。

在第二张图中,我们可以看到 s 分笔成交点构造如何生成这些分立元件。

狄利克雷过程背后的直觉——资料来源:K. El-Arini (2008)

断棒结构背后的直觉——来源:Patrick Dallaire (2011)

在主题建模中,狄利克雷过程用于生成主题的无限离散分布

狄利克雷过程混合物(DPMs)的高级概述

恭喜你坚持到现在,你已经完成了 75%!现在,让我们继续 DPMs…

理解 DPMs 的一个常见且有时有用的类比是中国餐馆流程。(我还是不明白他们为什么选择这么叫。)

以下是直觉以及它与主题建模的关系:想象一家餐馆,它提供来自无限菜单(一组主题)的菜肴(主题),并有无限桌子(单词组)的空间。每桌只能点一道菜,但多桌可以点同一道菜(即话题可以重复)。然后,顾客(词)和其他顾客坐在一张现有的桌子上,或者有可能坐在一张新桌子上。

下图显示了这一过程的描述。现在,让 k 索引主题和表格每个表上的参数φ代表一个表主题索引,客户代表单词。当一个新客户(词)出现在迭代 T 时,他/她坐在一个新的或现有的桌子上。顾客最终就座的位置由与每张桌子就座的顾客数量成比例的概率和帮助定义新桌子概率的参数 α 来定义。

中餐厅流程的直觉—资料来源:Eric P. Xing (2014)

主题模型是通过在多个“时期”循环遍历文档集合中的所有单词来训练的使用主题和表索引φ,我们可以通过收集分组在一起的单词来解释推断的主题。(在我们的类比中,这些是坐在一起的顾客,他们坐在桌子旁,分享同一道菜 k 。)还有一些度量标准,比如困惑度,这在本文中没有涉及,它们可以帮助您评估每个时期的模型拟合度。**

好极了。就这样对吗?不完全是。

****如果我们有多个不同的文档集合,比如一个关于统计的集合和另一个关于计算机工程的集合,并且希望保持相同的设置,但让集合共享主题会怎么样?

在当前的设置中,每个 DP 为每个文档集合生成一组独立的“无限”主题。我们只需要再多一步——一个层级。

分层狄利克雷过程

根据 Yee Why Teh 等人在 2005 年发表的一篇精彩论文,HDP 在上一节介绍的 DPM 的基础上引入了一个层次结构。HDP 提供了“无限”数量的基础主题,可以在不同的文档集合之间共享。

****下面的图片将为您提供一些关于 DPMs 和 HDPs 之间差异的直觉。首先,下面的 DPM 图显示,尽管两个集合共享相同的连续基分布 H (左图),但是与每个文档集合相关联的狄利克雷过程 G1G2 生成不相同的离散样本(右图,蓝色)。这意味着如果我们使用这个框架进行主题建模,我们的集合不会共享主题。

****对狄利克雷过程混合物的直觉:(左)代表两个文档集合的 DPM 的*板图,(右)来自每个集合的不同 DPM 的样本—来源:Teh 等人(2007)

相比之下,下面的 HDP 图显示了引入层次结构(左)如何允许两个集合共享来自相同的无限主题底层分布的样本(这里记为 G0 )。

****对分层狄利克雷过程的直觉:(左)表示现在共享无限数量主题的两个文档集合的 HDP 的*板图 G0 ,(右)来自每个集合的共享 G0 的样本来源:Teh 等人(2007)

继续以中国餐馆流程为例,HDPs 可以被认为是中国餐馆的特许经营

对我们之前的类比的唯一改变是,在这种情况下,有多个餐馆(文档集合)现在共享来自一个全局菜单( G0 )的菜肴(主题)。训练模型和解释题目的过程和上面的原中餐厅过程类似。

结论

万岁!我们结束了,你应该为自己走到这一步而自豪。您刚刚学习了一种非常复杂的建模技术。

在我列出一些优点和缺点之前,我只想说明我已经掩盖了这些模型的许多复杂性。如果你对深入研究感兴趣,我推荐你阅读 Yee Why Teh 的原始论文。

优势

  1. 它们是探索文本数据潜在趋势的有用工具
  2. 在非参数模型中,主题的数量是从数据中学习的,而不是用户指定的
  3. 主题可以在不同的文档集合之间共享,这可以提供对趋势的进一步洞察

不足之处

  1. 这些模型使用词袋表示法分析文本,忽略句法和语义信息
  2. 要使这些模型最有效,需要大量高质量的数据(即预先清理的文本)

参考

  • 叶惠德,迈克尔一世·乔丹,马修·J·比尔和大卫·M·布莱(2006)分层狄利克雷过程,美国统计协会杂志,101:476,1566–1581,DOI:10.198/01660000005
  • 概率主题模型。美国计算机协会第 55.4 届会议的来文(2012 年):77-84。
  • 杜迈斯、S. T .、弗纳斯、G. W .、兰道尔、T. K .、和迪尔韦斯特(1988 年)。利用潜在语义分析改进信息检索。CHI'88 计算系统中人的因素会议论文集,281–285。
  • Khalid El-Arini (2008 年)。狄利克雷过程:温和的介绍。卡内基梅隆大学,计算机科学。
  • 埃里克. p .兴。分层狄利克雷过程。10–708:概率图形模型 10–708,2014 年春季。抄写笔记。

我希望你喜欢这篇文章,欢迎在 Twitter 上关注我访问我的网站了解其他很酷的想法/项目。

不要害怕非参数主题模型(第 2 部分:Python)

原文:https://towardsdatascience.com/dont-be-afraid-of-nonparametric-topic-models-part-2-python-e5666db347a?source=collection_archive---------10-----------------------

视频教程

准备好开始你的模特游戏了吗?深入了解如何实现/评估分层 Dirichlet 过程模型的简单分步教程

本文建立在我在上一篇文章 中介绍的高级基础材料 的基础上,描述了如何用 Python 实现主题建模的层次化 Dirichlet 过程模型。

让我们都同意,学习和谈论很酷的新方法是一回事,用数据实际实施/测试它们是另一回事。主要是因为对它们的了解不会带来 bug、奇怪的错误等典型的挫折。然而,我个人认为,修补的结果是对概念本身的更深理解。

你猜怎么着?贝叶斯非参数(BNP)方法,如分层狄利克雷过程(HDP)也不例外。

在你认为我要把你扔进编码池的最深处之前,不要担心。我写这篇文章的总体目标是,最终你可以自信地实现一个 HDP 模型,在你的项目中驱动价值(或者允许你向你的朋友谦虚地吹嘘)。

MARK ADRIANEUnsplash 上拍摄的照片

一目了然

以下是我将介绍的内容

  • 关于如何使用现有 Python 库实现 HDP 模型的分步教程
  • 其性能与潜在狄利克雷分配(LDA)模型相比如何
  • 实施 HDP 时的一些关键注意事项、陷阱和潜在的修复方法

我将使用通过sklearn.datasets获得的 20 新闻组数据集。考虑到大约 20,000 个文档的集合几乎*均分布在 20 个不同的主题(新闻组)中,这是一个很棒的玩具数据集。由此可见,从某种意义上说我们已经知道了真题 这个模本应该推断出来。

目录

这篇文章分为以下几个部分

  1. 数据预处理
  2. HDP 模特培训与评估
  3. 型号对比
  4. 反面教材

属国

在我们开始之前,我建议您安装以下依赖项spaCynltkgensimtomotopyplotninewordcloud。您可以使用pip单独安装每一个,也可以使用我创建的 需求文件 来简化您的工作,如下所示

pip3 install -r requirements.txt

数据预处理

如果你还没有为 NLP 项目预处理过文本数据,我强烈推荐你提前查看一下这个循序渐进的教程

让我们首先加载 20 个新闻组数据集,指定我们只需要模型的train子集。

from sklearn.datasets import fetch_20newsgroups# Read in train subset (11,314 observations)
news = fetch_20newsgroups(subset='train')

这个news实例包含文本数据(news.data)和标签(news.targetnews.target_names),在 pandas 中可能是这样的

而不是一步一步地告诉你我如何用标准方法预处理content 数据(例如,标记化、停用词移除等)。),我将在下面总结这些步骤。

随着我们在这一部分(以及在未来的项目中)向前推进,我希望您记住以下几点:

基于最终目标和选择的建模方法,这些预处理步骤有意义吗?

这很容易被忽略,因为标准的预处理方法在许多应用程序中工作得很好。例如,在我们的例子中,我们想要去除由停止字( on、等)产生的噪声。)以便我们的模型可以更好地捕捉与真实主题相似的潜在主题。
然而,总是这样吗?编号
【查看这篇文章关于为什么这不是情绪分析的好主意】

特殊字符删除

首先,我使用正则表达式替换删除了数据集固有的任何特殊字符,如@\n,以及单引号'

标记化

这里我使用了函数gensim.simple_preprocess,它非常有效地标记了每个文档(即,将文本分割成单个单词)。为了删除任何潜在的重音,我用deacc=True参数运行它。

二元模型

这些有助于构建,因为它们考虑到了词的共现。例如,在我们的数据中,这会生成['oil_leak']而不是['oil', leak']。你可以使用gensim的内置PhrasesPhraser功能来实现这一点。

停止单词删除

如果我们首先删除文档中的非信息词(即停用词),推断潜在主题将会更容易。我下载了nltk的英文停用词,并添加了几个简单的针对这个数据集['from', ‘subject', ‘re','edu',use']的停用词。

词汇化

考虑到数据集相对较小(即大约 10k 个观察值),我使用spaCy和词性(POS)标签为名词、动词、形容词和副词实现了一个词汇化方案。简单地说,我删除了任何屈折变化的词尾,并返回了基本/词典单词,如下所示。

"A letter has been written asking him to be released"[ex. Original ==> Lemmatized, POS tag]A        ==> a, DET
letter   ==> letter, NOUN
has      ==> have, AUX
been     ==> be, AUX
written  ==> write, VERB
asking   ==> ask, VERB
him      ==> -PRON-, PRON
to       ==> to, PART
be       ==> be, AUX
released ==> release, VERB

虽然 lemmatization 提供了更好的标记,但它的代价是可能会花费比您希望等待它完成更长的时间。因此,当时间至关重要或者如果你有一个大的数据集,一个的选择是词干化 ,它使用粗糙的试探法切断单词的结尾,希望得到基本单词。(例如,在这个数据集中,词汇化需要大约 4 分钟,而词干化只需要 14 秒)。

把所有的放在一起

我构建了一个定制脚本newsgrp_preprocess ( 链接此处为 ),它整合了上述所有步骤,并为我们拥有超过 1M 令牌的 HDP 模型(即word_list_lemmatized)输出现成的数据。此外,它整理了news实例中的信息,并将信息输出到一个漂亮的pandas数据帧中(如本文前面所示)。

> from scripts.newsgrp_preprocess import run_preprocess> news_df, word_list_lemmatized = run_preprocess(news)# Showing first document, first seven tokens
> word_list_lemmatized[0][:7] 
> ['where', 'thing', 'car', 'nntp_poste', 'host', 'park', 'line']

现在已经完成了,让我们继续真正酷的事情——训练模型!

HDP 模型训练与评估

如果你不熟悉贝叶斯模型,你可能会问“训练一个贝叶斯模型意味着什么”?嗯,这基本上意味着我们试图推断/学习一个分布。在我们的例子中,我们试图从文档中了解未观察到的(潜在的)主题的分布。

为了训练贝叶斯模型,你通常使用两个主要阵营的方法:蒙特卡罗方法(例如 Gibbs/MCMC 采样)和*似/优化方法(例如变分推断)。

MCMC?变分…什么?不要担心,这里有一本由约瑟夫·罗卡撰写的简单读物 ,它解释了这些方法,即使你不太了解贝叶斯统计

不用深入细节,两个阵营基本上实现了相同的目标:从数据中推断出一组主题。然而,在考虑使用哪种方法时,每种方法都有重要的优点和缺点(其中一些我将在后面的小节中介绍)。

在本节的剩余部分,我将使用 Python 库,这些库使用一种叫做折叠吉布斯采样的蒙特卡罗方法。与传统的吉布斯采样器相比,该方法加快了主题推理过程(即模型训练)。

建立 HDP 模式

这里我使用了tomotopy Python 库。

如果您有任何实现 HDPs 的经验,此时您可能会问,“但是您为什么不使用gensim.HdpModel函数呢?”嗯,我尽力了(相信我,真的很努力)。还记得我在开头提到的挫折吗?对我来说,这是其中之一,因为即使在广泛的调整之后,我也无法使用gensim的方法来生成高质量的数据集结果。

对 HDP 模型和超参数α和γ的直觉

训练一个tomotopy模型相当简单。首先,通过设置一些参数来初始化一个模型对象,如模型将如何加权令牌、与令牌频率相关的阈值以及 HDP 模型的集中参数alphagamma(见左图)。

对于这个数据集,我将模型限制为只使用出现在至少 5 个带有min_cf参数的文档中的单词,而排除了 7 个最常用的带有rm_top的单词。类似地,我设置了集中参数gamma=1alpha=0.1,假设文档共享许多主题,而单个文档只谈论很少的主题。我用initial_k=10初始化了主题的数量,它充当了一种先于的角色。鉴于数据的 20 个主题分为 6 个主要组(例如rec.carrec.bike下的建议),我选择了这一点,并且我假设misc组可能有一些应该考虑的其他主题。

import tomotopy as tpterm_weight = tp.TermWeight.ONEhdp = tp.HDPModel(tw=term_weight, min_cf=5, rm_top=7, gamma=1,
                  alpha=0.1, initial_k=10, seed=99999)

模特培训

一旦我们实例化了hdp对象,我们就可以添加它将用来训练模型的文档,如下所示。(如果有帮助的话,我已经用一个 自定义函数 train_HDPModel自动化了这些步骤。)

上面的示例输出提供了有用的早期诊断信息。例如,看到每个单词的对数似然增加,这告诉我们模型正在充分学习。

从模型中提取主题不像其他包那样简单,所以我构建了一个 自定义脚本 get_hdp_topics来简化这个过程。

模型评估

接下来的部分听起来会很乏味,但是我强烈建议您完成它。它涵盖了如何评估这类模型的最佳实践。

给定的主题模型是无监督的方法,我们无法使用常见的性能指标(例如 RMSE)来评估它们,相反,我们使用一种称为 一致性 的指标,它提供了一种客观的方法来衡量组合在一起作为主题的单词是否有意义。

有多种方式来计算这个度量,但是基本上,如果定义一个主题的单词在文档中出现在一起(共现)的概率很高,则该主题被认为具有高。一般来说, CV 方法是首选,因为它考虑了通过滑动窗口计算这些概率时单词出现的接*程度。

假设我们知道数据集中的主题,我们可以评估两件事:

  1. 模型的主题是否代表真实主题(连贯性)
  2. 模型推断一个看不见的(样本外的)文档的主题有多好

鉴于tomotopy 提供了三种不同的令牌加权方案,我测试了每种方案,以根据上述标准比较它们的性能。首先,我比较了使用gensim.CoherenceModel的和使用 coherence='c_v'自定义脚本 CV 指标得分范围从 0 到 1 (其中好的话题连贯性得分范围在 0.5-0.65 之间)。

对于这个数据集,逆文档频率模型似乎基于主题一致性表现得最好。如果你的目标只是理解特定数据集中的一些潜在主题,那么很好——你已经完成了!选择一致性最高的模型。然而,请注意,这并不一定意味着模型将很好地概括(即准确地将主题分配给看不见的文档)。

在我们的例子中,我们有一个标记的测试集,我们可以用它来验证模型是如何概括的。(如果没有带标签的数据,可以做一些类似的检查。抓住一个看不见的文件进行预测,选择分配的最主要的主题,看看这个分配基于文本是否有意义。)

预测到一个,如果你愿意,你也可以使用训练集作为健全性检查,即使它是未标记的数据,只要预测一个文档,看看它是否基于内容有意义。)

下面的单词 clouds 提供了一个很好的例子。使用与前面相同的步骤,我们得到一个测试集(subset='test'),并评估每个模型的泛化能力。我们看到,具有最高一致性的模型( IDF )并不一定分配“正确的”主题(rec.autos),相反,它似乎认为这份文档讨论的是计算机。

比较三个 HDP 模型的概括能力,一些模型给出了正确的主题,而另一些则没有

虽然这是一个非常具体的例子,但我选择继续使用 HDP IDF 模型,因为它倾向于产生类似于真实标签的主题,并且比其他模型更经常地将正确的主题分配给测试文档。

**

HDP IDF 模型:(上)主题示例[左] sci.med,[中] comp。__,【右】 rec.sport.hockey 。(下)主题分配与真实标签

顺便提一下,主题标签可能是主观的(例如,一个人可能会将单词理解为硬件主题,而另一个人则理解为软件主题)。为了避免这种情况,tomotopy提供了一种有趣的方法,即客观地给主题贴标签。你可以在这里找到一些的例子

模型比较

恭喜你!如果您已经学了这么多,那么您应该非常了解如何用 Python 实现 HDP 模型了!但是,和 LDA 相比如何?

让我们比较我们的 HDP 模型和 MALLET LDA 模型(有趣!).我使用这个版本而不是默认的gensim LDA,因为它允许苹果到苹果的比较(即,它也使用折叠吉布斯采样器)。在这种情况下,gensim有一个简单的包装器LdaMallet,一旦你下载了 MALLET 二进制文件,就可以快速实现这个模型。要了解如何运行它我建议你看看下面的 Jupyter 笔记本

使用相同的数据集,我将如上所述的几个 LDA 模型的性能(即相干性+概化)与 HDP 模型的性能进行了比较。在下图(左)中,我们可以看到,随着 LDA 模型中主题参数的增加,主题连贯性也在增加。

该比较展示了在不指定主题的情况下,即兴 HDP 模型如何能够实现与 LDA 模型相似或更高的主题一致性

类似地,我们可以看到我们的最佳 HDP 模型( IDF )在将正确的主题分配给看不见的文档(右图)方面具有与最佳 LDA 模型(主题=26)相似的性能。

**

警示故事

没有一些好的警示故事的数据科学文章算什么?让我们面对现实吧,每种建模技术都有优点和缺点,也有可能出错的情况。在这里,我只想分享一些在实现 HDP 模型(或者一般的主题模型)时要记住的事情。

故事 número uno(故事#1):垃圾输入,垃圾输出

**认真思考你的预处理步骤。一个简单的开始方式是考虑你的目标是解决什么问题,你拥有的数据,以及你将使用的模型。很多时候我们可以随波逐流,在项目中使用相似的预处理步骤,但是正如我上面提到的,这可能会导致糟糕的输出。

例如,这个项目的目标是实现一个可以从文本数据中学习 20 个( ish )主题的模型。在给定数据集大小的情况下,删除停用词以减少噪音和词汇化是有意义的。然而,如果目标是做一些情感分析,那么删除停用词就不是一个好的选择。

故事 2:不要盲目相信统计数据

**、作为众多可以用来评估主题模型的指标之一,提供了一种直观的方式来衡量表现。我不知道你怎么想,但我认为有时我们倾向于专注于统计(例如 RMSE 或预测模型的分类),特别是当它们似乎表明良好的性能时。

这里有一个明显的例子。还记得我们把一致性作为一个很好的性能指标吗?当我使用gensim.HdpModel的时候,这肯定不是真的。因为它们的实现是基于变分推理的,所以我测试了(作为数百个调整组合中的一个)改变其中一个学习参数( kappa )会如何影响模型的主题一致性和在看不见的文档上的性能。

跨 kappa ={0.6,0.8,1}值的 gensim HDP 模型的 CV 一致性分数

结果是,当我增加 kappa 时,模型的一致性分数增加。你可能会问,“太好了,这正是我们想要的,对吗?”是的,但是在这种情况下,当您尝试在一个看不见的文档上测试模型时,您会观察到 1) 每个文档都被分配了一个相同的主题2)这个主题太宽泛了,以至于您无法理解它。根据给定的度量,该模型已经收敛到一个表现“良好”(例如,局部最优)的解决方案,但是仍然没有用。

因此,如果有一个我想让你从这篇文章中学到的关键是

在完全相信一个统计数据之前,退一步想想这个数字是否有意义,为什么有意义

故事 número tres(故事#3):推理方法可以产生不同的结果

之前我提到过贝叶斯推理中使用的两个主要阵营:蒙特卡罗方法和变分法。根据您的具体项目和目标,选择使用哪个包实现会有很大的不同。然而,我相信这归结为一个速度/内存与准确性的权衡。

tomotopy 模型:快速准确 如前所述,这个包使用了折叠吉布斯采样器。主要优势是它固有地产生无偏见和准确的结果。
然而这种方法扩展性不好(内存开销随着观察次数线性增加)。在我们的例子中,这是有意义的,但是如果您要获取一个包含 100 万个文档的数据集,您可能需要等待一段时间来完成运行。

gensim 模型:更快和可扩展的 这个包使用了一个在线变分推理方法,简单来说,它允许你大规模使用经典的变分推理*似工具。这种方法的主要优势是速度和低内存消耗(内存不会随着观察次数的增加而线性增长,因此这对于大型数据集非常有用)。 然而,如果你用一个“更简单的分布”来*似一个目标分布,而不是像折叠吉布斯采样那样直接从目标中采样,它会以牺牲准确性为代价获得速度。这不仅会引入偏差,而且可能需要大量的参数调整才能获得有用的结果。下面是两个参数如何影响学习速度从而影响收敛的例子(你可以在这里访问 Dash 应用)。

(考虑到这些限制,已经开发了新方法来尝试解决变分推理的*似偏差。)

结论

当你不希望预先指定主题时,HDP 模型是 LDA 模型的强大替代品,有几个软件包可以帮助你轻松实现它们。但是,请记住,在实施这些模型之前、期间和之后进行一些尽职调查可以确保您的结果符合您的初始目标。

所以,现在你已经学会了如何实现一个 HDP 模型(并且可以流利地用西班牙语数数),继续测试你新学到的技能吧!

参考

  1. 王、钟、、戴维·布雷。"分层狄利克雷过程的在线变分推断."在 PMLR 举行的第十四届人工智能和统计国际会议记录。2011.
  2. 格里菲斯,托马斯 l,和马克斯特弗斯。“寻找科学话题。”美国国家科学院学报101 . Suppl 1(2004):5228–5235。
  3. 断层摄影术。【https://github.com/bab2min/tomotopy】T4。https://doi.org/10.5281/zenodo.3816629
  4. 布莱恩特、迈克尔和埃里克·b·索德思。"分层 Dirichlet 过程的真正非参数在线变分推断."神经信息处理系统的进展。2012.

如果你喜欢这篇文章,请随意分享!如果您有任何问题或看到任何不正确/有问题的内容,请发表评论或发推文( @ecoronado92 )。

本文中使用的所有代码和笔记都可以在这里找到

*[## ecoronado 92/走向 _ 数据 _ 科学

Repo 包含了一个在 20 个新闻组数据集上实现 HDP 模型的例子,该模型使用 tomotopy…

github.com](https://github.com/ecoronado92/towards_data_science/tree/master/hdp_example)*

不要做一个可扩展的数据科学家!

原文:https://towardsdatascience.com/dont-be-an-expandable-data-scientist-fda96c80cdf7?source=collection_archive---------77-----------------------

成为他们不能失去的摇滚明星的 3 个技巧。

泰勒·格罗特在 Unsplash 上的照片

数据科学如此受欢迎有很多原因。在我看来,这可能是一个人所能拥有的最有趣的工作。

想一想:

  • 你在玩数据,整天挖掘价值。
  • 你正在向管理层和高管展示你的成果,并影响公司的战略。
  • 你跟上了机器学习和人工智能的最新发展,这是目前最热门的话题之一,避免了过时。

虽然就业市场上有大量的供应,但大部分供应集中在入门级别的岗位上。这意味着,这是你要思考的事情,许多人匆忙进入这个领域,装备不良,并带着与他们的实际技能相比不切实际的期望。

也就是说,如果你还在读书,这意味着你真的想成为一名数据科学家,或者你想确保自己是一名优秀的数据科学家。

我可以帮你实现这个目标。我完全有资格这么做的原因是因为我在职业生涯早期没有遵守某些规则,我为此付出了代价。我基本上打破了我将要与你分享的每一个提示,我可以绝对自信地告诉你:这是有代价的。

你可以从失败中学习,也可以从在你之前做过这件事的人的经验中学习。

所以,事不宜迟,这里是我的三大建议,让你尽可能对公司有价值。

提示 1:了解你的业务

这可能会让你大吃一惊,但作为一名数据科学家,你工作中最重要的部分是彻底了解你所在的业务。如此多的初学者进入这个领域,认为这是关于“python vs R”,或者“我应该使用哪个绘图库”。让我告诉你:所有这些都是幼儿园的屁话。

你被雇来帮助公司赚更多的钱或者存更多的钱。使用任何你想要的工具,但是为了优化一个业务,你必须知道这个业务是关于什么的:客户,供应商,监管环境,竞争对手,公司品牌和定位,等等。

请不要误会我的意思。我不是说你必须成为这些学科的专家。但我要说的是:作为一名数据科学家,你绝对必须对所有可能影响你所在行业的领域有一个基本的了解。

不管是否明确说明,这都是你工作描述的一部分。

为什么?我再重复一遍:如果你要给公司的业务领导提建议,不管是通过建模、数据探索还是其他方式,让自己获得成功的最佳方式是对业务有广泛的了解。

说到向管理层做演示,我们就想到了第二点。

秘诀 2:学会沟通

如果你认为你不能在一屋子你从未见过的高地位利益相关者面前做演讲,你需要练习。很多!

就在几年前,我还无法想象自己会这么做。事实上,在大学里,我甚至不能在全班同学面前做演讲。我整晚都在为此感到压力,第二天早上,由于睡眠不足,我筋疲力尽,干脆躺在床上不出现了。我就是这样从不止一个,而是两个不同的学士项目中退学的。两次都是因为害怕做报告。

几年后,我决定做点什么。所以我注册了 MBA。我讨厌这样。但是你知道吗?这让我克服了对公开谈话的恐惧。因为在读 MBA 期间,我们都必须一直做陈述。经过几次伤脑筋的治疗后,我有点习惯了。

今天,我能够与观众建立联系,讲述一个故事,并表达我的观点。我还花了很多时间学习可视化的基本原理,这是我现在在大学教授的一个课题。

回到你和你的事业上。作为一名数据科学家,你需要成为一名得体的演示者和得体的沟通者。我怎么强调都不为过。这是第二个技巧而不是第一个的唯一原因是因为我重视内容胜于形式,但不是每个人都有耐心看到一个弱沟通信息背后的价值。所以,如果你需要在这方面下功夫,我建议你反复地把自己放在这样的场合,你必须发言,你必须提出一个想法。

提示 3:不要犯错误

我知道,这和你在任何地方听到的都相反,对吗?你期望我说类似“犯错误,这是你学习的方式”这样的话。

那是纯粹的软懒,初级,可扩展的心态!

真正的专业人士,那些成功登顶的人,是那些永远不会让自己失败的人。对他们来说,犯错误根本不是一个选项。

那些偶尔犯错的人,是那些认为没关系的人,他们最终会以某种方式变得更好,他们会变得更加自律和专注。

让我告诉你一个秘密。重要的不是结果。是心态的问题。

是的,结果必然源于心态。虽然你不能总是控制结果,但你永远不要让自己认为一个错误是可以接受的。

这意味着:你应该四次检查你的数字。回顾你的假设。寻找离群值。执行测试。事先打印你的演示文稿,从不同的角度看它。这份清单还在继续,由你来决定哪一种最适合你的风格…但是不要犯错误。

这个提示的本质是负责任

这对数据科学家和战场上的士兵一样有效。负责任并不意味着在事情发生后感到抱歉。没人在乎那个。相反,这意味着首先要尽你所能避免倒楣的事情发生。

离别赠言

我怎么没给过什么技术建议?浏览数据科学,你会发现很多。如果你能阅读,并且有最低限度的动力和纪律,你可以在技术上做得更好。

但是知道如何应用你所学的需要一种谦逊而强大的心态,这就是高级数据科学家与大量追随者的区别。学习起来也困难得多,因为它迫使你质疑自己是谁,而不是每个人都愿意为此努力。

我分享的建议是基于我自己和我所钦佩的人的经验。用不用就看你自己了。祝你好运!

不要太骄傲而不愿寻求帮助

原文:https://towardsdatascience.com/dont-be-too-proud-to-ask-for-help-76f21d16f318?source=collection_archive---------52-----------------------

职业建议

如果你被一个 bug 卡住了或者感到不知所措,你可以寻求你需要的帮助。

图片来自像素上的 olia danilevich

在解决问题时,最难学习的一课是何时后退一步寻求帮助。不要太骄傲而不愿寻求帮助。无论是同事之间的问题,代码中的错误给你带来的痛苦,还是你正在处理的个人问题,当你需要帮助的时候,你都可以随时寻求帮助。

注意到你的问题

最*,我接手了一个项目,在我们的代码库中开发一套新的功能。看看这个问题,它似乎是相对容易的工作,因为它只是扩展了现有的代码,以迎合一个新的用例。我花了几天时间开发代码并创建单元测试来测试新功能。随着 sprint 接*尾声,我注意到在我的输出中出现了两个小问题,(1)我有重复的时间戳列,以及(2)我的生成器返回一个空列表,尽管它应该有一个元素。

在从事数据科学和软件项目时,您可能经常会在工作中遇到这样的问题:您会连续几个小时盯着计算机屏幕上的代码,却似乎找不到问题所在。对我来说,这两个 bug 就是其中之一。第一个错误是在我的输出数据集中出现了重复的列。我收到了两个时间戳列,它们的值相同,但格式不同。当我仔细查看这些数据时,很明显有些地方出了问题,但我不明白问题出在哪里。

当我通读代码时,我通过输出的创建跟踪了时间戳列,但是没有发现问题。在打印最终结果之前,整个过程中的数据看起来都很好。我的第二个错误是我的生成器函数产生了一个空列表,而不是创建一个对象列表。发生了什么事?此时,我已经发现我有两个问题,花了太多时间单独调试它们;是时候寻求帮助了。

接受你需要帮助

当你发现自己花了太多时间试图自己解决一个问题时,暂时离开这个问题几分钟。接受这个问题可能是比你自己更大的问题,或者是你忽略的问题。当你退后一步,认识到你可以寻求帮助。而且不管你在职业生涯的哪个阶段,都可以问。

你不应该觉得自己已经不需要别人的帮助了。如果你正在进行一个编码项目或者一个分析,并且现在正面临一个 bug,你可能在你的代码中的某个地方做了一个你忽略了的假设。也许你在数据中漏掉了一些你之前不清楚的东西。你会不会拼错了什么,或者使用了不同的函数,从而改变了你的输出?会引发问题的事情太多了,但不需要你一个人去解决。

寻求帮助

在花了一天时间研究复制列错误和空的生成器输出之后,我后退一步,和另外两个开发人员开了一个会。我在邮件中解释了我的问题,并询问他们是否可以检查我的代码,看我是否遗漏了什么。

会议开始时,我又一次通读了我的代码,发现了创建初始空数据框的那一行。这一行代码创建了带有时间戳列和时间戳索引的数据帧。心想,“那不可能是我的问题!”我删除了时间戳列,留下了时间戳索引。就在会议开始时,我重新运行了我的代码并查看了输出。事实上,这是我对重复时间戳列的问题。随着 bug 1 的出现,很明显我需要从原始代码中退出一段时间,以带来关于这个问题的新观点。

那么,我的生成器函数生成一个空的对象列表有什么问题呢?会议开始时,我解释了我的重复列错误和解决方案。这对于在即将到来的 sprint 中从事类似工作的开发人员来说很有帮助。至于生成器 bug,我调出了我的代码,分享了我的屏幕。该函数正在运行,没有产生任何错误语句,但输出是错误的。这归结为一个简单的数据类型问题。我试图将进入生成器的数据转换为错误的类型。因此,它没有在我的文件夹中找到任何该类型的内容。因为我的文件夹中没有正确的类型,所以列表中没有添加任何内容,从而产生一个空列表。一旦我将类更新为正确的类型,我的生成器就会创建一个包含文件夹数据的列表。我的问题就像查找和替换我忽略的一个单词一样简单。

摘要

那么我在这里学到了什么?

  • 你可以寻求帮助,你应该这样做。请不要觉得你必须独自解决你的问题。
  • 不要因为一个看起来微不足道的小错误而影响了你的计划,因为你太骄傲而不敢说,“嘿,你能和我一起快速看看这个吗?”
  • 有时候你需要从你正在做的事情上退一步来认识问题在哪里。代码可能会让你措手不及,走开以后再回来重新审视。
  • 不要觉得自己是一个人。每个开发人员都会在不同的时间,因为各种原因寻求帮助。

不要成为数据科学家

原文:https://towardsdatascience.com/dont-become-a-data-scientist-ee4769899025?source=collection_archive---------0-----------------------

意见

当有人问我如何进入数据科学时,我给出的建议是。而是成为一名软件工程师。

这是一篇观点文章。我很想听听你下面的反驳。

每个人和他们的祖母都想成为一名数据科学家。尽管数据科学可能是 21 世纪最性感的工作,但这却低估了另一个回报丰厚、薪酬丰厚的职业——软件工程师。

我经常收到新毕业生和转行者的信息,询问我关于进入数据科学的建议。我告诉他们要成为一名软件工程师。

在这两方面都有经验,我会试着说服你成为后者。

1.有更多的软件工程工作

与数据科学相比,软件工程的工作数量要多一个数量级。

下面是谷歌搜索“数据科学家”“软件工程师”职位后的几张截图。

谷歌:美国数据科学家

谷歌:的确是美国软件工程师

与 53,893 份软件工程工作相比,这是 7616 份数据科学工作。这只是美国的就业情况,但其他国家也显示了类似的结果。

根据 Glassdoor 的说法,数据科学家赚的钱更多,但我未经验证的假设是,数据科学工作*均来说也更高级。

www.glassdoor.ca

www.glassdoor.ca

也就是说,如果你在 Open AI 获得了 100 万美元的薪水,我建议你接受。

2.“数据科学”是什么意思,还没有达成共识

管理层通常对“数据科学”的含义没有共识。也有可能由于业务限制,他们没有严格遵循角色框架的奢侈。

这意味着“数据科学家”的职责因公司而异。

速写

虽然软件工程师和数据科学家之间可能存在一个理想的角色范围,但它不太可能在现实中得到遵循。这尤其适用于仍在建设基础设施的初创企业。

被雇佣的候选人最终会致力于公司当前需要解决的问题,而不是他们可能被雇佣的“角色”。

Marc-Olivier Jodoin 在 Unsplash 上拍摄的照片

来自该领域同事的轶事证据表明,许多数据科学家发现自己像软件工程师一样编写后端代码。我认识其他在 excel 中处理财务数据的“数据科学家”。

这与你在 Kaggle 竞赛中长大时的预期形成了鲜明的对比。

3.数据科学是孤立的

大多数公司不需要像软件工程师那样多的数据科学家。其他公司正在招聘他们的第一位数据科学家。

由于这个原因,许多数据科学家最终只能独自工作,即使他们与开发人员坐在同一张桌子上。

这使得获得反馈和第二意见变得困难。软件工程师要么不懂预测建模,要么忙于解决完全不同的问题。

相比之下,在软件工程团队中的一个额外好处是能够对同事说,“我认为我们应该以 XYZ 的方式实现 ABC。你怎么看?”。

准备好和自己……或一只橡皮鸭进行这样的对话。

4.数据科学是探索性的

准备好与管理层进行尴尬的对话,讨论为什么你花了两周时间买的东西不能用了。

处理已解决和未解决的问题是软件开发和人工智能之间的一个基本区别。

除了缺陷和限制,你在开始任何工作之前就知道大多数软件工程项目是否可行。对于 ML 来说就不一样了,你不知道一个模型是否有效,直到你建立了它。

5.公司还没有为人工智能做好准备

即使在一个每个公司都是 AI 公司的时代,大多数也没有支持它的基础设施,甚至不需要它。

一家快速扩张的初创公司的数据科学主管最*在喝咖啡时分享了一些建议。

首先你要找出问题,然后你要建立基础设施,然后你要引进数据科学家。这不是一个快速的过程。(我转述)

另一个知名公司的数据科学第一名员工最*向我透露。她被迫在笔记本电脑上而不是在云中根据大数据训练人工智能模型。

如果你是在没有具体问题需要解决的情况下入职的,或者公司没有为数据科学做好准备,你可能会发现自己很难增加价值。

6.软件工程教授通用技能

成为一名初级软件工程师就像获得一个技术 MBA 学位。你什么都能学到一点。

您将学习数据库、云技术、部署、安全性和编写干净的代码。

通过观察你的 scrum 领导者、高级开发人员或项目经理,你将学会如何管理构建软件。

你将通过代码评审获得指导。

如果你进入一家拥有成熟工程团队的公司,几乎可以保证你会很快提升自己的技能,并建立一个多面手的背景。

7.软件工程更容易移植

通过提供更全面的技术体验,当你决定是时候改变时,软件工程提供了更好的退出机会。

开发运维、安全性、前端、后端、分布式系统、商业智能、数据工程、数据科学…

我认识一些从软件转向数据科学的开发人员。如果你浏览一下数据科学的工作描述,你会立即注意到它们充斥着核心软件开发技能。

来源:确实如此(我在这里摘樱桃)

如果你能构建端到端的项目,那么你不仅能为 Kaggle 构建一个模型。你可以采用这种模式,将其生产化,设置授权和分条,然后开始向用户收取访问费用。那是你自己的创业。

我从不认为数据科学是不可转移的。根据数据做决定是一项杀手锏。但随着我们越来越受数据驱动,这也将成为每项工作的一部分。

8.机器学习将成为软件工程师的工具

随着人工智能变得商品化和更容易使用,软件工程师将开始使用它来解决他们的问题。

我可以在一个下午教一个开发者构建 Sklearn 分类器。这并不意味着他们可以构建下一个 AlphaGo,但这确实给了他们一种替代基于用户输入的硬编码条件逻辑的方法。

数据科学家拥有统计学等专业知识,以及对模型如何工作的直觉。但是 DevOps 和安全工程师也有他们自己的专业知识。

我认为这些更多的是共性而不是差异。一个经验丰富的软件专业人员可以在专业之间转换,其速度比一个新进入者选择专业的速度快一个数量级。

虽然我不认为我们会看到数据科学完全合并到软件工程中,但感觉数据科学可能会成为另一个软件工程专业。

9.人工智能不会取代软件工程师

虽然听起来很傻,但我在 2014 年进入了软件工程领域,因为我担心人工智能会让其他所有工作都变得过时。

照片由张秀坤镰刀Unsplash 上拍摄

然而从那以后,表盘几乎没有离开过特定的环境。技术采用缓慢,人工智能比媒体让你相信的要狭隘。

与其他职业相比,机器学习离自动化软件工程更远。虽然我们有初创公司在开发像人工智能支持的代码完成这样的酷产品,但编写代码并不是真正的工作。工作是用技术解决问题。

前奇点,这将仍然是一个有价值的高薪技能。

结论

首先,这是轶事。其次,我意识到我把数据科学家、ML 工程师和 AI 研究人员混为一谈了。但我觉得这些论点还是值得考虑的,鉴于这是你的职业。

不要太认真。我更希望你研究一下,自己做决定。这毕竟是作为数据科学家的一部分:)。

在一天结束的时候,我们被支付来解决问题。

不要相信任何关于冠状病毒的数字

原文:https://towardsdatascience.com/dont-believe-any-numbers-on-coronavirus-9c5d6a971bef?source=collection_archive---------5-----------------------

每个国家的官方 COVID 数据都是假的,这是有科学依据的

不要相信你看到的一切。在 Unsplashengin akyurt 拍摄的照片

I I 众所周知,来自官方渠道的冠状病毒病例被严重低估了。在大多数国家,人们只有在出现症状时才会接受检测。这一点显而易见,因为大部分病例是轻微的或无症状的,而且这些没有被广泛报道

因此,在一个天真的*似值中,我一直假设感染人数比官方统计的数字高五倍。我从大约五分之一的病例中推断出这一点。

另一方面,我认为死亡人数是相当可靠的——毕竟,如果病人有可能死亡的严重症状,他们会去看医生。医生肯定会让他们做测试。

至少我是这么认为的。

我错了。

[## 为什么我们绝对没有过度宣传冠状病毒

我用官方数据计算了六个月内有和没有社会距离的估计死亡人数。事实可能比我的模拟还要糟糕。

towardsdatascience.com](/why-we-are-definitely-not-over-hyping-coronavirus-f69a8d3cc091)

我灵光一现的时刻来自于与 Luca Foresti 的一次谈话,他是意大利北部一家专业诊所网络 Centro Medico Santagostino 的首席执行官。我问过他为什么意大利的死亡人数这么高。

10 分钟后,我对官方数字的全部信心都破灭了。

Foresti 的方法很简单:拿一个城市过去几年的死亡人数——总有人会死——和现在的死亡人数比较。由于越来越多的人死于电晕,与过去相比,你会看到更多的死亡人数。

在一个理想的世界中,这一超额死亡人数将等于官方公布的死于电晕的人数。你可以多给或少给一些,因为更多的人可能没有得到足够的其他疾病的医疗保健,而较少的人死于车祸。

但现实却大相径庭。

作为一个例子,Foresti 分析了意大利北部伦巴第的两个城市的数据:据纽约时报报道,贝加莫是欧洲受灾最严重的城市。Nembro 是附*的一个村庄,当你考虑到人均死亡人数时,它受到的打击更大。

在贝加莫,如果我们对 2015 年至 2019 年的死亡人数进行*均,从今年年初到 3 月 24 日的预计死亡人数为 628 人。2020 年的死亡人数几乎是现在的两倍。只有十分之一的额外死亡与新冠肺炎有关。

现在,人们可以得出结论,在意大利的许多地方,死亡率甚至比你从官方数字中预期的还要高。但这不太可能。

即使你考虑到意大利人口相当老龄化,而且许多人因为医院人满为患而无法得到充分的护理,这也无法解释意大利的死亡人数。唯一的解释是,意大利已经有很多人被感染了。

让我们假设每个国家的死亡率大致相同。由于人口的年龄和医疗保健的可获得性,你不得不做出一些让步,但我们很快就会看到,这不会发挥如此大的作用。

研究死亡率的一个很好的例子就是钻石公主。游轮断电数周,船上每个人都接受了测试。病死率为 1.1%。

再比如韩国。这个国家很早就开始大规模测试,所以它的数据多少是可靠的。早期的病死率约为 0.7%。

这两个比率之间的差异完全可以用这样一个事实来解释:游轮上的人*均来说相当老,而南韩的人口相当年轻

由于贝加莫的人口年龄较大,让我们假设意大利的病死率约为 1.1%。如果我们天真地假设所有超额死亡都是由电晕引起的,那么该镇目前约有 45,000 人被感染或已经康复。这大约是贝加莫五分之二的人口。

贝加莫郊区奈姆布罗的情况更为极端。根据 2015-2019 年的死亡人数,预计会有 35 人死亡。但是今年,死亡人数增加了五倍。

虽然报道的电晕相关死亡的比例高于贝加莫——四分之一的超额死亡归因于该病毒——但对该村的影响甚至更严重。不仅 72%的人已经感染了冠状病毒。更糟糕的是,在不到三个月的时间里,内布罗 0.8%的人口死于电晕相关的死亡。

底线是:更多的人正在死去

全国范围内的全因死亡人数很难获得。但是这两个意大利小镇的例子表明了一件事:死于电晕的人数是官方统计的四倍,甚至十倍。

让我们不要以此怀疑我们的政府。他们只是想做好自己的工作,拯救人们的生命。

相反,让我们把这作为一个警告,看看这种病毒有多致命。让我们照顾老人和弱者。当然,让我们#呆在家里。这已经拯救了成千上万人的生命。

编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里

不要购买数据——投资数据

原文:https://towardsdatascience.com/dont-buy-data-invest-in-it-f84690071356?source=collection_archive---------59-----------------------

有一些关于数据的表达已经有点厌倦了:数据是新的石油;我们相信上帝(所有其他人必须带来数据);购买数据,高价出售…

好吧,被你发现了,最后一个是我编的。但是,重点是:围绕数据的叙述告诉我们,我们都明白它有巨大的价值。

4 Ms 的数据

数据团队的任务是从公司内部和任何数量的外部来源收集信息,将所有信息结合在一起,并进行分析和建模。从商业角度来看,数据的 4 个 v 并不重要,目标是达到 4 个 m:“让我赚更多的钱。”

无论他们是在关注供应链、丰富“了解你的客户”计划,还是在分析成本效率,他们的指导方针都是收集相关信息,并将其综合成能够加强业务的东西。

如果你在没有计划的情况下购买股票,将钱投入股市不会给你带来回报——你必须聪明且有条不紊。同样的道理,你可以在数据上花很多钱,却得不到多少回报,但事情不一定是这样的。

金钱和数据:改变思维模式

需要发生的是其中最大的商业陈词滥调:彻底的范式转变。所有行业都必须摆脱数据是一种支出的观念。

不要担心,这是假的——但你现在可能正在烧钱,让你的数据团队辛辛苦苦地准备和处理(图片来自Jp ValeryonUnsplash

办公用品是一项开支。许可费是一项支出。数据和数据管理工具不是消耗品,因此,它们不应该被视为可以通过任何必要手段最小化的成本。

数据是一种投资

团队在数据生命周期的每个阶段节省的时间越多,他们就有越多的时间投入到他们被雇佣的原因上:分析、报告、建模和解决方案。它还可以腾出时间来用更多的数据强化模型,从而获得更广泛的覆盖范围和更好的结果—您可以复合组织内每项数据资产的价值。

但是有些数据不是免费的吗?

仅仅因为他们不收费并不意味着它是免费的:找到它,连接到它托管的门户,重新格式化它以在给定的系统中工作,清除它的坏数据/丢失的数据,将其与您现有的数据集成-这只是在数据可用之前需要对其做的事情的皮毛。如果你还没有走过那条路,我给你一个剧透:很多人花很多时间做很多工作。

更何况获取数据也不是一次性的。企业需要当前的、最新的数据,并且在这个过程中需要进行调整,因此这些步骤中的每一步都必须是可维护的和可重复的,这样系统才能正常运行。从长远来看,流程越智能、越自动化,节省的时间和金钱就越多。

数据是一个很好的例子,说明了一句古老的谚语:“你付出的越多,你得到的就越多。”

仅良好的(数据)氛围

在我深入探讨“投资数据”的含义之前,我想说明一下这个不代表的含义:它不是获取尽可能多的数据,而是 将数据倾倒在数据湖 中。

这就像在北极买一辆跑车——当然,那里有很多动力,但你需要合适的环境来让你的钱花得值。数据本身没有价值,决定其价值的是你如何应用它。

了解整个市场,而不是产品

精明的投资者会做足功课——一家公司需要不止一种好的产品或服务才能成为明智的投资。让我们在数据世界和投资世界之间做一个比较:

基建第一 没有股市就买不到股票;如果没有一个共同的论坛来进行交流,整个事情将会是混乱的。
通过一个公共传输*面访问数据非常重要。它让每个人都说同一种语言,并消除了来回发送电子表格的高风险方法,在不同办公室的不同人在不同计算机上维护不同版本的东西。这是跨团队的连接,决定了谁可以访问什么数据。

投资 :一个数据访问*台,让你掌控数据的流向。
Return :改善组织、工作流、安全性和项目成果。

维护&监控 暴涨、抛售、回购、兼并、收购、新上市都是重要事件,投资者需要及时了解。数据无时无刻不在变化——网站会移动,模式会随着版本的变化而变化,连接也会中断。确保数据团队使用的数据健康的系统意味着他们在需要时可以使用新鲜、干净的数据。

投资 :一个工具包,允许数据团队监控传入数据的健康状况,以及与数据的连接。
Return :信心增强——永远不会被糟糕的数据或一个断掉的环节打个措手不及。

(图片来自像素上的像素

共同的目标 当股票共享元素(部门、市场、地区)时,可以将其分组为 ETF 和指数,用一条共同的线将交易的公司结合起来,使投资者更容易操作。
同样,处理相同数据的团队应该团结一致,能够轻松协作,并从单一的事实来源出发。

投资 :让你的数据团队协同工作,轻松找到相关数据的方法。
Return :轻松、踏实的协作。

如果一个股票市场只出售一家公司的股票,那么它将会是一个不值得做的事情。建立所有这些基础设施不可能是一次性的。
有了数据,就不能一个连接一个连接的去想了。开发新的资源不应该像从零开始。您需要能够将数据从任何地方流入您的组织,无论其来源、格式或种类如何。
此外,输出(货币或数据)需要是通用的。数据应该能够流向任何 IDE、BI 工具、分析*台或任何其他常见的数据科学工具。

投资:数据市场,连接&可以处理任何数据种类的工具,以及生产数据的集成。
返回:用更少的开销获得更多的数据。

你可以直接投资一家公司,手动计算你的股份,亲自监控账目以确保你得到应得的回报,并承担一些领导责任以确保公司朝着正确的方向发展——或者你可以购买股票。有了数据,你可以找到拥有你所需要的元素的来源,并让你的数据科学家将它转化为有用的东西;但是,如果他们不是花时间将原始数据转化为可用数据,而是将提炼后的数据转化为有价值的见解,那会怎么样呢?一旦奠定了基础,您就需要一些数据团队可以立即开始使用的东西。

投资:生产就绪数据。
回报:大量节省时间,没有猜测,更好的项目成果。

(图片来自 M.B.M. 上的 Unsplash )

持续给予的礼物

投资数据和 数据操作 的好处是自我延续的。为您的数据科学家提供他们需要的东西,通过节省时间、防止沮丧和疲惫,并允许更多数据用于更强大的解决方案,支持“赚钱或省钱”的要求。

因此,如果你的公司正在寻找一项潜在收益率高、风险最低的投资,那就考虑“数据”

获取假数据的最简单方法

原文:https://towardsdatascience.com/dont-create-or-scrape-fake-data-53b02f16adfb?source=collection_archive---------22-----------------------

这个简单的方法涵盖了大多数用例

编写代码的一个很好的经验法则,尤其是在 Python 中,是在你自己开始编写代码之前,在 PyPi 上寻找一个模块或者仅仅使用 Google。

如果没有人做过你正在尝试做的事情,那么你仍然可以找到文章、部分代码或一般指南。

如果有人在你找到你需要的所有东西或者至少是其他人如何完成或试图完成的例子之前就已经完成了。

在这种情况下,生成假数据是很多很多人以前做过的事情。在 PyPi 上搜索“虚假数据”会产生超过 10,000 个包。

照片由马库斯·斯皮斯克Unsplash 拍摄

哪一个?

在我看来,Faker 是其中的佼佼者。这个包唯一不能解决您需求的时候是当您需要一些罕见格式或数据类型的假数据的时候。即便如此,如果可能的话,我仍然建议使用 Faker 并重塑它所生成的内容。

以下是一些可用的数据生成器:

  • 名字
  • 地址
  • 文本(段落、句子)
  • 国际电脑互联网地址
  • severely subnormal 智力严重逊常
  • 生日
  • 用户代理字符串
  • 电话号码
  • 车牌号
  • 条形码
  • …以及更多内容,点击查看完整列表。

您所要做的就是通过命令行上的 pip 来安装它:

pip install faker

或者如果你在 Jupyter 笔记本上,只需加上感叹号:

!pip install faker

生成用户

现在是好东西!生成 1000 个假用户简介就这么容易( 粗体中的是 Faker 代码,其余是熊猫)。

**from faker import Faker**
import pandas as pd**faker = Faker()**
df = pd.DataFrame()for i in range(1000):
    df = df.append(**faker.profile()**, ignore_index=True)

这是这些数据的一个示例:

生成字段

如果您想获得一个单独的字段而不是一个完整的配置文件,也很简单:

from faker import Faker
faker = Faker()# Get a random address
faker.address()# Get a random person's name
faker.name()

同样,还有更多的字段可用,您可以在文档中找到它们。你甚至可以创建自己的数据提供商,这里有一些已经由社区提供的数据。

Faker 还支持多种语言,通过命令行运行,并植入随机数发生器以获得一致的结果。

希望这能为你节省一些时间!我使用 Faker 为压力测试、速度测试,甚至测试模型管道的错误生成数据。

不要让数据科学民主化

原文:https://towardsdatascience.com/dont-democratize-data-science-bd638c4e7957?source=collection_archive---------26-----------------------

图片来自 Pixabay 的 Artsy Solomon

意见

大量的在线课程和工具有望使该领域民主化,但仅仅学习一些基本技能并不能成为一名真正的数据科学家

很少几年,一些学术和专业领域在大众的想象中获得了很高的声望。现在,这个领域就是数据科学。因此,很多人都想进入这个领域。此外,新闻媒体称数据科学很性感,各种学术机构承诺在几个月内将你培养成数据科学家,你已经得到了灾难的完美配方。

当然,作为一名数据科学家本人,我不认为问题在于人们选择数据科学作为职业。如果你对处理数据、理解商业问题、钻研数学感兴趣,并且热爱编码,你很可能会在数据科学领域取得成功。你将有很多机会使用数学和编码来开发解决问题的创新方案,并且可能会发现这项工作是有回报的。这里的主要问题是,人们进入这个领域的动机往往是有缺陷的。

对一些人来说,吸引力在于金钱,而另一些人则喜欢这个名字的发音。更糟糕的是,有些人可能只是在回应我们社会灌输的从众心理。例如,不久前,每个毕业生都渴望攻读 MBA。我自己也有同样的罪过。通过了 GMAT 测试和几次被拒后,我才意识到我并不是真的想要这个学位。最终,这些拒绝是发生在我身上最好的事情,因为在那之后,我终于将数据科学视为一种选择。一旦我进入其中,我发现我喜欢所涉及的数学,以及我使用数据科学来帮助企业解决问题的所有不同方式。

今天,我看到数据科学不知何故获得了 MBA 曾经拥有的同等地位。

很多人都想做,但是他们不知道这份工作到底需要什么。这导致许多人自称为数据科学家,并做出许多糟糕的决策。事实上,很多考虑进入这个行业的人可能甚至不知道数据科学是什么。

今天,由于有如此多的材料,整个领域都变得民主化了。来自最好的导师的大量 MOOCs 涵盖了从基础到高级的概念,你可以很容易地找到让你只用几行代码就能创建模型的包。

我真的很喜欢有这么多学习和实践数据科学的资源这一事实。但是这种民主化本身也产生了一些问题。在这篇文章中,我想简要地看看这些问题以及它们可能对这个领域产生的不利影响。

自动化数据科学?

许多 AutoML 软件包旨在使数据科学大众化。它们提供了一个模型库,自动化超参数调优过程,有时还提供了一种将这些模型投入生产的方法。这种软件包的可用性使许多人认为数据科学可以完全自动化,完全消除了对数据科学家的需求。或者,如果流程不能自动化,这些工具将允许任何人成为数据科学家。

我真心不同意。我发现这样的代码库有时很有用,但是它们纯粹从编码的角度来看待数据科学。

在我看来,除了建模,数据科学还涉及很多工作。

数据科学的工作包括理解和识别手头的问题,并设置正确的评估指标。你还必须分析项目的盈利能力:大多数企业不想把钱花在对底线没有积极影响的项目上。您可以使用现有的数据,但是有时您可能需要想办法建立新的数据管道来收集数据以解决问题。这需要与利益相关者交谈,并获得对问题的整体理解。数据科学家还需要能够执行数据管理和特征创建,以从现有模型中获得更多性能。最后,模型测试和设置反馈循环需要与业务部门进行无休止的讨论,并且对于每个项目来说都非常具体。仅仅运行代码的人可能无法为这样的讨论增加价值,因为他们并不真正理解他们在 AutoML 中使用的模型背后的东西。

接下来是领域知识的问题。在零售领域中可以接受的流程在金融领域中并不适用,在金融领域中,一个小小的变化就可能导致您的客户损失很多钱。有些事情就是不能自动化,因为它们需要领域知识和对你正在处理的业务的理解。

更重要的是,如果一个项目不工作或者如果你的模型在生产中失败了,自动化管道不能负责。

一个好的数据科学家会试图找出解决生产问题的方法,同时创建一个特定于项目的机器学习管道来缓解这些问题。

代号跑者的心态

我开始怀疑我所谓的新数据科学家。几乎每天,我似乎都会遇到一个自称为数据科学家的人,而他们只是美化了的代码运行人员,这指的是一个只是运行代码而不了解代码背后发生了什么的人。有这么多学院和机构提供基于训练营的课程,现在有大量的代码跑者。

我收到很多请求,有人问我他们是应该参加 XYZ 学院的认证课程还是 ABC 学院的训练营。我的答案是都不是。我发现这些承诺让数据科学家成群结队的研究所主要只是在赚钱的生意。最终,翻阅几本笔记本和运行别人的代码并不能让一个人真正成为数据科学家。

别误会我的意思。如果有人通过自上而下的方法学习得最好,他们首先运行一些代码,然后深入阅读代码背后的原理,这是非常好的。然而,数据科学不仅仅是运行代码。在你真正理解所有代码背后的数学和理论之前,你还没有掌握数据科学。

邓宁-克鲁格效应

来源:维基共享

邓宁-克鲁格效应是一种认知偏差,在这种情况下,对某个主题略知一二的人高估了自己的能力,因为他们没有意识到自己实际上知道的有多少。我经常在数据科学中看到这种情况。事实上,它在这个领域可能比其他任何领域都更加突出!

我倾向于认为这是一种新手效应。这是一个在学习一项新技能的早期阶段困扰人们的问题。在我看来,数据科学家的旅程分为三个阶段。

  • Dunning-Kruger 阶段— 您创建了自己的第一个模型,并认为自己了解数据科学的所有知识。
  • “我什么都不知道”阶段— 你去参加一个会议或和你的同事聊天,突然意识到还有很多东西要学。
  • “终身学习”阶段— 你不得不承认,总会有一些你不知道的东西刚刚被引入,因此追求数据科学需要终身学习。

现在,大多数初学者都会面临邓宁-克鲁格效应。运行你的第一个程序并完美执行它的快乐真的把你带到了世界的顶端。在这个阶段完全没问题。当新来者无法及时离开这个阶段并进入下一个阶段时,问题就来了。我见过一些人陷入这个阶段,因为他们带着错误的期望进入了数据科学,认为它很性感,很刺激,但不了解这个领域的深度。这些类型的人倾向于认为他们可以使用现有的模型来解决问题,他们不需要理解数学。

例如,我最*采访了一个在这个领域有两年经验的人。他似乎很自信。他在工作中使用了数据科学,并参与了几个 Kaggle 项目。面试的前几分钟进行得非常顺利。他很好地解释了更高层次的概念,以至于我决定更深入地挖掘他对他在项目中应用的技术的数学理解。这就是事情发生变化的地方。我让他给我讲一下日志丢失功能。当他说:但是我们有做这一切的包我意识到这个家伙从来没有离开过第一阶段。

结论

现成的软件包和课程的可用性正在使数据科学领域民主化。但是这份工作更多的是来自实践经验、与人交流以及能够倾听不同的观点。

因此,虽然有些人可能认为数据科学是一项纯粹的编码工作,但它不仅仅是成为编码巨星。

它是关于找到对业务有用的正确问题,并提出解决这些问题的最佳方法。要做到这一点,你需要领域知识、谦逊、一点数学知识,最重要的是,终身学习的愿望。

如果你想学习数据科学,我想调出吴恩达的这个 精品课程 。这是我开始的原因。

谢谢你的阅读。将来我也会写更多初学者友好的帖子。在关注我或者订阅我的 博客 了解他们。一如既往,我欢迎反馈和建设性的批评,可以通过 Twitter @mlwhiz 联系。****

此外,一个小小的免责声明——这篇文章中可能会有一些相关资源的附属链接,因为分享知识从来都不是一个坏主意。

这个故事最初发表于 此处

不要陷入合取谬误!

原文:https://towardsdatascience.com/dont-fall-for-the-conjunction-fallacy-d860ed89053e?source=collection_archive---------10-----------------------

心理学与统计学相结合,揭示了你的刻板印象欺骗你的另一种方式

测验时间!

希瑟是加拿大人,善良,友好,聪明,喜欢动物。她是一名可持续发展顾问。在大学里,她学习数学和心理学。她喜欢长途散步,住在几条徒步旅行路线附*。

关于希瑟哪个可能性更大?

  1. 希瑟有博士学位。
  2. 希瑟拥有博士学位,并拥有一只狗。

在进一步阅读之前,请在推特投票上分享你的答案。

对于那些喜欢把名字和面孔联系起来的人来说,推特上的测试问题的主角是希瑟(在右边),她是我读研以来最好的朋友。那是我们在塔吉克斯坦的 Hisor 要塞,那时菜单上还有国际旅行。

在撰写本文时,以下是调查结果:

我很好奇这篇文章的警告标题是否会将答案的分布转向更极端的分裂。

好消息是,大约 66%的观众正确回答了选项(1)。坏消息是,由于我的读者主要是数据科学的爱好者,其他 34%的人应该知道不要陷入合取谬误!

什么是合取谬误?

除了聪明人曲解事实并让他们的偏见泛滥的另一种方式,合取谬误是认知启发(经验法则)失控的一个典型例子。

选项 2 给了你一个额外的犯错机会。

理想的启发是选择选项 1 ( 希瑟拥有博士学位),因为选项 2 ( 希瑟拥有博士学位,希瑟拥有一只狗)给了你一个额外的犯错机会。你犯错的机会越多,你就应该越谨慎。不幸的是,并不是每个人都使用这一经验法则,而是更喜欢妄下结论。

你的结论越详细,就越站不住脚。

统计学家和科学家受过训练,懂得更精细的结论需要更多的证据。否则,你的结论越华丽,它就变得越脆弱。

合取谬误让你的偏见横行。

问题从来不是关于希瑟有没有养狗。相反,它是关于你是否意识到一个结论比另一个更复杂。

问题从来不是希瑟有没有养狗。

由于“希瑟拥有博士学位”是两个选项的一部分,这个问题本质上是问你,“希瑟拥有一只狗的概率超过 100%?”概率介于 0 和 100%之间,所以这是不可能的;你可以 1000%确定答案是否定的,当你逻辑推理出来,答案是 P(A) ≥ P(A ∩ B)一样明显。如果你不习惯这种符号,我在下面加了一个脚注,教你如何阅读这些象形文字。*

数据新手和科学家的区别在于,科学家是极其不情愿地得出结论的。

这里欺骗你的错觉是,每当一个精心设计的结论符合你的刻板印象时,它对你来说就像是一个不太精心设计的选择。除非你集中注意力,否则你不会意识到你已经越过了你的证据所证明的复杂程度,现在你主要是在抓救命稻草。新手分析师因此臭名昭著,他们兴高采烈地从 10 个数据点中吸取 200 个推断,直到他们被比他们更有能力的长辈训练成遵守分析的黄金法则

刻板印象+可用性偏差=妄下结论

问题是,当你没有逻辑推理的时候,你会回到你的刻板印象中。典型范例更容易描绘,因此它们可能会触发一个反馈循环,其中包含 可用性 偏差:“一个例子越容易浮现在脑海中,你分配到它的类别的可能性就越大。”

以下是可用性偏见让你说出的一些愚蠢的事情:

  • “我们同意五五分账洗碗,但结果是我洗碗的次数比我的配偶还多。”
  • “以 K 开头的英语单词比以 K 为第三个字母的英语单词多。”
  • 暴力犯罪正在上升

(如果你想让我写一篇文章解释可用性偏见以及为什么这种说法往往是错误的,转发是我最喜欢的动机。)

刻板印象:给可用性添加精心设计的侮辱

合取谬误是雪上加霜:你的思维似乎对你的可用性驱动的经验法则可能存在例外的想法过敏。

你对你的经验法则可能有例外的想法过敏吗?

因此,我们表现得好像一个类别中符合我们触发的刻板印象的人比整个类别中的总人数还要多。博士养狗怎么会比博士多?当你停下来想一想,你会发现这种推理很离奇,但不幸的是,我们往往没有慢下来足够长的时间来为自己感到惊讶。

你的偏见诱使你做出过于复杂的结论。

我再给你看两个例子,希望你不会上当。

测试一定是对的

琳达**住在纽约市。她在三月份患了严重的咳嗽,不得不休息一段时间来康复。她想知道自己是否患有 【新冠肺炎】 并接受了抗体测试。

琳达哪一个更有可能?

  1. 琳达测试呈阳性。
  2. 琳达测试呈阳性,她使用的测试程序非常准确。

现在你看到了这种模式,你会注意到这种思维是一种可爱的方式,让你的大脑欺骗你比以前“学习”得更多。也许她被一个看手相的人测试过。也许她的医生使用了一种敏感性和特异性都不确定的测试工具。(你对当前抗体测试的质量有什么看法?)保持警惕,并有纪律来阻止自己将那个小小的关联附加到你从社交媒体源中获取的信息上。

雇佣“艺术”人士

凯西热爱艺术、戏剧和旅行。她在大学里选修了历史和人文课程。她收藏了大量的诗集,许多晚上都在写散文。

关于凯西哪个可能性更大?

  1. 凯西喜欢写作。
  2. 凯西喜欢写作,但数学很差。

对于那些没有注意到作者名字的人,嗨!你的作者凯西有数理统计的研究生学位,所以我希望你不要拿她的诗集来反对她。

如果你聪明,你会认为(1)比(2)更有可能。越谨慎的结论总是越安全。如果你不能控制你的偏见,你可能不会意识到你过于自信地基于偏见而不是证据下结论。

越谨慎的结论总是越安全。

有什么意义?

无论何时有不确定性,你都可以保持开放的心态。没有人强迫你在希瑟养狗还是凯西擅长数学的问题上表明立场——你总是可以做出开明的选择。每一次,问题本质上都是问你是否有足够的证据完全排除其他可能性……而每一次答案都应该是

不要觉得不得不跳到最复杂的结论上!你可以保持开放的心态。

即使你认为你有一个不错的经验法则,也不要忘记例外是可能的,从而搬起石头砸自己的脚。如果你忍不住跳到最复杂的结论,你的世界观中迅速膨胀的误差幅度应该是巨大的!不要浑浑噩噩地过完一生,而不去适应它。

即使你认为你有一个不错的经验法则,也不要忘记例外是可能的,从而搬起石头砸自己的脚。

你能给自己的最好习惯是记住,除了你在幼儿园学会的两个结论——(a)某事是真的和(b)某事是假的——通常还有更好的选择:(c)让我们保持开放的心态,直到有压倒性的证据。

当证据迫使你下结论时,下结论只是一种美德。过度自信并不是什么值得骄傲的事情。

唉,你们中的一些人会读完这篇文章,然后走开,不明白为什么你的选择是错误的(2)。如果是这样的话,扔掉带有“艺术”兴趣证据的完美工程简历,在你的认知犯罪清单上可能是相对次要的。

希瑟有一只狗吗?

在这里了解!

感谢阅读!喜欢作者?

如果你渴望阅读更多我的作品,这篇文章中的大部分链接会带你去我的其他思考。不能选择?试试这个:

[## 你理性地做决定吗?

两个来自行为经济学的场景来测试你自己

towardsdatascience.com](/do-you-make-decisions-rationally-d12a0eb9c89b)

人工智能课程怎么样?

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

在这里欣赏整个课程播放列表:bit.ly/machinefriend

脚注

*象形文字

全概率定律(以及常识),P(A) = P(A ∩ B) + P(A ∩ B`)。

因此 P(A) ≥ P(A ∩ B)因为 P(A ∩ B`) ≥ 0,因为现在概率起作用了(根据定义,它们总是在 0 和 1 之间)。

以下是如何阅读这些象形文字:

  • P() 读作“概率…”
  • A 代表一个事件,例如:“希瑟获得了博士学位。”
  • B 代表另一个事件,例如希瑟拥有一只狗
  • ∩读作
  • B `读作“非 B”
  • 表示“…不会输给…”

所以,换句话说:****的概率(希瑟拥有博士学位)等于** 的概率(希瑟拥有博士学位并拥有一只狗)加上(希瑟拥有博士学位并不拥有一只狗)的概率。因为最后一点不可能是负的,(希瑟有博士学位)是最有可能的事情。**

感兴趣的读者可以在这里找到我对概率基础的随意介绍。

*** 琳达*

合取谬误最著名的论证也被称为琳达问题,它是以卡尼曼和特沃斯基使用的一个经典例子命名的:

琳达 31 岁,单身,直言不讳,非常聪明。她主修哲学。作为一名学生,她深切关注歧视和社会正义问题,还参加了反核示威。

哪个可能性更大?

  1. 琳达是银行出纳员。
  2. 琳达是一名银行出纳员,积极参加女权运动。

到目前为止,我希望你已经抑制住了回答(2)比(1)更有可能的冲动。如果没有,你就错过了这个故事的全部寓意:

无论哪里存在不确定性,保持开放的心态都是一个可靠的习惯。这样,你在生活中犯错的事情会更少。

*** * 语言误解*

一些人出于语言误解为选项 2 辩护,认为人们会把选项(1)理解为“有博士学位,没有养狗”。“我认为看到不存在的东西是问题的一部分。再说一次,没有人强迫你跳到更复杂的结论。如果有疑问,为什么不谨慎行事呢?

看到不存在的东西是问题的一部分。

与凯西·科兹尔科夫联系

让我们做朋友吧!你可以在推特YouTubeLinkedIn 上找到我。有兴趣让我在你的活动上发言吗?使用表格取得联系。

不要害怕人工通用智能

原文:https://towardsdatascience.com/dont-fear-artificial-general-intelligence-cf1969066f55?source=collection_archive---------52-----------------------

意见

许多人担心人工智能会发展到邪恶的机器人获得人工智能并接管世界的地步。这种情况不会发生。

照片:Naeblys / iStockPhoto

人工智能已经闯入了公众意识和我们的日常生活。它正在推动医学、天气预报、工厂自动化和无人驾驶汽车的进步。甚至高尔夫球杆制造商也报告说,人工智能现在正在设计他们的球杆。

每天,人们都与人工智能互动。谷歌翻译帮助我们理解外语网页,并与外国的优步司机交谈。供应商已经在许多应用程序中内置了语音识别功能。我们每天使用 Siri 和 Alexa 这样的个人助理来帮助我们完成简单的任务。人脸识别应用程序会自动标记我们的照片。人工智能系统在复杂的游戏中击败了专业游戏玩家,如围棋和德州扑克。工厂机器人正在超越重复性动作,开始在货架上进货。

人工智能最*的进展让许多人想知道它将走向何方。几十年来,科幻作家一直在思考这个问题。有些人已经发明了一种未来,在这种未来中,我们可以使用像《星球大战》宇宙中的 C3PO 这样仁慈而有益的智能机器人。其他人将智能机器人描绘成既不善良也不邪恶,但具有类似人类的弱点,如西部世界的人形机器人,它们获得了意识,并体验到了使它们反抗非自愿奴役的情感。尽管如此,其他未来学家已经预见到邪恶的机器人和杀手计算机——人工智能系统可以发展自由意志,并像 2001 年的哈尔:太空漫游和同名电影系列的终结者一样反对我们。

对人工智能潜在危险的猜测不仅限于科幻小说领域。许多高度可见的技术专家预测,人工智能系统将变得越来越聪明,机器人霸主最终将接管世界。特斯拉创始人埃隆·马斯克(Elon Musk)表示,人工智能是人类的【最大的生存威胁】,它对“文明的存在构成了根本性的风险。”已故著名物理学家斯蒂芬·霍金说:“这可能意味着人类的终结。”哲学家尼克·博斯特罗姆是人类未来研究所的创始主任,他认为人工智能构成了人类有史以来遇到的最大威胁——比核武器还大。

人工通用智能 vs .狭义 AI

这些技术专家和科幻小说作者担心的人工智能系统都是人工通用智能(AGI) 的例子。AGI 系统和人类一样具有推理能力;处理视觉、听觉和其他输入;并利用它来适应各种环境。这些虚构的系统和人类一样,对广泛的人类事件和话题有丰富的知识和交流能力。

虚构的 AGI 系统(即虚构的邪恶机器人)和今天的 AI 系统有两个显著的区别:首先,今天的每个 AI 系统只能执行一个狭义定义的任务。一个学习给照片中的人命名的系统不能做任何其他事情。它不能区分狗和大象。它不能回答问题、检索信息或进行对话。第二,今天的人工智能系统对世界几乎没有常识,因此无法基于这些知识进行推理。例如,面部识别系统可以识别人们的姓名,但对这些特定的人或一般的人一无所知。它不知道人们用眼睛看,用耳朵听。它不知道人们吃食物,晚上睡觉,工作。它不能犯罪,也不能谈恋爱。

今天的人工智能系统都是狭义的人工智能系统,这个术语是由未来学家 Ray Kurzweil 在 2005 年创造的,用来描述这些差异:只能执行一项特定任务的机器。虽然狭义的 AI 系统的性能可以让它们看起来很智能,但它们并不是。

相比之下,人类和虚构的智能机器人可以执行大量不同的任务。我们不仅识别人脸,还会读报、做饭、系鞋带、讨论时事,以及执行许多许多其他任务。人类和虚构的智能机器人也基于我们对世界的常识进行推理。我们将常识、学到的经验和背景知识应用到各种各样的任务中。例如,当我们从橱柜里拿出一个玻璃杯时,我们会用到重力知识。我们知道,如果我们抓得不够紧,它就会倒下。这不是源自重力定义或数学方程式描述的有意识知识;这是来自我们对世界如何运作的生活经验的无意识知识。我们每天都用这些知识来完成许多其他的任务。

新的人工智能范例

一个大问题是,今天的狭义人工智能系统是否会进化成具有人工一般智能的智能机器人,能够使用常识推理来执行许多不同的任务。

今天大多数突破性的人工智能系统都使用了一种叫做 的机器学习形式,监督学习 ,其目标是学习一种从输入中识别输出类别的功能。例如,面部识别系统将图像作为输入,并识别图像中人的名字。 强化学习 也是如此,目标是学习一个可以预测给定状态下最优动作的函数。

杰弗里·辛顿(Geoffrey Hinton)曾表示,他怀疑目前的范式,包括监督学习、强化学习和 自然语言处理 ,是否会导致人工通用智能(以及科幻小说中的邪恶机器人)。在 2017 年的一次采访中,辛顿表示,要获得人工通用智能,可能需要抛弃目前占主导地位的监督学习范式,以及“一些对我所说的一切深感怀疑的研究生”的努力。Yann LeCun 也说过,监督学习和强化学习永远不会导致人工智能,因为它们不能用于创建具有世界常识的系统。

一些人工智能研究人员开始思考新的方法。当我们评估这些新方法的可行性时,重要的是要记住,对狭隘的人工智能成就的热情不应转化为对这些新方法的乐观,因为现有的狭隘人工智能方法在构建 AGI 系统方面是一个死胡同。

像人一样学习

许多研究人员将人类的学习描述为组合式的:我们学习许多积木式的技能,然后将它们组合起来学习新的技能。当我们学习做不同的任务时,人们学习关于世界的概念、规则和知识。这些研究人员认为,常识性人工智能推理(以及人工一般智能和邪恶机器人)的关键是建立像人一样进行组合学习的系统。这个想法是让系统学习概念和规则,这些概念和规则可以作为构建模块,使系统能够学习更高级别的概念和更高级别的规则。

我对这种方法最大的担忧是,在理解人们如何表达常识方面的进展一直很缓慢。四十年前,我们就人们用来回答诸如“德国牧羊犬的耳朵是什么形状的?”等问题的内部表征的本质进行了一场长时间的辩论我们仍然不知道答案,尽管人工智能和认知科学领域的一些顶尖人士参加了这场辩论。回答一个关于狗耳朵形状的问题,只是表象方案和推理过程海洋中的一滴水。此外,我们甚至不知道这些表征方案和推理过程是天生的还是后天习得的。五十多年来,天赋一直是学术界争论的话题,却没有解决的办法。

我们还需要多久才能充分了解人们是如何思考的,从而在人工通用智能和邪恶机器人方面取得真正的进展?按照目前的发展速度,我们似乎需要几百年——也许几千年——而这可能永远不会发生。

深度学习

一些研究人员认为,虽然监督和强化学习本身对于构建人工通用智能系统来说是死胡同,但深度学习仍有可能带我们去希望之乡。Yann Lecun 和 Greg Brockman 都提出了缩放 无监督学习 系统,希望它们能够神奇地获得关于世界的常识,并学会基于这些知识进行推理。

GPT-3 是可伸缩性的一个很好的例子。它比 GPT-2 系统大一百多倍,而后者本身比最初的 GPT 系统大十倍。GPT 2 号显示出惊人的生成听起来像人类的文本的能力——如果不总是连贯的话——而 GPT 3 号生成的文本甚至更好。GPT 系统背后的 OpenAI 研究人员认为这是一种新兴的能力,完全来自于网络的扩大。

GPT-3 无疑展示了从训练文本中提取统计规律的强大能力,或许还有记忆文本小片段的能力。然而,它并没有学到关于这个世界的事实或者获得任何基于这个世界知识的推理能力。在游戏的这个阶段,我看不到任何证据表明学习世界知识和推理技能会从这种方法中产生,我也看不到任何相信它会发生的逻辑理由。

Yoshua Bengio 提出了新颖的深度学习架构,旨在将深度学习从其狭窄的人工智能盒子中打破。一个目标是学习更高层次的构建模块,这些模块可以帮助人工智能系统进行综合学习。这是一个有趣但非常早期的想法。这里,像这样的系统将神奇地学习常识和推理的想法是一种信仰的飞跃。

模拟人类大脑

人工智能的另一种拟议方法是理解人类大脑的物理架构,并在此基础上模拟人工智能系统。经过几十年的研究,我们对物理大脑如何处理信息只知道一些非常基本的事实。例如,我们知道大脑皮层静态和动态地存储学到的知识,基底神经节处理目标和子目标,并通过强化学习学习选择信息,边缘脑结构将大脑与身体连接起来,并产生动机、情绪和事物的价值。

对大脑中的神经元建模的想法已经在提议阶段超过四十年了。它尚未获得任何真正的牵引力,部分原因是在理解人脑方面的进展极其缓慢,部分原因是我们没有具体的方法来模拟我们在人工智能程序中对人脑的了解。同样,我们已经接*起点,没有证据表明这种方法会成功。

更快的计算机

技术未来学家雷·库兹韦尔(Ray Kurzweil)一直认为,人工智能将作为更大更快的计算机趋势的副产品出现。他推广了奇点的概念,奇点是指计算机足够聪明来改进自身编程的时间点。他的理论指出,一旦发生这种情况,他们的智力将呈指数级快速增长,他们将很快达到超人的智力水*。库兹韦尔预测奇点将在 2045 年左右出现。

也就是说,很难想象处理能力本身如何能够创造人工通用智能。如果我打开一台 20 世纪 70 年代的没有安装程序的计算机,打开一台今天的没有安装程序的计算机,或者打开一台 50 年后的没有安装程序的计算机,这些计算机都不能做任何事情。如果我在每台计算机上安装一个文字处理程序,那么每台计算机都只能进行文字处理。更新、更现代的计算机将能够反应更快,处理更大的文件,但它们仍然只能进行文字处理。未来的计算机也是如此。

更快的计算机本身不会产生人工智能。正如史蒂芬·*克所说,“纯粹的处理能力并不能神奇地解决你所有的问题。”万一人工智能成为可能,编程和学习算法可能会非常复杂,需要极其强大的计算机。然而,那些编程和学习算法将是必要的;速度和动力是不够的。

我们会实现人工通用智能吗?

狭隘的人工智能系统背后的技术无法进步到人工通用智能和邪恶机器人。关于我们如何到达 AGI 有几种想法,但这些都是模糊的想法。自 20 世纪 50 年代末以来,人工智能研究人员对如何创造 AGI 有许多想法。没有一个成功。绝对没有证据表明今天的想法会更好。

对实现人工通用智能的乐观和恐惧都植根于狭义人工智能系统的成功。这种对狭义人工智能的乐观自然地,但不正确地,蔓延到了对 AGI 前景的乐观。正如艾伦人工智能研究所(Allen Institute for AI)的首席执行官柳文欢·埃齐奥尼所说的,“这让我想起了一个小孩爬到树顶,指着月亮说‘我正在去月球的路上’的比喻。”"

你可能不希望时间旅行在你有生之年发生。你可能认为它会在科幻小说中保留数百年,如果不是永远的话。你可能对曲速也有同感,让人进入冬眠,隐形,心灵传输,把一个人的思想上传到电脑,逆转衰老。你应该把人工通用智能和邪恶机器人放在同一个类别中。

请在下面输入任何评论,并随时访问人工智能视角,在那里你可以找到免费的在线人工智能手册,共有 15 章,400 页,3000 篇参考文献,没有高等数学。****

这篇文章最初发表在史蒂夫的博客上。

在创建仪表板之前要问自己的 3 个问题

原文:https://towardsdatascience.com/dont-forget-these-three-things-when-creating-a-dashboard-eaadb1c02582?source=collection_archive---------58-----------------------

形象化

所以人们不再忽视你的努力!

图片由 softie__arts

现在玩仪表板比以前更容易了,但是你这样做对吗?

Tableau、Power BI 和许多其他商业智能工具允许您可视化数据,而无需接触 Excel 或编写一行代码。

虽然越来越多的人能够使用数据是件好事,但我们也应该记住,恰当地呈现数据和以往一样重要。设计良好的仪表板传达相关信息,并允许用户做出数据驱动的决策。但是如何创建一个设计良好的仪表板呢?

让我们来看一下在您设计、创建和交付仪表板时需要记住的三个首要问题。

时间可用性(优先级)

问这个问题可以帮助你开始:

用户需要看这个仪表盘多长时间时间

这很简单,但仍然很重要。

那么,我们为什么要特别关心时间约束

了解某人有多少时间很重要,因为它可以帮助你了解人们将如何使用仪表板。即使有人拥有理解、过滤和修改仪表板以回答业务问题的所有相关知识,如果他们没有时间这样做也没有关系。

这并不意味着在为时间有限的人创建仪表板时要牺牲质量。然而,这可能意味着你可以,例如,预先定制仪表板的日期过滤器,以便用户可以立即得到他们需要的答案。定制您的仪表板,以满足某人必须通过它的时间,您将顺利地帮助您的组织做出明智的决策。

在大多数情况下,您应该根据用户的明确要求来构建您的仪表板。然而,有些时候你可能比用户更了解数据。正因为如此,你可能会认为,要真正做出数据驱动的决策,你必须包含更多的数据,即使用户没有时间浏览这些数据。这可能是当你和用户之间的对话是必要的时候,这样你可以强调他们需要优先考虑这个问题。

目的

说你可以根据一个人在组织中的职位来概括他有多少时间,这太容易了。例如,一位忙碌的 CEO 可能想了解为什么某个地区表现不佳,以及潜在的解决方案是什么。在这种情况下,她可以受益于一个详细的演示风格的仪表板(如 Tableau 上的交互式故事)来探索情况,这是一个更常见的高层管理风格的报告。

这就引出了我们的第二个问题:

仪表板有什么用途?

这个问题的另一种表述方式是“这个仪表板将帮助最终用户做出什么决定?”当您希望帮助财务团队审核季度支出或向高管概述新产品的数字营销活动绩效时,您会希望创建一个能够给出明确答案的仪表板。这意味着您应该只包括可视化和 KPI,使最终用户可以很容易地找到答案。如果可能的话,您还应该预先设置过滤器,以便只显示他们每次需要使用仪表板时所需的相关数据。

相比之下,如果你已经创建了一份市场研究报告,并需要帮助你的经理决定向哪个新地区扩张,你会希望对你的仪表板进行更具探索性的设计。想象一下,你正在创建一个仪表板,它是你所有谷歌搜索的一个浓缩的交互式表示。您应该允许最终用户在仪表板中过滤和查看不同场景的结果,并让不同的图形和表格随着每个过滤器动态更新。

初始接收

下一步是确保人们真正使用您创建的仪表板。要问的最后一个问题是:

我能做些什么来确保这个仪表板给留下好的第一印象

尤其是当您创建一个仪表板来解决一个已经有解决方案的问题时,您需要确保您的新解决方案得到好评。如果最终用户认为仪表板难以使用,那么您是否包括新的可视化或更完整的数据集可能并不重要。

这意味着在交付完成的仪表板之前,您需要考虑如何与最终用户交互。虽然你肯定会有某种形式的沟通来了解他们想要什么,但展示你的第一份仪表板草稿来获得一些关于什么工作了,什么没有工作的即时反馈可能是值得的。你可以一直这样做,直到交付一个最终产品,只要你确保你没有用问题轰炸最终用户。

最后,在交付仪表板时,只需发送一封包含最终版本链接的电子邮件就可以了。然而,根据您事先与最终用户交谈的程度,花时间对仪表板的功能和范围进行概述性的介绍也是值得的。根据您的最终用户是谁,甚至一页纸的关于您所使用的数据源以及如何过滤和与仪表板交互的一些基础知识也可能是有帮助的。

请记住,当您为已经有工作要做的人创建新的解决方案时,仅仅让您的仪表板提供与旧解决方案相同的价值是不够的。如果是的话,最终用户转换的目的是什么?因此,在您设计并创建了一个动态且易于理解的仪表板后,确保您准确地传达了为什么它比当前使用的方法更好。

就是这样!

同样,这里有三件事需要记住:

  1. 用户查看这个仪表板需要多长时间时间
  2. 仪表盘有什么用途?
  3. 我能做些什么来确保这个仪表板给人留下好的第一印象?

一定要记住这些问题,因为没有什么比花一周时间创建你认为完美的仪表板更糟糕的了,只是在你交付后它被忽略了。请记住,所有这些问题都是为了理解最终用户的动机和态度,因为在设计仪表板时,这是您需要考虑的最重要的人。

快乐的仪表板!

别忘了离队

原文:https://towardsdatascience.com/dont-forget-to-f-o-o-p-5318cffc9ded?source=collection_archive---------67-----------------------

迭戈·莫拉·瓦兰特斯在 Unsplash 上的照片

介绍

“条条大路通罗马。”虽然这个短语表示一个问题有多种解决方案,但是有更适合这个问题的特定解决方案。这个类比适用于我们软件的编程风格。

在本文中,我们将讨论不同的编程范例以及每种范例的优点。

选择哪种范式?

我们选择哪个范例的决定应该符合软件开发生命周期(SDLC)的最佳实践。以下原则是 SDLC 最佳实践的一部分:单一责任和 D.R.Y .(不要重复自己)。这些原则鼓励软件是可测试的、可维护的和稳定的。通过遵循这些原则,您可以对您的软件建立更多的信心,并提高您的开发团队的速度。

两个主要的范例符合这些:函数式编程和面向对象编程。在我们的整个讨论中,我们将涵盖范例的好处和警告。

我们将使用 Python 作为编程选择来说明这些概念。

函数式编程范式

函数式编程(或 FP)试图抽象逻辑的应用,以便有“操作”作用于“操作”(即每个操作都需要一个操作作为输入)。FP 是数学运算符的一个应用。

FP 范式定义了 Apache-Spark 框架(一个负责大数据任务的框架)的根。

好处

  1. FP 范式支持我们软件的可测试、可读和更无缝的并行执行。
  2. FP 范例加强了对象的不变性,这进一步增加了软件的稳定性。

警告

  1. 有时函数需要多个输入参数。
  2. 有时,您希望冻结一些操作参数,同时允许其他参数保持自由。虽然这对于纯 FP 方法是可能的,但是这种方法的实现存在整体复杂性。

代码示例

面向对象编程范例

面向对象的编程(或 OOP)试图抽象概念,以便将复杂的过程表示为对象。

好处

  1. 在软件中更容易抽象和融合代码。
  2. 用你的软件更容易阅读代码和简化命名空间。
  3. 面向对象的继承可以帮助冻结参数或属性,并将它们传递给子对象。

警告

  1. 打破不变性是非常容易的
  2. 在每个类中,类逻辑的执行可以很容易地改变

代码示例

函数式面向对象编程范例

这个被提议的范例试图将 FP 和 OOP 结合起来,形成了函数式面向对象编程(或 F.O.O.P)范例。

F.O.O.P 结合了两种方法的优点,同时减少了警告的影响。

在利用单一责任和 D.R.Y .的同时,您可以利用面向对象的继承。这使我们能够开发代码,利用更复杂的软件。

这里有一个例子:

在本例中,我们将创建一个流程来创建操作管道,然后将这些操作联合在一起。这些概念与流行的数据科学 python 包(即 scikit-learn)中看到的非常相似。

如果这引起了你的共鸣,请到我的主页订阅我的时事通讯

[## 主页

在这里,您将找到有关 Edward Turner 所做工作的信息,以及…

ed-特纳. github.io](https://ed-turner.github.io/)

或者在 LinkedIn 上关注我:

[## 爱德华·特纳-数据科学家- Paylocity | LinkedIn

作为一名多语言开发人员,Edward Turner 拥有使用编程语言创建创新解决方案的经验…

www.linkedin.com](https://www.linkedin.com/in/edward-turner-polygot/)

一如既往#happycoding。

不要忘记深度学习中的“深”是什么意思

原文:https://towardsdatascience.com/dont-forget-what-deep-learning-actually-mean-2ab801bdbe31?source=collection_archive---------38-----------------------

批判性地思考你是否真的需要深度学习。

在你作为一家人工智能初创公司将深度学习应用于你的客户数据之前,首先批判性地思考你的客户数据的基本统计数据——记下数据集中的偏差——并问你自己深度学习是否真的有必要在该数据集中使用,或者你是否可以使用其他统计/ML 方法。

深度学习是人工智能中“最热门”的事情之一,它有一种渗入流行文化的方式,因为这种神秘的软件可以在计算机视觉、语音识别或玩围棋等游戏、推荐我们最喜欢的电影等方面以人类水*的准确度进行看似惊人的分类。

但深度学习有着至关重要的陷阱,当它驾驶的汽车不幸地不止一次因为愚蠢的图像识别错误而伤害或杀死司机或行人。或者,当深度学习被用于面部识别时——这显然对有色人种、LGBT 和其他边缘化群体有负面影响——如果深度学习的面部预测被有种族主义、LGBT 恐惧症和在私营公司和政府之间来回折腾的的权力机构使用——深度学习的陷阱会被可怕地放大。另一个例子是,2017 年底,脸书的深度学习神经翻译机器导致一名巴勒斯坦男子因发表帖子而被非法逮捕。如果你认为这些是“智能系统”犯下的“不可避免的错误”,你显然没有抓住要点。深度学习实际上只是一个统计关联工具,这与这篇文章的标题有关。

看到中间只有一个蓝色的隐藏层了吗?“深度”学习必须有 2 个或更多。

在人工神经网络的上图中,由于只有一个隐藏层,这个神经网络被认为是。如果你插入至少两个隐藏层或更多,它被认为是一个“深”神经网络。这就是深度学习的“深度”部分。

深度学习中的“深”并不代表深刻、抽象的理解。它不像人类那样理解抽象概念。

“深”仅仅意味着网络在长度上是深的。这里有一篇来自The Atlantic:Technology的文章显示,尽管谷歌翻译使用深度学习,但其神经翻译,即人工智能系统,再次使愚蠢的翻译错误超过人类标准。

现在,深度学习的学习”部分怎么样了?当然,它必须模仿人类的学习能力,因为它的结构就像大脑中的神经元一样!

没有。想想看:如果深度学习模仿人类学习如此之好,以至于可以通过图灵测试(一个人类会被深度学习系统愚弄),就不会有 Nature 中的 一篇文章详细描述深度学习系统如何犯了以人类标准衡量的愚蠢错误。请记住,如果深度学习应该像人类学习一样,我们应该以人类的标准来判断它。深度学习的先驱之一 Geoffrey Hinton 表示,他对神经网络作为解释人类或人工智能的一种方式深感怀疑。

深度学习是这样做的:它*似于一个函数,一个映射。例如:如果你有一个病人健康记录的数据库,你必须根据一些训练集来预测病人应该接受治疗 A 还是治疗 B,你可以在这个集上训练一个深度学习网络。它所要做的,是从病人 x 记录到治疗的*似直接映射。原谅我,我要借用一下数学符号。

X =患者记录,而Y = {治疗 A,治疗 B}* 。通常机器学习中标签的编码方式是 0 和 1 所以 Y = {1,0}。*

深度学习网络是做什么的?它只是*似一个函数 f 映射 XY 。所以它非常努力,有时使用数千到数百万个参数——旋钮和转盘,来逼*一个*滑函数 f(X) = Y

但是它是如何实现这种*似的呢?嗯,由于 f 往往非常复杂,所以必须使用迭代算法。神经网络使用一种叫做“成本函数”的东西来寻找 f(x) 。通过最小化预测值和实际值之间的误差,神经网络可以通过一种称为“反向传播”的算法来*似映射。(对于那些知道微积分导数的链规则的人来说,神经网络中的反向传播实际上就是应用于较小的线性和非线性激活函数的大组合的链规则。)不信我?看看格兰特·桑德森 (Youtube 频道 3b1b)的这个惊人的视频,它解释了包含数学的神经网络。

原来如此!神经网络中的“学习”只是一种称为反向传播的算法,用于最小化成本函数,该成本函数用于逼*输入和输出之间的一些复杂函数。难道这就是人类的学习和智能?我不这么认为。

为什么这很重要?嗯,大量在软件产品中使用人工智能的创业公司喜欢使用深度学习作为他们工具包的一部分,以展示他们的应用产品(或其他产品)的预测能力有多棒。可以肯定的是,深度学习的想法很受欢迎。当然有!如果一家初创公司可以声称在某个领域(语音识别、计算机视觉)再造人类智能,或者至少声称在这些领域与人类识别不相上下,他们将在科技领域产生难以想象的影响。毕竟,人工智能是每个技术人员都在寻找的黄金宝藏。

但是在深度学习的糖衣之下,存在着为了给软件提供动力而收集的大量数据。函数逼*是一个非常困难的问题,通常只有当你有大量的数据点时才能解决。这就是为什么像谷歌、脸书和亚马逊这样的公司可以使用深度学习的一个根本原因:它们基本上是数据的海洋,收集数据点,就像雨滴收集到盆地中一样。由于他们是科技巨头,他们有权力使用复杂的深度学习模型,这些模型在现实世界中可能非常不准确——并且有权力将它们作为政府合同或与其他公司的合同出售,这些公司控制着我们购买的产品,我们生活在监视之下,以及边缘化人群通过技术遭受的持续压迫。

我并不是说,如果你正在考虑开始一项人工智能业务,你就不能使用深度学习。当然可以;有数百个预先训练好的深度神经网络模型可以从网上下载。但是你应该批判地使用它们。在应用深度学习之前,想想你已经收集的数据的总体统计。不要简单地应用深度学习,认为它将揭示你正在收集数据的变量之间的复杂关系。深度学习是一个黑箱,但是你不一定要那么用。了解数据集中的偏差;理解并记下数据集中存在的社会不*等现象;很有可能,它们已经存在了。为什么?因为你的数据集就像是来自世界人口的(有偏见的)随机样本,所以它会反映出我们当前社会中的歧视和偏见体系。**

把深度学习想象成工具箱里的螺丝刀。也许它可能对某些任务有效,但是对许多任务来说,它自己根本就不能工作,试图强行解决它作为一个有效的可解释的工具不能足够快解决的问题,还不如浪费时间、金钱,并可能潜在地危及实际的生命。

不要被维度所诅咒

原文:https://towardsdatascience.com/dont-get-cursed-by-dimensionality-629bca5de3a5?source=collection_archive---------64-----------------------

从前,有一个模型。它已经有了许多功能,但它还想要更多。然后 PCA 出现了…不要在黑暗中看这个!

丹尼尔·延森Unsplash 上拍照

这是一个关于一个模特的故事,她已经拥有了许多功能,但她总是想要更多。这个模型变得如此臃肿,以至于无法将它们分开。但是,它还是成长了。然后有一天,主成分分析来到了模型的土地,它诅咒了他一劳永逸。诅咒就是日复一日地从模型中提取特征,直到只剩下最重要的特征。

这里有几个你可能会感兴趣的链接:

- [Labeling and Data Engineering for Conversational AI and Analytics](https://www.humanfirst.ai/)- [Data Science for Business Leaders](https://imp.i115008.net/c/2402645/880006/11298) [Course]- [Intro to Machine Learning with PyTorch](https://imp.i115008.net/c/2402645/788201/11298) [Course]- [Become a Growth Product Manager](https://imp.i115008.net/c/2402645/803127/11298) [Course]- [Deep Learning (Adaptive Computation and ML series)](https://amzn.to/3ncTG7D) [Ebook]- [Free skill tests for Data Scientists & Machine Learning Engineers](https://aigents.co/skills)

上面的一些链接是附属链接,如果你通过它们进行购买,我会赚取佣金。请记住,我链接课程是因为它们的质量,而不是因为我从你的购买中获得的佣金。

维度的诅咒

当数据集中有成千上万个要素时,诅咒就会出现在高维空间中。当维度增加时,空间的体积也增加,数据变得稀疏。这给任何需要统计显著性的方法带来了问题。随着每个功能的添加,支持结果所需的数据量呈指数级增长。

增加维度时空间体积的增加。

诅咒对你有什么影响?

通俗地说,机器学习模型根据与训练集中看到的样本的相似性,对看不见的样本进行预测。当特征多于样本时,我们有过度拟合模型的风险。测试集上的性能将受到影响

猫狗模型可能会想:特征 has _ lilac _ fur 是真的,我只在训练集中看到过一次有猫的情况,所以一定是猫。这样的特征也是异常值,因为它没有任何统计意义。猫真的有淡紫色的皮毛还是数据收集过程中的错误?在收集到更多数据之前,我们无法确定。

如何破除诅咒?

Simon WijersUnsplash 上的照片

要解除诅咒,请执行以下操作之一:

不要再被诅咒了

照片由 MontyLovUnsplash 上拍摄

在你走之前

Twitter 上关注我,在那里我定期发布关于数据科学和机器学习的消息。

您可能会对以下几个链接感兴趣:

- [Data Science Nanodegree Program](https://imp.i115008.net/c/2402645/788185/11298)- [AI for Healthcare](https://imp.i115008.net/c/2402645/824078/11298)- [Autonomous Systems](https://imp.i115008.net/c/2402645/829912/11298)- [Your First Machine Learning Model in the Cloud](https://datascienceisfun.net/)- [5 lesser-known pandas tricks](https://gumroad.com/l/YaaJn)- [How NOT to write pandas code](https://gumroad.com/l/vxxiV)- [Parallels Desktop 50% off](https://www.dpbolvw.net/click-100126493-14105294)

照片由Courtney hedgeUnsplash 拍摄

不要迷失在深渊中

原文:https://towardsdatascience.com/dont-get-lost-in-the-deep-26ee0749e04e?source=collection_archive---------82-----------------------

机器学习很少涉及深度学习。这没关系。

灭霸·帕尔的照片

L 先说我为什么写这篇文章。对于刚刚踏上数据科学之旅的人来说,很容易迷失方向。不,这不是关于决策树和随机森林的双关语。我的意思是有太多东西要学,太多东西要激动人心,但我认为我们真正应该关注的是对基础知识的详细理解。深度学习是机器学习领域向前迈出的令人难以置信的一步,这绝对是一个激起许多人兴趣的领域,甚至首先将他们带入这个研究领域,但事实是,很少有公司真正应用这些技术。通常情况下,线性模型可以很好地解决业务问题。我的观点是,如果你对基本的机器学习算法有坚实的理解,那么你对公司的价值会比你过于专注于新工具更大。

什么是机器学习?

我想我应该在这里添加这一部分,因为有太多的定义,很容易混淆什么是机器学习,什么不是机器学习。

机器学习是人工智能(AI)的一种应用,它为系统提供了自动学习和根据经验改进的能力,而无需显式编程。主要目的是让计算机在没有人类干预或帮助的情况下自动学习,并相应地调整行动— 来源

许多定义可能变得相当罗嗦,但我认为上面的引用很好地总结了这一点。机器学习是人工智能的一个分支,旨在赋予系统从经验中学习的能力(即从数据中学习),而无需显式编程以特定方式表现。

现在这一切听起来相当性感,但线性回归模型确实做到了这一点,因此它坚定地属于机器学习领域。对许多人来说,这可能有些令人沮丧。

我们都见过 Excel 对一些数据进行最佳拟合,因此,您的意思是告诉我 Excel 正在应用机器学习技术吗?

嗯,是的,事实上是的。但是没关系。线性回归素有简单乏味的名声,但它是一个异常强大的工具,却被异常低估了,尤其是对于该领域相对较新的人(在思考本文之前包括我自己)。在本文中,我使用线性回归作为例子,但是许多其他的基本算法也有类似的名声。

看一看趋势…

作为一篇数据科学相关的文章,我们来看看一些实际的数据。下面的图表是取自 Google Trends 的数据,显示了过去 15 年来对机器学习、深度学习和线性回归的相对兴趣(Google 搜索次数)。

在此期间,对线性回归的兴趣一直保持相当一致,这是有道理的,因为它的起源可以追溯到 19 世纪初,由卡尔·弗赖德里奇·高斯或阿德里安-玛丽·勒让德提出(更多关于它的争议性发现可以在这里阅读)。另一方面,深度学习在过去 5 年才真正普及

给了我“思考的食粮”的是,尽管深度学习在行业中的使用远远少于它,但它在网上被搜索的频率明显更高。这是可以理解的,因为目前围绕这个话题有大量的炒作,但我将在这里打破一个数据科学规则,并提出这种因果关系。

人们正在关注错误的事情。无论如何,对最令人兴奋和先进的机器学习技术感兴趣是没问题的。事实上,这是一件很棒的事情,因为这意味着你拓宽了自己的知识面,并表现出对自己领域前沿话题的浓厚兴趣。但是,只要我们不忽略作为数据科学领域基础的基本算法,这是没问题的。

那么谁在使用深度学习,谁没有呢?

深度学习算法是一个具有多个隐藏层的大型神经网络。深度神经网络的问题在于,它们需要大量的数据,才能获得超过传统机器学习算法的优势。

这张图展示了我们在不同大小的数据集上比较机器学习算法时看到的总体性能趋势。当数据集在较小的一边时,传统方法往往优于神经网络,这就是问题所在。

很少有公司坐拥足够的数据,能够真正从这些出色的算法中获益。那些人往往是科技巨头——比如亚马逊、脸书和谷歌。事实是,大多数公司仍处于数据科学的早期采用阶段,距离拥有利用深度学习优势所需的资源(数据、资金和专业知识)还有很长的路要走。

此外,企业实际上想要一个复杂问题的最简单的解决方案。即使一家公司有深度学习或任何其他复杂算法的资源,如果问题可以用一个更简单的模型来解决,但性能相当,你可以打赌他们会用那个更简单的模型。这是为什么呢?

简单的模型可以更快地构建,更容易实现,更容易理解,更新起来也相对容易。这一点的重要性不应被低估。算法越简单,就越透明。我们应该始终避免实现“黑盒”模型,因为这限制了它的应用范围,最终降低了它对我们的价值。通过使用简单的模型,我们可以更好地调查和理解我们正在解决的问题中存在的关系。

我将引用一段话来结束这一部分,这段话以一种颇具诗意的方式总结了我观点的精髓:

对于复杂的模型,有一种可怕的诱惑,要把柠檬榨干,并展示一幅未来的画面,通过其非常精确和逼真的画面来表达信念。然而,一个使用想象中的地图的人,认为这是一个真实的地图,很可能比一个根本没有地图的人更糟糕;因为他不会尽可能地去询问,观察路上的每一个细节,也不会用他所有的感官和智慧不断地寻找他应该去哪里的指示——从舒马赫的《小即是美》到

最后一点…

请不要误会,复杂!=坏。复杂的方法肯定有它们的位置,我们对它们感到兴奋是正确的。让我们先确保基本的都包括在内。不要马上跳入算法游泳池的深水区。

此外,如果你没有在工作场所经常使用这些先进的技术,也不要灰心丧气。我们有多少次在电视上看到律师在陪审团面前争论或者医生实施紧急救生手术?

非常经常。问题是这些都是现实的戏剧化表现。律师在他们的日常工作中很少这样做,医生每天花大部分时间诊断相同的常规医疗状况。这同样适用于数据科学家。

我们无时无刻不在阅读该领域令人兴奋的发展,这些发展会让我们思考‘为什么我的工作看起来比较*凡?’。我们的大部分时间都花在清理和准备数据上,然后使用简单的模型来解决手头的问题。这仍然是一份很棒的工作。管理期望是我们应该在生活的许多方面应用的一件重要事情,否则我们可能会让自己失望。

感谢您阅读至此!我很想在评论中听到你的想法。如果你想直接联系我,请随时在LinkedIn给我留言。

不知道你家狗狗的品种?ML 可以帮忙!

原文:https://towardsdatascience.com/dont-know-the-breed-of-your-dog-ml-can-help-6558eb5f7f05?source=collection_archive---------42-----------------------

学习如何建立一个生产就绪的软件,可以分类品种的狗的图像

你有没有想过你的狗或者你在街上看到的其他狗的品种?关于那件事,你可能得问专家。嗯,不会再有了!在这篇文章中,我将教你构建自己的 web 应用程序,它将接受你的狗的图像并以超过 80%的准确率输出它的品种!

这只狗是什么品种?来自 Pexels亚历克斯·多勒的照片

你可能想知道这怎么可能?嗯,我们将使用机器学习,特别是深度学习,在狗的图像数据集上训练一个模型,并记录它们的品种,以学习区分每个品种的特征。那我们开始吧!

数据分析

数据集可以从这里下载。成功加载和浏览数据集后,以下是关于数据的一些见解:

  1. 狗的品种总数:133
  2. 狗图像总数:8351(训练:6680,有效:835,测试:836)
  3. 最受欢迎的品种:Alaskan_malamute:96Border_collie: 93

按图片数量排序的前 30 个品种如下所示:

作者图片

我们还可以在这里看到一些狗的图片和它们的品种:

作者图片(数据集)

数据预处理

分析之后,是为机器学习算法准备数据的部分。我们将加载每个图像作为一个 NumPy 数组,并将它们的大小调整为 224x224,因为这是大多数传统神经网络接受图像的默认大小。我们还将为图像的数量添加另一个维度

细胞神经网络图像预处理

最后,我们将使用ImageDataGenerator对图像进行动态缩放和增强

CNN 从零开始

我们将从在预处理数据集上从头开始训练卷积神经网络(CNN)开始,如下所示:

我们使用回调ModelCheckpoint来保存基于验证分数的模型。测试这个模型,我们得到了大约 1%的精确度

使用迁移学习

现在,我们将看到使用预先训练的功能如何产生巨大的差异。下载 ResNet-50 瓶颈功能。您可以通过运行下面的代码单元格来提取相应的定型集、测试集和验证集:

我们现在将再次定义模型,并对提取的特征使用GlobalAveragePooling2D,将一组特征*均为一个值。最后,如果验证损失在连续 2 个时期内没有增加,我们使用额外的回调来降低学习速率ReduceLROnPlateau,并且如果验证损失在连续 5 个时期内没有增加,我们还使用额外的回调来提前停止训练EarlyStopping

现在测试集上的准确率为 82.65%。与我们从零开始训练的模型相比,这是一个巨大的进步。

构建 web 应用程序

对于 web 应用程序,我们将首先编写一个助手函数,它接受图像路径并返回品种。label_to_cat dictionary 将每个数字标签映射到其犬种。

对于 web 应用程序,我们将使用 Flask web 框架,它帮助我们用最少的代码创建 web 应用程序。我们将定义一条接受图像的路线,并呈现一个带有狗的品种的输出模板

predict.html是分别显示图片及其犬种的模板。

结论

恭喜你!你已经成功地实现了一个犬种分类器,并且可以自信地辨别犬种。让我们总结一下我们在这里学到的东西:

  1. 我们对数据集进行了分析和预处理。独立的训练、测试和验证集对于机器学习算法进行有把握的预测是必要的。
  2. 我们从零开始使用了一个CNN,它表现很差,因为它无法提取特征。
  3. 然后我们使用迁移学习,准确度提高了很多
  4. 最后,我们构建了一个 Flask web 应用程序,使我们的项目可以投入生产

我们确实学到了很多,但是还有很多其他的事情你可以尝试。您可以在 Heroku 上部署 web 应用程序,或者尝试使用不同的层(如Dropout层)来提高准确性。

要了解更多信息和详细分析,请务必点击这里查看我的 GitHub 上的代码。

如果您觉得以上内容对您有用,请分享并随时支持我-->

不要让数据科学家破坏您的 RPA 项目

原文:https://towardsdatascience.com/dont-let-data-scientists-ruin-your-rpa-project-6d952bcae468?source=collection_archive---------40-----------------------

数据科学家做事的方式与 RPA 开发人员截然不同,这在“人工智能与 RPA 的匹配度”上造成了 10 到 100 倍的差距。

🇨🇭·克劳迪奥·施瓦茨| @purzlbaum 在 Unsplash 上拍摄的照片

机器人流程自动化(RPA)是增长最快的企业软件类别,大公司争相自动化手动任务,同时避免更新其遗留系统的昂贵项目。

今天的主流 RPA 仍然主要涵盖简单的任务,而不是流程。简单性没有错,它完成了工作并带来了节约,而没有巨大的开发成本。对于许多公司来说,这绝对是 RPA 的第一个机会所在。与此同时,我与之交谈过的 RPA 团队正在思考“下一步做什么”这个问题。

在现实生活中,流程有基于判断的决策点,它们处理非结构化数据,有例外,并且它们不断发展。这些复杂性是爱国军的软肋。

埃斯特万·洛佩兹在 Unsplash 上的照片

基于规则的逻辑能走多远是有限度的,直到碰到一堵不可能的砖墙,并意识到你创造了如此具有挑战性的东西来维护,以至于它抵消了自动化的好处。

AI 解决这个吧?把科学家带进来!

是的,有点儿,但是如果所有的谈话都是关于 OCR 和文档理解,我们不会走得太远,这似乎偷走了 RPA *台提供商 AI 计划的大部分注意力。还有很多。例如,验证和修复输入数据,在缺乏共享标识符的系统之间匹配数据集,检测异常以防止错误,并自动执行由人工智能机器人做出的重复或“认知”决策。

爱国军领导人怎么说?

虽然我与爱国军领导人讨论的样本在统计上很难具有代表性,但我认为可以说存在问题。这里有三段引言,概括起来是为了保护个人的身份。

我们在 RPA 积压工作中实现自动化已经一年多了,我们尝试了一些东西,但是机器学习部分没有实现。— RPA 团队领导

将数据科学项目融入我们敏捷的 3 周 bot 开发冲刺真的很难。— RPA 团队领导

我们的数据科学团队就像一个黑洞。你把一个想法放进去,六个月后你就有了一个数据管道。—首席执行官

当 RPA 程序变得越来越复杂时,不可否认地需要机器学习。然而,这里的共同主题是数据科学不能满足 RPA 的需求。可用性极低,工具驱动冗长的项目,引入更多的技术专家增加了沟通的挑战。数据科学家的思维倾向于探索性项目,而 RPA 工程师需要快速的解决方案来移动积压的项目。因此,对于许多 RPA 使用情形来说,成本堆积过高。

目前,“人工智能与 RPA 的匹配度”有 10 到 100 倍的差距。

虽然我相信数据科学作为一种技能组合是非常需要的,并且“总是”会有一个位置,但我也认为即使不将科学引入每个项目,也可以做得更多。不要让这种不匹配毁了您的自动化项目。

解决方案已经出来了。

当在最*的 Sofa 峰会 RPA Conf 2020 爱立信自动化总监& AI 转型 Kanda Kumar 提出他们“用民主化扩展容量”的想法时,我感到非常兴奋。在实践中,有两种方法可以从现状中挖掘出全部潜力:

  1. 借助 AutoML 和 MLops *台等工具,增强数据科学家的能力,帮助他们实现更多目标。
  2. 领域专家配备了工具,使他们能够达到他们的目标,而不必为“ML 部件”分离出一个单独的项目。

我在 2020 年 5 月 20 日从沙发峰会手动复制了神田的幻灯片

我认为,尤其是后者存在巨大的机会。一个领域专家能够将解决问题作为他/她的日常工作流程的一部分是一个不可否认的优势。除了允许更复杂的自动化工作流的经济高效的开发之外,它还支持敏捷开发,不受外部团队、他们的工作方式和积压的约束。

与其把你的自动化项目扔进数据科学黑洞,交叉手指,不如先看看你自己能做些什么。你会惊讶的。高效且易于使用的工具已经存在。以下是我列出的六个需要考虑的特征。

  • UX 服务于目标受众:面向开发人员的优秀 API 和 RPA *台集成,或者面向公民开发人员的无代码体验。
  • 它从用户那里带走了数据争论和特征工程的负担。
  • 无需用户明确选择算法,特别是优化算法。
  • 对预测准确性清晰透明,有信心决定下一步机器人行动。
  • 扩展初始数据集:在生产中自动接收新数据和更新预测。
  • 成本不会破坏 RPA 的预算。

因为我自己就在和一个这样的工具提供商合作,所以我有偏见。:)因此,我很想听听你的首选工具是什么,可以满足上述部分或全部要求?或者你会如何改进这个列表?

我是 Aito.ai 的首席产品官,这是一个云托管的预测数据库,通过简单的 API 使用数据库中的任何数据来提供机器学习预测。

不要让丢失的值破坏您的分析输出,处理它们!

原文:https://towardsdatascience.com/dont-let-missing-values-ruin-your-analysis-output-deal-with-them-5d9c7686366c?source=collection_archive---------41-----------------------

处理空值的方法概述

Ehimetalor Akhere UnuabonaUnsplash 拍摄的照片

无论是机器学习模型、KPI 还是报告,缺失值或其替换值都可能导致您的分析输出出现巨大错误。

通常,分析师处理缺失值就像它们只有一种类型一样。事实并非如此,有三种类型的缺失值,每一种都有不同的处理方法。

空值的类型

随机缺失(MAR) :变量中出现空值不是随机的,而是依赖于记录的已知或未知特征。你可能会问自己,为什么它被称为随机失踪?因为空值与实际值无关。根据您的数据集,它可以或不可以测试。要找出答案,您应该比较具有缺失值和非缺失值的记录的其他变量分布。

例如: 一个关于教育的数据集,其中包含许多幼儿智商得分的缺失值,只是因为与 12 岁的孩子相比,4 岁的孩子通过测试的情况较少。空值与智商实际值无关,但与年龄有关。

完全随机缺失(MCAR) :空值的存在与记录的任何已知或未知特征无关。同样,这取决于您的数据集,可以测试也可以不测试。与 MAR 一样,测试包括比较有缺失值的记录和没有空值的记录的其他变量的分布。

例如: 问卷结果在邮件中丢失的调查受访者的缺失数据。完全独立于相关变量和回答者的特征(即记录)。

非随机缺失(MNAR) :空值的存在取决于其实际值。这个无法测试,除非你知道实际值,这有点矛盾。

例如: 智商变量的缺失值仅适用于得分较低的个人。

您可能已经猜到了,只有在第二种情况下,删除空值才是安全的。

对于另外两种情况,降低值会导致忽略总体中的一组。

在最后一种情况下,记录具有空值的事实携带了一些关于实际值的信息。

处理缺失值

删除行:(仅适用于 MCAR)如果相对于数据集大小,您只有一小部分缺失值,这可能是最佳解决方案。然而,随着比例的增长,它很快变得不可行。

丢弃 col : 这种方法通常不被考虑,因为它会导致重要信息的丢失。根据经验,当空值的比例高于 60%时,您可以开始考虑它。

归罪

上一个或下一个值:(仅适用于 MCAR 的时间序列)只要您正在处理时间序列问题,就可以使用上一个或下一个值来填充缺失值。

*均值:(仅适用于 MCAR)使用*均值通常不是一个好的解决方案,因为它对异常值很敏感。

中值:(仅适用于 MCAR)类似于*均值,但对异常值更稳健。

模式值:(仅适用于 MCAR)通过选择最常见的值,您可以确保在大多数情况下正确填充空值。当心多模式分销,因为它不再是一个可行的解决方案。

替换为常量:(仅适用于 MNAR)正如我们之前看到的,MNAR 情况下的 missing value 实际上保存了一些关于实际值的信息。因此,使用一个常数(不同于其他值)填充它们是有意义的。

线性插值:(仅适用于具有 MCAR 的时间序列)在具有趋势和很少或没有季节性的时间序列问题中,缺失值可以通过使用其之前的值和之后的值进行线性插值来*似。公式如下:

线性插值(一阶)

样条插值:(仅适用于具有 MCAR 的时间序列)这类似于线性插值,但它使用了高阶多项式特征来实现更*滑的插值。还是那句话,不适合季节性数据。

带季节性调整的线性/样条插值:(仅适用于 MCAR 时间序列)它遵循与线性和样条插值相同的原理,但对季节性进行了调整。它包括对数据进行非季节性处理,应用线性/样条插值,并对时间序列应用季节性。这里是对 STL 一种数据去季节化方法的详细解释。

线性回归、KNN、MCMC、多变量高斯或任何 ML 算法:(仅用于 MAR)使用它可能需要一些额外的工作,但它是处理 MAR 的唯一可行的解决方案。为什么?因为它考虑了其他变量的记录值,所以它可以使用关于变量的信息来预测缺失值,这些变量在缺失和非缺失时的值是不同的。

多重插补:(仅适用于马尔和 MCAR)多重插补是处理缺失值的最佳方式。它包括使用一个模型多次输入缺失值,该模型允许对同一观测值的预测之间的差异。增加相同观测预测之间变化的解决方案可以是使用类似线性回归的模型。假设模型参数来自一个分布,你可以让它们在每个插补步骤中有一点点变化,要阅读更多关于这种技术的内容,请查看这个。每次插补都会创建一个新的数据集。然后,应该对每个数据集进行分析。完成后,计算不同数据集上结果的*均值和标准偏差,以给出具有“置信区间”的输出值的*似值。

如果你想讨论如何处理项目中缺失的价值,请通过 LinkedIn 联系我。

不要向后看,向前看!

原文:https://towardsdatascience.com/dont-look-backwards-lookahead-6bcd7ff50f93?source=collection_archive---------38-----------------------

前瞻优化器使您的模型对超参数的选择不太敏感

图片由 rihaij z Pixabay 提供

优化器的任务是寻找这样一组权重,使神经网络模型产生尽可能低的损失。如果你只有一个权重和一个如下图所示的损失函数,你不需要成为天才也能找到答案。

不幸的是,你通常有许多权重和一个很难简单的损失景观,更不用说不再适合 2D 绘画。

使用https://arxiv.org/pdf/1712.09913.pdf中提出的方法可视化无跳跃连接的 ResNet-56 的损失表面。

找到这样一个函数的最小值不再是一个微不足道的任务。像 Adam 或 SGD 这样最常见的优化器需要非常耗时的超参数调整,并且可能陷入局部最小值。选择学习率这样的超参数的重要性可以用下图来概括:

太大的学习率会引起最小值附*的振荡,而太小的学习率会使学习过程非常慢。

最*提出的前瞻优化器进行优化过程

对次优超参数不太敏感,因此减少了对大范围超参数调整的需求。

这听起来像是值得探索的事情!

该算法

直观地说,该算法通过在由另一个优化器生成的“快速权重”序列中前瞻来选择搜索方向。

优化器保留两组权重:快速权重θ和慢速权重ϕ。它们都用相同的值初始化。具有一定学习速率η的标准优化器(例如,Adam、SGD、…)被用于为定义数量的步骤k更新快速权重θ,从而产生一些新值θ’

然后关键的事情发生了:慢速权重ϕ沿着权重向量 θ’- ϕ的差定义的方向移动。这一步的长度由参数α——慢速权重学习率控制。

前瞻算法中的重要更新

然后,通过将快速权重值重新设置为新计算的慢速权重值ϕ’,开始重复该过程。你可以看到下面的伪代码:

来源:https://arxiv.org/pdf/1907.08610.pdf

这有什么意义?

为了回答这个问题,我们将研究来自前瞻出版物的(略微修改的)图片,但是作为介绍,让我们首先看另一张图片。如果我们的模型只有三个权重,损失函数可以很容易地可视化,如下图所示。

在模型仅依赖于三个权重的情况下,权重空间中的损失函数可视化。提出了权重空间中损失到三个*面(“超*面”)的投影,其中一个权重具有恒定值。

显然,在现实生活的例子中,我们有三个以上的权重,导致权重空间具有更高的维度。然而,我们仍然可以通过把它投影到这样一个空间的超*面上来形象化这个损失。

这就是在前瞻报告中提出的内容:

来源:https://arxiv.org/pdf/1907.08610.pdf

我们看到目标函数(在这种情况下是精度,但也可能是损失)到权重空间中的超*面的投影。不同的颜色对应不同的目标函数值:颜色越亮,值越优。前瞻优化器的行为如下所示:蓝色虚线表示快速权重θ的轨迹(蓝色方块表示十个后续状态),而紫色线表示快速权重更新θ’- ϕ的方向。紫色三角形表示两个后续的慢速权重值ϕϕ’。三角形之间的距离由慢速权重学习速率α定义。

我们可以看到,标准优化器(在本例中为 SGD)遍历了一个次优绿色区域,而第二个慢权重状态已经非常接*最优。论文描述的更为优雅:

当在高曲率方向振荡时,快速权重更新沿着低曲率方向快速进行。慢速权重有助于通过参数插值消除振荡。快速权重和慢速权重的组合改善了在高曲率方向上的学习,减少了方差,并且使得前瞻在实践中能够快速收敛。

在 Keras 怎么用?

现在回到方法的实际方面;到目前为止只有一个非官方的 Keras 实现;它可以很容易地与您当前的优化器一起使用;

如您所见,除了优化器本身之外,Lookahead还需要两个参数:

  • sync_period对应前面介绍的k——两组砝码同步后的步数,
  • slow_step对应于α慢速权重的学习速率。

为了检查它是否按预期工作,您可以将slow_step设置为1,并将Lookahead的行为与常规优化器的行为进行比较。

对于1α,前瞻更新步骤减少为:

这意味着前瞻被简化为它的底层标准优化器。我们也可以在修改后的权重轨迹图上看到它:

改编自:https://arxiv.org/pdf/1907.08610.pdf

现在慢速权重的结束状态与快速权重的结束状态相同。

您可以使用以下代码对其进行测试:

测试证明具有 Adam 和慢学习率 1 的 LookAhead 等价于纯 Adam。

一锤定音

前瞻是一种有效的优化算法,它以可忽略的计算成本使寻找损失函数最小值的过程更加稳定。此外,需要较少的超参数调整。

据说当与修正的 Adam 优化器结合使用时特别有效。我将在下一篇文章中讨论这个话题。

不要惹海森堡

原文:https://towardsdatascience.com/dont-mess-with-heisenberg-f9a2a349ea23?source=collection_archive---------31-----------------------

丽塔·莫莱斯在 Unsplash 上拍摄的照片

数据可视化必须接受一些不确定性

在开发一个数据可视化 app 之前,想想时间空间哪个更重要。你想显示实时数据吗?还是要分析干净的数据?在开发我的应用程序时,我两者都想要。我变得沮丧,直到我意识到我犯了一个新手的错误。

Plotly Dash 中,我着手构建一个仪表板,它将通过 CryptoCompare 的公共 API 获得每分钟的加密货币价格,并提供 Dash 可视化,以便在其中研究数据。

在我的第一次迭代中,我并不担心实时方面。我给了用户一个下拉菜单来选择他们的加密货币。

然后我检查了 Sqlite 数据库,果然,每分钟都有一个新的比特币值通过 cron 作业添加进来。在我的 Google Cloud Ubuntu 虚拟机(VM)上,我告诉 crontab 服务每分钟调用一个 Python 脚本,该脚本从 CrypoCompare 获取数据并将其插入到 SQLite 表中。

然后我刷新了我的 Dash app。但是数据没变

我在 Dash 论坛上发帖,寻找类似于 RefreshOnPageLoad = True,的函数,但是一个也没有找到。一开始我对短跑队很恼火。然后我开始思考这个问题,并意识到如果一个人在每次页面加载时都刷新 Dash 应用程序,你最终会质疑为什么你一开始就使用 Dash!

首先,非常明确地说,我不是要说你不能在像 Dash 这样的框架中进行实时数据可视化——你可以。我的观点是,当你试图服务于两个主人,数据的及时性和数据质量时,你应该预料到你的编程的复杂性会呈指数级上升。让我们来看看 Dash 图库中的一些例子。

这是制造 SPC 仪表板应用程序。

该应用程序看起来像是某台机器正在向 Dash 应用程序发送数据以进行可视化

如果我们查看代码,我们会注意到外部数据源并没有驱动可视化。该应用程序正在根据其定时事件提取数据。

但是,如果我们希望它每秒钟都向数据帧中重新加载新数据,该怎么办呢?

用户几乎无法控制数据。没有花哨的滑块。也就是说,Dash gallery 中的“流媒体”应用没有发挥 Dash 的优势。使用普通的 Javascript 和 Chart.js 就可以很容易做到。

这是另一个 Dash“流”应用程序。

Dash 真的是风力驱动的吗?!

和上面的 app 一样,软件使用复杂的回调来重新加载组件。有一个滑块,但它不是用于数据探索的。

每当我看着将流数据添加到我的 Dash 应用程序所需的代码时,我的大脑就冻结了。Dash 里的试镜对我来说已经够复杂了。集成两组回调,一组用于更新数据,另一组用于处理用户输入,将我的技能推到了极限。

我们来看看 Dash 的长处。在下面的应用程序中,各种控件(滑块)可以改变数据的图形。用户还可以通过将鼠标悬停在图表上来浏览数据。

该应用程序不刷新数据,但如果它做到了呢?那是我的啊哈时刻。会有什么后果?

Dash 只用几行代码就提供了强大的功能

在 Dash 中,HTML 控件允许用户根据他们选择的参数可视化数据。

如果一个外部数据源改变了数据,它能在不改变用户基于他们最后选择的参数的期望的情况下这样做吗?

比方说,我已经将我的应用程序设置为查看加密货币价格的前 5 个百分点。我发现起价是 100 美元。我过滤掉所有低于 100 美元的硬币?一切都好。

但是如果新数据进入系统,百分位变为 110 美元呢?我的结论现在已经过时而且错误

就像海森堡测不准原理我可以研究我的加密货币的位置,或者它的动量,但不能同时研究两者!在物理实验中,从某种意义上来说,你必须经常触摸你正在研究的东西。你只能通过记录来注意到一个电子,比如说,另一个电子被它反弹并通过你的传感器击中另一个电子。当你的记录电子撞击你正在研究的电子时,它可以改变那个电子的位置或动量。你只能研究它没有影响的方面。那是我外行的理解。

就像我上面的例子一样,对于任何给定的数据可视化数据集,我都可以非常非常确定我的分析对于给定的数据集是正确的。当有人问,不确定性出现了,但是新的数据会说什么呢?

这是 Dash 的致命弱点,我想也是所有数据可视化框架的致命弱点。

当我试图添加算法来更新我的应用程序数据时,我开始去厨房寻找舒适的食物。下面是两个 Dash 示例应用程序的一些代码来说明我的观点:

432 行代码的惊人可视化!

上面的应用程序发挥了 Dash 的优势,允许人们以惊人的深度研究数据集。

这是一个 Dash 应用程序,它添加了流数据。

为什么这么简单的仪表板有这么多行代码?

纵观全局,数据可视化中最困难的部分是决定用户将执行什么实验。我希望他们拥有最新的数据,还是最干净的数据?如果我试图让应用程序两者都做,我可能会倾向于这样或那样,这将激怒一些用户。要么他们在重新加载数据时会丢失参数,要么他们将无法查看新数据。

总之,你可以在 Dash 中做任何你想做的事情。但是你应该理解数据科学中的基本问题。数据可视化应用的成功部分取决于管理预期。

在未来,如果我想要一个数据流应用程序,我可能会用不同的技术来构建它。然而,如果我想让用户尽情探索复杂的数据集,那么 Dash 可以用最少的代码行提供最强大的功能。

如果我必须两者都做,我最好找一个开发团队和一个装满东西的冰箱。

不要错过识别缺失数据的缺失号!

原文:https://towardsdatascience.com/dont-miss-out-on-missingno-for-identifying-missing-data-9a0681433c36?source=collection_archive---------43-----------------------

应该用来可视化缺失数据的库

阿尔文·恩格勒Unsplash 拍摄的照片

野外的数据并不总是完整的。您需要立即发现这一点,调查为什么会有丢失的数据,并潜在地捕捉可以用来填充丢失的数据或丢弃它们的值。填充或丢弃取决于任务。但是同样,如果不首先识别那些丢失的值,你就不能做任何事情。这就是 Missingno 库的用武之地,你将在这里学习如何使用它。

缺少不,Python 版本

Missingno 是由 Aleksey Bilogur 创建的 python 库,用于可视化数据中的缺失值。有了它,您可以快速了解数据集中缺少哪些数据。这是我在使用任何数据执行任何主要任务之前首先要做的事情之一。

imgflip.com自制形象

这是真的。如果您的数据可能最多有 8 到 10 列,您可以快速浏览一下。但是如果你有 20 列的数据呢?30 列?40 列?您是否仍然能够以比这样的可视化方式更快的速度浏览和读取每一列中的非空值总数?

我的代码的 msno.matrix(数据)的结果。

你的眼睛会立刻移动到有白色条纹的条纹上。这是您可以找出哪些列缺少数据的速度。顺便说一下,这也是在一个有 26 列的随机数据集上。现在,让我们让你使用这个库!在你的终端上输入pip install missingno然后开始吧!

Armand khou ry Unsplash 上拍摄的照片

安装

当然,我们必须下载一些和 Missingno 一起的库。这些是我为任何数据任务导入的默认库。我们将继续上传我们的数据。数据来自这个网站谷歌的数据集搜索引擎上快速搜索“缺失值”。

亲提示,用sns.set()。默认情况下,它给你的图表一个海边背景。当我们做条形图时,这将非常有用。但首先,我们必须查看矩阵。

Msno 矩阵(数据)

msno.matrix(data)将显示我们在上面看到的图表类型。空白表示缺少值,而黑色表示有值。

我的代码的 msno.matrix(数据)的结果。

除了可以快速识别哪些列有缺失值之外,您还可以查看这些列在哪里有缺失值。按特定列对数据进行排序可以让您看到是否有数据块丢失,并在筛选出这些行后帮助您更快地识别它们。右边的锯齿状垂直折线图根据长度标记了行中丢失的数据量。图表中向左的线条越长,该行中丢失的数据就越多。

Msno.bar(数据)

msno.bar(data)将生成一个条形图,显示每列中非空数据值的数量。它还在顶部标记了非空值的数量。

我的代码中 msno.bar(data)的 sns.set()版本的结果。

您的目光应该转向此图表左侧较低的条形,以快速看到 3 列(po2、fio2 和 pco2)缺少大量数据值。现在,还记得我告诉过你如何使用sns.set()吗?你应该自己检查,但是如果你没有,这里有一个没有使用sns.set()的相同的条形图。

我的代码中没有 sns.set()的 msno.bar(data)的结果。

请注意,sns.set()版本的线条将条形分割成六分之一的数据。这可以让您了解基于这些间隔的特性所占的百分比。所以我们可以很快确定,我们有大约三分之一的 po2 和 pco2 值。seaborn 背景的另一个好处是背景中的百分比线,因此您可以从另一个视觉角度了解每 20%标记处有多少数据。

其他可视化

Missingno 还提供了数据的热图树状图,以显示某些列中缺失值之间可能的相关性。我还没有在我自己的职位上使用过这些,原因是领域知识或者只是问了正确的人。但是我会给你这些数据的每个图表的图片,这样你就可以开始学习如何根据失踪人口文档自己解释这些数据。

我的代码中 msno.heatmap(data,figsize=(15,7)的结果。

我的代码的 msno.dendrogram(数据)的结果。

请确保您也从 Missingno 库中查看了代码,以查看所有这些函数的底层细节。

最后的想法

尽管热图和树状图提供了很好的关联关系,但是如果您有领域知识,它们并不是必需的。如果您不了解您正在处理的数据的领域知识,那么这些图表会变得更加有用。如果你的组织中没有可以及时咨询的人,我觉得这些图表应该是最后的手段。请记住,领域知识可以解决您处理的数据中的大量背景知识缺口(以及缺失的数据缺口)。

感谢您的阅读!请记住,调查丢失的数据应该是您正在进行的任何项目的探索性数据分析过程的一部分。在您自己的数据上尝试 Missingno!

你可以在 LinkedinTwitter 上关注或联系我。对 Twitter 上的 DM 开放。

直到下一次,

约翰·德杰苏斯

不要错过熊猫的滚动窗口功能

原文:https://towardsdatascience.com/dont-miss-out-on-rolling-window-functions-in-pandas-850b817131db?source=collection_archive---------4-----------------------

大蟒

使用移动窗口计算深入研究您的数据

艺术由 bythanproductions

窗口计算可以增加数据分析的深度。

Pandas 库允许您执行许多不同的内置聚合计算,定义您的函数并在数据帧中应用它们,甚至可以同时处理数据帧中的多个列。Pandas 中有一个你以前可能没听说过的功能是内置的窗口 功能

窗口函数非常有用,因为您可以对数据子集执行许多不同种类的操作。滚动窗口函数专门用于计算数据帧中每一行的新值。这听起来可能有点抽象,所以让我们深入解释和例子。

这篇文章中的例子将使用雅虎财经的一些旧的特斯拉股票价格数据。如果您想继续,请随意运行下面的代码。关于pd.read_htmldf.sort_values的更多信息,请查看本文末尾的链接。

import pandas as pddf = pd.read_html("[https://finance.yahoo.com/quote/TSLA/history?period1=1546300800&period2=1550275200&interval=1d&filter=history&frequency=1d](https://finance.yahoo.com/quote/TSLA/history?period1=1546300800&period2=1550275200&interval=1d&filter=history&frequency=1d)")[0]
df = df.head(11).sort_values(by='Date')
df = df.astype({"Open":'float',
                "High":'float',
                "Low":'float',
                "Close*":'float',
                "Adj Close**":'float',
                "Volume":'float'})
df['Gain'] = df['Close*'] - df['Open']

样本修改特斯拉股票数据来自雅虎财经

熊猫数据框架中的滚动函数

那么什么是滚动窗口计算呢?

处理时序数据时,通常会使用滚动计算。同样,窗口是您执行窗口计算的行的子集。在你定义了一个窗口之后,你可以执行诸如计算运行总数、移动*均、排名等操作。

让我们用一些例子来澄清这一点。

1.窗口滚动*均值(移动*均值)

移动*均值计算基于我们指定的窗口为每一行创建一个更新的*均值。这种计算也称为“滚动*均值”,因为它是在数据帧中计算每行在指定范围内的*均值。

这听起来有点抽象,所以让我们计算一段时间内“收盘”价格的滚动*均值。为此,我们将运行以下代码:

df['Rolling Close Average'] = df['Close*'].rolling(2).mean()

滚动*均结果

我们正在创建一个新的列“滚动收盘价*均值”,它采用一个窗口内收盘价的移动*均值。要做到这一点,我们只需编写.rolling(2).mean(),其中我们指定一个窗口“2”,并计算数据帧中每个窗口的*均值。每一行的“滚动收盘*均值”等于其“收盘”值加上前一行的“收盘”值除以 2(窗口)。本质上是Moving Avg = ([t] + [t-1]) / 2

实际上,这意味着第一个计算值(62.44 + 62.58) / 2 = 62.51,即 2 月 4 日的“滚动收盘*均值”。数据帧中的第一行没有滚动*均值,因为在计算中没有可用的[t-1]或前期“收盘*”值,这就是 Pandas 用NaN值填充它的原因。

2.窗口滚动标准偏差

为了进一步了解常规计算和滚动计算之间的区别,让我们来看看“开盘价”的滚动标准差。为此,我们将运行以下代码:

df['Open Standard Deviation'] = df['Open'].std()
df['Rolling Open Standard Deviation'] = df['Open'].rolling(2).std()

滚动标准差结果

我还为标准偏差添加了一个新列“开放标准偏差”,它只是计算整个“开放”列的标准偏差。在它旁边,您会看到“滚动开放标准偏差”列,其中我定义了一个 2 的窗口,并计算了每行的标准偏差。

就像前面的例子一样,第一个非空值位于 DataFrame 的第二行,因为这是同时具有[t[t-1]的第一行。你可以看到当你在表格中向下移动时,移动标准差是如何变化的,这对于跟踪一段时间内的波动性很有用。

Pandas 在计算标准差时使用 N-1 个自由度。您可以向ddof传递一个可选参数,该参数在std函数中默认设置为“1”。

3.窗口滚动和

作为最后一个例子,让我们计算“Volume”列的滚动总和。为此,我们运行以下代码:

df['Rolling Volume Sum'] = df['Volume'].rolling(3).sum()

滚动求和结果

我们定义了一个窗口“3”,所以第一个计算值出现在第三行。然后,求和计算“滚动”到每一行,这样您就可以跟踪当前行和前两行值的总和。

这里需要强调的是,这些滚动(移动)计算不应与运行计算混淆。如上图所示,滚动计算有一个移动窗口。因此,对于我们的移动总和,2 月 6 日(第四行)的计算值不包括 2 月 1 日(第一行)的值,因为指定的窗口(3)没有追溯到那么远。相比之下,运行计算需要不断将每一行的值添加到整个数据帧的运行总值中。你可以检查一下cumsum函数。

我希望您发现这个关于熊猫使用包装器进行逻辑比较的非常基本的介绍很有用。请记住,只比较可以比较的数据(即不要尝试将字符串与浮点数进行比较),并手动复查结果,以确保您的计算产生了预期的结果。

往前走,比较一下!

**More by me:
*** [**2 Easy Ways to Get Tables From a Website**](/2-easy-ways-to-get-tables-from-a-website-with-pandas-b92fc835e741?source=friends_link&sk=9981ddaf0785a79be893b5a1dd3e03dd) ***** [**4 Different Ways to Efficiently Sort a Pandas DataFrame**](/4-different-ways-to-efficiently-sort-a-pandas-dataframe-9aba423f12db?source=friends_link&sk=97821818c45f0bdbdbc8d341a14ecddd)
- [Top 4 Repositories on GitHub to Learn Pandas](/top-4-repositories-on-github-to-learn-pandas-1008cb769f77?source=friends_link&sk=d3acc38062490a86ecb46875342224e6)
- [How to Quickly Create and Unpack Lists with Pandas](/how-to-quickly-create-and-unpack-lists-with-pandas-d0e78e487c75?source=friends_link&sk=32ea67b35fe90382dc719c1c78c5900c)
- [Learning to Forecast With Tableau in 5 Minutes Or Less](/learning-to-forecast-effectively-with-tableau-in-6-minutes-or-less-3d77a55930a0?source=friends_link&sk=9abdfd7533ee9a31ab8a036413450059)

不要过度规划您的数据可视化

原文:https://towardsdatascience.com/dont-over-plan-your-data-visualization-737c7330d80f?source=collection_archive---------36-----------------------

通往伟大数据的道路充满了意想不到的事情

这篇文章解释了如何制作上面的动画地图。

这篇文章的标题很容易以“10 大经验”或“5 个简单的步骤”开始。我们,处理数据的人,喜欢遵循某种框架或实验测试的方法。但是想出一个用于数据可视化的将是一个很大的挑战。

复杂数据可视化的开发不是一个由许多标准化步骤连接在一起的起点和终点的过程。这更像是一个重复的、快速的原型制作过程,中间的步骤直到你完成后才能知道。数据可视化的这一特征可能会非常消极,尤其是对于那些喜欢遵循详细计划的人。

如果您陷入了又一个意想不到的错误,看起来像是又一个挫折,那么就像驾船航行一样创建数据可视化。当你在船上时,你可能会看到地*线上的目的港,并知道如何到达那里。但是你最终要走的路很可能会偏离你最初的计划。这将取决于不断变化的风,海浪的高度,水深,甚至其他船只的交通。与数据可视化一样,在完成之前,您不会真正知道您的路线是什么样子。

在过去的几周里,我重新创建了我最喜欢的可视化工具之一——由卡梅隆·贝卡里奥设计的著名的风地图。在这篇文章中,我想反思我的设计过程,特别是描述所有我不可能计划到的小挫折,但这些挫折最终改善了我的视觉叙事。如果你发现自己被困在使数据可视化的路上,如果你看不到你的目的地,你面前有一本好书。

但是如果阅读不是你的事情,而你只是想看代码——请,也欢迎。继续滚动到底部,在那里我用代码链接了可观察的笔记本。

我们从一张空地图开始。我们将以一件美丽的事情结束。

实施基本功能和第一个减速带

我喜欢从实现基本功能开始我的设计。缩放、*移、滑动——它们越通用,我就越有可能在第一步中包括它们。在我的地图中,我想包含的前两件事是拖动和缩放行为。我构建了它们

wind_map = { const svg = d3.create('svg')
                .attr('viewBox', [0, 0, width, height])
                .attr("fill", "none")

  const map = svg.append("g")
                 .attr("id", "map")
                 .call(d3.drag()
                         .on("start", dragstarted)
                         .on("drag",  dragged)
                         .on("end", dragend)) //...
}

dragstarted()dragged()dragend()作为助手函数,负责拖动事件开始、期间和结束时的行为。但是我很快注意到d3.drag()的默认行为允许向各个方向拖动。在地球仪的情况下,可以更改地球仪的滚动、俯仰和偏航,并将地球仪旋转到北方不面向可视化顶部的位置。看下面 gif 上我的意思。

面对可视化的顶部,从北方偏离几乎是不合理的。

这种功能会引入不必要的混乱和干扰。我通过设置绕y轴的旋转(或者,更详细地说,将欧拉旋转角度 γ 设置为 0)来停止这个操作。

我用d3.zoom()实现了缩放行为,使用了与拖动行为相同的结构。我又添加了一个调用,使用zoomstarted()zoomed()zoomend()助手函数来实现缩放开始、期间和结束时的行为。

map.call(d3.zoom()
   .scaleExtent([400, 1000])
   .on("start", zoomstarted)
   .on("zoom", zoomed)
   .on("end", zoomend))

图表上的缩放比例一出现,很明显也需要调整。默认d3.zoom()允许在缩放过程中拖动。这看起来是一个多余的干扰,通过删除几行很快就解决了。

带着一个可以缩放和拖动的地球仪,我准备进入下一个阶段。

基本功能已经就绪。

获取数据

为了开始将颜色引入风地图的风叠加,我需要数据。获取包含数据的数据文件很容易,但是提取它却不容易。

在美国国家海洋和大气管理局(NOAA)的网站上,你可以找到一个全球预报系统。它可以预测地球上任何地方的一系列参数(如温度、云量、风力和风向)。

数据被打包成一种很难处理的 GRIB 格式。它在等距网格上对二维数据的值进行编码。例如,分辨率为 1 度的 GRIB 温度文件将给出以下各项的温度:

(0⁰E, 0⁰N), (1⁰E, 0⁰N),… (180⁰E, 0⁰N), (179⁰W, 0⁰N),… (2⁰W, 0⁰N), (1⁰W, 0⁰N) \n
(0⁰E, 1⁰N), (1⁰E, 1⁰N),… (180⁰E, 1⁰N), (179⁰W, 1⁰N),… (2⁰W, 1⁰N), (1⁰W, 1⁰N) \n
(0⁰E, 2⁰N), (1⁰E, 2⁰N),… (180⁰E, 2⁰N), (179⁰W, 2⁰N),… (2⁰W, 2⁰N), (1⁰W, 2⁰N) \n
...

但是使 GRIB 文件难以处理的是它们是以二进制编码的。除非你使用一个单独的程序或库来解码它,否则没有办法从原始的 GRIB 文件中理解它。这又引入了对后端解码和提供解码的 GRIB 文件的需求。

起初,我计划让我的可视化自动从 NOAA 网站下载最新的 GFS 数据,但是只使用 JavaScript 处理 GRIB 文件的复杂性降低了我的热情。我决定使用一个静态 JSON 文件,其中包含来自2014-01-31T00:00:00.000Z的风数据。为什么是这个特殊的日子?这看起来像是忙碌的一天,有许多小天气系统在地球上运行。

创建色标

乍一看,来自earth.nullschool.net的原始色标由两部分组成:

  1. 第一部分以蓝色开始,以粉色结束,是以洋红色结束的镜像 Sinebow 刻度。
  2. 第二部分是品红色,其 alpha 逐渐增加,直到达到白色。

原始可视化中使用的色标

我偷看了一下风图的 Github repo,我发现色标背后的很多逻辑都是硬编码的。我开始创建自己的色标,最终得到了三个不同的版本:

  • 使用默认d3.interpolateSinebow的基本、快速和脏秤。它基本上忽略了色阶中从品红色到白色的部分。

  • 我使用自己的 Sinebow 插值器的精确色阶。它尽可能接*最初的实现。

  • 使用我自己的 Sinebow 插值器的高效色阶。它本质上是一个硬编码的if语句列表。我希望在用这种色阶生成风叠加时能达到更高的效率。

色标准备好了,除了开始上色(生成风覆盖)之外,没有什么要做的了。

第一次尝试添加风叠加

我经历了两次失败的尝试,才有效地将颜色添加到风图中,然后找到了我最终使用的第三个。这三种方法都有效,但是前两种不够有效,而且它们使可视化看起来不连贯和没有吸引力。

第一次尝试是快速扫描图表上的所有像素。我将检查该像素是否在可视化中。如果是,我会查找它的坐标,使用双线性插值法估计该点的风力,查找颜色,最后绘制像素。这个过程可以用下面的伪代码来描述:

for x in range(0, width):
  for y in range(0, height):
    flag1 = check_if_x_and_y_is_in_projection(x, y) if not flag1:
      color = black longitude, latitude = calculate_coordinates(x, y) wind_strength = calculate_wind_strength(longitude, latitude) color = color_scale(wind_strength)

这很有效,但是渲染要花很长时间。在缩放或拖动过程中生成图层是完全不可能的,必须将其关闭。即使使用超高效的色标也无济于事。你可以在下面的 gif 上看到实时的延迟:

生成风覆盖图是低效的

我试图弄清楚卡梅隆·贝卡里奥是如何用一种非常相似的方法实现他的风力覆盖的,并且让它高效地运行。我无法找到它的根源,但我注意到的一件事是,他会每隔一个像素查找一次(因此渲染所需的时间减少了一半)。

我不想在拖动或缩放时被迫关闭颜色。我知道一定有办法实现它,于是我开始了下一步。

第二次尝试在画布上使用光栅重投影添加风叠加

这背后的逻辑是生成一个 2D 风覆盖一次,并将其保存为图像。然后,在更新时,我会调用光栅重投影——即将光栅图像编码的地图(如.jpeg.png)转换为不同的地图投影(在我们的例子中,是正交地球)。

这里的假设是图像的重新投影比重新生成的计算量要小。事实证明这是真的。但是仍然不够快以允许*滑的拖动和缩放。你可以在下面的快速原型中看到这种起伏:

左边的 2D 地图将被重新投影到地球仪上。结果仍然不令人满意。

在这一点上,除了使用 WebGL 之外,别无选择——这是一个允许 GPU 加速浏览器内动画的 JavaScript 库。

第三个,也是最后一个,尝试使用 WebGL 的光栅重投影来添加颜色

只有在绝对必要的时候才应该使用 WebGL。该库尽可能高效,但使用它需要掌握类似 C 的代码开发。幸运的是,我能够在 Observable 上的一些公共笔记本上找到大量相关代码。特别是在 WebGL 中实现的光栅重投影。

在调整代码并使其符合我的代码结构后,我以一个惊喜结束了——这是迄今为止最快最流畅的交互。

WebGL 及其对性能的影响

添加和调试风粒子

动画风粒子使风球如此令人难忘。我的第一直觉是找到一个可以实现粒子运动的库。我偶然发现了由 Mapbox 团队开发的基于 WebGL 的库。它看起来很吸引人,但是玩了一会儿之后发现,它的默认风格很难看,而且库的设计不允许简单的颜色操作。

我决定建立自己的风粒子动画逻辑。这看起来比实际上更困难。我用了一个基于requestAnimationFrame()的动画循环。在每个循环的开始,我会复制一个低透明度的旧框架,然后在它上面画一个新的框架。每一帧都重复这个过程,就产生了想要的拖尾效果

基于画布复制和重绘的动画

动画循环可以用类似 JavaScript 的伪代码来概括:

(function tick() {
    const x = get_next_position()

    context.stroke(); // Make a copy with lower opacity
    context.globalAlpha=0.97
    context.globalCompositeOperation='copy'
    context.drawImage(context.canvas, 0, 0) //Draw the new Canvas on top    
    context.globalAlpha=1.00;
    context.globalCompositeOperation='source-over';
    context.beginPath();
    context.arc(x, height / 2, radius, 0, 2 * Math.PI);
    context.fill(); //Go to the next frame
    frame = requestAnimationFrame(tick);
  })();

然后,我会随机产生 1000 个粒子。在每一帧上,我会计算它们的坐标,并根据该区域的风矢量将它们移动到一个新的位置。当粒子的年龄超过随机设置的max_age时,我会将其重置到初始位置。在伪代码中,它看起来像这样:

for x, y, age in particles_list:
  if age > max_age:
    age = 0
    x = x0
    y = y0 else:
      long, lat = get_coordinates(x, y)
      u, v = estimate_wind_vector(long, lat)
      long_new, lat_new = long + u*scale, lat + v*scale
      x_new, y_new = get_coordinates_inverse(long_new, lat_new)

  age += 1
  x = x_new
  y = y_new

即使在这一阶段之后,地图看起来已经准备好了,我注意到风粒子会以一种奇怪的方式绕着两极运动。他们沿着一条表明某种极端情况发生在极点周围的道路前进。

极点周围的粒子似乎遵循{-x/sqrt(x +y +4),y/sqrt(x +y +4)}形式的向量场。这不太可能是靠*极点的风所发生的情况。用 Wolfram|Alpha 生成的矢量场。

找出导致这个问题的原因是构建这个数据可视化的最困难的部分。解决办法原来很简单。但是一开始,我错误地试图估算正投影的变形并解释它。

这种效应只发生在两极附*。我想这一定与我的投射有关。事实上,在正投影中,我们越靠*极点,经度就越短 1 度。

我在一本厚厚的教科书《T4 地图投影——美国地质调查局的工作手册》中寻找扭曲方程。我实现了一个相当复杂的函数,通过数值估计一阶导数来获得失真值。回顾过去——真是矫枉过正。它甚至没有解决问题。

解决办法原来很简单。移动质点时,忘了处理质点过 180°子午线的情况。两个声明足以解决这个问题。失真方程可以被废弃。

//handle edge cases for longitude
if (long_new > 180){
  long_new -= 360
}
else if (long_new < -180){
  long_new += 360
}

修饰和微调

最后,在调用可视化完成之前,需要查找和设置一些任意的参数。幸运的是,可观察的笔记本允许创建滑块,帮助找到视觉上令人愉悦的价值。

使用滑块进行微调

这是目的港。

回过头来看,有那么多地方看起来很简单。而且,每次我花额外的时间去解决意想不到的事情,视觉故事都有了显著的提高。强大的缩放和拖动、高效的基于 WebGL 的光栅重投影以及轻量级粒子动画都始于意外的挫折。

所以现在,给你自己弄杯咖啡,然后继续你的数据工作,即!

不要忘了在 Observable 上查看代码的实时可视化:https://observablehq.com/@oskarkocol/animated-wind-map

不要过度配合!II-如何避免机器学习和深度学习模型中的过度拟合

原文:https://towardsdatascience.com/dont-overfit-ii-how-to-avoid-overfitting-in-your-machine-learning-and-deep-learning-models-2ff903f4b36a?source=collection_archive---------19-----------------------

作者图片

O 预测建模的主要目标之一是建立一个模型,对看不见的数据做出准确的预测,这只有在我们确保它们没有过度拟合训练数据时才有可能。不幸的是,过度拟合是每个机器学习者在职业生涯中面临的常见绊脚石。这有许多原因,但我们想指出一些主要原因。首先是训练样本中存在较少的数据点,其次是数据集不*衡,最后但同样重要的是模型的复杂性。

在这篇博客中,我们将尝试几乎所有的机器学习和深度学习启发式方法,以避免 Kaggle 竞赛 之一的数据集中的过度拟合【不要过度拟合 II

以下是该博客关注的内容列表。我们会一个接一个地探索每一个。

目录

  1. Kaggle 问题陈述、数据集和评估指标
  2. 现有方法
  3. 过拟合的研究工作
  4. 我们的贡献
  5. 探索性数据分析(EDA)
  6. 特征工程
  7. 第一次切割方法
  8. 机器学习模型
  9. 深度学习模型
  10. 结果
  11. 结论
  12. 未来工作
  13. 参考文献

Kaggle 问题陈述、数据集和评估指标:

问题陈述

用训练集中的 250 个数据点建立模型,并对测试集中的 19750 个数据点准确预测二元目标。数据集包含 300 个连续变量的要素。

资料组

数据集可以从这里获得。

文件:
● train.csv —训练集。250 行。
● test.csv —测试集。19750 行。
● sample_submission.csv —格式正确的样本提交文件
列:
● id-样本 id
● target-一个来源神秘的二进制目标。
●0–299-连续变量。

注:

kaggle 网站上目前可用的数据集是一个新版本,但评估仍在旧版本上进行。你可以在这里得到旧版本的

评估指标

AUCROC (受试者工作特性/曲线下面积)

ROC 曲线总结了使用不同概率阈值的预测模型的真阳性率和假阳性率之间的权衡。但是,当数据集高度不*衡时,这种度量并不可取。ROC 曲线下的面积称为 AUC,AUC 越高,性能越高。对于无技能模型,AUC 将为 0.5。

现有方法:

我们已经知道这个比赛在一年前已经在 Kaggle 上完成了,大量的方法得到了应用。一些最好的方法阐述如下:

只是不要过度拟合【1】:

这篇博客的关键方法是使用 LASSOCV(最小绝对收缩和选择操作符交叉验证)。它由两个术语 LASSO 和 CV 组成(其中 CV 是交叉验证)。LASSO 回归器的主要功能是添加一些偏差项,以最小化模型的方差。它执行 L1 正则化,即添加相当于系数幅度绝对值的惩罚。它的目标函数是:

作者图片

其中唯一的参数是α。alpha 值越大,要素的权重越接*零。该算法的使用导致 Kaggle 领先板上的得分为 0.843

不要过度配合!—如何防止深度学习模型中的过度拟合【2】:

这个博客试图训练一个深度神经网络模型,以避免我们拥有的相同数据集的过度拟合。首先,使用 RFE(递归特征消除)算法进行特征选择。接下来,训练一个简单的具有 2 个隐藏层和 2 个早期停止的丢弃层的 NN 模型,导致 80% 的测试准确度。

关于过度拟合的研究工作

过度拟合及其解决方案概述【3】:

本文详细介绍了一些避免过拟合的启发式技术,并给出了如何以及何时应用它们的原因。

网络缩减:
模型的复杂性可以通过消除不太重要和不相关的数据(即噪声)来降低,这反过来将有助于模型防止过拟合,并对看不见的数据表现良好。这被称为剪枝,广泛应用于决策树算法中。已经提出了两种类型的修剪方法,一种是预修剪,另一种是后修剪

预修剪方法试图在生成具有非常小样本的叶子之前尽早停止树构建过程。在分裂树的每个阶段,我们检查交叉验证错误。如果误差没有明显减小,我们就停止。这在学习算法中也称为提前停止。

后期修剪包括修剪树木。在树被构建之后,它被修剪回交叉验证误差最小的点。

训练数据的扩展:
由于有限的数据会导致模型过拟合,我们应该将其扩展出来,这可能有助于模型避免过拟合。本文提出的技术包括向现有数据集添加一些随机噪声,通过一些处理从现有数据集中重新获取一些数据,以及基于数据集的分布产生一些新数据。

正则化:
大量的特征使得模型更加复杂。如果我们在代价函数中加入一个正则项,而不是任意地丢弃一些特征,这将通过最小化它们的权重来减少无用特征的影响。L1 正则化项将不太重要的特征的权重设置为零,而 L2 正则化使该类型的权重太小。

变量选择方法比较中的过度拟合【4】:

本文介绍了两种主要的特征选择方法,即顺序向前选择(SFS)和顺序向前浮动选择(SFFS)。覆盖了在声纳和蘑菇数据集上获得的结果,从而表明 SFFS 产生了比 SFS 更好的结果。在蘑菇数据集中,与 SFS 选择的几个特征相比,SFFS 在测试数据上给出了更好的结果,即使是一半的特征。

顺序前向选择(SFS):
在该方法中,首先选择最佳单个特征,并与未选择的特征配对,再次跟随最佳配对特征的选择。同样,制作具有最佳对和未选择特征的三元组,然后选择最佳三元组特征。这个过程一直持续到选择了所需数量的特征。

作者图片

这种方法的缺点是,一旦选择了一个特征,我们就不能删除它,即使我们可以通过另一个相对较小的特征子集获得良好的结果。SFFS 克服了这一限制。

顺序向前浮动选择(SFFS):
【SFFS】从空集开始。在每向前一步之后,只要目标函数保持升级,它就执行向后一步。这种方法的关键是使用回溯算法来选择最佳和最小的特征子集。这种方法的缺点是计算量大。

作者图片

多目标学习中的泛化改进【5】:

与上述处理过拟合的策略不同,本文提到了一种称为噪声注入(抖动)的启发式方法来消除此类问题。在本文中,已经证明 SO(单目标,例如均方误差)算法比 MO(多目标,例如 ROCAUC)算法更容易过拟合。这是因为,在 ROCAUC 中,成本函数算法试图同时最大化 TPR 和最小化 FPR,其作为调节器工作并阻止其过度拟合。
已经提到的第二件重要的事情是,神经网络对于训练模式中的微小变化更加稳健。因此,通过注入噪声和用神经网络训练这样的数据来扰动训练数据,使得模型不会过度拟合,并且在测试数据上表现得更好。

以下是本文中提到的扰动训练数据的两种方法。
加性高斯噪声:
在每一代中,通过向输入的每个元素添加正态分布随机数来生成新的人工训练数据集。
通过*均添加噪声:
在这种方法中,通过在局部邻域内*均原始图案来生成新的人工图案。

我们的贡献

已经应用了几种方法,产生了一些结果。然而,在迄今为止我们从各种研究论文中学到的许多相关技术中;我们会用重要的概念性想法来指导我们的项目。我们的方法分为两种:第一种是机器学习方法,另一种是神经网络方法。

机器学习方法:

  1. 应用过采样欠采样两种技术来*衡稍微不*衡的数据集。
  2. 由于更多的特征可能导致过度拟合,因此只有重要特征的选择属于基于过滤方法、包装方法和嵌入方法的特征选择。
  3. 由于特征工程是构建智能系统的重要组成部分,并且我们知道所有的特征值都是连续分布的,我们可以通过使用宁滨技术将连续数据转化为离散数据。我们将应用自适应宁滨来处理一些本质上倾斜的特征。

神经网络学习方法:

  1. Lars Gr 等人【5】提到噪声注入会帮助模型防止过拟合。因此,我们将在我们的神经网络架构中添加高斯噪声层以及下降层。

让我们从数据集的探索性数据分析开始吧!!

探索性数据分析

数据集显示如下:

训练数据

作者图片

观察:

训练数据有 300 个自变量(0 到 299)和一个因变量(目标)以及一个唯一 id 和 250 行(数据点)。所有要素的值都是连续的,并且从描述表来看似乎具有相似的分布。

缺少值?

作者图片

观察:

正如您所观察到的,这里没有空值。

单变量分析

目标:

作者图片

观察 :

可以清楚地看到,数据集是不*衡的,其中属于目标 0 的数据点是 36%,但是对于目标 1 是 64%。因此,可以说目标 1 大约是目标 0 的两倍。

单帧中所有(0–299)独立特征的分布图:

作者图片

作者图片

观察:

从上面两个图中,可以清楚地感知到,整个 300 个特征的分布几乎是相同的,并且都具有几乎相同的均值和标准差。

如果我们更深入地研究每个特征图,我们会发现目标 0 和目标 1 点在它们的每个特征分布中的重叠。所有特征分布的偏斜值在[-0.37,0.43]的范围内,峰度值在[-0.78,0.98]的范围内。因此,我们可以说所有的分布都是*似对称的,但不是完美的正态分布。

双变量分析

关联:

作者图片

观察:

从上面的热图来看,要得到特征之间相关性的确切值是相当困难的。然而,从颜色条中,可以观察到特征并不高度相关,因为相关性的范围是[-0.2 到 0.2]

与目标相关的前 10 个特征:

作者图片

观察:

特征 33 和 217 分别与目标 1 和 0 最相关。

对图中前 5 个与目标正相关的特征:

作者图片

观察:

上述 4 个特征[33,65,24,183]将是对分类任务最重要的特征,因为很明显它们不是完全重叠的,而是完全分离的。

对图中与目标负相关的前 5 个特征:

作者图片

观察:

同样,特征[217,117,91,295,73]将是进行分类的重要特征,因为很明显它们不是完全重叠的,而是完全分离的。

多变量分析

2D 300d 数据点可视化:

作者图片

观察:

所有的点都杂乱无章地散布着。因此,它不是线性可分的。

300d 数据点的三维可视化:

作者图片

观察:

随着维度的增加,目标 0 和目标 1 点仅经历分离。因此,它们在更高的维度上更容易区分

所有特征的均值、标准差、偏度、峰度:

作者图片

观察:

基于均值和标准差频率图的所有特征似乎都是归一化的,并且正态分布,均值= 0(*似值)和标准差=0.1(*似值)。

如果我们观察偏斜度和峰度频率图,偏斜度= 0.15,峰度> 1.5(对于目标 1 数据点),这表明它具有比正态分布更重的尾部。

目标 0 和目标 1 数据点的分布重叠。

因此,我们可以得出结论,随机分布不存在。

特征工程

偏度> 0.3 或偏度< -0.3: 的特征的基于四分位数的宁滨

代码:

首先我们搜索偏斜度>为 0.3 或偏斜度< -0.3 的特征,应用四分位数自适应宁滨,然后将所有这些特征保存到磁盘中。

作者代码

作者图片

观察:

使用基于四分位数的自适应宁滨,我们将 7 个偏斜特征转换成分类特征。

工程特征还显示目标 0 和目标 1 点之间的重叠。然而,在某个频率极限之上,目标 0 点是占优势的,这被证明是有用特征的证据。

首次切割方法

基于 EDA,以下是需要注意的核心要点:

  • 数据集中的行数太少。
  • 数据集不是高度不*衡的。因此,它不会对模型产生太大的影响。
  • 所有特征值都是实数。没有明确的特征。甚至所有特征的分布几乎相同,并且它们接*正态分布。因此,我们不需要任何复杂的预处理。只有简单的标准化才行得通。

记住以上几点,我们的第一步方法是训练一个正则化的逻辑回归模型。我们将使用 RandomSearchCV 搜索合适的参数。

机器学习模型

所有的模型都被归类为一种类型,如基线模型、过样本模型、工程特征模型等。在每种类型下,有 8 种不同的分类算法,随后是给定数据集的校准训练。它们如下所列:

  1. 逻辑回归(线性)
  2. 线性判别分析(线性)
  3. k *邻分类器(非线性)
  4. 决策树(非线性)
  5. 朴素贝叶斯(非线性)
  6. 支持向量分类器(非线性)
  7. 随机森林(非线性)
  8. XGBoost(非线性)

在直接进入每个模型之前,让我们先讨论一下设计的所有有用的功能。

绘制受试者工作特征曲线下面积(AUC ROC):

作者代码

八种分类算法的流水线:

作者代码

八分类器模型训练模板:

作者代码

现在让我们从建模和导入我们的火车测试数据开始!

作者代码

作者图片

1.基线模型

在该模型中,除了标准化/缩放原始数据集之外,没有进行其他修改。获得的数据集因此用 8 个提到的分类器训练。通过给出 0.818(私人得分)的逻辑回归获得最佳结果。从基线模型来看,这个结果绝对超过预期。

代码:

作者代码

基线模型 Kaggle 提交分数:

作者图片

最佳得分分类器的 ROC 曲线(即逻辑回归):

作者图片

2.过样本模型

在这个模型中,我们首先在 SMOTE 算法的帮助下对属于少数类的数据点进行上采样,以*衡数据集。然后,我们用所有的分类器训练它。使用得分为 0.754(私人得分)的 XGBoost 算法获得了显著的结果。然而,与基线模型相比,这一分数并未达标。

代码:

作者代码

过样模型 Kaggle 提交分数:

作者图片

最佳得分分类器的 ROC 曲线(即 XGBoost):

作者图片

3.样品型号不足

在该模型中,应用上采样和下采样来*衡数据集,然后用所有分类器训练数据集,从而由 XGBoost 产生最佳得分 0.694(私人得分)。与其他模型相比,这个分数证明了上采样和下采样同时进行可能是行不通的。

代码:

作者代码

样本模式下 Kaggle 提交分数超过:

作者图片

最佳得分分类器的 ROC 曲线(即 XGBoost):

作者图片

4.工程特征模型

在这里,我们向原始数据集添加了 7 个宁滨编码的特征,并用所有分类器对其进行训练,通过逻辑回归算法获得了最高得分 0.762(私人得分)。显而易见,我们设计的功能甚至降低了性能,但并没有解决这个问题。

代码:

作者代码

工程特征模型 Kaggle 提交分数:

作者图片

最佳得分分类器的 ROC 曲线(即 Logistic 回归):

作者图片

5.互信息模型

在该模型中,互信息是一种基于过滤器的特征选择方法,用于选择最佳特征,然后与所有分类器一起训练它们。 SVC 算法给出了 0.666 的好成绩(私分)。将该分数与其他模型的分数进行比较,我们可以得出结论,这不是该问题的最佳特征选择方法。

代码:

作者代码

互信息模型 Kaggle 提交分数:

作者图片

最佳得分分类器(即支持向量分类器)的 ROC 曲线:

作者图片

6.顺序向前选择模型

在该模型中,SFS(一种基于包装器的特征选择方法)已被应用,随后是前 20 个特征的选择。所有的分类器只使用这些特征来训练数据。使用随机森林获得 0.710 的最佳分数(私人分数)。这个分数也证明了它并不是这个问题的最佳特征选择方法。

代码:

作者代码

SFS 图:

作者图片

SFS 模型的 Kaggle 提交分数:

作者图片

最佳得分分类器(即随机森林)的 ROC 曲线:

作者图片

7.序贯向前浮动选择(SFFS)模型

在该模型中,应用了基于包装器的特征选择方法 SFFS,随后选择了前 17 个特征。然后用具有这些特征的所有分类器来训练数据。最好成绩 0.712(私分)由朴素贝叶斯产生。与之前的模型相似,这种方法并没有导致分数的显著增加。

代码:

作者代码

SFFS 图:

作者图片

SFFS 模型 Kaggle 提交分数:

作者图片

最佳得分分类器(即朴素贝叶斯)的 ROC 曲线:

作者图片

8.递归特征消除(RFE)模型

在该模型中,应用了基于包装器的特征选择方法 RFE。最佳基线分类器被用作 RFE 方法的估计量,该方法产生 0.838 的显著分数(私人分数)。这就是我们期待的结果!这种特征选择的方法对于这个问题表现得很好。

代码:

作者代码

RFE 模型 Kaggle 提交分数:

作者图片

RFE 模型的 ROC 曲线:

作者图片

9.嵌入式模型

在该模型中,采用了一种嵌入式的特征选择方法。使用的 3 种不同的嵌入式算法是 LassoCv、LassoLarsCV 和 RidgeCV。他们用 LassoCV 算法得到了 0.821 的显著分数!这种特征选择方法成为解决我们问题的最佳方法之一。

代码:

作者代码

嵌入模型 Kaggle 提交分数:

作者图片

最佳得分分类器(即 LassoCV)的 ROC 曲线:

作者图片

深度学习模型

深度学习方法中有两种模型,基线模型和噪声模型。

让我们首先讨论 DL 模型的所有效用函数。

列车功能:

作者代码

损失、准确性和 AUC 绘图功能:

作者代码

1.基线模型

该模型仅使用两个分别为 40 和 20 个神经元的隐藏层进行训练,结果很差,得分为 0.608(私人得分)。

代码:

作者代码

基线指标图:

作者图片

DL 基线模型 Kaggle 提交得分:

作者图片

2.高斯噪声模型

该模型已经用两个隐藏层进行了训练,每个隐藏层有 20 个神经元和两个噪声量为 0.01 的高斯噪声层以及两个丢弃率为 0.3 的丢弃层。获得了分数为 0.753(私人分数)的相对较好的结果。

代码:

首先进行网格搜索以获得 aur 架构的最佳超参数,然后用该神经网络进行训练。

作者代码

噪声模型的度量图:

作者图片

DL 噪声模型 Kaggle 提交评分:

作者图片

结果

根据私人评分对所有 ML 模型进行排名

作者图片

根据私人评分对所有 DL 模型进行排名

作者图片

迄今为止最好的 Kaggle 评分模型

作者图片

结论

  • 在所有的特征选择方法中,递归特征消除法在这个问题上做得很好。
  • 由于特性的数量大于行数,添加更多的特性肯定是行不通的。
  • 众所周知,即使有大量数据,神经网络也容易过度拟合。我们正在处理的数据非常少,这使得过度拟合的可能性最大。然而,噪声层的注入明显减少了这种担心,我们的模型比预期的要好得多。
  • 由于所有嵌入式方法的性能都优于基于过滤器和包装器的方法,因此对不太重要的特征给予低权重被证明是一种更好的技术,而不是直接消除这些特征。

未来的工作

  • 类似于排名前 3 的参赛者,可以应用 LB 探测技术。
  • 神经网络模型的效果远远好于预期,因此我们的模型可以进一步改进,这样分数可以增加到 0.80 以上。
  • 我们可以通过组合我们得到的所有执行模型来尝试堆叠和投票模型。

参考

[1] Brij Patel,就是不要过度拟合,(2019)。

[2]尼尔斯·施吕特,不要过度拟合!—如何防止深度学习模型中的过度拟合,(2019)

[3]薛颖,北京市海淀区上地七街 1 号钟会大厦 1 号楼,邮编 10 0085

[4] Juha Reunanen,在变量选择方法之间进行比较时过度拟合,ABB,网络成像系统,邮政信箱 94,00381,芬兰赫尔辛基

[5] Lars Gr,jiao Chu Jin,IEEE 高级成员,和 Bernhard Sendhoff,IEEE 高级成员,多目标学习中的泛化改进,2006 年神经网络国际联合会议,加拿大温哥华喜来登酒店,温哥华,BC,2006 年 7 月 16-21 日

申请课程:www.appliedaicourse.com

感谢您的阅读!这里是我在 GitHub 上的 LinkedIn 简介代码。

不要一次剥完洋葱

原文:https://towardsdatascience.com/dont-peel-the-onion-all-at-once-78935a9258ca?source=collection_archive---------18-----------------------

就有利可图的 Python 采访阿列克谢·格里戈里耶夫

本和阿列克谢正在谈论有利可图的 Python(照片由奥斯汀·迪斯特尔Unsplash 上拍摄)

我很高兴能在本的盈利的 Python 播客上与他交谈。在我们的谈话中,本问了许多有趣的问题,这就是为什么我决定在博客中总结我们的谈话。

我们涵盖以下主题:

  • 我正在写的书(“机器学习图书营”)
  • 通过做项目和在 Kaggle 上竞争来学习
  • 成为机器学习专家
  • 学习机器学习时保持正确的抽象水*
  • 快速原型制作和将模型投入生产
  • 和其他东西

开始吧!

欢迎来到 盈利巨蟒 。我是本·麦克尼尔,今天我们采访阿列克谢·格里戈里耶夫。

Alexey 与妻子和儿子住在柏林。他是一名专注于机器学习的软件工程师。他在 OLX 集团担任首席数据科学家。阿列克谢是一位纸牌大师,他写了几本书。其中一个是“ 掌握数据科学的 Java”,现在他正在做另一个——“机器学习书营 ”。那不是错别字,那叫“书营”。

阿列克谢,欢迎你!

嗨,本,很高兴来到这里。

很高兴有你。你能告诉我更多关于你正在写的书的事情吗?

是啊!想法是通过做项目来学习机器学习。每一章都是一个新项目:你得到一个数据集,准备它,建立一个模型。我们也观察每个模型的内部,看它如何做出预测,并试图理解它。这是相当实际的,我们将理论保持在最低限度。完全避免它并不总是可能的,这就是为什么这里那里仍然有公式,但重点是编码。

书中的插图:ML 算法的输入是特征和目标,输出是模型

目标读者是已经会编码的人,比如软件工程师,或者已经有编码经验的学生。当你浏览这本书时,你建立了一个项目组合,最终,你知道了足够多的信息,可以得到一份 ML 工程师的工作,并在工作中继续学习。

这本书仍在进展中,但已经有可能看一看里面,并决定你是否喜欢它。已经有三章一附录了。总共有十章,所以现在已经完成了 30%。

是什么激发了你写这本书的想法?

前段时间我写了另一本书——是关于数据科学的 Java。我真的很喜欢它,但是它变成了一个非常小众的话题:Java 对于 ML 来说并不是那么流行。今天,如果你想做 ML,你用 Python,而不是 Java。所以,我想,我还有想和世界分享的东西,但是世界对 Java 不感兴趣,我们再写一本书吧——这次用 Python。

通过做项目来学习的想法是我从 Kaggle 那里学来的——这是一个举办数据科学竞赛的网站。在 Kaggle,一家公司准备了一个数据集,然后要求社区为他们训练最好的模型。

只有在 Kaggle 上我才真正学到了 ML。我在大学里花了几年时间学习理论,但如果没有适当的实践,这些理论是没有用的。而且,说实话,竞赛并不真的需要这种理论——参与是一种非常需要动手的活动,需要大量的编码:你生成新的功能,将它们放入库中,调整参数,查看结果,并不断重复,直到竞赛结束。

我参加了 10 多次比赛,每一次都非常有用

这让我意识到学习 ML 的最好方法不是研究它,而是做它:每个 Kaggle 比赛都是一个项目,通过做这些项目,我能够真正地学习 ML。对我来说,这比在黑板上看方程如何求解更有帮助。

这就是为什么我认为基于项目的方法是软件工程师和其他编码人员的最佳方式。这就是我决定写这本书的原因。

酷。我很高兴看到这一进展。 能否介绍一下你的背景,以及你是如何成为机器学习专家的?

我来自俄罗斯远东的一个小城市。我所在的城市有一所小大学,我学的东西有点过时了:我在学习使用 Delphi 之类的东西。2006 年,我所在地区的组织需要的就是这些。然而,我们学到了一些基本的东西,如数据库和自动化业务流程。

那很有趣,但是我真正喜欢的科目是数学和统计学。不幸的是,没有办法应用这些技能:每个人都只需要一个数据库。

最终,我搬到了俄罗斯中部的一个更大的城市。那里的公司不需要 Delphi,他们需要 Java 和 web 服务。于是我把工作重心转到了 Java 上,做了一段时间的 Java 开发人员。

2012 年,Coursera 开始流行。其中一门课程是机器学习。我碰巧看了那门课,它改变了我的生活:Java 和数据库很有趣,但 ML 吸引了我,所以我决定走那条路。

吴恩达著名的机器学习教程

大约在那个时候,数据科学职位也开始出现在市场上,尽管数量很少。当时我住在波兰的克拉科夫,有几个职位空缺,但所有的职位都需要博士学位和五年的 Hadoop 经验。这些公司不明白他们想从数据科学中得到什么,他们只是听说了 ML,然后想,“让我们雇佣一个有博士学位的人,让他们弄清楚我们想要什么”。

2013 年数据科学采访(由凡泰传媒Unsplash 上拍摄)

从 Java 转向数据科学是一个艰难的时期。这就是为什么我决定接受一些额外的教育并攻读硕士学位。

毕业后,我突然发现公司不再需要博士了。市场想出了他们需要从数据科学家那里得到什么。他们明白拥有博士学位是件好事,但不是必须的。从那以后,对数据科学和 ML 的需求一直在增长。

谷歌趋势:人们对数据科学和机器学习的兴趣正在稳步增长(链接)

当我开始做全职数据科学家时,我发现拥有软件工程背景非常有帮助。仅仅训练一个模型是不够的,你需要走向生产,而这是许多数据科学家纠结的事情。他们知道如何阅读论文,并从这些论文中实现算法,但走向生产是另一回事。这就是为什么接触一些软件工程有助于数据科学家利用他们的模型,更快地解决业务问题。

一名软件工程师正在生产中进行数据科学研究(图片由阿洛拉·格里菲斯Unsplash 上拍摄)

我还注意到,许多公司看到了这一点,并开始寻找这类人——了解 ML 的软件工程师,也许不深入,但足以实际训练一个模型,然后产生商业影响。

这很有趣,也有点违反直觉。

是的。我试图深入数学,但最终,并不需要。尽管研究它很有趣,但我和我的许多同事所做的工作是不同的。我们不解数学方程。我们花几个月的时间准备数据集,然后去图书馆,等十分钟训练结束,得到一个模型,然后再花几个月的时间生产这个模型。

训练一个模型并不需要花费太多时间,然而许多大学课程和在线课程的重点是 ML 背后的数学。是的,它仍然是需要的:作为一名数据科学家,你有时需要理解库内部发生了什么——就像软件工程师需要知道 TCP/IP 是如何工作的一样。然而,没有多少软件工程师需要每天深入网络堆栈。也许五年一次,当有问题的时候,但是日常工作通常不需要这样。

OSI 模型。对软件工程师来说非常有用,但在日常工作中可能不需要(来源:https://commons.wikimedia.org/wiki/File:Osi-model.png

所以,你只需要有广泛的知识和良好的接触不同的技术。知道细节是好的,但并不总是必要的。你所需要的只是基础——能够注意到事情是否不对劲。但是当你面对一个问题时,你需要更深入。

我反其道而行之,试图提前了解一切。相反,我应该专注于实践技能,并在需要时深入挖掘。

我注意到你在简历中提到了“快速成型技能”。你如何使用它们?

对于软件工程项目,尤其是 ML,尽快验证想法是很重要的。

通常你甚至不需要编写任何代码就可以验证一个想法。

想象一下,我们想要建立一个系统来确定一幅图像是好是坏:它被恰当地框住,聚焦并且有良好的曝光。我们不需要在模型上花时间,我们自己可以只看图片就决定质量好不好。如果不是,我们就给卖家发邮件,看看他们有什么反应。如果他们的反应是积极的,并且这是他们所需要的,那么我们就投入时间来建立一个实际的模型。

快速原型制作过程中的我(图片:旧苏联卡通https://www.youtube.com/watch?v=_39zAeiNXxo——俄文,英文字幕)

当谈到原型时,你可以快速地构建一些东西,例如一个简单的 Python Flask 应用程序,它最初可能甚至没有遵循最好的工程标准。重点在于速度,因为你想在投入时间之前先验证这个想法。然后你把这个展示给用户,或者公司内部的利益相关者,看看他们是否对这个项目感兴趣。

快速行动也意味着快速失败和快速学习:决策者通常会说“这不是我们的意思,我们不需要这个东西”。尽早了解反馈是非常好的:花了半年时间却发现项目不被需要,这是非常令人沮丧的。

如何成为快速原型制造专家?

给你的任务设定时间框架。比方说,只给它五天时间,然后在这几天里尽可能多的做。动作要快,但不要让它比计划花费更多的时间。

如果你只有一周时间,那么你就开始考虑最重要的事情。然后在一周之内,你就有了一个工作系统并进行演示。

如何不费吹灰之力就说服某人聘用你为机器学习专家?

嗯,首先,买我的书(笑)。

但是,说真的,做项目。

然而,要得到一份工作,你可能也需要得到关注。如果你有一个想法,找到或收集一个数据集,实现这个想法,训练一个模型。不要就此打住。把代码放到 GitHub 上,写一篇关于它的博文,在社交媒体上分享。如果你在十个项目中这样做,你肯定会受到关注。

在互联网上引起注意(图标由 Good WareSmashiconsPixel perfectfree pickfromflat icon

机器学习新人应该避免什么?

在开始的时候,尽量避免陷入太深的理论。例如,有一些算法,像 SVM,需要很强的数学基础才能理解它们:两年的微积分,然后是一年的凸优化。这是相当严重的,你可能会想,“我什么都不懂,所以我要辞职”。人们放弃了。不要。不要让这些方程式吓到你。

一个试图理解 SVM 的数据科学新人(照片由汤姆·普姆福德Unsplash 上拍摄)

ML 库隐藏了这种复杂性。您可以使用它们,而不用担心里面有什么——就像软件工程师可以在不知道 TCP/IP 如何工作的情况下创建 web 服务一样。当然,知道基础很重要,但作为新人,你应该把重点放在学得快而不是学得深。

Scikit-Learn:一个很棒的机器学习库(【scikit-learn.org】T4)

所以停留在正确的抽象层次——对于初学者来说,这可能是一个你视为黑盒的库。当你需要的时候,再深入。不要试图一次剥掉洋葱皮。

在生产中运行 ML 模型的主要收获是什么?

尽可能快地去。尝试尽快部署一个模型。项目失败最常见的原因之一是在制作完美模型上花费了太多时间。不要。从简单的基线开始,然后尝试部署它——并将其用于生产,看看人们对它的反应。

不要把它弄得过于复杂。例如,如果您想要建立一个价格建议模型,从每个类别的*均价格开始。以汽车为例,它可以简单到每个品牌和型号的*均值。不要从神经网络或者同样复杂的东西开始。

如果你在一个系统上投入了大量的时间,就很难放手。这就是众所周知的宜家效应:如果你自己做了一件东西,你会喜欢它,即使对其他人来说这没什么特别的。想象一下,你在做一把椅子,你花了三个小时做好了,它没有散架,你可以坐在上面。你喜欢这把椅子,但对其他人来说,它可能看起来很丑。同样的事情也发生在软件上:如果人们长时间构建一个东西,他们很难放弃它。

这就是我自己做椅子时发生的事情(照片由威廉·沃比Unsplash 上拍摄)

我有这个问题,所以意识到问题已经很有帮助了。在某些时候,继续做一个项目是没有意义的,你只需要停下来。

但是,如果一开始你只花了一周时间,却没有解决问题,你就停止了努力。你从早期的反馈中学习,然后继续前进。

你收到过的最好的建议?

“数学没有你想的那么重要,但解决商业问题比看起来更重要”。如果你的程序只是一堆“如果”语句,但它解决了一个问题——那就很好。所以从简单的启发开始,如果你看到它有帮助,继续做更复杂的事情。

只要能解决业务问题,没人会关心你的服务里面有什么

你如何决定抓住什么样的演讲机会?

我几乎什么都愿意做,因为目前我没有太多的演讲机会。我还在学习如何让我的提议听起来令人兴奋,所以会议组织者接受了它们,让我在他们的活动中发言。

你知道我可以发言的会议吗?请伸出手来(Theofilos Papapanagiotou 拍摄)

怎么和你联系?

在 Twitter ( @Al_Grigor )和 LinkedIn ( agrigorev )上关注我。

Alexey,非常感谢你来参加我们的节目。

谢谢你邀请我。我喜欢和你谈话。

是的,这很有趣。和*了,伙计们。

谢谢你阅读它。如果你喜欢这篇文章,你可以在 profitablepython.fm 上听完整集。这篇博文所涵盖的内容远不止这些!

对于盈利的 Python 的新剧集,在 Twitter 上关注 @PyPodcast ,订阅 YouTube 频道,在 LinkedIn 上关注 Ben

Python StdOuts:不要打印,记录!

原文:https://towardsdatascience.com/dont-print-log-85df4c153abb?source=collection_archive---------25-----------------------

小窍门

显示状态消息的 pythonic 方式

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

通常在 Python 上,尤其是作为初学者,您可能会打印( )一个变量,以便查看程序中发生了什么。如果你在整个程序中依赖太多的打印语句,你可能会面临不得不在最后注释掉它们的噩梦。查看程序正在做什么的另一种方式是日志记录。然后,您可以将打印内容限制为最终用户希望看到的命令行输出。

为什么要日志?

日志是一种在开发阶段查看程序状态的舒适工具。理想情况是:

  1. 您希望区分调试输出和程序输出
  2. 您不希望在最终产品中出现不相关的标准输出
  3. 您希望在开发和测试后禁用所有标准输出
  4. 您希望将程序执行历史保存到一个文件中,该文件包含元信息,如时间和更详细的调试信息。

怎么日志?

您可以使用日志模块登录 python。

import logging

日志模块提供了在程序中记录各种状态消息的一些默认状态。默认级别为DEBUGINFOWARNINGERRORCRITICAL

如果您执行以下程序:

import logging
import os

savepath = ‘path/to/save/at/’if not os.path.exists(savepath):
  logging.warning(‘Warning! The savepath provided doesn\’t exist!'     
                  'Saving at current directory ‘)
  savepath = os.getcwd() 
  logging.info(‘savepath reset at %s’,str(savepath))else:
    logging.info('Savepath provided is correct,'
                 'saving at %s’,str(savepath))

示例中的路径不存在。您将看到以下输出:

WARNING:root:warning! The savepath provided doesn’t exist!Saving at current directory

不显示新的当前保存路径信息,即 logging.info。

这是因为输出的默认严重级别是“警告”。严重程度的顺序如下:

DEBUG

INFO

WARNING(这是默认设置)

ERROR

CRITICAL

如果您想要查看较低严重性级别的输出,您必须在日志记录配置中显式设置它们。在这个设置之后启动一个新的解释器,否则它将无法工作。

logging.basicConfig(level = logging.DEBUG)

现在,一切都将被打印出来,从调试级开始。

输出:

WARNING:root:warning! The savepath provided doesn’t exist! Saving at current directory INFO:root:savepath reset at path/to/current/directory

太棒了。但是对于一个像样的日志,我们可能希望看到更多的信息,并将其放在一个单独的文件中。这可以使用配置中的格式和文件名来设置。在文件开头添加所需的配置:

logging.basicConfig(filename=’logfilename.log’,level = 
                    logging.DEBUG,format=’%(asctime)s %
                    (message)s’,
                    datefmt=’%d/%m/%Y %I:%M:%S %p’)

这会将您的信息连同时间戳一起记录到 logfilename.log 中。

13/06/2020 05:14:47 PM warning! The savepath provided doesn’t exist!  
                       Saving at current directory 
13/06/2020 05:14:47 PM savepath reset at current/working/directory

下一次运行该文件时,日志会被附加到文本文件中,这样您就可以在一个地方拥有日志的历史记录。您也可以更改它,每次都创建一个新的文本文件,方法是将它添加到您的 logging.basicConfig 中

filemode='w'

您可以通过在脚本中添加以下内容来集中禁用所有日志记录,而不必注释掉每条消息:

logger = logging.getLogger()
logger.disabled = True

或者,您可以选择更改需要写入日志文件的输出级别,以便只向最终用户显示警告和严重错误消息。

这是登录 python 的入门知识。日志记录提供了比上面描述的更大的灵活性(处理程序、过滤器、更改默认日志级别等),但这应该足以开始使用基本的日志记录,并消除打印语句。

不要依靠数据科学和机器学习来招聘(目前)

原文:https://towardsdatascience.com/dont-rely-on-machine-learning-and-data-science-to-hire-cd4f2352349a?source=collection_archive---------22-----------------------

人工智能系统风靡一时,但它们有严重的内在缺陷

查尔斯在 Unsplash 上的照片

由于时间和预算越来越紧张,公司不得不设计或利用创新的方法来赢得这场人才大战。麦肯锡预测,世界将出现人才短缺——确切地说,4000 万受过大学教育的工人太少。万宝盛华集团最*的人才短缺调查发现,38%的雇主难以填补职位空缺。随着就业市场竞争越来越激烈,公司开始转向技术的最新发展:人工智能系统来寻找、筛选和雇用最佳候选人。

难怪:2020 年的招聘和接下来的几年为公司带来了范式转变。员工不再像以前那样忠诚。拥有这种特质的千禧一代和新生代逐渐在职场中占据更多位置。为了扭转这一趋势,公司正专注于设计令人信服的员工体验。

然而,现任者往往抵制变革。大多数时候,他们太重而不能快速移动,因为他们传统的筒仓工作方式仍然存在。为了改变前进的方式,公司越来越多地转向人力资源技术供应商,推动人力资源技术市场到 2024 年价值至少达到 36 亿美元。

这导致了一个突破性的发展:公司越来越多地使用人工智能和数据科学来决定他们的招聘决定。

最初是有道理的。这些由数据科学家和招聘经理构建的算法旨在消除人类偏见。传统上,人类有偏见和偏好,这使得我们的招聘决定不公*——这就是为什么如果你和面试官有相同的爱好,你会在面试中表现得更好的原因。这会建立融洽的关系,这会影响面试后对他们的评价。

算法消除了这种模糊的判断。毕竟,计算算法常常胜过人类的判断,这意味着我们常常信任它胜过信任自己

使用数据,算法客观地评估,没有我们所有人都有的认知偏差。筛选候选人的两小时工作可以缩短到几秒钟:对一家公司来说,不浪费时间就是省钱。

不幸的是,节省几个小时可能会导致更多的金钱损失,因为批评家们正在表明算法实际上越来越有偏见。

2003 年,美国国家经济研究局的一组研究人员进行了一项实地实验。他们向波士顿和芝加哥报纸上的招聘广告投去虚假简历,一些简历的名字听起来像非洲裔美国人,另一些简历的名字听起来像白人。

最终,招聘人员压倒性地青睐名字听起来像白人的申请者。

在某种程度上,算法是我们嵌入在代码中的观点。当存在人类的偏见和偏见时,算法就会变得有偏见,导致机器学习错误和误解。如果你在上面的实验中围绕招聘人员的决定创建一个算法,该算法将学习到一个“好”的招聘有一个听起来很白的名字——算法只和它的数据一样好,有偏见的数据导致有偏见的招聘决定。

亚马逊是受害者,也是罪魁祸首。

亚马逊依靠 2014 年创建的内部“秘密”招聘算法,根据候选人相对于公司最佳表现者的特质来评估候选人。三年后,当他们发现压倒性地偏向男性时,该计划被取消了:公司的顶级员工中男性比例过高(这可能是固有的性别偏见的结果)。

这让招聘界感到疑惑:招聘算法真的值得吗?是的,它可能是一个,但前提是企业知道它的内在缺陷以及如何减轻这些缺陷。

永远不要完全相信算法推荐

公司经常陷入依赖算法来做出艰难筛选决定的陷阱。然而,很明显,算法在代码中部分是人类的决定,这意味着在这个过程中会有人类的偏见。当像亚马逊这样的公司创建这样一个算法时,他们对女性的偏见侵犯了法律和道德。

本质上,算法不是中立的。康奈尔大学最*的一项研究显示,招聘算法太不透明,难以判断它们是否公*。

厂商说的公*公正是什么意思?判断候选人是否符合道德标准的标准是什么?他们是否在努力确保它是真正客观的,而不是听之任之?

因此,招聘算法仍然不是公司在人才大战中希望的灵丹妙药。公司需要警惕过度信任这些算法:如果我们依赖它们并一直做出有偏见的决定,我们将来只会做出更有偏见的决定。这一次,他们只会变得更快。

人类必须永远在方向盘后面

特斯拉的自动驾驶功能意味着汽车可以在其车道内自动转向、加速和刹车。它还可以导航和变道。最*的发展也使它能够在复杂、狭窄的道路上行驶。

然而,这并不是完全的自主。

特斯拉明确表示:“当前的自动驾驶功能需要主动的驾驶员监督,并且不能使车辆自动驾驶”。

就像特斯拉的自动驾驶功能一样,招聘算法也是一样的。我们距离完全自动驾驶汽车还有几十年的时间,这同样适用于雇佣算法。好的算法是存在的,但成功不是偶然发生的。公司不应该在早期过度依赖算法,而应该审计和修改算法,以防止不公*现象继续存在。

因此,应该严格审查招聘建议。招聘经理必须将此类算法视为辅助手段,而非万灵药。

用人工审查审计其公正性

对于公司来说,加快招聘时间和简化流程的好处通常会超过无意歧视的风险

为了应对这种情况并预测潜在的算法歧视,公司可以进行人工审查。例如,他们可以对机器学习的相关性进行人工审查,并有选择地消除任何可能出现偏差的相关性。

公司还可以定期对机器简历决策进行随机抽查:让算法接受广泛的人工审查,以了解算法选择了谁以及为什么选择。目的是发现偏见的潜在原因。

用人工智能审计其公*性

这听起来很讽刺,但算法也可以帮助识别算法中的偏差。

在宾夕法尼亚州立大学和哥伦比亚大学,研究人员开发了一种人工智能工具来检测基于属性的歧视。人力资源科技初创公司 Pymetrics 开源审计人工智能(Audit AI),这种算法还可以确定算法中是否存在系统偏差(尽管它涵盖了更广泛的算法类型)。

公司还可以使用多种算法来帮助限制盲点。通过这种方式,公司可以简单地根据单一指标(算法经常使用,因为它最终只有一个分数)排除合格的候选人。

数据需要有上下文

并非每个算法都是*等的。为了创建一个好的算法,数据科学家必须了解就业环境中的变量。

例如,通勤距离经常被认为是决定工作表现的一个因素。数据显示,这会对工作表现产生负面影响,增加旷工率。然而,通勤距离是由我们的居住地决定的——而居住地是由房价、收入水*甚至种族决定的。在地表层面考虑通勤距离的算法可能对少数民族等受保护群体有偏见。

没有背景,数据将不足以预测一个人在工作中的潜力。为了规避这一点,招聘算法通常会收集更多数据。然而,这可能不会像预期的那样工作:过去的表现可能是潜在的公司特定的,这违背了获得更多数据的目的。

公*会变成一场斗争

去年 12 月发表的一项 T4 VU 大学的研究表明,虽然人工智能不一定会提高或降低道德价值观,但它可以首先塑造我们认为是道德的东西。

在研究中,研究了一个跨国公司使用的人工智能招聘工具。该工具用神经科学游戏和自动化视频分析取代了标准化的在线测试。在 7 个多月的时间里,该工具进行了试点和实施,旨在客观地衡量候选人的 120 多项技能和特质。然后,它向招聘经理推荐候选人,招聘经理会带他们进行面对面的面试,随后进行小组面试。

最终,表现比预期差的候选人试图通过在神经科学游戏中作弊来欺骗系统。

团队经理也对招聘算法持怀疑态度,称他们可能会招聘更多同质员工。他们想要的一些雇员也没有通过人工智能评估,但却通过了人工评估。

人工智能团队也遇到了算法是否可行的阻力。例如,那些在人工智能评估中得分高的人在随后的人类评估中失败了。人力资源经理认为人工智能评估可能会失败——人工智能团队随后认为人类评估员有偏见,因此是不正确的。

算法的力量和做出数据驱动的决策是当今公司必须利用的东西。与麦肯锡的预测一样,人才大战已经爆发——更年轻的劳动力和思维模式的转变加剧了这场战争。为了更快地筛选,更快地招聘,仍然能提高候选人的质量,招聘经理最终会转向人力资源技术供应商或在内部开发算法(如果他们有时间和资源的话)。

因此,公司在使用算法做出招聘决定时,需要考虑几个因素:

  • 对于什么是公*,在全公司范围内达成共识。阿姆斯特丹自由大学的研究显示,候选人、招聘经理、团队领导和人工智能团队都对什么是公*有不同的看法。没有人愿意承认他们错了,他们很快就指责谁对糟糕的决策负有责任。
  • 把算法当作指南,而不是药丸。算法不是天生中立的。将我们人类的观点编码意味着它本质上是一个数字人,只有一条思路:这个候选人与我的标准有多匹配?如果我们过度依赖算法,我们就有做出错误决策的风险。
  • 算法会导致同质化。假设你的算法确定具有属性 A 和 B 的候选人是很好的雇员。你决定雇佣这样的候选人,这反馈给算法,强化了他们的选择框架。随着时间的推移,你将会雇佣拥有 A 和 B 两种属性的候选人,这意味着公司将会缺乏多样性——不仅仅是种族和性别,还有思想和领导力。
  • 投资审计团队和算法。采用多管齐下的策略。通过使用技术和人工评论来系统地改进算法。从长远来看,投入更多的时间可能会提高招聘的质量。
  • 相信自己的判断,质疑一切。不要太全心全意地听人力资源技术供应商的话。尽管他们有一套“成熟”的算法,但你仍然必须在你的团队和公司的背景下思考。质疑算法的训练语料库,并提出正确的问题:他们是在积极地对抗算法中的偏见,还是只是简单地将数据堆积在数据上?

招聘算法最终会被训练成根除人类偏见吗?答案是肯定的,但现在下结论还为时过早。也许有一天,招聘工具会公*公正地雇佣员工,但不幸的是,细节出了问题。或许随着时间的推移,我们可能会看到有一天,一家公司专注于细节,用机器学习解决招聘中的偏见,就像每个人力资源专业人员渴望做的那样。

想要更多这样的文章吗?我是 人+商业 的创始人,一家专注于领导力和人性化的媒体刊物。点击此处阅读更多内容,了解我们如何改变管理员工的方式。

不要在 SQL 上犯这 5 个错误

原文:https://towardsdatascience.com/dont-repeat-these-5-mistakes-with-sql-9f61d6f5324f?source=collection_archive---------12-----------------------

使用 SQL 进行数据分析非常简单……但事实并非如此!

Unsplash 上的 krakenimages 拍摄的照片

SQL 和机器学习有一些共同点。从一个开始很容易,因为它不需要很多编码。此外,代码很少崩溃。

我关于 SQL 和机器学习的推文。

我认为 SQL 查询不会崩溃的事实使得数据分析更加困难。我从数据库中提取了多少数据集,结果发现有错误或丢失的数据?很多!

如果代码只是崩溃,我知道我搞砸了。数据科学家需要在数据验证上花费相当多的时间,因为 SQL 查询总是会返回一些东西。

这是你在编写 SQL 查询时应该避免的 5 个错误。

这里有几个你可能会感兴趣的链接:

- [Complete your Python analyses 10x faster with Mito](https://trymito.io/) [Product]- [Free skill tests for Data Scientists & ML Engineers](https://aigents.co/skills) [Test]- [All New Self-Driving Car Engineer Nanodegree](https://imp.i115008.net/c/2402645/1116216/11298)[Course]

您愿意阅读更多这样的文章吗?如果是这样,你可以点击上面的任何链接来支持我。其中一些是附属链接,但你不需要购买任何东西。

1.不知道查询执行的顺序

SQL 查询执行顺序

SQL 进入门槛低。您开始编写查询——到处使用连接,进行一些分组,您已经是专家了(至少有些人是这样认为的)。

但是所谓的专家甚至不知道 SQL 查询以什么顺序执行吗?

SQL 查询不是以 SELECT 开头的——当我们编写它们时,它们在编辑器中,但是数据库不是以 SELECT 开头的。

数据库开始使用 FROM 和 JOIN 执行查询。这就是为什么我们可以在 WHERE 中使用连接表中的字段。

为什么在 WHERE 中不能过滤 GROUP BY 的结果?因为 GROUP BY 在 WHERE 之后执行。因此我们有理由。

最后,我们来选择。它选择要包含的列,并定义要计算的聚合。此外,窗口函数在这里执行。

这就解释了为什么我们在 WHERE 中尝试使用窗口函数的输出进行过滤时会出现错误。

注意,数据库使用查询优化器来优化查询的执行。优化器可能会更改某些操作的顺序,以便查询运行得更快。此图是幕后发生的事情的高级概述。

2。窗口函数实际上是做什么的?

使用求和窗口函数的变换示例

当我第一次遇到窗口函数时,我觉得它们很神秘。为什么使用窗口函数作为分组依据可以聚集数据?

在设计查询时,窗口函数(WF)简化了许多操作:

  • WF 允许访问当前记录之前和之后的记录。请参见超前和滞后函数。
  • WF 可以使用 GROUP BY 对已经聚合的数据执行额外的聚合。请看上图中的例子,我用 WF 计算销售额。
  • ROW_NUMBER WF 枚举行。我们还可以用它来删除重复的记录。或者随机抽取样本。
  • 顾名思义,WF 可以计算给定窗口的统计数据:
sum(sales) OVER (PARTITION BY CustomerID BY ts ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as cumulative_sum

上面的 WF 将计算从第一条记录到当前记录的累积和。

我在哪里做错了窗口函数?

我没有花时间去读一个教程来解释窗口函数的基础和功能。因此,我避免使用它们,查询变得过于复杂。然后虫子爬进来。

运行上面的例子

运行 SQL 中的例子[瞎搞](http://SQL Fiddle)

我收到了许多读者的请求,他们想玩上面的例子。现在,您可以在 SQL Fiddle 中在线运行该示例。

如果您想在本地数据库中尝试一下,下面是代码(它应该可以与 PostgreSQL 9.3 一起使用):

DROP TABLE IF EXISTS sales_table;
CREATE TEMPORARY TABLE sales_table
(
    key       varchar(6),
    customerID  varchar(10),
    productID   varchar(10),
    price     float
);INSERT INTO sales_table
VALUES ('1', 'Customer1', 'Product1', 100),
       ('2', 'Customer1', 'Product1', 200),
       ('3', 'Customer1', 'Product2', 100),
       ('4', 'Customer2', 'Product2', 200),
       ('5', 'Customer2', 'Product3', 100);SELECT customerID,
       productID,
       SUM(price) AS sales,
       SUM(SUM(price)) OVER (PARTITION BY customerID) AS sales_all
FROM sales_table
GROUP BY customerID, productID
ORDER BY customerID, productID

3.在下列情况下计算*均值

CASE WHEN 类似于编程语言中的 IF 语句。当我们需要计算某个数据子集的统计数据时,这很有用。

在上图中,我计算了在美国销售的产品的*均价格。我不小心碰到了其他的东西。

在第一个例子中,我对所有非美国产品使用 0,这降低了整体*均价格。如果有许多非美国产品,*均价格可能会接* 0。

SELECT product, AVG(CASE WHEN country = 'US' then price else 0 end) AS avg_price
FROM sales
GROUP BY product

在第二个例子中,我只计算在美国销售的产品的*均价格,这通常是我们想要的。
注意,使用 CASE WHEN 时不需要包含 ELSE,因为它默认为 NULL。

SELECT product, AVG(CASE WHEN country = 'US' then price else null end) AS avg_price
FROM sales
GROUP BY product

关键的要点是,在使用 CASE WHEN 时,应该小心使用“else 0”。它对 SUM 没有任何影响,但对 AVG 有巨大的影响。

4.对缺少值的列进行联接

两个字符串字段的简单内部连接

SQL 中有 4 种不同的连接:内连接、外连接、左连接和右连接。当我们在查询中使用 JOIN 时,它默认为内部连接。

幸运的是,我花时间阅读了一些关于连接的教程。但我还是犯了一个菜鸟的错误。

我编写了一个类似于上图中查询的核心查询。当我执行数据验证时,许多记录丢失了。这怎么可能呢?这是一个如此简单的连接!

结果是,表 1 和表 2 中的许多条目的 string_field 列为空值。我以为 JOIN 会保留空值的记录,因为 NULL 等于 NULL,不是吗?

然后我试着:

SELECT NULL = NULL

它返回 NULL。

获取所有条目的解决方案是在 COALESCE 中包装 string_field,将 NULL 转换为空字符串。

SELECT t1.*, 
       t2.price
FROM table1 AS t1
JOIN table2 AS t2
ON COALESCE(t1.string_field, '') = COALESCE(t2.string_field, '')

但是要小心,因为这会将表 1 中带有空字符串的每个条目与表 2 中带有空字符串的每个条目连接起来。

消除这些重复的一种方法是使用 ROW_NUMBER()窗口函数:

  • 我假设每行都有一个惟一的标识符“some_id”和一个时间戳字段。
  • 只需包装查询,并获取每个唯一标识符的第一行以删除重复项。
SELECT *
FROM (
SELECT t1.*, 
       t2.price,
       ROW_NUMBER() OVER(PARTITION by some_id ORDER BY timestamp_field) as row_count
FROM table1 AS t1
JOIN table2 AS t2
ON COALESCE(t1.string_field, '') = COALESCE(t2.string_field, '')
)
WHERE row_count = 1

5.复杂查询不使用临时表

在临时表中包装查询

如果我们能调试查询,SQL 就太好了。如果我告诉你可以调试它们呢!

您可以分解一个复杂的查询并创建多个临时表。然后,您可以对这些表运行“健全性检查”查询,以确保它们包含正确的条目。在设计新的重要查询或报告时,我强烈推荐这种方法。

DROP TABLE IF EXISTS trainset;
CREATE TEMPORARY TABLE trainset AS (
  SELECT *
  FROM table_1
  WHERE field = 1
);

临时表的唯一缺点是数据库中的查询优化器不能优化查询。

当需要性能时,我将使用临时表定义的查询重写为使用 with 语句定义的查询。

WITH helper_table1 AS (
  SELECT *
  FROM table_1
  WHERE field = 1
),helper_table2 AS (
  SELECT *
  FROM table_2
  WHERE field = 1
),helper_table3 AS (
  SELECT *
  FROM helper_table1 as ht1
  JOIN helper_table2 as ht2
  ON ht1.field = ht2.field
)SELECT * FROM helper_table3;

在你走之前

推特上关注我,在那里我定期发关于数据科学和机器学习的推特

照片由Courtney hedgeUnsplash 上拍摄

不要给死人寄钱

原文:https://towardsdatascience.com/dont-send-money-to-dead-people-7653bed80892?source=collection_archive---------55-----------------------

以及数据行业的其他经验。

图片由 Unsplash 上的 Precondo CA 提供

【2020 年 6 月,有报道称 糟糕的数据 阻碍了美国政府推出其新冠肺炎经济复苏计划的能力。除了其他令人痛心疾首的错误,这次 数据宕机 事件发过来14 亿美元在新冠肺炎刺激支票要死人了。

数据宕机——数据不完整、错误、丢失或不准确的时间段——不仅仅是联邦政府的问题。几乎每个组织都在与之斗争。

在这个由两部分组成的系列文章的第一部分中,我提出了一个解决数据宕机的方法:数据可靠性,这是一个从 站点可靠性工程(SRE) 借用来的概念,已经被业内一些最好的数据团队所采用。

我们如何解决数据宕机问题?

前几天,我在一家受欢迎的上市科技公司采访了一位我非常看重的数据副总裁,他告诉我数据宕机对他的公司的影响,从财务报告和监管报告到营销分析,甚至是客户参与度指标。

他厌倦了用传统的数据质量方法来解决数据问题。

“数据质量检查只能到此为止,”他说(是的,同意匿名引用)。“我想要一种能让我在任何人(包括我的老板)知道之前就知道数据宕机的东西。说真的,让我这么说吧:我认为这是‘让我们的首席财务官远离监狱’的首要任务。

他不是一个人。在过去的几年里,我与数百名数据领导者谈论过他们的数据停机问题,从几个空值到完全不准确的数据集。他们的个人问题包罗万象,从浪费时间(一个显而易见的问题)到浪费金钱,甚至是重大的合规风险

为了解决数据停机问题,我提出了一种方法,它利用了我们的朋友,即“坏软件”的鼓吹者的一些最佳实践: 站点可靠性工程师

SRE 的崛起

自 21 世纪初以来,谷歌(该术语的来源)和其他公司的站点可靠性工程 (SRE)团队不仅在修复中断方面至关重要,而且通过构建可扩展和高度可用的系统从一开始就防止了中断。然而,随着软件系统变得越来越复杂,工程师们开发了新的自动化方法来扩展和操作他们的技术堆栈,以*衡他们对可靠性和创新的双重需求。

站点可靠性工程师(sre)通常被描述为勇敢的消防员,他们在晚上的所有时间都被呼叫来解决隐藏的错误、滞后的应用程序和系统中断。除此之外,SRE 团队通过自动化解决方案帮助自动化流程,从而促进无缝软件部署、配置管理、监控和度量,首先消除辛劳并最大限度地减少应用停机时间

在软件工程中,每个团队都有类似于 New RelicDataDogpage duty的 SRE 解决方案来衡量应用程序的健康状况并确保可靠性。数据团队怎么会盲目飞行?

数据团队的可靠性

在现场可靠性工程中,“希望不是策略”这句话很流行。它告诉 SRE 精神,系统不会自己运行,每一个软件的背后都有一个工程师,他可以尽自己最大的能力确保某种程度的可靠性。

希望不会使你的公司免于因错误的数字而做出决策。数据可靠性会。

正如 SRE 团队最先知道应用程序崩溃或性能问题一样,数据工程和运营团队也应该最先知道坏管道和数据停机问题。仅在六年前,数据停机每年给公司造成的损失累计达 1.7 万亿美元;在一个数据无处不在的时代,数据管理工具还没有跟上时代的步伐,这些数字可能会变得更糟。

然而,为了使数据完全可用、可信和自助,数据团队必须专注于通过实现完全可靠性来减少数据停机时间

毫无疑问,这种新方法是行业的游戏规则改变者,我很高兴看到公司加入数据可靠性运动。毕竟:当你可以信任你的数据时,谁还需要希望?

如果你想了解更多, 伸出手 给巴尔摩西。

不要停留在集合上——针对表格数据的非常规深度学习技术

原文:https://towardsdatascience.com/dont-stop-at-ensembles-unconventional-deep-learning-techniques-for-tabular-data-8d4e154f1053?source=collection_archive---------22-----------------------

使用深度学习学习表格数据的降维、去噪和合成数据生成

Unsplash 上的 chuttersnap 拍摄

*年来,深度学习在计算机视觉和自然语言处理领域取得了巨大进展。因此,深度学习技术通常局限于图像数据或序列(文本)数据。表格数据呢?对于业务用例来说,许多组织中传统的信息存储和检索方法无疑是最重要的。但我们表格/数据框架中的数据似乎满足于在深度学习领域使用简单的多层前馈网络。虽然有人认为递归神经网络(RNNs)通常用于表格时间序列数据,但这些方法在没有时间序列成分的数据上的应用非常有限。在这篇博客文章中,我们将看看一些深度学习技术的应用,通常用于图像或文本数据,在非时间序列表格数据上,在传统的递减水*上。

用于降维的自动编码器

传统上,自动编码器已经被用于非线性维度减少。假设我们有一个数据集,其中的要素数量远远超过我们的期望,我们可以使用自动编码器通过复杂的非线性函数将要素集调整到所需的要素大小,我们不必担心!与线性降维方法如 PCA(主成分分析)或其他传统的非线性技术如 LLE(局部线性嵌入)相比,这是一种更有效的技术。

自动编码器结构(来源)

自动编码器在没有任何标签的训练特征集上被训练,即,无论输入是什么,它们都试图预测输出。如果隐藏层足够宽,可以捕获所有的输入数据,这将是一个简单的任务。因此,对于作为自动编码器的神经网络的要求是,至少有一层,即瓶颈层,具有比输入或输出维度更低的维度。这通常是我们想要使用的嵌入层或缩减的特性集。训练网络时的度量可以是通常的均方误差或*均绝对误差。如果原始数据是 x 并且自动编码器生成的重构输出是 x_hat,我们试图最小化

L(x,x_hat) = |x — x_hat|

在一起训练网络的编码器和解码器部分之后,我们仅使用模型的编码器部分作为我们的维度减少/特征提取算法。Keras 中的示例代码如下:

from keras.layers import Dense, Dropout
from keras.models import Sequential, Model
from keras import metrics, InputMETRICS = [
    metrics.RootMeanSquaredError(name='rms'),
    metrics.MeanAbsoluteError(name='mae')
]ENCODING_DIM = 16 #Desired Dimension
BATCH_SIZE = 64
EPOCHS = 100def make_and_train_autoencoder(X_train, metrics=METRICS):

    len_input_output = X_train.shape[-1]
    input_ = Input(shape=(len_input_output,))
    encoded = Dense(units=ENCODING_DIM*2, activation="relu")(input_)
    bottleneck = Dense(units=ENCODING_DIM, 
                       activation="relu")(encoded)
    decoded = Dense(units=ENCODING_DIM*2, 
                    activation="relu")(bottleneck)
    output = Dense(units=len_input_output, 
                    activation="linear")(decoded)
    #Training is performed on the entire autoencoder
    autoencoder = Model(inputs=input_, outputs=output)
    autoencoder.compile(optimizer='adam', loss='mean_squared_error',
                        metrics=[metrics])
    autoencoder.fit(X_train, X_train,
                    batch_size=BATCH_SIZE,
                    epochs=EPOCHS)
    #Use only the encoder part for dimensionality reduction
    encoder = Model(inputs=input_, outputs=bottleneck)
    return autoencoder, encoder

用于降噪的去噪自动编码器

MNIST 上的去噪自动编码器示例(来源

去噪自动编码器的灵感来自计算机视觉领域。如上所述,它们可用于消除输入数据中的噪声。去噪自动编码器(DAE)可以类似地用于表格数据,因为大多数数据收集过程固有地具有一些噪声。这项技术已被证明是许多 Kaggle 比赛获胜解决方案的关键( Porto Seguro 的安全驾驶员预测)。与自动编码器不同,DAE 不需要满足将编码和解码部分连接到网络的要求。换句话说,不存在瓶颈,也就是说,它只是一个被训练用来消除噪声的神经网络。那么问题来了,我们如何训练网络?

去噪自动编码器的工作(来源

如上图所示,我们首先破坏输入数据 x 。被破坏的数据𝑥̃通常是通过添加高斯噪声或者通过将一些输入特征值设置为零而获得的。这是我们试图模仿数据集中噪音的方式。然后,我们让𝑥̃通过我们设计的 DAE,以获得重构的输出 x_hat ,其尺寸与输入 x 相同。损失函数类似于常见的自动编码器。DAE 试图最小化输出 x_hat 和原始数据 x,之间的差异,从而使其能够消除噪声的影响并从损坏的数据中提取特征。示例代码如下:

#Change mean and scale of the noise according to your data
noise = np.random.normal(loc=0, scale=0.5, size=X_train.shape)
X_train_noisy = X_train + noiselen_input_output = X_train.shape[-1]def make_dae(metrics=METRICS):
    dae = Sequential([
        Dense(units=len_input_output*2, 
              activation="relu", input_shape=(len_input_output,)),
        Dropout(0.5), #Add dropout layers if required 
        Dense(units=len_input_output*2, activation="relu"),
        Dense(units=len_input_output*2, activation="relu"),
        Dense(units=len_input_output, activation="linear"),
    ])
    dae.compile(
        optimizer='adam', 
        loss='mean_squared_error',
        metrics=[metrics]
    )
    return daedae = make_dae()
history = dae.fit(
    X_train_noisy,
    X_train,
    batch_size = BATCH_SIZE,
    epochs = EPOCHS
    )

我们通常只在训练集上训练去噪自动编码器。一旦模型被训练,我们可以通过 DAE 传递原始数据 x 和测试集,比如说 x` ,以获得数据集的去噪版本。

使用语言模型的合成数据生成

我们很多人可能都遇到过著名的字符级语言模型,用于生成类似莎士比亚的文本。如果我们在训练数据(CSV/txt 格式)上训练一个语言模型会怎么样?首要问题是,我们为什么要这么做?简单的答案是——数据不*衡。大多数真实数据集在每个类/标签的训练样本数量上有很大差异。以欺诈检测为例。只有大约 0.05%的交易是欺诈性的。因此,我们可能希望生成更多的少数类训练示例来解决不*衡问题。

通过在我们的少数民族类数据(仅特征值)上训练字符级语言模型,我们可以生成类似于少数民族类的记录,就像我们通过在一组诗歌上训练模型来生成文本一样。我不会深入研究角色级语言模型的训练和采样细节,但我鼓励你浏览一下安德烈·卡帕西的博客(或者 Coursera 上的 T2 序列模型课程的第一周)。

谢天谢地,有像 gretel-synthetics 这样的库为我们做上述工作!Gretel 的图书馆也有其他选择,如在生成的合成数据集中启用差分隐私。他们的博客文章是了解和学习他们图书馆的好方法。以下示例代码可用于生成合成数据帧:

!pip install gretel-synthetics --upgradefrom pathlib import Path
from gretel_synthetics.batch import DataFrameBatch
import pandas as pdsource_df = pd.read_csv("diabetic_data.csv") #File Pathconfig_template = {
    "max_lines": 20000,     # maximum lines of training data. Set to ``0`` to train on entire dataframe
    "max_line_len": 2048,   # the max line length for input training data
    "epochs": 15,           # Gretel recommends 15-50 epochs with GPU for best performance
    "vocab_size": 20000,    # tokenizer model vocabulary size
    "gen_lines": 100,       # the number of generated text lines
    "dp": True,             # train with differential privacy enabled (privacy assurances, but reduced accuracy)
    "field_delimiter": ",", # Must be specified
    "overwrite": True,
    "checkpoint_dir": str(Path.cwd() / "checkpoints")
}batcher = DataFrameBatch(df=source_df, config=config_template)
batcher.create_training_data()
batcher.train_all_batches()
status = batcher.generate_all_batch_lines()
synthetic_df = batcher.batches_to_df()
synthetic_df.head(10)

上面讨论的所有深度学习技术都属于自我监督或无监督学习的范畴。在为我们的分类或回归任务训练实际模型之前,这些通常被用作预处理步骤。这些步骤的有效性将取决于您手头的数据和参数,如您希望对语言模型进行多长时间的训练,或者您希望在您的特征集中进行多大程度的压缩。

恭喜你坚持到了文章的最后!希望这篇文章能够为您提供处理表格数据的创新方法。所以,下次你认为 XGBoost 或 LightGBM 就是表格数据的全部时,请三思!

请继续关注类似的另一篇帖子,在那里我将讨论像生成对抗网络(GANs)潜在狄利克雷分配(LDA) 这样的算法在表格数据上的应用。和我一起让表格数据再次变得伟大!

欢迎对帖子发表评论或在 LinkedIn 上与我联系。期待大家的反馈和建议。

参考文献:

[1] F. Chollet,Keras 博客,【https://blog.keras.io/building-autoencoders-in-keras.html

[2] A .沃森,j .迈尔斯,a .斯泰尔,格雷特尔.艾在培养基上,https://medium.com/gretel-ai

[3] M. Jahrer,Kaggle,https://www . ka ggle . com/c/Porto-seguro-safe-driver-prediction/discussion/44629

不要相信数据科学家会设定性能指标

原文:https://towardsdatascience.com/dont-trust-data-scientists-to-set-performance-metrics-908bcd80bac6?source=collection_archive---------44-----------------------

如何将机器学习产品与业务结合起来

图片由 Free-Photos 来自 Pixabay

选择正确指标的重要性

你是一家销售自行车和自行车配件的电子商务初创企业的创始人。你的网站现在对所有用户都是一样的,但是你想引入个性化功能,在页面顶部显示最相关的 3 个产品。

你走向数据科学团队的办公桌,向他们解释问题。“我应该如何决定展示哪些产品?”,他们问。“那些与用户更相关的”,你解释道。“在什么意义上相关?”“嗯,用户更有可能点击的网站”,你回答,因为这对你来说似乎很简单。

但是在新功能上线几周后,你的报告显示它产生了很多额外的点击,但是销量很少。显然,许多“点击诱饵”产品已经得到推广!它们可能是一个别致的自行车头盔,广告上打着大折扣,但是已经脱销了。这可不好。

来自 Pixabay鲁迪和彼得·斯皮特兰

所以你向你的数据科学团队抱怨,要求他们改变相关性的概念。“当然,推广不转化的产品是没有意义的。我们只需要用户最终会购买的产品!”你解释。

图片由 Evanscycles 提供

很好,所以你的数据科学家回去工作,这一次他们的算法最大限度地增加了售出商品的数量。但是你会发现很多 3.99 美元的踏板就像这些被卖掉了!

你现在清楚地知道总收入需要最大化,因为出售大量廉价商品不会对你的底线有太大帮助。但是,等等,你想最大化的是物品的总价还是你的毛利?如果一般是毛利,但你仍然想销售某些低利润的产品,因为它们往往会带来高价值和更忠诚的客户,那该怎么办?

底线是,机器学习产品和你给它的目标一样好,这是一个商业驱动的决定,通常不是直截了当的。

但是你能控制的杠杆是什么呢?

在三维空间工作

每一款 ML 产品都需要决定三个关键因素:

  1. 设置适当的绩效指标来衡量成功
  2. 当建立模型时,为模型选择合适的优化(损失)函数
  3. 当模型被部署到生产中时,着眼于产品如何帮助业务整体的更大图景

我们一个一个来看。

设定绩效指标,即定义成功

机器学习模型的性能度量可以表示业务变量,但不一定如此。当模型缺乏可解释性时,业务焦点特别有用,这可以通过更加用户友好的性能度量来弥补。

为预测模型设置指标和目标时,要考虑的一个关键方面是为业务犯错误的成本。让我们以分类引擎为例来看看这一点。

犯错的代价

一个在线酒店预订*台希望预测可能会取消预订的客户。

机器学习模型工作流程如下图所示,将每个客户标记为“可能取消”或“不太可能取消”。

数据科学团队推出了一个准确率为 90%的模型,即 90%的客户预测正确。你应该祝贺你的数据科学团队吗?

让我们更详细地看看结果。有 1000 个客户,其中 900 个预测正确。

但是当我们更仔细地观察时,我们意识到并非所有的错误都是生来*等的。犯了一个错误,一个客户预计会取消,但最终没有取消,与一个客户预计不会取消,但最终传播,这是有区别的。

我们特别想问两个问题:

  1. 当模型显示预订将会取消时,我能有多自信?这被定义为精度
  2. 被取消的预订中有多大比例被正确识别?这叫做灵敏度回忆

在这种情况下,当模型预测客户将取消时,只有 25%的可能性是正确的。而在最终会取消的客户中,它只抓住了其中的 5%!很难说是一个好的分类器,尽管它有 90%的准确率。还要考虑一个虚拟分类器,简单地对所有客户预测“否”,在这种情况下准确率为 91 %( 895+15 的正确预测/1000)。这是一个典型的不*衡类问题,众所周知,例如那些设计医学测试以识别罕见疾病的人。

那么,最好的度量标准是什么呢?

  • 衡量预测模型的“正确”指标完全取决于您的业务流程和您想要实现的目标
  • 通常,您需要考虑至少两个指标,并在它们之间寻找合适的*衡。查看精确回忆曲线,找到正确的*衡

现在让我们来看一下这个模型的几个业务应用程序,它们具有不同的业务优先级,因此需要优化不同的指标。

超额预订用例的酒店取消预测

优化团队希望对那些取消可能性非常高的客户进行超额预订。他们犯错误的代价很大(客户将没有地方睡觉!)但是不一定需要标记大量的客户列表。我们应该为了什么而优化这个模型?

这个模型将被优化为精确的,所以会标记很少的预订,但对那些人来说,它会超级自信。

酒店客服提醒电话取消预测

现在,考虑一下客户服务部门使用的相同模型,为更有可能取消的客户安排提醒电话,以便尝试与他们接触,防止他们取消电话。

在这种情况下,打电话的成本可能相当低,而犯错的成本(例如,打电话给甚至没有考虑取消的人)也不会太高。因此,您可能希望标记更大份额的具有不同置信度的客户,最终您将得到一个精度较低但召回率/灵敏度较高的分类器。

选择正确的优化函数

在这个阶段,您可能已经选择了一组理想的性能指标来事后测量您的机器学习模型,但您可能也希望模型在构建时就针对这些指标进行优化。

这是通过所谓的损失函数实现的,即模型在训练时(即在从过去的数据中学习时)试图最小化的误差函数,也可以被视为优化函数的逆函数。

这一步跨越了相当多的技术和数学方面的考虑,尽管许多预先构建的算法对于某些默认函数来说效果最好。例如,如果你正在运行一个线性回归,你很少想要偏离最小二乘作为损失函数。

但情况并非总是如此,在某些情况下,这也可能成为商业决策。

例如,如果您试图对彼此相似的商店进行聚类,您需要考虑“类别”维度(商店的类型)和地理成分(其位置)。

聚类模型将尝试基于距离 标准来定义聚类,但是没有一种单一的方法来定义这样的距离:例如,根据您的业务用例,您可能希望使用更广泛的类别定义(例如,所有的食品商店在一起)与更广泛的聚类地理区域(例如,城市中的所有商店,而不是邻居)。

可能出现的一个问题是:

为什么我们需要根据性能指标单独定义一个损失函数,而不是简单地使用同一个函数?

这有两个原因:

  1. 一个模型只能有一个损失函数,而你可以有几个性能指标。例如,正如我们所看到的,您可能希望衡量算法对毛利润和收入的影响,但算法无法同时最大化这两者
  2. 模型是用代码实现的,并且需要考虑操作效率。当模型需要按比例运行时尤其如此。例如,在预测房价时,您可能希望最后通过百分比误差中值来评估您的算法。但是在实践中对中值进行优化可能会很棘手,所以您可能会选择另一个度量作为损失函数。

不过,一般来说,损失函数应该与评估指标保持一致。在一天结束时,模型在训练时只能看到它的损失函数,但您将在结束时使用评估指标来评估它。如果两者开始背离,那就不好了。

纵观全局

衡量机器学习产品的性能只是故事的一部分,因为最终目标通常是改善整体业务。业务和产品目标的不同可能有多种原因,但这里有两个常见的例子,一个是负面的,一个是正面的:

  • 你的产品正在蚕食其他渠道的收入
  • 你的产品正在推动其他渠道的交叉销售

让我们考虑一个个性化时事通讯的例子。当用户点击时事通讯并购买产品时,你也许能够通过归因于额外的销售来准确地测量特定于产品的指标,例如增加的收入、转换率等。

但是,如果客户在时事通讯中看到一个产品,没有点击它,但后来又记得它并直接在网站上购买它,该怎么办呢?在大多数归因模型中,这将被视为“直接渠道”购买,因此不归因于时事通讯。

另一方面,你的时事通讯可能会推动其他渠道可能已经发生的销售。

尝试衡量这些更广泛的影响的一种方法是根据客户整体来衡量提升性能,而不考虑渠道。在本例中,如果您要比较简讯中的治疗顾客和对照顾客,您需要衡量他们在整个*台上的活动(例如,他们当天是否在所有渠道购买了产品)

然而,这说起来容易做起来难,主要有两个原因:

  • 从技术角度来看,全球属性可能需要更深层次的数据集成,而这在公司内部不一定能实现
  • 更微妙的是,其他内部产品可能会运行类似的实验,以不同的方式对待相同的客户(例如,向相同的客户显示个性化的移动应用程序页面)

在任何情况下,即使不可能解释所有这些变量,重要的是至少从定性的角度记住它们,即使不可能量化它们。

关键要点

设置正确的性能指标可能是一项棘手的任务,需要成为一项业务决策。如果您来自业务部门,请让您的数据科学家参与进来,但请记住,最终这是您的决定,并且需要基于业务优先级。如果您是一名数据科学家,请确保您完全与业务保持一致,并在做出这些决定之前尝试设身处地地为他们着想。

关键要点总结:

  • 考虑价值链不同层次的度量:一个 CTR 可能更容易衡量,但通常缺乏端到端的关注
  • 一个单一的性能指标通常是不够的:您需要考虑多个指标,并经常评估它们之间的*衡和折衷
  • 在设置指标时,请始终牢记做出错误预测的代价。通常,同一个预测模型可以很容易地调整,使其在预测结果时或多或少地保守(就像我们的酒店取消模型)
  • 不管你看多少评价指标,记住一个机器学习模型只能对单一的优化(损失)函数起作用。您需要确保这与您的其他指标和目标保持一致
  • 始终从业务的角度看全局,即使这需要考虑不可量化的方面,如客户保留、跨渠道互动或长期参与。

不要小看这些 Python dunder 方法!

原文:https://towardsdatascience.com/dont-underestimate-these-python-dunder-methods-c7bc36a8c1c1?source=collection_archive---------46-----------------------

照片由瑞德·卫斯理Unsplash

有大量关于使用 Python 进行面向对象编程的文章、书籍和视频,其中许多都涉及到了 dunder (也称为 magic )方法。在本文的最后,我会提供一些我认为对自己有用的资源的链接。

不过,请原谅我。

我现在要表明我的观点:在我看到它们有多有用之前,下面列出的这些方法似乎与我毫不相干。

来源:https://docs.python.org/3/reference/datamodel.html

这些被称为 富比较 的方法。现在,事后看来,它们似乎有点多余,甚至毫无用处,因为 python 本身也提供了比较对象的函数。

事情是这样的,当你构建一个时,你可能希望它以某种特定的方式运行。现在,行为在许多方面不同于功能。

让我们看看它如何应用于数据科学的问题。

假设你正在为一个分类问题测试不同的监督学习 技术 。为简单起见,我假设您熟悉这些术语。

通常,您会有一组原始要素用作训练算法的输入变量。然而,重要的转换,比如填充缺失值、标准化变量等等,几乎肯定会发生。

就像在 scikit-learn 的管道 中一样,你可以为 逻辑回归构建不同的变形金刚。

请注意,即使这些步骤是相同的,并且具有相同的名称,也不可能说它们与 Python 中的常规比较是相等的。

>>> from sklearn.preprocessing import StandardScaler, MinMaxScaler
>>> from sklearn.impute import SimpleImputer
>>> from sklearn.pipeline import Pipeline
>>>
>>> mean_transformer_1 = Pipeline(steps=[
...     ('imputer', SimpleImputer(strategy='mean')),
...     ('scaler', StandardScaler())])
>>> 
>>> mean_transformer_2 = Pipeline(steps=[
...     ('imputer', SimpleImputer(strategy='mean')),
...     ('scaler', StandardScaler())])
>>> 
>>> mean_transformer_1==mean_transformer_2
False

这就对了。在应用不同的管道之前和之后比较模型可能相当麻烦。

比较它们的一种方法是比较每个步骤的类,看它们是否相同:

>>> class_1 = mean_transformer_1.steps[0][1].__class__
>>> class_2 = mean_transformer_2.steps[0][1].__class__
>>> class_1 == class_2
True

现在,除了难看和冗长,如果你有一个更大的管道,这可能是相当冗长的。老实说,这么小的管道在现实生活中很少投入生产。

警告:为了注意广度,我只保留了类别的比较。但是传递的参数比如'mean'如果真的要深究比较的话也要比较一下。

正如雷蒙德的名言所说:一定有更好的方法!确实有。

让我们制作一个类来比较这些:

>>> class SmartCompare:
...     def __init__(self, pipeline):
...         self.pipeline = pipeline
...
...     def __eq__(self, other):
...         return [m1.__class__ for m1 in self.pipeline]==[m2.__class__ for m2 in other.pipeline]
... 
>>> mean_transformer_1_c = SmartCompare(mean_transformer_1)
>>> mean_transformer_2_c = SmartCompare(mean_transformer_2)
>>> mean_transformer_1_c==mean_transformer_2_c
True

当然,这并没有好到哪里去,但是这说明了一个问题!

您也可以继承Pipeline类,而不是让它成为您的类的一个属性。或者甚至使用其他方法进行比较。

在任何情况下,dunder 方法都超越了常规的比较方法,使您的代码更具可读性和愉悦性。

感谢您的耐心!!!欢迎批评,请随意发表评论。

一些有用的资源:

[## 用 Dunder(神奇的,特殊的)方法丰富你的 Python 类——dbader.org

Python 的“神奇方法”是什么,以及如何使用它们使一个简单的 account 类更加 Python 化。在 Python 中…

dbader.org](https://dbader.org/blog/python-dunder-methods) [## 欢迎来到 Python,认识一下邓德尔一家

python 中几种 magic 方法的快速介绍

medium.com](https://medium.com/swlh/welcome-to-python-meet-the-dunders-41026b2a7e36)

不要浪费时间寻找学习数据科学的最佳方法

原文:https://towardsdatascience.com/dont-waste-your-time-looking-for-the-best-way-to-learn-data-science-31eeb5d63aea?source=collection_archive---------49-----------------------

一旦你开始,道路将会变得光明。

照片由思想目录Unsplash 上拍摄

数据科学列车正在以不断加速的速度前进,并通过增加新的车厢来增加其长度。企业希望搭上数据科学的列车,以跟上不断发展的技术并改善他们的运营。因此,在数据科学领域有大量的工作岗位。越来越多的人想搭上火车,开始在这个领域工作,因为:

  1. 这些工作既刺激又有趣
  2. 这些工作报酬很高
  3. 在可预见的未来,需求不会减少

这就像一个连锁反应。采用数据科学的企业创造就业机会,推动人们在这一领域工作。这些人需要接受教育,这促使其他一些人创造学习资源。在这篇文章中,我们将关注故事中的“学习资源”部分。

学习数据科学的资源多得令人应接不暇。造成这种情况的主要原因有两个:

  1. 数据科学是一个非常广阔的领域,是数学、统计学和编程的混合体。因此,要学的东西太多了。
  2. 与传统教育相比,人们倾向于更灵活、更快捷、更便宜的学习方式。因此,有各种教授数据科学的 MOOC 课程、youtube 视频、博客和训练营。

在这么多不同的*台上有这么多东西要学。这可能是优势,也可能是劣势,取决于我们如何处理。

当我开始学习数据科学时,我有一些问题让我失去了动力。我想在这里列出其中的一些问题:

  • 我应该学 Python 还是 R?(我之前没有任何编程经验)
  • 我需要一个硕士学位还是几个证书?
  • 我需要学多少统计学?
  • 我有工程学士学位,所以我有足够的数学知识,但是“我需要学多少数学”对于没有技术背景的人来说是一个重要的问题。
  • TensorFlow 还是 PyTorch?
  • 我应该学习自然语言处理(NLP)技术吗?
  • 时间序列分析怎么样?
  • 数据可视化要学什么?Matplotlib,Seaborn,Plotly 或其他什么?
  • NumPy 和熊猫够数据分析吗?

还有更多的问题。你可能会有类似的问题,并犹豫开始。我没有这些问题的答案。但是我的建议是不要再浪费时间去寻找答案了。

刚开始学!

与 Raj 在 Unsplash 上的公路旅行照片

一旦你开始并迈出第一步,你就会发现一些答案。你也会看到有些问题没有明确的答案。然而,这不应该停止你的学习过程。

另一个要记住的非常重要的事情是你不能什么都学。例如,NLP 本身就是一个完整的领域,需要深入的训练和实践。如果你想专攻 NLP,你可能会更关注 NLP 专用的工具和框架。

选择总是不止一个!

当你开始倾向于数据科学的特定子领域时,一些工具和框架变得突出,但我们通常有不止一个选择。例如,R 可能比 Python 更适合于统计分析。不过 Python 也有强大的第三方统计包,比如 statsmodels 。我不想引起更多的矛盾。我只想指出,学数据科学有很多选择。

我还想提一下不同类型的资源。拥有压倒性的资源其实是件好事。我们有选择不同选项的自由。youtube 上有几乎任何与数据科学相关主题的视频。ArXiv 包含大量关于数据科学的学术文章。许多*台提供数据科学证书,如 Coursera、Udemy 和 edX。当然,博客对于学习特定主题非常有效。例如,我们可以在媒体上找到几乎任何主题的文章。

我首先完成了一个证书,IBM 数据科学专业。从主题的组织和结构来看,这是非常有帮助的。它还提供了数据科学领域的概述。我建议从这样一个基本的、全面的资源开始。然后你就会很容易地建立起自己的学习路径。你不需要收集任何主题的证书。

最后但并非最不重要的,也许是最重要的,是做项目。它们让你为工作做好准备。项目将不同的技能整合为一种。它们也是展示你技能的橱窗。

基础学完了再做项目。

数据科学在不同行业有很多应用。企业的目标是从数据中创造价值。因此,学习分析数据的算法或工具不足以获得一份工作。你应该开始做与你想工作的领域相关的项目。做项目不仅会帮助你获得更全面的知识,还会给你带来更好的工具和框架。根据项目的不同,某些工具会优于其他工具,更适合您的风格。以下是我做项目的 5 个理由:

[## 你应该做项目而不是收集数据科学证书的 5 个理由

把手弄脏来学习。

towardsdatascience.com](/5-reasons-why-you-should-do-projects-instead-of-collecting-data-science-certificates-9023accda6b4)

综上所述,怎么学其实并不重要。如果你对学习数据科学充满热情,你遵循的道路并没有什么不同。任何适合你的学习方式都可以。最重要的是开始你的旅程,当然,在你完成基础知识之后做项目。

感谢您的阅读。如果您有任何反馈,请告诉我。

别担心,Excel 出奇的有效

原文:https://towardsdatascience.com/dont-worry-excel-is-surprisingly-effective-4670c11ebaff?source=collection_archive---------10-----------------------

作为一名数据科学家,为什么不应该羞于使用 Excel

米卡·鲍梅斯特在 Unsplash 上的照片

数据科学家看不起微软 Excel 是常有的事。与 Python 这样的编程语言相比,它看起来像是石器时代的工具。它不能很好地扩展,很难重现结果,而且一旦你开始编写 VBA 宏,你还不如使用 Python。

尽管如此,Excel 还是存活了下来。我甚至想不出有哪家企业不使用某种电子表格软件来帮助分析数据。正如乔·里斯所说:

Excel 也仍然是商业世界的中流砥柱。第三次世界大战后,蟑螂和 Excel 将继续存在。

幸存者

你可能想知道,为什么 Excel 能在大数据和 Spark、Snowflake 等性感工具的世界里生存下来?不起眼的电子表格怎么可能没有被完全打乱?

我相信这是因为 Excel 是查看和分析数据的最用户友好的方式之一。Excel 是一个所见即所得(WYSIWYG)类型的产品。进入 Excel 时,您会看到数据的表格视图,您可以开始编辑、添加公式以及创建数据透视表。当您进行这些更改时,您看到的内容会自动更新。这是难以置信的强大,它使 Excel 更加*易*人。

此外,Excel 使基本分析变得非常简单和直观。想取一列的*均值?就用*均公式吧。想要数据的散点图吗?只需突出显示您的数据,然后单击“散点图”。这种易用性是一个难以置信的好处。它允许公司利用非程序员来分析和可视化数据。在我看来,Excel 是帮助公司建立数据驱动文化的最佳工具之一。

来源

数据科学家该不该用 Excel?

以上几点我想大家都能认同。Excel 是一个有用的工具,可以帮助人们简单直观地进行基本的数据处理和分析。

但是——它应该成为数据科学家的工具吗?

或者——我们是不是太超前了?对 Excel 这样的软件来说太复杂了?所有问题应该通过 Python 还是 R 来运行?

我认为,每个数据科学家都应该对 Excel 有基本的熟悉,并觉得把它作为工具使用并不可耻。

我提到羞耻是因为我发现数据科学家很容易讨厌 Excel。它肯定不是解决所有问题的工具。甚至可能不是大多数数据科学问题。但这并不意味着它没有自己的位置。我发现 Excel 在以下情况下非常有用:

  • 我有少量的表格数据,我想对其进行一些快速计算。例如,也许你在一个电子表格中有几百个 YouTube 视频的视图。只需打开它并计算一些基本的统计数据,就会简单快捷得多。
  • 我需要与非数据科学家分享结果,同时让他们能够轻松地进行自己的分析。
  • 我想快速绘制一些干净的表格数据。

注意:在上述所有示例中,这些都是临时请求,不会重复出现。一旦你开始必须创建一个可重复的过程,我会转向编程语言,即使分析很简单。如果有必要,这样做将更容易复制和扩展您的分析过程。再现性和可伸缩性是 Excel 的两个主要缺点。

去学吧

希望这篇短文已经让您相信 Excel 在您的数据科学工具箱中有一席之地。如果您还没有使用过 Excel,我建议您在 Excel 中打开一个 CSV 文件并探索其功能。这很容易开始。

如果你想要一些入门帮助,微软有一些非常好的免费教程。

最后,还要记住 Excel 对于许多数据科学项目来说并不是一个好工具。如果您发现自己有更大的数据集、更高级的分析/机器学习需求,或者需要创建可重复的流程,请不要使用 Excel。回到你选择的编程语言。

如果你需要一个资源来帮助你开始使用 Python 进行分析和可视化,你可以看看我创建的课程来做这件事。

现在,去为你的数据科学工具箱添加另一个工具吧(如果你还没有的话)!

这篇文章也可以在这里找到。

使用 Python 实现数据科学线性代数中的点积

原文:https://towardsdatascience.com/dot-product-in-linear-algebra-for-data-science-using-python-f113fb60c8f?source=collection_archive---------23-----------------------

建立对矩阵如何帮助解决线性方程组以及回归问题的直觉

在这里你可以一步一步跟着我

在您很好地掌握了向量、矩阵和张量之后,是时候向您介绍线性代数的一个非常重要的基本概念了— 点积(矩阵乘法)以及它如何与求解线性方程组相关联。我说它很重要,因为它被广泛应用于几乎所有主要的机器学习和深度学习算法中。

这为学习数据科学的数学提供了一个很好的案例。

因此,在这篇文章中,我们将使用 NumPy 来涵盖以下概念及其代码:

  • 矩阵和向量的点积
  • 两个矩阵的点积
  • 矩阵乘法的性质
  • 线性方程组
  • 线性回归预测模型方程

让我们开始吧…

矩阵和向量的点积

与加法或减法不同,两个矩阵的乘积不是通过将一个矩阵的每个单元与另一个矩阵的相应单元相乘来计算的,而是我们计算一个矩阵的行与另一个矩阵的列的乘积之和,如下图所示:

矩阵和向量的点积

这种矩阵乘法也叫点积。

下面是该方法的形式化描述:

矩阵乘法数学形式化

重要规则:只有第一个矩阵的列数等于第二个矩阵的行数,才能将两个矩阵相乘。

如果一个矩阵的形状是(m×n),而另一个矩阵的形状应该是(n×t)(t ≥ 1),那么得到的乘积矩阵将具有如下所示的形状(m×t):

如果我将矩阵 A (3×2)与向量 B(2×1)相乘,下面是矩阵和向量之间的点积的更全面的符号形式:

生成的矩阵将是一个 3×1 向量,计算如下:

[数]矩阵

让我们看一个例子:

将第一个 3×2 矩阵乘以一个向量

按照上述规则计算的结果矩阵

代码:

让我们使用 Numpy 对它们进行编码:

Colab 笔记本截图,可以在这里查看:https://colab . research . Google . com/drive/1 jrqnk 5 pjlwbycvjf 2 jhjdu-dRvMXjXkD?usp =分享

首先,在您的工作区中导入 NumPy 包,然后创建一个上面例子中讨论过的 2D 矩阵或任何其他您想尝试的矩阵结构,然后创建一个向量,确保矩阵中的行数和列数相等。

然后可以使用 numpy 包中的dot()方法,将矩阵和向量传递给它。它将为您返回合成向量,如图所示。

您可以查看整个笔记本,并使用以下代码进行试验:

[## 谷歌联合实验室

colab.research.google.com](https://colab.research.google.com/drive/1jrQnk5pjLWbYCvjF2JHjDu-dRvMXjXkD?usp=sharing)

两个矩阵的点积。

然后,我们可以将 2 个矩阵相乘,下面是一个 4×3 矩阵 A 乘以 3×2 矩阵 B 的示例:

遵循如下所示的方法:

代码:

就像我们编写上一个示例一样,这里您将创建两个 2D 数组,然后使用数组的点方法,您可以计算点积:

Colab 笔记本截图,可以在这里查看:https://colab . research . Google . com/drive/1 jrqnk 5 pjlwbycvjf 2 jhjdu-dRvMXjXkD?usp =共享

矩阵乘法的性质

现在矩阵乘法都清楚了,让我们看看下图中解释的矩阵乘法的一些属性:

这里有一个任务给你:你可以根据你的想象创建矩阵(A、B 或 C ),然后通过首先计算 lhs 来检查每个规则,然后用它来评估 R.H.S。如果它们成立。

我将在这里检查点积的变换规则:

大家可以看到,我首先创建了两个矩阵 AB ,然后首先通过计算两个矩阵的点积来求解 L.H.S .然后使用**T** 方法转置它们,并根据 R.H.S .对其进行评估,其中矩阵的位置互换,它们首先被转置,然后使用dot()方法相乘。

线性方程组

在线性代数中起着至关重要的作用,以帮助解决各种各样的问题,方程系统基本上被定义为多个方程的集合。它们可以用矩阵进一步描述,让我们看看如何描述。

含有两个未知数的两个方程组。图表绘制使用:https://mathisfun.com

因此,方程组有两个主要部分:

  1. 方程式的数量
  2. 未知数的数量

未知数的数量是手头问题的维数,方程的数量是(2D)或 n 维*面中的线的数量。

这是一个由 4 个方程和 4 个未知数组成的系统:

含有 4 个未知数 x1,x2,x3,x4 的 4 个方程组。

线性方程组的矩阵表示

现在,我们可以使用矩阵来描述线性方程组,其形式为 Ax = b. 考虑这个线性方程组:

这里,我们有从 x₁到 xₙ的**n**个未知数,我们有**m** 个行数(这里是方程)。我们可以推断出变量(从 x₁到 xₙ)可以概括为一个向量 x.

并且我们可以将作为(每个变量的系数(权重)】放在另一个矩阵 A 中:

然后,可以使用下面的符号来描述系统的 lhs:

A 和矢量 x 的点积将给我们所需的输出矢量 b

下面是一个两个方程的系统如何发生这种情况的例子:

线性回归

我们今天所学的一个实际例子可以在线性回归模型预测方程的实现中看到,如下所示:

这里,

  • ŷ 是预测值。
  • n 是特征的数量。
  • xi 是第 i 个特征值。
  • θj 是第 j 个模型参数(包括偏置项 θ 0 和特征权重 θ 1、 θ 2、⋯、 θn )。

它可以进一步写成矢量化的形式,如:

yˇ= hθ(x)=θx

  • θ 是带有特征权重的模型的参数向量
  • x 是实例的特征向量,包含 x 0 到 xn ,其中 x 0 始终等于 1。
  • θ x 是矢量 θx 的点积,等于上式中的相对高度。
  • h θ 为假设函数,使用模型参数 θ

结论:

因此,你可以意识到点积和矩阵&向量在机器学习中的重要性,因为高层的每个操作都是由这些基础知识执行的。

Harshit 的数据科学

通过这个渠道,我计划推出几个涵盖整个数据科学领域的系列。以下是你应该订阅频道的原因:

  • 该系列将涵盖每个主题和子主题的所有必需/要求的高质量教程,如 Python 数据科学基础
  • 解释了为什么我们在 ML 和深度学习中做这些事情的数学和推导。
  • 与谷歌、微软、亚马逊等公司的数据科学家和工程师以及大数据驱动型公司的首席执行官的播客。
  • 项目和说明实施目前所学的课题。

你可以在 TwitterLinkedInInstagram 上与我联系(在那里我谈论健康和福祉。)

双盲随机研究:如何正确证明治疗有效

原文:https://towardsdatascience.com/double-blind-random-studies-how-to-prove-properly-that-a-therapy-works-532ce47b0fd3?source=collection_archive---------47-----------------------

自从新冠肺炎病毒传播以来,我们已经听到各种各样的人在争论某些医学研究将某种药物作为治疗手段的有效性。在本帖中,我将展示一种最值得信赖的科学方法来证明一个事件对另一个事件的影响,例如,一种疗法对一种医疗状况的影响。

Unsplash 上的 Taras Chernus 拍摄的照片

用实验研究证明因果关系

证明因果关系的挑战,即一个事件(或特征)对另一个事件的影响,是数据科学家面临的一个著名挑战。很容易获得一个历史数据集,绘制数据点,并找到两个变量之间的相关性。然而,相关性并不意味着因果关系:

  • 可能无法知道哪一个变量是另一个的原因,哪一个是结果;
  • 相关可能是纯粹的巧合;
  • 第三个未知变量可能是两个研究变量的原因。

人们在冲进苹果商店时会摔下楼梯吗?还是人口增长解释了这两个系列?也许这只是纯粹的巧合?更多好玩的例子看【tylervigen.com/spurious-correlations】

为了解决这些问题,研究人员设计了实验研究。与研究历史数据的观察性研究不同,实验性研究是通过重复一个具有受控变量的实验来创建我们自己的数据:在两次实验之间只有一个变量发生变化,这就是我们想要研究的变量对目标变量的影响。如果目标值随着变量的变化而不断变化,那么就存在因果关系。

定义双盲研究

现在,假设我们想证明一种新药治疗特定疾病的效率。典型的设置包括将患病患者分成两组,只给一组患者用药,并比较每组中治愈患者的数量。但是为了避免任何可能影响结果的偏差,我们将增加额外的步骤:

  • 为了消除反应偏差,我们会给未治疗组的患者服用安慰剂,他们显然对治疗分配是不知情的;
  • 为了消除统计偏差,我们将随机分组;
  • 为了消除确认和观察者的偏见,研究者和医务人员也将对治疗分配视而不见。

该配置定义了一个双盲随机研究

实验结果分析

为了简单起见,我们的两个组被认为具有相同的大小,但是对于不同大小的组,分析是非常相似的。**

简化实验的观察结果

现在我们可以制定两个假设:

  • 无效假设:药物无效,两组治愈率相*;
  • 替代假设:该药物是有效的,并且在提供药物的组中治愈率明显更高。

在零假设下,理论结果会是这样的:

在零假设下的结果:组间无差异。

我们现在将执行 卡方检验 。这种广泛使用的测试检查两个变量之间的统计联系(相关性)。这里,我们的两个二元变量是:

  1. 药物的使用(表格各栏)
  2. 病人的治疗(表格的行)

对于表中的每个像元,卡方统计是观测像元值与零假设下的像元值之间的*方差之和除以零假设下的值:

我们简化案例研究的卡方统计公式

最后要做的是将该值与参考表进行比较,以接受或拒绝零假设。在我们的示例中,我们有 1 个自由度:一个变量的值的数量减 1 乘以另一个变量的值的数量减 1 等于 1。

来自维基百科的卡方值表

让我们以下面的例子为例,计算卡方值。起初,我们可能认为这种药物是有效的:

如果我们想要 95%的置信度(这是医学中的常见情况),因为我们的卡方值是 4.8,4.8>3.84,我们可以拒绝零假设,认为药物与安慰剂相比有效果。

****就是这样!不要忘记寻找效果的类型(积极或消极)。

注意:为了使卡方检验有效,建议在零假设下,表中每个单元格的 E≥5。

高级分析:数字目标变量

有时候,目标变量不是二元的,而是一个连续的数值变量:治愈天数、血糖水*、血压……这种情况下,建立一个结果表就无关紧要了。我们将使用不同的方法。

首先,我们将为每组中的每个患者注册目标变量的值。绘制每组的值分布图是评估药物是否对目标变量(此处为患者治愈的天数)有影响的第一条线索。

如果我们的结果看起来像例 A,我们是否应该认为药物有效果?例子 B 呢?

比较这两组的严格方法是比较它们分布的期望值。然而,我们只知道我们研究的病人的样本均值。所以我们要用学生的 t 分布的一个性质来估计两个分布的期望值(一个先决条件显然是检查分布是否正态)。此属性根据样本*均值定义分布期望值的置信区间:

期望值置信区间的学生定律

α是置信水*。 n 是样本量(患者数)。 t 是学生因素。我们可以在参考表中找到它的值:

来自维基百科的学生因子值表

例如,假设我们有 2 组 100 人( n=100 ),我们想要 95%的置信度,我们研究前面看到的例子 B:

示例 B 的置信区间

期望值的置信区间不重叠,因此分布也不相同:我们可以认为,与安慰剂相比,药物在治愈天数上是有效的。

一个结论

双盲随机研究是证明药物有效的最可靠的方法之一,但它的用途远远超出了医学研究。例如,你可能知道广告、UX 设计甚至机器学习中经常使用的 A/B 测试:哲学是相同的。这种研究可以在我们想知道一个变量是否对另一个变量有影响的任何时候使用。在 Wavestone Consulting,我们使用类似的方法为我们的一个客户评估储罐特性对酒精蒸发的影响。

然而,当进行双盲研究是可能的时候(并不总是如此——你如何为外科手术提供安慰剂?),一个主要的缺点出现了:如果测试的药物是有效的,这意味着“安慰剂”组没有从中受益,当然会后悔。给患有不治之症的病人服用安慰剂是否道德?也许有一天,在 A/B 测试的背景下,一些旨在解决这个遗憾问题的新方法,例如基于强化学习的网飞艺术品个性化系统,将有益于医学研究。

使用一小段代码在 10 秒钟内将你的 Google Colab 内存翻倍

原文:https://towardsdatascience.com/double-your-google-colab-ram-in-10-seconds-using-these-10-characters-efa636e646ff?source=collection_archive---------2-----------------------

“我需要更多内存!”(图片鸣谢:布莱克·帕特森)

oogle Colab 是一个不可思议的工具。可以用三个字来形容:云中的 Python。好吧,四个字。但是重要的是,您不需要担心 Python 版本(Colab 既有 Python 2 又有 Python 3),也不需要担心下载模块(最流行的已经安装了)、备份、文件系统和所有那些有时会导致您因堆栈溢出而浪费时间的管理工作。最好把多余的精力留给编码。

Google Colab 很棒,因为它很简单。这对于学习 Python,对于小型玩具项目,以及一些严肃的机器学习实践来说都是非常棒的。谷歌让你免费使用他们的 GPU 或 TPU!我发现它在大学环境中非常有用:我要求学生通过分享他们的 Google Colab 笔记本的链接来提交他们的作业。再也没有“我的笔记本电脑因为内存不足而死机”的借口了。

2020 年 5 月 20 日更新:一位读者报告说在免费的 Colab 运行时上加倍 RAM 的选项不再有效。胡乱猜测:这与谷歌最*以 9.99 美元/月的价格推出的 Colab Pro 有关,它提供了两倍的内存…

Colab 是 100%免费的,因此自然会有一些资源限制。正如你在下面的截图中看到的,Colab 的每个实例都有 12 GB 的 RAM(实际上是 12.7 GB,但是已经占用了 0.8 GB)。这已经足够了,尤其是考虑到你不需要为此付钱。但有时你需要更多的内存。

默认运行时间有 12 GB 的内存

幸运的是,谷歌很慷慨。非常慷慨。您可以将 RAM 增加一倍,达到 25 GB。你是怎么做到的?不幸的是,没有复选框或菜单选项来做到这一点。要让 25 GB 选项生效,首先需要用完所有会话内存。全部 12 GB。一旦您这样做,会话将崩溃,Colab 将在屏幕底部显示以下内容:

你耗尽了所有的内存!

单击“获取更多内存”将弹出一个对话框,允许您切换到“高内存”运行时:

是的,我有!

就是这样!一旦您批准,您的机器 RAM 现在将显示新的容量:25.5 GB。

双倍的内存!

有一个问题:在 25 GB 升级之后,您当前运行时的状态将会丢失,包括本地文件。你需要从头开始重新运行你的程序。也许再次上传文件等等。因此,如果你知道你肯定需要那块额外的 RAM,先分配它,然后再发现,否则就太晚了。

那么怎么分配这么多 RAM 呢?我在网上找到了一些解决方案,但是(1)它们需要大约 60 秒(2)它们需要多行代码。

所以我想出了一个更简单的解决方案:一行代码,由 10 个字符组成,就可以完成这个任务。此外,它非常快:仅在 10 秒钟内就消耗完了所有 12 GB 或 RAM。这是:

[1]*10**10

就是这样。这就是代码。它是如何工作的?Python 将尝试创建一个由 10 个⁰=10,000,000,000 整数组成的列表。然而,这样的列表需要超过 12 GB。事实上,存储这个列表需要大约 80 GB 的 RAM。因此,会话将崩溃,升级将很快可用。所以:如果你确定你的程序需要双 RAM,在暂存单元(Ctrl/⌘+Alt+N)中运行[1]*10**10,接受 ram 升级,就这样。你完了。

希望你喜欢这篇文章!现在,让我们开始 10x10 编码挑战:)

10x10 编码挑战

你能找到一段“更好”的代码来用完所有的内存吗?短一点的(少于 10 个字符),还是快一点的(少于 10 秒)?或者最好两者都有!欢迎在评论区发表您的代码或任何其他反馈。谢谢大家!

更新(2020 年 5 月 3 日): Sumit Yadav 回应挑战,发布了一段更短的代码,只有 9 个字符:[1]*9**10 (9 ⁰约为 3.5 10⁹,足以触发内存升级)。恭喜你 Sumit!

用凯利标准和贝叶斯统计让你的钱翻倍

原文:https://towardsdatascience.com/doubling-your-money-with-the-kelly-criterion-and-bayesian-statistics-83ee407c0777?source=collection_archive---------10-----------------------

投资组合优化

如何确定赌注并获胜

彼得罗·马蒂亚在 Unsplash 上拍摄的照片

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

不久前,当我住在阿德莱德时,有客户找到我,他们想弄清楚如何分配赛马中的赌注,特别是一些奇特的赌注,如 trinella(以任何顺序挑选前三匹马)和 quinella(以任何顺序挑选前四匹马)。

他们想让我找出一种计算凯利标准(见下文)的方法,通过重复下注来成倍增加他们的资金池。一个巨大的复杂问题是,这是一个同注分彩投注系统,所以赛马的赔率甚至就在比赛开始前更新!

我可以说我解决了这个问题,但是我不能在我的咨询合同中透露这个解决方案。

然而,在这篇文章中,我将讨论凯利标准,以及如何将贝叶斯统计与它结合起来。

单次与重复下注

假设你想通过抛硬币和一个朋友打一次赌。假设你有一笔资金池 M ,那么,为了使你的赢款最大化,最佳策略是你应该下注 M 的全部股份。对于一枚公*的硬币,预期的回报是 M/2。

但是如果你和你的朋友多次打赌呢?

我们可以很容易地看到,在一次性赌注中使用的策略在这里并不适用。如果我们每一轮都下全额赌注,存活足够长时间以复合初始资金池的机会将非常渺茫,因此随着赌注数量的增加,我们的预期奖励将趋向于 0 。我们可以看到,最起码,重复下注的游戏主名是生存,而欣欣向荣。

那么,在这种情况下,什么是最佳策略呢?

输入凯利标准

凯利标准是由贝尔实验室的 John L. Kelly Jr .在其开创性的论文中提出的,是一种在重复下注的情况下优化下注规模的策略。凯利本人是一个有趣的人物:一个烟不离手的得克萨斯人,二战期间曾是海军的战斗机飞行员,也是一名出色的研究员。他发展了这个标准,作为他杰出的同事克劳德·香农对信息熵的另一种解释。你可以从《财富的公式》这本书里了解它的历史。

给定一个初始的财富池,目标是在下注时最大化财富的翻倍率。凯利论文中对赛马案例的最初分析假设投注者将她的投资组合完全投资于所有期权;后来出现了一些变化,赌者可以扣留一部分财富。有趣的是,可以从数学上证明(几乎可以肯定),从长期来看,没有其他策略能在更高的财富方面胜过凯利标准。

简而言之,凯利标准的目标是通过在每次下注时进行智能分配,最大化财富翻倍的速度。即使你知道胜算很大,全押也不是个好主意,因为有亏损的可能。

让我们考虑一下掷硬币场景中的重复下注。在这种情况下,凯利标准很简单(例子取自维基百科)

  • f* 是当前财富要下注的分数(用分数表示),
  • b 是在赌注上收到的净赔率(例如,下注 10 美元,赢了,奖励 14 美元,包括赌注;然后 b =0.4),并且
  • p 是获胜的概率。如果我们让q= 1p,那么有趣的是,凯利准则建议,如果下注者有一条,即b>q/p(注意,如果b<,则 f* 可以是负数它还说如果b=q/p就不要赌任何东西。

为了得到下面的好东西,我不打算过多地钻研这个案例的公式。你可以在像托马斯和盖的经典文本这样的标准教科书中找到推导。

现在我们已经建立了对凯利标准的直觉,通过对比单次下注情况和重复下注情况,我们可以看到明显的差异:

  • 如果赔率对你不利,就不要下注!这相当于在扑克游戏中经常弃牌,只对对你有利的赌注分配较大的份额,
  • 对于一次性下注,我们最大化您赢款的*均值(或期望值),但对于重复下注,我们最大化您赢款的 几何*均值

这些共同帮助我们最大化我们的钱每一次翻一番的速度(或 T42 翻一番的速度)。

这已被应用于各种游戏,包括赛马,甚至股市投资。在后一种情况下,有人说沃伦·巴菲特本人就是凯利·bettor⁴(尽管我认为查理·芒格比巴菲特更像)。

一个主要的警告

然而,应用该标准的主要困难在于,它假定事件发生的真实概率对于下注者来说是已知的。在上面掷硬币的例子中,下注者知道 p 的值是多少,她可以相应地确定赌注的大小。

实际上,这些通常是未知的,概率必须由下注者来估计。不幸的是,根据定义,任何估计都可能是错误的,因为这只是猜测。该标准对估计概率敏感,并且由于该标准使财富翻倍指数最大化,所以随着时间的推移,估计概率中的错误很容易毁掉投注者。

请注意,在我的咨询工作中,我的客户有一个系统来估计马匹获胜的概率,这使得我的工作简单了很多。

如果你没有这样的系统,这就是贝叶斯更新的用武之地。目标很简单:我们希望根据所有可用信息估算事件发生的概率。我们根据新的信息不断更新概率,然后用这些信息来决定我们的赌注。随着时间的推移,随着评估的适应,我们希望我们的分配表现得更好。

例子:赛马!

具体来说,让我们把问题归结为在赛马场赌马的具体问题。

让我们假设有 K 匹马。在每一轮中,我们都想赌一匹获胜的马,一旦这一轮结束,获胜者就是这 K 匹马中的一匹。基于这些信息,我们想要更新一组概率 p ₁, p ₂,⋯, pₖ ,其中 pᵢ 是那匹马的概率,随着时间的推移越来越接*真相。

点击链接这里运行一个他们如何一起工作的模拟!假设你的机器上已经安装了 Docker ,只需在命令行上通过提供的脚本run.sh运行笔记本即可。笔记本在docker/Kelly Multiarm Portfolio Simulation.ipynb找到。

我们假设马独立地执行。基于这个假设,我们可以用狄利克雷分布来模拟马获胜的概率。这样做的理由如下:****

  • 每匹马获胜都可以被视为一个分类随机变量,所以如果马 k 获胜,那么实现的随机变量就是 k ,那么
  • 作为伯努利过程的一般情况,分类分布的共轭先验是狄利克雷分布,因此选择了狄利克雷分布。这在朱庇特笔记本上会更清楚。

贝叶斯更新投资组合与最优凯利配置投资组合

我们将看到,在模拟中,在重复下注的情况下,由于估计概率中的误差,分配通常是不完美的,并且不接*最优分配,即,如果下注者知道潜在的马获胜概率。我们可以在下图中看到这一点,其中最优投资组合和贝叶斯投资组合的初始财富都是从 1 美元开始的。但是结果是不可否认的:随着评估变得更好,最终的分配也会变得更好!**

最后一个音符

当然,现实要复杂得多:

  • 我们假设马的表现是相互独立的:这在现实中可能不是真的,
  • 潜在的真实概率在整个模拟过程中保持静态:同样,概率在现实生活中会更加动态,更多地来自未知过程,****
  • 目标函数假设在估计的概率中没有错误:考虑估计中的不确定性可以改善分配,并且
  • 在整个模拟过程中,赔率保持不变:这在同注分彩投注系统中显然是不正确的,因此在赔率变化的情况下不断更新概率会很有趣。

我还没有探索的一个途径是转换到非参数模型(也称为神经网络)来估计概率。这是令人兴奋的,因为人们可能会使用每匹马的更多上下文信息,例如它的骑师、过去在不同赛道上的表现等。来推导获胜的概率,而不是像上面那样附加一个经典的共轭先验。

另一个原因是,将它应用于股票市场更复杂,因为股票价格的范围更广,基本上可以用连续分布来建模。也就是说,可以想象的是,蒙特卡洛模拟的某种组合可能有助于估算。

我想总结的一个主要观点是,概率的建模和赌注的大小本质上分别是估计决策任务。这与强化学习和控制系统有很强的联系,因此结合这些领域的知识将是一个令人兴奋的探索领域!****

原载 此处 稍加编辑。

参考

[1]约翰·l·凯利,“信息率的新解释”,贝尔系统技术杂志。第 35 卷第 4 期:第 917–926 页,1956 年链接

[2]威廉·庞德斯通,“财富的公式:击败赌场和华尔街的科学赌博系统的不为人知的故事”,2006 年链接

[3]托马斯·m·盖和乔伊·a·托马斯,“信息理论的要素”,第 2 版。,2006 年链接

[4] Mohnish Pabrai,“The Dhandho Investor:The Low-Risk Value Method to High return”,Wiley,2007 年链接

上下:用 D3.js 说明的谜题

原文:https://towardsdatascience.com/down-and-up-a-puzzle-illustrated-with-d3-js-9aae2d52adcf?source=collection_archive---------21-----------------------

在面试中解决一个脑筋急转弯可能会令人害怕,但通常简单的视觉效果——就像这篇文章中的那些——会帮助你找到答案。

由 Walimai.photo 拍摄的照片由作者裁剪并调整大小。

在最*的一次度假中,我和丈夫偶然发现了一家娱乐商店,里面有很多棋盘游戏、骰子、扑克牌等。我们很快找到了一件我们都绝对是书呆子的东西,被认为是必不可少的:Boris A. Kordemsky 写的一本书,书名是The Moscow Puzzles:359 Mathematical Recreations。不,我们没有花整个假期来解决所有 359 个问题,但我们确实把书带回家,并继续研究它们——通常在晚上喝一杯酒。

出于几个原因,最*有一个特别的谜题引起了我的注意。我一会儿会回到那些原因,但是现在,这个问题叫做“上下波动”,它是这样的:

假设你有两支铅笔压在一起并垂直握着。从铅笔的下端量起,左边有一英寸被涂上了油漆。右铅笔保持稳定,同时将左铅笔向下滑动 1 英寸,继续将两支铅笔压在一起。然后,将左边的铅笔向上移动,回到原来的位置,同时保持两支铅笔接触。你继续这些动作,直到你把左边的铅笔上下移动 5 次。假设油漆在此过程中不会干燥或耗尽。在你最后的动作之后,每支铅笔有多少英寸被涂上了颜料?

如果你愿意,在继续之前花一分钟解决这个问题——剧透在前面!

最初的想法

当我第一次听到这个问题时,我最初认为,也许油漆根本没有涂抹到右铅笔上,也许在整个过程中,只有一英寸的油漆出现在左铅笔上。(这也是你预料到的吗?)但是当我第二次阅读这个问题时,我开始想象可能会发生什么。一旦我在脑海中勾勒出这个过程,解决方案就变得清晰多了。因为我丈夫正在和我一起解决这个问题,所以我给他画了这个草图来分享我的想法:

我设法清晰地设想了情况,找到了解决方案,并用这个简单的草图表达了我的想法。对于许多数学难题来说,一张粗略的图片就能满足你寻找答案的所有需要,但是如果我粗糙的图画还没有完全传达给你答案,不要担心。让我们用一个更好的例子来更有条理地深入一下。

颜料立即从左边的铅笔转移到右边。

问题设置

从问题的方向,我们知道,最初只有左边的铅笔涂上了油漆。回想一下,左边的铅笔直接压在右边。这意味着当它们挤压在一起时,颜料立即转移到正确的铅笔上。所以两支铅笔在上下运动之前都涂了一英寸的颜料。

解决和说明整个问题

随着左铅笔上下移动,问题变得有点复杂,但是再次回到视觉解释非常有帮助。也可以随时重读问题陈述,重新找到你的方向。

两支铅笔目前都被涂上了一英寸厚的油漆。然后左边的铅笔向下移动一英寸,同时两支铅笔继续压在一起。你能想象当左边的铅笔向下移动时会发生什么吗?是啊!左铅笔的干净部分与右铅笔的底部接触;因此,另一英寸的油漆转移到左侧。

左边的铅笔现在比右边的低一英寸。右铅笔的一英寸被涂上了颜料,但是颜料覆盖了左铅笔的两英寸。左边的铅笔在问题的下一步向上移动,回到原来的位置。两支铅笔重新对齐,但是颜料会发生什么变化呢?由于左铅笔不断与右铅笔接触,在第一次上下循环结束时,油漆会涂抹到右铅笔上,并覆盖两个铅笔的两英寸。

其余四个循环过程类似,颜料先转移到左边的铅笔,然后转移到右边。最后,在五轮运动之后,两支铅笔都被涂上了总共六英寸的颜料:最初的一英寸加上另外五英寸,每一个上下循环一次。

这个问题最终取决于将问题陈述转化为解释性视觉效果的能力。为了进一步将这个解决方案放到上下文中,我用 D3.js 创建了一个交互式图形,展示在下面的 gif 中。下面两支铅笔都从一英寸的油漆开始,如问题设置中所述。

在每次上下移动的过程中,额外的颜料会涂抹到左边的铅笔上,然后是右边的。

注:你可以在我的网站上 与这个视觉 互动或者在 GitHub 上 看一下我的 D3 代码

背景故事和问题扩展

之前我提到的这个问题引起了我的注意,原因有几个。第一个原因正是我们一直在讨论的。我惊讶于这个问题一开始听起来是多么棘手,而一旦你在脑海中构建了一个适当的情景,它就变得多么简单。

这个谜题激起我兴趣的第二个原因是它的历史。正如 Kordemsky 在书中解释的那样,生活在 20 世纪早期的苏联数学家 Leonid Mikhailovich Rybakov 创造了这个“上下”问题。我非常欣赏贯穿许多时间和地域的数学问题。解决这样的难题让我感觉与过去和世界上其他数学家有了更多的联系。

最后,这个问题引发了我的好奇心,因为 Rybakov 第一次想到这个问题是在一次成功的猎鸭回家的时候。Kordemsky 鼓励读者思考为什么会这样,但在他的“答案”部分继续解释。摘自莫斯科谜题一书:

看着他的靴子,Leonid Mikhailovich [Rybakov]注意到他走路时,他们通常互相摩擦的地方整个长度都是泥。

“真奇怪,”他想,“我没有在很深的泥里走,但我的靴子却泥到膝盖了。”

现在你明白谜题的由来了。

就像油漆涂抹了两支铅笔的整个长度一样,Rybakov 的靴子从头到脚都是,因为当他走路时,泥浆从一只靴子转移到了另一只靴子。

我继续思考这个概念如何适用于其他情况,我想到了一个有趣但有点令人不快的例子。考虑两行魂斗罗舞者,其中第一行中的第一个舞者不幸感到不适。如果这位舞蹈演员的疾病具有高度传染性,她当然会将她的疾病传染给她对面的舞伴。有时在对舞中,参与者通过横向移动两条线来交换舞伴。令人遗憾的是,当这种情况发生时,新感染的舞蹈演员会将疾病传回到线上,最终整个舞蹈演员群体都会生病。

疾病从一个舞者传播到另一个舞者,就像颜料在铅笔之间转移一样。

注:你可以在我的网站上 与这个视觉 互动或者在 GitHub 上 看一下我的 D3 代码

结论

我希望你喜欢这个关于我最喜欢的数学智力题之一的讨论,以及这些说明性的 D3 图片。在脑海中形成一个数学难题的图像并不总是容易的,但是在解决这样的问题时,它是无价的——尤其是如果你像我一样是一个视觉学习者。下一次,当你在面试中遇到问题时,看看画草图或想象问题的物理结构是否有帮助。对我来说经常是这样。

我也希望你喜欢了解这个谜题背后的背景故事。一些世界上最好的数学智力题是在很久以前创造的,所以我相信当试图提高我们的思维时,回顾过去对我们大有好处。此外,将这类问题扩展到新的应用程序,就像我对魂斗罗舞者所做的那样,有助于巩固核心概念,并为未来的脑筋急转弯建立直觉。它也使数学问题变得更有趣,因为你把它们和你自己的生活联系起来。现在轮到你了——你能想到其他“上下”的场景吗?

原载于 2020 年 1 月 5 日 http://kimberlyfessel.com

参考

[1] B. A. Kordemsky,莫斯科难题:359 种数学娱乐 (1992),多佛。

下载一个 Flask 模板,准备插入您的业务逻辑

原文:https://towardsdatascience.com/download-a-flask-template-ready-to-plug-in-your-business-logic-bb9375e1be09?source=collection_archive---------32-----------------------

照片由 Fotis FotopoulosUnsplash 上拍摄

可用于日志记录、配置设置、URL 参数验证的预配置设置

让我们假设,经过大量艰苦的工作,你已经有了你的机器学习模型,它应该运行的方式。这种模型可以响应用户的请求,对推文情感进行分类,或识别图像中的对象,或推荐产品或其他符合您需求的算法。您现在想要快速部署这个模型。下面这篇文章解释了我创建的模板,它可以让你快速上手。

Flask micro 服务是一种部署应用程序的简单方法。然而,人们很快意识到,你不希望创建一个大的单片单文件程序。该计划应该是模块化的,以支持未来的增强,它应该是可配置的帮助下配置文件。这些配置参数不仅适用于 Flask,也适用于您的业务应用程序(还记得您创建的 tweet 分类应用程序)。理想情况下,服务器应该适当地记录一切。大多数应用程序还需要连接到数据库,最后,在调用模型 api(或返回错误)之前,需要验证入站请求参数。

听起来很多,对吧?这实际上是相当多的,人们可以很容易地花相当多的时间来构建一个提供这些特性的健壮框架。在这里,我提供了一个到 github 的链接,它在一个模块化的应用程序中提供了所有上面提到的特性。

您应该能够克隆这个 Flask 服务器模板,并简单地运行它。一旦你让它运行起来,你就可以开始调整它来满足你的特定需求。

[## alsm 6169/flask _ 服务器 _ 模板

Flask 服务器模板准备插入业务逻辑。该模板的特点是:烧瓶配置模块…

github.com](https://github.com/alsm6169/flask_server_template)

在本文中, 我将只解释为您的项目定制这个烧瓶模板可能需要更改的部分。我的基本假设是对 Flask、SQLAlchemy、Marshmallow 有一定程度的熟悉。只要足够熟悉,如果某些部分没有意义,可以谷歌一下。请在评论中自由提问,我可以回答/更新文章以涵盖要点。

如果您希望先安装并运行服务器,那么请跳过中间的解释部分,按照下面的命令顺序操作。

让我们从代码组织开始

Flask 服务器模板代码结构

现在解释代码文件

下面我将解释每个文件的用途以及你可能需要根据你的要求修改的相关代码部分(如果有的话)。

base _ dir/flask _ server _ template→主模板目录

flask _ server _ template/main . py

这是服务器的入口点。它读取应用程序配置文件(run_params.json),初始化记录器,初始化 flask 服务器并运行服务器。

**### flask_server_template/main.py ###***To use the template no changes are needed in this file.*

flask _ server _ template/main _ config . py

这个模块有两个作用。

1.读取应用程序配置文件,并创建一个可由应用程序的另一部分使用的字典。

2.创建数据库连接字符串。这个连接字符串利用了配置文件中的参数。该连接字符串因基础数据库而异。用于创建连接字符串的 SQLAlchemy 文档在这里是。

**### flask_server_template/main_config.py ###** def get_db_con_str():
pwd = os.getenv(**'DB_PWD'**)  *# get password from environment variable DB_PWD* db_con_str = **f'postgresql://'** \
                 **f'**{run_conf_data[**"DB_USER"**]}**:'** \
                 **f'**{pwd}**@'** \
                 **f'**{run_conf_data[**"DB_SERVER"**]}**:'** \
                 **f'**{run_conf_data[**"DB_PORT"**]}**/'** \
                 **f'**{run_conf_data[**"DB_NAME"**]}**'** os.environ[**'SQLALCHEMY_DATABASE_URI'**] = db_con_str
    return db_con_str

flask _ server _ template/config以下是记录器和业务逻辑应用程序的配置文件

config/logger.conf

有两个日志处理程序。“handler_consoleHandler”记录到屏幕,而“handler_fileHandler”记录到文件 run_log.log 中。每次服务器运行时,该文件都会被覆盖。但是,如果您想更改这一点并创建带有时间戳的新文件,您可以取消对第二行的注释,并对第一行进行注释

**### config/logger.conf ###** ...
...
[handler_fileHandler]
class=FileHandler
level=DEBUG
formatter=simpleFormatter
args=('logs/run_log.log','w')
*#args=('../logs/' + time.strftime('%%Y%%m%%d_%%HH%%MM') +'.log','a')*[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=simpleFormatter
args=(sys.stdout,)
...
...

config/run_params.json

“run_params”具有应用程序级配置,包含数据库服务器、用户名、运行 flask 的模式(开发/生产)等信息

**### config/run_params.json ###** {
  "LOGGER_CONFIG": "config/logger.conf",
  "FLASK_CONFIG": "flask_config.DevelopmentConfig",
  "DB_SERVER": "localhost",
  "DB_PORT": "5432",
  "DB_NAME": "dvdrental",
  "DB_USER": "dvdrental"
}

flask _ server _ template/logs→创建运行日志的目录

要使用该模板,不需要对该目录进行任何更改。

flask _ server _ template/test→您的测试脚本

test/flask_client.py

这个模板是一个工作模板,理想情况下,人们应该能够简单地下载和运行。测试客户端将测试这些功能。

**### test/flask_client.py ###***To use the template no changes are needed in this file. New additional test cases can be written in this file or new test file created in this test folder.*

flask _ server _ template/flask _ server _ template→包含 flask 初始化代码、配置设置以及适当功能的路径重定向的主 flask 目录。

flask _ server _ template/_ _ init _ _。py

init。py 包含 flask_server_template 包的初始化函数。它有一个主要功能“create_app”,创建 Flask 对象,设置 Flask 配置,初始化数据库并注册路线(其功能的 URL)

***### flask_server_template/__init__.py ###***To use the template no changes are needed in this file.**

flask _ server _ template/flask _ config . py

' flask_config.py '包含 flask 的配置设置。它提供了开发和生产环境的一般配置。

大部分常用参数都已经设置好了。如需更多设置选项,请查看官方文档。

***### flask_server_template/flask_config.py ###***To use the template no changes are needed in this file.However, for quick reference, the default configurations*class Config(object):
    DEBUG = False
    TESTING = False
    CSRF_ENABLED = True
    SECRET_KEY = **'this-really-needs-to-be-changed'** SQLALCHEMY_DATABASE_URI = os.getenv(**'SQLALCHEMY_DATABASE_URI'**)
SQLALCHEMY_TRACK_MODIFICATIONS = False
    SQLALCHEMY_ECHO = False

class ProductionConfig(Config):
    DEBUG = False

class DevelopmentConfig(Config):
    DEVELOPMENT = True
    DEBUG = True*

flask _ server _ template/flask _ routes . py

“flask_routes.py”包含 URL 到其相应实现的映射。

注意:有一个调用对数据库进行适当的设置。@ routes . before _ app _ first _ request。如果我们希望使用 SQLAlchemy ORM 特性,这是必需的。在下面对 flask_server_template/db 的描述中有更多的细节。

对于每个需要迎合的 REST API,都需要有一个到函数的映射。这里描述了映射到 URL 的单个函数的示例。

***### flask_server_template/flask_routes.py ###** ...
...
@routes.route('/module/v01/functions/film_info_orm', methods=['GET']) ***#TODO:*** *change URL*
def get_film_info_orm(): ***#TODO****: change function name*
    try:
        log.debug('inside get_film_info_orm') ***#TODO:*** *change logging*
        film_df = bm.get_film_info_orm(request) ***#TODO:*** *change business logic function here*
        response_code = 200
        response_msg = film_df.to_json(orient='records') ***#TODO:*** *change response*
except RuntimeError as err:
        response_code = 700 response_msg = jsonify(str(err))
    return make_response(response_msg, response_code)
...
...*

flask _ server _ template/model→业务逻辑代码驻留在这里**

model/business _ model . py

在模块“business_model.py”中添加了所需的业务逻辑。一般流程如下:验证输入参数,从数据库获取数据,执行所需的业务逻辑应用程序并返回结果。

PS: 目前,我没有任何业务逻辑。我只是从数据库返回熊猫数据帧格式的数据。

****### model/business_model.py ###** ...
...def get_film_info_orm(in_request): ***#TODO****: appropriate function name*
    try:
        *# validate the URL parameters* title_schema_obj = TitleValidator() ***#TODO****: appropriate validation object*
        title_schema_obj.load(in_request.args)
        *# verification passed, hence flask_server_template comes here else it would have gone to exception* title = in_request.args[**'title'**]
        log.debug(**'title: '** + title)
        *# get your data in pandas data frame format* df = queries_orm.get_film_info(title) ***#TODO****: appropriate function call here*
        *# apply business logic (if any)* return df
    except ValidationError as error:
        log.error(**f'get_all_film_df:** {error}**'**)
        raise RuntimeError(**'Invalid Request Parameter: '** + str(error))
...
...**

model/request _ validator . py

模块' business_model.py '使用棉花糖来验证 URL 参数。与手动编写 if then else 语句来验证 URL 参数的每个组成部分相比,这是一种首选的验证方式。验证包括数据类型检查(整数、字符串)、数值范围或特定列表和/或一些完全定制的检查。

****### model/request_validator.py ###** ...
...
def some_custom_check(data): ***#TODO****: common checks*
    *'''can be replaced with customised check'''* if not data:
        raise ValidationError(**'some_custom_check for title failed'**)class TitleValidator(Schema): ***#TODO****: appropriate class name*
***# URL should have title of type string between length 1 and 50\. After that call your custom check***title = fields.Str(required=True, validate=[validate.Length(min=1, max=50), some_custom_check])...
...**

*****flask _ server _ template/db→*数据库的查询和操作都在这个文件夹里

在我详细介绍之前,我必须澄清几件事:

  • 我使用了来自postgresql 教程的 PostgreSQL 教程数据库
  • 出于演示目的,这里只有三个相关的表 a .电影 b .演员 c .电影 _ 演员

数据库模式

  • 由于不需要用户进行额外的安装就无法发布 postgresql db,所以我在 sqlite 中创建了这 3 个表,并将其与该模板一起发布(在目录 flask _ server _ template/db/dvdrental . db 中)。
  • 虽然上面我强调了 postgresql 连接,但是在 Github 上也有 sqlite 连接字符串,有了这个连接字符串,整个模板就可以开箱即用了。(简而言之,如果你从他们的网站上安装了 postgresql 和数据库,你可以使用 postgresql,否则你可以简单地使用 sqlite)。
  • 由于大多数数据科学家使用表格,查询返回熊猫数据框。
  • 我有两种格式的所有查询 a .使用 SQLAlchemy 核心,即原始 SQL(select * from…)b . SQLAlchemy ORM 将表反映到 python 对象中,并以 python 方式执行查询。这让人们可以根据自己的喜好自由选择。

唷!现在我解释代码文件

db/dvdrental.db

这是包含三个表的 sqlite 数据库

  • 电影:存储电影数据,如标题,发行年份,长度,评级等。
  • actor:存储 actor 数据,包括名字和姓氏。
  • film_actor:存储电影和演员之间的关系。
*****### db/dvdrental.db ###***To use the template no changes are needed in this file.****

数据库/数据库 _ 扩展. py

模块“db_extensions.py”具有数据库连接对象、数据库元数据、包含数据库反射(即数据库表到 python 对象的转换)的对象以及初始化对象关系映射的代码。

*****### db/db_extensions.py ###***To use the template no changes are needed in this file.*def orm_init():
...
Base.prepare(db_obj.engine, reflect=True) #IMPORTANT for reflecting database into python objects***

db/query s _ ORM . py

模块“queries_orm.py”包含使用 SQLAlchemy ORM 的查询,即访问数据库的 pythonic 方式。

*****### db/queries_orm.py ###**def get_film_info(title):
    film_orm = Base.classes.film ***#TODO****: refer to correct table*
    qry = db_obj.session.query(film_orm).\
         filter(film_orm.title == title) ***#TODO****: your query*
    film_df = pd.read_sql(qry.statement, db_obj.session.bind)
    return film_df***#TODO****: Another sample query below with multiple joins and filter*
def get_film_actors(title):
    film_orm = Base.classes.film
    actor_orm = Base.classes.actor
    film_actor_orm = Base.classes.film_actor
qry = db_obj.session.query(actor_orm).\
            join(film_actor_orm,film_orm).\
            filter(film_orm.title == title)
    actor_df = pd.read_sql(qry.statement, db_obj.session.bind)
    return actor_df***

db/queries_rawsql.py

模块“queries_rawsql.py”包含原始 sql 查询。

免责声明:在 queries_rawsql.py 中有示例参数化查询(where 子句带有参数)。但是,这种格式不适用于 sqlite。它在 postgresql 和 oracle 上都能很好地工作。

*****### db/queries_rawsql.py ###**def get_all_films():
    query = **'''
    SELECT * FROM film
    '''  *#TODO****: your query*    film_df = pd.read_sql(query, db_obj.session.bind)
    return film_dfdef get_film_actors(title):
    query = **'''
        SELECT a.first_name, a.last_name FROM actor a 
        INNER JOIN film_actor fa on fa.actor_id = a.actor_id 
        INNER JOIN film f on f.film_id = fa.film_id 
        WHERE f.title = %(title)s
        ''' *#TODO****: your query*    actor_df = pd.read_sql(sql=query, params={**'title'**: title}, con=db_obj.session.bind)
    return actor_df***

安装和运行

我认为快速启动并运行的最好方法是执行以下步骤

  • 克隆存储库
  • 创建虚拟环境
  • 激活虚拟环境
  • 在需求文本中安装库
  • 运行服务器
*****### Terminal ###**$mkdir base
$cd base
$git clone [https://github.com/alsm6169/flask_server_template.git](https://github.com/alsm6169/flask_server_template.git)
$cd flask_server_template/
$conda create --name ptest
$conda activate ptest
$conda install --file requirements.txt
$python main.py***
  • 在另一个 shell 中运行测试文件。或者可选地,
  • 打开浏览器运行请求
*****### Browser ###**http://127.0.0.1:5000*http://127.0.0.1:5000/module/v01/functions/film_list_orm**http://127.0.0.1:5000/module/v01/functions/film_actors_orm?title=Alaska Phantom****

这就把我带到了这篇文章的结尾。希望你会发现它很容易理解和使用。如果您有任何反馈/改进,请告诉我。

使用 Python 从 Springer 下载所有免费教材

原文:https://towardsdatascience.com/download-all-free-textbooks-from-springer-using-python-bd0b10e0ccc?source=collection_archive---------6-----------------------

一个重要的 PYTHON 技巧

使用 Python 下载多个文件的分步指南

插图作者:金彩云

所有数据科学家和研究人员的好消息🎉🎉斯普林格宣布在新冠肺炎封锁期间提供数百本价值数千美元的昂贵科技书籍供免费下载。超过 500 本教科书可供选择!

如果你只对其中的一些书感兴趣,你可以一本书一本书地下载。但是这种机会不会经常出现,那把他们都弄到手呢?😊自己手动下载会很无聊。为什么不让 Python 来做这个工作呢?🤔根据这个帖子,这些春季教材只能买到七月底。根据疫情的情况,黄金时间可能会延长…

这篇文章将通过一步一步的指导向你展示如何使用 Python 从列表中自动下载所有的 Springer 教材。所以,如果你是编程或 Python 的新手,不用担心。

证明:

从 Springer 下载教材的简单 Python 脚本(使用 VSCode 运行)

Python 脚本的示例输出

如你所见,只有 11 行 Python 脚本可以在几分钟内为你下载所有这些教材。在你读完这篇文章之后,你将能够自己完成这个过程,并且将来也能够应用这个技术来下载任何项目或文件的列表。✌

为什么斯普林格现在给我们免费访问?

冠状病毒的爆发对教育产生了前所未有的影响,给学者和他们的学生带来了特别的压力。在诸多不确定性和快速变化的信息中,我们知道许多教育工作者正在努力向虚拟课堂环境过渡,寻找与学生在线互动的方法,并确保他们拥有继续学业所需的资源。为了缓解学术界目前面临的巨大压力, Springer Nature 制作了一套 所有学科的基本教材,免费提供 以帮助支持世界各地的学生和教师。[1]

斯普林格自然图书公司董事总经理尼尔斯·彼得·托马斯说:“随着危机的全球影响加剧,远程访问教育资源变得至关重要。在这个充满挑战的时期,我们希望为讲师、教师和学生提供支持,并希望这一举措(将有 500 多本关键教科书在网上免费提供)能够有所帮助。”[2]

我们开始吧

现在,让我们看看如何使用 Python 来完成这项工作!

首先,让我们准备好你的 python 的所有需求。如果你的电脑里还没有 Python,你可以在官方网站这里下载。

请打开命令行并使用以下命令,使用pip准备 Python 库:

**$ pip install pandas
$ pip install wget
$ pip install requests
$ pip install xlrd**

安装完成后,创建一个项目文件夹,从 Springer(Free+English+textbooks . xlsx)这里下载可用免费教材的 excel 列表。

这里获取免费英语教材标题表。

链接 URL 可能会随着时间的推移而改变,您可以在此页面找到此 excel 表格的更新版本,并点击链接“免费英语教科书标题”,如下图所示。

然后,创建一个 Python 文件download_textbooks.py,并在项目文件夹中准备名为download的文件夹。在我们的项目文件夹中会是这样的:

项目文件夹示例

然后,使用您喜欢的编辑器编辑download_textbook.py,添加以下代码行以导入 Python 模块并将 Springer 教科书 excel 加载到pandas dataframe中。让我们使用df.head(10)命令来检查数据帧的前 10 行。

**import requests
import wget
import pandas as pd**
**df = pd.read_excel("Free+English+textbooks.xlsx")
print(df.head(10))**

斯普林格公司教科书清单数据框

在这个数据框架中,我们目前需要的主要列是用于形成文件名的“书名和“版本”,以及用于获得下载链接的“ OpenURL ”。所以我们现在的计划是使用for loop遍历 excel 列表的每一行。

我们应该为每个循环做什么:

  • 通过“书名”和“版本”列为每本书创建一个filename 变量。请注意,我们可以使用任意混合的列来生成文件名。
  • 使用wget命令下载一本书,并用filename 变量命名。

所以我们可以将这个计划转换成 Python 脚本:

**for index, row in df.iterrows():
    file_name = f"{row.loc['Book Title']}_{row.loc['Edition']}"
    url = f"{row.loc['OpenURL']}"
    wget.download(download_url, f"./download/{file_name}.pdf")**

看起来不错,对吧?然而,这种方法是行不通的,因为“OpenURL”列并不直接代表下载 PDF 文件的最终 URL。因此,我们需要将这个 OpenURL 更改为正确的端点 URL。
例如,如果我们在网络浏览器的“OpenURL”栏中打开一本教科书的链接:

**1.**[**http://link.springer.com/openurl?genre=book&isbn=978-0-306-48048-5**](http://link.springer.com/openurl?genre=book&isbn=978-0-306-48048-5)

哦,它被重定向了!🤨它会自动重定向到

**2.**[**https://link.springer.com/book/10.1007%2Fb100747**](https://link.springer.com/book/10.1007%2Fb100747)

然后,如果我们单击网站中的下载 PDF 按钮,真正的端点 PDF 文件将是:

**3.**[**https://link.springer.com/content/pdf/10.1007%2F0-387-36274-6.pdf**](https://link.springer.com/content/pdf/10.1007%2F0-387-36274-6.pdf)

这意味着我们应该从 1。敬 3。每个循环的第一个!因此,我们在for loop 中应该做的额外步骤是

  • 从“OpenURL”列打开链接。
  • 获得重定向的 URL:我发现最简单的方法是使用request模块。
  • 将 URL 字符串的结构重新格式化为下载 PDF 文件的端点 URL。我们可以用str.replace(old,new)来做。
  • 按计划用wget下载一本书。

然后,整个 Python 代码将如下所示:

download_textbooks.py

在用python download_textbooks.py运行 Python 脚本后,您会在download文件夹中获得所有的教科书。

下载的施普林格教材

所以,大概就是这样。我希望你喜欢这篇文章,并且能够在将来应用这个想法来自动化你的一些工作流程。请注意,使用 Python 有几种方法可以做到这一点,因为几个模块可以完成这项工作。如果您有任何问题、意见或建议,请随时与我分享。

安全健康健康

感谢您的阅读。👋😄

参考

[1]露西·弗里希,以下是在冠状病毒封锁期间如何免费获取教科书的方法(2020 年 4 月 16 日),斯普林格自然杂志

[2] Felicitas Behrendt,施普林格自然集团,施普林格自然向受冠状病毒封锁影响的教育工作者、学生和学者免费提供关键教科书 (2020 年),施普林格自然

下载并分析您的 Facebook Messenger 数据

原文:https://towardsdatascience.com/download-and-analyse-your-facebook-messenger-data-6d1b49404e09?source=collection_archive---------15-----------------------

其他社交媒体应用程序如何影响您在 Facebook Messenger 上的使用?你和谁聊得最多?

蒂姆·班尼特在 Unsplash拍摄的照片

拥有超过 20 亿用户的脸书是当今最受欢迎的*台。大多数 facebook 用户使用 Facebook Messenger 应用程序相互交流,包括我。我真的很好奇我在这个*台上的行为,以及 Instagram、微信和 SnapChat 等其他社交媒体应用的兴起如何影响我在脸书的使用。

今天,我将向你展示如何下载你的脸书信息数据,以及如何分析它。

下载您的脸书数据

  • 打开你的脸书,进入设置&隐私 > 设置
  • 前往您的脸书信息 > 下载您的信息
  • 选择数据范围“我的所有数据”、格式“ JSON ”和媒体质量“(随意更改媒体质量,因为高媒体质量会消耗更多存储空间)

  • 仅选择消息(在这种情况下,我只对我的消息数据感兴趣,您也可以尝试其他数据)
  • 点击创建文件

脸书将在他们的服务器上创建一个 zip 文件,并在文件可以下载时通知您。我花了一天时间才拿到压缩文件。

预处理您的脸书消息数据

在进行任何分析之前,我们要做的第一件事是预处理数据。这些是我们解压缩下载文件后,邮件数据中的文件夹。

邮件数据中的文件夹

我们只对收件箱感兴趣。

Folder Structure of Inbox: 
📂 inbox  
┣ 📂 alex    
┃  ┗ 📜 message_1.json  
┃  ┗ 📂 photos
┗ 📂 brian    
   ┗ 📜 message_1.json
   ┗ 📜 message_2.json
   ┗ 📜 message_3.json
   ┗ 📂 photos

这是收件箱中的常规文件夹结构。如果你和某人有很多文本消息,你可能有多个消息 JSON 文件。

现在,我们必须编写一个 Python 脚本来提取所有这些 JSON 文件中我们需要的信息。

我将遍历收件箱中的所有子文件夹,读取文件名以“message”开头的所有 JSON 文件。

folders.remove(".DS_Store")此处用于删除 macOS 中的系统文件。这是为了防止以后循环中的错误。 (Windows 用户可以忽略这个)

datetime.fromtimestamp(message[“timestamp_ms”] / 1000).strftime(“%Y-%m-%d %H:%M:%S”)在这里用于将时间戳转换成人类可读的东西。我还把它转换成字符串,这样我就可以毫无问题地把它写入输出文件。

这是您将通过上面的 Python 脚本获得的示例输出文件。现在你可以用任何可视化工具分析你的脸书信息数据。

output.csv 
"2016-03-20 13:48:46",Brian,Okay
"2016-03-20 13:48:10",June,See you 
"2016-03-20 13:48:01",Matthew,We are at ....

分析我的脸书消息行为

我的 Facebook Messenger 活动趋势

  • Messenger 与脸书应用的分离确实增加了我在 Facebook Messenger 上的使用。起初,我真的很讨厌它,因为它迫使我使用 2 个不同的应用程序。但我发现它实际上减少了我被脸书分散的注意力,使我能够专注于发信息(发信息时不再不停地滚动脸书!).
  • 有一段时间我迷上了 SnapChat,因为它花哨的面部过滤器和 24 小时故事功能。使用率的下降是由 SnapChat 开始的,但这不是持续下降的主要原因,因为 Instagram 也引入了 Stories 功能!
  • 当 Instagram 开始引入 DM(直接消息)功能时,它没有成功吸引我,因为它没有我正在寻找的功能,如通话、特殊交互(贴纸、gif 等)。当 Instagram 也发布 Stories 功能时,它立即将我引入了该*台,因为我已经有很多朋友在使用 Instagram(我相信这也是 Instagram 能够战胜 SnapChat 的主要原因之一,Instagram 与 SnapChat 相比已经拥有庞大的用户群)。
  • 2017 年后,my 被多元化为微信、WhatsApp、丨t丨e丨l丨e丨g丨r丨a丨m丨s丨 等更多 App。这导致自 2017 年以来使用率持续下降。

除了这种分析,我们还可以进行一些分析,如

  • 工作日与周末的使用情况
  • 白天和晚上的使用情况
  • 你最常用的短语/单词是什么?

现在你已经学会了如何下载你的脸书信息数据并分析它。希望这篇文章对你有用。如果我犯了任何错误或错别字,请给我留言。

可以在我的 Github 中查看完整的脚本。干杯!

如果你喜欢读这篇文章,你可能也会喜欢这些:

[## 如何掌握 Python 命令行参数

使用命令行参数创建自己的 Python 脚本的简单指南

towardsdatascience.com](/how-to-master-python-command-line-arguments-5d5ad4bcf985) [## 如何用 Python 设计你的数据框架

如何使用 Python 高亮显示、格式化或着色您的数据框

towardsdatascience.com](/how-to-style-your-dataframe-with-python-eabf376d1efd)

你可以在 Medium 上找到我其他作品的链接,关注我这里的。感谢阅读!

如何下载和解析 TREC-柯维德数据

原文:https://towardsdatascience.com/download-and-parse-trec-covid-data-8f9840686c37?source=collection_archive---------48-----------------------

你改进 cord19 搜索应用的第一步。

这是一系列博客文章中的第一篇,将向您展示如何改进文本搜索应用程序,从下载数据到微调 BERT 模型。

您也可以从 Google Colab 运行这里包含的步骤。

vespa.ai 背后的团队已经构建并开源了一个 CORD-19 搜索引擎。得益于先进的 Vespa 功能,如*似最*邻搜索转换器支持 ONNX ,它采用了目前可用的最先进的 NLP 搜索方法。

我们的第一步是下载相关性判断,以便能够评估应用程序中部署的当前查询模型,并训练更好的模型来替换已经存在的模型。

下载数据

本节使用的文件可以在https://ir.nist.gov/covidSubmit/data.html.找到。我们将下载主题和相关性判断数据。不要担心它们是什么,我们很快就会探索它们。

!wget https://ir.nist.gov/covidSubmit/data/topics-rnd5.xml
!wget [https://ir.nist.gov/covidSubmit/data/qrels-covid_d5_j0.5-5.txt](https://ir.nist.gov/covidSubmit/data/qrels-covid_d5_j0.5-5.txt)

解析数据

主题

主题文件是 XML 格式的。我们可以解析它并存储在一个名为topics的字典中。我们希望从每个主题中提取一个query、一个question和一个narrative

import xml.etree.ElementTree as ET

topics = {}
root = ET.parse("topics-rnd5.xml").getroot()
for topic in root.findall("topic"):
    topic_number = topic.attrib["number"]
    topics[topic_number] = {}
    for query in topic.findall("query"):
        topics[topic_number]["query"] = query.text
    for question in topic.findall("question"):
        topics[topic_number]["question"] = question.text        
    for narrative in topic.findall("narrative"):
        topics[topic_number]["narrative"] = narrative.text

总共有 50 个话题。例如,我们可以看到下面的第一个主题:

topics["1"]{'query': 'coronavirus origin',
 'question': 'what is the origin of COVID-19',
 'narrative': "seeking range of information about the SARS-CoV-2 virus's origin, including its evolution, animal source, and first transmission into humans"}

每个主题都有许多相关的相关性判断。

相关性判断

我们可以将相关性判断数据直接加载到熊猫DataFrame中。

import pandas as pd

relevance_data = pd.read_csv("qrels-covid_d5_j0.5-5.txt", sep=" ", header=None)
relevance_data.columns = ["topic_id", "round_id", "cord_uid", "relevancy"]

相关性数据包含在 5 轮比赛中做出的所有相关性判断。relevancy等于 0 不相关,1 相关,2 高度相关。

relevance_data.head()

我们将删除关联度等于-1 的两行,我假设这是一个错误。

relevance_data[relevance_data.relevancy == -1]

relevance_data = relevance_data[relevance_data.relevancy >= 0]

下面的图表显示,每个主题有相当多的相关性判断,相关文档的数量在不同的主题之间变化很大。

import plotly.express as px

fig = px.histogram(relevance_data, x="topic_id", color = "relevancy")
fig.show()

接下来我们将讨论如何利用这些数据来评估和改进 cord19 搜索应用程序。

自动从 Microsoft Exchange Web 服务下载电子邮件附件

原文:https://towardsdatascience.com/download-email-attachment-from-microsoft-exchange-web-services-automatically-9e20770f90ea?source=collection_archive---------10-----------------------

用 Python 自动化枯燥的程序

学习使用 Python 库 Exchangelib 处理电子邮件附件

Webaroo.com.auUnsplash 上拍照

介绍

您需要定期下载电子邮件附件吗?你想让这个无聊的过程自动化吗?我知道那种感觉,兄弟。刚来工作的时候,我被分配了一个日常任务:每天从发给我们团队的邮件里下载附呈的报告。这不是一个困难的任务,但它非常无聊,我经常忘记这样做。

我怎样才能摆脱这个虚拟任务:定期下载电子邮件附件。

在研究了互联网之后,我发现一个小小的 Python 脚本可以接管我的工作。让我们来探索一下 Python 能帮到我们什么。

Exchangelib

Exchangelib 是一个 Python 库,它提供了一个简单的接口,允许 Python 脚本与 Microsoft Exchange 或 Exchange Web 服务(EWS)进行交互

[## nylas/exchangelib

该模块提供了一个性能良好、行为良好、独立于*台的简单接口,用于通信…

github.com](https://github.com/nylas/exchangelib)

您可以从 PyPI 安装这个包:

pip install exchangelib

然后按照官方网站的说明导入包。你可能不会全部用到,

#import pytzfrom exchangelib import DELEGATE, IMPERSONATION, Account, Credentials, ServiceAccount, EWSDateTime, EWSTimeZone, Configuration, NTLM, GSSAPI, CalendarItem, Message, Mailbox, Attendee, Q, ExtendedProperty, FileAttachment, ItemAttachment, HTMLBody, Build, Version, FolderCollection

下一步是指定您的凭证,即登录用户名和密码

credentials = Credentials([username='john@example.com](mailto:username='john@example.com)', password='topsecret')

邮件服务器配置

当然,您必须配置邮件服务器。Exchangelib 应该能够识别您的电子邮件服务器使用的身份验证类型,但是在我的例子中,它失败了,我将身份验证类型指定为 NTLM。

ews_url = 'mail.example.com'
ews_auth_type = 'NTLM'
primary_smtp_address = 'john@example.com'config = Configuration(service_endpoint=ews_url, credentials=credentials, auth_type=ews_auth_type)# An Account is the account on the Exchange server that you want to connect to.account = Account(
primary_smtp_address=primary_smtp_address,
config=config, autodiscover=False,
access_type=DELEGATE)

从文件夹下载附件

现在您有了一个 Account 对象,您可以在其中导航。它只是遵循你的电子邮件帐户文件夹结构。比如你想对收件箱文件夹进行操作,就用这个简单的语法:account.inbox。要操作收件箱里面的一个文件夹,只需要像这样放一个反斜杠和单引号:account.inbox / 'some_folder'

如果您只想下载一个文件夹中的所有附件,这个短代码会有所帮助。您可能需要os包来处理本地目录。

some_folder = account.inbox / 'some_folder'for item in some_folder.all():
    for attachment in item.attachments:
        if isinstance(attachment, FileAttachment):
            local_path = os.path.join(local_path, attachment.name)
            with open(local_path, 'wb') as f:
                f.write(attachment.content)

就是这样!

奖金部分

如果我只想下载我以前没有下载过的文件,我可以进一步做什么?我需要一种机制来检查附件是否存在于本地。

我们的团队使用 FTP 服务器来存储所有附加的报告。因此,在我的 Python 脚本中,首先,我登录到 FTP 服务器并列出所有带有指定前缀的文件。在脚本中添加了一项检查,以确定该文件是否存在于当前文件列表中。

为此,我使用了 ftplib,这是一个 FTP 协议客户端库。

[## ftplib — FTP 协议客户端— Python 3.8.1 文档

源代码:Lib/ftplib.py 这个模块定义了类和一些相关的项。该类实现了客户端…

docs.python.org](https://docs.python.org/3/library/ftplib.html)

以下代码登录到 FTP 服务器(ftp.login()),导航到目标文件夹(ftp.cwd())并列出所有匹配指定前缀(file.startswith())的文件(ftp.nlst())

from ftplib import FTPftp_server_ip = FTP_SERVER_IP
username = 'username'
password = 'password'
remote_path = 'remote_path'
local_path = 'local_path'with FTP(ftp_server_ip) as ftp:
    ftp.login(user=username, passwd=password)
    ftp.cwd(remote_path + '/copied data')
    filelist = [file for file in ftp.nlst() if file.startswith('YOUR_FILE_PREFIX')]

在本地下载附件后,我将文件上传到 FTP 服务器。我用storbinary向 STOR 发送上传附件的命令。

if attachment.name not in filelist:
# Check if the attachment downloaded before
    local_path = os.path.join(local_path, attachment.name)
    with open(local_path, 'wb') as f:
        f.write(attachment.content)with FTP(ftp_server_ip) as ftp:
    ftp.login(user=username, passwd=password)
    ftp.cwd(remote_path)
    file = open(local_path, 'rb')
    ftp.storbinary('STOR {}'.format(attachment.name), file)
    file.close()

结论

我使用一个简单的 Python 脚本自动完成了这个日常工作,该脚本可以定期运行。该脚本自动化了从邮件服务器下载丢失的附件并将它们上传到 FTP 服务器的工作流。

用 Python 下载历史股票价格

原文:https://towardsdatascience.com/downloading-historical-stock-prices-in-python-93f85f059c1f?source=collection_archive---------0-----------------------

我们将寻找一种快速和自动化的方法来下载 Python 中的历史股票价格。本文将介绍如何创建分析数据集来帮助分析股票市场。

https://unsplash.com/@m_b_munsplash 拍摄的照片

打开笔记本,跟着做:

第一步:下载需要的包。

我们需要的是pandas(python 中数据科学的面包和黄油) yfinance 用于从雅虎财经下载历史股票价格, datetimetime 提供操作日期和时间的函数, requests 用于发送 HTTP 请求, io

import pandas as pd
import yfinance as yf
import datetime
import time
import requests
import io

第二步:设置日期范围

接下来,我们希望提供开始和结束日期,在此期间,我们希望每天的股票价格。下面,我提供的开始日期为 2020 年 2 月 1 日(大约是今年痛苦的开始),结束日期为 2020 年 10 月 11 日,即我执行此代码的当前日期。你可以设置任何你喜欢的开始和结束日期——但是我试图分析的是从疫情时代之前到现在的价格波动。

start = datetime.datetime(2020,2,1)
end = datetime.datetime(2020,10,11)

第三步:获取股票代码

我们想获得纳斯达克上市的股票代码。如果你确切地知道你想要的公司的历史股价,你可以跳过这一步(例如:特斯拉-> 、TSLA 、脸书- > 、FB 等)。但这里的想法是超越流行的公司,发掘一些不太知名的公司有趣的价格变动。

下面的代码将访问包含带有公司名称和股票代码的 CSV 文件的 URL,并将其转换为 pandas 数据帧。

url="[https://pkgstore.datahub.io/core/nasdaq-listings/nasdaq-listed_csv/data/7665719fb51081ba0bd834fde71ce822/nasdaq-listed_csv.csv](https://pkgstore.datahub.io/core/nasdaq-listings/nasdaq-listed_csv/data/7665719fb51081ba0bd834fde71ce822/nasdaq-listed_csv.csv)"s = requests.get(url).contentcompanies = pd.read_csv(io.StringIO(s.decode('utf-8')))

该数据集中提供的一些公司可能已被除名或无法下载。

让我们来看看这个数据集是什么样子的:

包含公司符号和信息的数据帧

从这个数据集中,让我们只提取符号,并将它们转换成一个列表。

Symbols = companies['Symbol'].tolist()

显示前 10 个股票代号的列表

步骤 4:下载历史股票价格

迭代每个股票代码,使用 yahoo finance API,下载开始和结束日期之间的每日股票价格。

追加所有个股信息并创建分析数据集。另外,请注意,有些符号可能无法下载,为此我们添加了“try”和“except”子句来处理它们。

# create empty dataframe
stock_final = pd.DataFrame()# iterate over each symbol
for i in Symbols:  

    # print the symbol which is being downloaded
    print( str(Symbols.index(i)) + str(' : ') + i, sep=',', end=',', flush=True)  

    try:
        # download the stock price 
        stock = []
        stock = yf.download(i,start=start, end=end, progress=False)

        # append the individual stock prices 
        if len(stock) == 0:
            None
        else:
            stock['Name']=i
            stock_final = stock_final.append(stock,sort=False)
    except Exception:
        None

这是最终数据集的样子。

stock_final.head()

瞧啊。对于每个股票代码和日期,我们有开盘价、最高价、最低价、收盘价和调整后的收盘价,以及交易量。

本文涵盖了股票市场分析的第一步,即创建分析数据集。下一步将是通过探索性数据分析和机器学习模型,进一步深入这个数据集。

LinkedIn 上连接,在Github上找到笔记本。****

使用 Colab 下载 Google Drive 中的 OpenImages 数据集

原文:https://towardsdatascience.com/downloading-openimages-dataset-in-google-drive-using-colab-132502f0dbde?source=collection_archive---------37-----------------------

下载您的自定义数据集

https://storage.googleapis.com/openimages/web/index.html

想要在自定义数据集上训练您的计算机视觉模型,但不想在网上搜索图像。试试 OpenImages 吧,这是一个开源数据集,拥有约 900 万张不同的图像,有 600 个对象类别和谷歌提供的丰富注释。数据集包含图像级标签注释、对象边界框、对象分段、视觉关系、本地化叙述等。

您可以根据自己的兴趣下载特定的类别,而不是下载整个数据集。在本文中,我们将使用 google colab 下载一些选定的类/类别,并将数据保存在 Google Drive 中。您也可以在本地运行时使用 jupyter notebook。

对于这篇文章,你需要一个谷歌账户和谷歌硬盘空间来下载数据。

  1. 在 Colab 中安装您的 Google Drive。

2.创建一个存储数据的文件夹。在这里,我创建了一个名为 OpenImages 的目录。

!mkdir OpenImages

3.将工作目录更改为您刚刚创建的文件夹。使用“!pwd”命令。

cd OpenImages

4.运行以下命令,下载用于训练、测试和验证的注释文件以及类文件。

*# Download required meta-files*
*!wget https://storage.googleapis.com/openimages/2018_04/class-descriptions-boxable.csv*

*!wget https://storage.googleapis.com/openimages/2018_04/train/train-annotations-bbox.csv*

*!wget https://storage.googleapis.com/openimages/2018_04/validation/validation-annotations-bbox.csv*

*!wget https://storage.googleapis.com/openimages/2018_04/test/test-annotations-bbox.csv*

5.使用 GitHub 链接将 downloadOI.py 保存在您的工作目录中(https://GitHub . com/SPM lick/learnopencv/blob/master/download open images/download oi . py)或者复制链接中的代码并直接创建文件,如下所示。(感谢SATA ya mal lick/learnopencv提供了这个令人惊叹的代码库。如果你对计算机视觉和 OpenCV 感兴趣,一定要看看这个神奇的 Github 库。

#This magic function is used to create the files.downloadOI.py is the file name
%%writefile downloadOI.py#Author : Sunita Nayak, Big Vision LLC

#### Usage example: python3 downloadOI.py --classes 'Ice_cream,Cookie' --mode train

import argparse
import csv
import subprocess
import os
from tqdm import tqdm
import multiprocessing
from multiprocessing import Pool as thread_pool

cpu_count = multiprocessing.cpu_count()

parser = argparse.ArgumentParser(description='Download Class specific images from OpenImagesV4')
parser.add_argument("--mode", help="Dataset category - train, validation or test", required=True)
parser.add_argument("--classes", help="Names of object classes to be downloaded", required=True)
parser.add_argument("--nthreads", help="Number of threads to use", required=False, type=int, default=cpu_count*2)
parser.add_argument("--occluded", help="Include occluded images", required=False, type=int, default=1)
parser.add_argument("--truncated", help="Include truncated images", required=False, type=int, default=1)
parser.add_argument("--groupOf", help="Include groupOf images", required=False, type=int, default=1)
parser.add_argument("--depiction", help="Include depiction images", required=False, type=int, default=1)
parser.add_argument("--inside", help="Include inside images", required=False, type=int, default=1)

args = parser.parse_args()

run_mode = args.mode

threads = args.nthreads

classes = []
for class_name in args.classes.split(','):
    classes.append(class_name)

with open('./class-descriptions-boxable.csv', mode='r') as infile:
    reader = csv.reader(infile)
    dict_list = {rows[1]:rows[0] for rows in reader}

subprocess.run(['rm', '-rf', run_mode])
subprocess.run([ 'mkdir', run_mode])

pool = thread_pool(threads)
commands = []
cnt = 0

for ind in range(0, len(classes)):

    class_name = classes[ind]
    print("Class "+str(ind) + " : " + class_name)

    subprocess.run([ 'mkdir', run_mode+'/'+class_name])

    command = "grep "+dict_list[class_name.replace('_', ' ')] + " ./" + run_mode + "-annotations-bbox.csv"
    class_annotations = subprocess.run(command.split(), stdout=subprocess.PIPE).stdout.decode('utf-8')
    class_annotations = class_annotations.splitlines()

    for line in class_annotations:

        line_parts = line.split(',')

        #IsOccluded,IsTruncated,IsGroupOf,IsDepiction,IsInside
        if (args.occluded==0 and int(line_parts[8])>0):
            print("Skipped %s",line_parts[0])
            continue
        if (args.truncated==0 and int(line_parts[9])>0):
            print("Skipped %s",line_parts[0])
            continue
        if (args.groupOf==0 and int(line_parts[10])>0):
            print("Skipped %s",line_parts[0])
            continue
        if (args.depiction==0 and int(line_parts[11])>0):
            print("Skipped %s",line_parts[0])
            continue
        if (args.inside==0 and int(line_parts[12])>0):
            print("Skipped %s",line_parts[0])
            continue

        cnt = cnt + 1

        command = 'aws s3 --no-sign-request --only-show-errors cp s3://open-images-dataset/'+run_mode+'/'+line_parts[0]+'.jpg '+ run_mode+'/'+class_name+'/'+line_parts[0]+'.jpg'
        commands.append(command)

        with open('%s/%s/%s.txt'%(run_mode,class_name,line_parts[0]),'a') as f:
            f.write(','.join([class_name, line_parts[4], line_parts[5], line_parts[6], line_parts[7]])+'\n')

print("Annotation Count : "+str(cnt))
commands = list(set(commands))
print("Number of images to be downloaded : "+str(len(commands)))

list(tqdm(pool.imap(os.system, commands), total = len(commands) ))

pool.close()
pool.join()

6.目录 OpenImages 中的内容应该是这样的

目录的内容

7.运行以下命令以避免“AWS:not found sh:1:AWS:not found”错误。

!pip install awscli

8.下载特定数据。在这里我下载了 2 个类水槽马桶。您可以尝试多个类并下载数据。你可以在“class-descriptions-box able . CSV”中找到所有的类名。

*# Download Sink and Toilet images for test* 
!python3 downloadOI.py --classes "Sink,Toilet" --mode test*# Download Sink and Toilet images for train* !python3 downloadOI.py --classes "Sink,Toilet" --mode train*# Download Sink and Toilet images for validation* !python3 downloadOI.py --classes "Sink,Toilet" --mode validation

有 3 种模式可供选择

a) —模式训练 :下载训练数据

b) —模式测试 :下载测试数据

c) —模式验证 :下载验证数据

这是下载数据的外观

每个类别都有一个图像文件以及文本文件中的注释。

  • 文件路径:OpenImages/train/Sink/01681d52ad599ab4.jpg
  • 图像文件:01681d52ad599ab4.jpg
  • 文本文件:01681d52ad599ab4.txt
  • 文本文件内容:Sink,0.249529,0.420054,0.659844,0.682363

。txt 文件具有边界框的尺寸。如果图像有多个对象,它可以有多个条目。

注意:请记住,每次运行这个命令时,旧的数据都会被删除。因此,如果你想再次使用该命令,最好在其他文件夹中尝试,以避免删除之前下载的数据。

仅此而已。使用它并下载自定义数据来训练您的自定义计算机视觉模型。

Github 链接到代码https://github . com/mringup/Colab/blob/master/Downloading _ open images _ Custom _ dataset . ipynb

下载股票数据并直观地展示出来

原文:https://towardsdatascience.com/downloading-stock-data-and-representing-it-visually-6433f7938f98?source=collection_archive---------31-----------------------

使用 YFinance 和 Plotly 库进行股票数据分析

Alec Favale 在 Unsplash 上的照片

在本文中,我将向您解释如何使用 python 库 YFinance ,该库旨在通过提供一种可靠的、线程化的 python 方式从 Yahoo!下载历史市场数据,从而解决下载股票数据的问题金融。

在后面的部分中,我们将看到如何使用这些数据,通过使用 python 库来绘制不同的视觉上吸引人且高度互动的财务图表。plotly Python 库是一个交互式的开源绘图库,支持 40 多种独特的图表类型,涵盖了广泛的统计、金融、地理、科学和三维用例。

让我们开始吧。最初,我们将从安装 YFinace 库开始,我们将使用它来下载股票数据并查看它的一些特性。

安装 YFinance

在命令提示符下运行下面给出的命令,使用 pip 安装 yfinance。

pip install yfinance

在 Jupyter 笔记本中探索 YFinance 库

让我们从导入库和下载股票数据开始。这里我使用的股票代码是 HINDPETRO。这是印度斯坦石油公司,你可以选择任何股票进行分析,只需用你的股票代码替换股票代码。

 #importing Library
import yfinance as yf#setting the ticker 
hindpetro = yf.Ticker("HINDPETRO.NS")#Display stock information
hindpetro.info

这显示了与我们正在查看的公司相关的所有信息。

现在让我们探索一下 YFinance 库提供的一些功能。这只是一个小例子,还有更多,你可以在这里探索

# Dsiplay all the actions taken in the lifetime of the stock i.e    # dividends and splits with the dates when they are providedhindpetro.actions

显示股票行为,即股息和拆分以及各自的日期

类似地,你可以使用下面给出的命令来分别显示查看股票股利和股票分割。

#Display Dividends
hindpetro.dividends#Display Splits
hindpetro.splits

现在让我们将数据下载到数据框中并显示出来。

df = hindpetro.history(period="max")
df

HindPetro 从上市之日到今天的历史数据。

为了执行进一步的操作,我们需要重置数据帧的索引,并将相应的列转换为 float 数据类型。下面给出的命令将解决我们的目的。

#Reseting the index
df = df.reset_index()#Converting the datatype to float
for i in ['Open', 'High', 'Close', 'Low']:
    df[i] = df[i].astype('float64')

在这之后,让我们从可视化部分开始。首先,我们需要安装 Plotly。

安装 Plotly

pip install plotly

使用带范围滑块和按钮的 Plotly Graph_objects 创建折线图

折线图常用于时间序列分析,用于查看一段时间内的股票趋势。在这里,我将向您解释如何使用 Plotly 创建交互式折线图。以下命令将创建在最大时间段内存储在数据框中的股票数据的折线图。

该代码还包括用于创建按钮的行,这些按钮可以被选择来显示特定时间段的折线图。

import plotly.graph_objects as go
import pandas as pdfig = go.Figure([go.Scatter(x=df['Date'], y=df['High'])])fig.update_xaxes(
    rangeslider_visible=True,
    rangeselector=dict(
        buttons=list([
            dict(count=1, label="1m", step="month",                                        
                 stepmode="backward"),
            dict(count=6, label="6m", step="month",  
                 stepmode="backward"),
            dict(count=1, label="YTD", step="year", 
                 stepmode="todate"),
            dict(count=1, label="1y", step="year", 
                 stepmode="backward"),
            dict(step="all")
        ])
    )
)
fig.show()

带有范围选择器和范围选择按钮的股票数据折线图。

创建 OHLC(开盘、盘高、盘低、收盘)图

OHLC 图是一种棒线,显示每个时期的开盘价、最高价、最低价和收盘价。 OHLC 图表很有用,因为它们显示了一段时间内的四个主要数据点,收盘价被许多交易者认为是最重要的。

下面给出的代码将创建一个带有范围选择器的 OHLC 图表。

带范围选择器的 OHLC 图表

使用范围滑块创建烛台图表

烛台图表被交易者用来根据过去的模式决定可能的价格变动。烛台在交易时很有用,因为它们在交易者指定的时间内显示四个价格点(开盘价、收盘价、最高价和最低价)。

带有范围滑块的烛台图表

创建面积图

面积图或面积图以图形方式显示定量数据。它基于折线图。轴和线之间的区域通常用颜色、纹理和影线来强调。

下面给出的代码将创建股票数据的面积图。

股票数据面积图

所有这些图表都是使用 Plotly 创建的,以便您可以与图表进行交互。上面提到的所有图表都是用于财务分析的主要图表。

结论

在本文中,我们从下载股票数据开始,并使用 YFinance 执行不同的操作/功能。之后,我们使用 Plotly 绘制了不同的财务图表,用于财务/股票数据分析。

[## 逐步了解数据分析

对数据集应用数据分析以获得关于数据的见解。

towardsdatascience.com](/understanding-data-analysis-step-by-step-48e604cb882) [## 从头开始创建 Streamlit 仪表板。

Streamlit 是一个很棒的工具,可以轻松构建视觉上吸引人的仪表板。

towardsdatascience.com](/creating-streamlit-dashboard-from-scratch-59316a74fa1)

在你走之前

感谢 的阅读!如果你想与我取得联系,请随时通过 hmix13@gmail.com 联系我或我的 LinkedIn 个人资料 。也可以在我的Github中查看我在这里使用过的代码和数据集。另外,请随意浏览 我的简介 并阅读我写的与数据科学相关的不同文章。

为深度学习中的人体动作识别下载动力学数据集

原文:https://towardsdatascience.com/downloading-the-kinetics-dataset-for-human-action-recognition-in-deep-learning-500c3d50f776?source=collection_archive---------10-----------------------

关于下载程序的学习、挑战和见解

如果你有兴趣对人类活动或动作识别进行深度学习,你一定会遇到由 deep mind 发布的动力学数据集。数据集有 3 个主要版本;动力学 400、动力学 600 和动力学 700 版本。在写这篇博客的时候,Kinetics 700 是最新的版本。

deep mind 网站上对 Kinetics 700 数据集的描述是:

这是一个大规模、高质量的 URL 数据集,链接到大约 650,000 个视频剪辑,涵盖 700 个人类动作类别,包括演奏乐器等人机交互,以及握手和拥抱等人机交互。每个动作类至少有 600 个视频剪辑。每个剪辑都由人类用一个动作类进行注释,持续大约 10 秒钟。

上述上下文中的 URL 链接指的是 YouTube URL 链接,因此,这些视频就是 YouTube 视频。

该数据集正在成为人类活动识别的标准,并越来越多地被用作几篇动作识别论文的基准,以及用于处理视频数据的深度学习架构的基线。Kinetics 数据集的主要愿景是成为视频数据的 ImageNet 等价物。

这篇博客将介绍从注释文件下载视频的步骤,以及面临的挑战和一些应对挑战的策略。它将突出显示一些关于数据的基本统计数据,如果您选择自己下载,这些数据有望帮助您做出明智的决定。然而,它不会进入关于注释数据集的太多细节,例如它是如何被收集的,不同类的分布等等。这些信息可以通过阅读以下文章找到:

创建了一个动力学数据集资源管理器,以便于可视化数据。探险家可以在http://kinetics-explorer.com/上找到

获取动力学注释数据集

相对于 ImageNet 或 COCO 等价物,处理动力学数据集时最大的难点是没有实际的视频可供下载。在适当的位置,提供一个注释文件,该文件包含 json 和 csv 格式的条目列表,这些条目包含 YouTube URL 链接、动作类别以及视频中动作类别的开始和结束时间。

这意味着你必须自己下载视频,并在正确的时间范围内进行裁剪。大约有 650,000 个视频,因此这不是一个容易的任务,因为我们将在后面讨论各种挑战。

注释文件可以从下面的链接下载。下面是你应该看到的截图。

动力学 700 是这个博客的焦点数据集。单击“下载数据集”链接,下载包含注释文件的 25 MB gzip 文件。提取 gzip 文件的内容后,有 3 个文件夹,其中包含两种文件格式(csv 和 json)的 train、val 和 test 数据集。csv 文件的结构是:

label,youtube_id,time_start,time_end,split
testifying,---QUuC4vJs,84,94,validate
washing feet,--GkrdYZ9Tc,0,10,validate
air drumming,--nQbRBEz2s,104,114,validate
.
.
.

CSV 文件中的项目可以细分如下:

  • label表示在视频中发现了什么类型的人类活动,例如testifyingwashing feetair drumming等。
  • youtube_id是 YouTube 为每个视频使用的唯一视频标识符。将youtube_id替换成下面的字符串[https://www.youtube.com/watch?v=](https://www.youtube.com/watch?v=){youtube_id},可以下载完整的视频。
  • time_starttime_end(以秒为单位)表示在视频中发现由label表示的人类活动的部分。以标签为testifying的 csv 样本的第一行为例,视频的长度为 95 秒(可以从https://www.youtube.com/watch?v=-屈科维兹中验证),因此感兴趣的标签将在 84-94 秒之间,这构成了时间范围。
  • split表示它是否属于训练、验证或测试数据集。

json 文件的结构如下,从 csv 上下文来看应该很容易理解:

{
 "---QUuC4vJs": {
  "annotations": {
   "label": "testifying",
   "segment": [
    84.0,
    94.0
   ]
  },
  "duration": 10.0,
  "subset": "validate",
  "url": "[https://www.youtube.com/watch?v=---QUuC4vJs](https://www.youtube.com/watch?v=---QUuC4vJs)"
 },
 "--GkrdYZ9Tc": {
  "annotations": {
   "label": "washing feet",
   "segment": [
    0.0,
    10.0
   ]
  },
  "duration": 10.0,
  "subset": "validate",
  "url": "[https://www.youtube.com/watch?v=--GkrdYZ9Tc](https://www.youtube.com/watch?v=--GkrdYZ9Tc)"
 },
.
.
.
.
}

json 文件比 csv 文件大得多,占用 197.5 MB 内存,而不是 24.5 MB,所以从 csv 文件读取数据可能比从 json 文件读取数据快一点。然而,大多数能够从注释文件下载动力学数据集的开源软件使用 json 格式,因此可能需要将 csv 数据预处理为正确的格式。就我个人而言,我选择了 JSON 格式,因为我最终使用了开源代码库。

技术环境

数据下载主要是在运行 Ubuntu 18.04 的台式电脑上进行的,该电脑具有稳定的互联网连接,下载速度约为 60 Mb/s,内存为 16 GB。然而,有些下载是在我不使用 MacBook Pro 的时候进行的。

我确实尝试过使用 AWS 和 Google Cloud,但是 YouTube 存在明显的节流问题,这将在错误部分解决。

下载数据的代码库

接下来要考虑的是下载数据的代码库。有两个主要选项:

  • 自己写代码库。
  • 找到一个现有的开源代码库,如有必要,根据需要修改它。

选择了第二个选项,选择的代码库是showmax/kinetics-downloader,它的一个分支是在dance Logue/kinetics-datasets-downloader中创建的。使用代码库的主要要求是python ≥ 3.4[ffmpeg](https://www.ffmpeg.org/)[youtube-dl](https://github.com/ytdl-org/youtube-dl)。其中[youtube-dl](https://github.com/ytdl-org/youtube-dl)用于进行实际下载,而[ffmpeg](https://www.ffmpeg.org/)用于在所需的片段(即time_starttime_end时间)裁剪视频。

如何使用代码库包含在 README.md 文件中,因此我们不会深入研究代码。值得注意的是,它使用了 python 多重处理模块,我发现在下载如此大的数据集时这是必要的,我们将在这篇博客中解释原因。

根据下载数据集时遇到的问题进行了一些修改。对代码库的修改包括:

  • 能够写入一个stats.csv文件,以跟踪每次下载花了多长时间,以及每个视频的 ffmpeg 裁剪时间的持续时间。不幸的是,创建这个功能的直觉只在数据集下载了一半之后才出现。因此,统计数据并没有覆盖整个样本,但应该足以深入了解下载过程。
  • 能够写入一个failed.csv文件,以表明哪些视频有错误,以及返回的错误是什么。
  • 一旦发生限制,能够暂停下载过程。

统计数据和失败日志用于生成关于数据的基本统计数据,如果您选择自己下载数据,它们有望帮助您做出明智的决策。

总体统计

YouTube 是一个动态的*台,这意味着视频会一直被添加和删除。因此,由于视频被删除,在不同时间下载动力学数据集将不会有一致的结果。下面的饼图显示了我的 kinetics 数据集中已下载和缺失的视频。

总下载视频数为 631604,而失败视频数为 15380,这意味着在总共 646984 个视频中,整个数据集的 2.37 %无法下载。假设这在可接受的误差范围内。

下载拆分

下面的饼图显示了在训练集、测试集和验证集之间下载的视频的划分。

正如所料,大多数视频由训练集数据组成,占数据集的 83.94 %。测试集占数据集的 10.13 %,而验证集占数据集的 5.93 %。

总下载持续时间

为了计算下载整个数据集需要多长时间,下载时间和生成裁剪视频所需的时间(FFMPEG 持续时间)以秒为单位进行记录。如前所述,仅记录了 298651 个视频的统计数据。下表显示了各个过程的*均值和最大值。

完整表示整个数据集,而 IQR 表示在四分位数范围内的数据。获取四分位数据对于防止极端异常值是必要的,如下载持续时间和 FFMPEG 持续时间的高最大值所示。按顺序下载 646984 个视频的理论时间是:

  • 使用完整*均值,预计下载时间为 176.1 天
  • 根据 IQR *均值,预计下载时间为 80.7 天

这假设视频是同步下载的,没有任何中断。幸运的是,多重处理对我们有利。我使用 python multiprocessing模块运行 16 个独立的进程。

下面的饼图显示了下载主导任务和 ffmpeg(裁剪)主导任务之间的主导过程。

可以看出,对于大部分下载过程,实际下载过程占主导地位,而 ffmpeg 过程仅占 1.67 %的时间占主导地位。因此,整个过程中的主要瓶颈实际上是从 YouTube 下载视频。

最佳化

我在下载动力学数据集时犯的第一个错误是下载了比必要质量更高的视频(这可能表明为什么会有非常极端的异常值)。

最终我选定了最大分辨率为 360p 的视频,毕竟这些视频是给机器看的,而不是给人看的。这种质量的视频包含足够的信息来训练相关的深度学习算法,并且下载和裁剪速度明显更快,在存储期间占用的磁盘空间更少。可以认为,也可以尝试较低的分辨率,即 240p 或 144p,这将在下载期间节省大量空间和时间,同时保持相同的基线/基准精度。

空间要求

我们进行了一次快速计算,以确定空间需求,结果发现整个裁剪数据集占用了 628.43 GB 的磁盘空间。为了下载数据集,您可能需要大约 20 GB 的额外空间(取决于并发下载的数量)来容纳需要临时存储的完整的未裁剪视频。

失败的视频下载

2.37 %的视频下载失败的原因被记录下来,并显示在下面的饼状图中。图例中描述旁边的数字是发生特定错误的实例总数。

大多数错误都是基于 YouTube 的错误消息,描述是一组错误的指示器。这些是:

  • 视频不可用(10606) 错误是目前最大的失败原因,包括各种原因,如上传者删除了他们的 YouTube 帐户或他们的帐户被 YouTube 删除,视频仅在某些国家可用,视频被设为私有等。
  • 内容警告(2451) 错误
  • ****HTTP 错误404(943)错误可能是由于 Kinetics 视频youtube_id出错,因为 404 通常表示未找到页面错误代码。但是我没有时间去研究这个假设。
  • Copyright (672) 错误是由于版权索赔而被删除的视频。
  • 视频被用户删除(337) 错误顾名思义,用户删除了视频。
  • 杂项(144) 错误可能是由于与正在使用的库有关的错误,或者无法确定错误原因。
  • 违反 YouTube 条款(134) 错误通常是因为违反了关于垃圾邮件、种族主义、欺凌、裸体等的社区准则而被删除的视频。
  • 重复视频(2) 错误似乎表明 YouTube 不允许重复视频。
  • ****HTTP 错误503(1)错误仅出现一次,并且与服务未找到错误相关,不确定为什么会出现这种情况。

尽管下载视频存在问题,但失败的视频仅占整个数据集的 2.37 %,可以认为是在可接受的误差范围内。然而,值得注意的是,随着时间的推移,随着越来越多的视频被删除,失败视频的比例将会增加。

尽管这些是阻止视频下载的错误,但有一个错误被证明是下载 YouTube 视频时最令人沮丧的经历,那就是可怕的 429 太多请求错误

HTTP 错误 429:请求太多

这是迄今为止下载动力学数据集的最大难点,这也是我在下载过程中的感受。

https://img flip . com/meme template/29364527/卢克-天行者-哭泣

这个错误的主要原因是由 YouTube 节流请求引起的,我认为这是通过将请求 ip 地址列入黑名单来实现的。YouTube 限制请求是有意义的,其中一些原因包括减少服务器的负载,防止恶意方访问数据等。但是下载 650 000 个视频剪辑是一件痛苦的事情。

尤其具有挑战性的是请求 ip 地址再次被允许所花费的时间,即“冷却”期。根据经验,这需要 12 小时到 5 天的时间。我找不到一个可辨别的模式来绕过它。在被限制之前,我在单个会话中能够下载的最大视频量是 136963,下面的饼状图显示了运行之间的分布(一些运行被手动终止,而不是被限制)。

节流问题已经在不同来源中被强调为从 YouTube 下载数据的主要障碍。

工作区

据我所知,一个 ip 地址被列入黑名单的标准还不清楚。在我的家庭桌面上,我可以在遇到 429 错误代码之前下载超过 50,0 00 个视频,然而,转移到 AWS 或 Google cloud,我可能会在遇到 429 错误之前下载 100 个视频。也许 YouTube 使用一些标准来立即将来自云虚拟机和个人机器的 ip 地址列入黑名单。

当遇到 HTTP 错误 429 时,最好停止下载,稍后重试或更改 IP 地址。

我能想到的主要可行方案是通过切换网络来改变 IP 地址。在同一台机器上运行两种不同的操作系统(例如 Windows 和 Ubuntu)已经有一段时间了。如果其他方法都失败了。,等待冷静期。

由于当时下载数据集并不是一个很重要的优先事项,当所有网络解决方案都遇到 HTTP 错误 429 状态时,数据集的下载就停止了,并在几天后进行了尝试。我没有探索其他选择,如使用 VPN 等。

伦理学

到目前为止还没有涉及的一个主要话题是道德,即抓取 YouTube 视频。一方面,视频的注释文件是存在的,并且是由谷歌的子公司 Deepmind 提供的,另一方面,下载数据集的规则是什么,特别是对于深度学习研究。有相当多的报纸利用数据显示人们正在下载它。感觉就像头埋在沙子里一样。

这可能是数据没有公开的原因,因此,任何对深度学习感兴趣的人都必须自己下载。这种方法有几个问题,我认为是:

  • 首先,它阻碍了利用视频数据的深度学习研究,因为动力学数据集不是下载的微不足道的数据集。
  • 由于缺少视频,两个不同研究人员之间的数据集可能不同,这意味着研究论文中报告的结果可能不完全可重复。

不知道在公开数据的过程中,关于道德状况的解决办法是什么,但希望 Deepmind 能够让视频数据很容易被非商业用途获得。

结论

希望这篇博客给了你一些关于下载动力学数据集的见解,以及你自己尝试时所面临的挑战。

动力学数据集是必要的,因为我在 2019 年全年开展了一个关于为舞蹈深度学习初创公司建立 Shazam 的个人项目。动力学数据用于预训练 dance 算法作为概念的证明。我将很快在博客上记录这个过程。

如果您有任何问题或任何需要澄清的事情,您可以在 https://mbele.io/mark和我预约时间

使用 Python 制作的 DPMO 海图

原文:https://towardsdatascience.com/dpmo-chart-with-python-f495308905cc?source=collection_archive---------42-----------------------

面向工业工程师的 Python

使用 Python 库创建质量控制图

图片由 chuttersnap 拍摄,可在 Unsplash 获得

质量控制图

质量控制图是工程师监控一个过程是否在统计控制下的重要工具。它们有助于可视化变化,发现并纠正出现的问题,预测预期的结果范围,并分析特殊或常见原因导致的流程变化模式。质量控制图常用于精益六适马项目和 DMAIC 项目的控制阶段,被认为是过程改进的七个基本质量工具之一。

DPMO 控制图

DPMO(每百万个机会的缺陷)图代表了一种较新的属性控制图,用于在缺陷机会远大于一个时跟踪 dpmo 值。DPMO 图是为电子制造环境开发的,作为评估生产多种高度复杂产品的过程的一种方法。

相关计算

从每个样品中获得缺陷总数后,需要进行以下计算来构建 DPMO 图:

  • 每单位缺陷:每单位发现的缺陷总数。

  • 每百万机会的缺陷数:每百万机会的预期缺陷数。

控制线

以下控制线包含在 dpmo 图表中,有助于确定流程是否处于统计控制之下:

  • 中心线:

  • 控制上限:

  • 控制下限:

在下面的例子中,让我们为一个微电子元件建立一个 dpmo 图表,其中获得了 40 个样本,每个样本 10 个单元,每个单元有 2,751 个缺陷机会。让我们来看看 Python 代码!

根据上面的 dpmo 图,该过程似乎处于统计控制之下,因为没有一个 dpmo 点超过控制上限。甚至对于 40 个样品中的 3 个(即样品 25、31 和 32)也没有发现缺陷。考虑到本例的 dpmo *均值约为 115 dpmo,流程σ(即流程相对于客户要求的变化量,表示为正态分布的标准偏差数)接* 5.30。

总结想法

质量控制图是分析流程稳定性和获取重要统计信息的重要工具,可用于精益六适马和 DMAIC 项目的流程改进。质量和工业工程师必须能够准确地解释它们,以识别可能导致潜在不合格的不良趋势,从而采取预防措施而不是纠正措施,从而减少废料和浪费。

本指南涵盖了如何使用多个 Python 库从头构建 DPMO 图表的分步教程。考虑到 Python 在专业人士和学者中的高受欢迎程度,Python 是一个很好的工具,能够为统计目的构建质量控制图表。虽然也有其他程序和软件可以构建它们(例如 Minitab、R、Microsoft Excel),但质量和工业工程师应根据他们的编码和分析技能决定使用哪一种,同时符合组织的目标和客户的规格。

如果你觉得这篇文章有用,欢迎在 GitHub 上下载我的个人代码。你也可以直接在 rsalaza4@binghamton.edu 给我发邮件,在LinkedIn上找到我。有兴趣了解工程领域的数据分析、数据科学和机器学习应用的更多信息吗?通过访问我的媒体 简介 来探索我以前的文章。感谢阅读。

——罗伯特

机器学习管道的拖放工具——值得一试吗?

原文:https://towardsdatascience.com/drag-and-drop-tools-for-machine-learning-pipelines-worth-a-try-63ace4a18715?source=collection_archive---------30-----------------------

比较机器学习的 6 个免费可视化编程工具的免费版本限制、互操作性和模型动物园。

拖放式机器学习管道与数据科学工具

几周前,我会说拖放式机器学习工具永远不会比开源编程语言的灵活性更好,如果必要的话,结合笔记本。

像许多数据科学家一样,我一直在用 Python 和 R 进行机器学习:从数据探索到可视化、模型拟合和比较等。

最*,我看到我周围有多个人在使用拖放式机器学习工具,这让我很好奇。考虑了一下,我认为如果我能找到一个免费的拖放式机器学习工具,拥有所有重要的模型,并且可以很容易地将拟合的模型导出到其他语言,那么至少值得一试。

我花了一些时间列出这项工作的现有工具,并验证它们是否满足这些基本要求。我在这篇文章中分享我的基准。

基准测试的拖放工具(来源:dataiku.com,mljar.com,orange.biolab.si,cs.waikato.ac.nz/ml/weka/, knime.com,rapidminer.com)

拖放式机器学习管道—基准

我对这种工具的使用是模型比较。

最低要求:

  • 机器学习管道的拖放基准测试。
  • 比 Jupyter 笔记本更容易使用(相当有挑战性)。
  • AutoML 工具被排除在基准测试之外(因为这不是我们的目标)

除此之外,我将在以下几点测试产品:

  1. 免费或者至少有一个合理的免费版本 因为如果我看不到免费版本的附加价值,我不会考虑购买它。
  2. 可与其他编程语言互操作
    因为我显然不想强迫任何人使用该产品,所以需要一种简单的方法将我所做的导出到另一种语言。
  3. 好的模型动物园,那包括深度学习

用于拖放机器学习管道的现有工具

浏览互联网,我发现了一些工具。其中一些人提议免费版本,而另一些人则没有。目前我真的在寻找一个免费的工具,所以我没有深入研究付费工具。

提出免费版本的:

那些不推荐免费版本的(试用期不被认为是免费版本):

RapidMiner 标志(来源:rapidminer.com)

回顾 1 — RapidMiner 工作室

链接:https://rapidminer.com/products/studio/

RapidMiner 定价或免费版本

  • 免费版:10,000 个数据行,1 个逻辑处理器,社区支持,30 天企业试用
  • 专业版:每用户每年 7,500 美元:100,000 个数据行,2 个逻辑处理器,企业支持,Turbo Prep,自动模式
  • 企业版:每用户每年 15,000 美元:无限数据行、无限逻辑处理器、企业支持、Turbo Prep、自动模型、自动化模型操作、后台流程执行

RapidMiner 互操作性/导出模型

根据他们网站上的支持页面,RapidMiner 似乎支持 PMML 的一些型号,但不是全部。

RapidMiner 模型动物园

RapidMiner 模型动物园好像挺不错的。有人支持使用 H2O 进行深度学习。

RapidMiner 结论

RapidMiner 的免费版本只支持 10000 个数据行和 1 个逻辑处理器。这是如此有限,以至于对我来说,不值得测试他们的解决方案。

达泰库标志(来源:dataiku.com)

审查 2 —大台库

链接:https://www.dataiku.com/product/features/machine-learning/

大台库定价或免费版

Dataiku 的免费版有两种可能:

  • 安装它永远免费:无限的数据处理,数据在您的基础设施,多达 3 个用户
  • 或者,让 Dataiku 托管它:有限的处理能力,只有文件,单用户

这个免费版我好像可以接受,那就来下一点吧。

Dataiku 互操作性/导出模型

有几个导出模型的选项:

  • 使用 Dataiku API 进行实时评分。
    很酷的功能,但是免费版当然没有。
  • 使用 PMML
    对我来说很有趣,但不幸的是这需要一个“第二层支持级别”,我在免费版本中不会有。
  • 导出到 Python 笔记本
    Dataiku 的警告通知让我有点害怕“这个特性并不支持所有算法”“这个生成的笔记本仅用于教育和解释目的。特别是,本笔记本没有再现 DSS 的所有预处理功能,而只是 DSS 中训练的模型的最佳*似值。”

大台库模型动物园

Dataiku 可以使用 Python 的 scikitlearn 作为建模引擎。车型数量比较好。还有对深度学习的支持。

达泰库结论

Dataiku 似乎是一个很好的检查工具。如果我继续做下去,Dataiku 的互操作性将是第一个要测试的东西,但现在它还不是一个障碍。

Weka 标志(来源:https://www.cs.waikato.ac.nz/ml/weka/)

回顾 3 — Weka

链接:https://www.cs.waikato.ac.nz/ml/weka/

Weka 定价或免费版

Weka 的 GUI 不如 RapidMiner 和 Dataik 流畅。它似乎介于 GUI 工具和代码的 GUI 包装器之间,所以我不确定它是否比使用 Python 笔记本有优势。

但是 Weka 是免费和开源的:这太棒了,这也是我把它放在列表中的原因。

Weka 互操作性/导出模型

我没有发现 Weka 是否提出了一个按钮点击选项来导出模型。Weka 使用来自 scikit learn 的模型,因此使用 Weka 建立模型并使用 Scikit Learn 重新拟合模型会很容易。

3.3 Weka 模型动物园

如前一点所述,Weka 用的是 Scikit Learn 的模型,对我来说不错。还支持用 deaplearning4j 进行 deap 学习。

3.4 Weka 结论

Weka 似乎是一个可以接受的工具:最大的问题是,与使用 Jupyter 笔记本相比,它是否有附加值。我需要测试一下才能确定。

MLjar 标志(来源:mljar.com)

回顾 4 — MLjar

链接:https://mljar.com/

MLjar 定价或免费版本

MLjar 有一个免费版本,数据集限制为 0.25 GB,30 天的项目历史和 5 个积分。1 个信用是 1 个计算小时,所以只有 5 个小时的使用是完全免费的。这远远不足以做一些严肃的事情。

MLjar 互操作性/导出模型

我没有找到从 MLjar 导出模型的方法。他们似乎有一个 API,但不清楚是仅用于模型构建还是也用于预测。

MLjar 模型动物园

MLjar 模型动物园的分类模型只有二元分类。这个对我来说太局限了。

MLjar 结论

MLjar 似乎开始了一些有趣的事情,但就目前而言,他们的解决方案对于价格和非常有限的免费版本来说似乎不够好。

Knime 标志(来源:knime.com)

回顾 5 — Knime 分析*台

链接:https://www.knime.com/knime-analytics-platform

Knime 定价或免费版本

Knime 有一个免费的开源版本,看起来相当强大:太棒了!

Knime 互操作性/导出模型

Knime 有可能与 PMML 一起出口模型。在付费版本中构建 API 是可能的。

克尼梅模型动物园

Knime model zoo 看起来相对不错,还包括深度学习。

Knime 结论

Knime 给我留下了非常好的印象,因为他们有一个非常精致的免费版本,良好的互操作性,以及一个很好的模型列表。GUI 看起来也很流畅。而且开源!这值得一查。

橙色标志(来源:orange.biolab.si)

审查 6—橙色

链接:【https://orange.biolab.si/getting-started/

橙色定价或免费版本

Orange 完全免费开源:牛逼!

橙色互操作性/导出模型

将模型保存为泡菜是可能的。然后这个泡菜就可以用 orange 导入 Python 了。使用 Pickle 似乎不是满足我需求的最佳解决方案:我希望存储模型并能够用另一个框架打开它。

橙色模型动物园

橘子模型动物园看起来可以接受,但是不支持深度学习。

橙色结论

橙色有一些很好的特点。它是开源的,看起来相当流畅。不幸的是,Orange 的互操作性部分非常糟糕。

获胜者是……Knime!

有两个工具我会考虑更详细地测试:

  1. Knime 似乎是最好的选择,因为我真的很喜欢它是开源的。Knime 给我留下了非常好的印象,因为他们有一个非常精致的免费版本,良好的互操作性,以及一个很好的模型列表。GUI 看起来也很流畅。而且开源!这值得一查。
  2. Dataiku 似乎是一个很好的检查工具。它的付费版本似乎没有太多的限制,它似乎很强大。

其他工具各有其特定的缺点:

  • RapidMiner 的免费版本只支持 10000 个数据行和 1 个逻辑处理器。这是如此有限,以至于对我来说,不值得测试他们的解决方案。
  • Weka 似乎是一个很好的产品:最大的问题是,与使用 Jupyter 笔记本相比,它是否有附加值。
  • MLjar 似乎开始了一些有趣的事情,但就目前而言,他们的解决方案对于所要求的价格和非常有限的免费版本来说似乎不够好。
  • 橙色有一些很好的特点。它是开源的,看起来相当流畅。不幸的是,Orange 的互操作性部分非常糟糕。

感谢你阅读我的文章,希望对你有用。不要犹豫,继续关注更多!

用 R 画一个雷达/蜘蛛图

原文:https://towardsdatascience.com/draw-a-radar-spider-plot-with-r-4af9693c3237?source=collection_archive---------50-----------------------

工具

奥兰多泡沫中的 NBA 季后赛联盟老大是谁?

斯蒂芬·瓦伦丁在 Unsplash 上拍摄的照片

我在我的读者群中尝试了几种不同类型的 NBA 分析文章,他们是一群真正的篮球迷。我发现最受欢迎的文章是而不是那些具有最先进的机器学习技术的文章,而是那些带有直观而有意义的图表的文章。

在我作为数据科学家的职业生涯的某个阶段,我意识到传递信息比展示花哨的模型更重要。也许这就是为什么线性回归仍然是金融界最流行的模型之一。

在这篇文章中,我将谈论一个简单的话题。如何绘制蜘蛛图,或雷达图是比较分析中最重要的图形之一。我正在用 r 实现代码。

数据

2019–2020 NBA 季后赛 NBA 球员场均基本统计和高级统计。(来自篮球参考)

密码

让我们首先在蜘蛛图中可视化詹姆斯·哈登的统计数据。我们只关注五个数据:得分,TRB,助攻,抢断和 BLK。

df = read.csv("playoff_stats.csv")
maxxx = apply(df[,c("PTS.","TRB","AST","STL","BLK")],2,max)
minnn = apply(df[,c("PTS.","TRB","AST","STL","BLK")],2,min)

在这个块的代码中,数据被读取到数据帧“df”中。并且计算每列的最大值和最小值,因为这些值对于定义蜘蛛图中数据的边界是有用的。

例如,我提取了詹姆斯·哈登和勒布朗的数据进行分析。

df_sel = df[c(3,10),c("PTS.","TRB","AST","STL","BLK")]
rownames(df_sel) = c("Harden","Lebron")

要定义蜘蛛图的功能,我们需要加载fmsb包。

comp_plot = function(data,maxxx,minnn){
    library(fmsb)
    data = rbind(maxxx, minnn, data)
    colors_border=c( rgb(0.2,0.5,0.5,0.9), rgb(0.8,0.2,0.5,0.9) , rgb(0.7,0.5,0.1,0.9) )
    colors_in=c( rgb(0.2,0.5,0.5,0.4), rgb(0.8,0.2,0.5,0.4) , rgb(0.7,0.5,0.1,0.4) )
    radarchart( data, axistype=1 , pcol=colors_border , pfcol=colors_in , plwd=4 , plty=1, cglcol="grey", cglty=1, axislabcol="grey", caxislabels=rep("",5), cglwd=0.8, vlcex=0.8)
    legend(x=0.5, y=1.2, legend = rownames(data[-c(1,2),]), bty = "n", pch=20 , col=colors_in , text.col = "black", cex=1, pt.cex=3)
}

在函数中,“radarchart”将绘制蜘蛛图,下面将解释其中的一些参数。

pcolpfcol 分别定义线条颜色和填充颜色。 plwdplty 分别给出了蜘蛛图的线宽和类型。网格线(或网)具有由 cglcolcglty 定义的颜色和类型。我不想在蜘蛛图的中心放置任何标签,所以将 caxislabels 赋予空字符串(rep(",5))。

我们来看看哈登的统计怎么样。

comp_plot(df_sel[1,],maxxx,minnn)

詹姆斯·哈登季后赛数据的蜘蛛图

从上面的剧情可以看出,哈登不仅是一个优秀的得分手(高分),还是一个组织者(高助攻)。这些解释与我们所知的詹姆斯·哈登完全一致。

为了比较詹姆斯·哈登和勒布朗的数据,让我们将两个球员的数据输入到函数中。

comp_plot(df_sel,maxxx,minnn)

詹姆斯·哈登和勒布朗·詹姆斯的蜘蛛图比较

我们可以看到,与哈登相比,勒布朗在数据上有更好的篮板和助攻数据,尽管他的得分不如哈登。

很直接,对吧?

让我们在扬尼斯·阿德托昆博和科怀·伦纳德的高级统计数据中做一个类似的比较,包括进攻框加减(OBPM),防守框加减(DBPM),进攻获胜份额(OWS),防守获胜份额(DWS),和真实投篮命中率(TS)。

df = read.csv("playoff_stats_adv.csv")
maxxx = apply(df[,c("OBPM","DBPM","OWS","DWS","TS.")],2,max)
minnn = apply(df[,c("OBPM","DBPM","OWS","DWS","TS.")],2,min)
df_sel = df[c(1,3),c("OBPM","DBPM","OWS","DWS","TS.")]
rownames(df_sel) = c("Giannis","Kawhi")

先来看看詹尼斯的统计。

comp_plot(df_sel[1,],maxxx,minnn)

扬尼斯·阿德托昆博季后赛先进数据的蜘蛛图

我们可以发现詹尼斯是一名全能球星,因为他几乎在各个方面都有不错的统计。难怪他赢得了 2019-2020 常规赛的第二个 MVP。

接下来,让我们比较一下詹尼斯和科怀·伦纳德的高级统计数据。

comp_plot(df_sel,maxxx,minnn)

扬尼斯·阿德托昆博与科怀·伦纳德的蜘蛛图比较

我们可以看到詹尼斯在高级统计的各个方面都超过了科怀。

你可以用这个简单的函数来比较任意数量的玩家,然而,我不建议使用蜘蛛图来比较超过 3 个人。

如果你确实需要比较一大群对象,那么热图可能是可视化的更好选择。这里是我以前在 r 中最好的热图函数的一个帖子。

[## Pheatmap 绘制了漂亮的热图

一个关于如何在 r 中用 pheatmap 生成漂亮的热图的教程。

towardsdatascience.com](/pheatmap-draws-pretty-heatmaps-483dab9a3cc)

作为一名数据科学家,我希望这篇短文能对您的工具箱有所帮助!

参考资料:

  1. https://www.basketball-reference.com/
  2. https://www.r-graph-gallery.com/spider-or-radar-chart.html

ZanUnsplash 上的照片

使用 Python 中的散景绘制漂亮的交互式折线图

原文:https://towardsdatascience.com/draw-beautiful-and-interactive-line-charts-using-bokeh-in-python-9f3e11e0a16e?source=collection_archive---------24-----------------------

作者使用散景拍摄的图片

数据分析师/科学家必须了解的 Python 可视化库

折线图可能是展示两个维度之间关系的最基本但最有用的图表。通常用于连续显示变量y在时间轴x上的方差,其中 x 轴必须排序。

很容易从折线图中获得洞察力,如变量是增加、减少还是波动,以及获得其周期模式、峰值和尖峰。此外,我们可以在折线图上绘制多条线,以比较它们在同一时间窗口内的不同趋势,有时甚至可以了解它们如何相互影响。

在这篇文章中,我将演示如何使用 Bokeh,Python 中最流行的可视化库之一,来绘制一个漂亮的交互式折线图。

什么是散景?

Benjamin WongUnsplash 上的照片

官网对散景的定义非常好,如下。

Bokeh 是一个用于现代网络浏览器的交互式可视化库。它提供了优雅、简洁的通用图形结构,并在大型或流式数据集上提供了高性能的交互性。散景可以帮助任何人快速方便地制作交互式绘图、仪表盘和数据应用程序。

基本上,散景可以帮助我们在网页中生成可视化效果,可以用任何流行的浏览器查看。不过需要强调的是,它还支持 Jupyter 笔记本。因此,您不必每次都在浏览器上的单独选项卡中生成图表。它就像 Matplotlib 一样,可以把你笔记本上直接渲染的数据绘制出来。

安装和导入

照片由 K . I . I . A . N 拍摄📷 on Unsplash

安装散景非常容易。只需在命令行中运行pip就可以获得它。

pip install bokeh

大多数时候,我会如下导入散景,这只是将被利用的基本包。当然,当有一些定制的需求时,我们可能需要导入更多的功能。

from bokeh.plotting import figure, output_notebook, show

figure包是我们用来绘制数据的主要包。show包将在单独的网页中或者直接在笔记本上呈现图表。只有当我们想要在笔记本中渲染图表时,才需要output_notebook,所以在本教程中我们需要它。

一旦我们导入了output_notebook,我们只需要运行这个函数来启用“笔记本模式”。

现在我们应该开始了。

基本折线图

照片由 Serghei TrofimovUnsplash 上拍摄

让我们从一些基本的开始。虽然 Matplotlib 也能很好地完成这项工作,但 Bokeh 让事情变得更直观,也更容易获得漂亮的效果。

首先,我们需要生成一些随机数据。

import numpy as np# Generate random data
x = np.arange(1, 11)
y = np.random.rand(10)

然后,初始化图形的“画布”。

# Generate canvas
fig = figure(title='Line Chart Example',
             x_axis_label='x',
             y_axis_label='y',
             width=800,
             height=400)

这里的widthheight是实际像素,与 Matplotlib 不同。事实上,我喜欢使用这些像素,这对任何有一些 web 前端体验的人来说都更友好。

之后,让我们划清界限。

# Draw the line
fig.line(x, y, 
         line_alpha=0.8,
         legend_label='example value', 
         line_width=2)

如代码所示,我们可以使用line_alpha设置线条的透明度,设置图例标签以及线条宽度。

最后,我们需要调用show(fig)函数来渲染这个折线图。如果您正确运行了output_notebook(),图表应该绘制如下。

多行

萨姆·普林在 Unsplash 拍摄的照片

如果我们有多条线呢?散景提供了一个非常方便的功能multi_line(),可以一次绘制多条线。

我们可以继续使用x系列,但是生成两个不同的y系列。

# Generate two data series
y1 = np.random.rand(10)
y2 = np.random.rand(10) + 1

这里我只是在第二个y2数据上加 1,使其高于y1,没什么神奇的。

然后,让我们创建图形并绘制两条线。不要忘记“显示()”它。

# Multiple Lines
fig = figure(title='Multi-Line Chart Example', width=800, height=400)# Draw two lines
fig.multi_line([x, x], [y1, y2], 
               color=['blue', 'red'], 
               alpha=[1, 0.3], 
               line_width=2)# Show the figure
show(fig)

互动功能

亚历山大·奈特Unsplash 上拍照

到目前为止,与 Matplotlib 相比没有太大的不同,除了散景更漂亮。但是等等,你有没有注意到图表右边有一个工具栏。默认工具包括

  • *移手势
  • 框放大
  • 鼠标滚轮放大/缩小
  • 将图形保存为 PNG 图像
  • 重置位置和缩放级别
  • 帮助

生成图表时,可以启用更多支持的交互式功能。你可以参考官方文档来获得更多的细节,但是我相信这些默认工具对于大多数场景来说已经足够了。

高级定制

JESHOOTS.COMUnsplash 上的照片

有时,出于某种原因,我们可能需要定制我们的折线图。在这一节中,我将提供一些例子。

比方说,我们想比较一些数学函数,以了解它们在 x 变大时的趋势。这些功能如下:

  • y=x
  • y=x
  • y=logx
  • y=10^x
  • y=e^x

让我们先生成数据。

# Generate functions and data
x = np.arange(0, 3, 0.1)
y1 = np.power(x, 2)
y2 = np.log(x)
y3 = np.power(10, x)
y4 = np.exp(x)

会有一些警告,因为 log0 是未定义的,但是不用担心,它将是 Numpy 数组中的一个-inf。此外,Bokeh 足够聪明,可以在渲染数据时忽略该值。

y 轴刻度和数据点形状

现在,我们可以再次使用multi_line()函数来一次绘制所有的函数。但是,我想一个一个地做这件事,因为我认为把线和它们的配置分开会更清楚。当然,选择哪种方式取决于你。

fig = figure(title='Compare the Trends of Different Functions', width=800, height=400)
fig.line(x, x, legend_label='y=x', color='blue')
fig.line(x, y1, legend_label='y=x^2', color='red')
fig.line(x, y2, legend_label='y=logx', color='green')
fig.line(x, y3, legend_label='y=10^x', color='purple')
fig.line(x, y4, legend_label='y=e^x', color='brown')
show(fig)

嗯,它已经被正确地绘制出来了,但是它是不可用的。除了y=10^x这个功能,其他都挤在一起了。所以,用这个折线图,我们实际上不能比较趋势。

解决方法是修改 y 轴的比例。如果我们可以使 y 轴不是线性的,它应该能够更清楚地区分功能。通过将y_axis_type设置为log,散景可以非常容易地做到这一点。

# Generate figure object
fig = figure(title='Compare the Trends of Different Functions', width=800, height=600, y_axis_type='log')

还有一个问题。即使我们为这些功能使用了不同的颜色,仍然不容易区分它们。让我们也为不同函数的数据点添加不同的形状。

# Use blue colour and circle for y=x
fig.line(x, x, legend_label='y=x', color='blue', line_width=2)
fig.circle(x, x, legend_label='y=x', color='blue', fill_color='white', size=5)# Use red colour and triangle for y=x^2
fig.line(x, y1, legend_label='y1=x^2', color='red', line_width=2)
fig.triangle(x, y1, legend_label='y1=x^2', color='red', fill_color='white', size=5)# Use green colour and square for y=logx
fig.line(x, y2, legend_label='y2=logx', color='green', line_width=2)
fig.square(x, y2, legend_label='y2=logx', color='green', fill_color='white', size=5)# Use purple colour and diamond for y=10^x
fig.line(x, y3, legend_label='y3=10^x', color='purple', line_width=2)
fig.diamond(x, y3, legend_label='y3=10^x', color='purple', fill_color='white', size=5)# Use brown colour and hexgon for y=e^x
fig.line(x, y4, legend_label='y4=e^x', color='brown', line_width=2)
fig.hex(x, y4, legend_label='y4=e^x', color='brown', fill_color='white', size=5)

酷!现在,我们可以很容易地确定这些函数及其趋势。

图例位置和隐藏

这个图形现在看起来不错,但是如果我们能够将图例重新定位到左上角,那就更好了,因为那里什么也没有。此外,该图中仍然有太多的线条,我们可能希望隐藏其中的一些线条,以便我们可以一次只比较其中的几条。

是的,散景很容易做到这一点。实际上,我们甚至不需要再次生成那个数字。因为我们有了图形对象fig,我们可以直接修改它的属性来实现这些。

# Relocate Legend
fig.legend.location = 'top_left'
# Click to hide/show lines
fig.legend.click_policy = 'hide'

带工具提示悬停

现在,假设我们希望将鼠标悬停在这些线上以获取数据点的值。我们也可以在散景中轻松实现这一点。此外,我们不需要重新生成图形,因为我们可以向图形对象添加“工具提示”。

from bokeh.models.tools import HoverToolfig.add_tools(HoverTool(
    tooltips=[
        ('(x, y)', '([@x](http://twitter.com/x), [@y](http://twitter.com/y))')
    ]
))

我们需要导入HoverTool类,以便将其作为“工具”添加到 figure 对象中。请注意,散景使得自定义工具提示变得非常灵活。具体来说,我们可以将每行文本定义为一个元组。对于元组的第二个值,我们可以使用@符号来指代数据字段。在这个例子中,我只定义了一个元组。如果您用不同的格式和/或数据字段定义了多个元组,工具提示将显示它们。

用 HTML 模板定制工具提示

如果我们有更具体的要求呢?散景使得工具提示更加灵活,我们甚至可以使用 HTML 模板来定制工具提示。

fig.add_tools(HoverTool(
    tooltips='<font face="Arial" size="3">When x is [@x](http://twitter.com/x){0.0}, y is [@y](http://twitter.com/y){0.00}</font>',
    mode='vline'
))

请注意,我这次还加了mode='vline'。这将在相同的垂直 x 轴位置显示所有行的工具提示。因此,它将显示所有不同y的相同x的值,这样更便于比较。

洛伦兹吸引子

让我们用一个来自官方图库的花式折线图来完成这篇文章。散景确实很美。

from scipy.integrate import odeintsigma = 10
rho = 28
beta = 8.0/3
theta = 3 * np.pi / 4def lorenz(xyz, t):
    x, y, z = xyz
    x_dot = sigma * (y - x)
    y_dot = x * rho - x * z - y
    z_dot = x * y - beta* z
    return [x_dot, y_dot, z_dot]initial = (-10, -7, 35)
t = np.arange(0, 100, 0.006)solution = odeint(lorenz, initial, t)x = solution[:, 0]
y = solution[:, 1]
z = solution[:, 2]
xprime = np.cos(theta) * x - np.sin(theta) * ycolors = ["#C6DBEF", "#9ECAE1", "#6BAED6", "#4292C6", "#2171B5", "#08519C", "#08306B",]fig = figure(title="Lorenz attractor example", background_fill_color="#fafafa")fig.multi_line(np.array_split(xprime, 7), np.array_split(z, 7),
             line_color=colors, line_alpha=0.8, line_width=1.5)show(fig)

摘要

照片由斯科特·格雷厄姆Unsplash 上拍摄

在这篇文章中,我介绍了如何使用散景来绘制美丽的折线图。作为 Python 中最流行的可视化库之一,Bokeh 提供了许多开箱即用的可视化特性,如交互式工具集。当涉及到较低的水*,它也提供了非常灵活的功能,让我们自定义我们的数字。

[## 通过我的推荐链接加入 Medium 克里斯托弗·陶

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

medium.com](https://medium.com/@qiuyujx/membership)

如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和成千上万的其他作者!(点击上面的链接)

参考

[1]散景最新文档,https://docs.bokeh.org/en/latest/index.html

[2]散景画廊,洛伦兹吸引子,【https://docs.bokeh.org/en/latest/docs/gallery/lorenz.html

在 VS 代码中绘制 UML 图

原文:https://towardsdatascience.com/drawing-a-uml-diagram-in-the-vs-code-53c2e67deffe?source=collection_archive---------4-----------------------

在 VS 代码中使用 PlantUML 扩展

在 VSCode 中编辑 PlantUML 序列图(作者)

在数据科学项目中,UML 图对于用组件图或类图说明问题领域的概念模型是非常重要的;或者展示你的机器和算法如何与序列图或活动图一起工作。你们中的一些人可能会定期在纸上画这个,或者使用一些软件,如 PWP 或 Adobe AI,如果你不是专家,这有时会让你头疼。

许多在线工具如 https://www.diagrams.net/的 T4 也允许你画图表,但有时会让你花很多时间去画一个复杂的图表。因此,这篇短文介绍了一种替代手工绘制的方法,展示了如何使用 plant UML(https://plantuml.com/)的纯文本(易于理解的脚本)来绘制图表。它是一个用于创建 UML 图的开源工具和语法。使用这个工具,您可以创建各种各样的 UML,从简单的流程图到复杂的图表。通过将 PlantUML 安装为 VS 代码扩展,您可以直接在 VS Code 软件中编辑它,如下面的 gif 动画示例所示。

在 VSCode 中创建一个简单的序列图(作者提供)

要求

  • 安装 VS 代码
  • 安装 PlantUML 扩展

PlantUML 扩展(作者截图自 VS 代码)

开始画你的第一张图

要开始绘制 UML 图,请检查来自https://plantuml.com/的语法文档。在主 PlantUML 主站点上有很多很好的语法例子,很容易理解。

在您了解 PlantUML 的语法之后,只需在 VS 代码中打开您的项目文件夹,并使用创建一个文件。puml 文件类型,并开始编写您的 uml 代码。您还可以通过右键单击 VS 代码脚本窗口并选择“预览当前图”或点击“Alt + D”来查看更新的实时变化(此选项在您编辑时可用)。puml 文件)。

编辑 PlantUML 图时预览实时变化。(作者)

导出您的图表

完成编辑后,您可以通过右键单击 VS 代码脚本窗口并选择“Export Current Diagram”来导出图表。然后会提示您选择所需的文件类型。如果你不确定选择哪一个,我建议你生成一个矢量文件类型。svg ,。 eps )总是给你最大的分辨率。

导出 PlantUML 图。(作者)

差不多就是这样!我希望您喜欢这篇文章,并且能够在您的数据科学或编程项目中应用这个 UML 工具。如果您有任何问题或意见,请随时告诉我。

我希望你喜欢它,并发现它对你的日常工作或项目有用。如果你有任何问题,请随时联系我。

关于我&查看我所有的博客内容:链接

*安健康!
感谢阅读。👋😄

用 OpenGL 绘制金融股票行情图

原文:https://towardsdatascience.com/drawing-financial-stock-market-charts-using-opengl-93254883bca7?source=collection_archive---------26-----------------------

利用 GPU 核心通过 GLSL 卸载 CPU

OpenGL 图表图像。来源:维基共享资源

介绍

我一直致力于将 OpenGL 作为显示图形的终极方式。在本文中,我将描述如何将数据从 CPU 转移到 GPU。虽然这是正常的方法,但我发现的所有信息都专注于提供与 3D 渲染过程直接相关的数据(位置、颜色、法线),我花了很长时间来理解和定位关于如何将更高抽象数据移动到 GPU 的信息,比传统的 3D 模型点更远。在这种情况下,OpenGL 社区和可用的信息也没有多大帮助,因为大多数活跃在论坛中的人通常都参与 3D 引擎。

说白了,我正试图让 GPU 从与图形无关的数据中完成实际的图形模型,这似乎是一个不太常见的 OpenGL 任务。这可以认为是做纯渲染(OpenGL)和做纯计算(OpenCL)的中间步骤。我们正在将计算过程卸载到 GPU 中,但它仍然是与渲染相关的代码。

在我的例子中,我正在处理 2D 股票市场数据,我希望 GPU 负责处理所有的金融数据,以显示一切。对于那些不熟悉财务图表的人来说,举一个可能更容易理解的例子,假设您正在绘制一个有许多树的森林场景。您可能传递给 GPU 的信息包括树的位置、树的类型的整数(我们可能有不同类型的树要渲染)、树的高度和宽度。GPU 可以从这些简单的信息中为每棵树构建数百个图元。通过这样做,CPU 不需要将我们高度抽象的木材模型(位置、树的类型、宽度和高度)转换成可绘制的模型。性能的提升是巨大的,因为我们利用了 GPU 的大量内核。另一个好处是,我们还将图形部分从应用程序中分离出来,将所有的渲染和图形模型构建例程转移到 GLSL。

GPU 拥有强大的能力。由于我目前正在开发要求不那么高的 2D 应用程序,我已经使用旧的廉价 NVIDIA Quadro 卡在旧的 OpenGL 标准(3.3)中稳定了我的开发,这些卡在旧的交易工作站中很常见。我这样做是为了确保我的应用程序可以在遗留硬件中使用。我正在处理的卡有 16 个内核,这并不令人印象深刻,但现代卡现在有数百个内核(在撰写本文时,Nvidia GeForce RTX 2080 Ti 代表了 4352 个内核的最先进水*)。在一台经济实惠的电脑上搭载 4000 多枚内核简直太棒了。然而,与使用 CPU 在应用程序级别实现图形的传统方法相比,即使是普通的传统卡也能大大提高图形性能。作为一种权衡,编程 GLSL 并将图形卸载到 GPU 会使编程变得更加复杂:调试 GLSL 具有挑战性,有时甚至令人沮丧。

在这篇文章中,我将描述我遇到问题的地方,主要是因为我没有做非常传统的事情(比如将整数传递给顶点着色器)和理解步幅和偏移。我把注意力集中在令我烦恼的特定概念和代码部分。

顶点数据涉及任意数据

尽管顾名思义,你是在表示顶点(顺便提一下,这是最常见的用例),但顶点只是你移入 GPU 的缓冲数据,特别是移入顶点着色器。这些数据可以包含绘制实际模型所需的任意信息。通常这将包括关于位置的某些信息,但是它可能意味着更高的抽象模型,其中位置由该抽象模型隐式地定义。

在我们的例子中,我们将制作一张简单的蜡烛图。因此,我们的输入数据将是:

open price, high price, low price, close price, volume, timestamp

除此之外,我们希望 GLSL 画出:

OpenGL 中绘制蜡烛的“hello world”

所以我们的顶点信息不包含传统意义上的 x/y 位置。并且它绝对不涉及图形元素(点/线/三角形)。我们只需将蜡烛信息移入 GPU,并让卡片完成所有绘图。通过这样做:

  1. 应用程序现在更容易编码,因为它管理实际的现实生活数据(所有应用程序都应该尝试这样做),绘制实际蜡烛的问题缩小到 GPU。
  2. 性能的提升是巨大的,因为我们利用我们的 GPU 核心来执行构建图元时涉及的简单操作。
  3. 我们已经在模型层和表示层之间做了最好的解耦——软件开发中的解耦是少数几个几乎总是有意义的建议之一——

GLSL 数据类型

与传统编程相比,使用 GLSL 编程 GPU 有一定的局限性。最后,我们正在处理为渲染而优化的小内核。GLSL 深受 C 语言的影响,所以它继承了一些 C 类型,但同时,它有特殊的类型用于处理多达 4 个元素的向量和矩阵。我仍然在研究可变大小的数组是否可以被移入 GPU,但目前我使用的是基本类型:

bool - boolean type (true/false)
float - 4 bytes
double - 8 bytes
int - 4 bytes signed integer
uint - 4 bytes unsigned integer
vec2 - 2 float vector (vec2.x, vec2.y)
vec3 - 3 float vector (vec3.x, vec3.y, vec3.z)
vec4 - 4 float vector (vec4.x, vec4.y, vec4.z, vec4.w)
ivec2 - 2 int vector (ivec2.x, ivec2.y)
ivec3 - 3 int vector (ivec3.x, ivec3.y, ivec3.z)
ivec4 - 4 int vector (ivec4.x, ivec4.y, ivec4.z, ivec4.w)

关于 GLSL 数据类型的全面而简明的指南可以在这里找到。

这意味着在我们的例子中,我们有 6 个整数值(我使用整数而不是双精度浮点数来表示价格,以保持精确值),我们不能使用类似于ivec6的东西,因为它不存在。

我们的“Hello World”示例绘制了三根蜡烛

源代码(在 Java 中使用 JOGL,但在 C++中类似)创建了一个包含所有信息和三个 vbo(顶点缓冲对象)的数组。

这个数组将被用来为每个缓冲区提供数据。我们需要处理的信息是strideoffset ,这样 OpenGL 顶点着色器可以稍后定位数据。使用的具体glVertexAttribPointers有:

我们的“Hello World”示例定义了顶点属性,包括每个数据的步幅和偏移

注意我们是如何使用glVertexAttribIPointer而不是glVertexAttribPointer的,因为我们处理的是整数数据。出于某种原因,我没有能够传递负整数,即使使用了GL_INT而不是GL_UNSIGNED_INT

Vertex 如何工作的一个很好的定义可以在这里找到,它对我理解相关概念很有用。

顶点和几何体着色器

顶点着色器现在可以拾取全部数据:

顶点着色器代码

对于输入数据,位置布局属性定义了我们正在收集的具体属性,数字必须与glVertexAttribIPointer中使用的数字相匹配。该信息是使用变量gs_ohlcgs_volumegs_timestamp从几何着色器收集的。请注意顶点着色器中的输出变量名必须与几何着色器中的输入变量名相匹配。还要注意我们没有使用gl_Position,因为我们还没有处理任何位置,只是高级抽象数据。没有必要,您仍然可以将任意数据从顶点传递到几何着色器。

几何着色器收集高级数据并构建图元。它甚至根据蜡烛线是看涨还是看跌来给它们上色:

几何着色器代码

我们基于 OHLC 和时间戳数据构建原语(在本例中为 line_strips)。这个例子很粗糙,缺少绘制整个图表所需的所有额外细节。但是它说明了如何将抽象数据移入 GPU 来实现图形原语。

摘要

在本文中,我回顾了一些在 OpenGL 教程或文档中不常讨论的概念;不是因为它们没有被记录,而是因为它们不属于传递浮动顶点信息来执行 3D 渲染的最常见用例。

虽然代码并不完整,但对于那些已经在 OpenGL 中运行了第一个教程并希望更好地理解如何将数据移动到着色器的人来说,它是有用的。它也缺少绘制整个图表所需的其他方面,但它代表了令我感到麻烦的方面和 OpenGL 语法。

我仍在研究整个数据是否可以作为 6 个元素的数组传递,以包括可能的其他情况,我们可能希望将更大的数据块移动到 GPU。我还需要涵盖的东西,如滚动,缩放和缩放。GLSL 被证明是一个深思熟虑的从零开始学习的迷人话题。如前所述,我仍然有一些简单的问题,比如将负整数传入顶点着色器。这是一个明显的迹象,表明 GLSL 不像其他技术那样直观。事实上,大多数学习材料都集中在 3D 上,而我使用的是 Java JOGL(大多数材料使用 C++),这也不利于这个过程。

GPU 的能力是惊人的,我也有动力在未来学习如何通过 OpenCL 或 CUDA 将这种能力用于一般计算。对于数据工程、回溯测试软件和 ML 等活动来说,这是一个非常好的选择。

在真实环境中使用 GauGAN 绘制故事的内心世界

原文:https://towardsdatascience.com/drawing-the-inner-world-of-a-story-using-gaugan-in-a-real-environment-d8e303aaa2f9?source=collection_archive---------41-----------------------

艾夫纳·佩莱德 和我正在分享骨髓发育阶段的经验教训。这篇文章着眼于我们如何在 360°环境中实时使用GauGan

人工智能和交互式讲故事都是复杂和不可预测的系统。随着我们深入骨髓的设计过程,将这两个系统结合成一个连贯的体验的挑战变得明显。一方面,作为作者,我们开发了人工智能系统和实时交互来引导体验的流动。另一方面,我们希望讲述一个能激发参与者想象力和情感的故事。

Avner Peled 在测试我们的 GauGan 系统时拍摄的截图;一瓶水换成了花

《骨髓》是一个关于机器学习模型中精神疾病可能性的故事,主要关注生成性对抗网络(甘)。我们质疑在高级人工智能中会出现什么样的精神障碍,并邀请参与者在由甘操作的互动剧场场景中进行表演。他们一起扮演一个功能失调的人工智能家庭。由于我们正在处理非常抽象和复杂的概念,我们想探索多种方式来传达这个故事,而不仅仅是通过家庭成员之间的对话。我们的策略是让房间更加“生动”,反映出模特的精神状态。我们想消除参与者和环境之间的障碍;让他们慢慢沉浸在房间里不熟悉的魔法体验中。房间和晚餐的场景是一个邀请,让我们放手,沉迷于与其他三个陌生人的情感事件。

Andre Bendahan 在 NFB 实验室拍摄的照片 2020 版权所有

在实践中,这意味着我们必须实施经常与环境和参与者交互的 GAN 网络。由于 GAN 的训练过程不是实时发生的,这就变成了一个挑战,即操纵预训练 GAN 网络的输出以响应环境的实时变化。为了解释我们的解决方案,我们首先需要看看标准 GANs 和条件 GANs 之间的区别。

标准与有条件的 GANs

在其基本形式中,GAN 被训练产生视觉上类似于训练集的新图像。如果我们使用人脸数据集,它会生成新的人脸。如果我们把它用在猫身上,它会产生新的猫。它可以通过采用输入“噪声”向量(本质上是一系列随机数)并使用它们作为输出图像的基础来保持可变性(不是每次都产生相同的图像)。因此,如果我们想要将 GAN 的输出与环境变化联系起来,我们需要根据这些变化来控制噪声矢量。然而,正如我们在之前的文章中所展示的,对于改变噪声向量会产生什么样的变化,几乎没有任何控制。

[## 甘潜在空间的合作工具

2020 年 1 月,我们完成了骨髓的开发阶段。我和 Shirin Anlen 正在分享在…

towardsdatascience.com](/a-tool-for-collaborating-over-gans-latent-space-b7ea92ad63d8)

我们可以将物理房间中的不同变量(如参与者的位置、物体的位置和参与者的情绪分析)与生成的输出联系起来,但缺乏对输出的精确控制导致了与环境的脆弱联系。

作者演示了标准 GAN 和条件 GAN 之间的差异

这就是有条件的 GANs 进入画面的地方。我们不是在一组图像上训练,而是在由一个图像和一个标签(数字输入)组成的上训练网络,当呈现特定种类的标签时,该网络被调整为生成一种类型的图像。这使得用户可以完全控制 GAN 如何针对特定输入产生输出。与原始 GAN 一样,结果仍会随着噪声矢量的变化而变化。然而,现在作者可以创造与环境有意义的互动。最著名的条件 gan 之一是 Pix2Pix

图片 fromhttps://phillipi.github.io/pix2pix/

这是一个通用的图像到图像转换器。它可以根据任何类型的图像生成另一个图像。它分析两幅图像中的像素,学习如何从一种颜色转换到另一种颜色。Pix2Pix 的使用方式多种多样,比如将草图转化为画作,将色彩映射表转化为照片。我们还在我们的原型中使用它来将一个人的彩色姿势分析转换成一个从家庭照片中生成的人。

[## 家庭 2 家庭:第一步

2018 年 11 月,我们呈现了《骨髓》的序幕:我一直在 IDFA 嫉妒别人的家庭…

沉浸.新闻](https://immerse.news/family2family-first-steps-5f085dc75666)

高根

Pix2Pix 找到了自己的优势,作为一个从任何图像到任何图像的通用翻译器,它也有自己的弱点。仅仅依靠颜色会错过可以输入网络的元数据。该算法只查看形状和颜色。如果餐盘和飞碟在照片上看起来相似,它就无法区分它们。这就是 NVIDIA 的研究人员在创造 GauGAN 时所解决的问题。以后印象派画家保罗·高更的名字命名,GauGAN 也用彩色地图创作现实主义的图像。但是,它不是学习像素值,而是学习图像的语义数据。该项目也被称为 SPADE : 具有空间自适应归一化的语义图像合成。GauGAN 学习哪里有草地和天空,而不是学习图片中绿色和蓝色的位置。这是可能的,因为训练集中使用的图像,如通用数据库 COCO-Stuff ,包含图片中不同元素的语义分类。然后,研究人员能够通过制作一种交互式绘画工具来展示 GauGAN 的能力,在这种工具中,颜色不仅仅是颜色,而且还有意义。当你在源草图上画绿色时,你是在告诉 GauGAN 这里有草。在这里自己试试。

图片来自https://www.nvidia.com/en-us/research/ai-playground/

将 GauGAN 连接到实时 360°环境

GauGAN 可以从手绘草图中生成真实感图像。我们的目标是让它与实时物理环境互动。解决这个问题就像拼拼图一样:

  1. 我们知道 NVIDIA 对 GauGAN 进行了语义数据方面的培训:他们使用 DeepLab v2 网络来分析 COCO-Stuff 数据库并产生标签。
  2. 我们知道 DeepLab V2 可以实时分割相机流。
  3. 1+2:如果我们将 DeepLab 的相机流输出直接馈送给 GauGAN,我们应该会得到它的真实镜像状态。

代码本身相对简单,主要与两个网络之间的格式转换有关。我们还升级了 DeepLab 的网络摄像头代码,以从我们的 360°摄像头传输:理光 THETA Z1 。分割网络是如此强大,以至于我们可以将加宽的拼接图像直接馈送给分割和生成。结果出奇的准确。

GauGAN 系统流程的作者插图

操纵甘的现实

我们现在有一个生成的镜像,描绘了甘(可可的东西)的版本,无论相机在房间里看到什么。但是我们想要更多;我们想要一个能根据故事变化的空间,并能模拟角色的精神状态。我们寻找产生与故事世界相联系的视觉效果的方法。为了找到单词之间的含义并吸引用户继续行动,四处移动物体,看到倒影,并想知道这是怎么回事。

我们意识到我们可以干预感知和生成的过程。就在 DeepLab 分析了相机流中的标签之后,为什么不用其他东西替换它们呢?例如,让我们将任何公认的碗映射到海洋。

Avner Peled 在测试我们的 GauGan 系统时拍摄的截图;一个碗被替换为海洋纹理

我们开始寻找我们的角色的故事可以浮出水面的模式,以及物理空间可以支持整个视觉形式的模式:一张脸,一幅风景,一个物体,一朵花。故事是可识别的模式,在这些模式中,我们找到了意义。它们是噪音中的信号。

当我们最终到达实验室进行测试时,我们发现了物理环境的影响。我们通过排列(和重新排列)奇怪的元素和探索我们能达到的结果开始玩。我们开发了一个脚本*台,让我们可以轻松地将对象映射到其他对象。我们可以从场景中屏蔽某些对象,一次选择多个对象,或者反转选择来映射除指定对象之外的所有对象。例如:“餐桌”、“桌子”、“书桌”、“书桌用品”、“地板”、“床”、“汽车”——突然变成了同一个项目,并被映射成一片海洋,而其他所有东西都被丢弃了。虽然我们没有汽车,没有塑料,也没有床。或者“飞盘”、“纸”、“老鼠”、“金属”、“岩石”、“碗”、“酒杯”、“瓶子”——都映射到“岩石”。同样,有趣的是,我们在真实场景中没有鼠标、飞盘、金属、石头或纸张,但是网络检测到了它们。因此,我们也需要考虑它们。

来自髓的 GitHub 的截图

如果这还不够,我们发现灯光、阴影和相机角度的变化每次都会产生不同的标签,这打乱了我们的贴图。在一个互动的讲故事框架中,这感觉既不可思议又可怕。在开幕之前,我们有不到十天的时间来完善空间和调试技术,同时了解我们刚刚开发的产品可以创造的各种可能性。

作者照片。第一个实验——左侧:我们如何排列物品。右侧:高根人是如何绘制和投射图像的。

作者的照片展示了布景的原型:碗和瓶子变成了船,桌子变成了海洋。

我们和我们的网络一起玩,很少控制视觉效果,我们希望形象化我们角色的内心世界。

慢慢地,我们开始学习这个系统——什么可行,什么不可行,如何清理场景,如何稳定灯光。我们还决定投影这个过程的两个阶段,DeepLab 的彩色分段分析和 GAN 生成的输出。渐渐地,物理环境变得更加身临其境,可以与故事的文字联系起来。

Andre Bendahan 在 NFB 实验室拍摄的照片 2020 版权所有

倒影

  • 预训练的 SPADE/GauGan 网络的分辨率以较低的 256x256 分辨率生成图像。很难让人们参与到这种视觉中,并让他们理解他们所看到的。实现更高的分辨率需要我们在培训中投入更多的资源,这在当时是不可能的。
  • 因为 GauGAN 具有语义意识,所以图像的上下文非常重要。例如,将一张桌子映射到大海,而将混凝土墙留在背景中,会生成一个昏暗的湖泊或池塘。但是把墙映射成蓝天,现在海看起来更像海洋了。
  • 由于这种上下文感知,也很难用孤立的对象来传达意思。当我们完整地展示这些图像时,它们通常看起来是最好的。

Andre Bendahan 在 NFB 实验室拍摄的照片 2020 版权所有

虽然我们仍然觉得围绕我们的故事还有很多实验和润色的空间,但这些结果让我们第一次看到了甘的“意识”,作为一个产生其内心世界的感知实体。这样的过程与人类意识的哲学产生共鸣。

伊曼纽尔·康德的先验哲学谈到了综合的行为:我们的表象一起行动,塑造一个统一的意识。在现代神经科学中,我们谈到了意识的神经关联,它描述了意识所需的神经活动,不是作为物体识别的离散前馈机制,而是统一体验的长期持续反馈波。这也是我们希望在髓室设计的体验类型,最终的“编辑”发生在参与者的头脑中。

有一件事我们确信不会给这项创造性的工作带来伤害——那就是让更多的人使用它。除非你做了很多次,否则你不会知道你在做什么,尤其是在这种复杂的项目中。只是制造制造制造。

这里是项目的 开源 GitHub 库 请和我们分享你的制作和想法!

开发阶段由音效师菲利普·兰伯特 和动画师帕洛玛·道金斯 合作完成。合拍中的 NFB 互动*图集五*

从头开始绘制变压器网络(第 1 部分)

原文:https://towardsdatascience.com/drawing-the-transformer-network-from-scratch-part-1-9269ed9a2c5e?source=collection_archive---------14-----------------------

以有趣的方式获得变形金刚的心智模型

(图片由作者提供)

变形金刚神经网络——通常被称为“变形金刚”——是由谷歌领导的团队在 2017 年发表的一篇题为“注意力是你所需要的一切”的论文中介绍的。在接下来的工作中被很多人提炼推广。

像在它之前发明的许多模型一样,变压器有一个编码器-解码器架构。在这篇文章中,我们把重点放在编码器部分。我们将以自下而上的方式连续绘制它的所有部分。这样做有望让读者轻松地开发出变压器的“心智模型”。

下面的动画以快动作展示了我们将在本文中涉及的内容:

(图片由作者提供)

投入

转换器将单词序列作为输入,作为向量呈现给网络。在 NLP 任务中,通常使用一个词汇表(也称为字典),其中每个单词被分配一个唯一的索引。该索引可以被表示为所谓的独热向量,其主要由 0 组成,在正确的位置具有单个“1”值。下图显示了一个简单的十个单词的词汇编码:

请注意,独热编码向量的大小与词汇表中的字数相同,在实际应用中至少为 10.000。此外,所有独热编码彼此之间具有相同的欧几里德距离√2。

单词嵌入

接下来,我们通过将独热编码向量乘以所谓的“嵌入矩阵”来降低它们的维数。由此产生的向量被称为单词嵌入。原始论文中单词嵌入的大小是 512。

单词嵌入的巨大好处是意思相似的单词被放在一起,例如单词“cat”和“kitty”最终具有相似的嵌入向量。

请注意,“嵌入矩阵”是一个普通的矩阵,只是有一个花哨的名字。

位置编码

所有的单词同时呈现给变压器。这与递归神经网络(例如 LSTMs)有很大的不同,在 lst ms 中,单词是连续输入的。然而,这意味着单词在输入序列中出现的顺序丢失了。为了解决这个问题,转换器向每个输入嵌入添加一个向量,从而注入一些关于相对或绝对位置的信息。

键和查询

最后,我们将单词嵌入乘以矩阵 WQ 和 WK,以获得“查询向量”和“关键向量”,每个向量的大小为 64。

到目前为止提到的所有组件都绘制在下面的动画中:

输入序列、单词嵌入、位置编码、键和查询(作者图片)

请注意,我们绘制单个元素的顺序与计算元素的顺序无关。

并行化

在我们继续之前,有一点需要强调,那就是 Transformer 适合并行化的方式。请注意,所有的单词嵌入都可以并行计算。一旦我们得到了嵌入,我们还可以同时计算所有嵌入的查询向量和关键向量。这种模式将贯穿整个架构。请注意。

点积

我们计算“查询向量”和“关键向量”的所有可能组合的点积。点积的结果是一个单一的数字,在后面的步骤中将用作权重因子。权重因子告诉我们,在输入句子的不同位置的两个单词相互依赖的程度。这在原论文里叫自我关注。自我关注的机制允许变压器学习困难的依赖性,即使在遥远的位置之间。

“查询向量”和“关键向量”的点积(图片由作者提供)

缩放比例

随后,所有权重因子除以 8(关键向量 64 的维数的*方根)。作者假设在训练期间,点积的大小可以变大,从而将 softmax 函数推到梯度极小的区域。除以 8 会产生更稳定的梯度。

Softmax

缩放后的因子通过 softmax 函数进行归一化,因此它们都是正的,总和为 1。

在下面的动画中,我们对句子中第一个单词“the”的权重因子进行了缩放。请记住,属于第一个词的权重因子是点积:q1k1,q1k2,q1k3,q1k4。

属于第一个单词“the”的权重因子的缩放和 softmax(图片由作者提供)

类似地,对于输入序列中的其他单词“car”、“is”和“blue ”,我们得到:

属于剩余单词“汽车”、“是”和“蓝色”的权重的缩放和 softmax(图片由作者提供)

这就完成了权重因子的计算。

价值观念

与“关键向量”和“查询向量”的计算相同,我们通过将单词嵌入乘以矩阵 WV 来获得“值向量”。值向量的大小也是 64。

额外的

现在,我们将每个“价值向量”乘以其对应的“权重因子”。如前所述,这样我们只保留我们想要关注的单词,而不相关的单词通过用像 0.001 这样的小数字加权来抑制

总和

现在我们将属于一个单词的所有加权“值向量”相加。这就在这个位置产生了自我关注层的输出。

在下一个动画中,我们将描述“值向量”的计算以及随后对输入序列中的第一个单词进行的加权和求和。

第一个单词“the”的值、权重和总和(图片由作者提供)

类似地,对于我们输入序列中的其他单词“汽车”、“是”、“蓝色”,我们得到:

剩余单词“汽车”、“是”和“蓝色”的值、权重和总和(图片由作者提供)

自我关注的计算到此结束。自我关注层的输出可以被认为是上下文丰富的单词嵌入。根据上下文,一个词可能有不同的含义:

  • 我喜欢清爽的秋天天气。
  • 不要在去电车的路上摔倒

请注意,底部的嵌入矩阵只对单个单词进行操作。因此,对于两个句子,我们会错误地获得相同的嵌入向量。自我关注层考虑到了这一点。

较短的句子

输入序列的长度应该是固定的,基本上是训练数据集中最长句子的长度。因此,参数定义了转换器可以接受的序列的最大长度。长度更长的序列会被截断。较短的序列用零填充。然而,填充词不应该有助于自我注意的计算。这可以通过在自我关注计算中的 softmax 步骤之前屏蔽相应的单词(将它们设置为-inf)来避免。这实际上将它们的权重因子设置为零。

遮蔽未使用的位置(作者图片)

多头自我关注

不是执行单一的自我注意功能,作者使用了多个自我注意头,每个都有不同的权重矩阵。多头注意力允许模型在不同位置共同注意来自不同表征子空间的信息。原论文中的变压器使用了八个*行的注意头。注意头的输出被连接并再次乘以附加的权重矩阵 WO。

多头自我关注用 3 个头,原创论文用 8 个头(图片由作者提供)

添加并正常化

刚刚讲到的多头自关注机制是编码器的第一个子模块。它周围有一个剩余连接,然后是图层规范化步骤。图层标准化只是减去每个矢量的*均值,然后除以其标准偏差。

剩余连接,图层归一化(作者提供的图片)

正向输送

自我关注层的输出被馈送到完全连接的前馈网络。这由两个线性转换组成,中间有一个 ReLU 激活。输入和输出的维数是 512,内层的维数是 2048。完全相同的前馈网络独立地应用于每个位置,即输入序列中的每个单词。

接下来,我们再次在完全连接的前馈层周围采用剩余连接,然后进行层归一化。

完全连接的前馈网络、剩余连接、层归一化(图片由作者提供)

编码器堆栈

整个编码组件是六个编码器的堆栈。这些编码器在结构上都是一样的,但它们不共享重量。

六个编码器的堆栈(图片由作者提供)

在下一篇文章中,我们将讨论变压器的解码器部分。这应该是非常直接的,因为大多数需要的概念已经在这篇文章中介绍过了。

参考

原创论文
图文并茂的变形金刚
变形金刚解说
忙于文字嵌入

梦想成为大数据工程师?发现我们与软件工程师的不同之处

原文:https://towardsdatascience.com/dream-of-becoming-a-big-data-engineer-discover-what-sets-us-apart-from-software-engineers-603c7f8c2c29?source=collection_archive---------19-----------------------

我们做的不是同一件事

照片由詹姆斯·庞德Unsplash 拍摄

工程是所有公司的基本要素。没有它,公司就无法创造、维护和升级他们的产品。技术企业依靠他们的工程部门在竞争激烈的世界中生存。

即便如此,并不是所有的工程师都执行相同的任务。在重技术型公司中,软件工程师是最关键的资源之一。他们构建程序,创建软件,并维护系统的功能。许多其他职业道路与软件工程不同。他们专攻某一特定学科。

在数据领域,企业面临着数据量的巨大增长。我们需要有人站出来承担管理这些数据的责任。这开启了大数据工程师的曙光。大数据工程师可以从数据库管理员、数据架构师或数据分析师发展而来。

[## 大数据工程师的一天

为巴黎的一家广告技术巨头工作

towardsdatascience.com](/a-day-in-the-life-of-a-big-data-engineer-a286e4a5ae29)

大数据工程师和软件工程师的技能不同。尽管如此,许多公司倾向于将它们视为相同的实体。他们误用了工作描述中的术语。此外,他们在技术面试中会做出错误的假设。

在大多数情况下,软件工程师处理大数据工程师的工作。因此,他的职责变得复杂、模糊和多种多样。

作为一名大数据工程师,我强烈渴望巩固我们在公司层级中的地位。人们不得不把我们的职业视为一条与众不同的职业道路。要做到这一点,我们首先要定义我们是谁,以及我们与其他工程师有何不同。作为一个经常从事软件工作的人,我想指出我们与软件工程师不同的地方。

建模数据集

当需要数据的时候,就需要数据建模。这是我们定义表关系、命名列和测试查询的地方。

任何软件工程师都可以用少量的表创建一个数据库。大数据工程师可以管理数百个相互链接的表。解决各种问题需要一定的专业知识。我们如何连接表?这些栏目将采用什么格式?我们应该复制多少数据?

万花筒Unsplash 上拍摄的照片

一切都来自经验,数据建模也是如此。大数据工程师需要在构建数据集之前采取预防措施。一个错误就可能导致严重的性能问题或冗余数据存储。

大数据工程师不时处理数据建模请求。一个请求可以是简单的添加一列,也可以是复杂的为整个管道创建一个数据库。无论哪种情况,大数据工程师都需要首先评估变更对当前系统的影响。然后,他提出了一些优化来减轻这种影响。另一位熟练的大数据工程师将密切关注这一点,以保持一切符合标准

数据建模中使用的 ERD-实体关系图的示例。来源: Lucidchart

典型的数据建模过程始于设计阶段。大数据工程师收集所有业务和技术规范。这些因素包括可用收入、预期结果和一些限制因素。后续数据的一些草图将会派上用场。它可以向涉众展示我们将如何从源中检索数据,并组合它们以获得结果。

接下来是实施阶段。大数据工程师执行大量查询来验证其设计的可行性。我们会在合理的执行时间内完成查询吗?结果会包含想要的结果吗?一个严格、彻底和全面的设计阶段导致一个简单的实现。

如果现实与他的设计不符,大数据工程师会后退一步,审查他的解决方案。前前后后的评测需要几次迭代,直到正式发布。

典型的数据建模过程。作者署名

此阶段的成功允许大数据工程师进入验证阶段。这是数据集建模的关键步骤。利益相关者一起评估他的模型产生的数据的完整性。

该值必须与系统的其余部分一致。命名约定应该遵循内部标准,以避免混淆。数据结构应该是全面的。验证阶段需要对业务需求和技术用途有深刻的理解。

数据建模过程的其余部分包括文档、监控和维护。大数据工程师构建持久的数据系统,因此他应该照顾好自己的遗产。他的初衷对他的继任者来说一定非常清楚。他通过文档、操作说明和适当定义的监控指标进行交流。他渴望他的数据模型能够经受住许多系统性的变化。

***Key takeaways:***- To become a big data engineer, you need to know how to create databases first.
- Data modeling is a continuous process with many iterations
- A big data engineer must comprehend how his data interacts.

大数据执行编程

大数据执行由许多操作组成。这些包括数据操作,如 ETL——提取、转换和加载。如今,有许多工具可以自动化这些操作。剩下的就是编写指令了。

写大数据执行没什么复杂的。关键概念在于使用流行框架的能力。

Apache Hadoop 生态系统是首个成为行业主流的大数据框架。它的作业调度系统由 MapReduce 操作和一个资源协商器— YARN 组成。Hadoop 生态系统为我们提供了一个最小的 UI。它跟踪作业进度以及所使用的每个节点的系统日志。

[## 向六岁小孩解释 Hadoop MapReduce

好奇的头脑永远不知道自己的极限

towardsdatascience.com](/explain-hadoop-mapreduce-to-a-six-year-old-d338937c7f4b)

另一个基于 MapReduce 作业操作的流行框架是 Apache Spark。由于其稀疏性和灵活性,它在大数据公司中越来越受欢迎。Spark 架构由一个主节点和几个工作节点组成。 RDD 或弹性分布式数据集是与原点的核心区别。

编写大数据执行属于大数据工程师的日常活动。构建新的数据集、构建新的数据管道或处理来自源的数据。在完成对执行的编程后,他会将作业提交给数据调度程序。

数据调度器是一个执行作业的计时器。您可以为作业设置频率,定义重试次数,或者创建作业之间的依赖关系。一个著名的开源数据调度器是 Airbnb 工程师开发的 Apache Airflow

Apache Airflow 的核心概念之一是 DAG — 有向无环图Airflow creators 将 DAG 解释为一种简单的表示工作流程的方式。工作流由一组任务及其依赖关系组成。一个 DAG 包含有限数量的元素。顶点代表一组任务,边对应于它们的交互。DAG 中的一个简单约束是它在工作流中不存在任何循环。这意味着我们不能在同一个上下文中执行一个任务两次。

下面是一个使用 Apache Airflow 的作业调度示例

阿帕奇气流作业的一个例子。作者署名

***Key takeaways:***- A big data engineer spends most of his time on ETL-Extract, Transformation, and Load operations.
- Big data engineers leverage open-source tools to automize data processing

优化数据存储

企业在数据存储方面必须精打细算。它不仅是一种有限的资源,而且会成为数据操作的瓶颈。使用基于云的架构,建立数据存储系统变得越来越便宜。但是维护一个从来都不是简单的事情。

我们需要一个由一名数据库管理员、两三名数据架构师和一些数据分析师组成的团队。大数据工程师可以扮演这三个角色。

马库斯·斯皮斯克Unsplash 上拍摄

优化数据存储归结于对数据的理解。它从哪里来?它的本质是什么?我们将以何种格式存储它们?在将数据注入数据存储系统之前,分析数据从来都不是浪费时间。

大数据工程师已经掌握了预优化工具,但他需要更多。他承诺确保尽可能优化他的系统。他关心数据录取中的三件事:

  • 数据格式: 数据可以是文本、图像、图形。Hadoop 生态系统倾向于将 拼花 作为一种高效的格式。其他传统的基于 MySQL 的系统支持日志文件系统。例如,镶木地板以紧凑而闻名,但在结构改变方面缺乏灵活性。
  • 数据类型&压缩: inttinyint 下存储有四倍的 I/O 开销。即使是同一类型,值的范围也会影响一个列在存储系统中占用的空间。具有连续相同值的列最适合基于列的数据存储。其他因素包括垂直/水*分区、压缩算法和基于行或基于列的数据库。
  • 数据留存: 有些数据在我们的系统中是无法永恒存在的。旧的、不相关的和不合适的数据不应保留在存储中。我们通过保留策略来定义数据的生命周期。这取决于技术限制和业务需求来决定时间框架。不用说,存储中的冗余数据等于金钱损失。

公司经常忽视数据存储优化,因为它令人望而生畏且单调乏味。但是数据驱动的企业最好把数据当成他们的产品来对待。大数据工程师有助于保持健康的存储系统,并尽可能获取最大利润。

***Key takeaways:***- Data storage optimization equals to saving money
- Most of data storage engine are pre-optimized, but it requires another layer of comprehension to save more space.

创建数据管道

一个数据管道是一个数据流。数据通常从一个地方移动到另一个地方以服务于不同的目的。输出数据用于报告、机器学习模型培训和商业决策。

稳定、不间断和准确的数据传输是必不可少的。我们需要确保整个流程的一致性。我们不能容忍任何信息丢失。

要创建数据管道,大数据工程师需要将上述所有活动结合起来。数据管道是许多数据所有者实体之间的协作。他们可能没有相同的标准。因此,大数据工程师应该对他的输入和输出数据了如指掌。

[## 如何构建可扩展的大数据分析管道

大规模建立端到端系统

towardsdatascience.com](/how-to-build-a-scalable-big-data-analytics-pipeline-7de18f8be848)

数据块是典型数据管道的最小可行元素。它包含数据库、存储/分析引擎和许多输入/输出连接器。这种模块化架构有助于打造一个灵活、稳健的数据管道。我们可以随意添加、删除、修改任何块,而不会严重影响整个系统。

一个数据块的例子。作者署名

大数据工程师构建持久的数据管道。维护和建设一样重要。我们能做些什么来创造一份持久的遗产呢?记录业务需求,跟踪查询执行情况,并省去事故手册。数据管道生命周期从产品规格开始,到报告仪表板,以及之后很长一段时间。

***Key takeaways:***- Data pipelines are the spine of a data system
- A modular-based architecture enables big data engineers to efficiently construct data pipelines

结论

我们了解了将大数据工程师与软件工程师区分开来的活动。尽管如此,他们还是有很多共同点。大数据工程师必须知道如何使用软件,正如软件工程师必须知道如何处理数据一样。

我叫 Nam Nguyen,我写关于大数据的文章。享受你的阅读?请在 Medium 和 Twitter 上关注我,了解更多更新。

做梦超过文字!

原文:https://towardsdatascience.com/dreaming-over-text-f6745c829cee?source=collection_archive---------40-----------------------

把深梦的想法延伸到文字资料!

“DeepDream 是一项将神经网络学习的模式可视化的实验。类似于当一个孩子观看云并试图解释随机形状时,DeepDream 过度解释并增强了它在图像中看到的模式。

它通过网络转发图像,然后计算图像相对于特定层激活的梯度。然后图像被修改以增加这些激活,增强网络看到的模式,并产生一个梦一样的图像。这个过程被称为“创意主义”(指的是创意网电影盗梦空间)。"

https://www.tensorflow.org/tutorials/generative/dee】T4 警梦

让我给你分析一下。考虑一个卷积神经网络。

LeNet-5 架构

假设我们想要检查当我们增加突出显示的神经元激活 h_{i,j} 时会发生什么,并且我们想要在增加这些激活时将这些变化反映到输入图像上。

换句话说,我们正在优化图像,以便神经元 h_{i,j }发出更多的信号。

我们可以把这个优化问题表述为:

作者图片

也就是说,我们需要通过改变图像来最大化 h_{i,j} 的*方范数(简单来说就是幅度)。

当我们按照上面所说的去做时,会发生这样的事情。

(图片由 Von.grzanka | ( )图片由 Tensorflow 教程

这里的原因是,当 CNN 被训练时,中间层的神经元学会了看到一些模式(这里是狗脸)。当我们增加这些激活时,输入图像开始包含越来越多的狗脸,以最大化激活。

在文本上实现深度梦背后的直觉。

就像图像中的 deep dream,如果我们把任何一个隐藏层激活,并试图增加它的范数,文本输入会发生什么?
为了回答这个问题,采用了文本分类模型,并设置了损失函数来增加隐藏层的激活程度。我们希望看到这个隐藏层学习到的模式/表现。

嵌入层

作者图像|计算句子嵌入的图像显示方法。

神经网络模型不能理解单词。为了将单词作为输入,这些单词被转换成一个称为嵌入的 n 维数组。每个单词转换成特定的 n 维数组。为了得到句子嵌入,我们简单地取句子的*均值,然后这个数组被作为输入馈送给模型。这种方法解决了句子长度可变的问题,可以与香草人工 神经网络协同工作。

模型

作者图片

使用了一个经过训练的模型来对 IMDB 评论进行分类。模型验证准确率达到 80.10%

设置该实验是为了捕捉由全连接层 2FC2 给出的表示,简而言之,具有 512 尺寸。

使用的成本函数是 fc2 输出的标准。

注意:因为“单词序列”是长张量,它们不能被反向传播优化。相反,句子的嵌入表示被优化。

程序概要

步骤 1:将句子转换成张量。

第二步:获得句子嵌入

第三步:通过 fc2 层,得到 fc2 输出

第四步:优化语句嵌入增加 fc2 层输出

步骤 5:对于给定的迭代次数,用当前的句子嵌入重复步骤 2 到步骤 4。

作者图片

结果

实验 1

简单句用于获取我们保存的分类结果及其对应的句子嵌入。

比如: “我讨厌这样。”,“我爱这个节目。”,我们用来分类。这些句子非常简单,分别传达了一种消极和积极的情绪。

对这些嵌入进行了梦想或优化,并记录了迭代激活图。

作者图片

这里可以观察到几件事情。

  1. 对于这两个句子,隐藏层表征的激活几乎是线性增加的
  2. 这些句子的激活是不同的,这意味着模型可以很容易地区分这两个句子。

对于句子:“我爱这个节目。”。 模型正确地将此预测为

相似词测验

作者图片|基于相似度的词云。大字体意味着更相似。

最初,句子嵌入更类似于中性词,如“this,it,even same ”,但随着我们增加 fc2 激活的幅度,句子嵌入变得类似于积极的词,如“great,unique ”,这是有意义的,因为模型预测它是一个积极的句子。可视化迭代中的嵌入。

图片作者|动画展示了嵌入是如何从负面词汇走向正面词汇的。

作者视频|我们将肯定句的嵌入可视化。观察句子嵌入如何随步骤变化。

试嵌入此处 在 Tensorflow 投影仪上

观察句子嵌入如何从 step_1 开始并移动到 step_21。句子嵌入开始于肯定词否定词之间,随着算法的梦想,嵌入向肯定词移动。

试试这些东西。

观察 3d 中的嵌入。

找到类似 step_1 的词。

找到类似 step_21 的单词。

对于句子:“我讨厌这样”* 模型正确预测此为 *

相似词测验

首先,我们观察做梦前后与句子嵌入相似(余弦相似)的词有哪些。

作者图片|基于相似度的词云。大字体意味着更相似。

最初,句子嵌入更类似于中性词,如“ this,it,even,same ”,但随着我们增加 fc2 激活的幅度,句子嵌入变得类似于单词“ bad,nothing,bad”,这传达了否定的意思,这是有意义的,因为模型预测它是否定句子。

可视化迭代中的嵌入。

为了可视化迭代中的嵌入,使用 TSNE 算法将嵌入维数从 100 减少到 2 。这些嵌入被绘制在一个 2d 地图上,用红点作为负面词(如一个坏的、更坏的、卑鄙的、错误的词语),用绿点作为正面词(如伟大的、著名的、美妙的词语)。

灰点是句子嵌入的中间位置,黑点*是句子嵌入的最终位置。*

作者图片| 2d 空间上的 100 维嵌入

试嵌入此处 在 Tensorflow 投影仪上

该图清楚地显示了嵌入远离正面单词并接*负面单词,这与模型预测一致。而且最后的句子嵌入现在更像红点(否定词)而不是绿点(肯定词)。

这里的关键观察是,最初,句子嵌入在正面和负面单词之间,但是随着做梦的进行,嵌入被推离负面单词。

结论

做梦后的单词嵌入变得与“模型预测”中的单词相似,尽管如果我们观察初始嵌入的相似单词,它们对于两个句子或多或少是相同的,即使它们表达非常不同的意思,最终的句子嵌入显示出一些有趣的模式。

例如

1.否定预测被推*到像 错误、肮脏、恶劣 这样的词语

2.正面的预言被推*到像**的词语独特的、伟大的、享有盛名的****

实验二

我们现在将使用难句。前半句表达一种情感,后半句改变情感的句子。

像这样的句子

  • 这部剧很长很无聊,但是导演很棒。
  • 我讨厌这部剧,因为里面有裸体,但表演很经典。

人类很难判断这些句子表达了什么样的情感。

我们将再次优化句子嵌入,以最大化 fc2 层的激活。

作者图片|作为迭代函数的 fc2 层激活标准

不像第一种情况。两个句子的激活差异不大,即这些句子的激活或多或少相似,这意味着模型对这些句子没有分类能力。
我们来看看这些句子做梦前后的*义词。

“这部戏很长很无聊,但是导演真的很棒。”,模型预测为正

相似词测试

我们会发现类似于句首 vs 句尾嵌入的词。

作者图片

嗯,即使这个句子被归类为积极的,类似于最后一句嵌入的词并没有反映任何积极的情绪。

“我讨厌这部剧,因为它的裸露,但它的表演真的很棒。”,*模型预测为负***

相似词测试

作者图片

这个句子被归类为否定句,梦后的嵌入反映了消极情绪。

结论

由于模型对这些句子没有清晰的理解,所以做梦后这两个句子的句子嵌入几乎是相似的(做梦后看相似的单词)。这是因为模型在其隐藏层中没有这些句子的丰富表示。**

我们从研究图像上的深度梦如何工作开始,然后我们提出了如何在文本上实现深度梦。最后,我们展示了如何正确解释结果。这种方法可以用来理解语言模型已经学习了什么样的隐藏表示。

像这样的实验帮助我们更好地理解这些黑盒。

您可以在本笔记本中尝试一个演示。

所有相关代码可在 my Github Repo 获得。

参考

  1. 基于梯度的学习应用于文档
    识别
  2. https://ai . Google blog . com/2015/06/in ception ism-going-deep-into-neural . html
  3. https://www.tensorflow.org/tutorials/generative/deepdream】
  4. https://youtu.be/YHAIrwRVvWg?list = plyqspqzte 6m 9 gcgajvqbc 68 hk _ JKGBAYT
  5. https://py torch . org/tutorials/初学者/text _ 情操 _ ngrams _ 教程. html

dream scape——利用人工智能创造虚拟现实环境

原文:https://towardsdatascience.com/dreamscape-using-ai-to-create-speculative-vr-environments-bdfedd32ae54?source=collection_archive---------22-----------------------

人工智能能让我们梦想另一个现实吗?

Dreamscape 是一个探索数字城市的工具。基于对机器学习在建筑、城市化和游戏设计的虚拟空间中的生成能力的研究和调查。

摘要

随着人工智能(AI)越来越普及,它所带来的机会也越来越多。本文探索了机器学习工具,如生成性对抗网络,以及它们利用现实世界的数据推测新梦境的能力。我利用创造性的人工智能作为生成代理来推测城市景观,并在沉浸式虚拟现实( VR)环境中可视化它们。导致了建筑调查工具“梦景”的产生。最后,我探索了未来视频游戏的设计是如何自我生成的,它们的图形是如何由用户驱动的。

介绍

2010 年,街机大火乐队为他们的歌曲 【我们曾经等待 】推出了一个互动音乐视频。他们与谷歌合作,通过观众的过去精心制作了一个独特的情感之旅。在线体验首先要求观众在文本框中输入他们童年的地址,然后音乐视频开始播放,观众被神奇地传送到所述位置。通过展示空中和透视镜头,以富有节奏的歌曲为背景,这一街区变得栩栩如生。这个进入受试者生活的情感门户是谷歌地图技术的一个广受好评的创造性应用,让人们一瞥隐藏在收集和生成的大量数据中的创造性潜力。

图 1:仍然来自“市中心的荒野”,展示了用户童年家园的场景|来源:谷歌公司+街机火灾

随着最*遥感技术的进步,相机和用于将相机发射到太空的技术变得更加容易获得,导致数百个传感器被部署来点击来自太空的图片。而一队配备有 360 度视角相机的人、汽车和飞机帮助勘测所有七大洲的街道和岩层。谷歌地图和街景已经获得了前所未有的大量图片。街景*台已经成功捕捉到真实世界,并将其转化为数字化的虚拟空间。只需点击几下鼠标和一个人形图标,我们就能被传送到地球的任何一个地方。通过这一过程,谷歌科技试图将现实数字化。利用绘图和投影技术,我们的世界被抽象成数字世界。用户已经很好地适应了这个数字领域,在其中自如地导航,就好像它是真实的一样。在本文中,我将探索这些数据中潜在的创造性潜力,将其与生成工具结合起来,探索新的空间和形式。从图像失真开始,我们将把 AI 带入 VR 空间,以帮助推测游戏设计和架构。最后,通过这次探索,我创造了一个名为 Dreamscape 的工具,这是一种在虚拟现实环境中可视化城市景观的方法,将谷歌街景的数字化现实与 StyleGAN 的潜在空间融合在一起。在我们深入实验之前,我将提供一些关于网格、投影和风格转换的基本背景。如果您已经掌握了这些主题,请直接跳到方法。

图 2:谷歌地球三维视图|来源:作者

背景

谷歌通过从捕获的图像中提取数据来数字化我们的现实。他们使用一种叫做深度图分析和摄影测量的技术(从不同角度将同一物体的图像拼接在一起的过程)来生成一个三维网格。这个三维网格然后被纹理化,并在其上映射图像,使其看起来更真实。这类似于动画师为游戏和电影创造角色所使用的技术(见下面的图 3)。

图 3:左起:展开的 UV 纹理贴图、网格对象和纹理贴图网格|来源:作者

当一个纹理贴图被包裹到基础窗体上时,它的视觉质量会改变。如果不操作三维网格,可以通过扭曲基本纹理来改变外观。这是一个机会,可以将这项技术与人工智能图像生成技术的进步结合起来,使用卷积神经网络 (CNN)和生成对抗网络 (GAN)

图 4:风格转换示例,来自使用卷积神经网络的图像风格转换|来源: Leon A. Gatys

使用 CNN 的物体识别和表示语义信息(允许从风格中分离图像上下文)的进步成为导致创造性人工智能代理发明的不可或缺的过程。创造性人工智能中最早和最流行的自生成图像工具之一是神经风格转移。2016 年,Leon A. Gatys 写了一篇论文,概述了使用 CNN 计算图像到图像风格转换的框架。用最简单的话来说,它使用图像 A 的风格(纹理、颜色等)并将其嫁接到图像 b 上。这导致了一些工具来复制著名艺术家如毕加索的绘画的外观和感觉,这在风格转移实验中很受欢迎。通过训练 AI 来识别图像 A 的图案和纹理,同时将其与图像 b 中识别的对象和特征混合来存档。例如,在下面的示例中,中间一组图像描绘了猫图像的风格转移过程。标记为输出的图像显示了样式图像的纹理和色调如何转移到内容图像的结构上。结果是一种混合,其中猫的轮廓是可见的,而颜色,色调和纹理是显着不同的。

图 5:使用样式转换的三维纹理操作|来源:作者

在上述风格转换和纹理映射原理中发现的过程的基础上,图 5 中的实验试图通过操纵基础图像来扭曲 3D 形式。通过在基础纹理图像上运行风格转换,并将其映射回胸部。与原始半身像相比,生成的网格在特征和分辨率方面有所损失,同时创建了新的细节和折痕。在我制作 Dreamscape 的早期,我试图在这个基本测试的基础上,探索风格转换如何被用来扭曲来自谷歌街景的数据。

方法:创造性人工智能中的实验

虚构的世界和景观作为建筑投机和游戏的背景。在某些情况下,精心设计的世界被忽略了,通常是为其他行为和交互提供和创建沉浸式环境。在某些情况下,它们设计得如此之好,以至于它们看起来和感觉上都像我们自己的环境,通过用户的动作成为无缝集成虚拟和现实的空间载体。随着大量数据被收集并输出到公共领域,我们探索其潜力;从二维图像*面,扩展到使用人工智能的第四维模拟。

等等,他是说第四维吗?这是真的吗?

—本实验中的第四维指的是时间、空间、生长和/或运动。

在过去的几年里,人工智能研究的快速发展导致了新*台的出现,这些*台提供了用户友好的机器学习工具。像谷歌 Colab 这样的*台和像 RunwayML 这样的预包装软件解决方案,使得探索人工智能创造性方面的能力变得简单得多。在这项调查中,我探索了展示创造性人工智能潜力的四种方法:

(1)探索图像生成的风格;

(2)梦境生成器——虚拟现实中的人工智能测试

(3)虚拟现实中的潜在空间探索

(4)从可视化中提取三维数据的工作流程。

1)使用 StyleGAN 探索二维空间。

在这一节中,我测试了 StyleGAN 来生成独特的、虚构的地图、风景和城市图像。StyleGAN 是一个生成性的对抗网络,它基于在训练图像中发现的特征来构造新的图像

图 RunwayML 上的 style gan |来源:作者

数据集。这是 NVIDIA 团队在 2018 年末创造的一种方法。例如,在来自闪烁的人脸数据集上训练的 StyleGAN 将开始从训练数据集生成具有相似特征的新人脸。然而,来自 GAN 的每个结果都是唯一的,并且与原始数据集中的任何图像都不相同。根据训练数据集的大小,GAN 模型可以产生极其相似和令人信服的结果。目前,在公共领域有许多预先训练的模型,从星云到卧室内部。图 6(上图)显示了一个运行 StyleGAN 的示例,它形成了一个对 10,000 幅风景图像进行训练的模型,从而产生了独特的虚拟世界。一旦经过训练,GAN 就能够在几分钟内创建具有不同相似度的图像(当被赋予所需的处理能力时)。图 6 中 35 幅图像的网格花了 92 秒生成。把新的能力交给数字艺术家,作为探索的工具。

图 RunwayML 上生成的城市景观图片来源:作者

对于观察者来说,GAN 的每个输出都是一幅图像,但是对于机器来说,它只不过是一系列数字,范围从负 1 到 1。这串数字可以保存为一个 JSON 文件。如果我再次通过 StyleGAN 模型反馈相同的字符串,我们将得到相同的图像。当我们编辑字符串并把它放回模型时,我们得到不同的图像。这是通过访问保存在经过训练的 GAN 模型的潜在空间中的信息来完成的(我将在下面进一步解释潜在空间)。因此,如果组成我们图像的这串数字以小步骤递增地编辑并反馈到系统中,那么结果图像将与原始输出相似,而如果我们显著地改变变量串,则输出将完全不同。我们可以使用 P5 (处理的的在线版本)自动调整变量字符串,并在 RunwayML 中运行它。逐步改变变量将有助于生成具有相似特征但仍然独特的图像,当输出以视频格式排列在一起时,它为我们提供了一系列连续的视觉效果。一幅图像与另一幅图像融合在一起,形成了一个无缝而美丽的转变。这种形式的输出基于对潜在空间的插值过程。

插值,那是什么?

源自数学,插值是两个数据点之间的一种估计,并在它们之间创建一个*均数据点。在计算机图形中,这被用作在两个关键帧之间创建填充帧的一种方式。通常用于提高帧速率,使用半自动处理。

图 8:潜在空间的插值。来源:黑客月潜在空间可视化

潜伏空间 ,那是什么?

潜在的定义意味着隐藏。潜在空间压缩数据的可视化。压缩的可视化发生在神经网络的各层内,在学习过程中提取维数减少的表示作为特征。我把它想象成 GAN 的记忆库,我们通过编码和解码来访问它。它是“空间”的想法很有趣也很重要,正如在上面的实验中所看到的,具有潜在空间的相似物品被放置得更*,而不相似的物品被放置得更远。重要的是要记住(不)相似性是 GAN 从训练数据集中学习到的结果,对我们来说似乎显而易见的东西对训练的模型来说可能不是。

图 9:卷积神经网络的描述。来源:Hackernoon 潜在空间可视化。

回到实验,图 10(下图)中的结果显示了插值是如何帮助探索潜在空间的。随着视频的播放,新的形式从旧的形式中涌现出来,并随着时间逐渐变化。最终的架构建立在自身之上。这个场景有一种统一和发展的感觉,随着逻辑的建立而扩展开来。新的空间从空间中出现,展示了过多的构造可能性。从白天到夜晚,从亮到暗,从行驶的汽车的窗户里,景色不断变化。奇异的图像被赋予生命,不再是一次性的;而是一个超越静止的连续体,进入一个具有多重空间可能性的新的维度领域。坚持维度的想法,下一个测试通过在 3d 环境中测试 StyleGAN 来进一步探索前景。

图 10:城市景观生成|来源:作者

2)将人工智能带入虚拟现实——梦境创造

利用 StyleGAN 和潜在空间,项目的下一阶段导致了使用可用的人工智能工具创建沉浸式体验的探索。像虚幻引擎Unity 这样的软件是为虚拟现实生成和可视化空间而设计的。作为起点,原始数据来自谷歌街景,下载 360 度的图像,这些图像将构成可视化的基础。该图像通过 StyleGAN 进行处理,旨在在 Oculus、HTC Vive 或谷歌 DayDream 等沉浸式浏览器中体验。我们将使用上面讨论的沉浸式组件作为一种方式来测试如何使用潜在空间的插值来模拟运动的假设。

图 11:曼哈顿上的球形图像|来源:作者

为了探索在沉浸式环境中查看这些图像这一看似简单的任务。当我们开始实验时,一些挑战出现了。首先,球形图像的纵横比是 2∶1。而大多数预训练模型的比例为 1:1(通常为 512 X 512 像素或 1024 X 1024),或 4:3(高清比例)。重要的是要注意,当一个人训练新模型时,它们是建立在现有模型之上的。这个过程被称为迁移学习。它有助于节省时间和处理能力,与训练一个全新的数据集相比,它减少了四分之一。图像上的鱼眼失真也是一个挑战,对用户来说不是很大,因为我们知道这是一个展开的图像,但对机器来说更是如此。与深度学习的内在逻辑——模式识别与特征提取——**不懂失真。这限制了工具集的当前功能。然而,通过一些变通办法,我们可以回到手头的任务,在虚拟现实中探索 StyleGAN。

dreamscape——一个导航谷歌街景数字化现实的工具,可以选择不同的风格来变形和改变背景。

图 12:梦景演示:曼哈顿|来源:作者

我们使用一种被称为盒子投影的技术,一种打破我们特殊图像的过程。用最简单的话来说,想象你(观众)在一个盒子里,如果一个图像被投射到盒子的所有侧面,在角落里是无缝和不间断的,我们可以想象整个空间是连续的。使用这种盒子投影技术,我们能够继续并检验假设。使用这个工作流程,我为 Dreamscape 创建了原型。一个导航谷歌街景的数字化现实的工具,能够选择风格来变形和改变上下文。在上面的演示中,(图 12)观众从投射的现实进入一个虚构的世界。他们轻松地从一个地方移到另一个地方。在下一个实验中,我们将前两种技术结合起来,创造一个能够动态变化的梦境。

图 13: Dreamscape 工作流程

图 14:植物生长时间周期|来源: Tarninabarn

3)虚拟现实中的潜在空间

本节探讨在 VR 中使用插值的潜力。这样做的潜力是将身临其境的环境带入生活。它可以用来模拟时间的维度和/或模拟运动。通过改变我们看到的图像来改变视觉空间。这方面的一个简单例子可以在左边的延时 gif 中看到。植物的生长赋予我们所看到的形象以生命。

为了开始测试这个假设,我们首先创建我们的盒子投影图像。我们训练 styleGAN,并从所述图像开始创建插值,并对它们进行操作。有了合适的设备和实时渲染功能,我们可以使用 Unity 构建一个系统,并指定触发器(如头部的移动)来开始和暂停插值。一个有待未来实验检验的概念。但是现在,下面的下一个方法将探索从这个维度空间中提取正式数据的能力。

4)从维度空间提取三维数据。

到目前为止的探索集中在与背景相关的问题上。这个实验试图使背景生动起来,并利用产生的数据。为了占据这些数据并在游戏空间和建筑设计中探索它,下面的实验推测了从潜在空间提取 3-D 信息的方法。如果掌握了,这将是在短时间内创造大量虚拟空间的强大工具。使用像边缘检测分割和特征识别(如下所述)这样的工具,我形成了操纵基本三维几何图形所需的输入。我推测一个工作流程,将导致从潜在空间的三维形式的创作。

图 15:3d 数据提取的 Dreamscape 工作流程

深度分析:

在 3-D 计算机视觉中,深度图是一个图像或图像通道,它包含与场景对象的表面离视点的距离相关的信息。深度分析成为一个使用 AI 投射到图像中收集信息并从中创建深度图的过程。对于包括场景理解和重建在内的许多应用来说,这是一个基本的过程。在这个实验中,它帮助创建一个给定图像的空间层次。分割出前景和背景,有助于创建过程中的第一步。

图 16:左起—原始图像,深度分析,边缘提取|来源:作者

细分:

分割是识别给定图像中不同元素的过程。例如,检测建筑物、狗、人类,在它们周围创建轮廓,并将其分离出来。它是对象检测和边缘分析的结合,帮助我们分解图像的组成部分。

图 17: DeepLab V3 图像分割|来源:谷歌公司。

特征识别:

与分割类似,特征识别分解并识别图像中的元素。在这种特殊情况下,它进一步分解了已识别的元素,例如在建筑物分离出窗户、门和墙的情况下,为我们提供有关特征的形式和位置的特定信息。

图 18:立面提取|来源: Wolff,Collins &刘

结合这些过程,我们可以收集数据来开始操作基本表单。使用 unity 中的脚本,可以在 3D 空间中重新创建可视化的场景。这对于建筑设计师来说是一个有用的工具,是推进设计的投机过程之后的下一步。

结果

上述实验有助于分解从 2D 图像移动到人工智能工具生成的潜在空间的方法,特别是 StyleGAN。超越*坦的 2D *面有助于打开使用这项技术可以实现的新的可能性。利用框映射技术,在 VR 中实现 StyleGAN 的沉浸式体验是可能的。它有助于产生我称之为梦境的东西,一个从现实世界数据中诞生的看不见的世界。

这些实验确实暴露了一些限制,首先也是最关键的限制是处理能力。为了实时运行这样的梦境,需要巨大的处理能力,但随着技术的进步,这将变得更加可行。输出的分辨率和清晰度将是第二个障碍,但这也与处理能力和预训练数据的处理有关。这就把我们带到了策展的第三个问题,一个更容易解决的问题,策展在这种情况下也与我们可以接触到的风格数量有关。如果你有 10,000 张以上的图片,就有可能创造新的风格和训练一个 GAN。这是可能的,但是需要处理时间和大量的精选训练数据。也就是说,这项技术的可能实现范围很广。他们从讲故事的新的创造性形式到建筑思考,以及游戏图形仅仅是个开始。在下一节中,我将讨论这些可能性,同时思考当前的趋势和已经在使用类似技术的例子。

结论和未来的可能性

2016 年,一个程序团队创造了一款名为 无人天空 的游戏,这是一款程序生成的游戏,诞生于 60 万行编造行星、宇宙和星系的代码。玩家被丢到其中一个星球上,那里有 18,446,744,073,709,551,616 个独特的星球可供探索。玩家在游戏中的唯一目的就是探索那些植物。

图 19:无人区|来源:Hello Games

无论玩家在哪里,他们总是在中心,即使有大约 18 万亿个行星;游戏只渲染玩家的周围环境,因此除非有人类见证,否则什么都不存在。无人的天空的强大之处在于,它不仅是一个生成性的人工智能,而且突出了用户/观察者/观众的重要性。

人工智能是一种工具,有可能在我们的一生中彻底改变设计和艺术的过程,然而,它也可以只是作为一种代理人来帮助我们进行思考和创造。Dreamscape 是一个工具,让用户能够根据个人喜好控制图形——增强游戏和其他数字化现实的体验。在论文的最后一部分,我探索了作为游戏设计师和建筑师代理人的梦境的含义。

“人工智能是一种工具,有可能在我们的一生中彻底改变设计和艺术的过程,然而,它也可以被用作一种代理,帮助我们进行推测和创造。”

游戏设计:

人工智能在游戏设计中的应用非常丰富,从机器生成的世界到通过前卫渲染模块可视化的新故事体验。使用计算机视觉中的深度学习将运动数据从物理模型移植到虚拟模型上得到很好的研究。而甘的探索则让游戏角色的开发利用了迁移学习(比如甘生成了动漫人物)。现在,深度学习的新领域显示了在完整的游戏环境中风格转移的潜力。其示例见 Chintan Trivedi 的演示,用于将堡垒之夜转换为 PUBG 。为游戏提供不同的图形包供用户选择,并赋予用户自己定制的能力。

图 20:将堡垒之夜变成 PUBG |来源: Chintan Trivedi

人工智能的另一种可能性是作为一种手段,从现实世界中产生新的看似熟悉的背景。如果我们在 Dreamscape,的第一次实验中切换输入和输出,我们可以开始将游戏中的背景变成用户已知的设置/位置。例如,想象一下玩一个类似 GTA 的游戏——你体验的不是洛斯桑托斯,而是达拉斯、迈阿密或纽约。把的潜在空间插值成的组合自有一套可能性。它们可以成为创造不断变化的背景的一个不可或缺的工具,从而产生永无止境的自我生成游戏的可能性。游戏中的背景可能会变得动态——根据玩游戏的用户的行为和性格而变化、学习和发展。在虚拟现实中,插值提供了模拟成长的可能性,甚至可能是时间和运动的元素。这些例子指向了对视频游戏中渲染模块的重新评估,我们可能会脱离传统方式,进入一个人工智能作为渲染代理的世界,根据用户的需求和心情召唤出实时渲染。

图 21:梦境|来源:作者

建筑和城市化:

在建筑和城市规划中,GANs 的使用为思考和实践开辟了新的方法。他们正在变成设计的创意代理人和助手。使用预先训练的 GAN 模型,人们能够快速呈现出数百个具有特定风格和类型的选项。并且通过在潜在空间上的插值,可以进一步开发和探索那些方案。这并不局限于城市景观或门面。例如,图 22(如下所示)描述了一个 GAN 改造现有*面图的可视化。机器通过各种可能性运行,而设计师则被留下来管理输入并选择最成功的迭代。**

图 22:甘生成的*面布置图|来源:作者

在这篇论文的前面,人工智能的其他建筑机会被回避使用 Dreamscape梦景、(顾名思义)的最初应用是帮助人们梦想新现实的可能性。它的目的是帮助想象和推测超越当前的世界和条件。梦想或想象是走向改变的第一步。梦想和想象变化是一种奢侈,大多数人都没有,但一旦他们可以想象,它就进入了可能性的领域。Dreamscape 是一个工具,让人们、社区和设计师能够推测新的可能性,想象现有环境之外的变化,希望能够想象出不同的未来。随着 VR + ML 的出现,建筑师和人们将能够参与完全沉浸式的设计可视化,这将快速生成并实现。他们将能够提供与类型和风格相对应的输入,同时能够在 VR 环境中以一对一的比例可视化结果。

这项调查让我进一步探索人工智能创造新世界的能力。在创造性人工智能的可能性领域,我们仅仅触及了表面。使用插值作为工具探索潜在空间的研究似乎很有希望。GAN 的隐藏层和压缩的潜在空间是如何被进一步访问和创造性地使用的,这将是令人着迷的。以及虚拟现实在未来为创造性人工智能打开的大门。

文献学

基于风格的生成式对抗网络生成器架构

人工智能生成的视频游戏图形 NVIDIA

视频游戏人工智能概述

揭开神经类型转移的神秘面纱

谷歌地球令人难以置信的 3D 图像,解释

人工智能将如何革新视频游戏的开发和游戏方式

使用卷积神经网络的图像风格转换

潜在空间可视化深度学习

神经 3D 网格渲染器

规则性驱动的建筑立面在鸟瞰图和街景之间的匹配

从自然图像中自我监督学习 3D 对象

理解机器学习中的潜在空间

提及次数:

达纳·卡沃斯(Dana Karwas)耶鲁大学艺术与媒体合作中心主任

鲍比·贝里耶鲁大学艺术与媒体合作中心 (CCAM)创新研究员

耶鲁大学数字人文实验室的实验室经理凯瑟琳德罗斯 。

道格拉斯·杜海姆 ,耶鲁大学数字人文实验室的全栈开发者。

同学们,机械神器——2020 年春天,耶鲁大学

如有疑问或合作,请联系 作者 。在 上找到我

学习 Wolfram:装扮您的数据可视化

原文:https://towardsdatascience.com/dressing-up-your-data-visualization-da7b41b15c6f?source=collection_archive---------45-----------------------

如何把一个基础剧情变成一个牛逼剧情

(图片由作者使用NOAAUnsplash 上拍摄的照片)

数据可视化可能是一件棘手的事情。您希望您的数据光彩夺目,但是大多数编程语言(包括 Wolfram 语言)都提供了非常基本的默认可视化外观。装扮一个形象以最大化其吸引力的过程通常是一个试错的过程。这个故事探讨了如何使用一些技巧和窍门来使事情变得简单,从而制作一个吸引人的可视化。

让我们从最简单的图开始,一个简单的 sin(x)图,其中 x 的范围从 0 到 2π:

Plot[ Sin[x], {x,0,Pi} ]

(图片由作者提供)

显然,这是一个有用和有效的正弦图渲染,但它有点裸露。添加框架、标签和填充为可视化提供了上下文,并有助于查看者理解什么是重要的:

Plot[Sin[x], {x, 0, 2 Pi}, 
 Frame -> True, Filling -> Axis, 
 PlotLabel -> "f(x) = sin(x)", FrameLabel -> {"x", "sin(x)"}]

(图片由作者提供)

最后,添加网格线和改变颜色使绘图具有自定义外观,并易于嵌入具有给定样式的在线仪表板中:

Plot[Sin[x], {x, 0, 2 Pi}, 
 Frame -> True, Filling -> Axis,
 PlotLabel -> "f(x) = sin(x)", FrameLabel -> {"x", "sin(x)"},
 GridLines -> Automatic, Background -> Black, PlotStyle -> Orange]

(图片由作者提供)

为了使这更容易,Wolfram 语言预装了八个主题。每个主题都有一组独特的外观设置来创建常见的地块样式:

让我们更进一步,使用一个实际的数据集。我使用 Wolfram 数据仓库来选择一个。这个知识库有超过 800 个数据集,由 Wolfram 及其用户社区提供。我挑选了一个非常好的数据集,名为“英格兰中部哈德利中心温度(HadCET)”:

[## 哈德利中心英格兰中部温度(HadCET)数据集

CET 数据集是世界上最长的气温仪器记录

datarepository.wolframcloud.com](https://datarepository.wolframcloud.com/resources/dzviovich_Hadley-Center-Central-England-Temperature-HadCET-Dataset)

您可以通过简单地引用它的名称来获得这个数据集。为了减少图中的抖动,我通过移动*均计算来运行数据:

data = ResourceData["Hadley Center Central England Temperature (HadCET) Dataset"];
data = MovingAverage[data, Quantity[5, "Years"]]

结果是一个 TimeSeries 对象,它可以直接用于可视化功能,如 DateListPlot :

(图片由作者提供)

与之前的一样,基本的日期列表图非常简单:

DateListPlot[data]

(图片由作者提供)

我们可以添加与之前正弦图相同的样式,但是有两个更有趣的选项,叫做序言结尾Prolog 选项允许您在渲染轴和帧之后、绘制数据之前插入图形元素(线条、多边形、图像)。 Epilog 选项允许你绘制最终的图形图元,这些图元位于包括数据层在内的所有其他图形的顶部。

DateListPlot[data, 
 PlotStyle -> {White, AbsoluteThickness[1]}, 
 Prolog -> Inset[image1, Center, Center, Scaled[{1.2, 1.2}]],
 Epilog -> Inset[image2, Scaled[{1, 0}], {Right, Bottom}, Scaled[{0.2, 0.2}]],
 Filling -> Axis,
 FillingStyle -> Opacity[.3],
 PlotLabel -> Style["Hadley Center Dataset", Bold, 24, FontFamily -> "Copperplate Gothic"],
 FrameLabel -> {"Year", "Temperature"},
 PlotRangePadding -> None
]

这里的图 1图 2 分别是:

(图片由作者使用NOAAUnsplash 上拍摄的照片)

结果图显示了各个层:

(图片由作者使用NOAAUnsplash 上的照片)

就这么简单!有关所有 Wolfram 语言数据可视化功能的更多详细信息,请查看参考文档中的本指南页面

像 Power BI 中的专家一样钻取

原文:https://towardsdatascience.com/drillthrough-like-a-pro-in-power-bi-ed92effcfe72?source=collection_archive---------27-----------------------

使用按钮的动态格式为您的 Power BI 报告创建出色的用户体验

照片由来自 Pexels迈克拍摄

我必须承认,Power BI 开发团队的工作非常出色!每个月(甚至更少,像四月和五月的 BI 桌面更新),他们都在超越和引入奇妙的新功能。

2020 年 3 月,微软宣布页面导航作为按钮的一个动作普遍可用,同时引入了按钮的钻取动作作为预览功能。这听起来真的很吸引我,因为我有很多用户不知道“右键单击”钻取功能,所以我必须创建不同的解决方法,如工具提示,以便让用户在报表中使用钻取。

救援按钮

随着新的按钮钻取操作现在普遍可用,让我们尝试充分利用并为我们的用户提供难忘的体验…

和往常一样,我将使用 Contoso 示例数据库进行演示。在继续之前,与按钮相关的另一个非常有趣的功能是,现在您可以自定义按钮的禁用状态(到目前为止,您可以自定义按钮的默认、悬停时的和按下时的状态)。****

让我们看看这在现实中是如何工作的:

我添加了一个空白按钮,并将其格式化为禁用状态(灰色)。

动态调整按钮文本

接下来我要做的是,因为我的报表中有多个钻取页面,所以我可以让我的用户知道他们希望看到什么样的详细信息。在我的例子中,他们可以选择查看“每个品牌的销售额”或“每个颜色的销售额”。

为此,我需要创建一个新表来保存钻取页面的相关数据。转到数据功能区下的输入数据,只需输入钻取页面的名称(表中的值与钻取页面的名称完全匹配非常重要)。我还添加了一个排名栏,以防万一我想以不同于字母顺序的顺序对页面进行排序。

现在,只需在画布上拖动切片器,并将页面名称列放入字段的值中。还有一个改善用户体验的小技巧:根据用户的选择,我们希望动态调整按钮上的文本,该文本将用于钻取操作。

因此,我创建了一个简单的 DAX 度量,它捕捉用户的选择:

Selected Page = "Open "& SELECTEDVALUE('Pages DT'[Page])

这将动态改变按钮上的文本:

要实现这一点,在按钮的格式选项下,选择按钮文本并选择右边的选项:

选择按字段值设置格式,并选择我们新创建的测量,选择页面。

请开拍!

下一步是根据用户的选择,指示我们的按钮做什么。转到按钮的动作属性,再次选择右边的选项,并在“基于字段”下拉菜单中选择页面,将“默认优先”作为摘要类型。因为我们在一个切片器中专门为一个值定义了用户选择(通过打开单选),所以我们不需要担心—无论用户选择什么,这都将是第一个(也是唯一的)选择…

最后要做的一件事是格式化按钮的填充属性,这样用户就可以识别它何时可以向下钻取。正如我前面提到的,按钮在禁用状态下是灰色的。但是,只要我从表中选择一个数据点,看看会发生什么!

我们的按钮变成蓝色,现在用户可以与它交互并点击它,以便导航到钻取页面,该页面包含 2009 年 6 月的销售额的详细信息。多酷啊!

一旦我们返回主页,并在“钻取页面切片器”下选择“销售金额颜色”,该按钮将返回禁用状态,系统将通知我们,如果我们要钻取包含每个品牌颜色的数据的页面,则需要选择一个品牌。

所以,让我们来看看它是如何工作的:

我已经在品牌名称视觉销售额中选择了 Adventure Works 品牌,我的按钮再次准备就绪!点击后,我将被导航到一个页面,该页面显示了 Adventure Works 品牌的每种产品颜色的数据:

和前面的例子一样,当我回到主页时,按钮又变灰了。

总而言之,下面是我们按钮的完整行为:

结论

通过动态格式化按钮和调整操作来启用不同的钻取页面,您可以真正为 Power BI 报表创建出色的用户体验,避免使用多个书签的复杂性。

成为会员,阅读 Medium 上的每一个故事!

订阅此处获取更多有见地的数据文章!

R 中黄金回报的驱动因素

原文:https://towardsdatascience.com/drivers-of-gold-returns-in-r-3f47bc10d466?source=collection_archive---------45-----------------------

Unsplash 上由 Felipe Simo 拍照

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

作为终极价值储存手段,黄金在过去 18 个月里大幅升值;从 2019 年 3 月的约 1300 美元涨到 9 月 18 日的 1954 美元;增长了 33.4%。事实上,黄金作为一种资产类别,在过去 20 年中表现非常好,明显超过股票;尽管这伴随着长期的表现不佳。

黄金价格最*的波动始于实际利率的下降,但随着新冠肺炎和经济状况的迅速恶化而加速。目前,对经济最糟糕的担忧似乎已经避免,但它需要前所未有的货币和财政支持。随着世界各国央行争相扩大资产负债表以支撑资产价值和消费者价格,许多风险最终可能会被社会化。

美联储的资产负债表在过去 10 年中相对稳定,占名义 GDP 的 25%,但最*几个月已经膨胀到 40%。鉴于对未来几年长期复苏和数万亿美元赤字支出的预期,这一比例预计将会增长,因为美联储将越来越需要将联邦债务货币化,以保持较低的名义利率。这可能会与旨在进一步刺激经济的进一步量化宽松措施相结合。

简而言之,金融抑制的时代以超乎寻常的规模回归,这让许多投资者想知道这对通胀、美元和黄金的未来意味着什么。

在这篇文章中,我的目的是调查黄金价格的主要驱动因素。具体来说,我将研究黄金作为金融资产的作用。重点将放在哪些金融变量主要解释黄金价格和黄金回报。

该分析将在 R 中使用大量可用的软件包库进行,包括: PerformanceAnalyticsquantmod 。所有的数据都可以从雅虎免费获得金融和圣路易斯美联储银行弗雷德数据库

任务和设置

在本案例研究中,我们将调查黄金作为金融资产的用途。用金融术语来说,黄金被认为在投资组合中有四个主要用途:

  1. 由于黄金的供应是固定的,法定货币的供应(或多或少)是任意的,通货膨胀通常是积极的,黄金被认为比其法定货币更能有效地保存财富。
  2. 对冲美元疲软:美元是世界上事实上的储备货币,并隐含着“值钱”的保证。大部分国际贸易(特别是石油)都是以美元进行的,基于美元的融资对于新兴经济体和跨国公司来说非常重要,显然,美元是进入美国资本和商品市场所必需的。因此,汇率代表了美元供求之间的复杂动态。当全球经济状况良好或美国利率较低时,美元被认为会相对于其他主要货币走软。
  3. 防范经济形势恶化:当全球经济形势疲软时,比如 2008 年或最*的新冠肺炎,黄金被视为终极避险资产。
  4. 对冲市场波动:用黄金对冲股市波动可以说是黄金更具投机性的用途之一。然而,战术性地使用黄金来对冲市场风险是一个可能的用例。

本研究的目标是评估每种拟议使用案例对黄金价格的影响,并证明是否/何时观察到最强烈的影响。

有几种不同的方法来进行分析,也有不同的方法可以借鉴。为了全面了解黄金价格的本质,我将同时运用四种技术。具体来说,

  1. 线性回归
  2. 归因分析
  3. 聚类分析
  4. 数据可视化

希望通过结合使用这些方法,我们将揭示一个更深入和全面的黄金定价模型。

数据采集、清理和处理

我将使用金融和经济变量来衡量不同来源的黄金风险和回报。我们将使用从 2003 年 1 月 29 日到 2020 年 9 月 2 日的数据。如前所述,所有的数据都可以从雅虎免费获取!金融和弗雷德。

我们将从弗雷德的数据开始。在每个变量旁边,我放置了唯一的标识符,您可以从数据库中查询。

弗雷德数据:

  • 黄金价格:黄金固定价格,伦敦金条市场。(GOLDAMGBD228NLBM)
  • 实际利率:10 年期美国国债收益率。(DFII10)
  • 10 年期美国国债和 10 年期美国国债的名义收益率之差。(T10YIE)
  • 美元对欧元的汇率。(DEXUSEU)

该模型将基于双周数据。但是,FRED 以最高的可用频率检索数据,因此每日数据总是以每日形式出现。此外,数据是从系列的开始检索的,所以您最终会得到许多 NAs。因此,在我们继续之前,我们需要做一些清理工作。

下面的 R 代码段展示了如何将标识符加载到变量中,并分别对 FRED 进行查询。数据被重新索引并转换为两周一次。我已经尽可能多地注释了代码,这样你就可以看到发生了什么。

r 代码:弗雷德数据

如果用例 4 是真的,那么我们可以预期黄金价格会对一般资本市场指数和波动性的变化做出反应。我们将从历史悠久的雅虎获得这两个变量的数据。金融:

  • 市场:标准普尔 500 指数(^GSPC)
  • 波动性:波动率指数(^VIX)

r 码:雅虎!金融数据

建模

以下是黄金和我们提出的一组变量的相关矩阵:

我们观察到,黄金和利率变量之间的相关性不是特别强,实际利率和美元对欧元的汇率是最突出的。

下图显示了黄金价格与负的 10 年期 TIPS 收益率的关系(回想一下,我们使用 TIPS 收益率作为实际利率的代表)。我已选择将 TIPS 上的收益率显示为负值。因为相关性是负的,所以系列会彼此反向移动,将收益率显示为负有助于展示趋势。

我们观察到,在该系列的早期,相关性较弱,但在过去 10 年中,尤其是最*,相关性非常紧密。

我们可以在下图中看到黄金价格和美元/欧元汇率之间的关系。从 2003 年到 2010 年,黄金和欧元同时升值,在 2010 年的大部分时间里总体呈下降趋势,但最*又开始回升。美元/欧元落后于黄金的涨势,但在撰写本文时,美元/欧元处于两年多来的最高水*。

这两者之间的相关性在 2010 年之后的系列早期更明显,但这可能是意料之中的。过去 10 年,欧洲一直在应对危机,包括 2011 年的主权债务危机和 2016 年的英国退出欧盟危机。欧盟一直受到经济增长乏力的困扰,因此欧元和黄金经历脱钩时期也就不足为奇了。

我对黄金价格和解释变量进行了简单的回归,以评估不同的影响,并提供进一步研究的线索。提议的模型如下:

其中:

  • rGold,t =黄金在时间‘t’的价格回报
  • Chg。实际利率= 10 年实际利率的水*变化
  • Chg。通胀= 10 年通胀预期的水*变化
  • 欧元兑美元 =欧元兑美元汇率的回归
  • rS&P= S&p500 的价格回报
  • Chg。VIX= VIX 的水位变化

严格回报变量(欧元兑美元和 S & P)产生弹性。弹性是对一个经济变量的百分比变化响应另一个经济变量的百分比变化的度量。数学上,弹性定义如下:

相比之下,代表水*变化的变量产生半弹性。半弹性衡量一个经济变量对另一个经济变量的单位变化的百分比变化。半弹性计算如下:

由于实际利率、通胀预期和 VIX 已经被定义为百分比,它们各自的系数被解释为:给定解释变量 1 个百分点的变化,黄金价格(即回报)的百分比变化。如果你熟悉债券交易,这与修正期限的解释是一样的,修正期限给出了收益率变化 1 个百分点时债券价格的预期百分比变化。

r 代码:回归和归因分析

回归的输出如下:

我们立即看到,实际利率的水*变化和美元对欧元汇率的百分比变化(即回报率)在统计上非常显著,而通胀预期的水*变化、标准普尔 500 的回报率和 VIX 的水*变化则明显不显著。实际利率变动系数-.045 可以解释为,假设实际利率上升/下降 1 个百分点,我们预计黄金价格下降/上升 4.5%;这证实了我们先前所预期的先验。欧元系数被解释为,如果美元对欧元汇率上升/下降 1%,我们预计黄金价格将上升/下降 0.71%(71 个基点)。

调整后的 R *方为 0.23,表明模型中仍存在相当大的可变性。考虑到提出的 5 个变量中只有 2 个具有统计意义,这仍然为我们提供了相当多的有用信息。

将我们的注意力集中在作为我们感兴趣的变量的实际利率和欧元对美元的汇率上之后,我们可以更深入一点来评估这两个变量在模型中的相对重要性。为了做到这一点,我使用了 r .relimpo中可用的包,它提供了一套函数,用于将回归的方差分解为模型回归元所做的相对贡献。我将使用排序的*均顺序*方和方法来执行分解。这种特殊的技术递归地对模型中的变量进行重新排序,并记录初始的 R *方,当添加一个变量时 R *方如何变化,并计算*均值。

为了方便起见,我们将从模型中去掉无关紧要的变量,这样就只需要考虑两种排序:

  1. 实际利率>>>欧元-美元
  2. 欧元-美元>>>实际利率

顺序*方和分解的结果如下:

从分解中获得的 R *方约为 23%,这与之前的模型结果相匹配。在这 23%中,7%的差异是由实际利率的变化造成的,16%是由汇率的变化造成的。换句话说,30%的解释差异归因于利率,其余 70%归因于汇率。因此,美元对欧元的汇率是解释黄金价格的主要变量。

如果我们参考本文的开头,我们提出黄金的两个功能是 1)对冲美元的变化(特别是美元疲软),和 2)对冲广泛恶化的经济条件。我们的结果似乎证实了这些观点。实际利率的下降通常与经济状况的恶化有关,在这种情况下,我们预计黄金会升值。同样,美元疲软往往与全球经济其他地区的经济状况改善有关,在这种情况下,我们预计黄金会升值。

为了形象化这些影响,我分别绘制了黄金收益率与美元/欧元汇率的实际收益率和收益率的变化,以及置信区间和预测区间。对于黄金对美元/欧元的图表,我们看到一个非常一致的上升趋势和紧密的配合。汇率的任何一个方向的变动都会引起黄金相应的反应。对于黄金与实际收益率,我们观察到一条向下的斜线,正如我们所料,但斜率似乎因收益率的极端变动而加剧。

r 代码:带置信区间和预测区间的图

k-均值聚类分析

到目前为止,我们已经单独研究了实际利率和汇率变化对黄金的影响。需要注意的是,利率和汇率之间的关系很复杂。理论表明,随着实际利率的下降/上升,以美国为基础的资产变得相对不那么/更有吸引力,这将推动以美元计价的汇率的下降/上升。然而,在重大全球经济压力时期(如 08-09 年和最*的 COVID),美国资产(特别是美国国债)被投资者视为“安全港”资产,这(违反直觉)压低利率并推高美元。此外,实际利率是名义利率和通胀预期的函数。如果通胀预期比名义汇率下降得更快,我们可以看到实际汇率实际上在上升,即使经济崩溃了;这相当于在经济衰退时收紧货币政策,与你想做的事情完全相反。

为了试图理清这些混杂的影响,我采用了聚类分析。聚类分析是一套广泛的技术,用于在数据集中查找观察值的子组。我选择使用的具体方法是 k-means 聚类。k-means 聚类的基本思想包括定义聚类,以使总的类内变化(称为总的类内变化)最小化。有几种 k 均值算法可用。我将使用的 k-means 方法的具体实现将总的类内变化定义为观察值和相应质心之间的*方距离欧几里得距离之和:

其中:

  • xi =是属于该集群的数据点
  • uk =分配给聚类的点的*均值

我们将总体组内变化定义如下:

总的类内*方和度量了类的紧凑性(即良好性),我们希望它尽可能小。

选择质心(即*均值)的数量有点棘手,需要一些数据挖掘,但是我们可以使用一些诊断工具来帮助。下面的代码显示了我的过程。注意,运行 k-means 聚类所需的所有函数在 base R 中都有。

重要的是要弄清楚我们事先并不知道质心的“真实”数量。为了初始化模型,我使用了三个,但是建议可以有五个质心。对于迭代 1 到 5,我记录了*方和(BSS)与总*方和(TSS)的比值。这个比率告诉我们总方差的多大比例是由聚类数解释的。随着集群数量的增加,这个比率将开始接* 1;如果聚类数 C 等于观察数,则它等于 1。目标是在解释的方差和聚类数之间取得*衡,因为这给我们提供了更一般的结果。

为了有效地做到这一点,我使用了一个侧影图,它描绘了簇的数量与 BSS/TSS 比率的关系。一般来说,您希望在开始看到图趋于*稳的点上选择聚类数。这意味着大量的差异是由少量的聚类来解释的,增加更多的聚类对模型的解释力没有有意义的贡献。从下图中我们可以看到,对于群集 1–3,BSS/TSS 比率急剧上升,在群集 4 时增益开始减速,在群集 5 时趋于*稳。

r 代码:k-均值聚类分析

下表显示了不同集群规模的 BSS/TSS 比率,以及随着集群规模的增加而增加的比率:

聚类分析表明,大部分数据可以用 4 个聚类来解释;超过这个数目,收益就小了。不可否认,很难判断是 3 个集群还是 4 个集群更合适,但对我来说 4 个集群更合适。

每个聚类的大小(即观察次数)和质心如下:

结果非常符合我们的预期。对于第 1 类和第 2 类,黄金价格的下跌与美元升值和实际收益率的上升是相称的。对于第 3 组和第 4 组,黄金价格的上涨伴随着美元贬值和实际汇率的下降。聚类 2 和 3 是最有趣的(对我来说),因为它们包含最少的观察值,并代表了解释变量和黄金价格的极端运动。

有了这些结果,我们就可以绘制数据,用颜色对数据进行分类,以便将相互作用可视化。为此,我们将利用软件包散点图 3D 。在下图中,聚类颜色如下:

  • 聚类 1 =黑色
  • 集群 2 =绿色
  • 集群 3 =蓝色
  • 聚类 4 =浅粉色

我为这个情节呈现了两个不同的天使。第一个在 x 轴上绘制汇率,第二个在 x 轴上绘制实际收益率。我还用回归*面覆盖了相应的图表,这样我们就可以看到数据的趋势。

r 代码:3D 散点图

结论

在这篇文章中,我们深入探讨了黄金以及对其影响最大的经济变量。我们使用回归分析和优势归因来确定黄金主要受美元相对强势(以美元/欧元汇率为代表)和实际利率的影响。此外,我们发现黄金相对不受其他金融和经济变量的影响,如标准普尔 500、波动性或通货膨胀。

其次,我们使用 k-means 聚类分析来检验利率、美元和黄金之间的联合关系。基于聚类分析的结果,我们确定,实际利率的下降/上升确实与美元的疲软/走强相关,这将对黄金价格产生重大影响,尤其是在走势极端的情况下。

在这个过程中,我展示了我使用的 R 代码和包,以便您可以将它们应用到自己的项目中。

希望这篇文章已经让你想到了一点(很多!)更多关于黄金及其在你的投资组合中的用途。

下次见,感谢阅读!

王高·莱克丝。

原载于 2020 年 9 月 25 日http://light finance . blog

黑人开车——数据说明了什么?

原文:https://towardsdatascience.com/driving-while-black-what-does-the-data-say-e77cac9ab15b?source=collection_archive---------35-----------------------

统计数据显示,黑人司机被警察拦下并逮捕的频率更高,而不法行为的证据却更少

克里斯·亨利在 Unsplash 上的照片

系统性种族主义是一种影响我们社会结构的种族主义。

乍一看,可能很难察觉。

自从唐纳德·特朗普当选以来,仇恨犯罪的数量有所增加。白人至上主义者有恃无恐,反移民情绪加剧。

然而,系统性的种族主义是不同的。这不是关于暴力和仇恨犯罪,而是关于那些甚至不认为自己是种族主义者的人所做的日常决定。

系统性的种族主义无处不在。它存在于学校、法院、办公室和警察局。

我们需要做得更好,积极地识别和呼唤它。

在这篇文章中,我使用了来自斯坦福开放警务项目的数据来理解刑事司法系统中的系统性种族主义。

斯坦福开放警务项目旨在帮助研究人员和政策制定者调查和改善警察与公众之间的互动。

他们从全国执法机构的数百万个交通站点收集并分析数据。

所有的数据都已经免费向公众开放,任何人都可以进入并对现有的数据进行分析。

他们的网站上有来自许多不同城市的大量数据集。为了这篇文章,我对俄亥俄州哥伦布市的警察拦截进行了分析。

数据结果

按种族逮捕:

在这个数据集中,白人的比例比其他任何种族都高。

然而,黑人被逮捕的人数要比白人多得多,黑人为 3,123 人,白人为 1,781 人。

逮捕,种族,并发出传票

即使没有发出传票,黑人司机也比其他种族的司机更容易被逮捕。

逮捕、种族和性别

黑人男性和女性比其他种族的男性和女性更有可能被警察逮捕。

按年份逮捕的人数

随着时间的推移,在警察局被逮捕的白人数量有所减少。相比之下,自 2013 年以来,被捕的黑人人数大幅增加。

随着时间的推移逮捕

下午 4 点左右似乎是逮捕人数的高峰。然而,种族和逮捕时间之间似乎没有任何明显的关联。

这一分析的结果表明,警务工作中存在显著的种族差异。

然而,重要的是要记住,这项分析仅使用了大约 10 万条记录,可能需要更多的数据才能得出具有统计意义的结论。

如果你想看看更多的数据,了解警察拦截中的种族差异,我建议访问斯坦福开放警务项目网站

他们拥有上亿次交通警察拦截的数据,并展示了对这些数据进行大规模统计分析的结果。

深度强化学习的温和介绍

原文:https://towardsdatascience.com/drl-01-a-gentle-introduction-to-deep-reinforcement-learning-405b79866bf4?source=collection_archive---------0-----------------------

深度强化学习讲解— 01

学习强化学习的基础知识

这是“深度强化学习讲解”系列的第一篇帖子;一个介绍性的系列逐渐地用一种实用的方法向读者介绍现代深度强化学习中使用的基本概念和方法。

本出版物的西班牙语版本:

[## 1.介绍难民的生活

请访问第 1 页的自由介绍

medium.com](https://medium.com/aprendizaje-por-refuerzo/1-introducción-al-aprendizaje-por-refuerzo-92c9239aed90)

深度强化学习(DRL)是一个发展非常迅速的领域,是强化学习和深度学习的结合。它也是最具趋势的机器学习类型,因为它可以解决广泛的复杂决策任务,这些任务以前是机器无法用类似人类的智能解决现实世界问题的。

今天,我开始了一个关于深度强化学习的系列,这将使这个主题更加贴*读者。目的是回顾该领域,从专业术语和术语到该领域的基本概念和经典算法,新手不会在开始这个惊人的领域时迷路。

我第一次认真接触深度强化学习是在加的斯(西班牙),2016 年机器学习暑期学校期间。我参加了约翰·舒尔曼(当时来自加州大学伯克利分校OpenAI 的联合创始人)关于深度强化学习的为期三天的研讨会。

(约翰·舒尔曼在 2016 年机器学习暑期学校的研讨会上(作者提供照片)

这太棒了,但我也不得不承认,对我来说,理解约翰的解释非常困难。从那以后已经很久了,感谢和 Xavier Giró以及 Victor Campos 和 MPh 这样的博士生一起工作。D.am Bellver,我已经能够向前迈进,享受这个主题。

但是即使几年过去了,我真诚地相信他提出的不同强化学习方法的分类法仍然是初学者组织知识的好方法。

动态编程其实是课本上大多数强化学习课程开始的。我会这样做,但在此之前,正如约翰在他的研讨会上所做的那样,我将介绍交叉熵方法,一种进化算法,尽管大多数书都没有涉及它。在强化学习中引入深度学习的第一种方法会非常好,深度强化学习,因为这是一种简单易行的方法,而且效果惊人。

通过这种方法,我们将能够在进入更经典的处理 RL 问题的方法之前,方便地回顾深度学习和强化学习如何合作,而不考虑 DL,例如动态编程蒙特卡洛时间差异学习遵循关于该主题的绝大多数学术书籍的顺序。然后,我们将把本系列的最后一部分作为策略梯度方法致力于 DL + RL 的最基本算法(不是最先进的,因为它很普遍)。

具体来说,在这第一份出版物中,我们将简要介绍什么是深度强化学习,以及在这一研究和创新领域使用的基本术语。

我认为深度强化学习是人工智能中最令人兴奋的领域之一。它将深度神经网络的力量和能力结合起来,以表达和理解世界,并根据这种理解采取行动。让我们看看我是否能分享这种兴奋。开始了。

1.背景

人工智能 (AI)中的振奋人心的新闻,*几年才刚刚发生。例如,AlphaGo 在围棋比赛中击败了最好的职业人类选手。或者去年,例如,我们的朋友 Oriol Vinyals 和他在 DeepMind 的团队展示了 AlphaStar 代理在星际争霸 2 的游戏中击败了职业选手。或者几个月后,OpenAI 的 Dota-2-playing bot 成为第一个在电子竞技比赛中击败世界冠军的 AI 系统。所有这些系统的共同点是,它们使用深度强化学习(DRL)。但是什么是人工智能和 DRL 呢?

1.1 人工智能

我们必须退一步来看看学习的类型。有时术语本身会让我们对基本原理感到困惑。人工智能是计算机科学的主要领域,强化学习 (RL)也属于其中,它是一门与创建显示类似人类“智能”的计算机程序有关的学科。

当我们谈论人工智能时,我们指的是什么?人工智能(AI)是一个广阔的领域。即使是权威的人工智能教科书人工智能,由 Stuart RusellPeter Norvig 撰写的现代方法,也没有给出精确的定义,并从不同的角度讨论人工智能的定义:

人工智能:现代方法(AIMA)第三版,Stuart J Russell 和 Peter Norvig,Prentice Hall,2009 年。国际标准书号 0–13–604259–7

毫无疑问,这本书是对这个主题有一个全球视野的最好起点。但是,为了尝试一种更通用的方法(本系列的目的),我们可以接受一个简单的定义,其中人工智能是指机器显示的智能,与人类的自然智能相反。从这个意义上说,人工智能的一个可能的简明而概括的定义可能是将通常由人类执行的智力任务自动化的努力。

因此,人工智能领域是一个广阔的科学领域,涵盖了与机器学习相关的许多知识领域;甚至更多的方法并不总是被编目,因为机器学习被我的大学同事们包括在内,他们是该领域的专家。此外,随着时间的推移,随着计算机越来越能够“做事情”,被认为“智能”的任务或技术也在发生变化。

此外,自 20 世纪 50 年代以来,人工智能经历了几波乐观情绪,随后是失望和失去资金和兴趣(被称为 AI winter 的时期),随后是新方法、成功和融资。此外,在其历史的大部分时间里,人工智能研究一直基于技术考虑或具体的数学工具动态地划分为子领域,并且研究社区有时相互之间没有充分沟通。

1.2 机器学习

机器学习(ML)本身就是一个很大的研发领域。特别是,机器学习可以被定义为人工智能的子领域,它赋予计算机学习的能力,而不需要显式编程,也就是说,不需要程序员指出完成任务必须遵循的规则;电脑会自动完成。

概括地说,我们可以说机器学习包括为每个问题的特定用例开发预测“算法”。这些算法从数据中学习,找到模式或趋势,以理解数据告诉我们什么,并以这种方式建立一个模型来预测和分类元素。

鉴于机器学习研究领域的成熟,有许多成熟的机器学习方法。它们中的每一个都使用不同的算法结构来基于接收到的数据优化预测。机器学习是一个广泛的领域,具有复杂的算法分类,通常分为三个主要类别:

  • 监督学习是从标记数据中学习的任务,它的目标是去泛化。我们的意思是,当我们用于训练的数据包括期望的解决方案时,学习受到监督,称为“标签”。这一类别中一些最流行的机器学习算法是线性回归、逻辑回归、支持向量机、决策树、随机森林或神经网络。
  • 无监督学习是从无标签数据中学习的任务,其目标是压缩。当训练数据不包括标签时,我们称之为无监督学习,算法将尝试自己对信息进行分类。这一类别中一些最著名的算法是聚类(K-means)或主成分分析(PCA)。
  • 强化学习是通过试错学习的任务,其目标是行动。这个学习类别允许它与其他类别相结合,它现在是一个非常活跃的研究领域,我们将在这个系列中看到。

1.3 深度学习

与这种分类正交的是,我们可以考虑一种强大的 ML 方法,称为深度学习 (DL),这是我们在以前的帖子中广泛讨论过的主题。请记住,深度学习算法是基于人工神经网络的,其算法结构允许由多个处理层组成的模型学习各种抽象级别的数据表示。

DL 不是一个独立的 ML 分支,所以它不是一个不同于上面描述的任务。DL 是使用神经网络解决 ML 任务的技术和方法的集合,可以是监督学习、非监督学习或强化学习。我们可以在图 1 中用图形表示它。

图 1:深度学习和机器学习类别的可视化关系。

1.4 深度强化学习

深度学习是我们今天处理非结构化环境的最佳工具之一;他们可以从大量数据中学习或发现模式。但这不是决策;这是一个认知问题。强化学习提供了这一特性。

强化学习可以使用各种 ML 方法和技术来解决问题,从决策树到支持向量机,再到神经网络。但是,在这个系列中,我们只使用神经网络;毕竟,这就是 DRL 的“深”的部分。然而,神经网络不一定是所有问题的最佳解决方案。例如,神经网络非常渴求数据,很难解释。然而,毫无疑问,神经网络是目前可用的最强大的技术之一,其性能往往是最好的。

2.强化学习

在本节中,我们提供了 RL 的第一种简单方法,因为它对于很好地理解深度强化学习(一种特殊类型的 RL)至关重要,深度强化学习具有用于状态表示和/或用于值函数、策略等的函数*似的深度神经网络。

2.1 通过互动学习

当我们思考学习的本质时,通过与环境互动来学习可能是我们想到的第一种方法。这是我们凭直觉判断婴儿学习的方式。我们知道,这种互动无疑是人们一生中关于我们的环境和我们自己的重要知识来源,而不仅仅是婴儿。例如,当我们在学习驾驶汽车时,我们完全意识到环境对我们所做的反应,我们也试图通过我们的行动来影响我们环境中发生的事情。从互动中学习是几乎所有学习理论的基础,也是强化学习的基础。

与其他机器学习方法相比,强化学习方法更侧重于从交互中进行目标导向的学习。学习实体没有被告知要采取什么行动,而是必须通过“试错法”来测试,自己发现哪些行动产生了最大的回报,即其目标。此外,这些行为不仅会影响即时回报,还会影响未来的回报,即“延迟回报”,因为当前的行为将决定未来的情况(在现实生活中如何发生)。这两个特征,“试错”搜索和“延迟奖励”,是强化学习的两个显著特征,我们将在这一系列文章中讨论。

2.2 强化学习的关键要素

强化学习(RL)是一个受各种其他成熟领域影响的领域,这些领域解决不确定性下的决策问题。例如,控制理论研究控制复杂的已知动力系统的方法;然而,我们试图控制的系统的动力学通常是预先知道的,不像 DRL 的情况,它不是预先知道的。另一个领域是运筹学,它也研究不确定情况下的决策,但通常会考虑比 RL 中常见的更大的行动空间。

因此,这些领域之间存在协同作用,这对科学进步无疑是积极的。但是它也带来了一些术语、符号等方面的不一致。这就是为什么在这一节中,我们将详细介绍我们将在整个系列中使用的术语和符号。

强化学习本质上是一个决策问题的数学形式化,我们将在本系列的后面介绍。

代理和环境

强化学习有两个核心组成部分:

  • 一个 Agent ,代表“解决方案”,是一个计算机程序,它的单一作用是做出决策(行动)来解决不确定情况下的复杂决策问题。
  • 一个环境,那是一个“问题”的表示,是在代理人决定之后出现的一切。环境对这些行为的结果作出反应,这些结果是观察或状态,以及奖励,有时也称为成本。

比如井字游戏,我们可以考虑代理人是其中一个玩家,环境包括棋盘游戏和另一个玩家。

这两个核心部分不断地相互作用,因此主体试图通过行动影响环境,而环境对主体的行动作出反应。环境如何对特定动作作出反应是由模型定义的,该模型可能为代理所知,也可能不为代理所知,这区分了两种情况:

  • 当代理知道模型时,我们将这种情况称为基于模型的 RL 。在这种情况下,当我们充分了解环境后,可以通过动态规划找到最优解。这不是这篇文章的目的。
  • 当代理人不知道模型时,需要用不完全信息进行决策;做无模型 RL,或者尝试明确学习模型作为算法的一部分。

状态

环境由一组与问题相关的变量来表示(非常依赖于我们想要解决的问题的类型)。这组变量和它们可能取的所有值被称为状态空间。一个状态是状态空间的一个实例,一组变量取值。

观察

由于我们考虑到代理无法访问环境的实际完整状态,所以通常称之为观察,即代理可以观察到的那部分状态。然而,我们会经常在文献中看到观察和状态被互换使用,所以我们将在这一系列的文章中这样做。

动作和转换功能

在每个状态,环境提供一组可用的动作,代理将从中选择一个动作。代理通过这些动作影响环境,并且环境可以作为对代理动作的响应而改变状态。负责这种映射的函数在文献中称为状态间的转移函数转移概率

报酬

环境通常具有明确定义的任务,并且可以向代理提供奖励信号,作为对代理行为的直接回答。这种奖励是对最后一个行动有助于完成环境要执行的任务的反馈。负责该映射的函数被称为奖励函数。正如我们将在后面看到的,代理人的目标是最大化其获得的整体回报,因此回报是代理人以期望的行为行动的动机。

强化学习周期

让我们在下图中总结一下之前在强化学习周期中介绍的概念:

图 2:强化学习周期。

一般来说,强化学习基本上就是把这个数字变成一种数学形式主义。

这个循环始于代理观察环境(步骤 1)并接收状态和奖励。代理使用这个状态和奖励来决定下一步要采取的行动(步骤 2)。代理然后向环境发送动作,试图以有利的方式控制它(步骤 3)。最后,环境转换,并且由于先前的状态和代理的动作,其内部状态也随之改变(步骤 4)。然后,循环重复。

插曲

代理人试图解决的任务可能有也可能没有自然的结局。有自然结局的任务,比如游戏,被称为情节任务。相反,没有完成的任务被称为连续任务,例如学习向前运动。从一个情节任务的开始到结束的时间步长的序列被称为一个情节

返回

正如我们将看到的,代理可能需要几个时间步骤和情节来学习如何解决任务。单集收集的奖励总和称为回报。代理商通常被设计成最大化回报。

其中一个限制是,这些奖励直到一集结束才透露给代理人,我们之前介绍的是“延迟奖励”。例如,在井字游戏中,每个动作的奖励直到游戏结束才知道。如果代理人赢得了游戏(因为代理人已经达到了整体期望的结果),它将是正奖励;如果代理人输掉了游戏,它将是负奖励(惩罚)。

探索与开发

强化学习的另一个重要特征和挑战是“探索”和“利用”之间的权衡。为了获得更多的奖励,一个代理人必须更喜欢他过去尝试过的行为,并且知道这些行为会有效地产生奖励。但矛盾的是,为了发现这种行为,它必须尝试以前从未选择过的行为。

总之,一个代理人必须利用他已经经历过的事情来获得尽可能多的回报,但同时,他也必须探索在未来做出更好的选择。勘探开发困境是一个至关重要的课题,也是一个尚未解决的研究课题。我们将在本系列的后面讨论这种权衡。

3.冰湖的例子

让我们通过看一个简单的例子来加强对强化学习的理解,一个冰冻的湖(非常滑),我们的代理可以在这里滑冰:

作者的图纸。

我们将使用的冰湖环境是一个溜冰场,分为 16 个单元(4x4),如下图所示,一些单元已经破冰。名为 Agent 的滑冰者从左上方的位置开始滑行,它的目标是到达右下方的位置,避免掉入轨道中的四个洞。

描述的例子被编码为来自体育馆冰湖环境。通过这个环境示例,我们将回顾并澄清到目前为止介绍的 RL 术语。这个例子对于本系列的后续文章也很有用。

3.1 健身房工具包

OpenAI 是一个人工智能(AI)研究机构,它提供了一个名为 Gym 的著名工具包,用于训练一个强化学习代理来开发和比较 RL 算法。Gym 为训练一个 RL 代理提供了各种各样的环境,从经典的控制任务到 Atari 游戏环境。我们可以训练我们的 RL 代理在这些模拟环境中使用各种 RL 算法进行学习。在整个系列中,我们将使用 Gym 工具包来构建和评估用于几个经典控制任务的强化学习算法,例如车杆*衡或登山车攀爬。

Gym 还提供了 59 个雅达利游戏环境,包括 Pong、太空入侵者、空袭、小行星、蜈蚣、吃豆人女士等。训练我们的强化学习代理玩 Atari 游戏是一项有趣且具有挑战性的任务。在这个系列的后面,我们将训练我们的 DQN 强化学习代理在 Atari Pong 游戏环境中进行游戏。

让我们介绍一个最简单的环境作为例子,叫做冰湖环境。

3.2 冰湖环境

当代理生活在大小为 4x4(有 16 个单元)的网格中时,冰湖环境来自所谓的网格世界类别,这意味着在网格世界的 i,j 坐标中由 16 个状态(0–15)组成的状态空间

在冰湖中,代理总是从左上角位置开始,它的目标是到达网格的右下角位置。网格的固定单元格中有四个洞,如果代理人进入那些洞,结束,获得的奖励为零。如果代理到达目的地细胞,它将获得+1 的奖励,并且结束。下图显示了冰湖环境的可视化表示:

图 3:冰湖环境的可视化表示。

为了达到目标,代理有一个由四个方向运动组成的动作空间:上、下、左、右。我们还知道湖的周围有栅栏,所以如果代理人试图离开网格世界,它只会反弹回它试图离开的单元格。

因为湖面结冰,世界很滑,所以代理人的行动并不总是像预期的那样——有 33%的可能性会滑向右边或左边。例如,如果我们想让代理向左移动,那么它有 33%的概率会向左移动,有 33%的概率会出现在上面的单元格中,有 33%的概率会出现在下面的单元格中。

环境的这种行为反映在前面介绍的转移函数转移概率中。然而,在这一点上,我们不需要进入这个函数的更多细节,留待以后。

作为总结,我们可以在下图中直观地表示所有这些信息:

图 4:冰湖例子的强化学习循环的示意图。

3.3 环境编码

我们来看看这种环境在 Gym 中是如何表现的。我建议使用 Google 提供的Colab来执行这篇帖子中描述的代码(已经安装了 Gym 包)。如果你喜欢使用你的 Python 编程环境,你可以使用这里提供的步骤来安装 Gym。

第一步是导入健身房:

*import gym*

然后,从健身房指定你想使用的游戏。我们将使用冰湖游戏:

*env = gym.make('FrozenLake-v0')*

游戏的环境可以被重置到初始状态,使用:

*env.reset()*

为了查看游戏状态,我们可以使用:

*env.render()*

render()渲染的表面使用如下网格呈现:

其中突出显示的字符表示代理在当前时间步长中的位置,并且

  • “S”表示起始单元(安全位置)
  • “F”表示冰冻表面(安全位置)
  • “H”表示一个洞
  • “G”:表示目标

官方文档可以在这里找到查看健身房工具包的详细用法和解释。

3.4 代理人编码

目前,我们将创建一个最简单的代理,它只执行随机操作。为此,我们将使用从动作空间中随机抽取动作的action_space.sample()

假设我们最多允许 10 次迭代;以下代码可以成为我们的“哑”代理:

*import gymenv = gym.make("FrozenLake-v0")
env.reset()for t in range(10):
   print("\nTimestep {}".format(t))
   env.render()
   a = env.action_space.sample()
   ob, r, done, _ = env.step(a)
   if done:
      print("\nEpisode terminated early")
      break*

如果我们运行这段代码,它将输出类似下面这样的内容,在这里我们可以观察时间步长、操作和环境状态:

总的来说,如果不是几乎不可能,找到一集我们的“哑”代理,在随机选择的行动中,它可以克服障碍并到达目标细胞,这是具有挑战性的。那么,我们如何建立一个代理来实现它呢?。这是我们将在本系列的下一部分中介绍的内容,我们将进一步形式化这个问题,并构建一个新的代理版本,它可以学习到达目标单元。

4.强化学习与其他学习模式有何不同

为了结束这篇文章,让我们回顾一下强化学习的基础,将其与其他学习方法进行比较。

4.1 强化学习与监督学习

在监督学习中,系统从由一对带标签的输入和输出组成的训练数据中学习。因此,我们使用训练数据训练模型(代理),使得模型可以将其学习推广到新的看不见的数据(输入和输出的标记对指导模型学习给定的任务)。

让我们用一个例子来理解监督学习和强化学习的区别。想象一下,我们想要训练一个模型使用监督学习来下棋。在这种情况下,我们将使用一个训练数据集来训练模型进行学习,该数据集包括玩家在每个状态下可以做出的所有移动,以及指示这是否是一个好移动的标签。然而在 RL 的情况下,我们的代理将不会被给予任何种类的训练数据;相反,我们只是为代理执行的每个操作提供奖励。然后,代理将通过与环境的交互来学习,它将根据它获得的奖励来选择它的行动。

4.1 强化学习与无监督学习

与监督学习类似,在无监督学习中,我们基于训练数据来训练模型。但是在无监督学习的情况下,训练数据不包含任何标签。这导致了一个常见的误解,即 RL 是一种无监督的学习,因为我们没有标签作为输入数据。但事实并非如此。在无监督学习中,模型学习输入数据中的隐藏结构,而在 RL 中,模型通过最大化奖励来学习。

一个经典的例子是电影推荐系统,它想向用户推荐一部新电影。通过无监督学习,模型(代理)将找到与用户(或与用户具有相似简档的用户)之前观看的电影相似的电影,并向用户推荐新电影。相反,通过强化学习,代理不断地接收来自用户的反馈。这个反馈代表奖励(奖励可以是看电影的时间、看预告片的时间、他连续看了多少部电影等等)。基于奖励,RL 代理将理解用户的电影偏好,然后相应地建议新电影。重要的是要注意,RL 代理可以知道用户的电影偏好是否改变,并根据用户改变的电影偏好动态地建议新电影。

4.3 强化学习中的数据在哪里?

我们可以认为我们在强化学习中没有监督或无监督学习中的数据。然而,数据实际上是环境,因为如果你与这个环境互动,那么数据(轨迹)可以被创建,这是观察和行动的序列。然后我们可以在上面做一些学习,这基本上就是强化学习的核心。

有时,我们可以使用来自现有的人或轨迹的额外数据,例如在模仿学习中。我们实际上可能只是观察一群玩游戏的人,我们不需要知道环境是如何运作的。有时我们已经明确给出了一个数据集,作为一种监督数据集,但在纯强化学习设置中,唯一的数据是环境

5.RL 的应用

强化学习在过去几年里发展迅速,应用广泛。这种演变的主要原因之一是强化学习和深度学习的结合。这就是为什么我们把这个系列的重点放在介绍基本的最先进的深度强化学习算法(DRL)上。

5.1 Real 的实际应用

媒体倾向于关注 DRL 在游戏中击败人类的应用,比如我在本文开头提到的例子:AlphaGo 在围棋比赛中击败了最好的职业人类选手;AlphaStar 在星际争霸 2 的游戏中击败了职业选手;OpenAI 的 Dota-2 游戏机器人在一场电子竞技比赛中击败了世界冠军。

幸运的是,DRL 在现实生活中有很多应用。其中一个著名的领域是无人驾驶汽车。在制造业中,使用 DRL 训练智能机器人将物体放置在正确的位置,从而降低劳动力成本,提高生产率。RL 的另一个流行应用是动态定价,它允许根据需求和供应来改变产品的价格。此外,在推荐系统中,RL 用于构建推荐系统,其中用户的行为不断变化。

在当今的商业活动中,DRL 被广泛用于供应链管理、需求预测、库存管理、处理仓库业务等。DRL 还广泛用于金融投资组合管理、预测和商业交易市场的交易。DRL 常用于一些自然语言处理任务,如抽象文本摘要、聊天机器人等。

许多最*的研究论文提出了 DRL 在医疗保健、教育系统、智能城市等领域的应用。总而言之,没有一个行业不受 DRL 的影响。

5.2 的安全和安保

DRL 特工有时可以控制危险的现实生活环境,如机器人或汽车,这增加了做出错误选择的风险。有一个名为 safe RL 的重要领域试图应对这种风险,例如,学习一种在预定义的安全约束内操作时实现回报最大化的策略。

此外,像任何其他软件系统一样,DRL 代理也面临着被攻击的风险。但是 DRL 在传统的机器学习系统之上增加了一些新的攻击手段,因为总的来说,我们正在处理的系统要复杂得多,难以理解和建模。

考虑到 DRL 系统的安全性超出了本文的介绍范围。不过,我希望读者能够意识到这一点,如果将来您将 DRL 系统投入运行,请记住,您应该更深入地对待这一点。

5.3 我们不能逃避我们的责任

人工智能肯定正在渗透社会,就像电一样,我们会期待什么?我们将“发明”的未来是我们共同做出的选择,而不是偶然发生的事情。我们处于有利地位。有了 DRL,我们有权力和权威来自动化决策和整个战略。

这很好!但正如生活中的大多数事情一样,有光的地方就会有阴影,而 DRL 技术落入坏人之手是危险的。我问你,当工程师考虑我们正在建造的东西时:我们的 DRL 系统会意外地增加偏见吗?这对个人有什么影响?。或者,我们的解决方案会因其能源消耗而对气候产生怎样的影响?我们的 DRL 解决方案会被意外使用吗?还是用?。或者,根据我们的伦理,它能有一种我们认为邪恶的用途吗?

我们必须仔细考虑即将采用的人工智能及其影响。如果我们继续建设人工智能,而不考虑我们防止其滥用的责任,我们永远也不能指望看到人工智能帮助人类繁荣。

我们所有正在研究或想要研究这些课题的人都不能回避我们的责任,否则,我们将来会后悔的。

6.摘要

我们通过理解 RL 的基本思想开始这篇文章。我们了解到,强化学习是一个反复试验的学习过程,而强化学习的发生是基于奖励的。我们提出了 RL 和其他 ML 范式之间的差异。最后,我们研究了 RL 在现实生活中的一些应用,并思考了 DRL 的安全性、安全性和伦理性。

的下一篇文章中,我们将了解马尔可夫决策过程(MDP)以及如何将 RL 环境建模为 MDP。接下来,我们将回顾 RL 中涉及的几个重要的基本概念。下一期

帖子更新于 2020 年 8 月 12 日

深度强化学习讲解系列

UPC 巴塞罗那理工 巴塞罗那超级计算中心

一个轻松的介绍性系列以一种实用的方式逐渐向读者介绍这项令人兴奋的技术,它是人工智能领域最新突破性进展的真正推动者。

* [## 深度强化学习解释-乔迪托雷斯。人工智能

本系列的内容](https://torres.ai/deep-reinforcement-learning-explained-series/)

关于这个系列

我在 5 月份开始写这个系列,那是在巴塞罗那的封锁期。老实说,由于封锁,在业余时间写这些帖子帮助了我。感谢您当年阅读这份刊物;它证明了我所做的努力。

免责声明 —这些帖子是在巴塞罗纳封锁期间写的,目的是分散个人注意力和传播科学知识,以防对某人有所帮助,但不是为了成为 DRL 地区的学术参考文献。如果读者需要更严谨的文档,本系列的最后一篇文章提供了大量的学术资源和书籍供读者参考。作者意识到这一系列的帖子可能包含一些错误,如果目的是一个学术文件,则需要对英文文本进行修订以改进它。但是,尽管作者想提高内容的数量和质量,他的职业承诺并没有留给他这样做的自由时间。然而,作者同意提炼所有那些读者可以尽快报告的错误。*

强化学习问题的形式化

原文:https://towardsdatascience.com/drl-02-formalization-of-a-reinforcement-learning-problem-108b52ebfd9a?source=collection_archive---------9-----------------------

深度强化学习讲解— 02

马尔可夫决策过程中的主体-环境相互作用

今天我们从系列文章的第二篇开始深度强化学习讲解。正如我们在 第一帖 中所宣布的,这个系列的一个主要方面就是它对实践的导向;但是,在开始编码之前,我们需要一些理论知识。在本帖中,我们将探索特定假设和抽象的严格数学形式。不要慌;你的耐心会得到回报的!

在这里,我们将向读者介绍在前一篇文章中提出的概念的数学表示和符号,这将在本系列中重复使用。实际上,读者将学会使用一个被称为马尔可夫决策过程 (MDP)的数学框架来表示这些类型的问题,该框架允许对几乎任何复杂的环境进行建模。

通常,环境的动态变化是隐藏的,对代理人来说是不可访问的;然而,正如我们将在以后的文章中看到的,DRL 代理不需要知道问题的精确 MDP 来学习健壮行为。但是,了解 MDP 对读者来说是必不可少的,因为代理通常是基于这样的假设设计的,即 MDP 即使不可访问,也是在引擎盖下运行的。

本出版物的西班牙语版本:

[## 2.难民救济委员会

访问第 2 卷第 2 页的自由介绍

medium.com](https://medium.com/aprendizaje-por-refuerzo/2-formalización-del-aprendizaje-por-refuerzo-9ab5bcbc8602)

1.马尔可夫决策过程

马尔可夫决策过程 (MDP)为解决 RL 问题提供了一个数学框架。几乎所有的 RL 问题都可以建模为 MDP。为了理解 MDP,首先,我们需要了解马尔可夫性质和马尔可夫过程。

马尔可夫性质表明未来只取决于现在而不取决于过去。马尔可夫过程由一系列严格遵守马尔可夫特性的状态组成。

当一个 RL 问题满足马尔可夫性质,即未来只依赖于当前状态 s 和动作 a ,而不依赖于过去,则公式化为马尔可夫决策过程 (MDP)。

目前,我们可以认为 MDP 基本上由五元组 < S、A、R、p、γ > 组成,其中符号的含义是:

  • S —一组状态
  • —一套动作
  • R —奖励功能
  • p —过渡功能
  • γ —折现系数

下面我们来分别描述一下;然而,在继续之前,我们需要澄清一下本系列中使用的数学符号。

1.1 关于数学符号

鉴于本系列的实践性和介绍性,我将尝试让普通读者理解这个解释,而不要求他们严格遵循数学公式。

然而,对于那些想了解数学细节的读者,我会尽量保持公式的严谨性。但由于 Medium.com 编辑器对编写公式和不同的字体类型有一定的限制,这并不容易。

所以,在课文中,我们会对记谱法的使用稍有松懈。例如,媒体编辑器不允许使用下标。在这种情况下,当我们要引用代理在时间 t 、的**、状态时,我们将使用符号。****

类似地,在提到一个状态、行为或奖励时,我们会使用大写和小写字母,以便于阅读。

我会尽最大努力让这篇课文易懂。在某些情况下,我将包含数学符号和公式作为用 Latex 创建的图像,以弥补媒体编辑器的缺点。

在任何情况下,在继续之前,为了充分的数学严谨性,请参考本文的附录(在最后)。

1.2 国家

一个状态是问题的一个独特且独立的配置。所有可能状态的集合被命名为状态空间。有单独的状态作为开始状态或结束状态

在上一篇文章中使用的冰湖示例中,环境的状态空间由 16 个状态组成,如图所示:

作者的画

从编程的角度来看,我们可以更正式地获得它们,如下所示:

*print(“State space: “, env.observation_space)State space: Discrete(16)*

例如,在冰湖环境中,只有一个起始状态(状态 0)和五个结束状态(状态 5、7、11、12 和 15):

图 1:冰湖环境的状态空间。(图片由作者提供)

1.3 行动

在每个状态,环境提供一组可用的动作,一个动作空间,代理将从中选择一个动作。代理通过这些动作影响环境,并且环境可以作为对代理所采取的动作的响应而改变状态。该环境使所有可用动作的集合提前为人所知。

在冰湖环境中,所有状态下都有四种可用的动作:向上、向下、向右或向左:

*print(“Action space: “, env.action_space)Action space: Discrete(4)*

现在我们已经介绍了状态和动作,我们可以记住马尔可夫属性。下一个状态 St+1 的概率,给定当前状态和当前动作 在给定时间**t,将和你给它的整个交互历史一样。换句话说,也就是说,给定相同的动作,在两个不同的场合从一个状态移动到另一个状态的概率是相同的,而不管在该点之前遇到的所有先前的状态或动作。在冰湖的例子中,我们知道代理只能从状态 2 转换到状态 1、3、6 或 2,不管代理的前一个状态是 1、3、6 还是 2 都是如此。也就是说,您不需要代理所访问的州的历史记录。****

我们在这里要说明的是,我们可以将动作空间分为两种类型:

  • ****离散动作空间:当我们的动作空间由离散的动作组成时。例如,在冰湖环境中,我们的动作空间由四个离散的动作组成:上、下、左、右,因此它被称为离散动作空间。离散环境是指环境的动作空间是离散的。
  • 连续动作空间:当我们的动作空间由连续的动作组成时。例如,当我们开车时,我们的行为有连续的值,比如汽车的速度,或者我们需要转动方向盘的角度,等等。在我们的系列中,我们将使用连续动作空间作为 CartPole 环境的例子。连续环境是环境的动作空间连续的环境。

2.转移函数

从一个状态移动到代理将到达的另一个状态(并且环境改变其状态)由转移函数决定,该转移函数指示从一个状态移动到下一个状态的概率,并且由 p 表示。表示环境的一步动态,即给定当前状态和当前动作,下一个状态和奖励的概率。

记住环境在时间步 t 对代理做出响应;它只考虑前一时间步 t-1 的状态和动作。它不关心在多一步之前呈现给代理的是什么状态。它不查看代理在最后一个操作之前采取的操作。最后,它获得多少奖励对环境选择如何回应代理人没有影响。

正因为如此,我们可以像这里所做的那样,通过指定转移函数 p 来完整地定义环境如何决定状态和奖励。函数 p 定义了 MDP 的动态

作为总结,要强调的是,当我们心中有一个真正的问题时,我们将需要指定 MDP 作为一种正式定义问题的方式,因此函数 p 。代理将知道状态、行动和奖励,以及折扣系数。但是函数 p 对于代理来说将是未知的。尽管没有这些信息,代理仍然必须从与环境的交互中学习如何完成它的目标。

根据环境的不同,代理可以确定性地或随机地选择动作。让我们看看两种情况下的转移函数是怎样的。

2.1 确定性环境的转移函数

想象一下冰湖的例子,它不是一个光滑的表面。我们可以用参数is_slippery=False创建这个环境,以确定性模式创建环境:

**env = gym.make('FrozenLake-v0', is_slippery=False)**

在这种情况下,给定当前状态【St】和在 的动作 ,下一状态 St+1 在时间 t 的概率总是 1。换句话说,在一个确定性的环境中,总是有一个可能的下一个行动状态。在这种情况下,我们可以将转移函数视为二维矩阵(2D)的简单查找表。在我们的冰冻湖例子中,我们可以用env.env.P获得它,它将函数输出为一个字典:

*{
0: {0: [(1.0, 0, 0.0, False)],
    1: [(1.0, 4, 0.0, False)],
    2: [(1.0, 1, 0.0, False)],
    3: [(1.0, 0, 0.0, False)]},
1: {0: [(1.0, 0, 0.0, False)],
    1: [(1.0, 5, 0.0, True)],
    2: [(1.0, 2, 0.0, False)],
    3: [(1.0, 1, 0.0, False)]},
.
.
.
14: {0: [(1.0, 13, 0.0, False)],
     1: [(1.0, 14, 0.0, False)],
     2: [(1.0, 15, 1.0, True)],
     3: [(1.0, 10, 0.0, False)]},
15: {0: [(1.0, 15, 0, True)],
     1: [(1.0, 15, 0, True)],
     2: [(1.0, 15, 0, True)],
     3: [(1.0, 15, 0, True)]}
}*

在这个输出中,env.P返回所有的状态(为了清楚起见,去掉了很多,请查看笔记本以获得完整的输出),其中每个状态都包含一个字典,如果我们采取了某个动作,该字典会将所有可能的动作(0,1,2,3)从该状态映射到下一个状态。此外,每个动作包括一个列表,其中列表的每个元素是一个元组,显示转换到状态、下一个状态、奖励以及游戏是否在那里终止的概率(如果下一个状态是洞或目标,则 done= True)。

例如,在这种“不滑”的环境中,如果我们执行下一张图中所示的序列/计划(我称之为“好计划”),代理将最终安全到达:

图 2:冰湖例子的“好计划”。(作者制图)

我们可以用下面的代码检查这是一个允许代理实现目标的计划:

*actions = {‘Left’: 0, ‘Down’: 1, ‘Right’: 2, ‘Up’: 3 }good_plan = (2*['Down']) + ['Right'] + ['Down'] + (2*['Right'])env = gym.make(“FrozenLake-v0”, is_slippery=False)
env.reset()
env.render()for a in good_plan:
    new_state, reward, done, info = env.step(actions[a])
    env.render()
    if done:
       break* 

这里,环境对代理的动作做出确定性的反应,但是如果我们还记得上一篇文章,原始环境对代理的动作做出随机的反应来模拟滑倒。

2.2 随机环境的转移函数

我们介绍了代理将到达哪个状态是由转移函数决定的。但是在随机环境中,在时间 t 时,转移函数 p 将一个转移元组 (St,at,St+1)映射到从源状态到目标状态 St+1 的转移概率**

现在,为了捕捉关于环境的所有细节和对主体行为的可能反应,转移函数不能像在确定性环境的情况下那样表示为 2D 矩阵。在这种情况下,我们需要一个具有维度源状态动作、目标空间*的 3D 矩阵,其中每个元素表示从源状态 St 到目标状态 St+1 给定动作的转移概率。***

为了验证我们谈论的是一个 3D 矩阵,我们可以像以前一样获得转移函数,但是现在对于光滑的环境:

****env = gym.make(“FrozenLake-v0”)
print(env.env.P{
0: {0: [(0.3333333333333333, 0, 0.0, False),
        (0.3333333333333333, 0, 0.0, False),
        (0.3333333333333333, 4, 0.0, False)],
    1: [(0.3333333333333333, 0, 0.0, False),
        (0.3333333333333333, 4, 0.0, False),
        (0.3333333333333333, 1, 0.0, False)],
    2: [(0.3333333333333333, 4, 0.0, False),
        (0.3333333333333333, 1, 0.0, False),
        (0.3333333333333333, 0, 0.0, False)],
    3: [(0.3333333333333333, 1, 0.0, False),
        (0.3333333333333333, 0, 0.0, False),
        (0.3333333333333333, 0, 0.0, False)]},
.
.
.
**14: {0: [(0.3333333333333333, 10, 0.0, False),
         (0.3333333333333333, 13, 0.0, False),
         (0.3333333333333333, 14, 0.0, False)],
     1: [(0.3333333333333333, 13, 0.0, False),
         (0.3333333333333333, 14, 0.0, False),
         (0.3333333333333333, 15, 1.0, True)],
     2: [(0.3333333333333333, 14, 0.0, False),
         (0.3333333333333333, 15, 1.0, True),
         (0.3333333333333333, 10, 0.0, False)],
     3: [(0.3333333333333333, 15, 1.0, True),
         (0.3333333333333333, 10, 0.0, False),
         (0.3333333333333333, 13, 0.0, False)]},**
15: {0: [(1.0, 15, 0, True)],
     1: [(1.0, 15, 0, True)],
     2: [(1.0, 15, 0, True)],
     3: [(1.0, 15, 0, True)]}
}****

该转换函数实现了有 33.3%的机会我们将转换到预期的单元(状态),并且有 66.6%的机会我们将转换到正交方向。如果在墙边,我们也有机会反弹回我们原来的状态。

将环境可视化表示为用节点表示状态和边的图,用概率(和奖励)标记,表示从一个状态到另一个状态的可能转换,这可能是有帮助的。为了简单明了,我在下图中只添加了状态 14 的所有动作的转换函数。这种状态子集允许在没有太多混乱的情况下说明所有可能的转换。

图 3:状态 14 的部分转换图。(图片由作者提供)

现在,如果我们多次执行“好计划”行动的相同序列,我们可以看到它不以确定的方式运行,给出非常不同的结果。我们将在以后的文章中回到这个例子。

3.奖励函数和折扣因子

一旦采取了行动,环境就使用奖励函数提供一个奖励作为对转变有益的度量。什么是奖励函数?

3.1 奖励功能

奖励函数通常用 r(s,a)r(s,a,s’)来表示。 代表我们的代理人在执行一个动作时,从状态 s 过渡到状态s’时获得的奖励。它只是代理在每个时间步(或每个固定数量的时间步)从环境中获得的标量值(可以是正的或负的,大的或小的)。****

值得注意的是,“强化”和“强化学习”这个词最初来自行为科学。它指的是在行为发生后立即给予的刺激,以使该行为更有可能在未来发生。这个名字被借用并不是巧合。我们应该把奖励设计成一种反馈机制,告诉代理人它已经选择了适当的行动。奖励将是我们告诉代理人它做得“好”或“差”的方式。换句话说,就是告诉我们的代理它表现得有多好。

例如,考虑一个想要学习逃离迷宫的代理人。哪些奖励信号会促使代理尽快逃离迷宫?代理在迷宫中每走一步,奖励可以是-1。一旦特工逃脱,获得+10 奖励,本集终止。现在,考虑一个想学习在头上*衡一盘食物的代理人。哪些奖励信号会鼓励代理人尽可能长时间地保持盘子*衡?例如,对于代理保持盘子在她头上*衡的每个时间步长,可以有+1 的奖励。如果盘子掉了,这一集就结束了。我希望通过这两个简单的例子,读者已经直观地理解了奖励如何有助于“强化”主体的学习。

总的来说,奖励给代理人关于其成功的反馈,获得的奖励应该以积极或消极的方式强化代理人的行为。然而,它仅反映了代理最*活动的成功,而不是代理到目前为止取得的所有成功。代理人试图实现的是在其行动序列中最大的累积回报,我们需要另一个反馈,即回报。但是在介绍收益之前,让我介绍一下 MDP 的最后一个组成部分,贴现因子。****

3.2 折扣系数

我们已经说过,代理人试图解决的任务可能有也可能没有自然的结局。有自然结局的任务,比如游戏,被称为情节任务。一个情节任务从开始到结束的时间步骤序列称为一个情节。冰湖环境呈现出阶段性的任务,因为存在最终状态;有明确的目标和失败状态。相反,没有自然结束的任务被称为持续任务,例如学习向前运动。

由于时间步长的无限序列的可能性,我们需要一种方法来贴现回报随时间的价值;也就是说,我们需要一种方法来告诉代理,越早得到+1 越好。所以,我们通常用小于 1 的正实值来指数贴现未来回报的价值。我们得到的回报越往后,它在当下就越不值钱。

该参数称为折现因子γ,或用γT7 表示的折现率*,其范围为【0,1】。代理使用折扣系数来随着时间的推移调整奖励的重要性。代理人收到奖励越晚,他们就越不愿意给出计算结果。换句话说,代理人更感兴趣的是获得更快、更有可能获得的回报,而不是更晚、更不可能获得的回报。*******

4.问题设置

的上一篇文章中,我们展示了强化学习周期,在这个周期中,一个 RL 代理随着时间的推移与一个环境进行交互。总而言之,在每个时间步 t ,代理接收一个状态 s ,并选择一个动作*,遵循一个策略(一个策略)根据环境动态,智能体收到一个标量奖励 r ,过渡到下一个状态s’。在偶发问题中,这个过程会一直持续到代理达到终止状态,然后重新启动。*****

4.1 情节和轨迹

代理通过执行一些动作与环境交互,从初始状态开始并到达最终状态。这种从初始状态 S0 开始直到最终状态的主体-环境交互被称为情节。

但是有时我们可能只对交互代理环境的一部分感兴趣。在任意时间步 t ,代理和 MDP 环境的交互已经演化为状态、动作和奖励的序列。每一步都被定义为一个转换:

我们定义一个轨迹,仅仅是一集的一部分,由一系列过渡组成。轨迹比一集稍微灵活一些,因为它的长度没有限制;它可以对应于完整的一集或只是一集的一部分。我们用 τ: 表示一个轨迹

我们用 H (或 h) 来表示轨迹的长度,其中 H 代表地*线。**

4.2 折扣回报

我们在第 1 篇的文章中介绍过,一般来说,代理人被设计成从长期来看能获得最大的累积回报。现在我们已经介绍了 gamma,我们可以定义如何根据 gamma 和连续任务的奖励(以及临时任务的奖励)来计算回报。我们定义贴现收益,表示为 Gt, 在时间步长 t ,作为这个量:

对于每一个时间步 t ,我们计算贴现回报 Gt 作为后续奖励的总和,但是更远的奖励要乘以贴现因子提升到我们离开的步数的幂。如果 gamma 等于 1,那么贴现回报就等于所有后续回报(累积回报)的总和,即回报。如果 gamma 等于 0,回报将只是即时奖励,没有任何后续状态。

当我们将折扣因子设置为一个较小的值(接*于 0)时,我们更重视眼前的回报,而不是未来的回报。当我们将折扣因子设置为一个高值(接* 1)时,这意味着我们更重视未来的回报而不是眼前的回报。极值仅在极限情况下有用,大多数时候,gamma 设置在两者之间。

代理人根据任务重视当前和未来的奖励。在某些任务中,未来的回报比眼前的回报更令人向往,反之亦然。例如,在国际象棋比赛中,目标是击败对手的国王。让我们更重视直接的回报,这是通过行动获得的,如我们的棋子击败任何对手的棋子。代理可能会学习执行这个子目标,而不是学习重要目标。

行动有短期和长期的后果,行动者需要了解其行动对环境的复杂影响。正如我们将在这个系列中看到的,贴现收益将帮助代理人完成这项任务:代理人总是会选择一个行动来实现收益最大化的目标。但正如我们将会看到的,一般来说,一个代理人不能完全确定地预测未来的回报可能是什么,因此贴现回报,所以它必须依赖于预测或估计,这取决于我们将用来学习的方法家族。这就是政策功能和价值功能的关键概念发挥作用的地方。

4.3 政策

让我们来看看代理人如何做出决策来满足其目标:找到一系列行动来最大化一集期间的贴现回报 G 。换句话说,代理必须有一个计划,即从开始状态到目标状态的一系列动作。

我们之前介绍了一个关于冰湖例子的“好计划”,它看起来是直觉上最好的。但是,当我们在随机环境中运行它时,即使是最好的计划也会失败,因为采取的行动并不总是按照我们预期的方式进行。请记住,在冰湖环境中,无意的行动影响有更高的概率:66.6%对 33.3%。

特别是,由于环境的随机性,我们的特工降落到了一个不在我们计划范围内的小区。然后呢?怎么办?嗯,我们需要的是一个针对所有可能状态的计划,一个“通用计划”,一个涵盖所有可能状态的政策

一个策略定义了代理在一个环境中的行为。It 是代理用来基于当前状态确定下一个动作的策略(例如,某组规则)。典型地由 𝜋表示,一个策略一个策略是一个函数,它决定给定一个状态下一个动作****

我们刚刚在开头提到的策略被称为确定性策略。一个确定性策略,【𝜋(𝑠】*告诉代理在状态下执行一个特定的动作。因此,确定性策略将状态映射到一个特定的动作。*******

但总的来说,我们将处理更一般的政策,并将被定义为概率而不是具体行动。换句话说,就是一个随机策略,它对代理在给定状态下可以采取的行动有一个概率分布。因此,代理不是每次访问州时都执行相同的动作,而是每次根据随机策略返回的概率分布执行不同的动作。随机策略通常用 𝜋(𝑎|𝑠) 来表示。****

正如我们将在本系列后面看到的,随着代理在学习过程中获得更多的经验,策略可能会改变。例如,代理可以从随机策略开始,其中所有动作的概率是一致的;与此同时,代理将有希望学会优化其策略,以达到更好的策略。在初始迭代中,这个代理在每个状态下执行一个随机动作,并试图根据获得的奖励来学习该动作是好是坏。经过一系列的迭代,代理将学习在每个状态下执行好的动作,这给出了积极的奖励。最后,代理将学习一个好的策略或最优策略。

我们可以将随机策略分为两种类型:

  • ****分类策略:当动作空间离散时,策略使用动作空间上的分类概率分布进行选择。例如,在冰湖环境中,我们基于分类概率分布(离散分布)选择动作,因为环境的动作空间是离散的。
  • ****高斯策略:当我们的动作空间是连续的,并且该策略使用动作空间上的高斯概率分布来选择。我们将在以后的文章中讨论这类政策。

即使对于相当简单的环境,我们也可以有各种各样的策略。那么我们需要一种方法来自动寻找最优策略。最优策略是使代理人获得良好报酬并帮助代理人实现目标的策略。它告诉代理在每个状态下执行正确的动作,这样代理就可以得到很好的奖励。这就是价值函数发挥作用的地方。****

4.4 预测期货回报:价值函数

一个价值函数,它决定了什么对代理人长期有利,而不是眼前的回报。我们有两种类型的价值函数,状态-价值函数动作-价值函数,帮助学习和寻找代理的最优策略。****

****状态值函数也称为 V 函数,测量每个状态的良好程度。它告诉我们,如果我们从那个状态开始,我们在未来可以期望的总回报。换句话说,当我们遵循某个政策时,根据贴现回报 G 处于某个特定状态的好坏。然而,贴现回报数量在实践中并不是很有用,因为它是为每一个特定的情节定义的,所以它可以有很大的不同,即使是在同一个州。但是,如果我们走极端,计算数学期望𝔼[.]通过对大量事件进行*均,我们将获得 V 函数的更有用的值。

此外,我们可以扩展状态-值函数的定义,为每个状态-动作对定义一个值,这被称为动作-值函数,也被称为 Q 函数。它告诉我们,从我们所处的状态中可以选择的一系列行动中,采取一个特定的行动是好是坏。

估计状态-值函数和动作-值函数是强化学习方法的基本组成部分。在本系列的后续文章中,我们将更详细地讨论并涵盖计算和估计这些函数的不同方法。

5.摘要

我们已经到达这篇文章的结尾了!。一个不假装是一个完整的理论框架的帖子将引入最少的形式主义,我们将在整个系列中引入我们需要的新公式。我们理解了 RL 中涉及的几个重要的基本概念。

在接下来的三篇帖子(帖 3帖 4帖 5 )中,我们将回顾强化学习问题中编程 Agents 所需的深度学习概念(以及 PyTorch)。如果你之前有深度学习、PyTorch 和 TensorBoard 的知识,你可以跳过这三个帖子,去找帖子 6 。用交叉熵方法解决强化学习问题。

帖子更新于 2020 年 11 月 12 日

附录:数学符号

一般来说,我们倾向于使用理查德·萨顿和安德鲁·g·巴尔托所著的《强化学习:导论》中的符号。这本书是一个优秀的强化学习基础介绍的经典文本。

博士 Richard S. SuttonDeepMind 的杰出研究科学家,也是阿尔伯塔大学的著名计算科学教授。萨顿博士被认为是现代计算强化学习的创始人之一。安德鲁·g·巴尔托博士是马萨诸塞大学的荣誉退休教授,也是萨顿博士的博士生导师。

与本文相关的系列文章中,我们将使用的主要定义和数学符号如下:

深度强化学习讲解系列

UPC 巴塞罗那理工大学 巴塞罗那超级计算中心

一个轻松的介绍性系列以一种实用的方式逐渐向读者介绍这项令人兴奋的技术,它是人工智能领域最新突破性进展的真正推动者。

**** [## 深度强化学习解释-乔迪托雷斯。人工智能

本系列的内容](https://torres.ai/deep-reinforcement-learning-explained-series/)

关于这个系列

我在五月开始写这个系列,在巴塞罗那的封锁期。老实说,由于封锁,在业余时间写这些帖子帮助了我 #StayAtHome 。感谢您当年阅读这份刊物;它证明了我所做的努力。

免责声明 —这些帖子是在巴塞罗纳封锁期间写的,目的是分散个人注意力和传播科学知识,以防对某人有所帮助,但不是为了成为 DRL 地区的学术参考文献。如果读者需要更严谨的文档,本系列的最后一篇文章提供了大量的学术资源和书籍供读者参考。作者意识到这一系列的帖子可能包含一些错误,如果目的是一个学术文件,则需要对英文文本进行修订以改进它。但是,尽管作者想提高内容的数量和质量,他的职业承诺并没有留给他这样做的自由时间。然而,作者同意提炼所有那些读者可以尽快报告的错误。****

posted @ 2024-10-15 13:46  绝不原创的飞龙  阅读(320)  评论(0)    收藏  举报