import matplotlib.pyplot as plt
import pandas as pd
dataset = pd.read_csv('../data/LinearRegressionData.csv') # 데이터 로드
dataset.head() # 상위 5개 데이터 확인
hour | score | |
---|---|---|
0 | 0.5 | 10 |
1 | 1.2 | 8 |
2 | 1.8 | 14 |
3 | 2.4 | 26 |
4 | 2.6 | 22 |
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()
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
데이터 세트 분리¶
import matplotlib.pyplot as plt
import pandas as pd
dataset = pd.read_csv('../data/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
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_
0.6115562905169796
모델 평가¶
reg.score(X_test, y_test) # 테스트 세트를 통한 모델 평가
0.9727616474310156
reg.score(X_train, y_train) # 훈련 세트를 통한 모델 평가
0.9356663661221668
경사 하강법 (Gradient Descent)¶
from sklearn.linear_model import SGDRegressor # SGD : Stochastic Gradient Descent 확률적 경사 하강법
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()
sr = SGDRegressor(max_iter=200, eta0=1e-4, random_state=0, verbose=1)
지수표기법¶
1e-3 : 0.01 (10^-2) default
1e-3 : 0.001 (10^-3)
1e-4 : 0.0001 (10^-4)
1e+3 : 1000 (10^3)
1e+4 : 10000 (10^4)
max_iter : 훈련 세트 반복 횟수 (Epoch 횟수)
eta0 : 학습률 (learning rate)
random_state : 랜덤으로 데이터 추출 여부 (0 = 고정)
verbose : 손실률 표시
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.34066226]), array([1.75708648]))
sr.score(X_test, y_test) # 테스트 세트를 통한 모델 평가
0.96990866949905
sr.score(X_train, y_train) # 훈련 세트를 통한 모델 평가
0.9351165412877228
경사 하강법 (Gradient Descent)¶
1. 손실률(loss)이 가장 낮은 최적의 값으로 기울기를 찾기 위함함¶
학습률 조정의 가이드라인
학습률이 너무 크면: 학습이 불안정해지고, 수렴하지 않거나 성능이 나빠집니다.
학습률이 너무 작으면: 학습은 안정적이지만, 시간이 많이 걸리고 최적 성능에 도달하지 못할 수 있습니다.
결론 학습률이 적절한 범위 내에 있어야 학습이 잘 이루어집니다.
학습률이 너무 크면 정확도가 낮아지고, 학습률이 너무 작으면 학습 속도가 느려지면서 최적의 성능을 얻기 어렵습니다.
따라서 정확도를 높이려면:
먼저 큰 학습률로 시작하여 성능을 확인하고, 모델이 불안정하거나 수렴하지 않으면 점차 학습률을 줄이면서 성능을 비교하는 방식으로 적절한 값을 찾는 것이 좋습니다. 일반적으로는 1e-2, 1e-3, 1e-4 등의 값으로 실험해보며 성능을 확인할 수 있습니다.
2. 경사 하강법이 왜 필요한가?¶
기계 학습이나 최적화 문제에서는 우리가 어떤 함수(보통은 손실 함수라고 부름)의 최솟값을 찾고자 합니다.
예를 들어, 선형 회귀에서는 우리가 데이터에 맞는 최적의 직선을 찾는 것이 목표입니다.
이 직선을 찾기 위해서는, 각 데이터 포인트에서 예측한 값과 실제 값의 차이를 줄이는 방향으로 학습을 진행해야 합니다.
이러한 차이를 손실이라고 부르는데, 이 손실이 최소화되도록 파라미터(가중치, 절편 등)를 조정해야 합니다.
경사 하강법은 이 손실을 줄이는 방법입니다. 즉, 손실을 줄이는 방향으로 함수의 파라미터(가중치 등)를 조금씩 업데이트해서 최적의 값을 찾습니다.
3. 경사 하강법이 언제 쓰이는가?¶
최적화 문제를 풀 때: 함수의 최소값(또는 최대값)을 찾는 것이 목표일 때 사용됩니다.
예를 들어, 손실 함수를 최소화하는 것이 목표라면 경사 하강법이 적합합니다.
모델을 학습할 때: 기계 학습에서 모델의 파라미터(가중치 등)를 조정해 최적의 성능을 내기 위해 경사 하강법을 사용합니다.
예를 들어, 선형 회귀, 로지스틱 회귀, 신경망 등 다양한 기계 학습 알고리즘 에서 경사 하강법을 사용해 학습을 진행합니다.
4. 경사 하강법이 어떻게 작동하는가?¶
경사 하강법은 함수의 경사를 계산하여 그 경사에 따라 값을 조정해 나가는 방법입니다.
경사는 말 그대로 "기울기"를 의미하며, 이 기울기가 크면 크게, 작으면 작게 조정됩니다.
현재 위치에서 손실 함수의 기울기를 계산합니다.
그 기울기가 큰 쪽은 손실이 더 커지므로, 기울기의 반대 방향으로 이동합니다.
한 번 이동할 때 이동하는 거리(조정량)는 학습률(learning rate)에 따라 결정됩니다.
학습률이 크면 큰 폭으로 이동하고, 작으면 조금씩 이동합니다.
이 과정을 반복하면서 손실 함수의 값이 더 이상 줄어들지 않을 때까지 진행합니다.
5. 언제 경사 하강법을 사용하나?¶
함수의 기울기를 계산할 수 있을 때: 기울기를 계산할 수 있으면 경사 하강법을 사용할 수 있습니다.
보통 손실 함수의 기울기 를 쉽게 구할 수 있는 문제에서 사용합니다.
최적화를 할 때:
경사 하강법은 매우 일반적인 최적화 방법입니다. 선형 회귀, 로지스틱 회귀, 신경망 등 다양한 기계 학습 모델에서 파라미터를 최적화하는 데 사용합니다.
대규모 데이터셋에서:
데이터가 많을 때는 손실 함수의 형태가 복잡하고, 수작업으로 최적점을 찾기가 어렵습니다. 이때 경사 하강법은 효율적으로 손실을 줄이는 방법을 제공합니다.
6. 경사 하강법의 종류¶
- 경사 하강법의 종류
배치 경사 하강법 (Batch Gradient Descent):
전체 데이터셋을 사용해 기울기를 계산합니다. 안정적이지만 계산 비용이 큽니다.
- 확률적 경사 하강법 (SGD):
하나의 샘플만으로 기울기를 계산합니다. 빠르지만 흔들림이 있습니다.
- 미니배치 경사 하강법 (Mini-Batch Gradient Descent):
데이터를 여러 묶음(배치)으로 나누어 기울기를 계산합니다. 배치 경사 하강법과 SGD의 장점을 절충한 방식입니다.
7. 핵심 요약¶
- 경사 하강법의 목표는 손실 함수의 최소값을 찾는 것.
- 작동 방식은 함수의 기울기를 계산해 기울기가 낮아지는 방향으로 파라미터를 조정하는 것.
- 사용 시점은 기계 학습에서 모델을 학습하거나 함수의 최적화 문제를 풀 때.
'Python > SikitLearn' 카테고리의 다른 글
05. (비지도학습)_K-Means (0) | 2024.11.23 |
---|---|
04. (지도학습)_Logistic Regression(로지스틱 회귀) (0) | 2024.11.23 |
03. (지도학습)_Polynomial Regression(다항 회귀) (0) | 2024.11.23 |
02. (지도학습)_Multiple Linear Regression(다중 선형 회귀) (0) | 2024.11.23 |