프로그래밍(Web)/업무관련

[바미] 선형 보간법

Bami 2024. 6. 8. 09:03
728x90
반응형

데이터를 가지고 특정 기간별 통계, 분석을 내야할 때 특정 기간의 데이터가 null로 비어있는 경우 데이터를 자동으로 보정처리 해주면 편하겠다 싶을겁니다.

 

그 때 사용되는 보정 방법 중 하나가 선형 보간법이라는 방법인데 오늘은 선형 보간법에 대해 살펴보도록 하겠습니다.


선형 보간법?

선형 보간법은 두 개의 알려진 데이터 포인트 사이의 값을 추정하는 방법입니다

이 방법은 계산이 간단하고 직관적이어서 여러 분야에서 널리 사용되고 있습니다.

 

예를 들어 두 점 (𝑥0, 𝑦0)와  (𝑥1, 𝑦1)이 주어졌을 때,  𝑥0와 𝑥1사이의 어떤 𝑥에 대한 𝑦값을 추정할 때

선형 보간법은 아래와 같은 공식을 사용합니다.

\( y = y_{0} - \left( y_{0} - y_{1} \right) \cdot \frac{x - x_{0}}{x_{1} - x_{0}} \)
  • 𝑦0: 첫 번째 점의 y 값
  • 𝑦1: 두 번째 점의 y 값
  • 𝑥0: 첫 번째 점의 x 값
  • 𝑥1: 두 번째 점의 x 값
  • 𝑥: 추정하고자 하는 x 값
  • 𝑦: 추정된 y 값

예제

두 점 (1, 2)와 (3, 6)이 있다고 가정해보죠. 이 두 점 사이의 𝑥 = 2 일 때의 𝑦값을 추정하려면 다음과 같이 계산할 수 있습니다. 

 

첫 번째 점: (𝑥0 , 𝑦0)  = (1,  2) 
두 번째 점: (𝑥1 ,𝑦1) =(3, 6)
추정할 𝑥값: 𝑥 = 2 

 

이제 위에 값에 공식을 사용하여 
𝑦 값을 계산하면 아래와 같이 계산됩니다.

\(y=2+\left( 6-2\right) \cdot \dfrac{2-1}{3-1} \)
𝑦 = 2 + 4 ⋅ 0.5
𝑦 = 2 + 2
𝑦 = 4

 

따라서 𝑥 = 2일 때  𝑦값은 4가 됩니다.


장점과 한계점

장점으로는 앞서 말씀드렸듯이 계산이 간단하고 빠르고, 정확도가 높아 실제로 많은 곳에서 사용하는 기법입니다.

 

하지만 두 점 사이의 선형 변화만을 가정하기 때문에 데이터가 비선형적(데이터 포인트들이 단순한 직선이 아닌 곡선이나 복잡한 형태로 분포되어 있는 형태)일 경우나 데이터에 빈 값이 많을 수록 정확도가 떨어지게 되고, 복잡한 패턴을 가진 데이터에서는 더 정교한 보간 방법이 필요하다는 한계점이 존재합니다.


코드

그럼 이제 자바스크립트로 구현 했을 때 코드를 보여드리도록 하겠습니다.

function linearInterpolation(data) {
    // 데이터를 타임스탬프 기준으로 정렬합니다.
    data.sort((a, b) => a.date - b.date);

    // 데이터 전체를 순회하며 보간 작업을 수행합니다.
    for (let i = 0; i < data.length; i++) {
        if (data[i].value === null) {
            // null 값을 가진 데이터 포인트를 찾습니다.
            let j = i;
            while (j < data.length && data[j].value === null) {
                j++;
            }

            if (j < data.length) {
                // 보간을 위한 데이터 포인트를 찾습니다.
                let t0 = data[i - 1].date;
                let t1 = data[j].date;
                let v0 = data[i - 1].value;
                let v1 = data[j].value;

                // null 값을 가진 구간에 대해 선형 보간 계산
                for (let k = i; k < j; k++) {
                    let t = data[k].date;
                    data[k].value = v0 + (v1 - v0) * ((t - t0) / (t1 - t0));
                }
            } else {
                // 마지막 데이터 포인트까지 null인 경우 처리
                let v0 = data[i - 1].value;
                for (let k = i; k < data.length; k++) {
                    data[k].value = v0;
                }
            }

            i = j - 1; // 이미 보간한 구간을 건너뜁니다.
        }
    }

    return data;
}

// 예시 데이터
let data = [
    { date: 1625097600000, value: 10.2 },
    { date: 1625184000000, value: null },
    { date: 1625270400000, value: 30.4 },
    { date: 1625356800000, value: null },
    { date: 1625443200000, value: null },
    { date: 1625529600000, value: 60.3 },
    { date: 1625616000000, value: 70.2 },
    { date: 1625702400000, value: null },
    { date: 1625788800000, value: 90.5 }
];

let interpolatedData = linearInterpolation(data);
console.log(interpolatedData);

 

정수형 데이터를 정상적으로 처리해주는 모습을 볼 수 있습니다.

728x90
반응형