Quantile regression(분위수 회귀 분석)이란 통계학과 계량경제학 분야에서 많이 사용 되는 회귀 분석의 한 유형이다.
기존 회귀분석에서는 최소 제곱법을 이용하여 설명 변수에 따른 반응 변수의 조건부 평균을 추정하지만, 분위수 회귀 분석에서는 반응 변수의 조건부 분위수 값을 추정한다.
분위수 회귀 분석은 선형 회귀 분석의 조건이 충족되지 않는 경우 사용할 수 있는 선형 회귀 분석의 확장이다.
Quantile regression 의 장점
예측 값이 정규분포임을 가정한 기존의 선형 회귀분석과 달리, 분위수 회귀 분석에서는 데이터 평균 외부의 변수 관계를 이해할 수 있으므로 비정규 분포를 따르고 예측 변수와 비선형 관계를 갖는 결과를 이해하는 데 유용하다.
그리고 선형 회귀의 가정을 벗어나서 예측 변수에 중요한 영향을 끼치는 요인 식별이 가능하다.
Quantile regression 을 사용 할 때
- 중위수. 혹은 분위수 값을 예측하고 싶을 때
- 선형 회귀의 조건이 맞지 않을 때
- 이상치가 존재할 때
- 잔차가 정규성을 만족하지 않을 때
- 결과 변수 증가에 따른 오차의 분산도 커질 때
기존의 선형 회귀 분석
Linear Regression Model Equation :
$ y_{i} = \beta_{0} + \beta_{1}x_{i1}+\cdots + \beta_{p}x_{ip} $
$where$
$ p $ = the number of regressor variables
$ i $ = a data index
우리가 알다시피 기존의 선형 회귀 분석 방정식은 이러한 형태이다.
최적의 선형 회귀 식을 찾는 과정은 아래 평균 제곱 오차(MSE) 값을 최소화하는 $ \beta $ 추정 값을 구하는 문제로도 풀이 될 수 있다.
Mean Squared Error
$ MSE = \frac{1}{n} \sum_{i=1}^{n}(y_{i} - (\beta_{0} + \beta_{1}x_{i1} +\cdots +\beta_{p}x_{ip}))^{2} $
분위수 회귀 분석
Quantile Regression Model Equation for the $ \tau $th quantile :
$ Q_{\tau}(y_{i}) = \beta_{0}(\tau) + \beta_{1}(\tau)x_{i1} + \cdots + \beta_{p}(\tau)x_{ip} $
$where$
$ p $ : the number of regressor variables
$ i $ : a data index
기존 회귀 분석 방정식에 없던 파라메터 $ \tau $가 추가되어 식이 복잡해 보이지만, 사실은 우리가 알던 기존의 선형 회귀 방정식과 크게 다르지 않다. 쉽게 말해 기존의 조건부 평균 값 예측이 아닌 조건부 분위수 값을 예측하는 문제로 풀이 될 수 있다.
최적의 분위수 방정식을 찾기 위한 과정은 중위수 절대 편차(MAD) 값을 최소화함으로써 찾을 수 있습니다.
Median Absolute Deviation
$ MAD = \frac{1}{n} \sum_{i=1}^{n} \rho_{\tau}(y_{i} - (\beta_{0}(\tau) + \beta_{1}(\tau)x_{i1} +\cdots +\beta_{p}(\tau)x_{ip})) $
$where$
$ p $ : the number of regressor variables
$ i $ : a data index
여기서 $ \rho $ 함수는 오차의 분위수와 전체적인 부호에 따라 오차에 비대칭 가중치를 부여하는 체크 함수이다.
$ \rho $은 아래의 형태를 취함.
* $ \rho_{\tau}(u) = \tau\max(u,0) + (1-\tau)\max(-u,0) $
예제
사용 데이터 : the Magic Bricks House data set (Kaggle)
데이터 설명 : Delhi 지역의 집 정보 데이터
데이터 크기 : 1259 * 12
목적 : Delhi 지역의 집 정보 데이터로 분위수 회귀 분석을 실습해보자
설명 변수: 집의 면적(Area)
반응 변수: 집 값(Price)
- 모듈 세팅
import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
- 데이터 로드
house_data = pd.read_csv('../data/MagicBricks.csv')
- 변수 확인
house_data.info()
- 면적에 따른 집 값 산점도 확인
from pylab import rcParams
rcParams['figure.figsize'] = 20,10
sns.scatterplot(house_data['Area'],house_data['Price'])
- 집 값 변수 히스토그램 확인
sns.distplot(house_data['Price'])
- 집 값 변수 박스 플랏 확인
sns.boxplot(house_data['Price'])
확인 해보면 이상치가 존재 하며, 데이터 분포가 정규 분포와 같지 않은 것을 알 수 있다.
기존의 선형 회귀 분석과 비교 해보기 위해 먼저 선형 회귀 분석부터 실시해 보았다.
기존의 선형 회귀 분석
- 설명 변수와 반응 변수 구분
X = house_data[['Area']]
y = house_data['Price']
- 선형 회귀 모형 구축
from sklearn.linear_model import LinearRegression
lm_model = LinearRegression()
lm_model.fit(X,y)
y_pred = lm_model.predict(X)
- 산점도와 회귀 직선 시각화
plt.scatter(X['Area'], y, color ='gray')
plt.plot(X['Area'], y_pred, color ='red', linewidth=2)
plt.show()
눈으로 보았을 때 데이터의 이상치 때문에 적합이 제대로 이루어지지 않아 보인다.
분위수 회귀 분석
- 분위수 회귀 모형 구축
mod = smf.quantreg('Price ~ Area', house_data)
- 각 분위수에 따른 분위수 회귀 값 저장
quantiles = np.arange(.05,.96,.1) # quantiles = [.05,.15,.25,...,.95]
def fit_model(q):
res = mod.fit(q=q)
return [q, res.params['Intercept'], res.params['Area']] + \
res.conf_int().loc['Area'].tolist()
models = [fit_model(x) for x in quantiles]
models = pd.DataFrame(models, columns=['q', 'a', 'b', 'lb', 'ub'])
- 비교를 위해 최소 기존의 선형 회귀 값도 저장
ols = smf.ols('Price ~ Area', house_data).fit()
ols_ci = ols.conf_int().loc['Area'].tolist()
ols = dict(a = ols.params['Intercept'],
b = ols.params['Area'],
lb = ols_ci[0],
ub = ols_ci[1])
print(models)
print(ols)
분위수 회귀선 및 선형 회귀선 시각화
- 시각화 코드
x = np.arange(house_data.Area.min(), house_data.Area.max(), 50)
get_y = lambda a, b: a + b * x
fig, ax = plt.subplots(figsize=(8, 6))
for i in range(models.shape[0]):
y = get_y(models.a[i], models.b[i])
ax.plot(x, y, linestyle='dotted', label= str(round(0.05 + i*0.1, 2)))
y = get_y(ols['a'], ols['b'])
ax.plot(x, y, color='red', label='OLS')
ax.scatter(house_data.Area, house_data.Price, alpha=.2)
legend = ax.legend()
ax.set_xlabel('Area', fontsize=16)
ax.set_ylabel('Price', fontsize=16);
해당 시각화를 통해 기존의 선형 회귀선은 30번째 백분위수(q=0.3) 아래에 위치함을 알 수 있다. 일반 선형 회귀 모형은 빨간색 실선으로 표시 된다. 이 시각화 플랏을 통해 기존의 선형 회귀 모형과 분위수 모델 간의 비교를 눈으로 확인 가능하다.
다음으로는 다양한 백분위 값에 따른 기울기 상한/하한 추정값($ \hat{\beta} $) 시각화를 실시해보았다.
- 백분위 값에 따른 기울기 추정 값 시각화
n = models.shape[0]
p1 = plt.plot(models.q, models.b, color='black', label='Quantile Reg.')
p2 = plt.plot(models.q, models.ub, linestyle='dotted', color='black')
p3 = plt.plot(models.q, models.lb, linestyle='dotted', color='black')
p4 = plt.plot(models.q, [ols['b']] * n, color='red', label='OLS')
p5 = plt.plot(models.q, [ols['lb']] * n, linestyle='dotted', color='red')
p6 = plt.plot(models.q, [ols['ub']] * n, linestyle='dotted', color='red')
plt.ylabel(r'$\beta_{Area}$')
plt.xlabel('Quantiles of the conditional Price distribution')
plt.legend()
plt.show()
위 그래프는 여러 백분위에 걸친 기울기의 변동 값과 기존 선형 회귀 분석 기울기 추정 값의 비교를 가능하게 한다.
참고
www.statsmodels.org/devel/examples/notebooks/generated/quantile_regression.html
en.wikipedia.org/wiki/Quantile_regression
www.mygreatlearning.com/blog/what-is-quantile-regression/