データを0-1の範囲に正規化する方法は?


266

私はノーマライズに迷っています。誰でも私を案内してくれますか。

最小値と最大値、それぞれ-23.89と7.54990767があります。

5.6878の値を取得した場合、この値を0から1のスケールでスケーリングするにはどうすればよいですか。


8
=(value-min)/(max-min)
アンジェロ

3
このスレッドを読むのに役立つかもしれません:how-to-verify-a-distribution-is-normalized。それが質問に答えたら、このQを削除できます。そうでない場合は、Qを編集して、まだ理解していないものを指定します。
グン

1
保護の説明:この質問は、コードソリューションのみを含む追加の回答を集めています。一部の読者にとっては、これらは興味深いか有用かもしれませんが、コードソリューションのリポジトリを提供することはCVの目的ではありません。
ニックコックス

1
提供されるソリューションは線形コントラスト値を考慮します。たとえば、出力の均一な確率を達成するなど、別の正規化を希望しますか?
-meduz

回答:


299

データを正規化する場合は、提案どおりに正規化して、以下を計算できます。

z=バツバツ最大バツバツ

ここで、およびは正規化されたデータになります。コンセプトの証明として(要求はしませんでしたが)、この点を説明するためのコードとグラフを以下に示します。バツ=バツ1バツnzthR

ここに画像の説明を入力してください

# Example Data
x = sample(-100:100, 50)

#Normalized Data
normalized = (x-min(x))/(max(x)-min(x))

# Histogram of example data and normalized data
par(mfrow=c(1,2))
hist(x,          breaks=10, xlab="Data",            col="lightblue", main="")
hist(normalized, breaks=10, xlab="Normalized Data", col="lightblue", main="")

11
2つのまったく異なる外観のヒストグラムがillustrate the point(正しい)答えをどのように処理するのか疑問に思うだけです。
ttnphns

12
@ttnphnsヒストグラムのビニングにより、外観が異なるだけです。しかし、私のポイントは、元の値が-100から100の間であり、正規化後は0から1の間であるということを示すことでした。

20
@ttnphnsの穏やかなナッジは、(単純な)アイデアを説明するためにそれほど複雑でない手段を使用するだけでなく、より直接関連するイラストがここで有益であるかもしれないというヒントとして(私は疑います)OPによって実際に提供される最小値と最大値に適用される変換をグラフ化するより簡単な方法を見つけることで、両方を行うことができます
whuber

1
0-1ではなくカスタム範囲に「正規化」する方法はありますか?
ジョンDemetriou

1
@JohnDemetriouは最もクリーンなソリューションではないかもしれませんが、それを行うために正規化された値をスケーリングできます。たとえば、0-100の範囲が必要な場合は、各数値に100を掛けます。10-100など、0で始まらない範囲が必要な場合は、MAX-MINでスケーリングしてからMINを追加するだけで得られる値。したがって、90でスケーリングし、10を追加します。これで、ほとんどのカスタム範囲に十分なはずです。
アレクサンダーロッサ

47

観測されたminmaxを新しい任意の範囲min 'からmax'に線形的に再スケーリングする一般的な1行の式は次のとおりです。

  newvalue= (max'-min')/(max-min)*(value-max)+max'
  or
  newvalue= (max'-min')/(max-min)*(value-min)+min'.

9
これは正しいですが、効率的ではありません。これは線形変換であるため、事前に計算aしてb定数を適用し、次に適用するだけnewvalue = a * value + bです。 a = (max'-min')/(max-min)およびb = max - a * max
マークラカタ

1
これを引用する方法を知っていますか?どこかに「オリジナル」の参照がありますか?
Trefex

3
@MarkLakataわずか(?タイプミス)訂正:b = max' - a * maxまたはb = min' - (a * min)
ニック・

@Nick-はい。'が欠けています
マークラカタ14

あなたの正規化を比較してくださいすることができ、ここでse.mathworks.com/matlabcentral/answers/...は方程式、すなわちu = -1 + 2.*(u - min(u))./(max(u) - min(u));
レオレオポルドヘルツ

13

正規化のためのPHP実装は次のとおりです。

function normalize($value, $min, $max) {
	$normalized = ($value - $min) / ($max - $min);
	return $normalized;
}

しかし、独自の人工ニューラルネットワークを構築している間に、グラフの読みやすい出力を得るために、正規化された出力を元のデータに変換する必要がありました。

function denormalize($normalized, $min, $max) {
	$denormalized = ($normalized * ($max - $min) + $min);
	return $denormalized;
}

$int = 12;
$max = 20;
$min = 10;

$normalized = normalize($int, $min, $max); // 0.2
$denormalized = denormalize($normalized, $min, $max); //12

非正規化は次の式を使用します。

x(maxmin)+


2
この答えとすでに受け入れられている答えには重要な違いがあります。それは主要なアイデアを明確かつ直接的に説明し、次に一般的に使用されるプログラムでそれを行う方法を二次的に示しました。逆に、ここにコードのみを投稿します。このフォーラムではこれが良いコード(PHPを書いていない)であると信じて満足していますが、通常、考えられるすべての言語でそれを行う方法を説明するすべての質問に対する回答の束はありません。それ以外の場合、SAS、SPSS、Stata、MATLAB、C、C ++、C#、Javaで回答があります。Pythonなど
ニックコックス

2
これが唯一の違いだとは思いません。私のコードでは、正規化された値を正規化前の値に戻す方法も示しました。それはこの答えの価値があると思う。
ジャンカル

1
あなたがコードだけを投稿することはまだ真実です:そうでなければ読者はコードを読んでそれらが何であるかを見る必要があるので、コメントのコードのおそらく特別な美徳を強調する必要があると思います。おそらく、スケーリングの反転は、(a)元の値が上書きされたが、(b)ユーザーが最小値と最大値を保存することを慎重に覚えている場合にのみ有用です。上記でコメントしたように、私のより広いポイントは、CVがコード例のリポジトリになることを目的としていないということです。
ニックコックス

値を復元する必要がある場合、いくつかの問題があります。たとえば、Nueral Networks ...しかし、データ分析の方法では、この答えは非常に悪いです。
ジャンカル

3
@NickCox私は彼の答えが受け入れられたものよりも満足のいくものであることがわかりました。
カールモリソン

4

ゼロ除算

心に留めておくべきことの1つは、max - minゼロに等しいことです。この場合、その除算を実行したくないでしょう。

これが発生するのは、正規化しようとしているリスト内のすべての値が同じ場合です。このようなリストを正規化するには、各アイテムはになります1 / length

// JavaScript
function normalize(list) {
   var minMax = list.reduce((acc, value) => {
      if (value < acc.min) {
         acc.min = value;
      }

      if (value > acc.max) {
         acc.max = value;
      }

      return acc;
   }, {min: Number.POSITIVE_INFINITY, max: Number.NEGATIVE_INFINITY});

   return list.map(value => {
      // Verify that you're not about to divide by zero
      if (minMax.max === minMax.min) {
         return 1 / list.length
      }

      var diff = minMax.max - minMax.min;
      return (value - minMax.min) / diff;
   });
}

例:

normalize([3, 3, 3, 3]); // output => [0.25, 0.25, 0.25, 0.25]

これは、範囲0〜1ではなく、合計1に再スケーリングされます。したがって、答えはトピックから外れていると思います。
ttnphns

そうではありません。normalize([12, 20, 10])出力[0.2, 1.0, 0.0]。これは、と同じです(val - min) / (max - min)
ロドリゴシルベイラ

@ rodrigo-silveiraなぜすべて0.25が出力されるのかわかりません。0.5のほうがいいのではないでしょうか?すべてのアイテムは等しいため、間隔の中央に配置する必要があります。
javierdvalle

0

答えは正しいですが、提案があります。あなたのトレーニングデータが範囲外の数に直面したらどうなりますか?スカッシュテクニックを使用できます。決して範囲外に出ないことが保証されます。これよりも

ここに画像の説明を入力してください

これを使うことをお勧めします

ここに画像の説明を入力してください

範囲の最小値と最大値でこのようなつぶしで

ここに画像の説明を入力してください

予想される範囲外のギャップのサイズは、範囲外の値が存在するという信頼度に直接比例します。

詳細については、グーグルで検索できます。範囲外の番号を削除し、「ドリアンパイル」のデータ準備書を参照してください


5
従来どおり大文字を使用するように回答を編集してください。一貫した小文字はおもしろいまたは効率的に見えるかもしれませんが、ほとんどの人が読むのはより困難です。
ニックコックス

3
イラストはあなたの答えを適切に伝えていません。「押しつぶすテクニック」とは正確には何ですか?
whuber

0

これを試して。機能スケールと一致しています

normalize <- function(x) { 
  x <- as.matrix(x)
  minAttr=apply(x, 2, min)
  maxAttr=apply(x, 2, max)
  x <- sweep(x, 2, minAttr, FUN="-") 
  x=sweep(x, 2,  maxAttr-minAttr, "/") 
  attr(x, 'normalized:min') = minAttr
  attr(x, 'normalized:max') = maxAttr
  return (x)
} 

7
この答えとすでに受け入れられている答えには重要な違いがあります。それは主要なアイデアを明確かつ直接的に説明し、次に一般的に使用されるプログラムでそれを行う方法を二次的に示しました。逆に、ここにコードのみを投稿します。このフォーラムでは、これが(説明のつかない言語での)良いコードであると信じていますが、通常、考えられるすべての言語でそれを行う方法を説明するすべての質問に対する回答の束はありません。それ以外の場合、SAS、SPSS、Stata、MATLAB、C、C ++、C#、Javaで回答があります。Pythonなど
ニックコックス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.