วิธีการทำให้ข้อมูลกลับสู่ช่วง 0-1 เป็นปกติ


265

ฉันหลงทางในการทำให้ปกติ

ฉันมีค่าต่ำสุดและค่าสูงสุดคือ -23.89 และ 7.54990767 ตามลำดับ

หากฉันได้รับค่า 5.6878 ฉันจะขยายมูลค่านี้เป็นระดับ 0 ถึง 1 ได้อย่างไร


8
นี่คือวิธี = (ค่า - นาที) / (สูงสุด - นาที)
Angelo

3
มันอาจช่วยให้คุณสามารถอ่านกระทู้นี้: วิธีที่จะตรวจสอบ-a-กระจายเป็น-ปกติ หากตอบคำถามของคุณคุณสามารถลบคำถามนี้ได้ ถ้าไม่แก้ไข Q ของคุณเพื่อระบุสิ่งที่คุณยังไม่เข้าใจ
gung

1
คำอธิบายของการป้องกัน: คำถามนี้ดึงดูดคำตอบเพิ่มเติมที่มีโซลูชันรหัสเท่านั้น ในขณะที่สิ่งเหล่านี้อาจน่าสนใจหรือเป็นประโยชน์สำหรับผู้อ่านบางคนมันไม่ได้เป็นจุดมุ่งหมายของ CV เพื่อให้บริการที่เก็บของการแก้ปัญหารหัส
Nick Cox

1
วิธีแก้ปัญหาที่ให้มาพิจารณาค่าคอนทราสต์แบบเส้นตรง - คุณต้องการการทำให้เป็นมาตรฐานที่แตกต่างกันตัวอย่างเช่นค่าที่ให้ความน่าจะเป็นแบบเดียวกันสำหรับเอาต์พุตหรือไม่?
meduz

คำตอบ:


299

หากคุณต้องการทำให้ข้อมูลของคุณเป็นปกติคุณสามารถทำได้ตามที่คุณแนะนำและเพียงคำนวณสิ่งต่อไปนี้

Zผม=xผม-นาที(x)สูงสุด(x)-นาที(x)

โดยที่และเป็นข้อมูลปกติของคุณแล้วเป็นหลักฐานของแนวคิด (แม้ว่าคุณไม่ได้ขอ) นี่คือรหัสและกราฟประกอบเพื่อแสดงจุดนี้:x=(x1,...,xn)Zผมผมเสื้อชั่วโมงR

ป้อนคำอธิบายรูปภาพที่นี่

# 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
ฉันแค่สงสัยว่าฮิสโทแกรมที่ดูแตกต่างกันสองอย่างนั้นจะillustrate the pointตอบคำถามของคุณได้อย่างไร?
ttnphns

12
@ttnphns พวกเขาดูแตกต่างกันเพียงเล็กน้อยเนื่องจากฮิสโทแกรม จุดของฉันคือการแสดงให้เห็นว่าค่าเดิมอยู่ระหว่าง -100 ถึง 100 และตอนนี้หลังจาก normalization พวกเขาอยู่ระหว่าง 0 และ 1 ฉันสามารถใช้กราฟที่แตกต่างกันเพื่อแสดงสิ่งนี้ฉันคิดหรือเพียงแค่สรุปสถิติ

20
การเขยิบอย่างอ่อนโยนโดย @ttnphns นั้นหมายถึงการสนับสนุนให้คุณไม่เพียง แต่จะใช้วิธีการที่ซับซ้อนน้อยกว่าในการแสดงความคิด (ง่าย) แต่ยัง (ฉันสงสัยว่า) เป็นคำใบ้ว่าภาพประกอบที่เกี่ยวข้องโดยตรงอาจเป็นประโยชน์ต่อที่นี่ คุณสามารถทำได้ทั้งสองวิธีโดยการหาวิธีที่ง่ายกว่าในการทำกราฟการเปลี่ยนแปลงเมื่อมันถูกนำไปใช้กับ min และ max ที่ให้มาจริงโดย OP
whuber

1
มีวิธี "ปรับปกติ" เป็นช่วงที่กำหนดเองแทนที่จะเป็น 0-1 หรือไม่
John Demetriou

1
@JohnDemetriou อาจไม่ใช่วิธีที่สะอาดที่สุด แต่คุณสามารถปรับขนาดค่าปกติให้เป็นแบบนั้นได้ หากคุณต้องการตัวอย่างเช่นช่วง 0-100 คุณเพียงแค่คูณแต่ละจำนวนด้วย 100 ถ้าคุณต้องการช่วงที่ไม่ได้ขึ้นต้นด้วย 0 เช่น 10-100 คุณจะทำได้โดยการขยายด้วย MAX-MIN จากนั้นถึง ค่าที่คุณได้รับจากการเพิ่ม MIN ดังนั้นปรับขนาด 90 แล้วเพิ่ม 10 นั่นควรจะเพียงพอสำหรับช่วงที่กำหนดเองส่วนใหญ่ที่คุณอาจต้องการ
Alexander Rossa

47

สูตรหนึ่งบรรทัดทั่วไปเพื่อปรับลดค่าข้อมูลเชิงเส้นโดยสังเกตminและmaxเป็นช่วงใหม่โดยพลการmin 'ถึงmax'คือ

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

9
สิ่งนี้ถูกต้อง แต่ไม่มีประสิทธิภาพ มันเป็นแปลงเชิงเส้นดังนั้นคุณจะ precalculate aและค่าคงที่แล้วเพียงแค่ใช้ b และnewvalue = a * value + ba = (max'-min')/(max-min)b = max - a * max
ทำเครื่องหมาย Lakata

1
คุณรู้วิธีการอ้างอิงนี้หรือไม่? ฉันหมายถึงมีการอ้างอิง "ต้นฉบับ" ที่อื่นหรือไม่
Trefex

3
@MarkLakata Slight (การพิมพ์ผิด) ได้รับการแก้ไข: b = max' - a * maxหรือb = min' - (a * min)
Nick

@Nick - ใช่ ฉันไม่มี '
Mark Lakata

คุณสามารถโปรดเปรียบเทียบการฟื้นฟูของคุณที่นี่se.mathworks.com/matlabcentral/answers/...u = -1 + 2.*(u - min(u))./(max(u) - min(u));คือสมการ
LéoLéopold Hertz

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

Denormalisation ใช้สูตรต่อไปนี้:

x(maxmin)+min


2
มีความแตกต่างที่สำคัญระหว่างคำตอบนี้และคำตอบที่ยอมรับแล้ว นั่นอธิบายแนวคิดหลักอย่างชัดเจนและโดยตรงจากนั้นแสดงวิธีที่สองในโปรแกรมที่ใช้กันทั่วไป ในทางกลับกันคุณโพสต์โค้ดที่นี่เท่านั้น ในขณะที่ฉันมีความสุขที่จะเชื่อว่านี่เป็นรหัสที่ดี (ฉันไม่ได้เขียน PHP) ในฟอรัมนี้โดยปกติเราไม่มีกลุ่มคำตอบสำหรับคำถามทุกข้อที่อธิบายวิธีทำในภาษาที่เข้าใจได้ทั้งหมด มิฉะนั้นเราจะมีคำตอบที่นี่ใน SAS, SPSS, Stata, MATLAB, C, C ++, C #, Java Python ฯลฯ ฯลฯ
Nick Cox

2
ฉันไม่คิดว่านี่เป็นความแตกต่างเท่านั้น ในรหัสของฉันฉันยังแสดงให้เห็นว่าวิธีการคืนค่ามาตรฐานให้เป็นค่าก่อนการฟื้นฟู ฉันคิดว่ามันคุ้มค่ากับคำตอบนี้
jankal

1
มันยังคงเป็นความจริงที่คุณโพสต์รหัสเท่านั้น: ฉันคิดว่าคุณต้องเน้นย้ำถึงคุณธรรมพิเศษของรหัสในความเห็นมิฉะนั้นผู้อ่านจะต้องอ่านรหัสเพื่อดูว่าพวกเขาเป็นอย่างไร การสันนิษฐานว่าการปรับสเกลนั้นใช้เฉพาะเมื่อ (ก) ค่าดั้งเดิมถูกเขียนทับ แต่ (b) ผู้ใช้มีการจดจำอย่างรอบคอบเพื่อบันทึกขั้นต่ำและสูงสุด จุดที่กว้างขึ้นของฉันดังที่ได้กล่าวไว้ข้างต้นคือ CV ไม่ได้มีวัตถุประสงค์เพื่อเป็นที่เก็บตัวอย่างรหัส
Nick Cox

มีปัญหาบางอย่างที่คุณต้องการคืนค่า: เครือข่าย Nueral เช่น ... แต่คุณถูกต้องในลักษณะของการวิเคราะห์ข้อมูลคำตอบนี้แย่มาก
jankal

3
@ NickCox ฉันพบว่าคำตอบของเขาน่าพอใจมากกว่าคำตอบที่ยอมรับ
Karl Morrison

4

การหารด้วยศูนย์

สิ่งหนึ่งที่ต้องจำไว้คือมัน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]

นี่เป็นการลดขนาดให้กับผลรวม 1 ไม่ใช่เป็นช่วง 0-1 ฉันแค่คิดว่าคำตอบคือนอกหัวข้อดังนั้น
ttnphns

ไม่เช่นนั้น normalize([12, 20, 10])เอาท์พุทซึ่งเป็นที่เดียวกับที่คุณจะได้รับด้วย[0.2, 1.0, 0.0] (val - min) / (max - min)
rodrigo-silveira

@ rodrigo-silveira ฉันไม่เห็นว่าทำไมผลผลิตทั้งหมด 0.25 มันจะดีกว่าหรือไม่ 0.5 ทั้งหมด? รายการทั้งหมดมีค่าเท่ากันดังนั้นควรเก็บกึ่งกลางในช่วงเวลา
javierdvalle

0

คำตอบนั้นถูกต้อง แต่ฉันมีข้อเสนอแนะจะเกิดอะไรขึ้นถ้าข้อมูลการฝึกอบรมของคุณต้องเผชิญกับตัวเลขจำนวนหนึ่ง? คุณสามารถใช้เทคนิคการบีบ จะรับประกันว่าจะไม่ออกนอกช่วง มากกว่านี้

ป้อนคำอธิบายรูปภาพที่นี่

ฉันแนะนำให้ใช้สิ่งนี้

ป้อนคำอธิบายรูปภาพที่นี่

ด้วยการบีบแบบนี้ในหน่วยนาทีและช่วงสูงสุด

ป้อนคำอธิบายรูปภาพที่นี่

และขนาดของช่องว่างนอกช่วงที่คาดว่าจะเป็นสัดส่วนโดยตรงกับระดับของความเชื่อมั่นว่าจะมีค่านอกช่วง

สำหรับข้อมูลเพิ่มเติมคุณสามารถ google: squashing หมายเลข out-of-range และอ้างถึงหนังสือเตรียมข้อมูลของ "dorian pyle"


5
โปรดแก้ไขคำตอบของคุณเพื่อใช้ตัวพิมพ์ใหญ่เป็นแบบธรรมดา ตัวพิมพ์เล็กที่สอดคล้องกันอาจดูน่าขบขันหรือมีประสิทธิภาพ แต่ก็เป็นเรื่องยากสำหรับเกือบทุกคนที่จะอ่าน
Nick Cox

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 ฯลฯ ฯลฯ
Nick Cox
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.