티스토리 뷰
멀티캠퍼스 AI과정/05 Machine Learning
Machine Learning 08 - 성능 평과와 Multinomial Classification, Overshooting, Overfitting, Cross Validation, Softmax 함수
jhk828 2020. 10. 6. 17:25Logistic Regression은 반드시 성능평가 (Accuracy)를 진행해야 한다.
성능 평가 지표 (Metric)
Learning Rate와 Overshooting
- Learning Rate가 너무 큰 경우 Overshooting이 발생하여 최적점을 지나친다.
- Learning Rate가 너무 작은 경우에는 최적점에 도달하지 못한 채 학습이 끝난다.
Overfitting
- Training data에 대해 학습이 너무 잘 아루어져서, 오히려 실제 입력 데이터에는 적용이 잘 안되는 경우
Overfitting을 해결하는 방법들
- 많은 양의 Training Data를 활용한다. -> 프로그래밍적으로는 해결x
- Feature Engineering을 통해 Feature (=독립변수)의 개수를 줄인다.
- Weight 값을 인위적으로 조절하는 Regulation 기법을 이용한다.
- 딥러닝에서는 Dropout을 이용한다.
Evaluation (평가)
- 데이터를 어떻게 나누어서 평가할 것인가?
Cross Validation
Multinomial Classification와 Softmax 함수
Multinomial Classficiation¶
BMI 지수에 대한 데이터로 학습 후 예측까지 진행해본다.
BMI 지수는 키와 몸무게를 가지고 저체중, 정상, 과체중, 비만을 판단하는 지수
BMI = 자신의 몸무게 (kg) / 키의 제곱 (m)
18.5 이하 =>저체중
18.5 ~ 23 => 정상
23 ~ 25 => 과체중
25 ~ 비만
BMI 지수를 조사한 데이터를 학습하여 예측한다. 3가지로 분류됨
sklearn으로 Multinomial Classificiation 구현¶
In [27]:
# Multinomial Classficiation
import numpy as np
import pandas as pd
# stats 서브패키지는 확률분포 분석 기능 제공
from scipy import stats
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.metrics import accuracy_score
df = pd.read_csv('./data/bmi.csv', skiprows=3)
display(df)
# 결측치 확인 - 없음
df.isnull().sum()
# 이상치 확인
zscore = 1.8
# height의 이상치 확인 => 셋 다 없음
# df.loc[np.abs(stats.zscore(df['height'])) >= zscore, :]
# df.loc[np.abs(stats.zscore(df['weight'])) >= zscore, :]
# df.loc[np.abs(stats.zscore(df['label'])) >= zscore, :]
# Data Split
# training, test 7:3 분리
# 나중에 Train부분은 k-fold cross validation을 진행한다.
x_data_train, x_data_test, t_data_train, t_data_test = \
train_test_split(df[['height', 'weight']], df['label'], test_size=0.3, random_state=0)
# Normalization
scaler = MinMaxScaler() # scaler 객체를 생성한다.
scaler.fit(x_data_train) # scaler 객체에 최대, 최소와 같은 정보가 들어간다.
x_data_train_norm = scaler.transform(x_data_train)
x_data_test_norm = scaler.transform(x_data_test)
del x_data_train # 혼동을 방지하기 위해 변수 삭제
del x_data_test
# sklearn 구현은 매우 간단!
# Model을 생성하고, 학습시키고, 예측한다.
model = LogisticRegression()
model.fit(x_data_train_norm, t_data_train)
# model의 정확도 측정
# cross validation
kfold = 10
kfold_score = cross_val_score(model, x_data_train_norm, t_data_train, cv=kfold)
print('### cross validation ###')
print('### cross validation score ###')
print('score : {}'.format(kfold_score))
print('평균 : {}'.format(kfold_score.mean()))
# 최종모델평가
predict_val = model.predict(x_data_test_norm) # 테스트 데이터로 예측값을 구한다.
acc = accuracy_score(predict_val, t_data_test)
print('Model의 최종 Accuracy : {}'.format(acc))
# Predict
height = 188
weight = 78
my_state = [[height, weight]]
my_state_val = model.predict(scaler.transform(my_state))
print(my_state_val) # [1] -> 정상
tesorflow로 Multinomial Classificiation 구현¶
In [18]:
import numpy as np
import pandas as pd
df = pd.read_csv('./data/bmi.csv', skiprows=3)
display(df)
In [23]:
%reset
# BMI Multinomial Example
import numpy as np
import pandas as pd
import tensorflow as tf
from sklearn.preprocessing import MinMaxScaler # Normalization
from sklearn.model_selection import train_test_split # train, test 데이터 분리
from sklearn.model_selection import KFold # cross validation
# Raw Data Loading
df = pd.read_csv('./data/bmi.csv', skiprows=3)
# 결측치와 이상치 확인 및 처리
# 이상 없음
# Data Split
x_data_train, x_data_test, t_data_train, t_data_test = \
train_test_split(df[['height','weight']], df['label'], test_size=0.3, random_state=0)
# 7:3 비율로 train과 test 데이터를 분리했다.
# x_data_test, t_data_test 두개는 맨 끝에서 모델의 최종 Accuracy를 측정할 때 한번 사용한다.
# Normalizaion 진행 (Min-Max Scaling)
scaler = MinMaxScaler()
scaler.fit(x_data_train) # 나중에 scaling을 하기 위한 정보를 scaler에게 세팅
x_data_train_norm = scaler.transform(x_data_train)
x_data_test_norm = scaler.transform(x_data_test)
del x_data_train # 에러를 방지하기 위해 사용하지 않는 변수 삭제
del x_data_test
t_data_train
# 정답에 해당하는 t_data_train을 살펴보니 Multinomial이다.
# One hot encoding으로 데이터를 변환시켜야 한다.
# 0 -> 1 0 0
# 1 -> 0 1 0
# 2 -> 0 0 1
# 종류 3가지 => Logistic 3개 => depth 3
# Numpy를 이용한 로직 처리와, Tensorflow API를 이용하는 방법이 있는데 후자 선택.
# Tensorflow node를 실행하기 위해 session이 필요하다.
sess = tf.Session()
# 우리가 사용할 label(t_data)을 one hot encoding 형태로 변환
t_data_train_onehot = sess.run(tf.one_hot(t_data_train, depth=3))
t_data_test_onehot = sess.run(tf.one_hot(t_data_test, depth=3))
del t_data_train # 에러를 방지하기 위해 사용하지 않는 변수 삭제
del t_data_test
# 지금까지 위에서 x_data_train_norm, t_data_train_onehot을 만들었다.
# training data set을 준비했다.
# 데이터가 준비 되었으니 Tensorflow Graph를 그려보자
# Placeholder
# shape=[None, n] => 행은 상관 없음
X = tf.placeholder(shape=[None, 2], dtype=tf.float32)
T = tf.placeholder(shape=[None, 3], dtype=tf.float32)
# Weight & bias
# X, T의 shape을 이용한 행렬 연산으로 수행되기 위해
# W: 각각의 열이 logistic 1개에 해당 => 3개가 뭉쳐있음
W = tf.Variable(tf.random.normal([2, 3]), name='weight') # 2가 키, 몸무게인가?
b = tf.Variable(tf.random.normal([3]), name='bias')
# Hypothesis (Model)
logit = tf.matmul(X, W) + b
H = tf.nn.softmax(logit) # tf.sigmoid() 대신
# loss function
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=logit,
labels=T))
# train
train = tf.train.GradientDescentOptimizer(learning_rate=0.1).minimize(loss)
# 반복학습하는 함수
# parameter
num_of_epoch = 1000
batch_size = 100 # 한번에 학습할 x_data와 t_data의 행의 수
def run_train(sess, train_x, train_t):
print('### 학습이 시작된다. ###')
# session과 초기화
sess.run(tf.global_variables_initializer())
total_batch = int(train_x.shape[0] / batch_size) # (14000, 2)[0] => 14000
for step in range(num_of_epoch):
for i in range(total_batch):
batch_x = train_x[i*batch_size:(i+1)*batch_size]
batch_t = train_t[i*batch_size:(i+1)*batch_size]
_, loss_val = sess.run([train, loss],
feed_dict={X: batch_x,
T: batch_t})
if step % 100 == 0:
print('Loss : {}'.format(loss_val))
print('### 학습이 종료된다.###')
# Accuracy (정확도 측정) # 0 1 2 일 확률
predict = tf.argmax(H, 1) # [[0.5 0.4 0.1]] 입력한 값에 대한 예측 중 가장 큰 값을 알아냄
# 2차원이기에 axis 지정, axis=1 열방향 가로 방향
correct = tf.equal(predict, tf.argmax(T, 1))
accuracy = tf.reduce_mean(tf.cast(correct, dtype=tf.float32))
# 1. 학습을 진행하고 Training data로 validation 수행 - 의미 없지만 오버피팅 확인
# 학습진행
# run_train(sess, x_data_train_norm, t_data_train_onehot)
# # Accuracy 측정 (Training data로 validation 수행)
# result = sess.run(accuracy, feed_dict={X:x_data_train_norm,
# T:t_data_train_onehot})
# print('Training data로 validation한 정확도 : {}'.format(result))
# 2. 이렇게 하는 것 보다는 Cross Validation을 하는게 좋다.
# Cross Validation
cv = 5 # [훈련, 검증] => 5 set가 만들어 진다.
results = [] # 5 set에 대한 accuracy를 구해서 liast 안에 넣는다.
kf = KFold(n_splits=cv, shuffle=True)
for training_idx, validation_idx in kf.split(x_data_test_norm):
# training_idx : 결국은 index 값을 알아온다.
train_x = x_data_train_norm[training_idx] # Fancy indexing
train_t = t_data_train_onehot[training_idx] # Fancy indexing
valid_x = x_data_train_norm[validation_idx]
valid_t = t_data_train_onehot[validation_idx]
run_train(sess, train_x, train_t)
results.append(sess.run(accuracy,
feed_dict={X:valid_x,
T:valid_t}))
print('CrossValidation 결과 : {}'.format(results))
print('CrossValidation 최종 결과 : {}'.format(np.mean(results)))
# 3. 최종 accuracy 확인
# 학습진행
run_train(sess, x_data_train_norm, t_data_train_onehot)
# Accuracy 측정
result = sess.run(accuracy, feed_dict={X:x_data_test_norm,
T:t_data_test_onehot})
print('최종 정확도 : {}'.format(result))
In [25]:
# Prediction
height = 187
weight = 78
my_state = [[height, weight]]
my_state_scaled = scaler.transform(my_state)
print(my_state_scaled)
result = sess.run(H, feed_dict={X:my_state_scaled})
print(np.argmax(result))
'멀티캠퍼스 AI과정 > 05 Machine Learning' 카테고리의 다른 글
Machine Learning 10 - Tensorflow 2.1, K-NN (0) | 2020.10.13 |
---|---|
Machine Learning 09 - Google Colab에서 MNIST 예제, Tensorflow 1.x version (0) | 2020.10.12 |
Machine Learning 07 - titatic (0) | 2020.10.05 |
Machine Learning 06 - Logistic Regression 정리, accuracy (0) | 2020.09.29 |
Machine Learning 05 Classification - Logistic Regression (0) | 2020.09.28 |
댓글