본문 바로가기
R/RSTAT101

[RSTAT101] 9강. 잡음과 정규분포에 대하여

by 슬통이 2023. 6. 10.
반응형

잡음(white noise)

오늘은 잡음(noise)에 대하여 이야기를 꺼내볼까 합니다. 회귀분석을 모델링을 할 때, 우리는 암묵적으로 관측값에 잡음이 섞여 있다는 이야기를 하고 넘어갔습니다.

관측값에 잡음이 섞여 있다는 말이 무엇일까요? 우리가 관측하려고 하는 어떤 대상의 실제값을 가리는 다른 무언가가 존재한다는 말이겠죠. 다음 사진을 봅시다.

예쁜 건물 사진이네요. 이 사진에 잡음이 끼어있다면 어떨까요? 다음의 두 장의 사진을 한번 살펴 봅시다.

Image credit: vladimir yuzhikov

위의 두 사진 모두 원래의 집의 형태가 확실하게 보여지지 않고, 뭔가가 섞여있는 모습입니다. 하지만 두 장의 사진을 비교해보면, 잡음의 정도가 차이가 나는 것을 알 수 있죠. 왼쪽의 사진은 잡음이 섞여있지만 원래 사진에 있던 건물의 형채를 알아볼 수 있는 반면에, 오른쪽의 경우는 잡음이 너무 많이 섞여있어서 원래의 형태도 알아볼 수 없습니다.

회귀분석에서의 잡음

그렇다면 우리가 배웠던 회귀분석과 이런 잡음이 어떻게 연관이 될까요? 회귀분석에서는 우리가 관심있는 변수(종속변수)의 움직임을 우리가 잘 알고있는 변수(독립변수)들을 사용하여 독립변수 값에 대한 종속변수의 반응값을 예측하고자 합니다. 그리고 독립변수와 종속변수 간에 선형관계, 즉, 두 변수의 움직임을 결정하는 직선식이 존재한다고 가정합니다. 하지만 이 직선식에서 나오는 결과들이 어떤 불규칙적인 잡음들이 섞여서 나온다고 생각하는 것이죠. 즉, 잡음이라고 우리가 부르던 것들은 예측 불가능한 어떤 과정들을 묘사하는 통계적인 도구라고 생각할 수 있습니다.

어떤 것이 “예측 불가능 하다” 라는 것을 어떻게 해야 수학적으로 나타낼 수 있을까요?

잡음의 조건

이제부터는 좀 더 구체적인 예를 들어서 이야기를 해보도록 합시다. 우리가 원래 관찰하고 싶은 대상이 다음과 같은 직선이라고 생각해봅시다.

\[ y = 3 \times x + 20 \]

이 식을 그래프로 그려보면 다음과 같을 것입니다.

위의 직선 식을 함수형태로 만들어 R에 정의를 해보면 다음과 같을 것 입니다.

true_fuc <- function(x){
  result <- x * 3 + 20
  return(result)
}

이 함수는 항상 일정한 규칙을 따라 작동하게 되겠죠. 그래서 우리가 임의로 정한 \(x\)값을 넣으면, 그에 따른 \(y\)을 반환하게 되고, 그 값들을 바탕으로 우리는 관찰하고 싶은 직선의 모습을 볼 수 있을 것입니다. 실제 값들을 함수에 넣어보면 아래와 같이 반응값인 검정색 점들이 직선의 모습을 그대로 반영하고 있는 것을 알 수 있습니다.

x <- c(2, 6, 3, 7, 4, 6, 5, 1, 9, 8, 10)
y <- true_fuc(x)
plot(x, y, pch = 19)
abline(20, 3, lty = 2)

방향성

만약 우리가 관찰하는 함수값(\(y\))이 어떤 외부의 영향으로 인하여 5 만큼 더해져서 나온다면 어떨까요?

y <- true_fuc(x) + 5
plot(x, y, pch = 19)
abline(20, 3, lty = 2)

구해진 각각의 \(y\) 값들이 실제 함수에서 정확히 5만큼 떨어져서 관찰될 것입니다. 이러한 상황을 우리는 불확실 하다고 할 수 있을까요? 아니겠죠, 왜냐하면 우리가 관찰한 \(y\)들에 각각의 관찰값들이 영향을 받은 차이, 5만큼을 빼주면, 우리가 원하는 직선을 정확하게 얻을 수 있기 때문입니다.

통계에서는 이렇게 일정하게 치우쳐서 관찰값이 나오는 상황을 편향(bias)되어있다라고 말합니다. 이렇게 관찰값이 일정한 편향값을 가지는 가지고 있는 상황은 사실 완벽하게 예측 가능한 상황일 것입니다. 따라서 우리가 불확실성을 묘사하는 좋은 잡음의 조건 중 하나는 더해지는 값들이 일정한 방향성을 띄면 안된다는 것 일 것입니다.

규칙성

그렇다면, 방향성을 없앤다면 문제가 해결될까요? 만약 잡음이 일정한 규칙을 가지고 나온다고 하면 어떻게 될까요? 다음의 코드는 입력하는 \(x\)이 짝수인 경우는 5를 더하고, 홀수 인 경우에는 -5를 반환하는 규칙을 가진 노이즈 입니다.

noise <- function(x){
  noise_vec <- rep(0, length(x))
  noise_vec[x %% 2 == 0] <- 5
  noise_vec[x %% 2 == 1] <- -5
  return(noise_vec)
}
y <- true_fuc(x) + noise(x)
plot(x, y, pch = 19)
abline(20, 3, lty = 2)

noise_vec[x %% 2 == 0] 코드가 이해가 안 가신다면, 1강과 4강을 참고하세요.

그래프에서처럼 관찰값들은 직선을 중심으로 분포가 되어있지만, 역시나 일정 규칙을 띄고 있죠. 따라서, \(y\)값을 기준으로 우리가 알고 있는 규칙을 적용하면 완벽하게 직선을 구할 수 있죠.

denoise <- rep(0, length(y))
denoise[y %% 2 == 1] <- -5
denoise[y %% 2 == 0] <- 5
plot(x, y, pch = 19)
points(x, y + denoise, pch = 19, col = "blue")
abline(20, 3, lty = 2)

따라서 잡음(noise)을 만드는 것은 당연하게도 우리가 알아낼수 있는 방향성이나 규칙들을 가지고 있으면 안될 것입니다.

독자들 중에서는 어쩌면 엄청 복잡한 규칙을 가지고 있으면 되지 않으냐 생각할 수도 있겠지만, 입력값에 따른 규칙이 존재하는 한 그것은 규칙적인 것이 되어 버리는 것이죠. 눈치 채신 독자분도 있겠지만, 우리의 입력값은 11개인데 그래프의 점은 10가 찍혀있습니다. 왜냐하면 입력값 중 두 개의 6이 들어있기 때문에 점이 겹쳐 있는 것이죠.

x
>>  [1]  2  6  3  7  4  6  5  1  9  8 10

이렇게 입력값에 대한 규칙으로 잡음이 생성된다면, 같은 입력값에 대한 결과는 아무리 복잡해도 같은 값을 갖게 될 것입니다. 따라서 잡음에 대한 연구를 하 사람들은 결국 다음의 문제에 도달합니다.

어떻게 불규칙적인(random) 한 것을 만들어낼 수 있을까?

불규칙성의 모델링

그렇다면 어떻게 불규칙적인(random) 한 것을 구현해낼 수 있을까요? 사실 문제에 대한 연구는 무수한 시간동안 수많은 연구들이 있어왔고, 통계를 이루는 가장 근본이 되는 내용입니다. 그 연구들을 통계 공부를 시작하는 우리들이 바로 공부하기엔 벅차므로, 아이디어만 얻어보도록 합시다.

사실 우리는 불규칙한 것을 아이러니하게도 규칙적인 것으로부터 얻을 수 있는데, 바로 아주 규칙적으로 흘러가는 시간을 이용하여 불규칙한 것을 만들어낼 수 있습니다.

## print with possibly greater accuracy:
options(digits.secs = 6)
Sys.time()
>> [1] "2023-06-09 09:28:04.170562 EDT"

Sys.time 함수의 옵션을 이용하면, 현재의 시간을 컴퓨터가 측정할 수 있는 시간을 최대한 정확하게 측정해줍니다. 소수점 6자리까지 측정된 이 시간 결과 값은 제가 이 글을 쓰는 시간과 여러분이 이 글을 보면서 같은 코드를 실행했을 때의 시간이 다르므로 당연히 다른 값을 같게 되겠죠. 위의 소수점 6자리까지 측정된 결과값의 마지막자리 4개의 숫자를 가져와서 잡음으로 쓰면 어떨까요? 즉, 0.001초에서 0.00001초 단위 값들을 가져오는 것이죠.

시간을 통한 불규칙성 모델링

다음의 코드는 현재의 시간을 문자열로 result에 저장하고, 저장된 문자열의 맨 마지막 4자리를 가져오는 코드입니다.

current_time <- as.character(Sys.time())
n <- nchar(current_time)
time_decimal <- substr(current_time, n-3, n)
current_time; time_decimal
>> [1] "2023-06-09 09:28:04.192904"
>> [1] "2904"

nchar 함수는 문자열의 글자 숫자를 세어주는 함수이고, substr 함수는 subset of string을 나타내는 뜻으로서, 주어진 문자열의 부분을 가져오는 함수 입니다. 즉, 위의 코드는 current_time 문자열의 마지막 4개 글자를 가져와 time_decimal에 저장하게 됩니다.

위에서 구한 time_decimal의 4개의 숫자 정보를 다음과 같이 0에서 1사이의 숫자로 바꿀 수 있습니다.

as.integer(time_decimal) / 10000
>> [1] 0.2904

위의 과정을 함수로 만들어 봅시다.

random_0to1 <- function(){
  options(digits.secs = 6)
  current_time <- as.character(Sys.time())
  n <- nchar(current_time)
  time_decimal <- substr(current_time, n-3, n)
  return(as.integer(time_decimal)/ 10000)
}

위에서 정의한 random_0to1 함수는 이제 실행을 시킬때마다 소수점 네자리의 숫자를 우리들에게 알려줍니다.

random_0to1()
>> [1] 0.7034
random_0to1()
>> [1] 0.2516
random_0to1()
>> [1] 0.3526

만약 우리가 이 함수를 정말 빠르게, 0.00001초마다 실행을 시킨다면, 연속해서 증가하는 숫자들을 볼 수 있겠지만, 우리가 인지하는 시간속에서 방금 우리가 만든 함수의 값은 완벽하게 불규칙적인 값을 갖게 됩니다. 또한, 0에서 1사이의 값들 중 어떤 값이 자주 나오는 일이 없이 균일하게 나온다고 합리적으로 가정할 수 있습니다.

runif() 함수

앞에서 작성한 random_0to1의 고급버전이 바로 R에서 runif() 함수입니다. 이 함수는 0에서 1사이의 값들을 균일한 빈도로 무작위하게 뽑아서 우리에게 전해 줍니다. 발생하고 싶은 숫자 갯수를 입력값으로 넣으면 됩니다.

# 3개의 0~1 사이의 무작위 숫자 발생
runif(3)
>> [1] 0.8999241 0.7965745 0.6535918

이러한 runif() 함수를 사용하면, 어떤 범위의 값이든 불규칙한 값을 발생시킬 수 있습니다.

-5에서 5사이의 숫자를 무작위로 11개 발생 시켜보도록 합시다.

r_noise <- runif(11) * 10 - 5
r_noise
>>  [1]  0.3736142 -0.4655982 -4.1306279 -4.7911258  3.5496332 -0.3431999
>>  [7] -3.4564438  2.9423173  3.2719491 -4.3097979  1.4258722

0에서 1사이의 숫자들에 10를 곱하면 최소로 나올 수 있는 값은0, 최대로 나올 수 있는 값은 10이 나올 수 있을 것입니다. 이러한 숫자들에 5을 빼버리면, 최소로 나올 수 있는 값은 -5, 최대로 나올 수 있는 값은 5이 될 것입니다. 즉, r_noise는 -5에서 5까지의 무작위 숫자를 10개를 담고 있는 벡터가 될 것입니다.

잡음이 석인 직선

앞서 정의한 직선 식에 r_noise 함수를 더해보면 어떻게 될까요?

y <- true_fuc(x) + r_noise
plot(x, y, pch = 19, ylim = c(10, 55))
abline(20, 3, lty = 2)

이러한 잡음이 섞인 함수의 관찰값(\(y\))은 입력값(\(x\))과는 상관없이 불규칙적으로 -5에서 5사이의 잡음이 섞여서 관찰이 되는 것을 볼 수 있고, 같은 입력값 6에 대하여도 다른 관찰값을 갖는 것을 알 수 있습니다. 또한, 다시한번 코드를 실행시키면, 다른 관찰값들이 생성되는 것을 알 수 있습니다.

r_noise <- runif(11) * 10 - 5
y <- true_fuc(x) + r_noise
plot(x, y, pch = 19, ylim = c(10, 55))
abline(20, 3, lty = 2)

마치며

오늘은 통계에서 불규칙성(randomness)를 다루는 것에 대한 이야기를 해봤습니다. 마지막엔 불규칙적으로 생성된 숫자들을 가지고 직선의 관찰값에 더하여 잡음으로 사용하기도 해봤습니다. 하지만, 우리가 runif 함수로 만들어내는 잡음에는 다음과 같은 한계가 있습니다.

  1. 특정한 범위가 정해져서 나온다는 것.
  2. 지정된 범위에서 모두 고르게 잡음이 만들어져서 원래의 직선식의 정보를 너무나 가려버립니다. 마치 너무 많은 잡음이 섞여서 보이지 않았던 건물 사진 처럼 말이죠. 잡음의 정도를 조절할 수 있으면 좋겠는데 말이죠.

이러한 좋은 잡음의 조건을 따라가다 보면 자연스럽게 통계에서 가장 유명한 분포인 정규분포(Normal distribution)를 만나게 됩니다. 그리고 앞으로 해드릴 여러개의 강의들은 정규분포로 가기위한 포석이 되겠죠.

random_0to1 함수처럼 입력값이 없이 매번 값이 불규칙하게 바뀌는 이런 객체를 확률변수(random variable)이라고 부르며, random_0to1의 결과값처럼 나오는 값들이 균일한 빈도수를 가지고 나오는 확률변수를 균일 (혹은 균등) 확률변수라고 부릅니다. 다음 시간에는 확률변수에 대하여 좀 더 알아보도록 하겠습니다.

반응형

댓글