회귀분석(단순회귀)

선형모델은 100여년 전부터 사용되어 왔고 현재도 널리 사용되는 모델입니다. 이 모델은 입력 특성에 대한 선형함수 모델을 만들어서 예측을 수행하는 모델입니다. 간단히 직선의 방정식을 생각하면 됩니다. 기울기 w와 y축과 만나는 절편 b 값을 알아내는 것이 해당 모델의 핵심이라고 할 수 있습니다.

예를 들어 아래와 같은 fitness.csv 데이터셋이 있다고 가정해봅니다. 해당 데이터는 [‘age’, ‘weight’, ‘oxygen’, ‘runtime’, ‘runpulse’, ‘rstpulse’,’maxpulse’]의 7개의 Feature로 되어 있습니다. pandas 패키지로 파일을 읽어서 상위 10개의 데이터를 표시해봅니다.

dataset = pd.read_csv('./fitness.csv')
dataset[0:10]

각각의 column 혹은 feature 정보는 관계가 있을 수도 혹은 별다른 관계가 없을 수도 있습니다. 예를 들어서 위의 feature 정보를 통해서 아래와 같이 3개의 산점도(scatter)를 그려보면 1번은 두개의 변수간에 상관관계가 약하다고 할 수 있지만 아래의 두개 즉, runpulse-maxpulse, oxygen-runtime은 어느정도 상관관계가 있다고 할 수 있습니다. 이것을 방향에 따라서 양의 상관관계, 음의 상관관계라고 할 수 있습니다.

2번째 그래프와 같이 runpulse과 maxpulse의 관계를 통해서 본다면 runpulse 값이 증가할 수록 maxpulse 값도 함께 증가하는 것을 알 수 있습니다. 그렇기 때문에 이런 관계를 통해서 어떤 규칙성을 만들면 runpulse가 주어졌을 때 maxpulse를 어느정도는 예측할 수 있습니다. 이것을 통계적인 용어로 보면 독립변수인 runpulse의 변화에 따른 종속변수인 maxpulse의 상관관계를 파악하는 것이라고 할 수 있습니다.

fig, axes = plt.subplots(3,1,figsize=(10,12))
axes[0].set_title('runtime - maxpulse')
axes[0].scatter(dataset['runtime'],dataset['maxpulse'])

axes[1].set_title('runpulse - maxpulse')
axes[1].scatter(dataset['runpulse'],dataset['maxpulse'])

axes[2].set_title('oxygen - runtime')
axes[2].scatter(dataset['oxygen'],dataset['runtime'])

회귀분석을 위해서는 특정 독립 변수 값에 해당하는 종속변수의 값이 정규분포를 이뤄야합니다. 그래야 어떤 규칙성을 발견할 수 있습니다. 또 종속변수들의 값은 서로 독립적이어야 하는데 만일 그렇지 않으면 어떤 부분이 종속변수에 영향을 미치는지 발견하기가 어렵습니다. 이에 대한 연장으로 독립변수가 여러 개인 경우 변수간에 영향을 주지 않아야 합니다.

이런 이유로 회귀분석을 생각해 보면 아래의 표와 같이 독립변수의 수, 척도, 관계 등에 의해 회귀분석의 종류를 나눌 수 있습니다.

이훈영의 연구방법론, p.400

아래의 runpulse-maxpulse 그래프를 다시 살펴보면 데이터의 어떤 규칙성을 발견할 수 있습니다. 이제 이 데이터를 특징을 가장 잘 나타내는 직선을 긋는다고 생각해보겠습니다.

사람은 직관에 의해서 선을 한번에 그을 수 있습니다. 비록 정확하진 않더라도 정답과 비슷한 모양으로 선을 그을 수 있지만 컴퓨터는 그렇게 할 수 없습니다. 선형회귀는 바로 컴퓨터가 점들을 잘 표현하는 직선(Y = Xw + b)을 그리는 과정이라고 할 수 있습니다. 여기서 궁금한 것이 바로 w와 b 값입니다.

그중에서 가장 많이 사용하는 알고리즘을 sklearn에서 구현한 LinearRegression을 통해서 runpulse-maxpulse 회귀분석을 구현해보겠습니다. 구현은 생각보다 간단합니다. sklearn 패키지는 이런 복잡한 작업들을 단 2줄에 해결 할 수 있도록 편리한 함수를 제공해줍니다.

from sklearn.linear_model import LinearRegression
lr = LinearRegression().fit(dataset['runpulse'].values.reshape(-1,1),dataset['maxpulse'].values.reshape(-1,1))
print('W:{}, b:{}'.format(lr.coef_, lr.intercept_))
# W:[[0.83109283]], b:[32.78331594]

간단히 우리가 구하고자 하는 w, b 값을 구했습니다. 이제 두개의 미지수를 찾았으니 어떤 X 입력 값에 대해서 Y(여기서는 maxpulse)를 쉽게 예측할 수 있습니다. 실제로 데이터 예측을 해보겠습니다. fitness.csv 데이터가 많다면 훈련용 셋과 테스트 셋을 나눠서 정확도를 보겠지만 원본 데이터의 갯수가 30개라서 테스트용 데이터를 나누지 않고 위의 값 중에서 없는 runpulse 값을 찾고 이때에 maxpulse를 예측해보겠습니다.

dataset.loc[(dataset['runpulse']>=178) & (dataset['runpulse']<=180)]

위와 같은 조건으로 검색해보니 179가 없는 것을 확인했습니다. 179를 입력했을 때에 180과 185 사이의 값으로 예측된다면 예측 모델이 비교적 정확하다고 할 수 있겠습니다.

y_hat = lr.predict([[179]])
#array([[181.54893295]])

예측 결과 181.54 정도가 나와서 비교적 합리적인 값을 도출해냈습니다. 이렇게 해도 되고 y=Xw+b의 식에 값을 대입해도 동일한 y 값을 얻을 수 있습니다.

plt.plot(dataset['runpulse'],lr.predict(dataset['maxpulse'].values.reshape(-1,1)),'*')
plt.plot(dataset['runpulse'],dataset['maxpulse'],'x')

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다