문제 정의
이번 글에서는 선형 회귀(linear regression) 알고리즘을 구현하는 C 프로그램을 작성해 보겠습니다. 사용자는 먼저 입력할 데이터 값의 총 개수(n)를 지정한 뒤, 각 데이터의 x와 y 값을 차례로 입력하게 됩니다.
선형 회귀란?
선형 회귀는 관찰된 데이터에 직선 방정식을 적용하여 두 변수 사이의 관계를 찾아내는 통계 기법입니다. 이때 하나의 변수는 설명 변수(독립 변수, x) 역할을 하고, 다른 하나는 종속 변수(y) 역할을 합니다.
구하고자 하는 것은 다음 형태의 직선 방정식입니다.
y = mx + c
- m: 직선의 기울기(slope)
- c: y절편(intercept)
핵심 로직
최소제곱법(least squares method)에 기반한 계산 로직은 다음과 같습니다. 먼저 반복문을 통해 각종 합계를 누적합니다.
for(i=0;i<n;i++){
printf("enter values of x and y");
scanf("%f%f",&x,&y);
sumx = sumx + x;
sumxsq = sumxsq + (x*x);
sumy = sumy + y;
sumxy = sumxy + (x*y);
}
d = n*sumxsq - sumx*sumx;
m = (n*sumxy - sumx*sumy) / d;
c = (sumy*sumxsq - sumx*sumxy) / d;
각 항목의 의미는 다음과 같습니다.
- sumx: x 값들의 합 (Σx)
- sumxsq: x 값 제곱의 합 (Σx²)
- sumy: y 값들의 합 (Σy)
- sumxy: x·y 곱의 합 (Σxy)
누적된 합계를 이용해 분모(d)를 계산한 후, 기울기 m과 절편 c를 구하고 최종적으로 출력하면 됩니다.
전체 예제 코드
다음은 선형 회귀를 계산하는 C 프로그램의 완성된 코드입니다.
#include<math.h>
#include<stdio.h>
int main(){
int n, i;
float x, y, m, c, d;
float sumx = 0, sumxsq = 0, sumy = 0, sumxy = 0;
printf("enter the number of values for n:");
scanf("%d", &n);
for(i = 0; i < n; i++){
printf("enter values of x and y");
scanf("%f%f", &x, &y);
sumx = sumx + x;
sumxsq = sumxsq + (x*x);
sumy = sumy + y;
sumxy = sumxy + (x*y);
}
d = n*sumxsq - sumx*sumx;
m = (n*sumxy - sumx*sumy) / d;
c = (sumy*sumxsq - sumx*sumxy) / d;
printf("M=%f\tC=%f\n", m, c);
return 0;
}
참고로 최신 C 표준(C99 이후)에서는 main() 함수를 int main()으로 선언하고 마지막에 return 0;을 명시하는 것이 권장됩니다.
실행 결과
위 프로그램을 컴파일하여 실행하면 다음과 같은 결과가 출력됩니다.
enter the number of values for n:5 enter values of x and y1 5 enter values of x and y2 6 enter values of x and y2 4 enter values of x and y3 7 enter values of x and y1 1 M=2.000000 C=1.000000
5개의 데이터 쌍을 입력했을 때, 프로그램은 기울기 M = 2.0과 절편 C = 1.0을 정확히 계산해 냈습니다. 즉, 이 데이터에 가장 잘 맞는 직선은 y = 2x + 1이라는 결론을 얻을 수 있습니다.