로지스틱 회귀는 퍼셉트론과 아달린과 마찬가지로 이진 분류를 위한 선형 모델이다. 퍼셉트론에서는 클래스가 선형적으로 구분되지 않으면 수렴하지 않는다는 것이 큰 단점인데 로지스틱 회귀에서는 이러한 단점을 해소할 수 있다.
로지스틱 회귀도 아달린과 마찬가지로 활성화 함수 이후에 오차를 결정하고 가중치 업데이트를 수행하지만 다른 점은 활성화 함수가 무엇인가이다.
이름은 회귀(Regression) 이지만 로지스틱 회귀는 분류(Classification) 모델이다.
로지스틱 회귀는 단순히 샘플이 어디에 속하는지 분류하는 것이 아니라 샘플이 속하는 확률을 계산할 수 있어서 확률을 다루는 다양한 분야에서 사용된다.
로지스틱 회귀는 양성샘플(y=1)일 확률을 사용한 모델이다.
이 확률은 오즈비(odds ratio)로 나타내는데 P/(1-P)로 작성한다.
여기서 P = 양성샘플일 확률이다.
그리고 오즈비에 log를 붙인다.
다음과 같이 확률과 최종입력 z와의 관계가 만들어진다.
식을 풀어서 확률에 대한 식으로 나타내면 최종입력을 변수로 받아서 확률을 출력하는 시그모이드 함수가 만들어진다.
로지스틱 회귀에서는 이 시그모이드 함수를 가중치 업데이트 전 활성화 함수로 사용한다.
아달린과 로지스틱 회귀의 다른점은 이 활성화 함수의 차이이다.
활성화 함수를 그래프로 나타내면 위 그림과 같은데 최종입력을 확률로 변환해주고 확률 >= 0.5 이면 양성(y=1)로 판단하고 확률<0.5 이면 음성으로 판단한다.
이러한 활성화 함수를 이용해서 가중치를 업데이트 하며 결정 경계를 학습한다.
로지스틱 회귀모델에서 가중치를 학습하는 방법은 가능도 L(w)를 정의함으로써 설명가능하다.
가능도 L(w)는 가중치를 최대화하려는 식이다.
여기에 로그를 씌운식에 -를 붙이면 최소화하려는 식이 완성되므로 이것을 J(w) 비용함수로 정의한다.
비용함수와 확률과의 관계를 살펴보면 y=1(양성샘플)일 때 양성샘플일 확률이 높아지면(정확히 예측하면) 비용함수가 낮아지는 것을 볼 수 있다.(오차가 작아진다)
반대로 부정확한 예측을 했을 경우에는 비용함수가 무한대로 발산한다.
이러한 비용함수를 통해 가중치 업데이트 값을 구하고 가중치를 학습할 수 있는데 J(w)를 w로 편미분 한 것을 사용한다. 여기서 아달린(Adaline)모델과 유사성을 찾을 수 있는데 이 식은 아달린의 경사하강법과 동일하다.
따라서 아달린 클래스에서 활성화 함수와 비용함수를 수정함으로써 로지스틱 회귀를 구현할 수 있다.
### 로지스틱 회귀 클래스 ###
아달린 클래스에서 activation 메소드 (활성화 함수)를 수정하고 fit 메소드에서 cost(비용함수)를 계산하는 방법을 바꿈으로써 쉽게 구현할 수있 다.
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
class LogisticRegressionGD(object):
def __init__(self, eta=0.05, n_iter=100, random_state=1):
self.eta = eta # 학습률
self.n_iter = n_iter # 학습 횟수
self.random_state = random_state
# 로지스틱 회귀 객체 생성자
def fit(self, X, y):
# 훈련데이터 학습
# X : 2차원배열 훈련데이터, y: 1차원배열 타깃 값
rgen = np.random.RandomState(self.random_state)
self.w_ = rgen.normal(loc=0.0, scale=0.01, size=1 + X.shape[1])
self.cost_ = []
for i in range(self.n_iter):
net_input = self.net_input(X)
output = self.activation(net_input)
errors = (y - output)
self.w_[1:] += self.eta * X.T.dot(errors) # 절편을 제외한 나머지 구하기
self.w_[0] += self.eta * errors.sum() # 절편구하기
# 가중치 W를 계산
cost = (-y.dot(np.log(output))-
((1-y).dot(np.log(1-output))))
self.cost_.append(cost)
# 비용함수를 계산, 아달린과 다른 점
# 제곱오차합을 계산하는 것이 아니라 로지스틱 비용을 계산한다.
return self
def net_input(self, X):
return np.dot(X, self.w_[1:]) + self.w_[0]
# 최종입력 net_input 계산 메소드
# 절편과 나머지 입력에 가중치를 곱해서 최종입력을 구함
def activation(slef, z):
return 1. / (1. + np.exp(-np.clip(z, -250, 250)))
# 선형 활성화 계산 메소드
# 아달린에서는 입력을 그대로 사용하는 항등함수 모양이었지만
# 로지스틱회귀에서는 시그모이드 함수를 활성화 함수로 사용한다.
def predict(self, X):
return np.where(self.net_input(X) >= 0.0, 1, 0)
# 예측 메소드
# 단위계단 함수를 사용해서 클래스 레이블 반환
|
cs |
'머신러닝' 카테고리의 다른 글
선형회귀 - Linear Regression (3) | 2023.01.13 |
---|---|
커널 SVM으로 비선형적 데이터 분류 (0) | 2022.11.20 |
사이킷런으로 퍼셉트론 학습 (0) | 2022.11.17 |
적응형 선형 뉴런 Adaline, 경사하강법 (0) | 2022.11.17 |
퍼셉트론 Perceptron (1) | 2022.11.17 |