본문 바로가기

멀티캠퍼스 프로젝트형 AI 서비스 개발 5회차/ML

4/6 수

728x90

수요일!

 

오늘은 Multinomial Classification을 배운다.

Linear Regression(연속적인 숫자 값 예측)이 발전한 것이 Logistic Regression → Classification(분류를 판단하는 예측)
- Binary Classification(이항분류)
- Multinomial Classification(다항분류)

Logistic Regression은 이진 분류에 특화됨

SKlearn이 제공하는 분류기인 Gradient Descent(경사하강법)가 발전한 형태인 SGD Classifier(Stochastic Gradient Descent, 확률적 경사하강법)

 

1. Binary Classification - 위스콘신 유방암 데이터 by Gradient Descent Classifier

import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn import linear_model
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import warnings
warnings.filterwarnings('ignore')

# Raw Data Set Loading
cancer = load_breast_cancer()

# Data Set
x_data = cancer.data # 2차원 ndarray 독립변수(feature)
t_data = cancer.target # 1차원 ndarray 종속변수(label)

train_x_data, test_x_data, train_t_data, test_t_data = \
train_test_split(x_data, t_data, test_size=0.3, random_state=2, stratify=t_data) # stratify=t_data는 데이터가 편향되는 것을 방지함

# Model 생성
model = linear_model.LogisticRegression()

# Model 학습
model.fit(train_x_data, train_t_data)

# Accuracy로 Model 평가
test_score = model.score(test_x_data, test_t_data)

print('Logistic Regression Model의 정확도 : {}'.format(test_score)) # 0.9473684210526315

 

2. Binary Classification - 위스콘신 유방암 데이터 by SGD Classifier Ver. 1(정규화 안 함)

import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn import linear_model
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import warnings
warnings.filterwarnings('ignore')

# Raw Data Set Loading
cancer = load_breast_cancer()

# Data Set
x_data = cancer.data
t_data = cancer.target

train_x_data, test_x_data, train_t_data, test_t_data = \
train_test_split(x_data, t_data, test_size=0.3, random_state=2, stratify=t_data)

# Model 생성
sgd = linear_model.SGDClassifier(loss='log', # loss='log'는 Logistic Regression을 이용해 Binary Classification 하겠다.
                                tol=1e-5,    # log loss가 1e-5이면 반복을 멈춤
                                random_state=2)

# Model 학습
sgd.fit(train_x_data, train_t_data)

# Accuracy로 Model 평가
test_score = sgd.score(test_x_data, test_t_data)

print('SGD Classifier의 정확도 : {}'.format(test_score)) # 0.8947368421052632. 정규화를 안 했기 때문에 낮음

 

3. Binary Classification - 위스콘신 유방암 데이터 by SGD Classifier Ver. 2(정규화)

import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn import linear_model
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import warnings
warnings.filterwarnings('ignore')

# Raw Data Set Loading
cancer = load_breast_cancer()

# Data Set
x_data = cancer.data
t_data = cancer.target

train_x_data, test_x_data, train_t_data, test_t_data = \
train_test_split(x_data, t_data, test_size=0.3, random_state=2, stratify=t_data)

# Data 정규화
scaler = StandardScaler()
scaler.fit(train_x_data)

# Model 생성
sgd = linear_model.SGDClassifier(loss='log', # loss='log'는 Logistic Regression을 이용해 Binary Classification 하겠다.
                                tol=1e-5,    # log loss가 1e-5이면 반복을 멈춤
                                random_state=2)

# Model 학습
sgd.fit(scaler.transform(train_x_data), train_t_data)

# Accuracy로 Model 평가
test_score = sgd.score(scaler.transform(test_x_data), test_t_data)

print('정규화를 이용한 SGD Classifier의 정확도 : {}'.format(test_score)) # 0.9649122807017544. 정규화를 함

 

4. Binary Classification - 위스콘신 유방암 데이터 by SGD Classifier Ver. 3(정규화 + L2 규제)

Over-fitting(과대 적합) 방지하기 위해 Regularization 적용

import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn import linear_model
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import warnings
warnings.filterwarnings('ignore')

# Raw Data Set Loading
cancer = load_breast_cancer()

# Data Set
x_data = cancer.data
t_data = cancer.target

train_x_data, test_x_data, train_t_data, test_t_data = \
train_test_split(x_data, t_data, test_size=0.3, random_state=2, stratify=t_data)

# Data 정규화
scaler = StandardScaler()
scaler.fit(train_x_data)

# Model 생성
sgd = linear_model.SGDClassifier(loss='log', # loss='log'는 Logistic Regression을 이용해 Binary Classification 하겠다.
                                tol=1e-5,    # log loss가 1e-5이면 반복을 멈춤
                                random_state=2, # Random Seed
                                penalty='l2', # L2 - Ridge Regression로 규제 적용
                                alpha=0.001) # 규제 강도

# Model 학습
sgd.fit(scaler.transform(train_x_data), train_t_data)

# Accuracy로 Model 평가
test_score = sgd.score(scaler.transform(test_x_data), test_t_data)

print('정규화를 이용한 SGD Classifier의 정확도 : {}'.format(test_score)) # 0.9707602339181286. 정규화 + L2

여기까지가 Binary Classification(이항분류)


이제부터 Multinomial Classification(다항분류)

 

Multinomial에서는 Logistic에서 쓰는 Sigmoid가 아닌 Softmax를 사용하므로 모델(산식)도 Loss func(Cross Entropy)도 변경해야 함

Multinomial 1
Multinomial 2
Multinomial 3

 

1. Multinomial Classification - BMI 데이터 by Sklearn

import numpy as np
import pandas as pd
from sklearn import linear_model
from sklearn.preprocessing import MinMaxScaler # 결측치가 없기 때문에 정규화에 MinMaxScaler 사용
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from scipy import stats
import tensorflow as tf
import warnings
warnings.filterwarnings('ignore')

df = pd.read_csv('./data/bmi.csv', skiprows=3) # skiprows는 주석이 달려있는 상위 3행을 제외해라
# label 0: thin
# label 1: normal
# label 2: fat

display(df.head()); print(df.shape); display(df.info()) # (20000, 3)
# Data Preprocessing

# print(df.isnull().sum()) # None

zscore_threshold = 2.0 # Z-score로 이상치 처리
(np.abs(stats.zscore(df['height'])) > zscore_threshold).sum() # None
(np.abs(stats.zscore(df['weight'])) > zscore_threshold).sum() # None

#(array([0, 1, 2], dtype=int64), array([6470, 5857, 7673], dtype=int64))
# np.unique(df['label'], return_counts=True) # class의 비율 확인

# Train과 Validation Data Set으로 분리
train_x_data, test_x_data, train_t_data, test_t_data = \
train_test_split(df[['height', 'weight']], df['label'], test_size=0.3, random_state=1, stratify=df['label'])

# Normalization
scaler = MinMaxScaler()
scaler.fit(train_x_data)

norm_train_x_data = scaler.transform(train_x_data)
norm_test_x_data = scaler.transform(test_x_data)
# Model 생성 후 학습 및 평가
model = linear_model.LogisticRegression(C=1000) # C 옵션(alpha 값)으로 L2 규제를 적용할 수 있음. alpha=0.001(1/1000)
model.fit(norm_train_x_data, train_t_data)

predict_val = model.predict(norm_test_x_data)
acc = accuracy_score(predict_val, test_t_data)

print('Sklearn으로 구현한 Accuracy : {}'.format(acc)) # 0.9851666666666666, 0.9845

# Prediction
result = model.predict(scaler.transform(np.array([[187, 81]]))) # 187, 81 -> 1
print(result)

 

2. Multinomial Classification - BMI 데이터 by Tensorflow

여러 개의 class가 존재하기 때문에 행렬곱 연산을 위해 label을 One-Hot Encoding 처리를 해야 함

→ Tensorflow의 one_hot 기능을 이용해 Node로 만들기

 

학습 데이터의 사이즈가 매우 크면 메모리에 데이터를 모두 loading 할 수 없기 때문에 batch 처리를 해야 함

sess = tf.Session() # Tensorflow의 기능을 이용해 인코딩을 하므로 node가 생성됨
onehot_train_t_data = sess.run(tf.one_hot(train_t_data, depth=3)) # depth 옵션으로 class의 개수를 알려줘야 함
onehot_test_t_data = sess.run(tf.one_hot(test_t_data, depth=3))

# Placeholder
X = tf.placeholder(shape=[None,2], dtype=tf.float32) # 독립변수(feature)의 개수
T = tf.placeholder(shape=[None,3], dtype=tf.float32) # 원핫 인코딩! class의 개수이면서 Logistic의 개수

# Weight, bias
W = tf.Variable(tf.random.normal([2,3])) # 독립변수 2개, W 3개
b = tf.Variable(tf.random.normal([3]))

# Model, Hypothesis
logit = tf.matmul(X,W) + b
H = tf.nn.softmax(logit) # Multinomial Classification의 Softmax

# Cross Entropy(loss func)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=logit, labels=T))

# Train
train = tf.train.GradientDescentOptimizer(learning_rate=1e-1).minimize(loss)

# Session 초기화
sess.run(tf.global_variables_initializer())

# 반복 학습
# for step in range(10000):
#     _, loss_val = sess.run([train, loss], feed_dict={X:norm_train_x_data, T:onehot_train_t_data})
    
#     if step % 1000 == 0:
#         print('loss value : {}'.format(loss_val))

# Memory Fault 나는 것을 방지하기 위해 데이터를 쪼개서 학습 -> batch 처리
num_of_epoch = 1000 # 학습을 위한 전체 epoch 수
num_of_batch = 100   # 한번에 학습할 데이터 양

for step in range(num_of_epoch):
    total_batch = int(norm_train_x_data.shape[0] / num_of_batch) # 학습 데이터의 개수 / batch
    
    for i in range(total_batch):
        batch_x = norm_train_x_data[i*num_of_batch:(i+1)*num_of_batch] # [0:100], [100:200] ~. 100개씩 Slicing
        batch_y = onehot_train_t_data[i*num_of_batch:(i+1)*num_of_batch]
        _, loss_val = sess.run([train, loss], feed_dict={X:batch_x, T:batch_y})
        
    if step % 100 == 0:
        print('loss value : {}'.format(loss_val))
# 성능평가(Accuracy)
result = sess.run(H, feed_dict={X:scaler.transform(np.array([[187, 81]]))})

# print(result)       # [[4.761967e-05 9.079144e-01 9.203796e-02]]
# print(result[0,1])  # 0.9079144
# print(result.max()) # 중간의 0.9079144(1)가 가장 높은 확률
# print(np.argmax(result, axis=1)) # [1].가장 큰 값의 index를 추출

predict = tf.argmax(H,1)
correct = tf.equal(predict, tf.argmax(T,1))
accuracy = tf.reduce_mean(tf.cast(correct, dtype=tf.float32))

result = sess.run(accuracy, feed_dict={X:norm_test_x_data, T:onehot_test_t_data})
print(result) # 0.9855

앞으로 큰 사이즈의 데이터와 딥러닝을 다뤄야 하기 때문에 로컬의 Jupyter Notebook에서 구글 Colab으로 옮긴다!

 

수정 → 노트 설정 → 하드웨어 가속기 : GPU로 저장

print(tf.__version__) # Tensorflow의 기본 2.8.0. 버전 지우고 1.15.0 설치
!pip uninstall tensorflow
!pip install tensorflow==1.15

 

1. 3/15 화 2. 3/16 수 3. 3/17 목 4. 3/18 금 5. 3/21 월
ML
환경 설정

(아나콘다, 주피터 노트북),
Pandas,

Numpy,
ndarray
ML
Numpy,

행렬곱연산,
전치행렬,
iterator,
axis,
Pandas,
Series,
DataFrame
ML
Pandas,
DataFrame,

함수들
ML
Pandas,
데이터 분석,
데이터 전처리
ML
Pandas,
데이터 전처리,
수행평가
6. 3/22 화 7. 3/23 수 8. 3/24 목 9. 3/25 금 10. 3/28 월
ML
데이터 시각화,
Matplotlib,
기술통계
ML
기술통계
ML
기술통계,
머신러닝
ML
미분,
Regression
ML
머신러닝 기법들,
Regression
11. 3/29 화 12. 3/30 수 13. 3/31 목 14. 4/1 금 15. 4/4 월
ML
Regression 구현
(Python, Scikit-Learn)
ML
Outlier,
Z-score,
MinMaxScaler,
다변수
 ML
Tensorflow,
Classification
ML
Binary Classification,
Logistic Regression
ML
평가지표(Metrics)
16. 4/5 화 17. 4/6 수 18. 4/7 목 19. 4/8 금 20. 4/11 월
ML
평가 시 주의사항
(Over-fitting,
Regularization,
Over-Sampling)
ML
Multinomial Classification,
SGD Classifier,
Softmax,
batch
ML ML  

* 교재로도 수업 내용을 복습하자!

728x90

'멀티캠퍼스 프로젝트형 AI 서비스 개발 5회차 > ML' 카테고리의 다른 글

4/8 금  (0) 2022.04.08
4/7 목  (0) 2022.04.07
4/5 화  (0) 2022.04.05
4/4 월  (0) 2022.04.05
4/1 금  (0) 2022.04.01