TowardsDataScience 博客中文翻译 2020(一千零一十一)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

用 pandas 编写高级 SQL 查询

原文:https://towardsdatascience.com/writing-advanced-sql-queries-in-pandas-1dc494a17afe?source=collection_archive---------10-----------------------

利用您的 SQL 数据操作技能来学习熊猫

能够熟练地使用 SQL 和 pandas(Python 中的一个数据分析库)操作数据,对于数据分析师、数据科学家和任何处理数据的人来说都是一项很有价值的技能。在本帖中,我们将看看精选的一些高级 SQL 查询及其在 pandas 中的对应项。

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

照片由法比奥Unsplash 上拍摄

如果你还是熊猫新手,你可能想看看 10 分钟见熊猫我之前的帖子,在那里我讨论了基本查询和它们在熊猫中的对等物的并排比较。这篇文章假设读者熟悉 SQL 查询。

0.资料组📦

我们将创建一个小数据集来使用。假设我们有两个假想的人在过去两年的旅行数据:

df = pd.DataFrame({'name': ['Ann', 'Ann', 'Ann', 'Bob', 'Bob'], 
                   'destination': ['Japan', 'Korea', 'Switzerland', 
                                   'USA', 'Switzerland'], 
                   'dep_date': ['2019-02-02', '2019-01-01', 
                                '2020-01-11', '2019-05-05', 
                                '2020-01-11'], 
                   'duration': [7, 21, 14, 10, 14]})
df

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

让我们将 dep_date 定义为前往目的地的出发日期,并假设 duration 以天数表示行程长度。

1.比较🔎

📍 1.1.换档:超前()和滞后()

我们先从基本版的LEAD()LAG()说起。对于每一次行程,我们来拉下一次行程的出发日期: lead1 ,第二次下一次行程: lead2 ,上一次行程: lag1 ,第三次上一次行程: lag3

SELECT name
       , destination
       , dep_date
       , duration
       , LEAD(dep_date) OVER(ORDER BY dep_date, name) AS lead1
       , LEAD(dep_date, 2) OVER(ORDER BY dep_date, name) AS lead2
       , LAG(dep_date) OVER(ORDER BY dep_date, name) AS lag1
       , LAG(dep_date, 3) OVER(ORDER BY dep_date, name) AS lag3
FROM df

为了在熊猫身上得到同样的产量,我们使用shift():

df.sort_values(['dep_date', 'name'], inplace=True)
df.assign(lead1 = df['dep_date'].shift(-1),
          lead2 = df['dep_date'].shift(-2),
          lag1 = df['dep_date'].shift(),
          lag3 = df['dep_date'].shift(3))

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

在第一行中,我们用sort_values()对数据进行了排序,因为我们对所有的移位操作使用了相同的逻辑。这样做比我们每次创建新列时都要对数据进行排序更有效,如下所示:

df.assign(lead1 = df.sort_values(['dep_date', 'name'])['dep_date']
                    .shift(-1),
          lead2 = df.sort_values(['dep_date', 'name'])['dep_date']
                    .shift(-2),
          lag1 = df.sort_values(['dep_date', 'name'])['dep_date']
                   .shift(),
          lag3 = df.sort_values(['dep_date', 'name'])['dep_date']
                   .shift(3))

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

这种低效方法的输出将包含正确的值,但是行的顺序将与原始数据相同,并且不会被排序。

现在让我们看看剩下的 4 行代码。在熊猫中,我们可以用assign()创建多个栏目。但是,新的列还没有添加到 DataFrame 中。如果我们想添加新的列到df,我们需要这样分配:

df.sort_values(['dep_date', 'name'], inplace=True)
df = df.assign(lead1 = df['dep_date'].shift(-1),
               lead2 = df['dep_date'].shift(-2),
               lag1 = df['dep_date'].shift(),
               lag3 = df['dep_date'].shift(3))

我们将在最后一节看另一个带有PARTITION BY()LEAD()的例子。现在,让我们看看如何操作日期/日期时间列。

📍 1.2.Date/datetime: DATENAME(),DATEDIFF(),DATEADD()

在本节中,我们将从出发日期开始提取一周的日名称:,从出发日期开始的月份名称:,从上一次旅行开始经过的天数:和到达日期: arr_date

SELECT name
       , destination
       , dep_date
       , duration
       , DATENAME(WEEKDAY, dep_date) AS day
       , DATENAME(MONTH, dep_date) AS month
       , DATEDIFF(DAY,  
                  LAG(dep_date) OVER(ORDER BY dep_date, name), 
                  dep_date) AS diff
       , DATEADD(DAY, day, dep_date) AS arr_date
FROM df

首先,我们必须确保列数据类型是正确的:

# Convert to proper dtype
df['dep_date'] = pd.to_datetime(df['dep_date'])
df['duration'] = pd.to_timedelta(df['duration'], 'D')

dep_date 转换为 datetime 将允许我们使用.dt访问器访问许多日期部分。例如:df[‘dep_date’].dt.year将给出年份(相当于 SQL 中的DATEPART(YEAR, dep_date))。

持续时间转换为 timedelta 允许我们将其添加到一个日期时间列,以获得另一个日期时间列。

完成数据类型转换后,让我们来看一下比较:

df.sort_values(['dep_date', 'name'], inplace=True)
df.assign(day = df['dep_date'].dt.day_name(),
          month = df['dep_date'].dt.month_name(),
          diff = df['dep_date'] - df['dep_date'].shift(),
          arr_date = df['dep_date'] + df['duration'])

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

如您所见,一旦正确设置了数据类型,操作就变得简单了。值得注意的是,我们可以用 DataFrame 的dtypes属性检查列的数据类型。这里有一个例子:

df.sort_values(['dep_date', 'name'], inplace=True)
df.assign(day = df['dep_date'].dt.day_name(),
          month = df['dep_date'].dt.month_name(),
          diff = df['dep_date'] - df['dep_date'].shift(),
          arr_date = df['dep_date'] + df['duration']).dtypes

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

在 pandas 中,当发现两个日期之间的差异时,它返回一个 timedelta 列。因此,我们可以看到列 diff 实际上是一个时间增量。

📍 1.3.排名:ROW_NUMBER(),RANK(),DENSE_RANK()

您可能以前在 SQL 中至少使用过这些函数中的一个。这三者之间的关键区别是他们在排名关系和排名之后的待遇。让我们创建三个列,分别使用以下方法根据持续时间对每个记录进行排序: row_number_d,rank_ddense_rank_d.

使用ROW_NUMBER()时,领带的等级与其他两种不同。为了控制如何用ROW_NUMBER()处理平局,我们使用名称来打破平局。

SELECT name
       , destination
       , dep_date
       , duration
       , ROW_NUMBER() OVER(ORDER BY duration, name) AS row_number_d
       , RANK() OVER(ORDER BY duration) AS rank_d
       , DENSE_RANK() OVER(ORDER BY duration) AS dense_rank_d
FROM df

pandas 中的查询可以通过rank()实现:

df.sort_values(['duration', 'name']).assign(
    row_number_d = df['duration'].rank(method='first').astype(int),
    rank_d = df['duration'].rank(method='min').astype(int),
    dense_rank_d = df['duration'].rank(method='dense').astype(int))

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

如上图所示,我们在rank()中指定了相关的方法。值得注意的是,这里还有我们没有涉及的其他变化。如果你有兴趣了解一下,看看文档

我们在这个例子中做了一些稍微不同的事情。与前两节中的例子不同,我们没有对数据进行适当的排序。相反,我们将方法链接起来,根本没有修改数据。

你可能也注意到了我们已经包括了astype(int)。这是为了将浮点数中的秩转换成整数。如果您喜欢看到浮动,那么可以删除这部分代码:

df.sort_values(['duration', 'name']).assign(
    row_number_d = df['duration'].rank(method='first'),
    rank_d = df['duration'].rank(method='min'),
    dense_rank_d = df['duration'].rank(method='dense'))

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

📍 1.4.聚合窗口函数和分区

在本节中,我们将为最长的旅行持续时间创建列: max_dur ,所有旅行的总持续时间: sum_dur ,每人旅行的平均持续时间: avg_dur_name 以及每人旅行时间的累计总和: cum_sum_dur_name。

SELECT name
       , destination
       , dep_date 
       , duration
       , MAX(duration) OVER() AS max_dur
       , SUM(duration) OVER() AS sum_dur
       , AVG(duration) OVER(PARTITION BY name) AS avg_dur_name
       , SUM(duration) OVER(PARTITION BY name ORDER BY dep_date
                            RANGE BETWEEN UNBOUNDED PRECEDING
                            AND CURRENT ROW) AS cum_sum_dur_name
FROM df

熊猫可以这样做:

df.assign(max_dur=df['duration'].max(),
          sum_dur=df['duration'].sum(),
          avg_dur_name=df.groupby('name')['duration']
                         .transform('mean'),
          cum_sum_dur_name=df.sort_values('dep_date')
                             .groupby('name')['duration']
                             .transform('cumsum'))

因为广播,所以在 pandas 中添加诸如 max_dursum_dur 之类的聚合统计数据很简单。本质上,如果我们试图给 pandas 中的一个新列分配一个标量值,该值将在所有行中传播。PARTITION BYgroupby()transform()组合实现。

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

在此输出中,数据的顺序与之前相同(即未排序),但它将按照 SQL 中每个人的 dep_date 排序。我们仅在创建 cum_sum_dur_name 时对数据进行了排序。如果我们希望对输出进行排序,代码将变为:

df.sort_values(['name', 'dep_date'], inplace=True)
df.assign(max_dur=df['duration'].max(),
          sum_dur=df['duration'].sum(),
          avg_dur_name=df.groupby('name')['duration']
                         .transform('mean'),
          cum_sum_dur_name=df.groupby('name')['duration']
                             .transform('cumsum'))

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

这将与 SQL 输出相同。

📍 1.5.把它放在一起

最后,让我们编写一个查询,覆盖我们刚刚访问过的四个不同区域。这是我们的最后一个例子:

SELECT ROW_NUMBER() OVER(PARTITION BY name 
                         ORDER BY dep_date) AS number
       , name
       , destination
       , DATENAME(MONTH, dep_date) AS dep_month
       , dep_date
       , DATEADD(DAY, duration, dep_date) AS arr_date
       , LEAD(dep_date) OVER(PARTITION BY NAME 
                             ORDER BY dep_date) AS next_dep_date
       , DATEDIFF(DAY, 
                  dep_date, 
                  LEAD(dep_date) OVER(PARTITION BY NAME 
                                      ORDER BY dep_date)) AS gap
       , duration
       , AVG(1.0 * duration) OVER() AS avg_dur
       , AVG(1.0 * duration) OVER(PARTITION BY name) AS avg_dur_name
       , SUM(duration) OVER(PARTITION BY name ORDER BY dep_date
                            RANGE BETWEEN UNBOUNDED PRECEDING 
                            AND CURRENT ROW) AS cum_sum_dur_name   
FROM df
ORDER BY name, dep_date

我相信当我们练习自己的时候,我们会学到更多。我鼓励您在看到我们将要看到的比较之前,自己尝试将这个 SQL 查询翻译成 pandas。👀

下面是对比:

# Convert to proper type
df['dep_date'] = pd.to_datetime(df['dep_date'])
df['duration'] = pd.to_timedelta(df['duration'], 'D')# Sort data
df.sort_values(['name', 'dep_date'], inplace=True)# Append new columns to data
df = df.assign(number=df.groupby('name')['dep_date']
                        .rank('min')
                        .astype(int),
               dep_month = df['dep_date'].dt.month_name(),
               arr_date = df['dep_date'] + df['duration'],
               next_dep_date = df.groupby('name')['dep_date']
                                 .transform(lambda x: x.shift(-1)),
               gap = df.groupby('name')['dep_date']
                       .transform(lambda x: x.shift(-1))-
                                            df['dep_date'],
               avg_dur = df['duration'].mean(),
               avg_dur_name = df.groupby('name')['duration']
                                .transform(lambda x: x.mean()),
               cum_sum_dur_name = df.groupby('name')['duration']
                                   .transform(lambda x: x.cumsum()))# Reorder columns
columns = ['number', 'name', 'destination', 'dep_month', 
           'dep_date', 'arr_date', 'next_dep_date', 
           'gap', 'duration', 'avg_dur', 'avg_dur_name', 
           'cum_sum_dur_name']
df[columns]

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

输出—第 1 部分

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

输出—第二部分

我们已经转换了数据类型,对数据进行了分类,并用新列对其进行了修改。为了以与 SQL 查询相同的方式查看列排序的数据,我们使用了一个列出列顺序的列表。如果只运行df,列的排序会有所不同。

你可能已经注意到 avg_dur 是用天数、小时数和分钟数的组合来表示的:“13 天 04:48:00”。这相当于 13 + (460+48) / (2460) = 13.2 天。如果我们只想看到 13.2,那么我们可以用这个代码片段替换df[‘duration’].mean(),它在找到平均值之前将持续时间转换为数字类型:pd.to_numeric(df[‘duration’].dt.days).mean()

当创建 avg_dur_namecum_sum_dur_name 时,我们使用了lambda函数,而不是使用这样的语法:

avg_dur_name = df.groupby('name')['duration'].transform('mean'),
cum_sum_dur_name = df.groupby('name')['duration']
                     .transform('cumsum')

这是因为如果我们试图这样做,我们将会遇到一个在这里描述的问题。因此,我们使用了一种变通办法。

Voila❕这番话结束了我们的比较。

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

Unsplash 上的 Shubham Dhage 拍摄的照片

您想访问更多这样的内容吗?媒体会员可以无限制地访问媒体上的任何文章。如果你使用 我的推荐链接成为会员,你的一部分会费会直接去支持我。

谢谢你看我的帖子。希望这篇文章对你有用,✂️,并了解更多关于熊猫的知识。如果你有兴趣了解更多关于熊猫的信息,这里有我的一些帖子的链接:

◼️️pandas 中数据聚合的 5 个技巧
◼️️ 在 pandas 中编写 5 个常见的 SQL 查询
◼️️ 给 pandas 用户的 5 个技巧
◼️️ 如何转换 pandas 数据框架中的变量

再见🏃💨

编写自定义 scikit-学习变形金刚

原文:https://towardsdatascience.com/writing-custom-scikit-learn-transformers-e07a3cf7b559?source=collection_archive---------68-----------------------

当您需要量身定制的解决方案时。

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

Samule 孙Unsplash 上的照片

scikit-learn 的 transformers API 是一个用于数据清理、预处理、特征工程和提取的强大工具。然而,有时,在众多可用的变压器中,没有一个能与手头的具体问题相匹配。在这些场合,能够自己写一个是很方便的。幸运的是,很容易利用 scikit-learn 的类来构建一个遵循包约定的转换器,并且可以包含在 scikit-learn 管道中。

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

问题设置

为了实用,我们来看一个例子。我们有一个名为TAO 的数据集,代表热带大气海洋。它包含一些天气测量,如温度、湿度或风速。R 库VIM提供了这些数据的子样本。这里,我们正在处理一个稍微预处理过的版本。

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

快速浏览一下数据框,我们会发现air_temp变量中有大量缺失值,我们需要在建模前对其进行估算。

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 733 entries, 0 to 732
Data columns (total 8 columns):
year                733 non-null int64
latitude            733 non-null int64
longitude           733 non-null int64
sea_surface_temp    733 non-null float64
air_temp            655 non-null float64
humidity            642 non-null float64
uwind               733 non-null float64
vwind               733 non-null float64
dtypes: float64(5), int64(3)
memory usage: 45.9 KB

Scikit-learn 提供了输入转换器,如SimpleImputer,它通过变量的平均值、中间值或其他一些量来填充变量的缺失值。然而,众所周知,这种插补会破坏数据中的关系。

但是看,还有另一个叫做sea_surface_temp的变量没有丢失值!我们可以预期水温与气温高度相关!让我们画出这两个变量的对比图。

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

正如我们所料,存在明显的线性关系。此外,我们可以看到为什么均值或中值插补毫无意义:在水温为 22 或 29 的观测中,将气温设定为 24.5 度的中值完全破坏了这两个变量之间的关系。

似乎输入air_temp的一个好策略是使用带有sea_surface_temp的线性回归作为预测器。从 scikit-learn 0.21 版本开始,我们可以使用IterativeImputer并将LinearRegression设置为输入引擎。然而,这将使用数据中的所有变量作为预测值,而我们只需要水温。让我们编写自己的转换器来实现这一点。

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

定制变压器

scikit-learn 转换器应该是一个实现三种方法的类:

  • fit(),它简单地返回self
  • transform(),它将数据X作为输入,并执行所需的转换,
  • fit_transform(),如果包含TransformerMixin作为基类,会自动添加。

在这些之上,我们有__init__()来捕获参数——在我们的例子中是空气和水温列的指数。我们还可以包含BaseEstimator作为基类,这将允许我们从 transformer 对象中检索参数。

总而言之,所有的工作都归结为实际编写transform()方法,该方法使用适当的列来拟合线性回归模型,并使用它来估算气温。整个事情只有几行代码:

我们现在可以像使用任何其他 scikit-learn 转换器一样使用我们的 imputer:

我们还可以提取它的参数:

{'air_temp_index': 4, 'sea_temp_index': 3}

让我们通过在之前的散点图上绘制估算值来检查估算器是否工作良好。

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

看起来不错:所有估算的数据点都在一条线上,这应该是线性回归预测的情况。更重要的是,估算的数据看起来与观察到的数据相似。

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

感谢阅读!如果你有兴趣学习更高级的插补方法,请查看我在 DataCamp 上教授的 课程。

如果你喜欢这篇文章,为什么不订阅电子邮件更新我的新文章呢?并且通过 成为媒介会员 ,可以支持我的写作,获得其他作者和我自己的所有故事的无限访问权限。

需要咨询?你可以问我任何事情,也可以在这里为我预约 1:1

也可以试试 我的其他文章 中的一篇。不能选择?从这些中选择一个:

** [## 使用 Boto3 处理亚马逊 S3 桶。

完整的备忘单。

towardsdatascience.com](/working-with-amazon-s3-buckets-with-boto3-785252ea22e0) [## 插补的不确定性

你在预测中考虑到它了吗?

towardsdatascience.com](/uncertainty-from-imputation-8dbb34a19612) [## 线性回归中收缩法和选择法的比较

详细介绍 7 种流行的收缩和选择方法。

towardsdatascience.com](/a-comparison-of-shrinkage-and-selection-methods-for-linear-regression-ee4dd3a71f16)**

用 PyTorch 编写分布式数据并行应用程序

原文:https://towardsdatascience.com/writing-distributed-applications-with-pytorch-f5de4567ed3b?source=collection_archive---------19-----------------------

多 GPU 节点的分布式数据并行训练

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

照片由 Pexels 的 Manuel 拍摄

概要

本文的主要目的是用简单的步骤阐明如何利用 PyTorch 实现的分布式计算技术在多个 GPU 上训练深度学习模型。文章假设你熟悉训练深度学习网络。本教程首先介绍一些关于分布式计算的关键概念,然后使用 PyTorch 的分布式数据并行功能编写一个 python 脚本来训练一个具有 4 个 GPU 的模型

注意:此处的教程将仅涵盖与分布式培训相关的关键步骤。完整的代码可以在这里找到

分布式计算——什么是分布式计算?

分布式系统是通过网络进行通信以实现共同目标的不同独立节点的集合。每台机器被称为一个节点,通过单个网络连接的一群节点形成一个集群。节点利用网络与其对等节点通信。

分布式计算与这样一种编写程序的风格相关联,这种编写程序的风格充分利用了分布在整个体系结构中的计算机的计算能力

深度学习的分布式计算

深度学习和分布式系统是最近越来越受欢迎的两个不断发展的系统。计算能力最近几乎呈指数级增长,通过深度神经网络(DNN),研究爱好者正在世界各地创造奇迹。因此,从两者中获益是非常重要的。如果我们利用大规模分布式系统的计算潜力,DNNs 的训练时间可以大大减少,性能也会提高

优化计算的要点:

1.通过系统和一致的处理跨多个节点分布计算

2.在对等体之间建立同步

这里的重点是用简单的步骤解释如何利用 PyTorch 分布式模块通过数据并行技术为 BERT 模型进行屏蔽语言建模训练。训练其他模型也可以遵循相同的步骤

数据并行技术

这里,数据分布在多个节点上,以实现更快的训练时间。每个节点都应该有自己专用的模型副本、优化器和其他要素。我们将使用 PyTorch 模块的分布式 API 来实现这一点。

torch . distributed-基本概述

PyTorch 通过在任何 PyTorch 模型周围提供一个包装类来支持同步分布式训练。

每个流程都有自己的 python 解释器、优化器和模型副本,并在每一步执行完整的优化,从而减少开销时间

PyTorch 还支持不同的通信后端来收集跨多个节点的迭代的每一步的向前和向后传递的结果。

现在让我们深入实际的实现

步骤 1: 获取所有可用 GPU 的列表,包括 device _ ids 和可用 GPU 的总数

步骤 2: 从任何来源加载用于掩蔽语言建模的句子,并清理和处理数据。

**第三步:**加载一个预先训练好的 BertTokenizer,用它编码所有的句子,创建目标句子。屏蔽输入句子的某些单词以创建屏蔽句子

步骤 4: 设置分布式训练所需的不同配置参数,并将其加载到单个实体中,最好是一个类

世界规模:相当于可用 GPU 数量的进程总数

主地址:将托管等级为 0 的进程的机器的 IP 地址

主端口:节点间通信的空闲可用端口

步骤 5: 定义 train()函数:

这是将分布在多个节点上的功能。因此,确保每个节点都有自己的所需变量和设置的专用副本是非常重要的

将在单个实体上收集多个不同的参数和变量,并作为值参数传递给训练函数。

除此之外,训练函数还将接收参数 rank ,处理器通过该参数来决定它是工作者节点还是主节点。

等级为 0 的节点将是主节点。PyTorch 负责为每个 GPU 分配等级,所以我们不必为此担心

步骤 5.1 :用合适的后端系统和模型建立流程组

Init_process 允许进程通过共享它们的位置来相互通信和协调。PyTorch 给出了两种指定进程组配置和启动进程组的方法

1.指定世界大小、等级和商店(可选)

2.用 URL 中编码的等级和世界大小或其他方式指定 URL 字符串,以指示在哪里/如何与对等方通信。默认情况下,它将是**“env://”**

init_process 接受 4 个参数:

1.后端:要使用的通信后端。可用选项:格洛,NCCL,MPI。NCCL 适合 GPU 训练,而 Gloo 更适合 CPU 训练

  1. Init_method: 字符串 URL(默认值:env://)

  2. World_size :作业中的进程数。通常相当于可用的 GPU 数量

4.等级:当前流程的等级

步骤 5.3 :加载模型

加载所需的模型。在我们的例子中,加载用于屏蔽语言建模的 BERT 模型(BertForMaskedLM)

步骤 5.4: set-GPU device &加载模型到设备中

步骤 5.6 :用分布式数据并行类包装模型,将模型分布到各个节点

这个容器为我们的 PyTorch 模型提供了一个包装器,并将给定模块的应用并行化,并将输入拆分到指定的设备上。该模块在集群上的每台机器和每台设备上复制,每个副本处理一小部分输入。

1.模块:要并行化的模块。在我们的案例中,我们案例中使用的模型

2.设备标识 : CUDA 设备列表

步骤 5.7 :为每个副本设置数据加载器

我们设置 training_sampler u 使用 DistributedDataSampler() 包装类来采样和分发每个副本的输入数据。

参数:

1.数据集:输入数据集

2.副本数量:在我们的例子中等于世界大小(4)

下一步是用我们定义的分布式采样器来设置 Dataloader。

步骤 5.8 定义培训流程的其余部分&保存模型

**第六步:**根据可用的 GPU 数量启动产卵过程。PyTorch 现在将在指定的世界大小和设备列表中生成进程

希望本文为您提供了一个关于如何利用 PyTorch 的分布式 API 在多个 GPU 上实现分布式训练的合理思路。完整的代码可以在这里的资源库中找到。如果您希望深入了解这些模块,我建议您访问以下链接。

[## 分布式通信包- torch.distributed - PyTorch 主文档

torch.distributed 支持三个后端,每个后端都有不同的功能。下表显示了哪些功能是…

pytorch.org](https://pytorch.org/docs/stable/distributed.html#basics) [## 使用 PyTorch 编写分布式应用程序- PyTorch 教程 1.5.1 文档

作者:Séb Arnold 在这个简短的教程中,我们将介绍 PyTorch 的分发包。我们将看到如何…

pytorch.org-](https://pytorch.org/tutorials/intermediate/dist_tuto.html)

编写优秀的 SQL

原文:https://towardsdatascience.com/writing-good-sql-ccb578ff9919?source=collection_archive---------7-----------------------

通过适配层来进一步结构化查询语言

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

国家癌症研究所Unsplash 上拍摄的照片

你想写出好的 SQL 吗?当然,但是“好”实际上是什么意思?

在某些实时环境中,只有性能被认为是“好的”,并且您以毫秒来度量您的执行时间。在商业智能和数据仓库环境中,性能仍然很重要,但通常可维护性更有价值。这可能是一个更好的解决方案,产生可读和可维护的 SQL 代码,即使它每月都要耗费大量的资金。请记住理解复杂查询的时间成本、潜在错误产生的成本以及修复错误的时间。根据您的数据库引擎优化器,您通常会两者兼得。因此,在本文中,我们关注可读性和可维护性。

我假设您已经知道 SQL 的基本和更高级的元素:连接、分组、子查询或分析函数。结合这些元素,你可以很快产生一个大混乱。但是,我们能做些什么来保持具有数百行和 20 个或更多表格的大型查询的可读性呢?

最基本的

当我们说可读性时,我们不得不谈论风格。Simon Holywel l 有一篇很棒的 SQL 风格指南,看看吧。但是如果你很匆忙,你可以用这三个建议走得很远:

  • 对所有保留的关键字使用大写,如 SELECT、FROM 或 WHERE,对列、表和符号名称使用小写
  • 通过将关键字对齐到右边,将值对齐到左边,创建一个间隙
SELECT first_name, last_name, birth_date
  FROM emp.employees
 WHERE gender = ‘F’;
  • 每当查询变得比简单的 SELECT/FROM/WHERE 语句复杂时,就使用注释
 /* find highest actual salary for each employee */
SELECT first_name, last_name, MAX(salary)
  FROM emp.employees e
  JOIN emp.salaries s
    ON e.emp_no = s.emp_no
 WHERE current_date BETWEEN from_date AND to_date -- filter date
 GROUP BY first_name, last_name;

有了这些基本规则,您的 SQL 将很容易达到至少中等的可读性水平。随着您的 SQL 变得越来越大和越来越复杂,您将达到一定的极限,在这里您需要比样式指南提供的更多的结构。

子查询,或者痛苦从哪里开始

你知道子查询吗?子查询非常适合将问题封装在查询块中。基本上,SELECT 语句中有三种类型的子查询:

  • 在 FROM 子句中,作为具有别名的派生表
SELECT COUNT(*)
  FROM (SELECT gender
          FROM emp.employees) e
  • 作为限定符放在 WHERE 子句中
SELECT *
  FROM emp.employees e
 WHERE 0 < (SELECT COUNT(*)
              FROM emp.salaries s
             WHERE s.emp_no=e.emp_no
               AND salary > 3000)

请注意,这也是一个相关子查询,应该小心使用(参见https://en.wikipedia.org/wiki/Correlated_subquery)。

  • 标量子查询(也称为相关子查询)
SELECT last_name, (SELECT MAX(salary)
                     FROM emp.salaries
                    WHERE emp_no=e.emp_no)
  FROM emp.employees e

那么问题出在哪里呢?

子查询可以有更多任意深度的子查询。当您从子查询开始时,随着时间的推移,很可能会出现更多的子查询。其他人会以你为榜样。每个子查询都需要缩进,行变得越来越长。这是更复杂语句可读性的主要问题。

更重要的是,每个子查询都将周围的查询分成代码“before”和“after”。

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

查询中间的子查询

在过程化时代,编码的黄金法则之一是:

不要写比你的屏幕大的块

(一个屏幕有 25 行)。但是如果中间有一个子查询,那么在 SELECT 块和 WHERE 子句的列之间可以有数百行。

这导致了一种有趣的阅读 SQL 查询的方式。通常,你从中间的某个地方开始,慢慢地向边缘发展。

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

带有子查询的读取方向

这种“从里到外”的阅读方向与我们通常的从上到下的阅读方向相反,我们大多数人都很习惯这种阅读方向。

的力量

我们中的一些人编写 SQL 多年,但从未使用过 WITH 子句。试试看,值得!

在 WITH 子句中,可以给子查询一个符号名,就像在 FROM 子句中一样,同时将它移到语句的开头。

WITH t_avg_salary AS (
    --averagy salary for every employee
    SELECT emp_no, AVG(salary) avg_salary
      FROM emp.salaries
     GROUP BY emp_no
)
SELECT e.last_name, avg_salary
  FROM emp.employees e
  JOIN t_avg_salary
    ON e.emp_no = t_avg_salary.emp_no
 WHERE avg_salary < 3000;

并且您可以构建一个子查询的“管道”,这些子查询相互建立

WITH t_avg_salary AS (
    -- average salary for every employee
    SELECT emp_no, AVG(salary) avg_salary
      FROM emp.salaries
     GROUP BY emp_no
),
t_avg_salary_3k AS (
    -- limit to avg. salary smaller 3k
    SELECT *
      FROM t_avg_salary
     WHERE avg_salary < 3000
),
t_employee AS (
    -- Join employee and salary
    SELECT e.last_name, avg_salary
      FROM emp.employees e
      JOIN t_avg_salary_3k
        ON e.emp_no = t_avg_salary_3k.emp_no
)
SELECT *
  FROM t_employee;

这带来了以下进步:

  • 因为每个子查询本身都是一个块,所以功能是相互分离的
  • 每个子查询都可以获得自己的标题注释,这明显提高了可理解性
  • 你可以自上而下地阅读你的代码,这对可读性很好
  • 每个子查询都以固定的缩进量从行首开始。因此,遵循团队的编码风格指南会有更少的问题,该指南通常将行长度限制在 80 个字符以内
  • 向查询中添加功能(或更多子查询)不会强制您重新格式化整个查询。这导致了你的版本控制系统的细微变化。例如,取消平均工资限额:
7,12d6
< t_avg_salary_3k AS (
<     -- limit to avg. salary smaller 3k
<     SELECT *
<       FROM t_avg_salary
<      WHERE avg_salary < 3000
< ),
17c11
< JOIN t_avg_salary_3k
 ---
> JOIN t_avg_salary

保持子查询块较小,重点放在单一功能上。不要混合功能,例如连接、过滤、分组、映射。

最后但同样重要的是,使最后一个块非常简单,只有 SELECT 和 FROM。把它想象成一个层模型。第一个模块用于数据采集,最后一个模块仅用于输出。如果你把更多的功能放进去,你会像开始时一样结束。

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

用多个子查询分层

额外收获:构建特性在 SQL 中切换

在大型系统中使用 SQL 时,通常会涉及到变量替换。如果您试图在 SQL 的两个功能之间切换,很快就会得到难看的代码。

使用 WITH,您可以轻松地将数据库名称、表名称或不同的配置参数放入配置节中。而且,您可以使用它来打开和关闭块的使用。

假设您有一个前面讨论过的子查询流。其中一个实现了对“薪金< 3000”的限制,这应该只在您的代码的较新版本中有效。

将最后一个子查询中的连接表替换为变量“t_avg_salary”(此处为 python f-string 格式):

WITH
…
t_emp_join AS (
    -- Join employee and salary
    SELECT last_name, avg_salary
      FROM t_employee e
      JOIN t_avg_salary_3k s
        ON e.emp_no = s.emp_no
)
SELECT *
  FROM t_employee;

“t_avg_salary”的可能值现在是“t_avg_salary”和“t_avg_salary_3k”。

通过更改“t_avg_salary”切换变量,您可以更改 SQL 的输出,而无需更改代码。您是创建一个伪派生表,还是简单地使用下面的派生表取决于您。

简单地跳过中间的子查询。

编写更加地道和 Pythonic 化的代码

原文:https://towardsdatascience.com/writing-more-idiomatic-and-pythonic-code-c22e900eaf83?source=collection_archive---------6-----------------------

使你的 Python 代码可读、有效、简洁和可靠的习惯用法和惯例。

有许多方法可以实现相同的特性、算法或功能。有些简单明了——更好*,有些混乱低效——更糟*。Python 社区经常使用像Python这样的术语,或者在描述遵循特定(自然、恰当)风格和约定的代码时使用。这就是我们每天都在努力编写的好的、清晰的代码,在这篇文章中,我们将回顾一些技巧、约定和习惯用法,它们将帮助你编写更多的惯用python 式代码。**

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

照片由艾哈迈德·卡希姆Unsplash 上拍摄

身份和平等比较

不只是在 Python 中,实际上在任何编程语言中,您都可能陷入混淆身份和值相等的陷阱。在 Python 中,你可以选择使用is==进行比较,其中is检查身份而==检查值。

考虑到大多数时候我们只关心价值,而不是身份,我们通常会选择==。然而,在有些情况下,你应该总是使用is操作符。其中之一就是与所有的蟒蛇单线 - NoneTrueFalse进行比较。

使用is Noneis Trueis False不仅仅是为了约定俗成或提高可读性。这也提高了性能,尤其是如果您在循环内部使用x is None而不是x == None的话。为什么会这样?你可能会问。嗯,这是因为is操作符不能像==(实际上就是a.__eq__(b))那样被重载,所以 Python 可以跳过对这些 dunder 方法的查找,这些方法是使用==进行比较所需要的。

所以,这里的底线是,你应该尽可能地使用is,因为它可读性更强,速度更快,而且更习惯。但是要想知道你是否真的能使用它,你应该问问你自己你是否关心被比较变量的价值或同一性。

上下文管理器而不是try/finally

在其他语言中,常见的做法是使用try/finally来管理资源,并确保在发生异常时处理打开的文件或获取的锁。你也可以在 Python 中使用try/finally,但是我们可以使用with语句做得更好:

上面的代码显示了所谓的上下文协议的用法,该协议由两个方法组成——分别在进入退出with块的体时调用的__enter____exit__。你可能已经知道with语句及其用法,但你可能不知道上面使用的contextlib。它是一个模块,提供了将功能转化为上下文管理器的工具。至于上面的closing函数,它只是强制调用对象的.close()方法,在本例中是page

然而,上下文协议的使用并不局限于资源管理。它也可用于抑制异常(with suppress(...))或重定向输出(with redirect_stdout(...)):

检查是否提供了参数

有时,您可能需要定义带有可选参数的函数。用 Python 可以非常容易地做到这一点,当然知道怎么做:

大多数情况下,我们使用可选参数来允许 our 函数的用户省略明显的默认参数或很少使用的选项。但是在某些情况下,我们可能希望改变函数的行为,不仅基于可选参数的值,还基于参数是否被提供。对于这种情况,一个合理的解决方案是使用None作为缺省值(当它是None do X 时,当它不是 do Y 时)。但是如果None是可接受的值呢?您可以选择另一个一次性值,但是有一个很好的惯用的解决方案:

我们可以通过创建一个名为_no_value的常量来解决这个问题,我们将这个常量设置为可选参数的默认值。通过这样做,我们避免了任何可能可接受的值,因为我们实际上根本不检查值——我们检查的是标识。换句话说,我们正在检查y参数是否与分配给_no_value的参数指向同一个对象。

多重赋值

Python 的一个很好的特性是多重赋值,这是大多数编程语言所缺乏的。最简单的形式如下:

这很好,因为它缩短和简化了代码,但我个人很少有机会使用它。在将可重复项分解成多个变量时,可以使用更实用的版本:

与使用索引为每个变量赋值相比,这无疑是更好的选择,因为它产生的视觉噪声更少,更简洁,也更不容易出错。

变量解包

基于前面的例子,我们还可以使用星形表达式来解包任意长度的 iterable 元素:

通常,iterables 中的值会有一些模式或已知的组成部分,使用解包可以很容易地提取出来。这总是比在 iterable 中显式使用索引更好的解决方案,因为这样会创建带有大量未命名和未知变量的不可读代码。

不过,在使用星形表达式时,有一点需要注意。用星形表达式解包总是创建列表,即使变量从解包中接收到零值,考虑到你不需要做任何额外的类型检查,这可能很好,但是接收到[]而不是None也可能有点令人惊讶。

如果我们想扩展这个特性的限制,那么我们甚至可以将多个级别的 iterable 分解成其他 iterable:

我不一定推荐这样做,因为这不会产生可读性很好的代码,但是知道我们使用的工具的限制是有好处的,即使我们不经常使用或者根本不使用这个特定的选项。

交换值

在其他语言中,你需要额外的变量和 3 行代码来交换 2 个变量。然而在 Python 中,有一种更好的方法类似于前面展示的多重赋值:

这是超级简单和超级有用的,它是提醒你 Python 有多棒的特性之一。除了交换变量,这也适用于可变的可重复项(如列表)及其索引,这在排序中很常见:

这看起来像是 Python 的魔法,但实际上 Python 足够聪明,知道什么时候创建临时变量,什么时候放入临时变量,在哪里赋值,什么时候丢弃。

并行处理列表

例如,在处理数据库或 CSV 表时,您经常会发现自己有多个相关数据列表。它可能是数据库表中的几列,几个相关的数据集,等等。不管数据实际上是什么,您可能都希望使用它并并行处理它。在 Python 中,最简单的方法是使用zip:

zip函数获取可变数量的列表,并生成惰性生成器,该生成器生成包含来自每个所提供列表的元素的元组。这对于处理数据来说很棒,而且非常高效,因为——正如我提到的——生成器是懒惰的,所以它不会将整个列表加载到内存中,只加载当前的元素元组。

当使用这个函数时,你可能会意识到,当处理不同长度的列表时,它并不那么好,因为它只在列表中最短的用尽时才产生值,这可能并不总是令人满意的。如果您想消耗值,直到列表中最长的用完,您可以使用itertools.zip_longest,它将使用作为参数提供的Nonefillvalue来填充缺少的值。**

避免映射、过滤和减少

Python 有许多函数式编程概念和函数,如lambda表达式、列表理解、functools模块等。然而,有一些是许多人不喜欢的。这些是mapreducefilter。但是这些功能有什么不好呢?嗯,有多种原因,但我不得不同意的一个原因是,编写列表理解通常比编写mapfilter更干净和清晰,并且在reduce的情况下,当与非平凡函数参数一起使用时,代码变得难以阅读。不喜欢这些函数的另一个很好的理由是,理想情况下应该只有一种正确的做事方式,那么当我们有列表理解时,为什么还要使用mapfilterreduce甚至lambda

如果你不同意我的观点,这是可以理解的,但在写一些愤怒的评论之前,你可能想读一读 Guido va Rossum 的简短评论,这可能会改变你的想法。

底线——尽量少用上面的函数,理想的情况是尽可能用列表理解来代替它们。

“‘reduce’的唯一目的是编写真正混乱的代码,以显示你有多酷。我只是没那么酷。”—吉多·范·罗苏姆

含电池

Python 在很长一段时间里都保持着“包含电池”的理念,这意味着你会在标准库中找到很多有用的工具、模块和函数,这些都是你意想不到的。你应该经常检查你正试图解决的问题或者你正试图实现的函数是否在标准库中的某个地方,如果你找不到,很可能是你找得不够仔细。

这些【电池】在标准库中有很多例子,我想到的第一个模块是itertools,它提供了迭代器构建块。另一个很棒的是具有高阶函数集合的functools,我还必须提到具有非常有用的数据类型的collections模块,例如Counterdequenamedtuple等等。

所以,下一次你在程序中需要一些相当常见的功能时,不要重新发明轮子,去看看 Python 库文档,抓住已经有的东西,为自己节省一些时间。

“一帮”习语

当你定义一个 Python class时,你很可能会在它的__init__方法中声明几个属性。您可能只声明一个或两个属性,但也可能以如下形式结束:

class中只有几个属性,把它们写出来没什么问题,也不会让你的代码变得那么混乱,但是如果有 10 个左右的属性——就像上面的代码——你还能把它们都写出来吗?嗯,我不会。所以,为了避免它你可以使用所谓的【习语】:

上面的代码片段演示了self.__dict__的用法,这是一个存储了class所有属性的字典(除非声明了__slots__)。这里,我们将构造函数的任何关键字参数传递给生成所有属性的update函数。也可以用vars(self)在我看来好看一点。

你可能会认为这是一个肮脏的手段,但是我认为使用它是没问题的,特别是如果你有class(数据结构)来存储属性,而没有任何真正的功能。另外 Raymond Hettinger 说可以直接更新实例字典,所以就这样了。**

结论

我绝对推荐在你的 Python 代码中使用以上所有的习惯用法和技巧,我相信这些会让你的代码更加Python 化习惯化。然而,“什么是 Pythonic?”或者“什么是惯用语?”对我有效的,可能对你无效。所以,使用习惯用法使你的代码更易读、简洁和有效,而不仅仅是因为它是习惯用法。以同样的方式,使用语言特有的 Python 特性来改进你的代码,而不仅仅是使它更加 Python 化。

本文原帖martinheinz . dev

** [## 让 Python 程序快得惊人

让我们看看我们的 Python 程序的性能,看看如何让它们快 30%!

towardsdatascience.com](/making-python-programs-blazingly-fast-c1cd79bd1b32) [## Python Itertools 之旅

让我们探索两个伟大的 Python 库——ITER tools 和 more_itertools,看看如何利用它们来处理数据…

towardsdatascience.com](/tour-of-python-itertools-2af84db18a5e) [## Python 的技巧和诀窍,你还没有看过

有很多关于 Python 中很多很酷的特性的文章,但是还有更多值得讨论的…

towardsdatascience.com](/python-tips-and-trick-you-havent-already-seen-37825547544f)**

在介质上写作让我得到了一份数据分析的工作

原文:https://towardsdatascience.com/writing-on-medium-got-me-a-job-in-data-analytics-586564d29264?source=collection_archive---------10-----------------------

这是我从工业工程过渡到数据分析和数据科学的故事

F 首先,我想说的是,我写的关于走向数据科学的文章所得到的回应让我受宠若惊。我非常感谢那些关注我、持续阅读我的文章并给我反馈的人们——你们都很棒。

在开始讲述我的故事之前,我还想说明一点:我最近接受的职位名为“全球解决方案分析师”,它实际上是数据分析、一些数据工程、数据科学和一些工业工程的结合。

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

你好,我是梅根!(照片由亚当·索罗门Unsplash 上拍摄)

对于那些不了解我个人,或者没有在 LinkedIn 上跟踪我的人,我从 2015 年到 2019 年参加了加州理工大学,并获得了工业工程学士学位。在加州理工大学期间,我有过两次实习,主要集中在制造业的流程改进(在是德科技和特斯拉),目标是为公司省钱。我在两家公司都学到了很多东西,但我真的只是喜欢其中的一些工作。剧透——这是我处理大量数据的工作。

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

这不是我,但我是金发碧眼的,而且我戴了安全眼镜!(高清科普Unsplash 上拍摄)

我意识到我不想成为一名事必躬亲、深入工厂车间、掌握流程和修理机器的工业工程师。所以,我决定在毕业时找一份技术咨询的工作来改变现状。

(为一家会计公司)技术咨询并不是我想象中的那样。相比技术和数据,我更多地处理业务/变更管理,这与我寻找的和我认为我的技能所在的领域相反。很明显,我需要为我自己的幸福做出改变,所以我在仅仅 6 个月后就辞职了,这真的超出了我的舒适区,感觉…很可怕。

经过深思熟虑和查看工作描述后,我决定通过Thinkful.com参加一个数据科学训练营。这是一个为期 6 个月的项目,我很高兴我抓住了这个机会。我选择的课程是自定进度和完全在线的,所以我可以自由地在对我来说有挑战性或有趣的概念上花更多的时间。我也有额外的时间写中型文章,因为我没有兼职做全职工作。

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

数据数据数据数据数据。由克里斯·利维拉尼Unsplash 上拍摄

我开始写中型文章,为申请工作建立我的简历/文件夹。然后我意识到:1。我真的很喜欢写作。似乎缺少适合数据科学初学者的好文章。我阅读(并欣赏)了许多关于统计和特定数据科学技术的技术文章,但我没有看到许多人试图让数据科学概念真正易于非技术或初学者阅读。

我有史以来最受欢迎的文章是关于向一个五岁的孩子解释数据科学概念和机器学习模型的最酷的是:人们开始在 LinkedIn 上联系我,因为他们读了我的文章。后来,因为我的写作,我得到了斯坦利·布莱克和德克尔公司的面试机会,这给了我一份全职工作。说实话,我对整件事还有点震惊。

我有一种感觉,我会收到一些 LinkedIn DM 的咨询,询问我关于转行、获得数据分析工作、参加训练营等方面的建议。我不是一个有经验的专业人士,但我会积极主动地提供我的一般建议:努力工作,利用免费资源,在你想要的领域建立人际关系,并试图找到一种让自己与众不同的方法。无论是写文章,活跃在 LinkedIn 上,建立一个很酷的投资组合网站,发布 YouTube 视频,还是其他什么,你都可以为自己建立一个“品牌”,这对求职真的有帮助。

此外,我相信帮助我改变职业生涯的是突出我的工业工程领域知识作为一种资产。不管你的背景是什么,如果它能让你更好地理解你正在分析的数据,或者更好地,让你根据分析做出改变,那就非常有价值!

请随时在 LinkedIn 上与我联系,但请记住,我可能无法回答您的所有问题。(出于某种原因,我在 LinkedIn 上收到了很多提问,好像我是一个经验丰富的专业人士,或者好像我主动提出成为每个人的私人导师。)并且,无论你处于数据科学职业生涯的哪个阶段,还是媒介作家之旅的哪个阶段,我都祝你好运!

以下是我在过去 6 个月的数据科学训练营中学到的一些其他文章:

[## 我研究了 500 多个数据科学面试问题

以下是我一路走来学到的东西

towardsdatascience.com](/i-worked-through-500-data-science-interview-questions-51e2e4dead9d) [## 参加新兵训练营?这里有一些注意事项

经过 4 个月的数据科学课程,我学到了一些东西

medium.com](https://medium.com/thinkful/enrolling-in-a-boot-camp-here-are-some-dos-and-don-ts-95c93acff5d1)

此外,如果您希望开始或继续学习数据科学,这里有一篇文章提供了大量免费学习资源的链接:

[## 免费数据科学资源汇编

对于那些对学习数据科学感兴趣的人

towardsdatascience.com](/a-compilation-of-free-data-science-resources-7861f572cc85)

一如既往的感谢阅读:)

Kaggle 比赛后撰写论文/技术报告

原文:https://towardsdatascience.com/writing-papers-tech-reports-after-kaggle-competitions-ee504fc0c4c1?source=collection_archive---------29-----------------------

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

照片由帕特里克·福尔Unsplash 拍摄

我参加机器学习挑战赛后发表科技论文的经历

关于 Kaggle

Kaggle 是最受欢迎的机器学习竞赛平台。它举办免费的课堂竞赛、CVPR 和 NIPS 等会议的挑战、科学竞赛和商业挑战。挑战组织者通常提供数据、评估标准和评估测试集。该测试集用于形成公共排行榜,允许近似比较参与者的模型性能,并在挑战的追逐游戏中驱动游戏化能力。许多人被公众排行榜的追逐所消耗和摧毁,而不是相信他们的本地验证。

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

图片来自 Pixabaymorzaszum

Kaggle 平台也有讨论、笔记本和数据集,参与者可以分享他们的想法、数据和代码样本。这有助于加快这一进程,因为在一定程度上,这一挑战正得到集体解决。也为学习提供了很大的支持;因此,许多学生和起义机器学习专家选择 Kaggle 平台进行首次比赛。

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

Kaggle 网站界面。

当然还有其他的机器学习比赛平台,比如 topcoderCodalabZindi 等等【更多是这里。但是由于缺少笔记本和良好的论坛,他们更倾向于既定的专业人士,而不太适合学生和学习者。因此,Kaggle 通常是练习机器学习的首选。

Kaggle 经常为谷歌云平台提供凭证,可以在有限的挑战时间内使用。荷兰互联网服务提供商 HOSTKEY b . v .(https://www.hostkey.com/gpu-servers#/)也可以提供对 GPU 服务器的访问和技术援助。你可以在这里申请他们的资助:【http://landing.hostkey.com/grants】T2。

为什么要在 Kaggle 比赛后写论文/技术报告

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

安德鲁·尼尔Unsplash 上拍照

在机器学习竞赛期间,通常会尝试和验证许多方法和想法,通常会为给定的任务产生最先进的模型。太多时候,所有这一切都没有结果,除了前三名的解决方案可能会去挑战组织者那里。这显然是对知识和(通常是巨大的)计算资源的浪费,这很遗憾。

近年来,许多顶级参与者撰写文章描述他们的解决方案,甚至在比赛结束后公开他们的代码。这是一个伟大的创举。然而,简短的记录通常不足以再现结果,Kaggle 风格的代码通常有些混乱,没有注释很难理解。在挑战过程中,每个人都在匆忙追逐排行榜,只有少数参与者为生产质量代码而烦恼。

以下是考虑在比赛后将你的顶级 Kaggle 解决方案模型形成一份详细的技术报告/论文,而不是我们通常看到的一个小时的书面报告的主要原因。

1.这是对人类知识基础的巨大贡献,它确实产生了影响。通常,在竞赛期间,几个想法被实施,许多尝试(和失败)被执行,有时甚至可以在获奖模型中看到 SOTA 解决方案。详细总结这一切将有助于其他研究人员和学生在选择方法、模型架构、损失函数或增强时节省时间。

即使你没有明确地看到影响,它也是存在的——在你论文的所有引用和 GitHub repo 的分叉中。

2.挑战后适当的技术报告/论文迫使你清理你的代码,使其可读和可复制。作为 GitHub 上的一个迷你项目,它看起来很不错,引用了 arXiv 和一个干净的项目代码——你可以把它添加到简历中,在没有 nd a 问题的情况下分享。

3.向 arXiv 投稿没有同行评审程序,而向期刊/会议投稿则有。在 arXiv 上发布技术报告后,您可以将其发送到会议论文集或相关期刊。这件事也发生在我身上:在 arXiv 上发表了一份草稿后,它被邀请到一家 T2 杂志。将你的作品提交给会议和期刊会对你的模型和使用的方法进行适当的同行评审。是的,有时审查意味着你需要做额外的计算,烧蚀研究和重写一半的论文(我知道那种感觉),但值得知道的是,这种反馈使你的研究和技术部分更好。

4.你已经准备好了一切:数据分析、工作管道代码、你的结果甚至数字。挑战结束后直接把它们放在一起会更容易。

5.最后是很好的长期公关。Kaggle post 每天都很受欢迎,一篇好的同行评审论文会持续很长时间,它会出现在 arXiv 和相关的会议记录上,从而为你和你的公司(如果你有的话)创造一个长期的公关。

竞赛后写论文/技术报告的一些顾虑

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

图片由 Gerd AltmannPixabay 拍摄

  1. 天下没有免费的午餐。写一份技术报告或论文意味着花时间制作适当的文件,浏览相关文献,回顾当前的艺术水平,详述你的方法,绘制结果,起草文本等等。这需要时间。找到对此感兴趣的合作者是有用的,即使他们没有参与挑战。
  2. 做一份合适的论文通常意味着重新运行你在挑战追逐中快速做出的所有计算,所有这些尝试和失败现在都需要重现,消融研究也需要执行。在研究中没有失败,只有有价值的信息,所以是的,你需要运行所有那些未改进的模型来衡量你的改进的影响。这意味着更多的计算,更多的尝试和系统的研究。有时,你可能会找到一个比你提交的挑战更好的解决方案。很正常。
  3. 经历会议/期刊投稿和所有这些同行评审过程有时真的很痛苦。有时审查意味着你需要做额外的计算,烧蚀研究和重写一半的论文。记住,它让你工作得更好。它教会你耐心。
  4. 有时候,在竞争追逐之后,你太累了,以至于不能再看一遍代码,让它变得干净,添加所有那些文档字符串和注释。这也很正常。但是记住,编写一个好的代码并以 GitHub repo 的形式打开它也有助于你的简历。
  5. 同行评审过程可能会遭到拒绝。不要对此过于沮丧:考虑审稿人的反馈,然后重新提交给更相关的期刊或会议。

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

图片由来自 PixabayRyan McGuire 拍摄

去年,我成功地提交了两篇关于挑战的技术论文。我在 arXivGitHub 上发表了它们。一篇论文被邀请到天文学会杂志,第二篇论文被 CVPR 研讨会接受。以下是如何实现这一目标的分步指南。

赛后撰写论文/技术报告的步骤

  1. 做你的研究当前的艺术状态,用于类似任务的方法,阅读最近的相关论文。最有可能的是,你已经在一次竞赛中尝试实施这些论文中的想法。现在,是时候把东西放在一起,参考所有以前的工作,并在引言中用几句话形成一个概述。

关于深度学习的新方法的最新信息,一个很好的来源是papers with code。它提供了带有可用代码的出版物参考,并提供了流行数据集的最新排行榜。

2.清理代码并添加注释。您可以考虑使用 黑色 进行样式格式化, isort 进行导入排序,flake 8Mypy进行检查。这篇博文提供了如何让你的代码更具可读性的有用信息。编写一个自述文件,说明如何设置环境和下载数据,如何训练模型和再现实验。****

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

图片来自 Pixabay丹尼尔·基尔希

3.做消融研究。修正所有的随机种子和超参数,对所有有用的和不太成功的技巧重复计算,一个一个地引入变化,重复所有你尝试过但被拒绝的尝试,记录每次的度量。这将给你一个关于你所实现的模型改进的真正贡献的消融研究。

4.浏览 Kaggle 上分享的其他顶级解决方案,联系获胜者,询问如何使用他们的想法/代码作为参考。值得在您的消融研究中添加他们的改进,并在论文讨论环节中纳入他们的想法。总的来说,Kagglers 对此非常开放:我询问了大约 3-4 个人关于使用他们的参考内容的问题,并且总是得到许可。你甚至可以进一步改进你的模型,然后迟些提交参赛作品。Kaggle 平台允许迟交。

5.制作一个数据集描述,准备几个说明数据的图表,显示数据类别分布,给出所有使用的额外数据的来源。它应该遵循介绍。描述给定的任务和使用的指标。

6.当您完成消融研究,用改进的方法重新训练您的模型,并在排行榜上取得好成绩时,是时候写下来了。描述您使用的模型、您如何分割数据、使用的超参数以及培训过程。简洁明了,参考你的 GitHub repo。不要忘记引用你在文中使用的所有资源。

7.写下你的结果。制作一些图表,说明不同模型的训练和数据扩充;添加一个表格,列出您的实验和消融研究的评分结果。

8.最后,反思你的结果。你可以添加一个讨论区,也可以添加失败的尝试,提到什么没有成功。此外,您可以将其他参与者分享的观点纳入本部分。

9.不要忘记一个致谢环节,感谢挑战组织者、Kaggle 平台和任何你认为有用的东西。

10.要制作纸张样式,您可以使用 LaTex 编辑器(即 WinEdit)或在线编辑器(即背面),并从背面的下载不同的样式。一旦完成,用从语法上检查你的文本是个好主意。

11.首先向 arXiv 提交您的作品。然后,确定相关的会议和期刊,在选择会议时注意即将到来的提交截止日期,阅读他们对作者的说明,下载他们的 latex 模板,并将您的内容复制到其中。准备好后,通过会议或期刊网站提交,等待评审。

同行评审过程可能会遭到拒绝。不要对此过于沮丧:每个期刊/会议都有它的范围。尽可能遵循评论者的指导方针,并考虑他们的反馈。然后,将改进后的文章重新提交给另一个相关的期刊或会议。

经过所有的工作,一些挫折和改进,你的工作会看到世界。到那时,它将更具可读性和实用性。还有,很有可能,会让你开心:)。对于你的简历和 GitHub repo 来说都会是一笔很好的资产。

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

图片来自 StartupStockPhotos 来自 Pixabay

撰写专业数据科学文档

原文:https://towardsdatascience.com/writing-professsional-data-science-documentation-1141737836fa?source=collection_archive---------57-----------------------

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

安妮·斯普拉特在 Unsplash 上的照片

文档是成为数据科学家的重要组成部分。我建议使用 R Markdown 和 LaTeX 来记录数据科学模型。

好的文档有几个可取的特性

  • 容易接近
  • 易读的
  • 跨项目保持一致
  • 可再生的

在 R Markdown 中使用 LaTeX 允许用户在多个项目中使用一致的 LaTeX 格式,编写解释给定模型的专业数学公式,一致地引用图形/文章,并从模型的输出中动态地生成图形。

LaTeX 是一个文档准备系统,最初是为学者设计的,用于在科学出版物的格式上引入一致性。它还可以成功地用于记录机器学习模型。

为了使用它,你需要安装 LaTeX 发行版。不需要安装完整版的 LaTeX。可以使用 R 包 tinytex 来呈现带有 LaTeX 代码的文档。

tinytex::**install_tinytex**()

要安装缺失的 LaTeX 库,可以使用 tinytext 通过粘贴错误消息作为参数来安装。

tinytex::**parse_install()**

例如,您可以通过日志文件来修复所有缺失的库错误。

tinytex::**parse_install**("filename.log")

LaTex 在 R Markdown 中的主要用途是键入数学公式和编号方程,添加引用。这是我为格兰杰因果关系键入的代码示例。

\begin{equation}\begin{pmatrix}U_{t} \\OLI_{t} \\\end{pmatrix}=\begin{pmatrix}\alpha_{1} \\\alpha_{2} \\\end{pmatrix}+\begin{bmatrix}\delta_{1,1,1} & \delta_{1,1,2} \\\delta_{1,2,1} & \delta_{1,2,2} \\\end{bmatrix}\begin{pmatrix}U_{t-1} \\OLI_{t-1} \\\end{pmatrix}+ ... +\begin{bmatrix}\delta_{p,1,1} & \delta_{p,1,2} \\\delta_{p,2,1} & \delta_{p,2,2} \\\end{bmatrix}\begin{pmatrix}U_{t-p} \\OLI_{t-p} \\\end{pmatrix}+\begin{pmatrix}\eta_{1t} \\\eta_{2t} \\\end{pmatrix}\end{equation}

这就是它在渲染文档中的样子。

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

图 1:格兰杰因果关系

我意识到上面的代码可能看起来很吓人。LaTeX 可能有一个陡峭的学习曲线,但是一旦你在谷歌的帮助下键入几个第一方程,它就会变得明显更容易和更自动化。

R Markdown 允许您将文档划分为节/子节,添加标题,添加目录,并生成可以记录给定模型输出的图表。您可以在代码块中编写 R/Python 代码,并在代码块之间编写 LaTeX 公式和文本。R Markdown 文档易于编辑和呈现。要了解更多关于 R Markdown、设置参数和渲染 HTML/pdf 的信息,我推荐使用 R Markdown Cookbookhttps://bookdown . org/易慧/rmarkdown-Cookbook/rmarkdown-process . HTML

为 agile R Markdown 文档提供 LaTeX 的一致性和可能性,为您提供了一个记录数据科学模型的强大工具,这对于未来从事您的项目的数据科学家以及希望了解您的工作的更多细节的技术利益相关者来说至关重要。

我建议将 R Markdown 文档和呈现的 HTML/PDF 一起包含在您的项目 git 存储库中,在 documentation 文件夹中。这将允许您轻松访问模型的更多技术细节,并进行任何必要的更正。此外,您只能在渲染 pdf 时使用 LaTeX。否则,请随意使用 HTML。

LaTeX 和 R Markdown 的有用资源列表

[1]https://book down . org/易慧/rmarkdown-cookbook/rmarkdown-process . html

[2]https://bookdown.org/yihui/rmarkdown/pdf-document.html

[3]https://wch.github.io/latexsheet/

[4]https://www . over leaf . com/learn/latex/书目 _ 管理 _with_bibtex

如何编写 TensorFlow 2 自定义循环

原文:https://towardsdatascience.com/writing-tensorflow-2-custom-loops-438b1ab6eb6c?source=collection_archive---------19-----------------------

从 Keras 到 TensorFlow 2 的分步指南

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

Georg EiermannUnsplash 上拍摄

我使用 Keras 已经有一段时间了,我从来没有找到一个好的理由去其他地方。TensorFlow 1 笨拙,PyTorch 虽然性感,但不太懂我。我倾向于做原型的时候学的最多,Keras 是这里的王者。快进到 2019 年 9 月,TensorFlow 2 发布。不久之后,我把所有的import keras通话都切换到了import tensorflow.keras

如果这篇文章只是关于从 Keras 迁移到 TensorFlow 2,它可以在这里结束。真的。然而,在 TensorFlow 2 附带的所有功能中,自定义训练循环无疑是 Keras 用户的最佳新功能。在本文中,我解释了它们为什么重要以及如何实现。

**免责声明:**我已经将所有代码添加为图片,因为它在智能手机上显示得更好。所有代码都可以作为 GitHub gist获得。如果你知道或者更喜欢发布代码的其他替代方法,请写信给我。

张量流 2

对于外行人来说,TensorFlow 2 的问题在于,它抛弃了 TensorFlow 1 的大多数习惯用法和 Keras 上的几个 API,Keras 是唯一一个用于定义神经网络的 API。此外,他们热衷于执行死刑。

这两个变化一起解决了早期张量流的许多批评:

  1. 不再有几个 API。
  2. 不需要手动管理变量。
  3. 会话没了。
  4. 可以调试执行流程。
  5. 动态模型现在是可能的。

与此同时,他们成功实现了这一点,同时保留了使 TensorFlow 1 闻名遐迩的部署能力和速度。

对于 Keras 用户来说,新的 API 意味着四件事:

  1. 我们不再处于抽象层。
  2. 创作新技术要容易得多。
  3. 编写定制的训练循环现在是可行的。
  4. 执行速度大大加快。

其中,自定义循环是 TensorFlow 2 对 Keras 用户如此重要的原因。定制循环提供了对训练的最终控制,同时使训练速度提高了约 30%。

老实说,TensorFlow 2 更好的名字应该是 Keras 3。

我知道一些谷歌开发人员可能会在我写这篇文章的时候死去,但这是事实。TensorFlow 1 是 Keras 的后端,在升级后基本保持不变。大多数新事物都比张量流更经典。

训练循环

本质上,所有 Keras 计划都遵循以下结构:

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

这一切都从导入开始,然后是数据集加载和准备、模型加载/创建,最后是编译和拟合调用。Keras 独有的编译方法将模型与损失函数和优化器相关联,而拟合函数执行所谓的“训练循环”

训练循环是将整个训练集逐批提供给算法、计算损失、其梯度并应用优化器的代码。然后,验证集被用于计算验证损失和验证指标。最后,整个过程重复几个“时期”

在训练循环期间,fit 方法还执行其他功能,例如操作几个工作线程、对模型进行检查点操作以及将结果记录到磁盘。自定义代码也可以通过回调在特定事件中插入。

Keras 用户习惯于根本不用编写任何训练循环。fit 函数完美地完成了这一切,并允许对大多数用例进行适当的定制

固定训练循环的问题是,当不同的用例出现时,你就不走运了。最初的 Keras 很少提供定制的训练循环。

例子可以很容易地在 GAN 教程中找到。为了训练敌对网络,你必须交错他们的训练。为此,train_on_batch 方法是交错生成器和鉴别器训练的最佳方法,让您手动批处理和混洗数据集,编写您的进度条形码,并将其打包到每个历元的 For 循环中。

在 2017 年, Wasserstein GAN 被提出,它要求在训练中加入梯度裁剪,这是一个简单的要求。为了保持文明,Keras 中的 WGAN 实现是臃肿的。

这些都不是孤立的例子。任何多网络设置、渐变技巧或开箱即用的解决方案都可能需要您编写大量代码。这就是为什么 Keras 在研究者中如此不受欢迎(也是为什么 PyTorch 如此受欢迎)。

自定义循环

TensorFlow 2 为 Keras 用户带来的是打开train_on_batch 调用的能力,公开损失、梯度和优化器调用。然而,要使用它,您必须放弃编译和拟合功能。

从好的方面来看,Keras 不再是 TensorFlow 上的抽象。它现在是它的一部分了。这意味着我们不再需要在 Keras 中创建定制逻辑的所有奇怪的东西。一切兼容。我们不再需要。

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

首先,您必须自己获得损失和优化器对象。然后,定义 train_on_batch 调用。在我看来这很像 PyTorch 代码。你只需调用传递 x 的方法来得到ŷ,然后与 y 比较,得到损失值。

这一切都发生在梯度带的环境中,梯度带只是一种跟踪应该区分哪些操作的方法。使用磁带,我们可以得到关于每个训练变量损失的梯度。然后,梯度变量对被馈送到优化器,优化器将更新网络。

最后一行只是一个例子,说明如何提取一批 128 个样本来调试我们的新方法。

它的孪生兄弟validate_on_batch,只是它的一个简单版本。我们只需要摆脱胶带和梯度逻辑。

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

本质上,它是我们在渐变磁带中找到的相同代码,但是没有磁带(和渐变/优化器逻辑)。

**关于“训练=真”和“训练=假”参数的说明:**这改变了一些层的行为。例如, dropout 层在训练期间会丢弃一些连接,但在测试期间不会。这不会直接影响优化或任何其他与训练相关的任务。

完整训练循环的最小示例如下所示:

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

至此,我们有了一个最小的工作示例。然而,它缺少几个基本特征:

  1. 当前的批处理逻辑笨拙且容易出错。
  2. 除了每个时期打印一张以外,没有进度指示器。
  3. 没有模型检查点逻辑。

这使我们想到以下一点:

做自己的循环很好,但是它也需要你重新编码一些你认为理所当然的特性

谢天谢地,改进它并不难:)

改善环路

首先要注意的是tf.data包。它包含 tf.data.Dataset 类,该类封装了几个数据集任务。

数据集 API 使用“流畅的风格”这意味着对 Dataset 对象的所有调用都返回另一个 Dataset 对象。这使得链接调用成为可能。下面是一个用它来解决我们的问题的例子:

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

这些调用为定型和测试数据创建一个 dataset 对象,为洗牌做准备,并对实例进行批处理。在我们的循环中,笨拙的批处理代码如下所示:

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

整洁多了。新代码只需枚举数据集中的所有批次。这也为我们处理洗牌,这总是一个好主意。

为了让我们的代码看起来更加生动,我们可以添加一些打印语句。我们还可以使我们的验证逻辑更短一些:

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

现在我们打印当前的纪元和批次,以及一些点来保持它的移动。为了验证,我们创建了一个每批平均损耗的列表,然后打印出最终的平均损耗。这是它在控制台中的样子:

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

对于模型检查点,我们必须跟踪到目前为止最好的验证准确性,以便我们只保存提高了我们性能的模型。这要求我们跟踪最佳损失,并将新的损失与之进行比较。就代码而言,这变成如下:

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

这完成了我们的目标,即改进数据集处理,看到更频繁的屏幕更新,并在训练时保存模型检查点。

最后一步是让它具有性能。

tf .函数

到目前为止,我们正在所谓的“渴望模式”下运行这意味着如果你写“a + b ”,求和的结果会立即计算出来。虽然这简化了调试,但不是性能最好的方法。

深度学习发生在 GPU 上。每个“求和”和“相乘”命令都有成本。CPU 必须调用 GPU 并告诉哪些变量需要操作,等待操作完成,并取回结果。这是慢。一种更快的方法是给 GPU 一大堆要做的事情,并且只等待一次。

这种替代方法被称为“延迟模式”或“计算图”这个想法是让 TensorFlow 把你的网络变成一组对数据进行运算的数学步骤。这个命令列表再发送到 GPU,整体处理,速度快很多。

创建命令列表对于优化也是至关重要的。InceptionNet 等模型有多条路径,可以并行计算。简单的运算可以合并,例如乘法后接加法,等等。

要让 TensorFlow 为您构建这个图,您只需要用@tf.function 注释来注释train_on_batchvalidate_on_batch 调用。就这么简单:

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

第一次调用这两个函数时,TensorFlow 将解析其代码并构建关联的图。这将比平常花费更长的时间,但会使所有后续的调用明显更快。

一个很好的方法是在里面放一个 print 语句。在计算图形构建期间,打印将仅执行一次或两次。然后,它将不再打印,因为该函数不再被调用。

**在数值上,使用 RTX 2070 GPU,原始 Keras fit 函数需要 18 秒,自定义循环需要 40 秒,优化循环需要 20 秒。**这个简单的注释使它的速度比急切模式快了一倍。与 Keras fit 相比,它慢了 2 秒,显示了原始 fit 的优化程度。对于较大的问题和网络,优化的自定义循环优于原始拟合。在实践中,我发现使用定制循环可以提高 30%的纪元速度。

使用@tf.function 注释的缺点是它的错误消息很糟糕。经验法则是先在没有它的情况下开发,然后添加它只是为了验证,然后再添加到培训中。这样,您可以更容易地确定错误。

后续步骤

切换到自定义循环的用户正在不断改进他们的工作流程。例如,我已经在我的自定义代码中实现了回调和度量,以及一个漂亮的进度条。在互联网上,你可以找到一些软件包,如 TQDM 或非常 Keras 进度条

实现自定义循环看起来像是额外的工作,但是它很快就有了回报,并且您只需要做一次。它允许您完全控制何时进行验证、计算哪些指标、复杂的培训计划等等。就模型而言,篡改训练过程要容易得多。您可以添加梯度惩罚,训练几个模型,或轻松创建虚拟批次。

事实上,PyTorch 用户多年来一直在这么做。

我把如何实现这些留给了你。如果你有任何问题,欢迎在评论区提问。

在我离开之前,有一个好消息即将发布。T ensorflow 2.2 将允许您将自己的 **train_on_batch** **validate_on_batch** 函数反馈给原始函数。安装 API 。这意味着我们将两全其美。fit 调用将更加模块化,同时我们保留从头开始实现它的可能性。

这篇文章的代码可以在这里找到。

更新:我最近发表了一份关于 TensorFlow 和 Keras 的技巧列表。在那里,我描述了如何创建定制的训练循环,而不需要重新实现整个。适合功能。

[## 让 Keras 和 TensorFlow 更上一层楼

充分利用 Keras 和 TensorFlow 的 11 个技巧和诀窍

towardsdatascience.com](/taking-keras-and-tensorflow-to-the-next-level-c73466e829d3)

如果您对本文有任何问题,请随时发表评论或与我联系。如果你刚接触媒体,我强烈推荐订阅。对于数据和 IT 专业人士来说,中型文章是 StackOverflow 的完美搭档,对于新手来说更是如此。注册时请考虑使用我的会员链接。

感谢阅读:)

编写你的第一个人工智能/机器学习程序

原文:https://towardsdatascience.com/writing-your-first-ai-machine-learning-program-92a590df86de?source=collection_archive---------17-----------------------

用于分类的鸢尾花数据集上的多项式逻辑回归

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

来源:https://pix abay . com/photos/work-typing-computer-notebook-731198/

你可能已经学到了很多关于人工智能和机器学习的理论,并且觉得很有趣。但是没有什么比看到模型和算法在真实数据上工作并产生结果更好的了,不是吗?有很多资料教你如何着手编写你的第一个 ML 程序,但我发现在大多数情况下,没有多少关于如何着手解决特定问题的分步指导。写得好的代码到处都是,但是缺乏方法论,这和学习如何写程序一样重要。所以我决定写一篇著名的《人工智能世界入门》——鸢尾花分类问题。

使用的数据集和算法

Iris flowers 数据集基本上包含 150 种花的实例。每朵花有 4 个属性:萼片长度、萼片宽度、花瓣长度和花瓣宽度(每一个都以厘米为单位),它可能属于 3 个可能的类别:刚毛花、蠕虫花和海滨花。更多信息,请访问网站:【https://archive.ics.uci.edu/ml/datasets/iris

我们的目标是开发一个分类器,它可以基于 4 个特征将花准确地分类为 3 类中的一类。有很多算法可以做到这一点,但是因为这是你的第一个人工智能程序,让我们坚持一个最简单的算法,它也可以在这个数据集上相对较好地工作——逻辑回归。如果你刚开始学习机器,不知道它是什么,可以看看 Andrew NG 的流行的机器学习课程中的这一系列讲座。它们是一个完美的开始方式。如果你不熟悉正则化,也可以看看下一个系列的讲座,即第 7 讲。

如果你已经精通线性代数、一元和多元微积分、概率以及统计,并且想要更深入的数学理解,那么看看斯坦福在线的这个视频

是啊,我有点喜欢吴君如!总之,总结一下逻辑回归的作用,假设我们有以下数据集-

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

2D 数据集的散点图

旁边的数字显示了学生在两次考试中的录取分数,以及他们是否根据分数被学校/学院录取。逻辑回归所做的是,它试图找到一个线性决策边界,以最好地区分类别。

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

逻辑回归决策边界

正如我们所看到的,LR 很好地分离了这两个类。但是如果有两个以上的类呢,就像我们的例子一样?在这种情况下,我们为 n 个类别中的每个类别训练 n 个分类器,并让每个分类器尝试将一个类别从其余类别中分离出来。这种技术被正确地称为“一个对所有的分类”。最后,对于实例的预测,我们选择检测到其类最强的分类器,并将该类指定为预测类。这里的决策界限有点难以想象,但这里有一个来自 Sklearn 的例子

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

来源:https://sci kit-learn . org/stable/auto _ examples/linear _ model/plot _ iris _ logistic . html

入门指南

好了,必要条件讲够了,现在让我们开始写代码。当然,我们将使用 Python 以及以下模块:Numpy、Matplotlib、Seaborn 和 Sklearn。如果你像我一样在你的电脑上工作,确保你已经安装了这些模块。要安装它们,只需打开命令行/终端,输入命令“pip install ”。要检查安装了哪些模块,请输入“python”,然后输入“help('modules ')”以生成所有已安装模块的列表。

数据分析和可视化

首先,我们需要了解数据集中数据的分布情况。为此,让我们导入 matplotlib 和 seaborn 模块,并加载包含在 seaborn 模块中的 iris 数据集。

import matplotlib.pyplot as plt
import seaborn as sns
iris = sns.load_dataset(‘iris’)

这将把数据集加载到数据框架‘iris’中,这将使可视化更加容易。由于数据集有 4 个特征,我们不能直接将其可视化,但我们可以通过 seaborn 强大的 pairplot 获得一些直觉。pairplot 的作用是在数据集中的每对变量之间绘制散点图,以及每个变量的值的分布(沿对角线图形)。这可以用来分析哪些特征是数据的更好的分离器,哪些特征是密切相关的,以及数据分布。

sns.pairplot(iris, hue='species') #hue parameter colors distinct species
plt.show()

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

Iris 数据集上的 Seaborn Pairplot

Seaborn 的另一个强大工具是相关性热图。相关性是两个变量相互依赖程度的统计度量。如果一个变量的增加导致另一个变量的粗略增加,反之亦然,那么他们被称为正相关。如果一个变量的增加导致另一个变量的减少,反之亦然,它们是负相关的,如果它们之间没有这种相关性,它们就没有相关性。这就是我们如何用 Seaborn 绘制相关性图

sns.heatmap(iris.corr(), annot=True, cmap='coolwarm')
plt.show()

iris.corr()生成一个 4*4 矩阵,每个条目(I,j)代表 iᵗʰ和 jᵗʰ变量之间的相关性。显然,矩阵是对称的,因为 I 和 j 之间的依赖关系与 j 和 I 之间的依赖关系是一样的(希望这也适用于人类)。对角线元素是 1,因为一个变量显然完全依赖于它自己。annot 参数决定是否在热图顶部显示相关值,colormap 设置为 coolwarm,这意味着低值为蓝色,高值为红色。

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

Iris 数据集上的相关热图

数据准备和预处理

现在我们对数据有了一个直觉,让我们将数据装载到 numpy 数组中并对其进行预处理。预处理是至关重要的一步,它可以极大地提高算法的性能。我们导入所需的模块,以字典的形式从 sklearn 的 iris datasets 类中加载数据集,将特性和目标分别放入 numpy 数组 X 和 Y 中,并将类名放入 names 中。由于数据集中指定的目标是 0、1 和 2,代表 3 类物种,我们希望从这些整数映射到它们所代表的类的名称。为此,我们创建了一个从整数 0,1,2 到花名的字典映射。

import numpy as np
from sklearn.datasets import load_iris
dataset = load_iris()
X, Y, names = dataset['data'], dataset['target'], dataset['target_names']
target = dict(zip(np.array([0, 1, 2]), names))

让我们前进到预处理步骤。我们使用 sklearn 的 train_test_split 将数据分为训练集和测试集,使用 25%的测试集大小,然后使用 sklearn 的 StandardScaler 类。StandardScaler 所做的是计算数据集中每个要素的平均值和标准差,然后减去平均值并除以数据集中每个示例的标准差。这使得所有特征具有零均值和单位标准差/方差。将所有要素纳入同一范围也称为要素归一化,它有助于梯度下降等优化算法正常工作并更快收敛。

from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.25)
scaler = StandardScaler()  #create object of StandardScaler class
scaler.fit(X_train)        #fit it to the training set
X_train_pr = scaler.transform(X_train) #apply normalization to the training set

建立模型并评估它

是时候做真正的交易了。现在你会觉得非常感激 sklearn 让你的生活变得简单。我们创建了一个名为 model 的 LogisticRegression 类的对象,并使我们的训练数据集适合它,所有这些都使用了 3 行代码

from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X_train_pr, Y_train)

现在,为了进行预测,我们首先使用标准定标器对测试集进行归一化。注意,该变换与应用于训练集(我们将缩放器安装到该训练集)的变换相同。这很重要,因为我们必须根据训练集的平均值和标准偏差来标准化测试集,而不是测试集。然后,我们使用预测函数在训练集和测试集上生成预测的 1D 数组。sklearn 的度量类中有许多可用的度量,但我们将使用 3 个最相关的度量——准确性、分类报告和混淆矩阵。

from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
X_test_pr = scaler.transform(X_test)
Y_train_pred, Y_test_pred = model.predict(X_train_pr), model.predict(X_test_pr) 
print(accuracy_score(Y_train, Y_train_pred))
print(accuracy_score(Y_test, Y_test_pred))
print(classification_report(Y_test, Y_test_pred))
print(confusion_matrix(Y_test, Y_test_pred))

数据集非常小,因此,每次训练模型时,您可能会得到非常不同的结果。这是我得到的输出-

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

训练模型的评估

如果你不理解你看到的任何指标,请随意搜索它们,它们非常简单易懂。训练集精度约为 95.5%,测试集精度约为 94.7%。测试集中所有不同类别的 F1 分数的加权平均值是 0.95,并且测试集中的 2 个实例被错误地分类。第一次训练集上 94.7%的准确率确实很好,但我们可以做得更好。

改进模型

下面介绍多项式逻辑回归。事实证明,我们可以通过在模型中引入多项式特征来建立一个更好的模型,就像 x₁、x₁x₂、x₂那样,产生一个非线性的决策边界来更好地划分类别。这种模式比较实用。例如,让我们看看下面的数据集

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

2D 数据集的散点图

这个数据集看起来更实用一点,不是吗?它显示了在不同微芯片上的测试成绩和它们所属的类别。很明显,没有一个线性的决策边界能够令人满意地分离数据。使用多项式逻辑回归,我们可以得到一个决策边界,如下所示,它做得更好。

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

多项式逻辑回归决策边界

图中的λ= 1 指的是正则化参数。在处理非线性模型时,正则化变得非常重要,因为您不想过度适应训练集,也不想让您的模型在它没有见过的新示例上表现不佳。

要将多项式要素添加到数据集中,我们使用 sklearn 中的多项式要素类。这将作为附加步骤进入您的预处理,类似于特征标准化步骤。我们增加了 5 次幂项,你可以试着改变它,看看它对你的准确度有什么影响。结果是模型开始过度适应更高的程度,我们不希望这样。

from sklearn.preprocessing import PolynomialFeatures
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.25)
poly = PolynomialFeatures(degree = 5)
poly.fit(X_train)
X_train_pr = poly.transform(X_train)
scaler = StandardScaler()
scaler.fit(X_train_pr)
X_train_pr = scaler.transform(X_train_pr)

然后继续上面讨论的相同步骤来拟合模型。要进行预测,不要忘记首先使用 poly 转换测试集。

X_test_pr = poly.transform(X_test)
X_test_pr = scaler.transform(X_test_pr)
Y_train_pred, Y_test_pred = model.predict(X_train_pr), model.predict(X_test_pr)

然后使用上面讨论的指标评估模型。同样,每次训练模型的结果都会不同。这是我的输出-

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

改进模型的评估

相当不错的成绩!使用像逻辑回归这样的简单算法,大约 98.2%的训练集精度和大约 97.4%的测试集精度是非常好的。测试集的加权 F1 分数已提高到 0.97,并且该模型仅错误地分类了测试集中的 1 个示例。

生成预测

是时候使用模型来生成预测了。我们给它一组 4 个数字——代表一朵花的 4 个特征,它会告诉我们它认为它属于哪个物种。我们从数据集中随机选取 20 个例子,对它们进行预处理,得到预测类。

indices = np.random.randint(150, size=20)
X_pred, Y_true = X[indices], Y[indices]
X_pred_pr = poly.transform(X_pred)
X_pred_pr = scaler.transform(X_pred_pr)
Y_pred = model.predict(X_pred_pr)

注意,Y_true 表示示例的真实类,Y_pred 是预测类。它们都是整数,因为模型处理的是数字数据。我们现在将创建 2 个列表,使用我们已经创建的名为 target 的字典映射来存储每个例子中物种的真实名称和预测名称。

target_true, target_pred = [], []
for i in range(len(Y_true)):
    target_true.append(target[Y_true[i]])
    target_pred.append(target[Y_pred[i]])
print(X_pred)
print(target_true)
print(target_pred)

这是我得到的输出-

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

对 20 个随机例子的预测

由于我们模型的高精度,生成的 20 个预测全部正确!这是我们创建的最终模型的完整代码-

尝试对模型进行一些修改,看看是否可以进一步改进它,以做出更现实的预测。你可以尝试不同的模型,如 KNN 分类器,支持向量分类器,甚至是一个小型的神经网络,尽管我不喜欢用神经网络来完成这项任务,因为特征和数据集的数量都很少,机器学习模型也能很好地执行。

结论

希望这能给你一些关于如何着手建立一个简单的人工智能,或者具体地说,解决一个特定问题的机器学习模型的想法。基本上有五个阶段-

  1. 为该任务获取合适的数据集。
  2. 分析和可视化数据集,并尝试获得关于您应该使用的模型的直觉。
  3. 将数据转换成可用的形式,然后对其进行预处理。
  4. 建立模型,并对其进行评估。
  5. 检查模型的不足之处,并不断改进。

在处理构建人工智能应用程序时,需要进行大量的反复试验。即使你的第一个模型效果不好,也不要灰心。大多数情况下,通过调整它可以显著提高性能。获得正确的数据集是非常关键的,而且我觉得,当涉及到现实世界的模型时,它会改变游戏规则。该说的都说了,该做的都做了,尽可能地保持学习新东西,为了乐趣而做 AI!

编写自己的函数

原文:https://towardsdatascience.com/writing-your-own-functions-40d381bd679?source=collection_archive---------50-----------------------

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

用 Python 编写自己的函数。照片由妮可·沃尔夫Unsplash 拍摄

PYTHON 编程

数据科学家需要具有特定功能的函数

在 Python 中,你可以定义自己的函数。

先决条件

如果你不熟悉 Python,下面的文章会给你一点点 Python 的介绍。

[## Python:过程化编程还是面向对象编程?

过程化和面向对象之间有点争议,我们为什么要关心它?

towardsdatascience.com](/python-procedural-or-object-oriented-programming-42c66a008676)

您将有机会了解这些在数据科学背景下新发现的技能。

  1. 定义不带参数的函数
  2. 用单个参数定义函数
  3. 定义返回单个值和多个值的函数

为了定义一个函数,我们从关键字 def 开始,然后是函数名、一组括号和一个冒号。这段代码叫做函数。为了完成函数定义,您可以编写函数体并打印输出。

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

无参数函数。图片作者作者

如果调用函数,则执行函数体内的代码。当您像使用预构建函数一样调用函数时,这应该会返回值。如果你想在函数内部附加一个参数呢?

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

单参数函数。图片作者作者

要添加该功能,可以在括号之间的函数定义中添加一个参数。你可以看到我们将一个参数num作为变量添加到新的函数体中。该函数现在接受单个参数并打印出其值。如果我们不想直接打印该值呢?是否可以返回值并将其赋给一个变量

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

返回值而不是打印出来。图片由作者

您的函数可以通过添加return关键字,后跟要返回的值来返回新值。我们可以给一个变量赋值当函数的结果被调用时。用 Python 编写函数的另一个重要方面是文档字符串。它用来描述你的功能。

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

Docstring 放在三个引号之间。图片作者作者

这些描述是你的函数文档。任何一个阅读你的函数的人都可以理解这个函数,而不需要追溯所有的代码。函数文档字符串放在函数头后的下一行,并放在三个引号之间。

如果您想向函数传递多个参数,并返回不止一个值,而是多个值,该怎么办呢?

您可以通过让函数接受两个参数而不是一个来实现这一点。您还可以考虑更改函数名和文档字符串来反映这种新的行为。您可以通过给定两个参数来调用该函数,因为它有两个参数,如函数头中所述。

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

多参数函数。图片作者作者

参数的顺序必须与函数头参数的顺序相匹配。您也可以指定函数返回多个值。您可以通过在函数中创建称为元组的对象来实现这一点。

一个元组可以像一个列表一样包含多个值。但是,也有一些不同之处:

  • 与列表不同,元组是不可变的,一旦创建,就不能修改元组中的值
  • 虽然列表是使用方括号[]声明的,但是元组是使用一组括号()构造的

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

将元组元素分配到变量中。图片作者作者

你可以在一行中将一个元组解包成多个变量,并将其赋给变量。此外,您还可以像处理列表一样访问特定的元组元素。您可以使用零索引来访问元素。

你准备好定义自己的函数了吗?

**Other Interesting Articles**#1 [Function Arguments: Default, Keyword, and Arbitrary](/function-arguments-default-keyword-and-arbitrary-9588b5eaaef3)#2 [Scope of Variable and LEGB Rule](/scope-of-variable-and-legb-rule-4d44d4576df5)#3 [Python: Procedural or Object-Oriented Programming?](/python-procedural-or-object-oriented-programming-42c66a008676)#4 [Data Science with Python: How to Use NumPy Library](/data-science-with-python-how-to-use-numpy-library-5885aa83be6b)#5 [Do you have the Software Engineer and Data Scientist skills?](/do-you-have-the-software-engineer-and-data-scientist-skills-probably-not-7e8fb069e067)

关于作者

Wie Kiang 是一名研究员,负责收集、组织和分析意见和数据,以解决问题、探索问题和预测趋势。

他几乎在机器学习和深度学习的每个领域工作。他正在一系列领域进行实验和研究,包括卷积神经网络、自然语言处理和递归神经网络。

连接上 LinkedIn

为初学者编写自己的 Scikit-learn 类。

原文:https://towardsdatascience.com/writing-your-own-scikit-learn-classes-for-beginners-1e4e7d4de203?source=collection_archive---------20-----------------------

让你尽快入门的基础知识

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

图片来自:https://en . Wikipedia . org/wiki/File:Scikit _ learn _ logo _ small . SVG

S cikit-learn 是用于监督机器学习的最流行的 Python 库之一,它是一个非常强大的工具,同时也很简单。但我认为,它成功的原因主要不是因为它的核心功能,而是因为它的所有模块都具有很好的内聚性和一致性。这也是除了它的流行之外,为什么许多其他流行的库如 XGBoost、pyGAM、lighGBM 和 pyEarth 都是以 Scikit-learn 的风格编写的,并确保与它兼容,几乎就像它们是核心库的一部分一样。许多与 Scikit-learn 兼容的有用项目可以在这里找到。

这种内聚兼容性是 Scikit-learn 拥有自己的一套简单指南的结果,如果遵循这些指南,将确保一切正常运行。它还提供了一组基类,使得创建自己的类的过程更加容易。如果您是编写自己的类的新手,无论是为了自己使用还是为了一个库,本文都可以为您提供一个坚实的起点。

作为一个初学者,为什么要编写自己的类?

现在,您可能想知道为什么有人要编写自己的类,如果已经有这么多专业编写的类可以使用的话?你考虑一下是对的,因为如果免费提供的软件能完全满足你的需要,你就不应该再费心去写自己的了。然而,即使作为一个初学者,你也有可能在你自己独特的工作流程中遇到一些你想做的操作,但是没有什么东西可以完全按照你想要的那样去做。如果这个操作是您经常要做的,那么为它编写自己的类会很有用。

此外,如果您的操作处于一系列具有预写类的操作之间,它可能会阻止您将其添加到管道中以实现完全自动化。此外,使用 Scikit-learn 工具(如 GridSearchCV)不可能在整个过程中使用模型选择。

其他一些很好的理由是:

  • 它发展你的编程技能。
  • 它可以随着时间的推移而发展,为您自己的工作提供更多的选项和功能,也可能最终对他人有用。
  • 它使您能够为开源社区做出贡献。理解你所使用的大多数极其强大的工具之所以可以免费获得是因为这些贡献。

因此,让我们直接开始创建自己的类。

假设您想要构建一个转换器,从列中的所有值中减去列中的最小数字。例如,假设一列有数字[10,11,12,13,14,15],我们的转换器将把它改为[0,1,2,3,4,5]。这可能不是一个特别有用的变压器位,这是一个非常简单的例子,刚刚开始。

让我们创建两个玩具数据帧:

import pandas as pddf_a = pd.DataFrame({‘Number’:[11, 12, 13, 14, 15],’Color’: [‘Red’, ‘Blue’, ‘Green’, ‘Yellow’, ‘Orange’]})
df_b = pd.DataFrame({‘Number’:[21, 22, 23, 24, 25],’Color’: [‘Violet’, ‘Black’, ‘White’, ‘Brown’, ‘Pink’]})

这是它们的样子:

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

现在让我们编写转换器:

# These allow us the class to inherit Scikit-learn methods
# such as fit and transform
from sklearn.base import BaseEstimator, TransformerMixin# This function just makes sure that the object is fitted
from sklearn.utils.validation import check_is_fittedclass SubtractMin(BaseEstimator, TransformerMixin):
     def __init__(self, cols_to_operate):
         self.columns = cols_to_operate def fit(self, X, y = None):
         self.min_val_ = X[self.columns].min()
         return self

     def transform(self, X):
         # make sure that it was fitted
         check_is_fitted(self, ‘min_val_’)

         X = X.copy() # This is so we do not make changes to the            
                        original dataframe
         X[self.columns] = X[self.columns] — self.min_val_
         return X

我们从 sklearn.base 导入的类是使它工作的粘合剂。正是它们让我们的功能适合 Scikit-learn 的管道和模型选择工具。BaseEstimator 只是给了它所有 Scikit-learn 估算器都需要的 get_params 和 set_params 方法。TransformerMixin 为它提供了 fit_transform 方法。

BaseEstimator 文档可以在这里找到,TransformerMixin 文档可以在这里找到。

根据您想要构建的估计器的类型,还有其他类型的“mixin”可用,例如 ClassifierMixin 和 RegressorMixin,它们提供了对评分方法的访问。您可能知道,一般来说,数据处理器使用 fit 方法(以及 fit_transform ),模型(回归器和分类器)使用 predict 方法。因此,在创建评估器时,您需要添加适当的类作为父类。例如,一个自定义回归器需要 BaseEstimator 和 RegressorMixin,其他更复杂的类根据其功能可能需要更多。

check_is_fitted 只是一种验证方法,用于确保在尝试对对象进行某些操作之前,已经对其进行了拟合。

init 方法中,我们为它添加了转换器需要的所有初始参数。在这里,我们需要操作的只是数据帧的列名。

fit 和 transform 方法是所有 Scikit-Learn 转换器的必需方法(对于回归和分类器,它将是 fit 和 predict)。在我们的例子中,fit 方法只是找出列中的最小值并存储它。你可能注意到了,这里有一个 y = None,尽管我们在 fit 方法中没有用到 y。这是为了与 Scikit-learn 中的其他类保持一致,并确保管道中的兼容性。合体的方法也总是得回归自我。

transform 方法完成工作并返回输出。我们制作一个副本,这样原始数据帧就不会被触及,然后减去 fit 方法存储的最小值,然后返回输出。显然,这将在您自己的有用方法中更详细地说明。

让我们看看我们的变压器在工作。

sub = SubtractMin(‘Number’)
sub.fit_transform(df_a)

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

sub.transform(df_b)

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

您可能注意到的第一件事是,我们使用了 fit_transform 方法,尽管我们没有明确使用它。如前所述,这是从 TransformerMixin 基类继承的。

我们的转换器实际上从 df_a (10)中“学习”了最小值,并在调用 fit_transform 方法时从列中减去该值。然后,当调用 transform 方法时,它从 b 中减去相同的最小值。

Scikit-learn 有一套更详细的指南,需要遵循这些指南才能有所帮助,但是这些指南应该足以确保兼容性,并帮助您为自己的项目编写类。一旦你习惯了写你的课程,看看他们的指导方针(在这里)是个好主意,这样你就可以为社区做贡献了。这些指南更适合于为 Scikit-learn 或类似的库做出贡献。没有必要全部遵守,但建议遵守。有很多项目并没有按照写的那样进行。把在自己的班级里努力当作一个长期目标。

希望这能成为一个足够快的指南,帮助您开始编写自己的自定义 Scikit-learn 类。祝你好运!

编写自己的 sklearn 转换器:功能缩放、数据框架和列转换

原文:https://towardsdatascience.com/writing-your-own-sklearn-transformer-feature-scaling-dataframes-and-column-transformation-bc10cbe0bb86?source=collection_archive---------53-----------------------

编写自己的 sklearn 函数,第 2 部分

自从scikit-learn不久前给 API 增加了DataFrame支持,修改和编写你自己的变形金刚变得更加容易——并且工作流程也变得更加容易。

许多sklearns的补救措施仍然在内部使用numpy数组或返回数组,这在谈到性能时通常很有意义。性能在管道中尤其重要,因为如果一个转换器比其他转换器慢得多,它会很快引入瓶颈。当预测对时间要求很高时,这种情况尤其糟糕,例如,将模型用作实时预测的端点时。如果性能不重要或没有仔细评估,许多转换器可以调整和改进,以使用并返回DataFrames,这有一些优点:它们是数据科学工作流中非常自然的一部分,它们可以包含不同的数据类型并存储列名。

一个例子是特征标准化,如果你使用我们神经网络的线性模型,这可能是至关重要的:

import pandas as pd
import numpy as npdata = pd.DataFrame({
  'num1': [1.0, 2.0, 10.0, 1.0, 3.0, 0.0],
  'num2': [2.0, 3.0, 20.0, -3.0, 5.0, 0.5],
})data
##    num1  num2
## 0   1.0   2.0
## 1   2.0   3.0
## 2  10.0  20.0
## 3   1.0  -3.0
## 4   3.0   5.0
## 5   0.0   0.5

根据文档的说明,StandardScaler可以“通过去除平均值并缩放至单位方差来标准化特征”。在fit期间,它学习训练数据的平均值和标准偏差,这可用于在transform期间标准化特征。默认情况下,转换器将转换后的数据强制转换为一个numpy数组,因此列名被删除:

from sklearn.preprocessing import StandardScalerstandard_scaler = StandardScaler()
standard_scaler.fit(data);
standard_scaler.transform(data)
## array([[-0.54931379, -0.35307151],
##        [-0.24968808, -0.21639867],
##        [ 2.14731753,  2.10703964],
##        [-0.54931379, -1.03643571],
##        [ 0.04993762,  0.05694702],
##        [-0.84893949, -0.55808077]])

我们可以很容易地将转换器修改为返回DataFrames,要么继承现有的转换器,要么封装它:

another_standard_scaler = AnotherStandardScaler()
another_standard_scaler.fit_transform(data)##        num1      num2
## 0 -0.549314 -0.353072
## 1 -0.249688 -0.216399
## 2  2.147318  2.107040
## 3 -0.549314 -1.036436
## 4  0.049938  0.056947
## 5 -0.848939 -0.558081

我们可以进一步修改它,接受一个cols参数,只针对特定的列:

column_standard_scaler = ColumnStandardScaler(cols=['num1'])
column_standard_scaler.fit_transform(data)
##        num1  num2
## 0 -0.549314   2.0
## 1 -0.249688   3.0
## 2  2.147318  20.0
## 3 -0.549314  -3.0
## 4  0.049938   5.0
## 5 -0.848939   0.5

封装后的版本如下,我们仍然继承了BaseEstimatorTransformerMixin,因为BaseEstimator免费给了我们get_paramsset_params,而TransformerMixin提供了fit_transform。原谅这个愚蠢的名字,即AnotherColumnStandardScaler:

another_column_standard_scaler = AnotherColumnStandardScaler(cols=['num1'])
another_column_standard_scaler.fit_transform(data)
##        num1  num2
## 0 -0.549314   2.0
## 1 -0.249688   3.0
## 2  2.147318  20.0
## 3 -0.549314  -3.0
## 4  0.049938   5.0
## 5 -0.848939   0.5

如果我们想开发自己的转换器,而不是修改或封装现有的转换器,我们可以如下创建它:

custom_standard_scaler = CustomStandardScaler(cols=['num1'])
custom_standard_scaler.fit_transform(data)
##        num1  num2
## 0 -0.549314   2.0
## 1 -0.249688   3.0
## 2  2.147318  20.0
## 3 -0.549314  -3.0
## 4  0.049938   5.0
## 5 -0.848939   0.5

结果与普通 sklearn 缩放器相同:

custom_standard_scaler.transform(data)['num1'].values == standard_scaler.transform(data)[:,0]
## array([ True,  True,  True,  True,  True,  True])

除了编写我们自己的转换器,我们还可以使用sklearns ColumnTransformer将不同的转换器应用于不同的列(并通过传递passthrough保留其他的)。但是,这个函数将返回数组,因此会删除列名:

from sklearn.compose import ColumnTransformercolumn_transformer = ColumnTransformer(
    transformers=[
        ('scaler', AnotherStandardScaler(), ['num1']),
    ],
    remainder='passthrough')column_transformer.fit_transform(data)
## array([[-0.54931379,  2\.        ],
##        [-0.24968808,  3\.        ],
##        [ 2.14731753, 20\.        ],
##        [-0.54931379, -3\.        ],
##        [ 0.04993762,  5\.        ],
##        [-0.84893949,  0.5       ]])

原载于https://blog.telsemeyer.com

WSDM——KKBox 的音乐推荐挑战

原文:https://towardsdatascience.com/wsdm-kkboxs-music-recommendation-challange-bf15214c6635?source=collection_archive---------33-----------------------

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

音乐与自然!!莱奥·麦克拉伦(@leiomclaren) 在 Unsplash 上的照片

目标:

在这项任务中,我们必须预测用户在一个时间窗口内第一次可观察到的收听事件被触发后重复收听一首歌曲的机会。

概述:https://www . ka ggle . com/c/kkbox-music-recommendation-challenge/overview

大纲:

  1. 商业问题
  2. 数据讨论
  3. 电子设计自动化(Electronic Design Automation)
  4. 特征工程
  5. 数据预处理
  6. 模型
  7. 比较
  8. 结论和未来工作
  9. 参考

简介

音乐是人类意识不到自己在计数而通过计数体验到的快乐”——莱布尼茨

音乐帮助任何人与你正在做的事情联系起来。它能提升情绪,让思想的浪潮恢复活力。人们每次都喜欢听音乐,无论是通勤时间、工作时间还是专注时间。不同的人有不同的音乐风格。音乐已经为其用户提供了各种平台,如 waves of Victrola、磁带文化、随身听时代、i-pods、FM 收音机以及最新的音乐应用程序,如 Spotify、亚马逊 Prime Music、Deezer、SoundCloud、Gaana 等。

互联网在选择用户喜欢的音乐方面使生活变得容易,但仍然需要算法来向用户推荐喜欢的音乐,而不需要手动选择。

1。业务问题和限制:

我们的经营宗旨是为用户提供他们喜欢的歌曲!这一建议不需要几个小时,几秒钟就足以预测收听的机会。

  • ML 问题公式化

我们必须建立模型,通过评估用户和歌曲的给定特征来预测用户是否会重新收听歌曲。我们可以把这个问题转化为分类问题,可以应用各种分类算法。

2。资料讨论:

数据集来源:https://www . ka ggle . com/c/kkbox-music-re commendation-challenge/data

该问题有 6 个数据文件:

1.train.csv :该文件包括

user_id (msno)、song_id、source_system_tab(事件被触发的位置)、
source_type(用户首先播放音乐的入口点)、source_screen_name(用户看到的布局的名称)和 target ( 1 表示在用户第一次可观察到的收听事件之后的一个月内有重复的收听事件被触发,否则 target=0)。

2。test.csv :这个文件包括

user_id (msno)、song_id、source_system_tab(事件被触发的位置)、
source_type(用户首先播放音乐的入口点)和 source_screen_name(用户看到的布局的名称)。

3。songs.csv: 这个文件有如下特点

歌曲 id、歌曲长度、流派 id、艺术家姓名、作曲家、作词人和语言。

4。members.csv: 这个文件有 msno (user_id)、city、bd(可能包含离群值)、性别、register_via (register method)、register_init_time (date)和 expiration _ date(date)。

5。song_extra_info.csv: 该文件具有用于识别歌曲的特征宋立科 id、歌曲名称和
ISRC(国际标准录音代码)。

3。EDA:

让我们探索我们的数据,并了解每个特征的行为与情节。

一、列车特点:

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

源类型、源系统选项卡和源屏幕名称的计数图

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

我们有 source_type、source_system_tab 和 source_screen_name 的计数图。从图中我们可以看到,我们所有的特性在特性的每个值中几乎都是平衡的。

二。歌曲特色:

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

registered_via 和语言的计数图

歌曲数据中有不同类型的语言,用数字表示。我们可以看到,大多数用户更喜欢听来自’-1 ‘和’ 52 '语言的歌曲。

大多数用户更喜欢通过“4”、“7”和“9”方式注册。

三。成员数据:

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

注册开始时间和截止日期的 PDF

从上面的 pdf 我们可以说,在 2012 年之后,人们开始注册自己听音乐,因此他们的有效期也被发现接近 2020 年。

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

适合用户年龄的 PDF 和 CDF

嗯!50 岁以下的人说“你好!”听音乐并享受它!!

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

缺失值的热图

我们可以说作曲家、作词家、isrc 特征有更多缺失的价值。

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

特征树状图

这是特征的树状图。我们可以看到一个 source_system_tab -> source_type,composer ->作词人,语言-> (song_length,artist_name,name),isrc -> song_year 之间的关联。

正如我们所知,一些作曲家对某些艺术家、语言、歌词作者有偏见。

4。特征工程:

到目前为止,我们已经通过计数图和 PDF-CDF 研究了这些数据。让我们放弃那些丢失值超过 25%的特性,开始特性工程。我们还将根据特征填充缺失的值。

填充缺失值

根据维基百科, 特征工程 是利用领域知识通过数据挖掘技术从原始数据中提取特征的过程。提取的特征有助于提高机器学习算法的性能。

  • 我们将提取独立于成员、歌曲和歌曲 _extra 的个人特征。合并所有文件后,我们将提取按特征分组。
  • 我们将过滤 0 到 75 岁之间的年龄。

过滤器年龄

  • 我们将从到期和初始日期中提取成员资格 _ 天、年、月和日。

计算日期功能

  • 我们将从流派 id 和艺术家中提取流派 id 计数、艺术家计数。一些歌曲有许多艺术家和流派,所以我们还将提取第一个艺术家的名字和第一个流派 id。

计算艺术家特征

以下片段是艺术家的特点。

计算艺术家特征

  • 我们将从 isrc 特征中提取song_yearcountry_coderegistration_code

计算歌曲特征

  • 就艺术家、语言、流派和年龄组而言,每个人都有自己最喜欢的音乐风格。我们将基于这些来提取 group_by 特征。

group_by 功能

5。数据预处理:

从数据文件中提取所有特征后,是时候转换所有这些特征了。我们有数字和分类特征。有标准化、规范化、十进制等技术。我们将使用标准化,因为它通过移除平均值和缩放到单位方差来标准化特征。对于分类特征,我们有一次性编码、标签编码、响应编码等。我们将尝试对我们的分类特征进行标记编码。

转换数字特征

编码分类特征

6。型号:

正如我们先前所述,我们将把这个问题作为一个分类问题提出,我们可以在我们的数据点上应用各种分类算法。所以我们一个一个来试试。我们将在本节的最后讨论每个模型的特性重要性。在比较部分,我们将讨论结果。

1。逻辑回归

这是一种简单的分类技术,尽管它的名字中有“回归”这个词。我们将使用带有 log_loss 的SGD 分类器。我们将使用 GridSearchCV 调整超参数,如惩罚和 alpha。

使用 GridSearchCV 调整逻辑回归超参数

2。支持向量机

我们将使用带铰链损耗的SGD 分类器执行线性 SVM,并使用 GridSearchCV 进行超参数调谐。

使用 GriSeachCV 进行 SVM 超参数调谐

3。决策树

决策树是一组轴平行的超平面或决策规则,也可以对非线性可分的数据点进行分类。sklearn 提供了决策树分类器。我们将调整参数,如max_depth, min_samples_splitmax_leaf_nodes.

决策树分类器超参数调整 GridSearchCV

4。随机森林

元估计器在数据集的各种子样本上拟合多个决策树分类器,并使用平均来提高预测精度和控制过拟合。我们将使用 RandomForestClassifier 并使用randomsearchv进行超参数调整。

随机森林及其超参数调谐

5。XgBoost

XgBoost 是一个实现梯度提升决策树的库,它包含决策树作为基础学习器,并试图降低整体偏差。这里的是对 XgBoost 及其背后的深入数学的有用视频解释。

XgBoost 及其超参数调谐

6。LightGBM

LighGBM 也是一个梯度提升决策树的框架,但是它速度更快,占用内存更少。你可以从这里了解更多。

LGB 超参数调谐

7。堆叠

堆叠是一种集成技术,其中多个分类器的预测被用作训练元分类器的新特征。我们将使用堆叠分类器和决策树,RF 和 GBDT 作为一级分类器,逻辑回归作为元分类器。

堆积分类器

8。投票分类器

投票分类器是许多分类器的包装器。它将以软或硬的方式为来自基本分类器的预测投票。我们将执行来自 sklearn 的 VotingClassifier

投票分类器

9。深度学习

我们也将尝试基于深度学习的方法。我们将构建基于 MLP 的架构,该架构将所有特征作为输入,并将基于 sigmoid 概率生成适当的类别标签。我们将使用 Adam 作为优化器,使用二进制交叉熵作为损失函数。

MLP 模型与培训

(a)特征重要性:

为了更好地理解任何模型,建议检查特性的重要性。每一个特性都对模型的性能有积极或消极的影响。基于树的算法具有内置的特征重要性,而在 SVM LR 的情况下,我们必须通过model.coef_提取它

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

特征重要性

(b)特征选择和提取

特征选择意味着选择原始特征池的子集,而特征提取意味着从现有数据中获取有用的特征。我们使用选择测试进行特征选择,使用 PCA 进行特征提取。我们还可以从 DT、RF 或 XgBoost 等算法中选择基于特征重要性的特征。我们从 DT 中选择了最重要的特征,并在这些选择的特征上应用了最佳模型。这里的是型号和功能重要性的详细记录。

7。对比:

在对我们的数据集和特征重要性应用所有模型之后,我们可以说 LR 和 SVM 不太适合我们的数据集。他们还对具体特征给予更多负面的重视。基于树的算法工作得更好,具有更好的特征重要性。当我们使用 LighGBM 时,与其他模型相比,它提供了更高的性能。LightGBM 和 XgBoost 是 Kaggle 社区的热门。特征选择也推动分数。

下面是不同算法的对比表。

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

比较表

8。结论&未来工作:

  • 从上表中,我们可以看到,与其他模型相比,基于 LightGBM 的模型给出了更高的分数。在基于特征提取和选择的模型中,选择最佳模型的特征选择给出了更好的结果。
  • 由于资源限制,我只使用了 30%的数据点。如果我们使用所有数据点并进行更多的超参数调整,我们可以获得更好的结果。
  • 深度学习需要大量的数据点。
  • 我们还可以想到更多的特征提取。

9。参考文献:

  1. https://www . ka ggle . com/c/kkbox-music-recommendation-challenge/overview
  2. https://github . com/lyst do/Codes-for-WSDM 杯-Music-Rec-first-place-solution
  3. https://www . ka ggle . com/asmitavikas/feature-engineered-0-68310
  4. https://www . ka ggle . com/rohandx 1996/re commendation-system-with-83-accuracy-lgbm
  5. 【https://www.appliedaicourse.com/course/11/Applied-Machine-】
    学习-课程

感谢您的关注。如果你有任何想法,可以留下评论、反馈或任何
建议。

你可以在我的 Github repo 上找到完整的代码(这里)。

很高兴在 LinkedIn :)上与您联系

用于 DirectML 和张量流的 WSL2 / NVIDIA GPU 驱动程序

原文:https://towardsdatascience.com/wsl2-nvidia-gpu-driver-for-directml-and-tensor-flow-82996bb080b0?source=collection_archive---------29-----------------------

为 Linux 2 的 Windows 子系统配置 NVIDIA GPU

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

Unsplash 上由 Vinayak Sharma 拍摄的照片

2020 年 9 月, NVIDIA 在最新版本的预览版驱动程序中宣布了 Linux(wsl 2)Windows 子系统上的原生 CUDA 特性,这促使我写了这篇文章。

我会讲解如何在 WSL2(微软子系统 Linux) 上安装 NVIDIA 驱动,测试 TensorFlow 的并行执行。

一些主要的变化是:

  • 改善 CUDA 用户的使用体验
  • TensorFlow 支持基于 DirectX 12 的 GPU 加速
  • 对 PTX JIT 的支持将使我们能够运行并行执行(PTX )代码。

设置

在 Microsoft Windows build 20145 对公众不可用之前,要在 WSL 版本 2 上使用 GPU,您需要执行以下操作:

  1. 激活微软内部程序
  2. 检查您的 Windows Linux 子系统(WSL)版本。
  3. NVIDIA Developer 中登录或创建一个帐户
  4. 下载并安装 NVIDIA 驱动程序
  5. 测试 WSL2 对 GPU 的使用

检查您当前的 Microsoft 版本

为了激活 Microsoft Insider 计划,我们将检查所需的版本是否可用。为此,首先,转到检查更新并验证您是否有最新的更新。

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

Microsoft Windows 检查更新的图像

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

Windows Update、Microsoft Windows 的图像

下一步是转到“关于您的电脑”,验证操作系统是否符合 Windows 规范。

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

关于您的电脑的图片,Microsoft Windows

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

关于您的电脑的图片,Microsoft Windows

如果你的版本大于 **20145,**你可以跳过下一节。

1.激活 Microsoft Insider 计划

https://insider.windows.com/en-us/getting-started注册并按照步骤操作。重启后,你会得到一个新的设置选项, Windows Insider 程序设置。

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

Microsoft Windows 的搜索图像

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

Windows Update、Microsoft Windows 的图像

经过多次更新后,如果您有 20145 或更高版本的操作系统,您可以通过 WSL 使用 GPU。如果你没有最低版本,在 Windows Insider 程序设置中切换到开发频道快速环并重新运行 Windows Update。

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

Microsoft Windows 的 Windows Insider 程序设置的图像

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

Microsoft Windows 的 Windows Insider 程序设置的图像

2.检查您的 Windows Linux 子系统(WSL)版本

您需要适用于 Linux 的第二版 Windows 子系统。要检查您是否正在使用 WSL 2,请在提示符下运行以下命令

wsl --list -v

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

运行 WSL list 命令的 Ubuntu Windows 终端的图像

如果你有版本 1,可以用下面的链接更新。如果你没有安装 WSL,我推荐你阅读我的上一篇文章

下一步是更新您的 WSL 发行版。为此,打开一个提示符并执行:

sudo apt-get update && sudo apt-get upgrade

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

运行更新和升级命令的 Ubuntu Windows 终端的图像。

3.在 NVIDIA Developer 中登录或创建一个帐户

NVIDIA 开发者页面有一些不常见的登录或创建帐户的方法;进入https://developer.nvidia.com和右上角的账户,选择电子邮件登录或创建新账户。然后输入您当前的电子邮件和密码或点击创建账户并按照步骤操作。

4.下载并安装 NVIDIA 驱动程序

要下载最新版本的 NVIDIA 驱动程序,请前往https://developer.nvidia.com/cuda/wsl/download,根据您当前的硬件选择 GEFORCE 或 QUADRO。

我准备用 GeForce 和 express 安装版本460.20 _ gameready _ win 10-dch _ 64 bit _ international . exe

安装完成后,进入 GEFORCE Experience 选择设置,启用实验功能,按重启键。

5。通过 WSL2 测试 GPU 使用情况

在开始之前,我建议查看一下 NVIDIA WSL 文档。进行下一步并安装 **Miniconda。**没有的话在我的上一篇里会发现很有帮助。

您至少需要 Linux 内核版本 4.19.121。要了解您的 Linux 版本,请运行 cmd 或命令提示符并执行以下命令:

wsl cat /proc/version

您将看到与此类似的内容:

Linux version 4.19.128-microsoft-standard

接下来,更新 Miniconda,用 python 3.6 创建一个名为 DirectML 的新环境,安装 Tensor Flow / Direct ML。

conda update conda
conda update --allconda create --name directml python=3.6
conda activate directmlpip install tensorflow-directml

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

更新 conda 的 Ubuntu Windows 终端的图像

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

创建 DirectML 环境的 Ubuntu Windows 终端的图像

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

Ubuntu Windows 终端激活 DirectML 环境的图像

然后打开一个交互式 Python 并执行以下操作:

import tensorflow.compat.v1 as tf tf.enable_eager_execution(tf.ConfigProto(log_device_placement=True)) print(tf.add([1.0, 2.0], [3.0, 4.0]))

您将获得当前的硬件。

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

Ubuntu Windows 终端和 Windows 任务管理器的图像,用于测试 TensorFlow

为了仔细检查,我多次运行最后一条语句,在每次执行之间等待不同的时间,以尝试它是否会影响 GPU 的使用趋势:

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

Ubuntu Windows 终端和 Windows 任务管理器的图像,用于测试 TensorFlow

谢谢

最后,我要感谢我的兄弟迈克尔·萨维德拉,他鼓励我继续写这些话题。

有用的资源

[## WSL 上的 CUDA 预览更新了性能

最近,微软宣布了他们的 Windows 子系统 Linux ( WSL)功能的公开预览计划…

news.developer.nvidia.com](https://news.developer.nvidia.com/preview-for-cuda-on-wsl-updated-for-performance/?mkt_tok=eyJpIjoiT1RobVl6STVabVkxTmpjMiIsInQiOiJOZExCNVVIYjN4VUZKVUswVHhpUmF2SVhZMVNGaUNWelNDWE03V203OU1zbFhcL3o4dWJDdGlyM291dnRCeDhHUWFPVzM5SWJEWWJaaDlYNE9HOUhweE9xTmpXSVZDVHVWUzVlNFdyQkVQTGduRmRaZnFPOTRtRDZKVlVjUkdhdmEifQ%3D%3D) [## 用于 Linux (WSL)的 Windows 子系统中的 GPU

CUDA on Windows Subsystem for Linux(WSL)—公共预览版 Microsoft Windows 是一个无处不在的企业平台…

developer.nvidia.com](https://developer.nvidia.com/cuda/wsl) [## 在 Linux 2 的 Windows 子系统上发布 CUDA | NVIDIA 开发者博客

为了响应大众的需求,微软宣布了 Linux 2 (WSL 2)的 Windows 子系统的一个新特性——GPU…

developer.nvidia.com](https://developer.nvidia.com/blog/announcing-cuda-on-windows-subsystem-for-linux-2/) [## 微软/DirectML

DirectML 是一个高性能、硬件加速的 DirectX 12 库,用于机器学习。DirectML 提供 GPU…

github.com](https://github.com/microsoft/DirectML) [## GPU 计算、WSL 安装和 WSL 更新在 Windows 的最新内部版本中发布…

在最新的 Windows Insider 预览版中,针对 Linux 的 Windows 子系统(WSL)有三个激动人心的新更新…

devblogs.microsoft.com](https://devblogs.microsoft.com/commandline/gpu-compute-wsl-install-and-wsl-update-arrive-in-the-windows-insiders-fast-ring-for-the-windows-subsystem-for-linux/) [## 面向 Linux 的 Windows 子系统的新功能-2020 年 9 月| Windows 命令行

这篇博客文章强调了 WSL 的更新。在过去的几个月里,除了一些预览…

devblogs.microsoft.com](https://devblogs.microsoft.com/commandline/whats-new-in-the-windows-subsystem-for-linux-september-2020/)

WTH 是 R 平方和调整后的 R 平方?

原文:https://towardsdatascience.com/wth-are-r-squared-and-adjusted-r-squared-7b816eef90d9?source=collection_archive---------13-----------------------

理解 R 平方背后的数学和直觉。

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

Daria Nepriakhina 在 Unsplash 上拍摄的照片

T 今天我将从机器学习的角度来解释 R 平方和调整的 R 平方的概念。我还将向您展示如何找到 ML 模型的 R 平方值。让我们开始吧…

r 平方

它充当回归模型的评估指标。为了更好地理解它,让我引入一个回归问题。假设我正在构建一个模型,根据我在某个月的空闲时间来预测我在这个月会写多少文章。因此,这里的目标变量是文章数量,空闲时间是独立变量(也称为特性)。这是我创建的虚拟数据。

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

在这种情况下,简单的线性回归模型应该足够了。该模型的方程是…

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

模型的参数(w1b )可以通过最小化所有数据点的平方误差来找到。这也被称为最小平方损失函数。

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

在这个优化步骤之后,我们发现红线是我们的模型(最佳拟合线)。

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

现在我们想知道我们的模型有多好。这可以通过许多方式实现,但 R-squared 使用一种叫做**方差的统计方法。**方差表示数值围绕其平均值分布的程度。数学上,

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

n 是数据点的数量

R-squared 计算模型(独立变量的函数)解释了目标变量的多少方差。但是要找到它,我们需要知道两件事。 1)目标变量围绕平均值的方差(平均方差),2)目标变量围绕最佳拟合线的方差(模型方差)。

平均方差也可以被视为模型的方差,该模型输出每个输入的目标变量的平均值。我们可以把这个模型想象成一条水平线,它在所有数据点的 y 坐标的平均值处切割 y 轴。看图中的绿线。

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

忽略因子 1/n, 我们可以写…

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

模型方差的公式是…

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

现在我们可以理解 R 平方的公式了。

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

如何解读?

正如我前面提到的,R 平方值表示可以用你的模型解释的目标变量的方差的比例。解释的方差比例越多,你的模型就越好。因此,接近 1 的 R 平方值对应于好模型,接近 0 的值对应于坏模型。

假设我们模型的 R 值是 0.78。 这种说法意味着我们的模型解释了 78% 的文章数量对应的数据的方差。它接近于 1 所以我们可以说这是一个很好的模型。

R 的可能值

R = 0 当我们的模型与平均模型相同时。 R > 0 表示我们的模型比一般模型要好。R 的最大可能值等于 1 。虽然它的名字中有一个正方形,但它可能取负值。 R < 0 表示我们的模型比一般模型差。这种情况一般不会发生,因为优化步骤会产生比平均模型更好的模型。

R 平方的问题

起初,看起来一切都很好,但是随着我们添加更多的特性,R 出现了一个巨大的问题。随着新要素添加到模型中,r 平方永远不会减少。

这是一个问题,因为即使我们向我们的模型添加无用的或随机的特征,R 平方值也会增加,这表明新模型比以前的模型更好。这是错误的,因为新特征与输出变量无关,只会导致过度拟合。

为什么 R 的平方永远不能减小?

为了理解这一点,让我们为我们的模型引入一个新特性,它与我写的文章数量(输出变量)没有关系。我将一个月的平均温度作为我们的新特征。姑且称之为 x_2。 所以我们的模型就变成了……

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

在优化之后,对于 w_2 可能出现两种情况:

  1. 我们得到 w_20 。这意味着 x_2 和输出变量之间没有相关性,我们被之前的损失函数最小值卡住了。因此,我们的模型与之前的模型保持不变。所以,在这种情况下,R 值保持不变。
  2. 我们得到一个非零值 w_2 。这意味着已经找到了x2和输出变量之间的一些相关性,并且我们实现了损失函数的更好的最小值。所以,R 值增加。

几乎总是出现第二种情况,因为在随机性中很容易找到小的相关性。但是这种小的相关性过度拟合了模型。为了解决这个问题,我们使用调整的 R 平方。

调整后的 R 平方

调整后的 R-squared 背后的想法是,随着我们向模型中添加更多的特征,我们会对分数进行惩罚。我们来看看调整后的 R 平方的公式。

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

n 是数据点的数量;m 是独立特征的数量

分母 (n-m-1) 随着特征数量的增加而增加。因此,如果我们没有发现 R 的显著增加,那么整个表达式的值不会增加(甚至可能减少)。这就是为什么调整后的 R 在某种程度上抵抗了我们在普通 R 中所面临的问题。

如何求 R(使用 StatsModels)?

Statsmodels 库提供了一种执行许多统计任务的简单方法。首先,我创建了一个假数据集,并建立了一个线性回归模型。之后,我通过调用 summary() 函数打印了 R 和调整后的 R 值。下面是代码…

from pandas import DataFrame
import statsmodels.api as sm# making the fake dataset
data = { 
         'month': [12,11,10,9,8,7,6,5,4],
         'free_time': [120,110,100,90,80,85,60,50,40],
         'num_articles': [8,8,7,6,6,7,6,4,5]
       }df = DataFrame(data, columns=['month', 'free_time', 'num_articles'])# features
X = df[['free_time']] 
# target variable
Y = df['num_articles']
# adding a constant
X = sm.add_constant(X)# applying method of least squares
model = sm.OLS(Y, X).fit()
predictions = model.predict(X)print_model = model.summary()
print(print_model)

现在关注输出的选定部分。

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

还好奇?看一个我最近做的视频…

我希望你喜欢阅读。下次见…学习愉快!

WTH 是一个直方图🤷

原文:https://towardsdatascience.com/wth-is-a-histogram-dd63a70cc056?source=collection_archive---------35-----------------------

用简单的英语说…

在本期数据技能药丸中,我们将触及难以捉摸的直方图。好吧,也许这不是难以捉摸的,但这是你的团队中的一些人可能会纠结的概念之一,但当它被分解时,实际上是非常简单的。这篇文章的互动版本在这里

你的形状

直方图揭示了数据的形状。特别是,它们显示了数字在整个数据集中的分布趋势。通过观察数据集的形状,我们可以确定:

  1. 最常见的价值观是什么
  2. 值的变化有多大

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

数据来自气象,分析来自统计

MetaWeather 的这一数据列出了 2019 年伦敦每天的气温中位数。每个条形代表有多少天属于指定的 5 度温度范围。

从这里我们可以看到,伦敦的天气分布相当均匀,这是因为它以非常温和而闻名。

如果我们将其与迈阿密的相同数据进行比较,我们可以了解到更多信息:

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

来自气象的数据

首先,我们可以看到:

  1. 🥵:对我的美国朋友来说,大多数日子都是在 25-30 华氏度或 77-86 华氏度之间。
  2. 与伦敦的天气相比,迈阿密的天气非常稳定(例如,它的变化低于伦敦)。这从迈阿密的酒吧数量较少就可以明显看出,其中大多数酒吧都比伦敦的酒吧高。

这些东西中的一个与另一个不同

查看直方图,可以很容易地识别出似乎与其他点不匹配的点。这些通常被称为异常值,如果不小心处理,会严重影响您的分析和结果。

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

来自 Zillow 的数据

在本例中,我们仅使用了 Zillow 关于 2019 年美国约 700 个大都市地区房屋挂牌价格中值的数据。

每个条形代表在指定范围内有多少城市地区的房价中值。因此,2019 年,不到 200 个都会区的挂牌价格中值在 10 万美元至 15 万美元之间。

我们可以看到,美国大部分都会区的挂牌价格中值在 10 万美元到 25 万美元之间。

直方图还快速突出了异常值,尤其是一个房价中值超过 100 万美元的大都市地区😂。

如果你在意识到圣何塞和它的邻居旧金山和圣克鲁斯是如此异常之前进行分析,你的结果将会严重失真。例如:

  • 2019 年美国平均房价(包括圣何塞、旧金山和圣克鲁斯):43.75 万美元
  • 2019 年美国平均房价(不包括圣何塞、旧金山和圣克鲁斯):37.5 万美元

这超过了 60,000 美元(16%)的差距!一定要花时间检查那些异常值!

为什么它们很重要

除了前面两点,直方图还有一些好处,如:

🔮预测未来

通过理解共同的价值观和这些价值观的差异,你可以开始思考在未来会发生什么。

如果你必须猜测伦敦或迈阿密明天的气温,如果你猜对了,你会得到 100 美元,你会预测哪一个?(希望你说的是迈阿密:)

🚧提高直觉

主要的好处(IMO)是直方图是如此丰富的上下文来源。通过更深入地理解数据,你对世界的直觉会得到提高。

如果你在圣克鲁斯偶然发现一栋售价 200 美元的房子,你现在应该会有一种奇怪的感觉。你对数据有了一种直觉,如果没有丰富的研究和经验,你是不可能得到这种直觉的。

迪伊伊

如果你想自己做直方图,下面是步骤!

0.确保你的数据只是数字

抱歉,没有文本字段。您还将决定如何处理空值,是过滤掉它们,还是包含一个空值存储桶。

1.创建您的桶

挑选水桶有两种方法:

  1. 挑选一些有意义的东西:

对于温度示例,我们选择了 5 度的桶尺寸,因为这很容易理解。如果我们愿意,我们可以轻松地选择 1 度、2 度或 7.2343 度,但要获得相同的见解会困难得多。

2.选择你想要的桶数

我们也可以说我们想要 10 个桶,不管它们有多宽。为了计算出在这种情况下每个桶的宽度,我们可以使用:

bucket_size = (max_value - min_value)/number_of_buckets

做这件事没有对错之分。我建议尝试不同的桶大小,看看你的直方图如何变化!

2.将每个观察(行)分配给一个存储桶

3.绘制直方图

x 轴:铲斗升序排列

y 轴:有落入每个桶的观测值的计数。

针对工具的教程,我推荐这些给 ExcelSQL

下一步是什么?

你告诉我们!

你想看什么?我们正在为下一篇文章寻求建议。人头这里投出您的一票!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值