【问题标题】:Normalization to bring in the range of [0,1]归一化以引入 [0,1] 的范围
【发布时间】:2013-08-22 12:27:37
【问题描述】:

我有一个庞大的数据集,从中我导出了两组数据点,然后我必须对它们进行绘图和比较。这两个图的范围不同,所以我希望它们在[0,1] 的范围内。对于以下代码和特定数据集,我在 1 处得到一条恒定线作为数据集图,但这种归一化适用于其他数据集:

plt.plot(range(len(rvalue)),np.array(rvalue)/(max(rvalue)))

对于这段代码:

oldrange = max(rvalue) - min(rvalue)  # NORMALIZING
newmin = 0
newrange = 1 + 0.9999999999 - newmin
normal = map(
    lambda x, r=float(rvalue[-1] - rvalue[0]): ((x - rvalue[0]) / r)*1 - 0, 
    rvalue)
plt.plot(range(len(rvalue)), normal)

我得到错误:

ZeroDivisionError: float division by zero

对于所有数据集。我无法弄清楚如何将两个图都放在一个范围内进行比较。

【问题讨论】:

标签: python


【解决方案1】:

scikit_learn 有这个功能
sklearn.preprocessing.minmax_scale(X, feature_range=(0, 1), axis=0, copy=True)

比使用 MinMaxScale 类更方便。

https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.minmax_scale.html#sklearn.preprocessing.minmax_scale

【讨论】:

  • 什么是sklearn?如果用户必须要求澄清,答案通常不太被接受。我建议在您的答案中添加更多解释,以免将其标记为低质量。
【解决方案2】:

使用以下方法,使用数据序列中的最小值和最大值对 0 到 1 范围内的数据进行归一化:

import numpy as np

def NormalizeData(data):
    return (data - np.min(data)) / (np.max(data) - np.min(data))

【讨论】:

  • 目前尚不清楚这会增加其他答案或解决问题。
  • 我给了我nan值
  • @AdityaLandge 在以下情况下您可能会得到 nan 值:1)数据中的任何元素都是 nan,或 2)max 等于 min,导致除以零错误
【解决方案3】:

使用 scikit: http://scikit-learn.org/stable/modules/preprocessing.html#scaling-features-to-a-range

它具有将特征缩放到指定范围的内置功能。您可以在此处找到其他要规范化和标准化的函数。

看这个例子:

>>> import numpy as np
>>> from sklearn import preprocessing
>>> X_train = np.array([[ 1., -1.,  2.],
...                     [ 2.,  0.,  0.],
...                     [ 0.,  1., -1.]])
...
>>> min_max_scaler = preprocessing.MinMaxScaler()
>>> X_train_minmax = min_max_scaler.fit_transform(X_train)
>>> X_train_minmax
array([[ 0.5       ,  0.        ,  1.        ],
       [ 1.        ,  0.5       ,  0.33333333],
       [ 0.        ,  1.        ,  0.        ]])

【讨论】:

    【解决方案4】:

    只是为其他答案提供一些背景,这里是一个推导:

    通过点(x1, y1)和(x2, y2)的直线可以表示为:

    y = y1 + slope * (x - x1)
    

    在哪里

    slope = (y2 - y1) / (x2 - x1)
    

    现在,从 0 到 1 的标准化意味着

    y1 = 0, y2 = 1
    

    和

    x1 = x_min, x2 = x_max
    

    (反之亦然,取决于您的需要)

    然后等式简化为

    y = (x - x_min) / (x_max - x_min)
    

    【讨论】:

      【解决方案5】:

      我试图简化一些事情。试试这个:

      oldmin = min(rvalue)
      oldmax = max(rvalue)
      oldrange = oldmax - oldmin
      newmin = 0.
      newmax = 1.
      newrange = newmax - newmin
      if oldrange == 0:            # Deal with the case where rvalue is constant:
          if oldmin < newmin:      # If rvalue < newmin, set all rvalue values to newmin
              newval = newmin
          elif oldmin > newmax:    # If rvalue > newmax, set all rvalue values to newmax
              newval = newmax
          else:                    # If newmin <= rvalue <= newmax, keep rvalue the same
              newval = oldmin
          normal = [newval for v in rvalue]
      else:
          scale = newrange / oldrange
          normal = [(v - oldmin) * scale + newmin for v in rvalue]
      
      plt.plot(range(len(rvalue)),normal)
      

      我能看到ZeroDivisionError 的唯一原因是右值中的数据是否恒定(所有值都相同)。是这样吗?

      【讨论】:

      • 是的,我看到在某些情况下,右值是恒定的,所以 oldrange = 0。我还发现,对于大多数数据集,我的 ravlue 图保持在 0,1 的范围内,所以我想不需要对这个图进行标准化,只是另一个需要标准化。但我想知道,为了让我的代码适用于所有类型的数据集(其中右值不在 [0,1] 范围内),有没有办法在不出错的情况下进行规范化?...
      • @user2690054:当然,你只需要决定行为应该是什么。例如,如果rvalue = [-20, -20, ... , -20],是否应该映射到[0.0, 0.0, ..., 0.0]? rvalue = [30, 30, ..., 30] 是否应该映射到 [1.0, 1.0, ..., 1.0]?
      • @user2690054 我添加了一些语句来处理 oldrange 为零 - 看看它是否符合您的要求。
      • 我认为修改应该足以满足我的要求,具体取决于我想要的行为。在其他部分 bcoz 中,它在该位置本身给出了 zerodivision 错误,并且不进入 if 子句。感谢您的帮助!
      【解决方案6】:

      查找数组的范围由numpy内置函数numpy.ptp()提供,您的问题可以通过以下方式解决:

      #First we should filter input_array so that it does not contain NaN or Inf.
      input_array=np.array(some_data)
      if np.unique(input_array).shape[0]==1:
          pass #do thing if the input_array is constant
      else:
          result_array=(input_array-np.min(input_array))/np.ptp(input_array)
      #To extend it to higher dimension, add axis= kwarvg to np.min and np.ptp
      

      【讨论】:

        【解决方案7】:

        将 0 到 1 之间的任何值标准化的简单方法是将所有值除以最大值,从所有值中得出。将带来介于 0 到 1 之间的值。

        【讨论】:

        • 这不会规范化 0 和 1 之间的“任何东西”。这只会规范化正值。
        【解决方案8】:

        您可以将样本中的每个数字除以样本中所有数字的总和。

        【讨论】:

          猜你喜欢
          • 2021-12-15
          • 1970-01-01
          • 2018-03-17
          • 2020-07-22
          • 2019-03-02
          • 2020-07-19
          • 2021-05-23
          • 2020-08-19
          • 2016-07-10
          相关资源
          最近更新 更多