通过一个例子来说明什么是中心化与标准化,并且如何进行标准化与中心化。

1、Python包的加载与画图设置(不懂可以不看):

# 包的加载
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import palettable  #python颜色库
# 用于显示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

2、加载数据:

不懂代码的话可以理解为这里是读取一个表格数据。

# 这里做一个对矩阵进行标准化与中心化的对比,阐述其意义
state_data_0 = pd.read_csv('./state.csv')
state_data_0.set_index('Unnamed: 0', inplace=True)
state_data_0.index._name = 'state'
state_data = state_data_0.copy()
state_data

这个数据表是美国几个州的统计数据,每一行代表一个州,每一列分别是人口(Population)、收入(Income)、受教育程度(Illiteracy)、平均寿命(Life Exp)等等。

表格数据如图所示
表格数据如图所示

3、使用表格数据画图:

plt.figure(dpi=120)  # 在进行标准化与中心化处理之前绘制热图,由于不同列的数据差距过大,在绘制热图的时候就会导致反应出来的效果不好(例如:某一列的数据都在100~900,而另一列的数据都在10~99)
# sns.heatmap(state_data)
sns.heatmap(data=state_data,
            cmap=sns.cubehelix_palette(as_cmap=True),
            cbar=True,
            cbar_kws={'label': 'ColorBar',  #color bar的名称
                      'orientation': 'vertical',  #color bar的方向设置,默认为'vertical',可水平显示'horizontal'
                      # "ticks": np.arange(4.5, 8, 0.5),  #color bar中刻度值范围和间隔
                      # "format": "%.2f",  #格式化输出color bar中刻度值
                      "pad": 0.05,  #color bar与热图之间距离,距离变大热图会被压缩
                      },
            # annot=True,  #默认为False,当为True时,在每个格子写入data中数据
            # fmt=".2f",#设置每个格子中数据的格式,参考之前的文章,此处保留两位小数
            # annot_kws={'size':4,'weight':'normal', 'color':'blue'},#设置格子中数据的大小、粗细、颜色
            linewidths=1,  #格子与格子,默认为0
            # linecolor='red',  #每个格子边框颜色,默认为白色
            )
plt.title('未经过中心化与标准化的数据')

出图
出图

4、遇到了问题:

如上图所示,使用表格数据绘制了一张热图,但是发现由于表格中的数据相差过大(Population列都在千、万级别,Forst都在10~1000级别)导致绘制出来的图并不能很好地表达出来一定的区分度。

这个时候就在想有没有一种方法能够解决这个问题呢?——数据的标准化与中心化

标准化与中心化其实就是对一组数据求平均值和方差,然后计算:

$$ 处理后的结果=\frac{(源数据-源数据平均值)}{源数据的方差} $$

Python代码实现:

def norm_(pd_raw):
    """
    定义一个可以对DataFrame进行中心化与标准化的函数
    :param x: DataFrame
    :return: 经过标准化的DataFrame
    """
    pd_mean = np.mean(pd_raw, 0)  # 求DataFrame每一列的平均值
    pd_std = np.std(pd_raw, 0)  # 求DataFrame每一列的标准差
    return (pd_raw - pd_mean) / pd_std

上面这个函数就是定义一个可以用于将数据(Python中的DataFrame对象)进行标准化与中心化的函数,不懂代码的话可以理解为这一步就是如何将数据进行标准化与中心化。

5、对源数据进行标准化与中心化,然后重新出图:

state_data_norm = norm_(state_data)  # 这里对数据进行标准化与中心化处理,处理后各个列的数据都向中间靠拢
sns.heatmap(data=state_data_norm,
            cmap=sns.cubehelix_palette(as_cmap=True),
            cbar=True,
            cbar_kws={'label': 'ColorBar',  #color bar的名称
                      'orientation': 'vertical',  #color bar的方向设置,默认为'vertical',可水平显示'horizontal'
                      # "ticks": np.arange(4.5, 8, 0.5),  #color bar中刻度值范围和间隔
                      # "format": "%.2f",  #格式化输出color bar中刻度值
                      "pad": 0.05,  #color bar与热图之间距离,距离变大热图会被压缩
                      },
            # annot=True,  #默认为False,当为True时,在每个格子写入data中数据
            # fmt=".2f",#设置每个格子中数据的格式,参考之前的文章,此处保留两位小数
            # annot_kws={'size':4,'weight':'normal', 'color':'blue'},#设置格子中数据的大小、粗细、颜色
            linewidths=1,  #格子与格子,默认为0
            # linecolor='red',  #每个格子边框颜色,默认为白色
            )
plt.title('经过中心化与标准化的数据')

经过中心化与标准化的数据
经过中心化与标准化的数据

可以看到,经过中心化与标准化后,可以在热图上很好地对级别相差较大的数据进行区分。

这就是数据中心化与标注化的流程。