Multinomial classification(다중분류)

2021. 9. 9. 02:45ai/Machine Learning

728x90

Multinomial classification(다중분류) : logistic이 여러개 모여 다중분류

 

독립변수 1개 → 2차원상에 점이 찍히고 linear regresiion이 직선으로 나온다

독립변수 여러개 →독립변수에 갯수에 따라 hyperplane(초평면)이 변하는데  

                         차원이 올라갈수록 선 면 공간이 생긴다

(위 사진 참고)

hyperplane(초평면) : 2진분류에서 어느쪽에 있니의 기준선

아래식을 잘 보라

위 식은 각각을 구하는 linear regression이다  이를 아래쪽식과 같이 풀어서 사용할수 있다

 

 

 

linear legression모델이 학습이 끝나서 prediction한다 가정해보자 →

Cross Entropy를 각각 계산하면 A일 확률0.7123 /B일 확률 0.8585 /C일 확률 0.2347로 나온다 

[1 안에 ABC값을 구하고싶은데 각각 독립이라 모두 더해도 1이 아니에요]      그래서

 

logistic Model 과 Cross Entropy가 변한다 → A일 확률0.7/B일 확률 0.2 /C일 확률 0.1

 

 

 

Sigmoid → Softmax ( multinomial classfication의 model은 n개의 대한 확률값 )

Cross Entropy → Cross Entropy 

 

1. hyperplane(초평면) - Linear Regression       : y = Wx +b

w 와 b를 구해야 model이 완성되기때문에 gradient algorism을 통해 편미분을 통해 나온 값과 learning rate를 곱해

w 와 b를 update해서 학습을 진행해 model 완성

 

2. hyperplane(초평면) - Logistic Regression     : 1 / 1 + e ^ - (Wx +b) 

편미분 과정이 들어가고 그걸 하기위해 하나의 convex함수 형태로 하나의 함수형태로 loss함수라고 애기한다

logistic의 loss함수는 cross entropy 

를 편미분해서 줄여가지고 최적의 w와 b를 구한다

 

3. multinomial classification (다중분류)

(1) w는 행렬제곱을 위해 독립변수의 수와 같아야한다

   (독립변수의 수 = colum의 수 = 행의개수)

(2) w의 colum(열)의수는 class의 개수와 일치

(3) bias는 logistic의 개수의 따라 증가

 

 multinomial classification (다중분류) softmax (모델) 의 식

-n개의 확률이라 linear보다 복잡하다

probability : 확률

z = y

 multinomial classification (다중분류) cross Entropy( loss함수) 의 식

-model이 복잡하게 변해 cross Entropy도 변했다

Multinumial Classification은 Lable을 처리 해야해요!

 

- label이 0 과 1 이 아닌 A B C 이다

One - Hot - Encoding (하나만 뜨겁다) : 해당 label에 1로 넣고 나머지는 0으로 처리 

                                                     즉 a b c 각각 하나로 보고 숫자로 변경해서 사용하자 !!


 

# multinomial classification(다중분류) - BMI
# Tensorflow로 구현해 보아요!

%reset

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from scipy import stats                           #z - score로 이상치 처리
import tensorflow as tf

# Raw data Loading
df = pd.read_csv('./data/bmi/bmi.csv', sep=',', skiprows=3)

# skiprows=3 : csv 맨위 3줄은 건너뛰어



# 결측치 처리
# df.isnull().sum()   # 결측치가 없네요!!

# 이상치 처리
# zscore_threshold=1.8
# df.loc[np.abs(stats.zscore(df['height'])) > zscore_threshold, :]   # height에는 이상치가 없어요!
# df.loc[np.abs(stats.zscore(df['weight'])) > zscore_threshold, :]   # weight에는 이상치가 없어요!

 

# stats.zscore : z-score를구하는데 음수도 있기때문에

# np.abs       : 절대값


# train , validation data 분할

train_x_data, valid_x_data, train_t_data, valid_t_data = \
train_test_split(df[['height', 'weight']],
                 df[['label']],
                 test_size=0.3,
                 stratify=df[['label']],
                 random_state=1)

#df[['height', 'weight']] 는 x값을 fanct indexing으로 가져왔다

# Normalization(정규화)처리
scaler = MinMaxScaler()
scaler.fit(train_x_data)

train_x_data_norm = scaler.transform(train_x_data)
valid_x_data_norm = scaler.transform(valid_x_data)

del train_x_data    # 사용하지 않는 데이터는 삭제!
del valid_x_data

# t data는 one hot encoding을 해야하기 때문에 제외
# ONE-HOT Encoding 처리(Label처리)
# 0   -> 1 0 0
# 1   -> 0 1 0
# 2   -> 0 0 1
# 3가지 방법 중 하나를 이용해서 One-Hot Encoding을 처리
# numpy가 가지는 방법을 이용[복잡] , sklearn의 기능을 이용, Tensorflow의 기능을 이용
# 우리는 tensorflow 기능을 이용해서 one-hot encoding을 사용

sess = tf.Session()
train_t_data_onehot = sess.run(tf.one_hot(train_t_data, depth=3))
valid_t_data_onehot = sess.run(tf.one_hot(valid_t_data, depth=3))

 

#sess를 실행 시켜야 값을 땡길수 있다

#depth=3 는 class [t data종류] 의 갯수를 알려줘야 한다 왜냐하면 onehot incoding때문에

del train_t_data
del valid_t_data

 



# 데이터준비가 다 됬으니 Tensorflow graph를 그려보아요!

# placeholder
X = tf.placeholder(shape=[None,2], dtype=tf.float32)
T = tf.placeholder(shape=[None,3], dtype=tf.float32)

# Weight & bias
W = tf.Variable(tf.random.normal([2,3]))
b = tf.Variable(tf.random.normal([3]))

# Hypothesis(Model) => multinomial classification
logit = tf.matmul(X,W) + b
H = tf.nn.softmax(logit)   

 

#이전버전  H = tf.sigmoid(logit) => binary classification

# loss function

# binary classification loss  v 이전버전
# loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(logits=logit,
#                                                               labels=T))  

# multinolial classification loss
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)

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

# 반복학습
for step in range(10000):
    
    tmp, loss_val = sess.run([train, loss], 
                             feed_dict={X:train_x_data_norm, 
                                        T:train_t_data_onehot.reshape(-1,3)})
    if step % 1000 == 0:
        print('loss : {}'.format(loss_val))
        
       

# Evaluation(모델 평가)
# binary classification과는 달라요!
# X => [188  78]   정규화처리해서 [0.7   0.2]
# H => [[0.6  0.3   0.1]]   0      확률
# T => [1    0      0 ]     0       one hot encoding

# H 와 T 를 비교

predict = tf.argmax(H,1)        #h중 가장 큰값의 index  /  1은 axis를 뜻한다
correct = tf.equal(predict, tf.argmax(T,1))         # tf.equal 은 정답인지 확인
acc = tf.reduce_mean(tf.cast(correct, dtype=tf.float32))   #tf.cast : 숫자로 변환

print('accuracy(정확도) : {}'.format(sess.run(acc, feed_dict={X:valid_x_data_norm, 
                                                             T:valid_t_data_onehot.reshape(-1,3)})))

 

 

# Prediction 
predict_data = [[187, 78]]
predict_data_norm = scaler.transform(predict_data)
result = sess.run(predict, feed_dict={X:predict_data_norm})
print(result)  # [1] => normal

'ai > Machine Learning' 카테고리의 다른 글

tensor flow 2.0 ver  (0) 2021.09.10
MNIST(Multinomial classification)/model평가  (0) 2021.09.10
Regulerization(규제)  (0) 2021.09.08
SGDClassifier, StandardScaler  (0) 2021.09.08
titanic code  (0) 2021.09.07