from sklearn.preprocessing import OneHotEncoder
encoder = OneHotEncoder()

x0 = np.random.choice(3, 10)
x0

encoder.fit(x0[:, np.newaxis])
X = encoder.transform(x0[:, np.newaxis]).toarray()
X

dfX = pd.DataFrame(X, columns=encoder.active_features_)
dfX

"""
Explanation: 분산 분석 기반의 카테고리 분석
회귀 분석 대상이 되는 독립 변수가 카테고리 값을 가지는 변수인 경우에는 카테고리 값에 의해 연속 변수인 y값이 달라진다. 이러한 경우, 분산 분석(ANOVA)을 사용하면 카테고리 값의 영향을 정량적으로 분석할 수 있다. 또한 이는 카테고리 값에 의해 회귀 모형이 달라지는 것으로도 볼 수 있기 때문에 모형 비교에도 사용될 수 있다.
카테고리 독립 변수와 더미 변수
카테고리 값은 여러개의 다른 상태를 나타내는 값이다. 분석시에는 편의상 이 값은 0, 1과 같은 정수로 표현하지만 원래 카테고리값은 1, 2, 3과 같이 숫자로 표현되어 있어도 이는 단지 "A", "B", "C"라는 라벨을 숫자로 대신 쓴 것에 지나지 않으며 실제로 크기의 의미가 없다는 점에 주의해야 한다. 즉, 2라는 값이 1보다 2배 더 크다는 뜻이 아니고 3이라는 값도 1보다 3배 더 크다는 뜻이 아니다.
따라서 카테고리 값을 그냥 정수로 쓰면  회귀 분석 모형은 이 값을 크기를 가진 숫자로 인식할 수 있는 위험이 있기 때문에 반드시 one-hot-encoding 등을 통해 더미 변수(dummy variable)의 형태로 변환해야 함
더미 변수는 0 또는 1만으로 표현되는 값으로 어떤 요인이 존재하는가 존재하지 않는가를 표시하는 독립 변수이다. 다음과 같은 명칭으로도 불린다.

indicator variable
design variable
Boolean indicator
binary variable
treatment
End of explanation
"""


from sklearn.datasets import load_boston
boston = load_boston()
dfX0_boston = pd.DataFrame(boston.data, columns=boston.feature_names)
dfy_boston = pd.DataFrame(boston.target, columns=["MEDV"])

import statsmodels.api as sm
dfX_boston = sm.add_constant(dfX0_boston)

df_boston = pd.concat([dfX_boston, dfy_boston], axis=1)
df_boston.tail()

dfX_boston.CHAS.plot()
dfX_boston.CHAS.unique()

model = sm.OLS(dfy_boston, dfX_boston)
result = model.fit()
print(result.summary())

params1 = result.params.drop("CHAS")
params1

params2 = params1.copy()
params2["const"] += result.params["CHAS"]
params2

df_boston.boxplot("MEDV", "CHAS")
plt.show()

sns.stripplot(x="CHAS", y="MEDV", data=df_boston, jitter=True, alpha=.3)
sns.pointplot(x="CHAS", y="MEDV", data=df_boston, dodge=True, color='r')
plt.show()

"""
Explanation: 더미 변수와 모형 비교
더미 변수를 사용하면 사실상 회귀 모형 복수개를 동시에 사용하는 것과 실질적으로 동일하다.
더미 변수의 예 1
$$ Y = \alpha_{1} + \alpha_{2} D_2 + \alpha_{3} D_3  $$

$D_2 = 0, D_3 = 0$ 이면 $Y = \alpha_{1} $
$D_2 = 1, D_3 = 0$ 이면 $Y = \alpha_{1} + \alpha_{2} $
$D_2 = 0, D_3 = 1$ 이면 $Y = \alpha_{1} + \alpha_{3} $

<img src="https://upload.wikimedia.org/wikipedia/commons/6/61/Anova_graph.jpg" style="width:70%; margin: 0 auto 0 auto;">
더미 변수의 예 2
$$ Y = \alpha_{1} + \alpha_{2} D_2 + \alpha_{3} D_3  + \alpha_{4} X $$

$D_2 = 0, D_3 = 0$ 이면 $Y = \alpha_{1}  + \alpha_{4} X $
$D_2 = 1, D_3 = 0$ 이면 $Y = \alpha_{1} + \alpha_{2}  + \alpha_{4} X $
$D_2 = 0, D_3 = 1$ 이면 $Y = \alpha_{1} + \alpha_{3}  + \alpha_{4} X $

<img src="https://upload.wikimedia.org/wikipedia/commons/2/20/Ancova_graph.jpg" style="width:70%; margin: 0 auto 0 auto;">
더미 변수의 예 3
$$ Y = \alpha_{1} + \alpha_{2} D_2 + \alpha_{3} D_3  + \alpha_{4} X + \alpha_{5} D_4 X + \alpha_{6} D_5 X  $$

$D_2 = 0, D_3 = 0, D_4 = 0, D_5 = 0$ 이면 $Y = \alpha_{1} + \alpha_{4} X $
$D_2 = 1, D_3 = 0, D_4 = 1, D_5 = 0$ 이면 $Y = \alpha_{1} + \alpha_{2}  + (\alpha_{4} + \alpha_{5}) X $
$D_2 = 0, D_3 = 1, D_4 = 0, D_5 = 1$ 이면 $Y = \alpha_{1} + \alpha_{3}  + (\alpha_{4} + \alpha_{6}) X $

<img src="https://docs.google.com/drawings/d/1U1ahMIzvOq74T90ZDuX5YOQJ0YnSJmUhgQhjhV4Xj6c/pub?w=1428&h=622" style="width:90%; margin: 0 auto 0 auto;">
더미 변수의 예 4: Boston Dataset
End of explanation
"""


import statsmodels.api as sm
model = sm.OLS.from_formula("MEDV ~ C(CHAS)", data=df_boston)
result = model.fit()
table = sm.stats.anova_lm(result)
table

model1 = sm.OLS.from_formula("MEDV ~ CRIM + ZN +INDUS + NOX + RM + AGE + DIS + RAD + TAX + PTRATIO + B + LSTAT", data=df_boston)
model2 = sm.OLS.from_formula("MEDV ~ CRIM + ZN +INDUS + NOX + RM + AGE + DIS + RAD + TAX + PTRATIO + B + LSTAT + C(CHAS)", data=df_boston)
result1 = model1.fit()
result2 = model2.fit()
table = sm.stats.anova_lm(result1, result2)
table

"""
Explanation: 분산 분석을 이용한 모형 비교
$K$개의 복수의 카테고리 값을 가지는 더미 변수의 영향을 보기 위해서는 F-검정을 통해 복수 개의 모형을 비교하는 분산 분석을 사용할 수 있다. 
이 경우에는 분산 분석에 사용되는 각 분산의 의미가 다음과 같다.


ESS: 각 그룹 평균의 분산 (Between-Group Variance) 
  $$ BSS = \sum_{k=1}^K (\bar{x} - \bar{x}_k)^2 $$


RSS: 각 그룹 내의 오차의 분산의 합 (Within-Group Variance)
  $$ WSS = \sum_{k=1}^K \sum_{i} (x_{i} - \bar{x}_k)^2 $$


TSS : 전체 오차의 분산
  $$ TSS = \sum_{i} (x_{i} - \bar{x})^2 $$


| | source  | degree of freedom | mean square | F statstics | 
|-|-|-|-|-|
| Between | $$\text{BSS}$$ | $$K-1$$ | $$\dfrac{\text{ESS}}{K-1}$$   | $$F$$ |
| Within   | $$\text{WSS}$$ | $$N-K$$ | $$\dfrac{\text{RSS}}{N-K}$$ |
| Total      | $$\text{TSS}$$ | $$N-1$$ | $$\dfrac{\text{TSS}}{N-1}$$ |
| $R^2$      | $$\text{BSS} / \text{TSS}$$ | 
이 때 F-검정의 귀무가설은 $\text{BSS}=0$ 즉 $\text{WSS}=\text{TSS}$ 이다. 즉, 그룹간 차이가 없는 경우이다.
End of explanation
"""


