ML 用统计数据理解数据


在处理机器学习项目时,通常我们会忽略两个最重要的部分,称为 数学 and data .这是因为,我们知道 ML 是一种数据驱动的方法,我们的 ML 模型产生的结果与我们提供给它的数据一样好或一样坏。

在上一章中,我们讨论了如何将 CSV 数据上传到我们的 ML 项目中,但最好在上传之前了解数据。我们可以通过统计和可视化两种方式来理解数据。

在本章中,在以下 Python 秘籍的帮助下,我们将通过统计来理解 ML 数据。

查看原始数据


第一个秘诀是查看原始数据。查看原始数据很重要,因为我们在查看原始数据后获得的洞察力将增加我们更好地预处理和处理 ML 项目数据的机会。

下面是一个 Python 脚本,它使用 Pandas DataFrame 的 head() 函数在 Pima Indians 糖尿病数据集上查看前 50 行以更好地理解它:

例子

from pandas import read_csv
path = r"C:\pima-indians-diabetes.csv"
headernames = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(path, names=headernames)
print(data.head(50))
preg   plas  pres    skin  test  mass   pedi    age      class
0      6      148     72     35   0     33.6    0.627    50    1
1      1       85     66     29   0     26.6    0.351    31    0
2      8      183     64      0   0     23.3    0.672    32    1
3      1       89     66     23  94     28.1    0.167    21    0
4      0      137     40     35  168    43.1    2.288    33    1
5      5      116     74      0   0     25.6    0.201    30    0
6      3       78     50     32   88    31.0    0.248    26    1
7     10      115      0      0   0     35.3    0.134    29    0
8      2      197     70     45  543    30.5    0.158    53    1
9      8      125     96      0   0     0.0     0.232    54    1
10     4      110     92      0   0     37.6    0.191    30    0
11    10      168     74      0   0     38.0    0.537    34    1
12    10      139     80      0   0     27.1    1.441    57    0
13     1      189     60     23  846    30.1    0.398    59    1
14     5      166     72     19  175    25.8    0.587    51    1
15     7      100      0      0   0     30.0    0.484    32    1
16     0      118     84     47  230    45.8    0.551    31    1
17     7      107     74      0   0     29.6    0.254    31    1
18     1      103     30     38  83     43.3    0.183    33    0
19     1      115     70     30  96     34.6    0.529    32    1
20     3      126     88     41  235    39.3    0.704    27    0
21     8       99     84      0   0     35.4    0.388    50    0
22     7      196     90      0   0     39.8    0.451    41    1
23     9      119     80     35   0     29.0    0.263    29    1
24    11      143     94     33  146    36.6    0.254    51    1
25    10      125     70     26  115    31.1    0.205    41    1
26     7      147     76      0   0     39.4    0.257    43    1
27     1       97     66     15  140    23.2    0.487    22    0
28    13      145     82     19  110    22.2    0.245    57    0
29     5      117     92      0   0     34.1    0.337    38    0
30     5      109     75     26   0     36.0    0.546    60    0
31     3      158     76     36  245    31.6    0.851    28    1
32     3       88     58     11   54    24.8    0.267    22    0
33     6       92     92      0   0     19.9    0.188    28    0
34    10      122     78     31   0     27.6    0.512    45    0
35     4      103     60     33  192    24.0    0.966    33    0
36    11      138     76      0   0     33.2    0.420    35    0
37     9      102     76     37   0     32.9    0.665    46    1
38     2       90     68     42   0     38.2    0.503    27    1
39     4      111     72     47  207    37.1    1.390    56    1
40     3      180     64     25   70    34.0    0.271    26    0
41     7      133     84      0   0     40.2    0.696    37    0
42     7      106     92     18   0     22.7    0.235    48    0
43     9      171    110     24  240    45.4    0.721    54    1
44     7      159     64      0   0     27.4    0.294    40    0
45     0      180     66     39   0     42.0    1.893    25    1
46     1      146     56      0   0     29.7    0.564    29    0
47     2       71     70     27   0     28.0    0.586    22    0
48     7      103     66     32   0     39.1    0.344    31    1
49     7      105      0      0   0     0.0     0.305    24    0

我们可以从上面的输出中观察到,第一列给出了行号,这对于引用特定的观察非常有用。

检查数据的维度


了解我们的 ML 项目有多少行和列数据始终是一个好习惯。背后的原因是:

  • 假设如果我们有太多的行和列,那么运行算法和训练模型需要很长时间。

  • 假设如果我们的行和列太少,那么我们将没有足够的数据来很好地训练模型。

以下是通过在 Pandas Data Frame 上打印 shape 属性实现的 Python 脚本。我们将在 iris 数据集上实现它,以获取其中的总行数和列数。

例子

from pandas import read_csv
path = r"C:\iris.csv"
data = read_csv(path)
print(data.shape)
(150, 4)

我们可以很容易地从输出中观察到,我们将要使用的 iris 数据集有 150 行和 4 列。

获取每个属性的数据类型


了解每个属性的数据类型是另一个好习惯。背后的原因是,根据需要,有时我们可能需要将一种数据类型转换为另一种数据类型。例如,我们可能需要将字符串转换为浮点数或整数来表示分类或序数值。我们可以通过查看原始数据来了解属性的数据类型,但另一种方法是使用 Pandas DataFrame 的 dtypes 属性。借助 dtypes 属性,我们可以对每个属性数据类型进行分类。可以借助下面的Python脚本来理解:

例子

from pandas import read_csv
path = r"C:\iris.csv"
data = read_csv(path)
print(data.dtypes)
sepal_length  float64
sepal_width   float64
petal_length  float64
petal_width   float64
dtype: object

从上面的输出中,我们可以很容易地得到每个属性的数据类型。

数据统计汇总


我们已经讨论过 Python 方法来获取数据的形状,即行数和列数,但很多时候我们需要查看数据形状的摘要。可以借助 Pandas DataFrame 的 describe() 函数来完成,该函数进一步提供了每个数据属性的以下 8 个统计属性:

  • Count
  • Mean
  • 标准差
  • 最小值
  • 最大值
  • 25%
  • 中位数,即 50%
  • 75%

例子

from pandas import read_csv
from pandas import set_option
path = r"C:\pima-indians-diabetes.csv"
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(path, names=names)
set_option('display.width', 100)
set_option('precision', 2)
print(data.shape)
print(data.describe())
(768, 9)
            preg      plas       pres      skin      test        mass       pedi      age      class
count 768.00      768.00    768.00     768.00    768.00     768.00     768.00    768.00    768.00
mean    3.85      120.89     69.11      20.54     79.80      31.99       0.47     33.24      0.35
std     3.37       31.97     19.36      15.95    115.24       7.88       0.33     11.76      0.48
min     0.00        0.00      0.00       0.00      0.00       0.00       0.08     21.00      0.00
25%     1.00       99.00     62.00       0.00      0.00      27.30       0.24     24.00      0.00
50%     3.00      117.00     72.00      23.00     30.50      32.00       0.37     29.00      0.00
75%     6.00      140.25     80.00      32.00    127.25      36.60       0.63     41.00      1.00
max    17.00      199.00    122.00      99.00    846.00      67.10       2.42     81.00      1.00

从上面的输出中,我们可以观察到 Pima Indian Diabetes 数据集的数据统计摘要以及数据的形状。

审查班级分布


类分布统计在我们需要知道类值平衡的分类问题中很有用。了解类值分布很重要,因为如果我们有高度不平衡的类分布,即一个类比其他类有更多的观察,那么它可能需要在我们的机器学习项目的数据准备阶段进行特殊处理。借助 Pandas DataFrame,我们可以轻松地在 Python 中获取类分布。

例子

from pandas import read_csv
path = r"C:\pima-indians-diabetes.csv"
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(path, names=names)
count_class = data.groupby('class').size()
print(count_class)
Class
0  500
1  268
dtype: int64

从上面的输出可以清楚地看出,0 类的观察数量几乎是 1 类的观察数量的两倍。

查看属性之间的相关性


两个变量之间的关系称为相关性。在统计学中,计算相关性最常用的方法是皮尔逊相关系数。它可以有如下三个值:

  • 系数值 = 1 : 代表满 positive 变量之间的相关性。

  • 系数值 = -1 : 代表满 negative 变量之间的相关性。

  • 系数值 = 0 : 它代表 no 变量之间完全相关。

在将数据集用于 ML 项目之前,检查数据集中属性的成对相关性总是有好处的,因为如果我们具有高度相关的属性,一些机器学习算法(如线性回归和逻辑回归)将表现不佳。在 Python 中,我们可以借助 Pandas DataFrame 上的 corr() 函数轻松计算数据集属性的相关矩阵。

例子

from pandas import read_csv
from pandas import set_option
path = r"C:\pima-indians-diabetes.csv"
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(path, names=names)
set_option('display.width', 100)
set_option('precision', 2)
correlations = data.corr(method='pearson')
print(correlations)
preg     plas     pres     skin     test      mass     pedi       age      class
preg     1.00     0.13     0.14     -0.08     -0.07   0.02     -0.03       0.54   0.22
plas     0.13     1.00     0.15     0.06       0.33   0.22      0.14       0.26   0.47
pres     0.14     0.15     1.00     0.21       0.09   0.28      0.04       0.24   0.07
skin    -0.08     0.06     0.21     1.00       0.44   0.39      0.18      -0.11   0.07
test    -0.07     0.33     0.09     0.44       1.00   0.20      0.19      -0.04   0.13
mass     0.02     0.22     0.28     0.39       0.20   1.00      0.14       0.04   0.29
pedi    -0.03     0.14     0.04     0.18       0.19   0.14      1.00       0.03   0.17
age      0.54     0.26     0.24     -0.11     -0.04   0.04      0.03       1.00   0.24
class    0.22     0.47     0.07     0.07       0.13   0.29      0.17       0.24   1.00

上面输出中的矩阵给出了数据集中所有属性对之间的相关性。

审查属性分布的偏差


偏度可以定义为假设为高斯分布但在一个方向或另一个方向或向左或向右出现扭曲或偏移的分布。审查属性的偏度是一项重要任务,原因如下:

  • 数据中存在的偏度需要在数据准备阶段进行校正,以便我们可以从模型中获得更高的准确性。

  • 大多数 ML 算法都假设数据具有高斯分布,即钟形曲线数据的正态分布。

在 Python 中,我们可以通过 Pandas DataFrame 上的 skew() 函数轻松计算每个属性的 skew。

例子

from pandas import read_csv
path = r"C:\pima-indians-diabetes.csv"
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(path, names=names)
print(data.skew())
preg   0.90
plas   0.17
pres  -1.84
skin   0.11
test   2.27
mass  -0.43
pedi   1.92
age    1.13
class  0.64
dtype: float64

从上面的输出中,可以观察到正或负偏斜。如果该值更接近于零,则它显示的偏斜较小。