机器学习为什么需要数据预处理

描述

数据预处理是准备原始数据并使其适合机器学习模型的过程。这是创建机器学习模型的第一步也是关键的一步。

创建机器学习项目时,我们并不总是遇到干净且格式化的数据。在对数据进行任何操作时,必须对其进行清理并以格式化的方式进行存储。为此,我们使用数据预处理任务。

为什么我们需要数据预处理?

现实世界的数据通常包含噪声、缺失值,并且可能采用无法直接用于机器学习模型的不可用格式。数据预处理是清理数据并使其适合机器学习模型所需的任务,这也提高了机器学习模型的准确性和效率。

它涉及以下步骤:

获取数据集

导入库

导入数据集

查找丢失的数据

编码分类数据

将数据集拆分为训练集和测试集

特征缩放

1)获取数据集

要创建机器学习模型,我们首先需要的是数据集,因为机器学习模型完全依赖于数据。以适当的格式针对特定问题收集的数据称为数据集。

出于不同的目的,数据集可能具有不同的格式,例如,如果我们想要创建用于商业目的的机器学习模型,那么数据集将与肝脏患者所需的数据集不同。因此每个数据集都不同于另一个数据集。为了在代码中使用数据集,我们通常将其放入 CSV文件中。然而,有时,我们可能还需要使用 HTML 或 xlsx 文件。

什么是 CSV 文件?

CSV 代表“逗号分隔值”文件;它是一种文件格式,允许我们保存表格数据,例如电子表格。它对于巨大的数据集很有用,并且可以在程序中使用这些数据集。

这里我们将使用一个演示数据集进行数据预处理,为了练习,可以从这里下载,“ https://www.superdatascience.com/pages/machine-learning。对于实际问题,我们可以在线下载数据集来自各种来源,例如https://www.kaggle.com/uciml/datasets、https://archive.ics.uci.edu/ml/index.php等。

我们还可以通过使用 Python 的各种 API 收集数据来创建数据集,并将该数据放入 .csv 文件中。

2) 导入库

为了使用Python进行数据预处理,我们需要导入一些预定义的Python库。这些库用于执行一些特定的工作。我们将使用三个特定的库来进行数据预处理,它们是:

Numpy: Numpy Python 库用于在代码中包含任何类型的数学运算。它是Python中科学计算的基础包。它还支持添加大型多维数组和矩阵。因此,在 Python 中,我们可以将其导入为:

将 numpy 导入为 nm  

这里我们使用了nm,它是 Numpy 的简称,它将在整个程序中使用。

Matplotlib:第二个库是matplotlib,它是一个 Python 2D 绘图库,使用这个库,我们需要导入一个子库pyplot。该库用于在 Python 中为代码绘制任何类型的图表。它将按如下方式导入:

将 matplotlib.pyplot 导入为 mpt  

这里我们使用 mpt 作为该库的简称。

Pandas:最后一个库是 Pandas 库,它是最著名的 Python 库之一,用于导入和管理数据集。它是一个开源数据操作和分析库。它将按如下方式导入:

在这里,我们使用 pd 作为该库的简称。考虑下图:

代码

3)导入数据集

现在我们需要导入为机器学习项目收集的数据集。但在导入数据集之前,我们需要将当前目录设置为工作目录。要在Spyder IDE中设置工作目录,我们需要按照以下步骤操作:

将 Python 文件保存在包含数据集的目录中。

转到 Spyder IDE 中的文件资源管理器选项,然后选择所需的目录。

单击 F5 按钮或运行选项来执行该文件。

注意:我们可以将任何目录设置为工作目录,但它必须包含所需的数据集。

在下图中,我们可以看到 Python 文件以及所需的数据集。现在,当前文件夹被设置为工作目录。

代码

read_csv() 函数:

现在要导入数据集,我们将使用pandas库的read_csv()函数,用于读取数据集文件并对其执行各种操作。使用此函数,我们可以在本地以及通过 URL 读取 csv 文件。

我们可以使用 read_csv 函数,如下所示:

 

data_set =  pd .read_csv('数据集.csv')  

 

这里,data_set是存储数据集的变量名称,在函数内部,我们传递了数据集的名称。一旦我们执行了上面这行代码,它将成功地将数据集导入到我们的代码中。我们还可以通过单击变量资源管理器部分来检查导入的数据集,然后双击data_set。考虑下图:

代码

如上图,索引从0开始,这是Python中默认的索引。我们还可以通过单击格式选项来更改数据集的格式。

提取因变量和自变量:

在机器学习中,区分数据集中的特征矩阵(自变量)和因变量非常重要。在我们的数据集中,有 3 个自变量,即Country、Age和Salary,以及一个因变量Purchasing。

提取自变量:

为了提取自变量,我们将使用Pandas 库的iloc[ ]方法。它用于从数据集中提取所需的行和列。

 

x =  data_set .iloc[:,:-1].values  

 

在上面的代码中,第一个冒号(:)用于获取所有行,第二个冒号(:)用于获取所有列。这里我们使用了 :-1,因为我们不想采用最后一列,因为它包含因变量。通过这样做,我们将得到特征矩阵。

通过执行上面的代码,我们将得到如下输出:

 

[['India' 38.0 68000.0]  
 ['France' 43.0 45000.0]  
 ['Germany' 30.0 54000.0]  
 ['France' 48.0 65000.0]  
 ['Germany' 40.0 nan]  
 ['India' 35.0 58000.0]  
 ['Germany' nan 53000.0]  
 ['France' 49.0 79000.0]  
 ['India' 50.0 88000.0]  
 ['France' 37.0 77000.0]]  

 

正如我们在上面的输出中看到的,只有三个变量。

提取因变量:

为了提取因变量,我们将再次使用 Pandas .iloc[] 方法。

 

y =  data_set .iloc[:,3].values  

 

在这里,我们仅获取了所有行和最后一列。它将给出因变量的数组。

通过执行上面的代码,我们将得到如下输出:

输出:

 

array(['No', 'Yes', 'No', 'No', 'Yes', 'Yes', 'No', 'Yes', 'No', 'Yes'],
      dtype=object)

 

数据类型=对象)

注意:如果您使用Python语言进行机器学习,则提取是必需的,但对于R语言则不需要。

4)处理缺失数据:

数据预处理的下一步是处理数据集中缺失的数据。如果我们的数据集包含一些缺失的数据,那么它可能会给我们的机器学习模型带来巨大的问题。因此,有必要处理数据集中存在的缺失值。

处理缺失数据的方法:

处理缺失数据主要有两种方法:

通过删除特定行:第一种方式通常用于处理空值。这样,我们只需删除由空值组成的特定行或列即可。但这种方式效率不高,删除数据可能会导致信息丢失,从而无法给出准确的输出。

通过计算平均值:这样,我们将计算包含任何缺失值的该列或行的平均值,并将其放在缺失值的位置。该策略对于具有年龄、薪水、年份等数字数据的特征非常有用。在这里,我们将使用这种方法。

为了处理缺失值,我们将在代码中使用Scikit-learn库,其中包含用于构建机器学习模型的各种库。这里我们将使用sklearn.preprocessing库的Imputer类。下面是它的代码:

 

#处理缺失数据(用平均值替换缺失数据)  
从 sklearn.preprocessing 导入 Imputer  
imputer =  Imputer (missing_values  = 'NaN' , 策略= '平均值' , 轴 =  0 )  
#将imputer对象拟合到自变量x。   
imputer imputer = imputer.fit(x[:, 1:3])  
#用计算出的平均值替换缺失数据  
x[:, 1:3]= imputer.transform(x[:, 1:3])  

 

输出:

 

array([['India', 38.0, 68000.0],
       ['France', 43.0, 45000.0],
       ['Germany', 30.0, 54000.0],
       ['France', 48.0, 65000.0],
       ['Germany', 40.0, 65222.22222222222],
       ['India', 35.0, 58000.0],
       ['Germany', 41.111111111111114, 53000.0],
       ['France', 49.0, 79000.0],
       ['India', 50.0, 88000.0],
       ['France', 37.0, 77000.0]], dtype=object

 

正如我们在上面的输出中看到的,缺失值已被替换为其余列值的平均值。

5)编码分类数据:

分类数据是具有某些类别的数据,例如在我们的数据集中;有两个分类变量,Country和Purchasing。

由于机器学习模型完全适用于数学和数字,但如果我们的数据集有分类变量,那么在构建模型时可能会产生麻烦。因此有必要将这些分类变量编码为数字。

对于国家变量:

首先,我们将国家变量转换为分类数据。为此,我们将使用预处理库中的LabelEncoder()类。

 

#分类数据  
#for 国家变量  
从 sklearn.preprocessing 导入 LabelEncoder  
label_encoder_x =  LabelEncoder ()  
x[:, 0]= label_encoder_x.fit_transform(x[:, 0])  

 

输出:

 

Out[15]: 
  array([[2, 38.0, 68000.0],
            [0, 43.0, 45000.0],
         [1, 30.0, 54000.0],
         [0, 48.0, 65000.0],
         [1, 40.0, 65222.22222222222],
         [2, 35.0, 58000.0],
         [1, 41.111111111111114, 53000.0],
         [0, 49.0, 79000.0],
         [2, 50.0, 88000.0],
        [0, 37.0, 77000.0]], dtype=object)

 

解释:

在上面的代码中,我们导入了sklearn库的LabelEncoder类。此类已成功将变量编码为数字。

但在我们的例子中,有三个国家变量,正如我们在上面的输出中看到的,这些变量被编码为 0、1 和 2。通过这些值,机器学习模型可以假设这些变量之间存在某种相关性。会产生错误输出的变量。因此,为了解决这个问题,我们将使用虚拟编码。

虚拟变量:

虚拟变量是那些值为 0 或 1 的变量。值 1 表示该变量在特定列中的存在,其余变量变为 0。通过虚拟编码,我们将拥有等于类别数的列数。

在我们的数据集中,我们有 3 个类别,因此它将生成具有 0 和 1 值的三列。对于虚拟编码,我们将使用预处理库的OneHotEncoder类。

 

#for 国家变量  
从 sklearn.preprocessing 导入 LabelEncoder、OneHotEncoder  
label_encoder_x =  LabelEncoder ()  
x[:, 0]= label_encoder_x.fit_transform(x[:, 0])  
#虚拟变量的编码  
onehot_encoder =  OneHotEncoder ( categorical_features = [0])    
x =  onehot_encoder .fit_transform(x).toarray()  

 

输出:

 

array([[0.00000000e+00, 0.00000000e+00, 1.00000000e+00, 3.80000000e+01,
        6.80000000e+04],
       [1.00000000e+00, 0.00000000e+00, 0.00000000e+00, 4.30000000e+01,
        4.50000000e+04],
       [0.00000000e+00, 1.00000000e+00, 0.00000000e+00, 3.00000000e+01,
        5.40000000e+04],
       [1.00000000e+00, 0.00000000e+00, 0.00000000e+00, 4.80000000e+01,
        6.50000000e+04],
       [0.00000000e+00, 1.00000000e+00, 0.00000000e+00, 4.00000000e+01,
        6.52222222e+04],
       [0.00000000e+00, 0.00000000e+00, 1.00000000e+00, 3.50000000e+01,
        5.80000000e+04],
       [0.00000000e+00, 1.00000000e+00, 0.00000000e+00, 4.11111111e+01,
        5.30000000e+04],
       [1.00000000e+00, 0.00000000e+00, 0.00000000e+00, 4.90000000e+01,
        7.90000000e+04],
       [0.00000000e+00, 0.00000000e+00, 1.00000000e+00, 5.00000000e+01,
        8.80000000e+04],
       [1.00000000e+00, 0.00000000e+00, 0.00000000e+00, 3.70000000e+01,
        7.70000000e+04]])

 

正如我们在上面的输出中看到的,所有变量都被编码为数字 0 和 1,并分为三列。

通过单击 x 选项,可以在变量资源管理器部分中更清楚地看到它:

代码

对于购买的变量:

 

labelencoder_y =  LabelEncoder ()  


y =  labelencoder_y .fit_transform(y)  

 

对于第二个分类变量,我们将仅使用LableEncoder类的 labelencoder 对象。这里我们没有使用OneHotEncoder类,因为购买的变量只有 yes 或 no 两个类别,并且自动编码为 0 和 1。

输出:

 

Out[17]: array([0, 1, 0, 0, 1, 1, 0, 1, 0, 1])

 

view:

代码

6)将数据集分为训练集和测试集

在机器学习数据预处理中,我们将数据集分为训练集和测试集。这是数据预处理的关键步骤之一,因为通过这样做,我们可以提高机器学习模型的性能。

假设,如果我们通过数据集对机器学习模型进行训练,并通过完全不同的数据集对其进行测试。那么,这会给我们的模型理解模型之间的相关性带来困难。

如果我们的模型训练得很好,它的训练精度也很高,但是我们给它提供了一个新的数据集,那么它的性能就会下降。因此,我们总是尝试建立一个在训练集和测试数据集上都表现良好的机器学习模型。在这里,我们可以将这些数据集定义为:

代码

训练集:用于训练机器学习模型的数据集子集,我们已经知道输出。

测试集:用于测试机器学习模型的数据集子集,模型通过使用测试集来预测输出。

为了分割数据集,我们将使用以下代码行:

 

#从 sklearn.model_selection 导入 train_test_split  


x_train,x_test,y_train,  y_test =  train_test_split (x,y,  test_size =  0 .2,  random_state = 0 )  

 

解释:

在上面的代码中,第一行用于将数据集数组拆分为随机训练和测试子集。

在第二行中,我们使用了四个变量作为输出:

x_train:训练数据的特征

x_test:测试数据的特征

y_train:训练数据的因变量

y_test:测试数据的自变量

在train_test_split()函数中,我们传递了四个参数,其中前两个用于数据数组,test_size用于指定测试集的大小。test_size 可能是 0.5、.3 或 .2,它告诉我们训练集和测试集的划分比例。

最后一个参数random_state用于设置随机生成器的种子,以便始终得到相同的结果,最常用的值为 42。

输出:

通过执行上面的代码,我们将得到4个不同的变量,可以在变量资源管理器部分看到。

代码

正如我们在上图中看到的,x 和 y 变量被分为 4 个具有相应值的不同变量。

7) 特征缩放

特征缩放是机器学习中数据预处理的最后一步。它是一种将数据集的自变量标准化在特定范围内的技术。在特征缩放中,我们将变量放在相同的范围和相同的比例中,以便没有任何变量支配其他变量。

考虑以下数据集:

代码

正如我们所看到的,年龄和薪水列值不在同一范围内。机器学习模型基于欧几里德距离,如果我们不缩放变量,那么它将在我们的机器学习模型中引起一些问题。

欧几里德距离给出为:

代码

如果我们根据年龄和薪水计算任意两个值,那么薪水值将主导年龄值,并且会产生不正确的结果。因此,为了解决这个问题,我们需要对机器学习进行特征缩放。

机器学习中有两种执行特征缩放的方法:

标准化

代码

正常化

代码

在这里,我们将对数据集使用标准化方法。

对于特征缩放,我们将导入sklearn.preprocessing库的StandardScaler类:

从 sklearn.preprocessing 导入 StandardScaler  

现在,我们将为自变量或特征创建StandardScaler类的对象。然后我们将拟合和转换训练数据集。

 

st_x = 标准缩放器()  


x_train =  st_x .fit_transform(x_train)  

 

对于测试数据集,我们将直接应用transform()函数而不是fit_transform(),因为它已经在训练集中完成了。

 

x_test =  st_x .transform(x_test)  

 

输出:

通过执行上面的代码行,我们将得到 x_train 和 x_test 的缩放值:

x_train:

代码

x_test:

代码

正如我们在上面的输出中看到的,所有变量都在值 -1 到 1 之间缩放。

注意:这里,我们没有缩放因变量,因为只有两个值 0 和 1。但是如果这些变量有更多的值范围,那么我们还需要缩放这些变量。

结合所有步骤:

现在,最后,我们可以将所有步骤组合在一起,使完整的代码更容易理解。

 

# 导入库  


将 numpy 导入为 nm  


将 matplotlib.pyplot 导入为 mtp  


将 pandas 导入为 pd  


  


#导入数据集  


data_set =  pd .read_csv('数据集.csv')  


  


#提取自变量  


x =  data_set .iloc[:, :-1].values  


  


#提取因变量  


y =  data_set .iloc[:, 3].values  


  


#处理缺失数据(用平均值替换缺失数据)  


从 sklearn.preprocessing 导入 Imputer  


imputer =  Imputer (missing_values  = 'NaN' , 策略= '平均值' , 轴 =  0 )  


  


#将输入对象拟合到独立变量x。   


imputer imputer = imputer.fit(x[:, 1:3])  


  


#用计算出的平均值替换缺失数据  


x[:, 1:3]= imputer.transform(x[:, 1:3])  


  


#for 国家变量  


从 sklearn.preprocessing 导入 LabelEncoder、OneHotEncoder  


label_encoder_x =  LabelEncoder ()  


x[:, 0]= label_encoder_x.fit_transform(x[:, 0])  


  


#虚拟变量的编码  


onehot_encoder =  OneHotEncoder ( categorical_features = [0])    


x =  onehot_encoder .fit_transform(x).toarray()  


  


#购买变量的编码  


labelencoder_y =  LabelEncoder ()  


y =  labelencoder_y .fit_transform(y)  


  


# 将数据集分为训练集和测试集。  


从 sklearn.model_selection 导入 train_test_split  


x_train,x_test,y_train,  y_test =  train_test_split (x,y,  test_size =  0 .2,  random_state = 0 )  


  


#数据集的特征缩放  


从 sklearn.preprocessing 导入 StandardScaler  


st_x = 标准缩放器()  


x_train =  st_x .fit_transform(x_train)  


x_test =  st_x .transform(x_test)  

 

在上面的代码中,我们将所有数据预处理步骤包含在一起。但有些步骤或代码行并不是所有机器学习模型都必需的。因此,我们可以将它们从我们的代码中排除,使其可重用于所有模型。

        审核编辑:彭菁

 

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分