基于Scikit-Learn的数据预处理实战

作者: 好重 | 来源:发表于2019-04-29 22:18 被阅读3次

机器学习项目中,通俗地讲,一般70%以上的时间会被用于数据的处理,20%的时间用于训练,10%的时间用于评估结果,可见数据处理在机器学习中的重要性。有句话说的很好,数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。因此这里对数据处理的一些工具和方法做一下记录。本文使用的数据集是UCI的Breast Cancer Wisconsin (Diagnostic) ,该数据集用于二分类,使用sklearn.datasets中的load_breast_cancer函数可以方便地加载它。本文基于这个数据集,介绍一些常用的数据预处理方法。

数据的加载

该数据集有569个样本,30个特征,scikit-learn提供方便的函数来加载该数据集,代码如下:

from sklearn.datasets import load_breast_cancer
import pandas as pd
import numpy as np
bundle = load_breast_cancer()
X = bundle.data
y = bundle.target
X[11:21, 1] = np.NAN  #制造缺失值

c = ['mean_radius', 'mean_texture', 'mean_perimeter', 'mean_area', 
           'mean_smoothness', 'mean_compactness', 'mean_concavity', 
           'mean_concave', 'mean_symmetry', 'mean_fractal', 'standard_radius',
           'standard_texture', 'standard_perimeter', 'standard_area', 
           'standard_smoothness', 'standard_compactness', 'standard_concavity', 
           'standard_concave', 'standard_symmetry', 'standard_fractal', 'worst_radius',
           'worst_texture', 'worst_perimeter', 'worst_area', 'worst_smoothness', 
           'worst_compactness', 'worst_concavity', 'worst_concave', 'worst_symmetry', 'worst_fractal']
dataset = pd.DataFrame(X, columns = c)
dataset_part = dataset[c[0:10]]

由于特征较多,方便展示结果,这里只选取前10个特征。为了模拟具有缺失值的数据集,这里我手动把第11到20个样本的'mean_texture'特征值删去了。

数据的初步探索

快速查看

  1. 查看前五行
dataset_part.head() 

结果如下:

  1. 查看某个特征的值的个数,由于篇幅限制,这里只展示前10行:
dataset_part['mean_radius'].value_counts().iloc[0 : 10]

结果如下:

  1. 查看该数据集的简单描述,比如总行数、每个属性的类型和非控制的数量等
dataset_part.info()

结果如下:

  1. 显示属性的摘要,包括总数、中位数、均值等
dataset_part.describe()

结果如下:

  1. 绘制每个特征的直方图,横轴是特征值的范围,纵轴是实例的数量
%matplotlib inline
import matplotlib.pyplot as plt
dataset_part.hist(bins=50, figsize=(20,15))
plt.show()

结果如下所示:


特征之间的相关性

方法一

如果数据集不大,可以直接使用DataFrame的corr()方法,它会计算特征两两之间的标准相关系数(皮尔逊相关系数)。相关系数的范围从-1到1,越接近1,表示有越强的正相关性,接近-1,则表示有强烈的负相关性。对dataset_part使用corr()函数,得到下表:

可以看到各个特征与其它特征的相关度,比如mean_radius就与mean_perimeter具有很强烈的正相关性,而与mean_smoothness则相关度不高。

方法二

另一种方法是使用Pandas的scatter_matrix函数,它会绘制每个数值属性相对于其他数值属性的相关性。比如以下代码:

%matplotlib inline
from pandas.plotting import scatter_matrix
attr = ['mean_radius', "mean_texture", "mean_perimeter", "mean_area"]
scatter_matrix(dataset_part[attr], figsize=(20,12))
结果如下所示:

结果一目了然,可以看到mean_radius与mean_perimeter和mean_area有较强的正相关性,而与mean_texture则相关性很低。同一个特征则展示该特征的分布直方图,否则会是一条毫无价值的主对角线。

数据的清理

对于缺失值的处理,有三种选择:

  1. 放弃这些样本。Scikit-Learn提供以下方法:
df = dataset_part.dropna(subset=['mean_texture'])
print(len(dataset_part), len(df))
  1. 放弃这个特征。Scikit-Learn提供以下方法:
df = dataset_part.drop('mean_texture', axis=1)
df
  1. 将缺失的值设置为某个值(0、平均值或者中位数等都可以)。Scikit-Learn提供以下方法:
median = dataset_part['mean_texture'].median()
dataset_part['mean_texture'].fillna(median)[0:21]

这里scikit-learn还提供了另外一种方便的方法来处理缺失值,那就是Imputer。Imputer调用fit()方法之后,会将均值存放在statistics_成员变量中,调用transform()方法会产生一个np.ndarray对象,使用方法如下:

from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy='median')
imputer.fit(dataset_part)
imputer.statistics_
X = imputer.transform(dataset_part)
pd.DataFrame(X).iloc[11:21]

测试数据集的划分

一般我们可以将数据集划分为20%的测试数据集和80%的训练数据集,scikit-learn提供了方便的划分函数,使用如下:

from sklearn.model_selection import train_test_split
train_set, test_set = train_test_split(dataset_part, test_size=0.2, random_state=42)
print(len(train_set), len(test_set))

也提供了根据某一特征进行分层抽样的数据分割方法,StratifiedShuffleSplit类:

dataset_part["radius_cat"] = np.ceil(dataset_part['mean_radius'] / 3)
from sklearn.model_selection import StratifiedShuffleSplit
sss = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)
for train_index, test_index in sss.split(dataset_part, dataset_part['radius_cat']):
   strat_train_set = dataset_part.loc[train_index]
   strat_test_set = dataset_part.loc[test_index]
print(len(strat_train_set), len(strat_test_set))

总结

数据处理在机器学习项目中是很大的工程,且涉及很多的内容和知识,本文介绍的方法只是冰山一角,后续有更多内容会继续加进来。

相关文章

网友评论

    本文标题:基于Scikit-Learn的数据预处理实战

    本文链接:https://www.haomeiwen.com/subject/asfpnqtx.html