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

数据读取:
import pandas as pd
import numpy as np
datafile = '../data/normalization_data.xls' #参数初始化
data = pd.read_excel(datafile, header = None) #读取数据
通过移动属性值的小数位数,将属性值映射到【-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())) #小数定标规范化

假定minA和maxA分别为属性A的最小和最大值,则通过下面公式将A的值映射到区间[new_min, new_max]中的v’

其中,maxA为样本数据的最大值,minA为样本数据的最小值。maxA-minA为极差。离差标准化保留了原来数据中存在的关系,是消除量纲和数据取值范围影响的最简单方法。这种处理方法的缺点是若数值集中且某个数值很大,则规范化后各值会接近于0,并且将会相差不大。若将来遇到超过目前属性[minA,maxA]取值范围的时候,会引起系统出错,需要重新确定minA和maxA。
对上面举例的矩阵数据使用最小—最大规范化规范化:
(data - data.min())/(data.max() - data.min()) #最小-最大规范化

零-均值规范化也称标准差标准化,经过处理的数据的均值为0,标准差为1。转化公式为

其中 x̅ 为原始数据的均值,σ为原始数据的标准差,是当前用得最多的数据标准化方法。
(data - data.mean())/data.std() #零-均值规范化

注意:
连续变量的离散化,就是具体性的问题抽象为概括性的问题,即是将它取值的连续区间划分为小的区间,再将每个小区间重新定义为一个唯一的取值。数据离散化的基本方法主要有
对连续变量进行离散化处理,一般经过以下步骤:
下面使用上述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,再进行建模。