목표 : 수업시간에 배운 기계학습 모델들을 “직접” 구현하고, 응용 문제를 해결하기
구현한 모델은 MYLinearRegression 이라는 선형회귀 모델이다. 선형 회귀는 알려져있는 다른 관련 데이터 값을 사용하여 알 수 없는 데이터의 값을 예측하는 데이터 분석 방법으로 가장 기본적인 모델로서 많이 사용된다.
이 모델을 선택한 이유는 외부 라이브러리를 사용하지 못하는 상황에서 회귀문제를 풀기 위 해 가장 구현이 쉽고, 이해가 직관적으로 가능하였기 때문이다. 회귀문제를 해결하기 위해 KNN- Regression, Decisiontree- regression, 신경망 등 다양한 모델을 떠올렸고 이를 구 현하려 하였으나 데이터셋에 데이터 타입 처리에서 어려움을 겪었고, 결국 최종적으로 선형회 귀 모델을 선택하게 되었다.
내가 구현한 모델은 생성자, fit(), predict(), score() 4개로 이루어져 있다. 생성자 매서드 에서는 모델의 가중치를 저장할 변수 self.weights를 초기화 한다.
fit() 메서드는 훈련 데이터 X와 타겟 변수 y를 매개변수로 받는다. X의 각 샘플에 절편을 나타내는 1의 값을 추가한 후(X_b), 최소 제곱법을 사용하여 선형 회귀 모델의 가중치를 계산 한다. 계산된 가중치는 self.weights에 저장되어, 예측 시 사용된다. 여기서 np.linalg.inv 함 수는 행렬의 역행렬을 계산하는 데 사용된다.
predict 메서드는 새로운 입력 데이터 X를 매개변수로 받는다. 이 메서드는 먼저 X에 절편 항을 추가하고(X_b), 저장된 가중치 self.weights와의 곱셈을 통해 예측값을 계산한다. 이렇게 계산된 예측 값은 출력으로 반환된다.
score()는 입력 데이터 X와 타겟 데이터 y에 대한 모델의 성능을 평가하는 매서드로, R2score를 활용하였다.
위 공식에 맞게 계산결과를 반환하도록 코드를 작성하였다.
처음에는 이 모델을 통해 풀고자 하는 응용문제는 혼인율, 이혼율, 사망률 및 Date와 Region 을 토대로 대한민국의 정확한 출산율을 예측하는 것이었다. 한국의 출산율은 현재 대한민국 사회에서 가장 큰 이슈가 되고 있는 주제로, 세계적으로도 매우 낮은 수치를 기록하고 있다. 2022년 기준 대한민국의 합계 출산율은 ‘0.78’로 이례적으로 낮은 수치로 인해 향후 미래에 어떤 영향을 끼칠지 그 누구도 예상을 쉽게 하지 못하고 있다. 이러한 출산율에 대해 각 기관 에서 다양한 예측이 나오고 있는데에도 이 주제를 선택한 이유는 계속해서 낮아지고 있는 출 산율에 대해 정부 기관의 예측이 기관마다 다르고, 예전 통계청이 예측한 출산율보다 출산율 이 빠르게 감소하고 있다는 점에서 보다 정확한 예측이 필요로 한다고 생각하였기 때문이다.
2025년 0.65명을 기점으로 다시 반등을 시작한다고 되어있는데 내 생각으로는 과연 이에 대 한 신빙성이 부족하다고 생각한다.
따라서, 2000년~2022년의 한국 인구 데이터셋을 활용하여 모델을 구현해 보고, 이를 통계청 에서 발표한 2023년의 인구 데이터와 비교하여 출산율을 정확하게 예측할 수 있는 모델을 만 들어 보기로 하였다.
사용한 데이터 셋의 명은 Korean demographics 2000-2022 라는 데이터셋이다. 이 데이터셋은 한국의 birth,death,natural growth, marrage, and divorce의 value와 rate,각 지역별, 월별로 분리한 데이터 4860개를 포함하고 있다.
다음 그림은 data().info()와 data().describe() 이다. 이를통해 데이터의 타입이 어떻게 되어있는지와 통계값을 확인할 수 있었다.
특이사항으로는 ‘세종시’가 생기기 전인 2000년도의 데이터 또한 포함되어 있고, 이는 NULL 로 처리되어 있었다. 따라서, 데이터의 정확도를 위해 null이 하나라도 포함된 세종시의 데이 터는 학습에서 제외시켰다.
또한 Date와 Region 의 데이터 타입이 object이기에 이를 number 타입으로 변환하기 위해 Date는 time-stamp로 변환후 Unixtime, Region은 one-hot encoding을 통하여 bool 값으 로 변환 하였다. 문제는 모델을 만들고 실험을 진행하면서 발생하였다. 앞서 전처리한 Date와 Region 의 경우 데이터 타입으로 인해 계속 다음과 같은 문제가 발생하였다.
UFuncTypeError: ufunc 'subtract' did not contain a loop with signature matching
types (dtype('float64'), dtype('<U4')) -> None
이를 해결하여 Date, Region 등을 포함시켜 학습시키려고 하였으나, 장시간의 수정끝에도 해 결법을 찾지 못하였고, 결국 앞서 전처리한 Region과 date를 활용할 수 없었다.
또한 Natural_growth와 Natural_growth_rate를 국내 총생산이라고 생각하여 학습데이터의 포함시켰더니 0.999라는 r2 score가 나왔다. 이를 이상하게 생각하여 찾아보니 Natural_growth 가 국내 인구 증감량을 나타내는 수치였다. 따라서 타겟데이터와의 관련성이 너무 크다고 생각하여 학습에서 제외시켰다.
최종적으로 선택한 변수는 Death, Death_rate, Divorce, Divorce_rate, Marriage, Marriage_rate이다. 각 항목의 value와 백분율 값을 선택하였는데, 이를 중복하여 선택한 이 유는 rate 값만을 사용하였을 때보다 학습이 더 잘 될 거라는 직관으로 선택하였다. 그 결과 rate만을 사용하였을 때보다 r2값이 0.05 정도 증가함을 알 수 있었다.
아래 그림은 학습에 사용한 rate 변수들의 상관관계를 히트맵으로 나타낸 표이다.
히트맵으로 확인해 본 결과, 출산율은 결혼율과 가장 높은 상관관계를 보이고, 그다음으로는 이혼율, 마지막으로 사망률과는 낮은 상관관계를 보였다. 이 결과를 보고 사망률의 데이터를 제거할지 말지 고민을 했지만, 학습 변수가 많으면 많을수록 좋다는 판단하에 포함시켜 실험 을 진행하였다.
test_set/train_set을 0.2/0.8로 나누고, train_set을 다시 train_set/validation_set 0.75/0.25 로 나누었다. 따라서 총 train_set/test_set/validiation_set을 전체 데이터셋의 0.6/0.2/0.2로 나누어 실험을 진행하였다
그 결과 test_set의 경우 0.34403, validation set의 경우 0.39164 (round=5)의 r2score를 얻을 수 있었다.
test_set 과 validation set의 차이가 거의 없음으로 유추해 보았을 때, overfitting이 없이 학습된 것을 알 수 있다. 그러나 r2 score가 0.5 이하로 매우 낮게 나왔다. 이를 데이터 셋에 서 date, region 변수를 제거한 것으로 생각하여, 두 데이터를 포함하여 학습을 진행하려 하 였으나 앞서 말한 에러를 해결하는 것이 불가능하여 결국 배제 하고 학습을 진행하였 다.Knn-regression, perceptron 등 다른 학습 모델을 구현하여 실험을 진행하려 하였으나 이마저도 실패하고 말았다.
결국 sklearn에서 제공되는 LinearRegression, RandomForestRegressor, SVM 을 이용하 여 실험을 진행하였다. 그 결과 각각의 데이터는 아래 표와 같다.
sklearn의 Linear Regression 모델과 비교했을 때, 큰 차이가 나지 않는 것으로 보아 모델 의 구현은 정확하게 된 것으로 생각된다. RandomForest는 결정트리 기반의 앙상블학습 방법 으로 알고 있는데 일반적으로 선형회귀보다 높은 성능을 보여 이러한 결과를 나타낸 것으로 보인다. 반면 SVM의 경우 커널의 선택, 매개변수에 크게 의존하는데, 이러한 적절한 튜닝을 하지 않아 수치가 낮은 것으로 생각된다.
구현한 모델을 실험하기 위해, 2023년 6월 인구통계를 가져와 실험을 해보았다.
예측 출산율은 5.752로 타겟값인 4.4와 약간의 차이를 보인다.
여기서 조 출생률은 특정 국가나 지역의 연간 총 출생자 수를 당해 연도의 연앙 추계 인구로 나눈 것에 1000을 곱한 수치로, 일반적으로 뉴스에서 접하는 합계출산율과는 약간의 차이가 있다.
현재 데이터셋에는 데이터가 2022년 6월까지 존재하여 이를 테스트 할 수 있는 데이터의 개 수가 적어 22년 10월~23년 9월까지 1년치의 데이터를 실험해 보았다.
(https://kostat.go.kr/ansk/ ) 실험 결과 0.5 이내로 차이가 나는 항목이 22.10,23.2 2개가 나왔다. 반면 1.0 이상 차이가 나는 항목이 22.11, 22.12, 23.5, 23.6, 23.9 5개가 나와 기대와는 다 르게 낮은 정답률을 보여주었다.
이러한 불완전한 정확도의 원인은 앞서 데이터 전처리 과정에서 제거한 Region과 Date가 원 인이라고 생각한다. 학습할 수 있는 변수가 많아질수록 모델의 성능이 올라갈것으로 생각되는 데, 실제로 최종 결과를 내기 전 rate만을 포함하여 학습을 진행했을 때와 rate+value로 변수 의 수를 2배로 증가시켜 학습을 시킨 결과 내가 만든 모델 뿐만 아니라 다른 sklearn 모델들 에서도 성능이 올라감을 확인할 수 있었기 때문이다.
결론적으로 r2score의 값이 0.34403 로 매우 낮게 나왔고, 이는 좋은 학습에 실패하였다고 판단된다. 추후 위에서 말한 에러의 해결책을 찾아서 학습시키는 변수의 개수를 늘려 R2score를 향상시킬 수 있는 방법을 찾아보도록 해야겠다.