Eggs Sunny Side Up
본문 바로가기
Computer Engineering/머신러닝

선형회귀

by guswn100059 2023. 6. 16.

선형모델

: 입력 특성(데이터)을 설명할 수 있는 선형 함수를 구하는 것

=> 데이터에 대한 선형함수

선형함수의 기본식 : y = ax + b ==> 문제가 1개인 컬럼

문제가 p개의 컬럼 : y = w1x1 + w2x2 + ... + xpxp + b

a(기울기) = w(가중치)

w : 각 컬럼(문제)마다 다른 가중치를 적용

 

입력 데이터를 설명하는게 불가능

why?

그릴 수 있는 선형함수의 수가 무한대이기 때문에

모든 선형함수의 오차를 계산할 수 없음

--> 오차가 가장 작은 선형함수를 찾는 게 목적(입력 데이터를 가장 잘 설명하는 선형함수)

평균제곱오차(MSE)가 가장 작은 선형함수가 최선의 선형함수이다.

 

선형모델의 목적

그릴 수 있는 무한대의 선형함수 중에서 평균제곱오차가 가장 작은 선형함수 찾기

 

평균 제곱오차가 가장 작은 선형함수를 찾는 방법

1. 수학공식을 이용한 해석적 방법(공식으로 해결)

    : LinearRegression

2. 경사하강법

    : SGDRegressor

 

평가지표

분류 : 모델이 잘 만들어졌는지 판단 - score(정확도)

          정답/오답을 정확하게 표현할 수 있음 --> 맞춰야 하는 정답도 정해져 있음.

분류평가지표 : 정확도(0 ~ 1)

--> 1에 가까울수록 잘 만들어진 모델

 

회귀 : MSE가 작을수록 좋은 모델 - score(R2 score)

          집값 예측 시 2억 vs 2억 10원일 때의 미묘한 값 차이는 중요하지 않고,

          맞았다 틀렸다를 구분할 수 없음 

          --> 정답/오답을 정확하게 표현하기 어려움

회귀평가지표 : MSE(0 ~ 무한대)

--> 0에 가까울수록 성능이 좋다.


### 선형회귀 이해하기
- 성적 데이터를 기반으로 선형회귀를 이해해 보자

# 성적 데이터 생성을 위한 라이브러리 꺼내오기
import pandas as pd
import matplotlib.pyplot as plt

# 성적 데이터 생성
data = pd.DataFrame([[2, 20], [4, 40], [8, 80], [9, 90]],
                   index=['종현', '상준', '수하', '예은'],
                   columns=['시간', '성적'])
data

### MSE가 최소가 되는 최적의 w, b를 찾는 방법
- MSE : 평균 제곱 오차(mean squared error) --> 비용함수(cost)
- 1. 수학 공식을 이용한 해석적 모델 : LinearRegression
- 2. 경사 하강법 : SGDRegressor

#### 수학 공식을 이용한 해석적 모델 : LinearRegression
- LinearRegression
- 장점
- 공식을 이용해서 적은 계산으로 한 번에 최적의 선형함수를 찾는 방법
- 단점
- 공식이 완벽하지 않아서 잘못찾을 수도 있고,
- 공식이 잘못되었다면 고칠 수 없다는 문제

from sklearn.linear_model import LinearRegression

# 모델 생성
linear_model = LinearRegression()

# 학습
# 문제(X)는 항상 2차원
# 정답(y)은 항상 1차원
linear_model.fit(data[['시간']], data['성적'])

##### y = wx + b

# 기울기, 가중치 출력
print('기울기, 가중치 : ', linear_model.coef_)

# 절편, 편향 출력
print('절편, 편향 : ', linear_model.intercept_)

import warnings
warnings.filterwarnings('ignore')

# 승광씨가 7시간 공부했을 때 몇 점? ==> 예측
linear_model.predict([[7]])

#### H(x)
- 가설함수

# 함수 정의
def h(w, x) : 
    return w*x + 0

#### Cost function
- 비용함수

# 비용함수 정의
# data : 문제값
# target : 정답(실제 값)
# weight : 가중치

def cost(data, target, weight) :
    # 예측
    y_pre = h(weight, data)
    # ((예측값 - 실제값)**2).mean() = 평균제곱오차
    error = ((y_pre - target) ** 2).mean()
    return error

# 가중치에 따른 오차값 확인
cost(data['시간'], data['성적'], 15)

# 가중치 변화에 따른 비용함수의 변화를 그래프로 그리기 위해 값을 변경하고 저장

cost_list = []

for w in range(-10, 31): # -10 ~ 30까지 가중치 변화
    err = cost(data['시간'], data['성적'], w)
    cost_list.append(err)

# 비용함수(MSE) 그래프 그리기
plt.plot(range(-10, 31), cost_list)
plt.show()

### 경사하강법
- SGDRegressor
- 점진적으로 오차가 작은 선형함수를 찾아가는 방법
- 오차를 수정하는 방향으로 그래프를 다시 그려줌
- 선형함수를 잘못찾았을 경우 수정이 가능
- 점진적으로 찾아가므로 계산량이 많아서 시간이 오래 걸림
- 학습률(learning rate)
    - 너무 크게 설정하면 오차가 커지게 되어 발산
    - 너무 작게 설정하면 국소지역점에 빠져서 최적의 해를 찾지 못함

from sklearn.linear_model import SGDRegressor

sgd_model = SGDRegressor(max_iter=5000, # 가중치 업데이트 수치
                         eta0=0.001, # 학습률
                        verbose=1) # 학습과정 확인

# 학습
sgd_model.fit(data[['시간']], data['성적'])

# 예측
sgd_model.predict([[7]])

# 가중치(w), 절편(b) 확인
print(sgd_model.coef_)
print(sgd_model.intercept_)

sgd_model.score(data[['시간']], data['성적'])
# 1에 가까울수록 예측값의 정확도가 높다고 판단

 

댓글