定义:将数据缩放到特定的区间中,以使得数值之间具有可比较性。
目标:
为什么需要归一化:
哪些模型需要归一化:
哪些模型不需要归一化:
公式:\(X_{norm} = \frac{X - X_{min}}{X_{max}-X_{min}}\)
结果:将原始数据经过线性变换,把数值缩放到[0,1]之间,不会改变数据的分布。
公式:\(X_{norm} = \frac{X - X_{mean}}{X_{max}-X_{min}}\)
结果:将原始数据经过线性变换,把数值缩放到[-1,1]之间
公式:\(X_{norm} = \frac{X - X_{mean}}{\sigma}\),其中\(\sigma\)是标准差。
结果:转换后的数值,其平均值为0,方差为1,即服从标准正太分布,这个转换不会改变数据的分布。
公式:\(X_{norm} = \frac{X}{\|X\|}\),其中\(\|X\|\)是这个数据向量的欧式长度(Euclidean length)。
结果:转换后的数值在[0,1]之间。
公式:\(X_{norm} = \frac{log{X}}{log{X_{max}}}\)
结果:转换后的数值在[0,1]之间。
公式:\(X_{norm} = atan{X}*\frac{2}{\pi}\)
结果:如果X都大于0,则区间映射到[0,1],小于0的数据映射到[-1,0]之间。
原理:
结果:使得不同的数据集具有相同的分布,容易比较。(这个方法在microarray数据中使用得很多,原先叫quantile standardization,后来才叫做quantile normalization。wiki给出了一个例子,说的是在不同的样本中,如果将基因的表达量归一化到同一水平。)。下面是不同样本中前后表达量分布的例子:
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('ticks')
np.random.random(42)
X = np.random.exponential(size=1000)
X_norm_min_max = (X - X.min()) / (X.max() - X.min())
X_norm_mean_max = (X - X.mean()) / (X.max() - X.min())
X_norm_zscore = (X - X.mean()) / X.std()
X_norm_unit = X / np.linalg.norm(X)
fig, ax = plt.subplots(3, 2, figsize=(16,18), sharex=False, sharey=False)
sns.distplot(X, ax=ax[0,0])
ax[0,0].set_title('Raw')
sns.distplot(X_norm_min_max, ax=ax[0,1])
ax[0,1].set_title('min-max norm')
sns.distplot(X_norm_mean_max, ax=ax[1,0])
ax[1,0].set_title('mean-max norm')
sns.distplot(X_norm_zscore, ax=ax[1,1])
ax[1,1].set_title('z-score norm')
sns.distplot(X_norm_unit, ax=ax[2,0])
ax[2,0].set_title('unit length norm')