目录
一、数据挖掘流程
1. 获取数据
2. 数据预处理
3. 特征工程
4. 建模,测试模型并预测出结果
5. 验证模型效果
二、sklearn中的相关包
1.sklearn.preprocessing
2.sklearn.Impute
3.sklearn.feature_selection
4.sklearn.decomposition
三、数据预处理
1. 数据无量纲化
(1)数据归一化
(2)数据标准化
2. 缺失值
3. 处理分类型特征:编码与哑变量
(1)preprocessing.LabelEncoder
(2)preprocessing.OrdinalEncoder
(3)preprocessing.OneHotEncoder
4. 处理连续型特征:二值化与分段
(1)preprocessing.Binarizer
(2)preprocessing.KBinsDiscretizer
四、特征选择
1. Filter过滤法
(1)方差过滤
(2)相关性过滤
① 卡方过滤
② F检验
③ 互信息法
2. Embedded嵌入法
3. Wrapper包装法
4. 总结+补充
一、数据挖掘流程
1. 获取数据
2. 数据预处理
从数据中检测,纠正或删除损坏,不准确或不适用于模型的记录的过程。
目的:让数据适应模型,匹配模型的需求。
3. 特征工程
是将原始数据转换为 更能代表预测模型的潜在问题的 特征的过程,可以 通过 挑选最 相关的特征,提取特征 以及创造特征来实现。其中 创造特征 又经常以 降维算法的 方式实现。
目的:① 降低计算成本,② 提升模型上限
4. 建模,测试模型并预测出结果
5. 验证模型效果
二、sklearn中的相关包
1.sklearn.preprocessing:几乎包含数据预处理的所有内容。
2.sklearn.Impute:填补缺失值专用。
3.sklearn.feature_selection:包含特征选择的各种方法的实践。
4.sklearn.decomposition:包含降维算法。
三、数据预处理
涉及包:preprocessing & Impute
1. 数据无量纲化
在机器学习算法实践中,我们往往有着 将不同规格的 数据转换到 同一规格,或 不同分布的数据转换到 某个特定分布的需求,这种需求统称为将数据 “ 无量纲化 ”。无量纲化可以加快求解速度,也可以帮我们 提升模型精度,避免 某一个取值范围 特别大的 特征对距离 计算造成影响。
数据的无量纲化可以是 线性的,也可以是 非线性的。
线性的 无量纲化包括 中心化处理和缩放处理。(中心化的本质是让所有记录减去一个固定值,即让数据样本数据平移到某个位置。缩放的本质是通过除以一个固定值,将数据固定在某个范围之中,取对数也算是一种缩放处理。)
(1)数据归一化
当数据(x)按照最小值中心化后,再按极差(最大值 - 最小值)缩放,自个单位,并且会被收敛到[0, 1]之间,而这个过程,就叫做数据归一化。
sklearn中通过 preprocessing.MinMaxScaler 实现,其中参数 feature_range 控制我们希望 把数据压缩到的范围,默认是[0,1]。
(2)数据标准化
当数据(x)按均值(????)中心化后,再按标准差(????)缩放,数据就会服从为均值为 0,方差为 1 的正态分布(即标准正态分布),而这个过程,就叫做 数据标准化。
sklearn中通过 preprocessing.StandardScaler 实现。
2. 缺失值
机器学习和数据挖掘中所使用的数据,永远不可能是完美的。很多特征,对于分析和建模来说 意义非凡,但对于实际 收集数据的人 却不是如此,因此数据挖掘之中,常常会 有重要的字段缺失值很多,但又不能舍弃字段的情况。因此,数据预处理 中非常重要的一项就是 处理缺失值。
sklearn中通过 impute.Simplelmputer 实现。
重要参数:
① missing_values
默认空值np.nan。告诉Simplelmputer,数据中的缺失值长什么样。
② strategy
默认均值。填补缺失值的策略。
输入“mean” :使用均值填补(仅对数值型特征可用)。
输入“median” :用中值填补(仅对数值型特征可用)。
输入“most_frequent”: 用众数填补(对数值型和字符型特征都可用)。
输入“constant” :表示请参考参数 “ fill_value" 中的值(对数值型和字符型特征都可用)。
③ fill_value
常用 0。当参数 “startegy” 为 “constant” 的时候可用,可输入 字符串或数字表示 要填充的值。
④ copy
默认为True。将 创建特征矩阵的 副本,反之则 会将缺失值填补 到原本的 特征矩阵中去。
from sklearn.impute import SimpleImputer
imp_mean = SimpleImputer() # 均值填补
imp_median = SimpleImputer(strategy="median") # 中位数填补
imp_0 = SimpleImputer(strategy="constant", fill_value=0) # 0 填补
3. 处理分类型特征:编码与哑变量
(1)preprocessing.LabelEncoder:标签专用,能够将分类转换为分类数值。
(2)preprocessing.OrdinalEncoder:特征专用,能够将分类特征转换为分类数值。
(3)preprocessing.OneHotEncoder:独热编码,创建哑变量。
我们把分类转换成 数字的时候,忽略了 数字中自带的 数学性质,所以给算法 传达了一些 不准确的信息,而这会影响 我们的建模。类别 OrdinalEncoder 可以用来 处理有序变量,但对于名义变量,我们只有使用哑变量的方式来处理,才能够尽量向算法传达最准确的信息。
数据类型以及常用的统计量:
from sklearn.preprocessing import OneHotEncoder
enc = OneHotEncoder(categories='auto').fit(x)
result = enc.transform(x)
4. 处理连续型特征:二值化与分段
(1)preprocessing.Binarizer
根据阈值将数据 二值化(将特征值设置为 0 或 1),用于处理连续型变量。大于阈值的值 映射为 1,而小于或 等于阈值的值映射为 0。默认阈值为 0 时,特征中所有的 正值都映射到 1。
from sklearn.preprocessing import Binarizer
transformer = Binarizer(threshold=30).fit_transform(x)
(2)preprocessing.KBinsDiscretizer
将连续型变量划分为分类变量,能够将连续型变量排序后 按顺序分箱 后编码。
① n_bins
默认 5。每个特征中分箱的个数,即一次会被运用到所有导入的特征。
② encode
默认 “ onehot ”。编码的方式。
“onehot”:做哑变量,之后返回一个稀疏矩阵,每一列是一个特征中的一个类别,含有该类别的样本表示为1,不含的表示为0。
“ordinar”:每个特征的每个箱都被编码为一个 整数,返回 每一列是一个特征,每个特征下含有 不同整数编码的 箱的 矩阵。
“onehot-dense”:做哑变量,之后返回一个密集数组。
③ strategy
默认“quantile”。用来定义箱宽的方式。
“uniform”:表示等宽分箱,即每个特征中的每个箱的最大值之间的差为(特征.max()- 特征.min())/(n_bins)。
“quantile”:表示等位分箱,即每个特征中的 每个箱内的样本数量 都相同。
“kmeans”:表示按聚类分箱,每个箱中的值到 最近的一维 k均值聚类 的簇心 得距离 都相同。
from sklearn.preprocessing import KBinsDiscretizer
est = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='uniform')
est.fit_transform(x)
四、特征选择
涉及包:feature_selection
从所有的特征中,选择出有意义,对模型有帮助的特征,以避免必须将所有特征都导入模型去训练的情况。有四种方法可以用来选择特征:过滤法、嵌入法、包装法和降维算法。
1. Filter过滤法
过滤方法通常用作预处理步骤,特征选择完全 独立于任何机器 学习算法。它是 根据各种统计检验中的分数以及相关性的各项指标来选择特征。
过滤法的主要对象是:需要遍历特征或升维的算法们。
过滤法的主要目的是:在维持算法表现的前提下,帮助算法们降低计算成本。
(1)方差过滤
sklearn 中通过 VarianceThreshold 实现。
重要参数:threshold。表示方差的 阈值,表示舍弃所有方差小于 threshold的特征,不填默认为 0,即 删除所有的记录都相同的 特征。
(2)相关性过滤
我们希望 选出与标签相关且有 意义的特征,因为这样的特征能够为 我们提 供大量信息。如果特征 与标签无关,那只会 白白浪费我们的计算内存,可能还会给模型带来噪音。在sklearn当中,有三种 常用的方法来 评判特征与标签之间 的相关性:卡方、F检验、互信息。
① 卡方过滤
卡方过滤是专门针对离散型标签(即分类问题) 的相关性过滤,卡方检验类feature_selection.chi2 计算每个非负特征 和标签之间的 卡方统计量,并依照卡方统计量由高到低为特征排名。再结合 feature_selection.SelectKBest 这个可以输入 “评分标准” 来选出前 K 个分数最高的 特征的类,我们可以 借此除去最可能独立 于标签,与我们 分类目的无关的特征。
卡方检验的本质是推测 两组数据之间的 差异,其 检验的原假设是 “ 两组数据是相互独立的 ”。卡方检验 返回 卡方值和 P值 两个统计量,其中卡方值很 难界定有效的范围,而 p值,我们一般使用 0.01 或 0.05 作为显著性水平,即 p值判断的 边界。
② F检验
F检验,又称ANOVA,方差 齐性检验,是用来捕捉每个特征与标签之间的线性关系的过滤方法。它即可以做回归也 可以做分类,因此包含 feature_selection.f.classif(F检验分类)和feature_selection.f.regression(F检验回归)两个类。其中 F 检验分类 用于标签是 离散型变量的数据,而 F 检验回归 用于标签是连续型变量 的数据。和卡方检验一样,这两个类需要和类SelectKBest 连用。
需要注意的是,F 检验在数据 服从正态分布时效果会 非常稳定,因此如果使用 F 检验过滤,我们会 先将数据转换 成服从正态分布的方式。
F 检验的 本质是寻找 两组数据之问的 线性关系,其原假设是 “ 数据不存在显著的线性关系 ”。它返回 F 值和 P 值 两个统计量。和 卡方过滤一样,我们希望选取 p 值 小于 0.05或0.01 的特征,这些 特征与标签时显 著线性相关的,而 p 值大于 0.05 或 0.01 的特征 则被我们 认为是 和 标签 没有显著线性 关系的 特征,应该被删除。
③ 互信息法
互信息法是用来捕捉每个特征与标签之间的任意关系(包括线性和非线性关系)的过滤方法。和 F 检验相似,它既可以 做回归 也可以做分类,并且 包含两个类feature_selection.mutual_info_classif(互信息分类)和feature_selection.mutual_info_regression(互信息回归)。这两个类的用法和參数都和 F 检验一模一样,不过互信息法比 F 检验 更加强大,F 检验只能 够找出 线性关系,而 互信息法可以找出任意关系。
互信息法不返回 P 值 或 F 值 类似的统计量,它返回 “ 每个特征与目标之间的互信息量的估计 ”,这个估计量在[0, 1]之间取值,为 0 则表示 两个变量独立,为 1 则表示 两个变量完全相关。
2. Embedded嵌入法
嵌入法是一种 让算法自己决定使用哪些特征的方法,即特征选择和算法训练同时进行。
在使用嵌入法时,我们 先 使用某些机器学习的算法和模型 进行训练,得到各个特征的权值系数,根据权值系数 从大到小选择特征。这些权值系数 往往代表了特征对于模型的 某种贡献或某种重要性,我们 可以列出各个特征 对树的建立的贡献,我们就 可以基于这种贡献的评估,找 出对模型建立最有用的特征。
相比于过滤法,嵌入法 的结果会 更加精确 到模型的 效用本身,对于 提高模型效力有更好的 效果。并且,由于 考虑特征对模型 的贡献,因此 无关的特征(需要 相关性过滤 的特征)和无区分度的特征(需要方差过滤的特征)都会因为缺乏 对模型的贡献而 被删除掉,可谓是 过滤法的 进化版。
sklearn 中通过 SelectFromModel 实现。
这是一个元变换器,可以与任何在拟合后具有coef_,feature_importances_属性或参数中可选惩罚项的评估器一起使用。
对于有 feature_importances_ 的模型来说,若重要性 低于提供的 阈值参数,则认为 这些特征 不重要并 被移除。feature_importances_ 的取值范围是 [0, 1],如果设置阈值 很小,比如 0.001,就 可以删除那些对 标签预测完全 没贡献的特征。如果 设置得很接近 1,可能只 有一两个特征能够被留下。
class sklearn.feature_selection.SelectFromModel(estimator, threshold=None, prefit=False, norm_order=1, max_features=None)
3. Wrapper包装法
包装法也是一个 特征选择和算法训练同时进行的方法,与嵌入法十分相似,它也是依赖于算法自身的选择,但不同的是,我们往往 使用一个 目标函数作为黑盒来帮助我们 选取特征,而不是自己输入 某个评估指标或统计量的 阈值。
包装法在初始特征集上 训练评估器,并且通过 coef_ 属性或 通过 feature_importances_ 属性获得每个特征的 重要性。然后,从当前的一组特征中 修剪最 不重要的特征。在 修剪的 集合上 递归地 重复该过程,直到 最终到达所需数量的 要选择的特征。
区别于过滤法和嵌入法的一次训练解决 所有问题,包装法 要使用特征 子集进行 多次训练,因此它所需要的计算成本是最高的。
注:在这个图中的 "算法” ,指的不 是我们最终用来 导入数据的分类 或 回归算法,而是专业的数据挖掘算法,即 我们的 目标函数。这些数据挖掘算法的 核心功能 就是选取 最佳特征子集。
最典型的目标函数是递归特征消除法 (Recursive feature elimination,简写为RFE),即sklearn中的 feature selection.RFE
class sklearn.feature_selection.RFE(estimator, n_features_to_select=None, step=1, verbose=0)
① estimator:需要填写的实例化后的评估器。
② n_features_to_select:想要选择的特征个数。
③ step:表示每次迭代中希望移除的特征个数。
RFE类的两个很重要的属性:
① .support_:返回所有的特征是否被选中的布尔矩阵。
② .ranking_:返回特征的按数次迭代中综合重要性的。
4. 总结+补充
① 大多数机器学习算法中,会选择 StandardScaler 来进行 特征缩放,因为 MinMaxScaler 对异常值 非常敏感。MinMaxScaler 在不涉及距离 度量、梯度、协方差计算以及数据 需要被时使用广泛。
② 在嵌入法下,我们 很容易就能够实现 特征选择的目标:减少计算量,提升模型表现。因此,比起要思考 很多统计量的 过滤法来说,嵌入法 可能是更有效的一种方法。然而,在 算法本身很复杂的时候,过滤法的 计算远远比嵌入法要快,所以大型数据中,我们还是会优先考虑过滤法。
③ 经验来说,过滤法更快速,但更粗糙。包装法和嵌入法 更精确,比较适合具体到算法去调整,但计算量比较大,运行时间长。当数据量很大的时候,优先使用方差过滤和互信息法调整,再上其他特征选择方法。使用逻辑回归时,优先使用嵌入法。使用支持向量机时,优先使用包装法。迷茫的时候,从过滤法走起,看具体数据具体分析。
④ 特征选择只是 特征工程中的第一步。真正的高手,往往使用特征创造或特征提取来寻找高级特征。