点击标题下「小小挖掘机」可快速关注

连续特征离散化可以使模型更加稳健,比如当我们预测用户是否点击某个商品时,一个点击该商品所属类别下次数为100次和一个点击次数为105次的用户可能具有相似的点击行为,有时候特征精度过高也可能是噪声,这也是为什么在LightGBM中,模型采用直方图算法来防止过拟合。连续特征经常是用户或者事物对应一些行为的统计值,常见的处理方法包括:

  • 归一化
  • 标准化
  • 离散化
  • 缺失值处理

这里要特别注意一下归一化和标准化的区别,在平常的使用中,很多同学都容易把这两者的概念混淆,因为两者的英文翻译是一样的(Feature scaling,特征缩放,参考维基百科 Feature scaling - Wikipedia)。但是根据其本意和实际用途(或者称之为公式)来理解是不一样的。

归一化

归一化一般是将数据映射到指定的范围,用于去除不同维度数据的量纲以及量纲单位,最常见的归一化方法有:

1、Min-Max 归一化

Min-Max 归一化是指对原始数据进行线性变换,将值映射到[0,1]之间。Min-Max 归一化的计算公式为:式中,为原始数据中的一个数据,表示原始数据中的最小值,表示原始数据中的最大 值, 为 Min-Max 归一化后的数据。

2、均值归一化

均值归一化是指通过原始数据中的均值、最大值和最小值来进行数据的标准化。均值归 一化法计算公式为:式中,为原始数据中的一个数据,表示原始数据的均值,表示原始数据中的最大值,表示原始数据中的最小值, 为均值归一化后的数据。

3、小数定标归一化

小数定标归一化是指通过移动小数点的位置来进行数据的归一化。小数点移动的位数取决于原始数据中的最大绝对值。小数定标归一化的计算公式为:式中,为原始数据中的一个数据,经过小数定标(Decimal scaling)归一化后的数据,表示满足条件的最小整数。例如,一组数据为[-309, -10, -43,87,344,970],其中绝对值最大的是 970。使用小数定标归一化,用 1000(即 j=3)除以每个值。这样,-309 被归一化为-0.309,970 被归一化为 0.97。

4、向量归一化

向量归一化是指通过用原始数据中的每个值除以所有数据之和来进行数据的归一化。向量归一化的计算公式为:式中,为原始数据中的一个值,分母表示的是原始数据的所有数据之和, 为归一化后的数据。

5、指数归一化

指数转换是指通过对原始数据的值进行相应的指数函数变换来进行数据的标准化。进行指数转换常见的函数方法有函数、函数和 函数。

a. 函数

函数对应的标准化计算公式为:式中,为原始数据中的一个数据,表示原始数据中的最大值, 为指数转换后的数据。

b. 函数

函数对应的标准化计算公式为:式中,为原始数据中的一个数据,为自然常数,分母表示的是原始数据中每个数据被 求指数后的和,分子表示的是原始数据中一个数据被 求指数, 为指数转换后的数据。

c. 函数

Sigmoid 函数对应的标准化计算公式为:式中,为原始数据中的一个常数,为自然常数, 为指数转换后的数据。

标准化

标准化:对数据的分布的进行转换,使其符合某种分布(比如正态分布)的一种非线性特征变换。需要注意的是标准化不改变数据分布的类型,比如原始数据服从正态分布,标准化处理之后依旧服从正态分布,只是数据的均值和方差发生了变化。可以结合PCA算法进行理解,如果分布改变了,那主成分分析就得不到原始数据的分布信息了。使用最广泛的标准化方法为:Z-Score标准化。Z-Score(也叫 Standard Score,标准分数)标准化是指基于原始数据的均值(mean)和 标准差(standard deviation)来进行数据的标准化。Z-Score 标准化的计算公式为:式中,为原始数据中的一个数据,表示原始数据的均值,表示原始数据的标准差,为 Z-Score 标准化后的数据。特征经过归一化或者标准化处理之后对于模型训练的好处有:

  • 提升模型精度。

    因为使不同量纲的特征处于同一数值量级,减少方差大的特征的影响。在KNN中,我们需要计算待分类点与所有实例点的距离。假设每个实例点(instance)由n个features构成。如果我们选用的距离度量为欧式距离,如果数据预先没有经过归一化,那么那些绝对值大的features在欧式距离计算的时候起了决定性作用。

    从经验上说,归一化是让不同维度之间的特征在数值上有一定比较性,可以大大提高分类器的准确性。

  • 提升收敛速度。

    对于线性model来说,数据归一化后,最优解的寻优过程明显会变得平缓,更容易正确的收敛到最优解。

    提升模型收敛速度

在对特征进行具体的处理时,需要结合具体的业务场景和算法模型评估特征是否需要进行归一化或者标准化。归一化改变数据分布,标准化不会改变数据分布,如下例:根据人的身高和体重预测人的健康指数,假设有如下原始样本数据是四维的(当然一般不会有这么无聊的数据)

在这里插入图片描述

在这里插入图片描述

从上面两个坐标图可以看出,样本在数据值上的分布差距是不一样的,但是其几何距离是一致的。而标准化就是一种对样本数据在不同维度上进行一个伸缩变化(而不改变数据的几何距离),也就是不改变原始数据的信息(分布)。这样的好处就是在进行特征提取时,忽略掉不同特征之间的一个度量,而保留样本在各个维度上的信息(分布)。

在这里插入图片描述

从采用大单位的身高和体重这两个特征来看,如果采用标准化,不改变样本在这两个维度上的分布,则左图还是会保持二维分布的一个扁平性;而采用归一化则会在不同维度上对数据进行不同的伸缩变化(归一区间,会改变数据的原始距离,分布,信息),使得其呈类圆形。虽然这样样本会失去原始的信息,但这防止了归一化前直接对原始数据进行梯度下降类似的优化算法时最终解被数值大的特征所主导。归一化之后,各个特征对目标函数的影响权重是一致的。这样的好处是在提高迭代求解的精度。当然,数据归一化并不是万能的。在实际应用中,通过梯度下降法求解的模型通常是需要归一化的,包括线性回归、逻辑回归、支持向量机、神经网络等模型。但对于决策树模型则并不适用,以C4.5为例,决策树在进行节点分裂时主要依据数据集D关于特征x的信息增益比,而信息增益比跟特征是否经过归一化是无关的,因为归一化并不会改变样本在特征 上的信息增益。

离散化

数据离散化(也叫数据分组)是指将连续的数据进行分组,使其变为一段段离散化的区间,离散化后的特征根据其所在的组进行One-Hot编码。根据离散化过程中是否考虑类别属性,可以将离散化算法分为有监督算法和无监督算法两 类。由于有监督算法(如基于熵进行数据的离散化)充分利用了类别属性的信息,所以在分类中能获得较高的正确率。常见的数据离散化方法有以下几种(以下介绍的数据分组方法均需要对数据进行排序,且假设待离散化的数据按照升序排列):

  • 二值化分组
  • 等宽分组
  • 等频分组
  • 单变量分组
  • 基于信息熵分组

1、二值化分组

二值化分组比较好理解,即将离散特征根据某个值划分成两个字段。例如,一组变量(1,7,12,12,22,30,34,38,46),可以将分割值设置为22,即小于等于22的为一组,大于22的为一组,划分后为:(1,7,12,12,22),(30,34,38,46)。

2、等宽分组

等宽分组的原理是,根据分组的个数得出固定的宽度,分到每个组中的变量的宽度是相等的。例如,将一组变量(1,7,12,12,22,30,34,38,46)分成三组。

  • 宽度为 15,即用变量中的最大值(46)减去变量中的最小值(1),然后用差除以组数(3)。
  • 每组的范围为:(1,16]、(16,31]、(31,46]
  • 分组后的结果为:(1,7,12,12)、(22,30)、(34,38,46)

(1,16]表示半开半闭区间,即大于 1 且小于或等于 16。另外,采用半开半闭区间时,最 小值不能进行有效分组,这里默认将其归为第一组。

3、等频分组

等频分组也叫分位数分组,即分组后每组的变量个数相同。例如,将一组变量(1,7,12,12,22,30,34,38,46)分成三组。变量的总个数为 9,所以每组的变量为 3 个。分组后的结果为:(1,7,12)、(12,22,30)、 (34,38,46)。

等宽分组和等频分组实现起来比较简单,但都需要人为地指定分组个数。等宽分组的缺点是:对离群值比较敏感,将属性值不均匀地分布到各个区间。有些区间 包含的变量较多,有些区间包含的变量较少。等频分组虽然能避免等宽分组的缺点,但是会将相同的变量值分到不同的组(以满足每 个组内的变量个数相同)。

4、单变量分组

单变量分组也叫秩分组。其原理是:将所有变量按照降序或升序排序,排序名次即为排序结果,即将值相同的变量划分到同一组。例如,将一组变量(1,7,12,12,22,30,34,38,46)分成三组,去重后,变量个数为 8,所以该组变量的分组数目为 8。结果为:(1)、(7)、(12,12)、(22)、(30)、(34)、(38)、(46)。

5、基于信息熵分组

在学习信息熵分组之前,先了解一下信息量和熵的概念。

信息量

香农(Shannon)被称为“信息论之父”,他认为“信息是用来消除随机不确定性的东西”。即,衡量信息量大小就看这个信息消除不确定性的程度。信息量是对事件发生概率的度量,一个事件发生的概率越低,则这个事件包含的信息量越大,这跟我们直观上的认知也是吻合的,越稀奇的新闻包含的信息量越大,因为这种新闻出现的概率低,即信息量的大小和事件发生的概率成反比。香农提出了一个定量衡量信息量的公式:式中,表示 事件发生的概率。信息量度量的是“一个具体事件发生”所带来的信息。

熵是在结果出来之前对可能产生的信息量的期望——考虑该随机变量的所有可能取值,即所有可能发生事件所带来的信息量的期望。熵越大表示结果的不确定性越大,熵为0表示没有任何不确定性。熵的计算公式为:式中,表示 事件发生的概率,为 中所有类别的个数。按照随机变量的所有可能取值划分数据的总熵 是所有事件的熵的加权平均:式中,是第 个事件出现的比例,是第 个可能取值出现的次数,是所有取值出现的总次数。所以,基于信息熵进行数据分组的具体做法是:

  • 1、对属性 的所有取值从小到大排序
  • 2、遍历属性 的每个值 ,将属性 的值分为两个区间 、,使得将其作为分隔点划分数据集后的熵 最小,熵 的计算方式见式上边的两个公式
  • 3、当划分后的熵大于设置的阈值且小于指定的数据分组个数时,递归对 、 执行步骤2中的划分

6、基于用户是否点击和信息熵对商品价格进行离散化

接下来通过一个实例看一下如何基于信息熵对数据进行离散化。基于信息熵的数据离散化算法是有监督学习算法。在使用该方法对数据进行离散化时,需 要数据有对应的标签。假设现在有一份下面这样的数据,其表示的是用户是否点击商品和商品价格之间的关系(当然这是一份假设的数据)。价格标签价格标签价格标签

56 1 453 1 764 0
87 1 10 1 121 1
129 0 9 0 28 0
23 0 88 1 49 1
342 1 222 0 361 1
641 1 97 0 164 0
63 0 2398 1 1210 1
2764 1 592 1
2323 0 561 1

对该份数据进行离散化,其实现的代码如下:

# Author: Thinkgamer# Desc  : 基于信息熵的数据离散化import numpy as npimport mathclass DataSplitByEntropy:def __init__(self, group, threshold):# 最大分组数        self.max_group = group# 停止划分的最小熵        self.min_threshold = threshold# 保存最终结果变量        self.result = dict()# 加载数据def load_data(self):        data = np.array(            [                [56, 1],   [87, 1],  [129, 0],  [23, 0],   [342, 1],                 [641, 1],  [63, 0],  [2764, 1], [2323, 0], [453, 1],                 [10, 1],   [9, 0],   [88, 1],   [222, 0],  [97, 0],                [2398, 1], [592, 1], [561, 1],  [764, 0],  [121, 1],                [28, 0],   [49, 1],  [361, 1],  [164, 0],  [1210, 1]            ]        )return data# 计算按照数据指定数据分组后的香农熵def cal_entropy(self, data):        num_data = len(data)        label_counts = {}for feature in data:# 获得标签            one_label = feature[-1]# 如果标签不在新定义的字典里则创建该标签            label_counts.setdefault(one_label, 0) # 该类标签下含有数据的个数             label_counts[one_label] += 1        entropy = 0.0for key in label_counts:# 同类标签出现的概率            prob = float(label_counts[key]) / num_data# 以2为底求对数            entropy -= prob * math.log(prob, 2)return entropy# 按照调和信息熵最小化原则分割数据集def split(self, data):# inf为正无穷大        min_entropy = np.inf# 记录最终分割索引        index = -1# 按照第一列对数据进行排序        sort_data = data[np.argsort(data[:, 0])]# 初始化最终分割数据后的熵        last_e1, last_e2 = -1, -1# 返回的数据结构,包含数据和对应的熵        S1 = dict()        S2 = dict()for i in range(len(sort_data)):# 分割数据集            split_data_1, split_data_2 = sort_data[: i + 1], sort_data[i + 1 :]             entropy1, entropy2 = ( self.cal_entropy(split_data_1), self.cal_entropy(split_data_2) ) # 计算信息熵            entropy = entropy1 * len(split_data_1) / len(sort_data) +  entropy2 * len( split_data_2) / len(sort_data)# 如果调和平均熵小于最小值if entropy                 min_entropy = entropy                 index = i                last_e1 = entropy1                 last_e2 = entropy2        S1["entropy"] = last_e1        S1["data"] = sort_data[: index + 1]        S2["entropy"] = last_e2        S2["data"] = sort_data[index + 1 :]return S1, S2, entropy# 对数据进行分组def train(self, data):# 需要遍历的 key        need_split_key = [0]# 将整个数据作为一组        self.result.setdefault(0, {})         self.result[0]["entropy"] = np.inf         self.result[0]["data"] = data        group = 1for key in need_split_key:            S1, S2, entropy = self.split(self.result[key]["data"])# 如果满足条件if entropy > self.min_threshold or group                 self.result[key] = S1                newKey = max(self.result.keys()) + 1                 self.result[newKey] = S2                need_split_key.extend([key])                 need_split_key.extend([newKey])                group += 1else: breakif __name__ == "__main__":    dse = DataSplitByEntropy(group=6,threshold=0.3)     data = dse.load_data()    dse.train(data)    print("result is {}".format(dse.result))

输出结果为:

result is {0: {'entropy': 0.8112781244591328, 'data': array([[ 9,  0],       [10,  1],       [23,  0],       [28,  0]])}, 1: {'entropy': 0.0, 'data': array([[342,   1],       [361,   1],       [453,   1],       [561,   1],       [592,   1],       [641,   1]])}, 2: {'entropy': 0.0, 'data': array([[129,   0]])}, 3: {'entropy': 0.9709505944546686, 'data': array([[ 764,    0],       [1210,    1],       [2323,    0],       [2398,    1],       [2764,    1]])}, 4: {'entropy': 0.863120568566631, 'data': array([[ 49,   1],       [ 56,   1],       [ 63,   0],       [ 87,   1],       [ 88,   1],       [ 97,   0],       [121,   1]])}, 5: {'entropy': 0.0, 'data': array([[164,   0],       [222,   0]])}}

分析结果可以看出,熵越大的簇类下数据对应的标签越凌乱,熵为0的簇类下数据对应的标签是一致的,这里可以自行调节group、threshold参数观察结果。

归一化处理公式_特征工程连续特征的常见处理方式(含实例)相关推荐

  1. 特征工程——连续特征与离散特征处理方法

    特征的标准化(归一化) 连续特征   z-score标准化:这是最常见的特征预处理方式,基本所有的线性模型在拟合的时候都会做 z-score标准化.具体的方法是求出样本特征x的均值mean和标准差st ...

  2. 线性稀疏自编码机_特征工程之特征缩放amp;特征编码

    机器学习入门系列(2)--如何构建一个完整的机器学习项目,第五篇! 本篇文章会继续介绍特征工程的内容,这次会介绍特征缩放和特征编码,前者主要是归一化和正则化,用于消除量纲关系的影响,后者包括了序号编码 ...

  3. ML之FE:数据处理—特征工程之特征三化(标准化【四大数据类型(数值型/类别型/字符串型/时间型)】、归一化、向量化)简介、代码实现、案例应用之详细攻略

    ML之FE:数据处理-特征工程之特征三化(标准化[四大数据类型(数值型/类别型/字符串型/时间型)].归一化.向量化)简介.代码实现.案例应用之详细攻略 目录 真正意义的标准化与归一化 1.标准化/Z ...

  4. AI基础:特征工程-数字特征处理

    0.导语 特征工程到底是什么呢?顾名思义,其本质是一项工程活动,目的是最大限度地从原始数据中提取特征以供算法和模型使用. 在此之前,我已经写了以下几篇AI基础的快速入门,本篇文章讲解特征工程基础第二部 ...

  5. 特征工程之特征缩放特征编码

    机器学习入门系列(2)–如何构建一个完整的机器学习项目,第五篇! 该系列的前四篇文章: 机器学习入门系列(2)–如何构建一个完整的机器学习项目(一) 机器学习数据集的获取和测试集的构建方法 特征工程之 ...

  6. 机器学习特征工程之特征缩放+无量纲化:数据标准化(StandardScaler)

    机器学习特征工程之特征缩放+无量纲化:数据标准化(StandardScaler) 在Andrew Ng的机器学习课程里面,讲到使用梯度下降的时候应当进行特征缩放(Feature Scaling).进行 ...

  7. 机器学习特征工程之特征缩放+无量纲化:最小最大缩放(MinMaxScaler)

    机器学习特征工程之特征缩放+无量纲化:最小最大缩放(MinMaxScaler) 在Andrew Ng的机器学习课程里面,讲到使用梯度下降的时候应当进行特征缩放(Feature Scaling).进行缩 ...

  8. 机器学习特征工程之特征缩放+无量纲化:最大绝对值缩放(MaxAbsScaler)

    机器学习特征工程之特征缩放+无量纲化:最大绝对值缩放(MaxAbsScaler) 在Andrew Ng的机器学习课程里面,讲到使用梯度下降的时候应当进行特征缩放(Feature Scaling).进行 ...

  9. ML之FE:利用FE特征工程(单个特征及其与标签关系的可视化)对RentListingInquries(Kaggle竞赛)数据集实现房屋感兴趣程度的多分类预测

    ML之FE:利用FE特征工程(单个特征及其与标签关系的可视化)对RentListingInquries(Kaggle竞赛)数据集实现房屋感兴趣程度的多分类预测 目录 输出结果 设计思路 核心代码 输出 ...

最新文章

  1. python读取excelsheet-python实现读取excel文件中所有sheet操作示例
  2. OpenCV实现图像金字塔
  3. 解决Delphi7的自带的UTF-8编码转换函数BUG
  4. 资本主义的历史仍未终结(作者:袁剑)【转】
  5. 开始使用vue.js
  6. 数学建模资料分享群——2群
  7. 信息系统项目管理师优秀论文:论信息系统范围管理
  8. go语言buffio与继承
  9. Pro*c源程序中使用宿主结构保存查询结果
  10. OpenCV-Python bindings是如何生成的(2)
  11. boa php5.5 移植,BOA+PHP在Tiny6410上的移植
  12. 【报告分享】2022年中国商业十大热点展望.pdf(附下载链接)
  13. RS报表从按月图表追溯到按日报表
  14. NodeJS开源项目
  15. matebook14支持触摸屏吗_matebook 14有触屏吗
  16. 如何在word中的图片上画圈标注_word图片上画圈 如何在word图片中进行画圈标示...
  17. idea切换工作空间_IDEA在一个工作空间中管理多个项目的详细步骤
  18. 为什么说程序员做外包没前途?
  19. linux中编辑jar包的内容
  20. html中的表格和表单设计总结

热门文章

  1. Openresty (nginx + lua)
  2. 想成为BAT中的一员,你总要去学点什么(一)
  3. mysql的分页查询
  4. 大剑无锋之介绍一下B+树【面试推荐】
  5. 那么到底什么是热点???
  6. HQL中的substring
  7. Java位操作:如何将long类型的指定位设置为0或1?How to set/unset a bit at specific position of a long?
  8. vb for循环 combobox的使用 Print的使用
  9. Win10 64位 汇编环境的搭建: 安装配置 DOSBOX、MASM
  10. C语言:L1-031 到底是不是太胖了 (10分)(解题报告)