Python数据挖掘007-数据变换
数据变换主要是对数据进行规范化处理,将数据转换成“适当的”形式,以适用于挖掘任务和算法的需要。
1. 简单函数变换
简单函数变换通常用来将不具有正态分布的数据变换成具有正太分布的数据。
在时间序列分析中,有时简单的对数变换或者差分运算就可以将非平稳序列转换成平稳序列。
另外,如果某属性的取值范围太大,也可以用对数变换。
eg:

2. 数据规范化(归一化)
为了消除指标之间的量纲和取值范围差异的影响,需要进行标准化处理,将数据按照比例进行缩放,使之落入一个特定的区域。比如将工资收入属性值映射到【-1,1】或者【0,1】之间
数据归一化对于基于距离的挖掘算法尤其重要
2.1 min-max归一化
也称离差标准化,是对原始数据的线性变换,将数值映射到【0,1】之间。

Min-max归一化能够保留原来数据中存在的关系,是消除量纲和数据取值范围影响的最简单方法。
缺点是:若某数据集中且某个数据很大,则归一化之后各值都回接近于0,且相差不大。而且,在将来test set中如果遇到查过目前的min-max范围的时候,可能非常不准确。
2.2 零-均值规范化
经过处理后的数据均值为0,标准差为1,公式为:

这个方法是当前应用最多的数据标准化方法。
2.3 小数定标规范化
移动属性值的小数位数,将属性值映射到【-1,1】之间,移动的位数取决于属性值绝对值的最大值。

下面是各种归一化代码:
data = pd.read_excel(r"E:\PyProjects\DataSet\PyMining\Data\chapter4\demo\data\normalization_data.xls", header = None) #读取数据
(data - data.min())/(data.max() - data.min()) #最小-最大规范化
(data - data.mean())/data.std() #零-均值规范化
data/10**np.ceil(np.log10(data.abs().max())) #小数定标规范化
3. 连续属性离散化
一些挖掘算法,特别是某些分类算法,比如ID3算法,Apriori算法,要求数据是分类属性形式,此时需要将连续属性变换为分类属性,即连续属性的离散化。
具体过程是:在数值的取值范围内设定若干个离散的划分点,将取值范围划分为一些离散化的区间,最后用不同的符号或整数值代表落在每个子区间中的数据值。
常用的离散化方法有等宽法,等频法,一维聚类法
3.1 等宽法
将属性的值域分成具有相同宽度的区间,区间个数由数据本身的特点决定,或者由用户指定,类似于制作频率分布表。
3.2 等频法
保证每个区间中的数据个数相等。
这两种方法简单易行,但需要认为指定划分区间的个数,同时对离群点等比较敏感。
3.3 一维聚类法
两个步骤:首先将连续属性的值用聚类算法(eg Kmeans)进行聚类。然后将聚类得到的簇进行处理,一个簇的连续属性值当作一个离散值,作同一个标记。
这个方法也需要用户指定簇的个数,从而决定产生的区间数。
代码
k=4 # 离散化为4个类别
d1 = pd.cut(data['肝气郁结证型系数'], k, labels = range(k)) #等宽离散化,各个类比依次命名为0,1,2,3
d1[:20]
## pd.cut是实现等宽离散化最简单的方法。

#等频率离散化
w=[1.0*i/k for i in range(k+1)]
print(w)
w=data.describe(percentiles = w)[4:4+k+1] #使用describe函数自动计算分位数
print(w)
d2 = pd.cut(data['肝气郁结证型系数'], w['肝气郁结证型系数'], labels = range(k))
print(d2[:20])

### Kmeans聚类进行离散化
from sklearn.cluster import KMeans #引入KMeans
kmodel = KMeans(n_clusters = k, n_jobs = 4) #建立模型,n_jobs是并行数,一般等于CPU数较好
kmodel.fit(data) #训练模型
print(kmodel)
print(kmodel.cluster_centers_)
c = pd.DataFrame(kmodel.cluster_centers_).sort_values(0) #输出聚类中心,并且排序(默认是随机序的)
print(c)
w = c.rolling(2).mean().iloc[1:] #相邻两项求中点,作为边界点
print('w: ',w)
w = [0] + list(w[0]) + [data['肝气郁结证型系数'].max()] #把首末边界点加上
print('w2: ',w)
d3 = pd.cut(data['肝气郁结证型系数'], w, labels = range(k))
print(d3[:20])

4. 属性构造
这个是特征工程的一部分。
为了提取更多有用的信息,挖掘更深层次的模式,有时需要利用已有的属性集构造出新的属性,并加入到现有的属性集合中。
一个构造属性比如:

线损率正常范围一般在3%-15%之间,如果远超过高范围,说明该线很有可能存在窃漏电异常行为。
5 小波变换
是近年来兴起的信号分析手段,该理论和方法在信号处理,图像处理,语音处理,模式识别等领域由广泛应用。
能够刻画某个问题的特征量往往是隐含在一个信号中的某个或者某些分量中,小波变换可以把非平稳信号分解为表达不同层次,不同频带信息的数据序列,即小波系数,选取适当的小波系数,即完成了信号的特征提取。
基于小波变换的信号特征提取方法由:


利用小波变换可以对声波信号进行特征提取,提取出可以代表声波信号的向量数据,即完成从声波信号到特征向量数据的变换。
下面利用小波函数对声波信号数据进行分解,得到5个层次的小波系数。利用这些小波系数求得各个能量值,这些能量值可以作为声波信号的特征数据。
更好用的python库是PyWavelets。
from scipy.io import loadmat #mat是MATLAB专用格式,需要用loadmat读取它
mat = loadmat(r"E:\PyProjects\DataSet\PyMining\Data\chapter4\demo\data\leleccum.mat")
signal = mat['leleccum'][0]
plt.plot(signal)

import pywt #导入PyWavelets
coeffs = pywt.wavedec(signal, 'bior3.7', level = 5)
#返回结果为level+1个数字,第一个数组为逼近系数数组,后面的依次是细节系数数组
plt.plot(coeffs[0])


参考资料:
《Python数据分析和挖掘实战》张良均等