2021. 9. 9. 02:45ㆍai/Machine Learning
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 : 확률
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 |