- Linear Regression(선형회귀)
1. Linear Regression(선형 회귀)
이론
선형 회귀에서 최소의 잔차 제곱의 합(RSS)
을 구하는것을 최소 제곱법(OLS)
X : 독립 변수(원인) = 입력 변수, feature
Y : 종속 변수(결과) = 출력 변수, target, label
각 점들과 예측 값의 거리를 통해서 최적의 선을 구해야한다.
즉, 실제 값과 예측 값 차이의 제곱의 합을 최소화 해야한다.
-
제곱을 하지 않으면 +,-로 인해 상쇄되므로 최적의 선을 못 구한다.
-
y = mx + b 식을 구하는것
공부 시간에 따른 시험 점수
import matplotlib.pyplot as plt
import pandas as pd
dataset = pd.read_csv('LinearRegressionData.csv')
dataset.head()
hour | score | |
---|---|---|
0 | 0.5 | 10 |
1 | 1.2 | 8 |
2 | 1.8 | 14 |
3 | 2.4 | 26 |
4 | 2.6 | 22 |
# iloc[row, column]
X = dataset.iloc[:, :-1].values # 처음부터 마지막 컬럼 직전까지의 데이터 (독립 변수 - 원인)
y = dataset.iloc[:, -1].values # 마지막 컬럼 데이터 (종속 변수 - 결과)
X, y
(array([[ 0.5], [ 1.2], [ 1.8], [ 2.4], [ 2.6], [ 3.2], [ 3.9], [ 4.4], [ 4.5], [ 5. ], [ 5.3], [ 5.8], [ 6. ], [ 6.1], [ 6.2], [ 6.9], [ 7.2], [ 8.4], [ 8.6], [10. ]]), array([ 10, 8, 14, 26, 22, 30, 42, 48, 38, 58, 60, 72, 62, 68, 72, 58, 76, 86, 90, 100], dtype=int64))
from sklearn.linear_model import LinearRegression
reg = LinearRegression() # 객체 생성
reg.fit(X, y) # 학습 (모델 생성)
LinearRegression()In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
LinearRegression()
# 학습한 모델을 통해 X 에 대한 예측 값을 출력(시간에 따라 예측한 점수)
y_pred = reg.predict(X) # X 에 대한 예측 값
y_pred
array([ 5.00336377, 12.31395163, 18.58016979, 24.84638795, 26.93512734, 33.20134551, 40.51193337, 45.73378184, 46.77815153, 52. , 55.13310908, 60.35495755, 62.44369694, 63.48806663, 64.53243633, 71.84302419, 74.97613327, 87.5085696 , 89.59730899, 104.2184847 ])
# 위에서 구한 데이터를 시각화(직선이 예측한 값이 되는것)
plt.scatter(X, y, color='blue') # 산점도
plt.plot(X, y_pred, color='green') # 선 그래프
plt.title('Score by hours') # 제목
plt.xlabel('hours') # X 축 이름
plt.ylabel('score') # Y 축 이름
plt.show()
print('9시간 공부했을 때 예상 점수 : ', reg.predict([[9]])) # [[9], [8], [7]]
9시간 공부했을 때 예상 점수 : [93.77478776]
reg.coef_ # 기울기 (m)
array([10.44369694])
reg.intercept_ # y 절편 (b)
-0.21848470286721522
y = mx + b -> y = 10.4436x - 0.2184
데이터 세트 분리
- 8:2로 분리하는것을 중점으로 확인
import matplotlib.pyplot as plt
import pandas as pd
dataset = pd.read_csv('LinearRegressionData.csv')
dataset
hour | score | |
---|---|---|
0 | 0.5 | 10 |
1 | 1.2 | 8 |
2 | 1.8 | 14 |
3 | 2.4 | 26 |
4 | 2.6 | 22 |
5 | 3.2 | 30 |
6 | 3.9 | 42 |
7 | 4.4 | 48 |
8 | 4.5 | 38 |
9 | 5.0 | 58 |
10 | 5.3 | 60 |
11 | 5.8 | 72 |
12 | 6.0 | 62 |
13 | 6.1 | 68 |
14 | 6.2 | 72 |
15 | 6.9 | 58 |
16 | 7.2 | 76 |
17 | 8.4 | 86 |
18 | 8.6 | 90 |
19 | 10.0 | 100 |
X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, -1].values
# test_size=0.2는 테스트 20을 의미
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0) # 훈련 80 : 테스트 20 으로 분리
X, len(X) # 전체 데이터 X, 개수
(array([[ 0.5], [ 1.2], [ 1.8], [ 2.4], [ 2.6], [ 3.2], [ 3.9], [ 4.4], [ 4.5], [ 5. ], [ 5.3], [ 5.8], [ 6. ], [ 6.1], [ 6.2], [ 6.9], [ 7.2], [ 8.4], [ 8.6], [10. ]]), 20)
X_train, len(X_train) # 훈련 세트 X, 개수
(array([[5.3], [8.4], [3.9], [6.1], [2.6], [1.8], [3.2], [6.2], [5. ], [4.4], [7.2], [5.8], [2.4], [0.5], [6.9], [6. ]]), 16)
X_test, len(X_test) # 테스트 세트 X, 개수
(array([[ 8.6], [ 1.2], [10. ], [ 4.5]]), 4)
y, len(y) # 전체 데이터 y
(array([ 10, 8, 14, 26, 22, 30, 42, 48, 38, 58, 60, 72, 62, 68, 72, 58, 76, 86, 90, 100], dtype=int64), 20)
y_train, len(y_train) # 훈련 세트 y
(array([60, 86, 42, 68, 22, 14, 30, 72, 58, 48, 76, 72, 26, 10, 58, 62], dtype=int64), 16)
y_test, len(y_test) # 테스트 세트 y
(array([ 90, 8, 100, 38], dtype=int64), 4)
분리된 데이터를 통한 모델링
- 이번엔 위에서 구한 데이터로 선형 회귀
from sklearn.linear_model import LinearRegression
reg = LinearRegression()
reg.fit(X_train, y_train) # 훈련 세트로 학습
LinearRegression()In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
LinearRegression()
데이터 시각화 (훈련 세트)
plt.scatter(X_train, y_train, color='blue') # 산점도
plt.plot(X_train, reg.predict(X_train), color='green') # 선 그래프
plt.title('Score by hours (train data)') # 제목
plt.xlabel('hours') # X 축 이름
plt.ylabel('score') # Y 축 이름
plt.show()
데이터 시각화 (테스트 세트)
plt.scatter(X_test, y_test, color='blue') # 산점도
plt.plot(X_train, reg.predict(X_train), color='green') # 선 그래프
plt.title('Score by hours (test data)') # 제목
plt.xlabel('hours') # X 축 이름
plt.ylabel('score') # Y 축 이름
plt.show()
reg.coef_ # 기울기
array([10.49161294])
reg.intercept_ # y절편
0.6115562905169796
모델 평가
- 위에서 만든 모델들을 평가를 해야 무엇이 더 좋은지 알 수 있을것이다.
# 0~1 범위로 제일 높은 점수가 1
reg.score(X_test, y_test) # 테스트 세트를 통한 모델 평가
0.9727616474310156
reg.score(X_train, y_train) # 훈련 세트를 통한 모델 평가
0.9356663661221668
경사 하강법 (Gradient Descent)
-
최소 제곱법
은 노이즈에 취약하고, 많은독립변수
에 취약하다. -
이런 단점을 극복한 것이
경사 하강법
이론
말그대로 경사를 따라서 하강하는 것이 기본적인 개념이다.
이또한 잔차 제곱의 합
이 최소인것을 찾는게 목표로 한다.
수학 그래프로 생각해보면, 식에서 기울기가 점점 낮아지는 지점으로 가는것을 목표
움직이는 보폭이 너무 크면 범위를 벗어날 수 있고, 작으면 반복을 너무해서 오래걸릴수 있다.
-
이것을
학습률(Learning rate)
라고 한다.- 일반적으로
0.001, 0.003, 0.01, 0.03, 0.1, 0.3
을 사용
- 일반적으로
-
에포크(Epoch)
: 경사 하강법에서 최적의 값을 찾기위해 훈련 세트에 있는 모든데이터를 한번씩 다 사용하는것을 의미- 그러나 이러한 방식은 컴퓨터 성능도 좋아야하고, 시간도 많이 걸린다.
-
그래서 나온것이
확률적 경사 하강법
이다.-
한번 수행때 모든데이터를 다 사용하는게 아닌 하나의 데이터 기울기만 구하는 그런 방식이다.
-
따라서 당연히 학습속도가 더 빠르다.
-
참고 할만한 시각화 자료 : 경사 하강법
max_iter : 훈련 세트 반복 횟수 (Epoch 횟수)
eta0 : 학습률 (learning rate)
from sklearn.linear_model import SGDRegressor # SGD : Stochastic Gradient Descent 확률적 경사 하강법
# 지수표기법
# 1e-3 : 0.001 (10^-3)
# 1e-4 : 0.0001 (10^-4)
# 1e+3 : 1000 (10^3)
# 1e+4 : 10000 (10^4)
# 옵션 설정(verbose는 변화 과정을 출력해줌)
# sr = SGDRegressor(max_iter=200, eta0=1e-4, random_state=0, verbose=1)
sr = SGDRegressor()
sr.fit(X_train, y_train)
SGDRegressor()In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
SGDRegressor()
plt.scatter(X_train, y_train, color='blue') # 산점도
plt.plot(X_train, sr.predict(X_train), color='green') # 선 그래프
plt.title('Score by hours (train data, SGD)') # 제목
plt.xlabel('hours') # X 축 이름
plt.ylabel('score') # Y 축 이름
plt.show()
sr.coef_, sr.intercept_
# 주의 : SGDRegressor() 객체를 생성할 때 random_state 값을 지정하지 않았으므로 결과가 다르게 나타날 수 있습니다
(array([10.2062811]), array([1.95017289]))
sr.score(X_test, y_test) # 테스트 세트를 통한 모델 평가
0.9732274354250781
sr.score(X_train, y_train) # 훈련 세트를 통한 모델 평가
0.9349740699430755
-
참고: 좋은 데이터는 훈련 세트가 점수가 더 높다.
-
현재 데이터가 너무 적어서 테스트 세트 점수가 더 높게 나온것이다.
참고자료 : 나도코딩-유튜브
추천!
댓글남기기