선형 회귀((Linear Regression))는 머신러닝 기초 알고리즘입니다. 복잡한 알고리즘에 비해서는 예측력이 떨어지지만 데이터 특성이 복잡하지 않을때는 쉽고 빠른 예측이 가능하기 때문에 많이 사용됩니다. 다른 모델과의 성능을 비교하는 베이스라인으로 사용하기도 합니다.
이번에는 선형 회귀 모델로 보험 데이터셋을 학습해 보험료를 예측하고, 선형 회귀의 작동 원리를 이해합니다. 총 4편으로 준비했습니다. 2편은 전처리와 모델링입니다.
전처리 : 학습셋과 시험셋 나누기
일반적으로 데이터를 손보는 데에 상당한 시간을 들여야 하지만 첫 장이니만큼 이미 정리된 데이터를 사용하겠습니다(그래서 데이터를 정제하는 작업인 데이터 클리닝 및 피처 엔지니어링을 생략합니다). 모델링에 들어가기 앞서 데이터를 나누는 작업을 할 것인데, 우선 왜 굳이 데이터를 나누어야 하는지를 알아보겠습니다.
💡 데이터 클리닝 및 피처 엔지니어링: 데이터 클리닝은 지저분한 데이터를 정리하는 과정입니다. 이는 결측치를 처리하는 과정부터, 오탈자 수정, 불필요한 문자 제거 등을 포괄합니다. 피처 엔지니어링은 가지고 있는 독립변수들을 활용해서 더욱 풍성하고 유용한 독립변수들을 만들어 내는 작업입니다.
데이터를 나누는 작업은 크게 2가지 차원으로 진행됩니다. 첫째는 종속변수와 독립변수 분리입니다. 둘째는 학습용 데이터셋인 학습셋(Train set)과 평가용 시험셋(Test set)을 나누는 겁니다. 이렇게 2×2조합으로 총 4개 데이터셋으로 나눕니다.
변수와 데이터셋을 나누는 이유
기본적으로 지도 학습에 속하는 머신러닝 모델은 독립변수를 통하여 종속변수를 예측하는 것이므로, 모델링할 때 어떤 변수가 종속변수인지 명확히 알려주어야 합니다. 이런 이유로 많은 머신러닝 알고리즘이 독립변수와 종속변수를 각각 별도의 데이터로 입력받습니다.
그렇다면 학습셋과 시험셋을 나누는 이유는 무얼까요? 예를 들어 학습셋과 시험셋을 구분하지 않고 예측 모델을 만든다고 가정해보겠습니다. 전체 데이터를 가지고 모델링( 학습)을 하고, 또 다시 전체 데이터에 대해서 예측값을 만들어서 종속변수와 비교해 예측이 잘 되었는지 평가한다고 합시다. 그 평가 결과가 어느 정도 괜찮았다고 해서 새로운 데이터에 대해서도 좋은 예측력을 보일까요? 보험 청구비를 예측하는 모델을 만들고 새로운 고객 정보(독립변수들)를 받아서 예측을 했을때,실제발생하는보험청구비를제대로잘예측할수있을지는장담할수없습니다.
왜 장담할 수 없냐하면 학습에 사용한 데이터와 평가용으로 사용한 데이터가 동일하다는 것은 모델을 만들고 나서 새로운 데이터에도 맞는지 검증하지 않은 거나 다름 없기 때문입니다.
이러한 (검증하지 않은 상태라는) 불확실성을 줄일 목적으로 준비하는 것이 시험셋입니다. 예를들어 1338개 데이터 중 1000개는 학습셋으로 나누어서 모델을 학습시키는 데 사용하고, 나머지 338개 데이터는 모델 학습이 완료된 이후에 평가용으로 사용할 수 있습니다. 이렇게 하면 학습된 모델에 있어 시험셋의 338개 데이터는 처음 만나게 되는 데이터인 겁니다. 시험셋으로 예측/평가를 했을 때도 예측력이 좋게 나타난다면, 향후 예측하게 될 새로운 데이터에 대해서도 잘 작동할 거라는 기대를 가질 수 있습니다.
이와 같은 이유로 학습셋과 시험셋을 나눕니다. 일반적으로 학습셋:시험셋을 각각 7:3 혹은 8:2 정도 비율로 나눕니다. 비율은 데이터 크기에 따라 달라지기 마련인데, 전체 데이터 크기가 작을수록 시험셋 비율을 낮게 잡습니다. 두 데이터셋 중에 더 중요한 쪽을 따지자면 학습셋입니다. 실제 모델을 만드는 데 사용되는 데이터이기 때문에 충분한 양이 보장되지 않으면 모델 학습이 제대로 진행되지 않을 수 있습니다.
따라서 전체 데이터 크기가 작다면, 학습셋의 비율을 높여서 최대한 학습셋을 많이 확보해야 합니다. 때에 따라서는 9:1의 비율도 가능하며, 반대로 데이터가 아주 방대할 때는 6:4나 5:5로 나눌 수도 있습니다. 비율은 경험적으로 판단하는 영역이기 때문에 정답을 말씀드릴 순 없습니다. 앞으로 이 책으로 공부하다 보면 적당한 비율에 대한 감을 잡을 수 있게 될 겁니다. 정답이 없기 때문에, 실제 분석을 하면서 비율을 수정해가며 다양한 시도를 해야 합니다.
데이터셋 나누기
이제 데이터셋을 나누어보겠습니다. 우선 종속변수와 독립변수를 나눈 후에 학습셋과 시험셋으로 나누겠습니다.
우선 독립변수를 X, 종속변수를 y로 나누겠습니다.
X = data[['age', 'sex', 'bmi', 'children', 'smoker']] # 독립변수
y = data['charges'] # 종속변수
통상적으로 이런 상황에서 X는 대문자, y는 소문자로 쓰는데, X는 변수가 여러 개 있는 데이터프레임(DataFrame)이기 때문에 대문자로, y는 변수가 하나인 시리즈Series이기 때문에 소문자로 씁니다. 관용적인 표현일 뿐, 다르게 쓴다고 해도 코드에서 문제는 없습니다.
그럼 이제 학습셋과 시험셋을 나누어줄 텐데 사이킷런(Sklearn)에서는 관련 모듈(train_test_split)을 제공하므로 모듈을 불러옵시다.
from sklearn.model_selection import train_test_split # 사이킷런 임포트
데이터셋을 분할합시다.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2,random_state=100) # 데이터셋 분할
독립변수/종속변수, 그리고 학습셋/시험셋 조합으로 총 4개 데이터셋(X_train, X_test, y_train, y_test)이 나왔습니다.
= 왼쪽(좌항)에 보통은 변수가 하나이기 마련인데 여기에서는 4개나 들어 있습니다. 이런 형태 코드가 조금 낯설 수 있습니다. 이 부분은 나중에 함수를 만드는 연습을 할 때 더 구체적으로 설명하겠지만, 여기서 간단히 말씀드리자면, train_test_split( ) 이라는 함수가 데이터셋 4개를 결과물로 내보내므로, 이를 받아줄 변수 4개가 필요합니다.
= 오른쪽 코드(우항)를 살펴보겠습니다. 괄호 안에 독립변수(X)와 종속변수(y)를 순서대로 입력해야 합니다. 다음은 test_size인데, 시험셋의 비율을 의미합니다. 여기에서는 0.2를 넣었으므로 20%, 즉 8:2로 데이터를 나누겠다는 의미입니다. 마지막으로 random_state는 랜덤 샘플링과 관련이 있는데, 우선 랜덤 샘플링을 알아봅시다.
기본적으로 train_test_split( ) 함수는 랜덤 샘플링을 지원합니다. 랜덤 샘플링은 데이터를 특정 비율로 나눌 때 마구잡이로 뒤섞어서 나누는 겁니다. 만약 랜덤 샘플링을 사용하지 않으면 데이터를 있는 순서 그대로 분할합니다. 예를 들어 1338개 데이터의 앞에서부터 80%가 학습셋이 되고, 뒷부분인 나머지 20%가 시험셋이 됩니다. 이 데이터에서는 크게 문제가 없을 수 있습니다만, 종종 데이터가 특정 순서로 정렬된 경우도 있습니다. 예를 들어 데이터 앞쪽에는 여자, 뒷쪽에는 남자를 두는 식으로 정리를 해둘 수 있죠. 이런 식으로 특정 기준에 따라 정렬된 데이터를 순서대로 분류해버리면 학습셋과 시험셋의 특징이 확연히 다를 수밖에 없습니다. 샘플링된 데이터셋은 그 특성이 최대한 전체 데이터셋과 비슷하게 유지되어야 하기 때문에 위험한 방식입니다. 이와 같은 이유로 랜덤 샘플링을 일반적으로 널리 사용합니다. train_test_split( ) 함수는 기존 데이터의 순서와 상관없이 마구잡이로 섞어서 데이터를 분류시킵니다. 그렇기 때문에 매번 실행할 때마다 train_set과 test_set에 들어가는 데이터가 달라집니다.
학습셋과 시험셋 각각에 들어가는 데이터가 매번 달라져도 랜덤 샘플링만 잘됐다면 크게 상관없을 수도 있습니다. 하지만 우리가 분석을 하다 보면 결과의 일관성을 유지해야 할 필요가 있습니다. 내가 작성한 코드를 동료에게 공유했는데, 동료가 같은 코드를 돌리고 나와 다른 결과를 보게 된다면 뭔가 이상할 수밖에 없습니다. train_test_split( ) 함수는 랜덤하게 샘플링하면서도, 지속적으로 같은 데이터 분류를 지원합니다. 바로 random_state 옵션을 사용하면 됩니다. 여기에는 그 어떤 임의의 숫자를 넣어도 상관없습니다. 같은 숫자라면 같은 형태로 분류된 데이터셋들을 얻게 됩니다. 여기에서는 100을 넣어서 나누었습니다. 여러분이 다른 숫자를 넣는다면, 결괏값이 책과 조금 다르게 나타날 겁니다. 똑같이 100을 입력하면 같은 결과를 볼 수 있습니다(간혹 패키지 버전 차이로 결과가 미세하게 다른 경우도 있습니다).
모델링
모델링은 머신러닝 알고리즘으로 모델을 학습시키는 과정이며, 그 결과물이 머신러닝 모델이 됩니다. 모델링에 사용할 머신러닝 알고리즘을 선택하고, 독립변수와 종속변수를 fit( ) 함수에 인수로 주어 학습합니다.
이번 데이터셋에는 선형 회귀 알고리즘을 사용합니다. 따라서 sklearn.linear_model에서 선형 회귀 라이브러리를 불러옵니다.
from sklearn.linear_model import LinearRegression
이제 모델을 만들어주어야 합니다. 여기서는 model이라는 이름의 객체에 선형 회귀의 속성을 부여하겠습니다.
model = LinearRegression()
선형 회귀에 사용할 model 객체를 생성했으니 model 객체를 사용해서 선형 회귀로 학습하고 예측할 수 있게 됩니다(물론 객체 이름을 model 대신 다른 이름으로 지어도 됩니다).
모델을 학습시킬 객체가 준비가 되었으니 학습을 시키는 fit( ) 함수를 알아보겠습니다.
model.fit(독립변수, 종속변수)
fit( ) 함수의 인수로 독립변수와 종속변수를 입력합니다. 이미 데이터를 나누었기 때문에 쉽게 독립변수와 종속변수를 나눠 입력할 수 있습니다. 학습 과정이므로 학습셋을 사용합니다.
model.fit(X_train, y_train)
여기서 ‘학습시킨다’함은, 데이터를 모델 안에 넣어서 독립변수와 종속변수 간의 관계들을 분석해 새로운 데이터를 예측할 수 있는 상태로 만드는 겁니다. 이로써 model은 데이터를 통해 학습을 완료해 예측을 할 수 있게 되었습니다.
3편을 ‘모델을 활용해 예측하기와 예측 모델 평가하기‘입니다.
삼성전자에 마케팅 직군으로 입사하여 앱스토어 결제 데이터를 운영 및 관리했습니다. 데이터에 관심이 생겨 미국으로 유학을 떠나 지금은 모바일 서비스 업체 IDT에서 데이터 사이언티스트로 일합니다. 문과 출신이 미국 현지 데이터 사이언티스트가 되기까지 파이썬과 머신러닝을 배우며 많은 시행착오를 겪었습니다. 제가 겪었던 시행착오를 덜어드리고, 머신러닝에 대한 재미를 전달하고자 유튜버로 활동하고 책을 집필합니다.
현) IDT Corporation (미국 모바일 서비스 업체) 데이터 사이언티스트
전) 콜롬비아 대학교, Machine Learning Tutor, 대학원생 대상
전) 콜롬비아 대학교, Big Data Immersion Program Teaching Assistant
전) 콜롬비아 대학교, M.S. in Applied Analytics
전) 삼성전자 무선사업부, 스마트폰 데이터 분석가
전) 삼성전자 무선사업부, 모바일앱 스토어 데이터 관리 및 운영
강의 : 패스트캠퍼스 〈파이썬을 활용한 이커머스 데이터 분석 입문〉
SNS : www.youtube.com/c/데싸노트