3. MSE, MAE를 C로 구현해보자!!
벌써 3번째 게시글을 쓰게 되었네요. 이번 게시글은 첫번째 정보과학융합탐구 게시글인데요. 평소에 관심을 가지던 주제를 코딩으로 구현해보는 과제가 주어졌습니다. 어떤 주제를 정해야할지 고민을 많이 했지만 결국 제가 주제는 MSE, MAE 인데요.
-MSE, MAE란 무엇일까?

머신러닝 회귀 모델을 평가할때 사용되는 지표의 종류입니다.
우선 MSE는 mean squared error의 약자로 평균제곱오차를 가리키는데요. 평균제곱오차는 말 그대로 오차를 제곱한 값에 평균을 취한 값입니다.
머신러닝에서 가장 많이 쓰이는 손실 함수 중 하나로 값이 0에 가까울수록 예측 값이 실제값에 가깝다는것이기 때문에 정확도가 높다고 할 수 있습니다. 지표가 직관적으로 나타나 분석에 용이하지만 제곱한다는 특성때문에 1미만의 에러는 훨씬 작아지고 1 이상의 에러는 훨씬 커진다는 단점이 있습니다. 또한, 예측값이 실제값보다 작은지 큰지도 알 수 없습니다. 그리고 특이값이 있다면 그 값에 큰 영향을 받습니다. 스케일에 의존적이라는 단점도 있겠네요.
이러한 MSE와 비슷하지만 다른 지표로 MAE가 있는데요. MAE는 mean absolute error의 약자로 평균절대오차를 가리킵니다. 평균절대오차는 오차에 절댓값을 취하여 평균을 취한 값입니다.
MAE도 마찬가지로 값이 0에 가까울수록 정확도가 높다고 할 수 있겠죠. MAE는 지표가 직관적이기도 하지만 예측값과 실제값의 단위가 같기때문에 분석하기에 용이합니다. 특잇값의 영향도 MSE보다는 적을것입니다. 그러나 오차에 절댓값을 취하기 때문에 예측값이 실제보다 작은지 큰지를 알 수 없고, 스케일에 의존적이라는 단점을 가지고 있습니다.
-이것들은 어디에 쓰이는 걸까?
위에서 언급한대로 모델 성능 평가에 쓰이는데요. 모델 성능 평가는 말그대로 예측값이 실제값과 얼마나 차이가 나는지에 대한 평가인데요. 이를 통해 과적합 현상을 방지하고 최적의 모델을 찾을 수 있게 됩니다. 모델에 따라 다양한 평가 지표가 존재하는데(아래 그림 참고) 저는 이주 회귀 모델 평가에 사용되는 2가지 지표에 대해 다루었습니다. 다른 방법들도 앞으로 기회가 된다면 블로그에 업로드 하도록 하겠습니다!
-C코드로 구현해보자

파이썬으로는 구현해보기도 했고 라이브러리를 이용하면 어렵지 않게 이용할 수 있지만 이번 기회에 C로 구현해보기로 하였습니다. 알고리즘은 다음과 같이 설계하였습니다.
ax+b라는 함수를 이용하여 예측하도록 하였고 배열에 n개의 x값과 실제 값을 입력받도록 하였습니다. 그다음 x값을 토대로한 예측값과 입력받은 실제값 사이의 차이를 분석해보는 알고리즘을 설계하였습니다.
#include <stdio.h>
#include <stdlib.h> //abs함수 사용을 위한 라이브러리
int main(){
int arr[100][2]; //x값과 실제값 저장
int n,a,b; //n개의 데이터, a는 기울기, b는 y절편
double sumse=0; //제곱오차들의 합
double sumae=0; //절대오차들의 합
printf("데이터의 개수:"); //변수 입력
scanf("%d",&n);
printf("기울기:");
scanf("%d",&a);
printf("y절편:");
scanf("%d",&b);
for(int i=1;i<=n;i++){ //데이터의 갯수만큼 입력 받기
printf("%d번째 데이터 입력(x값,실제값):",i); //데이터 입력
scanf("%d,%d",&arr[i][1],&arr[i][2]); //배열의 1열은 x값, 2열은 실제값
sumse+=(arr[i][2]-(a*arr[i][1]+b))*(arr[i][2]-(a*arr[i][1]+b)); //제곱 오차 계산
sumae+=abs((arr[i][2]-(a*arr[i][1]+b))); //절대 오차 계산(abs함수 이용)
}
for(int i=1;i<=n;i++){
printf("x값:%d 실제 값:%d 예측값 :%d\n",arr[i][1],arr[i][2],a*arr[i][1]+b); //데이터 나열
}
printf("MSE값:%.1f\n",sumse/n); //결과값 소숫점 첫째자리까지 출력
printf("MAE값:%.1f",sumae/n);
}
위의 내용을 구현한 코드입니다.
실행 결과 잘 작동하였습니다. 5개의 데이터를 가지고 실험을 해보았는데 직접 계산을 해보았을때
MSE: {(9-8)^2 + (13-6)^2 + (11-29)^2 + (25-30)^2 + (17-20)^2}/5=81.6
MAE: {|9-8| + |13-6| + |11-29| + |25-30| + |17-20|}/5 =6.8
이므로 계산이 잘 이루어지는것을 볼 수 있습니다. 복잡한 코드는 아니였어서 오류 없이 쉽게 구현할 수 있었던것 같아요.성공해서 매우 뿌듯하네요!
첫 정.융.탐 게시물인 만큼 아직 게시물에서 부족함이 많이 느껴지지만 오늘도 글을 읽어 주신 분들께 모두 감사하다는 말을 전하고 싶습니다. 앞으로 더욱 유용한 블로그가 되기 위하여 노력하겠습니다. 그럼 빠이!