对矢量化特征归一化进行适当的零方差处理?

Gno*_*ume 2 statistics matlab vectorization octave

问题:在 Octave 中进行特征归一化时,零方差输入会导致 div-zero 错误。

问题:在处理矢量化数据时,是否有一种很好的(r)方法来处理 div-zero?

示例: 输入是一个包含列中多个数据集的矩阵:

X =  [1  3.5  7.5  9 ; 
      1  4    8    9 ; 
      1  4.5  8.5  9]
Run Code Online (Sandbox Code Playgroud)

因此,X包含三个系列:x_1 = [1,1,1]x_2 = [7.5, 8, 8.5],和x_3 = [9,9,9]。为了使用矢量化对每个集合进行归一化,以下方法似乎是明智的:

X =  [1  3.5  7.5  9 ; 
      1  4    8    9 ; 
      1  4.5  8.5  9]
Run Code Online (Sandbox Code Playgroud)

然而,上述方法将失败,因为双方x_1x_3具有零方差等会发生分裂,零错误。

我对零方差数据的首选处理是将 sigma 设置为 1。目前我正在使用以下 kludge:

mu = mean(X);
sigma = std(X);
X_norm = (1 ./ sigma) .* (X - mu);
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 广播在这里使用了两次,在除法和减法运算中
  • 此示例基于 Octave,但该问题可能同样适用于 MATLAB。
  • 这个例子很容易说明——“真正的”用法会有更多、更大的数据集
  • 这个例子零方差数据与常规数据区别对待(不完美)
  • zscore听起来很相关,但(顾名思义)更适合计算 z 分数......

Lui*_*ndo 5

为什么不只是这个?

mu = mean(X);
sigma = std(X);
sigma(sigma==0) = 1; %// add this line to remove zeros
X_norm = (1 ./ sigma) .* (X - mu);
Run Code Online (Sandbox Code Playgroud)

或者,为了保存一些操作:

mu = mean(X);
sigma = std(X);
ind = sigma~=0; %// detect zero values
X_norm = X - mu;
X_norm(:,ind) = X_norm(:,ind) ./ sigma(ind) ;
Run Code Online (Sandbox Code Playgroud)

一般来说,最好使用

sigma(sigma<=tol) = 1; %// add this line to remove values close to zero
Run Code Online (Sandbox Code Playgroud)

在第一种方法中,或

ind = sigma>tol; %// detect values close to zero
Run Code Online (Sandbox Code Playgroud)

第二,对于给定的容差tol(例如tol = 1e-10)。在有限精度误差可以产生诸如1e-15而不是零之类的值的应用程序中,这是一种更好的方法。