数据变换

正态分布

为了让成绩符合正态分布,出题老师是怎么做的呢?

他们通常可以把考题分成三类

  • 第一类:基础题,占总分70%,基本上属于送分题
  • 第二类:灵活题,基础范围内+一定的灵活性,占20%
  • 第三类:难题,涉及知识面较广的难题,占10%

如果一个出题老师没有按照上面的标准来出题,而是将第三类难题比重占到了70%,也就是我们说的“超纲”

结果会是怎样呢?你会发现,大部分人成绩都“不及格”

最后在大家激烈的讨论声中,老师会将考试成绩做规范化处理,从而让成绩满足正态分布的情况

因为只有这样,成绩才更具有比较性。所以正态分布的成绩,不仅可以让你了解全班整体的情况,还能了解每个人的成绩在全班中的位置

数据变换在数据分析中的角色

假设A考了80分,B也考了80分,但前者是百分制(60分及格),后者500分制(300分及格)

如果我们把从这两个渠道收集上来的数据进行集成、挖掘

就算使用效率再高的算法,结果也不是正确的。因为这两个渠道的分数代表的含义完全不同

所以,在数据挖掘中数据变换比算法选择更重要

如果不进行变换的话,要不就是维数过多,增加了计算的成本,要不就是数据过于集中,很难找到数据之间的特征

在数据变换中,重点是如何将数值进行规范化,有三种常用的规范方法

  • Min-Max规范化
  • Z-Score规范化
  • 小数定标规范化

其中Z-Score规范化可以直接将数据转化为正态分布的情况,当然不是所有自然界的数据都需要正态分布

我们也可以根据实际的情况进行设计,比如取对数log,或者神经网络里采用的激活函数等

常见的变换方法

数据平滑:去除数据中的噪声,将连续数据离散化。这里可以采用分箱、聚类和回归的方式进行数据平滑

数据聚集:对数据进行汇总,在SQL中有一些聚合函数可以供我们操作,比如Max()反馈某个字段的数值最大值,Sum()返回某个字段的数值总和

数据概化:将数据由较低的概念抽象成为较高的概念,减少数据复杂度,即用更高的概念替代更低的概念。比如说上海、杭州、深圳、北京可以概化为中国

数据规范化:使属性数据按比例缩放,这样就将原来的数值映射到一个新的特定区域中。常用的方法有最小—最大规范化、Z—score规范化、按小数定标规范化等

  • Min-max规范化方法是将原始数据变换到[0,1]的空间中。用公式表示就是:新数值 =(原数值 - 极小值)/(极大值 - 极小值)
  • Z-Score规范化(以上面A、B考试成绩为例,A班平均值80,标准差10;B班平均值400,标准差100)新数值 =(原数值 - 均值)/ 标准差
    • 则A、B的新数值分别为:(80-80)/10=0、(80-400)/100=-3.2
    • 在Z-Score标准下,A的成绩比B的成绩好
    • Z-Score的优点是算法简单,不受数据量级影响,结果易于比较
    • Z-Score的缺点是需要数据整体的平均值和方差,而且结果没有实际意义,只是用于比较
  • 小数定标规范化,假设属性A的取值范围是-999到88,那么最大绝对值为999,小数点就会移动3位
    • 即新数值=原数值/1000。那么A的取值范围就被规范化为-0.999到0.088

属性构造:构造出新的属性并添加到属性集中。这里会用到特征工程的知识,因为通过属性与属性的连接构造新的属性,其实就是特征工程

  • 比如说,数据表中统计每个人的英语、语文和数学成绩,你可以构造一个“总和”这个属性,来作为新属性。这样“总和”这个属性就可以用到后续的数据挖掘计算中

Python的SciKit-Learn库使用

SciKit-Learn是Python的重要机器学习库,它帮我们封装了大量的机器学习算法,比如分类、聚类、回归、降维等。此外,它还包括了数据变换模块

Min-max规范化


from sklearn import preprocessing
import numpy as np

x = np.array([
    [1, 10, -100],
    [99, 666, 999],
    [-100, 0.02, 12]
])

minmax_scale = preprocessing.MinMaxScaler()
minmax_x = minmax_scale.fit_transform(x)

print(minmax_x)

Z-Score规范化


from sklearn import preprocessing
import numpy as np

x = np.array([
    [1, 10, -100],
    [99, 666, 999],
    [-100, 0.02, 12]
])

scaled_x = preprocessing.scale(x)

print(scaled_x)

小数定标规范化


import numpy as np

x = np.array([
    [1, 10, -100],
    [99, 666, 999],
    [-100, 0.02, 12]
])

# 利用log向上取整后,得到3
j = np.ceil(np.log10(np.max(abs(x))))

# 10的3次方,即1000
scaled_x = x/(10**j)

print(scaled_x)

results matching ""

    No results matching ""