- RandomForestClassifier를 활용한 mnist 머신 러닝 및 confution matrix -
<개요>
머신 러닝의 대표적인 예제인 mnist를 랜덤 포레스트를 활용
1. 데이터를 로드
2. 학습을 시킨 후 모델을 저장
3. 저장된 모델로 테스트를 진행하고 정확도를 도출
4. 모델의 출력 결과와 정답본을 비교하여 confusion matrix를 생성
5. confusion matrix를 시각화
# MNIST
MNIST는 (Modified National Institute of Standards and Technology database)는 손으로 쓴 숫자들로 이루어진
대형 데이터 베이스이며, 28 x 28 픽셀로 된 60,000개의 트레이닝 이미지와 10,000개의 테스트 이미지를 포함한다.
<코드 설명>
# tensorflow에서 제공하는 mnist 데이터셋을 불러옴
import tensorflow as tf
# 랜덤포레스트 모델 사용
from sklearn.ensemble import RandomForestClassifier
# 저장하고 불러오는 라이브러리
from joblib import dump, load
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
필요한 라이브러리들을 import
confusion matrix를 통해 결과를 보여줄 것이므로 matplotlib.pyplot과 seaborn 라이브러리도 import
# 데이터 로드
# 인자를 안 넣어주면 자동으로 False
def load_dataset(online=False):
# tensorflow 에서 제공하는 mnist 데이터 셋
if online:
(tr_data, tr_lable), (te_data, te_lable) = tf.keras.datasets.mnist.load_data()
# online 이 아닐 경우 같은 경로상에 있는 mnist.npz 데이터 셋을 사용
else:
path = "mnist.npz" # numpy 파일
(tr_data, tr_lable), (te_data, te_lable) = tf.keras.datasets.mnist.load_data(path)
return (tr_data, tr_lable), (te_data, te_lable)
온라인 혹은 오프라인으로 데이터를 로드하여 (tr_data, tr_lable), (te_data, te_lable)에 각각 저장
# 학습 및 저장
def train(x, y):
# 랜덤포레스트 모델 사용
csf = RandomForestClassifier()
# 학습
csf.fit(x, y)
# 학습데이터에 대해서 얼마나 맞혔는지 알아보는 점수
print(csf.score(x, y))
# 학습된 모델을 "rf_mnist.pkl" 파일로 저장
dump(csf, "rf_mnist2.pkl")
인자를 받아(train_data, train_label) 랜덤 포레스트 모델을 사용하여 학습
학습 데이터에 대한 점수도 확인
학습시킨 모델을 dump 메서드를 이용해 "rf_mnist2.pkl" 이름으로 저장
모델을 저장하는 이유는 코드를 실행할 때마다 학습하는 시간을 아끼기 위함
# 테스트
def test(x, y):
# 모델 로드
model = load("rf_mnist.pkl")
# 테스트 데이터 예측
result = model.predict(x)
# 정확도 계산을 위한 변수 지정
hit = 0
miss = 0
dif_list = []
# test_label 과 예측한 result 의 결과가 같으면 hit += 1, 다르면 miss += 1
for i in range(len(x)):
if y[i] == result[i]:
hit += 1
else:
miss += 1
print(f'맞힌 개수 : {hit}\n틀린 개수 : {miss}\n정확도 : {(hit / (hit + miss)) * 100}%')
return result
테스트 데이터를 예측 후 test_label과 result를 비교하여 정확도를 계산
# confusion matrix 만드는 함수
# 각 숫자를 어떤 숫자로 인식했는지 확률을 구해주는 함수
def make_conMatrix(x, y):
# 크기가 [10x10] 인 0 행렬 생성
cm = []
for i in range(10):
cm.append([0] * 10)
# cm의 (result[i], test_label[i]) 자리에 1 추가
# -> 각 숫자를 어떤 숫자로 인식했는지 개수를 셈
for i in range(10000):
cm[x[i]][y[i]] += 1
# 행의 총 합으로 각 행의 요소들을 나눠준다. -> 확률 구하기
for i in range(10):
sum_i = sum(cm[i])
for j in range(10):
cm[i][j] = round((cm[i][j] / sum_i) * 100, 2)
return cm
각 숫자를 어떤 숫자로 인식했는지 그 확률을 보여주는 confusion matrix를 생성
# confusion matrix 시각화
def show_conMatrix(x):
# plt 창 크기
plt.figure(figsize=(12, 10))
# seaborn 의 heatmap 메소드를 활용해 table 로 생성
sns.heatmap(x, linewidths=3, annot=True, cmap='YlGnBu', fmt=".2f")
plt.title('MNIST Confusion Matrix', fontsize=25)
plt.show()
위에서 만든 confusion matrix를 heatmap을 이용해 시각화
# 메인에서 함수 호출
if __name__ == "__main__":
# 데이터 로드 함수 호출
(train_data, train_lable), (test_data, test_lable) = load_dataset()
# 학습 데이터 변환
# [28 x 28]인 2차원 행렬 데이터를 [1 x 784]인 1차원벡터(한 줄)로 된 데이터로 만듬
train_data = train_data.reshape(60000, 784)
# 학습
train(train_data, train_lable)
# # 테스트 데이터 변환
# test_data = test_data.reshape(10000, 784)
# # test 함수를 실행해 return 값인 result 를 calResult 에 저장.
# calResult = test(test_data, test_lable)
# # confusion 함수를 실행해 return 값인 cm 을 conMatrix 에 저장.
# conMatrix = make_conMatrix(calResult, test_lable)
# # confusion matrix 출력
# show_conMatrix(conMatrix)
train 함수를 먼저 실행하여 학습 후,
train 함수는 주석 처리하고 아래 test, make_conMatrix, show_conMatrix 함수들을 실행하여 결과를 도출
<전체 코드>
import tensorflow as tf
from sklearn.ensemble import RandomForestClassifier
from joblib import dump, load
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
def load_dataset(online=False):
if online:
(tr_data, tr_lable), (te_data, te_lable) = tf.keras.datasets.mnist.load_data()
else:
path = "mnist.npz"
(tr_data, tr_lable), (te_data, te_lable) = tf.keras.datasets.mnist.load_data(path)
return (tr_data, tr_lable), (te_data, te_lable)
def train(x, y):
csf = RandomForestClassifier()
csf.fit(x, y)
print(csf.score(x, y))
dump(csf, "rf_mnist.pkl")
def test(x, y):
model = load("rf_mnist.pkl")
result = model.predict(x)
hit = 0
miss = 0
dif_list = []
for i in range(len(x)):
if y[i] == result[i]:
hit += 1
else:
miss += 1
print(f'맞힌 개수 : {hit}\n틀린 개수 : {miss}\n정확도 : {(hit / (hit + miss)) * 100}%')
return result
def make_conMatrix(x, y):
cm = []
for i in range(10):
cm.append([0] * 10)
for i in range(10000):
cm[x[i]][y[i]] += 1
for i in range(10):
sum_i = sum(cm[i])
for j in range(10):
cm[i][j] = round((cm[i][j] / sum_i) * 100, 2)
return cm
def show_conMatrix(x):
plt.figure(figsize=(12, 10))
sns.heatmap(x, linewidths=3, annot=True, cmap='YlGnBu', fmt=".2f")
plt.title('MNIST Confusion Matrix', fontsize=25)
plt.show()
if __name__ == "__main__":
(train_data, train_lable), (test_data, test_lable) = load_dataset()
# train
train_data = train_data.reshape(60000, 784)
train(train_data, train_lable)
# test
test_data = test_data.reshape(10000, 784)
calResult = test(test_data, test_lable)
# confusion matrix
conMatrix = make_conMatrix(calResult, test_lable)
show_conMatrix(conMatrix)
<실행 화면>
정확도가 약 97% 나오는 것을 확인
- Just Do It -
'Python > Machine_learning' 카테고리의 다른 글
[Python] IRIS (0) | 2021.07.24 |
---|---|
[Python] CIFAR-10 (0) | 2021.07.24 |