04-1 로지스틱 회귀
데이터 준비하기
판다스 데이터프레임에서 하나의 열을 선택하면 1차원 배열에 해당하는 판다스 시리즈(series) 객체가 반환됩니다.
따라서 Species 열을 선택할 때 fish[[‘Species’]]와 같이 두 개의 괄호를 사용하지 않도록 주의하세요.
이렇게 하면 fish_target이 데이터 프레임이 됩니다.
scikit-learn의 대부분의 모델은
-
입력 x → 2차원 DataFrame 또는 2차원 ndarray
-
타깃 y → 1차원 Series 또는 1차원 ndarray
k-최근접 이웃 분류기의 확률 예측
다중 분류(multiclass classification) : 타깃 데이터에 2개 이상의 클래스가 포함된 문제
이진 분류와 모델을 만들고 훈련하는 방식은 동일합니다.
다중 분류에서도 타깃값을 숫자로 바꾸어 입력할 수 있지만 사이킷런에서는 편리하게도 문자열로 된 타깃값을 그대로 사용할 수 있습니다.
이때 주의할 점은 타깃값을 그대로 사이킷런 모델에 전달하면 순서가 자동으로 알파벳 순으로 매겨집니다.
따라서 pd.unique(fish['Species'])
로 출력했던 순서와 다릅니다.
KNeighborsClassifier
에서 정렬된 타깃값은 classes_
속성에 저장되어 있습니다.
predict() 메서드 : 타깃값으로 예측을 출력
predict_proba() 메서드 : 클래스별 확률값 반환
round() 함수는 기본으로 소수점 첫째 자리에서 반올림을 하는데, decimals 매개변수로 유지할 소수점 아래 자릿수를 지정할 수 있습니다.
kneighbors() 메서드의 입력은 2차원 배열이어야 합니다.
이를 위해 넘파이 배열의 슬라이싱 연산자를 사용했습니다.
슬라이싱 연산자는 하나의 샘플만 선택해도 항상 1차원 배열이 만들어집니다.
test_scaled[3:4]
→ 테스트 데이터에서 4번째 샘플 하나만 슬라이싱해서 가져온 것 (주의: 3
만 쓰면 1차원이 돼서 2차원 형태 유지하려고 3:4
로 씀)
kneighbors()
→ 입력한 샘플과 훈련 데이터의 거리와 이웃의 인덱스(번호)를 구해줌.
distances
: 입력 샘플과 k개의 이웃까지의 거리값
indexes
: 그 이웃들의 훈련 데이터 내 인덱스 값
indexes[0]
: kneighbors()
가 반환한 이웃들의 인덱스 리스트 (예: [4, 27, 15]
)
train_target.iloc[indexes[0]]
→ 훈련 타깃 데이터에서 그 이웃들의 타깃값만 골라서 출력
로지스틱 회귀
로지스틱 회귀(logistic regression) : 이름은 회귀이지만 분류 모델
z=a×Weight+b×Length+c×Diagonal+d×Height+e×Width+f
z는 어떤 값도 가능하나 확률이 되려면 0~1 사이 값이 되어야 합니다
→ 시그모이드 함수(또는 로지스틱 함수) 사용 : z가 아주 큰 음수일 때 0이 되고, z가 아주 큰 양수일 때 1이 되도록 바꾸어 주는 방법
이진 분류일 경우 시그모이드 함수의 출력이 0.5보다 그면 양성 클래스, 작으면 음성 클래스로 판단합니다.
정확히 0.5일 때 라이브러리마다 다른데, 사이킷런은 음성 클래스로 판단합니다.
로지스틱 회귀로 이진 분류 수행하기
불리언 인덱싱(boolean indexing) : 넘파이 배열에서 True, False 값을 전달하여 행을 선택
첫 번째 열이 음성 클래스(0)에 대한 확률이고 두 번째 열이 양성 클래스(1)에 대한 확률입니다.
사이킷런은 타깃값을 알파벳순으로 정렬하여 사용하므로 Bream이 음성 클래스 입니다.
y=−0.4038⋅Weight−0.5762⋅Length−0.6628⋅Diagonal−1.0129⋅Height−0.7317⋅Width−2.1616
LogisticsRegression 클래스는 decision_function() 메서드로 z값을 출력할 수 있습니다.
z값은 모델이 얼마나 강하게 1(또는 0)에 가까운지를 말해주는 수치입니다.
로지스틱 회귀에서의 예측 과정은 다음과 같습니다
-
선형 결합
-
시그모이드 함수로 확률 계산
decision_function()
은 위의 z값,predict_proba()
는 시그모이드 함수로 계산된 확률을 반환합니다.
파이썬의 scipy 라이브러리에도 시그모이드 함수(expit)가 있습니다.
np.exp() 함수를 사용해 분수 계산을 하는 것보다 훨씬 편리하고 안전합니다.
출력된 값을 보면 predict_proba() 메서드 출력의 두 번째 열과 동일합니다.
→ 즉, decision_function() 메서드는 양성 클래스에 대한 z값을 반환합니다.
로지스틱 회귀로 다중 분류 수행하기
1. 반복 알고리즘과 max_iter
-
로지스틱 회귀는 정답을 한 번에 계산하지 않고, 정답에 가까운 값을 조금씩 반복해서 찾는 방식을 사용합니다.
-
이걸 최적화(optimization) 라고 합니다.
이때, 최대 몇 번 반복할지 정하는 것이 max_iter
입니다.
-
기본값은
100
, 즉 최대 100번 반복해서 답을 찾습니다. -
데이터가 복잡하거나 정답 찾기가 어려우면, 더 많이 반복해야 할 수도 있습니다.
-
반복이 부족하면 경고가 뜨고, 모델이 제대로 훈련되지 않을 수 있습니다.
2. 규제(Regularization)란?
-
규제는 과적합(overfitting) 을 막기 위한 장치입니다.
-
모델이 훈련 데이터에 너무 잘 맞춰져서, 새 데이터에서는 못 맞히는 걸 방지합니다.
규제는 계수(w)의 크기를 너무 커지지 않게 제한합니다.
3. L2 규제 (= 릿지 회귀와 같은 방식)
-
LogisticRegression
은 기본적으로 L2 규제를 사용합니다. -
이는 각 계수(가중치)의 제곱을 더해서 페널티를 주는 방식입니다.
-
여기서
는 규제의 세기를 조절하는 숫자입니다.
4. alpha
vs C
차이
모델 | 규제 세기 조절 변수 | 값이 커질수록 규제는 |
---|---|---|
릿지 회귀 | alpha |
강해짐 |
로지스틱 회귀 (sklearn) | C |
약해짐 (반대 방향) |
C
는 “규제의 역수”입니다.
-
C
가 작을수록 규제가 강해집니다. -
C=1
이 기본값C=0.1
→ 규제 강함C=10
→ 규제 약함
이진 분류에서는 시그모이드 함수를 사용해 z를 0과 1 사이의 값으로 변환합니다.
다중 분류는 이와 달리 소프트맥스(softmax) 함수를 사용하여 클래스 개수의 z값을 확률로 변환합니다.
소프트맥스 함수는 여러 개의 선형 방정식의 출력값을 0~1 사이의 확률로 압축하고 전체 합이 1이 되도록 만듭니다.
일반적인 맥스(max)함수는 최댓값 하나를 고르지만 소프트맥스는 최댓값에 높은 확률을 할당하면서도 다른 값에도 작은 확률을 부여합니다.
이를 위해 지수함수를 사용하기 때문에 정규화된 지수 함수라고도 부릅니다.
04-2 확률적 경사 하강법
점진적인 학습
점진적 학습(온라인 학습) : 데이터를 한꺼번에 다 쓰지 않고, 하나씩 들어올 때마다 조금씩 학습하는 방식
대표 알고리즘 : 확률적 경사 하강법(Stochastic Gradient Descent)
확률적 경사 하강법
확률적 : ‘무작위하게’ 혹은 ‘랜덤하게’의 기술적인 표현
경사 : 기울기
확률적 경사 하강법은 훈련세트에서 랜덤하게 하나의 샘플을 선택하여 가파른 경사를 조금 내려갑니다.
그다음 훈련 세트에서 랜덤하게 또 다른 샘플을 하나 선택하여 경사를 조금 내려갑니다.
이런식으로 전체 샘플을 모두 사용할 때가지 계속합니다.
모든 샘플을 다 사용해도 산을 다 내려오지 못했으면 다시 처음부터 시작합니다.
에포그(epoch) : 확률적 경사 하강법에서 훈련 세트를 한 번 모두 사용하는 과정
미니배치 경사 하강법(minibatch gradient descent) : 여러개의 샘을 사용해 경사 하강법을 수행하는 방식
배치 경사 하강법(batch gradient descent) : 전체 샘플 사용
전체 데이터를 사용하기 때문에 가장 안정적인 방법이지만 그만큼 컴퓨터 자원을 많이 사용하게 됩니다.
확률적 경사 하강법은 최적의 장소로 조금씩 이동하는 알고리즘이기 때문에 훈련 데이터가 모두 준비되어 있지 않고 매일매일 업데이터되어도 학습을 계속 이어나갈 수 있습니다.
신경망 알고리즘
신경망은 일반적으로 많은 데이터를 사용하기 때문에 한 번에 모든 데이터를 사용하기 어렵습니다.
→ 확률적 경사 하강법이나 미니배치 경사 하강법 사용
손실 함수
손실 함수(loss function) : 어떤 문제에서 머신러닝 알고리즘이 얼마나 엉터리인지 측정하는 기준
(손실 함수의 값이 작을수록 좋습니다.)
손실 함수와 비용 함수
손실 함수 : 샘플 하나에 대한 손실을 정의
비용 함수 : 훈련 세트에 있는 모든 샘플에 대한 손실 함수의 합
손실 함수는 미분 가능해야 합니다.
로지스틱 손실 함수
손실함수한 모델이 예측한 결과와 실제 정답이 얼마나 차이 나는지 측정하는 함수입니다.
예측이 정답과 가까우면 손실(loss)이 작고, 틀리면 손실이 커집니다.
모델은 이 손실을 최소화하도록 학습합니다.
즉, 손실함수는 모델의 성능을 평가하고 개선하는 기준이 됩니다.
로지스틱 손실함수는 주로 이진 분류(binary classification) 문제에 사용됩니다.
예측이 1에 가까울수록 좋은 모델이며, 예측이 1에 가까울수록 타깃의 곱의 음수는 점점 작아집니다.
음성클래스의 경우에는 타깃을 마치 양성 클래스로 바꾸어 1로 만들고, 예측값도 양성 클래스에 대한 예측으로 바꿉니다.
여기에서 예측 확률에 로그 함수를 적용하면 0~1 사이에서 음수가 되므로 최종 손실 값은 양수가 됩니다.
로그 함수는 0에 가까울수록 아주 큰 음수가 되기 때문에 손실을 아주 크게 만들어 모델에 큰 영향을 미칠 수 있습니다.
- 타깃 = 1 일 때 → -log(예측 확률)
- 타깃 = 0 일 때 → -log(1-예측 확률)
이 손실 함수를 로지스틱 손실 함수(logistic loss function) 또는 이진 크로스엔트로피 손실 함수(binary cross-entropy loss function)라고 부릅니다.
크로스엔트로피 손실 함수(cross-entropy loss function) : 다중 분류에서 사용하는 손실 함수
SGDClassifier
훈련 세트에서 학습한 통계 값으로 테스트 세트도 변환해야 합니다.
여기서 핵심은 ss.fit()
은 train_input에만 적용하고,ss.transform()
은 train_input과 test_input 모두에 적용한다는 점입니다.
특성값의 스케일을 맞춘 trian_scaled와 test_scaled 두 넘파이 배열을 준비했습니다.
사이킷런에서 확률적 경사 하강법을 제공하는 대표적인 분류용 클래스는 SGDClassifier입니다.
다중 분류일 경우 SGDClassifier에 loss=’log_loss’로 지정하면 클래스마다 이진 분류 모델을 만듭니다.
즉, 도미는 양성 클래스로 두고 나머지는 모두 음성 클래스로 두는 방식입니다.
이런 방식을 OvR(One versus Rest)이라고 부립니다.
확률적 경사 하강법은 점진적 학습이 가능합니다.
SGDClassifier 객체를 다시 만들지 않고 모델을 이어서 훈련할 때는 partial_fit() 메서드를 사용합니다.
이 메서드는 fit() 메서드와 사용법이 같지만 호출할 때마다 1 에포크씩 이어서 훈련할 수 있습니다.
에포크는 훈련 데이터 전체를 한 번 모두 사용해서 학습하는 과정을 말합니다.
에포크와 과대/과소적합
확률적 경사 하강법을 사용한 모델은 에포크 횟수에 따라 과소적합이나 과대적합이 될 수 있습니다.
적은 에포크 횟수 동안에 훈련한 모델은 훈련 세트와 테스트 세트에 잘 맞지 않는 과소적합된 모델일 가능성이 높습니다.
반대로 많은 에포크 횟수 동안에 훈련한 모델은 훈련 세트에 너무 잘 맞아 테스트 세트에는 오히려 점수가 나쁜 과대적합된 모델일 가능성이 높습니다.
훈련 세트 점수는 에포크가 진행될수록 꾸준히 증가하지만 테스트 세트 점수는 어느 순간 감소하기 시작합니다.
바로 이 지점이 모델이 과대적합되기 시작하는 곳입니다.
과대적합이 시작되기 전에 훈련을 멈추는 것을 조기 종료(early stopping)라고 합니다.
SGDClassifier는 일정 에포크 동안 성능이 향상되지 않으면 더 훈련하지 않고 자동으로 멈춥니다.
tol 매개변수에서 향상될 최솟값을 지정합니다.
loss 매개변수의 기본값은 ‘hinge’입니다.
힌지 손실(hinge loss)은 서포트 벡터 머신(support vector machine)이라 불리는 또 다른 머신러닝을 위한 손실 함수입니다.
기본 숙제
Ch.04(04-1) 확인문제(p.208) 2번 풀고, 설명하기
2. 로지스틱 회귀가 이진 분류에서 확률을 출력하기 위해 사용하는 함수는 무엇인가요?
① 시그모이드 함수
② 소프트맥스 함수
③ 로그 함수
④ 지수 함수
로지스틱 회귀는 이진 분류에서 각 샘플이 특정 클래스에 속할 확률을 계산하기 위해 시그모이드 함수를 사용합니다.
이 함수는 입력값을 0과 1 사이의 값으로 변환하여 확률처럼 해석할 수 있게 만듭니다.
반면, 소프트맥스 함수는 다중 클래스 분류에서 여러 클래스 확률을 구할 때 사용되고,
로그 함수와 지수 함수는 각각 확률 계산의 일부로 쓰이지만 확률 변환 함수 자체는 아닙니다.
따라서 이진 분류 확률 출력을 위한 함수로는 시그모이드가 정답입니다.
추가 숙제
Ch.04(04-2) 과대적합/과소적합 손코딩(p.220)하고 코랩 화면 캡쳐하기