JAVA使用ND4J实现统计学归一化

497 阅读3分钟

介绍

归一化(Normalization)是数据预处理中的一个重要步骤,它旨在调整数据尺度,使其适合特定的范围或满足特定的条件。在机器学习和数据科学领域,归一化有助于改善算法的收敛速度和性能。以下是几种常见的归一化方法:

引入

在ND4J中配置AVX CPU支持的AVX级别相匹配的ND4J版本。 对于nd4j/nd4j-platform依赖项,ND4J默认配置(仅包括nd4j-native 或 nd4j-native-platform依赖项而不包括maven分类器配置)是“generic x86”(无AVX)。 要配置AVX2和AVX512,需要为适当的架构指定一个分类器。 为X86体系结构提供了以下二进制文件(nd4j-native分类器):

  • Generic x86 (no AVX): linux-x86_64, windows-x86_64, macosx-x86_64
  • AVX2: linux-x86_64-avx2, windows-x86_64-avx2, macosx-x86_64-avx2
  • AVX512: linux-x86_64-avx512
<dependency>
<groupId>org.nd4j</groupId>
<artifactId>nd4j-native</artifactId>
<version>1.0.0-beta7</version>
</dependency>
<dependency>
<groupId>org.nd4j</groupId>
<artifactId>nd4j-native</artifactId>
<version>1.0.0-beta7</version>
<classifier>windows-x86_64-avx2</classifier>
</dependency>

归一化常见几种方式

最小-最大归一化(Min-Max Normalization)

  • 描述:将数据缩放到一个指定的范围,通常是0到1。
  • 公式: x' = (x - min) / (max - min)
  • 适用场景:当知道数据分布的范围,并且需要将数据限制在特定范围内时。

案例

// 创建一个INDArray,这里我们使用了一些正数,但通常你应该根据实际情况来创建数组
INDArray array = Nd4j.create(new double[]{1, 2, 3, 4, 5});
double min=array.minNumber().doubleValue();
double max=array.maxNumber().doubleValue();
//使用最小-最大归一化
INDArray nomal = array.sub(min).div(max-min);
System.out.println(nomal);

Z分数归一化(Z-Score Normalization)

  • 描述:将数据调整为具有零均值(均值为0)和单位方差(标准差为1)。
  • 公式:Z值 = (X - µ) / σ
  • 适用场景:当知道数据分布的范围,并且需要将数据限制在特定范围内时。 案例
INDArray array = Nd4j.create(new double[]{1, 2, 3, 4, 5});
// 计算均值和标准差
double mean = array.meanNumber().doubleValue();
System.out.println(mean);
double std = array.stdNumber().doubleValue();
System.out.println(std);
// 进行Z分数归一化
INDArray normalizedArray = array.sub(mean).div(std);
System.out.println(normalizedArray);

对数归一化(Logarithmic Normalization)

  • 描述:通过取对数来压缩数据的范围,特别是当数据的分布范围很广时。
  • 公式:X = log(X + 1)(通常加1是为了避免对0取对数)
  • 适用场景:当数据分布呈现指数分布或长尾分布时

案例

// 创建一个INDArray,这里我们使用了一些正数,但通常你应该根据实际情况来创建数组
INDArray array = Nd4j.create(new double[]{1, 2, 3, 4, 5});
// 为了防止对0或负数取对数,我们先将数组中的每个元素加1
INDArray shiftedArray = array.add(1.0);
// 应用对数归一化
INDArray logNormalizedArray = Nd4j.math.log(shiftedArray);
// 打印原始数组和归一化后的数组
System.out.println("Original array: " + array);
System.out.println("Log normalized array: " + logNormalizedArray);

L1和L2归一化(L1/L2 Normalization)

  • 描述:L1归一化是将向量中每个元素的绝对值之和归一化为1,L2归一化是将向量中每个元素的平方和归一化为1。
  • 适用场景:在机器学习中,特别是深度学习中,用于权重向量的归一化
  • 公式

1729740296383.jpg

案例

// 创建一个INDArray
INDArray array = Nd4j.create(new double[]{1, 2, 3, 4, 5});
// L1归一化(每个元素除以所有元素绝对值之和)
INDArray l1NormalizedArray = array.div(Transforms.abs(array).sum());
// L2归一化(每个元素除以所有元素平方和的平方根)
INDArray l2NormalizedArray = array.div(Nd4j.norm2(l1NormalizedArray));
System.out.println(Nd4j.norm2(l1NormalizedArray));
// 打印原始数组和归一化后的数组
System.out.println("Original array: " + array);
System.out.println("L1 normalized array: " + l1NormalizedArray);
System.out.println("L2 normalized array: " + l2NormalizedArray);