Logistic Regression
- 선형 회귀 방식을 이용한 이진 분류 (binary classification)알고리즘
- 우리가 분류해야 하는 class가 두 개
- 분류 레이블 : 0 or 1
- 0~1 범위를 예측 결과로 갖는 모델 필요
- 가설 결과에 Sigmoid 함수 적용
- Logistic, sigmoid 함수
- S자 모양의 함수
- Logistic, sigmoid 함수
- e^(-z) ⇒ np.exp(-z) 사용
- 𝑧 값을 0과 1사이의 값으로 바꾸는 함수
Sigmoid 함수 원리
11=111=1인데, 분모 1에다 0보다 크거나 같은 어떤 수를 더 하면 그 결과는 1 보다 클 수 없다.
분모에 더 할 값은 𝑒^-𝑧, 이 값은 어떤 𝑧가 주어져도 0보다 작아 지지 않는다.
𝑒^-𝑧는 𝑧의 값이 크면 클 수록 0에 가까운 작은 수가 되고 𝑧z값이 작으면 무한대에 가까운 큰 수가 된다
따라서 𝑧의 값이 크면 𝑒^-𝑧의 값이 작아져서 1/1+𝑒^-𝑧의 값은 1에 가까워 지고 그 반대는 0에 가까워 진다.
- sklearn API
- sklearn.linear_model.LogisticRegression
Sigmoid 함수 그리기
# 이진 분류에 쓰이는 sigmoid
import numpy as np
import matplotlib.pyplot as plt
# e는 np.exp()로
def sigmoid(z):
return 1 / (1+np.exp(-z))
plt.figure(figsize=(10, 7))
x = np.arange(-10, 10)
y = sigmoid(x)
plt.plot(x, y)
plt.show()
로지스틱 회귀 실습
plt.figure(figsize=(8,6))
x = np.array([1,2,3,4,5,6,7,8,9,11,13])
y = np.array([0,0,0,0,0,0,0,1,1,1,1])
plt.scatter(x,y)
plt.show()
⇒ 이 그래프는 linear로 예측할 수 없으므로 부득이 하게 아래와 같이 표현해야 함
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.linear_model import LinearRegression
from sklearn.metrics import accuracy_score
model = LinearRegression()
model.fit(x.reshape(-1,1),y)
pred = model.predict(x.reshape(-1,1))
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.plot(x, pred, c ='r')
plt.show()
linear regression을 가미한 rogistic regression이다!
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
model = LogisticRegression()
model.fit(x.reshape(-1,1),y)
pred = model.predict(x.reshape(-1,1))
plt.figure(figsize=(8,6))
plt.scatter(x,y)
plt.plot(x, pred, c ='r')
plt.show()
정확도 예측
아래 두 표현 동일
#정확도
(pred==y).mean() # 1.0
accuracy_score(pred, y) # 1.0
로지스틱 회귀 실습 : 위스콘신 유방암 환자 데이터
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score
from sklearn.datasets import load_breast_cancer
# 데이터셋 로드
cancer = load_breast_cancer()
# 데이터 프레임
df = pd.DataFrame(cancer['data'], columns=cancer['feature_names']) # data안에는 feature만 들어감!
df['target'] = cancer['target']
df
이런 데이터는 nomalization보다 standardization 성능이 더 높다.
# standardization
scaler = StandardScaler()
scaled = scaler.fit_transform(df.drop('target',axis=1)) # target만 뺀 데이터 넣어야 함
# 데스트 분할하기
x_train, x_test, y_train, y_test = train_test_split(scaled, df['target'], random_state=10)
# 모델 생성 LogisticRegression 모델생성 / 학습하고 / 예측하기
model = LinearRegression()
model.fit(x_train, y_train)
# 예측
pred = model.predict(x_test)
#정확도 측정
accuracy_score(pred, y_test) # 0.958041958041958
분류 모델 평가지표 Accuracy = 예측결과가 동일한 데이타 건수 / 전체 예측 데이타 건수
- 직접 확인y_test 결과와 predict 결과를 서로 비교해보면 100% 일치하고 있지 않은 부분들이 두군데 보인다. 직접 확인..
- 사용자 함수 정의y_test, predict 이 2개의 변수를 비교해서 성능을 측정할수 있다. 아래는 함수를 이용해서 성능평가 함수를 직접 구현해서 만든것임.
- score() 라이브러리 사용accuracy_score 함수를 이용해서 성능측정 한다. from sklearn.metrics import accuracy_score Confusion Matrix
- 정밀도(Precision)
- 재현율(Recall)
- F1 Score
Accuracy
직접확인
pred = model.predict(x_test)
pred
'''
array([0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0,
1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0,
1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0,
1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1,
1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0])
'''
y_test
'''
172 0
553 1
374 1
370 0
419 1
..
545 1
161 0
434 1
59 1
164 0
Name: target, Length: 143, dtype: int32
'''
# zip : 두개의 리스트값을 병렬적으로 추출하는 기능
# 2)
y_tuple=list(zip(y_test, pred))
y_tuple
'''
[(0, 0),
(1, 1),
(1, 1),
(0, 0),
(1, 1),
(1, 1),
(1, 1),
.
.
.
'''
사용자함수 정의
count = 0
for a,b in y_tuple:
if not a==b:
count = count+1
print('unmatched : (y_test, pred)=(',a,',',b,')')
print('UnMatched Target',count,'개')
'''
unmatched : (y_test, pred)=( 0 , 1 )
unmatched : (y_test, pred)=( 1 , 0 )
unmatched : (y_test, pred)=( 0 , 1 )
unmatched : (y_test, pred)=( 1 , 0 )
unmatched : (y_test, pred)=( 1 , 0 )
unmatched : (y_test, pred)=( 1 , 0 )
UnMatched Target 6 개
'''
len(y_test) # 143
accuracy_score 함수사용
# accuracy = accuracy_score(y_test, pred)
accuracy = accuracy_score(pred,y_test)
print(accuracy) # 0.958041958041958
오차 행렬 (Confusion Matrix)
성능지표에서 잘 활용되는 있는 오차행렬은 학습된 분류모델이 예측을 수행하면서 얼마나 헷갈리고(Confusion) 있는지도 잘 보여주는 지표이다.
아래 코드의 결과를 보면 a와 b의 오차 행렬 결과로 아래 두 가지 특징을 보인다.
- cherry를 apple로 잘못 예측
- cherry를 banana로 잘못 예측
from sklearn.metrics import confusion_matrix
from IPython.display import Image
# 샘플데이타
y_true=[2,0,2,2,0,1]
y_pred=[0,0,2,2,0,2]
confusion_matrix(y_true, y_pred)
'''
array([[2, 0, 0],
[0, 0, 1],
[1, 0, 2]], dtype=int64)
'''
a = ['cherry','apple','apple','banana','cherry'] #Label
b = ['banana','apple','apple','banana','apple'] #Predict
confusion_matrix(a, b) # 라벨 a 먼저, 그 다음 데이터 b 순서
'''
array([[2, 0, 0],
[0, 1, 0],
[1, 1, 0]], dtype=int64)
'''
a = ['cherry','apple','apple','banana','cherry'] #Label
b = ['banana','apple','apple','banana','apple'] #Predict
confusion_matrix(a, b) # 라벨 a 먼저, 그 다음 데이터 b 순서
'''
array([[2, 0, 0],
[0, 1, 0],
[1, 1, 0]], dtype=int64)
'''
실제 데이터 적용
cm = confusion_matrix(y_test, pred)
cm
''' 이차원 배열 구조
array([[50, 2],
[ 4, 87]], dtype=int64)
'''
cm = pd.DataFrame(confusion_matrix(y_test, pred), columns=cancer['target_names'],
index = cancer['target_names']
)
cm
import seaborn as sns
plt.figure(figsize=(6,5))
sns.heatmap(cm, annot=True, annot_kws={'size':20}, cmap='Blues')
plt.xlabel('Predict', fontsize=20)
plt.xlabel('Actual', fontsize=20)
위의 2 표시 되는 곳으로 표시한 곳이 암인데 정상으로 예측했기 때문에 더 위험하다.
위의 경우를 잡아내는 것이 recall 이라고 한다.
Accuracy와 함께 사용되는 보조 지표로서 재현율인 Recall 과 정밀도인 Precision 두 가지 서로 trade off 관계이기 때문에 둘을 종합적으로 판단하는 f1score를 사용한다.
Accuracy
보조지표 두 가지
분류 문제에서 정확도와 재현율을 ~하는 것이 가장 중요
- Recall (재현율)
- 가로 방향 (암, 정상 순서)
- 암 환자가 원래는 52가 나아야 하는데 50명밖에 안 나옴, 2명은 정상으로 오진단
- Precision (정밀도)
- 세로 방향 (암, 정상 순서)
- 정상인데 암으로 4명을 예측함, 따라서 암진단에서는 precision이 별로 중요하지 않다.
'AI > 머신러닝' 카테고리의 다른 글
[머신러닝] Ensemble (앙상블) (0) | 2022.04.18 |
---|---|
[머신러닝] 결정트리 (0) | 2022.04.18 |
[머신러닝] 회귀 모델 (Regression Models) 2 (0) | 2022.04.16 |
[머신러닝] 회귀 모델 (Regression Models) 1 (0) | 2022.04.16 |
[머신러닝] 경사하강법 (Gradient Descent) 2 (0) | 2022.04.16 |
댓글