주피터를 이용한 선형 회귀

박건우
Research Team — DAWN
6 min readJul 30, 2021

--

주피터를 이용하여 알고리즘 기초를 공부하면서 잘 이해가 가지 않은 부분을 글로 쓰며 정리해보고자 한다 글의 주제는 선형회귀로 다중선형회귀, 다항 회귀 와 많은 연관이 있으며 중요하기 때문에 글의 주제로 선정하였다

선형 회귀 (Linear Regression) : 데이터를 가장 잘 대변해 주는 선을 찾아내는 것 이와 같은 선을 통계학 에서는 ‘최적선(line of best fit)’ 이라고 한다 선형회귀는 단순하고, 유용하여 다른 많은 알고리즘의 기반이 된다 우리가 맞추려고 하는 값을 ‘목표 변수’, 영어로는 ‘target variable’, 또는 ‘output variable’이라고도 한다 목표 변수를 맞추기 위해서 사용하는 값을 ‘입력 변수’, 영어로는 ‘input variable’이라고 하며 일반적으로는 ‘feature’라고도 한다 Feature를 한국말로 하면 ‘특징’, ‘속성’… 의미를 가지고 있다
예를 들어서 지하철역과의 거리를 갖고 집의 가격을 예측하려고 하면 집과 지하철역 사이의 거리가 입력 변수, 집 가격이 목표 변수가 되며 거리라는 속성을 이용해서 집 가격을 예측한다

최적선을 찾아내기 위해서는 다양한 함수를 시도해 봐야 한다 우리가 시도하는 이 함수 하나하나를 ‘가설 함수’(hypothesis function)이라고 하며 선형회귀의 가설함수는

이와 같이 표현하며 가장 적절한 세타 값을 찾아 내는 것이 선형회귀의 임무이다

선형 회귀에서 가설 함수를 평가하는 방법중 가장 많이 사용하는 ‘평균 제곱 오차’(mean squared error) 라고 한다 평균 제곱 오차라는 건, 이 데이터들과 가설 함수가 평균적으로 얼마나 떨어져 있는지 나타내기 위한 하나의 방식이다 예측한 값과 실제 값의 차를 구하고 제곱을 통해 오차를 추정하는 것이다 평균 제곱 오차가 크다는 건 가설 함수와 데이터들 간의 오차가 크다는 거고, 결국 그 가설 함수는 데이터들을 잘 표현해 내지 못한 함수를 말하는 것이다
평균 제곱 오차를 일반화해서 수학적으로 표현하면 같이 표현할수 있다

손실 함수는 어떤 가설 함수를 평가하기 위한 함수이며 손실 함수의 아웃풋이 작을수록 가설 함수의 손실이 적기 때문에 더 좋은 가설 함수라고 할 수 있고, 반대로 손실 함수의 아웃풋이 클수록 가설 함수의 손실이 큰 거기 때문에 더 나쁜 가설 함수라고 할 수 있다
손실 함수는 보통 J라는 문자를 쓰고 선형 회귀의 경우에는 평균 제곱 오차가 손실 함수의 아웃풋이다 특정 가설 함수의 평균 제곱 오차가 크면 이 손실 함수의 아웃풋이 크다는 거고, 그러면 손실이 크기 때문에 안 좋은 가설 함수이고 가설 함수의 평균 제곱 오차가 작으면 이 손실 함수의 아웃풋이 작다는 거고, 그러면 손실이 적기 때문에 좋은 가설 함수이다
손실 함수 J의 인풋은, 바로 세타이며 세타 값들을 잘 조율해서, 가장 적합한 가설 함수를 찾아내야 한다 결국 손실 함수의 아웃풋은 이 세타 값들을 어떻게 설정하느냐에 달려 있다

손실함수의 아웃풋 최소화를 찾기 위해서 ‘경사하강법’(Gradient Descent)을 이용한다 경사의 방향과 크기를 이용해서 극소점으로 내려가는 방법이다 예를 들어 손실함수의 인풋(쎄타)이 2개일경우는 3차원 곡선이 된다 3차원 곡선에서도 최소점을 찾아야 하므로 편미분을 이용하여 결과식을 구한 후 현재 위치의 좌표를 대입하여 이것을 벡터로 만들어 만들어진 기울기 벡터가 현재위치의 기울기로 나타낼 수 있다 가장 가파르게 내려가는 벡터를 계속 찾아내어 최소점(극소점)을 찾는것이다

위의 내용을 주피터로 정리하면

# 필요한 라이브러리 import
from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error

import pandas as pd

# 보스턴 집 데이터 갖고 오기
boston_house_dataset = datasets.load_boston()
<13개의 입력변수와 1개의 목표변수로 구성된 sklearn에 내장된 데이터>

# 입력 변수를 사용하기 편하게 pandas dataframe으로 변환
X = pd.DataFrame(boston_house_dataset.data, columns=boston_house_dataset.feature_names)

# 목표 변수를 사용하기 편하게 pandas dataframe으로 변환
y = pd.DataFrame(boston_house_dataset.target, columns=[‘MEDV’])

# 범죄율 열만 사용
X = X[[‘CRIM’]]

# train_test_split를 사용해서 주어진 데이터를 학습, 테스트 데이터로 나눈다
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state=5)

model = LinearRegression() # 선형 회귀 모델을 가지고 오고

model.fit(X_train, y_train) # 학습 데이터를 이용해서 모델을 학습 시킨다

model.coef_ # 쎄타 1의 값이 나오고
model.intercept_ #쎄타 0의 값이 나온다
# F(x) = 24.12202188–0.41546547x (선형회귀 함수)

y_test_predict = model.predict(X_test) # 학습시킨 모델로 예측

# 평균 제곱 오차의 루트를 통해서 테스트 데이터에서의 모델 성능 판단
mse = mean_squared_error(y_test, y_test_predict)

# 테스트 코드 (평균 제곱근 오차로 모델 성능 평가)
mse = mean_squared_error(y_test, y_test_predict)

mse ** 0.5
= 8.180697228317348 ( 약 8천 달러의 오차가 발생할 수도 있다)

--

--