In [1]:
from sklearn.datasets import load_boston
boston = load_boston()
In [2]:
X = boston.data
y = boston.target
names = boston.feature_names
In [4]:
# from sklearn.preprocessing import scale
# X_scaled = scale(X)
# 되도록이면 클래스로 하기
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler(with_mean=False)
X_scaled = scaler.fit_transform(X)
In [5]:
dfX0 = pd.DataFrame(X_scaled, columns=names)
dfX = sm.add_constant(dfX0)
dfy = pd.DataFrame(y, columns=["MEDV"])
df = pd.concat([dfX, dfy], axis=1)
df.tail()
Out[5]:
In [6]:
%config InlineBackend.figure_formats = {'png', 'retina'}
In [35]:
sns.pairplot(df)
plt.show()
In [7]:
sns.jointplot("RM", "MEDV", data=df)
Out[7]:
In [8]:
sns.jointplot("CHAS", "MEDV", data=df)
Out[8]:
In [9]:
model = sm.OLS(df.ix[:, -1], df.ix[:, :-1])
result = model.fit()
print(result.summary())
In [10]:
# scikit-learn
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(df.ix[:, :-1], df.ix[:, -1])
model.intercept_, model.coef_
Out[10]:
In [11]:
# nomal분포 y 혹은 입실론
sns.distplot(result.resid)
Out[11]:
In [12]:
sns.distplot(df.MEDV)
Out[12]:
In [13]:
# sensored 데이터 아웃라이어 잘못된 데이터 때문에 모델이 정규분포를 따르지 않는다.
In [14]:
# 아웃라이어를 제거
df2 = df.drop(df[df.MEDV >= df.MEDV.max()].index)
In [15]:
model2 = sm.OLS(df2.ix[:,-1], df2.ix[:,:-1])
result2 = model2.fit()
print(result2.summary())
# Jarque-Bera 값이 161로 줄어듦
In [16]:
model2 = LinearRegression()
result2 = model2.fit(df2.ix[:,:-1],df2.ix[:,-1])
model2.intercept_, model2.coef_
Out[16]:
In [17]:
# ANOVA
model_anova = sm.OLS.from_formula("MEDV ~ C(CHAS)", data=df2)
result_anova = model_anova.fit()
table_anova = sm.stats.anova_lm(result_anova)
table_anova
# CHAS 때문에 움직인 분산의크기 mean_sq 가 residual보다 크다.
# PR>F(P-value)가 9.8% 유의 수준이 5%이면 이거로는 영향이 없다. (P-value가 작을수록 영향력이 크다.)
Out[17]:
In [18]:
model1_anova = sm.OLS.from_formula("MEDV ~ CRIM + ZN +INDUS + NOX + RM + AGE + DIS + RAD + TAX + PTRATIO + B + LSTAT", data=df2)
model2_anova = sm.OLS.from_formula("MEDV ~ CRIM + ZN +INDUS + NOX + RM + AGE + DIS + RAD + TAX + PTRATIO + B + LSTAT + C(CHAS)", data=df2)
result1_anova = model1_anova.fit()
result2_anova = model2_anova.fit()
table2_anova = sm.stats.anova_lm(result1_anova, result2_anova)
table2_anova
Out[18]:
In [19]:
model2 = LinearRegression()
model2.fit(df2.ix[:,:-1],df2.ix[:,-1]) # feature, target
model2.intercept_, model2.coef_
Out[19]:
In [20]:
from sklearn.cross_validation import cross_val_score
# cv 숫자만 넣으면 KFold로 만들어서 실행 시킨다.
scores2 = cross_val_score(model2, df2.ix[:,:-1], df2.ix[:,-1], cv=5)
scores2, scores2.mean(), scores2.std()
# scores2.mean() : 평균, scores2.std() : 분산
# -> 0.3 만큼 수치가 왔다 갔다 함으로 분석결과가 안 좋음 (분산이 적어야 R-squres 값이 안정적) -> 모델이 좋음
# 실제 R square 는 0.418
Out[20]:
In [21]:
# 회기분석에서 R square 값 오차를 줄이자
# target에 대해서 feature가 로그취하기 -기울기를 갖는 데이터
In [22]:
df3 = df2.drop(["CRIM","DIS","LSTAT","MEDV"], axis=1)
df3["LOGCRIM"] = np.log(df2.CRIM)
df3["LOGDIS"] = np.log(df2.DIS)
df3["LOGLSTAT"] = np.log(df2.LSTAT)
df3["MEDV"] = df2.MEDV
df3.tail()
Out[22]:
In [23]:
sns.jointplot("CRIM","MEDV", data=df2)
sns.jointplot("LOGCRIM","MEDV", data=df3)
Out[23]:
In [24]:
sns.jointplot("DIS","MEDV", data=df2)
sns.jointplot("LOGDIS","MEDV", data=df3)
Out[24]:
In [109]:
sns.jointplot("LSTAT","MEDV", data=df2)
sns.jointplot("LOGLSTAT","MEDV", data=df3)
Out[109]:
In [25]:
model3 = sm.OLS(df3.ix[:,-1], df3.ix[:,:-1])
result3 = model3.fit()
print(result3.summary())
#
In [26]:
# cross-validation
scores3 = cross_val_score(LinearRegression(), df3.ix[:,:-1], df3.ix[:,-1], cv=5)
scores3, scores3.mean(), scores3.std()
# 점수(R-square)도 높아지고 r-square의 분산도 줄어들었다.
Out[26]:
In [27]:
# Multicolinearity (다중공선성) 이 있음
In [28]:
sns.heatmap(np.corrcoef(df3.T), annot=True, xticklabels=df3.columns, yticklabels=df3.columns)
# 0에 가까울 수록 좋다. 파란애가 좋고 빨간애가 안좋다. 빨간애들을 잘라내야 한다.
Out[28]:
In [136]:
df4 = df3.drop(["RAD","TAX","ZN","INDUS","AGE","LOGCRIM"], axis=1)
model4 = sm.OLS(df4.ix[:,-1],df4.ix[:,:-1])
result4 = model4.fit()
print(result4.summary())
# 변수가 빠졌음에도 R-squared: 는 그대로고, Adj. R-squared: 는 더 좋아짐
In [137]:
scores4 = cross_val_score(LinearRegression(), df4.ix[:,:-1], df4.ix[:,-1], cv = 5)
scores4, scores4.mean(), scores4.std()
# R-square과 분산 수치가 좋아졌다
# grid search
Out[137]:
In [138]:
sns.heatmap(np.corrcoef(df4.T), annot=True, xticklabels=df4.columns, yticklabels=df4.columns)
Out[138]:
In [139]:
# grid search로 찾자 anova 분석으로 줄이자
# PCA로 줄여야 한다. feature 공간을 회전시켜서 가장 떨어지는 조합을 제거한다.
In [ ]: