지도학습1 - 분류(Classification) -> 출력이 0 혹은 1
지도학습2 - 회귀(Regression) -> 출력이 연속된 값(continuous value)임
비지도학습1 - 군집
비지도학습2 - 차원 축소
회귀 : ex) 주택의 넓이와 가격이라는 데이터를 가지고 주택크기가 주어졌을 때 주택가격을 예측하기
선형회귀(Linear Regression) : 입력변수(특징) x가 하나인 경우, 선형회귀는 주어진 학습데이터와 가장 잘 맞는 Hypothesis 함수 h를 찾는 문제가 됨
OLS (Ordinary Linear Least Square)
!pip install statsmodels
import pandas as pd
data = {'x' : [1., 2., 3., 4., 5.], 'y' : [1., 3., 4., 6., 5.]}
df = pd.DataFrame(data)
df
import statsmodels.formula.api as smf
lm_model = smf.ols(formula='y ~ x', data=df).fit()
lm_model.params
-> 출력결과
Intercept 0.5
x 1.1
dtype: float64
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.lmplot(x='x', y='y', data=df);
잔차 평가 (residue)
-> 잔차는 평균이 0인 정규분포를 따르는 것이어야 함
-> 잔차 평가는 잔차의 평균이 0이고 정규분포를 따르는지 확인
잔차 확인
resid = lm_model.resid
resid
결정계수 (R-Squared)
-> y_hat은 예측된 값
-> 예측 값과 실제 값(y)이 일치하면 결정계수는 1이 됨
-> 즉 결정계수가 높을수록 좋은 모델
numpy로 직접 결정계수 계산하기
import numpy as np
mu = np.mean(df.y)
y = df.y
y_hat = lm_model.predict()
np.sum((y_hat - mu)**2 / np.sum((y - mu)**2))
lm_model.rsquared
sns.distplot(resid, color='black');
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
data_url = "https://raw.githubusercontent.com/PinkWink/ML_tutorial/master/dataset/ecommerce.csv"
data = pd.read_csv(data_url)
data.columns
data.drop(['Email', 'Address', 'Avatar'], axis=1, inplace=True)
data.info()
plt.figure(figsize=(12, 6))
sns.boxplot(data=data);
plt.figure(figsize=(12, 6))
sns.boxplot(data=data.iloc[:, :-1]);
plt.figure(figsize=(12, 6))
sns.boxplot(data=data['Yearly Amount Spent']);
plt.figure(figsize=(12, 6))
sns.pairplot(data=data);
-> 큰 상관관계를 보이는 것은 'Length of Membership'와 'Yearly Amount Spent'
plt.figure(figsize=(12, 6))
sns.lmplot(x='Length of Membership', y='Yearly Amount Spent', data=data);
import statsmodels.api as sm
X = data['Length of Membership']
y = data['Yearly Amount Spent']
lm = sm.OLS(y, X).fit()
lm.summary()
pred = lm.predict(X)
sns.scatterplot(x=X, y=y)
plt.plot(X, pred, 'r', ls='dashed', lw=3)
sns.scatterplot(x=y, y=pred)
plt.plot([min(y), max(y)], [min(y), max(y)], 'r', ls='dashed', lw=3);
plt.plot([0, max(y)], [0, max(y)], 'b', ls='dashed', lw=3)
plt.axis([0, max(y), 0, max(y)])
-> 상수항이 없음
X = np.c_[X, [1]*len(X)]
X[:5]
lm = sm.OLS(y, X).fit()
lm.summary()
pred = lm.predict(X)
sns.scatterplot(x=X[:, 0], y=y)
plt.plot(X[:, 0], pred, 'r', ls='dashed', lw=3)
pred = lm.predict(X)
sns.scatterplot(x=y, y=pred)
plt.plot([min(y), max(y)], [min(y), max(y)], 'r', ls='dashed', lw=3);
from sklearn.model_selection import train_test_split
X = data.drop('Yearly Amount Spent', axis=1)
y = data['Yearly Amount Spent']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=13)
import statsmodels.api as sm
lm = sm.OLS(y_train, X_train).fit()
lm.summary()
pred = lm.predict(X_test)
sns.scatterplot(x=y_test, y=pred)
plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], 'r', ls='dashed', lw=3);
import numpy as np
np.poly1d([2, -1])**2 + np.poly1d([3, -5])**2 + np.poly1d([5, -6])**2
-> 출력결과 : poly1d([ 38, -94, 62])
-> poly1d : 다항식 표현하는 도구, 다항식 계산에 용이함
!pip install sympy
import sympy as sym
theta = sym.Symbol('theta')
diff_th = sym.diff(38*theta**2 - 94*theta + 62, theta)
diff_th
실제 데이터는 너무 복잡해서 손으로 풀기 어려움. 데이터의 특징(feature)이 여러 개가 존재해서 평면상의 방정식이 아니라 다차원에서 고민해야 할 때가 많음.
Cost Function의 최솟값을 찾기 위해서 특단의 대책이 필요
-> Gradient Descent
Gradient Descent
-> 미분을 통해서 Cost Function의 최솟값을 찾음
Learning Rate(학습률)
from sklearn.datasets import load_boston
boston = load_boston()
print(boston.DESCR)
[each for each in boston.feature_names]
import pandas as pd
boston_pd = pd.DataFrame(boston.data, columns=boston.feature_names)
boston_pd['Price'] = boston.target # 집 값
boston_pd.head()
import plotly.express as px
fig = px.histogram(boston_pd, x='PRICE')
fig.show()
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
corr_mat = boston_pd.corr().round(1)
sns.set(rc={'figure.figsize' : (10, 8)})
sns.heatmap(data=corr_mat, annot_True, cmap='bwr');
-> Price와 방의 수(RM), 저소득층 인구(LSTAT)와 높은 상관관계가 보임
sns.set_style('darkgrid')
sns.set(rc={'figure.figsize' : (12, 6)})
fig, ax = plt.subplots(ncols=2)
sns.regplot(x='RM', y='PRICE', data=boston_pd, ax=ax[0])
sns.regplot(x='LSTAT', y='PRICE', data=boston_pd, ax=ax[1]);
-> 저소득층 인구가 낮을수록, 방의 개수가 많을수록 집 값이 높아짐
-> 두 특성이 정말 집 값에 유의미한 영향을 주는지 확인해볼 필요가 있음
from sklearn.model_selection import train_test_split
X = boston_pd.drop('PRICE', axis=1)
y = boston_pd['PRICE']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=13)
from sklearn.linear_model import LinearRegression
reg = LinearRegression()
reg.fit(X_train, y_train)
import numpy as np
from sklearn.metrics import mean_squared_error
pred_tr = reg.predict(X_train)
pred_test = reg.predict(X_test)
rmse_tr = (np.sqrt(mean_squared_error(y_train, pred_tr)))
rmse_test = (np.sqrt(mean_squared_error(y_test, pred_test)))
print('RMSE of Train Data : ', rmse_tr)
print('RMSE of Test Data : ', rmse_test)
plt.scatter(y_test, pred_test)
plt.xlabel('Actual House Prices ($1000)')
plt.ylabel('Predicted Prices')
plt.title('Real vs Predicted')
plt.plot([0,50], [0,50], 'r')
plt.show()
X = boston_pd.drop(['PRICE', 'LSTAT'], axis=1)
y = boston_pd['PRICE']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=13)
reg = LinearRegression()
reg.fit(X_train, y_train)
pred_tr = reg.predict(X_train)
pred_test = reg.predict(X_test)
rmse_tr = (np.sqrt(mean_squared_error(y_train, pred_tr)))
rmse_test = (np.sqrt(mean_squared_error(y_test, pred_test)))
print('RMSE of Train Data : ', rmse_tr)
print('RMSE of Test Data : ', rmse_test) # 높아짐
-> 성능이 나빠짐 but LSTAT를 빼도 될지 안될지는 더 고민해봐야 함
plt.scatter(y_test, pred_test)
plt.xlabel('Actual House Prices ($1000)')
plt.ylabel('Predicted Prices')
plt.title('Real vs Predicted')
plt.plot([0,48], [0,48], 'r')
plt.show()
<제로베이스 데이터 취업 스쿨>