【深度学习】数据归一化/标准化 Normalization/Standardization

本文详细介绍了数据处理中的归一化技术,包括Min-max、均值、标准差归一化以及非线性方法如对数和反正切归一化。文章还讨论了如何根据应用场景选择合适的归一化函数,并给出了Java实现的工具类示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、实际问题

二、归一化 Normalization

三、归一化的类型

1. Min-max normalization (Rescaling)

2. Mean normalization

3.Z-score normalization (Standardization)

4.非线性归一化

4-1 对数归一化

4-2 反正切函数归一化

4-3 小数定标标准化(Demical Point Normalization)

四、如何选择归一化函数?

五、Java实现归一化工具类


一、实际问题

在数据分析、深度学习中,经常需要对数据进行处理,数据处理时,会发现一个问题:

不同维度的数据,数据范围偏差比较大,如

  • 距离地铁的距离——房价的关系
  • 海拔高度——氧气含量的关系

一个维度的数据范围大,一个小,导致以下问题:

【1】求解过程不平缓、函数收敛慢

【2】相关性展示不明显

如下图:

海拔越高、氧气含量越低,因为数据范围的原因,导致两者的相关性展示得不明显。

解决得方式就是归一化和标准化

二、归一化 Normalization

归一化,指将数据样本中的数据进行处理,使它们处于同一量级。

如 [0,1] 或者 [-1,1] 或者其它

归一化后,数据更具有可比性,如图

函数的求解过程也会比较平缓,更快求得最优解,如下图

左:未归一化的求解  右:归一化后的求解

三、归一化的类型

1. Min-max normalization (Rescaling)

最值归一化,公式如下:

\mathbf{​{x}'=\frac{x-min}{max-min}}

归一化后的数据范围为 [0, 1],其中min max分别求样本数据的最小值和最大值。

2. Mean normalization

均值归一化,公式如下:

\mathbf{​{x}'=\frac{x-mean}{max-min}}

归一化后的数据范围为 [-1, 1],其中mean、min、max为样本数据的平均值、最小值和最大值。

3.Z-score normalization (Standardization)

标准差归一化,也成为标准化(标准化其实就是归一化的一种),公式如下:

\boldsymbol{\mathbf{}\boldsymbol{\mathbf{}{x}'=\frac{x-mean}{\sigma}}}

归一化后的数据范围为实数集,其中mean、σ 分别为样本数据的均值和标准差。

4.非线性归一化

4-1 对数归一化

\boldsymbol{\mathbf{}{x}'=\frac{lg(x)}{lg(max)}}

4-2 反正切函数归一化

\boldsymbol{\mathbf{}{x}'=arctan(x)*\frac{2}{pi}}

归一化后的数据范围为 [-1, 1]

4-3 小数定标标准化(Demical Point Normalization)

\boldsymbol{\mathbf{}{x}'=\frac{x}{10^{j}}}

j为使

 \boldsymbol{\mathbf{}max(\left |{ x}' \right |)<1}

的最小整数,归一化后的数据范围为 [-1, 1]

四、如何选择归一化函数?

Min-Max归一化、Mean归一化适合

【1】最大最小值明确不变:如图像处理中,RGB值为0~255,可以使用Min-Max来处理。

【2】对数据范围有明确要求:如需要数据范围为-1~1

不适合:

【1】最大最小值不明确:每次有新的值加入,之前的结果就会发生改变,导致不稳定。

【2】有过大或过小的异常值存在:效果会较差

Z-score归一化适合:

【1】存在异常值、最大最小值不固定

缺点是:

【1】改变了数据的状态分布,但不会改变分布的种类:经过处理的数据呈均值为0,标准差为1的分布

非线性归一化适合

【1】数据分化程度较大的场景

五、Java实现归一化工具类

package com.potato.commonpro.util.math;

import java.util.ArrayList;
import java.util.List;

/**
 * 数据样本归一化工具类
 * 包含了多个归一化函数,提供了List/Array两种类型的输入输出,具体的归一化函数如下:
 * 【1】min-max normalization(Rescaling)
 * 【2】mean normalization
 * 【3】Z-score normalization (Standardization)
 * 【4】对数归一化
 * 【5】反正切函数归一化
 * 【6】小数定标标准化
 * <p>
 * Author:PotatoChan
 * Date:2023-12-30
 */
public class PotatoNormalization {


    /**
     * min-max normalization(Rescaling)
     * 归一化公式:x'=(x-min)/(max-min)
     * 归一化后的数据范围为 [0, 1],其中min 、max 分别求样本数据的最小值和最大值。
     *
     * @param data 数据样本
     * @return 归一化后的数据样本
     */
    public static List<Double> normalizationForMinToMax(List<Double> data) {
        List<Double> result = new ArrayList<>();
        //求取样本数据中的最大值与最小值
        double max = Double.MIN_VALUE;
        double min = Double.MAX_VALUE;
        for (Double item : data) {
            if (item > max) max = item;
            if (item < min) min = item;
        }
        //计算归一化后的数据
        double dis = max - min;
        for (Double item : data) {
            double num = (item - min) / dis;
            result.add(num);
        }
        return result;
    }

    /**
     * min-max normalization(Rescaling)
     * 归一化公式:x'=(x-min)/(max-min)
     * 归一化后的数据范围为 [0, 1],其中min 、max 分别求样本数据的最小值和最大值。
     *
     * @param data 数据样本
     * @return 归一化后的数据样本
     */
    public static double[] normalizationForMinToMax(double[] data) {
        double[] result = new double[data.length];

        //求取样本数据中的最大值与最小值
        double max = Double.MIN_VALUE;
        double min = Double.MAX_VALUE;
        for (Double item : data) {
            if (item > max) max = item;
            if (item < min) min = item;
        }
        //计算归一化后的数据
        double dis = max - min;
        for (int i = 0; i < data.length; i++) {
            result[i] = (data[i] - min) / dis;
        }

        return result;
    }

    /**
     * mean normalization
     * 归一化公式:x'=(x-mean)/(max-min)
     * 归一化后的数据范围为 [-1, 1],其中mean为样本数据的平均值,min 、max 分别求样本数据的最小值和最大值
     *
     * @param data 数据样本
     * @return 归一化后的数据样本
     */
    public static List<Double> normalizationForMean(List<Double> data) {
        List<Double> result = new ArrayList<>();
        //求取样本数据中的最大值与最小值、平均值
        double max = Double.MIN_VALUE;
        double min = Double.MAX_VALUE;
        double mean = 0;
        for (Double item : data) {
            if (item > max) max = item;
            if (item < min) min = item;
            mean += item;
        }
        mean = mean / data.size();

        //计算归一化后的数据
        double dis = max - min;
        for (Double item : data) {
            double num = (item - mean) / dis;
            result.add(num);
        }
        return result;
    }

    /**
     * mean normalization
     * 归一化公式:x'=(x-mean)/(max-min)
     * 归一化后的数据范围为 [-1, 1],其中mean为样本数据的平均值,min 、max 分别求样本数据的最小值和最大值
     *
     * @param data 数据样本
     * @return 归一化后的数据样本
     */
    public static double[] normalizationForMean(double[] data) {
        double[] result = new double[data.length];
        //求取样本数据中的最大值与最小值、平均值
        double max = Double.MIN_VALUE;
        double min = Double.MAX_VALUE;
        double mean = 0;
        for (Double item : data) {
            if (item > max) max = item;
            if (item < min) min = item;
            mean += item;
        }
        mean = mean / data.length;

        //计算归一化后的数据
        double dis = max - min;
        for (int i = 0; i < data.length; i++) {
            result[i] = (data[i] - mean) / dis;
        }
        return result;
    }

    /**
     * Z-score normalization (Standardization)
     * 归一化公式:x'=(x-mean)/σ
     * 归一化后的数据范围为实数集,其中μ、σ 分别为样本数据的均值和标准差
     *
     * @param data 数据样本
     * @return 归一化后的数据样本
     */
    public static List<Double> normalizationForZScore(List<Double> data) {
        List<Double> result = new ArrayList<>();
        //求取样本数据中的平均值
        double mean = 0;
        for (Double item : data) {
            mean += item;
        }
        mean = mean / data.size();

        //计算方差
        double variance = 0;
        for (Double item : data) {
            variance += (item - mean) * (item - mean);
        }
        variance = variance / data.size();
        //计算标准差
        double standardDeviation = Math.sqrt(variance);

        //计算归一化后的数据
        for (Double item : data) {
            double num = (item - mean) / standardDeviation;
            result.add(num);
        }
        return result;
    }

    /**
     * Z-score normalization (Standardization)
     * 归一化公式:x'=(x-mean)/σ
     * 归一化后的数据范围为实数集,其中μ、σ 分别为样本数据的均值和标准差
     *
     * @param data 数据样本
     * @return 归一化后的数据样本
     */
    public static double[] normalizationForZScore(double[] data) {
        double[] result = new double[data.length];
        //求取样本数据中的平均值
        double mean = 0;
        for (Double item : data) {
            mean += item;
        }
        mean = mean / data.length;

        //计算方差
        double variance = 0;
        for (Double item : data) {
            variance += (item - mean) * (item - mean);
        }
        variance = variance / data.length;
        //计算标准差
        double standardDeviation = Math.sqrt(variance);

        //计算归一化后的数据
        for (int i = 0; i < data.length; i++) {
            result[i] = (data[i] - mean) / standardDeviation;
        }
        return result;
    }

    /**
     * 对数归一化
     * 归一化公式:x'=ln(x)/ln(max)
     * 其中,max为数据样本的最大值
     *
     * @param data 数据样本
     * @return 归一化后的数据样本
     */
    public static List<Double> normalizationForlg(List<Double> data) {
        List<Double> result = new ArrayList<>();
        //求取样本数据中的最大值
        double max = Double.MIN_VALUE;
        for (Double item : data) {
            if (item > max) max = item;
        }
        //计算归一化后的数据
        for (Double item : data) {
            double num = Math.log10(item) / Math.log10(max);
            result.add(num);
        }
        return result;
    }

    /**
     * 对数归一化
     * 归一化公式:x'=ln(x)/ln(max)
     * 其中,max为数据样本的最大值
     *
     * @param data 数据样本
     * @return 归一化后的数据样本
     */
    public static double[] normalizationForlg(double[] data) {
        double[] result = new double[data.length];
        //求取样本数据中的最大值
        double max = Double.MIN_VALUE;
        for (Double item : data) {
            if (item > max) max = item;
        }
        //计算归一化后的数据
        for (int i = 0; i < data.length; i++) {
            result[i] = Math.log10(data[i]) / Math.log10(max);

        }
        return result;
    }

    /**
     * 反正切函数归一化
     * 归一化公式:x'=arctan(x)*(2/PI)
     * 归一化后的数据范围为 [-1, 1],PI表示圆周率Π
     *
     * @param data 数据样本
     * @return 归一化后的数据样本
     */
    public static List<Double> normalizationForArctan(List<Double> data) {
        List<Double> result = new ArrayList<>();
        //计算归一化后的数据
        for (Double item : data) {
            double num = Math.atan(item) * (2 / Math.PI);
            result.add(num);
        }
        return result;
    }


    /**
     * 反正切函数归一化
     * 归一化公式:x'=arctan(x)*(2/PI)
     * 归一化后的数据范围为 [-1, 1],PI表示圆周率Π
     *
     * @param data 数据样本
     * @return 归一化后的数据样本
     */
    public static double[] normalizationForArctan(double[] data) {
        double[] result = new double[data.length];
        //计算归一化后的数据
        for (int i = 0; i < data.length; i++) {
            result[i] = Math.atan(data[i]) * (2 / Math.PI);
        }
        return result;
    }


}

<think>好的,用户现在想了解如何对天线数据集进行归一化标准化处理,以便转换为适合训练的CSV格式。我需要结合之前的对话内容来给出合适的回答。首先,回顾一下用户之前的问题,他们需要将天线数据的前四列作为结构参数,后200列为不同频点的S11值,转换为CSV格式。现在用户进一步询问数据预处理中的归一化标准化步骤。 首先,我需要确定用户的数据结构。之前的回答中提到前四列是结构参数(比如L, W, H, d),后面的列是S11参数值。现在用户需要进行归一化标准化处理,可能需要区分对待结构参数和S11值,因为它们的量纲可能不同。例如,结构参数可能是毫米或厘米,而S11是分贝或其他单位。所以,可能需要不同的处理方式。 接下来,用户需要了解归一化标准化的区别。归一化通常指将数据缩放到[0,1]区间,而标准化则是将数据调整为均值为0,标准差为1。这两种方法的应用场景不同,归一化对异常值敏感,标准化更适合大多数机器学习算法,尤其是涉及距离计算的模型。 然后,我需要考虑如何在实际操作中应用这些方法。使用Python的pandas和scikit-learn库是比较常见的做法。可能需要分别对结构参数和S11参数进行处理,或者统一处理所有特征。需要给出代码示例,比如使用MinMaxScaler和StandardScaler,并解释每个步骤的作用。 另外,用户可能想知道在什么时候进行这些预处理步骤。是在数据合并到CSV之前还是之后?根据之前的回答,数据转换是在合并到CSV时进行的,所以预处理应该在合并后的数据集上进行。但如果是多个文件合并,可能需要先合并再处理,或者逐个处理后再合并。需要明确步骤顺序。 还需要注意,归一化标准化后的数据需要保存到CSV中,以便后续训练使用。要提醒用户保存时不要包含索引,并验证处理后的数据范围是否符合预期,比如归一化后的数据是否在0-1之间,标准化后的均值和标准差是否正确。 可能用户还会关心是否需要区分训练集和测试集,在预处理时是否需要分开处理。但根据当前问题,用户可能只是需要整体的处理步骤,所以暂时可以假设整个数据集的处理,后续再考虑训练测试分割时的注意事项。 最后,根据用户之前的引用,比如引用[2]中提到线性方法的局限性,可能需要提到数据预处理如何帮助模型更好地捕捉非线性结构,但这点可能稍微超出当前问题的范围,可以简要提及或留到相关问题中。 总结步骤应该是:加载数据,区分结构参数和S11参数,选择归一化标准化的方法,应用处理,合并数据,保存为CSV。同时需要给出代码示例,并解释关键点,如列的选择、处理顺序、验证方法等。</think>以下是对天线数据集进行归一化/标准化处理的完整解决方案,结合工程实践和机器学习预处理要求: ### 一、数据处理流程设计 1. **参数类型区分处理** - 结构参数(前4列):建议采用标准化(Z-score),消除不同物理量纲的影响 $$ x' = \frac{x - \mu}{\sigma} $$ - S11参数(后200列):推荐Min-Max归一化,保留频响曲线形态特征 $$ x_{norm} = \frac{x - x_{min}}{x_{max} - x_{min}} $$ 2. **处理顺序**(基于前次转换结果) 原始数据 → 格式转换(上次处理) → 特征工程 → 归一化 → 训练用CSV[^1] ### 二、Python实现代码 ```python import pandas as pd from sklearn.preprocessing import StandardScaler, MinMaxScaler # 读取已转换的CSV df = pd.read_csv('antenna_dataset.csv') # 分离特征类型 structural_params = df.iloc[:, :4] # 前4列结构参数 s11_features = df.iloc[:, 4:] # 后200列S11参数 # 创建预处理管道 structural_scaler = StandardScaler() s11_scaler = MinMaxScaler(feature_range=(0, 1)) # 执行预处理 structural_processed = structural_scaler.fit_transform(structural_params) s11_processed = s11_scaler.fit_transform(s11_features) # 合并数据集 processed_data = pd.DataFrame( data=np.hstack([structural_processed, s11_processed]), columns=df.columns ) # 保存处理结果(添加预处理标记) processed_data.to_csv('antenna_dataset_normalized.csv', index=False) ``` ### 三、关键参数验证 1. **标准化验证** ```python assert np.allclose(structural_processed.mean(axis=0), 0, atol=1e-5) assert np.allclose(structural_processed.std(axis=0), 1, atol=1e-5) ``` 2. **归一化验证** ```python print(f"S11值域验证: Min={s11_processed.min():.2f}, Max={s11_processed.max():.2f}") # 应输出: Min=0.00, Max=1.00 ``` ### 四、工程实践建议 1. **参数保存** - 将scaler对象通过joblib保存,确保推理阶段使用相同参数 ```python from joblib import dump dump(structural_scaler, 'structural_scaler.joblib') dump(s11_scaler, 's11_scaler.joblib') ``` 2. **混合处理方法** 当存在多个物理量纲时,可对每个结构参数单独标准化: ```python for param in ['L', 'W', 'H', 'd']: scaler = StandardScaler() df[param] = scaler.fit_transform(df[[param]]) ``` ### 五、可视化验证(可选) 绘制处理前后参数分布对比: ```python import matplotlib.pyplot as plt plt.figure(figsize=(10,4)) plt.subplot(121) plt.hist(structural_params['L'], bins=30) plt.title('原始结构参数分布') plt.subplot(122) plt.hist(structural_processed[:,0], bins=30) plt.title('标准化后分布') plt.show() ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值