今天看到了“指数移动平均窗口标准化”,就研究了一下这是个啥东西,然后又顺便看了一下其他的数据标准化方法,这里顺便记录一下,方便以后查阅。
zscore标准化是一种基于数据分布的标准化方法。它的基本思想是将数据转换为均值为0,标准差为1的分布
,从而使得数据具有更好的可比性和可解释性。具体来说,对于给定的数据集 x 1 , x 2 , . . . , x n x_1, x_2, ..., x_n x1,x2,...,xn,我们可以计算其zscore标准化后的结果 y 1 , y 2 , . . . , y n y_1, y_2, ..., y_n y1,y2,...,yn 如下:
y i = x i − μ σ y_i = \frac{x_i - \mu}{\sigma} yi=σxi−μ
其中, μ \mu μ 和 σ \sigma σ 分别表示数据集的均值和标准差。
相比于指数移动平均窗口标准化,zscore标准化具有以下优点:
当数据集符合正态分布或者需要将数据转换为标准正态分布时,可以考虑使用zscore标准化。
scipy.stats.zscore
>>> import numpy as np
>>> a = np.array([ 0.7972, 0.0767, 0.4383, 0.7866, 0.8091,
0.1954, 0.6307, 0.6599, 0.1065, 0.0508])
>>> from scipy import stats
>>> stats.zscore(a)
array([ 1.1273, -1.247 , -0.0552, 1.0923, 1.1664, -0.8559, 0.5786,
0.6748, -1.1488, -1.3324])
指数移动平均窗口标准化(Exponential Moving Window Normalization)和zscore标准化是两种常用的数据标准化方法,它们的作用是将数据转换为具有相似分布的标准正态分布或者均值为0,标准差为1的分布
,以便更好地适配模型。
指数移动平均窗口标准化是一种基于指数移动平均的标准化方法。它的基本思想是计算每个时间步的均值和标准差,并使用指数移动平均来动态更新均值和标准差,从而使得标准化后的数据具有更好的稳定性和一致性。具体来说,对于给定的时间序列数据 x 1 , x 2 , . . . , x t x_1, x_2, ..., x_t x1,x2,...,xt,我们可以计算其指数移动平均窗口标准化后的结果 y 1 , y 2 , . . . , y t y_1, y_2, ..., y_t y1,y2,...,yt 如下:
y t = x t − μ t σ t + ϵ y_t = \frac{x_t - \mu_t}{\sigma_t + \epsilon} yt=σt+ϵxt−μt
其中, μ t \mu_t μt 和 σ t \sigma_t σt 分别表示时间步 t t t 前 n n n 个时间步数据的均值和标准差, ϵ \epsilon ϵ 是一个小的常数,用于避免除数为0的情况。
相比于zscore标准化,指数移动平均窗口标准化具有以下优点:
当数据集中存在较多的极端值时,可以考虑使用指数移动平均窗口标准化,以避免标准化结果不稳定的问题。
import numpy as np
def exponential_moving_window_normalize(data, window_size, eps=1e-8):
"""
Exponential Moving Window Normalization
Args:
data: 输入的数据,可以是一维或者二维的数组
window_size: 窗口大小,即计算均值和标准差的时间步数
eps: 避免分母为0的小常数,默认为1e-8
Returns:
Exponential Moving Window Normalized data
"""
if len(data.shape) == 1:
data = data.reshape(-1, 1)
n_samples, n_features = data.shape
mu = np.zeros((n_samples, n_features))
sigma = np.zeros((n_samples, n_features))
for i in range(n_samples):
if i < window_size:
mu[i] = np.mean(data[:i+1], axis=0)
sigma[i] = np.std(data[:i+1], axis=0)
else:
mu[i] = np.mean(data[i-window_size+1:i+1], axis=0)
sigma[i] = np.std(data[i-window_size+1:i+1], axis=0)
return (data - mu) / (sigma + eps)
import torch
def exponential_moving_window_normalize(data, window_size, eps=1e-8):
"""
Exponential Moving Window Normalization
Args:
data: 输入的数据,可以是一维或者二维的Tensor
window_size: 窗口大小,即计算均值和标准差的时间步数
eps: 避免分母为0的小常数,默认为1e-8
Returns:
Exponential Moving Window Normalized data
"""
if len(data.shape) == 1:
data = data.unsqueeze(-1)
n_samples, n_features = data.shape
mu = torch.zeros((n_samples, n_features), device=data.device)
sigma = torch.zeros((n_samples, n_features), device=data.device)
for i in range(n_samples):
if i < window_size:
mu[i] = torch.mean(data[:i+1], dim=0)
sigma[i] = torch.std(data[:i+1], dim=0)
else:
mu[i] = torch.mean(data[i-window_size+1:i+1], dim=0)
sigma[i] = torch.std(data[i-window_size+1:i+1], dim=0)
return (data - mu) / (sigma + eps)
Min-Max标准化(Min-Max Normalization):将数据线性缩放到[0,1]或者[-1,1]的区间内。具体来说,对于给定的数据集 x 1 , x 2 , . . . , x n x_1, x_2, ..., x_n x1,x2,...,xn,我们可以计算其Min-Max标准化后的结果 y 1 , y 2 , . . . , y n y_1, y_2, ..., y_n y1,y2,...,yn 如下:
y i = x i − min ( x ) max ( x ) − min ( x ) y_i = \frac{x_i - \min(x)}{\max(x) - \min(x)} yi=max(x)−min(x)xi−min(x)
Min-Max标准化(Min-Max Normalization):将数据线性缩放到[0,1]或者[-1,1]的区间内。适用于数据分布比较均匀、无明显异常值的情况
。对于神经网络等对数据范围敏感的模型,Min-Max标准化也是一种常用的数据标准化方法。
>>> from sklearn.preprocessing import MinMaxScaler
>>> data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
>>> scaler = MinMaxScaler()
>>> print(scaler.fit(data))
MinMaxScaler()
>>> print(scaler.data_max_)
[ 1. 18.]
>>> print(scaler.transform(data))
[[0. 0. ]
[0.25 0.25]
[0.5 0.5 ]
[1. 1. ]]
>>> print(scaler.transform([[2, 2]]))
[[1.5 0. ]]
Decimal Scaling标准化(Decimal Scaling Normalization):将数据除以一个适当的10的幂次方,使得标准化后的数据的绝对值小于1。具体来说,对于给定的数据集 x 1 , x 2 , . . . , x n x_1, x_2, ..., x_n x1,x2,...,xn,我们可以计算其Decimal Scaling标准化后的结果 y 1 , y 2 , . . . , y n y_1, y_2, ..., y_n y1,y2,...,yn 如下:
y i = x i 1 0 j y_i = \frac{x_i}{10^j} yi=10jxi
其中, j j j 是一个适当的幂次方,使得 1 0 j > max ( ∣ x 1 ∣ , ∣ x 2 ∣ , . . . , ∣ x n ∣ ) 10^j > \max(|x_1|, |x_2|, ..., |x_n|) 10j>max(∣x1∣,∣x2∣,...,∣xn∣)。
Decimal Scaling标准化(Decimal Scaling Normalization):将数据除以一个适当的10的幂次方,使得标准化后的数据的绝对值小于1。适用于数据的值域较大,但又不方便或不必要对数据进行归一化的情况
。
import numpy as np
def decimal_scaling_normalization(x, j):
y = x / 10**j
return y
Logarithmic标准化(Logarithmic Normalization):将数据取对数后再进行标准化。具体来说,对于给定的数据集 x 1 , x 2 , . . . , x n x_1, x_2, ..., x_n x1,x2,...,xn,我们可以计算其Logarithmic标准化后的结果 y 1 , y 2 , . . . , y n y_1, y_2, ..., y_n y1,y2,...,yn 如下:
y i = log ( x i ) log ( max ( x ) ) y_i = \frac{\log(x_i)}{\log(\max(x))} yi=log(max(x))log(xi)
其中, max ( x ) \max(x) max(x) 是数据集中的最大值。
Logarithmic标准化(Logarithmic Normalization):将数据取对数后再进行标准化。适用于数据的值域较大,但又不方便或不必要对数据进行归一化的情况
。对于呈现指数增长或指数衰减的数据,取对数可以使其更加平滑,从而更容易进行分析和建模。
import numpy as np
def logarithmic_normalization(x):
y = np.log(x) / np.log(np.max(x))
return y
Power Transformation标准化(Power Transformation Normalization):将数据进行幂次变换后再进行标准化。具体来说,对于给定的数据集 x 1 , x 2 , . . . , x n x_1, x_2, ..., x_n x1,x2,...,xn,我们可以先对其进行幂次变换 x i ( λ ) x_i^{(\lambda)} xi(λ),然后计算其Power Transformation标准化后的结果 y 1 , y 2 , . . . , y n y_1, y_2, ..., y_n y1,y2,...,yn 如下:
y i = x i ( λ ) − min ( x ( λ ) ) max ( x ( λ ) ) − min ( x ( λ ) ) y_i = \frac{x_i^{(\lambda)} - \min(x^{(\lambda)})}{\max(x^{(\lambda)}) - \min(x^{(\lambda)})} yi=max(x(λ))−min(x(λ))xi(λ)−min(x(λ))
其中, λ \lambda λ 是一个超参数,用于控制幂次变换的强度, x ( λ ) x^{(\lambda)} x(λ) 是对数据集 x 1 , x 2 , . . . , x n x_1, x_2, ..., x_n x1,x2,...,xn 进行幂次变换后得到的结果,即 x i ( λ ) = sgn ( x i ) ∣ x i ∣ λ x_i^{(\lambda)} = \text{sgn}(x_i) |x_i|^\lambda xi(λ)=sgn(xi)∣xi∣λ,其中 sgn ( ⋅ ) \text{sgn}(\cdot) sgn(⋅) 表示符号函数。
Power Transformation标准化(Power Transformation Normalization):将数据进行幂次变换后再进行标准化。适用于数据分布不均匀,存在明显偏态或异常值的情况
。通过幂次变换可以调整数据分布的形态,使得数据更符合模型的假设,从而提高模型的预测能力。
import numpy as np
def power_transformation_normalization(x, lam):
x_lam = np.sign(x) * np.abs(x)**lam
y = (x_lam - np.min(x_lam)) / (np.max(x_lam) - np.min(x_lam))
return y