정상성(Stationarity)
정상성(Stationarity)이란 언제 관측되는지에 관계없이 어떤 시점에 관찰하더라도 예측할 수 있는 패턴을 발견할 수 없는 것을 뜻한다.
정상성에 대한 자세한 사항은 여기를 참조하면 된다.
로그 변환(Log Transform)
비정상성 시계열을 정상성으로 변환하는 방법은 로그 변환(Log Transformation)과 차분(Differencing) 2가지가 있다.
우선 로그 변환(Log Transformation)이란 변동폭이 일정하지 않은 경우 사용할 수 있는데 일반적인 수학의 x를 log(x)로 바꾸는 변환 방식이다. 로그 변환은 원본 데이터의 왜곡을 줄이거나 제거하는데 여기서 주의할 점은 원 데이터가 로그 정규 분포를 따르거나 대략 따라줘야 한다. 그렇지 않으면 로그 변환 적용이 잘 적용되지 않는다.
이 변환 방식은 레벨-레벨(level-level), 레벨-로그(level-log), 로그-레벨(log-level), 로그-로그(log-log)가 있다. 레벨-레벨(level-level) 방식은 변환을 취하지 않으므로 설명을 생략한다. 여기서 자연로그는 ln으로 표시한다.
해당 설명은 아래 식을 기준으로 전개한다.
$$ y_i = 5 + 0.3*x_i $$
레벨-로그(level-log) 방식은 독립변수인 x에만 로그를 취하는게 가능할 때 적용할 수 있다.
$$ Y_2-Y_1 = (5+0.03ln(x_2))-(5+0.03ln(x_1)) $$
$$ Y_2-Y_1 = 0.03(ln(x_2)-ln(x_1)) $$
$$ Y_2-Y_1 = 0.03(ln(x_2/x_1)) $$
독립변수 값의 고정된 백분율 변화에 대해 종속변수가 0.03 * x 백분율 변화의 자연로그만큼 변경된다고 가정할 수 있다. 예를 들어 x가 10 % 증가하면 Y는 0.3 % 증가한다(0.03 * ln (1.1) = 0.003). x가 50 % 증가하면 Y는 1.2 % 증가한다(0.03 * ln (1.5) = 0.012). x의 백분율 변경이 고정되어 있으면 Y도 고정된 백분율로 변경된다.
로그-레벨(log-level) 방식은 종속변수에만 로그를 취할 수 있는 경우에 적용하는데, 우선 e를 밑으로 하는 독립 변수의 계수를 지수화한다.
$$ ln(Y_2)-ln(Y_1) = (5+0.03x_2)-(5+0.03x_1) $$
$$ ln(Y_2)-ln(Y_1) = 0.03(x_2-x_1) $$
$$ Y_2/Y_1 = e^{0.03(x_2-x_1)} $$
$$ Y_2/Y_1 = 1.03^{(x_2-x_1)} $$
독립변수가 1 증가할 때마다 종속 변수가 3 % (1.03¹ = 1.03) 증가한다는 결론을 내릴 수 있다. 여기서 중요한 것은 이 증가가 고정된 값이어야 한다는 것이다. x를 10 단위 늘리면 Y의 변화는 34%가 된다(1.03¹⁰ = 1.34).
로그-로그(log-log) 방식은 독립변수, 종속변수 모두 로그 변환을 취한다. 방정식의 좌변에서 로그를 제거하고 e를 밑으로하는 우변을 지수화한다.
독립변수에서 변경된 고정 백분율에 대해 종속변수가 x 백분율 변경으로 0.03의 거듭 제곱으로 변경됨을 알려준다 . x가 10 % 변하면 y는 0.3 % 변한다(1.1⁰⁰³ = 1.003). x가 20 % 변경되면 y는 0.5 % 변경된다(1.2⁰⁰³ = 1.005).
$$ ln(Y_2)-ln(Y_1) = (5+0.03ln(x_2))-(5+0.03ln(x_1)) $$
$$ ln(Y_2)-ln(Y_1) = 0.03(ln(x_2/x_1)) $$
$$ Y_2/Y_1 = e^{0.03ln(x_2/x_1)} $$
$$ Y_2/Y_1 = e^{ln(x_2/x_1)^{0.03}} $$
$$ Y_2/Y_1 = (x_2/x_1)^{0.03} $$
아래는 python으로 로그 변환을 수행한 결과이다. 로그 변환 시 변동폭이 일정해진다.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("co2_data.csv")["2111PT0001"]
y = np.log(df)
plt.plot(df, label="Original")
plt.plot(y, label="log")
plt.suptitle("Log Transform", size=24)
plt.legend()
plt.show()
차분(Differencing)
차분(Differencing)이란 임의의 두 점에서 함수 값들의 차이를 의미한다. 차분을 수행하면 평균이 균일한 시계열로 변환된다. 만약 1차 차분을 진행하였을 때 정상성을 띄는 데이터로 변환하지 못했다면 차분을 2차, 3차 반복해서 수행하면 된다. 보통 1차에서 끝난다.
$$ 1차 차분: y\prime_t = y_t - y_{t-1} $$ $$ 2차 차분: y\prime\prime _t = y\prime_t - y\prime_{t-1} $$ $$ = (y_t - y_{t-1}) - (y_{t-1} - y_{t-2}) $$ $$ = y_t - 2y_{t-1} + y_{t-2} $$
하지만 데이터가 계절성을 띄는 경우엔 계절 차분(Seasonal Differencing)을 먼저 수행해주는 것이 좋다. 계절성 차분이란 관측치와 같은 계절의 이전 관측값과의 차이를 의미한다.
$$ 계절 차분: y\prime_t = y_t - y_{t-m} $$
만약 월별 계절성이 관측된다면 \(m=12\)가 될 것이고, 분기별 계절성이 나타난다면 \(m=4\)가 될 것이다.
아래는 python으로 차분을 수행한 결과이다.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("co2_data.csv")["2111PT0001"]
def difference(dataset, interval=1):
diff = list()
for i in range(interval, len(dataset)):
value = dataset[i] - dataset[i - interval]
diff.append(value)
return np.array(diff)
diff_1 = difference(df)
plt.plot(df, label="Original")
plt.plot(diff_1, label="diff_1")
plt.suptitle("Differencing", size=24)
plt.legend()
plt.show()
관련 포스트
2021.12.03 - [Data Science/Statistics] - [Python] 정상성(Stationarity)과 비정상성(Non-Stationary)
참고 자료
https://otexts.com/fppkr/stationarity.html
소스 코드
정상성(Stationarity)
정상성(Stationarity)이란 언제 관측되는지에 관계없이 어떤 시점에 관찰하더라도 예측할 수 있는 패턴을 발견할 수 없는 것을 뜻한다.
정상성에 대한 자세한 사항은 여기를 참조하면 된다.
로그 변환(Log Transform)
비정상성 시계열을 정상성으로 변환하는 방법은 로그 변환(Log Transformation)과 차분(Differencing) 2가지가 있다.
우선 로그 변환(Log Transformation)이란 변동폭이 일정하지 않은 경우 사용할 수 있는데 일반적인 수학의 x를 log(x)로 바꾸는 변환 방식이다. 로그 변환은 원본 데이터의 왜곡을 줄이거나 제거하는데 여기서 주의할 점은 원 데이터가 로그 정규 분포를 따르거나 대략 따라줘야 한다. 그렇지 않으면 로그 변환 적용이 잘 적용되지 않는다.
이 변환 방식은 레벨-레벨(level-level), 레벨-로그(level-log), 로그-레벨(log-level), 로그-로그(log-log)가 있다. 레벨-레벨(level-level) 방식은 변환을 취하지 않으므로 설명을 생략한다. 여기서 자연로그는 ln으로 표시한다.
해당 설명은 아래 식을 기준으로 전개한다.
레벨-로그(level-log) 방식은 독립변수인 x에만 로그를 취하는게 가능할 때 적용할 수 있다.
독립변수 값의 고정된 백분율 변화에 대해 종속변수가 0.03 * x 백분율 변화의 자연로그만큼 변경된다고 가정할 수 있다. 예를 들어 x가 10 % 증가하면 Y는 0.3 % 증가한다(0.03 * ln (1.1) = 0.003). x가 50 % 증가하면 Y는 1.2 % 증가한다(0.03 * ln (1.5) = 0.012). x의 백분율 변경이 고정되어 있으면 Y도 고정된 백분율로 변경된다.
로그-레벨(log-level) 방식은 종속변수에만 로그를 취할 수 있는 경우에 적용하는데, 우선 e를 밑으로 하는 독립 변수의 계수를 지수화한다.
독립변수가 1 증가할 때마다 종속 변수가 3 % (1.03¹ = 1.03) 증가한다는 결론을 내릴 수 있다. 여기서 중요한 것은 이 증가가 고정된 값이어야 한다는 것이다. x를 10 단위 늘리면 Y의 변화는 34%가 된다(1.03¹⁰ = 1.34).
로그-로그(log-log) 방식은 독립변수, 종속변수 모두 로그 변환을 취한다. 방정식의 좌변에서 로그를 제거하고 e를 밑으로하는 우변을 지수화한다.
독립변수에서 변경된 고정 백분율에 대해 종속변수가 x 백분율 변경으로 0.03의 거듭 제곱으로 변경됨을 알려준다 . x가 10 % 변하면 y는 0.3 % 변한다(1.1⁰⁰³ = 1.003). x가 20 % 변경되면 y는 0.5 % 변경된다(1.2⁰⁰³ = 1.005).
아래는 python으로 로그 변환을 수행한 결과이다. 로그 변환 시 변동폭이 일정해진다.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("co2_data.csv")["2111PT0001"]
y = np.log(df)
plt.plot(df, label="Original")
plt.plot(y, label="log")
plt.suptitle("Log Transform", size=24)
plt.legend()
plt.show()
차분(Differencing)
차분(Differencing)이란 임의의 두 점에서 함수 값들의 차이를 의미한다. 차분을 수행하면 평균이 균일한 시계열로 변환된다. 만약 1차 차분을 진행하였을 때 정상성을 띄는 데이터로 변환하지 못했다면 차분을 2차, 3차 반복해서 수행하면 된다. 보통 1차에서 끝난다.
하지만 데이터가 계절성을 띄는 경우엔 계절 차분(Seasonal Differencing)을 먼저 수행해주는 것이 좋다. 계절성 차분이란 관측치와 같은 계절의 이전 관측값과의 차이를 의미한다.
만약 월별 계절성이 관측된다면
아래는 python으로 차분을 수행한 결과이다.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.read_csv("co2_data.csv")["2111PT0001"]
def difference(dataset, interval=1):
diff = list()
for i in range(interval, len(dataset)):
value = dataset[i] - dataset[i - interval]
diff.append(value)
return np.array(diff)
diff_1 = difference(df)
plt.plot(df, label="Original")
plt.plot(diff_1, label="diff_1")
plt.suptitle("Differencing", size=24)
plt.legend()
plt.show()
관련 포스트
2021.12.03 - [Data Science/Statistics] - [Python] 정상성(Stationarity)과 비정상성(Non-Stationary)
참고 자료
https://otexts.com/fppkr/stationarity.html
소스 코드