TowardsDataScience 2023 博客中文翻译(一百一十四)

原文:TowardsDataScience

协议:CC BY-NC-SA 4.0

使用 Pandas 数据框更有效地进行 7 种顶级列操作

原文:towardsdatascience.com/dominate-pandas-data-frames-with-the-top-7-column-operations-2a11521e9e2d

完整指南,介绍以不同方式执行 7 种顶级 Pandas 列操作

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

·发表于 Towards Data Science ·阅读时间 15 分钟·2023 年 7 月 6 日

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

图片由 Alan 提供,来源于 Pixabay

在数据分析方面,Pandas 是最常用的 Python 库,用于操控和准备数据以进行进一步的分析和机器学习。

现实是 Pandas 是一个非常灵活的库,甚至可以用来转换文件格式。

然而,即使我们几乎每天使用一些 Pandas 功能,我们仍然花费大量时间 Googling 如何在 Pandas 中做某些事情。

我知道,我抓住你了!

但说实话:一些功能很难记住,也许是因为我们可以用不同的方法达到相同的目标。所以,每天 Google 同样的内容也没有什么可羞愧的。

然而,节省时间始终是个好主意。为此,在本文中,我们将探讨操控 Pandas 列的 7 个顶级功能。这样你就不需要再去 Google 查找了:只需保存这篇文章(也许通过收藏它)并在需要时返回查看即可。

这是你会在这里找到的内容:

**Table of contents:** 
How to create a new Pandas column
How to add a new column to a Pandas data frame
How to rename a column in Pandas
How to drop a Pandas column
How to find unique values in a Pandas column
How to transform a Pandas column into a list
How to sort a Pandas data frame for a column

如何创建一个新的 Pandas 列

首先,让我们记住 Pandas 列也被称为 Pandas 系列。这意味着 Pandas 数据框是有序的 Pandas 系列集合。

有几种方法可以创建新的 Pandas 列。我们来看看它们吧。

创建一个 Pandas 列作为 Pandas 系列

创建一个被认为“独立存在”的 Pandas 列的正确方法是通过 Pandas 系列方法,如下所示:

# Create a Panad series
series = pd.Series([6, 12, 18, 24])

# Print Pandas series
print(series)

>>>

  0     6
  1    12
  2    18
  3    24
  dtype: int64

我说“正确的方法”是因为,正如我们所说,Pandas 列是 Pandas 系列。因此,如果我们只需要单列,我们应该使用这种方法,如果我们想要“正式正确”。

创建一个 Pandas 列作为 Pandas 数据框

然而,现实是我们不会经常需要一个单独的列。

所以,创建 Pandas 列的另一种方法是通过创建一个只有一列的新 Pandas 数据框:这样,我们可以在第二步中用其他列来丰富它。

我们可以这样做:

import pandas as pd

# Create a Pandas column as a Pandas data frame
df = pd.DataFrame({'A': [1, 2, 3, 4]})

# Print Pandas data frame
print(df)

>>>

     A
  0  1
  1  2
  2  3
  3  4

所以,这里与之前的例子不同的是,这次 Pandas 列也有名字。在这种情况下,我们将其命名为“A”。

**NOTE:**

If we take a look more closely to what we've done here, we can see that
we can create a Pandas data frame as a dictionary.

In fact, "A" is the key and it's separated by a list of values
by a colon. Then, both the keys and the values are inside curly braces.

从 NumPy 数组开始创建 Pandas 列作为 Pandas 数据框

Pandas 的超级能力之一是它可以“接受” NumPy 数组作为输入值。换句话说,我们可以从 NumPy 数组创建一个数据框。

对于单列的情况,我们可以创建一个一维数组并将其转换为数据框:这将得到一个只有一列的数据框。

我们可以这样做:

import numpy as np
import pandas as pd

# Create a NumPy array
values = np.array([5, 10, 15, 20])

# Transform array into Pandas data frame
df = pd.DataFrame(values)

# Print data frame
print(df)

>>>

    0
0   5
1  10
2  15
3  20

如何向 Pandas 数据框添加新列

将新列添加到 Pandas 数据框的可能性与创建新列的过程有某种程度上的关联。

我的意思是,我们首先需要创建一个 Pandas 数据框,然后是一个单独的 Pandas 列,最后需要将该列添加到数据框中。

在这种情况下,我们也有多种可能的实现方法。让我们全部查看一下。

向 Pandas 数据框添加新列:标准方法

向 Pandas 数据框添加新列的标准方法是先创建数据框,然后创建一个单独的列,最后将其添加到数据框中。

我们将在接下来的所有示例中使用这种方法。所以,我们可以这样做:

import pandas as pd

# Create a DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4]})

# Add a new column by using a list of values
df['B'] = [20, 30, 40, 50]

# Print data frame
print(df)

>>>

   A   B
0  1  20
1  2  30
2  3  40
3  4  50

那么,让我们一步一步分析我们所做的:

  1. 我们使用 pd.DataFrame() 方法创建了一个 Pandas 数据框。

  2. 我们用 df['B'] 创建了一个新列,这意味着我们将这个新列命名为“B”。

  3. 我们已经将值分配给新创建的列,使用了一个数字列表。

那么,创建新列的另一种方法是什么?如果我们已经有一个数据框,可以使用数字列表

向 Pandas 数据框添加新列:应用函数

将新列添加到现有数据框的标准方法使我们能够创建一个新列并将其添加到现有数据框中,所有这些都在一行代码中完成。

例如,假设我们想创建两个新列作为现有列的组合。我们可以通过将函数应用于现有列来做到这一点,如下所示:

import pandas as pd

# Create a DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4]})

# Create a column doubling the values of column A
df['B'] = df['A'] * 2

# Apply lambda function to column A to create column C
df['C'] = df['A'].apply(lambda x: x ** 2)

# Print data frame
print(df)

>>>

   A  B   C
0  1  2   1
1  2  4   4
2  3  6   9
3  4  8  16

所以,这里是我们所做的:

  1. 我们已经创建了一个 Pandas 列(“A”)作为一个数据框。

  2. 我们通过将列“A”的值翻倍来创建了列“B”。

  3. 我们通过将 lambda 函数应用于列“A”创建了列“C”。具体来说,在这种情况下,我们是在对列“A”的值进行平方运算。

所有这些列都一起存储在一个唯一的数据框中。

向 Pandas 数据框添加新列:使用 Pandas 系列或单个 Pandas 列

当然,我们可以向 Pandas 数据框中添加列,即使这些列是 Pandas 系列或 Pandas 数据框。

下面是我们可以做到的:

import pandas as pd

# Create a DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4]})

# Create a new column using pd.Series()
values = pd.Series([5, 10, 15, 20]) # Create series
df['B'] = values # Add series to data frame as a column

# Print data frame
print(df)

>>>

   A   B
0  1   5
1  2  10
2  3  15
3  4  20

所以,在上面的例子中,我们创建了一个 Pandas 系列,然后通过给它命名将其添加到现有的数据框中。

在作为 Pandas 数据框创建的 Pandas 列的情况下,我们有:

import pandas as pd

# Create a DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [5, 6, 7, 8]})

# Create a Pandas column as a data frame
df['C'] = pd.DataFrame({'C': [9, 10, 11, 12]})

# Print data frame
print(df)

>>>

   A  B   C
0  1  5   9
1  2  6  10
2  3  7  11
3  4  8  12

就这样。

**NOTE**:

of course, the same methodology can be applied if we create a column
as a NumPy array. We won't show the method here as "the game" should
now be clear.

如何重命名 Pandas 列

重命名 Pandas 列(或多个列)是我们需要执行的另一个典型的日常任务,但我们常常记不住。

同样,在这种情况下,我们有不同的方法来做到这一点。让我们看看它们。

如何重命名 Pandas 列:rename()方法

我们可以使用rename()方法来重命名 Pandas 列,如下所示:

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})

# Renaming a single column
df = df.rename(columns={'A': 'NewA'})

# Print data frame
print(df)

>>>
     NewA  B
0     1    4
1     2    5
2     3    6 

所以,这就像我们在使用字典。在rename()方法中,实际上,我们需要传递参数columns,并在大括号中指定实际名称和新名称,用冒号分隔它们。就像我们在字典中做的那样。

当然,我们可以使用这种方法重命名多个列,如下所示:

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})

# Rename multiple columns
df = df.rename(columns={'A': 'NewA', 'B': 'NewB'})

# Print data frame
print(df)

>>>

    NewA  NewB
0     1     4
1     2     5
2     3     6

再次,这就像我们在使用字典一样。

如何重命名 Pandas 列:column属性

要重命名一个 Pandas 列(或多个列,如我们将看到的),我们可以使用columns属性,如下所示:

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})

# Renaming all columns
df.columns = ['NewA', 'NewB']

# Print data frame
print(df)

>>>

    NewA  NewB
0     1     4
1     2     5
2     3     6

所以,在这种情况下,columns属性让我们可以使用字符串列表来重命名列。

如何重命名 Pandas 列:set_axis()方法

要重命名一个(或多个)Pandas 列,我们可以使用set_axis()方法,如下所示:

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})

# Renaming all columns
df.set_axis(['NewA', 'NewB'], axis=1, inplace=True)

# Print data frame
print(df)

>>>

     NewA  NewB
0     1     4
1     2     5
2     3     6

所以,即使在这种情况下,我们也使用字符串列表来重命名列,但这里我们还需要传递参数axis=1inplace=True,因为set_axis()方法是从零开始设置轴,因此它会重新创建它们。这使得这个方法可以重命名列。

如何重命名 Pandas 列:使用 lambda 函数

当我们处理字符串(如 Pandas 列名称的情况)时,我们可以使用 lambda 函数来修改文本中的字符。

例如,我们可能希望(或需要)通过简单地将字母转为小写来重命名列。我们可以这样做:

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'COLUMN_1': [1, 2, 3], 'COLUMN_2': [4, 5, 6]})

# Renaming columns using a lambda function
df = df.rename(columns=lambda x: x.lower())  # Lowercase column names

# Print data frame
print(df)

>>>

      column_1  column_2
0         1         4
1         2         5
2         3         6

就这样。

如何删除 Pandas 列

删除 Pandas 列(或多个列)是我们经常需要执行的另一个任务。也许是因为它的值不重要,也许是因为它的值都是NULL或其他原因。

要执行这个任务,我们有两种方法。让我们看看它们。

如何删除 Pandas 列:使用 drop()方法

删除 Pandas 列(或多个列)的典型方法是使用drop()方法。

在这里,唯一需要记住的是决定是否要删除某些列并创建一个新的数据框,或者是否要删除这些列并替换当前的数据框。

让我展示一下区别:

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]})

# Drop one column and substitute the current data frame
df = df.drop('A', axis=1)

# Print updated data frame
print(df)

>>>

   B  C
0  4  7
1  5  8
2  6  9

所以,我们使用 drop() 方法删除了“ A”列,指定了要删除的列的名称和轴(axis=1 在 Pandas 中表示垂直方向,必须指定)。

在这种情况下,我们决定替换数据框 df。因此,在过程结束时,数据框 df 中没有“ A”列。

相反,如果我们想创建另一个数据框,假设我们称之为 df_2,我们必须这样做:

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9],
      'D': [10, 11, 12]})

# Drop one column and substitute the current data frame
df_2 = df.drop(['A', 'D'], axis=1)

# Print new data frame
print(df_2)

>>>

   B  C
0  4  7
1  5  8
2  6  9

所以,在这种情况下,我们删除了两列,并创建了一个新的数据框,仅包含“B”和“C”列。

如果我们认为未来可能需要原始数据框 df 以进行进一步分析,这可能会很有用。

如何删除 Pandas 列:使用列索引

在 Pandas 中,列可以通过索引单独提取。这意味着我们可以像这样使用索引删除它们:

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9],
      'D': [10, 11, 12]})

# Drop one column and append to a new data frame
df_2 = df.drop(df.columns[[0, 1]], axis=1)

# Print new data frame
print(df_2)

>>>

   C    D
0  7   10
1  8   11
2  9   12

所以,在这种情况下,我们创建了一个新的数据框,仅包含“ C”和“ D”列,并通过使用它们的索引删除了“ A”和“ B”列。

记住在 Python 中我们从 0 开始计数(所以,第一列的索引是 0,列为“ A”),我们必须说明,如果我们有数十列,这种方法可能不是最优的,原因很简单:我们应该通过计数找到要删除的那一列(或那些列),这容易出错。

如何在 Pandas 列中查找唯一值

在 Pandas 列中查找唯一值是我们可能需要每天执行的另一项任务,因为重复值必须以特定方式处理。

在这种情况下,我们有几种方法可以做到这一点:一种是显示一列中的重复项,另一种是删除它们。

让我们看看这两种方法。

如何在 Pandas 列中查找唯一值:使用 value_counts() 方法查找重复项

如果我们想查看 Pandas 列是否有重复值,并且我们还想知道它们有多少个,可以像这样使用 value_counts()

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 1, 3], 'B': [4, 5, 6, 7, 8,],
    'C': [7, 8, 9, 10, 11]})

# Find unique values in a Pandas column
unique_values = df['A'].value_counts()

# Print unique values
print(unique_values)

>>>

1    2
3    2
2    1
Name: A, dtype: int64

所以,这里的结果告诉我们:

  1. 列的名称是“ A”,所有类型都是“ int64”。

  2. 我们有两个 1。

  3. 我们有两个 3。

  4. 我们有一个 2。

所以,它向我们展示了这些值,并告诉我们它们在我们关注的列中出现了多少次。

如何在 Pandas 列中查找唯一值:使用 drop_duplicates() 方法删除重复项

如果我们想删除 Pandas 列中的重复值(因为我们知道其中有重复项),可以像这样使用 drop_duplicates() 方法:

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 1, 3], 'B': [4, 5, 6, 7, 8,],
       'C': [7, 8, 9, 10, 11]})

# Drop the duplicate values in a Pandas column
unique_values = df['A'].drop_duplicates()

# Print unique values
print(unique_values)

>>>

0    1
1    2
2    3

所以,我们从“ A”列中删除了重复项,创建了一个名为 unique_values 的新 Pandas 列。

如何在 Pandas 列中查找唯一值:研究数据框

在这一点上,你可能会问:“ 那么,如果我有一个包含数十列的大数据框,我如何知道哪些列确实有重复项?”

好问题!我们可以做的是首先研究整个数据框。

例如,我们可能想查看是否有任何列有重复项。我们可以这样做:

import pandas as pd

# Creating a DataFrame with duplicates
df = pd.DataFrame({'A': [1, 2, 2, 3, 4, 4], 'B': [5, 6, 6, 7, 8, 8]})

# Check if there are duplicates in the DataFrame
has_duplicates = df.duplicated().any()

# Print the result
print(has_duplicates)

>>>

True

所以,这段代码会返回“True”如果存在重复列,返回“False”如果不存在。

那如果我们想知道哪些列实际上有重复项呢?我们可以像这样做:

import pandas as pd

# Creating a DataFrame with duplicates
df = pd.DataFrame({'A': [1, 2, 2, 3, 4, 4], 'B': [5, 6, 6, 7, 8, 8]})

# Find duplicate rows
duplicate_rows = df.duplicated()

# Print the duplicate rows
print(df[duplicate_rows])

>>>

   A  B
2  2  6
5  4  8

所以,上面的代码显示了:

  • 包含重复项的列。

  • 重复项的值。

现在我们可以进一步调查 value_counts() 方法或使用 drop_duplicates() 方法删除重复项。

如何将 Pandas 列转换为列表

将 Pandas 列转换为列表是一个有用的特性,它可以让我们“隔离”所有来自 Pandas 列的值,将其放入列表中。然后,我们可以对列表进行任何需要的操作,因为列表很容易管理(如迭代等)。

我们有两种方法可以进行这个转换。

如何将 Pandas 列转换为列表:使用 list() 方法

list() 方法是一个内置的 Python 函数,用于将可迭代对象转换为列表。我们可以像这样使用它:

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 1, 3], 'B': [4, 5, 6, 7, 8,],
    'C': [7, 8, 9, 10, 11]})

# Transform Pandas column into a list
column_list = list(df['B'])

# Print list
print(column_list)

>>>

[4, 5, 6, 7, 8]

所以,我们已经轻松地提取了我们的值并将其放入列表中。

如何将 Pandas 列转换为列表:使用 to_list() 方法

要实现相同的结果,我们可以使用 Pandas 的 to_list() 方法。但请注意:它在 Pandas 版本 1.2.0 或更高版本中可用

我们可以像这样使用它:

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [1, 2, 3, 1, 3], 'B': [4, 5, 6, 7, 8,],
      'C': [7, 8, 9, 10, 11]})

# Transform Pandas column into a list
column_list = df['B'].to_list()

# Print list
print(column_list)

>>>

[4, 5, 6, 7, 8]

当然,我们得到了与之前相同的结果。

如何按列对 Pandas 数据框进行排序

有很多情况需要对列进行排序。排序意味着排序,因此我们可以选择按升序或降序排列数据。

我们可以通过以下方法实现这个目标。

如何按列对 Pandas 数据框进行排序:使用 sort_values() 方法

要按列对 Pandas 数据框进行排序,我们可以像这样使用 sort_values()

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [10, 2, 7, 1, 15], 'B': [4, 2, 6, 28, 8,],
    'C': [7, 1, 9, 10, 19]})

# Sort df for A in ascending order
df.sort_values('A', ascending=True, inplace=True)

# Print sorted data frame
print(df)

>>>

    A   B   C
3   1  28  10
1   2   2   1
2   7   6   9
0  10   4   7
4  15   8  19

所以,我们可以看到,数据框已按列“A”升序排序。实际上,如果我们检查:

  • 在初始数据框中,列“A”中的数字 1 位于第 4 个位置。在列“B”中,数字 28 位于第四个位置。

  • 在排序后的数据框中,列“A”中的数字 1 位于第一个位置。在列“B”中,数字 28 位于第一个位置。

因此,我们对数据框进行排序,但不会丢失列值之间的关系。

这个方法的一个非常有用的特性是它可以通过将 NaNs 作为第一个值来排序列。我们可以像这样做:

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [10, 0, 0, 1, 15], 'B': [4, 2, 6, 28, 8,],
    'C': [7, 1, 15, 10, 19]})

# Sort NaNs in the beginning
df.sort_values('A', ascending=True, inplace=True)

# Print sorted data frame
print(df)

>>>

    A   B   C
1   0   2   1
2   0   6  15
3   1  28  10
0  10   4   7
4  15   8  19

我们到了这里。

如何按列对 Pandas 数据框进行排序:使用 sort_index() 方法

我们还可以按如下方式对数据框进行排序,以根据索引值排序:

import pandas as pd

# Creating a DataFrame
df = pd.DataFrame({'A': [10, 2, 7, 1, 15], 'B': [4, 2, 6, 28, 8,],
    'C': [7, 1, 9, 10, 19]})

# Sort data frame for index
df.sort_index(inplace=True)

# Print sorted data frame
print(df)

>>>

    A   B   C
0  10   4   7
1   2   2   1
2   7   6   9
3   1  28  10
4  15   8  19

正如我们所见,索引是有序的(按升序排列)。

结论

在这篇文章中,我们已经看到了在 Pandas 列上执行的 7 种主要操作,这些操作我们几乎每天都会执行。

如果你保存这份指南,它将帮助你节省很多时间,因为我们已经以不同的方式执行了相同的任务,这样你就不需要再谷歌搜索它们了,节省了很多时间。

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

费德里科·特罗塔

你好,我是费德里科·特罗塔,我是一名自由职业技术作家。

想与我合作吗? 联系我

在申请科技公司之前,先掌握这 6 项必备的数据科学技能

原文:towardsdatascience.com/dont-apply-to-tech-without-mastering-these-6-must-have-data-science-skills-a-spotify-data-8b1b7b8cc0ba

进入科技的魔法世界

一窥科技的魔法世界以及你需要做的准备才能成功成为数据巫师

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

·发表在数据科学之路 ·阅读时间 20 分钟·2023 年 10 月 27 日

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

图片由Tuyen Vo提供,Unsplash

你是否一直在等待霍格沃茨的录取通知书?你的猫头鹰总是丢失在邮件中,你担心它可能永远不会到来?

如果你是一名渴望进入科技领域的 数据科学家,别再等待了。这里有一封信会让你像骑上扫帚一样飞向你梦想的公司。

我看到很多人今天自称为数据巫师。老实说,如果有比成为科学家更酷的事情,那一定是成为巫师。而在数据的世界里,如果有一个属于我们这些人的魔法世界,那无疑就是科技的魔法世界。

一旦你进入,你就获得了一剂成功与乐趣的神奇药水。

为什么?

  • 科技公司总是在人工智能竞赛的前沿 在这个领域,大多数数据科学家在研发中处于产品的核心。这意味着一旦你进入,你就处于与尖端技术合作的最佳位置,并成为所有与人工智能相关事物的积极参与者。

  • 没有比科技行业更好的地方了,在这里你可以找到无尽的高质量数据来挥舞你的魔杖 拥有丰富高质量数据的机会和可能性是无价的福利。你将不断地对数据进行实验,这将确保你始终保持竞争力。

不过,有一个问题,并不是每个人都有资格收到他们的魔法接受信。没有正确的魔法咒语,您可能会永远等待。

这就是我出现的地方。我在这里为您提供所需的内部地图。把它当作是 马拉 uders 地图,我将在上面揭示所有隐藏的秘密通道,带您到达您想去的地方!

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

Klim Musalimov拍摄的照片,来源于Unsplash

在这本“魔法书”——呃,文章中,我将与您分享将您转变为数据巫师的顶级技能,并帮助您找到在科技神秘领域中的位置(由一位科技女巫亲自撰写 ;)。

万圣节季节🎃,让我们将神秘感带入数据世界,揭开其中的魔法,好吗?

小小免责声明!

我将在下面分享的所有技能都是您在科技领域作为数据科学家所需的最重要的技能。

然而,由于“数据科学家”这个词在不同公司中可能意味着不同的事情,我实际上是在谈论我自己在 Spotify 的那种数据科学家。也适用于 FAANG 公司以及其他类似公司中的专家。

基本上,利用数据生成洞察和价值以推动决策的人。了解如何实现机器学习是必要的,但并不总是在实践中应用,除非需要。

基本上,倾向于决策科学的数据科学家

本文适用于任何即将进入数据科学职业的人,无论您是学生、应届毕业生,还是已经在担任数据科学家的工作。

我在 Spotify 每天都使用这些技能。

自从 2.5 年前作为实习生加入 Spotify 以来,我一直在挥舞我的魔杖。我很幸运在没有掌握以下列出的技能的情况下进入公司。但我能逃脱的主要原因是因为我当时还是一名学生。

作为早期职业者,您可以逃避许多事情,但一旦开始积累经验,游戏规则也会开始变化。

除非您是作为实习生加入,否则进入科技领域(或其他任何工作)的障碍会迅速堆积在您面前。好消息是:您仍然可以进入这个圈子。

您只需聪明地玩转这场游戏,首先要确保手中掌握了正确的卡片,并在简历上出色地展示。这包括:

  1. 掌握数据提取、准备与探索的炼金术

  2. 用数据可视化编织迷人故事

  3. 破解统计学的预测魔法

  4. 通过 A/B 测试发现占卜的艺术

  5. 学习 KPI 背后的数字魔法

  6. 锻造您的巫师宝典

好吧,我知道这可能听起来有点神秘,但直接给你答案的乐趣在哪里呢 😈

#1. 掌握数据提取、准备和探索的炼金术

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

图像作者(DALL.E)

无论是分析 A/B 测试还是进行基础研究,过程总是从提取数据并将其转化为所需的形式开始。

我不是变形者,但我学会了在数据上施展技巧(或者至少我一直在尝试)。这通常从调用 SQL 的神奇功能来提取数据并将其转换为最终形态开始。然后,我们将数据集转移到 Python 中,以获得更深入的见解。

课程 #1 — 掌握数据汇总和处理复杂查询的艺术

你可能认为你已经知道这些,但相信我,事情可能很快变得混乱。让我解释一下原因。

当我提到 SQL 时,我不是指基本的 SELECT 和 GROUP BY。在这个层面上,你需要调用更多的高级查询函数,例如窗口函数、日期时间数据、数组/结构操作等。

在我当前的一个项目中,我正在进行 A/B 测试分析,我们通过 4 个指标(+1 个防护指标以确保我们在过程中没有搞砸任何事情)来衡量成功 → 这意味着每次提取一个单一指标时,都需要编写 5 个复杂的查询,每个查询 40-50 行。

挑战?在复杂的查询网络中确保准确性。一旦你开始处理交织的查询,任何事情都可能出错。

课程 #2 — 掌握使用统计学进行探索性数据分析的技能

如果到这个阶段你已经磨练了从头创建准确数据集的技能,那么你已经通过了第一关。接下来是确保你使用统计技术和可视化工具(如直方图、散点图或箱形图)来理解数据。

再次强调,如果你不保持对数据数学含义的开放思维,事情可能很容易变得复杂。

在我之前提到的实验中,某个成功指标存在一些极端的异常值,这些值扭曲了指标结果。我不得不在用户级别上汇总数据,以捕捉这种偏差,然后正确地修复它。这时统计知识就派上用场了。

发现我的数据遵循泊松分布后,我能够通过一个简单的技巧来修正问题,即将异常值替换为比均值高 3 个标准差的限制值。这是我使用的查询:

WITH statistics AS (
  SELECT
    CEIL(average_value + (std_dev*3)) AS upper_limit
  FROM (
    SELECT
      AVG(metric) AS average_value,
      STDDEV_SAMP(metric) AS std_dev
    FROM data
  )
)

SELECT
  id,
  IF(metric > s.upper_limit, s.upper_limit, metric) AS metric_count
FROM data us
CROSS JOIN statistics s
ORDER BY 2 DESC

如果这是一个正态分布,我会采用不同的方法,因为曲线的形状不同。具体来说,这种方法是:

SELECT * 
FROM data 
WHERE metric_count <= 
(SELECT 
  DISTINCT PERCENTILE_DISC(metric_count, 0.997) OVER() AS percentile_99th -- 3 standard deviation above the mean to remove outliers
  FROM data)
ORDER BY 2 DESC

现在你明白为什么了解数据中的分布、趋势和潜在异常是如此重要了。就像我做的那样,有时你也需要通过在用户级别或其他维度上汇总数据来进一步挖掘。

你如何培养这些技能?

首先,动手使用 SQL 的高级函数进行复杂查询。学习如何检查查询的质量。

我恰好正在制作终极备忘单,帮助你学习数据科学家在科技领域最常用的高级 SQL 函数。

注册我的通讯后,你就能获取到!你可以在下面的链接中找到,

[## K 的 DataLadder | Khouloud El Alami | Substack

一名 Spotify 数据科学家在科技领域的日常——起伏、学习和所有介于之间的事。点击阅读……

levelupwithk.substack.com

复习统计概念与概率理论,并巩固基础:

  • 描述性统计 确保你掌握数据的属性,如均值、中位数、方差和标准差,还包括异常值、四分位数等。

  • 分布理论 使你熟悉不同的概率分布,如正态分布、二项分布和泊松分布(及其形状)。这将帮助你对数据做出正确的假设,并相应处理数据。

我仍然不时复习这些概念。即便是经验丰富的数据魔法师也常常需要刷新。毕竟,没有人能免于记忆法的失误。

#2. 用数据可视化编织迷人的故事

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

作者制作的图片 (DALL.E)

如果你还没意识到,所有优秀的数据科学家都仅仅依赖于他们的讲故事技巧。这在科技领域尤其如此。

讲故事就像是每个数据科学家必须精准掌握的魔法棒。即使是专家数据科学家也需不断磨练他们的叙事技能。

实际上,我将很快与其他 Spotify 数据科学家一起参加一个工作坊,学习如何制作有影响力的图表和数据可视化。科技公司非常重视这项技能——这完全有理由。

即使是你最突破性的发现,如果无法传达信息也会毫无用处。有效的沟通是关键,而它始于我们如何框定见解。

第 3 课——磨练你设计引人注目的视觉效果的能力,吸引你的同行高手。

第一个问题是什么? 你的数据想讲述什么故事?

想要可视化一个关系?

  • 散点图: 这些是你绘制两个变量之间关系的首选工具。

  • 气泡图: 需要包含两个以上的变量?气泡图能帮你搞定。

  • 困扰图: 适合可视化不同组元素之间那些讨厌的重叠部分。

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

作者使用 Chartify 库制作

如何展示一个比较?

  • 时间序列数据: 折线图或纵向条形图是最佳选择。

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

作者使用 Chartify 库制作

  • 静态数据: 深入了解条形图,无论是垂直的还是水平的。漏斗图对于多个变量也很有效。

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

由作者使用 Chartify 库制作

需要检查分布吗?

  • 直方图和折线图: 非常适合单变量洞察。

  • 散点图: 它们非常适合显示两个变量的联合分布。

想要突出比例吗?

  • 时间序列数据: 堆叠区域图,无论你使用绝对数字还是选择 100%基准。

  • 静态数据: 堆叠条形图(100%基准)和百分位图是你的好帮手。

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

由作者使用 Chartify 库制作

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

由作者使用 Chartify 库制作

想要深入了解如何将你的讲故事技能提升到一个新水平?那就一定要看看我写的这篇文章,它将帮助你实现这一目标!

## Step-by-Step Guide: The Art of Winning Stakeholders as a Data Scientist to Drive Impact

来自 Spotify 的数据科学家——将你的工作转化为行动的终极组合

towardsdatascience.com

课程#4——尝试使用仪表板工具提升简历

单独的可视化图表可以非常强大,而当它们组合在一起时则更具威力。

在科技领域,数据科学家通常构建仪表板以展示和跟踪关键指标。

在过去的几个月里,我花了大量时间从零开始设计和构建 Tableau 仪表板。我不是唯一一个,我的整个团队也投入了同样的精力来构建类似范围的仪表板。

为什么这么忙碌?因为数据科学家的真正魔力在于从研究中创造商业价值。由于我们不断支持跨职能的工程师、设计师、产品经理等团队,我们的时间变得更加宝贵。

我们不能被临时问题分散注意力。相反,精心制作的仪表板使利益相关者能够获取他们需要的数据,让我们可以专注于我们的强项——研究!

了解 Tableau 或 Power BI 等工具的基础知识,可以为你的科技职位简历增添一些额外的魔力!

我认为这不是必需的,因为你可以在工作中学习这项技能,但如果你渴望进入迷人的科技世界,可以考虑增加另一项技能。

我将在即将发布的文章中教你如何制作类似的图表。不要错过——点击订阅按钮!

#3. 解密统计学的预测魔法

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

图片由作者提供(DALL.E)

我们经常喜欢通过进行 A/B 测试来测试我们特性发布或更新的影响。当这种方法不可行时,我们转向其他估计发布因果效应的方法,如因果推断。

有时我们可能需要深入技术方法来对用户群体进行聚类或进行特征重要性分析,以理解用户行为 (就像我在下面的文章中做的那样)

特征重要性分析与 SHAP:我在 Spotify 学到的(在复仇者的帮助下)

识别顶级特征并了解它们如何影响机器学习模型的预测结果,使用 SHAP

特征重要性分析与 SHAP:我在 Spotify 学到的

再次强调,掌握更高级的统计概念、建模和机器学习技术是基础。但你可能已经知道这一点。

第 5 课——深化你在分析、建模和预测方面的统计掌握

你不需要深入研究机器学习,比如沉浸于深度学习。实际上,我记不起上一次在日常工作中应用这些复杂性的情况。

然而,这并不意味着你所有的统计知识都会被遗忘。可以说,它被重新用于更实际的应用。此外,还有比深度学习更复杂的内容。

进行因果推断分析可能会很有挑战,具体取决于使用场景,但结果通常更直接且不那么抽象,相比于你可能在深度学习的研究中找到的内容。

所以答案是肯定的,你需要了解统计和概率。你可能不会做很多机器学习的操作,但我发现能够探索统计的力量比机器学习更有趣。这是相当被低估的。

#4. 发现 A/B 测试的艺术 创新

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

作者提供的图像 (DALL.E)

想象一下像 Spotify、Apple、Google 等公司。它们有什么共同点——我不是说它们都是科技公司?

这是创新。这些公司不断大量投资于新奇的事物。这就是它们保持竞争力的方式。研发是科技的核心。它从创建一个新特性并进行测试开始。

在这个过程中,数据科学家扮演着关键角色。我们进行研究,推动新特性的出现。然后,我们进行测试,以判断这个新特性是否值得发布给整个客户群。

怎么做?我们设计实验,也称为 A/B 测试来验证我们的假设。当你看到一个新特性被发布时,是因为它经过了实验的检验。

作为数据科学家,我们参与实验的创建,选择指标并分析结果。

我们确保实验在统计上是正确的,结果是可以解释的。这样,我们最大限度地提高了基于数据的决策的可能性。

第 6 课 — 熟悉 A/B 测试的基础知识

不得不说,这一切又都涉及统计学。它们无处不在,我们似乎无法摆脱它们。

进行实验完全依赖于假设检验的统计概念。因此,确保你彻底了解这一点。

我在加入 Spotify 之前从未做过 A/B 测试。我尝试学习这个,但坦白说,当你没有直接在公司内部做这个事时,很难做到。如果你目前的工作中没有机会学习 A/B 测试,那么这里有一个简单的逐步指南,帮助你掌握这些概念:

1. 假设检验

  • 这是什么? 确定数据中是否有足够的证据推断某个条件对整个总体而不仅仅是我们测试的样本成立的过程。

  • 为什么重要? 这是 A/B 测试的核心;你在测试改变(B)是否比现状(A)更好。

  • 如何学习? 参考基础统计学教材或在线课程,重点关注推断统计学。

2. 检验统计量

  • 这是什么? 一个标准化的值,帮助决定是否拒绝原假设(现状)。它们帮助你评估你在对照组(A)和处理组(B)之间观察到的差异是否具有统计学意义,还是可能由于随机偶然因素产生的。

  • 为什么重要? 这个值会告诉你测试中观察到的效应是否可能是由于偶然因素还是你所做的改变。

  • 如何学习? 与假设检验一起学习。像可汗学院或 Coursera 这样的在线平台提供了很好的模块来覆盖这一点。

这是主要检验统计量及其使用时机的详细说明:

  1. Z 检验 → 当样本量较大且总体方差已知时使用。

  2. 学生 t 检验 → 当样本量较小且总体方差未知时使用。

  3. 卡方检验 → 用于分类/二元结果的测试,以检查观察到的频率与预期频率的差异。

  4. F 统计量 → 用于在 A/B/C…测试中比较多个组之间的方差。

检验统计量是根据样本数据计算的,我们利用它来确定 p 值。

什么是 p 值? 在假设原假设为真的情况下,观察到的检验统计量与样本中计算出的检验统计量一样极端或更极端的概率。

3. 样本量计算

  • 这是什么? 基本上,是你需要多少观察才能检测到对照组和处理组之间的显著差异。你不能在整个客户群体(总体)上测试你的新特性,万一出现问题怎么办?我们不想在总体中搞乱事情,因此我们使用样本。

  • 这有何意义? 观察数量过少可能会错过真实效果;观察数量过多可能浪费资源(或影响体验)。

  • 如何学习这个? 使用在线计算器来获取感觉,然后通过在线课程或统计学教材深入学习数学。

4. 基础曝光与自定义曝光

  • 这是什么? 基础曝光是指默认百分比的用户会接触到某个变体,而自定义曝光则允许进行特定的定向。例如,我们可能只希望那些在 Spotify 上播放过歌曲的用户,而不仅仅是打开过播放列表的用户。

  • 这有何意义? 确保你在测试正确的人群,并且不会偏倚你的结果。

  • 如何了解更多? 阅读来自主要科技公司的案例研究或 A/B 测试最佳实践,以了解不同的策略。

5. 最小可检测效果(MDE)

  • 这是什么? 你希望你的测试能够检测到的最小效果大小。

  • 这为什么重要? 有助于样本大小计算,并为“成功”测试设定明确的基准。

  • 如何了解更多? 关于 A/B 测试的文章和案例研究通常会讨论这一点。一些 A/B 测试工具内置了计算器。

6. 新颖效应与首因效应

  • 这是什么? 用户可能对新事物(新颖性)有积极反应,或者更容易记住他们首次看到的东西(首因效应),这可能会影响结果。

  • 这为什么重要? 确保你没有将短期的兴奋误认为是实际的偏好。

  • 如何了解更多? 行为心理学资源可以提供见解,A/B 测试文献也可以深入探讨这些偏差。

你还可以生成模拟数据并进行 A/B 测试,以获取对过程的感觉。

在我即将发布的文章中,我会更深入地探讨 A/B 测试,因为我目前在 Spotify 学到了很多关于这一点的知识。如果你想了解更多,请继续关注!

最后一句话——记住我们正在涉足统计学的领域。绝对的确定性是一种幻觉。然而,优秀的数据科学家努力遵循实验最佳实践,以避免因假阳性或假阴性导致的误导性结论。

#5. 了解 KPI 背后的数字魔法

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

图片由作者提供(DALL.E)

自从我加入公司以来,我听到的最多的就是指标讨论。这对我来说总是感觉相当模糊,就像“数字魔法”这个词一样。起初,由于复杂性,我并不总是参与定义指标的过程,但现在我参与了。

将业务目标转化为可衡量的 KPI 是至关重要的。这通常是数据科学家的职责之一,将业务目标正确地转化为可操作的指标。

指标框架成为许多利益相关者的参考点,特别是当我们想要衡量成功并跟踪进展时。

课程 #7 — 学习指标背后的哲学

让我们以 A/B 测试为例进行讨论。

如果你不知道如何正确定义你的指标,你的实验将毫无价值。如果你没有选择合适的指标来捕捉你试图衡量的变化,你可能会:

  1. 因为你可能选择了不够敏感的错误指标而错过了变化

  2. 对你试图衡量的任何漏洞修复或功能发布的真实效果得出错误结论

  3. 制定错误建议可能会带来更大的后果

定义指标并不像看起来那么简单。我们在我参与的上一个实验中花了几周时间讨论指标,以找到衡量成功的最佳方法。

因为我们花了很长时间讨论指标,我意识到它们是多么重要。

在创建指标时,数据科学家常常需要确保它们:

  • 易于定义、理解和创建。

  • 在实验中可重复使用。

  • 对变化敏感且响应迅速。

如何学习指标的哲学?

如果你无法获得现实世界的指标,你可以:

  1. 深入案例研究: 在线有许多商业案例研究。选择一个与你感兴趣的行业相关的案例。试图了解业务目标,并对可能衡量成功的指标进行头脑风暴。

  2. 启动理论项目: 想象一个假设的产品或服务。成功的标准是什么?为这种成功定义关键绩效指标。你甚至可以与同事或导师讨论以获得反馈。

  3. 阅读科学论文: 我最近深入研究了这篇由 Alex Deng 和 Xiaolin Shi 撰写的论文,作为我对指标框架研究的一部分。我发现它非常有信息量并且适用于实际案例,我建议任何刚开始研究指标的人都阅读它。

对于那些已经在工作中的人,你可以:

  1. 参与跨职能合作: 与公司内的产品经理或业务战略家合作。了解更广泛的业务目标,并对可能与这些目标一致的关键绩效指标进行头脑风暴。

  2. 回顾过去的项目: 回顾以往的项目或实验。设定的指标是否有效?它们是否捕捉到了预期的效果?反思过去的经验可以是一个很好的学习工具。

  3. 找一个导师: 如果你的组织里有一个特别擅长指标设置的人,考虑请他们指导你。定期讨论可以帮助你完善指标的方法。

指标不是一成不变的。随着业务目标的演变,你的指标也应随之调整。

#6. 锻造你的法典

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

作者提供的图像(DALL.E)

虽然你的数据科学技艺至关重要,但你使用的工具和技巧——你的代码——需要保持锋利和强效。

第 8 课——提升你的编程技能,以便更好地独立解决问题和团队协作

让我们深入探讨一下这意味着什么:

  1. 代码编写效率: 能够编写有效的代码是有价值的,但效率不仅仅是速度。它涉及到创造能够最佳运作、明智使用资源并且容易被他人理解的解决方案。

  2. Python 和 SQL 精通: 这些是许多数据科学家的核心技能。确保你不仅仅是熟悉它们,而是深入了解它们的复杂性。

  3. 大数据平台: 随着数据的增长,其复杂性也在增加。像 BigQuery 或 AWS 这样的平台在处理大数据方面处于前沿。熟悉这些平台可以提升你的简历,并让你看起来‘随时准备行动’。

  4. 代码组织与文档: 干净、组织良好的代码不仅是为了你自己。这是为了将来可能会接触到你工作的人。确保你学习编写可共享代码的最佳实践。

  5. 与 Git 的协作: 数据科学不是一个人的工作。共享和存储代码是必不可少的,像 Git 这样的平台使其变得无缝。除了‘了解’ Git,尝试理解提交信息、分支和合并的最佳实践。我认为 Git 并不是特别直观,但它可以改变游戏规则。

  6. 持续学习: 技术领域迅速变化。库更新,新工具不断出现,方法论也在变化。保持更新不仅是有益的,而且是必需的。确保你留出时间进行探索,以免过度落伍。

要深入阅读,你可以查看我写的这篇文章,详细介绍了掌握 Python、SQL 和机器学习的顶级内容以及方法!

## 不要在开始数据科学旅程前错过这五个必须做的步骤,来自 Spotify 数据科学家

这是我在开始数据科学之旅之前希望自己能做到的一切的完整指南,祝你第一年顺利……

[towardsdatascience.com

终极技能——最后一个要点

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

作者提供的图片 (DALL.E)

确保你始终将一切与潜在的业务目标连接起来。这是最宝贵的技能。

科技公司首先是商业企业,因此我们所做的一切都与推动全球商业目标相关。每一份数据、每一个分析和每一个建议都应与更大的商业愿景产生共鸣。

这将贯穿于你的整个数据科学职业生涯——它本身就是一段旅程。

为了展示你出色的商业敏锐度,确保你练习解决根植于现实商业场景的数据问题。这些是你在简历上最要突出的。

考虑将这些添加到你的 Github 仓库中(你将把它们链接到你的简历上),以及一个详细说明你的策略、见解和建议的幻灯片。这样,他们会知道谁才是真正的老板——我是说游戏中的“巫师”。

总结——在申请科技职位之前磨练这些技能可以增加你获得梦想工作的机会。

当然,这意味着你必须确保在简历上突出这些内容,否则他们怎么会知道你的魔法能力?所以请通过引用示例和链接展示你的项目来做到这一点。

就像未能有效传达重要见解——如果你不能以引人入胜的方式分享这些内容,那就没有意义了 😉!

1. 学习高级数据处理和探索性数据分析(EDA)

→ 专注于掌握 SQL 的高级功能,以提升你的准确性和处理复杂查询的能力。

→ 复习统计概念和概率理论,以提高你的 EDA 能力并捕捉异常。

2. 发展讲述引人入胜的视觉故事的技能

→ 熟悉你可以使用的不同类型的视觉效果以及它们的不同应用场景。

→ 练习使用不同的可视化库,并打磨你的风格。

→ 试验像 Tableau、Power BI、Data Studio 等仪表盘工具。

3. 深入掌握统计学以进行建模和预测

→ 复习你的数学基础。

→ 探索统计学在商业用例中的其他应用,而不仅仅是机器学习。

4. 熟悉 A/B 测试的基础知识

→ 复习假设检验、检验统计量、样本量计算、暴露量、最小可检测效应等概念。

→ 模拟你自己的 A/B 测试,并进行在线练习。

5. 了解指标框架背后的哲学

→ 了解如何成功设置指标。

→ 如果你是学生或没有从事数据科学工作,你可以深入研究案例研究,开始理论项目,阅读科学论文。如果不是,你也可以与同行合作,回顾过去的项目,或者寻找一个导师。

6. 提升你的编程武器库

→ 学习如何编写高效的 SQL 和 Python 代码,以便同行在 Git 上可以共享和阅读。

→ 尝试大数据平台,以提升你的简历。

→ 继续学习最新的科技和人工智能趋势。

在这一点上,我写这篇文章很开心,也希望你读起来也很开心!愿这篇文章能为你的科技之路增添光彩。干杯🎃!

我有礼物送给你🎁!

注册我的新闻通讯 K’s DataLadder,你将自动获得我的终极 SQL 备忘单,其中包含我在大科技公司工作中每天使用的所有查询 + 另一个神秘礼物!

我每周分享作为科技领域数据科学家的经验,包括实用技巧、技能和故事,旨在帮助你提升水平——因为没有人真正知道,除非他们亲身经历!

如果你还没有做过

  • 订阅我的YouTube频道。新视频很快就会发布!

  • InstagramLinkedInX上关注我,选择你喜欢的方式

很快见!

不要害怕超越在线编程课程

原文:towardsdatascience.com/dont-be-afraid-to-go-beyond-online-coding-courses-9667ebdea9a7

互动编程课程很棒,但(由于设计原因)它们只能帮你走到一定程度。以下是如何在克服其局限性的同时最大化它们的潜力

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

·发布于Towards Data Science ·8 分钟阅读·2023 年 5 月 8 日

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

图片由Alex Radelich提供,来源于Unsplash

我在 2019 年开始了我的第一个在线编程课程。

我还没有完成它。

这个课程承诺通过构建真实世界的应用程序来教你 Python。我很喜欢这个课程,但它并没有特别关注 Python 的数据科学应用场景,不久之后我就放弃了它。

根据 2019 年麻省理工学院研究人员的研究[1],我并不是唯一一个习惯于放弃在线课程的人——这些课程的辍学率常常高达 96%。我的朋友们,如果你们是那 4%退学的人,请自我介绍一下。你们是谁?

尽管如此,尽管我个人缺乏毅力,我对在线编程课程还是充满了喜爱。我在像 CodeAcademy 和 Udemy 这样的网站上上过(并享受过!)许多课程,并且我经常向有志成为数据科学家的朋友推荐这些课程。

但问题是。

像所有形式的学习一样,它们也有其局限性。如果你没有意识到这些,那么你有很高的风险错过那些对建立成功的数据科学职业至关重要的东西。我在本文中的目的是突出这些局限性,以便你对这些网站能为你的职业带来什么有更现实的期望。

我将先讨论在线编程课程的优点,然后讨论一些局限性,最后讨论如何在充分利用这些课程的同时避免它们的陷阱。

在线课程使学习数据科学变得非常简单

从你登陆 CodeAcademy.com 的那一刻起,大约需要 41 秒来创建账户、注册免费课程并开始编码。我知道,因为我刚刚测了时间。

在 2023 年,这可能听起来并不特别值得注意。毕竟,我们是 i 世代——我们习惯了只需点击几下就能快速上手。

但当你考虑数据科学教育的历史背景时,这点令人瞠目结舌。在这些网站出现之前,学习“数据科学”的主要方式是阅读那些名字吓人的大部头书籍,比如统计学习的要素模式识别与机器学习即使是我们这些斯莱特林也不得不承认,自那时以来我们已经取得了令人印象深刻的进展。

为什么速度很重要?好吧,冒着陈词滥调的风险,如果你是想学习编码的人,那么你实际上是想学习如何编码,而不是安装包和在命令行上卡住。像CodeAcademy这样的网站让你能够轻松跳入学习,而不必麻烦的设置过程,这是非常棒的。

他们的引导路径对于像我这样毫无头绪的新手来说非常棒。

除此之外,这些网站提供了出色的引导学习路径。作为一个最近刚刚转行进入数据科学领域的人,这点对我帮助巨大。为什么?因为学习编程最难的事情之一就是知道从哪里开始。你应该选择哪些语言?你应该以什么顺序学习各种函数和方法?你应该解决什么样的问题?

在线编码课程去除了这一猜测过程。通过提供清晰的引导路径,它们展示了你需要学习的内容,并给出大致的学习时间估计。我喜欢这样,因为它使目标变得非常具体。CodeAcademy提供的职业路径(除了技能路径)使这一点更加真实:完成“数据科学家:NLP 专家”路径的目标比“学习 Python,以便进行数据科学”这种模糊的目标要更容易实现。

到了这一步,你可能会想:有什么不好的吗?在线课程似乎很棒!不过,除了这些优势之外,还有一些重要的局限性需要注意。

他们不会教你“宏观层面”的问题解决技能。

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

图片由Olav Ahrens Røtne提供,来源于Unsplash

这些网站的速度和结构意味着它们非常擅长教你如何编码——编写语法和理解新的编程语言。但 Python 并不等于数据科学。SQL、R 或任何其他单独的语言也是如此。

Python 并不等于数据科学。

数据科学不能简化为一堆编码语言;它远不止于此。这是一种利用科学方法以假设驱动的方法解决问题的学科。它不是仅仅解决像 Fizzbuzz 或旅行推销员这样的抽象编码难题。

不要误解我的意思:我并不反对这些挑战。解决快速的难题是提升编码技能和练习解决跨领域问题的好方法,这是一个很棒的技能。但这些难题与数据科学家日常工作中遇到的问题相差甚远。在行业中,你通常需要从根本原因入手:将商业问题转化为可验证的假设或机器学习用例,并制定如何用数据科学方法解决它的计划。做好这一点是至关重要的技能,但遗憾的是,这种技能很难通过 MOOCs 或标准化编码课程来教授。

他们很少教你如何在浏览器外运行代码

许多课程提供基于浏览器的互动开发环境(IDEs),不需要你安装任何软件。

然而,尽管这些基于浏览器的 IDEs 在速度和可及性方面很出色,但它们也有不少缺点。最大的问题是,你可能会在不知道如何在特定平台之外运行代码的情况下完成在线课程。你学会了语法,但不知道如何在解决现实问题时“在野外”执行代码。

他们鼓励你作弊,但方式不对。

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

图片由 Lucas Sankey 提供,来源于 Unsplash

我们都经历过这种情况:你在一个 HackerRank 挑战上卡了好几个小时,完全没有思路。在你脑海里,你知道 Google 一下这个问题大概只需 5 秒钟,便可以找到一些代码复制粘贴。诱惑是难以抵挡的。

许多标准化在线课程面临相同的问题:如果你遇到困难,可以使用 Google 找到你的问题的答案。很多人参加这些课程意味着可能有人以前问过完全相同的问题,并得到了完美的回答,说明你需要做什么。这使得作弊变得非常容易,而在没有真正学习底层理论和框架的情况下通过在线课程。

当然,作为数据科学家“作弊”并没有什么错——这叫做 StackOverflow!(也就是说,如果我们把作弊定义为查找其他人代码中的有用提示的话)。但通常在像 StackOverflow 这样的站点上,你不能直接将别人的代码应用到你的问题上;你必须弄清楚如何将其调整以适应你的具体问题。你不是直接复制粘贴;而是复制-调整-粘贴。因为你通常可以在在线课程中找到确切的答案,你不总是学到这种复制-调整-粘贴的技巧。你只学会了如何复制和粘贴。

很难记住你所学的内容

人类在记忆新信息方面 notoriously 糟糕:平均而言,我们在学习后的一个月内忘记 90% 的新信息 [2]。正如 1880 年艾宾浩斯提出的遗忘曲线著名地展示的 [3],为了让信息真正记住,你需要一遍又一遍地重新学习它。

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

图片由作者提供,基于艾宾浩斯经典的遗忘曲线

像 Duolingo 这样的应用程序对此非常了解:你会重复看到相同的信息,并通过轻微的变化来帮助你学习基本概念。然而,在许多在线编码课程中,课程进展非常快,你不总是有机会重新回顾之前学过的概念。

根据我的经验,这使得记住我所学的所有信息变得困难,我常常发现自己在记住即使是基础的新语法时也感到困难,因为我没有机会通过在线课程进行实践。

这让我们处于什么境地?

我对在线编码课程的总体看法在下图中总结。

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

图片来自Neil ThomasUnsplash

在线数据科学课程可以是一个很好的资源,帮助你快速成长,但正如我在这篇文章中尝试展示的那样,它们也有其局限性。随着你进一步发展并希望过渡到现实世界的角色中,你需要找到在没有它们支持的情况下继续成长的方法。

那么,我们如何解决这些限制呢?这是我的一些建议:

  1. 学习问题解决框架以及编码语言。 要成为一名成功的数据科学家,你需要学习如何将业务问题转化为具体的机器学习应用案例和可测试的假设。我在‘如何寻找独特的数据科学项目创意’中谈到我自己的方法。

  2. 不要仅仅参加编码课程;还要上那些教授你在现实世界中运行代码所需支持工具的课程(例如,GitHub、Jupyter notebooks、VS Code)。知道如何编码对于获得数据科学家的职位至关重要。但要在现实世界中运行代码,你需要掌握像 GitHub、Jupyter 和 AWS、Google Cloud Platform 等云工具。幸运的是,这些工具的技能门槛很低:掌握基础知识并不需要很长时间,你可以通过 YouTube 上的免费课程轻松自学。

  3. 尝试在课程提供的浏览器 IDE 之外应用你所学的知识。如果你只在在线编码课程的课程内容中做项目,你将难以在未来求职时脱颖而出。根据我的经验,创建在线作品集是一个极其有用的方式来应用你的新技能,并向雇主展示它们。我的建议是将你在在线课程中学到的东西应用于个人项目,而不是课程内置的 IDE 中。

哦,还有一件事——

我开始了一份免费的新闻通讯,名为 AI in Five,每周分享 5 个要点,涵盖最新的 AI 新闻、编码技巧和数据科学家/分析师的职业故事。没有炒作,没有“数据是新石油”的废话,也没有埃隆的推文——只有实用的技巧和见解,帮助你在职业发展中提升。如果这听起来对你有帮助,点击这里订阅

## AI in Five | Matt Chapman | Substack

最新的新闻、职业故事和编码技巧,从数据科学和 AI 的世界中总结出 5 个要点…

aiinfive.substack.com

来源

[1] MOOC 转型

[2] 设计教育体验时的考虑因素

[3] Ebbinghaus H (1880) Urmanuskript “Ueber das Gedächtniß”。帕绍:帕萨维亚大学出版社。

不要忘记你的 ML 产品的置信区间

原文:towardsdatascience.com/dont-forget-confidence-intervals-for-your-ml-product-272009bfab56

机器学习从来不是 100%正确的。因此,ML 模型只有在用户理解预测的不确定性时才有帮助。

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

·发表于Towards Data Science·7 分钟阅读·2023 年 10 月 10 日

几乎每天我们都会发现新的机器学习产品、服务或数据集的发布。尽管我们处于人工智能时代,但很少有这些产品会告知用户对结果的置信度。然而,研究表明,良好的决策需要了解何时信任 AI,何时不信任。否则,用户常常需要频繁尝试模型以了解何时可以信任该模型以及何时不能信任,以便确定所提供的产品是否对他们有用。

用户采用这种试错原则的原因在于每个模型(无论是基于机器学习还是统计学)都是建立在数据及其不确定性上的。模型的基础数据并不代表模型所要预测的实际真相。否则,如果那个真相是可以获得的,你本来不需要模型。因此,得到的模型只会提供一个估计值,而不是一个真实值。

简而言之,机器学习和统计模型的正确性是不确定的,不能总是被信任。

示例:预测跨县移动

让我们举一个例子(图 1)。假设一个产品为你提供从一个国家到另一个国家迁移的人数。当然,存在一些数据(如税务报告)可以提供这些信息,但这些数据是否真正代表了全部迁移人口?每个学生、移民或前配偶都会更改他们的税务报告吗?不,很可能不是这样。因此,即使是提供迁移信息这样简单的产品也会偏向其底层数据样本(例如公开的税务报告)。更复杂的产品容易出现偏见,这是很容易想象的。

对于机器学习来说,这种限制更为严重,因为其概率性质、多样的输入以及每个输入仅代表总体的一小部分。因此,底层模型会偏向训练数据中描述的大多数情况,并会偏离我们不知道的真实世界情况。简而言之,机器学习和统计模型的正确性是不确定的,不能总是被信任。

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

图 1:模型预测从一个国家到另一个国家的迁移示例。用户不知道真实的迁移情况(灰色)。如果不了解模型的置信度,结果的解释可能会产生误导。在这种情况下,假设从 CA 到欧盟和从美国到欧盟的人数是相同的。

置信区间将决策留给用户

我们有时盲目信任数据产品的原因在于我们对开发产品的人或公司有信任。我们确实期望公司在推出产品之前进行严格的质量测试。但在一个越来越多工作也外包给人工智能的资本主义世界中,我们能否相信每个产品的发布都足够好且经过适当测试?

实际上,没有任何数据产品(特别是没有机器学习模型)会告诉你何时它是错误的。它只会给你一个预测(无论这个预测有多么偏离)。那么,如果一个重要的业务决策是基于错误的预测做出的,那该怪谁呢?作为开发这个产品的数据科学家,我不想成为那个被责怪的人!这就是为什么提供直观的置信区间对于每一个数据产品都很重要。

置信区间是告知客户产品不确定性的解决方案,以便他们可以做出是否信任预测的明智决策

起初这听起来很复杂,有些用户可能会对置信区间这一术语感到害怕,但它们并不像听起来那么可怕。直观的置信区间是有帮助的,也是产品质量的标志。它们显示公司关心你作为用户,因为他们试图帮助你做出最佳决策。

什么是 95%置信区间?

选择 95%的置信区间是一种常见的描述信心的方法,因为它易于解释。置信区间包含数据的下限和上限(通常显示为图表上的细条)。下限和上限基本上描述了一个范围或一个走廊,其中 95%的预测值将落在实际(未知)真实值的范围内。因此,较大的范围(与预测值相比)表明用户应该对所提供的值的信心较低,因为潜在的真实值可能会有很大差异。

如何计算置信区间?

以上面的例子为例,定义一个产品,该产品提供从加拿大和美国到欧盟国家的迁移量。如图 1 所示,这里的假设模型对来自加拿大的迁移预测更接近真实情况。因此,告知最终用户对加拿大模型的高信心与对美国模型的低信心相比,将是有益的。

如果我们不以置信区间的形式提供这些信息,则数据的直观结论(右侧的蓝色条,因为你无法知道灰色条)是两个国家向欧盟的流出量相等。然而,一旦我们添加描述对这些数字的信任度的置信区间,解释就会发生变化。如果置信区间描述了 95%的信心,那么更好的解释是实际的迁移量可能与这里提供的差异很大。它可能是两倍多,但仍然在 95%的置信范围内。因此,用户不应仅依据所提供的数据做出商业决策,而应关注 CA 迁移或评估其他数据来源。

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

图 2:当你的模型通过测试数据得到积极评价并投入生产时,你可以使用这些测试数据来计算真实值与预测值之间的差异,这反过来允许你估计置信范围。

那么我们如何创建并添加置信区间到我们的模型中?顾名思义,要构建置信区间(或任何其他信心度量),你首先需要定义你的指标代表什么以及信心对你和你的用户意味着什么。衍生信心度量的方法有很多,但都依赖于某种可以用来验证和测试你预测的知识。例如:

  • 当你拥有真实数据时: 真实数据通常在历史上已经存在或在某个延迟后出现。如果是这样,可以用来评估你的预测偏差有多大,并且可以用来更新你对未来预测的信心。例如,当你可以访问税务报告以查看有多少人迁移时,你可以看到你的预测与实际情况的相关性如何。

  • 当你对你的预测拥有专家知识时: 对于很多产品来说,真实情况并不总是可用的,或者有很长的延迟。然而,有时你可以定义数据应该遵循的某些特征或模式。如果是这样,你可以将这些特征视为与真实情况的相关因素,并让它们帮助你建立置信区间。例如,当你对 Covid19 如何影响运动有专家知识时,你可以分析你的预测与这些知识的匹配程度。

  • 当你有一个测试集评估时: 即使没有持续的真实情况或专家知识,你仍然可以使用测试集评估来描述置信区间(见图 2)。每个建立的模型都需要一个测试集,以确保模型能够成功预测预期结果(有关模型开发的更多信息,请参见这里)。该测试集还会告诉你模型的表现良好与否。至少对于样本内类别,它将允许你提供置信区间。不过,缺点是模型随着时间的推移容易发生漂移。因此,找到更新置信区间的方法是很重要的。

简单代码示例 (SQL)

当你拥有上述条件之一时,估计 95%的置信区间可以相当简单,只要数据是正态分布的,并且每个样本相互独立(没有自相关)。下面是如何在标准 SQL 中估计每个类别(主键)的置信区间的示例。

首先,我们计算预测结果与真实情况之间的误差:

SELECT 
  date, 
  primary_key, 
  (prediction - groundtruth) AS error
FROM input_table

然后,基于标准差和样本大小计算误差范围:

WITH base as (
SELECT
  primary_key,
  count(*) AS n,
  STDDEV(error) AS error_std
FROM error_table
GROUP BY primary_key
)

-- 1.96 represents z-score for 95% confidence level
SELECT
  primary_key,
  1.96 * SAFE_DIVIDE(error_std, sqrt(n)) AS margin_of_error

最后,应用误差范围来推导下限和上限置信区间:

SELECT
  date,
  primary_key,
  prediction - margin_of_error as lower_confidence_interval,
  prediction + margin_of_error as upper_confidence_interval
FROM input_table
JOIN margin_of_error_table USING(primary_key)

总结

统计和机器学习模型提供的是估计,而不是真实情况。我们都必须理解这一点,并找到相应的工作方式。置信度的测量将允许用户理解在基于某个模型的产品中应对收到的答案投入多少信任和权重,从而使用户能够做出更好的决策。

重要的是要强调,低置信度得分并不一定意味着产品质量低,这可能只是意味着产品不适用于当前的用例,其他数据源在决策过程中应当更具权重。

可以得出结论,置信区间为最终用户提供了帮助,以做出明智的决策,同时也保护数据科学家免于过于简单的解读,认为每个数据始终是正确的。

除非另有说明,否则所有图片均由作者提供。

别忘了 Python 是动态的!

原文:towardsdatascience.com/dont-forget-that-python-is-dynamic-e298e2a30118

PYTHON 编程

越来越多的静态和动态检查……这是我们希望 Python 发展的方向吗?

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

·发表于 Towards Data Science ·8 分钟阅读·2023 年 6 月 13 日

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

Python 将走向何方?照片由 Jamie Templeton 拍摄,来源于 Unsplash

Python 是一种动态语言。然而,近年来,越来越多的关注被放在了静态类型检查上。这反过来导致了对运行时类型检查的兴趣增加。我们将走多远呢?在这篇文章中,我们将回顾为什么 Python 曾经被认为是一个强大的动态类型编程语言。

现在仍然如此吗?

Python 的优势一直在于其简洁性,这至少部分源于动态类型,不仅因为我们可以在 REPL 中编写 Python 代码,还因为以下原因:

  • 你可以在整个程序中轻松地改变变量的类型。

  • 你不需要定义变量的类型。

  • 代码(或可以)易于阅读和理解。

  • 有时,你可以用几行代码实现即使是相当复杂的算法。而静态类型语言通常需要更多的——或者至少更多的——代码行数。

当然,动态类型也有其代价。第一个是性能下降,这是我们都知道的。性能下降的原因在于,类型——这些类型没有被声明——必须在运行时进行检查(由 Python 完成)。另一个代价是运行时错误的风险增加:由于类型不是在编译时检查,而是在运行时检查,相关错误会在程序执行期间抛出,而不是在编译期间。

我们需要记住,Python 提供了一系列工具来处理其性能下降的问题:

[## Python 的速度:并没有那么糟糕!

我总是听到 Python 非常慢。真的是这样吗?

medium.com

多年来,Python 爱好者为 Python 是一种动态类型语言而感到自豪和高兴。当然,那些不喜欢 Python 的人声称它是一种糟糕的语言……我还能说什么呢?每个人都可以有自己的看法;编程是一个自由的世界。

编程是一个自由的世界。

然而,最近一段时间,Python 正在向编程的静态方面发展。这一变化的最重要方面是类型提示。虽然它们是可选的,但现在大多数大型项目都实现了类型提示。你会更常听到在一个严肃的项目中你必须提示类型,而不是你不必这样做——更不用说你不应该这样做。准备好听到这样的说法:“当然,类型提示是可选的,因此对于原型和短脚本,你不需要使用它们,但对于大型项目——嗯,唯一的选择就是提示类型。”我听到过不止一次,也不止两次。

这个情况引发了以下问题:我们真的需要所有这些类型提示、静态类型检查器和运行时类型检查器吗?

我不会对这个问题做出回应。这主要是因为我远不是那些自以为知道一切的人……嗯,几乎知道一切的人。但我希望邀请你自己思考这个问题。

不过,我会提醒你——也提醒我自己——Python 的动态类型,也被称为 鸭子类型,是这个语言成功的基础。以下是关于鸭子类型如何工作的流行解释:

如果它走起来像鸭子,叫起来也像鸭子,那它一定是一只鸭子。

Duck typing 在没有类型提示和运行时类型检查的情况下也可以非常强大。我将通过非常简单的示例向你展示这一点,不再赘述,让我们直接跳入这个简单的示例:

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

通过运行时类型检查捕捉错误。图片由作者提供

在这里,我们检查 xy 的类型,它们都应该是字符串(str)。注意,这样我们有点在检查我们提供给 str.join() 方法的内容是否是 tuple[str, str]。当然,我们不必检查这个方法是否得到了一个元组,因为我们是自己创建的;只需检查 xy 的类型。当其中任何一个不是字符串时,函数将抛出 TypeError 并带有简单的消息:“提供一个字符串!”。

很棒,对吧?我们可以确保函数仅在正确类型的值上运行。如果不符合,我们会看到自定义的消息。我们也可以使用自定义错误:

## 我们是否应该在 Python 中使用自定义异常?

Python 有这么多内置异常,我们很少需要创建和使用自定义异常。或者说我们需要吗?

[towardsdatascience.com

现在,让我们移除类型检查,看看函数的表现:

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

捕捉没有运行时类型检查的错误;消息不是内置的。图片来源于作者

哈,看起来确实以非常相似的方式工作……我的意思是,异常基本上在同一个地方被引发,所以我们没有冒任何风险。那么……

确实,这里函数 foo_no_check() 使用了鸭子类型,它使用了一种隐式类型的概念。在这个例子中,str.join() 方法假设它接受一个字符串元组,因此 xy 必须是字符串,如果不是,隐式类型 tuple[str, str] 就没有被实现。因此出现了错误。

你可能会说:“但是嘿!看看消息!之前我们可以使用自定义消息,现在却不能了!”

我们真的不能吗?看看:

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

捕捉没有运行时类型检查的错误;错误消息已自定义。图片来源于作者

我们现在可以看到两条消息:内置的(sequence item 1: expected str instance, in found)和自定义的(提供字符串!)。

性能

你可能会问:有什么区别?所以,我检查类型。有什么问题吗?

好吧,确实有很大的区别:性能。让我们使用 [perftester](https://github.com/nyggus/perftester) 包来基准测试这三个版本的函数:

## 轻松基准测试 Python 函数:perftester

你可以使用 perftester 来轻松地对 Python 函数进行基准测试

[towardsdatascience.com

这是基准测试结果:

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

使用 perftester 包进行的基准测试。图片来源于作者

在本文所有的基准测试中,我使用的是 Windows 10 机器上的 Python 3.11,WSL 1,32GB 内存和四个物理(八个逻辑)核心。

在第二行,我将默认实验次数设置为 10,在每次运行中,每个函数都要执行一亿次。我们从十次运行中取最好的一次,并报告平均时间(秒)。

foo() 函数,即具有运行时类型检查的那个,明显比其他两个要慢。foo_no_check() 函数是最快的,尽管 foo_no_check_tryexcept() 仅稍慢一点。

结论?运行时类型检查是昂贵的。

你可能会说:“什么?你在开玩笑吗?昂贵?这只是小于一秒的微小部分!甚至不到一微秒!”

确实。这并不多。但这是一个只有两个检查的非常简单的函数。现在想象一个庞大的代码库,有许多类、方法和函数——以及大量的运行时类型检查。有时候,这可能会显著降低性能。

运行时类型检查是昂贵的。

结论

阅读关于鸭子类型时,你通常会看到猫会喵、狗不会、牛会哞的例子。当你听到一种动物在喵的时候,它既不是狗也不是牛,而是一只猫。但不是老虎。我决定使用一个不寻常的例子,希望它足够清晰,让你看到鸭子类型的优势。

如你所见,Python 异常处理在运行时类型检查方面做得很出色。你可以通过在需要时添加额外的类型检查来帮助它,但始终记住,它们会增加一些开销时间。

结论?Python 拥有很好的异常处理工具,效果非常好。很多时候,我们根本不需要使用运行时类型检查。然而,有时候我们可能需要。当两种类型具有相似的接口时,鸭子类型可能会失败。

例如,假设你想要加两个数字(x + y),但用户提供了两个字符串。这不会意味着出错,因为你可以加两个字符串。在这种情况下,你可能需要添加运行时类型检查,如果你不想让程序继续使用这些不正确的值。迟早它会破坏,因此问题是你是否希望程序继续运行到那时。如果是的话,你可能会冒着异常被稍晚引发的风险,所以添加类型检查实际上可以节省时间。此外,稍晚在程序流中引发异常可能会导致找到错误真正原因的困难。

总而言之,我并不是说运行时类型检查绝对不应该使用。但很多时候,这些检查是在不需要的时候被添加的。

我希望我激发了你的兴趣和灵感。今天,这就是我想要达到的目标。请在评论中分享你的想法。告诉我们你是否会在这样简单的情况下使用运行时类型检查。

我没有讨论静态检查和鹅类型。我已经写了几篇关于静态检查和类型提示的文章:

[## Python 的类型提示:朋友、敌人还是单纯的头疼?

类型提示在 Python 社区中的受欢迎程度正在上升。这将引领我们到哪里?我们可以做些什么来使用它…

betterprogramming.pub ## Python 类型提示:鸭子类型兼容性和一致性

当你提示float时,不必同时提示int,提示tuple时也不必提示namedtuple。为什么?

towardsdatascience.com ## Python 类型提示:从类型别名到类型变量和新类型

查看类型别名、类型变量和新类型的实际应用

towardsdatascience.com

我还没有写过关于鹅类型的内容,但迟早会有那一天。

Python 是否仍被认为是一种强大的动态类型语言?说实话,我不知道。Python 中如此多的关注点都集中在静态和运行时检查上,我担心很多人已经忘记了 Python 真正的力量在于完全不同的东西:它的简单性、可读性——还有,鸭子类型

我听说过一些经验丰富的 Python 爱好者表达他们对 Python 不再像以前那样的失望之情。他们中的一些人决定从 Python 转向其他语言,声称“如果我需要在变量上定义类型,Python 会是我最后的选择!”这非常有道理。静态类型语言可以比 Python 快得多——而且它们仍然可以像 Go 那样相当简单和可读。但 Python… Python 提供了简单而强大的鸭子类型… 许多人似乎忘记了这种鸭子类型

我自己喜欢 Python 和 Go。Go 是静态类型的,这使它比 Python 明显更快。但你知道吗?对我来说,Go 的静态类型代码往往比带有类型提示的 Python 代码更容易阅读和理解!

当我看到代码中到处都是运行时检查时,我感到疲惫和沮丧。这不是 Python 创建的初衷。是的,类型提示可以非常有用——但只有在正确使用并且不过度使用时才有效。如果使用过度,它们可能成为相当大的负担。

当我看到代码中到处都是运行时检查时,我感到疲惫和沮丧。这不是 Python 创建的初衷。

感谢阅读。如果你喜欢这篇文章,你可能也会喜欢我写的其他文章;你可以在这里看到它们。如果你想加入 Medium,请使用下面的推荐链接:

[## 使用我的推荐链接加入 Medium - Marcin Kozak

阅读 Marcin Kozak(以及 Medium 上的其他成千上万的作家)的每一篇故事。你的会员费直接支持…

medium.com](https://medium.com/@nyggus/membership?source=post_page-----e298e2a30118--------------------------------)

不要让你的第一个 AI 项目在推出时陷入困境

原文:towardsdatascience.com/dont-let-your-first-ai-project-get-stuck-going-out-the-door-9b2217a0affa?source=collection_archive---------11-----------------------#2023-05-09

融合 AI 和 DevOps,启动你组织的 AI 之旅

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

·

关注 发表在 Towards Data Science · 7 分钟阅读 · 2023 年 5 月 9 日

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

不要让你的 AI 项目在推出时陷入困境!(所有图片均由作者和 DALL-E 提供。)

人工智能(AI)项目有可能彻底改变组织,但成功将 AI 项目投入生产需要强大的 DevOps 基础。这篇文章是为那些刚刚开始 AI 策略或第一个 AI 项目的团队设计的。如果你只是为了乐趣而尝试 AI 模型,那很好!但如果你的目标是最终让模型可供客户(内部或外部)使用,这篇文章就是为你准备的。

基于他人的组织学习,我将分享如何为 AI 项目构建一个稳固的 DevOps 框架的建议,以及为什么这对你团队的成功至关重要。

1. 在开始之前进入 DevOps 思维模式。

如果你的团队对 AI 不熟悉,你有机会避免一些其他团队犯过的错误!在首次 AI 项目中一个常见的错误是仅专注于构建模型。

作为 AI 解决方案架构师,我见证了无数团队决定投资 AI,构建模型,然后几个月甚至几年都没有推出一个模型!通常,团队没有明确的路径来将模型发布出去。看到一个模型接近影响业务价值却在最后一刻止步,真的让人感到沮丧。

除非你决心为了研究做 AI,否则你的目标不是“拥有一个模型。”你的目标是“让人们使用这个模型。”DevOps 是开发工作和用户使用产品之间的界限。不要让优秀的实验因为没有转化为优秀的产品而白白浪费。

2. 提前与团队设定期望。

认识到,将模型服务于最终用户需要不同的技能和工具,与训练模型不同。促进你的 DevOps 团队和 AI 团队之间的合作。或者,如果你的 AI 团队将自行执行 DevOps 任务,提前讨论支持生产环境中的模型将涉及哪些内容。

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

3. 接受 AI 项目的迭代特性。

对于新进入该领域的团队来说,AI 部署的一个方面可能会让人感到意外,那就是 AI 是一个不断发展的过程。要做好支持持续改进和迭代的准备。

即使你的模型一开始具有令人印象深刻的准确性,但它遇到的输入和条件会随着时间的推移而变化。这个过程变成了一个训练、整合新数据和重新训练的循环,以不断提升 AI 的能力。

这里有一些示例,展示了为什么持续再训练可能是至关重要的:

  1. 预测产品和服务需求的 AI 模型必须不断适应不断变化的市场条件和客户偏好。

  2. 检测欺诈交易的 AI 模型需要与不断变化的欺诈手法和金融数据模式保持同步。

  3. 分析社交媒体趋势的 AI 模型需要考虑到病毒内容和用户行为迅速变化的环境。

所以,如果你希望模型保持相关性和有效性,可能会有长期的 DevOps 工作来支持迭代和重新部署。

10 个关键问题,助力 AI 项目增长。

在你为团队制定最佳实践时,考虑以下目标和问题。

注意: 你可能会发现第一个 AI 项目的答案与后续项目不同。现在,大多数问题的答案可能是“Jesse 每周手动检查”。最好现在就有一个明确的计划——即使看起来技术含量不高——也比以后遇到意外要好。

1. 促进合作和知识共享

你如何促进 AI 和 DevOps 团队之间的跨功能协作?哪些平台或工具将促进有效的知识共享?

  • 计划一个联合启动会议和定期的团队检查点。如果你有一个 DevOps 团队,他们可以了解即将发生的事情,并与模型构建者感受到团队的归属感。如果你的模型构建者将执行 DevOps 工作,这将明确地集中时间进行生产计划。

  • 为讨论或工作跟踪指定一个空间。(Slack?JIRA?)

  • 在各个小组之间广泛分享关于模型开发进展的激动人心的更新。

2. 确定 AI 特定流程

部署和管理 AI 模型时,你需要什么独特的流程?你的 DevOps 团队如何学习并适应这些流程?

  • 开始起草将模型从开发转移到生产的部署管道。

  • 讨论你对监控、维护和更新生产中 AI 模型的目标。

  • 识别可能需要时间或资源来学习 AI DevOps 工具或实践的人。

3. 实施强有力的安全和合规措施

应该遵循哪些安全最佳实践来保护你的 AI 模型和数据?你将如何确保遵守相关法规和行业标准?

  • 考虑这个新用例是否与数据的现有使用预期一致(例如,你的客户是否同意以这种方式使用他们的数据?)。

  • 考虑是否需要起草有关数据和模型使用的新文档,可能是内部使用的或面向客户的文档。考虑是否需要涉及你的法律团队。

  • 识别适用的法规(例如 GDPR、HIPAA),并建立流程以保持合规。

  • 进行定期的合规审查和审计。

4. 明智地分配资源

你将如何监控和分配资源,例如 GPU 使用情况?你有硬件预算吗?

在开始时,你可能会关注在哪里训练模型和如何部署它。随着进展,你可能会探索更高级的基础设施规划,例如优化资源分配或将管道容器化以实现可移植性和可扩展性。

5. 监控模型性能

我们将如何跟踪 AI 模型在生产中的性能?哪些指标和监控工具将帮助识别潜在问题或性能退化?

  • 确定模型的关键性能指标。除了准确性,其他指标可能也很重要,具体取决于应用程序和用例(例如,精确度、召回率)。还要考虑是否有模型的延迟要求。

  • 制定一个持续审查关键性能指标和检测“模型漂移”的计划。

6. 计划模型再训练

我们如何安排和管理 AI 模型的定期再训练,以确保它们跟上最新的信息?我们可以实施哪些具体方法或工具来简化再训练过程并开始自动化?

  • 实施一个纳入新数据的流程。

  • 根据数据和模型性能的预期变化速率制定再训练计划。考虑如何在部署前验证再训练的模型。

7. 高效管理数据管道

我们将如何处理数据摄取和预处理?我们需要设置什么数据验证?哪些工具和流程能确保数据在整个管道中的质量和一致性?

  • 考虑实施数据质量检查,以识别错误或缺失值。考虑检查异常值、离群值或数据漂移。

  • 对于数据准备工作流,考虑你的团队是否会倾向于使用你正在使用的机器学习工具中的原生功能(例如 PyTorch),而不是添加额外的管道管理工具(例如 Airflow)。

注意:虽然深入了解机器学习运维(MLOps)很有诱惑,但早期过度自动化是很重要的

仔细思考你要解决的问题和解决问题所需的基本方法,而不是过于分心于炫目的工具或平台。 — Mihail Eric, MLOps Is a Mess But That’s to be Expected

从简单开始,根据需要让你的 MLOps 流程自然增长。

8. 确保模型的可重复性

你将如何保证在训练和部署 AI 模型时结果的一致性?哪些版本控制和追踪系统会有所帮助?

  • 尽可能记录和版本控制 AI 项目的各个方面,包括数据、代码和配置。

  • 考虑使用像 Docker 这样的容器化工具,以确保开发和生产环境的一致性。

9. 最终制定模型更新策略

一开始,你的重点可能是让你的 AI 模型按照项目目标运行。在未来,你的团队可能会探索结合架构改进、新特性或调整模型参数以提升其能力。为了支持这些未来的发展,你可能最终会制定一个包含强大测试过程和必要时能够回滚更改的模型更新策略。

10. 不断完善和优化流程

你将如何不断改进你的 AI DevOps 流程?哪些指标有助于优化?

  • 鼓励所有相关小组的团队成员之间开放沟通。

  • 定期审查流程并结合反馈以优化工作流。

总结

这是一长串需要考虑的问题!如果有疑问,尽量避免创建以下情况:

  • 😞 AI 模型经过一次重大努力后被发布,但几乎不可能发布模型的新版本。

  • 😞 消耗新的训练数据需要巨大的努力。

  • 😞 没有人知道模型在 6 个月后是否仍然准确。

你能做到的!

启动你的第一个 AI 项目可能是一个复杂且具有挑战性的过程。通过遵循这些指南并专注于整合 AI 和 DevOps,你可以为成功的 AI 之旅奠定基础。记住保持沟通畅通,适应变化的需求,并随着组织的演变自然地发展你的 AI 和 DevOps 实践。

不要在没有这 5 个必做步骤的情况下开始你的数据科学之旅——Spotify 数据科学家的完整指南

原文:towardsdatascience.com/dont-start-your-data-science-journey-without-these-5-must-do-steps-from-a-spotify-data-scientist-c9cec11fd1b

一份关于我希望在开始数据科学之旅前做的所有事情的完整指南,祝你在数据科学的第一年取得优异成绩

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

·发布于 Towards Data Science ·阅读时间 18 分钟·2023 年 9 月 24 日

你是刚开始数据科学之旅吗?也许你已经盯着这个数据科学学位或训练营看了太久,现在不知道从哪里开始?

也许你已经开始了你的数据科学之旅,现在感到不知所措,手忙脚乱?

四年前,我和你一样——只是我盲目地跳入了一个没有任何编码技能的数据科学学位。剧透:我遇到了很多困难。

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

庆祝我在毕业两年后的胜利

快进到今天:我是一名 Spotify 的数据科学家,我在这里给你提供我希望 4 年前有人给我的提醒。如果你正准备迈向你梦想的学位,那么这篇文章可能会成为你的终极改变者。

相信我,你不想在没有准备的情况下跳入这个领域。我以为进入 NYU 意味着我可以顺利度过这一年。我知道路途会很崎岖,但我没准备好面对那些真正的山峰。

另一个剧透:我活下来了。但这是一个充满眼泪和暴饮暴食的痛苦旅程。所以我在这里是为了让你免受这种折磨。

在这篇文章中,我将深入探讨我希望在开始 NYU 的数据科学学位之前做的 5 个最关键的步骤。这 5 个步骤实际上是我在学位期间一并学到的。

这可能会非常令人不安,因为同时学习所有这些技能是具有挑战性的 → 有太多内容需要在极短的时间内处理。

没有人应该在没有充分准备的情况下睡着般地迎接这样一个具有挑战性的项目。

这篇文章是我写给过去的自己——也是写给你的。

但首先,确保订阅我的新闻通讯!

每周,我都会分享一个关于我作为 Spotify 数据科学家一天的快速故事和经验。

[## K’s DataLadder | Khouloud El Alami | Substack

一名科技公司数据科学家的生活——起伏、学习以及一切。点击阅读 K 的…

levelupwithk.substack.com](https://levelupwithk.substack.com/?source=post_page-----c9cec11fd1b--------------------------------)

准备好了吗?那就直接开始吧。你会感谢我的!

今日菜单

#1. 避免未来的头痛——掌握线性代数和统计基础

#2. 说计算机的语言——理解基本算法框架和数据结构

#3. 超越导入机器学习算法——理解其结构,你将无敌

#4. 驯服 Python 怪兽及其库

#5. 与 SQL 交朋友

在科技领域,我们经常使用复杂的 SQL 函数!我为你整理了最重要的函数在这份终极备忘单中💜

让我告诉你我最初是怎么到达那里(否则你可以跳到下一部分,我不会生气)

从前,一位公主被唤醒了。那天早上 5 点不是童话中的真爱之吻打醒了我。试试 NYU 的营销服务吧,谁知道他们从哪里来推广他们的数据科学项目。

我接了电话并听着。这是我第一次给营销电话留了怀疑的余地。

长话短说,他们很好,因为六个月后,我已经在纽约市的大街小巷游荡。

我记得那时我感觉自己快要征服世界了。但那时,我完全没有意识到我即将经历我人生中最大的耳光。这个耳光那么重,持续了整整 10 个月。

这是四年前的事了,所以在这期间,我获得了足够的视角和作为数据科学家的经验,可以准确告诉你如何为成功做准备。

如果你想了解更多关于我如何经历起伏的旅程,最终进入 Spotify 的故事,那一定要查看下面的文章。

## 从商业学生到 Spotify 的数据科学家

我如何从害怕数学变成在著名科技公司成为一名全面的数据科学家的时间线

towardsdatascience.com

或者如果你想了解更多关于如何加入你梦想的科技公司的信息,那么一定要仔细遵循下面文章中的规则!

## 不要在没有掌握这 6 个必须具备的数据科学技能的情况下申请技术职位

一窥科技的魔法世界,了解你需要什么才能成功成为数据巫师。

[不要在没有掌握这 6 个必须具备的数据科学技能的情况下申请技术职位

我建议按照下面列出的五个步骤进行操作。

#1. 避免未来的头痛——掌握线性代数和统计学基础

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

图片由 Raghav Modi 提供,来源于 Unsplash

如果这些术语对你没有什么启发,那么你真的不应该考虑跳入数据科学培训。

想象一下: 一整年我都在构建机器学习模型,但直到一年后我才意识到我只是像机器人一样重复代码。我没有将这些新概念与我在线性代数和统计学中学到的概念联系起来。这最终减缓了我的进步。

如果你不掌握线性代数和统计学基础,你将永远无法:

  • 高效地处理和准确地解释大数据集。

  • 掌握大多数机器学习算法背后的基础 原理

  • 学会从数据中验证并得出有意义的结论

  • 被视为真正的数据科学家,特别是在科技公司中。

如果没有这两者,你将会在机器学习的海洋中毫无方向。

成为数据科学家不仅仅是从库中导入算法并让魔法发挥作用。这首先是关于理解你实际在做什么的。

线性代数为何如此重要?

  • 向量和矩阵: 在数据科学中,尤其是在机器学习中,数据通常表示为向量和矩阵。例如,一个包含n用户和m变量的数据集可以表示为n x m 矩阵。

  • 变换: 主成分分析(PCA)等降维技术根植于线性代数中的特征值和正交性概念。这些概念至关重要,因为它们允许你将数据转换为更易管理或解释的形式。

  • 机器学习模型: 机器学习在很大程度上依赖于线性代数。例如,神经网络的权重可以表示为矩阵,而它们的操作涉及大量的矩阵乘法。

为什么统计学和概率论如此重要?

  • 描述性统计: 在深入复杂模型之前,理解数据的基本属性,如均值、中位数、方差和标准差,是至关重要的。

  • 推断: 仅仅做出预测或理解模式是不够的。我们还需要评估我们的预测或结果有多可靠。统计推断有助于估计总体参数和检验假设。这使我们能够理解我们的发现的意义,就像我们对 A/B 测试所做的那样。

  • 概率论: 许多机器学习算法的基础是概率论。像条件概率和贝叶斯定理这样的概念是了解像朴素贝叶斯、贝叶斯网络及其他许多算法的关键。

  • 分布理论: 理解不同的概率分布,如正态分布、二项分布和泊松分布,有助于对数据或算法做出假设。许多机器学习模型依赖于数据符合特定类型的分布的假设,因此如果你对概率分布了解不多,怎么能期望你确定使用哪种算法呢?

  • 抽样和估计: 数据科学家几乎总是处理样本数据而非整个总体,原因有很多。统计学为你提供了理解样本与总体之间关系的工具,以确保你能够从发现中进行概括。

  • 模型评估: 像卡方检验、t 检验、方差分析等技术用于比较和评估不同的模型。在做 A/B 测试时我们会频繁使用这些技术,这些测试主要依赖于假设检验。

最后,你需要能够回答如下问题:

  • 什么是 p 值?

  • 什么是过拟合?

  • 什么是线性独立性?

  • 什么是真阳性率?假阳性率?

  • 什么是统计显著性以及如何验证它?

  • 不同的统计检验是什么,它们是如何工作的?

而且问题还不止这些。 这些也是面试中经常出现的问题,所以最好尽早开始准备!

构建和优化模型,以及解释数据结果和预测需要了解算法的基本原理。如果不首先深入那些数学概念,你不会走得太远。

#2. 讲计算机的语言——了解基本的算法框架和数据结构

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

图片来源:Андрей СизовUnsplash

在加入 NYU 之前,我花了 2 到 3 个月的时间来进行编码实践。我参加的第一堂课已经要求我们使用 Python 库在地图上可视化数据。

如果你只能勉强打印出“Hello World”,你应该赶紧回去学习算法基础,因为学习编程就像学习一门新语言。它需要时间。

由于没有人知道随机的单词并将它们神奇地粘在一起形成正确的句子,算法也是如此。

为什么这如此重要?

成为数据科学家需要从大量数据中提取价值。没有任何 Excel 表格能够承受数据的 terabyte 级别,因此我们别无选择,只能学习计算机可以理解的复杂语言。

在深入学习这些语言之前,你首先需要理解它们的基本结构。

这就像用英语为主要语言时学习日语。你的句子的直觉和结构会完全改变。如果你不知道代词应该放在句子的最后而不是最前面,你就无法形成正确的句子。所以要理清你的算法语法。

为此,学习算法是如何构建的以及架构背后的逻辑。你如何将你的想法翻译成算法词汇?你如何在尝试教计算机之前讲解计算机的语言?

你怎么学习这些呢?

让我们将其拆分成你可以遵循的步骤:

  1. 练习基本编程概念: 确保你对循环、条件语句和基本数据类型感到熟悉。它们就像这门新语言中的名词、动词和形容词。

  2. 深入学习数据结构: 就像句子由单词组成一样,算法是通过数据结构构建的。了解数组、列表、字典、树和图。把它们看作是你的算法词汇。

  3. 理解算法设计: 深入了解排序算法、搜索算法和基本优化技术。这些是你将频繁使用的基本“短语”。

在数据结构方面,我建议你关注以下几个,因为它们是数据科学家使用最多的:

  1. 字符串: 将字符串视为字符的链条,如句子或单词。在编程中,“apple”是由字符组成的字符串。就像我们可以将单词组合成句子一样,你可以将字符串组合成消息。

  2. 列表: 现在,想象你有一个购物清单:牛奶、面包、鸡蛋。这就是一个列表!列表是多功能的,可以存储项。你可以向其中添加、删除甚至排序。这就像有一个播放列表,你可以随意播放歌曲、添加新歌曲或删除你不喜欢的歌曲。

  3. 元组: 将元组视为固定的列表。你列出了你最喜欢的历史前三部电影。那个列表可能不会改变,对吧?元组就是这样的——一旦创建,就不能修改。

  4. 字典: 想象字典是一个存储信息对的容器——一个‘键’和它的‘值’。例如,如果‘name’是键,‘John’可能是它的值。

  5. 数据框: 想象组织一个大型学校同学聚会。你会想要一个表格,包含姓名、联系方式、饮食偏好等。数据框就像这些表格——结构化的数据网格。它们帮助清晰地组织大量信息。

  6. 类: 这部分内容有些抽象,也是我最挣扎的地方。可以把类看作是蓝图。如果你在建房子,蓝图提供了设计:房间数量、厨房大小等。但你可以用同一个蓝图建造许多房子。类似地,在编码中,类是创建对象(特定数据结构)的蓝图。它定义了属性(如颜色或大小)和方法(与该类相关的函数),这些方法可以操作数据。

其他值得探索的数据结构:集合、树和图。

你如何练习你的技能?

从像CodewarsHackerRank这样的编码平台开始,你可以通过不同的算法挑战来动手实践。

这些平台提供从初学者到专家级别的问题,这样你可以在进步的过程中提高自己的技能。

记住,目标不是成为下一个顶级软件工程师, 我们是在做数据科学。所以,不要觉得有压力深入算法。

你主要的关注点应该是掌握基础知识,更重要的是,熟练操作数据结构。 你玩得越多,就会变得越舒适。

#3. 超越导入机器学习算法——理解其结构,你将无可阻挡

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

图片由Markus Winkler拍摄,来源于Unsplash

想象一下: 在我第一个学期,我在调整超参数,但并没有真正理解超参数在特定机器学习算法中的意义。

当我发现机器学习算法时,我意识到它们有各种形态和形式。这意味着我需要了解每个算法的工作原理、何时使用它们以及在使用之前需要验证哪些假设。

唯一的问题是我在学习过程中意识到这一点有点晚了。所以在此期间我花了很长时间抓狂于试图理解那些术语。我不知道如何正确地接近机器学习,但现在我知道了,所以这是我的一些建议。

首先,你需要理解构建机器学习模型时涉及的结构,通常是这样的:

  1. 检查数据分布: 把这看作是观察一个混合水果碗,并弄清楚每种水果的数量。这很重要,因为如果你的数据偏向某一种类型(比如,苹果太多而橙子不足),你的模型可能会非常擅长识别苹果,但对其他水果则不那么熟练。通过检查分布,你可以确保你的模型有一个平衡的“饮食”,从而避免过拟合。

  2. 准备数据: 把这看作是整理你的房间,以便你知道每样东西在哪里。就像一些玩具需要电池才能工作一样,一些机器学习模型需要数据以特定格式呈现。这可能包括独热编码、缩放或规范化数据列。简单来说,就是让数据对模型来说整洁。

  3. 拆分数据: 想象一下为游戏分牌。我们将数据分成训练集、验证集和测试集。这样,我们用一些数据来教模型,并用未见过的数据测试模型,以查看它学得如何。

  4. 训练模型: 这是教学阶段。我们将训练数据输入模型,以便它能够学习模式。如果需要,我们可能会调整模型,以使其更好地适应数据。

  5. 测试模型: 在训练之后,我们查看模型在测试数据上的表现——就像课后的测验一样。

  6. 调整超参数: 想象一下你有一辆可以自定义的玩具车。车轮的大小、颜色或你为车选择的引擎类型就像超参数。你决定并设置它们。玩具车将根据你的设置运行。有像交叉验证和网格搜索这样的工具来帮助你找到最佳设置。要正确调整这些,你需要了解算法如何工作,这意味着要停下来看看我们的好朋友:数学。

  7. 选择正确的指标: 这是关于评估你的模型。根据项目的目标,你将使用不同的“评分卡”或指标。无论是准确性、召回率还是其他指标,了解哪一个与你的目标相符。

确保检查偏差和权衡。 就像你平衡学习和玩耍时间一样,在机器学习中,你经常需要权衡,比如选择一个超级准确但慢的模型和一个更快但更简单的模型。

请记住,这些步骤中的每一个都有其细微差别和细节。你在处理机器学习模型的过程中,越多地工作,越会理解每一步的重要性!

#4. 驯服 Python 野兽及其库

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

作者提供的图像(Midjourney)

当我开始机器学习时,我对编码了解甚少。我不知道在某些情况下需要重新格式化数据,如何导入奇怪类型的文件,将数据转换为不同的数据类型等等。

我花了一些时间才消化完那些术语,期间我已经堆积了其他类型的困扰。现在你已经掌握了计算机语言的基础,下一步就是学习如何应用它们!

这是处理数据时你将最常用的代码函数。确保对它们非常熟悉!

1. 数据输入/输出 读取和写入数据—— 读取 .csv 或 .sql 文件,反向地将数据框写入 .csv 文件。

2. 列和行操作 处理列—— 重命名列、选择和索引列或行、创建新列、修改列内的元素,以及更改它们的格式。

格式化你的数据框或列 — 重置索引,分组数据。

3. 数据形状和重塑 更改 DataFrame 的形状 — 使用连接、合并、拼接、透视和熔化。

4. 缺失数据处理 确定缺失数据,并知道根据研究项目应用哪种技术处理它们。

5. 数据过滤和排序 过滤数据 — 根据某些标准选择行的子集。

排序数据 — 根据一个或多个列将数据按升序或降序排列。

6. 数据总结和统计 数据聚合 — 使用聚合函数如总和、平均数、计数等总结数据。

描述性统计 — 快速统计,如均值、中位数、众数、标准差等。

7. 字符串和数据类型操作 字符串处理 — 处理和清理字符串数据,使用正则表达式,拆分字符串或转换大小写。

类型转换 — 将数据类型转换,例如从字符串到整数或从浮点数到日期。

8. 高级操作 条件操作 — 根据特定条件应用函数或进行更改。

设置和重置多级索引 — 对于时间序列或层次数据非常有用。

9. 自定义函数 制作自己的代码快捷方式,以便操作数据和自动化任务。

最终,在处理数据和进行机器学习时,你总会发现自己在处理库。

想象你在烤蛋糕。你不需要从零开始制作所有东西,而是从商店里买一个蛋糕混合粉。这种混合粉包含了你需要的许多成分,全部打包在一个盒子里,这样可以节省时间和精力。

Python 库就像编程中的蛋糕混合粉。这是一个预先编写的代码集合,你可以用它来帮助你更快、更容易地完成任务。因此,自然地,你需要熟悉这些库并深入了解它们。

这就像是扩展你的朋友圈。

这是你的前 6 个伙伴:

1. Numpy:** 你的数学伙伴。

2. Pandas: 数据整理器。

3. Matplotlib & Seaborn: 可视化数据的艺术双胞胎。

4. Sklearn: 你进行机器学习工具的首选。

5. Statsmodels: 你的统计顾问。

一旦你在机器学习方面变得更熟练,你可能还想了解这些其他库:

1. TensorFlow & PyTorch: 深度学习的动态组合。

2. Beautiful Soup & Scrapy: 你的网页抓取专家。

3. NLTK & SpaCy: 你的语言学专家,用于文本分析和自然语言处理。

每个库都有其专门的领域,所以你不需要精通它们,只需知道它们的存在将来会很有用。

#5. 结交 SQL 朋友

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

照片由 Campaign Creators 提供,来源于 Unsplash

这个在清单中排名靠前。我在 Spotify 担任数据科学家,几乎每天都使用 SQL。这不是一块蛋糕,但我现在可以顺利应对了。以前并非如此。

当我第一次接触 SQL 时,我的大脑进入了过热模式。那时,我还在学习如何在 Spark 上编程,进行云计算和高级机器学习。因此,理解全新的编码范式对我来说要求太高了。这就像同时学习瑞典语和日语。

当我完全掌握 SQL 的直觉时,它的语法和方法与 Python 完全不同,我的课程已经结束了。

如果我在开始数据之旅之前花时间熟悉 SQL,我本可以在课堂上更好地连接点。这也会为我节省大量不必要的压力。

为什么早点学习 SQL 如此重要?

SQL 和 Python 是你在数据科学中需要掌握的动态组合。我们不是在谈论“专业水平”那种层次。不,我们要达到完全的母语者模式。如果你不能将你的想法正确地转化为 SQL 和 Python 语言,那么可以肯定这些想法永远不会实现。

不仅如此,你在思维过程中也会受到限制,因为如果你从未接触过语言的广度,你可能无法想到解决问题的创造性方法。

一位伟大的哲学家路德维希·维特根斯坦曾说过:

“我的语言的限制意味着我的世界的限制”

语言的结构为我们的思维提供了限制和框架,这意味着我们无法构思没有词汇或语言的事物。这同样适用于编程。

记住,这些语言绝非直观,它们是计算机级别的直觉,而不是人类的直觉。否则,我们会用简单的英语与机器对话,而不是使用它们扭曲的外星语言。这可能是它们统治世界的另一个邪恶阴谋。

如何学习 SQL 以及该关注什么?

  1. SQL 介绍: 了解 SQL(结构化查询语言)用于管理和查询关系数据库中的数据。

  2. 基本查询:SELECT语句开始。

    **SELECT** column_name **FROM** table_name

  3. 数据筛选: 使用WHERE子句筛选特定结果。

    **SELECT** column_name **FROM** table_name **WHERE** condition

  4. 排序结果: 使用ORDER BY子句排列数据。

    **SELECT** column_name **FROM** table_name **ORDER BY** another_column_name **DESC/ASC**

  5. 连接表格: 理解JOIN操作来根据相关列组合表格。熟悉INNER JOINLEFT JOINRIGHT JOINFULL JOIN

  6. 日期时间函数: 学习与日期和时间相关的函数和操作。

    → 提取组件:YEAR(), MONTH(), DAY(), 等等

    → 日期算术、格式化和间隔计算。

  7. 聚合: 使用诸如 COUNT()SUM()AVG()MAX()MIN() 的函数对数据进行计算。

  8. 数据分组: 结合使用 GROUP BY 子句与聚合函数进行分组计算。

  9. CTEs(公共表表达式): 通过将复杂查询拆分成可重用的块来简化查询。

    **WITH** cte_name **AS** (SELECT …) SELECT … **FROM** cte_name

  10. 窗口函数: 精通相对于当前行的表行集合上的高级计算。

    → 熟悉诸如 ROW_NUMBER()、LEAD()、LAG() 和 RANK() 等函数

    → 探索 PARTITION BY 来在窗口计算中对数据进行分段

    → 理解运行总计,例如 SUM(column_name) OVER (ORDER BY another_column)

  11. 跨分区查询: 掌握从多个日期时间分区中提取数据的技巧

    **SELECT** **PARSE_DATE**(‘%Y%m%D’, _TABLE_SUFFIX) AS partition_date **FROM** `data.partition_*` 其中 * 是日期时间后缀的占位符

    **WHERE** _TABLE_SUFFIX **BETWEEN** **FORMAT_DATE**(‘%Y%m%d’, **DATE_ADD**(‘2023–09–09’, **INTERVAL** -1 DAY)) AND ‘20230909’

以及更多!

哪里可以练习你的新技能?

许多编码平台提供各种难度的 SQL 挑战,其中包括 SQLZooLeetCodeHackerRankMode Analytics 等。

确保在开始数据科学培训之前复习 SQL 技能,以免在需要与机器学习(及其他范式)同时处理时感到过于困惑!

总结 — 为什么在进入数据科学之前遵循这些步骤至关重要

1. 掌握线性代数与统计学基础

在没有对线性代数和统计学有扎实理解的情况下:

→ 你无法高效处理或解释大数据集。

→ 掌握基础机器学习算法变得具有挑战性。

→ 得出有意义的结论并理解数据验证几乎是不可能的。

→ 你有可能只是一个代码重用者,而不是真正理解你所应用的基础原理。

2. 学习算法框架

在没有对算法框架有扎实理解的情况下:

→ 你将难以从庞大的数据集中提取价值。

→ 将你的想法转化为算法术语将会具有挑战性。

3. 超越算法,理解其结构

机器学习算法在结构和应用上差异很大。

→ 理解每种算法的使用时机和方法至关重要。

→ 掌握构建机器学习模型的结构将帮助你打下高效模型的基础。

4. 精通 Python 及其库

Python 及其库是数据科学家工具包中的关键工具。因此,最好在学习如何掌握它们之前,先熟悉它们。

→ 库通过提供预编写的优化代码来简化任务。

→ 它们加快了那些从零开始编写代码的耗时任务。

5. 亲近 SQL

如果 Python 统治数据世界,那 SQL 也共享这个王冠。

→ 精通 SQL 和 Python 能够让你有效地转化和实现想法。

→ 及早理解 SQL 扩展了你的思维过程,让你在解决问题时更具创造力。

记住维特根斯坦:你的语言的限制就是你世界的限制。

我在数据科学的第一年中经历了很多困难,因此我从中吸取了教训。如果你认真遵循这些步骤,我保证你不会流太多的泪水。祝好运!

我有礼物送给你🎁!

注册我的新闻通讯 K’s DataLadder,你将自动获得我的终极 SQL 备忘单,其中包含我在大公司工作中每天使用的所有查询 + 另一个秘密礼物!

我每周分享成为技术数据科学家的经历,以及实用的技巧、技能和故事,所有这些都是为了帮助你提升——因为没有人真正知道,直到他们身处其中!

如果你还没有做到这一点

  • 订阅我的YouTube频道。新视频很快就会发布!

  • InstagramLinkedInX上关注我,选择最适合你的平台

很快见!

双重机器学习简化版:第一部分 — 基本的因果推断应用

原文:towardsdatascience.com/double-machine-learning-simplified-part-1-basic-causal-inference-applications-3f7afc9852ee?source=collection_archive---------2-----------------------#2023-07-12

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

所有图片由作者提供

学习如何在因果推断任务中利用 DML

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

·

关注 发表在 Towards Data Science ·17 分钟阅读·2023 年 7 月 12 日

本文是2 部分系列中的第一部分,旨在简化和普及双重机器学习。在第一部分中,我们将覆盖双重机器学习的基础知识,以及两个基本的因果推断应用示例(使用 python)。然后,在第二部分中,我们将扩展这些知识,将因果推断问题转化为预测任务,其中我们预测个体级别的处理效果,以辅助决策和数据驱动的目标定位。

统计/机器学习(ML)与因果推断/计量经济学(CI)任务之间的概念性和实践性区别已经存在多年——ML 旨在预测,而 CI 旨在推断处理效果或变量之间的“因果”关系。然而,数据科学家仍然常常从训练的机器学习模型或其他可解释的 ML 方法中得出因果结论。尽管如此,业界和许多学术学科在推动因果声明的严谨性方面取得了显著进展,这也刺激了因果推断领域的广泛讨论。在这一进展中,我们看到了一些惊人的工作,开始弥合 ML 与 CI 之间的概念差距,特别是 CI 工具利用了 ML 方法的强大能力。

本系列的主要动机是使双重机器学习(DML)的使用和应用变得普及,这一方法首次由 Chernozhukov 等人在其开创性论文《用于处理和因果参数的双重机器学习》中介绍,并使数据科学家能够在日常因果推断任务中利用 DML。[1] 为此,我们将首先深入探讨 DML 的基础知识。具体而言,我们将涵盖一些概念/理论基础,包括因果关系的回归框架及Frisch-Waugh-Lovell 定理,然后我们将利用这一框架来发展 DML。最后,我们将展示双重机器学习的两个显著应用:

  1. 在我们的处理过程中趋向于外生性/CIA/可忽略性(尤其是当我们的协变量集具有高维度时)

  2. 在实验数据(随机对照试验(RCTs)或 A/B 测试)中提高精确度和统计功效

如果这些内容对你来说仍感到非常陌生,我推荐查看我的上一篇文章,其中涵盖了因果回归框架和 Frisch-Waugh-Lovell 定理。尽管如此,我会在下面涵盖这些主题,并尽力简化并使其对所有人都易于理解。让我们首先快速概述一下这些理论基础!

因果回归框架与 FWL 定理

确立因果关系的金标准是 RCT 或 A/B 测试,在这些测试中,我们随机分配一部分个体接受处理,T(测试组),而其他个体则不接受处理(对照组)或接受不同的处理(在“A/B”测试中)。为了估计处理对结果y的平均处理效应(ATE),我们可以估计以下双变量线性回归:

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

(1)

由于处理是随机分配的,我们确保处理是外生的;即,独立于误差项ε,因此不存在我们未控制的混杂变量(影响处理和结果的变量)—— cov(T,ε)=0(例如,假设违反情况下,y = 收入 & T = 教育年限,那么我们可以预期例如 IQ 这样的变量会在ε中混杂真实关系)。由于这种独立性,T上的系数估计具有因果解释——ATE:

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

(2) 离散处理

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

(3) 连续处理

当我们处理非实验或观察数据时,几乎总是处理变量不是与ε独立的,或者是内生的——cov(T,ε)≠0,并且存在我们未考虑的混杂变量。换句话说,我们不能再将处理中的真实随机变化与结果解释分开。在这种情况下,简单的双变量回归将因遗漏变量偏倚而导致 ATE 的偏倚估计(β(真实 ATE)+偏倚)。然而,如果我们能控制所有可能的混杂变量,X,以及在使用参数模型时的混杂函数形式,我们可以在我们的处理上实现外生性,或者也称为条件独立假设(CIA),或可忽略性。换句话说,处理中的剩余变化是“好像是随机的”。即,在误差项中没有剩余的混杂因素,或者:

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

(4)

如果外生性成立(X之外没有混杂变量),那么在多元回归中控制X允许T上的系数估计具有类似的 ATE 因果解释:

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

(5)

警告: 控制所有可能的协变量不是最佳实践,而是控制那些被假设/已知会影响结果y和感兴趣的处理T的变量。这是混淆变量的概念。相反,如果yT都影响某个变量,我们不希望控制该变量,因为这可能会引入yT之间的虚假关联。这是碰撞变量的概念。我们将在本文后面展示这一点的实际例子。此外,我们不希望包括那些是我们处理变量的中介变量的变量;即,一个受处理影响进而影响结果的协变量。包括这种中介变量可能会侵蚀我们处理效应的估计。简而言之,我们只希望包括混淆变量(以及可能的非中介和非碰撞预测变量以提高精确度;这将在下面的例子 2 中讨论)。

然而,在实践中,外生性/CIA/可忽略性非常难以获得和证明,因为我们不太可能观察到所有的混淆变量并控制这些混淆变量可能出现的潜在非线性关系。这是 DML 的一个特定动机——然而,让我们首先讨论 FWL 定理,因为这使我们能够理论上开发 DML。

FWL 定理是一个重要的计量经济学定理,它允许我们在上述多重回归(方程 5)中利用以下 3 步程序获得相同的ATE 参数估计β₁,关于处理变量T

  1. 分别对y进行回归X,对T进行回归X

  2. 保存第 1 步的残差——称之为yT

  3. y进行回归T

在准 Python 代码中,

import statsmodels.formula.api as smf

reg_y = smf.ols(formula='y ~ 1 + X', data = df).fit()
reg_T = smf.ols(formula='T ~ 1 + X', data = df).fit()

y_residual = reg_y.resid
T_residual = reg_T.resid

ATE_model = smf.ols(formula='y_residual ~ 1 + T_residual', data = df).fit()

直观地说,FWL 定理将Ty中的变异部分从混淆变量X中分离出来,然后利用剩余的变异来解释关键的关系(即,T如何影响y)。更具体地说,它利用X的一种特殊类型的正交投影矩阵,称为消除矩阵或残差生成矩阵,来残差化Ty。有关 FWL 程序的实际应用,请参见我之前的帖子。该定理对于理解 DML 至关重要。

请注意,我(故意)略过了一些额外的因果推断假设,例如 Positivity/Common Support 和 SUTVA/反事实一致性。一般来说,CIA/可忽略性假设是需要辩护的最常见假设。然而,建议感兴趣的读者熟悉额外的假设。简言之,Positivity 确保我们有与处理过的家庭相似且可比较的未处理家庭,以便进行反事实估计,而 SUTVA 确保没有溢出/网络类型效应(一个个体的处理影响另一个个体)。

双重机器学习… 简化版!

双重机器学习的核心是允许在 FWL 程序的步骤 1) 和 2) 中进行的残差化/正交化使用任何高度灵活的 ML 模型,从而构造一个部分线性模型。也就是说,我们可以通过以下方式估计 ATE:

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

(6)

其中𝑀𝑦MT都是任何用于预测yTML模型,给定混淆因素和/或控制变量X𝑀𝑦MT也被称为“干扰函数”,因为我们正在构造函数来部分去除yT中由 X 解释的变化,这不是主要关注的内容。为了避免过拟合并确保这种方法的稳健性,我们使用交叉验证预测通过样本和交叉拟合。我相信这里再次看到这种程序在准 Python 代码中的示例会很有用:

from sklearn.model_selection import cross_val_predict
import statsmodels.formula.api as smf

M_y = *some ML model*
M_T = *some ML model*

y_residual = df[y] - cross_val_predict(M_y, df[X], df[y], cv=3)
T_residual = df[T] - cross_val_predict(M_T, df[X], df[T], cv=3)

ATE_model = smf.ols(formula='y_residual ~ 1 + T_residual', data = df).fit()

其中 T_residual 上的系数将是我们估计的 ATE,并且围绕我们的估计有渐近正态推断。就这样!

这是 DML 估计 ATE 背后的过程。它使我们的混淆建模具有高度的灵活性和非参数特性,特别是在存在高维协变量的情况下。

我不会深入探讨为什么这有效的技术细节,并且我会将感兴趣的读者引导到原始论文EconML 文档。然而,简而言之,DML 满足一个称为 Neyman 正交性的条件(即,干扰函数在真实值附近的小扰动对矩条件有二阶效应,因此不会影响我们的关键参数估计),这解决了正则化偏差的问题,并且与 DML 中的交叉验证程序结合使用,解决了过拟合偏差,从而确保了该方法的稳健性。

DML 有一些非常酷的扩展将在系列的第二部分中讨论,但现在我们先通过两个应用来查看它的实际效果。

DML 应用

应用 1: 在处理非实验/观察数据时,趋向于外生性/CIA/可忽略性

回顾一下,我们讨论了在没有随机实验数据的情况下,我们必须控制所有潜在的混杂因素,以确保我们获得我们感兴趣的处理的外生性。换句话说,当我们控制了所有潜在的混杂因素时,我们的处理是“如同随机分配”。这里仍然存在两个主要问题:

  1. 了解所有混杂因素并且获取所有这些混杂因素的数据是困难的,在某些情况下甚至是不可能的。解决这个问题涉及对数据生成过程的深入了解,仔细构建因果模型(即,构建一个DAG的同时评估潜在混杂因素并避免碰撞器),以及/或者利用准实验设计。

  2. 如果我们确实处理了第一点,我们仍然需要在使用参数模型(例如在回归框架中)时指定混杂的正确参数形式,包括交互项和高阶项。仅在回归中包含线性项可能不足以控制混杂。这就是 DML 发挥作用的地方;它可以以高度非参数的方式灵活地部分控制混杂。这特别有利于节省数据科学家直接建模混杂的函数形式的麻烦,并使更多的注意力可以集中在识别和测量混杂因素上。让我们看看这是如何工作的!

假设,作为一个高度简化的例子,我们在一家电子商务公司工作,并且我们的任务是估计个人在网站上花费的时间对他们在过去一个月的购买金额或销售额的平均处理效应(ATE)。然而,进一步假设我们只有观察数据可以使用,但我们已经测量了所有潜在的混杂因素(那些影响网站停留时间和销售额的变量)。让这个因果过程通过以下的有向无环图(DAG)进行描述:

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

假设数据生成过程如下(请注意,所有值和数据都是为了演示目的而随意选择和生成的,因此不一定代表真实世界直观的很大程度,除非我们对 ATE 的估计):

import numpy as np
import pandas as pd

# Sample Size
N = 100_000

# Observed Confounders (Age, Number of Social Media Accounts, & Years Member on Website)
age = np.random.randint(low=18,high=75,size=N)
num_social_media_profiles = np.random.choice([0,1,2,3,4,5,6,7,8,9,10], size = N)
yr_membership = np.random.choice([0,1,2,3,4,5,6,7,8,9,10], size = N)

# Additional Covariates (Arbitrary Z)
Z = np.random.normal(loc=50, scale = 25, size = N)

# Error Terms
ε_1 = np.random.normal(loc=20,scale=5,size=N)
ε_2 = np.random.normal(loc=40,scale=15,size=N)

# Treatment DGP (T = g(X) + ε) - Hrs spent on website in past month
time_on_website = np.maximum(10
                             - 0.01*age 
                             - 0.001*age**2 
                             + num_social_media_profiles 
                             - 0.01 * num_social_media_profiles**2
                             - 0.01*(age * num_social_media_profiles)
                             + 0.2 * yr_membership
                             + 0.001 * yr_membership**2
                             - 0.01 * (age * yr_membership)
                             + 0.2 * (num_social_media_profiles * yr_membership)
                             + 0.01 * (num_social_media_profiles * np.log(age) * age * yr_membership**(1/2))
                             + ε_1
                               ,0)

# Outcome DGP (y = f(T,X,Z) + ε) - Sales in past month
sales = np.maximum(25
                   +  5 * time_on_website # Simulated ATE = $5
                   - 0.1*age 
                   - 0.001*age**2 
                   + 8 * num_social_media_profiles 
                   - 0.1 * num_social_media_profiles**2
                   - 0.01*(age * num_social_media_profiles)
                   + 2 * yr_membership
                   + 0.1 * yr_membership**2
                   - 0.01 * (age * yr_membership)
                   + 3 * (num_social_media_profiles * yr_membership)
                   + 0.1 * (num_social_media_profiles * np.log(age) * age * yr_membership**(1/2))
                   + 0.5 * Z
                   + ε_2
                     ,0)

collider = np.random.normal(loc=100, scale=50, size=N) + 2*sales + 7*time_on_website

df = pd.DataFrame(np.array([sales,time_on_website,age,num_social_media_profiles,yr_membership,Z]).T
                  ,columns=["sales","time_on_website","age","num_social_media_profiles","yr_membership","Z"])

根据构建,我们的兴趣处理(过去一个月在网站上花费的时间)和我们的结果(过去一个月的销售额)有以下混杂因素:年龄、社交媒体账户数量和网站会员年限,这种混杂是任意非线性的。此外,我们可以看到构建的ATE 真实值是 $5(在上面的销售 DGP 中说明)。也就是说,平均而言,每增加一小时的在网站上花费的时间,个人会多花 $5。 注意,我们还包括了一个碰撞器变量(受网站花费时间和销售额影响的变量),该变量将在下面的演示中用于说明这种偏差如何影响 ATE。

为了展示 DML 灵活部分化高度非线性混杂因素的能力,我们将运行以下 4 个模型:

  1. 销售(y)对网站上花费的时间(T)进行天真的 OLS 回归

  2. 销售(y)对网站上花费的时间(T)及所有混杂因素的线性项进行多重 OLS 回归

  3. 使用 DML 残差化过程的 OLS 回归,详见公式 (5)

  4. 包括碰撞器变量的 DML 残差化过程的 OLS 回归

代码如下:

import statsmodels.formula.api as smf
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import cross_val_predict

# 1 - Naive OLS
naive_regression = smf.ols(formula=’sales ~ 1 + time_on_website’,data=df).fit()

# 2 - Multiple OLS
multiple_regression = smf.ols(formula=’sales ~ 1 + time_on_website + age + num_social_media_profiles + yr_membership’,data=df).fit()

# 3 - DML Procedure
M_sales = GradientBoostingRegressor()
M_time_on_website = GradientBoostingRegressor()

df[‘residualized_sales’] = df["sales"] - cross_val_predict(M_sales, df[["age","num_social_media_profiles","yr_membership"]], df[‘sales’], cv=3)
df[‘residualized_time_on_website’] = df[‘time_on_website’] - cross_val_predict(M_time_on_website, df[["age","num_social_media_profiles","yr_membership"]], df[‘time_on_website’], cv=3)

DML_model = smf.ols(formula=’residualized_sales ~ 1 + residualized_time_on_website’, data = df).fit()

# 4 - DML Procedure w/ Collider
M_sales = GradientBoostingRegressor()
M_time_on_website = GradientBoostingRegressor()

df[‘residualized_sales’] = df["sales"] - cross_val_predict(M_sales, df[["age","num_social_media_profiles","yr_membership","collider"]], df[‘sales’], cv=3)
df[‘residualized_time_on_website’] = df['time_on_website'] - cross_val_predict(M_time_on_website, df[["age","num_social_media_profiles","yr_membership", "collider"]], df['time_on_website'], cv=3)

DML_model_collider = smf.ols(formula='residualized_sales ~ 1 + residualized_time_on_website', data = df).fit()

对应的结果(见附录中的代码以创建此表):

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

回忆一下我们模拟的 ATE 真实值是**$5**。注意,唯一能够捕捉这个值的模型是 DML 过程!我们可以看到,天真的模型在估计中有显著的正偏差,而仅对混杂因素的线性项进行控制的多重回归则稍微减少了这种偏差。此外,带有碰撞器的 DML 过程展示了一个负偏差;通过在我们的碰撞器 DGP 中求解销售额,可以松散地演示/观察到销售与我们处理之间的这种负相关。

collider = 100 + 2*sales + 7*time_on_website

# Note the negative relationship between sales and time_on_website here
sales = (collider - 100 - 7*time_on_website)/2

这些结果展示了使用灵活的非参数 ML 模型在 DML 过程中去除混杂的明确能力!相当令人满意,对吧? DML 去除了对混杂 DGP 的正确参数化规格的必要性(前提是所有混杂因素都被控制)!

细心的读者会注意到,我们在销售的生成过程中包括了任意的协变量 Z。然而,注意到 Z 并不会直接影响在网站上花费的时间,因此它不符合混杂因素的定义,因此对结果没有影响(除了可能提高估计的精确度——见应用程序 2)

应用程序 2: 提高实验数据的精确度和统计效能(随机对照试验 (RCTs) 或 A/B 测试)

一个常见的误解是,如果一个实验有一个足够大的样本量,就可以获得足够的统计功效来准确测量感兴趣的处理。然而,确定实验中的统计功效以及最终 ATE 估计精度的一个常被忽视的因素是你试图测量的结果的变异性。

例如,假设我们对某个特定广告对个人购买金额的影响感兴趣,并且我们预计效果较小,但并非微不足道——例如,ATE 为$5。然而,假设个人销售额的标准差非常大……可能在$100 甚至$1000 的范围内。在这种情况下,由于这种高变异性,准确捕捉 ATE 可能会非常困难——也就是说,我们的估计可能会获得非常低的精度(大的标准误差)。然而,捕捉到$5 的 ATE 可能在经济上是有意义的(如果我们对 100,000 户家庭进行实验,这可能达到$500,000)。这就是 DML 能够发挥作用的地方。在我们展示实际操作之前,让我们先查看方程(1)中简单回归的 ATE 估计的标准误差公式:

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

(7)

在这里,我们观察到我们估计的标准误差直接受到残差(ε)大小的影响。那么这告诉我们什么呢?如果我们的处理是随机化的,我们可以在多重普通最小二乘法(OLS)或双重机器学习(DML)程序中包含协变量,这样做的目的是减少我们结果的变异性,而不是获得外生性。更具体地说,我们可以包含那些对结果有强预测作用的变量,从而减少残差,并因此降低我们估计的标准误差。让我们来看一下这个实际应用。首先,假设以下有向无环图(DAG)(注意处理是随机化的,所以没有混杂因素):

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

此外,假设以下数据生成过程(DGP):

import numpy as np
import pandas as pd

# Sample Size
N = 100_000

# Observed Confounders (Age, Number of Social Media Accounts, & Years Member on Website)
age = np.random.randint(low=18,high=75,size=N)
num_social_media_profiles = np.random.choice([0,1,2,3,4,5,6,7,8,9,10], size = N)
yr_membership = np.random.choice([0,1,2,3,4,5,6,7,8,9,10], size = N)

# Additional Covariates (Arbitrary Z)
Z = np.random.normal(loc=50, scale = 25, size = N)

# Error Term
ε = np.random.normal(loc=40,scale=15,size=N)

# Randomized Treatment (T) - Advertisement Exposure
advertisement_exposure = np.random.choice([0,1],size=N,p=[.5,.5])

# Outcome (y = f(T,X,Z) + ε) - Sales in past month
sales = np.maximum(500
                   +  5 * advertisement_exposure # Ground Truth ATE of $5
                   - 10*age 
                   - 0.05*age**2 
                   + 15 * num_social_media_profiles 
                   - 0.01 * num_social_media_profiles**2
                   - 0.5*(age * num_social_media_profiles)
                   + 20 * yr_membership
                   + 0.5 * yr_membership**2
                   - 0.8 * (age * yr_membership)
                   + 5 * (num_social_media_profiles * yr_membership)
                   + 0.8 * (num_social_media_profiles * np.log(age) * age * yr_membership**(1/2))
                   + 15 * Z
                   + 2 * Z**2
                   + ε
                     ,0)

df = pd.DataFrame(np.array([sales,advertisement_exposure,age,num_social_media_profiles,yr_membership, Z]).T
                  ,columns=["sales","advertisement_exposure","age","num_social_media_profiles","yr_membership","Z"])

在这里,我们再次人工模拟真实的 ATE 为$5。不过这次,我们生成的销售数据具有非常大的方差,因此难以检测到$5 的 ATE。

为了演示在 DML 程序中包含那些对我们的结果有强预测作用的协变量如何大大提高 ATE 估计的精度,我们将运行以下三个模型:

  1. 销售(y)对随机广告暴露(T)的简单 OLS

  2. 销售(y)对随机广告暴露(T)及所有销售预测变量的线性项的多重 OLS

  3. 使用 DML 残差化程序的 OLS,如方程(5)所述

代码如下:

import statsmodels.formula.api as smf
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import cross_val_predict

# 1 - Naive OLS
naive_regression = smf.ols(formula=“sales ~ 1 + advertisement_exposure”,data=df).fit()

# 2 - Multiple OLS
multiple_regression = smf.ols(formula=“sales ~ 1 + advertisement_exposure + age + num_social_media_profiles + yr_membership + Z”,data=df).fit()

# 3 - DML Procedure
M_sales = GradientBoostingRegressor()
M_advertisement_exposure = GradientBoostingClassifier() # Note binary treatment 

df[‘residualized_sales’] = df["sales"] - cross_val_predict(M_sales, df[["age","num_social_media_profiles","yr_membership","Z"]], df[‘sales’], cv=3)
df['residualized_advertisement_exposure'] = df['advertisement_exposure'] - cross_val_predict(M_advertisement_exposure, df[["age","num_social_media_profiles","yr_membership", "Z"]], df['advertisement_exposure'], cv=3, method = 'predict_proba')[:,0]

DML_model = smf.ols(formula='residualized_sales ~ 1 + residualized_advertisement_exposure', data = df).fit()

您可能会注意到我们还包括了用于预测广告曝光的 ML 模型。这主要是为了与 DML 程序保持一致。 然而,因为我们知道广告曝光是随机的,这并非完全必要,但我建议验证我们的示例模型确实无法学到任何东西(即,在我们的案例中,它应该为所有个体预测 ~0.50 的概率,因此残差将保持与初始处理分配相同的变异)。

这些模型的相应结果(请参阅附录中的代码以创建此表):

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

首先,请注意,由于处理是随机分配的,因此上面没有发生真正的混淆。 (1) 和 (2) 中的 ATE 估计误差是由于不精确的估计(见括号中的大标准误差)直接导致的。 注意随着我们从 (1) 到 (3) 迁移,标准误差如何变小(精度提高),其中 DML 程序具有最精确的估计。 请注意上面红框中的“残差标准误差”行。 我们可以看到 DML 程序通过从我们结果的 ML 模型(销售)中的预测因子中部分消除可学习的变异,显著减少了 ATE 模型残差的变异。 再次,在这个例子中,我们看到 DML 是唯一一个能够获得真实 ATE 的模型!

这些结果展示了在实验环境中使用 DML 以提高统计能力和 ATE 估计精度的好处。 具体而言,这可以应用于 RCT 或 A/B 测试环境,其中结果的变异非常大和/或在精确估计方面遇到困难,并且可以访问强有力的结果预测因子。

结论

就这样——双重机器学习简化版(希望如此)! 感谢您花时间阅读我的文章。 我希望这篇文章能为您提供对 DML 基础知识的清晰而直观的理解,以及DML 所具备的真正力量,以及如何在日常因果推断任务中利用 DML。

敬请关注第二部分系列,我们将深入探讨一些非常酷的 DML 扩展,这些扩展将我们的因果推断问题转化为预测任务,我们超越 ATE,预测个体级别的处理效应,以辅助决策和数据驱动的目标。

一如既往,我希望你们读这篇文章时和我写这篇文章时一样愉快!

附录

创建漂亮的表格:

# Example 1
file = open('Example 1.html','w')

order = ['time_on_website','residualized_time_on_website','age','num_social_media_profiles','yr_membership','Intercept']
rename = {'time_on_website':'Treatment: Hours on Website','residualized_time_on_website':'Residualized Treatment: Hours on Website','age':'Age',
          'num_social_media_profiles':"# of Social Media Profiles", "yr_membership":"Years of Membership"}
columns = ['Naive OLS','Multiple OLS','DML','DML w/ Collider']

regtable = Stargazer([naive_regression, multiple_regression, DML_model, DML_model_collider])
regtable.covariate_order(order)
regtable.custom_columns(columns,[1,1,1,1])
regtable.rename_covariates(rename)
regtable.show_degrees_of_freedom(False)
regtable.title('Example 1: Obtaining Exogeneity w/ DML')

file.write(regtable.render_html())
file.close()

# Example 2
file = open('Example 2.html','w')

order = ['advertisement_exposure','residualized_advertisement_exposure','age','num_social_media_profiles','yr_membership','Intercept']
rename = {'advertisement_exposure':'Treatment: Exposure to Advertisement','residualized_advertisement_exposure':'Residualized Treatment: Exposure to Advertisement','age':'Age',
          'num_social_media_profiles':"# of Social Media Profiles", "yr_membership":"Years of Membership"}
columns = ['Naive OLS','Multiple OLS','DML']

regtable = Stargazer([naive_regression, multiple_regression, DML_model])
regtable.covariate_order(order)
regtable.custom_columns(columns,[1,1,1])
regtable.rename_covariates(rename)
regtable.show_degrees_of_freedom(False)
regtable.title('Example 2: Improving Statistical Power in RCT')

file.write(regtable.render_html())
file.close()

资源

[1] V. Chernozhukov, D. Chetverikov, M. Demirer, E. Duflo, C. Hansen, 和 a. W. Newey. 双重机器学习用于处理和因果参数。ArXiv 电子印刷品,2016 年 7 月。

通过这个 GitHub 仓库访问所有代码: github.com/jakepenzak/Blog-Posts

感谢你阅读我的文章!我在 Medium 上的文章旨在探讨利用 计量经济学 统计学/机器学习 技术的现实世界和理论应用。此外,我还致力于通过理论和模拟提供有关各种方法论的理论基础的文章。最重要的是,我写作是为了学习和帮助他人学习!我希望使复杂的主题对所有人稍微更容易理解。如果你喜欢这篇文章,请考虑 关注我在 Medium 上的账号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值