선형 회귀(Linear Regression)는 주어진 데이터 포인트 집합으로부터 가장 잘 맞는 직선의 방정식을 찾아내는 통계 기법입니다. 주어진 점들이 하나의 직선을 따른다고 가정하고, 이를 통해 현재 데이터 집합에 존재하지 않는 특정 지점의 값을 예측할 수 있습니다.
핵심 공식
데이터 포인트들을 이용해 선형 회귀 문제를 풀기 위해서는 다음 공식들을 사용합니다.
여기서 m은 기울기(slope)를, c는 y절편(y-intercept)을 의미합니다. 이 식들을 활용하면 다음과 같은 형태의 직선 방정식을 얻을 수 있습니다.
y = mx + c
입력과 출력
입력:
점들의 (x, y) 좌표 {(1,3), (2,4), (3,5), (4,6), (5,8)}
출력:
기울기(Slope): 1.2, 절편(Intercept): 1.6
방정식: y = 1.2x + 1.6알고리즘
linReg(coord)
입력: 주어진 좌표 포인트들의 집합
출력: 기울기 m과 y절편 c
Begin
for i := 1 to n, do
sumX := sumX + coord[i,0]
sumY := sumY + coord[i,1]
sumXsq := sumXsq + (coord[i,0]*coord[i,0])
sumXY := sumXY + (coord[i,0] * coord[i,1])
done
m := (n * sumXY – (sumX*sumY)) / (n * sumXsq – (sumX * sumX))
c := (sumY / n) – (m * sumX)/n
End알고리즘의 동작 과정을 살펴보면 다음과 같습니다.
- x값의 합(sumX), y값의 합(sumY), x²의 합(sumXsq), xy의 합(sumXY)을 각각 누적하여 계산합니다.
- 최소제곱법(Least Squares Method)에 기반한 공식으로 기울기 m을 구합니다.
- y절편 c는 평균 관계식 c = ȳ − m·x̄ 를 이용해 계산합니다.
C++ 구현 예제
#include<iostream>
#include<cmath>
#define N 5
using namespace std;
void linReg(int coord[N][2], float &m, float &c) {
float sx2 = 0, sx = 0, sxy = 0, sy = 0;
for(int i = 0; i<N; i++) {
sx += coord[i][0]; // x값의 합
sy += coord[i][1]; // y값의 합
sx2 += coord[i][0]*coord[i][0]; // x²의 합
sxy += coord[i][0]*coord[i][1]; // x*y의 합
}
// 기울기와 절편 계산
m = (N*sxy-(sx*sy))/(N*sx2-(sx*sx));
c = (sy/N)-(m*sx)/N;
}
main() {
// 좌표 포인트를 저장하는 2차원 배열
int point[N][2] = {{1,3},{2,4},{3,5},{4,6},{5,8}};
float m, c;
linReg(point, m, c);
cout << "기울기: " << m << " 절편: " << c << endl;
cout << "방정식: " << "y = "<< m <<"x + "<< c;
}실행 결과
기울기: 1.2 절편: 1.6 방정식: y = 1.2x + 1.6
이처럼 선형 회귀는 비교적 간단한 수학적 계산만으로 데이터의 추세를 나타내는 직선을 구할 수 있으며, 머신러닝의 기초가 되는 중요한 알고리즘입니다. 위 코드에서 볼 수 있듯이, 모든 좌표에 대한 합계를 한 번의 반복문으로 계산한 뒤 공식에 대입하기 때문에 시간 복잡도는 O(n)으로 효율적입니다.