프로젝트/2021 한이음(probono)

[프로보노프로젝트/딥러닝/개발] sklearn 을 이용한 타겟데이터 만들기 (sklearn:target data) + 그 외 데이터 셋 개발 백업

pxatd 2021. 9. 14. 15:22
728x90

딥러닝 개발도 어느새 막바지에 접어들었다. 현재까지는 편의를 위해 보이스피싱인 데이터 셋으로 딥러닝 개발을 진행하였다면, 지금부터는 실생활에 사용할 수 있도록 보이스피싱인 데이터, 보이스피싱이 아닌 데이터, 그리고 각각의 데이터 셋에 대한 학습데이터, 검증데이터, 평가데이터, 그리고 타겟데이터를 만들어야 한다.

데이터 셋의 종류가 많기 때문에 헷갈리지 않도록 각각의 개념을 정립하는 것이 중요하다. 나도 처음에는 이 개념을 이해하지 못했기 때문에 개발하는데 자꾸 버벅였다. 내가 뭘 만들어야 하는지 모르니 당연하다. 그럴 때마다 팀장님께서 내가 뭘 만들어야하는지 항상 상기시켜주셨고 초등학생에게 설명하는 것 처럼 각각의 개념에 대해 본인에게 설명해보라고 하셨다. 덕분에 개념을 잘 학습할 수 있었던 것 같다.


타겟 데이터(target data)란 말그대로 정답, 해답 데이터이다. 기계에게 학습시킬 때 데이터만 입력한다고 학습이 되는게 아니다. 데이터를 주고 이건 정답이야 이건 오답이야 라고 정해줘야 기계가 그 데이터를 바탕으로 학습하는 것이다. 그렇기 때문에 기존 데이터에서 데이터 값과 라벨 값을 지정해준 뒤 오답 데이터는 라벨값을 '0'으로 지정해주고, 정답데이터는 라벨값을 '1'로 지정해준다. 꼭 0과 1이 아니더라도 상관 없다. 또, 꼭 두 가지일 필요도 없다. 1,2 / 1,2,3 이런식으로 아무 정수나 괜찮다.

1.sklearn.datasets:target data

훈련 데이터셋을 세팅하기 위해 sklearn 패키지를 사용하였다.

import numpy as np #훈련데이터셋 세팅 from sklearn.datasets import load_digits import pandas as pd text_data = pd.read_csv('textvp.txt', names=['data','label'], sep='|') text_train = text_data['data'].to_numpy() train_target=text_data['label'].to_numpy() not_text_data = pd.read_csv('notPhishing.txt', names=['text']) not_text_train = not_text_data['text'].to_numpy() # not_train_target=text_data['label'].to_numpy() print(text_data.keys()) print(not_text_data.keys()) #data는 학습해야 할 feed용 데이터를 의미 text_data['data'] #target은 label 데이터 이며, 예측해야 할 (class) 데이터 text_data['label'] not_text_data['text']

 

2.보이스피싱아닌 데이터셋 개수 줄이기

팀원이 가져온 보이스피싱이 아닌 데이터 셋의 개수가 5만개가 넘었기 때문에 너무 많다고 판단했다. 보통 데이터 셋의 개수는 1만개 정도면 적당하기 때문에 이것을 어떻게 줄일 지 고민하다가 각 샘플의 길이가 보이스피싱인 데이터보다 짧다는 것을 알게되었다. 따라서 colab python으로 보이스피싱이 아닌 데이터 셋의 개수를 줄이는 코드를 개발하였다.

이 코드는 5만개의 코드 range를 50번 반복하며 리스트에 추가한다. 따라서 보이스피싱이 아닌 데이터셋의 크기는 1111개로 줄어들었다.

import pandas as pd print(len(not_text_train)) #print(not_text_train[55626]) print(not_text_train[55549]) import numpy as np num = 0 #body = np.array() body = [] for k in range(1111): a = '' num += 50 for i in range(num-50, num): sentence = not_text_train[i] a = a + sentence body.append(a) body=np.array(body) #list to array (now, body=numpy) #print(len(body)) #print(body[1110]) #print(body[0]) print(body[0:50]) for i in range(50): print(len(body))

중간에 np.array 코드는 보이스피싱인 데이터와 합치기 위해 list와 nparray중 하나로 통일 한 것이다.

3.보이스피싱데이터+보이스피싱 아닌 데이터셋 만들기

이제 보이스피싱인 데이터와 보이스피싱이 아닌 데이터 셋을 만들 차례이다. 지금까지는 보이스피싱인 데이터 (testvp) 와 보이스피싱이 아닌 데이터(notvp)로 구분해놨지만 학습데이터를 만들 때는 그렇지 않다. 각각의 데이터 속성에 따라 라벨값을 0과 1로 붙여놓을 것이니 데이터를 섞어도 기계는 잘 학습할 수 있을 것이다.

allData=np.append(text_train,body) print(len(allData)) print(allData[:])

for반복문을 통해 하나하나 리스트에 추가하려고 했는데 무슨 이유인지 잘 되지 않았다. 여러번 테스트를 해 본 결과 for반복문을 사용하게 되면 data,label 값이 추가되거나, for반복문을 돌 때마다 리스트가 초기화되는 경우, 그냥 내가 코드를 잘 못 짠 경우(이중 for반복문을 썻는데 천천히 의미를 파악해 보니 notvp데이터 셋에서만 데이터를 추가하고 있었다..)가 있어 그냥 append(x,y)를 통해 간단히 해결할 수 있었다.

두 개의 데이터 셋이 잘 합쳐진 모습

4. target데이터 만들기

위에서 설명했듯 우리가 정답으로 설정한 target 데이터는 보이스피싱인 데이터로 라벨값을 1로 지정해주는 코드를 개발해야한다. 우리의 데이터 셋 중 보이스피싱인 데이터는 이미 1로 라벨링이 되어있기 때문에 보이스피싱이 아닌 데이터를 0으로 라벨링 해주면 되었다.
이에대해 라벨링을 어떻게 진행해야 할 지 막막했는데 팀장님께서 np패키지에 zero라는 함수를 사용하면 된다고 알려주셨다.

zero=np.zeros(1111) print(zero) print(len(zero)) print(type(zero)) allTarget=np.append(train_target,zero) print(len(allTarget))

0으로 라벨링 한 부분 => 아까 보이스피싱이 아닌 데이터 셋의 개수 줄임 1111개
allTarget이 1273 개인 이유 => 보이스피싱 데이터 162개 + 아닌 데이터 1111개

5. 훈련 데이터 셋 분할

이제 데이터까지 모두 합쳤으니 우리가 정한 비율 (2:3:5)로 분할하면 된다. 여기에서도 sklearn 패키지를 이용하였다. 개발하면서 매개변수에 대한 부분은 주석으로 처리해놓았다.

x = allData y = allTarget #훈련데이터셋 분할 from sklearn.model_selection import train_test_split #dataset 자체는 order가 깔끔히 정렬된 상태이기 때문에 반드시 dataset을 shuffle 해주어야 한다. #sklearn에서 제공해주는 train_test_split을 활용하면 매우 쉽게 shuffle과 split을 할 수 있다. x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2) #train_test_split()은 기본적으로 훈련데이터 세트를 75:25의 비율로 나눔 #이 비율을 조정하고 싶을 때는 test_size 매개변수에 테스트 세트의 비율을 전달하면 조절할 수 있음 #여기서는 입력된 데이터 세트의 20%를 테스트 세트로 나누기 위해 0.2를 전달 print(x.shape) ## 훈련데이터세트의 shape ## print(x_train.shape, x_test.shape) ## 훈련세트, 테스트세트 shape ## np.unique(y, return_counts = True) ## 훈련데이터세트의 클래스 비율 ## np.unique(y_train, return_counts = True) ## 훈련세트의 클래스 비율 ## np.unique(y_test, return_counts = True) ## 훈련세트의 클래스 비율 ##

이렇게 하면 데이터 셋에 대한 개발은 정말 거의 다 되었다. 이제 내가 맡은 일 중엔 전처리 개발 코드와 딥러닝 엔진 코드 모듈끼리 합하고 잘 돌아가는지 확인만 하면 된다. 그 외에 변수 통일, 데이터 셋 자료명 통일 등 자잘한 일들이 남았다.
전체 프로젝트로 보면 STT API의 성능 향상 방법 강구, 라즈베리파이 운영체제 설정 + 연결, 스니핑 (멀티브로드캐스팅) 등이 남았다.

728x90