# ex03_iris데이터_다중분류
### 목표
- iris 데이터 활용하여 붓꽃 품종을 분류해보자
- 신경망에서 다중분류 학습하는 모델을 만들어보자
# 환경셋팅
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 훈련셋, 테스트셋 분리하는 도구 가져오기
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
# 데이터 살펴보기
data = load_iris()
data # bunch 객체 - 데이터 묶음
# {key:value} => 데이터 접근 시 dictionary 처럼 활용
# 키값들만 확인할 때 => 데이터.keys()
data.keys()
# data - 특성 데이터
# feature_names - 특성 이름
# target - 답 데이터
# target_names - 타겟(답 클래스) 이름
# DESCR - 설명하다, 기술하다, 데이터 정보 기술
# data - 특성 데이터 확인
# data['key] => data['data]
# data.key
data.data.shape # 실수형 숫자 데이터가 있음
# 2차원
# 150행, 4열(특성의 개수 => 4)
# 딥러닝 입력층에 연결되는 특성의 개수가 4개
# => input_dim 매개변수에 연결되어져야 하는 크기 값
# 특성 이름 확인
data.feature_names
# 'sepal length (cm)' : 꽃받침 길이
# 'sepal width (cm)' : 꽃받침 너비
# 'petal length (cm)' : 꽃잎의 길이
# 'petal width (cm)' : 꽃잎의 너비
# 특성이 총 4개
# 답 데이터 확인
data.target
# 랜덤 샘플링 작업이 필요함 => train_test_split
# 답 데이터 이름 확인
data.target_names
# 인덱스 번호로 매칭
# 'setosa' : 0
# 'versicolor' : 1
# 'virginica' : 2
# => 3가지의 iris 품종이 있음
# class 개수 = 3개
# 인공 신경망 모델의 출력층에서 units=3
# 문제와 답을 분리
# X = data.data
# y = data.target 이런식으로 분리 안해줘도 됨.
# 훈련용과 테스트용 분리
# 8 : 2
# 랜덤 3
X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.2, random_state=3)
# 크기 확인
X_train.shape, X_test.shape, y_train.shape, y_test.shape
# 특성 4개
# 답 데이터 전처리
# 각각의 클래스에 대한 확률을 출력, 오차 계산 계산하기 위해
# 원핫인코딩 => pd.get_dummies()
# 데이터 프레임으로 결과 출력, 2차원
# 1 => 0 1 0
# 0 => 1 0 0
# 2 => 0 0 1
y_train_oh = pd.get_dummies(y_train)
y_test_oh = pd.get_dummies(y_test)
# 딥러닝 패키지에 있는 원핫인코딩 도구
# from tensorflow.keras.utils import to_categorical
# to_categorical(바꿀 대상) # 2차원, array 배열로 출력됨
# y_train_oh = to_categorical(y_train) => array로 출력
# 크기 확인
y_train_oh.shape, y_test_oh.shape
# 클래스=3, 출력층 units 클래스의 개수만큼!
### keras 활용 인공신경망 생성
- 1. 신경망 구조 설계(뼈대 구축, 층 쌓기)
- 2. 학습/평가 방법 설정(compile)
- 3. 학습 및 시각화(fit)
- 4. 평가 + 예측값 확인(evaluate, predict)
# 도구 불러오기
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
# 1. 신경망 뼈대 구축
model = Sequential()
# 입력층 + 중간층1 설정
# 뉴런 16, 입력 특성의 개수 4개, 활성화 sigmoid
# units을 앞에 적어줄 때는 생략 가능!
model.add(Dense(16, input_dim=4, activation='relu'))
# 중간층 2개
# 32, 활성화
# 8, 활성화
# 다음층으로 몇 개의 특성이 전달되는지 작성은 X
model.add(Dense(32, activation='relu'))
model.add(Dense(8, activation='relu'))
# 출력층
# 다중분류
# 퍼셉트론 개수 -> 클래스의 개수 만큼
# 활성화 함수 -> 'softmax'
model.add(Dense(3, activation='softmax'))
# 모델 요약
model.summary()
# Param 퍼셉트론 안에 있는 w, b의 총 개수
# 2. 학습/평가 방법 설정
# 다중분류대로
# compile(오차loss, 최적화함수optimizer, 평가지표metrics)
model.compile(loss='categorical_crossentropy', # 손실함수 - 다중분류 오차계산 공식
optimizer='adam', # 경사하강법 종류 1 - 확률적 경사하강법
metrics=['accuracy'])
# 3. 학습 및 시각화
# 학습 현황 h 변수에 담기
# fit(훈련문제, 원핫훈련답, 반복횟수200)
h2 = model.fit(X_train, y_train_oh, epochs=200)
h2
h2.history['accuracy']
# h 학습현황 acc 기준으로 시각화
plt.figure(figsize=(10,3))
plt.plot(range(1, 201), h.history['accuracy'], label='h1_acc')
plt.plot(range(1, 201), h2.history['accuracy'], label='h2_acc')
plt.legend() # 범례 출력
plt.show()
# 결과적으로 해석해보기
# h2가 더 빨리 더 성능이 좋게 개선되고 있음
# 좋은 w, b를 빠르게 찾아내고 있음
# h가 안좋은 이유 -> 좋은 w, b를 늦게 찾고 잘못찾았기 때문에
# optimizer, activation 고쳐봤음
# 반복 횟수가 오래 지나야 성능 개선되는 현상이 보임
# 학습이 제대로 되지 않는 것 같음
# 최적의 w, b를 제대로 셋팅하지 못함
# 영향을 주는 매개변수는 무엇일까?
# 평가
# test
model.evaluate(X_test, y_test_oh)[1] # 약 97%
# 예측
pre = model.predict(X_test)
pre
# 열 3개(class : 3)
# 0, 1, 2
# 결과가 float 출력 => 과학적 표기법
# 각각 클래스에 대한 확률 정보
# 꽃 하나에 대한 확률 정보
# 데이터 값이 제일 큰 인덱스 번호(클래스 값) 출력 => np.argmax(확인배열)
np.argmax(pre[0]) # 0번째 꽃은 0이라고 예측
y_test[0]
댓글