[ML] Linear Regression(회기), OLS

박미영·2023년 5월 24일
0

DataSchool StudyNote - ML

목록 보기
10/19

📌지도학습

라벨(정답)을 주고 학습을 시키는 것

- Classification(분류)



- Regression(회기)
출력이 연속된 값이다.



📌비지도학습

비지도 학습은 Label이 없다.


- 군집


- 차원 축소



📌Regression(회기)

ex) 주택의 넓이과 가격이라는 데이터가 있고 주택가격을 예측


  • 머신러닝 모델 만들기


  • 모델을 어떻게 만드는가?

  • 만약 1차 함수라면

  • 선형 회귀

  • 모델을 구성하는 파라미터를 어떻게 찾을까?

그렇다면 Linear Regression(선형 회기) 직선 값을 구하기 위해 파라미터를 구하는 방법은?



- OLS(Ordinary Linear Least Square)

이렇게 생긴 데이터를 하나의 직선으로 만든다면

















- OLS 실습

!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



  • 가설 세우기
    y ~ x : y = ax+b
import statsmodels.formula.api as smf

lm_model = smf.ols(formula="y ~ x", data=df).fit()
lm_model.params

x 기울기: 1.1
b: 0.5



  • seaborn으로 그리기
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
sns.lmplot(x='x', y='y', data=df);
plt.xlim([0, 5])



- 잔차 평가 residue

  • Error(모델과 실제 값의 차이)
  • 잔차는 평균이 0인 정규분포를 따르는 것 이어야 함
  • 잔차 평가는 잔차의 평균이 0이고 정규분포를 따르는 지 확인



  • 잔차 확인
resid = lm_model.resid
resid



⭐⭐⭐결정계수 R-Squared

  • y_hat은 예측된 값
  • 예측 값과 실제 값(y)이 일치하면 결정계수는 1이 됨 (즉 결정계수가 높을 수록 좋은 모델)

⭐녹색선: 평균
분모: 참값이 가지는 평균으로부터의 오차(분산과 비슷)
분자: 예측값의 평균으로부터의 오차



  • 결정계수 계산
import numpy as np

mu = np.mean(df.y)
y = df.y
yhat = lm_model.predict() # 예측값
np.sum((yhat - 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.head()

  • 사용자 세션 길이는 ‘한 번 접속했을 때 평균 어느 정도의 시간을 사용하는지에 대한 데이터'
  • Time on App : 폰 앱으로 접속했을 때 유지 시간 (분)
  • Time on Website : 웹사이트로 접속했을 때 유지 시간 (분)
  • Length of Membership : 회원 자격 유지 기간 (연)



  • 필요없는 컬럼 삭제

data.drop(['Email', 'Address', 'Avatar'], axis=1, inplace=True)
data.info()



  • 컬럼별 boxplot
plt.figure(figsize=(12, 6))
sns.boxplot(data=data)



  • 특성들만 다시 boxplot
plt.figure(figsize=(12, 6))
sns.boxplot(data=data.iloc[:, :-1]);



  • Label 값에 대한 boxplot
plt.figure(figsize=(12, 6))
sns.boxplot(data=data['Yearly Amount Spent']);



  • pairplot으로 경향 확인
plt.figure(figsize=(12, 6))
sns.pairplot(data=data)

뭔가 큰 상관 관계를 가지고 있다라고 하기에는 좀 어려워 보인다.
큰 상관관계를 보이는 것은 멤버쉽 유지 기간



  • 멤버쉽 유지 기간 lmplot
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()

회기 리포트



📍수치의 의미 해석하기

  • R-squared : 모형 적합도, y의 분산을 각각의 변수들이 약 99.8%로 설명할 수 있음
  • Adj. R-squared : 독립변수가 여러 개인 다중회귀분석에서 사용
  • Prob. F-Statistic : 회귀모형에 대한 통계적 유의미성 검정.
    이 값이 0.05 이하라면 모집단에서도 의미가 있다고 볼 수 있음



  • 회기 모델 시각화
pred = lm.predict(X)

sns.scatterplot(x=X, y=y)
plt.plot(X, pred, 'r', ls='dashed', lw=3);



  • 참 값 vs 예측 값 시각화
sns.scatterplot(x=y, y=pred)
plt.plot([min(y), max(y)], [min(y), max(y)], '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)])

상수항이 없어 0부터 시작되고 있다.



  • 상수항 넣어주기(열 추가)
X = np.c_[X, [1]*len(X)]
X[:5]



  • 다시 모델 fit
lm = sm.OLS(y, X).fit()
lm.summary()

x1,const가 생겼고 R-squared가 작아졌다.
AIC(내가 만들어낸 모델이 나의 데이터를 얼마나 잘 반영하는가 즉, 손실 수치)가 낮아졌다 -> 좋은것

R-squared 수치를 무조건 믿으면 안된다.



  • 선형 회기 결과
pred = lm.predict(X)

sns.scatterplot(x=X[:, 0], y=y)
plt.plot(X[:, 0], pred, 'r', ls='dashed', lw=3);



-참 값 vs 예측 값

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()



  • 참 값 vs 예측 값
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);






"이 글은 제로베이스 데이터 취업 스쿨 강의를 듣고 작성한 내용으로 제로베이스 데이터 취업 스쿨 강의 자료 일부를 발췌한 내용이 포함되어 있습니다."

0개의 댓글