大多机器学习算法不能处理缺失的特征,因此先创建一些函数来处理特征缺失的问题。当在一些.csv文件中缺少某些值的时候,一般有三种方法解决:
1 去掉对应的整个属性
2 去掉缺失值所在的数据
3 将缺失值进行赋值
在pandas中,用 DataFrame 的 dropna() ,drop() ,和 fillna() 方法,可以方便地实现:
#去掉缺失值所在数据
data.dropna(subset=["years","salary","..."])
#去掉整个属性
data.drop("one",axis=1)
#替换缺失值
median = data["years"].median()
housing["year"].fillna(median)
Scikit-Learn 提供了一个方便的类来处理缺失值: Imputer 。
下面是其使用方法:首先,需要创建一个 Imputer 实例,指定用某属性的中位数来替换该属性所有的缺失值:
from sklearn.preprocessing import Imputer
imputer = Imputer(strategy="median")
#其中的strategy是选择替换缺失值的方式,midian表示用中位数替换
#然后就可以将整个数据集放入imputer中
imputer.fit(data)
imputer 计算出了每个属性的中位数,并将结果保存在了实例变量 statistics_ 中,可以通过imputer.statistics_查看
imputer.statistics_
array([ -118.51 , 34.26 , 29. , 2119. , 433. , 1164. , 408. , 3.5414])
>>> data.median().values
array([ -118.51 , 34.26 , 29. , 2119. , 433. , 1164. , 408. , 3.5414])
通过fit后的imputer()对数据集进行转换,将缺失值替换为中位数
X = imputer.transform(data)
结果是一个包含转换后特征的普通的 Numpy 数组。如果你想将其放回到Pandas DataFrame 中,也很简单
data_= pd.DataFrame(X, columns=data.columns)
可能会比较纠结的就是Scikit-Learn 设计方面,为什么又要 fit() 又要transfrom()
Scikit-Learn 设计的 API 设计的非常好。它的主要设计原则是:
一致性:所有对象的接口一致且简单:
估计器(estimator):任何可以基于数据集对一些参数进行估计的对象都被称为估计器(比如, imputer 就是个估计器)。估计本身是通过 fit() 方法,只需要一个数据集作为参数(对于监督学习算法,需要两个数据集;第二个数据集包含标签)。任何其它用来指导估计过程的参数都被当做超参数(比如 imputer 的 strategy ),并且超参数要被设置成实例变量(通常通过构造器参数设置)。
转换器(transformer)。一些估计器(比如 imputer )也可以转换数据集,这些估计器被称为转换器。API也是相当简单:转换是通过 transform() 方法,被转换的数据集作为参数。返回的是经过转换的数据集。转换过程依赖学习到的参数,比如 imputer 的例子。所有的转换都有一个便捷的方法 fit_transform() ,等同于调用 fit() 再 transform() (但有
时 fit_transform() 经过优化,运行的更快)。
预测器(predictor)。最后,一些估计器可以根据给出的数据集做预测,这些估计器称为预测器。例如,上一章的 LinearRegression 模型就是一个预测器:它根据一个国家的人均 GDP 预测生活满意度。预测器有一个 predict() 方法,可以用新实例的数据集做出相应的预测。预测器还有一个 score() 方法,可以根据测试集(和相应的标签,如果是监督学习算法的话)对预测进行衡器。可检验。所有估计器的超参数都可以通过实例的public变量直接访问(比如, imputer.strategy ),并且所有估计器学习到的参数也可以通过在实例变量名后加下划线来访问(比如, imputer.statistics_ )。类不可扩散。数据集被表示成 NumPy 数组或 SciPy 稀疏矩阵,而不是自制的类。超参数只是普通的 Python 字符串或数字。可组合。尽可能使用现存的模块。例如,用任意的转换器序列加上一个估计器,就可以做成一个流水线,后面会看到例子。合理的默认值。Scikit-Learn 给大多数参数提供了合理的默认值,很容易就能创建一个系统。