데이터를 추출하면 클래스와 상관없는 속성과 클래스와 상관이 큰 속성으로 나뉜다.
딥러닝을 실행하기 전, 클래스와 상관관계가 있는 속성을 분류하여 딥러닝의 정확성을 높이자.
아래는 피마 인디언들의 당뇨병 여부를 예측하는 프로그램이다.
샘플 수는 768개이고, 속성이 8개 인것을 알 수 있다. 그리고 클래스는 1 혹은 0으로 구분된다.
# 파일 선택을 통해 예제 데이터를 내 컴퓨터에서 불러옵니다.
from google.colab import files
uploaded = files.upload()
my_data = 'pima-indians-diabetes.csv'
# pandas 라이브러리를 불러옵니다.
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 불러온 데이터셋을 적용합니다. 이 때 각 컬럼에 해당하는 이름을 지정합니다.
df = pd.read_csv(my_data,
names = ["pregnant", "plasma", "pressure", "thickness", "insulin", "BMI", "pedigree", "age", "class"])
# names는 각각의 속성의 이름을 지정해준다. my_data는 파일 경로이다.
각각의 속성은 df = pd.read_csv(my_data,
names = ["pregnant", "plasma", "pressure", "thickness", "insulin", "BMI", "pedigree", "age", "class"])
로 구분한다.
pandas.read_csv는 라벨이 붙은 2차원 배열(그냥 표라고 생각하자)를 반환한다.
참고로 csv는 comma separated values file의 약자로, 콤마로 구분된 데이터의 모음이다.
보통은 데이터를 설명하는 한줄이 파일 맨 처음에 있는데, 이 파일에는 없다.
# 처음 5줄을 봅니다.
print(df.head(5))
출력 결과
# 데이터의 전반적인 정보, 각 속성의 특징을 살펴본다.
print(df.info())
출력 결과
# 속성 값에 통계적 특징 좀더 자세히 출력합니다.
print(df.describe())
count는 샘플의 개수 mean은 평균, std는 표준편차를 의미한다.
각 퍼센티지는 하위 기준으로 백분위로 해당하는 샘플의 개수를 의미한다.
# 데이터 중 임신 정보와 클래스 만을 출력해 봅니다.
print(df[['plasma', 'class']])
print(df[['pregnant', 'class']])
데이터의 내용물을 간단히 살펴보는 것은 이정도로 하고, 데이터 간의 상관관계를 파악하는 방법을 살펴보자.
# 데이터를 가공하여 어떤 데이터를 취급할 지 생각해야한다.
# 어떤 속성이 당뇨병 발생과 상관관계가 있는 지 살펴야한다.
# 임신 회수와 당뇨병 발병의 확률
print(df[['pregnant','class']].groupby(['pregnant'], as_index=False).mean().sort_values(by='pregnant',ascending=True))
groupby() : pregnant 정보를 기준으로하는 새 그룹을 만든다.
as_index=False : pregnant 왼쪽에 새로운 인덱스를 만든다. 없어도 된다.
mean() : 평균을 구하고 그에 대한 2차원 데이터 구조를 반환한다. std()와 같은 것도 가능.
sort_values() : pregnant 칼럼을 오름차순으로 정렬한다.
heatmap을 이용해서 상관관계를 그래프로 볼 수 있다.
# 그래프를 통해 한눈에 속성간 상관관계를 살핀다.
# matplotlib, sseaborn을 사용한다.
# 데이터 간의 상관관계를 그래프로 표현해 봅니다.
colormap = plt.cm.gist_heat #그래프의 색상 구성을 정합니다.
plt.figure(figsize=(12,12)) #그래프의 크기를 정합니다.
# heatmap이 항목간 상관관계를 잘 나타낸다.
# 상관관계가 없으면 0 있으면 1
# 그래프의 속성을 결정합니다.
sns.heatmap(df.corr(),linewidths=0.1,vmax=0.5, cmap=colormap, linecolor='white', annot=True)
plt.show()
그래프로 나온 결과를 보면 밝을 수록 숫자가 높은 것을 확인 할 수 있고, plasma가 당뇨와 가장 상관관계가 높다는 것을 알 수 있다.
위의 코드에 대해 조금 더 자세히 알아보자.
df.corr에 관한 레퍼런스
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.corr.html
상관관계 행렬을 반환한다.
seabon.heatmap에 대한 레퍼런스
https://seaborn.pydata.org/generated/seaborn.heatmap.html
sns.heatmap(df.corr(),linewidths=0.1,vmax=0.5, cmap=colormap, linecolor='white', annot=True)
에서
df.corr()는 df의 상관관계 행렬을 반환한다.
linewidths는 그래프의 각 셀의 간격을 조정한다.
vmax는 색상의 값을 고정한다.
vmax의 값을 0.5로 지정해 0.5에 가까울 수록 밝은 색으로 표시되게 합니다.
cmap은 matplotlib 색상의 설정값을 불러온다.
annot은 각 칸에 df.corr이 들어가도록 설정한다.
grid = sns.FacetGrid(df, col='class')
grid.map(plt.hist, 'plasma', bins=10)
plt.show()
당뇨병 환자의 경우 plasma 항목의 수치가 150이상인 사람이 많다는 걸 알 수 있다..
이렇게 데이터 전처리 과정을 마친다.
코드에 대해서 더 설명하자면,
sns.FacetGrid의 레퍼런스
https://seaborn.pydata.org/generated/seaborn.FacetGrid.html
grid = sns.FacetGrid(df, col='class')
첫번째 인자인 df는 각 열이 변수이고 각 행이 관측 대상인 것이 되어야한다.
col, row에 들어가는 string은 각기 다른 곳에 그려질 변수명을 적어줘야한다. 같은 col에는 같은 class가 들어가게 된다.
sns.FacetGrid.map의 레퍼런스
https://seaborn.pydata.org/generated/seaborn.FacetGrid.map.html
grid.map(plt.hist, 'plasma', bins=10)
각 facetGrid에 그림을 그린다.
plt.hist : 히스토그램으로 그린다.
'plasma' : plasma라는 이름의 data를 기준으로 그린다.
bins=10 : 히스토그램의 막대기는 10개
pyplot.show()의 레퍼런스. 딱히 볼 필요는 없다.
https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.show.html
※ 보통 데이터 전처리 과정은, omit된 데이터를 평균/중앙값으로 대치하는 과정, 관계없는 데이터가 없는 지 확인하는 과정 등이 포함된다.
SVM, RF등의 머신러닝 기법은 중요 속성을 뽑아 내는 FEATURE EXTRACTION 과정도 데이터 전처리에 포함하지만, 딥러닝은 중요 속성을 내부적으로 추출하므로 데이터 전처리 시에 해당 작업을 할 필요는 없다.
이대로 딥러닝을 구동하면
# 딥러닝을 구동하는 데 필요한 케라스 함수를 불러옵니다.
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
# 필요한 라이브러리를 불러옵니다.
import numpy
import tensorflow as tf
# 실행할 때마다 같은 결과를 출력하기 위해 설정하는 부분입니다.
numpy.random.seed(3)
tf.random.set_seed(3)
# 데이터를 불러 옵니다.
dataset = numpy.loadtxt(my_data, delimiter=",")
X = dataset[:,0:8]
Y = dataset[:,8]
# 모델을 설정합니다.
model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu')) #입력 + 은닉층
model.add(Dense(8, activation='relu')) # 은닉층
model.add(Dense(1, activation='sigmoid'))
# 모델을 컴파일합니다.
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
# 모델을 실행합니다.
model.fit(X, Y, epochs=200, batch_size=10)
# 결과를 출력합니다.
print("\n Accuracy: %.4f" % (model.evaluate(X, Y)[1]))
출력
...
Epoch 190/200
77/77 [==============================] - 0s 1ms/step - loss: 0.4687 - accuracy: 0.7760
Epoch 191/200
77/77 [==============================] - 0s 1ms/step - loss: 0.4675 - accuracy: 0.7669
Epoch 192/200
77/77 [==============================] - 0s 1ms/step - loss: 0.4675 - accuracy: 0.7565
Epoch 193/200
77/77 [==============================] - 0s 1ms/step - loss: 0.4743 - accuracy: 0.7799
Epoch 194/200
77/77 [==============================] - 0s 1ms/step - loss: 0.4765 - accuracy: 0.7695
Epoch 195/200
77/77 [==============================] - 0s 1ms/step - loss: 0.4664 - accuracy: 0.7682
Epoch 196/200
77/77 [==============================] - 0s 1ms/step - loss: 0.4741 - accuracy: 0.7669
Epoch 197/200
77/77 [==============================] - 0s 1ms/step - loss: 0.4734 - accuracy: 0.7747
Epoch 198/200
77/77 [==============================] - 0s 1ms/step - loss: 0.4668 - accuracy: 0.7578
Epoch 199/200
77/77 [==============================] - 0s 1ms/step - loss: 0.4679 - accuracy: 0.7760
Epoch 200/200
77/77 [==============================] - 0s 1ms/step - loss: 0.4662 - accuracy: 0.7721
24/24 [==============================] - 0s 1ms/step - loss: 0.4587 - accuracy: 0.7708
Accuracy: 0.7708
코드를 더 설명하도록 하겠다.
numpy.random.seed(3)
tf.random.set_seed(3)
에서 seed값을 설정하는다는 것은 난수표에서 몇 번째 테이블을 불러와 슬지 정하는 것과 같다. 따라서 seed 값이 같으면 똑같은 랜덤 값을 출력한다.
단 이렇게 seed 값을 설정해도 출력 값이 약간 다를 수 있는데, cuDNN 등의 내부 커널이 난수표를 자체 생성하기 때문이다.
이런 부분까지 seed로 지정할 수는 없으므로 최종적인 딥러닝 결과는 여러번 실행하여 평균을 구하는 것이 좋다.
tf.keras.Sequential()
의 공식문서를 살펴보자
https://www.tensorflow.org/api_docs/python/tf/keras/Sequential
model = Sequential(layers, name)
은 딥러닝 모델의 클래스를 의미한다.
Sequential 클래스 아래에는 add, fit, compile 등의 메서드가 있다.
model.add(layer)
이 메서드는 Layer를 추가한다.
model.compile(optimizer='rmsprop', loss=None, metrics=None, loss_weights=None, weighted_metrics=None, run_eagerly=None, steps_per_execution=None, **kwargs)
는 학습 전 모델에 대한 환경설정을 한다.
여기서 metric은 평가될 대상을 의미한다.
model.fit(X, Y, epochs=200, batch_size=10)
fit(
x=None, y=None, batch_size=None, epochs=1, verbose='auto',
callbacks=None, validation_split=0.0, validation_data=None, shuffle=True,
class_weight=None, sample_weight=None, initial_epoch=0, steps_per_epoch=None,
validation_steps=None, validation_batch_size=None, validation_freq=1,
max_queue_size=10, workers=1, use_multiprocessing=False
)
는 epoch의 수 만큼 train을 감행한다.
batch_size의 수 만큼 배치를 추출해서 확률적 경사하강법을 실행한다.
model.evaluate(X, Y)[1] # 인덱스 0은 loss, 1은 accuracy를 뱉는다.
evaluate(x=None, y=None, batch_size=None, verbose=1, sample_weight=None, steps=None, callbacks=None, max_queue_size=10, workers=1, e_multiprocessing=False, return_dict=False, **kwargs)
는 오차 값과 compile에서 정한 metrics의 값을 반환한다.
'AI > 모두의 딥러닝' 카테고리의 다른 글
[Deep Learning : 딥러닝] 과적합 Overfitting (0) | 2021.06.25 |
---|---|
[Deep Learning : 딥러닝] 다중 분류 문제 (0) | 2021.06.23 |
[Deep Learning : 딥러닝] 딥러닝 모델 설계 (0) | 2021.06.18 |
[Deep Learning : 딥러닝] 오차 역전파 기울기 소실, 확률적 경사 하강법(Stochastic Gradient Descent) (0) | 2021.06.10 |
[Deep Learning : 딥러닝] 오차 역전파와 XOR 문제 (0) | 2021.06.09 |