ML 지도 학습 중 회귀(Regression)에 대해 알아보자.
ML을 위해 샘플 데이터를 많이 사용하는데, 이때 load_dataset에서 사용되는 data의 타입 Bunch에 대해 알아보자.
Dictionary와 유사한 형태로, key들의 종류와 그 의미는 아래와 같다.
- data: 분석이나 모델 학습에 쓰이는 메인 입력 데이터 (보통 변수 X 사용)
- target: 지도 학습 등에서 정답값(라벨) (보통 변수 y 사용)
- feature_names: 입력 데이터 각 컬럼의 의미나 이름
- target_names: 정답값의 실제 클래스 이름 (예: 'setosa', 'versicolor', 'virginica')
- DESCR: 데이터셋에 대한 상세 설명, 출처, 특성 등 읽기 자료
- filename: 원본 데이터 파일의 위치(일부 데이터셋에서만 제공)
X.shape의 의미 = ( (sample 크기, 단측치 수 = 데이터 개수, batch ), feature의 수 )
Question
훈련 데이터와 테스트데이터간 Index는 완전히 동일할까?
train_test_split() 하더라도 인덱싱이 순차적이진 않지만 pair는 동일함을 보장함.
Train/Test 데이터는 항상 분할하지만, Validation data 까지 분할하는건 어떤 경우일까?
Validation data 사용 목적 : 학습중에 학습이 충분히 완료되었는지 평가하고 재학습 시키기 위해서.
DL의 경우 epoch 단위로 학습을 하는 경우에 있어 단위별로 끝나는 경우마다 검증 데이터를 활용하여 추가 학습 진행 여부 판단.
회귀 분석
독립변수(=feature, 연속형/범주형)가 종속변수(=레이블,연속형 변수)에 미치는 영향을 추정하는 통계적 방법
- 선형 회귀 : 가장 기본적인 회귀 분석 방법으로, 데이터 간의 관계가 선형일 때 사용
- 회귀 직선 Y = wx + b (w: 가중치 = 회귀계수, b : 편향)
- 최소 제곱법 (Ordinary Least Squares, OLS) : 회귀 직선(w,b)을 찾기 위한 방법, 데이터 포인트와 회귀 직선 사이의 거리(잔차)를 최소화
- 간단한 편미분/연립방정식을 통해 정확한 값을 계산 가능
- 독립변수가 많이지면 계산량이 증가하며, 이상치가 많은 경우 성능이 하락.
- ex) RSS를 줄이려고 하는 과정에서, ^2에 따라 이상치의 값을 줄였을 때 보다 유리하다고 판단. -> 무시해야 되는 이상치에 overfitting.
- 경사 하강법 (Gradient Descent) : 가설에 대한 비용이 최소화 되는 가중치와 편향을 찾는 방법, 비용 계산에 함수로 MSE를 사용.
- 대부분의 최적화 문제를 풀 수 있는 범용적인 기법
- 한번에 처리하는 데이터의 양에 따라 성능이 크게 차이남
- 최소 제곱법 (Ordinary Least Squares, OLS) : 회귀 직선(w,b)을 찾기 위한 방법, 데이터 포인트와 회귀 직선 사이의 거리(잔차)를 최소화
- 회귀 직선 Y = wx + b (w: 가중치 = 회귀계수, b : 편향)
평가지표 (metric)
1. MSE (Mean Squared Error, 평균제곱오차)
실제값과 예측값의 차이를 제곱해서 평균낸 값.
오차가 클수록 값이 크게 증가하여, 이상치에 민감함.
예측 오차의 크기를 원래 데이터의 단위와 동일하게 만들어 해석을 쉽게 해주는 RMSE(MSE의 제곱근)를 보다 많이 사용한다.
2. MAE (Mean Absolute Error, 평균절대오차)
실제값과 예측값의 차이의 절댓값을 평균낸 값.
MSE에 비해 이상치(Outlier)에 덜 민감.
3. R-squared ($R^2$, 결정계수)
전체 변동성(분산) 대비, 모델이 설명하는 비율. 1에 가까울수록 우수한 성능.
예측값이 실제값과 얼마나 잘 맞는지(설명력)를 0~1 사이로 표시.
모델이 성능이 안좋은 경우 음수가 나올 수 있으며, 이 경우 그 모델은 사용하지 않는다.
4. MSLE (Mean Squared Logarithmic Error, 평균제곱로그오차)
예측값과 실제값의 차이를 로그 변환 후 제곱한 뒤 평균을 구한 지표
- 주로 데이터의 차이가 상대적으로 중요하거나, 값의 스케일이 크고 이상치가 많을 때 사용 (수요 예측)
- 실제값과 예측값이 모두 클 때, 작은 차이는 크게 평가하지 않고, 값이 작을 때 오차에 더 민감 (작은 예측에 penalty)
- 0 이하 값에는 부적합 (로그 함수의 특성상, 입력값이 항상 0 이상이어야 함)
- RMSE와 동일하게 RMSLE를 주로 사용
회귀 모델
회귀 문제의 데이터 전처리
- Feature Scailing : feature간 다른 범위를 가지지 않도록 조정
- 거리 기반 알고리즘이나 경사 하강법을 사용하는 모델에 유용
- 결측치 처리 : Simple Imputer, KNN Imputer, Iterative Imputer
- 이상치 처리 : 제거 혹은 로그 변환을 통해 분포를 조정 (제거해도 되는 이상치인지에 대한 판별이 필요.)
- Feature Selection : 상관관계가 낮거나 다중공선성이 있는 피쳐를 제거
- Feature Engineering : 기존 특성을 결합하거나 수학적 변환을 통해 새로운 피쳐를 생성
- Log Transformation : 데이터 분포를 정규에 가깝게 만들기 위해 사용 (분포 안정화 및 이상치 영향 감소)
- 차원 축소 기법 : 주성분 분석(PCA)를 통해 분산을 최대화하는 방향으로 새로운 축을 생성하여 데이터를 저차원 공간으로 투영
Feature Scaling
- 스케일: 연속형 변수의 분포 위치(평균 등)와 범위(최소~최대) 정보를 포함하는 개념
- 스케일링(Scaling): 데이터를 일정한 위치와 범위로 변환하는 과정
- 스케일 차이 문제점
- 거리 계산 시 스케일 큰 변수가 결과를 지배하여 왜곡 발생
- 경사 하강법의 최적화 경로가 비효율적이고 불안정해져 수렴이 느려짐
- 해결책
- MinMaxScaler 0~1 (이미지 데이터, 값이 한정되어 있는 경우와 같이 이상치 자체를 정의하지 않는 경우에 사용)
- StandardScaler 평균 0 , 표준편차 1로 조정 (이상치와 정상치의 거리가 줄어듬, 가장 보편적인 방법, 이상치가 너무 크면 영향을 받음..)
- RobustScaler (이상치가 너무 큰 경우에 사용. )
Scailing 과 Polynomial중 뭘 먼저 해야 할까?
^은 값의 scale이 바뀌더라도 모양은 유지가 되기에, 항상 다항특성 변환을 먼저 하고, Scailing을 나중에 진행하자.
다항 회귀 모델
x와 y가 비선형관계일 때 사용
기존 특성을 다항 특성으로 확장 (다항특성 변환) -> 결과를 선형 회귀 모델에 삽입
like x^2을 인자로 넘겼지만 나는 이걸 x라고 해석할래..
선형 회귀와 동일하게 범위 밖의 값에서도 예측이 가능하지만, 지수적으로 증가하기에 거리가 멀어짐에 따라 결과가 다를 위험성이 있다.
차수가 높아질수록 훈련 데이터에 과적합될 가능성이 큼.
import pandas as pd
from sklearn.preprocessing import PolynomialFeatures
dummy = pd.DataFrame({
'X1':[1,2,3],
'X2':[4,5,6],
})
P = PolynomialFeatures(degree=2, include_bias= False, interaction_only=False ) #degree : 최고차항의 차수
# 변환과정은 fit -> transfrom
P.fit(dummy) # X특성 데이터만 전달 (2D로), 학습 데이터로만
poly = P.transform(dummy) # 변환 발생, 학습/검증/평가 모두
# poly = P.fit_transform(dummy) # fit과 transfrom 동시에 진행
pd.DataFrame(poly, columns=P.get_feature_names_out())
- Degree 1 : 선형 회귀
- 예시로 보여주기 위해 선형 회귀를 직선으로 표현할 뿐, feature이 많아지면 시각화 불가함을 인지하자.
- 항상 시각화를 우선 진행해서 피쳐들간의 관계를 파악하자.
- Degree가 높아짐에 따라 과적합 발생 확률 증가
선형 모델 성능 개선 방안
- L1 정칙화 (Regularization)
- Lasso 회귀로도 알려져 있으며, 목적 함수에 가중치의 절대값 합을 추가하는 방식으로 정칙화를 수행
- 특정 가중치를 0으로 만들거나 가깝게 하여 상대적으로 불필요한 특징을 제거한다.
- 데이터가 소량이거나 특징의 수가 많을 때 유용하다.
- 튜닝시 범위를 좁게 잡아서 세밀하게.
- 알파나 람다 값이 올라가면 계수가 0이 되면서 잘못된 FS 발생
- L2 정칙화
- 과적합 방지 및 모델의 일반화 성능을 개선하기 위해 사용
- 기존의 선형 회귀 식에 L2_penalty가 적용된 모델인 Ridge가 있다.
- |w| 가중치의 크기가 증가 한다는 것은 overfitting이 약화된다는걸 의미한다. (train 성능 감소, test 성능 증가)
- 튜닝시 범위를 넓게 잡아서 크게크게.
- 알파나 람다 증가시 계수의 방향 및 크기 정상화
- feature중 그 가중치의 값이 가장 큰 녀석들부터 감소시키기에, 모든 가중치의 값이 감소하지만 가중치가 0이 되는 케이스는 이론적으로 불가하다.
=> 모든 가중치의 영향력이 점점 비슷해진다.
- 다중공선성 (SKADA 중요!!) : 두 개 이상의 독립 변수가 가장 선형 관계를 가지는 경우 발생하는 문제.
- 두 변수가 상관계수가 1에 근접하다면..? 둘 다 가져갈 필요가 있을까..?
- 해결방법
- 상관관계가 높은 변수를 결합하여 새로운 변수를 생성
- 정칙화 기법을 사용하여 완화
- 다중공선성을 일으키는 변수 (높은 VIF값을 가진 변수)를 제거하여 모델 간소화
- 주성분 분석을 통해 상관관계 제거 및 저차원 공간으로 변환
- 교차 검증 : ML모델의 일반화 성능을 정확히 평가하기 위해 여러 번 훈련/검증 세트로 나누어 반복적으로 학습 및 평가하는 기법
- 데이터가 충분히 크지 않을 때는 여러 번 분할하는것을 권장
- 주로 K-fold 교차 검증을 사용. K개의 fold로 나누고 각 fold를 검증용으로, 나머지를 훈련용으로 해서 K번 반복수행.
- 하이퍼파라미터 튜닝
- 모델이 자동으로 학습(최적화)하는 가중치(파라미터)와는 구별된다.
- 값에 따라 모델이 과소적합/과대적합 될 수 있다.
- 그리드 서치는 여러 하이퍼파라미터에 대해 시도해볼 값들의 목록(범위, grid)를 정해두고 모든 조합을 완전 탐색하여 최적의 조합을 찾아내는 방법이다.
- 그리드 서치는 완탐이기에 오래 걸린다는 단점이 있음. -> RandomizedSearchCV 를 사용하면 내가 지정한 횟수만큼만 탐색.
- 앙상블
*VIF (Variance Inflation Factor) : 분산 팽창 요인이라고 하며, 특정 독립 변수가 다른 모든 독립 변수에 의해 얼마나 잘 설명되는지를 나타내는 지표
-> 보통 값이 10이상이면 다중공선성이 있다고 판단한다. (주로 변수들간의 상관관계를 시각화하여 판단)
# 하이퍼파라미터 후보(탐색 범위) 정의
param_grid = {
'alpha' : [0.001, 0.01, 0.1, 1.0]
}
# GridSearchCV 객체 생성
grid_search = GridSearchCV(model, param_grid, cv=5, scoring='neg_mean_squared_error')
grid_search.fit(X, y)
display(pd.DataFrame(grid_search.cv_results_))
# # 최적의 하이퍼파라미터와 그 때의 점수
print("최적의 파라미터:", grid_search.best_params_)
print("최적의 교차검증 점수:", grid_search.best_score_)
Question
로지스틱스 회귀는 회귀야? 분류야? 연속형 종속변수를 예측해?
(로지스틱스 회귀는 예외적으로 회귀가 들어가 있지만 분류에 사용하며, 연속형 변수가 아닌 범주형 종속변수를 예측한다.)
잔차와 오차는 뭐가 다를까?
y^이 모집단인지 표본집단인지에 따라 다름.
x[1,2,3,4,5] 는 (5,1) ? (1,5)?
- label data라면 (5,1)이 정답.
- 학습 데이터라면 둘 다 가능.
- 추론시에는 하나씩 데이터가 들어갈 수 있지만(1,5), 표준적으로는 batch 방식으로 데이터 삽입하며 (sample 수, feature 수)가 기준.
epoch early stopping과 validation data를 통한 추가 학습의 차이점 ?
early stopping을 통해서는 학습 데이터를 기준으로 성능을 검토한다면, validation data는 그 후 외부 데이터 (테스트 데이터)에서도 잘 동작하는지를 검토한다.
즉, eraly stopping 후 validation data로 검증을 해도 성능이 충분치 않다면, 다시 학습 진행 -> early stopping ->validation data 이렇게 반복될 수 있다.
내부적으로 log1p 사용중이기에 예측값에 음수가 있다면 0으로 치환후 사용해도 ok.
model.fit 과 preprocessor.fit 의 차이점
model -> 실질적인 학습
preprocessor -> 변환을 하기 위해 필요한 값을 미리 계산하는 과정
가중치의 값을 줄인다고 해도, 여전히 해당 변수는 존재하는데 왜 모델이 심플해진다고 말할 수 있을까?
실제 파라미터의 개수가 똑같고, 전체가 연산에 사용된다 하더라도, 그 결과로 만들어지는 x와 y의 관계가 심플하냐 복잡하냐로 기준을 이야기할 수 있다.