数据预处理与特征工程初步

Intro

使用鸢尾花数据集:

from sklearn.datasets import load_iris

data = load_iris()

features = data.data
labels = data.target

其中features是特征矩阵,labels是真实分类。

1. 预处理(preprocessing)

1.1 预处理的目的

数据预处理的目的在于:使得特征数据在处理后,能让学习模型得到更好的效果。预处理通常会解决原始数据存在的如下问题:

  • 量纲不同:比如可能存在两个特征,都是“长度”,但其中一个以千米为单位,一个以毫米为单位。直接让模型去学习这两个特征,明显是不科学的。
  • 信息冗余:经常会有好几个特征表达同一个含义;或者某个特征过于具体或连续,但其实我们只需要一个区段标记或者“是”与“否”的标记。
  • 定性(Categorical)的特征:比如国籍、XX状态等,需要处理成数值编码才可以被学习。
  • 缺失值。

下面具体地介绍几种预处理的手段:

1.2 无量纲化

1.2.1 标准化(standardization)

常用的z-score标准化计算公式:

x' = \frac{x - \bar{X}}{S}

在sklearn库中,实现标准化的类是:StandardScaler。

from sklearn.preprocessing import StandardScaler

StandardScaler().fit_transform(features)

可以对比下转换前和转换后,第一行数据的形态:

# 转换前
[5.1, 3.5, 1.4, 0.2]

# 转换后
[-9.00681170e-01,  1.03205722e+00, -1.34127240e+00, -1.31297673e+00]

1.2.2 最大-最小值缩放(min-max scaler)

其实区间缩放的方式不止最大-最小值这一种,但这是最常用的一种,也是归一化方式的一种。公式如下:

x' = \frac{x - Min}{Max - Min}

sklearn中实现的类为MinMaxScaler:

from sklearn.preprocessing import MinMaxScaler

MinMaxScaler().fit_transform(features)

转换后特征变成 [0, 1] 区间内的数值:

# 转换后
[0.22222222, 0.625, 0.06779661, 0.04166667]

1.2.2 L2归一化(L2 Normalization)

其实上面的最大-最小值缩放也是归一化的一种,但通常说归一化,指的还是L2的归一化方式。公式如下:

x' = \frac{x}{\sqrt{\sum{x[j]^2}}}

特征转换后得到的也是 [0, 1] 区间内的数值。

代码如下:

from sklearn.preprocessing import Normalizer

Normalizer().fit_transform(features)
# 转换后
[0.80377277, 0.55160877, 0.22064351, 0.0315205 ]

标准化与归一化的区别在于:标准化是对一个特征的所有值求z-score,它并不会改变整个特征的分布。而归一化是对一个数据点做处理,得到的是一个更好的新的分布。

1.3 哑编码/独热编码

定性(categorical)的特征无法直接被学习器学习,必需先转换成数值型的编码。哑编码是最常用的方式,在sklearn中有OneHotEncoder类:

from sklearn.preprocessing import OneHotEncoder

OneHotEncoder().fit_transform(labels.reshape(-1, 1))

1.4 基于多项式的变换

数据变换,总体来说就是根据一定的规律造指标。这里介绍的是多项式,其实还可以基于指数函数或者log函数。多项式变换的核心在于“度”(degree)的选择,选择正确的度对于运算复杂度和最终预测结果都有很大的影响。

sklearn用于实现变换的类为:PolynomialFeatures。

from sklearn.preprocessing import PolynomialFeatures

# 其实可定义参数degree,默认值为2
PolynomialFeatures().fit_transform(features)

2. 特征选择

对特征数据的预处理只是第一步,在实际输入到学习器之前,还需要对特征的必要性进行排查。不必要的特征需要删除。

特征的选择通常从两方面来考虑:

  1. 特征方差取值:方差大的特征更具有选择性。
  2. 特征相关性:与label相关性越强的特征越好。

下面介绍三种常用的特征选择操作。

2.1 过滤(Filter)

2.1.1 方差过滤

单独计算每个特征的方差,设定阈值并只保留大于阈值的特征。在sklearn中是使用feature_selection库的VarianceThreshold类来实现。

from sklearn.feature_selection import VarianceThreshold

# threshold就是阈值
VarianceThreshold(threshold=3).fit_transform(features)

2.1.2 相关系数过滤

计算各个特征对目标值的相关系数以及相关系数的P值。用feature_selection库的SelectKBest类结合相关系数来选择特征的代码如下:

from sklearn.feature_selection import SelectKBest
from scipy.stats import pearsonr

SelectKBest(lambda X, Y: array(map(lambda x: pearsonr(x, Y), X.T)).T, k=2).fit_transform(features, labels)

2.1.3 卡方检验过滤

经典的卡方检验是检验定性自变量对定性因变量的相关性。假设自变量有N种取值,因变量有M种取值,考虑自变量等于i且因变量等于j的样本频数的观察值与期望的差距。

用feature_selection库的SelectKBest类结合卡方检验来选择特征的代码如下:

from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2

# 选择K个最好的特征,返回选择特征后的数据
SelectKBest(chi2, k=2).fit_transform(features, labels)

2.2 包裹(Wrapper)

2.2.1 递归特征消除

递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。使用feature_selection库的RFE类来选择特征的代码如下:

from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression

#递归特征消除法,返回特征选择后的数据
#参数estimator为基模型
#参数n_features_to_select为选择的特征个数
RFE(estimator=LogisticRegression(), n_features_to_select=2).fit_transform(features, labels)

3. 特征降维

当特征选择完成后,可以直接训练模型了,但是可能由于特征矩阵过大,导致计算量大,训练时间长的问题,因此降低特征矩阵维度也是必不可少的。常见的降维方法除了以上提到的基于L1惩罚项的模型以外,另外还有主成分分析法(PCA)和线性判别分析(LDA),线性判别分析本身也是一个分类模型。PCA和LDA有很多的相似点,其本质是要将原始的样本映射到维度更低的样本空间中,但是PCA和LDA的映射目标不一样:PCA是为了让映射后的样本具有最大的发散性;而LDA是为了让映射后的样本有最好的分类性能。所以说PCA是一种无监督的降维方法,而LDA是一种有监督的降维方法。

3.1 主成分分析(PCA)

from sklearn.decomposition import PCA

# 主成分分析法,返回降维后的数据
# 参数n_components为主成分数目
PCA(n_components=2).fit_transform(features)

3.2 线性判别(LDA)

from sklearn.lda import LDA

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

推荐阅读更多精彩内容

  • 0 关于本文 ​ 主要内容和结构框架由@jasonfreak--使用sklearn做单机特征工程提供,其中夹杂...
    mrlevo520阅读 21,357评论 4 61
  • 作者:jasonfreak,原文地址:使用sklearn做单机特征工程 目录 特征工程是什么? 数据预处理2.1 ...
    JSong1122阅读 1,111评论 0 8
  • 文章主要参考于大神城东(部分认为有问题的地方进行了修改) 1. 特征工程是什么? 数据和特征决定了机器学习的上限,...
    jockerMe阅读 1,713评论 0 11
  • 本周(2017-10-16~20)为求索班驻校督学周,但因工作及时间关系,很遗憾今天与明天无人应征,此刻,我特意向...
    天宇无缘阅读 884评论 2 4
  • 第一次听说有拆书会这种玩法,第一次自己读完一本书,然后去听拆书会。昨晚听完筝小钱老师的拆书会,挺受教的,跟我想象中...
    小小一美分阅读 1,602评论 0 4