project:eve
23.01.25 Linear Regression, Ridge 경사하강법, 릿지 회귀 본문
오늘은 선형회귀의 접근방식 중 하나인 경사하강법에 대해 배워보기로 했다.
이전에 선형회귀 분석을 할 때 사용했던 LinearRegression은 최소제곱법을 사용하는 정규방정식 함수이다.
경사하강법이란?
함수의 값(y)가 낮아지는 방향으로 독립변수의 값을 바꿔가면서 최종적으로 함수 값이 가장 작아지는 독립변수 값을 찾아내가는 방식이다.
책에는 이 방법을 쓰는 이유도 나오는데,
1) 분석에 사용되는 함수들은 형태가 복잡해 수식으로 해를 찾기 어려울 수 있다
2) 데이터의 양이 큰 경우에 상대적으로 값을 구하기 쉬울 수 있다
그런데 잘 이해는 안 간다... 통계적으로 직접 수식을 마주하고 풀어본 것이 아니라서 체감이 안 된다ㅠ
또 경사하강법에는 여러 종류가 있다.
1) 배치 경사하강법 : 반복할 때마다 전체 데이터를 사용해 가중값을 변경. 시간이 많이 소요되는 단점
2) 확률 경사하강법 : 무작위로 한 데이터를 선택해 그 값의 경사를 계산해 사용한다. 매번 선택된 데이터에 따라 가중값이 천차만별로 달라지므로 수렴하기 전까지는 값이 요동치며 평균적으로 감소.
3) 미니 배치 경사하강법 : 1)번의 간소화 버전. 전체 데이터 대신 30~50개의 데이터의 평균 가중값을 계산해 사용한다. 2)번보다 비교적 낮은 오차율을 가지고 최종적으로는 더 낮은 최솟값을 구할 수 있음
여기서 가중값, 경사라는 단어는 함수식에서 기울기를 말하는 것 같다.
궁금한 건 어쨌든 전체 데이터를 다 훑어서 최솟값을 구하는게 제일 정확하지 않은가?싶다. 책에는 1)번에 대해 그런 이야기는 없고 잡음이 적은 최적치를 구할 수 있다는데 이 최적치라는게 독립변수를 말하는 것 같다.
정리하면 구한 최솟값의 정확도는 1>3>2, 속도는 2>3>1 이므로 3번이 절충안으로 활용되는 것 같다
이번에는 파이썬으로 써보자. 경사하강법 함수도 선형회귀와 마찬가지로 같은 라이브러리에 들어있다. 식도 이전에 회귀분석했던 거랑 똑같아서 함수명만 바꿔주었다. 나이에 따른 보험료를 계산하기로 하고 모든 데이터를 적합-> 분석모델로 19세와 64세의 보험료를 예측해봤다.
from sklearn.linear_model import SGDRegressor
ins = pd.read_csv('../jupyter notebook/files/insurance.csv')
X = ins['age'].values
Y = ins['charges'].values
Sr = SGDRegressor()
X_ = X.reshape(1338, 1)#np.array(X).reshape(1338, 1)
Y_ = Y.reshape(1338, 1)#np.array(Y).reshape(1338, 1)
Sr.fit(X_, Y_)
print('절편 : ', Sr.intercept_, '계수 : ', Sr.coef_)
print('결정계수 : ', Sr.score(X_, Y_))
x_new = np.array([19, 64]).reshape(-1, 1)
pred = Sr.predict(x_new)
pred

19세는 10195원, 64세는 20499원을 내면 된다.
+추가) 다중회귀에 대해서도 공부했다.
다중회귀분석이란??
여러 개의 독립변수가 복합적으로 종속변수에 영향을 미치는 경우 사용하는 분석 방법이다.
식으로 표현하면 이렇다

각 독립변수마다 가중치가 다르구나.. 말고는 단순선형회귀와 똑같은 식이다.
다른 점은 다중회귀분석에서는 최적의 모델을 생성하기 위해 다양한 방법으로 변수를 선택한다. 가장 영향을 많이 미치는 변수만을 고른다고 생각하면 될 것 같다.
1) 변수선택법 : 전진/후진선택법
- 변수를 하나씩 추가해 가며 회귀계수에 의해 변수를 선택하거나, 모든 변수를 추가한 상태에서 하나씩 제거해 가며 변수를 선택하는 방법.
2) 규칙 제어 : 릿지, 라쏘, 엘라스틱넷
- 일정한 규칙을 생성해 회귀계수 추정치를 0에 가깝게 만들어 성능을 높이는 방법.
2-1) 릿지 회귀

릿지회귀의 장점?
하이퍼파라미터 α를 조정해 편향과 분산을 절충할 수 있다. α가 증가하면 편향이 증가하고 분산은 감소 -> 학습 데이터의 작은 변화에 회귀계수 추정치가 변동하는 문제를 극복한다.
아무튼 편향이 증가, 분산이 감소하는 형태로 정규화를 한다. 변수선택법과 비교해 속도도 빠르다.
(편향은 예측값과 실제값의 오차의 정도, 분산은 예측값들이 서로 떨어진 정도로 높으면 안좋은 수치인데 왜 편향이 증가하는 방식으로 정규화를 하지? 반쪽짜리 성능 아닌가..)
결론
1. 회귀계수를 최대한 작게 만들어준다.(최소제곱법과 비교했을 때) α값을 조정해 회귀계수 크기를 제어할 수 있다.
2. 1번으로 인해 학습데이터의 변동에 의해 회귀계수 추정치가 요동치는 것을 막을 수 있다.
sklearn 데이터를 릿지 회귀로 풀어보자. 당뇨병 데이터를 가져와 독립변수, 종속변수항으로 나누었다.
from sklearn.datasets import load_diabetes
diab = load_diabetes()
df_diab = pd.DataFrame(diab.data, columns=diab.feature_names)
df_diab['result'] = diab.target
x = df_diab.drop(columns=['result'])
y = df_diab['result']
릿지 함수를 정의한다. alpha는 릿지함수 속성에 넣어줄 α값이다.
np.logspace(m, n, l)은 m과 n을 포함하고 일정한 간격을 가지고 있는 l개의 로그 변수를 생성해준다.(1차원 np.array 데이터)
from sklearn.linear_model import Ridge
rg = Ridge()
alpha= np.logspace(-3, 1, 5)
data = []
for i, a in enumerate(alpha):
ridge = Ridge(alpha=a)
ridge.fit(x, y)
data.append(ridge.coef_)
df_coef = pd.DataFrame(data, index=alpha)
print(df_coef)


alpha값이 가장 작은 0.001에서 10까지 회귀계수의 변화를 보면 0에 수렴하고 있다는 것을 알 수 있다.
alpha값에 따른 회귀계수의 변화를 시각화해보자. plt.semilogx() 를 쓰면 x축을 log를 적용한 수치로 바꿀 수 있다. xscale/yscale('log', base=10)도 마찬가지로 사용
plt.axhline은 평행선 생성할 때 사용했음
fig = plt.figure()
plt.semilogx(df_coef)
plt.axhline(y=0, linestyle='--', color='black', linewidth=3)
plt.legend(df_coef.columns, bbox_to_anchor=(1,1))

LinearRegression을 사용해서 회귀계수를 구한 뒤 릿지회귀계수와 비교해봤다. Lr을 사용해 구한 회귀계수는 alpha값이 0인 릿지 회귀계수와 비슷하다
Lr = LinearRegression()
Lr.fit(x, y)
plt.plot(Lr.coef_, 'r-', label= 'LinearRegression')
plt.plot(df_coef.loc[0.001], '*-', label= 'Ridge 0.001')
plt.plot(df_coef.loc[10], '^-', label= 'Ridge 10')
plt.axhline(y=0, linestyle='--', linewidth=3)
plt.legend(df_coef.columns)
plt.legend(bbox_to_anchor=(1,1))

실제로 alpha값이 0.001인 회귀계수와 선형회귀계수 값이 비슷함. 그에 반해 alhpa값이 10인 회귀계수는 0에 근접하며 비교적 분산이 감소한 것을 눈으로 볼 수 있다.
'Daily' 카테고리의 다른 글
| 23.01.28 SVM 서포트 벡터 머신 (0) | 2023.01.29 |
|---|---|
| 23.01.28 Logistic Regression로지스틱 회귀 (0) | 2023.01.29 |
| 23.01.27 Lasso, Elasticnet 라쏘, 엘라스틱넷 (0) | 2023.01.28 |
| 23.01.24 Classification 분류분석 (0) | 2023.01.24 |
| 23.01.18 Regression 회귀분석 (0) | 2023.01.18 |