예를 위해 위 Github에서 0과 1로 이루이진 이진 클래스 데이터 셋이 있다. 이 글은 데이터를 라벨에 맞게 골고루 분리하는 것이므로 데이터 분석은 따로 하지 않는다.
csv 파일은 7개이며, 총 데이터의 개수는 42000개이다.
sklearn 라이브러리에서 train_test_split을 사용하면 간단히 데이터를 분할할 수 있다. 아래 코드에서 간단히 데이터셋을 불러올 수 있다. 이 데이터셋의 경우 nlos가 클래스(혹은 정답 데이터)이다. 아래의 그림을 보게 되면 0, 1, 0, 1, 1...로 무작위로 정렬돼었다. 각 클래스의 개수를 출력하면, 21000개를 확인할 수 있다.
import uwb_dataset
import pandas as pd
columns, data = uwb_dataset.import_from_files()
for item in data:
item[15:] = item[15:]/float(item[2])
print("\nColumns :", columns.shape, sep=" ")
print("Data :", data.shape, sep=" ")
print(type(data))
df_uwb = pd.DataFrame(data=data, columns=columns)
print(df_uwb.head(10))
los_count = df_uwb.query("NLOS == 0")["NLOS"].count()
nlos_count = df_uwb.query("NLOS == 1")["NLOS"].count()
print("Line of Sight Count :", los_count)
print("Non Line of Sight Count :", nlos_count)
"""
결과
./dataset/uwb_dataset_part5.csv
./dataset/uwb_dataset_part7.csv
./dataset/uwb_dataset_part2.csv
./dataset/uwb_dataset_part3.csv
./dataset/uwb_dataset_part4.csv
./dataset/uwb_dataset_part1.csv
./dataset/uwb_dataset_part6.csv
Columns : (1031,)
Data : (42000, 1031)
<class 'numpy.ndarray'>
Line of Sight Count : 21000
Non Line of Sight Count : 21000
"""
파이썬으로 개발을 하면서 느낀 것은 최대한 반복문을 지양하고 라이브러리를 사용하는 것이다. 파이썬은 빠르게 데모 프로그램 구현에 많이 사용하는데 라이브러리가 이를 가능케 한다. 그리고 가장 큰 이유는 내가 만든 코드는 절대 라이브러리를 이길 수 없다는 것이다. 이번에 사용하고자 하는 train_test_split은 sklearn 라이브러리의 함수이다. sklearn는 머신러닝 대표 라이브러리이지만 딥러닝 사용에 있어 문제가 없다.
train_test_split : 배열 또는 행렬을 무작위 학습 및 테스트 하위 집합으로 분할.
-test_size : 0~1 사이의 값으로, 기본 test size는 0.25로 자동으로 train size는 0.75이다. 아래의 그림처럼 데이터를 분할.
- random_state : shuffle 제어하는 인자이다. 모델의 성능을 향상시키기 위해 다양한 방법으로 모델을 디자인한다. 하지만 공정한 검증을 위해 똑같은 데이터셋을 필요로 한다. 그 때 사용하는 인자이다.
import os
path_ = './data/test.csv'
fieldnames = ['device_name','f_port', 'ucnt', 'dr', 'rssi', 'snr', 'channel', 'lat', 'long_', 'alt']
if __name__ == '__main__':
file_exists = os.path.isfile(path_)
while(1):
"""
Do something ex) serial.read, post, parsing...
"""
with open(file_name, 'a', newline='\n') as csvfile:
wr = csv.DictWriter(csvfile, delimiter=',', fieldnames=fieldnames)
if not file_exists: wr.writeheader()
wr.writerow({
'device_name' :device_name,
'f_port':f_port,
'ucnt' : ucnt,
'dr' :dr,
'rssi':rssi,
'snr':snr,
'channel':channel,
'lat':lat,
'long_': long_,
'alt': alt})
1. with문을 사용한 이유 :
우선 파이썬 공식문서는 with문을 쓰기 권장한다. 파일 쓰기 위해선 파일을 열어야 합니다. 그리고 쓰기가 완료되면 닫아야 합니다. 하지만 파일 쓰기가 완료되었지만, 파일이 열려 있으면 파일이 깨지거나, 제대로 된 데이터가 아닐 수 있습니다. with문은 이를 방지 위해 파일 열기, 닫기를 자동으로 해줍니다.
2. 위 csv 저장하는 코드는 데이터를 이어 저장하는 형식이며, 만약 파일 이름(path_)이 지정한 경로(./data/) 내에 이름이 같은 파일이 없다면, csv header(fieldnames)를 추가한다. 파일 이름이 지정한 경로 내에 이름이 같은 파일이 있다면, csv header를 추가하지 않고, 데이터를 그대로 이어 저장한다.
csv 형태를 잘 만들어 놓으면 나중에 pandas 혹은 matlab가지고 놀기 편합니다.
이런 느낌의 코드를 전에 짜놓고 또 못찾아서 새로 짜고를 3번 정도 반복할쯤 그냥 블로그에 올리기로 했습니다.