利用字典对归一化后的数据0误差还原

发布于:2024-11-03 ⋅ 阅读:(130) ⋅ 点赞:(0)
  • 假设我对精度要求很高,高到无法容忍有任何误差,那么我先将x按照大小排序,然后归一化,用字典将归一化前后的x存储下来,在深度学习时使用归一化后的x进行处理,但是最后画图等处理时,我用字典取出归一化之前对应的值。

思路:x = [3, 4, 5, 1, 2, 3],先排序,然后用scaler = StandardScaler()
x_scaled = scaler.fit_transform(x.reshape(-1, 1))
这种方法归一化得到结果, 然后采用1个字典,能存储归一化之后的值:归一化之前的值,这种字典,以及归一化之前的值:归一化之后的值这种字典。

首先,将 x 数组排序并使用 StandardScaler 进行归一化。接着,创建两个字典:

  1. 归一化后的值:归一化之前的值scaled_to_original
  2. 归一化之前的值:归一化之后的值original_to_scaled

下面是实现的示例代码:

import numpy as np
from sklearn.preprocessing import StandardScaler

# 原始数据
x = np.array([3, 4, 5, 1, 2, 3])

# 排序数据
x_sorted = np.sort(x)

# 使用 StandardScaler 进行归一化
scaler = StandardScaler()
x_scaled = scaler.fit_transform(x_sorted.reshape(-1, 1)).flatten()

# 创建字典存储归一化值到原始值的映射
scaled_to_original = {scaled: original for scaled, original in zip(x_scaled, x_sorted)}

# 创建字典存储原始值到归一化值的映射
original_to_scaled = {original: scaled for original, scaled in zip(x_sorted, x_scaled)}

# 打印结果
print("归一化后的值:归一化之前的值 字典:", scaled_to_original)
print("归一化之前的值:归一化后的值 字典:", original_to_scaled)

# 示例:使用归一化值查找原始值
example_scaled_value = x_scaled[0]
example_original_value = scaled_to_original[example_scaled_value]
print(f"归一化值 {example_scaled_value} 对应的原始值: {example_original_value}")

# 示例:使用原始值查找归一化值
example_original_value = 3
example_scaled_value = original_to_scaled[example_original_value]
print(f"原始值 {example_original_value} 对应的归一化值: {example_scaled_value}")

代码说明

  1. 数据排序x_sorted = np.sort(x) 会将 x 中的元素排序。
  2. 归一化scaler.fit_transform() 方法对排序后的数据进行标准化,返回标准化后的结果。
  3. 字典生成
    • scaled_to_original 字典将归一化后的值作为键,原始值作为值。
    • original_to_scaled 字典将原始值作为键,归一化后的值作为值。

运行结果

当运行上述代码时,输出结果会显示两个字典的内容,并且可以通过这两个字典进行值的查找。

示例输出

输出结果:

归一化后的值:归一化之前的值 字典: {-1.5491933384829668: 1, -0.7745966692414834: 2, 0.0: 3, 0.7745966692414834: 4, 1.5491933384829668: 5}
归一化之前的值:归一化后的值 字典: {1: -1.5491933384829668, 2: -0.7745966692414834, 3: 0.0, 4: 0.7745966692414834, 5: 1.5491933384829668}
归一化值 -1.5491933384829668 对应的原始值: 1
原始值 3 对应的归一化值: 0.0

由于 3x 中出现了两次,因此在字典中将其映射到的归一化值是相同的。


  • 一个宽松的版本
  1. 使用插值方法:可以使用线性插值来获取最接近的原始值,而不是严格寻找对应的值。
  2. 确保预测值在范围内:确保生成的 predicted_normalized 值确实在归一化范围内。

以下是采用线性插值的实现方式:

示例代码

import numpy as np
from sklearn.preprocessing import MinMaxScaler
from scipy.interpolate import interp1d

# 生成数据
x = np.random.rand(100) * 100  # 生成100个随机数,范围在0到100之间

# 创建 MinMaxScaler 对象
scaler = MinMaxScaler()

# 对数据进行排序
x_sorted = np.sort(x)

# 归一化数据
x_normalized = scaler.fit_transform(x_sorted.reshape(-1, 1)).flatten()

# 创建字典存储原始值与归一化值的对应关系
value_map = {original: normalized for original, normalized in zip(x_sorted, x_normalized)}

# 深度学习模型处理(示例代码省略)

# 假设预测的归一化值为 predicted_normalized
predicted_normalized = np.random.rand(10)  # 示例:10个随机生成的归一化值

# 使用插值来反归一化
# 创建插值函数
interp_function = interp1d(x_normalized, x_sorted, bounds_error=False, fill_value="extrapolate")

# 获取对应的原始值
predicted_original = interp_function(predicted_normalized)

print("归一化后的预测值:", predicted_normalized)
print("对应的原始值:", predicted_original)

输出

归一化后的预测值: [0.01215447 0.96987883 0.04315991 0.89114311 0.52770111 0.9929648
 0.07379656 0.55385428 0.96930254 0.52309784]
对应的原始值: [ 2.27449952 96.09964077  5.31200141 88.38615894 52.78092728 98.36129815
  8.31337469 55.34306884 96.04318341 52.32996038]

说明

  • 插值函数interp1dscipy.interpolate 中导入,可以根据归一化值计算相应的原始值。通过设置 bounds_error=Falsefill_value="extrapolate",可以处理在 value_map.values() 中找不到的值(即插值和外推)。通过使用插值技术,可以避免在查找字典中直接索引可能不存在的归一化值,从而确保代码的健壮性和有效性。
  • 适用性:这种方法适用于在归一化数据中查找最接近的原始值,确保获得合理的输出,而不是直接找不到值时导致错误。

网站公告

今日签到

点亮在社区的每一天
去签到