SKADA | DRAM 내부 회로의 파형 예측 (2)
데이터 이해 및 전처리
시계열 데이터
-
시계열 데이터는 연속된 시간 동안 순차적으로 측정한 데이터를 의미한다.
-
일반적인 데이터는 서로 독립적인데 반해, 시계열 데이터는 데이터 간에 시간적으로 상관관계가 있다.
-
즉, 시계열 데이터를 분석하려면 과거의 데이터들이 미래에 미치는 영향의 패턴을 알아내는 것이 중요하다.
-
시계열 데이터 예시 : 일년 동안의 기온, 주가, 자연어, 비디오 등
-
시계열 데이터의 이용

- Many to many : 입력과 출력 모두 시계열
- One to many : 입력은 시계열 X, 출력은 시계열
- 이미지 캡셔닝 : 이미지가 입력되면 출력으로 이미지를 설명하는 문장 출력
- Many to one : 입력은 시계열, 출력은 시계열 X
전압 파형 데이터
- 회로에 인가한 입력 전압과 그에 따른 5가지 출력 전압 값을 picosecond 단위로 기록
- 훈련 데이터 : 약 45만개
- 테스트 데이터 : 약 19만개
- txt 파일 형태로 저장
- , 로 구분(이렇게 구분되어 있는 데이터는 csv(comma-separated values)
- 시간, 입력 전압, 출력 전압 A ~ E ⇒ Time, Input_V, A, B, C, D, E
- 학습용 데이터 중 일부는 학습에, 일부는 검증에 사용
- 실무에서 테스트용 데이터는 일반적으로 label이 없음
- 딥러닝 모델을 개발할 때, 모델을 여러 개 만들어서 어떻게 동작하는지 보게 되는데 동작의 검증을 validation 데이터로 하게 됨
- 학습용 데이터로 학습하고 성능 확인은 validation으로 하고, 가장 성능이 좋은 걸 사용
읽기
-
Pandas의 read_csv 함수 활용
import pandas as pd # pandas 라이브러리 불러오기 train_data_path = './dataset/~.txt' # 학습 data 위치를 변수로 저장 test_data_path = './dataset/~.txt' # 테스트 data 위치를 변수로 저장 df_train = pd.read_csv(train_data_path, delimiter = ',', header = 0) # 학습 data 읽기 df_test = pd.read_csv(test_data_path, delimiter = ',', header = 0) # 테스트 data 읽기- 하드 드라이브에 있는 것을 메모리로 데이터를 불러오기
- read_csv : 데이터 불러오기
- df : 일반적으로 pandas에서 데이터를 불러올 때 dataframe이라고 함
- 하드 드라이버에 있는 데이터부터 불러옴
- delimiter은 각각의 데이터가 어떤 걸로 분리되어 있는지, 헤더는 몇 번째부터의 데이터를 활용할 것인지 알려주는 argument
-
Pandas의 여러 함수 및 인덱싱을 사용해 데이터 내부 확인
df_test.shape # 테스트 data의 행과 열 개수 출력 ex. (19xxx, 7) df_test.head(5) # 테스트 data 중 첫 다섯 행만 출력 df_test.tail(5) # 테스트 data 중 마지막 다섯 행만 출력df_test.describe() # 테스트 data의 통계값 출력(count, mean, std 등) df_test.columns # 테스트 data의 header (열 이름) 출력 df_test.values # dataframe을 numpy ndarray로 변환 # df_test.to_numpy() # ndarray n dimensional array(행렬은 2 dimensional array)df_test.loc[0:4] # 테스트 data의 첫 4개 행을 반환 df_test.loc[0:4, ['Input_V', 'A']] # 첫 다섯 행을 반환하되, Input_V와 A열만 반환 df_test.iloc[-4:, 0:2] # 마지막 네 개 행을 반환하되, 첫 두 개 열만 반환
결측 치 존재 여부 확인
-
데이터에 결측 치 (NaN)가 존재할 수 있음
-
결측 치란 관찰되지 않은 데이터로, 빈 칸을 의미함
is_null = df_train.isnull() # dataframe을 구성하는 각 element가 빈 칸이면 True Is_null_np = is_null.values # is_null을 numpy ndarray로 변환 exists_null = is_null_np.any() # data에 빈칸이 하나라도 존재하면 True, 아니면 False
데이터 시각화
-
데이터 이해를 돕기 위해 읽어 온 데이터를 시각화 해보기
from matplotlib import pyplot as plt # matplotlib 라이브러리 불러오기 %matplotlib inline # 출력된 그래프가 브라우저에서 보이도록 함 fig = plt.figure(figsize = (10, 5)) # 가로 10, 세로 5 사이즈의 figure 생성 plt.xlabel('Time (picosecond) ') # x 축 레이블 지정 plt.ylabel('Values ') # y 축 레이블 지정 picoseconds = df_train.iloc[10000:20000, 0] * 10e+12 # 1만 ~ 2만 행의 시간 값(첫번째 열) for i in range(1, len(df_train.columns)): plt.plot(picoseconds, df_train.iloc[10000:20000, i], label = df_train.columns[i]) # 1만 ~ 2만 행의 입력 및 출력 전압 값(두번째 열 ~ 마지막 열) plt.legend(loc = 'upper right') # 범례가 오른쪽 위에 위치하도록 함 plt.show()
학습용 데이터와 검증용 데이터를 분리
-
학습용 데이터 중 앞 90%는 학습에, 나머지 10%는 검증에 사용한다.
-
딥러닝 모델 학습 시, 모델의 에폭 별 성능을 평가하기 위해 학습용 데이터를 이용하는 것은 적절치 않다.
- 에폭 : 전체 학습 데이터셋을 모델이 한 번 학습하는 것
- 여러번의 에폭을 통해 학습하고 매 에폭마다 성능을 평가한다.
- 학습 데이터는 크기 때문에 성능 검증만으로 시간이 많이 걸린다.
- 검증용 데이터를 만들어서 한 에폭이 끝나면 검증용 데이터에서 성능을 평가한다.
- 모델이 학습용 데이터에 과적합 되어있을 수 있기 때문이다.
-
그래서, 모델 학습에 사용되지 않은 검증용 데이터를 모델 평가에 사용한다.
- training data loss는 줄이게 되고, 테스트 데이터 셋의 loss는 감소하다가 증가한다.
- 학습 초반에 테스트 셋에서도 train에서 성능이 안 좋아서 안 쓴다.
- 학습이 많이 진행된 것은 과적합, training에서는 좋은 성능을 보이지만 테스트에서는 일반화가 잘 되지 않는 모델이 되기에 쓰지 않는다.
train_valid_ratio = 0.9 # 학습용 데이터와 검증용 데이터의 비율을 9:1로 설정합니다. train_len = int(df_train.shape[0] * train_valid_ratio) # 학습 데이터의 개수 valid_len = df_train.shape[0] - train_len # 검증용 데이터의 개수 Test_len = df_test.shape[0] # 테스트용 데이터의 개수 - training data loss는 줄이게 되고, 테스트 데이터 셋의 loss는 감소하다가 증가한다.
-
각 dataframe을 numpy ndarray로 변환하여 학습 데이터, 검증 데이터, 테스트 데이터를 dictionary로 저장
train_data = { 'time' : df_train.iloc[:, 0].values[:train_len], 'X' : df_train.iloc[:, 1].values[:train_len], 'y' : df_train.iloc[:, 2].values[:train_len] } valid_data = { 'time' : df_train.iloc[:, 0].values[train_len:], 'X' : df_train.iloc[:, 1].values[train_len:], 'y' : df_train.iloc[:, 2].values[train_len:] } test_data = { 'time' : df_test.iloc[:, 0].values, 'X' : df_test.iloc[:, 1].values, 'y' : df_test.iloc[:, 2].values }
데이터 정규화
-
데이터 정규화는 데이터의 범위를 적당하게 (ex. -1 ~ 1 사이) 맞춰 주는 것을 의미한다.
-
일반적으로, 머신러닝 모델은 정규화 된 데이터에서 더 잘 학습되는 것으로 알려져 있다.
-
이 프로젝트에서, 데이터의 각 변수를 표준화 (평균을 뺀 후 표준편차로 나누어 줌) 하여 정규분포를 따르도록 하는 정규화를 수행한다.

-
평균이 0, 표준 편차가 1이 되도록 정규화시킨다.
X_mean = train_data['X'].mean() # 학습 데이터의 입력 전압 평균 X_std = train_data['X'].std() # 학습 데이터의 입력 전압 표준편차 X_train = (train_data['X'] - X_mean) / X_std # 학습 데이터 정규화 X_valid = (valid_data['X'] - X_mean) / X_std # 검증 데이터 정규화 X_test = (test_data['X'] - X_mean) / X_std # 테스트 데이터 정규화