일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 딥러닝
- 취업부트캠프 5기
- SQL
- AWS builders
- 특성중요도
- sql정리
- SLASH22
- 유데미코리아
- 토스
- pytorch
- NLU
- 추천시스템
- 유데미부트캠프
- 부트캠프후기
- 데이터도서
- BERT
- 사이드프로젝트
- MatchSum
- 스타터스
- 스타터스부트캠프
- 알고리즘
- AARRR
- 그로스해킹
- 유데미큐레이션
- 서비스기획부트캠프
- NLP
- 취업부트캠프
- 임베딩
- 그래프
- 서비스기획
- Today
- Total
다시 이음
회귀 분석 - 4 (Logistic Regression) 본문
Logistic Regression
훈련/검증/테스트(train/validate/test)
- 훈련데이터는 모델을 Fit(학습) 하는데 사용합니다.
- 검증데이터는 예측 모델을 선택하기 위해서 예측의 오류를 측정할 때 사용합니다.
- 테스트데이터는 일반화 오류를 평가하기 위해 선택된 모델에 한하여 마지막에 한 번 사용합니다. 테스트세트는 훈련이나 검증과정에서 사용하지 않도록 주의해야 합니다. 왜냐하면 테스트데이터가 유출(leak)이 되어 훈련/검증과정에 사용이 되면 모델을 잘못 평가하게 됩니다.
** 검증데이터를 통해 transform을 하게 되면 모델에 성능을 확인 할 수 있지만 성능을 개선하지는 못합니다. 개선하는 것은 하이퍼파라미터(직접 지정하여 변화를 줄 수 있는 파라미터)를 적절하게 변경함으로써 가능합니다.
Logistic Regression
로지스틱 회귀는 회귀분석 같지만 사실은 분류문제를 해결하는 방법입니다.
그중에서도 target이 이변량 종속변수(0,1의 값을 가지는 변수)인 경우에 사용하고 있습니다.
1) 분류문제를 해결하기 위해 기준모델 설정하기
- 분류문제에서는 보통 타겟 변수에서 가장 빈번하게 나타나는 범주를 기준모델로 설정합니다.
타겟 범주가 어떤 비율을 가지고 있는지 확인하는 것이 우선입니다.
# 타겟 설정
target = '열 이름'
# 타겟 데이터 범주의 비율을 확인합니다.
y_train = train[target]
y_train.value_counts(normalize=True)
# mode(): 최대로 빈번한 값을 반환
major = y_train.mode()[0]
# 타겟 샘플 수 만큼 0이 담긴 리스트를 만듭니다. 기준모델로 예측
y_pred = [major] * len(y_train)
#위의 과정에서 오류가 난다면 major의 형태가 시리즈가 아닌 데이터프레임일 경우입니다.
#이유는 타겟값을 시리즈가 아닌 데이터프레임으로 설정했기 때문인데요.
#y_train.mode()의 값을 시리즈로 변환시킨 후에 진행을 하면 오류를 없이 진행이 가능합니다.
2) 분류문제의 평가 지표
분류문제에서는 회귀문제와 다른 평가지표를 사용합니다.
즉, r2과 같은 평가지표를 사용할 수 없습니다.
여러 방법이 있지만 이번에는 정확도(Accuracy)에 대해서만 다루도록 하겠습니다.
# 최다 클래스의 빈도가 정확도가 됩니다.
from sklearn.metrics import accuracy_score
print("training accuracy: ", accuracy_score(y_train, y_pred))
# 검증세트 에서도 정확도를 확인해 볼 수 있습니다.
y_val = val[target]
y_pred = [major] * len(y_val)
print("validation accuracy: ", accuracy_score(y_val, y_pred))

궁금증 타임) 분류문제를 회귀분석을 통해서 해결 할 수 있을까??
범주형 데이터인 타겟을 가지는 분류문제를 연속적 데이터를 다루는 회귀분석을 통해 해결이 가능할까요?
답은 어느정도의 유추는 가능하다 입니다.
설정한 feature(독립변수)의 계수값을 통해서 유추가 가능합니다.
linear regression을 사용하여 model학습을 완료한 이후 coef_ 메소드를 통해 각 특성의 계수를 보면
음수 혹은 양수의 값을 가지고 음수라면 그 특성의 크기가 클수록 타겟의 false에 가까워진다고 해석하고
양수라면 특성의 크기가 클수록 타겟의 true 값에 가까워 진다고 해석할 수 있겠죠?
하지만 엄연히 한계가 있습니다.
정확한 특성 값을 입력하고 predict를 통해 예측을 하면 0,1의 값을 벗어나 더 크거나 음수의 값을 가질 수도 있습니다.
그렇기 때문에 정확한 결과를 알 수가 없고 위에서 언급한 분류문제 평가지표를 적용할 수 없습니다.
3) 로지스틱 회귀 란?
로지스틱 회귀는 확률값으로 0,1로 나누어 표현이 됩니다.
위의 그래프가 로지스틱 회귀 그래프입니다.
확률값이 정해진 기준값 보다 크면 1 아니면 0 이라고 예측을 하게 됩니다.
-Logit transformation
로지스틱회귀의 계수는 비선형 함수 내에 있어서 직관적으로 해석하기가 어려운데 오즈(Odds) 를 사용하면 선형결합 형태로 변환 가능해 보다 쉽게 해석이 가능합니다. 오즈는 실패확률에 대한 성공확률의 비 인데 예를들어 odds = 4 이면 성공확률이 실패확률의 4배 라는 뜻입니다. 분류문제에서는 클래스 1 확률에 대한 클래스 0 확률의 비라고 해석하면 되겠습니다.
오즈비는 다른 집단 간에 발생할 확률의 비를 의미합니다. 즉, 독립변수가 분류 결정에 미치는 영향의 정도를 계량화 하는데 사용합니다.
로지스틱회귀분석에서는 오즈비로 계산을 하는데 그 이유는 다음과 같습니다.
- 수리적 관점에서 비율 혹은 확률은 0과 1사이의 값만 존재하지만 오즈로 계산하게되면 0에서 무한대 값이 됩니다. 종속변수의 범위가 마이너스 무한대에서 무한대로 실수 전체 구간으로 확대됨으로써 회귀모델로 추정하는 것이 가능해집니다.
- 더욱 현실적인 결과로 해석된다는 장점이 있습니다. 로지스틱 회귀분석의 목적은 종속변수의 두 범주 중 어떤 특정 범주에 속할 확률 또는 가능성을 파악하는 것입니다. 그런 결과가 나오게 된 이유가 무엇인지 얼마나 영향을 주었는지 등을 파악할 수 있습니다.
오즈비가 1보다 크면 독립변수가 종속변수에 양의 방향으로 영향을 미친다는 뜻을 의미합니다. 따라서, 다른 집단과의 비교값인 오즈비가 더욱 타당한의미를 가집니다. 확률과 오즈에서 나타나는 문제 모두 해결 가능함에 따라 1차식의 관계가 도출될 수 있고 선형관계로 모델 추정이 쉽게 때문에 로지스틱 회귀분석에서는 오즈비를 사용합니다.
이렇게 오즈에 로그를 취해 변환하는 것을 로짓변환(Logit transformation) 이라고 합니다.
로짓변환을 통해 비선형형태인 로지스틱함수형태를 선형형태로 만들어 회귀계수의 의미를 해석하기 쉽게 하는데, 특성 X의 증가에 따라 로짓(ln(odds))가 얼마나 증가(or감소)했다고 해석을 할 수 있게 됩니다.
4) 로지스틱 회귀 만들기
데이터를 모델에 적합하기 전에 3 가지 데이터 변환을 수행해보겠습니다.
- 카테고리 데이터 처리를 위해 OneHotEncoder
- 결측치(missing value) 처리를 위한 SimpleImputer
- 특성들의 척도를 맞추기 위해 표준정규분포로 표준화하는(평균=0, 표준편차=1) StandardScaler

*참고하면 좋은 정보)
이전 포스팅에서 범주형 데이터를 시스템에 인식시키기 위해서 원핫인코딩을 사용한다고 했습니다.
그러나, 문자열로 이루어진 범주형 데이터의 경우에는 무조건 인코딩을 거쳐야 하지만 숫자형 데이터인 범주형 데이터는 변환하지 않더라도 모델에 학습이 가능합니다.
물론 숫자열로 이루어진 범주형 데이터를 인코딩하지 않으면 로지스틱 회귀 평가지표를 통해 성능을 확인할 때 했을 때와 차이가 있습니다.
이러한 차이는 두가지 경우를 모두 실행해서 성능을 파악하고 성능이 좋은 방법을 택하면 됩니다.
from category_encoders import OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
features = ['열이름']
target = '열이름'
X_train = train[features]
y_train = train[target]
X_val = val[features]
y_val = val[target]
#원핫인코딩
encoder = OneHotEncoder(use_cat_names=True) # cols='열이름'을 지정하면 원하는 열만 인코딩
X_train_encoded = encoder.fit_transform(X_train)
X_val_encoded = encoder.transform(X_val)
#결측치를 평균으로 대치
imputer = SimpleImputer(strategy='mean')
X_train_imputed = imputer.fit_transform(X_train_encoded)
X_val_imputed = imputer.transform(X_val_encoded)
#특성값을 표준화
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train_imputed)
X_val_scaled = scaler.transform(X_val_imputed)
#로지스틱 회귀 학습
from sklearn.linear_model import LogisticRegression
logistic = LogisticRegression()
logistic.fit(X_train_imputed, y_train)
#평가지표 사용하기
print('검증세트 정확도', logistic.score(X_val_imputed, y_val))
#예측하기
logistic.predict(특성마다 값설정넣기)
#타겟값 0,1에 속할 확률 확인하기
logistic.predict_proba(test_case)
# 로지스틱 회귀의 계수는 비선형형태여서 계수값 자체는 해석이 어렵다.
# 선형회귀분석과 비교했을 때 회귀계수 수치는 변했지만 방향은 같음을 볼 수 있습니다.
print(logistic.coef_)
'AI 일별 공부 정리' 카테고리의 다른 글
트리 기반 모델 - 1 결정 트리 (Decision Trees) (0) | 2021.08.18 |
---|---|
회귀 분석 - 5 (Polynomial Regression) (0) | 2021.08.16 |
회귀 분석 - 3 (Ridge Regression) (0) | 2021.08.12 |
회귀 분석 - 2 (다중회귀분석) (0) | 2021.08.10 |
회귀 분석 - 1 (단순선형회귀모델) (0) | 2021.08.09 |