데이터 정의/EDA
[R/머신러닝/실습] 랜덤포레스트를 이용한 다중 분류 분석
데이터 정의 및 탐색적 데이터 분석(EDA) 1) 데이터 정의 iris 데이터셋은 꽃잎의 각 부분의 너비와 길이들을 측정한 데이터이며 150개의 레코드로 구성되어 있다. 변수명 변수 설명 Sepal.Length 꽃받
robinlovesyeon.tistory.com
위 링크 참고
파이썬에서는 seaborn을 이용한 변수 비교를 추가했다.
import seaborn as sns
sns.pairplot(raw_data, hue="Species", size=3, diag_kind="kde")
4개의 특성에 해당하는 Sepal.Length, Sepal.Width, Petal.Length, Petal.Width와 모든 쌍(pair)의 조합인 16개의 경우에 대한 산점도. 만약 동일한 특성의 쌍일 경우에는 히스토그램으로 나타냄.
다중 분류 분석
1) 데이터 호출
from SyncRNG import SyncRNG
import pandas as pd
from tensorflow import keras
import matplotlib.pyplot as plt
import tensorflow.compat.v1 as tf
import numpy as np
from sklearn.preprocessing import LabelEncoder
raw_data = pd.read_csv('iris.csv')
2) 데이터 전처리 및 샘플링
v=list(range(1,len(raw_data)+1))
s=SyncRNG(seed=38)
ord=s.shuffle(v)
idx=ord[:round(len(raw_data)*0.7)]
for i in range(0,len(idx)):
idx[i]=idx[i]-1
train=raw_data.loc[idx] # 70%
test=raw_data.drop(idx) # 30%
x_train = np.array(train.iloc[:,0:4], dtype=np.float32)
y_train = np.array(train.Species.replace(['setosa','versicolor','virginica'],[0,1,2]))
x_test = np.array(test.iloc[:,0:4], dtype=np.float32)
y_test = np.array(test.Species.replace(['setosa','versicolor','virginica'],[0,1,2]))
y_train_encoded = tf.keras.utils.to_categorical(y_train)
y_test_encoded = tf.keras.utils.to_categorical(y_test)
y_train_encoded.shape, y_test_encoded.shape
class_name=['Setosa','Versicolor','Virginica']
raw_data.Species.unique()
np.bincount(y_test)
np.bincount(y_train)
x_train.shape
x_test.shape
R과 Python의 난수 생성을 동일하게 하기 위해 SyncRNG 함수를 이용했으며, train, test셋은 7:3비율이다. Species기준으로 분할했기 때문에 각 종의 빈도수는 같다. 타겟의 명목형 변수를 숫자로 바꿔 불필요한 의미가 부여되지 않도록 했고, 의도한 범위 내에서만 값을 얻을 수 있도록 하기 위해 레이블인코딩을 했으며 마지막으로 원-핫 인코딩을 실시해서 차원을 재구성 했다. 그래서 R에서의 Setosa, Versicolor, Virginica가 파이썬에서는 0, 1, 2로 표현되어 있음을 유의해야 한다.
3) 케라스를 이용한 신경망 생성
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
model = Sequential()
model.add(Dense(3, input_dim=4, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
history = model.fit(x_train, y_train_encoded, epochs=200, batch_size=5, validation_data=(x_test, y_test_encoded))
print("\n 테스트 loss: %.4f" % (model.evaluate(x_test, y_test_encoded)[0]))
print("\n 테스트 accuracy: %.4f" % (model.evaluate(x_test, y_test_encoded)[1]))
predictions=model.predict(x_test)
케라스를 이용해서 모델을 생성한다. 활성화 함수는 소프트맥스 함수를 이용하고 은닉층 갯수는 따로 설정하지 않았다. 출력층 뉴런 갯수는 타겟의 클래스 갯수인 3개로 설정했고 소프트맥스 함수로 출력값을 분류한다. 오차 함수로는 크로스 엔트로피 함수를 사용하고 옵티마이저로는 경사 하강법의 일종인 SGD를 사용 했다.
테스트 loss: 0.1904
테스트 accuracy: 0.9778
array([[9.67251122e-01, 3.27430032e-02, 5.91728667e-06],……
[2.61039147e-03, 6.79958761e-01, 3.17430854e-01],……
[1.08743525e-05, 1.76265225e-01, 8.23723912e-01],…… ]]
출력층 뉴런 결과 값의 일부이다. accuracy값은 약 0.98이다.
그리고 출력층 뉴런은 3개이고 출력층 뉴런 수는 타겟의 클래스 수와 일치한다. 첫 번째 행 [9.67251122e-01, 3.27430032e-02, 5.91728667e-06]의 순서대로 Setosa, Versicolor, Virginica 의 분류 확률이며 이는 모든 행에 동일하게 부여된다. 셋 중 가장 높은 확률값으로 분류를 하는데, 첫 번째 행에서는 9.67251122e-01 이 가장 높으므로 Setosa로 분류되고, 두 번째 행은 6.79958761e-01 이 가장 높으므로 Versicolor로 분류되고, 세 번째 행은 8.23723912e-01 이 가장 높으므로 Virginica로 분류된다.
4) 시각화
print(history.history.keys())
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.legend(['loss','val_loss'])
plt.show()
plt.plot(history.history['accuracy'])
plt.plot(history.history['val_accuracy'])
plt.legend(['accuracy','val_accuracy'])
plt.show()
약 50번째 Epochs 부터 더이상 증가하지 못하고 일정하게 유지되는데, 따라서 Epochs 수는 50개가 최적점으로 판단된다. 50개 이상부터는 과적합이 발생할 수 있으니 유의해야 한다.
def plot_value_array(i, predictions_array, true_label):
true_label = true_label[i]
plt.grid(False)
plt.xticks(range(3),class_names,rotation=15)
thisplot = plt.bar(range(3), predictions_array, color="#777777")
plt.ylim([0, 1])
predicted_label = np.argmax(predictions_array)
title_font = {
'fontsize': 10,
}
if predicted_label == true_label:
color = 'blue'
else:
color = 'red'
plt.title("{}. {} {:2.0f}% ({})".format(i,class_names[predicted_label],
100*np.max(predictions_array),
class_names[true_label]),
color=color,fontdict=title_font)
thisplot[predicted_label].set_color('red')
thisplot[true_label].set_color('blue')
predictions=model.predict(x_test)
#0~24
num_rows = 5
num_cols = 5
num_table = num_rows*num_cols
plt.figure(figsize=(2*num_cols, 2*num_rows))
for i in range(num_table):
plt.subplot(num_rows, num_cols,i+1)
plot_value_array(i, predictions[i], y_test)
plt.tight_layout()
plt.show()
#25~44
num_rows = 4
num_cols = 5
num_table = num_rows*num_cols
plt.figure(figsize=(2*num_cols, 2*num_rows))
for i in range(num_table):
plt.subplot(num_rows, num_cols,i+1)
plot_value_array(i+25, predictions[i+25], y_test)
if i>=19:
break
plt.tight_layout()
plt.show()
사용자 정의 클래스를 생성하여 테스트 셋의 예측 결과를 시각화했다. 가독성을 위해 25개씩 출력하였다.
테스트 셋의 예측 결과를 막대그래프로 시각화했다. X축은 종속변수의 클래스, Y축은 확률 값이다. 즉, 총 45개의 막대 그래프는 테스트 셋이 Setosa, Versicolor, Virginica 중 하나로 분류될 확률을 나타낸다. 이때 정확하게 분류된 것은 파란색으로, 잘못 분류된 것은 빨간색으로 표시했다. 45개의 테스트 셋 중 43개가 정답을 맞추고 2개가 오답이었는데, 각각 63%, 53%의 확률로 Virginica로 잘못 분류된 것을 확인할 수 있다.
'python > 실습(project)' 카테고리의 다른 글
[Python/딥러닝/실습] 로지스틱 회귀 분석 (0) | 2023.01.12 |
---|---|
[Python/딥러닝/실습] 단순 선형회귀 분석 (0) | 2023.01.05 |
[Python/실습] 의사결정나무를 이용한 BostonHousing 예측분석 (0) | 2023.01.03 |
[Python/실습] 랜덤포레스트 모델을 이용한 위스콘신 유방암 데이터 분류분석 (0) | 2023.01.02 |
[python/실습] xgboost를 이용한 위스콘신 유방암 데이터 분류분석 (0) | 2022.12.20 |
댓글