数据预处理(系统整理)
前两节,我们总结了数据预处理中的一个小部分 -- 数据类型转换。这一节我们系统地总结下数据预处理相关知识点。纵然我们掌握了很多机器学习算法,十八般武艺,样样精通,可是在拿到一份数据集的时候,还是无法直接应用。因为我们的数据集真的是很“dirty”的,里面包含了大量的缺失值,异常值,离群值,非结构化数值等等。通常,在做机器学习或数据挖掘时,数据预处理会占用60%~70%的时间,所以这一部分也是整个机器学习任务中最具挑战性的部分。
Data preprocess.jpg
数据预处理的组成部分:
1.数据清洗
2.数据转换
3.数据描述
4.特征选择
5.特征提取
接下来,我们对这五个部分进行逐一地归纳总结。
1. 数据清洗
数据清洗主要包括缺失值,离群值,异常值以及重复值处理。本想选择一份包含这四种缺陷的数据集来做案例演示,由于我见到的数据集很有限,没有找到合适的,所以就选取不同的数据集进行说明。
1.1 缺失值处理
对缺失值的处理,我们有两种方法:1.当缺失数据的样本较少,或缺失数据的特征对最终结果的影响不大时,可删除含有缺失值的样本或者特征;2.当缺失的数据对最终结果影响较大时,这时我们需对缺失值进行填充。
Titanic数据集链接:https://pan.baidu.com/s/1EZqIAhSYE51NLDX1NNgBPQ
提取码:ln2z
#导入数据分析要用的工具包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
titanic = pd.read_csv('D:\\Py_dataset\\titanic.csv')
#查看该数据集的缺失值
titanic.isnull().sum()
#结果展示,可以看出‘Age’特征缺失了177个值,‘Cabin’列缺失了687个值,‘Embarked’缺失了2个值,我们的总样本数为891。
PassengerId 0
Survived 0
Pclass 0
Name 0
Sex 0
Age 177
SibSp 0
Parch 0
Ticket 0
Fare 0
Cabin 687
Embarked 2
dtype: int64
#由于Cabin列的缺失数据过多,所以很难将这一特征利用起来,可将其直接删掉。
titanic = titanic.drop('Cabin',axis = 1)
#Age特征对最终结果的影响较大,所以我们可以对其进行填充,这里我们使用乘客年龄的中位数对其进行填充。
titanic['Age'] = titanic['Age'].fillna(titanic['Age'].median())
#使用登陆最多的港口对Embarked列进行填充。
titanic['Embarked'].value_counts()
#结果展示,可以看出S是登录最多的港口。
S 644
C 168
Q 77
Name: Embarked, dtype: int64
titanic['Embarked'] = titanic['Embarked'].fillna('S')
#我们再次查看下数据的缺失情况
titanic.isnull().sum()
#结果展示,数据集中的缺失值都被我们处理掉了。
PassengerId 0
Survived 0
Pclass 0
Name 0
Sex 0
Age 0
SibSp 0
Parch 0
Ticket 0
Fare 0
Embarked 0
dtype: int64
1.2 离群值处理
举例说明:一般情况下,我们的身高都在170cm~180cm左右,而大姚的身高是226cm,这时我们就可以认为大姚的身高就是一个离群点。离群点对数据的统计特征会带来影响,平时我们会经常看到平均工资的数据,总会感叹自己又拖后腿了,这也是我们的工资水平都被那些超高工资的人给平均了。
我们观察离群点最简单的方法就是画盒图,在盒图的上下两边界之外就是离群点。对于离群点的处理方式,一般情况下可直接删除这些离群点。
#调用画图工具包seaborn
import seaborn as sns;sns.set()
plt.figure(figsize = (6,4))
plt.subplot(1,2,1)
sns.boxplot(y = 'Age',data = titanic)
plt.subplot(1,2,2)
sns.boxplot(y = 'Fare',data = titanic)
Outlier image.png
1.3 异常值处理
举例说明:某人在信息采集表中的收入栏填写的数值是-100,对于我们而言-100肯定是不符合常理的,所以像这样的数值就是异常值。对于这种数据,我们通常可以用平均收入替代该异常值,也可以直接删除该异常值。
1.4 重复值处理
有时候,我们在收集数据的时候,可能会对某一个样本记录两次,这样就会导致我们后期的统计结果出现偏差。在数据清洗的时候,就需要删除这些重复值。
这里以学生在线学习的数据集为例,实际上这份数据集是不重复的,因为我们可以在网上选择好多门课程,可以天天学习,每一次的学习都对应着一条记录,唯一不变的就是你的学号。在这里我们主要是学习重复数据的处理方法,不去深究这份数据是否真正的重复。
enrollments数据集链接:https://pan.baidu.com/s/1lKHwJFcsLe3W3DjG0KPniA
提取码:76rd
df = pd.read_csv('D:\\Py_dataset\\enrollments.csv')
#查看前10行数据,可以看到学号448对应了9条数据,我们假定这9条数据是相同的。
df.head(10)
enrollments.data.png
我们的目标是每个学号只保留一条学习记录,所以就需要将多余的记录删除掉。
df = df.drop_duplicates(['account_key'])
df.head()
new_enrollments.png
2. 数据转换
在我们对数据进行建模时,机器学习算法所能处理的数据类型为数值型,所以就需要我们对非数值型的数据进行格式转换,将其转化为数值型数据。涉及数据转换的内容,前面写的比较零散,这一节将这些零散的知识点串起来,具体内容可点击链接参考以前的方法总结。
2.1 离散型数据的转换方法:pd.map(), pd.get_dummies(), sklearn.LabelEncoder(),sklearn.OneHotEncoding()
详细内容可参考:https://www.jianshu.com/p/2c82088390f2
2.2 连续型数据的转换方法:对数据进行切割,pd.cut()
详细内容可参考:https://www.jianshu.com/p/867782d538ce
2.3 数据的归一化和标准化:sklearn.preprocessing.MinMaxScaler(),sklearn.preprocessing.StandardScaler()
数据归一化:v' = (v - min)/(max - min)
数据标准化:v' = (v - μ)/σ
详细内容可参考:https://www.jianshu.com/p/3056827b6513
3. 数据可视化
数据可视化可以帮助我们更加直观地认识数据,可以帮助我们发现数据所无法直接体现出来的规律。数据可视化是探索性数据分析(EDA)过程中非常重要的工具,我们的分析步骤通常为单特征分析 -- 双特征分析 -- 多特征分析。数据可视化同时也贯穿于数据分析的全过程,每一个阶段我们都可以对数据进行可视化展示。
数据可视化详细内容可参考:https://www.jianshu.com/p/74bfef922d12
4. 特征选择
下图是我们titanic数据集的前五行,我们将'Survived'列作为标签值,将其余的列作为特征值,假如我们要采用分类算法对其进行建模,是否我们要使用所有的特征呢?当然不是,从下图的数据集中就可以看出,'PassengerId','Name','Ticket'对最终结果'Survived'是没有任何影响的,所以这些特征我们不采用。我们尽可能的选择对最终结果影响较大的特征,这可能就需要我们具备一些领域知识来进行判断。当然如果不确定某个特征是否重要,我们可以做个对照试验,加上这个特征建立一个模型,不加这个特征建立一个模型,最终对比两个模型的效果。
titanic.png5. 特征提取
特征提取与特征选择不同,特征选择是从众多特征中选择对结果影响较大的特征,特征提取是对现有的特征进行组合,以较低维数的特征来尽可能地表达事物的全貌。我们最常用的特征提取方法有两种:LDA和PCA。
LDA:线性判别分析,是一种有监督学习的降维算法。其核心思想是:降维后的数据类别之间的距离尽可能的大,类内的距离尽可能的小。
LDA算法具体内容可参考:https://www.jianshu.com/p/aed99ea310e1
PCA:主成分分析,是一种无监督学习的降维算法。其核心思想是把原始数据投影到方差最大的方向,以保留尽可能多的特征。
PCA算法具体内容可参考:https://www.jianshu.com/p/59d1a9e63799
以上,我们对数据预处理做了一个完整的总结。在拿到一份数据集之后,我们就可以按照数据清洗、数据变换、数据可视化、特征选择,特征提取的方式对数据进行处理。数据的质量对最终的模型效果起着决定性作用,所以数据预处理工作是机器学习任务中最重要的一环。
由于我对数据挖掘与机器学习的认识水平很有限,在总结上述内容的过程中,难免存在错误,还请大家在阅读过程中提出宝贵的修改意见,谢谢!