机器学习数据预处理
我本身是做机器学习的,在机器学习中,数据分析也是其中重要的一环,比如上一节内容, 我专门聊到了如何做疫情数据的分析。
一般来说,分析数据的前奏,分析完数据,我们基本对数据有一个大体概念,如果是要拿这数据做机器学习, 接下来就要对数据做加工处理,处理成模型能够接受的样子。而这个课程就是教你怎么处理真实的数据。
网上数据很多,我发现还是莺尾花的数据最好做,又好可视化,又好做异常处理,还好用于机器学习,所以这次我还是会拿这份数据。 不过先提醒下大家,原始的莺尾花数据还挺干净的,我手动污染了一下数据,加了些脏数据进去 用于演示接下来的流程。
本节我会按照下面的几个步骤:
加载数据¶
因为我还没做本地上传文件的功能,所以我做了一个 init_files()
的功能,从我的服务器下载一个 iris.csv
文件到浏览器的沙箱中。 如果你需要下载 iris.csv
到本地做实验,请点击这里 。
请一定要点击一次上面的运行按钮,不然没有数据,你做不了下面的练习。 下载数据后,用 Excel 打开能看到类似下面的界面。
接下来,我们在用 Pandas 加载到 DataFrame 中来。 这里我们使用到了读取数据那一节讲得内容,更多读取方式,请回看这节内容。
NaN数据处理¶
NaN 数据表示的是那些空值数据,在数据表中为空,或者没有记录上值的数据。空数据对机器学习的危害还是挺大的,举例像神经网络这样的算法, 如果训练的时候来了个空值,它很可能就学废
了。其他机器学习的方法,多少都受到空值的影响。所以我们首先就是先确认数据中有没有空值。
在 Iris 的原始数据中(没有被我修改过),是不存在空值的。我想让你体验一下有空值是什么情况,所以特意加上了一些有问题的数据。
用 Pandas 自带的 isna()
功能就能找到每一个格子是不是空值。
不过当你运行,你会发现,这也太多数据了,我怎么才能知道这一批数据中是否存在空值,做一个快速验证呢?
在 .isna()
的结果后面再加上个 .any()
这样就可以在有任意值为空值的时候输出 True
了。而且它还帮我们标出来了哪一个 column 有空值。
那好,我们看看具体怎么定位到这一行数据吧。看看真实情况是什么。
好了,现在找到了空值问题,接下来是要如何处理空值了。方案可以分为两种:
- 丢弃掉这一行
- 给空值填上一个你觉得合理的数
第一种方法很简单粗暴,第二种方法比较麻烦,因为什么是合理的本来就比较主观,你可以填上平均数,中值等,但我觉得都不太合理。所以当这种问题数据量比较少的时候, 我还是偏向于直接丢弃。我在异常数据处理的课程里有提到过很多种方法。
再来看看还有没有 NaN。
异常值处理¶
如何才能查找到异常值呢?我个人喜欢用最直观的画图方式来看,通过数据图片,直接看有没有任何的 peek 不符合预期。
这里我们正好可以用之前的用 Pandas 画图的课程 学习到的 .plot()
功能。
如果你还是觉得太乱,也可以尝试一条条画出来看。
在上面多尝试几个 column (sepal length
, sepal width
, petal length
, petal width
)的名字,仔细观看不同 column 的数据图。 很明显像 "sepal length"
这个数据特征,它有一个出乎意料的负值,这个肯定有问题,说不定是记录员手抖了,记错了,我们待会得改。
好,我根据图像,发现有一个是负值,有两个大于等于 20。现在我就对这些数做处理。处理方案还是和上面的一样:
- 丢弃掉这一行有问题的
- 给问题数值换一个你觉得合理的数
同样,我觉得还是第一种方式比较好。
先看看 sepal length
特征的问题
发现它有值小于 0,那么我们就用下面这个 .drop()
功能,来移除有问题的 row。
你自己在来处理一下其他的数据吧,看看筛选条件怎么选择。
最后还可以看一下这份数据的分布,看看有没有问题。
切分训练和测试数据¶
再来就是和机器学习相关的主题了。通常我们知道机器学习会分训练和测试数据集。而一般我们收集数据的时候都是一个集合收集起来的,比如说这一份 iris 数据就是一体的。 而且如果你仔细看数据,会发现标签都是聚集在一起的,比如前 n 行都是一个 class 类别的数据。
如果直接选一个 row index 来切分训练和预测数据。 很可能切分不均匀。比如测试数据集全部都是一个类(Iris-virginica)。
所以我觉得先要给他随机乱个序,然后在乱序后的 row 中切分个 20% 测试数据,80% 训练数据。这样会均匀分布些。 使用 Pandas 的 .sample()
功能就能对整个数据在 row 上乱序了。
注意看结果 df 的 index,现在已经不是按 1,2,3,4 这样的序号排列的。说明已经乱序了。 接着在做 20%,80% 的切分就更合理了。
切分标签数据¶
切分标签也是机器学习中的一步,这步相对比较简单,我们只需要确定机器学习的特征是哪些,标签是哪些,那么就能按照规定的字段来选择。 比如说在 Iris 数据集中,比较明显 class
就是我们要做分类的类别标签。我们把它单拎出来。
因为训练数据和测试数据都需要做标签的切分,我们可以写一个函数来做统一处理。
仔细的你可能注意到,我在上面挑选数据划分的时候用过 .loc[:, "xxx"]
和 df[["xxx"]]
这两种形式,他们都是可以选出 column 的方法。 殊途同归。
好了,对于测试数据,我们也能复用刚刚定义的 get_xy()
功能了。
有的机器学习框架、模型可以直接使用 Pandas 数据类型,有的不一定可以,但是基本上都可以支持 Numpy array。 所以我们还可以进一步将 Pandas 的 DataFrame 转成 Numpy array。
这么做有个好处,就是 Numpy array 比 Pandas 的数据结构更简单,同时运行计算时也更快。 这点我在这个教学中也详细讲解过。
总结¶
到此,我们已经初步体验了如何用 Pandas 来做数据预处理的过程,我们还绑定了机器学习的要求,见识了 Pandas 怎么做机器学习的前置工作。 经历这系列的教学之后,希望你可以更顺利的踏上机器学习之旅。了解更多学习内容,请看我绘制的学习路径。