数据规范化与数据离散化

时间:2022-10-03 15:53:51

一、数据规范化

数据规范化(归一化)处理是数据挖掘的一项基础工作。不同评价指标往往具有不同的量纲,数值间的差别可能很大,不进行处理可能会影响到数据分析的结果。为了消除指标之间的量纲和取值范围差异的影响,需要进行标准化处理,将数据按照比例进行缩放,使之落入一个特定的区域,便于进行综合分析。如将工资收入属性值映射到【-1,1】或者【0,1】内。
常用的方法有:

  • 小数定标规范化;
  • 最小-最大规范化;
  • 零-均值规范化(z-score规范化)

数据规范化的目的:

将一个属性取值范围影射到一个特定范围之内,以消除数值性属性因大小不一而造成挖掘结果的偏差

数据示例:我们将用下面这个矩阵数据来举例说明

数据规范化与数据离散化
数据读取:

import pandas as pd
import numpy as np

datafile = '../data/normalization_data.xls' #参数初始化
data = pd.read_excel(datafile, header = None) #读取数据

1、小数定标规范化

通过移动属性值的小数位数,将属性值映射到【-1,1】之间,移动的小数位数取决于属性值绝对值的最大值。
转换公式:
数据规范化与数据离散化
其中j是使Max(|v'|)<1的最小整数,例:假定A的取值范围[-986,917],则A的最大绝对值为986,为使用小数定标规范化,用1000(即j=3)除每个值,这样-986被规范化为-0.986。
对上面举例的矩阵数据使用小数定标规范化:

data/10**np.ceil(np.log10(data.abs().max())) #小数定标规范化

数据规范化与数据离散化

2、最小—最大规范化

假定minAmaxA分别为属性A的最小和最大值,则通过下面公式将A的值映射到区间[new_min, new_max]中的v’
数据规范化与数据离散化
其中,maxA为样本数据的最大值,minA为样本数据的最小值。maxA-minA为极差。离差标准化保留了原来数据中存在的关系,是消除量纲和数据取值范围影响的最简单方法。这种处理方法的缺点是若数值集中且某个数值很大,则规范化后各值会接近于0,并且将会相差不大。若将来遇到超过目前属性[minA,maxA]取值范围的时候,会引起系统出错,需要重新确定minA和maxA。
对上面举例的矩阵数据使用最小—最大规范化规范化:

(data - data.min())/(data.max() - data.min()) #最小-最大规范化

数据规范化与数据离散化

3、零-均值规范化(z-score规范化)

零-均值规范化也称标准差标准化,经过处理的数据的均值为0,标准差为1。转化公式为
数据规范化与数据离散化
其中 x̅ 为原始数据的均值,σ为原始数据的标准差,是当前用得最多的数据标准化方法。

(data - data.mean())/data.std() #零-均值规范化

数据规范化与数据离散化
注意:

  • 规范化将原来的数据改变很多,特别是上述的后两种方法。
  • 有必要保留规范化参数(如平均值和标准差,如果使用z-score规范化)以便将来的数据可以用一致的方式规范化。

二、数据离散化

连续变量的离散化,就是具体性的问题抽象为概括性的问题,即是将它取值的连续区间划分为小的区间,再将每个小区间重新定义为一个唯一的取值。数据离散化的基本方法主要有

  • (1)等宽法
    将属性的值域分成具有相同宽度的区间,区间的个数由数据本身的特点决定,或者由用户指定,类似于制作频率分布表。
  • (2)等频法
    将相同数量的记录放进每个区间。
    这两种方法简单,易于操作,但都需要人为地规定划分区间的个数。同时,等宽法的缺点在于它对离群点比较敏感,倾向于不均匀地把属性值分布到各个区间。有些区间包含许多数据,而另外一些区间的数据极少,这样会严重损坏建立的决策模型。等频法虽然避免了上述问题的产生,却可能将相同的数据值分到不同的区间以满足每个区间中固定的数据个数。
  • (3)基于聚类分析的方法
    一维聚类的方法包括两个步骤,首先将连续属性的值用聚类算法(如K-Means算法)进行聚类,然后再将聚类得到的簇进行处理,合并到一个簇的连续属性值并做同一标记。聚类分析的离散化方法也需要用户指定簇的个数,从而决定产生的区间数

对连续变量进行离散化处理,一般经过以下步骤:

  • 对此变量进行排序。
  • 选择某个点作为候选断点,根据给定的要求,判断此断点是否满足要求。
  • 若候选断点满足离散化的要求,则对数据集进行分裂或合并,再选择下一个候选断点。
  • 重复步骤2和3,如果满足停止准则,则不再进行离散化过程,从而得到最终的离散结果。

下面使用上述3种离散化方法对“医学中中医证型的相关数据”进行连续属性离散化的对比,该属性的示例数据如下:
数据规范化与数据离散化

# -*- coding: utf-8 -*-
# 数据规范化
import numpy as np
import pandas as pd

datafile = '../data/discretization_data.xls'  # 参数初始化
data = pd.read_excel(datafile)  # 读取数据
data = data[u'肝气郁结证型系数'].copy()
k = 4

d1 = pd.cut(data, k, labels=range(k))  # 等宽离散化,各个类比依次命名为0,1,2,3

# 等频率离散化
w = [1.0 * i / k for i in range(k + 1)]
w = data.describe(percentiles=w)[4:4 + k + 1]  # 使用describe函数自动计算分位数
w[0] = w[0] * (1 - 1e-10)
d2 = pd.cut(data, w, labels=range(k))
#
from sklearn.cluster import KMeans  # 引入KMeans

kmodel = KMeans(n_clusters=k, n_jobs=4)  # 建立模型,n_jobs是并行数,一般等于CPU数较好
data = data.values.reshape(-1,1)
kmodel.fit(data.reshape((len(data), 1)))  # 训练模型
c = pd.DataFrame(kmodel.cluster_centers_).sort_values(0)  # 输出聚类中心,并且排序(默认是随机序的)
w = c.rolling(2).mean().iloc[1:]  # 相邻两项求中点,作为边界点
w = [0] + list(w[0]) + [data.max()]  # 把首末边界点加上
l = []
for i in data:
    i = i[0]
    l.append(i)

d3 = pd.cut(l, w, labels=range(k))


def cluster_plot(d, k):  # 自定义作图函数来显示聚类结果
    import matplotlib.pyplot as plt
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
    plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

    plt.figure(figsize=(8, 3))
    for j in range(0, k):
        plt.plot(data[d == j], [j for i in d[d == j]], 'o')

    plt.ylim(-0.5, k - 0.5)
    return plt

等宽离散化结果:

cluster_plot(d1, k).show()

数据规范化与数据离散化
等频离散化结果:

cluster_plot(d2, k).show()

数据规范化与数据离散化

(一维)聚类离散化结果

cluster_plot(d3, k).show()

数据规范化与数据离散化
分别用等宽法、等频法和(一维)聚类对数据进行离散化,将数据分成4类,然后将每一类记为同一个标识,如分别记为A1、A2、A3、A4,再进行建模。