声明:版权所有,转载请联系作者并注明出处 http://blog.csdn.net/u013719780?viewmode=contents
博主简介:风雪夜归子(英文名: Allen),机器学习算法攻城狮,喜爱钻研Machine Learning的黑科技,对Deep Learning和Artificial Intelligence充满兴趣,经常关注kaggle数据挖掘竞赛平台,对数据、Machine Learning和Artificial Intelligence有兴趣的各位童鞋可以一起探讨哦,个人CSDN博客: http://blog.csdn.net/u013719780?viewmode=contents
处理缺失值
实践中数值计算不可或缺,好在有很多方法可用,这个主题将介绍其中一些。不过,这些方法未必能解决你的问题。
scikit-learn有一些常见的计算方法,它可以对现有数据进行变换填补NA
值。但是,如果数据集中的缺失值是有意而为之的——例如,服务器响应时间超过100ms——那么更合适的方法是用其他包解决,像处理贝叶斯问题的PyMC,处理风险模型的lifelines,或者自己设计一套方法。
Getting ready
处理缺失值的第一步是创建缺失值。Numpy可以很方便的实现:
In [2]:from sklearn import datasets
import numpy as np
iris = datasets.load_iris()
iris_X = iris.data
masking_array = np.random.binomial(1, .25, iris_X.shape).astype(bool)
iris_X[masking_array] = np.nan
让我们看看这几行代码,Numpy和平时用法不太一样,这里是在数组中用了一个数组作为索引。为了创建了随机的缺失值,先创建一个随机布尔值数组,其形状和iris_X
数据集的维度相同。然后,根据布尔值数组分配缺失值。因为每次运行都是随机数据,所以masking_array
每次都会不同。
masking_array[:5]Out[3]: In [4]:
iris_X[:5]Out[4]:
How to do it...
本书贯穿始终的一条原则(由于scikit-learn的存在)就是那些拟合与转换数据集的类都是可用的,可以在其他数据集中继续使用。具体演示如下所示:
In [5]:from sklearn import preprocessingOut[5]:
impute = preprocessing.Imputer()
iris_X_prime = impute.fit_transform(iris_X)
iris_X_prime[:5]
注意[3,0]
位置的不同:
iris_X_prime[3,0]Out[6]: In [8]:
iris_X[3,0]Out[8]:
How it works...
上面的计算可以通过不同的方法实现。默认是均值mean
,一共是三种:
- 均值
mean
(默认方法) - 中位数
median
- 众数
most_frequent
scikit-learn会用指定的方法计算数据集中的每个缺失值,然后把它们填充好。
例如,用median
方法重新计算iris_X
,重新初始化impute
即可:
impute = preprocessing.Imputer(strategy='median')Out[9]:
iris_X_prime = impute.fit_transform(iris_X)
iris_X_prime[:5]
如果数据有缺失值,后面计算过程中可能会出问题。例如,在How to do it...一节里面,np.nan
作为默认缺失值,但是缺失值有很多表现形式。有时用-1
表示。为了处理这些缺失值,可以在方法中指定那些值是缺失值。方法默认缺失值表现形式是Nan
,就是np.nan
的值。
假设我们将iris_X
的缺失值都用-1
表示。看着很奇怪,但是iris
数据集的度量值不可能是负数,因此用-1
表示缺失值完全合理:
iris_X[np.isnan(iris_X)] = -1Out[10]:
iris_X[:5]
填充这些缺失值也很简单:
In [11]:impute = preprocessing.Imputer(missing_values=-1)Out[11]:
iris_X_prime = impute.fit_transform(iris_X)
iris_X_prime[:5]
There's more...
pandas库也可以处理缺失值,而且更加灵活,但是重用性较弱:
In [12]:import pandas as pdOut[12]:
iris_X[masking_array] = np.nan
iris_df = pd.DataFrame(iris_X, columns=iris.feature_names)
iris_df.fillna(iris_df.mean())['sepal length (cm)'].head(5)
其灵活性在于,fillna
可以填充任意统计参数值:
iris_df.fillna(iris_df.max())['sepal length (cm)'].head(5)Out[13]: