회귀분석의 소개
Contents
3.2. 회귀분석의 소개#
3.2.1. 단변수 회귀분석#
서로 상관관계가 있는 두가지 데이터가 있으면 한가지 데이터의 값으로부터 다른 하나의 데이터 값을 대략적이나마 유추할 수 있다. 예를 들어 팁데이터에서 총 지불금액 total_bill과 팁 금액 tip은 다음과 같이 하나가 증가하면 다른 하나도 증가하는 양의 상관관계가 있다.
import seaborn as sns
tips = sns.load_dataset("tips")
sns.scatterplot(x="total_bill", y="tip", data=tips)
plt.show()

위 그림을 보면 total_bill 데이터와 tip 데이터가 대략적이나마 직선의 형태를 띄는 것을 알 수 있다. seaborn 패키지에서 제공하는 regplot
함수를 사용하면 total_bill과 tip의 선형 상관관계를 대표하는 직선, 즉 스캐터플롯의 모습과 가장 유사한 직선을 스캐터플롯 위에 표시할 수 있다. 직선의 방정식은 다음과 같다.
이 식에서 tip 데이터 변수를 \(\widehat{\text{tip}}\)이라고 표시한 이유는 이 직선의 방정식으로 계산한 값은 정확한 tip 값과는 다르기 때문이다.
sns.regplot(x="total_bill", y="tip", data=tips,
ci=None, line_kws={"color": "r", "lw": 10, "alpha": 0.5})
plt.show()

statsmodels 패키지를 사용하면 이 직선의 방정식에 들어가는 계수 \(w_0\), \(w_1\) 값을 알아낼 수 있다.
import statsmodels.api as sm
result1 = sm.OLS.from_formula("tip ~ total_bill", tips).fit()
result1.params
Intercept 0.920270
total_bill 0.105025
dtype: float64
위 코드를 작성하는 방법와 결과를 해석하는 방법은 다음 절에서 자세힌 설명한다. 우선은 위 결과로부터 직선의 방정식이 다음과 같다는 것을 알 수 있다.
이 방정식은 total_bill을 입력으로 받아 tip을 출력하는 함수의 방정식이므로 total_bill 값을 입력하면 tip의 대략적인 값인 \(\widehat{\text{tip}}\) 값을 알아낼 수 있다. 이 함수의 식에서 total_bill 에 곱해지는 0.1050이라는 숫자를 total_bill에 대한 가중치(weight)라고 한다. 수식의 처음에 있는 0.9203은 상수항(constant)이라고 한다.
위 함수를 파이썬 함수로 정의하면 다음과 같다.
def reg1(total_bill):
return 0.9203 + 0.1050 * total_bill
예를 들어 total_bill의 값이 30달러이면 방정식으로부터 tip 금액은 약 4.07달러가 된다.
reg1(30)
4.0703
실제로 total_bill이 30달러 근처(29달러 이상 31달러 이하)인 경우의 데이터를 모아서 보면 다음과 같다.
tip_totalbill30 = tips[(tips.total_bill >= 29) & (tips.total_bill <= 31)].tip
tip_totalbill30
44 5.60
116 5.07
125 4.20
155 5.14
187 2.00
210 2.00
219 3.09
239 5.92
Name: tip, dtype: float64
이 데이터의 평균은 4.13달러다. 우리가 위 방정식으로부터 계산한 값과 유사한 것을 알 수 있다.
tip_totalbill30.mean()
4.1275
이렇게 데이터 간의 상관관계를 이용하여 하나의 데이터로부터 다른 데이터의 값을 알아내는 것을 예측(prediction)이라고 한다. 이 때 예측이라는 말에 시간적인 미래(future) 시점의 의미는 없다는 점에 주의한다.
만약 예측하고자 하는 데이터가 수치형 데이터인 경우에는 예측 중에서도 특별히 회귀분석(regression analysis)이라고 한다. total_bill 하나의 데이터를 사용하여 tip 데이터를 예측한 것처럼 예측을 위해 입력하는 데이터가 하나뿐인 경우에는 단변수 회귀분석(univariate regression analysis)이라고 한다.
3.2.2. 다변수 회귀분석#
위에서는 total_bill이라는 하나의 데이터만을 사용하여 tip을 계산하였지만 tip과 상관관계가 있는 다른 데이터가 있다면 그 값도 동시에 사용할 수 있다. 예를 들어 size와 tip도 서로 약간의 상관관계를 가지고 있다.
from scipy.stats import pearsonr
pearsonr(tips["size"], tips["tip"])
(0.4892987752303571, 4.3005433272249695e-16)
sns.regplot(x="size", y="tip", data=tips)
plt.show()

total_bill과 size 두 가지 값을 모두 입력값으로 하여 tip을 예측하려면 다음 방정식을 이용해야 한다.
위 방정식의 계수 \(w_0, w_1, w_2\)는 다음과 같이 계산한다.
result2 = sm.OLS.from_formula("tip ~ total_bill + size", tips).fit()
result2.params
Intercept 0.668945
total_bill 0.092713
size 0.192598
dtype: float64
위 코드에 대해서도 다음 절에서 설명한다. 일단은 위 결과로부터 우리가 원하는 방정식은 다음과 같다는 것을 알 수 있다.
이 식에서 total_bill에 대한 가중치는 0.0927, size에 대한 가중치는 0.1926, 상수항은 0.6689라는 것을 알 수 있다.
이 함수를 파이썬 함수로 정의하면 다음과 같다.
def reg2(total_bill, size):
return 0.6689 + 0.0927 * total_bill + 0.1926 * size
이 함수를 이용하여 total_bill=30, size=4 인 경우 즉, 4인 고객이 30달러를 지불하는 경우의 팁을 계산하면 4.22달러다.
reg2(30, 4)
4.2203
실제로 해당 경우의 데이터를 구하면 다음과 같다.
idx = (tips.total_bill >= 29) & (tips.total_bill <= 31) & (tips["size"] == 4)
tip_totalbill30size4 = tips[idx].tip
tip_totalbill30size4
44 5.60
116 5.07
219 3.09
Name: tip, dtype: float64
평균값은 4.59달러로 우리가 계산한 4.22달러와 비슷하다.
tip_totalbill30size4.mean()
4.586666666666667
이 예에서는 2개의 데이터를 입력으로 사용하여 예측을 하였지만 상관관계가 있는 데이터가 더 있다면 이보다 많은 종류의 데이터를 사용하여 회귀분석을 할 수도 있다. 이와 같이 복수의 데이터 값으로부터 다른 수치형 데이터의 값을 구하는 것을 다변수 회귀분석(multivariate regression analysis)이라고 한다.
3.2.3. 독립변수와 종속변수#
회귀분석을 하려면 우선 우리가 값을 예측하려는 수치형 데이터와 그 데이터를 계산하기 위해 사용하는 데이터들이 무엇인지를 결정해야 한다. 회귀분석에서 분석의 대상이 되는 수치형 변수를 종속변수(independent variable)라 하고 그 종속변수에 영향을 주는 다른 변수들을 독립변수(dependent variable)라 한다. 수식으로 표현할 때 종속변수는 \(y\) 기호로 나타내고 독립변수는 \(x\) 기호로 나타낸다. 독립변수가 여러개 있을 때는 \(x_1, x_2, \ldots, x_K\) 등으로 아랫첨자를 이용하여 표시한다.
위에서 보인 첫번째 회귀분석 예에서는 독립변수와 종속변수가 다음과 같았다.
독립변수
\(x_1\) : total_bill
종속변수
\(y\) : tip
두번째 회귀분석 예의 독립변수와 종속변수는 다음과 같았다.
독립변수
\(x_1\) : total_bill
\(x_2\) : size
종속변수
\(y\) : tip
3.2.4. 회귀분석#
수학적으로 회귀분석을 정의할 수 있는 방법도 여러가지가 있다. 가장 간단한 정의는 \(N\)개의 데이터 쌍 \(\{x_i, y_i\}\)가 있을 때 이 데이터와 가장 비슷한 함수
를 찾아내는 것이다. 가장 비슷하다는 것은 다음과 같이 정의한다.
우리가 가지고 있는 \(N\)개의 데이터 중 \(i\)번째 데이터 \(x_i\)를 이 함수에 넣으면 함수의 결과 즉, 회귀분석 예측값 \(\hat{y}_i\)이 나온다.
이 예측값 \(\hat{y}_i\)은 \(x_i\)에 대응하는 원 데이터 \(y_i\)값과 차이가 있을 수 있다. 이 차이를 잔차(residual)라고 한다.
\(N\)개의 모든 데이터에 대해 이를 반복하면 \(N\)개의 잔차값이 나온다. 이 모든 잔차를 제곱하여 더한 것을 잔차제곱합(RSS: Residual Sum of Squares)이라고 한다.
잔차제곱합 RSS가 작을수록 회귀분석으로 구한 예측값 \(\hat{y}_i\)값이 원래 데이터 \(y_i\)값이 비슷하다는 뜻이므로 좋은 함수가 된다. 회귀분석은 미리 정해놓은 여러가지 함수들 중에서 가장 잔차제곱합이 작은 함수를 찾는 과정이다.
위에서 보인 첫번째 회귀분석 예에서 잔차제곱합을 구해보자. 우선 회귀분석 함수에서 \(\hat{y}\)를 구하면 다음과 같다.
y_hat = reg1(tips.total_bill)
y_hat
0 2.70425
1 2.00600
2 3.12635
3 3.40670
4 3.50225
...
239 3.96845
240 3.77420
241 3.30065
242 2.79140
243 2.89220
Name: total_bill, Length: 244, dtype: float64
원래의 tip 값에서 이 값을 빼면 잔차 \(e\)를 구할 수 있다.
e = tips.tip - y_hat
e
0 -1.69425
1 -0.34600
2 0.37365
3 -0.09670
4 0.10775
...
239 1.95155
240 -1.77420
241 -1.30065
242 -1.04140
243 0.10780
Length: 244, dtype: float64
이 잔차들을 제곱하여 합한 잔차제곱합 RSS를 구하면 약 252.7888이다.
(e ** 2).sum()
252.78880587749998
3.2.5. 선형회귀분석#
이제 회귀분석 중에서 가장 널리 사용되는 선형회귀분석(linear regression analysis)에 대해 설명한다.
3.2.5.1. 선형회귀분석 모형#
선형회귀분석에서는 현실세계의 데이터가 다음과 같은 규칙을 따른다고 가정한다.
당연히 이 규칙은 진짜로 존재하는 것이 아니라 우리가 가정한 것일 뿐이므로 정확하게는 회귀분석 모형(regression model) 혹은 간단히 모형이라고 부른다.
이 모형 식에서 \(x_1, x_2, \ldots, x_K\)는 \(K\)개의 독립변수의 값이고 \(w_0, w_1, \ldots, w_K\)는 상수항을 포함한 가중치다. 독립변수의 값은 데이터 표본마다 바뀔 수 있지만 가중치는 항상 변하지 않는 고정된 값이다. 가중치와 독립변수로 이루어진
부분을 독립변수의 선형조합(linear combination)이라고 한다. 선형조합 부분의 값은 독립변수의 값과 가중치만 알면 정확하게 계산할 수 있다.
위 모형 식에서 가장 끝에 있는 \(\varepsilon\)은 교란항(disturbance)이라고 하며 값을 예측할 수 없는 확률변수이다. 따라서 위 모형을 해석하면 다음과 같은 의미가 된다.
선형회귀분석의 가정
종속변수 \(y\)의 값은 독립변수 \(x_1, x_2, \ldots, x_K\) 값의 선형조합으로 어느 정도 결정되지만 이것만으로 예측할 수 없는 부분이 존재한다.
3.2.5.2. 가중치의 의미#
선형회귀분석에서 가중치는 독립변수가 종속변수에 미치는 영향을 정량화한 것이다. 수식으로 보면 독립변수 \(x_1\)이 단위크기 1만큼 커지면 종속변수 \(y\)는 가중치 \(w_1\)만큼 커진다. 가중치가 크면 독립변수가 변했을 때 종속변수가 받는 영향이 크다는 뜻이다. 만약 가중치의 부호가 음수이면 독립변수가 증가했을 때 종속변수는 증가하는게 아니라 감소한다. 만약 가중치가 0이라면 해당 독립변수가 증가하든 감소하든 종속변수는 영향을 받지 않는다.
독립변수가 1개인 선형회귀분석의 경우에는 모형이 다음과 같아진다.
이 수식에서 선형조합부분만 보면 y절편이 \(w_0\)이고 기울기가 \(w_1\)인 직선의 방정식과 같으므로 그림으로 표현하면 다음과 같다.

3.2.5.3. 선형회귀분석의 1차적 목적#
선형회귀분석의 1차적인 목적은 바로 이 가중치 \(w_0, w_1, \ldots, w_K\)을 알아내는 것이다. 하지만 우리는 어떠한 선형회귀분석 방법으로 이 값을 100% 정확하게는 알아낼 수 없다. 우리가 선형회귀분석으로 알아낸 값은 가중치 \(w_0, w_1, \ldots, w_K\)에 대한 추정값 \(\hat{w}_0, \hat{w}_1, \ldots, \hat{w}_K\)일 뿐이다. 이 가중치의 추정값 \(\hat{w}_j\)는 원래 가중치 \(w_j\)와 같은 값이라는 보장이 없다.
이를 그림으로 표현하면 다음과 같다.

3.2.5.4. 선형회귀분석을 사용한 종속변수 예측#
선형회귀분석의 최종 목적은 독립변수의 값이 주어졌을 때 종속변수의 값을 예측하는 것이다. 이 때는 다음 수식을 사용하게 된다.
이 예측치 \(\hat{y}\)값은 두가지 측면에서 원래의 \(y\)값과 달라진다.
가중치 \(w\)를 정확하게 예측하더라도 교란항(disturbance) \(\varepsilon\)만큼 차이가 있다.
그런데 가중치 \(w\) 자체도 정확하게 예측하지 못하고 이에 대한 추정값 \(\hat{w}\)을 사용하므로 선형조합 부분도 원래의 선형조합 부분과 차이가 있다.
이렇게 발생하는 원래의 \(y\)값과 예측치 \(\hat{y}\)의 차이를 잔차(residual) \(e\)라고 한다.
이를 그림으로 표현하면 다음과 같다. 그림에서 교란항과 잔차가 다르다는 점에 유의하라.
