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

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

1 数据的加载

该数据集有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'特征值删去了。

2 数据的初步探索

2.1 快速查看

1. 查看前五行

dataset_part.head() 

结果如下:

2. 查看某个特征的值的个数,由于篇幅限制,这里只展示前10行:

dataset_part['mean_radius'].value_counts().iloc[0 : 10]

结果如下:

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

dataset_part.info()

结果如下:

4. 显示属性的摘要,包括总数、中位数、均值等

dataset_part.describe()

结果如下:

5. 绘制每个特征的直方图,横轴是特征值的范围,纵轴是实例的数量

%matplotlib inline
import matplotlib.pyplot as plt
dataset_part.hist(bins=50, figsize=(20,15))
plt.show()

结果如下所示:


2.2 特征之间的相关性

方法一

如果数据集不大,可以直接使用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则相关性很低。同一个特征则展示该特征的分布直方图,否则会是一条毫无价值的主对角线。

3 数据的清理

对于缺失值的处理,有三种选择:
1. 放弃这些样本。Scikit-Learn提供以下方法:

df = dataset_part.dropna(subset=['mean_texture'])
print(len(dataset_part), len(df))

输出:(569, 559)
2. 放弃这个特征。Scikit-Learn提供以下方法:

df = dataset_part.drop('mean_texture', axis=1)
df

输出如下,可以看到,mean_texture列已经不见了:

3. 将缺失的值设置为某个值(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]

4 测试数据集的划分

一般我们可以将数据集划分为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))

输出:(455, 114)

也提供了根据某一特征进行分层抽样的数据分割方法。什么是分层抽样呢?比如我们想预测大盘用户对某类保险产品的购买意愿,假设用户的收入水平对这类保险的意愿有很大的影响,用户的收入水平被划分成A、B、C、D四个层次,已知大盘用户收入水平的占比依次是20%、40%、30%、10%,研究方法是从大盘中抽出10W个用户进行训练,我们当然希望这10W个用户的收入水平分布和大盘用户的一致,这就是分层抽样。同理,我们对数据集进行划分,也希望训练集和测试集对某一特征的分布是一致的,这时就可以使用Scikit-Learn提供的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))

输出:(455, 114)

StratifiedShuffleSplit允许对数据集进行多次划分,产生多组train/test对,以进行交叉验证。在这个例子中,我们只进行一次分割。

5 总结

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352