Machine Learning Mastery 数据准备教程(一)

原文:Machine Learning Mastery

协议:CC BY-NC-SA 4.0

如何用 Python 进行机器学习的数据清洗

原文:https://machinelearningmastery.com/basic-data-cleaning-for-machine-learning/

最后更新于 2020 年 6 月 30 日

数据清理是任何机器学习项目中至关重要的一步。

在表格数据中,有许多不同的统计分析和数据可视化技术可用于浏览数据,以确定您可能想要执行的数据清理操作。

在跳到复杂的方法之前,您可能应该在每个机器学习项目中执行一些非常基本的数据清理操作。这些是如此基本,以至于它们经常被经验丰富的机器学习从业者所忽视,但又是如此关键,以至于如果跳过,模型可能会崩溃或报告过于乐观的表现结果。

在本教程中,您将发现应该始终对数据集执行的基本数据清理。

完成本教程后,您将知道:

  • 如何识别和移除只有一个值的列变量?
  • 如何识别和考虑唯一值很少的列变量?
  • 如何识别和删除包含重复观察的行?

用我的新书机器学习的数据准备启动你的项目,包括分步教程和所有示例的 Python 源代码文件。

我们开始吧。

  • 2020 年 4 月更新:增加了数据集和变量阈值部分。
  • 2020 年 5 月更新:增加了引用和书籍参考。

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

机器学习中必须执行的基本数据清理
图片由艾伦·麦格雷戈提供,保留部分权利。

教程概述

本教程分为七个部分;它们是:

  1. 杂乱的数据集
  2. 标识包含单个值的列
  3. 删除包含单个值的列
  4. 考虑值很少的列
  5. 删除差异较小的列
  6. 识别包含重复数据的行
  7. 删除包含重复数据的行

杂乱的数据集

数据清理是指识别和纠正数据集中可能对预测模型产生负面影响的错误。

数据清理是指检测和修复数据中错误的各种任务和活动。

—第十三页,数据清理,2019。

尽管数据清理至关重要,但它并不令人兴奋,也不涉及花哨的技术。只是对数据集有很好的了解。

清理数据并不是最有魅力的任务,但却是数据争论的重要部分。[……]知道如何正确地清理和组合数据将使您与您所在领域的其他人相距甚远。

—第 149 页,与 Python 的数据角力,2016。

数据集中存在多种类型的错误,尽管一些最简单的错误包括不包含太多信息的列和重复的行。

在我们深入识别和纠正混乱的数据之前,让我们定义一些混乱的数据集。

我们将使用两个数据集作为本教程的基础,漏油数据集鸢尾花数据集

漏油数据集

所谓的“漏油”数据集是标准的机器学习数据集。

该任务包括预测该区块是否含有石油泄漏,例如,非法或意外倾倒在海洋中的石油,给出一个矢量,描述一个卫星图像区块的内容。

有 937 例。每个案例由 48 个数字计算机视觉衍生特征、一个补丁编号和一个类别标签组成。

正常情况下,没有漏油被指定为 0 级标签,而漏油被指定为 1 级标签。无漏油 896 例,漏油 41 例。

您可以在这里访问整个数据集:

查看文件的内容。

文件的前几行应该如下所示:

1,2558,1506.09,456.63,90,6395000,40.88,7.89,29780,0.19,214.7,0.21,0.26,0.49,0.1,0.4,99.59,32.19,1.84,0.16,0.2,87.65,0,0.47,132.78,-0.01,3.78,0.22,3.2,-3.71,-0.18,2.19,0,2.19,310,16110,0,138.68,89,69,2850,1000,763.16,135.46,3.73,0,33243.19,65.74,7.95,1
2,22325,79.11,841.03,180,55812500,51.11,1.21,61900,0.02,901.7,0.02,0.03,0.11,0.01,0.11,6058.23,4061.15,2.3,0.02,0.02,87.65,0,0.58,132.78,-0.01,3.78,0.84,7.09,-2.21,0,0,0,0,704,40140,0,68.65,89,69,5750,11500,9593.48,1648.8,0.6,0,51572.04,65.73,6.26,0
3,115,1449.85,608.43,88,287500,40.42,7.34,3340,0.18,86.1,0.21,0.32,0.5,0.17,0.34,71.2,16.73,1.82,0.19,0.29,87.65,0,0.46,132.78,-0.01,3.78,0.7,4.79,-3.36,-0.23,1.95,0,1.95,29,1530,0.01,38.8,89,69,1400,250,150,45.13,9.33,1,31692.84,65.81,7.84,1
4,1201,1562.53,295.65,66,3002500,42.4,7.97,18030,0.19,166.5,0.21,0.26,0.48,0.1,0.38,120.22,33.47,1.91,0.16,0.21,87.65,0,0.48,132.78,-0.01,3.78,0.84,6.78,-3.54,-0.33,2.2,0,2.2,183,10080,0,108.27,89,69,6041.52,761.58,453.21,144.97,13.33,1,37696.21,65.67,8.07,1
5,312,950.27,440.86,37,780000,41.43,7.03,3350,0.17,232.8,0.15,0.19,0.35,0.09,0.26,289.19,48.68,1.86,0.13,0.16,87.65,0,0.47,132.78,-0.01,3.78,0.02,2.28,-3.44,-0.44,2.19,0,2.19,45,2340,0,14.39,89,69,1320.04,710.63,512.54,109.16,2.58,0,29038.17,65.66,7.35,0
...

我们可以看到第一列包含补丁号的整数。我们还可以看到,计算机视觉导出的特征是实值的,具有不同的比例,例如第二列中的千分之一和其他列中的分数。

此数据集包含的列具有非常少的唯一值,这为数据清理提供了良好的基础。

鸢尾花数据集

所谓的“鸢尾花”数据集是另一个标准的机器学习数据集。

该数据集包括预测花的种类,给出鸢尾花的厘米测量值。

这是一个多类分类问题。每个班级的观察人数是平衡的。有 150 个观测值,4 个输入变量和 1 个输出变量。

您可以在这里访问整个数据集:

查看文件的内容。

文件的前几行应该如下所示:

5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
4.6,3.1,1.5,0.2,Iris-setosa
5.0,3.6,1.4,0.2,Iris-setosa
...

我们可以看到,所有四个输入变量都是数字,目标类变量是代表鸢尾花种类的字符串。

此数据集包含重复的行,这为数据清理提供了良好的基础。

标识包含单个值的列

只有一个观察值或值的列可能对建模没有用。

这些列或预测因子被称为零方差预测因子,就好像我们测量了方差(均值的平均值),它将为零。

当一个预测值包含单个值时,我们称之为零方差预测值,因为预测值确实没有变化。

—第 96 页,特征工程与选择,2019。

这里,单个值意味着该列的每一行都有相同的值。例如,列 X1 对于数据集中的所有行都具有值 1.0:

X1
1.0
1.0
1.0
1.0
1.0
...

所有行只有一个值的列不包含任何建模信息。

根据数据准备和建模算法的选择,具有单一值的变量也会导致错误或意外结果。

您可以使用 unique() NumPy 函数检测具有此属性的行,该函数将报告每列中唯一值的数量。

以下示例加载了包含 50 个变量的漏油类别数据集,并总结了每列的唯一值的数量。

# summarize the number of unique values for each column using numpy
from urllib.request import urlopen
from numpy import loadtxt
from numpy import unique
# define the location of the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/oil-spill.csv'
# load the dataset
data = loadtxt(urlopen(path), delimiter=',')
# summarize the number of unique values in each column
for i in range(data.shape[1]):
	print(i, len(unique(data[:, i])))

运行该示例直接从 URL 加载数据集,并为每列打印唯一值的数量。

我们可以看到,列索引 22 只有一个值,应该删除。

0 238
1 297
2 927
3 933
4 179
5 375
6 820
7 618
8 561
9 57
10 577
11 59
12 73
13 107
14 53
15 91
16 893
17 810
18 170
19 53
20 68
21 9
22 1
23 92
24 9
25 8
26 9
27 308
28 447
29 392
30 107
31 42
32 4
33 45
34 141
35 110
36 3
37 758
38 9
39 9
40 388
41 220
42 644
43 649
44 499
45 2
46 937
47 169
48 286
49 2

一个更简单的方法是使用 nunique() Pandas 函数,它为你做艰苦的工作。

下面是使用熊猫函数的同一个例子。

# summarize the number of unique values for each column using numpy
from pandas import read_csv
# define the location of the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/oil-spill.csv'
# load the dataset
df = read_csv(path, header=None)
# summarize the number of unique values in each column
print(df.nunique())

运行该示例,我们得到相同的结果,列索引,以及每列的唯一值的数量。

0     238
1     297
2     927
3     933
4     179
5     375
6     820
7     618
8     561
9      57
10    577
11     59
12     73
13    107
14     53
15     91
16    893
17    810
18    170
19     53
20     68
21      9
22      1
23     92
24      9
25      8
26      9
27    308
28    447
29    392
30    107
31     42
32      4
33     45
34    141
35    110
36      3
37    758
38      9
39      9
40    388
41    220
42    644
43    649
44    499
45      2
46    937
47    169
48    286
49      2
dtype: int64

删除包含单个值的列

可能应该从数据集中删除具有单个值的变量或列。

…简单地去掉零方差预测因子。

—第 96 页,特征工程与选择,2019。

从 NumPy 数组或 Pandas 数据框中移除列相对容易。

一种方法是记录所有具有单一唯一值的列,然后通过调用 drop()函数从 Pandas DataFrame 中删除它们。

下面列出了完整的示例。

# delete columns with a single unique value
from pandas import read_csv
# define the location of the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/oil-spill.csv'
# load the dataset
df = read_csv(path, header=None)
print(df.shape)
# get number of unique values for each column
counts = df.nunique()
# record columns to delete
to_del = [i for i,v in enumerate(counts) if v == 1]
print(to_del)
# drop useless columns
df.drop(to_del, axis=1, inplace=True)
print(df.shape)

运行该示例首先加载数据集,并报告行数和列数。

计算每一列的唯一值的数量,并且识别具有单个唯一值的那些列。在这种情况下,列索引为 22。

然后从数据框中删除已识别的列,并报告数据框中的行数和列数以确认更改。

(937, 50)
[22]
(937, 49)

考虑值很少的列

在前一节中,我们看到示例数据集中的一些列几乎没有唯一值。

例如,有些列只有 2、4 和 9 个唯一值。这可能对序数或分类变量有意义。在这种情况下,数据集只包含数字变量。因此,一列中只有 2、4 或 9 个唯一的数值可能会令人惊讶。

我们可以将这些列或预测器称为接近零的方差预测器,因为它们的方差不是零,而是非常小的接近零的数字。

…在重采样过程中接近零的方差预测值或有可能接近零的方差。这些预测值几乎没有唯一值(例如二进制伪变量的两个值),并且在数据中很少出现。

—第 96-97 页,特征工程与选择,2019。

这些列可能有助于也可能没有助于模型的技巧。我们不能假设它们对建模没有用。

虽然接近零方差的预测因子可能包含很少有价值的预测信息,但我们可能不希望过滤掉这些信息。

—第 97 页,特征工程与选择,2019 年。

根据数据准备和建模算法的选择,数值很少的变量也会导致错误或意外结果。例如,我看到它们在使用幂变换进行数据准备时,以及在拟合假设“合理的”数据概率分布的线性模型时,会导致错误。

为了帮助突出显示这种类型的列,可以计算每个变量的唯一值的数量占数据集中总行数的百分比。

让我们使用 NumPy 手动完成这项工作。下面列出了完整的示例。

# summarize the percentage of unique values for each column using numpy
from urllib.request import urlopen
from numpy import loadtxt
from numpy import unique
# define the location of the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/oil-spill.csv'
# load the dataset
data = loadtxt(urlopen(path), delimiter=',')
# summarize the number of unique values in each column
for i in range(data.shape[1]):
	num = len(unique(data[:, i]))
	percentage = float(num) / data.shape[0] * 100
	print('%d, %d, %.1f%%' % (i, num, percentage))

运行该示例会报告列索引和每列的唯一值的数量,然后是数据集中所有行的唯一值的百分比。

在这里,我们可以看到一些列的唯一值百分比非常低,例如低于 1%。

0, 238, 25.4%
1, 297, 31.7%
2, 927, 98.9%
3, 933, 99.6%
4, 179, 19.1%
5, 375, 40.0%
6, 820, 87.5%
7, 618, 66.0%
8, 561, 59.9%
9, 57, 6.1%
10, 577, 61.6%
11, 59, 6.3%
12, 73, 7.8%
13, 107, 11.4%
14, 53, 5.7%
15, 91, 9.7%
16, 893, 95.3%
17, 810, 86.4%
18, 170, 18.1%
19, 53, 5.7%
20, 68, 7.3%
21, 9, 1.0%
22, 1, 0.1%
23, 92, 9.8%
24, 9, 1.0%
25, 8, 0.9%
26, 9, 1.0%
27, 308, 32.9%
28, 447, 47.7%
29, 392, 41.8%
30, 107, 11.4%
31, 42, 4.5%
32, 4, 0.4%
33, 45, 4.8%
34, 141, 15.0%
35, 110, 11.7%
36, 3, 0.3%
37, 758, 80.9%
38, 9, 1.0%
39, 9, 1.0%
40, 388, 41.4%
41, 220, 23.5%
42, 644, 68.7%
43, 649, 69.3%
44, 499, 53.3%
45, 2, 0.2%
46, 937, 100.0%
47, 169, 18.0%
48, 286, 30.5%
49, 2, 0.2%

我们可以更新示例,只汇总那些唯一值小于行数 1%的变量。

# summarize the percentage of unique values for each column using numpy
from urllib.request import urlopen
from numpy import loadtxt
from numpy import unique
# define the location of the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/oil-spill.csv'
# load the dataset
data = loadtxt(urlopen(path), delimiter=',')
# summarize the number of unique values in each column
for i in range(data.shape[1]):
	num = len(unique(data[:, i]))
	percentage = float(num) / data.shape[0] * 100
	if percentage < 1:
		print('%d, %d, %.1f%%' % (i, num, percentage))

运行该示例,我们可以看到 50 个变量中有 11 个变量的唯一值小于行数的 1%。

这并不意味着应该删除这些行和列,但它们需要进一步关注。

例如:

  • 也许唯一的值可以被编码为序数?
  • 也许唯一的值可以被编码为分类值?
  • 也许将模型技能与从数据集中移除的每个变量进行比较?
21, 9, 1.0%
22, 1, 0.1%
24, 9, 1.0%
25, 8, 0.9%
26, 9, 1.0%
32, 4, 0.4%
36, 3, 0.3%
38, 9, 1.0%
39, 9, 1.0%
45, 2, 0.2%
49, 2, 0.2%

例如,如果我们想删除唯一值小于 1%行的所有 11 列;下面的例子演示了这一点。

# delete columns where number of unique values is less than 1% of the rows
from pandas import read_csv
# define the location of the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/oil-spill.csv'
# load the dataset
df = read_csv(path, header=None)
print(df.shape)
# get number of unique values for each column
counts = df.nunique()
# record columns to delete
to_del = [i for i,v in enumerate(counts) if (float(v)/df.shape[0]*100) < 1]
print(to_del)
# drop useless columns
df.drop(to_del, axis=1, inplace=True)
print(df.shape)

运行该示例首先加载数据集,并报告行数和列数。

计算每列的唯一值的数量,并且识别那些唯一值的数量少于行的 1%的列。在这种情况下,11 列。

然后从数据框中删除已识别的列,并报告数据框中的行数和列数以确认更改。

(937, 50)
[21, 22, 24, 25, 26, 32, 36, 38, 39, 45, 49]
(937, 39)

删除差异较小的列

移除几乎没有唯一值的列的另一种方法是考虑列的方差。

回想一下方差是对一个变量计算的统计量,作为样本值与平均值的平均平方差。

方差可以用作识别要从数据集中移除的列的过滤器。单个值的列的方差为 0.0,唯一值很少的列的方差值很小。

Sklearn 库中的 VarianceThreshold 类支持这种类型的特征选择。可以创建类的一个实例,指定“阈值”参数,该参数默认为 0.0 以删除具有单个值的列。

然后,可以通过调用 fit_transform() 函数来拟合数据集并将其应用于数据集,以创建数据集的转换版本,其中方差低于阈值的列已被自动移除。

...
# define the transform
transform = VarianceThreshold()
# transform the input data
X_sel = transform.fit_transform(X)

我们可以在漏油数据集上对此进行如下演示:

# example of apply the variance threshold
from pandas import read_csv
from sklearn.feature_selection import VarianceThreshold
# define the location of the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/oil-spill.csv'
# load the dataset
df = read_csv(path, header=None)
# split data into inputs and outputs
data = df.values
X = data[:, :-1]
y = data[:, -1]
print(X.shape, y.shape)
# define the transform
transform = VarianceThreshold()
# transform the input data
X_sel = transform.fit_transform(X)
print(X_sel.shape)

运行该示例首先加载数据集,然后应用转换来移除方差为 0.0 的所有列。

数据集的形状是在转换前后报告的,我们可以看到所有值都相同的单个列已经被移除。

(937, 49) (937,)
(937, 48)

我们可以扩展这个例子,看看当我们使用不同的阈值时会发生什么。

我们可以定义从 0.0 到 0.5 的阈值序列,步长为 0.05,例如 0.0、0.05、0.1 等。

...
# define thresholds to check
thresholds = arange(0.0, 0.55, 0.05)

然后,我们可以报告每个给定阈值的转换数据集中的要素数量。

...
# apply transform with each threshold
results = list()
for t in thresholds:
	# define the transform
	transform = VarianceThreshold(threshold=t)
	# transform the input data
	X_sel = transform.fit_transform(X)
	# determine the number of input features
	n_features = X_sel.shape[1]
	print('>Threshold=%.2f, Features=%d' % (t, n_features))
	# store the result
	results.append(n_features)

最后,我们可以绘制结果。

将这些联系在一起,下面列出了将方差阈值与所选特征的数量进行比较的完整示例。

# explore the effect of the variance thresholds on the number of selected features
from numpy import arange
from pandas import read_csv
from sklearn.feature_selection import VarianceThreshold
from matplotlib import pyplot
# define the location of the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/oil-spill.csv'
# load the dataset
df = read_csv(path, header=None)
# split data into inputs and outputs
data = df.values
X = data[:, :-1]
y = data[:, -1]
print(X.shape, y.shape)
# define thresholds to check
thresholds = arange(0.0, 0.55, 0.05)
# apply transform with each threshold
results = list()
for t in thresholds:
	# define the transform
	transform = VarianceThreshold(threshold=t)
	# transform the input data
	X_sel = transform.fit_transform(X)
	# determine the number of input features
	n_features = X_sel.shape[1]
	print('>Threshold=%.2f, Features=%d' % (t, n_features))
	# store the result
	results.append(n_features)
# plot the threshold vs the number of selected features
pyplot.plot(thresholds, results)
pyplot.show()

运行该示例首先加载数据,并确认原始数据集有 49 列。

接下来,将变量阈值应用于值从 0.0 到 0.5 的原始数据集,并报告应用变换后剩余的特征数量。

我们可以看到,数据集中的要素数量从未更改数据中的 49 个快速下降到阈值为 0.15 的 35 个。后来下降到 31 个(删除了 18 列),阈值为 0.5。

(937, 49) (937,)
>Threshold=0.00, Features=48
>Threshold=0.05, Features=37
>Threshold=0.10, Features=36
>Threshold=0.15, Features=35
>Threshold=0.20, Features=35
>Threshold=0.25, Features=35
>Threshold=0.30, Features=35
>Threshold=0.35, Features=35
>Threshold=0.40, Features=35
>Threshold=0.45, Features=33
>Threshold=0.50, Features=31

然后创建一个折线图,显示阈值和变换数据集中要素数量之间的关系。

我们可以看到,即使使用 0.15 到 0.4 之间的小阈值,大量特征(14)也会立即被移除。

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

方差阈值(X)与所选要素数量(Y)的线图

识别包含重复数据的行

具有相同数据的行即使在模型评估期间没有危险的误导,也可能是无用的。

这里,重复行是一行,其中该行的每一列中的每个值在另一行中以相同的顺序(相同的列值)出现。

…如果您使用了可能有重复条目的原始数据,删除重复数据将是确保您的数据能够被准确使用的重要一步。

—第 173 页,与 Python 的数据角力,2016。

从概率的角度来看,您可以将重复数据视为调整类标签或数据分布的优先级。如果你希望有目的地偏向先验,这可能有助于像朴素贝叶斯这样的算法。通常情况下,情况并非如此,机器学习算法将通过识别和移除具有重复数据的行而表现得更好。

从算法评估的角度来看,重复的行将导致误导性的表现。例如,如果您正在使用训练/测试分割或 k-fold 交叉验证,那么在训练和测试数据集中可能会出现一个或多个重复行,并且在这些行上对模型的任何评估都将是(或者应该是)正确的。这将导致对未知数据的表现的乐观估计。

重复数据消除,也称为重复检测、记录链接、记录匹配或实体解析,是指在引用同一现实实体的一个或多个关系中识别元组的过程。

—第 47 页,数据清理,2019 年。

如果您认为您的数据集或所选模型并非如此,请设计一个受控实验来测试它。这可以通过使用原始数据集和删除重复数据的数据集评估模型技能并比较表现来实现。另一个实验可能涉及用不同数量的随机选择的重复示例来扩充数据集。

熊猫函数复制()将报告给定行是否重复。所有行都标记为“假”表示不是重复行,或者标记为“真”表示是重复行。如我们所料,如果有重复项,第一次出现的行将被标记为 False(默认情况下)。

以下示例检查重复项。

# locate rows of duplicate data
from pandas import read_csv
# define the location of the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/iris.csv'
# load the dataset
df = read_csv(path, header=None)
# calculate duplicates
dups = df.duplicated()
# report if there are any duplicates
print(dups.any())
# list all duplicate rows
print(df[dups])

运行该示例首先加载数据集,然后计算重复行。

首先,报告任何重复行的存在,在这种情况下,我们可以看到存在重复(真)。

然后报告所有重复的行。在这种情况下,我们可以看到打印了三个重复的行。

True
       0    1    2    3               4
34   4.9  3.1  1.5  0.1     Iris-setosa
37   4.9  3.1  1.5  0.1     Iris-setosa
142  5.8  2.7  5.1  1.9  Iris-virginica

删除包含重复数据的行

在建模之前,可能应该从数据集中删除重复数据行。

如果数据集只是有重复的行,就不需要担心保存数据;它已经是已完成数据集的一部分,您只需从已清理的数据中移除或删除这些行。

—第 186 页,与 Python 的数据角力,2016。

实现这一点的方法有很多,虽然 Pandas 提供了 drop_duplicates()函数正是实现了这一点。

下面的示例演示了如何从数据集中删除重复的行。

# delete rows of duplicate data from the dataset
from pandas import read_csv
# define the location of the dataset
path = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/iris.csv'
# load the dataset
df = read_csv(path, header=None)
print(df.shape)
# delete duplicate rows
df.drop_duplicates(inplace=True)
print(df.shape)

运行该示例首先加载数据集,并报告行数和列数。

接下来,识别重复数据行,并将其从数据框中删除。然后报告数据框的形状以确认更改。

(150, 5)
(147, 5)

进一步阅读

如果您想更深入地了解这个主题,本节将提供更多资源。

教程

蜜蜂

摘要

在本教程中,您发现了应该始终对数据集执行的基本数据清理。

具体来说,您了解到:

  • 如何识别和移除只有一个值的列变量?
  • 如何识别和考虑唯一值很少的列变量?
  • 如何识别和删除包含重复观察的行?

你有什么问题吗?
在下面的评论中提问,我会尽力回答。

为机器学习的缺失值添加二元标志

原文:https://machinelearningmastery.com/binary-flags-for-missing-values-for-machine-learning/

最后更新于 2020 年 8 月 17 日

在用机器学习算法建模分类和回归预测问题时,缺失值会导致问题。

一种常见的方法是用计算出的统计数据(如列的平均值)替换缺失的值。这允许数据集按照正常方式建模,但不会向模型显示原始行包含缺失值。

解决这个问题的一种方法是包括附加的二元标志输入特征,该特征指示一行或一列是否包含被输入的缺失值。该附加信息可能对模型预测目标值有帮助,也可能没有帮助。

在本教程中,您将发现如何为建模的缺失值添加二元标志。

完成本教程后,您将知道:

  • 如何在缺少值的类别数据集上加载和评估带有统计插补的模型。
  • 如何添加一个标志来指示一行是否还有一个缺失值,并使用此新功能评估模型。
  • 如何为每个缺少值的输入变量添加一个标志,并使用这些新特性评估模型。

用我的新书机器学习的数据准备启动你的项目,包括分步教程和所有示例的 Python 源代码文件。

我们开始吧。

  • 2020 年 7 月更新:修复了标志变量创建中的 bug。

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

为机器学习的缺失值添加二元标志
Keith o connell 摄,保留部分权利。

教程概述

本教程分为三个部分;它们是:

  1. 马结肠数据集的输入
  2. 带有缺失值二元标志的模型
  3. 带有所有缺失值指示器的模型

马结肠数据集的输入

马绞痛数据集描述了患有绞痛的马的医学特征以及它们是活的还是死的。

有 300 行 26 个输入变量和一个输出变量。这是一个二分类预测任务,包括预测 1 如果马活了,2 如果马死了。

在这个数据集中,我们可以选择许多字段进行预测。在这种情况下,我们将预测问题是否是外科手术(列索引 23),使其成为二分类问题。

对于许多列,数据集有许多缺失值,其中每个缺失值都用问号字符(“?”)标记).

下面提供了数据集中带有标记缺失值的行的示例。

2,1,530101,38.50,66,28,3,3,?,2,5,4,4,?,?,?,3,5,45.00,8.40,?,?,2,2,11300,00000,00000,2
1,1,534817,39.2,88,20,?,?,4,1,3,4,2,?,?,?,4,2,50,85,2,2,3,2,02208,00000,00000,2
2,1,530334,38.30,40,24,1,1,3,1,3,3,1,?,?,?,1,1,33.00,6.70,?,?,1,2,00000,00000,00000,1
1,9,5290409,39.10,164,84,4,1,6,2,2,4,4,1,2,5.00,3,?,48.00,7.20,3,5.30,2,1,02208,00000,00000,1
...

您可以在此了解有关数据集的更多信息:

不需要下载数据集,因为我们将在工作示例中自动下载它。

使用 Python 在加载的数据集中用 NaN(而不是数字)值标记缺失值是最佳实践。

我们可以使用 read_csv() Pandas 函数加载数据集,并指定“ na_values ”来加载“?”作为缺失,用 NaN 值标记。

下面的示例下载数据集,标记“?”值为 NaN(缺少)并总结数据集的形状。

# summarize the horse colic dataset
from pandas import read_csv
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/horse-colic.csv'
dataframe = read_csv(url, header=None, na_values='?')
data = dataframe.values
# split into input and output elements
ix = [i for i in range(data.shape[1]) if i != 23]
X, y = data[:, ix], data[:, 23]
print(X.shape, y.shape)

运行该示例会下载数据集并报告行数和列数,符合我们的预期。

(300, 27) (300,)

接下来,我们可以在这个数据集上评估一个模型。

我们可以使用simple 插补器类进行统计插补,并用每一列的平均值替换缺失的值。然后,我们可以在数据集上拟合一个随机森林模型。

有关如何使用简单估计器类的更多信息,请参见教程:

为了实现这一点,我们将定义一个管道,首先执行插补,然后拟合模型,并使用三次重复和 10 次折叠的重复分层 k-fold 交叉验证来评估该建模管道。

下面列出了完整的示例。

# evaluate mean imputation and random forest for the horse colic dataset
from numpy import mean
from numpy import std
from pandas import read_csv
from sklearn.ensemble import RandomForestClassifier
from sklearn.impute import SimpleImputer
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.pipeline import Pipeline
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/horse-colic.csv'
dataframe = read_csv(url, header=None, na_values='?')
# split into input and output elements
data = dataframe.values
ix = [i for i in range(data.shape[1]) if i != 23]
X, y = data[:, ix], data[:, 23]
# define modeling pipeline
model = RandomForestClassifier()
imputer = SimpleImputer()
pipeline = Pipeline(steps=[('i', imputer), ('m', model)])
# define model evaluation
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# evaluate model
scores = cross_val_score(pipeline, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
print('Mean Accuracy: %.3f (%.3f)' % (mean(scores), std(scores)))

运行该示例使用马结肠数据集上的平均统计插补来评估随机森林。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,管道实现了大约 86.2%的估计分类准确率。

Mean Accuracy: 0.862 (0.056)

接下来,让我们看看是否可以通过提供更多关于缺失值的信息来提高模型的表现。

带有缺失值二元标志的模型

在前面的部分中,我们用计算的统计数据替换了缺失的值。

模型不知道丢失的值已被替换。

在进行预测时,了解一行是否包含缺失值可能对模型有用。

向模型公开这一知识的一种方法是提供一个额外的列,该列是一个二元标志,指示该行是否有丢失的值。

  • 0:行不包含缺失值。
  • 1:行包含一个缺失值(过去/将来会被估计)。

这可以直接在加载的数据集上实现。首先,我们可以对每一行的值求和,以创建一个新的列,其中如果该行至少包含一个 NaN,那么总和将是一个 NaN。

然后我们可以将新列中的所有值标记为 1(如果它们包含 NaN),否则标记为 0。

最后,我们可以将该列添加到加载的数据集中。

将这些联系在一起,下面列出了添加二元标志来指示每行中一个或多个缺失值的完整示例。

# add a binary flag that indicates if a row contains a missing value
from numpy import isnan
from numpy import hstack
from pandas import read_csv
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/horse-colic.csv'
dataframe = read_csv(url, header=None, na_values='?')
# split into input and output elements
data = dataframe.values
ix = [i for i in range(data.shape[1]) if i != 23]
X, y = data[:, ix], data[:, 23]
print(X.shape)
# sum each row where rows with a nan will sum to nan
a = X.sum(axis=1)
# mark all non-nan as 0
a[~isnan(a)] = 0
# mark all nan as 1
a[isnan(a)] = 1
a = a.reshape((len(a), 1))
# add to the dataset as another column
X = hstack((X, a))
print(X.shape)

运行该示例首先下载数据集,并按照预期报告行数和列数。

然后创建新的二进制变量,指示一行是否包含缺失值,并将其添加到输入变量的末尾。然后报告输入数据的形状,确认增加了特征,从 27 列到 28 列。

(300, 27)
(300, 28)

然后,我们可以像上一节一样使用额外的二元标志来评估模型,看看它是否会影响模型表现。

下面列出了完整的示例。

# evaluate model performance with a binary flag for missing values and imputed missing
from numpy import isnan
from numpy import hstack
from numpy import mean
from numpy import std
from pandas import read_csv
from sklearn.ensemble import RandomForestClassifier
from sklearn.impute import SimpleImputer
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.pipeline import Pipeline
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/horse-colic.csv'
dataframe = read_csv(url, header=None, na_values='?')
# split into input and output elements
data = dataframe.values
ix = [i for i in range(data.shape[1]) if i != 23]
X, y = data[:, ix], data[:, 23]
# sum each row where rows with a nan will sum to nan
a = X.sum(axis=1)
# mark all non-nan as 0
a[~isnan(a)] = 0
# mark all nan as 1
a[isnan(a)] = 1
a = a.reshape((len(a), 1))
# add to the dataset as another column
X = hstack((X, a))
# define modeling pipeline
model = RandomForestClassifier()
imputer = SimpleImputer()
pipeline = Pipeline(steps=[('i', imputer), ('m', model)])
# define model evaluation
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# evaluate model
scores = cross_val_score(pipeline, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
print('Mean Accuracy: %.3f (%.3f)' % (mean(scores), std(scores)))

运行该示例报告了具有附加特征和插补的马结肠数据集的平均和标准偏差分类准确率。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们看到表现从 86.2%适度提升到 86.3%。差异很小,可能没有统计学意义。

Mean Accuracy: 0.863 (0.055)

此数据集中的大多数行都有缺失值,这种方法在缺失值较少的数据集上可能更有好处。

接下来,让我们看看是否可以向模型提供更多关于缺失值的信息。

带有所有缺失值指示器的模型

在前一节中,我们添加了一个额外的列来指示一行是否包含缺失值。

下一步是指出每个输入值是否缺失和估计。这实际上为每个包含缺失值的输入变量增加了一列,并可能为模型带来好处。

这可以通过在定义简单估计器实例时将“ add_indicator ”参数设置为 True 来实现。

...
# impute and mark missing values
X = SimpleImputer(add_indicator=True).fit_transform(X)

我们可以用一个成功的例子来证明这一点。

下面的示例像以前一样加载 horse colic 数据集,然后估计整个数据集的缺失值,并为每个缺失值的输入变量添加指示变量

# impute and add indicators for columns with missing values
from pandas import read_csv
from sklearn.impute import SimpleImputer
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/horse-colic.csv'
dataframe = read_csv(url, header=None, na_values='?')
data = dataframe.values
# split into input and output elements
ix = [i for i in range(data.shape[1]) if i != 23]
X, y = data[:, ix], data[:, 23]
print(X.shape)
# impute and mark missing values
X = SimpleImputer(strategy='mean', add_indicator=True).fit_transform(X)
print(X.shape)

运行该示例首先按照预期下载并汇总数据集的形状,然后应用插补并添加二进制(1 和 0 值)列,以指示每行是否包含给定输入变量的缺失值。

我们可以看到输入变量的数量从 27 个增加到了 48 个,这表明增加了 21 个二进制输入变量,反过来,27 个输入变量中的 21 个必须包含至少一个缺失值。

(300, 27)
(300, 48)

接下来,我们可以使用这些附加信息来评估模型。

下面完整的例子演示了这一点。

# evaluate imputation with added indicators features on the horse colic dataset
from numpy import mean
from numpy import std
from pandas import read_csv
from sklearn.ensemble import RandomForestClassifier
from sklearn.impute import SimpleImputer
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.pipeline import Pipeline
# load dataset
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/horse-colic.csv'
dataframe = read_csv(url, header=None, na_values='?')
# split into input and output elements
data = dataframe.values
ix = [i for i in range(data.shape[1]) if i != 23]
X, y = data[:, ix], data[:, 23]
# define modeling pipeline
model = RandomForestClassifier()
imputer = SimpleImputer(add_indicator=True)
pipeline = Pipeline(steps=[('i', imputer), ('m', model)])
# define model evaluation
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
# evaluate model
scores = cross_val_score(pipeline, X, y, scoring='accuracy', cv=cv, n_jobs=-1)
print('Mean Accuracy: %.3f (%.3f)' % (mean(scores), std(scores)))

运行该示例报告了马结肠数据集的平均和标准偏差分类准确率,以及附加的指标特征和插补。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们看到表现从上一部分的 86.3%提升到了 86.7%。

这可能提供强有力的证据,表明在这个数据集和所选模型上,为输入的每一列添加一个标志是更好的策略。

Mean Accuracy: 0.867 (0.055)

进一步阅读

如果您想更深入地了解这个主题,本节将提供更多资源。

相关教程

摘要

在本教程中,您发现了如何为建模的缺失值添加二元标志。

具体来说,您了解到:

  • 如何在缺少值的类别数据集上加载和评估带有统计插补的模型。
  • 如何添加一个标志来指示一行是否还有一个缺失值,并使用此新功能评估模型。
  • 如何为每个缺少值的输入变量添加一个标志,并使用这些新特性评估模型。

你有什么问题吗?
在下面的评论中提问,我会尽力回答。

8 本关于数据清理和特征工程的顶级书籍

原文:https://machinelearningmastery.com/books-on-data-cleaning-data-preparation-and-feature-engineering/

数据准备是将原始数据转换成更适合建模的形式。

由于不同项目的数据在形式、类型和结构上有所不同,因此这是一个具有挑战性的讨论话题。

尽管如此,项目之间还是有一些常见的数据准备任务。这是一个庞大的研究领域,有许多名称,如“数据清洗”、“数据扯皮、“数据预处理、“特征工程”等等。其中一些是不同的数据准备任务,一些术语用于描述整个数据准备过程。

尽管这是一个很有挑战性的话题,但还是有很多关于这个话题的书。

在这篇文章中,你将发现关于数据清理、数据准备、特征工程和相关主题的顶级书籍。

我们开始吧。

用我的新书机器学习的数据准备启动你的项目,包括分步教程和所有示例的 Python 源代码文件。

概观

这里的重点是表格数据的数据准备,例如,表格形式的数据,在 excel 电子表格中有行和列。

数据准备是所有数据类型的重要主题,尽管每个类型都需要专业方法,例如计算机视觉中的图像数据、自然语言处理中的文本数据以及时间序列预测中的序列数据。

数据准备通常是机器学习教科书中的一章,尽管有专门针对该主题的书籍。我们将专注于这些书。

我收集了所有能找到的关于选题资料准备的书籍,挑选了我认为最好或更好的书籍,并将其组织成三组;它们是:

  1. 数据清理
  2. 数据争论
  3. 特征工程

我会尽量给出每本书的味道,包括目标、目录,以及去哪里了解更多。

数据清理

数据清理是指在建模之前识别和修复数据中的错误,包括但不限于异常值、缺失值等等。

关于数据清理的顶级书籍包括:

让我们依次仔细看看每一个。

《不良数据手册》

《不良数据手册:清理数据让你可以重新工作》一书由伊森·麦卡勒姆编辑,于 2012 年出版。

不良数据不仅被描述为损坏的数据,而且被描述为任何损害建模过程的数据。

很难确定“坏数据”的准确定义有些人认为这纯粹是一种动手操作的技术现象:缺少值、格式错误的记录和古怪的文件格式。当然,这只是一部分,但坏数据远不止这些。[……]不良数据是碍事的数据。

—第 1 页,“不良数据手册:清理数据以便可以重新开始工作”,2012 年。

这是一个由 19 名机器学习实践者和我们收集的论文集,充满了关于数据准备和管理的有用信息。

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

不良数据手册

这本书的完整目录如下。

  • 第一章:设定节奏:什么是坏数据?
  • 第二章:是只有我,还是这个数据闻起来很好笑?
  • 第三章:用于人类消费而非机器消费的数据
  • 第四章:隐藏在纯文本中的不良数据
  • 第五章:(重新)组织网络数据
  • 第六章:发现骗子和矛盾网络评论中的困惑
  • 第七章:坏数据请站起来好吗?
  • 第八章:血、汗和尿
  • 第九章:当数据和现实不符时
  • 第十章:偏见和错误的微妙来源
  • 第十一章:不要让完美成为好的敌人:坏数据真的坏吗?
  • 第十二章:当数据库受到攻击时:何时坚持使用文件的指南
  • 第十三章:卧桌,隐藏网络
  • 第十四章:云计算的神话
  • 第十五章:数据科学的阴暗面
  • 第十六章:如何喂养和照顾你的机器学习专家
  • 第十七章:数据可追溯性
  • 第十八章:社交媒体:可擦墨水?
  • 第十九章:数据质量分析揭秘:知道你的数据何时足够好

我很喜欢这本书;它充满了宝贵的实用建议。我强烈推荐!

了解更多信息:

“数据清理的最佳实践”

《数据清理的最佳实践:收集数据前后需要做的所有事情的完整指南》一书由杰森·奥斯本撰写,于 2012 年出版。

这是一本关于基于计算的社会科学的数据准备的更通用的教科书,而不是专门的机器学习。然而,它包含了大量有用的建议。

我写这本书的目的是在一个地方收集我认为是数据清理最佳实践的系统概述,我可以证明这些东西对您的数据分析有所帮助。我寻求改变现状,改变社会科学定量研究的现状。

—第 2 页,“数据清理的最佳实践:收集数据前后需要做的一切的完整指南”,2012 年。

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

数据清理的最佳实践

这本书的完整目录如下。

  • 第一章:为什么数据清理很重要:揭穿健壮性神话
  • 第二章:权力与数据收集规划:揭穿权力充足的神话
  • 第三章:忠于目标人群:揭穿代表性神话
  • 第四章:用概率采样框架使用大数据集:揭穿平等的神话
  • 第五章:为潜在问题筛选你的数据:揭穿完美数据的神话
  • 第六章:处理缺失或不完整的数据:揭穿空虚的神话
  • 第七章:极端而有影响力的数据点:揭穿平等神话
  • 第八章:通过 Box-Cox 变换提高变量的正态性:揭穿分布不相关的神话
  • 第九章:可靠性重要吗?揭穿完美测量的神话
  • 第十章:随机反应、动机错误反应和反应集:揭穿动机参与者的神话
  • 第十一章:为什么将连续变量二分很少是一个好的实践:揭穿分类的神话
  • 第十二章:清洁重复测量数据的特殊挑战:许多坑会掉进去
  • 第十三章:现在神话被揭穿了…:21 世纪理性量化方法论的愿景

我认为这是一般数据准备技术的一个很好的参考指南,考虑到更强的统计焦点,也许比大多数“机器学习”的书籍覆盖面更好。

了解更多信息:

“数据清理”

数据清理一书由伊哈布易勒雅斯储旭撰写,2019 年出版。

顾名思义,这本书专注于在建模之前修复原始数据错误的数据清理技术。

数据清理是指检测和修复数据中错误的各种任务和活动。在本书中,我们不关注特定的数据清理任务,而是概述了端到端数据清理过程,描述了各种错误检测和修复方法,并试图用多个分类法和视图来锚定这些建议。

—第 ixx 页,“数据清理”,2019 年。

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

数据清理

这本书的完整目录如下。

  • 第一章:引言
  • 第二章:异常检测
  • 第三章:重复数据消除
  • 第四章:数据转换
  • 第五章:数据质量规则定义和发现
  • 第六章:基于规则的数据清理
  • 第七章:机器学习和概率数据清洗
  • 第八章:结论与未来思考

与其说它是一本实用的书,不如说它更像是一本教科书,非常适合那些既想回顾方法又想参考原始研究论文的学者和研究人员。

了解更多信息:

数据争论

数据争论是数据准备的一个更通用或通俗的术语,可能包括一些数据清理和特征工程。

关于数据争论的顶级书籍包括:

让我们依次仔细看看每一个。

“与 Python 的数据争论”

《与 Python 的数据角力:让你的生活更轻松的技巧和工具》一书由杰奎琳·卡兹尔凯瑟琳·贾马尔撰写,于 2016 年出版。

本书的重点是帮助您将原始数据转换成准备建模的表单的工具和方法。

数据争论是关于获取一个混乱的或未经提炼的数据源,并将其转化为有用的东西。

—第十二页,“与 Python 的数据角力:让生活更轻松的技巧和工具”,2016 年。

这是一本初学者的书,适合那些初次使用 Python 进行数据准备和建模的人,例如当前的 excel 用户。

这本书是为那些想要探索桌面工具之外的数据争论的人准备的。如果你擅长 Excel,想让你的数据分析更上一层楼,这本书会有帮助的!

—第十二页,“与 Python 的数据角力:让生活更轻松的技巧和工具”,2016 年。

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

与 Python 的数据争论

这本书的完整目录如下。

  • 第一章:Python 简介
  • 第二章:Python 基础
  • 第三章:机器应该读取的数据
  • 第四章:使用 Excel 文件
  • 第五章:pdf 和 Python 中的问题解决
  • 第六章:获取和存储数据
  • 第七章:数据清理:调查、匹配和格式化
  • 第八章:数据清理:标准化和脚本
  • 第九章:数据探索与分析
  • 第十章:展示您的数据
  • 第十一章:网页抓取:从网上获取和存储数据
  • 第十二章:高级网页抓取:屏幕抓取器和蜘蛛
  • 第十三章:原料药
  • 第十四章:自动化和扩展
  • 第十五章:结论

如果您刚开始使用 Python 进行数据加载和组织,这本书可以帮助您。

了解更多信息:

“数据争论的原则”

《数据角力的原理:数据准备的实用技术》一书由 Tye Rattenbury 等人撰写,于 2017 年出版。

数据争论用于描述所有与为建模准备数据相关的任务。

诞生于现代敏捷分析背景下的“数据争论”一词,意在描述人们花在数据工作上的大部分时间。

—第九页,“数据角力原理:数据准备实用技术”,2017。

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

数据争论的原则

这本书的完整目录如下。

  • 第一章:引言
  • 第二章:数据工作流框架
  • 第三章:数据争论的动态
  • 第四章:分析
  • 第五章:转型:结构化
  • 第六章:转型:丰富
  • 第七章:使用转换清理数据
  • 第八章:角色和责任
  • 第九章:数据争论工具

这是一本好书,但水平很高。也许它更适合经理而不是从业者。例如,我想我没有看到一行代码。

了解更多信息:

“与 R 的数据争论”

《与 R 的数据角力》一书由布拉德利·伯姆克撰写,于 2016 年出版。

顾名思义,这本书专注于 r 的数据准备。

在这本书里,我将帮助你学习预处理数据的要点,利用 R 编程语言轻松快速地将有噪声的数据转化为可用的信息。

—第五页,与 R 的数据角力,2016。

这是一本实用的书。它有许多小的、重点突出的章节,其中有关于数据准备过程中会遇到的具体问题的代码示例。与本综述中的许多其他高级书籍相比,这是一个可喜的变化。

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

与 R 的数据争论

这本书的完整目录如下。

  • 第一章:数据争论的作用
  • 第二章:R 入门
  • 第三章:基础
  • 第四章:处理数字
  • 第五章:处理字符串
  • 第六章:处理正则表达式
  • 第七章:处理因素
  • 第八章:处理日期
  • 第九章:数据结构基础
  • 第十章:管理媒介
  • 第十一章:管理列表
  • 第十二章:管理矩阵
  • 第十三章:管理数据框
  • 第十四章:处理缺失值
  • 第十五章:导入数据
  • 第十六章:抓取数据
  • 第十七章:导出数据
  • 第十八章:功能
  • 第十九章:循环控制语句
  • 第二十章:用%>%简化代码
  • 第二十一章:用 tidyr 重塑您的数据
  • 第二十二章:使用 dplyr 转换您的数据

我是这本书的粉丝,如果你用的是 R,你需要一本。缺点是这本书里的 R 基础知识有点太多了。我宁愿这些被扔掉,读者被导向一本介绍性的 R 书,稍微提高对读者的要求。

了解更多信息:

特征工程

特征工程指的是从原始数据创建新的输入变量,尽管它也指更一般的数据准备。

关于功能工程的顶级书籍包括:

让我们依次仔细看看每一个。

“特征工程和选择”

《特征工程与选择:预测模型的实用方法》一书由马克斯·库恩谢尔·约翰逊撰写,于 2019 年出版。

这本书描述了为特征工程建模准备原始数据的一般过程。

调整和改造预测因子,使模型更好地揭示预测因子-反应的关系,被称为特征工程。

—Xi,“特征工程和选择:预测模型的实用方法”,2019 年。

书中的例子是用 R 演示的,这很重要,因为作者 Max Kuhn 也是流行的 caret 包的创建者。

书中采取的一个重要观点是,数据准备不仅仅是满足建模算法的期望;需要最好地暴露问题的底层结构,需要反复试验和错误。这和我通常的观点是一样的,在一本现代书中看到它令人耳目一新。

…我们通常不知道改善模型表现的预测因子的最佳再现。相反,预测器的重新工作更像是一门艺术,需要正确的工具和经验来找到更好的预测器表示。此外,我们可能需要搜索许多替代的预测器表示来提高模型表现。

—第十二页,“特征工程和选择:预测模型的实用方法”,2019 年。

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

特征工程与选择

这本书的完整目录如下。

  • 第一章。介绍
  • 第二章。示例:预测缺血性中风的风险
  • 第三章。预测建模过程综述
  • 第四章。探索性可视化
  • 第五章。编码分类预测因子
  • 第六章。工程数字预测器
  • 第七章。检测交互效果
  • 第八章。处理丢失的数据
  • 第九章。使用配置文件数据
  • 第十章。功能选择概述
  • 第十一章。贪婪搜索方法
  • 第十二章。全局搜索方法

我认为这是一本必须拥有的书,即使 R 不是你的主要语言。所讨论的方法的广度仅值标价。

了解更多信息:

“机器学习的特征工程”

《机器学习的特征工程:数据科学家的原理与技术》一书由Alice ZhengAmanda Casari撰写,于 2018 年出版。

我认为这本书在我看过的所有书中有最直接的定义,将特征描述为模型和特征工程的数字输入,从原始数据中获得有用的数字特征。非常脆!

要素是原始数据的一个方面的数字表示。特征位于机器学习管道中的数据和模型之间。特征工程是从原始数据中提取特征并将它们转换成适合机器学习模型的格式的行为。

—第七页,“机器学习的特征工程:数据科学家的原理和技术”,2018。

这些例子是用 Python 编写的,重点是使用 NumPy 和 Pandas,并且有很多成功的例子,非常棒。我觉得这是一本相当于上面*“与 R* 的数据角力”或者特征工程与选择的好姐妹书或者 Python,“虽然可能覆盖面比较小。

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

机器学习的特征工程

这本书的完整目录如下。

  • 第一章:机器学习管道
  • 第二章:简单数字的花式把戏
  • 第三章:文本数据:展平、过滤和分块
  • 第四章:特征缩放的效果:从词袋到 Tf-Idf
  • 第五章:分类变量:机器鸡时代的鸡蛋计数
  • 第六章:降维:用主成分分析挤压数据饼
  • 第七章:基于 K-均值模型叠加的非线性特征化
  • 第八章:特征器自动化:图像特征提取和深度学习
  • 第九章:回到未来:构建学术论文推荐系统
  • 附录一:线性建模和线性代数基础

我喜欢这本书。

我想我更愿意放弃数学,直接把读者引向教科书。我也希望这些例子关注机器学习建模管道,而不是独立的转换。但是我很挑剔,并且在给定的项目中极力争取直接有用的代码。

了解更多信息:

推荐

你必须根据你的需求选择适合你的书,例如代码或教科书,Python 或 r。

我拥有所有这些书,但我推荐的两本书是:

原因是我喜欢实用的书,当我想出该尝试什么的时候,我喜欢 R 和 Python 的视角。

一个密切的后续行动将是:

第一是超级实用;第二个充满了超级有用(但又超级具体)的建议。

对于大多数研究者需要参考的教科书,我可能会推荐:

摘要

在这篇文章中,你发现了关于数据清理、数据准备、特征工程和相关主题的顶级书籍。

是不是错过了一本关于数据准备的好书?
在下面的评论里告诉我。

你读过列出的书吗?
在评论中告诉我你对它的看法。

如何用 Python 计算特征重要性

原文:https://machinelearningmastery.com/calculate-feature-importance-with-python/

最后更新于 2020 年 8 月 20 日

特征重要性指的是根据输入特征在预测目标变量时的有用程度为输入特征打分的技术。

特征重要性分数有许多类型和来源,尽管流行的例子包括统计相关分数、作为线性模型一部分计算的系数、决策树和排列重要性分数。

特征重要性分数在预测建模项目中起着重要的作用,包括提供对数据的洞察、对模型的洞察,以及降维特征选择的基础,它们可以提高预测模型对问题的效率和有效性。

在本教程中,您将发现 python 中机器学习的特征重要性分数

完成本教程后,您将知道:

  • 特征重要性在预测建模问题中的作用。
  • 如何从线性模型和决策树计算和检查特征重要性?
  • 如何计算和复习排列特征重要性分数?

用我的新书机器学习的数据准备启动你的项目,包括分步教程和所有示例的 Python 源代码文件。

我们开始吧。

  • 2020 年 5 月更新:增加了利用重要性进行特征选择的例子。

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

如何用 Python 计算特征重要性
图片由邦妮·莫兰提供,保留部分权利。

教程概述

本教程分为六个部分;它们是:

  1. 特征重要性
  2. 准备
    1. 检查套件-学习版本
    2. 测试数据集
  3. 作为特征重要性的系数
    1. 线性回归特征重要性
    2. 逻辑回归特征重要性
  4. 决策树特征重要性
    1. 购物车功能重要性
    2. 随机森林特征重要性
    3. 扩展功能重要性
  5. 排列特征重要性
    1. 回归的置换特征重要性
    2. 排列特征对分类的重要性
  6. 具有重要性的特征选择

特征重要性

特征重要性是指一类技术,用于将输入特征的得分分配给预测模型,该预测模型指示每个特征在进行预测时的相对重要性。

可以为涉及预测数值的问题(称为回归)和涉及预测类别标签的问题(称为分类)计算特征重要性分数。

分数很有用,可以用于预测建模问题中的一系列情况,例如:

  • 更好地理解数据。
  • 更好地理解模型。
  • 减少输入特征的数量。

特征重要性分数可以提供对数据集的洞察。相对分数可以突出显示哪些特征可能与目标最相关,反之,哪些特征最不相关。这可以由领域专家进行解释,并可以用作收集更多或不同数据的基础。

特征重要性分数可以提供对模型的洞察。大多数重要度分数都是通过适合数据集的预测模型来计算的。检查重要性分数可以深入了解特定的模型,以及在进行预测时哪些特征对模型最重要,哪些最不重要。这是一种可以为支持它的模型执行的模型解释类型。

特征重要性可用于改进预测模型。这可以通过使用重要性分数来选择要删除的特征(最低分数)或要保留的特征(最高分数)来实现。这是一种特征选择,可以简化正在建模的问题,加快建模过程(删除特征称为降维),在某些情况下,可以提高模型的表现。

通常,我们希望量化预测因子和结果之间关系的强度。[……]在筛选大量数据时,以这种方式对预测值进行排名非常有用。

—第 463 页,应用预测建模,2013 年。

特征重要性分数可以被馈送到包装器模型,例如selectfrommel类,以执行特征选择。

有许多方法可以计算特征重要性分数,也有许多模型可以用于此目的。

也许最简单的方法是计算每个特征和目标变量之间的简单系数统计。有关这种方法的更多信息,请参见教程:

在本教程中,我们将研究三种更高级的重要特性;它们是:

  • 模型系数的特征重要性。
  • 决策树的特征重要性。
  • 置换测试的特征重要性。

让我们仔细看看每一个。

准备

在我们深入研究之前,让我们确认我们的环境并准备一些测试数据集。

检查 Scikit-学习版本

首先,确认您安装了 Sklearn 库的现代版本。

这很重要,因为我们将在本教程中探索的一些模型需要一个现代版本的库。

您可以使用下面的代码示例检查已安装的库的版本:

# check Sklearn version
import sklearn
print(sklearn.__version__)

运行该示例将打印库的版本。在撰写本文时,这大约是 0.22 版本。

您需要使用 Sklearn 或更高版本。

0.22.1

测试数据集

接下来,让我们定义一些测试数据集,我们可以将其用作演示和探索特征重要性分数的基础。

每个测试问题有五个重要的和五个不重要的特征,看看哪些方法在根据特征的重要性找到或区分特征方面是一致的可能会很有趣。

类别数据集

我们将使用 make_classification()函数创建一个测试二进制类别数据集。

数据集将有 1,000 个示例,有 10 个输入要素,其中 5 个是信息性的,其余 5 个是冗余的。我们将修复随机数种子,以确保每次运行代码时得到相同的例子。

下面列出了创建和汇总数据集的示例。

# test classification dataset
from sklearn.datasets import make_classification
# define dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, random_state=1)
# summarize the dataset
print(X.shape, y.shape)

运行该示例将创建数据集,并确认样本和要素的预期数量。

(1000, 10) (1000,)

回归数据集

我们将使用make _ revolution()函数创建一个测试回归数据集。

与类别数据集一样,回归数据集将有 1,000 个示例,有 10 个输入要素,其中 5 个是信息性的,其余 5 个是冗余的。

# test regression dataset
from sklearn.datasets import make_regression
# define dataset
X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, random_state=1)
# summarize the dataset
print(X.shape, y.shape)

运行该示例将创建数据集,并确认样本和要素的预期数量。

(1000, 10) (1000,)

接下来,让我们仔细看看作为重要性分数的系数。

作为特征重要性的系数

线性机器学习算法适合一个模型,其中预测是输入值的加权和。

示例包括线性回归、逻辑回归和添加正则化的扩展,如岭回归和弹性网。

所有这些算法都会找到一组用于加权和的系数,以便进行预测。这些系数可以直接用作特征重要性得分的粗略类型。

让我们仔细看看使用系数作为分类和回归的特征重要性。我们将在数据集上拟合一个模型来找到系数,然后总结每个输入特征的重要性分数,最后创建一个条形图来了解特征的相对重要性。

线性回归特征重要性

我们可以在回归数据集上拟合线性回归模型,并检索包含为每个输入变量找到的系数的系数 _ 属性。

这些系数可以为粗略的特征重要性评分提供基础。这假设输入变量具有相同的比例或者在拟合模型之前已经被缩放。

下面列出了特征重要性的线性回归系数的完整示例。

# linear regression feature importance
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
from matplotlib import pyplot
# define dataset
X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, random_state=1)
# define the model
model = LinearRegression()
# fit the model
model.fit(X, y)
# get importance
importance = model.coef_
# summarize feature importance
for i,v in enumerate(importance):
	print('Feature: %0d, Score: %.5f' % (i,v))
# plot feature importance
pyplot.bar([x for x in range(len(importance))], importance)
pyplot.show()

运行该示例来拟合模型,然后报告每个特征的系数值。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

这些分数表明,该模型找到了五个重要的特征,并用零系数标记了所有其他特征,基本上将它们从模型中移除。

Feature: 0, Score: 0.00000
Feature: 1, Score: 12.44483
Feature: 2, Score: -0.00000
Feature: 3, Score: -0.00000
Feature: 4, Score: 93.32225
Feature: 5, Score: 86.50811
Feature: 6, Score: 26.74607
Feature: 7, Score: 3.28535
Feature: 8, Score: -0.00000
Feature: 9, Score: 0.00000

然后为特征重要性分数创建条形图。

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

作为特征重要性得分的线性回归系数条形图

这种方法也可以用于弹性线模型。

逻辑回归特征重要性

我们可以在回归数据集上拟合一个逻辑回归模型,并检索包含为每个输入变量找到的系数的系数 _ 属性。

这些系数可以为粗略的特征重要性评分提供基础。这假设输入变量具有相同的比例或者在拟合模型之前已经被缩放。

下面列出了特征重要性的逻辑回归系数的完整示例。

# logistic regression for feature importance
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
from matplotlib import pyplot
# define dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, random_state=1)
# define the model
model = LogisticRegression()
# fit the model
model.fit(X, y)
# get importance
importance = model.coef_[0]
# summarize feature importance
for i,v in enumerate(importance):
	print('Feature: %0d, Score: %.5f' % (i,v))
# plot feature importance
pyplot.bar([x for x in range(len(importance))], importance)
pyplot.show()

运行该示例来拟合模型,然后报告每个特征的系数值。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

回想一下,这是 0 类和 1 类的分类问题。请注意,系数既是正的,也是负的。正分数表示预测类别 1 的特征,而负分数表示预测类别 0 的特征。

从这些结果中,没有明确的重要和不重要的特征模式可以被识别,至少从我所能告诉的来看。

Feature: 0, Score: 0.16320
Feature: 1, Score: -0.64301
Feature: 2, Score: 0.48497
Feature: 3, Score: -0.46190
Feature: 4, Score: 0.18432
Feature: 5, Score: -0.11978
Feature: 6, Score: -0.40602
Feature: 7, Score: 0.03772
Feature: 8, Score: -0.51785
Feature: 9, Score: 0.26540

然后为特征重要性分数创建条形图。

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

作为特征重要性得分的逻辑回归系数条形图

现在我们已经看到了使用系数作为重要性分数,让我们来看看基于决策树的重要性分数的更常见的例子。

决策树特征重要性

分类和回归树 (CART)这样的决策树算法基于用于选择分割点的标准的减少来提供重要性分数,像基尼或熵。

同样的方法可以用于决策树的集成,例如随机森林和随机梯度提升算法。

让我们来看一个成功的例子。

购物车功能重要性

我们可以使用 Sklearn 中实现的特征重要性的 CART 算法作为决策树回归器决策树分类器类。

拟合后,模型提供了一个特征重要度 _ 属性,可以访问该属性来检索每个输入特征的相对重要度得分。

让我们看一个回归和分类的例子。

CART 回归特征重要性

下面列出了拟合决策树回归器并汇总计算出的特征重要性分数的完整示例。

# decision tree for feature importance on a regression problem
from sklearn.datasets import make_regression
from sklearn.tree import DecisionTreeRegressor
from matplotlib import pyplot
# define dataset
X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, random_state=1)
# define the model
model = DecisionTreeRegressor()
# fit the model
model.fit(X, y)
# get importance
importance = model.feature_importances_
# summarize feature importance
for i,v in enumerate(importance):
	print('Feature: %0d, Score: %.5f' % (i,v))
# plot feature importance
pyplot.bar([x for x in range(len(importance))], importance)
pyplot.show()

运行该示例来拟合模型,然后报告每个特征的系数值。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

结果表明,10 个特征中可能有 3 个对预测很重要。

Feature: 0, Score: 0.00294
Feature: 1, Score: 0.00502
Feature: 2, Score: 0.00318
Feature: 3, Score: 0.00151
Feature: 4, Score: 0.51648
Feature: 5, Score: 0.43814
Feature: 6, Score: 0.02723
Feature: 7, Score: 0.00200
Feature: 8, Score: 0.00244
Feature: 9, Score: 0.00106

然后为特征重要性分数创建条形图。

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

决策树柱状图回归器特征重要性得分

CART 分类特征重要性

下面列出了拟合决策树分类器并汇总计算出的特征重要性分数的完整示例。

# decision tree for feature importance on a classification problem
from sklearn.datasets import make_classification
from sklearn.tree import DecisionTreeClassifier
from matplotlib import pyplot
# define dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, random_state=1)
# define the model
model = DecisionTreeClassifier()
# fit the model
model.fit(X, y)
# get importance
importance = model.feature_importances_
# summarize feature importance
for i,v in enumerate(importance):
	print('Feature: %0d, Score: %.5f' % (i,v))
# plot feature importance
pyplot.bar([x for x in range(len(importance))], importance)
pyplot.show()

运行该示例来拟合模型,然后报告每个特征的系数值。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

结果表明,10 个特征中可能有 4 个对预测很重要。

Feature: 0, Score: 0.01486
Feature: 1, Score: 0.01029
Feature: 2, Score: 0.18347
Feature: 3, Score: 0.30295
Feature: 4, Score: 0.08124
Feature: 5, Score: 0.00600
Feature: 6, Score: 0.19646
Feature: 7, Score: 0.02908
Feature: 8, Score: 0.12820
Feature: 9, Score: 0.04745

然后为特征重要性分数创建条形图。

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

决策树分类器特征重要性得分条形图

随机森林特征重要性

我们可以使用 Sklearn 中实现的随机森林算法作为随机森林回归器随机森林分类器类。

拟合后,模型提供了一个特征重要度 _ 属性,可以访问该属性来检索每个输入特征的相对重要度得分。

这种方法也可以与装袋和额外树算法一起使用。

让我们看一个回归和分类的例子。

随机森林回归特征重要性

下面列出了拟合一个随机森林回归器并总结计算出的特征重要性分数的完整示例。

# random forest for feature importance on a regression problem
from sklearn.datasets import make_regression
from sklearn.ensemble import RandomForestRegressor
from matplotlib import pyplot
# define dataset
X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, random_state=1)
# define the model
model = RandomForestRegressor()
# fit the model
model.fit(X, y)
# get importance
importance = model.feature_importances_
# summarize feature importance
for i,v in enumerate(importance):
	print('Feature: %0d, Score: %.5f' % (i,v))
# plot feature importance
pyplot.bar([x for x in range(len(importance))], importance)
pyplot.show()

运行该示例来拟合模型,然后报告每个特征的系数值。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

结果表明,10 个特征中可能有两三个对预测很重要。

Feature: 0, Score: 0.00280
Feature: 1, Score: 0.00545
Feature: 2, Score: 0.00294
Feature: 3, Score: 0.00289
Feature: 4, Score: 0.52992
Feature: 5, Score: 0.42046
Feature: 6, Score: 0.02663
Feature: 7, Score: 0.00304
Feature: 8, Score: 0.00304
Feature: 9, Score: 0.00283

然后为特征重要性分数创建条形图。

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

随机森林回归器特征重要性得分条形图

随机森林分类特征重要性

下面列出了拟合一个随机森林分类器并总结计算出的特征重要性分数的完整例子。

# random forest for feature importance on a classification problem
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from matplotlib import pyplot
# define dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, random_state=1)
# define the model
model = RandomForestClassifier()
# fit the model
model.fit(X, y)
# get importance
importance = model.feature_importances_
# summarize feature importance
for i,v in enumerate(importance):
	print('Feature: %0d, Score: %.5f' % (i,v))
# plot feature importance
pyplot.bar([x for x in range(len(importance))], importance)
pyplot.show()

运行该示例来拟合模型,然后报告每个特征的系数值。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

结果表明,10 个特征中可能有两三个对预测很重要。

Feature: 0, Score: 0.06523
Feature: 1, Score: 0.10737
Feature: 2, Score: 0.15779
Feature: 3, Score: 0.20422
Feature: 4, Score: 0.08709
Feature: 5, Score: 0.09948
Feature: 6, Score: 0.10009
Feature: 7, Score: 0.04551
Feature: 8, Score: 0.08830
Feature: 9, Score: 0.04493

然后为特征重要性分数创建条形图。

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

随机森林分类器特征重要性得分条形图

扩展功能重要性

XGBoost 是一个库,它提供了随机梯度提升算法的高效和有效的实现。

该算法可以通过xgbreversorXGBClassifier 类与 Sklearn 一起使用。

拟合后,模型提供了一个特征重要度 _ 属性,可以访问该属性来检索每个输入特征的相对重要度得分。

该算法也通过 Sklearn 通过梯度提升分类器梯度提升回归器类提供,并且可以使用相同的特征选择方法。

首先,安装 XGBoost 库,比如用 pip:

sudo pip install xgboost

然后,通过检查版本号来确认库安装正确并且工作正常。

# check xgboost version
import xgboost
print(xgboost.__version__)

运行该示例时,您应该会看到以下版本号或更高版本号。

0.90

有关 XGBoost 库的更多信息,请从这里开始:

让我们看一个关于回归和分类问题的特征重要性的 XGBoost 例子。

XGBoost 回归特征重要性

下面列出了拟合一个xgbrevoller并汇总计算出的特征重要性分数的完整示例。

# xgboost for feature importance on a regression problem
from sklearn.datasets import make_regression
from xgboost import XGBRegressor
from matplotlib import pyplot
# define dataset
X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, random_state=1)
# define the model
model = XGBRegressor()
# fit the model
model.fit(X, y)
# get importance
importance = model.feature_importances_
# summarize feature importance
for i,v in enumerate(importance):
	print('Feature: %0d, Score: %.5f' % (i,v))
# plot feature importance
pyplot.bar([x for x in range(len(importance))], importance)
pyplot.show()

运行该示例来拟合模型,然后报告每个特征的系数值。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

结果表明,10 个特征中可能有两三个对预测很重要。

Feature: 0, Score: 0.00060
Feature: 1, Score: 0.01917
Feature: 2, Score: 0.00091
Feature: 3, Score: 0.00118
Feature: 4, Score: 0.49380
Feature: 5, Score: 0.42342
Feature: 6, Score: 0.05057
Feature: 7, Score: 0.00419
Feature: 8, Score: 0.00124
Feature: 9, Score: 0.00491

然后为特征重要性分数创建条形图。

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

XGBRegressor 特征重要性分数条形图

扩展分类特征重要性

下面列出了拟合一个 XGBClassifier 并汇总计算出的特征重要性分数的完整示例。

# xgboost for feature importance on a classification problem
from sklearn.datasets import make_classification
from xgboost import XGBClassifier
from matplotlib import pyplot
# define dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, random_state=1)
# define the model
model = XGBClassifier()
# fit the model
model.fit(X, y)
# get importance
importance = model.feature_importances_
# summarize feature importance
for i,v in enumerate(importance):
	print('Feature: %0d, Score: %.5f' % (i,v))
# plot feature importance
pyplot.bar([x for x in range(len(importance))], importance)
pyplot.show()

运行该示例拟合模型,然后报告每个特征的系数值。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

结果表明,10 个特征中可能有 7 个对预测很重要。

Feature: 0, Score: 0.02464
Feature: 1, Score: 0.08153
Feature: 2, Score: 0.12516
Feature: 3, Score: 0.28400
Feature: 4, Score: 0.12694
Feature: 5, Score: 0.10752
Feature: 6, Score: 0.08624
Feature: 7, Score: 0.04820
Feature: 8, Score: 0.09357
Feature: 9, Score: 0.02220

然后为特征重要性分数创建条形图。

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

分类器特征重要性得分柱状图

排列特征重要性

排列特征重要性是一种独立于所用模型计算相对重要性分数的技术。

首先,模型适合数据集,例如不支持原生特征重要性分数的模型。然后使用该模型对数据集进行预测,尽管数据集中某个要素(列)的值会被打乱。对数据集中的每个要素重复这一过程。然后整个过程重复 3、5、10 次或更多次。结果是每个输入特征的平均重要性分数(以及给定重复的分数分布)。

这种方法可用于回归或分类,并要求选择表现指标作为重要性得分的基础,例如回归的均方误差和分类的准确性。

排列特征选择可以通过排列重要性()函数使用,该函数采用拟合模型、数据集(训练或测试数据集都可以)和评分函数。

让我们看一下这种特征选择方法,其算法本身不支持特征选择,特别是 k 近邻

回归的置换特征重要性

下面列出了拟合一个kneighborsrgressor并总结计算出的排列特征重要性分数的完整示例。

# permutation feature importance with knn for regression
from sklearn.datasets import make_regression
from sklearn.neighbors import KNeighborsRegressor
from sklearn.inspection import permutation_importance
from matplotlib import pyplot
# define dataset
X, y = make_regression(n_samples=1000, n_features=10, n_informative=5, random_state=1)
# define the model
model = KNeighborsRegressor()
# fit the model
model.fit(X, y)
# perform permutation importance
results = permutation_importance(model, X, y, scoring='neg_mean_squared_error')
# get importance
importance = results.importances_mean
# summarize feature importance
for i,v in enumerate(importance):
	print('Feature: %0d, Score: %.5f' % (i,v))
# plot feature importance
pyplot.bar([x for x in range(len(importance))], importance)
pyplot.show()

运行该示例来拟合模型,然后报告每个特征的系数值。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

结果表明,10 个特征中可能有两三个对预测很重要。

Feature: 0, Score: 175.52007
Feature: 1, Score: 345.80170
Feature: 2, Score: 126.60578
Feature: 3, Score: 95.90081
Feature: 4, Score: 9666.16446
Feature: 5, Score: 8036.79033
Feature: 6, Score: 929.58517
Feature: 7, Score: 139.67416
Feature: 8, Score: 132.06246
Feature: 9, Score: 84.94768

然后为特征重要性分数创建条形图。

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

具有排列特征重要性分数的 kneighbors 回归条形图

排列特征对分类的重要性

下面列出了拟合一个kneighborscclassifier并汇总计算出的排列特征重要性分数的完整示例。

# permutation feature importance with knn for classification
from sklearn.datasets import make_classification
from sklearn.neighbors import KNeighborsClassifier
from sklearn.inspection import permutation_importance
from matplotlib import pyplot
# define dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, random_state=1)
# define the model
model = KNeighborsClassifier()
# fit the model
model.fit(X, y)
# perform permutation importance
results = permutation_importance(model, X, y, scoring='accuracy')
# get importance
importance = results.importances_mean
# summarize feature importance
for i,v in enumerate(importance):
	print('Feature: %0d, Score: %.5f' % (i,v))
# plot feature importance
pyplot.bar([x for x in range(len(importance))], importance)
pyplot.show()

运行该示例来拟合模型,然后报告每个特征的系数值。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

结果表明,10 个特征中可能有两三个对预测很重要。

Feature: 0, Score: 0.04760
Feature: 1, Score: 0.06680
Feature: 2, Score: 0.05240
Feature: 3, Score: 0.09300
Feature: 4, Score: 0.05140
Feature: 5, Score: 0.05520
Feature: 6, Score: 0.07920
Feature: 7, Score: 0.05560
Feature: 8, Score: 0.05620
Feature: 9, Score: 0.03080

然后为特征重要性分数创建条形图。

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

具有排列特征重要性分数的 KNeighborsClassifier 条形图

具有重要性的特征选择

特征重要性分数可用于帮助解释数据,但也可直接用于帮助排列和选择对预测模型最有用的特征。

我们可以用一个小例子来证明这一点。

回想一下,我们的合成数据集有 1000 个例子,每个例子有 10 个输入变量,其中 5 个是冗余的,5 个对结果很重要。我们可以使用特征重要性分数来帮助选择相关的五个变量,并且只将它们用作预测模型的输入。

首先,我们可以将训练数据集分成训练集和测试集,并在训练数据集上训练模型,在测试集上进行预测,并使用分类准确率评估结果。我们将使用逻辑回归模型作为预测模型。

当我们使用特征重要性分数移除一些特征时,这为比较提供了基线。

下面列出了使用所有特征作为合成数据集输入来评估逻辑回归模型的完整示例。

# evaluation of a model using all features
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
# define the dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, random_state=1)
# split into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
# fit the model
model = LogisticRegression(solver='liblinear')
model.fit(X_train, y_train)
# evaluate the model
yhat = model.predict(X_test)
# evaluate predictions
accuracy = accuracy_score(y_test, yhat)
print('Accuracy: %.2f' % (accuracy*100))

运行示例首先在训练数据集上运行逻辑回归模型,并在测试集上对其进行评估。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到模型使用数据集中的所有特征实现了大约 84.55%的分类准确率。

Accuracy: 84.55

假设我们创建了数据集,我们会期望用一半数量的输入变量得到更好或相同的结果。

我们可以使用上面探讨的任何特征重要性分数,但是在这种情况下,我们将使用随机森林提供的特征重要性分数。

我们可以使用 SelectFromModel 类来定义我们希望计算重要性分数的模型,在这种情况下是随机森林分类器,以及要选择的特征数量,在这种情况下是 5。

...
# configure to select a subset of features
fs = SelectFromModel(RandomForestClassifier(n_estimators=200), max_features=5)

我们可以在训练数据集上拟合特征选择方法。

这将计算可用于对所有输入要素进行排名的重要性分数。然后,我们可以将该方法应用为转换,从数据集中选择 5 个最重要特征的子集。该转换将应用于训练数据集和测试集。

...
# learn relationship from training data
fs.fit(X_train, y_train)
# transform train input data
X_train_fs = fs.transform(X_train)
# transform test input data
X_test_fs = fs.transform(X_test)

将所有这些结合起来,下面列出了使用随机森林特征重要性进行特征选择的完整示例。

# evaluation of a model using 5 features chosen with random forest importance
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score

# feature selection
def select_features(X_train, y_train, X_test):
	# configure to select a subset of features
	fs = SelectFromModel(RandomForestClassifier(n_estimators=1000), max_features=5)
	# learn relationship from training data
	fs.fit(X_train, y_train)
	# transform train input data
	X_train_fs = fs.transform(X_train)
	# transform test input data
	X_test_fs = fs.transform(X_test)
	return X_train_fs, X_test_fs, fs

# define the dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, random_state=1)
# split into train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1)
# feature selection
X_train_fs, X_test_fs, fs = select_features(X_train, y_train, X_test)
# fit the model
model = LogisticRegression(solver='liblinear')
model.fit(X_train_fs, y_train)
# evaluate the model
yhat = model.predict(X_test_fs)
# evaluate predictions
accuracy = accuracy_score(y_test, yhat)
print('Accuracy: %.2f' % (accuracy*100))

运行该示例首先对数据集执行特征选择,然后像以前一样拟合和评估逻辑回归模型。

:考虑到算法或评估程序的随机性,或数值准确率的差异,您的结果可能会有所不同。考虑运行该示例几次,并比较平均结果。

在这种情况下,我们可以看到模型在数据集上实现了相同的表现,尽管输入要素的数量只有一半。不出所料,由随机森林计算的特征重要性分数使我们能够准确地对输入特征进行排名,并删除那些与目标变量无关的特征。

Accuracy: 84.55

进一步阅读

如果您想更深入地了解这个主题,本节将提供更多资源。

相关教程

蜜蜂

摘要

在本教程中,您发现了 python 中机器学习的特性重要性分数

具体来说,您了解到:

  • 特征重要性在预测建模问题中的作用。
  • 如何从线性模型和决策树计算和检查特征重要性?
  • 如何计算和复习排列特征重要性分数?

你有什么问题吗?
在下面的评论中提问,我会尽力回答。

如何选择机器学习的数据准备方式

原文:https://machinelearningmastery.com/choose-data-preparation-methods-for-machine-learning/

最后更新于 2020 年 7 月 15 日

数据准备是预测建模项目的重要部分。

数据准备的正确应用将把原始数据转化为一种表示,这种表示允许学习算法最大限度地利用数据并做出巧妙的预测。问题是选择一个变换或变换序列来产生一个有用的表示是非常具有挑战性的。以至于它可能被认为是一门艺术而不是一门科学。

在本教程中,您将发现可用于为预测建模数据集选择数据准备技术的策略。

完成本教程后,您将知道:

  • 可以根据数据集和算法的详细知识来选择数据准备技术,这是最常见的方法。
  • 数据准备技术可以作为建模管道中的另一个超参数进行网格搜索。
  • 数据转换可以并行应用于训练数据集,以创建许多提取的特征,在这些特征上可以应用特征选择并训练模型。

用我的新书机器学习的数据准备启动你的项目,包括分步教程和所有示例的 Python 源代码文件。

我们开始吧。

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

如何选择机器学习的数据准备方式
图片由 StockPhotosforFree 提供,保留部分权利。

教程概述

本教程分为四个部分;它们是:

  1. 选择数据准备技术的策略
  2. 方法 1:手动指定数据准备
  3. 方法 2:网格搜索数据准备方法
  4. 方法 3:并行应用数据准备方法

选择数据准备技术的策略

机器学习模型的表现只有用来训练它的数据好。

这给数据和用于准备建模的技术带来了沉重的负担。

数据准备是指用于将原始数据转换成最符合机器学习算法预期或要求的形式的技术。

这是一个挑战,因为我们无法知道原始数据的表示将导致预测模型的良好或最佳表现。

然而,我们经常不知道改善模型表现的预测因子的最佳再现。相反,预测器的重新工作更像是一门艺术,需要正确的工具和经验来找到更好的预测器表示。此外,我们可能需要搜索许多替代的预测器表示来提高模型表现。

—第十二页,特征工程与选择,2019 年。

相反,我们必须使用受控实验来系统地评估模型上的数据转换,以便发现什么工作得好或最好。

因此,在预测建模项目中,我们可以决定使用三种主要策略来为数据集选择数据准备技术或技术序列;它们是:

  1. 基于对数据和所选算法的深入了解,手动指定用于给定算法的数据准备。
  2. 测试一套不同的数据转换和转换序列,并发现对于一个或一系列模型,什么在数据集上工作得好或最好。
  3. 对数据并行应用一套数据转换,以创建大量工程特征,这些特征可以使用特征选择来减少并用于训练模型。

让我们依次仔细看看这些方法。

方法 1:手动指定数据准备

这种方法包括研究数据和特定算法的需求,并选择数据转换来改变您的数据以最好地满足需求。

许多从业者认为这是选择数据准备技术的唯一可能的方法,因为这通常是教科书中教授或描述的唯一方法。

这种方法可能包括首先选择一种算法,并为其专门准备数据,或者测试一套算法,并确保数据准备方法适合每种算法。

这种方法需要对数据有详细的了解。这可以通过查看每个变量的汇总统计数据、数据分布图,甚至可能通过统计测试来查看数据是否与已知分布相匹配来实现。

这种方法还需要详细了解您将使用的算法。这可以通过复习描述算法的教科书来实现。

从高层次来说,大多数算法的数据需求是众所周知的。

例如,以下算法可能对数值输入变量的规模和分布以及不相关和冗余变量的存在很敏感:

  • 线性回归(和扩展)
  • 逻辑回归
  • 线性判别分析
  • 高斯朴素贝叶斯
  • 神经网络
  • 支持向量机
  • k-最近邻

以下算法可能对数值输入变量的规模和分布不敏感,并且对不相关的冗余变量相当不敏感:

  • 决策图表
  • adaboost 算法
  • 袋装决策树
  • 随机森林
  • 梯度升压

这种方法的好处是,它可以让您确信您的数据已经根据特定算法的期望和要求进行了定制。这可能会带来良好甚至出色的表现。

缺点是,这可能是一个缓慢的过程,需要大量的分析、专业知识和潜在的研究。这也可能导致一种错误的信心,认为已经取得了好的或最好的结果,不可能或几乎不可能有进一步的改善。

有关这种数据准备方法的更多信息,请参见教程:

方法 2:网格搜索数据准备方法

这种方法承认算法可能有期望和要求,并且确实确保数据集的转换是为了满足这些要求而创建的,尽管它并不假设满足这些要求将导致最佳表现。

它为不明显和不直观的解决方案敞开了大门。

这可能是一个数据转换,“不应该工作””或“不应该适合算法”但结果良好或伟大的表现。或者,对于被认为是“绝对必要的”的输入变量,可能缺少数据转换,但仍会产生良好或出色的表现。

*这可以通过设计数据准备技术的网格搜索和/或流水线中的数据准备技术序列来实现。这可能涉及在单个选择的机器学习算法或一套机器学习算法上评估每一个。

结果将是大量的结果,这些结果将清楚地表明那些数据转换、转换序列和/或与模型相结合的转换,从而在数据集上产生良好或最佳的表现。

这些可以直接使用,尽管更有可能通过调整数据转换和模型超参数来提供进一步研究的基础,以最大限度地利用这些方法,并通过消融研究来确认建模管道的所有元素有助于熟练的预测。

我自己通常使用这种方法,并向希望在项目中快速取得好表现的初学者或从业者推荐这种方法。

这种方法的好处是,它总是会产生建模管道的建议,从而给出良好的相对结果。最重要的是,它可以为从业者挖掘不明显和不直观的解决方案,而不需要深厚的专业知识。

缺点是需要一些编程能力来实现网格搜索,以及评估许多不同的数据准备技术和管道所增加的计算成本。

有关这种数据准备方法的更多信息,请参见教程:

方法 3:并行应用数据准备方法

像前面的方法一样,使用这种方法,假设算法有期望和要求,并且它还允许找到违背这些期望的好的解决方案,尽管它更进一步。

这种方法还承认,适合同一数据的多个视角的模型可能比适合数据的单个视角的模型更有益。

这是通过对原始数据集并行执行多个数据转换来实现的,然后将所有转换的结果收集在一起,形成一个包含数百甚至数千个输入要素的大型数据集(即 Sklearn 中的 FeatureUnion 类可用于实现这一点)。它允许并行使用从不同变换中找到的良好输入特征。

对于使用的每个变换,输入要素的数量可能会急剧增加。因此,最好将这种方法与特征选择方法相结合,选择与目标变量最相关的特征子集。同样,这可能涉及应用一种、两种或更多种不同的特征选择技术来提供比正常情况下更大的有用特征子集。

或者,可以在生成的特征上使用降维技术(例如 PCA ,或者可以直接在生成的特征上训练执行自动特征选择的算法(例如随机森林)。

我喜欢把它看作是一种显式的特性工程方法,在这种方法中,我们从原始数据中生成我们可能想到的所有特性,分解数据中的分布和关系。然后选择最相关特征的子集并拟合模型。因为我们显式地使用数据转换将问题的复杂性分解为并行特征,所以它可能允许使用更简单的预测模型,例如带有强惩罚的线性模型,以帮助它忽略不太有用的特征。

这种方法的一种变体是在原始数据集的每个变换上拟合不同的模型,并使用集成模型来组合来自每个模型的预测。

这种通用方法的一个好处是,它允许模型利用同一原始数据的多个不同视角或视图,这是上面讨论的其他两种方法所缺乏的特性。这可能允许从数据集中挤出额外的预测技能。

这种方法的缺点是增加了计算成本,并且需要仔细选择特征选择技术和/或用于解释如此大量输入特征的模型。

有关这种数据准备方法的更多信息,请参见教程:

进一步阅读

如果您想更深入地了解这个主题,本节将提供更多资源。

相关教程

摘要

在本教程中,您发现了可用于为预测建模数据集选择数据准备技术的策略。

具体来说,您了解到:

  • 可以根据数据集和算法的详细知识来选择数据准备技术,这是最常见的方法。
  • 数据准备技术可以作为建模管道中的另一个超参数进行网格搜索。
  • 数据转换可以并行应用于训练数据集,以创建许多提取的特征,在这些特征上可以应用特征选择并训练模型。

你有什么问题吗?
在下面的评论中提问,我会尽力回答。*

机器学习是种人工智能领域的研究,通过让计算机从数据中模式中学习和改进,可以让计算机具备从经验中学习的能力。R是种流行的编程语言,被广泛用于数据分析和统计学习。在R中,可以使用不同的机器学习算法来处理和分析数据。 "Machine Learning Mastery with R" 是本书籍或教程,旨在帮助读者掌握使用R进行机器学习的技能。该书可能包含以下内容: 1. R的基础知识:介绍R编程语言的基本语法和数据结构,帮助读者理解如何在R环境中进行数据处理和分析。 2. 机器学习算法:介绍常见的机器学习算法,如线性回归、逻辑回归、决策树、随机森林等,并提供使用R实现这些算法的示例。 3. 特征工程:介绍如何选择和处理数据的特征,以提高机器学习算法的性能。这可能包括特征选择、特征缩放和特征转换等技术。 4. 模型评估和调优:介绍如何评估和优化机器学习模型的性能。这可能包括交叉验证、网格搜索和模型选择等技术。 5. 实际案例:提供些真实世界的案例研究,展示如何应用机器学习和R来解决实际问题。 通过学习"Machine Learning Mastery with R",读者可以了解机器学习的基本概念和技术,并掌握使用R语言进行机器学习的实践技能。这将使他们能够在实际项目中应用机器学习算法,从而更好地理解和分析数据,并做出准确的预测和决策。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值