
数据预处理(EDA)概述
在加载数据之后,深入机器学习或统计建模之前,数据预处理是一个重要的步骤。EDA,也称为探索性数据分析,是对已有的原始数据在尽量少的先验假定下进行探索,发掘数据数据的结构和内在规律的一种数据分析方法。
数据的处理包括以下几个主要步骤。在这里,我们将数据描述和数据清理也归为广义的EDA范畴。
数据的描述数据的清理缺失数据的管理非数值性数据的处理数据降维处理数据可视化数据描述
当外部文件中的数据读入到 Pandas 的 DataFrame 以后,通过得到数据的内容,统计信息和描述信息对数据内容有初步的了解。以下的例子以 kaggle 的项目 Titanic: Machine Learning from Disaster 为例演示数据描述功能。其中,例子中用到的数据已经上载到 github,见程序第4行的数据链接。
# 调用pandds软件包,从csv文件加载数据到DatFrame; import pandas as pd ur_data = https://raw.githubusercontent.com/yunchuangao777/dataset/master/train.csv df_data = pd.read_csv(ur_data) # 显示数据的头10行; print(数据的头5行:) print(df_data.head(5)) print(\n) # 显示数据的末10行; print(数据的最后5行:) print(df_data.tail(5)) print(\n) # 数据的统计信息 print(数据的统计信息:) df_data.info() print(\n) # 数据描述 print(数据的描述:) print(df_data.describe()) print(\n)运行输出:
数据的头5行: PassengerId Survived Pclass ... Fare Cabin Embarked 0 1 0 3 ... 7.2500 NaN S 1 2 1 1 ... 71.2833 C85 C 2 3 1 3 ... 7.9250 NaN S 3 4 1 1 ... 53.1000 C123 S 4 5 0 3 ... 8.0500 NaN S [5 rows x 12 columns] 数据的最后5行: PassengerId Survived Pclass ... Fare Cabin Embarked 886 887 0 2 ... 13.00 NaN S 887 888 1 1 ... 30.00 B42 S 888 889 0 3 ... 23.45 NaN S 889 890 1 1 ... 30.00 C148 C 890 891 0 3 ... 7.75 NaN Q [5 rows x 12 columns] 数据的统计信息: RangeIndex: 891 entries, 0 to 890 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 PassengerId 891 non-null int64 1 Survived 891 non-null int64 2 Pclass 891 non-null int64 3 Name 891 non-null object 4 Sex 891 non-null object 5 Age 714 non-null float64 6 SibSp 891 non-null int64 7 Parch 891 non-null int64 8 Ticket 891 non-null object 9 Fare 891 non-null float64 10 Cabin 204 non-null object 11 Embarked 889 non-null object dtypes: float64(2), int64(5), object(5) memory usage: 83.7+ KB 数据的描述: PassengerId Survived Pclass ... SibSp Parch Fare count 891.000000 891.000000 891.000000 ... 891.000000 891.000000 891.000000 mean 446.000000 0.383838 2.308642 ... 0.523008 0.381594 32.204208 std 257.353842 0.486592 0.836071 ... 1.102743 0.806057 49.693429 min 1.000000 0.000000 1.000000 ... 0.000000 0.000000 0.000000 25% 223.500000 0.000000 2.000000 ... 0.000000 0.000000 7.910400 50% 446.000000 0.000000 3.000000 ... 0.000000 0.000000 14.454200 75% 668.500000 1.000000 3.000000 ... 1.000000 0.000000 31.000000 max 891.000000 1.000000 3.000000 ... 8.000000 6.000000 512.329200 [8 rows x 7 columns]数据清理
数据清理,包括清除无关信息,以及冗余信息。无关信息需要人们基于项目本身的知识来判断。而冗余信息的判断,可以借助一些统计分析:
相关系数(Correlation):相关系数高(接近1.0)的两列,被认为含有重复信息;方差(Variance):方差特别小(接近0)的列,被认为含有无用信息;离群值(Outlier):与其他值相比差异特别大的值,常因为错误输入信息导致。以下的例子中,根据经验,我们相信 Name, Ticket, Embarked三列的信息对目标(即生存)没有影响,因此将这三列从数据中删除。
# 调用pandds软件包,从csv文件加载数据到DatFrame; import pandas as pd import numpy as np ur_data = https://raw.githubusercontent.com/yunchuangao777/dataset/master/train.csv df_data = pd.read_csv(ur_data) # 清除无关信息 drop_column = [Name,Ticket,Embarked] df_data.drop(drop_column, axis= 1, inplace = True) # 显示剩余的列名 print(df_data.columns)运行输出:
Index([PassengerId, Survived, Pclass, Sex, Age, SibSp, Parch, Fare, Cabin], dtype=object)缺失数据管理
在 DataFrame 中,缺失数据以 NaN 标识。缺失数据的处理方式有:
去除含有缺失数据的行或者列。这样虽然简单,但是会损失有价值的信息。Imputation:利用其他的信息填补缺失的数据,比如:用同一列中其他非空数据的平均值/中值填补;用同一列中出现频率最高的数值填补;基于常识,用0或者其他常数填补。基于算法的数据填补:比如利用k-nearest neighbor算法,利用缺失值附近的信息。其他的算法:诸如 stochastic regression; extrapolation/intrapolation; hot-deck imputation。以下的函数可以用来检查DataFrame中每一列的数据缺失情况。
# 调用pandds软件包,从csv文件加载数据到DatFrame; import pandas as pd ur_data = https://raw.githubusercontent.com/yunchuangao777/dataset/master/train.csv df_data = pd.read_csv(ur_data) # 检测 DataFrame 数据缺失的函数; def check_missing_data(df): total = df.isnull().sum().sort_values(ascending = False) percent = round(df.isnull().sum().sort_values(ascending = False) * 100 /len(df),2) return pd.concat([total, percent], axis=1, keys=[Total,Percent]) # 调用函数检查数据缺失的比率 df_missing = check_missing_data(df_data) print(df_missing)运行输出:
Total Percent Cabin 687 77.10 Age 177 19.87 Embarked 2 0.22 PassengerId 0 0.00 Survived 0 0.00 Pclass 0 0.00 Name 0 0.00 Sex 0 0.00 SibSp 0 0.00 Parch 0 0.00 Ticket 0 0.00 Fare 0 0.00在上面的例子中,列Cabin 有缺失的数据,以 NaN 标示。一个简单的处理缺失数据的方式,就是用0和1填补 Cabin的缺失数据。因为Cabin本身的字符没有意义,所以在 Cabin缺失的位置填0,并且用1替代Cabin的原有非空字符。
# 调用pandds软件包,从csv文件加载数据到DatFrame; import pandas as pd import numpy as np ur_data = https://raw.githubusercontent.com/yunchuangao777/dataset/master/train.csv df_data = pd.read_csv(ur_data) # 用0取代缺失的数据;1取代非空数据; df_data[Cabin]=np.where(df_data[Cabin].isnull(),0,1) # 检查是否还有缺失数据 print(df_data[Cabin].isnull().sum())运行输出:
0非数值型(离散)数据的处理
多数机器模型要求输入的特征值是数值型的,因此需要将非数值型数据转化为数值型。
最简单的方法,就是去除非数值型数据,这样虽然简单,但是会损失有价值的信息。较为常用的方式:Label Encoding。例如下面的例子,将male用0替代,female用1替代。One-hot encoding:使用N位状态寄存器来对N个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候,其中只有一位有效。这种方法扩充了特征值,同时会占用更多存储空间。# 调用pandds软件包,从csv文件加载数据到DatFrame; import pandas as pd import numpy as np ur_data = https://raw.githubusercontent.com/yunchuangao777/dataset/master/train.csv df_data = pd.read_csv(ur_data) # 对性别进行编码; genders = {"male": 0, "female": 1} # Label encoding; df_data[Sex] = df_data[Sex].map(genders) # 检查数据; print(df_data[Sex])运行输出:
0 0 1 1 2 1 3 1 4 0 .. 886 0 887 1 888 1 889 0 890 0 Name: Sex, Length: 891, dtype: int64数据降维处理
当数据量非常大,或者特征值的数量相比样本数非常大时,需要对原数据进行降维处理。降维处理的目的是降低数据维度的同时尽可能保留原数据的有价值信息。主要方法有:
PCA: principle component analysis;ICA: independent component analysis;Factor analysis.